1 /* 2 * Copyright (c) 2016-2021 The Linux Foundation. All rights reserved. 3 * Copyright (c) 2021-2023 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 /* 72 * If FW supports WMI_SERVICE_SCAN_CONFIG_PER_CHANNEL, 73 * then channel_list may fill the upper 12 bits with channel flags, 74 * while using only the lower 20 bits for channel frequency. 75 * If FW doesn't support WMI_SERVICE_SCAN_CONFIG_PER_CHANNEL, 76 * then channel_list only holds the frequency value. 77 */ 78 #define CHAN_LIST_FLAG_MASK_POS 20 79 #define TARGET_SET_FREQ_IN_CHAN_LIST_TLV(buf, freq) \ 80 ((buf) |= ((freq) & WMI_SCAN_CHANNEL_FREQ_MASK)) 81 #define TARGET_SET_FLAGS_IN_CHAN_LIST_TLV(buf, flags) \ 82 ((buf) |= ((flags) << CHAN_LIST_FLAG_MASK_POS)) 83 84 /* HTC service ids for WMI for multi-radio */ 85 static const uint32_t multi_svc_ids[] = {WMI_CONTROL_SVC, 86 WMI_CONTROL_SVC_WMAC1, 87 WMI_CONTROL_SVC_WMAC2}; 88 89 #ifdef ENABLE_HOST_TO_TARGET_CONVERSION 90 /*Populate peer_param array whose index as host id and 91 *value as target id 92 */ 93 static const uint32_t peer_param_tlv[] = { 94 [WMI_HOST_PEER_MIMO_PS_STATE] = WMI_PEER_MIMO_PS_STATE, 95 [WMI_HOST_PEER_AMPDU] = WMI_PEER_AMPDU, 96 [WMI_HOST_PEER_AUTHORIZE] = WMI_PEER_AUTHORIZE, 97 [WMI_HOST_PEER_CHWIDTH] = WMI_PEER_CHWIDTH, 98 [WMI_HOST_PEER_NSS] = WMI_PEER_NSS, 99 [WMI_HOST_PEER_USE_4ADDR] = WMI_PEER_USE_4ADDR, 100 [WMI_HOST_PEER_MEMBERSHIP] = WMI_PEER_MEMBERSHIP, 101 [WMI_HOST_PEER_USERPOS] = WMI_PEER_USERPOS, 102 [WMI_HOST_PEER_CRIT_PROTO_HINT_ENABLED] = 103 WMI_PEER_CRIT_PROTO_HINT_ENABLED, 104 [WMI_HOST_PEER_TX_FAIL_CNT_THR] = WMI_PEER_TX_FAIL_CNT_THR, 105 [WMI_HOST_PEER_SET_HW_RETRY_CTS2S] = WMI_PEER_SET_HW_RETRY_CTS2S, 106 [WMI_HOST_PEER_IBSS_ATIM_WINDOW_LENGTH] = 107 WMI_PEER_IBSS_ATIM_WINDOW_LENGTH, 108 [WMI_HOST_PEER_PHYMODE] = WMI_PEER_PHYMODE, 109 [WMI_HOST_PEER_USE_FIXED_PWR] = WMI_PEER_USE_FIXED_PWR, 110 [WMI_HOST_PEER_PARAM_FIXED_RATE] = WMI_PEER_PARAM_FIXED_RATE, 111 [WMI_HOST_PEER_SET_MU_ALLOWLIST] = WMI_PEER_SET_MU_ALLOWLIST, 112 [WMI_HOST_PEER_SET_MAX_TX_RATE] = WMI_PEER_SET_MAX_TX_RATE, 113 [WMI_HOST_PEER_SET_MIN_TX_RATE] = WMI_PEER_SET_MIN_TX_RATE, 114 [WMI_HOST_PEER_SET_DEFAULT_ROUTING] = WMI_PEER_SET_DEFAULT_ROUTING, 115 [WMI_HOST_PEER_NSS_VHT160] = WMI_PEER_NSS_VHT160, 116 [WMI_HOST_PEER_NSS_VHT80_80] = WMI_PEER_NSS_VHT80_80, 117 [WMI_HOST_PEER_PARAM_SU_TXBF_SOUNDING_INTERVAL] = 118 WMI_PEER_PARAM_SU_TXBF_SOUNDING_INTERVAL, 119 [WMI_HOST_PEER_PARAM_MU_TXBF_SOUNDING_INTERVAL] = 120 WMI_PEER_PARAM_MU_TXBF_SOUNDING_INTERVAL, 121 [WMI_HOST_PEER_PARAM_TXBF_SOUNDING_ENABLE] = 122 WMI_PEER_PARAM_TXBF_SOUNDING_ENABLE, 123 [WMI_HOST_PEER_PARAM_MU_ENABLE] = WMI_PEER_PARAM_MU_ENABLE, 124 [WMI_HOST_PEER_PARAM_OFDMA_ENABLE] = WMI_PEER_PARAM_OFDMA_ENABLE, 125 [WMI_HOST_PEER_PARAM_ENABLE_FT] = WMI_PEER_PARAM_ENABLE_FT, 126 [WMI_HOST_PEER_CHWIDTH_PUNCTURE_20MHZ_BITMAP] = 127 WMI_PEER_CHWIDTH_PUNCTURE_20MHZ_BITMAP, 128 [WMI_HOST_PEER_FT_ROAMING_PEER_UPDATE] = 129 WMI_PEER_FT_ROAMING_PEER_UPDATE, 130 [WMI_HOST_PEER_PARAM_DMS_SUPPORT] = WMI_PEER_PARAM_DMS_SUPPORT, 131 }; 132 133 #define PARAM_MAP(name, NAME) [wmi_ ## name] = WMI_ ##NAME 134 135 /* Populate pdev_param whose index is host param and value is target */ 136 static const uint32_t pdev_param_tlv[] = { 137 PARAM_MAP(pdev_param_tx_chain_mask, PDEV_PARAM_TX_CHAIN_MASK), 138 PARAM_MAP(pdev_param_rx_chain_mask, PDEV_PARAM_RX_CHAIN_MASK), 139 PARAM_MAP(pdev_param_txpower_limit2g, PDEV_PARAM_TXPOWER_LIMIT2G), 140 PARAM_MAP(pdev_param_txpower_limit5g, PDEV_PARAM_TXPOWER_LIMIT5G), 141 PARAM_MAP(pdev_param_txpower_scale, PDEV_PARAM_TXPOWER_SCALE), 142 PARAM_MAP(pdev_param_beacon_gen_mode, PDEV_PARAM_BEACON_GEN_MODE), 143 PARAM_MAP(pdev_param_beacon_tx_mode, PDEV_PARAM_BEACON_TX_MODE), 144 PARAM_MAP(pdev_param_resmgr_offchan_mode, 145 PDEV_PARAM_RESMGR_OFFCHAN_MODE), 146 PARAM_MAP(pdev_param_protection_mode, PDEV_PARAM_PROTECTION_MODE), 147 PARAM_MAP(pdev_param_dynamic_bw, PDEV_PARAM_DYNAMIC_BW), 148 PARAM_MAP(pdev_param_non_agg_sw_retry_th, 149 PDEV_PARAM_NON_AGG_SW_RETRY_TH), 150 PARAM_MAP(pdev_param_agg_sw_retry_th, PDEV_PARAM_AGG_SW_RETRY_TH), 151 PARAM_MAP(pdev_param_sta_kickout_th, PDEV_PARAM_STA_KICKOUT_TH), 152 PARAM_MAP(pdev_param_ac_aggrsize_scaling, 153 PDEV_PARAM_AC_AGGRSIZE_SCALING), 154 PARAM_MAP(pdev_param_ltr_enable, PDEV_PARAM_LTR_ENABLE), 155 PARAM_MAP(pdev_param_ltr_ac_latency_be, 156 PDEV_PARAM_LTR_AC_LATENCY_BE), 157 PARAM_MAP(pdev_param_ltr_ac_latency_bk, PDEV_PARAM_LTR_AC_LATENCY_BK), 158 PARAM_MAP(pdev_param_ltr_ac_latency_vi, PDEV_PARAM_LTR_AC_LATENCY_VI), 159 PARAM_MAP(pdev_param_ltr_ac_latency_vo, PDEV_PARAM_LTR_AC_LATENCY_VO), 160 PARAM_MAP(pdev_param_ltr_ac_latency_timeout, 161 PDEV_PARAM_LTR_AC_LATENCY_TIMEOUT), 162 PARAM_MAP(pdev_param_ltr_sleep_override, PDEV_PARAM_LTR_SLEEP_OVERRIDE), 163 PARAM_MAP(pdev_param_ltr_rx_override, PDEV_PARAM_LTR_RX_OVERRIDE), 164 PARAM_MAP(pdev_param_ltr_tx_activity_timeout, 165 PDEV_PARAM_LTR_TX_ACTIVITY_TIMEOUT), 166 PARAM_MAP(pdev_param_l1ss_enable, PDEV_PARAM_L1SS_ENABLE), 167 PARAM_MAP(pdev_param_dsleep_enable, PDEV_PARAM_DSLEEP_ENABLE), 168 PARAM_MAP(pdev_param_pcielp_txbuf_flush, PDEV_PARAM_PCIELP_TXBUF_FLUSH), 169 PARAM_MAP(pdev_param_pcielp_txbuf_watermark, 170 PDEV_PARAM_PCIELP_TXBUF_WATERMARK), 171 PARAM_MAP(pdev_param_pcielp_txbuf_tmo_en, 172 PDEV_PARAM_PCIELP_TXBUF_TMO_EN), 173 PARAM_MAP(pdev_param_pcielp_txbuf_tmo_value, 174 PDEV_PARAM_PCIELP_TXBUF_TMO_VALUE), 175 PARAM_MAP(pdev_param_pdev_stats_update_period, 176 PDEV_PARAM_PDEV_STATS_UPDATE_PERIOD), 177 PARAM_MAP(pdev_param_vdev_stats_update_period, 178 PDEV_PARAM_VDEV_STATS_UPDATE_PERIOD), 179 PARAM_MAP(pdev_param_peer_stats_update_period, 180 PDEV_PARAM_PEER_STATS_UPDATE_PERIOD), 181 PARAM_MAP(pdev_param_bcnflt_stats_update_period, 182 PDEV_PARAM_BCNFLT_STATS_UPDATE_PERIOD), 183 PARAM_MAP(pdev_param_pmf_qos, PDEV_PARAM_PMF_QOS), 184 PARAM_MAP(pdev_param_arp_ac_override, PDEV_PARAM_ARP_AC_OVERRIDE), 185 PARAM_MAP(pdev_param_dcs, PDEV_PARAM_DCS), 186 PARAM_MAP(pdev_param_ani_enable, PDEV_PARAM_ANI_ENABLE), 187 PARAM_MAP(pdev_param_ani_poll_period, PDEV_PARAM_ANI_POLL_PERIOD), 188 PARAM_MAP(pdev_param_ani_listen_period, PDEV_PARAM_ANI_LISTEN_PERIOD), 189 PARAM_MAP(pdev_param_ani_ofdm_level, PDEV_PARAM_ANI_OFDM_LEVEL), 190 PARAM_MAP(pdev_param_ani_cck_level, PDEV_PARAM_ANI_CCK_LEVEL), 191 PARAM_MAP(pdev_param_dyntxchain, PDEV_PARAM_DYNTXCHAIN), 192 PARAM_MAP(pdev_param_proxy_sta, PDEV_PARAM_PROXY_STA), 193 PARAM_MAP(pdev_param_idle_ps_config, PDEV_PARAM_IDLE_PS_CONFIG), 194 PARAM_MAP(pdev_param_power_gating_sleep, PDEV_PARAM_POWER_GATING_SLEEP), 195 PARAM_MAP(pdev_param_rfkill_enable, PDEV_PARAM_RFKILL_ENABLE), 196 PARAM_MAP(pdev_param_burst_dur, PDEV_PARAM_BURST_DUR), 197 PARAM_MAP(pdev_param_burst_enable, PDEV_PARAM_BURST_ENABLE), 198 PARAM_MAP(pdev_param_hw_rfkill_config, PDEV_PARAM_HW_RFKILL_CONFIG), 199 PARAM_MAP(pdev_param_low_power_rf_enable, 200 PDEV_PARAM_LOW_POWER_RF_ENABLE), 201 PARAM_MAP(pdev_param_l1ss_track, PDEV_PARAM_L1SS_TRACK), 202 PARAM_MAP(pdev_param_hyst_en, PDEV_PARAM_HYST_EN), 203 PARAM_MAP(pdev_param_power_collapse_enable, 204 PDEV_PARAM_POWER_COLLAPSE_ENABLE), 205 PARAM_MAP(pdev_param_led_sys_state, PDEV_PARAM_LED_SYS_STATE), 206 PARAM_MAP(pdev_param_led_enable, PDEV_PARAM_LED_ENABLE), 207 PARAM_MAP(pdev_param_audio_over_wlan_latency, 208 PDEV_PARAM_AUDIO_OVER_WLAN_LATENCY), 209 PARAM_MAP(pdev_param_audio_over_wlan_enable, 210 PDEV_PARAM_AUDIO_OVER_WLAN_ENABLE), 211 PARAM_MAP(pdev_param_whal_mib_stats_update_enable, 212 PDEV_PARAM_WHAL_MIB_STATS_UPDATE_ENABLE), 213 PARAM_MAP(pdev_param_vdev_rate_stats_update_period, 214 PDEV_PARAM_VDEV_RATE_STATS_UPDATE_PERIOD), 215 PARAM_MAP(pdev_param_cts_cbw, PDEV_PARAM_CTS_CBW), 216 PARAM_MAP(pdev_param_wnts_config, PDEV_PARAM_WNTS_CONFIG), 217 PARAM_MAP(pdev_param_adaptive_early_rx_enable, 218 PDEV_PARAM_ADAPTIVE_EARLY_RX_ENABLE), 219 PARAM_MAP(pdev_param_adaptive_early_rx_min_sleep_slop, 220 PDEV_PARAM_ADAPTIVE_EARLY_RX_MIN_SLEEP_SLOP), 221 PARAM_MAP(pdev_param_adaptive_early_rx_inc_dec_step, 222 PDEV_PARAM_ADAPTIVE_EARLY_RX_INC_DEC_STEP), 223 PARAM_MAP(pdev_param_early_rx_fix_sleep_slop, 224 PDEV_PARAM_EARLY_RX_FIX_SLEEP_SLOP), 225 PARAM_MAP(pdev_param_bmiss_based_adaptive_bto_enable, 226 PDEV_PARAM_BMISS_BASED_ADAPTIVE_BTO_ENABLE), 227 PARAM_MAP(pdev_param_bmiss_bto_min_bcn_timeout, 228 PDEV_PARAM_BMISS_BTO_MIN_BCN_TIMEOUT), 229 PARAM_MAP(pdev_param_bmiss_bto_inc_dec_step, 230 PDEV_PARAM_BMISS_BTO_INC_DEC_STEP), 231 PARAM_MAP(pdev_param_bto_fix_bcn_timeout, 232 PDEV_PARAM_BTO_FIX_BCN_TIMEOUT), 233 PARAM_MAP(pdev_param_ce_based_adaptive_bto_enable, 234 PDEV_PARAM_CE_BASED_ADAPTIVE_BTO_ENABLE), 235 PARAM_MAP(pdev_param_ce_bto_combo_ce_value, 236 PDEV_PARAM_CE_BTO_COMBO_CE_VALUE), 237 PARAM_MAP(pdev_param_tx_chain_mask_2g, PDEV_PARAM_TX_CHAIN_MASK_2G), 238 PARAM_MAP(pdev_param_rx_chain_mask_2g, PDEV_PARAM_RX_CHAIN_MASK_2G), 239 PARAM_MAP(pdev_param_tx_chain_mask_5g, PDEV_PARAM_TX_CHAIN_MASK_5G), 240 PARAM_MAP(pdev_param_rx_chain_mask_5g, PDEV_PARAM_RX_CHAIN_MASK_5G), 241 PARAM_MAP(pdev_param_tx_chain_mask_cck, PDEV_PARAM_TX_CHAIN_MASK_CCK), 242 PARAM_MAP(pdev_param_tx_chain_mask_1ss, PDEV_PARAM_TX_CHAIN_MASK_1SS), 243 PARAM_MAP(pdev_param_soft_tx_chain_mask, PDEV_PARAM_TX_CHAIN_MASK), 244 PARAM_MAP(pdev_param_rx_filter, PDEV_PARAM_RX_FILTER), 245 PARAM_MAP(pdev_set_mcast_to_ucast_tid, PDEV_SET_MCAST_TO_UCAST_TID), 246 PARAM_MAP(pdev_param_mgmt_retry_limit, PDEV_PARAM_MGMT_RETRY_LIMIT), 247 PARAM_MAP(pdev_param_aggr_burst, PDEV_PARAM_AGGR_BURST), 248 PARAM_MAP(pdev_peer_sta_ps_statechg_enable, 249 PDEV_PEER_STA_PS_STATECHG_ENABLE), 250 PARAM_MAP(pdev_param_proxy_sta_mode, PDEV_PARAM_PROXY_STA_MODE), 251 PARAM_MAP(pdev_param_mu_group_policy, PDEV_PARAM_MU_GROUP_POLICY), 252 PARAM_MAP(pdev_param_noise_detection, PDEV_PARAM_NOISE_DETECTION), 253 PARAM_MAP(pdev_param_noise_threshold, PDEV_PARAM_NOISE_THRESHOLD), 254 PARAM_MAP(pdev_param_dpd_enable, PDEV_PARAM_DPD_ENABLE), 255 PARAM_MAP(pdev_param_set_mcast_bcast_echo, 256 PDEV_PARAM_SET_MCAST_BCAST_ECHO), 257 PARAM_MAP(pdev_param_atf_strict_sch, PDEV_PARAM_ATF_STRICT_SCH), 258 PARAM_MAP(pdev_param_atf_sched_duration, PDEV_PARAM_ATF_SCHED_DURATION), 259 PARAM_MAP(pdev_param_ant_plzn, PDEV_PARAM_ANT_PLZN), 260 PARAM_MAP(pdev_param_sensitivity_level, PDEV_PARAM_SENSITIVITY_LEVEL), 261 PARAM_MAP(pdev_param_signed_txpower_2g, PDEV_PARAM_SIGNED_TXPOWER_2G), 262 PARAM_MAP(pdev_param_signed_txpower_5g, PDEV_PARAM_SIGNED_TXPOWER_5G), 263 PARAM_MAP(pdev_param_enable_per_tid_amsdu, 264 PDEV_PARAM_ENABLE_PER_TID_AMSDU), 265 PARAM_MAP(pdev_param_enable_per_tid_ampdu, 266 PDEV_PARAM_ENABLE_PER_TID_AMPDU), 267 PARAM_MAP(pdev_param_cca_threshold, PDEV_PARAM_CCA_THRESHOLD), 268 PARAM_MAP(pdev_param_rts_fixed_rate, PDEV_PARAM_RTS_FIXED_RATE), 269 PARAM_MAP(pdev_param_cal_period, UNAVAILABLE_PARAM), 270 PARAM_MAP(pdev_param_pdev_reset, PDEV_PARAM_PDEV_RESET), 271 PARAM_MAP(pdev_param_wapi_mbssid_offset, PDEV_PARAM_WAPI_MBSSID_OFFSET), 272 PARAM_MAP(pdev_param_arp_srcaddr, PDEV_PARAM_ARP_DBG_SRCADDR), 273 PARAM_MAP(pdev_param_arp_dstaddr, PDEV_PARAM_ARP_DBG_DSTADDR), 274 PARAM_MAP(pdev_param_txpower_decr_db, PDEV_PARAM_TXPOWER_DECR_DB), 275 PARAM_MAP(pdev_param_rx_batchmode, UNAVAILABLE_PARAM), 276 PARAM_MAP(pdev_param_packet_aggr_delay, UNAVAILABLE_PARAM), 277 PARAM_MAP(pdev_param_atf_obss_noise_sch, PDEV_PARAM_ATF_OBSS_NOISE_SCH), 278 PARAM_MAP(pdev_param_atf_obss_noise_scaling_factor, 279 PDEV_PARAM_ATF_OBSS_NOISE_SCALING_FACTOR), 280 PARAM_MAP(pdev_param_cust_txpower_scale, PDEV_PARAM_CUST_TXPOWER_SCALE), 281 PARAM_MAP(pdev_param_atf_dynamic_enable, PDEV_PARAM_ATF_DYNAMIC_ENABLE), 282 PARAM_MAP(pdev_param_atf_ssid_group_policy, UNAVAILABLE_PARAM), 283 PARAM_MAP(pdev_param_igmpmld_override, PDEV_PARAM_IGMPMLD_AC_OVERRIDE), 284 PARAM_MAP(pdev_param_igmpmld_tid, PDEV_PARAM_IGMPMLD_AC_OVERRIDE), 285 PARAM_MAP(pdev_param_antenna_gain, PDEV_PARAM_ANTENNA_GAIN), 286 PARAM_MAP(pdev_param_block_interbss, PDEV_PARAM_BLOCK_INTERBSS), 287 PARAM_MAP(pdev_param_set_disable_reset_cmdid, 288 PDEV_PARAM_SET_DISABLE_RESET_CMDID), 289 PARAM_MAP(pdev_param_set_msdu_ttl_cmdid, PDEV_PARAM_SET_MSDU_TTL_CMDID), 290 PARAM_MAP(pdev_param_txbf_sound_period_cmdid, 291 PDEV_PARAM_TXBF_SOUND_PERIOD_CMDID), 292 PARAM_MAP(pdev_param_set_burst_mode_cmdid, 293 PDEV_PARAM_SET_BURST_MODE_CMDID), 294 PARAM_MAP(pdev_param_en_stats, PDEV_PARAM_EN_STATS), 295 PARAM_MAP(pdev_param_mesh_mcast_enable, PDEV_PARAM_MESH_MCAST_ENABLE), 296 PARAM_MAP(pdev_param_set_promisc_mode_cmdid, 297 PDEV_PARAM_SET_PROMISC_MODE_CMDID), 298 PARAM_MAP(pdev_param_set_ppdu_duration_cmdid, 299 PDEV_PARAM_SET_PPDU_DURATION_CMDID), 300 PARAM_MAP(pdev_param_remove_mcast2ucast_buffer, 301 PDEV_PARAM_REMOVE_MCAST2UCAST_BUFFER), 302 PARAM_MAP(pdev_param_set_mcast2ucast_buffer, 303 PDEV_PARAM_SET_MCAST2UCAST_BUFFER), 304 PARAM_MAP(pdev_param_set_mcast2ucast_mode, 305 PDEV_PARAM_SET_MCAST2UCAST_MODE), 306 PARAM_MAP(pdev_param_smart_antenna_default_antenna, 307 PDEV_PARAM_SMART_ANTENNA_DEFAULT_ANTENNA), 308 PARAM_MAP(pdev_param_fast_channel_reset, 309 PDEV_PARAM_FAST_CHANNEL_RESET), 310 PARAM_MAP(pdev_param_rx_decap_mode, PDEV_PARAM_RX_DECAP_MODE), 311 PARAM_MAP(pdev_param_tx_ack_timeout, PDEV_PARAM_ACK_TIMEOUT), 312 PARAM_MAP(pdev_param_cck_tx_enable, PDEV_PARAM_CCK_TX_ENABLE), 313 PARAM_MAP(pdev_param_antenna_gain_half_db, 314 PDEV_PARAM_ANTENNA_GAIN_HALF_DB), 315 PARAM_MAP(pdev_param_esp_indication_period, 316 PDEV_PARAM_ESP_INDICATION_PERIOD), 317 PARAM_MAP(pdev_param_esp_ba_window, PDEV_PARAM_ESP_BA_WINDOW), 318 PARAM_MAP(pdev_param_esp_airtime_fraction, 319 PDEV_PARAM_ESP_AIRTIME_FRACTION), 320 PARAM_MAP(pdev_param_esp_ppdu_duration, PDEV_PARAM_ESP_PPDU_DURATION), 321 PARAM_MAP(pdev_param_ru26_allowed, PDEV_PARAM_UL_RU26_ALLOWED), 322 PARAM_MAP(pdev_param_use_nol, PDEV_PARAM_USE_NOL), 323 PARAM_MAP(pdev_param_ul_trig_int, PDEV_PARAM_SET_UL_BSR_TRIG_INTERVAL), 324 PARAM_MAP(pdev_param_sub_channel_marking, 325 PDEV_PARAM_SUB_CHANNEL_MARKING), 326 PARAM_MAP(pdev_param_ul_ppdu_duration, PDEV_PARAM_SET_UL_PPDU_DURATION), 327 PARAM_MAP(pdev_param_equal_ru_allocation_enable, 328 PDEV_PARAM_EQUAL_RU_ALLOCATION_ENABLE), 329 PARAM_MAP(pdev_param_per_peer_prd_cfr_enable, 330 PDEV_PARAM_PER_PEER_PERIODIC_CFR_ENABLE), 331 PARAM_MAP(pdev_param_nav_override_config, 332 PDEV_PARAM_NAV_OVERRIDE_CONFIG), 333 PARAM_MAP(pdev_param_set_mgmt_ttl, PDEV_PARAM_SET_MGMT_TTL), 334 PARAM_MAP(pdev_param_set_prb_rsp_ttl, 335 PDEV_PARAM_SET_PROBE_RESP_TTL), 336 PARAM_MAP(pdev_param_set_mu_ppdu_duration, 337 PDEV_PARAM_SET_MU_PPDU_DURATION), 338 PARAM_MAP(pdev_param_set_tbtt_ctrl, 339 PDEV_PARAM_SET_TBTT_CTRL), 340 PARAM_MAP(pdev_param_set_cmd_obss_pd_threshold, 341 PDEV_PARAM_SET_CMD_OBSS_PD_THRESHOLD), 342 PARAM_MAP(pdev_param_set_cmd_obss_pd_per_ac, 343 PDEV_PARAM_SET_CMD_OBSS_PD_PER_AC), 344 PARAM_MAP(pdev_param_set_cong_ctrl_max_msdus, 345 PDEV_PARAM_SET_CONG_CTRL_MAX_MSDUS), 346 PARAM_MAP(pdev_param_enable_fw_dynamic_he_edca, 347 PDEV_PARAM_ENABLE_FW_DYNAMIC_HE_EDCA), 348 PARAM_MAP(pdev_param_enable_srp, PDEV_PARAM_ENABLE_SRP), 349 PARAM_MAP(pdev_param_enable_sr_prohibit, PDEV_PARAM_ENABLE_SR_PROHIBIT), 350 PARAM_MAP(pdev_param_sr_trigger_margin, PDEV_PARAM_SR_TRIGGER_MARGIN), 351 PARAM_MAP(pdev_param_pream_punct_bw, PDEV_PARAM_SET_PREAM_PUNCT_BW), 352 PARAM_MAP(pdev_param_enable_mbssid_ctrl_frame, 353 PDEV_PARAM_ENABLE_MBSSID_CTRL_FRAME), 354 PARAM_MAP(pdev_param_set_mesh_params, PDEV_PARAM_SET_MESH_PARAMS), 355 PARAM_MAP(pdev_param_mpd_userpd_ssr, PDEV_PARAM_MPD_USERPD_SSR), 356 PARAM_MAP(pdev_param_low_latency_mode, 357 PDEV_PARAM_LOW_LATENCY_SCHED_MODE), 358 PARAM_MAP(pdev_param_scan_radio_tx_on_dfs, 359 PDEV_PARAM_SCAN_RADIO_TX_ON_DFS), 360 PARAM_MAP(pdev_param_en_probe_all_bw, 361 PDEV_PARAM_EN_PROBE_ALL_BW), 362 PARAM_MAP(pdev_param_obss_min_duration_check_for_sr, 363 PDEV_PARAM_OBSS_MIN_DURATION_CHECK_FOR_SR), 364 PARAM_MAP(pdev_param_truncate_sr, PDEV_PARAM_TRUNCATE_SR), 365 PARAM_MAP(pdev_param_ctrl_frame_obss_pd_threshold, 366 PDEV_PARAM_CTRL_FRAME_OBSS_PD_THRESHOLD), 367 PARAM_MAP(pdev_param_rate_upper_cap, PDEV_PARAM_RATE_UPPER_CAP), 368 PARAM_MAP(pdev_param_set_disabled_sched_modes, 369 PDEV_PARAM_SET_DISABLED_SCHED_MODES), 370 PARAM_MAP(pdev_param_rate_retry_mcs_drop, 371 PDEV_PARAM_SET_RATE_DROP_DOWN_RETRY_THRESH), 372 PARAM_MAP(pdev_param_mcs_probe_intvl, 373 PDEV_PARAM_MIN_MAX_MCS_PROBE_INTERVAL), 374 PARAM_MAP(pdev_param_nss_probe_intvl, 375 PDEV_PARAM_MIN_MAX_NSS_PROBE_INTERVAL), 376 PARAM_MAP(pdev_param_dtim_synth, PDEV_PARAM_DTIM_SYNTH), 377 PARAM_MAP(pdev_param_1ch_dtim_optimized_chain_selection, 378 PDEV_PARAM_1CH_DTIM_OPTIMIZED_CHAIN_SELECTION), 379 PARAM_MAP(pdev_param_tx_sch_delay, PDEV_PARAM_TX_SCH_DELAY), 380 PARAM_MAP(pdev_param_en_update_scram_seed, 381 PDEV_PARAM_EN_UPDATE_SCRAM_SEED), 382 PARAM_MAP(pdev_param_secondary_retry_enable, 383 PDEV_PARAM_SECONDARY_RETRY_ENABLE), 384 PARAM_MAP(pdev_param_set_sap_xlna_bypass, 385 PDEV_PARAM_SET_SAP_XLNA_BYPASS), 386 PARAM_MAP(pdev_param_set_dfs_chan_ageout_time, 387 PDEV_PARAM_SET_DFS_CHAN_AGEOUT_TIME), 388 PARAM_MAP(pdev_param_pdev_stats_tx_xretry_ext, 389 PDEV_PARAM_PDEV_STATS_TX_XRETRY_EXT), 390 PARAM_MAP(pdev_param_smart_chainmask_scheme, 391 PDEV_PARAM_SMART_CHAINMASK_SCHEME), 392 PARAM_MAP(pdev_param_alternative_chainmask_scheme, 393 PDEV_PARAM_ALTERNATIVE_CHAINMASK_SCHEME), 394 PARAM_MAP(pdev_param_enable_rts_sifs_bursting, 395 PDEV_PARAM_ENABLE_RTS_SIFS_BURSTING), 396 PARAM_MAP(pdev_param_max_mpdus_in_ampdu, PDEV_PARAM_MAX_MPDUS_IN_AMPDU), 397 PARAM_MAP(pdev_param_set_iot_pattern, PDEV_PARAM_SET_IOT_PATTERN), 398 PARAM_MAP(pdev_param_mwscoex_scc_chavd_delay, 399 PDEV_PARAM_MWSCOEX_SCC_CHAVD_DELAY), 400 PARAM_MAP(pdev_param_mwscoex_pcc_chavd_delay, 401 PDEV_PARAM_MWSCOEX_PCC_CHAVD_DELAY), 402 PARAM_MAP(pdev_param_mwscoex_set_5gnr_pwr_limit, 403 PDEV_PARAM_MWSCOEX_SET_5GNR_PWR_LIMIT), 404 PARAM_MAP(pdev_param_mwscoex_4g_allow_quick_ftdm, 405 PDEV_PARAM_MWSCOEX_4G_ALLOW_QUICK_FTDM), 406 PARAM_MAP(pdev_param_fast_pwr_transition, 407 PDEV_PARAM_FAST_PWR_TRANSITION), 408 PARAM_MAP(pdev_auto_detect_power_failure, 409 PDEV_AUTO_DETECT_POWER_FAILURE), 410 PARAM_MAP(pdev_param_gcmp_support_enable, 411 PDEV_PARAM_GCMP_SUPPORT_ENABLE), 412 PARAM_MAP(pdev_param_abg_mode_tx_chain_num, 413 PDEV_PARAM_ABG_MODE_TX_CHAIN_NUM), 414 PARAM_MAP(pdev_param_peer_stats_info_enable, 415 PDEV_PARAM_PEER_STATS_INFO_ENABLE), 416 PARAM_MAP(pdev_param_enable_cck_txfir_override, 417 PDEV_PARAM_ENABLE_CCK_TXFIR_OVERRIDE), 418 PARAM_MAP(pdev_param_twt_ac_config, PDEV_PARAM_TWT_AC_CONFIG), 419 PARAM_MAP(pdev_param_pcie_hw_ilp, PDEV_PARAM_PCIE_HW_ILP), 420 PARAM_MAP(pdev_param_disable_hw_assist, PDEV_PARAM_DISABLE_HW_ASSIST), 421 PARAM_MAP(pdev_param_ant_div_usrcfg, PDEV_PARAM_ANT_DIV_USRCFG), 422 PARAM_MAP(pdev_param_ctrl_retry_limit, PDEV_PARAM_CTRL_RETRY_LIMIT), 423 PARAM_MAP(pdev_param_propagation_delay, PDEV_PARAM_PROPAGATION_DELAY), 424 PARAM_MAP(pdev_param_ena_ant_div, PDEV_PARAM_ENA_ANT_DIV), 425 PARAM_MAP(pdev_param_force_chain_ant, PDEV_PARAM_FORCE_CHAIN_ANT), 426 PARAM_MAP(pdev_param_ant_div_selftest, PDEV_PARAM_ANT_DIV_SELFTEST), 427 PARAM_MAP(pdev_param_ant_div_selftest_intvl, 428 PDEV_PARAM_ANT_DIV_SELFTEST_INTVL), 429 PARAM_MAP(pdev_param_1ch_dtim_optimized_chain_selection, 430 PDEV_PARAM_1CH_DTIM_OPTIMIZED_CHAIN_SELECTION), 431 PARAM_MAP(pdev_param_data_stall_detect_enable, 432 PDEV_PARAM_DATA_STALL_DETECT_ENABLE), 433 PARAM_MAP(pdev_param_max_mpdus_in_ampdu, 434 PDEV_PARAM_MAX_MPDUS_IN_AMPDU), 435 PARAM_MAP(pdev_param_stats_observation_period, 436 PDEV_PARAM_STATS_OBSERVATION_PERIOD), 437 PARAM_MAP(pdev_param_cts2self_for_p2p_go_config, 438 PDEV_PARAM_CTS2SELF_FOR_P2P_GO_CONFIG), 439 PARAM_MAP(pdev_param_txpower_reason_sar, PDEV_PARAM_TXPOWER_REASON_SAR), 440 PARAM_MAP(pdev_param_default_6ghz_rate, PDEV_PARAM_DEFAULT_6GHZ_RATE), 441 PARAM_MAP(pdev_param_scan_blanking_mode, 442 PDEV_PARAM_SET_SCAN_BLANKING_MODE), 443 PARAM_MAP(pdev_param_set_conc_low_latency_mode, 444 PDEV_PARAM_SET_CONC_LOW_LATENCY_MODE), 445 PARAM_MAP(pdev_param_rtt_11az_rsid_range, 446 PDEV_PARAM_RTT_11AZ_RSID_RANGE), 447 PARAM_MAP(pdev_param_pcie_config, PDEV_PARAM_PCIE_CONFIG), 448 PARAM_MAP(pdev_param_probe_resp_retry_limit, 449 PDEV_PARAM_PROBE_RESP_RETRY_LIMIT), 450 PARAM_MAP(pdev_param_cts_timeout, PDEV_PARAM_CTS_TIMEOUT), 451 PARAM_MAP(pdev_param_slot_time, PDEV_PARAM_SLOT_TIME), 452 PARAM_MAP(pdev_param_atf_vo_dedicated_time, 453 PDEV_PARAM_ATF_VO_DEDICATED_TIME), 454 PARAM_MAP(pdev_param_atf_vi_dedicated_time, 455 PDEV_PARAM_ATF_VI_DEDICATED_TIME), 456 }; 457 458 /* Populate vdev_param array whose index is host param, value is target param */ 459 static const uint32_t vdev_param_tlv[] = { 460 PARAM_MAP(vdev_param_rts_threshold, VDEV_PARAM_RTS_THRESHOLD), 461 PARAM_MAP(vdev_param_fragmentation_threshold, 462 VDEV_PARAM_FRAGMENTATION_THRESHOLD), 463 PARAM_MAP(vdev_param_beacon_interval, VDEV_PARAM_BEACON_INTERVAL), 464 PARAM_MAP(vdev_param_listen_interval, VDEV_PARAM_LISTEN_INTERVAL), 465 PARAM_MAP(vdev_param_multicast_rate, VDEV_PARAM_MULTICAST_RATE), 466 PARAM_MAP(vdev_param_mgmt_tx_rate, VDEV_PARAM_MGMT_TX_RATE), 467 PARAM_MAP(vdev_param_slot_time, VDEV_PARAM_SLOT_TIME), 468 PARAM_MAP(vdev_param_preamble, VDEV_PARAM_PREAMBLE), 469 PARAM_MAP(vdev_param_swba_time, VDEV_PARAM_SWBA_TIME), 470 PARAM_MAP(vdev_stats_update_period, VDEV_STATS_UPDATE_PERIOD), 471 PARAM_MAP(vdev_pwrsave_ageout_time, VDEV_PWRSAVE_AGEOUT_TIME), 472 PARAM_MAP(vdev_host_swba_interval, VDEV_HOST_SWBA_INTERVAL), 473 PARAM_MAP(vdev_param_dtim_period, VDEV_PARAM_DTIM_PERIOD), 474 PARAM_MAP(vdev_oc_scheduler_air_time_limit, 475 VDEV_OC_SCHEDULER_AIR_TIME_LIMIT), 476 PARAM_MAP(vdev_param_wds, VDEV_PARAM_WDS), 477 PARAM_MAP(vdev_param_atim_window, VDEV_PARAM_ATIM_WINDOW), 478 PARAM_MAP(vdev_param_bmiss_count_max, VDEV_PARAM_BMISS_COUNT_MAX), 479 PARAM_MAP(vdev_param_bmiss_first_bcnt, VDEV_PARAM_BMISS_FIRST_BCNT), 480 PARAM_MAP(vdev_param_bmiss_final_bcnt, VDEV_PARAM_BMISS_FINAL_BCNT), 481 PARAM_MAP(vdev_param_feature_wmm, VDEV_PARAM_FEATURE_WMM), 482 PARAM_MAP(vdev_param_chwidth, VDEV_PARAM_CHWIDTH), 483 PARAM_MAP(vdev_param_chextoffset, VDEV_PARAM_CHEXTOFFSET), 484 PARAM_MAP(vdev_param_disable_htprotection, 485 VDEV_PARAM_DISABLE_HTPROTECTION), 486 PARAM_MAP(vdev_param_sta_quickkickout, VDEV_PARAM_STA_QUICKKICKOUT), 487 PARAM_MAP(vdev_param_mgmt_rate, VDEV_PARAM_MGMT_RATE), 488 PARAM_MAP(vdev_param_protection_mode, VDEV_PARAM_PROTECTION_MODE), 489 PARAM_MAP(vdev_param_fixed_rate, VDEV_PARAM_FIXED_RATE), 490 PARAM_MAP(vdev_param_sgi, VDEV_PARAM_SGI), 491 PARAM_MAP(vdev_param_ldpc, VDEV_PARAM_LDPC), 492 PARAM_MAP(vdev_param_tx_stbc, VDEV_PARAM_TX_STBC), 493 PARAM_MAP(vdev_param_rx_stbc, VDEV_PARAM_RX_STBC), 494 PARAM_MAP(vdev_param_intra_bss_fwd, VDEV_PARAM_INTRA_BSS_FWD), 495 PARAM_MAP(vdev_param_def_keyid, VDEV_PARAM_DEF_KEYID), 496 PARAM_MAP(vdev_param_nss, VDEV_PARAM_NSS), 497 PARAM_MAP(vdev_param_bcast_data_rate, VDEV_PARAM_BCAST_DATA_RATE), 498 PARAM_MAP(vdev_param_mcast_data_rate, VDEV_PARAM_MCAST_DATA_RATE), 499 PARAM_MAP(vdev_param_mcast_indicate, VDEV_PARAM_MCAST_INDICATE), 500 PARAM_MAP(vdev_param_dhcp_indicate, VDEV_PARAM_DHCP_INDICATE), 501 PARAM_MAP(vdev_param_unknown_dest_indicate, 502 VDEV_PARAM_UNKNOWN_DEST_INDICATE), 503 PARAM_MAP(vdev_param_ap_keepalive_min_idle_inactive_time_secs, 504 VDEV_PARAM_AP_KEEPALIVE_MIN_IDLE_INACTIVE_TIME_SECS), 505 PARAM_MAP(vdev_param_ap_keepalive_max_idle_inactive_time_secs, 506 VDEV_PARAM_AP_KEEPALIVE_MAX_IDLE_INACTIVE_TIME_SECS), 507 PARAM_MAP(vdev_param_ap_keepalive_max_unresponsive_time_secs, 508 VDEV_PARAM_AP_KEEPALIVE_MAX_UNRESPONSIVE_TIME_SECS), 509 PARAM_MAP(vdev_param_ap_enable_nawds, VDEV_PARAM_AP_ENABLE_NAWDS), 510 PARAM_MAP(vdev_param_enable_rtscts, VDEV_PARAM_ENABLE_RTSCTS), 511 PARAM_MAP(vdev_param_txbf, VDEV_PARAM_TXBF), 512 PARAM_MAP(vdev_param_packet_powersave, VDEV_PARAM_PACKET_POWERSAVE), 513 PARAM_MAP(vdev_param_drop_unencry, VDEV_PARAM_DROP_UNENCRY), 514 PARAM_MAP(vdev_param_tx_encap_type, VDEV_PARAM_TX_ENCAP_TYPE), 515 PARAM_MAP(vdev_param_ap_detect_out_of_sync_sleeping_sta_time_secs, 516 VDEV_PARAM_AP_DETECT_OUT_OF_SYNC_SLEEPING_STA_TIME_SECS), 517 PARAM_MAP(vdev_param_early_rx_adjust_enable, 518 VDEV_PARAM_EARLY_RX_ADJUST_ENABLE), 519 PARAM_MAP(vdev_param_early_rx_tgt_bmiss_num, 520 VDEV_PARAM_EARLY_RX_TGT_BMISS_NUM), 521 PARAM_MAP(vdev_param_early_rx_bmiss_sample_cycle, 522 VDEV_PARAM_EARLY_RX_BMISS_SAMPLE_CYCLE), 523 PARAM_MAP(vdev_param_early_rx_slop_step, VDEV_PARAM_EARLY_RX_SLOP_STEP), 524 PARAM_MAP(vdev_param_early_rx_init_slop, VDEV_PARAM_EARLY_RX_INIT_SLOP), 525 PARAM_MAP(vdev_param_early_rx_adjust_pause, 526 VDEV_PARAM_EARLY_RX_ADJUST_PAUSE), 527 PARAM_MAP(vdev_param_tx_pwrlimit, VDEV_PARAM_TX_PWRLIMIT), 528 PARAM_MAP(vdev_param_snr_num_for_cal, VDEV_PARAM_SNR_NUM_FOR_CAL), 529 PARAM_MAP(vdev_param_roam_fw_offload, VDEV_PARAM_ROAM_FW_OFFLOAD), 530 PARAM_MAP(vdev_param_enable_rmc, VDEV_PARAM_ENABLE_RMC), 531 PARAM_MAP(vdev_param_ibss_max_bcn_lost_ms, 532 VDEV_PARAM_IBSS_MAX_BCN_LOST_MS), 533 PARAM_MAP(vdev_param_max_rate, VDEV_PARAM_MAX_RATE), 534 PARAM_MAP(vdev_param_early_rx_drift_sample, 535 VDEV_PARAM_EARLY_RX_DRIFT_SAMPLE), 536 PARAM_MAP(vdev_param_set_ibss_tx_fail_cnt_thr, 537 VDEV_PARAM_SET_IBSS_TX_FAIL_CNT_THR), 538 PARAM_MAP(vdev_param_ebt_resync_timeout, 539 VDEV_PARAM_EBT_RESYNC_TIMEOUT), 540 PARAM_MAP(vdev_param_aggr_trig_event_enable, 541 VDEV_PARAM_AGGR_TRIG_EVENT_ENABLE), 542 PARAM_MAP(vdev_param_is_ibss_power_save_allowed, 543 VDEV_PARAM_IS_IBSS_POWER_SAVE_ALLOWED), 544 PARAM_MAP(vdev_param_is_power_collapse_allowed, 545 VDEV_PARAM_IS_POWER_COLLAPSE_ALLOWED), 546 PARAM_MAP(vdev_param_is_awake_on_txrx_enabled, 547 VDEV_PARAM_IS_AWAKE_ON_TXRX_ENABLED), 548 PARAM_MAP(vdev_param_inactivity_cnt, VDEV_PARAM_INACTIVITY_CNT), 549 PARAM_MAP(vdev_param_txsp_end_inactivity_time_ms, 550 VDEV_PARAM_TXSP_END_INACTIVITY_TIME_MS), 551 PARAM_MAP(vdev_param_dtim_policy, VDEV_PARAM_DTIM_POLICY), 552 PARAM_MAP(vdev_param_ibss_ps_warmup_time_secs, 553 VDEV_PARAM_IBSS_PS_WARMUP_TIME_SECS), 554 PARAM_MAP(vdev_param_ibss_ps_1rx_chain_in_atim_window_enable, 555 VDEV_PARAM_IBSS_PS_1RX_CHAIN_IN_ATIM_WINDOW_ENABLE), 556 PARAM_MAP(vdev_param_rx_leak_window, VDEV_PARAM_RX_LEAK_WINDOW), 557 PARAM_MAP(vdev_param_stats_avg_factor, 558 VDEV_PARAM_STATS_AVG_FACTOR), 559 PARAM_MAP(vdev_param_disconnect_th, VDEV_PARAM_DISCONNECT_TH), 560 PARAM_MAP(vdev_param_rtscts_rate, VDEV_PARAM_RTSCTS_RATE), 561 PARAM_MAP(vdev_param_mcc_rtscts_protection_enable, 562 VDEV_PARAM_MCC_RTSCTS_PROTECTION_ENABLE), 563 PARAM_MAP(vdev_param_mcc_broadcast_probe_enable, 564 VDEV_PARAM_MCC_BROADCAST_PROBE_ENABLE), 565 PARAM_MAP(vdev_param_mgmt_tx_power, VDEV_PARAM_MGMT_TX_POWER), 566 PARAM_MAP(vdev_param_beacon_rate, VDEV_PARAM_BEACON_RATE), 567 PARAM_MAP(vdev_param_rx_decap_type, VDEV_PARAM_RX_DECAP_TYPE), 568 PARAM_MAP(vdev_param_he_dcm_enable, VDEV_PARAM_HE_DCM), 569 PARAM_MAP(vdev_param_he_range_ext_enable, VDEV_PARAM_HE_RANGE_EXT), 570 PARAM_MAP(vdev_param_he_bss_color, VDEV_PARAM_BSS_COLOR), 571 PARAM_MAP(vdev_param_set_hemu_mode, VDEV_PARAM_SET_HEMU_MODE), 572 PARAM_MAP(vdev_param_set_he_sounding_mode, 573 VDEV_PARAM_SET_HE_SOUNDING_MODE), 574 PARAM_MAP(vdev_param_set_heop, VDEV_PARAM_HEOPS_0_31), 575 PARAM_MAP(vdev_param_set_ehtop, VDEV_PARAM_EHTOPS_0_31), 576 PARAM_MAP(vdev_param_set_eht_mu_mode, VDEV_PARAM_SET_EHT_MU_MODE), 577 PARAM_MAP(vdev_param_set_eht_puncturing_mode, 578 VDEV_PARAM_SET_EHT_PUNCTURING_MODE), 579 PARAM_MAP(vdev_param_set_eht_ltf, VDEV_PARAM_EHT_LTF), 580 PARAM_MAP(vdev_param_set_ul_eht_ltf, VDEV_PARAM_UL_EHT_LTF), 581 PARAM_MAP(vdev_param_set_eht_dcm, VDEV_PARAM_EHT_DCM), 582 PARAM_MAP(vdev_param_set_eht_range_ext, VDEV_PARAM_EHT_RANGE_EXT), 583 PARAM_MAP(vdev_param_set_non_data_eht_range_ext, 584 VDEV_PARAM_NON_DATA_EHT_RANGE_EXT), 585 PARAM_MAP(vdev_param_sensor_ap, VDEV_PARAM_SENSOR_AP), 586 PARAM_MAP(vdev_param_dtim_enable_cts, VDEV_PARAM_DTIM_ENABLE_CTS), 587 PARAM_MAP(vdev_param_atf_ssid_sched_policy, 588 VDEV_PARAM_ATF_SSID_SCHED_POLICY), 589 PARAM_MAP(vdev_param_disable_dyn_bw_rts, VDEV_PARAM_DISABLE_DYN_BW_RTS), 590 PARAM_MAP(vdev_param_mcast2ucast_set, VDEV_PARAM_MCAST2UCAST_SET), 591 PARAM_MAP(vdev_param_rc_num_retries, VDEV_PARAM_RC_NUM_RETRIES), 592 PARAM_MAP(vdev_param_cabq_maxdur, VDEV_PARAM_CABQ_MAXDUR), 593 PARAM_MAP(vdev_param_mfptest_set, VDEV_PARAM_MFPTEST_SET), 594 PARAM_MAP(vdev_param_rts_fixed_rate, VDEV_PARAM_RTS_FIXED_RATE), 595 PARAM_MAP(vdev_param_vht_sgimask, VDEV_PARAM_VHT_SGIMASK), 596 PARAM_MAP(vdev_param_vht80_ratemask, VDEV_PARAM_VHT80_RATEMASK), 597 PARAM_MAP(vdev_param_proxy_sta, VDEV_PARAM_PROXY_STA), 598 PARAM_MAP(vdev_param_bw_nss_ratemask, VDEV_PARAM_BW_NSS_RATEMASK), 599 PARAM_MAP(vdev_param_set_he_ltf, VDEV_PARAM_HE_LTF), 600 PARAM_MAP(vdev_param_disable_cabq, VDEV_PARAM_DISABLE_CABQ), 601 PARAM_MAP(vdev_param_rate_dropdown_bmap, VDEV_PARAM_RATE_DROPDOWN_BMAP), 602 PARAM_MAP(vdev_param_set_ba_mode, VDEV_PARAM_BA_MODE), 603 PARAM_MAP(vdev_param_capabilities, VDEV_PARAM_CAPABILITIES), 604 PARAM_MAP(vdev_param_autorate_misc_cfg, VDEV_PARAM_AUTORATE_MISC_CFG), 605 PARAM_MAP(vdev_param_ul_shortgi, VDEV_PARAM_UL_GI), 606 PARAM_MAP(vdev_param_ul_he_ltf, VDEV_PARAM_UL_HE_LTF), 607 PARAM_MAP(vdev_param_ul_nss, VDEV_PARAM_UL_NSS), 608 PARAM_MAP(vdev_param_ul_ppdu_bw, VDEV_PARAM_UL_PPDU_BW), 609 PARAM_MAP(vdev_param_ul_ldpc, VDEV_PARAM_UL_LDPC), 610 PARAM_MAP(vdev_param_ul_stbc, VDEV_PARAM_UL_STBC), 611 PARAM_MAP(vdev_param_ul_fixed_rate, VDEV_PARAM_UL_FIXED_RATE), 612 PARAM_MAP(vdev_param_rawmode_open_war, VDEV_PARAM_RAW_IS_ENCRYPTED), 613 PARAM_MAP(vdev_param_max_mtu_size, VDEV_PARAM_MAX_MTU_SIZE), 614 PARAM_MAP(vdev_param_mcast_rc_stale_period, 615 VDEV_PARAM_MCAST_RC_STALE_PERIOD), 616 PARAM_MAP(vdev_param_enable_multi_group_key, 617 VDEV_PARAM_ENABLE_MULTI_GROUP_KEY), 618 PARAM_MAP(vdev_param_max_group_keys, VDEV_PARAM_NUM_GROUP_KEYS), 619 PARAM_MAP(vdev_param_enable_mcast_rc, VDEV_PARAM_ENABLE_MCAST_RC), 620 PARAM_MAP(vdev_param_6ghz_params, VDEV_PARAM_6GHZ_PARAMS), 621 PARAM_MAP(vdev_param_enable_disable_roam_reason_vsie, 622 VDEV_PARAM_ENABLE_DISABLE_ROAM_REASON_VSIE), 623 PARAM_MAP(vdev_param_set_cmd_obss_pd_threshold, 624 VDEV_PARAM_SET_CMD_OBSS_PD_THRESHOLD), 625 PARAM_MAP(vdev_param_set_cmd_obss_pd_per_ac, 626 VDEV_PARAM_SET_CMD_OBSS_PD_PER_AC), 627 PARAM_MAP(vdev_param_enable_srp, VDEV_PARAM_ENABLE_SRP), 628 PARAM_MAP(vdev_param_nan_config_features, 629 VDEV_PARAM_ENABLE_DISABLE_NAN_CONFIG_FEATURES), 630 PARAM_MAP(vdev_param_enable_disable_rtt_responder_role, 631 VDEV_PARAM_ENABLE_DISABLE_RTT_RESPONDER_ROLE), 632 PARAM_MAP(vdev_param_enable_disable_rtt_initiator_role, 633 VDEV_PARAM_ENABLE_DISABLE_RTT_INITIATOR_ROLE), 634 PARAM_MAP(vdev_param_mcast_steer, VDEV_PARAM_MCAST_STEERING), 635 PARAM_MAP(vdev_param_set_normal_latency_flags_config, 636 VDEV_PARAM_NORMAL_LATENCY_FLAGS_CONFIGURATION), 637 PARAM_MAP(vdev_param_set_xr_latency_flags_config, 638 VDEV_PARAM_XR_LATENCY_FLAGS_CONFIGURATION), 639 PARAM_MAP(vdev_param_set_low_latency_flags_config, 640 VDEV_PARAM_LOW_LATENCY_FLAGS_CONFIGURATION), 641 PARAM_MAP(vdev_param_set_ultra_low_latency_flags_config, 642 VDEV_PARAM_ULTRA_LOW_LATENCY_FLAGS_CONFIGURATION), 643 PARAM_MAP(vdev_param_set_normal_latency_ul_dl_config, 644 VDEV_PARAM_NORMAL_LATENCY_UL_DL_CONFIGURATION), 645 PARAM_MAP(vdev_param_set_xr_latency_ul_dl_config, 646 VDEV_PARAM_XR_LATENCY_UL_DL_CONFIGURATION), 647 PARAM_MAP(vdev_param_set_low_latency_ul_dl_config, 648 VDEV_PARAM_LOW_LATENCY_UL_DL_CONFIGURATION), 649 PARAM_MAP(vdev_param_set_ultra_low_latency_ul_dl_config, 650 VDEV_PARAM_ULTRA_LOW_LATENCY_UL_DL_CONFIGURATION), 651 PARAM_MAP(vdev_param_set_default_ll_config, 652 VDEV_PARAM_DEFAULT_LATENCY_LEVEL_CONFIGURATION), 653 PARAM_MAP(vdev_param_set_multi_client_ll_feature_config, 654 VDEV_PARAM_MULTI_CLIENT_LL_FEATURE_CONFIGURATION), 655 PARAM_MAP(vdev_param_set_traffic_config, 656 VDEV_PARAM_VDEV_TRAFFIC_CONFIG), 657 PARAM_MAP(vdev_param_he_range_ext, VDEV_PARAM_HE_RANGE_EXT), 658 PARAM_MAP(vdev_param_non_data_he_range_ext, 659 VDEV_PARAM_NON_DATA_HE_RANGE_EXT), 660 PARAM_MAP(vdev_param_ndp_inactivity_timeout, 661 VDEV_PARAM_NDP_INACTIVITY_TIMEOUT), 662 PARAM_MAP(vdev_param_ndp_keepalive_timeout, 663 VDEV_PARAM_NDP_KEEPALIVE_TIMEOUT), 664 PARAM_MAP(vdev_param_final_bmiss_time_sec, 665 VDEV_PARAM_FINAL_BMISS_TIME_SEC), 666 PARAM_MAP(vdev_param_final_bmiss_time_wow_sec, 667 VDEV_PARAM_FINAL_BMISS_TIME_WOW_SEC), 668 PARAM_MAP(vdev_param_ap_keepalive_max_idle_inactive_secs, 669 VDEV_PARAM_AP_KEEPALIVE_MAX_IDLE_INACTIVE_TIME_SECS), 670 PARAM_MAP(vdev_param_per_band_mgmt_tx_rate, 671 VDEV_PARAM_PER_BAND_MGMT_TX_RATE), 672 PARAM_MAP(vdev_param_max_li_of_moddtim, 673 VDEV_PARAM_MAX_LI_OF_MODDTIM), 674 PARAM_MAP(vdev_param_moddtim_cnt, VDEV_PARAM_MODDTIM_CNT), 675 PARAM_MAP(vdev_param_max_li_of_moddtim_ms, 676 VDEV_PARAM_MAX_LI_OF_MODDTIM_MS), 677 PARAM_MAP(vdev_param_dyndtim_cnt, VDEV_PARAM_DYNDTIM_CNT), 678 PARAM_MAP(vdev_param_wmm_txop_enable, VDEV_PARAM_WMM_TXOP_ENABLE), 679 PARAM_MAP(vdev_param_enable_bcast_probe_response, 680 VDEV_PARAM_ENABLE_BCAST_PROBE_RESPONSE), 681 PARAM_MAP(vdev_param_fils_max_channel_guard_time, 682 VDEV_PARAM_FILS_MAX_CHANNEL_GUARD_TIME), 683 PARAM_MAP(vdev_param_probe_delay, VDEV_PARAM_PROBE_DELAY), 684 PARAM_MAP(vdev_param_repeat_probe_time, VDEV_PARAM_REPEAT_PROBE_TIME), 685 PARAM_MAP(vdev_param_enable_disable_oce_features, 686 VDEV_PARAM_ENABLE_DISABLE_OCE_FEATURES), 687 PARAM_MAP(vdev_param_enable_disable_nan_config_features, 688 VDEV_PARAM_ENABLE_DISABLE_NAN_CONFIG_FEATURES), 689 PARAM_MAP(vdev_param_rsn_capability, VDEV_PARAM_RSN_CAPABILITY), 690 PARAM_MAP(vdev_param_smps_intolerant, VDEV_PARAM_SMPS_INTOLERANT), 691 PARAM_MAP(vdev_param_abg_mode_tx_chain_num, 692 VDEV_PARAM_ABG_MODE_TX_CHAIN_NUM), 693 PARAM_MAP(vdev_param_nth_beacon_to_host, VDEV_PARAM_NTH_BEACON_TO_HOST), 694 PARAM_MAP(vdev_param_prohibit_data_mgmt, VDEV_PARAM_PROHIBIT_DATA_MGMT), 695 PARAM_MAP(vdev_param_skip_roam_eapol_4way_handshake, 696 VDEV_PARAM_SKIP_ROAM_EAPOL_4WAY_HANDSHAKE), 697 PARAM_MAP(vdev_param_skip_sae_roam_4way_handshake, 698 VDEV_PARAM_SKIP_SAE_ROAM_4WAY_HANDSHAKE), 699 PARAM_MAP(vdev_param_roam_11kv_ctrl, VDEV_PARAM_ROAM_11KV_CTRL), 700 PARAM_MAP(vdev_param_disable_noa_p2p_go, VDEV_PARAM_DISABLE_NOA_P2P_GO), 701 PARAM_MAP(vdev_param_packet_capture_mode, 702 VDEV_PARAM_PACKET_CAPTURE_MODE), 703 PARAM_MAP(vdev_param_smart_monitor_config, 704 VDEV_PARAM_SMART_MONITOR_CONFIG), 705 PARAM_MAP(vdev_param_force_dtim_cnt, VDEV_PARAM_FORCE_DTIM_CNT), 706 PARAM_MAP(vdev_param_sho_config, VDEV_PARAM_SHO_CONFIG), 707 PARAM_MAP(vdev_param_gtx_enable, VDEV_PARAM_GTX_ENABLE), 708 PARAM_MAP(vdev_param_mu_edca_fw_update_en, 709 VDEV_PARAM_MU_EDCA_FW_UPDATE_EN), 710 PARAM_MAP(vdev_param_enable_disable_rtt_initiator_random_mac, 711 VDEV_PARAM_ENABLE_DISABLE_RTT_INITIATOR_RANDOM_MAC), 712 PARAM_MAP(vdev_param_allow_nan_initial_discovery_of_mp0_cluster, 713 VDEV_PARAM_ALLOW_NAN_INITIAL_DISCOVERY_OF_MP0_CLUSTER), 714 PARAM_MAP(vdev_param_txpower_scale_decr_db, 715 VDEV_PARAM_TXPOWER_SCALE_DECR_DB), 716 PARAM_MAP(vdev_param_txpower_scale, VDEV_PARAM_TXPOWER_SCALE), 717 PARAM_MAP(vdev_param_agg_sw_retry_th, VDEV_PARAM_AGG_SW_RETRY_TH), 718 PARAM_MAP(vdev_param_obsspd, VDEV_PARAM_OBSSPD), 719 PARAM_MAP(vdev_param_amsdu_aggregation_size_optimization, 720 VDEV_PARAM_AMSDU_AGGREGATION_SIZE_OPTIMIZATION), 721 PARAM_MAP(vdev_param_non_agg_sw_retry_th, 722 VDEV_PARAM_NON_AGG_SW_RETRY_TH), 723 PARAM_MAP(vdev_param_set_cmd_obss_pd_threshold, 724 VDEV_PARAM_SET_CMD_OBSS_PD_THRESHOLD), 725 PARAM_MAP(vdev_param_set_profile, 726 VDEV_PARAM_SET_PROFILE), 727 PARAM_MAP(vdev_param_set_disabled_modes, 728 VDEV_PARAM_SET_DISABLED_SCHED_MODES), 729 PARAM_MAP(vdev_param_set_sap_ps_with_twt, 730 VDEV_PARAM_SET_SAP_PS_WITH_TWT), 731 PARAM_MAP(vdev_param_rtt_11az_tb_max_session_expiry, 732 VDEV_PARAM_RTT_11AZ_TB_MAX_SESSION_EXPIRY), 733 PARAM_MAP(vdev_param_wifi_standard_version, 734 VDEV_PARAM_WIFI_STANDARD_VERSION), 735 PARAM_MAP(vdev_param_rtt_11az_ntb_max_time_bw_meas, 736 VDEV_PARAM_RTT_11AZ_NTB_MAX_TIME_BW_MEAS), 737 PARAM_MAP(vdev_param_rtt_11az_ntb_min_time_bw_meas, 738 VDEV_PARAM_RTT_11AZ_NTB_MIN_TIME_BW_MEAS), 739 PARAM_MAP(vdev_param_11az_security_config, 740 VDEV_PARAM_11AZ_SECURITY_CONFIG), 741 }; 742 #endif 743 744 #ifndef WMI_PKTLOG_EVENT_CBF 745 #define WMI_PKTLOG_EVENT_CBF 0x100 746 #endif 747 748 /* 749 * Populate the pktlog event tlv array, where 750 * the values are the FW WMI events, which host 751 * uses to communicate with FW for pktlog 752 */ 753 754 static const uint32_t pktlog_event_tlv[] = { 755 [WMI_HOST_PKTLOG_EVENT_RX_BIT] = WMI_PKTLOG_EVENT_RX, 756 [WMI_HOST_PKTLOG_EVENT_TX_BIT] = WMI_PKTLOG_EVENT_TX, 757 [WMI_HOST_PKTLOG_EVENT_RCF_BIT] = WMI_PKTLOG_EVENT_RCF, 758 [WMI_HOST_PKTLOG_EVENT_RCU_BIT] = WMI_PKTLOG_EVENT_RCU, 759 [WMI_HOST_PKTLOG_EVENT_DBG_PRINT_BIT] = 0, 760 [WMI_HOST_PKTLOG_EVENT_SMART_ANTENNA_BIT] = 761 WMI_PKTLOG_EVENT_SMART_ANTENNA, 762 [WMI_HOST_PKTLOG_EVENT_H_INFO_BIT] = 0, 763 [WMI_HOST_PKTLOG_EVENT_STEERING_BIT] = 0, 764 [WMI_HOST_PKTLOG_EVENT_TX_DATA_CAPTURE_BIT] = 0, 765 [WMI_HOST_PKTLOG_EVENT_PHY_LOGGING_BIT] = WMI_PKTLOG_EVENT_PHY, 766 [WMI_HOST_PKTLOG_EVENT_CBF_BIT] = WMI_PKTLOG_EVENT_CBF, 767 #ifdef BE_PKTLOG_SUPPORT 768 [WMI_HOST_PKTLOG_EVENT_HYBRID_TX_BIT] = WMI_PKTLOG_EVENT_HYBRID_TX, 769 #endif 770 }; 771 772 /** 773 * convert_host_pdev_id_to_target_pdev_id() - Convert pdev_id from 774 * host to target defines. 775 * @wmi_handle: pointer to wmi_handle 776 * @pdev_id: host pdev_id to be converted. 777 * Return: target pdev_id after conversion. 778 */ 779 static uint32_t convert_host_pdev_id_to_target_pdev_id(wmi_unified_t wmi_handle, 780 uint32_t pdev_id) 781 { 782 if (pdev_id <= WMI_HOST_PDEV_ID_2 && pdev_id >= WMI_HOST_PDEV_ID_0) { 783 if (!wmi_handle->soc->is_pdev_is_map_enable) { 784 switch (pdev_id) { 785 case WMI_HOST_PDEV_ID_0: 786 return WMI_PDEV_ID_1ST; 787 case WMI_HOST_PDEV_ID_1: 788 return WMI_PDEV_ID_2ND; 789 case WMI_HOST_PDEV_ID_2: 790 return WMI_PDEV_ID_3RD; 791 } 792 } else { 793 return wmi_handle->cmd_pdev_id_map[pdev_id]; 794 } 795 } else { 796 return WMI_PDEV_ID_SOC; 797 } 798 799 QDF_ASSERT(0); 800 801 return WMI_PDEV_ID_SOC; 802 } 803 804 /** 805 * convert_target_pdev_id_to_host_pdev_id() - Convert pdev_id from 806 * target to host defines. 807 * @wmi_handle: pointer to wmi_handle 808 * @pdev_id: target pdev_id to be converted. 809 * Return: host pdev_id after conversion. 810 */ 811 static uint32_t convert_target_pdev_id_to_host_pdev_id(wmi_unified_t wmi_handle, 812 uint32_t pdev_id) 813 { 814 815 if (pdev_id <= WMI_PDEV_ID_3RD && pdev_id >= WMI_PDEV_ID_1ST) { 816 if (!wmi_handle->soc->is_pdev_is_map_enable) { 817 switch (pdev_id) { 818 case WMI_PDEV_ID_1ST: 819 return WMI_HOST_PDEV_ID_0; 820 case WMI_PDEV_ID_2ND: 821 return WMI_HOST_PDEV_ID_1; 822 case WMI_PDEV_ID_3RD: 823 return WMI_HOST_PDEV_ID_2; 824 } 825 } else { 826 return wmi_handle->evt_pdev_id_map[pdev_id - 1]; 827 } 828 } else if (pdev_id == WMI_PDEV_ID_SOC) { 829 return WMI_HOST_PDEV_ID_SOC; 830 } else { 831 wmi_err("Invalid pdev_id"); 832 } 833 834 return WMI_HOST_PDEV_ID_INVALID; 835 } 836 837 /** 838 * convert_host_phy_id_to_target_phy_id() - Convert phy_id from 839 * host to target defines. 840 * @wmi_handle: pointer to wmi_handle 841 * @phy_id: host pdev_id to be converted. 842 * Return: target phy_id after conversion. 843 */ 844 static uint32_t convert_host_phy_id_to_target_phy_id(wmi_unified_t wmi_handle, 845 uint32_t phy_id) 846 { 847 if (!wmi_handle->soc->is_phy_id_map_enable || 848 phy_id >= WMI_MAX_RADIOS) { 849 return phy_id; 850 } 851 852 return wmi_handle->cmd_phy_id_map[phy_id]; 853 } 854 855 /** 856 * convert_target_phy_id_to_host_phy_id() - Convert phy_id from 857 * target to host defines. 858 * @wmi_handle: pointer to wmi_handle 859 * @phy_id: target phy_id to be converted. 860 * Return: host phy_id after conversion. 861 */ 862 static uint32_t convert_target_phy_id_to_host_phy_id(wmi_unified_t wmi_handle, 863 uint32_t phy_id) 864 { 865 if (!wmi_handle->soc->is_phy_id_map_enable || 866 phy_id >= WMI_MAX_RADIOS) { 867 return phy_id; 868 } 869 870 return wmi_handle->evt_phy_id_map[phy_id]; 871 } 872 873 /** 874 * wmi_tlv_pdev_id_conversion_enable() - Enable pdev_id conversion 875 * @wmi_handle: WMI handle 876 * @pdev_id_map: pointer to mapping table 877 * @size: number of entries in @pdev_id_map 878 * 879 * Return: None. 880 */ 881 static void wmi_tlv_pdev_id_conversion_enable(wmi_unified_t wmi_handle, 882 uint32_t *pdev_id_map, 883 uint8_t size) 884 { 885 int i = 0; 886 887 if (pdev_id_map && (size <= WMI_MAX_RADIOS)) { 888 for (i = 0; i < size; i++) { 889 wmi_handle->cmd_pdev_id_map[i] = pdev_id_map[i]; 890 wmi_handle->evt_pdev_id_map[i] = 891 WMI_HOST_PDEV_ID_INVALID; 892 wmi_handle->cmd_phy_id_map[i] = pdev_id_map[i] - 1; 893 wmi_handle->evt_phy_id_map[i] = 894 WMI_HOST_PDEV_ID_INVALID; 895 } 896 897 for (i = 0; i < size; i++) { 898 if (wmi_handle->cmd_pdev_id_map[i] != 899 WMI_HOST_PDEV_ID_INVALID) { 900 wmi_handle->evt_pdev_id_map 901 [wmi_handle->cmd_pdev_id_map[i] - 1] = i; 902 } 903 if (wmi_handle->cmd_phy_id_map[i] != 904 WMI_HOST_PDEV_ID_INVALID) { 905 wmi_handle->evt_phy_id_map 906 [wmi_handle->cmd_phy_id_map[i]] = i; 907 } 908 } 909 wmi_handle->soc->is_pdev_is_map_enable = true; 910 wmi_handle->soc->is_phy_id_map_enable = true; 911 } else { 912 wmi_handle->soc->is_pdev_is_map_enable = false; 913 wmi_handle->soc->is_phy_id_map_enable = false; 914 } 915 916 wmi_handle->ops->convert_pdev_id_host_to_target = 917 convert_host_pdev_id_to_target_pdev_id; 918 wmi_handle->ops->convert_pdev_id_target_to_host = 919 convert_target_pdev_id_to_host_pdev_id; 920 921 /* phy_id convert function assignments */ 922 wmi_handle->ops->convert_phy_id_host_to_target = 923 convert_host_phy_id_to_target_phy_id; 924 wmi_handle->ops->convert_phy_id_target_to_host = 925 convert_target_phy_id_to_host_phy_id; 926 } 927 928 /* copy_vdev_create_pdev_id() - copy pdev from host params to target command 929 * buffer. 930 * @wmi_handle: pointer to wmi_handle 931 * @cmd: pointer target vdev create command buffer 932 * @param: pointer host params for vdev create 933 * 934 * Return: None 935 */ 936 static inline void copy_vdev_create_pdev_id( 937 struct wmi_unified *wmi_handle, 938 wmi_vdev_create_cmd_fixed_param * cmd, 939 struct vdev_create_params *param) 940 { 941 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 942 wmi_handle, 943 param->pdev_id); 944 } 945 946 void wmi_mtrace(uint32_t message_id, uint16_t vdev_id, uint32_t data) 947 { 948 uint16_t mtrace_message_id; 949 950 mtrace_message_id = QDF_WMI_MTRACE_CMD_ID(message_id) | 951 (QDF_WMI_MTRACE_GRP_ID(message_id) << 952 QDF_WMI_MTRACE_CMD_NUM_BITS); 953 qdf_mtrace(QDF_MODULE_ID_WMI, QDF_MODULE_ID_TARGET, 954 mtrace_message_id, vdev_id, data); 955 } 956 qdf_export_symbol(wmi_mtrace); 957 958 QDF_STATUS wmi_unified_cmd_send_pm_chk(struct wmi_unified *wmi_handle, 959 wmi_buf_t buf, 960 uint32_t buflen, uint32_t cmd_id, 961 bool is_qmi_send_support) 962 { 963 if (!is_qmi_send_support) 964 goto send_over_wmi; 965 966 if (!wmi_is_qmi_stats_enabled(wmi_handle)) 967 goto send_over_wmi; 968 969 if (wmi_is_target_suspended(wmi_handle)) { 970 if (QDF_IS_STATUS_SUCCESS( 971 wmi_unified_cmd_send_over_qmi(wmi_handle, buf, 972 buflen, cmd_id))) 973 return QDF_STATUS_SUCCESS; 974 } 975 976 send_over_wmi: 977 qdf_atomic_set(&wmi_handle->num_stats_over_qmi, 0); 978 979 return wmi_unified_cmd_send(wmi_handle, buf, buflen, cmd_id); 980 } 981 982 /** 983 * send_vdev_create_cmd_tlv() - send VDEV create command to fw 984 * @wmi_handle: wmi handle 985 * @param: pointer to hold vdev create parameter 986 * @macaddr: vdev mac address 987 * 988 * Return: QDF_STATUS_SUCCESS for success or error code 989 */ 990 static QDF_STATUS send_vdev_create_cmd_tlv(wmi_unified_t wmi_handle, 991 uint8_t macaddr[QDF_MAC_ADDR_SIZE], 992 struct vdev_create_params *param) 993 { 994 wmi_vdev_create_cmd_fixed_param *cmd; 995 wmi_buf_t buf; 996 int32_t len = sizeof(*cmd); 997 QDF_STATUS ret; 998 int num_bands = 2; 999 uint8_t *buf_ptr; 1000 wmi_vdev_txrx_streams *txrx_streams; 1001 1002 len += (num_bands * sizeof(*txrx_streams) + WMI_TLV_HDR_SIZE); 1003 len += vdev_create_mlo_params_size(param); 1004 1005 buf = wmi_buf_alloc(wmi_handle, len); 1006 if (!buf) 1007 return QDF_STATUS_E_NOMEM; 1008 1009 cmd = (wmi_vdev_create_cmd_fixed_param *) wmi_buf_data(buf); 1010 WMITLV_SET_HDR(&cmd->tlv_header, 1011 WMITLV_TAG_STRUC_wmi_vdev_create_cmd_fixed_param, 1012 WMITLV_GET_STRUCT_TLVLEN 1013 (wmi_vdev_create_cmd_fixed_param)); 1014 cmd->vdev_id = param->vdev_id; 1015 cmd->vdev_type = param->type; 1016 cmd->vdev_subtype = param->subtype; 1017 cmd->flags = param->mbssid_flags; 1018 cmd->flags |= (param->special_vdev_mode ? VDEV_FLAGS_SCAN_MODE_VAP : 0); 1019 cmd->vdevid_trans = param->vdevid_trans; 1020 cmd->num_cfg_txrx_streams = num_bands; 1021 #ifdef QCA_VDEV_STATS_HW_OFFLOAD_SUPPORT 1022 cmd->vdev_stats_id_valid = param->vdev_stats_id_valid; 1023 cmd->vdev_stats_id = param->vdev_stats_id; 1024 #endif 1025 copy_vdev_create_pdev_id(wmi_handle, cmd, param); 1026 WMI_CHAR_ARRAY_TO_MAC_ADDR(macaddr, &cmd->vdev_macaddr); 1027 wmi_debug("ID = %d[pdev:%d] VAP Addr = "QDF_MAC_ADDR_FMT, 1028 param->vdev_id, cmd->pdev_id, 1029 QDF_MAC_ADDR_REF(macaddr)); 1030 buf_ptr = (uint8_t *)cmd + sizeof(*cmd); 1031 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 1032 (num_bands * sizeof(wmi_vdev_txrx_streams))); 1033 buf_ptr += WMI_TLV_HDR_SIZE; 1034 1035 wmi_debug("type %d, subtype %d, nss_2g %d, nss_5g %d", 1036 param->type, param->subtype, 1037 param->nss_2g, param->nss_5g); 1038 txrx_streams = (wmi_vdev_txrx_streams *)buf_ptr; 1039 txrx_streams->band = WMI_TPC_CHAINMASK_CONFIG_BAND_2G; 1040 txrx_streams->supported_tx_streams = param->nss_2g; 1041 txrx_streams->supported_rx_streams = param->nss_2g; 1042 WMITLV_SET_HDR(&txrx_streams->tlv_header, 1043 WMITLV_TAG_STRUC_wmi_vdev_txrx_streams, 1044 WMITLV_GET_STRUCT_TLVLEN(wmi_vdev_txrx_streams)); 1045 1046 txrx_streams++; 1047 txrx_streams->band = WMI_TPC_CHAINMASK_CONFIG_BAND_5G; 1048 txrx_streams->supported_tx_streams = param->nss_5g; 1049 txrx_streams->supported_rx_streams = param->nss_5g; 1050 WMITLV_SET_HDR(&txrx_streams->tlv_header, 1051 WMITLV_TAG_STRUC_wmi_vdev_txrx_streams, 1052 WMITLV_GET_STRUCT_TLVLEN(wmi_vdev_txrx_streams)); 1053 1054 buf_ptr += (num_bands * sizeof(wmi_vdev_txrx_streams)); 1055 buf_ptr = vdev_create_add_mlo_params(buf_ptr, param); 1056 1057 wmi_mtrace(WMI_VDEV_CREATE_CMDID, cmd->vdev_id, 0); 1058 ret = wmi_unified_cmd_send(wmi_handle, buf, len, WMI_VDEV_CREATE_CMDID); 1059 if (QDF_IS_STATUS_ERROR(ret)) { 1060 wmi_err("Failed to send WMI_VDEV_CREATE_CMDID"); 1061 wmi_buf_free(buf); 1062 } 1063 1064 return ret; 1065 } 1066 1067 /** 1068 * send_vdev_delete_cmd_tlv() - send VDEV delete command to fw 1069 * @wmi_handle: wmi handle 1070 * @if_id: vdev id 1071 * 1072 * Return: QDF_STATUS_SUCCESS for success or error code 1073 */ 1074 static QDF_STATUS send_vdev_delete_cmd_tlv(wmi_unified_t wmi_handle, 1075 uint8_t if_id) 1076 { 1077 wmi_vdev_delete_cmd_fixed_param *cmd; 1078 wmi_buf_t buf; 1079 QDF_STATUS ret; 1080 1081 buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd)); 1082 if (!buf) 1083 return QDF_STATUS_E_NOMEM; 1084 1085 cmd = (wmi_vdev_delete_cmd_fixed_param *) wmi_buf_data(buf); 1086 WMITLV_SET_HDR(&cmd->tlv_header, 1087 WMITLV_TAG_STRUC_wmi_vdev_delete_cmd_fixed_param, 1088 WMITLV_GET_STRUCT_TLVLEN 1089 (wmi_vdev_delete_cmd_fixed_param)); 1090 cmd->vdev_id = if_id; 1091 wmi_mtrace(WMI_VDEV_DELETE_CMDID, cmd->vdev_id, 0); 1092 ret = wmi_unified_cmd_send(wmi_handle, buf, 1093 sizeof(wmi_vdev_delete_cmd_fixed_param), 1094 WMI_VDEV_DELETE_CMDID); 1095 if (QDF_IS_STATUS_ERROR(ret)) { 1096 wmi_err("Failed to send WMI_VDEV_DELETE_CMDID"); 1097 wmi_buf_free(buf); 1098 } 1099 wmi_debug("vdev id = %d", if_id); 1100 1101 return ret; 1102 } 1103 1104 /** 1105 * send_vdev_nss_chain_params_cmd_tlv() - send VDEV nss chain params to fw 1106 * @wmi_handle: wmi handle 1107 * @vdev_id: vdev id 1108 * @user_cfg: user configured nss chain params 1109 * 1110 * Return: QDF_STATUS_SUCCESS for success or error code 1111 */ 1112 static QDF_STATUS 1113 send_vdev_nss_chain_params_cmd_tlv(wmi_unified_t wmi_handle, 1114 uint8_t vdev_id, 1115 struct vdev_nss_chains *user_cfg) 1116 { 1117 wmi_vdev_chainmask_config_cmd_fixed_param *cmd; 1118 wmi_buf_t buf; 1119 QDF_STATUS ret; 1120 1121 buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd)); 1122 if (!buf) 1123 return QDF_STATUS_E_NOMEM; 1124 1125 cmd = (wmi_vdev_chainmask_config_cmd_fixed_param *)wmi_buf_data(buf); 1126 WMITLV_SET_HDR(&cmd->tlv_header, 1127 WMITLV_TAG_STRUC_wmi_vdev_chainmask_config_cmd_fixed_param, 1128 WMITLV_GET_STRUCT_TLVLEN 1129 (wmi_vdev_chainmask_config_cmd_fixed_param)); 1130 cmd->vdev_id = vdev_id; 1131 cmd->disable_rx_mrc_2g = user_cfg->disable_rx_mrc[NSS_CHAINS_BAND_2GHZ]; 1132 cmd->disable_tx_mrc_2g = user_cfg->disable_tx_mrc[NSS_CHAINS_BAND_2GHZ]; 1133 cmd->disable_rx_mrc_5g = user_cfg->disable_rx_mrc[NSS_CHAINS_BAND_5GHZ]; 1134 cmd->disable_tx_mrc_5g = user_cfg->disable_tx_mrc[NSS_CHAINS_BAND_5GHZ]; 1135 cmd->num_rx_chains_2g = user_cfg->num_rx_chains[NSS_CHAINS_BAND_2GHZ]; 1136 cmd->num_tx_chains_2g = user_cfg->num_tx_chains[NSS_CHAINS_BAND_2GHZ]; 1137 cmd->num_rx_chains_5g = user_cfg->num_rx_chains[NSS_CHAINS_BAND_5GHZ]; 1138 cmd->num_tx_chains_5g = user_cfg->num_tx_chains[NSS_CHAINS_BAND_5GHZ]; 1139 cmd->rx_nss_2g = user_cfg->rx_nss[NSS_CHAINS_BAND_2GHZ]; 1140 cmd->tx_nss_2g = user_cfg->tx_nss[NSS_CHAINS_BAND_2GHZ]; 1141 cmd->rx_nss_5g = user_cfg->rx_nss[NSS_CHAINS_BAND_5GHZ]; 1142 cmd->tx_nss_5g = user_cfg->tx_nss[NSS_CHAINS_BAND_5GHZ]; 1143 cmd->num_tx_chains_a = user_cfg->num_tx_chains_11a; 1144 cmd->num_tx_chains_b = user_cfg->num_tx_chains_11b; 1145 cmd->num_tx_chains_g = user_cfg->num_tx_chains_11g; 1146 1147 wmi_mtrace(WMI_VDEV_CHAINMASK_CONFIG_CMDID, cmd->vdev_id, 0); 1148 ret = wmi_unified_cmd_send(wmi_handle, buf, 1149 sizeof(wmi_vdev_chainmask_config_cmd_fixed_param), 1150 WMI_VDEV_CHAINMASK_CONFIG_CMDID); 1151 if (QDF_IS_STATUS_ERROR(ret)) { 1152 wmi_err("Failed to send WMI_VDEV_CHAINMASK_CONFIG_CMDID"); 1153 wmi_buf_free(buf); 1154 } 1155 wmi_debug("vdev_id %d", vdev_id); 1156 1157 return ret; 1158 } 1159 1160 /** 1161 * send_vdev_stop_cmd_tlv() - send vdev stop command to fw 1162 * @wmi: wmi handle 1163 * @vdev_id: vdev id 1164 * 1165 * Return: QDF_STATUS_SUCCESS for success or error code 1166 */ 1167 static QDF_STATUS send_vdev_stop_cmd_tlv(wmi_unified_t wmi, 1168 uint8_t vdev_id) 1169 { 1170 wmi_vdev_stop_cmd_fixed_param *cmd; 1171 wmi_buf_t buf; 1172 int32_t len = sizeof(*cmd); 1173 1174 buf = wmi_buf_alloc(wmi, len); 1175 if (!buf) 1176 return QDF_STATUS_E_NOMEM; 1177 1178 cmd = (wmi_vdev_stop_cmd_fixed_param *) wmi_buf_data(buf); 1179 WMITLV_SET_HDR(&cmd->tlv_header, 1180 WMITLV_TAG_STRUC_wmi_vdev_stop_cmd_fixed_param, 1181 WMITLV_GET_STRUCT_TLVLEN(wmi_vdev_stop_cmd_fixed_param)); 1182 cmd->vdev_id = vdev_id; 1183 wmi_mtrace(WMI_VDEV_STOP_CMDID, cmd->vdev_id, 0); 1184 if (wmi_unified_cmd_send(wmi, buf, len, WMI_VDEV_STOP_CMDID)) { 1185 wmi_err("Failed to send vdev stop command"); 1186 wmi_buf_free(buf); 1187 return QDF_STATUS_E_FAILURE; 1188 } 1189 wmi_debug("vdev id = %d", vdev_id); 1190 1191 return 0; 1192 } 1193 1194 /** 1195 * send_vdev_down_cmd_tlv() - send vdev down command to fw 1196 * @wmi: wmi handle 1197 * @vdev_id: vdev id 1198 * 1199 * Return: QDF_STATUS_SUCCESS for success or error code 1200 */ 1201 static QDF_STATUS send_vdev_down_cmd_tlv(wmi_unified_t wmi, uint8_t vdev_id) 1202 { 1203 wmi_vdev_down_cmd_fixed_param *cmd; 1204 wmi_buf_t buf; 1205 int32_t len = sizeof(*cmd); 1206 1207 buf = wmi_buf_alloc(wmi, len); 1208 if (!buf) 1209 return QDF_STATUS_E_NOMEM; 1210 1211 cmd = (wmi_vdev_down_cmd_fixed_param *) wmi_buf_data(buf); 1212 WMITLV_SET_HDR(&cmd->tlv_header, 1213 WMITLV_TAG_STRUC_wmi_vdev_down_cmd_fixed_param, 1214 WMITLV_GET_STRUCT_TLVLEN(wmi_vdev_down_cmd_fixed_param)); 1215 cmd->vdev_id = vdev_id; 1216 wmi_mtrace(WMI_VDEV_DOWN_CMDID, cmd->vdev_id, 0); 1217 if (wmi_unified_cmd_send(wmi, buf, len, WMI_VDEV_DOWN_CMDID)) { 1218 wmi_err("Failed to send vdev down"); 1219 wmi_buf_free(buf); 1220 return QDF_STATUS_E_FAILURE; 1221 } 1222 wmi_debug("vdev_id %d", vdev_id); 1223 1224 return 0; 1225 } 1226 1227 static inline void copy_channel_info( 1228 wmi_vdev_start_request_cmd_fixed_param * cmd, 1229 wmi_channel *chan, 1230 struct vdev_start_params *req) 1231 { 1232 chan->mhz = req->channel.mhz; 1233 1234 WMI_SET_CHANNEL_MODE(chan, req->channel.phy_mode); 1235 1236 chan->band_center_freq1 = req->channel.cfreq1; 1237 chan->band_center_freq2 = req->channel.cfreq2; 1238 1239 if (req->channel.half_rate) 1240 WMI_SET_CHANNEL_FLAG(chan, WMI_CHAN_FLAG_HALF_RATE); 1241 else if (req->channel.quarter_rate) 1242 WMI_SET_CHANNEL_FLAG(chan, WMI_CHAN_FLAG_QUARTER_RATE); 1243 1244 if (req->channel.dfs_set) { 1245 WMI_SET_CHANNEL_FLAG(chan, WMI_CHAN_FLAG_DFS); 1246 cmd->disable_hw_ack = req->disable_hw_ack; 1247 } 1248 1249 if (req->channel.dfs_set_cfreq2) 1250 WMI_SET_CHANNEL_FLAG(chan, WMI_CHAN_FLAG_DFS_CFREQ2); 1251 1252 if (req->channel.is_stadfs_en) 1253 WMI_SET_CHANNEL_FLAG(chan, WMI_CHAN_FLAG_STA_DFS); 1254 1255 /* According to firmware both reg power and max tx power 1256 * on set channel power is used and set it to max reg 1257 * power from regulatory. 1258 */ 1259 WMI_SET_CHANNEL_MIN_POWER(chan, req->channel.minpower); 1260 WMI_SET_CHANNEL_MAX_POWER(chan, req->channel.maxpower); 1261 WMI_SET_CHANNEL_REG_POWER(chan, req->channel.maxregpower); 1262 WMI_SET_CHANNEL_ANTENNA_MAX(chan, req->channel.antennamax); 1263 WMI_SET_CHANNEL_REG_CLASSID(chan, req->channel.reg_class_id); 1264 WMI_SET_CHANNEL_MAX_TX_POWER(chan, req->channel.maxregpower); 1265 1266 } 1267 1268 /** 1269 * vdev_start_cmd_fill_11be() - 11be information filling in vdev_start 1270 * @cmd: wmi cmd 1271 * @req: vdev start params 1272 * 1273 * Return: QDF status 1274 */ 1275 #ifdef WLAN_FEATURE_11BE 1276 static void 1277 vdev_start_cmd_fill_11be(wmi_vdev_start_request_cmd_fixed_param *cmd, 1278 struct vdev_start_params *req) 1279 { 1280 cmd->eht_ops = req->eht_ops; 1281 cmd->puncture_20mhz_bitmap = ~req->channel.puncture_bitmap; 1282 wmi_info("EHT ops: %x puncture_bitmap %x wmi cmd puncture bitmap %x", 1283 req->eht_ops, req->channel.puncture_bitmap, 1284 cmd->puncture_20mhz_bitmap); 1285 } 1286 #else 1287 static void 1288 vdev_start_cmd_fill_11be(wmi_vdev_start_request_cmd_fixed_param *cmd, 1289 struct vdev_start_params *req) 1290 { 1291 } 1292 #endif 1293 1294 /** 1295 * send_vdev_start_cmd_tlv() - send vdev start request to fw 1296 * @wmi_handle: wmi handle 1297 * @req: vdev start params 1298 * 1299 * Return: QDF status 1300 */ 1301 static QDF_STATUS send_vdev_start_cmd_tlv(wmi_unified_t wmi_handle, 1302 struct vdev_start_params *req) 1303 { 1304 wmi_vdev_start_request_cmd_fixed_param *cmd; 1305 wmi_buf_t buf; 1306 wmi_channel *chan; 1307 int32_t len, ret; 1308 uint8_t *buf_ptr; 1309 1310 len = sizeof(*cmd) + sizeof(wmi_channel) + WMI_TLV_HDR_SIZE; 1311 if (!req->is_restart) 1312 len += vdev_start_mlo_params_size(req); 1313 buf = wmi_buf_alloc(wmi_handle, len); 1314 if (!buf) 1315 return QDF_STATUS_E_NOMEM; 1316 1317 buf_ptr = (uint8_t *) wmi_buf_data(buf); 1318 cmd = (wmi_vdev_start_request_cmd_fixed_param *) buf_ptr; 1319 chan = (wmi_channel *) (buf_ptr + sizeof(*cmd)); 1320 WMITLV_SET_HDR(&cmd->tlv_header, 1321 WMITLV_TAG_STRUC_wmi_vdev_start_request_cmd_fixed_param, 1322 WMITLV_GET_STRUCT_TLVLEN 1323 (wmi_vdev_start_request_cmd_fixed_param)); 1324 WMITLV_SET_HDR(&chan->tlv_header, WMITLV_TAG_STRUC_wmi_channel, 1325 WMITLV_GET_STRUCT_TLVLEN(wmi_channel)); 1326 cmd->vdev_id = req->vdev_id; 1327 1328 /* Fill channel info */ 1329 copy_channel_info(cmd, chan, req); 1330 cmd->beacon_interval = req->beacon_interval; 1331 cmd->dtim_period = req->dtim_period; 1332 1333 cmd->bcn_tx_rate = req->bcn_tx_rate_code; 1334 if (req->bcn_tx_rate_code) 1335 wmi_enable_bcn_ratecode(&cmd->flags); 1336 1337 if (!req->is_restart) { 1338 if (req->pmf_enabled) 1339 cmd->flags |= WMI_UNIFIED_VDEV_START_PMF_ENABLED; 1340 1341 cmd->mbss_capability_flags = req->mbssid_flags; 1342 cmd->vdevid_trans = req->vdevid_trans; 1343 cmd->mbssid_multi_group_flag = req->mbssid_multi_group_flag; 1344 cmd->mbssid_multi_group_id = req->mbssid_multi_group_id; 1345 } 1346 1347 /* Copy the SSID */ 1348 if (req->ssid.length) { 1349 if (req->ssid.length < sizeof(cmd->ssid.ssid)) 1350 cmd->ssid.ssid_len = req->ssid.length; 1351 else 1352 cmd->ssid.ssid_len = sizeof(cmd->ssid.ssid); 1353 qdf_mem_copy(cmd->ssid.ssid, req->ssid.ssid, 1354 cmd->ssid.ssid_len); 1355 } 1356 1357 if (req->hidden_ssid) 1358 cmd->flags |= WMI_UNIFIED_VDEV_START_HIDDEN_SSID; 1359 1360 cmd->flags |= WMI_UNIFIED_VDEV_START_LDPC_RX_ENABLED; 1361 cmd->num_noa_descriptors = req->num_noa_descriptors; 1362 cmd->preferred_rx_streams = req->preferred_rx_streams; 1363 cmd->preferred_tx_streams = req->preferred_tx_streams; 1364 cmd->cac_duration_ms = req->cac_duration_ms; 1365 cmd->regdomain = req->regdomain; 1366 cmd->he_ops = req->he_ops; 1367 1368 buf_ptr = (uint8_t *) (((uintptr_t) cmd) + sizeof(*cmd) + 1369 sizeof(wmi_channel)); 1370 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 1371 cmd->num_noa_descriptors * 1372 sizeof(wmi_p2p_noa_descriptor)); 1373 if (!req->is_restart) { 1374 buf_ptr += WMI_TLV_HDR_SIZE + 1375 (cmd->num_noa_descriptors * sizeof(wmi_p2p_noa_descriptor)); 1376 1377 buf_ptr = vdev_start_add_mlo_params(buf_ptr, req); 1378 buf_ptr = vdev_start_add_ml_partner_links(buf_ptr, req); 1379 } 1380 wmi_info("vdev_id %d freq %d chanmode %d ch_info: 0x%x is_dfs %d " 1381 "beacon interval %d dtim %d center_chan %d center_freq2 %d " 1382 "reg_info_1: 0x%x reg_info_2: 0x%x, req->max_txpow: 0x%x " 1383 "Tx SS %d, Rx SS %d, ldpc_rx: %d, cac %d, regd %d, HE ops: %d" 1384 "req->dis_hw_ack: %d ", req->vdev_id, 1385 chan->mhz, req->channel.phy_mode, chan->info, 1386 req->channel.dfs_set, req->beacon_interval, cmd->dtim_period, 1387 chan->band_center_freq1, chan->band_center_freq2, 1388 chan->reg_info_1, chan->reg_info_2, req->channel.maxregpower, 1389 req->preferred_tx_streams, req->preferred_rx_streams, 1390 req->ldpc_rx_enabled, req->cac_duration_ms, 1391 req->regdomain, req->he_ops, 1392 req->disable_hw_ack); 1393 1394 vdev_start_cmd_fill_11be(cmd, req); 1395 1396 if (req->is_restart) { 1397 wmi_mtrace(WMI_VDEV_RESTART_REQUEST_CMDID, cmd->vdev_id, 0); 1398 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 1399 WMI_VDEV_RESTART_REQUEST_CMDID); 1400 } else { 1401 wmi_mtrace(WMI_VDEV_START_REQUEST_CMDID, cmd->vdev_id, 0); 1402 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 1403 WMI_VDEV_START_REQUEST_CMDID); 1404 } 1405 if (ret) { 1406 wmi_err("Failed to send vdev start command"); 1407 wmi_buf_free(buf); 1408 return QDF_STATUS_E_FAILURE; 1409 } 1410 1411 return QDF_STATUS_SUCCESS; 1412 } 1413 1414 /** 1415 * send_peer_flush_tids_cmd_tlv() - flush peer tids packets in fw 1416 * @wmi: wmi handle 1417 * @peer_addr: peer mac address 1418 * @param: pointer to hold peer flush tid parameter 1419 * 1420 * Return: QDF_STATUS_SUCCESS for success or error code 1421 */ 1422 static QDF_STATUS send_peer_flush_tids_cmd_tlv(wmi_unified_t wmi, 1423 uint8_t peer_addr[QDF_MAC_ADDR_SIZE], 1424 struct peer_flush_params *param) 1425 { 1426 wmi_peer_flush_tids_cmd_fixed_param *cmd; 1427 wmi_buf_t buf; 1428 int32_t len = sizeof(*cmd); 1429 1430 buf = wmi_buf_alloc(wmi, len); 1431 if (!buf) 1432 return QDF_STATUS_E_NOMEM; 1433 1434 cmd = (wmi_peer_flush_tids_cmd_fixed_param *) wmi_buf_data(buf); 1435 WMITLV_SET_HDR(&cmd->tlv_header, 1436 WMITLV_TAG_STRUC_wmi_peer_flush_tids_cmd_fixed_param, 1437 WMITLV_GET_STRUCT_TLVLEN 1438 (wmi_peer_flush_tids_cmd_fixed_param)); 1439 WMI_CHAR_ARRAY_TO_MAC_ADDR(peer_addr, &cmd->peer_macaddr); 1440 cmd->peer_tid_bitmap = param->peer_tid_bitmap; 1441 cmd->vdev_id = param->vdev_id; 1442 wmi_debug("peer_addr "QDF_MAC_ADDR_FMT" vdev_id %d and peer bitmap %d", 1443 QDF_MAC_ADDR_REF(peer_addr), param->vdev_id, 1444 param->peer_tid_bitmap); 1445 wmi_mtrace(WMI_PEER_FLUSH_TIDS_CMDID, cmd->vdev_id, 0); 1446 if (wmi_unified_cmd_send(wmi, buf, len, WMI_PEER_FLUSH_TIDS_CMDID)) { 1447 wmi_err("Failed to send flush tid command"); 1448 wmi_buf_free(buf); 1449 return QDF_STATUS_E_FAILURE; 1450 } 1451 1452 return 0; 1453 } 1454 1455 #ifdef WLAN_FEATURE_PEER_TXQ_FLUSH_CONF 1456 /** 1457 * map_to_wmi_flush_policy() - Map flush policy to firmware defined values 1458 * @policy: The target i/f flush policy value 1459 * 1460 * Return: WMI layer flush policy 1461 */ 1462 static wmi_peer_flush_policy 1463 map_to_wmi_flush_policy(enum peer_txq_flush_policy policy) 1464 { 1465 switch (policy) { 1466 case PEER_TXQ_FLUSH_POLICY_NONE: 1467 return WMI_NO_FLUSH; 1468 case PEER_TXQ_FLUSH_POLICY_TWT_SP_END: 1469 return WMI_TWT_FLUSH; 1470 default: 1471 return WMI_MAX_FLUSH_POLICY; 1472 } 1473 } 1474 1475 /** 1476 * send_peer_txq_flush_config_cmd_tlv() - Send peer TID queue flush config 1477 * @wmi: wmi handle 1478 * @param: Peer txq flush configuration 1479 * 1480 * Return: QDF_STATUS_SUCCESS for success or error code 1481 */ 1482 static QDF_STATUS 1483 send_peer_txq_flush_config_cmd_tlv(wmi_unified_t wmi, 1484 struct peer_txq_flush_config_params *param) 1485 { 1486 wmi_peer_flush_policy_cmd_fixed_param *cmd; 1487 wmi_buf_t buf; 1488 int32_t len = sizeof(*cmd); 1489 1490 buf = wmi_buf_alloc(wmi, len); 1491 if (!buf) 1492 return QDF_STATUS_E_NOMEM; 1493 1494 cmd = (wmi_peer_flush_policy_cmd_fixed_param *)wmi_buf_data(buf); 1495 1496 WMITLV_SET_HDR(&cmd->tlv_header, 1497 WMITLV_TAG_STRUC_wmi_peer_flush_policy_cmd_fixed_param, 1498 WMITLV_GET_STRUCT_TLVLEN 1499 (wmi_peer_flush_policy_cmd_fixed_param)); 1500 1501 WMI_CHAR_ARRAY_TO_MAC_ADDR(param->peer, &cmd->peer_macaddr); 1502 cmd->peer_tid_bitmap = param->tid_mask; 1503 cmd->vdev_id = param->vdev_id; 1504 cmd->flush_policy = map_to_wmi_flush_policy(param->policy); 1505 if (cmd->flush_policy == WMI_MAX_FLUSH_POLICY) { 1506 wmi_buf_free(buf); 1507 wmi_err("Invalid policy"); 1508 return QDF_STATUS_E_INVAL; 1509 } 1510 wmi_debug("peer_addr " QDF_MAC_ADDR_FMT "vdev %d tid %x policy %d", 1511 QDF_MAC_ADDR_REF(param->peer), param->vdev_id, 1512 param->tid_mask, param->policy); 1513 wmi_mtrace(WMI_PEER_FLUSH_POLICY_CMDID, cmd->vdev_id, 0); 1514 if (wmi_unified_cmd_send(wmi, buf, len, WMI_PEER_FLUSH_POLICY_CMDID)) { 1515 wmi_err("Failed to send flush policy command"); 1516 wmi_buf_free(buf); 1517 return QDF_STATUS_E_FAILURE; 1518 } 1519 1520 return QDF_STATUS_SUCCESS; 1521 } 1522 #endif 1523 /** 1524 * send_peer_delete_cmd_tlv() - send PEER delete command to fw 1525 * @wmi: wmi handle 1526 * @peer_addr: peer mac addr 1527 * @param: peer delete parameters 1528 * 1529 * Return: QDF_STATUS_SUCCESS for success or error code 1530 */ 1531 static QDF_STATUS send_peer_delete_cmd_tlv(wmi_unified_t wmi, 1532 uint8_t peer_addr[QDF_MAC_ADDR_SIZE], 1533 struct peer_delete_cmd_params *param) 1534 { 1535 wmi_peer_delete_cmd_fixed_param *cmd; 1536 wmi_buf_t buf; 1537 int32_t len = sizeof(*cmd); 1538 uint8_t *buf_ptr; 1539 1540 len += peer_delete_mlo_params_size(param); 1541 buf = wmi_buf_alloc(wmi, len); 1542 if (!buf) 1543 return QDF_STATUS_E_NOMEM; 1544 1545 buf_ptr = (uint8_t *)wmi_buf_data(buf); 1546 cmd = (wmi_peer_delete_cmd_fixed_param *)buf_ptr; 1547 WMITLV_SET_HDR(&cmd->tlv_header, 1548 WMITLV_TAG_STRUC_wmi_peer_delete_cmd_fixed_param, 1549 WMITLV_GET_STRUCT_TLVLEN 1550 (wmi_peer_delete_cmd_fixed_param)); 1551 WMI_CHAR_ARRAY_TO_MAC_ADDR(peer_addr, &cmd->peer_macaddr); 1552 cmd->vdev_id = param->vdev_id; 1553 buf_ptr = (uint8_t *)(((uintptr_t) cmd) + sizeof(*cmd)); 1554 buf_ptr = peer_delete_add_mlo_params(buf_ptr, param); 1555 wmi_debug("peer_addr "QDF_MAC_ADDR_FMT" vdev_id %d", 1556 QDF_MAC_ADDR_REF(peer_addr), param->vdev_id); 1557 wmi_mtrace(WMI_PEER_DELETE_CMDID, cmd->vdev_id, 0); 1558 if (wmi_unified_cmd_send(wmi, buf, len, WMI_PEER_DELETE_CMDID)) { 1559 wmi_err("Failed to send peer delete command"); 1560 wmi_buf_free(buf); 1561 return QDF_STATUS_E_FAILURE; 1562 } 1563 return 0; 1564 } 1565 1566 static void 1567 wmi_get_converted_peer_bitmap(uint32_t src_peer_bitmap, uint32_t *dst_bitmap) 1568 { 1569 if (QDF_HAS_PARAM(src_peer_bitmap, WLAN_PEER_SELF)) 1570 WMI_VDEV_DELETE_ALL_PEER_BITMAP_SET(dst_bitmap, 1571 WMI_PEER_TYPE_DEFAULT); 1572 1573 if (QDF_HAS_PARAM(src_peer_bitmap, WLAN_PEER_AP)) 1574 WMI_VDEV_DELETE_ALL_PEER_BITMAP_SET(dst_bitmap, 1575 WMI_PEER_TYPE_BSS); 1576 1577 if (QDF_HAS_PARAM(src_peer_bitmap, WLAN_PEER_TDLS)) 1578 WMI_VDEV_DELETE_ALL_PEER_BITMAP_SET(dst_bitmap, 1579 WMI_PEER_TYPE_TDLS); 1580 1581 if (QDF_HAS_PARAM(src_peer_bitmap, WLAN_PEER_NDP)) 1582 WMI_VDEV_DELETE_ALL_PEER_BITMAP_SET(dst_bitmap, 1583 WMI_PEER_TYPE_NAN_DATA); 1584 1585 if (QDF_HAS_PARAM(src_peer_bitmap, WLAN_PEER_RTT_PASN)) 1586 WMI_VDEV_DELETE_ALL_PEER_BITMAP_SET(dst_bitmap, 1587 WMI_PEER_TYPE_PASN); 1588 } 1589 1590 /** 1591 * send_peer_delete_all_cmd_tlv() - send PEER delete all command to fw 1592 * @wmi: wmi handle 1593 * @param: pointer to hold peer delete all parameter 1594 * 1595 * Return: QDF_STATUS_SUCCESS for success or error code 1596 */ 1597 static QDF_STATUS send_peer_delete_all_cmd_tlv( 1598 wmi_unified_t wmi, 1599 struct peer_delete_all_params *param) 1600 { 1601 wmi_vdev_delete_all_peer_cmd_fixed_param *cmd; 1602 wmi_buf_t buf; 1603 int32_t len = sizeof(*cmd); 1604 1605 buf = wmi_buf_alloc(wmi, len); 1606 if (!buf) 1607 return QDF_STATUS_E_NOMEM; 1608 1609 cmd = (wmi_vdev_delete_all_peer_cmd_fixed_param *)wmi_buf_data(buf); 1610 WMITLV_SET_HDR( 1611 &cmd->tlv_header, 1612 WMITLV_TAG_STRUC_wmi_vdev_delete_all_peer_cmd_fixed_param, 1613 WMITLV_GET_STRUCT_TLVLEN 1614 (wmi_vdev_delete_all_peer_cmd_fixed_param)); 1615 cmd->vdev_id = param->vdev_id; 1616 wmi_get_converted_peer_bitmap(param->peer_type_bitmap, 1617 cmd->peer_type_bitmap); 1618 1619 wmi_debug("vdev_id %d peer_type_bitmap:%d", cmd->vdev_id, 1620 param->peer_type_bitmap); 1621 wmi_mtrace(WMI_VDEV_DELETE_ALL_PEER_CMDID, cmd->vdev_id, 0); 1622 if (wmi_unified_cmd_send(wmi, buf, len, 1623 WMI_VDEV_DELETE_ALL_PEER_CMDID)) { 1624 wmi_err("Failed to send peer del all command"); 1625 wmi_buf_free(buf); 1626 return QDF_STATUS_E_FAILURE; 1627 } 1628 1629 return QDF_STATUS_SUCCESS; 1630 } 1631 1632 /** 1633 * convert_host_peer_param_id_to_target_id_tlv - convert host peer param_id 1634 * to target id. 1635 * @peer_param_id: host param id. 1636 * 1637 * Return: Target param id. 1638 */ 1639 #ifdef ENABLE_HOST_TO_TARGET_CONVERSION 1640 static inline uint32_t convert_host_peer_param_id_to_target_id_tlv( 1641 uint32_t peer_param_id) 1642 { 1643 if (peer_param_id < QDF_ARRAY_SIZE(peer_param_tlv)) 1644 return peer_param_tlv[peer_param_id]; 1645 return WMI_UNAVAILABLE_PARAM; 1646 } 1647 #else 1648 static inline uint32_t convert_host_peer_param_id_to_target_id_tlv( 1649 uint32_t peer_param_id) 1650 { 1651 return peer_param_id; 1652 } 1653 #endif 1654 1655 /** 1656 * wmi_host_chan_bw_to_target_chan_bw - convert wmi_host_channel_width to 1657 * wmi_channel_width 1658 * @bw: wmi_host_channel_width channel width 1659 * 1660 * Return: wmi_channel_width 1661 */ 1662 static wmi_channel_width wmi_host_chan_bw_to_target_chan_bw( 1663 wmi_host_channel_width bw) 1664 { 1665 wmi_channel_width target_bw = WMI_CHAN_WIDTH_20; 1666 1667 switch (bw) { 1668 case WMI_HOST_CHAN_WIDTH_20: 1669 target_bw = WMI_CHAN_WIDTH_20; 1670 break; 1671 case WMI_HOST_CHAN_WIDTH_40: 1672 target_bw = WMI_CHAN_WIDTH_40; 1673 break; 1674 case WMI_HOST_CHAN_WIDTH_80: 1675 target_bw = WMI_CHAN_WIDTH_80; 1676 break; 1677 case WMI_HOST_CHAN_WIDTH_160: 1678 target_bw = WMI_CHAN_WIDTH_160; 1679 break; 1680 case WMI_HOST_CHAN_WIDTH_80P80: 1681 target_bw = WMI_CHAN_WIDTH_80P80; 1682 break; 1683 case WMI_HOST_CHAN_WIDTH_5: 1684 target_bw = WMI_CHAN_WIDTH_5; 1685 break; 1686 case WMI_HOST_CHAN_WIDTH_10: 1687 target_bw = WMI_CHAN_WIDTH_10; 1688 break; 1689 case WMI_HOST_CHAN_WIDTH_165: 1690 target_bw = WMI_CHAN_WIDTH_165; 1691 break; 1692 case WMI_HOST_CHAN_WIDTH_160P160: 1693 target_bw = WMI_CHAN_WIDTH_160P160; 1694 break; 1695 case WMI_HOST_CHAN_WIDTH_320: 1696 target_bw = WMI_CHAN_WIDTH_320; 1697 break; 1698 default: 1699 break; 1700 } 1701 1702 return target_bw; 1703 } 1704 1705 /** 1706 * convert_host_peer_param_value_to_target_value_tlv() - convert host peer 1707 * param value to target 1708 * @param_id: target param id 1709 * @param_value: host param value 1710 * 1711 * Return: target param value 1712 */ 1713 static uint32_t convert_host_peer_param_value_to_target_value_tlv( 1714 uint32_t param_id, uint32_t param_value) 1715 { 1716 uint32_t fw_param_value = 0; 1717 wmi_host_channel_width bw; 1718 uint16_t punc; 1719 1720 switch (param_id) { 1721 case WMI_PEER_CHWIDTH_PUNCTURE_20MHZ_BITMAP: 1722 bw = QDF_GET_BITS(param_value, 0, 8); 1723 punc = QDF_GET_BITS(param_value, 8, 16); 1724 QDF_SET_BITS(fw_param_value, 0, 8, 1725 wmi_host_chan_bw_to_target_chan_bw(bw)); 1726 QDF_SET_BITS(fw_param_value, 8, 16, ~punc); 1727 break; 1728 default: 1729 fw_param_value = param_value; 1730 break; 1731 } 1732 1733 return fw_param_value; 1734 } 1735 1736 #ifdef WLAN_SUPPORT_PPEDS 1737 /** 1738 * peer_ppe_ds_param_send_tlv() - Set peer PPE DS config 1739 * @wmi: wmi handle 1740 * @param: pointer to hold PPE DS config 1741 * 1742 * Return: QDF_STATUS_SUCCESS for success or error code 1743 */ 1744 static QDF_STATUS peer_ppe_ds_param_send_tlv(wmi_unified_t wmi, 1745 struct peer_ppe_ds_param *param) 1746 { 1747 wmi_peer_config_ppe_ds_cmd_fixed_param *cmd; 1748 wmi_buf_t buf; 1749 int32_t err; 1750 uint32_t len = sizeof(wmi_peer_config_ppe_ds_cmd_fixed_param); 1751 1752 buf = wmi_buf_alloc(wmi, sizeof(*cmd)); 1753 if (!buf) 1754 return QDF_STATUS_E_NOMEM; 1755 1756 cmd = (wmi_peer_config_ppe_ds_cmd_fixed_param *)wmi_buf_data(buf); 1757 WMITLV_SET_HDR(&cmd->tlv_header, 1758 WMITLV_TAG_STRUC_wmi_peer_config_ppe_ds_cmd_fixed_param, 1759 WMITLV_GET_STRUCT_TLVLEN 1760 (wmi_peer_config_ppe_ds_cmd_fixed_param)); 1761 1762 WMI_CHAR_ARRAY_TO_MAC_ADDR(param->peer_macaddr, &cmd->peer_macaddr); 1763 1764 if (param->ppe_routing_enabled) 1765 cmd->ppe_routing_enable = param->use_ppe ? 1766 WMI_AST_USE_PPE_ENABLED : WMI_AST_USE_PPE_DISABLED; 1767 else 1768 cmd->ppe_routing_enable = WMI_PPE_ROUTING_DISABLED; 1769 1770 cmd->service_code = param->service_code; 1771 cmd->priority_valid = param->priority_valid; 1772 cmd->src_info = param->src_info; 1773 cmd->vdev_id = param->vdev_id; 1774 1775 wmi_debug("vdev_id %d peer_mac: QDF_MAC_ADDR_FMT\n" 1776 "ppe_routing_enable: %u service_code: %u\n" 1777 "priority_valid:%d src_info:%u", 1778 param->vdev_id, 1779 QDF_MAC_ADDR_REF(param->peer_macaddr), 1780 param->ppe_routing_enabled, 1781 param->service_code, 1782 param->priority_valid, 1783 param->src_info); 1784 1785 wmi_mtrace(WMI_PEER_CONFIG_PPE_DS_CMDID, cmd->vdev_id, 0); 1786 err = wmi_unified_cmd_send(wmi, buf, 1787 len, 1788 WMI_PEER_CONFIG_PPE_DS_CMDID); 1789 if (err) { 1790 wmi_err("Failed to send ppeds config cmd"); 1791 wmi_buf_free(buf); 1792 return QDF_STATUS_E_FAILURE; 1793 } 1794 1795 return 0; 1796 } 1797 #endif /* WLAN_SUPPORT_PPEDS */ 1798 1799 /** 1800 * send_peer_param_cmd_tlv() - set peer parameter in fw 1801 * @wmi: wmi handle 1802 * @peer_addr: peer mac address 1803 * @param: pointer to hold peer set parameter 1804 * 1805 * Return: QDF_STATUS_SUCCESS for success or error code 1806 */ 1807 static QDF_STATUS send_peer_param_cmd_tlv(wmi_unified_t wmi, 1808 uint8_t peer_addr[QDF_MAC_ADDR_SIZE], 1809 struct peer_set_params *param) 1810 { 1811 wmi_peer_set_param_cmd_fixed_param *cmd; 1812 wmi_buf_t buf; 1813 int32_t err; 1814 uint32_t param_id; 1815 uint32_t param_value; 1816 1817 param_id = convert_host_peer_param_id_to_target_id_tlv(param->param_id); 1818 if (param_id == WMI_UNAVAILABLE_PARAM) { 1819 wmi_err("Unavailable param %d", param->param_id); 1820 return QDF_STATUS_E_NOSUPPORT; 1821 } 1822 param_value = convert_host_peer_param_value_to_target_value_tlv( 1823 param_id, param->param_value); 1824 buf = wmi_buf_alloc(wmi, sizeof(*cmd)); 1825 if (!buf) 1826 return QDF_STATUS_E_NOMEM; 1827 1828 cmd = (wmi_peer_set_param_cmd_fixed_param *) wmi_buf_data(buf); 1829 WMITLV_SET_HDR(&cmd->tlv_header, 1830 WMITLV_TAG_STRUC_wmi_peer_set_param_cmd_fixed_param, 1831 WMITLV_GET_STRUCT_TLVLEN 1832 (wmi_peer_set_param_cmd_fixed_param)); 1833 cmd->vdev_id = param->vdev_id; 1834 WMI_CHAR_ARRAY_TO_MAC_ADDR(peer_addr, &cmd->peer_macaddr); 1835 cmd->param_id = param_id; 1836 cmd->param_value = param_value; 1837 1838 wmi_debug("vdev_id %d peer_mac: "QDF_MAC_ADDR_FMT" param_id: %u param_value: %x", 1839 cmd->vdev_id, 1840 QDF_MAC_ADDR_REF(peer_addr), param->param_id, 1841 cmd->param_value); 1842 1843 wmi_mtrace(WMI_PEER_SET_PARAM_CMDID, cmd->vdev_id, 0); 1844 err = wmi_unified_cmd_send(wmi, buf, 1845 sizeof(wmi_peer_set_param_cmd_fixed_param), 1846 WMI_PEER_SET_PARAM_CMDID); 1847 if (err) { 1848 wmi_err("Failed to send set_param cmd"); 1849 wmi_buf_free(buf); 1850 return QDF_STATUS_E_FAILURE; 1851 } 1852 1853 return 0; 1854 } 1855 1856 /** 1857 * send_vdev_up_cmd_tlv() - send vdev up command in fw 1858 * @wmi: wmi handle 1859 * @bssid: bssid 1860 * @params: pointer to hold vdev up parameter 1861 * 1862 * Return: QDF_STATUS_SUCCESS for success or error code 1863 */ 1864 static QDF_STATUS send_vdev_up_cmd_tlv(wmi_unified_t wmi, 1865 uint8_t bssid[QDF_MAC_ADDR_SIZE], 1866 struct vdev_up_params *params) 1867 { 1868 wmi_vdev_up_cmd_fixed_param *cmd; 1869 wmi_buf_t buf; 1870 int32_t len = sizeof(*cmd); 1871 1872 wmi_debug("VDEV_UP"); 1873 wmi_debug("vdev_id %d aid %d profile idx %d count %d bssid " 1874 QDF_MAC_ADDR_FMT " trans bssid " QDF_MAC_ADDR_FMT, 1875 params->vdev_id, params->assoc_id, 1876 params->profile_idx, params->profile_num, 1877 QDF_MAC_ADDR_REF(bssid), QDF_MAC_ADDR_REF(params->trans_bssid)); 1878 buf = wmi_buf_alloc(wmi, len); 1879 if (!buf) 1880 return QDF_STATUS_E_NOMEM; 1881 1882 cmd = (wmi_vdev_up_cmd_fixed_param *) wmi_buf_data(buf); 1883 WMITLV_SET_HDR(&cmd->tlv_header, 1884 WMITLV_TAG_STRUC_wmi_vdev_up_cmd_fixed_param, 1885 WMITLV_GET_STRUCT_TLVLEN(wmi_vdev_up_cmd_fixed_param)); 1886 cmd->vdev_id = params->vdev_id; 1887 cmd->vdev_assoc_id = params->assoc_id; 1888 cmd->profile_idx = params->profile_idx; 1889 cmd->profile_num = params->profile_num; 1890 WMI_CHAR_ARRAY_TO_MAC_ADDR(params->trans_bssid, &cmd->trans_bssid); 1891 WMI_CHAR_ARRAY_TO_MAC_ADDR(bssid, &cmd->vdev_bssid); 1892 wmi_mtrace(WMI_VDEV_UP_CMDID, cmd->vdev_id, 0); 1893 if (wmi_unified_cmd_send(wmi, buf, len, WMI_VDEV_UP_CMDID)) { 1894 wmi_err("Failed to send vdev up command"); 1895 wmi_buf_free(buf); 1896 return QDF_STATUS_E_FAILURE; 1897 } 1898 1899 return 0; 1900 } 1901 1902 #ifdef ENABLE_HOST_TO_TARGET_CONVERSION 1903 static uint32_t convert_peer_type_host_to_target(uint32_t peer_type) 1904 { 1905 /* Host sets the peer_type as 0 for the peer create command sent to FW 1906 * other than PASN and BRIDGE peer create command. 1907 */ 1908 if (peer_type == WLAN_PEER_RTT_PASN) 1909 return WMI_PEER_TYPE_PASN; 1910 1911 if (peer_type == WLAN_PEER_MLO_BRIDGE) 1912 return WMI_PEER_TYPE_BRIDGE; 1913 1914 return peer_type; 1915 } 1916 #else 1917 static uint32_t convert_peer_type_host_to_target(uint32_t peer_type) 1918 { 1919 return peer_type; 1920 } 1921 #endif 1922 /** 1923 * send_peer_create_cmd_tlv() - send peer create command to fw 1924 * @wmi: wmi handle 1925 * @param: peer create parameters 1926 * 1927 * Return: QDF_STATUS_SUCCESS for success or error code 1928 */ 1929 static QDF_STATUS send_peer_create_cmd_tlv(wmi_unified_t wmi, 1930 struct peer_create_params *param) 1931 { 1932 wmi_peer_create_cmd_fixed_param *cmd; 1933 wmi_buf_t buf; 1934 uint8_t *buf_ptr; 1935 int32_t len = sizeof(*cmd); 1936 1937 len += peer_create_mlo_params_size(param); 1938 buf = wmi_buf_alloc(wmi, len); 1939 if (!buf) 1940 return QDF_STATUS_E_NOMEM; 1941 1942 cmd = (wmi_peer_create_cmd_fixed_param *) wmi_buf_data(buf); 1943 WMITLV_SET_HDR(&cmd->tlv_header, 1944 WMITLV_TAG_STRUC_wmi_peer_create_cmd_fixed_param, 1945 WMITLV_GET_STRUCT_TLVLEN 1946 (wmi_peer_create_cmd_fixed_param)); 1947 WMI_CHAR_ARRAY_TO_MAC_ADDR(param->peer_addr, &cmd->peer_macaddr); 1948 cmd->peer_type = convert_peer_type_host_to_target(param->peer_type); 1949 cmd->vdev_id = param->vdev_id; 1950 1951 buf_ptr = (uint8_t *)wmi_buf_data(buf); 1952 buf_ptr += sizeof(*cmd); 1953 buf_ptr = peer_create_add_mlo_params(buf_ptr, param); 1954 wmi_mtrace(WMI_PEER_CREATE_CMDID, cmd->vdev_id, 0); 1955 if (wmi_unified_cmd_send(wmi, buf, len, WMI_PEER_CREATE_CMDID)) { 1956 wmi_err("Failed to send WMI_PEER_CREATE_CMDID"); 1957 wmi_buf_free(buf); 1958 return QDF_STATUS_E_FAILURE; 1959 } 1960 wmi_debug("peer_addr "QDF_MAC_ADDR_FMT" vdev_id %d", 1961 QDF_MAC_ADDR_REF(param->peer_addr), 1962 param->vdev_id); 1963 1964 return 0; 1965 } 1966 1967 /** 1968 * send_peer_rx_reorder_queue_setup_cmd_tlv() - send rx reorder setup 1969 * command to fw 1970 * @wmi: wmi handle 1971 * @param: Rx reorder queue setup parameters 1972 * 1973 * Return: QDF_STATUS_SUCCESS for success or error code 1974 */ 1975 static 1976 QDF_STATUS send_peer_rx_reorder_queue_setup_cmd_tlv(wmi_unified_t wmi, 1977 struct rx_reorder_queue_setup_params *param) 1978 { 1979 wmi_peer_reorder_queue_setup_cmd_fixed_param *cmd; 1980 wmi_buf_t buf; 1981 int32_t len = sizeof(*cmd); 1982 1983 buf = wmi_buf_alloc(wmi, len); 1984 if (!buf) 1985 return QDF_STATUS_E_NOMEM; 1986 1987 cmd = (wmi_peer_reorder_queue_setup_cmd_fixed_param *)wmi_buf_data(buf); 1988 WMITLV_SET_HDR(&cmd->tlv_header, 1989 WMITLV_TAG_STRUC_wmi_peer_reorder_queue_setup_cmd_fixed_param, 1990 WMITLV_GET_STRUCT_TLVLEN 1991 (wmi_peer_reorder_queue_setup_cmd_fixed_param)); 1992 WMI_CHAR_ARRAY_TO_MAC_ADDR(param->peer_macaddr, &cmd->peer_macaddr); 1993 cmd->vdev_id = param->vdev_id; 1994 cmd->tid = param->tid; 1995 cmd->queue_ptr_lo = param->hw_qdesc_paddr_lo; 1996 cmd->queue_ptr_hi = param->hw_qdesc_paddr_hi; 1997 cmd->queue_no = param->queue_no; 1998 cmd->ba_window_size_valid = param->ba_window_size_valid; 1999 cmd->ba_window_size = param->ba_window_size; 2000 2001 2002 wmi_mtrace(WMI_PEER_REORDER_QUEUE_SETUP_CMDID, cmd->vdev_id, 0); 2003 if (wmi_unified_cmd_send(wmi, buf, len, 2004 WMI_PEER_REORDER_QUEUE_SETUP_CMDID)) { 2005 wmi_err("Fail to send WMI_PEER_REORDER_QUEUE_SETUP_CMDID"); 2006 wmi_buf_free(buf); 2007 return QDF_STATUS_E_FAILURE; 2008 } 2009 wmi_debug("peer_macaddr "QDF_MAC_ADDR_FMT" vdev_id %d, tid %d", 2010 QDF_MAC_ADDR_REF(param->peer_macaddr), 2011 param->vdev_id, param->tid); 2012 2013 return QDF_STATUS_SUCCESS; 2014 } 2015 2016 /** 2017 * send_peer_rx_reorder_queue_remove_cmd_tlv() - send rx reorder remove 2018 * command to fw 2019 * @wmi: wmi handle 2020 * @param: Rx reorder queue remove parameters 2021 * 2022 * Return: QDF_STATUS_SUCCESS for success or error code 2023 */ 2024 static 2025 QDF_STATUS send_peer_rx_reorder_queue_remove_cmd_tlv(wmi_unified_t wmi, 2026 struct rx_reorder_queue_remove_params *param) 2027 { 2028 wmi_peer_reorder_queue_remove_cmd_fixed_param *cmd; 2029 wmi_buf_t buf; 2030 int32_t len = sizeof(*cmd); 2031 2032 buf = wmi_buf_alloc(wmi, len); 2033 if (!buf) 2034 return QDF_STATUS_E_NOMEM; 2035 2036 cmd = (wmi_peer_reorder_queue_remove_cmd_fixed_param *) 2037 wmi_buf_data(buf); 2038 WMITLV_SET_HDR(&cmd->tlv_header, 2039 WMITLV_TAG_STRUC_wmi_peer_reorder_queue_remove_cmd_fixed_param, 2040 WMITLV_GET_STRUCT_TLVLEN 2041 (wmi_peer_reorder_queue_remove_cmd_fixed_param)); 2042 WMI_CHAR_ARRAY_TO_MAC_ADDR(param->peer_macaddr, &cmd->peer_macaddr); 2043 cmd->vdev_id = param->vdev_id; 2044 cmd->tid_mask = param->peer_tid_bitmap; 2045 2046 wmi_mtrace(WMI_PEER_REORDER_QUEUE_REMOVE_CMDID, cmd->vdev_id, 0); 2047 if (wmi_unified_cmd_send(wmi, buf, len, 2048 WMI_PEER_REORDER_QUEUE_REMOVE_CMDID)) { 2049 wmi_err("Fail to send WMI_PEER_REORDER_QUEUE_REMOVE_CMDID"); 2050 wmi_buf_free(buf); 2051 return QDF_STATUS_E_FAILURE; 2052 } 2053 wmi_debug("peer_macaddr "QDF_MAC_ADDR_FMT" vdev_id %d, tid_map %d", 2054 QDF_MAC_ADDR_REF(param->peer_macaddr), 2055 param->vdev_id, param->peer_tid_bitmap); 2056 2057 return QDF_STATUS_SUCCESS; 2058 } 2059 2060 #ifdef WLAN_SUPPORT_GREEN_AP 2061 /** 2062 * send_green_ap_ps_cmd_tlv() - enable green ap powersave command 2063 * @wmi_handle: wmi handle 2064 * @value: value 2065 * @pdev_id: pdev id to have radio context 2066 * 2067 * Return: QDF_STATUS_SUCCESS for success or error code 2068 */ 2069 static QDF_STATUS send_green_ap_ps_cmd_tlv(wmi_unified_t wmi_handle, 2070 uint32_t value, uint8_t pdev_id) 2071 { 2072 wmi_pdev_green_ap_ps_enable_cmd_fixed_param *cmd; 2073 wmi_buf_t buf; 2074 int32_t len = sizeof(*cmd); 2075 2076 wmi_debug("Set Green AP PS val %d", value); 2077 2078 buf = wmi_buf_alloc(wmi_handle, len); 2079 if (!buf) 2080 return QDF_STATUS_E_NOMEM; 2081 2082 cmd = (wmi_pdev_green_ap_ps_enable_cmd_fixed_param *) wmi_buf_data(buf); 2083 WMITLV_SET_HDR(&cmd->tlv_header, 2084 WMITLV_TAG_STRUC_wmi_pdev_green_ap_ps_enable_cmd_fixed_param, 2085 WMITLV_GET_STRUCT_TLVLEN 2086 (wmi_pdev_green_ap_ps_enable_cmd_fixed_param)); 2087 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 2088 wmi_handle, 2089 pdev_id); 2090 cmd->enable = value; 2091 2092 wmi_mtrace(WMI_PDEV_GREEN_AP_PS_ENABLE_CMDID, NO_SESSION, 0); 2093 if (wmi_unified_cmd_send(wmi_handle, buf, len, 2094 WMI_PDEV_GREEN_AP_PS_ENABLE_CMDID)) { 2095 wmi_err("Set Green AP PS param Failed val %d", value); 2096 wmi_buf_free(buf); 2097 return QDF_STATUS_E_FAILURE; 2098 } 2099 2100 return 0; 2101 } 2102 #endif 2103 2104 #ifdef WLAN_SUPPORT_GAP_LL_PS_MODE 2105 static QDF_STATUS send_green_ap_ll_ps_cmd_tlv(wmi_unified_t wmi_handle, 2106 struct green_ap_ll_ps_cmd_param *green_ap_ll_ps_params) 2107 { 2108 uint32_t len; 2109 wmi_buf_t buf; 2110 wmi_xgap_enable_cmd_fixed_param *cmd; 2111 2112 len = sizeof(*cmd); 2113 2114 wmi_debug("Green AP low latency PS: bcn interval: %u state: %u cookie: %u", 2115 green_ap_ll_ps_params->bcn_interval, 2116 green_ap_ll_ps_params->state, 2117 green_ap_ll_ps_params->cookie); 2118 2119 buf = wmi_buf_alloc(wmi_handle, len); 2120 if (!buf) 2121 return QDF_STATUS_E_NOMEM; 2122 2123 cmd = (wmi_xgap_enable_cmd_fixed_param *)wmi_buf_data(buf); 2124 WMITLV_SET_HDR(&cmd->tlv_header, 2125 WMITLV_TAG_STRUC_wmi_xgap_enable_cmd_fixed_param, 2126 WMITLV_GET_STRUCT_TLVLEN 2127 (wmi_xgap_enable_cmd_fixed_param)); 2128 2129 cmd->beacon_interval = green_ap_ll_ps_params->bcn_interval; 2130 cmd->sap_lp_flag = green_ap_ll_ps_params->state; 2131 cmd->dialog_token = green_ap_ll_ps_params->cookie; 2132 2133 wmi_mtrace(WMI_XGAP_ENABLE_CMDID, NO_SESSION, 0); 2134 if (wmi_unified_cmd_send(wmi_handle, buf, len, 2135 WMI_XGAP_ENABLE_CMDID)) { 2136 wmi_err("Green AP Low latency PS cmd Failed"); 2137 wmi_buf_free(buf); 2138 return QDF_STATUS_E_FAILURE; 2139 } 2140 2141 return QDF_STATUS_SUCCESS; 2142 } 2143 #endif 2144 2145 /** 2146 * send_pdev_utf_cmd_tlv() - send utf command to fw 2147 * @wmi_handle: wmi handle 2148 * @param: pointer to pdev_utf_params 2149 * @mac_id: mac id to have radio context 2150 * 2151 * Return: QDF_STATUS_SUCCESS for success or error code 2152 */ 2153 static QDF_STATUS 2154 send_pdev_utf_cmd_tlv(wmi_unified_t wmi_handle, 2155 struct pdev_utf_params *param, 2156 uint8_t mac_id) 2157 { 2158 wmi_buf_t buf; 2159 uint8_t *cmd; 2160 /* if param->len is 0 no data is sent, return error */ 2161 QDF_STATUS ret = QDF_STATUS_E_INVAL; 2162 static uint8_t msgref = 1; 2163 uint8_t segNumber = 0, segInfo, numSegments; 2164 uint16_t chunk_len, total_bytes; 2165 uint8_t *bufpos; 2166 struct seg_hdr_info segHdrInfo; 2167 2168 bufpos = param->utf_payload; 2169 total_bytes = param->len; 2170 ASSERT(total_bytes / MAX_WMI_UTF_LEN == 2171 (uint8_t) (total_bytes / MAX_WMI_UTF_LEN)); 2172 numSegments = (uint8_t) (total_bytes / MAX_WMI_UTF_LEN); 2173 2174 if (param->len - (numSegments * MAX_WMI_UTF_LEN)) 2175 numSegments++; 2176 2177 while (param->len) { 2178 if (param->len > MAX_WMI_UTF_LEN) 2179 chunk_len = MAX_WMI_UTF_LEN; /* MAX message */ 2180 else 2181 chunk_len = param->len; 2182 2183 buf = wmi_buf_alloc(wmi_handle, 2184 (chunk_len + sizeof(segHdrInfo) + 2185 WMI_TLV_HDR_SIZE)); 2186 if (!buf) 2187 return QDF_STATUS_E_NOMEM; 2188 2189 cmd = (uint8_t *) wmi_buf_data(buf); 2190 2191 segHdrInfo.len = total_bytes; 2192 segHdrInfo.msgref = msgref; 2193 segInfo = ((numSegments << 4) & 0xF0) | (segNumber & 0xF); 2194 segHdrInfo.segmentInfo = segInfo; 2195 segHdrInfo.pad = 0; 2196 2197 wmi_debug("segHdrInfo.len = %d, segHdrInfo.msgref = %d," 2198 " segHdrInfo.segmentInfo = %d", 2199 segHdrInfo.len, segHdrInfo.msgref, 2200 segHdrInfo.segmentInfo); 2201 2202 wmi_debug("total_bytes %d segNumber %d totalSegments %d" 2203 " chunk len %d", total_bytes, segNumber, 2204 numSegments, chunk_len); 2205 2206 segNumber++; 2207 2208 WMITLV_SET_HDR(cmd, WMITLV_TAG_ARRAY_BYTE, 2209 (chunk_len + sizeof(segHdrInfo))); 2210 cmd += WMI_TLV_HDR_SIZE; 2211 memcpy(cmd, &segHdrInfo, sizeof(segHdrInfo)); /* 4 bytes */ 2212 WMI_HOST_IF_MSG_COPY_CHAR_ARRAY(&cmd[sizeof(segHdrInfo)], 2213 bufpos, chunk_len); 2214 2215 wmi_mtrace(WMI_PDEV_UTF_CMDID, NO_SESSION, 0); 2216 ret = wmi_unified_cmd_send(wmi_handle, buf, 2217 (chunk_len + sizeof(segHdrInfo) + 2218 WMI_TLV_HDR_SIZE), 2219 WMI_PDEV_UTF_CMDID); 2220 2221 if (QDF_IS_STATUS_ERROR(ret)) { 2222 wmi_err("Failed to send WMI_PDEV_UTF_CMDID command"); 2223 wmi_buf_free(buf); 2224 break; 2225 } 2226 2227 param->len -= chunk_len; 2228 bufpos += chunk_len; 2229 } 2230 2231 msgref++; 2232 2233 return ret; 2234 } 2235 2236 #ifdef ENABLE_HOST_TO_TARGET_CONVERSION 2237 static inline uint32_t convert_host_pdev_param_tlv(uint32_t host_param) 2238 { 2239 if (host_param < QDF_ARRAY_SIZE(pdev_param_tlv)) 2240 return pdev_param_tlv[host_param]; 2241 return WMI_UNAVAILABLE_PARAM; 2242 } 2243 2244 static inline uint32_t convert_host_vdev_param_tlv(uint32_t host_param) 2245 { 2246 if (host_param < QDF_ARRAY_SIZE(vdev_param_tlv)) 2247 return vdev_param_tlv[host_param]; 2248 return WMI_UNAVAILABLE_PARAM; 2249 } 2250 #else 2251 static inline uint32_t convert_host_pdev_param_tlv(uint32_t host_param) 2252 { 2253 return host_param; 2254 } 2255 2256 static inline uint32_t convert_host_vdev_param_tlv(uint32_t host_param) 2257 { 2258 return host_param; 2259 } 2260 #endif /* end of ENABLE_HOST_TO_TARGET_CONVERSION */ 2261 2262 /** 2263 * send_pdev_param_cmd_tlv() - set pdev parameters 2264 * @wmi_handle: wmi handle 2265 * @param: pointer to pdev parameter 2266 * @mac_id: radio context 2267 * 2268 * Return: QDF_STATUS_SUCCESS for success or error code 2269 */ 2270 static QDF_STATUS 2271 send_pdev_param_cmd_tlv(wmi_unified_t wmi_handle, 2272 struct pdev_params *param, 2273 uint8_t mac_id) 2274 { 2275 QDF_STATUS ret; 2276 wmi_pdev_set_param_cmd_fixed_param *cmd; 2277 wmi_buf_t buf; 2278 uint16_t len = sizeof(*cmd); 2279 uint32_t pdev_param; 2280 2281 pdev_param = convert_host_pdev_param_tlv(param->param_id); 2282 if (pdev_param == WMI_UNAVAILABLE_PARAM) { 2283 wmi_err("Unavailable param %d", param->param_id); 2284 return QDF_STATUS_E_INVAL; 2285 } 2286 2287 buf = wmi_buf_alloc(wmi_handle, len); 2288 if (!buf) 2289 return QDF_STATUS_E_NOMEM; 2290 2291 cmd = (wmi_pdev_set_param_cmd_fixed_param *) wmi_buf_data(buf); 2292 WMITLV_SET_HDR(&cmd->tlv_header, 2293 WMITLV_TAG_STRUC_wmi_pdev_set_param_cmd_fixed_param, 2294 WMITLV_GET_STRUCT_TLVLEN 2295 (wmi_pdev_set_param_cmd_fixed_param)); 2296 if (param->is_host_pdev_id) 2297 cmd->pdev_id = wmi_handle->ops->convert_host_pdev_id_to_target( 2298 wmi_handle, 2299 mac_id); 2300 else 2301 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 2302 wmi_handle, 2303 mac_id); 2304 cmd->param_id = pdev_param; 2305 cmd->param_value = param->param_value; 2306 wmi_nofl_debug("Set pdev %d param 0x%x to %u", cmd->pdev_id, 2307 cmd->param_id, cmd->param_value); 2308 wmi_mtrace(WMI_PDEV_SET_PARAM_CMDID, NO_SESSION, 0); 2309 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 2310 WMI_PDEV_SET_PARAM_CMDID); 2311 if (QDF_IS_STATUS_ERROR(ret)) { 2312 wmi_buf_free(buf); 2313 } 2314 return ret; 2315 } 2316 2317 /** 2318 * send_multi_param_cmd_using_pdev_set_param_tlv() - set pdev parameters 2319 * @wmi_handle: wmi handle 2320 * @params: pointer to hold set_multiple_pdev_vdev_param info 2321 * 2322 * Return: QDF_STATUS_SUCCESS for success or error code 2323 */ 2324 static QDF_STATUS 2325 send_multi_param_cmd_using_pdev_set_param_tlv(wmi_unified_t wmi_handle, 2326 struct set_multiple_pdev_vdev_param *params) 2327 { 2328 uint8_t index; 2329 struct pdev_params pdevparam; 2330 uint8_t n_params = params->n_params; 2331 2332 pdevparam.is_host_pdev_id = params->is_host_pdev_id; 2333 for (index = 0; index < n_params; index++) { 2334 pdevparam.param_id = params->params[index].param_id; 2335 pdevparam.param_value = params->params[index].param_value; 2336 if (QDF_IS_STATUS_ERROR(send_pdev_param_cmd_tlv(wmi_handle, 2337 &pdevparam, 2338 params->dev_id))) { 2339 wmi_err("failed to send pdev setparam:%d", 2340 pdevparam.param_id); 2341 return QDF_STATUS_E_FAILURE; 2342 } 2343 } 2344 return QDF_STATUS_SUCCESS; 2345 } 2346 2347 #ifdef WLAN_PDEV_VDEV_SEND_MULTI_PARAM 2348 2349 /** 2350 * convert_host_pdev_vdev_param_id_to_target()- convert host params to target params 2351 * @params: pointer to point set_multiple_pdev_vdev_param info 2352 * 2353 * Return: returns QDF_STATUS 2354 */ 2355 static QDF_STATUS 2356 convert_host_pdev_vdev_param_id_to_target(struct set_multiple_pdev_vdev_param *params) 2357 { 2358 uint8_t index; 2359 uint32_t dev_paramid; 2360 uint8_t num = params->n_params; 2361 2362 if (params->param_type == MLME_PDEV_SETPARAM) { 2363 for (index = 0; index < num; index++) { 2364 dev_paramid = convert_host_pdev_param_tlv(params->params[index].param_id); 2365 if (dev_paramid == WMI_UNAVAILABLE_PARAM) { 2366 wmi_err("pdev param %d not available", 2367 params->params[index].param_id); 2368 return QDF_STATUS_E_INVAL; 2369 } 2370 params->params[index].param_id = dev_paramid; 2371 } 2372 } else if (params->param_type == MLME_VDEV_SETPARAM) { 2373 for (index = 0; index < num; index++) { 2374 dev_paramid = convert_host_vdev_param_tlv(params->params[index].param_id); 2375 if (dev_paramid == WMI_UNAVAILABLE_PARAM) { 2376 wmi_err("vdev param %d not available", 2377 params->params[index].param_id); 2378 return QDF_STATUS_E_INVAL; 2379 } 2380 params->params[index].param_id = dev_paramid; 2381 } 2382 } else { 2383 wmi_err("invalid param type"); 2384 return QDF_STATUS_E_INVAL; 2385 } 2386 return QDF_STATUS_SUCCESS; 2387 } 2388 2389 /** 2390 * send_multi_pdev_vdev_set_param_cmd_tlv()-set pdev/vdev params 2391 * @wmi_handle: wmi handle 2392 * @params: pointer to hold set_multiple_pdev_vdev_param info 2393 * 2394 * Return: returns QDF_STATUS 2395 */ 2396 static QDF_STATUS 2397 send_multi_pdev_vdev_set_param_cmd_tlv( 2398 wmi_unified_t wmi_handle, 2399 struct set_multiple_pdev_vdev_param *params) 2400 { 2401 uint8_t *buf_ptr; 2402 QDF_STATUS ret; 2403 wmi_buf_t buf; 2404 wmi_set_param_info *setparam; 2405 wmi_set_multiple_pdev_vdev_param_cmd_fixed_param *cmd; 2406 uint8_t num = params->n_params; 2407 uint16_t len; 2408 uint8_t index = 0; 2409 const char *dev_string[] = {"pdev", "vdev"}; 2410 2411 if (convert_host_pdev_vdev_param_id_to_target(params)) 2412 return QDF_STATUS_E_INVAL; 2413 2414 len = sizeof(*cmd) + WMI_TLV_HDR_SIZE + (num * sizeof(*setparam)); 2415 buf = wmi_buf_alloc(wmi_handle, len); 2416 if (!buf) 2417 return QDF_STATUS_E_NOMEM; 2418 2419 buf_ptr = (uint8_t *)wmi_buf_data(buf); 2420 cmd = (wmi_set_multiple_pdev_vdev_param_cmd_fixed_param *)buf_ptr; 2421 2422 WMITLV_SET_HDR(&cmd->tlv_header, 2423 WMITLV_TAG_STRUC_wmi_set_multiple_pdev_vdev_param_cmd_fixed_param, 2424 WMITLV_GET_STRUCT_TLVLEN(wmi_set_multiple_pdev_vdev_param_cmd_fixed_param)); 2425 2426 cmd->is_vdev = params->param_type; 2427 if (params->param_type == MLME_PDEV_SETPARAM) { 2428 if (params->is_host_pdev_id) 2429 params->dev_id = wmi_handle->ops->convert_host_pdev_id_to_target(wmi_handle, 2430 params->dev_id); 2431 else 2432 params->dev_id = wmi_handle->ops->convert_pdev_id_host_to_target(wmi_handle, 2433 params->dev_id); 2434 } 2435 cmd->dev_id = params->dev_id; 2436 buf_ptr += sizeof(wmi_set_multiple_pdev_vdev_param_cmd_fixed_param); 2437 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, (num * sizeof(*setparam))); 2438 buf_ptr += WMI_TLV_HDR_SIZE; 2439 for (index = 0; index < num; index++) { 2440 setparam = (wmi_set_param_info *)buf_ptr; 2441 WMITLV_SET_HDR(&setparam->tlv_header, 2442 WMITLV_TAG_STRUC_wmi_set_param_info, 2443 WMITLV_GET_STRUCT_TLVLEN(*setparam)); 2444 setparam->param_id = params->params[index].param_id; 2445 setparam->param_value = params->params[index].param_value; 2446 wmi_nofl_debug("Set %s %d param 0x%x to %u", 2447 dev_string[cmd->is_vdev], params->dev_id, 2448 setparam->param_id, setparam->param_value); 2449 buf_ptr += sizeof(*setparam); 2450 } 2451 wmi_mtrace(WMI_SET_MULTIPLE_PDEV_VDEV_PARAM_CMDID, 2452 cmd->dev_id, 0); 2453 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 2454 WMI_SET_MULTIPLE_PDEV_VDEV_PARAM_CMDID); 2455 if (QDF_IS_STATUS_ERROR(ret)) { 2456 wmi_buf_free(buf); 2457 } 2458 return ret; 2459 } 2460 2461 /** 2462 * send_multiple_pdev_param_cmd_tlv() - set pdev parameters 2463 * @wmi_handle: wmi handle 2464 * @params: pointer to set_multiple_pdev_vdev_param structure 2465 * 2466 * Return: QDF_STATUS_SUCCESS for success or error code 2467 */ 2468 static QDF_STATUS 2469 send_multiple_pdev_param_cmd_tlv(wmi_unified_t wmi_handle, 2470 struct set_multiple_pdev_vdev_param *params) 2471 { 2472 if (!wmi_service_enabled(wmi_handle, 2473 wmi_service_combined_set_param_support)) 2474 return send_multi_param_cmd_using_pdev_set_param_tlv(wmi_handle, 2475 params); 2476 return send_multi_pdev_vdev_set_param_cmd_tlv(wmi_handle, params); 2477 } 2478 2479 #else /* WLAN_PDEV_VDEV_SEND_MULTI_PARAM */ 2480 /** 2481 * send_multiple_pdev_param_cmd_tlv() - set pdev parameters 2482 * @wmi_handle: wmi handle 2483 * @params: pointer to set_multiple_pdev_vdev_param structure 2484 * 2485 * Return: QDF_STATUS_SUCCESS for success or error code 2486 */ 2487 static QDF_STATUS 2488 send_multiple_pdev_param_cmd_tlv(wmi_unified_t wmi_handle, 2489 struct set_multiple_pdev_vdev_param *params) 2490 { 2491 return send_multi_param_cmd_using_pdev_set_param_tlv(wmi_handle, params); 2492 } 2493 #endif /* end of WLAN_PDEV_VDEV_SEND_MULTI_PARAM */ 2494 2495 /** 2496 * send_pdev_set_hw_mode_cmd_tlv() - Send WMI_PDEV_SET_HW_MODE_CMDID to FW 2497 * @wmi_handle: wmi handle 2498 * @hw_mode_index: The HW_Mode field is a enumerated type that is selected 2499 * from the HW_Mode table, which is returned in the WMI_SERVICE_READY_EVENTID. 2500 * 2501 * Provides notification to the WLAN firmware that host driver is requesting a 2502 * HardWare (HW) Mode change. This command is needed to support iHelium in the 2503 * configurations that include the Dual Band Simultaneous (DBS) feature. 2504 * 2505 * Return: Success if the cmd is sent successfully to the firmware 2506 */ 2507 static QDF_STATUS send_pdev_set_hw_mode_cmd_tlv(wmi_unified_t wmi_handle, 2508 uint32_t hw_mode_index) 2509 { 2510 wmi_pdev_set_hw_mode_cmd_fixed_param *cmd; 2511 wmi_buf_t buf; 2512 uint32_t len; 2513 2514 len = sizeof(*cmd); 2515 2516 buf = wmi_buf_alloc(wmi_handle, len); 2517 if (!buf) 2518 return QDF_STATUS_E_NOMEM; 2519 2520 cmd = (wmi_pdev_set_hw_mode_cmd_fixed_param *)wmi_buf_data(buf); 2521 WMITLV_SET_HDR(&cmd->tlv_header, 2522 WMITLV_TAG_STRUC_wmi_pdev_set_hw_mode_cmd_fixed_param, 2523 WMITLV_GET_STRUCT_TLVLEN( 2524 wmi_pdev_set_hw_mode_cmd_fixed_param)); 2525 2526 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 2527 wmi_handle, 2528 WMI_HOST_PDEV_ID_SOC); 2529 cmd->hw_mode_index = hw_mode_index; 2530 wmi_debug("HW mode index:%d", cmd->hw_mode_index); 2531 2532 wmi_mtrace(WMI_PDEV_SET_HW_MODE_CMDID, NO_SESSION, 0); 2533 if (wmi_unified_cmd_send(wmi_handle, buf, len, 2534 WMI_PDEV_SET_HW_MODE_CMDID)) { 2535 wmi_err("Failed to send WMI_PDEV_SET_HW_MODE_CMDID"); 2536 wmi_buf_free(buf); 2537 return QDF_STATUS_E_FAILURE; 2538 } 2539 2540 return QDF_STATUS_SUCCESS; 2541 } 2542 2543 /** 2544 * send_pdev_set_rf_path_cmd_tlv() - Send WMI_PDEV_SET_RF_PATH_CMDID to FW 2545 * @wmi_handle: wmi handle 2546 * @rf_path_index: the rf path mode to be selected 2547 * @pdev_id: pdev id 2548 * 2549 * Provides notification to the WLAN firmware that host driver is requesting a 2550 * rf path change. 2551 * 2552 * Return: Success if the cmd is sent successfully to the firmware 2553 */ 2554 static QDF_STATUS send_pdev_set_rf_path_cmd_tlv(wmi_unified_t wmi_handle, 2555 uint32_t rf_path_index, 2556 uint8_t pdev_id) 2557 { 2558 wmi_pdev_set_rf_path_cmd_fixed_param *cmd; 2559 wmi_buf_t buf; 2560 uint32_t len; 2561 2562 len = sizeof(*cmd); 2563 2564 buf = wmi_buf_alloc(wmi_handle, len); 2565 if (!buf) 2566 return QDF_STATUS_E_NOMEM; 2567 2568 cmd = (wmi_pdev_set_rf_path_cmd_fixed_param *)wmi_buf_data(buf); 2569 WMITLV_SET_HDR(&cmd->tlv_header, 2570 WMITLV_TAG_STRUC_wmi_pdev_set_rf_path_cmd_fixed_param, 2571 WMITLV_GET_STRUCT_TLVLEN( 2572 wmi_pdev_set_rf_path_cmd_fixed_param)); 2573 2574 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 2575 wmi_handle, 2576 pdev_id); 2577 cmd->rf_path = rf_path_index; 2578 wmi_debug("HW mode index:%d", cmd->rf_path); 2579 2580 wmi_mtrace(WMI_PDEV_SET_RF_PATH_CMDID, NO_SESSION, 0); 2581 if (wmi_unified_cmd_send(wmi_handle, buf, len, 2582 WMI_PDEV_SET_RF_PATH_CMDID)) { 2583 wmi_err("Failed to send WMI_PDEV_SET_RF_PATH_CMDID"); 2584 wmi_buf_free(buf); 2585 return QDF_STATUS_E_FAILURE; 2586 } 2587 2588 return QDF_STATUS_SUCCESS; 2589 } 2590 2591 /** 2592 * send_suspend_cmd_tlv() - WMI suspend function 2593 * @wmi_handle: handle to WMI. 2594 * @param: pointer to hold suspend parameter 2595 * @mac_id: radio context 2596 * 2597 * Return: QDF_STATUS_SUCCESS for success or error code 2598 */ 2599 static QDF_STATUS send_suspend_cmd_tlv(wmi_unified_t wmi_handle, 2600 struct suspend_params *param, 2601 uint8_t mac_id) 2602 { 2603 wmi_pdev_suspend_cmd_fixed_param *cmd; 2604 wmi_buf_t wmibuf; 2605 uint32_t len = sizeof(*cmd); 2606 int32_t ret; 2607 2608 /* 2609 * send the command to Target to ignore the 2610 * PCIE reset so as to ensure that Host and target 2611 * states are in sync 2612 */ 2613 wmibuf = wmi_buf_alloc(wmi_handle, len); 2614 if (!wmibuf) 2615 return QDF_STATUS_E_NOMEM; 2616 2617 cmd = (wmi_pdev_suspend_cmd_fixed_param *) wmi_buf_data(wmibuf); 2618 WMITLV_SET_HDR(&cmd->tlv_header, 2619 WMITLV_TAG_STRUC_wmi_pdev_suspend_cmd_fixed_param, 2620 WMITLV_GET_STRUCT_TLVLEN 2621 (wmi_pdev_suspend_cmd_fixed_param)); 2622 if (param->disable_target_intr) 2623 cmd->suspend_opt = WMI_PDEV_SUSPEND_AND_DISABLE_INTR; 2624 else 2625 cmd->suspend_opt = WMI_PDEV_SUSPEND; 2626 2627 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 2628 wmi_handle, 2629 mac_id); 2630 2631 wmi_mtrace(WMI_PDEV_SUSPEND_CMDID, NO_SESSION, 0); 2632 ret = wmi_unified_cmd_send(wmi_handle, wmibuf, len, 2633 WMI_PDEV_SUSPEND_CMDID); 2634 if (ret) { 2635 wmi_buf_free(wmibuf); 2636 wmi_err("Failed to send WMI_PDEV_SUSPEND_CMDID command"); 2637 } 2638 2639 return ret; 2640 } 2641 2642 /** 2643 * send_resume_cmd_tlv() - WMI resume function 2644 * @wmi_handle: handle to WMI. 2645 * @mac_id: radio context 2646 * 2647 * Return: QDF_STATUS_SUCCESS for success or error code 2648 */ 2649 static QDF_STATUS send_resume_cmd_tlv(wmi_unified_t wmi_handle, 2650 uint8_t mac_id) 2651 { 2652 wmi_buf_t wmibuf; 2653 wmi_pdev_resume_cmd_fixed_param *cmd; 2654 QDF_STATUS ret; 2655 2656 wmibuf = wmi_buf_alloc(wmi_handle, sizeof(*cmd)); 2657 if (!wmibuf) 2658 return QDF_STATUS_E_NOMEM; 2659 cmd = (wmi_pdev_resume_cmd_fixed_param *) wmi_buf_data(wmibuf); 2660 WMITLV_SET_HDR(&cmd->tlv_header, 2661 WMITLV_TAG_STRUC_wmi_pdev_resume_cmd_fixed_param, 2662 WMITLV_GET_STRUCT_TLVLEN 2663 (wmi_pdev_resume_cmd_fixed_param)); 2664 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 2665 wmi_handle, 2666 mac_id); 2667 wmi_mtrace(WMI_PDEV_RESUME_CMDID, NO_SESSION, 0); 2668 ret = wmi_unified_cmd_send(wmi_handle, wmibuf, sizeof(*cmd), 2669 WMI_PDEV_RESUME_CMDID); 2670 if (QDF_IS_STATUS_ERROR(ret)) { 2671 wmi_err("Failed to send WMI_PDEV_RESUME_CMDID command"); 2672 wmi_buf_free(wmibuf); 2673 } 2674 2675 return ret; 2676 } 2677 2678 /** 2679 * send_wow_enable_cmd_tlv() - WMI wow enable function 2680 * @wmi_handle: handle to WMI. 2681 * @param: pointer to hold wow enable parameter 2682 * @mac_id: radio context 2683 * 2684 * Return: QDF_STATUS_SUCCESS for success or error code 2685 */ 2686 static QDF_STATUS send_wow_enable_cmd_tlv(wmi_unified_t wmi_handle, 2687 struct wow_cmd_params *param, 2688 uint8_t mac_id) 2689 { 2690 wmi_wow_enable_cmd_fixed_param *cmd; 2691 wmi_buf_t buf; 2692 int32_t len; 2693 int32_t ret; 2694 2695 len = sizeof(wmi_wow_enable_cmd_fixed_param); 2696 2697 buf = wmi_buf_alloc(wmi_handle, len); 2698 if (!buf) 2699 return QDF_STATUS_E_NOMEM; 2700 2701 cmd = (wmi_wow_enable_cmd_fixed_param *) wmi_buf_data(buf); 2702 WMITLV_SET_HDR(&cmd->tlv_header, 2703 WMITLV_TAG_STRUC_wmi_wow_enable_cmd_fixed_param, 2704 WMITLV_GET_STRUCT_TLVLEN 2705 (wmi_wow_enable_cmd_fixed_param)); 2706 cmd->enable = param->enable; 2707 if (param->can_suspend_link) 2708 cmd->pause_iface_config = WOW_IFACE_PAUSE_ENABLED; 2709 else 2710 cmd->pause_iface_config = WOW_IFACE_PAUSE_DISABLED; 2711 cmd->flags = param->flags; 2712 2713 wmi_debug("suspend type: %s flag is 0x%x", 2714 cmd->pause_iface_config == WOW_IFACE_PAUSE_ENABLED ? 2715 "WOW_IFACE_PAUSE_ENABLED" : "WOW_IFACE_PAUSE_DISABLED", 2716 cmd->flags); 2717 2718 wmi_mtrace(WMI_WOW_ENABLE_CMDID, NO_SESSION, 0); 2719 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 2720 WMI_WOW_ENABLE_CMDID); 2721 if (ret) 2722 wmi_buf_free(buf); 2723 2724 return ret; 2725 } 2726 2727 /** 2728 * send_set_ap_ps_param_cmd_tlv() - set ap powersave parameters 2729 * @wmi_handle: wmi handle 2730 * @peer_addr: peer mac address 2731 * @param: pointer to ap_ps parameter structure 2732 * 2733 * Return: QDF_STATUS_SUCCESS for success or error code 2734 */ 2735 static QDF_STATUS send_set_ap_ps_param_cmd_tlv(wmi_unified_t wmi_handle, 2736 uint8_t *peer_addr, 2737 struct ap_ps_params *param) 2738 { 2739 wmi_ap_ps_peer_cmd_fixed_param *cmd; 2740 wmi_buf_t buf; 2741 int32_t err; 2742 2743 buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd)); 2744 if (!buf) 2745 return QDF_STATUS_E_NOMEM; 2746 2747 cmd = (wmi_ap_ps_peer_cmd_fixed_param *) wmi_buf_data(buf); 2748 WMITLV_SET_HDR(&cmd->tlv_header, 2749 WMITLV_TAG_STRUC_wmi_ap_ps_peer_cmd_fixed_param, 2750 WMITLV_GET_STRUCT_TLVLEN 2751 (wmi_ap_ps_peer_cmd_fixed_param)); 2752 cmd->vdev_id = param->vdev_id; 2753 WMI_CHAR_ARRAY_TO_MAC_ADDR(peer_addr, &cmd->peer_macaddr); 2754 cmd->param = param->param; 2755 cmd->value = param->value; 2756 wmi_mtrace(WMI_AP_PS_PEER_PARAM_CMDID, cmd->vdev_id, 0); 2757 err = wmi_unified_cmd_send(wmi_handle, buf, 2758 sizeof(*cmd), WMI_AP_PS_PEER_PARAM_CMDID); 2759 if (err) { 2760 wmi_err("Failed to send set_ap_ps_param cmd"); 2761 wmi_buf_free(buf); 2762 return QDF_STATUS_E_FAILURE; 2763 } 2764 2765 return 0; 2766 } 2767 2768 /** 2769 * send_set_sta_ps_param_cmd_tlv() - set sta powersave parameters 2770 * @wmi_handle: wmi handle 2771 * @param: pointer to sta_ps parameter structure 2772 * 2773 * Return: QDF_STATUS_SUCCESS for success or error code 2774 */ 2775 static QDF_STATUS send_set_sta_ps_param_cmd_tlv(wmi_unified_t wmi_handle, 2776 struct sta_ps_params *param) 2777 { 2778 wmi_sta_powersave_param_cmd_fixed_param *cmd; 2779 wmi_buf_t buf; 2780 int32_t len = sizeof(*cmd); 2781 2782 buf = wmi_buf_alloc(wmi_handle, len); 2783 if (!buf) 2784 return QDF_STATUS_E_NOMEM; 2785 2786 cmd = (wmi_sta_powersave_param_cmd_fixed_param *) wmi_buf_data(buf); 2787 WMITLV_SET_HDR(&cmd->tlv_header, 2788 WMITLV_TAG_STRUC_wmi_sta_powersave_param_cmd_fixed_param, 2789 WMITLV_GET_STRUCT_TLVLEN 2790 (wmi_sta_powersave_param_cmd_fixed_param)); 2791 cmd->vdev_id = param->vdev_id; 2792 cmd->param = param->param_id; 2793 cmd->value = param->value; 2794 2795 wmi_mtrace(WMI_STA_POWERSAVE_PARAM_CMDID, cmd->vdev_id, 0); 2796 if (wmi_unified_cmd_send(wmi_handle, buf, len, 2797 WMI_STA_POWERSAVE_PARAM_CMDID)) { 2798 wmi_err("Set Sta Ps param Failed vdevId %d Param %d val %d", 2799 param->vdev_id, param->param_id, param->value); 2800 wmi_buf_free(buf); 2801 return QDF_STATUS_E_FAILURE; 2802 } 2803 2804 return 0; 2805 } 2806 2807 /** 2808 * send_crash_inject_cmd_tlv() - inject fw crash 2809 * @wmi_handle: wmi handle 2810 * @param: pointer to crash inject parameter structure 2811 * 2812 * Return: QDF_STATUS_SUCCESS for success or return error 2813 */ 2814 static QDF_STATUS send_crash_inject_cmd_tlv(wmi_unified_t wmi_handle, 2815 struct crash_inject *param) 2816 { 2817 int32_t ret = 0; 2818 WMI_FORCE_FW_HANG_CMD_fixed_param *cmd; 2819 uint16_t len = sizeof(*cmd); 2820 wmi_buf_t buf; 2821 2822 buf = wmi_buf_alloc(wmi_handle, len); 2823 if (!buf) 2824 return QDF_STATUS_E_NOMEM; 2825 2826 cmd = (WMI_FORCE_FW_HANG_CMD_fixed_param *) wmi_buf_data(buf); 2827 WMITLV_SET_HDR(&cmd->tlv_header, 2828 WMITLV_TAG_STRUC_WMI_FORCE_FW_HANG_CMD_fixed_param, 2829 WMITLV_GET_STRUCT_TLVLEN 2830 (WMI_FORCE_FW_HANG_CMD_fixed_param)); 2831 cmd->type = param->type; 2832 cmd->delay_time_ms = param->delay_time_ms; 2833 2834 wmi_mtrace(WMI_FORCE_FW_HANG_CMDID, NO_SESSION, 0); 2835 wmi_info("type:%d delay_time_ms:%d current_time:%ld", 2836 cmd->type, cmd->delay_time_ms, qdf_mc_timer_get_system_time()); 2837 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 2838 WMI_FORCE_FW_HANG_CMDID); 2839 if (ret) { 2840 wmi_err("Failed to send set param command, ret = %d", ret); 2841 wmi_buf_free(buf); 2842 } 2843 2844 return ret; 2845 } 2846 2847 /** 2848 * send_dbglog_cmd_tlv() - set debug log level 2849 * @wmi_handle: handle to WMI. 2850 * @dbglog_param: pointer to hold dbglog level parameter 2851 * 2852 * Return: QDF_STATUS_SUCCESS on success, otherwise QDF_STATUS_E_* 2853 */ 2854 static QDF_STATUS 2855 send_dbglog_cmd_tlv(wmi_unified_t wmi_handle, 2856 struct dbglog_params *dbglog_param) 2857 { 2858 wmi_buf_t buf; 2859 wmi_debug_log_config_cmd_fixed_param *configmsg; 2860 QDF_STATUS status; 2861 int32_t i; 2862 int32_t len; 2863 int8_t *buf_ptr; 2864 int32_t *module_id_bitmap_array; /* Used to form the second tlv */ 2865 2866 ASSERT(dbglog_param->bitmap_len < MAX_MODULE_ID_BITMAP_WORDS); 2867 2868 /* Allocate size for 2 tlvs - including tlv hdr space for second tlv */ 2869 len = sizeof(wmi_debug_log_config_cmd_fixed_param) + WMI_TLV_HDR_SIZE + 2870 (sizeof(int32_t) * MAX_MODULE_ID_BITMAP_WORDS); 2871 buf = wmi_buf_alloc(wmi_handle, len); 2872 if (!buf) 2873 return QDF_STATUS_E_NOMEM; 2874 2875 configmsg = 2876 (wmi_debug_log_config_cmd_fixed_param *) (wmi_buf_data(buf)); 2877 buf_ptr = (int8_t *) configmsg; 2878 WMITLV_SET_HDR(&configmsg->tlv_header, 2879 WMITLV_TAG_STRUC_wmi_debug_log_config_cmd_fixed_param, 2880 WMITLV_GET_STRUCT_TLVLEN 2881 (wmi_debug_log_config_cmd_fixed_param)); 2882 configmsg->dbg_log_param = dbglog_param->param; 2883 configmsg->value = dbglog_param->val; 2884 /* Filling in the data part of second tlv -- should 2885 * follow first tlv _ WMI_TLV_HDR_SIZE */ 2886 module_id_bitmap_array = (uint32_t *) (buf_ptr + 2887 sizeof 2888 (wmi_debug_log_config_cmd_fixed_param) 2889 + WMI_TLV_HDR_SIZE); 2890 WMITLV_SET_HDR(buf_ptr + sizeof(wmi_debug_log_config_cmd_fixed_param), 2891 WMITLV_TAG_ARRAY_UINT32, 2892 sizeof(uint32_t) * MAX_MODULE_ID_BITMAP_WORDS); 2893 if (dbglog_param->module_id_bitmap) { 2894 for (i = 0; i < dbglog_param->bitmap_len; ++i) { 2895 module_id_bitmap_array[i] = 2896 dbglog_param->module_id_bitmap[i]; 2897 } 2898 } 2899 2900 wmi_mtrace(WMI_DBGLOG_CFG_CMDID, NO_SESSION, 0); 2901 status = wmi_unified_cmd_send(wmi_handle, buf, 2902 len, WMI_DBGLOG_CFG_CMDID); 2903 2904 if (status != QDF_STATUS_SUCCESS) 2905 wmi_buf_free(buf); 2906 2907 return status; 2908 } 2909 2910 /** 2911 * send_vdev_set_param_cmd_tlv() - WMI vdev set parameter function 2912 * @wmi_handle: handle to WMI. 2913 * @param: pointer to hold vdev set parameter 2914 * 2915 * Return: QDF_STATUS_SUCCESS for success or error code 2916 */ 2917 static QDF_STATUS send_vdev_set_param_cmd_tlv(wmi_unified_t wmi_handle, 2918 struct vdev_set_params *param) 2919 { 2920 QDF_STATUS ret; 2921 wmi_vdev_set_param_cmd_fixed_param *cmd; 2922 wmi_buf_t buf; 2923 uint16_t len = sizeof(*cmd); 2924 uint32_t vdev_param; 2925 2926 vdev_param = convert_host_vdev_param_tlv(param->param_id); 2927 if (vdev_param == WMI_UNAVAILABLE_PARAM) { 2928 wmi_err("Vdev param %d not available", param->param_id); 2929 return QDF_STATUS_E_INVAL; 2930 2931 } 2932 2933 buf = wmi_buf_alloc(wmi_handle, len); 2934 if (!buf) 2935 return QDF_STATUS_E_NOMEM; 2936 2937 cmd = (wmi_vdev_set_param_cmd_fixed_param *) wmi_buf_data(buf); 2938 WMITLV_SET_HDR(&cmd->tlv_header, 2939 WMITLV_TAG_STRUC_wmi_vdev_set_param_cmd_fixed_param, 2940 WMITLV_GET_STRUCT_TLVLEN(wmi_vdev_set_param_cmd_fixed_param)); 2941 cmd->vdev_id = param->vdev_id; 2942 cmd->param_id = vdev_param; 2943 cmd->param_value = param->param_value; 2944 wmi_nofl_debug("Set vdev %d param 0x%x to %u", 2945 cmd->vdev_id, cmd->param_id, cmd->param_value); 2946 wmi_mtrace(WMI_VDEV_SET_PARAM_CMDID, cmd->vdev_id, 0); 2947 ret = wmi_unified_cmd_send(wmi_handle, buf, len, WMI_VDEV_SET_PARAM_CMDID); 2948 if (QDF_IS_STATUS_ERROR(ret)) { 2949 wmi_buf_free(buf); 2950 } 2951 2952 return ret; 2953 } 2954 2955 /** 2956 * send_multi_param_cmd_using_vdev_param_tlv() - vdev set parameter function 2957 * @wmi_handle : handle to WMI. 2958 * @params: pointer to parameters to set 2959 * 2960 * Return: QDF_STATUS_SUCCESS on success, otherwise QDF_STATUS_E_* 2961 */ 2962 static QDF_STATUS 2963 send_multi_param_cmd_using_vdev_param_tlv(wmi_unified_t wmi_handle, 2964 struct set_multiple_pdev_vdev_param *params) 2965 { 2966 uint8_t index; 2967 struct vdev_set_params vdevparam; 2968 2969 for (index = 0; index < params->n_params; index++) { 2970 vdevparam.param_id = params->params[index].param_id; 2971 vdevparam.param_value = params->params[index].param_value; 2972 vdevparam.vdev_id = params->dev_id; 2973 if (QDF_IS_STATUS_ERROR(send_vdev_set_param_cmd_tlv(wmi_handle, &vdevparam))) { 2974 wmi_err("failed to send param:%d", vdevparam.param_id); 2975 return QDF_STATUS_E_FAILURE; 2976 } 2977 } 2978 return QDF_STATUS_SUCCESS; 2979 } 2980 2981 #ifdef WLAN_PDEV_VDEV_SEND_MULTI_PARAM 2982 /** 2983 * send_multiple_vdev_param_cmd_tlv() - WMI vdev set parameter function 2984 * @wmi_handle : handle to WMI. 2985 * @params: pointer to hold set_multiple_pdev_vdev_param info 2986 * 2987 * Return: QDF_STATUS_SUCCESS for success or error code 2988 */ 2989 static QDF_STATUS 2990 send_multiple_vdev_param_cmd_tlv(wmi_unified_t wmi_handle, 2991 struct set_multiple_pdev_vdev_param *params) 2992 { 2993 if (!wmi_service_enabled(wmi_handle, 2994 wmi_service_combined_set_param_support)) 2995 return send_multi_param_cmd_using_vdev_param_tlv(wmi_handle, 2996 params); 2997 return send_multi_pdev_vdev_set_param_cmd_tlv(wmi_handle, params); 2998 } 2999 3000 #else /* WLAN_PDEV_VDEV_SEND_MULTI_PARAM */ 3001 3002 /** 3003 * send_multiple_vdev_param_cmd_tlv() - WMI vdev set parameter function 3004 * @wmi_handle : handle to WMI. 3005 * @params: pointer to hold set_multiple_pdev_vdev_param info 3006 * 3007 * Return: QDF_STATUS_SUCCESS for success or error code 3008 */ 3009 static QDF_STATUS 3010 send_multiple_vdev_param_cmd_tlv(wmi_unified_t wmi_handle, 3011 struct set_multiple_pdev_vdev_param *params) 3012 { 3013 return send_multi_param_cmd_using_vdev_param_tlv(wmi_handle, params); 3014 } 3015 #endif /*end of WLAN_PDEV_VDEV_SEND_MULTI_PARAM */ 3016 3017 /** 3018 * send_vdev_set_mu_snif_cmd_tlv() - WMI vdev set mu snif function 3019 * @wmi_handle: handle to WMI. 3020 * @param: pointer to hold mu sniffer parameter 3021 * 3022 * Return: QDF_STATUS_SUCCESS for success or error code 3023 */ 3024 static 3025 QDF_STATUS send_vdev_set_mu_snif_cmd_tlv(wmi_unified_t wmi_handle, 3026 struct vdev_set_mu_snif_param *param) 3027 { 3028 QDF_STATUS ret; 3029 wmi_vdev_set_mu_snif_cmd_param *cmd; 3030 wmi_buf_t buf; 3031 uint32_t *tmp_ptr; 3032 uint16_t len = sizeof(*cmd); 3033 uint8_t *buf_ptr; 3034 uint32_t i; 3035 3036 /* Length TLV placeholder for array of uint32_t */ 3037 len += WMI_TLV_HDR_SIZE; 3038 3039 if (param->num_aid) 3040 len += param->num_aid * sizeof(uint32_t); 3041 3042 buf = wmi_buf_alloc(wmi_handle, len); 3043 if (!buf) 3044 return QDF_STATUS_E_NOMEM; 3045 3046 buf_ptr = (uint8_t *)wmi_buf_data(buf); 3047 cmd = (wmi_vdev_set_mu_snif_cmd_param *)buf_ptr; 3048 3049 WMITLV_SET_HDR(&cmd->tlv_header, 3050 WMITLV_TAG_STRUC_wmi_vdev_set_mu_snif_cmd_param, 3051 WMITLV_GET_STRUCT_TLVLEN 3052 (wmi_vdev_set_mu_snif_cmd_param)); 3053 3054 cmd->vdev_id = param->vdev_id; 3055 cmd->mode = param->mode; 3056 cmd->max_num_user = param->num_user; 3057 3058 buf_ptr += sizeof(*cmd); 3059 3060 tmp_ptr = (uint32_t *)(buf_ptr + WMI_TLV_HDR_SIZE); 3061 3062 for (i = 0; i < param->num_aid; ++i) 3063 tmp_ptr[i] = param->aid[i]; 3064 3065 WMITLV_SET_HDR(buf_ptr, 3066 WMITLV_TAG_ARRAY_UINT32, 3067 (param->num_aid * sizeof(uint32_t))); 3068 3069 wmi_debug("Setting vdev %d mode = %x, max user = %u aids= %u", 3070 cmd->vdev_id, cmd->mode, cmd->max_num_user, param->num_aid); 3071 wmi_mtrace(WMI_VDEV_SET_PARAM_CMDID, cmd->vdev_id, 0); 3072 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 3073 WMI_VDEV_SET_MU_SNIF_CMDID); 3074 if (QDF_IS_STATUS_ERROR(ret)) { 3075 wmi_err("Failed to send set param command ret = %d", ret); 3076 wmi_buf_free(buf); 3077 } 3078 3079 return ret; 3080 } 3081 3082 /** 3083 * send_peer_based_pktlog_cmd() - Send WMI command to enable packet-log 3084 * @wmi_handle: handle to WMI. 3085 * @macaddr: Peer mac address to be filter 3086 * @mac_id: mac id to have radio context 3087 * @enb_dsb: Enable MAC based filtering or Disable 3088 * 3089 * Return: QDF_STATUS 3090 */ 3091 static QDF_STATUS send_peer_based_pktlog_cmd(wmi_unified_t wmi_handle, 3092 uint8_t *macaddr, 3093 uint8_t mac_id, 3094 uint8_t enb_dsb) 3095 { 3096 int32_t ret; 3097 wmi_pdev_pktlog_filter_cmd_fixed_param *cmd; 3098 wmi_pdev_pktlog_filter_info *mac_info; 3099 wmi_buf_t buf; 3100 uint8_t *buf_ptr; 3101 uint16_t len = sizeof(wmi_pdev_pktlog_filter_cmd_fixed_param) + 3102 sizeof(wmi_pdev_pktlog_filter_info) + WMI_TLV_HDR_SIZE; 3103 3104 buf = wmi_buf_alloc(wmi_handle, len); 3105 if (!buf) 3106 return QDF_STATUS_E_NOMEM; 3107 3108 buf_ptr = (uint8_t *)wmi_buf_data(buf); 3109 cmd = (wmi_pdev_pktlog_filter_cmd_fixed_param *)buf_ptr; 3110 WMITLV_SET_HDR(&cmd->tlv_header, 3111 WMITLV_TAG_STRUC_wmi_pdev_pktlog_filter_cmd_fixed_param, 3112 WMITLV_GET_STRUCT_TLVLEN 3113 (wmi_pdev_pktlog_filter_cmd_fixed_param)); 3114 cmd->pdev_id = mac_id; 3115 cmd->enable = enb_dsb; 3116 cmd->num_of_mac_addresses = 1; 3117 wmi_mtrace(WMI_PDEV_PKTLOG_FILTER_CMDID, cmd->pdev_id, 0); 3118 3119 buf_ptr += sizeof(*cmd); 3120 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 3121 sizeof(wmi_pdev_pktlog_filter_info)); 3122 buf_ptr += WMI_TLV_HDR_SIZE; 3123 3124 mac_info = (wmi_pdev_pktlog_filter_info *)(buf_ptr); 3125 3126 WMITLV_SET_HDR(&mac_info->tlv_header, 3127 WMITLV_TAG_STRUC_wmi_pdev_pktlog_filter_info, 3128 WMITLV_GET_STRUCT_TLVLEN 3129 (wmi_pdev_pktlog_filter_info)); 3130 3131 WMI_CHAR_ARRAY_TO_MAC_ADDR(macaddr, &mac_info->peer_mac_address); 3132 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 3133 WMI_PDEV_PKTLOG_FILTER_CMDID); 3134 if (ret) { 3135 wmi_err("Failed to send peer based pktlog command to FW =%d" 3136 , ret); 3137 wmi_buf_free(buf); 3138 } 3139 3140 return ret; 3141 } 3142 3143 /** 3144 * send_packet_log_enable_cmd_tlv() - Send WMI command to enable packet-log 3145 * @wmi_handle: handle to WMI. 3146 * @PKTLOG_EVENT: packet log event 3147 * @mac_id: mac id to have radio context 3148 * 3149 * Return: QDF_STATUS_SUCCESS for success or error code 3150 */ 3151 static QDF_STATUS send_packet_log_enable_cmd_tlv(wmi_unified_t wmi_handle, 3152 WMI_HOST_PKTLOG_EVENT PKTLOG_EVENT, uint8_t mac_id) 3153 { 3154 int32_t ret, idx, max_idx; 3155 wmi_pdev_pktlog_enable_cmd_fixed_param *cmd; 3156 wmi_buf_t buf; 3157 uint16_t len = sizeof(wmi_pdev_pktlog_enable_cmd_fixed_param); 3158 3159 buf = wmi_buf_alloc(wmi_handle, len); 3160 if (!buf) 3161 return -QDF_STATUS_E_NOMEM; 3162 3163 cmd = (wmi_pdev_pktlog_enable_cmd_fixed_param *) wmi_buf_data(buf); 3164 WMITLV_SET_HDR(&cmd->tlv_header, 3165 WMITLV_TAG_STRUC_wmi_pdev_pktlog_enable_cmd_fixed_param, 3166 WMITLV_GET_STRUCT_TLVLEN 3167 (wmi_pdev_pktlog_enable_cmd_fixed_param)); 3168 max_idx = sizeof(pktlog_event_tlv) / (sizeof(pktlog_event_tlv[0])); 3169 cmd->evlist = 0; 3170 for (idx = 0; idx < max_idx; idx++) { 3171 if (PKTLOG_EVENT & (1 << idx)) 3172 cmd->evlist |= pktlog_event_tlv[idx]; 3173 } 3174 cmd->pdev_id = mac_id; 3175 wmi_mtrace(WMI_PDEV_PKTLOG_ENABLE_CMDID, cmd->pdev_id, 0); 3176 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 3177 WMI_PDEV_PKTLOG_ENABLE_CMDID); 3178 if (ret) { 3179 wmi_err("Failed to send pktlog enable cmd to FW =%d", ret); 3180 wmi_buf_free(buf); 3181 } 3182 3183 return ret; 3184 } 3185 3186 /** 3187 * send_packet_log_disable_cmd_tlv() - Send WMI command to disable packet-log 3188 * @wmi_handle: handle to WMI. 3189 * @mac_id: mac id to have radio context 3190 * 3191 * Return: QDF_STATUS_SUCCESS for success or error code 3192 */ 3193 static QDF_STATUS send_packet_log_disable_cmd_tlv(wmi_unified_t wmi_handle, 3194 uint8_t mac_id) 3195 { 3196 int32_t ret; 3197 wmi_pdev_pktlog_disable_cmd_fixed_param *cmd; 3198 wmi_buf_t buf; 3199 uint16_t len = sizeof(wmi_pdev_pktlog_disable_cmd_fixed_param); 3200 3201 buf = wmi_buf_alloc(wmi_handle, len); 3202 if (!buf) 3203 return -QDF_STATUS_E_NOMEM; 3204 3205 cmd = (wmi_pdev_pktlog_disable_cmd_fixed_param *) wmi_buf_data(buf); 3206 WMITLV_SET_HDR(&cmd->tlv_header, 3207 WMITLV_TAG_STRUC_wmi_pdev_pktlog_disable_cmd_fixed_param, 3208 WMITLV_GET_STRUCT_TLVLEN 3209 (wmi_pdev_pktlog_disable_cmd_fixed_param)); 3210 cmd->pdev_id = mac_id; 3211 wmi_mtrace(WMI_PDEV_PKTLOG_DISABLE_CMDID, cmd->pdev_id, 0); 3212 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 3213 WMI_PDEV_PKTLOG_DISABLE_CMDID); 3214 if (ret) { 3215 wmi_err("Failed to send pktlog disable cmd to FW =%d", ret); 3216 wmi_buf_free(buf); 3217 } 3218 3219 return ret; 3220 } 3221 3222 #define WMI_FW_TIME_STAMP_LOW_MASK 0xffffffff 3223 /** 3224 * send_time_stamp_sync_cmd_tlv() - Send WMI command to 3225 * sync time between between host and firmware 3226 * @wmi_handle: handle to WMI. 3227 * 3228 * Return: None 3229 */ 3230 static void send_time_stamp_sync_cmd_tlv(wmi_unified_t wmi_handle) 3231 { 3232 wmi_buf_t buf; 3233 QDF_STATUS status = QDF_STATUS_SUCCESS; 3234 WMI_DBGLOG_TIME_STAMP_SYNC_CMD_fixed_param *time_stamp; 3235 int32_t len; 3236 qdf_time_t time_ms; 3237 3238 len = sizeof(*time_stamp); 3239 buf = wmi_buf_alloc(wmi_handle, len); 3240 3241 if (!buf) 3242 return; 3243 3244 time_stamp = 3245 (WMI_DBGLOG_TIME_STAMP_SYNC_CMD_fixed_param *) 3246 (wmi_buf_data(buf)); 3247 WMITLV_SET_HDR(&time_stamp->tlv_header, 3248 WMITLV_TAG_STRUC_wmi_dbglog_time_stamp_sync_cmd_fixed_param, 3249 WMITLV_GET_STRUCT_TLVLEN( 3250 WMI_DBGLOG_TIME_STAMP_SYNC_CMD_fixed_param)); 3251 3252 time_ms = qdf_get_time_of_the_day_ms(); 3253 time_stamp->mode = WMI_TIME_STAMP_SYNC_MODE_MS; 3254 time_stamp->time_stamp_low = time_ms & 3255 WMI_FW_TIME_STAMP_LOW_MASK; 3256 /* 3257 * Send time_stamp_high 0 as the time converted from HR:MIN:SEC:MS to ms 3258 * won't exceed 27 bit 3259 */ 3260 time_stamp->time_stamp_high = 0; 3261 wmi_debug("WMA --> DBGLOG_TIME_STAMP_SYNC_CMDID mode %d time_stamp low %d high %d", 3262 time_stamp->mode, time_stamp->time_stamp_low, 3263 time_stamp->time_stamp_high); 3264 3265 wmi_mtrace(WMI_DBGLOG_TIME_STAMP_SYNC_CMDID, NO_SESSION, 0); 3266 status = wmi_unified_cmd_send(wmi_handle, buf, 3267 len, WMI_DBGLOG_TIME_STAMP_SYNC_CMDID); 3268 if (status) { 3269 wmi_err("Failed to send WMI_DBGLOG_TIME_STAMP_SYNC_CMDID command"); 3270 wmi_buf_free(buf); 3271 } 3272 3273 } 3274 3275 /** 3276 * send_fd_tmpl_cmd_tlv() - WMI FILS Discovery send function 3277 * @wmi_handle: handle to WMI. 3278 * @param: pointer to hold FILS Discovery send cmd parameter 3279 * 3280 * Return: QDF_STATUS_SUCCESS for success or error code 3281 */ 3282 static QDF_STATUS send_fd_tmpl_cmd_tlv(wmi_unified_t wmi_handle, 3283 struct fils_discovery_tmpl_params *param) 3284 { 3285 int32_t ret; 3286 wmi_fd_tmpl_cmd_fixed_param *cmd; 3287 wmi_buf_t wmi_buf; 3288 uint8_t *buf_ptr; 3289 uint32_t wmi_buf_len; 3290 3291 wmi_buf_len = sizeof(wmi_fd_tmpl_cmd_fixed_param) + 3292 WMI_TLV_HDR_SIZE + param->tmpl_len_aligned; 3293 wmi_buf = wmi_buf_alloc(wmi_handle, wmi_buf_len); 3294 if (!wmi_buf) 3295 return QDF_STATUS_E_NOMEM; 3296 3297 buf_ptr = (uint8_t *) wmi_buf_data(wmi_buf); 3298 cmd = (wmi_fd_tmpl_cmd_fixed_param *) buf_ptr; 3299 WMITLV_SET_HDR(&cmd->tlv_header, 3300 WMITLV_TAG_STRUC_wmi_fd_tmpl_cmd_fixed_param, 3301 WMITLV_GET_STRUCT_TLVLEN(wmi_fd_tmpl_cmd_fixed_param)); 3302 cmd->vdev_id = param->vdev_id; 3303 cmd->buf_len = param->tmpl_len; 3304 buf_ptr += sizeof(wmi_fd_tmpl_cmd_fixed_param); 3305 3306 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, param->tmpl_len_aligned); 3307 buf_ptr += WMI_TLV_HDR_SIZE; 3308 qdf_mem_copy(buf_ptr, param->frm, param->tmpl_len); 3309 3310 wmi_mtrace(WMI_FD_TMPL_CMDID, cmd->vdev_id, 0); 3311 ret = wmi_unified_cmd_send(wmi_handle, 3312 wmi_buf, wmi_buf_len, WMI_FD_TMPL_CMDID); 3313 3314 if (ret) { 3315 wmi_err("Failed to send fd tmpl: %d", ret); 3316 wmi_buf_free(wmi_buf); 3317 return ret; 3318 } 3319 3320 return 0; 3321 } 3322 3323 /** 3324 * send_beacon_tmpl_send_cmd_tlv() - WMI beacon send function 3325 * @wmi_handle: handle to WMI. 3326 * @param: pointer to hold beacon send cmd parameter 3327 * 3328 * Return: QDF_STATUS_SUCCESS for success or error code 3329 */ 3330 static QDF_STATUS send_beacon_tmpl_send_cmd_tlv(wmi_unified_t wmi_handle, 3331 struct beacon_tmpl_params *param) 3332 { 3333 int32_t ret; 3334 wmi_bcn_tmpl_cmd_fixed_param *cmd; 3335 wmi_bcn_prb_info *bcn_prb_info; 3336 wmi_buf_t wmi_buf; 3337 uint8_t *buf_ptr; 3338 uint32_t wmi_buf_len; 3339 3340 wmi_buf_len = sizeof(wmi_bcn_tmpl_cmd_fixed_param) + 3341 sizeof(wmi_bcn_prb_info) + WMI_TLV_HDR_SIZE + 3342 param->tmpl_len_aligned + 3343 bcn_tmpl_mlo_param_size(param) + 3344 bcn_tmpl_ml_info_size(param); 3345 3346 wmi_buf = wmi_buf_alloc(wmi_handle, wmi_buf_len); 3347 if (!wmi_buf) 3348 return QDF_STATUS_E_NOMEM; 3349 3350 buf_ptr = (uint8_t *) wmi_buf_data(wmi_buf); 3351 cmd = (wmi_bcn_tmpl_cmd_fixed_param *) buf_ptr; 3352 WMITLV_SET_HDR(&cmd->tlv_header, 3353 WMITLV_TAG_STRUC_wmi_bcn_tmpl_cmd_fixed_param, 3354 WMITLV_GET_STRUCT_TLVLEN(wmi_bcn_tmpl_cmd_fixed_param)); 3355 cmd->vdev_id = param->vdev_id; 3356 cmd->tim_ie_offset = param->tim_ie_offset; 3357 cmd->mbssid_ie_offset = param->mbssid_ie_offset; 3358 cmd->csa_switch_count_offset = param->csa_switch_count_offset; 3359 cmd->ext_csa_switch_count_offset = param->ext_csa_switch_count_offset; 3360 cmd->esp_ie_offset = param->esp_ie_offset; 3361 cmd->mu_edca_ie_offset = param->mu_edca_ie_offset; 3362 cmd->ema_params = param->ema_params; 3363 cmd->buf_len = param->tmpl_len; 3364 cmd->csa_event_bitmap = param->csa_event_bitmap; 3365 3366 WMI_BEACON_PROTECTION_EN_SET(cmd->feature_enable_bitmap, 3367 param->enable_bigtk); 3368 buf_ptr += sizeof(wmi_bcn_tmpl_cmd_fixed_param); 3369 3370 bcn_prb_info = (wmi_bcn_prb_info *) buf_ptr; 3371 WMITLV_SET_HDR(&bcn_prb_info->tlv_header, 3372 WMITLV_TAG_STRUC_wmi_bcn_prb_info, 3373 WMITLV_GET_STRUCT_TLVLEN(wmi_bcn_prb_info)); 3374 bcn_prb_info->caps = 0; 3375 bcn_prb_info->erp = 0; 3376 buf_ptr += sizeof(wmi_bcn_prb_info); 3377 3378 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, param->tmpl_len_aligned); 3379 buf_ptr += WMI_TLV_HDR_SIZE; 3380 3381 /* for big endian host, copy engine byte_swap is enabled 3382 * But the frame content is in network byte order 3383 * Need to byte swap the frame content - so when copy engine 3384 * does byte_swap - target gets frame content in the correct order 3385 */ 3386 WMI_HOST_IF_MSG_COPY_CHAR_ARRAY(buf_ptr, param->frm, 3387 param->tmpl_len); 3388 3389 buf_ptr += roundup(param->tmpl_len, sizeof(uint32_t)); 3390 buf_ptr = bcn_tmpl_add_ml_partner_links(buf_ptr, param); 3391 3392 buf_ptr = bcn_tmpl_add_ml_info(buf_ptr, param); 3393 3394 wmi_mtrace(WMI_BCN_TMPL_CMDID, cmd->vdev_id, 0); 3395 ret = wmi_unified_cmd_send(wmi_handle, 3396 wmi_buf, wmi_buf_len, WMI_BCN_TMPL_CMDID); 3397 if (ret) { 3398 wmi_err("Failed to send bcn tmpl: %d", ret); 3399 wmi_buf_free(wmi_buf); 3400 } 3401 3402 return 0; 3403 } 3404 3405 #ifdef WLAN_FEATURE_11BE 3406 static inline void copy_peer_flags_tlv_11be( 3407 wmi_peer_assoc_complete_cmd_fixed_param * cmd, 3408 struct peer_assoc_params *param) 3409 { 3410 if (param->bw_320) 3411 cmd->peer_flags_ext |= WMI_PEER_EXT_320MHZ; 3412 if (param->eht_flag) 3413 cmd->peer_flags_ext |= WMI_PEER_EXT_EHT; 3414 3415 wmi_debug("peer_flags_ext 0x%x", cmd->peer_flags_ext); 3416 } 3417 #else 3418 static inline void copy_peer_flags_tlv_11be( 3419 wmi_peer_assoc_complete_cmd_fixed_param * cmd, 3420 struct peer_assoc_params *param) 3421 { 3422 } 3423 #endif 3424 #ifdef WLAN_FEATURE_11BE_MLO 3425 static inline void copy_peer_flags_tlv_vendor( 3426 wmi_peer_assoc_complete_cmd_fixed_param * cmd, 3427 struct peer_assoc_params *param) 3428 { 3429 if (!(param->mlo_params.mlo_enabled)) 3430 return; 3431 if (param->qcn_node_flag) 3432 cmd->peer_flags_ext |= WMI_PEER_EXT_IS_QUALCOMM_NODE; 3433 if (param->mesh_node_flag) 3434 cmd->peer_flags_ext |= WMI_PEER_EXT_IS_MESH_NODE; 3435 3436 wmi_debug("peer_flags_ext 0x%x", cmd->peer_flags_ext); 3437 } 3438 #else 3439 static inline void copy_peer_flags_tlv_vendor( 3440 wmi_peer_assoc_complete_cmd_fixed_param * cmd, 3441 struct peer_assoc_params *param) 3442 { 3443 } 3444 #endif 3445 3446 static inline void copy_peer_flags_tlv( 3447 wmi_peer_assoc_complete_cmd_fixed_param * cmd, 3448 struct peer_assoc_params *param) 3449 { 3450 /* 3451 * The target only needs a subset of the flags maintained in the host. 3452 * Just populate those flags and send it down 3453 */ 3454 cmd->peer_flags = 0; 3455 if (param->peer_dms_capable) 3456 cmd->peer_flags_ext |= WMI_PEER_EXT_DMS_CAPABLE; 3457 /* 3458 * Do not enable HT/VHT if WMM/wme is disabled for vap. 3459 */ 3460 if (param->is_wme_set) { 3461 3462 if (param->qos_flag) 3463 cmd->peer_flags |= WMI_PEER_QOS; 3464 if (param->apsd_flag) 3465 cmd->peer_flags |= WMI_PEER_APSD; 3466 if (param->ht_flag) 3467 cmd->peer_flags |= WMI_PEER_HT; 3468 if (param->bw_40) 3469 cmd->peer_flags |= WMI_PEER_40MHZ; 3470 if (param->bw_80) 3471 cmd->peer_flags |= WMI_PEER_80MHZ; 3472 if (param->bw_160) 3473 cmd->peer_flags |= WMI_PEER_160MHZ; 3474 3475 copy_peer_flags_tlv_11be(cmd, param); 3476 copy_peer_flags_tlv_vendor(cmd, param); 3477 3478 /* Typically if STBC is enabled for VHT it should be enabled 3479 * for HT as well 3480 **/ 3481 if (param->stbc_flag) 3482 cmd->peer_flags |= WMI_PEER_STBC; 3483 3484 /* Typically if LDPC is enabled for VHT it should be enabled 3485 * for HT as well 3486 **/ 3487 if (param->ldpc_flag) 3488 cmd->peer_flags |= WMI_PEER_LDPC; 3489 3490 if (param->static_mimops_flag) 3491 cmd->peer_flags |= WMI_PEER_STATIC_MIMOPS; 3492 if (param->dynamic_mimops_flag) 3493 cmd->peer_flags |= WMI_PEER_DYN_MIMOPS; 3494 if (param->spatial_mux_flag) 3495 cmd->peer_flags |= WMI_PEER_SPATIAL_MUX; 3496 if (param->vht_flag) 3497 cmd->peer_flags |= WMI_PEER_VHT; 3498 if (param->he_flag) 3499 cmd->peer_flags |= WMI_PEER_HE; 3500 if (param->p2p_capable_sta) 3501 cmd->peer_flags |= WMI_PEER_IS_P2P_CAPABLE; 3502 } 3503 3504 if (param->is_pmf_enabled) 3505 cmd->peer_flags |= WMI_PEER_PMF; 3506 /* 3507 * Suppress authorization for all AUTH modes that need 4-way handshake 3508 * (during re-association). 3509 * Authorization will be done for these modes on key installation. 3510 */ 3511 if (param->auth_flag) 3512 cmd->peer_flags |= WMI_PEER_AUTH; 3513 if (param->need_ptk_4_way) 3514 cmd->peer_flags |= WMI_PEER_NEED_PTK_4_WAY; 3515 else 3516 cmd->peer_flags &= ~WMI_PEER_NEED_PTK_4_WAY; 3517 if (param->need_gtk_2_way) 3518 cmd->peer_flags |= WMI_PEER_NEED_GTK_2_WAY; 3519 /* safe mode bypass the 4-way handshake */ 3520 if (param->safe_mode_enabled) 3521 cmd->peer_flags &= 3522 ~(WMI_PEER_NEED_PTK_4_WAY | WMI_PEER_NEED_GTK_2_WAY); 3523 /* inter BSS peer */ 3524 if (param->inter_bss_peer) 3525 cmd->peer_flags |= WMI_PEER_INTER_BSS_PEER; 3526 /* Disable AMSDU for station transmit, if user configures it */ 3527 /* Disable AMSDU for AP transmit to 11n Stations, if user configures 3528 * it 3529 * if (param->amsdu_disable) Add after FW support 3530 **/ 3531 3532 /* Target asserts if node is marked HT and all MCS is set to 0. 3533 * Mark the node as non-HT if all the mcs rates are disabled through 3534 * iwpriv 3535 **/ 3536 if (param->peer_ht_rates.num_rates == 0) 3537 cmd->peer_flags &= ~WMI_PEER_HT; 3538 3539 if (param->twt_requester) 3540 cmd->peer_flags |= WMI_PEER_TWT_REQ; 3541 3542 if (param->twt_responder) 3543 cmd->peer_flags |= WMI_PEER_TWT_RESP; 3544 } 3545 3546 static inline void copy_peer_mac_addr_tlv( 3547 wmi_peer_assoc_complete_cmd_fixed_param * cmd, 3548 struct peer_assoc_params *param) 3549 { 3550 WMI_CHAR_ARRAY_TO_MAC_ADDR(param->peer_mac, &cmd->peer_macaddr); 3551 } 3552 3553 #ifdef WLAN_FEATURE_11BE 3554 static uint8_t *update_peer_flags_tlv_ehtinfo( 3555 wmi_peer_assoc_complete_cmd_fixed_param * cmd, 3556 struct peer_assoc_params *param, uint8_t *buf_ptr) 3557 { 3558 wmi_eht_rate_set *eht_mcs; 3559 int i; 3560 3561 cmd->peer_eht_ops = param->peer_eht_ops; 3562 cmd->puncture_20mhz_bitmap = ~param->puncture_bitmap; 3563 3564 qdf_mem_copy(&cmd->peer_eht_cap_mac, ¶m->peer_eht_cap_macinfo, 3565 sizeof(param->peer_eht_cap_macinfo)); 3566 qdf_mem_copy(&cmd->peer_eht_cap_phy, ¶m->peer_eht_cap_phyinfo, 3567 sizeof(param->peer_eht_cap_phyinfo)); 3568 qdf_mem_copy(&cmd->peer_eht_ppet, ¶m->peer_eht_ppet, 3569 sizeof(param->peer_eht_ppet)); 3570 3571 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 3572 (param->peer_eht_mcs_count * sizeof(wmi_eht_rate_set))); 3573 buf_ptr += WMI_TLV_HDR_SIZE; 3574 3575 /* Loop through the EHT rate set */ 3576 for (i = 0; i < param->peer_eht_mcs_count; i++) { 3577 eht_mcs = (wmi_eht_rate_set *)buf_ptr; 3578 WMITLV_SET_HDR(eht_mcs, WMITLV_TAG_STRUC_wmi_eht_rate_set, 3579 WMITLV_GET_STRUCT_TLVLEN(wmi_eht_rate_set)); 3580 3581 eht_mcs->rx_mcs_set = param->peer_eht_rx_mcs_set[i]; 3582 eht_mcs->tx_mcs_set = param->peer_eht_tx_mcs_set[i]; 3583 wmi_debug("EHT idx %d RxMCSmap %x TxMCSmap %x ", 3584 i, eht_mcs->rx_mcs_set, eht_mcs->tx_mcs_set); 3585 buf_ptr += sizeof(wmi_eht_rate_set); 3586 } 3587 3588 wmi_debug("nss %d ru mask 0x%x", 3589 cmd->peer_eht_ppet.numss_m1, cmd->peer_eht_ppet.ru_mask); 3590 for (i = 0; i < WMI_MAX_NUM_SS; i++) { 3591 wmi_debug("ppet idx %d ppet %x ", 3592 i, cmd->peer_eht_ppet.ppet16_ppet8_ru3_ru0[i]); 3593 } 3594 3595 if ((param->eht_flag) && (param->peer_eht_mcs_count > 1) && 3596 (param->peer_eht_rx_mcs_set[WMI_HOST_EHT_TXRX_MCS_NSS_IDX_160] 3597 == WMI_HOST_EHT_INVALID_MCSNSSMAP || 3598 param->peer_eht_tx_mcs_set[WMI_HOST_EHT_TXRX_MCS_NSS_IDX_160] 3599 == WMI_HOST_HE_INVALID_MCSNSSMAP)) { 3600 wmi_debug("param->peer_eht_tx_mcs_set[160MHz]=%x", 3601 param->peer_eht_tx_mcs_set 3602 [WMI_HOST_HE_TXRX_MCS_NSS_IDX_160]); 3603 wmi_debug("param->peer_eht_rx_mcs_set[160MHz]=%x", 3604 param->peer_eht_rx_mcs_set 3605 [WMI_HOST_HE_TXRX_MCS_NSS_IDX_160]); 3606 wmi_debug("peer_mac="QDF_MAC_ADDR_FMT, 3607 QDF_MAC_ADDR_REF(param->peer_mac)); 3608 } 3609 3610 wmi_debug("EHT cap_mac %x %x ehtops %x EHT phy %x %x %x pp %x", 3611 cmd->peer_eht_cap_mac[0], 3612 cmd->peer_eht_cap_mac[1], cmd->peer_eht_ops, 3613 cmd->peer_eht_cap_phy[0], cmd->peer_eht_cap_phy[1], 3614 cmd->peer_eht_cap_phy[2], cmd->puncture_20mhz_bitmap); 3615 3616 return buf_ptr; 3617 } 3618 #else 3619 static uint8_t *update_peer_flags_tlv_ehtinfo( 3620 wmi_peer_assoc_complete_cmd_fixed_param * cmd, 3621 struct peer_assoc_params *param, uint8_t *buf_ptr) 3622 { 3623 return buf_ptr; 3624 } 3625 #endif 3626 3627 #ifdef WLAN_FEATURE_11BE 3628 static 3629 uint32_t wmi_eht_peer_assoc_params_len(struct peer_assoc_params *param) 3630 { 3631 return (sizeof(wmi_he_rate_set) * param->peer_eht_mcs_count 3632 + WMI_TLV_HDR_SIZE); 3633 } 3634 3635 static void wmi_populate_service_11be(uint32_t *wmi_service) 3636 { 3637 wmi_service[wmi_service_11be] = WMI_SERVICE_11BE; 3638 } 3639 3640 #else 3641 static 3642 uint32_t wmi_eht_peer_assoc_params_len(struct peer_assoc_params *param) 3643 { 3644 return 0; 3645 } 3646 3647 static void wmi_populate_service_11be(uint32_t *wmi_service) 3648 { 3649 } 3650 3651 #endif 3652 3653 /** 3654 * send_peer_assoc_cmd_tlv() - WMI peer assoc function 3655 * @wmi_handle: handle to WMI. 3656 * @param: pointer to peer assoc parameter 3657 * 3658 * Return: QDF_STATUS_SUCCESS for success or error code 3659 */ 3660 static QDF_STATUS send_peer_assoc_cmd_tlv(wmi_unified_t wmi_handle, 3661 struct peer_assoc_params *param) 3662 { 3663 wmi_peer_assoc_complete_cmd_fixed_param *cmd; 3664 wmi_vht_rate_set *mcs; 3665 wmi_he_rate_set *he_mcs; 3666 wmi_buf_t buf; 3667 int32_t len; 3668 uint8_t *buf_ptr; 3669 QDF_STATUS ret; 3670 uint32_t peer_legacy_rates_align; 3671 uint32_t peer_ht_rates_align; 3672 int32_t i; 3673 3674 3675 peer_legacy_rates_align = wmi_align(param->peer_legacy_rates.num_rates); 3676 peer_ht_rates_align = wmi_align(param->peer_ht_rates.num_rates); 3677 3678 len = sizeof(*cmd) + WMI_TLV_HDR_SIZE + 3679 (peer_legacy_rates_align * sizeof(uint8_t)) + 3680 WMI_TLV_HDR_SIZE + 3681 (peer_ht_rates_align * sizeof(uint8_t)) + 3682 sizeof(wmi_vht_rate_set) + 3683 (sizeof(wmi_he_rate_set) * param->peer_he_mcs_count 3684 + WMI_TLV_HDR_SIZE) 3685 + wmi_eht_peer_assoc_params_len(param) + 3686 peer_assoc_mlo_params_size(param) + 3687 peer_assoc_t2lm_params_size(param); 3688 3689 buf = wmi_buf_alloc(wmi_handle, len); 3690 if (!buf) 3691 return QDF_STATUS_E_NOMEM; 3692 3693 buf_ptr = (uint8_t *) wmi_buf_data(buf); 3694 cmd = (wmi_peer_assoc_complete_cmd_fixed_param *) buf_ptr; 3695 WMITLV_SET_HDR(&cmd->tlv_header, 3696 WMITLV_TAG_STRUC_wmi_peer_assoc_complete_cmd_fixed_param, 3697 WMITLV_GET_STRUCT_TLVLEN 3698 (wmi_peer_assoc_complete_cmd_fixed_param)); 3699 3700 cmd->vdev_id = param->vdev_id; 3701 3702 cmd->peer_new_assoc = param->peer_new_assoc; 3703 cmd->peer_associd = param->peer_associd; 3704 3705 copy_peer_flags_tlv(cmd, param); 3706 copy_peer_mac_addr_tlv(cmd, param); 3707 3708 cmd->peer_rate_caps = param->peer_rate_caps; 3709 cmd->peer_caps = param->peer_caps; 3710 cmd->peer_listen_intval = param->peer_listen_intval; 3711 cmd->peer_ht_caps = param->peer_ht_caps; 3712 cmd->peer_max_mpdu = param->peer_max_mpdu; 3713 cmd->peer_mpdu_density = param->peer_mpdu_density; 3714 cmd->peer_vht_caps = param->peer_vht_caps; 3715 cmd->peer_phymode = param->peer_phymode; 3716 cmd->bss_max_idle_option = param->peer_bss_max_idle_option; 3717 3718 /* Update 11ax capabilities */ 3719 cmd->peer_he_cap_info = 3720 param->peer_he_cap_macinfo[WMI_HOST_HECAP_MAC_WORD1]; 3721 cmd->peer_he_cap_info_ext = 3722 param->peer_he_cap_macinfo[WMI_HOST_HECAP_MAC_WORD2]; 3723 cmd->peer_he_cap_info_internal = param->peer_he_cap_info_internal; 3724 cmd->peer_he_ops = param->peer_he_ops; 3725 qdf_mem_copy(&cmd->peer_he_cap_phy, ¶m->peer_he_cap_phyinfo, 3726 sizeof(param->peer_he_cap_phyinfo)); 3727 qdf_mem_copy(&cmd->peer_ppet, ¶m->peer_ppet, 3728 sizeof(param->peer_ppet)); 3729 cmd->peer_he_caps_6ghz = param->peer_he_caps_6ghz; 3730 3731 /* Update peer legacy rate information */ 3732 buf_ptr += sizeof(*cmd); 3733 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, 3734 peer_legacy_rates_align); 3735 buf_ptr += WMI_TLV_HDR_SIZE; 3736 cmd->num_peer_legacy_rates = param->peer_legacy_rates.num_rates; 3737 qdf_mem_copy(buf_ptr, param->peer_legacy_rates.rates, 3738 param->peer_legacy_rates.num_rates); 3739 3740 /* Update peer HT rate information */ 3741 buf_ptr += peer_legacy_rates_align; 3742 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, 3743 peer_ht_rates_align); 3744 buf_ptr += WMI_TLV_HDR_SIZE; 3745 cmd->num_peer_ht_rates = param->peer_ht_rates.num_rates; 3746 qdf_mem_copy(buf_ptr, param->peer_ht_rates.rates, 3747 param->peer_ht_rates.num_rates); 3748 3749 /* VHT Rates */ 3750 buf_ptr += peer_ht_rates_align; 3751 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_STRUC_wmi_vht_rate_set, 3752 WMITLV_GET_STRUCT_TLVLEN(wmi_vht_rate_set)); 3753 3754 cmd->auth_mode = param->akm; 3755 cmd->peer_nss = param->peer_nss; 3756 3757 /* Update bandwidth-NSS mapping */ 3758 cmd->peer_bw_rxnss_override = 0; 3759 cmd->peer_bw_rxnss_override |= param->peer_bw_rxnss_override; 3760 3761 mcs = (wmi_vht_rate_set *) buf_ptr; 3762 if (param->vht_capable) { 3763 mcs->rx_max_rate = param->rx_max_rate; 3764 mcs->rx_mcs_set = param->rx_mcs_set; 3765 mcs->tx_max_rate = param->tx_max_rate; 3766 mcs->tx_mcs_set = param->tx_mcs_set; 3767 mcs->tx_max_mcs_nss = param->tx_max_mcs_nss; 3768 } 3769 3770 /* HE Rates */ 3771 cmd->min_data_rate = param->min_data_rate; 3772 cmd->peer_he_mcs = param->peer_he_mcs_count; 3773 buf_ptr += sizeof(wmi_vht_rate_set); 3774 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 3775 (param->peer_he_mcs_count * sizeof(wmi_he_rate_set))); 3776 buf_ptr += WMI_TLV_HDR_SIZE; 3777 3778 WMI_PEER_STA_TYPE_SET(cmd->sta_type, param->peer_bsscolor_rept_info); 3779 /* Loop through the HE rate set */ 3780 for (i = 0; i < param->peer_he_mcs_count; i++) { 3781 he_mcs = (wmi_he_rate_set *) buf_ptr; 3782 WMITLV_SET_HDR(he_mcs, WMITLV_TAG_STRUC_wmi_he_rate_set, 3783 WMITLV_GET_STRUCT_TLVLEN(wmi_he_rate_set)); 3784 3785 he_mcs->rx_mcs_set = param->peer_he_rx_mcs_set[i]; 3786 he_mcs->tx_mcs_set = param->peer_he_tx_mcs_set[i]; 3787 wmi_debug("HE idx %d RxMCSmap %x TxMCSmap %x ", 3788 i, he_mcs->rx_mcs_set, he_mcs->tx_mcs_set); 3789 buf_ptr += sizeof(wmi_he_rate_set); 3790 } 3791 3792 if ((param->he_flag) && (param->peer_he_mcs_count > 1) && 3793 (param->peer_he_rx_mcs_set[WMI_HOST_HE_TXRX_MCS_NSS_IDX_160] 3794 == WMI_HOST_HE_INVALID_MCSNSSMAP || 3795 param->peer_he_tx_mcs_set[WMI_HOST_HE_TXRX_MCS_NSS_IDX_160] 3796 == WMI_HOST_HE_INVALID_MCSNSSMAP)) { 3797 wmi_debug("param->peer_he_tx_mcs_set[160MHz]=%x", 3798 param->peer_he_tx_mcs_set[WMI_HOST_HE_TXRX_MCS_NSS_IDX_160]); 3799 wmi_debug("param->peer_he_rx_mcs_set[160MHz]=%x", 3800 param->peer_he_rx_mcs_set[WMI_HOST_HE_TXRX_MCS_NSS_IDX_160]); 3801 wmi_debug("peer_mac="QDF_MAC_ADDR_FMT, 3802 QDF_MAC_ADDR_REF(param->peer_mac)); 3803 } 3804 3805 wmi_debug("vdev_id %d associd %d peer_flags %x rate_caps %x " 3806 "peer_caps %x listen_intval %d ht_caps %x max_mpdu %d " 3807 "nss %d phymode %d peer_mpdu_density %d " 3808 "cmd->peer_vht_caps %x " 3809 "HE cap_info %x ops %x " 3810 "HE cap_info_ext %x " 3811 "HE phy %x %x %x " 3812 "peer_bw_rxnss_override %x", 3813 cmd->vdev_id, cmd->peer_associd, cmd->peer_flags, 3814 cmd->peer_rate_caps, cmd->peer_caps, 3815 cmd->peer_listen_intval, cmd->peer_ht_caps, 3816 cmd->peer_max_mpdu, cmd->peer_nss, cmd->peer_phymode, 3817 cmd->peer_mpdu_density, 3818 cmd->peer_vht_caps, cmd->peer_he_cap_info, 3819 cmd->peer_he_ops, cmd->peer_he_cap_info_ext, 3820 cmd->peer_he_cap_phy[0], cmd->peer_he_cap_phy[1], 3821 cmd->peer_he_cap_phy[2], 3822 cmd->peer_bw_rxnss_override); 3823 3824 buf_ptr = peer_assoc_add_mlo_params(buf_ptr, param); 3825 3826 buf_ptr = update_peer_flags_tlv_ehtinfo(cmd, param, buf_ptr); 3827 3828 buf_ptr = peer_assoc_add_ml_partner_links(buf_ptr, param); 3829 3830 buf_ptr = peer_assoc_add_tid_to_link_map(buf_ptr, param); 3831 3832 wmi_mtrace(WMI_PEER_ASSOC_CMDID, cmd->vdev_id, 0); 3833 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 3834 WMI_PEER_ASSOC_CMDID); 3835 if (QDF_IS_STATUS_ERROR(ret)) { 3836 wmi_err("Failed to send peer assoc command ret = %d", ret); 3837 wmi_buf_free(buf); 3838 } 3839 3840 return ret; 3841 } 3842 3843 /* copy_scan_notify_events() - Helper routine to copy scan notify events 3844 */ 3845 static inline void copy_scan_event_cntrl_flags( 3846 wmi_start_scan_cmd_fixed_param * cmd, 3847 struct scan_req_params *param) 3848 { 3849 3850 /* Scan events subscription */ 3851 if (param->scan_ev_started) 3852 cmd->notify_scan_events |= WMI_SCAN_EVENT_STARTED; 3853 if (param->scan_ev_completed) 3854 cmd->notify_scan_events |= WMI_SCAN_EVENT_COMPLETED; 3855 if (param->scan_ev_bss_chan) 3856 cmd->notify_scan_events |= WMI_SCAN_EVENT_BSS_CHANNEL; 3857 if (param->scan_ev_foreign_chan) 3858 cmd->notify_scan_events |= WMI_SCAN_EVENT_FOREIGN_CHANNEL; 3859 if (param->scan_ev_dequeued) 3860 cmd->notify_scan_events |= WMI_SCAN_EVENT_DEQUEUED; 3861 if (param->scan_ev_preempted) 3862 cmd->notify_scan_events |= WMI_SCAN_EVENT_PREEMPTED; 3863 if (param->scan_ev_start_failed) 3864 cmd->notify_scan_events |= WMI_SCAN_EVENT_START_FAILED; 3865 if (param->scan_ev_restarted) 3866 cmd->notify_scan_events |= WMI_SCAN_EVENT_RESTARTED; 3867 if (param->scan_ev_foreign_chn_exit) 3868 cmd->notify_scan_events |= WMI_SCAN_EVENT_FOREIGN_CHANNEL_EXIT; 3869 if (param->scan_ev_suspended) 3870 cmd->notify_scan_events |= WMI_SCAN_EVENT_SUSPENDED; 3871 if (param->scan_ev_resumed) 3872 cmd->notify_scan_events |= WMI_SCAN_EVENT_RESUMED; 3873 3874 /** Set scan control flags */ 3875 cmd->scan_ctrl_flags = 0; 3876 if (param->scan_f_passive) 3877 cmd->scan_ctrl_flags |= WMI_SCAN_FLAG_PASSIVE; 3878 if (param->scan_f_strict_passive_pch) 3879 cmd->scan_ctrl_flags |= WMI_SCAN_FLAG_STRICT_PASSIVE_ON_PCHN; 3880 if (param->scan_f_promisc_mode) 3881 cmd->scan_ctrl_flags |= WMI_SCAN_FILTER_PROMISCOUS; 3882 if (param->scan_f_capture_phy_err) 3883 cmd->scan_ctrl_flags |= WMI_SCAN_CAPTURE_PHY_ERROR; 3884 if (param->scan_f_half_rate) 3885 cmd->scan_ctrl_flags |= WMI_SCAN_FLAG_HALF_RATE_SUPPORT; 3886 if (param->scan_f_quarter_rate) 3887 cmd->scan_ctrl_flags |= WMI_SCAN_FLAG_QUARTER_RATE_SUPPORT; 3888 if (param->scan_f_cck_rates) 3889 cmd->scan_ctrl_flags |= WMI_SCAN_ADD_CCK_RATES; 3890 if (param->scan_f_ofdm_rates) 3891 cmd->scan_ctrl_flags |= WMI_SCAN_ADD_OFDM_RATES; 3892 if (param->scan_f_chan_stat_evnt) 3893 cmd->scan_ctrl_flags |= WMI_SCAN_CHAN_STAT_EVENT; 3894 if (param->scan_f_filter_prb_req) 3895 cmd->scan_ctrl_flags |= WMI_SCAN_FILTER_PROBE_REQ; 3896 if (param->scan_f_bcast_probe) 3897 cmd->scan_ctrl_flags |= WMI_SCAN_ADD_BCAST_PROBE_REQ; 3898 if (param->scan_f_offchan_mgmt_tx) 3899 cmd->scan_ctrl_flags |= WMI_SCAN_OFFCHAN_MGMT_TX; 3900 if (param->scan_f_offchan_data_tx) 3901 cmd->scan_ctrl_flags |= WMI_SCAN_OFFCHAN_DATA_TX; 3902 if (param->scan_f_force_active_dfs_chn) 3903 cmd->scan_ctrl_flags |= WMI_SCAN_FLAG_FORCE_ACTIVE_ON_DFS; 3904 if (param->scan_f_add_tpc_ie_in_probe) 3905 cmd->scan_ctrl_flags |= WMI_SCAN_ADD_TPC_IE_IN_PROBE_REQ; 3906 if (param->scan_f_add_ds_ie_in_probe) 3907 cmd->scan_ctrl_flags |= WMI_SCAN_ADD_DS_IE_IN_PROBE_REQ; 3908 if (param->scan_f_add_spoofed_mac_in_probe) 3909 cmd->scan_ctrl_flags |= WMI_SCAN_ADD_SPOOFED_MAC_IN_PROBE_REQ; 3910 if (param->scan_f_add_rand_seq_in_probe) 3911 cmd->scan_ctrl_flags |= WMI_SCAN_RANDOM_SEQ_NO_IN_PROBE_REQ; 3912 if (param->scan_f_en_ie_allowlist_in_probe) 3913 cmd->scan_ctrl_flags |= 3914 WMI_SCAN_ENABLE_IE_WHTELIST_IN_PROBE_REQ; 3915 if (param->scan_f_pause_home_channel) 3916 cmd->scan_ctrl_flags |= 3917 WMI_SCAN_FLAG_PAUSE_HOME_CHANNEL; 3918 if (param->scan_f_report_cca_busy_for_each_20mhz) 3919 cmd->scan_ctrl_flags |= 3920 WMI_SCAN_FLAG_REPORT_CCA_BUSY_FOREACH_20MHZ; 3921 3922 /* for adaptive scan mode using 3 bits (21 - 23 bits) */ 3923 WMI_SCAN_SET_DWELL_MODE(cmd->scan_ctrl_flags, 3924 param->adaptive_dwell_time_mode); 3925 } 3926 3927 /* scan_copy_ie_buffer() - Copy scan ie_data */ 3928 static inline void scan_copy_ie_buffer(uint8_t *buf_ptr, 3929 struct scan_req_params *params) 3930 { 3931 qdf_mem_copy(buf_ptr, params->extraie.ptr, params->extraie.len); 3932 } 3933 3934 /** 3935 * wmi_copy_scan_random_mac() - To copy scan randomization attrs to wmi buffer 3936 * @mac: random mac addr 3937 * @mask: random mac mask 3938 * @mac_addr: wmi random mac 3939 * @mac_mask: wmi random mac mask 3940 * 3941 * Return None. 3942 */ 3943 static inline 3944 void wmi_copy_scan_random_mac(uint8_t *mac, uint8_t *mask, 3945 wmi_mac_addr *mac_addr, wmi_mac_addr *mac_mask) 3946 { 3947 WMI_CHAR_ARRAY_TO_MAC_ADDR(mac, mac_addr); 3948 WMI_CHAR_ARRAY_TO_MAC_ADDR(mask, mac_mask); 3949 } 3950 3951 /* 3952 * wmi_fill_vendor_oui() - fill vendor OUIs 3953 * @buf_ptr: pointer to wmi tlv buffer 3954 * @num_vendor_oui: number of vendor OUIs to be filled 3955 * @param_voui: pointer to OUI buffer 3956 * 3957 * This function populates the wmi tlv buffer when vendor specific OUIs are 3958 * present. 3959 * 3960 * Return: None 3961 */ 3962 static inline 3963 void wmi_fill_vendor_oui(uint8_t *buf_ptr, uint32_t num_vendor_oui, 3964 uint32_t *pvoui) 3965 { 3966 wmi_vendor_oui *voui = NULL; 3967 uint32_t i; 3968 3969 voui = (wmi_vendor_oui *)buf_ptr; 3970 3971 for (i = 0; i < num_vendor_oui; i++) { 3972 WMITLV_SET_HDR(&voui[i].tlv_header, 3973 WMITLV_TAG_STRUC_wmi_vendor_oui, 3974 WMITLV_GET_STRUCT_TLVLEN(wmi_vendor_oui)); 3975 voui[i].oui_type_subtype = pvoui[i]; 3976 } 3977 } 3978 3979 /* 3980 * wmi_fill_ie_allowlist_attrs() - fill IE allowlist attrs 3981 * @ie_bitmap: output pointer to ie bit map in cmd 3982 * @num_vendor_oui: output pointer to num vendor OUIs 3983 * @ie_allowlist: input parameter 3984 * 3985 * This function populates the IE allowlist attrs of scan, pno and 3986 * scan oui commands for ie_allowlist parameter. 3987 * 3988 * Return: None 3989 */ 3990 static inline 3991 void wmi_fill_ie_allowlist_attrs(uint32_t *ie_bitmap, 3992 uint32_t *num_vendor_oui, 3993 struct probe_req_allowlist_attr *ie_allowlist) 3994 { 3995 uint32_t i = 0; 3996 3997 for (i = 0; i < PROBE_REQ_BITMAP_LEN; i++) 3998 ie_bitmap[i] = ie_allowlist->ie_bitmap[i]; 3999 4000 *num_vendor_oui = ie_allowlist->num_vendor_oui; 4001 } 4002 4003 /** 4004 * send_scan_start_cmd_tlv() - WMI scan start function 4005 * @wmi_handle: handle to WMI. 4006 * @params: pointer to hold scan start cmd parameter 4007 * 4008 * Return: QDF_STATUS_SUCCESS for success or error code 4009 */ 4010 static QDF_STATUS send_scan_start_cmd_tlv(wmi_unified_t wmi_handle, 4011 struct scan_req_params *params) 4012 { 4013 int32_t ret = 0; 4014 int32_t i; 4015 wmi_buf_t wmi_buf; 4016 wmi_start_scan_cmd_fixed_param *cmd; 4017 uint8_t *buf_ptr; 4018 uint32_t *tmp_ptr; 4019 wmi_ssid *ssid = NULL; 4020 wmi_mac_addr *bssid; 4021 size_t len = sizeof(*cmd); 4022 uint16_t extraie_len_with_pad = 0; 4023 uint8_t phymode_roundup = 0; 4024 struct probe_req_allowlist_attr *ie_allowlist = ¶ms->ie_allowlist; 4025 wmi_hint_freq_short_ssid *s_ssid = NULL; 4026 wmi_hint_freq_bssid *hint_bssid = NULL; 4027 4028 /* Length TLV placeholder for array of uint32_t */ 4029 len += WMI_TLV_HDR_SIZE; 4030 /* calculate the length of buffer required */ 4031 if (params->chan_list.num_chan) 4032 len += params->chan_list.num_chan * sizeof(uint32_t); 4033 4034 /* Length TLV placeholder for array of wmi_ssid structures */ 4035 len += WMI_TLV_HDR_SIZE; 4036 if (params->num_ssids) 4037 len += params->num_ssids * sizeof(wmi_ssid); 4038 4039 /* Length TLV placeholder for array of wmi_mac_addr structures */ 4040 len += WMI_TLV_HDR_SIZE; 4041 if (params->num_bssid) 4042 len += sizeof(wmi_mac_addr) * params->num_bssid; 4043 4044 /* Length TLV placeholder for array of bytes */ 4045 len += WMI_TLV_HDR_SIZE; 4046 if (params->extraie.len) 4047 extraie_len_with_pad = 4048 roundup(params->extraie.len, sizeof(uint32_t)); 4049 len += extraie_len_with_pad; 4050 4051 len += WMI_TLV_HDR_SIZE; /* Length of TLV for array of wmi_vendor_oui */ 4052 if (ie_allowlist->num_vendor_oui) 4053 len += ie_allowlist->num_vendor_oui * sizeof(wmi_vendor_oui); 4054 4055 len += WMI_TLV_HDR_SIZE; /* Length of TLV for array of scan phymode */ 4056 if (params->scan_f_wide_band) 4057 phymode_roundup = 4058 qdf_roundup(params->chan_list.num_chan * sizeof(uint8_t), 4059 sizeof(uint32_t)); 4060 len += phymode_roundup; 4061 4062 len += WMI_TLV_HDR_SIZE; 4063 if (params->num_hint_bssid) 4064 len += params->num_hint_bssid * sizeof(wmi_hint_freq_bssid); 4065 4066 len += WMI_TLV_HDR_SIZE; 4067 if (params->num_hint_s_ssid) 4068 len += params->num_hint_s_ssid * sizeof(wmi_hint_freq_short_ssid); 4069 4070 /* Allocate the memory */ 4071 wmi_buf = wmi_buf_alloc(wmi_handle, len); 4072 if (!wmi_buf) 4073 return QDF_STATUS_E_FAILURE; 4074 4075 buf_ptr = (uint8_t *) wmi_buf_data(wmi_buf); 4076 cmd = (wmi_start_scan_cmd_fixed_param *) buf_ptr; 4077 WMITLV_SET_HDR(&cmd->tlv_header, 4078 WMITLV_TAG_STRUC_wmi_start_scan_cmd_fixed_param, 4079 WMITLV_GET_STRUCT_TLVLEN 4080 (wmi_start_scan_cmd_fixed_param)); 4081 4082 cmd->scan_id = params->scan_id; 4083 cmd->scan_req_id = params->scan_req_id; 4084 cmd->vdev_id = params->vdev_id; 4085 cmd->scan_priority = params->scan_priority; 4086 4087 copy_scan_event_cntrl_flags(cmd, params); 4088 4089 cmd->dwell_time_active = params->dwell_time_active; 4090 cmd->dwell_time_active_2g = params->dwell_time_active_2g; 4091 cmd->dwell_time_passive = params->dwell_time_passive; 4092 cmd->min_dwell_time_6ghz = params->min_dwell_time_6g; 4093 cmd->dwell_time_active_6ghz = params->dwell_time_active_6g; 4094 cmd->dwell_time_passive_6ghz = params->dwell_time_passive_6g; 4095 cmd->scan_start_offset = params->scan_offset_time; 4096 cmd->min_rest_time = params->min_rest_time; 4097 cmd->max_rest_time = params->max_rest_time; 4098 cmd->repeat_probe_time = params->repeat_probe_time; 4099 cmd->probe_spacing_time = params->probe_spacing_time; 4100 cmd->idle_time = params->idle_time; 4101 cmd->max_scan_time = params->max_scan_time; 4102 cmd->probe_delay = params->probe_delay; 4103 cmd->burst_duration = params->burst_duration; 4104 cmd->num_chan = params->chan_list.num_chan; 4105 cmd->num_bssid = params->num_bssid; 4106 cmd->num_ssids = params->num_ssids; 4107 cmd->ie_len = params->extraie.len; 4108 cmd->n_probes = params->n_probes; 4109 cmd->scan_ctrl_flags_ext = params->scan_ctrl_flags_ext; 4110 WMI_SCAN_MLD_PARAM_MLD_ID_SET(cmd->mld_parameter, params->mld_id); 4111 wmi_debug("MLD ID: %u", cmd->mld_parameter); 4112 4113 if (params->scan_random.randomize) 4114 wmi_copy_scan_random_mac(params->scan_random.mac_addr, 4115 params->scan_random.mac_mask, 4116 &cmd->mac_addr, 4117 &cmd->mac_mask); 4118 4119 if (ie_allowlist->allow_list) 4120 wmi_fill_ie_allowlist_attrs(cmd->ie_bitmap, 4121 &cmd->num_vendor_oui, 4122 ie_allowlist); 4123 4124 buf_ptr += sizeof(*cmd); 4125 tmp_ptr = (uint32_t *) (buf_ptr + WMI_TLV_HDR_SIZE); 4126 for (i = 0; i < params->chan_list.num_chan; ++i) { 4127 TARGET_SET_FREQ_IN_CHAN_LIST_TLV(tmp_ptr[i], 4128 params->chan_list.chan[i].freq); 4129 TARGET_SET_FLAGS_IN_CHAN_LIST_TLV(tmp_ptr[i], 4130 params->chan_list.chan[i].flags); 4131 } 4132 4133 WMITLV_SET_HDR(buf_ptr, 4134 WMITLV_TAG_ARRAY_UINT32, 4135 (params->chan_list.num_chan * sizeof(uint32_t))); 4136 buf_ptr += WMI_TLV_HDR_SIZE + 4137 (params->chan_list.num_chan * sizeof(uint32_t)); 4138 4139 if (params->num_ssids > WLAN_SCAN_MAX_NUM_SSID) { 4140 wmi_err("Invalid value for num_ssids %d", params->num_ssids); 4141 goto error; 4142 } 4143 4144 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_FIXED_STRUC, 4145 (params->num_ssids * sizeof(wmi_ssid))); 4146 4147 if (params->num_ssids) { 4148 ssid = (wmi_ssid *) (buf_ptr + WMI_TLV_HDR_SIZE); 4149 for (i = 0; i < params->num_ssids; ++i) { 4150 ssid->ssid_len = params->ssid[i].length; 4151 qdf_mem_copy(ssid->ssid, params->ssid[i].ssid, 4152 params->ssid[i].length); 4153 ssid++; 4154 } 4155 } 4156 buf_ptr += WMI_TLV_HDR_SIZE + (params->num_ssids * sizeof(wmi_ssid)); 4157 4158 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_FIXED_STRUC, 4159 (params->num_bssid * sizeof(wmi_mac_addr))); 4160 bssid = (wmi_mac_addr *) (buf_ptr + WMI_TLV_HDR_SIZE); 4161 4162 if (params->num_bssid) { 4163 for (i = 0; i < params->num_bssid; ++i) { 4164 WMI_CHAR_ARRAY_TO_MAC_ADDR( 4165 ¶ms->bssid_list[i].bytes[0], bssid); 4166 bssid++; 4167 } 4168 } 4169 4170 buf_ptr += WMI_TLV_HDR_SIZE + 4171 (params->num_bssid * sizeof(wmi_mac_addr)); 4172 4173 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, extraie_len_with_pad); 4174 if (params->extraie.len) 4175 scan_copy_ie_buffer(buf_ptr + WMI_TLV_HDR_SIZE, 4176 params); 4177 4178 buf_ptr += WMI_TLV_HDR_SIZE + extraie_len_with_pad; 4179 4180 /* probe req ie allowlisting */ 4181 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 4182 ie_allowlist->num_vendor_oui * sizeof(wmi_vendor_oui)); 4183 4184 buf_ptr += WMI_TLV_HDR_SIZE; 4185 4186 if (cmd->num_vendor_oui) { 4187 wmi_fill_vendor_oui(buf_ptr, cmd->num_vendor_oui, 4188 ie_allowlist->voui); 4189 buf_ptr += cmd->num_vendor_oui * sizeof(wmi_vendor_oui); 4190 } 4191 4192 /* Add phy mode TLV if it's a wide band scan */ 4193 if (params->scan_f_wide_band) { 4194 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, phymode_roundup); 4195 buf_ptr = (uint8_t *) (buf_ptr + WMI_TLV_HDR_SIZE); 4196 for (i = 0; i < params->chan_list.num_chan; ++i) 4197 buf_ptr[i] = 4198 WMI_SCAN_CHAN_SET_MODE(params->chan_list.chan[i].phymode); 4199 buf_ptr += phymode_roundup; 4200 } else { 4201 /* Add ZERO length phy mode TLV */ 4202 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, 0); 4203 buf_ptr += WMI_TLV_HDR_SIZE; 4204 } 4205 4206 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_FIXED_STRUC, 4207 (params->num_hint_s_ssid * sizeof(wmi_hint_freq_short_ssid))); 4208 if (params->num_hint_s_ssid) { 4209 s_ssid = (wmi_hint_freq_short_ssid *)(buf_ptr + WMI_TLV_HDR_SIZE); 4210 for (i = 0; i < params->num_hint_s_ssid; ++i) { 4211 s_ssid->freq_flags = params->hint_s_ssid[i].freq_flags; 4212 s_ssid->short_ssid = params->hint_s_ssid[i].short_ssid; 4213 s_ssid++; 4214 } 4215 } 4216 buf_ptr += WMI_TLV_HDR_SIZE + 4217 (params->num_hint_s_ssid * sizeof(wmi_hint_freq_short_ssid)); 4218 4219 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_FIXED_STRUC, 4220 (params->num_hint_bssid * sizeof(wmi_hint_freq_bssid))); 4221 if (params->num_hint_bssid) { 4222 hint_bssid = (wmi_hint_freq_bssid *)(buf_ptr + WMI_TLV_HDR_SIZE); 4223 for (i = 0; i < params->num_hint_bssid; ++i) { 4224 hint_bssid->freq_flags = 4225 params->hint_bssid[i].freq_flags; 4226 WMI_CHAR_ARRAY_TO_MAC_ADDR(¶ms->hint_bssid[i].bssid.bytes[0], 4227 &hint_bssid->bssid); 4228 hint_bssid++; 4229 } 4230 } 4231 4232 wmi_mtrace(WMI_START_SCAN_CMDID, cmd->vdev_id, 0); 4233 ret = wmi_unified_cmd_send(wmi_handle, wmi_buf, 4234 len, WMI_START_SCAN_CMDID); 4235 if (ret) { 4236 wmi_err("Failed to start scan: %d", ret); 4237 wmi_buf_free(wmi_buf); 4238 } 4239 return ret; 4240 error: 4241 wmi_buf_free(wmi_buf); 4242 return QDF_STATUS_E_FAILURE; 4243 } 4244 4245 /** 4246 * send_scan_stop_cmd_tlv() - WMI scan start function 4247 * @wmi_handle: handle to WMI. 4248 * @param: pointer to hold scan cancel cmd parameter 4249 * 4250 * Return: QDF_STATUS_SUCCESS for success or error code 4251 */ 4252 static QDF_STATUS send_scan_stop_cmd_tlv(wmi_unified_t wmi_handle, 4253 struct scan_cancel_param *param) 4254 { 4255 wmi_stop_scan_cmd_fixed_param *cmd; 4256 int ret; 4257 int len = sizeof(*cmd); 4258 wmi_buf_t wmi_buf; 4259 4260 /* Allocate the memory */ 4261 wmi_buf = wmi_buf_alloc(wmi_handle, len); 4262 if (!wmi_buf) { 4263 ret = QDF_STATUS_E_NOMEM; 4264 goto error; 4265 } 4266 4267 cmd = (wmi_stop_scan_cmd_fixed_param *) wmi_buf_data(wmi_buf); 4268 WMITLV_SET_HDR(&cmd->tlv_header, 4269 WMITLV_TAG_STRUC_wmi_stop_scan_cmd_fixed_param, 4270 WMITLV_GET_STRUCT_TLVLEN(wmi_stop_scan_cmd_fixed_param)); 4271 cmd->vdev_id = param->vdev_id; 4272 cmd->requestor = param->requester; 4273 cmd->scan_id = param->scan_id; 4274 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 4275 wmi_handle, 4276 param->pdev_id); 4277 /* stop the scan with the corresponding scan_id */ 4278 if (param->req_type == WLAN_SCAN_CANCEL_PDEV_ALL) { 4279 /* Cancelling all scans */ 4280 cmd->req_type = WMI_SCAN_STOP_ALL; 4281 } else if (param->req_type == WLAN_SCAN_CANCEL_VDEV_ALL) { 4282 /* Cancelling VAP scans */ 4283 cmd->req_type = WMI_SCN_STOP_VAP_ALL; 4284 } else if (param->req_type == WLAN_SCAN_CANCEL_SINGLE) { 4285 /* Cancelling specific scan */ 4286 cmd->req_type = WMI_SCAN_STOP_ONE; 4287 } else if (param->req_type == WLAN_SCAN_CANCEL_HOST_VDEV_ALL) { 4288 cmd->req_type = WMI_SCN_STOP_HOST_VAP_ALL; 4289 } else { 4290 wmi_err("Invalid Scan cancel req type: %d", param->req_type); 4291 wmi_buf_free(wmi_buf); 4292 return QDF_STATUS_E_INVAL; 4293 } 4294 4295 wmi_mtrace(WMI_STOP_SCAN_CMDID, cmd->vdev_id, 0); 4296 ret = wmi_unified_cmd_send(wmi_handle, wmi_buf, 4297 len, WMI_STOP_SCAN_CMDID); 4298 if (ret) { 4299 wmi_err("Failed to send stop scan: %d", ret); 4300 wmi_buf_free(wmi_buf); 4301 } 4302 4303 error: 4304 return ret; 4305 } 4306 4307 #define WMI_MAX_CHAN_INFO_LOG 192 4308 4309 /** 4310 * wmi_scan_chanlist_dump() - Dump scan channel list info 4311 * @scan_chan_list: scan channel list 4312 * 4313 * Return: void 4314 */ 4315 static void wmi_scan_chanlist_dump(struct scan_chan_list_params *scan_chan_list) 4316 { 4317 uint32_t i; 4318 uint8_t info[WMI_MAX_CHAN_INFO_LOG]; 4319 uint32_t len = 0; 4320 struct channel_param *chan; 4321 int ret; 4322 4323 wmi_debug("Total chan %d", scan_chan_list->nallchans); 4324 for (i = 0; i < scan_chan_list->nallchans; i++) { 4325 chan = &scan_chan_list->ch_param[i]; 4326 ret = qdf_scnprintf(info + len, sizeof(info) - len, 4327 " %d[%d][%d][%d]", chan->mhz, 4328 chan->maxregpower, 4329 chan->dfs_set, chan->nan_disabled); 4330 if (ret <= 0) 4331 break; 4332 len += ret; 4333 if (len >= (sizeof(info) - 20)) { 4334 wmi_nofl_debug("Chan[TXPwr][DFS][nan_disabled]:%s", 4335 info); 4336 len = 0; 4337 } 4338 } 4339 if (len) 4340 wmi_nofl_debug("Chan[TXPwr][DFS]:%s", info); 4341 } 4342 4343 static QDF_STATUS send_scan_chan_list_cmd_tlv(wmi_unified_t wmi_handle, 4344 struct scan_chan_list_params *chan_list) 4345 { 4346 wmi_buf_t buf; 4347 QDF_STATUS qdf_status = QDF_STATUS_SUCCESS; 4348 wmi_scan_chan_list_cmd_fixed_param *cmd; 4349 int i; 4350 uint8_t *buf_ptr; 4351 wmi_channel *chan_info; 4352 struct channel_param *tchan_info; 4353 uint16_t len; 4354 uint16_t num_send_chans, num_sends = 0; 4355 4356 wmi_scan_chanlist_dump(chan_list); 4357 tchan_info = &chan_list->ch_param[0]; 4358 while (chan_list->nallchans) { 4359 len = sizeof(*cmd) + WMI_TLV_HDR_SIZE; 4360 if (chan_list->nallchans > MAX_NUM_CHAN_PER_WMI_CMD) 4361 num_send_chans = MAX_NUM_CHAN_PER_WMI_CMD; 4362 else 4363 num_send_chans = chan_list->nallchans; 4364 4365 chan_list->nallchans -= num_send_chans; 4366 len += sizeof(wmi_channel) * num_send_chans; 4367 buf = wmi_buf_alloc(wmi_handle, len); 4368 if (!buf) { 4369 qdf_status = QDF_STATUS_E_NOMEM; 4370 goto end; 4371 } 4372 4373 buf_ptr = (uint8_t *)wmi_buf_data(buf); 4374 cmd = (wmi_scan_chan_list_cmd_fixed_param *)buf_ptr; 4375 WMITLV_SET_HDR(&cmd->tlv_header, 4376 WMITLV_TAG_STRUC_wmi_scan_chan_list_cmd_fixed_param, 4377 WMITLV_GET_STRUCT_TLVLEN 4378 (wmi_scan_chan_list_cmd_fixed_param)); 4379 4380 wmi_debug("no of channels = %d, len = %d", num_send_chans, len); 4381 4382 if (num_sends) 4383 cmd->flags |= APPEND_TO_EXISTING_CHAN_LIST; 4384 4385 if (chan_list->max_bw_support_present) 4386 cmd->flags |= CHANNEL_MAX_BANDWIDTH_VALID; 4387 4388 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 4389 wmi_handle, 4390 chan_list->pdev_id); 4391 4392 wmi_mtrace(WMI_SCAN_CHAN_LIST_CMDID, cmd->pdev_id, 0); 4393 4394 cmd->num_scan_chans = num_send_chans; 4395 WMITLV_SET_HDR((buf_ptr + 4396 sizeof(wmi_scan_chan_list_cmd_fixed_param)), 4397 WMITLV_TAG_ARRAY_STRUC, 4398 sizeof(wmi_channel) * num_send_chans); 4399 chan_info = (wmi_channel *)(buf_ptr + sizeof(*cmd) + 4400 WMI_TLV_HDR_SIZE); 4401 4402 for (i = 0; i < num_send_chans; ++i) { 4403 WMITLV_SET_HDR(&chan_info->tlv_header, 4404 WMITLV_TAG_STRUC_wmi_channel, 4405 WMITLV_GET_STRUCT_TLVLEN(wmi_channel)); 4406 chan_info->mhz = tchan_info->mhz; 4407 chan_info->band_center_freq1 = 4408 tchan_info->cfreq1; 4409 chan_info->band_center_freq2 = 4410 tchan_info->cfreq2; 4411 4412 if (tchan_info->is_chan_passive) 4413 WMI_SET_CHANNEL_FLAG(chan_info, 4414 WMI_CHAN_FLAG_PASSIVE); 4415 if (tchan_info->dfs_set) 4416 WMI_SET_CHANNEL_FLAG(chan_info, 4417 WMI_CHAN_FLAG_DFS); 4418 4419 if (tchan_info->dfs_set_cfreq2) 4420 WMI_SET_CHANNEL_FLAG(chan_info, 4421 WMI_CHAN_FLAG_DFS_CFREQ2); 4422 4423 if (tchan_info->allow_he) 4424 WMI_SET_CHANNEL_FLAG(chan_info, 4425 WMI_CHAN_FLAG_ALLOW_HE); 4426 4427 if (tchan_info->allow_eht) 4428 WMI_SET_CHANNEL_FLAG(chan_info, 4429 WMI_CHAN_FLAG_ALLOW_EHT); 4430 4431 if (tchan_info->allow_vht) 4432 WMI_SET_CHANNEL_FLAG(chan_info, 4433 WMI_CHAN_FLAG_ALLOW_VHT); 4434 4435 if (tchan_info->allow_ht) 4436 WMI_SET_CHANNEL_FLAG(chan_info, 4437 WMI_CHAN_FLAG_ALLOW_HT); 4438 WMI_SET_CHANNEL_MODE(chan_info, 4439 tchan_info->phy_mode); 4440 4441 if (tchan_info->half_rate) 4442 WMI_SET_CHANNEL_FLAG(chan_info, 4443 WMI_CHAN_FLAG_HALF_RATE); 4444 4445 if (tchan_info->quarter_rate) 4446 WMI_SET_CHANNEL_FLAG(chan_info, 4447 WMI_CHAN_FLAG_QUARTER_RATE); 4448 4449 if (tchan_info->psc_channel) 4450 WMI_SET_CHANNEL_FLAG(chan_info, 4451 WMI_CHAN_FLAG_PSC); 4452 4453 if (tchan_info->nan_disabled) 4454 WMI_SET_CHANNEL_FLAG(chan_info, 4455 WMI_CHAN_FLAG_NAN_DISABLED); 4456 4457 /* also fill in power information */ 4458 WMI_SET_CHANNEL_MIN_POWER(chan_info, 4459 tchan_info->minpower); 4460 WMI_SET_CHANNEL_MAX_POWER(chan_info, 4461 tchan_info->maxpower); 4462 WMI_SET_CHANNEL_REG_POWER(chan_info, 4463 tchan_info->maxregpower); 4464 WMI_SET_CHANNEL_ANTENNA_MAX(chan_info, 4465 tchan_info->antennamax); 4466 WMI_SET_CHANNEL_REG_CLASSID(chan_info, 4467 tchan_info->reg_class_id); 4468 WMI_SET_CHANNEL_MAX_TX_POWER(chan_info, 4469 tchan_info->maxregpower); 4470 WMI_SET_CHANNEL_MAX_BANDWIDTH(chan_info, 4471 tchan_info->max_bw_supported); 4472 4473 tchan_info++; 4474 chan_info++; 4475 } 4476 4477 qdf_status = wmi_unified_cmd_send( 4478 wmi_handle, 4479 buf, len, WMI_SCAN_CHAN_LIST_CMDID); 4480 4481 if (QDF_IS_STATUS_ERROR(qdf_status)) { 4482 wmi_err("Failed to send WMI_SCAN_CHAN_LIST_CMDID"); 4483 wmi_buf_free(buf); 4484 goto end; 4485 } 4486 num_sends++; 4487 } 4488 4489 end: 4490 return qdf_status; 4491 } 4492 4493 /** 4494 * populate_tx_send_params - Populate TX param TLV for mgmt and offchan tx 4495 * 4496 * @bufp: Pointer to buffer 4497 * @param: Pointer to tx param 4498 * 4499 * Return: QDF_STATUS_SUCCESS for success and QDF_STATUS_E_FAILURE for failure 4500 */ 4501 static inline QDF_STATUS populate_tx_send_params(uint8_t *bufp, 4502 struct tx_send_params param) 4503 { 4504 wmi_tx_send_params *tx_param; 4505 QDF_STATUS status = QDF_STATUS_SUCCESS; 4506 4507 if (!bufp) { 4508 status = QDF_STATUS_E_FAILURE; 4509 return status; 4510 } 4511 tx_param = (wmi_tx_send_params *)bufp; 4512 WMITLV_SET_HDR(&tx_param->tlv_header, 4513 WMITLV_TAG_STRUC_wmi_tx_send_params, 4514 WMITLV_GET_STRUCT_TLVLEN(wmi_tx_send_params)); 4515 WMI_TX_SEND_PARAM_PWR_SET(tx_param->tx_param_dword0, param.pwr); 4516 WMI_TX_SEND_PARAM_MCS_MASK_SET(tx_param->tx_param_dword0, 4517 param.mcs_mask); 4518 WMI_TX_SEND_PARAM_NSS_MASK_SET(tx_param->tx_param_dword0, 4519 param.nss_mask); 4520 WMI_TX_SEND_PARAM_RETRY_LIMIT_SET(tx_param->tx_param_dword0, 4521 param.retry_limit); 4522 WMI_TX_SEND_PARAM_CHAIN_MASK_SET(tx_param->tx_param_dword1, 4523 param.chain_mask); 4524 WMI_TX_SEND_PARAM_BW_MASK_SET(tx_param->tx_param_dword1, 4525 param.bw_mask); 4526 WMI_TX_SEND_PARAM_PREAMBLE_SET(tx_param->tx_param_dword1, 4527 param.preamble_type); 4528 WMI_TX_SEND_PARAM_FRAME_TYPE_SET(tx_param->tx_param_dword1, 4529 param.frame_type); 4530 WMI_TX_SEND_PARAM_CFR_CAPTURE_SET(tx_param->tx_param_dword1, 4531 param.cfr_enable); 4532 WMI_TX_SEND_PARAM_BEAMFORM_SET(tx_param->tx_param_dword1, 4533 param.en_beamforming); 4534 WMI_TX_SEND_PARAM_RETRY_LIMIT_EXT_SET(tx_param->tx_param_dword1, 4535 param.retry_limit_ext); 4536 4537 return status; 4538 } 4539 4540 #ifdef CONFIG_HL_SUPPORT 4541 /** 4542 * send_mgmt_cmd_tlv() - WMI scan start function 4543 * @wmi_handle: handle to WMI. 4544 * @param: pointer to hold mgmt cmd parameter 4545 * 4546 * Return: QDF_STATUS_SUCCESS for success or error code 4547 */ 4548 static QDF_STATUS send_mgmt_cmd_tlv(wmi_unified_t wmi_handle, 4549 struct wmi_mgmt_params *param) 4550 { 4551 wmi_buf_t buf; 4552 uint8_t *bufp; 4553 int32_t cmd_len; 4554 wmi_mgmt_tx_send_cmd_fixed_param *cmd; 4555 int32_t bufp_len = (param->frm_len < mgmt_tx_dl_frm_len) ? param->frm_len : 4556 mgmt_tx_dl_frm_len; 4557 4558 if (param->frm_len > mgmt_tx_dl_frm_len) { 4559 wmi_err("mgmt frame len %u exceeds %u", 4560 param->frm_len, mgmt_tx_dl_frm_len); 4561 return QDF_STATUS_E_INVAL; 4562 } 4563 4564 cmd_len = sizeof(wmi_mgmt_tx_send_cmd_fixed_param) + 4565 WMI_TLV_HDR_SIZE + 4566 roundup(bufp_len, sizeof(uint32_t)); 4567 4568 buf = wmi_buf_alloc(wmi_handle, sizeof(wmi_tx_send_params) + cmd_len); 4569 if (!buf) 4570 return QDF_STATUS_E_NOMEM; 4571 4572 cmd = (wmi_mgmt_tx_send_cmd_fixed_param *)wmi_buf_data(buf); 4573 bufp = (uint8_t *) cmd; 4574 WMITLV_SET_HDR(&cmd->tlv_header, 4575 WMITLV_TAG_STRUC_wmi_mgmt_tx_send_cmd_fixed_param, 4576 WMITLV_GET_STRUCT_TLVLEN 4577 (wmi_mgmt_tx_send_cmd_fixed_param)); 4578 4579 cmd->vdev_id = param->vdev_id; 4580 4581 cmd->desc_id = param->desc_id; 4582 cmd->chanfreq = param->chanfreq; 4583 bufp += sizeof(wmi_mgmt_tx_send_cmd_fixed_param); 4584 WMITLV_SET_HDR(bufp, WMITLV_TAG_ARRAY_BYTE, roundup(bufp_len, 4585 sizeof(uint32_t))); 4586 bufp += WMI_TLV_HDR_SIZE; 4587 qdf_mem_copy(bufp, param->pdata, bufp_len); 4588 4589 cmd->frame_len = param->frm_len; 4590 cmd->buf_len = bufp_len; 4591 cmd->tx_params_valid = param->tx_params_valid; 4592 cmd->tx_flags = param->tx_flags; 4593 cmd->peer_rssi = param->peer_rssi; 4594 4595 wmi_mgmt_cmd_record(wmi_handle, WMI_MGMT_TX_SEND_CMDID, 4596 bufp, cmd->vdev_id, cmd->chanfreq); 4597 4598 bufp += roundup(bufp_len, sizeof(uint32_t)); 4599 if (param->tx_params_valid) { 4600 if (populate_tx_send_params(bufp, param->tx_param) != 4601 QDF_STATUS_SUCCESS) { 4602 wmi_err("Populate TX send params failed"); 4603 goto free_buf; 4604 } 4605 cmd_len += sizeof(wmi_tx_send_params); 4606 } 4607 4608 wmi_mtrace(WMI_MGMT_TX_SEND_CMDID, cmd->vdev_id, 0); 4609 if (wmi_unified_cmd_send(wmi_handle, buf, cmd_len, 4610 WMI_MGMT_TX_SEND_CMDID)) { 4611 wmi_err("Failed to send mgmt Tx"); 4612 goto free_buf; 4613 } 4614 return QDF_STATUS_SUCCESS; 4615 4616 free_buf: 4617 wmi_buf_free(buf); 4618 return QDF_STATUS_E_FAILURE; 4619 } 4620 #else 4621 /** 4622 * send_mgmt_cmd_tlv() - WMI scan start function 4623 * @wmi_handle: handle to WMI. 4624 * @param: pointer to hold mgmt cmd parameter 4625 * 4626 * Return: QDF_STATUS_SUCCESS for success or error code 4627 */ 4628 static QDF_STATUS send_mgmt_cmd_tlv(wmi_unified_t wmi_handle, 4629 struct wmi_mgmt_params *param) 4630 { 4631 wmi_buf_t buf; 4632 wmi_mgmt_tx_send_cmd_fixed_param *cmd; 4633 int32_t cmd_len; 4634 uint64_t dma_addr; 4635 void *qdf_ctx = param->qdf_ctx; 4636 uint8_t *bufp; 4637 QDF_STATUS status = QDF_STATUS_SUCCESS; 4638 wmi_mlo_tx_send_params *mlo_params; 4639 int32_t bufp_len = (param->frm_len < mgmt_tx_dl_frm_len) ? param->frm_len : 4640 mgmt_tx_dl_frm_len; 4641 4642 cmd_len = sizeof(wmi_mgmt_tx_send_cmd_fixed_param) + 4643 WMI_TLV_HDR_SIZE + 4644 roundup(bufp_len, sizeof(uint32_t)); 4645 4646 buf = wmi_buf_alloc(wmi_handle, sizeof(wmi_tx_send_params) + cmd_len + 4647 WMI_TLV_HDR_SIZE + sizeof(wmi_mlo_tx_send_params)); 4648 if (!buf) 4649 return QDF_STATUS_E_NOMEM; 4650 4651 cmd = (wmi_mgmt_tx_send_cmd_fixed_param *)wmi_buf_data(buf); 4652 bufp = (uint8_t *) cmd; 4653 WMITLV_SET_HDR(&cmd->tlv_header, 4654 WMITLV_TAG_STRUC_wmi_mgmt_tx_send_cmd_fixed_param, 4655 WMITLV_GET_STRUCT_TLVLEN 4656 (wmi_mgmt_tx_send_cmd_fixed_param)); 4657 4658 cmd->vdev_id = param->vdev_id; 4659 4660 cmd->desc_id = param->desc_id; 4661 cmd->chanfreq = param->chanfreq; 4662 cmd->peer_rssi = param->peer_rssi; 4663 bufp += sizeof(wmi_mgmt_tx_send_cmd_fixed_param); 4664 WMITLV_SET_HDR(bufp, WMITLV_TAG_ARRAY_BYTE, roundup(bufp_len, 4665 sizeof(uint32_t))); 4666 bufp += WMI_TLV_HDR_SIZE; 4667 4668 /* for big endian host, copy engine byte_swap is enabled 4669 * But the frame content is in network byte order 4670 * Need to byte swap the frame content - so when copy engine 4671 * does byte_swap - target gets frame content in the correct order 4672 */ 4673 WMI_HOST_IF_MSG_COPY_CHAR_ARRAY(bufp, param->pdata, bufp_len); 4674 4675 status = qdf_nbuf_map_single(qdf_ctx, param->tx_frame, 4676 QDF_DMA_TO_DEVICE); 4677 if (status != QDF_STATUS_SUCCESS) { 4678 wmi_err("wmi buf map failed"); 4679 goto free_buf; 4680 } 4681 4682 dma_addr = qdf_nbuf_get_frag_paddr(param->tx_frame, 0); 4683 cmd->paddr_lo = (uint32_t)(dma_addr & 0xffffffff); 4684 #if defined(HTT_PADDR64) 4685 cmd->paddr_hi = (uint32_t)((dma_addr >> 32) & 0x1F); 4686 #endif 4687 cmd->frame_len = param->frm_len; 4688 cmd->buf_len = bufp_len; 4689 cmd->tx_params_valid = param->tx_params_valid; 4690 cmd->tx_flags = param->tx_flags; 4691 4692 wmi_mgmt_cmd_record(wmi_handle, WMI_MGMT_TX_SEND_CMDID, 4693 bufp, cmd->vdev_id, cmd->chanfreq); 4694 4695 bufp += roundup(bufp_len, sizeof(uint32_t)); 4696 if (param->tx_params_valid) { 4697 status = populate_tx_send_params(bufp, param->tx_param); 4698 if (status != QDF_STATUS_SUCCESS) { 4699 wmi_err("Populate TX send params failed"); 4700 goto unmap_tx_frame; 4701 } 4702 } else { 4703 WMITLV_SET_HDR(&((wmi_tx_send_params *)bufp)->tlv_header, 4704 WMITLV_TAG_STRUC_wmi_tx_send_params, 4705 WMITLV_GET_STRUCT_TLVLEN(wmi_tx_send_params)); 4706 } 4707 4708 /* Even tx_params_valid is false, still need reserve space to pass wmi 4709 * tag check */ 4710 cmd_len += sizeof(wmi_tx_send_params); 4711 bufp += sizeof(wmi_tx_send_params); 4712 /* wmi_mlo_tx_send_params */ 4713 if (param->mlo_link_agnostic) { 4714 wmi_debug("Set mlo mgmt tid"); 4715 WMITLV_SET_HDR(bufp, WMITLV_TAG_ARRAY_STRUC, 4716 sizeof(wmi_mlo_tx_send_params)); 4717 bufp += WMI_TLV_HDR_SIZE; 4718 mlo_params = (wmi_mlo_tx_send_params *)bufp; 4719 WMITLV_SET_HDR(&mlo_params->tlv_header, 4720 WMITLV_TAG_STRUC_wmi_mlo_tx_send_params, 4721 WMITLV_GET_STRUCT_TLVLEN(wmi_mlo_tx_send_params)); 4722 mlo_params->hw_link_id = WMI_MLO_MGMT_TID; 4723 cmd_len += WMI_TLV_HDR_SIZE + sizeof(wmi_mlo_tx_send_params); 4724 } 4725 4726 wmi_mtrace(WMI_MGMT_TX_SEND_CMDID, cmd->vdev_id, 0); 4727 if (wmi_unified_cmd_send(wmi_handle, buf, cmd_len, 4728 WMI_MGMT_TX_SEND_CMDID)) { 4729 wmi_err("Failed to send mgmt Tx"); 4730 goto unmap_tx_frame; 4731 } 4732 return QDF_STATUS_SUCCESS; 4733 4734 unmap_tx_frame: 4735 qdf_nbuf_unmap_single(qdf_ctx, param->tx_frame, 4736 QDF_DMA_TO_DEVICE); 4737 free_buf: 4738 wmi_buf_free(buf); 4739 return QDF_STATUS_E_FAILURE; 4740 } 4741 #endif /* CONFIG_HL_SUPPORT */ 4742 4743 /** 4744 * send_offchan_data_tx_cmd_tlv() - Send off-chan tx data 4745 * @wmi_handle: handle to WMI. 4746 * @param: pointer to offchan data tx cmd parameter 4747 * 4748 * Return: QDF_STATUS_SUCCESS on success and error on failure. 4749 */ 4750 static QDF_STATUS send_offchan_data_tx_cmd_tlv(wmi_unified_t wmi_handle, 4751 struct wmi_offchan_data_tx_params *param) 4752 { 4753 wmi_buf_t buf; 4754 wmi_offchan_data_tx_send_cmd_fixed_param *cmd; 4755 int32_t cmd_len; 4756 uint64_t dma_addr; 4757 void *qdf_ctx = param->qdf_ctx; 4758 uint8_t *bufp; 4759 int32_t bufp_len = (param->frm_len < mgmt_tx_dl_frm_len) ? 4760 param->frm_len : mgmt_tx_dl_frm_len; 4761 QDF_STATUS status = QDF_STATUS_SUCCESS; 4762 4763 cmd_len = sizeof(wmi_offchan_data_tx_send_cmd_fixed_param) + 4764 WMI_TLV_HDR_SIZE + 4765 roundup(bufp_len, sizeof(uint32_t)); 4766 4767 buf = wmi_buf_alloc(wmi_handle, sizeof(wmi_tx_send_params) + cmd_len); 4768 if (!buf) 4769 return QDF_STATUS_E_NOMEM; 4770 4771 cmd = (wmi_offchan_data_tx_send_cmd_fixed_param *) wmi_buf_data(buf); 4772 bufp = (uint8_t *) cmd; 4773 WMITLV_SET_HDR(&cmd->tlv_header, 4774 WMITLV_TAG_STRUC_wmi_offchan_data_tx_send_cmd_fixed_param, 4775 WMITLV_GET_STRUCT_TLVLEN 4776 (wmi_offchan_data_tx_send_cmd_fixed_param)); 4777 4778 cmd->vdev_id = param->vdev_id; 4779 4780 cmd->desc_id = param->desc_id; 4781 cmd->chanfreq = param->chanfreq; 4782 bufp += sizeof(wmi_offchan_data_tx_send_cmd_fixed_param); 4783 WMITLV_SET_HDR(bufp, WMITLV_TAG_ARRAY_BYTE, roundup(bufp_len, 4784 sizeof(uint32_t))); 4785 bufp += WMI_TLV_HDR_SIZE; 4786 qdf_mem_copy(bufp, param->pdata, bufp_len); 4787 qdf_nbuf_map_single(qdf_ctx, param->tx_frame, QDF_DMA_TO_DEVICE); 4788 dma_addr = qdf_nbuf_get_frag_paddr(param->tx_frame, 0); 4789 cmd->paddr_lo = (uint32_t)(dma_addr & 0xffffffff); 4790 #if defined(HTT_PADDR64) 4791 cmd->paddr_hi = (uint32_t)((dma_addr >> 32) & 0x1F); 4792 #endif 4793 cmd->frame_len = param->frm_len; 4794 cmd->buf_len = bufp_len; 4795 cmd->tx_params_valid = param->tx_params_valid; 4796 4797 wmi_mgmt_cmd_record(wmi_handle, WMI_OFFCHAN_DATA_TX_SEND_CMDID, 4798 bufp, cmd->vdev_id, cmd->chanfreq); 4799 4800 bufp += roundup(bufp_len, sizeof(uint32_t)); 4801 if (param->tx_params_valid) { 4802 status = populate_tx_send_params(bufp, param->tx_param); 4803 if (status != QDF_STATUS_SUCCESS) { 4804 wmi_err("Populate TX send params failed"); 4805 goto err1; 4806 } 4807 cmd_len += sizeof(wmi_tx_send_params); 4808 } 4809 4810 wmi_mtrace(WMI_OFFCHAN_DATA_TX_SEND_CMDID, cmd->vdev_id, 0); 4811 if (wmi_unified_cmd_send(wmi_handle, buf, cmd_len, 4812 WMI_OFFCHAN_DATA_TX_SEND_CMDID)) { 4813 wmi_err("Failed to offchan data Tx"); 4814 goto err1; 4815 } 4816 4817 return QDF_STATUS_SUCCESS; 4818 4819 err1: 4820 wmi_buf_free(buf); 4821 return QDF_STATUS_E_FAILURE; 4822 } 4823 4824 /** 4825 * send_modem_power_state_cmd_tlv() - set modem power state to fw 4826 * @wmi_handle: wmi handle 4827 * @param_value: parameter value 4828 * 4829 * Return: QDF_STATUS_SUCCESS for success or error code 4830 */ 4831 static QDF_STATUS send_modem_power_state_cmd_tlv(wmi_unified_t wmi_handle, 4832 uint32_t param_value) 4833 { 4834 QDF_STATUS ret; 4835 wmi_modem_power_state_cmd_param *cmd; 4836 wmi_buf_t buf; 4837 uint16_t len = sizeof(*cmd); 4838 4839 buf = wmi_buf_alloc(wmi_handle, len); 4840 if (!buf) 4841 return QDF_STATUS_E_NOMEM; 4842 4843 cmd = (wmi_modem_power_state_cmd_param *) wmi_buf_data(buf); 4844 WMITLV_SET_HDR(&cmd->tlv_header, 4845 WMITLV_TAG_STRUC_wmi_modem_power_state_cmd_param, 4846 WMITLV_GET_STRUCT_TLVLEN 4847 (wmi_modem_power_state_cmd_param)); 4848 cmd->modem_power_state = param_value; 4849 wmi_debug("Setting cmd->modem_power_state = %u", param_value); 4850 wmi_mtrace(WMI_MODEM_POWER_STATE_CMDID, NO_SESSION, 0); 4851 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 4852 WMI_MODEM_POWER_STATE_CMDID); 4853 if (QDF_IS_STATUS_ERROR(ret)) { 4854 wmi_err("Failed to send notify cmd ret = %d", ret); 4855 wmi_buf_free(buf); 4856 } 4857 4858 return ret; 4859 } 4860 4861 /** 4862 * send_set_sta_ps_mode_cmd_tlv() - set sta powersave mode in fw 4863 * @wmi_handle: wmi handle 4864 * @vdev_id: vdev id 4865 * @val: value 4866 * 4867 * Return: QDF_STATUS_SUCCESS for success or error code. 4868 */ 4869 static QDF_STATUS send_set_sta_ps_mode_cmd_tlv(wmi_unified_t wmi_handle, 4870 uint32_t vdev_id, uint8_t val) 4871 { 4872 wmi_sta_powersave_mode_cmd_fixed_param *cmd; 4873 wmi_buf_t buf; 4874 int32_t len = sizeof(*cmd); 4875 4876 wmi_debug("Set Sta Mode Ps vdevId %d val %d", vdev_id, val); 4877 4878 buf = wmi_buf_alloc(wmi_handle, len); 4879 if (!buf) 4880 return QDF_STATUS_E_NOMEM; 4881 4882 cmd = (wmi_sta_powersave_mode_cmd_fixed_param *) wmi_buf_data(buf); 4883 WMITLV_SET_HDR(&cmd->tlv_header, 4884 WMITLV_TAG_STRUC_wmi_sta_powersave_mode_cmd_fixed_param, 4885 WMITLV_GET_STRUCT_TLVLEN 4886 (wmi_sta_powersave_mode_cmd_fixed_param)); 4887 cmd->vdev_id = vdev_id; 4888 if (val) 4889 cmd->sta_ps_mode = WMI_STA_PS_MODE_ENABLED; 4890 else 4891 cmd->sta_ps_mode = WMI_STA_PS_MODE_DISABLED; 4892 4893 wmi_mtrace(WMI_STA_POWERSAVE_MODE_CMDID, cmd->vdev_id, 0); 4894 if (wmi_unified_cmd_send(wmi_handle, buf, len, 4895 WMI_STA_POWERSAVE_MODE_CMDID)) { 4896 wmi_err("Set Sta Mode Ps Failed vdevId %d val %d", 4897 vdev_id, val); 4898 wmi_buf_free(buf); 4899 return QDF_STATUS_E_FAILURE; 4900 } 4901 return QDF_STATUS_SUCCESS; 4902 } 4903 4904 /** 4905 * send_idle_roam_monitor_cmd_tlv() - send idle monitor command to fw 4906 * @wmi_handle: wmi handle 4907 * @val: non-zero to turn monitor on 4908 * 4909 * Return: QDF_STATUS_SUCCESS for success or error code. 4910 */ 4911 static QDF_STATUS send_idle_roam_monitor_cmd_tlv(wmi_unified_t wmi_handle, 4912 uint8_t val) 4913 { 4914 wmi_idle_trigger_monitor_cmd_fixed_param *cmd; 4915 wmi_buf_t buf; 4916 size_t len = sizeof(*cmd); 4917 4918 buf = wmi_buf_alloc(wmi_handle, len); 4919 if (!buf) 4920 return QDF_STATUS_E_NOMEM; 4921 4922 cmd = (wmi_idle_trigger_monitor_cmd_fixed_param *)wmi_buf_data(buf); 4923 WMITLV_SET_HDR(&cmd->tlv_header, 4924 WMITLV_TAG_STRUC_wmi_idle_trigger_monitor_cmd_fixed_param, 4925 WMITLV_GET_STRUCT_TLVLEN(wmi_idle_trigger_monitor_cmd_fixed_param)); 4926 4927 cmd->idle_trigger_monitor = (val ? WMI_IDLE_TRIGGER_MONITOR_ON : 4928 WMI_IDLE_TRIGGER_MONITOR_OFF); 4929 4930 wmi_debug("val: %d", cmd->idle_trigger_monitor); 4931 4932 if (wmi_unified_cmd_send(wmi_handle, buf, len, 4933 WMI_IDLE_TRIGGER_MONITOR_CMDID)) { 4934 wmi_buf_free(buf); 4935 return QDF_STATUS_E_FAILURE; 4936 } 4937 return QDF_STATUS_SUCCESS; 4938 } 4939 4940 /** 4941 * send_set_mimops_cmd_tlv() - set MIMO powersave 4942 * @wmi_handle: wmi handle 4943 * @vdev_id: vdev id 4944 * @value: value 4945 * 4946 * Return: QDF_STATUS_SUCCESS for success or error code. 4947 */ 4948 static QDF_STATUS send_set_mimops_cmd_tlv(wmi_unified_t wmi_handle, 4949 uint8_t vdev_id, int value) 4950 { 4951 QDF_STATUS ret; 4952 wmi_sta_smps_force_mode_cmd_fixed_param *cmd; 4953 wmi_buf_t buf; 4954 uint16_t len = sizeof(*cmd); 4955 4956 buf = wmi_buf_alloc(wmi_handle, len); 4957 if (!buf) 4958 return QDF_STATUS_E_NOMEM; 4959 4960 cmd = (wmi_sta_smps_force_mode_cmd_fixed_param *) wmi_buf_data(buf); 4961 WMITLV_SET_HDR(&cmd->tlv_header, 4962 WMITLV_TAG_STRUC_wmi_sta_smps_force_mode_cmd_fixed_param, 4963 WMITLV_GET_STRUCT_TLVLEN 4964 (wmi_sta_smps_force_mode_cmd_fixed_param)); 4965 4966 cmd->vdev_id = vdev_id; 4967 4968 /* WMI_SMPS_FORCED_MODE values do not directly map 4969 * to SM power save values defined in the specification. 4970 * Make sure to send the right mapping. 4971 */ 4972 switch (value) { 4973 case 0: 4974 cmd->forced_mode = WMI_SMPS_FORCED_MODE_NONE; 4975 break; 4976 case 1: 4977 cmd->forced_mode = WMI_SMPS_FORCED_MODE_DISABLED; 4978 break; 4979 case 2: 4980 cmd->forced_mode = WMI_SMPS_FORCED_MODE_STATIC; 4981 break; 4982 case 3: 4983 cmd->forced_mode = WMI_SMPS_FORCED_MODE_DYNAMIC; 4984 break; 4985 default: 4986 wmi_err("INVALID MIMO PS CONFIG: %d", value); 4987 wmi_buf_free(buf); 4988 return QDF_STATUS_E_FAILURE; 4989 } 4990 4991 wmi_debug("Setting vdev %d value = %u", vdev_id, value); 4992 4993 wmi_mtrace(WMI_STA_SMPS_FORCE_MODE_CMDID, cmd->vdev_id, 0); 4994 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 4995 WMI_STA_SMPS_FORCE_MODE_CMDID); 4996 if (QDF_IS_STATUS_ERROR(ret)) { 4997 wmi_err("Failed to send set Mimo PS ret = %d", ret); 4998 wmi_buf_free(buf); 4999 } 5000 5001 return ret; 5002 } 5003 5004 /** 5005 * send_set_smps_params_cmd_tlv() - set smps params 5006 * @wmi_handle: wmi handle 5007 * @vdev_id: vdev id 5008 * @value: value 5009 * 5010 * Return: QDF_STATUS_SUCCESS for success or error code. 5011 */ 5012 static QDF_STATUS send_set_smps_params_cmd_tlv(wmi_unified_t wmi_handle, uint8_t vdev_id, 5013 int value) 5014 { 5015 QDF_STATUS ret; 5016 wmi_sta_smps_param_cmd_fixed_param *cmd; 5017 wmi_buf_t buf; 5018 uint16_t len = sizeof(*cmd); 5019 5020 buf = wmi_buf_alloc(wmi_handle, len); 5021 if (!buf) 5022 return QDF_STATUS_E_NOMEM; 5023 5024 cmd = (wmi_sta_smps_param_cmd_fixed_param *) wmi_buf_data(buf); 5025 WMITLV_SET_HDR(&cmd->tlv_header, 5026 WMITLV_TAG_STRUC_wmi_sta_smps_param_cmd_fixed_param, 5027 WMITLV_GET_STRUCT_TLVLEN 5028 (wmi_sta_smps_param_cmd_fixed_param)); 5029 5030 cmd->vdev_id = vdev_id; 5031 cmd->value = value & WMI_SMPS_MASK_LOWER_16BITS; 5032 cmd->param = 5033 (value >> WMI_SMPS_PARAM_VALUE_S) & WMI_SMPS_MASK_UPPER_3BITS; 5034 5035 wmi_debug("Setting vdev %d value = %x param %x", vdev_id, cmd->value, 5036 cmd->param); 5037 5038 wmi_mtrace(WMI_STA_SMPS_PARAM_CMDID, cmd->vdev_id, 0); 5039 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 5040 WMI_STA_SMPS_PARAM_CMDID); 5041 if (QDF_IS_STATUS_ERROR(ret)) { 5042 wmi_err("Failed to send set Mimo PS ret = %d", ret); 5043 wmi_buf_free(buf); 5044 } 5045 5046 return ret; 5047 } 5048 5049 /** 5050 * send_get_temperature_cmd_tlv() - get pdev temperature req 5051 * @wmi_handle: wmi handle 5052 * 5053 * Return: QDF_STATUS_SUCCESS for success or error code. 5054 */ 5055 static QDF_STATUS send_get_temperature_cmd_tlv(wmi_unified_t wmi_handle) 5056 { 5057 wmi_pdev_get_temperature_cmd_fixed_param *cmd; 5058 wmi_buf_t wmi_buf; 5059 uint32_t len = sizeof(wmi_pdev_get_temperature_cmd_fixed_param); 5060 uint8_t *buf_ptr; 5061 5062 if (!wmi_handle) { 5063 wmi_err("WMI is closed, can not issue cmd"); 5064 return QDF_STATUS_E_INVAL; 5065 } 5066 5067 wmi_buf = wmi_buf_alloc(wmi_handle, len); 5068 if (!wmi_buf) 5069 return QDF_STATUS_E_NOMEM; 5070 5071 buf_ptr = (uint8_t *) wmi_buf_data(wmi_buf); 5072 5073 cmd = (wmi_pdev_get_temperature_cmd_fixed_param *) buf_ptr; 5074 WMITLV_SET_HDR(&cmd->tlv_header, 5075 WMITLV_TAG_STRUC_wmi_pdev_get_temperature_cmd_fixed_param, 5076 WMITLV_GET_STRUCT_TLVLEN 5077 (wmi_pdev_get_temperature_cmd_fixed_param)); 5078 5079 wmi_mtrace(WMI_PDEV_GET_TEMPERATURE_CMDID, NO_SESSION, 0); 5080 if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len, 5081 WMI_PDEV_GET_TEMPERATURE_CMDID)) { 5082 wmi_err("Failed to send get temperature command"); 5083 wmi_buf_free(wmi_buf); 5084 return QDF_STATUS_E_FAILURE; 5085 } 5086 5087 return QDF_STATUS_SUCCESS; 5088 } 5089 5090 /** 5091 * send_set_sta_uapsd_auto_trig_cmd_tlv() - set uapsd auto trigger command 5092 * @wmi_handle: wmi handle 5093 * @param: UAPSD trigger parameters 5094 * 5095 * This function sets the trigger 5096 * uapsd params such as service interval, delay interval 5097 * and suspend interval which will be used by the firmware 5098 * to send trigger frames periodically when there is no 5099 * traffic on the transmit side. 5100 * 5101 * Return: QDF_STATUS_SUCCESS for success or error code. 5102 */ 5103 static QDF_STATUS send_set_sta_uapsd_auto_trig_cmd_tlv(wmi_unified_t wmi_handle, 5104 struct sta_uapsd_trig_params *param) 5105 { 5106 wmi_sta_uapsd_auto_trig_cmd_fixed_param *cmd; 5107 QDF_STATUS ret; 5108 uint32_t param_len = param->num_ac * sizeof(wmi_sta_uapsd_auto_trig_param); 5109 uint32_t cmd_len = sizeof(*cmd) + param_len + WMI_TLV_HDR_SIZE; 5110 uint32_t i; 5111 wmi_buf_t buf; 5112 uint8_t *buf_ptr; 5113 struct sta_uapsd_params *uapsd_param; 5114 wmi_sta_uapsd_auto_trig_param *trig_param; 5115 5116 buf = wmi_buf_alloc(wmi_handle, cmd_len); 5117 if (!buf) 5118 return QDF_STATUS_E_NOMEM; 5119 5120 buf_ptr = (uint8_t *) wmi_buf_data(buf); 5121 cmd = (wmi_sta_uapsd_auto_trig_cmd_fixed_param *) buf_ptr; 5122 WMITLV_SET_HDR(&cmd->tlv_header, 5123 WMITLV_TAG_STRUC_wmi_sta_uapsd_auto_trig_cmd_fixed_param, 5124 WMITLV_GET_STRUCT_TLVLEN 5125 (wmi_sta_uapsd_auto_trig_cmd_fixed_param)); 5126 cmd->vdev_id = param->vdevid; 5127 cmd->num_ac = param->num_ac; 5128 WMI_CHAR_ARRAY_TO_MAC_ADDR(param->peer_addr, &cmd->peer_macaddr); 5129 5130 /* TLV indicating array of structures to follow */ 5131 buf_ptr += sizeof(*cmd); 5132 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, param_len); 5133 5134 buf_ptr += WMI_TLV_HDR_SIZE; 5135 5136 /* 5137 * Update tag and length for uapsd auto trigger params (this will take 5138 * care of updating tag and length if it is not pre-filled by caller). 5139 */ 5140 uapsd_param = (struct sta_uapsd_params *)param->auto_triggerparam; 5141 trig_param = (wmi_sta_uapsd_auto_trig_param *)buf_ptr; 5142 for (i = 0; i < param->num_ac; i++) { 5143 WMITLV_SET_HDR((buf_ptr + 5144 (i * sizeof(wmi_sta_uapsd_auto_trig_param))), 5145 WMITLV_TAG_STRUC_wmi_sta_uapsd_auto_trig_param, 5146 WMITLV_GET_STRUCT_TLVLEN 5147 (wmi_sta_uapsd_auto_trig_param)); 5148 trig_param->wmm_ac = uapsd_param->wmm_ac; 5149 trig_param->user_priority = uapsd_param->user_priority; 5150 trig_param->service_interval = uapsd_param->service_interval; 5151 trig_param->suspend_interval = uapsd_param->suspend_interval; 5152 trig_param->delay_interval = uapsd_param->delay_interval; 5153 trig_param++; 5154 uapsd_param++; 5155 } 5156 5157 wmi_mtrace(WMI_STA_UAPSD_AUTO_TRIG_CMDID, cmd->vdev_id, 0); 5158 ret = wmi_unified_cmd_send(wmi_handle, buf, cmd_len, 5159 WMI_STA_UAPSD_AUTO_TRIG_CMDID); 5160 if (QDF_IS_STATUS_ERROR(ret)) { 5161 wmi_err("Failed to send set uapsd param ret = %d", ret); 5162 wmi_buf_free(buf); 5163 } 5164 5165 return ret; 5166 } 5167 5168 /** 5169 * send_set_thermal_mgmt_cmd_tlv() - set thermal mgmt command to fw 5170 * @wmi_handle: Pointer to wmi handle 5171 * @thermal_info: Thermal command information 5172 * 5173 * This function sends the thermal management command 5174 * to the firmware 5175 * 5176 * Return: QDF_STATUS_SUCCESS for success otherwise failure 5177 */ 5178 static QDF_STATUS send_set_thermal_mgmt_cmd_tlv(wmi_unified_t wmi_handle, 5179 struct thermal_cmd_params *thermal_info) 5180 { 5181 wmi_thermal_mgmt_cmd_fixed_param *cmd = NULL; 5182 wmi_buf_t buf = NULL; 5183 QDF_STATUS status; 5184 uint32_t len = 0; 5185 uint8_t action; 5186 5187 switch (thermal_info->thermal_action) { 5188 case THERMAL_MGMT_ACTION_DEFAULT: 5189 action = WMI_THERMAL_MGMT_ACTION_DEFAULT; 5190 break; 5191 5192 case THERMAL_MGMT_ACTION_HALT_TRAFFIC: 5193 action = WMI_THERMAL_MGMT_ACTION_HALT_TRAFFIC; 5194 break; 5195 5196 case THERMAL_MGMT_ACTION_NOTIFY_HOST: 5197 action = WMI_THERMAL_MGMT_ACTION_NOTIFY_HOST; 5198 break; 5199 5200 case THERMAL_MGMT_ACTION_CHAINSCALING: 5201 action = WMI_THERMAL_MGMT_ACTION_CHAINSCALING; 5202 break; 5203 5204 default: 5205 wmi_err("Invalid thermal_action code %d", 5206 thermal_info->thermal_action); 5207 return QDF_STATUS_E_FAILURE; 5208 } 5209 5210 len = sizeof(*cmd); 5211 5212 buf = wmi_buf_alloc(wmi_handle, len); 5213 if (!buf) 5214 return QDF_STATUS_E_FAILURE; 5215 5216 cmd = (wmi_thermal_mgmt_cmd_fixed_param *) wmi_buf_data(buf); 5217 5218 WMITLV_SET_HDR(&cmd->tlv_header, 5219 WMITLV_TAG_STRUC_wmi_thermal_mgmt_cmd_fixed_param, 5220 WMITLV_GET_STRUCT_TLVLEN 5221 (wmi_thermal_mgmt_cmd_fixed_param)); 5222 5223 cmd->lower_thresh_degreeC = thermal_info->min_temp; 5224 cmd->upper_thresh_degreeC = thermal_info->max_temp; 5225 cmd->enable = thermal_info->thermal_enable; 5226 cmd->action = action; 5227 5228 wmi_debug("TM Sending thermal mgmt cmd: low temp %d, upper temp %d, enabled %d action %d", 5229 cmd->lower_thresh_degreeC, cmd->upper_thresh_degreeC, 5230 cmd->enable, cmd->action); 5231 5232 wmi_mtrace(WMI_THERMAL_MGMT_CMDID, NO_SESSION, 0); 5233 status = wmi_unified_cmd_send(wmi_handle, buf, len, 5234 WMI_THERMAL_MGMT_CMDID); 5235 if (QDF_IS_STATUS_ERROR(status)) { 5236 wmi_buf_free(buf); 5237 wmi_err("Failed to send thermal mgmt command"); 5238 } 5239 5240 return status; 5241 } 5242 5243 /** 5244 * send_lro_config_cmd_tlv() - process the LRO config command 5245 * @wmi_handle: Pointer to WMI handle 5246 * @wmi_lro_cmd: Pointer to LRO configuration parameters 5247 * 5248 * This function sends down the LRO configuration parameters to 5249 * the firmware to enable LRO, sets the TCP flags and sets the 5250 * seed values for the toeplitz hash generation 5251 * 5252 * Return: QDF_STATUS_SUCCESS for success otherwise failure 5253 */ 5254 static QDF_STATUS send_lro_config_cmd_tlv(wmi_unified_t wmi_handle, 5255 struct wmi_lro_config_cmd_t *wmi_lro_cmd) 5256 { 5257 wmi_lro_info_cmd_fixed_param *cmd; 5258 wmi_buf_t buf; 5259 QDF_STATUS status; 5260 uint8_t pdev_id = wmi_lro_cmd->pdev_id; 5261 5262 buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd)); 5263 if (!buf) 5264 return QDF_STATUS_E_FAILURE; 5265 5266 cmd = (wmi_lro_info_cmd_fixed_param *) wmi_buf_data(buf); 5267 5268 WMITLV_SET_HDR(&cmd->tlv_header, 5269 WMITLV_TAG_STRUC_wmi_lro_info_cmd_fixed_param, 5270 WMITLV_GET_STRUCT_TLVLEN(wmi_lro_info_cmd_fixed_param)); 5271 5272 cmd->lro_enable = wmi_lro_cmd->lro_enable; 5273 WMI_LRO_INFO_TCP_FLAG_VALS_SET(cmd->tcp_flag_u32, 5274 wmi_lro_cmd->tcp_flag); 5275 WMI_LRO_INFO_TCP_FLAGS_MASK_SET(cmd->tcp_flag_u32, 5276 wmi_lro_cmd->tcp_flag_mask); 5277 cmd->toeplitz_hash_ipv4_0_3 = 5278 wmi_lro_cmd->toeplitz_hash_ipv4[0]; 5279 cmd->toeplitz_hash_ipv4_4_7 = 5280 wmi_lro_cmd->toeplitz_hash_ipv4[1]; 5281 cmd->toeplitz_hash_ipv4_8_11 = 5282 wmi_lro_cmd->toeplitz_hash_ipv4[2]; 5283 cmd->toeplitz_hash_ipv4_12_15 = 5284 wmi_lro_cmd->toeplitz_hash_ipv4[3]; 5285 cmd->toeplitz_hash_ipv4_16 = 5286 wmi_lro_cmd->toeplitz_hash_ipv4[4]; 5287 5288 cmd->toeplitz_hash_ipv6_0_3 = 5289 wmi_lro_cmd->toeplitz_hash_ipv6[0]; 5290 cmd->toeplitz_hash_ipv6_4_7 = 5291 wmi_lro_cmd->toeplitz_hash_ipv6[1]; 5292 cmd->toeplitz_hash_ipv6_8_11 = 5293 wmi_lro_cmd->toeplitz_hash_ipv6[2]; 5294 cmd->toeplitz_hash_ipv6_12_15 = 5295 wmi_lro_cmd->toeplitz_hash_ipv6[3]; 5296 cmd->toeplitz_hash_ipv6_16_19 = 5297 wmi_lro_cmd->toeplitz_hash_ipv6[4]; 5298 cmd->toeplitz_hash_ipv6_20_23 = 5299 wmi_lro_cmd->toeplitz_hash_ipv6[5]; 5300 cmd->toeplitz_hash_ipv6_24_27 = 5301 wmi_lro_cmd->toeplitz_hash_ipv6[6]; 5302 cmd->toeplitz_hash_ipv6_28_31 = 5303 wmi_lro_cmd->toeplitz_hash_ipv6[7]; 5304 cmd->toeplitz_hash_ipv6_32_35 = 5305 wmi_lro_cmd->toeplitz_hash_ipv6[8]; 5306 cmd->toeplitz_hash_ipv6_36_39 = 5307 wmi_lro_cmd->toeplitz_hash_ipv6[9]; 5308 cmd->toeplitz_hash_ipv6_40 = 5309 wmi_lro_cmd->toeplitz_hash_ipv6[10]; 5310 5311 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 5312 wmi_handle, 5313 pdev_id); 5314 wmi_debug("WMI_LRO_CONFIG: lro_enable %d, tcp_flag 0x%x, pdev_id: %d", 5315 cmd->lro_enable, cmd->tcp_flag_u32, cmd->pdev_id); 5316 5317 wmi_mtrace(WMI_LRO_CONFIG_CMDID, NO_SESSION, 0); 5318 status = wmi_unified_cmd_send(wmi_handle, buf, 5319 sizeof(*cmd), WMI_LRO_CONFIG_CMDID); 5320 if (QDF_IS_STATUS_ERROR(status)) { 5321 wmi_buf_free(buf); 5322 wmi_err("Failed to send WMI_LRO_CONFIG_CMDID"); 5323 } 5324 5325 return status; 5326 } 5327 5328 /** 5329 * send_peer_rate_report_cmd_tlv() - process the peer rate report command 5330 * @wmi_handle: Pointer to wmi handle 5331 * @rate_report_params: Pointer to peer rate report parameters 5332 * 5333 * 5334 * Return: QDF_STATUS_SUCCESS for success otherwise failure 5335 */ 5336 static QDF_STATUS send_peer_rate_report_cmd_tlv(wmi_unified_t wmi_handle, 5337 struct wmi_peer_rate_report_params *rate_report_params) 5338 { 5339 wmi_peer_set_rate_report_condition_fixed_param *cmd = NULL; 5340 wmi_buf_t buf = NULL; 5341 QDF_STATUS status = 0; 5342 uint32_t len = 0; 5343 uint32_t i, j; 5344 5345 len = sizeof(*cmd); 5346 5347 buf = wmi_buf_alloc(wmi_handle, len); 5348 if (!buf) 5349 return QDF_STATUS_E_FAILURE; 5350 5351 cmd = (wmi_peer_set_rate_report_condition_fixed_param *) 5352 wmi_buf_data(buf); 5353 5354 WMITLV_SET_HDR( 5355 &cmd->tlv_header, 5356 WMITLV_TAG_STRUC_wmi_peer_set_rate_report_condition_fixed_param, 5357 WMITLV_GET_STRUCT_TLVLEN( 5358 wmi_peer_set_rate_report_condition_fixed_param)); 5359 5360 cmd->enable_rate_report = rate_report_params->rate_report_enable; 5361 cmd->report_backoff_time = rate_report_params->backoff_time; 5362 cmd->report_timer_period = rate_report_params->timer_period; 5363 for (i = 0; i < PEER_RATE_REPORT_COND_MAX_NUM; i++) { 5364 cmd->cond_per_phy[i].val_cond_flags = 5365 rate_report_params->report_per_phy[i].cond_flags; 5366 cmd->cond_per_phy[i].rate_delta.min_delta = 5367 rate_report_params->report_per_phy[i].delta.delta_min; 5368 cmd->cond_per_phy[i].rate_delta.percentage = 5369 rate_report_params->report_per_phy[i].delta.percent; 5370 for (j = 0; j < MAX_NUM_OF_RATE_THRESH; j++) { 5371 cmd->cond_per_phy[i].rate_threshold[j] = 5372 rate_report_params->report_per_phy[i]. 5373 report_rate_threshold[j]; 5374 } 5375 } 5376 5377 wmi_debug("enable %d backoff_time %d period %d", 5378 cmd->enable_rate_report, 5379 cmd->report_backoff_time, cmd->report_timer_period); 5380 5381 wmi_mtrace(WMI_PEER_SET_RATE_REPORT_CONDITION_CMDID, NO_SESSION, 0); 5382 status = wmi_unified_cmd_send(wmi_handle, buf, len, 5383 WMI_PEER_SET_RATE_REPORT_CONDITION_CMDID); 5384 if (QDF_IS_STATUS_ERROR(status)) { 5385 wmi_buf_free(buf); 5386 wmi_err("Failed to send peer_set_report_cond command"); 5387 } 5388 return status; 5389 } 5390 5391 /** 5392 * send_process_update_edca_param_cmd_tlv() - update EDCA params 5393 * @wmi_handle: wmi handle 5394 * @vdev_id: vdev id. 5395 * @mu_edca_param: true if these are MU EDCA params 5396 * @wmm_vparams: edca parameters 5397 * 5398 * This function updates EDCA parameters to the target 5399 * 5400 * Return: CDF Status 5401 */ 5402 static QDF_STATUS send_process_update_edca_param_cmd_tlv(wmi_unified_t wmi_handle, 5403 uint8_t vdev_id, bool mu_edca_param, 5404 struct wmi_host_wme_vparams wmm_vparams[WMI_MAX_NUM_AC]) 5405 { 5406 uint8_t *buf_ptr; 5407 wmi_buf_t buf; 5408 wmi_vdev_set_wmm_params_cmd_fixed_param *cmd; 5409 wmi_wmm_vparams *wmm_param; 5410 struct wmi_host_wme_vparams *twmm_param; 5411 int len = sizeof(*cmd); 5412 int ac; 5413 5414 buf = wmi_buf_alloc(wmi_handle, len); 5415 5416 if (!buf) 5417 return QDF_STATUS_E_NOMEM; 5418 5419 buf_ptr = (uint8_t *) wmi_buf_data(buf); 5420 cmd = (wmi_vdev_set_wmm_params_cmd_fixed_param *) buf_ptr; 5421 WMITLV_SET_HDR(&cmd->tlv_header, 5422 WMITLV_TAG_STRUC_wmi_vdev_set_wmm_params_cmd_fixed_param, 5423 WMITLV_GET_STRUCT_TLVLEN 5424 (wmi_vdev_set_wmm_params_cmd_fixed_param)); 5425 cmd->vdev_id = vdev_id; 5426 cmd->wmm_param_type = mu_edca_param; 5427 5428 for (ac = 0; ac < WMI_MAX_NUM_AC; ac++) { 5429 wmm_param = (wmi_wmm_vparams *) (&cmd->wmm_params[ac]); 5430 twmm_param = (struct wmi_host_wme_vparams *) (&wmm_vparams[ac]); 5431 WMITLV_SET_HDR(&wmm_param->tlv_header, 5432 WMITLV_TAG_STRUC_wmi_vdev_set_wmm_params_cmd_fixed_param, 5433 WMITLV_GET_STRUCT_TLVLEN(wmi_wmm_vparams)); 5434 wmm_param->cwmin = twmm_param->cwmin; 5435 wmm_param->cwmax = twmm_param->cwmax; 5436 wmm_param->aifs = twmm_param->aifs; 5437 if (mu_edca_param) 5438 wmm_param->mu_edca_timer = twmm_param->mu_edca_timer; 5439 else 5440 wmm_param->txoplimit = twmm_param->txoplimit; 5441 wmm_param->acm = twmm_param->acm; 5442 wmm_param->no_ack = twmm_param->noackpolicy; 5443 } 5444 5445 wmi_mtrace(WMI_VDEV_SET_WMM_PARAMS_CMDID, cmd->vdev_id, 0); 5446 if (wmi_unified_cmd_send(wmi_handle, buf, len, 5447 WMI_VDEV_SET_WMM_PARAMS_CMDID)) 5448 goto fail; 5449 5450 return QDF_STATUS_SUCCESS; 5451 5452 fail: 5453 wmi_buf_free(buf); 5454 wmi_err("Failed to set WMM Parameters"); 5455 return QDF_STATUS_E_FAILURE; 5456 } 5457 5458 static WMI_EDCA_PARAM_TYPE 5459 wmi_convert_edca_pifs_param_type(enum host_edca_param_type type) 5460 { 5461 switch (type) { 5462 case HOST_EDCA_PARAM_TYPE_AGGRESSIVE: 5463 return WMI_EDCA_PARAM_TYPE_AGGRESSIVE; 5464 case HOST_EDCA_PARAM_TYPE_PIFS: 5465 return WMI_EDCA_PARAM_TYPE_PIFS; 5466 default: 5467 return WMI_EDCA_PARAM_TYPE_AGGRESSIVE; 5468 } 5469 } 5470 5471 /** 5472 * send_update_edca_pifs_param_cmd_tlv() - update EDCA params 5473 * @wmi_handle: wmi handle 5474 * @edca_pifs: edca/pifs parameters 5475 * 5476 * This function updates EDCA/PIFS parameters to the target 5477 * 5478 * Return: QDF Status 5479 */ 5480 5481 static QDF_STATUS 5482 send_update_edca_pifs_param_cmd_tlv(wmi_unified_t wmi_handle, 5483 struct edca_pifs_vparam *edca_pifs) 5484 { 5485 uint8_t *buf_ptr; 5486 wmi_buf_t buf = NULL; 5487 wmi_vdev_set_twt_edca_params_cmd_fixed_param *cmd; 5488 wmi_wmm_params *wmm_params; 5489 wmi_pifs_params *pifs_params; 5490 uint16_t len; 5491 5492 if (!edca_pifs) { 5493 wmi_debug("edca_pifs is NULL"); 5494 return QDF_STATUS_E_FAILURE; 5495 } 5496 5497 len = sizeof(wmi_vdev_set_twt_edca_params_cmd_fixed_param); 5498 if (edca_pifs->param.edca_param_type == 5499 HOST_EDCA_PARAM_TYPE_AGGRESSIVE) { 5500 len += WMI_TLV_HDR_SIZE; 5501 len += sizeof(wmi_wmm_params); 5502 } else { 5503 len += WMI_TLV_HDR_SIZE; 5504 } 5505 if (edca_pifs->param.edca_param_type == 5506 HOST_EDCA_PARAM_TYPE_PIFS) { 5507 len += WMI_TLV_HDR_SIZE; 5508 len += sizeof(wmi_pifs_params); 5509 } else { 5510 len += WMI_TLV_HDR_SIZE; 5511 } 5512 5513 buf = wmi_buf_alloc(wmi_handle, len); 5514 5515 if (!buf) 5516 return QDF_STATUS_E_NOMEM; 5517 5518 cmd = (wmi_vdev_set_twt_edca_params_cmd_fixed_param *)wmi_buf_data(buf); 5519 buf_ptr = (uint8_t *)cmd; 5520 5521 WMITLV_SET_HDR(&cmd->tlv_header, 5522 WMITLV_TAG_STRUC_wmi_vdev_set_twt_edca_params_cmd_fixed_param, 5523 WMITLV_GET_STRUCT_TLVLEN 5524 (wmi_vdev_set_twt_edca_params_cmd_fixed_param)); 5525 5526 cmd->vdev_id = edca_pifs->vdev_id; 5527 cmd->type = wmi_convert_edca_pifs_param_type( 5528 edca_pifs->param.edca_param_type); 5529 buf_ptr += sizeof(wmi_vdev_set_twt_edca_params_cmd_fixed_param); 5530 5531 if (cmd->type == WMI_EDCA_PARAM_TYPE_AGGRESSIVE) { 5532 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 5533 sizeof(*wmm_params)); 5534 buf_ptr += WMI_TLV_HDR_SIZE; 5535 wmm_params = (wmi_wmm_params *)buf_ptr; 5536 WMITLV_SET_HDR(&wmm_params->tlv_header, 5537 WMITLV_TAG_STRUC_wmi_wmm_params, 5538 WMITLV_GET_STRUCT_TLVLEN(wmi_wmm_params)); 5539 5540 wmm_params->cwmin = 5541 BIT(edca_pifs->param.edca_pifs_param.eparam.acvo_cwmin) - 1; 5542 wmm_params->cwmax = 5543 BIT(edca_pifs->param.edca_pifs_param.eparam.acvo_cwmax) - 1; 5544 wmm_params->aifs = 5545 edca_pifs->param.edca_pifs_param.eparam.acvo_aifsn - 1; 5546 wmm_params->txoplimit = 5547 edca_pifs->param.edca_pifs_param.eparam.acvo_txoplimit; 5548 wmm_params->acm = 5549 edca_pifs->param.edca_pifs_param.eparam.acvo_acm; 5550 wmm_params->no_ack = 0; 5551 wmi_debug("vdev_id %d type %d cwmin %d cwmax %d aifsn %d txoplimit %d acm %d no_ack %d", 5552 cmd->vdev_id, cmd->type, wmm_params->cwmin, 5553 wmm_params->cwmax, wmm_params->aifs, 5554 wmm_params->txoplimit, wmm_params->acm, 5555 wmm_params->no_ack); 5556 buf_ptr += sizeof(*wmm_params); 5557 } else { 5558 /* set zero TLV's for wmm_params */ 5559 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 5560 WMITLV_GET_STRUCT_TLVLEN(0)); 5561 buf_ptr += WMI_TLV_HDR_SIZE; 5562 } 5563 if (cmd->type == WMI_EDCA_PARAM_TYPE_PIFS) { 5564 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 5565 sizeof(*pifs_params)); 5566 buf_ptr += WMI_TLV_HDR_SIZE; 5567 pifs_params = (wmi_pifs_params *)buf_ptr; 5568 WMITLV_SET_HDR(&pifs_params->tlv_header, 5569 WMITLV_TAG_STRUC_wmi_pifs_params, 5570 WMITLV_GET_STRUCT_TLVLEN(wmi_pifs_params)); 5571 5572 pifs_params->sap_pifs_offset = 5573 edca_pifs->param.edca_pifs_param.pparam.sap_pifs_offset; 5574 pifs_params->leb_pifs_offset = 5575 edca_pifs->param.edca_pifs_param.pparam.leb_pifs_offset; 5576 pifs_params->reb_pifs_offset = 5577 edca_pifs->param.edca_pifs_param.pparam.reb_pifs_offset; 5578 wmi_debug("vdev_id %d type %d sap_offset %d leb_offset %d reb_offset %d", 5579 cmd->vdev_id, cmd->type, pifs_params->sap_pifs_offset, 5580 pifs_params->leb_pifs_offset, 5581 pifs_params->reb_pifs_offset); 5582 } else { 5583 /* set zero TLV's for pifs_params */ 5584 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 5585 WMITLV_GET_STRUCT_TLVLEN(0)); 5586 buf_ptr += WMI_TLV_HDR_SIZE; 5587 } 5588 5589 wmi_mtrace(WMI_VDEV_SET_TWT_EDCA_PARAMS_CMDID, cmd->vdev_id, 0); 5590 if (wmi_unified_cmd_send(wmi_handle, buf, len, 5591 WMI_VDEV_SET_TWT_EDCA_PARAMS_CMDID)) 5592 goto fail; 5593 5594 return QDF_STATUS_SUCCESS; 5595 5596 fail: 5597 wmi_buf_free(buf); 5598 wmi_err("Failed to set EDCA/PIFS Parameters"); 5599 return QDF_STATUS_E_FAILURE; 5600 } 5601 5602 /** 5603 * extract_csa_ie_received_ev_params_tlv() - extract csa IE received event 5604 * @wmi_handle: wmi handle 5605 * @evt_buf: pointer to event buffer 5606 * @vdev_id: VDEV ID 5607 * @csa_event: csa event data 5608 * 5609 * Return: QDF_STATUS_SUCCESS on success, QDF_STATUS_E_** on error 5610 */ 5611 static QDF_STATUS 5612 extract_csa_ie_received_ev_params_tlv(wmi_unified_t wmi_handle, 5613 void *evt_buf, uint8_t *vdev_id, 5614 struct csa_offload_params *csa_event) 5615 { 5616 WMI_CSA_IE_RECEIVED_EVENTID_param_tlvs *param_buf; 5617 wmi_csa_event_fixed_param *csa_ev; 5618 struct xcsa_ie *xcsa_ie; 5619 struct csa_ie *csa_ie; 5620 uint8_t *bssid; 5621 bool ret; 5622 5623 param_buf = (WMI_CSA_IE_RECEIVED_EVENTID_param_tlvs *)evt_buf; 5624 if (!param_buf) { 5625 wmi_err("Invalid csa event buffer"); 5626 return QDF_STATUS_E_FAILURE; 5627 } 5628 csa_ev = param_buf->fixed_param; 5629 WMI_MAC_ADDR_TO_CHAR_ARRAY(&csa_ev->i_addr2, 5630 &csa_event->bssid.bytes[0]); 5631 5632 bssid = csa_event->bssid.bytes; 5633 ret = wlan_get_connected_vdev_from_psoc_by_bssid(wmi_handle->soc->wmi_psoc, 5634 bssid, vdev_id); 5635 if (!ret) { 5636 wmi_err("VDEV is not connected with BSSID"); 5637 return QDF_STATUS_E_FAILURE; 5638 } 5639 5640 if (csa_ev->ies_present_flag & WMI_CSA_IE_PRESENT) { 5641 csa_ie = (struct csa_ie *)(&csa_ev->csa_ie[0]); 5642 csa_event->channel = csa_ie->new_channel; 5643 csa_event->switch_mode = csa_ie->switch_mode; 5644 csa_event->ies_present_flag |= MLME_CSA_IE_PRESENT; 5645 } else if (csa_ev->ies_present_flag & WMI_XCSA_IE_PRESENT) { 5646 xcsa_ie = (struct xcsa_ie *)(&csa_ev->xcsa_ie[0]); 5647 csa_event->channel = xcsa_ie->new_channel; 5648 csa_event->switch_mode = xcsa_ie->switch_mode; 5649 csa_event->new_op_class = xcsa_ie->new_class; 5650 csa_event->ies_present_flag |= MLME_XCSA_IE_PRESENT; 5651 } else { 5652 wmi_err("CSA Event error: No CSA IE present"); 5653 return QDF_STATUS_E_INVAL; 5654 } 5655 5656 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", 5657 QDF_MAC_ADDR_REF(csa_event->bssid.bytes), 5658 csa_event->channel, 5659 csa_event->csa_chan_freq, 5660 csa_event->ies_present_flag, 5661 csa_event->new_ch_width, 5662 csa_event->new_ch_freq_seg1, 5663 csa_event->new_ch_freq_seg2, 5664 csa_event->new_op_class); 5665 5666 if (!csa_event->channel) { 5667 wmi_err("CSA Event with channel %d. Ignore !!", 5668 csa_event->channel); 5669 return QDF_STATUS_E_FAILURE; 5670 } 5671 5672 return QDF_STATUS_SUCCESS; 5673 } 5674 5675 #ifdef WLAN_RCC_ENHANCED_AOA_SUPPORT 5676 static void 5677 populate_per_band_aoa_caps(struct wlan_psoc_host_rcc_enh_aoa_caps_ext2 *aoa_cap, 5678 wmi_enhanced_aoa_per_band_caps_param per_band_cap) 5679 { 5680 uint8_t tbl_idx; 5681 uint16_t *gain_array = NULL; 5682 5683 if (per_band_cap.band_info == WMI_AOA_2G) 5684 gain_array = aoa_cap->max_agc_gain_per_tbl_2g; 5685 else if (per_band_cap.band_info == WMI_AOA_5G) 5686 gain_array = aoa_cap->max_agc_gain_per_tbl_5g; 5687 else if (per_band_cap.band_info == WMI_AOA_6G) 5688 gain_array = aoa_cap->max_agc_gain_per_tbl_6g; 5689 5690 if (!gain_array) { 5691 wmi_debug("unhandled AOA BAND TYPE!! fix it"); 5692 return; 5693 } 5694 5695 for (tbl_idx = 0; tbl_idx < aoa_cap->max_agc_gain_tbls; tbl_idx++) 5696 WMI_AOA_MAX_AGC_GAIN_GET(per_band_cap.max_agc_gain, 5697 tbl_idx, 5698 gain_array[tbl_idx]); 5699 } 5700 5701 static void 5702 populate_aoa_caps(struct wmi_unified *wmi_handle, 5703 struct wlan_psoc_host_rcc_enh_aoa_caps_ext2 *aoa_cap, 5704 wmi_enhanced_aoa_caps_param *aoa_caps_param) 5705 { 5706 uint8_t tbl_idx; 5707 5708 aoa_cap->max_agc_gain_tbls = aoa_caps_param->max_agc_gain_tbls; 5709 if (aoa_cap->max_agc_gain_tbls > PSOC_MAX_NUM_AGC_GAIN_TBLS) { 5710 wmi_err("Num gain table > PSOC_MAX_NUM_AGC_GAIN_TBLS cap"); 5711 aoa_cap->max_agc_gain_tbls = PSOC_MAX_NUM_AGC_GAIN_TBLS; 5712 } 5713 5714 if (aoa_cap->max_agc_gain_tbls > WMI_AGC_MAX_GAIN_TABLE_IDX) { 5715 wmi_err("num gain table > WMI_AGC_MAX_GAIN_TABLE_IDX cap"); 5716 aoa_cap->max_agc_gain_tbls = WMI_AGC_MAX_GAIN_TABLE_IDX; 5717 } 5718 5719 for (tbl_idx = 0; tbl_idx < aoa_cap->max_agc_gain_tbls; tbl_idx++) { 5720 WMI_AOA_MAX_BDF_ENTRIES_GET 5721 (aoa_caps_param->max_bdf_gain_entries, 5722 tbl_idx, aoa_cap->max_bdf_entries_per_tbl[tbl_idx]); 5723 } 5724 } 5725 5726 /** 5727 * extract_aoa_caps_tlv() - extract aoa cap tlv 5728 * @wmi_handle: wmi handle 5729 * @event: pointer to event buffer 5730 * @aoa_cap: pointer to structure where capability needs to extracted 5731 * 5732 * Return: QDF_STATUS_SUCCESS on success, QDF_STATUS_E_** on error 5733 */ 5734 static QDF_STATUS 5735 extract_aoa_caps_tlv(struct wmi_unified *wmi_handle, uint8_t *event, 5736 struct wlan_psoc_host_rcc_enh_aoa_caps_ext2 *aoa_cap) 5737 { 5738 int8_t band; 5739 5740 WMI_SERVICE_READY_EXT2_EVENTID_param_tlvs *param_buf; 5741 5742 param_buf = (WMI_SERVICE_READY_EXT2_EVENTID_param_tlvs *)event; 5743 if (!param_buf) { 5744 wmi_err("NULL param buf"); 5745 return QDF_STATUS_E_INVAL; 5746 } 5747 5748 if (!param_buf->aoa_caps_param) { 5749 wmi_debug("NULL aoa_caps_param"); 5750 return QDF_STATUS_E_INVAL; 5751 } 5752 5753 if (!param_buf->num_aoa_per_band_caps_param || 5754 !param_buf->aoa_per_band_caps_param) { 5755 wmi_debug("No aoa_per_band_caps_param"); 5756 return QDF_STATUS_E_INVAL; 5757 } 5758 populate_aoa_caps(wmi_handle, aoa_cap, param_buf->aoa_caps_param); 5759 5760 for (band = 0; band < param_buf->num_aoa_per_band_caps_param; band++) 5761 populate_per_band_aoa_caps 5762 (aoa_cap, param_buf->aoa_per_band_caps_param[band]); 5763 5764 return QDF_STATUS_SUCCESS; 5765 } 5766 #endif /* WLAN_RCC_ENHANCED_AOA_SUPPORT */ 5767 5768 /** 5769 * send_probe_rsp_tmpl_send_cmd_tlv() - send probe response template to fw 5770 * @wmi_handle: wmi handle 5771 * @vdev_id: vdev id 5772 * @probe_rsp_info: probe response info 5773 * 5774 * Return: QDF_STATUS_SUCCESS for success or error code 5775 */ 5776 static QDF_STATUS send_probe_rsp_tmpl_send_cmd_tlv(wmi_unified_t wmi_handle, 5777 uint8_t vdev_id, 5778 struct wmi_probe_resp_params *probe_rsp_info) 5779 { 5780 wmi_prb_tmpl_cmd_fixed_param *cmd; 5781 wmi_bcn_prb_info *bcn_prb_info; 5782 wmi_buf_t wmi_buf; 5783 uint32_t tmpl_len, tmpl_len_aligned, wmi_buf_len; 5784 uint8_t *buf_ptr; 5785 QDF_STATUS ret; 5786 5787 wmi_debug("Send probe response template for vdev %d", vdev_id); 5788 5789 tmpl_len = probe_rsp_info->prb_rsp_template_len; 5790 tmpl_len_aligned = roundup(tmpl_len, sizeof(uint32_t)); 5791 5792 wmi_buf_len = sizeof(wmi_prb_tmpl_cmd_fixed_param) + 5793 sizeof(wmi_bcn_prb_info) + WMI_TLV_HDR_SIZE + 5794 tmpl_len_aligned + 5795 prb_resp_tmpl_ml_info_size(probe_rsp_info); 5796 5797 if (wmi_buf_len > WMI_BEACON_TX_BUFFER_SIZE) { 5798 wmi_err("wmi_buf_len: %d > %d. Can't send wmi cmd", 5799 wmi_buf_len, WMI_BEACON_TX_BUFFER_SIZE); 5800 return QDF_STATUS_E_INVAL; 5801 } 5802 5803 wmi_buf = wmi_buf_alloc(wmi_handle, wmi_buf_len); 5804 if (!wmi_buf) 5805 return QDF_STATUS_E_NOMEM; 5806 5807 buf_ptr = (uint8_t *) wmi_buf_data(wmi_buf); 5808 5809 cmd = (wmi_prb_tmpl_cmd_fixed_param *) buf_ptr; 5810 WMITLV_SET_HDR(&cmd->tlv_header, 5811 WMITLV_TAG_STRUC_wmi_prb_tmpl_cmd_fixed_param, 5812 WMITLV_GET_STRUCT_TLVLEN(wmi_prb_tmpl_cmd_fixed_param)); 5813 cmd->vdev_id = vdev_id; 5814 cmd->buf_len = tmpl_len; 5815 buf_ptr += sizeof(wmi_prb_tmpl_cmd_fixed_param); 5816 5817 bcn_prb_info = (wmi_bcn_prb_info *) buf_ptr; 5818 WMITLV_SET_HDR(&bcn_prb_info->tlv_header, 5819 WMITLV_TAG_STRUC_wmi_bcn_prb_info, 5820 WMITLV_GET_STRUCT_TLVLEN(wmi_bcn_prb_info)); 5821 bcn_prb_info->caps = 0; 5822 bcn_prb_info->erp = 0; 5823 buf_ptr += sizeof(wmi_bcn_prb_info); 5824 5825 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, tmpl_len_aligned); 5826 buf_ptr += WMI_TLV_HDR_SIZE; 5827 qdf_mem_copy(buf_ptr, probe_rsp_info->prb_rsp_template_frm, tmpl_len); 5828 buf_ptr += tmpl_len_aligned; 5829 buf_ptr = prb_resp_tmpl_add_ml_info(buf_ptr, probe_rsp_info); 5830 5831 wmi_mtrace(WMI_PRB_TMPL_CMDID, cmd->vdev_id, 0); 5832 ret = wmi_unified_cmd_send(wmi_handle, 5833 wmi_buf, wmi_buf_len, WMI_PRB_TMPL_CMDID); 5834 if (QDF_IS_STATUS_ERROR(ret)) { 5835 wmi_err("Failed to send PRB RSP tmpl: %d", ret); 5836 wmi_buf_free(wmi_buf); 5837 } 5838 5839 return ret; 5840 } 5841 5842 #if defined(ATH_SUPPORT_WAPI) || defined(FEATURE_WLAN_WAPI) 5843 #define WPI_IV_LEN 16 5844 5845 /** 5846 * wmi_update_wpi_key_counter() - update WAPI tsc and rsc key counters 5847 * 5848 * @dest_tx: destination address of tsc key counter 5849 * @src_tx: source address of tsc key counter 5850 * @dest_rx: destination address of rsc key counter 5851 * @src_rx: source address of rsc key counter 5852 * 5853 * This function copies WAPI tsc and rsc key counters in the wmi buffer. 5854 * 5855 * Return: None 5856 * 5857 */ 5858 static void wmi_update_wpi_key_counter(uint8_t *dest_tx, uint8_t *src_tx, 5859 uint8_t *dest_rx, uint8_t *src_rx) 5860 { 5861 qdf_mem_copy(dest_tx, src_tx, WPI_IV_LEN); 5862 qdf_mem_copy(dest_rx, src_rx, WPI_IV_LEN); 5863 } 5864 #else 5865 static void wmi_update_wpi_key_counter(uint8_t *dest_tx, uint8_t *src_tx, 5866 uint8_t *dest_rx, uint8_t *src_rx) 5867 { 5868 return; 5869 } 5870 #endif 5871 5872 /** 5873 * send_setup_install_key_cmd_tlv() - set key parameters 5874 * @wmi_handle: wmi handle 5875 * @key_params: key parameters 5876 * 5877 * This function fills structure from information 5878 * passed in key_params. 5879 * 5880 * Return: QDF_STATUS_SUCCESS - success 5881 * QDF_STATUS_E_FAILURE - failure 5882 * QDF_STATUS_E_NOMEM - not able to allocate buffer 5883 */ 5884 static QDF_STATUS send_setup_install_key_cmd_tlv(wmi_unified_t wmi_handle, 5885 struct set_key_params *key_params) 5886 { 5887 wmi_vdev_install_key_cmd_fixed_param *cmd; 5888 wmi_buf_t buf; 5889 uint8_t *buf_ptr; 5890 uint32_t len; 5891 uint8_t *key_data; 5892 QDF_STATUS status; 5893 5894 len = sizeof(*cmd) + roundup(key_params->key_len, sizeof(uint32_t)) + 5895 WMI_TLV_HDR_SIZE; 5896 5897 buf = wmi_buf_alloc(wmi_handle, len); 5898 if (!buf) 5899 return QDF_STATUS_E_NOMEM; 5900 5901 buf_ptr = (uint8_t *) wmi_buf_data(buf); 5902 cmd = (wmi_vdev_install_key_cmd_fixed_param *) buf_ptr; 5903 WMITLV_SET_HDR(&cmd->tlv_header, 5904 WMITLV_TAG_STRUC_wmi_vdev_install_key_cmd_fixed_param, 5905 WMITLV_GET_STRUCT_TLVLEN 5906 (wmi_vdev_install_key_cmd_fixed_param)); 5907 cmd->vdev_id = key_params->vdev_id; 5908 cmd->key_ix = key_params->key_idx; 5909 if (key_params->group_key_idx) { 5910 cmd->is_group_key_ix_valid = 1; 5911 cmd->group_key_ix = key_params->group_key_idx; 5912 } 5913 5914 WMI_CHAR_ARRAY_TO_MAC_ADDR(key_params->peer_mac, &cmd->peer_macaddr); 5915 cmd->key_flags |= key_params->key_flags; 5916 cmd->key_cipher = key_params->key_cipher; 5917 if ((key_params->key_txmic_len) && 5918 (key_params->key_rxmic_len)) { 5919 cmd->key_txmic_len = key_params->key_txmic_len; 5920 cmd->key_rxmic_len = key_params->key_rxmic_len; 5921 } 5922 #if defined(ATH_SUPPORT_WAPI) || defined(FEATURE_WLAN_WAPI) 5923 wmi_update_wpi_key_counter(cmd->wpi_key_tsc_counter, 5924 key_params->tx_iv, 5925 cmd->wpi_key_rsc_counter, 5926 key_params->rx_iv); 5927 #endif 5928 buf_ptr += sizeof(wmi_vdev_install_key_cmd_fixed_param); 5929 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, 5930 roundup(key_params->key_len, sizeof(uint32_t))); 5931 key_data = (uint8_t *) (buf_ptr + WMI_TLV_HDR_SIZE); 5932 5933 /* for big endian host, copy engine byte_swap is enabled 5934 * But key_data is in network byte order 5935 * Need to byte swap the key_data - so when copy engine 5936 * does byte_swap - target gets key_data in the correct order 5937 */ 5938 WMI_HOST_IF_MSG_COPY_CHAR_ARRAY((void *)key_data, 5939 (const void *)key_params->key_data, 5940 key_params->key_len); 5941 qdf_mem_copy(&cmd->key_rsc_counter, &key_params->key_rsc_counter, 5942 sizeof(wmi_key_seq_counter)); 5943 cmd->key_len = key_params->key_len; 5944 5945 qdf_mem_copy(&cmd->key_tsc_counter, &key_params->key_tsc_counter, 5946 sizeof(wmi_key_seq_counter)); 5947 wmi_mtrace(WMI_VDEV_INSTALL_KEY_CMDID, cmd->vdev_id, 0); 5948 status = wmi_unified_cmd_send(wmi_handle, buf, len, 5949 WMI_VDEV_INSTALL_KEY_CMDID); 5950 if (QDF_IS_STATUS_ERROR(status)) { 5951 qdf_mem_zero(wmi_buf_data(buf), len); 5952 wmi_buf_free(buf); 5953 } 5954 return status; 5955 } 5956 5957 /** 5958 * send_p2p_go_set_beacon_ie_cmd_tlv() - set beacon IE for p2p go 5959 * @wmi_handle: wmi handle 5960 * @vdev_id: vdev id 5961 * @p2p_ie: p2p IE 5962 * 5963 * Return: QDF_STATUS_SUCCESS for success or error code 5964 */ 5965 static QDF_STATUS send_p2p_go_set_beacon_ie_cmd_tlv(wmi_unified_t wmi_handle, 5966 uint32_t vdev_id, uint8_t *p2p_ie) 5967 { 5968 QDF_STATUS ret; 5969 wmi_p2p_go_set_beacon_ie_fixed_param *cmd; 5970 wmi_buf_t wmi_buf; 5971 uint32_t ie_len, ie_len_aligned, wmi_buf_len; 5972 uint8_t *buf_ptr; 5973 5974 ie_len = (uint32_t) (p2p_ie[1] + 2); 5975 5976 /* More than one P2P IE may be included in a single frame. 5977 If multiple P2P IEs are present, the complete P2P attribute 5978 data consists of the concatenation of the P2P Attribute 5979 fields of the P2P IEs. The P2P Attributes field of each 5980 P2P IE may be any length up to the maximum (251 octets). 5981 In this case host sends one P2P IE to firmware so the length 5982 should not exceed more than 251 bytes 5983 */ 5984 if (ie_len > 251) { 5985 wmi_err("Invalid p2p ie length %u", ie_len); 5986 return QDF_STATUS_E_INVAL; 5987 } 5988 5989 ie_len_aligned = roundup(ie_len, sizeof(uint32_t)); 5990 5991 wmi_buf_len = 5992 sizeof(wmi_p2p_go_set_beacon_ie_fixed_param) + ie_len_aligned + 5993 WMI_TLV_HDR_SIZE; 5994 5995 wmi_buf = wmi_buf_alloc(wmi_handle, wmi_buf_len); 5996 if (!wmi_buf) 5997 return QDF_STATUS_E_NOMEM; 5998 5999 buf_ptr = (uint8_t *) wmi_buf_data(wmi_buf); 6000 6001 cmd = (wmi_p2p_go_set_beacon_ie_fixed_param *) buf_ptr; 6002 WMITLV_SET_HDR(&cmd->tlv_header, 6003 WMITLV_TAG_STRUC_wmi_p2p_go_set_beacon_ie_fixed_param, 6004 WMITLV_GET_STRUCT_TLVLEN 6005 (wmi_p2p_go_set_beacon_ie_fixed_param)); 6006 cmd->vdev_id = vdev_id; 6007 cmd->ie_buf_len = ie_len; 6008 6009 buf_ptr += sizeof(wmi_p2p_go_set_beacon_ie_fixed_param); 6010 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, ie_len_aligned); 6011 buf_ptr += WMI_TLV_HDR_SIZE; 6012 qdf_mem_copy(buf_ptr, p2p_ie, ie_len); 6013 6014 wmi_debug("Sending WMI_P2P_GO_SET_BEACON_IE"); 6015 6016 wmi_mtrace(WMI_P2P_GO_SET_BEACON_IE, cmd->vdev_id, 0); 6017 ret = wmi_unified_cmd_send(wmi_handle, 6018 wmi_buf, wmi_buf_len, 6019 WMI_P2P_GO_SET_BEACON_IE); 6020 if (QDF_IS_STATUS_ERROR(ret)) { 6021 wmi_err("Failed to send bcn tmpl: %d", ret); 6022 wmi_buf_free(wmi_buf); 6023 } 6024 6025 wmi_debug("Successfully sent WMI_P2P_GO_SET_BEACON_IE"); 6026 return ret; 6027 } 6028 6029 /** 6030 * send_scan_probe_setoui_cmd_tlv() - set scan probe OUI 6031 * @wmi_handle: wmi handle 6032 * @psetoui: OUI parameters 6033 * 6034 * set scan probe OUI parameters in firmware 6035 * 6036 * Return: QDF status 6037 */ 6038 static QDF_STATUS send_scan_probe_setoui_cmd_tlv(wmi_unified_t wmi_handle, 6039 struct scan_mac_oui *psetoui) 6040 { 6041 wmi_scan_prob_req_oui_cmd_fixed_param *cmd; 6042 wmi_buf_t wmi_buf; 6043 uint32_t len; 6044 uint8_t *buf_ptr; 6045 uint32_t *oui_buf; 6046 struct probe_req_allowlist_attr *ie_allowlist = &psetoui->ie_allowlist; 6047 6048 len = sizeof(*cmd) + WMI_TLV_HDR_SIZE + 6049 ie_allowlist->num_vendor_oui * sizeof(wmi_vendor_oui); 6050 6051 wmi_buf = wmi_buf_alloc(wmi_handle, len); 6052 if (!wmi_buf) 6053 return QDF_STATUS_E_NOMEM; 6054 6055 buf_ptr = (uint8_t *) wmi_buf_data(wmi_buf); 6056 cmd = (wmi_scan_prob_req_oui_cmd_fixed_param *) buf_ptr; 6057 WMITLV_SET_HDR(&cmd->tlv_header, 6058 WMITLV_TAG_STRUC_wmi_scan_prob_req_oui_cmd_fixed_param, 6059 WMITLV_GET_STRUCT_TLVLEN 6060 (wmi_scan_prob_req_oui_cmd_fixed_param)); 6061 6062 oui_buf = &cmd->prob_req_oui; 6063 qdf_mem_zero(oui_buf, sizeof(cmd->prob_req_oui)); 6064 *oui_buf = psetoui->oui[0] << 16 | psetoui->oui[1] << 8 6065 | psetoui->oui[2]; 6066 wmi_debug("wmi:oui received from hdd %08x", cmd->prob_req_oui); 6067 6068 cmd->vdev_id = psetoui->vdev_id; 6069 cmd->flags = WMI_SCAN_PROBE_OUI_SPOOFED_MAC_IN_PROBE_REQ; 6070 if (psetoui->enb_probe_req_sno_randomization) 6071 cmd->flags |= WMI_SCAN_PROBE_OUI_RANDOM_SEQ_NO_IN_PROBE_REQ; 6072 6073 if (ie_allowlist->allow_list) { 6074 wmi_fill_ie_allowlist_attrs(cmd->ie_bitmap, 6075 &cmd->num_vendor_oui, 6076 ie_allowlist); 6077 cmd->flags |= 6078 WMI_SCAN_PROBE_OUI_ENABLE_IE_WHITELIST_IN_PROBE_REQ; 6079 } 6080 6081 buf_ptr += sizeof(*cmd); 6082 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 6083 ie_allowlist->num_vendor_oui * sizeof(wmi_vendor_oui)); 6084 buf_ptr += WMI_TLV_HDR_SIZE; 6085 6086 if (cmd->num_vendor_oui != 0) { 6087 wmi_fill_vendor_oui(buf_ptr, cmd->num_vendor_oui, 6088 ie_allowlist->voui); 6089 buf_ptr += cmd->num_vendor_oui * sizeof(wmi_vendor_oui); 6090 } 6091 6092 wmi_mtrace(WMI_SCAN_PROB_REQ_OUI_CMDID, cmd->vdev_id, 0); 6093 if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len, 6094 WMI_SCAN_PROB_REQ_OUI_CMDID)) { 6095 wmi_err("Failed to send command WMI_SCAN_PROB_REQ_OUI_CMDID"); 6096 wmi_buf_free(wmi_buf); 6097 return QDF_STATUS_E_FAILURE; 6098 } 6099 return QDF_STATUS_SUCCESS; 6100 } 6101 6102 #ifdef IPA_OFFLOAD 6103 /** send_ipa_offload_control_cmd_tlv() - ipa offload control parameter 6104 * @wmi_handle: wmi handle 6105 * @ipa_offload: ipa offload control parameter 6106 * 6107 * Returns: 0 on success, error number otherwise 6108 */ 6109 static QDF_STATUS send_ipa_offload_control_cmd_tlv(wmi_unified_t wmi_handle, 6110 struct ipa_uc_offload_control_params *ipa_offload) 6111 { 6112 wmi_ipa_offload_enable_disable_cmd_fixed_param *cmd; 6113 wmi_buf_t wmi_buf; 6114 uint32_t len; 6115 u_int8_t *buf_ptr; 6116 6117 len = sizeof(*cmd); 6118 wmi_buf = wmi_buf_alloc(wmi_handle, len); 6119 if (!wmi_buf) 6120 return QDF_STATUS_E_NOMEM; 6121 6122 wmi_debug("offload_type=%d, enable=%d", 6123 ipa_offload->offload_type, ipa_offload->enable); 6124 6125 buf_ptr = (u_int8_t *)wmi_buf_data(wmi_buf); 6126 6127 cmd = (wmi_ipa_offload_enable_disable_cmd_fixed_param *)buf_ptr; 6128 WMITLV_SET_HDR(&cmd->tlv_header, 6129 WMITLV_TAG_STRUCT_wmi_ipa_offload_enable_disable_cmd_fixed_param, 6130 WMITLV_GET_STRUCT_TLVLEN( 6131 wmi_ipa_offload_enable_disable_cmd_fixed_param)); 6132 6133 cmd->offload_type = ipa_offload->offload_type; 6134 cmd->vdev_id = ipa_offload->vdev_id; 6135 cmd->enable = ipa_offload->enable; 6136 6137 wmi_mtrace(WMI_IPA_OFFLOAD_ENABLE_DISABLE_CMDID, cmd->vdev_id, 0); 6138 if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len, 6139 WMI_IPA_OFFLOAD_ENABLE_DISABLE_CMDID)) { 6140 wmi_err("Failed to send WMI_IPA_OFFLOAD_ENABLE_DISABLE_CMDID"); 6141 wmi_buf_free(wmi_buf); 6142 return QDF_STATUS_E_FAILURE; 6143 } 6144 6145 return QDF_STATUS_SUCCESS; 6146 } 6147 #endif 6148 6149 /** 6150 * send_pno_stop_cmd_tlv() - PNO stop request 6151 * @wmi_handle: wmi handle 6152 * @vdev_id: vdev id 6153 * 6154 * This function request FW to stop ongoing PNO operation. 6155 * 6156 * Return: QDF status 6157 */ 6158 static QDF_STATUS send_pno_stop_cmd_tlv(wmi_unified_t wmi_handle, uint8_t vdev_id) 6159 { 6160 wmi_nlo_config_cmd_fixed_param *cmd; 6161 int32_t len = sizeof(*cmd); 6162 wmi_buf_t buf; 6163 uint8_t *buf_ptr; 6164 int ret; 6165 6166 /* 6167 * TLV place holder for array of structures nlo_configured_parameters 6168 * TLV place holder for array of uint32_t channel_list 6169 * TLV place holder for chnl prediction cfg 6170 */ 6171 len += WMI_TLV_HDR_SIZE + WMI_TLV_HDR_SIZE + WMI_TLV_HDR_SIZE; 6172 buf = wmi_buf_alloc(wmi_handle, len); 6173 if (!buf) 6174 return QDF_STATUS_E_NOMEM; 6175 6176 cmd = (wmi_nlo_config_cmd_fixed_param *) wmi_buf_data(buf); 6177 buf_ptr = (uint8_t *) cmd; 6178 6179 WMITLV_SET_HDR(&cmd->tlv_header, 6180 WMITLV_TAG_STRUC_wmi_nlo_config_cmd_fixed_param, 6181 WMITLV_GET_STRUCT_TLVLEN 6182 (wmi_nlo_config_cmd_fixed_param)); 6183 6184 cmd->vdev_id = vdev_id; 6185 cmd->flags = WMI_NLO_CONFIG_STOP; 6186 buf_ptr += sizeof(*cmd); 6187 6188 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0); 6189 buf_ptr += WMI_TLV_HDR_SIZE; 6190 6191 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, 0); 6192 buf_ptr += WMI_TLV_HDR_SIZE; 6193 6194 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0); 6195 buf_ptr += WMI_TLV_HDR_SIZE; 6196 6197 wmi_mtrace(WMI_NETWORK_LIST_OFFLOAD_CONFIG_CMDID, cmd->vdev_id, 0); 6198 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 6199 WMI_NETWORK_LIST_OFFLOAD_CONFIG_CMDID); 6200 if (ret) { 6201 wmi_err("Failed to send nlo wmi cmd"); 6202 wmi_buf_free(buf); 6203 return QDF_STATUS_E_FAILURE; 6204 } 6205 6206 return QDF_STATUS_SUCCESS; 6207 } 6208 6209 /** 6210 * send_obss_disable_cmd_tlv() - disable obss scan request 6211 * @wmi_handle: wmi handle 6212 * @vdev_id: vdev id 6213 * 6214 * This function request FW to disable ongoing obss scan operation. 6215 * 6216 * Return: QDF status 6217 */ 6218 static QDF_STATUS send_obss_disable_cmd_tlv(wmi_unified_t wmi_handle, 6219 uint8_t vdev_id) 6220 { 6221 QDF_STATUS status; 6222 wmi_buf_t buf; 6223 wmi_obss_scan_disable_cmd_fixed_param *cmd; 6224 int len = sizeof(*cmd); 6225 6226 buf = wmi_buf_alloc(wmi_handle, len); 6227 if (!buf) 6228 return QDF_STATUS_E_NOMEM; 6229 6230 wmi_debug("cmd %x vdev_id %d", WMI_OBSS_SCAN_DISABLE_CMDID, vdev_id); 6231 6232 cmd = (wmi_obss_scan_disable_cmd_fixed_param *)wmi_buf_data(buf); 6233 WMITLV_SET_HDR(&cmd->tlv_header, 6234 WMITLV_TAG_STRUC_wmi_obss_scan_disable_cmd_fixed_param, 6235 WMITLV_GET_STRUCT_TLVLEN( 6236 wmi_obss_scan_disable_cmd_fixed_param)); 6237 6238 cmd->vdev_id = vdev_id; 6239 status = wmi_unified_cmd_send(wmi_handle, buf, len, 6240 WMI_OBSS_SCAN_DISABLE_CMDID); 6241 if (QDF_IS_STATUS_ERROR(status)) 6242 wmi_buf_free(buf); 6243 6244 return status; 6245 } 6246 6247 /** 6248 * wmi_set_pno_channel_prediction() - Set PNO channel prediction 6249 * @buf_ptr: Buffer passed by upper layers 6250 * @pno: Buffer to be sent to the firmware 6251 * 6252 * Copy the PNO Channel prediction configuration parameters 6253 * passed by the upper layers to a WMI format TLV and send it 6254 * down to the firmware. 6255 * 6256 * Return: None 6257 */ 6258 static void wmi_set_pno_channel_prediction(uint8_t *buf_ptr, 6259 struct pno_scan_req_params *pno) 6260 { 6261 nlo_channel_prediction_cfg *channel_prediction_cfg = 6262 (nlo_channel_prediction_cfg *) buf_ptr; 6263 WMITLV_SET_HDR(&channel_prediction_cfg->tlv_header, 6264 WMITLV_TAG_ARRAY_BYTE, 6265 WMITLV_GET_STRUCT_TLVLEN(nlo_channel_prediction_cfg)); 6266 #ifdef FEATURE_WLAN_SCAN_PNO 6267 channel_prediction_cfg->enable = pno->pno_channel_prediction; 6268 channel_prediction_cfg->top_k_num = pno->top_k_num_of_channels; 6269 channel_prediction_cfg->stationary_threshold = pno->stationary_thresh; 6270 channel_prediction_cfg->full_scan_period_ms = 6271 pno->channel_prediction_full_scan; 6272 #endif 6273 buf_ptr += sizeof(nlo_channel_prediction_cfg); 6274 wmi_debug("enable: %d, top_k_num: %d, stat_thresh: %d, full_scan: %d", 6275 channel_prediction_cfg->enable, 6276 channel_prediction_cfg->top_k_num, 6277 channel_prediction_cfg->stationary_threshold, 6278 channel_prediction_cfg->full_scan_period_ms); 6279 } 6280 6281 /** 6282 * send_cp_stats_cmd_tlv() - Send cp stats wmi command 6283 * @wmi_handle: wmi handle 6284 * @buf_ptr: Buffer passed by upper layers 6285 * @buf_len: Length of passed buffer by upper layer 6286 * 6287 * Copy the buffer passed by the upper layers and send it 6288 * down to the firmware. 6289 * 6290 * Return: None 6291 */ 6292 static QDF_STATUS send_cp_stats_cmd_tlv(wmi_unified_t wmi_handle, 6293 void *buf_ptr, uint32_t buf_len) 6294 { 6295 wmi_buf_t buf = NULL; 6296 QDF_STATUS status; 6297 int len; 6298 uint8_t *data_ptr; 6299 6300 len = buf_len; 6301 buf = wmi_buf_alloc(wmi_handle, len); 6302 if (!buf) 6303 return QDF_STATUS_E_NOMEM; 6304 6305 data_ptr = (uint8_t *)wmi_buf_data(buf); 6306 qdf_mem_copy(data_ptr, buf_ptr, len); 6307 6308 wmi_mtrace(WMI_REQUEST_CTRL_PATH_STATS_CMDID, NO_SESSION, 0); 6309 status = wmi_unified_cmd_send(wmi_handle, buf, 6310 len, WMI_REQUEST_CTRL_PATH_STATS_CMDID); 6311 6312 if (QDF_IS_STATUS_ERROR(status)) { 6313 wmi_buf_free(buf); 6314 return QDF_STATUS_E_FAILURE; 6315 } 6316 return QDF_STATUS_SUCCESS; 6317 } 6318 6319 /** 6320 * send_halphy_stats_cmd_tlv() - Send halphy stats wmi command 6321 * @wmi_handle: wmi handle 6322 * @buf_ptr: Buffer passed by upper layers 6323 * @buf_len: Length of passed buffer by upper layer 6324 * 6325 * Copy the buffer passed by the upper layers and send it 6326 * down to the firmware. 6327 * 6328 * Return: None 6329 */ 6330 static QDF_STATUS send_halphy_stats_cmd_tlv(wmi_unified_t wmi_handle, 6331 void *buf_ptr, uint32_t buf_len) 6332 { 6333 wmi_buf_t buf = NULL; 6334 QDF_STATUS status; 6335 int len; 6336 uint8_t *data_ptr; 6337 6338 len = buf_len; 6339 buf = wmi_buf_alloc(wmi_handle, len); 6340 if (!buf) 6341 return QDF_STATUS_E_NOMEM; 6342 6343 data_ptr = (uint8_t *)wmi_buf_data(buf); 6344 qdf_mem_copy(data_ptr, buf_ptr, len); 6345 6346 wmi_mtrace(WMI_REQUEST_HALPHY_CTRL_PATH_STATS_CMDID, NO_SESSION, 0); 6347 status = wmi_unified_cmd_send(wmi_handle, buf, 6348 len, 6349 WMI_REQUEST_HALPHY_CTRL_PATH_STATS_CMDID); 6350 6351 if (QDF_IS_STATUS_ERROR(status)) { 6352 wmi_buf_free(buf); 6353 return QDF_STATUS_E_FAILURE; 6354 } 6355 return QDF_STATUS_SUCCESS; 6356 } 6357 6358 /** 6359 * extract_cp_stats_more_pending_tlv - api to extract more flag from event data 6360 * @wmi_handle: wmi handle 6361 * @evt_buf: event buffer 6362 * @more_flag: buffer to populate more flag 6363 * 6364 * Return: status of operation 6365 */ 6366 static QDF_STATUS 6367 extract_cp_stats_more_pending_tlv(wmi_unified_t wmi_handle, void *evt_buf, 6368 uint32_t *more_flag) 6369 { 6370 WMI_CTRL_PATH_STATS_EVENTID_param_tlvs *param_buf; 6371 wmi_ctrl_path_stats_event_fixed_param *ev; 6372 6373 param_buf = (WMI_CTRL_PATH_STATS_EVENTID_param_tlvs *)evt_buf; 6374 if (!param_buf) { 6375 wmi_err_rl("param_buf is NULL"); 6376 return QDF_STATUS_E_FAILURE; 6377 } 6378 ev = (wmi_ctrl_path_stats_event_fixed_param *)param_buf->fixed_param; 6379 6380 *more_flag = ev->more; 6381 return QDF_STATUS_SUCCESS; 6382 } 6383 6384 /** 6385 * extract_halphy_stats_end_of_event_tlv - api to extract end_of_event flag 6386 * from event data 6387 * @wmi_handle: wmi handle 6388 * @evt_buf: event buffer 6389 * @end_of_event_flag: buffer to populate end_of_event flag 6390 * 6391 * Return: status of operation 6392 */ 6393 static QDF_STATUS 6394 extract_halphy_stats_end_of_event_tlv(wmi_unified_t wmi_handle, void *evt_buf, 6395 uint32_t *end_of_event_flag) 6396 { 6397 WMI_HALPHY_CTRL_PATH_STATS_EVENTID_param_tlvs *param_buf; 6398 wmi_halphy_ctrl_path_stats_event_fixed_param *ev; 6399 6400 param_buf = (WMI_HALPHY_CTRL_PATH_STATS_EVENTID_param_tlvs *)evt_buf; 6401 if (!param_buf) { 6402 wmi_err_rl("param_buf is NULL"); 6403 return QDF_STATUS_E_FAILURE; 6404 } 6405 ev = (wmi_halphy_ctrl_path_stats_event_fixed_param *) 6406 param_buf->fixed_param; 6407 6408 *end_of_event_flag = ev->end_of_event; 6409 return QDF_STATUS_SUCCESS; 6410 } 6411 6412 /** 6413 * extract_halphy_stats_event_count_tlv() - api to extract event count flag 6414 * from event data 6415 * @wmi_handle: wmi handle 6416 * @evt_buf: event buffer 6417 * @event_count_flag: buffer to populate event_count flag 6418 * 6419 * Return: status of operation 6420 */ 6421 static QDF_STATUS 6422 extract_halphy_stats_event_count_tlv(wmi_unified_t wmi_handle, void *evt_buf, 6423 uint32_t *event_count_flag) 6424 { 6425 WMI_HALPHY_CTRL_PATH_STATS_EVENTID_param_tlvs *param_buf; 6426 wmi_halphy_ctrl_path_stats_event_fixed_param *ev; 6427 6428 param_buf = (WMI_HALPHY_CTRL_PATH_STATS_EVENTID_param_tlvs *)evt_buf; 6429 if (!param_buf) { 6430 wmi_err_rl("param_buf is NULL"); 6431 return QDF_STATUS_E_FAILURE; 6432 } 6433 ev = (wmi_halphy_ctrl_path_stats_event_fixed_param *) 6434 param_buf->fixed_param; 6435 6436 *event_count_flag = ev->event_count; 6437 return QDF_STATUS_SUCCESS; 6438 } 6439 6440 /** 6441 * send_nlo_mawc_cmd_tlv() - Send MAWC NLO configuration 6442 * @wmi_handle: wmi handle 6443 * @params: configuration parameters 6444 * 6445 * Return: QDF_STATUS 6446 */ 6447 static QDF_STATUS send_nlo_mawc_cmd_tlv(wmi_unified_t wmi_handle, 6448 struct nlo_mawc_params *params) 6449 { 6450 wmi_buf_t buf = NULL; 6451 QDF_STATUS status; 6452 int len; 6453 uint8_t *buf_ptr; 6454 wmi_nlo_configure_mawc_cmd_fixed_param *wmi_nlo_mawc_params; 6455 6456 len = sizeof(*wmi_nlo_mawc_params); 6457 buf = wmi_buf_alloc(wmi_handle, len); 6458 if (!buf) 6459 return QDF_STATUS_E_NOMEM; 6460 6461 buf_ptr = (uint8_t *) wmi_buf_data(buf); 6462 wmi_nlo_mawc_params = 6463 (wmi_nlo_configure_mawc_cmd_fixed_param *) buf_ptr; 6464 WMITLV_SET_HDR(&wmi_nlo_mawc_params->tlv_header, 6465 WMITLV_TAG_STRUC_wmi_nlo_configure_mawc_cmd_fixed_param, 6466 WMITLV_GET_STRUCT_TLVLEN 6467 (wmi_nlo_configure_mawc_cmd_fixed_param)); 6468 wmi_nlo_mawc_params->vdev_id = params->vdev_id; 6469 if (params->enable) 6470 wmi_nlo_mawc_params->enable = 1; 6471 else 6472 wmi_nlo_mawc_params->enable = 0; 6473 wmi_nlo_mawc_params->exp_backoff_ratio = params->exp_backoff_ratio; 6474 wmi_nlo_mawc_params->init_scan_interval = params->init_scan_interval; 6475 wmi_nlo_mawc_params->max_scan_interval = params->max_scan_interval; 6476 wmi_debug("MAWC NLO en=%d, vdev=%d, ratio=%d, SCAN init=%d, max=%d", 6477 wmi_nlo_mawc_params->enable, wmi_nlo_mawc_params->vdev_id, 6478 wmi_nlo_mawc_params->exp_backoff_ratio, 6479 wmi_nlo_mawc_params->init_scan_interval, 6480 wmi_nlo_mawc_params->max_scan_interval); 6481 6482 wmi_mtrace(WMI_NLO_CONFIGURE_MAWC_CMDID, NO_SESSION, 0); 6483 status = wmi_unified_cmd_send(wmi_handle, buf, 6484 len, WMI_NLO_CONFIGURE_MAWC_CMDID); 6485 if (QDF_IS_STATUS_ERROR(status)) { 6486 wmi_err("WMI_NLO_CONFIGURE_MAWC_CMDID failed, Error %d", 6487 status); 6488 wmi_buf_free(buf); 6489 return QDF_STATUS_E_FAILURE; 6490 } 6491 6492 return QDF_STATUS_SUCCESS; 6493 } 6494 6495 /** 6496 * wmi_dump_pno_scan_freq_list() - dump frequency list associated with pno 6497 * scan 6498 * @scan_freq_list: frequency list for pno scan 6499 * 6500 * Return: void 6501 */ 6502 static void wmi_dump_pno_scan_freq_list(struct chan_list *scan_freq_list) 6503 { 6504 uint32_t i; 6505 uint8_t info[WMI_MAX_CHAN_INFO_LOG]; 6506 uint32_t len = 0; 6507 struct chan_info *chan_info; 6508 int ret; 6509 6510 wmi_debug("[PNO_SCAN] Total freq %d", scan_freq_list->num_chan); 6511 for (i = 0; i < scan_freq_list->num_chan; i++) { 6512 chan_info = &scan_freq_list->chan[i]; 6513 ret = qdf_scnprintf(info + len, sizeof(info) - len, 6514 " %d[%d]", chan_info->freq, 6515 chan_info->flags); 6516 if (ret <= 0) 6517 break; 6518 len += ret; 6519 if (len >= (sizeof(info) - 20)) { 6520 wmi_nofl_debug("Freq[flag]:%s", 6521 info); 6522 len = 0; 6523 } 6524 } 6525 if (len) 6526 wmi_nofl_debug("Freq[flag]:%s", info); 6527 } 6528 6529 /** 6530 * send_pno_start_cmd_tlv() - PNO start request 6531 * @wmi_handle: wmi handle 6532 * @pno: PNO request 6533 * 6534 * This function request FW to start PNO request. 6535 * Request: QDF status 6536 */ 6537 static QDF_STATUS send_pno_start_cmd_tlv(wmi_unified_t wmi_handle, 6538 struct pno_scan_req_params *pno) 6539 { 6540 wmi_nlo_config_cmd_fixed_param *cmd; 6541 nlo_configured_parameters *nlo_list; 6542 uint32_t *channel_list; 6543 int32_t len; 6544 qdf_freq_t freq; 6545 wmi_buf_t buf; 6546 uint8_t *buf_ptr; 6547 uint8_t i; 6548 int ret; 6549 struct probe_req_allowlist_attr *ie_allowlist = &pno->ie_allowlist; 6550 connected_nlo_rssi_params *nlo_relative_rssi; 6551 connected_nlo_bss_band_rssi_pref *nlo_band_rssi; 6552 6553 /* 6554 * TLV place holder for array nlo_configured_parameters(nlo_list) 6555 * TLV place holder for array of uint32_t channel_list 6556 * TLV place holder for chnnl prediction cfg 6557 * TLV place holder for array of wmi_vendor_oui 6558 * TLV place holder for array of connected_nlo_bss_band_rssi_pref 6559 */ 6560 len = sizeof(*cmd) + 6561 WMI_TLV_HDR_SIZE + WMI_TLV_HDR_SIZE + WMI_TLV_HDR_SIZE + 6562 WMI_TLV_HDR_SIZE + WMI_TLV_HDR_SIZE; 6563 6564 len += sizeof(uint32_t) * pno->networks_list[0].pno_chan_list.num_chan; 6565 len += sizeof(nlo_configured_parameters) * 6566 QDF_MIN(pno->networks_cnt, WMI_NLO_MAX_SSIDS); 6567 len += sizeof(nlo_channel_prediction_cfg); 6568 len += sizeof(enlo_candidate_score_params); 6569 len += sizeof(wmi_vendor_oui) * ie_allowlist->num_vendor_oui; 6570 len += sizeof(connected_nlo_rssi_params); 6571 len += sizeof(connected_nlo_bss_band_rssi_pref); 6572 6573 buf = wmi_buf_alloc(wmi_handle, len); 6574 if (!buf) 6575 return QDF_STATUS_E_NOMEM; 6576 6577 cmd = (wmi_nlo_config_cmd_fixed_param *) wmi_buf_data(buf); 6578 6579 buf_ptr = (uint8_t *) cmd; 6580 WMITLV_SET_HDR(&cmd->tlv_header, 6581 WMITLV_TAG_STRUC_wmi_nlo_config_cmd_fixed_param, 6582 WMITLV_GET_STRUCT_TLVLEN 6583 (wmi_nlo_config_cmd_fixed_param)); 6584 cmd->vdev_id = pno->vdev_id; 6585 cmd->flags = WMI_NLO_CONFIG_START | WMI_NLO_CONFIG_SSID_HIDE_EN; 6586 6587 #ifdef FEATURE_WLAN_SCAN_PNO 6588 WMI_SCAN_SET_DWELL_MODE(cmd->flags, 6589 pno->adaptive_dwell_mode); 6590 #endif 6591 /* Current FW does not support min-max range for dwell time */ 6592 cmd->active_dwell_time = pno->active_dwell_time; 6593 cmd->passive_dwell_time = pno->passive_dwell_time; 6594 6595 if (pno->do_passive_scan) 6596 cmd->flags |= WMI_NLO_CONFIG_SCAN_PASSIVE; 6597 /* Copy scan interval */ 6598 cmd->fast_scan_period = pno->fast_scan_period; 6599 cmd->slow_scan_period = pno->slow_scan_period; 6600 cmd->delay_start_time = WMI_SEC_TO_MSEC(pno->delay_start_time); 6601 cmd->fast_scan_max_cycles = pno->fast_scan_max_cycles; 6602 cmd->scan_backoff_multiplier = pno->scan_backoff_multiplier; 6603 6604 /* mac randomization attributes */ 6605 if (pno->scan_random.randomize) { 6606 cmd->flags |= WMI_NLO_CONFIG_SPOOFED_MAC_IN_PROBE_REQ | 6607 WMI_NLO_CONFIG_RANDOM_SEQ_NO_IN_PROBE_REQ; 6608 wmi_copy_scan_random_mac(pno->scan_random.mac_addr, 6609 pno->scan_random.mac_mask, 6610 &cmd->mac_addr, 6611 &cmd->mac_mask); 6612 } 6613 6614 buf_ptr += sizeof(wmi_nlo_config_cmd_fixed_param); 6615 6616 cmd->no_of_ssids = QDF_MIN(pno->networks_cnt, WMI_NLO_MAX_SSIDS); 6617 6618 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 6619 cmd->no_of_ssids * sizeof(nlo_configured_parameters)); 6620 buf_ptr += WMI_TLV_HDR_SIZE; 6621 6622 nlo_list = (nlo_configured_parameters *) buf_ptr; 6623 for (i = 0; i < cmd->no_of_ssids; i++) { 6624 WMITLV_SET_HDR(&nlo_list[i].tlv_header, 6625 WMITLV_TAG_ARRAY_BYTE, 6626 WMITLV_GET_STRUCT_TLVLEN 6627 (nlo_configured_parameters)); 6628 /* Copy ssid and it's length */ 6629 nlo_list[i].ssid.valid = true; 6630 nlo_list[i].ssid.ssid.ssid_len = 6631 pno->networks_list[i].ssid.length; 6632 qdf_mem_copy(nlo_list[i].ssid.ssid.ssid, 6633 pno->networks_list[i].ssid.ssid, 6634 nlo_list[i].ssid.ssid.ssid_len); 6635 6636 /* Copy rssi threshold */ 6637 if (pno->networks_list[i].rssi_thresh && 6638 pno->networks_list[i].rssi_thresh > 6639 WMI_RSSI_THOLD_DEFAULT) { 6640 nlo_list[i].rssi_cond.valid = true; 6641 nlo_list[i].rssi_cond.rssi = 6642 pno->networks_list[i].rssi_thresh; 6643 } 6644 nlo_list[i].bcast_nw_type.valid = true; 6645 nlo_list[i].bcast_nw_type.bcast_nw_type = 6646 pno->networks_list[i].bc_new_type; 6647 } 6648 buf_ptr += cmd->no_of_ssids * sizeof(nlo_configured_parameters); 6649 6650 /* Copy channel info */ 6651 cmd->num_of_channels = pno->networks_list[0].pno_chan_list.num_chan; 6652 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, 6653 (cmd->num_of_channels * sizeof(uint32_t))); 6654 buf_ptr += WMI_TLV_HDR_SIZE; 6655 6656 channel_list = (uint32_t *) buf_ptr; 6657 for (i = 0; i < cmd->num_of_channels; i++) { 6658 TARGET_SET_FREQ_IN_CHAN_LIST_TLV(channel_list[i], 6659 pno->networks_list[0].pno_chan_list.chan[i].freq); 6660 6661 if (channel_list[i] < WMI_NLO_FREQ_THRESH) { 6662 freq = pno->networks_list[0].pno_chan_list.chan[i].freq; 6663 TARGET_SET_FREQ_IN_CHAN_LIST_TLV(channel_list[i], 6664 wlan_chan_to_freq(freq)); 6665 } 6666 6667 TARGET_SET_FLAGS_IN_CHAN_LIST_TLV(channel_list[i], 6668 pno->networks_list[0].pno_chan_list.chan[i].flags); 6669 } 6670 6671 wmi_dump_pno_scan_freq_list(&pno->networks_list[0].pno_chan_list); 6672 6673 buf_ptr += cmd->num_of_channels * sizeof(uint32_t); 6674 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 6675 sizeof(nlo_channel_prediction_cfg)); 6676 buf_ptr += WMI_TLV_HDR_SIZE; 6677 wmi_set_pno_channel_prediction(buf_ptr, pno); 6678 buf_ptr += sizeof(nlo_channel_prediction_cfg); 6679 /** TODO: Discrete firmware doesn't have command/option to configure 6680 * App IE which comes from wpa_supplicant as of part PNO start request. 6681 */ 6682 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_STRUC_enlo_candidate_score_param, 6683 WMITLV_GET_STRUCT_TLVLEN(enlo_candidate_score_params)); 6684 buf_ptr += sizeof(enlo_candidate_score_params); 6685 6686 if (ie_allowlist->allow_list) { 6687 cmd->flags |= WMI_NLO_CONFIG_ENABLE_IE_WHITELIST_IN_PROBE_REQ; 6688 wmi_fill_ie_allowlist_attrs(cmd->ie_bitmap, 6689 &cmd->num_vendor_oui, 6690 ie_allowlist); 6691 } 6692 6693 /* ie allow list */ 6694 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 6695 ie_allowlist->num_vendor_oui * sizeof(wmi_vendor_oui)); 6696 buf_ptr += WMI_TLV_HDR_SIZE; 6697 if (cmd->num_vendor_oui != 0) { 6698 wmi_fill_vendor_oui(buf_ptr, cmd->num_vendor_oui, 6699 ie_allowlist->voui); 6700 buf_ptr += cmd->num_vendor_oui * sizeof(wmi_vendor_oui); 6701 } 6702 6703 if (pno->relative_rssi_set) 6704 cmd->flags |= WMI_NLO_CONFIG_ENABLE_CNLO_RSSI_CONFIG; 6705 6706 /* 6707 * Firmware calculation using connected PNO params: 6708 * New AP's RSSI >= (Connected AP's RSSI + relative_rssi +/- rssi_pref) 6709 * deduction of rssi_pref for chosen band_pref and 6710 * addition of rssi_pref for remaining bands (other than chosen band). 6711 */ 6712 nlo_relative_rssi = (connected_nlo_rssi_params *) buf_ptr; 6713 WMITLV_SET_HDR(&nlo_relative_rssi->tlv_header, 6714 WMITLV_TAG_STRUC_wmi_connected_nlo_rssi_params, 6715 WMITLV_GET_STRUCT_TLVLEN(connected_nlo_rssi_params)); 6716 nlo_relative_rssi->relative_rssi = pno->relative_rssi; 6717 buf_ptr += sizeof(*nlo_relative_rssi); 6718 6719 /* 6720 * As of now Kernel and Host supports one band and rssi preference. 6721 * Firmware supports array of band and rssi preferences 6722 */ 6723 cmd->num_cnlo_band_pref = 1; 6724 WMITLV_SET_HDR(buf_ptr, 6725 WMITLV_TAG_ARRAY_STRUC, 6726 cmd->num_cnlo_band_pref * 6727 sizeof(connected_nlo_bss_band_rssi_pref)); 6728 buf_ptr += WMI_TLV_HDR_SIZE; 6729 6730 nlo_band_rssi = (connected_nlo_bss_band_rssi_pref *) buf_ptr; 6731 for (i = 0; i < cmd->num_cnlo_band_pref; i++) { 6732 WMITLV_SET_HDR(&nlo_band_rssi[i].tlv_header, 6733 WMITLV_TAG_STRUC_wmi_connected_nlo_bss_band_rssi_pref, 6734 WMITLV_GET_STRUCT_TLVLEN( 6735 connected_nlo_bss_band_rssi_pref)); 6736 nlo_band_rssi[i].band = pno->band_rssi_pref.band; 6737 nlo_band_rssi[i].rssi_pref = pno->band_rssi_pref.rssi; 6738 } 6739 buf_ptr += cmd->num_cnlo_band_pref * sizeof(*nlo_band_rssi); 6740 6741 wmi_mtrace(WMI_NETWORK_LIST_OFFLOAD_CONFIG_CMDID, cmd->vdev_id, 0); 6742 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 6743 WMI_NETWORK_LIST_OFFLOAD_CONFIG_CMDID); 6744 if (ret) { 6745 wmi_err("Failed to send nlo wmi cmd"); 6746 wmi_buf_free(buf); 6747 return QDF_STATUS_E_FAILURE; 6748 } 6749 6750 return QDF_STATUS_SUCCESS; 6751 } 6752 6753 /** 6754 * is_service_enabled_tlv() - Check if service enabled 6755 * @wmi_handle: wmi handle 6756 * @service_id: service identifier 6757 * 6758 * Return: 1 enabled, 0 disabled 6759 */ 6760 static bool is_service_enabled_tlv(wmi_unified_t wmi_handle, 6761 uint32_t service_id) 6762 { 6763 struct wmi_soc *soc = wmi_handle->soc; 6764 6765 if (!soc->wmi_service_bitmap) { 6766 wmi_err("WMI service bit map is not saved yet"); 6767 return false; 6768 } 6769 6770 /* if wmi_service_enabled was received with extended2 bitmap, 6771 * use WMI_SERVICE_EXT2_IS_ENABLED to check the services. 6772 */ 6773 if (soc->wmi_ext2_service_bitmap) { 6774 if (!soc->wmi_ext_service_bitmap) { 6775 wmi_err("WMI service ext bit map is not saved yet"); 6776 return false; 6777 } 6778 6779 return WMI_SERVICE_EXT2_IS_ENABLED(soc->wmi_service_bitmap, 6780 soc->wmi_ext_service_bitmap, 6781 soc->wmi_ext2_service_bitmap, 6782 service_id); 6783 } 6784 6785 if (service_id >= WMI_MAX_EXT_SERVICE) { 6786 wmi_err_rl("Service id %d but WMI ext2 service bitmap is NULL", 6787 service_id); 6788 return false; 6789 } 6790 /* if wmi_service_enabled was received with extended bitmap, 6791 * use WMI_SERVICE_EXT_IS_ENABLED to check the services. 6792 */ 6793 if (soc->wmi_ext_service_bitmap) 6794 return WMI_SERVICE_EXT_IS_ENABLED(soc->wmi_service_bitmap, 6795 soc->wmi_ext_service_bitmap, 6796 service_id); 6797 6798 if (service_id >= WMI_MAX_SERVICE) { 6799 wmi_err("Service id %d but WMI ext service bitmap is NULL", 6800 service_id); 6801 return false; 6802 } 6803 6804 return WMI_SERVICE_IS_ENABLED(soc->wmi_service_bitmap, 6805 service_id); 6806 } 6807 6808 #ifdef WLAN_FEATURE_LINK_LAYER_STATS 6809 /** 6810 * send_process_ll_stats_clear_cmd_tlv() - clear link layer stats 6811 * @wmi_handle: wmi handle 6812 * @clear_req: ll stats clear request command params 6813 * 6814 * Return: QDF_STATUS_SUCCESS for success or error code 6815 */ 6816 static QDF_STATUS send_process_ll_stats_clear_cmd_tlv(wmi_unified_t wmi_handle, 6817 const struct ll_stats_clear_params *clear_req) 6818 { 6819 wmi_clear_link_stats_cmd_fixed_param *cmd; 6820 int32_t len; 6821 wmi_buf_t buf; 6822 uint8_t *buf_ptr; 6823 int ret; 6824 6825 len = sizeof(*cmd); 6826 buf = wmi_buf_alloc(wmi_handle, len); 6827 6828 if (!buf) 6829 return QDF_STATUS_E_NOMEM; 6830 6831 buf_ptr = (uint8_t *) wmi_buf_data(buf); 6832 qdf_mem_zero(buf_ptr, len); 6833 cmd = (wmi_clear_link_stats_cmd_fixed_param *) buf_ptr; 6834 6835 WMITLV_SET_HDR(&cmd->tlv_header, 6836 WMITLV_TAG_STRUC_wmi_clear_link_stats_cmd_fixed_param, 6837 WMITLV_GET_STRUCT_TLVLEN 6838 (wmi_clear_link_stats_cmd_fixed_param)); 6839 6840 cmd->stop_stats_collection_req = clear_req->stop_req; 6841 cmd->vdev_id = clear_req->vdev_id; 6842 cmd->stats_clear_req_mask = clear_req->stats_clear_mask; 6843 6844 WMI_CHAR_ARRAY_TO_MAC_ADDR(clear_req->peer_macaddr.bytes, 6845 &cmd->peer_macaddr); 6846 6847 wmi_debug("LINK_LAYER_STATS - Clear Request Params"); 6848 wmi_debug("StopReq: %d Vdev Id: %d Clear Stat Mask: %d" 6849 " Peer MAC Addr: "QDF_MAC_ADDR_FMT, 6850 cmd->stop_stats_collection_req, 6851 cmd->vdev_id, cmd->stats_clear_req_mask, 6852 QDF_MAC_ADDR_REF(clear_req->peer_macaddr.bytes)); 6853 6854 wmi_mtrace(WMI_CLEAR_LINK_STATS_CMDID, cmd->vdev_id, 0); 6855 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 6856 WMI_CLEAR_LINK_STATS_CMDID); 6857 if (ret) { 6858 wmi_err("Failed to send clear link stats req"); 6859 wmi_buf_free(buf); 6860 return QDF_STATUS_E_FAILURE; 6861 } 6862 6863 wmi_debug("Clear Link Layer Stats request sent successfully"); 6864 return QDF_STATUS_SUCCESS; 6865 } 6866 6867 /** 6868 * send_process_ll_stats_set_cmd_tlv() - link layer stats set request 6869 * @wmi_handle: wmi handle 6870 * @set_req: ll stats set request command params 6871 * 6872 * Return: QDF_STATUS_SUCCESS for success or error code 6873 */ 6874 static QDF_STATUS send_process_ll_stats_set_cmd_tlv(wmi_unified_t wmi_handle, 6875 const struct ll_stats_set_params *set_req) 6876 { 6877 wmi_start_link_stats_cmd_fixed_param *cmd; 6878 int32_t len; 6879 wmi_buf_t buf; 6880 uint8_t *buf_ptr; 6881 int ret; 6882 6883 len = sizeof(*cmd); 6884 buf = wmi_buf_alloc(wmi_handle, len); 6885 6886 if (!buf) 6887 return QDF_STATUS_E_NOMEM; 6888 6889 buf_ptr = (uint8_t *) wmi_buf_data(buf); 6890 qdf_mem_zero(buf_ptr, len); 6891 cmd = (wmi_start_link_stats_cmd_fixed_param *) buf_ptr; 6892 6893 WMITLV_SET_HDR(&cmd->tlv_header, 6894 WMITLV_TAG_STRUC_wmi_start_link_stats_cmd_fixed_param, 6895 WMITLV_GET_STRUCT_TLVLEN 6896 (wmi_start_link_stats_cmd_fixed_param)); 6897 6898 cmd->mpdu_size_threshold = set_req->mpdu_size_threshold; 6899 cmd->aggressive_statistics_gathering = 6900 set_req->aggressive_statistics_gathering; 6901 6902 wmi_debug("LINK_LAYER_STATS - Start/Set Params MPDU Size Thresh : %d Aggressive Gather: %d", 6903 cmd->mpdu_size_threshold, 6904 cmd->aggressive_statistics_gathering); 6905 6906 wmi_mtrace(WMI_START_LINK_STATS_CMDID, NO_SESSION, 0); 6907 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 6908 WMI_START_LINK_STATS_CMDID); 6909 if (ret) { 6910 wmi_err("Failed to send set link stats request"); 6911 wmi_buf_free(buf); 6912 return QDF_STATUS_E_FAILURE; 6913 } 6914 6915 return QDF_STATUS_SUCCESS; 6916 } 6917 6918 /** 6919 * send_process_ll_stats_get_cmd_tlv() - link layer stats get request 6920 * @wmi_handle: wmi handle 6921 * @get_req: ll stats get request command params 6922 * 6923 * Return: QDF_STATUS_SUCCESS for success or error code 6924 */ 6925 static QDF_STATUS send_process_ll_stats_get_cmd_tlv(wmi_unified_t wmi_handle, 6926 const struct ll_stats_get_params *get_req) 6927 { 6928 wmi_request_link_stats_cmd_fixed_param *cmd; 6929 int32_t len; 6930 wmi_buf_t buf; 6931 uint8_t *buf_ptr; 6932 int ret; 6933 bool is_link_stats_over_qmi; 6934 6935 len = sizeof(*cmd); 6936 buf = wmi_buf_alloc(wmi_handle, len); 6937 6938 if (!buf) 6939 return QDF_STATUS_E_NOMEM; 6940 6941 buf_ptr = (uint8_t *) wmi_buf_data(buf); 6942 qdf_mem_zero(buf_ptr, len); 6943 cmd = (wmi_request_link_stats_cmd_fixed_param *) buf_ptr; 6944 6945 WMITLV_SET_HDR(&cmd->tlv_header, 6946 WMITLV_TAG_STRUC_wmi_request_link_stats_cmd_fixed_param, 6947 WMITLV_GET_STRUCT_TLVLEN 6948 (wmi_request_link_stats_cmd_fixed_param)); 6949 6950 cmd->request_id = get_req->req_id; 6951 cmd->stats_type = get_req->param_id_mask; 6952 cmd->vdev_id = get_req->vdev_id; 6953 6954 WMI_CHAR_ARRAY_TO_MAC_ADDR(get_req->peer_macaddr.bytes, 6955 &cmd->peer_macaddr); 6956 6957 wmi_debug("LINK_LAYER_STATS - Get Request Params Request ID: %u Stats Type: %0x Vdev ID: %d Peer MAC Addr: "QDF_MAC_ADDR_FMT, 6958 cmd->request_id, cmd->stats_type, cmd->vdev_id, 6959 QDF_MAC_ADDR_REF(get_req->peer_macaddr.bytes)); 6960 6961 wmi_mtrace(WMI_REQUEST_LINK_STATS_CMDID, cmd->vdev_id, 0); 6962 is_link_stats_over_qmi = is_service_enabled_tlv( 6963 wmi_handle, 6964 WMI_SERVICE_UNIFIED_LL_GET_STA_OVER_QMI_SUPPORT); 6965 6966 if (is_link_stats_over_qmi) { 6967 ret = wmi_unified_cmd_send_over_qmi( 6968 wmi_handle, buf, len, 6969 WMI_REQUEST_LINK_STATS_CMDID); 6970 } else { 6971 ret = wmi_unified_cmd_send_pm_chk( 6972 wmi_handle, buf, len, 6973 WMI_REQUEST_LINK_STATS_CMDID, true); 6974 } 6975 6976 if (ret) { 6977 wmi_buf_free(buf); 6978 return QDF_STATUS_E_FAILURE; 6979 } 6980 6981 return QDF_STATUS_SUCCESS; 6982 } 6983 6984 #ifdef FEATURE_CLUB_LL_STATS_AND_GET_STATION 6985 #ifdef WLAN_FEATURE_11BE_MLO 6986 static int 6987 wmi_get_tlv_length_for_mlo_stats(const struct ll_stats_get_params *get_req) 6988 { 6989 int32_t len = 0; 6990 6991 /* In case of MLO connection, update the length of the buffer. 6992 * The wmi_inst_rssi_stats_params structure is not needed for MLO stats, 6993 * hence just update the TLV header, but allocate no memory for it. 6994 */ 6995 if (!get_req->is_mlo_req) 6996 return len; 6997 6998 len += WMI_TLV_HDR_SIZE + 0 * sizeof(wmi_inst_rssi_stats_params) + 6999 WMI_TLV_HDR_SIZE + 1 * sizeof(uint32_t) + 7000 WMI_TLV_HDR_SIZE + 1 * sizeof(wmi_mac_addr); 7001 7002 return len; 7003 } 7004 7005 static void 7006 wmi_update_tlv_headers_for_mlo_stats(const struct ll_stats_get_params *get_req, 7007 void *buf_ptr) 7008 { 7009 wmi_request_unified_ll_get_sta_cmd_fixed_param *unified_cmd; 7010 uint32_t *vdev_id_bitmap; 7011 wmi_mac_addr *mld_mac; 7012 7013 /* In case of MLO connection, update the TLV Headers */ 7014 if (!get_req->is_mlo_req) 7015 return; 7016 7017 buf_ptr += sizeof(*unified_cmd); 7018 7019 /* Fill TLV but no data for wmi_inst_rssi_stats_params */ 7020 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0); 7021 buf_ptr += WMI_TLV_HDR_SIZE; 7022 7023 /* Adding vdev_bitmap_id array TLV */ 7024 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, 7025 sizeof(*vdev_id_bitmap)); 7026 buf_ptr += WMI_TLV_HDR_SIZE; 7027 vdev_id_bitmap = buf_ptr; 7028 *(vdev_id_bitmap) = get_req->vdev_id_bitmap; 7029 buf_ptr += sizeof(*vdev_id_bitmap); 7030 7031 /* Adding mld_macaddr array TLV */ 7032 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_FIXED_STRUC, 7033 sizeof(*mld_mac)); 7034 buf_ptr += WMI_TLV_HDR_SIZE; 7035 mld_mac = buf_ptr; 7036 WMI_CHAR_ARRAY_TO_MAC_ADDR(get_req->mld_macaddr.bytes, mld_mac); 7037 7038 wmi_debug("MLO vdev_id_bitmap: 0x%x MLD MAC Addr: " 7039 QDF_MAC_ADDR_FMT, get_req->vdev_id_bitmap, 7040 QDF_MAC_ADDR_REF(get_req->mld_macaddr.bytes)); 7041 } 7042 #else 7043 static inline int 7044 wmi_get_tlv_length_for_mlo_stats(const struct ll_stats_get_params *get_req) 7045 { 7046 return 0; 7047 } 7048 7049 static inline void 7050 wmi_update_tlv_headers_for_mlo_stats(const struct ll_stats_get_params *get_req, 7051 void *buf_ptr) 7052 { 7053 } 7054 #endif 7055 7056 /** 7057 * send_unified_ll_stats_get_sta_cmd_tlv() - unified link layer stats and get 7058 * station request 7059 * @wmi_handle: wmi handle 7060 * @get_req: ll stats get request command params 7061 * 7062 * Return: QDF_STATUS_SUCCESS for success or error code 7063 */ 7064 static QDF_STATUS send_unified_ll_stats_get_sta_cmd_tlv( 7065 wmi_unified_t wmi_handle, 7066 const struct ll_stats_get_params *get_req) 7067 { 7068 wmi_request_unified_ll_get_sta_cmd_fixed_param *unified_cmd; 7069 int32_t len; 7070 wmi_buf_t buf; 7071 void *buf_ptr; 7072 QDF_STATUS ret; 7073 bool is_ll_get_sta_stats_over_qmi; 7074 7075 len = sizeof(*unified_cmd); 7076 len += wmi_get_tlv_length_for_mlo_stats(get_req); 7077 7078 buf = wmi_buf_alloc(wmi_handle, len); 7079 if (!buf) 7080 return QDF_STATUS_E_NOMEM; 7081 7082 buf_ptr = wmi_buf_data(buf); 7083 7084 unified_cmd = buf_ptr; 7085 WMITLV_SET_HDR( 7086 &unified_cmd->tlv_header, 7087 WMITLV_TAG_STRUC_wmi_request_unified_ll_get_sta_cmd_fixed_param, 7088 WMITLV_GET_STRUCT_TLVLEN 7089 (wmi_request_unified_ll_get_sta_cmd_fixed_param)); 7090 7091 unified_cmd->link_stats_type = get_req->param_id_mask; 7092 unified_cmd->get_sta_stats_id = (WMI_REQUEST_AP_STAT | 7093 WMI_REQUEST_PEER_STAT | 7094 WMI_REQUEST_VDEV_STAT | 7095 WMI_REQUEST_PDEV_STAT | 7096 WMI_REQUEST_VDEV_EXTD_STAT | 7097 WMI_REQUEST_PEER_EXTD2_STAT | 7098 WMI_REQUEST_RSSI_PER_CHAIN_STAT); 7099 unified_cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 7100 wmi_handle, 7101 WMI_HOST_PDEV_ID_SOC); 7102 7103 unified_cmd->vdev_id = get_req->vdev_id; 7104 unified_cmd->request_id = get_req->req_id; 7105 WMI_CHAR_ARRAY_TO_MAC_ADDR(get_req->peer_macaddr.bytes, 7106 &unified_cmd->peer_macaddr); 7107 7108 wmi_debug("UNIFIED_LINK_STATS_GET_STA - Get Request Params Request ID: %u Stats Type: %0x Vdev ID: %d Peer MAC Addr: " 7109 QDF_MAC_ADDR_FMT, 7110 get_req->req_id, get_req->param_id_mask, get_req->vdev_id, 7111 QDF_MAC_ADDR_REF(get_req->peer_macaddr.bytes)); 7112 7113 wmi_update_tlv_headers_for_mlo_stats(get_req, buf_ptr); 7114 wmi_mtrace(WMI_REQUEST_UNIFIED_LL_GET_STA_CMDID, get_req->vdev_id, 0); 7115 7116 /** 7117 * FW support for LL_get_sta command. True represents the unified 7118 * ll_get_sta command should be sent over QMI always irrespective of 7119 * WOW state. 7120 */ 7121 is_ll_get_sta_stats_over_qmi = is_service_enabled_tlv( 7122 wmi_handle, 7123 WMI_SERVICE_UNIFIED_LL_GET_STA_OVER_QMI_SUPPORT); 7124 7125 if (is_ll_get_sta_stats_over_qmi) { 7126 ret = wmi_unified_cmd_send_over_qmi( 7127 wmi_handle, buf, len, 7128 WMI_REQUEST_UNIFIED_LL_GET_STA_CMDID); 7129 } else { 7130 ret = wmi_unified_cmd_send_pm_chk( 7131 wmi_handle, buf, len, 7132 WMI_REQUEST_UNIFIED_LL_GET_STA_CMDID, 7133 true); 7134 } 7135 7136 if (QDF_IS_STATUS_ERROR(ret)) { 7137 wmi_buf_free(buf); 7138 return QDF_STATUS_E_FAILURE; 7139 } 7140 7141 return ret; 7142 } 7143 #endif 7144 #endif /* WLAN_FEATURE_LINK_LAYER_STATS */ 7145 7146 /** 7147 * send_congestion_cmd_tlv() - send request to fw to get CCA 7148 * @wmi_handle: wmi handle 7149 * @vdev_id: vdev id 7150 * 7151 * Return: QDF status 7152 */ 7153 static QDF_STATUS send_congestion_cmd_tlv(wmi_unified_t wmi_handle, 7154 uint8_t vdev_id) 7155 { 7156 wmi_buf_t buf; 7157 wmi_request_stats_cmd_fixed_param *cmd; 7158 uint8_t len; 7159 uint8_t *buf_ptr; 7160 7161 len = sizeof(*cmd); 7162 buf = wmi_buf_alloc(wmi_handle, len); 7163 if (!buf) 7164 return QDF_STATUS_E_FAILURE; 7165 7166 buf_ptr = wmi_buf_data(buf); 7167 cmd = (wmi_request_stats_cmd_fixed_param *)buf_ptr; 7168 WMITLV_SET_HDR(&cmd->tlv_header, 7169 WMITLV_TAG_STRUC_wmi_request_stats_cmd_fixed_param, 7170 WMITLV_GET_STRUCT_TLVLEN 7171 (wmi_request_stats_cmd_fixed_param)); 7172 7173 cmd->stats_id = WMI_REQUEST_CONGESTION_STAT; 7174 cmd->vdev_id = vdev_id; 7175 wmi_debug("STATS REQ VDEV_ID:%d stats_id %d -->", 7176 cmd->vdev_id, cmd->stats_id); 7177 7178 wmi_mtrace(WMI_REQUEST_STATS_CMDID, cmd->vdev_id, 0); 7179 if (wmi_unified_cmd_send(wmi_handle, buf, len, 7180 WMI_REQUEST_STATS_CMDID)) { 7181 wmi_err("Failed to send WMI_REQUEST_STATS_CMDID"); 7182 wmi_buf_free(buf); 7183 return QDF_STATUS_E_FAILURE; 7184 } 7185 7186 return QDF_STATUS_SUCCESS; 7187 } 7188 7189 /** 7190 * send_snr_request_cmd_tlv() - send request to fw to get RSSI stats 7191 * @wmi_handle: wmi handle 7192 * 7193 * Return: QDF status 7194 */ 7195 static QDF_STATUS send_snr_request_cmd_tlv(wmi_unified_t wmi_handle) 7196 { 7197 wmi_buf_t buf; 7198 wmi_request_stats_cmd_fixed_param *cmd; 7199 uint8_t len = sizeof(wmi_request_stats_cmd_fixed_param); 7200 7201 buf = wmi_buf_alloc(wmi_handle, len); 7202 if (!buf) 7203 return QDF_STATUS_E_FAILURE; 7204 7205 cmd = (wmi_request_stats_cmd_fixed_param *) wmi_buf_data(buf); 7206 WMITLV_SET_HDR(&cmd->tlv_header, 7207 WMITLV_TAG_STRUC_wmi_request_stats_cmd_fixed_param, 7208 WMITLV_GET_STRUCT_TLVLEN 7209 (wmi_request_stats_cmd_fixed_param)); 7210 cmd->stats_id = WMI_REQUEST_VDEV_STAT; 7211 wmi_mtrace(WMI_REQUEST_STATS_CMDID, cmd->vdev_id, 0); 7212 if (wmi_unified_cmd_send(wmi_handle, buf, len, 7213 WMI_REQUEST_STATS_CMDID)) { 7214 wmi_err("Failed to send host stats request to fw"); 7215 wmi_buf_free(buf); 7216 return QDF_STATUS_E_FAILURE; 7217 } 7218 7219 return QDF_STATUS_SUCCESS; 7220 } 7221 7222 /** 7223 * send_snr_cmd_tlv() - get RSSI from fw 7224 * @wmi_handle: wmi handle 7225 * @vdev_id: vdev id 7226 * 7227 * Return: QDF status 7228 */ 7229 static QDF_STATUS send_snr_cmd_tlv(wmi_unified_t wmi_handle, uint8_t vdev_id) 7230 { 7231 wmi_buf_t buf; 7232 wmi_request_stats_cmd_fixed_param *cmd; 7233 uint8_t len = sizeof(wmi_request_stats_cmd_fixed_param); 7234 7235 buf = wmi_buf_alloc(wmi_handle, len); 7236 if (!buf) 7237 return QDF_STATUS_E_FAILURE; 7238 7239 cmd = (wmi_request_stats_cmd_fixed_param *) wmi_buf_data(buf); 7240 cmd->vdev_id = vdev_id; 7241 7242 WMITLV_SET_HDR(&cmd->tlv_header, 7243 WMITLV_TAG_STRUC_wmi_request_stats_cmd_fixed_param, 7244 WMITLV_GET_STRUCT_TLVLEN 7245 (wmi_request_stats_cmd_fixed_param)); 7246 cmd->stats_id = WMI_REQUEST_VDEV_STAT; 7247 wmi_mtrace(WMI_REQUEST_STATS_CMDID, cmd->vdev_id, 0); 7248 if (wmi_unified_cmd_send(wmi_handle, buf, len, 7249 WMI_REQUEST_STATS_CMDID)) { 7250 wmi_err("Failed to send host stats request to fw"); 7251 wmi_buf_free(buf); 7252 return QDF_STATUS_E_FAILURE; 7253 } 7254 7255 return QDF_STATUS_SUCCESS; 7256 } 7257 7258 /** 7259 * send_link_status_req_cmd_tlv() - process link status request from UMAC 7260 * @wmi_handle: wmi handle 7261 * @link_status: get link params 7262 * 7263 * Return: QDF status 7264 */ 7265 static QDF_STATUS send_link_status_req_cmd_tlv(wmi_unified_t wmi_handle, 7266 struct link_status_params *link_status) 7267 { 7268 wmi_buf_t buf; 7269 wmi_request_stats_cmd_fixed_param *cmd; 7270 uint8_t len = sizeof(wmi_request_stats_cmd_fixed_param); 7271 7272 buf = wmi_buf_alloc(wmi_handle, len); 7273 if (!buf) 7274 return QDF_STATUS_E_FAILURE; 7275 7276 cmd = (wmi_request_stats_cmd_fixed_param *) wmi_buf_data(buf); 7277 WMITLV_SET_HDR(&cmd->tlv_header, 7278 WMITLV_TAG_STRUC_wmi_request_stats_cmd_fixed_param, 7279 WMITLV_GET_STRUCT_TLVLEN 7280 (wmi_request_stats_cmd_fixed_param)); 7281 cmd->stats_id = WMI_REQUEST_VDEV_RATE_STAT; 7282 cmd->vdev_id = link_status->vdev_id; 7283 wmi_mtrace(WMI_REQUEST_STATS_CMDID, cmd->vdev_id, 0); 7284 if (wmi_unified_cmd_send(wmi_handle, buf, len, 7285 WMI_REQUEST_STATS_CMDID)) { 7286 wmi_err("Failed to send WMI link status request to fw"); 7287 wmi_buf_free(buf); 7288 return QDF_STATUS_E_FAILURE; 7289 } 7290 7291 return QDF_STATUS_SUCCESS; 7292 } 7293 7294 #ifdef WLAN_SUPPORT_GREEN_AP 7295 /** 7296 * send_egap_conf_params_cmd_tlv() - send wmi cmd of egap configuration params 7297 * @wmi_handle: wmi handler 7298 * @egap_params: pointer to egap_params 7299 * 7300 * Return: 0 for success, otherwise appropriate error code 7301 */ 7302 static QDF_STATUS send_egap_conf_params_cmd_tlv(wmi_unified_t wmi_handle, 7303 struct wlan_green_ap_egap_params *egap_params) 7304 { 7305 wmi_ap_ps_egap_param_cmd_fixed_param *cmd; 7306 wmi_buf_t buf; 7307 int32_t err; 7308 7309 buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd)); 7310 if (!buf) 7311 return QDF_STATUS_E_NOMEM; 7312 7313 cmd = (wmi_ap_ps_egap_param_cmd_fixed_param *) wmi_buf_data(buf); 7314 WMITLV_SET_HDR(&cmd->tlv_header, 7315 WMITLV_TAG_STRUC_wmi_ap_ps_egap_param_cmd_fixed_param, 7316 WMITLV_GET_STRUCT_TLVLEN( 7317 wmi_ap_ps_egap_param_cmd_fixed_param)); 7318 7319 cmd->enable = egap_params->host_enable_egap; 7320 cmd->inactivity_time = egap_params->egap_inactivity_time; 7321 cmd->wait_time = egap_params->egap_wait_time; 7322 cmd->flags = egap_params->egap_feature_flags; 7323 wmi_mtrace(WMI_AP_PS_EGAP_PARAM_CMDID, NO_SESSION, 0); 7324 err = wmi_unified_cmd_send(wmi_handle, buf, 7325 sizeof(*cmd), WMI_AP_PS_EGAP_PARAM_CMDID); 7326 if (err) { 7327 wmi_err("Failed to send ap_ps_egap cmd"); 7328 wmi_buf_free(buf); 7329 return QDF_STATUS_E_FAILURE; 7330 } 7331 7332 return QDF_STATUS_SUCCESS; 7333 } 7334 #endif 7335 7336 /** 7337 * send_csa_offload_enable_cmd_tlv() - send CSA offload enable command 7338 * @wmi_handle: wmi handle 7339 * @vdev_id: vdev id 7340 * 7341 * Return: QDF_STATUS_SUCCESS for success or error code 7342 */ 7343 static QDF_STATUS send_csa_offload_enable_cmd_tlv(wmi_unified_t wmi_handle, 7344 uint8_t vdev_id) 7345 { 7346 wmi_csa_offload_enable_cmd_fixed_param *cmd; 7347 wmi_buf_t buf; 7348 int32_t len = sizeof(*cmd); 7349 7350 wmi_debug("vdev_id %d", vdev_id); 7351 buf = wmi_buf_alloc(wmi_handle, len); 7352 if (!buf) 7353 return QDF_STATUS_E_NOMEM; 7354 7355 cmd = (wmi_csa_offload_enable_cmd_fixed_param *) wmi_buf_data(buf); 7356 WMITLV_SET_HDR(&cmd->tlv_header, 7357 WMITLV_TAG_STRUC_wmi_csa_offload_enable_cmd_fixed_param, 7358 WMITLV_GET_STRUCT_TLVLEN 7359 (wmi_csa_offload_enable_cmd_fixed_param)); 7360 cmd->vdev_id = vdev_id; 7361 cmd->csa_offload_enable = WMI_CSA_OFFLOAD_ENABLE; 7362 wmi_mtrace(WMI_CSA_OFFLOAD_ENABLE_CMDID, cmd->vdev_id, 0); 7363 if (wmi_unified_cmd_send(wmi_handle, buf, len, 7364 WMI_CSA_OFFLOAD_ENABLE_CMDID)) { 7365 wmi_err("Failed to send CSA offload enable command"); 7366 wmi_buf_free(buf); 7367 return QDF_STATUS_E_FAILURE; 7368 } 7369 7370 return 0; 7371 } 7372 7373 #ifdef WLAN_FEATURE_CIF_CFR 7374 /** 7375 * send_oem_dma_cfg_cmd_tlv() - configure OEM DMA rings 7376 * @wmi_handle: wmi handle 7377 * @cfg: dma cfg req 7378 * 7379 * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure 7380 */ 7381 static QDF_STATUS send_oem_dma_cfg_cmd_tlv(wmi_unified_t wmi_handle, 7382 wmi_oem_dma_ring_cfg_req_fixed_param *cfg) 7383 { 7384 wmi_buf_t buf; 7385 uint8_t *cmd; 7386 QDF_STATUS ret; 7387 7388 WMITLV_SET_HDR(cfg, 7389 WMITLV_TAG_STRUC_wmi_oem_dma_ring_cfg_req_fixed_param, 7390 (sizeof(*cfg) - WMI_TLV_HDR_SIZE)); 7391 7392 buf = wmi_buf_alloc(wmi_handle, sizeof(*cfg)); 7393 if (!buf) 7394 return QDF_STATUS_E_FAILURE; 7395 7396 cmd = (uint8_t *) wmi_buf_data(buf); 7397 qdf_mem_copy(cmd, cfg, sizeof(*cfg)); 7398 wmi_debug("Sending OEM Data Request to target, data len %lu", 7399 sizeof(*cfg)); 7400 wmi_mtrace(WMI_OEM_DMA_RING_CFG_REQ_CMDID, NO_SESSION, 0); 7401 ret = wmi_unified_cmd_send(wmi_handle, buf, sizeof(*cfg), 7402 WMI_OEM_DMA_RING_CFG_REQ_CMDID); 7403 if (QDF_IS_STATUS_ERROR(ret)) { 7404 wmi_err("Failed to send WMI_OEM_DMA_RING_CFG_REQ_CMDID"); 7405 wmi_buf_free(buf); 7406 } 7407 7408 return ret; 7409 } 7410 #endif 7411 7412 /** 7413 * send_start_11d_scan_cmd_tlv() - start 11d scan request 7414 * @wmi_handle: wmi handle 7415 * @start_11d_scan: 11d scan start request parameters 7416 * 7417 * This function request FW to start 11d scan. 7418 * 7419 * Return: QDF status 7420 */ 7421 static QDF_STATUS send_start_11d_scan_cmd_tlv(wmi_unified_t wmi_handle, 7422 struct reg_start_11d_scan_req *start_11d_scan) 7423 { 7424 wmi_11d_scan_start_cmd_fixed_param *cmd; 7425 int32_t len; 7426 wmi_buf_t buf; 7427 int ret; 7428 7429 len = sizeof(*cmd); 7430 buf = wmi_buf_alloc(wmi_handle, len); 7431 if (!buf) 7432 return QDF_STATUS_E_NOMEM; 7433 7434 cmd = (wmi_11d_scan_start_cmd_fixed_param *)wmi_buf_data(buf); 7435 7436 WMITLV_SET_HDR(&cmd->tlv_header, 7437 WMITLV_TAG_STRUC_wmi_11d_scan_start_cmd_fixed_param, 7438 WMITLV_GET_STRUCT_TLVLEN 7439 (wmi_11d_scan_start_cmd_fixed_param)); 7440 7441 cmd->vdev_id = start_11d_scan->vdev_id; 7442 cmd->scan_period_msec = start_11d_scan->scan_period_msec; 7443 cmd->start_interval_msec = start_11d_scan->start_interval_msec; 7444 7445 wmi_debug("vdev %d sending 11D scan start req", cmd->vdev_id); 7446 7447 wmi_mtrace(WMI_11D_SCAN_START_CMDID, cmd->vdev_id, 0); 7448 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 7449 WMI_11D_SCAN_START_CMDID); 7450 if (ret) { 7451 wmi_err("Failed to send start 11d scan wmi cmd"); 7452 wmi_buf_free(buf); 7453 return QDF_STATUS_E_FAILURE; 7454 } 7455 7456 return QDF_STATUS_SUCCESS; 7457 } 7458 7459 /** 7460 * send_stop_11d_scan_cmd_tlv() - stop 11d scan request 7461 * @wmi_handle: wmi handle 7462 * @stop_11d_scan: 11d scan stop request parameters 7463 * 7464 * This function request FW to stop 11d scan. 7465 * 7466 * Return: QDF status 7467 */ 7468 static QDF_STATUS send_stop_11d_scan_cmd_tlv(wmi_unified_t wmi_handle, 7469 struct reg_stop_11d_scan_req *stop_11d_scan) 7470 { 7471 wmi_11d_scan_stop_cmd_fixed_param *cmd; 7472 int32_t len; 7473 wmi_buf_t buf; 7474 int ret; 7475 7476 len = sizeof(*cmd); 7477 buf = wmi_buf_alloc(wmi_handle, len); 7478 if (!buf) 7479 return QDF_STATUS_E_NOMEM; 7480 7481 cmd = (wmi_11d_scan_stop_cmd_fixed_param *)wmi_buf_data(buf); 7482 7483 WMITLV_SET_HDR(&cmd->tlv_header, 7484 WMITLV_TAG_STRUC_wmi_11d_scan_stop_cmd_fixed_param, 7485 WMITLV_GET_STRUCT_TLVLEN 7486 (wmi_11d_scan_stop_cmd_fixed_param)); 7487 7488 cmd->vdev_id = stop_11d_scan->vdev_id; 7489 7490 wmi_debug("vdev %d sending 11D scan stop req", cmd->vdev_id); 7491 7492 wmi_mtrace(WMI_11D_SCAN_STOP_CMDID, cmd->vdev_id, 0); 7493 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 7494 WMI_11D_SCAN_STOP_CMDID); 7495 if (ret) { 7496 wmi_err("Failed to send stop 11d scan wmi cmd"); 7497 wmi_buf_free(buf); 7498 return QDF_STATUS_E_FAILURE; 7499 } 7500 7501 return QDF_STATUS_SUCCESS; 7502 } 7503 7504 /** 7505 * send_start_oem_data_cmd_tlv() - start OEM data request to target 7506 * @wmi_handle: wmi handle 7507 * @data_len: the length of @data 7508 * @data: the pointer to data buf 7509 * 7510 * Return: QDF status 7511 */ 7512 static QDF_STATUS send_start_oem_data_cmd_tlv(wmi_unified_t wmi_handle, 7513 uint32_t data_len, 7514 uint8_t *data) 7515 { 7516 wmi_buf_t buf; 7517 uint8_t *cmd; 7518 QDF_STATUS ret; 7519 7520 buf = wmi_buf_alloc(wmi_handle, 7521 (data_len + WMI_TLV_HDR_SIZE)); 7522 if (!buf) 7523 return QDF_STATUS_E_FAILURE; 7524 7525 cmd = (uint8_t *) wmi_buf_data(buf); 7526 7527 WMITLV_SET_HDR(cmd, WMITLV_TAG_ARRAY_BYTE, data_len); 7528 cmd += WMI_TLV_HDR_SIZE; 7529 qdf_mem_copy(cmd, data, 7530 data_len); 7531 7532 wmi_debug("Sending OEM Data Request to target, data len %d", data_len); 7533 7534 wmi_mtrace(WMI_OEM_REQ_CMDID, NO_SESSION, 0); 7535 ret = wmi_unified_cmd_send(wmi_handle, buf, 7536 (data_len + 7537 WMI_TLV_HDR_SIZE), WMI_OEM_REQ_CMDID); 7538 7539 if (QDF_IS_STATUS_ERROR(ret)) { 7540 wmi_err("Failed to send WMI_OEM_REQ_CMDID"); 7541 wmi_buf_free(buf); 7542 } 7543 7544 return ret; 7545 } 7546 7547 #ifdef FEATURE_OEM_DATA 7548 /** 7549 * send_start_oemv2_data_cmd_tlv() - start OEM data to target 7550 * @wmi_handle: wmi handle 7551 * @oem_data: the pointer to oem data 7552 * 7553 * Return: QDF status 7554 */ 7555 static QDF_STATUS send_start_oemv2_data_cmd_tlv(wmi_unified_t wmi_handle, 7556 struct oem_data *oem_data) 7557 { 7558 QDF_STATUS ret; 7559 wmi_oem_data_cmd_fixed_param *cmd; 7560 struct wmi_ops *ops; 7561 wmi_buf_t buf; 7562 uint16_t len = sizeof(*cmd); 7563 uint16_t oem_data_len_aligned; 7564 uint8_t *buf_ptr; 7565 uint32_t pdev_id; 7566 7567 if (!oem_data || !oem_data->data) { 7568 wmi_err_rl("oem data is not valid"); 7569 return QDF_STATUS_E_FAILURE; 7570 } 7571 7572 oem_data_len_aligned = roundup(oem_data->data_len, sizeof(uint32_t)); 7573 if (oem_data_len_aligned < oem_data->data_len) { 7574 wmi_err_rl("integer overflow while rounding up data_len"); 7575 return QDF_STATUS_E_FAILURE; 7576 } 7577 7578 if (oem_data_len_aligned > WMI_SVC_MSG_MAX_SIZE - WMI_TLV_HDR_SIZE) { 7579 wmi_err_rl("wmi_max_msg_size overflow for given data_len"); 7580 return QDF_STATUS_E_FAILURE; 7581 } 7582 7583 len += WMI_TLV_HDR_SIZE + oem_data_len_aligned; 7584 buf = wmi_buf_alloc(wmi_handle, len); 7585 if (!buf) 7586 return QDF_STATUS_E_NOMEM; 7587 7588 buf_ptr = (uint8_t *)wmi_buf_data(buf); 7589 cmd = (wmi_oem_data_cmd_fixed_param *)buf_ptr; 7590 WMITLV_SET_HDR(&cmd->tlv_header, 7591 WMITLV_TAG_STRUC_wmi_oem_data_cmd_fixed_param, 7592 WMITLV_GET_STRUCT_TLVLEN(wmi_oem_data_cmd_fixed_param)); 7593 7594 pdev_id = oem_data->pdev_id; 7595 if (oem_data->pdev_vdev_flag) { 7596 ops = wmi_handle->ops; 7597 if (oem_data->is_host_pdev_id) 7598 pdev_id = 7599 ops->convert_host_pdev_id_to_target(wmi_handle, 7600 pdev_id); 7601 else 7602 pdev_id = 7603 ops->convert_pdev_id_host_to_target(wmi_handle, 7604 pdev_id); 7605 } 7606 7607 cmd->vdev_id = oem_data->vdev_id; 7608 cmd->data_len = oem_data->data_len; 7609 cmd->pdev_vdev_flag = oem_data->pdev_vdev_flag; 7610 cmd->pdev_id = pdev_id; 7611 7612 buf_ptr += sizeof(*cmd); 7613 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, oem_data_len_aligned); 7614 buf_ptr += WMI_TLV_HDR_SIZE; 7615 qdf_mem_copy(buf_ptr, oem_data->data, oem_data->data_len); 7616 7617 wmi_mtrace(WMI_OEM_DATA_CMDID, NO_SESSION, 0); 7618 ret = wmi_unified_cmd_send(wmi_handle, buf, len, WMI_OEM_DATA_CMDID); 7619 if (QDF_IS_STATUS_ERROR(ret)) { 7620 wmi_err_rl("Failed with ret = %d", ret); 7621 wmi_buf_free(buf); 7622 } 7623 7624 return ret; 7625 } 7626 #endif 7627 7628 /** 7629 * send_dfs_phyerr_filter_offload_en_cmd_tlv() - enable dfs phyerr filter 7630 * @wmi_handle: wmi handle 7631 * @dfs_phyerr_filter_offload: is dfs phyerr filter offload 7632 * 7633 * Send WMI_DFS_PHYERR_FILTER_ENA_CMDID or 7634 * WMI_DFS_PHYERR_FILTER_DIS_CMDID command 7635 * to firmware based on phyerr filtering 7636 * offload status. 7637 * 7638 * Return: 1 success, 0 failure 7639 */ 7640 static QDF_STATUS 7641 send_dfs_phyerr_filter_offload_en_cmd_tlv(wmi_unified_t wmi_handle, 7642 bool dfs_phyerr_filter_offload) 7643 { 7644 wmi_dfs_phyerr_filter_ena_cmd_fixed_param *enable_phyerr_offload_cmd; 7645 wmi_dfs_phyerr_filter_dis_cmd_fixed_param *disable_phyerr_offload_cmd; 7646 wmi_buf_t buf; 7647 uint16_t len; 7648 QDF_STATUS ret; 7649 7650 7651 if (false == dfs_phyerr_filter_offload) { 7652 wmi_debug("Phyerror Filtering offload is Disabled in ini"); 7653 len = sizeof(*disable_phyerr_offload_cmd); 7654 buf = wmi_buf_alloc(wmi_handle, len); 7655 if (!buf) 7656 return 0; 7657 7658 disable_phyerr_offload_cmd = 7659 (wmi_dfs_phyerr_filter_dis_cmd_fixed_param *) 7660 wmi_buf_data(buf); 7661 7662 WMITLV_SET_HDR(&disable_phyerr_offload_cmd->tlv_header, 7663 WMITLV_TAG_STRUC_wmi_dfs_phyerr_filter_dis_cmd_fixed_param, 7664 WMITLV_GET_STRUCT_TLVLEN 7665 (wmi_dfs_phyerr_filter_dis_cmd_fixed_param)); 7666 7667 /* 7668 * Send WMI_DFS_PHYERR_FILTER_DIS_CMDID 7669 * to the firmware to disable the phyerror 7670 * filtering offload. 7671 */ 7672 wmi_mtrace(WMI_DFS_PHYERR_FILTER_DIS_CMDID, NO_SESSION, 0); 7673 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 7674 WMI_DFS_PHYERR_FILTER_DIS_CMDID); 7675 if (QDF_IS_STATUS_ERROR(ret)) { 7676 wmi_err("Failed to send WMI_DFS_PHYERR_FILTER_DIS_CMDID ret=%d", 7677 ret); 7678 wmi_buf_free(buf); 7679 return QDF_STATUS_E_FAILURE; 7680 } 7681 wmi_debug("WMI_DFS_PHYERR_FILTER_DIS_CMDID Send Success"); 7682 } else { 7683 wmi_debug("Phyerror Filtering offload is Enabled in ini"); 7684 7685 len = sizeof(*enable_phyerr_offload_cmd); 7686 buf = wmi_buf_alloc(wmi_handle, len); 7687 if (!buf) 7688 return QDF_STATUS_E_FAILURE; 7689 7690 enable_phyerr_offload_cmd = 7691 (wmi_dfs_phyerr_filter_ena_cmd_fixed_param *) 7692 wmi_buf_data(buf); 7693 7694 WMITLV_SET_HDR(&enable_phyerr_offload_cmd->tlv_header, 7695 WMITLV_TAG_STRUC_wmi_dfs_phyerr_filter_ena_cmd_fixed_param, 7696 WMITLV_GET_STRUCT_TLVLEN 7697 (wmi_dfs_phyerr_filter_ena_cmd_fixed_param)); 7698 7699 /* 7700 * Send a WMI_DFS_PHYERR_FILTER_ENA_CMDID 7701 * to the firmware to enable the phyerror 7702 * filtering offload. 7703 */ 7704 wmi_mtrace(WMI_DFS_PHYERR_FILTER_ENA_CMDID, NO_SESSION, 0); 7705 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 7706 WMI_DFS_PHYERR_FILTER_ENA_CMDID); 7707 7708 if (QDF_IS_STATUS_ERROR(ret)) { 7709 wmi_err("Failed to send DFS PHYERR CMD ret=%d", ret); 7710 wmi_buf_free(buf); 7711 return QDF_STATUS_E_FAILURE; 7712 } 7713 wmi_debug("WMI_DFS_PHYERR_FILTER_ENA_CMDID Send Success"); 7714 } 7715 7716 return QDF_STATUS_SUCCESS; 7717 } 7718 7719 #if !defined(REMOVE_PKT_LOG) && defined(FEATURE_PKTLOG) 7720 /** 7721 * send_pktlog_wmi_send_cmd_tlv() - send pktlog enable/disable command to target 7722 * @wmi_handle: wmi handle 7723 * @pktlog_event: pktlog event 7724 * @cmd_id: pktlog cmd id 7725 * @user_triggered: user triggered input for PKTLOG enable mode 7726 * 7727 * Return: QDF status 7728 */ 7729 static QDF_STATUS send_pktlog_wmi_send_cmd_tlv(wmi_unified_t wmi_handle, 7730 WMI_PKTLOG_EVENT pktlog_event, 7731 WMI_CMD_ID cmd_id, uint8_t user_triggered) 7732 { 7733 WMI_PKTLOG_EVENT PKTLOG_EVENT; 7734 WMI_CMD_ID CMD_ID; 7735 wmi_pdev_pktlog_enable_cmd_fixed_param *cmd; 7736 wmi_pdev_pktlog_disable_cmd_fixed_param *disable_cmd; 7737 int len = 0; 7738 wmi_buf_t buf; 7739 int32_t idx, max_idx; 7740 7741 PKTLOG_EVENT = pktlog_event; 7742 CMD_ID = cmd_id; 7743 7744 max_idx = sizeof(pktlog_event_tlv) / (sizeof(pktlog_event_tlv[0])); 7745 switch (CMD_ID) { 7746 case WMI_PDEV_PKTLOG_ENABLE_CMDID: 7747 len = sizeof(*cmd); 7748 buf = wmi_buf_alloc(wmi_handle, len); 7749 if (!buf) 7750 return QDF_STATUS_E_NOMEM; 7751 7752 cmd = (wmi_pdev_pktlog_enable_cmd_fixed_param *) 7753 wmi_buf_data(buf); 7754 WMITLV_SET_HDR(&cmd->tlv_header, 7755 WMITLV_TAG_STRUC_wmi_pdev_pktlog_enable_cmd_fixed_param, 7756 WMITLV_GET_STRUCT_TLVLEN 7757 (wmi_pdev_pktlog_enable_cmd_fixed_param)); 7758 cmd->evlist = 0; 7759 for (idx = 0; idx < max_idx; idx++) { 7760 if (PKTLOG_EVENT & (1 << idx)) 7761 cmd->evlist |= pktlog_event_tlv[idx]; 7762 } 7763 cmd->enable = user_triggered ? WMI_PKTLOG_ENABLE_FORCE 7764 : WMI_PKTLOG_ENABLE_AUTO; 7765 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 7766 wmi_handle, 7767 WMI_HOST_PDEV_ID_SOC); 7768 wmi_mtrace(WMI_PDEV_PKTLOG_ENABLE_CMDID, NO_SESSION, 0); 7769 if (wmi_unified_cmd_send(wmi_handle, buf, len, 7770 WMI_PDEV_PKTLOG_ENABLE_CMDID)) { 7771 wmi_err("Failed to send pktlog enable cmdid"); 7772 goto wmi_send_failed; 7773 } 7774 break; 7775 case WMI_PDEV_PKTLOG_DISABLE_CMDID: 7776 len = sizeof(*disable_cmd); 7777 buf = wmi_buf_alloc(wmi_handle, len); 7778 if (!buf) 7779 return QDF_STATUS_E_NOMEM; 7780 7781 disable_cmd = (wmi_pdev_pktlog_disable_cmd_fixed_param *) 7782 wmi_buf_data(buf); 7783 WMITLV_SET_HDR(&disable_cmd->tlv_header, 7784 WMITLV_TAG_STRUC_wmi_pdev_pktlog_disable_cmd_fixed_param, 7785 WMITLV_GET_STRUCT_TLVLEN 7786 (wmi_pdev_pktlog_disable_cmd_fixed_param)); 7787 disable_cmd->pdev_id = 7788 wmi_handle->ops->convert_pdev_id_host_to_target( 7789 wmi_handle, 7790 WMI_HOST_PDEV_ID_SOC); 7791 wmi_mtrace(WMI_PDEV_PKTLOG_DISABLE_CMDID, NO_SESSION, 0); 7792 if (wmi_unified_cmd_send(wmi_handle, buf, len, 7793 WMI_PDEV_PKTLOG_DISABLE_CMDID)) { 7794 wmi_err("failed to send pktlog disable cmdid"); 7795 goto wmi_send_failed; 7796 } 7797 break; 7798 default: 7799 wmi_debug("Invalid PKTLOG command: %d", CMD_ID); 7800 break; 7801 } 7802 7803 return QDF_STATUS_SUCCESS; 7804 7805 wmi_send_failed: 7806 wmi_buf_free(buf); 7807 return QDF_STATUS_E_FAILURE; 7808 } 7809 #endif /* !REMOVE_PKT_LOG && FEATURE_PKTLOG */ 7810 7811 /** 7812 * send_stats_ext_req_cmd_tlv() - request ext stats from fw 7813 * @wmi_handle: wmi handle 7814 * @preq: stats ext params 7815 * 7816 * Return: QDF status 7817 */ 7818 static QDF_STATUS send_stats_ext_req_cmd_tlv(wmi_unified_t wmi_handle, 7819 struct stats_ext_params *preq) 7820 { 7821 QDF_STATUS ret; 7822 wmi_req_stats_ext_cmd_fixed_param *cmd; 7823 wmi_buf_t buf; 7824 size_t len; 7825 uint8_t *buf_ptr; 7826 uint16_t max_wmi_msg_size = wmi_get_max_msg_len(wmi_handle); 7827 uint32_t *vdev_bitmap; 7828 7829 if (preq->request_data_len > (max_wmi_msg_size - WMI_TLV_HDR_SIZE - 7830 sizeof(*cmd))) { 7831 wmi_err("Data length=%d is greater than max wmi msg size", 7832 preq->request_data_len); 7833 return QDF_STATUS_E_FAILURE; 7834 } 7835 7836 len = sizeof(*cmd) + WMI_TLV_HDR_SIZE + preq->request_data_len + 7837 WMI_TLV_HDR_SIZE + sizeof(uint32_t); 7838 7839 buf = wmi_buf_alloc(wmi_handle, len); 7840 if (!buf) 7841 return QDF_STATUS_E_NOMEM; 7842 7843 buf_ptr = (uint8_t *) wmi_buf_data(buf); 7844 cmd = (wmi_req_stats_ext_cmd_fixed_param *) buf_ptr; 7845 7846 WMITLV_SET_HDR(&cmd->tlv_header, 7847 WMITLV_TAG_STRUC_wmi_req_stats_ext_cmd_fixed_param, 7848 WMITLV_GET_STRUCT_TLVLEN 7849 (wmi_req_stats_ext_cmd_fixed_param)); 7850 cmd->vdev_id = preq->vdev_id; 7851 cmd->data_len = preq->request_data_len; 7852 7853 wmi_debug("The data len value is %u and vdev id set is %u", 7854 preq->request_data_len, preq->vdev_id); 7855 7856 buf_ptr += sizeof(wmi_req_stats_ext_cmd_fixed_param); 7857 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, cmd->data_len); 7858 7859 buf_ptr += WMI_TLV_HDR_SIZE; 7860 qdf_mem_copy(buf_ptr, preq->request_data, cmd->data_len); 7861 7862 buf_ptr += cmd->data_len; 7863 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, sizeof(uint32_t)); 7864 7865 buf_ptr += WMI_TLV_HDR_SIZE; 7866 7867 vdev_bitmap = (A_UINT32 *)buf_ptr; 7868 7869 vdev_bitmap[0] = preq->vdev_id_bitmap; 7870 7871 wmi_debug("Sending MLO vdev_id_bitmap:%x", vdev_bitmap[0]); 7872 7873 buf_ptr += sizeof(uint32_t); 7874 7875 wmi_mtrace(WMI_REQUEST_STATS_EXT_CMDID, cmd->vdev_id, 0); 7876 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 7877 WMI_REQUEST_STATS_EXT_CMDID); 7878 if (QDF_IS_STATUS_ERROR(ret)) { 7879 wmi_err("Failed to send notify cmd ret = %d", ret); 7880 wmi_buf_free(buf); 7881 } 7882 7883 return ret; 7884 } 7885 7886 /** 7887 * send_process_dhcpserver_offload_cmd_tlv() - enable DHCP server offload 7888 * @wmi_handle: wmi handle 7889 * @params: DHCP server offload info 7890 * 7891 * Return: QDF_STATUS_SUCCESS for success or error code 7892 */ 7893 static QDF_STATUS 7894 send_process_dhcpserver_offload_cmd_tlv(wmi_unified_t wmi_handle, 7895 struct dhcp_offload_info_params *params) 7896 { 7897 wmi_set_dhcp_server_offload_cmd_fixed_param *cmd; 7898 wmi_buf_t buf; 7899 QDF_STATUS status; 7900 7901 buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd)); 7902 if (!buf) 7903 return QDF_STATUS_E_NOMEM; 7904 7905 cmd = (wmi_set_dhcp_server_offload_cmd_fixed_param *) wmi_buf_data(buf); 7906 7907 WMITLV_SET_HDR(&cmd->tlv_header, 7908 WMITLV_TAG_STRUC_wmi_set_dhcp_server_offload_cmd_fixed_param, 7909 WMITLV_GET_STRUCT_TLVLEN 7910 (wmi_set_dhcp_server_offload_cmd_fixed_param)); 7911 cmd->vdev_id = params->vdev_id; 7912 cmd->enable = params->dhcp_offload_enabled; 7913 cmd->num_client = params->dhcp_client_num; 7914 cmd->srv_ipv4 = params->dhcp_srv_addr; 7915 cmd->start_lsb = 0; 7916 wmi_mtrace(WMI_SET_DHCP_SERVER_OFFLOAD_CMDID, cmd->vdev_id, 0); 7917 status = wmi_unified_cmd_send(wmi_handle, buf, 7918 sizeof(*cmd), 7919 WMI_SET_DHCP_SERVER_OFFLOAD_CMDID); 7920 if (QDF_IS_STATUS_ERROR(status)) { 7921 wmi_err("Failed to send set_dhcp_server_offload cmd"); 7922 wmi_buf_free(buf); 7923 return QDF_STATUS_E_FAILURE; 7924 } 7925 wmi_debug("Set dhcp server offload to vdevId %d", params->vdev_id); 7926 7927 return status; 7928 } 7929 7930 /** 7931 * send_pdev_set_regdomain_cmd_tlv() - send set regdomain command to fw 7932 * @wmi_handle: wmi handle 7933 * @param: pointer to pdev regdomain params 7934 * 7935 * Return: QDF_STATUS_SUCCESS for success or error code 7936 */ 7937 static QDF_STATUS 7938 send_pdev_set_regdomain_cmd_tlv(wmi_unified_t wmi_handle, 7939 struct pdev_set_regdomain_params *param) 7940 { 7941 wmi_buf_t buf; 7942 wmi_pdev_set_regdomain_cmd_fixed_param *cmd; 7943 int32_t len = sizeof(*cmd); 7944 7945 buf = wmi_buf_alloc(wmi_handle, len); 7946 if (!buf) 7947 return QDF_STATUS_E_NOMEM; 7948 7949 cmd = (wmi_pdev_set_regdomain_cmd_fixed_param *) wmi_buf_data(buf); 7950 WMITLV_SET_HDR(&cmd->tlv_header, 7951 WMITLV_TAG_STRUC_wmi_pdev_set_regdomain_cmd_fixed_param, 7952 WMITLV_GET_STRUCT_TLVLEN 7953 (wmi_pdev_set_regdomain_cmd_fixed_param)); 7954 7955 cmd->reg_domain = param->currentRDinuse; 7956 cmd->reg_domain_2G = param->currentRD2G; 7957 cmd->reg_domain_5G = param->currentRD5G; 7958 cmd->conformance_test_limit_2G = param->ctl_2G; 7959 cmd->conformance_test_limit_5G = param->ctl_5G; 7960 cmd->dfs_domain = param->dfsDomain; 7961 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 7962 wmi_handle, 7963 param->pdev_id); 7964 7965 wmi_mtrace(WMI_PDEV_SET_REGDOMAIN_CMDID, NO_SESSION, 0); 7966 if (wmi_unified_cmd_send(wmi_handle, buf, len, 7967 WMI_PDEV_SET_REGDOMAIN_CMDID)) { 7968 wmi_err("Failed to send pdev set regdomain command"); 7969 wmi_buf_free(buf); 7970 return QDF_STATUS_E_FAILURE; 7971 } 7972 7973 return QDF_STATUS_SUCCESS; 7974 } 7975 7976 /** 7977 * send_regdomain_info_to_fw_cmd_tlv() - send regdomain info to fw 7978 * @wmi_handle: wmi handle 7979 * @reg_dmn: reg domain 7980 * @regdmn2G: 2G reg domain 7981 * @regdmn5G: 5G reg domain 7982 * @ctl2G: 2G test limit 7983 * @ctl5G: 5G test limit 7984 * 7985 * Return: none 7986 */ 7987 static QDF_STATUS send_regdomain_info_to_fw_cmd_tlv(wmi_unified_t wmi_handle, 7988 uint32_t reg_dmn, uint16_t regdmn2G, 7989 uint16_t regdmn5G, uint8_t ctl2G, 7990 uint8_t ctl5G) 7991 { 7992 wmi_buf_t buf; 7993 wmi_pdev_set_regdomain_cmd_fixed_param *cmd; 7994 int32_t len = sizeof(*cmd); 7995 7996 7997 buf = wmi_buf_alloc(wmi_handle, len); 7998 if (!buf) 7999 return QDF_STATUS_E_NOMEM; 8000 8001 cmd = (wmi_pdev_set_regdomain_cmd_fixed_param *) wmi_buf_data(buf); 8002 WMITLV_SET_HDR(&cmd->tlv_header, 8003 WMITLV_TAG_STRUC_wmi_pdev_set_regdomain_cmd_fixed_param, 8004 WMITLV_GET_STRUCT_TLVLEN 8005 (wmi_pdev_set_regdomain_cmd_fixed_param)); 8006 cmd->reg_domain = reg_dmn; 8007 cmd->reg_domain_2G = regdmn2G; 8008 cmd->reg_domain_5G = regdmn5G; 8009 cmd->conformance_test_limit_2G = ctl2G; 8010 cmd->conformance_test_limit_5G = ctl5G; 8011 8012 wmi_debug("regd = %x, regd_2g = %x, regd_5g = %x, ctl_2g = %x, ctl_5g = %x", 8013 cmd->reg_domain, cmd->reg_domain_2G, cmd->reg_domain_5G, 8014 cmd->conformance_test_limit_2G, 8015 cmd->conformance_test_limit_5G); 8016 8017 wmi_mtrace(WMI_PDEV_SET_REGDOMAIN_CMDID, NO_SESSION, 0); 8018 if (wmi_unified_cmd_send(wmi_handle, buf, len, 8019 WMI_PDEV_SET_REGDOMAIN_CMDID)) { 8020 wmi_err("Failed to send pdev set regdomain command"); 8021 wmi_buf_free(buf); 8022 return QDF_STATUS_E_FAILURE; 8023 } 8024 8025 return QDF_STATUS_SUCCESS; 8026 } 8027 8028 /** 8029 * copy_custom_aggr_bitmap() - copies host side bitmap using FW APIs 8030 * @param: param sent from the host side 8031 * @cmd: param to be sent to the fw side 8032 */ 8033 static inline void copy_custom_aggr_bitmap( 8034 struct set_custom_aggr_size_params *param, 8035 wmi_vdev_set_custom_aggr_size_cmd_fixed_param *cmd) 8036 { 8037 WMI_VDEV_CUSTOM_AGGR_AC_SET(cmd->enable_bitmap, 8038 param->ac); 8039 WMI_VDEV_CUSTOM_AGGR_TYPE_SET(cmd->enable_bitmap, 8040 param->aggr_type); 8041 WMI_VDEV_CUSTOM_TX_AGGR_SZ_DIS_SET(cmd->enable_bitmap, 8042 param->tx_aggr_size_disable); 8043 WMI_VDEV_CUSTOM_RX_AGGR_SZ_DIS_SET(cmd->enable_bitmap, 8044 param->rx_aggr_size_disable); 8045 WMI_VDEV_CUSTOM_TX_AC_EN_SET(cmd->enable_bitmap, 8046 param->tx_ac_enable); 8047 WMI_VDEV_CUSTOM_AGGR_256_BA_EN_SET(cmd->enable_bitmap, 8048 param->aggr_ba_enable); 8049 } 8050 8051 /** 8052 * send_vdev_set_custom_aggr_size_cmd_tlv() - custom aggr size param in fw 8053 * @wmi_handle: wmi handle 8054 * @param: pointer to hold custom aggr size params 8055 * 8056 * Return: QDF_STATUS_SUCCESS for success or error code 8057 */ 8058 static QDF_STATUS send_vdev_set_custom_aggr_size_cmd_tlv( 8059 wmi_unified_t wmi_handle, 8060 struct set_custom_aggr_size_params *param) 8061 { 8062 wmi_vdev_set_custom_aggr_size_cmd_fixed_param *cmd; 8063 wmi_buf_t buf; 8064 int32_t len = sizeof(*cmd); 8065 8066 buf = wmi_buf_alloc(wmi_handle, len); 8067 if (!buf) 8068 return QDF_STATUS_E_FAILURE; 8069 8070 cmd = (wmi_vdev_set_custom_aggr_size_cmd_fixed_param *) 8071 wmi_buf_data(buf); 8072 WMITLV_SET_HDR(&cmd->tlv_header, 8073 WMITLV_TAG_STRUC_wmi_vdev_set_custom_aggr_size_cmd_fixed_param, 8074 WMITLV_GET_STRUCT_TLVLEN( 8075 wmi_vdev_set_custom_aggr_size_cmd_fixed_param)); 8076 cmd->vdev_id = param->vdev_id; 8077 cmd->tx_aggr_size = param->tx_aggr_size; 8078 cmd->rx_aggr_size = param->rx_aggr_size; 8079 copy_custom_aggr_bitmap(param, cmd); 8080 8081 wmi_debug("Set custom aggr: vdev id=0x%X, tx aggr size=0x%X " 8082 "rx_aggr_size=0x%X access category=0x%X, agg_type=0x%X " 8083 "tx_aggr_size_disable=0x%X, rx_aggr_size_disable=0x%X " 8084 "tx_ac_enable=0x%X", 8085 param->vdev_id, param->tx_aggr_size, param->rx_aggr_size, 8086 param->ac, param->aggr_type, param->tx_aggr_size_disable, 8087 param->rx_aggr_size_disable, param->tx_ac_enable); 8088 8089 wmi_mtrace(WMI_VDEV_SET_CUSTOM_AGGR_SIZE_CMDID, cmd->vdev_id, 0); 8090 if (wmi_unified_cmd_send(wmi_handle, buf, len, 8091 WMI_VDEV_SET_CUSTOM_AGGR_SIZE_CMDID)) { 8092 wmi_err("Setting custom aggregation size failed"); 8093 wmi_buf_free(buf); 8094 return QDF_STATUS_E_FAILURE; 8095 } 8096 8097 return QDF_STATUS_SUCCESS; 8098 } 8099 8100 /** 8101 * send_vdev_set_qdepth_thresh_cmd_tlv() - WMI set qdepth threshold 8102 * @wmi_handle: handle to WMI. 8103 * @param: pointer to tx antenna param 8104 * 8105 * Return: QDF_STATUS_SUCCESS for success or error code 8106 */ 8107 8108 static QDF_STATUS send_vdev_set_qdepth_thresh_cmd_tlv(wmi_unified_t wmi_handle, 8109 struct set_qdepth_thresh_params *param) 8110 { 8111 wmi_peer_tid_msduq_qdepth_thresh_update_cmd_fixed_param *cmd; 8112 wmi_msduq_qdepth_thresh_update *cmd_update; 8113 wmi_buf_t buf; 8114 int32_t len = 0; 8115 int i; 8116 uint8_t *buf_ptr; 8117 QDF_STATUS ret; 8118 8119 if (param->num_of_msduq_updates > QDEPTH_THRESH_MAX_UPDATES) { 8120 wmi_err("Invalid Update Count!"); 8121 return QDF_STATUS_E_INVAL; 8122 } 8123 8124 len = sizeof(*cmd) + WMI_TLV_HDR_SIZE; 8125 len += (sizeof(wmi_msduq_qdepth_thresh_update) * 8126 param->num_of_msduq_updates); 8127 buf = wmi_buf_alloc(wmi_handle, len); 8128 8129 if (!buf) 8130 return QDF_STATUS_E_NOMEM; 8131 8132 buf_ptr = (uint8_t *)wmi_buf_data(buf); 8133 cmd = (wmi_peer_tid_msduq_qdepth_thresh_update_cmd_fixed_param *) 8134 buf_ptr; 8135 8136 WMITLV_SET_HDR(&cmd->tlv_header, 8137 WMITLV_TAG_STRUC_wmi_peer_tid_msduq_qdepth_thresh_update_cmd_fixed_param 8138 , WMITLV_GET_STRUCT_TLVLEN( 8139 wmi_peer_tid_msduq_qdepth_thresh_update_cmd_fixed_param)); 8140 8141 cmd->pdev_id = 8142 wmi_handle->ops->convert_pdev_id_host_to_target( 8143 wmi_handle, 8144 param->pdev_id); 8145 cmd->vdev_id = param->vdev_id; 8146 WMI_CHAR_ARRAY_TO_MAC_ADDR(param->mac_addr, &cmd->peer_mac_address); 8147 cmd->num_of_msduq_updates = param->num_of_msduq_updates; 8148 8149 buf_ptr += sizeof( 8150 wmi_peer_tid_msduq_qdepth_thresh_update_cmd_fixed_param); 8151 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 8152 param->num_of_msduq_updates * 8153 sizeof(wmi_msduq_qdepth_thresh_update)); 8154 buf_ptr += WMI_TLV_HDR_SIZE; 8155 cmd_update = (wmi_msduq_qdepth_thresh_update *)buf_ptr; 8156 8157 for (i = 0; i < cmd->num_of_msduq_updates; i++) { 8158 WMITLV_SET_HDR(&cmd_update->tlv_header, 8159 WMITLV_TAG_STRUC_wmi_msduq_qdepth_thresh_update, 8160 WMITLV_GET_STRUCT_TLVLEN( 8161 wmi_msduq_qdepth_thresh_update)); 8162 cmd_update->tid_num = param->update_params[i].tid_num; 8163 cmd_update->msduq_update_mask = 8164 param->update_params[i].msduq_update_mask; 8165 cmd_update->qdepth_thresh_value = 8166 param->update_params[i].qdepth_thresh_value; 8167 wmi_debug("Set QDepth Threshold: vdev=0x%X pdev=0x%X, tid=0x%X " 8168 "mac_addr_upper4=%X, mac_addr_lower2:%X," 8169 " update mask=0x%X thresh val=0x%X", 8170 cmd->vdev_id, cmd->pdev_id, cmd_update->tid_num, 8171 cmd->peer_mac_address.mac_addr31to0, 8172 cmd->peer_mac_address.mac_addr47to32, 8173 cmd_update->msduq_update_mask, 8174 cmd_update->qdepth_thresh_value); 8175 cmd_update++; 8176 } 8177 8178 wmi_mtrace(WMI_PEER_TID_MSDUQ_QDEPTH_THRESH_UPDATE_CMDID, 8179 cmd->vdev_id, 0); 8180 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 8181 WMI_PEER_TID_MSDUQ_QDEPTH_THRESH_UPDATE_CMDID); 8182 8183 if (ret != 0) { 8184 wmi_err("Failed to send WMI_PEER_TID_MSDUQ_QDEPTH_THRESH_UPDATE_CMDID"); 8185 wmi_buf_free(buf); 8186 } 8187 8188 return ret; 8189 } 8190 8191 /** 8192 * send_set_vap_dscp_tid_map_cmd_tlv() - send vap dscp tid map cmd to fw 8193 * @wmi_handle: wmi handle 8194 * @param: pointer to hold vap dscp tid map param 8195 * 8196 * Return: QDF_STATUS_SUCCESS for success or error code 8197 */ 8198 static QDF_STATUS 8199 send_set_vap_dscp_tid_map_cmd_tlv(wmi_unified_t wmi_handle, 8200 struct vap_dscp_tid_map_params *param) 8201 { 8202 wmi_buf_t buf; 8203 wmi_vdev_set_dscp_tid_map_cmd_fixed_param *cmd; 8204 int32_t len = sizeof(*cmd); 8205 8206 buf = wmi_buf_alloc(wmi_handle, len); 8207 if (!buf) 8208 return QDF_STATUS_E_FAILURE; 8209 8210 cmd = (wmi_vdev_set_dscp_tid_map_cmd_fixed_param *)wmi_buf_data(buf); 8211 qdf_mem_copy(cmd->dscp_to_tid_map, param->dscp_to_tid_map, 8212 sizeof(uint32_t) * WMI_DSCP_MAP_MAX); 8213 8214 cmd->vdev_id = param->vdev_id; 8215 cmd->enable_override = 0; 8216 8217 wmi_debug("Setting dscp for vap id: %d", cmd->vdev_id); 8218 wmi_mtrace(WMI_VDEV_SET_DSCP_TID_MAP_CMDID, cmd->vdev_id, 0); 8219 if (wmi_unified_cmd_send(wmi_handle, buf, len, 8220 WMI_VDEV_SET_DSCP_TID_MAP_CMDID)) { 8221 wmi_err("Failed to set dscp cmd"); 8222 wmi_buf_free(buf); 8223 return QDF_STATUS_E_FAILURE; 8224 } 8225 8226 return QDF_STATUS_SUCCESS; 8227 } 8228 8229 /** 8230 * send_vdev_set_fwtest_param_cmd_tlv() - send fwtest param in fw 8231 * @wmi_handle: wmi handle 8232 * @param: pointer to hold fwtest param 8233 * 8234 * Return: QDF_STATUS_SUCCESS for success or error code 8235 */ 8236 static QDF_STATUS send_vdev_set_fwtest_param_cmd_tlv(wmi_unified_t wmi_handle, 8237 struct set_fwtest_params *param) 8238 { 8239 wmi_fwtest_set_param_cmd_fixed_param *cmd; 8240 wmi_buf_t buf; 8241 int32_t len = sizeof(*cmd); 8242 8243 buf = wmi_buf_alloc(wmi_handle, len); 8244 8245 if (!buf) 8246 return QDF_STATUS_E_FAILURE; 8247 8248 cmd = (wmi_fwtest_set_param_cmd_fixed_param *)wmi_buf_data(buf); 8249 WMITLV_SET_HDR(&cmd->tlv_header, 8250 WMITLV_TAG_STRUC_wmi_fwtest_set_param_cmd_fixed_param, 8251 WMITLV_GET_STRUCT_TLVLEN( 8252 wmi_fwtest_set_param_cmd_fixed_param)); 8253 cmd->param_id = param->arg; 8254 cmd->param_value = param->value; 8255 8256 wmi_mtrace(WMI_FWTEST_CMDID, NO_SESSION, 0); 8257 if (wmi_unified_cmd_send(wmi_handle, buf, len, WMI_FWTEST_CMDID)) { 8258 wmi_err("Setting FW test param failed"); 8259 wmi_buf_free(buf); 8260 return QDF_STATUS_E_FAILURE; 8261 } 8262 8263 return QDF_STATUS_SUCCESS; 8264 } 8265 8266 /** 8267 * send_phyerr_disable_cmd_tlv() - WMI phyerr disable function 8268 * @wmi_handle: handle to WMI. 8269 * 8270 * Return: QDF_STATUS_SUCCESS for success or error code 8271 */ 8272 static QDF_STATUS send_phyerr_disable_cmd_tlv(wmi_unified_t wmi_handle) 8273 { 8274 wmi_pdev_dfs_disable_cmd_fixed_param *cmd; 8275 wmi_buf_t buf; 8276 QDF_STATUS ret; 8277 int32_t len; 8278 8279 len = sizeof(*cmd); 8280 8281 buf = wmi_buf_alloc(wmi_handle, len); 8282 if (!buf) 8283 return QDF_STATUS_E_FAILURE; 8284 8285 cmd = (wmi_pdev_dfs_disable_cmd_fixed_param *)wmi_buf_data(buf); 8286 WMITLV_SET_HDR(&cmd->tlv_header, 8287 WMITLV_TAG_STRUC_wmi_pdev_dfs_disable_cmd_fixed_param, 8288 WMITLV_GET_STRUCT_TLVLEN( 8289 wmi_pdev_dfs_disable_cmd_fixed_param)); 8290 /* Filling it with WMI_PDEV_ID_SOC for now */ 8291 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 8292 wmi_handle, 8293 WMI_HOST_PDEV_ID_SOC); 8294 8295 wmi_mtrace(WMI_PDEV_DFS_DISABLE_CMDID, NO_SESSION, 0); 8296 ret = wmi_unified_cmd_send(wmi_handle, buf, sizeof(*cmd), 8297 WMI_PDEV_DFS_DISABLE_CMDID); 8298 8299 if (ret != 0) { 8300 wmi_err("Sending PDEV DFS disable cmd failed"); 8301 wmi_buf_free(buf); 8302 } 8303 8304 return ret; 8305 } 8306 8307 /** 8308 * send_phyerr_enable_cmd_tlv() - WMI phyerr disable function 8309 * @wmi_handle: handle to WMI. 8310 * 8311 * Return: QDF_STATUS_SUCCESS for success or error code 8312 */ 8313 static QDF_STATUS send_phyerr_enable_cmd_tlv(wmi_unified_t wmi_handle) 8314 { 8315 wmi_pdev_dfs_enable_cmd_fixed_param *cmd; 8316 wmi_buf_t buf; 8317 QDF_STATUS ret; 8318 int32_t len; 8319 8320 len = sizeof(*cmd); 8321 8322 buf = wmi_buf_alloc(wmi_handle, len); 8323 if (!buf) 8324 return QDF_STATUS_E_FAILURE; 8325 8326 cmd = (wmi_pdev_dfs_enable_cmd_fixed_param *)wmi_buf_data(buf); 8327 WMITLV_SET_HDR(&cmd->tlv_header, 8328 WMITLV_TAG_STRUC_wmi_pdev_dfs_enable_cmd_fixed_param, 8329 WMITLV_GET_STRUCT_TLVLEN( 8330 wmi_pdev_dfs_enable_cmd_fixed_param)); 8331 /* Reserved for future use */ 8332 cmd->reserved0 = 0; 8333 8334 wmi_mtrace(WMI_PDEV_DFS_ENABLE_CMDID, NO_SESSION, 0); 8335 ret = wmi_unified_cmd_send(wmi_handle, buf, sizeof(*cmd), 8336 WMI_PDEV_DFS_ENABLE_CMDID); 8337 8338 if (ret != 0) { 8339 wmi_err("Sending PDEV DFS enable cmd failed"); 8340 wmi_buf_free(buf); 8341 } 8342 8343 return ret; 8344 } 8345 8346 /** 8347 * send_periodic_chan_stats_config_cmd_tlv() - send periodic chan stats cmd 8348 * to fw 8349 * @wmi_handle: wmi handle 8350 * @param: pointer to hold periodic chan stats param 8351 * 8352 * Return: QDF_STATUS_SUCCESS for success or error code 8353 */ 8354 static QDF_STATUS 8355 send_periodic_chan_stats_config_cmd_tlv(wmi_unified_t wmi_handle, 8356 struct periodic_chan_stats_params *param) 8357 { 8358 wmi_set_periodic_channel_stats_config_fixed_param *cmd; 8359 wmi_buf_t buf; 8360 QDF_STATUS ret; 8361 int32_t len; 8362 8363 len = sizeof(*cmd); 8364 8365 buf = wmi_buf_alloc(wmi_handle, len); 8366 if (!buf) 8367 return QDF_STATUS_E_FAILURE; 8368 8369 cmd = (wmi_set_periodic_channel_stats_config_fixed_param *) 8370 wmi_buf_data(buf); 8371 WMITLV_SET_HDR(&cmd->tlv_header, 8372 WMITLV_TAG_STRUC_wmi_set_periodic_channel_stats_config_fixed_param, 8373 WMITLV_GET_STRUCT_TLVLEN( 8374 wmi_set_periodic_channel_stats_config_fixed_param)); 8375 cmd->enable = param->enable; 8376 cmd->stats_period = param->stats_period; 8377 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 8378 wmi_handle, 8379 param->pdev_id); 8380 8381 wmi_mtrace(WMI_SET_PERIODIC_CHANNEL_STATS_CONFIG_CMDID, NO_SESSION, 0); 8382 ret = wmi_unified_cmd_send(wmi_handle, buf, sizeof(*cmd), 8383 WMI_SET_PERIODIC_CHANNEL_STATS_CONFIG_CMDID); 8384 8385 if (ret != 0) { 8386 wmi_err("Sending periodic chan stats config failed"); 8387 wmi_buf_free(buf); 8388 } 8389 8390 return ret; 8391 } 8392 8393 #ifdef WLAN_IOT_SIM_SUPPORT 8394 /** 8395 * send_simulation_test_cmd_tlv() - send simulation test command to fw 8396 * 8397 * @wmi_handle: wmi handle 8398 * @param: pointer to hold simulation test parameter 8399 * 8400 * Return: QDF_STATUS_SUCCESS for success or error code 8401 */ 8402 static QDF_STATUS send_simulation_test_cmd_tlv(wmi_unified_t wmi_handle, 8403 struct simulation_test_params 8404 *param) 8405 { 8406 wmi_simulation_test_cmd_fixed_param *cmd; 8407 u32 wmi_buf_len; 8408 wmi_buf_t buf; 8409 u8 *buf_ptr; 8410 u32 aligned_len = 0; 8411 8412 wmi_buf_len = sizeof(*cmd); 8413 if (param->buf_len) { 8414 aligned_len = roundup(param->buf_len, sizeof(A_UINT32)); 8415 wmi_buf_len += WMI_TLV_HDR_SIZE + aligned_len; 8416 } 8417 8418 buf = wmi_buf_alloc(wmi_handle, wmi_buf_len); 8419 if (!buf) { 8420 wmi_err("wmi_buf_alloc failed"); 8421 return QDF_STATUS_E_NOMEM; 8422 } 8423 8424 buf_ptr = wmi_buf_data(buf); 8425 cmd = (wmi_simulation_test_cmd_fixed_param *)buf_ptr; 8426 WMITLV_SET_HDR(&cmd->tlv_header, 8427 WMITLV_TAG_STRUC_wmi_simulation_test_cmd_fixed_param, 8428 WMITLV_GET_STRUCT_TLVLEN( 8429 wmi_simulation_test_cmd_fixed_param)); 8430 cmd->pdev_id = param->pdev_id; 8431 cmd->vdev_id = param->vdev_id; 8432 WMI_CHAR_ARRAY_TO_MAC_ADDR(param->peer_mac, &cmd->peer_macaddr); 8433 cmd->test_cmd_type = param->test_cmd_type; 8434 cmd->test_subcmd_type = param->test_subcmd_type; 8435 WMI_SIM_FRAME_TYPE_SET(cmd->frame_type_subtype_seq, param->frame_type); 8436 WMI_SIM_FRAME_SUBTYPE_SET(cmd->frame_type_subtype_seq, 8437 param->frame_subtype); 8438 WMI_SIM_FRAME_SEQ_SET(cmd->frame_type_subtype_seq, param->seq); 8439 WMI_SIM_FRAME_OFFSET_SET(cmd->frame_offset_length, param->offset); 8440 WMI_SIM_FRAME_LENGTH_SET(cmd->frame_offset_length, param->frame_length); 8441 cmd->buf_len = param->buf_len; 8442 8443 if (param->buf_len) { 8444 buf_ptr += sizeof(*cmd); 8445 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, aligned_len); 8446 buf_ptr += WMI_TLV_HDR_SIZE; 8447 qdf_mem_copy(buf_ptr, param->bufp, param->buf_len); 8448 } 8449 8450 if (wmi_unified_cmd_send(wmi_handle, buf, wmi_buf_len, 8451 WMI_SIMULATION_TEST_CMDID)) { 8452 wmi_err("Failed to send test simulation cmd"); 8453 wmi_buf_free(buf); 8454 return QDF_STATUS_E_FAILURE; 8455 } 8456 8457 return QDF_STATUS_SUCCESS; 8458 } 8459 #endif 8460 8461 #ifdef WLAN_FEATURE_11BE 8462 #define WLAN_PHY_CH_WIDTH_320MHZ CH_WIDTH_320MHZ 8463 #else 8464 #define WLAN_PHY_CH_WIDTH_320MHZ CH_WIDTH_INVALID 8465 #endif 8466 enum phy_ch_width wmi_map_ch_width(A_UINT32 wmi_width) 8467 { 8468 switch (wmi_width) { 8469 case WMI_CHAN_WIDTH_20: 8470 return CH_WIDTH_20MHZ; 8471 case WMI_CHAN_WIDTH_40: 8472 return CH_WIDTH_40MHZ; 8473 case WMI_CHAN_WIDTH_80: 8474 return CH_WIDTH_80MHZ; 8475 case WMI_CHAN_WIDTH_160: 8476 return CH_WIDTH_160MHZ; 8477 case WMI_CHAN_WIDTH_80P80: 8478 return CH_WIDTH_80P80MHZ; 8479 case WMI_CHAN_WIDTH_5: 8480 return CH_WIDTH_5MHZ; 8481 case WMI_CHAN_WIDTH_10: 8482 return CH_WIDTH_10MHZ; 8483 case WMI_CHAN_WIDTH_320: 8484 return WLAN_PHY_CH_WIDTH_320MHZ; 8485 default: 8486 return CH_WIDTH_INVALID; 8487 } 8488 } 8489 8490 #ifdef WLAN_FEATURE_11BE 8491 /** 8492 * wmi_host_to_fw_phymode_11be() - convert host to fw phymode for 11be phymode 8493 * @host_phymode: phymode to convert 8494 * 8495 * Return: one of the 11be values defined in enum WMI_HOST_WLAN_PHY_MODE; 8496 * or WMI_HOST_MODE_UNKNOWN if the input is not an 11be phymode 8497 */ 8498 static WMI_HOST_WLAN_PHY_MODE 8499 wmi_host_to_fw_phymode_11be(enum wlan_phymode host_phymode) 8500 { 8501 switch (host_phymode) { 8502 case WLAN_PHYMODE_11BEA_EHT20: 8503 return WMI_HOST_MODE_11BE_EHT20; 8504 case WLAN_PHYMODE_11BEA_EHT40: 8505 return WMI_HOST_MODE_11BE_EHT40; 8506 case WLAN_PHYMODE_11BEA_EHT80: 8507 return WMI_HOST_MODE_11BE_EHT80; 8508 case WLAN_PHYMODE_11BEA_EHT160: 8509 return WMI_HOST_MODE_11BE_EHT160; 8510 case WLAN_PHYMODE_11BEA_EHT320: 8511 return WMI_HOST_MODE_11BE_EHT320; 8512 case WLAN_PHYMODE_11BEG_EHT20: 8513 return WMI_HOST_MODE_11BE_EHT20_2G; 8514 case WLAN_PHYMODE_11BEG_EHT40: 8515 case WLAN_PHYMODE_11BEG_EHT40PLUS: 8516 case WLAN_PHYMODE_11BEG_EHT40MINUS: 8517 return WMI_HOST_MODE_11BE_EHT40_2G; 8518 default: 8519 return WMI_HOST_MODE_UNKNOWN; 8520 } 8521 } 8522 #else 8523 static WMI_HOST_WLAN_PHY_MODE 8524 wmi_host_to_fw_phymode_11be(enum wlan_phymode host_phymode) 8525 { 8526 return WMI_HOST_MODE_UNKNOWN; 8527 } 8528 #endif 8529 8530 WMI_HOST_WLAN_PHY_MODE wmi_host_to_fw_phymode(enum wlan_phymode host_phymode) 8531 { 8532 switch (host_phymode) { 8533 case WLAN_PHYMODE_11A: 8534 return WMI_HOST_MODE_11A; 8535 case WLAN_PHYMODE_11G: 8536 return WMI_HOST_MODE_11G; 8537 case WLAN_PHYMODE_11B: 8538 return WMI_HOST_MODE_11B; 8539 case WLAN_PHYMODE_11G_ONLY: 8540 return WMI_HOST_MODE_11GONLY; 8541 case WLAN_PHYMODE_11NA_HT20: 8542 return WMI_HOST_MODE_11NA_HT20; 8543 case WLAN_PHYMODE_11NG_HT20: 8544 return WMI_HOST_MODE_11NG_HT20; 8545 case WLAN_PHYMODE_11NA_HT40: 8546 return WMI_HOST_MODE_11NA_HT40; 8547 case WLAN_PHYMODE_11NG_HT40: 8548 case WLAN_PHYMODE_11NG_HT40PLUS: 8549 case WLAN_PHYMODE_11NG_HT40MINUS: 8550 return WMI_HOST_MODE_11NG_HT40; 8551 case WLAN_PHYMODE_11AC_VHT20: 8552 return WMI_HOST_MODE_11AC_VHT20; 8553 case WLAN_PHYMODE_11AC_VHT40: 8554 return WMI_HOST_MODE_11AC_VHT40; 8555 case WLAN_PHYMODE_11AC_VHT80: 8556 return WMI_HOST_MODE_11AC_VHT80; 8557 case WLAN_PHYMODE_11AC_VHT20_2G: 8558 return WMI_HOST_MODE_11AC_VHT20_2G; 8559 case WLAN_PHYMODE_11AC_VHT40PLUS_2G: 8560 case WLAN_PHYMODE_11AC_VHT40MINUS_2G: 8561 case WLAN_PHYMODE_11AC_VHT40_2G: 8562 return WMI_HOST_MODE_11AC_VHT40_2G; 8563 case WLAN_PHYMODE_11AC_VHT80_2G: 8564 return WMI_HOST_MODE_11AC_VHT80_2G; 8565 case WLAN_PHYMODE_11AC_VHT80_80: 8566 return WMI_HOST_MODE_11AC_VHT80_80; 8567 case WLAN_PHYMODE_11AC_VHT160: 8568 return WMI_HOST_MODE_11AC_VHT160; 8569 case WLAN_PHYMODE_11AXA_HE20: 8570 return WMI_HOST_MODE_11AX_HE20; 8571 case WLAN_PHYMODE_11AXA_HE40: 8572 return WMI_HOST_MODE_11AX_HE40; 8573 case WLAN_PHYMODE_11AXA_HE80: 8574 return WMI_HOST_MODE_11AX_HE80; 8575 case WLAN_PHYMODE_11AXA_HE80_80: 8576 return WMI_HOST_MODE_11AX_HE80_80; 8577 case WLAN_PHYMODE_11AXA_HE160: 8578 return WMI_HOST_MODE_11AX_HE160; 8579 case WLAN_PHYMODE_11AXG_HE20: 8580 return WMI_HOST_MODE_11AX_HE20_2G; 8581 case WLAN_PHYMODE_11AXG_HE40: 8582 case WLAN_PHYMODE_11AXG_HE40PLUS: 8583 case WLAN_PHYMODE_11AXG_HE40MINUS: 8584 return WMI_HOST_MODE_11AX_HE40_2G; 8585 case WLAN_PHYMODE_11AXG_HE80: 8586 return WMI_HOST_MODE_11AX_HE80_2G; 8587 default: 8588 return wmi_host_to_fw_phymode_11be(host_phymode); 8589 } 8590 } 8591 8592 /* 8593 * convert_host_to_target_ch_width()- map host channel width(enum phy_ch_width) 8594 * to wmi channel width 8595 * @chan_width: Host channel width 8596 * 8597 * Return: wmi channel width 8598 */ 8599 static 8600 wmi_channel_width convert_host_to_target_ch_width(uint32_t chan_width) 8601 { 8602 switch (chan_width) { 8603 case CH_WIDTH_20MHZ: 8604 return WMI_CHAN_WIDTH_20; 8605 case CH_WIDTH_40MHZ: 8606 return WMI_CHAN_WIDTH_40; 8607 case CH_WIDTH_80MHZ: 8608 return WMI_CHAN_WIDTH_80; 8609 case CH_WIDTH_160MHZ: 8610 return WMI_CHAN_WIDTH_160; 8611 case CH_WIDTH_80P80MHZ: 8612 return WMI_CHAN_WIDTH_80P80; 8613 case CH_WIDTH_5MHZ: 8614 return WMI_CHAN_WIDTH_5; 8615 case CH_WIDTH_10MHZ: 8616 return WMI_CHAN_WIDTH_10; 8617 #ifdef WLAN_FEATURE_11BE 8618 case CH_WIDTH_320MHZ: 8619 return WMI_CHAN_WIDTH_320; 8620 #endif 8621 default: 8622 return WMI_CHAN_WIDTH_MAX; 8623 } 8624 } 8625 8626 /** 8627 * send_vdev_spectral_configure_cmd_tlv() - send VDEV spectral configure 8628 * command to fw 8629 * @wmi_handle: wmi handle 8630 * @param: pointer to hold spectral config parameter 8631 * 8632 * Return: QDF_STATUS_SUCCESS for success or error code 8633 */ 8634 static QDF_STATUS send_vdev_spectral_configure_cmd_tlv(wmi_unified_t wmi_handle, 8635 struct vdev_spectral_configure_params *param) 8636 { 8637 wmi_vdev_spectral_configure_cmd_fixed_param *cmd; 8638 wmi_buf_t buf; 8639 QDF_STATUS ret; 8640 int32_t len; 8641 8642 len = sizeof(*cmd); 8643 buf = wmi_buf_alloc(wmi_handle, len); 8644 if (!buf) 8645 return QDF_STATUS_E_FAILURE; 8646 8647 cmd = (wmi_vdev_spectral_configure_cmd_fixed_param *)wmi_buf_data(buf); 8648 WMITLV_SET_HDR(&cmd->tlv_header, 8649 WMITLV_TAG_STRUC_wmi_vdev_spectral_configure_cmd_fixed_param, 8650 WMITLV_GET_STRUCT_TLVLEN( 8651 wmi_vdev_spectral_configure_cmd_fixed_param)); 8652 8653 cmd->vdev_id = param->vdev_id; 8654 cmd->spectral_scan_count = param->count; 8655 cmd->spectral_scan_period = param->period; 8656 cmd->spectral_scan_priority = param->spectral_pri; 8657 cmd->spectral_scan_fft_size = param->fft_size; 8658 cmd->spectral_scan_gc_ena = param->gc_enable; 8659 cmd->spectral_scan_restart_ena = param->restart_enable; 8660 cmd->spectral_scan_noise_floor_ref = param->noise_floor_ref; 8661 cmd->spectral_scan_init_delay = param->init_delay; 8662 cmd->spectral_scan_nb_tone_thr = param->nb_tone_thr; 8663 cmd->spectral_scan_str_bin_thr = param->str_bin_thr; 8664 cmd->spectral_scan_wb_rpt_mode = param->wb_rpt_mode; 8665 cmd->spectral_scan_rssi_rpt_mode = param->rssi_rpt_mode; 8666 cmd->spectral_scan_rssi_thr = param->rssi_thr; 8667 cmd->spectral_scan_pwr_format = param->pwr_format; 8668 cmd->spectral_scan_rpt_mode = param->rpt_mode; 8669 cmd->spectral_scan_bin_scale = param->bin_scale; 8670 cmd->spectral_scan_dBm_adj = param->dbm_adj; 8671 cmd->spectral_scan_chn_mask = param->chn_mask; 8672 cmd->spectral_scan_mode = param->mode; 8673 cmd->spectral_scan_center_freq1 = param->center_freq1; 8674 cmd->spectral_scan_center_freq2 = param->center_freq2; 8675 cmd->spectral_scan_chan_width = 8676 convert_host_to_target_ch_width(param->chan_width); 8677 cmd->recapture_sample_on_gain_change = param->fft_recap; 8678 /* Not used, fill with zeros */ 8679 cmd->spectral_scan_chan_freq = 0; 8680 8681 wmi_mtrace(WMI_VDEV_SPECTRAL_SCAN_CONFIGURE_CMDID, cmd->vdev_id, 0); 8682 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 8683 WMI_VDEV_SPECTRAL_SCAN_CONFIGURE_CMDID); 8684 8685 if (ret != 0) { 8686 wmi_err("Sending set quiet cmd failed"); 8687 wmi_buf_free(buf); 8688 } 8689 8690 wmi_debug("Sent WMI_VDEV_SPECTRAL_SCAN_CONFIGURE_CMDID"); 8691 wmi_debug("vdev_id: %u spectral_scan_count: %u", 8692 param->vdev_id, param->count); 8693 wmi_debug("spectral_scan_period: %u spectral_scan_priority: %u", 8694 param->period, param->spectral_pri); 8695 wmi_debug("spectral_fft_recapture_cap: %u", param->fft_recap); 8696 wmi_debug("spectral_scan_fft_size: %u spectral_scan_gc_ena: %u", 8697 param->fft_size, param->gc_enable); 8698 wmi_debug("spectral_scan_restart_ena: %u", param->restart_enable); 8699 wmi_debug("spectral_scan_noise_floor_ref: %u", param->noise_floor_ref); 8700 wmi_debug("spectral_scan_init_delay: %u", param->init_delay); 8701 wmi_debug("spectral_scan_nb_tone_thr: %u", param->nb_tone_thr); 8702 wmi_debug("spectral_scan_str_bin_thr: %u", param->str_bin_thr); 8703 wmi_debug("spectral_scan_wb_rpt_mode: %u", param->wb_rpt_mode); 8704 wmi_debug("spectral_scan_rssi_rpt_mode: %u", param->rssi_rpt_mode); 8705 wmi_debug("spectral_scan_rssi_thr: %u spectral_scan_pwr_format: %u", 8706 param->rssi_thr, param->pwr_format); 8707 wmi_debug("spectral_scan_rpt_mode: %u spectral_scan_bin_scale: %u", 8708 param->rpt_mode, param->bin_scale); 8709 wmi_debug("spectral_scan_dBm_adj: %u spectral_scan_chn_mask: %u", 8710 param->dbm_adj, param->chn_mask); 8711 wmi_debug("spectral_scan_mode: %u spectral_scan_center_freq1: %u", 8712 param->mode, param->center_freq1); 8713 wmi_debug("spectral_scan_center_freq2: %u spectral_scan_chan_freq: %u", 8714 param->center_freq2, param->chan_freq); 8715 wmi_debug("spectral_scan_chan_width: %u Status: %d", 8716 param->chan_width, ret); 8717 8718 return ret; 8719 } 8720 8721 /** 8722 * send_vdev_spectral_enable_cmd_tlv() - send VDEV spectral configure 8723 * command to fw 8724 * @wmi_handle: wmi handle 8725 * @param: pointer to hold spectral enable parameter 8726 * 8727 * Return: QDF_STATUS_SUCCESS for success or error code 8728 */ 8729 static QDF_STATUS send_vdev_spectral_enable_cmd_tlv(wmi_unified_t wmi_handle, 8730 struct vdev_spectral_enable_params *param) 8731 { 8732 wmi_vdev_spectral_enable_cmd_fixed_param *cmd; 8733 wmi_buf_t buf; 8734 QDF_STATUS ret; 8735 int32_t len; 8736 8737 len = sizeof(*cmd); 8738 buf = wmi_buf_alloc(wmi_handle, len); 8739 if (!buf) 8740 return QDF_STATUS_E_FAILURE; 8741 8742 cmd = (wmi_vdev_spectral_enable_cmd_fixed_param *)wmi_buf_data(buf); 8743 WMITLV_SET_HDR(&cmd->tlv_header, 8744 WMITLV_TAG_STRUC_wmi_vdev_spectral_enable_cmd_fixed_param, 8745 WMITLV_GET_STRUCT_TLVLEN( 8746 wmi_vdev_spectral_enable_cmd_fixed_param)); 8747 8748 cmd->vdev_id = param->vdev_id; 8749 8750 if (param->active_valid) { 8751 cmd->trigger_cmd = param->active ? 1 : 2; 8752 /* 1: Trigger, 2: Clear Trigger */ 8753 } else { 8754 cmd->trigger_cmd = 0; /* 0: Ignore */ 8755 } 8756 8757 if (param->enabled_valid) { 8758 cmd->enable_cmd = param->enabled ? 1 : 2; 8759 /* 1: Enable 2: Disable */ 8760 } else { 8761 cmd->enable_cmd = 0; /* 0: Ignore */ 8762 } 8763 cmd->spectral_scan_mode = param->mode; 8764 8765 wmi_debug("vdev_id = %u trigger_cmd = %u enable_cmd = %u", 8766 cmd->vdev_id, cmd->trigger_cmd, cmd->enable_cmd); 8767 wmi_debug("spectral_scan_mode = %u", cmd->spectral_scan_mode); 8768 8769 wmi_mtrace(WMI_VDEV_SPECTRAL_SCAN_ENABLE_CMDID, cmd->vdev_id, 0); 8770 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 8771 WMI_VDEV_SPECTRAL_SCAN_ENABLE_CMDID); 8772 8773 if (ret != 0) { 8774 wmi_err("Sending scan enable CMD failed"); 8775 wmi_buf_free(buf); 8776 } 8777 8778 wmi_debug("Sent WMI_VDEV_SPECTRAL_SCAN_ENABLE_CMDID, Status: %d", 8779 ret); 8780 8781 return ret; 8782 } 8783 8784 #ifdef WLAN_CONV_SPECTRAL_ENABLE 8785 static QDF_STATUS 8786 extract_pdev_sscan_fw_cmd_fixed_param_tlv( 8787 wmi_unified_t wmi_handle, 8788 uint8_t *event, struct spectral_startscan_resp_params *param) 8789 { 8790 WMI_PDEV_SSCAN_FW_PARAM_EVENTID_param_tlvs *param_buf; 8791 wmi_pdev_sscan_fw_cmd_fixed_param *ev; 8792 8793 if (!wmi_handle) { 8794 wmi_err("WMI handle is null"); 8795 return QDF_STATUS_E_INVAL; 8796 } 8797 8798 if (!event) { 8799 wmi_err("WMI event is null"); 8800 return QDF_STATUS_E_INVAL; 8801 } 8802 8803 if (!param) { 8804 wmi_err("Spectral startscan response params is null"); 8805 return QDF_STATUS_E_INVAL; 8806 } 8807 8808 param_buf = (WMI_PDEV_SSCAN_FW_PARAM_EVENTID_param_tlvs *)event; 8809 if (!param_buf) 8810 return QDF_STATUS_E_INVAL; 8811 8812 ev = param_buf->fixed_param; 8813 if (!ev) 8814 return QDF_STATUS_E_INVAL; 8815 8816 param->pdev_id = wmi_handle->ops->convert_target_pdev_id_to_host( 8817 wmi_handle, 8818 ev->pdev_id); 8819 param->smode = ev->spectral_scan_mode; 8820 param->num_fft_bin_index = param_buf->num_fft_bin_index; 8821 param->num_det_info = param_buf->num_det_info; 8822 8823 wmi_debug("pdev id:%u smode:%u num_fft_bin_index:%u num_det_info:%u", 8824 ev->pdev_id, ev->spectral_scan_mode, 8825 param_buf->num_fft_bin_index, param_buf->num_det_info); 8826 8827 return QDF_STATUS_SUCCESS; 8828 } 8829 8830 static QDF_STATUS 8831 extract_pdev_sscan_fft_bin_index_tlv( 8832 wmi_unified_t wmi_handle, uint8_t *event, 8833 struct spectral_fft_bin_markers_160_165mhz *param) 8834 { 8835 WMI_PDEV_SSCAN_FW_PARAM_EVENTID_param_tlvs *param_buf; 8836 wmi_pdev_sscan_fft_bin_index *ev; 8837 8838 param_buf = (WMI_PDEV_SSCAN_FW_PARAM_EVENTID_param_tlvs *)event; 8839 if (!param_buf) 8840 return QDF_STATUS_E_INVAL; 8841 8842 ev = param_buf->fft_bin_index; 8843 if (!ev) 8844 return QDF_STATUS_E_INVAL; 8845 8846 param->start_pri80 = WMI_SSCAN_PRI80_START_BIN_GET(ev->pri80_bins); 8847 param->num_pri80 = WMI_SSCAN_PRI80_END_BIN_GET(ev->pri80_bins) - 8848 param->start_pri80 + 1; 8849 param->start_sec80 = WMI_SSCAN_SEC80_START_BIN_GET(ev->sec80_bins); 8850 param->num_sec80 = WMI_SSCAN_SEC80_END_BIN_GET(ev->sec80_bins) - 8851 param->start_sec80 + 1; 8852 param->start_5mhz = WMI_SSCAN_MID_5MHZ_START_BIN_GET(ev->mid_5mhz_bins); 8853 param->num_5mhz = WMI_SSCAN_MID_5MHZ_END_BIN_GET(ev->mid_5mhz_bins) - 8854 param->start_5mhz + 1; 8855 param->is_valid = true; 8856 8857 wmi_debug("start_pri80: %u num_pri80: %u start_sec80: %u num_sec80: %u start_5mhz: %u, num_5mhz: %u", 8858 param->start_pri80, param->num_pri80, 8859 param->start_sec80, param->num_sec80, 8860 param->start_5mhz, param->num_5mhz); 8861 8862 return QDF_STATUS_SUCCESS; 8863 } 8864 8865 /** 8866 * extract_pdev_spectral_session_chan_info_tlv() - Extract channel information 8867 * for a spectral scan session 8868 * @wmi_handle: handle to WMI. 8869 * @event: Event buffer 8870 * @chan_info: Spectral session channel information data structure to be filled 8871 * by this API 8872 * 8873 * Return: QDF_STATUS of operation 8874 */ 8875 static QDF_STATUS 8876 extract_pdev_spectral_session_chan_info_tlv( 8877 wmi_unified_t wmi_handle, void *event, 8878 struct spectral_session_chan_info *chan_info) 8879 { 8880 WMI_PDEV_SSCAN_FW_PARAM_EVENTID_param_tlvs *param_buf = event; 8881 wmi_pdev_sscan_chan_info *chan_info_tlv; 8882 8883 if (!param_buf) { 8884 wmi_err("param_buf is NULL"); 8885 return QDF_STATUS_E_NULL_VALUE; 8886 } 8887 8888 if (!chan_info) { 8889 wmi_err("chan_info is NULL"); 8890 return QDF_STATUS_E_NULL_VALUE; 8891 } 8892 8893 chan_info_tlv = param_buf->chan_info; 8894 if (!chan_info_tlv) { 8895 wmi_err("chan_info tlv is not present in the event"); 8896 return QDF_STATUS_E_NULL_VALUE; 8897 } 8898 8899 wmi_debug("operating_pri20_freq:%u operating_cfreq1:%u" 8900 "operating_cfreq2:%u operating_bw:%u" 8901 "operating_puncture_20mhz_bitmap:%u" 8902 "sscan_cfreq1:%u sscan_cfreq2:%u" 8903 "sscan_bw:%u sscan_puncture_20mhz_bitmap:%u", 8904 chan_info_tlv->operating_pri20_freq, 8905 chan_info_tlv->operating_cfreq1, 8906 chan_info_tlv->operating_cfreq2, chan_info_tlv->operating_bw, 8907 chan_info_tlv->operating_puncture_20mhz_bitmap, 8908 chan_info_tlv->sscan_cfreq1, chan_info_tlv->sscan_cfreq2, 8909 chan_info_tlv->sscan_bw, 8910 chan_info_tlv->sscan_puncture_20mhz_bitmap); 8911 8912 chan_info->operating_pri20_freq = 8913 (qdf_freq_t)chan_info_tlv->operating_pri20_freq; 8914 chan_info->operating_cfreq1 = 8915 (qdf_freq_t)chan_info_tlv->operating_cfreq1; 8916 chan_info->operating_cfreq2 = 8917 (qdf_freq_t)chan_info_tlv->operating_cfreq2; 8918 chan_info->operating_bw = wmi_map_ch_width(chan_info_tlv->operating_bw); 8919 chan_info->operating_puncture_20mhz_bitmap = 8920 chan_info_tlv->operating_puncture_20mhz_bitmap; 8921 8922 chan_info->sscan_cfreq1 = (qdf_freq_t)chan_info_tlv->sscan_cfreq1; 8923 chan_info->sscan_cfreq2 = (qdf_freq_t)chan_info_tlv->sscan_cfreq2; 8924 chan_info->sscan_bw = wmi_map_ch_width(chan_info_tlv->sscan_bw); 8925 chan_info->sscan_puncture_20mhz_bitmap = 8926 chan_info_tlv->sscan_puncture_20mhz_bitmap; 8927 8928 return QDF_STATUS_SUCCESS; 8929 } 8930 8931 static QDF_STATUS 8932 extract_pdev_spectral_session_detector_info_tlv( 8933 wmi_unified_t wmi_handle, void *event, 8934 struct spectral_session_det_info *det_info, uint8_t idx) 8935 { 8936 WMI_PDEV_SSCAN_FW_PARAM_EVENTID_param_tlvs *param_buf = event; 8937 wmi_pdev_sscan_per_detector_info *det_info_tlv; 8938 8939 if (!param_buf) { 8940 wmi_err("param_buf is NULL"); 8941 return QDF_STATUS_E_NULL_VALUE; 8942 } 8943 8944 if (!det_info) { 8945 wmi_err("chan_info is NULL"); 8946 return QDF_STATUS_E_NULL_VALUE; 8947 } 8948 8949 if (!param_buf->det_info) { 8950 wmi_err("det_info tlv is not present in the event"); 8951 return QDF_STATUS_E_NULL_VALUE; 8952 } 8953 8954 if (idx >= param_buf->num_det_info) { 8955 wmi_err("det_info index(%u) is greater than or equal to %u", 8956 idx, param_buf->num_det_info); 8957 return QDF_STATUS_E_FAILURE; 8958 } 8959 8960 det_info_tlv = ¶m_buf->det_info[idx]; 8961 8962 wmi_debug("det_info_idx: %u detector_id:%u start_freq:%u end_freq:%u", 8963 idx, det_info_tlv->detector_id, 8964 det_info_tlv->start_freq, det_info_tlv->end_freq); 8965 8966 det_info->det_id = det_info_tlv->detector_id; 8967 det_info->start_freq = (qdf_freq_t)det_info_tlv->start_freq; 8968 det_info->end_freq = (qdf_freq_t)det_info_tlv->end_freq; 8969 8970 return QDF_STATUS_SUCCESS; 8971 } 8972 8973 /** 8974 * extract_spectral_caps_fixed_param_tlv() - Extract fixed params from Spectral 8975 * capabilities WMI event 8976 * @wmi_handle: handle to WMI. 8977 * @event: Event buffer 8978 * @params: Spectral capabilities event parameters data structure to be filled 8979 * by this API 8980 * 8981 * Return: QDF_STATUS of operation 8982 */ 8983 static QDF_STATUS 8984 extract_spectral_caps_fixed_param_tlv( 8985 wmi_unified_t wmi_handle, void *event, 8986 struct spectral_capabilities_event_params *params) 8987 { 8988 WMI_SPECTRAL_CAPABILITIES_EVENTID_param_tlvs *param_buf = event; 8989 8990 if (!param_buf) { 8991 wmi_err("param_buf is NULL"); 8992 return QDF_STATUS_E_NULL_VALUE; 8993 } 8994 8995 if (!params) { 8996 wmi_err("event parameters is NULL"); 8997 return QDF_STATUS_E_NULL_VALUE; 8998 } 8999 9000 params->num_sscan_bw_caps = param_buf->num_sscan_bw_caps; 9001 params->num_fft_size_caps = param_buf->num_fft_size_caps; 9002 9003 wmi_debug("num_sscan_bw_caps:%u num_fft_size_caps:%u", 9004 params->num_sscan_bw_caps, params->num_fft_size_caps); 9005 9006 return QDF_STATUS_SUCCESS; 9007 } 9008 9009 /** 9010 * extract_spectral_scan_bw_caps_tlv() - Extract bandwidth caps from 9011 * Spectral capabilities WMI event 9012 * @wmi_handle: handle to WMI. 9013 * @event: Event buffer 9014 * @bw_caps: Data structure to be populated by this API after extraction 9015 * 9016 * Return: QDF_STATUS of operation 9017 */ 9018 static QDF_STATUS 9019 extract_spectral_scan_bw_caps_tlv( 9020 wmi_unified_t wmi_handle, void *event, 9021 struct spectral_scan_bw_capabilities *bw_caps) 9022 { 9023 WMI_SPECTRAL_CAPABILITIES_EVENTID_param_tlvs *param_buf = event; 9024 int idx; 9025 9026 if (!param_buf) { 9027 wmi_err("param_buf is NULL"); 9028 return QDF_STATUS_E_NULL_VALUE; 9029 } 9030 9031 if (!bw_caps) { 9032 wmi_err("bw_caps is null"); 9033 return QDF_STATUS_E_NULL_VALUE; 9034 } 9035 9036 for (idx = 0; idx < param_buf->num_sscan_bw_caps; idx++) { 9037 bw_caps[idx].pdev_id = 9038 wmi_handle->ops->convert_pdev_id_target_to_host( 9039 wmi_handle, 9040 param_buf->sscan_bw_caps[idx].pdev_id); 9041 bw_caps[idx].smode = param_buf->sscan_bw_caps[idx].sscan_mode; 9042 bw_caps[idx].operating_bw = wmi_map_ch_width( 9043 param_buf->sscan_bw_caps[idx].operating_bw); 9044 bw_caps[idx].supported_bws = 9045 param_buf->sscan_bw_caps[idx].supported_flags; 9046 9047 wmi_debug("bw_caps[%u]:: pdev_id:%u smode:%u" 9048 "operating_bw:%u supported_flags:0x%x", 9049 idx, param_buf->sscan_bw_caps[idx].pdev_id, 9050 param_buf->sscan_bw_caps[idx].sscan_mode, 9051 param_buf->sscan_bw_caps[idx].operating_bw, 9052 param_buf->sscan_bw_caps[idx].supported_flags); 9053 } 9054 9055 return QDF_STATUS_SUCCESS; 9056 } 9057 9058 /** 9059 * extract_spectral_fft_size_caps_tlv() - Extract FFT size caps from 9060 * Spectral capabilities WMI event 9061 * @wmi_handle: handle to WMI. 9062 * @event: Event buffer 9063 * @fft_size_caps: Data structure to be populated by this API after extraction 9064 * 9065 * Return: QDF_STATUS of operation 9066 */ 9067 static QDF_STATUS 9068 extract_spectral_fft_size_caps_tlv( 9069 wmi_unified_t wmi_handle, void *event, 9070 struct spectral_fft_size_capabilities *fft_size_caps) 9071 { 9072 WMI_SPECTRAL_CAPABILITIES_EVENTID_param_tlvs *param_buf = event; 9073 int idx; 9074 9075 if (!param_buf) { 9076 wmi_err("param_buf is NULL"); 9077 return QDF_STATUS_E_NULL_VALUE; 9078 } 9079 9080 if (!fft_size_caps) { 9081 wmi_err("fft size caps is NULL"); 9082 return QDF_STATUS_E_NULL_VALUE; 9083 } 9084 9085 for (idx = 0; idx < param_buf->num_fft_size_caps; idx++) { 9086 fft_size_caps[idx].pdev_id = 9087 wmi_handle->ops->convert_pdev_id_target_to_host( 9088 wmi_handle, 9089 param_buf->fft_size_caps[idx].pdev_id); 9090 fft_size_caps[idx].sscan_bw = wmi_map_ch_width( 9091 param_buf->fft_size_caps[idx].sscan_bw); 9092 fft_size_caps[idx].supports_fft_sizes = 9093 param_buf->fft_size_caps[idx].supported_flags; 9094 9095 wmi_debug("fft_size_caps[%u]:: pdev_id:%u sscan_bw:%u" 9096 "supported_flags:0x%x", 9097 idx, param_buf->fft_size_caps[idx].pdev_id, 9098 param_buf->fft_size_caps[idx].sscan_bw, 9099 param_buf->fft_size_caps[idx].supported_flags); 9100 } 9101 9102 return QDF_STATUS_SUCCESS; 9103 } 9104 #endif /* WLAN_CONV_SPECTRAL_ENABLE */ 9105 9106 #ifdef FEATURE_WPSS_THERMAL_MITIGATION 9107 static inline void 9108 wmi_fill_client_id_priority(wmi_therm_throt_config_request_fixed_param *tt_conf, 9109 struct thermal_mitigation_params *param) 9110 { 9111 tt_conf->client_id = param->client_id; 9112 tt_conf->priority = param->priority; 9113 } 9114 #else 9115 static inline void 9116 wmi_fill_client_id_priority(wmi_therm_throt_config_request_fixed_param *tt_conf, 9117 struct thermal_mitigation_params *param) 9118 { 9119 } 9120 #endif 9121 9122 /** 9123 * send_thermal_mitigation_param_cmd_tlv() - configure thermal mitigation params 9124 * @wmi_handle : handle to WMI. 9125 * @param : pointer to hold thermal mitigation param 9126 * 9127 * Return: QDF_STATUS_SUCCESS for success or error code 9128 */ 9129 static QDF_STATUS send_thermal_mitigation_param_cmd_tlv( 9130 wmi_unified_t wmi_handle, 9131 struct thermal_mitigation_params *param) 9132 { 9133 wmi_therm_throt_config_request_fixed_param *tt_conf = NULL; 9134 wmi_therm_throt_level_config_info *lvl_conf = NULL; 9135 wmi_buf_t buf = NULL; 9136 uint8_t *buf_ptr = NULL; 9137 int error; 9138 int32_t len; 9139 int i; 9140 9141 len = sizeof(*tt_conf) + WMI_TLV_HDR_SIZE + 9142 param->num_thermal_conf * 9143 sizeof(wmi_therm_throt_level_config_info); 9144 9145 buf = wmi_buf_alloc(wmi_handle, len); 9146 if (!buf) 9147 return QDF_STATUS_E_NOMEM; 9148 9149 tt_conf = (wmi_therm_throt_config_request_fixed_param *) wmi_buf_data(buf); 9150 9151 /* init fixed params */ 9152 WMITLV_SET_HDR(tt_conf, 9153 WMITLV_TAG_STRUC_wmi_therm_throt_config_request_fixed_param, 9154 (WMITLV_GET_STRUCT_TLVLEN(wmi_therm_throt_config_request_fixed_param))); 9155 9156 tt_conf->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 9157 wmi_handle, 9158 param->pdev_id); 9159 tt_conf->enable = param->enable; 9160 tt_conf->dc = param->dc; 9161 tt_conf->dc_per_event = param->dc_per_event; 9162 tt_conf->therm_throt_levels = param->num_thermal_conf; 9163 wmi_fill_client_id_priority(tt_conf, param); 9164 buf_ptr = (uint8_t *) ++tt_conf; 9165 /* init TLV params */ 9166 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 9167 (param->num_thermal_conf * 9168 sizeof(wmi_therm_throt_level_config_info))); 9169 9170 lvl_conf = (wmi_therm_throt_level_config_info *) (buf_ptr + WMI_TLV_HDR_SIZE); 9171 for (i = 0; i < param->num_thermal_conf; i++) { 9172 WMITLV_SET_HDR(&lvl_conf->tlv_header, 9173 WMITLV_TAG_STRUC_wmi_therm_throt_level_config_info, 9174 WMITLV_GET_STRUCT_TLVLEN(wmi_therm_throt_level_config_info)); 9175 lvl_conf->temp_lwm = param->levelconf[i].tmplwm; 9176 lvl_conf->temp_hwm = param->levelconf[i].tmphwm; 9177 lvl_conf->dc_off_percent = param->levelconf[i].dcoffpercent; 9178 lvl_conf->prio = param->levelconf[i].priority; 9179 lvl_conf++; 9180 } 9181 9182 wmi_mtrace(WMI_THERM_THROT_SET_CONF_CMDID, NO_SESSION, 0); 9183 error = wmi_unified_cmd_send(wmi_handle, buf, len, 9184 WMI_THERM_THROT_SET_CONF_CMDID); 9185 if (QDF_IS_STATUS_ERROR(error)) { 9186 wmi_buf_free(buf); 9187 wmi_err("Failed to send WMI_THERM_THROT_SET_CONF_CMDID command"); 9188 } 9189 9190 return error; 9191 } 9192 9193 /** 9194 * send_coex_config_cmd_tlv() - send coex config command to fw 9195 * @wmi_handle: wmi handle 9196 * @param: pointer to coex config param 9197 * 9198 * Return: QDF_STATUS_SUCCESS for success or error code 9199 */ 9200 static QDF_STATUS 9201 send_coex_config_cmd_tlv(wmi_unified_t wmi_handle, 9202 struct coex_config_params *param) 9203 { 9204 WMI_COEX_CONFIG_CMD_fixed_param *cmd; 9205 wmi_buf_t buf; 9206 QDF_STATUS ret; 9207 int32_t len; 9208 9209 len = sizeof(*cmd); 9210 buf = wmi_buf_alloc(wmi_handle, len); 9211 if (!buf) 9212 return QDF_STATUS_E_FAILURE; 9213 9214 cmd = (WMI_COEX_CONFIG_CMD_fixed_param *)wmi_buf_data(buf); 9215 WMITLV_SET_HDR(&cmd->tlv_header, 9216 WMITLV_TAG_STRUC_WMI_COEX_CONFIG_CMD_fixed_param, 9217 WMITLV_GET_STRUCT_TLVLEN( 9218 WMI_COEX_CONFIG_CMD_fixed_param)); 9219 9220 cmd->vdev_id = param->vdev_id; 9221 cmd->config_type = param->config_type; 9222 cmd->config_arg1 = param->config_arg1; 9223 cmd->config_arg2 = param->config_arg2; 9224 cmd->config_arg3 = param->config_arg3; 9225 cmd->config_arg4 = param->config_arg4; 9226 cmd->config_arg5 = param->config_arg5; 9227 cmd->config_arg6 = param->config_arg6; 9228 9229 wmi_mtrace(WMI_COEX_CONFIG_CMDID, cmd->vdev_id, 0); 9230 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 9231 WMI_COEX_CONFIG_CMDID); 9232 9233 if (ret != 0) { 9234 wmi_err("Sending COEX CONFIG CMD failed"); 9235 wmi_buf_free(buf); 9236 } 9237 9238 return ret; 9239 } 9240 9241 #ifdef WLAN_FEATURE_DBAM_CONFIG 9242 9243 static enum wmi_coex_dbam_mode_type 9244 map_to_wmi_coex_dbam_mode_type(enum coex_dbam_config_mode mode) 9245 { 9246 switch (mode) { 9247 case COEX_DBAM_ENABLE: 9248 return WMI_COEX_DBAM_ENABLE; 9249 case COEX_DBAM_FORCE_ENABLE: 9250 return WMI_COEX_DBAM_FORCED; 9251 case COEX_DBAM_DISABLE: 9252 default: 9253 return WMI_COEX_DBAM_DISABLE; 9254 } 9255 } 9256 9257 /** 9258 * send_dbam_config_cmd_tlv() - send coex DBAM config command to fw 9259 * @wmi_handle: wmi handle 9260 * @param: pointer to coex dbam config param 9261 * 9262 * Return: QDF_STATUS_SUCCESS for success or error code 9263 */ 9264 static QDF_STATUS 9265 send_dbam_config_cmd_tlv(wmi_unified_t wmi_handle, 9266 struct coex_dbam_config_params *param) 9267 { 9268 wmi_coex_dbam_cmd_fixed_param *cmd; 9269 wmi_buf_t buf; 9270 void *buf_ptr; 9271 QDF_STATUS ret; 9272 int32_t len; 9273 9274 len = sizeof(*cmd); 9275 buf = wmi_buf_alloc(wmi_handle, len); 9276 if (!buf) { 9277 wmi_err_rl("Failed to allocate wmi buffer"); 9278 return QDF_STATUS_E_NOMEM; 9279 } 9280 9281 buf_ptr = wmi_buf_data(buf); 9282 cmd = buf_ptr; 9283 WMITLV_SET_HDR(&cmd->tlv_header, 9284 WMITLV_TAG_STRUC_wmi_coex_dbam_cmd_fixed_param, 9285 WMITLV_GET_STRUCT_TLVLEN( 9286 wmi_coex_dbam_cmd_fixed_param)); 9287 9288 cmd->vdev_id = param->vdev_id; 9289 cmd->dbam_mode = map_to_wmi_coex_dbam_mode_type(param->dbam_mode); 9290 9291 wmi_mtrace(WMI_COEX_DBAM_CMDID, cmd->vdev_id, 0); 9292 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 9293 WMI_COEX_DBAM_CMDID); 9294 9295 if (QDF_IS_STATUS_ERROR(ret)) { 9296 wmi_err("Sending DBAM CONFIG CMD failed"); 9297 wmi_buf_free(buf); 9298 return QDF_STATUS_E_FAILURE; 9299 } 9300 9301 return ret; 9302 } 9303 9304 static enum coex_dbam_comp_status 9305 wmi_convert_dbam_comp_status(wmi_coex_dbam_comp_status status) 9306 { 9307 switch (status) { 9308 case WMI_COEX_DBAM_COMP_SUCCESS: 9309 case WMI_COEX_DBAM_COMP_ONGOING: 9310 case WMI_COEX_DBAM_COMP_DELAYED: 9311 return COEX_DBAM_COMP_SUCCESS; 9312 case WMI_COEX_DBAM_COMP_NOT_SUPPORT: 9313 return COEX_DBAM_COMP_NOT_SUPPORT; 9314 case WMI_COEX_DBAM_COMP_INVALID_PARAM: 9315 case WMI_COEX_DBAM_COMP_FAIL: 9316 default: 9317 return COEX_DBAM_COMP_FAIL; 9318 } 9319 } 9320 9321 /** 9322 * extract_dbam_config_resp_event_tlv() - extract dbam complete status event 9323 * @wmi_handle: WMI handle 9324 * @evt_buf: event buffer 9325 * @resp: pointer to coex dbam config response 9326 * 9327 * Return: QDF_STATUS 9328 */ 9329 static QDF_STATUS 9330 extract_dbam_config_resp_event_tlv(wmi_unified_t wmi_handle, void *evt_buf, 9331 struct coex_dbam_config_resp *resp) 9332 { 9333 WMI_COEX_DBAM_COMPLETE_EVENTID_param_tlvs *param_buf; 9334 wmi_coex_dbam_complete_event_fixed_param *event; 9335 9336 param_buf = (WMI_COEX_DBAM_COMPLETE_EVENTID_param_tlvs *)evt_buf; 9337 9338 event = param_buf->fixed_param; 9339 9340 resp->dbam_resp = wmi_convert_dbam_comp_status(event->comp_status); 9341 9342 return QDF_STATUS_SUCCESS; 9343 } 9344 #endif 9345 9346 #ifdef WLAN_SUPPORT_TWT 9347 static void wmi_copy_twt_resource_config(wmi_resource_config *resource_cfg, 9348 target_resource_config *tgt_res_cfg) 9349 { 9350 resource_cfg->twt_ap_pdev_count = tgt_res_cfg->twt_ap_pdev_count; 9351 resource_cfg->twt_ap_sta_count = tgt_res_cfg->twt_ap_sta_count; 9352 } 9353 #else 9354 static void wmi_copy_twt_resource_config(wmi_resource_config *resource_cfg, 9355 target_resource_config *tgt_res_cfg) 9356 { 9357 resource_cfg->twt_ap_pdev_count = 0; 9358 resource_cfg->twt_ap_sta_count = 0; 9359 } 9360 #endif 9361 9362 #ifdef WLAN_FEATURE_NAN 9363 static void wmi_set_nan_channel_support(wmi_resource_config *resource_cfg) 9364 { 9365 WMI_RSRC_CFG_HOST_SERVICE_FLAG_NAN_CHANNEL_SUPPORT_SET( 9366 resource_cfg->host_service_flags, 1); 9367 } 9368 #else 9369 static inline 9370 void wmi_set_nan_channel_support(wmi_resource_config *resource_cfg) 9371 { 9372 } 9373 #endif 9374 9375 #if defined(CONFIG_AFC_SUPPORT) 9376 static 9377 void wmi_copy_afc_deployment_config(wmi_resource_config *resource_cfg, 9378 target_resource_config *tgt_res_cfg) 9379 { 9380 WMI_RSRC_CFG_HOST_SERVICE_FLAG_AFC_INDOOR_SUPPORT_CHECK_SET( 9381 resource_cfg->host_service_flags, 9382 tgt_res_cfg->afc_indoor_support); 9383 9384 WMI_RSRC_CFG_HOST_SERVICE_FLAG_AFC_OUTDOOR_SUPPORT_CHECK_SET( 9385 resource_cfg->host_service_flags, 9386 tgt_res_cfg->afc_outdoor_support); 9387 } 9388 #else 9389 static 9390 void wmi_copy_afc_deployment_config(wmi_resource_config *resource_cfg, 9391 target_resource_config *tgt_res_cfg) 9392 { 9393 } 9394 #endif 9395 9396 #ifdef DP_TX_PACKET_INSPECT_FOR_ILP 9397 static inline 9398 void wmi_copy_latency_flowq_support(wmi_resource_config *resource_cfg, 9399 target_resource_config *tgt_res_cfg) 9400 { 9401 if (tgt_res_cfg->tx_ilp_enable) 9402 WMI_RSRC_CFG_FLAGS2_LATENCY_FLOWQ_SUPPORT_SET( 9403 resource_cfg->flags2, 1); 9404 } 9405 #else 9406 static inline 9407 void wmi_copy_latency_flowq_support(wmi_resource_config *resource_cfg, 9408 target_resource_config *tgt_res_cfg) 9409 { 9410 } 9411 #endif 9412 9413 #ifdef MOBILE_DFS_SUPPORT 9414 static inline 9415 void wmi_copy_full_bw_nol_cfg(wmi_resource_config *resource_cfg, 9416 target_resource_config *tgt_res_cfg) 9417 { 9418 WMI_RSRC_CFG_HOST_SERVICE_FLAG_RADAR_FLAGS_FULL_BW_NOL_SET(resource_cfg->host_service_flags, 9419 tgt_res_cfg->is_full_bw_nol_supported); 9420 } 9421 #else 9422 static inline 9423 void wmi_copy_full_bw_nol_cfg(wmi_resource_config *resource_cfg, 9424 target_resource_config *tgt_res_cfg) 9425 { 9426 } 9427 #endif 9428 9429 static 9430 void wmi_copy_resource_config(wmi_resource_config *resource_cfg, 9431 target_resource_config *tgt_res_cfg) 9432 { 9433 resource_cfg->num_vdevs = tgt_res_cfg->num_vdevs; 9434 resource_cfg->num_peers = tgt_res_cfg->num_peers; 9435 resource_cfg->num_offload_peers = tgt_res_cfg->num_offload_peers; 9436 resource_cfg->num_offload_reorder_buffs = 9437 tgt_res_cfg->num_offload_reorder_buffs; 9438 resource_cfg->num_peer_keys = tgt_res_cfg->num_peer_keys; 9439 resource_cfg->num_tids = tgt_res_cfg->num_tids; 9440 resource_cfg->ast_skid_limit = tgt_res_cfg->ast_skid_limit; 9441 resource_cfg->tx_chain_mask = tgt_res_cfg->tx_chain_mask; 9442 resource_cfg->rx_chain_mask = tgt_res_cfg->rx_chain_mask; 9443 resource_cfg->rx_timeout_pri[0] = tgt_res_cfg->rx_timeout_pri[0]; 9444 resource_cfg->rx_timeout_pri[1] = tgt_res_cfg->rx_timeout_pri[1]; 9445 resource_cfg->rx_timeout_pri[2] = tgt_res_cfg->rx_timeout_pri[2]; 9446 resource_cfg->rx_timeout_pri[3] = tgt_res_cfg->rx_timeout_pri[3]; 9447 resource_cfg->rx_decap_mode = tgt_res_cfg->rx_decap_mode; 9448 resource_cfg->scan_max_pending_req = 9449 tgt_res_cfg->scan_max_pending_req; 9450 resource_cfg->bmiss_offload_max_vdev = 9451 tgt_res_cfg->bmiss_offload_max_vdev; 9452 resource_cfg->roam_offload_max_vdev = 9453 tgt_res_cfg->roam_offload_max_vdev; 9454 resource_cfg->roam_offload_max_ap_profiles = 9455 tgt_res_cfg->roam_offload_max_ap_profiles; 9456 resource_cfg->num_mcast_groups = tgt_res_cfg->num_mcast_groups; 9457 resource_cfg->num_mcast_table_elems = 9458 tgt_res_cfg->num_mcast_table_elems; 9459 resource_cfg->mcast2ucast_mode = tgt_res_cfg->mcast2ucast_mode; 9460 resource_cfg->tx_dbg_log_size = tgt_res_cfg->tx_dbg_log_size; 9461 resource_cfg->num_wds_entries = tgt_res_cfg->num_wds_entries; 9462 resource_cfg->dma_burst_size = tgt_res_cfg->dma_burst_size; 9463 resource_cfg->mac_aggr_delim = tgt_res_cfg->mac_aggr_delim; 9464 resource_cfg->rx_skip_defrag_timeout_dup_detection_check = 9465 tgt_res_cfg->rx_skip_defrag_timeout_dup_detection_check; 9466 resource_cfg->vow_config = tgt_res_cfg->vow_config; 9467 resource_cfg->gtk_offload_max_vdev = tgt_res_cfg->gtk_offload_max_vdev; 9468 resource_cfg->num_msdu_desc = tgt_res_cfg->num_msdu_desc; 9469 resource_cfg->max_frag_entries = tgt_res_cfg->max_frag_entries; 9470 resource_cfg->num_tdls_vdevs = tgt_res_cfg->num_tdls_vdevs; 9471 resource_cfg->num_tdls_conn_table_entries = 9472 tgt_res_cfg->num_tdls_conn_table_entries; 9473 resource_cfg->beacon_tx_offload_max_vdev = 9474 tgt_res_cfg->beacon_tx_offload_max_vdev; 9475 resource_cfg->num_multicast_filter_entries = 9476 tgt_res_cfg->num_multicast_filter_entries; 9477 resource_cfg->num_wow_filters = 9478 tgt_res_cfg->num_wow_filters; 9479 resource_cfg->num_keep_alive_pattern = 9480 tgt_res_cfg->num_keep_alive_pattern; 9481 resource_cfg->keep_alive_pattern_size = 9482 tgt_res_cfg->keep_alive_pattern_size; 9483 resource_cfg->max_tdls_concurrent_sleep_sta = 9484 tgt_res_cfg->max_tdls_concurrent_sleep_sta; 9485 resource_cfg->max_tdls_concurrent_buffer_sta = 9486 tgt_res_cfg->max_tdls_concurrent_buffer_sta; 9487 resource_cfg->wmi_send_separate = 9488 tgt_res_cfg->wmi_send_separate; 9489 resource_cfg->num_ocb_vdevs = 9490 tgt_res_cfg->num_ocb_vdevs; 9491 resource_cfg->num_ocb_channels = 9492 tgt_res_cfg->num_ocb_channels; 9493 resource_cfg->num_ocb_schedules = 9494 tgt_res_cfg->num_ocb_schedules; 9495 resource_cfg->bpf_instruction_size = tgt_res_cfg->apf_instruction_size; 9496 resource_cfg->max_bssid_rx_filters = tgt_res_cfg->max_bssid_rx_filters; 9497 resource_cfg->use_pdev_id = tgt_res_cfg->use_pdev_id; 9498 resource_cfg->max_num_dbs_scan_duty_cycle = 9499 tgt_res_cfg->max_num_dbs_scan_duty_cycle; 9500 resource_cfg->sched_params = tgt_res_cfg->scheduler_params; 9501 resource_cfg->num_packet_filters = tgt_res_cfg->num_packet_filters; 9502 resource_cfg->num_max_sta_vdevs = tgt_res_cfg->num_max_sta_vdevs; 9503 resource_cfg->max_bssid_indicator = tgt_res_cfg->max_bssid_indicator; 9504 resource_cfg->max_num_group_keys = tgt_res_cfg->max_num_group_keys; 9505 /* Deferred AI: Max rnr neighbors supported in multisoc case 9506 * where in SoC can support 6ghz. During WMI init of a SoC 9507 * currently there is no way to figure if another SOC is plugged in 9508 * and it can support 6Ghz. 9509 */ 9510 resource_cfg->max_rnr_neighbours = MAX_SUPPORTED_NEIGHBORS; 9511 resource_cfg->ema_max_vap_cnt = tgt_res_cfg->ema_max_vap_cnt; 9512 resource_cfg->ema_max_profile_period = 9513 tgt_res_cfg->ema_max_profile_period; 9514 resource_cfg->ema_init_config = tgt_res_cfg->ema_init_config; 9515 resource_cfg->carrier_config = tgt_res_cfg->carrier_profile_config; 9516 9517 if (tgt_res_cfg->max_ndp_sessions) 9518 resource_cfg->max_ndp_sessions = 9519 tgt_res_cfg->max_ndp_sessions; 9520 resource_cfg->max_ndi_interfaces = tgt_res_cfg->max_ndi; 9521 resource_cfg->num_max_active_vdevs = tgt_res_cfg->num_max_active_vdevs; 9522 resource_cfg->num_max_mlo_link_per_ml_bss = 9523 tgt_res_cfg->num_max_mlo_link_per_ml_bss; 9524 9525 if (tgt_res_cfg->atf_config) 9526 WMI_RSRC_CFG_FLAG_ATF_CONFIG_ENABLE_SET(resource_cfg->flag1, 1); 9527 if (tgt_res_cfg->mgmt_comp_evt_bundle_support) 9528 WMI_RSRC_CFG_FLAG_MGMT_COMP_EVT_BUNDLE_SUPPORT_SET( 9529 resource_cfg->flag1, 1); 9530 if (tgt_res_cfg->tx_msdu_new_partition_id_support) 9531 WMI_RSRC_CFG_FLAG_TX_MSDU_ID_NEW_PARTITION_SUPPORT_SET( 9532 resource_cfg->flag1, 1); 9533 if (tgt_res_cfg->cce_disable) 9534 WMI_RSRC_CFG_FLAG_TCL_CCE_DISABLE_SET(resource_cfg->flag1, 1); 9535 if (tgt_res_cfg->enable_pci_gen) 9536 WMI_RSRC_CFG_FLAG_PCIE_GEN_SWITCH_CAPABLITY_SET( 9537 resource_cfg->flag1, 1); 9538 if (tgt_res_cfg->eapol_minrate_set) { 9539 WMI_RSRC_CFG_FLAG_EAPOL_REKEY_MINRATE_SUPPORT_ENABLE_SET( 9540 resource_cfg->flag1, 1); 9541 if (tgt_res_cfg->eapol_minrate_ac_set != 3) { 9542 WMI_RSRC_CFG_FLAG_EAPOL_AC_OVERRIDE_VALID_SET( 9543 resource_cfg->flag1, 1); 9544 WMI_RSRC_CFG_FLAG_EAPOL_AC_OVERRIDE_SET( 9545 resource_cfg->flag1, 9546 tgt_res_cfg->eapol_minrate_ac_set); 9547 } 9548 } 9549 if (tgt_res_cfg->new_htt_msg_format) { 9550 WMI_RSRC_CFG_FLAG_HTT_H2T_NO_HTC_HDR_LEN_IN_MSG_LEN_SET( 9551 resource_cfg->flag1, 1); 9552 } 9553 9554 if (tgt_res_cfg->peer_unmap_conf_support) 9555 WMI_RSRC_CFG_FLAG_PEER_UNMAP_RESPONSE_SUPPORT_SET( 9556 resource_cfg->flag1, 1); 9557 9558 if (tgt_res_cfg->tstamp64_en) 9559 WMI_RSRC_CFG_FLAG_TX_COMPLETION_TX_TSF64_ENABLE_SET( 9560 resource_cfg->flag1, 1); 9561 9562 if (tgt_res_cfg->three_way_coex_config_legacy_en) 9563 WMI_RSRC_CFG_FLAG_THREE_WAY_COEX_CONFIG_LEGACY_SUPPORT_SET( 9564 resource_cfg->flag1, 1); 9565 if (tgt_res_cfg->pktcapture_support) 9566 WMI_RSRC_CFG_FLAG_PACKET_CAPTURE_SUPPORT_SET( 9567 resource_cfg->flag1, 1); 9568 9569 /* 9570 * Control padding using config param/ini of iphdr_pad_config 9571 */ 9572 if (tgt_res_cfg->iphdr_pad_config) 9573 WMI_RSRC_CFG_FLAG_IPHR_PAD_CONFIG_ENABLE_SET( 9574 resource_cfg->flag1, 1); 9575 9576 WMI_RSRC_CFG_FLAG_IPA_DISABLE_SET(resource_cfg->flag1, 9577 tgt_res_cfg->ipa_disable); 9578 9579 if (tgt_res_cfg->time_sync_ftm) 9580 WMI_RSRC_CFG_FLAG_AUDIO_SYNC_SUPPORT_SET(resource_cfg->flag1, 9581 1); 9582 9583 wmi_copy_twt_resource_config(resource_cfg, tgt_res_cfg); 9584 resource_cfg->peer_map_unmap_versions = 9585 tgt_res_cfg->peer_map_unmap_version; 9586 resource_cfg->smart_ant_cap = tgt_res_cfg->smart_ant_cap; 9587 if (tgt_res_cfg->re_ul_resp) 9588 WMI_SET_BITS(resource_cfg->flags2, 0, 4, 9589 tgt_res_cfg->re_ul_resp); 9590 9591 /* 9592 * Enable Service Aware Wifi 9593 */ 9594 if (tgt_res_cfg->sawf) 9595 WMI_RSRC_CFG_FLAGS2_SAWF_CONFIG_ENABLE_SET(resource_cfg->flags2, 9596 tgt_res_cfg->sawf); 9597 9598 /* 9599 * Enable ast flow override per peer 9600 */ 9601 resource_cfg->msdu_flow_override_config0 = 0; 9602 WMI_MSDU_FLOW_AST_ENABLE_SET( 9603 resource_cfg->msdu_flow_override_config0, 9604 WMI_CONFIG_MSDU_AST_INDEX_1, 9605 tgt_res_cfg->ast_1_valid_mask_enable); 9606 9607 WMI_MSDU_FLOW_AST_ENABLE_SET( 9608 resource_cfg->msdu_flow_override_config0, 9609 WMI_CONFIG_MSDU_AST_INDEX_2, 9610 tgt_res_cfg->ast_2_valid_mask_enable); 9611 9612 WMI_MSDU_FLOW_AST_ENABLE_SET( 9613 resource_cfg->msdu_flow_override_config0, 9614 WMI_CONFIG_MSDU_AST_INDEX_3, 9615 tgt_res_cfg->ast_3_valid_mask_enable); 9616 9617 /* 9618 * Enable ast flow mask and TID valid mask configurations 9619 */ 9620 resource_cfg->msdu_flow_override_config1 = 0; 9621 9622 /*Enable UDP flow for Ast index 0*/ 9623 WMI_MSDU_FLOW_ASTX_MSDU_FLOW_MASKS_SET( 9624 resource_cfg->msdu_flow_override_config1, 9625 WMI_CONFIG_MSDU_AST_INDEX_0, 9626 tgt_res_cfg->ast_0_flow_mask_enable); 9627 9628 /*Enable Non UDP flow for Ast index 1*/ 9629 WMI_MSDU_FLOW_ASTX_MSDU_FLOW_MASKS_SET( 9630 resource_cfg->msdu_flow_override_config1, 9631 WMI_CONFIG_MSDU_AST_INDEX_1, 9632 tgt_res_cfg->ast_1_flow_mask_enable); 9633 9634 /*Enable Hi-Priority flow for Ast index 2*/ 9635 WMI_MSDU_FLOW_ASTX_MSDU_FLOW_MASKS_SET( 9636 resource_cfg->msdu_flow_override_config1, 9637 WMI_CONFIG_MSDU_AST_INDEX_2, 9638 tgt_res_cfg->ast_2_flow_mask_enable); 9639 9640 /*Enable Low-Priority flow for Ast index 3*/ 9641 WMI_MSDU_FLOW_ASTX_MSDU_FLOW_MASKS_SET( 9642 resource_cfg->msdu_flow_override_config1, 9643 WMI_CONFIG_MSDU_AST_INDEX_3, 9644 tgt_res_cfg->ast_3_flow_mask_enable); 9645 9646 /*Enable all 8 tid for Hi-Pririty Flow Queue*/ 9647 WMI_MSDU_FLOW_TID_VALID_HI_MASKS_SET( 9648 resource_cfg->msdu_flow_override_config1, 9649 tgt_res_cfg->ast_tid_high_mask_enable); 9650 9651 /*Enable all 8 tid for Low-Pririty Flow Queue*/ 9652 WMI_MSDU_FLOW_TID_VALID_LOW_MASKS_SET( 9653 resource_cfg->msdu_flow_override_config1, 9654 tgt_res_cfg->ast_tid_low_mask_enable); 9655 WMI_RSRC_CFG_HOST_SERVICE_FLAG_NAN_IFACE_SUPPORT_SET( 9656 resource_cfg->host_service_flags, 9657 tgt_res_cfg->nan_separate_iface_support); 9658 WMI_RSRC_CFG_HOST_SERVICE_FLAG_HOST_SUPPORT_MULTI_RADIO_EVTS_PER_RADIO_SET( 9659 resource_cfg->host_service_flags, 1); 9660 9661 WMI_RSRC_CFG_FLAG_VIDEO_OVER_WIFI_ENABLE_SET( 9662 resource_cfg->flag1, tgt_res_cfg->carrier_vow_optimization); 9663 9664 if (tgt_res_cfg->is_sap_connected_d3wow_enabled) 9665 WMI_RSRC_CFG_FLAGS2_IS_SAP_CONNECTED_D3WOW_ENABLED_SET( 9666 resource_cfg->flags2, 1); 9667 if (tgt_res_cfg->is_go_connected_d3wow_enabled) 9668 WMI_RSRC_CFG_FLAGS2_IS_GO_CONNECTED_D3WOW_ENABLED_SET( 9669 resource_cfg->flags2, 1); 9670 9671 if (tgt_res_cfg->sae_eapol_offload) 9672 WMI_RSRC_CFG_HOST_SERVICE_FLAG_SAE_EAPOL_OFFLOAD_SUPPORT_SET( 9673 resource_cfg->host_service_flags, 1); 9674 9675 WMI_RSRC_CFG_HOST_SERVICE_FLAG_REG_CC_EXT_SUPPORT_SET( 9676 resource_cfg->host_service_flags, 9677 tgt_res_cfg->is_reg_cc_ext_event_supported); 9678 9679 WMI_RSRC_CFG_HOST_SERVICE_FLAG_BANG_RADAR_320M_SUPPORT_SET( 9680 resource_cfg->host_service_flags, 9681 tgt_res_cfg->is_host_dfs_320mhz_bangradar_supported); 9682 9683 WMI_RSRC_CFG_HOST_SERVICE_FLAG_LPI_SP_MODE_SUPPORT_SET( 9684 resource_cfg->host_service_flags, 9685 tgt_res_cfg->is_6ghz_sp_pwrmode_supp_enabled); 9686 9687 WMI_RSRC_CFG_HOST_SERVICE_FLAG_REG_DISCARD_AFC_TIMER_CHECK_SET( 9688 resource_cfg->host_service_flags, 9689 tgt_res_cfg->afc_timer_check_disable); 9690 9691 WMI_RSRC_CFG_HOST_SERVICE_FLAG_REG_DISCARD_AFC_REQ_ID_CHECK_SET( 9692 resource_cfg->host_service_flags, 9693 tgt_res_cfg->afc_req_id_check_disable); 9694 9695 wmi_copy_afc_deployment_config(resource_cfg, tgt_res_cfg); 9696 9697 wmi_set_nan_channel_support(resource_cfg); 9698 9699 if (tgt_res_cfg->twt_ack_support_cap) 9700 WMI_RSRC_CFG_HOST_SERVICE_FLAG_STA_TWT_SYNC_EVT_SUPPORT_SET( 9701 resource_cfg->host_service_flags, 1); 9702 9703 if (tgt_res_cfg->reo_qdesc_shared_addr_table_enabled) 9704 WMI_RSRC_CFG_HOST_SERVICE_FLAG_REO_QREF_FEATURE_SUPPORT_SET( 9705 resource_cfg->host_service_flags, 1); 9706 /* 9707 * DP Peer Meta data FW version 9708 */ 9709 WMI_RSRC_CFG_FLAGS2_RX_PEER_METADATA_VERSION_SET( 9710 resource_cfg->flags2, 9711 tgt_res_cfg->dp_peer_meta_data_ver); 9712 9713 if (tgt_res_cfg->notify_frame_support) 9714 WMI_RSRC_CFG_FLAGS2_NOTIFY_FRAME_CONFIG_ENABLE_SET( 9715 resource_cfg->flags2, 1); 9716 9717 if (tgt_res_cfg->rf_path) 9718 WMI_RSRC_CFG_FLAGS2_RF_PATH_MODE_SET( 9719 resource_cfg->flags2, tgt_res_cfg->rf_path); 9720 9721 if (tgt_res_cfg->fw_ast_indication_disable) { 9722 WMI_RSRC_CFG_FLAGS2_DISABLE_WDS_PEER_MAP_UNMAP_EVENT_SET 9723 (resource_cfg->flags2, 9724 tgt_res_cfg->fw_ast_indication_disable); 9725 } 9726 9727 wmi_copy_latency_flowq_support(resource_cfg, tgt_res_cfg); 9728 wmi_copy_full_bw_nol_cfg(resource_cfg, tgt_res_cfg); 9729 9730 } 9731 9732 #ifdef FEATURE_SET 9733 /** 9734 * convert_host_to_target_vendor1_req2_version() -Convert host vendor1 9735 * requirement2 version to target vendor1 requirement2 version 9736 * @vendor1_req2_ver: Host vendor1 requirement2 version 9737 * 9738 * Return: Target vendor1 requirement2 version 9739 */ 9740 static WMI_VENDOR1_REQ2_VERSION convert_host_to_target_vendor1_req2_version( 9741 WMI_HOST_VENDOR1_REQ2_VERSION vendor1_req2_ver) 9742 { 9743 switch (vendor1_req2_ver) { 9744 case WMI_HOST_VENDOR1_REQ2_VERSION_3_00: 9745 return WMI_VENDOR1_REQ2_VERSION_3_00; 9746 case WMI_HOST_VENDOR1_REQ2_VERSION_3_01: 9747 return WMI_VENDOR1_REQ2_VERSION_3_01; 9748 case WMI_HOST_VENDOR1_REQ2_VERSION_3_20: 9749 return WMI_VENDOR1_REQ2_VERSION_3_20; 9750 case WMI_HOST_VENDOR1_REQ2_VERSION_3_50: 9751 return WMI_VENDOR1_REQ2_VERSION_3_50; 9752 default: 9753 return WMI_VENDOR1_REQ2_VERSION_3_00; 9754 } 9755 } 9756 9757 /** 9758 * convert_host_to_target_vendor1_req1_version() -Convert host vendor1 9759 * requirement1 version to target vendor1 requirement1 version 9760 * @vendor1_req1_ver: Host vendor1 requirement1 version 9761 * 9762 * Return: Target vendor1 requirement1 version 9763 */ 9764 static WMI_VENDOR1_REQ1_VERSION convert_host_to_target_vendor1_req1_version( 9765 WMI_HOST_VENDOR1_REQ1_VERSION vendor1_req1_ver) 9766 { 9767 switch (vendor1_req1_ver) { 9768 case WMI_HOST_VENDOR1_REQ1_VERSION_3_00: 9769 return WMI_VENDOR1_REQ1_VERSION_3_00; 9770 case WMI_HOST_VENDOR1_REQ1_VERSION_3_01: 9771 return WMI_VENDOR1_REQ1_VERSION_3_01; 9772 case WMI_HOST_VENDOR1_REQ1_VERSION_3_20: 9773 return WMI_VENDOR1_REQ1_VERSION_3_20; 9774 case WMI_HOST_VENDOR1_REQ1_VERSION_3_30: 9775 return WMI_VENDOR1_REQ1_VERSION_3_30; 9776 case WMI_HOST_VENDOR1_REQ1_VERSION_3_40: 9777 return WMI_VENDOR1_REQ1_VERSION_3_40; 9778 case WMI_HOST_VENDOR1_REQ1_VERSION_4_00: 9779 return WMI_VENDOR1_REQ1_VERSION_4_00; 9780 default: 9781 return WMI_VENDOR1_REQ1_VERSION_3_00; 9782 } 9783 } 9784 9785 /** 9786 * convert_host_to_target_wifi_standard() -Convert host wifi standard to 9787 * target wifi standard 9788 * @wifi_standard: Host wifi standard 9789 * 9790 * Return: Target wifi standard 9791 */ 9792 static WMI_WIFI_STANDARD convert_host_to_target_wifi_standard( 9793 WMI_HOST_WIFI_STANDARD wifi_standard) 9794 { 9795 switch (wifi_standard) { 9796 case WMI_HOST_WIFI_STANDARD_4: 9797 return WMI_WIFI_STANDARD_4; 9798 case WMI_HOST_WIFI_STANDARD_5: 9799 return WMI_WIFI_STANDARD_5; 9800 case WMI_HOST_WIFI_STANDARD_6: 9801 return WMI_WIFI_STANDARD_6; 9802 case WMI_HOST_WIFI_STANDARD_6E: 9803 return WMI_WIFI_STANDARD_6E; 9804 case WMI_HOST_WIFI_STANDARD_7: 9805 return WMI_WIFI_STANDARD_7; 9806 default: 9807 return WMI_WIFI_STANDARD_4; 9808 } 9809 } 9810 9811 /** 9812 * convert_host_to_target_band_concurrency() -Convert host band concurrency to 9813 * target band concurrency 9814 * @band_concurrency: Host Band concurrency 9815 * 9816 * Return: Target band concurrency 9817 */ 9818 static WMI_BAND_CONCURRENCY convert_host_to_target_band_concurrency( 9819 WMI_HOST_BAND_CONCURRENCY band_concurrency) 9820 { 9821 switch (band_concurrency) { 9822 case WMI_HOST_BAND_CONCURRENCY_DBS: 9823 return WMI_HOST_DBS; 9824 case WMI_HOST_BAND_CONCURRENCY_DBS_SBS: 9825 return WMI_HOST_DBS_SBS; 9826 default: 9827 return WMI_HOST_NONE; 9828 } 9829 } 9830 9831 /** 9832 * convert_host_to_target_num_antennas() -Convert host num antennas to 9833 * target num antennas 9834 * @num_antennas: Host num antennas 9835 * 9836 * Return: Target num antennas 9837 */ 9838 static WMI_NUM_ANTENNAS convert_host_to_target_num_antennas( 9839 WMI_HOST_NUM_ANTENNAS num_antennas) 9840 { 9841 switch (num_antennas) { 9842 case WMI_HOST_SISO: 9843 return WMI_SISO; 9844 case WMI_HOST_MIMO_2X2: 9845 return WMI_MIMO_2X2; 9846 default: 9847 return WMI_SISO; 9848 } 9849 } 9850 9851 /** 9852 * convert_host_to_target_band_capability() -Convert host band capability to 9853 * target band capability 9854 * @host_band_capability: Host band capability 9855 * 9856 * Return: Target band capability bitmap 9857 */ 9858 static uint8_t 9859 convert_host_to_target_band_capability(uint32_t host_band_capability) 9860 { 9861 uint8_t band_capability; 9862 9863 band_capability = (host_band_capability & WMI_HOST_BAND_CAP_2GHZ) | 9864 (host_band_capability & WMI_HOST_BAND_CAP_5GHZ) | 9865 (host_band_capability & WMI_HOST_BAND_CAP_6GHZ); 9866 return band_capability; 9867 } 9868 9869 /** 9870 * copy_feature_set_info() -Copy feature set info from host to target 9871 * @feature_set_bitmap: Target feature set pointer 9872 * @feature_set: Host feature set structure 9873 * 9874 * Return: None 9875 */ 9876 static inline void copy_feature_set_info(uint32_t *feature_set_bitmap, 9877 struct target_feature_set *feature_set) 9878 { 9879 WMI_NUM_ANTENNAS num_antennas; 9880 WMI_BAND_CONCURRENCY band_concurrency; 9881 WMI_WIFI_STANDARD wifi_standard; 9882 WMI_VENDOR1_REQ1_VERSION vendor1_req1_version; 9883 WMI_VENDOR1_REQ2_VERSION vendor1_req2_version; 9884 uint8_t band_capability; 9885 9886 num_antennas = convert_host_to_target_num_antennas( 9887 feature_set->num_antennas); 9888 band_concurrency = convert_host_to_target_band_concurrency( 9889 feature_set->concurrency_support); 9890 wifi_standard = convert_host_to_target_wifi_standard( 9891 feature_set->wifi_standard); 9892 vendor1_req1_version = convert_host_to_target_vendor1_req1_version( 9893 feature_set->vendor_req_1_version); 9894 vendor1_req2_version = convert_host_to_target_vendor1_req2_version( 9895 feature_set->vendor_req_2_version); 9896 9897 band_capability = 9898 convert_host_to_target_band_capability( 9899 feature_set->band_capability); 9900 9901 WMI_SET_WIFI_STANDARD(feature_set_bitmap, wifi_standard); 9902 WMI_SET_BAND_CONCURRENCY_SUPPORT(feature_set_bitmap, band_concurrency); 9903 WMI_SET_PNO_SCAN_IN_UNASSOC_STATE(feature_set_bitmap, 9904 feature_set->pno_in_unassoc_state); 9905 WMI_SET_PNO_SCAN_IN_ASSOC_STATE(feature_set_bitmap, 9906 feature_set->pno_in_assoc_state); 9907 WMI_SET_TWT_FEATURE_SUPPORT(feature_set_bitmap, 9908 feature_set->enable_twt); 9909 WMI_SET_TWT_REQUESTER(feature_set_bitmap, 9910 feature_set->enable_twt_requester); 9911 WMI_SET_TWT_BROADCAST(feature_set_bitmap, 9912 feature_set->enable_twt_broadcast); 9913 WMI_SET_TWT_FLEXIBLE(feature_set_bitmap, 9914 feature_set->enable_twt_flexible); 9915 WMI_SET_WIFI_OPT_FEATURE_SUPPORT(feature_set_bitmap, 9916 feature_set->enable_wifi_optimizer); 9917 WMI_SET_RFC8325_FEATURE_SUPPORT(feature_set_bitmap, 9918 feature_set->enable_rfc835); 9919 WMI_SET_MHS_5G_SUPPORT(feature_set_bitmap, 9920 feature_set->sap_5g_supported); 9921 WMI_SET_MHS_6G_SUPPORT(feature_set_bitmap, 9922 feature_set->sap_6g_supported); 9923 WMI_SET_MHS_MAX_CLIENTS_SUPPORT(feature_set_bitmap, 9924 feature_set->sap_max_num_clients); 9925 WMI_SET_MHS_SET_COUNTRY_CODE_HAL_SUPPORT( 9926 feature_set_bitmap, 9927 feature_set->set_country_code_hal_supported); 9928 WMI_SET_MHS_GETVALID_CHANNELS_SUPPORT( 9929 feature_set_bitmap, 9930 feature_set->get_valid_channel_supported); 9931 WMI_SET_MHS_DOT11_MODE_SUPPORT(feature_set_bitmap, 9932 feature_set->supported_dot11mode); 9933 WMI_SET_MHS_WPA3_SUPPORT(feature_set_bitmap, 9934 feature_set->sap_wpa3_support); 9935 WMI_SET_VENDOR_REQ_1_VERSION(feature_set_bitmap, vendor1_req1_version); 9936 WMI_SET_ROAMING_HIGH_CU_ROAM_TRIGGER( 9937 feature_set_bitmap, 9938 feature_set->roaming_high_cu_roam_trigger); 9939 WMI_SET_ROAMING_EMERGENCY_TRIGGER( 9940 feature_set_bitmap, 9941 feature_set->roaming_emergency_trigger); 9942 WMI_SET_ROAMING_BTM_TRIGGER(feature_set_bitmap, 9943 feature_set->roaming_btm_trihgger); 9944 WMI_SET_ROAMING_IDLE_TRIGGER(feature_set_bitmap, 9945 feature_set->roaming_idle_trigger); 9946 WMI_SET_ROAMING_WTC_TRIGGER(feature_set_bitmap, 9947 feature_set->roaming_wtc_trigger); 9948 WMI_SET_ROAMING_BTCOEX_TRIGGER(feature_set_bitmap, 9949 feature_set->roaming_btcoex_trigger); 9950 WMI_SET_ROAMING_BTW_WPA_WPA2(feature_set_bitmap, 9951 feature_set->roaming_btw_wpa_wpa2); 9952 WMI_SET_ROAMING_MANAGE_CHAN_LIST_API( 9953 feature_set_bitmap, 9954 feature_set->roaming_manage_chan_list_api); 9955 WMI_SET_ROAMING_ADAPTIVE_11R(feature_set_bitmap, 9956 feature_set->roaming_adaptive_11r); 9957 WMI_SET_ROAMING_CTRL_API_GET_SET(feature_set_bitmap, 9958 feature_set->roaming_ctrl_api_get_set); 9959 WMI_SET_ROAMING_CTRL_API_REASSOC(feature_set_bitmap, 9960 feature_set->roaming_ctrl_api_reassoc); 9961 WMI_SET_ROAMING_CTRL_GET_CU(feature_set_bitmap, 9962 feature_set->roaming_ctrl_get_cu); 9963 WMI_SET_VENDOR_REQ_2_VERSION(feature_set_bitmap, vendor1_req2_version); 9964 WMI_SET_ASSURANCE_DISCONNECT_REASON_API( 9965 feature_set_bitmap, 9966 feature_set->assurance_disconnect_reason_api); 9967 WMI_SET_FRAME_PCAP_LOG_MGMT(feature_set_bitmap, 9968 feature_set->frame_pcap_log_mgmt); 9969 WMI_SET_FRAME_PCAP_LOG_CTRL(feature_set_bitmap, 9970 feature_set->frame_pcap_log_ctrl); 9971 WMI_SET_FRAME_PCAP_LOG_DATA(feature_set_bitmap, 9972 feature_set->frame_pcap_log_data); 9973 WMI_SET_SECURITY_WPA3_SAE_H2E(feature_set_bitmap, 9974 feature_set->security_wpa3_sae_h2e); 9975 WMI_SET_SECURITY_WPA3_SAE_FT(feature_set_bitmap, 9976 feature_set->security_wpa3_sae_ft); 9977 WMI_SET_SECURITY_WPA3_ENTERP_SUITEB( 9978 feature_set_bitmap, 9979 feature_set->security_wpa3_enterp_suitb); 9980 WMI_SET_SECURITY_WPA3_ENTERP_SUITEB_192bit( 9981 feature_set_bitmap, 9982 feature_set->security_wpa3_enterp_suitb_192bit); 9983 WMI_SET_SECURITY_FILS_SHA256(feature_set_bitmap, 9984 feature_set->security_fills_sha_256); 9985 WMI_SET_SECURITY_FILS_SHA384(feature_set_bitmap, 9986 feature_set->security_fills_sha_384); 9987 WMI_SET_SECURITY_FILS_SHA256_FT(feature_set_bitmap, 9988 feature_set->security_fills_sha_256_FT); 9989 WMI_SET_SECURITY_FILS_SHA384_FT(feature_set_bitmap, 9990 feature_set->security_fills_sha_384_FT); 9991 WMI_SET_SECURITY_ENCHANCED_OPEN(feature_set_bitmap, 9992 feature_set->security_enhanced_open); 9993 WMI_SET_NAN_SUPPORT(feature_set_bitmap, feature_set->enable_nan); 9994 WMI_SET_TDLS_SUPPORT(feature_set_bitmap, feature_set->enable_tdls); 9995 WMI_SET_P2P6E_SUPPORT(feature_set_bitmap, feature_set->enable_p2p_6e); 9996 WMI_SET_TDLS_OFFCHAN_SUPPORT(feature_set_bitmap, 9997 feature_set->enable_tdls_offchannel); 9998 WMI_SET_TDLS_CAP_ENHANCE(feature_set_bitmap, 9999 feature_set->enable_tdls_capability_enhance); 10000 WMI_SET_MAX_TDLS_PEERS_SUPPORT(feature_set_bitmap, 10001 feature_set->max_tdls_peers); 10002 WMI_SET_STA_DUAL_P2P_SUPPORT(feature_set_bitmap, 10003 feature_set->sta_dual_p2p_support); 10004 WMI_SET_PEER_BIGDATA_GETBSSINFO_API_SUPPORT( 10005 feature_set_bitmap, 10006 feature_set->peer_bigdata_getbssinfo_support); 10007 WMI_SET_PEER_BIGDATA_GETASSOCREJECTINFO_API_SUPPORT( 10008 feature_set_bitmap, 10009 feature_set->peer_bigdata_assocreject_info_support); 10010 WMI_SET_PEER_BIGDATA_GETSTAINFO_API_SUPPORT( 10011 feature_set_bitmap, 10012 feature_set->peer_getstainfo_support); 10013 WMI_SET_FEATURE_SET_VERSION(feature_set_bitmap, 10014 feature_set->feature_set_version); 10015 WMI_SET_NUM_ANTENNAS(feature_set_bitmap, num_antennas); 10016 WMI_SET_HOST_BAND_CAP(feature_set_bitmap, band_capability); 10017 WMI_SET_STA_DUMP_SUPPORT(feature_set_bitmap, 10018 feature_set->sta_dump_support); 10019 } 10020 10021 /** 10022 * feature_set_cmd_send_tlv() -Send feature set command 10023 * @wmi_handle: WMI handle 10024 * @feature_set: Feature set structure 10025 * 10026 * Return: QDF_STATUS_SUCCESS on success else return failure 10027 */ 10028 static QDF_STATUS feature_set_cmd_send_tlv( 10029 struct wmi_unified *wmi_handle, 10030 struct target_feature_set *feature_set) 10031 { 10032 wmi_pdev_featureset_cmd_fixed_param *cmd; 10033 wmi_buf_t buf; 10034 uint16_t len; 10035 QDF_STATUS ret; 10036 uint8_t *buf_ptr; 10037 uint32_t *feature_set_bitmap; 10038 10039 len = sizeof(*cmd) + WMI_TLV_HDR_SIZE + 10040 WMI_FEATURE_SET_BITMAP_ARRAY_LEN32 * sizeof(uint32_t); 10041 buf = wmi_buf_alloc(wmi_handle, len); 10042 10043 if (!buf) 10044 return QDF_STATUS_E_NOMEM; 10045 10046 wmi_debug("Send feature set param"); 10047 10048 buf_ptr = (uint8_t *)wmi_buf_data(buf); 10049 10050 cmd = (wmi_pdev_featureset_cmd_fixed_param *)wmi_buf_data(buf); 10051 10052 WMITLV_SET_HDR(&cmd->tlv_header, 10053 WMITLV_TAG_STRUC_wmi_pdev_featureset_cmd_fixed_param, 10054 WMITLV_GET_STRUCT_TLVLEN( 10055 wmi_pdev_featureset_cmd_fixed_param)); 10056 10057 feature_set_bitmap = (uint32_t *)(buf_ptr + sizeof(*cmd) + 10058 WMI_TLV_HDR_SIZE); 10059 WMITLV_SET_HDR(buf_ptr + sizeof(*cmd), WMITLV_TAG_ARRAY_UINT32, 10060 (WMI_FEATURE_SET_BITMAP_ARRAY_LEN32 * sizeof(uint32_t))); 10061 copy_feature_set_info(feature_set_bitmap, feature_set); 10062 10063 qdf_trace_hex_dump(QDF_MODULE_ID_WMI, QDF_TRACE_LEVEL_DEBUG, 10064 feature_set_bitmap, 10065 WMI_FEATURE_SET_BITMAP_ARRAY_LEN32 * 10066 sizeof(uint32_t)); 10067 10068 wmi_mtrace(WMI_PDEV_FEATURESET_CMDID, NO_SESSION, 0); 10069 10070 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 10071 WMI_PDEV_FEATURESET_CMDID); 10072 if (QDF_IS_STATUS_ERROR(ret)) 10073 wmi_buf_free(buf); 10074 10075 return ret; 10076 } 10077 #endif 10078 10079 /* copy_hw_mode_id_in_init_cmd() - Helper routine to copy hw_mode in init cmd 10080 * @wmi_handle: pointer to wmi handle 10081 * @buf_ptr: pointer to current position in init command buffer 10082 * @len: pointer to length. This will be updated with current length of cmd 10083 * @param: point host parameters for init command 10084 * 10085 * Return: Updated pointer of buf_ptr. 10086 */ 10087 static inline uint8_t *copy_hw_mode_in_init_cmd(struct wmi_unified *wmi_handle, 10088 uint8_t *buf_ptr, int *len, struct wmi_init_cmd_param *param) 10089 { 10090 uint16_t idx; 10091 10092 if (param->hw_mode_id != WMI_HOST_HW_MODE_MAX) { 10093 wmi_pdev_set_hw_mode_cmd_fixed_param *hw_mode; 10094 wmi_pdev_band_to_mac *band_to_mac; 10095 10096 hw_mode = (wmi_pdev_set_hw_mode_cmd_fixed_param *) 10097 (buf_ptr + sizeof(wmi_init_cmd_fixed_param) + 10098 sizeof(wmi_resource_config) + 10099 WMI_TLV_HDR_SIZE + (param->num_mem_chunks * 10100 sizeof(wlan_host_memory_chunk))); 10101 10102 WMITLV_SET_HDR(&hw_mode->tlv_header, 10103 WMITLV_TAG_STRUC_wmi_pdev_set_hw_mode_cmd_fixed_param, 10104 (WMITLV_GET_STRUCT_TLVLEN 10105 (wmi_pdev_set_hw_mode_cmd_fixed_param))); 10106 10107 hw_mode->hw_mode_index = param->hw_mode_id; 10108 hw_mode->num_band_to_mac = param->num_band_to_mac; 10109 10110 buf_ptr = (uint8_t *) (hw_mode + 1); 10111 band_to_mac = (wmi_pdev_band_to_mac *) (buf_ptr + 10112 WMI_TLV_HDR_SIZE); 10113 for (idx = 0; idx < param->num_band_to_mac; idx++) { 10114 WMITLV_SET_HDR(&band_to_mac[idx].tlv_header, 10115 WMITLV_TAG_STRUC_wmi_pdev_band_to_mac, 10116 WMITLV_GET_STRUCT_TLVLEN 10117 (wmi_pdev_band_to_mac)); 10118 band_to_mac[idx].pdev_id = 10119 wmi_handle->ops->convert_pdev_id_host_to_target( 10120 wmi_handle, 10121 param->band_to_mac[idx].pdev_id); 10122 band_to_mac[idx].start_freq = 10123 param->band_to_mac[idx].start_freq; 10124 band_to_mac[idx].end_freq = 10125 param->band_to_mac[idx].end_freq; 10126 } 10127 *len += sizeof(wmi_pdev_set_hw_mode_cmd_fixed_param) + 10128 (param->num_band_to_mac * 10129 sizeof(wmi_pdev_band_to_mac)) + 10130 WMI_TLV_HDR_SIZE; 10131 10132 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 10133 (param->num_band_to_mac * 10134 sizeof(wmi_pdev_band_to_mac))); 10135 } 10136 10137 return buf_ptr; 10138 } 10139 10140 static inline void copy_fw_abi_version_tlv(wmi_unified_t wmi_handle, 10141 wmi_init_cmd_fixed_param *cmd) 10142 { 10143 int num_allowlist; 10144 wmi_abi_version my_vers; 10145 10146 num_allowlist = sizeof(version_whitelist) / 10147 sizeof(wmi_whitelist_version_info); 10148 my_vers.abi_version_0 = WMI_ABI_VERSION_0; 10149 my_vers.abi_version_1 = WMI_ABI_VERSION_1; 10150 my_vers.abi_version_ns_0 = WMI_ABI_VERSION_NS_0; 10151 my_vers.abi_version_ns_1 = WMI_ABI_VERSION_NS_1; 10152 my_vers.abi_version_ns_2 = WMI_ABI_VERSION_NS_2; 10153 my_vers.abi_version_ns_3 = WMI_ABI_VERSION_NS_3; 10154 10155 wmi_cmp_and_set_abi_version(num_allowlist, version_whitelist, 10156 &my_vers, 10157 (struct _wmi_abi_version *)&wmi_handle->fw_abi_version, 10158 &cmd->host_abi_vers); 10159 10160 qdf_debug("INIT_CMD version: %d, %d, 0x%x, 0x%x, 0x%x, 0x%x", 10161 WMI_VER_GET_MAJOR(cmd->host_abi_vers.abi_version_0), 10162 WMI_VER_GET_MINOR(cmd->host_abi_vers.abi_version_0), 10163 cmd->host_abi_vers.abi_version_ns_0, 10164 cmd->host_abi_vers.abi_version_ns_1, 10165 cmd->host_abi_vers.abi_version_ns_2, 10166 cmd->host_abi_vers.abi_version_ns_3); 10167 10168 /* Save version sent from host - 10169 * Will be used to check ready event 10170 */ 10171 qdf_mem_copy(&wmi_handle->final_abi_vers, &cmd->host_abi_vers, 10172 sizeof(wmi_abi_version)); 10173 } 10174 10175 /* 10176 * send_cfg_action_frm_tb_ppdu_cmd_tlv() - send action frame tb ppdu cfg to FW 10177 * @wmi_handle: Pointer to WMi handle 10178 * @ie_data: Pointer for ie data 10179 * 10180 * This function sends action frame tb ppdu cfg to FW 10181 * 10182 * Return: QDF_STATUS_SUCCESS for success otherwise failure 10183 * 10184 */ 10185 static QDF_STATUS send_cfg_action_frm_tb_ppdu_cmd_tlv(wmi_unified_t wmi_handle, 10186 struct cfg_action_frm_tb_ppdu_param *cfg_msg) 10187 { 10188 wmi_pdev_he_tb_action_frm_cmd_fixed_param *cmd; 10189 wmi_buf_t buf; 10190 uint8_t *buf_ptr; 10191 uint32_t len, frm_len_aligned; 10192 QDF_STATUS ret; 10193 10194 frm_len_aligned = roundup(cfg_msg->frm_len, sizeof(uint32_t)); 10195 /* Allocate memory for the WMI command */ 10196 len = sizeof(*cmd) + WMI_TLV_HDR_SIZE + frm_len_aligned; 10197 10198 buf = wmi_buf_alloc(wmi_handle, len); 10199 if (!buf) 10200 return QDF_STATUS_E_NOMEM; 10201 10202 buf_ptr = wmi_buf_data(buf); 10203 qdf_mem_zero(buf_ptr, len); 10204 10205 /* Populate the WMI command */ 10206 cmd = (wmi_pdev_he_tb_action_frm_cmd_fixed_param *)buf_ptr; 10207 10208 WMITLV_SET_HDR(&cmd->tlv_header, 10209 WMITLV_TAG_STRUC_wmi_pdev_he_tb_action_frm_cmd_fixed_param, 10210 WMITLV_GET_STRUCT_TLVLEN( 10211 wmi_pdev_he_tb_action_frm_cmd_fixed_param)); 10212 cmd->enable = cfg_msg->cfg; 10213 cmd->data_len = cfg_msg->frm_len; 10214 10215 buf_ptr += sizeof(*cmd); 10216 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, frm_len_aligned); 10217 buf_ptr += WMI_TLV_HDR_SIZE; 10218 10219 qdf_mem_copy(buf_ptr, cfg_msg->data, cmd->data_len); 10220 10221 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 10222 WMI_PDEV_HE_TB_ACTION_FRM_CMDID); 10223 if (QDF_IS_STATUS_ERROR(ret)) { 10224 wmi_err("HE TB action frame cmnd send fail, ret %d", ret); 10225 wmi_buf_free(buf); 10226 } 10227 10228 return ret; 10229 } 10230 10231 static QDF_STATUS save_fw_version_cmd_tlv(wmi_unified_t wmi_handle, void *evt_buf) 10232 { 10233 WMI_SERVICE_READY_EVENTID_param_tlvs *param_buf; 10234 wmi_service_ready_event_fixed_param *ev; 10235 10236 10237 param_buf = (WMI_SERVICE_READY_EVENTID_param_tlvs *) evt_buf; 10238 10239 ev = (wmi_service_ready_event_fixed_param *) param_buf->fixed_param; 10240 if (!ev) 10241 return QDF_STATUS_E_FAILURE; 10242 10243 /*Save fw version from service ready message */ 10244 /*This will be used while sending INIT message */ 10245 qdf_mem_copy(&wmi_handle->fw_abi_version, &ev->fw_abi_vers, 10246 sizeof(wmi_handle->fw_abi_version)); 10247 10248 return QDF_STATUS_SUCCESS; 10249 } 10250 10251 /** 10252 * check_and_update_fw_version_cmd_tlv() - save fw version 10253 * @wmi_handle: pointer to wmi handle 10254 * @evt_buf: pointer to the event buffer 10255 * 10256 * This function extracts and saves the firmware WMI ABI version 10257 * 10258 * Return: QDF_STATUS_SUCCESS for success otherwise failure 10259 * 10260 */ 10261 static QDF_STATUS check_and_update_fw_version_cmd_tlv(wmi_unified_t wmi_handle, 10262 void *evt_buf) 10263 { 10264 WMI_READY_EVENTID_param_tlvs *param_buf = NULL; 10265 wmi_ready_event_fixed_param *ev = NULL; 10266 10267 param_buf = (WMI_READY_EVENTID_param_tlvs *) evt_buf; 10268 ev = param_buf->fixed_param; 10269 if (!wmi_versions_are_compatible((struct _wmi_abi_version *) 10270 &wmi_handle->final_abi_vers, 10271 &ev->fw_abi_vers)) { 10272 /* 10273 * Error: Our host version and the given firmware version 10274 * are incompatible. 10275 **/ 10276 wmi_debug("Error: Incompatible WMI version." 10277 "Host: %d,%d,0x%x 0x%x 0x%x 0x%x, FW: %d,%d,0x%x 0x%x 0x%x 0x%x", 10278 WMI_VER_GET_MAJOR(wmi_handle->final_abi_vers. 10279 abi_version_0), 10280 WMI_VER_GET_MINOR(wmi_handle->final_abi_vers. 10281 abi_version_0), 10282 wmi_handle->final_abi_vers.abi_version_ns_0, 10283 wmi_handle->final_abi_vers.abi_version_ns_1, 10284 wmi_handle->final_abi_vers.abi_version_ns_2, 10285 wmi_handle->final_abi_vers.abi_version_ns_3, 10286 WMI_VER_GET_MAJOR(ev->fw_abi_vers.abi_version_0), 10287 WMI_VER_GET_MINOR(ev->fw_abi_vers.abi_version_0), 10288 ev->fw_abi_vers.abi_version_ns_0, 10289 ev->fw_abi_vers.abi_version_ns_1, 10290 ev->fw_abi_vers.abi_version_ns_2, 10291 ev->fw_abi_vers.abi_version_ns_3); 10292 10293 return QDF_STATUS_E_FAILURE; 10294 } 10295 qdf_mem_copy(&wmi_handle->final_abi_vers, &ev->fw_abi_vers, 10296 sizeof(wmi_abi_version)); 10297 qdf_mem_copy(&wmi_handle->fw_abi_version, &ev->fw_abi_vers, 10298 sizeof(wmi_abi_version)); 10299 10300 return QDF_STATUS_SUCCESS; 10301 } 10302 10303 /** 10304 * send_log_supported_evt_cmd_tlv() - Enable/Disable FW diag/log events 10305 * @wmi_handle: wmi handle 10306 * @event: Event received from FW 10307 * @len: Length of the event 10308 * 10309 * Enables the low frequency events and disables the high frequency 10310 * events. Bit 17 indicates if the event if low/high frequency. 10311 * 1 - high frequency, 0 - low frequency 10312 * 10313 * Return: QDF_STATUS_SUCCESS for success or error code 10314 */ 10315 static QDF_STATUS send_log_supported_evt_cmd_tlv(wmi_unified_t wmi_handle, 10316 uint8_t *event, 10317 uint32_t len) 10318 { 10319 uint32_t num_of_diag_events_logs; 10320 wmi_diag_event_log_config_fixed_param *cmd; 10321 wmi_buf_t buf; 10322 uint8_t *buf_ptr; 10323 uint32_t *cmd_args, *evt_args; 10324 uint32_t buf_len, i; 10325 10326 WMI_DIAG_EVENT_LOG_SUPPORTED_EVENTID_param_tlvs *param_buf; 10327 wmi_diag_event_log_supported_event_fixed_params *wmi_event; 10328 10329 wmi_debug("Received WMI_DIAG_EVENT_LOG_SUPPORTED_EVENTID"); 10330 10331 param_buf = (WMI_DIAG_EVENT_LOG_SUPPORTED_EVENTID_param_tlvs *) event; 10332 if (!param_buf) { 10333 wmi_err("Invalid log supported event buffer"); 10334 return QDF_STATUS_E_INVAL; 10335 } 10336 wmi_event = param_buf->fixed_param; 10337 num_of_diag_events_logs = wmi_event->num_of_diag_events_logs; 10338 10339 if (num_of_diag_events_logs > 10340 param_buf->num_diag_events_logs_list) { 10341 wmi_err("message number of events %d is more than tlv hdr content %d", 10342 num_of_diag_events_logs, 10343 param_buf->num_diag_events_logs_list); 10344 return QDF_STATUS_E_INVAL; 10345 } 10346 10347 evt_args = param_buf->diag_events_logs_list; 10348 if (!evt_args) { 10349 wmi_err("Event list is empty, num_of_diag_events_logs=%d", 10350 num_of_diag_events_logs); 10351 return QDF_STATUS_E_INVAL; 10352 } 10353 10354 wmi_debug("num_of_diag_events_logs=%d", num_of_diag_events_logs); 10355 10356 /* Free any previous allocation */ 10357 if (wmi_handle->events_logs_list) { 10358 qdf_mem_free(wmi_handle->events_logs_list); 10359 wmi_handle->events_logs_list = NULL; 10360 } 10361 10362 if (num_of_diag_events_logs > 10363 (WMI_SVC_MSG_MAX_SIZE / sizeof(uint32_t))) { 10364 wmi_err("excess num of logs: %d", num_of_diag_events_logs); 10365 QDF_ASSERT(0); 10366 return QDF_STATUS_E_INVAL; 10367 } 10368 /* Store the event list for run time enable/disable */ 10369 wmi_handle->events_logs_list = qdf_mem_malloc(num_of_diag_events_logs * 10370 sizeof(uint32_t)); 10371 if (!wmi_handle->events_logs_list) 10372 return QDF_STATUS_E_NOMEM; 10373 10374 wmi_handle->num_of_diag_events_logs = num_of_diag_events_logs; 10375 10376 /* Prepare the send buffer */ 10377 buf_len = sizeof(*cmd) + WMI_TLV_HDR_SIZE + 10378 (num_of_diag_events_logs * sizeof(uint32_t)); 10379 10380 buf = wmi_buf_alloc(wmi_handle, buf_len); 10381 if (!buf) { 10382 qdf_mem_free(wmi_handle->events_logs_list); 10383 wmi_handle->events_logs_list = NULL; 10384 return QDF_STATUS_E_NOMEM; 10385 } 10386 10387 cmd = (wmi_diag_event_log_config_fixed_param *) wmi_buf_data(buf); 10388 buf_ptr = (uint8_t *) cmd; 10389 10390 WMITLV_SET_HDR(&cmd->tlv_header, 10391 WMITLV_TAG_STRUC_wmi_diag_event_log_config_fixed_param, 10392 WMITLV_GET_STRUCT_TLVLEN( 10393 wmi_diag_event_log_config_fixed_param)); 10394 10395 cmd->num_of_diag_events_logs = num_of_diag_events_logs; 10396 10397 buf_ptr += sizeof(wmi_diag_event_log_config_fixed_param); 10398 10399 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, 10400 (num_of_diag_events_logs * sizeof(uint32_t))); 10401 10402 cmd_args = (uint32_t *) (buf_ptr + WMI_TLV_HDR_SIZE); 10403 10404 /* Populate the events */ 10405 for (i = 0; i < num_of_diag_events_logs; i++) { 10406 /* Low freq (0) - Enable (1) the event 10407 * High freq (1) - Disable (0) the event 10408 */ 10409 WMI_DIAG_ID_ENABLED_DISABLED_SET(cmd_args[i], 10410 !(WMI_DIAG_FREQUENCY_GET(evt_args[i]))); 10411 /* Set the event ID */ 10412 WMI_DIAG_ID_SET(cmd_args[i], 10413 WMI_DIAG_ID_GET(evt_args[i])); 10414 /* Set the type */ 10415 WMI_DIAG_TYPE_SET(cmd_args[i], 10416 WMI_DIAG_TYPE_GET(evt_args[i])); 10417 /* Storing the event/log list in WMI */ 10418 wmi_handle->events_logs_list[i] = evt_args[i]; 10419 } 10420 10421 wmi_mtrace(WMI_DIAG_EVENT_LOG_CONFIG_CMDID, NO_SESSION, 0); 10422 if (wmi_unified_cmd_send(wmi_handle, buf, buf_len, 10423 WMI_DIAG_EVENT_LOG_CONFIG_CMDID)) { 10424 wmi_err("WMI_DIAG_EVENT_LOG_CONFIG_CMDID failed"); 10425 wmi_buf_free(buf); 10426 /* Not clearing events_logs_list, though wmi cmd failed. 10427 * Host can still have this list 10428 */ 10429 return QDF_STATUS_E_INVAL; 10430 } 10431 10432 return 0; 10433 } 10434 10435 /** 10436 * send_enable_specific_fw_logs_cmd_tlv() - Start/Stop logging of diag log id 10437 * @wmi_handle: wmi handle 10438 * @start_log: Start logging related parameters 10439 * 10440 * Send the command to the FW based on which specific logging of diag 10441 * event/log id can be started/stopped 10442 * 10443 * Return: None 10444 */ 10445 static QDF_STATUS send_enable_specific_fw_logs_cmd_tlv(wmi_unified_t wmi_handle, 10446 struct wmi_wifi_start_log *start_log) 10447 { 10448 wmi_diag_event_log_config_fixed_param *cmd; 10449 wmi_buf_t buf; 10450 uint8_t *buf_ptr; 10451 uint32_t len, count, log_level, i; 10452 uint32_t *cmd_args; 10453 uint32_t total_len; 10454 count = 0; 10455 10456 if (!wmi_handle->events_logs_list) { 10457 wmi_debug("Not received event/log list from FW, yet"); 10458 return QDF_STATUS_E_NOMEM; 10459 } 10460 /* total_len stores the number of events where BITS 17 and 18 are set. 10461 * i.e., events of high frequency (17) and for extended debugging (18) 10462 */ 10463 total_len = 0; 10464 for (i = 0; i < wmi_handle->num_of_diag_events_logs; i++) { 10465 if ((WMI_DIAG_FREQUENCY_GET(wmi_handle->events_logs_list[i])) && 10466 (WMI_DIAG_EXT_FEATURE_GET(wmi_handle->events_logs_list[i]))) 10467 total_len++; 10468 } 10469 10470 len = sizeof(*cmd) + WMI_TLV_HDR_SIZE + 10471 (total_len * sizeof(uint32_t)); 10472 10473 buf = wmi_buf_alloc(wmi_handle, len); 10474 if (!buf) 10475 return QDF_STATUS_E_NOMEM; 10476 10477 cmd = (wmi_diag_event_log_config_fixed_param *) wmi_buf_data(buf); 10478 buf_ptr = (uint8_t *) cmd; 10479 10480 WMITLV_SET_HDR(&cmd->tlv_header, 10481 WMITLV_TAG_STRUC_wmi_diag_event_log_config_fixed_param, 10482 WMITLV_GET_STRUCT_TLVLEN( 10483 wmi_diag_event_log_config_fixed_param)); 10484 10485 cmd->num_of_diag_events_logs = total_len; 10486 10487 buf_ptr += sizeof(wmi_diag_event_log_config_fixed_param); 10488 10489 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, 10490 (total_len * sizeof(uint32_t))); 10491 10492 cmd_args = (uint32_t *) (buf_ptr + WMI_TLV_HDR_SIZE); 10493 10494 if (start_log->verbose_level >= WMI_LOG_LEVEL_ACTIVE) 10495 log_level = 1; 10496 else 10497 log_level = 0; 10498 10499 wmi_debug("Length: %d Log_level: %d", total_len, log_level); 10500 for (i = 0; i < wmi_handle->num_of_diag_events_logs; i++) { 10501 uint32_t val = wmi_handle->events_logs_list[i]; 10502 if ((WMI_DIAG_FREQUENCY_GET(val)) && 10503 (WMI_DIAG_EXT_FEATURE_GET(val))) { 10504 10505 WMI_DIAG_ID_SET(cmd_args[count], 10506 WMI_DIAG_ID_GET(val)); 10507 WMI_DIAG_TYPE_SET(cmd_args[count], 10508 WMI_DIAG_TYPE_GET(val)); 10509 WMI_DIAG_ID_ENABLED_DISABLED_SET(cmd_args[count], 10510 log_level); 10511 wmi_debug("Idx:%d, val:%x", i, val); 10512 count++; 10513 } 10514 } 10515 10516 wmi_mtrace(WMI_DIAG_EVENT_LOG_CONFIG_CMDID, NO_SESSION, 0); 10517 if (wmi_unified_cmd_send(wmi_handle, buf, len, 10518 WMI_DIAG_EVENT_LOG_CONFIG_CMDID)) { 10519 wmi_err("WMI_DIAG_EVENT_LOG_CONFIG_CMDID failed"); 10520 wmi_buf_free(buf); 10521 return QDF_STATUS_E_INVAL; 10522 } 10523 10524 return QDF_STATUS_SUCCESS; 10525 } 10526 10527 /** 10528 * send_flush_logs_to_fw_cmd_tlv() - Send log flush command to FW 10529 * @wmi_handle: WMI handle 10530 * 10531 * This function is used to send the flush command to the FW, 10532 * that will flush the fw logs that are residue in the FW 10533 * 10534 * Return: None 10535 */ 10536 static QDF_STATUS send_flush_logs_to_fw_cmd_tlv(wmi_unified_t wmi_handle) 10537 { 10538 wmi_debug_mesg_flush_fixed_param *cmd; 10539 wmi_buf_t buf; 10540 int len = sizeof(*cmd); 10541 QDF_STATUS ret; 10542 10543 buf = wmi_buf_alloc(wmi_handle, len); 10544 if (!buf) 10545 return QDF_STATUS_E_NOMEM; 10546 10547 cmd = (wmi_debug_mesg_flush_fixed_param *) wmi_buf_data(buf); 10548 WMITLV_SET_HDR(&cmd->tlv_header, 10549 WMITLV_TAG_STRUC_wmi_debug_mesg_flush_fixed_param, 10550 WMITLV_GET_STRUCT_TLVLEN( 10551 wmi_debug_mesg_flush_fixed_param)); 10552 cmd->reserved0 = 0; 10553 10554 wmi_mtrace(WMI_DEBUG_MESG_FLUSH_CMDID, NO_SESSION, 0); 10555 ret = wmi_unified_cmd_send(wmi_handle, 10556 buf, 10557 len, 10558 WMI_DEBUG_MESG_FLUSH_CMDID); 10559 if (QDF_IS_STATUS_ERROR(ret)) { 10560 wmi_err("Failed to send WMI_DEBUG_MESG_FLUSH_CMDID"); 10561 wmi_buf_free(buf); 10562 return QDF_STATUS_E_INVAL; 10563 } 10564 wmi_debug("Sent WMI_DEBUG_MESG_FLUSH_CMDID to FW"); 10565 10566 return ret; 10567 } 10568 10569 #ifdef BIG_ENDIAN_HOST 10570 #ifdef WLAN_FEATURE_FIPS_BER_CCMGCM 10571 /** 10572 * fips_extend_align_data_be() - LE to BE conversion of FIPS extend ev data 10573 * @wmi_handle: wmi handle 10574 * @param: fips extend param related parameters 10575 * 10576 * Return: QDF_STATUS - success or error status 10577 */ 10578 static QDF_STATUS fips_extend_align_data_be(wmi_unified_t wmi_handle, 10579 struct fips_extend_params *param) 10580 { 10581 unsigned char *key_unaligned, *nonce_iv_unaligned, *data_unaligned; 10582 int c; 10583 u_int8_t *key_aligned = NULL; 10584 u_int8_t *nonce_iv_aligned = NULL; 10585 u_int8_t *data_aligned = NULL; 10586 int ret = QDF_STATUS_SUCCESS; 10587 10588 /* Assigning unaligned space to copy the key */ 10589 key_unaligned = qdf_mem_malloc(sizeof(u_int8_t) * 10590 param->cmd_params.key_len + FIPS_ALIGN); 10591 /* Checking if kmalloc is successful to allocate space */ 10592 if (!key_unaligned) 10593 return QDF_STATUS_E_INVAL; 10594 10595 data_unaligned = qdf_mem_malloc(sizeof(u_int8_t) * param->data_len + 10596 FIPS_ALIGN); 10597 /* Checking if kmalloc is successful to allocate space */ 10598 if (!data_unaligned) { 10599 ret = QDF_STATUS_E_INVAL; 10600 goto fips_align_fail_data; 10601 } 10602 10603 /* Checking if space is aligned */ 10604 if (!FIPS_IS_ALIGNED(key_unaligned, FIPS_ALIGN)) { 10605 /* align to 4 */ 10606 key_aligned = (u_int8_t *)FIPS_ALIGNTO(key_unaligned, 10607 FIPS_ALIGN); 10608 } else { 10609 key_aligned = (u_int8_t *)key_unaligned; 10610 } 10611 10612 /* memset and copy content from key to key aligned */ 10613 OS_MEMSET(key_aligned, 0, param->cmd_params.key_len); 10614 OS_MEMCPY(key_aligned, param->cmd_params.key, 10615 param->cmd_params.key_len); 10616 10617 /* print a hexdump for host debug */ 10618 wmi_debug("Aligned and Copied Key: "); 10619 qdf_trace_hex_dump(QDF_MODULE_ID_WMI, QDF_TRACE_LEVEL_DEBUG, 10620 key_aligned, param->cmd_params.key_len); 10621 10622 /* Checking of space is aligned */ 10623 if (!FIPS_IS_ALIGNED(data_unaligned, FIPS_ALIGN)) { 10624 /* align to 4 */ 10625 data_aligned = 10626 (u_int8_t *)FIPS_ALIGNTO(data_unaligned, FIPS_ALIGN); 10627 } else { 10628 data_aligned = (u_int8_t *)data_unaligned; 10629 } 10630 10631 /* memset and copy content from data to data aligned */ 10632 OS_MEMSET(data_aligned, 0, param->data_len); 10633 OS_MEMCPY(data_aligned, param->data, param->data_len); 10634 10635 /* print a hexdump for host debug */ 10636 wmi_debug("\t Properly Aligned and Copied Data: "); 10637 qdf_trace_hex_dump(QDF_MODULE_ID_WMI, QDF_TRACE_LEVEL_DEBUG, 10638 data_aligned, param->data_len); 10639 10640 /* converting to little Endian */ 10641 for (c = 0; c < param->cmd_params.key_len / 4; c++) { 10642 *((u_int32_t *)key_aligned + c) = 10643 qdf_cpu_to_le32(*((u_int32_t *)key_aligned + c)); 10644 } 10645 for (c = 0; c < param->data_len / 4; c++) { 10646 *((u_int32_t *)data_aligned + c) = 10647 qdf_cpu_to_le32(*((u_int32_t *)data_aligned + c)); 10648 } 10649 10650 /* update endian data */ 10651 OS_MEMCPY(param->cmd_params.key, key_aligned, 10652 param->cmd_params.key_len); 10653 OS_MEMCPY(param->data, data_aligned, param->data_len); 10654 10655 if (param->cmd_params.nonce_iv_len) { 10656 nonce_iv_unaligned = qdf_mem_malloc(sizeof(u_int8_t) * 10657 param->cmd_params.nonce_iv_len + 10658 FIPS_ALIGN); 10659 10660 /* Checking if kmalloc is successful to allocate space */ 10661 if (!nonce_iv_unaligned) { 10662 ret = QDF_STATUS_E_INVAL; 10663 goto fips_align_fail_nonce_iv; 10664 } 10665 /* Checking if space is aligned */ 10666 if (!FIPS_IS_ALIGNED(nonce_iv_unaligned, FIPS_ALIGN)) { 10667 /* align to 4 */ 10668 nonce_iv_aligned = 10669 (u_int8_t *)FIPS_ALIGNTO(nonce_iv_unaligned, 10670 FIPS_ALIGN); 10671 } else { 10672 nonce_iv_aligned = (u_int8_t *)nonce_iv_unaligned; 10673 } 10674 10675 /* memset and copy content from iv to iv aligned */ 10676 OS_MEMSET(nonce_iv_aligned, 0, param->cmd_params.nonce_iv_len); 10677 OS_MEMCPY(nonce_iv_aligned, param->cmd_params.nonce_iv, 10678 param->cmd_params.nonce_iv_len); 10679 10680 /* print a hexdump for host debug */ 10681 wmi_debug("\t Aligned and Copied Nonce_IV: "); 10682 qdf_trace_hex_dump(QDF_MODULE_ID_WMI, QDF_TRACE_LEVEL_DEBUG, 10683 nonce_iv_aligned, 10684 param->cmd_params.nonce_iv_len); 10685 10686 for (c = 0; c < param->cmd_params.nonce_iv_len / 4; c++) { 10687 *((u_int32_t *)nonce_iv_aligned + c) = 10688 qdf_cpu_to_le32(*((u_int32_t *)nonce_iv_aligned + c)); 10689 } 10690 } 10691 10692 /* clean up allocated spaces */ 10693 qdf_mem_free(nonce_iv_unaligned); 10694 nonce_iv_unaligned = NULL; 10695 nonce_iv_aligned = NULL; 10696 10697 fips_align_fail_nonce_iv: 10698 qdf_mem_free(data_unaligned); 10699 data_unaligned = NULL; 10700 data_aligned = NULL; 10701 10702 fips_align_fail_data: 10703 qdf_mem_free(key_unaligned); 10704 key_unaligned = NULL; 10705 key_aligned = NULL; 10706 10707 return ret; 10708 } 10709 #endif 10710 10711 /** 10712 * fips_align_data_be() - LE to BE conversion of FIPS ev data 10713 * @wmi_handle: wmi handle 10714 * @param: fips param related parameters 10715 * 10716 * Return: QDF_STATUS - success or error status 10717 */ 10718 static QDF_STATUS fips_align_data_be(wmi_unified_t wmi_handle, 10719 struct fips_params *param) 10720 { 10721 unsigned char *key_unaligned, *data_unaligned; 10722 int c; 10723 u_int8_t *key_aligned = NULL; 10724 u_int8_t *data_aligned = NULL; 10725 10726 /* Assigning unaligned space to copy the key */ 10727 key_unaligned = qdf_mem_malloc( 10728 sizeof(u_int8_t)*param->key_len + FIPS_ALIGN); 10729 data_unaligned = qdf_mem_malloc( 10730 sizeof(u_int8_t)*param->data_len + FIPS_ALIGN); 10731 10732 /* Checking if kmalloc is successful to allocate space */ 10733 if (!key_unaligned) 10734 return QDF_STATUS_SUCCESS; 10735 /* Checking if space is aligned */ 10736 if (!FIPS_IS_ALIGNED(key_unaligned, FIPS_ALIGN)) { 10737 /* align to 4 */ 10738 key_aligned = 10739 (u_int8_t *)FIPS_ALIGNTO(key_unaligned, 10740 FIPS_ALIGN); 10741 } else { 10742 key_aligned = (u_int8_t *)key_unaligned; 10743 } 10744 10745 /* memset and copy content from key to key aligned */ 10746 OS_MEMSET(key_aligned, 0, param->key_len); 10747 OS_MEMCPY(key_aligned, param->key, param->key_len); 10748 10749 /* print a hexdump for host debug */ 10750 print_hex_dump(KERN_DEBUG, 10751 "\t Aligned and Copied Key:@@@@ ", 10752 DUMP_PREFIX_NONE, 10753 16, 1, key_aligned, param->key_len, true); 10754 10755 /* Checking if kmalloc is successful to allocate space */ 10756 if (!data_unaligned) 10757 return QDF_STATUS_SUCCESS; 10758 /* Checking of space is aligned */ 10759 if (!FIPS_IS_ALIGNED(data_unaligned, FIPS_ALIGN)) { 10760 /* align to 4 */ 10761 data_aligned = 10762 (u_int8_t *)FIPS_ALIGNTO(data_unaligned, 10763 FIPS_ALIGN); 10764 } else { 10765 data_aligned = (u_int8_t *)data_unaligned; 10766 } 10767 10768 /* memset and copy content from data to data aligned */ 10769 OS_MEMSET(data_aligned, 0, param->data_len); 10770 OS_MEMCPY(data_aligned, param->data, param->data_len); 10771 10772 /* print a hexdump for host debug */ 10773 print_hex_dump(KERN_DEBUG, 10774 "\t Properly Aligned and Copied Data:@@@@ ", 10775 DUMP_PREFIX_NONE, 10776 16, 1, data_aligned, param->data_len, true); 10777 10778 /* converting to little Endian both key_aligned and 10779 * data_aligned*/ 10780 for (c = 0; c < param->key_len/4; c++) { 10781 *((u_int32_t *)key_aligned+c) = 10782 qdf_cpu_to_le32(*((u_int32_t *)key_aligned+c)); 10783 } 10784 for (c = 0; c < param->data_len/4; c++) { 10785 *((u_int32_t *)data_aligned+c) = 10786 qdf_cpu_to_le32(*((u_int32_t *)data_aligned+c)); 10787 } 10788 10789 /* update endian data to key and data vectors */ 10790 OS_MEMCPY(param->key, key_aligned, param->key_len); 10791 OS_MEMCPY(param->data, data_aligned, param->data_len); 10792 10793 /* clean up allocated spaces */ 10794 qdf_mem_free(key_unaligned); 10795 key_unaligned = NULL; 10796 key_aligned = NULL; 10797 10798 qdf_mem_free(data_unaligned); 10799 data_unaligned = NULL; 10800 data_aligned = NULL; 10801 10802 return QDF_STATUS_SUCCESS; 10803 } 10804 #else 10805 #ifdef WLAN_FEATURE_FIPS_BER_CCMGCM 10806 static QDF_STATUS fips_extend_align_data_be(wmi_unified_t wmi_handle, 10807 struct fips_extend_params *param) 10808 { 10809 return QDF_STATUS_SUCCESS; 10810 } 10811 #endif 10812 10813 static QDF_STATUS fips_align_data_be(wmi_unified_t wmi_handle, 10814 struct fips_params *param) 10815 { 10816 return QDF_STATUS_SUCCESS; 10817 } 10818 #endif 10819 10820 #ifdef WLAN_FEATURE_DISA 10821 /** 10822 * send_encrypt_decrypt_send_cmd_tlv() - send encrypt/decrypt cmd to fw 10823 * @wmi_handle: wmi handle 10824 * @encrypt_decrypt_params: encrypt/decrypt params 10825 * 10826 * Return: QDF_STATUS_SUCCESS for success or error code 10827 */ 10828 static QDF_STATUS 10829 send_encrypt_decrypt_send_cmd_tlv(wmi_unified_t wmi_handle, 10830 struct disa_encrypt_decrypt_req_params 10831 *encrypt_decrypt_params) 10832 { 10833 wmi_vdev_encrypt_decrypt_data_req_cmd_fixed_param *cmd; 10834 wmi_buf_t wmi_buf; 10835 uint8_t *buf_ptr; 10836 QDF_STATUS ret; 10837 uint32_t len; 10838 10839 wmi_debug("Send encrypt decrypt cmd"); 10840 10841 len = sizeof(*cmd) + 10842 encrypt_decrypt_params->data_len + 10843 WMI_TLV_HDR_SIZE; 10844 wmi_buf = wmi_buf_alloc(wmi_handle, len); 10845 if (!wmi_buf) 10846 return QDF_STATUS_E_NOMEM; 10847 10848 buf_ptr = wmi_buf_data(wmi_buf); 10849 cmd = (wmi_vdev_encrypt_decrypt_data_req_cmd_fixed_param *)buf_ptr; 10850 10851 WMITLV_SET_HDR(&cmd->tlv_header, 10852 WMITLV_TAG_STRUC_wmi_vdev_encrypt_decrypt_data_req_cmd_fixed_param, 10853 WMITLV_GET_STRUCT_TLVLEN( 10854 wmi_vdev_encrypt_decrypt_data_req_cmd_fixed_param)); 10855 10856 cmd->vdev_id = encrypt_decrypt_params->vdev_id; 10857 cmd->key_flag = encrypt_decrypt_params->key_flag; 10858 cmd->key_idx = encrypt_decrypt_params->key_idx; 10859 cmd->key_cipher = encrypt_decrypt_params->key_cipher; 10860 cmd->key_len = encrypt_decrypt_params->key_len; 10861 cmd->key_txmic_len = encrypt_decrypt_params->key_txmic_len; 10862 cmd->key_rxmic_len = encrypt_decrypt_params->key_rxmic_len; 10863 10864 qdf_mem_copy(cmd->key_data, encrypt_decrypt_params->key_data, 10865 encrypt_decrypt_params->key_len); 10866 10867 qdf_mem_copy(cmd->mac_hdr, encrypt_decrypt_params->mac_header, 10868 MAX_MAC_HEADER_LEN); 10869 10870 cmd->data_len = encrypt_decrypt_params->data_len; 10871 10872 if (cmd->data_len) { 10873 buf_ptr += sizeof(*cmd); 10874 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, 10875 roundup(encrypt_decrypt_params->data_len, 10876 sizeof(uint32_t))); 10877 buf_ptr += WMI_TLV_HDR_SIZE; 10878 qdf_mem_copy(buf_ptr, encrypt_decrypt_params->data, 10879 encrypt_decrypt_params->data_len); 10880 } 10881 10882 /* This conversion is to facilitate data to FW in little endian */ 10883 cmd->pn[5] = encrypt_decrypt_params->pn[0]; 10884 cmd->pn[4] = encrypt_decrypt_params->pn[1]; 10885 cmd->pn[3] = encrypt_decrypt_params->pn[2]; 10886 cmd->pn[2] = encrypt_decrypt_params->pn[3]; 10887 cmd->pn[1] = encrypt_decrypt_params->pn[4]; 10888 cmd->pn[0] = encrypt_decrypt_params->pn[5]; 10889 10890 wmi_mtrace(WMI_VDEV_ENCRYPT_DECRYPT_DATA_REQ_CMDID, cmd->vdev_id, 0); 10891 ret = wmi_unified_cmd_send(wmi_handle, 10892 wmi_buf, len, 10893 WMI_VDEV_ENCRYPT_DECRYPT_DATA_REQ_CMDID); 10894 if (QDF_IS_STATUS_ERROR(ret)) { 10895 wmi_err("Failed to send ENCRYPT DECRYPT cmd: %d", ret); 10896 wmi_buf_free(wmi_buf); 10897 } 10898 10899 return ret; 10900 } 10901 #endif /* WLAN_FEATURE_DISA */ 10902 10903 /** 10904 * send_pdev_fips_cmd_tlv() - send pdev fips cmd to fw 10905 * @wmi_handle: wmi handle 10906 * @param: pointer to hold pdev fips param 10907 * 10908 * Return: QDF_STATUS_SUCCESS for success or error code 10909 */ 10910 static QDF_STATUS 10911 send_pdev_fips_cmd_tlv(wmi_unified_t wmi_handle, 10912 struct fips_params *param) 10913 { 10914 wmi_pdev_fips_cmd_fixed_param *cmd; 10915 wmi_buf_t buf; 10916 uint8_t *buf_ptr; 10917 uint32_t len = sizeof(wmi_pdev_fips_cmd_fixed_param); 10918 QDF_STATUS retval = QDF_STATUS_SUCCESS; 10919 10920 /* Length TLV placeholder for array of bytes */ 10921 len += WMI_TLV_HDR_SIZE; 10922 if (param->data_len) 10923 len += (param->data_len*sizeof(uint8_t)); 10924 10925 /* 10926 * Data length must be multiples of 16 bytes - checked against 0xF - 10927 * and must be less than WMI_SVC_MSG_SIZE - static size of 10928 * wmi_pdev_fips_cmd structure 10929 */ 10930 10931 /* do sanity on the input */ 10932 if (!(((param->data_len & 0xF) == 0) && 10933 ((param->data_len > 0) && 10934 (param->data_len < (WMI_HOST_MAX_BUFFER_SIZE - 10935 sizeof(wmi_pdev_fips_cmd_fixed_param)))))) { 10936 return QDF_STATUS_E_INVAL; 10937 } 10938 10939 buf = wmi_buf_alloc(wmi_handle, len); 10940 if (!buf) 10941 return QDF_STATUS_E_FAILURE; 10942 10943 buf_ptr = (uint8_t *) wmi_buf_data(buf); 10944 cmd = (wmi_pdev_fips_cmd_fixed_param *)buf_ptr; 10945 WMITLV_SET_HDR(&cmd->tlv_header, 10946 WMITLV_TAG_STRUC_wmi_pdev_fips_cmd_fixed_param, 10947 WMITLV_GET_STRUCT_TLVLEN 10948 (wmi_pdev_fips_cmd_fixed_param)); 10949 10950 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 10951 wmi_handle, 10952 param->pdev_id); 10953 if (param->key && param->data) { 10954 cmd->key_len = param->key_len; 10955 cmd->data_len = param->data_len; 10956 cmd->fips_cmd = !!(param->op); 10957 10958 if (fips_align_data_be(wmi_handle, param) != QDF_STATUS_SUCCESS) 10959 return QDF_STATUS_E_FAILURE; 10960 10961 qdf_mem_copy(cmd->key, param->key, param->key_len); 10962 10963 if (param->mode == FIPS_ENGINE_AES_CTR || 10964 param->mode == FIPS_ENGINE_AES_MIC) { 10965 cmd->mode = param->mode; 10966 } else { 10967 cmd->mode = FIPS_ENGINE_AES_CTR; 10968 } 10969 10970 print_hex_dump(KERN_DEBUG, "Key: ", DUMP_PREFIX_NONE, 16, 1, 10971 cmd->key, cmd->key_len, true); 10972 buf_ptr += sizeof(*cmd); 10973 10974 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, param->data_len); 10975 10976 buf_ptr += WMI_TLV_HDR_SIZE; 10977 if (param->data_len) 10978 qdf_mem_copy(buf_ptr, 10979 (uint8_t *) param->data, param->data_len); 10980 10981 print_hex_dump(KERN_DEBUG, "Plain text: ", DUMP_PREFIX_NONE, 10982 16, 1, buf_ptr, cmd->data_len, true); 10983 10984 buf_ptr += param->data_len; 10985 10986 wmi_mtrace(WMI_PDEV_FIPS_CMDID, NO_SESSION, 0); 10987 retval = wmi_unified_cmd_send(wmi_handle, buf, len, 10988 WMI_PDEV_FIPS_CMDID); 10989 } else { 10990 qdf_print("\n%s:%d Key or Data is NULL", __func__, __LINE__); 10991 wmi_buf_free(buf); 10992 retval = -QDF_STATUS_E_BADMSG; 10993 } 10994 10995 return retval; 10996 } 10997 10998 #ifdef WLAN_FEATURE_FIPS_BER_CCMGCM 10999 /** 11000 * send_pdev_fips_extend_cmd_tlv() - send pdev fips cmd to fw 11001 * @wmi_handle: wmi handle 11002 * @param: pointer to hold pdev fips param 11003 * 11004 * Return: QDF_STATUS_SUCCESS for success or error code 11005 */ 11006 static QDF_STATUS 11007 send_pdev_fips_extend_cmd_tlv(wmi_unified_t wmi_handle, 11008 struct fips_extend_params *param) 11009 { 11010 wmi_pdev_fips_extend_cmd_fixed_param *cmd; 11011 wmi_buf_t buf; 11012 uint8_t *buf_ptr; 11013 uint32_t len = sizeof(wmi_pdev_fips_extend_cmd_fixed_param); 11014 uint32_t data_len_aligned; 11015 QDF_STATUS retval = QDF_STATUS_SUCCESS; 11016 11017 len += WMI_TLV_HDR_SIZE; 11018 if (param->frag_idx == 0) 11019 len += sizeof(wmi_fips_extend_cmd_init_params); 11020 11021 /* Length TLV placeholder for array of bytes */ 11022 len += WMI_TLV_HDR_SIZE; 11023 if (param->data_len) { 11024 data_len_aligned = roundup(param->data_len, sizeof(uint32_t)); 11025 len += (data_len_aligned * sizeof(uint8_t)); 11026 } 11027 11028 buf = wmi_buf_alloc(wmi_handle, len); 11029 if (!buf) 11030 return QDF_STATUS_E_FAILURE; 11031 11032 buf_ptr = (uint8_t *)wmi_buf_data(buf); 11033 cmd = (wmi_pdev_fips_extend_cmd_fixed_param *)buf_ptr; 11034 WMITLV_SET_HDR(&cmd->tlv_header, 11035 WMITLV_TAG_STRUC_wmi_pdev_fips_extend_cmd_fixed_param, 11036 WMITLV_GET_STRUCT_TLVLEN 11037 (wmi_pdev_fips_extend_cmd_fixed_param)); 11038 11039 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 11040 wmi_handle, 11041 param->pdev_id); 11042 11043 cmd->fips_cookie = param->cookie; 11044 cmd->frag_idx = param->frag_idx; 11045 cmd->more_bit = param->more_bit; 11046 cmd->data_len = param->data_len; 11047 11048 if (fips_extend_align_data_be(wmi_handle, param) != 11049 QDF_STATUS_SUCCESS) { 11050 wmi_buf_free(buf); 11051 return QDF_STATUS_E_FAILURE; 11052 } 11053 11054 buf_ptr = (uint8_t *)(cmd + 1); 11055 if (cmd->frag_idx == 0) { 11056 wmi_fips_extend_cmd_init_params *cmd_params; 11057 11058 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 11059 sizeof(wmi_fips_extend_cmd_init_params)); 11060 buf_ptr += WMI_TLV_HDR_SIZE; 11061 cmd_params = (wmi_fips_extend_cmd_init_params *)buf_ptr; 11062 WMITLV_SET_HDR(buf_ptr, 11063 WMITLV_TAG_STRUC_wmi_fips_extend_cmd_init_params, 11064 WMITLV_GET_STRUCT_TLVLEN(wmi_fips_extend_cmd_init_params)); 11065 cmd_params->fips_cmd = param->cmd_params.fips_cmd; 11066 cmd_params->key_cipher = param->cmd_params.key_cipher; 11067 cmd_params->key_len = param->cmd_params.key_len; 11068 cmd_params->nonce_iv_len = param->cmd_params.nonce_iv_len; 11069 cmd_params->tag_len = param->cmd_params.tag_len; 11070 cmd_params->aad_len = param->cmd_params.aad_len; 11071 cmd_params->payload_len = param->cmd_params.payload_len; 11072 11073 qdf_mem_copy(cmd_params->key, param->cmd_params.key, 11074 param->cmd_params.key_len); 11075 qdf_mem_copy(cmd_params->nonce_iv, param->cmd_params.nonce_iv, 11076 param->cmd_params.nonce_iv_len); 11077 11078 wmi_debug("Key len = %d, IVNoncelen = %d, Tlen = %d, Alen = %d, Plen = %d", 11079 cmd_params->key_len, cmd_params->nonce_iv_len, 11080 cmd_params->tag_len, cmd_params->aad_len, 11081 cmd_params->payload_len); 11082 11083 buf_ptr += sizeof(wmi_fips_extend_cmd_init_params); 11084 } else { 11085 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0); 11086 buf_ptr += WMI_TLV_HDR_SIZE; 11087 } 11088 11089 if (param->data_len && param->data) { 11090 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, 11091 data_len_aligned); 11092 11093 buf_ptr += WMI_TLV_HDR_SIZE; 11094 if (param->data_len) 11095 qdf_mem_copy(buf_ptr, 11096 (uint8_t *)param->data, param->data_len); 11097 11098 wmi_debug("Data: "); 11099 qdf_trace_hex_dump(QDF_MODULE_ID_WMI, QDF_TRACE_LEVEL_DEBUG, 11100 buf_ptr, cmd->data_len); 11101 11102 if (param->data_len) 11103 buf_ptr += param->data_len; 11104 } else { 11105 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, 0); 11106 buf_ptr += WMI_TLV_HDR_SIZE; 11107 } 11108 11109 wmi_mtrace(WMI_PDEV_FIPS_EXTEND_CMDID, NO_SESSION, 0); 11110 retval = wmi_unified_cmd_send(wmi_handle, buf, len, 11111 WMI_PDEV_FIPS_EXTEND_CMDID); 11112 11113 if (retval) { 11114 wmi_err("Failed to send FIPS cmd"); 11115 wmi_buf_free(buf); 11116 } 11117 11118 return retval; 11119 } 11120 11121 /** 11122 * send_pdev_fips_mode_set_cmd_tlv() - send pdev fips cmd to fw 11123 * @wmi_handle: wmi handle 11124 * @param: pointer to hold pdev fips param 11125 * 11126 * Return: QDF_STATUS_SUCCESS for success or error code 11127 */ 11128 static QDF_STATUS 11129 send_pdev_fips_mode_set_cmd_tlv(wmi_unified_t wmi_handle, 11130 struct fips_mode_set_params *param) 11131 { 11132 wmi_pdev_fips_mode_set_cmd_fixed_param *cmd; 11133 wmi_buf_t buf; 11134 uint8_t *buf_ptr; 11135 uint32_t len = sizeof(wmi_pdev_fips_mode_set_cmd_fixed_param); 11136 QDF_STATUS retval = QDF_STATUS_SUCCESS; 11137 11138 buf = wmi_buf_alloc(wmi_handle, len); 11139 if (!buf) 11140 return QDF_STATUS_E_FAILURE; 11141 11142 buf_ptr = (uint8_t *)wmi_buf_data(buf); 11143 cmd = (wmi_pdev_fips_mode_set_cmd_fixed_param *)buf_ptr; 11144 WMITLV_SET_HDR(&cmd->tlv_header, 11145 WMITLV_TAG_STRUC_wmi_pdev_fips_mode_set_cmd_fixed_param, 11146 WMITLV_GET_STRUCT_TLVLEN 11147 (wmi_pdev_fips_mode_set_cmd_fixed_param)); 11148 11149 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 11150 wmi_handle, 11151 param->pdev_id); 11152 11153 cmd->fips_mode_set = param->mode; 11154 wmi_mtrace(WMI_PDEV_FIPS_MODE_SET_CMDID, NO_SESSION, 0); 11155 retval = wmi_unified_cmd_send(wmi_handle, buf, len, 11156 WMI_PDEV_FIPS_MODE_SET_CMDID); 11157 if (retval) { 11158 wmi_err("Failed to send FIPS mode enable cmd"); 11159 wmi_buf_free(buf); 11160 } 11161 return retval; 11162 } 11163 #endif 11164 11165 /** 11166 * send_wlan_profile_enable_cmd_tlv() - send wlan profile enable command 11167 * to fw 11168 * @wmi_handle: wmi handle 11169 * @param: pointer to wlan profile param 11170 * 11171 * Return: QDF_STATUS_SUCCESS for success or error code 11172 */ 11173 static QDF_STATUS 11174 send_wlan_profile_enable_cmd_tlv(wmi_unified_t wmi_handle, 11175 struct wlan_profile_params *param) 11176 { 11177 wmi_buf_t buf; 11178 uint16_t len; 11179 QDF_STATUS ret; 11180 wmi_wlan_profile_enable_profile_id_cmd_fixed_param *profile_enable_cmd; 11181 11182 len = sizeof(wmi_wlan_profile_enable_profile_id_cmd_fixed_param); 11183 buf = wmi_buf_alloc(wmi_handle, len); 11184 if (!buf) { 11185 wmi_err("Failed to send WMI_WLAN_PROFILE_ENABLE_PROFILE_ID_CMDID"); 11186 return QDF_STATUS_E_NOMEM; 11187 } 11188 11189 profile_enable_cmd = 11190 (wmi_wlan_profile_enable_profile_id_cmd_fixed_param *) 11191 wmi_buf_data(buf); 11192 WMITLV_SET_HDR(&profile_enable_cmd->tlv_header, 11193 WMITLV_TAG_STRUC_wmi_wlan_profile_enable_profile_id_cmd_fixed_param, 11194 WMITLV_GET_STRUCT_TLVLEN 11195 (wmi_wlan_profile_enable_profile_id_cmd_fixed_param)); 11196 11197 profile_enable_cmd->profile_id = param->profile_id; 11198 profile_enable_cmd->enable = param->enable; 11199 wmi_mtrace(WMI_WLAN_PROFILE_ENABLE_PROFILE_ID_CMDID, 11200 NO_SESSION, 0); 11201 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 11202 WMI_WLAN_PROFILE_ENABLE_PROFILE_ID_CMDID); 11203 if (ret) { 11204 wmi_err("Failed to send PROFILE_ENABLE_PROFILE_ID_CMDID"); 11205 wmi_buf_free(buf); 11206 } 11207 return ret; 11208 } 11209 11210 /** 11211 * send_wlan_profile_trigger_cmd_tlv() - send wlan profile trigger command 11212 * to fw 11213 * @wmi_handle: wmi handle 11214 * @param: pointer to wlan profile param 11215 * 11216 * Return: QDF_STATUS_SUCCESS for success or error code 11217 */ 11218 static QDF_STATUS 11219 send_wlan_profile_trigger_cmd_tlv(wmi_unified_t wmi_handle, 11220 struct wlan_profile_params *param) 11221 { 11222 wmi_buf_t buf; 11223 uint16_t len; 11224 QDF_STATUS ret; 11225 wmi_wlan_profile_trigger_cmd_fixed_param *prof_trig_cmd; 11226 11227 len = sizeof(wmi_wlan_profile_trigger_cmd_fixed_param); 11228 buf = wmi_buf_alloc(wmi_handle, len); 11229 if (!buf) { 11230 wmi_err("Failed to send WMI_WLAN_PROFILE_TRIGGER_CMDID"); 11231 return QDF_STATUS_E_NOMEM; 11232 } 11233 11234 prof_trig_cmd = 11235 (wmi_wlan_profile_trigger_cmd_fixed_param *) 11236 wmi_buf_data(buf); 11237 11238 WMITLV_SET_HDR(&prof_trig_cmd->tlv_header, 11239 WMITLV_TAG_STRUC_wmi_wlan_profile_trigger_cmd_fixed_param, 11240 WMITLV_GET_STRUCT_TLVLEN 11241 (wmi_wlan_profile_trigger_cmd_fixed_param)); 11242 11243 prof_trig_cmd->enable = param->enable; 11244 wmi_mtrace(WMI_WLAN_PROFILE_TRIGGER_CMDID, NO_SESSION, 0); 11245 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 11246 WMI_WLAN_PROFILE_TRIGGER_CMDID); 11247 if (ret) { 11248 wmi_err("Failed to send WMI_WLAN_PROFILE_TRIGGER_CMDID"); 11249 wmi_buf_free(buf); 11250 } 11251 return ret; 11252 } 11253 11254 /** 11255 * send_wlan_profile_hist_intvl_cmd_tlv() - send wlan profile interval command 11256 * to fw 11257 * @wmi_handle: wmi handle 11258 * @param: pointer to wlan profile param 11259 * 11260 * Return: QDF_STATUS_SUCCESS for success or error code 11261 */ 11262 static QDF_STATUS 11263 send_wlan_profile_hist_intvl_cmd_tlv(wmi_unified_t wmi_handle, 11264 struct wlan_profile_params *param) 11265 { 11266 wmi_buf_t buf; 11267 int32_t len = 0; 11268 QDF_STATUS ret; 11269 wmi_wlan_profile_set_hist_intvl_cmd_fixed_param *hist_intvl_cmd; 11270 11271 len = sizeof(wmi_wlan_profile_set_hist_intvl_cmd_fixed_param); 11272 buf = wmi_buf_alloc(wmi_handle, len); 11273 if (!buf) { 11274 wmi_err("Failed to send WMI_WLAN_PROFILE_SET_HIST_INTVL_CMDID"); 11275 return QDF_STATUS_E_NOMEM; 11276 } 11277 11278 hist_intvl_cmd = 11279 (wmi_wlan_profile_set_hist_intvl_cmd_fixed_param *) 11280 wmi_buf_data(buf); 11281 11282 WMITLV_SET_HDR(&hist_intvl_cmd->tlv_header, 11283 WMITLV_TAG_STRUC_wmi_wlan_profile_set_hist_intvl_cmd_fixed_param, 11284 WMITLV_GET_STRUCT_TLVLEN 11285 (wmi_wlan_profile_set_hist_intvl_cmd_fixed_param)); 11286 11287 hist_intvl_cmd->profile_id = param->profile_id; 11288 hist_intvl_cmd->value = param->enable; 11289 wmi_mtrace(WMI_WLAN_PROFILE_SET_HIST_INTVL_CMDID, 11290 NO_SESSION, 0); 11291 11292 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 11293 WMI_WLAN_PROFILE_SET_HIST_INTVL_CMDID); 11294 if (ret) { 11295 wmi_err("Failed to send PROFILE_SET_HIST_INTVL_CMDID"); 11296 wmi_buf_free(buf); 11297 } 11298 return ret; 11299 } 11300 11301 /** 11302 * send_fw_test_cmd_tlv() - send fw test command to fw. 11303 * @wmi_handle: wmi handle 11304 * @wmi_fwtest: fw test command 11305 * 11306 * This function sends fw test command to fw. 11307 * 11308 * Return: CDF STATUS 11309 */ 11310 static 11311 QDF_STATUS send_fw_test_cmd_tlv(wmi_unified_t wmi_handle, 11312 struct set_fwtest_params *wmi_fwtest) 11313 { 11314 wmi_fwtest_set_param_cmd_fixed_param *cmd; 11315 wmi_buf_t wmi_buf; 11316 uint16_t len; 11317 11318 len = sizeof(*cmd); 11319 11320 wmi_buf = wmi_buf_alloc(wmi_handle, len); 11321 if (!wmi_buf) 11322 return QDF_STATUS_E_NOMEM; 11323 11324 cmd = (wmi_fwtest_set_param_cmd_fixed_param *) wmi_buf_data(wmi_buf); 11325 WMITLV_SET_HDR(&cmd->tlv_header, 11326 WMITLV_TAG_STRUC_wmi_fwtest_set_param_cmd_fixed_param, 11327 WMITLV_GET_STRUCT_TLVLEN( 11328 wmi_fwtest_set_param_cmd_fixed_param)); 11329 cmd->param_id = wmi_fwtest->arg; 11330 cmd->param_value = wmi_fwtest->value; 11331 11332 wmi_mtrace(WMI_FWTEST_CMDID, NO_SESSION, 0); 11333 if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len, 11334 WMI_FWTEST_CMDID)) { 11335 wmi_err("Failed to send fw test command"); 11336 wmi_buf_free(wmi_buf); 11337 return QDF_STATUS_E_FAILURE; 11338 } 11339 11340 return QDF_STATUS_SUCCESS; 11341 } 11342 11343 static uint16_t wfa_config_param_len(enum wfa_test_cmds config) 11344 { 11345 uint16_t len = 0; 11346 11347 if (config == WFA_CONFIG_RXNE) 11348 len += WMI_TLV_HDR_SIZE + sizeof(wmi_wfa_config_rsnxe); 11349 else 11350 len += WMI_TLV_HDR_SIZE; 11351 11352 if (config == WFA_CONFIG_CSA) 11353 len += WMI_TLV_HDR_SIZE + sizeof(wmi_wfa_config_csa); 11354 else 11355 len += WMI_TLV_HDR_SIZE; 11356 11357 if (config == WFA_CONFIG_OCV) 11358 len += WMI_TLV_HDR_SIZE + sizeof(wmi_wfa_config_ocv); 11359 else 11360 len += WMI_TLV_HDR_SIZE; 11361 11362 if (config == WFA_CONFIG_SA_QUERY) 11363 len += WMI_TLV_HDR_SIZE + sizeof(wmi_wfa_config_saquery); 11364 else 11365 len += WMI_TLV_HDR_SIZE; 11366 11367 return len; 11368 } 11369 11370 /** 11371 * wmi_fill_ocv_frame_type() - Fill host ocv frm type into WMI ocv frm type. 11372 * @host_frmtype: Host defined OCV frame type 11373 * @ocv_frmtype: Pointer to hold WMI OCV frame type 11374 * 11375 * This function converts and fills host defined OCV frame type into WMI OCV 11376 * frame type. 11377 * 11378 * Return: CDF STATUS 11379 */ 11380 static QDF_STATUS 11381 wmi_fill_ocv_frame_type(uint32_t host_frmtype, uint32_t *ocv_frmtype) 11382 { 11383 switch (host_frmtype) { 11384 case WMI_HOST_WFA_CONFIG_OCV_FRMTYPE_SAQUERY_REQ: 11385 *ocv_frmtype = WMI_WFA_CONFIG_OCV_FRMTYPE_SAQUERY_REQ; 11386 break; 11387 11388 case WMI_HOST_WFA_CONFIG_OCV_FRMTYPE_SAQUERY_RSP: 11389 *ocv_frmtype = WMI_WFA_CONFIG_OCV_FRMTYPE_SAQUERY_RSP; 11390 break; 11391 11392 case WMI_HOST_WFA_CONFIG_OCV_FRMTYPE_FT_REASSOC_REQ: 11393 *ocv_frmtype = WMI_WFA_CONFIG_OCV_FRMTYPE_FT_REASSOC_REQ; 11394 break; 11395 11396 case WMI_HOST_WFA_CONFIG_OCV_FRMTYPE_FILS_REASSOC_REQ: 11397 *ocv_frmtype = WMI_WFA_CONFIG_OCV_FRMTYPE_FILS_REASSOC_REQ; 11398 break; 11399 11400 default: 11401 wmi_err("Invalid command type cmd %d", host_frmtype); 11402 return QDF_STATUS_E_FAILURE; 11403 } 11404 11405 return QDF_STATUS_SUCCESS; 11406 } 11407 11408 /** 11409 * send_wfa_test_cmd_tlv() - send wfa test command to fw. 11410 * @wmi_handle: wmi handle 11411 * @wmi_wfatest: wfa test command 11412 * 11413 * This function sends wfa test command to fw. 11414 * 11415 * Return: CDF STATUS 11416 */ 11417 static 11418 QDF_STATUS send_wfa_test_cmd_tlv(wmi_unified_t wmi_handle, 11419 struct set_wfatest_params *wmi_wfatest) 11420 { 11421 wmi_wfa_config_cmd_fixed_param *cmd; 11422 wmi_wfa_config_rsnxe *rxne; 11423 wmi_wfa_config_csa *csa; 11424 wmi_wfa_config_ocv *ocv; 11425 wmi_wfa_config_saquery *saquery; 11426 wmi_buf_t wmi_buf; 11427 uint16_t len = sizeof(*cmd); 11428 uint8_t *buf_ptr; 11429 11430 len += wfa_config_param_len(wmi_wfatest->cmd); 11431 wmi_buf = wmi_buf_alloc(wmi_handle, len); 11432 if (!wmi_buf) 11433 return QDF_STATUS_E_NOMEM; 11434 11435 cmd = (wmi_wfa_config_cmd_fixed_param *)wmi_buf_data(wmi_buf); 11436 WMITLV_SET_HDR(&cmd->tlv_header, 11437 WMITLV_TAG_STRUC_wmi_wfa_config_cmd_fixed_param, 11438 WMITLV_GET_STRUCT_TLVLEN( 11439 wmi_wfa_config_cmd_fixed_param)); 11440 11441 cmd->vdev_id = wmi_wfatest->vdev_id; 11442 buf_ptr = (uint8_t *)(cmd + 1); 11443 11444 if (wmi_wfatest->cmd == WFA_CONFIG_RXNE) { 11445 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 11446 sizeof(wmi_wfa_config_rsnxe)); 11447 buf_ptr += WMI_TLV_HDR_SIZE; 11448 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_STRUC_wmi_wfa_config_rsnxe, 11449 WMITLV_GET_STRUCT_TLVLEN(wmi_wfa_config_rsnxe)); 11450 rxne = (wmi_wfa_config_rsnxe *)buf_ptr; 11451 rxne->rsnxe_param = wmi_wfatest->value; 11452 buf_ptr += sizeof(wmi_wfa_config_rsnxe); 11453 } else { 11454 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0); 11455 buf_ptr += WMI_TLV_HDR_SIZE; 11456 } 11457 11458 if (wmi_wfatest->cmd == WFA_CONFIG_CSA) { 11459 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 11460 sizeof(wmi_wfa_config_csa)); 11461 buf_ptr += WMI_TLV_HDR_SIZE; 11462 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_STRUC_wmi_wfa_config_csa, 11463 WMITLV_GET_STRUCT_TLVLEN(wmi_wfa_config_csa)); 11464 csa = (wmi_wfa_config_csa *)buf_ptr; 11465 csa->ignore_csa = wmi_wfatest->value; 11466 buf_ptr += sizeof(wmi_wfa_config_csa); 11467 } else { 11468 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0); 11469 buf_ptr += WMI_TLV_HDR_SIZE; 11470 } 11471 11472 if (wmi_wfatest->cmd == WFA_CONFIG_OCV) { 11473 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 11474 sizeof(wmi_wfa_config_ocv)); 11475 buf_ptr += WMI_TLV_HDR_SIZE; 11476 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_STRUC_wmi_wfa_config_ocv, 11477 WMITLV_GET_STRUCT_TLVLEN(wmi_wfa_config_ocv)); 11478 ocv = (wmi_wfa_config_ocv *)buf_ptr; 11479 11480 if (wmi_fill_ocv_frame_type(wmi_wfatest->ocv_param->frame_type, 11481 &ocv->frame_types)) 11482 goto error; 11483 11484 ocv->chan_freq = wmi_wfatest->ocv_param->freq; 11485 buf_ptr += sizeof(wmi_wfa_config_ocv); 11486 } else { 11487 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0); 11488 buf_ptr += WMI_TLV_HDR_SIZE; 11489 } 11490 11491 if (wmi_wfatest->cmd == WFA_CONFIG_SA_QUERY) { 11492 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 11493 sizeof(wmi_wfa_config_saquery)); 11494 buf_ptr += WMI_TLV_HDR_SIZE; 11495 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_STRUC_wmi_wfa_config_saquery, 11496 WMITLV_GET_STRUCT_TLVLEN(wmi_wfa_config_saquery)); 11497 11498 saquery = (wmi_wfa_config_saquery *)buf_ptr; 11499 saquery->remain_connect_on_saquery_timeout = wmi_wfatest->value; 11500 } else { 11501 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0); 11502 buf_ptr += WMI_TLV_HDR_SIZE; 11503 } 11504 11505 wmi_mtrace(WMI_WFA_CONFIG_CMDID, wmi_wfatest->vdev_id, 0); 11506 if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len, 11507 WMI_WFA_CONFIG_CMDID)) { 11508 wmi_err("Failed to send wfa test command"); 11509 goto error; 11510 } 11511 11512 return QDF_STATUS_SUCCESS; 11513 11514 error: 11515 wmi_buf_free(wmi_buf); 11516 return QDF_STATUS_E_FAILURE; 11517 } 11518 11519 /** 11520 * send_unit_test_cmd_tlv() - send unit test command to fw. 11521 * @wmi_handle: wmi handle 11522 * @wmi_utest: unit test command 11523 * 11524 * This function send unit test command to fw. 11525 * 11526 * Return: CDF STATUS 11527 */ 11528 static QDF_STATUS send_unit_test_cmd_tlv(wmi_unified_t wmi_handle, 11529 struct wmi_unit_test_cmd *wmi_utest) 11530 { 11531 wmi_unit_test_cmd_fixed_param *cmd; 11532 wmi_buf_t wmi_buf; 11533 uint8_t *buf_ptr; 11534 int i; 11535 uint16_t len, args_tlv_len; 11536 uint32_t *unit_test_cmd_args; 11537 11538 args_tlv_len = 11539 WMI_TLV_HDR_SIZE + wmi_utest->num_args * sizeof(uint32_t); 11540 len = sizeof(wmi_unit_test_cmd_fixed_param) + args_tlv_len; 11541 11542 wmi_buf = wmi_buf_alloc(wmi_handle, len); 11543 if (!wmi_buf) 11544 return QDF_STATUS_E_NOMEM; 11545 11546 cmd = (wmi_unit_test_cmd_fixed_param *) wmi_buf_data(wmi_buf); 11547 buf_ptr = (uint8_t *) cmd; 11548 WMITLV_SET_HDR(&cmd->tlv_header, 11549 WMITLV_TAG_STRUC_wmi_unit_test_cmd_fixed_param, 11550 WMITLV_GET_STRUCT_TLVLEN(wmi_unit_test_cmd_fixed_param)); 11551 cmd->vdev_id = wmi_utest->vdev_id; 11552 cmd->module_id = wmi_utest->module_id; 11553 cmd->num_args = wmi_utest->num_args; 11554 cmd->diag_token = wmi_utest->diag_token; 11555 buf_ptr += sizeof(wmi_unit_test_cmd_fixed_param); 11556 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, 11557 (wmi_utest->num_args * sizeof(uint32_t))); 11558 unit_test_cmd_args = (uint32_t *) (buf_ptr + WMI_TLV_HDR_SIZE); 11559 wmi_debug("VDEV ID: %d MODULE ID: %d TOKEN: %d", 11560 cmd->vdev_id, cmd->module_id, cmd->diag_token); 11561 wmi_debug("%d num of args = ", wmi_utest->num_args); 11562 for (i = 0; (i < wmi_utest->num_args && i < WMI_UNIT_TEST_MAX_NUM_ARGS); i++) { 11563 unit_test_cmd_args[i] = wmi_utest->args[i]; 11564 wmi_debug("%d,", wmi_utest->args[i]); 11565 } 11566 wmi_mtrace(WMI_UNIT_TEST_CMDID, cmd->vdev_id, 0); 11567 if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len, 11568 WMI_UNIT_TEST_CMDID)) { 11569 wmi_err("Failed to send unit test command"); 11570 wmi_buf_free(wmi_buf); 11571 return QDF_STATUS_E_FAILURE; 11572 } 11573 11574 return QDF_STATUS_SUCCESS; 11575 } 11576 11577 /** 11578 * send_power_dbg_cmd_tlv() - send power debug commands 11579 * @wmi_handle: wmi handle 11580 * @param: wmi power debug parameter 11581 * 11582 * Send WMI_POWER_DEBUG_CMDID parameters to fw. 11583 * 11584 * Return: QDF_STATUS_SUCCESS on success, QDF_STATUS_E_** on error 11585 */ 11586 static QDF_STATUS send_power_dbg_cmd_tlv(wmi_unified_t wmi_handle, 11587 struct wmi_power_dbg_params *param) 11588 { 11589 wmi_buf_t buf = NULL; 11590 QDF_STATUS status; 11591 int len, args_tlv_len; 11592 uint8_t *buf_ptr; 11593 uint8_t i; 11594 wmi_pdev_wal_power_debug_cmd_fixed_param *cmd; 11595 uint32_t *cmd_args; 11596 11597 /* Prepare and send power debug cmd parameters */ 11598 args_tlv_len = WMI_TLV_HDR_SIZE + param->num_args * sizeof(uint32_t); 11599 len = sizeof(*cmd) + args_tlv_len; 11600 buf = wmi_buf_alloc(wmi_handle, len); 11601 if (!buf) 11602 return QDF_STATUS_E_NOMEM; 11603 11604 buf_ptr = (uint8_t *) wmi_buf_data(buf); 11605 cmd = (wmi_pdev_wal_power_debug_cmd_fixed_param *) buf_ptr; 11606 WMITLV_SET_HDR(&cmd->tlv_header, 11607 WMITLV_TAG_STRUC_wmi_pdev_wal_power_debug_cmd_fixed_param, 11608 WMITLV_GET_STRUCT_TLVLEN 11609 (wmi_pdev_wal_power_debug_cmd_fixed_param)); 11610 11611 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 11612 wmi_handle, 11613 param->pdev_id); 11614 cmd->module_id = param->module_id; 11615 cmd->num_args = param->num_args; 11616 buf_ptr += sizeof(*cmd); 11617 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, 11618 (param->num_args * sizeof(uint32_t))); 11619 cmd_args = (uint32_t *) (buf_ptr + WMI_TLV_HDR_SIZE); 11620 wmi_debug("%d num of args = ", param->num_args); 11621 for (i = 0; (i < param->num_args && i < WMI_MAX_POWER_DBG_ARGS); i++) { 11622 cmd_args[i] = param->args[i]; 11623 wmi_debug("%d,", param->args[i]); 11624 } 11625 11626 wmi_mtrace(WMI_PDEV_WAL_POWER_DEBUG_CMDID, NO_SESSION, 0); 11627 status = wmi_unified_cmd_send(wmi_handle, buf, 11628 len, WMI_PDEV_WAL_POWER_DEBUG_CMDID); 11629 if (QDF_IS_STATUS_ERROR(status)) { 11630 wmi_err("wmi_unified_cmd_send WMI_PDEV_WAL_POWER_DEBUG_CMDID returned Error %d", 11631 status); 11632 goto error; 11633 } 11634 11635 return QDF_STATUS_SUCCESS; 11636 error: 11637 wmi_buf_free(buf); 11638 11639 return status; 11640 } 11641 11642 /** 11643 * send_dfs_phyerr_offload_en_cmd_tlv() - send dfs phyerr offload enable cmd 11644 * @wmi_handle: wmi handle 11645 * @pdev_id: pdev id 11646 * 11647 * Send WMI_PDEV_DFS_PHYERR_OFFLOAD_ENABLE_CMDID command to firmware. 11648 * 11649 * Return: QDF_STATUS_SUCCESS on success, QDF_STATUS_E_** on error 11650 */ 11651 static QDF_STATUS send_dfs_phyerr_offload_en_cmd_tlv(wmi_unified_t wmi_handle, 11652 uint32_t pdev_id) 11653 { 11654 wmi_pdev_dfs_phyerr_offload_enable_cmd_fixed_param *cmd; 11655 wmi_buf_t buf; 11656 uint16_t len; 11657 QDF_STATUS ret; 11658 11659 len = sizeof(*cmd); 11660 buf = wmi_buf_alloc(wmi_handle, len); 11661 11662 wmi_debug("pdev_id=%d", pdev_id); 11663 11664 if (!buf) 11665 return QDF_STATUS_E_NOMEM; 11666 11667 cmd = (wmi_pdev_dfs_phyerr_offload_enable_cmd_fixed_param *) 11668 wmi_buf_data(buf); 11669 11670 WMITLV_SET_HDR(&cmd->tlv_header, 11671 WMITLV_TAG_STRUC_wmi_pdev_dfs_phyerr_offload_enable_cmd_fixed_param, 11672 WMITLV_GET_STRUCT_TLVLEN( 11673 wmi_pdev_dfs_phyerr_offload_enable_cmd_fixed_param)); 11674 11675 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 11676 wmi_handle, 11677 pdev_id); 11678 wmi_mtrace(WMI_PDEV_DFS_PHYERR_OFFLOAD_ENABLE_CMDID, NO_SESSION, 0); 11679 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 11680 WMI_PDEV_DFS_PHYERR_OFFLOAD_ENABLE_CMDID); 11681 if (QDF_IS_STATUS_ERROR(ret)) { 11682 wmi_err("Failed to send cmd to fw, ret=%d, pdev_id=%d", 11683 ret, pdev_id); 11684 wmi_buf_free(buf); 11685 return QDF_STATUS_E_FAILURE; 11686 } 11687 11688 return QDF_STATUS_SUCCESS; 11689 } 11690 11691 /** 11692 * send_dfs_phyerr_offload_dis_cmd_tlv() - send dfs phyerr offload disable cmd 11693 * @wmi_handle: wmi handle 11694 * @pdev_id: pdev id 11695 * 11696 * Send WMI_PDEV_DFS_PHYERR_OFFLOAD_DISABLE_CMDID command to firmware. 11697 * 11698 * Return: QDF_STATUS_SUCCESS on success, QDF_STATUS_E_** on error 11699 */ 11700 static QDF_STATUS send_dfs_phyerr_offload_dis_cmd_tlv(wmi_unified_t wmi_handle, 11701 uint32_t pdev_id) 11702 { 11703 wmi_pdev_dfs_phyerr_offload_disable_cmd_fixed_param *cmd; 11704 wmi_buf_t buf; 11705 uint16_t len; 11706 QDF_STATUS ret; 11707 11708 len = sizeof(*cmd); 11709 buf = wmi_buf_alloc(wmi_handle, len); 11710 11711 wmi_debug("pdev_id=%d", pdev_id); 11712 11713 if (!buf) 11714 return QDF_STATUS_E_NOMEM; 11715 11716 cmd = (wmi_pdev_dfs_phyerr_offload_disable_cmd_fixed_param *) 11717 wmi_buf_data(buf); 11718 11719 WMITLV_SET_HDR(&cmd->tlv_header, 11720 WMITLV_TAG_STRUC_wmi_pdev_dfs_phyerr_offload_disable_cmd_fixed_param, 11721 WMITLV_GET_STRUCT_TLVLEN( 11722 wmi_pdev_dfs_phyerr_offload_disable_cmd_fixed_param)); 11723 11724 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 11725 wmi_handle, 11726 pdev_id); 11727 wmi_mtrace(WMI_PDEV_DFS_PHYERR_OFFLOAD_DISABLE_CMDID, NO_SESSION, 0); 11728 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 11729 WMI_PDEV_DFS_PHYERR_OFFLOAD_DISABLE_CMDID); 11730 if (QDF_IS_STATUS_ERROR(ret)) { 11731 wmi_err("Failed to send cmd to fw, ret=%d, pdev_id=%d", 11732 ret, pdev_id); 11733 wmi_buf_free(buf); 11734 return QDF_STATUS_E_FAILURE; 11735 } 11736 11737 return QDF_STATUS_SUCCESS; 11738 } 11739 11740 #ifdef QCA_SUPPORT_AGILE_DFS 11741 static 11742 QDF_STATUS send_adfs_ch_cfg_cmd_tlv(wmi_unified_t wmi_handle, 11743 struct vdev_adfs_ch_cfg_params *param) 11744 { 11745 /* wmi_unified_cmd_send set request of agile ADFS channel*/ 11746 wmi_vdev_adfs_ch_cfg_cmd_fixed_param *cmd; 11747 wmi_buf_t buf; 11748 QDF_STATUS ret; 11749 uint16_t len; 11750 11751 len = sizeof(*cmd); 11752 buf = wmi_buf_alloc(wmi_handle, len); 11753 11754 if (!buf) { 11755 wmi_err("wmi_buf_alloc failed"); 11756 return QDF_STATUS_E_NOMEM; 11757 } 11758 11759 cmd = (wmi_vdev_adfs_ch_cfg_cmd_fixed_param *) 11760 wmi_buf_data(buf); 11761 11762 WMITLV_SET_HDR(&cmd->tlv_header, 11763 WMITLV_TAG_STRUC_wmi_vdev_adfs_ch_cfg_cmd_fixed_param, 11764 WMITLV_GET_STRUCT_TLVLEN 11765 (wmi_vdev_adfs_ch_cfg_cmd_fixed_param)); 11766 11767 cmd->vdev_id = param->vdev_id; 11768 cmd->ocac_mode = param->ocac_mode; 11769 cmd->center_freq1 = param->center_freq1; 11770 cmd->center_freq2 = param->center_freq2; 11771 cmd->chan_freq = param->chan_freq; 11772 cmd->chan_width = param->chan_width; 11773 cmd->min_duration_ms = param->min_duration_ms; 11774 cmd->max_duration_ms = param->max_duration_ms; 11775 wmi_debug("cmd->vdev_id: %d ,cmd->ocac_mode: %d cmd->center_freq: %d", 11776 cmd->vdev_id, cmd->ocac_mode, 11777 cmd->center_freq); 11778 11779 wmi_mtrace(WMI_VDEV_ADFS_CH_CFG_CMDID, NO_SESSION, 0); 11780 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 11781 WMI_VDEV_ADFS_CH_CFG_CMDID); 11782 11783 if (QDF_IS_STATUS_ERROR(ret)) { 11784 wmi_err("Failed to send cmd to fw, ret=%d", ret); 11785 wmi_buf_free(buf); 11786 return QDF_STATUS_E_FAILURE; 11787 } 11788 11789 return QDF_STATUS_SUCCESS; 11790 } 11791 11792 static 11793 QDF_STATUS send_adfs_ocac_abort_cmd_tlv(wmi_unified_t wmi_handle, 11794 struct vdev_adfs_abort_params *param) 11795 { 11796 /*wmi_unified_cmd_send with ocac abort on ADFS channel*/ 11797 wmi_vdev_adfs_ocac_abort_cmd_fixed_param *cmd; 11798 wmi_buf_t buf; 11799 QDF_STATUS ret; 11800 uint16_t len; 11801 11802 len = sizeof(*cmd); 11803 buf = wmi_buf_alloc(wmi_handle, len); 11804 11805 if (!buf) { 11806 wmi_err("wmi_buf_alloc failed"); 11807 return QDF_STATUS_E_NOMEM; 11808 } 11809 11810 cmd = (wmi_vdev_adfs_ocac_abort_cmd_fixed_param *) 11811 wmi_buf_data(buf); 11812 11813 WMITLV_SET_HDR 11814 (&cmd->tlv_header, 11815 WMITLV_TAG_STRUC_wmi_vdev_adfs_ocac_abort_cmd_fixed_param, 11816 WMITLV_GET_STRUCT_TLVLEN 11817 (wmi_vdev_adfs_ocac_abort_cmd_fixed_param)); 11818 11819 cmd->vdev_id = param->vdev_id; 11820 11821 wmi_mtrace(WMI_VDEV_ADFS_OCAC_ABORT_CMDID, NO_SESSION, 0); 11822 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 11823 WMI_VDEV_ADFS_OCAC_ABORT_CMDID); 11824 11825 if (QDF_IS_STATUS_ERROR(ret)) { 11826 wmi_err("Failed to send cmd to fw, ret=%d", ret); 11827 wmi_buf_free(buf); 11828 return QDF_STATUS_E_FAILURE; 11829 } 11830 11831 return QDF_STATUS_SUCCESS; 11832 } 11833 #endif 11834 11835 /** 11836 * init_cmd_send_tlv() - send initialization cmd to fw 11837 * @wmi_handle: wmi handle 11838 * @param: pointer to wmi init param 11839 * 11840 * Return: QDF_STATUS_SUCCESS for success or error code 11841 */ 11842 static QDF_STATUS init_cmd_send_tlv(wmi_unified_t wmi_handle, 11843 struct wmi_init_cmd_param *param) 11844 { 11845 wmi_buf_t buf; 11846 wmi_init_cmd_fixed_param *cmd; 11847 uint8_t *buf_ptr; 11848 wmi_resource_config *resource_cfg; 11849 wlan_host_memory_chunk *host_mem_chunks; 11850 uint32_t mem_chunk_len = 0, hw_mode_len = 0; 11851 uint16_t idx; 11852 int len; 11853 QDF_STATUS ret; 11854 11855 len = sizeof(*cmd) + sizeof(wmi_resource_config) + 11856 WMI_TLV_HDR_SIZE; 11857 mem_chunk_len = (sizeof(wlan_host_memory_chunk) * MAX_MEM_CHUNKS); 11858 11859 if (param->hw_mode_id != WMI_HOST_HW_MODE_MAX) 11860 hw_mode_len = sizeof(wmi_pdev_set_hw_mode_cmd_fixed_param) + 11861 WMI_TLV_HDR_SIZE + 11862 (param->num_band_to_mac * sizeof(wmi_pdev_band_to_mac)); 11863 11864 buf = wmi_buf_alloc(wmi_handle, len + mem_chunk_len + hw_mode_len); 11865 if (!buf) 11866 return QDF_STATUS_E_FAILURE; 11867 11868 buf_ptr = (uint8_t *) wmi_buf_data(buf); 11869 cmd = (wmi_init_cmd_fixed_param *) buf_ptr; 11870 resource_cfg = (wmi_resource_config *) (buf_ptr + sizeof(*cmd)); 11871 11872 host_mem_chunks = (wlan_host_memory_chunk *) 11873 (buf_ptr + sizeof(*cmd) + sizeof(wmi_resource_config) 11874 + WMI_TLV_HDR_SIZE); 11875 11876 WMITLV_SET_HDR(&cmd->tlv_header, 11877 WMITLV_TAG_STRUC_wmi_init_cmd_fixed_param, 11878 WMITLV_GET_STRUCT_TLVLEN(wmi_init_cmd_fixed_param)); 11879 wmi_copy_resource_config(resource_cfg, param->res_cfg); 11880 WMITLV_SET_HDR(&resource_cfg->tlv_header, 11881 WMITLV_TAG_STRUC_wmi_resource_config, 11882 WMITLV_GET_STRUCT_TLVLEN(wmi_resource_config)); 11883 11884 for (idx = 0; idx < param->num_mem_chunks; ++idx) { 11885 WMITLV_SET_HDR(&(host_mem_chunks[idx].tlv_header), 11886 WMITLV_TAG_STRUC_wlan_host_memory_chunk, 11887 WMITLV_GET_STRUCT_TLVLEN 11888 (wlan_host_memory_chunk)); 11889 host_mem_chunks[idx].ptr = param->mem_chunks[idx].paddr; 11890 host_mem_chunks[idx].size = param->mem_chunks[idx].len; 11891 host_mem_chunks[idx].req_id = param->mem_chunks[idx].req_id; 11892 if (is_service_enabled_tlv(wmi_handle, 11893 WMI_SERVICE_SUPPORT_EXTEND_ADDRESS)) 11894 host_mem_chunks[idx].ptr_high = 11895 qdf_get_upper_32_bits( 11896 param->mem_chunks[idx].paddr); 11897 QDF_TRACE(QDF_MODULE_ID_ANY, QDF_TRACE_LEVEL_DEBUG, 11898 "chunk %d len %d requested ,ptr 0x%x ", 11899 idx, host_mem_chunks[idx].size, 11900 host_mem_chunks[idx].ptr); 11901 } 11902 cmd->num_host_mem_chunks = param->num_mem_chunks; 11903 len += (param->num_mem_chunks * sizeof(wlan_host_memory_chunk)); 11904 11905 WMITLV_SET_HDR((buf_ptr + sizeof(*cmd) + sizeof(wmi_resource_config)), 11906 WMITLV_TAG_ARRAY_STRUC, 11907 (sizeof(wlan_host_memory_chunk) * 11908 param->num_mem_chunks)); 11909 11910 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", 11911 resource_cfg->num_peers, resource_cfg->num_offload_peers, 11912 resource_cfg->num_vdevs, resource_cfg->num_tids, 11913 resource_cfg->num_tdls_conn_table_entries, 11914 resource_cfg->num_tdls_vdevs); 11915 11916 /* Fill hw mode id config */ 11917 buf_ptr = copy_hw_mode_in_init_cmd(wmi_handle, buf_ptr, &len, param); 11918 11919 /* Fill fw_abi_vers */ 11920 copy_fw_abi_version_tlv(wmi_handle, cmd); 11921 11922 wmi_mtrace(WMI_INIT_CMDID, NO_SESSION, 0); 11923 ret = wmi_unified_cmd_send(wmi_handle, buf, len, WMI_INIT_CMDID); 11924 if (QDF_IS_STATUS_ERROR(ret)) { 11925 wmi_err("wmi_unified_cmd_send WMI_INIT_CMDID returned Error %d", 11926 ret); 11927 wmi_buf_free(buf); 11928 } 11929 11930 return ret; 11931 11932 } 11933 11934 /** 11935 * send_addba_send_cmd_tlv() - send addba send command to fw 11936 * @wmi_handle: wmi handle 11937 * @param: pointer to delba send params 11938 * @macaddr: peer mac address 11939 * 11940 * Send WMI_ADDBA_SEND_CMDID command to firmware 11941 * Return: QDF_STATUS_SUCCESS on success. QDF_STATUS_E** on error 11942 */ 11943 static QDF_STATUS 11944 send_addba_send_cmd_tlv(wmi_unified_t wmi_handle, 11945 uint8_t macaddr[QDF_MAC_ADDR_SIZE], 11946 struct addba_send_params *param) 11947 { 11948 wmi_addba_send_cmd_fixed_param *cmd; 11949 wmi_buf_t buf; 11950 uint16_t len; 11951 QDF_STATUS ret; 11952 11953 len = sizeof(*cmd); 11954 11955 buf = wmi_buf_alloc(wmi_handle, len); 11956 if (!buf) 11957 return QDF_STATUS_E_NOMEM; 11958 11959 cmd = (wmi_addba_send_cmd_fixed_param *)wmi_buf_data(buf); 11960 11961 WMITLV_SET_HDR(&cmd->tlv_header, 11962 WMITLV_TAG_STRUC_wmi_addba_send_cmd_fixed_param, 11963 WMITLV_GET_STRUCT_TLVLEN(wmi_addba_send_cmd_fixed_param)); 11964 11965 cmd->vdev_id = param->vdev_id; 11966 WMI_CHAR_ARRAY_TO_MAC_ADDR(macaddr, &cmd->peer_macaddr); 11967 cmd->tid = param->tidno; 11968 cmd->buffersize = param->buffersize; 11969 11970 wmi_mtrace(WMI_ADDBA_SEND_CMDID, cmd->vdev_id, 0); 11971 ret = wmi_unified_cmd_send(wmi_handle, buf, len, WMI_ADDBA_SEND_CMDID); 11972 if (QDF_IS_STATUS_ERROR(ret)) { 11973 wmi_err("Failed to send cmd to fw, ret=%d", ret); 11974 wmi_buf_free(buf); 11975 return QDF_STATUS_E_FAILURE; 11976 } 11977 11978 return QDF_STATUS_SUCCESS; 11979 } 11980 11981 /** 11982 * send_delba_send_cmd_tlv() - send delba send command to fw 11983 * @wmi_handle: wmi handle 11984 * @param: pointer to delba send params 11985 * @macaddr: peer mac address 11986 * 11987 * Send WMI_DELBA_SEND_CMDID command to firmware 11988 * Return: QDF_STATUS_SUCCESS on success. QDF_STATUS_E** on error 11989 */ 11990 static QDF_STATUS 11991 send_delba_send_cmd_tlv(wmi_unified_t wmi_handle, 11992 uint8_t macaddr[QDF_MAC_ADDR_SIZE], 11993 struct delba_send_params *param) 11994 { 11995 wmi_delba_send_cmd_fixed_param *cmd; 11996 wmi_buf_t buf; 11997 uint16_t len; 11998 QDF_STATUS ret; 11999 12000 len = sizeof(*cmd); 12001 12002 buf = wmi_buf_alloc(wmi_handle, len); 12003 if (!buf) 12004 return QDF_STATUS_E_NOMEM; 12005 12006 cmd = (wmi_delba_send_cmd_fixed_param *)wmi_buf_data(buf); 12007 12008 WMITLV_SET_HDR(&cmd->tlv_header, 12009 WMITLV_TAG_STRUC_wmi_delba_send_cmd_fixed_param, 12010 WMITLV_GET_STRUCT_TLVLEN(wmi_delba_send_cmd_fixed_param)); 12011 12012 cmd->vdev_id = param->vdev_id; 12013 WMI_CHAR_ARRAY_TO_MAC_ADDR(macaddr, &cmd->peer_macaddr); 12014 cmd->tid = param->tidno; 12015 cmd->initiator = param->initiator; 12016 cmd->reasoncode = param->reasoncode; 12017 12018 wmi_mtrace(WMI_DELBA_SEND_CMDID, cmd->vdev_id, 0); 12019 ret = wmi_unified_cmd_send(wmi_handle, buf, len, WMI_DELBA_SEND_CMDID); 12020 if (QDF_IS_STATUS_ERROR(ret)) { 12021 wmi_err("Failed to send cmd to fw, ret=%d", ret); 12022 wmi_buf_free(buf); 12023 return QDF_STATUS_E_FAILURE; 12024 } 12025 12026 return QDF_STATUS_SUCCESS; 12027 } 12028 12029 /** 12030 * send_addba_clearresponse_cmd_tlv() - send addba clear response command 12031 * to fw 12032 * @wmi_handle: wmi handle 12033 * @param: pointer to addba clearresp params 12034 * @macaddr: peer mac address 12035 * Return: QDF_STATUS_SUCCESS for success or error code 12036 */ 12037 static QDF_STATUS 12038 send_addba_clearresponse_cmd_tlv(wmi_unified_t wmi_handle, 12039 uint8_t macaddr[QDF_MAC_ADDR_SIZE], 12040 struct addba_clearresponse_params *param) 12041 { 12042 wmi_addba_clear_resp_cmd_fixed_param *cmd; 12043 wmi_buf_t buf; 12044 uint16_t len; 12045 QDF_STATUS ret; 12046 12047 len = sizeof(*cmd); 12048 12049 buf = wmi_buf_alloc(wmi_handle, len); 12050 if (!buf) 12051 return QDF_STATUS_E_FAILURE; 12052 12053 cmd = (wmi_addba_clear_resp_cmd_fixed_param *)wmi_buf_data(buf); 12054 12055 WMITLV_SET_HDR(&cmd->tlv_header, 12056 WMITLV_TAG_STRUC_wmi_addba_clear_resp_cmd_fixed_param, 12057 WMITLV_GET_STRUCT_TLVLEN(wmi_addba_clear_resp_cmd_fixed_param)); 12058 12059 cmd->vdev_id = param->vdev_id; 12060 WMI_CHAR_ARRAY_TO_MAC_ADDR(macaddr, &cmd->peer_macaddr); 12061 12062 wmi_mtrace(WMI_ADDBA_CLEAR_RESP_CMDID, cmd->vdev_id, 0); 12063 ret = wmi_unified_cmd_send(wmi_handle, 12064 buf, len, WMI_ADDBA_CLEAR_RESP_CMDID); 12065 if (QDF_IS_STATUS_ERROR(ret)) { 12066 wmi_err("Failed to send cmd to fw, ret=%d", ret); 12067 wmi_buf_free(buf); 12068 return QDF_STATUS_E_FAILURE; 12069 } 12070 12071 return QDF_STATUS_SUCCESS; 12072 } 12073 12074 #ifdef OBSS_PD 12075 /** 12076 * send_obss_spatial_reuse_set_def_thresh_cmd_tlv - send obss spatial reuse set 12077 * def thresh to fw 12078 * @wmi_handle: wmi handle 12079 * @thresh: pointer to obss_spatial_reuse_def_thresh 12080 * 12081 * Return: QDF_STATUS_SUCCESS for success or error code 12082 */ 12083 static 12084 QDF_STATUS send_obss_spatial_reuse_set_def_thresh_cmd_tlv( 12085 wmi_unified_t wmi_handle, 12086 struct wmi_host_obss_spatial_reuse_set_def_thresh 12087 *thresh) 12088 { 12089 wmi_buf_t buf; 12090 wmi_obss_spatial_reuse_set_def_obss_thresh_cmd_fixed_param *cmd; 12091 QDF_STATUS ret; 12092 uint32_t cmd_len; 12093 uint32_t tlv_len; 12094 12095 cmd_len = sizeof(*cmd); 12096 12097 buf = wmi_buf_alloc(wmi_handle, cmd_len); 12098 if (!buf) 12099 return QDF_STATUS_E_NOMEM; 12100 12101 cmd = (wmi_obss_spatial_reuse_set_def_obss_thresh_cmd_fixed_param *) 12102 wmi_buf_data(buf); 12103 12104 tlv_len = WMITLV_GET_STRUCT_TLVLEN( 12105 wmi_obss_spatial_reuse_set_def_obss_thresh_cmd_fixed_param); 12106 12107 WMITLV_SET_HDR(&cmd->tlv_header, 12108 WMITLV_TAG_STRUC_wmi_obss_spatial_reuse_set_def_obss_thresh_cmd_fixed_param, 12109 tlv_len); 12110 12111 cmd->obss_min = thresh->obss_min; 12112 cmd->obss_max = thresh->obss_max; 12113 cmd->vdev_type = thresh->vdev_type; 12114 ret = wmi_unified_cmd_send(wmi_handle, buf, cmd_len, 12115 WMI_PDEV_OBSS_PD_SPATIAL_REUSE_SET_DEF_OBSS_THRESH_CMDID); 12116 if (QDF_IS_STATUS_ERROR(ret)) 12117 wmi_buf_free(buf); 12118 12119 return ret; 12120 } 12121 12122 /** 12123 * send_obss_spatial_reuse_set_cmd_tlv - send obss spatial reuse set cmd to fw 12124 * @wmi_handle: wmi handle 12125 * @obss_spatial_reuse_param: pointer to obss_spatial_reuse_param 12126 * 12127 * Return: QDF_STATUS_SUCCESS for success or error code 12128 */ 12129 static 12130 QDF_STATUS send_obss_spatial_reuse_set_cmd_tlv(wmi_unified_t wmi_handle, 12131 struct wmi_host_obss_spatial_reuse_set_param 12132 *obss_spatial_reuse_param) 12133 { 12134 wmi_buf_t buf; 12135 wmi_obss_spatial_reuse_set_cmd_fixed_param *cmd; 12136 QDF_STATUS ret; 12137 uint32_t len; 12138 12139 len = sizeof(*cmd); 12140 12141 buf = wmi_buf_alloc(wmi_handle, len); 12142 if (!buf) 12143 return QDF_STATUS_E_FAILURE; 12144 12145 cmd = (wmi_obss_spatial_reuse_set_cmd_fixed_param *)wmi_buf_data(buf); 12146 WMITLV_SET_HDR(&cmd->tlv_header, 12147 WMITLV_TAG_STRUC_wmi_obss_spatial_reuse_set_cmd_fixed_param, 12148 WMITLV_GET_STRUCT_TLVLEN 12149 (wmi_obss_spatial_reuse_set_cmd_fixed_param)); 12150 12151 cmd->enable = obss_spatial_reuse_param->enable; 12152 cmd->obss_min = obss_spatial_reuse_param->obss_min; 12153 cmd->obss_max = obss_spatial_reuse_param->obss_max; 12154 cmd->vdev_id = obss_spatial_reuse_param->vdev_id; 12155 12156 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 12157 WMI_PDEV_OBSS_PD_SPATIAL_REUSE_CMDID); 12158 12159 if (QDF_IS_STATUS_ERROR(ret)) { 12160 wmi_err( 12161 "WMI_PDEV_OBSS_PD_SPATIAL_REUSE_CMDID send returned Error %d", 12162 ret); 12163 wmi_buf_free(buf); 12164 } 12165 12166 return ret; 12167 } 12168 12169 /** 12170 * send_self_srg_bss_color_bitmap_set_cmd_tlv() - Send 64-bit BSS color bitmap 12171 * to be used by SRG based Spatial Reuse feature to the FW 12172 * @wmi_handle: wmi handle 12173 * @bitmap_0: lower 32 bits in BSS color bitmap 12174 * @bitmap_1: upper 32 bits in BSS color bitmap 12175 * @pdev_id: pdev ID 12176 * 12177 * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure 12178 */ 12179 static QDF_STATUS 12180 send_self_srg_bss_color_bitmap_set_cmd_tlv( 12181 wmi_unified_t wmi_handle, uint32_t bitmap_0, 12182 uint32_t bitmap_1, uint8_t pdev_id) 12183 { 12184 wmi_buf_t buf; 12185 wmi_pdev_srg_bss_color_bitmap_cmd_fixed_param *cmd; 12186 QDF_STATUS ret; 12187 uint32_t len; 12188 12189 len = sizeof(*cmd); 12190 12191 buf = wmi_buf_alloc(wmi_handle, len); 12192 if (!buf) 12193 return QDF_STATUS_E_FAILURE; 12194 12195 cmd = (wmi_pdev_srg_bss_color_bitmap_cmd_fixed_param *) 12196 wmi_buf_data(buf); 12197 12198 WMITLV_SET_HDR( 12199 &cmd->tlv_header, 12200 WMITLV_TAG_STRUC_wmi_pdev_srg_bss_color_bitmap_cmd_fixed_param, 12201 WMITLV_GET_STRUCT_TLVLEN 12202 (wmi_pdev_srg_bss_color_bitmap_cmd_fixed_param)); 12203 12204 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 12205 wmi_handle, pdev_id); 12206 cmd->srg_bss_color_bitmap[0] = bitmap_0; 12207 cmd->srg_bss_color_bitmap[1] = bitmap_1; 12208 12209 ret = wmi_unified_cmd_send( 12210 wmi_handle, buf, len, 12211 WMI_PDEV_SET_SRG_BSS_COLOR_BITMAP_CMDID); 12212 12213 if (QDF_IS_STATUS_ERROR(ret)) { 12214 wmi_err( 12215 "WMI_PDEV_SET_SRG_BSS_COLOR_BITMAP_CMDID send returned Error %d", 12216 ret); 12217 wmi_buf_free(buf); 12218 } 12219 12220 return ret; 12221 } 12222 12223 /** 12224 * send_self_srg_partial_bssid_bitmap_set_cmd_tlv() - Send 64-bit partial BSSID 12225 * bitmap to be used by SRG based Spatial Reuse feature to the FW 12226 * @wmi_handle: wmi handle 12227 * @bitmap_0: lower 32 bits in partial BSSID bitmap 12228 * @bitmap_1: upper 32 bits in partial BSSID bitmap 12229 * @pdev_id: pdev ID 12230 * 12231 * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure 12232 */ 12233 static QDF_STATUS 12234 send_self_srg_partial_bssid_bitmap_set_cmd_tlv( 12235 wmi_unified_t wmi_handle, uint32_t bitmap_0, 12236 uint32_t bitmap_1, uint8_t pdev_id) 12237 { 12238 wmi_buf_t buf; 12239 wmi_pdev_srg_partial_bssid_bitmap_cmd_fixed_param *cmd; 12240 QDF_STATUS ret; 12241 uint32_t len; 12242 12243 len = sizeof(*cmd); 12244 12245 buf = wmi_buf_alloc(wmi_handle, len); 12246 if (!buf) 12247 return QDF_STATUS_E_FAILURE; 12248 12249 cmd = (wmi_pdev_srg_partial_bssid_bitmap_cmd_fixed_param *) 12250 wmi_buf_data(buf); 12251 12252 WMITLV_SET_HDR( 12253 &cmd->tlv_header, 12254 WMITLV_TAG_STRUC_wmi_pdev_srg_partial_bssid_bitmap_cmd_fixed_param, 12255 WMITLV_GET_STRUCT_TLVLEN 12256 (wmi_pdev_srg_partial_bssid_bitmap_cmd_fixed_param)); 12257 12258 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 12259 wmi_handle, pdev_id); 12260 12261 cmd->srg_partial_bssid_bitmap[0] = bitmap_0; 12262 cmd->srg_partial_bssid_bitmap[1] = bitmap_1; 12263 12264 ret = wmi_unified_cmd_send( 12265 wmi_handle, buf, len, 12266 WMI_PDEV_SET_SRG_PARTIAL_BSSID_BITMAP_CMDID); 12267 12268 if (QDF_IS_STATUS_ERROR(ret)) { 12269 wmi_err( 12270 "WMI_PDEV_SET_SRG_PARTIAL_BSSID_BITMAP_CMDID send returned Error %d", 12271 ret); 12272 wmi_buf_free(buf); 12273 } 12274 12275 return ret; 12276 } 12277 12278 /** 12279 * send_self_srg_obss_color_enable_bitmap_cmd_tlv() - Send 64-bit BSS color 12280 * enable bitmap to be used by SRG based Spatial Reuse feature to the FW 12281 * @wmi_handle: wmi handle 12282 * @bitmap_0: lower 32 bits in BSS color enable bitmap 12283 * @bitmap_1: upper 32 bits in BSS color enable bitmap 12284 * @pdev_id: pdev ID 12285 * 12286 * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure 12287 */ 12288 static QDF_STATUS 12289 send_self_srg_obss_color_enable_bitmap_cmd_tlv( 12290 wmi_unified_t wmi_handle, uint32_t bitmap_0, 12291 uint32_t bitmap_1, uint8_t pdev_id) 12292 { 12293 wmi_buf_t buf; 12294 wmi_pdev_srg_obss_color_enable_bitmap_cmd_fixed_param *cmd; 12295 QDF_STATUS ret; 12296 uint32_t len; 12297 12298 len = sizeof(*cmd); 12299 12300 buf = wmi_buf_alloc(wmi_handle, len); 12301 if (!buf) 12302 return QDF_STATUS_E_FAILURE; 12303 12304 cmd = (wmi_pdev_srg_obss_color_enable_bitmap_cmd_fixed_param *) 12305 wmi_buf_data(buf); 12306 12307 WMITLV_SET_HDR( 12308 &cmd->tlv_header, 12309 WMITLV_TAG_STRUC_wmi_pdev_srg_obss_color_enable_bitmap_cmd_fixed_param, 12310 WMITLV_GET_STRUCT_TLVLEN 12311 (wmi_pdev_srg_obss_color_enable_bitmap_cmd_fixed_param)); 12312 12313 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 12314 wmi_handle, pdev_id); 12315 cmd->srg_obss_en_color_bitmap[0] = bitmap_0; 12316 cmd->srg_obss_en_color_bitmap[1] = bitmap_1; 12317 12318 ret = wmi_unified_cmd_send( 12319 wmi_handle, buf, len, 12320 WMI_PDEV_SET_SRG_OBSS_COLOR_ENABLE_BITMAP_CMDID); 12321 12322 if (QDF_IS_STATUS_ERROR(ret)) { 12323 wmi_err( 12324 "WMI_PDEV_SET_SRG_OBSS_COLOR_ENABLE_BITMAP_CMDID send returned Error %d", 12325 ret); 12326 wmi_buf_free(buf); 12327 } 12328 12329 return ret; 12330 } 12331 12332 /** 12333 * send_self_srg_obss_bssid_enable_bitmap_cmd_tlv() - Send 64-bit OBSS BSSID 12334 * enable bitmap to be used by SRG based Spatial Reuse feature to the FW 12335 * @wmi_handle: wmi handle 12336 * @bitmap_0: lower 32 bits in BSSID enable bitmap 12337 * @bitmap_1: upper 32 bits in BSSID enable bitmap 12338 * @pdev_id: pdev ID 12339 * 12340 * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure 12341 */ 12342 static QDF_STATUS 12343 send_self_srg_obss_bssid_enable_bitmap_cmd_tlv( 12344 wmi_unified_t wmi_handle, uint32_t bitmap_0, 12345 uint32_t bitmap_1, uint8_t pdev_id) 12346 { 12347 wmi_buf_t buf; 12348 wmi_pdev_srg_obss_bssid_enable_bitmap_cmd_fixed_param *cmd; 12349 QDF_STATUS ret; 12350 uint32_t len; 12351 12352 len = sizeof(*cmd); 12353 12354 buf = wmi_buf_alloc(wmi_handle, len); 12355 if (!buf) 12356 return QDF_STATUS_E_FAILURE; 12357 12358 cmd = (wmi_pdev_srg_obss_bssid_enable_bitmap_cmd_fixed_param *) 12359 wmi_buf_data(buf); 12360 12361 WMITLV_SET_HDR( 12362 &cmd->tlv_header, 12363 WMITLV_TAG_STRUC_wmi_pdev_srg_obss_bssid_enable_bitmap_cmd_fixed_param, 12364 WMITLV_GET_STRUCT_TLVLEN 12365 (wmi_pdev_srg_obss_bssid_enable_bitmap_cmd_fixed_param)); 12366 12367 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 12368 wmi_handle, pdev_id); 12369 cmd->srg_obss_en_bssid_bitmap[0] = bitmap_0; 12370 cmd->srg_obss_en_bssid_bitmap[1] = bitmap_1; 12371 12372 ret = wmi_unified_cmd_send( 12373 wmi_handle, buf, len, 12374 WMI_PDEV_SET_SRG_OBSS_BSSID_ENABLE_BITMAP_CMDID); 12375 12376 if (QDF_IS_STATUS_ERROR(ret)) { 12377 wmi_err( 12378 "WMI_PDEV_SET_SRG_OBSS_BSSID_ENABLE_BITMAP_CMDID send returned Error %d", 12379 ret); 12380 wmi_buf_free(buf); 12381 } 12382 12383 return ret; 12384 } 12385 12386 /** 12387 * send_self_non_srg_obss_color_enable_bitmap_cmd_tlv() - Send 64-bit BSS color 12388 * enable bitmap to be used by Non-SRG based Spatial Reuse feature to the FW 12389 * @wmi_handle: wmi handle 12390 * @bitmap_0: lower 32 bits in BSS color enable bitmap 12391 * @bitmap_1: upper 32 bits in BSS color enable bitmap 12392 * @pdev_id: pdev ID 12393 * 12394 * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure 12395 */ 12396 static QDF_STATUS 12397 send_self_non_srg_obss_color_enable_bitmap_cmd_tlv( 12398 wmi_unified_t wmi_handle, uint32_t bitmap_0, 12399 uint32_t bitmap_1, uint8_t pdev_id) 12400 { 12401 wmi_buf_t buf; 12402 wmi_pdev_non_srg_obss_color_enable_bitmap_cmd_fixed_param *cmd; 12403 QDF_STATUS ret; 12404 uint32_t len; 12405 12406 len = sizeof(*cmd); 12407 12408 buf = wmi_buf_alloc(wmi_handle, len); 12409 if (!buf) 12410 return QDF_STATUS_E_FAILURE; 12411 12412 cmd = (wmi_pdev_non_srg_obss_color_enable_bitmap_cmd_fixed_param *) 12413 wmi_buf_data(buf); 12414 12415 WMITLV_SET_HDR( 12416 &cmd->tlv_header, 12417 WMITLV_TAG_STRUC_wmi_pdev_non_srg_obss_color_enable_bitmap_cmd_fixed_param, 12418 WMITLV_GET_STRUCT_TLVLEN 12419 (wmi_pdev_non_srg_obss_color_enable_bitmap_cmd_fixed_param)); 12420 12421 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 12422 wmi_handle, pdev_id); 12423 cmd->non_srg_obss_en_color_bitmap[0] = bitmap_0; 12424 cmd->non_srg_obss_en_color_bitmap[1] = bitmap_1; 12425 12426 ret = wmi_unified_cmd_send( 12427 wmi_handle, buf, len, 12428 WMI_PDEV_SET_NON_SRG_OBSS_COLOR_ENABLE_BITMAP_CMDID); 12429 12430 if (QDF_IS_STATUS_ERROR(ret)) { 12431 wmi_err( 12432 "WMI_PDEV_SET_NON_SRG_OBSS_COLOR_ENABLE_BITMAP_CMDID send returned Error %d", 12433 ret); 12434 wmi_buf_free(buf); 12435 } 12436 12437 return ret; 12438 } 12439 12440 /** 12441 * send_self_non_srg_obss_bssid_enable_bitmap_cmd_tlv() - Send 64-bit OBSS BSSID 12442 * enable bitmap to be used by Non-SRG based Spatial Reuse feature to the FW 12443 * @wmi_handle: wmi handle 12444 * @bitmap_0: lower 32 bits in BSSID enable bitmap 12445 * @bitmap_1: upper 32 bits in BSSID enable bitmap 12446 * @pdev_id: pdev ID 12447 * 12448 * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure 12449 */ 12450 static QDF_STATUS 12451 send_self_non_srg_obss_bssid_enable_bitmap_cmd_tlv( 12452 wmi_unified_t wmi_handle, uint32_t bitmap_0, 12453 uint32_t bitmap_1, uint8_t pdev_id) 12454 { 12455 wmi_buf_t buf; 12456 wmi_pdev_non_srg_obss_bssid_enable_bitmap_cmd_fixed_param *cmd; 12457 QDF_STATUS ret; 12458 uint32_t len; 12459 12460 len = sizeof(*cmd); 12461 12462 buf = wmi_buf_alloc(wmi_handle, len); 12463 if (!buf) 12464 return QDF_STATUS_E_FAILURE; 12465 12466 cmd = (wmi_pdev_non_srg_obss_bssid_enable_bitmap_cmd_fixed_param *) 12467 wmi_buf_data(buf); 12468 12469 WMITLV_SET_HDR( 12470 &cmd->tlv_header, 12471 WMITLV_TAG_STRUC_wmi_pdev_non_srg_obss_bssid_enable_bitmap_cmd_fixed_param, 12472 WMITLV_GET_STRUCT_TLVLEN 12473 (wmi_pdev_non_srg_obss_bssid_enable_bitmap_cmd_fixed_param)); 12474 12475 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 12476 wmi_handle, pdev_id); 12477 cmd->non_srg_obss_en_bssid_bitmap[0] = bitmap_0; 12478 cmd->non_srg_obss_en_bssid_bitmap[1] = bitmap_1; 12479 12480 ret = wmi_unified_cmd_send( 12481 wmi_handle, buf, len, 12482 WMI_PDEV_SET_NON_SRG_OBSS_BSSID_ENABLE_BITMAP_CMDID); 12483 12484 if (QDF_IS_STATUS_ERROR(ret)) { 12485 wmi_err( 12486 "WMI_PDEV_SET_NON_SRG_OBSS_BSSID_ENABLE_BITMAP_CMDID send returned Error %d", 12487 ret); 12488 wmi_buf_free(buf); 12489 } 12490 12491 return ret; 12492 } 12493 #endif 12494 12495 static 12496 QDF_STATUS send_injector_config_cmd_tlv(wmi_unified_t wmi_handle, 12497 struct wmi_host_injector_frame_params *inject_config_params) 12498 { 12499 wmi_buf_t buf; 12500 wmi_frame_inject_cmd_fixed_param *cmd; 12501 QDF_STATUS ret; 12502 uint32_t len; 12503 12504 len = sizeof(*cmd); 12505 12506 buf = wmi_buf_alloc(wmi_handle, len); 12507 if (!buf) 12508 return QDF_STATUS_E_NOMEM; 12509 12510 cmd = (wmi_frame_inject_cmd_fixed_param *)wmi_buf_data(buf); 12511 WMITLV_SET_HDR(&cmd->tlv_header, 12512 WMITLV_TAG_STRUC_wmi_frame_inject_cmd_fixed_param, 12513 WMITLV_GET_STRUCT_TLVLEN 12514 (wmi_frame_inject_cmd_fixed_param)); 12515 12516 cmd->vdev_id = inject_config_params->vdev_id; 12517 cmd->enable = inject_config_params->enable; 12518 cmd->frame_type = inject_config_params->frame_type; 12519 cmd->frame_inject_period = inject_config_params->frame_inject_period; 12520 cmd->fc_duration = inject_config_params->frame_duration; 12521 WMI_CHAR_ARRAY_TO_MAC_ADDR(inject_config_params->dstmac, 12522 &cmd->frame_addr1); 12523 cmd->bw = inject_config_params->frame_bw; 12524 12525 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 12526 WMI_PDEV_FRAME_INJECT_CMDID); 12527 12528 if (QDF_IS_STATUS_ERROR(ret)) { 12529 wmi_err( 12530 "WMI_PDEV_FRAME_INJECT_CMDID send returned Error %d", 12531 ret); 12532 wmi_buf_free(buf); 12533 } 12534 12535 return ret; 12536 } 12537 #ifdef QCA_SUPPORT_CP_STATS 12538 /** 12539 * extract_cca_stats_tlv - api to extract congestion stats from event buffer 12540 * @wmi_handle: wma handle 12541 * @evt_buf: event buffer 12542 * @out_buff: buffer to populated after stats extraction 12543 * 12544 * Return: status of operation 12545 */ 12546 static QDF_STATUS extract_cca_stats_tlv(wmi_unified_t wmi_handle, 12547 void *evt_buf, struct wmi_host_congestion_stats *out_buff) 12548 { 12549 WMI_UPDATE_STATS_EVENTID_param_tlvs *param_buf; 12550 wmi_congestion_stats *congestion_stats; 12551 12552 param_buf = (WMI_UPDATE_STATS_EVENTID_param_tlvs *)evt_buf; 12553 congestion_stats = param_buf->congestion_stats; 12554 if (!congestion_stats) 12555 return QDF_STATUS_E_INVAL; 12556 12557 out_buff->vdev_id = congestion_stats->vdev_id; 12558 out_buff->congestion = congestion_stats->congestion; 12559 12560 wmi_debug("cca stats event processed"); 12561 return QDF_STATUS_SUCCESS; 12562 } 12563 #endif /* QCA_SUPPORT_CP_STATS */ 12564 12565 /** 12566 * extract_ctl_failsafe_check_ev_param_tlv() - extract ctl data from 12567 * event 12568 * @wmi_handle: wmi handle 12569 * @evt_buf: pointer to event buffer 12570 * @param: Pointer to hold peer ctl data 12571 * 12572 * Return: QDF_STATUS_SUCCESS for success or error code 12573 */ 12574 static QDF_STATUS extract_ctl_failsafe_check_ev_param_tlv( 12575 wmi_unified_t wmi_handle, 12576 void *evt_buf, 12577 struct wmi_host_pdev_ctl_failsafe_event *param) 12578 { 12579 WMI_PDEV_CTL_FAILSAFE_CHECK_EVENTID_param_tlvs *param_buf; 12580 wmi_pdev_ctl_failsafe_check_fixed_param *fix_param; 12581 12582 param_buf = (WMI_PDEV_CTL_FAILSAFE_CHECK_EVENTID_param_tlvs *)evt_buf; 12583 if (!param_buf) { 12584 wmi_err("Invalid ctl_failsafe event buffer"); 12585 return QDF_STATUS_E_INVAL; 12586 } 12587 12588 fix_param = param_buf->fixed_param; 12589 param->ctl_failsafe_status = fix_param->ctl_FailsafeStatus; 12590 12591 return QDF_STATUS_SUCCESS; 12592 } 12593 12594 /** 12595 * save_service_bitmap_tlv() - save service bitmap 12596 * @wmi_handle: wmi handle 12597 * @evt_buf: pointer to event buffer 12598 * @bitmap_buf: bitmap buffer, for converged legacy support 12599 * 12600 * Return: QDF_STATUS 12601 */ 12602 static 12603 QDF_STATUS save_service_bitmap_tlv(wmi_unified_t wmi_handle, void *evt_buf, 12604 void *bitmap_buf) 12605 { 12606 WMI_SERVICE_READY_EVENTID_param_tlvs *param_buf; 12607 struct wmi_soc *soc = wmi_handle->soc; 12608 12609 param_buf = (WMI_SERVICE_READY_EVENTID_param_tlvs *) evt_buf; 12610 12611 /* If it is already allocated, use that buffer. This can happen 12612 * during target stop/start scenarios where host allocation is skipped. 12613 */ 12614 if (!soc->wmi_service_bitmap) { 12615 soc->wmi_service_bitmap = 12616 qdf_mem_malloc(WMI_SERVICE_BM_SIZE * sizeof(uint32_t)); 12617 if (!soc->wmi_service_bitmap) 12618 return QDF_STATUS_E_NOMEM; 12619 } 12620 12621 qdf_mem_copy(soc->wmi_service_bitmap, 12622 param_buf->wmi_service_bitmap, 12623 (WMI_SERVICE_BM_SIZE * sizeof(uint32_t))); 12624 12625 if (bitmap_buf) 12626 qdf_mem_copy(bitmap_buf, 12627 param_buf->wmi_service_bitmap, 12628 (WMI_SERVICE_BM_SIZE * sizeof(uint32_t))); 12629 12630 return QDF_STATUS_SUCCESS; 12631 } 12632 12633 /** 12634 * save_ext_service_bitmap_tlv() - save extendend service bitmap 12635 * @wmi_handle: wmi handle 12636 * @evt_buf: pointer to event buffer 12637 * @bitmap_buf: bitmap buffer, for converged legacy support 12638 * 12639 * Return: QDF_STATUS 12640 */ 12641 static 12642 QDF_STATUS save_ext_service_bitmap_tlv(wmi_unified_t wmi_handle, void *evt_buf, 12643 void *bitmap_buf) 12644 { 12645 WMI_SERVICE_AVAILABLE_EVENTID_param_tlvs *param_buf; 12646 wmi_service_available_event_fixed_param *ev; 12647 struct wmi_soc *soc = wmi_handle->soc; 12648 uint32_t i = 0; 12649 12650 param_buf = (WMI_SERVICE_AVAILABLE_EVENTID_param_tlvs *) evt_buf; 12651 12652 ev = param_buf->fixed_param; 12653 12654 /* If it is already allocated, use that buffer. This can happen 12655 * during target stop/start scenarios where host allocation is skipped. 12656 */ 12657 if (!soc->wmi_ext_service_bitmap) { 12658 soc->wmi_ext_service_bitmap = qdf_mem_malloc( 12659 WMI_SERVICE_SEGMENT_BM_SIZE32 * sizeof(uint32_t)); 12660 if (!soc->wmi_ext_service_bitmap) 12661 return QDF_STATUS_E_NOMEM; 12662 } 12663 12664 qdf_mem_copy(soc->wmi_ext_service_bitmap, 12665 ev->wmi_service_segment_bitmap, 12666 (WMI_SERVICE_SEGMENT_BM_SIZE32 * sizeof(uint32_t))); 12667 12668 wmi_debug("wmi_ext_service_bitmap 0:0x%x, 1:0x%x, 2:0x%x, 3:0x%x", 12669 soc->wmi_ext_service_bitmap[0], soc->wmi_ext_service_bitmap[1], 12670 soc->wmi_ext_service_bitmap[2], soc->wmi_ext_service_bitmap[3]); 12671 12672 if (bitmap_buf) 12673 qdf_mem_copy(bitmap_buf, 12674 soc->wmi_ext_service_bitmap, 12675 (WMI_SERVICE_SEGMENT_BM_SIZE32 * sizeof(uint32_t))); 12676 12677 if (!param_buf->wmi_service_ext_bitmap) { 12678 wmi_debug("wmi_service_ext_bitmap not available"); 12679 return QDF_STATUS_SUCCESS; 12680 } 12681 12682 if (!soc->wmi_ext2_service_bitmap || 12683 (param_buf->num_wmi_service_ext_bitmap > 12684 soc->wmi_ext2_service_bitmap_len)) { 12685 if (soc->wmi_ext2_service_bitmap) { 12686 qdf_mem_free(soc->wmi_ext2_service_bitmap); 12687 soc->wmi_ext2_service_bitmap = NULL; 12688 } 12689 soc->wmi_ext2_service_bitmap = 12690 qdf_mem_malloc(param_buf->num_wmi_service_ext_bitmap * 12691 sizeof(uint32_t)); 12692 if (!soc->wmi_ext2_service_bitmap) 12693 return QDF_STATUS_E_NOMEM; 12694 12695 soc->wmi_ext2_service_bitmap_len = 12696 param_buf->num_wmi_service_ext_bitmap; 12697 } 12698 12699 qdf_mem_copy(soc->wmi_ext2_service_bitmap, 12700 param_buf->wmi_service_ext_bitmap, 12701 (param_buf->num_wmi_service_ext_bitmap * 12702 sizeof(uint32_t))); 12703 12704 for (i = 0; i < param_buf->num_wmi_service_ext_bitmap; i++) { 12705 wmi_debug("wmi_ext2_service_bitmap %u:0x%x", 12706 i, soc->wmi_ext2_service_bitmap[i]); 12707 } 12708 12709 return QDF_STATUS_SUCCESS; 12710 } 12711 12712 static inline void copy_ht_cap_info(uint32_t ev_target_cap, 12713 struct wlan_psoc_target_capability_info *cap) 12714 { 12715 /* except LDPC all flags are common between legacy and here 12716 * also IBFEER is not defined for TLV 12717 */ 12718 cap->ht_cap_info |= ev_target_cap & ( 12719 WMI_HT_CAP_ENABLED 12720 | WMI_HT_CAP_HT20_SGI 12721 | WMI_HT_CAP_DYNAMIC_SMPS 12722 | WMI_HT_CAP_TX_STBC 12723 | WMI_HT_CAP_TX_STBC_MASK_SHIFT 12724 | WMI_HT_CAP_RX_STBC 12725 | WMI_HT_CAP_RX_STBC_MASK_SHIFT 12726 | WMI_HT_CAP_LDPC 12727 | WMI_HT_CAP_L_SIG_TXOP_PROT 12728 | WMI_HT_CAP_MPDU_DENSITY 12729 | WMI_HT_CAP_MPDU_DENSITY_MASK_SHIFT 12730 | WMI_HT_CAP_HT40_SGI); 12731 if (ev_target_cap & WMI_HT_CAP_LDPC) 12732 cap->ht_cap_info |= WMI_HOST_HT_CAP_RX_LDPC | 12733 WMI_HOST_HT_CAP_TX_LDPC; 12734 } 12735 /** 12736 * extract_service_ready_tlv() - extract service ready event 12737 * @wmi_handle: wmi handle 12738 * @evt_buf: pointer to received event buffer 12739 * @cap: pointer to hold target capability information extracted from even 12740 * 12741 * Return: QDF_STATUS_SUCCESS for success or error code 12742 */ 12743 static QDF_STATUS extract_service_ready_tlv(wmi_unified_t wmi_handle, 12744 void *evt_buf, struct wlan_psoc_target_capability_info *cap) 12745 { 12746 WMI_SERVICE_READY_EVENTID_param_tlvs *param_buf; 12747 wmi_service_ready_event_fixed_param *ev; 12748 12749 12750 param_buf = (WMI_SERVICE_READY_EVENTID_param_tlvs *) evt_buf; 12751 12752 ev = (wmi_service_ready_event_fixed_param *) param_buf->fixed_param; 12753 if (!ev) { 12754 qdf_print("%s: wmi_buf_alloc failed", __func__); 12755 return QDF_STATUS_E_FAILURE; 12756 } 12757 12758 cap->phy_capability = ev->phy_capability; 12759 cap->max_frag_entry = ev->max_frag_entry; 12760 cap->num_rf_chains = ev->num_rf_chains; 12761 copy_ht_cap_info(ev->ht_cap_info, cap); 12762 cap->vht_cap_info = ev->vht_cap_info; 12763 cap->vht_supp_mcs = ev->vht_supp_mcs; 12764 cap->hw_min_tx_power = ev->hw_min_tx_power; 12765 cap->hw_max_tx_power = ev->hw_max_tx_power; 12766 cap->sys_cap_info = ev->sys_cap_info; 12767 cap->min_pkt_size_enable = ev->min_pkt_size_enable; 12768 cap->max_bcn_ie_size = ev->max_bcn_ie_size; 12769 cap->max_num_scan_channels = ev->max_num_scan_channels; 12770 cap->max_supported_macs = ev->max_supported_macs; 12771 cap->wmi_fw_sub_feat_caps = ev->wmi_fw_sub_feat_caps; 12772 cap->txrx_chainmask = ev->txrx_chainmask; 12773 cap->default_dbs_hw_mode_index = ev->default_dbs_hw_mode_index; 12774 cap->num_msdu_desc = ev->num_msdu_desc; 12775 cap->fw_version = ev->fw_build_vers; 12776 /* fw_version_1 is not available in TLV. */ 12777 cap->fw_version_1 = 0; 12778 12779 return QDF_STATUS_SUCCESS; 12780 } 12781 12782 /* convert_wireless_modes_tlv() - Convert REGDMN_MODE values sent by target 12783 * to host internal HOST_REGDMN_MODE values. 12784 * REGULATORY TODO : REGDMN_MODE_11AC_VHT*_2G values are not used by the 12785 * host currently. Add this in the future if required. 12786 * 11AX (Phase II) : 11ax related values are not currently 12787 * advertised separately by FW. As part of phase II regulatory bring-up, 12788 * finalize the advertisement mechanism. 12789 * @target_wireless_mode: target wireless mode received in message 12790 * 12791 * Return: returns the host internal wireless mode. 12792 */ 12793 static inline uint32_t convert_wireless_modes_tlv(uint32_t target_wireless_mode) 12794 { 12795 12796 uint32_t wireless_modes = 0; 12797 12798 wmi_debug("Target wireless mode: 0x%x", target_wireless_mode); 12799 12800 if (target_wireless_mode & REGDMN_MODE_11A) 12801 wireless_modes |= HOST_REGDMN_MODE_11A; 12802 12803 if (target_wireless_mode & REGDMN_MODE_TURBO) 12804 wireless_modes |= HOST_REGDMN_MODE_TURBO; 12805 12806 if (target_wireless_mode & REGDMN_MODE_11B) 12807 wireless_modes |= HOST_REGDMN_MODE_11B; 12808 12809 if (target_wireless_mode & REGDMN_MODE_PUREG) 12810 wireless_modes |= HOST_REGDMN_MODE_PUREG; 12811 12812 if (target_wireless_mode & REGDMN_MODE_11G) 12813 wireless_modes |= HOST_REGDMN_MODE_11G; 12814 12815 if (target_wireless_mode & REGDMN_MODE_108G) 12816 wireless_modes |= HOST_REGDMN_MODE_108G; 12817 12818 if (target_wireless_mode & REGDMN_MODE_108A) 12819 wireless_modes |= HOST_REGDMN_MODE_108A; 12820 12821 if (target_wireless_mode & REGDMN_MODE_11AC_VHT20_2G) 12822 wireless_modes |= HOST_REGDMN_MODE_11AC_VHT20_2G; 12823 12824 if (target_wireless_mode & REGDMN_MODE_XR) 12825 wireless_modes |= HOST_REGDMN_MODE_XR; 12826 12827 if (target_wireless_mode & REGDMN_MODE_11A_HALF_RATE) 12828 wireless_modes |= HOST_REGDMN_MODE_11A_HALF_RATE; 12829 12830 if (target_wireless_mode & REGDMN_MODE_11A_QUARTER_RATE) 12831 wireless_modes |= HOST_REGDMN_MODE_11A_QUARTER_RATE; 12832 12833 if (target_wireless_mode & REGDMN_MODE_11NG_HT20) 12834 wireless_modes |= HOST_REGDMN_MODE_11NG_HT20; 12835 12836 if (target_wireless_mode & REGDMN_MODE_11NA_HT20) 12837 wireless_modes |= HOST_REGDMN_MODE_11NA_HT20; 12838 12839 if (target_wireless_mode & REGDMN_MODE_11NG_HT40PLUS) 12840 wireless_modes |= HOST_REGDMN_MODE_11NG_HT40PLUS; 12841 12842 if (target_wireless_mode & REGDMN_MODE_11NG_HT40MINUS) 12843 wireless_modes |= HOST_REGDMN_MODE_11NG_HT40MINUS; 12844 12845 if (target_wireless_mode & REGDMN_MODE_11NA_HT40PLUS) 12846 wireless_modes |= HOST_REGDMN_MODE_11NA_HT40PLUS; 12847 12848 if (target_wireless_mode & REGDMN_MODE_11NA_HT40MINUS) 12849 wireless_modes |= HOST_REGDMN_MODE_11NA_HT40MINUS; 12850 12851 if (target_wireless_mode & REGDMN_MODE_11AC_VHT20) 12852 wireless_modes |= HOST_REGDMN_MODE_11AC_VHT20; 12853 12854 if (target_wireless_mode & REGDMN_MODE_11AC_VHT40PLUS) 12855 wireless_modes |= HOST_REGDMN_MODE_11AC_VHT40PLUS; 12856 12857 if (target_wireless_mode & REGDMN_MODE_11AC_VHT40MINUS) 12858 wireless_modes |= HOST_REGDMN_MODE_11AC_VHT40MINUS; 12859 12860 if (target_wireless_mode & REGDMN_MODE_11AC_VHT80) 12861 wireless_modes |= HOST_REGDMN_MODE_11AC_VHT80; 12862 12863 if (target_wireless_mode & REGDMN_MODE_11AC_VHT160) 12864 wireless_modes |= HOST_REGDMN_MODE_11AC_VHT160; 12865 12866 if (target_wireless_mode & REGDMN_MODE_11AC_VHT80_80) 12867 wireless_modes |= HOST_REGDMN_MODE_11AC_VHT80_80; 12868 12869 return wireless_modes; 12870 } 12871 12872 /** 12873 * convert_11be_phybitmap_to_reg_flags() - Convert 11BE phybitmap to 12874 * to regulatory flags. 12875 * @target_phybitmap: target phybitmap. 12876 * @phybitmap: host internal REGULATORY_PHYMODE set based on target 12877 * phybitmap. 12878 * 12879 * Return: None 12880 */ 12881 12882 #ifdef WLAN_FEATURE_11BE 12883 static void convert_11be_phybitmap_to_reg_flags(uint32_t target_phybitmap, 12884 uint32_t *phybitmap) 12885 { 12886 if (target_phybitmap & WMI_REGULATORY_PHYMODE_NO11BE) 12887 *phybitmap |= REGULATORY_PHYMODE_NO11BE; 12888 } 12889 #else 12890 static void convert_11be_phybitmap_to_reg_flags(uint32_t target_phybitmap, 12891 uint32_t *phybitmap) 12892 { 12893 } 12894 #endif 12895 12896 /* convert_phybitmap_tlv() - Convert WMI_REGULATORY_PHYBITMAP values sent by 12897 * target to host internal REGULATORY_PHYMODE values. 12898 * 12899 * @target_target_phybitmap: target phybitmap received in the message. 12900 * 12901 * Return: returns the host internal REGULATORY_PHYMODE. 12902 */ 12903 static uint32_t convert_phybitmap_tlv(uint32_t target_phybitmap) 12904 { 12905 uint32_t phybitmap = 0; 12906 12907 wmi_debug("Target phybitmap: 0x%x", target_phybitmap); 12908 12909 if (target_phybitmap & WMI_REGULATORY_PHYMODE_NO11A) 12910 phybitmap |= REGULATORY_PHYMODE_NO11A; 12911 12912 if (target_phybitmap & WMI_REGULATORY_PHYMODE_NO11B) 12913 phybitmap |= REGULATORY_PHYMODE_NO11B; 12914 12915 if (target_phybitmap & WMI_REGULATORY_PHYMODE_NO11G) 12916 phybitmap |= REGULATORY_PHYMODE_NO11G; 12917 12918 if (target_phybitmap & WMI_REGULATORY_PHYMODE_NO11N) 12919 phybitmap |= REGULATORY_CHAN_NO11N; 12920 12921 if (target_phybitmap & WMI_REGULATORY_PHYMODE_NO11AC) 12922 phybitmap |= REGULATORY_PHYMODE_NO11AC; 12923 12924 if (target_phybitmap & WMI_REGULATORY_PHYMODE_NO11AX) 12925 phybitmap |= REGULATORY_PHYMODE_NO11AX; 12926 12927 convert_11be_phybitmap_to_reg_flags(target_phybitmap, &phybitmap); 12928 12929 return phybitmap; 12930 } 12931 12932 /** 12933 * convert_11be_flags_to_modes_ext() - Convert 11BE wireless mode flag 12934 * advertised by the target to wireless mode ext flags. 12935 * @target_wireless_modes_ext: Target wireless mode 12936 * @wireless_modes_ext: Variable to hold all the target wireless mode caps. 12937 * 12938 * Return: None 12939 */ 12940 #ifdef WLAN_FEATURE_11BE 12941 static void convert_11be_flags_to_modes_ext(uint32_t target_wireless_modes_ext, 12942 uint64_t *wireless_modes_ext) 12943 { 12944 if (target_wireless_modes_ext & REGDMN_MODE_U32_11BEG_EHT20) 12945 *wireless_modes_ext |= HOST_REGDMN_MODE_11BEG_EHT20; 12946 12947 if (target_wireless_modes_ext & REGDMN_MODE_U32_11BEG_EHT40PLUS) 12948 *wireless_modes_ext |= HOST_REGDMN_MODE_11BEG_EHT40PLUS; 12949 12950 if (target_wireless_modes_ext & REGDMN_MODE_U32_11BEG_EHT40MINUS) 12951 *wireless_modes_ext |= HOST_REGDMN_MODE_11BEG_EHT40MINUS; 12952 12953 if (target_wireless_modes_ext & REGDMN_MODE_U32_11BEA_EHT20) 12954 *wireless_modes_ext |= HOST_REGDMN_MODE_11BEA_EHT20; 12955 12956 if (target_wireless_modes_ext & REGDMN_MODE_U32_11BEA_EHT40PLUS) 12957 *wireless_modes_ext |= HOST_REGDMN_MODE_11BEA_EHT40PLUS; 12958 12959 if (target_wireless_modes_ext & REGDMN_MODE_U32_11BEA_EHT40MINUS) 12960 *wireless_modes_ext |= HOST_REGDMN_MODE_11BEA_EHT40MINUS; 12961 12962 if (target_wireless_modes_ext & REGDMN_MODE_U32_11BEA_EHT80) 12963 *wireless_modes_ext |= HOST_REGDMN_MODE_11BEA_EHT80; 12964 12965 if (target_wireless_modes_ext & REGDMN_MODE_U32_11BEA_EHT160) 12966 *wireless_modes_ext |= HOST_REGDMN_MODE_11BEA_EHT160; 12967 12968 if (target_wireless_modes_ext & REGDMN_MODE_U32_11BEA_EHT320) 12969 *wireless_modes_ext |= HOST_REGDMN_MODE_11BEA_EHT320; 12970 } 12971 #else 12972 static void convert_11be_flags_to_modes_ext(uint32_t target_wireless_modes_ext, 12973 uint64_t *wireless_modes_ext) 12974 { 12975 } 12976 #endif 12977 12978 static inline uint64_t convert_wireless_modes_ext_tlv( 12979 uint32_t target_wireless_modes_ext) 12980 { 12981 uint64_t wireless_modes_ext = 0; 12982 12983 wmi_debug("Target wireless mode: 0x%x", target_wireless_modes_ext); 12984 12985 if (target_wireless_modes_ext & REGDMN_MODE_U32_11AXG_HE20) 12986 wireless_modes_ext |= HOST_REGDMN_MODE_11AXG_HE20; 12987 12988 if (target_wireless_modes_ext & REGDMN_MODE_U32_11AXG_HE40PLUS) 12989 wireless_modes_ext |= HOST_REGDMN_MODE_11AXG_HE40PLUS; 12990 12991 if (target_wireless_modes_ext & REGDMN_MODE_U32_11AXG_HE40MINUS) 12992 wireless_modes_ext |= HOST_REGDMN_MODE_11AXG_HE40MINUS; 12993 12994 if (target_wireless_modes_ext & REGDMN_MODE_U32_11AXA_HE20) 12995 wireless_modes_ext |= HOST_REGDMN_MODE_11AXA_HE20; 12996 12997 if (target_wireless_modes_ext & REGDMN_MODE_U32_11AXA_HE40PLUS) 12998 wireless_modes_ext |= HOST_REGDMN_MODE_11AXA_HE40PLUS; 12999 13000 if (target_wireless_modes_ext & REGDMN_MODE_U32_11AXA_HE40MINUS) 13001 wireless_modes_ext |= HOST_REGDMN_MODE_11AXA_HE40MINUS; 13002 13003 if (target_wireless_modes_ext & REGDMN_MODE_U32_11AXA_HE80) 13004 wireless_modes_ext |= HOST_REGDMN_MODE_11AXA_HE80; 13005 13006 if (target_wireless_modes_ext & REGDMN_MODE_U32_11AXA_HE160) 13007 wireless_modes_ext |= HOST_REGDMN_MODE_11AXA_HE160; 13008 13009 if (target_wireless_modes_ext & REGDMN_MODE_U32_11AXA_HE80_80) 13010 wireless_modes_ext |= HOST_REGDMN_MODE_11AXA_HE80_80; 13011 13012 convert_11be_flags_to_modes_ext(target_wireless_modes_ext, 13013 &wireless_modes_ext); 13014 13015 return wireless_modes_ext; 13016 } 13017 13018 /** 13019 * extract_hal_reg_cap_tlv() - extract HAL registered capabilities 13020 * @wmi_handle: wmi handle 13021 * @evt_buf: Pointer to event buffer 13022 * @cap: pointer to hold HAL reg capabilities 13023 * 13024 * Return: QDF_STATUS_SUCCESS for success or error code 13025 */ 13026 static QDF_STATUS extract_hal_reg_cap_tlv(wmi_unified_t wmi_handle, 13027 void *evt_buf, struct wlan_psoc_hal_reg_capability *cap) 13028 { 13029 WMI_SERVICE_READY_EVENTID_param_tlvs *param_buf; 13030 13031 param_buf = (WMI_SERVICE_READY_EVENTID_param_tlvs *) evt_buf; 13032 if (!param_buf || !param_buf->hal_reg_capabilities) { 13033 wmi_err("Invalid arguments"); 13034 return QDF_STATUS_E_FAILURE; 13035 } 13036 qdf_mem_copy(cap, (((uint8_t *)param_buf->hal_reg_capabilities) + 13037 sizeof(uint32_t)), 13038 sizeof(struct wlan_psoc_hal_reg_capability)); 13039 13040 cap->wireless_modes = convert_wireless_modes_tlv( 13041 param_buf->hal_reg_capabilities->wireless_modes); 13042 13043 return QDF_STATUS_SUCCESS; 13044 } 13045 13046 /** 13047 * extract_hal_reg_cap_ext2_tlv() - extract HAL registered capability ext 13048 * @wmi_handle: wmi handle 13049 * @evt_buf: Pointer to event buffer 13050 * @phy_idx: Specific phy to extract 13051 * @param: pointer to hold HAL reg capabilities 13052 * 13053 * Return: QDF_STATUS_SUCCESS for success or error code 13054 */ 13055 static QDF_STATUS extract_hal_reg_cap_ext2_tlv( 13056 wmi_unified_t wmi_handle, void *evt_buf, uint8_t phy_idx, 13057 struct wlan_psoc_host_hal_reg_capabilities_ext2 *param) 13058 { 13059 WMI_SERVICE_READY_EXT2_EVENTID_param_tlvs *param_buf; 13060 WMI_HAL_REG_CAPABILITIES_EXT2 *reg_caps; 13061 13062 if (!evt_buf) { 13063 wmi_err("null evt_buf"); 13064 return QDF_STATUS_E_INVAL; 13065 } 13066 13067 param_buf = (WMI_SERVICE_READY_EXT2_EVENTID_param_tlvs *)evt_buf; 13068 13069 if (!param_buf->num_hal_reg_caps) 13070 return QDF_STATUS_SUCCESS; 13071 13072 if (phy_idx >= param_buf->num_hal_reg_caps) 13073 return QDF_STATUS_E_INVAL; 13074 13075 reg_caps = ¶m_buf->hal_reg_caps[phy_idx]; 13076 13077 param->phy_id = reg_caps->phy_id; 13078 param->wireless_modes_ext = convert_wireless_modes_ext_tlv( 13079 reg_caps->wireless_modes_ext); 13080 param->low_2ghz_chan_ext = reg_caps->low_2ghz_chan_ext; 13081 param->high_2ghz_chan_ext = reg_caps->high_2ghz_chan_ext; 13082 param->low_5ghz_chan_ext = reg_caps->low_5ghz_chan_ext; 13083 param->high_5ghz_chan_ext = reg_caps->high_5ghz_chan_ext; 13084 13085 return QDF_STATUS_SUCCESS; 13086 } 13087 13088 /** 13089 * extract_num_mem_reqs_tlv() - Extract number of memory entries requested 13090 * @wmi_handle: wmi handle 13091 * @evt_buf: pointer to event buffer 13092 * 13093 * Return: Number of entries requested 13094 */ 13095 static uint32_t extract_num_mem_reqs_tlv(wmi_unified_t wmi_handle, 13096 void *evt_buf) 13097 { 13098 WMI_SERVICE_READY_EVENTID_param_tlvs *param_buf; 13099 wmi_service_ready_event_fixed_param *ev; 13100 13101 param_buf = (WMI_SERVICE_READY_EVENTID_param_tlvs *) evt_buf; 13102 13103 ev = (wmi_service_ready_event_fixed_param *) param_buf->fixed_param; 13104 if (!ev) { 13105 qdf_print("%s: wmi_buf_alloc failed", __func__); 13106 return 0; 13107 } 13108 13109 if (ev->num_mem_reqs > param_buf->num_mem_reqs) { 13110 wmi_err("Invalid num_mem_reqs %d:%d", 13111 ev->num_mem_reqs, param_buf->num_mem_reqs); 13112 return 0; 13113 } 13114 13115 return ev->num_mem_reqs; 13116 } 13117 13118 /** 13119 * extract_host_mem_req_tlv() - Extract host memory required from 13120 * service ready event 13121 * @wmi_handle: wmi handle 13122 * @evt_buf: pointer to event buffer 13123 * @mem_reqs: pointer to host memory request structure 13124 * @num_active_peers: number of active peers for peer cache 13125 * @num_peers: number of peers 13126 * @fw_prio: FW priority 13127 * @idx: index for memory request 13128 * 13129 * Return: Host memory request parameters requested by target 13130 */ 13131 static QDF_STATUS extract_host_mem_req_tlv(wmi_unified_t wmi_handle, 13132 void *evt_buf, 13133 host_mem_req *mem_reqs, 13134 uint32_t num_active_peers, 13135 uint32_t num_peers, 13136 enum wmi_fw_mem_prio fw_prio, 13137 uint16_t idx) 13138 { 13139 WMI_SERVICE_READY_EVENTID_param_tlvs *param_buf; 13140 13141 param_buf = (WMI_SERVICE_READY_EVENTID_param_tlvs *)evt_buf; 13142 13143 mem_reqs->req_id = (uint32_t)param_buf->mem_reqs[idx].req_id; 13144 mem_reqs->unit_size = (uint32_t)param_buf->mem_reqs[idx].unit_size; 13145 mem_reqs->num_unit_info = 13146 (uint32_t)param_buf->mem_reqs[idx].num_unit_info; 13147 mem_reqs->num_units = (uint32_t)param_buf->mem_reqs[idx].num_units; 13148 mem_reqs->tgt_num_units = 0; 13149 13150 if (((fw_prio == WMI_FW_MEM_HIGH_PRIORITY) && 13151 (mem_reqs->num_unit_info & 13152 REQ_TO_HOST_FOR_CONT_MEMORY)) || 13153 ((fw_prio == WMI_FW_MEM_LOW_PRIORITY) && 13154 (!(mem_reqs->num_unit_info & 13155 REQ_TO_HOST_FOR_CONT_MEMORY)))) { 13156 /* First allocate the memory that requires contiguous memory */ 13157 mem_reqs->tgt_num_units = mem_reqs->num_units; 13158 if (mem_reqs->num_unit_info) { 13159 if (mem_reqs->num_unit_info & 13160 NUM_UNITS_IS_NUM_PEERS) { 13161 /* 13162 * number of units allocated is equal to number 13163 * of peers, 1 extra for self peer on target. 13164 * this needs to be fixed, host and target can 13165 * get out of sync 13166 */ 13167 mem_reqs->tgt_num_units = num_peers + 1; 13168 } 13169 if (mem_reqs->num_unit_info & 13170 NUM_UNITS_IS_NUM_ACTIVE_PEERS) { 13171 /* 13172 * Requesting allocation of memory using 13173 * num_active_peers in qcache. if qcache is 13174 * disabled in host, then it should allocate 13175 * memory for num_peers instead of 13176 * num_active_peers. 13177 */ 13178 if (num_active_peers) 13179 mem_reqs->tgt_num_units = 13180 num_active_peers + 1; 13181 else 13182 mem_reqs->tgt_num_units = 13183 num_peers + 1; 13184 } 13185 } 13186 13187 wmi_debug("idx %d req %d num_units %d num_unit_info %d" 13188 "unit size %d actual units %d", 13189 idx, mem_reqs->req_id, 13190 mem_reqs->num_units, 13191 mem_reqs->num_unit_info, 13192 mem_reqs->unit_size, 13193 mem_reqs->tgt_num_units); 13194 } 13195 13196 return QDF_STATUS_SUCCESS; 13197 } 13198 13199 /** 13200 * save_fw_version_in_service_ready_tlv() - Save fw version in service 13201 * ready function 13202 * @wmi_handle: wmi handle 13203 * @evt_buf: pointer to event buffer 13204 * 13205 * Return: QDF_STATUS_SUCCESS for success or error code 13206 */ 13207 static QDF_STATUS 13208 save_fw_version_in_service_ready_tlv(wmi_unified_t wmi_handle, void *evt_buf) 13209 { 13210 WMI_SERVICE_READY_EVENTID_param_tlvs *param_buf; 13211 wmi_service_ready_event_fixed_param *ev; 13212 13213 13214 param_buf = (WMI_SERVICE_READY_EVENTID_param_tlvs *) evt_buf; 13215 13216 ev = (wmi_service_ready_event_fixed_param *) param_buf->fixed_param; 13217 if (!ev) { 13218 qdf_print("%s: wmi_buf_alloc failed", __func__); 13219 return QDF_STATUS_E_FAILURE; 13220 } 13221 13222 /*Save fw version from service ready message */ 13223 /*This will be used while sending INIT message */ 13224 qdf_mem_copy(&wmi_handle->fw_abi_version, &ev->fw_abi_vers, 13225 sizeof(wmi_handle->fw_abi_version)); 13226 13227 return QDF_STATUS_SUCCESS; 13228 } 13229 13230 /** 13231 * ready_extract_init_status_tlv() - Extract init status from ready event 13232 * @wmi_handle: wmi handle 13233 * @evt_buf: Pointer to event buffer 13234 * 13235 * Return: ready status 13236 */ 13237 static uint32_t ready_extract_init_status_tlv(wmi_unified_t wmi_handle, 13238 void *evt_buf) 13239 { 13240 WMI_READY_EVENTID_param_tlvs *param_buf = NULL; 13241 wmi_ready_event_fixed_param *ev = NULL; 13242 13243 param_buf = (WMI_READY_EVENTID_param_tlvs *) evt_buf; 13244 ev = param_buf->fixed_param; 13245 13246 wmi_info("%s:%d", __func__, ev->status); 13247 13248 return ev->status; 13249 } 13250 13251 /** 13252 * ready_extract_mac_addr_tlv() - extract mac address from ready event 13253 * @wmi_handle: wmi handle 13254 * @evt_buf: pointer to event buffer 13255 * @macaddr: Pointer to hold MAC address 13256 * 13257 * Return: QDF_STATUS_SUCCESS for success or error code 13258 */ 13259 static QDF_STATUS ready_extract_mac_addr_tlv(wmi_unified_t wmi_handle, 13260 void *evt_buf, uint8_t *macaddr) 13261 { 13262 WMI_READY_EVENTID_param_tlvs *param_buf = NULL; 13263 wmi_ready_event_fixed_param *ev = NULL; 13264 13265 13266 param_buf = (WMI_READY_EVENTID_param_tlvs *) evt_buf; 13267 ev = param_buf->fixed_param; 13268 13269 WMI_MAC_ADDR_TO_CHAR_ARRAY(&ev->mac_addr, macaddr); 13270 13271 return QDF_STATUS_SUCCESS; 13272 } 13273 13274 /** 13275 * ready_extract_mac_addr_list_tlv() - extract MAC address list from ready event 13276 * @wmi_handle: wmi handle 13277 * @evt_buf: pointer to event buffer 13278 * @num_mac: Pointer to hold number of MAC addresses 13279 * 13280 * Return: Pointer to addr list 13281 */ 13282 static wmi_host_mac_addr * 13283 ready_extract_mac_addr_list_tlv(wmi_unified_t wmi_handle, 13284 void *evt_buf, uint8_t *num_mac) 13285 { 13286 WMI_READY_EVENTID_param_tlvs *param_buf = NULL; 13287 wmi_ready_event_fixed_param *ev = NULL; 13288 13289 param_buf = (WMI_READY_EVENTID_param_tlvs *) evt_buf; 13290 ev = param_buf->fixed_param; 13291 13292 *num_mac = ev->num_extra_mac_addr; 13293 13294 return (wmi_host_mac_addr *) param_buf->mac_addr_list; 13295 } 13296 13297 /** 13298 * extract_ready_event_params_tlv() - Extract data from ready event apart from 13299 * status, macaddr and version. 13300 * @wmi_handle: Pointer to WMI handle. 13301 * @evt_buf: Pointer to Ready event buffer. 13302 * @ev_param: Pointer to host defined struct to copy the data from event. 13303 * 13304 * Return: QDF_STATUS_SUCCESS on success. 13305 */ 13306 static QDF_STATUS extract_ready_event_params_tlv(wmi_unified_t wmi_handle, 13307 void *evt_buf, struct wmi_host_ready_ev_param *ev_param) 13308 { 13309 WMI_READY_EVENTID_param_tlvs *param_buf = NULL; 13310 wmi_ready_event_fixed_param *ev = NULL; 13311 13312 param_buf = (WMI_READY_EVENTID_param_tlvs *) evt_buf; 13313 ev = param_buf->fixed_param; 13314 13315 ev_param->status = ev->status; 13316 ev_param->num_dscp_table = ev->num_dscp_table; 13317 ev_param->num_extra_mac_addr = ev->num_extra_mac_addr; 13318 ev_param->num_total_peer = ev->num_total_peers; 13319 ev_param->num_extra_peer = ev->num_extra_peers; 13320 /* Agile_capability in ready event is supported in TLV target, 13321 * as per aDFS FR 13322 */ 13323 ev_param->max_ast_index = ev->max_ast_index; 13324 ev_param->pktlog_defs_checksum = ev->pktlog_defs_checksum; 13325 ev_param->agile_capability = 1; 13326 ev_param->num_max_active_vdevs = ev->num_max_active_vdevs; 13327 13328 return QDF_STATUS_SUCCESS; 13329 } 13330 13331 /** 13332 * extract_dbglog_data_len_tlv() - extract debuglog data length 13333 * @wmi_handle: wmi handle 13334 * @evt_buf: pointer to event buffer 13335 * @len: length of the log 13336 * 13337 * Return: pointer to the debug log 13338 */ 13339 static uint8_t *extract_dbglog_data_len_tlv(wmi_unified_t wmi_handle, 13340 void *evt_buf, uint32_t *len) 13341 { 13342 WMI_DEBUG_MESG_EVENTID_param_tlvs *param_buf; 13343 13344 param_buf = (WMI_DEBUG_MESG_EVENTID_param_tlvs *) evt_buf; 13345 13346 *len = param_buf->num_bufp; 13347 13348 return param_buf->bufp; 13349 } 13350 13351 13352 #ifdef MGMT_FRAME_RX_DECRYPT_ERROR 13353 #define IS_WMI_RX_MGMT_FRAME_STATUS_INVALID(_status) false 13354 #else 13355 #define IS_WMI_RX_MGMT_FRAME_STATUS_INVALID(_status) \ 13356 ((_status) & WMI_RXERR_DECRYPT) 13357 #endif 13358 13359 /** 13360 * extract_mgmt_rx_params_tlv() - extract management rx params from event 13361 * @wmi_handle: wmi handle 13362 * @evt_buf: pointer to event buffer 13363 * @hdr: Pointer to hold header 13364 * @bufp: Pointer to hold pointer to rx param buffer 13365 * 13366 * Return: QDF_STATUS_SUCCESS for success or error code 13367 */ 13368 static QDF_STATUS extract_mgmt_rx_params_tlv(wmi_unified_t wmi_handle, 13369 void *evt_buf, struct mgmt_rx_event_params *hdr, 13370 uint8_t **bufp) 13371 { 13372 WMI_MGMT_RX_EVENTID_param_tlvs *param_tlvs = NULL; 13373 wmi_mgmt_rx_hdr *ev_hdr = NULL; 13374 int i; 13375 13376 param_tlvs = (WMI_MGMT_RX_EVENTID_param_tlvs *) evt_buf; 13377 if (!param_tlvs) { 13378 wmi_err_rl("Get NULL point message from FW"); 13379 return QDF_STATUS_E_INVAL; 13380 } 13381 13382 ev_hdr = param_tlvs->hdr; 13383 if (!hdr) { 13384 wmi_err_rl("Rx event is NULL"); 13385 return QDF_STATUS_E_INVAL; 13386 } 13387 13388 if (IS_WMI_RX_MGMT_FRAME_STATUS_INVALID(ev_hdr->status)) { 13389 wmi_err_rl("RX mgmt frame decrypt error, discard it"); 13390 return QDF_STATUS_E_INVAL; 13391 } 13392 if ((ev_hdr->status) & WMI_RXERR_MIC) { 13393 wmi_err_rl("RX mgmt frame MIC mismatch for beacon protected frame"); 13394 } 13395 13396 if (ev_hdr->buf_len > param_tlvs->num_bufp) { 13397 wmi_err_rl("Rx mgmt frame length mismatch, discard it"); 13398 return QDF_STATUS_E_INVAL; 13399 } 13400 13401 hdr->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host( 13402 wmi_handle, 13403 ev_hdr->pdev_id); 13404 hdr->chan_freq = ev_hdr->chan_freq; 13405 hdr->channel = ev_hdr->channel; 13406 hdr->snr = ev_hdr->snr; 13407 hdr->rate = ev_hdr->rate; 13408 hdr->phy_mode = ev_hdr->phy_mode; 13409 hdr->buf_len = ev_hdr->buf_len; 13410 hdr->status = ev_hdr->status; 13411 hdr->flags = ev_hdr->flags; 13412 hdr->rssi = ev_hdr->rssi; 13413 hdr->tsf_delta = ev_hdr->tsf_delta; 13414 hdr->tsf_l32 = ev_hdr->rx_tsf_l32; 13415 for (i = 0; i < ATH_MAX_ANTENNA; i++) 13416 hdr->rssi_ctl[i] = ev_hdr->rssi_ctl[i]; 13417 13418 *bufp = param_tlvs->bufp; 13419 13420 extract_mgmt_rx_mlo_link_removal_tlv_count( 13421 param_tlvs->num_link_removal_tbtt_count, hdr); 13422 13423 return QDF_STATUS_SUCCESS; 13424 } 13425 13426 static QDF_STATUS extract_mgmt_rx_ext_params_tlv(wmi_unified_t wmi_handle, 13427 void *evt_buf, struct mgmt_rx_event_ext_params *ext_params) 13428 { 13429 WMI_MGMT_RX_EVENTID_param_tlvs *param_tlvs; 13430 wmi_mgmt_rx_params_ext *ext_params_tlv; 13431 wmi_mgmt_rx_hdr *ev_hdr; 13432 wmi_mgmt_rx_params_ext_meta_t meta_id; 13433 uint8_t *ie_data; 13434 13435 /* initialize to zero and set it only if tlv has valid meta data */ 13436 ext_params->u.addba.ba_win_size = 0; 13437 ext_params->u.addba.reo_win_size = 0; 13438 13439 param_tlvs = (WMI_MGMT_RX_EVENTID_param_tlvs *) evt_buf; 13440 if (!param_tlvs) { 13441 wmi_err("param_tlvs is NULL"); 13442 return QDF_STATUS_E_INVAL; 13443 } 13444 13445 ev_hdr = param_tlvs->hdr; 13446 if (!ev_hdr) { 13447 wmi_err("Rx event is NULL"); 13448 return QDF_STATUS_E_INVAL; 13449 } 13450 13451 ext_params_tlv = param_tlvs->mgmt_rx_params_ext; 13452 if (ext_params_tlv) { 13453 meta_id = WMI_RX_PARAM_EXT_META_ID_GET( 13454 ext_params_tlv->mgmt_rx_params_ext_dword0); 13455 if (meta_id == WMI_RX_PARAMS_EXT_META_ADDBA) { 13456 ext_params->meta_id = MGMT_RX_PARAMS_EXT_META_ADDBA; 13457 ext_params->u.addba.ba_win_size = 13458 WMI_RX_PARAM_EXT_BA_WIN_SIZE_GET( 13459 ext_params_tlv->mgmt_rx_params_ext_dword1); 13460 if (ext_params->u.addba.ba_win_size > 1024) { 13461 wmi_info("ba win size %d from TLV is Invalid", 13462 ext_params->u.addba.ba_win_size); 13463 return QDF_STATUS_E_INVAL; 13464 } 13465 13466 ext_params->u.addba.reo_win_size = 13467 WMI_RX_PARAM_EXT_REO_WIN_SIZE_GET( 13468 ext_params_tlv->mgmt_rx_params_ext_dword1); 13469 if (ext_params->u.addba.reo_win_size > 2048) { 13470 wmi_info("reo win size %d from TLV is Invalid", 13471 ext_params->u.addba.reo_win_size); 13472 return QDF_STATUS_E_INVAL; 13473 } 13474 } 13475 if (meta_id == WMI_RX_PARAMS_EXT_META_TWT) { 13476 ext_params->meta_id = MGMT_RX_PARAMS_EXT_META_TWT; 13477 ext_params->u.twt.ie_len = 13478 ext_params_tlv->twt_ie_buf_len; 13479 ie_data = param_tlvs->ie_data; 13480 if (ext_params->u.twt.ie_len && 13481 (ext_params->u.twt.ie_len < 13482 MAX_TWT_IE_RX_PARAMS_LEN)) { 13483 qdf_mem_copy(ext_params->u.twt.ie_data, 13484 ie_data, 13485 ext_params_tlv->twt_ie_buf_len); 13486 } 13487 } 13488 } 13489 13490 return QDF_STATUS_SUCCESS; 13491 } 13492 13493 #ifdef WLAN_MGMT_RX_REO_SUPPORT 13494 /** 13495 * extract_mgmt_rx_fw_consumed_tlv() - extract MGMT Rx FW consumed event 13496 * @wmi_handle: wmi handle 13497 * @evt_buf: pointer to event buffer 13498 * @params: Pointer to MGMT Rx REO parameters 13499 * 13500 * Return: QDF_STATUS_SUCCESS for success or error code 13501 */ 13502 static QDF_STATUS 13503 extract_mgmt_rx_fw_consumed_tlv(wmi_unified_t wmi_handle, 13504 void *evt_buf, 13505 struct mgmt_rx_reo_params *params) 13506 { 13507 WMI_MGMT_RX_FW_CONSUMED_EVENTID_param_tlvs *param_tlvs; 13508 wmi_mgmt_rx_fw_consumed_hdr *ev_hdr; 13509 13510 param_tlvs = evt_buf; 13511 if (!param_tlvs) { 13512 wmi_err("param_tlvs is NULL"); 13513 return QDF_STATUS_E_INVAL; 13514 } 13515 13516 ev_hdr = param_tlvs->hdr; 13517 if (!params) { 13518 wmi_err("Rx REO parameters is NULL"); 13519 return QDF_STATUS_E_INVAL; 13520 } 13521 13522 params->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host( 13523 wmi_handle, 13524 ev_hdr->pdev_id); 13525 params->valid = WMI_MGMT_RX_FW_CONSUMED_PARAM_MGMT_PKT_CTR_VALID_GET( 13526 ev_hdr->mgmt_pkt_ctr_info); 13527 params->global_timestamp = ev_hdr->global_timestamp; 13528 params->mgmt_pkt_ctr = WMI_MGMT_RX_FW_CONSUMED_PARAM_MGMT_PKT_CTR_GET( 13529 ev_hdr->mgmt_pkt_ctr_info); 13530 params->duration_us = ev_hdr->rx_ppdu_duration_us; 13531 params->start_timestamp = params->global_timestamp; 13532 params->end_timestamp = params->start_timestamp + 13533 params->duration_us; 13534 13535 return QDF_STATUS_SUCCESS; 13536 } 13537 13538 /** 13539 * extract_mgmt_rx_reo_params_tlv() - extract MGMT Rx REO params from 13540 * MGMT_RX_EVENT_ID 13541 * @wmi_handle: wmi handle 13542 * @evt_buf: pointer to event buffer 13543 * @reo_params: Pointer to MGMT Rx REO parameters 13544 * 13545 * Return: QDF_STATUS_SUCCESS for success or error code 13546 */ 13547 static QDF_STATUS extract_mgmt_rx_reo_params_tlv(wmi_unified_t wmi_handle, 13548 void *evt_buf, struct mgmt_rx_reo_params *reo_params) 13549 { 13550 WMI_MGMT_RX_EVENTID_param_tlvs *param_tlvs; 13551 wmi_mgmt_rx_reo_params *reo_params_tlv; 13552 wmi_mgmt_rx_hdr *ev_hdr; 13553 13554 param_tlvs = evt_buf; 13555 if (!param_tlvs) { 13556 wmi_err("param_tlvs is NULL"); 13557 return QDF_STATUS_E_INVAL; 13558 } 13559 13560 ev_hdr = param_tlvs->hdr; 13561 if (!ev_hdr) { 13562 wmi_err("Rx event is NULL"); 13563 return QDF_STATUS_E_INVAL; 13564 } 13565 13566 reo_params_tlv = param_tlvs->reo_params; 13567 if (!reo_params_tlv) { 13568 wmi_err("mgmt_rx_reo_params TLV is not sent by FW"); 13569 return QDF_STATUS_E_INVAL; 13570 } 13571 13572 if (!reo_params) { 13573 wmi_err("MGMT Rx REO params is NULL"); 13574 return QDF_STATUS_E_INVAL; 13575 } 13576 13577 reo_params->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host( 13578 wmi_handle, 13579 ev_hdr->pdev_id); 13580 reo_params->valid = WMI_MGMT_RX_REO_PARAM_MGMT_PKT_CTR_VALID_GET( 13581 reo_params_tlv->mgmt_pkt_ctr_link_info); 13582 reo_params->global_timestamp = reo_params_tlv->global_timestamp; 13583 reo_params->mgmt_pkt_ctr = WMI_MGMT_RX_REO_PARAM_MGMT_PKT_CTR_GET( 13584 reo_params_tlv->mgmt_pkt_ctr_link_info); 13585 reo_params->duration_us = reo_params_tlv->rx_ppdu_duration_us; 13586 reo_params->start_timestamp = reo_params->global_timestamp; 13587 reo_params->end_timestamp = reo_params->start_timestamp + 13588 reo_params->duration_us; 13589 13590 return QDF_STATUS_SUCCESS; 13591 } 13592 13593 /** 13594 * send_mgmt_rx_reo_filter_config_cmd_tlv() - Send MGMT Rx REO filter 13595 * configuration command 13596 * @wmi_handle: wmi handle 13597 * @pdev_id: pdev ID of the radio 13598 * @filter: Pointer to MGMT Rx REO filter 13599 * 13600 * Return: QDF_STATUS_SUCCESS for success or error code 13601 */ 13602 static QDF_STATUS send_mgmt_rx_reo_filter_config_cmd_tlv( 13603 wmi_unified_t wmi_handle, 13604 uint8_t pdev_id, 13605 struct mgmt_rx_reo_filter *filter) 13606 { 13607 QDF_STATUS ret; 13608 wmi_buf_t buf; 13609 wmi_mgmt_rx_reo_filter_configuration_cmd_fixed_param *cmd; 13610 size_t len = sizeof(*cmd); 13611 13612 if (!filter) { 13613 wmi_err("mgmt_rx_reo_filter is NULL"); 13614 return QDF_STATUS_E_INVAL; 13615 } 13616 13617 buf = wmi_buf_alloc(wmi_handle, len); 13618 if (!buf) { 13619 wmi_err("wmi_buf_alloc failed"); 13620 return QDF_STATUS_E_NOMEM; 13621 } 13622 13623 cmd = (wmi_mgmt_rx_reo_filter_configuration_cmd_fixed_param *) 13624 wmi_buf_data(buf); 13625 13626 WMITLV_SET_HDR(&cmd->tlv_header, 13627 WMITLV_TAG_STRUC_wmi_mgmt_rx_reo_filter_configuration_cmd_fixed_param, 13628 WMITLV_GET_STRUCT_TLVLEN(wmi_mgmt_rx_reo_filter_configuration_cmd_fixed_param)); 13629 13630 cmd->pdev_id = wmi_handle->ops->convert_host_pdev_id_to_target( 13631 wmi_handle, 13632 pdev_id); 13633 cmd->filter_low = filter->low; 13634 cmd->filter_high = filter->high; 13635 13636 wmi_mtrace(WMI_MGMT_RX_REO_FILTER_CONFIGURATION_CMDID, NO_SESSION, 0); 13637 ret = wmi_unified_cmd_send( 13638 wmi_handle, buf, len, 13639 WMI_MGMT_RX_REO_FILTER_CONFIGURATION_CMDID); 13640 13641 if (QDF_IS_STATUS_ERROR(ret)) { 13642 wmi_err("Failed to send WMI command"); 13643 wmi_buf_free(buf); 13644 } 13645 13646 return ret; 13647 } 13648 #endif 13649 13650 /** 13651 * extract_frame_pn_params_tlv() - extract PN params from event 13652 * @wmi_handle: wmi handle 13653 * @evt_buf: pointer to event buffer 13654 * @pn_params: Pointer to Frame PN params 13655 * 13656 * Return: QDF_STATUS_SUCCESS for success or error code 13657 */ 13658 static QDF_STATUS extract_frame_pn_params_tlv(wmi_unified_t wmi_handle, 13659 void *evt_buf, 13660 struct frame_pn_params *pn_params) 13661 { 13662 WMI_MGMT_RX_EVENTID_param_tlvs *param_tlvs; 13663 wmi_frame_pn_params *pn_params_tlv; 13664 13665 if (!is_service_enabled_tlv(wmi_handle, 13666 WMI_SERVICE_PN_REPLAY_CHECK_SUPPORT)) 13667 return QDF_STATUS_SUCCESS; 13668 13669 param_tlvs = evt_buf; 13670 if (!param_tlvs) { 13671 wmi_err("Got NULL point message from FW"); 13672 return QDF_STATUS_E_INVAL; 13673 } 13674 13675 if (!pn_params) { 13676 wmi_err("PN Params is NULL"); 13677 return QDF_STATUS_E_INVAL; 13678 } 13679 13680 /* PN Params TLV will be populated only if WMI_RXERR_PN error is 13681 * found by target 13682 */ 13683 pn_params_tlv = param_tlvs->pn_params; 13684 if (!pn_params_tlv) 13685 return QDF_STATUS_SUCCESS; 13686 13687 qdf_mem_copy(pn_params->curr_pn, pn_params_tlv->cur_pn, 13688 sizeof(pn_params->curr_pn)); 13689 qdf_mem_copy(pn_params->prev_pn, pn_params_tlv->prev_pn, 13690 sizeof(pn_params->prev_pn)); 13691 13692 return QDF_STATUS_SUCCESS; 13693 } 13694 13695 /** 13696 * extract_is_conn_ap_frm_param_tlv() - extract is_conn_ap_frame param from 13697 * event 13698 * @wmi_handle: wmi handle 13699 * @evt_buf: pointer to event buffer 13700 * @is_conn_ap: Pointer for is_conn_ap frame 13701 * 13702 * Return: QDF_STATUS_SUCCESS for success or error code 13703 */ 13704 static QDF_STATUS extract_is_conn_ap_frm_param_tlv( 13705 wmi_unified_t wmi_handle, 13706 void *evt_buf, 13707 struct frm_conn_ap *is_conn_ap) 13708 { 13709 WMI_MGMT_RX_EVENTID_param_tlvs *param_tlvs; 13710 wmi_is_my_mgmt_frame *my_frame_tlv; 13711 13712 param_tlvs = evt_buf; 13713 if (!param_tlvs) { 13714 wmi_err("Got NULL point message from FW"); 13715 return QDF_STATUS_E_INVAL; 13716 } 13717 13718 if (!is_conn_ap) { 13719 wmi_err(" is connected ap param is NULL"); 13720 return QDF_STATUS_E_INVAL; 13721 } 13722 13723 my_frame_tlv = param_tlvs->my_frame; 13724 if (!my_frame_tlv) 13725 return QDF_STATUS_SUCCESS; 13726 13727 is_conn_ap->mgmt_frm_sub_type = my_frame_tlv->mgmt_frm_sub_type; 13728 is_conn_ap->is_conn_ap_frm = my_frame_tlv->is_my_frame; 13729 13730 return QDF_STATUS_SUCCESS; 13731 } 13732 13733 /** 13734 * extract_vdev_roam_param_tlv() - extract vdev roam param from event 13735 * @wmi_handle: wmi handle 13736 * @evt_buf: pointer to event buffer 13737 * @param: Pointer to hold roam param 13738 * 13739 * Return: QDF_STATUS_SUCCESS for success or error code 13740 */ 13741 static QDF_STATUS extract_vdev_roam_param_tlv(wmi_unified_t wmi_handle, 13742 void *evt_buf, wmi_host_roam_event *param) 13743 { 13744 WMI_ROAM_EVENTID_param_tlvs *param_buf; 13745 wmi_roam_event_fixed_param *evt; 13746 13747 param_buf = (WMI_ROAM_EVENTID_param_tlvs *) evt_buf; 13748 if (!param_buf) { 13749 wmi_err("Invalid roam event buffer"); 13750 return QDF_STATUS_E_INVAL; 13751 } 13752 13753 evt = param_buf->fixed_param; 13754 qdf_mem_zero(param, sizeof(*param)); 13755 13756 param->vdev_id = evt->vdev_id; 13757 param->reason = evt->reason; 13758 param->rssi = evt->rssi; 13759 13760 return QDF_STATUS_SUCCESS; 13761 } 13762 13763 /** 13764 * extract_vdev_scan_ev_param_tlv() - extract vdev scan param from event 13765 * @wmi_handle: wmi handle 13766 * @evt_buf: pointer to event buffer 13767 * @param: Pointer to hold vdev scan param 13768 * 13769 * Return: QDF_STATUS_SUCCESS for success or error code 13770 */ 13771 static QDF_STATUS extract_vdev_scan_ev_param_tlv(wmi_unified_t wmi_handle, 13772 void *evt_buf, struct scan_event *param) 13773 { 13774 WMI_SCAN_EVENTID_param_tlvs *param_buf = NULL; 13775 wmi_scan_event_fixed_param *evt = NULL; 13776 13777 param_buf = (WMI_SCAN_EVENTID_param_tlvs *) evt_buf; 13778 evt = param_buf->fixed_param; 13779 13780 qdf_mem_zero(param, sizeof(*param)); 13781 13782 switch (evt->event) { 13783 case WMI_SCAN_EVENT_STARTED: 13784 param->type = SCAN_EVENT_TYPE_STARTED; 13785 break; 13786 case WMI_SCAN_EVENT_COMPLETED: 13787 param->type = SCAN_EVENT_TYPE_COMPLETED; 13788 break; 13789 case WMI_SCAN_EVENT_BSS_CHANNEL: 13790 param->type = SCAN_EVENT_TYPE_BSS_CHANNEL; 13791 break; 13792 case WMI_SCAN_EVENT_FOREIGN_CHANNEL: 13793 param->type = SCAN_EVENT_TYPE_FOREIGN_CHANNEL; 13794 break; 13795 case WMI_SCAN_EVENT_DEQUEUED: 13796 param->type = SCAN_EVENT_TYPE_DEQUEUED; 13797 break; 13798 case WMI_SCAN_EVENT_PREEMPTED: 13799 param->type = SCAN_EVENT_TYPE_PREEMPTED; 13800 break; 13801 case WMI_SCAN_EVENT_START_FAILED: 13802 param->type = SCAN_EVENT_TYPE_START_FAILED; 13803 break; 13804 case WMI_SCAN_EVENT_RESTARTED: 13805 param->type = SCAN_EVENT_TYPE_RESTARTED; 13806 break; 13807 case WMI_SCAN_EVENT_FOREIGN_CHANNEL_EXIT: 13808 param->type = SCAN_EVENT_TYPE_FOREIGN_CHANNEL_EXIT; 13809 break; 13810 case WMI_SCAN_EVENT_MAX: 13811 default: 13812 param->type = SCAN_EVENT_TYPE_MAX; 13813 break; 13814 }; 13815 13816 switch (evt->reason) { 13817 case WMI_SCAN_REASON_NONE: 13818 param->reason = SCAN_REASON_NONE; 13819 break; 13820 case WMI_SCAN_REASON_COMPLETED: 13821 param->reason = SCAN_REASON_COMPLETED; 13822 break; 13823 case WMI_SCAN_REASON_CANCELLED: 13824 param->reason = SCAN_REASON_CANCELLED; 13825 break; 13826 case WMI_SCAN_REASON_PREEMPTED: 13827 param->reason = SCAN_REASON_PREEMPTED; 13828 break; 13829 case WMI_SCAN_REASON_TIMEDOUT: 13830 param->reason = SCAN_REASON_TIMEDOUT; 13831 break; 13832 case WMI_SCAN_REASON_INTERNAL_FAILURE: 13833 param->reason = SCAN_REASON_INTERNAL_FAILURE; 13834 break; 13835 case WMI_SCAN_REASON_SUSPENDED: 13836 param->reason = SCAN_REASON_SUSPENDED; 13837 break; 13838 case WMI_SCAN_REASON_DFS_VIOLATION: 13839 param->reason = SCAN_REASON_DFS_VIOLATION; 13840 break; 13841 case WMI_SCAN_REASON_MAX: 13842 param->reason = SCAN_REASON_MAX; 13843 break; 13844 default: 13845 param->reason = SCAN_REASON_MAX; 13846 break; 13847 }; 13848 13849 param->chan_freq = evt->channel_freq; 13850 param->requester = evt->requestor; 13851 param->scan_id = evt->scan_id; 13852 param->vdev_id = evt->vdev_id; 13853 param->timestamp = evt->tsf_timestamp; 13854 13855 return QDF_STATUS_SUCCESS; 13856 } 13857 13858 #ifdef FEATURE_WLAN_SCAN_PNO 13859 /** 13860 * extract_nlo_match_ev_param_tlv() - extract NLO match param from event 13861 * @wmi_handle: pointer to WMI handle 13862 * @evt_buf: pointer to WMI event buffer 13863 * @param: pointer to scan event param for NLO match 13864 * 13865 * Return: QDF_STATUS_SUCCESS for success or error code 13866 */ 13867 static QDF_STATUS extract_nlo_match_ev_param_tlv(wmi_unified_t wmi_handle, 13868 void *evt_buf, 13869 struct scan_event *param) 13870 { 13871 WMI_NLO_MATCH_EVENTID_param_tlvs *param_buf = evt_buf; 13872 wmi_nlo_event *evt = param_buf->fixed_param; 13873 13874 qdf_mem_zero(param, sizeof(*param)); 13875 13876 param->type = SCAN_EVENT_TYPE_NLO_MATCH; 13877 param->vdev_id = evt->vdev_id; 13878 13879 return QDF_STATUS_SUCCESS; 13880 } 13881 13882 /** 13883 * extract_nlo_complete_ev_param_tlv() - extract NLO complete param from event 13884 * @wmi_handle: pointer to WMI handle 13885 * @evt_buf: pointer to WMI event buffer 13886 * @param: pointer to scan event param for NLO complete 13887 * 13888 * Return: QDF_STATUS_SUCCESS for success or error code 13889 */ 13890 static QDF_STATUS extract_nlo_complete_ev_param_tlv(wmi_unified_t wmi_handle, 13891 void *evt_buf, 13892 struct scan_event *param) 13893 { 13894 WMI_NLO_SCAN_COMPLETE_EVENTID_param_tlvs *param_buf = evt_buf; 13895 wmi_nlo_event *evt = param_buf->fixed_param; 13896 13897 qdf_mem_zero(param, sizeof(*param)); 13898 13899 param->type = SCAN_EVENT_TYPE_NLO_COMPLETE; 13900 param->vdev_id = evt->vdev_id; 13901 13902 return QDF_STATUS_SUCCESS; 13903 } 13904 #endif 13905 13906 /** 13907 * extract_unit_test_tlv() - extract unit test data 13908 * @wmi_handle: wmi handle 13909 * @evt_buf: pointer to event buffer 13910 * @unit_test: pointer to hold unit test data 13911 * @maxspace: Amount of space in evt_buf 13912 * 13913 * Return: QDF_STATUS_SUCCESS for success or error code 13914 */ 13915 static QDF_STATUS extract_unit_test_tlv(wmi_unified_t wmi_handle, 13916 void *evt_buf, wmi_unit_test_event *unit_test, uint32_t maxspace) 13917 { 13918 WMI_UNIT_TEST_EVENTID_param_tlvs *param_buf; 13919 wmi_unit_test_event_fixed_param *ev_param; 13920 uint32_t num_bufp; 13921 uint32_t copy_size; 13922 uint8_t *bufp; 13923 13924 param_buf = (WMI_UNIT_TEST_EVENTID_param_tlvs *) evt_buf; 13925 ev_param = param_buf->fixed_param; 13926 bufp = param_buf->bufp; 13927 num_bufp = param_buf->num_bufp; 13928 unit_test->vdev_id = ev_param->vdev_id; 13929 unit_test->module_id = ev_param->module_id; 13930 unit_test->diag_token = ev_param->diag_token; 13931 unit_test->flag = ev_param->flag; 13932 unit_test->payload_len = ev_param->payload_len; 13933 wmi_debug("vdev_id:%d mod_id:%d diag_token:%d flag:%d", 13934 ev_param->vdev_id, 13935 ev_param->module_id, 13936 ev_param->diag_token, 13937 ev_param->flag); 13938 wmi_debug("Unit-test data given below %d", num_bufp); 13939 qdf_trace_hex_dump(QDF_MODULE_ID_WMI, QDF_TRACE_LEVEL_DEBUG, 13940 bufp, num_bufp); 13941 copy_size = (num_bufp < maxspace) ? num_bufp : maxspace; 13942 qdf_mem_copy(unit_test->buffer, bufp, copy_size); 13943 unit_test->buffer_len = copy_size; 13944 13945 return QDF_STATUS_SUCCESS; 13946 } 13947 13948 /** 13949 * extract_pdev_ext_stats_tlv() - extract extended pdev stats from event 13950 * @wmi_handle: wmi handle 13951 * @evt_buf: pointer to event buffer 13952 * @index: Index into extended pdev stats 13953 * @pdev_ext_stats: Pointer to hold extended pdev stats 13954 * 13955 * Return: QDF_STATUS_SUCCESS for success or error code 13956 */ 13957 static QDF_STATUS extract_pdev_ext_stats_tlv(wmi_unified_t wmi_handle, 13958 void *evt_buf, uint32_t index, wmi_host_pdev_ext_stats *pdev_ext_stats) 13959 { 13960 WMI_UPDATE_STATS_EVENTID_param_tlvs *param_buf; 13961 wmi_pdev_extd_stats *ev; 13962 13963 param_buf = evt_buf; 13964 if (!param_buf) 13965 return QDF_STATUS_E_FAILURE; 13966 13967 if (!param_buf->pdev_extd_stats) 13968 return QDF_STATUS_E_FAILURE; 13969 13970 ev = param_buf->pdev_extd_stats + index; 13971 13972 pdev_ext_stats->pdev_id = 13973 wmi_handle->ops->convert_target_pdev_id_to_host( 13974 wmi_handle, 13975 ev->pdev_id); 13976 pdev_ext_stats->my_rx_count = ev->my_rx_count; 13977 pdev_ext_stats->rx_matched_11ax_msdu_cnt = ev->rx_matched_11ax_msdu_cnt; 13978 pdev_ext_stats->rx_other_11ax_msdu_cnt = ev->rx_other_11ax_msdu_cnt; 13979 13980 return QDF_STATUS_SUCCESS; 13981 } 13982 13983 /** 13984 * extract_bcn_stats_tlv() - extract bcn stats from event 13985 * @wmi_handle: wmi handle 13986 * @evt_buf: pointer to event buffer 13987 * @index: Index into vdev stats 13988 * @bcn_stats: Pointer to hold bcn stats 13989 * 13990 * Return: QDF_STATUS_SUCCESS for success or error code 13991 */ 13992 static QDF_STATUS extract_bcn_stats_tlv(wmi_unified_t wmi_handle, 13993 void *evt_buf, uint32_t index, wmi_host_bcn_stats *bcn_stats) 13994 { 13995 WMI_UPDATE_STATS_EVENTID_param_tlvs *param_buf; 13996 wmi_stats_event_fixed_param *ev_param; 13997 uint8_t *data; 13998 13999 param_buf = (WMI_UPDATE_STATS_EVENTID_param_tlvs *) evt_buf; 14000 ev_param = (wmi_stats_event_fixed_param *) param_buf->fixed_param; 14001 data = (uint8_t *) param_buf->data; 14002 14003 if (index < ev_param->num_bcn_stats) { 14004 wmi_bcn_stats *ev = (wmi_bcn_stats *) ((data) + 14005 ((ev_param->num_pdev_stats) * sizeof(wmi_pdev_stats)) + 14006 ((ev_param->num_vdev_stats) * sizeof(wmi_vdev_stats)) + 14007 ((ev_param->num_peer_stats) * sizeof(wmi_peer_stats)) + 14008 ((ev_param->num_chan_stats) * sizeof(wmi_chan_stats)) + 14009 ((ev_param->num_mib_stats) * sizeof(wmi_mib_stats)) + 14010 (index * sizeof(wmi_bcn_stats))); 14011 14012 bcn_stats->vdev_id = ev->vdev_id; 14013 bcn_stats->tx_bcn_succ_cnt = ev->tx_bcn_succ_cnt; 14014 bcn_stats->tx_bcn_outage_cnt = ev->tx_bcn_outage_cnt; 14015 } 14016 14017 return QDF_STATUS_SUCCESS; 14018 } 14019 14020 #ifdef WLAN_FEATURE_11BE_MLO 14021 /** 14022 * wmi_is_mlo_vdev_active() - get if mlo vdev is active or not 14023 * @flag: vdev link status info 14024 * 14025 * Return: True if active, else False 14026 */ 14027 static bool wmi_is_mlo_vdev_active(uint32_t flag) 14028 { 14029 if ((flag & WMI_VDEV_STATS_FLAGS_LINK_ACTIVE_FLAG_IS_VALID_MASK) && 14030 (flag & WMI_VDEV_STATS_FLAGS_IS_LINK_ACTIVE_MASK)) 14031 return true; 14032 14033 return false; 14034 } 14035 14036 static QDF_STATUS 14037 extract_mlo_vdev_status_info(WMI_UPDATE_STATS_EVENTID_param_tlvs *param_buf, 14038 wmi_vdev_extd_stats *ev, 14039 struct wmi_host_vdev_prb_fils_stats *vdev_stats) 14040 { 14041 if (!param_buf->num_vdev_extd_stats) { 14042 wmi_err("No vdev_extd_stats in the event buffer"); 14043 return QDF_STATUS_E_INVAL; 14044 } 14045 14046 vdev_stats->is_mlo_vdev_active = wmi_is_mlo_vdev_active(ev->flags); 14047 return QDF_STATUS_SUCCESS; 14048 } 14049 #else 14050 static QDF_STATUS 14051 extract_mlo_vdev_status_info(WMI_UPDATE_STATS_EVENTID_param_tlvs *param_buf, 14052 wmi_vdev_extd_stats *ev, 14053 struct wmi_host_vdev_prb_fils_stats *vdev_stats) 14054 { 14055 return QDF_STATUS_SUCCESS; 14056 } 14057 #endif 14058 14059 /** 14060 * extract_vdev_prb_fils_stats_tlv() - extract vdev probe and fils 14061 * stats from event 14062 * @wmi_handle: wmi handle 14063 * @evt_buf: pointer to event buffer 14064 * @index: Index into vdev stats 14065 * @vdev_stats: Pointer to hold vdev probe and fils stats 14066 * 14067 * Return: QDF_STATUS_SUCCESS for success or error code 14068 */ 14069 static QDF_STATUS 14070 extract_vdev_prb_fils_stats_tlv(wmi_unified_t wmi_handle, 14071 void *evt_buf, uint32_t index, 14072 struct wmi_host_vdev_prb_fils_stats *vdev_stats) 14073 { 14074 WMI_UPDATE_STATS_EVENTID_param_tlvs *param_buf; 14075 wmi_vdev_extd_stats *ev; 14076 QDF_STATUS status = QDF_STATUS_SUCCESS; 14077 14078 param_buf = (WMI_UPDATE_STATS_EVENTID_param_tlvs *)evt_buf; 14079 14080 if (param_buf->vdev_extd_stats) { 14081 ev = (wmi_vdev_extd_stats *)(param_buf->vdev_extd_stats + 14082 index); 14083 vdev_stats->vdev_id = ev->vdev_id; 14084 vdev_stats->fd_succ_cnt = ev->fd_succ_cnt; 14085 vdev_stats->fd_fail_cnt = ev->fd_fail_cnt; 14086 vdev_stats->unsolicited_prb_succ_cnt = 14087 ev->unsolicited_prb_succ_cnt; 14088 vdev_stats->unsolicited_prb_fail_cnt = 14089 ev->unsolicited_prb_fail_cnt; 14090 status = extract_mlo_vdev_status_info(param_buf, ev, 14091 vdev_stats); 14092 vdev_stats->vdev_tx_power = ev->vdev_tx_power; 14093 wmi_debug("vdev: %d, fd_s: %d, fd_f: %d, prb_s: %d, prb_f: %d", 14094 ev->vdev_id, ev->fd_succ_cnt, ev->fd_fail_cnt, 14095 ev->unsolicited_prb_succ_cnt, 14096 ev->unsolicited_prb_fail_cnt); 14097 wmi_debug("vdev txpwr: %d", ev->vdev_tx_power); 14098 } 14099 14100 return status; 14101 } 14102 14103 /** 14104 * extract_bcnflt_stats_tlv() - extract bcn fault stats from event 14105 * @wmi_handle: wmi handle 14106 * @evt_buf: pointer to event buffer 14107 * @index: Index into bcn fault stats 14108 * @bcnflt_stats: Pointer to hold bcn fault stats 14109 * 14110 * Return: QDF_STATUS_SUCCESS for success or error code 14111 */ 14112 static QDF_STATUS extract_bcnflt_stats_tlv(wmi_unified_t wmi_handle, 14113 void *evt_buf, uint32_t index, wmi_host_bcnflt_stats *bcnflt_stats) 14114 { 14115 return QDF_STATUS_SUCCESS; 14116 } 14117 14118 /** 14119 * extract_chan_stats_tlv() - extract chan stats from event 14120 * @wmi_handle: wmi handle 14121 * @evt_buf: pointer to event buffer 14122 * @index: Index into chan stats 14123 * @chan_stats: Pointer to hold chan stats 14124 * 14125 * Return: QDF_STATUS_SUCCESS for success or error code 14126 */ 14127 static QDF_STATUS extract_chan_stats_tlv(wmi_unified_t wmi_handle, 14128 void *evt_buf, uint32_t index, wmi_host_chan_stats *chan_stats) 14129 { 14130 WMI_UPDATE_STATS_EVENTID_param_tlvs *param_buf; 14131 wmi_stats_event_fixed_param *ev_param; 14132 uint8_t *data; 14133 14134 param_buf = (WMI_UPDATE_STATS_EVENTID_param_tlvs *) evt_buf; 14135 ev_param = (wmi_stats_event_fixed_param *) param_buf->fixed_param; 14136 data = (uint8_t *) param_buf->data; 14137 14138 if (index < ev_param->num_chan_stats) { 14139 wmi_chan_stats *ev = (wmi_chan_stats *) ((data) + 14140 ((ev_param->num_pdev_stats) * sizeof(wmi_pdev_stats)) + 14141 ((ev_param->num_vdev_stats) * sizeof(wmi_vdev_stats)) + 14142 ((ev_param->num_peer_stats) * sizeof(wmi_peer_stats)) + 14143 (index * sizeof(wmi_chan_stats))); 14144 14145 14146 /* Non-TLV doesn't have num_chan_stats */ 14147 chan_stats->chan_mhz = ev->chan_mhz; 14148 chan_stats->sampling_period_us = ev->sampling_period_us; 14149 chan_stats->rx_clear_count = ev->rx_clear_count; 14150 chan_stats->tx_duration_us = ev->tx_duration_us; 14151 chan_stats->rx_duration_us = ev->rx_duration_us; 14152 } 14153 14154 return QDF_STATUS_SUCCESS; 14155 } 14156 14157 /** 14158 * extract_profile_ctx_tlv() - extract profile context from event 14159 * @wmi_handle: wmi handle 14160 * @evt_buf: pointer to event buffer 14161 * @profile_ctx: Pointer to hold profile context 14162 * 14163 * Return: QDF_STATUS_SUCCESS for success or error code 14164 */ 14165 static QDF_STATUS extract_profile_ctx_tlv(wmi_unified_t wmi_handle, 14166 void *evt_buf, wmi_host_wlan_profile_ctx_t *profile_ctx) 14167 { 14168 WMI_WLAN_PROFILE_DATA_EVENTID_param_tlvs *param_buf; 14169 14170 wmi_wlan_profile_ctx_t *ev; 14171 14172 param_buf = (WMI_WLAN_PROFILE_DATA_EVENTID_param_tlvs *)evt_buf; 14173 if (!param_buf) { 14174 wmi_err("Invalid profile data event buf"); 14175 return QDF_STATUS_E_INVAL; 14176 } 14177 14178 ev = param_buf->profile_ctx; 14179 14180 profile_ctx->tot = ev->tot; 14181 profile_ctx->tx_msdu_cnt = ev->tx_msdu_cnt; 14182 profile_ctx->tx_mpdu_cnt = ev->tx_mpdu_cnt; 14183 profile_ctx->tx_ppdu_cnt = ev->tx_ppdu_cnt; 14184 profile_ctx->rx_msdu_cnt = ev->rx_msdu_cnt; 14185 profile_ctx->rx_mpdu_cnt = ev->rx_mpdu_cnt; 14186 profile_ctx->bin_count = ev->bin_count; 14187 14188 return QDF_STATUS_SUCCESS; 14189 } 14190 14191 /** 14192 * extract_profile_data_tlv() - extract profile data from event 14193 * @wmi_handle: wmi handle 14194 * @evt_buf: pointer to event buffer 14195 * @idx: profile stats index to extract 14196 * @profile_data: Pointer to hold profile data 14197 * 14198 * Return: QDF_STATUS_SUCCESS for success or error code 14199 */ 14200 static QDF_STATUS extract_profile_data_tlv(wmi_unified_t wmi_handle, 14201 void *evt_buf, uint8_t idx, wmi_host_wlan_profile_t *profile_data) 14202 { 14203 WMI_WLAN_PROFILE_DATA_EVENTID_param_tlvs *param_buf; 14204 wmi_wlan_profile_t *ev; 14205 14206 param_buf = (WMI_WLAN_PROFILE_DATA_EVENTID_param_tlvs *)evt_buf; 14207 if (!param_buf) { 14208 wmi_err("Invalid profile data event buf"); 14209 return QDF_STATUS_E_INVAL; 14210 } 14211 14212 ev = ¶m_buf->profile_data[idx]; 14213 profile_data->id = ev->id; 14214 profile_data->cnt = ev->cnt; 14215 profile_data->tot = ev->tot; 14216 profile_data->min = ev->min; 14217 profile_data->max = ev->max; 14218 profile_data->hist_intvl = ev->hist_intvl; 14219 qdf_mem_copy(profile_data->hist, ev->hist, sizeof(profile_data->hist)); 14220 14221 return QDF_STATUS_SUCCESS; 14222 } 14223 14224 /** 14225 * extract_pdev_utf_event_tlv() - extract UTF data info from event 14226 * @wmi_handle: WMI handle 14227 * @evt_buf: Pointer to event buffer 14228 * @event: Pointer to hold data 14229 * 14230 * Return: QDF_STATUS_SUCCESS for success or error code 14231 */ 14232 static QDF_STATUS extract_pdev_utf_event_tlv(wmi_unified_t wmi_handle, 14233 uint8_t *evt_buf, 14234 struct wmi_host_pdev_utf_event *event) 14235 { 14236 WMI_PDEV_UTF_EVENTID_param_tlvs *param_buf; 14237 struct wmi_host_utf_seg_header_info *seg_hdr; 14238 14239 param_buf = (WMI_PDEV_UTF_EVENTID_param_tlvs *)evt_buf; 14240 event->data = param_buf->data; 14241 event->datalen = param_buf->num_data; 14242 14243 if (event->datalen < sizeof(struct wmi_host_utf_seg_header_info)) { 14244 wmi_err("Invalid datalen: %d", event->datalen); 14245 return QDF_STATUS_E_INVAL; 14246 } 14247 seg_hdr = (struct wmi_host_utf_seg_header_info *)param_buf->data; 14248 /* Set pdev_id=1 until FW adds support to include pdev_id */ 14249 event->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host( 14250 wmi_handle, 14251 seg_hdr->pdev_id); 14252 14253 return QDF_STATUS_SUCCESS; 14254 } 14255 14256 #ifdef WLAN_SUPPORT_RF_CHARACTERIZATION 14257 static QDF_STATUS extract_num_rf_characterization_entries_tlv(wmi_unified_t wmi_handle, 14258 uint8_t *event, 14259 uint32_t *num_rf_characterization_entries) 14260 { 14261 WMI_CHAN_RF_CHARACTERIZATION_INFO_EVENTID_param_tlvs *param_buf; 14262 14263 param_buf = (WMI_CHAN_RF_CHARACTERIZATION_INFO_EVENTID_param_tlvs *)event; 14264 if (!param_buf) 14265 return QDF_STATUS_E_INVAL; 14266 14267 *num_rf_characterization_entries = 14268 param_buf->num_wmi_chan_rf_characterization_info; 14269 14270 return QDF_STATUS_SUCCESS; 14271 } 14272 14273 static QDF_STATUS extract_rf_characterization_entries_tlv(wmi_unified_t wmi_handle, 14274 uint8_t *event, 14275 uint32_t num_rf_characterization_entries, 14276 struct wmi_host_rf_characterization_event_param *rf_characterization_entries) 14277 { 14278 WMI_CHAN_RF_CHARACTERIZATION_INFO_EVENTID_param_tlvs *param_buf; 14279 WMI_CHAN_RF_CHARACTERIZATION_INFO *wmi_rf_characterization_entry; 14280 uint8_t ix; 14281 14282 param_buf = (WMI_CHAN_RF_CHARACTERIZATION_INFO_EVENTID_param_tlvs *)event; 14283 if (!param_buf) 14284 return QDF_STATUS_E_INVAL; 14285 14286 wmi_rf_characterization_entry = 14287 param_buf->wmi_chan_rf_characterization_info; 14288 if (!wmi_rf_characterization_entry) 14289 return QDF_STATUS_E_INVAL; 14290 14291 /* 14292 * Using num_wmi_chan_rf_characterization instead of param_buf value 14293 * since memory for rf_characterization_entries was allocated using 14294 * the former. 14295 */ 14296 for (ix = 0; ix < num_rf_characterization_entries; ix++) { 14297 rf_characterization_entries[ix].freq = 14298 WMI_CHAN_RF_CHARACTERIZATION_FREQ_GET( 14299 &wmi_rf_characterization_entry[ix]); 14300 14301 rf_characterization_entries[ix].bw = 14302 WMI_CHAN_RF_CHARACTERIZATION_BW_GET( 14303 &wmi_rf_characterization_entry[ix]); 14304 14305 rf_characterization_entries[ix].chan_metric = 14306 WMI_CHAN_RF_CHARACTERIZATION_CHAN_METRIC_GET( 14307 &wmi_rf_characterization_entry[ix]); 14308 14309 wmi_nofl_debug("rf_characterization_entries[%u]: freq: %u, " 14310 "bw: %u, chan_metric: %u", 14311 ix, rf_characterization_entries[ix].freq, 14312 rf_characterization_entries[ix].bw, 14313 rf_characterization_entries[ix].chan_metric); 14314 } 14315 14316 return QDF_STATUS_SUCCESS; 14317 } 14318 #endif 14319 14320 #ifdef WLAN_FEATURE_11BE 14321 static void 14322 extract_11be_chainmask(struct wlan_psoc_host_chainmask_capabilities *cap, 14323 WMI_MAC_PHY_CHAINMASK_CAPABILITY *chainmask_caps) 14324 { 14325 cap->supports_chan_width_320 = 14326 WMI_SUPPORT_CHAN_WIDTH_320_GET(chainmask_caps->supported_flags); 14327 cap->supports_aDFS_320 = 14328 WMI_SUPPORT_ADFS_320_GET(chainmask_caps->supported_flags); 14329 } 14330 #else 14331 static void 14332 extract_11be_chainmask(struct wlan_psoc_host_chainmask_capabilities *cap, 14333 WMI_MAC_PHY_CHAINMASK_CAPABILITY *chainmask_caps) 14334 { 14335 } 14336 #endif /* WLAN_FEATURE_11BE */ 14337 14338 /** 14339 * extract_chainmask_tables_tlv() - extract chain mask tables from event 14340 * @wmi_handle: wmi handle 14341 * @event: pointer to event buffer 14342 * @chainmask_table: Pointer to hold extracted chainmask tables 14343 * 14344 * Return: QDF_STATUS_SUCCESS for success or error code 14345 */ 14346 static QDF_STATUS extract_chainmask_tables_tlv(wmi_unified_t wmi_handle, 14347 uint8_t *event, struct wlan_psoc_host_chainmask_table *chainmask_table) 14348 { 14349 WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *param_buf; 14350 WMI_MAC_PHY_CHAINMASK_CAPABILITY *chainmask_caps; 14351 WMI_SOC_MAC_PHY_HW_MODE_CAPS *hw_caps; 14352 uint8_t i = 0, j = 0; 14353 uint32_t num_mac_phy_chainmask_caps = 0; 14354 14355 param_buf = (WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *) event; 14356 if (!param_buf) 14357 return QDF_STATUS_E_INVAL; 14358 14359 hw_caps = param_buf->soc_hw_mode_caps; 14360 if (!hw_caps) 14361 return QDF_STATUS_E_INVAL; 14362 14363 if ((!hw_caps->num_chainmask_tables) || 14364 (hw_caps->num_chainmask_tables > PSOC_MAX_CHAINMASK_TABLES) || 14365 (hw_caps->num_chainmask_tables > 14366 param_buf->num_mac_phy_chainmask_combo)) 14367 return QDF_STATUS_E_INVAL; 14368 14369 chainmask_caps = param_buf->mac_phy_chainmask_caps; 14370 14371 if (!chainmask_caps) 14372 return QDF_STATUS_E_INVAL; 14373 14374 for (i = 0; i < hw_caps->num_chainmask_tables; i++) { 14375 if (chainmask_table[i].num_valid_chainmasks > 14376 (UINT_MAX - num_mac_phy_chainmask_caps)) { 14377 wmi_err_rl("integer overflow, num_mac_phy_chainmask_caps:%d, i:%d, um_valid_chainmasks:%d", 14378 num_mac_phy_chainmask_caps, i, 14379 chainmask_table[i].num_valid_chainmasks); 14380 return QDF_STATUS_E_INVAL; 14381 } 14382 num_mac_phy_chainmask_caps += 14383 chainmask_table[i].num_valid_chainmasks; 14384 } 14385 14386 if (num_mac_phy_chainmask_caps > 14387 param_buf->num_mac_phy_chainmask_caps) { 14388 wmi_err_rl("invalid chainmask caps num, num_mac_phy_chainmask_caps:%d, param_buf->num_mac_phy_chainmask_caps:%d", 14389 num_mac_phy_chainmask_caps, 14390 param_buf->num_mac_phy_chainmask_caps); 14391 return QDF_STATUS_E_INVAL; 14392 } 14393 14394 for (i = 0; i < hw_caps->num_chainmask_tables; i++) { 14395 14396 wmi_nofl_debug("Dumping chain mask combo data for table : %d", 14397 i); 14398 for (j = 0; j < chainmask_table[i].num_valid_chainmasks; j++) { 14399 14400 chainmask_table[i].cap_list[j].chainmask = 14401 chainmask_caps->chainmask; 14402 14403 chainmask_table[i].cap_list[j].supports_chan_width_20 = 14404 WMI_SUPPORT_CHAN_WIDTH_20_GET(chainmask_caps->supported_flags); 14405 14406 chainmask_table[i].cap_list[j].supports_chan_width_40 = 14407 WMI_SUPPORT_CHAN_WIDTH_40_GET(chainmask_caps->supported_flags); 14408 14409 chainmask_table[i].cap_list[j].supports_chan_width_80 = 14410 WMI_SUPPORT_CHAN_WIDTH_80_GET(chainmask_caps->supported_flags); 14411 14412 chainmask_table[i].cap_list[j].supports_chan_width_160 = 14413 WMI_SUPPORT_CHAN_WIDTH_160_GET(chainmask_caps->supported_flags); 14414 14415 chainmask_table[i].cap_list[j].supports_chan_width_80P80 = 14416 WMI_SUPPORT_CHAN_WIDTH_80P80_GET(chainmask_caps->supported_flags); 14417 14418 chainmask_table[i].cap_list[j].chain_mask_2G = 14419 WMI_SUPPORT_CHAIN_MASK_2G_GET(chainmask_caps->supported_flags); 14420 14421 chainmask_table[i].cap_list[j].chain_mask_5G = 14422 WMI_SUPPORT_CHAIN_MASK_5G_GET(chainmask_caps->supported_flags); 14423 14424 chainmask_table[i].cap_list[j].chain_mask_tx = 14425 WMI_SUPPORT_CHAIN_MASK_TX_GET(chainmask_caps->supported_flags); 14426 14427 chainmask_table[i].cap_list[j].chain_mask_rx = 14428 WMI_SUPPORT_CHAIN_MASK_RX_GET(chainmask_caps->supported_flags); 14429 14430 chainmask_table[i].cap_list[j].supports_aDFS = 14431 WMI_SUPPORT_CHAIN_MASK_ADFS_GET(chainmask_caps->supported_flags); 14432 14433 chainmask_table[i].cap_list[j].supports_aSpectral = 14434 WMI_SUPPORT_AGILE_SPECTRAL_GET(chainmask_caps->supported_flags); 14435 14436 chainmask_table[i].cap_list[j].supports_aSpectral_160 = 14437 WMI_SUPPORT_AGILE_SPECTRAL_160_GET(chainmask_caps->supported_flags); 14438 14439 chainmask_table[i].cap_list[j].supports_aDFS_160 = 14440 WMI_SUPPORT_ADFS_160_GET(chainmask_caps->supported_flags); 14441 14442 extract_11be_chainmask(&chainmask_table[i].cap_list[j], 14443 chainmask_caps); 14444 14445 wmi_nofl_debug("supported_flags: 0x%08x chainmasks: 0x%08x", 14446 chainmask_caps->supported_flags, 14447 chainmask_caps->chainmask); 14448 chainmask_caps++; 14449 } 14450 } 14451 14452 return QDF_STATUS_SUCCESS; 14453 } 14454 14455 /** 14456 * extract_service_ready_ext_tlv() - extract basic extended service ready params 14457 * from event 14458 * @wmi_handle: wmi handle 14459 * @event: pointer to event buffer 14460 * @param: Pointer to hold evt buf 14461 * 14462 * Return: QDF_STATUS_SUCCESS for success or error code 14463 */ 14464 static QDF_STATUS extract_service_ready_ext_tlv(wmi_unified_t wmi_handle, 14465 uint8_t *event, struct wlan_psoc_host_service_ext_param *param) 14466 { 14467 WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *param_buf; 14468 wmi_service_ready_ext_event_fixed_param *ev; 14469 WMI_SOC_MAC_PHY_HW_MODE_CAPS *hw_caps; 14470 WMI_SOC_HAL_REG_CAPABILITIES *reg_caps; 14471 WMI_MAC_PHY_CHAINMASK_COMBO *chain_mask_combo; 14472 uint8_t i = 0; 14473 14474 param_buf = (WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *) event; 14475 if (!param_buf) 14476 return QDF_STATUS_E_INVAL; 14477 14478 ev = param_buf->fixed_param; 14479 if (!ev) 14480 return QDF_STATUS_E_INVAL; 14481 14482 /* Move this to host based bitmap */ 14483 param->default_conc_scan_config_bits = 14484 ev->default_conc_scan_config_bits; 14485 param->default_fw_config_bits = ev->default_fw_config_bits; 14486 param->he_cap_info = ev->he_cap_info; 14487 param->mpdu_density = ev->mpdu_density; 14488 param->max_bssid_rx_filters = ev->max_bssid_rx_filters; 14489 param->fw_build_vers_ext = ev->fw_build_vers_ext; 14490 param->num_dbr_ring_caps = param_buf->num_dma_ring_caps; 14491 param->num_bin_scaling_params = param_buf->num_wmi_bin_scaling_params; 14492 param->max_bssid_indicator = ev->max_bssid_indicator; 14493 qdf_mem_copy(¶m->ppet, &ev->ppet, sizeof(param->ppet)); 14494 14495 hw_caps = param_buf->soc_hw_mode_caps; 14496 if (hw_caps) 14497 param->num_hw_modes = hw_caps->num_hw_modes; 14498 else 14499 param->num_hw_modes = 0; 14500 14501 reg_caps = param_buf->soc_hal_reg_caps; 14502 if (reg_caps) 14503 param->num_phy = reg_caps->num_phy; 14504 else 14505 param->num_phy = 0; 14506 14507 if (hw_caps) { 14508 param->num_chainmask_tables = hw_caps->num_chainmask_tables; 14509 wmi_nofl_debug("Num chain mask tables: %d", 14510 hw_caps->num_chainmask_tables); 14511 } else 14512 param->num_chainmask_tables = 0; 14513 14514 if (param->num_chainmask_tables > PSOC_MAX_CHAINMASK_TABLES || 14515 param->num_chainmask_tables > 14516 param_buf->num_mac_phy_chainmask_combo) { 14517 wmi_err_rl("num_chainmask_tables is OOB: %u", 14518 param->num_chainmask_tables); 14519 return QDF_STATUS_E_INVAL; 14520 } 14521 chain_mask_combo = param_buf->mac_phy_chainmask_combo; 14522 14523 if (!chain_mask_combo) 14524 return QDF_STATUS_SUCCESS; 14525 14526 wmi_nofl_info_high("Dumping chain mask combo data"); 14527 14528 for (i = 0; i < param->num_chainmask_tables; i++) { 14529 14530 wmi_nofl_info_high("table_id : %d Num valid chainmasks: %d", 14531 chain_mask_combo->chainmask_table_id, 14532 chain_mask_combo->num_valid_chainmask); 14533 14534 param->chainmask_table[i].table_id = 14535 chain_mask_combo->chainmask_table_id; 14536 param->chainmask_table[i].num_valid_chainmasks = 14537 chain_mask_combo->num_valid_chainmask; 14538 chain_mask_combo++; 14539 } 14540 wmi_nofl_info_high("chain mask combo end"); 14541 14542 return QDF_STATUS_SUCCESS; 14543 } 14544 14545 #if defined(CONFIG_AFC_SUPPORT) 14546 /** 14547 * extract_svc_rdy_ext2_afc_tlv() - extract service ready ext2 afc deployment 14548 * type from event 14549 * @ev: pointer to event fixed param 14550 * @param: Pointer to hold the params 14551 * 14552 * Return: void 14553 */ 14554 static void 14555 extract_svc_rdy_ext2_afc_tlv(wmi_service_ready_ext2_event_fixed_param *ev, 14556 struct wlan_psoc_host_service_ext2_param *param) 14557 { 14558 WMI_AFC_FEATURE_6G_DEPLOYMENT_TYPE tgt_afc_dev_type; 14559 enum reg_afc_dev_deploy_type reg_afc_dev_type; 14560 14561 tgt_afc_dev_type = ev->afc_deployment_type; 14562 switch (tgt_afc_dev_type) { 14563 case WMI_AFC_FEATURE_6G_DEPLOYMENT_UNSPECIFIED: 14564 reg_afc_dev_type = AFC_DEPLOYMENT_INDOOR; 14565 break; 14566 case WMI_AFC_FEATURE_6G_DEPLOYMENT_INDOOR_ONLY: 14567 reg_afc_dev_type = AFC_DEPLOYMENT_INDOOR; 14568 break; 14569 case WMI_AFC_FEATURE_6G_DEPLOYMENT_OUTDOOR_ONLY: 14570 reg_afc_dev_type = AFC_DEPLOYMENT_OUTDOOR; 14571 break; 14572 default: 14573 wmi_err("invalid afc deployment %d", tgt_afc_dev_type); 14574 reg_afc_dev_type = AFC_DEPLOYMENT_UNKNOWN; 14575 break; 14576 } 14577 param->afc_dev_type = reg_afc_dev_type; 14578 14579 wmi_debug("afc dev type:%d", ev->afc_deployment_type); 14580 } 14581 #else 14582 static inline void 14583 extract_svc_rdy_ext2_afc_tlv(wmi_service_ready_ext2_event_fixed_param *ev, 14584 struct wlan_psoc_host_service_ext2_param *param) 14585 { 14586 } 14587 #endif 14588 14589 /** 14590 * extract_ul_mumimo_support() - extract UL-MUMIMO capability from target cap 14591 * @param: Pointer to hold the params 14592 * 14593 * Return: Void 14594 */ 14595 static void 14596 extract_ul_mumimo_support(struct wlan_psoc_host_service_ext2_param *param) 14597 { 14598 uint32_t tgt_cap = param->target_cap_flags; 14599 14600 param->ul_mumimo_rx_2g = WMI_TARGET_CAP_UL_MU_MIMO_RX_SUPPORT_2GHZ_GET(tgt_cap); 14601 param->ul_mumimo_rx_5g = WMI_TARGET_CAP_UL_MU_MIMO_RX_SUPPORT_5GHZ_GET(tgt_cap); 14602 param->ul_mumimo_rx_6g = WMI_TARGET_CAP_UL_MU_MIMO_RX_SUPPORT_6GHZ_GET(tgt_cap); 14603 param->ul_mumimo_tx_2g = WMI_TARGET_CAP_UL_MU_MIMO_TX_SUPPORT_2GHZ_GET(tgt_cap); 14604 param->ul_mumimo_tx_5g = WMI_TARGET_CAP_UL_MU_MIMO_TX_SUPPORT_5GHZ_GET(tgt_cap); 14605 param->ul_mumimo_tx_6g = WMI_TARGET_CAP_UL_MU_MIMO_TX_SUPPORT_6GHZ_GET(tgt_cap); 14606 } 14607 14608 /** 14609 * extract_hw_bdf_status() - extract service ready ext2 BDF hw status 14610 * type from event 14611 * @ev: pointer to event fixed param 14612 * 14613 * Return: void 14614 */ 14615 14616 static void 14617 extract_hw_bdf_status(wmi_service_ready_ext2_event_fixed_param *ev) 14618 { 14619 uint8_t hw_bdf_s; 14620 14621 hw_bdf_s = ev->hw_bd_status; 14622 switch (hw_bdf_s) { 14623 case WMI_BDF_VERSION_CHECK_DISABLED: 14624 wmi_info("BDF VER is %d, FW and BDF ver check skipped", 14625 hw_bdf_s); 14626 break; 14627 case WMI_BDF_VERSION_CHECK_GOOD: 14628 wmi_info("BDF VER is %d, FW and BDF ver check good", 14629 hw_bdf_s); 14630 break; 14631 case WMI_BDF_VERSION_TEMPLATE_TOO_OLD: 14632 wmi_info("BDF VER is %d, BDF ver is older than the oldest version supported by FW", 14633 hw_bdf_s); 14634 break; 14635 case WMI_BDF_VERSION_TEMPLATE_TOO_NEW: 14636 wmi_info("BDF VER is %d, BDF ver is newer than the newest version supported by FW", 14637 hw_bdf_s); 14638 break; 14639 case WMI_BDF_VERSION_FW_TOO_OLD: 14640 wmi_info("BDF VER is %d, FW ver is older than the major version supported by BDF", 14641 hw_bdf_s); 14642 break; 14643 case WMI_BDF_VERSION_FW_TOO_NEW: 14644 wmi_info("BDF VER is %d, FW ver is newer than the minor version supported by BDF", 14645 hw_bdf_s); 14646 break; 14647 default: 14648 wmi_info("unknown BDF VER %d", hw_bdf_s); 14649 break; 14650 } 14651 } 14652 14653 #ifdef QCA_MULTIPASS_SUPPORT 14654 static void 14655 extract_multipass_sap_cap(struct wlan_psoc_host_service_ext2_param *param, 14656 uint32_t target_cap_flag) 14657 { 14658 param->is_multipass_sap = 14659 WMI_TARGET_CAP_MULTIPASS_SAP_SUPPORT_GET(target_cap_flag); 14660 } 14661 #else 14662 static void 14663 extract_multipass_sap_cap(struct wlan_psoc_host_service_ext2_param *param, 14664 uint32_t target_cap_flag) 14665 { 14666 } 14667 #endif 14668 14669 #if defined(WLAN_FEATURE_11BE_MLO_ADV_FEATURE) 14670 static inline void 14671 extract_num_max_mlo_link(wmi_service_ready_ext2_event_fixed_param *ev, 14672 struct wlan_psoc_host_service_ext2_param *param) 14673 { 14674 param->num_max_mlo_link_per_ml_bss_supp = 14675 ev->num_max_mlo_link_per_ml_bss_supp; 14676 14677 wmi_debug("Firmware Max MLO link support: %d", 14678 param->num_max_mlo_link_per_ml_bss_supp); 14679 } 14680 #else 14681 static inline void 14682 extract_num_max_mlo_link(wmi_service_ready_ext2_event_fixed_param *ev, 14683 struct wlan_psoc_host_service_ext2_param *param) 14684 { 14685 } 14686 #endif 14687 14688 /** 14689 * extract_service_ready_ext2_tlv() - extract service ready ext2 params from 14690 * event 14691 * @wmi_handle: wmi handle 14692 * @event: pointer to event buffer 14693 * @param: Pointer to hold the params 14694 * 14695 * Return: QDF_STATUS_SUCCESS for success or error code 14696 */ 14697 static QDF_STATUS 14698 extract_service_ready_ext2_tlv(wmi_unified_t wmi_handle, uint8_t *event, 14699 struct wlan_psoc_host_service_ext2_param *param) 14700 { 14701 WMI_SERVICE_READY_EXT2_EVENTID_param_tlvs *param_buf; 14702 wmi_service_ready_ext2_event_fixed_param *ev; 14703 14704 param_buf = (WMI_SERVICE_READY_EXT2_EVENTID_param_tlvs *)event; 14705 if (!param_buf) 14706 return QDF_STATUS_E_INVAL; 14707 14708 ev = param_buf->fixed_param; 14709 if (!ev) 14710 return QDF_STATUS_E_INVAL; 14711 14712 param->reg_db_version_major = 14713 WMI_REG_DB_VERSION_MAJOR_GET( 14714 ev->reg_db_version); 14715 param->reg_db_version_minor = 14716 WMI_REG_DB_VERSION_MINOR_GET( 14717 ev->reg_db_version); 14718 param->bdf_reg_db_version_major = 14719 WMI_BDF_REG_DB_VERSION_MAJOR_GET( 14720 ev->reg_db_version); 14721 param->bdf_reg_db_version_minor = 14722 WMI_BDF_REG_DB_VERSION_MINOR_GET( 14723 ev->reg_db_version); 14724 param->chwidth_num_peer_caps = ev->chwidth_num_peer_caps; 14725 14726 param->num_dbr_ring_caps = param_buf->num_dma_ring_caps; 14727 14728 param->num_msdu_idx_qtype_map = 14729 param_buf->num_htt_msdu_idx_to_qtype_map; 14730 14731 if (param_buf->nan_cap) { 14732 param->max_ndp_sessions = 14733 param_buf->nan_cap->max_ndp_sessions; 14734 param->max_nan_pairing_sessions = 14735 param_buf->nan_cap->max_pairing_sessions; 14736 } else { 14737 param->max_ndp_sessions = 0; 14738 param->max_nan_pairing_sessions = 0; 14739 } 14740 14741 param->preamble_puncture_bw_cap = ev->preamble_puncture_bw; 14742 param->num_scan_radio_caps = param_buf->num_wmi_scan_radio_caps; 14743 param->max_users_dl_ofdma = WMI_MAX_USER_PER_PPDU_DL_OFDMA_GET( 14744 ev->max_user_per_ppdu_ofdma); 14745 param->max_users_ul_ofdma = WMI_MAX_USER_PER_PPDU_UL_OFDMA_GET( 14746 ev->max_user_per_ppdu_ofdma); 14747 param->max_users_dl_mumimo = WMI_MAX_USER_PER_PPDU_DL_MUMIMO_GET( 14748 ev->max_user_per_ppdu_mumimo); 14749 param->max_users_ul_mumimo = WMI_MAX_USER_PER_PPDU_UL_MUMIMO_GET( 14750 ev->max_user_per_ppdu_mumimo); 14751 param->target_cap_flags = ev->target_cap_flags; 14752 14753 param->dp_peer_meta_data_ver = 14754 WMI_TARGET_CAP_FLAGS_RX_PEER_METADATA_VERSION_GET( 14755 ev->target_cap_flags); 14756 14757 extract_multipass_sap_cap(param, ev->target_cap_flags); 14758 14759 extract_ul_mumimo_support(param); 14760 wmi_debug("htt peer data :%d", ev->target_cap_flags); 14761 14762 extract_svc_rdy_ext2_afc_tlv(ev, param); 14763 14764 extract_hw_bdf_status(ev); 14765 14766 extract_num_max_mlo_link(ev, param); 14767 14768 param->num_aux_dev_caps = param_buf->num_aux_dev_caps; 14769 14770 return QDF_STATUS_SUCCESS; 14771 } 14772 14773 /* 14774 * extract_dbs_or_sbs_cap_service_ready_ext2_tlv() - extract dbs_or_sbs cap from 14775 * service ready ext 2 14776 * 14777 * @wmi_handle: wmi handle 14778 * @event: pointer to event buffer 14779 * @sbs_lower_band_end_freq: If sbs_lower_band_end_freq is set to non-zero, 14780 * it indicates async SBS mode is supported, and 14781 * lower-band/higher band to MAC mapping is 14782 * switch-able. unit: mhz. examples 5180, 5320 14783 * 14784 * Return: QDF_STATUS_SUCCESS on success, QDF_STATUS_E_** on error 14785 */ 14786 static QDF_STATUS extract_dbs_or_sbs_cap_service_ready_ext2_tlv( 14787 wmi_unified_t wmi_handle, uint8_t *event, 14788 uint32_t *sbs_lower_band_end_freq) 14789 { 14790 WMI_SERVICE_READY_EXT2_EVENTID_param_tlvs *param_buf; 14791 wmi_dbs_or_sbs_cap_ext *dbs_or_sbs_caps; 14792 14793 param_buf = (WMI_SERVICE_READY_EXT2_EVENTID_param_tlvs *)event; 14794 if (!param_buf) 14795 return QDF_STATUS_E_INVAL; 14796 14797 dbs_or_sbs_caps = param_buf->dbs_or_sbs_cap_ext; 14798 if (!dbs_or_sbs_caps) 14799 return QDF_STATUS_E_INVAL; 14800 14801 *sbs_lower_band_end_freq = dbs_or_sbs_caps->sbs_lower_band_end_freq; 14802 14803 return QDF_STATUS_SUCCESS; 14804 } 14805 14806 /** 14807 * extract_sar_cap_service_ready_ext_tlv() - 14808 * extract SAR cap from service ready event 14809 * @wmi_handle: wmi handle 14810 * @event: pointer to event buffer 14811 * @ext_param: extended target info 14812 * 14813 * Return: QDF_STATUS_SUCCESS for success or error code 14814 */ 14815 static QDF_STATUS extract_sar_cap_service_ready_ext_tlv( 14816 wmi_unified_t wmi_handle, 14817 uint8_t *event, 14818 struct wlan_psoc_host_service_ext_param *ext_param) 14819 { 14820 WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *param_buf; 14821 WMI_SAR_CAPABILITIES *sar_caps; 14822 14823 param_buf = (WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *)event; 14824 14825 if (!param_buf) 14826 return QDF_STATUS_E_INVAL; 14827 14828 sar_caps = param_buf->sar_caps; 14829 if (sar_caps) 14830 ext_param->sar_version = sar_caps->active_version; 14831 else 14832 ext_param->sar_version = 0; 14833 14834 return QDF_STATUS_SUCCESS; 14835 } 14836 14837 /** 14838 * extract_hw_mode_cap_service_ready_ext_tlv() - 14839 * extract HW mode cap from service ready event 14840 * @wmi_handle: wmi handle 14841 * @event: pointer to event buffer 14842 * @hw_mode_idx: hw mode idx should be less than num_mode 14843 * @param: Pointer to hold evt buf 14844 * 14845 * Return: QDF_STATUS_SUCCESS for success or error code 14846 */ 14847 static QDF_STATUS extract_hw_mode_cap_service_ready_ext_tlv( 14848 wmi_unified_t wmi_handle, 14849 uint8_t *event, uint8_t hw_mode_idx, 14850 struct wlan_psoc_host_hw_mode_caps *param) 14851 { 14852 WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *param_buf; 14853 WMI_SOC_MAC_PHY_HW_MODE_CAPS *hw_caps; 14854 14855 param_buf = (WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *) event; 14856 if (!param_buf) 14857 return QDF_STATUS_E_INVAL; 14858 14859 hw_caps = param_buf->soc_hw_mode_caps; 14860 if (!hw_caps) 14861 return QDF_STATUS_E_INVAL; 14862 14863 if (!hw_caps->num_hw_modes || 14864 !param_buf->hw_mode_caps || 14865 hw_caps->num_hw_modes > PSOC_MAX_HW_MODE || 14866 hw_caps->num_hw_modes > param_buf->num_hw_mode_caps) 14867 return QDF_STATUS_E_INVAL; 14868 14869 if (hw_mode_idx >= hw_caps->num_hw_modes) 14870 return QDF_STATUS_E_INVAL; 14871 14872 param->hw_mode_id = param_buf->hw_mode_caps[hw_mode_idx].hw_mode_id; 14873 param->phy_id_map = param_buf->hw_mode_caps[hw_mode_idx].phy_id_map; 14874 14875 param->hw_mode_config_type = 14876 param_buf->hw_mode_caps[hw_mode_idx].hw_mode_config_type; 14877 14878 return QDF_STATUS_SUCCESS; 14879 } 14880 14881 /** 14882 * extract_service_ready_11be_support() - api to extract 11be support 14883 * @param: host mac phy capabilities 14884 * @mac_phy_caps: mac phy capabilities 14885 * 14886 * Return: void 14887 */ 14888 #ifdef WLAN_FEATURE_11BE 14889 static void 14890 extract_service_ready_11be_support(struct wlan_psoc_host_mac_phy_caps *param, 14891 WMI_MAC_PHY_CAPABILITIES *mac_phy_caps) 14892 { 14893 param->supports_11be = 14894 WMI_SUPPORT_11BE_GET(mac_phy_caps->supported_flags); 14895 14896 wmi_debug("11be support %d", param->supports_11be); 14897 } 14898 #else 14899 static void 14900 extract_service_ready_11be_support(struct wlan_psoc_host_mac_phy_caps *param, 14901 WMI_MAC_PHY_CAPABILITIES *mac_phy_caps) 14902 { 14903 } 14904 #endif 14905 14906 #if defined(WLAN_FEATURE_11BE_MLO) && defined(WLAN_MLO_MULTI_CHIP) 14907 static void extract_hw_link_id(struct wlan_psoc_host_mac_phy_caps *param, 14908 WMI_MAC_PHY_CAPABILITIES *mac_phy_caps) 14909 { 14910 param->hw_link_id = WMI_PHY_GET_HW_LINK_ID(mac_phy_caps->pdev_id); 14911 } 14912 #else 14913 static void extract_hw_link_id(struct wlan_psoc_host_mac_phy_caps *param, 14914 WMI_MAC_PHY_CAPABILITIES *mac_phy_caps) 14915 { 14916 } 14917 #endif /*WLAN_FEATURE_11BE_MLO && WLAN_MLO_MULTI_CHIP*/ 14918 14919 /** 14920 * extract_mac_phy_cap_service_ready_ext_tlv() - 14921 * extract MAC phy cap from service ready event 14922 * @wmi_handle: wmi handle 14923 * @event: pointer to event buffer 14924 * @hw_mode_id: hw mode idx should be less than num_mode 14925 * @phy_id: phy id within hw_mode 14926 * @param: Pointer to hold evt buf 14927 * 14928 * Return: QDF_STATUS_SUCCESS for success or error code 14929 */ 14930 static QDF_STATUS extract_mac_phy_cap_service_ready_ext_tlv( 14931 wmi_unified_t wmi_handle, 14932 uint8_t *event, uint8_t hw_mode_id, uint8_t phy_id, 14933 struct wlan_psoc_host_mac_phy_caps *param) 14934 { 14935 WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *param_buf; 14936 WMI_MAC_PHY_CAPABILITIES *mac_phy_caps; 14937 WMI_SOC_MAC_PHY_HW_MODE_CAPS *hw_caps; 14938 uint32_t phy_map; 14939 uint8_t hw_idx, phy_idx = 0, pdev_id; 14940 14941 param_buf = (WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *) event; 14942 if (!param_buf) 14943 return QDF_STATUS_E_INVAL; 14944 14945 hw_caps = param_buf->soc_hw_mode_caps; 14946 if (!hw_caps) 14947 return QDF_STATUS_E_INVAL; 14948 if (hw_caps->num_hw_modes > PSOC_MAX_HW_MODE || 14949 hw_caps->num_hw_modes > param_buf->num_hw_mode_caps) { 14950 wmi_err_rl("invalid num_hw_modes %d, num_hw_mode_caps %d", 14951 hw_caps->num_hw_modes, param_buf->num_hw_mode_caps); 14952 return QDF_STATUS_E_INVAL; 14953 } 14954 14955 for (hw_idx = 0; hw_idx < hw_caps->num_hw_modes; hw_idx++) { 14956 if (hw_mode_id == param_buf->hw_mode_caps[hw_idx].hw_mode_id) 14957 break; 14958 14959 phy_map = param_buf->hw_mode_caps[hw_idx].phy_id_map; 14960 while (phy_map) { 14961 phy_map >>= 1; 14962 phy_idx++; 14963 } 14964 } 14965 14966 if (hw_idx == hw_caps->num_hw_modes) 14967 return QDF_STATUS_E_INVAL; 14968 14969 phy_idx += phy_id; 14970 if (phy_idx >= param_buf->num_mac_phy_caps) 14971 return QDF_STATUS_E_INVAL; 14972 14973 mac_phy_caps = ¶m_buf->mac_phy_caps[phy_idx]; 14974 14975 param->hw_mode_id = mac_phy_caps->hw_mode_id; 14976 param->phy_idx = phy_idx; 14977 pdev_id = WMI_PHY_GET_PDEV_ID(mac_phy_caps->pdev_id); 14978 param->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host( 14979 wmi_handle, 14980 pdev_id); 14981 param->tgt_pdev_id = pdev_id; 14982 extract_hw_link_id(param, mac_phy_caps); 14983 param->phy_id = mac_phy_caps->phy_id; 14984 param->supports_11b = 14985 WMI_SUPPORT_11B_GET(mac_phy_caps->supported_flags); 14986 param->supports_11g = 14987 WMI_SUPPORT_11G_GET(mac_phy_caps->supported_flags); 14988 param->supports_11a = 14989 WMI_SUPPORT_11A_GET(mac_phy_caps->supported_flags); 14990 param->supports_11n = 14991 WMI_SUPPORT_11N_GET(mac_phy_caps->supported_flags); 14992 param->supports_11ac = 14993 WMI_SUPPORT_11AC_GET(mac_phy_caps->supported_flags); 14994 param->supports_11ax = 14995 WMI_SUPPORT_11AX_GET(mac_phy_caps->supported_flags); 14996 14997 extract_service_ready_11be_support(param, mac_phy_caps); 14998 14999 param->supported_bands = mac_phy_caps->supported_bands; 15000 param->ampdu_density = mac_phy_caps->ampdu_density; 15001 param->max_bw_supported_2G = mac_phy_caps->max_bw_supported_2G; 15002 param->ht_cap_info_2G = mac_phy_caps->ht_cap_info_2G; 15003 param->vht_cap_info_2G = mac_phy_caps->vht_cap_info_2G; 15004 param->vht_supp_mcs_2G = mac_phy_caps->vht_supp_mcs_2G; 15005 param->he_cap_info_2G[WMI_HOST_HECAP_MAC_WORD1] = 15006 mac_phy_caps->he_cap_info_2G; 15007 param->he_cap_info_2G[WMI_HOST_HECAP_MAC_WORD2] = 15008 mac_phy_caps->he_cap_info_2G_ext; 15009 param->he_supp_mcs_2G = mac_phy_caps->he_supp_mcs_2G; 15010 param->tx_chain_mask_2G = mac_phy_caps->tx_chain_mask_2G; 15011 param->rx_chain_mask_2G = mac_phy_caps->rx_chain_mask_2G; 15012 param->max_bw_supported_5G = mac_phy_caps->max_bw_supported_5G; 15013 param->ht_cap_info_5G = mac_phy_caps->ht_cap_info_5G; 15014 param->vht_cap_info_5G = mac_phy_caps->vht_cap_info_5G; 15015 param->vht_supp_mcs_5G = mac_phy_caps->vht_supp_mcs_5G; 15016 param->he_cap_info_5G[WMI_HOST_HECAP_MAC_WORD1] = 15017 mac_phy_caps->he_cap_info_5G; 15018 param->he_cap_info_5G[WMI_HOST_HECAP_MAC_WORD2] = 15019 mac_phy_caps->he_cap_info_5G_ext; 15020 param->he_supp_mcs_5G = mac_phy_caps->he_supp_mcs_5G; 15021 param->he_cap_info_internal = mac_phy_caps->he_cap_info_internal; 15022 param->tx_chain_mask_5G = mac_phy_caps->tx_chain_mask_5G; 15023 param->rx_chain_mask_5G = mac_phy_caps->rx_chain_mask_5G; 15024 qdf_mem_copy(¶m->he_cap_phy_info_2G, 15025 &mac_phy_caps->he_cap_phy_info_2G, 15026 sizeof(param->he_cap_phy_info_2G)); 15027 qdf_mem_copy(¶m->he_cap_phy_info_5G, 15028 &mac_phy_caps->he_cap_phy_info_5G, 15029 sizeof(param->he_cap_phy_info_5G)); 15030 qdf_mem_copy(¶m->he_ppet2G, &mac_phy_caps->he_ppet2G, 15031 sizeof(param->he_ppet2G)); 15032 qdf_mem_copy(¶m->he_ppet5G, &mac_phy_caps->he_ppet5G, 15033 sizeof(param->he_ppet5G)); 15034 param->chainmask_table_id = mac_phy_caps->chainmask_table_id; 15035 param->lmac_id = mac_phy_caps->lmac_id; 15036 param->reg_cap_ext.wireless_modes = convert_wireless_modes_tlv 15037 (mac_phy_caps->wireless_modes); 15038 param->reg_cap_ext.low_2ghz_chan = mac_phy_caps->low_2ghz_chan_freq; 15039 param->reg_cap_ext.high_2ghz_chan = mac_phy_caps->high_2ghz_chan_freq; 15040 param->reg_cap_ext.low_5ghz_chan = mac_phy_caps->low_5ghz_chan_freq; 15041 param->reg_cap_ext.high_5ghz_chan = mac_phy_caps->high_5ghz_chan_freq; 15042 param->nss_ratio_enabled = WMI_NSS_RATIO_ENABLE_DISABLE_GET( 15043 mac_phy_caps->nss_ratio); 15044 param->nss_ratio_info = WMI_NSS_RATIO_INFO_GET(mac_phy_caps->nss_ratio); 15045 15046 return QDF_STATUS_SUCCESS; 15047 } 15048 15049 #ifdef WLAN_FEATURE_11BE_MLO 15050 /** 15051 * extract_mac_phy_emlcap() - API to extract EML Capabilities 15052 * @param: host ext2 mac phy capabilities 15053 * @mac_phy_caps: ext mac phy capabilities 15054 * 15055 * Return: void 15056 */ 15057 static void extract_mac_phy_emlcap(struct wlan_psoc_host_mac_phy_caps_ext2 *param, 15058 WMI_MAC_PHY_CAPABILITIES_EXT *mac_phy_caps) 15059 { 15060 if (!param || !mac_phy_caps) 15061 return; 15062 15063 param->emlcap.emlsr_supp = WMI_SUPPORT_EMLSR_GET(mac_phy_caps->eml_capability); 15064 param->emlcap.emlsr_pad_delay = WMI_EMLSR_PADDING_DELAY_GET(mac_phy_caps->eml_capability); 15065 param->emlcap.emlsr_trans_delay = WMI_EMLSR_TRANSITION_DELAY_GET(mac_phy_caps->eml_capability); 15066 param->emlcap.emlmr_supp = WMI_SUPPORT_EMLMR_GET(mac_phy_caps->eml_capability); 15067 param->emlcap.emlmr_delay = WMI_EMLMR_DELAY_GET(mac_phy_caps->eml_capability); 15068 param->emlcap.trans_timeout = WMI_TRANSITION_TIMEOUT_GET(mac_phy_caps->eml_capability); 15069 } 15070 15071 /** 15072 * extract_mac_phy_mldcap() - API to extract MLD Capabilities 15073 * @param: host ext2 mac phy capabilities 15074 * @mac_phy_caps: ext mac phy capabilities 15075 * 15076 * Return: void 15077 */ 15078 static void extract_mac_phy_mldcap(struct wlan_psoc_host_mac_phy_caps_ext2 *param, 15079 WMI_MAC_PHY_CAPABILITIES_EXT *mac_phy_caps) 15080 { 15081 if (!param || !mac_phy_caps) 15082 return; 15083 15084 param->mldcap.max_simult_link = WMI_MAX_NUM_SIMULTANEOUS_LINKS_GET(mac_phy_caps->mld_capability); 15085 param->mldcap.srs_support = WMI_SUPPORT_SRS_GET(mac_phy_caps->mld_capability); 15086 param->mldcap.tid2link_neg_support = WMI_TID_TO_LINK_NEGOTIATION_GET(mac_phy_caps->mld_capability); 15087 param->mldcap.str_freq_sep = WMI_FREQ_SEPERATION_STR_GET(mac_phy_caps->mld_capability); 15088 param->mldcap.aar_support = WMI_SUPPORT_AAR_GET(mac_phy_caps->mld_capability); 15089 } 15090 15091 /** 15092 * extract_mac_phy_msdcap() - API to extract MSD Capabilities 15093 * @param: host ext2 mac phy capabilities 15094 * @mac_phy_caps: ext mac phy capabilities 15095 * 15096 * Return: void 15097 */ 15098 static void extract_mac_phy_msdcap(struct wlan_psoc_host_mac_phy_caps_ext2 *param, 15099 WMI_MAC_PHY_CAPABILITIES_EXT *mac_phy_caps) 15100 { 15101 if (!param || !mac_phy_caps) 15102 return; 15103 15104 param->msdcap.medium_sync_duration = WMI_MEDIUM_SYNC_DURATION_GET(mac_phy_caps->msd_capability); 15105 param->msdcap.medium_sync_ofdm_ed_thresh = WMI_MEDIUM_SYNC_OFDM_ED_THRESHOLD_GET(mac_phy_caps->msd_capability); 15106 param->msdcap.medium_sync_max_txop_num = WMI_MEDIUM_SYNC_MAX_NO_TXOPS_GET(mac_phy_caps->msd_capability); 15107 } 15108 #else 15109 static void extract_mac_phy_emlcap(struct wlan_psoc_host_mac_phy_caps_ext2 *param, 15110 WMI_MAC_PHY_CAPABILITIES_EXT *mac_phy_caps) 15111 { 15112 } 15113 15114 static void extract_mac_phy_mldcap(struct wlan_psoc_host_mac_phy_caps_ext2 *param, 15115 WMI_MAC_PHY_CAPABILITIES_EXT *mac_phy_caps) 15116 { 15117 } 15118 15119 static void extract_mac_phy_msdcap(struct wlan_psoc_host_mac_phy_caps_ext2 *param, 15120 WMI_MAC_PHY_CAPABILITIES_EXT *mac_phy_caps) 15121 { 15122 } 15123 #endif 15124 15125 /** 15126 * extract_mac_phy_cap_ehtcaps- api to extract eht mac phy caps 15127 * @param: host ext2 mac phy capabilities 15128 * @mac_phy_caps: ext mac phy capabilities 15129 * 15130 * Return: void 15131 */ 15132 #ifdef WLAN_FEATURE_11BE 15133 static void extract_mac_phy_cap_ehtcaps( 15134 struct wlan_psoc_host_mac_phy_caps_ext2 *param, 15135 WMI_MAC_PHY_CAPABILITIES_EXT *mac_phy_caps) 15136 { 15137 uint32_t i; 15138 15139 param->eht_supp_mcs_2G = mac_phy_caps->eht_supp_mcs_2G; 15140 param->eht_supp_mcs_5G = mac_phy_caps->eht_supp_mcs_5G; 15141 param->eht_cap_info_internal = mac_phy_caps->eht_cap_info_internal; 15142 15143 qdf_mem_copy(¶m->eht_cap_info_2G, 15144 &mac_phy_caps->eht_cap_mac_info_2G, 15145 sizeof(param->eht_cap_info_2G)); 15146 qdf_mem_copy(¶m->eht_cap_info_5G, 15147 &mac_phy_caps->eht_cap_mac_info_5G, 15148 sizeof(param->eht_cap_info_5G)); 15149 15150 qdf_mem_copy(¶m->eht_cap_phy_info_2G, 15151 &mac_phy_caps->eht_cap_phy_info_2G, 15152 sizeof(param->eht_cap_phy_info_2G)); 15153 qdf_mem_copy(¶m->eht_cap_phy_info_5G, 15154 &mac_phy_caps->eht_cap_phy_info_5G, 15155 sizeof(param->eht_cap_phy_info_5G)); 15156 15157 qdf_mem_copy(¶m->eht_supp_mcs_ext_2G, 15158 &mac_phy_caps->eht_supp_mcs_ext_2G, 15159 sizeof(param->eht_supp_mcs_ext_2G)); 15160 qdf_mem_copy(¶m->eht_supp_mcs_ext_5G, 15161 &mac_phy_caps->eht_supp_mcs_ext_5G, 15162 sizeof(param->eht_supp_mcs_ext_5G)); 15163 15164 qdf_mem_copy(¶m->eht_ppet2G, &mac_phy_caps->eht_ppet2G, 15165 sizeof(param->eht_ppet2G)); 15166 qdf_mem_copy(¶m->eht_ppet5G, &mac_phy_caps->eht_ppet5G, 15167 sizeof(param->eht_ppet5G)); 15168 15169 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", 15170 mac_phy_caps->eht_cap_mac_info_2G[0], 15171 mac_phy_caps->eht_cap_mac_info_5G[0], 15172 mac_phy_caps->eht_supp_mcs_2G, mac_phy_caps->eht_supp_mcs_5G, 15173 mac_phy_caps->eht_cap_info_internal); 15174 15175 wmi_nofl_debug("EHT phy caps: "); 15176 15177 wmi_nofl_debug("2G:"); 15178 for (i = 0; i < PSOC_HOST_MAX_EHT_PHY_SIZE; i++) { 15179 wmi_nofl_debug("index %d value %x", 15180 i, param->eht_cap_phy_info_2G[i]); 15181 } 15182 wmi_nofl_debug("5G:"); 15183 for (i = 0; i < PSOC_HOST_MAX_EHT_PHY_SIZE; i++) { 15184 wmi_nofl_debug("index %d value %x", 15185 i, param->eht_cap_phy_info_5G[i]); 15186 } 15187 wmi_nofl_debug("2G MCS ext Map:"); 15188 for (i = 0; i < PSOC_HOST_EHT_MCS_NSS_MAP_2G_SIZE; i++) { 15189 wmi_nofl_debug("index %d value %x", 15190 i, param->eht_supp_mcs_ext_2G[i]); 15191 } 15192 wmi_nofl_debug("5G MCS ext Map:"); 15193 for (i = 0; i < PSOC_HOST_EHT_MCS_NSS_MAP_5G_SIZE; i++) { 15194 wmi_nofl_debug("index %d value %x", 15195 i, param->eht_supp_mcs_ext_5G[i]); 15196 } 15197 wmi_nofl_debug("2G PPET: numss_m1 %x ru_bit_mask %x", 15198 param->eht_ppet2G.numss_m1, 15199 param->eht_ppet2G.ru_bit_mask); 15200 for (i = 0; i < PSOC_HOST_MAX_NUM_SS; i++) { 15201 wmi_nofl_debug("index %d value %x", 15202 i, param->eht_ppet2G.ppet16_ppet8_ru3_ru0[i]); 15203 } 15204 wmi_nofl_debug("5G PPET: numss_m1 %x ru_bit_mask %x", 15205 param->eht_ppet5G.numss_m1, 15206 param->eht_ppet5G.ru_bit_mask); 15207 for (i = 0; i < PSOC_HOST_MAX_NUM_SS; i++) { 15208 wmi_nofl_debug("index %d value %x", 15209 i, param->eht_ppet5G.ppet16_ppet8_ru3_ru0[i]); 15210 } 15211 } 15212 #else 15213 static void extract_mac_phy_cap_ehtcaps( 15214 struct wlan_psoc_host_mac_phy_caps_ext2 *param, 15215 WMI_MAC_PHY_CAPABILITIES_EXT *mac_phy_caps) 15216 { 15217 } 15218 #endif 15219 15220 static QDF_STATUS extract_mac_phy_cap_service_ready_ext2_tlv( 15221 wmi_unified_t wmi_handle, 15222 uint8_t *event, uint8_t hw_mode_id, uint8_t phy_id, 15223 uint8_t phy_idx, 15224 struct wlan_psoc_host_mac_phy_caps_ext2 *param) 15225 { 15226 WMI_SERVICE_READY_EXT2_EVENTID_param_tlvs *param_buf; 15227 WMI_MAC_PHY_CAPABILITIES_EXT *mac_phy_caps; 15228 15229 if (!event) { 15230 wmi_err("null evt_buf"); 15231 return QDF_STATUS_E_INVAL; 15232 } 15233 15234 param_buf = (WMI_SERVICE_READY_EXT2_EVENTID_param_tlvs *)event; 15235 15236 if (!param_buf->num_mac_phy_caps) 15237 return QDF_STATUS_SUCCESS; 15238 15239 if (phy_idx >= param_buf->num_mac_phy_caps) 15240 return QDF_STATUS_E_INVAL; 15241 15242 mac_phy_caps = ¶m_buf->mac_phy_caps[phy_idx]; 15243 15244 if ((hw_mode_id != mac_phy_caps->hw_mode_id) || 15245 (phy_id != mac_phy_caps->phy_id)) 15246 return QDF_STATUS_E_INVAL; 15247 15248 param->hw_mode_id = mac_phy_caps->hw_mode_id; 15249 param->phy_id = mac_phy_caps->phy_id; 15250 param->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host( 15251 wmi_handle, WMI_PHY_GET_PDEV_ID(mac_phy_caps->pdev_id)); 15252 param->wireless_modes_ext = convert_wireless_modes_ext_tlv( 15253 mac_phy_caps->wireless_modes_ext); 15254 15255 extract_mac_phy_cap_ehtcaps(param, mac_phy_caps); 15256 extract_mac_phy_emlcap(param, mac_phy_caps); 15257 extract_mac_phy_mldcap(param, mac_phy_caps); 15258 extract_mac_phy_msdcap(param, mac_phy_caps); 15259 15260 return QDF_STATUS_SUCCESS; 15261 } 15262 15263 /** 15264 * extract_reg_cap_service_ready_ext_tlv() - 15265 * extract REG cap from service ready event 15266 * @wmi_handle: wmi handle 15267 * @event: pointer to event buffer 15268 * @phy_idx: phy idx should be less than num_mode 15269 * @param: Pointer to hold evt buf 15270 * 15271 * Return: QDF_STATUS_SUCCESS for success or error code 15272 */ 15273 static QDF_STATUS extract_reg_cap_service_ready_ext_tlv( 15274 wmi_unified_t wmi_handle, 15275 uint8_t *event, uint8_t phy_idx, 15276 struct wlan_psoc_host_hal_reg_capabilities_ext *param) 15277 { 15278 WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *param_buf; 15279 WMI_SOC_HAL_REG_CAPABILITIES *reg_caps; 15280 WMI_HAL_REG_CAPABILITIES_EXT *ext_reg_cap; 15281 15282 param_buf = (WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *) event; 15283 if (!param_buf) 15284 return QDF_STATUS_E_INVAL; 15285 15286 reg_caps = param_buf->soc_hal_reg_caps; 15287 if (!reg_caps) 15288 return QDF_STATUS_E_INVAL; 15289 15290 if (reg_caps->num_phy > param_buf->num_hal_reg_caps) 15291 return QDF_STATUS_E_INVAL; 15292 15293 if (phy_idx >= reg_caps->num_phy) 15294 return QDF_STATUS_E_INVAL; 15295 15296 if (!param_buf->hal_reg_caps) 15297 return QDF_STATUS_E_INVAL; 15298 15299 ext_reg_cap = ¶m_buf->hal_reg_caps[phy_idx]; 15300 15301 param->phy_id = ext_reg_cap->phy_id; 15302 param->eeprom_reg_domain = ext_reg_cap->eeprom_reg_domain; 15303 param->eeprom_reg_domain_ext = ext_reg_cap->eeprom_reg_domain_ext; 15304 param->regcap1 = ext_reg_cap->regcap1; 15305 param->regcap2 = ext_reg_cap->regcap2; 15306 param->wireless_modes = convert_wireless_modes_tlv( 15307 ext_reg_cap->wireless_modes); 15308 param->low_2ghz_chan = ext_reg_cap->low_2ghz_chan; 15309 param->high_2ghz_chan = ext_reg_cap->high_2ghz_chan; 15310 param->low_5ghz_chan = ext_reg_cap->low_5ghz_chan; 15311 param->high_5ghz_chan = ext_reg_cap->high_5ghz_chan; 15312 15313 return QDF_STATUS_SUCCESS; 15314 } 15315 15316 static QDF_STATUS validate_dbr_ring_caps_idx(uint8_t idx, 15317 uint8_t num_dma_ring_caps) 15318 { 15319 /* If dma_ring_caps is populated, num_dbr_ring_caps is non-zero */ 15320 if (!num_dma_ring_caps) { 15321 wmi_err("dma_ring_caps %d", num_dma_ring_caps); 15322 return QDF_STATUS_E_INVAL; 15323 } 15324 if (idx >= num_dma_ring_caps) { 15325 wmi_err("Index %d exceeds range", idx); 15326 return QDF_STATUS_E_INVAL; 15327 } 15328 return QDF_STATUS_SUCCESS; 15329 } 15330 15331 static void 15332 populate_dbr_ring_cap_elems(wmi_unified_t wmi_handle, 15333 struct wlan_psoc_host_dbr_ring_caps *param, 15334 WMI_DMA_RING_CAPABILITIES *dbr_ring_caps) 15335 { 15336 param->pdev_id = wmi_handle->ops->convert_target_pdev_id_to_host( 15337 wmi_handle, 15338 dbr_ring_caps->pdev_id); 15339 param->mod_id = dbr_ring_caps->mod_id; 15340 param->ring_elems_min = dbr_ring_caps->ring_elems_min; 15341 param->min_buf_size = dbr_ring_caps->min_buf_size; 15342 param->min_buf_align = dbr_ring_caps->min_buf_align; 15343 } 15344 15345 static QDF_STATUS extract_dbr_ring_cap_service_ready_ext_tlv( 15346 wmi_unified_t wmi_handle, 15347 uint8_t *event, uint8_t idx, 15348 struct wlan_psoc_host_dbr_ring_caps *param) 15349 { 15350 WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *param_buf; 15351 QDF_STATUS status; 15352 15353 param_buf = (WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *)event; 15354 if (!param_buf) 15355 return QDF_STATUS_E_INVAL; 15356 15357 status = validate_dbr_ring_caps_idx(idx, param_buf->num_dma_ring_caps); 15358 if (status != QDF_STATUS_SUCCESS) 15359 return status; 15360 15361 populate_dbr_ring_cap_elems(wmi_handle, param, 15362 ¶m_buf->dma_ring_caps[idx]); 15363 return QDF_STATUS_SUCCESS; 15364 } 15365 15366 static QDF_STATUS extract_dbr_ring_cap_service_ready_ext2_tlv( 15367 wmi_unified_t wmi_handle, 15368 uint8_t *event, uint8_t idx, 15369 struct wlan_psoc_host_dbr_ring_caps *param) 15370 { 15371 WMI_SERVICE_READY_EXT2_EVENTID_param_tlvs *param_buf; 15372 QDF_STATUS status; 15373 15374 param_buf = (WMI_SERVICE_READY_EXT2_EVENTID_param_tlvs *)event; 15375 if (!param_buf) 15376 return QDF_STATUS_E_INVAL; 15377 15378 status = validate_dbr_ring_caps_idx(idx, param_buf->num_dma_ring_caps); 15379 if (status != QDF_STATUS_SUCCESS) 15380 return status; 15381 15382 populate_dbr_ring_cap_elems(wmi_handle, param, 15383 ¶m_buf->dma_ring_caps[idx]); 15384 return QDF_STATUS_SUCCESS; 15385 } 15386 15387 static QDF_STATUS extract_scan_radio_cap_service_ready_ext2_tlv( 15388 wmi_unified_t wmi_handle, 15389 uint8_t *event, uint8_t idx, 15390 struct wlan_psoc_host_scan_radio_caps *param) 15391 { 15392 WMI_SERVICE_READY_EXT2_EVENTID_param_tlvs *param_buf; 15393 WMI_SCAN_RADIO_CAPABILITIES_EXT2 *scan_radio_caps; 15394 15395 param_buf = (WMI_SERVICE_READY_EXT2_EVENTID_param_tlvs *)event; 15396 if (!param_buf) 15397 return QDF_STATUS_E_INVAL; 15398 15399 if (idx >= param_buf->num_wmi_scan_radio_caps) 15400 return QDF_STATUS_E_INVAL; 15401 15402 scan_radio_caps = ¶m_buf->wmi_scan_radio_caps[idx]; 15403 param->phy_id = scan_radio_caps->phy_id; 15404 param->scan_radio_supported = 15405 WMI_SCAN_RADIO_CAP_SCAN_RADIO_FLAG_GET(scan_radio_caps->flags); 15406 param->dfs_en = 15407 WMI_SCAN_RADIO_CAP_DFS_FLAG_GET(scan_radio_caps->flags); 15408 param->blanking_en = 15409 WMI_SCAN_RADIO_CAP_BLANKING_SUPPORT_GET(scan_radio_caps->flags); 15410 15411 return QDF_STATUS_SUCCESS; 15412 } 15413 15414 static QDF_STATUS extract_msdu_idx_qtype_map_service_ready_ext2_tlv( 15415 wmi_unified_t wmi_handle, 15416 uint8_t *event, uint8_t idx, 15417 uint8_t *msdu_qtype) 15418 { 15419 WMI_SERVICE_READY_EXT2_EVENTID_param_tlvs *param_buf; 15420 wmi_htt_msdu_idx_to_htt_msdu_qtype *msdu_idx_to_qtype; 15421 uint8_t wmi_htt_msdu_idx; 15422 15423 param_buf = (WMI_SERVICE_READY_EXT2_EVENTID_param_tlvs *)event; 15424 if (!param_buf) 15425 return QDF_STATUS_E_INVAL; 15426 15427 if (idx >= param_buf->num_htt_msdu_idx_to_qtype_map) 15428 return QDF_STATUS_E_INVAL; 15429 15430 msdu_idx_to_qtype = ¶m_buf->htt_msdu_idx_to_qtype_map[idx]; 15431 wmi_htt_msdu_idx = 15432 WMI_HTT_MSDUQ_IDX_TO_MSDUQ_QTYPE_INDEX_GET( 15433 msdu_idx_to_qtype->index_and_type); 15434 if (wmi_htt_msdu_idx != idx) { 15435 wmi_err("wmi_htt_msdu_idx 0x%x is not same as idx 0x%x", 15436 wmi_htt_msdu_idx, idx); 15437 return QDF_STATUS_E_INVAL; 15438 } 15439 15440 *msdu_qtype = 15441 WMI_HTT_MSDUQ_IDX_TO_MSDUQ_QTYPE_TYPE_GET( 15442 msdu_idx_to_qtype->index_and_type); 15443 15444 return QDF_STATUS_SUCCESS; 15445 } 15446 15447 static QDF_STATUS extract_sw_cal_ver_ext2_tlv(wmi_unified_t wmi_handle, 15448 uint8_t *event, 15449 struct wmi_host_sw_cal_ver *cal) 15450 { 15451 WMI_SERVICE_READY_EXT2_EVENTID_param_tlvs *param_buf; 15452 wmi_sw_cal_ver_cap *fw_cap; 15453 15454 param_buf = (WMI_SERVICE_READY_EXT2_EVENTID_param_tlvs *)event; 15455 if (!param_buf) 15456 return QDF_STATUS_E_INVAL; 15457 15458 fw_cap = param_buf->sw_cal_ver_cap; 15459 if (!fw_cap) 15460 return QDF_STATUS_E_INVAL; 15461 15462 cal->bdf_cal_ver = fw_cap->bdf_cal_ver; 15463 cal->ftm_cal_ver = fw_cap->ftm_cal_ver; 15464 cal->status = fw_cap->status; 15465 15466 return QDF_STATUS_SUCCESS; 15467 } 15468 15469 static QDF_STATUS extract_aux_dev_cap_service_ready_ext2_tlv( 15470 wmi_unified_t wmi_handle, 15471 uint8_t *event, uint8_t idx, 15472 struct wlan_psoc_host_aux_dev_caps *param) 15473 15474 { 15475 WMI_SERVICE_READY_EXT2_EVENTID_param_tlvs *param_buf; 15476 wmi_aux_dev_capabilities *aux_dev_caps; 15477 15478 param_buf = (WMI_SERVICE_READY_EXT2_EVENTID_param_tlvs *)event; 15479 15480 if (!param_buf->num_aux_dev_caps) 15481 return QDF_STATUS_E_INVAL; 15482 15483 if (!param_buf->aux_dev_caps) { 15484 wmi_err("aux_dev_caps is NULL"); 15485 return QDF_STATUS_E_INVAL; 15486 } 15487 15488 if (idx >= param_buf->num_aux_dev_caps) 15489 return QDF_STATUS_E_INVAL; 15490 15491 aux_dev_caps = ¶m_buf->aux_dev_caps[idx]; 15492 15493 param->aux_index = aux_dev_caps->aux_index; 15494 param->hw_mode_id = aux_dev_caps->hw_mode_id; 15495 param->supported_modes_bitmap = aux_dev_caps->supported_modes_bitmap; 15496 param->listen_pdev_id_map = aux_dev_caps->listen_pdev_id_map; 15497 param->emlsr_pdev_id_map = aux_dev_caps->emlsr_pdev_id_map; 15498 15499 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", 15500 idx, aux_dev_caps->aux_index, 15501 aux_dev_caps->hw_mode_id, 15502 aux_dev_caps->supported_modes_bitmap, 15503 aux_dev_caps->listen_pdev_id_map, 15504 aux_dev_caps->emlsr_pdev_id_map); 15505 15506 return QDF_STATUS_SUCCESS; 15507 } 15508 15509 /** 15510 * wmi_tgt_thermal_level_to_host() - Convert target thermal level to host enum 15511 * @level: target thermal level from WMI_THERM_THROT_STATS_EVENTID event 15512 * 15513 * Return: host thermal throt level 15514 */ 15515 static enum thermal_throttle_level 15516 wmi_tgt_thermal_level_to_host(uint32_t level) 15517 { 15518 switch (level) { 15519 case WMI_THERMAL_FULLPERF: 15520 return THERMAL_FULLPERF; 15521 case WMI_THERMAL_MITIGATION: 15522 return THERMAL_MITIGATION; 15523 case WMI_THERMAL_SHUTOFF: 15524 return THERMAL_SHUTOFF; 15525 case WMI_THERMAL_SHUTDOWN_TGT: 15526 return THERMAL_SHUTDOWN_TARGET; 15527 default: 15528 return THERMAL_UNKNOWN; 15529 } 15530 } 15531 15532 #ifdef THERMAL_STATS_SUPPORT 15533 static void 15534 populate_thermal_stats(WMI_THERM_THROT_STATS_EVENTID_param_tlvs *param_buf, 15535 uint32_t *therm_throt_levels, 15536 struct thermal_throt_level_stats *tt_temp_range_stats) 15537 { 15538 uint8_t lvl_idx; 15539 wmi_therm_throt_stats_event_fixed_param *tt_stats_event; 15540 wmi_thermal_throt_temp_range_stats *wmi_tt_stats; 15541 15542 tt_stats_event = param_buf->fixed_param; 15543 *therm_throt_levels = (tt_stats_event->therm_throt_levels > 15544 WMI_THERMAL_STATS_TEMP_THRESH_LEVEL_MAX) ? 15545 WMI_THERMAL_STATS_TEMP_THRESH_LEVEL_MAX : 15546 tt_stats_event->therm_throt_levels; 15547 15548 if (*therm_throt_levels > param_buf->num_temp_range_stats) { 15549 wmi_err("therm_throt_levels:%u oob num_temp_range_stats:%u", 15550 *therm_throt_levels, 15551 param_buf->num_temp_range_stats); 15552 return; 15553 } 15554 15555 wmi_tt_stats = param_buf->temp_range_stats; 15556 if (!wmi_tt_stats) { 15557 wmi_err("wmi_tt_stats Null"); 15558 return; 15559 } 15560 15561 for (lvl_idx = 0; lvl_idx < *therm_throt_levels; lvl_idx++) { 15562 tt_temp_range_stats[lvl_idx].start_temp_level = 15563 wmi_tt_stats[lvl_idx].start_temp_level; 15564 tt_temp_range_stats[lvl_idx].end_temp_level = 15565 wmi_tt_stats[lvl_idx].end_temp_level; 15566 tt_temp_range_stats[lvl_idx].total_time_ms_lo = 15567 wmi_tt_stats[lvl_idx].total_time_ms_lo; 15568 tt_temp_range_stats[lvl_idx].total_time_ms_hi = 15569 wmi_tt_stats[lvl_idx].total_time_ms_hi; 15570 tt_temp_range_stats[lvl_idx].num_entry = 15571 wmi_tt_stats[lvl_idx].num_entry; 15572 wmi_debug("level %d, start temp %d, end temp %d, total time low %d, total time high %d, counter %d", 15573 lvl_idx, wmi_tt_stats[lvl_idx].start_temp_level, 15574 wmi_tt_stats[lvl_idx].end_temp_level, 15575 wmi_tt_stats[lvl_idx].total_time_ms_lo, 15576 wmi_tt_stats[lvl_idx].total_time_ms_hi, 15577 wmi_tt_stats[lvl_idx].num_entry); 15578 } 15579 } 15580 #else 15581 static void 15582 populate_thermal_stats(WMI_THERM_THROT_STATS_EVENTID_param_tlvs *param_buf, 15583 uint32_t *therm_throt_levels, 15584 struct thermal_throt_level_stats *tt_temp_range_stats) 15585 { 15586 } 15587 #endif 15588 15589 /** 15590 * extract_thermal_stats_tlv() - extract thermal stats from event 15591 * @wmi_handle: wmi handle 15592 * @evt_buf: Pointer to event buffer 15593 * @temp: Pointer to hold extracted temperature 15594 * @level: Pointer to hold extracted level in host enum 15595 * @therm_throt_levels: Pointer to hold extracted thermal throttle temp 15596 * range 15597 * @tt_temp_range_stats_event: Pointer to hold extracted thermal stats for 15598 * every level 15599 * @pdev_id: Pointer to hold extracted pdev id 15600 * 15601 * Return: QDF_STATUS_SUCCESS for success or error code 15602 */ 15603 static QDF_STATUS 15604 extract_thermal_stats_tlv(wmi_unified_t wmi_handle, 15605 void *evt_buf, uint32_t *temp, 15606 enum thermal_throttle_level *level, 15607 uint32_t *therm_throt_levels, 15608 struct thermal_throt_level_stats *tt_temp_range_stats_event, 15609 uint32_t *pdev_id) 15610 { 15611 WMI_THERM_THROT_STATS_EVENTID_param_tlvs *param_buf; 15612 wmi_therm_throt_stats_event_fixed_param *tt_stats_event; 15613 15614 param_buf = 15615 (WMI_THERM_THROT_STATS_EVENTID_param_tlvs *) evt_buf; 15616 if (!param_buf) 15617 return QDF_STATUS_E_INVAL; 15618 15619 tt_stats_event = param_buf->fixed_param; 15620 wmi_debug("thermal temperature %d level %d", 15621 tt_stats_event->temp, tt_stats_event->level); 15622 *pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host( 15623 wmi_handle, 15624 tt_stats_event->pdev_id); 15625 *temp = tt_stats_event->temp; 15626 *level = wmi_tgt_thermal_level_to_host(tt_stats_event->level); 15627 15628 if (tt_stats_event->therm_throt_levels) 15629 populate_thermal_stats(param_buf, therm_throt_levels, 15630 tt_temp_range_stats_event); 15631 15632 return QDF_STATUS_SUCCESS; 15633 } 15634 15635 /** 15636 * extract_thermal_level_stats_tlv() - extract thermal level stats from event 15637 * @wmi_handle: wmi handle 15638 * @evt_buf: pointer to event buffer 15639 * @idx: Index to level stats 15640 * @levelcount: Pointer to hold levelcount 15641 * @dccount: Pointer to hold dccount 15642 * 15643 * Return: QDF_STATUS_SUCCESS for success or error code 15644 */ 15645 static QDF_STATUS 15646 extract_thermal_level_stats_tlv(wmi_unified_t wmi_handle, 15647 void *evt_buf, uint8_t idx, uint32_t *levelcount, 15648 uint32_t *dccount) 15649 { 15650 WMI_THERM_THROT_STATS_EVENTID_param_tlvs *param_buf; 15651 wmi_therm_throt_level_stats_info *tt_level_info; 15652 15653 param_buf = 15654 (WMI_THERM_THROT_STATS_EVENTID_param_tlvs *) evt_buf; 15655 if (!param_buf) 15656 return QDF_STATUS_E_INVAL; 15657 15658 tt_level_info = param_buf->therm_throt_level_stats_info; 15659 15660 if (idx < THERMAL_LEVELS) { 15661 *levelcount = tt_level_info[idx].level_count; 15662 *dccount = tt_level_info[idx].dc_count; 15663 return QDF_STATUS_SUCCESS; 15664 } 15665 15666 return QDF_STATUS_E_FAILURE; 15667 } 15668 15669 /** 15670 * fips_conv_data_be() - LE to BE conversion of FIPS ev data 15671 * @data_len: data length 15672 * @data: pointer to data 15673 * 15674 * Return: QDF_STATUS - success or error status 15675 */ 15676 #ifdef BIG_ENDIAN_HOST 15677 static QDF_STATUS fips_conv_data_be(uint32_t data_len, uint8_t *data) 15678 { 15679 uint8_t *data_aligned = NULL; 15680 int c; 15681 unsigned char *data_unaligned; 15682 15683 data_unaligned = qdf_mem_malloc(((sizeof(uint8_t) * data_len) + 15684 FIPS_ALIGN)); 15685 /* Assigning unaligned space to copy the data */ 15686 /* Checking if kmalloc does successful allocation */ 15687 if (!data_unaligned) 15688 return QDF_STATUS_E_FAILURE; 15689 15690 /* Checking if space is aligned */ 15691 if (!FIPS_IS_ALIGNED(data_unaligned, FIPS_ALIGN)) { 15692 /* align the data space */ 15693 data_aligned = 15694 (uint8_t *)FIPS_ALIGNTO(data_unaligned, FIPS_ALIGN); 15695 } else { 15696 data_aligned = (u_int8_t *)data_unaligned; 15697 } 15698 15699 /* memset and copy content from data to data aligned */ 15700 OS_MEMSET(data_aligned, 0, data_len); 15701 OS_MEMCPY(data_aligned, data, data_len); 15702 /* Endianness to LE */ 15703 for (c = 0; c < data_len/4; c++) { 15704 *((u_int32_t *)data_aligned + c) = 15705 qdf_le32_to_cpu(*((u_int32_t *)data_aligned + c)); 15706 } 15707 15708 /* Copy content to event->data */ 15709 OS_MEMCPY(data, data_aligned, data_len); 15710 15711 /* clean up allocated space */ 15712 qdf_mem_free(data_unaligned); 15713 data_aligned = NULL; 15714 data_unaligned = NULL; 15715 15716 /*************************************************************/ 15717 15718 return QDF_STATUS_SUCCESS; 15719 } 15720 #else 15721 static QDF_STATUS fips_conv_data_be(uint32_t data_len, uint8_t *data) 15722 { 15723 return QDF_STATUS_SUCCESS; 15724 } 15725 #endif 15726 15727 /** 15728 * send_pdev_get_pn_cmd_tlv() - send get PN request params to fw 15729 * @wmi_handle: wmi handle 15730 * @params: PN request params for peer 15731 * 15732 * Return: QDF_STATUS - success or error status 15733 */ 15734 static QDF_STATUS 15735 send_pdev_get_pn_cmd_tlv(wmi_unified_t wmi_handle, 15736 struct peer_request_pn_param *params) 15737 { 15738 wmi_peer_tx_pn_request_cmd_fixed_param *cmd; 15739 wmi_buf_t buf; 15740 uint8_t *buf_ptr; 15741 uint32_t len = sizeof(wmi_peer_tx_pn_request_cmd_fixed_param); 15742 15743 buf = wmi_buf_alloc(wmi_handle, len); 15744 if (!buf) { 15745 wmi_err("wmi_buf_alloc failed"); 15746 return QDF_STATUS_E_FAILURE; 15747 } 15748 15749 buf_ptr = (uint8_t *)wmi_buf_data(buf); 15750 cmd = (wmi_peer_tx_pn_request_cmd_fixed_param *)buf_ptr; 15751 15752 WMITLV_SET_HDR(&cmd->tlv_header, 15753 WMITLV_TAG_STRUC_wmi_peer_tx_pn_request_cmd_fixed_param, 15754 WMITLV_GET_STRUCT_TLVLEN(wmi_peer_tx_pn_request_cmd_fixed_param)); 15755 15756 cmd->vdev_id = params->vdev_id; 15757 WMI_CHAR_ARRAY_TO_MAC_ADDR(params->peer_macaddr, &cmd->peer_macaddr); 15758 cmd->key_type = params->key_type; 15759 cmd->key_ix = params->keyix; 15760 if (wmi_unified_cmd_send(wmi_handle, buf, len, 15761 WMI_PEER_TX_PN_REQUEST_CMDID)) { 15762 wmi_err("Failed to send WMI command"); 15763 wmi_buf_free(buf); 15764 return QDF_STATUS_E_FAILURE; 15765 } 15766 return QDF_STATUS_SUCCESS; 15767 } 15768 15769 /** 15770 * extract_get_pn_data_tlv() - extract pn resp 15771 * @wmi_handle: wmi handle 15772 * @evt_buf: pointer to event buffer 15773 * @param: PN response params for peer 15774 * 15775 * Return: QDF_STATUS - success or error status 15776 */ 15777 static QDF_STATUS 15778 extract_get_pn_data_tlv(wmi_unified_t wmi_handle, void *evt_buf, 15779 struct wmi_host_get_pn_event *param) 15780 { 15781 WMI_PEER_TX_PN_RESPONSE_EVENTID_param_tlvs *param_buf; 15782 wmi_peer_tx_pn_response_event_fixed_param *event = NULL; 15783 15784 param_buf = (WMI_PEER_TX_PN_RESPONSE_EVENTID_param_tlvs *)evt_buf; 15785 event = 15786 (wmi_peer_tx_pn_response_event_fixed_param *)param_buf->fixed_param; 15787 15788 param->vdev_id = event->vdev_id; 15789 param->key_type = event->key_type; 15790 param->key_ix = event->key_ix; 15791 qdf_mem_copy(param->pn, event->pn, sizeof(event->pn)); 15792 WMI_MAC_ADDR_TO_CHAR_ARRAY(&event->peer_macaddr, param->mac_addr); 15793 15794 return QDF_STATUS_SUCCESS; 15795 } 15796 15797 /** 15798 * send_pdev_get_rxpn_cmd_tlv() - send get Rx PN request params to fw 15799 * @wmi_handle: wmi handle 15800 * @params: Rx PN request params for peer 15801 * 15802 * Return: QDF_STATUS - success or error status 15803 */ 15804 static QDF_STATUS 15805 send_pdev_get_rxpn_cmd_tlv(wmi_unified_t wmi_handle, 15806 struct peer_request_rxpn_param *params) 15807 { 15808 wmi_peer_rx_pn_request_cmd_fixed_param *cmd; 15809 wmi_buf_t buf; 15810 uint8_t *buf_ptr; 15811 uint32_t len = sizeof(wmi_peer_rx_pn_request_cmd_fixed_param); 15812 15813 if (!is_service_enabled_tlv(wmi_handle, 15814 WMI_SERVICE_PN_REPLAY_CHECK_SUPPORT)) { 15815 wmi_err("Rx PN Replay Check not supported by target"); 15816 return QDF_STATUS_E_NOSUPPORT; 15817 } 15818 15819 buf = wmi_buf_alloc(wmi_handle, len); 15820 if (!buf) { 15821 wmi_err("wmi_buf_alloc failed"); 15822 return QDF_STATUS_E_FAILURE; 15823 } 15824 15825 buf_ptr = (uint8_t *)wmi_buf_data(buf); 15826 cmd = (wmi_peer_rx_pn_request_cmd_fixed_param *)buf_ptr; 15827 15828 WMITLV_SET_HDR(&cmd->tlv_header, 15829 WMITLV_TAG_STRUC_wmi_peer_rx_pn_request_cmd_fixed_param, 15830 WMITLV_GET_STRUCT_TLVLEN(wmi_peer_rx_pn_request_cmd_fixed_param)); 15831 15832 cmd->vdev_id = params->vdev_id; 15833 WMI_CHAR_ARRAY_TO_MAC_ADDR(params->peer_macaddr, &cmd->peer_macaddr); 15834 cmd->key_ix = params->keyix; 15835 if (wmi_unified_cmd_send(wmi_handle, buf, len, 15836 WMI_PEER_RX_PN_REQUEST_CMDID)) { 15837 wmi_err("Failed to send WMI command"); 15838 wmi_buf_free(buf); 15839 return QDF_STATUS_E_FAILURE; 15840 } 15841 return QDF_STATUS_SUCCESS; 15842 } 15843 15844 /** 15845 * extract_get_rxpn_data_tlv() - extract Rx PN resp 15846 * @wmi_handle: wmi handle 15847 * @evt_buf: pointer to event buffer 15848 * @params: Rx PN response params for peer 15849 * 15850 * Return: QDF_STATUS - success or error status 15851 */ 15852 static QDF_STATUS 15853 extract_get_rxpn_data_tlv(wmi_unified_t wmi_handle, void *evt_buf, 15854 struct wmi_host_get_rxpn_event *params) 15855 { 15856 WMI_PEER_RX_PN_RESPONSE_EVENTID_param_tlvs *param_buf; 15857 wmi_peer_rx_pn_response_event_fixed_param *event; 15858 15859 param_buf = evt_buf; 15860 event = param_buf->fixed_param; 15861 15862 params->vdev_id = event->vdev_id; 15863 params->keyix = event->key_idx; 15864 qdf_mem_copy(params->pn, event->pn, sizeof(event->pn)); 15865 WMI_MAC_ADDR_TO_CHAR_ARRAY(&event->peer_macaddr, params->mac_addr); 15866 15867 return QDF_STATUS_SUCCESS; 15868 } 15869 15870 /** 15871 * extract_fips_event_data_tlv() - extract fips event data 15872 * @wmi_handle: wmi handle 15873 * @evt_buf: pointer to event buffer 15874 * @param: pointer FIPS event params 15875 * 15876 * Return: QDF_STATUS_SUCCESS for success or error code 15877 */ 15878 static QDF_STATUS extract_fips_event_data_tlv(wmi_unified_t wmi_handle, 15879 void *evt_buf, struct wmi_host_fips_event_param *param) 15880 { 15881 WMI_PDEV_FIPS_EVENTID_param_tlvs *param_buf; 15882 wmi_pdev_fips_event_fixed_param *event; 15883 15884 param_buf = (WMI_PDEV_FIPS_EVENTID_param_tlvs *) evt_buf; 15885 event = (wmi_pdev_fips_event_fixed_param *) param_buf->fixed_param; 15886 15887 if (event->data_len > param_buf->num_data) 15888 return QDF_STATUS_E_FAILURE; 15889 15890 if (fips_conv_data_be(event->data_len, param_buf->data) != 15891 QDF_STATUS_SUCCESS) 15892 return QDF_STATUS_E_FAILURE; 15893 15894 param->data = (uint32_t *)param_buf->data; 15895 param->data_len = event->data_len; 15896 param->error_status = event->error_status; 15897 param->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host( 15898 wmi_handle, 15899 event->pdev_id); 15900 15901 return QDF_STATUS_SUCCESS; 15902 } 15903 15904 #ifdef WLAN_FEATURE_FIPS_BER_CCMGCM 15905 /** 15906 * extract_fips_extend_event_data_tlv() - extract fips event data 15907 * @wmi_handle: wmi handle 15908 * @evt_buf: pointer to event buffer 15909 * @param: pointer FIPS event params 15910 * 15911 * Return: QDF_STATUS_SUCCESS for success or error code 15912 */ 15913 static QDF_STATUS 15914 extract_fips_extend_event_data_tlv(wmi_unified_t wmi_handle, 15915 void *evt_buf, 15916 struct wmi_host_fips_extend_event_param 15917 *param) 15918 { 15919 WMI_PDEV_FIPS_EXTEND_EVENTID_param_tlvs *param_buf; 15920 wmi_pdev_fips_extend_event_fixed_param *event; 15921 15922 param_buf = (WMI_PDEV_FIPS_EXTEND_EVENTID_param_tlvs *)evt_buf; 15923 event = (wmi_pdev_fips_extend_event_fixed_param *)param_buf->fixed_param; 15924 15925 if (fips_conv_data_be(event->data_len, param_buf->data) != 15926 QDF_STATUS_SUCCESS) 15927 return QDF_STATUS_E_FAILURE; 15928 15929 param->data = (uint32_t *)param_buf->data; 15930 param->data_len = event->data_len; 15931 param->error_status = event->error_status; 15932 param->fips_cookie = event->fips_cookie; 15933 param->cmd_frag_idx = event->cmd_frag_idx; 15934 param->more_bit = event->more_bit; 15935 param->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host( 15936 wmi_handle, 15937 event->pdev_id); 15938 15939 return QDF_STATUS_SUCCESS; 15940 } 15941 #endif 15942 15943 #ifdef WLAN_FEATURE_DISA 15944 /** 15945 * extract_encrypt_decrypt_resp_event_tlv() - extract encrypt decrypt resp 15946 * params from event 15947 * @wmi_handle: wmi handle 15948 * @evt_buf: pointer to event buffer 15949 * @resp: Pointer to hold resp parameters 15950 * 15951 * Return: QDF_STATUS_SUCCESS for success or error code 15952 */ 15953 static QDF_STATUS 15954 extract_encrypt_decrypt_resp_event_tlv(wmi_unified_t wmi_handle, 15955 void *evt_buf, 15956 struct disa_encrypt_decrypt_resp_params 15957 *resp) 15958 { 15959 WMI_VDEV_ENCRYPT_DECRYPT_DATA_RESP_EVENTID_param_tlvs *param_buf; 15960 wmi_vdev_encrypt_decrypt_data_resp_event_fixed_param *data_event; 15961 15962 param_buf = evt_buf; 15963 if (!param_buf) { 15964 wmi_err("encrypt decrypt resp evt_buf is NULL"); 15965 return QDF_STATUS_E_INVAL; 15966 } 15967 15968 data_event = param_buf->fixed_param; 15969 15970 resp->vdev_id = data_event->vdev_id; 15971 resp->status = data_event->status; 15972 15973 if ((data_event->data_length > param_buf->num_enc80211_frame) || 15974 (data_event->data_length > WMI_SVC_MSG_MAX_SIZE - 15975 WMI_TLV_HDR_SIZE - sizeof(*data_event))) { 15976 wmi_err("FW msg data_len %d more than TLV hdr %d", 15977 data_event->data_length, 15978 param_buf->num_enc80211_frame); 15979 return QDF_STATUS_E_INVAL; 15980 } 15981 15982 resp->data_len = data_event->data_length; 15983 15984 if (resp->data_len) 15985 resp->data = (uint8_t *)param_buf->enc80211_frame; 15986 15987 return QDF_STATUS_SUCCESS; 15988 } 15989 #endif /* WLAN_FEATURE_DISA */ 15990 15991 static bool is_management_record_tlv(uint32_t cmd_id) 15992 { 15993 switch (cmd_id) { 15994 case WMI_MGMT_TX_SEND_CMDID: 15995 case WMI_MGMT_TX_COMPLETION_EVENTID: 15996 case WMI_OFFCHAN_DATA_TX_SEND_CMDID: 15997 case WMI_MGMT_RX_EVENTID: 15998 return true; 15999 default: 16000 return false; 16001 } 16002 } 16003 16004 static bool is_force_fw_hang_cmd_tlv(uint32_t cmd_id) 16005 { 16006 if (cmd_id == WMI_FORCE_FW_HANG_CMDID) 16007 return true; 16008 16009 return false; 16010 } 16011 16012 static bool is_diag_event_tlv(uint32_t event_id) 16013 { 16014 if (WMI_DIAG_EVENTID == event_id) 16015 return true; 16016 16017 return false; 16018 } 16019 16020 static uint16_t wmi_tag_fw_hang_cmd(wmi_unified_t wmi_handle) 16021 { 16022 uint16_t tag = 0; 16023 16024 if (qdf_atomic_read(&wmi_handle->is_target_suspended)) { 16025 qdf_nofl_err("%s: Target is already suspended, Ignore FW Hang Command", 16026 __func__); 16027 return tag; 16028 } 16029 16030 if (wmi_handle->tag_crash_inject) 16031 tag = HTC_TX_PACKET_TAG_AUTO_PM; 16032 16033 wmi_handle->tag_crash_inject = false; 16034 return tag; 16035 } 16036 16037 /** 16038 * wmi_set_htc_tx_tag_tlv() - set HTC TX tag for WMI commands 16039 * @wmi_handle: WMI handle 16040 * @buf: WMI buffer 16041 * @cmd_id: WMI command Id 16042 * 16043 * Return: htc_tx_tag 16044 */ 16045 static uint16_t wmi_set_htc_tx_tag_tlv(wmi_unified_t wmi_handle, 16046 wmi_buf_t buf, 16047 uint32_t cmd_id) 16048 { 16049 uint16_t htc_tx_tag = 0; 16050 16051 switch (cmd_id) { 16052 case WMI_WOW_ENABLE_CMDID: 16053 case WMI_PDEV_SUSPEND_CMDID: 16054 case WMI_WOW_HOSTWAKEUP_FROM_SLEEP_CMDID: 16055 case WMI_PDEV_RESUME_CMDID: 16056 case WMI_HB_SET_ENABLE_CMDID: 16057 case WMI_WOW_SET_ACTION_WAKE_UP_CMDID: 16058 #ifdef FEATURE_WLAN_D0WOW 16059 case WMI_D0_WOW_ENABLE_DISABLE_CMDID: 16060 #endif 16061 htc_tx_tag = HTC_TX_PACKET_TAG_AUTO_PM; 16062 break; 16063 case WMI_FORCE_FW_HANG_CMDID: 16064 htc_tx_tag = wmi_tag_fw_hang_cmd(wmi_handle); 16065 break; 16066 default: 16067 break; 16068 } 16069 16070 return htc_tx_tag; 16071 } 16072 16073 #ifdef CONFIG_BAND_6GHZ 16074 16075 static struct cur_reg_rule 16076 *create_ext_reg_rules_from_wmi(uint32_t num_reg_rules, 16077 wmi_regulatory_rule_ext_struct *wmi_reg_rule) 16078 { 16079 struct cur_reg_rule *reg_rule_ptr; 16080 uint32_t count; 16081 16082 if (!num_reg_rules) 16083 return NULL; 16084 16085 reg_rule_ptr = qdf_mem_malloc(num_reg_rules * 16086 sizeof(*reg_rule_ptr)); 16087 16088 if (!reg_rule_ptr) 16089 return NULL; 16090 16091 for (count = 0; count < num_reg_rules; count++) { 16092 reg_rule_ptr[count].start_freq = 16093 WMI_REG_RULE_START_FREQ_GET( 16094 wmi_reg_rule[count].freq_info); 16095 reg_rule_ptr[count].end_freq = 16096 WMI_REG_RULE_END_FREQ_GET( 16097 wmi_reg_rule[count].freq_info); 16098 reg_rule_ptr[count].max_bw = 16099 WMI_REG_RULE_MAX_BW_GET( 16100 wmi_reg_rule[count].bw_pwr_info); 16101 reg_rule_ptr[count].reg_power = 16102 WMI_REG_RULE_REG_POWER_GET( 16103 wmi_reg_rule[count].bw_pwr_info); 16104 reg_rule_ptr[count].ant_gain = 16105 WMI_REG_RULE_ANTENNA_GAIN_GET( 16106 wmi_reg_rule[count].bw_pwr_info); 16107 reg_rule_ptr[count].flags = 16108 WMI_REG_RULE_FLAGS_GET( 16109 wmi_reg_rule[count].flag_info); 16110 reg_rule_ptr[count].psd_flag = 16111 WMI_REG_RULE_PSD_FLAG_GET( 16112 wmi_reg_rule[count].psd_power_info); 16113 reg_rule_ptr[count].psd_eirp = 16114 WMI_REG_RULE_PSD_EIRP_GET( 16115 wmi_reg_rule[count].psd_power_info); 16116 } 16117 16118 return reg_rule_ptr; 16119 } 16120 #endif 16121 16122 static struct cur_reg_rule 16123 *create_reg_rules_from_wmi(uint32_t num_reg_rules, 16124 wmi_regulatory_rule_struct *wmi_reg_rule) 16125 { 16126 struct cur_reg_rule *reg_rule_ptr; 16127 uint32_t count; 16128 16129 if (!num_reg_rules) 16130 return NULL; 16131 16132 reg_rule_ptr = qdf_mem_malloc(num_reg_rules * 16133 sizeof(*reg_rule_ptr)); 16134 16135 if (!reg_rule_ptr) 16136 return NULL; 16137 16138 for (count = 0; count < num_reg_rules; count++) { 16139 reg_rule_ptr[count].start_freq = 16140 WMI_REG_RULE_START_FREQ_GET( 16141 wmi_reg_rule[count].freq_info); 16142 reg_rule_ptr[count].end_freq = 16143 WMI_REG_RULE_END_FREQ_GET( 16144 wmi_reg_rule[count].freq_info); 16145 reg_rule_ptr[count].max_bw = 16146 WMI_REG_RULE_MAX_BW_GET( 16147 wmi_reg_rule[count].bw_pwr_info); 16148 reg_rule_ptr[count].reg_power = 16149 WMI_REG_RULE_REG_POWER_GET( 16150 wmi_reg_rule[count].bw_pwr_info); 16151 reg_rule_ptr[count].ant_gain = 16152 WMI_REG_RULE_ANTENNA_GAIN_GET( 16153 wmi_reg_rule[count].bw_pwr_info); 16154 reg_rule_ptr[count].flags = 16155 WMI_REG_RULE_FLAGS_GET( 16156 wmi_reg_rule[count].flag_info); 16157 } 16158 16159 return reg_rule_ptr; 16160 } 16161 16162 static enum cc_setting_code wmi_reg_status_to_reg_status( 16163 WMI_REG_SET_CC_STATUS_CODE wmi_status_code) 16164 { 16165 if (wmi_status_code == WMI_REG_SET_CC_STATUS_PASS) { 16166 wmi_nofl_debug("REG_SET_CC_STATUS_PASS"); 16167 return REG_SET_CC_STATUS_PASS; 16168 } else if (wmi_status_code == WMI_REG_CURRENT_ALPHA2_NOT_FOUND) { 16169 wmi_nofl_debug("WMI_REG_CURRENT_ALPHA2_NOT_FOUND"); 16170 return REG_CURRENT_ALPHA2_NOT_FOUND; 16171 } else if (wmi_status_code == WMI_REG_INIT_ALPHA2_NOT_FOUND) { 16172 wmi_nofl_debug("WMI_REG_INIT_ALPHA2_NOT_FOUND"); 16173 return REG_INIT_ALPHA2_NOT_FOUND; 16174 } else if (wmi_status_code == WMI_REG_SET_CC_CHANGE_NOT_ALLOWED) { 16175 wmi_nofl_debug("WMI_REG_SET_CC_CHANGE_NOT_ALLOWED"); 16176 return REG_SET_CC_CHANGE_NOT_ALLOWED; 16177 } else if (wmi_status_code == WMI_REG_SET_CC_STATUS_NO_MEMORY) { 16178 wmi_nofl_debug("WMI_REG_SET_CC_STATUS_NO_MEMORY"); 16179 return REG_SET_CC_STATUS_NO_MEMORY; 16180 } else if (wmi_status_code == WMI_REG_SET_CC_STATUS_FAIL) { 16181 wmi_nofl_debug("WMI_REG_SET_CC_STATUS_FAIL"); 16182 return REG_SET_CC_STATUS_FAIL; 16183 } 16184 16185 wmi_debug("Unknown reg status code from WMI"); 16186 return REG_SET_CC_STATUS_FAIL; 16187 } 16188 16189 #ifdef CONFIG_BAND_6GHZ 16190 /** 16191 * reg_print_ap_power_type_6ghz - Prints the AP Power type 16192 * @ap_type: 6ghz-AP Power type 16193 * 16194 * Return: void 16195 */ 16196 static void reg_print_ap_power_type_6ghz(enum reg_6g_ap_type ap_type) 16197 { 16198 switch (ap_type) { 16199 case REG_INDOOR_AP: 16200 wmi_nofl_debug("AP Power type %s", "LOW POWER INDOOR"); 16201 break; 16202 case REG_STANDARD_POWER_AP: 16203 wmi_nofl_debug("AP Power type %s", "STANDARD POWER"); 16204 break; 16205 case REG_VERY_LOW_POWER_AP: 16206 wmi_nofl_debug("AP Power type %s", "VERY LOW POWER INDOOR"); 16207 break; 16208 default: 16209 wmi_nofl_debug("Invalid AP Power type %u", ap_type); 16210 } 16211 } 16212 16213 /** 16214 * reg_print_6ghz_client_type - Prints the client type 16215 * @client_type: 6ghz-client type 16216 * 16217 * Return: void 16218 */ 16219 static void reg_print_6ghz_client_type(enum reg_6g_client_type client_type) 16220 { 16221 switch (client_type) { 16222 case REG_DEFAULT_CLIENT: 16223 wmi_nofl_debug("Client type %s", "DEFAULT CLIENT"); 16224 break; 16225 case REG_SUBORDINATE_CLIENT: 16226 wmi_nofl_debug("Client type %s", "SUBORDINATE CLIENT"); 16227 break; 16228 default: 16229 wmi_nofl_debug("Invalid Client type %u", client_type); 16230 } 16231 } 16232 #else 16233 static inline void reg_print_ap_power_type_6ghz(enum reg_6g_ap_type ap_type) 16234 { 16235 } 16236 16237 static inline void reg_print_6ghz_client_type(enum reg_6g_client_type client_type) 16238 { 16239 } 16240 #endif /* CONFIG_BAND_6GHZ */ 16241 16242 #ifdef CONFIG_BAND_6GHZ 16243 16244 #ifdef CONFIG_REG_CLIENT 16245 #define MAX_NUM_FCC_RULES 2 16246 16247 /** 16248 * extract_ext_fcc_rules_from_wmi - extract fcc rules from WMI TLV 16249 * @num_fcc_rules: Number of FCC rules 16250 * @wmi_fcc_rule: WMI FCC rules TLV 16251 * 16252 * Return: fcc_rule_ptr 16253 */ 16254 static struct cur_fcc_rule 16255 *extract_ext_fcc_rules_from_wmi(uint32_t num_fcc_rules, 16256 wmi_regulatory_fcc_rule_struct *wmi_fcc_rule) 16257 { 16258 struct cur_fcc_rule *fcc_rule_ptr; 16259 uint32_t count; 16260 16261 if (!wmi_fcc_rule) 16262 return NULL; 16263 16264 fcc_rule_ptr = qdf_mem_malloc(num_fcc_rules * 16265 sizeof(*fcc_rule_ptr)); 16266 if (!fcc_rule_ptr) 16267 return NULL; 16268 16269 for (count = 0; count < num_fcc_rules; count++) { 16270 fcc_rule_ptr[count].center_freq = 16271 WMI_REG_FCC_RULE_CHAN_FREQ_GET( 16272 wmi_fcc_rule[count].freq_info); 16273 fcc_rule_ptr[count].tx_power = 16274 WMI_REG_FCC_RULE_FCC_TX_POWER_GET( 16275 wmi_fcc_rule[count].freq_info); 16276 } 16277 16278 return fcc_rule_ptr; 16279 } 16280 16281 /** 16282 * extract_reg_fcc_rules_tlv - Extract reg fcc rules TLV 16283 * @param_buf: Pointer to WMI params TLV 16284 * @ext_chan_list_event_hdr: Pointer to REG CHAN LIST CC EXT EVENT Fixed 16285 * Params TLV 16286 * @ext_wmi_reg_rule: Pointer to REG CHAN LIST CC EXT EVENT Reg Rules TLV 16287 * @ext_wmi_chan_priority: Pointer to REG CHAN LIST CC EXT EVENT Chan 16288 * Priority TLV 16289 * @evt_buf: Pointer to REG CHAN LIST CC EXT EVENT event buffer 16290 * @reg_info: Pointer to Regulatory Info 16291 * @len: Length of REG CHAN LIST CC EXT EVENT buffer 16292 * 16293 * Return: QDF_STATUS 16294 */ 16295 static QDF_STATUS extract_reg_fcc_rules_tlv( 16296 WMI_REG_CHAN_LIST_CC_EXT_EVENTID_param_tlvs *param_buf, 16297 wmi_reg_chan_list_cc_event_ext_fixed_param *ext_chan_list_event_hdr, 16298 wmi_regulatory_rule_ext_struct *ext_wmi_reg_rule, 16299 wmi_regulatory_chan_priority_struct *ext_wmi_chan_priority, 16300 uint8_t *evt_buf, 16301 struct cur_regulatory_info *reg_info, 16302 uint32_t len) 16303 { 16304 int i; 16305 wmi_regulatory_fcc_rule_struct *ext_wmi_fcc_rule; 16306 16307 if (!param_buf) { 16308 wmi_err("invalid channel list event buf"); 16309 return QDF_STATUS_E_INVAL; 16310 } 16311 16312 reg_info->num_fcc_rules = 0; 16313 if (param_buf->reg_fcc_rule) { 16314 if (param_buf->num_reg_fcc_rule > MAX_NUM_FCC_RULES) { 16315 wmi_err("Number of fcc rules is greater than MAX_NUM_FCC_RULES"); 16316 return QDF_STATUS_E_INVAL; 16317 } 16318 16319 ext_wmi_fcc_rule = 16320 (wmi_regulatory_fcc_rule_struct *) 16321 ((uint8_t *)ext_chan_list_event_hdr + 16322 sizeof(wmi_reg_chan_list_cc_event_ext_fixed_param) + 16323 WMI_TLV_HDR_SIZE + 16324 sizeof(wmi_regulatory_rule_ext_struct) * 16325 param_buf->num_reg_rule_array + 16326 WMI_TLV_HDR_SIZE + 16327 sizeof(wmi_regulatory_chan_priority_struct) * 16328 param_buf->num_reg_chan_priority + 16329 WMI_TLV_HDR_SIZE); 16330 16331 reg_info->fcc_rules_ptr = extract_ext_fcc_rules_from_wmi( 16332 param_buf->num_reg_fcc_rule, 16333 ext_wmi_fcc_rule); 16334 16335 reg_info->num_fcc_rules = param_buf->num_reg_fcc_rule; 16336 } else { 16337 wmi_err("Fcc rules not sent by fw"); 16338 } 16339 16340 if (reg_info->fcc_rules_ptr) { 16341 for (i = 0; i < reg_info->num_fcc_rules; i++) { 16342 wmi_nofl_debug("FCC rule %d center_freq %d tx_power %d", 16343 i, reg_info->fcc_rules_ptr[i].center_freq, 16344 reg_info->fcc_rules_ptr[i].tx_power); 16345 } 16346 } 16347 return QDF_STATUS_SUCCESS; 16348 } 16349 #else 16350 static QDF_STATUS extract_reg_fcc_rules_tlv( 16351 WMI_REG_CHAN_LIST_CC_EXT_EVENTID_param_tlvs *param_buf, 16352 wmi_reg_chan_list_cc_event_ext_fixed_param *ext_chan_list_event_hdr, 16353 wmi_regulatory_rule_ext_struct *ext_wmi_reg_rule, 16354 wmi_regulatory_chan_priority_struct *ext_wmi_chan_priority, 16355 uint8_t *evt_buf, 16356 struct cur_regulatory_info *reg_info, 16357 uint32_t len) 16358 { 16359 return QDF_STATUS_SUCCESS; 16360 } 16361 #endif 16362 16363 static QDF_STATUS extract_reg_chan_list_ext_update_event_tlv( 16364 wmi_unified_t wmi_handle, uint8_t *evt_buf, 16365 struct cur_regulatory_info *reg_info, uint32_t len) 16366 { 16367 uint32_t i, j, k; 16368 WMI_REG_CHAN_LIST_CC_EXT_EVENTID_param_tlvs *param_buf; 16369 wmi_reg_chan_list_cc_event_ext_fixed_param *ext_chan_list_event_hdr; 16370 wmi_regulatory_rule_ext_struct *ext_wmi_reg_rule; 16371 wmi_regulatory_chan_priority_struct *ext_wmi_chan_priority; 16372 uint32_t num_2g_reg_rules, num_5g_reg_rules; 16373 uint32_t num_6g_reg_rules_ap[REG_CURRENT_MAX_AP_TYPE]; 16374 uint32_t *num_6g_reg_rules_client[REG_CURRENT_MAX_AP_TYPE]; 16375 uint32_t total_reg_rules = 0; 16376 QDF_STATUS status; 16377 16378 param_buf = (WMI_REG_CHAN_LIST_CC_EXT_EVENTID_param_tlvs *)evt_buf; 16379 if (!param_buf) { 16380 wmi_err("invalid channel list event buf"); 16381 return QDF_STATUS_E_FAILURE; 16382 } 16383 16384 ext_chan_list_event_hdr = param_buf->fixed_param; 16385 ext_wmi_chan_priority = param_buf->reg_chan_priority; 16386 16387 if (ext_wmi_chan_priority) 16388 reg_info->reg_6g_thresh_priority_freq = 16389 WMI_GET_BITS(ext_wmi_chan_priority->freq_info, 0, 16); 16390 reg_info->num_2g_reg_rules = ext_chan_list_event_hdr->num_2g_reg_rules; 16391 reg_info->num_5g_reg_rules = ext_chan_list_event_hdr->num_5g_reg_rules; 16392 reg_info->num_6g_reg_rules_ap[REG_STANDARD_POWER_AP] = 16393 ext_chan_list_event_hdr->num_6g_reg_rules_ap_sp; 16394 reg_info->num_6g_reg_rules_ap[REG_INDOOR_AP] = 16395 ext_chan_list_event_hdr->num_6g_reg_rules_ap_lpi; 16396 reg_info->num_6g_reg_rules_ap[REG_VERY_LOW_POWER_AP] = 16397 ext_chan_list_event_hdr->num_6g_reg_rules_ap_vlp; 16398 16399 wmi_debug("num reg rules from fw, AP SP %d, LPI %d, VLP %d", 16400 reg_info->num_6g_reg_rules_ap[REG_STANDARD_POWER_AP], 16401 reg_info->num_6g_reg_rules_ap[REG_INDOOR_AP], 16402 reg_info->num_6g_reg_rules_ap[REG_VERY_LOW_POWER_AP]); 16403 16404 for (i = 0; i < REG_MAX_CLIENT_TYPE; i++) { 16405 reg_info->num_6g_reg_rules_client[REG_STANDARD_POWER_AP][i] = 16406 ext_chan_list_event_hdr->num_6g_reg_rules_client_sp[i]; 16407 reg_info->num_6g_reg_rules_client[REG_INDOOR_AP][i] = 16408 ext_chan_list_event_hdr->num_6g_reg_rules_client_lpi[i]; 16409 reg_info->num_6g_reg_rules_client[REG_VERY_LOW_POWER_AP][i] = 16410 ext_chan_list_event_hdr->num_6g_reg_rules_client_vlp[i]; 16411 wmi_nofl_debug("client %d SP %d, LPI %d, VLP %d", i, 16412 ext_chan_list_event_hdr->num_6g_reg_rules_client_sp[i], 16413 ext_chan_list_event_hdr->num_6g_reg_rules_client_lpi[i], 16414 ext_chan_list_event_hdr->num_6g_reg_rules_client_vlp[i]); 16415 } 16416 16417 num_2g_reg_rules = reg_info->num_2g_reg_rules; 16418 total_reg_rules += num_2g_reg_rules; 16419 num_5g_reg_rules = reg_info->num_5g_reg_rules; 16420 total_reg_rules += num_5g_reg_rules; 16421 for (i = 0; i < REG_CURRENT_MAX_AP_TYPE; i++) { 16422 num_6g_reg_rules_ap[i] = reg_info->num_6g_reg_rules_ap[i]; 16423 if (num_6g_reg_rules_ap[i] > MAX_6G_REG_RULES) { 16424 wmi_err_rl("Invalid num_6g_reg_rules_ap: %u", 16425 num_6g_reg_rules_ap[i]); 16426 return QDF_STATUS_E_FAILURE; 16427 } 16428 total_reg_rules += num_6g_reg_rules_ap[i]; 16429 num_6g_reg_rules_client[i] = 16430 reg_info->num_6g_reg_rules_client[i]; 16431 } 16432 16433 for (i = 0; i < REG_MAX_CLIENT_TYPE; i++) { 16434 total_reg_rules += 16435 num_6g_reg_rules_client[REG_STANDARD_POWER_AP][i]; 16436 total_reg_rules += num_6g_reg_rules_client[REG_INDOOR_AP][i]; 16437 total_reg_rules += 16438 num_6g_reg_rules_client[REG_VERY_LOW_POWER_AP][i]; 16439 if ((num_6g_reg_rules_client[REG_STANDARD_POWER_AP][i] > 16440 MAX_6G_REG_RULES) || 16441 (num_6g_reg_rules_client[REG_INDOOR_AP][i] > 16442 MAX_6G_REG_RULES) || 16443 (num_6g_reg_rules_client[REG_VERY_LOW_POWER_AP][i] > 16444 MAX_6G_REG_RULES)) { 16445 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", 16446 num_6g_reg_rules_client[REG_STANDARD_POWER_AP][i], 16447 num_6g_reg_rules_client[REG_INDOOR_AP][i], 16448 num_6g_reg_rules_client[REG_VERY_LOW_POWER_AP][i], 16449 i); 16450 return QDF_STATUS_E_FAILURE; 16451 } 16452 } 16453 16454 if (total_reg_rules != param_buf->num_reg_rule_array) { 16455 wmi_err_rl("Total reg rules %u does not match event params num reg rule %u", 16456 total_reg_rules, param_buf->num_reg_rule_array); 16457 return QDF_STATUS_E_FAILURE; 16458 } 16459 16460 if ((num_2g_reg_rules > MAX_REG_RULES) || 16461 (num_5g_reg_rules > MAX_REG_RULES)) { 16462 wmi_err_rl("Invalid num_2g_reg_rules: %u, num_5g_reg_rules: %u", 16463 num_2g_reg_rules, num_5g_reg_rules); 16464 return QDF_STATUS_E_FAILURE; 16465 } 16466 16467 if ((num_6g_reg_rules_ap[REG_STANDARD_POWER_AP] > MAX_6G_REG_RULES) || 16468 (num_6g_reg_rules_ap[REG_INDOOR_AP] > MAX_6G_REG_RULES) || 16469 (num_6g_reg_rules_ap[REG_VERY_LOW_POWER_AP] > MAX_6G_REG_RULES)) { 16470 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", 16471 num_6g_reg_rules_ap[REG_STANDARD_POWER_AP], 16472 num_6g_reg_rules_ap[REG_INDOOR_AP], 16473 num_6g_reg_rules_ap[REG_VERY_LOW_POWER_AP]); 16474 return QDF_STATUS_E_FAILURE; 16475 } 16476 16477 if (param_buf->num_reg_rule_array > 16478 (WMI_SVC_MSG_MAX_SIZE - sizeof(*ext_chan_list_event_hdr)) / 16479 sizeof(*ext_wmi_reg_rule)) { 16480 wmi_err_rl("Invalid ext_num_reg_rule_array: %u", 16481 param_buf->num_reg_rule_array); 16482 return QDF_STATUS_E_FAILURE; 16483 } 16484 16485 qdf_mem_copy(reg_info->alpha2, &ext_chan_list_event_hdr->alpha2, 16486 REG_ALPHA2_LEN); 16487 reg_info->dfs_region = ext_chan_list_event_hdr->dfs_region; 16488 reg_info->phybitmap = convert_phybitmap_tlv( 16489 ext_chan_list_event_hdr->phybitmap); 16490 reg_info->offload_enabled = true; 16491 reg_info->num_phy = ext_chan_list_event_hdr->num_phy; 16492 reg_info->phy_id = wmi_handle->ops->convert_phy_id_target_to_host( 16493 wmi_handle, ext_chan_list_event_hdr->phy_id); 16494 reg_info->ctry_code = ext_chan_list_event_hdr->country_id; 16495 reg_info->reg_dmn_pair = ext_chan_list_event_hdr->domain_code; 16496 16497 reg_info->status_code = 16498 wmi_reg_status_to_reg_status(ext_chan_list_event_hdr-> 16499 status_code); 16500 16501 reg_info->min_bw_2g = ext_chan_list_event_hdr->min_bw_2g; 16502 reg_info->max_bw_2g = ext_chan_list_event_hdr->max_bw_2g; 16503 reg_info->min_bw_5g = ext_chan_list_event_hdr->min_bw_5g; 16504 reg_info->max_bw_5g = ext_chan_list_event_hdr->max_bw_5g; 16505 reg_info->min_bw_6g_ap[REG_STANDARD_POWER_AP] = 16506 ext_chan_list_event_hdr->min_bw_6g_ap_sp; 16507 reg_info->max_bw_6g_ap[REG_STANDARD_POWER_AP] = 16508 ext_chan_list_event_hdr->max_bw_6g_ap_sp; 16509 reg_info->min_bw_6g_ap[REG_INDOOR_AP] = 16510 ext_chan_list_event_hdr->min_bw_6g_ap_lpi; 16511 reg_info->max_bw_6g_ap[REG_INDOOR_AP] = 16512 ext_chan_list_event_hdr->max_bw_6g_ap_lpi; 16513 reg_info->min_bw_6g_ap[REG_VERY_LOW_POWER_AP] = 16514 ext_chan_list_event_hdr->min_bw_6g_ap_vlp; 16515 reg_info->max_bw_6g_ap[REG_VERY_LOW_POWER_AP] = 16516 ext_chan_list_event_hdr->max_bw_6g_ap_vlp; 16517 16518 for (i = 0; i < REG_MAX_CLIENT_TYPE; i++) { 16519 reg_info->min_bw_6g_client[REG_STANDARD_POWER_AP][i] = 16520 ext_chan_list_event_hdr->min_bw_6g_client_sp[i]; 16521 reg_info->max_bw_6g_client[REG_STANDARD_POWER_AP][i] = 16522 ext_chan_list_event_hdr->max_bw_6g_client_sp[i]; 16523 reg_info->min_bw_6g_client[REG_INDOOR_AP][i] = 16524 ext_chan_list_event_hdr->min_bw_6g_client_lpi[i]; 16525 reg_info->max_bw_6g_client[REG_INDOOR_AP][i] = 16526 ext_chan_list_event_hdr->max_bw_6g_client_lpi[i]; 16527 reg_info->min_bw_6g_client[REG_VERY_LOW_POWER_AP][i] = 16528 ext_chan_list_event_hdr->min_bw_6g_client_vlp[i]; 16529 reg_info->max_bw_6g_client[REG_VERY_LOW_POWER_AP][i] = 16530 ext_chan_list_event_hdr->max_bw_6g_client_vlp[i]; 16531 } 16532 16533 wmi_nofl_debug("num_phys = %u and phy_id = %u", 16534 reg_info->num_phy, reg_info->phy_id); 16535 16536 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", 16537 reg_info->alpha2, reg_info->dfs_region, reg_info->reg_dmn_pair, 16538 reg_info->min_bw_2g, reg_info->max_bw_2g, reg_info->min_bw_5g, 16539 reg_info->max_bw_5g); 16540 16541 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", 16542 reg_info->min_bw_6g_ap[REG_STANDARD_POWER_AP], 16543 reg_info->max_bw_6g_ap[REG_STANDARD_POWER_AP], 16544 reg_info->min_bw_6g_ap[REG_INDOOR_AP], 16545 reg_info->max_bw_6g_ap[REG_INDOOR_AP], 16546 reg_info->min_bw_6g_ap[REG_VERY_LOW_POWER_AP], 16547 reg_info->max_bw_6g_ap[REG_VERY_LOW_POWER_AP]); 16548 16549 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", 16550 reg_info->min_bw_6g_client[REG_STANDARD_POWER_AP][REG_DEFAULT_CLIENT], 16551 reg_info->max_bw_6g_client[REG_STANDARD_POWER_AP][REG_DEFAULT_CLIENT], 16552 reg_info->min_bw_6g_client[REG_INDOOR_AP][REG_DEFAULT_CLIENT], 16553 reg_info->max_bw_6g_client[REG_INDOOR_AP][REG_DEFAULT_CLIENT], 16554 reg_info->min_bw_6g_client[REG_VERY_LOW_POWER_AP][REG_DEFAULT_CLIENT], 16555 reg_info->max_bw_6g_client[REG_VERY_LOW_POWER_AP][REG_DEFAULT_CLIENT]); 16556 16557 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", 16558 reg_info->min_bw_6g_client[REG_STANDARD_POWER_AP][REG_SUBORDINATE_CLIENT], 16559 reg_info->max_bw_6g_client[REG_STANDARD_POWER_AP][REG_SUBORDINATE_CLIENT], 16560 reg_info->min_bw_6g_client[REG_INDOOR_AP][REG_SUBORDINATE_CLIENT], 16561 reg_info->max_bw_6g_client[REG_INDOOR_AP][REG_SUBORDINATE_CLIENT], 16562 reg_info->min_bw_6g_client[REG_VERY_LOW_POWER_AP][REG_SUBORDINATE_CLIENT], 16563 reg_info->max_bw_6g_client[REG_VERY_LOW_POWER_AP][REG_SUBORDINATE_CLIENT]); 16564 16565 wmi_nofl_debug("num_2g_reg_rules %d num_5g_reg_rules %d", 16566 num_2g_reg_rules, num_5g_reg_rules); 16567 16568 wmi_nofl_debug("num_6g_ap_sp_reg_rules %d num_6g_ap_lpi_reg_rules %d num_6g_ap_vlp_reg_rules %d", 16569 reg_info->num_6g_reg_rules_ap[REG_STANDARD_POWER_AP], 16570 reg_info->num_6g_reg_rules_ap[REG_INDOOR_AP], 16571 reg_info->num_6g_reg_rules_ap[REG_VERY_LOW_POWER_AP]); 16572 16573 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", 16574 reg_info->num_6g_reg_rules_client[REG_STANDARD_POWER_AP][REG_DEFAULT_CLIENT], 16575 reg_info->num_6g_reg_rules_client[REG_INDOOR_AP][REG_DEFAULT_CLIENT], 16576 reg_info->num_6g_reg_rules_client[REG_VERY_LOW_POWER_AP][REG_DEFAULT_CLIENT]); 16577 16578 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", 16579 reg_info->num_6g_reg_rules_client[REG_STANDARD_POWER_AP][REG_SUBORDINATE_CLIENT], 16580 reg_info->num_6g_reg_rules_client[REG_INDOOR_AP][REG_SUBORDINATE_CLIENT], 16581 reg_info->num_6g_reg_rules_client[REG_VERY_LOW_POWER_AP][REG_SUBORDINATE_CLIENT]); 16582 16583 ext_wmi_reg_rule = 16584 (wmi_regulatory_rule_ext_struct *) 16585 ((uint8_t *)ext_chan_list_event_hdr + 16586 sizeof(wmi_reg_chan_list_cc_event_ext_fixed_param) + 16587 WMI_TLV_HDR_SIZE); 16588 reg_info->reg_rules_2g_ptr = 16589 create_ext_reg_rules_from_wmi(num_2g_reg_rules, 16590 ext_wmi_reg_rule); 16591 ext_wmi_reg_rule += num_2g_reg_rules; 16592 if (!num_2g_reg_rules) 16593 wmi_nofl_debug("No 2ghz reg rule"); 16594 for (i = 0; i < num_2g_reg_rules; i++) { 16595 if (!reg_info->reg_rules_2g_ptr) 16596 break; 16597 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", 16598 i, reg_info->reg_rules_2g_ptr[i].start_freq, 16599 reg_info->reg_rules_2g_ptr[i].end_freq, 16600 reg_info->reg_rules_2g_ptr[i].max_bw, 16601 reg_info->reg_rules_2g_ptr[i].reg_power, 16602 reg_info->reg_rules_2g_ptr[i].ant_gain, 16603 reg_info->reg_rules_2g_ptr[i].flags, 16604 reg_info->reg_rules_2g_ptr[i].psd_flag, 16605 reg_info->reg_rules_2g_ptr[i].psd_eirp); 16606 } 16607 reg_info->reg_rules_5g_ptr = 16608 create_ext_reg_rules_from_wmi(num_5g_reg_rules, 16609 ext_wmi_reg_rule); 16610 ext_wmi_reg_rule += num_5g_reg_rules; 16611 if (!num_5g_reg_rules) 16612 wmi_nofl_debug("No 5ghz reg rule"); 16613 for (i = 0; i < num_5g_reg_rules; i++) { 16614 if (!reg_info->reg_rules_5g_ptr) 16615 break; 16616 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", 16617 i, reg_info->reg_rules_5g_ptr[i].start_freq, 16618 reg_info->reg_rules_5g_ptr[i].end_freq, 16619 reg_info->reg_rules_5g_ptr[i].max_bw, 16620 reg_info->reg_rules_5g_ptr[i].reg_power, 16621 reg_info->reg_rules_5g_ptr[i].ant_gain, 16622 reg_info->reg_rules_5g_ptr[i].flags, 16623 reg_info->reg_rules_5g_ptr[i].psd_flag, 16624 reg_info->reg_rules_5g_ptr[i].psd_eirp); 16625 } 16626 16627 for (i = 0; i < REG_CURRENT_MAX_AP_TYPE; i++) { 16628 reg_print_ap_power_type_6ghz(i); 16629 reg_info->reg_rules_6g_ap_ptr[i] = 16630 create_ext_reg_rules_from_wmi(num_6g_reg_rules_ap[i], 16631 ext_wmi_reg_rule); 16632 16633 ext_wmi_reg_rule += num_6g_reg_rules_ap[i]; 16634 if (!num_6g_reg_rules_ap[i]) 16635 wmi_nofl_debug("No 6ghz reg rule"); 16636 for (j = 0; j < num_6g_reg_rules_ap[i]; j++) { 16637 if (!reg_info->reg_rules_6g_ap_ptr[i]) 16638 break; 16639 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", 16640 j, reg_info->reg_rules_6g_ap_ptr[i][j].start_freq, 16641 reg_info->reg_rules_6g_ap_ptr[i][j].end_freq, 16642 reg_info->reg_rules_6g_ap_ptr[i][j].max_bw, 16643 reg_info->reg_rules_6g_ap_ptr[i][j].reg_power, 16644 reg_info->reg_rules_6g_ap_ptr[i][j].ant_gain, 16645 reg_info->reg_rules_6g_ap_ptr[i][j].flags, 16646 reg_info->reg_rules_6g_ap_ptr[i][j].psd_flag, 16647 reg_info->reg_rules_6g_ap_ptr[i][j].psd_eirp); 16648 } 16649 } 16650 16651 for (j = 0; j < REG_CURRENT_MAX_AP_TYPE; j++) { 16652 reg_print_ap_power_type_6ghz(j); 16653 for (i = 0; i < REG_MAX_CLIENT_TYPE; i++) { 16654 reg_print_6ghz_client_type(i); 16655 reg_info->reg_rules_6g_client_ptr[j][i] = 16656 create_ext_reg_rules_from_wmi( 16657 num_6g_reg_rules_client[j][i], 16658 ext_wmi_reg_rule); 16659 16660 ext_wmi_reg_rule += num_6g_reg_rules_client[j][i]; 16661 if (!num_6g_reg_rules_client[j][i]) 16662 wmi_nofl_debug("No 6ghz reg rule for [%d][%d]", j, i); 16663 for (k = 0; k < num_6g_reg_rules_client[j][i]; k++) { 16664 if (!reg_info->reg_rules_6g_client_ptr[j][i]) 16665 break; 16666 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", 16667 k, reg_info->reg_rules_6g_client_ptr[j][i][k].start_freq, 16668 reg_info->reg_rules_6g_client_ptr[j][i][k].end_freq, 16669 reg_info->reg_rules_6g_client_ptr[j][i][k].max_bw, 16670 reg_info->reg_rules_6g_client_ptr[j][i][k].reg_power, 16671 reg_info->reg_rules_6g_client_ptr[j][i][k].ant_gain, 16672 reg_info->reg_rules_6g_client_ptr[j][i][k].flags, 16673 reg_info->reg_rules_6g_client_ptr[j][i][k].psd_flag, 16674 reg_info->reg_rules_6g_client_ptr[j][i][k].psd_eirp); 16675 } 16676 } 16677 } 16678 16679 reg_info->client_type = ext_chan_list_event_hdr->client_type; 16680 reg_info->rnr_tpe_usable = ext_chan_list_event_hdr->rnr_tpe_usable; 16681 reg_info->unspecified_ap_usable = 16682 ext_chan_list_event_hdr->unspecified_ap_usable; 16683 reg_info->domain_code_6g_ap[REG_STANDARD_POWER_AP] = 16684 ext_chan_list_event_hdr->domain_code_6g_ap_sp; 16685 reg_info->domain_code_6g_ap[REG_INDOOR_AP] = 16686 ext_chan_list_event_hdr->domain_code_6g_ap_lpi; 16687 reg_info->domain_code_6g_ap[REG_VERY_LOW_POWER_AP] = 16688 ext_chan_list_event_hdr->domain_code_6g_ap_vlp; 16689 16690 wmi_nofl_debug("client type %d, RNR TPE usable %d, unspecified AP usable %d, domain code AP SP %d, LPI %d, VLP %d", 16691 reg_info->client_type, reg_info->rnr_tpe_usable, 16692 reg_info->unspecified_ap_usable, 16693 reg_info->domain_code_6g_ap[REG_STANDARD_POWER_AP], 16694 reg_info->domain_code_6g_ap[REG_INDOOR_AP], 16695 reg_info->domain_code_6g_ap[REG_VERY_LOW_POWER_AP]); 16696 16697 for (i = 0; i < REG_MAX_CLIENT_TYPE; i++) { 16698 reg_info->domain_code_6g_client[REG_STANDARD_POWER_AP][i] = 16699 ext_chan_list_event_hdr->domain_code_6g_client_sp[i]; 16700 reg_info->domain_code_6g_client[REG_INDOOR_AP][i] = 16701 ext_chan_list_event_hdr->domain_code_6g_client_lpi[i]; 16702 reg_info->domain_code_6g_client[REG_VERY_LOW_POWER_AP][i] = 16703 ext_chan_list_event_hdr->domain_code_6g_client_vlp[i]; 16704 wmi_nofl_debug("domain code client %d SP %d, LPI %d, VLP %d", i, 16705 reg_info->domain_code_6g_client[REG_STANDARD_POWER_AP][i], 16706 reg_info->domain_code_6g_client[REG_INDOOR_AP][i], 16707 reg_info->domain_code_6g_client[REG_VERY_LOW_POWER_AP][i]); 16708 } 16709 16710 reg_info->domain_code_6g_super_id = 16711 ext_chan_list_event_hdr->domain_code_6g_super_id; 16712 16713 status = extract_reg_fcc_rules_tlv(param_buf, ext_chan_list_event_hdr, 16714 ext_wmi_reg_rule, ext_wmi_chan_priority, 16715 evt_buf, reg_info, len); 16716 if (status != QDF_STATUS_SUCCESS) 16717 return status; 16718 16719 return QDF_STATUS_SUCCESS; 16720 } 16721 16722 #ifdef CONFIG_AFC_SUPPORT 16723 /** 16724 * copy_afc_chan_eirp_info() - Copy the channel EIRP object from 16725 * chan_eirp_power_info_hdr to the internal buffer chan_eirp_info. Since the 16726 * cfi and eirp is continuously filled in chan_eirp_power_info_hdr, there is 16727 * an index pointer required to store the current index of 16728 * chan_eirp_power_info_hdr, to fill into the chan_eirp_info object. 16729 * @chan_eirp_info: pointer to chan_eirp_info 16730 * @num_chans: Number of channels 16731 * @chan_eirp_power_info_hdr: Pointer to chan_eirp_power_info_hdr 16732 * @index: Pointer to index 16733 * 16734 * Return: void 16735 */ 16736 static void 16737 copy_afc_chan_eirp_info(struct chan_eirp_obj *chan_eirp_info, 16738 uint8_t num_chans, 16739 wmi_afc_chan_eirp_power_info *chan_eirp_power_info_hdr, 16740 uint8_t *index) 16741 { 16742 uint8_t chan_idx; 16743 16744 for (chan_idx = 0; chan_idx < num_chans; chan_idx++, (*index)++) { 16745 chan_eirp_info[chan_idx].cfi = 16746 chan_eirp_power_info_hdr[*index].channel_cfi; 16747 chan_eirp_info[chan_idx].eirp_power = 16748 chan_eirp_power_info_hdr[*index].eirp_pwr; 16749 wmi_debug("Chan idx = %d chan freq idx = %d EIRP power = %d", 16750 chan_idx, 16751 chan_eirp_info[chan_idx].cfi, 16752 chan_eirp_info[chan_idx].eirp_power); 16753 } 16754 } 16755 16756 /** 16757 * copy_afc_chan_obj_info() - Copy the channel object from channel_info_hdr to 16758 * to the internal buffer afc_chan_info. 16759 * @afc_chan_info: pointer to afc_chan_info 16760 * @num_chan_objs: Number of channel objects 16761 * @channel_info_hdr: Pointer to channel_info_hdr 16762 * @chan_eirp_power_info_hdr: Pointer to chan_eirp_power_info_hdr 16763 * 16764 * Return: void 16765 */ 16766 static void 16767 copy_afc_chan_obj_info(struct afc_chan_obj *afc_chan_info, 16768 uint8_t num_chan_objs, 16769 wmi_6g_afc_channel_info *channel_info_hdr, 16770 wmi_afc_chan_eirp_power_info *chan_eirp_power_info_hdr) 16771 { 16772 uint8_t count; 16773 uint8_t src_pwr_index = 0; 16774 16775 for (count = 0; count < num_chan_objs; count++) { 16776 afc_chan_info[count].global_opclass = 16777 channel_info_hdr[count].global_operating_class; 16778 afc_chan_info[count].num_chans = 16779 channel_info_hdr[count].num_channels; 16780 wmi_debug("Chan object count = %d global opclasss = %d", 16781 count, 16782 afc_chan_info[count].global_opclass); 16783 wmi_debug("Number of Channel EIRP objects = %d", 16784 afc_chan_info[count].num_chans); 16785 16786 if (afc_chan_info[count].num_chans > 0) { 16787 struct chan_eirp_obj *chan_eirp_info; 16788 16789 chan_eirp_info = 16790 qdf_mem_malloc(afc_chan_info[count].num_chans * 16791 sizeof(*chan_eirp_info)); 16792 16793 if (!chan_eirp_info) 16794 return; 16795 16796 copy_afc_chan_eirp_info(chan_eirp_info, 16797 afc_chan_info[count].num_chans, 16798 chan_eirp_power_info_hdr, 16799 &src_pwr_index); 16800 afc_chan_info[count].chan_eirp_info = chan_eirp_info; 16801 } else { 16802 wmi_err("Number of channels is zero in object idx %d", 16803 count); 16804 } 16805 } 16806 } 16807 16808 static void copy_afc_freq_obj_info(struct afc_freq_obj *afc_freq_info, 16809 uint8_t num_freq_objs, 16810 wmi_6g_afc_frequency_info *freq_info_hdr) 16811 { 16812 uint8_t count; 16813 16814 for (count = 0; count < num_freq_objs; count++) { 16815 afc_freq_info[count].low_freq = 16816 WMI_REG_RULE_START_FREQ_GET(freq_info_hdr[count].freq_info); 16817 afc_freq_info[count].high_freq = 16818 WMI_REG_RULE_END_FREQ_GET(freq_info_hdr[count].freq_info); 16819 afc_freq_info[count].max_psd = 16820 freq_info_hdr[count].psd_power_info; 16821 wmi_debug("count = %d low_freq = %d high_freq = %d max_psd = %d", 16822 count, 16823 afc_freq_info[count].low_freq, 16824 afc_freq_info[count].high_freq, 16825 afc_freq_info[count].max_psd); 16826 } 16827 } 16828 16829 /** 16830 * copy_afc_event_fixed_hdr_power_info() - Copy the fixed header portion of 16831 * the power event info from the WMI AFC event buffer to the internal buffer 16832 * power_info. 16833 * @power_info: pointer to power_info 16834 * @afc_power_event_hdr: pointer to afc_power_event_hdr 16835 * 16836 * Return: void 16837 */ 16838 static void 16839 copy_afc_event_fixed_hdr_power_info( 16840 struct reg_fw_afc_power_event *power_info, 16841 wmi_afc_power_event_param *afc_power_event_hdr) 16842 { 16843 power_info->fw_status_code = afc_power_event_hdr->fw_status_code; 16844 power_info->resp_id = afc_power_event_hdr->resp_id; 16845 power_info->serv_resp_code = afc_power_event_hdr->afc_serv_resp_code; 16846 power_info->afc_wfa_version = 16847 WMI_AFC_WFA_MINOR_VERSION_GET(afc_power_event_hdr->afc_wfa_version); 16848 power_info->afc_wfa_version |= 16849 WMI_AFC_WFA_MAJOR_VERSION_GET(afc_power_event_hdr->afc_wfa_version); 16850 16851 power_info->avail_exp_time_d = 16852 WMI_AVAIL_EXPIRY_TIME_DAY_GET(afc_power_event_hdr->avail_exp_time_d); 16853 power_info->avail_exp_time_d |= 16854 WMI_AVAIL_EXPIRY_TIME_MONTH_GET(afc_power_event_hdr->avail_exp_time_d); 16855 power_info->avail_exp_time_d |= 16856 WMI_AVAIL_EXPIRY_TIME_YEAR_GET(afc_power_event_hdr->avail_exp_time_d); 16857 16858 power_info->avail_exp_time_t = 16859 WMI_AVAIL_EXPIRY_TIME_SEC_GET(afc_power_event_hdr->avail_exp_time_t); 16860 power_info->avail_exp_time_t |= 16861 WMI_AVAIL_EXPIRY_TIME_MINUTE_GET(afc_power_event_hdr->avail_exp_time_t); 16862 power_info->avail_exp_time_t |= 16863 WMI_AVAIL_EXPIRY_TIME_HOUR_GET(afc_power_event_hdr->avail_exp_time_t); 16864 wmi_debug("FW status = %d resp_id = %d serv_resp_code = %d", 16865 power_info->fw_status_code, 16866 power_info->resp_id, 16867 power_info->serv_resp_code); 16868 wmi_debug("AFC version = %u exp_date = %u exp_time = %u", 16869 power_info->afc_wfa_version, 16870 power_info->avail_exp_time_d, 16871 power_info->avail_exp_time_t); 16872 } 16873 16874 /** 16875 * copy_power_event() - Copy the power event parameters from the AFC event 16876 * buffer to the power_info within the afc_info. 16877 * @afc_info: pointer to afc_info 16878 * @param_buf: pointer to param_buf 16879 * 16880 * Return: void 16881 */ 16882 static void copy_power_event(struct afc_regulatory_info *afc_info, 16883 WMI_AFC_EVENTID_param_tlvs *param_buf) 16884 { 16885 struct reg_fw_afc_power_event *power_info; 16886 wmi_afc_power_event_param *afc_power_event_hdr; 16887 struct afc_freq_obj *afc_freq_info; 16888 16889 power_info = qdf_mem_malloc(sizeof(*power_info)); 16890 16891 if (!power_info) 16892 return; 16893 16894 afc_power_event_hdr = param_buf->afc_power_event_param; 16895 copy_afc_event_fixed_hdr_power_info(power_info, afc_power_event_hdr); 16896 afc_info->power_info = power_info; 16897 16898 power_info->num_freq_objs = param_buf->num_freq_info_array; 16899 wmi_debug("Number of frequency objects = %d", 16900 power_info->num_freq_objs); 16901 if (power_info->num_freq_objs > 0) { 16902 wmi_6g_afc_frequency_info *freq_info_hdr; 16903 16904 freq_info_hdr = param_buf->freq_info_array; 16905 afc_freq_info = qdf_mem_malloc(power_info->num_freq_objs * 16906 sizeof(*afc_freq_info)); 16907 16908 if (!afc_freq_info) 16909 return; 16910 16911 copy_afc_freq_obj_info(afc_freq_info, power_info->num_freq_objs, 16912 freq_info_hdr); 16913 power_info->afc_freq_info = afc_freq_info; 16914 } else { 16915 wmi_err("Number of frequency objects is zero"); 16916 } 16917 16918 power_info->num_chan_objs = param_buf->num_channel_info_array; 16919 wmi_debug("Number of channel objects = %d", power_info->num_chan_objs); 16920 if (power_info->num_chan_objs > 0) { 16921 struct afc_chan_obj *afc_chan_info; 16922 wmi_6g_afc_channel_info *channel_info_hdr; 16923 16924 channel_info_hdr = param_buf->channel_info_array; 16925 afc_chan_info = qdf_mem_malloc(power_info->num_chan_objs * 16926 sizeof(*afc_chan_info)); 16927 16928 if (!afc_chan_info) 16929 return; 16930 16931 copy_afc_chan_obj_info(afc_chan_info, 16932 power_info->num_chan_objs, 16933 channel_info_hdr, 16934 param_buf->chan_eirp_power_info_array); 16935 power_info->afc_chan_info = afc_chan_info; 16936 } else { 16937 wmi_err("Number of channel objects is zero"); 16938 } 16939 } 16940 16941 static void copy_expiry_event(struct afc_regulatory_info *afc_info, 16942 WMI_AFC_EVENTID_param_tlvs *param_buf) 16943 { 16944 struct reg_afc_expiry_event *expiry_info; 16945 16946 expiry_info = qdf_mem_malloc(sizeof(*expiry_info)); 16947 16948 if (!expiry_info) 16949 return; 16950 16951 expiry_info->request_id = 16952 param_buf->expiry_event_param->request_id; 16953 expiry_info->event_subtype = 16954 param_buf->expiry_event_param->event_subtype; 16955 wmi_debug("Event subtype %d request ID %d", 16956 expiry_info->event_subtype, 16957 expiry_info->request_id); 16958 afc_info->expiry_info = expiry_info; 16959 } 16960 16961 /** 16962 * copy_afc_event_common_info() - Copy the phy_id and event_type parameters 16963 * in the AFC event. 'Common' indicates that these parameters are common for 16964 * WMI_AFC_EVENT_POWER_INFO and WMI_AFC_EVENT_TIMER_EXPIRY. 16965 * @wmi_handle: wmi handle 16966 * @afc_info: pointer to afc_info 16967 * @event_fixed_hdr: pointer to event_fixed_hdr 16968 * 16969 * Return: void 16970 */ 16971 static void 16972 copy_afc_event_common_info(wmi_unified_t wmi_handle, 16973 struct afc_regulatory_info *afc_info, 16974 wmi_afc_event_fixed_param *event_fixed_hdr) 16975 { 16976 afc_info->phy_id = wmi_handle->ops->convert_phy_id_target_to_host( 16977 wmi_handle, event_fixed_hdr->phy_id); 16978 wmi_debug("phy_id %d", afc_info->phy_id); 16979 afc_info->event_type = event_fixed_hdr->event_type; 16980 } 16981 16982 static QDF_STATUS extract_afc_event_tlv(wmi_unified_t wmi_handle, 16983 uint8_t *evt_buf, 16984 struct afc_regulatory_info *afc_info, 16985 uint32_t len) 16986 { 16987 WMI_AFC_EVENTID_param_tlvs *param_buf; 16988 wmi_afc_event_fixed_param *event_fixed_hdr; 16989 16990 param_buf = (WMI_AFC_EVENTID_param_tlvs *)evt_buf; 16991 if (!param_buf) { 16992 wmi_err("Invalid AFC event buf"); 16993 return QDF_STATUS_E_FAILURE; 16994 } 16995 16996 event_fixed_hdr = param_buf->fixed_param; 16997 copy_afc_event_common_info(wmi_handle, afc_info, event_fixed_hdr); 16998 wmi_debug("AFC event type %d received", afc_info->event_type); 16999 17000 switch (afc_info->event_type) { 17001 case WMI_AFC_EVENT_POWER_INFO: 17002 copy_power_event(afc_info, param_buf); 17003 break; 17004 case WMI_AFC_EVENT_TIMER_EXPIRY: 17005 copy_expiry_event(afc_info, param_buf); 17006 return QDF_STATUS_SUCCESS; 17007 default: 17008 wmi_err("Invalid event type"); 17009 return QDF_STATUS_E_FAILURE; 17010 } 17011 17012 return QDF_STATUS_SUCCESS; 17013 } 17014 #endif 17015 #endif 17016 17017 static QDF_STATUS extract_reg_chan_list_update_event_tlv( 17018 wmi_unified_t wmi_handle, uint8_t *evt_buf, 17019 struct cur_regulatory_info *reg_info, uint32_t len) 17020 { 17021 uint32_t i; 17022 WMI_REG_CHAN_LIST_CC_EVENTID_param_tlvs *param_buf; 17023 wmi_reg_chan_list_cc_event_fixed_param *chan_list_event_hdr; 17024 wmi_regulatory_rule_struct *wmi_reg_rule; 17025 uint32_t num_2g_reg_rules, num_5g_reg_rules; 17026 17027 wmi_debug("processing regulatory channel list"); 17028 17029 param_buf = (WMI_REG_CHAN_LIST_CC_EVENTID_param_tlvs *)evt_buf; 17030 if (!param_buf) { 17031 wmi_err("invalid channel list event buf"); 17032 return QDF_STATUS_E_FAILURE; 17033 } 17034 17035 chan_list_event_hdr = param_buf->fixed_param; 17036 17037 reg_info->num_2g_reg_rules = chan_list_event_hdr->num_2g_reg_rules; 17038 reg_info->num_5g_reg_rules = chan_list_event_hdr->num_5g_reg_rules; 17039 num_2g_reg_rules = reg_info->num_2g_reg_rules; 17040 num_5g_reg_rules = reg_info->num_5g_reg_rules; 17041 if ((num_2g_reg_rules > MAX_REG_RULES) || 17042 (num_5g_reg_rules > MAX_REG_RULES) || 17043 (num_2g_reg_rules + num_5g_reg_rules > MAX_REG_RULES) || 17044 (num_2g_reg_rules + num_5g_reg_rules != 17045 param_buf->num_reg_rule_array)) { 17046 wmi_err_rl("Invalid num_2g_reg_rules: %u, num_5g_reg_rules: %u", 17047 num_2g_reg_rules, num_5g_reg_rules); 17048 return QDF_STATUS_E_FAILURE; 17049 } 17050 if (param_buf->num_reg_rule_array > 17051 (WMI_SVC_MSG_MAX_SIZE - sizeof(*chan_list_event_hdr)) / 17052 sizeof(*wmi_reg_rule)) { 17053 wmi_err_rl("Invalid num_reg_rule_array: %u", 17054 param_buf->num_reg_rule_array); 17055 return QDF_STATUS_E_FAILURE; 17056 } 17057 17058 qdf_mem_copy(reg_info->alpha2, &(chan_list_event_hdr->alpha2), 17059 REG_ALPHA2_LEN); 17060 reg_info->dfs_region = chan_list_event_hdr->dfs_region; 17061 reg_info->phybitmap = convert_phybitmap_tlv( 17062 chan_list_event_hdr->phybitmap); 17063 reg_info->offload_enabled = true; 17064 reg_info->num_phy = chan_list_event_hdr->num_phy; 17065 reg_info->phy_id = wmi_handle->ops->convert_phy_id_target_to_host( 17066 wmi_handle, chan_list_event_hdr->phy_id); 17067 reg_info->ctry_code = chan_list_event_hdr->country_id; 17068 reg_info->reg_dmn_pair = chan_list_event_hdr->domain_code; 17069 17070 reg_info->status_code = 17071 wmi_reg_status_to_reg_status(chan_list_event_hdr->status_code); 17072 17073 reg_info->min_bw_2g = chan_list_event_hdr->min_bw_2g; 17074 reg_info->max_bw_2g = chan_list_event_hdr->max_bw_2g; 17075 reg_info->min_bw_5g = chan_list_event_hdr->min_bw_5g; 17076 reg_info->max_bw_5g = chan_list_event_hdr->max_bw_5g; 17077 17078 wmi_debug("num_phys = %u and phy_id = %u", 17079 reg_info->num_phy, reg_info->phy_id); 17080 17081 wmi_debug("cc %s dfs_region %d reg_dmn_pair %x BW: min_2g %d max_2g %d min_5g %d max_5g %d", 17082 reg_info->alpha2, reg_info->dfs_region, reg_info->reg_dmn_pair, 17083 reg_info->min_bw_2g, reg_info->max_bw_2g, 17084 reg_info->min_bw_5g, reg_info->max_bw_5g); 17085 17086 wmi_debug("num_2g_reg_rules %d num_5g_reg_rules %d", 17087 num_2g_reg_rules, num_5g_reg_rules); 17088 wmi_reg_rule = 17089 (wmi_regulatory_rule_struct *)((uint8_t *)chan_list_event_hdr 17090 + sizeof(wmi_reg_chan_list_cc_event_fixed_param) 17091 + WMI_TLV_HDR_SIZE); 17092 reg_info->reg_rules_2g_ptr = create_reg_rules_from_wmi(num_2g_reg_rules, 17093 wmi_reg_rule); 17094 wmi_reg_rule += num_2g_reg_rules; 17095 if (!num_2g_reg_rules) 17096 wmi_nofl_debug("No 2ghz reg rule"); 17097 for (i = 0; i < num_2g_reg_rules; i++) { 17098 if (!reg_info->reg_rules_2g_ptr) 17099 break; 17100 wmi_nofl_debug("2 GHz rule %u start freq %u end freq %u max_bw %u reg_power %u ant_gain %u flags %u", 17101 i, reg_info->reg_rules_2g_ptr[i].start_freq, 17102 reg_info->reg_rules_2g_ptr[i].end_freq, 17103 reg_info->reg_rules_2g_ptr[i].max_bw, 17104 reg_info->reg_rules_2g_ptr[i].reg_power, 17105 reg_info->reg_rules_2g_ptr[i].ant_gain, 17106 reg_info->reg_rules_2g_ptr[i].flags); 17107 } 17108 17109 reg_info->reg_rules_5g_ptr = create_reg_rules_from_wmi(num_5g_reg_rules, 17110 wmi_reg_rule); 17111 if (!num_5g_reg_rules) 17112 wmi_nofl_debug("No 5ghz reg rule"); 17113 for (i = 0; i < num_5g_reg_rules; i++) { 17114 if (!reg_info->reg_rules_5g_ptr) 17115 break; 17116 wmi_nofl_debug("5 GHz rule %u start freq %u end freq %u max_bw %u reg_power %u ant_gain %u flags %u", 17117 i, reg_info->reg_rules_5g_ptr[i].start_freq, 17118 reg_info->reg_rules_5g_ptr[i].end_freq, 17119 reg_info->reg_rules_5g_ptr[i].max_bw, 17120 reg_info->reg_rules_5g_ptr[i].reg_power, 17121 reg_info->reg_rules_5g_ptr[i].ant_gain, 17122 reg_info->reg_rules_5g_ptr[i].flags); 17123 } 17124 17125 wmi_debug("processed regulatory channel list"); 17126 17127 return QDF_STATUS_SUCCESS; 17128 } 17129 17130 static QDF_STATUS extract_reg_11d_new_country_event_tlv( 17131 wmi_unified_t wmi_handle, uint8_t *evt_buf, 17132 struct reg_11d_new_country *reg_11d_country, uint32_t len) 17133 { 17134 wmi_11d_new_country_event_fixed_param *reg_11d_country_event; 17135 WMI_11D_NEW_COUNTRY_EVENTID_param_tlvs *param_buf; 17136 17137 param_buf = (WMI_11D_NEW_COUNTRY_EVENTID_param_tlvs *)evt_buf; 17138 if (!param_buf) { 17139 wmi_err("invalid 11d country event buf"); 17140 return QDF_STATUS_E_FAILURE; 17141 } 17142 17143 reg_11d_country_event = param_buf->fixed_param; 17144 17145 qdf_mem_copy(reg_11d_country->alpha2, 17146 ®_11d_country_event->new_alpha2, REG_ALPHA2_LEN); 17147 reg_11d_country->alpha2[REG_ALPHA2_LEN] = '\0'; 17148 17149 wmi_debug("processed 11d country event, new cc %s", 17150 reg_11d_country->alpha2); 17151 17152 return QDF_STATUS_SUCCESS; 17153 } 17154 17155 static QDF_STATUS extract_reg_ch_avoid_event_tlv( 17156 wmi_unified_t wmi_handle, uint8_t *evt_buf, 17157 struct ch_avoid_ind_type *ch_avoid_ind, uint32_t len) 17158 { 17159 wmi_avoid_freq_ranges_event_fixed_param *afr_fixed_param; 17160 wmi_avoid_freq_range_desc *afr_desc; 17161 uint32_t num_freq_ranges, freq_range_idx; 17162 WMI_WLAN_FREQ_AVOID_EVENTID_param_tlvs *param_buf = 17163 (WMI_WLAN_FREQ_AVOID_EVENTID_param_tlvs *) evt_buf; 17164 17165 if (!param_buf) { 17166 wmi_err("Invalid channel avoid event buffer"); 17167 return QDF_STATUS_E_INVAL; 17168 } 17169 17170 afr_fixed_param = param_buf->fixed_param; 17171 if (!afr_fixed_param) { 17172 wmi_err("Invalid channel avoid event fixed param buffer"); 17173 return QDF_STATUS_E_INVAL; 17174 } 17175 17176 if (!ch_avoid_ind) { 17177 wmi_err("Invalid channel avoid indication buffer"); 17178 return QDF_STATUS_E_INVAL; 17179 } 17180 if (param_buf->num_avd_freq_range < afr_fixed_param->num_freq_ranges) { 17181 wmi_err("no.of freq ranges exceeded the limit"); 17182 return QDF_STATUS_E_INVAL; 17183 } 17184 num_freq_ranges = (afr_fixed_param->num_freq_ranges > 17185 CH_AVOID_MAX_RANGE) ? CH_AVOID_MAX_RANGE : 17186 afr_fixed_param->num_freq_ranges; 17187 17188 wmi_debug("Channel avoid event received with %d ranges", 17189 num_freq_ranges); 17190 17191 ch_avoid_ind->ch_avoid_range_cnt = num_freq_ranges; 17192 afr_desc = (wmi_avoid_freq_range_desc *)(param_buf->avd_freq_range); 17193 for (freq_range_idx = 0; freq_range_idx < num_freq_ranges; 17194 freq_range_idx++) { 17195 ch_avoid_ind->avoid_freq_range[freq_range_idx].start_freq = 17196 afr_desc->start_freq; 17197 ch_avoid_ind->avoid_freq_range[freq_range_idx].end_freq = 17198 afr_desc->end_freq; 17199 wmi_debug("range %d tlv id %u, start freq %u, end freq %u", 17200 freq_range_idx, afr_desc->tlv_header, 17201 afr_desc->start_freq, afr_desc->end_freq); 17202 afr_desc++; 17203 } 17204 17205 return QDF_STATUS_SUCCESS; 17206 } 17207 17208 #ifdef DFS_COMPONENT_ENABLE 17209 /** 17210 * extract_dfs_cac_complete_event_tlv() - extract cac complete event 17211 * @wmi_handle: wma handle 17212 * @evt_buf: event buffer 17213 * @vdev_id: vdev id 17214 * @len: length of buffer 17215 * 17216 * Return: QDF_STATUS_SUCCESS for success or error code 17217 */ 17218 static QDF_STATUS extract_dfs_cac_complete_event_tlv(wmi_unified_t wmi_handle, 17219 uint8_t *evt_buf, 17220 uint32_t *vdev_id, 17221 uint32_t len) 17222 { 17223 WMI_VDEV_DFS_CAC_COMPLETE_EVENTID_param_tlvs *param_tlvs; 17224 wmi_vdev_dfs_cac_complete_event_fixed_param *cac_event; 17225 17226 param_tlvs = (WMI_VDEV_DFS_CAC_COMPLETE_EVENTID_param_tlvs *) evt_buf; 17227 if (!param_tlvs) { 17228 wmi_err("invalid cac complete event buf"); 17229 return QDF_STATUS_E_FAILURE; 17230 } 17231 17232 cac_event = param_tlvs->fixed_param; 17233 *vdev_id = cac_event->vdev_id; 17234 wmi_debug("processed cac complete event vdev %d", *vdev_id); 17235 17236 return QDF_STATUS_SUCCESS; 17237 } 17238 17239 /** 17240 * extract_dfs_ocac_complete_event_tlv() - extract cac complete event 17241 * @wmi_handle: wma handle 17242 * @evt_buf: event buffer 17243 * @param: extracted event 17244 * 17245 * Return: QDF_STATUS_SUCCESS for success or error code 17246 */ 17247 static QDF_STATUS 17248 extract_dfs_ocac_complete_event_tlv(wmi_unified_t wmi_handle, 17249 uint8_t *evt_buf, 17250 struct vdev_adfs_complete_status *param) 17251 { 17252 WMI_VDEV_ADFS_OCAC_COMPLETE_EVENTID_param_tlvs *param_tlvs; 17253 wmi_vdev_adfs_ocac_complete_event_fixed_param *ocac_complete_status; 17254 17255 param_tlvs = (WMI_VDEV_ADFS_OCAC_COMPLETE_EVENTID_param_tlvs *)evt_buf; 17256 if (!param_tlvs) { 17257 wmi_err("invalid ocac complete event buf"); 17258 return QDF_STATUS_E_FAILURE; 17259 } 17260 17261 if (!param_tlvs->fixed_param) { 17262 wmi_err("invalid param_tlvs->fixed_param"); 17263 return QDF_STATUS_E_FAILURE; 17264 } 17265 17266 ocac_complete_status = param_tlvs->fixed_param; 17267 param->vdev_id = ocac_complete_status->vdev_id; 17268 param->chan_freq = ocac_complete_status->chan_freq; 17269 param->center_freq1 = ocac_complete_status->center_freq1; 17270 param->center_freq2 = ocac_complete_status->center_freq2; 17271 param->ocac_status = ocac_complete_status->status; 17272 param->chan_width = ocac_complete_status->chan_width; 17273 wmi_debug("processed ocac complete event vdev %d" 17274 " agile chan %d %d width %d status %d", 17275 param->vdev_id, 17276 param->center_freq1, 17277 param->center_freq2, 17278 param->chan_width, 17279 param->ocac_status); 17280 17281 return QDF_STATUS_SUCCESS; 17282 } 17283 17284 /** 17285 * extract_dfs_radar_detection_event_tlv() - extract radar found event 17286 * @wmi_handle: wma handle 17287 * @evt_buf: event buffer 17288 * @radar_found: radar found event info 17289 * @len: length of buffer 17290 * 17291 * Return: QDF_STATUS_SUCCESS for success or error code 17292 */ 17293 static QDF_STATUS extract_dfs_radar_detection_event_tlv( 17294 wmi_unified_t wmi_handle, 17295 uint8_t *evt_buf, 17296 struct radar_found_info *radar_found, 17297 uint32_t len) 17298 { 17299 WMI_PDEV_DFS_RADAR_DETECTION_EVENTID_param_tlvs *param_tlv; 17300 wmi_pdev_dfs_radar_detection_event_fixed_param *radar_event; 17301 17302 param_tlv = (WMI_PDEV_DFS_RADAR_DETECTION_EVENTID_param_tlvs *) evt_buf; 17303 if (!param_tlv) { 17304 wmi_err("invalid radar detection event buf"); 17305 return QDF_STATUS_E_FAILURE; 17306 } 17307 17308 radar_event = param_tlv->fixed_param; 17309 17310 radar_found->pdev_id = convert_target_pdev_id_to_host_pdev_id( 17311 wmi_handle, 17312 radar_event->pdev_id); 17313 17314 if (radar_found->pdev_id == WMI_HOST_PDEV_ID_INVALID) 17315 return QDF_STATUS_E_FAILURE; 17316 17317 qdf_mem_zero(radar_found, sizeof(struct radar_found_info)); 17318 radar_found->detection_mode = radar_event->detection_mode; 17319 radar_found->chan_freq = radar_event->chan_freq; 17320 radar_found->chan_width = radar_event->chan_width; 17321 radar_found->detector_id = radar_event->detector_id; 17322 radar_found->segment_id = radar_event->segment_id; 17323 radar_found->timestamp = radar_event->timestamp; 17324 radar_found->is_chirp = radar_event->is_chirp; 17325 radar_found->freq_offset = radar_event->freq_offset; 17326 radar_found->sidx = radar_event->sidx; 17327 17328 if (is_service_enabled_tlv(wmi_handle, 17329 WMI_SERVICE_RADAR_FLAGS_SUPPORT)) { 17330 WMI_RADAR_FLAGS *radar_flags; 17331 17332 radar_flags = param_tlv->radar_flags; 17333 if (radar_flags) { 17334 radar_found->is_full_bw_nol = 17335 WMI_RADAR_FLAGS_FULL_BW_NOL_GET(radar_flags->flags); 17336 wmi_debug("Is full bw nol %d", 17337 radar_found->is_full_bw_nol); 17338 } 17339 } 17340 17341 wmi_debug("processed radar found event pdev %d," 17342 "Radar Event Info:pdev_id %d,timestamp %d,chan_freq (dur) %d," 17343 "chan_width (RSSI) %d,detector_id (false_radar) %d," 17344 "freq_offset (radar_check) %d,segment_id %d,sidx %d," 17345 "is_chirp %d,detection mode %d", 17346 radar_event->pdev_id, radar_found->pdev_id, 17347 radar_event->timestamp, radar_event->chan_freq, 17348 radar_event->chan_width, radar_event->detector_id, 17349 radar_event->freq_offset, radar_event->segment_id, 17350 radar_event->sidx, radar_event->is_chirp, 17351 radar_event->detection_mode); 17352 17353 return QDF_STATUS_SUCCESS; 17354 } 17355 17356 #ifdef MOBILE_DFS_SUPPORT 17357 /** 17358 * extract_wlan_radar_event_info_tlv() - extract radar pulse event 17359 * @wmi_handle: wma handle 17360 * @evt_buf: event buffer 17361 * @wlan_radar_event: Pointer to struct radar_event_info 17362 * @len: length of buffer 17363 * 17364 * Return: QDF_STATUS 17365 */ 17366 static QDF_STATUS extract_wlan_radar_event_info_tlv( 17367 wmi_unified_t wmi_handle, 17368 uint8_t *evt_buf, 17369 struct radar_event_info *wlan_radar_event, 17370 uint32_t len) 17371 { 17372 WMI_DFS_RADAR_EVENTID_param_tlvs *param_tlv; 17373 wmi_dfs_radar_event_fixed_param *radar_event; 17374 17375 param_tlv = (WMI_DFS_RADAR_EVENTID_param_tlvs *)evt_buf; 17376 if (!param_tlv) { 17377 wmi_err("invalid wlan radar event buf"); 17378 return QDF_STATUS_E_FAILURE; 17379 } 17380 17381 radar_event = param_tlv->fixed_param; 17382 wlan_radar_event->pulse_is_chirp = radar_event->pulse_is_chirp; 17383 wlan_radar_event->pulse_center_freq = radar_event->pulse_center_freq; 17384 wlan_radar_event->pulse_duration = radar_event->pulse_duration; 17385 wlan_radar_event->rssi = radar_event->rssi; 17386 wlan_radar_event->pulse_detect_ts = radar_event->pulse_detect_ts; 17387 wlan_radar_event->upload_fullts_high = radar_event->upload_fullts_high; 17388 wlan_radar_event->upload_fullts_low = radar_event->upload_fullts_low; 17389 wlan_radar_event->peak_sidx = radar_event->peak_sidx; 17390 wlan_radar_event->delta_peak = radar_event->pulse_delta_peak; 17391 wlan_radar_event->delta_diff = radar_event->pulse_delta_diff; 17392 if (radar_event->pulse_flags & 17393 WMI_DFS_RADAR_PULSE_FLAG_MASK_PSIDX_DIFF_VALID) { 17394 wlan_radar_event->is_psidx_diff_valid = true; 17395 wlan_radar_event->psidx_diff = radar_event->psidx_diff; 17396 } else { 17397 wlan_radar_event->is_psidx_diff_valid = false; 17398 } 17399 17400 wlan_radar_event->pdev_id = radar_event->pdev_id; 17401 17402 return QDF_STATUS_SUCCESS; 17403 } 17404 #else 17405 static QDF_STATUS extract_wlan_radar_event_info_tlv( 17406 wmi_unified_t wmi_handle, 17407 uint8_t *evt_buf, 17408 struct radar_event_info *wlan_radar_event, 17409 uint32_t len) 17410 { 17411 return QDF_STATUS_SUCCESS; 17412 } 17413 #endif 17414 #endif 17415 17416 /** 17417 * send_get_rcpi_cmd_tlv() - send request for rcpi value 17418 * @wmi_handle: wmi handle 17419 * @get_rcpi_param: rcpi params 17420 * 17421 * Return: QDF status 17422 */ 17423 static QDF_STATUS send_get_rcpi_cmd_tlv(wmi_unified_t wmi_handle, 17424 struct rcpi_req *get_rcpi_param) 17425 { 17426 wmi_buf_t buf; 17427 wmi_request_rcpi_cmd_fixed_param *cmd; 17428 uint8_t len = sizeof(wmi_request_rcpi_cmd_fixed_param); 17429 17430 buf = wmi_buf_alloc(wmi_handle, len); 17431 if (!buf) 17432 return QDF_STATUS_E_NOMEM; 17433 17434 cmd = (wmi_request_rcpi_cmd_fixed_param *) wmi_buf_data(buf); 17435 WMITLV_SET_HDR(&cmd->tlv_header, 17436 WMITLV_TAG_STRUC_wmi_request_rcpi_cmd_fixed_param, 17437 WMITLV_GET_STRUCT_TLVLEN 17438 (wmi_request_rcpi_cmd_fixed_param)); 17439 17440 cmd->vdev_id = get_rcpi_param->vdev_id; 17441 WMI_CHAR_ARRAY_TO_MAC_ADDR(get_rcpi_param->mac_addr, 17442 &cmd->peer_macaddr); 17443 17444 switch (get_rcpi_param->measurement_type) { 17445 17446 case RCPI_MEASUREMENT_TYPE_AVG_MGMT: 17447 cmd->measurement_type = WMI_RCPI_MEASUREMENT_TYPE_AVG_MGMT; 17448 break; 17449 17450 case RCPI_MEASUREMENT_TYPE_AVG_DATA: 17451 cmd->measurement_type = WMI_RCPI_MEASUREMENT_TYPE_AVG_DATA; 17452 break; 17453 17454 case RCPI_MEASUREMENT_TYPE_LAST_MGMT: 17455 cmd->measurement_type = WMI_RCPI_MEASUREMENT_TYPE_LAST_MGMT; 17456 break; 17457 17458 case RCPI_MEASUREMENT_TYPE_LAST_DATA: 17459 cmd->measurement_type = WMI_RCPI_MEASUREMENT_TYPE_LAST_DATA; 17460 break; 17461 17462 default: 17463 /* 17464 * invalid rcpi measurement type, fall back to 17465 * RCPI_MEASUREMENT_TYPE_AVG_MGMT 17466 */ 17467 cmd->measurement_type = WMI_RCPI_MEASUREMENT_TYPE_AVG_MGMT; 17468 break; 17469 } 17470 wmi_debug("RCPI REQ VDEV_ID:%d-->", cmd->vdev_id); 17471 wmi_mtrace(WMI_REQUEST_RCPI_CMDID, cmd->vdev_id, 0); 17472 if (wmi_unified_cmd_send(wmi_handle, buf, len, 17473 WMI_REQUEST_RCPI_CMDID)) { 17474 17475 wmi_err("Failed to send WMI_REQUEST_RCPI_CMDID"); 17476 wmi_buf_free(buf); 17477 return QDF_STATUS_E_FAILURE; 17478 } 17479 17480 return QDF_STATUS_SUCCESS; 17481 } 17482 17483 /** 17484 * extract_rcpi_response_event_tlv() - Extract RCPI event params 17485 * @wmi_handle: wmi handle 17486 * @evt_buf: pointer to event buffer 17487 * @res: pointer to hold rcpi response from firmware 17488 * 17489 * Return: QDF_STATUS_SUCCESS for successful event parse 17490 * else QDF_STATUS_E_INVAL or QDF_STATUS_E_FAILURE 17491 */ 17492 static QDF_STATUS 17493 extract_rcpi_response_event_tlv(wmi_unified_t wmi_handle, 17494 void *evt_buf, struct rcpi_res *res) 17495 { 17496 WMI_UPDATE_RCPI_EVENTID_param_tlvs *param_buf; 17497 wmi_update_rcpi_event_fixed_param *event; 17498 17499 param_buf = (WMI_UPDATE_RCPI_EVENTID_param_tlvs *)evt_buf; 17500 if (!param_buf) { 17501 wmi_err("Invalid rcpi event"); 17502 return QDF_STATUS_E_INVAL; 17503 } 17504 17505 event = param_buf->fixed_param; 17506 res->vdev_id = event->vdev_id; 17507 WMI_MAC_ADDR_TO_CHAR_ARRAY(&event->peer_macaddr, res->mac_addr); 17508 17509 switch (event->measurement_type) { 17510 17511 case WMI_RCPI_MEASUREMENT_TYPE_AVG_MGMT: 17512 res->measurement_type = RCPI_MEASUREMENT_TYPE_AVG_MGMT; 17513 break; 17514 17515 case WMI_RCPI_MEASUREMENT_TYPE_AVG_DATA: 17516 res->measurement_type = RCPI_MEASUREMENT_TYPE_AVG_DATA; 17517 break; 17518 17519 case WMI_RCPI_MEASUREMENT_TYPE_LAST_MGMT: 17520 res->measurement_type = RCPI_MEASUREMENT_TYPE_LAST_MGMT; 17521 break; 17522 17523 case WMI_RCPI_MEASUREMENT_TYPE_LAST_DATA: 17524 res->measurement_type = RCPI_MEASUREMENT_TYPE_LAST_DATA; 17525 break; 17526 17527 default: 17528 wmi_err("Invalid rcpi measurement type from firmware"); 17529 res->measurement_type = RCPI_MEASUREMENT_TYPE_INVALID; 17530 return QDF_STATUS_E_FAILURE; 17531 } 17532 17533 if (event->status) 17534 return QDF_STATUS_E_FAILURE; 17535 else 17536 return QDF_STATUS_SUCCESS; 17537 } 17538 17539 /** 17540 * convert_host_pdev_id_to_target_pdev_id_legacy() - Convert pdev_id from 17541 * host to target defines. For legacy there is not conversion 17542 * required. Just return pdev_id as it is. 17543 * @wmi_handle: handle to WMI. 17544 * @pdev_id: host pdev_id to be converted. 17545 * Return: target pdev_id after conversion. 17546 */ 17547 static uint32_t convert_host_pdev_id_to_target_pdev_id_legacy( 17548 wmi_unified_t wmi_handle, 17549 uint32_t pdev_id) 17550 { 17551 if (pdev_id == WMI_HOST_PDEV_ID_SOC) 17552 return WMI_PDEV_ID_SOC; 17553 17554 /*No conversion required*/ 17555 return pdev_id; 17556 } 17557 17558 /** 17559 * convert_target_pdev_id_to_host_pdev_id_legacy() - Convert pdev_id from 17560 * target to host defines. For legacy there is not conversion 17561 * required. Just return pdev_id as it is. 17562 * @wmi_handle: handle to WMI. 17563 * @pdev_id: target pdev_id to be converted. 17564 * Return: host pdev_id after conversion. 17565 */ 17566 static uint32_t convert_target_pdev_id_to_host_pdev_id_legacy( 17567 wmi_unified_t wmi_handle, 17568 uint32_t pdev_id) 17569 { 17570 /*No conversion required*/ 17571 return pdev_id; 17572 } 17573 17574 /** 17575 * convert_host_phy_id_to_target_phy_id_legacy() - Convert phy_id from 17576 * host to target defines. For legacy there is not conversion 17577 * required. Just return phy_id as it is. 17578 * @wmi_handle: handle to WMI. 17579 * @phy_id: host phy_id to be converted. 17580 * 17581 * Return: target phy_id after conversion. 17582 */ 17583 static uint32_t convert_host_phy_id_to_target_phy_id_legacy( 17584 wmi_unified_t wmi_handle, 17585 uint32_t phy_id) 17586 { 17587 /*No conversion required*/ 17588 return phy_id; 17589 } 17590 17591 /** 17592 * convert_target_phy_id_to_host_phy_id_legacy() - Convert phy_id from 17593 * target to host defines. For legacy there is not conversion 17594 * required. Just return phy_id as it is. 17595 * @wmi_handle: handle to WMI. 17596 * @phy_id: target phy_id to be converted. 17597 * 17598 * Return: host phy_id after conversion. 17599 */ 17600 static uint32_t convert_target_phy_id_to_host_phy_id_legacy( 17601 wmi_unified_t wmi_handle, 17602 uint32_t phy_id) 17603 { 17604 /*No conversion required*/ 17605 return phy_id; 17606 } 17607 17608 /** 17609 * send_set_country_cmd_tlv() - WMI scan channel list function 17610 * @wmi_handle: handle to WMI. 17611 * @params: pointer to hold scan channel list parameter 17612 * 17613 * Return: QDF_STATUS_SUCCESS for success or error code 17614 */ 17615 static QDF_STATUS send_set_country_cmd_tlv(wmi_unified_t wmi_handle, 17616 struct set_country *params) 17617 { 17618 wmi_buf_t buf; 17619 QDF_STATUS qdf_status; 17620 wmi_set_current_country_cmd_fixed_param *cmd; 17621 uint16_t len = sizeof(*cmd); 17622 uint8_t pdev_id = params->pdev_id; 17623 17624 buf = wmi_buf_alloc(wmi_handle, len); 17625 if (!buf) { 17626 qdf_status = QDF_STATUS_E_NOMEM; 17627 goto end; 17628 } 17629 17630 cmd = (wmi_set_current_country_cmd_fixed_param *)wmi_buf_data(buf); 17631 WMITLV_SET_HDR(&cmd->tlv_header, 17632 WMITLV_TAG_STRUC_wmi_set_current_country_cmd_fixed_param, 17633 WMITLV_GET_STRUCT_TLVLEN 17634 (wmi_set_current_country_cmd_fixed_param)); 17635 17636 cmd->pdev_id = wmi_handle->ops->convert_host_pdev_id_to_target( 17637 wmi_handle, 17638 pdev_id); 17639 wmi_debug("setting current country to %s and target pdev_id = %u", 17640 params->country, cmd->pdev_id); 17641 17642 qdf_mem_copy((uint8_t *)&cmd->new_alpha2, params->country, 3); 17643 17644 wmi_mtrace(WMI_SET_CURRENT_COUNTRY_CMDID, NO_SESSION, 0); 17645 qdf_status = wmi_unified_cmd_send(wmi_handle, 17646 buf, len, WMI_SET_CURRENT_COUNTRY_CMDID); 17647 17648 if (QDF_IS_STATUS_ERROR(qdf_status)) { 17649 wmi_err("Failed to send WMI_SET_CURRENT_COUNTRY_CMDID"); 17650 wmi_buf_free(buf); 17651 } 17652 17653 end: 17654 return qdf_status; 17655 } 17656 17657 #define WMI_REG_COUNTRY_ALPHA_SET(alpha, val0, val1, val2) do { \ 17658 WMI_SET_BITS(alpha, 0, 8, val0); \ 17659 WMI_SET_BITS(alpha, 8, 8, val1); \ 17660 WMI_SET_BITS(alpha, 16, 8, val2); \ 17661 } while (0) 17662 17663 static QDF_STATUS send_user_country_code_cmd_tlv(wmi_unified_t wmi_handle, 17664 uint8_t pdev_id, struct cc_regdmn_s *rd) 17665 { 17666 wmi_set_init_country_cmd_fixed_param *cmd; 17667 uint16_t len; 17668 wmi_buf_t buf; 17669 int ret; 17670 17671 len = sizeof(wmi_set_init_country_cmd_fixed_param); 17672 buf = wmi_buf_alloc(wmi_handle, len); 17673 if (!buf) 17674 return QDF_STATUS_E_NOMEM; 17675 17676 cmd = (wmi_set_init_country_cmd_fixed_param *) wmi_buf_data(buf); 17677 WMITLV_SET_HDR(&cmd->tlv_header, 17678 WMITLV_TAG_STRUC_wmi_set_init_country_cmd_fixed_param, 17679 WMITLV_GET_STRUCT_TLVLEN 17680 (wmi_set_init_country_cmd_fixed_param)); 17681 17682 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 17683 wmi_handle, 17684 pdev_id); 17685 17686 if (rd->flags == CC_IS_SET) { 17687 cmd->countrycode_type = WMI_COUNTRYCODE_COUNTRY_ID; 17688 cmd->country_code.country_id = rd->cc.country_code; 17689 } else if (rd->flags == ALPHA_IS_SET) { 17690 cmd->countrycode_type = WMI_COUNTRYCODE_ALPHA2; 17691 WMI_REG_COUNTRY_ALPHA_SET(cmd->country_code.alpha2, 17692 rd->cc.alpha[0], 17693 rd->cc.alpha[1], 17694 rd->cc.alpha[2]); 17695 } else if (rd->flags == REGDMN_IS_SET) { 17696 cmd->countrycode_type = WMI_COUNTRYCODE_DOMAIN_CODE; 17697 WMI_SET_BITS(cmd->country_code.domain_code, 0, 16, 17698 rd->cc.regdmn.reg_2g_5g_pair_id); 17699 WMI_SET_BITS(cmd->country_code.domain_code, 16, 16, 17700 rd->cc.regdmn.sixg_superdmn_id); 17701 } 17702 17703 wmi_mtrace(WMI_SET_INIT_COUNTRY_CMDID, NO_SESSION, 0); 17704 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 17705 WMI_SET_INIT_COUNTRY_CMDID); 17706 if (ret) { 17707 wmi_err("Failed to config wow wakeup event"); 17708 wmi_buf_free(buf); 17709 return QDF_STATUS_E_FAILURE; 17710 } 17711 17712 return QDF_STATUS_SUCCESS; 17713 } 17714 17715 /** 17716 * send_obss_detection_cfg_cmd_tlv() - send obss detection 17717 * configurations to firmware. 17718 * @wmi_handle: wmi handle 17719 * @obss_cfg_param: obss detection configurations 17720 * 17721 * Send WMI_SAP_OBSS_DETECTION_CFG_CMDID parameters to fw. 17722 * 17723 * Return: QDF_STATUS 17724 */ 17725 static QDF_STATUS send_obss_detection_cfg_cmd_tlv(wmi_unified_t wmi_handle, 17726 struct wmi_obss_detection_cfg_param *obss_cfg_param) 17727 { 17728 wmi_buf_t buf; 17729 wmi_sap_obss_detection_cfg_cmd_fixed_param *cmd; 17730 uint8_t len = sizeof(wmi_sap_obss_detection_cfg_cmd_fixed_param); 17731 17732 buf = wmi_buf_alloc(wmi_handle, len); 17733 if (!buf) 17734 return QDF_STATUS_E_NOMEM; 17735 17736 cmd = (wmi_sap_obss_detection_cfg_cmd_fixed_param *)wmi_buf_data(buf); 17737 WMITLV_SET_HDR(&cmd->tlv_header, 17738 WMITLV_TAG_STRUC_wmi_sap_obss_detection_cfg_cmd_fixed_param, 17739 WMITLV_GET_STRUCT_TLVLEN 17740 (wmi_sap_obss_detection_cfg_cmd_fixed_param)); 17741 17742 cmd->vdev_id = obss_cfg_param->vdev_id; 17743 cmd->detect_period_ms = obss_cfg_param->obss_detect_period_ms; 17744 cmd->b_ap_detect_mode = obss_cfg_param->obss_11b_ap_detect_mode; 17745 cmd->b_sta_detect_mode = obss_cfg_param->obss_11b_sta_detect_mode; 17746 cmd->g_ap_detect_mode = obss_cfg_param->obss_11g_ap_detect_mode; 17747 cmd->a_detect_mode = obss_cfg_param->obss_11a_detect_mode; 17748 cmd->ht_legacy_detect_mode = obss_cfg_param->obss_ht_legacy_detect_mode; 17749 cmd->ht_mixed_detect_mode = obss_cfg_param->obss_ht_mixed_detect_mode; 17750 cmd->ht_20mhz_detect_mode = obss_cfg_param->obss_ht_20mhz_detect_mode; 17751 17752 wmi_mtrace(WMI_SAP_OBSS_DETECTION_CFG_CMDID, cmd->vdev_id, 0); 17753 if (wmi_unified_cmd_send(wmi_handle, buf, len, 17754 WMI_SAP_OBSS_DETECTION_CFG_CMDID)) { 17755 wmi_err("Failed to send WMI_SAP_OBSS_DETECTION_CFG_CMDID"); 17756 wmi_buf_free(buf); 17757 return QDF_STATUS_E_FAILURE; 17758 } 17759 17760 return QDF_STATUS_SUCCESS; 17761 } 17762 17763 /** 17764 * extract_obss_detection_info_tlv() - Extract obss detection info 17765 * received from firmware. 17766 * @evt_buf: pointer to event buffer 17767 * @obss_detection: Pointer to hold obss detection info 17768 * 17769 * Return: QDF_STATUS 17770 */ 17771 static QDF_STATUS extract_obss_detection_info_tlv(uint8_t *evt_buf, 17772 struct wmi_obss_detect_info 17773 *obss_detection) 17774 { 17775 WMI_SAP_OBSS_DETECTION_REPORT_EVENTID_param_tlvs *param_buf; 17776 wmi_sap_obss_detection_info_evt_fixed_param *fix_param; 17777 17778 if (!obss_detection) { 17779 wmi_err("Invalid obss_detection event buffer"); 17780 return QDF_STATUS_E_INVAL; 17781 } 17782 17783 param_buf = (WMI_SAP_OBSS_DETECTION_REPORT_EVENTID_param_tlvs *)evt_buf; 17784 if (!param_buf) { 17785 wmi_err("Invalid evt_buf"); 17786 return QDF_STATUS_E_INVAL; 17787 } 17788 17789 fix_param = param_buf->fixed_param; 17790 obss_detection->vdev_id = fix_param->vdev_id; 17791 obss_detection->matched_detection_masks = 17792 fix_param->matched_detection_masks; 17793 WMI_MAC_ADDR_TO_CHAR_ARRAY(&fix_param->matched_bssid_addr, 17794 &obss_detection->matched_bssid_addr[0]); 17795 switch (fix_param->reason) { 17796 case WMI_SAP_OBSS_DETECTION_EVENT_REASON_NOT_SUPPORT: 17797 obss_detection->reason = OBSS_OFFLOAD_DETECTION_DISABLED; 17798 break; 17799 case WMI_SAP_OBSS_DETECTION_EVENT_REASON_PRESENT_NOTIFY: 17800 obss_detection->reason = OBSS_OFFLOAD_DETECTION_PRESENT; 17801 break; 17802 case WMI_SAP_OBSS_DETECTION_EVENT_REASON_ABSENT_TIMEOUT: 17803 obss_detection->reason = OBSS_OFFLOAD_DETECTION_ABSENT; 17804 break; 17805 default: 17806 wmi_err("Invalid reason: %d", fix_param->reason); 17807 return QDF_STATUS_E_INVAL; 17808 } 17809 17810 return QDF_STATUS_SUCCESS; 17811 } 17812 17813 /** 17814 * send_roam_scan_stats_cmd_tlv() - Send roam scan stats req command to fw 17815 * @wmi_handle: wmi handle 17816 * @params: pointer to request structure 17817 * 17818 * Return: QDF_STATUS 17819 */ 17820 static QDF_STATUS 17821 send_roam_scan_stats_cmd_tlv(wmi_unified_t wmi_handle, 17822 struct wmi_roam_scan_stats_req *params) 17823 { 17824 wmi_buf_t buf; 17825 wmi_request_roam_scan_stats_cmd_fixed_param *cmd; 17826 WMITLV_TAG_ID tag; 17827 uint32_t size; 17828 uint32_t len = sizeof(*cmd); 17829 17830 buf = wmi_buf_alloc(wmi_handle, len); 17831 if (!buf) 17832 return QDF_STATUS_E_FAILURE; 17833 17834 cmd = (wmi_request_roam_scan_stats_cmd_fixed_param *)wmi_buf_data(buf); 17835 17836 tag = WMITLV_TAG_STRUC_wmi_request_roam_scan_stats_cmd_fixed_param; 17837 size = WMITLV_GET_STRUCT_TLVLEN( 17838 wmi_request_roam_scan_stats_cmd_fixed_param); 17839 WMITLV_SET_HDR(&cmd->tlv_header, tag, size); 17840 17841 cmd->vdev_id = params->vdev_id; 17842 17843 wmi_debug("Roam Scan Stats Req vdev_id: %u", cmd->vdev_id); 17844 if (wmi_unified_cmd_send(wmi_handle, buf, len, 17845 WMI_REQUEST_ROAM_SCAN_STATS_CMDID)) { 17846 wmi_err("Failed to send WMI_REQUEST_ROAM_SCAN_STATS_CMDID"); 17847 wmi_buf_free(buf); 17848 return QDF_STATUS_E_FAILURE; 17849 } 17850 17851 return QDF_STATUS_SUCCESS; 17852 } 17853 17854 /** 17855 * send_roam_scan_ch_list_req_cmd_tlv() - send wmi cmd to get roam scan 17856 * channel list from firmware 17857 * @wmi_handle: wmi handler 17858 * @vdev_id: vdev id 17859 * 17860 * Return: QDF_STATUS 17861 */ 17862 static QDF_STATUS send_roam_scan_ch_list_req_cmd_tlv(wmi_unified_t wmi_handle, 17863 uint32_t vdev_id) 17864 { 17865 wmi_buf_t buf; 17866 wmi_roam_get_scan_channel_list_cmd_fixed_param *cmd; 17867 uint16_t len = sizeof(*cmd); 17868 int ret; 17869 17870 buf = wmi_buf_alloc(wmi_handle, len); 17871 if (!buf) { 17872 wmi_err("Failed to allocate wmi buffer"); 17873 return QDF_STATUS_E_NOMEM; 17874 } 17875 17876 cmd = (wmi_roam_get_scan_channel_list_cmd_fixed_param *) 17877 wmi_buf_data(buf); 17878 WMITLV_SET_HDR(&cmd->tlv_header, 17879 WMITLV_TAG_STRUC_wmi_roam_get_scan_channel_list_cmd_fixed_param, 17880 WMITLV_GET_STRUCT_TLVLEN( 17881 wmi_roam_get_scan_channel_list_cmd_fixed_param)); 17882 cmd->vdev_id = vdev_id; 17883 wmi_mtrace(WMI_ROAM_GET_SCAN_CHANNEL_LIST_CMDID, vdev_id, 0); 17884 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 17885 WMI_ROAM_GET_SCAN_CHANNEL_LIST_CMDID); 17886 if (QDF_IS_STATUS_ERROR(ret)) { 17887 wmi_err("Failed to send get roam scan channels request = %d", 17888 ret); 17889 wmi_buf_free(buf); 17890 } 17891 return ret; 17892 } 17893 17894 /** 17895 * extract_roam_scan_stats_res_evt_tlv() - Extract roam scan stats event 17896 * @wmi_handle: wmi handle 17897 * @evt_buf: pointer to event buffer 17898 * @vdev_id: output pointer to hold vdev id 17899 * @res_param: output pointer to hold the allocated response 17900 * 17901 * Return: QDF_STATUS 17902 */ 17903 static QDF_STATUS 17904 extract_roam_scan_stats_res_evt_tlv(wmi_unified_t wmi_handle, void *evt_buf, 17905 uint32_t *vdev_id, 17906 struct wmi_roam_scan_stats_res **res_param) 17907 { 17908 WMI_ROAM_SCAN_STATS_EVENTID_param_tlvs *param_buf; 17909 wmi_roam_scan_stats_event_fixed_param *fixed_param; 17910 uint32_t *client_id = NULL; 17911 wmi_roaming_timestamp *timestamp = NULL; 17912 uint32_t *num_channels = NULL; 17913 uint32_t *chan_info = NULL; 17914 wmi_mac_addr *old_bssid = NULL; 17915 uint32_t *is_roaming_success = NULL; 17916 wmi_mac_addr *new_bssid = NULL; 17917 uint32_t *num_roam_candidates = NULL; 17918 wmi_roam_scan_trigger_reason *roam_reason = NULL; 17919 wmi_mac_addr *bssid = NULL; 17920 uint32_t *score = NULL; 17921 uint32_t *channel = NULL; 17922 uint32_t *rssi = NULL; 17923 int chan_idx = 0, cand_idx = 0; 17924 uint32_t total_len; 17925 struct wmi_roam_scan_stats_res *res; 17926 uint32_t i, j; 17927 uint32_t num_scans, scan_param_size; 17928 17929 *res_param = NULL; 17930 *vdev_id = 0xFF; /* Initialize to invalid vdev id */ 17931 param_buf = (WMI_ROAM_SCAN_STATS_EVENTID_param_tlvs *)evt_buf; 17932 if (!param_buf) { 17933 wmi_err("Invalid roam scan stats event"); 17934 return QDF_STATUS_E_INVAL; 17935 } 17936 17937 fixed_param = param_buf->fixed_param; 17938 17939 num_scans = fixed_param->num_roam_scans; 17940 scan_param_size = sizeof(struct wmi_roam_scan_stats_params); 17941 *vdev_id = fixed_param->vdev_id; 17942 if (num_scans > WMI_ROAM_SCAN_STATS_MAX) { 17943 wmi_err_rl("%u exceeded maximum roam scan stats: %u", 17944 num_scans, WMI_ROAM_SCAN_STATS_MAX); 17945 return QDF_STATUS_E_INVAL; 17946 } 17947 17948 total_len = sizeof(*res) + num_scans * scan_param_size; 17949 17950 res = qdf_mem_malloc(total_len); 17951 if (!res) 17952 return QDF_STATUS_E_NOMEM; 17953 17954 if (!num_scans) { 17955 *res_param = res; 17956 return QDF_STATUS_SUCCESS; 17957 } 17958 17959 if (param_buf->client_id && 17960 param_buf->num_client_id == num_scans) 17961 client_id = param_buf->client_id; 17962 17963 if (param_buf->timestamp && 17964 param_buf->num_timestamp == num_scans) 17965 timestamp = param_buf->timestamp; 17966 17967 if (param_buf->old_bssid && 17968 param_buf->num_old_bssid == num_scans) 17969 old_bssid = param_buf->old_bssid; 17970 17971 if (param_buf->new_bssid && 17972 param_buf->num_new_bssid == num_scans) 17973 new_bssid = param_buf->new_bssid; 17974 17975 if (param_buf->is_roaming_success && 17976 param_buf->num_is_roaming_success == num_scans) 17977 is_roaming_success = param_buf->is_roaming_success; 17978 17979 if (param_buf->roam_reason && 17980 param_buf->num_roam_reason == num_scans) 17981 roam_reason = param_buf->roam_reason; 17982 17983 if (param_buf->num_channels && 17984 param_buf->num_num_channels == num_scans) { 17985 uint32_t count, chan_info_sum = 0; 17986 17987 num_channels = param_buf->num_channels; 17988 for (count = 0; count < param_buf->num_num_channels; count++) { 17989 if (param_buf->num_channels[count] > 17990 WMI_ROAM_SCAN_STATS_CHANNELS_MAX) { 17991 wmi_err_rl("%u exceeded max scan channels %u", 17992 param_buf->num_channels[count], 17993 WMI_ROAM_SCAN_STATS_CHANNELS_MAX); 17994 goto error; 17995 } 17996 chan_info_sum += param_buf->num_channels[count]; 17997 } 17998 17999 if (param_buf->chan_info && 18000 param_buf->num_chan_info == chan_info_sum) 18001 chan_info = param_buf->chan_info; 18002 } 18003 18004 if (param_buf->num_roam_candidates && 18005 param_buf->num_num_roam_candidates == num_scans) { 18006 uint32_t cnt, roam_cand_sum = 0; 18007 18008 num_roam_candidates = param_buf->num_roam_candidates; 18009 for (cnt = 0; cnt < param_buf->num_num_roam_candidates; cnt++) { 18010 if (param_buf->num_roam_candidates[cnt] > 18011 WMI_ROAM_SCAN_STATS_CANDIDATES_MAX) { 18012 wmi_err_rl("%u exceeded max scan cand %u", 18013 param_buf->num_roam_candidates[cnt], 18014 WMI_ROAM_SCAN_STATS_CANDIDATES_MAX); 18015 goto error; 18016 } 18017 roam_cand_sum += param_buf->num_roam_candidates[cnt]; 18018 } 18019 18020 if (param_buf->bssid && 18021 param_buf->num_bssid == roam_cand_sum) 18022 bssid = param_buf->bssid; 18023 18024 if (param_buf->score && 18025 param_buf->num_score == roam_cand_sum) 18026 score = param_buf->score; 18027 18028 if (param_buf->channel && 18029 param_buf->num_channel == roam_cand_sum) 18030 channel = param_buf->channel; 18031 18032 if (param_buf->rssi && 18033 param_buf->num_rssi == roam_cand_sum) 18034 rssi = param_buf->rssi; 18035 } 18036 18037 res->num_roam_scans = num_scans; 18038 for (i = 0; i < num_scans; i++) { 18039 struct wmi_roam_scan_stats_params *roam = &res->roam_scan[i]; 18040 18041 if (timestamp) 18042 roam->time_stamp = timestamp[i].lower32bit | 18043 (timestamp[i].upper32bit << 31); 18044 18045 if (client_id) 18046 roam->client_id = client_id[i]; 18047 18048 if (num_channels) { 18049 roam->num_scan_chans = num_channels[i]; 18050 if (chan_info) { 18051 for (j = 0; j < num_channels[i]; j++) 18052 roam->scan_freqs[j] = 18053 chan_info[chan_idx++]; 18054 } 18055 } 18056 18057 if (is_roaming_success) 18058 roam->is_roam_successful = is_roaming_success[i]; 18059 18060 if (roam_reason) { 18061 roam->trigger_id = roam_reason[i].trigger_id; 18062 roam->trigger_value = roam_reason[i].trigger_value; 18063 } 18064 18065 if (num_roam_candidates) { 18066 roam->num_roam_candidates = num_roam_candidates[i]; 18067 18068 for (j = 0; j < num_roam_candidates[i]; j++) { 18069 if (score) 18070 roam->cand[j].score = score[cand_idx]; 18071 if (rssi) 18072 roam->cand[j].rssi = rssi[cand_idx]; 18073 if (channel) 18074 roam->cand[j].freq = 18075 channel[cand_idx]; 18076 18077 if (bssid) 18078 WMI_MAC_ADDR_TO_CHAR_ARRAY( 18079 &bssid[cand_idx], 18080 roam->cand[j].bssid); 18081 18082 cand_idx++; 18083 } 18084 } 18085 18086 if (old_bssid) 18087 WMI_MAC_ADDR_TO_CHAR_ARRAY(&old_bssid[i], 18088 roam->old_bssid); 18089 18090 if (new_bssid) 18091 WMI_MAC_ADDR_TO_CHAR_ARRAY(&new_bssid[i], 18092 roam->new_bssid); 18093 } 18094 18095 *res_param = res; 18096 18097 return QDF_STATUS_SUCCESS; 18098 error: 18099 qdf_mem_free(res); 18100 return QDF_STATUS_E_FAILURE; 18101 } 18102 18103 /** 18104 * extract_offload_bcn_tx_status_evt() - Extract beacon-tx status event 18105 * @wmi_handle: wmi handle 18106 * @evt_buf: pointer to event buffer 18107 * @vdev_id: output pointer to hold vdev id 18108 * @tx_status: output pointer to hold the tx_status 18109 * 18110 * Return: QDF_STATUS 18111 */ 18112 static QDF_STATUS extract_offload_bcn_tx_status_evt(wmi_unified_t wmi_handle, 18113 void *evt_buf, 18114 uint32_t *vdev_id, 18115 uint32_t *tx_status) { 18116 WMI_OFFLOAD_BCN_TX_STATUS_EVENTID_param_tlvs *param_buf; 18117 wmi_offload_bcn_tx_status_event_fixed_param *bcn_tx_status_event; 18118 18119 param_buf = (WMI_OFFLOAD_BCN_TX_STATUS_EVENTID_param_tlvs *)evt_buf; 18120 if (!param_buf) { 18121 wmi_err("Invalid offload bcn tx status event buffer"); 18122 return QDF_STATUS_E_INVAL; 18123 } 18124 18125 bcn_tx_status_event = param_buf->fixed_param; 18126 *vdev_id = bcn_tx_status_event->vdev_id; 18127 *tx_status = bcn_tx_status_event->tx_status; 18128 18129 return QDF_STATUS_SUCCESS; 18130 } 18131 18132 #ifdef WLAN_SUPPORT_GREEN_AP 18133 static QDF_STATUS extract_green_ap_egap_status_info_tlv( 18134 uint8_t *evt_buf, 18135 struct wlan_green_ap_egap_status_info *egap_status_info_params) 18136 { 18137 WMI_AP_PS_EGAP_INFO_EVENTID_param_tlvs *param_buf; 18138 wmi_ap_ps_egap_info_event_fixed_param *egap_info_event; 18139 wmi_ap_ps_egap_info_chainmask_list *chainmask_event; 18140 18141 param_buf = (WMI_AP_PS_EGAP_INFO_EVENTID_param_tlvs *)evt_buf; 18142 if (!param_buf) { 18143 wmi_err("Invalid EGAP Info status event buffer"); 18144 return QDF_STATUS_E_INVAL; 18145 } 18146 18147 egap_info_event = (wmi_ap_ps_egap_info_event_fixed_param *) 18148 param_buf->fixed_param; 18149 chainmask_event = (wmi_ap_ps_egap_info_chainmask_list *) 18150 param_buf->chainmask_list; 18151 18152 if (!egap_info_event || !chainmask_event) { 18153 wmi_err("Invalid EGAP Info event or chainmask event"); 18154 return QDF_STATUS_E_INVAL; 18155 } 18156 18157 egap_status_info_params->status = egap_info_event->status; 18158 egap_status_info_params->mac_id = chainmask_event->mac_id; 18159 egap_status_info_params->tx_chainmask = chainmask_event->tx_chainmask; 18160 egap_status_info_params->rx_chainmask = chainmask_event->rx_chainmask; 18161 18162 return QDF_STATUS_SUCCESS; 18163 } 18164 #endif 18165 18166 #ifdef WLAN_SUPPORT_GAP_LL_PS_MODE 18167 static QDF_STATUS extract_green_ap_ll_ps_param_tlv( 18168 uint8_t *evt_buf, 18169 struct wlan_green_ap_ll_ps_event_param *ll_ps_params) 18170 { 18171 WMI_XGAP_ENABLE_COMPLETE_EVENTID_param_tlvs *param_buf; 18172 wmi_xgap_enable_complete_event_fixed_param *ll_ps_event; 18173 18174 param_buf = (WMI_XGAP_ENABLE_COMPLETE_EVENTID_param_tlvs *)evt_buf; 18175 if (!param_buf) { 18176 wmi_err("Invalid XGAP SAP info status"); 18177 return QDF_STATUS_E_INVAL; 18178 } 18179 18180 ll_ps_event = (wmi_xgap_enable_complete_event_fixed_param *) 18181 param_buf->fixed_param; 18182 if (!ll_ps_event) { 18183 wmi_err("Invalid low latency power save event buffer"); 18184 return QDF_STATUS_E_INVAL; 18185 } 18186 18187 ll_ps_params->dialog_token = ll_ps_event->dialog_token; 18188 ll_ps_params->next_tsf = 18189 ((uint64_t)ll_ps_event->next_tsf_high32 << 32) | 18190 ll_ps_event->next_tsf_low32; 18191 18192 wmi_debug("cookie : %u next_tsf %llu", ll_ps_params->dialog_token, 18193 ll_ps_params->next_tsf); 18194 18195 return QDF_STATUS_SUCCESS; 18196 } 18197 #endif 18198 18199 /* 18200 * extract_comb_phyerr_tlv() - extract comb phy error from event 18201 * @wmi_handle: wmi handle 18202 * @evt_buf: pointer to event buffer 18203 * @datalen: data length of event buffer 18204 * @buf_offset: Pointer to hold value of current event buffer offset 18205 * post extraction 18206 * @phyerr: Pointer to hold phyerr 18207 * 18208 * Return: QDF_STATUS 18209 */ 18210 static QDF_STATUS extract_comb_phyerr_tlv(wmi_unified_t wmi_handle, 18211 void *evt_buf, 18212 uint16_t datalen, 18213 uint16_t *buf_offset, 18214 wmi_host_phyerr_t *phyerr) 18215 { 18216 WMI_PHYERR_EVENTID_param_tlvs *param_tlvs; 18217 wmi_comb_phyerr_rx_hdr *pe_hdr; 18218 18219 param_tlvs = (WMI_PHYERR_EVENTID_param_tlvs *)evt_buf; 18220 if (!param_tlvs) { 18221 wmi_debug("Received null data from FW"); 18222 return QDF_STATUS_E_FAILURE; 18223 } 18224 18225 pe_hdr = param_tlvs->hdr; 18226 if (!pe_hdr) { 18227 wmi_debug("Received Data PE Header is NULL"); 18228 return QDF_STATUS_E_FAILURE; 18229 } 18230 18231 /* Ensure it's at least the size of the header */ 18232 if (datalen < sizeof(*pe_hdr)) { 18233 wmi_debug("Expected minimum size %zu, received %d", 18234 sizeof(*pe_hdr), datalen); 18235 return QDF_STATUS_E_FAILURE; 18236 } 18237 18238 phyerr->pdev_id = wmi_handle->ops-> 18239 convert_pdev_id_target_to_host(wmi_handle, pe_hdr->pdev_id); 18240 phyerr->tsf64 = pe_hdr->tsf_l32; 18241 phyerr->tsf64 |= (((uint64_t)pe_hdr->tsf_u32) << 32); 18242 phyerr->bufp = param_tlvs->bufp; 18243 18244 if (pe_hdr->buf_len > param_tlvs->num_bufp) { 18245 wmi_debug("Invalid buf_len %d, num_bufp %d", 18246 pe_hdr->buf_len, param_tlvs->num_bufp); 18247 return QDF_STATUS_E_FAILURE; 18248 } 18249 18250 phyerr->buf_len = pe_hdr->buf_len; 18251 phyerr->phy_err_mask0 = pe_hdr->rsPhyErrMask0; 18252 phyerr->phy_err_mask1 = pe_hdr->rsPhyErrMask1; 18253 *buf_offset = sizeof(*pe_hdr) + sizeof(uint32_t); 18254 18255 return QDF_STATUS_SUCCESS; 18256 } 18257 18258 /** 18259 * extract_single_phyerr_tlv() - extract single phy error from event 18260 * @wmi_handle: wmi handle 18261 * @evt_buf: pointer to event buffer 18262 * @datalen: data length of event buffer 18263 * @buf_offset: Pointer to hold value of current event buffer offset 18264 * post extraction 18265 * @phyerr: Pointer to hold phyerr 18266 * 18267 * Return: QDF_STATUS 18268 */ 18269 static QDF_STATUS extract_single_phyerr_tlv(wmi_unified_t wmi_handle, 18270 void *evt_buf, 18271 uint16_t datalen, 18272 uint16_t *buf_offset, 18273 wmi_host_phyerr_t *phyerr) 18274 { 18275 wmi_single_phyerr_rx_event *ev; 18276 uint16_t n = *buf_offset; 18277 uint8_t *data = (uint8_t *)evt_buf; 18278 18279 if (n < datalen) { 18280 if ((datalen - n) < sizeof(ev->hdr)) { 18281 wmi_debug("Not enough space. len=%d, n=%d, hdr=%zu", 18282 datalen, n, sizeof(ev->hdr)); 18283 return QDF_STATUS_E_FAILURE; 18284 } 18285 18286 /* 18287 * Obtain a pointer to the beginning of the current event. 18288 * data[0] is the beginning of the WMI payload. 18289 */ 18290 ev = (wmi_single_phyerr_rx_event *)&data[n]; 18291 18292 /* 18293 * Sanity check the buffer length of the event against 18294 * what we currently have. 18295 * 18296 * Since buf_len is 32 bits, we check if it overflows 18297 * a large 32 bit value. It's not 0x7fffffff because 18298 * we increase n by (buf_len + sizeof(hdr)), which would 18299 * in itself cause n to overflow. 18300 * 18301 * If "int" is 64 bits then this becomes a moot point. 18302 */ 18303 if (ev->hdr.buf_len > PHYERROR_MAX_BUFFER_LENGTH) { 18304 wmi_debug("buf_len is garbage 0x%x", ev->hdr.buf_len); 18305 return QDF_STATUS_E_FAILURE; 18306 } 18307 18308 if ((n + ev->hdr.buf_len) > datalen) { 18309 wmi_debug("len exceeds n=%d, buf_len=%d, datalen=%d", 18310 n, ev->hdr.buf_len, datalen); 18311 return QDF_STATUS_E_FAILURE; 18312 } 18313 18314 phyerr->phy_err_code = WMI_UNIFIED_PHYERRCODE_GET(&ev->hdr); 18315 phyerr->tsf_timestamp = ev->hdr.tsf_timestamp; 18316 phyerr->bufp = &ev->bufp[0]; 18317 phyerr->buf_len = ev->hdr.buf_len; 18318 phyerr->rf_info.rssi_comb = WMI_UNIFIED_RSSI_COMB_GET(&ev->hdr); 18319 18320 /* 18321 * Advance the buffer pointer to the next PHY error. 18322 * buflen is the length of this payload, so we need to 18323 * advance past the current header _AND_ the payload. 18324 */ 18325 n += sizeof(*ev) + ev->hdr.buf_len; 18326 } 18327 *buf_offset = n; 18328 18329 return QDF_STATUS_SUCCESS; 18330 } 18331 18332 /** 18333 * extract_esp_estimation_ev_param_tlv() - extract air time from event 18334 * @wmi_handle: wmi handle 18335 * @evt_buf: pointer to event buffer 18336 * @param: Pointer to hold esp event 18337 * 18338 * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_INVAL on failure 18339 */ 18340 static QDF_STATUS 18341 extract_esp_estimation_ev_param_tlv(wmi_unified_t wmi_handle, 18342 void *evt_buf, 18343 struct esp_estimation_event *param) 18344 { 18345 WMI_ESP_ESTIMATE_EVENTID_param_tlvs *param_buf; 18346 wmi_esp_estimate_event_fixed_param *esp_event; 18347 18348 param_buf = (WMI_ESP_ESTIMATE_EVENTID_param_tlvs *)evt_buf; 18349 if (!param_buf) { 18350 wmi_err("Invalid ESP Estimate Event buffer"); 18351 return QDF_STATUS_E_INVAL; 18352 } 18353 esp_event = param_buf->fixed_param; 18354 param->ac_airtime_percentage = esp_event->ac_airtime_percentage; 18355 18356 param->pdev_id = convert_target_pdev_id_to_host_pdev_id( 18357 wmi_handle, 18358 esp_event->pdev_id); 18359 18360 if (param->pdev_id == WMI_HOST_PDEV_ID_INVALID) 18361 return QDF_STATUS_E_FAILURE; 18362 18363 return QDF_STATUS_SUCCESS; 18364 } 18365 18366 /* 18367 * send_bss_color_change_enable_cmd_tlv() - Send command to enable or disable of 18368 * updating bss color change within firmware when AP announces bss color change. 18369 * @wmi_handle: wmi handle 18370 * @vdev_id: vdev ID 18371 * @enable: enable bss color change within firmware 18372 * 18373 * Send WMI_BSS_COLOR_CHANGE_ENABLE_CMDID parameters to fw. 18374 * 18375 * Return: QDF_STATUS 18376 */ 18377 static QDF_STATUS send_bss_color_change_enable_cmd_tlv(wmi_unified_t wmi_handle, 18378 uint32_t vdev_id, 18379 bool enable) 18380 { 18381 wmi_buf_t buf; 18382 wmi_bss_color_change_enable_fixed_param *cmd; 18383 uint8_t len = sizeof(wmi_bss_color_change_enable_fixed_param); 18384 18385 buf = wmi_buf_alloc(wmi_handle, len); 18386 if (!buf) 18387 return QDF_STATUS_E_NOMEM; 18388 18389 cmd = (wmi_bss_color_change_enable_fixed_param *)wmi_buf_data(buf); 18390 WMITLV_SET_HDR(&cmd->tlv_header, 18391 WMITLV_TAG_STRUC_wmi_bss_color_change_enable_fixed_param, 18392 WMITLV_GET_STRUCT_TLVLEN 18393 (wmi_bss_color_change_enable_fixed_param)); 18394 cmd->vdev_id = vdev_id; 18395 cmd->enable = enable; 18396 wmi_mtrace(WMI_BSS_COLOR_CHANGE_ENABLE_CMDID, cmd->vdev_id, 0); 18397 if (wmi_unified_cmd_send(wmi_handle, buf, len, 18398 WMI_BSS_COLOR_CHANGE_ENABLE_CMDID)) { 18399 wmi_err("Failed to send WMI_BSS_COLOR_CHANGE_ENABLE_CMDID"); 18400 wmi_buf_free(buf); 18401 return QDF_STATUS_E_FAILURE; 18402 } 18403 18404 return QDF_STATUS_SUCCESS; 18405 } 18406 18407 /** 18408 * send_obss_color_collision_cfg_cmd_tlv() - send bss color detection 18409 * configurations to firmware. 18410 * @wmi_handle: wmi handle 18411 * @cfg_param: obss detection configurations 18412 * 18413 * Send WMI_OBSS_COLOR_COLLISION_DET_CONFIG_CMDID parameters to fw. 18414 * 18415 * Return: QDF_STATUS 18416 */ 18417 static QDF_STATUS send_obss_color_collision_cfg_cmd_tlv( 18418 wmi_unified_t wmi_handle, 18419 struct wmi_obss_color_collision_cfg_param *cfg_param) 18420 { 18421 wmi_buf_t buf; 18422 wmi_obss_color_collision_det_config_fixed_param *cmd; 18423 uint8_t len = sizeof(wmi_obss_color_collision_det_config_fixed_param); 18424 18425 buf = wmi_buf_alloc(wmi_handle, len); 18426 if (!buf) 18427 return QDF_STATUS_E_NOMEM; 18428 18429 cmd = (wmi_obss_color_collision_det_config_fixed_param *)wmi_buf_data( 18430 buf); 18431 WMITLV_SET_HDR(&cmd->tlv_header, 18432 WMITLV_TAG_STRUC_wmi_obss_color_collision_det_config_fixed_param, 18433 WMITLV_GET_STRUCT_TLVLEN 18434 (wmi_obss_color_collision_det_config_fixed_param)); 18435 cmd->vdev_id = cfg_param->vdev_id; 18436 cmd->flags = cfg_param->flags; 18437 cmd->current_bss_color = cfg_param->current_bss_color; 18438 cmd->detection_period_ms = cfg_param->detection_period_ms; 18439 cmd->scan_period_ms = cfg_param->scan_period_ms; 18440 cmd->free_slot_expiry_time_ms = cfg_param->free_slot_expiry_time_ms; 18441 18442 switch (cfg_param->evt_type) { 18443 case OBSS_COLOR_COLLISION_DETECTION_DISABLE: 18444 cmd->evt_type = WMI_BSS_COLOR_COLLISION_DISABLE; 18445 break; 18446 case OBSS_COLOR_COLLISION_DETECTION: 18447 cmd->evt_type = WMI_BSS_COLOR_COLLISION_DETECTION; 18448 break; 18449 case OBSS_COLOR_FREE_SLOT_TIMER_EXPIRY: 18450 cmd->evt_type = WMI_BSS_COLOR_FREE_SLOT_TIMER_EXPIRY; 18451 break; 18452 case OBSS_COLOR_FREE_SLOT_AVAILABLE: 18453 cmd->evt_type = WMI_BSS_COLOR_FREE_SLOT_AVAILABLE; 18454 break; 18455 default: 18456 wmi_err("Invalid event type: %d", cfg_param->evt_type); 18457 wmi_buf_free(buf); 18458 return QDF_STATUS_E_FAILURE; 18459 } 18460 18461 wmi_debug("evt_type: %d vdev id: %d current_bss_color: %d " 18462 "detection_period_ms: %d scan_period_ms: %d " 18463 "free_slot_expiry_timer_ms: %d", 18464 cmd->evt_type, cmd->vdev_id, cmd->current_bss_color, 18465 cmd->detection_period_ms, cmd->scan_period_ms, 18466 cmd->free_slot_expiry_time_ms); 18467 18468 wmi_mtrace(WMI_OBSS_COLOR_COLLISION_DET_CONFIG_CMDID, cmd->vdev_id, 0); 18469 if (wmi_unified_cmd_send(wmi_handle, buf, len, 18470 WMI_OBSS_COLOR_COLLISION_DET_CONFIG_CMDID)) { 18471 wmi_err("Sending OBSS color det cmd failed, vdev_id: %d", 18472 cfg_param->vdev_id); 18473 wmi_buf_free(buf); 18474 return QDF_STATUS_E_FAILURE; 18475 } 18476 18477 return QDF_STATUS_SUCCESS; 18478 } 18479 18480 /** 18481 * extract_obss_color_collision_info_tlv() - Extract bss color collision info 18482 * received from firmware. 18483 * @evt_buf: pointer to event buffer 18484 * @info: Pointer to hold bss collision info 18485 * 18486 * Return: QDF_STATUS 18487 */ 18488 static QDF_STATUS extract_obss_color_collision_info_tlv(uint8_t *evt_buf, 18489 struct wmi_obss_color_collision_info *info) 18490 { 18491 WMI_OBSS_COLOR_COLLISION_DETECTION_EVENTID_param_tlvs *param_buf; 18492 wmi_obss_color_collision_evt_fixed_param *fix_param; 18493 18494 if (!info) { 18495 wmi_err("Invalid obss color buffer"); 18496 return QDF_STATUS_E_INVAL; 18497 } 18498 18499 param_buf = (WMI_OBSS_COLOR_COLLISION_DETECTION_EVENTID_param_tlvs *) 18500 evt_buf; 18501 if (!param_buf) { 18502 wmi_err("Invalid evt_buf"); 18503 return QDF_STATUS_E_INVAL; 18504 } 18505 18506 fix_param = param_buf->fixed_param; 18507 info->vdev_id = fix_param->vdev_id; 18508 info->obss_color_bitmap_bit0to31 = 18509 fix_param->bss_color_bitmap_bit0to31; 18510 info->obss_color_bitmap_bit32to63 = 18511 fix_param->bss_color_bitmap_bit32to63; 18512 18513 switch (fix_param->evt_type) { 18514 case WMI_BSS_COLOR_COLLISION_DISABLE: 18515 info->evt_type = OBSS_COLOR_COLLISION_DETECTION_DISABLE; 18516 break; 18517 case WMI_BSS_COLOR_COLLISION_DETECTION: 18518 info->evt_type = OBSS_COLOR_COLLISION_DETECTION; 18519 break; 18520 case WMI_BSS_COLOR_FREE_SLOT_TIMER_EXPIRY: 18521 info->evt_type = OBSS_COLOR_FREE_SLOT_TIMER_EXPIRY; 18522 break; 18523 case WMI_BSS_COLOR_FREE_SLOT_AVAILABLE: 18524 info->evt_type = OBSS_COLOR_FREE_SLOT_AVAILABLE; 18525 break; 18526 default: 18527 wmi_err("Invalid event type: %d, vdev_id: %d", 18528 fix_param->evt_type, fix_param->vdev_id); 18529 return QDF_STATUS_E_FAILURE; 18530 } 18531 18532 return QDF_STATUS_SUCCESS; 18533 } 18534 18535 static void wmi_11ax_bss_color_attach_tlv(struct wmi_unified *wmi_handle) 18536 { 18537 struct wmi_ops *ops = wmi_handle->ops; 18538 18539 ops->send_obss_color_collision_cfg_cmd = 18540 send_obss_color_collision_cfg_cmd_tlv; 18541 ops->extract_obss_color_collision_info = 18542 extract_obss_color_collision_info_tlv; 18543 } 18544 18545 #if defined(WLAN_SUPPORT_FILS) || defined(CONFIG_BAND_6GHZ) 18546 static QDF_STATUS 18547 send_vdev_fils_enable_cmd_send(struct wmi_unified *wmi_handle, 18548 struct config_fils_params *param) 18549 { 18550 wmi_buf_t buf; 18551 wmi_enable_fils_cmd_fixed_param *cmd; 18552 uint8_t len = sizeof(wmi_enable_fils_cmd_fixed_param); 18553 18554 buf = wmi_buf_alloc(wmi_handle, len); 18555 if (!buf) 18556 return QDF_STATUS_E_NOMEM; 18557 18558 cmd = (wmi_enable_fils_cmd_fixed_param *)wmi_buf_data( 18559 buf); 18560 WMITLV_SET_HDR(&cmd->tlv_header, 18561 WMITLV_TAG_STRUC_wmi_enable_fils_cmd_fixed_param, 18562 WMITLV_GET_STRUCT_TLVLEN 18563 (wmi_enable_fils_cmd_fixed_param)); 18564 cmd->vdev_id = param->vdev_id; 18565 cmd->fd_period = param->fd_period; 18566 if (param->send_prb_rsp_frame) 18567 cmd->flags |= WMI_FILS_FLAGS_BITMAP_BCAST_PROBE_RSP; 18568 wmi_debug("vdev id: %d fd_period: %d cmd->Flags %d", 18569 cmd->vdev_id, cmd->fd_period, cmd->flags); 18570 wmi_mtrace(WMI_ENABLE_FILS_CMDID, cmd->vdev_id, cmd->fd_period); 18571 if (wmi_unified_cmd_send(wmi_handle, buf, len, 18572 WMI_ENABLE_FILS_CMDID)) { 18573 wmi_err("Sending FILS cmd failed, vdev_id: %d", param->vdev_id); 18574 wmi_buf_free(buf); 18575 return QDF_STATUS_E_FAILURE; 18576 } 18577 18578 return QDF_STATUS_SUCCESS; 18579 } 18580 #endif 18581 18582 #ifdef WLAN_MWS_INFO_DEBUGFS 18583 /** 18584 * send_mws_coex_status_req_cmd_tlv() - send coex cmd to fw 18585 * 18586 * @wmi_handle: wmi handle 18587 * @vdev_id: vdev id 18588 * @cmd_id: Coex command id 18589 * 18590 * Send WMI_VDEV_GET_MWS_COEX_INFO_CMDID to fw. 18591 * 18592 * Return: QDF_STATUS 18593 */ 18594 static QDF_STATUS send_mws_coex_status_req_cmd_tlv(wmi_unified_t wmi_handle, 18595 uint32_t vdev_id, 18596 uint32_t cmd_id) 18597 { 18598 wmi_buf_t buf; 18599 wmi_vdev_get_mws_coex_info_cmd_fixed_param *cmd; 18600 uint16_t len = sizeof(*cmd); 18601 int ret; 18602 18603 buf = wmi_buf_alloc(wmi_handle, len); 18604 if (!buf) { 18605 wmi_err("Failed to allocate wmi buffer"); 18606 return QDF_STATUS_E_NOMEM; 18607 } 18608 18609 cmd = (wmi_vdev_get_mws_coex_info_cmd_fixed_param *)wmi_buf_data(buf); 18610 WMITLV_SET_HDR(&cmd->tlv_header, 18611 WMITLV_TAG_STRUC_wmi_vdev_get_mws_coex_info_cmd_fixed_param, 18612 WMITLV_GET_STRUCT_TLVLEN 18613 (wmi_vdev_get_mws_coex_info_cmd_fixed_param)); 18614 cmd->vdev_id = vdev_id; 18615 cmd->cmd_id = cmd_id; 18616 wmi_mtrace(WMI_VDEV_GET_MWS_COEX_INFO_CMDID, vdev_id, 0); 18617 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 18618 WMI_VDEV_GET_MWS_COEX_INFO_CMDID); 18619 if (QDF_IS_STATUS_ERROR(ret)) { 18620 wmi_err("Failed to send set param command ret = %d", ret); 18621 wmi_buf_free(buf); 18622 } 18623 return ret; 18624 } 18625 #endif 18626 18627 #ifdef FEATURE_MEC_OFFLOAD 18628 static QDF_STATUS 18629 send_pdev_set_mec_timer_cmd_tlv(struct wmi_unified *wmi_handle, 18630 struct set_mec_timer_params *param) 18631 { 18632 wmi_pdev_mec_aging_timer_config_cmd_fixed_param *cmd; 18633 wmi_buf_t buf; 18634 int32_t len = sizeof(*cmd); 18635 18636 buf = wmi_buf_alloc(wmi_handle, len); 18637 if (!buf) { 18638 wmi_err("wmi_buf_alloc failed"); 18639 return QDF_STATUS_E_FAILURE; 18640 } 18641 cmd = (wmi_pdev_mec_aging_timer_config_cmd_fixed_param *) 18642 wmi_buf_data(buf); 18643 WMITLV_SET_HDR(&cmd->tlv_header, 18644 WMITLV_TAG_STRUC_wmi_pdev_mec_aging_timer_config_cmd_fixed_param, 18645 WMITLV_GET_STRUCT_TLVLEN( 18646 wmi_pdev_mec_aging_timer_config_cmd_fixed_param)); 18647 cmd->pdev_id = param->pdev_id; 18648 cmd->mec_aging_timer_threshold = param->mec_aging_timer_threshold; 18649 18650 wmi_mtrace(WMI_PDEV_MEC_AGING_TIMER_CONFIG_CMDID, param->vdev_id, 0); 18651 if (wmi_unified_cmd_send(wmi_handle, buf, len, 18652 WMI_PDEV_MEC_AGING_TIMER_CONFIG_CMDID)) { 18653 wmi_err("Failed to set mec aging timer param"); 18654 wmi_buf_free(buf); 18655 return QDF_STATUS_E_FAILURE; 18656 } 18657 18658 return QDF_STATUS_SUCCESS; 18659 } 18660 #endif 18661 18662 #ifdef WIFI_POS_CONVERGED 18663 /** 18664 * extract_oem_response_param_tlv() - Extract oem response params 18665 * @wmi_handle: wmi handle 18666 * @resp_buf: response buffer 18667 * @oem_resp_param: pointer to hold oem response params 18668 * 18669 * Return: QDF_STATUS_SUCCESS on success or proper error code. 18670 */ 18671 static QDF_STATUS 18672 extract_oem_response_param_tlv(wmi_unified_t wmi_handle, void *resp_buf, 18673 struct wmi_oem_response_param *oem_resp_param) 18674 { 18675 uint64_t temp_addr; 18676 WMI_OEM_RESPONSE_EVENTID_param_tlvs *param_buf = 18677 (WMI_OEM_RESPONSE_EVENTID_param_tlvs *)resp_buf; 18678 18679 if (!param_buf) { 18680 wmi_err("Invalid OEM response"); 18681 return QDF_STATUS_E_INVAL; 18682 } 18683 18684 if (param_buf->num_data) { 18685 oem_resp_param->num_data1 = param_buf->num_data; 18686 oem_resp_param->data_1 = param_buf->data; 18687 } 18688 18689 if (param_buf->num_data2) { 18690 oem_resp_param->num_data2 = param_buf->num_data2; 18691 oem_resp_param->data_2 = param_buf->data2; 18692 } 18693 18694 if (param_buf->indirect_data) { 18695 oem_resp_param->indirect_data.pdev_id = 18696 param_buf->indirect_data->pdev_id; 18697 temp_addr = (param_buf->indirect_data->addr_hi) & 0xf; 18698 oem_resp_param->indirect_data.addr = 18699 param_buf->indirect_data->addr_lo + 18700 ((uint64_t)temp_addr << 32); 18701 oem_resp_param->indirect_data.len = 18702 param_buf->indirect_data->len; 18703 } 18704 18705 return QDF_STATUS_SUCCESS; 18706 } 18707 #endif /* WIFI_POS_CONVERGED */ 18708 18709 #if defined(WIFI_POS_CONVERGED) && defined(WLAN_FEATURE_RTT_11AZ_SUPPORT) 18710 #define WLAN_PASN_LTF_KEY_SEED_REQUIRED 0x2 18711 18712 static QDF_STATUS 18713 extract_pasn_peer_create_req_event_tlv(wmi_unified_t wmi_handle, void *evt_buf, 18714 struct wifi_pos_pasn_peer_data *dst) 18715 { 18716 WMI_RTT_PASN_PEER_CREATE_REQ_EVENTID_param_tlvs *param_buf; 18717 wmi_rtt_pasn_peer_create_req_event_fixed_param *fixed_param; 18718 wmi_rtt_pasn_peer_create_req_param *buf; 18719 uint8_t security_mode, i; 18720 18721 param_buf = (WMI_RTT_PASN_PEER_CREATE_REQ_EVENTID_param_tlvs *)evt_buf; 18722 if (!param_buf) { 18723 wmi_err("Invalid peer_create req buffer"); 18724 return QDF_STATUS_E_INVAL; 18725 } 18726 18727 fixed_param = param_buf->fixed_param; 18728 18729 if (param_buf->num_rtt_pasn_peer_param > 18730 ((WMI_SVC_MSG_MAX_SIZE - sizeof(*fixed_param)) / 18731 sizeof(wmi_rtt_pasn_peer_create_req_param))) { 18732 wmi_err("Invalid TLV size"); 18733 return QDF_STATUS_E_INVAL; 18734 } 18735 18736 if (!param_buf->num_rtt_pasn_peer_param || 18737 param_buf->num_rtt_pasn_peer_param > WLAN_MAX_11AZ_PEERS) { 18738 wmi_err("Invalid num TLV:%d", 18739 param_buf->num_rtt_pasn_peer_param); 18740 return QDF_STATUS_E_INVAL; 18741 } 18742 18743 dst->vdev_id = fixed_param->vdev_id; 18744 if (dst->vdev_id >= WLAN_UMAC_PDEV_MAX_VDEVS) { 18745 wmi_err("Invalid vdev id:%d", dst->vdev_id); 18746 return QDF_STATUS_E_INVAL; 18747 } 18748 18749 buf = param_buf->rtt_pasn_peer_param; 18750 if (!buf) { 18751 wmi_err("NULL peer param TLV"); 18752 return QDF_STATUS_E_INVAL; 18753 } 18754 18755 for (i = 0; i < param_buf->num_rtt_pasn_peer_param; i++) { 18756 WMI_MAC_ADDR_TO_CHAR_ARRAY(&buf->self_mac_addr, 18757 dst->peer_info[i].self_mac.bytes); 18758 WMI_MAC_ADDR_TO_CHAR_ARRAY(&buf->dest_mac_addr, 18759 dst->peer_info[i].peer_mac.bytes); 18760 security_mode = WMI_RTT_PASN_PEER_CREATE_SECURITY_MODE_GET( 18761 buf->control_flag); 18762 if (security_mode) 18763 dst->peer_info[i].peer_type = 18764 WLAN_WIFI_POS_PASN_SECURE_PEER; 18765 else 18766 dst->peer_info[i].peer_type = 18767 WLAN_WIFI_POS_PASN_UNSECURE_PEER; 18768 if (security_mode & WLAN_PASN_LTF_KEY_SEED_REQUIRED) 18769 dst->peer_info[i].is_ltf_keyseed_required = true; 18770 18771 dst->peer_info[i].force_self_mac_usage = 18772 WMI_RTT_PASN_PEER_CREATE_FORCE_SELF_MAC_USE_GET( 18773 buf->control_flag); 18774 dst->num_peers++; 18775 buf++; 18776 } 18777 18778 return QDF_STATUS_SUCCESS; 18779 } 18780 18781 static QDF_STATUS 18782 extract_pasn_peer_delete_req_event_tlv(wmi_unified_t wmi_handle, void *evt_buf, 18783 struct wifi_pos_pasn_peer_data *dst) 18784 { 18785 WMI_RTT_PASN_PEER_DELETE_EVENTID_param_tlvs *param_buf; 18786 wmi_rtt_pasn_peer_delete_event_fixed_param *fixed_param; 18787 wmi_rtt_pasn_peer_delete_param *buf; 18788 uint8_t i; 18789 18790 param_buf = (WMI_RTT_PASN_PEER_DELETE_EVENTID_param_tlvs *)evt_buf; 18791 if (!param_buf) { 18792 wmi_err("Invalid peer_delete evt buffer"); 18793 return QDF_STATUS_E_INVAL; 18794 } 18795 18796 fixed_param = param_buf->fixed_param; 18797 18798 if (param_buf->num_rtt_pasn_peer_param > 18799 ((WMI_SVC_MSG_MAX_SIZE - sizeof(*fixed_param)) / 18800 sizeof(wmi_rtt_pasn_peer_delete_param))) { 18801 wmi_err("Invalid TLV size"); 18802 return QDF_STATUS_E_INVAL; 18803 } 18804 18805 if (!param_buf->num_rtt_pasn_peer_param || 18806 param_buf->num_rtt_pasn_peer_param > WLAN_MAX_11AZ_PEERS) { 18807 wmi_err("Invalid num TLV:%d", 18808 param_buf->num_rtt_pasn_peer_param); 18809 return QDF_STATUS_E_INVAL; 18810 } 18811 18812 dst->vdev_id = fixed_param->vdev_id; 18813 if (dst->vdev_id >= WLAN_UMAC_PDEV_MAX_VDEVS) { 18814 wmi_err("Invalid vdev id:%d", dst->vdev_id); 18815 return QDF_STATUS_E_INVAL; 18816 } 18817 18818 buf = param_buf->rtt_pasn_peer_param; 18819 if (!buf) { 18820 wmi_err("NULL peer param TLV"); 18821 return QDF_STATUS_E_INVAL; 18822 } 18823 18824 for (i = 0; i < param_buf->num_rtt_pasn_peer_param; i++) { 18825 WMI_MAC_ADDR_TO_CHAR_ARRAY(&buf->peer_mac_addr, 18826 dst->peer_info[i].peer_mac.bytes); 18827 dst->peer_info[i].control_flags = buf->control_flag; 18828 18829 dst->num_peers++; 18830 buf++; 18831 } 18832 18833 return QDF_STATUS_SUCCESS; 18834 } 18835 18836 static QDF_STATUS 18837 send_rtt_pasn_auth_status_cmd_tlv(wmi_unified_t wmi_handle, 18838 struct wlan_pasn_auth_status *data) 18839 { 18840 QDF_STATUS status; 18841 wmi_buf_t buf; 18842 wmi_rtt_pasn_auth_status_cmd_fixed_param *fixed_param; 18843 uint8_t *buf_ptr; 18844 uint8_t i; 18845 size_t len = sizeof(*fixed_param) + 18846 data->num_peers * sizeof(wmi_rtt_pasn_auth_status_param) + 18847 WMI_TLV_HDR_SIZE; 18848 18849 buf = wmi_buf_alloc(wmi_handle, len); 18850 if (!buf) { 18851 wmi_err("wmi_buf_alloc failed"); 18852 return QDF_STATUS_E_FAILURE; 18853 } 18854 buf_ptr = (uint8_t *)wmi_buf_data(buf); 18855 fixed_param = 18856 (wmi_rtt_pasn_auth_status_cmd_fixed_param *)wmi_buf_data(buf); 18857 WMITLV_SET_HDR(&fixed_param->tlv_header, 18858 WMITLV_TAG_STRUC_wmi_rtt_pasn_auth_status_cmd_fixed_param, 18859 WMITLV_GET_STRUCT_TLVLEN( 18860 wmi_rtt_pasn_auth_status_cmd_fixed_param)); 18861 buf_ptr += sizeof(*fixed_param); 18862 18863 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 18864 (data->num_peers * 18865 sizeof(wmi_rtt_pasn_auth_status_param))); 18866 buf_ptr += WMI_TLV_HDR_SIZE; 18867 18868 for (i = 0; i < data->num_peers; i++) { 18869 wmi_rtt_pasn_auth_status_param *auth_status_tlv = 18870 (wmi_rtt_pasn_auth_status_param *)buf_ptr; 18871 18872 WMITLV_SET_HDR(&auth_status_tlv->tlv_header, 18873 WMITLV_TAG_STRUC_wmi_rtt_pasn_auth_status_param, 18874 WMITLV_GET_STRUCT_TLVLEN(wmi_rtt_pasn_auth_status_param)); 18875 18876 WMI_CHAR_ARRAY_TO_MAC_ADDR(data->auth_status[i].peer_mac.bytes, 18877 &auth_status_tlv->peer_mac_addr); 18878 WMI_CHAR_ARRAY_TO_MAC_ADDR(data->auth_status[i].self_mac.bytes, 18879 &auth_status_tlv->source_mac_addr); 18880 auth_status_tlv->status = data->auth_status[i].status; 18881 wmi_debug("peer_mac: " QDF_MAC_ADDR_FMT " self_mac:" QDF_MAC_ADDR_FMT " status:%d", 18882 QDF_MAC_ADDR_REF(data->auth_status[i].peer_mac.bytes), 18883 QDF_MAC_ADDR_REF(data->auth_status[i].self_mac.bytes), 18884 auth_status_tlv->status); 18885 18886 buf_ptr += sizeof(wmi_rtt_pasn_auth_status_param); 18887 } 18888 18889 wmi_mtrace(WMI_RTT_PASN_AUTH_STATUS_CMD, 0, 0); 18890 status = wmi_unified_cmd_send(wmi_handle, buf, len, 18891 WMI_RTT_PASN_AUTH_STATUS_CMD); 18892 if (QDF_IS_STATUS_ERROR(status)) { 18893 wmi_err("Failed to send Auth status command ret = %d", status); 18894 wmi_buf_free(buf); 18895 } 18896 18897 return status; 18898 } 18899 18900 static QDF_STATUS 18901 send_rtt_pasn_deauth_cmd_tlv(wmi_unified_t wmi_handle, 18902 struct qdf_mac_addr *peer_mac) 18903 { 18904 QDF_STATUS status; 18905 wmi_buf_t buf; 18906 wmi_rtt_pasn_deauth_cmd_fixed_param *fixed_param; 18907 size_t len = sizeof(*fixed_param); 18908 18909 buf = wmi_buf_alloc(wmi_handle, len); 18910 if (!buf) { 18911 wmi_err("wmi_buf_alloc failed"); 18912 return QDF_STATUS_E_FAILURE; 18913 } 18914 fixed_param = 18915 (wmi_rtt_pasn_deauth_cmd_fixed_param *)wmi_buf_data(buf); 18916 WMITLV_SET_HDR(&fixed_param->tlv_header, 18917 WMITLV_TAG_STRUC_wmi_rtt_pasn_deauth_cmd_fixed_param, 18918 WMITLV_GET_STRUCT_TLVLEN( 18919 wmi_rtt_pasn_deauth_cmd_fixed_param)); 18920 WMI_CHAR_ARRAY_TO_MAC_ADDR(peer_mac->bytes, 18921 &fixed_param->peer_mac_addr); 18922 18923 wmi_mtrace(WMI_RTT_PASN_DEAUTH_CMD, 0, 0); 18924 status = wmi_unified_cmd_send(wmi_handle, buf, len, 18925 WMI_RTT_PASN_DEAUTH_CMD); 18926 if (QDF_IS_STATUS_ERROR(status)) { 18927 wmi_err("Failed to send pasn deauth command ret = %d", status); 18928 wmi_buf_free(buf); 18929 } 18930 18931 return status; 18932 } 18933 #endif /* WLAN_FEATURE_RTT_11AZ_SUPPORT */ 18934 18935 static QDF_STATUS 18936 send_vdev_set_ltf_key_seed_cmd_tlv(wmi_unified_t wmi_handle, 18937 struct wlan_crypto_ltf_keyseed_data *data) 18938 { 18939 QDF_STATUS status; 18940 wmi_buf_t buf; 18941 wmi_vdev_set_ltf_key_seed_cmd_fixed_param *fixed_param; 18942 uint8_t *buf_ptr; 18943 size_t len = sizeof(*fixed_param) + data->key_seed_len + 18944 WMI_TLV_HDR_SIZE; 18945 18946 buf = wmi_buf_alloc(wmi_handle, len); 18947 if (!buf) { 18948 wmi_err("wmi_buf_alloc failed"); 18949 return QDF_STATUS_E_FAILURE; 18950 } 18951 18952 buf_ptr = (uint8_t *)wmi_buf_data(buf); 18953 fixed_param = 18954 (wmi_vdev_set_ltf_key_seed_cmd_fixed_param *)wmi_buf_data(buf); 18955 WMITLV_SET_HDR(&fixed_param->tlv_header, 18956 WMITLV_TAG_STRUC_wmi_vdev_set_ltf_key_seed_cmd_fixed_param, 18957 WMITLV_GET_STRUCT_TLVLEN( 18958 wmi_vdev_set_ltf_key_seed_cmd_fixed_param)); 18959 18960 fixed_param->vdev_id = data->vdev_id; 18961 WMI_CHAR_ARRAY_TO_MAC_ADDR(data->peer_mac_addr.bytes, 18962 &fixed_param->peer_macaddr); 18963 fixed_param->key_seed_len = data->key_seed_len; 18964 fixed_param->rsn_authmode = data->rsn_authmode; 18965 18966 buf_ptr += sizeof(*fixed_param); 18967 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, 18968 (fixed_param->key_seed_len * sizeof(A_UINT8))); 18969 buf_ptr += WMI_TLV_HDR_SIZE; 18970 18971 qdf_mem_copy(buf_ptr, data->key_seed, fixed_param->key_seed_len); 18972 18973 wmi_mtrace(WMI_VDEV_SET_LTF_KEY_SEED_CMDID, 0, 0); 18974 status = wmi_unified_cmd_send(wmi_handle, buf, len, 18975 WMI_VDEV_SET_LTF_KEY_SEED_CMDID); 18976 if (QDF_IS_STATUS_ERROR(status)) { 18977 wmi_err("Failed to send ltf keyseed command ret = %d", status); 18978 wmi_buf_free(buf); 18979 } 18980 18981 return status; 18982 } 18983 18984 /** 18985 * extract_hw_mode_resp_event_status_tlv() - Extract HW mode change status 18986 * @wmi_handle: wmi handle 18987 * @evt_buf: pointer to event buffer 18988 * @cmd_status: status of HW mode change command 18989 * 18990 * Return: QDF_STATUS_SUCCESS on success or proper error code. 18991 */ 18992 static QDF_STATUS 18993 extract_hw_mode_resp_event_status_tlv(wmi_unified_t wmi_handle, void *evt_buf, 18994 uint32_t *cmd_status) 18995 { 18996 WMI_PDEV_SET_HW_MODE_RESP_EVENTID_param_tlvs *param_buf; 18997 wmi_pdev_set_hw_mode_response_event_fixed_param *fixed_param; 18998 18999 param_buf = (WMI_PDEV_SET_HW_MODE_RESP_EVENTID_param_tlvs *)evt_buf; 19000 if (!param_buf) { 19001 wmi_err("Invalid mode change event buffer"); 19002 return QDF_STATUS_E_INVAL; 19003 } 19004 19005 fixed_param = param_buf->fixed_param; 19006 if (!fixed_param) { 19007 wmi_err("Invalid fixed param"); 19008 return QDF_STATUS_E_INVAL; 19009 } 19010 19011 *cmd_status = fixed_param->status; 19012 return QDF_STATUS_SUCCESS; 19013 } 19014 19015 /** 19016 * extract_rf_path_resp_tlv() - Extract RF path change status 19017 * @wmi_handle: wmi handle 19018 * @evt_buf: pointer to event buffer 19019 * @cmd_status: status of RF path change request 19020 * 19021 * Return: QDF_STATUS_SUCCESS on success or proper error code. 19022 */ 19023 static QDF_STATUS 19024 extract_rf_path_resp_tlv(wmi_unified_t wmi_handle, void *evt_buf, 19025 uint32_t *cmd_status) 19026 { 19027 WMI_PDEV_SET_RF_PATH_RESP_EVENTID_param_tlvs *param_buf; 19028 wmi_pdev_set_rf_path_event_fixed_param *fixed_param; 19029 19030 param_buf = (WMI_PDEV_SET_RF_PATH_RESP_EVENTID_param_tlvs *)evt_buf; 19031 if (!param_buf) { 19032 wmi_err("Invalid RF path event buffer"); 19033 return QDF_STATUS_E_INVAL; 19034 } 19035 19036 fixed_param = param_buf->fixed_param; 19037 if (!fixed_param) { 19038 wmi_err("Invalid fixed param"); 19039 return QDF_STATUS_E_INVAL; 19040 } 19041 19042 *cmd_status = fixed_param->status; 19043 return QDF_STATUS_SUCCESS; 19044 } 19045 19046 #ifdef FEATURE_ANI_LEVEL_REQUEST 19047 static QDF_STATUS send_ani_level_cmd_tlv(wmi_unified_t wmi_handle, 19048 uint32_t *freqs, 19049 uint8_t num_freqs) 19050 { 19051 wmi_buf_t buf; 19052 wmi_get_channel_ani_cmd_fixed_param *cmd; 19053 QDF_STATUS ret; 19054 uint32_t len; 19055 A_UINT32 *chan_list; 19056 uint8_t i, *buf_ptr; 19057 19058 len = sizeof(wmi_get_channel_ani_cmd_fixed_param) + 19059 WMI_TLV_HDR_SIZE + 19060 num_freqs * sizeof(A_UINT32); 19061 19062 buf = wmi_buf_alloc(wmi_handle, len); 19063 if (!buf) 19064 return QDF_STATUS_E_FAILURE; 19065 19066 buf_ptr = (uint8_t *)wmi_buf_data(buf); 19067 cmd = (wmi_get_channel_ani_cmd_fixed_param *)buf_ptr; 19068 WMITLV_SET_HDR(&cmd->tlv_header, 19069 WMITLV_TAG_STRUC_wmi_get_channel_ani_cmd_fixed_param, 19070 WMITLV_GET_STRUCT_TLVLEN( 19071 wmi_get_channel_ani_cmd_fixed_param)); 19072 19073 buf_ptr += sizeof(wmi_get_channel_ani_cmd_fixed_param); 19074 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, 19075 (num_freqs * sizeof(A_UINT32))); 19076 19077 chan_list = (A_UINT32 *)(buf_ptr + WMI_TLV_HDR_SIZE); 19078 for (i = 0; i < num_freqs; i++) { 19079 chan_list[i] = freqs[i]; 19080 wmi_debug("Requesting ANI for channel[%d]", chan_list[i]); 19081 } 19082 19083 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 19084 WMI_GET_CHANNEL_ANI_CMDID); 19085 19086 if (QDF_IS_STATUS_ERROR(ret)) { 19087 wmi_err("WMI_GET_CHANNEL_ANI_CMDID send error %d", ret); 19088 wmi_buf_free(buf); 19089 } 19090 19091 return ret; 19092 } 19093 19094 static QDF_STATUS extract_ani_level_tlv(uint8_t *evt_buf, 19095 struct wmi_host_ani_level_event **info, 19096 uint32_t *num_freqs) 19097 { 19098 WMI_GET_CHANNEL_ANI_EVENTID_param_tlvs *param_buf; 19099 wmi_get_channel_ani_event_fixed_param *fixed_param; 19100 wmi_channel_ani_info_tlv_param *tlv_params; 19101 uint8_t *buf_ptr, i; 19102 19103 param_buf = (WMI_GET_CHANNEL_ANI_EVENTID_param_tlvs *)evt_buf; 19104 if (!param_buf) { 19105 wmi_err("Invalid ani level event buffer"); 19106 return QDF_STATUS_E_INVAL; 19107 } 19108 19109 fixed_param = 19110 (wmi_get_channel_ani_event_fixed_param *)param_buf->fixed_param; 19111 if (!fixed_param) { 19112 wmi_err("Invalid fixed param"); 19113 return QDF_STATUS_E_INVAL; 19114 } 19115 19116 buf_ptr = (uint8_t *)fixed_param; 19117 buf_ptr += sizeof(wmi_get_channel_ani_event_fixed_param); 19118 buf_ptr += WMI_TLV_HDR_SIZE; 19119 19120 *num_freqs = param_buf->num_ani_info; 19121 if (*num_freqs > MAX_NUM_FREQS_FOR_ANI_LEVEL) { 19122 wmi_err("Invalid number of freqs received"); 19123 return QDF_STATUS_E_INVAL; 19124 } 19125 19126 *info = qdf_mem_malloc(*num_freqs * 19127 sizeof(struct wmi_host_ani_level_event)); 19128 if (!(*info)) 19129 return QDF_STATUS_E_NOMEM; 19130 19131 tlv_params = (wmi_channel_ani_info_tlv_param *)buf_ptr; 19132 for (i = 0; i < param_buf->num_ani_info; i++) { 19133 (*info)[i].ani_level = tlv_params->ani_level; 19134 (*info)[i].chan_freq = tlv_params->chan_freq; 19135 tlv_params++; 19136 } 19137 19138 return QDF_STATUS_SUCCESS; 19139 } 19140 #endif /* FEATURE_ANI_LEVEL_REQUEST */ 19141 19142 #ifdef WLAN_FEATURE_ROAM_OFFLOAD 19143 /** 19144 * convert_wtc_scan_mode() - Function to convert TLV specific 19145 * ROAM_TRIGGER_SCAN_MODE scan mode to unified Roam trigger scan mode enum 19146 * @scan_mode: scan freq scheme coming from firmware 19147 * 19148 * Return: ROAM_TRIGGER_SCAN_MODE 19149 */ 19150 static enum roam_scan_freq_scheme 19151 convert_wtc_scan_mode(WMI_ROAM_TRIGGER_SCAN_MODE scan_mode) 19152 { 19153 switch (scan_mode) { 19154 case ROAM_TRIGGER_SCAN_MODE_NO_SCAN_DISCONNECTION: 19155 return ROAM_SCAN_FREQ_SCHEME_NO_SCAN; 19156 case ROAM_TRIGGER_SCAN_MODE_PARTIAL: 19157 return ROAM_SCAN_FREQ_SCHEME_PARTIAL_SCAN; 19158 case ROAM_TRIGGER_SCAN_MODE_FULL: 19159 return ROAM_SCAN_FREQ_SCHEME_FULL_SCAN; 19160 default: 19161 return ROAM_SCAN_FREQ_SCHEME_NONE; 19162 } 19163 } 19164 19165 static uint32_t wmi_convert_fw_to_cm_trig_reason(uint32_t fw_trig_reason) 19166 { 19167 switch (fw_trig_reason) { 19168 case WMI_ROAM_TRIGGER_REASON_NONE: 19169 return ROAM_TRIGGER_REASON_NONE; 19170 case WMI_ROAM_TRIGGER_REASON_PER: 19171 return ROAM_TRIGGER_REASON_PER; 19172 case WMI_ROAM_TRIGGER_REASON_BMISS: 19173 return ROAM_TRIGGER_REASON_BMISS; 19174 case WMI_ROAM_TRIGGER_REASON_LOW_RSSI: 19175 return ROAM_TRIGGER_REASON_LOW_RSSI; 19176 case WMI_ROAM_TRIGGER_REASON_HIGH_RSSI: 19177 return ROAM_TRIGGER_REASON_HIGH_RSSI; 19178 case WMI_ROAM_TRIGGER_REASON_PERIODIC: 19179 return ROAM_TRIGGER_REASON_PERIODIC; 19180 case WMI_ROAM_TRIGGER_REASON_MAWC: 19181 return ROAM_TRIGGER_REASON_MAWC; 19182 case WMI_ROAM_TRIGGER_REASON_DENSE: 19183 return ROAM_TRIGGER_REASON_DENSE; 19184 case WMI_ROAM_TRIGGER_REASON_BACKGROUND: 19185 return ROAM_TRIGGER_REASON_BACKGROUND; 19186 case WMI_ROAM_TRIGGER_REASON_FORCED: 19187 return ROAM_TRIGGER_REASON_FORCED; 19188 case WMI_ROAM_TRIGGER_REASON_BTM: 19189 return ROAM_TRIGGER_REASON_BTM; 19190 case WMI_ROAM_TRIGGER_REASON_UNIT_TEST: 19191 return ROAM_TRIGGER_REASON_UNIT_TEST; 19192 case WMI_ROAM_TRIGGER_REASON_BSS_LOAD: 19193 return ROAM_TRIGGER_REASON_BSS_LOAD; 19194 case WMI_ROAM_TRIGGER_REASON_DEAUTH: 19195 return ROAM_TRIGGER_REASON_DEAUTH; 19196 case WMI_ROAM_TRIGGER_REASON_IDLE: 19197 return ROAM_TRIGGER_REASON_IDLE; 19198 case WMI_ROAM_TRIGGER_REASON_STA_KICKOUT: 19199 return ROAM_TRIGGER_REASON_STA_KICKOUT; 19200 case WMI_ROAM_TRIGGER_REASON_ESS_RSSI: 19201 return ROAM_TRIGGER_REASON_ESS_RSSI; 19202 case WMI_ROAM_TRIGGER_REASON_WTC_BTM: 19203 return ROAM_TRIGGER_REASON_WTC_BTM; 19204 case WMI_ROAM_TRIGGER_REASON_PMK_TIMEOUT: 19205 return ROAM_TRIGGER_REASON_PMK_TIMEOUT; 19206 case WMI_ROAM_TRIGGER_REASON_BTC: 19207 return ROAM_TRIGGER_REASON_BTC; 19208 case WMI_ROAM_TRIGGER_EXT_REASON_MAX: 19209 return ROAM_TRIGGER_REASON_MAX; 19210 default: 19211 return ROAM_TRIGGER_REASON_NONE; 19212 } 19213 } 19214 19215 /** 19216 * extract_roam_11kv_candidate_info - Extract btm candidate info 19217 * @wmi_handle: wmi_handle 19218 * @evt_buf: Event buffer 19219 * @dst_info: Destination buffer 19220 * @btm_idx: BTM index 19221 * @num_cand: Number of candidates 19222 * 19223 * Return: QDF_STATUS 19224 */ 19225 static QDF_STATUS 19226 extract_roam_11kv_candidate_info(wmi_unified_t wmi_handle, void *evt_buf, 19227 struct wmi_btm_req_candidate_info *dst_info, 19228 uint8_t btm_idx, uint16_t num_cand) 19229 { 19230 WMI_ROAM_STATS_EVENTID_param_tlvs *param_buf; 19231 wmi_roam_btm_request_candidate_info *src_data; 19232 uint8_t i; 19233 19234 param_buf = (WMI_ROAM_STATS_EVENTID_param_tlvs *)evt_buf; 19235 if (!param_buf || !param_buf->roam_btm_request_candidate_info || 19236 !param_buf->num_roam_btm_request_candidate_info || 19237 (btm_idx + 19238 num_cand) > param_buf->num_roam_btm_request_candidate_info) 19239 return QDF_STATUS_SUCCESS; 19240 19241 src_data = ¶m_buf->roam_btm_request_candidate_info[btm_idx]; 19242 if (num_cand > WLAN_MAX_BTM_CANDIDATE) 19243 num_cand = WLAN_MAX_BTM_CANDIDATE; 19244 for (i = 0; i < num_cand; i++) { 19245 WMI_MAC_ADDR_TO_CHAR_ARRAY(&src_data->btm_candidate_bssid, 19246 dst_info->candidate_bssid.bytes); 19247 dst_info->preference = src_data->preference; 19248 src_data++; 19249 dst_info++; 19250 } 19251 19252 return QDF_STATUS_SUCCESS; 19253 } 19254 19255 static enum roam_trigger_sub_reason 19256 wmi_convert_roam_sub_reason(WMI_ROAM_TRIGGER_SUB_REASON_ID subreason) 19257 { 19258 switch (subreason) { 19259 case WMI_ROAM_TRIGGER_SUB_REASON_PERIODIC_TIMER: 19260 return ROAM_TRIGGER_SUB_REASON_PERIODIC_TIMER; 19261 case WMI_ROAM_TRIGGER_SUB_REASON_INACTIVITY_TIMER: 19262 return ROAM_TRIGGER_SUB_REASON_INACTIVITY_TIMER_LOW_RSSI; 19263 case WMI_ROAM_TRIGGER_SUB_REASON_BTM_DI_TIMER: 19264 return ROAM_TRIGGER_SUB_REASON_BTM_DI_TIMER; 19265 case WMI_ROAM_TRIGGER_SUB_REASON_FULL_SCAN: 19266 return ROAM_TRIGGER_SUB_REASON_FULL_SCAN; 19267 case WMI_ROAM_TRIGGER_SUB_REASON_LOW_RSSI_PERIODIC: 19268 return ROAM_TRIGGER_SUB_REASON_LOW_RSSI_PERIODIC; 19269 case WMI_ROAM_TRIGGER_SUB_REASON_CU_PERIODIC: 19270 return ROAM_TRIGGER_SUB_REASON_CU_PERIODIC; 19271 case WMI_ROAM_TRIGGER_SUB_REASON_PERIODIC_TIMER_AFTER_INACTIVITY: 19272 return ROAM_TRIGGER_SUB_REASON_PERIODIC_TIMER_AFTER_INACTIVITY; 19273 case WMI_ROAM_TRIGGER_SUB_REASON_PERIODIC_TIMER_AFTER_INACTIVITY_CU: 19274 return ROAM_TRIGGER_SUB_REASON_PERIODIC_TIMER_AFTER_INACTIVITY_CU; 19275 case WMI_ROAM_TRIGGER_SUB_REASON_INACTIVITY_TIMER_CU: 19276 return ROAM_TRIGGER_SUB_REASON_INACTIVITY_TIMER_CU; 19277 default: 19278 break; 19279 } 19280 19281 return 0; 19282 } 19283 19284 /** 19285 * wlan_roam_fail_reason_code() - Convert FW enum to Host enum 19286 * @wmi_roam_fail_reason: roam fail enum 19287 * 19288 * Return: Roaming failure reason codes 19289 */ 19290 static enum wlan_roam_failure_reason_code 19291 wlan_roam_fail_reason_code(uint16_t wmi_roam_fail_reason) 19292 { 19293 switch (wmi_roam_fail_reason) { 19294 case WMI_ROAM_FAIL_REASON_NO_SCAN_START: 19295 return ROAM_FAIL_REASON_NO_SCAN_START; 19296 case WMI_ROAM_FAIL_REASON_NO_AP_FOUND: 19297 return ROAM_FAIL_REASON_NO_AP_FOUND; 19298 case WMI_ROAM_FAIL_REASON_NO_CAND_AP_FOUND: 19299 return ROAM_FAIL_REASON_NO_CAND_AP_FOUND; 19300 case WMI_ROAM_FAIL_REASON_HOST: 19301 return ROAM_FAIL_REASON_HOST; 19302 case WMI_ROAM_FAIL_REASON_AUTH_SEND: 19303 return ROAM_FAIL_REASON_AUTH_SEND; 19304 case WMI_ROAM_FAIL_REASON_AUTH_RECV: 19305 return ROAM_FAIL_REASON_AUTH_RECV; 19306 case WMI_ROAM_FAIL_REASON_NO_AUTH_RESP: 19307 return ROAM_FAIL_REASON_NO_AUTH_RESP; 19308 case WMI_ROAM_FAIL_REASON_REASSOC_SEND: 19309 return ROAM_FAIL_REASON_REASSOC_SEND; 19310 case WMI_ROAM_FAIL_REASON_REASSOC_RECV: 19311 return ROAM_FAIL_REASON_REASSOC_RECV; 19312 case WMI_ROAM_FAIL_REASON_NO_REASSOC_RESP: 19313 return ROAM_FAIL_REASON_NO_REASSOC_RESP; 19314 case WMI_ROAM_FAIL_REASON_EAPOL_TIMEOUT: 19315 return ROAM_FAIL_REASON_EAPOL_TIMEOUT; 19316 case WMI_ROAM_FAIL_REASON_MLME: 19317 return ROAM_FAIL_REASON_MLME; 19318 case WMI_ROAM_FAIL_REASON_INTERNAL_ABORT: 19319 return ROAM_FAIL_REASON_INTERNAL_ABORT; 19320 case WMI_ROAM_FAIL_REASON_SCAN_START: 19321 return ROAM_FAIL_REASON_SCAN_START; 19322 case WMI_ROAM_FAIL_REASON_AUTH_NO_ACK: 19323 return ROAM_FAIL_REASON_AUTH_NO_ACK; 19324 case WMI_ROAM_FAIL_REASON_AUTH_INTERNAL_DROP: 19325 return ROAM_FAIL_REASON_AUTH_INTERNAL_DROP; 19326 case WMI_ROAM_FAIL_REASON_REASSOC_NO_ACK: 19327 return ROAM_FAIL_REASON_REASSOC_NO_ACK; 19328 case WMI_ROAM_FAIL_REASON_REASSOC_INTERNAL_DROP: 19329 return ROAM_FAIL_REASON_REASSOC_INTERNAL_DROP; 19330 case WMI_ROAM_FAIL_REASON_EAPOL_M2_SEND: 19331 return ROAM_FAIL_REASON_EAPOL_M2_SEND; 19332 case WMI_ROAM_FAIL_REASON_EAPOL_M2_INTERNAL_DROP: 19333 return ROAM_FAIL_REASON_EAPOL_M2_INTERNAL_DROP; 19334 case WMI_ROAM_FAIL_REASON_EAPOL_M2_NO_ACK: 19335 return ROAM_FAIL_REASON_EAPOL_M2_NO_ACK; 19336 case WMI_ROAM_FAIL_REASON_EAPOL_M3_TIMEOUT: 19337 return ROAM_FAIL_REASON_EAPOL_M3_TIMEOUT; 19338 case WMI_ROAM_FAIL_REASON_EAPOL_M4_SEND: 19339 return ROAM_FAIL_REASON_EAPOL_M4_SEND; 19340 case WMI_ROAM_FAIL_REASON_EAPOL_M4_INTERNAL_DROP: 19341 return ROAM_FAIL_REASON_EAPOL_M4_INTERNAL_DROP; 19342 case WMI_ROAM_FAIL_REASON_EAPOL_M4_NO_ACK: 19343 return ROAM_FAIL_REASON_EAPOL_M4_NO_ACK; 19344 case WMI_ROAM_FAIL_REASON_NO_SCAN_FOR_FINAL_BMISS: 19345 return ROAM_FAIL_REASON_NO_SCAN_FOR_FINAL_BMISS; 19346 case WMI_ROAM_FAIL_REASON_DISCONNECT: 19347 return ROAM_FAIL_REASON_DISCONNECT; 19348 case WMI_ROAM_FAIL_REASON_SYNC: 19349 return ROAM_FAIL_REASON_SYNC; 19350 case WMI_ROAM_FAIL_REASON_SAE_INVALID_PMKID: 19351 return ROAM_FAIL_REASON_SAE_INVALID_PMKID; 19352 case WMI_ROAM_FAIL_REASON_SAE_PREAUTH_TIMEOUT: 19353 return ROAM_FAIL_REASON_SAE_PREAUTH_TIMEOUT; 19354 case WMI_ROAM_FAIL_REASON_SAE_PREAUTH_FAIL: 19355 return ROAM_FAIL_REASON_SAE_PREAUTH_FAIL; 19356 case WMI_ROAM_FAIL_REASON_UNABLE_TO_START_ROAM_HO: 19357 return ROAM_FAIL_REASON_UNABLE_TO_START_ROAM_HO; 19358 case WMI_ROAM_FAIL_REASON_NO_AP_FOUND_AND_FINAL_BMISS_SENT: 19359 return ROAM_FAIL_REASON_NO_AP_FOUND_AND_FINAL_BMISS_SENT; 19360 case WMI_ROAM_FAIL_REASON_NO_CAND_AP_FOUND_AND_FINAL_BMISS_SENT: 19361 return ROAM_FAIL_REASON_NO_CAND_AP_FOUND_AND_FINAL_BMISS_SENT; 19362 case WMI_ROAM_FAIL_REASON_CURR_AP_STILL_OK: 19363 return ROAM_FAIL_REASON_CURR_AP_STILL_OK; 19364 default: 19365 return ROAM_FAIL_REASON_UNKNOWN; 19366 } 19367 } 19368 19369 /** 19370 * wmi_convert_to_cm_roam_invoke_reason() - Convert FW enum to Host enum 19371 * @reason: roam invoke reason from fw 19372 * 19373 * Return: Roam invoke reason code defined in host driver 19374 */ 19375 static enum roam_invoke_reason 19376 wmi_convert_to_cm_roam_invoke_reason(enum wlan_roam_invoke_reason reason) 19377 { 19378 switch (reason) { 19379 case ROAM_INVOKE_REASON_UNDEFINED: 19380 return WLAN_ROAM_STATS_INVOKE_REASON_UNDEFINED; 19381 case ROAM_INVOKE_REASON_NUD_FAILURE: 19382 return WLAN_ROAM_STATS_INVOKE_REASON_NUD_FAILURE; 19383 case ROAM_INVOKE_REASON_USER_SPACE: 19384 return WLAN_ROAM_STATS_INVOKE_REASON_USER_SPACE; 19385 default: 19386 return WLAN_ROAM_STATS_INVOKE_REASON_UNDEFINED; 19387 } 19388 } 19389 19390 /** 19391 * wmi_convert_to_cm_roam_tx_fail_reason() - Convert FW enum to Host enum 19392 * @tx_fail_reason: roam tx fail reason from fw 19393 * 19394 * Return: Roam tx fail reason code defined in host driver 19395 */ 19396 static enum roam_tx_failures_reason 19397 wmi_convert_to_cm_roam_tx_fail_reason(PEER_KICKOUT_REASON tx_fail_reason) 19398 { 19399 switch (tx_fail_reason) { 19400 case WMI_PEER_STA_KICKOUT_REASON_UNSPECIFIED: 19401 return WLAN_ROAM_STATS_KICKOUT_REASON_UNSPECIFIED; 19402 case WMI_PEER_STA_KICKOUT_REASON_XRETRY: 19403 return WLAN_ROAM_STATS_KICKOUT_REASON_XRETRY; 19404 case WMI_PEER_STA_KICKOUT_REASON_INACTIVITY: 19405 return WLAN_ROAM_STATS_KICKOUT_REASON_INACTIVITY; 19406 case WMI_PEER_STA_KICKOUT_REASON_IBSS_DISCONNECT: 19407 return WLAN_ROAM_STATS_KICKOUT_REASON_IBSS_DISCONNECT; 19408 case WMI_PEER_STA_KICKOUT_REASON_TDLS_DISCONNECT: 19409 return WLAN_ROAM_STATS_KICKOUT_REASON_TDLS_DISCONNECT; 19410 case WMI_PEER_STA_KICKOUT_REASON_SA_QUERY_TIMEOUT: 19411 return WLAN_ROAM_STATS_KICKOUT_REASON_SA_QUERY_TIMEOUT; 19412 case WMI_PEER_STA_KICKOUT_REASON_ROAMING_EVENT: 19413 return WLAN_ROAM_STATS_KICKOUT_REASON_ROAMING_EVENT; 19414 default: 19415 return WLAN_ROAM_STATS_KICKOUT_REASON_UNSPECIFIED; 19416 } 19417 } 19418 19419 /** 19420 * wmi_convert_roam_abort_reason() - Convert FW enum to Host enum 19421 * @abort_reason: roam abort reason from fw 19422 * 19423 * Return: Roam abort reason code defined in host driver 19424 */ 19425 static enum roam_abort_reason 19426 wmi_convert_roam_abort_reason(WMI_ROAM_FAIL_SUB_REASON_ID abort_reason) 19427 { 19428 switch (abort_reason) { 19429 case WMI_ROAM_ABORT_UNSPECIFIED: 19430 return WLAN_ROAM_STATS_ABORT_UNSPECIFIED; 19431 case WMI_ROAM_ABORT_LOWRSSI_DATA_RSSI_HIGH: 19432 return WLAN_ROAM_STATS_ABORT_LOWRSSI_DATA_RSSI_HIGH; 19433 case WMI_ROAM_ABORT_LOWRSSI_LINK_SPEED_GOOD: 19434 return WLAN_ROAM_STATS_ABORT_LOWRSSI_LINK_SPEED_GOOD; 19435 case WMI_ROAM_ABORT_BG_DATA_RSSI_HIGH: 19436 return WLAN_ROAM_STATS_ABORT_BG_DATA_RSSI_HIGH; 19437 case WMI_ROAM_ABORT_BG_RSSI_ABOVE_THRESHOLD: 19438 return WLAN_ROAM_STATS_ABORT_BG_RSSI_ABOVE_THRESHOLD; 19439 default: 19440 return WLAN_ROAM_STATS_ABORT_UNSPECIFIED; 19441 } 19442 } 19443 19444 /** 19445 * wlan_roam_scan_type() - Convert FW enum to Host enum 19446 * @scan_type: roam scan type from fw 19447 * 19448 * Return: Roam scan type defined in host driver 19449 */ 19450 static enum roam_stats_scan_type 19451 wlan_roam_scan_type(uint32_t scan_type) 19452 { 19453 switch (scan_type) { 19454 case 0: 19455 return ROAM_STATS_SCAN_TYPE_PARTIAL; 19456 case 1: 19457 return ROAM_STATS_SCAN_TYPE_FULL; 19458 case 2: 19459 return ROAM_STATS_SCAN_TYPE_NO_SCAN; 19460 case 3: 19461 return ROAM_STATS_SCAN_TYPE_HIGHER_BAND_5GHZ_6GHZ; 19462 case 4: 19463 return ROAM_STATS_SCAN_TYPE_HIGHER_BAND_6GHZ; 19464 default: 19465 return ROAM_STATS_SCAN_TYPE_PARTIAL; 19466 } 19467 } 19468 19469 /** 19470 * wlan_roam_dwell_type() - Convert FW enum to Host enum 19471 * @dwell_type: roam channel scan dwell type from fw 19472 * 19473 * Return: Roam channel scan dwell type defined in host driver 19474 */ 19475 static enum roam_scan_dwell_type 19476 wlan_roam_dwell_type(uint32_t dwell_type) 19477 { 19478 switch (dwell_type) { 19479 case 0: 19480 return WLAN_ROAM_DWELL_TYPE_UNSPECIFIED; 19481 case 1: 19482 return WLAN_ROAM_DWELL_ACTIVE_TYPE; 19483 case 2: 19484 return WLAN_ROAM_DWELL_PASSIVE_TYPE; 19485 default: 19486 return WLAN_ROAM_DWELL_TYPE_UNSPECIFIED; 19487 } 19488 } 19489 19490 #define WLAN_ROAM_PER_TX_RATE_OFFSET 0 19491 #define WLAN_ROAM_PER_RX_RATE_OFFSET 16 19492 #define WLAN_ROAM_BMISS_FINNAL_OFFSET 0 19493 #define WLAN_ROAM_BMISS_CONSECUTIVE_OFFSET 7 19494 #define WLAN_ROAM_BMISS_QOSNULL_OFFSET 24 19495 #define WLAN_ROAM_DENSE_ROAMABLE_OFFSET 0 19496 19497 /** 19498 * extract_roam_trigger_stats_tlv() - Extract the Roam trigger stats 19499 * from the WMI_ROAM_STATS_EVENTID 19500 * @wmi_handle: wmi handle 19501 * @evt_buf: Pointer to the event buffer 19502 * @trig: Pointer to destination structure to fill data 19503 * @idx: TLV id 19504 * @btm_idx: BTM index 19505 */ 19506 static QDF_STATUS 19507 extract_roam_trigger_stats_tlv(wmi_unified_t wmi_handle, void *evt_buf, 19508 struct wmi_roam_trigger_info *trig, uint8_t idx, 19509 uint8_t btm_idx) 19510 { 19511 WMI_ROAM_STATS_EVENTID_param_tlvs *param_buf; 19512 wmi_roam_trigger_reason *src_data = NULL; 19513 uint32_t trig_reason = 0; 19514 uint32_t fail_reason = 0; 19515 uint32_t abort = 0; 19516 uint32_t invoke = 0; 19517 uint32_t tx_fail = 0; 19518 wmi_roam_trigger_reason_cmm *cmn_data = NULL; 19519 wmi_roam_trigger_per *per_data = NULL; 19520 wmi_roam_trigger_bmiss *bmiss_data = NULL; 19521 wmi_roam_trigger_hi_rssi *hi_rssi_data = NULL; 19522 wmi_roam_trigger_dense *dense_data = NULL; 19523 wmi_roam_trigger_force *force_data = NULL; 19524 wmi_roam_trigger_btm *btm_data = NULL; 19525 wmi_roam_trigger_bss_load *bss_load_data = NULL; 19526 wmi_roam_trigger_deauth *deauth_data = NULL; 19527 wmi_roam_trigger_periodic *periodic_data = NULL; 19528 wmi_roam_trigger_rssi *rssi_data = NULL; 19529 wmi_roam_trigger_kickout *kickout_data = NULL; 19530 wmi_roam_result *roam_result = NULL; 19531 wmi_roam_scan_info *scan_info = NULL; 19532 19533 param_buf = (WMI_ROAM_STATS_EVENTID_param_tlvs *)evt_buf; 19534 if (!param_buf) { 19535 wmi_err("Param buf is NULL"); 19536 return QDF_STATUS_E_FAILURE; 19537 } 19538 19539 if (!param_buf->roam_result || idx >= param_buf->num_roam_result) 19540 wmi_err("roam_result or idx error.%u", idx); 19541 19542 if (!param_buf->roam_scan_info || idx >= param_buf->num_roam_scan_info) 19543 wmi_err("roam_scan_info or idx error.%u", idx); 19544 19545 trig->present = true; 19546 19547 if (param_buf->roam_scan_info) 19548 scan_info = ¶m_buf->roam_scan_info[idx]; 19549 19550 if (param_buf->roam_trigger_reason_cmm) 19551 cmn_data = ¶m_buf->roam_trigger_reason_cmm[idx]; 19552 19553 if (param_buf->roam_trigger_reason) 19554 src_data = ¶m_buf->roam_trigger_reason[idx]; 19555 19556 if (cmn_data) { 19557 trig_reason = cmn_data->trigger_reason; 19558 trig->trigger_reason = 19559 wmi_convert_fw_to_cm_trig_reason(trig_reason); 19560 trig->trigger_sub_reason = 19561 wmi_convert_roam_sub_reason(cmn_data->trigger_sub_reason); 19562 trig->timestamp = cmn_data->timestamp; 19563 trig->common_roam = true; 19564 } else if (src_data) { 19565 trig_reason = src_data->trigger_reason; 19566 trig->trigger_reason = 19567 wmi_convert_fw_to_cm_trig_reason(trig_reason); 19568 trig->trigger_sub_reason = 19569 wmi_convert_roam_sub_reason(src_data->trigger_sub_reason); 19570 trig->current_rssi = src_data->current_rssi; 19571 trig->timestamp = src_data->timestamp; 19572 trig->common_roam = false; 19573 } 19574 19575 if (param_buf->roam_trigger_rssi) 19576 rssi_data = ¶m_buf->roam_trigger_rssi[idx]; 19577 19578 if (param_buf->roam_result) { 19579 roam_result = ¶m_buf->roam_result[idx]; 19580 19581 if (roam_result) { 19582 trig->roam_status = roam_result->roam_status; 19583 if (trig->roam_status) { 19584 fail_reason = roam_result->roam_fail_reason; 19585 trig->fail_reason = 19586 wlan_roam_fail_reason_code(fail_reason); 19587 19588 if (rssi_data) { 19589 abort = roam_result->roam_abort_reason; 19590 trig->abort_reason.abort_reason_code = 19591 wmi_convert_roam_abort_reason(abort); 19592 trig->abort_reason.data_rssi = 19593 rssi_data->data_rssi; 19594 trig->abort_reason.data_rssi_threshold = 19595 rssi_data->data_rssi_threshold; 19596 trig->abort_reason.rx_linkspeed_status = 19597 rssi_data->rx_linkspeed_status; 19598 } 19599 } 19600 } 19601 } 19602 19603 if (scan_info) 19604 trig->scan_type = 19605 wlan_roam_scan_type(scan_info->roam_scan_type); 19606 19607 switch (trig_reason) { 19608 case WMI_ROAM_TRIGGER_REASON_PER: 19609 if (param_buf->roam_trigger_per) 19610 per_data = ¶m_buf->roam_trigger_per[idx]; 19611 if (per_data) { 19612 trig->per_trig_data.tx_rate_thresh_percent = 19613 WMI_GET_BITS(per_data->rate_thresh_percnt, 19614 WLAN_ROAM_PER_RX_RATE_OFFSET, 8); 19615 trig->per_trig_data.rx_rate_thresh_percent = 19616 WMI_GET_BITS(per_data->rate_thresh_percnt, 19617 WLAN_ROAM_PER_TX_RATE_OFFSET, 8); 19618 } 19619 return QDF_STATUS_SUCCESS; 19620 19621 case WMI_ROAM_TRIGGER_REASON_BMISS: 19622 if (param_buf->roam_trigger_bmiss) 19623 bmiss_data = ¶m_buf->roam_trigger_bmiss[idx]; 19624 if (bmiss_data) { 19625 trig->bmiss_trig_data.final_bmiss_cnt = 19626 WMI_GET_BITS(bmiss_data->bmiss_status, 19627 WLAN_ROAM_BMISS_FINNAL_OFFSET, 7); 19628 trig->bmiss_trig_data.consecutive_bmiss_cnt = 19629 WMI_GET_BITS(bmiss_data->bmiss_status, 19630 WLAN_ROAM_BMISS_CONSECUTIVE_OFFSET, 19631 17); 19632 trig->bmiss_trig_data.qos_null_success = 19633 WMI_GET_BITS(bmiss_data->bmiss_status, 19634 WLAN_ROAM_BMISS_QOSNULL_OFFSET, 1); 19635 } 19636 return QDF_STATUS_SUCCESS; 19637 19638 case WMI_ROAM_TRIGGER_REASON_HIGH_RSSI: 19639 if (param_buf->roam_trigger_hi_rssi) 19640 hi_rssi_data = ¶m_buf->roam_trigger_hi_rssi[idx]; 19641 19642 if (hi_rssi_data && cmn_data) { 19643 trig->hi_rssi_trig_data.current_rssi = 19644 (uint8_t)cmn_data->current_rssi; 19645 trig->hi_rssi_trig_data.hirssi_threshold = 19646 (uint8_t)hi_rssi_data->hi_rssi_threshold; 19647 } 19648 return QDF_STATUS_SUCCESS; 19649 19650 case WMI_ROAM_TRIGGER_REASON_MAWC: 19651 case WMI_ROAM_TRIGGER_REASON_DENSE: 19652 if (param_buf->roam_trigger_dense) 19653 dense_data = ¶m_buf->roam_trigger_dense[idx]; 19654 if (dense_data) { 19655 trig->congestion_trig_data.rx_tput = 19656 dense_data->rx_tput; 19657 trig->congestion_trig_data.tx_tput = 19658 dense_data->tx_tput; 19659 trig->congestion_trig_data.roamable_count = 19660 WMI_GET_BITS(dense_data->dense_status, 19661 WLAN_ROAM_DENSE_ROAMABLE_OFFSET, 19662 8); 19663 } 19664 return QDF_STATUS_SUCCESS; 19665 19666 case WMI_ROAM_TRIGGER_REASON_BACKGROUND: 19667 if (cmn_data && rssi_data) { 19668 trig->background_trig_data.current_rssi = 19669 (uint8_t)cmn_data->current_rssi; 19670 trig->background_trig_data.data_rssi = 19671 (uint8_t)rssi_data->data_rssi; 19672 trig->background_trig_data.data_rssi_threshold = 19673 (uint8_t)rssi_data->data_rssi_threshold; 19674 } 19675 return QDF_STATUS_SUCCESS; 19676 19677 case WMI_ROAM_TRIGGER_REASON_IDLE: 19678 case WMI_ROAM_TRIGGER_REASON_FORCED: 19679 if (param_buf->roam_trigger_force) 19680 force_data = ¶m_buf->roam_trigger_force[idx]; 19681 if (force_data) { 19682 invoke = force_data->invoke_reason; 19683 trig->user_trig_data.invoke_reason = 19684 wmi_convert_to_cm_roam_invoke_reason(invoke); 19685 } 19686 return QDF_STATUS_SUCCESS; 19687 19688 case WMI_ROAM_TRIGGER_REASON_UNIT_TEST: 19689 case WMI_ROAM_TRIGGER_REASON_BTC: 19690 return QDF_STATUS_SUCCESS; 19691 19692 case WMI_ROAM_TRIGGER_REASON_BTM: 19693 if (param_buf->roam_trigger_btm) 19694 btm_data = ¶m_buf->roam_trigger_btm[idx]; 19695 if (btm_data) { 19696 trig->btm_trig_data.btm_request_mode = 19697 btm_data->btm_request_mode; 19698 trig->btm_trig_data.disassoc_timer = 19699 btm_data->disassoc_imminent_timer; 19700 trig->btm_trig_data.validity_interval = 19701 btm_data->validity_internal; 19702 trig->btm_trig_data.candidate_list_count = 19703 btm_data->candidate_list_count; 19704 trig->btm_trig_data.btm_resp_status = 19705 btm_data->btm_response_status_code; 19706 trig->btm_trig_data.btm_bss_termination_timeout = 19707 btm_data->btm_bss_termination_timeout; 19708 trig->btm_trig_data.btm_mbo_assoc_retry_timeout = 19709 btm_data->btm_mbo_assoc_retry_timeout; 19710 trig->btm_trig_data.token = 19711 (uint16_t)btm_data->btm_req_dialog_token; 19712 if (scan_info) { 19713 trig->btm_trig_data.band = 19714 WMI_GET_MLO_BAND(scan_info->flags); 19715 if (trig->btm_trig_data.band != 19716 WMI_MLO_BAND_NO_MLO) 19717 trig->btm_trig_data.is_mlo = true; 19718 } 19719 } else if (src_data) { 19720 trig->btm_trig_data.btm_request_mode = 19721 src_data->btm_request_mode; 19722 trig->btm_trig_data.disassoc_timer = 19723 src_data->disassoc_imminent_timer; 19724 trig->btm_trig_data.validity_interval = 19725 src_data->validity_internal; 19726 trig->btm_trig_data.candidate_list_count = 19727 src_data->candidate_list_count; 19728 trig->btm_trig_data.btm_resp_status = 19729 src_data->btm_response_status_code; 19730 trig->btm_trig_data.btm_bss_termination_timeout = 19731 src_data->btm_bss_termination_timeout; 19732 trig->btm_trig_data.btm_mbo_assoc_retry_timeout = 19733 src_data->btm_mbo_assoc_retry_timeout; 19734 trig->btm_trig_data.token = 19735 src_data->btm_req_dialog_token; 19736 if (scan_info) { 19737 trig->btm_trig_data.band = 19738 WMI_GET_MLO_BAND(scan_info->flags); 19739 if (trig->btm_trig_data.band != 19740 WMI_MLO_BAND_NO_MLO) 19741 trig->btm_trig_data.is_mlo = true; 19742 } 19743 if ((btm_idx + 19744 trig->btm_trig_data.candidate_list_count) <= 19745 param_buf->num_roam_btm_request_candidate_info) 19746 extract_roam_11kv_candidate_info( 19747 wmi_handle, evt_buf, 19748 trig->btm_trig_data.btm_cand, 19749 btm_idx, 19750 src_data->candidate_list_count); 19751 } 19752 19753 return QDF_STATUS_SUCCESS; 19754 19755 case WMI_ROAM_TRIGGER_REASON_BSS_LOAD: 19756 if (param_buf->roam_trigger_bss_load) 19757 bss_load_data = ¶m_buf->roam_trigger_bss_load[idx]; 19758 if (bss_load_data) 19759 trig->cu_trig_data.cu_load = bss_load_data->cu_load; 19760 else if (src_data) 19761 trig->cu_trig_data.cu_load = src_data->cu_load; 19762 return QDF_STATUS_SUCCESS; 19763 19764 case WMI_ROAM_TRIGGER_REASON_DEAUTH: 19765 if (param_buf->roam_trigger_deauth) 19766 deauth_data = ¶m_buf->roam_trigger_deauth[idx]; 19767 if (deauth_data) { 19768 trig->deauth_trig_data.type = deauth_data->deauth_type; 19769 trig->deauth_trig_data.reason = 19770 deauth_data->deauth_reason; 19771 } else if (src_data) { 19772 trig->deauth_trig_data.type = src_data->deauth_type; 19773 trig->deauth_trig_data.reason = src_data->deauth_reason; 19774 } 19775 return QDF_STATUS_SUCCESS; 19776 19777 case WMI_ROAM_TRIGGER_REASON_PERIODIC: 19778 if (param_buf->roam_trigger_periodic) 19779 periodic_data = ¶m_buf->roam_trigger_periodic[idx]; 19780 if (periodic_data) { 19781 trig->periodic_trig_data.periodic_timer_ms = 19782 periodic_data->periodic_timer_ms; 19783 } else if (src_data) 19784 trig->rssi_trig_data.threshold = 19785 src_data->roam_rssi_threshold; 19786 return QDF_STATUS_SUCCESS; 19787 19788 case WMI_ROAM_TRIGGER_REASON_LOW_RSSI: 19789 if (cmn_data && rssi_data) { 19790 trig->low_rssi_trig_data.current_rssi = 19791 (uint8_t)cmn_data->current_rssi; 19792 trig->low_rssi_trig_data.roam_rssi_threshold = 19793 (uint8_t)rssi_data->roam_rssi_threshold; 19794 trig->low_rssi_trig_data.rx_linkspeed_status = 19795 (uint8_t)rssi_data->rx_linkspeed_status; 19796 } else if (src_data) 19797 trig->rssi_trig_data.threshold = 19798 src_data->roam_rssi_threshold; 19799 19800 return QDF_STATUS_SUCCESS; 19801 19802 case WMI_ROAM_TRIGGER_REASON_STA_KICKOUT: 19803 if (param_buf->roam_trigger_kickout) 19804 kickout_data = ¶m_buf->roam_trigger_kickout[idx]; 19805 if (kickout_data) { 19806 tx_fail = kickout_data->kickout_reason; 19807 trig->tx_failures_trig_data.kickout_threshold = 19808 kickout_data->kickout_th; 19809 trig->tx_failures_trig_data.kickout_reason = 19810 wmi_convert_to_cm_roam_tx_fail_reason(tx_fail); 19811 } 19812 return QDF_STATUS_SUCCESS; 19813 19814 case WMI_ROAM_TRIGGER_REASON_WTC_BTM: 19815 if (src_data) { 19816 trig->wtc_btm_trig_data.roaming_mode = 19817 src_data->vendor_specific1[0]; 19818 trig->wtc_btm_trig_data.vsie_trigger_reason = 19819 src_data->vendor_specific1[1]; 19820 trig->wtc_btm_trig_data.sub_code = 19821 src_data->vendor_specific1[2]; 19822 trig->wtc_btm_trig_data.wtc_mode = 19823 src_data->vendor_specific1[3]; 19824 trig->wtc_btm_trig_data.wtc_scan_mode = 19825 convert_wtc_scan_mode(src_data->vendor_specific1[4]); 19826 trig->wtc_btm_trig_data.wtc_rssi_th = 19827 src_data->vendor_specific1[5]; 19828 trig->wtc_btm_trig_data.wtc_candi_rssi_th = 19829 src_data->vendor_specific1[6]; 19830 19831 trig->wtc_btm_trig_data.wtc_candi_rssi_ext_present = 19832 src_data->vendor_specific2[0]; 19833 trig->wtc_btm_trig_data.wtc_candi_rssi_th_5g = 19834 src_data->vendor_specific2[1]; 19835 trig->wtc_btm_trig_data.wtc_candi_rssi_th_6g = 19836 src_data->vendor_specific2[2]; 19837 trig->wtc_btm_trig_data.duration = 19838 src_data->vendor_specific2[3]; 19839 } 19840 return QDF_STATUS_SUCCESS; 19841 default: 19842 return QDF_STATUS_SUCCESS; 19843 } 19844 19845 return QDF_STATUS_SUCCESS; 19846 } 19847 19848 /** 19849 * extract_roam_scan_ap_stats_tlv() - Extract the Roam trigger stats 19850 * from the WMI_ROAM_STATS_EVENTID 19851 * @wmi_handle: wmi handle 19852 * @evt_buf: Pointer to the event buffer 19853 * @dst: Pointer to destination structure to fill data 19854 * @ap_idx: TLV index for this roam scan 19855 * @num_cand: number of candidates list in the roam scan 19856 */ 19857 static QDF_STATUS 19858 extract_roam_scan_ap_stats_tlv(wmi_unified_t wmi_handle, void *evt_buf, 19859 struct wmi_roam_candidate_info *dst, 19860 uint8_t ap_idx, uint16_t num_cand) 19861 { 19862 WMI_ROAM_STATS_EVENTID_param_tlvs *param_buf; 19863 wmi_roam_ap_info *src = NULL; 19864 uint8_t i; 19865 19866 param_buf = (WMI_ROAM_STATS_EVENTID_param_tlvs *)evt_buf; 19867 if (!param_buf) { 19868 wmi_err("Param buf is NULL"); 19869 return QDF_STATUS_E_FAILURE; 19870 } 19871 19872 if (ap_idx >= param_buf->num_roam_ap_info) { 19873 wmi_err("Invalid roam scan AP tlv ap_idx:%d total_ap:%d", 19874 ap_idx, param_buf->num_roam_ap_info); 19875 return QDF_STATUS_E_FAILURE; 19876 } 19877 19878 src = ¶m_buf->roam_ap_info[ap_idx]; 19879 19880 for (i = 0; i < num_cand; i++) { 19881 WMI_MAC_ADDR_TO_CHAR_ARRAY(&src->bssid, dst->bssid.bytes); 19882 dst->type = src->candidate_type; 19883 dst->freq = src->channel; 19884 dst->etp = src->etp; 19885 dst->rssi = src->rssi; 19886 dst->rssi_score = src->rssi_score; 19887 dst->cu_load = src->cu_load; 19888 dst->cu_score = src->cu_score; 19889 dst->total_score = src->total_score; 19890 dst->timestamp = src->timestamp; 19891 dst->dl_reason = src->bl_reason; 19892 dst->dl_source = src->bl_source; 19893 dst->dl_timestamp = src->bl_timestamp; 19894 dst->dl_original_timeout = src->bl_original_timeout; 19895 dst->is_mlo = WMI_GET_AP_INFO_MLO_STATUS(src->flags); 19896 19897 src++; 19898 dst++; 19899 } 19900 19901 return QDF_STATUS_SUCCESS; 19902 } 19903 19904 #define ROAM_SUCCESS 0 19905 19906 /** 19907 * extract_roam_scan_stats_tlv() - Extract the Roam trigger stats 19908 * from the WMI_ROAM_STATS_EVENTID 19909 * @wmi_handle: wmi handle 19910 * @evt_buf: Pointer to the event buffer 19911 * @dst: Pointer to destination structure to fill data 19912 * @idx: TLV id 19913 * @chan_idx: Index of the channel tlv for the current roam trigger 19914 * @ap_idx: Index of the candidate AP TLV for the current roam trigger 19915 */ 19916 static QDF_STATUS 19917 extract_roam_scan_stats_tlv(wmi_unified_t wmi_handle, void *evt_buf, 19918 struct wmi_roam_scan_data *dst, uint8_t idx, 19919 uint8_t chan_idx, uint8_t ap_idx) 19920 { 19921 WMI_ROAM_STATS_EVENTID_param_tlvs *param_buf; 19922 wmi_roam_scan_info *src_data = NULL; 19923 wmi_roam_scan_channel_info *src_chan = NULL; 19924 QDF_STATUS status; 19925 uint8_t i; 19926 19927 param_buf = (WMI_ROAM_STATS_EVENTID_param_tlvs *)evt_buf; 19928 if (!param_buf || !param_buf->roam_scan_info || 19929 idx >= param_buf->num_roam_scan_info) 19930 return QDF_STATUS_E_FAILURE; 19931 19932 src_data = ¶m_buf->roam_scan_info[idx]; 19933 19934 dst->present = true; 19935 dst->type = src_data->roam_scan_type; 19936 dst->num_chan = src_data->roam_scan_channel_count; 19937 dst->scan_complete_timestamp = src_data->scan_complete_timestamp; 19938 dst->next_rssi_threshold = src_data->next_rssi_trigger_threshold; 19939 dst->is_btcoex_active = WMI_GET_BTCONNECT_STATUS(src_data->flags); 19940 dst->frame_info_count = src_data->frame_info_count; 19941 if (dst->frame_info_count > WLAN_ROAM_MAX_FRAME_INFO) 19942 dst->frame_info_count = WLAN_ROAM_MAX_FRAME_INFO; 19943 19944 dst->band = WMI_GET_MLO_BAND(src_data->flags); 19945 if (dst->band != WMI_MLO_BAND_NO_MLO) 19946 dst->is_mlo = true; 19947 19948 /* Read the channel data only for dst->type is 0 (partial scan) */ 19949 if (dst->num_chan && !dst->type && param_buf->num_roam_scan_chan_info && 19950 chan_idx < param_buf->num_roam_scan_chan_info) { 19951 if (dst->num_chan > MAX_ROAM_SCAN_CHAN) 19952 dst->num_chan = MAX_ROAM_SCAN_CHAN; 19953 19954 src_chan = ¶m_buf->roam_scan_chan_info[chan_idx]; 19955 19956 if ((dst->num_chan + chan_idx) > 19957 param_buf->num_roam_scan_chan_info) { 19958 wmi_err("Invalid TLV. num_chan %d chan_idx %d num_roam_scan_chan_info %d", 19959 dst->num_chan, chan_idx, 19960 param_buf->num_roam_scan_chan_info); 19961 return QDF_STATUS_SUCCESS; 19962 } 19963 19964 for (i = 0; i < dst->num_chan; i++) { 19965 dst->chan_freq[i] = src_chan->channel; 19966 dst->dwell_type[i] = 19967 (uint8_t)wlan_roam_dwell_type(src_chan->ch_dwell_type); 19968 src_chan++; 19969 } 19970 } 19971 19972 if (!src_data->roam_ap_count || !param_buf->num_roam_ap_info) 19973 return QDF_STATUS_SUCCESS; 19974 19975 dst->num_ap = src_data->roam_ap_count; 19976 if (dst->num_ap > MAX_ROAM_CANDIDATE_AP) 19977 dst->num_ap = MAX_ROAM_CANDIDATE_AP; 19978 19979 status = extract_roam_scan_ap_stats_tlv(wmi_handle, evt_buf, dst->ap, 19980 ap_idx, dst->num_ap); 19981 if (QDF_IS_STATUS_ERROR(status)) { 19982 wmi_err("Extract candidate stats for tlv[%d] failed", idx); 19983 return status; 19984 } 19985 19986 return QDF_STATUS_SUCCESS; 19987 } 19988 19989 /** 19990 * extract_roam_result_stats_tlv() - Extract the Roam trigger stats 19991 * from the WMI_ROAM_STATS_EVENTID 19992 * @wmi_handle: wmi handle 19993 * @evt_buf: Pointer to the event buffer 19994 * @dst: Pointer to destination structure to fill data 19995 * @idx: TLV id 19996 */ 19997 static QDF_STATUS 19998 extract_roam_result_stats_tlv(wmi_unified_t wmi_handle, void *evt_buf, 19999 struct wmi_roam_result *dst, uint8_t idx) 20000 { 20001 WMI_ROAM_STATS_EVENTID_param_tlvs *param_buf; 20002 wmi_roam_result *src_data = NULL; 20003 20004 param_buf = (WMI_ROAM_STATS_EVENTID_param_tlvs *)evt_buf; 20005 if (!param_buf || !param_buf->roam_result || 20006 idx >= param_buf->num_roam_result) 20007 return QDF_STATUS_E_FAILURE; 20008 20009 src_data = ¶m_buf->roam_result[idx]; 20010 20011 dst->present = true; 20012 dst->status = src_data->roam_status; 20013 dst->timestamp = src_data->timestamp; 20014 if (src_data->roam_fail_reason != ROAM_SUCCESS) 20015 dst->fail_reason = 20016 wlan_roam_fail_reason_code(src_data->roam_fail_reason); 20017 WMI_MAC_ADDR_TO_CHAR_ARRAY(&src_data->bssid, dst->fail_bssid.bytes); 20018 20019 return QDF_STATUS_SUCCESS; 20020 } 20021 20022 /** 20023 * extract_roam_11kv_stats_tlv() - Extract the Roam trigger stats 20024 * from the WMI_ROAM_STATS_EVENTID 20025 * @wmi_handle: wmi handle 20026 * @evt_buf: Pointer to the event buffer 20027 * @dst: Pointer to destination structure to fill data 20028 * @idx: TLV id 20029 * @rpt_idx: Neighbor report Channel index 20030 * @band: Band of the link on which packet is transmitted or received 20031 */ 20032 static QDF_STATUS 20033 extract_roam_11kv_stats_tlv(wmi_unified_t wmi_handle, void *evt_buf, 20034 struct wmi_neighbor_report_data *dst, 20035 uint8_t idx, uint8_t rpt_idx, uint8_t band) 20036 { 20037 WMI_ROAM_STATS_EVENTID_param_tlvs *param_buf; 20038 wmi_roam_neighbor_report_info *src_data = NULL; 20039 wmi_roam_neighbor_report_channel_info *src_freq = NULL; 20040 uint8_t i; 20041 20042 param_buf = (WMI_ROAM_STATS_EVENTID_param_tlvs *)evt_buf; 20043 if (!param_buf || !param_buf->roam_neighbor_report_info || 20044 !param_buf->num_roam_neighbor_report_info || 20045 idx >= param_buf->num_roam_neighbor_report_info) { 20046 wmi_debug("Invalid 1kv param buf"); 20047 return QDF_STATUS_E_FAILURE; 20048 } 20049 20050 src_data = ¶m_buf->roam_neighbor_report_info[idx]; 20051 20052 dst->present = true; 20053 dst->req_type = src_data->request_type; 20054 dst->num_freq = src_data->neighbor_report_channel_count; 20055 dst->req_time = src_data->neighbor_report_request_timestamp; 20056 dst->resp_time = src_data->neighbor_report_response_timestamp; 20057 dst->btm_query_token = src_data->btm_query_token; 20058 dst->btm_query_reason = src_data->btm_query_reason_code; 20059 dst->req_token = 20060 WMI_ROAM_NEIGHBOR_REPORT_INFO_REQUEST_TOKEN_GET(src_data->neighbor_report_detail); 20061 dst->resp_token = 20062 WMI_ROAM_NEIGHBOR_REPORT_INFO_RESPONSE_TOKEN_GET(src_data->neighbor_report_detail); 20063 dst->num_rpt = 20064 WMI_ROAM_NEIGHBOR_REPORT_INFO_NUM_OF_NRIE_GET(src_data->neighbor_report_detail); 20065 20066 dst->band = band; 20067 20068 if (dst->band != WMI_MLO_BAND_NO_MLO) 20069 dst->is_mlo = true; 20070 20071 if (!dst->num_freq || !param_buf->num_roam_neighbor_report_chan_info || 20072 rpt_idx >= param_buf->num_roam_neighbor_report_chan_info) 20073 return QDF_STATUS_SUCCESS; 20074 20075 if (!param_buf->roam_neighbor_report_chan_info) { 20076 wmi_debug("11kv channel present, but TLV is NULL num_freq:%d", 20077 dst->num_freq); 20078 dst->num_freq = 0; 20079 /* return success as its optional tlv and we can print neighbor 20080 * report received info 20081 */ 20082 return QDF_STATUS_SUCCESS; 20083 } 20084 20085 src_freq = ¶m_buf->roam_neighbor_report_chan_info[rpt_idx]; 20086 20087 if (dst->num_freq > MAX_ROAM_SCAN_CHAN) 20088 dst->num_freq = MAX_ROAM_SCAN_CHAN; 20089 20090 if ((dst->num_freq + rpt_idx) > 20091 param_buf->num_roam_neighbor_report_chan_info) { 20092 wmi_err("Invalid TLV. num_freq %d rpt_idx %d num_roam_neighbor_report_chan_info %d", 20093 dst->num_freq, rpt_idx, 20094 param_buf->num_roam_scan_chan_info); 20095 return QDF_STATUS_SUCCESS; 20096 } 20097 20098 for (i = 0; i < dst->num_freq; i++) { 20099 dst->freq[i] = src_freq->channel; 20100 src_freq++; 20101 } 20102 20103 return QDF_STATUS_SUCCESS; 20104 } 20105 20106 /** 20107 * send_roam_set_param_cmd_tlv() - WMI roam set parameter function 20108 * @wmi_handle: handle to WMI. 20109 * @roam_param: pointer to hold roam set parameter 20110 * 20111 * Return: QDF_STATUS_SUCCESS for success or error code 20112 */ 20113 static QDF_STATUS 20114 send_roam_set_param_cmd_tlv(wmi_unified_t wmi_handle, 20115 struct vdev_set_params *roam_param) 20116 { 20117 QDF_STATUS ret; 20118 wmi_roam_set_param_cmd_fixed_param *cmd; 20119 wmi_buf_t buf; 20120 uint16_t len = sizeof(*cmd); 20121 20122 buf = wmi_buf_alloc(wmi_handle, len); 20123 if (!buf) 20124 return QDF_STATUS_E_NOMEM; 20125 20126 cmd = (wmi_roam_set_param_cmd_fixed_param *)wmi_buf_data(buf); 20127 WMITLV_SET_HDR(&cmd->tlv_header, 20128 WMITLV_TAG_STRUC_wmi_roam_set_param_cmd_fixed_param, 20129 WMITLV_GET_STRUCT_TLVLEN 20130 (wmi_roam_set_param_cmd_fixed_param)); 20131 cmd->vdev_id = roam_param->vdev_id; 20132 cmd->param_id = roam_param->param_id; 20133 cmd->param_value = roam_param->param_value; 20134 wmi_debug("Setting vdev %d roam_param = %x, value = %u", 20135 cmd->vdev_id, cmd->param_id, cmd->param_value); 20136 wmi_mtrace(WMI_ROAM_SET_PARAM_CMDID, cmd->vdev_id, 0); 20137 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 20138 WMI_ROAM_SET_PARAM_CMDID); 20139 if (QDF_IS_STATUS_ERROR(ret)) { 20140 wmi_err("Failed to send roam set param command, ret = %d", ret); 20141 wmi_buf_free(buf); 20142 } 20143 20144 return ret; 20145 } 20146 #else 20147 static inline QDF_STATUS 20148 extract_roam_trigger_stats_tlv(wmi_unified_t wmi_handle, void *evt_buf, 20149 struct wmi_roam_trigger_info *trig, uint8_t idx, 20150 uint8_t btm_idx) 20151 { 20152 return QDF_STATUS_E_NOSUPPORT; 20153 } 20154 20155 static inline QDF_STATUS 20156 extract_roam_result_stats_tlv(wmi_unified_t wmi_handle, void *evt_buf, 20157 struct wmi_roam_result *dst, uint8_t idx) 20158 { 20159 return QDF_STATUS_E_NOSUPPORT; 20160 } 20161 20162 static QDF_STATUS 20163 extract_roam_11kv_stats_tlv(wmi_unified_t wmi_handle, void *evt_buf, 20164 struct wmi_neighbor_report_data *dst, 20165 uint8_t idx, uint8_t rpt_idx, uint8_t band) 20166 { 20167 return QDF_STATUS_E_NOSUPPORT; 20168 } 20169 20170 static QDF_STATUS 20171 extract_roam_scan_stats_tlv(wmi_unified_t wmi_handle, void *evt_buf, 20172 struct wmi_roam_scan_data *dst, uint8_t idx, 20173 uint8_t chan_idx, uint8_t ap_idx) 20174 { 20175 return QDF_STATUS_E_NOSUPPORT; 20176 } 20177 #endif 20178 20179 #ifdef WLAN_FEATURE_PKT_CAPTURE 20180 static QDF_STATUS 20181 extract_vdev_mgmt_offload_event_tlv(void *handle, void *evt_buf, 20182 struct mgmt_offload_event_params *params) 20183 { 20184 WMI_VDEV_MGMT_OFFLOAD_EVENTID_param_tlvs *param_tlvs; 20185 wmi_mgmt_hdr *hdr; 20186 20187 param_tlvs = (WMI_VDEV_MGMT_OFFLOAD_EVENTID_param_tlvs *)evt_buf; 20188 if (!param_tlvs) 20189 return QDF_STATUS_E_INVAL; 20190 20191 hdr = param_tlvs->fixed_param; 20192 if (!hdr) 20193 return QDF_STATUS_E_INVAL; 20194 20195 if (hdr->buf_len > param_tlvs->num_bufp) 20196 return QDF_STATUS_E_INVAL; 20197 20198 params->tsf_l32 = hdr->tsf_l32; 20199 params->chan_freq = hdr->chan_freq; 20200 params->rate_kbps = hdr->rate_kbps; 20201 params->rssi = hdr->rssi; 20202 params->buf_len = hdr->buf_len; 20203 params->tx_status = hdr->tx_status; 20204 params->buf = param_tlvs->bufp; 20205 params->tx_retry_cnt = hdr->tx_retry_cnt; 20206 return QDF_STATUS_SUCCESS; 20207 } 20208 #endif /* WLAN_FEATURE_PKT_CAPTURE */ 20209 20210 #ifdef WLAN_FEATURE_PKT_CAPTURE_V2 20211 static QDF_STATUS 20212 extract_smart_monitor_event_tlv(void *handle, void *evt_buf, 20213 struct smu_event_params *params) 20214 { 20215 WMI_VDEV_SMART_MONITOR_EVENTID_param_tlvs *param_buf = NULL; 20216 wmi_vdev_smart_monitor_event_fixed_param *smu_event = NULL; 20217 20218 param_buf = (WMI_VDEV_SMART_MONITOR_EVENTID_param_tlvs *)evt_buf; 20219 if (!param_buf) { 20220 wmi_err("Invalid smart monitor event"); 20221 return QDF_STATUS_E_INVAL; 20222 } 20223 20224 smu_event = param_buf->fixed_param; 20225 if (!smu_event) { 20226 wmi_err("smart monitor event fixed param is NULL"); 20227 return QDF_STATUS_E_INVAL; 20228 } 20229 20230 params->vdev_id = smu_event->vdev_id; 20231 if (params->vdev_id >= WLAN_UMAC_PDEV_MAX_VDEVS) 20232 return QDF_STATUS_E_INVAL; 20233 20234 params->rx_vht_sgi = smu_event->rx_vht_sgi; 20235 20236 return QDF_STATUS_SUCCESS; 20237 } 20238 #endif /* WLAN_FEATURE_PKT_CAPTURE_V2 */ 20239 20240 #ifdef FEATURE_WLAN_TIME_SYNC_FTM 20241 /** 20242 * send_wlan_ts_ftm_trigger_cmd_tlv(): send wlan time sync cmd to FW 20243 * 20244 * @wmi: wmi handle 20245 * @vdev_id: vdev id 20246 * @burst_mode: Indicates whether relation derived using FTM is needed for 20247 * each FTM frame or only aggregated result is required. 20248 * 20249 * Send WMI_AUDIO_SYNC_TRIGGER_CMDID to FW. 20250 * 20251 * Return: QDF_STATUS 20252 */ 20253 static QDF_STATUS send_wlan_ts_ftm_trigger_cmd_tlv(wmi_unified_t wmi, 20254 uint32_t vdev_id, 20255 bool burst_mode) 20256 { 20257 wmi_audio_sync_trigger_cmd_fixed_param *cmd; 20258 wmi_buf_t buf; 20259 int32_t len = sizeof(*cmd); 20260 20261 buf = wmi_buf_alloc(wmi, len); 20262 if (!buf) { 20263 wmi_err("wmi_buf_alloc failed"); 20264 return QDF_STATUS_E_NOMEM; 20265 } 20266 cmd = (wmi_audio_sync_trigger_cmd_fixed_param *)wmi_buf_data(buf); 20267 WMITLV_SET_HDR(&cmd->tlv_header, 20268 WMITLV_TAG_STRUC_wmi_audio_sync_trigger_cmd_fixed_param, 20269 WMITLV_GET_STRUCT_TLVLEN(wmi_audio_sync_trigger_cmd_fixed_param)); 20270 cmd->vdev_id = vdev_id; 20271 cmd->agg_relation = burst_mode ? false : true; 20272 if (wmi_unified_cmd_send(wmi, buf, len, WMI_VDEV_AUDIO_SYNC_TRIGGER_CMDID)) { 20273 wmi_err("Failed to send audio sync trigger cmd"); 20274 wmi_buf_free(buf); 20275 return QDF_STATUS_E_FAILURE; 20276 } 20277 20278 return QDF_STATUS_SUCCESS; 20279 } 20280 20281 static QDF_STATUS send_wlan_ts_qtime_cmd_tlv(wmi_unified_t wmi, 20282 uint32_t vdev_id, 20283 uint64_t lpass_ts) 20284 { 20285 wmi_audio_sync_qtimer_cmd_fixed_param *cmd; 20286 wmi_buf_t buf; 20287 int32_t len = sizeof(*cmd); 20288 20289 buf = wmi_buf_alloc(wmi, len); 20290 if (!buf) { 20291 wmi_err("wmi_buf_alloc failed"); 20292 return QDF_STATUS_E_NOMEM; 20293 } 20294 cmd = (wmi_audio_sync_qtimer_cmd_fixed_param *)wmi_buf_data(buf); 20295 WMITLV_SET_HDR(&cmd->tlv_header, 20296 WMITLV_TAG_STRUC_wmi_audio_sync_qtimer_cmd_fixed_param, 20297 WMITLV_GET_STRUCT_TLVLEN(wmi_audio_sync_qtimer_cmd_fixed_param)); 20298 cmd->vdev_id = vdev_id; 20299 cmd->qtimer_u32 = (uint32_t)((lpass_ts & 0xffffffff00000000LL) >> 32); 20300 cmd->qtimer_l32 = (uint32_t)(lpass_ts & 0xffffffffLL); 20301 20302 if (wmi_unified_cmd_send(wmi, buf, len, WMI_VDEV_AUDIO_SYNC_QTIMER_CMDID)) { 20303 wmi_err("Failed to send audio qtime command"); 20304 wmi_buf_free(buf); 20305 return QDF_STATUS_E_FAILURE; 20306 } 20307 20308 return QDF_STATUS_SUCCESS; 20309 } 20310 20311 static QDF_STATUS extract_time_sync_ftm_start_stop_event_tlv( 20312 wmi_unified_t wmi, void *buf, 20313 struct ftm_time_sync_start_stop_params *param) 20314 { 20315 WMI_VDEV_AUDIO_SYNC_START_STOP_EVENTID_param_tlvs *param_buf; 20316 wmi_audio_sync_start_stop_event_fixed_param *resp_event; 20317 20318 param_buf = (WMI_VDEV_AUDIO_SYNC_START_STOP_EVENTID_param_tlvs *)buf; 20319 if (!param_buf) { 20320 wmi_err("Invalid audio sync start stop event buffer"); 20321 return QDF_STATUS_E_FAILURE; 20322 } 20323 20324 resp_event = param_buf->fixed_param; 20325 if (!resp_event) { 20326 wmi_err("Invalid audio sync start stop fixed param buffer"); 20327 return QDF_STATUS_E_FAILURE; 20328 } 20329 20330 param->vdev_id = resp_event->vdev_id; 20331 param->timer_interval = resp_event->periodicity; 20332 param->num_reads = resp_event->reads_needed; 20333 param->qtime = ((uint64_t)resp_event->qtimer_u32 << 32) | 20334 resp_event->qtimer_l32; 20335 param->mac_time = ((uint64_t)resp_event->mac_timer_u32 << 32) | 20336 resp_event->mac_timer_l32; 20337 20338 wmi_debug("FTM time sync time_interval %d, num_reads %d", 20339 param->timer_interval, param->num_reads); 20340 20341 return QDF_STATUS_SUCCESS; 20342 } 20343 20344 static QDF_STATUS 20345 extract_time_sync_ftm_offset_event_tlv(wmi_unified_t wmi, void *buf, 20346 struct ftm_time_sync_offset *param) 20347 { 20348 WMI_VDEV_AUDIO_SYNC_Q_MASTER_SLAVE_OFFSET_EVENTID_param_tlvs *param_buf; 20349 wmi_audio_sync_q_master_slave_offset_event_fixed_param *resp_event; 20350 wmi_audio_sync_q_master_slave_times *q_pair; 20351 int iter; 20352 20353 param_buf = 20354 (WMI_VDEV_AUDIO_SYNC_Q_MASTER_SLAVE_OFFSET_EVENTID_param_tlvs *)buf; 20355 if (!param_buf) { 20356 wmi_err("Invalid timesync ftm offset event buffer"); 20357 return QDF_STATUS_E_FAILURE; 20358 } 20359 20360 resp_event = param_buf->fixed_param; 20361 if (!resp_event) { 20362 wmi_err("Invalid timesync ftm offset fixed param buffer"); 20363 return QDF_STATUS_E_FAILURE; 20364 } 20365 20366 param->vdev_id = resp_event->vdev_id; 20367 param->num_qtime = param_buf->num_audio_sync_q_master_slave_times; 20368 if (param->num_qtime > FTM_TIME_SYNC_QTIME_PAIR_MAX) 20369 param->num_qtime = FTM_TIME_SYNC_QTIME_PAIR_MAX; 20370 20371 q_pair = param_buf->audio_sync_q_master_slave_times; 20372 if (!q_pair) { 20373 wmi_err("Invalid q_master_slave_times buffer"); 20374 return QDF_STATUS_E_FAILURE; 20375 } 20376 20377 for (iter = 0; iter < param->num_qtime; iter++) { 20378 param->pairs[iter].qtime_initiator = ( 20379 (uint64_t)q_pair[iter].qmaster_u32 << 32) | 20380 q_pair[iter].qmaster_l32; 20381 param->pairs[iter].qtime_target = ( 20382 (uint64_t)q_pair[iter].qslave_u32 << 32) | 20383 q_pair[iter].qslave_l32; 20384 } 20385 return QDF_STATUS_SUCCESS; 20386 } 20387 #endif /* FEATURE_WLAN_TIME_SYNC_FTM */ 20388 20389 /** 20390 * send_vdev_tsf_tstamp_action_cmd_tlv() - send vdev tsf action command 20391 * @wmi: wmi handle 20392 * @vdev_id: vdev id 20393 * 20394 * TSF_TSTAMP_READ_VALUE is the only operation supported 20395 * Return: QDF_STATUS_SUCCESS for success or error code 20396 */ 20397 static QDF_STATUS 20398 send_vdev_tsf_tstamp_action_cmd_tlv(wmi_unified_t wmi, uint8_t vdev_id) 20399 { 20400 wmi_vdev_tsf_tstamp_action_cmd_fixed_param *cmd; 20401 wmi_buf_t buf; 20402 int32_t len = sizeof(*cmd); 20403 20404 buf = wmi_buf_alloc(wmi, len); 20405 if (!buf) 20406 return QDF_STATUS_E_NOMEM; 20407 20408 cmd = (wmi_vdev_tsf_tstamp_action_cmd_fixed_param *)wmi_buf_data(buf); 20409 WMITLV_SET_HDR(&cmd->tlv_header, 20410 WMITLV_TAG_STRUC_wmi_vdev_tsf_tstamp_action_cmd_fixed_param, 20411 WMITLV_GET_STRUCT_TLVLEN(wmi_vdev_tsf_tstamp_action_cmd_fixed_param)); 20412 cmd->vdev_id = vdev_id; 20413 cmd->tsf_action = TSF_TSTAMP_QTIMER_CAPTURE_REQ; 20414 wmi_mtrace(WMI_VDEV_TSF_TSTAMP_ACTION_CMDID, cmd->vdev_id, 0); 20415 if (wmi_unified_cmd_send(wmi, buf, len, 20416 WMI_VDEV_TSF_TSTAMP_ACTION_CMDID)) { 20417 wmi_err("%s: Failed to send WMI_VDEV_TSF_TSTAMP_ACTION_CMDID", 20418 __func__); 20419 wmi_buf_free(buf); 20420 return QDF_STATUS_E_FAILURE; 20421 } 20422 20423 return QDF_STATUS_SUCCESS; 20424 } 20425 20426 /** 20427 * extract_vdev_tsf_report_event_tlv() - extract vdev tsf report from event 20428 * @wmi_handle: wmi handle 20429 * @evt_buf: pointer to event buffer 20430 * @param: Pointer to struct to hold event info 20431 * 20432 * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure 20433 */ 20434 static QDF_STATUS 20435 extract_vdev_tsf_report_event_tlv(wmi_unified_t wmi_handle, void *evt_buf, 20436 struct wmi_host_tsf_event *param) 20437 { 20438 WMI_VDEV_TSF_REPORT_EVENTID_param_tlvs *param_buf; 20439 wmi_vdev_tsf_report_event_fixed_param *evt; 20440 20441 param_buf = (WMI_VDEV_TSF_REPORT_EVENTID_param_tlvs *)evt_buf; 20442 if (!param_buf) { 20443 wmi_err("Invalid tsf report event buffer"); 20444 return QDF_STATUS_E_INVAL; 20445 } 20446 20447 evt = param_buf->fixed_param; 20448 param->vdev_id = evt->vdev_id; 20449 param->tsf = ((uint64_t)(evt->tsf_high) << 32) | evt->tsf_low; 20450 param->tsf_low = evt->tsf_low; 20451 param->tsf_high = evt->tsf_high; 20452 param->qtimer_low = evt->qtimer_low; 20453 param->qtimer_high = evt->qtimer_high; 20454 param->tsf_id = evt->tsf_id; 20455 param->tsf_id_valid = evt->tsf_id_valid; 20456 param->mac_id = evt->mac_id; 20457 param->mac_id_valid = evt->mac_id_valid; 20458 param->wlan_global_tsf_low = evt->wlan_global_tsf_low; 20459 param->wlan_global_tsf_high = evt->wlan_global_tsf_high; 20460 param->tqm_timer_low = evt->tqm_timer_low; 20461 param->tqm_timer_high = evt->tqm_timer_high; 20462 param->use_tqm_timer = evt->use_tqm_timer; 20463 20464 return QDF_STATUS_SUCCESS; 20465 } 20466 20467 /** 20468 * extract_pdev_csa_switch_count_status_tlv() - extract pdev csa switch count 20469 * status tlv 20470 * @wmi_handle: wmi handle 20471 * @evt_buf: pointer to event buffer 20472 * @param: Pointer to hold csa switch count status event param 20473 * 20474 * Return: QDF_STATUS_SUCCESS for success or error code 20475 */ 20476 static QDF_STATUS extract_pdev_csa_switch_count_status_tlv( 20477 wmi_unified_t wmi_handle, 20478 void *evt_buf, 20479 struct pdev_csa_switch_count_status *param) 20480 { 20481 WMI_PDEV_CSA_SWITCH_COUNT_STATUS_EVENTID_param_tlvs *param_buf; 20482 wmi_pdev_csa_switch_count_status_event_fixed_param *csa_status; 20483 20484 param_buf = (WMI_PDEV_CSA_SWITCH_COUNT_STATUS_EVENTID_param_tlvs *) 20485 evt_buf; 20486 if (!param_buf) { 20487 wmi_err("Invalid CSA status event"); 20488 return QDF_STATUS_E_INVAL; 20489 } 20490 20491 csa_status = param_buf->fixed_param; 20492 20493 param->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host( 20494 wmi_handle, 20495 csa_status->pdev_id); 20496 param->current_switch_count = csa_status->current_switch_count; 20497 param->num_vdevs = csa_status->num_vdevs; 20498 param->vdev_ids = param_buf->vdev_ids; 20499 20500 return QDF_STATUS_SUCCESS; 20501 } 20502 20503 #ifdef CONFIG_AFC_SUPPORT 20504 /** 20505 * send_afc_cmd_tlv() - Sends the AFC indication to FW 20506 * @wmi_handle: wmi handle 20507 * @pdev_id: Pdev id 20508 * @param: Pointer to hold AFC indication. 20509 * 20510 * Return: QDF_STATUS_SUCCESS for success or error code 20511 */ 20512 static 20513 QDF_STATUS send_afc_cmd_tlv(wmi_unified_t wmi_handle, 20514 uint8_t pdev_id, 20515 struct reg_afc_resp_rx_ind_info *param) 20516 { 20517 wmi_buf_t buf; 20518 wmi_afc_cmd_fixed_param *cmd; 20519 uint32_t len; 20520 uint8_t *buf_ptr; 20521 QDF_STATUS ret; 20522 20523 len = sizeof(wmi_afc_cmd_fixed_param); 20524 buf = wmi_buf_alloc(wmi_handle, len); 20525 if (!buf) 20526 return QDF_STATUS_E_NOMEM; 20527 20528 buf_ptr = (uint8_t *)wmi_buf_data(buf); 20529 cmd = (wmi_afc_cmd_fixed_param *)buf_ptr; 20530 20531 WMITLV_SET_HDR(&cmd->tlv_header, 20532 WMITLV_TAG_STRUC_wmi_afc_cmd_fixed_param, 20533 WMITLV_GET_STRUCT_TLVLEN(wmi_afc_cmd_fixed_param)); 20534 20535 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 20536 wmi_handle, 20537 pdev_id); 20538 cmd->cmd_type = param->cmd_type; 20539 cmd->serv_resp_format = param->serv_resp_format; 20540 20541 wmi_mtrace(WMI_AFC_CMDID, NO_SESSION, 0); 20542 ret = wmi_unified_cmd_send(wmi_handle, buf, len, WMI_AFC_CMDID); 20543 if (QDF_IS_STATUS_ERROR(ret)) { 20544 wmi_err("Failed to send WMI_AFC_CMDID"); 20545 wmi_buf_free(buf); 20546 return QDF_STATUS_E_FAILURE; 20547 } 20548 20549 return QDF_STATUS_SUCCESS; 20550 } 20551 #endif 20552 20553 /** 20554 * send_set_tpc_power_cmd_tlv() - Sends the set TPC power level to FW 20555 * @wmi_handle: wmi handle 20556 * @vdev_id: vdev id 20557 * @param: Pointer to hold TX power info 20558 * 20559 * Return: QDF_STATUS_SUCCESS for success or error code 20560 */ 20561 static QDF_STATUS send_set_tpc_power_cmd_tlv(wmi_unified_t wmi_handle, 20562 uint8_t vdev_id, 20563 struct reg_tpc_power_info *param) 20564 { 20565 wmi_buf_t buf; 20566 wmi_vdev_set_tpc_power_fixed_param *tpc_power_info_param; 20567 wmi_vdev_ch_power_info *ch_power_info; 20568 uint8_t *buf_ptr; 20569 uint16_t idx; 20570 uint32_t len; 20571 QDF_STATUS ret; 20572 20573 len = sizeof(wmi_vdev_set_tpc_power_fixed_param) + WMI_TLV_HDR_SIZE; 20574 len += (sizeof(wmi_vdev_ch_power_info) * param->num_pwr_levels); 20575 20576 buf = wmi_buf_alloc(wmi_handle, len); 20577 if (!buf) 20578 return QDF_STATUS_E_NOMEM; 20579 20580 buf_ptr = (uint8_t *)wmi_buf_data(buf); 20581 tpc_power_info_param = (wmi_vdev_set_tpc_power_fixed_param *)buf_ptr; 20582 20583 WMITLV_SET_HDR(&tpc_power_info_param->tlv_header, 20584 WMITLV_TAG_STRUC_wmi_vdev_set_tpc_power_cmd_fixed_param, 20585 WMITLV_GET_STRUCT_TLVLEN(wmi_vdev_set_tpc_power_fixed_param)); 20586 20587 tpc_power_info_param->vdev_id = vdev_id; 20588 tpc_power_info_param->psd_power = param->is_psd_power; 20589 tpc_power_info_param->eirp_power = param->eirp_power; 20590 tpc_power_info_param->power_type_6ghz = param->power_type_6g; 20591 wmi_debug("eirp_power = %d is_psd_power = %d", 20592 tpc_power_info_param->eirp_power, 20593 tpc_power_info_param->psd_power); 20594 reg_print_ap_power_type_6ghz(tpc_power_info_param->power_type_6ghz); 20595 20596 buf_ptr += sizeof(wmi_vdev_set_tpc_power_fixed_param); 20597 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 20598 param->num_pwr_levels * sizeof(wmi_vdev_ch_power_info)); 20599 20600 buf_ptr += WMI_TLV_HDR_SIZE; 20601 ch_power_info = (wmi_vdev_ch_power_info *)buf_ptr; 20602 20603 for (idx = 0; idx < param->num_pwr_levels; ++idx) { 20604 WMITLV_SET_HDR(&ch_power_info[idx].tlv_header, 20605 WMITLV_TAG_STRUC_wmi_vdev_ch_power_info, 20606 WMITLV_GET_STRUCT_TLVLEN(wmi_vdev_ch_power_info)); 20607 ch_power_info[idx].chan_cfreq = 20608 param->chan_power_info[idx].chan_cfreq; 20609 ch_power_info[idx].tx_power = 20610 param->chan_power_info[idx].tx_power; 20611 wmi_debug("chan_cfreq = %d tx_power = %d", 20612 ch_power_info[idx].chan_cfreq, 20613 ch_power_info[idx].tx_power); 20614 buf_ptr += sizeof(wmi_vdev_ch_power_info); 20615 } 20616 20617 wmi_mtrace(WMI_VDEV_SET_TPC_POWER_CMDID, vdev_id, 0); 20618 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 20619 WMI_VDEV_SET_TPC_POWER_CMDID); 20620 if (QDF_IS_STATUS_ERROR(ret)) 20621 wmi_buf_free(buf); 20622 20623 20624 return ret; 20625 } 20626 20627 /** 20628 * extract_dpd_status_ev_param_tlv() - extract dpd status from FW event 20629 * @wmi_handle: wmi handle 20630 * @evt_buf: event buffer 20631 * @param: dpd status info 20632 * 20633 * Return: QDF_STATUS_SUCCESS for success or error code 20634 */ 20635 static QDF_STATUS 20636 extract_dpd_status_ev_param_tlv(wmi_unified_t wmi_handle, 20637 void *evt_buf, 20638 struct wmi_host_pdev_get_dpd_status_event *param) 20639 { 20640 WMI_PDEV_GET_DPD_STATUS_EVENTID_param_tlvs *param_buf; 20641 wmi_pdev_get_dpd_status_evt_fixed_param *dpd_status; 20642 20643 param_buf = (WMI_PDEV_GET_DPD_STATUS_EVENTID_param_tlvs *)evt_buf; 20644 if (!param_buf) { 20645 wmi_err("Invalid get dpd_status event"); 20646 return QDF_STATUS_E_INVAL; 20647 } 20648 20649 dpd_status = param_buf->fixed_param; 20650 param->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host 20651 (wmi_handle, dpd_status->pdev_id); 20652 param->dpd_status = dpd_status->dpd_status; 20653 20654 return QDF_STATUS_SUCCESS; 20655 } 20656 20657 static int 20658 convert_halphy_status(wmi_pdev_get_halphy_cal_status_evt_fixed_param *status, 20659 WMI_HALPHY_CAL_VALID_BITMAP_STATUS valid_bit) 20660 { 20661 if (status->halphy_cal_valid_bmap && valid_bit) 20662 return (status->halphy_cal_status && valid_bit); 20663 20664 return 0; 20665 } 20666 20667 static QDF_STATUS 20668 extract_halphy_cal_status_ev_param_tlv(wmi_unified_t wmi_handle, 20669 void *evt_buf, 20670 struct wmi_host_pdev_get_halphy_cal_status_event *param) 20671 { 20672 WMI_PDEV_GET_HALPHY_CAL_STATUS_EVENTID_param_tlvs *param_buf; 20673 wmi_pdev_get_halphy_cal_status_evt_fixed_param *halphy_cal_status; 20674 20675 param_buf = (WMI_PDEV_GET_HALPHY_CAL_STATUS_EVENTID_param_tlvs *)evt_buf; 20676 if (!param_buf) { 20677 wmi_err("Invalid get halphy cal status event"); 20678 return QDF_STATUS_E_INVAL; 20679 } 20680 20681 halphy_cal_status = param_buf->fixed_param; 20682 param->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host 20683 (wmi_handle, halphy_cal_status->pdev_id); 20684 param->halphy_cal_adc_status = 20685 convert_halphy_status(halphy_cal_status, 20686 WMI_HALPHY_CAL_ADC_BMAP); 20687 param->halphy_cal_bwfilter_status = 20688 convert_halphy_status(halphy_cal_status, 20689 WMI_HALPHY_CAL_BWFILTER_BMAP); 20690 param->halphy_cal_pdet_and_pal_status = 20691 convert_halphy_status(halphy_cal_status, 20692 WMI_HALPHY_CAL_PDET_AND_PAL_BMAP); 20693 param->halphy_cal_rxdco_status = 20694 convert_halphy_status(halphy_cal_status, 20695 WMI_HALPHY_CAL_RXDCO_BMAP); 20696 param->halphy_cal_comb_txiq_rxiq_status = 20697 convert_halphy_status(halphy_cal_status, 20698 WMI_HALPHY_CAL_COMB_TXLO_TXIQ_RXIQ_BMAP); 20699 param->halphy_cal_ibf_status = 20700 convert_halphy_status(halphy_cal_status, 20701 WMI_HALPHY_CAL_IBF_BMAP); 20702 param->halphy_cal_pa_droop_status = 20703 convert_halphy_status(halphy_cal_status, 20704 WMI_HALPHY_CAL_PA_DROOP_BMAP); 20705 param->halphy_cal_dac_status = 20706 convert_halphy_status(halphy_cal_status, 20707 WMI_HALPHY_CAL_DAC_BMAP); 20708 param->halphy_cal_ani_status = 20709 convert_halphy_status(halphy_cal_status, 20710 WMI_HALPHY_CAL_ANI_BMAP); 20711 param->halphy_cal_noise_floor_status = 20712 convert_halphy_status(halphy_cal_status, 20713 WMI_HALPHY_CAL_NOISE_FLOOR_BMAP); 20714 20715 return QDF_STATUS_SUCCESS; 20716 } 20717 20718 /** 20719 * set_halphy_cal_fw_status_to_host_status() - Convert set halphy cal status to host enum 20720 * @fw_status: set halphy cal status from WMI_PDEV_SET_HALPHY_CAL_BMAP_EVENTID event 20721 * 20722 * Return: host_set_halphy_cal_status 20723 */ 20724 static enum wmi_host_set_halphy_cal_status 20725 set_halphy_cal_fw_status_to_host_status(uint32_t fw_status) 20726 { 20727 if (fw_status == 0) 20728 return WMI_HOST_SET_HALPHY_CAL_STATUS_SUCCESS; 20729 else if (fw_status == 1) 20730 return WMI_HOST_SET_HALPHY_CAL_STATUS_FAIL; 20731 20732 wmi_debug("Unknown set halphy status code(%u) from WMI", fw_status); 20733 return WMI_HOST_SET_HALPHY_CAL_STATUS_FAIL; 20734 } 20735 20736 /** 20737 * extract_halphy_cal_ev_param_tlv() - extract dpd status from FW event 20738 * @wmi_handle: wmi handle 20739 * @evt_buf: event buffer 20740 * @param: set halphy cal status info 20741 * 20742 * Return: QDF_STATUS_SUCCESS for success or error code 20743 */ 20744 static QDF_STATUS 20745 extract_halphy_cal_ev_param_tlv(wmi_unified_t wmi_handle, 20746 void *evt_buf, 20747 struct wmi_host_pdev_set_halphy_cal_event *param) 20748 { 20749 WMI_PDEV_SET_HALPHY_CAL_BMAP_EVENTID_param_tlvs *param_buf; 20750 wmi_pdev_set_halphy_cal_bmap_evt_fixed_param *set_halphy_status; 20751 20752 param_buf = (WMI_PDEV_SET_HALPHY_CAL_BMAP_EVENTID_param_tlvs *)evt_buf; 20753 if (!param_buf) { 20754 wmi_err("Invalid set halphy_status event"); 20755 return QDF_STATUS_E_INVAL; 20756 } 20757 20758 set_halphy_status = param_buf->fixed_param; 20759 param->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host 20760 (wmi_handle, set_halphy_status->pdev_id); 20761 param->status = set_halphy_cal_fw_status_to_host_status(set_halphy_status->status); 20762 20763 return QDF_STATUS_SUCCESS; 20764 } 20765 20766 /** 20767 * extract_install_key_comp_event_tlv() - extract install key complete event tlv 20768 * @wmi_handle: wmi handle 20769 * @evt_buf: pointer to event buffer 20770 * @len: length of the event buffer 20771 * @param: Pointer to hold install key complete event param 20772 * 20773 * Return: QDF_STATUS_SUCCESS for success or error code 20774 */ 20775 static QDF_STATUS 20776 extract_install_key_comp_event_tlv(wmi_unified_t wmi_handle, 20777 void *evt_buf, uint32_t len, 20778 struct wmi_install_key_comp_event *param) 20779 { 20780 WMI_VDEV_INSTALL_KEY_COMPLETE_EVENTID_param_tlvs *param_buf; 20781 wmi_vdev_install_key_complete_event_fixed_param *key_fp; 20782 20783 if (len < sizeof(*param_buf)) { 20784 wmi_err("invalid event buf len %d", len); 20785 return QDF_STATUS_E_INVAL; 20786 } 20787 20788 param_buf = (WMI_VDEV_INSTALL_KEY_COMPLETE_EVENTID_param_tlvs *)evt_buf; 20789 if (!param_buf) { 20790 wmi_err("received null buf from target"); 20791 return QDF_STATUS_E_INVAL; 20792 } 20793 20794 key_fp = param_buf->fixed_param; 20795 if (!key_fp) { 20796 wmi_err("received null event data from target"); 20797 return QDF_STATUS_E_INVAL; 20798 } 20799 20800 param->vdev_id = key_fp->vdev_id; 20801 param->key_ix = key_fp->key_ix; 20802 param->key_flags = key_fp->key_flags; 20803 param->status = key_fp->status; 20804 WMI_MAC_ADDR_TO_CHAR_ARRAY(&key_fp->peer_macaddr, 20805 param->peer_macaddr); 20806 20807 return QDF_STATUS_SUCCESS; 20808 } 20809 20810 static QDF_STATUS 20811 send_set_halphy_cal_tlv(wmi_unified_t wmi_handle, 20812 struct wmi_host_send_set_halphy_cal_info *param) 20813 { 20814 wmi_buf_t buf; 20815 wmi_pdev_set_halphy_cal_bmap_cmd_fixed_param *cmd; 20816 QDF_STATUS ret; 20817 uint32_t len; 20818 20819 len = sizeof(*cmd); 20820 20821 buf = wmi_buf_alloc(wmi_handle, len); 20822 if (!buf) 20823 return QDF_STATUS_E_FAILURE; 20824 20825 cmd = (void *)wmi_buf_data(buf); 20826 20827 WMITLV_SET_HDR(&cmd->tlv_header, 20828 WMITLV_TAG_STRUC_wmi_pdev_set_halphy_cal_bmap_cmd_fixed_param, 20829 WMITLV_GET_STRUCT_TLVLEN(wmi_pdev_set_halphy_cal_bmap_cmd_fixed_param)); 20830 20831 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target(wmi_handle, 20832 param->pdev_id); 20833 cmd->online_halphy_cals_bmap = param->value; 20834 cmd->home_scan_channel = param->chan_sel; 20835 20836 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 20837 WMI_PDEV_SET_HALPHY_CAL_BMAP_CMDID); 20838 if (QDF_IS_STATUS_ERROR(ret)) { 20839 wmi_err("WMI_PDEV_SET_HALPHY_CAL_BMAP_CMDID send returned Error %d",ret); 20840 wmi_buf_free(buf); 20841 } 20842 20843 return ret; 20844 } 20845 20846 #ifdef WLAN_FEATURE_DYNAMIC_MAC_ADDR_UPDATE 20847 /** 20848 * send_set_mac_address_cmd_tlv() - send set MAC address command to fw 20849 * @wmi: wmi handle 20850 * @params: set MAC address command params 20851 * 20852 * Return: QDF_STATUS_SUCCESS for success or error code 20853 */ 20854 static QDF_STATUS 20855 send_set_mac_address_cmd_tlv(wmi_unified_t wmi, 20856 struct set_mac_addr_params *params) 20857 { 20858 wmi_vdev_update_mac_addr_cmd_fixed_param *cmd; 20859 wmi_buf_t buf; 20860 int32_t len = sizeof(*cmd); 20861 20862 buf = wmi_buf_alloc(wmi, len); 20863 if (!buf) 20864 return QDF_STATUS_E_NOMEM; 20865 20866 cmd = (wmi_vdev_update_mac_addr_cmd_fixed_param *)wmi_buf_data(buf); 20867 WMITLV_SET_HDR( 20868 &cmd->tlv_header, 20869 WMITLV_TAG_STRUC_wmi_vdev_update_mac_addr_cmd_fixed_param, 20870 WMITLV_GET_STRUCT_TLVLEN 20871 (wmi_vdev_update_mac_addr_cmd_fixed_param)); 20872 cmd->vdev_id = params->vdev_id; 20873 WMI_CHAR_ARRAY_TO_MAC_ADDR(params->mac_addr.bytes, &cmd->vdev_macaddr); 20874 WMI_CHAR_ARRAY_TO_MAC_ADDR(params->mld_addr.bytes, &cmd->mld_macaddr); 20875 20876 wmi_debug("vdev %d mac_addr " QDF_MAC_ADDR_FMT " mld_addr " 20877 QDF_MAC_ADDR_FMT, cmd->vdev_id, 20878 QDF_MAC_ADDR_REF(params->mac_addr.bytes), 20879 QDF_MAC_ADDR_REF(params->mld_addr.bytes)); 20880 wmi_mtrace(WMI_VDEV_UPDATE_MAC_ADDR_CMDID, cmd->vdev_id, 0); 20881 if (wmi_unified_cmd_send(wmi, buf, len, 20882 WMI_VDEV_UPDATE_MAC_ADDR_CMDID)) { 20883 wmi_buf_free(buf); 20884 return QDF_STATUS_E_FAILURE; 20885 } 20886 20887 return QDF_STATUS_SUCCESS; 20888 } 20889 20890 /** 20891 * extract_update_mac_address_event_tlv() - extract update MAC address event 20892 * @wmi_handle: WMI handle 20893 * @evt_buf: event buffer 20894 * @vdev_id: VDEV ID 20895 * @status: FW status of the set MAC address operation 20896 * 20897 * Return: QDF_STATUS 20898 */ 20899 static QDF_STATUS extract_update_mac_address_event_tlv( 20900 wmi_unified_t wmi_handle, void *evt_buf, 20901 uint8_t *vdev_id, uint8_t *status) 20902 { 20903 WMI_VDEV_UPDATE_MAC_ADDR_CONF_EVENTID_param_tlvs *param_buf; 20904 wmi_vdev_update_mac_addr_conf_event_fixed_param *event; 20905 20906 param_buf = 20907 (WMI_VDEV_UPDATE_MAC_ADDR_CONF_EVENTID_param_tlvs *)evt_buf; 20908 20909 event = param_buf->fixed_param; 20910 20911 *vdev_id = event->vdev_id; 20912 *status = event->status; 20913 20914 return QDF_STATUS_SUCCESS; 20915 } 20916 #endif 20917 20918 #ifdef WLAN_FEATURE_11BE_MLO 20919 /** 20920 * extract_quiet_offload_event_tlv() - extract quiet offload event 20921 * @wmi_handle: WMI handle 20922 * @evt_buf: event buffer 20923 * @quiet_event: quiet event extracted from the buffer 20924 * 20925 * Return: QDF_STATUS 20926 */ 20927 static QDF_STATUS extract_quiet_offload_event_tlv( 20928 wmi_unified_t wmi_handle, void *evt_buf, 20929 struct vdev_sta_quiet_event *quiet_event) 20930 { 20931 WMI_QUIET_HANDLING_EVENTID_param_tlvs *param_buf; 20932 wmi_quiet_event_fixed_param *event; 20933 20934 param_buf = (WMI_QUIET_HANDLING_EVENTID_param_tlvs *)evt_buf; 20935 20936 event = param_buf->fixed_param; 20937 20938 if (!(event->mld_mac_address_present && event->linkid_present) && 20939 !event->link_mac_address_present) { 20940 wmi_err("Invalid sta quiet offload event. present bit: mld mac %d link mac %d linkid %d", 20941 event->mld_mac_address_present, 20942 event->linkid_present, 20943 event->link_mac_address_present); 20944 return QDF_STATUS_E_INVAL; 20945 } 20946 20947 if (event->mld_mac_address_present) 20948 WMI_MAC_ADDR_TO_CHAR_ARRAY(&event->mld_mac_address, 20949 quiet_event->mld_mac.bytes); 20950 if (event->link_mac_address_present) 20951 WMI_MAC_ADDR_TO_CHAR_ARRAY(&event->link_mac_address, 20952 quiet_event->link_mac.bytes); 20953 if (event->linkid_present) 20954 quiet_event->link_id = event->linkid; 20955 quiet_event->quiet_status = (event->quiet_status == 20956 WMI_QUIET_EVENT_START); 20957 20958 return QDF_STATUS_SUCCESS; 20959 } 20960 #endif 20961 20962 /** 20963 * send_vdev_pn_mgmt_rxfilter_cmd_tlv() - Send PN mgmt RxFilter command to FW 20964 * @wmi_handle: wmi handle 20965 * @params: RxFilter params 20966 * 20967 * Return: QDF_STATUS_SUCCESS for success or error code 20968 */ 20969 static QDF_STATUS 20970 send_vdev_pn_mgmt_rxfilter_cmd_tlv(wmi_unified_t wmi_handle, 20971 struct vdev_pn_mgmt_rxfilter_params *params) 20972 { 20973 wmi_vdev_pn_mgmt_rx_filter_cmd_fixed_param *cmd; 20974 wmi_buf_t buf; 20975 uint32_t len = sizeof(wmi_vdev_pn_mgmt_rx_filter_cmd_fixed_param); 20976 20977 if (!is_service_enabled_tlv(wmi_handle, 20978 WMI_SERVICE_PN_REPLAY_CHECK_SUPPORT)) { 20979 wmi_err("Rx PN Replay Check not supported by target"); 20980 return QDF_STATUS_E_NOSUPPORT; 20981 } 20982 20983 buf = wmi_buf_alloc(wmi_handle, len); 20984 if (!buf) { 20985 wmi_err("wmi buf alloc failed"); 20986 return QDF_STATUS_E_NOMEM; 20987 } 20988 20989 cmd = (wmi_vdev_pn_mgmt_rx_filter_cmd_fixed_param *)wmi_buf_data(buf); 20990 WMITLV_SET_HDR( 20991 &cmd->tlv_header, 20992 WMITLV_TAG_STRUC_wmi_vdev_pn_mgmt_rx_filter_cmd_fixed_param, 20993 WMITLV_GET_STRUCT_TLVLEN 20994 (wmi_vdev_pn_mgmt_rx_filter_cmd_fixed_param)); 20995 20996 cmd->vdev_id = params->vdev_id; 20997 cmd->pn_rx_filter = params->pn_rxfilter; 20998 20999 if (wmi_unified_cmd_send(wmi_handle, buf, len, 21000 WMI_VDEV_PN_MGMT_RX_FILTER_CMDID)) { 21001 wmi_err("Failed to send WMI command"); 21002 wmi_buf_free(buf); 21003 return QDF_STATUS_E_FAILURE; 21004 } 21005 21006 return QDF_STATUS_SUCCESS; 21007 } 21008 21009 static QDF_STATUS 21010 send_egid_info_cmd_tlv(wmi_unified_t wmi_handle, 21011 struct esl_egid_params *param) 21012 { 21013 wmi_esl_egid_cmd_fixed_param *cmd; 21014 wmi_buf_t buf; 21015 21016 uint32_t len = sizeof(*cmd); 21017 21018 buf = wmi_buf_alloc(wmi_handle, len); 21019 if (!buf) { 21020 wmi_err("wmi_buf_alloc failed"); 21021 return QDF_STATUS_E_NOMEM; 21022 } 21023 21024 cmd = (wmi_esl_egid_cmd_fixed_param *)wmi_buf_data(buf); 21025 WMITLV_SET_HDR( 21026 &cmd->tlv_header, 21027 WMITLV_TAG_STRUC_wmi_esl_egid_cmd_fixed_param, 21028 WMITLV_GET_STRUCT_TLVLEN(wmi_esl_egid_cmd_fixed_param)); 21029 qdf_mem_copy(cmd->egid_info, 21030 param->egid_info, 21031 sizeof(param->egid_info)); 21032 if (wmi_unified_cmd_send(wmi_handle, buf, len, WMI_ESL_EGID_CMDID)) { 21033 wmi_err("Failed to send WMI command"); 21034 wmi_buf_free(buf); 21035 return QDF_STATUS_E_FAILURE; 21036 } 21037 21038 return QDF_STATUS_SUCCESS; 21039 } 21040 21041 static QDF_STATUS 21042 extract_pktlog_decode_info_event_tlv(wmi_unified_t wmi_handle, void *evt_buf, 21043 uint8_t *pdev_id, uint8_t *software_image, 21044 uint8_t *chip_info, 21045 uint32_t *pktlog_json_version) 21046 { 21047 WMI_PDEV_PKTLOG_DECODE_INFO_EVENTID_param_tlvs *param_buf; 21048 wmi_pdev_pktlog_decode_info_evt_fixed_param *event; 21049 21050 param_buf = 21051 (WMI_PDEV_PKTLOG_DECODE_INFO_EVENTID_param_tlvs *)evt_buf; 21052 21053 event = param_buf->fixed_param; 21054 21055 if ((event->software_image[0] == '\0') || 21056 (event->chip_info[0] == '\0')) { 21057 *pdev_id = event->pdev_id; 21058 return QDF_STATUS_E_INVAL; 21059 } 21060 21061 qdf_mem_copy(software_image, event->software_image, 40); 21062 qdf_mem_copy(chip_info, event->chip_info, 40); 21063 *pktlog_json_version = event->pktlog_defs_json_version; 21064 *pdev_id = event->pdev_id; 21065 return QDF_STATUS_SUCCESS; 21066 } 21067 21068 #ifdef HEALTH_MON_SUPPORT 21069 /** 21070 * extract_health_mon_init_done_info_event_tlv() - Extract health monitor from 21071 * fw 21072 * @wmi_handle: wmi handle 21073 * @evt_buf: pointer to event buffer 21074 * @param: health monitor params 21075 * 21076 * Return: QDF_STATUS_SUCCESS for success or error code 21077 */ 21078 static QDF_STATUS 21079 extract_health_mon_init_done_info_event_tlv(wmi_unified_t wmi_handle, 21080 void *evt_buf, 21081 struct wmi_health_mon_params *param) 21082 { 21083 WMI_HEALTH_MON_INIT_DONE_EVENTID_param_tlvs *param_buf; 21084 wmi_health_mon_init_done_fixed_param *event; 21085 21086 param_buf = 21087 (WMI_HEALTH_MON_INIT_DONE_EVENTID_param_tlvs *)evt_buf; 21088 21089 event = param_buf->fixed_param; 21090 21091 param->ring_buf_paddr_low = event->ring_buf_paddr_low; 21092 param->ring_buf_paddr_high = event->ring_buf_paddr_high; 21093 param->initial_upload_period_ms = event->initial_upload_period_ms; 21094 param->read_index = 0; 21095 21096 return QDF_STATUS_SUCCESS; 21097 } 21098 #endif /* HEALTH_MON_SUPPORT */ 21099 21100 /** 21101 * extract_pdev_telemetry_stats_tlv - extract pdev telemetry stats 21102 * @wmi_handle: wmi handle 21103 * @evt_buf: pointer to event buffer 21104 * @pdev_stats: Pointer to hold pdev telemetry stats 21105 * 21106 * Return: QDF_STATUS_SUCCESS for success or error code 21107 */ 21108 static QDF_STATUS 21109 extract_pdev_telemetry_stats_tlv( 21110 wmi_unified_t wmi_handle, void *evt_buf, 21111 struct wmi_host_pdev_telemetry_stats *pdev_stats) 21112 { 21113 WMI_UPDATE_STATS_EVENTID_param_tlvs *param_buf; 21114 wmi_pdev_telemetry_stats *ev; 21115 21116 param_buf = (WMI_UPDATE_STATS_EVENTID_param_tlvs *)evt_buf; 21117 21118 if (param_buf->pdev_telemetry_stats) { 21119 ev = (wmi_pdev_telemetry_stats *)(param_buf->pdev_telemetry_stats); 21120 qdf_mem_copy(pdev_stats->avg_chan_lat_per_ac, 21121 ev->avg_chan_lat_per_ac, 21122 sizeof(ev->avg_chan_lat_per_ac)); 21123 pdev_stats->estimated_air_time_per_ac = 21124 ev->estimated_air_time_per_ac; 21125 } 21126 21127 return QDF_STATUS_SUCCESS; 21128 } 21129 21130 static QDF_STATUS 21131 send_set_mac_addr_rx_filter_cmd_tlv(wmi_unified_t wmi_handle, 21132 struct set_rx_mac_filter *param) 21133 { 21134 wmi_vdev_add_mac_addr_to_rx_filter_cmd_fixed_param *cmd; 21135 uint32_t len; 21136 wmi_buf_t buf; 21137 int ret; 21138 21139 if (!wmi_handle) { 21140 wmi_err("WMA context is invalid!"); 21141 return QDF_STATUS_E_INVAL; 21142 } 21143 21144 len = sizeof(*cmd); 21145 buf = wmi_buf_alloc(wmi_handle, len); 21146 if (!buf) { 21147 wmi_err("Failed allocate wmi buffer"); 21148 return QDF_STATUS_E_NOMEM; 21149 } 21150 21151 cmd = (wmi_vdev_add_mac_addr_to_rx_filter_cmd_fixed_param *) 21152 wmi_buf_data(buf); 21153 21154 WMITLV_SET_HDR( 21155 &cmd->tlv_header, 21156 WMITLV_TAG_STRUC_wmi_vdev_add_mac_addr_to_rx_filter_cmd_fixed_param, 21157 WMITLV_GET_STRUCT_TLVLEN( 21158 wmi_vdev_add_mac_addr_to_rx_filter_cmd_fixed_param)); 21159 21160 cmd->vdev_id = param->vdev_id; 21161 cmd->freq = param->freq; 21162 WMI_CHAR_ARRAY_TO_MAC_ADDR(param->mac, &cmd->mac_addr); 21163 if (param->set) 21164 cmd->enable = 1; 21165 else 21166 cmd->enable = 0; 21167 wmi_debug("set random mac rx vdev:%d freq:%d set:%d " QDF_MAC_ADDR_FMT, 21168 param->vdev_id, param->freq, param->set, 21169 QDF_MAC_ADDR_REF(param->mac)); 21170 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 21171 WMI_VDEV_ADD_MAC_ADDR_TO_RX_FILTER_CMDID); 21172 if (ret) { 21173 wmi_err("Failed to send action frame random mac cmd"); 21174 wmi_buf_free(buf); 21175 return QDF_STATUS_E_FAILURE; 21176 } 21177 21178 return QDF_STATUS_SUCCESS; 21179 } 21180 21181 static QDF_STATUS 21182 extract_sap_coex_fix_chan_caps(wmi_unified_t wmi_handle, 21183 uint8_t *event, 21184 struct wmi_host_coex_fix_chan_cap *cap) 21185 { 21186 WMI_SERVICE_READY_EXT2_EVENTID_param_tlvs *param_buf; 21187 WMI_COEX_FIX_CHANNEL_CAPABILITIES *fw_cap; 21188 21189 param_buf = (WMI_SERVICE_READY_EXT2_EVENTID_param_tlvs *)event; 21190 if (!param_buf) 21191 return QDF_STATUS_E_INVAL; 21192 21193 fw_cap = param_buf->coex_fix_channel_caps; 21194 if (!fw_cap) 21195 return QDF_STATUS_E_INVAL; 21196 21197 cap->fix_chan_priority = fw_cap->fix_channel_priority; 21198 21199 return QDF_STATUS_SUCCESS; 21200 } 21201 21202 static QDF_STATUS extract_tgtr2p_table_event_tlv(wmi_unified_t wmi_handle, 21203 uint8_t *evt_buf, 21204 struct r2p_table_update_status_obj *update_status, 21205 uint32_t len) 21206 { 21207 WMI_PDEV_SET_TGTR2P_TABLE_EVENTID_param_tlvs *param_buf; 21208 wmi_pdev_set_tgtr2p_table_event_fixed_param *event_fixed_hdr; 21209 21210 param_buf = (WMI_PDEV_SET_TGTR2P_TABLE_EVENTID_param_tlvs *)evt_buf; 21211 if (!param_buf) { 21212 wmi_err("Invalid TGTR2P event buf"); 21213 return QDF_STATUS_E_FAILURE; 21214 } 21215 21216 event_fixed_hdr = param_buf->fixed_param; 21217 update_status->pdev_id = event_fixed_hdr->pdev_id; 21218 update_status->status = event_fixed_hdr->status; 21219 21220 if (update_status->status != WMI_PDEV_TGTR2P_SUCCESS && 21221 update_status->status != 21222 WMI_PDEV_TGTR2P_SUCCESS_WAITING_FOR_END_OF_UPDATE) { 21223 wmi_err("Rate2Power table update failed. Status = %d", 21224 update_status->status); 21225 } 21226 21227 return QDF_STATUS_SUCCESS; 21228 } 21229 21230 struct wmi_ops tlv_ops = { 21231 .send_vdev_create_cmd = send_vdev_create_cmd_tlv, 21232 .send_vdev_delete_cmd = send_vdev_delete_cmd_tlv, 21233 .send_vdev_nss_chain_params_cmd = send_vdev_nss_chain_params_cmd_tlv, 21234 .send_vdev_down_cmd = send_vdev_down_cmd_tlv, 21235 .send_vdev_start_cmd = send_vdev_start_cmd_tlv, 21236 .send_peer_flush_tids_cmd = send_peer_flush_tids_cmd_tlv, 21237 .send_peer_param_cmd = send_peer_param_cmd_tlv, 21238 .send_vdev_up_cmd = send_vdev_up_cmd_tlv, 21239 .send_vdev_stop_cmd = send_vdev_stop_cmd_tlv, 21240 .send_peer_create_cmd = send_peer_create_cmd_tlv, 21241 .send_peer_delete_cmd = send_peer_delete_cmd_tlv, 21242 .send_peer_delete_all_cmd = send_peer_delete_all_cmd_tlv, 21243 .send_peer_rx_reorder_queue_setup_cmd = 21244 send_peer_rx_reorder_queue_setup_cmd_tlv, 21245 .send_peer_rx_reorder_queue_remove_cmd = 21246 send_peer_rx_reorder_queue_remove_cmd_tlv, 21247 .send_pdev_utf_cmd = send_pdev_utf_cmd_tlv, 21248 .send_pdev_param_cmd = send_pdev_param_cmd_tlv, 21249 .send_multiple_pdev_param_cmd = send_multiple_pdev_param_cmd_tlv, 21250 .send_pdev_set_hw_mode_cmd = send_pdev_set_hw_mode_cmd_tlv, 21251 .send_pdev_set_rf_path_cmd = send_pdev_set_rf_path_cmd_tlv, 21252 .send_suspend_cmd = send_suspend_cmd_tlv, 21253 .send_resume_cmd = send_resume_cmd_tlv, 21254 .send_wow_enable_cmd = send_wow_enable_cmd_tlv, 21255 .send_set_ap_ps_param_cmd = send_set_ap_ps_param_cmd_tlv, 21256 .send_set_sta_ps_param_cmd = send_set_sta_ps_param_cmd_tlv, 21257 .send_crash_inject_cmd = send_crash_inject_cmd_tlv, 21258 .send_dbglog_cmd = send_dbglog_cmd_tlv, 21259 .send_vdev_set_param_cmd = send_vdev_set_param_cmd_tlv, 21260 .send_vdev_set_mu_snif_cmd = send_vdev_set_mu_snif_cmd_tlv, 21261 .send_packet_log_enable_cmd = send_packet_log_enable_cmd_tlv, 21262 .send_peer_based_pktlog_cmd = send_peer_based_pktlog_cmd, 21263 .send_time_stamp_sync_cmd = send_time_stamp_sync_cmd_tlv, 21264 .send_packet_log_disable_cmd = send_packet_log_disable_cmd_tlv, 21265 .send_beacon_tmpl_send_cmd = send_beacon_tmpl_send_cmd_tlv, 21266 .send_fd_tmpl_cmd = send_fd_tmpl_cmd_tlv, 21267 .send_peer_assoc_cmd = send_peer_assoc_cmd_tlv, 21268 .send_scan_start_cmd = send_scan_start_cmd_tlv, 21269 .send_scan_stop_cmd = send_scan_stop_cmd_tlv, 21270 .send_scan_chan_list_cmd = send_scan_chan_list_cmd_tlv, 21271 .send_mgmt_cmd = send_mgmt_cmd_tlv, 21272 .send_offchan_data_tx_cmd = send_offchan_data_tx_cmd_tlv, 21273 .send_modem_power_state_cmd = send_modem_power_state_cmd_tlv, 21274 .send_set_sta_ps_mode_cmd = send_set_sta_ps_mode_cmd_tlv, 21275 .send_idle_roam_monitor_cmd = send_idle_roam_monitor_cmd_tlv, 21276 .send_set_sta_uapsd_auto_trig_cmd = 21277 send_set_sta_uapsd_auto_trig_cmd_tlv, 21278 .send_get_temperature_cmd = send_get_temperature_cmd_tlv, 21279 .send_set_smps_params_cmd = send_set_smps_params_cmd_tlv, 21280 .send_set_mimops_cmd = send_set_mimops_cmd_tlv, 21281 .send_set_thermal_mgmt_cmd = send_set_thermal_mgmt_cmd_tlv, 21282 .send_lro_config_cmd = send_lro_config_cmd_tlv, 21283 .send_peer_rate_report_cmd = send_peer_rate_report_cmd_tlv, 21284 .send_probe_rsp_tmpl_send_cmd = 21285 send_probe_rsp_tmpl_send_cmd_tlv, 21286 .send_p2p_go_set_beacon_ie_cmd = 21287 send_p2p_go_set_beacon_ie_cmd_tlv, 21288 .send_setup_install_key_cmd = 21289 send_setup_install_key_cmd_tlv, 21290 .send_scan_probe_setoui_cmd = 21291 send_scan_probe_setoui_cmd_tlv, 21292 #ifdef IPA_OFFLOAD 21293 .send_ipa_offload_control_cmd = 21294 send_ipa_offload_control_cmd_tlv, 21295 #endif 21296 .send_pno_stop_cmd = send_pno_stop_cmd_tlv, 21297 .send_pno_start_cmd = send_pno_start_cmd_tlv, 21298 .send_obss_disable_cmd = send_obss_disable_cmd_tlv, 21299 .send_nlo_mawc_cmd = send_nlo_mawc_cmd_tlv, 21300 #ifdef WLAN_FEATURE_LINK_LAYER_STATS 21301 .send_process_ll_stats_clear_cmd = send_process_ll_stats_clear_cmd_tlv, 21302 .send_process_ll_stats_set_cmd = send_process_ll_stats_set_cmd_tlv, 21303 .send_process_ll_stats_get_cmd = send_process_ll_stats_get_cmd_tlv, 21304 #ifdef FEATURE_CLUB_LL_STATS_AND_GET_STATION 21305 .send_unified_ll_stats_get_sta_cmd = 21306 send_unified_ll_stats_get_sta_cmd_tlv, 21307 #endif /* FEATURE_CLUB_LL_STATS_AND_GET_STATION */ 21308 #endif /* WLAN_FEATURE_LINK_LAYER_STATS*/ 21309 .send_congestion_cmd = send_congestion_cmd_tlv, 21310 .send_snr_request_cmd = send_snr_request_cmd_tlv, 21311 .send_snr_cmd = send_snr_cmd_tlv, 21312 .send_link_status_req_cmd = send_link_status_req_cmd_tlv, 21313 #if !defined(REMOVE_PKT_LOG) && defined(FEATURE_PKTLOG) 21314 .send_pktlog_wmi_send_cmd = send_pktlog_wmi_send_cmd_tlv, 21315 #endif 21316 #ifdef WLAN_SUPPORT_GREEN_AP 21317 .send_egap_conf_params_cmd = send_egap_conf_params_cmd_tlv, 21318 .send_green_ap_ps_cmd = send_green_ap_ps_cmd_tlv, 21319 .extract_green_ap_egap_status_info = 21320 extract_green_ap_egap_status_info_tlv, 21321 #endif 21322 #ifdef WLAN_SUPPORT_GAP_LL_PS_MODE 21323 .send_green_ap_ll_ps_cmd = send_green_ap_ll_ps_cmd_tlv, 21324 .extract_green_ap_ll_ps_param = extract_green_ap_ll_ps_param_tlv, 21325 #endif 21326 .send_csa_offload_enable_cmd = send_csa_offload_enable_cmd_tlv, 21327 .send_start_oem_data_cmd = send_start_oem_data_cmd_tlv, 21328 #ifdef FEATURE_OEM_DATA 21329 .send_start_oemv2_data_cmd = send_start_oemv2_data_cmd_tlv, 21330 #endif 21331 #ifdef WLAN_FEATURE_CIF_CFR 21332 .send_oem_dma_cfg_cmd = send_oem_dma_cfg_cmd_tlv, 21333 #endif 21334 .send_dfs_phyerr_filter_offload_en_cmd = 21335 send_dfs_phyerr_filter_offload_en_cmd_tlv, 21336 .send_stats_ext_req_cmd = send_stats_ext_req_cmd_tlv, 21337 .send_process_dhcpserver_offload_cmd = 21338 send_process_dhcpserver_offload_cmd_tlv, 21339 .send_pdev_set_regdomain_cmd = 21340 send_pdev_set_regdomain_cmd_tlv, 21341 .send_regdomain_info_to_fw_cmd = send_regdomain_info_to_fw_cmd_tlv, 21342 .send_cfg_action_frm_tb_ppdu_cmd = send_cfg_action_frm_tb_ppdu_cmd_tlv, 21343 .save_fw_version_cmd = save_fw_version_cmd_tlv, 21344 .check_and_update_fw_version = 21345 check_and_update_fw_version_cmd_tlv, 21346 .send_log_supported_evt_cmd = send_log_supported_evt_cmd_tlv, 21347 .send_enable_specific_fw_logs_cmd = 21348 send_enable_specific_fw_logs_cmd_tlv, 21349 .send_flush_logs_to_fw_cmd = send_flush_logs_to_fw_cmd_tlv, 21350 .send_unit_test_cmd = send_unit_test_cmd_tlv, 21351 #ifdef FEATURE_WLAN_APF 21352 .send_set_active_apf_mode_cmd = wmi_send_set_active_apf_mode_cmd_tlv, 21353 .send_apf_enable_cmd = wmi_send_apf_enable_cmd_tlv, 21354 .send_apf_write_work_memory_cmd = 21355 wmi_send_apf_write_work_memory_cmd_tlv, 21356 .send_apf_read_work_memory_cmd = 21357 wmi_send_apf_read_work_memory_cmd_tlv, 21358 .extract_apf_read_memory_resp_event = 21359 wmi_extract_apf_read_memory_resp_event_tlv, 21360 #endif /* FEATURE_WLAN_APF */ 21361 .init_cmd_send = init_cmd_send_tlv, 21362 .send_vdev_set_custom_aggr_size_cmd = 21363 send_vdev_set_custom_aggr_size_cmd_tlv, 21364 .send_vdev_set_qdepth_thresh_cmd = 21365 send_vdev_set_qdepth_thresh_cmd_tlv, 21366 .send_set_vap_dscp_tid_map_cmd = send_set_vap_dscp_tid_map_cmd_tlv, 21367 .send_vdev_set_fwtest_param_cmd = send_vdev_set_fwtest_param_cmd_tlv, 21368 .send_phyerr_disable_cmd = send_phyerr_disable_cmd_tlv, 21369 .send_phyerr_enable_cmd = send_phyerr_enable_cmd_tlv, 21370 .send_periodic_chan_stats_config_cmd = 21371 send_periodic_chan_stats_config_cmd_tlv, 21372 #ifdef WLAN_IOT_SIM_SUPPORT 21373 .send_simulation_test_cmd = send_simulation_test_cmd_tlv, 21374 #endif 21375 .send_vdev_spectral_configure_cmd = 21376 send_vdev_spectral_configure_cmd_tlv, 21377 .send_vdev_spectral_enable_cmd = 21378 send_vdev_spectral_enable_cmd_tlv, 21379 #ifdef WLAN_CONV_SPECTRAL_ENABLE 21380 .extract_pdev_sscan_fw_cmd_fixed_param = 21381 extract_pdev_sscan_fw_cmd_fixed_param_tlv, 21382 .extract_pdev_sscan_fft_bin_index = 21383 extract_pdev_sscan_fft_bin_index_tlv, 21384 .extract_pdev_spectral_session_chan_info = 21385 extract_pdev_spectral_session_chan_info_tlv, 21386 .extract_pdev_spectral_session_detector_info = 21387 extract_pdev_spectral_session_detector_info_tlv, 21388 .extract_spectral_caps_fixed_param = 21389 extract_spectral_caps_fixed_param_tlv, 21390 .extract_spectral_scan_bw_caps = 21391 extract_spectral_scan_bw_caps_tlv, 21392 .extract_spectral_fft_size_caps = 21393 extract_spectral_fft_size_caps_tlv, 21394 #endif /* WLAN_CONV_SPECTRAL_ENABLE */ 21395 .send_thermal_mitigation_param_cmd = 21396 send_thermal_mitigation_param_cmd_tlv, 21397 .send_process_update_edca_param_cmd = 21398 send_process_update_edca_param_cmd_tlv, 21399 .send_bss_color_change_enable_cmd = 21400 send_bss_color_change_enable_cmd_tlv, 21401 .send_coex_config_cmd = send_coex_config_cmd_tlv, 21402 .send_set_country_cmd = send_set_country_cmd_tlv, 21403 .send_addba_send_cmd = send_addba_send_cmd_tlv, 21404 .send_delba_send_cmd = send_delba_send_cmd_tlv, 21405 .send_addba_clearresponse_cmd = send_addba_clearresponse_cmd_tlv, 21406 .get_target_cap_from_service_ready = extract_service_ready_tlv, 21407 .extract_hal_reg_cap = extract_hal_reg_cap_tlv, 21408 .extract_num_mem_reqs = extract_num_mem_reqs_tlv, 21409 .extract_host_mem_req = extract_host_mem_req_tlv, 21410 .save_service_bitmap = save_service_bitmap_tlv, 21411 .save_ext_service_bitmap = save_ext_service_bitmap_tlv, 21412 .is_service_enabled = is_service_enabled_tlv, 21413 .save_fw_version = save_fw_version_in_service_ready_tlv, 21414 .ready_extract_init_status = ready_extract_init_status_tlv, 21415 .ready_extract_mac_addr = ready_extract_mac_addr_tlv, 21416 .ready_extract_mac_addr_list = ready_extract_mac_addr_list_tlv, 21417 .extract_ready_event_params = extract_ready_event_params_tlv, 21418 .extract_dbglog_data_len = extract_dbglog_data_len_tlv, 21419 .extract_mgmt_rx_params = extract_mgmt_rx_params_tlv, 21420 .extract_frame_pn_params = extract_frame_pn_params_tlv, 21421 .extract_is_conn_ap_frame = extract_is_conn_ap_frm_param_tlv, 21422 .extract_vdev_roam_param = extract_vdev_roam_param_tlv, 21423 .extract_vdev_scan_ev_param = extract_vdev_scan_ev_param_tlv, 21424 #ifdef FEATURE_WLAN_SCAN_PNO 21425 .extract_nlo_match_ev_param = extract_nlo_match_ev_param_tlv, 21426 .extract_nlo_complete_ev_param = extract_nlo_complete_ev_param_tlv, 21427 #endif 21428 .extract_unit_test = extract_unit_test_tlv, 21429 .extract_pdev_ext_stats = extract_pdev_ext_stats_tlv, 21430 .extract_bcn_stats = extract_bcn_stats_tlv, 21431 .extract_bcnflt_stats = extract_bcnflt_stats_tlv, 21432 .extract_chan_stats = extract_chan_stats_tlv, 21433 .extract_vdev_prb_fils_stats = extract_vdev_prb_fils_stats_tlv, 21434 .extract_profile_ctx = extract_profile_ctx_tlv, 21435 .extract_profile_data = extract_profile_data_tlv, 21436 .send_fw_test_cmd = send_fw_test_cmd_tlv, 21437 .send_wfa_test_cmd = send_wfa_test_cmd_tlv, 21438 .send_power_dbg_cmd = send_power_dbg_cmd_tlv, 21439 .extract_service_ready_ext = extract_service_ready_ext_tlv, 21440 .extract_service_ready_ext2 = extract_service_ready_ext2_tlv, 21441 .extract_dbs_or_sbs_service_ready_ext2 = 21442 extract_dbs_or_sbs_cap_service_ready_ext2_tlv, 21443 .extract_hw_mode_cap_service_ready_ext = 21444 extract_hw_mode_cap_service_ready_ext_tlv, 21445 .extract_mac_phy_cap_service_ready_ext = 21446 extract_mac_phy_cap_service_ready_ext_tlv, 21447 .extract_mac_phy_cap_service_ready_ext2 = 21448 extract_mac_phy_cap_service_ready_ext2_tlv, 21449 .extract_reg_cap_service_ready_ext = 21450 extract_reg_cap_service_ready_ext_tlv, 21451 .extract_hal_reg_cap_ext2 = extract_hal_reg_cap_ext2_tlv, 21452 .extract_dbr_ring_cap_service_ready_ext = 21453 extract_dbr_ring_cap_service_ready_ext_tlv, 21454 .extract_dbr_ring_cap_service_ready_ext2 = 21455 extract_dbr_ring_cap_service_ready_ext2_tlv, 21456 .extract_scan_radio_cap_service_ready_ext2 = 21457 extract_scan_radio_cap_service_ready_ext2_tlv, 21458 .extract_msdu_idx_qtype_map_service_ready_ext2 = 21459 extract_msdu_idx_qtype_map_service_ready_ext2_tlv, 21460 .extract_sw_cal_ver_ext2 = extract_sw_cal_ver_ext2_tlv, 21461 .extract_aux_dev_cap_service_ready_ext2 = 21462 extract_aux_dev_cap_service_ready_ext2_tlv, 21463 .extract_sar_cap_service_ready_ext = 21464 extract_sar_cap_service_ready_ext_tlv, 21465 .extract_pdev_utf_event = extract_pdev_utf_event_tlv, 21466 .wmi_set_htc_tx_tag = wmi_set_htc_tx_tag_tlv, 21467 .extract_fips_event_data = extract_fips_event_data_tlv, 21468 #ifdef WLAN_FEATURE_FIPS_BER_CCMGCM 21469 .extract_fips_extend_ev_data = extract_fips_extend_event_data_tlv, 21470 #endif 21471 #if defined(WLAN_SUPPORT_FILS) || defined(CONFIG_BAND_6GHZ) 21472 .send_vdev_fils_enable_cmd = send_vdev_fils_enable_cmd_send, 21473 #endif 21474 #ifdef WLAN_FEATURE_DISA 21475 .extract_encrypt_decrypt_resp_event = 21476 extract_encrypt_decrypt_resp_event_tlv, 21477 #endif 21478 .send_pdev_fips_cmd = send_pdev_fips_cmd_tlv, 21479 #ifdef WLAN_FEATURE_FIPS_BER_CCMGCM 21480 .send_pdev_fips_extend_cmd = send_pdev_fips_extend_cmd_tlv, 21481 .send_pdev_fips_mode_set_cmd = send_pdev_fips_mode_set_cmd_tlv, 21482 #endif 21483 .extract_get_pn_data = extract_get_pn_data_tlv, 21484 .send_pdev_get_pn_cmd = send_pdev_get_pn_cmd_tlv, 21485 .extract_get_rxpn_data = extract_get_rxpn_data_tlv, 21486 .send_pdev_get_rxpn_cmd = send_pdev_get_rxpn_cmd_tlv, 21487 .send_wlan_profile_enable_cmd = send_wlan_profile_enable_cmd_tlv, 21488 #ifdef WLAN_FEATURE_DISA 21489 .send_encrypt_decrypt_send_cmd = send_encrypt_decrypt_send_cmd_tlv, 21490 #endif 21491 .send_wlan_profile_trigger_cmd = send_wlan_profile_trigger_cmd_tlv, 21492 .send_wlan_profile_hist_intvl_cmd = 21493 send_wlan_profile_hist_intvl_cmd_tlv, 21494 .is_management_record = is_management_record_tlv, 21495 .is_diag_event = is_diag_event_tlv, 21496 .is_force_fw_hang_cmd = is_force_fw_hang_cmd_tlv, 21497 #ifdef WLAN_FEATURE_ACTION_OUI 21498 .send_action_oui_cmd = send_action_oui_cmd_tlv, 21499 #endif 21500 .send_dfs_phyerr_offload_en_cmd = send_dfs_phyerr_offload_en_cmd_tlv, 21501 #ifdef QCA_SUPPORT_AGILE_DFS 21502 .send_adfs_ch_cfg_cmd = send_adfs_ch_cfg_cmd_tlv, 21503 .send_adfs_ocac_abort_cmd = send_adfs_ocac_abort_cmd_tlv, 21504 #endif 21505 .send_dfs_phyerr_offload_dis_cmd = send_dfs_phyerr_offload_dis_cmd_tlv, 21506 .extract_reg_chan_list_update_event = 21507 extract_reg_chan_list_update_event_tlv, 21508 #ifdef CONFIG_BAND_6GHZ 21509 .extract_reg_chan_list_ext_update_event = 21510 extract_reg_chan_list_ext_update_event_tlv, 21511 #ifdef CONFIG_AFC_SUPPORT 21512 .extract_afc_event = extract_afc_event_tlv, 21513 #endif 21514 #endif 21515 #ifdef WLAN_SUPPORT_RF_CHARACTERIZATION 21516 .extract_num_rf_characterization_entries = 21517 extract_num_rf_characterization_entries_tlv, 21518 .extract_rf_characterization_entries = 21519 extract_rf_characterization_entries_tlv, 21520 #endif 21521 .extract_chainmask_tables = 21522 extract_chainmask_tables_tlv, 21523 .extract_thermal_stats = extract_thermal_stats_tlv, 21524 .extract_thermal_level_stats = extract_thermal_level_stats_tlv, 21525 .send_get_rcpi_cmd = send_get_rcpi_cmd_tlv, 21526 .extract_rcpi_response_event = extract_rcpi_response_event_tlv, 21527 #ifdef DFS_COMPONENT_ENABLE 21528 .extract_dfs_cac_complete_event = extract_dfs_cac_complete_event_tlv, 21529 .extract_dfs_ocac_complete_event = extract_dfs_ocac_complete_event_tlv, 21530 .extract_dfs_radar_detection_event = 21531 extract_dfs_radar_detection_event_tlv, 21532 .extract_wlan_radar_event_info = extract_wlan_radar_event_info_tlv, 21533 #endif 21534 .convert_pdev_id_host_to_target = 21535 convert_host_pdev_id_to_target_pdev_id_legacy, 21536 .convert_pdev_id_target_to_host = 21537 convert_target_pdev_id_to_host_pdev_id_legacy, 21538 21539 .convert_host_pdev_id_to_target = 21540 convert_host_pdev_id_to_target_pdev_id, 21541 .convert_target_pdev_id_to_host = 21542 convert_target_pdev_id_to_host_pdev_id, 21543 21544 .convert_host_vdev_param_tlv = convert_host_vdev_param_tlv, 21545 21546 .convert_phy_id_host_to_target = 21547 convert_host_phy_id_to_target_phy_id_legacy, 21548 .convert_phy_id_target_to_host = 21549 convert_target_phy_id_to_host_phy_id_legacy, 21550 21551 .convert_host_phy_id_to_target = 21552 convert_host_phy_id_to_target_phy_id, 21553 .convert_target_phy_id_to_host = 21554 convert_target_phy_id_to_host_phy_id, 21555 21556 .send_start_11d_scan_cmd = send_start_11d_scan_cmd_tlv, 21557 .send_stop_11d_scan_cmd = send_stop_11d_scan_cmd_tlv, 21558 .extract_reg_11d_new_country_event = 21559 extract_reg_11d_new_country_event_tlv, 21560 .send_user_country_code_cmd = send_user_country_code_cmd_tlv, 21561 .extract_reg_ch_avoid_event = 21562 extract_reg_ch_avoid_event_tlv, 21563 .send_obss_detection_cfg_cmd = send_obss_detection_cfg_cmd_tlv, 21564 .extract_obss_detection_info = extract_obss_detection_info_tlv, 21565 .wmi_pdev_id_conversion_enable = wmi_tlv_pdev_id_conversion_enable, 21566 .wmi_free_allocated_event = wmitlv_free_allocated_event_tlvs, 21567 .wmi_check_and_pad_event = wmitlv_check_and_pad_event_tlvs, 21568 .wmi_check_command_params = wmitlv_check_command_tlv_params, 21569 .extract_comb_phyerr = extract_comb_phyerr_tlv, 21570 .extract_single_phyerr = extract_single_phyerr_tlv, 21571 #ifdef QCA_SUPPORT_CP_STATS 21572 .extract_cca_stats = extract_cca_stats_tlv, 21573 #endif 21574 .extract_esp_estimation_ev_param = 21575 extract_esp_estimation_ev_param_tlv, 21576 .send_roam_scan_stats_cmd = send_roam_scan_stats_cmd_tlv, 21577 .extract_roam_scan_stats_res_evt = extract_roam_scan_stats_res_evt_tlv, 21578 #ifdef OBSS_PD 21579 .send_obss_spatial_reuse_set = send_obss_spatial_reuse_set_cmd_tlv, 21580 .send_obss_spatial_reuse_set_def_thresh = 21581 send_obss_spatial_reuse_set_def_thresh_cmd_tlv, 21582 .send_self_srg_bss_color_bitmap_set = 21583 send_self_srg_bss_color_bitmap_set_cmd_tlv, 21584 .send_self_srg_partial_bssid_bitmap_set = 21585 send_self_srg_partial_bssid_bitmap_set_cmd_tlv, 21586 .send_self_srg_obss_color_enable_bitmap = 21587 send_self_srg_obss_color_enable_bitmap_cmd_tlv, 21588 .send_self_srg_obss_bssid_enable_bitmap = 21589 send_self_srg_obss_bssid_enable_bitmap_cmd_tlv, 21590 .send_self_non_srg_obss_color_enable_bitmap = 21591 send_self_non_srg_obss_color_enable_bitmap_cmd_tlv, 21592 .send_self_non_srg_obss_bssid_enable_bitmap = 21593 send_self_non_srg_obss_bssid_enable_bitmap_cmd_tlv, 21594 #endif 21595 .extract_offload_bcn_tx_status_evt = extract_offload_bcn_tx_status_evt, 21596 .extract_ctl_failsafe_check_ev_param = 21597 extract_ctl_failsafe_check_ev_param_tlv, 21598 #ifdef WIFI_POS_CONVERGED 21599 .extract_oem_response_param = extract_oem_response_param_tlv, 21600 #endif /* WIFI_POS_CONVERGED */ 21601 #if defined(WIFI_POS_CONVERGED) && defined(WLAN_FEATURE_RTT_11AZ_SUPPORT) 21602 .extract_pasn_peer_create_req_event = 21603 extract_pasn_peer_create_req_event_tlv, 21604 .extract_pasn_peer_delete_req_event = 21605 extract_pasn_peer_delete_req_event_tlv, 21606 .send_rtt_pasn_auth_status_cmd = 21607 send_rtt_pasn_auth_status_cmd_tlv, 21608 .send_rtt_pasn_deauth_cmd = 21609 send_rtt_pasn_deauth_cmd_tlv, 21610 #endif 21611 #ifdef WLAN_MWS_INFO_DEBUGFS 21612 .send_mws_coex_status_req_cmd = send_mws_coex_status_req_cmd_tlv, 21613 #endif 21614 .extract_hw_mode_resp_event = extract_hw_mode_resp_event_status_tlv, 21615 #ifdef FEATURE_ANI_LEVEL_REQUEST 21616 .send_ani_level_cmd = send_ani_level_cmd_tlv, 21617 .extract_ani_level = extract_ani_level_tlv, 21618 #endif /* FEATURE_ANI_LEVEL_REQUEST */ 21619 .extract_roam_trigger_stats = extract_roam_trigger_stats_tlv, 21620 .extract_roam_scan_stats = extract_roam_scan_stats_tlv, 21621 .extract_roam_result_stats = extract_roam_result_stats_tlv, 21622 .extract_roam_11kv_stats = extract_roam_11kv_stats_tlv, 21623 #ifdef WLAN_FEATURE_PKT_CAPTURE 21624 .extract_vdev_mgmt_offload_event = extract_vdev_mgmt_offload_event_tlv, 21625 #endif 21626 #ifdef WLAN_FEATURE_PKT_CAPTURE_V2 21627 .extract_smart_monitor_event = extract_smart_monitor_event_tlv, 21628 #endif 21629 21630 #ifdef FEATURE_WLAN_TIME_SYNC_FTM 21631 .send_wlan_time_sync_ftm_trigger_cmd = send_wlan_ts_ftm_trigger_cmd_tlv, 21632 .send_wlan_ts_qtime_cmd = send_wlan_ts_qtime_cmd_tlv, 21633 .extract_time_sync_ftm_start_stop_event = 21634 extract_time_sync_ftm_start_stop_event_tlv, 21635 .extract_time_sync_ftm_offset_event = 21636 extract_time_sync_ftm_offset_event_tlv, 21637 #endif /* FEATURE_WLAN_TIME_SYNC_FTM */ 21638 .send_roam_scan_ch_list_req_cmd = send_roam_scan_ch_list_req_cmd_tlv, 21639 .send_injector_config_cmd = send_injector_config_cmd_tlv, 21640 .send_cp_stats_cmd = send_cp_stats_cmd_tlv, 21641 .send_halphy_stats_cmd = send_halphy_stats_cmd_tlv, 21642 #ifdef FEATURE_MEC_OFFLOAD 21643 .send_pdev_set_mec_timer_cmd = send_pdev_set_mec_timer_cmd_tlv, 21644 #endif 21645 #if defined(WLAN_SUPPORT_INFRA_CTRL_PATH_STATS) || defined(WLAN_CONFIG_TELEMETRY_AGENT) 21646 .extract_infra_cp_stats = extract_infra_cp_stats_tlv, 21647 #endif /* WLAN_SUPPORT_INFRA_CTRL_PATH_STATS */ 21648 .extract_cp_stats_more_pending = 21649 extract_cp_stats_more_pending_tlv, 21650 .extract_halphy_stats_end_of_event = 21651 extract_halphy_stats_end_of_event_tlv, 21652 .extract_halphy_stats_event_count = 21653 extract_halphy_stats_event_count_tlv, 21654 .send_vdev_tsf_tstamp_action_cmd = send_vdev_tsf_tstamp_action_cmd_tlv, 21655 .extract_vdev_tsf_report_event = extract_vdev_tsf_report_event_tlv, 21656 .extract_pdev_csa_switch_count_status = 21657 extract_pdev_csa_switch_count_status_tlv, 21658 .send_set_tpc_power_cmd = send_set_tpc_power_cmd_tlv, 21659 #ifdef CONFIG_AFC_SUPPORT 21660 .send_afc_cmd = send_afc_cmd_tlv, 21661 #endif 21662 .extract_dpd_status_ev_param = extract_dpd_status_ev_param_tlv, 21663 .extract_install_key_comp_event = extract_install_key_comp_event_tlv, 21664 .send_vdev_set_ltf_key_seed_cmd = 21665 send_vdev_set_ltf_key_seed_cmd_tlv, 21666 .extract_halphy_cal_status_ev_param = extract_halphy_cal_status_ev_param_tlv, 21667 .send_set_halphy_cal = send_set_halphy_cal_tlv, 21668 .extract_halphy_cal_ev_param = extract_halphy_cal_ev_param_tlv, 21669 #ifdef WLAN_MGMT_RX_REO_SUPPORT 21670 .extract_mgmt_rx_fw_consumed = extract_mgmt_rx_fw_consumed_tlv, 21671 .extract_mgmt_rx_reo_params = extract_mgmt_rx_reo_params_tlv, 21672 .send_mgmt_rx_reo_filter_config_cmd = 21673 send_mgmt_rx_reo_filter_config_cmd_tlv, 21674 #endif 21675 21676 #ifdef WLAN_FEATURE_ROAM_OFFLOAD 21677 .send_roam_set_param_cmd = send_roam_set_param_cmd_tlv, 21678 #endif /* WLAN_FEATURE_ROAM_OFFLOAD */ 21679 21680 #ifdef WLAN_FEATURE_DYNAMIC_MAC_ADDR_UPDATE 21681 .send_set_mac_address_cmd = send_set_mac_address_cmd_tlv, 21682 .extract_update_mac_address_event = 21683 extract_update_mac_address_event_tlv, 21684 #endif 21685 21686 #ifdef WLAN_FEATURE_11BE_MLO 21687 .extract_quiet_offload_event = 21688 extract_quiet_offload_event_tlv, 21689 #endif 21690 21691 #ifdef WLAN_SUPPORT_PPEDS 21692 .peer_ppe_ds_param_send = peer_ppe_ds_param_send_tlv, 21693 #endif /* WLAN_SUPPORT_PPEDS */ 21694 21695 .send_vdev_pn_mgmt_rxfilter_cmd = send_vdev_pn_mgmt_rxfilter_cmd_tlv, 21696 .extract_pktlog_decode_info_event = 21697 extract_pktlog_decode_info_event_tlv, 21698 .extract_pdev_telemetry_stats = extract_pdev_telemetry_stats_tlv, 21699 .extract_mgmt_rx_ext_params = extract_mgmt_rx_ext_params_tlv, 21700 #ifdef WLAN_FEATURE_PEER_TXQ_FLUSH_CONF 21701 .send_peer_txq_flush_config_cmd = send_peer_txq_flush_config_cmd_tlv, 21702 #endif 21703 #ifdef WLAN_FEATURE_DBAM_CONFIG 21704 .send_dbam_config_cmd = send_dbam_config_cmd_tlv, 21705 .extract_dbam_config_resp_event = extract_dbam_config_resp_event_tlv, 21706 #endif 21707 #ifdef FEATURE_SET 21708 .feature_set_cmd_send = feature_set_cmd_send_tlv, 21709 #endif 21710 #ifdef HEALTH_MON_SUPPORT 21711 .extract_health_mon_init_done_info_event = 21712 extract_health_mon_init_done_info_event_tlv, 21713 #endif /* HEALTH_MON_SUPPORT */ 21714 .send_multiple_vdev_param_cmd = send_multiple_vdev_param_cmd_tlv, 21715 .set_mac_addr_rx_filter = send_set_mac_addr_rx_filter_cmd_tlv, 21716 .send_update_edca_pifs_param_cmd = 21717 send_update_edca_pifs_param_cmd_tlv, 21718 .extract_sap_coex_cap_service_ready_ext2 = 21719 extract_sap_coex_fix_chan_caps, 21720 .extract_tgtr2p_table_event = extract_tgtr2p_table_event_tlv, 21721 .send_egid_info_cmd = send_egid_info_cmd_tlv, 21722 .extract_csa_ie_received_ev_params = 21723 extract_csa_ie_received_ev_params_tlv, 21724 .extract_rf_path_resp = extract_rf_path_resp_tlv, 21725 #ifdef WLAN_RCC_ENHANCED_AOA_SUPPORT 21726 .extract_aoa_caps_service_ready_ext2 = 21727 extract_aoa_caps_tlv, 21728 #endif /* WLAN_RCC_ENHANCED_AOA_SUPPORT */ 21729 }; 21730 21731 #ifdef WLAN_FEATURE_11BE_MLO 21732 static void populate_tlv_events_id_mlo(WMI_EVT_ID *event_ids) 21733 { 21734 event_ids[wmi_mlo_setup_complete_event_id] = 21735 WMI_MLO_SETUP_COMPLETE_EVENTID; 21736 event_ids[wmi_mlo_teardown_complete_event_id] = 21737 WMI_MLO_TEARDOWN_COMPLETE_EVENTID; 21738 event_ids[wmi_mlo_link_set_active_resp_eventid] = 21739 WMI_MLO_LINK_SET_ACTIVE_RESP_EVENTID; 21740 event_ids[wmi_vdev_quiet_offload_eventid] = 21741 WMI_QUIET_HANDLING_EVENTID; 21742 event_ids[wmi_mlo_ap_vdev_tid_to_link_map_eventid] = 21743 WMI_MLO_AP_VDEV_TID_TO_LINK_MAP_EVENTID; 21744 event_ids[wmi_mlo_link_removal_eventid] = 21745 WMI_MLO_LINK_REMOVAL_EVENTID; 21746 event_ids[wmi_mlo_link_state_info_eventid] = 21747 WMI_MLO_VDEV_LINK_INFO_EVENTID; 21748 event_ids[wmi_mlo_link_disable_request_eventid] = 21749 WMI_MLO_LINK_DISABLE_REQUEST_EVENTID; 21750 #ifdef WLAN_FEATURE_11BE_MLO_ADV_FEATURE 21751 event_ids[wmi_mlo_link_switch_request_eventid] = 21752 WMI_MLO_LINK_SWITCH_REQUEST_EVENTID; 21753 event_ids[wmi_mlo_link_state_switch_eventid] = 21754 WMI_MLO_LINK_STATE_SWITCH_EVENTID; 21755 #endif /* WLAN_FEATURE_11BE_MLO_ADV_FEATURE */ 21756 } 21757 #else /* WLAN_FEATURE_11BE_MLO */ 21758 static inline void populate_tlv_events_id_mlo(WMI_EVT_ID *event_ids) 21759 { 21760 } 21761 #endif /* WLAN_FEATURE_11BE_MLO */ 21762 21763 /** 21764 * populate_tlv_events_id() - populates wmi event ids 21765 * @event_ids: Pointer to hold event ids 21766 * 21767 * Return: None 21768 */ 21769 static void populate_tlv_events_id(WMI_EVT_ID *event_ids) 21770 { 21771 event_ids[wmi_service_ready_event_id] = WMI_SERVICE_READY_EVENTID; 21772 event_ids[wmi_ready_event_id] = WMI_READY_EVENTID; 21773 event_ids[wmi_scan_event_id] = WMI_SCAN_EVENTID; 21774 event_ids[wmi_pdev_tpc_config_event_id] = WMI_PDEV_TPC_CONFIG_EVENTID; 21775 event_ids[wmi_chan_info_event_id] = WMI_CHAN_INFO_EVENTID; 21776 event_ids[wmi_phyerr_event_id] = WMI_PHYERR_EVENTID; 21777 event_ids[wmi_pdev_dump_event_id] = WMI_PDEV_DUMP_EVENTID; 21778 event_ids[wmi_tx_pause_event_id] = WMI_TX_PAUSE_EVENTID; 21779 event_ids[wmi_dfs_radar_event_id] = WMI_DFS_RADAR_EVENTID; 21780 event_ids[wmi_pdev_l1ss_track_event_id] = WMI_PDEV_L1SS_TRACK_EVENTID; 21781 event_ids[wmi_pdev_temperature_event_id] = WMI_PDEV_TEMPERATURE_EVENTID; 21782 event_ids[wmi_service_ready_ext_event_id] = 21783 WMI_SERVICE_READY_EXT_EVENTID; 21784 event_ids[wmi_service_ready_ext2_event_id] = 21785 WMI_SERVICE_READY_EXT2_EVENTID; 21786 event_ids[wmi_vdev_start_resp_event_id] = WMI_VDEV_START_RESP_EVENTID; 21787 event_ids[wmi_vdev_stopped_event_id] = WMI_VDEV_STOPPED_EVENTID; 21788 event_ids[wmi_vdev_install_key_complete_event_id] = 21789 WMI_VDEV_INSTALL_KEY_COMPLETE_EVENTID; 21790 event_ids[wmi_vdev_mcc_bcn_intvl_change_req_event_id] = 21791 WMI_VDEV_MCC_BCN_INTERVAL_CHANGE_REQ_EVENTID; 21792 21793 event_ids[wmi_vdev_tsf_report_event_id] = WMI_VDEV_TSF_REPORT_EVENTID; 21794 event_ids[wmi_peer_sta_kickout_event_id] = WMI_PEER_STA_KICKOUT_EVENTID; 21795 event_ids[wmi_peer_info_event_id] = WMI_PEER_INFO_EVENTID; 21796 event_ids[wmi_peer_tx_fail_cnt_thr_event_id] = 21797 WMI_PEER_TX_FAIL_CNT_THR_EVENTID; 21798 event_ids[wmi_peer_estimated_linkspeed_event_id] = 21799 WMI_PEER_ESTIMATED_LINKSPEED_EVENTID; 21800 event_ids[wmi_peer_state_event_id] = WMI_PEER_STATE_EVENTID; 21801 event_ids[wmi_peer_create_conf_event_id] = 21802 WMI_PEER_CREATE_CONF_EVENTID; 21803 event_ids[wmi_peer_delete_response_event_id] = 21804 WMI_PEER_DELETE_RESP_EVENTID; 21805 event_ids[wmi_peer_delete_all_response_event_id] = 21806 WMI_VDEV_DELETE_ALL_PEER_RESP_EVENTID; 21807 event_ids[wmi_peer_oper_mode_change_event_id] = 21808 WMI_PEER_OPER_MODE_CHANGE_EVENTID; 21809 event_ids[wmi_mgmt_rx_event_id] = WMI_MGMT_RX_EVENTID; 21810 event_ids[wmi_host_swba_event_id] = WMI_HOST_SWBA_EVENTID; 21811 event_ids[wmi_tbttoffset_update_event_id] = 21812 WMI_TBTTOFFSET_UPDATE_EVENTID; 21813 event_ids[wmi_ext_tbttoffset_update_event_id] = 21814 WMI_TBTTOFFSET_EXT_UPDATE_EVENTID; 21815 event_ids[wmi_offload_bcn_tx_status_event_id] = 21816 WMI_OFFLOAD_BCN_TX_STATUS_EVENTID; 21817 event_ids[wmi_offload_prob_resp_tx_status_event_id] = 21818 WMI_OFFLOAD_PROB_RESP_TX_STATUS_EVENTID; 21819 event_ids[wmi_mgmt_tx_completion_event_id] = 21820 WMI_MGMT_TX_COMPLETION_EVENTID; 21821 event_ids[wmi_pdev_nfcal_power_all_channels_event_id] = 21822 WMI_PDEV_NFCAL_POWER_ALL_CHANNELS_EVENTID; 21823 event_ids[wmi_tx_delba_complete_event_id] = 21824 WMI_TX_DELBA_COMPLETE_EVENTID; 21825 event_ids[wmi_tx_addba_complete_event_id] = 21826 WMI_TX_ADDBA_COMPLETE_EVENTID; 21827 event_ids[wmi_ba_rsp_ssn_event_id] = WMI_BA_RSP_SSN_EVENTID; 21828 21829 event_ids[wmi_aggr_state_trig_event_id] = WMI_AGGR_STATE_TRIG_EVENTID; 21830 21831 event_ids[wmi_roam_event_id] = WMI_ROAM_EVENTID; 21832 event_ids[wmi_profile_match] = WMI_PROFILE_MATCH; 21833 21834 event_ids[wmi_roam_synch_event_id] = WMI_ROAM_SYNCH_EVENTID; 21835 event_ids[wmi_roam_synch_frame_event_id] = WMI_ROAM_SYNCH_FRAME_EVENTID; 21836 21837 event_ids[wmi_p2p_disc_event_id] = WMI_P2P_DISC_EVENTID; 21838 21839 event_ids[wmi_p2p_noa_event_id] = WMI_P2P_NOA_EVENTID; 21840 event_ids[wmi_p2p_lo_stop_event_id] = 21841 WMI_P2P_LISTEN_OFFLOAD_STOPPED_EVENTID; 21842 event_ids[wmi_vdev_add_macaddr_rx_filter_event_id] = 21843 WMI_VDEV_ADD_MAC_ADDR_TO_RX_FILTER_STATUS_EVENTID; 21844 event_ids[wmi_pdev_resume_event_id] = WMI_PDEV_RESUME_EVENTID; 21845 event_ids[wmi_wow_wakeup_host_event_id] = WMI_WOW_WAKEUP_HOST_EVENTID; 21846 event_ids[wmi_d0_wow_disable_ack_event_id] = 21847 WMI_D0_WOW_DISABLE_ACK_EVENTID; 21848 event_ids[wmi_wow_initial_wakeup_event_id] = 21849 WMI_WOW_INITIAL_WAKEUP_EVENTID; 21850 21851 event_ids[wmi_rtt_meas_report_event_id] = 21852 WMI_RTT_MEASUREMENT_REPORT_EVENTID; 21853 event_ids[wmi_tsf_meas_report_event_id] = 21854 WMI_TSF_MEASUREMENT_REPORT_EVENTID; 21855 event_ids[wmi_rtt_error_report_event_id] = WMI_RTT_ERROR_REPORT_EVENTID; 21856 event_ids[wmi_stats_ext_event_id] = WMI_STATS_EXT_EVENTID; 21857 event_ids[wmi_iface_link_stats_event_id] = WMI_IFACE_LINK_STATS_EVENTID; 21858 event_ids[wmi_peer_link_stats_event_id] = WMI_PEER_LINK_STATS_EVENTID; 21859 event_ids[wmi_radio_link_stats_link] = WMI_RADIO_LINK_STATS_EVENTID; 21860 event_ids[wmi_diag_event_id_log_supported_event_id] = 21861 WMI_DIAG_EVENT_LOG_SUPPORTED_EVENTID; 21862 event_ids[wmi_nlo_match_event_id] = WMI_NLO_MATCH_EVENTID; 21863 event_ids[wmi_nlo_scan_complete_event_id] = 21864 WMI_NLO_SCAN_COMPLETE_EVENTID; 21865 event_ids[wmi_apfind_event_id] = WMI_APFIND_EVENTID; 21866 event_ids[wmi_passpoint_match_event_id] = WMI_PASSPOINT_MATCH_EVENTID; 21867 21868 event_ids[wmi_gtk_offload_status_event_id] = 21869 WMI_GTK_OFFLOAD_STATUS_EVENTID; 21870 event_ids[wmi_gtk_rekey_fail_event_id] = WMI_GTK_REKEY_FAIL_EVENTID; 21871 event_ids[wmi_csa_handling_event_id] = WMI_CSA_HANDLING_EVENTID; 21872 event_ids[wmi_chatter_pc_query_event_id] = WMI_CHATTER_PC_QUERY_EVENTID; 21873 21874 event_ids[wmi_echo_event_id] = WMI_ECHO_EVENTID; 21875 21876 event_ids[wmi_pdev_utf_event_id] = WMI_PDEV_UTF_EVENTID; 21877 21878 event_ids[wmi_dbg_msg_event_id] = WMI_DEBUG_MESG_EVENTID; 21879 event_ids[wmi_update_stats_event_id] = WMI_UPDATE_STATS_EVENTID; 21880 event_ids[wmi_debug_print_event_id] = WMI_DEBUG_PRINT_EVENTID; 21881 event_ids[wmi_dcs_interference_event_id] = WMI_DCS_INTERFERENCE_EVENTID; 21882 event_ids[wmi_pdev_qvit_event_id] = WMI_PDEV_QVIT_EVENTID; 21883 event_ids[wmi_wlan_profile_data_event_id] = 21884 WMI_WLAN_PROFILE_DATA_EVENTID; 21885 event_ids[wmi_pdev_ftm_intg_event_id] = WMI_PDEV_FTM_INTG_EVENTID; 21886 event_ids[wmi_wlan_freq_avoid_event_id] = WMI_WLAN_FREQ_AVOID_EVENTID; 21887 event_ids[wmi_vdev_get_keepalive_event_id] = 21888 WMI_VDEV_GET_KEEPALIVE_EVENTID; 21889 event_ids[wmi_thermal_mgmt_event_id] = WMI_THERMAL_MGMT_EVENTID; 21890 21891 event_ids[wmi_diag_container_event_id] = 21892 WMI_DIAG_DATA_CONTAINER_EVENTID; 21893 21894 event_ids[wmi_host_auto_shutdown_event_id] = 21895 WMI_HOST_AUTO_SHUTDOWN_EVENTID; 21896 21897 event_ids[wmi_update_whal_mib_stats_event_id] = 21898 WMI_UPDATE_WHAL_MIB_STATS_EVENTID; 21899 21900 /*update ht/vht info based on vdev (rx and tx NSS and preamble) */ 21901 event_ids[wmi_update_vdev_rate_stats_event_id] = 21902 WMI_UPDATE_VDEV_RATE_STATS_EVENTID; 21903 21904 event_ids[wmi_diag_event_id] = WMI_DIAG_EVENTID; 21905 event_ids[wmi_unit_test_event_id] = WMI_UNIT_TEST_EVENTID; 21906 21907 /** Set OCB Sched Response, deprecated */ 21908 event_ids[wmi_ocb_set_sched_event_id] = WMI_OCB_SET_SCHED_EVENTID; 21909 21910 event_ids[wmi_dbg_mesg_flush_complete_event_id] = 21911 WMI_DEBUG_MESG_FLUSH_COMPLETE_EVENTID; 21912 event_ids[wmi_rssi_breach_event_id] = WMI_RSSI_BREACH_EVENTID; 21913 21914 /* GPIO Event */ 21915 event_ids[wmi_gpio_input_event_id] = WMI_GPIO_INPUT_EVENTID; 21916 event_ids[wmi_uploadh_event_id] = WMI_UPLOADH_EVENTID; 21917 21918 event_ids[wmi_captureh_event_id] = WMI_CAPTUREH_EVENTID; 21919 event_ids[wmi_rfkill_state_change_event_id] = 21920 WMI_RFKILL_STATE_CHANGE_EVENTID; 21921 21922 /* TDLS Event */ 21923 event_ids[wmi_tdls_peer_event_id] = WMI_TDLS_PEER_EVENTID; 21924 21925 event_ids[wmi_batch_scan_enabled_event_id] = 21926 WMI_BATCH_SCAN_ENABLED_EVENTID; 21927 event_ids[wmi_batch_scan_result_event_id] = 21928 WMI_BATCH_SCAN_RESULT_EVENTID; 21929 /* OEM Event */ 21930 event_ids[wmi_oem_cap_event_id] = WMI_OEM_CAPABILITY_EVENTID; 21931 event_ids[wmi_oem_meas_report_event_id] = 21932 WMI_OEM_MEASUREMENT_REPORT_EVENTID; 21933 event_ids[wmi_oem_report_event_id] = WMI_OEM_ERROR_REPORT_EVENTID; 21934 21935 /* NAN Event */ 21936 event_ids[wmi_nan_event_id] = WMI_NAN_EVENTID; 21937 21938 /* LPI Event */ 21939 event_ids[wmi_lpi_result_event_id] = WMI_LPI_RESULT_EVENTID; 21940 event_ids[wmi_lpi_status_event_id] = WMI_LPI_STATUS_EVENTID; 21941 event_ids[wmi_lpi_handoff_event_id] = WMI_LPI_HANDOFF_EVENTID; 21942 21943 /* ExtScan events */ 21944 event_ids[wmi_extscan_start_stop_event_id] = 21945 WMI_EXTSCAN_START_STOP_EVENTID; 21946 event_ids[wmi_extscan_operation_event_id] = 21947 WMI_EXTSCAN_OPERATION_EVENTID; 21948 event_ids[wmi_extscan_table_usage_event_id] = 21949 WMI_EXTSCAN_TABLE_USAGE_EVENTID; 21950 event_ids[wmi_extscan_cached_results_event_id] = 21951 WMI_EXTSCAN_CACHED_RESULTS_EVENTID; 21952 event_ids[wmi_extscan_wlan_change_results_event_id] = 21953 WMI_EXTSCAN_WLAN_CHANGE_RESULTS_EVENTID; 21954 event_ids[wmi_extscan_hotlist_match_event_id] = 21955 WMI_EXTSCAN_HOTLIST_MATCH_EVENTID; 21956 event_ids[wmi_extscan_capabilities_event_id] = 21957 WMI_EXTSCAN_CAPABILITIES_EVENTID; 21958 event_ids[wmi_extscan_hotlist_ssid_match_event_id] = 21959 WMI_EXTSCAN_HOTLIST_SSID_MATCH_EVENTID; 21960 21961 /* mDNS offload events */ 21962 event_ids[wmi_mdns_stats_event_id] = WMI_MDNS_STATS_EVENTID; 21963 21964 /* SAP Authentication offload events */ 21965 event_ids[wmi_sap_ofl_add_sta_event_id] = WMI_SAP_OFL_ADD_STA_EVENTID; 21966 event_ids[wmi_sap_ofl_del_sta_event_id] = WMI_SAP_OFL_DEL_STA_EVENTID; 21967 21968 /** Out-of-context-of-bss (OCB) events */ 21969 event_ids[wmi_ocb_set_config_resp_event_id] = 21970 WMI_OCB_SET_CONFIG_RESP_EVENTID; 21971 event_ids[wmi_ocb_get_tsf_timer_resp_event_id] = 21972 WMI_OCB_GET_TSF_TIMER_RESP_EVENTID; 21973 event_ids[wmi_dcc_get_stats_resp_event_id] = 21974 WMI_DCC_GET_STATS_RESP_EVENTID; 21975 event_ids[wmi_dcc_update_ndl_resp_event_id] = 21976 WMI_DCC_UPDATE_NDL_RESP_EVENTID; 21977 event_ids[wmi_dcc_stats_event_id] = WMI_DCC_STATS_EVENTID; 21978 /* System-On-Chip events */ 21979 event_ids[wmi_soc_set_hw_mode_resp_event_id] = 21980 WMI_SOC_SET_HW_MODE_RESP_EVENTID; 21981 event_ids[wmi_soc_hw_mode_transition_event_id] = 21982 WMI_SOC_HW_MODE_TRANSITION_EVENTID; 21983 event_ids[wmi_soc_set_dual_mac_config_resp_event_id] = 21984 WMI_SOC_SET_DUAL_MAC_CONFIG_RESP_EVENTID; 21985 event_ids[wmi_pdev_fips_event_id] = WMI_PDEV_FIPS_EVENTID; 21986 #ifdef WLAN_FEATURE_FIPS_BER_CCMGCM 21987 event_ids[wmi_pdev_fips_extend_event_id] = WMI_PDEV_FIPS_EXTEND_EVENTID; 21988 #endif 21989 event_ids[wmi_pdev_csa_switch_count_status_event_id] = 21990 WMI_PDEV_CSA_SWITCH_COUNT_STATUS_EVENTID; 21991 event_ids[wmi_vdev_ocac_complete_event_id] = 21992 WMI_VDEV_ADFS_OCAC_COMPLETE_EVENTID; 21993 event_ids[wmi_reg_chan_list_cc_event_id] = WMI_REG_CHAN_LIST_CC_EVENTID; 21994 event_ids[wmi_reg_chan_list_cc_ext_event_id] = 21995 WMI_REG_CHAN_LIST_CC_EXT_EVENTID; 21996 #ifdef CONFIG_AFC_SUPPORT 21997 event_ids[wmi_afc_event_id] = WMI_AFC_EVENTID, 21998 #endif 21999 event_ids[wmi_inst_rssi_stats_event_id] = WMI_INST_RSSI_STATS_EVENTID; 22000 event_ids[wmi_pdev_tpc_config_event_id] = WMI_PDEV_TPC_CONFIG_EVENTID; 22001 event_ids[wmi_peer_sta_ps_statechg_event_id] = 22002 WMI_PEER_STA_PS_STATECHG_EVENTID; 22003 event_ids[wmi_pdev_channel_hopping_event_id] = 22004 WMI_PDEV_CHANNEL_HOPPING_EVENTID; 22005 event_ids[wmi_offchan_data_tx_completion_event] = 22006 WMI_OFFCHAN_DATA_TX_COMPLETION_EVENTID; 22007 event_ids[wmi_dfs_cac_complete_id] = WMI_VDEV_DFS_CAC_COMPLETE_EVENTID; 22008 event_ids[wmi_dfs_radar_detection_event_id] = 22009 WMI_PDEV_DFS_RADAR_DETECTION_EVENTID; 22010 event_ids[wmi_tt_stats_event_id] = WMI_THERM_THROT_STATS_EVENTID; 22011 event_ids[wmi_11d_new_country_event_id] = WMI_11D_NEW_COUNTRY_EVENTID; 22012 event_ids[wmi_pdev_tpc_event_id] = WMI_PDEV_TPC_EVENTID; 22013 event_ids[wmi_get_arp_stats_req_id] = WMI_VDEV_GET_ARP_STAT_EVENTID; 22014 event_ids[wmi_service_available_event_id] = 22015 WMI_SERVICE_AVAILABLE_EVENTID; 22016 event_ids[wmi_update_rcpi_event_id] = WMI_UPDATE_RCPI_EVENTID; 22017 event_ids[wmi_pdev_check_cal_version_event_id] = WMI_PDEV_CHECK_CAL_VERSION_EVENTID; 22018 /* NDP events */ 22019 event_ids[wmi_ndp_initiator_rsp_event_id] = 22020 WMI_NDP_INITIATOR_RSP_EVENTID; 22021 event_ids[wmi_ndp_indication_event_id] = WMI_NDP_INDICATION_EVENTID; 22022 event_ids[wmi_ndp_confirm_event_id] = WMI_NDP_CONFIRM_EVENTID; 22023 event_ids[wmi_ndp_responder_rsp_event_id] = 22024 WMI_NDP_RESPONDER_RSP_EVENTID; 22025 event_ids[wmi_ndp_end_indication_event_id] = 22026 WMI_NDP_END_INDICATION_EVENTID; 22027 event_ids[wmi_ndp_end_rsp_event_id] = WMI_NDP_END_RSP_EVENTID; 22028 event_ids[wmi_ndl_schedule_update_event_id] = 22029 WMI_NDL_SCHEDULE_UPDATE_EVENTID; 22030 event_ids[wmi_ndp_event_id] = WMI_NDP_EVENTID; 22031 22032 event_ids[wmi_oem_response_event_id] = WMI_OEM_RESPONSE_EVENTID; 22033 event_ids[wmi_peer_stats_info_event_id] = WMI_PEER_STATS_INFO_EVENTID; 22034 event_ids[wmi_pdev_chip_power_stats_event_id] = 22035 WMI_PDEV_CHIP_POWER_STATS_EVENTID; 22036 event_ids[wmi_ap_ps_egap_info_event_id] = WMI_AP_PS_EGAP_INFO_EVENTID; 22037 event_ids[wmi_peer_assoc_conf_event_id] = WMI_PEER_ASSOC_CONF_EVENTID; 22038 event_ids[wmi_vdev_delete_resp_event_id] = WMI_VDEV_DELETE_RESP_EVENTID; 22039 event_ids[wmi_apf_capability_info_event_id] = 22040 WMI_BPF_CAPABILIY_INFO_EVENTID; 22041 event_ids[wmi_vdev_encrypt_decrypt_data_rsp_event_id] = 22042 WMI_VDEV_ENCRYPT_DECRYPT_DATA_RESP_EVENTID; 22043 event_ids[wmi_report_rx_aggr_failure_event_id] = 22044 WMI_REPORT_RX_AGGR_FAILURE_EVENTID; 22045 event_ids[wmi_pdev_chip_pwr_save_failure_detect_event_id] = 22046 WMI_PDEV_CHIP_POWER_SAVE_FAILURE_DETECTED_EVENTID; 22047 event_ids[wmi_peer_antdiv_info_event_id] = WMI_PEER_ANTDIV_INFO_EVENTID; 22048 event_ids[wmi_pdev_set_hw_mode_rsp_event_id] = 22049 WMI_PDEV_SET_HW_MODE_RESP_EVENTID; 22050 event_ids[wmi_pdev_hw_mode_transition_event_id] = 22051 WMI_PDEV_HW_MODE_TRANSITION_EVENTID; 22052 event_ids[wmi_pdev_set_mac_config_resp_event_id] = 22053 WMI_PDEV_SET_MAC_CONFIG_RESP_EVENTID; 22054 event_ids[wmi_coex_bt_activity_event_id] = 22055 WMI_WLAN_COEX_BT_ACTIVITY_EVENTID; 22056 event_ids[wmi_mgmt_tx_bundle_completion_event_id] = 22057 WMI_MGMT_TX_BUNDLE_COMPLETION_EVENTID; 22058 event_ids[wmi_radio_tx_power_level_stats_event_id] = 22059 WMI_RADIO_TX_POWER_LEVEL_STATS_EVENTID; 22060 event_ids[wmi_report_stats_event_id] = WMI_REPORT_STATS_EVENTID; 22061 event_ids[wmi_dma_buf_release_event_id] = 22062 WMI_PDEV_DMA_RING_BUF_RELEASE_EVENTID; 22063 event_ids[wmi_sap_obss_detection_report_event_id] = 22064 WMI_SAP_OBSS_DETECTION_REPORT_EVENTID; 22065 event_ids[wmi_host_swfda_event_id] = WMI_HOST_SWFDA_EVENTID; 22066 event_ids[wmi_sar_get_limits_event_id] = WMI_SAR_GET_LIMITS_EVENTID; 22067 event_ids[wmi_obss_color_collision_report_event_id] = 22068 WMI_OBSS_COLOR_COLLISION_DETECTION_EVENTID; 22069 event_ids[wmi_pdev_div_rssi_antid_event_id] = 22070 WMI_PDEV_DIV_RSSI_ANTID_EVENTID; 22071 #ifdef WLAN_SUPPORT_TWT 22072 event_ids[wmi_twt_enable_complete_event_id] = 22073 WMI_TWT_ENABLE_COMPLETE_EVENTID; 22074 event_ids[wmi_twt_disable_complete_event_id] = 22075 WMI_TWT_DISABLE_COMPLETE_EVENTID; 22076 event_ids[wmi_twt_add_dialog_complete_event_id] = 22077 WMI_TWT_ADD_DIALOG_COMPLETE_EVENTID; 22078 event_ids[wmi_twt_del_dialog_complete_event_id] = 22079 WMI_TWT_DEL_DIALOG_COMPLETE_EVENTID; 22080 event_ids[wmi_twt_pause_dialog_complete_event_id] = 22081 WMI_TWT_PAUSE_DIALOG_COMPLETE_EVENTID; 22082 event_ids[wmi_twt_resume_dialog_complete_event_id] = 22083 WMI_TWT_RESUME_DIALOG_COMPLETE_EVENTID; 22084 event_ids[wmi_twt_nudge_dialog_complete_event_id] = 22085 WMI_TWT_NUDGE_DIALOG_COMPLETE_EVENTID; 22086 event_ids[wmi_twt_session_stats_event_id] = 22087 WMI_TWT_SESSION_STATS_EVENTID; 22088 event_ids[wmi_twt_notify_event_id] = 22089 WMI_TWT_NOTIFY_EVENTID; 22090 event_ids[wmi_twt_ack_complete_event_id] = 22091 WMI_TWT_ACK_EVENTID; 22092 #endif 22093 event_ids[wmi_apf_get_vdev_work_memory_resp_event_id] = 22094 WMI_BPF_GET_VDEV_WORK_MEMORY_RESP_EVENTID; 22095 event_ids[wmi_wlan_sar2_result_event_id] = WMI_SAR2_RESULT_EVENTID; 22096 event_ids[wmi_esp_estimate_event_id] = WMI_ESP_ESTIMATE_EVENTID; 22097 event_ids[wmi_roam_scan_stats_event_id] = WMI_ROAM_SCAN_STATS_EVENTID; 22098 #ifdef WLAN_FEATURE_INTEROP_ISSUES_AP 22099 event_ids[wmi_pdev_interop_issues_ap_event_id] = 22100 WMI_PDEV_RAP_INFO_EVENTID; 22101 #endif 22102 #ifdef AST_HKV1_WORKAROUND 22103 event_ids[wmi_wds_peer_event_id] = WMI_WDS_PEER_EVENTID; 22104 #endif 22105 event_ids[wmi_pdev_ctl_failsafe_check_event_id] = 22106 WMI_PDEV_CTL_FAILSAFE_CHECK_EVENTID; 22107 event_ids[wmi_vdev_bcn_reception_stats_event_id] = 22108 WMI_VDEV_BCN_RECEPTION_STATS_EVENTID; 22109 event_ids[wmi_roam_denylist_event_id] = WMI_ROAM_BLACKLIST_EVENTID; 22110 event_ids[wmi_wlm_stats_event_id] = WMI_WLM_STATS_EVENTID; 22111 event_ids[wmi_peer_cfr_capture_event_id] = WMI_PEER_CFR_CAPTURE_EVENTID; 22112 event_ids[wmi_pdev_cold_boot_cal_event_id] = 22113 WMI_PDEV_COLD_BOOT_CAL_DATA_EVENTID; 22114 #ifdef WLAN_MWS_INFO_DEBUGFS 22115 event_ids[wmi_vdev_get_mws_coex_state_eventid] = 22116 WMI_VDEV_GET_MWS_COEX_STATE_EVENTID; 22117 event_ids[wmi_vdev_get_mws_coex_dpwb_state_eventid] = 22118 WMI_VDEV_GET_MWS_COEX_DPWB_STATE_EVENTID; 22119 event_ids[wmi_vdev_get_mws_coex_tdm_state_eventid] = 22120 WMI_VDEV_GET_MWS_COEX_TDM_STATE_EVENTID; 22121 event_ids[wmi_vdev_get_mws_coex_idrx_state_eventid] = 22122 WMI_VDEV_GET_MWS_COEX_IDRX_STATE_EVENTID; 22123 event_ids[wmi_vdev_get_mws_coex_antenna_sharing_state_eventid] = 22124 WMI_VDEV_GET_MWS_COEX_ANTENNA_SHARING_STATE_EVENTID; 22125 #endif 22126 event_ids[wmi_coex_report_antenna_isolation_event_id] = 22127 WMI_COEX_REPORT_ANTENNA_ISOLATION_EVENTID; 22128 event_ids[wmi_peer_ratecode_list_event_id] = 22129 WMI_PEER_RATECODE_LIST_EVENTID; 22130 event_ids[wmi_chan_rf_characterization_info_event_id] = 22131 WMI_CHAN_RF_CHARACTERIZATION_INFO_EVENTID; 22132 event_ids[wmi_roam_auth_offload_event_id] = 22133 WMI_ROAM_PREAUTH_START_EVENTID; 22134 event_ids[wmi_get_elna_bypass_event_id] = WMI_GET_ELNA_BYPASS_EVENTID; 22135 event_ids[wmi_motion_det_host_eventid] = WMI_MOTION_DET_HOST_EVENTID; 22136 event_ids[wmi_motion_det_base_line_host_eventid] = 22137 WMI_MOTION_DET_BASE_LINE_HOST_EVENTID; 22138 event_ids[wmi_get_ani_level_event_id] = WMI_GET_CHANNEL_ANI_EVENTID; 22139 event_ids[wmi_peer_tx_pn_response_event_id] = 22140 WMI_PEER_TX_PN_RESPONSE_EVENTID; 22141 event_ids[wmi_roam_stats_event_id] = WMI_ROAM_STATS_EVENTID; 22142 event_ids[wmi_oem_data_event_id] = WMI_OEM_DATA_EVENTID; 22143 event_ids[wmi_mgmt_offload_data_event_id] = 22144 WMI_VDEV_MGMT_OFFLOAD_EVENTID; 22145 event_ids[wmi_nan_dmesg_event_id] = 22146 WMI_NAN_DMESG_EVENTID; 22147 event_ids[wmi_pdev_multi_vdev_restart_response_event_id] = 22148 WMI_PDEV_MULTIPLE_VDEV_RESTART_RESP_EVENTID; 22149 event_ids[wmi_roam_pmkid_request_event_id] = 22150 WMI_ROAM_PMKID_REQUEST_EVENTID; 22151 #ifdef FEATURE_WLAN_TIME_SYNC_FTM 22152 event_ids[wmi_wlan_time_sync_ftm_start_stop_event_id] = 22153 WMI_VDEV_AUDIO_SYNC_START_STOP_EVENTID; 22154 event_ids[wmi_wlan_time_sync_q_initiator_target_offset_eventid] = 22155 WMI_VDEV_AUDIO_SYNC_Q_MASTER_SLAVE_OFFSET_EVENTID; 22156 #endif 22157 event_ids[wmi_roam_scan_chan_list_id] = 22158 WMI_ROAM_SCAN_CHANNEL_LIST_EVENTID; 22159 event_ids[wmi_muedca_params_config_eventid] = 22160 WMI_MUEDCA_PARAMS_CONFIG_EVENTID; 22161 event_ids[wmi_pdev_sscan_fw_param_eventid] = 22162 WMI_PDEV_SSCAN_FW_PARAM_EVENTID; 22163 event_ids[wmi_roam_cap_report_event_id] = 22164 WMI_ROAM_CAPABILITY_REPORT_EVENTID; 22165 event_ids[wmi_vdev_bcn_latency_event_id] = 22166 WMI_VDEV_BCN_LATENCY_EVENTID; 22167 event_ids[wmi_vdev_disconnect_event_id] = 22168 WMI_VDEV_DISCONNECT_EVENTID; 22169 event_ids[wmi_peer_create_conf_event_id] = 22170 WMI_PEER_CREATE_CONF_EVENTID; 22171 event_ids[wmi_pdev_cp_fwstats_eventid] = 22172 WMI_CTRL_PATH_STATS_EVENTID; 22173 event_ids[wmi_pdev_halphy_fwstats_eventid] = 22174 WMI_HALPHY_CTRL_PATH_STATS_EVENTID; 22175 event_ids[wmi_vdev_send_big_data_p2_eventid] = 22176 WMI_VDEV_SEND_BIG_DATA_P2_EVENTID; 22177 event_ids[wmi_pdev_get_dpd_status_event_id] = 22178 WMI_PDEV_GET_DPD_STATUS_EVENTID; 22179 #ifdef WLAN_FEATURE_PKT_CAPTURE_V2 22180 event_ids[wmi_vdev_smart_monitor_event_id] = 22181 WMI_VDEV_SMART_MONITOR_EVENTID; 22182 #endif 22183 event_ids[wmi_pdev_get_halphy_cal_status_event_id] = 22184 WMI_PDEV_GET_HALPHY_CAL_STATUS_EVENTID; 22185 event_ids[wmi_pdev_set_halphy_cal_event_id] = 22186 WMI_PDEV_SET_HALPHY_CAL_BMAP_EVENTID; 22187 event_ids[wmi_pdev_aoa_phasedelta_event_id] = 22188 WMI_PDEV_AOA_PHASEDELTA_EVENTID; 22189 #ifdef WLAN_MGMT_RX_REO_SUPPORT 22190 event_ids[wmi_mgmt_rx_fw_consumed_eventid] = 22191 WMI_MGMT_RX_FW_CONSUMED_EVENTID; 22192 #endif 22193 populate_tlv_events_id_mlo(event_ids); 22194 event_ids[wmi_roam_frame_event_id] = 22195 WMI_ROAM_FRAME_EVENTID; 22196 #ifdef WLAN_FEATURE_DYNAMIC_MAC_ADDR_UPDATE 22197 event_ids[wmi_vdev_update_mac_addr_conf_eventid] = 22198 WMI_VDEV_UPDATE_MAC_ADDR_CONF_EVENTID; 22199 #endif 22200 #ifdef WLAN_FEATURE_MCC_QUOTA 22201 event_ids[wmi_resmgr_chan_time_quota_changed_eventid] = 22202 WMI_RESMGR_CHAN_TIME_QUOTA_CHANGED_EVENTID; 22203 #endif 22204 event_ids[wmi_peer_rx_pn_response_event_id] = 22205 WMI_PEER_RX_PN_RESPONSE_EVENTID; 22206 event_ids[wmi_extract_pktlog_decode_info_eventid] = 22207 WMI_PDEV_PKTLOG_DECODE_INFO_EVENTID; 22208 #ifdef QCA_RSSI_DB2DBM 22209 event_ids[wmi_pdev_rssi_dbm_conversion_params_info_eventid] = 22210 WMI_PDEV_RSSI_DBM_CONVERSION_PARAMS_INFO_EVENTID; 22211 #endif 22212 #ifdef MULTI_CLIENT_LL_SUPPORT 22213 event_ids[wmi_vdev_latency_event_id] = WMI_VDEV_LATENCY_LEVEL_EVENTID; 22214 #endif 22215 #if defined(WIFI_POS_CONVERGED) && defined(WLAN_FEATURE_RTT_11AZ_SUPPORT) 22216 event_ids[wmi_rtt_pasn_peer_create_req_eventid] = 22217 WMI_RTT_PASN_PEER_CREATE_REQ_EVENTID; 22218 event_ids[wmi_rtt_pasn_peer_delete_eventid] = 22219 WMI_RTT_PASN_PEER_DELETE_EVENTID; 22220 #endif 22221 #ifdef WLAN_VENDOR_HANDOFF_CONTROL 22222 event_ids[wmi_get_roam_vendor_control_param_event_id] = 22223 WMI_ROAM_GET_VENDOR_CONTROL_PARAM_EVENTID; 22224 #endif 22225 #ifdef WLAN_FEATURE_DBAM_CONFIG 22226 event_ids[wmi_coex_dbam_complete_event_id] = 22227 WMI_COEX_DBAM_COMPLETE_EVENTID; 22228 #endif 22229 event_ids[wmi_spectral_capabilities_eventid] = 22230 WMI_SPECTRAL_CAPABILITIES_EVENTID; 22231 #ifdef WLAN_FEATURE_COAP 22232 event_ids[wmi_wow_coap_buf_info_eventid] = 22233 WMI_WOW_COAP_BUF_INFO_EVENTID; 22234 #endif 22235 #ifdef HEALTH_MON_SUPPORT 22236 event_ids[wmi_extract_health_mon_init_done_info_eventid] = 22237 WMI_HEALTH_MON_INIT_DONE_EVENTID; 22238 #endif /* HEALTH_MON_SUPPORT */ 22239 #ifdef WLAN_SUPPORT_GAP_LL_PS_MODE 22240 event_ids[wmi_xgap_enable_complete_eventid] = 22241 WMI_XGAP_ENABLE_COMPLETE_EVENTID; 22242 #endif 22243 event_ids[wmi_pdev_set_tgtr2p_table_eventid] = 22244 WMI_PDEV_SET_TGTR2P_TABLE_EVENTID; 22245 #ifdef QCA_MANUAL_TRIGGERED_ULOFDMA 22246 event_ids[wmi_manual_ul_ofdma_trig_feedback_eventid] = 22247 WMI_MANUAL_UL_OFDMA_TRIG_FEEDBACK_EVENTID; 22248 event_ids[wmi_manual_ul_ofdma_trig_rx_peer_userinfo_eventid] = 22249 WMI_MANUAL_UL_OFDMA_TRIG_RX_PEER_USERINFO_EVENTID; 22250 #endif 22251 #ifdef QCA_STANDALONE_SOUNDING_TRIGGER 22252 event_ids[wmi_vdev_standalone_sound_complete_eventid] = 22253 WMI_VDEV_STANDALONE_SOUND_COMPLETE_EVENTID; 22254 #endif 22255 event_ids[wmi_csa_ie_received_event_id] = WMI_CSA_IE_RECEIVED_EVENTID; 22256 #if defined(WLAN_FEATURE_ROAM_OFFLOAD) && defined(WLAN_FEATURE_11BE_MLO) 22257 event_ids[wmi_roam_synch_key_event_id] = WMI_ROAM_SYNCH_KEY_EVENTID; 22258 #endif 22259 #ifdef QCA_SUPPORT_PRIMARY_LINK_MIGRATE 22260 event_ids[wmi_peer_ptqm_migration_response_eventid] = 22261 WMI_MLO_PRIMARY_LINK_PEER_MIGRATION_EVENTID; 22262 #endif 22263 event_ids[wmi_pdev_set_rf_path_resp_eventid] = 22264 WMI_PDEV_SET_RF_PATH_RESP_EVENTID; 22265 #ifdef WLAN_RCC_ENHANCED_AOA_SUPPORT 22266 event_ids[wmi_pdev_enhanced_aoa_phasedelta_eventid] = 22267 WMI_PDEV_ENHANCED_AOA_PHASEDELTA_EVENTID; 22268 #endif 22269 } 22270 22271 #ifdef WLAN_FEATURE_LINK_LAYER_STATS 22272 #ifdef FEATURE_CLUB_LL_STATS_AND_GET_STATION 22273 static void wmi_populate_service_get_sta_in_ll_stats_req(uint32_t *wmi_service) 22274 { 22275 wmi_service[wmi_service_get_station_in_ll_stats_req] = 22276 WMI_SERVICE_UNIFIED_LL_GET_STA_CMD_SUPPORT; 22277 } 22278 #else 22279 static void wmi_populate_service_get_sta_in_ll_stats_req(uint32_t *wmi_service) 22280 { 22281 } 22282 #endif /* FEATURE_CLUB_LL_STATS_AND_GET_STATION */ 22283 #else 22284 static void wmi_populate_service_get_sta_in_ll_stats_req(uint32_t *wmi_service) 22285 { 22286 } 22287 #endif /* WLAN_FEATURE_LINK_LAYER_STATS */ 22288 22289 #ifdef WLAN_FEATURE_11BE_MLO 22290 static void populate_tlv_service_mlo(uint32_t *wmi_service) 22291 { 22292 wmi_service[wmi_service_mlo_sta_nan_ndi_support] = 22293 WMI_SERVICE_MLO_STA_NAN_NDI_SUPPORT; 22294 } 22295 #else /* WLAN_FEATURE_11BE_MLO */ 22296 static inline void populate_tlv_service_mlo(uint32_t *wmi_service) 22297 { 22298 } 22299 #endif /* WLAN_FEATURE_11BE_MLO */ 22300 22301 /** 22302 * populate_tlv_service() - populates wmi services 22303 * @wmi_service: Pointer to hold wmi_service 22304 * 22305 * Return: None 22306 */ 22307 static void populate_tlv_service(uint32_t *wmi_service) 22308 { 22309 wmi_service[wmi_service_beacon_offload] = WMI_SERVICE_BEACON_OFFLOAD; 22310 wmi_service[wmi_service_ack_timeout] = WMI_SERVICE_ACK_TIMEOUT; 22311 wmi_service[wmi_service_scan_offload] = WMI_SERVICE_SCAN_OFFLOAD; 22312 wmi_service[wmi_service_roam_scan_offload] = 22313 WMI_SERVICE_ROAM_SCAN_OFFLOAD; 22314 wmi_service[wmi_service_bcn_miss_offload] = 22315 WMI_SERVICE_BCN_MISS_OFFLOAD; 22316 wmi_service[wmi_service_sta_pwrsave] = WMI_SERVICE_STA_PWRSAVE; 22317 wmi_service[wmi_service_sta_advanced_pwrsave] = 22318 WMI_SERVICE_STA_ADVANCED_PWRSAVE; 22319 wmi_service[wmi_service_ap_uapsd] = WMI_SERVICE_AP_UAPSD; 22320 wmi_service[wmi_service_ap_dfs] = WMI_SERVICE_AP_DFS; 22321 wmi_service[wmi_service_11ac] = WMI_SERVICE_11AC; 22322 wmi_service[wmi_service_blockack] = WMI_SERVICE_BLOCKACK; 22323 wmi_service[wmi_service_phyerr] = WMI_SERVICE_PHYERR; 22324 wmi_service[wmi_service_bcn_filter] = WMI_SERVICE_BCN_FILTER; 22325 wmi_service[wmi_service_rtt] = WMI_SERVICE_RTT; 22326 wmi_service[wmi_service_wow] = WMI_SERVICE_WOW; 22327 wmi_service[wmi_service_ratectrl_cache] = WMI_SERVICE_RATECTRL_CACHE; 22328 wmi_service[wmi_service_iram_tids] = WMI_SERVICE_IRAM_TIDS; 22329 wmi_service[wmi_service_arpns_offload] = WMI_SERVICE_ARPNS_OFFLOAD; 22330 wmi_service[wmi_service_nlo] = WMI_SERVICE_NLO; 22331 wmi_service[wmi_service_gtk_offload] = WMI_SERVICE_GTK_OFFLOAD; 22332 wmi_service[wmi_service_scan_sch] = WMI_SERVICE_SCAN_SCH; 22333 wmi_service[wmi_service_csa_offload] = WMI_SERVICE_CSA_OFFLOAD; 22334 wmi_service[wmi_service_chatter] = WMI_SERVICE_CHATTER; 22335 wmi_service[wmi_service_coex_freqavoid] = WMI_SERVICE_COEX_FREQAVOID; 22336 wmi_service[wmi_service_packet_power_save] = 22337 WMI_SERVICE_PACKET_POWER_SAVE; 22338 wmi_service[wmi_service_force_fw_hang] = WMI_SERVICE_FORCE_FW_HANG; 22339 wmi_service[wmi_service_gpio] = WMI_SERVICE_GPIO; 22340 wmi_service[wmi_service_sta_dtim_ps_modulated_dtim] = 22341 WMI_SERVICE_STA_DTIM_PS_MODULATED_DTIM; 22342 wmi_service[wmi_sta_uapsd_basic_auto_trig] = 22343 WMI_STA_UAPSD_BASIC_AUTO_TRIG; 22344 wmi_service[wmi_sta_uapsd_var_auto_trig] = WMI_STA_UAPSD_VAR_AUTO_TRIG; 22345 wmi_service[wmi_service_sta_keep_alive] = WMI_SERVICE_STA_KEEP_ALIVE; 22346 wmi_service[wmi_service_tx_encap] = WMI_SERVICE_TX_ENCAP; 22347 wmi_service[wmi_service_ap_ps_detect_out_of_sync] = 22348 WMI_SERVICE_AP_PS_DETECT_OUT_OF_SYNC; 22349 wmi_service[wmi_service_early_rx] = WMI_SERVICE_EARLY_RX; 22350 wmi_service[wmi_service_sta_smps] = WMI_SERVICE_STA_SMPS; 22351 wmi_service[wmi_service_fwtest] = WMI_SERVICE_FWTEST; 22352 wmi_service[wmi_service_sta_wmmac] = WMI_SERVICE_STA_WMMAC; 22353 wmi_service[wmi_service_tdls] = WMI_SERVICE_TDLS; 22354 wmi_service[wmi_service_burst] = WMI_SERVICE_BURST; 22355 wmi_service[wmi_service_mcc_bcn_interval_change] = 22356 WMI_SERVICE_MCC_BCN_INTERVAL_CHANGE; 22357 wmi_service[wmi_service_adaptive_ocs] = WMI_SERVICE_ADAPTIVE_OCS; 22358 wmi_service[wmi_service_ba_ssn_support] = WMI_SERVICE_BA_SSN_SUPPORT; 22359 wmi_service[wmi_service_filter_ipsec_natkeepalive] = 22360 WMI_SERVICE_FILTER_IPSEC_NATKEEPALIVE; 22361 wmi_service[wmi_service_wlan_hb] = WMI_SERVICE_WLAN_HB; 22362 wmi_service[wmi_service_lte_ant_share_support] = 22363 WMI_SERVICE_LTE_ANT_SHARE_SUPPORT; 22364 wmi_service[wmi_service_batch_scan] = WMI_SERVICE_BATCH_SCAN; 22365 wmi_service[wmi_service_qpower] = WMI_SERVICE_QPOWER; 22366 wmi_service[wmi_service_plmreq] = WMI_SERVICE_PLMREQ; 22367 wmi_service[wmi_service_thermal_mgmt] = WMI_SERVICE_THERMAL_MGMT; 22368 wmi_service[wmi_service_rmc] = WMI_SERVICE_RMC; 22369 wmi_service[wmi_service_mhf_offload] = WMI_SERVICE_MHF_OFFLOAD; 22370 wmi_service[wmi_service_coex_sar] = WMI_SERVICE_COEX_SAR; 22371 wmi_service[wmi_service_bcn_txrate_override] = 22372 WMI_SERVICE_BCN_TXRATE_OVERRIDE; 22373 wmi_service[wmi_service_nan] = WMI_SERVICE_NAN; 22374 wmi_service[wmi_service_l1ss_stat] = WMI_SERVICE_L1SS_STAT; 22375 wmi_service[wmi_service_estimate_linkspeed] = 22376 WMI_SERVICE_ESTIMATE_LINKSPEED; 22377 wmi_service[wmi_service_obss_scan] = WMI_SERVICE_OBSS_SCAN; 22378 wmi_service[wmi_service_tdls_offchan] = WMI_SERVICE_TDLS_OFFCHAN; 22379 wmi_service[wmi_service_tdls_uapsd_buffer_sta] = 22380 WMI_SERVICE_TDLS_UAPSD_BUFFER_STA; 22381 wmi_service[wmi_service_tdls_uapsd_sleep_sta] = 22382 WMI_SERVICE_TDLS_UAPSD_SLEEP_STA; 22383 wmi_service[wmi_service_ibss_pwrsave] = WMI_SERVICE_IBSS_PWRSAVE; 22384 wmi_service[wmi_service_lpass] = WMI_SERVICE_LPASS; 22385 wmi_service[wmi_service_extscan] = WMI_SERVICE_EXTSCAN; 22386 wmi_service[wmi_service_d0wow] = WMI_SERVICE_D0WOW; 22387 wmi_service[wmi_service_hsoffload] = WMI_SERVICE_HSOFFLOAD; 22388 wmi_service[wmi_service_roam_ho_offload] = WMI_SERVICE_ROAM_HO_OFFLOAD; 22389 wmi_service[wmi_service_rx_full_reorder] = WMI_SERVICE_RX_FULL_REORDER; 22390 wmi_service[wmi_service_dhcp_offload] = WMI_SERVICE_DHCP_OFFLOAD; 22391 wmi_service[wmi_service_sta_rx_ipa_offload_support] = 22392 WMI_SERVICE_STA_RX_IPA_OFFLOAD_SUPPORT; 22393 wmi_service[wmi_service_mdns_offload] = WMI_SERVICE_MDNS_OFFLOAD; 22394 wmi_service[wmi_service_sap_auth_offload] = 22395 WMI_SERVICE_SAP_AUTH_OFFLOAD; 22396 wmi_service[wmi_service_dual_band_simultaneous_support] = 22397 WMI_SERVICE_DUAL_BAND_SIMULTANEOUS_SUPPORT; 22398 wmi_service[wmi_service_ocb] = WMI_SERVICE_OCB; 22399 wmi_service[wmi_service_ap_arpns_offload] = 22400 WMI_SERVICE_AP_ARPNS_OFFLOAD; 22401 wmi_service[wmi_service_per_band_chainmask_support] = 22402 WMI_SERVICE_PER_BAND_CHAINMASK_SUPPORT; 22403 wmi_service[wmi_service_packet_filter_offload] = 22404 WMI_SERVICE_PACKET_FILTER_OFFLOAD; 22405 wmi_service[wmi_service_mgmt_tx_htt] = WMI_SERVICE_MGMT_TX_HTT; 22406 wmi_service[wmi_service_mgmt_tx_wmi] = WMI_SERVICE_MGMT_TX_WMI; 22407 wmi_service[wmi_service_ext_msg] = WMI_SERVICE_EXT_MSG; 22408 wmi_service[wmi_service_ext2_msg] = WMI_SERVICE_EXT2_MSG; 22409 wmi_service[wmi_service_mawc] = WMI_SERVICE_MAWC; 22410 wmi_service[wmi_service_multiple_vdev_restart] = 22411 WMI_SERVICE_MULTIPLE_VDEV_RESTART; 22412 wmi_service[wmi_service_multiple_vdev_restart_bmap] = 22413 WMI_SERVICE_MULTIPLE_VDEV_RESTART_BITMAP_SUPPORT; 22414 wmi_service[wmi_service_smart_antenna_sw_support] = 22415 WMI_SERVICE_SMART_ANTENNA_SW_SUPPORT; 22416 wmi_service[wmi_service_smart_antenna_hw_support] = 22417 WMI_SERVICE_SMART_ANTENNA_HW_SUPPORT; 22418 22419 wmi_service[wmi_service_roam_offload] = WMI_SERVICE_UNAVAILABLE; 22420 wmi_service[wmi_service_ratectrl] = WMI_SERVICE_UNAVAILABLE; 22421 wmi_service[wmi_service_enhanced_proxy_sta] = WMI_SERVICE_UNAVAILABLE; 22422 wmi_service[wmi_service_tt] = WMI_SERVICE_THERM_THROT; 22423 wmi_service[wmi_service_atf] = WMI_SERVICE_ATF; 22424 wmi_service[wmi_service_peer_caching] = WMI_SERVICE_UNAVAILABLE; 22425 wmi_service[wmi_service_coex_gpio] = WMI_SERVICE_UNAVAILABLE; 22426 wmi_service[wmi_service_aux_spectral_intf] = WMI_SERVICE_UNAVAILABLE; 22427 wmi_service[wmi_service_aux_chan_load_intf] = WMI_SERVICE_UNAVAILABLE; 22428 wmi_service[wmi_service_bss_channel_info_64] = WMI_SERVICE_UNAVAILABLE; 22429 wmi_service[wmi_service_ext_res_cfg_support] = WMI_SERVICE_UNAVAILABLE; 22430 wmi_service[wmi_service_mesh] = WMI_SERVICE_UNAVAILABLE; 22431 wmi_service[wmi_service_restrt_chnl_support] = WMI_SERVICE_UNAVAILABLE; 22432 wmi_service[wmi_service_peer_stats] = WMI_SERVICE_UNAVAILABLE; 22433 wmi_service[wmi_service_mesh_11s] = WMI_SERVICE_UNAVAILABLE; 22434 wmi_service[wmi_service_periodic_chan_stat_support] = 22435 WMI_SERVICE_PERIODIC_CHAN_STAT_SUPPORT; 22436 wmi_service[wmi_service_tx_mode_push_only] = WMI_SERVICE_UNAVAILABLE; 22437 wmi_service[wmi_service_tx_mode_push_pull] = WMI_SERVICE_UNAVAILABLE; 22438 wmi_service[wmi_service_tx_mode_dynamic] = WMI_SERVICE_UNAVAILABLE; 22439 wmi_service[wmi_service_btcoex_duty_cycle] = WMI_SERVICE_UNAVAILABLE; 22440 wmi_service[wmi_service_4_wire_coex_support] = WMI_SERVICE_UNAVAILABLE; 22441 wmi_service[wmi_service_mesh] = WMI_SERVICE_ENTERPRISE_MESH; 22442 wmi_service[wmi_service_peer_assoc_conf] = WMI_SERVICE_PEER_ASSOC_CONF; 22443 wmi_service[wmi_service_egap] = WMI_SERVICE_EGAP; 22444 wmi_service[wmi_service_sta_pmf_offload] = WMI_SERVICE_STA_PMF_OFFLOAD; 22445 wmi_service[wmi_service_unified_wow_capability] = 22446 WMI_SERVICE_UNIFIED_WOW_CAPABILITY; 22447 wmi_service[wmi_service_enterprise_mesh] = WMI_SERVICE_ENTERPRISE_MESH; 22448 wmi_service[wmi_service_apf_offload] = WMI_SERVICE_BPF_OFFLOAD; 22449 wmi_service[wmi_service_sync_delete_cmds] = 22450 WMI_SERVICE_SYNC_DELETE_CMDS; 22451 wmi_service[wmi_service_ratectrl_limit_max_min_rates] = 22452 WMI_SERVICE_RATECTRL_LIMIT_MAX_MIN_RATES; 22453 wmi_service[wmi_service_nan_data] = WMI_SERVICE_NAN_DATA; 22454 wmi_service[wmi_service_nan_rtt] = WMI_SERVICE_NAN_RTT; 22455 wmi_service[wmi_service_11ax] = WMI_SERVICE_11AX; 22456 wmi_service[wmi_service_deprecated_replace] = 22457 WMI_SERVICE_DEPRECATED_REPLACE; 22458 wmi_service[wmi_service_tdls_conn_tracker_in_host_mode] = 22459 WMI_SERVICE_TDLS_CONN_TRACKER_IN_HOST_MODE; 22460 wmi_service[wmi_service_enhanced_mcast_filter] = 22461 WMI_SERVICE_ENHANCED_MCAST_FILTER; 22462 wmi_service[wmi_service_half_rate_quarter_rate_support] = 22463 WMI_SERVICE_HALF_RATE_QUARTER_RATE_SUPPORT; 22464 wmi_service[wmi_service_vdev_rx_filter] = WMI_SERVICE_VDEV_RX_FILTER; 22465 wmi_service[wmi_service_p2p_listen_offload_support] = 22466 WMI_SERVICE_P2P_LISTEN_OFFLOAD_SUPPORT; 22467 wmi_service[wmi_service_mark_first_wakeup_packet] = 22468 WMI_SERVICE_MARK_FIRST_WAKEUP_PACKET; 22469 wmi_service[wmi_service_multiple_mcast_filter_set] = 22470 WMI_SERVICE_MULTIPLE_MCAST_FILTER_SET; 22471 wmi_service[wmi_service_host_managed_rx_reorder] = 22472 WMI_SERVICE_HOST_MANAGED_RX_REORDER; 22473 wmi_service[wmi_service_flash_rdwr_support] = 22474 WMI_SERVICE_FLASH_RDWR_SUPPORT; 22475 wmi_service[wmi_service_wlan_stats_report] = 22476 WMI_SERVICE_WLAN_STATS_REPORT; 22477 wmi_service[wmi_service_tx_msdu_id_new_partition_support] = 22478 WMI_SERVICE_TX_MSDU_ID_NEW_PARTITION_SUPPORT; 22479 wmi_service[wmi_service_dfs_phyerr_offload] = 22480 WMI_SERVICE_DFS_PHYERR_OFFLOAD; 22481 wmi_service[wmi_service_rcpi_support] = WMI_SERVICE_RCPI_SUPPORT; 22482 wmi_service[wmi_service_fw_mem_dump_support] = 22483 WMI_SERVICE_FW_MEM_DUMP_SUPPORT; 22484 wmi_service[wmi_service_peer_stats_info] = WMI_SERVICE_PEER_STATS_INFO; 22485 wmi_service[wmi_service_regulatory_db] = WMI_SERVICE_REGULATORY_DB; 22486 wmi_service[wmi_service_11d_offload] = WMI_SERVICE_11D_OFFLOAD; 22487 wmi_service[wmi_service_hw_data_filtering] = 22488 WMI_SERVICE_HW_DATA_FILTERING; 22489 wmi_service[wmi_service_pkt_routing] = WMI_SERVICE_PKT_ROUTING; 22490 wmi_service[wmi_service_offchan_tx_wmi] = WMI_SERVICE_OFFCHAN_TX_WMI; 22491 wmi_service[wmi_service_chan_load_info] = WMI_SERVICE_CHAN_LOAD_INFO; 22492 wmi_service[wmi_service_extended_nss_support] = 22493 WMI_SERVICE_EXTENDED_NSS_SUPPORT; 22494 wmi_service[wmi_service_widebw_scan] = WMI_SERVICE_SCAN_PHYMODE_SUPPORT; 22495 wmi_service[wmi_service_bcn_offload_start_stop_support] = 22496 WMI_SERVICE_BCN_OFFLOAD_START_STOP_SUPPORT; 22497 wmi_service[wmi_service_offchan_data_tid_support] = 22498 WMI_SERVICE_OFFCHAN_DATA_TID_SUPPORT; 22499 wmi_service[wmi_service_support_dma] = 22500 WMI_SERVICE_SUPPORT_DIRECT_DMA; 22501 wmi_service[wmi_service_8ss_tx_bfee] = WMI_SERVICE_8SS_TX_BFEE; 22502 wmi_service[wmi_service_fils_support] = WMI_SERVICE_FILS_SUPPORT; 22503 wmi_service[wmi_service_mawc_support] = WMI_SERVICE_MAWC_SUPPORT; 22504 wmi_service[wmi_service_wow_wakeup_by_timer_pattern] = 22505 WMI_SERVICE_WOW_WAKEUP_BY_TIMER_PATTERN; 22506 wmi_service[wmi_service_11k_neighbour_report_support] = 22507 WMI_SERVICE_11K_NEIGHBOUR_REPORT_SUPPORT; 22508 wmi_service[wmi_service_ap_obss_detection_offload] = 22509 WMI_SERVICE_AP_OBSS_DETECTION_OFFLOAD; 22510 wmi_service[wmi_service_bss_color_offload] = 22511 WMI_SERVICE_BSS_COLOR_OFFLOAD; 22512 wmi_service[wmi_service_gmac_offload_support] = 22513 WMI_SERVICE_GMAC_OFFLOAD_SUPPORT; 22514 wmi_service[wmi_service_dual_beacon_on_single_mac_scc_support] = 22515 WMI_SERVICE_DUAL_BEACON_ON_SINGLE_MAC_SCC_SUPPORT; 22516 wmi_service[wmi_service_dual_beacon_on_single_mac_mcc_support] = 22517 WMI_SERVICE_DUAL_BEACON_ON_SINGLE_MAC_MCC_SUPPORT; 22518 wmi_service[wmi_service_twt_requestor] = WMI_SERVICE_STA_TWT; 22519 wmi_service[wmi_service_twt_responder] = WMI_SERVICE_AP_TWT; 22520 wmi_service[wmi_service_listen_interval_offload_support] = 22521 WMI_SERVICE_LISTEN_INTERVAL_OFFLOAD_SUPPORT; 22522 wmi_service[wmi_service_esp_support] = WMI_SERVICE_ESP_SUPPORT; 22523 wmi_service[wmi_service_obss_spatial_reuse] = 22524 WMI_SERVICE_OBSS_SPATIAL_REUSE; 22525 wmi_service[wmi_service_per_vdev_chain_support] = 22526 WMI_SERVICE_PER_VDEV_CHAINMASK_CONFIG_SUPPORT; 22527 wmi_service[wmi_service_new_htt_msg_format] = 22528 WMI_SERVICE_HTT_H2T_NO_HTC_HDR_LEN_IN_MSG_LEN; 22529 wmi_service[wmi_service_peer_unmap_cnf_support] = 22530 WMI_SERVICE_PEER_UNMAP_RESPONSE_SUPPORT; 22531 wmi_service[wmi_service_beacon_reception_stats] = 22532 WMI_SERVICE_BEACON_RECEPTION_STATS; 22533 wmi_service[wmi_service_vdev_latency_config] = 22534 WMI_SERVICE_VDEV_LATENCY_CONFIG; 22535 wmi_service[wmi_service_nan_dbs_support] = WMI_SERVICE_NAN_DBS_SUPPORT; 22536 wmi_service[wmi_service_ndi_dbs_support] = WMI_SERVICE_NDI_DBS_SUPPORT; 22537 wmi_service[wmi_service_nan_sap_support] = WMI_SERVICE_NAN_SAP_SUPPORT; 22538 wmi_service[wmi_service_ndi_sap_support] = WMI_SERVICE_NDI_SAP_SUPPORT; 22539 wmi_service[wmi_service_nan_disable_support] = 22540 WMI_SERVICE_NAN_DISABLE_SUPPORT; 22541 wmi_service[wmi_service_sta_plus_sta_support] = 22542 WMI_SERVICE_STA_PLUS_STA_SUPPORT; 22543 wmi_service[wmi_service_hw_db2dbm_support] = 22544 WMI_SERVICE_HW_DB2DBM_CONVERSION_SUPPORT; 22545 wmi_service[wmi_service_wlm_stats_support] = 22546 WMI_SERVICE_WLM_STATS_REQUEST; 22547 wmi_service[wmi_service_infra_mbssid] = WMI_SERVICE_INFRA_MBSSID; 22548 wmi_service[wmi_service_ema_ap_support] = WMI_SERVICE_EMA_AP_SUPPORT; 22549 wmi_service[wmi_service_ul_ru26_allowed] = WMI_SERVICE_UL_RU26_ALLOWED; 22550 wmi_service[wmi_service_cfr_capture_support] = 22551 WMI_SERVICE_CFR_CAPTURE_SUPPORT; 22552 wmi_service[wmi_service_cfr_capture_pdev_id_soc] = 22553 WMI_SERVICE_CFR_CAPTURE_PDEV_ID_SOC; 22554 wmi_service[wmi_service_bcast_twt_support] = 22555 WMI_SERVICE_BROADCAST_TWT; 22556 wmi_service[wmi_service_wpa3_ft_sae_support] = 22557 WMI_SERVICE_WPA3_FT_SAE_SUPPORT; 22558 wmi_service[wmi_service_wpa3_ft_suite_b_support] = 22559 WMI_SERVICE_WPA3_FT_SUITE_B_SUPPORT; 22560 wmi_service[wmi_service_ft_fils] = 22561 WMI_SERVICE_WPA3_FT_FILS; 22562 wmi_service[wmi_service_adaptive_11r_support] = 22563 WMI_SERVICE_ADAPTIVE_11R_ROAM; 22564 wmi_service[wmi_service_tx_compl_tsf64] = 22565 WMI_SERVICE_TX_COMPL_TSF64; 22566 wmi_service[wmi_service_data_stall_recovery_support] = 22567 WMI_SERVICE_DSM_ROAM_FILTER; 22568 wmi_service[wmi_service_vdev_delete_all_peer] = 22569 WMI_SERVICE_DELETE_ALL_PEER_SUPPORT; 22570 wmi_service[wmi_service_three_way_coex_config_legacy] = 22571 WMI_SERVICE_THREE_WAY_COEX_CONFIG_LEGACY; 22572 wmi_service[wmi_service_rx_fse_support] = 22573 WMI_SERVICE_RX_FSE_SUPPORT; 22574 wmi_service[wmi_service_sae_roam_support] = 22575 WMI_SERVICE_WPA3_SAE_ROAM_SUPPORT; 22576 wmi_service[wmi_service_owe_roam_support] = 22577 WMI_SERVICE_WPA3_OWE_ROAM_SUPPORT; 22578 wmi_service[wmi_service_6ghz_support] = 22579 WMI_SERVICE_6GHZ_SUPPORT; 22580 wmi_service[wmi_service_bw_165mhz_support] = 22581 WMI_SERVICE_BW_165MHZ_SUPPORT; 22582 wmi_service[wmi_service_bw_restricted_80p80_support] = 22583 WMI_SERVICE_BW_RESTRICTED_80P80_SUPPORT; 22584 wmi_service[wmi_service_packet_capture_support] = 22585 WMI_SERVICE_PACKET_CAPTURE_SUPPORT; 22586 wmi_service[wmi_service_nan_vdev] = WMI_SERVICE_NAN_VDEV_SUPPORT; 22587 wmi_service[wmi_service_peer_delete_no_peer_flush_tids_cmd] = 22588 WMI_SERVICE_PEER_DELETE_NO_PEER_FLUSH_TIDS_CMD; 22589 wmi_service[wmi_service_multiple_vdev_restart_ext] = 22590 WMI_SERVICE_UNAVAILABLE; 22591 wmi_service[wmi_service_time_sync_ftm] = 22592 WMI_SERVICE_AUDIO_SYNC_SUPPORT; 22593 wmi_service[wmi_service_nss_ratio_to_host_support] = 22594 WMI_SERVICE_NSS_RATIO_TO_HOST_SUPPORT; 22595 wmi_service[wmi_roam_scan_chan_list_to_host_support] = 22596 WMI_SERVICE_ROAM_SCAN_CHANNEL_LIST_TO_HOST_SUPPORT; 22597 wmi_service[wmi_beacon_protection_support] = 22598 WMI_SERVICE_BEACON_PROTECTION_SUPPORT; 22599 wmi_service[wmi_service_sta_nan_ndi_four_port] = 22600 WMI_SERVICE_NDI_NDI_STA_SUPPORT; 22601 wmi_service[wmi_service_host_scan_stop_vdev_all] = 22602 WMI_SERVICE_HOST_SCAN_STOP_VDEV_ALL_SUPPORT; 22603 wmi_service[wmi_support_extend_address] = 22604 WMI_SERVICE_SUPPORT_EXTEND_ADDRESS; 22605 wmi_service[wmi_service_srg_srp_spatial_reuse_support] = 22606 WMI_SERVICE_SRG_SRP_SPATIAL_REUSE_SUPPORT; 22607 wmi_service[wmi_service_suiteb_roam_support] = 22608 WMI_SERVICE_WPA3_SUITEB_ROAM_SUPPORT; 22609 wmi_service[wmi_service_no_interband_mcc_support] = 22610 WMI_SERVICE_NO_INTERBAND_MCC_SUPPORT; 22611 wmi_service[wmi_service_dual_sta_roam_support] = 22612 WMI_SERVICE_DUAL_STA_ROAM_SUPPORT; 22613 wmi_service[wmi_service_peer_create_conf] = 22614 WMI_SERVICE_PEER_CREATE_CONF; 22615 wmi_service[wmi_service_configure_roam_trigger_param_support] = 22616 WMI_SERVICE_CONFIGURE_ROAM_TRIGGER_PARAM_SUPPORT; 22617 wmi_service[wmi_service_5dot9_ghz_support] = 22618 WMI_SERVICE_5_DOT_9GHZ_SUPPORT; 22619 wmi_service[wmi_service_cfr_ta_ra_as_fp_support] = 22620 WMI_SERVICE_CFR_TA_RA_AS_FP_SUPPORT; 22621 wmi_service[wmi_service_cfr_capture_count_support] = 22622 WMI_SERVICE_CFR_CAPTURE_COUNT_SUPPORT; 22623 wmi_service[wmi_service_ocv_support] = 22624 WMI_SERVICE_OCV_SUPPORT; 22625 wmi_service[wmi_service_ll_stats_per_chan_rx_tx_time] = 22626 WMI_SERVICE_LL_STATS_PER_CHAN_RX_TX_TIME_SUPPORT; 22627 wmi_service[wmi_service_thermal_multi_client_support] = 22628 WMI_SERVICE_THERMAL_MULTI_CLIENT_SUPPORT; 22629 wmi_service[wmi_service_mbss_param_in_vdev_start_support] = 22630 WMI_SERVICE_MBSS_PARAM_IN_VDEV_START_SUPPORT; 22631 wmi_service[wmi_service_fse_cmem_alloc_support] = 22632 WMI_SERVICE_FSE_CMEM_ALLOC_SUPPORT; 22633 wmi_service[wmi_service_scan_conf_per_ch_support] = 22634 WMI_SERVICE_SCAN_CONFIG_PER_CHANNEL; 22635 wmi_service[wmi_service_csa_beacon_template] = 22636 WMI_SERVICE_CSA_BEACON_TEMPLATE; 22637 #if defined(WIFI_POS_CONVERGED) && defined(WLAN_FEATURE_RTT_11AZ_SUPPORT) 22638 wmi_service[wmi_service_rtt_11az_ntb_support] = 22639 WMI_SERVICE_RTT_11AZ_NTB_SUPPORT; 22640 wmi_service[wmi_service_rtt_11az_tb_support] = 22641 WMI_SERVICE_RTT_11AZ_TB_SUPPORT; 22642 wmi_service[wmi_service_rtt_11az_tb_rsta_support] = 22643 WMI_SERVICE_RTT_11AZ_TB_RSTA_SUPPORT; 22644 wmi_service[wmi_service_rtt_11az_mac_sec_support] = 22645 WMI_SERVICE_RTT_11AZ_MAC_SEC_SUPPORT; 22646 wmi_service[wmi_service_rtt_11az_mac_phy_sec_support] = 22647 WMI_SERVICE_RTT_11AZ_MAC_PHY_SEC_SUPPORT; 22648 #endif 22649 #ifdef WLAN_FEATURE_IGMP_OFFLOAD 22650 wmi_service[wmi_service_igmp_offload_support] = 22651 WMI_SERVICE_IGMP_OFFLOAD_SUPPORT; 22652 #endif 22653 22654 #ifdef FEATURE_WLAN_TDLS 22655 #ifdef WLAN_FEATURE_11AX 22656 wmi_service[wmi_service_tdls_ax_support] = 22657 WMI_SERVICE_11AX_TDLS_SUPPORT; 22658 wmi_service[wmi_service_tdls_6g_support] = 22659 WMI_SERVICE_TDLS_6GHZ_SUPPORT; 22660 #endif 22661 wmi_service[wmi_service_tdls_wideband_support] = 22662 WMI_SERVICE_TDLS_WIDEBAND_SUPPORT; 22663 wmi_service[wmi_service_tdls_concurrency_support] = 22664 WMI_SERVICE_TDLS_CONCURRENCY_SUPPORT; 22665 #endif 22666 #ifdef FEATURE_WLAN_TDLS 22667 #ifdef WLAN_FEATURE_11BE 22668 wmi_service[wmi_service_tdls_mlo_support] = 22669 WMI_SERVICE_11BE_MLO_TDLS_SUPPORT; 22670 #endif 22671 #endif 22672 #ifdef WLAN_SUPPORT_TWT 22673 wmi_service[wmi_service_twt_bcast_req_support] = 22674 WMI_SERVICE_BROADCAST_TWT_REQUESTER; 22675 wmi_service[wmi_service_twt_bcast_resp_support] = 22676 WMI_SERVICE_BROADCAST_TWT_RESPONDER; 22677 wmi_service[wmi_service_twt_nudge] = 22678 WMI_SERVICE_TWT_NUDGE; 22679 wmi_service[wmi_service_all_twt] = 22680 WMI_SERVICE_TWT_ALL_DIALOG_ID; 22681 wmi_service[wmi_service_twt_statistics] = 22682 WMI_SERVICE_TWT_STATS; 22683 wmi_service[wmi_service_restricted_twt] = WMI_SERVICE_RESTRICTED_TWT; 22684 #endif 22685 wmi_service[wmi_service_spectral_scan_disabled] = 22686 WMI_SERVICE_SPECTRAL_SCAN_DISABLED; 22687 wmi_service[wmi_service_sae_eapol_offload_support] = 22688 WMI_SERVICE_SAE_EAPOL_OFFLOAD_SUPPORT; 22689 wmi_populate_service_get_sta_in_ll_stats_req(wmi_service); 22690 22691 wmi_service[wmi_service_wapi_concurrency_supported] = 22692 WMI_SERVICE_WAPI_CONCURRENCY_SUPPORTED; 22693 wmi_service[wmi_service_sap_connected_d3_wow] = 22694 WMI_SERVICE_SAP_CONNECTED_D3WOW; 22695 wmi_service[wmi_service_go_connected_d3_wow] = 22696 WMI_SERVICE_SAP_CONNECTED_D3WOW; 22697 wmi_service[wmi_service_ext_tpc_reg_support] = 22698 WMI_SERVICE_EXT_TPC_REG_SUPPORT; 22699 wmi_service[wmi_service_eirp_preferred_support] = 22700 WMI_SERVICE_EIRP_PREFERRED_SUPPORT; 22701 wmi_service[wmi_service_ndi_txbf_support] = 22702 WMI_SERVICE_NDI_TXBF_SUPPORT; 22703 wmi_service[wmi_service_reg_cc_ext_event_support] = 22704 WMI_SERVICE_REG_CC_EXT_EVENT_SUPPORT; 22705 wmi_service[wmi_service_bang_radar_320_support] = 22706 WMI_SERVICE_BANG_RADAR_320_SUPPORT; 22707 #if defined(CONFIG_BAND_6GHZ) 22708 wmi_service[wmi_service_lower_6g_edge_ch_supp] = 22709 WMI_SERVICE_ENABLE_LOWER_6G_EDGE_CH_SUPP; 22710 wmi_service[wmi_service_disable_upper_6g_edge_ch_supp] = 22711 WMI_SERVICE_DISABLE_UPPER_6G_EDGE_CH_SUPP; 22712 #ifdef CONFIG_AFC_SUPPORT 22713 wmi_service[wmi_service_afc_support] = 22714 WMI_SERVICE_AFC_SUPPORT; 22715 #endif 22716 #endif 22717 wmi_service[wmi_service_dcs_awgn_int_support] = 22718 WMI_SERVICE_DCS_AWGN_INT_SUPPORT; 22719 wmi_populate_service_11be(wmi_service); 22720 22721 #ifdef WLAN_FEATURE_BIG_DATA_STATS 22722 wmi_service[wmi_service_big_data_support] = 22723 WMI_SERVICE_BIG_DATA_SUPPORT; 22724 #endif 22725 wmi_service[wmi_service_ampdu_tx_buf_size_256_support] = 22726 WMI_SERVICE_AMPDU_TX_BUF_SIZE_256_SUPPORT; 22727 wmi_service[wmi_service_halphy_cal_enable_disable_support] = 22728 WMI_SERVICE_HALPHY_CAL_ENABLE_DISABLE_SUPPORT; 22729 wmi_service[wmi_service_halphy_cal_status] = 22730 WMI_SERVICE_HALPHY_CAL_STATUS; 22731 wmi_service[wmi_service_rtt_ap_initiator_staggered_mode_supported] = 22732 WMI_SERVICE_RTT_AP_INITIATOR_STAGGERED_MODE_SUPPORTED; 22733 wmi_service[wmi_service_rtt_ap_initiator_bursted_mode_supported] = 22734 WMI_SERVICE_RTT_AP_INITIATOR_BURSTED_MODE_SUPPORTED; 22735 wmi_service[wmi_service_ema_multiple_group_supported] = 22736 WMI_SERVICE_EMA_MULTIPLE_GROUP_SUPPORT; 22737 wmi_service[wmi_service_large_beacon_supported] = 22738 WMI_SERVICE_LARGE_BEACON_SUPPORT; 22739 wmi_service[wmi_service_aoa_for_rcc_supported] = 22740 WMI_SERVICE_AOA_FOR_RCC_SUPPORTED; 22741 #ifdef WLAN_FEATURE_P2P_P2P_STA 22742 wmi_service[wmi_service_p2p_p2p_cc_support] = 22743 WMI_SERVICE_P2P_P2P_CONCURRENCY_SUPPORT; 22744 #endif 22745 #ifdef THERMAL_STATS_SUPPORT 22746 wmi_service[wmi_service_thermal_stats_temp_range_supported] = 22747 WMI_SERVICE_THERMAL_THROT_STATS_TEMP_RANGE_SUPPORT; 22748 #endif 22749 wmi_service[wmi_service_hw_mode_policy_offload_support] = 22750 WMI_SERVICE_HW_MODE_POLICY_OFFLOAD_SUPPORT; 22751 wmi_service[wmi_service_mgmt_rx_reo_supported] = 22752 WMI_SERVICE_MGMT_RX_REO_SUPPORTED; 22753 wmi_service[wmi_service_phy_dma_byte_swap_support] = 22754 WMI_SERVICE_UNAVAILABLE; 22755 wmi_service[wmi_service_spectral_session_info_support] = 22756 WMI_SERVICE_SPECTRAL_SESSION_INFO_SUPPORT; 22757 wmi_service[wmi_service_umac_hang_recovery_support] = 22758 WMI_SERVICE_UMAC_HANG_RECOVERY_SUPPORT; 22759 wmi_service[wmi_service_mu_snif] = WMI_SERVICE_MU_SNIF; 22760 #ifdef WLAN_FEATURE_DYNAMIC_MAC_ADDR_UPDATE 22761 wmi_service[wmi_service_dynamic_update_vdev_macaddr_support] = 22762 WMI_SERVICE_DYNAMIC_VDEV_MAC_ADDR_UPDATE_SUPPORT; 22763 #endif 22764 wmi_service[wmi_service_probe_all_bw_support] = 22765 WMI_SERVICE_PROBE_ALL_BW_SUPPORT; 22766 wmi_service[wmi_service_pno_scan_conf_per_ch_support] = 22767 WMI_SERVICE_PNO_SCAN_CONFIG_PER_CHANNEL; 22768 #ifdef QCA_UNDECODED_METADATA_SUPPORT 22769 wmi_service[wmi_service_fp_phy_err_filter_support] = 22770 WMI_SERVICE_FP_PHY_ERR_FILTER_SUPPORT; 22771 #endif 22772 populate_tlv_service_mlo(wmi_service); 22773 wmi_service[wmi_service_pdev_rate_config_support] = 22774 WMI_SERVICE_PDEV_RATE_CONFIG_SUPPORT; 22775 wmi_service[wmi_service_multi_peer_group_cmd_support] = 22776 WMI_SERVICE_MULTIPLE_PEER_GROUP_CMD_SUPPORT; 22777 #ifdef WLAN_FEATURE_11BE 22778 wmi_service[wmi_service_radar_found_chan_freq_eq_center_freq] = 22779 WMI_IS_RADAR_FOUND_CHAN_FREQ_IS_CENTER_FREQ; 22780 #endif 22781 #ifdef WLAN_PDEV_VDEV_SEND_MULTI_PARAM 22782 wmi_service[wmi_service_combined_set_param_support] = 22783 WMI_SERVICE_COMBINED_SET_PARAM_SUPPORT; 22784 #endif 22785 wmi_service[wmi_service_pn_replay_check_support] = 22786 WMI_SERVICE_PN_REPLAY_CHECK_SUPPORT; 22787 #ifdef QCA_RSSI_DB2DBM 22788 wmi_service[wmi_service_pdev_rssi_dbm_conv_event_support] = 22789 WMI_SERVICE_PDEV_RSSI_DBM_CONV_EVENT_SUPPORT; 22790 #endif 22791 wmi_service[wmi_service_pktlog_decode_info_support] = 22792 WMI_SERVICE_PKTLOG_DECODE_INFO_SUPPORT; 22793 #ifdef WLAN_FEATURE_ROAM_OFFLOAD 22794 wmi_service[wmi_service_roam_stats_per_candidate_frame_info] = 22795 WMI_SERVICE_ROAM_STAT_PER_CANDIDATE_FRAME_INFO_SUPPORT; 22796 #endif 22797 #ifdef MULTI_CLIENT_LL_SUPPORT 22798 wmi_service[wmi_service_configure_multi_client_ll_support] = 22799 WMI_SERVICE_MULTI_CLIENT_LL_SUPPORT; 22800 #endif 22801 #ifdef WLAN_VENDOR_HANDOFF_CONTROL 22802 wmi_service[wmi_service_configure_vendor_handoff_control_support] = 22803 WMI_SERVICE_FW_INI_PARSE_SUPPORT; 22804 #endif 22805 wmi_service[wmi_service_linkspeed_roam_trigger_support] = 22806 WMI_SERVICE_LINKSPEED_ROAM_TRIGGER_SUPPORT; 22807 #ifdef FEATURE_SET 22808 wmi_service[wmi_service_feature_set_event_support] = 22809 WMI_SERVICE_FEATURE_SET_EVENT_SUPPORT; 22810 #endif 22811 #ifdef WLAN_FEATURE_SR 22812 wmi_service[wmi_service_obss_per_packet_sr_support] = 22813 WMI_SERVICE_OBSS_PER_PACKET_SR_SUPPORT; 22814 #endif 22815 wmi_service[wmi_service_wpa3_sha384_roam_support] = 22816 WMI_SERVICE_WMI_SERVICE_WPA3_SHA384_ROAM_SUPPORT; 22817 wmi_service[wmi_service_self_mld_roam_between_dbs_and_hbs] = 22818 WMI_SERVICE_SELF_MLD_ROAM_BETWEEN_DBS_AND_HBS; 22819 /* TODO: Assign FW Enum after FW Shared header changes are merged */ 22820 wmi_service[wmi_service_v1a_v1b_supported] = 22821 WMI_SERVICE_PEER_METADATA_V1A_V1B_SUPPORT; 22822 #ifdef QCA_MANUAL_TRIGGERED_ULOFDMA 22823 wmi_service[wmi_service_manual_ulofdma_trigger_support] = 22824 WMI_SERVICE_MANUAL_ULOFDMA_TRIGGER_SUPPORT; 22825 #endif 22826 wmi_service[wmi_service_pre_rx_timeout] = 22827 WMI_SERVICE_PRE_RX_TO; 22828 #ifdef QCA_STANDALONE_SOUNDING_TRIGGER 22829 wmi_service[wmi_service_standalone_sound] = 22830 WMI_SERVICE_STANDALONE_SOUND; 22831 #endif 22832 wmi_service[wmi_service_cca_busy_info_for_each_20mhz] = 22833 WMI_SERVICE_CCA_BUSY_INFO_FOREACH_20MHZ; 22834 wmi_service[wmi_service_vdev_param_chwidth_with_notify_support] = 22835 WMI_SERVICE_VDEV_PARAM_CHWIDTH_WITH_NOTIFY_SUPPORT; 22836 #ifdef WLAN_FEATURE_11BE_MLO 22837 wmi_service[wmi_service_mlo_tsf_sync] = WMI_SERVICE_MLO_TSF_SYNC; 22838 wmi_service[wmi_service_n_link_mlo_support] = 22839 WMI_SERVICE_N_LINK_MLO_SUPPORT; 22840 wmi_service[wmi_service_per_link_stats_support] = 22841 WMI_SERVICE_PER_LINK_STATS_SUPPORT; 22842 wmi_service[wmi_service_pdev_wsi_stats_info_support] = 22843 WMI_SERVICE_PDEV_WSI_STATS_INFO_SUPPORT; 22844 wmi_service[wmi_service_mlo_tid_to_link_mapping_support] = 22845 WMI_SERVICE_MLO_TID_TO_LINK_MAPPING_SUPPORT; 22846 #endif 22847 wmi_service[wmi_service_aux_mac_support] = WMI_SERVICE_AUX_MAC_SUPPORT; 22848 #ifdef WLAN_ATF_INCREASED_STA 22849 wmi_service[wmi_service_atf_max_client_512_support] = 22850 WMI_SERVICE_ATF_MAX_CLIENT_512_SUPPORT; 22851 #endif 22852 wmi_service[wmi_service_fisa_dynamic_msdu_aggr_size_support] = 22853 WMI_SERVICE_FISA_DYNAMIC_MSDU_AGGR_SIZE_SUPPORT; 22854 wmi_service[wmi_service_radar_flags_support] = 22855 WMI_SERVICE_RADAR_FLAGS_SUPPORT; 22856 } 22857 22858 /** 22859 * wmi_ocb_ut_attach() - Attach OCB test framework 22860 * @wmi_handle: wmi handle 22861 * 22862 * Return: None 22863 */ 22864 #ifdef WLAN_OCB_UT 22865 void wmi_ocb_ut_attach(struct wmi_unified *wmi_handle); 22866 #else 22867 static inline void wmi_ocb_ut_attach(struct wmi_unified *wmi_handle) 22868 { 22869 return; 22870 } 22871 #endif 22872 22873 /** 22874 * wmi_tlv_attach() - Attach TLV APIs 22875 * @wmi_handle: wmi handle 22876 * Return: None 22877 */ 22878 void wmi_tlv_attach(wmi_unified_t wmi_handle) 22879 { 22880 wmi_handle->ops = &tlv_ops; 22881 wmi_ocb_ut_attach(wmi_handle); 22882 wmi_handle->soc->svc_ids = &multi_svc_ids[0]; 22883 #ifdef WMI_INTERFACE_EVENT_LOGGING 22884 /* Skip saving WMI_CMD_HDR and TLV HDR */ 22885 wmi_handle->soc->buf_offset_command = 8; 22886 /* WMI_CMD_HDR is already stripped, skip saving TLV HDR */ 22887 wmi_handle->soc->buf_offset_event = 4; 22888 #endif 22889 populate_tlv_events_id(wmi_handle->wmi_events); 22890 populate_tlv_service(wmi_handle->services); 22891 wmi_wds_attach_tlv(wmi_handle); 22892 wmi_twt_attach_tlv(wmi_handle); 22893 wmi_extscan_attach_tlv(wmi_handle); 22894 wmi_smart_ant_attach_tlv(wmi_handle); 22895 wmi_dbr_attach_tlv(wmi_handle); 22896 wmi_atf_attach_tlv(wmi_handle); 22897 wmi_ap_attach_tlv(wmi_handle); 22898 wmi_bcn_attach_tlv(wmi_handle); 22899 wmi_ocb_attach_tlv(wmi_handle); 22900 wmi_nan_attach_tlv(wmi_handle); 22901 wmi_p2p_attach_tlv(wmi_handle); 22902 wmi_interop_issues_ap_attach_tlv(wmi_handle); 22903 wmi_dcs_attach_tlv(wmi_handle); 22904 wmi_roam_attach_tlv(wmi_handle); 22905 wmi_concurrency_attach_tlv(wmi_handle); 22906 wmi_pmo_attach_tlv(wmi_handle); 22907 wmi_sta_attach_tlv(wmi_handle); 22908 wmi_11ax_bss_color_attach_tlv(wmi_handle); 22909 wmi_fwol_attach_tlv(wmi_handle); 22910 wmi_vdev_attach_tlv(wmi_handle); 22911 wmi_cfr_attach_tlv(wmi_handle); 22912 wmi_cp_stats_attach_tlv(wmi_handle); 22913 wmi_gpio_attach_tlv(wmi_handle); 22914 wmi_11be_attach_tlv(wmi_handle); 22915 wmi_coap_attach_tlv(wmi_handle); 22916 wmi_mlme_attach_tlv(wmi_handle); 22917 } 22918 qdf_export_symbol(wmi_tlv_attach); 22919 22920 /** 22921 * wmi_tlv_init() - Initialize WMI TLV module by registering TLV attach routine 22922 * 22923 * Return: None 22924 */ 22925 void wmi_tlv_init(void) 22926 { 22927 wmi_unified_register_module(WMI_TLV_TARGET, &wmi_tlv_attach); 22928 } 22929