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, 1875 params->vdev_id, params->assoc_id, 1876 params->profile_idx, params->profile_num, 1877 QDF_MAC_ADDR_REF(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 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 2836 WMI_FORCE_FW_HANG_CMDID); 2837 if (ret) { 2838 wmi_err("Failed to send set param command, ret = %d", ret); 2839 wmi_buf_free(buf); 2840 } 2841 2842 return ret; 2843 } 2844 2845 /** 2846 * send_dbglog_cmd_tlv() - set debug log level 2847 * @wmi_handle: handle to WMI. 2848 * @dbglog_param: pointer to hold dbglog level parameter 2849 * 2850 * Return: QDF_STATUS_SUCCESS on success, otherwise QDF_STATUS_E_* 2851 */ 2852 static QDF_STATUS 2853 send_dbglog_cmd_tlv(wmi_unified_t wmi_handle, 2854 struct dbglog_params *dbglog_param) 2855 { 2856 wmi_buf_t buf; 2857 wmi_debug_log_config_cmd_fixed_param *configmsg; 2858 QDF_STATUS status; 2859 int32_t i; 2860 int32_t len; 2861 int8_t *buf_ptr; 2862 int32_t *module_id_bitmap_array; /* Used to form the second tlv */ 2863 2864 ASSERT(dbglog_param->bitmap_len < MAX_MODULE_ID_BITMAP_WORDS); 2865 2866 /* Allocate size for 2 tlvs - including tlv hdr space for second tlv */ 2867 len = sizeof(wmi_debug_log_config_cmd_fixed_param) + WMI_TLV_HDR_SIZE + 2868 (sizeof(int32_t) * MAX_MODULE_ID_BITMAP_WORDS); 2869 buf = wmi_buf_alloc(wmi_handle, len); 2870 if (!buf) 2871 return QDF_STATUS_E_NOMEM; 2872 2873 configmsg = 2874 (wmi_debug_log_config_cmd_fixed_param *) (wmi_buf_data(buf)); 2875 buf_ptr = (int8_t *) configmsg; 2876 WMITLV_SET_HDR(&configmsg->tlv_header, 2877 WMITLV_TAG_STRUC_wmi_debug_log_config_cmd_fixed_param, 2878 WMITLV_GET_STRUCT_TLVLEN 2879 (wmi_debug_log_config_cmd_fixed_param)); 2880 configmsg->dbg_log_param = dbglog_param->param; 2881 configmsg->value = dbglog_param->val; 2882 /* Filling in the data part of second tlv -- should 2883 * follow first tlv _ WMI_TLV_HDR_SIZE */ 2884 module_id_bitmap_array = (uint32_t *) (buf_ptr + 2885 sizeof 2886 (wmi_debug_log_config_cmd_fixed_param) 2887 + WMI_TLV_HDR_SIZE); 2888 WMITLV_SET_HDR(buf_ptr + sizeof(wmi_debug_log_config_cmd_fixed_param), 2889 WMITLV_TAG_ARRAY_UINT32, 2890 sizeof(uint32_t) * MAX_MODULE_ID_BITMAP_WORDS); 2891 if (dbglog_param->module_id_bitmap) { 2892 for (i = 0; i < dbglog_param->bitmap_len; ++i) { 2893 module_id_bitmap_array[i] = 2894 dbglog_param->module_id_bitmap[i]; 2895 } 2896 } 2897 2898 wmi_mtrace(WMI_DBGLOG_CFG_CMDID, NO_SESSION, 0); 2899 status = wmi_unified_cmd_send(wmi_handle, buf, 2900 len, WMI_DBGLOG_CFG_CMDID); 2901 2902 if (status != QDF_STATUS_SUCCESS) 2903 wmi_buf_free(buf); 2904 2905 return status; 2906 } 2907 2908 /** 2909 * send_vdev_set_param_cmd_tlv() - WMI vdev set parameter function 2910 * @wmi_handle: handle to WMI. 2911 * @param: pointer to hold vdev set parameter 2912 * 2913 * Return: QDF_STATUS_SUCCESS for success or error code 2914 */ 2915 static QDF_STATUS send_vdev_set_param_cmd_tlv(wmi_unified_t wmi_handle, 2916 struct vdev_set_params *param) 2917 { 2918 QDF_STATUS ret; 2919 wmi_vdev_set_param_cmd_fixed_param *cmd; 2920 wmi_buf_t buf; 2921 uint16_t len = sizeof(*cmd); 2922 uint32_t vdev_param; 2923 2924 vdev_param = convert_host_vdev_param_tlv(param->param_id); 2925 if (vdev_param == WMI_UNAVAILABLE_PARAM) { 2926 wmi_err("Vdev param %d not available", param->param_id); 2927 return QDF_STATUS_E_INVAL; 2928 2929 } 2930 2931 buf = wmi_buf_alloc(wmi_handle, len); 2932 if (!buf) 2933 return QDF_STATUS_E_NOMEM; 2934 2935 cmd = (wmi_vdev_set_param_cmd_fixed_param *) wmi_buf_data(buf); 2936 WMITLV_SET_HDR(&cmd->tlv_header, 2937 WMITLV_TAG_STRUC_wmi_vdev_set_param_cmd_fixed_param, 2938 WMITLV_GET_STRUCT_TLVLEN(wmi_vdev_set_param_cmd_fixed_param)); 2939 cmd->vdev_id = param->vdev_id; 2940 cmd->param_id = vdev_param; 2941 cmd->param_value = param->param_value; 2942 wmi_nofl_debug("Set vdev %d param 0x%x to %u", 2943 cmd->vdev_id, cmd->param_id, cmd->param_value); 2944 wmi_mtrace(WMI_VDEV_SET_PARAM_CMDID, cmd->vdev_id, 0); 2945 ret = wmi_unified_cmd_send(wmi_handle, buf, len, WMI_VDEV_SET_PARAM_CMDID); 2946 if (QDF_IS_STATUS_ERROR(ret)) { 2947 wmi_buf_free(buf); 2948 } 2949 2950 return ret; 2951 } 2952 2953 /** 2954 * send_multi_param_cmd_using_vdev_param_tlv() - vdev set parameter function 2955 * @wmi_handle : handle to WMI. 2956 * @params: pointer to parameters to set 2957 * 2958 * Return: QDF_STATUS_SUCCESS on success, otherwise QDF_STATUS_E_* 2959 */ 2960 static QDF_STATUS 2961 send_multi_param_cmd_using_vdev_param_tlv(wmi_unified_t wmi_handle, 2962 struct set_multiple_pdev_vdev_param *params) 2963 { 2964 uint8_t index; 2965 struct vdev_set_params vdevparam; 2966 2967 for (index = 0; index < params->n_params; index++) { 2968 vdevparam.param_id = params->params[index].param_id; 2969 vdevparam.param_value = params->params[index].param_value; 2970 vdevparam.vdev_id = params->dev_id; 2971 if (QDF_IS_STATUS_ERROR(send_vdev_set_param_cmd_tlv(wmi_handle, &vdevparam))) { 2972 wmi_err("failed to send param:%d", vdevparam.param_id); 2973 return QDF_STATUS_E_FAILURE; 2974 } 2975 } 2976 return QDF_STATUS_SUCCESS; 2977 } 2978 2979 #ifdef WLAN_PDEV_VDEV_SEND_MULTI_PARAM 2980 /** 2981 * send_multiple_vdev_param_cmd_tlv() - WMI vdev set parameter function 2982 * @wmi_handle : handle to WMI. 2983 * @params: pointer to hold set_multiple_pdev_vdev_param info 2984 * 2985 * Return: QDF_STATUS_SUCCESS for success or error code 2986 */ 2987 static QDF_STATUS 2988 send_multiple_vdev_param_cmd_tlv(wmi_unified_t wmi_handle, 2989 struct set_multiple_pdev_vdev_param *params) 2990 { 2991 if (!wmi_service_enabled(wmi_handle, 2992 wmi_service_combined_set_param_support)) 2993 return send_multi_param_cmd_using_vdev_param_tlv(wmi_handle, 2994 params); 2995 return send_multi_pdev_vdev_set_param_cmd_tlv(wmi_handle, params); 2996 } 2997 2998 #else /* WLAN_PDEV_VDEV_SEND_MULTI_PARAM */ 2999 3000 /** 3001 * send_multiple_vdev_param_cmd_tlv() - WMI vdev set parameter function 3002 * @wmi_handle : handle to WMI. 3003 * @params: pointer to hold set_multiple_pdev_vdev_param info 3004 * 3005 * Return: QDF_STATUS_SUCCESS for success or error code 3006 */ 3007 static QDF_STATUS 3008 send_multiple_vdev_param_cmd_tlv(wmi_unified_t wmi_handle, 3009 struct set_multiple_pdev_vdev_param *params) 3010 { 3011 return send_multi_param_cmd_using_vdev_param_tlv(wmi_handle, params); 3012 } 3013 #endif /*end of WLAN_PDEV_VDEV_SEND_MULTI_PARAM */ 3014 3015 /** 3016 * send_vdev_set_mu_snif_cmd_tlv() - WMI vdev set mu snif function 3017 * @wmi_handle: handle to WMI. 3018 * @param: pointer to hold mu sniffer parameter 3019 * 3020 * Return: QDF_STATUS_SUCCESS for success or error code 3021 */ 3022 static 3023 QDF_STATUS send_vdev_set_mu_snif_cmd_tlv(wmi_unified_t wmi_handle, 3024 struct vdev_set_mu_snif_param *param) 3025 { 3026 QDF_STATUS ret; 3027 wmi_vdev_set_mu_snif_cmd_param *cmd; 3028 wmi_buf_t buf; 3029 uint32_t *tmp_ptr; 3030 uint16_t len = sizeof(*cmd); 3031 uint8_t *buf_ptr; 3032 uint32_t i; 3033 3034 /* Length TLV placeholder for array of uint32_t */ 3035 len += WMI_TLV_HDR_SIZE; 3036 3037 if (param->num_aid) 3038 len += param->num_aid * sizeof(uint32_t); 3039 3040 buf = wmi_buf_alloc(wmi_handle, len); 3041 if (!buf) 3042 return QDF_STATUS_E_NOMEM; 3043 3044 buf_ptr = (uint8_t *)wmi_buf_data(buf); 3045 cmd = (wmi_vdev_set_mu_snif_cmd_param *)buf_ptr; 3046 3047 WMITLV_SET_HDR(&cmd->tlv_header, 3048 WMITLV_TAG_STRUC_wmi_vdev_set_mu_snif_cmd_param, 3049 WMITLV_GET_STRUCT_TLVLEN 3050 (wmi_vdev_set_mu_snif_cmd_param)); 3051 3052 cmd->vdev_id = param->vdev_id; 3053 cmd->mode = param->mode; 3054 cmd->max_num_user = param->num_user; 3055 3056 buf_ptr += sizeof(*cmd); 3057 3058 tmp_ptr = (uint32_t *)(buf_ptr + WMI_TLV_HDR_SIZE); 3059 3060 for (i = 0; i < param->num_aid; ++i) 3061 tmp_ptr[i] = param->aid[i]; 3062 3063 WMITLV_SET_HDR(buf_ptr, 3064 WMITLV_TAG_ARRAY_UINT32, 3065 (param->num_aid * sizeof(uint32_t))); 3066 3067 wmi_debug("Setting vdev %d mode = %x, max user = %u aids= %u", 3068 cmd->vdev_id, cmd->mode, cmd->max_num_user, param->num_aid); 3069 wmi_mtrace(WMI_VDEV_SET_PARAM_CMDID, cmd->vdev_id, 0); 3070 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 3071 WMI_VDEV_SET_MU_SNIF_CMDID); 3072 if (QDF_IS_STATUS_ERROR(ret)) { 3073 wmi_err("Failed to send set param command ret = %d", ret); 3074 wmi_buf_free(buf); 3075 } 3076 3077 return ret; 3078 } 3079 3080 /** 3081 * send_peer_based_pktlog_cmd() - Send WMI command to enable packet-log 3082 * @wmi_handle: handle to WMI. 3083 * @macaddr: Peer mac address to be filter 3084 * @mac_id: mac id to have radio context 3085 * @enb_dsb: Enable MAC based filtering or Disable 3086 * 3087 * Return: QDF_STATUS 3088 */ 3089 static QDF_STATUS send_peer_based_pktlog_cmd(wmi_unified_t wmi_handle, 3090 uint8_t *macaddr, 3091 uint8_t mac_id, 3092 uint8_t enb_dsb) 3093 { 3094 int32_t ret; 3095 wmi_pdev_pktlog_filter_cmd_fixed_param *cmd; 3096 wmi_pdev_pktlog_filter_info *mac_info; 3097 wmi_buf_t buf; 3098 uint8_t *buf_ptr; 3099 uint16_t len = sizeof(wmi_pdev_pktlog_filter_cmd_fixed_param) + 3100 sizeof(wmi_pdev_pktlog_filter_info) + WMI_TLV_HDR_SIZE; 3101 3102 buf = wmi_buf_alloc(wmi_handle, len); 3103 if (!buf) 3104 return QDF_STATUS_E_NOMEM; 3105 3106 buf_ptr = (uint8_t *)wmi_buf_data(buf); 3107 cmd = (wmi_pdev_pktlog_filter_cmd_fixed_param *)buf_ptr; 3108 WMITLV_SET_HDR(&cmd->tlv_header, 3109 WMITLV_TAG_STRUC_wmi_pdev_pktlog_filter_cmd_fixed_param, 3110 WMITLV_GET_STRUCT_TLVLEN 3111 (wmi_pdev_pktlog_filter_cmd_fixed_param)); 3112 cmd->pdev_id = mac_id; 3113 cmd->enable = enb_dsb; 3114 cmd->num_of_mac_addresses = 1; 3115 wmi_mtrace(WMI_PDEV_PKTLOG_FILTER_CMDID, cmd->pdev_id, 0); 3116 3117 buf_ptr += sizeof(*cmd); 3118 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 3119 sizeof(wmi_pdev_pktlog_filter_info)); 3120 buf_ptr += WMI_TLV_HDR_SIZE; 3121 3122 mac_info = (wmi_pdev_pktlog_filter_info *)(buf_ptr); 3123 3124 WMITLV_SET_HDR(&mac_info->tlv_header, 3125 WMITLV_TAG_STRUC_wmi_pdev_pktlog_filter_info, 3126 WMITLV_GET_STRUCT_TLVLEN 3127 (wmi_pdev_pktlog_filter_info)); 3128 3129 WMI_CHAR_ARRAY_TO_MAC_ADDR(macaddr, &mac_info->peer_mac_address); 3130 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 3131 WMI_PDEV_PKTLOG_FILTER_CMDID); 3132 if (ret) { 3133 wmi_err("Failed to send peer based pktlog command to FW =%d" 3134 , ret); 3135 wmi_buf_free(buf); 3136 } 3137 3138 return ret; 3139 } 3140 3141 /** 3142 * send_packet_log_enable_cmd_tlv() - Send WMI command to enable packet-log 3143 * @wmi_handle: handle to WMI. 3144 * @PKTLOG_EVENT: packet log event 3145 * @mac_id: mac id to have radio context 3146 * 3147 * Return: QDF_STATUS_SUCCESS for success or error code 3148 */ 3149 static QDF_STATUS send_packet_log_enable_cmd_tlv(wmi_unified_t wmi_handle, 3150 WMI_HOST_PKTLOG_EVENT PKTLOG_EVENT, uint8_t mac_id) 3151 { 3152 int32_t ret, idx, max_idx; 3153 wmi_pdev_pktlog_enable_cmd_fixed_param *cmd; 3154 wmi_buf_t buf; 3155 uint16_t len = sizeof(wmi_pdev_pktlog_enable_cmd_fixed_param); 3156 3157 buf = wmi_buf_alloc(wmi_handle, len); 3158 if (!buf) 3159 return -QDF_STATUS_E_NOMEM; 3160 3161 cmd = (wmi_pdev_pktlog_enable_cmd_fixed_param *) wmi_buf_data(buf); 3162 WMITLV_SET_HDR(&cmd->tlv_header, 3163 WMITLV_TAG_STRUC_wmi_pdev_pktlog_enable_cmd_fixed_param, 3164 WMITLV_GET_STRUCT_TLVLEN 3165 (wmi_pdev_pktlog_enable_cmd_fixed_param)); 3166 max_idx = sizeof(pktlog_event_tlv) / (sizeof(pktlog_event_tlv[0])); 3167 cmd->evlist = 0; 3168 for (idx = 0; idx < max_idx; idx++) { 3169 if (PKTLOG_EVENT & (1 << idx)) 3170 cmd->evlist |= pktlog_event_tlv[idx]; 3171 } 3172 cmd->pdev_id = mac_id; 3173 wmi_mtrace(WMI_PDEV_PKTLOG_ENABLE_CMDID, cmd->pdev_id, 0); 3174 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 3175 WMI_PDEV_PKTLOG_ENABLE_CMDID); 3176 if (ret) { 3177 wmi_err("Failed to send pktlog enable cmd to FW =%d", ret); 3178 wmi_buf_free(buf); 3179 } 3180 3181 return ret; 3182 } 3183 3184 /** 3185 * send_packet_log_disable_cmd_tlv() - Send WMI command to disable packet-log 3186 * @wmi_handle: handle to WMI. 3187 * @mac_id: mac id to have radio context 3188 * 3189 * Return: QDF_STATUS_SUCCESS for success or error code 3190 */ 3191 static QDF_STATUS send_packet_log_disable_cmd_tlv(wmi_unified_t wmi_handle, 3192 uint8_t mac_id) 3193 { 3194 int32_t ret; 3195 wmi_pdev_pktlog_disable_cmd_fixed_param *cmd; 3196 wmi_buf_t buf; 3197 uint16_t len = sizeof(wmi_pdev_pktlog_disable_cmd_fixed_param); 3198 3199 buf = wmi_buf_alloc(wmi_handle, len); 3200 if (!buf) 3201 return -QDF_STATUS_E_NOMEM; 3202 3203 cmd = (wmi_pdev_pktlog_disable_cmd_fixed_param *) wmi_buf_data(buf); 3204 WMITLV_SET_HDR(&cmd->tlv_header, 3205 WMITLV_TAG_STRUC_wmi_pdev_pktlog_disable_cmd_fixed_param, 3206 WMITLV_GET_STRUCT_TLVLEN 3207 (wmi_pdev_pktlog_disable_cmd_fixed_param)); 3208 cmd->pdev_id = mac_id; 3209 wmi_mtrace(WMI_PDEV_PKTLOG_DISABLE_CMDID, cmd->pdev_id, 0); 3210 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 3211 WMI_PDEV_PKTLOG_DISABLE_CMDID); 3212 if (ret) { 3213 wmi_err("Failed to send pktlog disable cmd to FW =%d", ret); 3214 wmi_buf_free(buf); 3215 } 3216 3217 return ret; 3218 } 3219 3220 #define WMI_FW_TIME_STAMP_LOW_MASK 0xffffffff 3221 /** 3222 * send_time_stamp_sync_cmd_tlv() - Send WMI command to 3223 * sync time between between host and firmware 3224 * @wmi_handle: handle to WMI. 3225 * 3226 * Return: None 3227 */ 3228 static void send_time_stamp_sync_cmd_tlv(wmi_unified_t wmi_handle) 3229 { 3230 wmi_buf_t buf; 3231 QDF_STATUS status = QDF_STATUS_SUCCESS; 3232 WMI_DBGLOG_TIME_STAMP_SYNC_CMD_fixed_param *time_stamp; 3233 int32_t len; 3234 qdf_time_t time_ms; 3235 3236 len = sizeof(*time_stamp); 3237 buf = wmi_buf_alloc(wmi_handle, len); 3238 3239 if (!buf) 3240 return; 3241 3242 time_stamp = 3243 (WMI_DBGLOG_TIME_STAMP_SYNC_CMD_fixed_param *) 3244 (wmi_buf_data(buf)); 3245 WMITLV_SET_HDR(&time_stamp->tlv_header, 3246 WMITLV_TAG_STRUC_wmi_dbglog_time_stamp_sync_cmd_fixed_param, 3247 WMITLV_GET_STRUCT_TLVLEN( 3248 WMI_DBGLOG_TIME_STAMP_SYNC_CMD_fixed_param)); 3249 3250 time_ms = qdf_get_time_of_the_day_ms(); 3251 time_stamp->mode = WMI_TIME_STAMP_SYNC_MODE_MS; 3252 time_stamp->time_stamp_low = time_ms & 3253 WMI_FW_TIME_STAMP_LOW_MASK; 3254 /* 3255 * Send time_stamp_high 0 as the time converted from HR:MIN:SEC:MS to ms 3256 * won't exceed 27 bit 3257 */ 3258 time_stamp->time_stamp_high = 0; 3259 wmi_debug("WMA --> DBGLOG_TIME_STAMP_SYNC_CMDID mode %d time_stamp low %d high %d", 3260 time_stamp->mode, time_stamp->time_stamp_low, 3261 time_stamp->time_stamp_high); 3262 3263 wmi_mtrace(WMI_DBGLOG_TIME_STAMP_SYNC_CMDID, NO_SESSION, 0); 3264 status = wmi_unified_cmd_send(wmi_handle, buf, 3265 len, WMI_DBGLOG_TIME_STAMP_SYNC_CMDID); 3266 if (status) { 3267 wmi_err("Failed to send WMI_DBGLOG_TIME_STAMP_SYNC_CMDID command"); 3268 wmi_buf_free(buf); 3269 } 3270 3271 } 3272 3273 /** 3274 * send_fd_tmpl_cmd_tlv() - WMI FILS Discovery send function 3275 * @wmi_handle: handle to WMI. 3276 * @param: pointer to hold FILS Discovery send cmd parameter 3277 * 3278 * Return: QDF_STATUS_SUCCESS for success or error code 3279 */ 3280 static QDF_STATUS send_fd_tmpl_cmd_tlv(wmi_unified_t wmi_handle, 3281 struct fils_discovery_tmpl_params *param) 3282 { 3283 int32_t ret; 3284 wmi_fd_tmpl_cmd_fixed_param *cmd; 3285 wmi_buf_t wmi_buf; 3286 uint8_t *buf_ptr; 3287 uint32_t wmi_buf_len; 3288 3289 wmi_buf_len = sizeof(wmi_fd_tmpl_cmd_fixed_param) + 3290 WMI_TLV_HDR_SIZE + param->tmpl_len_aligned; 3291 wmi_buf = wmi_buf_alloc(wmi_handle, wmi_buf_len); 3292 if (!wmi_buf) 3293 return QDF_STATUS_E_NOMEM; 3294 3295 buf_ptr = (uint8_t *) wmi_buf_data(wmi_buf); 3296 cmd = (wmi_fd_tmpl_cmd_fixed_param *) buf_ptr; 3297 WMITLV_SET_HDR(&cmd->tlv_header, 3298 WMITLV_TAG_STRUC_wmi_fd_tmpl_cmd_fixed_param, 3299 WMITLV_GET_STRUCT_TLVLEN(wmi_fd_tmpl_cmd_fixed_param)); 3300 cmd->vdev_id = param->vdev_id; 3301 cmd->buf_len = param->tmpl_len; 3302 buf_ptr += sizeof(wmi_fd_tmpl_cmd_fixed_param); 3303 3304 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, param->tmpl_len_aligned); 3305 buf_ptr += WMI_TLV_HDR_SIZE; 3306 qdf_mem_copy(buf_ptr, param->frm, param->tmpl_len); 3307 3308 wmi_mtrace(WMI_FD_TMPL_CMDID, cmd->vdev_id, 0); 3309 ret = wmi_unified_cmd_send(wmi_handle, 3310 wmi_buf, wmi_buf_len, WMI_FD_TMPL_CMDID); 3311 3312 if (ret) { 3313 wmi_err("Failed to send fd tmpl: %d", ret); 3314 wmi_buf_free(wmi_buf); 3315 return ret; 3316 } 3317 3318 return 0; 3319 } 3320 3321 /** 3322 * send_beacon_tmpl_send_cmd_tlv() - WMI beacon send function 3323 * @wmi_handle: handle to WMI. 3324 * @param: pointer to hold beacon send cmd parameter 3325 * 3326 * Return: QDF_STATUS_SUCCESS for success or error code 3327 */ 3328 static QDF_STATUS send_beacon_tmpl_send_cmd_tlv(wmi_unified_t wmi_handle, 3329 struct beacon_tmpl_params *param) 3330 { 3331 int32_t ret; 3332 wmi_bcn_tmpl_cmd_fixed_param *cmd; 3333 wmi_bcn_prb_info *bcn_prb_info; 3334 wmi_buf_t wmi_buf; 3335 uint8_t *buf_ptr; 3336 uint32_t wmi_buf_len; 3337 3338 wmi_buf_len = sizeof(wmi_bcn_tmpl_cmd_fixed_param) + 3339 sizeof(wmi_bcn_prb_info) + WMI_TLV_HDR_SIZE + 3340 param->tmpl_len_aligned + 3341 bcn_tmpl_mlo_param_size(param) + 3342 bcn_tmpl_ml_info_size(param); 3343 3344 wmi_buf = wmi_buf_alloc(wmi_handle, wmi_buf_len); 3345 if (!wmi_buf) 3346 return QDF_STATUS_E_NOMEM; 3347 3348 buf_ptr = (uint8_t *) wmi_buf_data(wmi_buf); 3349 cmd = (wmi_bcn_tmpl_cmd_fixed_param *) buf_ptr; 3350 WMITLV_SET_HDR(&cmd->tlv_header, 3351 WMITLV_TAG_STRUC_wmi_bcn_tmpl_cmd_fixed_param, 3352 WMITLV_GET_STRUCT_TLVLEN(wmi_bcn_tmpl_cmd_fixed_param)); 3353 cmd->vdev_id = param->vdev_id; 3354 cmd->tim_ie_offset = param->tim_ie_offset; 3355 cmd->mbssid_ie_offset = param->mbssid_ie_offset; 3356 cmd->csa_switch_count_offset = param->csa_switch_count_offset; 3357 cmd->ext_csa_switch_count_offset = param->ext_csa_switch_count_offset; 3358 cmd->esp_ie_offset = param->esp_ie_offset; 3359 cmd->mu_edca_ie_offset = param->mu_edca_ie_offset; 3360 cmd->ema_params = param->ema_params; 3361 cmd->buf_len = param->tmpl_len; 3362 cmd->csa_event_bitmap = param->csa_event_bitmap; 3363 3364 WMI_BEACON_PROTECTION_EN_SET(cmd->feature_enable_bitmap, 3365 param->enable_bigtk); 3366 buf_ptr += sizeof(wmi_bcn_tmpl_cmd_fixed_param); 3367 3368 bcn_prb_info = (wmi_bcn_prb_info *) buf_ptr; 3369 WMITLV_SET_HDR(&bcn_prb_info->tlv_header, 3370 WMITLV_TAG_STRUC_wmi_bcn_prb_info, 3371 WMITLV_GET_STRUCT_TLVLEN(wmi_bcn_prb_info)); 3372 bcn_prb_info->caps = 0; 3373 bcn_prb_info->erp = 0; 3374 buf_ptr += sizeof(wmi_bcn_prb_info); 3375 3376 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, param->tmpl_len_aligned); 3377 buf_ptr += WMI_TLV_HDR_SIZE; 3378 3379 /* for big endian host, copy engine byte_swap is enabled 3380 * But the frame content is in network byte order 3381 * Need to byte swap the frame content - so when copy engine 3382 * does byte_swap - target gets frame content in the correct order 3383 */ 3384 WMI_HOST_IF_MSG_COPY_CHAR_ARRAY(buf_ptr, param->frm, 3385 param->tmpl_len); 3386 3387 buf_ptr += roundup(param->tmpl_len, sizeof(uint32_t)); 3388 buf_ptr = bcn_tmpl_add_ml_partner_links(buf_ptr, param); 3389 3390 buf_ptr = bcn_tmpl_add_ml_info(buf_ptr, param); 3391 3392 wmi_mtrace(WMI_BCN_TMPL_CMDID, cmd->vdev_id, 0); 3393 ret = wmi_unified_cmd_send(wmi_handle, 3394 wmi_buf, wmi_buf_len, WMI_BCN_TMPL_CMDID); 3395 if (ret) { 3396 wmi_err("Failed to send bcn tmpl: %d", ret); 3397 wmi_buf_free(wmi_buf); 3398 } 3399 3400 return 0; 3401 } 3402 3403 #ifdef WLAN_FEATURE_11BE 3404 static inline void copy_peer_flags_tlv_11be( 3405 wmi_peer_assoc_complete_cmd_fixed_param * cmd, 3406 struct peer_assoc_params *param) 3407 { 3408 if (param->bw_320) 3409 cmd->peer_flags_ext |= WMI_PEER_EXT_320MHZ; 3410 if (param->eht_flag) 3411 cmd->peer_flags_ext |= WMI_PEER_EXT_EHT; 3412 3413 wmi_debug("peer_flags_ext 0x%x", cmd->peer_flags_ext); 3414 } 3415 #else 3416 static inline void copy_peer_flags_tlv_11be( 3417 wmi_peer_assoc_complete_cmd_fixed_param * cmd, 3418 struct peer_assoc_params *param) 3419 { 3420 } 3421 #endif 3422 #ifdef WLAN_FEATURE_11BE_MLO 3423 static inline void copy_peer_flags_tlv_vendor( 3424 wmi_peer_assoc_complete_cmd_fixed_param * cmd, 3425 struct peer_assoc_params *param) 3426 { 3427 if (!(param->mlo_params.mlo_enabled)) 3428 return; 3429 if (param->qcn_node_flag) 3430 cmd->peer_flags_ext |= WMI_PEER_EXT_IS_QUALCOMM_NODE; 3431 if (param->mesh_node_flag) 3432 cmd->peer_flags_ext |= WMI_PEER_EXT_IS_MESH_NODE; 3433 3434 wmi_debug("peer_flags_ext 0x%x", cmd->peer_flags_ext); 3435 } 3436 #else 3437 static inline void copy_peer_flags_tlv_vendor( 3438 wmi_peer_assoc_complete_cmd_fixed_param * cmd, 3439 struct peer_assoc_params *param) 3440 { 3441 } 3442 #endif 3443 3444 static inline void copy_peer_flags_tlv( 3445 wmi_peer_assoc_complete_cmd_fixed_param * cmd, 3446 struct peer_assoc_params *param) 3447 { 3448 /* 3449 * The target only needs a subset of the flags maintained in the host. 3450 * Just populate those flags and send it down 3451 */ 3452 cmd->peer_flags = 0; 3453 if (param->peer_dms_capable) 3454 cmd->peer_flags_ext |= WMI_PEER_EXT_DMS_CAPABLE; 3455 /* 3456 * Do not enable HT/VHT if WMM/wme is disabled for vap. 3457 */ 3458 if (param->is_wme_set) { 3459 3460 if (param->qos_flag) 3461 cmd->peer_flags |= WMI_PEER_QOS; 3462 if (param->apsd_flag) 3463 cmd->peer_flags |= WMI_PEER_APSD; 3464 if (param->ht_flag) 3465 cmd->peer_flags |= WMI_PEER_HT; 3466 if (param->bw_40) 3467 cmd->peer_flags |= WMI_PEER_40MHZ; 3468 if (param->bw_80) 3469 cmd->peer_flags |= WMI_PEER_80MHZ; 3470 if (param->bw_160) 3471 cmd->peer_flags |= WMI_PEER_160MHZ; 3472 3473 copy_peer_flags_tlv_11be(cmd, param); 3474 copy_peer_flags_tlv_vendor(cmd, param); 3475 3476 /* Typically if STBC is enabled for VHT it should be enabled 3477 * for HT as well 3478 **/ 3479 if (param->stbc_flag) 3480 cmd->peer_flags |= WMI_PEER_STBC; 3481 3482 /* Typically if LDPC is enabled for VHT it should be enabled 3483 * for HT as well 3484 **/ 3485 if (param->ldpc_flag) 3486 cmd->peer_flags |= WMI_PEER_LDPC; 3487 3488 if (param->static_mimops_flag) 3489 cmd->peer_flags |= WMI_PEER_STATIC_MIMOPS; 3490 if (param->dynamic_mimops_flag) 3491 cmd->peer_flags |= WMI_PEER_DYN_MIMOPS; 3492 if (param->spatial_mux_flag) 3493 cmd->peer_flags |= WMI_PEER_SPATIAL_MUX; 3494 if (param->vht_flag) 3495 cmd->peer_flags |= WMI_PEER_VHT; 3496 if (param->he_flag) 3497 cmd->peer_flags |= WMI_PEER_HE; 3498 if (param->p2p_capable_sta) 3499 cmd->peer_flags |= WMI_PEER_IS_P2P_CAPABLE; 3500 } 3501 3502 if (param->is_pmf_enabled) 3503 cmd->peer_flags |= WMI_PEER_PMF; 3504 /* 3505 * Suppress authorization for all AUTH modes that need 4-way handshake 3506 * (during re-association). 3507 * Authorization will be done for these modes on key installation. 3508 */ 3509 if (param->auth_flag) 3510 cmd->peer_flags |= WMI_PEER_AUTH; 3511 if (param->need_ptk_4_way) 3512 cmd->peer_flags |= WMI_PEER_NEED_PTK_4_WAY; 3513 else 3514 cmd->peer_flags &= ~WMI_PEER_NEED_PTK_4_WAY; 3515 if (param->need_gtk_2_way) 3516 cmd->peer_flags |= WMI_PEER_NEED_GTK_2_WAY; 3517 /* safe mode bypass the 4-way handshake */ 3518 if (param->safe_mode_enabled) 3519 cmd->peer_flags &= 3520 ~(WMI_PEER_NEED_PTK_4_WAY | WMI_PEER_NEED_GTK_2_WAY); 3521 /* inter BSS peer */ 3522 if (param->inter_bss_peer) 3523 cmd->peer_flags |= WMI_PEER_INTER_BSS_PEER; 3524 /* Disable AMSDU for station transmit, if user configures it */ 3525 /* Disable AMSDU for AP transmit to 11n Stations, if user configures 3526 * it 3527 * if (param->amsdu_disable) Add after FW support 3528 **/ 3529 3530 /* Target asserts if node is marked HT and all MCS is set to 0. 3531 * Mark the node as non-HT if all the mcs rates are disabled through 3532 * iwpriv 3533 **/ 3534 if (param->peer_ht_rates.num_rates == 0) 3535 cmd->peer_flags &= ~WMI_PEER_HT; 3536 3537 if (param->twt_requester) 3538 cmd->peer_flags |= WMI_PEER_TWT_REQ; 3539 3540 if (param->twt_responder) 3541 cmd->peer_flags |= WMI_PEER_TWT_RESP; 3542 } 3543 3544 static inline void copy_peer_mac_addr_tlv( 3545 wmi_peer_assoc_complete_cmd_fixed_param * cmd, 3546 struct peer_assoc_params *param) 3547 { 3548 WMI_CHAR_ARRAY_TO_MAC_ADDR(param->peer_mac, &cmd->peer_macaddr); 3549 } 3550 3551 #ifdef WLAN_FEATURE_11BE 3552 static uint8_t *update_peer_flags_tlv_ehtinfo( 3553 wmi_peer_assoc_complete_cmd_fixed_param * cmd, 3554 struct peer_assoc_params *param, uint8_t *buf_ptr) 3555 { 3556 wmi_eht_rate_set *eht_mcs; 3557 int i; 3558 3559 cmd->peer_eht_ops = param->peer_eht_ops; 3560 cmd->puncture_20mhz_bitmap = ~param->puncture_bitmap; 3561 3562 qdf_mem_copy(&cmd->peer_eht_cap_mac, ¶m->peer_eht_cap_macinfo, 3563 sizeof(param->peer_eht_cap_macinfo)); 3564 qdf_mem_copy(&cmd->peer_eht_cap_phy, ¶m->peer_eht_cap_phyinfo, 3565 sizeof(param->peer_eht_cap_phyinfo)); 3566 qdf_mem_copy(&cmd->peer_eht_ppet, ¶m->peer_eht_ppet, 3567 sizeof(param->peer_eht_ppet)); 3568 3569 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 3570 (param->peer_eht_mcs_count * sizeof(wmi_eht_rate_set))); 3571 buf_ptr += WMI_TLV_HDR_SIZE; 3572 3573 /* Loop through the EHT rate set */ 3574 for (i = 0; i < param->peer_eht_mcs_count; i++) { 3575 eht_mcs = (wmi_eht_rate_set *)buf_ptr; 3576 WMITLV_SET_HDR(eht_mcs, WMITLV_TAG_STRUC_wmi_eht_rate_set, 3577 WMITLV_GET_STRUCT_TLVLEN(wmi_eht_rate_set)); 3578 3579 eht_mcs->rx_mcs_set = param->peer_eht_rx_mcs_set[i]; 3580 eht_mcs->tx_mcs_set = param->peer_eht_tx_mcs_set[i]; 3581 wmi_debug("EHT idx %d RxMCSmap %x TxMCSmap %x ", 3582 i, eht_mcs->rx_mcs_set, eht_mcs->tx_mcs_set); 3583 buf_ptr += sizeof(wmi_eht_rate_set); 3584 } 3585 3586 wmi_debug("nss %d ru mask 0x%x", 3587 cmd->peer_eht_ppet.numss_m1, cmd->peer_eht_ppet.ru_mask); 3588 for (i = 0; i < WMI_MAX_NUM_SS; i++) { 3589 wmi_debug("ppet idx %d ppet %x ", 3590 i, cmd->peer_eht_ppet.ppet16_ppet8_ru3_ru0[i]); 3591 } 3592 3593 if ((param->eht_flag) && (param->peer_eht_mcs_count > 1) && 3594 (param->peer_eht_rx_mcs_set[WMI_HOST_EHT_TXRX_MCS_NSS_IDX_160] 3595 == WMI_HOST_EHT_INVALID_MCSNSSMAP || 3596 param->peer_eht_tx_mcs_set[WMI_HOST_EHT_TXRX_MCS_NSS_IDX_160] 3597 == WMI_HOST_HE_INVALID_MCSNSSMAP)) { 3598 wmi_debug("param->peer_eht_tx_mcs_set[160MHz]=%x", 3599 param->peer_eht_tx_mcs_set 3600 [WMI_HOST_HE_TXRX_MCS_NSS_IDX_160]); 3601 wmi_debug("param->peer_eht_rx_mcs_set[160MHz]=%x", 3602 param->peer_eht_rx_mcs_set 3603 [WMI_HOST_HE_TXRX_MCS_NSS_IDX_160]); 3604 wmi_debug("peer_mac="QDF_MAC_ADDR_FMT, 3605 QDF_MAC_ADDR_REF(param->peer_mac)); 3606 } 3607 3608 wmi_debug("EHT cap_mac %x %x ehtops %x EHT phy %x %x %x pp %x", 3609 cmd->peer_eht_cap_mac[0], 3610 cmd->peer_eht_cap_mac[1], cmd->peer_eht_ops, 3611 cmd->peer_eht_cap_phy[0], cmd->peer_eht_cap_phy[1], 3612 cmd->peer_eht_cap_phy[2], cmd->puncture_20mhz_bitmap); 3613 3614 return buf_ptr; 3615 } 3616 #else 3617 static uint8_t *update_peer_flags_tlv_ehtinfo( 3618 wmi_peer_assoc_complete_cmd_fixed_param * cmd, 3619 struct peer_assoc_params *param, uint8_t *buf_ptr) 3620 { 3621 return buf_ptr; 3622 } 3623 #endif 3624 3625 #ifdef WLAN_FEATURE_11BE 3626 static 3627 uint32_t wmi_eht_peer_assoc_params_len(struct peer_assoc_params *param) 3628 { 3629 return (sizeof(wmi_he_rate_set) * param->peer_eht_mcs_count 3630 + WMI_TLV_HDR_SIZE); 3631 } 3632 3633 static void wmi_populate_service_11be(uint32_t *wmi_service) 3634 { 3635 wmi_service[wmi_service_11be] = WMI_SERVICE_11BE; 3636 } 3637 3638 #else 3639 static 3640 uint32_t wmi_eht_peer_assoc_params_len(struct peer_assoc_params *param) 3641 { 3642 return 0; 3643 } 3644 3645 static void wmi_populate_service_11be(uint32_t *wmi_service) 3646 { 3647 } 3648 3649 #endif 3650 3651 /** 3652 * send_peer_assoc_cmd_tlv() - WMI peer assoc function 3653 * @wmi_handle: handle to WMI. 3654 * @param: pointer to peer assoc parameter 3655 * 3656 * Return: QDF_STATUS_SUCCESS for success or error code 3657 */ 3658 static QDF_STATUS send_peer_assoc_cmd_tlv(wmi_unified_t wmi_handle, 3659 struct peer_assoc_params *param) 3660 { 3661 wmi_peer_assoc_complete_cmd_fixed_param *cmd; 3662 wmi_vht_rate_set *mcs; 3663 wmi_he_rate_set *he_mcs; 3664 wmi_buf_t buf; 3665 int32_t len; 3666 uint8_t *buf_ptr; 3667 QDF_STATUS ret; 3668 uint32_t peer_legacy_rates_align; 3669 uint32_t peer_ht_rates_align; 3670 int32_t i; 3671 3672 3673 peer_legacy_rates_align = wmi_align(param->peer_legacy_rates.num_rates); 3674 peer_ht_rates_align = wmi_align(param->peer_ht_rates.num_rates); 3675 3676 len = sizeof(*cmd) + WMI_TLV_HDR_SIZE + 3677 (peer_legacy_rates_align * sizeof(uint8_t)) + 3678 WMI_TLV_HDR_SIZE + 3679 (peer_ht_rates_align * sizeof(uint8_t)) + 3680 sizeof(wmi_vht_rate_set) + 3681 (sizeof(wmi_he_rate_set) * param->peer_he_mcs_count 3682 + WMI_TLV_HDR_SIZE) 3683 + wmi_eht_peer_assoc_params_len(param) + 3684 peer_assoc_mlo_params_size(param) + 3685 peer_assoc_t2lm_params_size(param); 3686 3687 buf = wmi_buf_alloc(wmi_handle, len); 3688 if (!buf) 3689 return QDF_STATUS_E_NOMEM; 3690 3691 buf_ptr = (uint8_t *) wmi_buf_data(buf); 3692 cmd = (wmi_peer_assoc_complete_cmd_fixed_param *) buf_ptr; 3693 WMITLV_SET_HDR(&cmd->tlv_header, 3694 WMITLV_TAG_STRUC_wmi_peer_assoc_complete_cmd_fixed_param, 3695 WMITLV_GET_STRUCT_TLVLEN 3696 (wmi_peer_assoc_complete_cmd_fixed_param)); 3697 3698 cmd->vdev_id = param->vdev_id; 3699 3700 cmd->peer_new_assoc = param->peer_new_assoc; 3701 cmd->peer_associd = param->peer_associd; 3702 3703 copy_peer_flags_tlv(cmd, param); 3704 copy_peer_mac_addr_tlv(cmd, param); 3705 3706 cmd->peer_rate_caps = param->peer_rate_caps; 3707 cmd->peer_caps = param->peer_caps; 3708 cmd->peer_listen_intval = param->peer_listen_intval; 3709 cmd->peer_ht_caps = param->peer_ht_caps; 3710 cmd->peer_max_mpdu = param->peer_max_mpdu; 3711 cmd->peer_mpdu_density = param->peer_mpdu_density; 3712 cmd->peer_vht_caps = param->peer_vht_caps; 3713 cmd->peer_phymode = param->peer_phymode; 3714 cmd->bss_max_idle_option = param->peer_bss_max_idle_option; 3715 3716 /* Update 11ax capabilities */ 3717 cmd->peer_he_cap_info = 3718 param->peer_he_cap_macinfo[WMI_HOST_HECAP_MAC_WORD1]; 3719 cmd->peer_he_cap_info_ext = 3720 param->peer_he_cap_macinfo[WMI_HOST_HECAP_MAC_WORD2]; 3721 cmd->peer_he_cap_info_internal = param->peer_he_cap_info_internal; 3722 cmd->peer_he_ops = param->peer_he_ops; 3723 qdf_mem_copy(&cmd->peer_he_cap_phy, ¶m->peer_he_cap_phyinfo, 3724 sizeof(param->peer_he_cap_phyinfo)); 3725 qdf_mem_copy(&cmd->peer_ppet, ¶m->peer_ppet, 3726 sizeof(param->peer_ppet)); 3727 cmd->peer_he_caps_6ghz = param->peer_he_caps_6ghz; 3728 3729 /* Update peer legacy rate information */ 3730 buf_ptr += sizeof(*cmd); 3731 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, 3732 peer_legacy_rates_align); 3733 buf_ptr += WMI_TLV_HDR_SIZE; 3734 cmd->num_peer_legacy_rates = param->peer_legacy_rates.num_rates; 3735 qdf_mem_copy(buf_ptr, param->peer_legacy_rates.rates, 3736 param->peer_legacy_rates.num_rates); 3737 3738 /* Update peer HT rate information */ 3739 buf_ptr += peer_legacy_rates_align; 3740 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, 3741 peer_ht_rates_align); 3742 buf_ptr += WMI_TLV_HDR_SIZE; 3743 cmd->num_peer_ht_rates = param->peer_ht_rates.num_rates; 3744 qdf_mem_copy(buf_ptr, param->peer_ht_rates.rates, 3745 param->peer_ht_rates.num_rates); 3746 3747 /* VHT Rates */ 3748 buf_ptr += peer_ht_rates_align; 3749 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_STRUC_wmi_vht_rate_set, 3750 WMITLV_GET_STRUCT_TLVLEN(wmi_vht_rate_set)); 3751 3752 cmd->auth_mode = param->akm; 3753 cmd->peer_nss = param->peer_nss; 3754 3755 /* Update bandwidth-NSS mapping */ 3756 cmd->peer_bw_rxnss_override = 0; 3757 cmd->peer_bw_rxnss_override |= param->peer_bw_rxnss_override; 3758 3759 mcs = (wmi_vht_rate_set *) buf_ptr; 3760 if (param->vht_capable) { 3761 mcs->rx_max_rate = param->rx_max_rate; 3762 mcs->rx_mcs_set = param->rx_mcs_set; 3763 mcs->tx_max_rate = param->tx_max_rate; 3764 mcs->tx_mcs_set = param->tx_mcs_set; 3765 mcs->tx_max_mcs_nss = param->tx_max_mcs_nss; 3766 } 3767 3768 /* HE Rates */ 3769 cmd->min_data_rate = param->min_data_rate; 3770 cmd->peer_he_mcs = param->peer_he_mcs_count; 3771 buf_ptr += sizeof(wmi_vht_rate_set); 3772 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 3773 (param->peer_he_mcs_count * sizeof(wmi_he_rate_set))); 3774 buf_ptr += WMI_TLV_HDR_SIZE; 3775 3776 WMI_PEER_STA_TYPE_SET(cmd->sta_type, param->peer_bsscolor_rept_info); 3777 /* Loop through the HE rate set */ 3778 for (i = 0; i < param->peer_he_mcs_count; i++) { 3779 he_mcs = (wmi_he_rate_set *) buf_ptr; 3780 WMITLV_SET_HDR(he_mcs, WMITLV_TAG_STRUC_wmi_he_rate_set, 3781 WMITLV_GET_STRUCT_TLVLEN(wmi_he_rate_set)); 3782 3783 he_mcs->rx_mcs_set = param->peer_he_rx_mcs_set[i]; 3784 he_mcs->tx_mcs_set = param->peer_he_tx_mcs_set[i]; 3785 wmi_debug("HE idx %d RxMCSmap %x TxMCSmap %x ", 3786 i, he_mcs->rx_mcs_set, he_mcs->tx_mcs_set); 3787 buf_ptr += sizeof(wmi_he_rate_set); 3788 } 3789 3790 if ((param->he_flag) && (param->peer_he_mcs_count > 1) && 3791 (param->peer_he_rx_mcs_set[WMI_HOST_HE_TXRX_MCS_NSS_IDX_160] 3792 == WMI_HOST_HE_INVALID_MCSNSSMAP || 3793 param->peer_he_tx_mcs_set[WMI_HOST_HE_TXRX_MCS_NSS_IDX_160] 3794 == WMI_HOST_HE_INVALID_MCSNSSMAP)) { 3795 wmi_debug("param->peer_he_tx_mcs_set[160MHz]=%x", 3796 param->peer_he_tx_mcs_set[WMI_HOST_HE_TXRX_MCS_NSS_IDX_160]); 3797 wmi_debug("param->peer_he_rx_mcs_set[160MHz]=%x", 3798 param->peer_he_rx_mcs_set[WMI_HOST_HE_TXRX_MCS_NSS_IDX_160]); 3799 wmi_debug("peer_mac="QDF_MAC_ADDR_FMT, 3800 QDF_MAC_ADDR_REF(param->peer_mac)); 3801 } 3802 3803 wmi_debug("vdev_id %d associd %d peer_flags %x rate_caps %x " 3804 "peer_caps %x listen_intval %d ht_caps %x max_mpdu %d " 3805 "nss %d phymode %d peer_mpdu_density %d " 3806 "cmd->peer_vht_caps %x " 3807 "HE cap_info %x ops %x " 3808 "HE cap_info_ext %x " 3809 "HE phy %x %x %x " 3810 "peer_bw_rxnss_override %x", 3811 cmd->vdev_id, cmd->peer_associd, cmd->peer_flags, 3812 cmd->peer_rate_caps, cmd->peer_caps, 3813 cmd->peer_listen_intval, cmd->peer_ht_caps, 3814 cmd->peer_max_mpdu, cmd->peer_nss, cmd->peer_phymode, 3815 cmd->peer_mpdu_density, 3816 cmd->peer_vht_caps, cmd->peer_he_cap_info, 3817 cmd->peer_he_ops, cmd->peer_he_cap_info_ext, 3818 cmd->peer_he_cap_phy[0], cmd->peer_he_cap_phy[1], 3819 cmd->peer_he_cap_phy[2], 3820 cmd->peer_bw_rxnss_override); 3821 3822 buf_ptr = peer_assoc_add_mlo_params(buf_ptr, param); 3823 3824 buf_ptr = update_peer_flags_tlv_ehtinfo(cmd, param, buf_ptr); 3825 3826 buf_ptr = peer_assoc_add_ml_partner_links(buf_ptr, param); 3827 3828 buf_ptr = peer_assoc_add_tid_to_link_map(buf_ptr, param); 3829 3830 wmi_mtrace(WMI_PEER_ASSOC_CMDID, cmd->vdev_id, 0); 3831 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 3832 WMI_PEER_ASSOC_CMDID); 3833 if (QDF_IS_STATUS_ERROR(ret)) { 3834 wmi_err("Failed to send peer assoc command ret = %d", ret); 3835 wmi_buf_free(buf); 3836 } 3837 3838 return ret; 3839 } 3840 3841 /* copy_scan_notify_events() - Helper routine to copy scan notify events 3842 */ 3843 static inline void copy_scan_event_cntrl_flags( 3844 wmi_start_scan_cmd_fixed_param * cmd, 3845 struct scan_req_params *param) 3846 { 3847 3848 /* Scan events subscription */ 3849 if (param->scan_ev_started) 3850 cmd->notify_scan_events |= WMI_SCAN_EVENT_STARTED; 3851 if (param->scan_ev_completed) 3852 cmd->notify_scan_events |= WMI_SCAN_EVENT_COMPLETED; 3853 if (param->scan_ev_bss_chan) 3854 cmd->notify_scan_events |= WMI_SCAN_EVENT_BSS_CHANNEL; 3855 if (param->scan_ev_foreign_chan) 3856 cmd->notify_scan_events |= WMI_SCAN_EVENT_FOREIGN_CHANNEL; 3857 if (param->scan_ev_dequeued) 3858 cmd->notify_scan_events |= WMI_SCAN_EVENT_DEQUEUED; 3859 if (param->scan_ev_preempted) 3860 cmd->notify_scan_events |= WMI_SCAN_EVENT_PREEMPTED; 3861 if (param->scan_ev_start_failed) 3862 cmd->notify_scan_events |= WMI_SCAN_EVENT_START_FAILED; 3863 if (param->scan_ev_restarted) 3864 cmd->notify_scan_events |= WMI_SCAN_EVENT_RESTARTED; 3865 if (param->scan_ev_foreign_chn_exit) 3866 cmd->notify_scan_events |= WMI_SCAN_EVENT_FOREIGN_CHANNEL_EXIT; 3867 if (param->scan_ev_suspended) 3868 cmd->notify_scan_events |= WMI_SCAN_EVENT_SUSPENDED; 3869 if (param->scan_ev_resumed) 3870 cmd->notify_scan_events |= WMI_SCAN_EVENT_RESUMED; 3871 3872 /** Set scan control flags */ 3873 cmd->scan_ctrl_flags = 0; 3874 if (param->scan_f_passive) 3875 cmd->scan_ctrl_flags |= WMI_SCAN_FLAG_PASSIVE; 3876 if (param->scan_f_strict_passive_pch) 3877 cmd->scan_ctrl_flags |= WMI_SCAN_FLAG_STRICT_PASSIVE_ON_PCHN; 3878 if (param->scan_f_promisc_mode) 3879 cmd->scan_ctrl_flags |= WMI_SCAN_FILTER_PROMISCOUS; 3880 if (param->scan_f_capture_phy_err) 3881 cmd->scan_ctrl_flags |= WMI_SCAN_CAPTURE_PHY_ERROR; 3882 if (param->scan_f_half_rate) 3883 cmd->scan_ctrl_flags |= WMI_SCAN_FLAG_HALF_RATE_SUPPORT; 3884 if (param->scan_f_quarter_rate) 3885 cmd->scan_ctrl_flags |= WMI_SCAN_FLAG_QUARTER_RATE_SUPPORT; 3886 if (param->scan_f_cck_rates) 3887 cmd->scan_ctrl_flags |= WMI_SCAN_ADD_CCK_RATES; 3888 if (param->scan_f_ofdm_rates) 3889 cmd->scan_ctrl_flags |= WMI_SCAN_ADD_OFDM_RATES; 3890 if (param->scan_f_chan_stat_evnt) 3891 cmd->scan_ctrl_flags |= WMI_SCAN_CHAN_STAT_EVENT; 3892 if (param->scan_f_filter_prb_req) 3893 cmd->scan_ctrl_flags |= WMI_SCAN_FILTER_PROBE_REQ; 3894 if (param->scan_f_bcast_probe) 3895 cmd->scan_ctrl_flags |= WMI_SCAN_ADD_BCAST_PROBE_REQ; 3896 if (param->scan_f_offchan_mgmt_tx) 3897 cmd->scan_ctrl_flags |= WMI_SCAN_OFFCHAN_MGMT_TX; 3898 if (param->scan_f_offchan_data_tx) 3899 cmd->scan_ctrl_flags |= WMI_SCAN_OFFCHAN_DATA_TX; 3900 if (param->scan_f_force_active_dfs_chn) 3901 cmd->scan_ctrl_flags |= WMI_SCAN_FLAG_FORCE_ACTIVE_ON_DFS; 3902 if (param->scan_f_add_tpc_ie_in_probe) 3903 cmd->scan_ctrl_flags |= WMI_SCAN_ADD_TPC_IE_IN_PROBE_REQ; 3904 if (param->scan_f_add_ds_ie_in_probe) 3905 cmd->scan_ctrl_flags |= WMI_SCAN_ADD_DS_IE_IN_PROBE_REQ; 3906 if (param->scan_f_add_spoofed_mac_in_probe) 3907 cmd->scan_ctrl_flags |= WMI_SCAN_ADD_SPOOFED_MAC_IN_PROBE_REQ; 3908 if (param->scan_f_add_rand_seq_in_probe) 3909 cmd->scan_ctrl_flags |= WMI_SCAN_RANDOM_SEQ_NO_IN_PROBE_REQ; 3910 if (param->scan_f_en_ie_allowlist_in_probe) 3911 cmd->scan_ctrl_flags |= 3912 WMI_SCAN_ENABLE_IE_WHTELIST_IN_PROBE_REQ; 3913 if (param->scan_f_pause_home_channel) 3914 cmd->scan_ctrl_flags |= 3915 WMI_SCAN_FLAG_PAUSE_HOME_CHANNEL; 3916 if (param->scan_f_report_cca_busy_for_each_20mhz) 3917 cmd->scan_ctrl_flags |= 3918 WMI_SCAN_FLAG_REPORT_CCA_BUSY_FOREACH_20MHZ; 3919 3920 /* for adaptive scan mode using 3 bits (21 - 23 bits) */ 3921 WMI_SCAN_SET_DWELL_MODE(cmd->scan_ctrl_flags, 3922 param->adaptive_dwell_time_mode); 3923 } 3924 3925 /* scan_copy_ie_buffer() - Copy scan ie_data */ 3926 static inline void scan_copy_ie_buffer(uint8_t *buf_ptr, 3927 struct scan_req_params *params) 3928 { 3929 qdf_mem_copy(buf_ptr, params->extraie.ptr, params->extraie.len); 3930 } 3931 3932 /** 3933 * wmi_copy_scan_random_mac() - To copy scan randomization attrs to wmi buffer 3934 * @mac: random mac addr 3935 * @mask: random mac mask 3936 * @mac_addr: wmi random mac 3937 * @mac_mask: wmi random mac mask 3938 * 3939 * Return None. 3940 */ 3941 static inline 3942 void wmi_copy_scan_random_mac(uint8_t *mac, uint8_t *mask, 3943 wmi_mac_addr *mac_addr, wmi_mac_addr *mac_mask) 3944 { 3945 WMI_CHAR_ARRAY_TO_MAC_ADDR(mac, mac_addr); 3946 WMI_CHAR_ARRAY_TO_MAC_ADDR(mask, mac_mask); 3947 } 3948 3949 /* 3950 * wmi_fill_vendor_oui() - fill vendor OUIs 3951 * @buf_ptr: pointer to wmi tlv buffer 3952 * @num_vendor_oui: number of vendor OUIs to be filled 3953 * @param_voui: pointer to OUI buffer 3954 * 3955 * This function populates the wmi tlv buffer when vendor specific OUIs are 3956 * present. 3957 * 3958 * Return: None 3959 */ 3960 static inline 3961 void wmi_fill_vendor_oui(uint8_t *buf_ptr, uint32_t num_vendor_oui, 3962 uint32_t *pvoui) 3963 { 3964 wmi_vendor_oui *voui = NULL; 3965 uint32_t i; 3966 3967 voui = (wmi_vendor_oui *)buf_ptr; 3968 3969 for (i = 0; i < num_vendor_oui; i++) { 3970 WMITLV_SET_HDR(&voui[i].tlv_header, 3971 WMITLV_TAG_STRUC_wmi_vendor_oui, 3972 WMITLV_GET_STRUCT_TLVLEN(wmi_vendor_oui)); 3973 voui[i].oui_type_subtype = pvoui[i]; 3974 } 3975 } 3976 3977 /* 3978 * wmi_fill_ie_allowlist_attrs() - fill IE allowlist attrs 3979 * @ie_bitmap: output pointer to ie bit map in cmd 3980 * @num_vendor_oui: output pointer to num vendor OUIs 3981 * @ie_allowlist: input parameter 3982 * 3983 * This function populates the IE allowlist attrs of scan, pno and 3984 * scan oui commands for ie_allowlist parameter. 3985 * 3986 * Return: None 3987 */ 3988 static inline 3989 void wmi_fill_ie_allowlist_attrs(uint32_t *ie_bitmap, 3990 uint32_t *num_vendor_oui, 3991 struct probe_req_allowlist_attr *ie_allowlist) 3992 { 3993 uint32_t i = 0; 3994 3995 for (i = 0; i < PROBE_REQ_BITMAP_LEN; i++) 3996 ie_bitmap[i] = ie_allowlist->ie_bitmap[i]; 3997 3998 *num_vendor_oui = ie_allowlist->num_vendor_oui; 3999 } 4000 4001 /** 4002 * send_scan_start_cmd_tlv() - WMI scan start function 4003 * @wmi_handle: handle to WMI. 4004 * @params: pointer to hold scan start cmd parameter 4005 * 4006 * Return: QDF_STATUS_SUCCESS for success or error code 4007 */ 4008 static QDF_STATUS send_scan_start_cmd_tlv(wmi_unified_t wmi_handle, 4009 struct scan_req_params *params) 4010 { 4011 int32_t ret = 0; 4012 int32_t i; 4013 wmi_buf_t wmi_buf; 4014 wmi_start_scan_cmd_fixed_param *cmd; 4015 uint8_t *buf_ptr; 4016 uint32_t *tmp_ptr; 4017 wmi_ssid *ssid = NULL; 4018 wmi_mac_addr *bssid; 4019 size_t len = sizeof(*cmd); 4020 uint16_t extraie_len_with_pad = 0; 4021 uint8_t phymode_roundup = 0; 4022 struct probe_req_allowlist_attr *ie_allowlist = ¶ms->ie_allowlist; 4023 wmi_hint_freq_short_ssid *s_ssid = NULL; 4024 wmi_hint_freq_bssid *hint_bssid = NULL; 4025 4026 /* Length TLV placeholder for array of uint32_t */ 4027 len += WMI_TLV_HDR_SIZE; 4028 /* calculate the length of buffer required */ 4029 if (params->chan_list.num_chan) 4030 len += params->chan_list.num_chan * sizeof(uint32_t); 4031 4032 /* Length TLV placeholder for array of wmi_ssid structures */ 4033 len += WMI_TLV_HDR_SIZE; 4034 if (params->num_ssids) 4035 len += params->num_ssids * sizeof(wmi_ssid); 4036 4037 /* Length TLV placeholder for array of wmi_mac_addr structures */ 4038 len += WMI_TLV_HDR_SIZE; 4039 if (params->num_bssid) 4040 len += sizeof(wmi_mac_addr) * params->num_bssid; 4041 4042 /* Length TLV placeholder for array of bytes */ 4043 len += WMI_TLV_HDR_SIZE; 4044 if (params->extraie.len) 4045 extraie_len_with_pad = 4046 roundup(params->extraie.len, sizeof(uint32_t)); 4047 len += extraie_len_with_pad; 4048 4049 len += WMI_TLV_HDR_SIZE; /* Length of TLV for array of wmi_vendor_oui */ 4050 if (ie_allowlist->num_vendor_oui) 4051 len += ie_allowlist->num_vendor_oui * sizeof(wmi_vendor_oui); 4052 4053 len += WMI_TLV_HDR_SIZE; /* Length of TLV for array of scan phymode */ 4054 if (params->scan_f_wide_band) 4055 phymode_roundup = 4056 qdf_roundup(params->chan_list.num_chan * sizeof(uint8_t), 4057 sizeof(uint32_t)); 4058 len += phymode_roundup; 4059 4060 len += WMI_TLV_HDR_SIZE; 4061 if (params->num_hint_bssid) 4062 len += params->num_hint_bssid * sizeof(wmi_hint_freq_bssid); 4063 4064 len += WMI_TLV_HDR_SIZE; 4065 if (params->num_hint_s_ssid) 4066 len += params->num_hint_s_ssid * sizeof(wmi_hint_freq_short_ssid); 4067 4068 /* Allocate the memory */ 4069 wmi_buf = wmi_buf_alloc(wmi_handle, len); 4070 if (!wmi_buf) 4071 return QDF_STATUS_E_FAILURE; 4072 4073 buf_ptr = (uint8_t *) wmi_buf_data(wmi_buf); 4074 cmd = (wmi_start_scan_cmd_fixed_param *) buf_ptr; 4075 WMITLV_SET_HDR(&cmd->tlv_header, 4076 WMITLV_TAG_STRUC_wmi_start_scan_cmd_fixed_param, 4077 WMITLV_GET_STRUCT_TLVLEN 4078 (wmi_start_scan_cmd_fixed_param)); 4079 4080 cmd->scan_id = params->scan_id; 4081 cmd->scan_req_id = params->scan_req_id; 4082 cmd->vdev_id = params->vdev_id; 4083 cmd->scan_priority = params->scan_priority; 4084 4085 copy_scan_event_cntrl_flags(cmd, params); 4086 4087 cmd->dwell_time_active = params->dwell_time_active; 4088 cmd->dwell_time_active_2g = params->dwell_time_active_2g; 4089 cmd->dwell_time_passive = params->dwell_time_passive; 4090 cmd->min_dwell_time_6ghz = params->min_dwell_time_6g; 4091 cmd->dwell_time_active_6ghz = params->dwell_time_active_6g; 4092 cmd->dwell_time_passive_6ghz = params->dwell_time_passive_6g; 4093 cmd->scan_start_offset = params->scan_offset_time; 4094 cmd->min_rest_time = params->min_rest_time; 4095 cmd->max_rest_time = params->max_rest_time; 4096 cmd->repeat_probe_time = params->repeat_probe_time; 4097 cmd->probe_spacing_time = params->probe_spacing_time; 4098 cmd->idle_time = params->idle_time; 4099 cmd->max_scan_time = params->max_scan_time; 4100 cmd->probe_delay = params->probe_delay; 4101 cmd->burst_duration = params->burst_duration; 4102 cmd->num_chan = params->chan_list.num_chan; 4103 cmd->num_bssid = params->num_bssid; 4104 cmd->num_ssids = params->num_ssids; 4105 cmd->ie_len = params->extraie.len; 4106 cmd->n_probes = params->n_probes; 4107 cmd->scan_ctrl_flags_ext = params->scan_ctrl_flags_ext; 4108 4109 if (params->scan_random.randomize) 4110 wmi_copy_scan_random_mac(params->scan_random.mac_addr, 4111 params->scan_random.mac_mask, 4112 &cmd->mac_addr, 4113 &cmd->mac_mask); 4114 4115 if (ie_allowlist->allow_list) 4116 wmi_fill_ie_allowlist_attrs(cmd->ie_bitmap, 4117 &cmd->num_vendor_oui, 4118 ie_allowlist); 4119 4120 buf_ptr += sizeof(*cmd); 4121 tmp_ptr = (uint32_t *) (buf_ptr + WMI_TLV_HDR_SIZE); 4122 for (i = 0; i < params->chan_list.num_chan; ++i) { 4123 TARGET_SET_FREQ_IN_CHAN_LIST_TLV(tmp_ptr[i], 4124 params->chan_list.chan[i].freq); 4125 TARGET_SET_FLAGS_IN_CHAN_LIST_TLV(tmp_ptr[i], 4126 params->chan_list.chan[i].flags); 4127 } 4128 4129 WMITLV_SET_HDR(buf_ptr, 4130 WMITLV_TAG_ARRAY_UINT32, 4131 (params->chan_list.num_chan * sizeof(uint32_t))); 4132 buf_ptr += WMI_TLV_HDR_SIZE + 4133 (params->chan_list.num_chan * sizeof(uint32_t)); 4134 4135 if (params->num_ssids > WLAN_SCAN_MAX_NUM_SSID) { 4136 wmi_err("Invalid value for num_ssids %d", params->num_ssids); 4137 goto error; 4138 } 4139 4140 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_FIXED_STRUC, 4141 (params->num_ssids * sizeof(wmi_ssid))); 4142 4143 if (params->num_ssids) { 4144 ssid = (wmi_ssid *) (buf_ptr + WMI_TLV_HDR_SIZE); 4145 for (i = 0; i < params->num_ssids; ++i) { 4146 ssid->ssid_len = params->ssid[i].length; 4147 qdf_mem_copy(ssid->ssid, params->ssid[i].ssid, 4148 params->ssid[i].length); 4149 ssid++; 4150 } 4151 } 4152 buf_ptr += WMI_TLV_HDR_SIZE + (params->num_ssids * sizeof(wmi_ssid)); 4153 4154 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_FIXED_STRUC, 4155 (params->num_bssid * sizeof(wmi_mac_addr))); 4156 bssid = (wmi_mac_addr *) (buf_ptr + WMI_TLV_HDR_SIZE); 4157 4158 if (params->num_bssid) { 4159 for (i = 0; i < params->num_bssid; ++i) { 4160 WMI_CHAR_ARRAY_TO_MAC_ADDR( 4161 ¶ms->bssid_list[i].bytes[0], bssid); 4162 bssid++; 4163 } 4164 } 4165 4166 buf_ptr += WMI_TLV_HDR_SIZE + 4167 (params->num_bssid * sizeof(wmi_mac_addr)); 4168 4169 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, extraie_len_with_pad); 4170 if (params->extraie.len) 4171 scan_copy_ie_buffer(buf_ptr + WMI_TLV_HDR_SIZE, 4172 params); 4173 4174 buf_ptr += WMI_TLV_HDR_SIZE + extraie_len_with_pad; 4175 4176 /* probe req ie allowlisting */ 4177 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 4178 ie_allowlist->num_vendor_oui * sizeof(wmi_vendor_oui)); 4179 4180 buf_ptr += WMI_TLV_HDR_SIZE; 4181 4182 if (cmd->num_vendor_oui) { 4183 wmi_fill_vendor_oui(buf_ptr, cmd->num_vendor_oui, 4184 ie_allowlist->voui); 4185 buf_ptr += cmd->num_vendor_oui * sizeof(wmi_vendor_oui); 4186 } 4187 4188 /* Add phy mode TLV if it's a wide band scan */ 4189 if (params->scan_f_wide_band) { 4190 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, phymode_roundup); 4191 buf_ptr = (uint8_t *) (buf_ptr + WMI_TLV_HDR_SIZE); 4192 for (i = 0; i < params->chan_list.num_chan; ++i) 4193 buf_ptr[i] = 4194 WMI_SCAN_CHAN_SET_MODE(params->chan_list.chan[i].phymode); 4195 buf_ptr += phymode_roundup; 4196 } else { 4197 /* Add ZERO length phy mode TLV */ 4198 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, 0); 4199 buf_ptr += WMI_TLV_HDR_SIZE; 4200 } 4201 4202 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_FIXED_STRUC, 4203 (params->num_hint_s_ssid * sizeof(wmi_hint_freq_short_ssid))); 4204 if (params->num_hint_s_ssid) { 4205 s_ssid = (wmi_hint_freq_short_ssid *)(buf_ptr + WMI_TLV_HDR_SIZE); 4206 for (i = 0; i < params->num_hint_s_ssid; ++i) { 4207 s_ssid->freq_flags = params->hint_s_ssid[i].freq_flags; 4208 s_ssid->short_ssid = params->hint_s_ssid[i].short_ssid; 4209 s_ssid++; 4210 } 4211 } 4212 buf_ptr += WMI_TLV_HDR_SIZE + 4213 (params->num_hint_s_ssid * sizeof(wmi_hint_freq_short_ssid)); 4214 4215 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_FIXED_STRUC, 4216 (params->num_hint_bssid * sizeof(wmi_hint_freq_bssid))); 4217 if (params->num_hint_bssid) { 4218 hint_bssid = (wmi_hint_freq_bssid *)(buf_ptr + WMI_TLV_HDR_SIZE); 4219 for (i = 0; i < params->num_hint_bssid; ++i) { 4220 hint_bssid->freq_flags = 4221 params->hint_bssid[i].freq_flags; 4222 WMI_CHAR_ARRAY_TO_MAC_ADDR(¶ms->hint_bssid[i].bssid.bytes[0], 4223 &hint_bssid->bssid); 4224 hint_bssid++; 4225 } 4226 } 4227 4228 wmi_mtrace(WMI_START_SCAN_CMDID, cmd->vdev_id, 0); 4229 ret = wmi_unified_cmd_send(wmi_handle, wmi_buf, 4230 len, WMI_START_SCAN_CMDID); 4231 if (ret) { 4232 wmi_err("Failed to start scan: %d", ret); 4233 wmi_buf_free(wmi_buf); 4234 } 4235 return ret; 4236 error: 4237 wmi_buf_free(wmi_buf); 4238 return QDF_STATUS_E_FAILURE; 4239 } 4240 4241 /** 4242 * send_scan_stop_cmd_tlv() - WMI scan start function 4243 * @wmi_handle: handle to WMI. 4244 * @param: pointer to hold scan cancel cmd parameter 4245 * 4246 * Return: QDF_STATUS_SUCCESS for success or error code 4247 */ 4248 static QDF_STATUS send_scan_stop_cmd_tlv(wmi_unified_t wmi_handle, 4249 struct scan_cancel_param *param) 4250 { 4251 wmi_stop_scan_cmd_fixed_param *cmd; 4252 int ret; 4253 int len = sizeof(*cmd); 4254 wmi_buf_t wmi_buf; 4255 4256 /* Allocate the memory */ 4257 wmi_buf = wmi_buf_alloc(wmi_handle, len); 4258 if (!wmi_buf) { 4259 ret = QDF_STATUS_E_NOMEM; 4260 goto error; 4261 } 4262 4263 cmd = (wmi_stop_scan_cmd_fixed_param *) wmi_buf_data(wmi_buf); 4264 WMITLV_SET_HDR(&cmd->tlv_header, 4265 WMITLV_TAG_STRUC_wmi_stop_scan_cmd_fixed_param, 4266 WMITLV_GET_STRUCT_TLVLEN(wmi_stop_scan_cmd_fixed_param)); 4267 cmd->vdev_id = param->vdev_id; 4268 cmd->requestor = param->requester; 4269 cmd->scan_id = param->scan_id; 4270 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 4271 wmi_handle, 4272 param->pdev_id); 4273 /* stop the scan with the corresponding scan_id */ 4274 if (param->req_type == WLAN_SCAN_CANCEL_PDEV_ALL) { 4275 /* Cancelling all scans */ 4276 cmd->req_type = WMI_SCAN_STOP_ALL; 4277 } else if (param->req_type == WLAN_SCAN_CANCEL_VDEV_ALL) { 4278 /* Cancelling VAP scans */ 4279 cmd->req_type = WMI_SCN_STOP_VAP_ALL; 4280 } else if (param->req_type == WLAN_SCAN_CANCEL_SINGLE) { 4281 /* Cancelling specific scan */ 4282 cmd->req_type = WMI_SCAN_STOP_ONE; 4283 } else if (param->req_type == WLAN_SCAN_CANCEL_HOST_VDEV_ALL) { 4284 cmd->req_type = WMI_SCN_STOP_HOST_VAP_ALL; 4285 } else { 4286 wmi_err("Invalid Scan cancel req type: %d", param->req_type); 4287 wmi_buf_free(wmi_buf); 4288 return QDF_STATUS_E_INVAL; 4289 } 4290 4291 wmi_mtrace(WMI_STOP_SCAN_CMDID, cmd->vdev_id, 0); 4292 ret = wmi_unified_cmd_send(wmi_handle, wmi_buf, 4293 len, WMI_STOP_SCAN_CMDID); 4294 if (ret) { 4295 wmi_err("Failed to send stop scan: %d", ret); 4296 wmi_buf_free(wmi_buf); 4297 } 4298 4299 error: 4300 return ret; 4301 } 4302 4303 #define WMI_MAX_CHAN_INFO_LOG 192 4304 4305 /** 4306 * wmi_scan_chanlist_dump() - Dump scan channel list info 4307 * @scan_chan_list: scan channel list 4308 * 4309 * Return: void 4310 */ 4311 static void wmi_scan_chanlist_dump(struct scan_chan_list_params *scan_chan_list) 4312 { 4313 uint32_t i; 4314 uint8_t info[WMI_MAX_CHAN_INFO_LOG]; 4315 uint32_t len = 0; 4316 struct channel_param *chan; 4317 int ret; 4318 4319 wmi_debug("Total chan %d", scan_chan_list->nallchans); 4320 for (i = 0; i < scan_chan_list->nallchans; i++) { 4321 chan = &scan_chan_list->ch_param[i]; 4322 ret = qdf_scnprintf(info + len, sizeof(info) - len, 4323 " %d[%d][%d][%d]", chan->mhz, 4324 chan->maxregpower, 4325 chan->dfs_set, chan->nan_disabled); 4326 if (ret <= 0) 4327 break; 4328 len += ret; 4329 if (len >= (sizeof(info) - 20)) { 4330 wmi_nofl_debug("Chan[TXPwr][DFS][nan_disabled]:%s", 4331 info); 4332 len = 0; 4333 } 4334 } 4335 if (len) 4336 wmi_nofl_debug("Chan[TXPwr][DFS]:%s", info); 4337 } 4338 4339 static QDF_STATUS send_scan_chan_list_cmd_tlv(wmi_unified_t wmi_handle, 4340 struct scan_chan_list_params *chan_list) 4341 { 4342 wmi_buf_t buf; 4343 QDF_STATUS qdf_status = QDF_STATUS_SUCCESS; 4344 wmi_scan_chan_list_cmd_fixed_param *cmd; 4345 int i; 4346 uint8_t *buf_ptr; 4347 wmi_channel *chan_info; 4348 struct channel_param *tchan_info; 4349 uint16_t len; 4350 uint16_t num_send_chans, num_sends = 0; 4351 4352 wmi_scan_chanlist_dump(chan_list); 4353 tchan_info = &chan_list->ch_param[0]; 4354 while (chan_list->nallchans) { 4355 len = sizeof(*cmd) + WMI_TLV_HDR_SIZE; 4356 if (chan_list->nallchans > MAX_NUM_CHAN_PER_WMI_CMD) 4357 num_send_chans = MAX_NUM_CHAN_PER_WMI_CMD; 4358 else 4359 num_send_chans = chan_list->nallchans; 4360 4361 chan_list->nallchans -= num_send_chans; 4362 len += sizeof(wmi_channel) * num_send_chans; 4363 buf = wmi_buf_alloc(wmi_handle, len); 4364 if (!buf) { 4365 qdf_status = QDF_STATUS_E_NOMEM; 4366 goto end; 4367 } 4368 4369 buf_ptr = (uint8_t *)wmi_buf_data(buf); 4370 cmd = (wmi_scan_chan_list_cmd_fixed_param *)buf_ptr; 4371 WMITLV_SET_HDR(&cmd->tlv_header, 4372 WMITLV_TAG_STRUC_wmi_scan_chan_list_cmd_fixed_param, 4373 WMITLV_GET_STRUCT_TLVLEN 4374 (wmi_scan_chan_list_cmd_fixed_param)); 4375 4376 wmi_debug("no of channels = %d, len = %d", num_send_chans, len); 4377 4378 if (num_sends) 4379 cmd->flags |= APPEND_TO_EXISTING_CHAN_LIST; 4380 4381 if (chan_list->max_bw_support_present) 4382 cmd->flags |= CHANNEL_MAX_BANDWIDTH_VALID; 4383 4384 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 4385 wmi_handle, 4386 chan_list->pdev_id); 4387 4388 wmi_mtrace(WMI_SCAN_CHAN_LIST_CMDID, cmd->pdev_id, 0); 4389 4390 cmd->num_scan_chans = num_send_chans; 4391 WMITLV_SET_HDR((buf_ptr + 4392 sizeof(wmi_scan_chan_list_cmd_fixed_param)), 4393 WMITLV_TAG_ARRAY_STRUC, 4394 sizeof(wmi_channel) * num_send_chans); 4395 chan_info = (wmi_channel *)(buf_ptr + sizeof(*cmd) + 4396 WMI_TLV_HDR_SIZE); 4397 4398 for (i = 0; i < num_send_chans; ++i) { 4399 WMITLV_SET_HDR(&chan_info->tlv_header, 4400 WMITLV_TAG_STRUC_wmi_channel, 4401 WMITLV_GET_STRUCT_TLVLEN(wmi_channel)); 4402 chan_info->mhz = tchan_info->mhz; 4403 chan_info->band_center_freq1 = 4404 tchan_info->cfreq1; 4405 chan_info->band_center_freq2 = 4406 tchan_info->cfreq2; 4407 4408 if (tchan_info->is_chan_passive) 4409 WMI_SET_CHANNEL_FLAG(chan_info, 4410 WMI_CHAN_FLAG_PASSIVE); 4411 if (tchan_info->dfs_set) 4412 WMI_SET_CHANNEL_FLAG(chan_info, 4413 WMI_CHAN_FLAG_DFS); 4414 4415 if (tchan_info->dfs_set_cfreq2) 4416 WMI_SET_CHANNEL_FLAG(chan_info, 4417 WMI_CHAN_FLAG_DFS_CFREQ2); 4418 4419 if (tchan_info->allow_he) 4420 WMI_SET_CHANNEL_FLAG(chan_info, 4421 WMI_CHAN_FLAG_ALLOW_HE); 4422 4423 if (tchan_info->allow_eht) 4424 WMI_SET_CHANNEL_FLAG(chan_info, 4425 WMI_CHAN_FLAG_ALLOW_EHT); 4426 4427 if (tchan_info->allow_vht) 4428 WMI_SET_CHANNEL_FLAG(chan_info, 4429 WMI_CHAN_FLAG_ALLOW_VHT); 4430 4431 if (tchan_info->allow_ht) 4432 WMI_SET_CHANNEL_FLAG(chan_info, 4433 WMI_CHAN_FLAG_ALLOW_HT); 4434 WMI_SET_CHANNEL_MODE(chan_info, 4435 tchan_info->phy_mode); 4436 4437 if (tchan_info->half_rate) 4438 WMI_SET_CHANNEL_FLAG(chan_info, 4439 WMI_CHAN_FLAG_HALF_RATE); 4440 4441 if (tchan_info->quarter_rate) 4442 WMI_SET_CHANNEL_FLAG(chan_info, 4443 WMI_CHAN_FLAG_QUARTER_RATE); 4444 4445 if (tchan_info->psc_channel) 4446 WMI_SET_CHANNEL_FLAG(chan_info, 4447 WMI_CHAN_FLAG_PSC); 4448 4449 if (tchan_info->nan_disabled) 4450 WMI_SET_CHANNEL_FLAG(chan_info, 4451 WMI_CHAN_FLAG_NAN_DISABLED); 4452 4453 /* also fill in power information */ 4454 WMI_SET_CHANNEL_MIN_POWER(chan_info, 4455 tchan_info->minpower); 4456 WMI_SET_CHANNEL_MAX_POWER(chan_info, 4457 tchan_info->maxpower); 4458 WMI_SET_CHANNEL_REG_POWER(chan_info, 4459 tchan_info->maxregpower); 4460 WMI_SET_CHANNEL_ANTENNA_MAX(chan_info, 4461 tchan_info->antennamax); 4462 WMI_SET_CHANNEL_REG_CLASSID(chan_info, 4463 tchan_info->reg_class_id); 4464 WMI_SET_CHANNEL_MAX_TX_POWER(chan_info, 4465 tchan_info->maxregpower); 4466 WMI_SET_CHANNEL_MAX_BANDWIDTH(chan_info, 4467 tchan_info->max_bw_supported); 4468 4469 tchan_info++; 4470 chan_info++; 4471 } 4472 4473 qdf_status = wmi_unified_cmd_send( 4474 wmi_handle, 4475 buf, len, WMI_SCAN_CHAN_LIST_CMDID); 4476 4477 if (QDF_IS_STATUS_ERROR(qdf_status)) { 4478 wmi_err("Failed to send WMI_SCAN_CHAN_LIST_CMDID"); 4479 wmi_buf_free(buf); 4480 goto end; 4481 } 4482 num_sends++; 4483 } 4484 4485 end: 4486 return qdf_status; 4487 } 4488 4489 /** 4490 * populate_tx_send_params - Populate TX param TLV for mgmt and offchan tx 4491 * 4492 * @bufp: Pointer to buffer 4493 * @param: Pointer to tx param 4494 * 4495 * Return: QDF_STATUS_SUCCESS for success and QDF_STATUS_E_FAILURE for failure 4496 */ 4497 static inline QDF_STATUS populate_tx_send_params(uint8_t *bufp, 4498 struct tx_send_params param) 4499 { 4500 wmi_tx_send_params *tx_param; 4501 QDF_STATUS status = QDF_STATUS_SUCCESS; 4502 4503 if (!bufp) { 4504 status = QDF_STATUS_E_FAILURE; 4505 return status; 4506 } 4507 tx_param = (wmi_tx_send_params *)bufp; 4508 WMITLV_SET_HDR(&tx_param->tlv_header, 4509 WMITLV_TAG_STRUC_wmi_tx_send_params, 4510 WMITLV_GET_STRUCT_TLVLEN(wmi_tx_send_params)); 4511 WMI_TX_SEND_PARAM_PWR_SET(tx_param->tx_param_dword0, param.pwr); 4512 WMI_TX_SEND_PARAM_MCS_MASK_SET(tx_param->tx_param_dword0, 4513 param.mcs_mask); 4514 WMI_TX_SEND_PARAM_NSS_MASK_SET(tx_param->tx_param_dword0, 4515 param.nss_mask); 4516 WMI_TX_SEND_PARAM_RETRY_LIMIT_SET(tx_param->tx_param_dword0, 4517 param.retry_limit); 4518 WMI_TX_SEND_PARAM_CHAIN_MASK_SET(tx_param->tx_param_dword1, 4519 param.chain_mask); 4520 WMI_TX_SEND_PARAM_BW_MASK_SET(tx_param->tx_param_dword1, 4521 param.bw_mask); 4522 WMI_TX_SEND_PARAM_PREAMBLE_SET(tx_param->tx_param_dword1, 4523 param.preamble_type); 4524 WMI_TX_SEND_PARAM_FRAME_TYPE_SET(tx_param->tx_param_dword1, 4525 param.frame_type); 4526 WMI_TX_SEND_PARAM_CFR_CAPTURE_SET(tx_param->tx_param_dword1, 4527 param.cfr_enable); 4528 WMI_TX_SEND_PARAM_BEAMFORM_SET(tx_param->tx_param_dword1, 4529 param.en_beamforming); 4530 WMI_TX_SEND_PARAM_RETRY_LIMIT_EXT_SET(tx_param->tx_param_dword1, 4531 param.retry_limit_ext); 4532 4533 return status; 4534 } 4535 4536 #ifdef CONFIG_HL_SUPPORT 4537 /** 4538 * send_mgmt_cmd_tlv() - WMI scan start function 4539 * @wmi_handle: handle to WMI. 4540 * @param: pointer to hold mgmt cmd parameter 4541 * 4542 * Return: QDF_STATUS_SUCCESS for success or error code 4543 */ 4544 static QDF_STATUS send_mgmt_cmd_tlv(wmi_unified_t wmi_handle, 4545 struct wmi_mgmt_params *param) 4546 { 4547 wmi_buf_t buf; 4548 uint8_t *bufp; 4549 int32_t cmd_len; 4550 wmi_mgmt_tx_send_cmd_fixed_param *cmd; 4551 int32_t bufp_len = (param->frm_len < mgmt_tx_dl_frm_len) ? param->frm_len : 4552 mgmt_tx_dl_frm_len; 4553 4554 if (param->frm_len > mgmt_tx_dl_frm_len) { 4555 wmi_err("mgmt frame len %u exceeds %u", 4556 param->frm_len, mgmt_tx_dl_frm_len); 4557 return QDF_STATUS_E_INVAL; 4558 } 4559 4560 cmd_len = sizeof(wmi_mgmt_tx_send_cmd_fixed_param) + 4561 WMI_TLV_HDR_SIZE + 4562 roundup(bufp_len, sizeof(uint32_t)); 4563 4564 buf = wmi_buf_alloc(wmi_handle, sizeof(wmi_tx_send_params) + cmd_len); 4565 if (!buf) 4566 return QDF_STATUS_E_NOMEM; 4567 4568 cmd = (wmi_mgmt_tx_send_cmd_fixed_param *)wmi_buf_data(buf); 4569 bufp = (uint8_t *) cmd; 4570 WMITLV_SET_HDR(&cmd->tlv_header, 4571 WMITLV_TAG_STRUC_wmi_mgmt_tx_send_cmd_fixed_param, 4572 WMITLV_GET_STRUCT_TLVLEN 4573 (wmi_mgmt_tx_send_cmd_fixed_param)); 4574 4575 cmd->vdev_id = param->vdev_id; 4576 4577 cmd->desc_id = param->desc_id; 4578 cmd->chanfreq = param->chanfreq; 4579 bufp += sizeof(wmi_mgmt_tx_send_cmd_fixed_param); 4580 WMITLV_SET_HDR(bufp, WMITLV_TAG_ARRAY_BYTE, roundup(bufp_len, 4581 sizeof(uint32_t))); 4582 bufp += WMI_TLV_HDR_SIZE; 4583 qdf_mem_copy(bufp, param->pdata, bufp_len); 4584 4585 cmd->frame_len = param->frm_len; 4586 cmd->buf_len = bufp_len; 4587 cmd->tx_params_valid = param->tx_params_valid; 4588 cmd->tx_flags = param->tx_flags; 4589 cmd->peer_rssi = param->peer_rssi; 4590 4591 wmi_mgmt_cmd_record(wmi_handle, WMI_MGMT_TX_SEND_CMDID, 4592 bufp, cmd->vdev_id, cmd->chanfreq); 4593 4594 bufp += roundup(bufp_len, sizeof(uint32_t)); 4595 if (param->tx_params_valid) { 4596 if (populate_tx_send_params(bufp, param->tx_param) != 4597 QDF_STATUS_SUCCESS) { 4598 wmi_err("Populate TX send params failed"); 4599 goto free_buf; 4600 } 4601 cmd_len += sizeof(wmi_tx_send_params); 4602 } 4603 4604 wmi_mtrace(WMI_MGMT_TX_SEND_CMDID, cmd->vdev_id, 0); 4605 if (wmi_unified_cmd_send(wmi_handle, buf, cmd_len, 4606 WMI_MGMT_TX_SEND_CMDID)) { 4607 wmi_err("Failed to send mgmt Tx"); 4608 goto free_buf; 4609 } 4610 return QDF_STATUS_SUCCESS; 4611 4612 free_buf: 4613 wmi_buf_free(buf); 4614 return QDF_STATUS_E_FAILURE; 4615 } 4616 #else 4617 /** 4618 * send_mgmt_cmd_tlv() - WMI scan start function 4619 * @wmi_handle: handle to WMI. 4620 * @param: pointer to hold mgmt cmd parameter 4621 * 4622 * Return: QDF_STATUS_SUCCESS for success or error code 4623 */ 4624 static QDF_STATUS send_mgmt_cmd_tlv(wmi_unified_t wmi_handle, 4625 struct wmi_mgmt_params *param) 4626 { 4627 wmi_buf_t buf; 4628 wmi_mgmt_tx_send_cmd_fixed_param *cmd; 4629 int32_t cmd_len; 4630 uint64_t dma_addr; 4631 void *qdf_ctx = param->qdf_ctx; 4632 uint8_t *bufp; 4633 QDF_STATUS status = QDF_STATUS_SUCCESS; 4634 wmi_mlo_tx_send_params *mlo_params; 4635 int32_t bufp_len = (param->frm_len < mgmt_tx_dl_frm_len) ? param->frm_len : 4636 mgmt_tx_dl_frm_len; 4637 4638 cmd_len = sizeof(wmi_mgmt_tx_send_cmd_fixed_param) + 4639 WMI_TLV_HDR_SIZE + 4640 roundup(bufp_len, sizeof(uint32_t)); 4641 4642 buf = wmi_buf_alloc(wmi_handle, sizeof(wmi_tx_send_params) + cmd_len + 4643 WMI_TLV_HDR_SIZE + sizeof(wmi_mlo_tx_send_params)); 4644 if (!buf) 4645 return QDF_STATUS_E_NOMEM; 4646 4647 cmd = (wmi_mgmt_tx_send_cmd_fixed_param *)wmi_buf_data(buf); 4648 bufp = (uint8_t *) cmd; 4649 WMITLV_SET_HDR(&cmd->tlv_header, 4650 WMITLV_TAG_STRUC_wmi_mgmt_tx_send_cmd_fixed_param, 4651 WMITLV_GET_STRUCT_TLVLEN 4652 (wmi_mgmt_tx_send_cmd_fixed_param)); 4653 4654 cmd->vdev_id = param->vdev_id; 4655 4656 cmd->desc_id = param->desc_id; 4657 cmd->chanfreq = param->chanfreq; 4658 cmd->peer_rssi = param->peer_rssi; 4659 bufp += sizeof(wmi_mgmt_tx_send_cmd_fixed_param); 4660 WMITLV_SET_HDR(bufp, WMITLV_TAG_ARRAY_BYTE, roundup(bufp_len, 4661 sizeof(uint32_t))); 4662 bufp += WMI_TLV_HDR_SIZE; 4663 4664 /* for big endian host, copy engine byte_swap is enabled 4665 * But the frame content is in network byte order 4666 * Need to byte swap the frame content - so when copy engine 4667 * does byte_swap - target gets frame content in the correct order 4668 */ 4669 WMI_HOST_IF_MSG_COPY_CHAR_ARRAY(bufp, param->pdata, bufp_len); 4670 4671 status = qdf_nbuf_map_single(qdf_ctx, param->tx_frame, 4672 QDF_DMA_TO_DEVICE); 4673 if (status != QDF_STATUS_SUCCESS) { 4674 wmi_err("wmi buf map failed"); 4675 goto free_buf; 4676 } 4677 4678 dma_addr = qdf_nbuf_get_frag_paddr(param->tx_frame, 0); 4679 cmd->paddr_lo = (uint32_t)(dma_addr & 0xffffffff); 4680 #if defined(HTT_PADDR64) 4681 cmd->paddr_hi = (uint32_t)((dma_addr >> 32) & 0x1F); 4682 #endif 4683 cmd->frame_len = param->frm_len; 4684 cmd->buf_len = bufp_len; 4685 cmd->tx_params_valid = param->tx_params_valid; 4686 cmd->tx_flags = param->tx_flags; 4687 4688 wmi_mgmt_cmd_record(wmi_handle, WMI_MGMT_TX_SEND_CMDID, 4689 bufp, cmd->vdev_id, cmd->chanfreq); 4690 4691 bufp += roundup(bufp_len, sizeof(uint32_t)); 4692 if (param->tx_params_valid) { 4693 status = populate_tx_send_params(bufp, param->tx_param); 4694 if (status != QDF_STATUS_SUCCESS) { 4695 wmi_err("Populate TX send params failed"); 4696 goto unmap_tx_frame; 4697 } 4698 } else { 4699 WMITLV_SET_HDR(&((wmi_tx_send_params *)bufp)->tlv_header, 4700 WMITLV_TAG_STRUC_wmi_tx_send_params, 4701 WMITLV_GET_STRUCT_TLVLEN(wmi_tx_send_params)); 4702 } 4703 4704 /* Even tx_params_valid is false, still need reserve space to pass wmi 4705 * tag check */ 4706 cmd_len += sizeof(wmi_tx_send_params); 4707 bufp += sizeof(wmi_tx_send_params); 4708 /* wmi_mlo_tx_send_params */ 4709 if (param->mlo_link_agnostic) { 4710 wmi_debug("Set mlo mgmt tid"); 4711 WMITLV_SET_HDR(bufp, WMITLV_TAG_ARRAY_STRUC, 4712 sizeof(wmi_mlo_tx_send_params)); 4713 bufp += WMI_TLV_HDR_SIZE; 4714 mlo_params = (wmi_mlo_tx_send_params *)bufp; 4715 WMITLV_SET_HDR(&mlo_params->tlv_header, 4716 WMITLV_TAG_STRUC_wmi_mlo_tx_send_params, 4717 WMITLV_GET_STRUCT_TLVLEN(wmi_mlo_tx_send_params)); 4718 mlo_params->hw_link_id = WMI_MLO_MGMT_TID; 4719 cmd_len += WMI_TLV_HDR_SIZE + sizeof(wmi_mlo_tx_send_params); 4720 } 4721 4722 wmi_mtrace(WMI_MGMT_TX_SEND_CMDID, cmd->vdev_id, 0); 4723 if (wmi_unified_cmd_send(wmi_handle, buf, cmd_len, 4724 WMI_MGMT_TX_SEND_CMDID)) { 4725 wmi_err("Failed to send mgmt Tx"); 4726 goto unmap_tx_frame; 4727 } 4728 return QDF_STATUS_SUCCESS; 4729 4730 unmap_tx_frame: 4731 qdf_nbuf_unmap_single(qdf_ctx, param->tx_frame, 4732 QDF_DMA_TO_DEVICE); 4733 free_buf: 4734 wmi_buf_free(buf); 4735 return QDF_STATUS_E_FAILURE; 4736 } 4737 #endif /* CONFIG_HL_SUPPORT */ 4738 4739 /** 4740 * send_offchan_data_tx_cmd_tlv() - Send off-chan tx data 4741 * @wmi_handle: handle to WMI. 4742 * @param: pointer to offchan data tx cmd parameter 4743 * 4744 * Return: QDF_STATUS_SUCCESS on success and error on failure. 4745 */ 4746 static QDF_STATUS send_offchan_data_tx_cmd_tlv(wmi_unified_t wmi_handle, 4747 struct wmi_offchan_data_tx_params *param) 4748 { 4749 wmi_buf_t buf; 4750 wmi_offchan_data_tx_send_cmd_fixed_param *cmd; 4751 int32_t cmd_len; 4752 uint64_t dma_addr; 4753 void *qdf_ctx = param->qdf_ctx; 4754 uint8_t *bufp; 4755 int32_t bufp_len = (param->frm_len < mgmt_tx_dl_frm_len) ? 4756 param->frm_len : mgmt_tx_dl_frm_len; 4757 QDF_STATUS status = QDF_STATUS_SUCCESS; 4758 4759 cmd_len = sizeof(wmi_offchan_data_tx_send_cmd_fixed_param) + 4760 WMI_TLV_HDR_SIZE + 4761 roundup(bufp_len, sizeof(uint32_t)); 4762 4763 buf = wmi_buf_alloc(wmi_handle, sizeof(wmi_tx_send_params) + cmd_len); 4764 if (!buf) 4765 return QDF_STATUS_E_NOMEM; 4766 4767 cmd = (wmi_offchan_data_tx_send_cmd_fixed_param *) wmi_buf_data(buf); 4768 bufp = (uint8_t *) cmd; 4769 WMITLV_SET_HDR(&cmd->tlv_header, 4770 WMITLV_TAG_STRUC_wmi_offchan_data_tx_send_cmd_fixed_param, 4771 WMITLV_GET_STRUCT_TLVLEN 4772 (wmi_offchan_data_tx_send_cmd_fixed_param)); 4773 4774 cmd->vdev_id = param->vdev_id; 4775 4776 cmd->desc_id = param->desc_id; 4777 cmd->chanfreq = param->chanfreq; 4778 bufp += sizeof(wmi_offchan_data_tx_send_cmd_fixed_param); 4779 WMITLV_SET_HDR(bufp, WMITLV_TAG_ARRAY_BYTE, roundup(bufp_len, 4780 sizeof(uint32_t))); 4781 bufp += WMI_TLV_HDR_SIZE; 4782 qdf_mem_copy(bufp, param->pdata, bufp_len); 4783 qdf_nbuf_map_single(qdf_ctx, param->tx_frame, QDF_DMA_TO_DEVICE); 4784 dma_addr = qdf_nbuf_get_frag_paddr(param->tx_frame, 0); 4785 cmd->paddr_lo = (uint32_t)(dma_addr & 0xffffffff); 4786 #if defined(HTT_PADDR64) 4787 cmd->paddr_hi = (uint32_t)((dma_addr >> 32) & 0x1F); 4788 #endif 4789 cmd->frame_len = param->frm_len; 4790 cmd->buf_len = bufp_len; 4791 cmd->tx_params_valid = param->tx_params_valid; 4792 4793 wmi_mgmt_cmd_record(wmi_handle, WMI_OFFCHAN_DATA_TX_SEND_CMDID, 4794 bufp, cmd->vdev_id, cmd->chanfreq); 4795 4796 bufp += roundup(bufp_len, sizeof(uint32_t)); 4797 if (param->tx_params_valid) { 4798 status = populate_tx_send_params(bufp, param->tx_param); 4799 if (status != QDF_STATUS_SUCCESS) { 4800 wmi_err("Populate TX send params failed"); 4801 goto err1; 4802 } 4803 cmd_len += sizeof(wmi_tx_send_params); 4804 } 4805 4806 wmi_mtrace(WMI_OFFCHAN_DATA_TX_SEND_CMDID, cmd->vdev_id, 0); 4807 if (wmi_unified_cmd_send(wmi_handle, buf, cmd_len, 4808 WMI_OFFCHAN_DATA_TX_SEND_CMDID)) { 4809 wmi_err("Failed to offchan data Tx"); 4810 goto err1; 4811 } 4812 4813 return QDF_STATUS_SUCCESS; 4814 4815 err1: 4816 wmi_buf_free(buf); 4817 return QDF_STATUS_E_FAILURE; 4818 } 4819 4820 /** 4821 * send_modem_power_state_cmd_tlv() - set modem power state to fw 4822 * @wmi_handle: wmi handle 4823 * @param_value: parameter value 4824 * 4825 * Return: QDF_STATUS_SUCCESS for success or error code 4826 */ 4827 static QDF_STATUS send_modem_power_state_cmd_tlv(wmi_unified_t wmi_handle, 4828 uint32_t param_value) 4829 { 4830 QDF_STATUS ret; 4831 wmi_modem_power_state_cmd_param *cmd; 4832 wmi_buf_t buf; 4833 uint16_t len = sizeof(*cmd); 4834 4835 buf = wmi_buf_alloc(wmi_handle, len); 4836 if (!buf) 4837 return QDF_STATUS_E_NOMEM; 4838 4839 cmd = (wmi_modem_power_state_cmd_param *) wmi_buf_data(buf); 4840 WMITLV_SET_HDR(&cmd->tlv_header, 4841 WMITLV_TAG_STRUC_wmi_modem_power_state_cmd_param, 4842 WMITLV_GET_STRUCT_TLVLEN 4843 (wmi_modem_power_state_cmd_param)); 4844 cmd->modem_power_state = param_value; 4845 wmi_debug("Setting cmd->modem_power_state = %u", param_value); 4846 wmi_mtrace(WMI_MODEM_POWER_STATE_CMDID, NO_SESSION, 0); 4847 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 4848 WMI_MODEM_POWER_STATE_CMDID); 4849 if (QDF_IS_STATUS_ERROR(ret)) { 4850 wmi_err("Failed to send notify cmd ret = %d", ret); 4851 wmi_buf_free(buf); 4852 } 4853 4854 return ret; 4855 } 4856 4857 /** 4858 * send_set_sta_ps_mode_cmd_tlv() - set sta powersave mode in fw 4859 * @wmi_handle: wmi handle 4860 * @vdev_id: vdev id 4861 * @val: value 4862 * 4863 * Return: QDF_STATUS_SUCCESS for success or error code. 4864 */ 4865 static QDF_STATUS send_set_sta_ps_mode_cmd_tlv(wmi_unified_t wmi_handle, 4866 uint32_t vdev_id, uint8_t val) 4867 { 4868 wmi_sta_powersave_mode_cmd_fixed_param *cmd; 4869 wmi_buf_t buf; 4870 int32_t len = sizeof(*cmd); 4871 4872 wmi_debug("Set Sta Mode Ps vdevId %d val %d", vdev_id, val); 4873 4874 buf = wmi_buf_alloc(wmi_handle, len); 4875 if (!buf) 4876 return QDF_STATUS_E_NOMEM; 4877 4878 cmd = (wmi_sta_powersave_mode_cmd_fixed_param *) wmi_buf_data(buf); 4879 WMITLV_SET_HDR(&cmd->tlv_header, 4880 WMITLV_TAG_STRUC_wmi_sta_powersave_mode_cmd_fixed_param, 4881 WMITLV_GET_STRUCT_TLVLEN 4882 (wmi_sta_powersave_mode_cmd_fixed_param)); 4883 cmd->vdev_id = vdev_id; 4884 if (val) 4885 cmd->sta_ps_mode = WMI_STA_PS_MODE_ENABLED; 4886 else 4887 cmd->sta_ps_mode = WMI_STA_PS_MODE_DISABLED; 4888 4889 wmi_mtrace(WMI_STA_POWERSAVE_MODE_CMDID, cmd->vdev_id, 0); 4890 if (wmi_unified_cmd_send(wmi_handle, buf, len, 4891 WMI_STA_POWERSAVE_MODE_CMDID)) { 4892 wmi_err("Set Sta Mode Ps Failed vdevId %d val %d", 4893 vdev_id, val); 4894 wmi_buf_free(buf); 4895 return QDF_STATUS_E_FAILURE; 4896 } 4897 return QDF_STATUS_SUCCESS; 4898 } 4899 4900 /** 4901 * send_idle_roam_monitor_cmd_tlv() - send idle monitor command to fw 4902 * @wmi_handle: wmi handle 4903 * @val: non-zero to turn monitor on 4904 * 4905 * Return: QDF_STATUS_SUCCESS for success or error code. 4906 */ 4907 static QDF_STATUS send_idle_roam_monitor_cmd_tlv(wmi_unified_t wmi_handle, 4908 uint8_t val) 4909 { 4910 wmi_idle_trigger_monitor_cmd_fixed_param *cmd; 4911 wmi_buf_t buf; 4912 size_t len = sizeof(*cmd); 4913 4914 buf = wmi_buf_alloc(wmi_handle, len); 4915 if (!buf) 4916 return QDF_STATUS_E_NOMEM; 4917 4918 cmd = (wmi_idle_trigger_monitor_cmd_fixed_param *)wmi_buf_data(buf); 4919 WMITLV_SET_HDR(&cmd->tlv_header, 4920 WMITLV_TAG_STRUC_wmi_idle_trigger_monitor_cmd_fixed_param, 4921 WMITLV_GET_STRUCT_TLVLEN(wmi_idle_trigger_monitor_cmd_fixed_param)); 4922 4923 cmd->idle_trigger_monitor = (val ? WMI_IDLE_TRIGGER_MONITOR_ON : 4924 WMI_IDLE_TRIGGER_MONITOR_OFF); 4925 4926 wmi_debug("val: %d", cmd->idle_trigger_monitor); 4927 4928 if (wmi_unified_cmd_send(wmi_handle, buf, len, 4929 WMI_IDLE_TRIGGER_MONITOR_CMDID)) { 4930 wmi_buf_free(buf); 4931 return QDF_STATUS_E_FAILURE; 4932 } 4933 return QDF_STATUS_SUCCESS; 4934 } 4935 4936 /** 4937 * send_set_mimops_cmd_tlv() - set MIMO powersave 4938 * @wmi_handle: wmi handle 4939 * @vdev_id: vdev id 4940 * @value: value 4941 * 4942 * Return: QDF_STATUS_SUCCESS for success or error code. 4943 */ 4944 static QDF_STATUS send_set_mimops_cmd_tlv(wmi_unified_t wmi_handle, 4945 uint8_t vdev_id, int value) 4946 { 4947 QDF_STATUS ret; 4948 wmi_sta_smps_force_mode_cmd_fixed_param *cmd; 4949 wmi_buf_t buf; 4950 uint16_t len = sizeof(*cmd); 4951 4952 buf = wmi_buf_alloc(wmi_handle, len); 4953 if (!buf) 4954 return QDF_STATUS_E_NOMEM; 4955 4956 cmd = (wmi_sta_smps_force_mode_cmd_fixed_param *) wmi_buf_data(buf); 4957 WMITLV_SET_HDR(&cmd->tlv_header, 4958 WMITLV_TAG_STRUC_wmi_sta_smps_force_mode_cmd_fixed_param, 4959 WMITLV_GET_STRUCT_TLVLEN 4960 (wmi_sta_smps_force_mode_cmd_fixed_param)); 4961 4962 cmd->vdev_id = vdev_id; 4963 4964 /* WMI_SMPS_FORCED_MODE values do not directly map 4965 * to SM power save values defined in the specification. 4966 * Make sure to send the right mapping. 4967 */ 4968 switch (value) { 4969 case 0: 4970 cmd->forced_mode = WMI_SMPS_FORCED_MODE_NONE; 4971 break; 4972 case 1: 4973 cmd->forced_mode = WMI_SMPS_FORCED_MODE_DISABLED; 4974 break; 4975 case 2: 4976 cmd->forced_mode = WMI_SMPS_FORCED_MODE_STATIC; 4977 break; 4978 case 3: 4979 cmd->forced_mode = WMI_SMPS_FORCED_MODE_DYNAMIC; 4980 break; 4981 default: 4982 wmi_err("INVALID MIMO PS CONFIG: %d", value); 4983 wmi_buf_free(buf); 4984 return QDF_STATUS_E_FAILURE; 4985 } 4986 4987 wmi_debug("Setting vdev %d value = %u", vdev_id, value); 4988 4989 wmi_mtrace(WMI_STA_SMPS_FORCE_MODE_CMDID, cmd->vdev_id, 0); 4990 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 4991 WMI_STA_SMPS_FORCE_MODE_CMDID); 4992 if (QDF_IS_STATUS_ERROR(ret)) { 4993 wmi_err("Failed to send set Mimo PS ret = %d", ret); 4994 wmi_buf_free(buf); 4995 } 4996 4997 return ret; 4998 } 4999 5000 /** 5001 * send_set_smps_params_cmd_tlv() - set smps params 5002 * @wmi_handle: wmi handle 5003 * @vdev_id: vdev id 5004 * @value: value 5005 * 5006 * Return: QDF_STATUS_SUCCESS for success or error code. 5007 */ 5008 static QDF_STATUS send_set_smps_params_cmd_tlv(wmi_unified_t wmi_handle, uint8_t vdev_id, 5009 int value) 5010 { 5011 QDF_STATUS ret; 5012 wmi_sta_smps_param_cmd_fixed_param *cmd; 5013 wmi_buf_t buf; 5014 uint16_t len = sizeof(*cmd); 5015 5016 buf = wmi_buf_alloc(wmi_handle, len); 5017 if (!buf) 5018 return QDF_STATUS_E_NOMEM; 5019 5020 cmd = (wmi_sta_smps_param_cmd_fixed_param *) wmi_buf_data(buf); 5021 WMITLV_SET_HDR(&cmd->tlv_header, 5022 WMITLV_TAG_STRUC_wmi_sta_smps_param_cmd_fixed_param, 5023 WMITLV_GET_STRUCT_TLVLEN 5024 (wmi_sta_smps_param_cmd_fixed_param)); 5025 5026 cmd->vdev_id = vdev_id; 5027 cmd->value = value & WMI_SMPS_MASK_LOWER_16BITS; 5028 cmd->param = 5029 (value >> WMI_SMPS_PARAM_VALUE_S) & WMI_SMPS_MASK_UPPER_3BITS; 5030 5031 wmi_debug("Setting vdev %d value = %x param %x", vdev_id, cmd->value, 5032 cmd->param); 5033 5034 wmi_mtrace(WMI_STA_SMPS_PARAM_CMDID, cmd->vdev_id, 0); 5035 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 5036 WMI_STA_SMPS_PARAM_CMDID); 5037 if (QDF_IS_STATUS_ERROR(ret)) { 5038 wmi_err("Failed to send set Mimo PS ret = %d", ret); 5039 wmi_buf_free(buf); 5040 } 5041 5042 return ret; 5043 } 5044 5045 /** 5046 * send_get_temperature_cmd_tlv() - get pdev temperature req 5047 * @wmi_handle: wmi handle 5048 * 5049 * Return: QDF_STATUS_SUCCESS for success or error code. 5050 */ 5051 static QDF_STATUS send_get_temperature_cmd_tlv(wmi_unified_t wmi_handle) 5052 { 5053 wmi_pdev_get_temperature_cmd_fixed_param *cmd; 5054 wmi_buf_t wmi_buf; 5055 uint32_t len = sizeof(wmi_pdev_get_temperature_cmd_fixed_param); 5056 uint8_t *buf_ptr; 5057 5058 if (!wmi_handle) { 5059 wmi_err("WMI is closed, can not issue cmd"); 5060 return QDF_STATUS_E_INVAL; 5061 } 5062 5063 wmi_buf = wmi_buf_alloc(wmi_handle, len); 5064 if (!wmi_buf) 5065 return QDF_STATUS_E_NOMEM; 5066 5067 buf_ptr = (uint8_t *) wmi_buf_data(wmi_buf); 5068 5069 cmd = (wmi_pdev_get_temperature_cmd_fixed_param *) buf_ptr; 5070 WMITLV_SET_HDR(&cmd->tlv_header, 5071 WMITLV_TAG_STRUC_wmi_pdev_get_temperature_cmd_fixed_param, 5072 WMITLV_GET_STRUCT_TLVLEN 5073 (wmi_pdev_get_temperature_cmd_fixed_param)); 5074 5075 wmi_mtrace(WMI_PDEV_GET_TEMPERATURE_CMDID, NO_SESSION, 0); 5076 if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len, 5077 WMI_PDEV_GET_TEMPERATURE_CMDID)) { 5078 wmi_err("Failed to send get temperature command"); 5079 wmi_buf_free(wmi_buf); 5080 return QDF_STATUS_E_FAILURE; 5081 } 5082 5083 return QDF_STATUS_SUCCESS; 5084 } 5085 5086 /** 5087 * send_set_sta_uapsd_auto_trig_cmd_tlv() - set uapsd auto trigger command 5088 * @wmi_handle: wmi handle 5089 * @param: UAPSD trigger parameters 5090 * 5091 * This function sets the trigger 5092 * uapsd params such as service interval, delay interval 5093 * and suspend interval which will be used by the firmware 5094 * to send trigger frames periodically when there is no 5095 * traffic on the transmit side. 5096 * 5097 * Return: QDF_STATUS_SUCCESS for success or error code. 5098 */ 5099 static QDF_STATUS send_set_sta_uapsd_auto_trig_cmd_tlv(wmi_unified_t wmi_handle, 5100 struct sta_uapsd_trig_params *param) 5101 { 5102 wmi_sta_uapsd_auto_trig_cmd_fixed_param *cmd; 5103 QDF_STATUS ret; 5104 uint32_t param_len = param->num_ac * sizeof(wmi_sta_uapsd_auto_trig_param); 5105 uint32_t cmd_len = sizeof(*cmd) + param_len + WMI_TLV_HDR_SIZE; 5106 uint32_t i; 5107 wmi_buf_t buf; 5108 uint8_t *buf_ptr; 5109 struct sta_uapsd_params *uapsd_param; 5110 wmi_sta_uapsd_auto_trig_param *trig_param; 5111 5112 buf = wmi_buf_alloc(wmi_handle, cmd_len); 5113 if (!buf) 5114 return QDF_STATUS_E_NOMEM; 5115 5116 buf_ptr = (uint8_t *) wmi_buf_data(buf); 5117 cmd = (wmi_sta_uapsd_auto_trig_cmd_fixed_param *) buf_ptr; 5118 WMITLV_SET_HDR(&cmd->tlv_header, 5119 WMITLV_TAG_STRUC_wmi_sta_uapsd_auto_trig_cmd_fixed_param, 5120 WMITLV_GET_STRUCT_TLVLEN 5121 (wmi_sta_uapsd_auto_trig_cmd_fixed_param)); 5122 cmd->vdev_id = param->vdevid; 5123 cmd->num_ac = param->num_ac; 5124 WMI_CHAR_ARRAY_TO_MAC_ADDR(param->peer_addr, &cmd->peer_macaddr); 5125 5126 /* TLV indicating array of structures to follow */ 5127 buf_ptr += sizeof(*cmd); 5128 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, param_len); 5129 5130 buf_ptr += WMI_TLV_HDR_SIZE; 5131 5132 /* 5133 * Update tag and length for uapsd auto trigger params (this will take 5134 * care of updating tag and length if it is not pre-filled by caller). 5135 */ 5136 uapsd_param = (struct sta_uapsd_params *)param->auto_triggerparam; 5137 trig_param = (wmi_sta_uapsd_auto_trig_param *)buf_ptr; 5138 for (i = 0; i < param->num_ac; i++) { 5139 WMITLV_SET_HDR((buf_ptr + 5140 (i * sizeof(wmi_sta_uapsd_auto_trig_param))), 5141 WMITLV_TAG_STRUC_wmi_sta_uapsd_auto_trig_param, 5142 WMITLV_GET_STRUCT_TLVLEN 5143 (wmi_sta_uapsd_auto_trig_param)); 5144 trig_param->wmm_ac = uapsd_param->wmm_ac; 5145 trig_param->user_priority = uapsd_param->user_priority; 5146 trig_param->service_interval = uapsd_param->service_interval; 5147 trig_param->suspend_interval = uapsd_param->suspend_interval; 5148 trig_param->delay_interval = uapsd_param->delay_interval; 5149 trig_param++; 5150 uapsd_param++; 5151 } 5152 5153 wmi_mtrace(WMI_STA_UAPSD_AUTO_TRIG_CMDID, cmd->vdev_id, 0); 5154 ret = wmi_unified_cmd_send(wmi_handle, buf, cmd_len, 5155 WMI_STA_UAPSD_AUTO_TRIG_CMDID); 5156 if (QDF_IS_STATUS_ERROR(ret)) { 5157 wmi_err("Failed to send set uapsd param ret = %d", ret); 5158 wmi_buf_free(buf); 5159 } 5160 5161 return ret; 5162 } 5163 5164 /** 5165 * send_set_thermal_mgmt_cmd_tlv() - set thermal mgmt command to fw 5166 * @wmi_handle: Pointer to wmi handle 5167 * @thermal_info: Thermal command information 5168 * 5169 * This function sends the thermal management command 5170 * to the firmware 5171 * 5172 * Return: QDF_STATUS_SUCCESS for success otherwise failure 5173 */ 5174 static QDF_STATUS send_set_thermal_mgmt_cmd_tlv(wmi_unified_t wmi_handle, 5175 struct thermal_cmd_params *thermal_info) 5176 { 5177 wmi_thermal_mgmt_cmd_fixed_param *cmd = NULL; 5178 wmi_buf_t buf = NULL; 5179 QDF_STATUS status; 5180 uint32_t len = 0; 5181 uint8_t action; 5182 5183 switch (thermal_info->thermal_action) { 5184 case THERMAL_MGMT_ACTION_DEFAULT: 5185 action = WMI_THERMAL_MGMT_ACTION_DEFAULT; 5186 break; 5187 5188 case THERMAL_MGMT_ACTION_HALT_TRAFFIC: 5189 action = WMI_THERMAL_MGMT_ACTION_HALT_TRAFFIC; 5190 break; 5191 5192 case THERMAL_MGMT_ACTION_NOTIFY_HOST: 5193 action = WMI_THERMAL_MGMT_ACTION_NOTIFY_HOST; 5194 break; 5195 5196 case THERMAL_MGMT_ACTION_CHAINSCALING: 5197 action = WMI_THERMAL_MGMT_ACTION_CHAINSCALING; 5198 break; 5199 5200 default: 5201 wmi_err("Invalid thermal_action code %d", 5202 thermal_info->thermal_action); 5203 return QDF_STATUS_E_FAILURE; 5204 } 5205 5206 len = sizeof(*cmd); 5207 5208 buf = wmi_buf_alloc(wmi_handle, len); 5209 if (!buf) 5210 return QDF_STATUS_E_FAILURE; 5211 5212 cmd = (wmi_thermal_mgmt_cmd_fixed_param *) wmi_buf_data(buf); 5213 5214 WMITLV_SET_HDR(&cmd->tlv_header, 5215 WMITLV_TAG_STRUC_wmi_thermal_mgmt_cmd_fixed_param, 5216 WMITLV_GET_STRUCT_TLVLEN 5217 (wmi_thermal_mgmt_cmd_fixed_param)); 5218 5219 cmd->lower_thresh_degreeC = thermal_info->min_temp; 5220 cmd->upper_thresh_degreeC = thermal_info->max_temp; 5221 cmd->enable = thermal_info->thermal_enable; 5222 cmd->action = action; 5223 5224 wmi_debug("TM Sending thermal mgmt cmd: low temp %d, upper temp %d, enabled %d action %d", 5225 cmd->lower_thresh_degreeC, cmd->upper_thresh_degreeC, 5226 cmd->enable, cmd->action); 5227 5228 wmi_mtrace(WMI_THERMAL_MGMT_CMDID, NO_SESSION, 0); 5229 status = wmi_unified_cmd_send(wmi_handle, buf, len, 5230 WMI_THERMAL_MGMT_CMDID); 5231 if (QDF_IS_STATUS_ERROR(status)) { 5232 wmi_buf_free(buf); 5233 wmi_err("Failed to send thermal mgmt command"); 5234 } 5235 5236 return status; 5237 } 5238 5239 /** 5240 * send_lro_config_cmd_tlv() - process the LRO config command 5241 * @wmi_handle: Pointer to WMI handle 5242 * @wmi_lro_cmd: Pointer to LRO configuration parameters 5243 * 5244 * This function sends down the LRO configuration parameters to 5245 * the firmware to enable LRO, sets the TCP flags and sets the 5246 * seed values for the toeplitz hash generation 5247 * 5248 * Return: QDF_STATUS_SUCCESS for success otherwise failure 5249 */ 5250 static QDF_STATUS send_lro_config_cmd_tlv(wmi_unified_t wmi_handle, 5251 struct wmi_lro_config_cmd_t *wmi_lro_cmd) 5252 { 5253 wmi_lro_info_cmd_fixed_param *cmd; 5254 wmi_buf_t buf; 5255 QDF_STATUS status; 5256 uint8_t pdev_id = wmi_lro_cmd->pdev_id; 5257 5258 buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd)); 5259 if (!buf) 5260 return QDF_STATUS_E_FAILURE; 5261 5262 cmd = (wmi_lro_info_cmd_fixed_param *) wmi_buf_data(buf); 5263 5264 WMITLV_SET_HDR(&cmd->tlv_header, 5265 WMITLV_TAG_STRUC_wmi_lro_info_cmd_fixed_param, 5266 WMITLV_GET_STRUCT_TLVLEN(wmi_lro_info_cmd_fixed_param)); 5267 5268 cmd->lro_enable = wmi_lro_cmd->lro_enable; 5269 WMI_LRO_INFO_TCP_FLAG_VALS_SET(cmd->tcp_flag_u32, 5270 wmi_lro_cmd->tcp_flag); 5271 WMI_LRO_INFO_TCP_FLAGS_MASK_SET(cmd->tcp_flag_u32, 5272 wmi_lro_cmd->tcp_flag_mask); 5273 cmd->toeplitz_hash_ipv4_0_3 = 5274 wmi_lro_cmd->toeplitz_hash_ipv4[0]; 5275 cmd->toeplitz_hash_ipv4_4_7 = 5276 wmi_lro_cmd->toeplitz_hash_ipv4[1]; 5277 cmd->toeplitz_hash_ipv4_8_11 = 5278 wmi_lro_cmd->toeplitz_hash_ipv4[2]; 5279 cmd->toeplitz_hash_ipv4_12_15 = 5280 wmi_lro_cmd->toeplitz_hash_ipv4[3]; 5281 cmd->toeplitz_hash_ipv4_16 = 5282 wmi_lro_cmd->toeplitz_hash_ipv4[4]; 5283 5284 cmd->toeplitz_hash_ipv6_0_3 = 5285 wmi_lro_cmd->toeplitz_hash_ipv6[0]; 5286 cmd->toeplitz_hash_ipv6_4_7 = 5287 wmi_lro_cmd->toeplitz_hash_ipv6[1]; 5288 cmd->toeplitz_hash_ipv6_8_11 = 5289 wmi_lro_cmd->toeplitz_hash_ipv6[2]; 5290 cmd->toeplitz_hash_ipv6_12_15 = 5291 wmi_lro_cmd->toeplitz_hash_ipv6[3]; 5292 cmd->toeplitz_hash_ipv6_16_19 = 5293 wmi_lro_cmd->toeplitz_hash_ipv6[4]; 5294 cmd->toeplitz_hash_ipv6_20_23 = 5295 wmi_lro_cmd->toeplitz_hash_ipv6[5]; 5296 cmd->toeplitz_hash_ipv6_24_27 = 5297 wmi_lro_cmd->toeplitz_hash_ipv6[6]; 5298 cmd->toeplitz_hash_ipv6_28_31 = 5299 wmi_lro_cmd->toeplitz_hash_ipv6[7]; 5300 cmd->toeplitz_hash_ipv6_32_35 = 5301 wmi_lro_cmd->toeplitz_hash_ipv6[8]; 5302 cmd->toeplitz_hash_ipv6_36_39 = 5303 wmi_lro_cmd->toeplitz_hash_ipv6[9]; 5304 cmd->toeplitz_hash_ipv6_40 = 5305 wmi_lro_cmd->toeplitz_hash_ipv6[10]; 5306 5307 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 5308 wmi_handle, 5309 pdev_id); 5310 wmi_debug("WMI_LRO_CONFIG: lro_enable %d, tcp_flag 0x%x, pdev_id: %d", 5311 cmd->lro_enable, cmd->tcp_flag_u32, cmd->pdev_id); 5312 5313 wmi_mtrace(WMI_LRO_CONFIG_CMDID, NO_SESSION, 0); 5314 status = wmi_unified_cmd_send(wmi_handle, buf, 5315 sizeof(*cmd), WMI_LRO_CONFIG_CMDID); 5316 if (QDF_IS_STATUS_ERROR(status)) { 5317 wmi_buf_free(buf); 5318 wmi_err("Failed to send WMI_LRO_CONFIG_CMDID"); 5319 } 5320 5321 return status; 5322 } 5323 5324 /** 5325 * send_peer_rate_report_cmd_tlv() - process the peer rate report command 5326 * @wmi_handle: Pointer to wmi handle 5327 * @rate_report_params: Pointer to peer rate report parameters 5328 * 5329 * 5330 * Return: QDF_STATUS_SUCCESS for success otherwise failure 5331 */ 5332 static QDF_STATUS send_peer_rate_report_cmd_tlv(wmi_unified_t wmi_handle, 5333 struct wmi_peer_rate_report_params *rate_report_params) 5334 { 5335 wmi_peer_set_rate_report_condition_fixed_param *cmd = NULL; 5336 wmi_buf_t buf = NULL; 5337 QDF_STATUS status = 0; 5338 uint32_t len = 0; 5339 uint32_t i, j; 5340 5341 len = sizeof(*cmd); 5342 5343 buf = wmi_buf_alloc(wmi_handle, len); 5344 if (!buf) 5345 return QDF_STATUS_E_FAILURE; 5346 5347 cmd = (wmi_peer_set_rate_report_condition_fixed_param *) 5348 wmi_buf_data(buf); 5349 5350 WMITLV_SET_HDR( 5351 &cmd->tlv_header, 5352 WMITLV_TAG_STRUC_wmi_peer_set_rate_report_condition_fixed_param, 5353 WMITLV_GET_STRUCT_TLVLEN( 5354 wmi_peer_set_rate_report_condition_fixed_param)); 5355 5356 cmd->enable_rate_report = rate_report_params->rate_report_enable; 5357 cmd->report_backoff_time = rate_report_params->backoff_time; 5358 cmd->report_timer_period = rate_report_params->timer_period; 5359 for (i = 0; i < PEER_RATE_REPORT_COND_MAX_NUM; i++) { 5360 cmd->cond_per_phy[i].val_cond_flags = 5361 rate_report_params->report_per_phy[i].cond_flags; 5362 cmd->cond_per_phy[i].rate_delta.min_delta = 5363 rate_report_params->report_per_phy[i].delta.delta_min; 5364 cmd->cond_per_phy[i].rate_delta.percentage = 5365 rate_report_params->report_per_phy[i].delta.percent; 5366 for (j = 0; j < MAX_NUM_OF_RATE_THRESH; j++) { 5367 cmd->cond_per_phy[i].rate_threshold[j] = 5368 rate_report_params->report_per_phy[i]. 5369 report_rate_threshold[j]; 5370 } 5371 } 5372 5373 wmi_debug("enable %d backoff_time %d period %d", 5374 cmd->enable_rate_report, 5375 cmd->report_backoff_time, cmd->report_timer_period); 5376 5377 wmi_mtrace(WMI_PEER_SET_RATE_REPORT_CONDITION_CMDID, NO_SESSION, 0); 5378 status = wmi_unified_cmd_send(wmi_handle, buf, len, 5379 WMI_PEER_SET_RATE_REPORT_CONDITION_CMDID); 5380 if (QDF_IS_STATUS_ERROR(status)) { 5381 wmi_buf_free(buf); 5382 wmi_err("Failed to send peer_set_report_cond command"); 5383 } 5384 return status; 5385 } 5386 5387 /** 5388 * send_process_update_edca_param_cmd_tlv() - update EDCA params 5389 * @wmi_handle: wmi handle 5390 * @vdev_id: vdev id. 5391 * @mu_edca_param: true if these are MU EDCA params 5392 * @wmm_vparams: edca parameters 5393 * 5394 * This function updates EDCA parameters to the target 5395 * 5396 * Return: CDF Status 5397 */ 5398 static QDF_STATUS send_process_update_edca_param_cmd_tlv(wmi_unified_t wmi_handle, 5399 uint8_t vdev_id, bool mu_edca_param, 5400 struct wmi_host_wme_vparams wmm_vparams[WMI_MAX_NUM_AC]) 5401 { 5402 uint8_t *buf_ptr; 5403 wmi_buf_t buf; 5404 wmi_vdev_set_wmm_params_cmd_fixed_param *cmd; 5405 wmi_wmm_vparams *wmm_param; 5406 struct wmi_host_wme_vparams *twmm_param; 5407 int len = sizeof(*cmd); 5408 int ac; 5409 5410 buf = wmi_buf_alloc(wmi_handle, len); 5411 5412 if (!buf) 5413 return QDF_STATUS_E_NOMEM; 5414 5415 buf_ptr = (uint8_t *) wmi_buf_data(buf); 5416 cmd = (wmi_vdev_set_wmm_params_cmd_fixed_param *) buf_ptr; 5417 WMITLV_SET_HDR(&cmd->tlv_header, 5418 WMITLV_TAG_STRUC_wmi_vdev_set_wmm_params_cmd_fixed_param, 5419 WMITLV_GET_STRUCT_TLVLEN 5420 (wmi_vdev_set_wmm_params_cmd_fixed_param)); 5421 cmd->vdev_id = vdev_id; 5422 cmd->wmm_param_type = mu_edca_param; 5423 5424 for (ac = 0; ac < WMI_MAX_NUM_AC; ac++) { 5425 wmm_param = (wmi_wmm_vparams *) (&cmd->wmm_params[ac]); 5426 twmm_param = (struct wmi_host_wme_vparams *) (&wmm_vparams[ac]); 5427 WMITLV_SET_HDR(&wmm_param->tlv_header, 5428 WMITLV_TAG_STRUC_wmi_vdev_set_wmm_params_cmd_fixed_param, 5429 WMITLV_GET_STRUCT_TLVLEN(wmi_wmm_vparams)); 5430 wmm_param->cwmin = twmm_param->cwmin; 5431 wmm_param->cwmax = twmm_param->cwmax; 5432 wmm_param->aifs = twmm_param->aifs; 5433 if (mu_edca_param) 5434 wmm_param->mu_edca_timer = twmm_param->mu_edca_timer; 5435 else 5436 wmm_param->txoplimit = twmm_param->txoplimit; 5437 wmm_param->acm = twmm_param->acm; 5438 wmm_param->no_ack = twmm_param->noackpolicy; 5439 } 5440 5441 wmi_mtrace(WMI_VDEV_SET_WMM_PARAMS_CMDID, cmd->vdev_id, 0); 5442 if (wmi_unified_cmd_send(wmi_handle, buf, len, 5443 WMI_VDEV_SET_WMM_PARAMS_CMDID)) 5444 goto fail; 5445 5446 return QDF_STATUS_SUCCESS; 5447 5448 fail: 5449 wmi_buf_free(buf); 5450 wmi_err("Failed to set WMM Parameters"); 5451 return QDF_STATUS_E_FAILURE; 5452 } 5453 5454 static WMI_EDCA_PARAM_TYPE 5455 wmi_convert_edca_pifs_param_type(enum host_edca_param_type type) 5456 { 5457 switch (type) { 5458 case HOST_EDCA_PARAM_TYPE_AGGRESSIVE: 5459 return WMI_EDCA_PARAM_TYPE_AGGRESSIVE; 5460 case HOST_EDCA_PARAM_TYPE_PIFS: 5461 return WMI_EDCA_PARAM_TYPE_PIFS; 5462 default: 5463 return WMI_EDCA_PARAM_TYPE_AGGRESSIVE; 5464 } 5465 } 5466 5467 /** 5468 * send_update_edca_pifs_param_cmd_tlv() - update EDCA params 5469 * @wmi_handle: wmi handle 5470 * @edca_pifs: edca/pifs parameters 5471 * 5472 * This function updates EDCA/PIFS parameters to the target 5473 * 5474 * Return: QDF Status 5475 */ 5476 5477 static QDF_STATUS 5478 send_update_edca_pifs_param_cmd_tlv(wmi_unified_t wmi_handle, 5479 struct edca_pifs_vparam *edca_pifs) 5480 { 5481 uint8_t *buf_ptr; 5482 wmi_buf_t buf = NULL; 5483 wmi_vdev_set_twt_edca_params_cmd_fixed_param *cmd; 5484 wmi_wmm_params *wmm_params; 5485 wmi_pifs_params *pifs_params; 5486 uint16_t len; 5487 5488 if (!edca_pifs) { 5489 wmi_debug("edca_pifs is NULL"); 5490 return QDF_STATUS_E_FAILURE; 5491 } 5492 5493 len = sizeof(wmi_vdev_set_twt_edca_params_cmd_fixed_param); 5494 if (edca_pifs->param.edca_param_type == 5495 HOST_EDCA_PARAM_TYPE_AGGRESSIVE) { 5496 len += WMI_TLV_HDR_SIZE; 5497 len += sizeof(wmi_wmm_params); 5498 } else { 5499 len += WMI_TLV_HDR_SIZE; 5500 } 5501 if (edca_pifs->param.edca_param_type == 5502 HOST_EDCA_PARAM_TYPE_PIFS) { 5503 len += WMI_TLV_HDR_SIZE; 5504 len += sizeof(wmi_pifs_params); 5505 } else { 5506 len += WMI_TLV_HDR_SIZE; 5507 } 5508 5509 buf = wmi_buf_alloc(wmi_handle, len); 5510 5511 if (!buf) 5512 return QDF_STATUS_E_NOMEM; 5513 5514 cmd = (wmi_vdev_set_twt_edca_params_cmd_fixed_param *)wmi_buf_data(buf); 5515 buf_ptr = (uint8_t *)cmd; 5516 5517 WMITLV_SET_HDR(&cmd->tlv_header, 5518 WMITLV_TAG_STRUC_wmi_vdev_set_twt_edca_params_cmd_fixed_param, 5519 WMITLV_GET_STRUCT_TLVLEN 5520 (wmi_vdev_set_twt_edca_params_cmd_fixed_param)); 5521 5522 cmd->vdev_id = edca_pifs->vdev_id; 5523 cmd->type = wmi_convert_edca_pifs_param_type( 5524 edca_pifs->param.edca_param_type); 5525 buf_ptr += sizeof(wmi_vdev_set_twt_edca_params_cmd_fixed_param); 5526 5527 if (cmd->type == WMI_EDCA_PARAM_TYPE_AGGRESSIVE) { 5528 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 5529 sizeof(*wmm_params)); 5530 buf_ptr += WMI_TLV_HDR_SIZE; 5531 wmm_params = (wmi_wmm_params *)buf_ptr; 5532 WMITLV_SET_HDR(&wmm_params->tlv_header, 5533 WMITLV_TAG_STRUC_wmi_wmm_params, 5534 WMITLV_GET_STRUCT_TLVLEN(wmi_wmm_params)); 5535 5536 wmm_params->cwmin = 5537 BIT(edca_pifs->param.edca_pifs_param.eparam.acvo_cwmin) - 1; 5538 wmm_params->cwmax = 5539 BIT(edca_pifs->param.edca_pifs_param.eparam.acvo_cwmax) - 1; 5540 wmm_params->aifs = 5541 edca_pifs->param.edca_pifs_param.eparam.acvo_aifsn - 1; 5542 wmm_params->txoplimit = 5543 edca_pifs->param.edca_pifs_param.eparam.acvo_txoplimit; 5544 wmm_params->acm = 5545 edca_pifs->param.edca_pifs_param.eparam.acvo_acm; 5546 wmm_params->no_ack = 0; 5547 wmi_debug("vdev_id %d type %d cwmin %d cwmax %d aifsn %d txoplimit %d acm %d no_ack %d", 5548 cmd->vdev_id, cmd->type, wmm_params->cwmin, 5549 wmm_params->cwmax, wmm_params->aifs, 5550 wmm_params->txoplimit, wmm_params->acm, 5551 wmm_params->no_ack); 5552 buf_ptr += sizeof(*wmm_params); 5553 } else { 5554 /* set zero TLV's for wmm_params */ 5555 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 5556 WMITLV_GET_STRUCT_TLVLEN(0)); 5557 buf_ptr += WMI_TLV_HDR_SIZE; 5558 } 5559 if (cmd->type == WMI_EDCA_PARAM_TYPE_PIFS) { 5560 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 5561 sizeof(*pifs_params)); 5562 buf_ptr += WMI_TLV_HDR_SIZE; 5563 pifs_params = (wmi_pifs_params *)buf_ptr; 5564 WMITLV_SET_HDR(&pifs_params->tlv_header, 5565 WMITLV_TAG_STRUC_wmi_pifs_params, 5566 WMITLV_GET_STRUCT_TLVLEN(wmi_pifs_params)); 5567 5568 pifs_params->sap_pifs_offset = 5569 edca_pifs->param.edca_pifs_param.pparam.sap_pifs_offset; 5570 pifs_params->leb_pifs_offset = 5571 edca_pifs->param.edca_pifs_param.pparam.leb_pifs_offset; 5572 pifs_params->reb_pifs_offset = 5573 edca_pifs->param.edca_pifs_param.pparam.reb_pifs_offset; 5574 wmi_debug("vdev_id %d type %d sap_offset %d leb_offset %d reb_offset %d", 5575 cmd->vdev_id, cmd->type, pifs_params->sap_pifs_offset, 5576 pifs_params->leb_pifs_offset, 5577 pifs_params->reb_pifs_offset); 5578 } else { 5579 /* set zero TLV's for pifs_params */ 5580 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 5581 WMITLV_GET_STRUCT_TLVLEN(0)); 5582 buf_ptr += WMI_TLV_HDR_SIZE; 5583 } 5584 5585 wmi_mtrace(WMI_VDEV_SET_TWT_EDCA_PARAMS_CMDID, cmd->vdev_id, 0); 5586 if (wmi_unified_cmd_send(wmi_handle, buf, len, 5587 WMI_VDEV_SET_TWT_EDCA_PARAMS_CMDID)) 5588 goto fail; 5589 5590 return QDF_STATUS_SUCCESS; 5591 5592 fail: 5593 wmi_buf_free(buf); 5594 wmi_err("Failed to set EDCA/PIFS Parameters"); 5595 return QDF_STATUS_E_FAILURE; 5596 } 5597 5598 /** 5599 * extract_csa_ie_received_ev_params_tlv() - extract csa IE received event 5600 * @wmi_handle: wmi handle 5601 * @evt_buf: pointer to event buffer 5602 * @vdev_id: VDEV ID 5603 * @csa_event: csa event data 5604 * 5605 * Return: QDF_STATUS_SUCCESS on success, QDF_STATUS_E_** on error 5606 */ 5607 static QDF_STATUS 5608 extract_csa_ie_received_ev_params_tlv(wmi_unified_t wmi_handle, 5609 void *evt_buf, uint8_t *vdev_id, 5610 struct csa_offload_params *csa_event) 5611 { 5612 WMI_CSA_IE_RECEIVED_EVENTID_param_tlvs *param_buf; 5613 wmi_csa_event_fixed_param *csa_ev; 5614 struct xcsa_ie *xcsa_ie; 5615 struct csa_ie *csa_ie; 5616 uint8_t *bssid; 5617 bool ret; 5618 5619 param_buf = (WMI_CSA_IE_RECEIVED_EVENTID_param_tlvs *)evt_buf; 5620 if (!param_buf) { 5621 wmi_err("Invalid csa event buffer"); 5622 return QDF_STATUS_E_FAILURE; 5623 } 5624 csa_ev = param_buf->fixed_param; 5625 WMI_MAC_ADDR_TO_CHAR_ARRAY(&csa_ev->i_addr2, 5626 &csa_event->bssid.bytes[0]); 5627 5628 bssid = csa_event->bssid.bytes; 5629 ret = wlan_get_connected_vdev_from_psoc_by_bssid(wmi_handle->soc->wmi_psoc, 5630 bssid, vdev_id); 5631 if (!ret) { 5632 wmi_err("VDEV is not connected with BSSID"); 5633 return QDF_STATUS_E_FAILURE; 5634 } 5635 5636 if (csa_ev->ies_present_flag & WMI_CSA_IE_PRESENT) { 5637 csa_ie = (struct csa_ie *)(&csa_ev->csa_ie[0]); 5638 csa_event->channel = csa_ie->new_channel; 5639 csa_event->switch_mode = csa_ie->switch_mode; 5640 csa_event->ies_present_flag |= MLME_CSA_IE_PRESENT; 5641 } else if (csa_ev->ies_present_flag & WMI_XCSA_IE_PRESENT) { 5642 xcsa_ie = (struct xcsa_ie *)(&csa_ev->xcsa_ie[0]); 5643 csa_event->channel = xcsa_ie->new_channel; 5644 csa_event->switch_mode = xcsa_ie->switch_mode; 5645 csa_event->new_op_class = xcsa_ie->new_class; 5646 csa_event->ies_present_flag |= MLME_XCSA_IE_PRESENT; 5647 } else { 5648 wmi_err("CSA Event error: No CSA IE present"); 5649 return QDF_STATUS_E_INVAL; 5650 } 5651 5652 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", 5653 QDF_MAC_ADDR_REF(csa_event->bssid.bytes), 5654 csa_event->channel, 5655 csa_event->csa_chan_freq, 5656 csa_event->ies_present_flag, 5657 csa_event->new_ch_width, 5658 csa_event->new_ch_freq_seg1, 5659 csa_event->new_ch_freq_seg2, 5660 csa_event->new_op_class); 5661 5662 if (!csa_event->channel) { 5663 wmi_err("CSA Event with channel %d. Ignore !!", 5664 csa_event->channel); 5665 return QDF_STATUS_E_FAILURE; 5666 } 5667 5668 return QDF_STATUS_SUCCESS; 5669 } 5670 5671 #ifdef WLAN_RCC_ENHANCED_AOA_SUPPORT 5672 static void 5673 populate_per_band_aoa_caps(struct wlan_psoc_host_rcc_enh_aoa_caps_ext2 *aoa_cap, 5674 wmi_enhanced_aoa_per_band_caps_param per_band_cap) 5675 { 5676 uint8_t tbl_idx; 5677 uint16_t *gain_array = NULL; 5678 5679 if (per_band_cap.band_info == WMI_AOA_2G) 5680 gain_array = aoa_cap->max_agc_gain_per_tbl_2g; 5681 else if (per_band_cap.band_info == WMI_AOA_5G) 5682 gain_array = aoa_cap->max_agc_gain_per_tbl_5g; 5683 else if (per_band_cap.band_info == WMI_AOA_6G) 5684 gain_array = aoa_cap->max_agc_gain_per_tbl_6g; 5685 5686 if (!gain_array) { 5687 wmi_debug("unhandled AOA BAND TYPE!! fix it"); 5688 return; 5689 } 5690 5691 for (tbl_idx = 0; tbl_idx < aoa_cap->max_agc_gain_tbls; tbl_idx++) 5692 WMI_AOA_MAX_AGC_GAIN_GET(per_band_cap.max_agc_gain, 5693 tbl_idx, 5694 gain_array[tbl_idx]); 5695 } 5696 5697 static void 5698 populate_aoa_caps(struct wmi_unified *wmi_handle, 5699 struct wlan_psoc_host_rcc_enh_aoa_caps_ext2 *aoa_cap, 5700 wmi_enhanced_aoa_caps_param *aoa_caps_param) 5701 { 5702 uint8_t tbl_idx; 5703 5704 aoa_cap->max_agc_gain_tbls = aoa_caps_param->max_agc_gain_tbls; 5705 if (aoa_cap->max_agc_gain_tbls > PSOC_MAX_NUM_AGC_GAIN_TBLS) { 5706 wmi_err("Num gain table > PSOC_MAX_NUM_AGC_GAIN_TBLS cap"); 5707 aoa_cap->max_agc_gain_tbls = PSOC_MAX_NUM_AGC_GAIN_TBLS; 5708 } 5709 5710 if (aoa_cap->max_agc_gain_tbls > WMI_AGC_MAX_GAIN_TABLE_IDX) { 5711 wmi_err("num gain table > WMI_AGC_MAX_GAIN_TABLE_IDX cap"); 5712 aoa_cap->max_agc_gain_tbls = WMI_AGC_MAX_GAIN_TABLE_IDX; 5713 } 5714 5715 for (tbl_idx = 0; tbl_idx < aoa_cap->max_agc_gain_tbls; tbl_idx++) { 5716 WMI_AOA_MAX_BDF_ENTRIES_GET 5717 (aoa_caps_param->max_bdf_gain_entries, 5718 tbl_idx, aoa_cap->max_bdf_entries_per_tbl[tbl_idx]); 5719 } 5720 } 5721 5722 /** 5723 * extract_aoa_caps_tlv() - extract aoa cap tlv 5724 * @wmi_handle: wmi handle 5725 * @event: pointer to event buffer 5726 * @aoa_cap: pointer to structure where capability needs to extracted 5727 * 5728 * Return: QDF_STATUS_SUCCESS on success, QDF_STATUS_E_** on error 5729 */ 5730 static QDF_STATUS 5731 extract_aoa_caps_tlv(struct wmi_unified *wmi_handle, uint8_t *event, 5732 struct wlan_psoc_host_rcc_enh_aoa_caps_ext2 *aoa_cap) 5733 { 5734 int8_t band; 5735 5736 WMI_SERVICE_READY_EXT2_EVENTID_param_tlvs *param_buf; 5737 5738 param_buf = (WMI_SERVICE_READY_EXT2_EVENTID_param_tlvs *)event; 5739 if (!param_buf) { 5740 wmi_err("NULL param buf"); 5741 return QDF_STATUS_E_INVAL; 5742 } 5743 5744 if (!param_buf->aoa_caps_param) { 5745 wmi_debug("NULL aoa_caps_param"); 5746 return QDF_STATUS_E_INVAL; 5747 } 5748 5749 if (!param_buf->num_aoa_per_band_caps_param || 5750 !param_buf->aoa_per_band_caps_param) { 5751 wmi_debug("No aoa_per_band_caps_param"); 5752 return QDF_STATUS_E_INVAL; 5753 } 5754 populate_aoa_caps(wmi_handle, aoa_cap, param_buf->aoa_caps_param); 5755 5756 for (band = 0; band < param_buf->num_aoa_per_band_caps_param; band++) 5757 populate_per_band_aoa_caps 5758 (aoa_cap, param_buf->aoa_per_band_caps_param[band]); 5759 5760 return QDF_STATUS_SUCCESS; 5761 } 5762 #endif /* WLAN_RCC_ENHANCED_AOA_SUPPORT */ 5763 5764 /** 5765 * send_probe_rsp_tmpl_send_cmd_tlv() - send probe response template to fw 5766 * @wmi_handle: wmi handle 5767 * @vdev_id: vdev id 5768 * @probe_rsp_info: probe response info 5769 * 5770 * Return: QDF_STATUS_SUCCESS for success or error code 5771 */ 5772 static QDF_STATUS send_probe_rsp_tmpl_send_cmd_tlv(wmi_unified_t wmi_handle, 5773 uint8_t vdev_id, 5774 struct wmi_probe_resp_params *probe_rsp_info) 5775 { 5776 wmi_prb_tmpl_cmd_fixed_param *cmd; 5777 wmi_bcn_prb_info *bcn_prb_info; 5778 wmi_buf_t wmi_buf; 5779 uint32_t tmpl_len, tmpl_len_aligned, wmi_buf_len; 5780 uint8_t *buf_ptr; 5781 QDF_STATUS ret; 5782 5783 wmi_debug("Send probe response template for vdev %d", vdev_id); 5784 5785 tmpl_len = probe_rsp_info->prb_rsp_template_len; 5786 tmpl_len_aligned = roundup(tmpl_len, sizeof(uint32_t)); 5787 5788 wmi_buf_len = sizeof(wmi_prb_tmpl_cmd_fixed_param) + 5789 sizeof(wmi_bcn_prb_info) + WMI_TLV_HDR_SIZE + 5790 tmpl_len_aligned + 5791 prb_resp_tmpl_ml_info_size(probe_rsp_info); 5792 5793 if (wmi_buf_len > WMI_BEACON_TX_BUFFER_SIZE) { 5794 wmi_err("wmi_buf_len: %d > %d. Can't send wmi cmd", 5795 wmi_buf_len, WMI_BEACON_TX_BUFFER_SIZE); 5796 return QDF_STATUS_E_INVAL; 5797 } 5798 5799 wmi_buf = wmi_buf_alloc(wmi_handle, wmi_buf_len); 5800 if (!wmi_buf) 5801 return QDF_STATUS_E_NOMEM; 5802 5803 buf_ptr = (uint8_t *) wmi_buf_data(wmi_buf); 5804 5805 cmd = (wmi_prb_tmpl_cmd_fixed_param *) buf_ptr; 5806 WMITLV_SET_HDR(&cmd->tlv_header, 5807 WMITLV_TAG_STRUC_wmi_prb_tmpl_cmd_fixed_param, 5808 WMITLV_GET_STRUCT_TLVLEN(wmi_prb_tmpl_cmd_fixed_param)); 5809 cmd->vdev_id = vdev_id; 5810 cmd->buf_len = tmpl_len; 5811 buf_ptr += sizeof(wmi_prb_tmpl_cmd_fixed_param); 5812 5813 bcn_prb_info = (wmi_bcn_prb_info *) buf_ptr; 5814 WMITLV_SET_HDR(&bcn_prb_info->tlv_header, 5815 WMITLV_TAG_STRUC_wmi_bcn_prb_info, 5816 WMITLV_GET_STRUCT_TLVLEN(wmi_bcn_prb_info)); 5817 bcn_prb_info->caps = 0; 5818 bcn_prb_info->erp = 0; 5819 buf_ptr += sizeof(wmi_bcn_prb_info); 5820 5821 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, tmpl_len_aligned); 5822 buf_ptr += WMI_TLV_HDR_SIZE; 5823 qdf_mem_copy(buf_ptr, probe_rsp_info->prb_rsp_template_frm, tmpl_len); 5824 buf_ptr += tmpl_len_aligned; 5825 buf_ptr = prb_resp_tmpl_add_ml_info(buf_ptr, probe_rsp_info); 5826 5827 wmi_mtrace(WMI_PRB_TMPL_CMDID, cmd->vdev_id, 0); 5828 ret = wmi_unified_cmd_send(wmi_handle, 5829 wmi_buf, wmi_buf_len, WMI_PRB_TMPL_CMDID); 5830 if (QDF_IS_STATUS_ERROR(ret)) { 5831 wmi_err("Failed to send PRB RSP tmpl: %d", ret); 5832 wmi_buf_free(wmi_buf); 5833 } 5834 5835 return ret; 5836 } 5837 5838 #if defined(ATH_SUPPORT_WAPI) || defined(FEATURE_WLAN_WAPI) 5839 #define WPI_IV_LEN 16 5840 5841 /** 5842 * wmi_update_wpi_key_counter() - update WAPI tsc and rsc key counters 5843 * 5844 * @dest_tx: destination address of tsc key counter 5845 * @src_tx: source address of tsc key counter 5846 * @dest_rx: destination address of rsc key counter 5847 * @src_rx: source address of rsc key counter 5848 * 5849 * This function copies WAPI tsc and rsc key counters in the wmi buffer. 5850 * 5851 * Return: None 5852 * 5853 */ 5854 static void wmi_update_wpi_key_counter(uint8_t *dest_tx, uint8_t *src_tx, 5855 uint8_t *dest_rx, uint8_t *src_rx) 5856 { 5857 qdf_mem_copy(dest_tx, src_tx, WPI_IV_LEN); 5858 qdf_mem_copy(dest_rx, src_rx, WPI_IV_LEN); 5859 } 5860 #else 5861 static void wmi_update_wpi_key_counter(uint8_t *dest_tx, uint8_t *src_tx, 5862 uint8_t *dest_rx, uint8_t *src_rx) 5863 { 5864 return; 5865 } 5866 #endif 5867 5868 /** 5869 * send_setup_install_key_cmd_tlv() - set key parameters 5870 * @wmi_handle: wmi handle 5871 * @key_params: key parameters 5872 * 5873 * This function fills structure from information 5874 * passed in key_params. 5875 * 5876 * Return: QDF_STATUS_SUCCESS - success 5877 * QDF_STATUS_E_FAILURE - failure 5878 * QDF_STATUS_E_NOMEM - not able to allocate buffer 5879 */ 5880 static QDF_STATUS send_setup_install_key_cmd_tlv(wmi_unified_t wmi_handle, 5881 struct set_key_params *key_params) 5882 { 5883 wmi_vdev_install_key_cmd_fixed_param *cmd; 5884 wmi_buf_t buf; 5885 uint8_t *buf_ptr; 5886 uint32_t len; 5887 uint8_t *key_data; 5888 QDF_STATUS status; 5889 5890 len = sizeof(*cmd) + roundup(key_params->key_len, sizeof(uint32_t)) + 5891 WMI_TLV_HDR_SIZE; 5892 5893 buf = wmi_buf_alloc(wmi_handle, len); 5894 if (!buf) 5895 return QDF_STATUS_E_NOMEM; 5896 5897 buf_ptr = (uint8_t *) wmi_buf_data(buf); 5898 cmd = (wmi_vdev_install_key_cmd_fixed_param *) buf_ptr; 5899 WMITLV_SET_HDR(&cmd->tlv_header, 5900 WMITLV_TAG_STRUC_wmi_vdev_install_key_cmd_fixed_param, 5901 WMITLV_GET_STRUCT_TLVLEN 5902 (wmi_vdev_install_key_cmd_fixed_param)); 5903 cmd->vdev_id = key_params->vdev_id; 5904 cmd->key_ix = key_params->key_idx; 5905 if (key_params->group_key_idx) { 5906 cmd->is_group_key_ix_valid = 1; 5907 cmd->group_key_ix = key_params->group_key_idx; 5908 } 5909 5910 WMI_CHAR_ARRAY_TO_MAC_ADDR(key_params->peer_mac, &cmd->peer_macaddr); 5911 cmd->key_flags |= key_params->key_flags; 5912 cmd->key_cipher = key_params->key_cipher; 5913 if ((key_params->key_txmic_len) && 5914 (key_params->key_rxmic_len)) { 5915 cmd->key_txmic_len = key_params->key_txmic_len; 5916 cmd->key_rxmic_len = key_params->key_rxmic_len; 5917 } 5918 #if defined(ATH_SUPPORT_WAPI) || defined(FEATURE_WLAN_WAPI) 5919 wmi_update_wpi_key_counter(cmd->wpi_key_tsc_counter, 5920 key_params->tx_iv, 5921 cmd->wpi_key_rsc_counter, 5922 key_params->rx_iv); 5923 #endif 5924 buf_ptr += sizeof(wmi_vdev_install_key_cmd_fixed_param); 5925 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, 5926 roundup(key_params->key_len, sizeof(uint32_t))); 5927 key_data = (uint8_t *) (buf_ptr + WMI_TLV_HDR_SIZE); 5928 5929 /* for big endian host, copy engine byte_swap is enabled 5930 * But key_data is in network byte order 5931 * Need to byte swap the key_data - so when copy engine 5932 * does byte_swap - target gets key_data in the correct order 5933 */ 5934 WMI_HOST_IF_MSG_COPY_CHAR_ARRAY((void *)key_data, 5935 (const void *)key_params->key_data, 5936 key_params->key_len); 5937 qdf_mem_copy(&cmd->key_rsc_counter, &key_params->key_rsc_counter, 5938 sizeof(wmi_key_seq_counter)); 5939 cmd->key_len = key_params->key_len; 5940 5941 qdf_mem_copy(&cmd->key_tsc_counter, &key_params->key_tsc_counter, 5942 sizeof(wmi_key_seq_counter)); 5943 wmi_mtrace(WMI_VDEV_INSTALL_KEY_CMDID, cmd->vdev_id, 0); 5944 status = wmi_unified_cmd_send(wmi_handle, buf, len, 5945 WMI_VDEV_INSTALL_KEY_CMDID); 5946 if (QDF_IS_STATUS_ERROR(status)) { 5947 qdf_mem_zero(wmi_buf_data(buf), len); 5948 wmi_buf_free(buf); 5949 } 5950 return status; 5951 } 5952 5953 /** 5954 * send_p2p_go_set_beacon_ie_cmd_tlv() - set beacon IE for p2p go 5955 * @wmi_handle: wmi handle 5956 * @vdev_id: vdev id 5957 * @p2p_ie: p2p IE 5958 * 5959 * Return: QDF_STATUS_SUCCESS for success or error code 5960 */ 5961 static QDF_STATUS send_p2p_go_set_beacon_ie_cmd_tlv(wmi_unified_t wmi_handle, 5962 uint32_t vdev_id, uint8_t *p2p_ie) 5963 { 5964 QDF_STATUS ret; 5965 wmi_p2p_go_set_beacon_ie_fixed_param *cmd; 5966 wmi_buf_t wmi_buf; 5967 uint32_t ie_len, ie_len_aligned, wmi_buf_len; 5968 uint8_t *buf_ptr; 5969 5970 ie_len = (uint32_t) (p2p_ie[1] + 2); 5971 5972 /* More than one P2P IE may be included in a single frame. 5973 If multiple P2P IEs are present, the complete P2P attribute 5974 data consists of the concatenation of the P2P Attribute 5975 fields of the P2P IEs. The P2P Attributes field of each 5976 P2P IE may be any length up to the maximum (251 octets). 5977 In this case host sends one P2P IE to firmware so the length 5978 should not exceed more than 251 bytes 5979 */ 5980 if (ie_len > 251) { 5981 wmi_err("Invalid p2p ie length %u", ie_len); 5982 return QDF_STATUS_E_INVAL; 5983 } 5984 5985 ie_len_aligned = roundup(ie_len, sizeof(uint32_t)); 5986 5987 wmi_buf_len = 5988 sizeof(wmi_p2p_go_set_beacon_ie_fixed_param) + ie_len_aligned + 5989 WMI_TLV_HDR_SIZE; 5990 5991 wmi_buf = wmi_buf_alloc(wmi_handle, wmi_buf_len); 5992 if (!wmi_buf) 5993 return QDF_STATUS_E_NOMEM; 5994 5995 buf_ptr = (uint8_t *) wmi_buf_data(wmi_buf); 5996 5997 cmd = (wmi_p2p_go_set_beacon_ie_fixed_param *) buf_ptr; 5998 WMITLV_SET_HDR(&cmd->tlv_header, 5999 WMITLV_TAG_STRUC_wmi_p2p_go_set_beacon_ie_fixed_param, 6000 WMITLV_GET_STRUCT_TLVLEN 6001 (wmi_p2p_go_set_beacon_ie_fixed_param)); 6002 cmd->vdev_id = vdev_id; 6003 cmd->ie_buf_len = ie_len; 6004 6005 buf_ptr += sizeof(wmi_p2p_go_set_beacon_ie_fixed_param); 6006 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, ie_len_aligned); 6007 buf_ptr += WMI_TLV_HDR_SIZE; 6008 qdf_mem_copy(buf_ptr, p2p_ie, ie_len); 6009 6010 wmi_debug("Sending WMI_P2P_GO_SET_BEACON_IE"); 6011 6012 wmi_mtrace(WMI_P2P_GO_SET_BEACON_IE, cmd->vdev_id, 0); 6013 ret = wmi_unified_cmd_send(wmi_handle, 6014 wmi_buf, wmi_buf_len, 6015 WMI_P2P_GO_SET_BEACON_IE); 6016 if (QDF_IS_STATUS_ERROR(ret)) { 6017 wmi_err("Failed to send bcn tmpl: %d", ret); 6018 wmi_buf_free(wmi_buf); 6019 } 6020 6021 wmi_debug("Successfully sent WMI_P2P_GO_SET_BEACON_IE"); 6022 return ret; 6023 } 6024 6025 /** 6026 * send_scan_probe_setoui_cmd_tlv() - set scan probe OUI 6027 * @wmi_handle: wmi handle 6028 * @psetoui: OUI parameters 6029 * 6030 * set scan probe OUI parameters in firmware 6031 * 6032 * Return: QDF status 6033 */ 6034 static QDF_STATUS send_scan_probe_setoui_cmd_tlv(wmi_unified_t wmi_handle, 6035 struct scan_mac_oui *psetoui) 6036 { 6037 wmi_scan_prob_req_oui_cmd_fixed_param *cmd; 6038 wmi_buf_t wmi_buf; 6039 uint32_t len; 6040 uint8_t *buf_ptr; 6041 uint32_t *oui_buf; 6042 struct probe_req_allowlist_attr *ie_allowlist = &psetoui->ie_allowlist; 6043 6044 len = sizeof(*cmd) + WMI_TLV_HDR_SIZE + 6045 ie_allowlist->num_vendor_oui * sizeof(wmi_vendor_oui); 6046 6047 wmi_buf = wmi_buf_alloc(wmi_handle, len); 6048 if (!wmi_buf) 6049 return QDF_STATUS_E_NOMEM; 6050 6051 buf_ptr = (uint8_t *) wmi_buf_data(wmi_buf); 6052 cmd = (wmi_scan_prob_req_oui_cmd_fixed_param *) buf_ptr; 6053 WMITLV_SET_HDR(&cmd->tlv_header, 6054 WMITLV_TAG_STRUC_wmi_scan_prob_req_oui_cmd_fixed_param, 6055 WMITLV_GET_STRUCT_TLVLEN 6056 (wmi_scan_prob_req_oui_cmd_fixed_param)); 6057 6058 oui_buf = &cmd->prob_req_oui; 6059 qdf_mem_zero(oui_buf, sizeof(cmd->prob_req_oui)); 6060 *oui_buf = psetoui->oui[0] << 16 | psetoui->oui[1] << 8 6061 | psetoui->oui[2]; 6062 wmi_debug("wmi:oui received from hdd %08x", cmd->prob_req_oui); 6063 6064 cmd->vdev_id = psetoui->vdev_id; 6065 cmd->flags = WMI_SCAN_PROBE_OUI_SPOOFED_MAC_IN_PROBE_REQ; 6066 if (psetoui->enb_probe_req_sno_randomization) 6067 cmd->flags |= WMI_SCAN_PROBE_OUI_RANDOM_SEQ_NO_IN_PROBE_REQ; 6068 6069 if (ie_allowlist->allow_list) { 6070 wmi_fill_ie_allowlist_attrs(cmd->ie_bitmap, 6071 &cmd->num_vendor_oui, 6072 ie_allowlist); 6073 cmd->flags |= 6074 WMI_SCAN_PROBE_OUI_ENABLE_IE_WHITELIST_IN_PROBE_REQ; 6075 } 6076 6077 buf_ptr += sizeof(*cmd); 6078 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 6079 ie_allowlist->num_vendor_oui * sizeof(wmi_vendor_oui)); 6080 buf_ptr += WMI_TLV_HDR_SIZE; 6081 6082 if (cmd->num_vendor_oui != 0) { 6083 wmi_fill_vendor_oui(buf_ptr, cmd->num_vendor_oui, 6084 ie_allowlist->voui); 6085 buf_ptr += cmd->num_vendor_oui * sizeof(wmi_vendor_oui); 6086 } 6087 6088 wmi_mtrace(WMI_SCAN_PROB_REQ_OUI_CMDID, cmd->vdev_id, 0); 6089 if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len, 6090 WMI_SCAN_PROB_REQ_OUI_CMDID)) { 6091 wmi_err("Failed to send command WMI_SCAN_PROB_REQ_OUI_CMDID"); 6092 wmi_buf_free(wmi_buf); 6093 return QDF_STATUS_E_FAILURE; 6094 } 6095 return QDF_STATUS_SUCCESS; 6096 } 6097 6098 #ifdef IPA_OFFLOAD 6099 /** send_ipa_offload_control_cmd_tlv() - ipa offload control parameter 6100 * @wmi_handle: wmi handle 6101 * @ipa_offload: ipa offload control parameter 6102 * 6103 * Returns: 0 on success, error number otherwise 6104 */ 6105 static QDF_STATUS send_ipa_offload_control_cmd_tlv(wmi_unified_t wmi_handle, 6106 struct ipa_uc_offload_control_params *ipa_offload) 6107 { 6108 wmi_ipa_offload_enable_disable_cmd_fixed_param *cmd; 6109 wmi_buf_t wmi_buf; 6110 uint32_t len; 6111 u_int8_t *buf_ptr; 6112 6113 len = sizeof(*cmd); 6114 wmi_buf = wmi_buf_alloc(wmi_handle, len); 6115 if (!wmi_buf) 6116 return QDF_STATUS_E_NOMEM; 6117 6118 wmi_debug("offload_type=%d, enable=%d", 6119 ipa_offload->offload_type, ipa_offload->enable); 6120 6121 buf_ptr = (u_int8_t *)wmi_buf_data(wmi_buf); 6122 6123 cmd = (wmi_ipa_offload_enable_disable_cmd_fixed_param *)buf_ptr; 6124 WMITLV_SET_HDR(&cmd->tlv_header, 6125 WMITLV_TAG_STRUCT_wmi_ipa_offload_enable_disable_cmd_fixed_param, 6126 WMITLV_GET_STRUCT_TLVLEN( 6127 wmi_ipa_offload_enable_disable_cmd_fixed_param)); 6128 6129 cmd->offload_type = ipa_offload->offload_type; 6130 cmd->vdev_id = ipa_offload->vdev_id; 6131 cmd->enable = ipa_offload->enable; 6132 6133 wmi_mtrace(WMI_IPA_OFFLOAD_ENABLE_DISABLE_CMDID, cmd->vdev_id, 0); 6134 if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len, 6135 WMI_IPA_OFFLOAD_ENABLE_DISABLE_CMDID)) { 6136 wmi_err("Failed to send WMI_IPA_OFFLOAD_ENABLE_DISABLE_CMDID"); 6137 wmi_buf_free(wmi_buf); 6138 return QDF_STATUS_E_FAILURE; 6139 } 6140 6141 return QDF_STATUS_SUCCESS; 6142 } 6143 #endif 6144 6145 /** 6146 * send_pno_stop_cmd_tlv() - PNO stop request 6147 * @wmi_handle: wmi handle 6148 * @vdev_id: vdev id 6149 * 6150 * This function request FW to stop ongoing PNO operation. 6151 * 6152 * Return: QDF status 6153 */ 6154 static QDF_STATUS send_pno_stop_cmd_tlv(wmi_unified_t wmi_handle, uint8_t vdev_id) 6155 { 6156 wmi_nlo_config_cmd_fixed_param *cmd; 6157 int32_t len = sizeof(*cmd); 6158 wmi_buf_t buf; 6159 uint8_t *buf_ptr; 6160 int ret; 6161 6162 /* 6163 * TLV place holder for array of structures nlo_configured_parameters 6164 * TLV place holder for array of uint32_t channel_list 6165 * TLV place holder for chnl prediction cfg 6166 */ 6167 len += WMI_TLV_HDR_SIZE + WMI_TLV_HDR_SIZE + WMI_TLV_HDR_SIZE; 6168 buf = wmi_buf_alloc(wmi_handle, len); 6169 if (!buf) 6170 return QDF_STATUS_E_NOMEM; 6171 6172 cmd = (wmi_nlo_config_cmd_fixed_param *) wmi_buf_data(buf); 6173 buf_ptr = (uint8_t *) cmd; 6174 6175 WMITLV_SET_HDR(&cmd->tlv_header, 6176 WMITLV_TAG_STRUC_wmi_nlo_config_cmd_fixed_param, 6177 WMITLV_GET_STRUCT_TLVLEN 6178 (wmi_nlo_config_cmd_fixed_param)); 6179 6180 cmd->vdev_id = vdev_id; 6181 cmd->flags = WMI_NLO_CONFIG_STOP; 6182 buf_ptr += sizeof(*cmd); 6183 6184 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0); 6185 buf_ptr += WMI_TLV_HDR_SIZE; 6186 6187 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, 0); 6188 buf_ptr += WMI_TLV_HDR_SIZE; 6189 6190 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0); 6191 buf_ptr += WMI_TLV_HDR_SIZE; 6192 6193 wmi_mtrace(WMI_NETWORK_LIST_OFFLOAD_CONFIG_CMDID, cmd->vdev_id, 0); 6194 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 6195 WMI_NETWORK_LIST_OFFLOAD_CONFIG_CMDID); 6196 if (ret) { 6197 wmi_err("Failed to send nlo wmi cmd"); 6198 wmi_buf_free(buf); 6199 return QDF_STATUS_E_FAILURE; 6200 } 6201 6202 return QDF_STATUS_SUCCESS; 6203 } 6204 6205 /** 6206 * send_obss_disable_cmd_tlv() - disable obss scan request 6207 * @wmi_handle: wmi handle 6208 * @vdev_id: vdev id 6209 * 6210 * This function request FW to disable ongoing obss scan operation. 6211 * 6212 * Return: QDF status 6213 */ 6214 static QDF_STATUS send_obss_disable_cmd_tlv(wmi_unified_t wmi_handle, 6215 uint8_t vdev_id) 6216 { 6217 QDF_STATUS status; 6218 wmi_buf_t buf; 6219 wmi_obss_scan_disable_cmd_fixed_param *cmd; 6220 int len = sizeof(*cmd); 6221 6222 buf = wmi_buf_alloc(wmi_handle, len); 6223 if (!buf) 6224 return QDF_STATUS_E_NOMEM; 6225 6226 wmi_debug("cmd %x vdev_id %d", WMI_OBSS_SCAN_DISABLE_CMDID, vdev_id); 6227 6228 cmd = (wmi_obss_scan_disable_cmd_fixed_param *)wmi_buf_data(buf); 6229 WMITLV_SET_HDR(&cmd->tlv_header, 6230 WMITLV_TAG_STRUC_wmi_obss_scan_disable_cmd_fixed_param, 6231 WMITLV_GET_STRUCT_TLVLEN( 6232 wmi_obss_scan_disable_cmd_fixed_param)); 6233 6234 cmd->vdev_id = vdev_id; 6235 status = wmi_unified_cmd_send(wmi_handle, buf, len, 6236 WMI_OBSS_SCAN_DISABLE_CMDID); 6237 if (QDF_IS_STATUS_ERROR(status)) 6238 wmi_buf_free(buf); 6239 6240 return status; 6241 } 6242 6243 /** 6244 * wmi_set_pno_channel_prediction() - Set PNO channel prediction 6245 * @buf_ptr: Buffer passed by upper layers 6246 * @pno: Buffer to be sent to the firmware 6247 * 6248 * Copy the PNO Channel prediction configuration parameters 6249 * passed by the upper layers to a WMI format TLV and send it 6250 * down to the firmware. 6251 * 6252 * Return: None 6253 */ 6254 static void wmi_set_pno_channel_prediction(uint8_t *buf_ptr, 6255 struct pno_scan_req_params *pno) 6256 { 6257 nlo_channel_prediction_cfg *channel_prediction_cfg = 6258 (nlo_channel_prediction_cfg *) buf_ptr; 6259 WMITLV_SET_HDR(&channel_prediction_cfg->tlv_header, 6260 WMITLV_TAG_ARRAY_BYTE, 6261 WMITLV_GET_STRUCT_TLVLEN(nlo_channel_prediction_cfg)); 6262 #ifdef FEATURE_WLAN_SCAN_PNO 6263 channel_prediction_cfg->enable = pno->pno_channel_prediction; 6264 channel_prediction_cfg->top_k_num = pno->top_k_num_of_channels; 6265 channel_prediction_cfg->stationary_threshold = pno->stationary_thresh; 6266 channel_prediction_cfg->full_scan_period_ms = 6267 pno->channel_prediction_full_scan; 6268 #endif 6269 buf_ptr += sizeof(nlo_channel_prediction_cfg); 6270 wmi_debug("enable: %d, top_k_num: %d, stat_thresh: %d, full_scan: %d", 6271 channel_prediction_cfg->enable, 6272 channel_prediction_cfg->top_k_num, 6273 channel_prediction_cfg->stationary_threshold, 6274 channel_prediction_cfg->full_scan_period_ms); 6275 } 6276 6277 /** 6278 * send_cp_stats_cmd_tlv() - Send cp stats wmi command 6279 * @wmi_handle: wmi handle 6280 * @buf_ptr: Buffer passed by upper layers 6281 * @buf_len: Length of passed buffer by upper layer 6282 * 6283 * Copy the buffer passed by the upper layers and send it 6284 * down to the firmware. 6285 * 6286 * Return: None 6287 */ 6288 static QDF_STATUS send_cp_stats_cmd_tlv(wmi_unified_t wmi_handle, 6289 void *buf_ptr, uint32_t buf_len) 6290 { 6291 wmi_buf_t buf = NULL; 6292 QDF_STATUS status; 6293 int len; 6294 uint8_t *data_ptr; 6295 6296 len = buf_len; 6297 buf = wmi_buf_alloc(wmi_handle, len); 6298 if (!buf) 6299 return QDF_STATUS_E_NOMEM; 6300 6301 data_ptr = (uint8_t *)wmi_buf_data(buf); 6302 qdf_mem_copy(data_ptr, buf_ptr, len); 6303 6304 wmi_mtrace(WMI_REQUEST_CTRL_PATH_STATS_CMDID, NO_SESSION, 0); 6305 status = wmi_unified_cmd_send(wmi_handle, buf, 6306 len, WMI_REQUEST_CTRL_PATH_STATS_CMDID); 6307 6308 if (QDF_IS_STATUS_ERROR(status)) { 6309 wmi_buf_free(buf); 6310 return QDF_STATUS_E_FAILURE; 6311 } 6312 return QDF_STATUS_SUCCESS; 6313 } 6314 6315 /** 6316 * send_halphy_stats_cmd_tlv() - Send halphy stats wmi command 6317 * @wmi_handle: wmi handle 6318 * @buf_ptr: Buffer passed by upper layers 6319 * @buf_len: Length of passed buffer by upper layer 6320 * 6321 * Copy the buffer passed by the upper layers and send it 6322 * down to the firmware. 6323 * 6324 * Return: None 6325 */ 6326 static QDF_STATUS send_halphy_stats_cmd_tlv(wmi_unified_t wmi_handle, 6327 void *buf_ptr, uint32_t buf_len) 6328 { 6329 wmi_buf_t buf = NULL; 6330 QDF_STATUS status; 6331 int len; 6332 uint8_t *data_ptr; 6333 6334 len = buf_len; 6335 buf = wmi_buf_alloc(wmi_handle, len); 6336 if (!buf) 6337 return QDF_STATUS_E_NOMEM; 6338 6339 data_ptr = (uint8_t *)wmi_buf_data(buf); 6340 qdf_mem_copy(data_ptr, buf_ptr, len); 6341 6342 wmi_mtrace(WMI_REQUEST_HALPHY_CTRL_PATH_STATS_CMDID, NO_SESSION, 0); 6343 status = wmi_unified_cmd_send(wmi_handle, buf, 6344 len, 6345 WMI_REQUEST_HALPHY_CTRL_PATH_STATS_CMDID); 6346 6347 if (QDF_IS_STATUS_ERROR(status)) { 6348 wmi_buf_free(buf); 6349 return QDF_STATUS_E_FAILURE; 6350 } 6351 return QDF_STATUS_SUCCESS; 6352 } 6353 6354 /** 6355 * extract_cp_stats_more_pending_tlv - api to extract more flag from event data 6356 * @wmi_handle: wmi handle 6357 * @evt_buf: event buffer 6358 * @more_flag: buffer to populate more flag 6359 * 6360 * Return: status of operation 6361 */ 6362 static QDF_STATUS 6363 extract_cp_stats_more_pending_tlv(wmi_unified_t wmi_handle, void *evt_buf, 6364 uint32_t *more_flag) 6365 { 6366 WMI_CTRL_PATH_STATS_EVENTID_param_tlvs *param_buf; 6367 wmi_ctrl_path_stats_event_fixed_param *ev; 6368 6369 param_buf = (WMI_CTRL_PATH_STATS_EVENTID_param_tlvs *)evt_buf; 6370 if (!param_buf) { 6371 wmi_err_rl("param_buf is NULL"); 6372 return QDF_STATUS_E_FAILURE; 6373 } 6374 ev = (wmi_ctrl_path_stats_event_fixed_param *)param_buf->fixed_param; 6375 6376 *more_flag = ev->more; 6377 return QDF_STATUS_SUCCESS; 6378 } 6379 6380 /** 6381 * extract_halphy_stats_end_of_event_tlv - api to extract end_of_event flag 6382 * from event data 6383 * @wmi_handle: wmi handle 6384 * @evt_buf: event buffer 6385 * @end_of_event_flag: buffer to populate end_of_event flag 6386 * 6387 * Return: status of operation 6388 */ 6389 static QDF_STATUS 6390 extract_halphy_stats_end_of_event_tlv(wmi_unified_t wmi_handle, void *evt_buf, 6391 uint32_t *end_of_event_flag) 6392 { 6393 WMI_HALPHY_CTRL_PATH_STATS_EVENTID_param_tlvs *param_buf; 6394 wmi_halphy_ctrl_path_stats_event_fixed_param *ev; 6395 6396 param_buf = (WMI_HALPHY_CTRL_PATH_STATS_EVENTID_param_tlvs *)evt_buf; 6397 if (!param_buf) { 6398 wmi_err_rl("param_buf is NULL"); 6399 return QDF_STATUS_E_FAILURE; 6400 } 6401 ev = (wmi_halphy_ctrl_path_stats_event_fixed_param *) 6402 param_buf->fixed_param; 6403 6404 *end_of_event_flag = ev->end_of_event; 6405 return QDF_STATUS_SUCCESS; 6406 } 6407 6408 /** 6409 * extract_halphy_stats_event_count_tlv() - api to extract event count flag 6410 * from event data 6411 * @wmi_handle: wmi handle 6412 * @evt_buf: event buffer 6413 * @event_count_flag: buffer to populate event_count flag 6414 * 6415 * Return: status of operation 6416 */ 6417 static QDF_STATUS 6418 extract_halphy_stats_event_count_tlv(wmi_unified_t wmi_handle, void *evt_buf, 6419 uint32_t *event_count_flag) 6420 { 6421 WMI_HALPHY_CTRL_PATH_STATS_EVENTID_param_tlvs *param_buf; 6422 wmi_halphy_ctrl_path_stats_event_fixed_param *ev; 6423 6424 param_buf = (WMI_HALPHY_CTRL_PATH_STATS_EVENTID_param_tlvs *)evt_buf; 6425 if (!param_buf) { 6426 wmi_err_rl("param_buf is NULL"); 6427 return QDF_STATUS_E_FAILURE; 6428 } 6429 ev = (wmi_halphy_ctrl_path_stats_event_fixed_param *) 6430 param_buf->fixed_param; 6431 6432 *event_count_flag = ev->event_count; 6433 return QDF_STATUS_SUCCESS; 6434 } 6435 6436 /** 6437 * send_nlo_mawc_cmd_tlv() - Send MAWC NLO configuration 6438 * @wmi_handle: wmi handle 6439 * @params: configuration parameters 6440 * 6441 * Return: QDF_STATUS 6442 */ 6443 static QDF_STATUS send_nlo_mawc_cmd_tlv(wmi_unified_t wmi_handle, 6444 struct nlo_mawc_params *params) 6445 { 6446 wmi_buf_t buf = NULL; 6447 QDF_STATUS status; 6448 int len; 6449 uint8_t *buf_ptr; 6450 wmi_nlo_configure_mawc_cmd_fixed_param *wmi_nlo_mawc_params; 6451 6452 len = sizeof(*wmi_nlo_mawc_params); 6453 buf = wmi_buf_alloc(wmi_handle, len); 6454 if (!buf) 6455 return QDF_STATUS_E_NOMEM; 6456 6457 buf_ptr = (uint8_t *) wmi_buf_data(buf); 6458 wmi_nlo_mawc_params = 6459 (wmi_nlo_configure_mawc_cmd_fixed_param *) buf_ptr; 6460 WMITLV_SET_HDR(&wmi_nlo_mawc_params->tlv_header, 6461 WMITLV_TAG_STRUC_wmi_nlo_configure_mawc_cmd_fixed_param, 6462 WMITLV_GET_STRUCT_TLVLEN 6463 (wmi_nlo_configure_mawc_cmd_fixed_param)); 6464 wmi_nlo_mawc_params->vdev_id = params->vdev_id; 6465 if (params->enable) 6466 wmi_nlo_mawc_params->enable = 1; 6467 else 6468 wmi_nlo_mawc_params->enable = 0; 6469 wmi_nlo_mawc_params->exp_backoff_ratio = params->exp_backoff_ratio; 6470 wmi_nlo_mawc_params->init_scan_interval = params->init_scan_interval; 6471 wmi_nlo_mawc_params->max_scan_interval = params->max_scan_interval; 6472 wmi_debug("MAWC NLO en=%d, vdev=%d, ratio=%d, SCAN init=%d, max=%d", 6473 wmi_nlo_mawc_params->enable, wmi_nlo_mawc_params->vdev_id, 6474 wmi_nlo_mawc_params->exp_backoff_ratio, 6475 wmi_nlo_mawc_params->init_scan_interval, 6476 wmi_nlo_mawc_params->max_scan_interval); 6477 6478 wmi_mtrace(WMI_NLO_CONFIGURE_MAWC_CMDID, NO_SESSION, 0); 6479 status = wmi_unified_cmd_send(wmi_handle, buf, 6480 len, WMI_NLO_CONFIGURE_MAWC_CMDID); 6481 if (QDF_IS_STATUS_ERROR(status)) { 6482 wmi_err("WMI_NLO_CONFIGURE_MAWC_CMDID failed, Error %d", 6483 status); 6484 wmi_buf_free(buf); 6485 return QDF_STATUS_E_FAILURE; 6486 } 6487 6488 return QDF_STATUS_SUCCESS; 6489 } 6490 6491 /** 6492 * wmi_dump_pno_scan_freq_list() - dump frequency list associated with pno 6493 * scan 6494 * @scan_freq_list: frequency list for pno scan 6495 * 6496 * Return: void 6497 */ 6498 static void wmi_dump_pno_scan_freq_list(struct chan_list *scan_freq_list) 6499 { 6500 uint32_t i; 6501 uint8_t info[WMI_MAX_CHAN_INFO_LOG]; 6502 uint32_t len = 0; 6503 struct chan_info *chan_info; 6504 int ret; 6505 6506 wmi_debug("[PNO_SCAN] Total freq %d", scan_freq_list->num_chan); 6507 for (i = 0; i < scan_freq_list->num_chan; i++) { 6508 chan_info = &scan_freq_list->chan[i]; 6509 ret = qdf_scnprintf(info + len, sizeof(info) - len, 6510 " %d[%d]", chan_info->freq, 6511 chan_info->flags); 6512 if (ret <= 0) 6513 break; 6514 len += ret; 6515 if (len >= (sizeof(info) - 20)) { 6516 wmi_nofl_debug("Freq[flag]:%s", 6517 info); 6518 len = 0; 6519 } 6520 } 6521 if (len) 6522 wmi_nofl_debug("Freq[flag]:%s", info); 6523 } 6524 6525 /** 6526 * send_pno_start_cmd_tlv() - PNO start request 6527 * @wmi_handle: wmi handle 6528 * @pno: PNO request 6529 * 6530 * This function request FW to start PNO request. 6531 * Request: QDF status 6532 */ 6533 static QDF_STATUS send_pno_start_cmd_tlv(wmi_unified_t wmi_handle, 6534 struct pno_scan_req_params *pno) 6535 { 6536 wmi_nlo_config_cmd_fixed_param *cmd; 6537 nlo_configured_parameters *nlo_list; 6538 uint32_t *channel_list; 6539 int32_t len; 6540 qdf_freq_t freq; 6541 wmi_buf_t buf; 6542 uint8_t *buf_ptr; 6543 uint8_t i; 6544 int ret; 6545 struct probe_req_allowlist_attr *ie_allowlist = &pno->ie_allowlist; 6546 connected_nlo_rssi_params *nlo_relative_rssi; 6547 connected_nlo_bss_band_rssi_pref *nlo_band_rssi; 6548 6549 /* 6550 * TLV place holder for array nlo_configured_parameters(nlo_list) 6551 * TLV place holder for array of uint32_t channel_list 6552 * TLV place holder for chnnl prediction cfg 6553 * TLV place holder for array of wmi_vendor_oui 6554 * TLV place holder for array of connected_nlo_bss_band_rssi_pref 6555 */ 6556 len = sizeof(*cmd) + 6557 WMI_TLV_HDR_SIZE + WMI_TLV_HDR_SIZE + WMI_TLV_HDR_SIZE + 6558 WMI_TLV_HDR_SIZE + WMI_TLV_HDR_SIZE; 6559 6560 len += sizeof(uint32_t) * pno->networks_list[0].pno_chan_list.num_chan; 6561 len += sizeof(nlo_configured_parameters) * 6562 QDF_MIN(pno->networks_cnt, WMI_NLO_MAX_SSIDS); 6563 len += sizeof(nlo_channel_prediction_cfg); 6564 len += sizeof(enlo_candidate_score_params); 6565 len += sizeof(wmi_vendor_oui) * ie_allowlist->num_vendor_oui; 6566 len += sizeof(connected_nlo_rssi_params); 6567 len += sizeof(connected_nlo_bss_band_rssi_pref); 6568 6569 buf = wmi_buf_alloc(wmi_handle, len); 6570 if (!buf) 6571 return QDF_STATUS_E_NOMEM; 6572 6573 cmd = (wmi_nlo_config_cmd_fixed_param *) wmi_buf_data(buf); 6574 6575 buf_ptr = (uint8_t *) cmd; 6576 WMITLV_SET_HDR(&cmd->tlv_header, 6577 WMITLV_TAG_STRUC_wmi_nlo_config_cmd_fixed_param, 6578 WMITLV_GET_STRUCT_TLVLEN 6579 (wmi_nlo_config_cmd_fixed_param)); 6580 cmd->vdev_id = pno->vdev_id; 6581 cmd->flags = WMI_NLO_CONFIG_START | WMI_NLO_CONFIG_SSID_HIDE_EN; 6582 6583 #ifdef FEATURE_WLAN_SCAN_PNO 6584 WMI_SCAN_SET_DWELL_MODE(cmd->flags, 6585 pno->adaptive_dwell_mode); 6586 #endif 6587 /* Current FW does not support min-max range for dwell time */ 6588 cmd->active_dwell_time = pno->active_dwell_time; 6589 cmd->passive_dwell_time = pno->passive_dwell_time; 6590 6591 if (pno->do_passive_scan) 6592 cmd->flags |= WMI_NLO_CONFIG_SCAN_PASSIVE; 6593 /* Copy scan interval */ 6594 cmd->fast_scan_period = pno->fast_scan_period; 6595 cmd->slow_scan_period = pno->slow_scan_period; 6596 cmd->delay_start_time = WMI_SEC_TO_MSEC(pno->delay_start_time); 6597 cmd->fast_scan_max_cycles = pno->fast_scan_max_cycles; 6598 cmd->scan_backoff_multiplier = pno->scan_backoff_multiplier; 6599 6600 /* mac randomization attributes */ 6601 if (pno->scan_random.randomize) { 6602 cmd->flags |= WMI_NLO_CONFIG_SPOOFED_MAC_IN_PROBE_REQ | 6603 WMI_NLO_CONFIG_RANDOM_SEQ_NO_IN_PROBE_REQ; 6604 wmi_copy_scan_random_mac(pno->scan_random.mac_addr, 6605 pno->scan_random.mac_mask, 6606 &cmd->mac_addr, 6607 &cmd->mac_mask); 6608 } 6609 6610 buf_ptr += sizeof(wmi_nlo_config_cmd_fixed_param); 6611 6612 cmd->no_of_ssids = QDF_MIN(pno->networks_cnt, WMI_NLO_MAX_SSIDS); 6613 6614 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 6615 cmd->no_of_ssids * sizeof(nlo_configured_parameters)); 6616 buf_ptr += WMI_TLV_HDR_SIZE; 6617 6618 nlo_list = (nlo_configured_parameters *) buf_ptr; 6619 for (i = 0; i < cmd->no_of_ssids; i++) { 6620 WMITLV_SET_HDR(&nlo_list[i].tlv_header, 6621 WMITLV_TAG_ARRAY_BYTE, 6622 WMITLV_GET_STRUCT_TLVLEN 6623 (nlo_configured_parameters)); 6624 /* Copy ssid and it's length */ 6625 nlo_list[i].ssid.valid = true; 6626 nlo_list[i].ssid.ssid.ssid_len = 6627 pno->networks_list[i].ssid.length; 6628 qdf_mem_copy(nlo_list[i].ssid.ssid.ssid, 6629 pno->networks_list[i].ssid.ssid, 6630 nlo_list[i].ssid.ssid.ssid_len); 6631 6632 /* Copy rssi threshold */ 6633 if (pno->networks_list[i].rssi_thresh && 6634 pno->networks_list[i].rssi_thresh > 6635 WMI_RSSI_THOLD_DEFAULT) { 6636 nlo_list[i].rssi_cond.valid = true; 6637 nlo_list[i].rssi_cond.rssi = 6638 pno->networks_list[i].rssi_thresh; 6639 } 6640 nlo_list[i].bcast_nw_type.valid = true; 6641 nlo_list[i].bcast_nw_type.bcast_nw_type = 6642 pno->networks_list[i].bc_new_type; 6643 } 6644 buf_ptr += cmd->no_of_ssids * sizeof(nlo_configured_parameters); 6645 6646 /* Copy channel info */ 6647 cmd->num_of_channels = pno->networks_list[0].pno_chan_list.num_chan; 6648 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, 6649 (cmd->num_of_channels * sizeof(uint32_t))); 6650 buf_ptr += WMI_TLV_HDR_SIZE; 6651 6652 channel_list = (uint32_t *) buf_ptr; 6653 for (i = 0; i < cmd->num_of_channels; i++) { 6654 TARGET_SET_FREQ_IN_CHAN_LIST_TLV(channel_list[i], 6655 pno->networks_list[0].pno_chan_list.chan[i].freq); 6656 6657 if (channel_list[i] < WMI_NLO_FREQ_THRESH) { 6658 freq = pno->networks_list[0].pno_chan_list.chan[i].freq; 6659 TARGET_SET_FREQ_IN_CHAN_LIST_TLV(channel_list[i], 6660 wlan_chan_to_freq(freq)); 6661 } 6662 6663 TARGET_SET_FLAGS_IN_CHAN_LIST_TLV(channel_list[i], 6664 pno->networks_list[0].pno_chan_list.chan[i].flags); 6665 } 6666 6667 wmi_dump_pno_scan_freq_list(&pno->networks_list[0].pno_chan_list); 6668 6669 buf_ptr += cmd->num_of_channels * sizeof(uint32_t); 6670 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 6671 sizeof(nlo_channel_prediction_cfg)); 6672 buf_ptr += WMI_TLV_HDR_SIZE; 6673 wmi_set_pno_channel_prediction(buf_ptr, pno); 6674 buf_ptr += sizeof(nlo_channel_prediction_cfg); 6675 /** TODO: Discrete firmware doesn't have command/option to configure 6676 * App IE which comes from wpa_supplicant as of part PNO start request. 6677 */ 6678 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_STRUC_enlo_candidate_score_param, 6679 WMITLV_GET_STRUCT_TLVLEN(enlo_candidate_score_params)); 6680 buf_ptr += sizeof(enlo_candidate_score_params); 6681 6682 if (ie_allowlist->allow_list) { 6683 cmd->flags |= WMI_NLO_CONFIG_ENABLE_IE_WHITELIST_IN_PROBE_REQ; 6684 wmi_fill_ie_allowlist_attrs(cmd->ie_bitmap, 6685 &cmd->num_vendor_oui, 6686 ie_allowlist); 6687 } 6688 6689 /* ie allow list */ 6690 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 6691 ie_allowlist->num_vendor_oui * sizeof(wmi_vendor_oui)); 6692 buf_ptr += WMI_TLV_HDR_SIZE; 6693 if (cmd->num_vendor_oui != 0) { 6694 wmi_fill_vendor_oui(buf_ptr, cmd->num_vendor_oui, 6695 ie_allowlist->voui); 6696 buf_ptr += cmd->num_vendor_oui * sizeof(wmi_vendor_oui); 6697 } 6698 6699 if (pno->relative_rssi_set) 6700 cmd->flags |= WMI_NLO_CONFIG_ENABLE_CNLO_RSSI_CONFIG; 6701 6702 /* 6703 * Firmware calculation using connected PNO params: 6704 * New AP's RSSI >= (Connected AP's RSSI + relative_rssi +/- rssi_pref) 6705 * deduction of rssi_pref for chosen band_pref and 6706 * addition of rssi_pref for remaining bands (other than chosen band). 6707 */ 6708 nlo_relative_rssi = (connected_nlo_rssi_params *) buf_ptr; 6709 WMITLV_SET_HDR(&nlo_relative_rssi->tlv_header, 6710 WMITLV_TAG_STRUC_wmi_connected_nlo_rssi_params, 6711 WMITLV_GET_STRUCT_TLVLEN(connected_nlo_rssi_params)); 6712 nlo_relative_rssi->relative_rssi = pno->relative_rssi; 6713 buf_ptr += sizeof(*nlo_relative_rssi); 6714 6715 /* 6716 * As of now Kernel and Host supports one band and rssi preference. 6717 * Firmware supports array of band and rssi preferences 6718 */ 6719 cmd->num_cnlo_band_pref = 1; 6720 WMITLV_SET_HDR(buf_ptr, 6721 WMITLV_TAG_ARRAY_STRUC, 6722 cmd->num_cnlo_band_pref * 6723 sizeof(connected_nlo_bss_band_rssi_pref)); 6724 buf_ptr += WMI_TLV_HDR_SIZE; 6725 6726 nlo_band_rssi = (connected_nlo_bss_band_rssi_pref *) buf_ptr; 6727 for (i = 0; i < cmd->num_cnlo_band_pref; i++) { 6728 WMITLV_SET_HDR(&nlo_band_rssi[i].tlv_header, 6729 WMITLV_TAG_STRUC_wmi_connected_nlo_bss_band_rssi_pref, 6730 WMITLV_GET_STRUCT_TLVLEN( 6731 connected_nlo_bss_band_rssi_pref)); 6732 nlo_band_rssi[i].band = pno->band_rssi_pref.band; 6733 nlo_band_rssi[i].rssi_pref = pno->band_rssi_pref.rssi; 6734 } 6735 buf_ptr += cmd->num_cnlo_band_pref * sizeof(*nlo_band_rssi); 6736 6737 wmi_mtrace(WMI_NETWORK_LIST_OFFLOAD_CONFIG_CMDID, cmd->vdev_id, 0); 6738 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 6739 WMI_NETWORK_LIST_OFFLOAD_CONFIG_CMDID); 6740 if (ret) { 6741 wmi_err("Failed to send nlo wmi cmd"); 6742 wmi_buf_free(buf); 6743 return QDF_STATUS_E_FAILURE; 6744 } 6745 6746 return QDF_STATUS_SUCCESS; 6747 } 6748 6749 /** 6750 * is_service_enabled_tlv() - Check if service enabled 6751 * @wmi_handle: wmi handle 6752 * @service_id: service identifier 6753 * 6754 * Return: 1 enabled, 0 disabled 6755 */ 6756 static bool is_service_enabled_tlv(wmi_unified_t wmi_handle, 6757 uint32_t service_id) 6758 { 6759 struct wmi_soc *soc = wmi_handle->soc; 6760 6761 if (!soc->wmi_service_bitmap) { 6762 wmi_err("WMI service bit map is not saved yet"); 6763 return false; 6764 } 6765 6766 /* if wmi_service_enabled was received with extended2 bitmap, 6767 * use WMI_SERVICE_EXT2_IS_ENABLED to check the services. 6768 */ 6769 if (soc->wmi_ext2_service_bitmap) { 6770 if (!soc->wmi_ext_service_bitmap) { 6771 wmi_err("WMI service ext bit map is not saved yet"); 6772 return false; 6773 } 6774 6775 return WMI_SERVICE_EXT2_IS_ENABLED(soc->wmi_service_bitmap, 6776 soc->wmi_ext_service_bitmap, 6777 soc->wmi_ext2_service_bitmap, 6778 service_id); 6779 } 6780 6781 if (service_id >= WMI_MAX_EXT_SERVICE) { 6782 wmi_err_rl("Service id %d but WMI ext2 service bitmap is NULL", 6783 service_id); 6784 return false; 6785 } 6786 /* if wmi_service_enabled was received with extended bitmap, 6787 * use WMI_SERVICE_EXT_IS_ENABLED to check the services. 6788 */ 6789 if (soc->wmi_ext_service_bitmap) 6790 return WMI_SERVICE_EXT_IS_ENABLED(soc->wmi_service_bitmap, 6791 soc->wmi_ext_service_bitmap, 6792 service_id); 6793 6794 if (service_id >= WMI_MAX_SERVICE) { 6795 wmi_err("Service id %d but WMI ext service bitmap is NULL", 6796 service_id); 6797 return false; 6798 } 6799 6800 return WMI_SERVICE_IS_ENABLED(soc->wmi_service_bitmap, 6801 service_id); 6802 } 6803 6804 #ifdef WLAN_FEATURE_LINK_LAYER_STATS 6805 /** 6806 * send_process_ll_stats_clear_cmd_tlv() - clear link layer stats 6807 * @wmi_handle: wmi handle 6808 * @clear_req: ll stats clear request command params 6809 * 6810 * Return: QDF_STATUS_SUCCESS for success or error code 6811 */ 6812 static QDF_STATUS send_process_ll_stats_clear_cmd_tlv(wmi_unified_t wmi_handle, 6813 const struct ll_stats_clear_params *clear_req) 6814 { 6815 wmi_clear_link_stats_cmd_fixed_param *cmd; 6816 int32_t len; 6817 wmi_buf_t buf; 6818 uint8_t *buf_ptr; 6819 int ret; 6820 6821 len = sizeof(*cmd); 6822 buf = wmi_buf_alloc(wmi_handle, len); 6823 6824 if (!buf) 6825 return QDF_STATUS_E_NOMEM; 6826 6827 buf_ptr = (uint8_t *) wmi_buf_data(buf); 6828 qdf_mem_zero(buf_ptr, len); 6829 cmd = (wmi_clear_link_stats_cmd_fixed_param *) buf_ptr; 6830 6831 WMITLV_SET_HDR(&cmd->tlv_header, 6832 WMITLV_TAG_STRUC_wmi_clear_link_stats_cmd_fixed_param, 6833 WMITLV_GET_STRUCT_TLVLEN 6834 (wmi_clear_link_stats_cmd_fixed_param)); 6835 6836 cmd->stop_stats_collection_req = clear_req->stop_req; 6837 cmd->vdev_id = clear_req->vdev_id; 6838 cmd->stats_clear_req_mask = clear_req->stats_clear_mask; 6839 6840 WMI_CHAR_ARRAY_TO_MAC_ADDR(clear_req->peer_macaddr.bytes, 6841 &cmd->peer_macaddr); 6842 6843 wmi_debug("LINK_LAYER_STATS - Clear Request Params"); 6844 wmi_debug("StopReq: %d Vdev Id: %d Clear Stat Mask: %d" 6845 " Peer MAC Addr: "QDF_MAC_ADDR_FMT, 6846 cmd->stop_stats_collection_req, 6847 cmd->vdev_id, cmd->stats_clear_req_mask, 6848 QDF_MAC_ADDR_REF(clear_req->peer_macaddr.bytes)); 6849 6850 wmi_mtrace(WMI_CLEAR_LINK_STATS_CMDID, cmd->vdev_id, 0); 6851 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 6852 WMI_CLEAR_LINK_STATS_CMDID); 6853 if (ret) { 6854 wmi_err("Failed to send clear link stats req"); 6855 wmi_buf_free(buf); 6856 return QDF_STATUS_E_FAILURE; 6857 } 6858 6859 wmi_debug("Clear Link Layer Stats request sent successfully"); 6860 return QDF_STATUS_SUCCESS; 6861 } 6862 6863 /** 6864 * send_process_ll_stats_set_cmd_tlv() - link layer stats set request 6865 * @wmi_handle: wmi handle 6866 * @set_req: ll stats set request command params 6867 * 6868 * Return: QDF_STATUS_SUCCESS for success or error code 6869 */ 6870 static QDF_STATUS send_process_ll_stats_set_cmd_tlv(wmi_unified_t wmi_handle, 6871 const struct ll_stats_set_params *set_req) 6872 { 6873 wmi_start_link_stats_cmd_fixed_param *cmd; 6874 int32_t len; 6875 wmi_buf_t buf; 6876 uint8_t *buf_ptr; 6877 int ret; 6878 6879 len = sizeof(*cmd); 6880 buf = wmi_buf_alloc(wmi_handle, len); 6881 6882 if (!buf) 6883 return QDF_STATUS_E_NOMEM; 6884 6885 buf_ptr = (uint8_t *) wmi_buf_data(buf); 6886 qdf_mem_zero(buf_ptr, len); 6887 cmd = (wmi_start_link_stats_cmd_fixed_param *) buf_ptr; 6888 6889 WMITLV_SET_HDR(&cmd->tlv_header, 6890 WMITLV_TAG_STRUC_wmi_start_link_stats_cmd_fixed_param, 6891 WMITLV_GET_STRUCT_TLVLEN 6892 (wmi_start_link_stats_cmd_fixed_param)); 6893 6894 cmd->mpdu_size_threshold = set_req->mpdu_size_threshold; 6895 cmd->aggressive_statistics_gathering = 6896 set_req->aggressive_statistics_gathering; 6897 6898 wmi_debug("LINK_LAYER_STATS - Start/Set Params MPDU Size Thresh : %d Aggressive Gather: %d", 6899 cmd->mpdu_size_threshold, 6900 cmd->aggressive_statistics_gathering); 6901 6902 wmi_mtrace(WMI_START_LINK_STATS_CMDID, NO_SESSION, 0); 6903 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 6904 WMI_START_LINK_STATS_CMDID); 6905 if (ret) { 6906 wmi_err("Failed to send set link stats request"); 6907 wmi_buf_free(buf); 6908 return QDF_STATUS_E_FAILURE; 6909 } 6910 6911 return QDF_STATUS_SUCCESS; 6912 } 6913 6914 /** 6915 * send_process_ll_stats_get_cmd_tlv() - link layer stats get request 6916 * @wmi_handle: wmi handle 6917 * @get_req: ll stats get request command params 6918 * 6919 * Return: QDF_STATUS_SUCCESS for success or error code 6920 */ 6921 static QDF_STATUS send_process_ll_stats_get_cmd_tlv(wmi_unified_t wmi_handle, 6922 const struct ll_stats_get_params *get_req) 6923 { 6924 wmi_request_link_stats_cmd_fixed_param *cmd; 6925 int32_t len; 6926 wmi_buf_t buf; 6927 uint8_t *buf_ptr; 6928 int ret; 6929 bool is_link_stats_over_qmi; 6930 6931 len = sizeof(*cmd); 6932 buf = wmi_buf_alloc(wmi_handle, len); 6933 6934 if (!buf) 6935 return QDF_STATUS_E_NOMEM; 6936 6937 buf_ptr = (uint8_t *) wmi_buf_data(buf); 6938 qdf_mem_zero(buf_ptr, len); 6939 cmd = (wmi_request_link_stats_cmd_fixed_param *) buf_ptr; 6940 6941 WMITLV_SET_HDR(&cmd->tlv_header, 6942 WMITLV_TAG_STRUC_wmi_request_link_stats_cmd_fixed_param, 6943 WMITLV_GET_STRUCT_TLVLEN 6944 (wmi_request_link_stats_cmd_fixed_param)); 6945 6946 cmd->request_id = get_req->req_id; 6947 cmd->stats_type = get_req->param_id_mask; 6948 cmd->vdev_id = get_req->vdev_id; 6949 6950 WMI_CHAR_ARRAY_TO_MAC_ADDR(get_req->peer_macaddr.bytes, 6951 &cmd->peer_macaddr); 6952 6953 wmi_debug("LINK_LAYER_STATS - Get Request Params Request ID: %u Stats Type: %0x Vdev ID: %d Peer MAC Addr: "QDF_MAC_ADDR_FMT, 6954 cmd->request_id, cmd->stats_type, cmd->vdev_id, 6955 QDF_MAC_ADDR_REF(get_req->peer_macaddr.bytes)); 6956 6957 wmi_mtrace(WMI_REQUEST_LINK_STATS_CMDID, cmd->vdev_id, 0); 6958 is_link_stats_over_qmi = is_service_enabled_tlv( 6959 wmi_handle, 6960 WMI_SERVICE_UNIFIED_LL_GET_STA_OVER_QMI_SUPPORT); 6961 6962 if (is_link_stats_over_qmi) { 6963 ret = wmi_unified_cmd_send_over_qmi( 6964 wmi_handle, buf, len, 6965 WMI_REQUEST_LINK_STATS_CMDID); 6966 } else { 6967 ret = wmi_unified_cmd_send_pm_chk( 6968 wmi_handle, buf, len, 6969 WMI_REQUEST_LINK_STATS_CMDID, true); 6970 } 6971 6972 if (ret) { 6973 wmi_buf_free(buf); 6974 return QDF_STATUS_E_FAILURE; 6975 } 6976 6977 return QDF_STATUS_SUCCESS; 6978 } 6979 6980 #ifdef FEATURE_CLUB_LL_STATS_AND_GET_STATION 6981 #ifdef WLAN_FEATURE_11BE_MLO 6982 static int 6983 wmi_get_tlv_length_for_mlo_stats(const struct ll_stats_get_params *get_req) 6984 { 6985 int32_t len = 0; 6986 6987 /* In case of MLO connection, update the length of the buffer. 6988 * The wmi_inst_rssi_stats_params structure is not needed for MLO stats, 6989 * hence just update the TLV header, but allocate no memory for it. 6990 */ 6991 if (!get_req->is_mlo_req) 6992 return len; 6993 6994 len += WMI_TLV_HDR_SIZE + 0 * sizeof(wmi_inst_rssi_stats_params) + 6995 WMI_TLV_HDR_SIZE + 1 * sizeof(uint32_t) + 6996 WMI_TLV_HDR_SIZE + 1 * sizeof(wmi_mac_addr); 6997 6998 return len; 6999 } 7000 7001 static void 7002 wmi_update_tlv_headers_for_mlo_stats(const struct ll_stats_get_params *get_req, 7003 void *buf_ptr) 7004 { 7005 wmi_request_unified_ll_get_sta_cmd_fixed_param *unified_cmd; 7006 uint32_t *vdev_id_bitmap; 7007 wmi_mac_addr *mld_mac; 7008 7009 /* In case of MLO connection, update the TLV Headers */ 7010 if (!get_req->is_mlo_req) 7011 return; 7012 7013 buf_ptr += sizeof(*unified_cmd); 7014 7015 /* Fill TLV but no data for wmi_inst_rssi_stats_params */ 7016 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0); 7017 buf_ptr += WMI_TLV_HDR_SIZE; 7018 7019 /* Adding vdev_bitmap_id array TLV */ 7020 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, 7021 sizeof(*vdev_id_bitmap)); 7022 buf_ptr += WMI_TLV_HDR_SIZE; 7023 vdev_id_bitmap = buf_ptr; 7024 *(vdev_id_bitmap) = get_req->vdev_id_bitmap; 7025 buf_ptr += sizeof(*vdev_id_bitmap); 7026 7027 /* Adding mld_macaddr array TLV */ 7028 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_FIXED_STRUC, 7029 sizeof(*mld_mac)); 7030 buf_ptr += WMI_TLV_HDR_SIZE; 7031 mld_mac = buf_ptr; 7032 WMI_CHAR_ARRAY_TO_MAC_ADDR(get_req->mld_macaddr.bytes, mld_mac); 7033 7034 wmi_debug("MLO vdev_id_bitmap: 0x%x MLD MAC Addr: " 7035 QDF_MAC_ADDR_FMT, get_req->vdev_id_bitmap, 7036 QDF_MAC_ADDR_REF(get_req->mld_macaddr.bytes)); 7037 } 7038 #else 7039 static inline int 7040 wmi_get_tlv_length_for_mlo_stats(const struct ll_stats_get_params *get_req) 7041 { 7042 return 0; 7043 } 7044 7045 static inline void 7046 wmi_update_tlv_headers_for_mlo_stats(const struct ll_stats_get_params *get_req, 7047 void *buf_ptr) 7048 { 7049 } 7050 #endif 7051 7052 /** 7053 * send_unified_ll_stats_get_sta_cmd_tlv() - unified link layer stats and get 7054 * station request 7055 * @wmi_handle: wmi handle 7056 * @get_req: ll stats get request command params 7057 * 7058 * Return: QDF_STATUS_SUCCESS for success or error code 7059 */ 7060 static QDF_STATUS send_unified_ll_stats_get_sta_cmd_tlv( 7061 wmi_unified_t wmi_handle, 7062 const struct ll_stats_get_params *get_req) 7063 { 7064 wmi_request_unified_ll_get_sta_cmd_fixed_param *unified_cmd; 7065 int32_t len; 7066 wmi_buf_t buf; 7067 void *buf_ptr; 7068 QDF_STATUS ret; 7069 bool is_ll_get_sta_stats_over_qmi; 7070 7071 len = sizeof(*unified_cmd); 7072 len += wmi_get_tlv_length_for_mlo_stats(get_req); 7073 7074 buf = wmi_buf_alloc(wmi_handle, len); 7075 if (!buf) 7076 return QDF_STATUS_E_NOMEM; 7077 7078 buf_ptr = wmi_buf_data(buf); 7079 7080 unified_cmd = buf_ptr; 7081 WMITLV_SET_HDR( 7082 &unified_cmd->tlv_header, 7083 WMITLV_TAG_STRUC_wmi_request_unified_ll_get_sta_cmd_fixed_param, 7084 WMITLV_GET_STRUCT_TLVLEN 7085 (wmi_request_unified_ll_get_sta_cmd_fixed_param)); 7086 7087 unified_cmd->link_stats_type = get_req->param_id_mask; 7088 unified_cmd->get_sta_stats_id = (WMI_REQUEST_AP_STAT | 7089 WMI_REQUEST_PEER_STAT | 7090 WMI_REQUEST_VDEV_STAT | 7091 WMI_REQUEST_PDEV_STAT | 7092 WMI_REQUEST_VDEV_EXTD_STAT | 7093 WMI_REQUEST_PEER_EXTD2_STAT | 7094 WMI_REQUEST_RSSI_PER_CHAIN_STAT); 7095 unified_cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 7096 wmi_handle, 7097 WMI_HOST_PDEV_ID_SOC); 7098 7099 unified_cmd->vdev_id = get_req->vdev_id; 7100 unified_cmd->request_id = get_req->req_id; 7101 WMI_CHAR_ARRAY_TO_MAC_ADDR(get_req->peer_macaddr.bytes, 7102 &unified_cmd->peer_macaddr); 7103 7104 wmi_debug("UNIFIED_LINK_STATS_GET_STA - Get Request Params Request ID: %u Stats Type: %0x Vdev ID: %d Peer MAC Addr: " 7105 QDF_MAC_ADDR_FMT, 7106 get_req->req_id, get_req->param_id_mask, get_req->vdev_id, 7107 QDF_MAC_ADDR_REF(get_req->peer_macaddr.bytes)); 7108 7109 wmi_update_tlv_headers_for_mlo_stats(get_req, buf_ptr); 7110 wmi_mtrace(WMI_REQUEST_UNIFIED_LL_GET_STA_CMDID, get_req->vdev_id, 0); 7111 7112 /** 7113 * FW support for LL_get_sta command. True represents the unified 7114 * ll_get_sta command should be sent over QMI always irrespective of 7115 * WOW state. 7116 */ 7117 is_ll_get_sta_stats_over_qmi = is_service_enabled_tlv( 7118 wmi_handle, 7119 WMI_SERVICE_UNIFIED_LL_GET_STA_OVER_QMI_SUPPORT); 7120 7121 if (is_ll_get_sta_stats_over_qmi) { 7122 ret = wmi_unified_cmd_send_over_qmi( 7123 wmi_handle, buf, len, 7124 WMI_REQUEST_UNIFIED_LL_GET_STA_CMDID); 7125 } else { 7126 ret = wmi_unified_cmd_send_pm_chk( 7127 wmi_handle, buf, len, 7128 WMI_REQUEST_UNIFIED_LL_GET_STA_CMDID, 7129 true); 7130 } 7131 7132 if (QDF_IS_STATUS_ERROR(ret)) { 7133 wmi_buf_free(buf); 7134 return QDF_STATUS_E_FAILURE; 7135 } 7136 7137 return ret; 7138 } 7139 #endif 7140 #endif /* WLAN_FEATURE_LINK_LAYER_STATS */ 7141 7142 /** 7143 * send_congestion_cmd_tlv() - send request to fw to get CCA 7144 * @wmi_handle: wmi handle 7145 * @vdev_id: vdev id 7146 * 7147 * Return: QDF status 7148 */ 7149 static QDF_STATUS send_congestion_cmd_tlv(wmi_unified_t wmi_handle, 7150 uint8_t vdev_id) 7151 { 7152 wmi_buf_t buf; 7153 wmi_request_stats_cmd_fixed_param *cmd; 7154 uint8_t len; 7155 uint8_t *buf_ptr; 7156 7157 len = sizeof(*cmd); 7158 buf = wmi_buf_alloc(wmi_handle, len); 7159 if (!buf) 7160 return QDF_STATUS_E_FAILURE; 7161 7162 buf_ptr = wmi_buf_data(buf); 7163 cmd = (wmi_request_stats_cmd_fixed_param *)buf_ptr; 7164 WMITLV_SET_HDR(&cmd->tlv_header, 7165 WMITLV_TAG_STRUC_wmi_request_stats_cmd_fixed_param, 7166 WMITLV_GET_STRUCT_TLVLEN 7167 (wmi_request_stats_cmd_fixed_param)); 7168 7169 cmd->stats_id = WMI_REQUEST_CONGESTION_STAT; 7170 cmd->vdev_id = vdev_id; 7171 wmi_debug("STATS REQ VDEV_ID:%d stats_id %d -->", 7172 cmd->vdev_id, cmd->stats_id); 7173 7174 wmi_mtrace(WMI_REQUEST_STATS_CMDID, cmd->vdev_id, 0); 7175 if (wmi_unified_cmd_send(wmi_handle, buf, len, 7176 WMI_REQUEST_STATS_CMDID)) { 7177 wmi_err("Failed to send WMI_REQUEST_STATS_CMDID"); 7178 wmi_buf_free(buf); 7179 return QDF_STATUS_E_FAILURE; 7180 } 7181 7182 return QDF_STATUS_SUCCESS; 7183 } 7184 7185 /** 7186 * send_snr_request_cmd_tlv() - send request to fw to get RSSI stats 7187 * @wmi_handle: wmi handle 7188 * 7189 * Return: QDF status 7190 */ 7191 static QDF_STATUS send_snr_request_cmd_tlv(wmi_unified_t wmi_handle) 7192 { 7193 wmi_buf_t buf; 7194 wmi_request_stats_cmd_fixed_param *cmd; 7195 uint8_t len = sizeof(wmi_request_stats_cmd_fixed_param); 7196 7197 buf = wmi_buf_alloc(wmi_handle, len); 7198 if (!buf) 7199 return QDF_STATUS_E_FAILURE; 7200 7201 cmd = (wmi_request_stats_cmd_fixed_param *) wmi_buf_data(buf); 7202 WMITLV_SET_HDR(&cmd->tlv_header, 7203 WMITLV_TAG_STRUC_wmi_request_stats_cmd_fixed_param, 7204 WMITLV_GET_STRUCT_TLVLEN 7205 (wmi_request_stats_cmd_fixed_param)); 7206 cmd->stats_id = WMI_REQUEST_VDEV_STAT; 7207 wmi_mtrace(WMI_REQUEST_STATS_CMDID, cmd->vdev_id, 0); 7208 if (wmi_unified_cmd_send(wmi_handle, buf, len, 7209 WMI_REQUEST_STATS_CMDID)) { 7210 wmi_err("Failed to send host stats request to fw"); 7211 wmi_buf_free(buf); 7212 return QDF_STATUS_E_FAILURE; 7213 } 7214 7215 return QDF_STATUS_SUCCESS; 7216 } 7217 7218 /** 7219 * send_snr_cmd_tlv() - get RSSI from fw 7220 * @wmi_handle: wmi handle 7221 * @vdev_id: vdev id 7222 * 7223 * Return: QDF status 7224 */ 7225 static QDF_STATUS send_snr_cmd_tlv(wmi_unified_t wmi_handle, uint8_t vdev_id) 7226 { 7227 wmi_buf_t buf; 7228 wmi_request_stats_cmd_fixed_param *cmd; 7229 uint8_t len = sizeof(wmi_request_stats_cmd_fixed_param); 7230 7231 buf = wmi_buf_alloc(wmi_handle, len); 7232 if (!buf) 7233 return QDF_STATUS_E_FAILURE; 7234 7235 cmd = (wmi_request_stats_cmd_fixed_param *) wmi_buf_data(buf); 7236 cmd->vdev_id = vdev_id; 7237 7238 WMITLV_SET_HDR(&cmd->tlv_header, 7239 WMITLV_TAG_STRUC_wmi_request_stats_cmd_fixed_param, 7240 WMITLV_GET_STRUCT_TLVLEN 7241 (wmi_request_stats_cmd_fixed_param)); 7242 cmd->stats_id = WMI_REQUEST_VDEV_STAT; 7243 wmi_mtrace(WMI_REQUEST_STATS_CMDID, cmd->vdev_id, 0); 7244 if (wmi_unified_cmd_send(wmi_handle, buf, len, 7245 WMI_REQUEST_STATS_CMDID)) { 7246 wmi_err("Failed to send host stats request to fw"); 7247 wmi_buf_free(buf); 7248 return QDF_STATUS_E_FAILURE; 7249 } 7250 7251 return QDF_STATUS_SUCCESS; 7252 } 7253 7254 /** 7255 * send_link_status_req_cmd_tlv() - process link status request from UMAC 7256 * @wmi_handle: wmi handle 7257 * @link_status: get link params 7258 * 7259 * Return: QDF status 7260 */ 7261 static QDF_STATUS send_link_status_req_cmd_tlv(wmi_unified_t wmi_handle, 7262 struct link_status_params *link_status) 7263 { 7264 wmi_buf_t buf; 7265 wmi_request_stats_cmd_fixed_param *cmd; 7266 uint8_t len = sizeof(wmi_request_stats_cmd_fixed_param); 7267 7268 buf = wmi_buf_alloc(wmi_handle, len); 7269 if (!buf) 7270 return QDF_STATUS_E_FAILURE; 7271 7272 cmd = (wmi_request_stats_cmd_fixed_param *) wmi_buf_data(buf); 7273 WMITLV_SET_HDR(&cmd->tlv_header, 7274 WMITLV_TAG_STRUC_wmi_request_stats_cmd_fixed_param, 7275 WMITLV_GET_STRUCT_TLVLEN 7276 (wmi_request_stats_cmd_fixed_param)); 7277 cmd->stats_id = WMI_REQUEST_VDEV_RATE_STAT; 7278 cmd->vdev_id = link_status->vdev_id; 7279 wmi_mtrace(WMI_REQUEST_STATS_CMDID, cmd->vdev_id, 0); 7280 if (wmi_unified_cmd_send(wmi_handle, buf, len, 7281 WMI_REQUEST_STATS_CMDID)) { 7282 wmi_err("Failed to send WMI link status request to fw"); 7283 wmi_buf_free(buf); 7284 return QDF_STATUS_E_FAILURE; 7285 } 7286 7287 return QDF_STATUS_SUCCESS; 7288 } 7289 7290 #ifdef WLAN_SUPPORT_GREEN_AP 7291 /** 7292 * send_egap_conf_params_cmd_tlv() - send wmi cmd of egap configuration params 7293 * @wmi_handle: wmi handler 7294 * @egap_params: pointer to egap_params 7295 * 7296 * Return: 0 for success, otherwise appropriate error code 7297 */ 7298 static QDF_STATUS send_egap_conf_params_cmd_tlv(wmi_unified_t wmi_handle, 7299 struct wlan_green_ap_egap_params *egap_params) 7300 { 7301 wmi_ap_ps_egap_param_cmd_fixed_param *cmd; 7302 wmi_buf_t buf; 7303 int32_t err; 7304 7305 buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd)); 7306 if (!buf) 7307 return QDF_STATUS_E_NOMEM; 7308 7309 cmd = (wmi_ap_ps_egap_param_cmd_fixed_param *) wmi_buf_data(buf); 7310 WMITLV_SET_HDR(&cmd->tlv_header, 7311 WMITLV_TAG_STRUC_wmi_ap_ps_egap_param_cmd_fixed_param, 7312 WMITLV_GET_STRUCT_TLVLEN( 7313 wmi_ap_ps_egap_param_cmd_fixed_param)); 7314 7315 cmd->enable = egap_params->host_enable_egap; 7316 cmd->inactivity_time = egap_params->egap_inactivity_time; 7317 cmd->wait_time = egap_params->egap_wait_time; 7318 cmd->flags = egap_params->egap_feature_flags; 7319 wmi_mtrace(WMI_AP_PS_EGAP_PARAM_CMDID, NO_SESSION, 0); 7320 err = wmi_unified_cmd_send(wmi_handle, buf, 7321 sizeof(*cmd), WMI_AP_PS_EGAP_PARAM_CMDID); 7322 if (err) { 7323 wmi_err("Failed to send ap_ps_egap cmd"); 7324 wmi_buf_free(buf); 7325 return QDF_STATUS_E_FAILURE; 7326 } 7327 7328 return QDF_STATUS_SUCCESS; 7329 } 7330 #endif 7331 7332 /** 7333 * send_csa_offload_enable_cmd_tlv() - send CSA offload enable command 7334 * @wmi_handle: wmi handle 7335 * @vdev_id: vdev id 7336 * 7337 * Return: QDF_STATUS_SUCCESS for success or error code 7338 */ 7339 static QDF_STATUS send_csa_offload_enable_cmd_tlv(wmi_unified_t wmi_handle, 7340 uint8_t vdev_id) 7341 { 7342 wmi_csa_offload_enable_cmd_fixed_param *cmd; 7343 wmi_buf_t buf; 7344 int32_t len = sizeof(*cmd); 7345 7346 wmi_debug("vdev_id %d", vdev_id); 7347 buf = wmi_buf_alloc(wmi_handle, len); 7348 if (!buf) 7349 return QDF_STATUS_E_NOMEM; 7350 7351 cmd = (wmi_csa_offload_enable_cmd_fixed_param *) wmi_buf_data(buf); 7352 WMITLV_SET_HDR(&cmd->tlv_header, 7353 WMITLV_TAG_STRUC_wmi_csa_offload_enable_cmd_fixed_param, 7354 WMITLV_GET_STRUCT_TLVLEN 7355 (wmi_csa_offload_enable_cmd_fixed_param)); 7356 cmd->vdev_id = vdev_id; 7357 cmd->csa_offload_enable = WMI_CSA_OFFLOAD_ENABLE; 7358 wmi_mtrace(WMI_CSA_OFFLOAD_ENABLE_CMDID, cmd->vdev_id, 0); 7359 if (wmi_unified_cmd_send(wmi_handle, buf, len, 7360 WMI_CSA_OFFLOAD_ENABLE_CMDID)) { 7361 wmi_err("Failed to send CSA offload enable command"); 7362 wmi_buf_free(buf); 7363 return QDF_STATUS_E_FAILURE; 7364 } 7365 7366 return 0; 7367 } 7368 7369 #ifdef WLAN_FEATURE_CIF_CFR 7370 /** 7371 * send_oem_dma_cfg_cmd_tlv() - configure OEM DMA rings 7372 * @wmi_handle: wmi handle 7373 * @cfg: dma cfg req 7374 * 7375 * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure 7376 */ 7377 static QDF_STATUS send_oem_dma_cfg_cmd_tlv(wmi_unified_t wmi_handle, 7378 wmi_oem_dma_ring_cfg_req_fixed_param *cfg) 7379 { 7380 wmi_buf_t buf; 7381 uint8_t *cmd; 7382 QDF_STATUS ret; 7383 7384 WMITLV_SET_HDR(cfg, 7385 WMITLV_TAG_STRUC_wmi_oem_dma_ring_cfg_req_fixed_param, 7386 (sizeof(*cfg) - WMI_TLV_HDR_SIZE)); 7387 7388 buf = wmi_buf_alloc(wmi_handle, sizeof(*cfg)); 7389 if (!buf) 7390 return QDF_STATUS_E_FAILURE; 7391 7392 cmd = (uint8_t *) wmi_buf_data(buf); 7393 qdf_mem_copy(cmd, cfg, sizeof(*cfg)); 7394 wmi_debug("Sending OEM Data Request to target, data len %lu", 7395 sizeof(*cfg)); 7396 wmi_mtrace(WMI_OEM_DMA_RING_CFG_REQ_CMDID, NO_SESSION, 0); 7397 ret = wmi_unified_cmd_send(wmi_handle, buf, sizeof(*cfg), 7398 WMI_OEM_DMA_RING_CFG_REQ_CMDID); 7399 if (QDF_IS_STATUS_ERROR(ret)) { 7400 wmi_err("Failed to send WMI_OEM_DMA_RING_CFG_REQ_CMDID"); 7401 wmi_buf_free(buf); 7402 } 7403 7404 return ret; 7405 } 7406 #endif 7407 7408 /** 7409 * send_start_11d_scan_cmd_tlv() - start 11d scan request 7410 * @wmi_handle: wmi handle 7411 * @start_11d_scan: 11d scan start request parameters 7412 * 7413 * This function request FW to start 11d scan. 7414 * 7415 * Return: QDF status 7416 */ 7417 static QDF_STATUS send_start_11d_scan_cmd_tlv(wmi_unified_t wmi_handle, 7418 struct reg_start_11d_scan_req *start_11d_scan) 7419 { 7420 wmi_11d_scan_start_cmd_fixed_param *cmd; 7421 int32_t len; 7422 wmi_buf_t buf; 7423 int ret; 7424 7425 len = sizeof(*cmd); 7426 buf = wmi_buf_alloc(wmi_handle, len); 7427 if (!buf) 7428 return QDF_STATUS_E_NOMEM; 7429 7430 cmd = (wmi_11d_scan_start_cmd_fixed_param *)wmi_buf_data(buf); 7431 7432 WMITLV_SET_HDR(&cmd->tlv_header, 7433 WMITLV_TAG_STRUC_wmi_11d_scan_start_cmd_fixed_param, 7434 WMITLV_GET_STRUCT_TLVLEN 7435 (wmi_11d_scan_start_cmd_fixed_param)); 7436 7437 cmd->vdev_id = start_11d_scan->vdev_id; 7438 cmd->scan_period_msec = start_11d_scan->scan_period_msec; 7439 cmd->start_interval_msec = start_11d_scan->start_interval_msec; 7440 7441 wmi_debug("vdev %d sending 11D scan start req", cmd->vdev_id); 7442 7443 wmi_mtrace(WMI_11D_SCAN_START_CMDID, cmd->vdev_id, 0); 7444 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 7445 WMI_11D_SCAN_START_CMDID); 7446 if (ret) { 7447 wmi_err("Failed to send start 11d scan wmi cmd"); 7448 wmi_buf_free(buf); 7449 return QDF_STATUS_E_FAILURE; 7450 } 7451 7452 return QDF_STATUS_SUCCESS; 7453 } 7454 7455 /** 7456 * send_stop_11d_scan_cmd_tlv() - stop 11d scan request 7457 * @wmi_handle: wmi handle 7458 * @stop_11d_scan: 11d scan stop request parameters 7459 * 7460 * This function request FW to stop 11d scan. 7461 * 7462 * Return: QDF status 7463 */ 7464 static QDF_STATUS send_stop_11d_scan_cmd_tlv(wmi_unified_t wmi_handle, 7465 struct reg_stop_11d_scan_req *stop_11d_scan) 7466 { 7467 wmi_11d_scan_stop_cmd_fixed_param *cmd; 7468 int32_t len; 7469 wmi_buf_t buf; 7470 int ret; 7471 7472 len = sizeof(*cmd); 7473 buf = wmi_buf_alloc(wmi_handle, len); 7474 if (!buf) 7475 return QDF_STATUS_E_NOMEM; 7476 7477 cmd = (wmi_11d_scan_stop_cmd_fixed_param *)wmi_buf_data(buf); 7478 7479 WMITLV_SET_HDR(&cmd->tlv_header, 7480 WMITLV_TAG_STRUC_wmi_11d_scan_stop_cmd_fixed_param, 7481 WMITLV_GET_STRUCT_TLVLEN 7482 (wmi_11d_scan_stop_cmd_fixed_param)); 7483 7484 cmd->vdev_id = stop_11d_scan->vdev_id; 7485 7486 wmi_debug("vdev %d sending 11D scan stop req", cmd->vdev_id); 7487 7488 wmi_mtrace(WMI_11D_SCAN_STOP_CMDID, cmd->vdev_id, 0); 7489 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 7490 WMI_11D_SCAN_STOP_CMDID); 7491 if (ret) { 7492 wmi_err("Failed to send stop 11d scan wmi cmd"); 7493 wmi_buf_free(buf); 7494 return QDF_STATUS_E_FAILURE; 7495 } 7496 7497 return QDF_STATUS_SUCCESS; 7498 } 7499 7500 /** 7501 * send_start_oem_data_cmd_tlv() - start OEM data request to target 7502 * @wmi_handle: wmi handle 7503 * @data_len: the length of @data 7504 * @data: the pointer to data buf 7505 * 7506 * Return: QDF status 7507 */ 7508 static QDF_STATUS send_start_oem_data_cmd_tlv(wmi_unified_t wmi_handle, 7509 uint32_t data_len, 7510 uint8_t *data) 7511 { 7512 wmi_buf_t buf; 7513 uint8_t *cmd; 7514 QDF_STATUS ret; 7515 7516 buf = wmi_buf_alloc(wmi_handle, 7517 (data_len + WMI_TLV_HDR_SIZE)); 7518 if (!buf) 7519 return QDF_STATUS_E_FAILURE; 7520 7521 cmd = (uint8_t *) wmi_buf_data(buf); 7522 7523 WMITLV_SET_HDR(cmd, WMITLV_TAG_ARRAY_BYTE, data_len); 7524 cmd += WMI_TLV_HDR_SIZE; 7525 qdf_mem_copy(cmd, data, 7526 data_len); 7527 7528 wmi_debug("Sending OEM Data Request to target, data len %d", data_len); 7529 7530 wmi_mtrace(WMI_OEM_REQ_CMDID, NO_SESSION, 0); 7531 ret = wmi_unified_cmd_send(wmi_handle, buf, 7532 (data_len + 7533 WMI_TLV_HDR_SIZE), WMI_OEM_REQ_CMDID); 7534 7535 if (QDF_IS_STATUS_ERROR(ret)) { 7536 wmi_err("Failed to send WMI_OEM_REQ_CMDID"); 7537 wmi_buf_free(buf); 7538 } 7539 7540 return ret; 7541 } 7542 7543 #ifdef FEATURE_OEM_DATA 7544 /** 7545 * send_start_oemv2_data_cmd_tlv() - start OEM data to target 7546 * @wmi_handle: wmi handle 7547 * @oem_data: the pointer to oem data 7548 * 7549 * Return: QDF status 7550 */ 7551 static QDF_STATUS send_start_oemv2_data_cmd_tlv(wmi_unified_t wmi_handle, 7552 struct oem_data *oem_data) 7553 { 7554 QDF_STATUS ret; 7555 wmi_oem_data_cmd_fixed_param *cmd; 7556 struct wmi_ops *ops; 7557 wmi_buf_t buf; 7558 uint16_t len = sizeof(*cmd); 7559 uint16_t oem_data_len_aligned; 7560 uint8_t *buf_ptr; 7561 uint32_t pdev_id; 7562 7563 if (!oem_data || !oem_data->data) { 7564 wmi_err_rl("oem data is not valid"); 7565 return QDF_STATUS_E_FAILURE; 7566 } 7567 7568 oem_data_len_aligned = roundup(oem_data->data_len, sizeof(uint32_t)); 7569 if (oem_data_len_aligned < oem_data->data_len) { 7570 wmi_err_rl("integer overflow while rounding up data_len"); 7571 return QDF_STATUS_E_FAILURE; 7572 } 7573 7574 if (oem_data_len_aligned > WMI_SVC_MSG_MAX_SIZE - WMI_TLV_HDR_SIZE) { 7575 wmi_err_rl("wmi_max_msg_size overflow for given data_len"); 7576 return QDF_STATUS_E_FAILURE; 7577 } 7578 7579 len += WMI_TLV_HDR_SIZE + oem_data_len_aligned; 7580 buf = wmi_buf_alloc(wmi_handle, len); 7581 if (!buf) 7582 return QDF_STATUS_E_NOMEM; 7583 7584 buf_ptr = (uint8_t *)wmi_buf_data(buf); 7585 cmd = (wmi_oem_data_cmd_fixed_param *)buf_ptr; 7586 WMITLV_SET_HDR(&cmd->tlv_header, 7587 WMITLV_TAG_STRUC_wmi_oem_data_cmd_fixed_param, 7588 WMITLV_GET_STRUCT_TLVLEN(wmi_oem_data_cmd_fixed_param)); 7589 7590 pdev_id = oem_data->pdev_id; 7591 if (oem_data->pdev_vdev_flag) { 7592 ops = wmi_handle->ops; 7593 if (oem_data->is_host_pdev_id) 7594 pdev_id = 7595 ops->convert_host_pdev_id_to_target(wmi_handle, 7596 pdev_id); 7597 else 7598 pdev_id = 7599 ops->convert_pdev_id_host_to_target(wmi_handle, 7600 pdev_id); 7601 } 7602 7603 cmd->vdev_id = oem_data->vdev_id; 7604 cmd->data_len = oem_data->data_len; 7605 cmd->pdev_vdev_flag = oem_data->pdev_vdev_flag; 7606 cmd->pdev_id = pdev_id; 7607 7608 buf_ptr += sizeof(*cmd); 7609 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, oem_data_len_aligned); 7610 buf_ptr += WMI_TLV_HDR_SIZE; 7611 qdf_mem_copy(buf_ptr, oem_data->data, oem_data->data_len); 7612 7613 wmi_mtrace(WMI_OEM_DATA_CMDID, NO_SESSION, 0); 7614 ret = wmi_unified_cmd_send(wmi_handle, buf, len, WMI_OEM_DATA_CMDID); 7615 if (QDF_IS_STATUS_ERROR(ret)) { 7616 wmi_err_rl("Failed with ret = %d", ret); 7617 wmi_buf_free(buf); 7618 } 7619 7620 return ret; 7621 } 7622 #endif 7623 7624 /** 7625 * send_dfs_phyerr_filter_offload_en_cmd_tlv() - enable dfs phyerr filter 7626 * @wmi_handle: wmi handle 7627 * @dfs_phyerr_filter_offload: is dfs phyerr filter offload 7628 * 7629 * Send WMI_DFS_PHYERR_FILTER_ENA_CMDID or 7630 * WMI_DFS_PHYERR_FILTER_DIS_CMDID command 7631 * to firmware based on phyerr filtering 7632 * offload status. 7633 * 7634 * Return: 1 success, 0 failure 7635 */ 7636 static QDF_STATUS 7637 send_dfs_phyerr_filter_offload_en_cmd_tlv(wmi_unified_t wmi_handle, 7638 bool dfs_phyerr_filter_offload) 7639 { 7640 wmi_dfs_phyerr_filter_ena_cmd_fixed_param *enable_phyerr_offload_cmd; 7641 wmi_dfs_phyerr_filter_dis_cmd_fixed_param *disable_phyerr_offload_cmd; 7642 wmi_buf_t buf; 7643 uint16_t len; 7644 QDF_STATUS ret; 7645 7646 7647 if (false == dfs_phyerr_filter_offload) { 7648 wmi_debug("Phyerror Filtering offload is Disabled in ini"); 7649 len = sizeof(*disable_phyerr_offload_cmd); 7650 buf = wmi_buf_alloc(wmi_handle, len); 7651 if (!buf) 7652 return 0; 7653 7654 disable_phyerr_offload_cmd = 7655 (wmi_dfs_phyerr_filter_dis_cmd_fixed_param *) 7656 wmi_buf_data(buf); 7657 7658 WMITLV_SET_HDR(&disable_phyerr_offload_cmd->tlv_header, 7659 WMITLV_TAG_STRUC_wmi_dfs_phyerr_filter_dis_cmd_fixed_param, 7660 WMITLV_GET_STRUCT_TLVLEN 7661 (wmi_dfs_phyerr_filter_dis_cmd_fixed_param)); 7662 7663 /* 7664 * Send WMI_DFS_PHYERR_FILTER_DIS_CMDID 7665 * to the firmware to disable the phyerror 7666 * filtering offload. 7667 */ 7668 wmi_mtrace(WMI_DFS_PHYERR_FILTER_DIS_CMDID, NO_SESSION, 0); 7669 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 7670 WMI_DFS_PHYERR_FILTER_DIS_CMDID); 7671 if (QDF_IS_STATUS_ERROR(ret)) { 7672 wmi_err("Failed to send WMI_DFS_PHYERR_FILTER_DIS_CMDID ret=%d", 7673 ret); 7674 wmi_buf_free(buf); 7675 return QDF_STATUS_E_FAILURE; 7676 } 7677 wmi_debug("WMI_DFS_PHYERR_FILTER_DIS_CMDID Send Success"); 7678 } else { 7679 wmi_debug("Phyerror Filtering offload is Enabled in ini"); 7680 7681 len = sizeof(*enable_phyerr_offload_cmd); 7682 buf = wmi_buf_alloc(wmi_handle, len); 7683 if (!buf) 7684 return QDF_STATUS_E_FAILURE; 7685 7686 enable_phyerr_offload_cmd = 7687 (wmi_dfs_phyerr_filter_ena_cmd_fixed_param *) 7688 wmi_buf_data(buf); 7689 7690 WMITLV_SET_HDR(&enable_phyerr_offload_cmd->tlv_header, 7691 WMITLV_TAG_STRUC_wmi_dfs_phyerr_filter_ena_cmd_fixed_param, 7692 WMITLV_GET_STRUCT_TLVLEN 7693 (wmi_dfs_phyerr_filter_ena_cmd_fixed_param)); 7694 7695 /* 7696 * Send a WMI_DFS_PHYERR_FILTER_ENA_CMDID 7697 * to the firmware to enable the phyerror 7698 * filtering offload. 7699 */ 7700 wmi_mtrace(WMI_DFS_PHYERR_FILTER_ENA_CMDID, NO_SESSION, 0); 7701 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 7702 WMI_DFS_PHYERR_FILTER_ENA_CMDID); 7703 7704 if (QDF_IS_STATUS_ERROR(ret)) { 7705 wmi_err("Failed to send DFS PHYERR CMD ret=%d", ret); 7706 wmi_buf_free(buf); 7707 return QDF_STATUS_E_FAILURE; 7708 } 7709 wmi_debug("WMI_DFS_PHYERR_FILTER_ENA_CMDID Send Success"); 7710 } 7711 7712 return QDF_STATUS_SUCCESS; 7713 } 7714 7715 #if !defined(REMOVE_PKT_LOG) && defined(FEATURE_PKTLOG) 7716 /** 7717 * send_pktlog_wmi_send_cmd_tlv() - send pktlog enable/disable command to target 7718 * @wmi_handle: wmi handle 7719 * @pktlog_event: pktlog event 7720 * @cmd_id: pktlog cmd id 7721 * @user_triggered: user triggered input for PKTLOG enable mode 7722 * 7723 * Return: QDF status 7724 */ 7725 static QDF_STATUS send_pktlog_wmi_send_cmd_tlv(wmi_unified_t wmi_handle, 7726 WMI_PKTLOG_EVENT pktlog_event, 7727 WMI_CMD_ID cmd_id, uint8_t user_triggered) 7728 { 7729 WMI_PKTLOG_EVENT PKTLOG_EVENT; 7730 WMI_CMD_ID CMD_ID; 7731 wmi_pdev_pktlog_enable_cmd_fixed_param *cmd; 7732 wmi_pdev_pktlog_disable_cmd_fixed_param *disable_cmd; 7733 int len = 0; 7734 wmi_buf_t buf; 7735 int32_t idx, max_idx; 7736 7737 PKTLOG_EVENT = pktlog_event; 7738 CMD_ID = cmd_id; 7739 7740 max_idx = sizeof(pktlog_event_tlv) / (sizeof(pktlog_event_tlv[0])); 7741 switch (CMD_ID) { 7742 case WMI_PDEV_PKTLOG_ENABLE_CMDID: 7743 len = sizeof(*cmd); 7744 buf = wmi_buf_alloc(wmi_handle, len); 7745 if (!buf) 7746 return QDF_STATUS_E_NOMEM; 7747 7748 cmd = (wmi_pdev_pktlog_enable_cmd_fixed_param *) 7749 wmi_buf_data(buf); 7750 WMITLV_SET_HDR(&cmd->tlv_header, 7751 WMITLV_TAG_STRUC_wmi_pdev_pktlog_enable_cmd_fixed_param, 7752 WMITLV_GET_STRUCT_TLVLEN 7753 (wmi_pdev_pktlog_enable_cmd_fixed_param)); 7754 cmd->evlist = 0; 7755 for (idx = 0; idx < max_idx; idx++) { 7756 if (PKTLOG_EVENT & (1 << idx)) 7757 cmd->evlist |= pktlog_event_tlv[idx]; 7758 } 7759 cmd->enable = user_triggered ? WMI_PKTLOG_ENABLE_FORCE 7760 : WMI_PKTLOG_ENABLE_AUTO; 7761 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 7762 wmi_handle, 7763 WMI_HOST_PDEV_ID_SOC); 7764 wmi_mtrace(WMI_PDEV_PKTLOG_ENABLE_CMDID, NO_SESSION, 0); 7765 if (wmi_unified_cmd_send(wmi_handle, buf, len, 7766 WMI_PDEV_PKTLOG_ENABLE_CMDID)) { 7767 wmi_err("Failed to send pktlog enable cmdid"); 7768 goto wmi_send_failed; 7769 } 7770 break; 7771 case WMI_PDEV_PKTLOG_DISABLE_CMDID: 7772 len = sizeof(*disable_cmd); 7773 buf = wmi_buf_alloc(wmi_handle, len); 7774 if (!buf) 7775 return QDF_STATUS_E_NOMEM; 7776 7777 disable_cmd = (wmi_pdev_pktlog_disable_cmd_fixed_param *) 7778 wmi_buf_data(buf); 7779 WMITLV_SET_HDR(&disable_cmd->tlv_header, 7780 WMITLV_TAG_STRUC_wmi_pdev_pktlog_disable_cmd_fixed_param, 7781 WMITLV_GET_STRUCT_TLVLEN 7782 (wmi_pdev_pktlog_disable_cmd_fixed_param)); 7783 disable_cmd->pdev_id = 7784 wmi_handle->ops->convert_pdev_id_host_to_target( 7785 wmi_handle, 7786 WMI_HOST_PDEV_ID_SOC); 7787 wmi_mtrace(WMI_PDEV_PKTLOG_DISABLE_CMDID, NO_SESSION, 0); 7788 if (wmi_unified_cmd_send(wmi_handle, buf, len, 7789 WMI_PDEV_PKTLOG_DISABLE_CMDID)) { 7790 wmi_err("failed to send pktlog disable cmdid"); 7791 goto wmi_send_failed; 7792 } 7793 break; 7794 default: 7795 wmi_debug("Invalid PKTLOG command: %d", CMD_ID); 7796 break; 7797 } 7798 7799 return QDF_STATUS_SUCCESS; 7800 7801 wmi_send_failed: 7802 wmi_buf_free(buf); 7803 return QDF_STATUS_E_FAILURE; 7804 } 7805 #endif /* !REMOVE_PKT_LOG && FEATURE_PKTLOG */ 7806 7807 /** 7808 * send_stats_ext_req_cmd_tlv() - request ext stats from fw 7809 * @wmi_handle: wmi handle 7810 * @preq: stats ext params 7811 * 7812 * Return: QDF status 7813 */ 7814 static QDF_STATUS send_stats_ext_req_cmd_tlv(wmi_unified_t wmi_handle, 7815 struct stats_ext_params *preq) 7816 { 7817 QDF_STATUS ret; 7818 wmi_req_stats_ext_cmd_fixed_param *cmd; 7819 wmi_buf_t buf; 7820 size_t len; 7821 uint8_t *buf_ptr; 7822 uint16_t max_wmi_msg_size = wmi_get_max_msg_len(wmi_handle); 7823 uint32_t *vdev_bitmap; 7824 7825 if (preq->request_data_len > (max_wmi_msg_size - WMI_TLV_HDR_SIZE - 7826 sizeof(*cmd))) { 7827 wmi_err("Data length=%d is greater than max wmi msg size", 7828 preq->request_data_len); 7829 return QDF_STATUS_E_FAILURE; 7830 } 7831 7832 len = sizeof(*cmd) + WMI_TLV_HDR_SIZE + preq->request_data_len + 7833 WMI_TLV_HDR_SIZE + sizeof(uint32_t); 7834 7835 buf = wmi_buf_alloc(wmi_handle, len); 7836 if (!buf) 7837 return QDF_STATUS_E_NOMEM; 7838 7839 buf_ptr = (uint8_t *) wmi_buf_data(buf); 7840 cmd = (wmi_req_stats_ext_cmd_fixed_param *) buf_ptr; 7841 7842 WMITLV_SET_HDR(&cmd->tlv_header, 7843 WMITLV_TAG_STRUC_wmi_req_stats_ext_cmd_fixed_param, 7844 WMITLV_GET_STRUCT_TLVLEN 7845 (wmi_req_stats_ext_cmd_fixed_param)); 7846 cmd->vdev_id = preq->vdev_id; 7847 cmd->data_len = preq->request_data_len; 7848 7849 wmi_debug("The data len value is %u and vdev id set is %u", 7850 preq->request_data_len, preq->vdev_id); 7851 7852 buf_ptr += sizeof(wmi_req_stats_ext_cmd_fixed_param); 7853 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, cmd->data_len); 7854 7855 buf_ptr += WMI_TLV_HDR_SIZE; 7856 qdf_mem_copy(buf_ptr, preq->request_data, cmd->data_len); 7857 7858 buf_ptr += cmd->data_len; 7859 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, sizeof(uint32_t)); 7860 7861 buf_ptr += WMI_TLV_HDR_SIZE; 7862 7863 vdev_bitmap = (A_UINT32 *)buf_ptr; 7864 7865 vdev_bitmap[0] = preq->vdev_id_bitmap; 7866 7867 wmi_debug("Sending MLO vdev_id_bitmap:%x", vdev_bitmap[0]); 7868 7869 buf_ptr += sizeof(uint32_t); 7870 7871 wmi_mtrace(WMI_REQUEST_STATS_EXT_CMDID, cmd->vdev_id, 0); 7872 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 7873 WMI_REQUEST_STATS_EXT_CMDID); 7874 if (QDF_IS_STATUS_ERROR(ret)) { 7875 wmi_err("Failed to send notify cmd ret = %d", ret); 7876 wmi_buf_free(buf); 7877 } 7878 7879 return ret; 7880 } 7881 7882 /** 7883 * send_process_dhcpserver_offload_cmd_tlv() - enable DHCP server offload 7884 * @wmi_handle: wmi handle 7885 * @params: DHCP server offload info 7886 * 7887 * Return: QDF_STATUS_SUCCESS for success or error code 7888 */ 7889 static QDF_STATUS 7890 send_process_dhcpserver_offload_cmd_tlv(wmi_unified_t wmi_handle, 7891 struct dhcp_offload_info_params *params) 7892 { 7893 wmi_set_dhcp_server_offload_cmd_fixed_param *cmd; 7894 wmi_buf_t buf; 7895 QDF_STATUS status; 7896 7897 buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd)); 7898 if (!buf) 7899 return QDF_STATUS_E_NOMEM; 7900 7901 cmd = (wmi_set_dhcp_server_offload_cmd_fixed_param *) wmi_buf_data(buf); 7902 7903 WMITLV_SET_HDR(&cmd->tlv_header, 7904 WMITLV_TAG_STRUC_wmi_set_dhcp_server_offload_cmd_fixed_param, 7905 WMITLV_GET_STRUCT_TLVLEN 7906 (wmi_set_dhcp_server_offload_cmd_fixed_param)); 7907 cmd->vdev_id = params->vdev_id; 7908 cmd->enable = params->dhcp_offload_enabled; 7909 cmd->num_client = params->dhcp_client_num; 7910 cmd->srv_ipv4 = params->dhcp_srv_addr; 7911 cmd->start_lsb = 0; 7912 wmi_mtrace(WMI_SET_DHCP_SERVER_OFFLOAD_CMDID, cmd->vdev_id, 0); 7913 status = wmi_unified_cmd_send(wmi_handle, buf, 7914 sizeof(*cmd), 7915 WMI_SET_DHCP_SERVER_OFFLOAD_CMDID); 7916 if (QDF_IS_STATUS_ERROR(status)) { 7917 wmi_err("Failed to send set_dhcp_server_offload cmd"); 7918 wmi_buf_free(buf); 7919 return QDF_STATUS_E_FAILURE; 7920 } 7921 wmi_debug("Set dhcp server offload to vdevId %d", params->vdev_id); 7922 7923 return status; 7924 } 7925 7926 /** 7927 * send_pdev_set_regdomain_cmd_tlv() - send set regdomain command to fw 7928 * @wmi_handle: wmi handle 7929 * @param: pointer to pdev regdomain params 7930 * 7931 * Return: QDF_STATUS_SUCCESS for success or error code 7932 */ 7933 static QDF_STATUS 7934 send_pdev_set_regdomain_cmd_tlv(wmi_unified_t wmi_handle, 7935 struct pdev_set_regdomain_params *param) 7936 { 7937 wmi_buf_t buf; 7938 wmi_pdev_set_regdomain_cmd_fixed_param *cmd; 7939 int32_t len = sizeof(*cmd); 7940 7941 buf = wmi_buf_alloc(wmi_handle, len); 7942 if (!buf) 7943 return QDF_STATUS_E_NOMEM; 7944 7945 cmd = (wmi_pdev_set_regdomain_cmd_fixed_param *) wmi_buf_data(buf); 7946 WMITLV_SET_HDR(&cmd->tlv_header, 7947 WMITLV_TAG_STRUC_wmi_pdev_set_regdomain_cmd_fixed_param, 7948 WMITLV_GET_STRUCT_TLVLEN 7949 (wmi_pdev_set_regdomain_cmd_fixed_param)); 7950 7951 cmd->reg_domain = param->currentRDinuse; 7952 cmd->reg_domain_2G = param->currentRD2G; 7953 cmd->reg_domain_5G = param->currentRD5G; 7954 cmd->conformance_test_limit_2G = param->ctl_2G; 7955 cmd->conformance_test_limit_5G = param->ctl_5G; 7956 cmd->dfs_domain = param->dfsDomain; 7957 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 7958 wmi_handle, 7959 param->pdev_id); 7960 7961 wmi_mtrace(WMI_PDEV_SET_REGDOMAIN_CMDID, NO_SESSION, 0); 7962 if (wmi_unified_cmd_send(wmi_handle, buf, len, 7963 WMI_PDEV_SET_REGDOMAIN_CMDID)) { 7964 wmi_err("Failed to send pdev set regdomain command"); 7965 wmi_buf_free(buf); 7966 return QDF_STATUS_E_FAILURE; 7967 } 7968 7969 return QDF_STATUS_SUCCESS; 7970 } 7971 7972 /** 7973 * send_regdomain_info_to_fw_cmd_tlv() - send regdomain info to fw 7974 * @wmi_handle: wmi handle 7975 * @reg_dmn: reg domain 7976 * @regdmn2G: 2G reg domain 7977 * @regdmn5G: 5G reg domain 7978 * @ctl2G: 2G test limit 7979 * @ctl5G: 5G test limit 7980 * 7981 * Return: none 7982 */ 7983 static QDF_STATUS send_regdomain_info_to_fw_cmd_tlv(wmi_unified_t wmi_handle, 7984 uint32_t reg_dmn, uint16_t regdmn2G, 7985 uint16_t regdmn5G, uint8_t ctl2G, 7986 uint8_t ctl5G) 7987 { 7988 wmi_buf_t buf; 7989 wmi_pdev_set_regdomain_cmd_fixed_param *cmd; 7990 int32_t len = sizeof(*cmd); 7991 7992 7993 buf = wmi_buf_alloc(wmi_handle, len); 7994 if (!buf) 7995 return QDF_STATUS_E_NOMEM; 7996 7997 cmd = (wmi_pdev_set_regdomain_cmd_fixed_param *) wmi_buf_data(buf); 7998 WMITLV_SET_HDR(&cmd->tlv_header, 7999 WMITLV_TAG_STRUC_wmi_pdev_set_regdomain_cmd_fixed_param, 8000 WMITLV_GET_STRUCT_TLVLEN 8001 (wmi_pdev_set_regdomain_cmd_fixed_param)); 8002 cmd->reg_domain = reg_dmn; 8003 cmd->reg_domain_2G = regdmn2G; 8004 cmd->reg_domain_5G = regdmn5G; 8005 cmd->conformance_test_limit_2G = ctl2G; 8006 cmd->conformance_test_limit_5G = ctl5G; 8007 8008 wmi_debug("regd = %x, regd_2g = %x, regd_5g = %x, ctl_2g = %x, ctl_5g = %x", 8009 cmd->reg_domain, cmd->reg_domain_2G, cmd->reg_domain_5G, 8010 cmd->conformance_test_limit_2G, 8011 cmd->conformance_test_limit_5G); 8012 8013 wmi_mtrace(WMI_PDEV_SET_REGDOMAIN_CMDID, NO_SESSION, 0); 8014 if (wmi_unified_cmd_send(wmi_handle, buf, len, 8015 WMI_PDEV_SET_REGDOMAIN_CMDID)) { 8016 wmi_err("Failed to send pdev set regdomain command"); 8017 wmi_buf_free(buf); 8018 return QDF_STATUS_E_FAILURE; 8019 } 8020 8021 return QDF_STATUS_SUCCESS; 8022 } 8023 8024 /** 8025 * copy_custom_aggr_bitmap() - copies host side bitmap using FW APIs 8026 * @param: param sent from the host side 8027 * @cmd: param to be sent to the fw side 8028 */ 8029 static inline void copy_custom_aggr_bitmap( 8030 struct set_custom_aggr_size_params *param, 8031 wmi_vdev_set_custom_aggr_size_cmd_fixed_param *cmd) 8032 { 8033 WMI_VDEV_CUSTOM_AGGR_AC_SET(cmd->enable_bitmap, 8034 param->ac); 8035 WMI_VDEV_CUSTOM_AGGR_TYPE_SET(cmd->enable_bitmap, 8036 param->aggr_type); 8037 WMI_VDEV_CUSTOM_TX_AGGR_SZ_DIS_SET(cmd->enable_bitmap, 8038 param->tx_aggr_size_disable); 8039 WMI_VDEV_CUSTOM_RX_AGGR_SZ_DIS_SET(cmd->enable_bitmap, 8040 param->rx_aggr_size_disable); 8041 WMI_VDEV_CUSTOM_TX_AC_EN_SET(cmd->enable_bitmap, 8042 param->tx_ac_enable); 8043 WMI_VDEV_CUSTOM_AGGR_256_BA_EN_SET(cmd->enable_bitmap, 8044 param->aggr_ba_enable); 8045 } 8046 8047 /** 8048 * send_vdev_set_custom_aggr_size_cmd_tlv() - custom aggr size param in fw 8049 * @wmi_handle: wmi handle 8050 * @param: pointer to hold custom aggr size params 8051 * 8052 * Return: QDF_STATUS_SUCCESS for success or error code 8053 */ 8054 static QDF_STATUS send_vdev_set_custom_aggr_size_cmd_tlv( 8055 wmi_unified_t wmi_handle, 8056 struct set_custom_aggr_size_params *param) 8057 { 8058 wmi_vdev_set_custom_aggr_size_cmd_fixed_param *cmd; 8059 wmi_buf_t buf; 8060 int32_t len = sizeof(*cmd); 8061 8062 buf = wmi_buf_alloc(wmi_handle, len); 8063 if (!buf) 8064 return QDF_STATUS_E_FAILURE; 8065 8066 cmd = (wmi_vdev_set_custom_aggr_size_cmd_fixed_param *) 8067 wmi_buf_data(buf); 8068 WMITLV_SET_HDR(&cmd->tlv_header, 8069 WMITLV_TAG_STRUC_wmi_vdev_set_custom_aggr_size_cmd_fixed_param, 8070 WMITLV_GET_STRUCT_TLVLEN( 8071 wmi_vdev_set_custom_aggr_size_cmd_fixed_param)); 8072 cmd->vdev_id = param->vdev_id; 8073 cmd->tx_aggr_size = param->tx_aggr_size; 8074 cmd->rx_aggr_size = param->rx_aggr_size; 8075 copy_custom_aggr_bitmap(param, cmd); 8076 8077 wmi_debug("Set custom aggr: vdev id=0x%X, tx aggr size=0x%X " 8078 "rx_aggr_size=0x%X access category=0x%X, agg_type=0x%X " 8079 "tx_aggr_size_disable=0x%X, rx_aggr_size_disable=0x%X " 8080 "tx_ac_enable=0x%X", 8081 param->vdev_id, param->tx_aggr_size, param->rx_aggr_size, 8082 param->ac, param->aggr_type, param->tx_aggr_size_disable, 8083 param->rx_aggr_size_disable, param->tx_ac_enable); 8084 8085 wmi_mtrace(WMI_VDEV_SET_CUSTOM_AGGR_SIZE_CMDID, cmd->vdev_id, 0); 8086 if (wmi_unified_cmd_send(wmi_handle, buf, len, 8087 WMI_VDEV_SET_CUSTOM_AGGR_SIZE_CMDID)) { 8088 wmi_err("Setting custom aggregation size failed"); 8089 wmi_buf_free(buf); 8090 return QDF_STATUS_E_FAILURE; 8091 } 8092 8093 return QDF_STATUS_SUCCESS; 8094 } 8095 8096 /** 8097 * send_vdev_set_qdepth_thresh_cmd_tlv() - WMI set qdepth threshold 8098 * @wmi_handle: handle to WMI. 8099 * @param: pointer to tx antenna param 8100 * 8101 * Return: QDF_STATUS_SUCCESS for success or error code 8102 */ 8103 8104 static QDF_STATUS send_vdev_set_qdepth_thresh_cmd_tlv(wmi_unified_t wmi_handle, 8105 struct set_qdepth_thresh_params *param) 8106 { 8107 wmi_peer_tid_msduq_qdepth_thresh_update_cmd_fixed_param *cmd; 8108 wmi_msduq_qdepth_thresh_update *cmd_update; 8109 wmi_buf_t buf; 8110 int32_t len = 0; 8111 int i; 8112 uint8_t *buf_ptr; 8113 QDF_STATUS ret; 8114 8115 if (param->num_of_msduq_updates > QDEPTH_THRESH_MAX_UPDATES) { 8116 wmi_err("Invalid Update Count!"); 8117 return QDF_STATUS_E_INVAL; 8118 } 8119 8120 len = sizeof(*cmd) + WMI_TLV_HDR_SIZE; 8121 len += (sizeof(wmi_msduq_qdepth_thresh_update) * 8122 param->num_of_msduq_updates); 8123 buf = wmi_buf_alloc(wmi_handle, len); 8124 8125 if (!buf) 8126 return QDF_STATUS_E_NOMEM; 8127 8128 buf_ptr = (uint8_t *)wmi_buf_data(buf); 8129 cmd = (wmi_peer_tid_msduq_qdepth_thresh_update_cmd_fixed_param *) 8130 buf_ptr; 8131 8132 WMITLV_SET_HDR(&cmd->tlv_header, 8133 WMITLV_TAG_STRUC_wmi_peer_tid_msduq_qdepth_thresh_update_cmd_fixed_param 8134 , WMITLV_GET_STRUCT_TLVLEN( 8135 wmi_peer_tid_msduq_qdepth_thresh_update_cmd_fixed_param)); 8136 8137 cmd->pdev_id = 8138 wmi_handle->ops->convert_pdev_id_host_to_target( 8139 wmi_handle, 8140 param->pdev_id); 8141 cmd->vdev_id = param->vdev_id; 8142 WMI_CHAR_ARRAY_TO_MAC_ADDR(param->mac_addr, &cmd->peer_mac_address); 8143 cmd->num_of_msduq_updates = param->num_of_msduq_updates; 8144 8145 buf_ptr += sizeof( 8146 wmi_peer_tid_msduq_qdepth_thresh_update_cmd_fixed_param); 8147 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 8148 param->num_of_msduq_updates * 8149 sizeof(wmi_msduq_qdepth_thresh_update)); 8150 buf_ptr += WMI_TLV_HDR_SIZE; 8151 cmd_update = (wmi_msduq_qdepth_thresh_update *)buf_ptr; 8152 8153 for (i = 0; i < cmd->num_of_msduq_updates; i++) { 8154 WMITLV_SET_HDR(&cmd_update->tlv_header, 8155 WMITLV_TAG_STRUC_wmi_msduq_qdepth_thresh_update, 8156 WMITLV_GET_STRUCT_TLVLEN( 8157 wmi_msduq_qdepth_thresh_update)); 8158 cmd_update->tid_num = param->update_params[i].tid_num; 8159 cmd_update->msduq_update_mask = 8160 param->update_params[i].msduq_update_mask; 8161 cmd_update->qdepth_thresh_value = 8162 param->update_params[i].qdepth_thresh_value; 8163 wmi_debug("Set QDepth Threshold: vdev=0x%X pdev=0x%X, tid=0x%X " 8164 "mac_addr_upper4=%X, mac_addr_lower2:%X," 8165 " update mask=0x%X thresh val=0x%X", 8166 cmd->vdev_id, cmd->pdev_id, cmd_update->tid_num, 8167 cmd->peer_mac_address.mac_addr31to0, 8168 cmd->peer_mac_address.mac_addr47to32, 8169 cmd_update->msduq_update_mask, 8170 cmd_update->qdepth_thresh_value); 8171 cmd_update++; 8172 } 8173 8174 wmi_mtrace(WMI_PEER_TID_MSDUQ_QDEPTH_THRESH_UPDATE_CMDID, 8175 cmd->vdev_id, 0); 8176 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 8177 WMI_PEER_TID_MSDUQ_QDEPTH_THRESH_UPDATE_CMDID); 8178 8179 if (ret != 0) { 8180 wmi_err("Failed to send WMI_PEER_TID_MSDUQ_QDEPTH_THRESH_UPDATE_CMDID"); 8181 wmi_buf_free(buf); 8182 } 8183 8184 return ret; 8185 } 8186 8187 /** 8188 * send_set_vap_dscp_tid_map_cmd_tlv() - send vap dscp tid map cmd to fw 8189 * @wmi_handle: wmi handle 8190 * @param: pointer to hold vap dscp tid map param 8191 * 8192 * Return: QDF_STATUS_SUCCESS for success or error code 8193 */ 8194 static QDF_STATUS 8195 send_set_vap_dscp_tid_map_cmd_tlv(wmi_unified_t wmi_handle, 8196 struct vap_dscp_tid_map_params *param) 8197 { 8198 wmi_buf_t buf; 8199 wmi_vdev_set_dscp_tid_map_cmd_fixed_param *cmd; 8200 int32_t len = sizeof(*cmd); 8201 8202 buf = wmi_buf_alloc(wmi_handle, len); 8203 if (!buf) 8204 return QDF_STATUS_E_FAILURE; 8205 8206 cmd = (wmi_vdev_set_dscp_tid_map_cmd_fixed_param *)wmi_buf_data(buf); 8207 qdf_mem_copy(cmd->dscp_to_tid_map, param->dscp_to_tid_map, 8208 sizeof(uint32_t) * WMI_DSCP_MAP_MAX); 8209 8210 cmd->vdev_id = param->vdev_id; 8211 cmd->enable_override = 0; 8212 8213 wmi_debug("Setting dscp for vap id: %d", cmd->vdev_id); 8214 wmi_mtrace(WMI_VDEV_SET_DSCP_TID_MAP_CMDID, cmd->vdev_id, 0); 8215 if (wmi_unified_cmd_send(wmi_handle, buf, len, 8216 WMI_VDEV_SET_DSCP_TID_MAP_CMDID)) { 8217 wmi_err("Failed to set dscp cmd"); 8218 wmi_buf_free(buf); 8219 return QDF_STATUS_E_FAILURE; 8220 } 8221 8222 return QDF_STATUS_SUCCESS; 8223 } 8224 8225 /** 8226 * send_vdev_set_fwtest_param_cmd_tlv() - send fwtest param in fw 8227 * @wmi_handle: wmi handle 8228 * @param: pointer to hold fwtest param 8229 * 8230 * Return: QDF_STATUS_SUCCESS for success or error code 8231 */ 8232 static QDF_STATUS send_vdev_set_fwtest_param_cmd_tlv(wmi_unified_t wmi_handle, 8233 struct set_fwtest_params *param) 8234 { 8235 wmi_fwtest_set_param_cmd_fixed_param *cmd; 8236 wmi_buf_t buf; 8237 int32_t len = sizeof(*cmd); 8238 8239 buf = wmi_buf_alloc(wmi_handle, len); 8240 8241 if (!buf) 8242 return QDF_STATUS_E_FAILURE; 8243 8244 cmd = (wmi_fwtest_set_param_cmd_fixed_param *)wmi_buf_data(buf); 8245 WMITLV_SET_HDR(&cmd->tlv_header, 8246 WMITLV_TAG_STRUC_wmi_fwtest_set_param_cmd_fixed_param, 8247 WMITLV_GET_STRUCT_TLVLEN( 8248 wmi_fwtest_set_param_cmd_fixed_param)); 8249 cmd->param_id = param->arg; 8250 cmd->param_value = param->value; 8251 8252 wmi_mtrace(WMI_FWTEST_CMDID, NO_SESSION, 0); 8253 if (wmi_unified_cmd_send(wmi_handle, buf, len, WMI_FWTEST_CMDID)) { 8254 wmi_err("Setting FW test param failed"); 8255 wmi_buf_free(buf); 8256 return QDF_STATUS_E_FAILURE; 8257 } 8258 8259 return QDF_STATUS_SUCCESS; 8260 } 8261 8262 /** 8263 * send_phyerr_disable_cmd_tlv() - WMI phyerr disable function 8264 * @wmi_handle: handle to WMI. 8265 * 8266 * Return: QDF_STATUS_SUCCESS for success or error code 8267 */ 8268 static QDF_STATUS send_phyerr_disable_cmd_tlv(wmi_unified_t wmi_handle) 8269 { 8270 wmi_pdev_dfs_disable_cmd_fixed_param *cmd; 8271 wmi_buf_t buf; 8272 QDF_STATUS ret; 8273 int32_t len; 8274 8275 len = sizeof(*cmd); 8276 8277 buf = wmi_buf_alloc(wmi_handle, len); 8278 if (!buf) 8279 return QDF_STATUS_E_FAILURE; 8280 8281 cmd = (wmi_pdev_dfs_disable_cmd_fixed_param *)wmi_buf_data(buf); 8282 WMITLV_SET_HDR(&cmd->tlv_header, 8283 WMITLV_TAG_STRUC_wmi_pdev_dfs_disable_cmd_fixed_param, 8284 WMITLV_GET_STRUCT_TLVLEN( 8285 wmi_pdev_dfs_disable_cmd_fixed_param)); 8286 /* Filling it with WMI_PDEV_ID_SOC for now */ 8287 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 8288 wmi_handle, 8289 WMI_HOST_PDEV_ID_SOC); 8290 8291 wmi_mtrace(WMI_PDEV_DFS_DISABLE_CMDID, NO_SESSION, 0); 8292 ret = wmi_unified_cmd_send(wmi_handle, buf, sizeof(*cmd), 8293 WMI_PDEV_DFS_DISABLE_CMDID); 8294 8295 if (ret != 0) { 8296 wmi_err("Sending PDEV DFS disable cmd failed"); 8297 wmi_buf_free(buf); 8298 } 8299 8300 return ret; 8301 } 8302 8303 /** 8304 * send_phyerr_enable_cmd_tlv() - WMI phyerr disable function 8305 * @wmi_handle: handle to WMI. 8306 * 8307 * Return: QDF_STATUS_SUCCESS for success or error code 8308 */ 8309 static QDF_STATUS send_phyerr_enable_cmd_tlv(wmi_unified_t wmi_handle) 8310 { 8311 wmi_pdev_dfs_enable_cmd_fixed_param *cmd; 8312 wmi_buf_t buf; 8313 QDF_STATUS ret; 8314 int32_t len; 8315 8316 len = sizeof(*cmd); 8317 8318 buf = wmi_buf_alloc(wmi_handle, len); 8319 if (!buf) 8320 return QDF_STATUS_E_FAILURE; 8321 8322 cmd = (wmi_pdev_dfs_enable_cmd_fixed_param *)wmi_buf_data(buf); 8323 WMITLV_SET_HDR(&cmd->tlv_header, 8324 WMITLV_TAG_STRUC_wmi_pdev_dfs_enable_cmd_fixed_param, 8325 WMITLV_GET_STRUCT_TLVLEN( 8326 wmi_pdev_dfs_enable_cmd_fixed_param)); 8327 /* Reserved for future use */ 8328 cmd->reserved0 = 0; 8329 8330 wmi_mtrace(WMI_PDEV_DFS_ENABLE_CMDID, NO_SESSION, 0); 8331 ret = wmi_unified_cmd_send(wmi_handle, buf, sizeof(*cmd), 8332 WMI_PDEV_DFS_ENABLE_CMDID); 8333 8334 if (ret != 0) { 8335 wmi_err("Sending PDEV DFS enable cmd failed"); 8336 wmi_buf_free(buf); 8337 } 8338 8339 return ret; 8340 } 8341 8342 /** 8343 * send_periodic_chan_stats_config_cmd_tlv() - send periodic chan stats cmd 8344 * to fw 8345 * @wmi_handle: wmi handle 8346 * @param: pointer to hold periodic chan stats param 8347 * 8348 * Return: QDF_STATUS_SUCCESS for success or error code 8349 */ 8350 static QDF_STATUS 8351 send_periodic_chan_stats_config_cmd_tlv(wmi_unified_t wmi_handle, 8352 struct periodic_chan_stats_params *param) 8353 { 8354 wmi_set_periodic_channel_stats_config_fixed_param *cmd; 8355 wmi_buf_t buf; 8356 QDF_STATUS ret; 8357 int32_t len; 8358 8359 len = sizeof(*cmd); 8360 8361 buf = wmi_buf_alloc(wmi_handle, len); 8362 if (!buf) 8363 return QDF_STATUS_E_FAILURE; 8364 8365 cmd = (wmi_set_periodic_channel_stats_config_fixed_param *) 8366 wmi_buf_data(buf); 8367 WMITLV_SET_HDR(&cmd->tlv_header, 8368 WMITLV_TAG_STRUC_wmi_set_periodic_channel_stats_config_fixed_param, 8369 WMITLV_GET_STRUCT_TLVLEN( 8370 wmi_set_periodic_channel_stats_config_fixed_param)); 8371 cmd->enable = param->enable; 8372 cmd->stats_period = param->stats_period; 8373 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 8374 wmi_handle, 8375 param->pdev_id); 8376 8377 wmi_mtrace(WMI_SET_PERIODIC_CHANNEL_STATS_CONFIG_CMDID, NO_SESSION, 0); 8378 ret = wmi_unified_cmd_send(wmi_handle, buf, sizeof(*cmd), 8379 WMI_SET_PERIODIC_CHANNEL_STATS_CONFIG_CMDID); 8380 8381 if (ret != 0) { 8382 wmi_err("Sending periodic chan stats config failed"); 8383 wmi_buf_free(buf); 8384 } 8385 8386 return ret; 8387 } 8388 8389 #ifdef WLAN_IOT_SIM_SUPPORT 8390 /** 8391 * send_simulation_test_cmd_tlv() - send simulation test command to fw 8392 * 8393 * @wmi_handle: wmi handle 8394 * @param: pointer to hold simulation test parameter 8395 * 8396 * Return: QDF_STATUS_SUCCESS for success or error code 8397 */ 8398 static QDF_STATUS send_simulation_test_cmd_tlv(wmi_unified_t wmi_handle, 8399 struct simulation_test_params 8400 *param) 8401 { 8402 wmi_simulation_test_cmd_fixed_param *cmd; 8403 u32 wmi_buf_len; 8404 wmi_buf_t buf; 8405 u8 *buf_ptr; 8406 u32 aligned_len = 0; 8407 8408 wmi_buf_len = sizeof(*cmd); 8409 if (param->buf_len) { 8410 aligned_len = roundup(param->buf_len, sizeof(A_UINT32)); 8411 wmi_buf_len += WMI_TLV_HDR_SIZE + aligned_len; 8412 } 8413 8414 buf = wmi_buf_alloc(wmi_handle, wmi_buf_len); 8415 if (!buf) { 8416 wmi_err("wmi_buf_alloc failed"); 8417 return QDF_STATUS_E_NOMEM; 8418 } 8419 8420 buf_ptr = wmi_buf_data(buf); 8421 cmd = (wmi_simulation_test_cmd_fixed_param *)buf_ptr; 8422 WMITLV_SET_HDR(&cmd->tlv_header, 8423 WMITLV_TAG_STRUC_wmi_simulation_test_cmd_fixed_param, 8424 WMITLV_GET_STRUCT_TLVLEN( 8425 wmi_simulation_test_cmd_fixed_param)); 8426 cmd->pdev_id = param->pdev_id; 8427 cmd->vdev_id = param->vdev_id; 8428 WMI_CHAR_ARRAY_TO_MAC_ADDR(param->peer_mac, &cmd->peer_macaddr); 8429 cmd->test_cmd_type = param->test_cmd_type; 8430 cmd->test_subcmd_type = param->test_subcmd_type; 8431 WMI_SIM_FRAME_TYPE_SET(cmd->frame_type_subtype_seq, param->frame_type); 8432 WMI_SIM_FRAME_SUBTYPE_SET(cmd->frame_type_subtype_seq, 8433 param->frame_subtype); 8434 WMI_SIM_FRAME_SEQ_SET(cmd->frame_type_subtype_seq, param->seq); 8435 WMI_SIM_FRAME_OFFSET_SET(cmd->frame_offset_length, param->offset); 8436 WMI_SIM_FRAME_LENGTH_SET(cmd->frame_offset_length, param->frame_length); 8437 cmd->buf_len = param->buf_len; 8438 8439 if (param->buf_len) { 8440 buf_ptr += sizeof(*cmd); 8441 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, aligned_len); 8442 buf_ptr += WMI_TLV_HDR_SIZE; 8443 qdf_mem_copy(buf_ptr, param->bufp, param->buf_len); 8444 } 8445 8446 if (wmi_unified_cmd_send(wmi_handle, buf, wmi_buf_len, 8447 WMI_SIMULATION_TEST_CMDID)) { 8448 wmi_err("Failed to send test simulation cmd"); 8449 wmi_buf_free(buf); 8450 return QDF_STATUS_E_FAILURE; 8451 } 8452 8453 return QDF_STATUS_SUCCESS; 8454 } 8455 #endif 8456 8457 #ifdef WLAN_FEATURE_11BE 8458 #define WLAN_PHY_CH_WIDTH_320MHZ CH_WIDTH_320MHZ 8459 #else 8460 #define WLAN_PHY_CH_WIDTH_320MHZ CH_WIDTH_INVALID 8461 #endif 8462 enum phy_ch_width wmi_map_ch_width(A_UINT32 wmi_width) 8463 { 8464 switch (wmi_width) { 8465 case WMI_CHAN_WIDTH_20: 8466 return CH_WIDTH_20MHZ; 8467 case WMI_CHAN_WIDTH_40: 8468 return CH_WIDTH_40MHZ; 8469 case WMI_CHAN_WIDTH_80: 8470 return CH_WIDTH_80MHZ; 8471 case WMI_CHAN_WIDTH_160: 8472 return CH_WIDTH_160MHZ; 8473 case WMI_CHAN_WIDTH_80P80: 8474 return CH_WIDTH_80P80MHZ; 8475 case WMI_CHAN_WIDTH_5: 8476 return CH_WIDTH_5MHZ; 8477 case WMI_CHAN_WIDTH_10: 8478 return CH_WIDTH_10MHZ; 8479 case WMI_CHAN_WIDTH_320: 8480 return WLAN_PHY_CH_WIDTH_320MHZ; 8481 default: 8482 return CH_WIDTH_INVALID; 8483 } 8484 } 8485 8486 #ifdef WLAN_FEATURE_11BE 8487 /** 8488 * wmi_host_to_fw_phymode_11be() - convert host to fw phymode for 11be phymode 8489 * @host_phymode: phymode to convert 8490 * 8491 * Return: one of the 11be values defined in enum WMI_HOST_WLAN_PHY_MODE; 8492 * or WMI_HOST_MODE_UNKNOWN if the input is not an 11be phymode 8493 */ 8494 static WMI_HOST_WLAN_PHY_MODE 8495 wmi_host_to_fw_phymode_11be(enum wlan_phymode host_phymode) 8496 { 8497 switch (host_phymode) { 8498 case WLAN_PHYMODE_11BEA_EHT20: 8499 return WMI_HOST_MODE_11BE_EHT20; 8500 case WLAN_PHYMODE_11BEA_EHT40: 8501 return WMI_HOST_MODE_11BE_EHT40; 8502 case WLAN_PHYMODE_11BEA_EHT80: 8503 return WMI_HOST_MODE_11BE_EHT80; 8504 case WLAN_PHYMODE_11BEA_EHT160: 8505 return WMI_HOST_MODE_11BE_EHT160; 8506 case WLAN_PHYMODE_11BEA_EHT320: 8507 return WMI_HOST_MODE_11BE_EHT320; 8508 case WLAN_PHYMODE_11BEG_EHT20: 8509 return WMI_HOST_MODE_11BE_EHT20_2G; 8510 case WLAN_PHYMODE_11BEG_EHT40: 8511 case WLAN_PHYMODE_11BEG_EHT40PLUS: 8512 case WLAN_PHYMODE_11BEG_EHT40MINUS: 8513 return WMI_HOST_MODE_11BE_EHT40_2G; 8514 default: 8515 return WMI_HOST_MODE_UNKNOWN; 8516 } 8517 } 8518 #else 8519 static WMI_HOST_WLAN_PHY_MODE 8520 wmi_host_to_fw_phymode_11be(enum wlan_phymode host_phymode) 8521 { 8522 return WMI_HOST_MODE_UNKNOWN; 8523 } 8524 #endif 8525 8526 WMI_HOST_WLAN_PHY_MODE wmi_host_to_fw_phymode(enum wlan_phymode host_phymode) 8527 { 8528 switch (host_phymode) { 8529 case WLAN_PHYMODE_11A: 8530 return WMI_HOST_MODE_11A; 8531 case WLAN_PHYMODE_11G: 8532 return WMI_HOST_MODE_11G; 8533 case WLAN_PHYMODE_11B: 8534 return WMI_HOST_MODE_11B; 8535 case WLAN_PHYMODE_11G_ONLY: 8536 return WMI_HOST_MODE_11GONLY; 8537 case WLAN_PHYMODE_11NA_HT20: 8538 return WMI_HOST_MODE_11NA_HT20; 8539 case WLAN_PHYMODE_11NG_HT20: 8540 return WMI_HOST_MODE_11NG_HT20; 8541 case WLAN_PHYMODE_11NA_HT40: 8542 return WMI_HOST_MODE_11NA_HT40; 8543 case WLAN_PHYMODE_11NG_HT40: 8544 case WLAN_PHYMODE_11NG_HT40PLUS: 8545 case WLAN_PHYMODE_11NG_HT40MINUS: 8546 return WMI_HOST_MODE_11NG_HT40; 8547 case WLAN_PHYMODE_11AC_VHT20: 8548 return WMI_HOST_MODE_11AC_VHT20; 8549 case WLAN_PHYMODE_11AC_VHT40: 8550 return WMI_HOST_MODE_11AC_VHT40; 8551 case WLAN_PHYMODE_11AC_VHT80: 8552 return WMI_HOST_MODE_11AC_VHT80; 8553 case WLAN_PHYMODE_11AC_VHT20_2G: 8554 return WMI_HOST_MODE_11AC_VHT20_2G; 8555 case WLAN_PHYMODE_11AC_VHT40PLUS_2G: 8556 case WLAN_PHYMODE_11AC_VHT40MINUS_2G: 8557 case WLAN_PHYMODE_11AC_VHT40_2G: 8558 return WMI_HOST_MODE_11AC_VHT40_2G; 8559 case WLAN_PHYMODE_11AC_VHT80_2G: 8560 return WMI_HOST_MODE_11AC_VHT80_2G; 8561 case WLAN_PHYMODE_11AC_VHT80_80: 8562 return WMI_HOST_MODE_11AC_VHT80_80; 8563 case WLAN_PHYMODE_11AC_VHT160: 8564 return WMI_HOST_MODE_11AC_VHT160; 8565 case WLAN_PHYMODE_11AXA_HE20: 8566 return WMI_HOST_MODE_11AX_HE20; 8567 case WLAN_PHYMODE_11AXA_HE40: 8568 return WMI_HOST_MODE_11AX_HE40; 8569 case WLAN_PHYMODE_11AXA_HE80: 8570 return WMI_HOST_MODE_11AX_HE80; 8571 case WLAN_PHYMODE_11AXA_HE80_80: 8572 return WMI_HOST_MODE_11AX_HE80_80; 8573 case WLAN_PHYMODE_11AXA_HE160: 8574 return WMI_HOST_MODE_11AX_HE160; 8575 case WLAN_PHYMODE_11AXG_HE20: 8576 return WMI_HOST_MODE_11AX_HE20_2G; 8577 case WLAN_PHYMODE_11AXG_HE40: 8578 case WLAN_PHYMODE_11AXG_HE40PLUS: 8579 case WLAN_PHYMODE_11AXG_HE40MINUS: 8580 return WMI_HOST_MODE_11AX_HE40_2G; 8581 case WLAN_PHYMODE_11AXG_HE80: 8582 return WMI_HOST_MODE_11AX_HE80_2G; 8583 default: 8584 return wmi_host_to_fw_phymode_11be(host_phymode); 8585 } 8586 } 8587 8588 /* 8589 * convert_host_to_target_ch_width()- map host channel width(enum phy_ch_width) 8590 * to wmi channel width 8591 * @chan_width: Host channel width 8592 * 8593 * Return: wmi channel width 8594 */ 8595 static 8596 wmi_channel_width convert_host_to_target_ch_width(uint32_t chan_width) 8597 { 8598 switch (chan_width) { 8599 case CH_WIDTH_20MHZ: 8600 return WMI_CHAN_WIDTH_20; 8601 case CH_WIDTH_40MHZ: 8602 return WMI_CHAN_WIDTH_40; 8603 case CH_WIDTH_80MHZ: 8604 return WMI_CHAN_WIDTH_80; 8605 case CH_WIDTH_160MHZ: 8606 return WMI_CHAN_WIDTH_160; 8607 case CH_WIDTH_80P80MHZ: 8608 return WMI_CHAN_WIDTH_80P80; 8609 case CH_WIDTH_5MHZ: 8610 return WMI_CHAN_WIDTH_5; 8611 case CH_WIDTH_10MHZ: 8612 return WMI_CHAN_WIDTH_10; 8613 #ifdef WLAN_FEATURE_11BE 8614 case CH_WIDTH_320MHZ: 8615 return WMI_CHAN_WIDTH_320; 8616 #endif 8617 default: 8618 return WMI_CHAN_WIDTH_MAX; 8619 } 8620 } 8621 8622 /** 8623 * send_vdev_spectral_configure_cmd_tlv() - send VDEV spectral configure 8624 * command to fw 8625 * @wmi_handle: wmi handle 8626 * @param: pointer to hold spectral config parameter 8627 * 8628 * Return: QDF_STATUS_SUCCESS for success or error code 8629 */ 8630 static QDF_STATUS send_vdev_spectral_configure_cmd_tlv(wmi_unified_t wmi_handle, 8631 struct vdev_spectral_configure_params *param) 8632 { 8633 wmi_vdev_spectral_configure_cmd_fixed_param *cmd; 8634 wmi_buf_t buf; 8635 QDF_STATUS ret; 8636 int32_t len; 8637 8638 len = sizeof(*cmd); 8639 buf = wmi_buf_alloc(wmi_handle, len); 8640 if (!buf) 8641 return QDF_STATUS_E_FAILURE; 8642 8643 cmd = (wmi_vdev_spectral_configure_cmd_fixed_param *)wmi_buf_data(buf); 8644 WMITLV_SET_HDR(&cmd->tlv_header, 8645 WMITLV_TAG_STRUC_wmi_vdev_spectral_configure_cmd_fixed_param, 8646 WMITLV_GET_STRUCT_TLVLEN( 8647 wmi_vdev_spectral_configure_cmd_fixed_param)); 8648 8649 cmd->vdev_id = param->vdev_id; 8650 cmd->spectral_scan_count = param->count; 8651 cmd->spectral_scan_period = param->period; 8652 cmd->spectral_scan_priority = param->spectral_pri; 8653 cmd->spectral_scan_fft_size = param->fft_size; 8654 cmd->spectral_scan_gc_ena = param->gc_enable; 8655 cmd->spectral_scan_restart_ena = param->restart_enable; 8656 cmd->spectral_scan_noise_floor_ref = param->noise_floor_ref; 8657 cmd->spectral_scan_init_delay = param->init_delay; 8658 cmd->spectral_scan_nb_tone_thr = param->nb_tone_thr; 8659 cmd->spectral_scan_str_bin_thr = param->str_bin_thr; 8660 cmd->spectral_scan_wb_rpt_mode = param->wb_rpt_mode; 8661 cmd->spectral_scan_rssi_rpt_mode = param->rssi_rpt_mode; 8662 cmd->spectral_scan_rssi_thr = param->rssi_thr; 8663 cmd->spectral_scan_pwr_format = param->pwr_format; 8664 cmd->spectral_scan_rpt_mode = param->rpt_mode; 8665 cmd->spectral_scan_bin_scale = param->bin_scale; 8666 cmd->spectral_scan_dBm_adj = param->dbm_adj; 8667 cmd->spectral_scan_chn_mask = param->chn_mask; 8668 cmd->spectral_scan_mode = param->mode; 8669 cmd->spectral_scan_center_freq1 = param->center_freq1; 8670 cmd->spectral_scan_center_freq2 = param->center_freq2; 8671 cmd->spectral_scan_chan_width = 8672 convert_host_to_target_ch_width(param->chan_width); 8673 cmd->recapture_sample_on_gain_change = param->fft_recap; 8674 /* Not used, fill with zeros */ 8675 cmd->spectral_scan_chan_freq = 0; 8676 8677 wmi_mtrace(WMI_VDEV_SPECTRAL_SCAN_CONFIGURE_CMDID, cmd->vdev_id, 0); 8678 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 8679 WMI_VDEV_SPECTRAL_SCAN_CONFIGURE_CMDID); 8680 8681 if (ret != 0) { 8682 wmi_err("Sending set quiet cmd failed"); 8683 wmi_buf_free(buf); 8684 } 8685 8686 wmi_debug("Sent WMI_VDEV_SPECTRAL_SCAN_CONFIGURE_CMDID"); 8687 wmi_debug("vdev_id: %u spectral_scan_count: %u", 8688 param->vdev_id, param->count); 8689 wmi_debug("spectral_scan_period: %u spectral_scan_priority: %u", 8690 param->period, param->spectral_pri); 8691 wmi_debug("spectral_fft_recapture_cap: %u", param->fft_recap); 8692 wmi_debug("spectral_scan_fft_size: %u spectral_scan_gc_ena: %u", 8693 param->fft_size, param->gc_enable); 8694 wmi_debug("spectral_scan_restart_ena: %u", param->restart_enable); 8695 wmi_debug("spectral_scan_noise_floor_ref: %u", param->noise_floor_ref); 8696 wmi_debug("spectral_scan_init_delay: %u", param->init_delay); 8697 wmi_debug("spectral_scan_nb_tone_thr: %u", param->nb_tone_thr); 8698 wmi_debug("spectral_scan_str_bin_thr: %u", param->str_bin_thr); 8699 wmi_debug("spectral_scan_wb_rpt_mode: %u", param->wb_rpt_mode); 8700 wmi_debug("spectral_scan_rssi_rpt_mode: %u", param->rssi_rpt_mode); 8701 wmi_debug("spectral_scan_rssi_thr: %u spectral_scan_pwr_format: %u", 8702 param->rssi_thr, param->pwr_format); 8703 wmi_debug("spectral_scan_rpt_mode: %u spectral_scan_bin_scale: %u", 8704 param->rpt_mode, param->bin_scale); 8705 wmi_debug("spectral_scan_dBm_adj: %u spectral_scan_chn_mask: %u", 8706 param->dbm_adj, param->chn_mask); 8707 wmi_debug("spectral_scan_mode: %u spectral_scan_center_freq1: %u", 8708 param->mode, param->center_freq1); 8709 wmi_debug("spectral_scan_center_freq2: %u spectral_scan_chan_freq: %u", 8710 param->center_freq2, param->chan_freq); 8711 wmi_debug("spectral_scan_chan_width: %u Status: %d", 8712 param->chan_width, ret); 8713 8714 return ret; 8715 } 8716 8717 /** 8718 * send_vdev_spectral_enable_cmd_tlv() - send VDEV spectral configure 8719 * command to fw 8720 * @wmi_handle: wmi handle 8721 * @param: pointer to hold spectral enable parameter 8722 * 8723 * Return: QDF_STATUS_SUCCESS for success or error code 8724 */ 8725 static QDF_STATUS send_vdev_spectral_enable_cmd_tlv(wmi_unified_t wmi_handle, 8726 struct vdev_spectral_enable_params *param) 8727 { 8728 wmi_vdev_spectral_enable_cmd_fixed_param *cmd; 8729 wmi_buf_t buf; 8730 QDF_STATUS ret; 8731 int32_t len; 8732 8733 len = sizeof(*cmd); 8734 buf = wmi_buf_alloc(wmi_handle, len); 8735 if (!buf) 8736 return QDF_STATUS_E_FAILURE; 8737 8738 cmd = (wmi_vdev_spectral_enable_cmd_fixed_param *)wmi_buf_data(buf); 8739 WMITLV_SET_HDR(&cmd->tlv_header, 8740 WMITLV_TAG_STRUC_wmi_vdev_spectral_enable_cmd_fixed_param, 8741 WMITLV_GET_STRUCT_TLVLEN( 8742 wmi_vdev_spectral_enable_cmd_fixed_param)); 8743 8744 cmd->vdev_id = param->vdev_id; 8745 8746 if (param->active_valid) { 8747 cmd->trigger_cmd = param->active ? 1 : 2; 8748 /* 1: Trigger, 2: Clear Trigger */ 8749 } else { 8750 cmd->trigger_cmd = 0; /* 0: Ignore */ 8751 } 8752 8753 if (param->enabled_valid) { 8754 cmd->enable_cmd = param->enabled ? 1 : 2; 8755 /* 1: Enable 2: Disable */ 8756 } else { 8757 cmd->enable_cmd = 0; /* 0: Ignore */ 8758 } 8759 cmd->spectral_scan_mode = param->mode; 8760 8761 wmi_debug("vdev_id = %u trigger_cmd = %u enable_cmd = %u", 8762 cmd->vdev_id, cmd->trigger_cmd, cmd->enable_cmd); 8763 wmi_debug("spectral_scan_mode = %u", cmd->spectral_scan_mode); 8764 8765 wmi_mtrace(WMI_VDEV_SPECTRAL_SCAN_ENABLE_CMDID, cmd->vdev_id, 0); 8766 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 8767 WMI_VDEV_SPECTRAL_SCAN_ENABLE_CMDID); 8768 8769 if (ret != 0) { 8770 wmi_err("Sending scan enable CMD failed"); 8771 wmi_buf_free(buf); 8772 } 8773 8774 wmi_debug("Sent WMI_VDEV_SPECTRAL_SCAN_ENABLE_CMDID, Status: %d", 8775 ret); 8776 8777 return ret; 8778 } 8779 8780 #ifdef WLAN_CONV_SPECTRAL_ENABLE 8781 static QDF_STATUS 8782 extract_pdev_sscan_fw_cmd_fixed_param_tlv( 8783 wmi_unified_t wmi_handle, 8784 uint8_t *event, struct spectral_startscan_resp_params *param) 8785 { 8786 WMI_PDEV_SSCAN_FW_PARAM_EVENTID_param_tlvs *param_buf; 8787 wmi_pdev_sscan_fw_cmd_fixed_param *ev; 8788 8789 if (!wmi_handle) { 8790 wmi_err("WMI handle is null"); 8791 return QDF_STATUS_E_INVAL; 8792 } 8793 8794 if (!event) { 8795 wmi_err("WMI event is null"); 8796 return QDF_STATUS_E_INVAL; 8797 } 8798 8799 if (!param) { 8800 wmi_err("Spectral startscan response params is null"); 8801 return QDF_STATUS_E_INVAL; 8802 } 8803 8804 param_buf = (WMI_PDEV_SSCAN_FW_PARAM_EVENTID_param_tlvs *)event; 8805 if (!param_buf) 8806 return QDF_STATUS_E_INVAL; 8807 8808 ev = param_buf->fixed_param; 8809 if (!ev) 8810 return QDF_STATUS_E_INVAL; 8811 8812 param->pdev_id = wmi_handle->ops->convert_target_pdev_id_to_host( 8813 wmi_handle, 8814 ev->pdev_id); 8815 param->smode = ev->spectral_scan_mode; 8816 param->num_fft_bin_index = param_buf->num_fft_bin_index; 8817 param->num_det_info = param_buf->num_det_info; 8818 8819 wmi_debug("pdev id:%u smode:%u num_fft_bin_index:%u num_det_info:%u", 8820 ev->pdev_id, ev->spectral_scan_mode, 8821 param_buf->num_fft_bin_index, param_buf->num_det_info); 8822 8823 return QDF_STATUS_SUCCESS; 8824 } 8825 8826 static QDF_STATUS 8827 extract_pdev_sscan_fft_bin_index_tlv( 8828 wmi_unified_t wmi_handle, uint8_t *event, 8829 struct spectral_fft_bin_markers_160_165mhz *param) 8830 { 8831 WMI_PDEV_SSCAN_FW_PARAM_EVENTID_param_tlvs *param_buf; 8832 wmi_pdev_sscan_fft_bin_index *ev; 8833 8834 param_buf = (WMI_PDEV_SSCAN_FW_PARAM_EVENTID_param_tlvs *)event; 8835 if (!param_buf) 8836 return QDF_STATUS_E_INVAL; 8837 8838 ev = param_buf->fft_bin_index; 8839 if (!ev) 8840 return QDF_STATUS_E_INVAL; 8841 8842 param->start_pri80 = WMI_SSCAN_PRI80_START_BIN_GET(ev->pri80_bins); 8843 param->num_pri80 = WMI_SSCAN_PRI80_END_BIN_GET(ev->pri80_bins) - 8844 param->start_pri80 + 1; 8845 param->start_sec80 = WMI_SSCAN_SEC80_START_BIN_GET(ev->sec80_bins); 8846 param->num_sec80 = WMI_SSCAN_SEC80_END_BIN_GET(ev->sec80_bins) - 8847 param->start_sec80 + 1; 8848 param->start_5mhz = WMI_SSCAN_MID_5MHZ_START_BIN_GET(ev->mid_5mhz_bins); 8849 param->num_5mhz = WMI_SSCAN_MID_5MHZ_END_BIN_GET(ev->mid_5mhz_bins) - 8850 param->start_5mhz + 1; 8851 param->is_valid = true; 8852 8853 wmi_debug("start_pri80: %u num_pri80: %u start_sec80: %u num_sec80: %u start_5mhz: %u, num_5mhz: %u", 8854 param->start_pri80, param->num_pri80, 8855 param->start_sec80, param->num_sec80, 8856 param->start_5mhz, param->num_5mhz); 8857 8858 return QDF_STATUS_SUCCESS; 8859 } 8860 8861 /** 8862 * extract_pdev_spectral_session_chan_info_tlv() - Extract channel information 8863 * for a spectral scan session 8864 * @wmi_handle: handle to WMI. 8865 * @event: Event buffer 8866 * @chan_info: Spectral session channel information data structure to be filled 8867 * by this API 8868 * 8869 * Return: QDF_STATUS of operation 8870 */ 8871 static QDF_STATUS 8872 extract_pdev_spectral_session_chan_info_tlv( 8873 wmi_unified_t wmi_handle, void *event, 8874 struct spectral_session_chan_info *chan_info) 8875 { 8876 WMI_PDEV_SSCAN_FW_PARAM_EVENTID_param_tlvs *param_buf = event; 8877 wmi_pdev_sscan_chan_info *chan_info_tlv; 8878 8879 if (!param_buf) { 8880 wmi_err("param_buf is NULL"); 8881 return QDF_STATUS_E_NULL_VALUE; 8882 } 8883 8884 if (!chan_info) { 8885 wmi_err("chan_info is NULL"); 8886 return QDF_STATUS_E_NULL_VALUE; 8887 } 8888 8889 chan_info_tlv = param_buf->chan_info; 8890 if (!chan_info_tlv) { 8891 wmi_err("chan_info tlv is not present in the event"); 8892 return QDF_STATUS_E_NULL_VALUE; 8893 } 8894 8895 wmi_debug("operating_pri20_freq:%u operating_cfreq1:%u" 8896 "operating_cfreq2:%u operating_bw:%u" 8897 "operating_puncture_20mhz_bitmap:%u" 8898 "sscan_cfreq1:%u sscan_cfreq2:%u" 8899 "sscan_bw:%u sscan_puncture_20mhz_bitmap:%u", 8900 chan_info_tlv->operating_pri20_freq, 8901 chan_info_tlv->operating_cfreq1, 8902 chan_info_tlv->operating_cfreq2, chan_info_tlv->operating_bw, 8903 chan_info_tlv->operating_puncture_20mhz_bitmap, 8904 chan_info_tlv->sscan_cfreq1, chan_info_tlv->sscan_cfreq2, 8905 chan_info_tlv->sscan_bw, 8906 chan_info_tlv->sscan_puncture_20mhz_bitmap); 8907 8908 chan_info->operating_pri20_freq = 8909 (qdf_freq_t)chan_info_tlv->operating_pri20_freq; 8910 chan_info->operating_cfreq1 = 8911 (qdf_freq_t)chan_info_tlv->operating_cfreq1; 8912 chan_info->operating_cfreq2 = 8913 (qdf_freq_t)chan_info_tlv->operating_cfreq2; 8914 chan_info->operating_bw = wmi_map_ch_width(chan_info_tlv->operating_bw); 8915 chan_info->operating_puncture_20mhz_bitmap = 8916 chan_info_tlv->operating_puncture_20mhz_bitmap; 8917 8918 chan_info->sscan_cfreq1 = (qdf_freq_t)chan_info_tlv->sscan_cfreq1; 8919 chan_info->sscan_cfreq2 = (qdf_freq_t)chan_info_tlv->sscan_cfreq2; 8920 chan_info->sscan_bw = wmi_map_ch_width(chan_info_tlv->sscan_bw); 8921 chan_info->sscan_puncture_20mhz_bitmap = 8922 chan_info_tlv->sscan_puncture_20mhz_bitmap; 8923 8924 return QDF_STATUS_SUCCESS; 8925 } 8926 8927 static QDF_STATUS 8928 extract_pdev_spectral_session_detector_info_tlv( 8929 wmi_unified_t wmi_handle, void *event, 8930 struct spectral_session_det_info *det_info, uint8_t idx) 8931 { 8932 WMI_PDEV_SSCAN_FW_PARAM_EVENTID_param_tlvs *param_buf = event; 8933 wmi_pdev_sscan_per_detector_info *det_info_tlv; 8934 8935 if (!param_buf) { 8936 wmi_err("param_buf is NULL"); 8937 return QDF_STATUS_E_NULL_VALUE; 8938 } 8939 8940 if (!det_info) { 8941 wmi_err("chan_info is NULL"); 8942 return QDF_STATUS_E_NULL_VALUE; 8943 } 8944 8945 if (!param_buf->det_info) { 8946 wmi_err("det_info tlv is not present in the event"); 8947 return QDF_STATUS_E_NULL_VALUE; 8948 } 8949 8950 if (idx >= param_buf->num_det_info) { 8951 wmi_err("det_info index(%u) is greater than or equal to %u", 8952 idx, param_buf->num_det_info); 8953 return QDF_STATUS_E_FAILURE; 8954 } 8955 8956 det_info_tlv = ¶m_buf->det_info[idx]; 8957 8958 wmi_debug("det_info_idx: %u detector_id:%u start_freq:%u end_freq:%u", 8959 idx, det_info_tlv->detector_id, 8960 det_info_tlv->start_freq, det_info_tlv->end_freq); 8961 8962 det_info->det_id = det_info_tlv->detector_id; 8963 det_info->start_freq = (qdf_freq_t)det_info_tlv->start_freq; 8964 det_info->end_freq = (qdf_freq_t)det_info_tlv->end_freq; 8965 8966 return QDF_STATUS_SUCCESS; 8967 } 8968 8969 /** 8970 * extract_spectral_caps_fixed_param_tlv() - Extract fixed params from Spectral 8971 * capabilities WMI event 8972 * @wmi_handle: handle to WMI. 8973 * @event: Event buffer 8974 * @params: Spectral capabilities event parameters data structure to be filled 8975 * by this API 8976 * 8977 * Return: QDF_STATUS of operation 8978 */ 8979 static QDF_STATUS 8980 extract_spectral_caps_fixed_param_tlv( 8981 wmi_unified_t wmi_handle, void *event, 8982 struct spectral_capabilities_event_params *params) 8983 { 8984 WMI_SPECTRAL_CAPABILITIES_EVENTID_param_tlvs *param_buf = event; 8985 8986 if (!param_buf) { 8987 wmi_err("param_buf is NULL"); 8988 return QDF_STATUS_E_NULL_VALUE; 8989 } 8990 8991 if (!params) { 8992 wmi_err("event parameters is NULL"); 8993 return QDF_STATUS_E_NULL_VALUE; 8994 } 8995 8996 params->num_sscan_bw_caps = param_buf->num_sscan_bw_caps; 8997 params->num_fft_size_caps = param_buf->num_fft_size_caps; 8998 8999 wmi_debug("num_sscan_bw_caps:%u num_fft_size_caps:%u", 9000 params->num_sscan_bw_caps, params->num_fft_size_caps); 9001 9002 return QDF_STATUS_SUCCESS; 9003 } 9004 9005 /** 9006 * extract_spectral_scan_bw_caps_tlv() - Extract bandwidth caps from 9007 * Spectral capabilities WMI event 9008 * @wmi_handle: handle to WMI. 9009 * @event: Event buffer 9010 * @bw_caps: Data structure to be populated by this API after extraction 9011 * 9012 * Return: QDF_STATUS of operation 9013 */ 9014 static QDF_STATUS 9015 extract_spectral_scan_bw_caps_tlv( 9016 wmi_unified_t wmi_handle, void *event, 9017 struct spectral_scan_bw_capabilities *bw_caps) 9018 { 9019 WMI_SPECTRAL_CAPABILITIES_EVENTID_param_tlvs *param_buf = event; 9020 int idx; 9021 9022 if (!param_buf) { 9023 wmi_err("param_buf is NULL"); 9024 return QDF_STATUS_E_NULL_VALUE; 9025 } 9026 9027 if (!bw_caps) { 9028 wmi_err("bw_caps is null"); 9029 return QDF_STATUS_E_NULL_VALUE; 9030 } 9031 9032 for (idx = 0; idx < param_buf->num_sscan_bw_caps; idx++) { 9033 bw_caps[idx].pdev_id = 9034 wmi_handle->ops->convert_pdev_id_target_to_host( 9035 wmi_handle, 9036 param_buf->sscan_bw_caps[idx].pdev_id); 9037 bw_caps[idx].smode = param_buf->sscan_bw_caps[idx].sscan_mode; 9038 bw_caps[idx].operating_bw = wmi_map_ch_width( 9039 param_buf->sscan_bw_caps[idx].operating_bw); 9040 bw_caps[idx].supported_bws = 9041 param_buf->sscan_bw_caps[idx].supported_flags; 9042 9043 wmi_debug("bw_caps[%u]:: pdev_id:%u smode:%u" 9044 "operating_bw:%u supported_flags:0x%x", 9045 idx, param_buf->sscan_bw_caps[idx].pdev_id, 9046 param_buf->sscan_bw_caps[idx].sscan_mode, 9047 param_buf->sscan_bw_caps[idx].operating_bw, 9048 param_buf->sscan_bw_caps[idx].supported_flags); 9049 } 9050 9051 return QDF_STATUS_SUCCESS; 9052 } 9053 9054 /** 9055 * extract_spectral_fft_size_caps_tlv() - Extract FFT size caps from 9056 * Spectral capabilities WMI event 9057 * @wmi_handle: handle to WMI. 9058 * @event: Event buffer 9059 * @fft_size_caps: Data structure to be populated by this API after extraction 9060 * 9061 * Return: QDF_STATUS of operation 9062 */ 9063 static QDF_STATUS 9064 extract_spectral_fft_size_caps_tlv( 9065 wmi_unified_t wmi_handle, void *event, 9066 struct spectral_fft_size_capabilities *fft_size_caps) 9067 { 9068 WMI_SPECTRAL_CAPABILITIES_EVENTID_param_tlvs *param_buf = event; 9069 int idx; 9070 9071 if (!param_buf) { 9072 wmi_err("param_buf is NULL"); 9073 return QDF_STATUS_E_NULL_VALUE; 9074 } 9075 9076 if (!fft_size_caps) { 9077 wmi_err("fft size caps is NULL"); 9078 return QDF_STATUS_E_NULL_VALUE; 9079 } 9080 9081 for (idx = 0; idx < param_buf->num_fft_size_caps; idx++) { 9082 fft_size_caps[idx].pdev_id = 9083 wmi_handle->ops->convert_pdev_id_target_to_host( 9084 wmi_handle, 9085 param_buf->fft_size_caps[idx].pdev_id); 9086 fft_size_caps[idx].sscan_bw = wmi_map_ch_width( 9087 param_buf->fft_size_caps[idx].sscan_bw); 9088 fft_size_caps[idx].supports_fft_sizes = 9089 param_buf->fft_size_caps[idx].supported_flags; 9090 9091 wmi_debug("fft_size_caps[%u]:: pdev_id:%u sscan_bw:%u" 9092 "supported_flags:0x%x", 9093 idx, param_buf->fft_size_caps[idx].pdev_id, 9094 param_buf->fft_size_caps[idx].sscan_bw, 9095 param_buf->fft_size_caps[idx].supported_flags); 9096 } 9097 9098 return QDF_STATUS_SUCCESS; 9099 } 9100 #endif /* WLAN_CONV_SPECTRAL_ENABLE */ 9101 9102 #ifdef FEATURE_WPSS_THERMAL_MITIGATION 9103 static inline void 9104 wmi_fill_client_id_priority(wmi_therm_throt_config_request_fixed_param *tt_conf, 9105 struct thermal_mitigation_params *param) 9106 { 9107 tt_conf->client_id = param->client_id; 9108 tt_conf->priority = param->priority; 9109 } 9110 #else 9111 static inline void 9112 wmi_fill_client_id_priority(wmi_therm_throt_config_request_fixed_param *tt_conf, 9113 struct thermal_mitigation_params *param) 9114 { 9115 } 9116 #endif 9117 9118 /** 9119 * send_thermal_mitigation_param_cmd_tlv() - configure thermal mitigation params 9120 * @wmi_handle : handle to WMI. 9121 * @param : pointer to hold thermal mitigation param 9122 * 9123 * Return: QDF_STATUS_SUCCESS for success or error code 9124 */ 9125 static QDF_STATUS send_thermal_mitigation_param_cmd_tlv( 9126 wmi_unified_t wmi_handle, 9127 struct thermal_mitigation_params *param) 9128 { 9129 wmi_therm_throt_config_request_fixed_param *tt_conf = NULL; 9130 wmi_therm_throt_level_config_info *lvl_conf = NULL; 9131 wmi_buf_t buf = NULL; 9132 uint8_t *buf_ptr = NULL; 9133 int error; 9134 int32_t len; 9135 int i; 9136 9137 len = sizeof(*tt_conf) + WMI_TLV_HDR_SIZE + 9138 param->num_thermal_conf * 9139 sizeof(wmi_therm_throt_level_config_info); 9140 9141 buf = wmi_buf_alloc(wmi_handle, len); 9142 if (!buf) 9143 return QDF_STATUS_E_NOMEM; 9144 9145 tt_conf = (wmi_therm_throt_config_request_fixed_param *) wmi_buf_data(buf); 9146 9147 /* init fixed params */ 9148 WMITLV_SET_HDR(tt_conf, 9149 WMITLV_TAG_STRUC_wmi_therm_throt_config_request_fixed_param, 9150 (WMITLV_GET_STRUCT_TLVLEN(wmi_therm_throt_config_request_fixed_param))); 9151 9152 tt_conf->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 9153 wmi_handle, 9154 param->pdev_id); 9155 tt_conf->enable = param->enable; 9156 tt_conf->dc = param->dc; 9157 tt_conf->dc_per_event = param->dc_per_event; 9158 tt_conf->therm_throt_levels = param->num_thermal_conf; 9159 wmi_fill_client_id_priority(tt_conf, param); 9160 buf_ptr = (uint8_t *) ++tt_conf; 9161 /* init TLV params */ 9162 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 9163 (param->num_thermal_conf * 9164 sizeof(wmi_therm_throt_level_config_info))); 9165 9166 lvl_conf = (wmi_therm_throt_level_config_info *) (buf_ptr + WMI_TLV_HDR_SIZE); 9167 for (i = 0; i < param->num_thermal_conf; i++) { 9168 WMITLV_SET_HDR(&lvl_conf->tlv_header, 9169 WMITLV_TAG_STRUC_wmi_therm_throt_level_config_info, 9170 WMITLV_GET_STRUCT_TLVLEN(wmi_therm_throt_level_config_info)); 9171 lvl_conf->temp_lwm = param->levelconf[i].tmplwm; 9172 lvl_conf->temp_hwm = param->levelconf[i].tmphwm; 9173 lvl_conf->dc_off_percent = param->levelconf[i].dcoffpercent; 9174 lvl_conf->prio = param->levelconf[i].priority; 9175 lvl_conf++; 9176 } 9177 9178 wmi_mtrace(WMI_THERM_THROT_SET_CONF_CMDID, NO_SESSION, 0); 9179 error = wmi_unified_cmd_send(wmi_handle, buf, len, 9180 WMI_THERM_THROT_SET_CONF_CMDID); 9181 if (QDF_IS_STATUS_ERROR(error)) { 9182 wmi_buf_free(buf); 9183 wmi_err("Failed to send WMI_THERM_THROT_SET_CONF_CMDID command"); 9184 } 9185 9186 return error; 9187 } 9188 9189 /** 9190 * send_coex_config_cmd_tlv() - send coex config command to fw 9191 * @wmi_handle: wmi handle 9192 * @param: pointer to coex config param 9193 * 9194 * Return: QDF_STATUS_SUCCESS for success or error code 9195 */ 9196 static QDF_STATUS 9197 send_coex_config_cmd_tlv(wmi_unified_t wmi_handle, 9198 struct coex_config_params *param) 9199 { 9200 WMI_COEX_CONFIG_CMD_fixed_param *cmd; 9201 wmi_buf_t buf; 9202 QDF_STATUS ret; 9203 int32_t len; 9204 9205 len = sizeof(*cmd); 9206 buf = wmi_buf_alloc(wmi_handle, len); 9207 if (!buf) 9208 return QDF_STATUS_E_FAILURE; 9209 9210 cmd = (WMI_COEX_CONFIG_CMD_fixed_param *)wmi_buf_data(buf); 9211 WMITLV_SET_HDR(&cmd->tlv_header, 9212 WMITLV_TAG_STRUC_WMI_COEX_CONFIG_CMD_fixed_param, 9213 WMITLV_GET_STRUCT_TLVLEN( 9214 WMI_COEX_CONFIG_CMD_fixed_param)); 9215 9216 cmd->vdev_id = param->vdev_id; 9217 cmd->config_type = param->config_type; 9218 cmd->config_arg1 = param->config_arg1; 9219 cmd->config_arg2 = param->config_arg2; 9220 cmd->config_arg3 = param->config_arg3; 9221 cmd->config_arg4 = param->config_arg4; 9222 cmd->config_arg5 = param->config_arg5; 9223 cmd->config_arg6 = param->config_arg6; 9224 9225 wmi_mtrace(WMI_COEX_CONFIG_CMDID, cmd->vdev_id, 0); 9226 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 9227 WMI_COEX_CONFIG_CMDID); 9228 9229 if (ret != 0) { 9230 wmi_err("Sending COEX CONFIG CMD failed"); 9231 wmi_buf_free(buf); 9232 } 9233 9234 return ret; 9235 } 9236 9237 #ifdef WLAN_FEATURE_DBAM_CONFIG 9238 9239 static enum wmi_coex_dbam_mode_type 9240 map_to_wmi_coex_dbam_mode_type(enum coex_dbam_config_mode mode) 9241 { 9242 switch (mode) { 9243 case COEX_DBAM_ENABLE: 9244 return WMI_COEX_DBAM_ENABLE; 9245 case COEX_DBAM_FORCE_ENABLE: 9246 return WMI_COEX_DBAM_FORCED; 9247 case COEX_DBAM_DISABLE: 9248 default: 9249 return WMI_COEX_DBAM_DISABLE; 9250 } 9251 } 9252 9253 /** 9254 * send_dbam_config_cmd_tlv() - send coex DBAM config command to fw 9255 * @wmi_handle: wmi handle 9256 * @param: pointer to coex dbam config param 9257 * 9258 * Return: QDF_STATUS_SUCCESS for success or error code 9259 */ 9260 static QDF_STATUS 9261 send_dbam_config_cmd_tlv(wmi_unified_t wmi_handle, 9262 struct coex_dbam_config_params *param) 9263 { 9264 wmi_coex_dbam_cmd_fixed_param *cmd; 9265 wmi_buf_t buf; 9266 void *buf_ptr; 9267 QDF_STATUS ret; 9268 int32_t len; 9269 9270 len = sizeof(*cmd); 9271 buf = wmi_buf_alloc(wmi_handle, len); 9272 if (!buf) { 9273 wmi_err_rl("Failed to allocate wmi buffer"); 9274 return QDF_STATUS_E_NOMEM; 9275 } 9276 9277 buf_ptr = wmi_buf_data(buf); 9278 cmd = buf_ptr; 9279 WMITLV_SET_HDR(&cmd->tlv_header, 9280 WMITLV_TAG_STRUC_wmi_coex_dbam_cmd_fixed_param, 9281 WMITLV_GET_STRUCT_TLVLEN( 9282 wmi_coex_dbam_cmd_fixed_param)); 9283 9284 cmd->vdev_id = param->vdev_id; 9285 cmd->dbam_mode = map_to_wmi_coex_dbam_mode_type(param->dbam_mode); 9286 9287 wmi_mtrace(WMI_COEX_DBAM_CMDID, cmd->vdev_id, 0); 9288 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 9289 WMI_COEX_DBAM_CMDID); 9290 9291 if (QDF_IS_STATUS_ERROR(ret)) { 9292 wmi_err("Sending DBAM CONFIG CMD failed"); 9293 wmi_buf_free(buf); 9294 return QDF_STATUS_E_FAILURE; 9295 } 9296 9297 return ret; 9298 } 9299 9300 static enum coex_dbam_comp_status 9301 wmi_convert_dbam_comp_status(wmi_coex_dbam_comp_status status) 9302 { 9303 switch (status) { 9304 case WMI_COEX_DBAM_COMP_SUCCESS: 9305 case WMI_COEX_DBAM_COMP_ONGOING: 9306 case WMI_COEX_DBAM_COMP_DELAYED: 9307 return COEX_DBAM_COMP_SUCCESS; 9308 case WMI_COEX_DBAM_COMP_NOT_SUPPORT: 9309 return COEX_DBAM_COMP_NOT_SUPPORT; 9310 case WMI_COEX_DBAM_COMP_INVALID_PARAM: 9311 case WMI_COEX_DBAM_COMP_FAIL: 9312 default: 9313 return COEX_DBAM_COMP_FAIL; 9314 } 9315 } 9316 9317 /** 9318 * extract_dbam_config_resp_event_tlv() - extract dbam complete status event 9319 * @wmi_handle: WMI handle 9320 * @evt_buf: event buffer 9321 * @resp: pointer to coex dbam config response 9322 * 9323 * Return: QDF_STATUS 9324 */ 9325 static QDF_STATUS 9326 extract_dbam_config_resp_event_tlv(wmi_unified_t wmi_handle, void *evt_buf, 9327 struct coex_dbam_config_resp *resp) 9328 { 9329 WMI_COEX_DBAM_COMPLETE_EVENTID_param_tlvs *param_buf; 9330 wmi_coex_dbam_complete_event_fixed_param *event; 9331 9332 param_buf = (WMI_COEX_DBAM_COMPLETE_EVENTID_param_tlvs *)evt_buf; 9333 9334 event = param_buf->fixed_param; 9335 9336 resp->dbam_resp = wmi_convert_dbam_comp_status(event->comp_status); 9337 9338 return QDF_STATUS_SUCCESS; 9339 } 9340 #endif 9341 9342 #ifdef WLAN_SUPPORT_TWT 9343 static void wmi_copy_twt_resource_config(wmi_resource_config *resource_cfg, 9344 target_resource_config *tgt_res_cfg) 9345 { 9346 resource_cfg->twt_ap_pdev_count = tgt_res_cfg->twt_ap_pdev_count; 9347 resource_cfg->twt_ap_sta_count = tgt_res_cfg->twt_ap_sta_count; 9348 } 9349 #else 9350 static void wmi_copy_twt_resource_config(wmi_resource_config *resource_cfg, 9351 target_resource_config *tgt_res_cfg) 9352 { 9353 resource_cfg->twt_ap_pdev_count = 0; 9354 resource_cfg->twt_ap_sta_count = 0; 9355 } 9356 #endif 9357 9358 #ifdef WLAN_FEATURE_NAN 9359 static void wmi_set_nan_channel_support(wmi_resource_config *resource_cfg) 9360 { 9361 WMI_RSRC_CFG_HOST_SERVICE_FLAG_NAN_CHANNEL_SUPPORT_SET( 9362 resource_cfg->host_service_flags, 1); 9363 } 9364 #else 9365 static inline 9366 void wmi_set_nan_channel_support(wmi_resource_config *resource_cfg) 9367 { 9368 } 9369 #endif 9370 9371 #if defined(CONFIG_AFC_SUPPORT) 9372 static 9373 void wmi_copy_afc_deployment_config(wmi_resource_config *resource_cfg, 9374 target_resource_config *tgt_res_cfg) 9375 { 9376 WMI_RSRC_CFG_HOST_SERVICE_FLAG_AFC_INDOOR_SUPPORT_CHECK_SET( 9377 resource_cfg->host_service_flags, 9378 tgt_res_cfg->afc_indoor_support); 9379 9380 WMI_RSRC_CFG_HOST_SERVICE_FLAG_AFC_OUTDOOR_SUPPORT_CHECK_SET( 9381 resource_cfg->host_service_flags, 9382 tgt_res_cfg->afc_outdoor_support); 9383 } 9384 #else 9385 static 9386 void wmi_copy_afc_deployment_config(wmi_resource_config *resource_cfg, 9387 target_resource_config *tgt_res_cfg) 9388 { 9389 } 9390 #endif 9391 9392 #ifdef DP_TX_PACKET_INSPECT_FOR_ILP 9393 static inline 9394 void wmi_copy_latency_flowq_support(wmi_resource_config *resource_cfg, 9395 target_resource_config *tgt_res_cfg) 9396 { 9397 if (tgt_res_cfg->tx_ilp_enable) 9398 WMI_RSRC_CFG_FLAGS2_LATENCY_FLOWQ_SUPPORT_SET( 9399 resource_cfg->flags2, 1); 9400 } 9401 #else 9402 static inline 9403 void wmi_copy_latency_flowq_support(wmi_resource_config *resource_cfg, 9404 target_resource_config *tgt_res_cfg) 9405 { 9406 } 9407 #endif 9408 9409 #ifdef MOBILE_DFS_SUPPORT 9410 static inline 9411 void wmi_copy_full_bw_nol_cfg(wmi_resource_config *resource_cfg, 9412 target_resource_config *tgt_res_cfg) 9413 { 9414 WMI_RSRC_CFG_HOST_SERVICE_FLAG_RADAR_FLAGS_FULL_BW_NOL_SET(resource_cfg->host_service_flags, 9415 tgt_res_cfg->is_full_bw_nol_supported); 9416 } 9417 #else 9418 static inline 9419 void wmi_copy_full_bw_nol_cfg(wmi_resource_config *resource_cfg, 9420 target_resource_config *tgt_res_cfg) 9421 { 9422 } 9423 #endif 9424 9425 static 9426 void wmi_copy_resource_config(wmi_resource_config *resource_cfg, 9427 target_resource_config *tgt_res_cfg) 9428 { 9429 resource_cfg->num_vdevs = tgt_res_cfg->num_vdevs; 9430 resource_cfg->num_peers = tgt_res_cfg->num_peers; 9431 resource_cfg->num_offload_peers = tgt_res_cfg->num_offload_peers; 9432 resource_cfg->num_offload_reorder_buffs = 9433 tgt_res_cfg->num_offload_reorder_buffs; 9434 resource_cfg->num_peer_keys = tgt_res_cfg->num_peer_keys; 9435 resource_cfg->num_tids = tgt_res_cfg->num_tids; 9436 resource_cfg->ast_skid_limit = tgt_res_cfg->ast_skid_limit; 9437 resource_cfg->tx_chain_mask = tgt_res_cfg->tx_chain_mask; 9438 resource_cfg->rx_chain_mask = tgt_res_cfg->rx_chain_mask; 9439 resource_cfg->rx_timeout_pri[0] = tgt_res_cfg->rx_timeout_pri[0]; 9440 resource_cfg->rx_timeout_pri[1] = tgt_res_cfg->rx_timeout_pri[1]; 9441 resource_cfg->rx_timeout_pri[2] = tgt_res_cfg->rx_timeout_pri[2]; 9442 resource_cfg->rx_timeout_pri[3] = tgt_res_cfg->rx_timeout_pri[3]; 9443 resource_cfg->rx_decap_mode = tgt_res_cfg->rx_decap_mode; 9444 resource_cfg->scan_max_pending_req = 9445 tgt_res_cfg->scan_max_pending_req; 9446 resource_cfg->bmiss_offload_max_vdev = 9447 tgt_res_cfg->bmiss_offload_max_vdev; 9448 resource_cfg->roam_offload_max_vdev = 9449 tgt_res_cfg->roam_offload_max_vdev; 9450 resource_cfg->roam_offload_max_ap_profiles = 9451 tgt_res_cfg->roam_offload_max_ap_profiles; 9452 resource_cfg->num_mcast_groups = tgt_res_cfg->num_mcast_groups; 9453 resource_cfg->num_mcast_table_elems = 9454 tgt_res_cfg->num_mcast_table_elems; 9455 resource_cfg->mcast2ucast_mode = tgt_res_cfg->mcast2ucast_mode; 9456 resource_cfg->tx_dbg_log_size = tgt_res_cfg->tx_dbg_log_size; 9457 resource_cfg->num_wds_entries = tgt_res_cfg->num_wds_entries; 9458 resource_cfg->dma_burst_size = tgt_res_cfg->dma_burst_size; 9459 resource_cfg->mac_aggr_delim = tgt_res_cfg->mac_aggr_delim; 9460 resource_cfg->rx_skip_defrag_timeout_dup_detection_check = 9461 tgt_res_cfg->rx_skip_defrag_timeout_dup_detection_check; 9462 resource_cfg->vow_config = tgt_res_cfg->vow_config; 9463 resource_cfg->gtk_offload_max_vdev = tgt_res_cfg->gtk_offload_max_vdev; 9464 resource_cfg->num_msdu_desc = tgt_res_cfg->num_msdu_desc; 9465 resource_cfg->max_frag_entries = tgt_res_cfg->max_frag_entries; 9466 resource_cfg->num_tdls_vdevs = tgt_res_cfg->num_tdls_vdevs; 9467 resource_cfg->num_tdls_conn_table_entries = 9468 tgt_res_cfg->num_tdls_conn_table_entries; 9469 resource_cfg->beacon_tx_offload_max_vdev = 9470 tgt_res_cfg->beacon_tx_offload_max_vdev; 9471 resource_cfg->num_multicast_filter_entries = 9472 tgt_res_cfg->num_multicast_filter_entries; 9473 resource_cfg->num_wow_filters = 9474 tgt_res_cfg->num_wow_filters; 9475 resource_cfg->num_keep_alive_pattern = 9476 tgt_res_cfg->num_keep_alive_pattern; 9477 resource_cfg->keep_alive_pattern_size = 9478 tgt_res_cfg->keep_alive_pattern_size; 9479 resource_cfg->max_tdls_concurrent_sleep_sta = 9480 tgt_res_cfg->max_tdls_concurrent_sleep_sta; 9481 resource_cfg->max_tdls_concurrent_buffer_sta = 9482 tgt_res_cfg->max_tdls_concurrent_buffer_sta; 9483 resource_cfg->wmi_send_separate = 9484 tgt_res_cfg->wmi_send_separate; 9485 resource_cfg->num_ocb_vdevs = 9486 tgt_res_cfg->num_ocb_vdevs; 9487 resource_cfg->num_ocb_channels = 9488 tgt_res_cfg->num_ocb_channels; 9489 resource_cfg->num_ocb_schedules = 9490 tgt_res_cfg->num_ocb_schedules; 9491 resource_cfg->bpf_instruction_size = tgt_res_cfg->apf_instruction_size; 9492 resource_cfg->max_bssid_rx_filters = tgt_res_cfg->max_bssid_rx_filters; 9493 resource_cfg->use_pdev_id = tgt_res_cfg->use_pdev_id; 9494 resource_cfg->max_num_dbs_scan_duty_cycle = 9495 tgt_res_cfg->max_num_dbs_scan_duty_cycle; 9496 resource_cfg->sched_params = tgt_res_cfg->scheduler_params; 9497 resource_cfg->num_packet_filters = tgt_res_cfg->num_packet_filters; 9498 resource_cfg->num_max_sta_vdevs = tgt_res_cfg->num_max_sta_vdevs; 9499 resource_cfg->max_bssid_indicator = tgt_res_cfg->max_bssid_indicator; 9500 resource_cfg->max_num_group_keys = tgt_res_cfg->max_num_group_keys; 9501 /* Deferred AI: Max rnr neighbors supported in multisoc case 9502 * where in SoC can support 6ghz. During WMI init of a SoC 9503 * currently there is no way to figure if another SOC is plugged in 9504 * and it can support 6Ghz. 9505 */ 9506 resource_cfg->max_rnr_neighbours = MAX_SUPPORTED_NEIGHBORS; 9507 resource_cfg->ema_max_vap_cnt = tgt_res_cfg->ema_max_vap_cnt; 9508 resource_cfg->ema_max_profile_period = 9509 tgt_res_cfg->ema_max_profile_period; 9510 resource_cfg->ema_init_config = tgt_res_cfg->ema_init_config; 9511 resource_cfg->carrier_config = tgt_res_cfg->carrier_profile_config; 9512 9513 if (tgt_res_cfg->max_ndp_sessions) 9514 resource_cfg->max_ndp_sessions = 9515 tgt_res_cfg->max_ndp_sessions; 9516 resource_cfg->max_ndi_interfaces = tgt_res_cfg->max_ndi; 9517 resource_cfg->num_max_active_vdevs = tgt_res_cfg->num_max_active_vdevs; 9518 resource_cfg->num_max_mlo_link_per_ml_bss = 9519 tgt_res_cfg->num_max_mlo_link_per_ml_bss; 9520 9521 if (tgt_res_cfg->atf_config) 9522 WMI_RSRC_CFG_FLAG_ATF_CONFIG_ENABLE_SET(resource_cfg->flag1, 1); 9523 if (tgt_res_cfg->mgmt_comp_evt_bundle_support) 9524 WMI_RSRC_CFG_FLAG_MGMT_COMP_EVT_BUNDLE_SUPPORT_SET( 9525 resource_cfg->flag1, 1); 9526 if (tgt_res_cfg->tx_msdu_new_partition_id_support) 9527 WMI_RSRC_CFG_FLAG_TX_MSDU_ID_NEW_PARTITION_SUPPORT_SET( 9528 resource_cfg->flag1, 1); 9529 if (tgt_res_cfg->cce_disable) 9530 WMI_RSRC_CFG_FLAG_TCL_CCE_DISABLE_SET(resource_cfg->flag1, 1); 9531 if (tgt_res_cfg->enable_pci_gen) 9532 WMI_RSRC_CFG_FLAG_PCIE_GEN_SWITCH_CAPABLITY_SET( 9533 resource_cfg->flag1, 1); 9534 if (tgt_res_cfg->eapol_minrate_set) { 9535 WMI_RSRC_CFG_FLAG_EAPOL_REKEY_MINRATE_SUPPORT_ENABLE_SET( 9536 resource_cfg->flag1, 1); 9537 if (tgt_res_cfg->eapol_minrate_ac_set != 3) { 9538 WMI_RSRC_CFG_FLAG_EAPOL_AC_OVERRIDE_VALID_SET( 9539 resource_cfg->flag1, 1); 9540 WMI_RSRC_CFG_FLAG_EAPOL_AC_OVERRIDE_SET( 9541 resource_cfg->flag1, 9542 tgt_res_cfg->eapol_minrate_ac_set); 9543 } 9544 } 9545 if (tgt_res_cfg->new_htt_msg_format) { 9546 WMI_RSRC_CFG_FLAG_HTT_H2T_NO_HTC_HDR_LEN_IN_MSG_LEN_SET( 9547 resource_cfg->flag1, 1); 9548 } 9549 9550 if (tgt_res_cfg->peer_unmap_conf_support) 9551 WMI_RSRC_CFG_FLAG_PEER_UNMAP_RESPONSE_SUPPORT_SET( 9552 resource_cfg->flag1, 1); 9553 9554 if (tgt_res_cfg->tstamp64_en) 9555 WMI_RSRC_CFG_FLAG_TX_COMPLETION_TX_TSF64_ENABLE_SET( 9556 resource_cfg->flag1, 1); 9557 9558 if (tgt_res_cfg->three_way_coex_config_legacy_en) 9559 WMI_RSRC_CFG_FLAG_THREE_WAY_COEX_CONFIG_LEGACY_SUPPORT_SET( 9560 resource_cfg->flag1, 1); 9561 if (tgt_res_cfg->pktcapture_support) 9562 WMI_RSRC_CFG_FLAG_PACKET_CAPTURE_SUPPORT_SET( 9563 resource_cfg->flag1, 1); 9564 9565 /* 9566 * Control padding using config param/ini of iphdr_pad_config 9567 */ 9568 if (tgt_res_cfg->iphdr_pad_config) 9569 WMI_RSRC_CFG_FLAG_IPHR_PAD_CONFIG_ENABLE_SET( 9570 resource_cfg->flag1, 1); 9571 9572 WMI_RSRC_CFG_FLAG_IPA_DISABLE_SET(resource_cfg->flag1, 9573 tgt_res_cfg->ipa_disable); 9574 9575 if (tgt_res_cfg->time_sync_ftm) 9576 WMI_RSRC_CFG_FLAG_AUDIO_SYNC_SUPPORT_SET(resource_cfg->flag1, 9577 1); 9578 9579 wmi_copy_twt_resource_config(resource_cfg, tgt_res_cfg); 9580 resource_cfg->peer_map_unmap_versions = 9581 tgt_res_cfg->peer_map_unmap_version; 9582 resource_cfg->smart_ant_cap = tgt_res_cfg->smart_ant_cap; 9583 if (tgt_res_cfg->re_ul_resp) 9584 WMI_SET_BITS(resource_cfg->flags2, 0, 4, 9585 tgt_res_cfg->re_ul_resp); 9586 9587 /* 9588 * Enable Service Aware Wifi 9589 */ 9590 if (tgt_res_cfg->sawf) 9591 WMI_RSRC_CFG_FLAGS2_SAWF_CONFIG_ENABLE_SET(resource_cfg->flags2, 9592 tgt_res_cfg->sawf); 9593 9594 /* 9595 * Enable ast flow override per peer 9596 */ 9597 resource_cfg->msdu_flow_override_config0 = 0; 9598 WMI_MSDU_FLOW_AST_ENABLE_SET( 9599 resource_cfg->msdu_flow_override_config0, 9600 WMI_CONFIG_MSDU_AST_INDEX_1, 9601 tgt_res_cfg->ast_1_valid_mask_enable); 9602 9603 WMI_MSDU_FLOW_AST_ENABLE_SET( 9604 resource_cfg->msdu_flow_override_config0, 9605 WMI_CONFIG_MSDU_AST_INDEX_2, 9606 tgt_res_cfg->ast_2_valid_mask_enable); 9607 9608 WMI_MSDU_FLOW_AST_ENABLE_SET( 9609 resource_cfg->msdu_flow_override_config0, 9610 WMI_CONFIG_MSDU_AST_INDEX_3, 9611 tgt_res_cfg->ast_3_valid_mask_enable); 9612 9613 /* 9614 * Enable ast flow mask and TID valid mask configurations 9615 */ 9616 resource_cfg->msdu_flow_override_config1 = 0; 9617 9618 /*Enable UDP flow for Ast index 0*/ 9619 WMI_MSDU_FLOW_ASTX_MSDU_FLOW_MASKS_SET( 9620 resource_cfg->msdu_flow_override_config1, 9621 WMI_CONFIG_MSDU_AST_INDEX_0, 9622 tgt_res_cfg->ast_0_flow_mask_enable); 9623 9624 /*Enable Non UDP flow for Ast index 1*/ 9625 WMI_MSDU_FLOW_ASTX_MSDU_FLOW_MASKS_SET( 9626 resource_cfg->msdu_flow_override_config1, 9627 WMI_CONFIG_MSDU_AST_INDEX_1, 9628 tgt_res_cfg->ast_1_flow_mask_enable); 9629 9630 /*Enable Hi-Priority flow for Ast index 2*/ 9631 WMI_MSDU_FLOW_ASTX_MSDU_FLOW_MASKS_SET( 9632 resource_cfg->msdu_flow_override_config1, 9633 WMI_CONFIG_MSDU_AST_INDEX_2, 9634 tgt_res_cfg->ast_2_flow_mask_enable); 9635 9636 /*Enable Low-Priority flow for Ast index 3*/ 9637 WMI_MSDU_FLOW_ASTX_MSDU_FLOW_MASKS_SET( 9638 resource_cfg->msdu_flow_override_config1, 9639 WMI_CONFIG_MSDU_AST_INDEX_3, 9640 tgt_res_cfg->ast_3_flow_mask_enable); 9641 9642 /*Enable all 8 tid for Hi-Pririty Flow Queue*/ 9643 WMI_MSDU_FLOW_TID_VALID_HI_MASKS_SET( 9644 resource_cfg->msdu_flow_override_config1, 9645 tgt_res_cfg->ast_tid_high_mask_enable); 9646 9647 /*Enable all 8 tid for Low-Pririty Flow Queue*/ 9648 WMI_MSDU_FLOW_TID_VALID_LOW_MASKS_SET( 9649 resource_cfg->msdu_flow_override_config1, 9650 tgt_res_cfg->ast_tid_low_mask_enable); 9651 WMI_RSRC_CFG_HOST_SERVICE_FLAG_NAN_IFACE_SUPPORT_SET( 9652 resource_cfg->host_service_flags, 9653 tgt_res_cfg->nan_separate_iface_support); 9654 WMI_RSRC_CFG_HOST_SERVICE_FLAG_HOST_SUPPORT_MULTI_RADIO_EVTS_PER_RADIO_SET( 9655 resource_cfg->host_service_flags, 1); 9656 9657 WMI_RSRC_CFG_FLAG_VIDEO_OVER_WIFI_ENABLE_SET( 9658 resource_cfg->flag1, tgt_res_cfg->carrier_vow_optimization); 9659 9660 if (tgt_res_cfg->is_sap_connected_d3wow_enabled) 9661 WMI_RSRC_CFG_FLAGS2_IS_SAP_CONNECTED_D3WOW_ENABLED_SET( 9662 resource_cfg->flags2, 1); 9663 if (tgt_res_cfg->is_go_connected_d3wow_enabled) 9664 WMI_RSRC_CFG_FLAGS2_IS_GO_CONNECTED_D3WOW_ENABLED_SET( 9665 resource_cfg->flags2, 1); 9666 9667 if (tgt_res_cfg->sae_eapol_offload) 9668 WMI_RSRC_CFG_HOST_SERVICE_FLAG_SAE_EAPOL_OFFLOAD_SUPPORT_SET( 9669 resource_cfg->host_service_flags, 1); 9670 9671 WMI_RSRC_CFG_HOST_SERVICE_FLAG_REG_CC_EXT_SUPPORT_SET( 9672 resource_cfg->host_service_flags, 9673 tgt_res_cfg->is_reg_cc_ext_event_supported); 9674 9675 WMI_RSRC_CFG_HOST_SERVICE_FLAG_BANG_RADAR_320M_SUPPORT_SET( 9676 resource_cfg->host_service_flags, 9677 tgt_res_cfg->is_host_dfs_320mhz_bangradar_supported); 9678 9679 WMI_RSRC_CFG_HOST_SERVICE_FLAG_LPI_SP_MODE_SUPPORT_SET( 9680 resource_cfg->host_service_flags, 9681 tgt_res_cfg->is_6ghz_sp_pwrmode_supp_enabled); 9682 9683 WMI_RSRC_CFG_HOST_SERVICE_FLAG_REG_DISCARD_AFC_TIMER_CHECK_SET( 9684 resource_cfg->host_service_flags, 9685 tgt_res_cfg->afc_timer_check_disable); 9686 9687 WMI_RSRC_CFG_HOST_SERVICE_FLAG_REG_DISCARD_AFC_REQ_ID_CHECK_SET( 9688 resource_cfg->host_service_flags, 9689 tgt_res_cfg->afc_req_id_check_disable); 9690 9691 wmi_copy_afc_deployment_config(resource_cfg, tgt_res_cfg); 9692 9693 wmi_set_nan_channel_support(resource_cfg); 9694 9695 if (tgt_res_cfg->twt_ack_support_cap) 9696 WMI_RSRC_CFG_HOST_SERVICE_FLAG_STA_TWT_SYNC_EVT_SUPPORT_SET( 9697 resource_cfg->host_service_flags, 1); 9698 9699 if (tgt_res_cfg->reo_qdesc_shared_addr_table_enabled) 9700 WMI_RSRC_CFG_HOST_SERVICE_FLAG_REO_QREF_FEATURE_SUPPORT_SET( 9701 resource_cfg->host_service_flags, 1); 9702 /* 9703 * DP Peer Meta data FW version 9704 */ 9705 WMI_RSRC_CFG_FLAGS2_RX_PEER_METADATA_VERSION_SET( 9706 resource_cfg->flags2, 9707 tgt_res_cfg->dp_peer_meta_data_ver); 9708 9709 if (tgt_res_cfg->notify_frame_support) 9710 WMI_RSRC_CFG_FLAGS2_NOTIFY_FRAME_CONFIG_ENABLE_SET( 9711 resource_cfg->flags2, 1); 9712 9713 if (tgt_res_cfg->rf_path) 9714 WMI_RSRC_CFG_FLAGS2_RF_PATH_MODE_SET( 9715 resource_cfg->flags2, tgt_res_cfg->rf_path); 9716 9717 if (tgt_res_cfg->fw_ast_indication_disable) { 9718 WMI_RSRC_CFG_FLAGS2_DISABLE_WDS_PEER_MAP_UNMAP_EVENT_SET 9719 (resource_cfg->flags2, 9720 tgt_res_cfg->fw_ast_indication_disable); 9721 } 9722 9723 wmi_copy_latency_flowq_support(resource_cfg, tgt_res_cfg); 9724 wmi_copy_full_bw_nol_cfg(resource_cfg, tgt_res_cfg); 9725 9726 } 9727 9728 #ifdef FEATURE_SET 9729 /** 9730 * convert_host_to_target_vendor1_req2_version() -Convert host vendor1 9731 * requirement2 version to target vendor1 requirement2 version 9732 * @vendor1_req2_ver: Host vendor1 requirement2 version 9733 * 9734 * Return: Target vendor1 requirement2 version 9735 */ 9736 static WMI_VENDOR1_REQ2_VERSION convert_host_to_target_vendor1_req2_version( 9737 WMI_HOST_VENDOR1_REQ2_VERSION vendor1_req2_ver) 9738 { 9739 switch (vendor1_req2_ver) { 9740 case WMI_HOST_VENDOR1_REQ2_VERSION_3_00: 9741 return WMI_VENDOR1_REQ2_VERSION_3_00; 9742 case WMI_HOST_VENDOR1_REQ2_VERSION_3_01: 9743 return WMI_VENDOR1_REQ2_VERSION_3_01; 9744 case WMI_HOST_VENDOR1_REQ2_VERSION_3_20: 9745 return WMI_VENDOR1_REQ2_VERSION_3_20; 9746 case WMI_HOST_VENDOR1_REQ2_VERSION_3_50: 9747 return WMI_VENDOR1_REQ2_VERSION_3_50; 9748 default: 9749 return WMI_VENDOR1_REQ2_VERSION_3_00; 9750 } 9751 } 9752 9753 /** 9754 * convert_host_to_target_vendor1_req1_version() -Convert host vendor1 9755 * requirement1 version to target vendor1 requirement1 version 9756 * @vendor1_req1_ver: Host vendor1 requirement1 version 9757 * 9758 * Return: Target vendor1 requirement1 version 9759 */ 9760 static WMI_VENDOR1_REQ1_VERSION convert_host_to_target_vendor1_req1_version( 9761 WMI_HOST_VENDOR1_REQ1_VERSION vendor1_req1_ver) 9762 { 9763 switch (vendor1_req1_ver) { 9764 case WMI_HOST_VENDOR1_REQ1_VERSION_3_00: 9765 return WMI_VENDOR1_REQ1_VERSION_3_00; 9766 case WMI_HOST_VENDOR1_REQ1_VERSION_3_01: 9767 return WMI_VENDOR1_REQ1_VERSION_3_01; 9768 case WMI_HOST_VENDOR1_REQ1_VERSION_3_20: 9769 return WMI_VENDOR1_REQ1_VERSION_3_20; 9770 case WMI_HOST_VENDOR1_REQ1_VERSION_3_30: 9771 return WMI_VENDOR1_REQ1_VERSION_3_30; 9772 case WMI_HOST_VENDOR1_REQ1_VERSION_3_40: 9773 return WMI_VENDOR1_REQ1_VERSION_3_40; 9774 case WMI_HOST_VENDOR1_REQ1_VERSION_4_00: 9775 return WMI_VENDOR1_REQ1_VERSION_4_00; 9776 default: 9777 return WMI_VENDOR1_REQ1_VERSION_3_00; 9778 } 9779 } 9780 9781 /** 9782 * convert_host_to_target_wifi_standard() -Convert host wifi standard to 9783 * target wifi standard 9784 * @wifi_standard: Host wifi standard 9785 * 9786 * Return: Target wifi standard 9787 */ 9788 static WMI_WIFI_STANDARD convert_host_to_target_wifi_standard( 9789 WMI_HOST_WIFI_STANDARD wifi_standard) 9790 { 9791 switch (wifi_standard) { 9792 case WMI_HOST_WIFI_STANDARD_4: 9793 return WMI_WIFI_STANDARD_4; 9794 case WMI_HOST_WIFI_STANDARD_5: 9795 return WMI_WIFI_STANDARD_5; 9796 case WMI_HOST_WIFI_STANDARD_6: 9797 return WMI_WIFI_STANDARD_6; 9798 case WMI_HOST_WIFI_STANDARD_6E: 9799 return WMI_WIFI_STANDARD_6E; 9800 case WMI_HOST_WIFI_STANDARD_7: 9801 return WMI_WIFI_STANDARD_7; 9802 default: 9803 return WMI_WIFI_STANDARD_4; 9804 } 9805 } 9806 9807 /** 9808 * convert_host_to_target_band_concurrency() -Convert host band concurrency to 9809 * target band concurrency 9810 * @band_concurrency: Host Band concurrency 9811 * 9812 * Return: Target band concurrency 9813 */ 9814 static WMI_BAND_CONCURRENCY convert_host_to_target_band_concurrency( 9815 WMI_HOST_BAND_CONCURRENCY band_concurrency) 9816 { 9817 switch (band_concurrency) { 9818 case WMI_HOST_BAND_CONCURRENCY_DBS: 9819 return WMI_HOST_DBS; 9820 case WMI_HOST_BAND_CONCURRENCY_DBS_SBS: 9821 return WMI_HOST_DBS_SBS; 9822 default: 9823 return WMI_HOST_NONE; 9824 } 9825 } 9826 9827 /** 9828 * convert_host_to_target_num_antennas() -Convert host num antennas to 9829 * target num antennas 9830 * @num_antennas: Host num antennas 9831 * 9832 * Return: Target num antennas 9833 */ 9834 static WMI_NUM_ANTENNAS convert_host_to_target_num_antennas( 9835 WMI_HOST_NUM_ANTENNAS num_antennas) 9836 { 9837 switch (num_antennas) { 9838 case WMI_HOST_SISO: 9839 return WMI_SISO; 9840 case WMI_HOST_MIMO_2X2: 9841 return WMI_MIMO_2X2; 9842 default: 9843 return WMI_SISO; 9844 } 9845 } 9846 9847 /** 9848 * convert_host_to_target_band_capability() -Convert host band capability to 9849 * target band capability 9850 * @host_band_capability: Host band capability 9851 * 9852 * Return: Target band capability bitmap 9853 */ 9854 static uint8_t 9855 convert_host_to_target_band_capability(uint32_t host_band_capability) 9856 { 9857 uint8_t band_capability; 9858 9859 band_capability = (host_band_capability & WMI_HOST_BAND_CAP_2GHZ) | 9860 (host_band_capability & WMI_HOST_BAND_CAP_5GHZ) | 9861 (host_band_capability & WMI_HOST_BAND_CAP_6GHZ); 9862 return band_capability; 9863 } 9864 9865 /** 9866 * copy_feature_set_info() -Copy feature set info from host to target 9867 * @feature_set_bitmap: Target feature set pointer 9868 * @feature_set: Host feature set structure 9869 * 9870 * Return: None 9871 */ 9872 static inline void copy_feature_set_info(uint32_t *feature_set_bitmap, 9873 struct target_feature_set *feature_set) 9874 { 9875 WMI_NUM_ANTENNAS num_antennas; 9876 WMI_BAND_CONCURRENCY band_concurrency; 9877 WMI_WIFI_STANDARD wifi_standard; 9878 WMI_VENDOR1_REQ1_VERSION vendor1_req1_version; 9879 WMI_VENDOR1_REQ2_VERSION vendor1_req2_version; 9880 uint8_t band_capability; 9881 9882 num_antennas = convert_host_to_target_num_antennas( 9883 feature_set->num_antennas); 9884 band_concurrency = convert_host_to_target_band_concurrency( 9885 feature_set->concurrency_support); 9886 wifi_standard = convert_host_to_target_wifi_standard( 9887 feature_set->wifi_standard); 9888 vendor1_req1_version = convert_host_to_target_vendor1_req1_version( 9889 feature_set->vendor_req_1_version); 9890 vendor1_req2_version = convert_host_to_target_vendor1_req2_version( 9891 feature_set->vendor_req_2_version); 9892 9893 band_capability = 9894 convert_host_to_target_band_capability( 9895 feature_set->band_capability); 9896 9897 WMI_SET_WIFI_STANDARD(feature_set_bitmap, wifi_standard); 9898 WMI_SET_BAND_CONCURRENCY_SUPPORT(feature_set_bitmap, band_concurrency); 9899 WMI_SET_PNO_SCAN_IN_UNASSOC_STATE(feature_set_bitmap, 9900 feature_set->pno_in_unassoc_state); 9901 WMI_SET_PNO_SCAN_IN_ASSOC_STATE(feature_set_bitmap, 9902 feature_set->pno_in_assoc_state); 9903 WMI_SET_TWT_FEATURE_SUPPORT(feature_set_bitmap, 9904 feature_set->enable_twt); 9905 WMI_SET_TWT_REQUESTER(feature_set_bitmap, 9906 feature_set->enable_twt_requester); 9907 WMI_SET_TWT_BROADCAST(feature_set_bitmap, 9908 feature_set->enable_twt_broadcast); 9909 WMI_SET_TWT_FLEXIBLE(feature_set_bitmap, 9910 feature_set->enable_twt_flexible); 9911 WMI_SET_WIFI_OPT_FEATURE_SUPPORT(feature_set_bitmap, 9912 feature_set->enable_wifi_optimizer); 9913 WMI_SET_RFC8325_FEATURE_SUPPORT(feature_set_bitmap, 9914 feature_set->enable_rfc835); 9915 WMI_SET_MHS_5G_SUPPORT(feature_set_bitmap, 9916 feature_set->sap_5g_supported); 9917 WMI_SET_MHS_6G_SUPPORT(feature_set_bitmap, 9918 feature_set->sap_6g_supported); 9919 WMI_SET_MHS_MAX_CLIENTS_SUPPORT(feature_set_bitmap, 9920 feature_set->sap_max_num_clients); 9921 WMI_SET_MHS_SET_COUNTRY_CODE_HAL_SUPPORT( 9922 feature_set_bitmap, 9923 feature_set->set_country_code_hal_supported); 9924 WMI_SET_MHS_GETVALID_CHANNELS_SUPPORT( 9925 feature_set_bitmap, 9926 feature_set->get_valid_channel_supported); 9927 WMI_SET_MHS_DOT11_MODE_SUPPORT(feature_set_bitmap, 9928 feature_set->supported_dot11mode); 9929 WMI_SET_MHS_WPA3_SUPPORT(feature_set_bitmap, 9930 feature_set->sap_wpa3_support); 9931 WMI_SET_VENDOR_REQ_1_VERSION(feature_set_bitmap, vendor1_req1_version); 9932 WMI_SET_ROAMING_HIGH_CU_ROAM_TRIGGER( 9933 feature_set_bitmap, 9934 feature_set->roaming_high_cu_roam_trigger); 9935 WMI_SET_ROAMING_EMERGENCY_TRIGGER( 9936 feature_set_bitmap, 9937 feature_set->roaming_emergency_trigger); 9938 WMI_SET_ROAMING_BTM_TRIGGER(feature_set_bitmap, 9939 feature_set->roaming_btm_trihgger); 9940 WMI_SET_ROAMING_IDLE_TRIGGER(feature_set_bitmap, 9941 feature_set->roaming_idle_trigger); 9942 WMI_SET_ROAMING_WTC_TRIGGER(feature_set_bitmap, 9943 feature_set->roaming_wtc_trigger); 9944 WMI_SET_ROAMING_BTCOEX_TRIGGER(feature_set_bitmap, 9945 feature_set->roaming_btcoex_trigger); 9946 WMI_SET_ROAMING_BTW_WPA_WPA2(feature_set_bitmap, 9947 feature_set->roaming_btw_wpa_wpa2); 9948 WMI_SET_ROAMING_MANAGE_CHAN_LIST_API( 9949 feature_set_bitmap, 9950 feature_set->roaming_manage_chan_list_api); 9951 WMI_SET_ROAMING_ADAPTIVE_11R(feature_set_bitmap, 9952 feature_set->roaming_adaptive_11r); 9953 WMI_SET_ROAMING_CTRL_API_GET_SET(feature_set_bitmap, 9954 feature_set->roaming_ctrl_api_get_set); 9955 WMI_SET_ROAMING_CTRL_API_REASSOC(feature_set_bitmap, 9956 feature_set->roaming_ctrl_api_reassoc); 9957 WMI_SET_ROAMING_CTRL_GET_CU(feature_set_bitmap, 9958 feature_set->roaming_ctrl_get_cu); 9959 WMI_SET_VENDOR_REQ_2_VERSION(feature_set_bitmap, vendor1_req2_version); 9960 WMI_SET_ASSURANCE_DISCONNECT_REASON_API( 9961 feature_set_bitmap, 9962 feature_set->assurance_disconnect_reason_api); 9963 WMI_SET_FRAME_PCAP_LOG_MGMT(feature_set_bitmap, 9964 feature_set->frame_pcap_log_mgmt); 9965 WMI_SET_FRAME_PCAP_LOG_CTRL(feature_set_bitmap, 9966 feature_set->frame_pcap_log_ctrl); 9967 WMI_SET_FRAME_PCAP_LOG_DATA(feature_set_bitmap, 9968 feature_set->frame_pcap_log_data); 9969 WMI_SET_SECURITY_WPA3_SAE_H2E(feature_set_bitmap, 9970 feature_set->security_wpa3_sae_h2e); 9971 WMI_SET_SECURITY_WPA3_SAE_FT(feature_set_bitmap, 9972 feature_set->security_wpa3_sae_ft); 9973 WMI_SET_SECURITY_WPA3_ENTERP_SUITEB( 9974 feature_set_bitmap, 9975 feature_set->security_wpa3_enterp_suitb); 9976 WMI_SET_SECURITY_WPA3_ENTERP_SUITEB_192bit( 9977 feature_set_bitmap, 9978 feature_set->security_wpa3_enterp_suitb_192bit); 9979 WMI_SET_SECURITY_FILS_SHA256(feature_set_bitmap, 9980 feature_set->security_fills_sha_256); 9981 WMI_SET_SECURITY_FILS_SHA384(feature_set_bitmap, 9982 feature_set->security_fills_sha_384); 9983 WMI_SET_SECURITY_FILS_SHA256_FT(feature_set_bitmap, 9984 feature_set->security_fills_sha_256_FT); 9985 WMI_SET_SECURITY_FILS_SHA384_FT(feature_set_bitmap, 9986 feature_set->security_fills_sha_384_FT); 9987 WMI_SET_SECURITY_ENCHANCED_OPEN(feature_set_bitmap, 9988 feature_set->security_enhanced_open); 9989 WMI_SET_NAN_SUPPORT(feature_set_bitmap, feature_set->enable_nan); 9990 WMI_SET_TDLS_SUPPORT(feature_set_bitmap, feature_set->enable_tdls); 9991 WMI_SET_P2P6E_SUPPORT(feature_set_bitmap, feature_set->enable_p2p_6e); 9992 WMI_SET_TDLS_OFFCHAN_SUPPORT(feature_set_bitmap, 9993 feature_set->enable_tdls_offchannel); 9994 WMI_SET_TDLS_CAP_ENHANCE(feature_set_bitmap, 9995 feature_set->enable_tdls_capability_enhance); 9996 WMI_SET_MAX_TDLS_PEERS_SUPPORT(feature_set_bitmap, 9997 feature_set->max_tdls_peers); 9998 WMI_SET_STA_DUAL_P2P_SUPPORT(feature_set_bitmap, 9999 feature_set->sta_dual_p2p_support); 10000 WMI_SET_PEER_BIGDATA_GETBSSINFO_API_SUPPORT( 10001 feature_set_bitmap, 10002 feature_set->peer_bigdata_getbssinfo_support); 10003 WMI_SET_PEER_BIGDATA_GETASSOCREJECTINFO_API_SUPPORT( 10004 feature_set_bitmap, 10005 feature_set->peer_bigdata_assocreject_info_support); 10006 WMI_SET_PEER_BIGDATA_GETSTAINFO_API_SUPPORT( 10007 feature_set_bitmap, 10008 feature_set->peer_getstainfo_support); 10009 WMI_SET_FEATURE_SET_VERSION(feature_set_bitmap, 10010 feature_set->feature_set_version); 10011 WMI_SET_NUM_ANTENNAS(feature_set_bitmap, num_antennas); 10012 WMI_SET_HOST_BAND_CAP(feature_set_bitmap, band_capability); 10013 WMI_SET_STA_DUMP_SUPPORT(feature_set_bitmap, 10014 feature_set->sta_dump_support); 10015 } 10016 10017 /** 10018 * feature_set_cmd_send_tlv() -Send feature set command 10019 * @wmi_handle: WMI handle 10020 * @feature_set: Feature set structure 10021 * 10022 * Return: QDF_STATUS_SUCCESS on success else return failure 10023 */ 10024 static QDF_STATUS feature_set_cmd_send_tlv( 10025 struct wmi_unified *wmi_handle, 10026 struct target_feature_set *feature_set) 10027 { 10028 wmi_pdev_featureset_cmd_fixed_param *cmd; 10029 wmi_buf_t buf; 10030 uint16_t len; 10031 QDF_STATUS ret; 10032 uint8_t *buf_ptr; 10033 uint32_t *feature_set_bitmap; 10034 10035 len = sizeof(*cmd) + WMI_TLV_HDR_SIZE + 10036 WMI_FEATURE_SET_BITMAP_ARRAY_LEN32 * sizeof(uint32_t); 10037 buf = wmi_buf_alloc(wmi_handle, len); 10038 10039 if (!buf) 10040 return QDF_STATUS_E_NOMEM; 10041 10042 wmi_debug("Send feature set param"); 10043 10044 buf_ptr = (uint8_t *)wmi_buf_data(buf); 10045 10046 cmd = (wmi_pdev_featureset_cmd_fixed_param *)wmi_buf_data(buf); 10047 10048 WMITLV_SET_HDR(&cmd->tlv_header, 10049 WMITLV_TAG_STRUC_wmi_pdev_featureset_cmd_fixed_param, 10050 WMITLV_GET_STRUCT_TLVLEN( 10051 wmi_pdev_featureset_cmd_fixed_param)); 10052 10053 feature_set_bitmap = (uint32_t *)(buf_ptr + sizeof(*cmd) + 10054 WMI_TLV_HDR_SIZE); 10055 WMITLV_SET_HDR(buf_ptr + sizeof(*cmd), WMITLV_TAG_ARRAY_UINT32, 10056 (WMI_FEATURE_SET_BITMAP_ARRAY_LEN32 * sizeof(uint32_t))); 10057 copy_feature_set_info(feature_set_bitmap, feature_set); 10058 10059 qdf_trace_hex_dump(QDF_MODULE_ID_WMI, QDF_TRACE_LEVEL_DEBUG, 10060 feature_set_bitmap, 10061 WMI_FEATURE_SET_BITMAP_ARRAY_LEN32 * 10062 sizeof(uint32_t)); 10063 10064 wmi_mtrace(WMI_PDEV_FEATURESET_CMDID, NO_SESSION, 0); 10065 10066 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 10067 WMI_PDEV_FEATURESET_CMDID); 10068 if (QDF_IS_STATUS_ERROR(ret)) 10069 wmi_buf_free(buf); 10070 10071 return ret; 10072 } 10073 #endif 10074 10075 /* copy_hw_mode_id_in_init_cmd() - Helper routine to copy hw_mode in init cmd 10076 * @wmi_handle: pointer to wmi handle 10077 * @buf_ptr: pointer to current position in init command buffer 10078 * @len: pointer to length. This will be updated with current length of cmd 10079 * @param: point host parameters for init command 10080 * 10081 * Return: Updated pointer of buf_ptr. 10082 */ 10083 static inline uint8_t *copy_hw_mode_in_init_cmd(struct wmi_unified *wmi_handle, 10084 uint8_t *buf_ptr, int *len, struct wmi_init_cmd_param *param) 10085 { 10086 uint16_t idx; 10087 10088 if (param->hw_mode_id != WMI_HOST_HW_MODE_MAX) { 10089 wmi_pdev_set_hw_mode_cmd_fixed_param *hw_mode; 10090 wmi_pdev_band_to_mac *band_to_mac; 10091 10092 hw_mode = (wmi_pdev_set_hw_mode_cmd_fixed_param *) 10093 (buf_ptr + sizeof(wmi_init_cmd_fixed_param) + 10094 sizeof(wmi_resource_config) + 10095 WMI_TLV_HDR_SIZE + (param->num_mem_chunks * 10096 sizeof(wlan_host_memory_chunk))); 10097 10098 WMITLV_SET_HDR(&hw_mode->tlv_header, 10099 WMITLV_TAG_STRUC_wmi_pdev_set_hw_mode_cmd_fixed_param, 10100 (WMITLV_GET_STRUCT_TLVLEN 10101 (wmi_pdev_set_hw_mode_cmd_fixed_param))); 10102 10103 hw_mode->hw_mode_index = param->hw_mode_id; 10104 hw_mode->num_band_to_mac = param->num_band_to_mac; 10105 10106 buf_ptr = (uint8_t *) (hw_mode + 1); 10107 band_to_mac = (wmi_pdev_band_to_mac *) (buf_ptr + 10108 WMI_TLV_HDR_SIZE); 10109 for (idx = 0; idx < param->num_band_to_mac; idx++) { 10110 WMITLV_SET_HDR(&band_to_mac[idx].tlv_header, 10111 WMITLV_TAG_STRUC_wmi_pdev_band_to_mac, 10112 WMITLV_GET_STRUCT_TLVLEN 10113 (wmi_pdev_band_to_mac)); 10114 band_to_mac[idx].pdev_id = 10115 wmi_handle->ops->convert_pdev_id_host_to_target( 10116 wmi_handle, 10117 param->band_to_mac[idx].pdev_id); 10118 band_to_mac[idx].start_freq = 10119 param->band_to_mac[idx].start_freq; 10120 band_to_mac[idx].end_freq = 10121 param->band_to_mac[idx].end_freq; 10122 } 10123 *len += sizeof(wmi_pdev_set_hw_mode_cmd_fixed_param) + 10124 (param->num_band_to_mac * 10125 sizeof(wmi_pdev_band_to_mac)) + 10126 WMI_TLV_HDR_SIZE; 10127 10128 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 10129 (param->num_band_to_mac * 10130 sizeof(wmi_pdev_band_to_mac))); 10131 } 10132 10133 return buf_ptr; 10134 } 10135 10136 static inline void copy_fw_abi_version_tlv(wmi_unified_t wmi_handle, 10137 wmi_init_cmd_fixed_param *cmd) 10138 { 10139 int num_allowlist; 10140 wmi_abi_version my_vers; 10141 10142 num_allowlist = sizeof(version_whitelist) / 10143 sizeof(wmi_whitelist_version_info); 10144 my_vers.abi_version_0 = WMI_ABI_VERSION_0; 10145 my_vers.abi_version_1 = WMI_ABI_VERSION_1; 10146 my_vers.abi_version_ns_0 = WMI_ABI_VERSION_NS_0; 10147 my_vers.abi_version_ns_1 = WMI_ABI_VERSION_NS_1; 10148 my_vers.abi_version_ns_2 = WMI_ABI_VERSION_NS_2; 10149 my_vers.abi_version_ns_3 = WMI_ABI_VERSION_NS_3; 10150 10151 wmi_cmp_and_set_abi_version(num_allowlist, version_whitelist, 10152 &my_vers, 10153 (struct _wmi_abi_version *)&wmi_handle->fw_abi_version, 10154 &cmd->host_abi_vers); 10155 10156 qdf_debug("INIT_CMD version: %d, %d, 0x%x, 0x%x, 0x%x, 0x%x", 10157 WMI_VER_GET_MAJOR(cmd->host_abi_vers.abi_version_0), 10158 WMI_VER_GET_MINOR(cmd->host_abi_vers.abi_version_0), 10159 cmd->host_abi_vers.abi_version_ns_0, 10160 cmd->host_abi_vers.abi_version_ns_1, 10161 cmd->host_abi_vers.abi_version_ns_2, 10162 cmd->host_abi_vers.abi_version_ns_3); 10163 10164 /* Save version sent from host - 10165 * Will be used to check ready event 10166 */ 10167 qdf_mem_copy(&wmi_handle->final_abi_vers, &cmd->host_abi_vers, 10168 sizeof(wmi_abi_version)); 10169 } 10170 10171 /* 10172 * send_cfg_action_frm_tb_ppdu_cmd_tlv() - send action frame tb ppdu cfg to FW 10173 * @wmi_handle: Pointer to WMi handle 10174 * @ie_data: Pointer for ie data 10175 * 10176 * This function sends action frame tb ppdu cfg to FW 10177 * 10178 * Return: QDF_STATUS_SUCCESS for success otherwise failure 10179 * 10180 */ 10181 static QDF_STATUS send_cfg_action_frm_tb_ppdu_cmd_tlv(wmi_unified_t wmi_handle, 10182 struct cfg_action_frm_tb_ppdu_param *cfg_msg) 10183 { 10184 wmi_pdev_he_tb_action_frm_cmd_fixed_param *cmd; 10185 wmi_buf_t buf; 10186 uint8_t *buf_ptr; 10187 uint32_t len, frm_len_aligned; 10188 QDF_STATUS ret; 10189 10190 frm_len_aligned = roundup(cfg_msg->frm_len, sizeof(uint32_t)); 10191 /* Allocate memory for the WMI command */ 10192 len = sizeof(*cmd) + WMI_TLV_HDR_SIZE + frm_len_aligned; 10193 10194 buf = wmi_buf_alloc(wmi_handle, len); 10195 if (!buf) 10196 return QDF_STATUS_E_NOMEM; 10197 10198 buf_ptr = wmi_buf_data(buf); 10199 qdf_mem_zero(buf_ptr, len); 10200 10201 /* Populate the WMI command */ 10202 cmd = (wmi_pdev_he_tb_action_frm_cmd_fixed_param *)buf_ptr; 10203 10204 WMITLV_SET_HDR(&cmd->tlv_header, 10205 WMITLV_TAG_STRUC_wmi_pdev_he_tb_action_frm_cmd_fixed_param, 10206 WMITLV_GET_STRUCT_TLVLEN( 10207 wmi_pdev_he_tb_action_frm_cmd_fixed_param)); 10208 cmd->enable = cfg_msg->cfg; 10209 cmd->data_len = cfg_msg->frm_len; 10210 10211 buf_ptr += sizeof(*cmd); 10212 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, frm_len_aligned); 10213 buf_ptr += WMI_TLV_HDR_SIZE; 10214 10215 qdf_mem_copy(buf_ptr, cfg_msg->data, cmd->data_len); 10216 10217 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 10218 WMI_PDEV_HE_TB_ACTION_FRM_CMDID); 10219 if (QDF_IS_STATUS_ERROR(ret)) { 10220 wmi_err("HE TB action frame cmnd send fail, ret %d", ret); 10221 wmi_buf_free(buf); 10222 } 10223 10224 return ret; 10225 } 10226 10227 static QDF_STATUS save_fw_version_cmd_tlv(wmi_unified_t wmi_handle, void *evt_buf) 10228 { 10229 WMI_SERVICE_READY_EVENTID_param_tlvs *param_buf; 10230 wmi_service_ready_event_fixed_param *ev; 10231 10232 10233 param_buf = (WMI_SERVICE_READY_EVENTID_param_tlvs *) evt_buf; 10234 10235 ev = (wmi_service_ready_event_fixed_param *) param_buf->fixed_param; 10236 if (!ev) 10237 return QDF_STATUS_E_FAILURE; 10238 10239 /*Save fw version from service ready message */ 10240 /*This will be used while sending INIT message */ 10241 qdf_mem_copy(&wmi_handle->fw_abi_version, &ev->fw_abi_vers, 10242 sizeof(wmi_handle->fw_abi_version)); 10243 10244 return QDF_STATUS_SUCCESS; 10245 } 10246 10247 /** 10248 * check_and_update_fw_version_cmd_tlv() - save fw version 10249 * @wmi_handle: pointer to wmi handle 10250 * @evt_buf: pointer to the event buffer 10251 * 10252 * This function extracts and saves the firmware WMI ABI version 10253 * 10254 * Return: QDF_STATUS_SUCCESS for success otherwise failure 10255 * 10256 */ 10257 static QDF_STATUS check_and_update_fw_version_cmd_tlv(wmi_unified_t wmi_handle, 10258 void *evt_buf) 10259 { 10260 WMI_READY_EVENTID_param_tlvs *param_buf = NULL; 10261 wmi_ready_event_fixed_param *ev = NULL; 10262 10263 param_buf = (WMI_READY_EVENTID_param_tlvs *) evt_buf; 10264 ev = param_buf->fixed_param; 10265 if (!wmi_versions_are_compatible((struct _wmi_abi_version *) 10266 &wmi_handle->final_abi_vers, 10267 &ev->fw_abi_vers)) { 10268 /* 10269 * Error: Our host version and the given firmware version 10270 * are incompatible. 10271 **/ 10272 wmi_debug("Error: Incompatible WMI version." 10273 "Host: %d,%d,0x%x 0x%x 0x%x 0x%x, FW: %d,%d,0x%x 0x%x 0x%x 0x%x", 10274 WMI_VER_GET_MAJOR(wmi_handle->final_abi_vers. 10275 abi_version_0), 10276 WMI_VER_GET_MINOR(wmi_handle->final_abi_vers. 10277 abi_version_0), 10278 wmi_handle->final_abi_vers.abi_version_ns_0, 10279 wmi_handle->final_abi_vers.abi_version_ns_1, 10280 wmi_handle->final_abi_vers.abi_version_ns_2, 10281 wmi_handle->final_abi_vers.abi_version_ns_3, 10282 WMI_VER_GET_MAJOR(ev->fw_abi_vers.abi_version_0), 10283 WMI_VER_GET_MINOR(ev->fw_abi_vers.abi_version_0), 10284 ev->fw_abi_vers.abi_version_ns_0, 10285 ev->fw_abi_vers.abi_version_ns_1, 10286 ev->fw_abi_vers.abi_version_ns_2, 10287 ev->fw_abi_vers.abi_version_ns_3); 10288 10289 return QDF_STATUS_E_FAILURE; 10290 } 10291 qdf_mem_copy(&wmi_handle->final_abi_vers, &ev->fw_abi_vers, 10292 sizeof(wmi_abi_version)); 10293 qdf_mem_copy(&wmi_handle->fw_abi_version, &ev->fw_abi_vers, 10294 sizeof(wmi_abi_version)); 10295 10296 return QDF_STATUS_SUCCESS; 10297 } 10298 10299 /** 10300 * send_log_supported_evt_cmd_tlv() - Enable/Disable FW diag/log events 10301 * @wmi_handle: wmi handle 10302 * @event: Event received from FW 10303 * @len: Length of the event 10304 * 10305 * Enables the low frequency events and disables the high frequency 10306 * events. Bit 17 indicates if the event if low/high frequency. 10307 * 1 - high frequency, 0 - low frequency 10308 * 10309 * Return: QDF_STATUS_SUCCESS for success or error code 10310 */ 10311 static QDF_STATUS send_log_supported_evt_cmd_tlv(wmi_unified_t wmi_handle, 10312 uint8_t *event, 10313 uint32_t len) 10314 { 10315 uint32_t num_of_diag_events_logs; 10316 wmi_diag_event_log_config_fixed_param *cmd; 10317 wmi_buf_t buf; 10318 uint8_t *buf_ptr; 10319 uint32_t *cmd_args, *evt_args; 10320 uint32_t buf_len, i; 10321 10322 WMI_DIAG_EVENT_LOG_SUPPORTED_EVENTID_param_tlvs *param_buf; 10323 wmi_diag_event_log_supported_event_fixed_params *wmi_event; 10324 10325 wmi_debug("Received WMI_DIAG_EVENT_LOG_SUPPORTED_EVENTID"); 10326 10327 param_buf = (WMI_DIAG_EVENT_LOG_SUPPORTED_EVENTID_param_tlvs *) event; 10328 if (!param_buf) { 10329 wmi_err("Invalid log supported event buffer"); 10330 return QDF_STATUS_E_INVAL; 10331 } 10332 wmi_event = param_buf->fixed_param; 10333 num_of_diag_events_logs = wmi_event->num_of_diag_events_logs; 10334 10335 if (num_of_diag_events_logs > 10336 param_buf->num_diag_events_logs_list) { 10337 wmi_err("message number of events %d is more than tlv hdr content %d", 10338 num_of_diag_events_logs, 10339 param_buf->num_diag_events_logs_list); 10340 return QDF_STATUS_E_INVAL; 10341 } 10342 10343 evt_args = param_buf->diag_events_logs_list; 10344 if (!evt_args) { 10345 wmi_err("Event list is empty, num_of_diag_events_logs=%d", 10346 num_of_diag_events_logs); 10347 return QDF_STATUS_E_INVAL; 10348 } 10349 10350 wmi_debug("num_of_diag_events_logs=%d", num_of_diag_events_logs); 10351 10352 /* Free any previous allocation */ 10353 if (wmi_handle->events_logs_list) { 10354 qdf_mem_free(wmi_handle->events_logs_list); 10355 wmi_handle->events_logs_list = NULL; 10356 } 10357 10358 if (num_of_diag_events_logs > 10359 (WMI_SVC_MSG_MAX_SIZE / sizeof(uint32_t))) { 10360 wmi_err("excess num of logs: %d", num_of_diag_events_logs); 10361 QDF_ASSERT(0); 10362 return QDF_STATUS_E_INVAL; 10363 } 10364 /* Store the event list for run time enable/disable */ 10365 wmi_handle->events_logs_list = qdf_mem_malloc(num_of_diag_events_logs * 10366 sizeof(uint32_t)); 10367 if (!wmi_handle->events_logs_list) 10368 return QDF_STATUS_E_NOMEM; 10369 10370 wmi_handle->num_of_diag_events_logs = num_of_diag_events_logs; 10371 10372 /* Prepare the send buffer */ 10373 buf_len = sizeof(*cmd) + WMI_TLV_HDR_SIZE + 10374 (num_of_diag_events_logs * sizeof(uint32_t)); 10375 10376 buf = wmi_buf_alloc(wmi_handle, buf_len); 10377 if (!buf) { 10378 qdf_mem_free(wmi_handle->events_logs_list); 10379 wmi_handle->events_logs_list = NULL; 10380 return QDF_STATUS_E_NOMEM; 10381 } 10382 10383 cmd = (wmi_diag_event_log_config_fixed_param *) wmi_buf_data(buf); 10384 buf_ptr = (uint8_t *) cmd; 10385 10386 WMITLV_SET_HDR(&cmd->tlv_header, 10387 WMITLV_TAG_STRUC_wmi_diag_event_log_config_fixed_param, 10388 WMITLV_GET_STRUCT_TLVLEN( 10389 wmi_diag_event_log_config_fixed_param)); 10390 10391 cmd->num_of_diag_events_logs = num_of_diag_events_logs; 10392 10393 buf_ptr += sizeof(wmi_diag_event_log_config_fixed_param); 10394 10395 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, 10396 (num_of_diag_events_logs * sizeof(uint32_t))); 10397 10398 cmd_args = (uint32_t *) (buf_ptr + WMI_TLV_HDR_SIZE); 10399 10400 /* Populate the events */ 10401 for (i = 0; i < num_of_diag_events_logs; i++) { 10402 /* Low freq (0) - Enable (1) the event 10403 * High freq (1) - Disable (0) the event 10404 */ 10405 WMI_DIAG_ID_ENABLED_DISABLED_SET(cmd_args[i], 10406 !(WMI_DIAG_FREQUENCY_GET(evt_args[i]))); 10407 /* Set the event ID */ 10408 WMI_DIAG_ID_SET(cmd_args[i], 10409 WMI_DIAG_ID_GET(evt_args[i])); 10410 /* Set the type */ 10411 WMI_DIAG_TYPE_SET(cmd_args[i], 10412 WMI_DIAG_TYPE_GET(evt_args[i])); 10413 /* Storing the event/log list in WMI */ 10414 wmi_handle->events_logs_list[i] = evt_args[i]; 10415 } 10416 10417 wmi_mtrace(WMI_DIAG_EVENT_LOG_CONFIG_CMDID, NO_SESSION, 0); 10418 if (wmi_unified_cmd_send(wmi_handle, buf, buf_len, 10419 WMI_DIAG_EVENT_LOG_CONFIG_CMDID)) { 10420 wmi_err("WMI_DIAG_EVENT_LOG_CONFIG_CMDID failed"); 10421 wmi_buf_free(buf); 10422 /* Not clearing events_logs_list, though wmi cmd failed. 10423 * Host can still have this list 10424 */ 10425 return QDF_STATUS_E_INVAL; 10426 } 10427 10428 return 0; 10429 } 10430 10431 /** 10432 * send_enable_specific_fw_logs_cmd_tlv() - Start/Stop logging of diag log id 10433 * @wmi_handle: wmi handle 10434 * @start_log: Start logging related parameters 10435 * 10436 * Send the command to the FW based on which specific logging of diag 10437 * event/log id can be started/stopped 10438 * 10439 * Return: None 10440 */ 10441 static QDF_STATUS send_enable_specific_fw_logs_cmd_tlv(wmi_unified_t wmi_handle, 10442 struct wmi_wifi_start_log *start_log) 10443 { 10444 wmi_diag_event_log_config_fixed_param *cmd; 10445 wmi_buf_t buf; 10446 uint8_t *buf_ptr; 10447 uint32_t len, count, log_level, i; 10448 uint32_t *cmd_args; 10449 uint32_t total_len; 10450 count = 0; 10451 10452 if (!wmi_handle->events_logs_list) { 10453 wmi_debug("Not received event/log list from FW, yet"); 10454 return QDF_STATUS_E_NOMEM; 10455 } 10456 /* total_len stores the number of events where BITS 17 and 18 are set. 10457 * i.e., events of high frequency (17) and for extended debugging (18) 10458 */ 10459 total_len = 0; 10460 for (i = 0; i < wmi_handle->num_of_diag_events_logs; i++) { 10461 if ((WMI_DIAG_FREQUENCY_GET(wmi_handle->events_logs_list[i])) && 10462 (WMI_DIAG_EXT_FEATURE_GET(wmi_handle->events_logs_list[i]))) 10463 total_len++; 10464 } 10465 10466 len = sizeof(*cmd) + WMI_TLV_HDR_SIZE + 10467 (total_len * sizeof(uint32_t)); 10468 10469 buf = wmi_buf_alloc(wmi_handle, len); 10470 if (!buf) 10471 return QDF_STATUS_E_NOMEM; 10472 10473 cmd = (wmi_diag_event_log_config_fixed_param *) wmi_buf_data(buf); 10474 buf_ptr = (uint8_t *) cmd; 10475 10476 WMITLV_SET_HDR(&cmd->tlv_header, 10477 WMITLV_TAG_STRUC_wmi_diag_event_log_config_fixed_param, 10478 WMITLV_GET_STRUCT_TLVLEN( 10479 wmi_diag_event_log_config_fixed_param)); 10480 10481 cmd->num_of_diag_events_logs = total_len; 10482 10483 buf_ptr += sizeof(wmi_diag_event_log_config_fixed_param); 10484 10485 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, 10486 (total_len * sizeof(uint32_t))); 10487 10488 cmd_args = (uint32_t *) (buf_ptr + WMI_TLV_HDR_SIZE); 10489 10490 if (start_log->verbose_level >= WMI_LOG_LEVEL_ACTIVE) 10491 log_level = 1; 10492 else 10493 log_level = 0; 10494 10495 wmi_debug("Length: %d Log_level: %d", total_len, log_level); 10496 for (i = 0; i < wmi_handle->num_of_diag_events_logs; i++) { 10497 uint32_t val = wmi_handle->events_logs_list[i]; 10498 if ((WMI_DIAG_FREQUENCY_GET(val)) && 10499 (WMI_DIAG_EXT_FEATURE_GET(val))) { 10500 10501 WMI_DIAG_ID_SET(cmd_args[count], 10502 WMI_DIAG_ID_GET(val)); 10503 WMI_DIAG_TYPE_SET(cmd_args[count], 10504 WMI_DIAG_TYPE_GET(val)); 10505 WMI_DIAG_ID_ENABLED_DISABLED_SET(cmd_args[count], 10506 log_level); 10507 wmi_debug("Idx:%d, val:%x", i, val); 10508 count++; 10509 } 10510 } 10511 10512 wmi_mtrace(WMI_DIAG_EVENT_LOG_CONFIG_CMDID, NO_SESSION, 0); 10513 if (wmi_unified_cmd_send(wmi_handle, buf, len, 10514 WMI_DIAG_EVENT_LOG_CONFIG_CMDID)) { 10515 wmi_err("WMI_DIAG_EVENT_LOG_CONFIG_CMDID failed"); 10516 wmi_buf_free(buf); 10517 return QDF_STATUS_E_INVAL; 10518 } 10519 10520 return QDF_STATUS_SUCCESS; 10521 } 10522 10523 /** 10524 * send_flush_logs_to_fw_cmd_tlv() - Send log flush command to FW 10525 * @wmi_handle: WMI handle 10526 * 10527 * This function is used to send the flush command to the FW, 10528 * that will flush the fw logs that are residue in the FW 10529 * 10530 * Return: None 10531 */ 10532 static QDF_STATUS send_flush_logs_to_fw_cmd_tlv(wmi_unified_t wmi_handle) 10533 { 10534 wmi_debug_mesg_flush_fixed_param *cmd; 10535 wmi_buf_t buf; 10536 int len = sizeof(*cmd); 10537 QDF_STATUS ret; 10538 10539 buf = wmi_buf_alloc(wmi_handle, len); 10540 if (!buf) 10541 return QDF_STATUS_E_NOMEM; 10542 10543 cmd = (wmi_debug_mesg_flush_fixed_param *) wmi_buf_data(buf); 10544 WMITLV_SET_HDR(&cmd->tlv_header, 10545 WMITLV_TAG_STRUC_wmi_debug_mesg_flush_fixed_param, 10546 WMITLV_GET_STRUCT_TLVLEN( 10547 wmi_debug_mesg_flush_fixed_param)); 10548 cmd->reserved0 = 0; 10549 10550 wmi_mtrace(WMI_DEBUG_MESG_FLUSH_CMDID, NO_SESSION, 0); 10551 ret = wmi_unified_cmd_send(wmi_handle, 10552 buf, 10553 len, 10554 WMI_DEBUG_MESG_FLUSH_CMDID); 10555 if (QDF_IS_STATUS_ERROR(ret)) { 10556 wmi_err("Failed to send WMI_DEBUG_MESG_FLUSH_CMDID"); 10557 wmi_buf_free(buf); 10558 return QDF_STATUS_E_INVAL; 10559 } 10560 wmi_debug("Sent WMI_DEBUG_MESG_FLUSH_CMDID to FW"); 10561 10562 return ret; 10563 } 10564 10565 #ifdef BIG_ENDIAN_HOST 10566 #ifdef WLAN_FEATURE_FIPS_BER_CCMGCM 10567 /** 10568 * fips_extend_align_data_be() - LE to BE conversion of FIPS extend ev data 10569 * @wmi_handle: wmi handle 10570 * @param: fips extend param related parameters 10571 * 10572 * Return: QDF_STATUS - success or error status 10573 */ 10574 static QDF_STATUS fips_extend_align_data_be(wmi_unified_t wmi_handle, 10575 struct fips_extend_params *param) 10576 { 10577 unsigned char *key_unaligned, *nonce_iv_unaligned, *data_unaligned; 10578 int c; 10579 u_int8_t *key_aligned = NULL; 10580 u_int8_t *nonce_iv_aligned = NULL; 10581 u_int8_t *data_aligned = NULL; 10582 int ret = QDF_STATUS_SUCCESS; 10583 10584 /* Assigning unaligned space to copy the key */ 10585 key_unaligned = qdf_mem_malloc(sizeof(u_int8_t) * 10586 param->cmd_params.key_len + FIPS_ALIGN); 10587 /* Checking if kmalloc is successful to allocate space */ 10588 if (!key_unaligned) 10589 return QDF_STATUS_E_INVAL; 10590 10591 data_unaligned = qdf_mem_malloc(sizeof(u_int8_t) * param->data_len + 10592 FIPS_ALIGN); 10593 /* Checking if kmalloc is successful to allocate space */ 10594 if (!data_unaligned) { 10595 ret = QDF_STATUS_E_INVAL; 10596 goto fips_align_fail_data; 10597 } 10598 10599 /* Checking if space is aligned */ 10600 if (!FIPS_IS_ALIGNED(key_unaligned, FIPS_ALIGN)) { 10601 /* align to 4 */ 10602 key_aligned = (u_int8_t *)FIPS_ALIGNTO(key_unaligned, 10603 FIPS_ALIGN); 10604 } else { 10605 key_aligned = (u_int8_t *)key_unaligned; 10606 } 10607 10608 /* memset and copy content from key to key aligned */ 10609 OS_MEMSET(key_aligned, 0, param->cmd_params.key_len); 10610 OS_MEMCPY(key_aligned, param->cmd_params.key, 10611 param->cmd_params.key_len); 10612 10613 /* print a hexdump for host debug */ 10614 wmi_debug("Aligned and Copied Key: "); 10615 qdf_trace_hex_dump(QDF_MODULE_ID_WMI, QDF_TRACE_LEVEL_DEBUG, 10616 key_aligned, param->cmd_params.key_len); 10617 10618 /* Checking of space is aligned */ 10619 if (!FIPS_IS_ALIGNED(data_unaligned, FIPS_ALIGN)) { 10620 /* align to 4 */ 10621 data_aligned = 10622 (u_int8_t *)FIPS_ALIGNTO(data_unaligned, FIPS_ALIGN); 10623 } else { 10624 data_aligned = (u_int8_t *)data_unaligned; 10625 } 10626 10627 /* memset and copy content from data to data aligned */ 10628 OS_MEMSET(data_aligned, 0, param->data_len); 10629 OS_MEMCPY(data_aligned, param->data, param->data_len); 10630 10631 /* print a hexdump for host debug */ 10632 wmi_debug("\t Properly Aligned and Copied Data: "); 10633 qdf_trace_hex_dump(QDF_MODULE_ID_WMI, QDF_TRACE_LEVEL_DEBUG, 10634 data_aligned, param->data_len); 10635 10636 /* converting to little Endian */ 10637 for (c = 0; c < param->cmd_params.key_len / 4; c++) { 10638 *((u_int32_t *)key_aligned + c) = 10639 qdf_cpu_to_le32(*((u_int32_t *)key_aligned + c)); 10640 } 10641 for (c = 0; c < param->data_len / 4; c++) { 10642 *((u_int32_t *)data_aligned + c) = 10643 qdf_cpu_to_le32(*((u_int32_t *)data_aligned + c)); 10644 } 10645 10646 /* update endian data */ 10647 OS_MEMCPY(param->cmd_params.key, key_aligned, 10648 param->cmd_params.key_len); 10649 OS_MEMCPY(param->data, data_aligned, param->data_len); 10650 10651 if (param->cmd_params.nonce_iv_len) { 10652 nonce_iv_unaligned = qdf_mem_malloc(sizeof(u_int8_t) * 10653 param->cmd_params.nonce_iv_len + 10654 FIPS_ALIGN); 10655 10656 /* Checking if kmalloc is successful to allocate space */ 10657 if (!nonce_iv_unaligned) { 10658 ret = QDF_STATUS_E_INVAL; 10659 goto fips_align_fail_nonce_iv; 10660 } 10661 /* Checking if space is aligned */ 10662 if (!FIPS_IS_ALIGNED(nonce_iv_unaligned, FIPS_ALIGN)) { 10663 /* align to 4 */ 10664 nonce_iv_aligned = 10665 (u_int8_t *)FIPS_ALIGNTO(nonce_iv_unaligned, 10666 FIPS_ALIGN); 10667 } else { 10668 nonce_iv_aligned = (u_int8_t *)nonce_iv_unaligned; 10669 } 10670 10671 /* memset and copy content from iv to iv aligned */ 10672 OS_MEMSET(nonce_iv_aligned, 0, param->cmd_params.nonce_iv_len); 10673 OS_MEMCPY(nonce_iv_aligned, param->cmd_params.nonce_iv, 10674 param->cmd_params.nonce_iv_len); 10675 10676 /* print a hexdump for host debug */ 10677 wmi_debug("\t Aligned and Copied Nonce_IV: "); 10678 qdf_trace_hex_dump(QDF_MODULE_ID_WMI, QDF_TRACE_LEVEL_DEBUG, 10679 nonce_iv_aligned, 10680 param->cmd_params.nonce_iv_len); 10681 10682 for (c = 0; c < param->cmd_params.nonce_iv_len / 4; c++) { 10683 *((u_int32_t *)nonce_iv_aligned + c) = 10684 qdf_cpu_to_le32(*((u_int32_t *)nonce_iv_aligned + c)); 10685 } 10686 } 10687 10688 /* clean up allocated spaces */ 10689 qdf_mem_free(nonce_iv_unaligned); 10690 nonce_iv_unaligned = NULL; 10691 nonce_iv_aligned = NULL; 10692 10693 fips_align_fail_nonce_iv: 10694 qdf_mem_free(data_unaligned); 10695 data_unaligned = NULL; 10696 data_aligned = NULL; 10697 10698 fips_align_fail_data: 10699 qdf_mem_free(key_unaligned); 10700 key_unaligned = NULL; 10701 key_aligned = NULL; 10702 10703 return ret; 10704 } 10705 #endif 10706 10707 /** 10708 * fips_align_data_be() - LE to BE conversion of FIPS ev data 10709 * @wmi_handle: wmi handle 10710 * @param: fips param related parameters 10711 * 10712 * Return: QDF_STATUS - success or error status 10713 */ 10714 static QDF_STATUS fips_align_data_be(wmi_unified_t wmi_handle, 10715 struct fips_params *param) 10716 { 10717 unsigned char *key_unaligned, *data_unaligned; 10718 int c; 10719 u_int8_t *key_aligned = NULL; 10720 u_int8_t *data_aligned = NULL; 10721 10722 /* Assigning unaligned space to copy the key */ 10723 key_unaligned = qdf_mem_malloc( 10724 sizeof(u_int8_t)*param->key_len + FIPS_ALIGN); 10725 data_unaligned = qdf_mem_malloc( 10726 sizeof(u_int8_t)*param->data_len + FIPS_ALIGN); 10727 10728 /* Checking if kmalloc is successful to allocate space */ 10729 if (!key_unaligned) 10730 return QDF_STATUS_SUCCESS; 10731 /* Checking if space is aligned */ 10732 if (!FIPS_IS_ALIGNED(key_unaligned, FIPS_ALIGN)) { 10733 /* align to 4 */ 10734 key_aligned = 10735 (u_int8_t *)FIPS_ALIGNTO(key_unaligned, 10736 FIPS_ALIGN); 10737 } else { 10738 key_aligned = (u_int8_t *)key_unaligned; 10739 } 10740 10741 /* memset and copy content from key to key aligned */ 10742 OS_MEMSET(key_aligned, 0, param->key_len); 10743 OS_MEMCPY(key_aligned, param->key, param->key_len); 10744 10745 /* print a hexdump for host debug */ 10746 print_hex_dump(KERN_DEBUG, 10747 "\t Aligned and Copied Key:@@@@ ", 10748 DUMP_PREFIX_NONE, 10749 16, 1, key_aligned, param->key_len, true); 10750 10751 /* Checking if kmalloc is successful to allocate space */ 10752 if (!data_unaligned) 10753 return QDF_STATUS_SUCCESS; 10754 /* Checking of space is aligned */ 10755 if (!FIPS_IS_ALIGNED(data_unaligned, FIPS_ALIGN)) { 10756 /* align to 4 */ 10757 data_aligned = 10758 (u_int8_t *)FIPS_ALIGNTO(data_unaligned, 10759 FIPS_ALIGN); 10760 } else { 10761 data_aligned = (u_int8_t *)data_unaligned; 10762 } 10763 10764 /* memset and copy content from data to data aligned */ 10765 OS_MEMSET(data_aligned, 0, param->data_len); 10766 OS_MEMCPY(data_aligned, param->data, param->data_len); 10767 10768 /* print a hexdump for host debug */ 10769 print_hex_dump(KERN_DEBUG, 10770 "\t Properly Aligned and Copied Data:@@@@ ", 10771 DUMP_PREFIX_NONE, 10772 16, 1, data_aligned, param->data_len, true); 10773 10774 /* converting to little Endian both key_aligned and 10775 * data_aligned*/ 10776 for (c = 0; c < param->key_len/4; c++) { 10777 *((u_int32_t *)key_aligned+c) = 10778 qdf_cpu_to_le32(*((u_int32_t *)key_aligned+c)); 10779 } 10780 for (c = 0; c < param->data_len/4; c++) { 10781 *((u_int32_t *)data_aligned+c) = 10782 qdf_cpu_to_le32(*((u_int32_t *)data_aligned+c)); 10783 } 10784 10785 /* update endian data to key and data vectors */ 10786 OS_MEMCPY(param->key, key_aligned, param->key_len); 10787 OS_MEMCPY(param->data, data_aligned, param->data_len); 10788 10789 /* clean up allocated spaces */ 10790 qdf_mem_free(key_unaligned); 10791 key_unaligned = NULL; 10792 key_aligned = NULL; 10793 10794 qdf_mem_free(data_unaligned); 10795 data_unaligned = NULL; 10796 data_aligned = NULL; 10797 10798 return QDF_STATUS_SUCCESS; 10799 } 10800 #else 10801 #ifdef WLAN_FEATURE_FIPS_BER_CCMGCM 10802 static QDF_STATUS fips_extend_align_data_be(wmi_unified_t wmi_handle, 10803 struct fips_extend_params *param) 10804 { 10805 return QDF_STATUS_SUCCESS; 10806 } 10807 #endif 10808 10809 static QDF_STATUS fips_align_data_be(wmi_unified_t wmi_handle, 10810 struct fips_params *param) 10811 { 10812 return QDF_STATUS_SUCCESS; 10813 } 10814 #endif 10815 10816 #ifdef WLAN_FEATURE_DISA 10817 /** 10818 * send_encrypt_decrypt_send_cmd_tlv() - send encrypt/decrypt cmd to fw 10819 * @wmi_handle: wmi handle 10820 * @encrypt_decrypt_params: encrypt/decrypt params 10821 * 10822 * Return: QDF_STATUS_SUCCESS for success or error code 10823 */ 10824 static QDF_STATUS 10825 send_encrypt_decrypt_send_cmd_tlv(wmi_unified_t wmi_handle, 10826 struct disa_encrypt_decrypt_req_params 10827 *encrypt_decrypt_params) 10828 { 10829 wmi_vdev_encrypt_decrypt_data_req_cmd_fixed_param *cmd; 10830 wmi_buf_t wmi_buf; 10831 uint8_t *buf_ptr; 10832 QDF_STATUS ret; 10833 uint32_t len; 10834 10835 wmi_debug("Send encrypt decrypt cmd"); 10836 10837 len = sizeof(*cmd) + 10838 encrypt_decrypt_params->data_len + 10839 WMI_TLV_HDR_SIZE; 10840 wmi_buf = wmi_buf_alloc(wmi_handle, len); 10841 if (!wmi_buf) 10842 return QDF_STATUS_E_NOMEM; 10843 10844 buf_ptr = wmi_buf_data(wmi_buf); 10845 cmd = (wmi_vdev_encrypt_decrypt_data_req_cmd_fixed_param *)buf_ptr; 10846 10847 WMITLV_SET_HDR(&cmd->tlv_header, 10848 WMITLV_TAG_STRUC_wmi_vdev_encrypt_decrypt_data_req_cmd_fixed_param, 10849 WMITLV_GET_STRUCT_TLVLEN( 10850 wmi_vdev_encrypt_decrypt_data_req_cmd_fixed_param)); 10851 10852 cmd->vdev_id = encrypt_decrypt_params->vdev_id; 10853 cmd->key_flag = encrypt_decrypt_params->key_flag; 10854 cmd->key_idx = encrypt_decrypt_params->key_idx; 10855 cmd->key_cipher = encrypt_decrypt_params->key_cipher; 10856 cmd->key_len = encrypt_decrypt_params->key_len; 10857 cmd->key_txmic_len = encrypt_decrypt_params->key_txmic_len; 10858 cmd->key_rxmic_len = encrypt_decrypt_params->key_rxmic_len; 10859 10860 qdf_mem_copy(cmd->key_data, encrypt_decrypt_params->key_data, 10861 encrypt_decrypt_params->key_len); 10862 10863 qdf_mem_copy(cmd->mac_hdr, encrypt_decrypt_params->mac_header, 10864 MAX_MAC_HEADER_LEN); 10865 10866 cmd->data_len = encrypt_decrypt_params->data_len; 10867 10868 if (cmd->data_len) { 10869 buf_ptr += sizeof(*cmd); 10870 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, 10871 roundup(encrypt_decrypt_params->data_len, 10872 sizeof(uint32_t))); 10873 buf_ptr += WMI_TLV_HDR_SIZE; 10874 qdf_mem_copy(buf_ptr, encrypt_decrypt_params->data, 10875 encrypt_decrypt_params->data_len); 10876 } 10877 10878 /* This conversion is to facilitate data to FW in little endian */ 10879 cmd->pn[5] = encrypt_decrypt_params->pn[0]; 10880 cmd->pn[4] = encrypt_decrypt_params->pn[1]; 10881 cmd->pn[3] = encrypt_decrypt_params->pn[2]; 10882 cmd->pn[2] = encrypt_decrypt_params->pn[3]; 10883 cmd->pn[1] = encrypt_decrypt_params->pn[4]; 10884 cmd->pn[0] = encrypt_decrypt_params->pn[5]; 10885 10886 wmi_mtrace(WMI_VDEV_ENCRYPT_DECRYPT_DATA_REQ_CMDID, cmd->vdev_id, 0); 10887 ret = wmi_unified_cmd_send(wmi_handle, 10888 wmi_buf, len, 10889 WMI_VDEV_ENCRYPT_DECRYPT_DATA_REQ_CMDID); 10890 if (QDF_IS_STATUS_ERROR(ret)) { 10891 wmi_err("Failed to send ENCRYPT DECRYPT cmd: %d", ret); 10892 wmi_buf_free(wmi_buf); 10893 } 10894 10895 return ret; 10896 } 10897 #endif /* WLAN_FEATURE_DISA */ 10898 10899 /** 10900 * send_pdev_fips_cmd_tlv() - send pdev fips cmd to fw 10901 * @wmi_handle: wmi handle 10902 * @param: pointer to hold pdev fips param 10903 * 10904 * Return: QDF_STATUS_SUCCESS for success or error code 10905 */ 10906 static QDF_STATUS 10907 send_pdev_fips_cmd_tlv(wmi_unified_t wmi_handle, 10908 struct fips_params *param) 10909 { 10910 wmi_pdev_fips_cmd_fixed_param *cmd; 10911 wmi_buf_t buf; 10912 uint8_t *buf_ptr; 10913 uint32_t len = sizeof(wmi_pdev_fips_cmd_fixed_param); 10914 QDF_STATUS retval = QDF_STATUS_SUCCESS; 10915 10916 /* Length TLV placeholder for array of bytes */ 10917 len += WMI_TLV_HDR_SIZE; 10918 if (param->data_len) 10919 len += (param->data_len*sizeof(uint8_t)); 10920 10921 /* 10922 * Data length must be multiples of 16 bytes - checked against 0xF - 10923 * and must be less than WMI_SVC_MSG_SIZE - static size of 10924 * wmi_pdev_fips_cmd structure 10925 */ 10926 10927 /* do sanity on the input */ 10928 if (!(((param->data_len & 0xF) == 0) && 10929 ((param->data_len > 0) && 10930 (param->data_len < (WMI_HOST_MAX_BUFFER_SIZE - 10931 sizeof(wmi_pdev_fips_cmd_fixed_param)))))) { 10932 return QDF_STATUS_E_INVAL; 10933 } 10934 10935 buf = wmi_buf_alloc(wmi_handle, len); 10936 if (!buf) 10937 return QDF_STATUS_E_FAILURE; 10938 10939 buf_ptr = (uint8_t *) wmi_buf_data(buf); 10940 cmd = (wmi_pdev_fips_cmd_fixed_param *)buf_ptr; 10941 WMITLV_SET_HDR(&cmd->tlv_header, 10942 WMITLV_TAG_STRUC_wmi_pdev_fips_cmd_fixed_param, 10943 WMITLV_GET_STRUCT_TLVLEN 10944 (wmi_pdev_fips_cmd_fixed_param)); 10945 10946 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 10947 wmi_handle, 10948 param->pdev_id); 10949 if (param->key && param->data) { 10950 cmd->key_len = param->key_len; 10951 cmd->data_len = param->data_len; 10952 cmd->fips_cmd = !!(param->op); 10953 10954 if (fips_align_data_be(wmi_handle, param) != QDF_STATUS_SUCCESS) 10955 return QDF_STATUS_E_FAILURE; 10956 10957 qdf_mem_copy(cmd->key, param->key, param->key_len); 10958 10959 if (param->mode == FIPS_ENGINE_AES_CTR || 10960 param->mode == FIPS_ENGINE_AES_MIC) { 10961 cmd->mode = param->mode; 10962 } else { 10963 cmd->mode = FIPS_ENGINE_AES_CTR; 10964 } 10965 10966 print_hex_dump(KERN_DEBUG, "Key: ", DUMP_PREFIX_NONE, 16, 1, 10967 cmd->key, cmd->key_len, true); 10968 buf_ptr += sizeof(*cmd); 10969 10970 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, param->data_len); 10971 10972 buf_ptr += WMI_TLV_HDR_SIZE; 10973 if (param->data_len) 10974 qdf_mem_copy(buf_ptr, 10975 (uint8_t *) param->data, param->data_len); 10976 10977 print_hex_dump(KERN_DEBUG, "Plain text: ", DUMP_PREFIX_NONE, 10978 16, 1, buf_ptr, cmd->data_len, true); 10979 10980 buf_ptr += param->data_len; 10981 10982 wmi_mtrace(WMI_PDEV_FIPS_CMDID, NO_SESSION, 0); 10983 retval = wmi_unified_cmd_send(wmi_handle, buf, len, 10984 WMI_PDEV_FIPS_CMDID); 10985 } else { 10986 qdf_print("\n%s:%d Key or Data is NULL", __func__, __LINE__); 10987 wmi_buf_free(buf); 10988 retval = -QDF_STATUS_E_BADMSG; 10989 } 10990 10991 return retval; 10992 } 10993 10994 #ifdef WLAN_FEATURE_FIPS_BER_CCMGCM 10995 /** 10996 * send_pdev_fips_extend_cmd_tlv() - send pdev fips cmd to fw 10997 * @wmi_handle: wmi handle 10998 * @param: pointer to hold pdev fips param 10999 * 11000 * Return: QDF_STATUS_SUCCESS for success or error code 11001 */ 11002 static QDF_STATUS 11003 send_pdev_fips_extend_cmd_tlv(wmi_unified_t wmi_handle, 11004 struct fips_extend_params *param) 11005 { 11006 wmi_pdev_fips_extend_cmd_fixed_param *cmd; 11007 wmi_buf_t buf; 11008 uint8_t *buf_ptr; 11009 uint32_t len = sizeof(wmi_pdev_fips_extend_cmd_fixed_param); 11010 uint32_t data_len_aligned; 11011 QDF_STATUS retval = QDF_STATUS_SUCCESS; 11012 11013 len += WMI_TLV_HDR_SIZE; 11014 if (param->frag_idx == 0) 11015 len += sizeof(wmi_fips_extend_cmd_init_params); 11016 11017 /* Length TLV placeholder for array of bytes */ 11018 len += WMI_TLV_HDR_SIZE; 11019 if (param->data_len) { 11020 data_len_aligned = roundup(param->data_len, sizeof(uint32_t)); 11021 len += (data_len_aligned * sizeof(uint8_t)); 11022 } 11023 11024 buf = wmi_buf_alloc(wmi_handle, len); 11025 if (!buf) 11026 return QDF_STATUS_E_FAILURE; 11027 11028 buf_ptr = (uint8_t *)wmi_buf_data(buf); 11029 cmd = (wmi_pdev_fips_extend_cmd_fixed_param *)buf_ptr; 11030 WMITLV_SET_HDR(&cmd->tlv_header, 11031 WMITLV_TAG_STRUC_wmi_pdev_fips_extend_cmd_fixed_param, 11032 WMITLV_GET_STRUCT_TLVLEN 11033 (wmi_pdev_fips_extend_cmd_fixed_param)); 11034 11035 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 11036 wmi_handle, 11037 param->pdev_id); 11038 11039 cmd->fips_cookie = param->cookie; 11040 cmd->frag_idx = param->frag_idx; 11041 cmd->more_bit = param->more_bit; 11042 cmd->data_len = param->data_len; 11043 11044 if (fips_extend_align_data_be(wmi_handle, param) != 11045 QDF_STATUS_SUCCESS) { 11046 wmi_buf_free(buf); 11047 return QDF_STATUS_E_FAILURE; 11048 } 11049 11050 buf_ptr = (uint8_t *)(cmd + 1); 11051 if (cmd->frag_idx == 0) { 11052 wmi_fips_extend_cmd_init_params *cmd_params; 11053 11054 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 11055 sizeof(wmi_fips_extend_cmd_init_params)); 11056 buf_ptr += WMI_TLV_HDR_SIZE; 11057 cmd_params = (wmi_fips_extend_cmd_init_params *)buf_ptr; 11058 WMITLV_SET_HDR(buf_ptr, 11059 WMITLV_TAG_STRUC_wmi_fips_extend_cmd_init_params, 11060 WMITLV_GET_STRUCT_TLVLEN(wmi_fips_extend_cmd_init_params)); 11061 cmd_params->fips_cmd = param->cmd_params.fips_cmd; 11062 cmd_params->key_cipher = param->cmd_params.key_cipher; 11063 cmd_params->key_len = param->cmd_params.key_len; 11064 cmd_params->nonce_iv_len = param->cmd_params.nonce_iv_len; 11065 cmd_params->tag_len = param->cmd_params.tag_len; 11066 cmd_params->aad_len = param->cmd_params.aad_len; 11067 cmd_params->payload_len = param->cmd_params.payload_len; 11068 11069 qdf_mem_copy(cmd_params->key, param->cmd_params.key, 11070 param->cmd_params.key_len); 11071 qdf_mem_copy(cmd_params->nonce_iv, param->cmd_params.nonce_iv, 11072 param->cmd_params.nonce_iv_len); 11073 11074 wmi_debug("Key len = %d, IVNoncelen = %d, Tlen = %d, Alen = %d, Plen = %d", 11075 cmd_params->key_len, cmd_params->nonce_iv_len, 11076 cmd_params->tag_len, cmd_params->aad_len, 11077 cmd_params->payload_len); 11078 11079 buf_ptr += sizeof(wmi_fips_extend_cmd_init_params); 11080 } else { 11081 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0); 11082 buf_ptr += WMI_TLV_HDR_SIZE; 11083 } 11084 11085 if (param->data_len && param->data) { 11086 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, 11087 data_len_aligned); 11088 11089 buf_ptr += WMI_TLV_HDR_SIZE; 11090 if (param->data_len) 11091 qdf_mem_copy(buf_ptr, 11092 (uint8_t *)param->data, param->data_len); 11093 11094 wmi_debug("Data: "); 11095 qdf_trace_hex_dump(QDF_MODULE_ID_WMI, QDF_TRACE_LEVEL_DEBUG, 11096 buf_ptr, cmd->data_len); 11097 11098 if (param->data_len) 11099 buf_ptr += param->data_len; 11100 } else { 11101 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, 0); 11102 buf_ptr += WMI_TLV_HDR_SIZE; 11103 } 11104 11105 wmi_mtrace(WMI_PDEV_FIPS_EXTEND_CMDID, NO_SESSION, 0); 11106 retval = wmi_unified_cmd_send(wmi_handle, buf, len, 11107 WMI_PDEV_FIPS_EXTEND_CMDID); 11108 11109 if (retval) { 11110 wmi_err("Failed to send FIPS cmd"); 11111 wmi_buf_free(buf); 11112 } 11113 11114 return retval; 11115 } 11116 11117 /** 11118 * send_pdev_fips_mode_set_cmd_tlv() - send pdev fips cmd to fw 11119 * @wmi_handle: wmi handle 11120 * @param: pointer to hold pdev fips param 11121 * 11122 * Return: QDF_STATUS_SUCCESS for success or error code 11123 */ 11124 static QDF_STATUS 11125 send_pdev_fips_mode_set_cmd_tlv(wmi_unified_t wmi_handle, 11126 struct fips_mode_set_params *param) 11127 { 11128 wmi_pdev_fips_mode_set_cmd_fixed_param *cmd; 11129 wmi_buf_t buf; 11130 uint8_t *buf_ptr; 11131 uint32_t len = sizeof(wmi_pdev_fips_mode_set_cmd_fixed_param); 11132 QDF_STATUS retval = QDF_STATUS_SUCCESS; 11133 11134 buf = wmi_buf_alloc(wmi_handle, len); 11135 if (!buf) 11136 return QDF_STATUS_E_FAILURE; 11137 11138 buf_ptr = (uint8_t *)wmi_buf_data(buf); 11139 cmd = (wmi_pdev_fips_mode_set_cmd_fixed_param *)buf_ptr; 11140 WMITLV_SET_HDR(&cmd->tlv_header, 11141 WMITLV_TAG_STRUC_wmi_pdev_fips_mode_set_cmd_fixed_param, 11142 WMITLV_GET_STRUCT_TLVLEN 11143 (wmi_pdev_fips_mode_set_cmd_fixed_param)); 11144 11145 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 11146 wmi_handle, 11147 param->pdev_id); 11148 11149 cmd->fips_mode_set = param->mode; 11150 wmi_mtrace(WMI_PDEV_FIPS_MODE_SET_CMDID, NO_SESSION, 0); 11151 retval = wmi_unified_cmd_send(wmi_handle, buf, len, 11152 WMI_PDEV_FIPS_MODE_SET_CMDID); 11153 if (retval) { 11154 wmi_err("Failed to send FIPS mode enable cmd"); 11155 wmi_buf_free(buf); 11156 } 11157 return retval; 11158 } 11159 #endif 11160 11161 /** 11162 * send_wlan_profile_enable_cmd_tlv() - send wlan profile enable command 11163 * to fw 11164 * @wmi_handle: wmi handle 11165 * @param: pointer to wlan profile param 11166 * 11167 * Return: QDF_STATUS_SUCCESS for success or error code 11168 */ 11169 static QDF_STATUS 11170 send_wlan_profile_enable_cmd_tlv(wmi_unified_t wmi_handle, 11171 struct wlan_profile_params *param) 11172 { 11173 wmi_buf_t buf; 11174 uint16_t len; 11175 QDF_STATUS ret; 11176 wmi_wlan_profile_enable_profile_id_cmd_fixed_param *profile_enable_cmd; 11177 11178 len = sizeof(wmi_wlan_profile_enable_profile_id_cmd_fixed_param); 11179 buf = wmi_buf_alloc(wmi_handle, len); 11180 if (!buf) { 11181 wmi_err("Failed to send WMI_WLAN_PROFILE_ENABLE_PROFILE_ID_CMDID"); 11182 return QDF_STATUS_E_NOMEM; 11183 } 11184 11185 profile_enable_cmd = 11186 (wmi_wlan_profile_enable_profile_id_cmd_fixed_param *) 11187 wmi_buf_data(buf); 11188 WMITLV_SET_HDR(&profile_enable_cmd->tlv_header, 11189 WMITLV_TAG_STRUC_wmi_wlan_profile_enable_profile_id_cmd_fixed_param, 11190 WMITLV_GET_STRUCT_TLVLEN 11191 (wmi_wlan_profile_enable_profile_id_cmd_fixed_param)); 11192 11193 profile_enable_cmd->profile_id = param->profile_id; 11194 profile_enable_cmd->enable = param->enable; 11195 wmi_mtrace(WMI_WLAN_PROFILE_ENABLE_PROFILE_ID_CMDID, 11196 NO_SESSION, 0); 11197 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 11198 WMI_WLAN_PROFILE_ENABLE_PROFILE_ID_CMDID); 11199 if (ret) { 11200 wmi_err("Failed to send PROFILE_ENABLE_PROFILE_ID_CMDID"); 11201 wmi_buf_free(buf); 11202 } 11203 return ret; 11204 } 11205 11206 /** 11207 * send_wlan_profile_trigger_cmd_tlv() - send wlan profile trigger command 11208 * to fw 11209 * @wmi_handle: wmi handle 11210 * @param: pointer to wlan profile param 11211 * 11212 * Return: QDF_STATUS_SUCCESS for success or error code 11213 */ 11214 static QDF_STATUS 11215 send_wlan_profile_trigger_cmd_tlv(wmi_unified_t wmi_handle, 11216 struct wlan_profile_params *param) 11217 { 11218 wmi_buf_t buf; 11219 uint16_t len; 11220 QDF_STATUS ret; 11221 wmi_wlan_profile_trigger_cmd_fixed_param *prof_trig_cmd; 11222 11223 len = sizeof(wmi_wlan_profile_trigger_cmd_fixed_param); 11224 buf = wmi_buf_alloc(wmi_handle, len); 11225 if (!buf) { 11226 wmi_err("Failed to send WMI_WLAN_PROFILE_TRIGGER_CMDID"); 11227 return QDF_STATUS_E_NOMEM; 11228 } 11229 11230 prof_trig_cmd = 11231 (wmi_wlan_profile_trigger_cmd_fixed_param *) 11232 wmi_buf_data(buf); 11233 11234 WMITLV_SET_HDR(&prof_trig_cmd->tlv_header, 11235 WMITLV_TAG_STRUC_wmi_wlan_profile_trigger_cmd_fixed_param, 11236 WMITLV_GET_STRUCT_TLVLEN 11237 (wmi_wlan_profile_trigger_cmd_fixed_param)); 11238 11239 prof_trig_cmd->enable = param->enable; 11240 wmi_mtrace(WMI_WLAN_PROFILE_TRIGGER_CMDID, NO_SESSION, 0); 11241 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 11242 WMI_WLAN_PROFILE_TRIGGER_CMDID); 11243 if (ret) { 11244 wmi_err("Failed to send WMI_WLAN_PROFILE_TRIGGER_CMDID"); 11245 wmi_buf_free(buf); 11246 } 11247 return ret; 11248 } 11249 11250 /** 11251 * send_wlan_profile_hist_intvl_cmd_tlv() - send wlan profile interval command 11252 * to fw 11253 * @wmi_handle: wmi handle 11254 * @param: pointer to wlan profile param 11255 * 11256 * Return: QDF_STATUS_SUCCESS for success or error code 11257 */ 11258 static QDF_STATUS 11259 send_wlan_profile_hist_intvl_cmd_tlv(wmi_unified_t wmi_handle, 11260 struct wlan_profile_params *param) 11261 { 11262 wmi_buf_t buf; 11263 int32_t len = 0; 11264 QDF_STATUS ret; 11265 wmi_wlan_profile_set_hist_intvl_cmd_fixed_param *hist_intvl_cmd; 11266 11267 len = sizeof(wmi_wlan_profile_set_hist_intvl_cmd_fixed_param); 11268 buf = wmi_buf_alloc(wmi_handle, len); 11269 if (!buf) { 11270 wmi_err("Failed to send WMI_WLAN_PROFILE_SET_HIST_INTVL_CMDID"); 11271 return QDF_STATUS_E_NOMEM; 11272 } 11273 11274 hist_intvl_cmd = 11275 (wmi_wlan_profile_set_hist_intvl_cmd_fixed_param *) 11276 wmi_buf_data(buf); 11277 11278 WMITLV_SET_HDR(&hist_intvl_cmd->tlv_header, 11279 WMITLV_TAG_STRUC_wmi_wlan_profile_set_hist_intvl_cmd_fixed_param, 11280 WMITLV_GET_STRUCT_TLVLEN 11281 (wmi_wlan_profile_set_hist_intvl_cmd_fixed_param)); 11282 11283 hist_intvl_cmd->profile_id = param->profile_id; 11284 hist_intvl_cmd->value = param->enable; 11285 wmi_mtrace(WMI_WLAN_PROFILE_SET_HIST_INTVL_CMDID, 11286 NO_SESSION, 0); 11287 11288 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 11289 WMI_WLAN_PROFILE_SET_HIST_INTVL_CMDID); 11290 if (ret) { 11291 wmi_err("Failed to send PROFILE_SET_HIST_INTVL_CMDID"); 11292 wmi_buf_free(buf); 11293 } 11294 return ret; 11295 } 11296 11297 /** 11298 * send_fw_test_cmd_tlv() - send fw test command to fw. 11299 * @wmi_handle: wmi handle 11300 * @wmi_fwtest: fw test command 11301 * 11302 * This function sends fw test command to fw. 11303 * 11304 * Return: CDF STATUS 11305 */ 11306 static 11307 QDF_STATUS send_fw_test_cmd_tlv(wmi_unified_t wmi_handle, 11308 struct set_fwtest_params *wmi_fwtest) 11309 { 11310 wmi_fwtest_set_param_cmd_fixed_param *cmd; 11311 wmi_buf_t wmi_buf; 11312 uint16_t len; 11313 11314 len = sizeof(*cmd); 11315 11316 wmi_buf = wmi_buf_alloc(wmi_handle, len); 11317 if (!wmi_buf) 11318 return QDF_STATUS_E_NOMEM; 11319 11320 cmd = (wmi_fwtest_set_param_cmd_fixed_param *) wmi_buf_data(wmi_buf); 11321 WMITLV_SET_HDR(&cmd->tlv_header, 11322 WMITLV_TAG_STRUC_wmi_fwtest_set_param_cmd_fixed_param, 11323 WMITLV_GET_STRUCT_TLVLEN( 11324 wmi_fwtest_set_param_cmd_fixed_param)); 11325 cmd->param_id = wmi_fwtest->arg; 11326 cmd->param_value = wmi_fwtest->value; 11327 11328 wmi_mtrace(WMI_FWTEST_CMDID, NO_SESSION, 0); 11329 if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len, 11330 WMI_FWTEST_CMDID)) { 11331 wmi_err("Failed to send fw test command"); 11332 wmi_buf_free(wmi_buf); 11333 return QDF_STATUS_E_FAILURE; 11334 } 11335 11336 return QDF_STATUS_SUCCESS; 11337 } 11338 11339 static uint16_t wfa_config_param_len(enum wfa_test_cmds config) 11340 { 11341 uint16_t len = 0; 11342 11343 if (config == WFA_CONFIG_RXNE) 11344 len += WMI_TLV_HDR_SIZE + sizeof(wmi_wfa_config_rsnxe); 11345 else 11346 len += WMI_TLV_HDR_SIZE; 11347 11348 if (config == WFA_CONFIG_CSA) 11349 len += WMI_TLV_HDR_SIZE + sizeof(wmi_wfa_config_csa); 11350 else 11351 len += WMI_TLV_HDR_SIZE; 11352 11353 if (config == WFA_CONFIG_OCV) 11354 len += WMI_TLV_HDR_SIZE + sizeof(wmi_wfa_config_ocv); 11355 else 11356 len += WMI_TLV_HDR_SIZE; 11357 11358 if (config == WFA_CONFIG_SA_QUERY) 11359 len += WMI_TLV_HDR_SIZE + sizeof(wmi_wfa_config_saquery); 11360 else 11361 len += WMI_TLV_HDR_SIZE; 11362 11363 return len; 11364 } 11365 11366 /** 11367 * wmi_fill_ocv_frame_type() - Fill host ocv frm type into WMI ocv frm type. 11368 * @host_frmtype: Host defined OCV frame type 11369 * @ocv_frmtype: Pointer to hold WMI OCV frame type 11370 * 11371 * This function converts and fills host defined OCV frame type into WMI OCV 11372 * frame type. 11373 * 11374 * Return: CDF STATUS 11375 */ 11376 static QDF_STATUS 11377 wmi_fill_ocv_frame_type(uint32_t host_frmtype, uint32_t *ocv_frmtype) 11378 { 11379 switch (host_frmtype) { 11380 case WMI_HOST_WFA_CONFIG_OCV_FRMTYPE_SAQUERY_REQ: 11381 *ocv_frmtype = WMI_WFA_CONFIG_OCV_FRMTYPE_SAQUERY_REQ; 11382 break; 11383 11384 case WMI_HOST_WFA_CONFIG_OCV_FRMTYPE_SAQUERY_RSP: 11385 *ocv_frmtype = WMI_WFA_CONFIG_OCV_FRMTYPE_SAQUERY_RSP; 11386 break; 11387 11388 case WMI_HOST_WFA_CONFIG_OCV_FRMTYPE_FT_REASSOC_REQ: 11389 *ocv_frmtype = WMI_WFA_CONFIG_OCV_FRMTYPE_FT_REASSOC_REQ; 11390 break; 11391 11392 case WMI_HOST_WFA_CONFIG_OCV_FRMTYPE_FILS_REASSOC_REQ: 11393 *ocv_frmtype = WMI_WFA_CONFIG_OCV_FRMTYPE_FILS_REASSOC_REQ; 11394 break; 11395 11396 default: 11397 wmi_err("Invalid command type cmd %d", host_frmtype); 11398 return QDF_STATUS_E_FAILURE; 11399 } 11400 11401 return QDF_STATUS_SUCCESS; 11402 } 11403 11404 /** 11405 * send_wfa_test_cmd_tlv() - send wfa test command to fw. 11406 * @wmi_handle: wmi handle 11407 * @wmi_wfatest: wfa test command 11408 * 11409 * This function sends wfa test command to fw. 11410 * 11411 * Return: CDF STATUS 11412 */ 11413 static 11414 QDF_STATUS send_wfa_test_cmd_tlv(wmi_unified_t wmi_handle, 11415 struct set_wfatest_params *wmi_wfatest) 11416 { 11417 wmi_wfa_config_cmd_fixed_param *cmd; 11418 wmi_wfa_config_rsnxe *rxne; 11419 wmi_wfa_config_csa *csa; 11420 wmi_wfa_config_ocv *ocv; 11421 wmi_wfa_config_saquery *saquery; 11422 wmi_buf_t wmi_buf; 11423 uint16_t len = sizeof(*cmd); 11424 uint8_t *buf_ptr; 11425 11426 len += wfa_config_param_len(wmi_wfatest->cmd); 11427 wmi_buf = wmi_buf_alloc(wmi_handle, len); 11428 if (!wmi_buf) 11429 return QDF_STATUS_E_NOMEM; 11430 11431 cmd = (wmi_wfa_config_cmd_fixed_param *)wmi_buf_data(wmi_buf); 11432 WMITLV_SET_HDR(&cmd->tlv_header, 11433 WMITLV_TAG_STRUC_wmi_wfa_config_cmd_fixed_param, 11434 WMITLV_GET_STRUCT_TLVLEN( 11435 wmi_wfa_config_cmd_fixed_param)); 11436 11437 cmd->vdev_id = wmi_wfatest->vdev_id; 11438 buf_ptr = (uint8_t *)(cmd + 1); 11439 11440 if (wmi_wfatest->cmd == WFA_CONFIG_RXNE) { 11441 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 11442 sizeof(wmi_wfa_config_rsnxe)); 11443 buf_ptr += WMI_TLV_HDR_SIZE; 11444 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_STRUC_wmi_wfa_config_rsnxe, 11445 WMITLV_GET_STRUCT_TLVLEN(wmi_wfa_config_rsnxe)); 11446 rxne = (wmi_wfa_config_rsnxe *)buf_ptr; 11447 rxne->rsnxe_param = wmi_wfatest->value; 11448 buf_ptr += sizeof(wmi_wfa_config_rsnxe); 11449 } else { 11450 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0); 11451 buf_ptr += WMI_TLV_HDR_SIZE; 11452 } 11453 11454 if (wmi_wfatest->cmd == WFA_CONFIG_CSA) { 11455 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 11456 sizeof(wmi_wfa_config_csa)); 11457 buf_ptr += WMI_TLV_HDR_SIZE; 11458 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_STRUC_wmi_wfa_config_csa, 11459 WMITLV_GET_STRUCT_TLVLEN(wmi_wfa_config_csa)); 11460 csa = (wmi_wfa_config_csa *)buf_ptr; 11461 csa->ignore_csa = wmi_wfatest->value; 11462 buf_ptr += sizeof(wmi_wfa_config_csa); 11463 } else { 11464 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0); 11465 buf_ptr += WMI_TLV_HDR_SIZE; 11466 } 11467 11468 if (wmi_wfatest->cmd == WFA_CONFIG_OCV) { 11469 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 11470 sizeof(wmi_wfa_config_ocv)); 11471 buf_ptr += WMI_TLV_HDR_SIZE; 11472 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_STRUC_wmi_wfa_config_ocv, 11473 WMITLV_GET_STRUCT_TLVLEN(wmi_wfa_config_ocv)); 11474 ocv = (wmi_wfa_config_ocv *)buf_ptr; 11475 11476 if (wmi_fill_ocv_frame_type(wmi_wfatest->ocv_param->frame_type, 11477 &ocv->frame_types)) 11478 goto error; 11479 11480 ocv->chan_freq = wmi_wfatest->ocv_param->freq; 11481 buf_ptr += sizeof(wmi_wfa_config_ocv); 11482 } else { 11483 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0); 11484 buf_ptr += WMI_TLV_HDR_SIZE; 11485 } 11486 11487 if (wmi_wfatest->cmd == WFA_CONFIG_SA_QUERY) { 11488 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 11489 sizeof(wmi_wfa_config_saquery)); 11490 buf_ptr += WMI_TLV_HDR_SIZE; 11491 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_STRUC_wmi_wfa_config_saquery, 11492 WMITLV_GET_STRUCT_TLVLEN(wmi_wfa_config_saquery)); 11493 11494 saquery = (wmi_wfa_config_saquery *)buf_ptr; 11495 saquery->remain_connect_on_saquery_timeout = wmi_wfatest->value; 11496 } else { 11497 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0); 11498 buf_ptr += WMI_TLV_HDR_SIZE; 11499 } 11500 11501 wmi_mtrace(WMI_WFA_CONFIG_CMDID, wmi_wfatest->vdev_id, 0); 11502 if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len, 11503 WMI_WFA_CONFIG_CMDID)) { 11504 wmi_err("Failed to send wfa test command"); 11505 goto error; 11506 } 11507 11508 return QDF_STATUS_SUCCESS; 11509 11510 error: 11511 wmi_buf_free(wmi_buf); 11512 return QDF_STATUS_E_FAILURE; 11513 } 11514 11515 /** 11516 * send_unit_test_cmd_tlv() - send unit test command to fw. 11517 * @wmi_handle: wmi handle 11518 * @wmi_utest: unit test command 11519 * 11520 * This function send unit test command to fw. 11521 * 11522 * Return: CDF STATUS 11523 */ 11524 static QDF_STATUS send_unit_test_cmd_tlv(wmi_unified_t wmi_handle, 11525 struct wmi_unit_test_cmd *wmi_utest) 11526 { 11527 wmi_unit_test_cmd_fixed_param *cmd; 11528 wmi_buf_t wmi_buf; 11529 uint8_t *buf_ptr; 11530 int i; 11531 uint16_t len, args_tlv_len; 11532 uint32_t *unit_test_cmd_args; 11533 11534 args_tlv_len = 11535 WMI_TLV_HDR_SIZE + wmi_utest->num_args * sizeof(uint32_t); 11536 len = sizeof(wmi_unit_test_cmd_fixed_param) + args_tlv_len; 11537 11538 wmi_buf = wmi_buf_alloc(wmi_handle, len); 11539 if (!wmi_buf) 11540 return QDF_STATUS_E_NOMEM; 11541 11542 cmd = (wmi_unit_test_cmd_fixed_param *) wmi_buf_data(wmi_buf); 11543 buf_ptr = (uint8_t *) cmd; 11544 WMITLV_SET_HDR(&cmd->tlv_header, 11545 WMITLV_TAG_STRUC_wmi_unit_test_cmd_fixed_param, 11546 WMITLV_GET_STRUCT_TLVLEN(wmi_unit_test_cmd_fixed_param)); 11547 cmd->vdev_id = wmi_utest->vdev_id; 11548 cmd->module_id = wmi_utest->module_id; 11549 cmd->num_args = wmi_utest->num_args; 11550 cmd->diag_token = wmi_utest->diag_token; 11551 buf_ptr += sizeof(wmi_unit_test_cmd_fixed_param); 11552 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, 11553 (wmi_utest->num_args * sizeof(uint32_t))); 11554 unit_test_cmd_args = (uint32_t *) (buf_ptr + WMI_TLV_HDR_SIZE); 11555 wmi_debug("VDEV ID: %d MODULE ID: %d TOKEN: %d", 11556 cmd->vdev_id, cmd->module_id, cmd->diag_token); 11557 wmi_debug("%d num of args = ", wmi_utest->num_args); 11558 for (i = 0; (i < wmi_utest->num_args && i < WMI_UNIT_TEST_MAX_NUM_ARGS); i++) { 11559 unit_test_cmd_args[i] = wmi_utest->args[i]; 11560 wmi_debug("%d,", wmi_utest->args[i]); 11561 } 11562 wmi_mtrace(WMI_UNIT_TEST_CMDID, cmd->vdev_id, 0); 11563 if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len, 11564 WMI_UNIT_TEST_CMDID)) { 11565 wmi_err("Failed to send unit test command"); 11566 wmi_buf_free(wmi_buf); 11567 return QDF_STATUS_E_FAILURE; 11568 } 11569 11570 return QDF_STATUS_SUCCESS; 11571 } 11572 11573 /** 11574 * send_power_dbg_cmd_tlv() - send power debug commands 11575 * @wmi_handle: wmi handle 11576 * @param: wmi power debug parameter 11577 * 11578 * Send WMI_POWER_DEBUG_CMDID parameters to fw. 11579 * 11580 * Return: QDF_STATUS_SUCCESS on success, QDF_STATUS_E_** on error 11581 */ 11582 static QDF_STATUS send_power_dbg_cmd_tlv(wmi_unified_t wmi_handle, 11583 struct wmi_power_dbg_params *param) 11584 { 11585 wmi_buf_t buf = NULL; 11586 QDF_STATUS status; 11587 int len, args_tlv_len; 11588 uint8_t *buf_ptr; 11589 uint8_t i; 11590 wmi_pdev_wal_power_debug_cmd_fixed_param *cmd; 11591 uint32_t *cmd_args; 11592 11593 /* Prepare and send power debug cmd parameters */ 11594 args_tlv_len = WMI_TLV_HDR_SIZE + param->num_args * sizeof(uint32_t); 11595 len = sizeof(*cmd) + args_tlv_len; 11596 buf = wmi_buf_alloc(wmi_handle, len); 11597 if (!buf) 11598 return QDF_STATUS_E_NOMEM; 11599 11600 buf_ptr = (uint8_t *) wmi_buf_data(buf); 11601 cmd = (wmi_pdev_wal_power_debug_cmd_fixed_param *) buf_ptr; 11602 WMITLV_SET_HDR(&cmd->tlv_header, 11603 WMITLV_TAG_STRUC_wmi_pdev_wal_power_debug_cmd_fixed_param, 11604 WMITLV_GET_STRUCT_TLVLEN 11605 (wmi_pdev_wal_power_debug_cmd_fixed_param)); 11606 11607 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 11608 wmi_handle, 11609 param->pdev_id); 11610 cmd->module_id = param->module_id; 11611 cmd->num_args = param->num_args; 11612 buf_ptr += sizeof(*cmd); 11613 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, 11614 (param->num_args * sizeof(uint32_t))); 11615 cmd_args = (uint32_t *) (buf_ptr + WMI_TLV_HDR_SIZE); 11616 wmi_debug("%d num of args = ", param->num_args); 11617 for (i = 0; (i < param->num_args && i < WMI_MAX_POWER_DBG_ARGS); i++) { 11618 cmd_args[i] = param->args[i]; 11619 wmi_debug("%d,", param->args[i]); 11620 } 11621 11622 wmi_mtrace(WMI_PDEV_WAL_POWER_DEBUG_CMDID, NO_SESSION, 0); 11623 status = wmi_unified_cmd_send(wmi_handle, buf, 11624 len, WMI_PDEV_WAL_POWER_DEBUG_CMDID); 11625 if (QDF_IS_STATUS_ERROR(status)) { 11626 wmi_err("wmi_unified_cmd_send WMI_PDEV_WAL_POWER_DEBUG_CMDID returned Error %d", 11627 status); 11628 goto error; 11629 } 11630 11631 return QDF_STATUS_SUCCESS; 11632 error: 11633 wmi_buf_free(buf); 11634 11635 return status; 11636 } 11637 11638 /** 11639 * send_dfs_phyerr_offload_en_cmd_tlv() - send dfs phyerr offload enable cmd 11640 * @wmi_handle: wmi handle 11641 * @pdev_id: pdev id 11642 * 11643 * Send WMI_PDEV_DFS_PHYERR_OFFLOAD_ENABLE_CMDID command to firmware. 11644 * 11645 * Return: QDF_STATUS_SUCCESS on success, QDF_STATUS_E_** on error 11646 */ 11647 static QDF_STATUS send_dfs_phyerr_offload_en_cmd_tlv(wmi_unified_t wmi_handle, 11648 uint32_t pdev_id) 11649 { 11650 wmi_pdev_dfs_phyerr_offload_enable_cmd_fixed_param *cmd; 11651 wmi_buf_t buf; 11652 uint16_t len; 11653 QDF_STATUS ret; 11654 11655 len = sizeof(*cmd); 11656 buf = wmi_buf_alloc(wmi_handle, len); 11657 11658 wmi_debug("pdev_id=%d", pdev_id); 11659 11660 if (!buf) 11661 return QDF_STATUS_E_NOMEM; 11662 11663 cmd = (wmi_pdev_dfs_phyerr_offload_enable_cmd_fixed_param *) 11664 wmi_buf_data(buf); 11665 11666 WMITLV_SET_HDR(&cmd->tlv_header, 11667 WMITLV_TAG_STRUC_wmi_pdev_dfs_phyerr_offload_enable_cmd_fixed_param, 11668 WMITLV_GET_STRUCT_TLVLEN( 11669 wmi_pdev_dfs_phyerr_offload_enable_cmd_fixed_param)); 11670 11671 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 11672 wmi_handle, 11673 pdev_id); 11674 wmi_mtrace(WMI_PDEV_DFS_PHYERR_OFFLOAD_ENABLE_CMDID, NO_SESSION, 0); 11675 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 11676 WMI_PDEV_DFS_PHYERR_OFFLOAD_ENABLE_CMDID); 11677 if (QDF_IS_STATUS_ERROR(ret)) { 11678 wmi_err("Failed to send cmd to fw, ret=%d, pdev_id=%d", 11679 ret, pdev_id); 11680 wmi_buf_free(buf); 11681 return QDF_STATUS_E_FAILURE; 11682 } 11683 11684 return QDF_STATUS_SUCCESS; 11685 } 11686 11687 /** 11688 * send_dfs_phyerr_offload_dis_cmd_tlv() - send dfs phyerr offload disable cmd 11689 * @wmi_handle: wmi handle 11690 * @pdev_id: pdev id 11691 * 11692 * Send WMI_PDEV_DFS_PHYERR_OFFLOAD_DISABLE_CMDID command to firmware. 11693 * 11694 * Return: QDF_STATUS_SUCCESS on success, QDF_STATUS_E_** on error 11695 */ 11696 static QDF_STATUS send_dfs_phyerr_offload_dis_cmd_tlv(wmi_unified_t wmi_handle, 11697 uint32_t pdev_id) 11698 { 11699 wmi_pdev_dfs_phyerr_offload_disable_cmd_fixed_param *cmd; 11700 wmi_buf_t buf; 11701 uint16_t len; 11702 QDF_STATUS ret; 11703 11704 len = sizeof(*cmd); 11705 buf = wmi_buf_alloc(wmi_handle, len); 11706 11707 wmi_debug("pdev_id=%d", pdev_id); 11708 11709 if (!buf) 11710 return QDF_STATUS_E_NOMEM; 11711 11712 cmd = (wmi_pdev_dfs_phyerr_offload_disable_cmd_fixed_param *) 11713 wmi_buf_data(buf); 11714 11715 WMITLV_SET_HDR(&cmd->tlv_header, 11716 WMITLV_TAG_STRUC_wmi_pdev_dfs_phyerr_offload_disable_cmd_fixed_param, 11717 WMITLV_GET_STRUCT_TLVLEN( 11718 wmi_pdev_dfs_phyerr_offload_disable_cmd_fixed_param)); 11719 11720 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 11721 wmi_handle, 11722 pdev_id); 11723 wmi_mtrace(WMI_PDEV_DFS_PHYERR_OFFLOAD_DISABLE_CMDID, NO_SESSION, 0); 11724 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 11725 WMI_PDEV_DFS_PHYERR_OFFLOAD_DISABLE_CMDID); 11726 if (QDF_IS_STATUS_ERROR(ret)) { 11727 wmi_err("Failed to send cmd to fw, ret=%d, pdev_id=%d", 11728 ret, pdev_id); 11729 wmi_buf_free(buf); 11730 return QDF_STATUS_E_FAILURE; 11731 } 11732 11733 return QDF_STATUS_SUCCESS; 11734 } 11735 11736 #ifdef QCA_SUPPORT_AGILE_DFS 11737 static 11738 QDF_STATUS send_adfs_ch_cfg_cmd_tlv(wmi_unified_t wmi_handle, 11739 struct vdev_adfs_ch_cfg_params *param) 11740 { 11741 /* wmi_unified_cmd_send set request of agile ADFS channel*/ 11742 wmi_vdev_adfs_ch_cfg_cmd_fixed_param *cmd; 11743 wmi_buf_t buf; 11744 QDF_STATUS ret; 11745 uint16_t len; 11746 11747 len = sizeof(*cmd); 11748 buf = wmi_buf_alloc(wmi_handle, len); 11749 11750 if (!buf) { 11751 wmi_err("wmi_buf_alloc failed"); 11752 return QDF_STATUS_E_NOMEM; 11753 } 11754 11755 cmd = (wmi_vdev_adfs_ch_cfg_cmd_fixed_param *) 11756 wmi_buf_data(buf); 11757 11758 WMITLV_SET_HDR(&cmd->tlv_header, 11759 WMITLV_TAG_STRUC_wmi_vdev_adfs_ch_cfg_cmd_fixed_param, 11760 WMITLV_GET_STRUCT_TLVLEN 11761 (wmi_vdev_adfs_ch_cfg_cmd_fixed_param)); 11762 11763 cmd->vdev_id = param->vdev_id; 11764 cmd->ocac_mode = param->ocac_mode; 11765 cmd->center_freq1 = param->center_freq1; 11766 cmd->center_freq2 = param->center_freq2; 11767 cmd->chan_freq = param->chan_freq; 11768 cmd->chan_width = param->chan_width; 11769 cmd->min_duration_ms = param->min_duration_ms; 11770 cmd->max_duration_ms = param->max_duration_ms; 11771 wmi_debug("cmd->vdev_id: %d ,cmd->ocac_mode: %d cmd->center_freq: %d", 11772 cmd->vdev_id, cmd->ocac_mode, 11773 cmd->center_freq); 11774 11775 wmi_mtrace(WMI_VDEV_ADFS_CH_CFG_CMDID, NO_SESSION, 0); 11776 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 11777 WMI_VDEV_ADFS_CH_CFG_CMDID); 11778 11779 if (QDF_IS_STATUS_ERROR(ret)) { 11780 wmi_err("Failed to send cmd to fw, ret=%d", ret); 11781 wmi_buf_free(buf); 11782 return QDF_STATUS_E_FAILURE; 11783 } 11784 11785 return QDF_STATUS_SUCCESS; 11786 } 11787 11788 static 11789 QDF_STATUS send_adfs_ocac_abort_cmd_tlv(wmi_unified_t wmi_handle, 11790 struct vdev_adfs_abort_params *param) 11791 { 11792 /*wmi_unified_cmd_send with ocac abort on ADFS channel*/ 11793 wmi_vdev_adfs_ocac_abort_cmd_fixed_param *cmd; 11794 wmi_buf_t buf; 11795 QDF_STATUS ret; 11796 uint16_t len; 11797 11798 len = sizeof(*cmd); 11799 buf = wmi_buf_alloc(wmi_handle, len); 11800 11801 if (!buf) { 11802 wmi_err("wmi_buf_alloc failed"); 11803 return QDF_STATUS_E_NOMEM; 11804 } 11805 11806 cmd = (wmi_vdev_adfs_ocac_abort_cmd_fixed_param *) 11807 wmi_buf_data(buf); 11808 11809 WMITLV_SET_HDR 11810 (&cmd->tlv_header, 11811 WMITLV_TAG_STRUC_wmi_vdev_adfs_ocac_abort_cmd_fixed_param, 11812 WMITLV_GET_STRUCT_TLVLEN 11813 (wmi_vdev_adfs_ocac_abort_cmd_fixed_param)); 11814 11815 cmd->vdev_id = param->vdev_id; 11816 11817 wmi_mtrace(WMI_VDEV_ADFS_OCAC_ABORT_CMDID, NO_SESSION, 0); 11818 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 11819 WMI_VDEV_ADFS_OCAC_ABORT_CMDID); 11820 11821 if (QDF_IS_STATUS_ERROR(ret)) { 11822 wmi_err("Failed to send cmd to fw, ret=%d", ret); 11823 wmi_buf_free(buf); 11824 return QDF_STATUS_E_FAILURE; 11825 } 11826 11827 return QDF_STATUS_SUCCESS; 11828 } 11829 #endif 11830 11831 /** 11832 * init_cmd_send_tlv() - send initialization cmd to fw 11833 * @wmi_handle: wmi handle 11834 * @param: pointer to wmi init param 11835 * 11836 * Return: QDF_STATUS_SUCCESS for success or error code 11837 */ 11838 static QDF_STATUS init_cmd_send_tlv(wmi_unified_t wmi_handle, 11839 struct wmi_init_cmd_param *param) 11840 { 11841 wmi_buf_t buf; 11842 wmi_init_cmd_fixed_param *cmd; 11843 uint8_t *buf_ptr; 11844 wmi_resource_config *resource_cfg; 11845 wlan_host_memory_chunk *host_mem_chunks; 11846 uint32_t mem_chunk_len = 0, hw_mode_len = 0; 11847 uint16_t idx; 11848 int len; 11849 QDF_STATUS ret; 11850 11851 len = sizeof(*cmd) + sizeof(wmi_resource_config) + 11852 WMI_TLV_HDR_SIZE; 11853 mem_chunk_len = (sizeof(wlan_host_memory_chunk) * MAX_MEM_CHUNKS); 11854 11855 if (param->hw_mode_id != WMI_HOST_HW_MODE_MAX) 11856 hw_mode_len = sizeof(wmi_pdev_set_hw_mode_cmd_fixed_param) + 11857 WMI_TLV_HDR_SIZE + 11858 (param->num_band_to_mac * sizeof(wmi_pdev_band_to_mac)); 11859 11860 buf = wmi_buf_alloc(wmi_handle, len + mem_chunk_len + hw_mode_len); 11861 if (!buf) 11862 return QDF_STATUS_E_FAILURE; 11863 11864 buf_ptr = (uint8_t *) wmi_buf_data(buf); 11865 cmd = (wmi_init_cmd_fixed_param *) buf_ptr; 11866 resource_cfg = (wmi_resource_config *) (buf_ptr + sizeof(*cmd)); 11867 11868 host_mem_chunks = (wlan_host_memory_chunk *) 11869 (buf_ptr + sizeof(*cmd) + sizeof(wmi_resource_config) 11870 + WMI_TLV_HDR_SIZE); 11871 11872 WMITLV_SET_HDR(&cmd->tlv_header, 11873 WMITLV_TAG_STRUC_wmi_init_cmd_fixed_param, 11874 WMITLV_GET_STRUCT_TLVLEN(wmi_init_cmd_fixed_param)); 11875 wmi_copy_resource_config(resource_cfg, param->res_cfg); 11876 WMITLV_SET_HDR(&resource_cfg->tlv_header, 11877 WMITLV_TAG_STRUC_wmi_resource_config, 11878 WMITLV_GET_STRUCT_TLVLEN(wmi_resource_config)); 11879 11880 for (idx = 0; idx < param->num_mem_chunks; ++idx) { 11881 WMITLV_SET_HDR(&(host_mem_chunks[idx].tlv_header), 11882 WMITLV_TAG_STRUC_wlan_host_memory_chunk, 11883 WMITLV_GET_STRUCT_TLVLEN 11884 (wlan_host_memory_chunk)); 11885 host_mem_chunks[idx].ptr = param->mem_chunks[idx].paddr; 11886 host_mem_chunks[idx].size = param->mem_chunks[idx].len; 11887 host_mem_chunks[idx].req_id = param->mem_chunks[idx].req_id; 11888 if (is_service_enabled_tlv(wmi_handle, 11889 WMI_SERVICE_SUPPORT_EXTEND_ADDRESS)) 11890 host_mem_chunks[idx].ptr_high = 11891 qdf_get_upper_32_bits( 11892 param->mem_chunks[idx].paddr); 11893 QDF_TRACE(QDF_MODULE_ID_ANY, QDF_TRACE_LEVEL_DEBUG, 11894 "chunk %d len %d requested ,ptr 0x%x ", 11895 idx, host_mem_chunks[idx].size, 11896 host_mem_chunks[idx].ptr); 11897 } 11898 cmd->num_host_mem_chunks = param->num_mem_chunks; 11899 len += (param->num_mem_chunks * sizeof(wlan_host_memory_chunk)); 11900 11901 WMITLV_SET_HDR((buf_ptr + sizeof(*cmd) + sizeof(wmi_resource_config)), 11902 WMITLV_TAG_ARRAY_STRUC, 11903 (sizeof(wlan_host_memory_chunk) * 11904 param->num_mem_chunks)); 11905 11906 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", 11907 resource_cfg->num_peers, resource_cfg->num_offload_peers, 11908 resource_cfg->num_vdevs, resource_cfg->num_tids, 11909 resource_cfg->num_tdls_conn_table_entries, 11910 resource_cfg->num_tdls_vdevs); 11911 11912 /* Fill hw mode id config */ 11913 buf_ptr = copy_hw_mode_in_init_cmd(wmi_handle, buf_ptr, &len, param); 11914 11915 /* Fill fw_abi_vers */ 11916 copy_fw_abi_version_tlv(wmi_handle, cmd); 11917 11918 wmi_mtrace(WMI_INIT_CMDID, NO_SESSION, 0); 11919 ret = wmi_unified_cmd_send(wmi_handle, buf, len, WMI_INIT_CMDID); 11920 if (QDF_IS_STATUS_ERROR(ret)) { 11921 wmi_err("wmi_unified_cmd_send WMI_INIT_CMDID returned Error %d", 11922 ret); 11923 wmi_buf_free(buf); 11924 } 11925 11926 return ret; 11927 11928 } 11929 11930 /** 11931 * send_addba_send_cmd_tlv() - send addba send command to fw 11932 * @wmi_handle: wmi handle 11933 * @param: pointer to delba send params 11934 * @macaddr: peer mac address 11935 * 11936 * Send WMI_ADDBA_SEND_CMDID command to firmware 11937 * Return: QDF_STATUS_SUCCESS on success. QDF_STATUS_E** on error 11938 */ 11939 static QDF_STATUS 11940 send_addba_send_cmd_tlv(wmi_unified_t wmi_handle, 11941 uint8_t macaddr[QDF_MAC_ADDR_SIZE], 11942 struct addba_send_params *param) 11943 { 11944 wmi_addba_send_cmd_fixed_param *cmd; 11945 wmi_buf_t buf; 11946 uint16_t len; 11947 QDF_STATUS ret; 11948 11949 len = sizeof(*cmd); 11950 11951 buf = wmi_buf_alloc(wmi_handle, len); 11952 if (!buf) 11953 return QDF_STATUS_E_NOMEM; 11954 11955 cmd = (wmi_addba_send_cmd_fixed_param *)wmi_buf_data(buf); 11956 11957 WMITLV_SET_HDR(&cmd->tlv_header, 11958 WMITLV_TAG_STRUC_wmi_addba_send_cmd_fixed_param, 11959 WMITLV_GET_STRUCT_TLVLEN(wmi_addba_send_cmd_fixed_param)); 11960 11961 cmd->vdev_id = param->vdev_id; 11962 WMI_CHAR_ARRAY_TO_MAC_ADDR(macaddr, &cmd->peer_macaddr); 11963 cmd->tid = param->tidno; 11964 cmd->buffersize = param->buffersize; 11965 11966 wmi_mtrace(WMI_ADDBA_SEND_CMDID, cmd->vdev_id, 0); 11967 ret = wmi_unified_cmd_send(wmi_handle, buf, len, WMI_ADDBA_SEND_CMDID); 11968 if (QDF_IS_STATUS_ERROR(ret)) { 11969 wmi_err("Failed to send cmd to fw, ret=%d", ret); 11970 wmi_buf_free(buf); 11971 return QDF_STATUS_E_FAILURE; 11972 } 11973 11974 return QDF_STATUS_SUCCESS; 11975 } 11976 11977 /** 11978 * send_delba_send_cmd_tlv() - send delba send command to fw 11979 * @wmi_handle: wmi handle 11980 * @param: pointer to delba send params 11981 * @macaddr: peer mac address 11982 * 11983 * Send WMI_DELBA_SEND_CMDID command to firmware 11984 * Return: QDF_STATUS_SUCCESS on success. QDF_STATUS_E** on error 11985 */ 11986 static QDF_STATUS 11987 send_delba_send_cmd_tlv(wmi_unified_t wmi_handle, 11988 uint8_t macaddr[QDF_MAC_ADDR_SIZE], 11989 struct delba_send_params *param) 11990 { 11991 wmi_delba_send_cmd_fixed_param *cmd; 11992 wmi_buf_t buf; 11993 uint16_t len; 11994 QDF_STATUS ret; 11995 11996 len = sizeof(*cmd); 11997 11998 buf = wmi_buf_alloc(wmi_handle, len); 11999 if (!buf) 12000 return QDF_STATUS_E_NOMEM; 12001 12002 cmd = (wmi_delba_send_cmd_fixed_param *)wmi_buf_data(buf); 12003 12004 WMITLV_SET_HDR(&cmd->tlv_header, 12005 WMITLV_TAG_STRUC_wmi_delba_send_cmd_fixed_param, 12006 WMITLV_GET_STRUCT_TLVLEN(wmi_delba_send_cmd_fixed_param)); 12007 12008 cmd->vdev_id = param->vdev_id; 12009 WMI_CHAR_ARRAY_TO_MAC_ADDR(macaddr, &cmd->peer_macaddr); 12010 cmd->tid = param->tidno; 12011 cmd->initiator = param->initiator; 12012 cmd->reasoncode = param->reasoncode; 12013 12014 wmi_mtrace(WMI_DELBA_SEND_CMDID, cmd->vdev_id, 0); 12015 ret = wmi_unified_cmd_send(wmi_handle, buf, len, WMI_DELBA_SEND_CMDID); 12016 if (QDF_IS_STATUS_ERROR(ret)) { 12017 wmi_err("Failed to send cmd to fw, ret=%d", ret); 12018 wmi_buf_free(buf); 12019 return QDF_STATUS_E_FAILURE; 12020 } 12021 12022 return QDF_STATUS_SUCCESS; 12023 } 12024 12025 /** 12026 * send_addba_clearresponse_cmd_tlv() - send addba clear response command 12027 * to fw 12028 * @wmi_handle: wmi handle 12029 * @param: pointer to addba clearresp params 12030 * @macaddr: peer mac address 12031 * Return: QDF_STATUS_SUCCESS for success or error code 12032 */ 12033 static QDF_STATUS 12034 send_addba_clearresponse_cmd_tlv(wmi_unified_t wmi_handle, 12035 uint8_t macaddr[QDF_MAC_ADDR_SIZE], 12036 struct addba_clearresponse_params *param) 12037 { 12038 wmi_addba_clear_resp_cmd_fixed_param *cmd; 12039 wmi_buf_t buf; 12040 uint16_t len; 12041 QDF_STATUS ret; 12042 12043 len = sizeof(*cmd); 12044 12045 buf = wmi_buf_alloc(wmi_handle, len); 12046 if (!buf) 12047 return QDF_STATUS_E_FAILURE; 12048 12049 cmd = (wmi_addba_clear_resp_cmd_fixed_param *)wmi_buf_data(buf); 12050 12051 WMITLV_SET_HDR(&cmd->tlv_header, 12052 WMITLV_TAG_STRUC_wmi_addba_clear_resp_cmd_fixed_param, 12053 WMITLV_GET_STRUCT_TLVLEN(wmi_addba_clear_resp_cmd_fixed_param)); 12054 12055 cmd->vdev_id = param->vdev_id; 12056 WMI_CHAR_ARRAY_TO_MAC_ADDR(macaddr, &cmd->peer_macaddr); 12057 12058 wmi_mtrace(WMI_ADDBA_CLEAR_RESP_CMDID, cmd->vdev_id, 0); 12059 ret = wmi_unified_cmd_send(wmi_handle, 12060 buf, len, WMI_ADDBA_CLEAR_RESP_CMDID); 12061 if (QDF_IS_STATUS_ERROR(ret)) { 12062 wmi_err("Failed to send cmd to fw, ret=%d", ret); 12063 wmi_buf_free(buf); 12064 return QDF_STATUS_E_FAILURE; 12065 } 12066 12067 return QDF_STATUS_SUCCESS; 12068 } 12069 12070 #ifdef OBSS_PD 12071 /** 12072 * send_obss_spatial_reuse_set_def_thresh_cmd_tlv - send obss spatial reuse set 12073 * def thresh to fw 12074 * @wmi_handle: wmi handle 12075 * @thresh: pointer to obss_spatial_reuse_def_thresh 12076 * 12077 * Return: QDF_STATUS_SUCCESS for success or error code 12078 */ 12079 static 12080 QDF_STATUS send_obss_spatial_reuse_set_def_thresh_cmd_tlv( 12081 wmi_unified_t wmi_handle, 12082 struct wmi_host_obss_spatial_reuse_set_def_thresh 12083 *thresh) 12084 { 12085 wmi_buf_t buf; 12086 wmi_obss_spatial_reuse_set_def_obss_thresh_cmd_fixed_param *cmd; 12087 QDF_STATUS ret; 12088 uint32_t cmd_len; 12089 uint32_t tlv_len; 12090 12091 cmd_len = sizeof(*cmd); 12092 12093 buf = wmi_buf_alloc(wmi_handle, cmd_len); 12094 if (!buf) 12095 return QDF_STATUS_E_NOMEM; 12096 12097 cmd = (wmi_obss_spatial_reuse_set_def_obss_thresh_cmd_fixed_param *) 12098 wmi_buf_data(buf); 12099 12100 tlv_len = WMITLV_GET_STRUCT_TLVLEN( 12101 wmi_obss_spatial_reuse_set_def_obss_thresh_cmd_fixed_param); 12102 12103 WMITLV_SET_HDR(&cmd->tlv_header, 12104 WMITLV_TAG_STRUC_wmi_obss_spatial_reuse_set_def_obss_thresh_cmd_fixed_param, 12105 tlv_len); 12106 12107 cmd->obss_min = thresh->obss_min; 12108 cmd->obss_max = thresh->obss_max; 12109 cmd->vdev_type = thresh->vdev_type; 12110 ret = wmi_unified_cmd_send(wmi_handle, buf, cmd_len, 12111 WMI_PDEV_OBSS_PD_SPATIAL_REUSE_SET_DEF_OBSS_THRESH_CMDID); 12112 if (QDF_IS_STATUS_ERROR(ret)) 12113 wmi_buf_free(buf); 12114 12115 return ret; 12116 } 12117 12118 /** 12119 * send_obss_spatial_reuse_set_cmd_tlv - send obss spatial reuse set cmd to fw 12120 * @wmi_handle: wmi handle 12121 * @obss_spatial_reuse_param: pointer to obss_spatial_reuse_param 12122 * 12123 * Return: QDF_STATUS_SUCCESS for success or error code 12124 */ 12125 static 12126 QDF_STATUS send_obss_spatial_reuse_set_cmd_tlv(wmi_unified_t wmi_handle, 12127 struct wmi_host_obss_spatial_reuse_set_param 12128 *obss_spatial_reuse_param) 12129 { 12130 wmi_buf_t buf; 12131 wmi_obss_spatial_reuse_set_cmd_fixed_param *cmd; 12132 QDF_STATUS ret; 12133 uint32_t len; 12134 12135 len = sizeof(*cmd); 12136 12137 buf = wmi_buf_alloc(wmi_handle, len); 12138 if (!buf) 12139 return QDF_STATUS_E_FAILURE; 12140 12141 cmd = (wmi_obss_spatial_reuse_set_cmd_fixed_param *)wmi_buf_data(buf); 12142 WMITLV_SET_HDR(&cmd->tlv_header, 12143 WMITLV_TAG_STRUC_wmi_obss_spatial_reuse_set_cmd_fixed_param, 12144 WMITLV_GET_STRUCT_TLVLEN 12145 (wmi_obss_spatial_reuse_set_cmd_fixed_param)); 12146 12147 cmd->enable = obss_spatial_reuse_param->enable; 12148 cmd->obss_min = obss_spatial_reuse_param->obss_min; 12149 cmd->obss_max = obss_spatial_reuse_param->obss_max; 12150 cmd->vdev_id = obss_spatial_reuse_param->vdev_id; 12151 12152 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 12153 WMI_PDEV_OBSS_PD_SPATIAL_REUSE_CMDID); 12154 12155 if (QDF_IS_STATUS_ERROR(ret)) { 12156 wmi_err( 12157 "WMI_PDEV_OBSS_PD_SPATIAL_REUSE_CMDID send returned Error %d", 12158 ret); 12159 wmi_buf_free(buf); 12160 } 12161 12162 return ret; 12163 } 12164 12165 /** 12166 * send_self_srg_bss_color_bitmap_set_cmd_tlv() - Send 64-bit BSS color bitmap 12167 * to be used by SRG based Spatial Reuse feature to the FW 12168 * @wmi_handle: wmi handle 12169 * @bitmap_0: lower 32 bits in BSS color bitmap 12170 * @bitmap_1: upper 32 bits in BSS color bitmap 12171 * @pdev_id: pdev ID 12172 * 12173 * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure 12174 */ 12175 static QDF_STATUS 12176 send_self_srg_bss_color_bitmap_set_cmd_tlv( 12177 wmi_unified_t wmi_handle, uint32_t bitmap_0, 12178 uint32_t bitmap_1, uint8_t pdev_id) 12179 { 12180 wmi_buf_t buf; 12181 wmi_pdev_srg_bss_color_bitmap_cmd_fixed_param *cmd; 12182 QDF_STATUS ret; 12183 uint32_t len; 12184 12185 len = sizeof(*cmd); 12186 12187 buf = wmi_buf_alloc(wmi_handle, len); 12188 if (!buf) 12189 return QDF_STATUS_E_FAILURE; 12190 12191 cmd = (wmi_pdev_srg_bss_color_bitmap_cmd_fixed_param *) 12192 wmi_buf_data(buf); 12193 12194 WMITLV_SET_HDR( 12195 &cmd->tlv_header, 12196 WMITLV_TAG_STRUC_wmi_pdev_srg_bss_color_bitmap_cmd_fixed_param, 12197 WMITLV_GET_STRUCT_TLVLEN 12198 (wmi_pdev_srg_bss_color_bitmap_cmd_fixed_param)); 12199 12200 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 12201 wmi_handle, pdev_id); 12202 cmd->srg_bss_color_bitmap[0] = bitmap_0; 12203 cmd->srg_bss_color_bitmap[1] = bitmap_1; 12204 12205 ret = wmi_unified_cmd_send( 12206 wmi_handle, buf, len, 12207 WMI_PDEV_SET_SRG_BSS_COLOR_BITMAP_CMDID); 12208 12209 if (QDF_IS_STATUS_ERROR(ret)) { 12210 wmi_err( 12211 "WMI_PDEV_SET_SRG_BSS_COLOR_BITMAP_CMDID send returned Error %d", 12212 ret); 12213 wmi_buf_free(buf); 12214 } 12215 12216 return ret; 12217 } 12218 12219 /** 12220 * send_self_srg_partial_bssid_bitmap_set_cmd_tlv() - Send 64-bit partial BSSID 12221 * bitmap to be used by SRG based Spatial Reuse feature to the FW 12222 * @wmi_handle: wmi handle 12223 * @bitmap_0: lower 32 bits in partial BSSID bitmap 12224 * @bitmap_1: upper 32 bits in partial BSSID bitmap 12225 * @pdev_id: pdev ID 12226 * 12227 * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure 12228 */ 12229 static QDF_STATUS 12230 send_self_srg_partial_bssid_bitmap_set_cmd_tlv( 12231 wmi_unified_t wmi_handle, uint32_t bitmap_0, 12232 uint32_t bitmap_1, uint8_t pdev_id) 12233 { 12234 wmi_buf_t buf; 12235 wmi_pdev_srg_partial_bssid_bitmap_cmd_fixed_param *cmd; 12236 QDF_STATUS ret; 12237 uint32_t len; 12238 12239 len = sizeof(*cmd); 12240 12241 buf = wmi_buf_alloc(wmi_handle, len); 12242 if (!buf) 12243 return QDF_STATUS_E_FAILURE; 12244 12245 cmd = (wmi_pdev_srg_partial_bssid_bitmap_cmd_fixed_param *) 12246 wmi_buf_data(buf); 12247 12248 WMITLV_SET_HDR( 12249 &cmd->tlv_header, 12250 WMITLV_TAG_STRUC_wmi_pdev_srg_partial_bssid_bitmap_cmd_fixed_param, 12251 WMITLV_GET_STRUCT_TLVLEN 12252 (wmi_pdev_srg_partial_bssid_bitmap_cmd_fixed_param)); 12253 12254 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 12255 wmi_handle, pdev_id); 12256 12257 cmd->srg_partial_bssid_bitmap[0] = bitmap_0; 12258 cmd->srg_partial_bssid_bitmap[1] = bitmap_1; 12259 12260 ret = wmi_unified_cmd_send( 12261 wmi_handle, buf, len, 12262 WMI_PDEV_SET_SRG_PARTIAL_BSSID_BITMAP_CMDID); 12263 12264 if (QDF_IS_STATUS_ERROR(ret)) { 12265 wmi_err( 12266 "WMI_PDEV_SET_SRG_PARTIAL_BSSID_BITMAP_CMDID send returned Error %d", 12267 ret); 12268 wmi_buf_free(buf); 12269 } 12270 12271 return ret; 12272 } 12273 12274 /** 12275 * send_self_srg_obss_color_enable_bitmap_cmd_tlv() - Send 64-bit BSS color 12276 * enable bitmap to be used by SRG based Spatial Reuse feature to the FW 12277 * @wmi_handle: wmi handle 12278 * @bitmap_0: lower 32 bits in BSS color enable bitmap 12279 * @bitmap_1: upper 32 bits in BSS color enable bitmap 12280 * @pdev_id: pdev ID 12281 * 12282 * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure 12283 */ 12284 static QDF_STATUS 12285 send_self_srg_obss_color_enable_bitmap_cmd_tlv( 12286 wmi_unified_t wmi_handle, uint32_t bitmap_0, 12287 uint32_t bitmap_1, uint8_t pdev_id) 12288 { 12289 wmi_buf_t buf; 12290 wmi_pdev_srg_obss_color_enable_bitmap_cmd_fixed_param *cmd; 12291 QDF_STATUS ret; 12292 uint32_t len; 12293 12294 len = sizeof(*cmd); 12295 12296 buf = wmi_buf_alloc(wmi_handle, len); 12297 if (!buf) 12298 return QDF_STATUS_E_FAILURE; 12299 12300 cmd = (wmi_pdev_srg_obss_color_enable_bitmap_cmd_fixed_param *) 12301 wmi_buf_data(buf); 12302 12303 WMITLV_SET_HDR( 12304 &cmd->tlv_header, 12305 WMITLV_TAG_STRUC_wmi_pdev_srg_obss_color_enable_bitmap_cmd_fixed_param, 12306 WMITLV_GET_STRUCT_TLVLEN 12307 (wmi_pdev_srg_obss_color_enable_bitmap_cmd_fixed_param)); 12308 12309 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 12310 wmi_handle, pdev_id); 12311 cmd->srg_obss_en_color_bitmap[0] = bitmap_0; 12312 cmd->srg_obss_en_color_bitmap[1] = bitmap_1; 12313 12314 ret = wmi_unified_cmd_send( 12315 wmi_handle, buf, len, 12316 WMI_PDEV_SET_SRG_OBSS_COLOR_ENABLE_BITMAP_CMDID); 12317 12318 if (QDF_IS_STATUS_ERROR(ret)) { 12319 wmi_err( 12320 "WMI_PDEV_SET_SRG_OBSS_COLOR_ENABLE_BITMAP_CMDID send returned Error %d", 12321 ret); 12322 wmi_buf_free(buf); 12323 } 12324 12325 return ret; 12326 } 12327 12328 /** 12329 * send_self_srg_obss_bssid_enable_bitmap_cmd_tlv() - Send 64-bit OBSS BSSID 12330 * enable bitmap to be used by SRG based Spatial Reuse feature to the FW 12331 * @wmi_handle: wmi handle 12332 * @bitmap_0: lower 32 bits in BSSID enable bitmap 12333 * @bitmap_1: upper 32 bits in BSSID enable bitmap 12334 * @pdev_id: pdev ID 12335 * 12336 * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure 12337 */ 12338 static QDF_STATUS 12339 send_self_srg_obss_bssid_enable_bitmap_cmd_tlv( 12340 wmi_unified_t wmi_handle, uint32_t bitmap_0, 12341 uint32_t bitmap_1, uint8_t pdev_id) 12342 { 12343 wmi_buf_t buf; 12344 wmi_pdev_srg_obss_bssid_enable_bitmap_cmd_fixed_param *cmd; 12345 QDF_STATUS ret; 12346 uint32_t len; 12347 12348 len = sizeof(*cmd); 12349 12350 buf = wmi_buf_alloc(wmi_handle, len); 12351 if (!buf) 12352 return QDF_STATUS_E_FAILURE; 12353 12354 cmd = (wmi_pdev_srg_obss_bssid_enable_bitmap_cmd_fixed_param *) 12355 wmi_buf_data(buf); 12356 12357 WMITLV_SET_HDR( 12358 &cmd->tlv_header, 12359 WMITLV_TAG_STRUC_wmi_pdev_srg_obss_bssid_enable_bitmap_cmd_fixed_param, 12360 WMITLV_GET_STRUCT_TLVLEN 12361 (wmi_pdev_srg_obss_bssid_enable_bitmap_cmd_fixed_param)); 12362 12363 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 12364 wmi_handle, pdev_id); 12365 cmd->srg_obss_en_bssid_bitmap[0] = bitmap_0; 12366 cmd->srg_obss_en_bssid_bitmap[1] = bitmap_1; 12367 12368 ret = wmi_unified_cmd_send( 12369 wmi_handle, buf, len, 12370 WMI_PDEV_SET_SRG_OBSS_BSSID_ENABLE_BITMAP_CMDID); 12371 12372 if (QDF_IS_STATUS_ERROR(ret)) { 12373 wmi_err( 12374 "WMI_PDEV_SET_SRG_OBSS_BSSID_ENABLE_BITMAP_CMDID send returned Error %d", 12375 ret); 12376 wmi_buf_free(buf); 12377 } 12378 12379 return ret; 12380 } 12381 12382 /** 12383 * send_self_non_srg_obss_color_enable_bitmap_cmd_tlv() - Send 64-bit BSS color 12384 * enable bitmap to be used by Non-SRG based Spatial Reuse feature to the FW 12385 * @wmi_handle: wmi handle 12386 * @bitmap_0: lower 32 bits in BSS color enable bitmap 12387 * @bitmap_1: upper 32 bits in BSS color enable bitmap 12388 * @pdev_id: pdev ID 12389 * 12390 * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure 12391 */ 12392 static QDF_STATUS 12393 send_self_non_srg_obss_color_enable_bitmap_cmd_tlv( 12394 wmi_unified_t wmi_handle, uint32_t bitmap_0, 12395 uint32_t bitmap_1, uint8_t pdev_id) 12396 { 12397 wmi_buf_t buf; 12398 wmi_pdev_non_srg_obss_color_enable_bitmap_cmd_fixed_param *cmd; 12399 QDF_STATUS ret; 12400 uint32_t len; 12401 12402 len = sizeof(*cmd); 12403 12404 buf = wmi_buf_alloc(wmi_handle, len); 12405 if (!buf) 12406 return QDF_STATUS_E_FAILURE; 12407 12408 cmd = (wmi_pdev_non_srg_obss_color_enable_bitmap_cmd_fixed_param *) 12409 wmi_buf_data(buf); 12410 12411 WMITLV_SET_HDR( 12412 &cmd->tlv_header, 12413 WMITLV_TAG_STRUC_wmi_pdev_non_srg_obss_color_enable_bitmap_cmd_fixed_param, 12414 WMITLV_GET_STRUCT_TLVLEN 12415 (wmi_pdev_non_srg_obss_color_enable_bitmap_cmd_fixed_param)); 12416 12417 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 12418 wmi_handle, pdev_id); 12419 cmd->non_srg_obss_en_color_bitmap[0] = bitmap_0; 12420 cmd->non_srg_obss_en_color_bitmap[1] = bitmap_1; 12421 12422 ret = wmi_unified_cmd_send( 12423 wmi_handle, buf, len, 12424 WMI_PDEV_SET_NON_SRG_OBSS_COLOR_ENABLE_BITMAP_CMDID); 12425 12426 if (QDF_IS_STATUS_ERROR(ret)) { 12427 wmi_err( 12428 "WMI_PDEV_SET_NON_SRG_OBSS_COLOR_ENABLE_BITMAP_CMDID send returned Error %d", 12429 ret); 12430 wmi_buf_free(buf); 12431 } 12432 12433 return ret; 12434 } 12435 12436 /** 12437 * send_self_non_srg_obss_bssid_enable_bitmap_cmd_tlv() - Send 64-bit OBSS BSSID 12438 * enable bitmap to be used by Non-SRG based Spatial Reuse feature to the FW 12439 * @wmi_handle: wmi handle 12440 * @bitmap_0: lower 32 bits in BSSID enable bitmap 12441 * @bitmap_1: upper 32 bits in BSSID enable bitmap 12442 * @pdev_id: pdev ID 12443 * 12444 * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure 12445 */ 12446 static QDF_STATUS 12447 send_self_non_srg_obss_bssid_enable_bitmap_cmd_tlv( 12448 wmi_unified_t wmi_handle, uint32_t bitmap_0, 12449 uint32_t bitmap_1, uint8_t pdev_id) 12450 { 12451 wmi_buf_t buf; 12452 wmi_pdev_non_srg_obss_bssid_enable_bitmap_cmd_fixed_param *cmd; 12453 QDF_STATUS ret; 12454 uint32_t len; 12455 12456 len = sizeof(*cmd); 12457 12458 buf = wmi_buf_alloc(wmi_handle, len); 12459 if (!buf) 12460 return QDF_STATUS_E_FAILURE; 12461 12462 cmd = (wmi_pdev_non_srg_obss_bssid_enable_bitmap_cmd_fixed_param *) 12463 wmi_buf_data(buf); 12464 12465 WMITLV_SET_HDR( 12466 &cmd->tlv_header, 12467 WMITLV_TAG_STRUC_wmi_pdev_non_srg_obss_bssid_enable_bitmap_cmd_fixed_param, 12468 WMITLV_GET_STRUCT_TLVLEN 12469 (wmi_pdev_non_srg_obss_bssid_enable_bitmap_cmd_fixed_param)); 12470 12471 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 12472 wmi_handle, pdev_id); 12473 cmd->non_srg_obss_en_bssid_bitmap[0] = bitmap_0; 12474 cmd->non_srg_obss_en_bssid_bitmap[1] = bitmap_1; 12475 12476 ret = wmi_unified_cmd_send( 12477 wmi_handle, buf, len, 12478 WMI_PDEV_SET_NON_SRG_OBSS_BSSID_ENABLE_BITMAP_CMDID); 12479 12480 if (QDF_IS_STATUS_ERROR(ret)) { 12481 wmi_err( 12482 "WMI_PDEV_SET_NON_SRG_OBSS_BSSID_ENABLE_BITMAP_CMDID send returned Error %d", 12483 ret); 12484 wmi_buf_free(buf); 12485 } 12486 12487 return ret; 12488 } 12489 #endif 12490 12491 static 12492 QDF_STATUS send_injector_config_cmd_tlv(wmi_unified_t wmi_handle, 12493 struct wmi_host_injector_frame_params *inject_config_params) 12494 { 12495 wmi_buf_t buf; 12496 wmi_frame_inject_cmd_fixed_param *cmd; 12497 QDF_STATUS ret; 12498 uint32_t len; 12499 12500 len = sizeof(*cmd); 12501 12502 buf = wmi_buf_alloc(wmi_handle, len); 12503 if (!buf) 12504 return QDF_STATUS_E_NOMEM; 12505 12506 cmd = (wmi_frame_inject_cmd_fixed_param *)wmi_buf_data(buf); 12507 WMITLV_SET_HDR(&cmd->tlv_header, 12508 WMITLV_TAG_STRUC_wmi_frame_inject_cmd_fixed_param, 12509 WMITLV_GET_STRUCT_TLVLEN 12510 (wmi_frame_inject_cmd_fixed_param)); 12511 12512 cmd->vdev_id = inject_config_params->vdev_id; 12513 cmd->enable = inject_config_params->enable; 12514 cmd->frame_type = inject_config_params->frame_type; 12515 cmd->frame_inject_period = inject_config_params->frame_inject_period; 12516 cmd->fc_duration = inject_config_params->frame_duration; 12517 WMI_CHAR_ARRAY_TO_MAC_ADDR(inject_config_params->dstmac, 12518 &cmd->frame_addr1); 12519 cmd->bw = inject_config_params->frame_bw; 12520 12521 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 12522 WMI_PDEV_FRAME_INJECT_CMDID); 12523 12524 if (QDF_IS_STATUS_ERROR(ret)) { 12525 wmi_err( 12526 "WMI_PDEV_FRAME_INJECT_CMDID send returned Error %d", 12527 ret); 12528 wmi_buf_free(buf); 12529 } 12530 12531 return ret; 12532 } 12533 #ifdef QCA_SUPPORT_CP_STATS 12534 /** 12535 * extract_cca_stats_tlv - api to extract congestion stats from event buffer 12536 * @wmi_handle: wma handle 12537 * @evt_buf: event buffer 12538 * @out_buff: buffer to populated after stats extraction 12539 * 12540 * Return: status of operation 12541 */ 12542 static QDF_STATUS extract_cca_stats_tlv(wmi_unified_t wmi_handle, 12543 void *evt_buf, struct wmi_host_congestion_stats *out_buff) 12544 { 12545 WMI_UPDATE_STATS_EVENTID_param_tlvs *param_buf; 12546 wmi_congestion_stats *congestion_stats; 12547 12548 param_buf = (WMI_UPDATE_STATS_EVENTID_param_tlvs *)evt_buf; 12549 congestion_stats = param_buf->congestion_stats; 12550 if (!congestion_stats) 12551 return QDF_STATUS_E_INVAL; 12552 12553 out_buff->vdev_id = congestion_stats->vdev_id; 12554 out_buff->congestion = congestion_stats->congestion; 12555 12556 wmi_debug("cca stats event processed"); 12557 return QDF_STATUS_SUCCESS; 12558 } 12559 #endif /* QCA_SUPPORT_CP_STATS */ 12560 12561 /** 12562 * extract_ctl_failsafe_check_ev_param_tlv() - extract ctl data from 12563 * event 12564 * @wmi_handle: wmi handle 12565 * @evt_buf: pointer to event buffer 12566 * @param: Pointer to hold peer ctl data 12567 * 12568 * Return: QDF_STATUS_SUCCESS for success or error code 12569 */ 12570 static QDF_STATUS extract_ctl_failsafe_check_ev_param_tlv( 12571 wmi_unified_t wmi_handle, 12572 void *evt_buf, 12573 struct wmi_host_pdev_ctl_failsafe_event *param) 12574 { 12575 WMI_PDEV_CTL_FAILSAFE_CHECK_EVENTID_param_tlvs *param_buf; 12576 wmi_pdev_ctl_failsafe_check_fixed_param *fix_param; 12577 12578 param_buf = (WMI_PDEV_CTL_FAILSAFE_CHECK_EVENTID_param_tlvs *)evt_buf; 12579 if (!param_buf) { 12580 wmi_err("Invalid ctl_failsafe event buffer"); 12581 return QDF_STATUS_E_INVAL; 12582 } 12583 12584 fix_param = param_buf->fixed_param; 12585 param->ctl_failsafe_status = fix_param->ctl_FailsafeStatus; 12586 12587 return QDF_STATUS_SUCCESS; 12588 } 12589 12590 /** 12591 * save_service_bitmap_tlv() - save service bitmap 12592 * @wmi_handle: wmi handle 12593 * @evt_buf: pointer to event buffer 12594 * @bitmap_buf: bitmap buffer, for converged legacy support 12595 * 12596 * Return: QDF_STATUS 12597 */ 12598 static 12599 QDF_STATUS save_service_bitmap_tlv(wmi_unified_t wmi_handle, void *evt_buf, 12600 void *bitmap_buf) 12601 { 12602 WMI_SERVICE_READY_EVENTID_param_tlvs *param_buf; 12603 struct wmi_soc *soc = wmi_handle->soc; 12604 12605 param_buf = (WMI_SERVICE_READY_EVENTID_param_tlvs *) evt_buf; 12606 12607 /* If it is already allocated, use that buffer. This can happen 12608 * during target stop/start scenarios where host allocation is skipped. 12609 */ 12610 if (!soc->wmi_service_bitmap) { 12611 soc->wmi_service_bitmap = 12612 qdf_mem_malloc(WMI_SERVICE_BM_SIZE * sizeof(uint32_t)); 12613 if (!soc->wmi_service_bitmap) 12614 return QDF_STATUS_E_NOMEM; 12615 } 12616 12617 qdf_mem_copy(soc->wmi_service_bitmap, 12618 param_buf->wmi_service_bitmap, 12619 (WMI_SERVICE_BM_SIZE * sizeof(uint32_t))); 12620 12621 if (bitmap_buf) 12622 qdf_mem_copy(bitmap_buf, 12623 param_buf->wmi_service_bitmap, 12624 (WMI_SERVICE_BM_SIZE * sizeof(uint32_t))); 12625 12626 return QDF_STATUS_SUCCESS; 12627 } 12628 12629 /** 12630 * save_ext_service_bitmap_tlv() - save extendend service bitmap 12631 * @wmi_handle: wmi handle 12632 * @evt_buf: pointer to event buffer 12633 * @bitmap_buf: bitmap buffer, for converged legacy support 12634 * 12635 * Return: QDF_STATUS 12636 */ 12637 static 12638 QDF_STATUS save_ext_service_bitmap_tlv(wmi_unified_t wmi_handle, void *evt_buf, 12639 void *bitmap_buf) 12640 { 12641 WMI_SERVICE_AVAILABLE_EVENTID_param_tlvs *param_buf; 12642 wmi_service_available_event_fixed_param *ev; 12643 struct wmi_soc *soc = wmi_handle->soc; 12644 uint32_t i = 0; 12645 12646 param_buf = (WMI_SERVICE_AVAILABLE_EVENTID_param_tlvs *) evt_buf; 12647 12648 ev = param_buf->fixed_param; 12649 12650 /* If it is already allocated, use that buffer. This can happen 12651 * during target stop/start scenarios where host allocation is skipped. 12652 */ 12653 if (!soc->wmi_ext_service_bitmap) { 12654 soc->wmi_ext_service_bitmap = qdf_mem_malloc( 12655 WMI_SERVICE_SEGMENT_BM_SIZE32 * sizeof(uint32_t)); 12656 if (!soc->wmi_ext_service_bitmap) 12657 return QDF_STATUS_E_NOMEM; 12658 } 12659 12660 qdf_mem_copy(soc->wmi_ext_service_bitmap, 12661 ev->wmi_service_segment_bitmap, 12662 (WMI_SERVICE_SEGMENT_BM_SIZE32 * sizeof(uint32_t))); 12663 12664 wmi_debug("wmi_ext_service_bitmap 0:0x%x, 1:0x%x, 2:0x%x, 3:0x%x", 12665 soc->wmi_ext_service_bitmap[0], soc->wmi_ext_service_bitmap[1], 12666 soc->wmi_ext_service_bitmap[2], soc->wmi_ext_service_bitmap[3]); 12667 12668 if (bitmap_buf) 12669 qdf_mem_copy(bitmap_buf, 12670 soc->wmi_ext_service_bitmap, 12671 (WMI_SERVICE_SEGMENT_BM_SIZE32 * sizeof(uint32_t))); 12672 12673 if (!param_buf->wmi_service_ext_bitmap) { 12674 wmi_debug("wmi_service_ext_bitmap not available"); 12675 return QDF_STATUS_SUCCESS; 12676 } 12677 12678 if (!soc->wmi_ext2_service_bitmap || 12679 (param_buf->num_wmi_service_ext_bitmap > 12680 soc->wmi_ext2_service_bitmap_len)) { 12681 if (soc->wmi_ext2_service_bitmap) { 12682 qdf_mem_free(soc->wmi_ext2_service_bitmap); 12683 soc->wmi_ext2_service_bitmap = NULL; 12684 } 12685 soc->wmi_ext2_service_bitmap = 12686 qdf_mem_malloc(param_buf->num_wmi_service_ext_bitmap * 12687 sizeof(uint32_t)); 12688 if (!soc->wmi_ext2_service_bitmap) 12689 return QDF_STATUS_E_NOMEM; 12690 12691 soc->wmi_ext2_service_bitmap_len = 12692 param_buf->num_wmi_service_ext_bitmap; 12693 } 12694 12695 qdf_mem_copy(soc->wmi_ext2_service_bitmap, 12696 param_buf->wmi_service_ext_bitmap, 12697 (param_buf->num_wmi_service_ext_bitmap * 12698 sizeof(uint32_t))); 12699 12700 for (i = 0; i < param_buf->num_wmi_service_ext_bitmap; i++) { 12701 wmi_debug("wmi_ext2_service_bitmap %u:0x%x", 12702 i, soc->wmi_ext2_service_bitmap[i]); 12703 } 12704 12705 return QDF_STATUS_SUCCESS; 12706 } 12707 12708 static inline void copy_ht_cap_info(uint32_t ev_target_cap, 12709 struct wlan_psoc_target_capability_info *cap) 12710 { 12711 /* except LDPC all flags are common between legacy and here 12712 * also IBFEER is not defined for TLV 12713 */ 12714 cap->ht_cap_info |= ev_target_cap & ( 12715 WMI_HT_CAP_ENABLED 12716 | WMI_HT_CAP_HT20_SGI 12717 | WMI_HT_CAP_DYNAMIC_SMPS 12718 | WMI_HT_CAP_TX_STBC 12719 | WMI_HT_CAP_TX_STBC_MASK_SHIFT 12720 | WMI_HT_CAP_RX_STBC 12721 | WMI_HT_CAP_RX_STBC_MASK_SHIFT 12722 | WMI_HT_CAP_LDPC 12723 | WMI_HT_CAP_L_SIG_TXOP_PROT 12724 | WMI_HT_CAP_MPDU_DENSITY 12725 | WMI_HT_CAP_MPDU_DENSITY_MASK_SHIFT 12726 | WMI_HT_CAP_HT40_SGI); 12727 if (ev_target_cap & WMI_HT_CAP_LDPC) 12728 cap->ht_cap_info |= WMI_HOST_HT_CAP_RX_LDPC | 12729 WMI_HOST_HT_CAP_TX_LDPC; 12730 } 12731 /** 12732 * extract_service_ready_tlv() - extract service ready event 12733 * @wmi_handle: wmi handle 12734 * @evt_buf: pointer to received event buffer 12735 * @cap: pointer to hold target capability information extracted from even 12736 * 12737 * Return: QDF_STATUS_SUCCESS for success or error code 12738 */ 12739 static QDF_STATUS extract_service_ready_tlv(wmi_unified_t wmi_handle, 12740 void *evt_buf, struct wlan_psoc_target_capability_info *cap) 12741 { 12742 WMI_SERVICE_READY_EVENTID_param_tlvs *param_buf; 12743 wmi_service_ready_event_fixed_param *ev; 12744 12745 12746 param_buf = (WMI_SERVICE_READY_EVENTID_param_tlvs *) evt_buf; 12747 12748 ev = (wmi_service_ready_event_fixed_param *) param_buf->fixed_param; 12749 if (!ev) { 12750 qdf_print("%s: wmi_buf_alloc failed", __func__); 12751 return QDF_STATUS_E_FAILURE; 12752 } 12753 12754 cap->phy_capability = ev->phy_capability; 12755 cap->max_frag_entry = ev->max_frag_entry; 12756 cap->num_rf_chains = ev->num_rf_chains; 12757 copy_ht_cap_info(ev->ht_cap_info, cap); 12758 cap->vht_cap_info = ev->vht_cap_info; 12759 cap->vht_supp_mcs = ev->vht_supp_mcs; 12760 cap->hw_min_tx_power = ev->hw_min_tx_power; 12761 cap->hw_max_tx_power = ev->hw_max_tx_power; 12762 cap->sys_cap_info = ev->sys_cap_info; 12763 cap->min_pkt_size_enable = ev->min_pkt_size_enable; 12764 cap->max_bcn_ie_size = ev->max_bcn_ie_size; 12765 cap->max_num_scan_channels = ev->max_num_scan_channels; 12766 cap->max_supported_macs = ev->max_supported_macs; 12767 cap->wmi_fw_sub_feat_caps = ev->wmi_fw_sub_feat_caps; 12768 cap->txrx_chainmask = ev->txrx_chainmask; 12769 cap->default_dbs_hw_mode_index = ev->default_dbs_hw_mode_index; 12770 cap->num_msdu_desc = ev->num_msdu_desc; 12771 cap->fw_version = ev->fw_build_vers; 12772 /* fw_version_1 is not available in TLV. */ 12773 cap->fw_version_1 = 0; 12774 12775 return QDF_STATUS_SUCCESS; 12776 } 12777 12778 /* convert_wireless_modes_tlv() - Convert REGDMN_MODE values sent by target 12779 * to host internal HOST_REGDMN_MODE values. 12780 * REGULATORY TODO : REGDMN_MODE_11AC_VHT*_2G values are not used by the 12781 * host currently. Add this in the future if required. 12782 * 11AX (Phase II) : 11ax related values are not currently 12783 * advertised separately by FW. As part of phase II regulatory bring-up, 12784 * finalize the advertisement mechanism. 12785 * @target_wireless_mode: target wireless mode received in message 12786 * 12787 * Return: returns the host internal wireless mode. 12788 */ 12789 static inline uint32_t convert_wireless_modes_tlv(uint32_t target_wireless_mode) 12790 { 12791 12792 uint32_t wireless_modes = 0; 12793 12794 wmi_debug("Target wireless mode: 0x%x", target_wireless_mode); 12795 12796 if (target_wireless_mode & REGDMN_MODE_11A) 12797 wireless_modes |= HOST_REGDMN_MODE_11A; 12798 12799 if (target_wireless_mode & REGDMN_MODE_TURBO) 12800 wireless_modes |= HOST_REGDMN_MODE_TURBO; 12801 12802 if (target_wireless_mode & REGDMN_MODE_11B) 12803 wireless_modes |= HOST_REGDMN_MODE_11B; 12804 12805 if (target_wireless_mode & REGDMN_MODE_PUREG) 12806 wireless_modes |= HOST_REGDMN_MODE_PUREG; 12807 12808 if (target_wireless_mode & REGDMN_MODE_11G) 12809 wireless_modes |= HOST_REGDMN_MODE_11G; 12810 12811 if (target_wireless_mode & REGDMN_MODE_108G) 12812 wireless_modes |= HOST_REGDMN_MODE_108G; 12813 12814 if (target_wireless_mode & REGDMN_MODE_108A) 12815 wireless_modes |= HOST_REGDMN_MODE_108A; 12816 12817 if (target_wireless_mode & REGDMN_MODE_11AC_VHT20_2G) 12818 wireless_modes |= HOST_REGDMN_MODE_11AC_VHT20_2G; 12819 12820 if (target_wireless_mode & REGDMN_MODE_XR) 12821 wireless_modes |= HOST_REGDMN_MODE_XR; 12822 12823 if (target_wireless_mode & REGDMN_MODE_11A_HALF_RATE) 12824 wireless_modes |= HOST_REGDMN_MODE_11A_HALF_RATE; 12825 12826 if (target_wireless_mode & REGDMN_MODE_11A_QUARTER_RATE) 12827 wireless_modes |= HOST_REGDMN_MODE_11A_QUARTER_RATE; 12828 12829 if (target_wireless_mode & REGDMN_MODE_11NG_HT20) 12830 wireless_modes |= HOST_REGDMN_MODE_11NG_HT20; 12831 12832 if (target_wireless_mode & REGDMN_MODE_11NA_HT20) 12833 wireless_modes |= HOST_REGDMN_MODE_11NA_HT20; 12834 12835 if (target_wireless_mode & REGDMN_MODE_11NG_HT40PLUS) 12836 wireless_modes |= HOST_REGDMN_MODE_11NG_HT40PLUS; 12837 12838 if (target_wireless_mode & REGDMN_MODE_11NG_HT40MINUS) 12839 wireless_modes |= HOST_REGDMN_MODE_11NG_HT40MINUS; 12840 12841 if (target_wireless_mode & REGDMN_MODE_11NA_HT40PLUS) 12842 wireless_modes |= HOST_REGDMN_MODE_11NA_HT40PLUS; 12843 12844 if (target_wireless_mode & REGDMN_MODE_11NA_HT40MINUS) 12845 wireless_modes |= HOST_REGDMN_MODE_11NA_HT40MINUS; 12846 12847 if (target_wireless_mode & REGDMN_MODE_11AC_VHT20) 12848 wireless_modes |= HOST_REGDMN_MODE_11AC_VHT20; 12849 12850 if (target_wireless_mode & REGDMN_MODE_11AC_VHT40PLUS) 12851 wireless_modes |= HOST_REGDMN_MODE_11AC_VHT40PLUS; 12852 12853 if (target_wireless_mode & REGDMN_MODE_11AC_VHT40MINUS) 12854 wireless_modes |= HOST_REGDMN_MODE_11AC_VHT40MINUS; 12855 12856 if (target_wireless_mode & REGDMN_MODE_11AC_VHT80) 12857 wireless_modes |= HOST_REGDMN_MODE_11AC_VHT80; 12858 12859 if (target_wireless_mode & REGDMN_MODE_11AC_VHT160) 12860 wireless_modes |= HOST_REGDMN_MODE_11AC_VHT160; 12861 12862 if (target_wireless_mode & REGDMN_MODE_11AC_VHT80_80) 12863 wireless_modes |= HOST_REGDMN_MODE_11AC_VHT80_80; 12864 12865 return wireless_modes; 12866 } 12867 12868 /** 12869 * convert_11be_phybitmap_to_reg_flags() - Convert 11BE phybitmap to 12870 * to regulatory flags. 12871 * @target_phybitmap: target phybitmap. 12872 * @phybitmap: host internal REGULATORY_PHYMODE set based on target 12873 * phybitmap. 12874 * 12875 * Return: None 12876 */ 12877 12878 #ifdef WLAN_FEATURE_11BE 12879 static void convert_11be_phybitmap_to_reg_flags(uint32_t target_phybitmap, 12880 uint32_t *phybitmap) 12881 { 12882 if (target_phybitmap & WMI_REGULATORY_PHYMODE_NO11BE) 12883 *phybitmap |= REGULATORY_PHYMODE_NO11BE; 12884 } 12885 #else 12886 static void convert_11be_phybitmap_to_reg_flags(uint32_t target_phybitmap, 12887 uint32_t *phybitmap) 12888 { 12889 } 12890 #endif 12891 12892 /* convert_phybitmap_tlv() - Convert WMI_REGULATORY_PHYBITMAP values sent by 12893 * target to host internal REGULATORY_PHYMODE values. 12894 * 12895 * @target_target_phybitmap: target phybitmap received in the message. 12896 * 12897 * Return: returns the host internal REGULATORY_PHYMODE. 12898 */ 12899 static uint32_t convert_phybitmap_tlv(uint32_t target_phybitmap) 12900 { 12901 uint32_t phybitmap = 0; 12902 12903 wmi_debug("Target phybitmap: 0x%x", target_phybitmap); 12904 12905 if (target_phybitmap & WMI_REGULATORY_PHYMODE_NO11A) 12906 phybitmap |= REGULATORY_PHYMODE_NO11A; 12907 12908 if (target_phybitmap & WMI_REGULATORY_PHYMODE_NO11B) 12909 phybitmap |= REGULATORY_PHYMODE_NO11B; 12910 12911 if (target_phybitmap & WMI_REGULATORY_PHYMODE_NO11G) 12912 phybitmap |= REGULATORY_PHYMODE_NO11G; 12913 12914 if (target_phybitmap & WMI_REGULATORY_PHYMODE_NO11N) 12915 phybitmap |= REGULATORY_CHAN_NO11N; 12916 12917 if (target_phybitmap & WMI_REGULATORY_PHYMODE_NO11AC) 12918 phybitmap |= REGULATORY_PHYMODE_NO11AC; 12919 12920 if (target_phybitmap & WMI_REGULATORY_PHYMODE_NO11AX) 12921 phybitmap |= REGULATORY_PHYMODE_NO11AX; 12922 12923 convert_11be_phybitmap_to_reg_flags(target_phybitmap, &phybitmap); 12924 12925 return phybitmap; 12926 } 12927 12928 /** 12929 * convert_11be_flags_to_modes_ext() - Convert 11BE wireless mode flag 12930 * advertised by the target to wireless mode ext flags. 12931 * @target_wireless_modes_ext: Target wireless mode 12932 * @wireless_modes_ext: Variable to hold all the target wireless mode caps. 12933 * 12934 * Return: None 12935 */ 12936 #ifdef WLAN_FEATURE_11BE 12937 static void convert_11be_flags_to_modes_ext(uint32_t target_wireless_modes_ext, 12938 uint64_t *wireless_modes_ext) 12939 { 12940 if (target_wireless_modes_ext & REGDMN_MODE_U32_11BEG_EHT20) 12941 *wireless_modes_ext |= HOST_REGDMN_MODE_11BEG_EHT20; 12942 12943 if (target_wireless_modes_ext & REGDMN_MODE_U32_11BEG_EHT40PLUS) 12944 *wireless_modes_ext |= HOST_REGDMN_MODE_11BEG_EHT40PLUS; 12945 12946 if (target_wireless_modes_ext & REGDMN_MODE_U32_11BEG_EHT40MINUS) 12947 *wireless_modes_ext |= HOST_REGDMN_MODE_11BEG_EHT40MINUS; 12948 12949 if (target_wireless_modes_ext & REGDMN_MODE_U32_11BEA_EHT20) 12950 *wireless_modes_ext |= HOST_REGDMN_MODE_11BEA_EHT20; 12951 12952 if (target_wireless_modes_ext & REGDMN_MODE_U32_11BEA_EHT40PLUS) 12953 *wireless_modes_ext |= HOST_REGDMN_MODE_11BEA_EHT40PLUS; 12954 12955 if (target_wireless_modes_ext & REGDMN_MODE_U32_11BEA_EHT40MINUS) 12956 *wireless_modes_ext |= HOST_REGDMN_MODE_11BEA_EHT40MINUS; 12957 12958 if (target_wireless_modes_ext & REGDMN_MODE_U32_11BEA_EHT80) 12959 *wireless_modes_ext |= HOST_REGDMN_MODE_11BEA_EHT80; 12960 12961 if (target_wireless_modes_ext & REGDMN_MODE_U32_11BEA_EHT160) 12962 *wireless_modes_ext |= HOST_REGDMN_MODE_11BEA_EHT160; 12963 12964 if (target_wireless_modes_ext & REGDMN_MODE_U32_11BEA_EHT320) 12965 *wireless_modes_ext |= HOST_REGDMN_MODE_11BEA_EHT320; 12966 } 12967 #else 12968 static void convert_11be_flags_to_modes_ext(uint32_t target_wireless_modes_ext, 12969 uint64_t *wireless_modes_ext) 12970 { 12971 } 12972 #endif 12973 12974 static inline uint64_t convert_wireless_modes_ext_tlv( 12975 uint32_t target_wireless_modes_ext) 12976 { 12977 uint64_t wireless_modes_ext = 0; 12978 12979 wmi_debug("Target wireless mode: 0x%x", target_wireless_modes_ext); 12980 12981 if (target_wireless_modes_ext & REGDMN_MODE_U32_11AXG_HE20) 12982 wireless_modes_ext |= HOST_REGDMN_MODE_11AXG_HE20; 12983 12984 if (target_wireless_modes_ext & REGDMN_MODE_U32_11AXG_HE40PLUS) 12985 wireless_modes_ext |= HOST_REGDMN_MODE_11AXG_HE40PLUS; 12986 12987 if (target_wireless_modes_ext & REGDMN_MODE_U32_11AXG_HE40MINUS) 12988 wireless_modes_ext |= HOST_REGDMN_MODE_11AXG_HE40MINUS; 12989 12990 if (target_wireless_modes_ext & REGDMN_MODE_U32_11AXA_HE20) 12991 wireless_modes_ext |= HOST_REGDMN_MODE_11AXA_HE20; 12992 12993 if (target_wireless_modes_ext & REGDMN_MODE_U32_11AXA_HE40PLUS) 12994 wireless_modes_ext |= HOST_REGDMN_MODE_11AXA_HE40PLUS; 12995 12996 if (target_wireless_modes_ext & REGDMN_MODE_U32_11AXA_HE40MINUS) 12997 wireless_modes_ext |= HOST_REGDMN_MODE_11AXA_HE40MINUS; 12998 12999 if (target_wireless_modes_ext & REGDMN_MODE_U32_11AXA_HE80) 13000 wireless_modes_ext |= HOST_REGDMN_MODE_11AXA_HE80; 13001 13002 if (target_wireless_modes_ext & REGDMN_MODE_U32_11AXA_HE160) 13003 wireless_modes_ext |= HOST_REGDMN_MODE_11AXA_HE160; 13004 13005 if (target_wireless_modes_ext & REGDMN_MODE_U32_11AXA_HE80_80) 13006 wireless_modes_ext |= HOST_REGDMN_MODE_11AXA_HE80_80; 13007 13008 convert_11be_flags_to_modes_ext(target_wireless_modes_ext, 13009 &wireless_modes_ext); 13010 13011 return wireless_modes_ext; 13012 } 13013 13014 /** 13015 * extract_hal_reg_cap_tlv() - extract HAL registered capabilities 13016 * @wmi_handle: wmi handle 13017 * @evt_buf: Pointer to event buffer 13018 * @cap: pointer to hold HAL reg capabilities 13019 * 13020 * Return: QDF_STATUS_SUCCESS for success or error code 13021 */ 13022 static QDF_STATUS extract_hal_reg_cap_tlv(wmi_unified_t wmi_handle, 13023 void *evt_buf, struct wlan_psoc_hal_reg_capability *cap) 13024 { 13025 WMI_SERVICE_READY_EVENTID_param_tlvs *param_buf; 13026 13027 param_buf = (WMI_SERVICE_READY_EVENTID_param_tlvs *) evt_buf; 13028 if (!param_buf || !param_buf->hal_reg_capabilities) { 13029 wmi_err("Invalid arguments"); 13030 return QDF_STATUS_E_FAILURE; 13031 } 13032 qdf_mem_copy(cap, (((uint8_t *)param_buf->hal_reg_capabilities) + 13033 sizeof(uint32_t)), 13034 sizeof(struct wlan_psoc_hal_reg_capability)); 13035 13036 cap->wireless_modes = convert_wireless_modes_tlv( 13037 param_buf->hal_reg_capabilities->wireless_modes); 13038 13039 return QDF_STATUS_SUCCESS; 13040 } 13041 13042 /** 13043 * extract_hal_reg_cap_ext2_tlv() - extract HAL registered capability ext 13044 * @wmi_handle: wmi handle 13045 * @evt_buf: Pointer to event buffer 13046 * @phy_idx: Specific phy to extract 13047 * @param: pointer to hold HAL reg capabilities 13048 * 13049 * Return: QDF_STATUS_SUCCESS for success or error code 13050 */ 13051 static QDF_STATUS extract_hal_reg_cap_ext2_tlv( 13052 wmi_unified_t wmi_handle, void *evt_buf, uint8_t phy_idx, 13053 struct wlan_psoc_host_hal_reg_capabilities_ext2 *param) 13054 { 13055 WMI_SERVICE_READY_EXT2_EVENTID_param_tlvs *param_buf; 13056 WMI_HAL_REG_CAPABILITIES_EXT2 *reg_caps; 13057 13058 if (!evt_buf) { 13059 wmi_err("null evt_buf"); 13060 return QDF_STATUS_E_INVAL; 13061 } 13062 13063 param_buf = (WMI_SERVICE_READY_EXT2_EVENTID_param_tlvs *)evt_buf; 13064 13065 if (!param_buf->num_hal_reg_caps) 13066 return QDF_STATUS_SUCCESS; 13067 13068 if (phy_idx >= param_buf->num_hal_reg_caps) 13069 return QDF_STATUS_E_INVAL; 13070 13071 reg_caps = ¶m_buf->hal_reg_caps[phy_idx]; 13072 13073 param->phy_id = reg_caps->phy_id; 13074 param->wireless_modes_ext = convert_wireless_modes_ext_tlv( 13075 reg_caps->wireless_modes_ext); 13076 param->low_2ghz_chan_ext = reg_caps->low_2ghz_chan_ext; 13077 param->high_2ghz_chan_ext = reg_caps->high_2ghz_chan_ext; 13078 param->low_5ghz_chan_ext = reg_caps->low_5ghz_chan_ext; 13079 param->high_5ghz_chan_ext = reg_caps->high_5ghz_chan_ext; 13080 13081 return QDF_STATUS_SUCCESS; 13082 } 13083 13084 /** 13085 * extract_num_mem_reqs_tlv() - Extract number of memory entries requested 13086 * @wmi_handle: wmi handle 13087 * @evt_buf: pointer to event buffer 13088 * 13089 * Return: Number of entries requested 13090 */ 13091 static uint32_t extract_num_mem_reqs_tlv(wmi_unified_t wmi_handle, 13092 void *evt_buf) 13093 { 13094 WMI_SERVICE_READY_EVENTID_param_tlvs *param_buf; 13095 wmi_service_ready_event_fixed_param *ev; 13096 13097 param_buf = (WMI_SERVICE_READY_EVENTID_param_tlvs *) evt_buf; 13098 13099 ev = (wmi_service_ready_event_fixed_param *) param_buf->fixed_param; 13100 if (!ev) { 13101 qdf_print("%s: wmi_buf_alloc failed", __func__); 13102 return 0; 13103 } 13104 13105 if (ev->num_mem_reqs > param_buf->num_mem_reqs) { 13106 wmi_err("Invalid num_mem_reqs %d:%d", 13107 ev->num_mem_reqs, param_buf->num_mem_reqs); 13108 return 0; 13109 } 13110 13111 return ev->num_mem_reqs; 13112 } 13113 13114 /** 13115 * extract_host_mem_req_tlv() - Extract host memory required from 13116 * service ready event 13117 * @wmi_handle: wmi handle 13118 * @evt_buf: pointer to event buffer 13119 * @mem_reqs: pointer to host memory request structure 13120 * @num_active_peers: number of active peers for peer cache 13121 * @num_peers: number of peers 13122 * @fw_prio: FW priority 13123 * @idx: index for memory request 13124 * 13125 * Return: Host memory request parameters requested by target 13126 */ 13127 static QDF_STATUS extract_host_mem_req_tlv(wmi_unified_t wmi_handle, 13128 void *evt_buf, 13129 host_mem_req *mem_reqs, 13130 uint32_t num_active_peers, 13131 uint32_t num_peers, 13132 enum wmi_fw_mem_prio fw_prio, 13133 uint16_t idx) 13134 { 13135 WMI_SERVICE_READY_EVENTID_param_tlvs *param_buf; 13136 13137 param_buf = (WMI_SERVICE_READY_EVENTID_param_tlvs *)evt_buf; 13138 13139 mem_reqs->req_id = (uint32_t)param_buf->mem_reqs[idx].req_id; 13140 mem_reqs->unit_size = (uint32_t)param_buf->mem_reqs[idx].unit_size; 13141 mem_reqs->num_unit_info = 13142 (uint32_t)param_buf->mem_reqs[idx].num_unit_info; 13143 mem_reqs->num_units = (uint32_t)param_buf->mem_reqs[idx].num_units; 13144 mem_reqs->tgt_num_units = 0; 13145 13146 if (((fw_prio == WMI_FW_MEM_HIGH_PRIORITY) && 13147 (mem_reqs->num_unit_info & 13148 REQ_TO_HOST_FOR_CONT_MEMORY)) || 13149 ((fw_prio == WMI_FW_MEM_LOW_PRIORITY) && 13150 (!(mem_reqs->num_unit_info & 13151 REQ_TO_HOST_FOR_CONT_MEMORY)))) { 13152 /* First allocate the memory that requires contiguous memory */ 13153 mem_reqs->tgt_num_units = mem_reqs->num_units; 13154 if (mem_reqs->num_unit_info) { 13155 if (mem_reqs->num_unit_info & 13156 NUM_UNITS_IS_NUM_PEERS) { 13157 /* 13158 * number of units allocated is equal to number 13159 * of peers, 1 extra for self peer on target. 13160 * this needs to be fixed, host and target can 13161 * get out of sync 13162 */ 13163 mem_reqs->tgt_num_units = num_peers + 1; 13164 } 13165 if (mem_reqs->num_unit_info & 13166 NUM_UNITS_IS_NUM_ACTIVE_PEERS) { 13167 /* 13168 * Requesting allocation of memory using 13169 * num_active_peers in qcache. if qcache is 13170 * disabled in host, then it should allocate 13171 * memory for num_peers instead of 13172 * num_active_peers. 13173 */ 13174 if (num_active_peers) 13175 mem_reqs->tgt_num_units = 13176 num_active_peers + 1; 13177 else 13178 mem_reqs->tgt_num_units = 13179 num_peers + 1; 13180 } 13181 } 13182 13183 wmi_debug("idx %d req %d num_units %d num_unit_info %d" 13184 "unit size %d actual units %d", 13185 idx, mem_reqs->req_id, 13186 mem_reqs->num_units, 13187 mem_reqs->num_unit_info, 13188 mem_reqs->unit_size, 13189 mem_reqs->tgt_num_units); 13190 } 13191 13192 return QDF_STATUS_SUCCESS; 13193 } 13194 13195 /** 13196 * save_fw_version_in_service_ready_tlv() - Save fw version in service 13197 * ready function 13198 * @wmi_handle: wmi handle 13199 * @evt_buf: pointer to event buffer 13200 * 13201 * Return: QDF_STATUS_SUCCESS for success or error code 13202 */ 13203 static QDF_STATUS 13204 save_fw_version_in_service_ready_tlv(wmi_unified_t wmi_handle, void *evt_buf) 13205 { 13206 WMI_SERVICE_READY_EVENTID_param_tlvs *param_buf; 13207 wmi_service_ready_event_fixed_param *ev; 13208 13209 13210 param_buf = (WMI_SERVICE_READY_EVENTID_param_tlvs *) evt_buf; 13211 13212 ev = (wmi_service_ready_event_fixed_param *) param_buf->fixed_param; 13213 if (!ev) { 13214 qdf_print("%s: wmi_buf_alloc failed", __func__); 13215 return QDF_STATUS_E_FAILURE; 13216 } 13217 13218 /*Save fw version from service ready message */ 13219 /*This will be used while sending INIT message */ 13220 qdf_mem_copy(&wmi_handle->fw_abi_version, &ev->fw_abi_vers, 13221 sizeof(wmi_handle->fw_abi_version)); 13222 13223 return QDF_STATUS_SUCCESS; 13224 } 13225 13226 /** 13227 * ready_extract_init_status_tlv() - Extract init status from ready event 13228 * @wmi_handle: wmi handle 13229 * @evt_buf: Pointer to event buffer 13230 * 13231 * Return: ready status 13232 */ 13233 static uint32_t ready_extract_init_status_tlv(wmi_unified_t wmi_handle, 13234 void *evt_buf) 13235 { 13236 WMI_READY_EVENTID_param_tlvs *param_buf = NULL; 13237 wmi_ready_event_fixed_param *ev = NULL; 13238 13239 param_buf = (WMI_READY_EVENTID_param_tlvs *) evt_buf; 13240 ev = param_buf->fixed_param; 13241 13242 wmi_info("%s:%d", __func__, ev->status); 13243 13244 return ev->status; 13245 } 13246 13247 /** 13248 * ready_extract_mac_addr_tlv() - extract mac address from ready event 13249 * @wmi_handle: wmi handle 13250 * @evt_buf: pointer to event buffer 13251 * @macaddr: Pointer to hold MAC address 13252 * 13253 * Return: QDF_STATUS_SUCCESS for success or error code 13254 */ 13255 static QDF_STATUS ready_extract_mac_addr_tlv(wmi_unified_t wmi_handle, 13256 void *evt_buf, uint8_t *macaddr) 13257 { 13258 WMI_READY_EVENTID_param_tlvs *param_buf = NULL; 13259 wmi_ready_event_fixed_param *ev = NULL; 13260 13261 13262 param_buf = (WMI_READY_EVENTID_param_tlvs *) evt_buf; 13263 ev = param_buf->fixed_param; 13264 13265 WMI_MAC_ADDR_TO_CHAR_ARRAY(&ev->mac_addr, macaddr); 13266 13267 return QDF_STATUS_SUCCESS; 13268 } 13269 13270 /** 13271 * ready_extract_mac_addr_list_tlv() - extract MAC address list from ready event 13272 * @wmi_handle: wmi handle 13273 * @evt_buf: pointer to event buffer 13274 * @num_mac: Pointer to hold number of MAC addresses 13275 * 13276 * Return: Pointer to addr list 13277 */ 13278 static wmi_host_mac_addr * 13279 ready_extract_mac_addr_list_tlv(wmi_unified_t wmi_handle, 13280 void *evt_buf, uint8_t *num_mac) 13281 { 13282 WMI_READY_EVENTID_param_tlvs *param_buf = NULL; 13283 wmi_ready_event_fixed_param *ev = NULL; 13284 13285 param_buf = (WMI_READY_EVENTID_param_tlvs *) evt_buf; 13286 ev = param_buf->fixed_param; 13287 13288 *num_mac = ev->num_extra_mac_addr; 13289 13290 return (wmi_host_mac_addr *) param_buf->mac_addr_list; 13291 } 13292 13293 /** 13294 * extract_ready_event_params_tlv() - Extract data from ready event apart from 13295 * status, macaddr and version. 13296 * @wmi_handle: Pointer to WMI handle. 13297 * @evt_buf: Pointer to Ready event buffer. 13298 * @ev_param: Pointer to host defined struct to copy the data from event. 13299 * 13300 * Return: QDF_STATUS_SUCCESS on success. 13301 */ 13302 static QDF_STATUS extract_ready_event_params_tlv(wmi_unified_t wmi_handle, 13303 void *evt_buf, struct wmi_host_ready_ev_param *ev_param) 13304 { 13305 WMI_READY_EVENTID_param_tlvs *param_buf = NULL; 13306 wmi_ready_event_fixed_param *ev = NULL; 13307 13308 param_buf = (WMI_READY_EVENTID_param_tlvs *) evt_buf; 13309 ev = param_buf->fixed_param; 13310 13311 ev_param->status = ev->status; 13312 ev_param->num_dscp_table = ev->num_dscp_table; 13313 ev_param->num_extra_mac_addr = ev->num_extra_mac_addr; 13314 ev_param->num_total_peer = ev->num_total_peers; 13315 ev_param->num_extra_peer = ev->num_extra_peers; 13316 /* Agile_capability in ready event is supported in TLV target, 13317 * as per aDFS FR 13318 */ 13319 ev_param->max_ast_index = ev->max_ast_index; 13320 ev_param->pktlog_defs_checksum = ev->pktlog_defs_checksum; 13321 ev_param->agile_capability = 1; 13322 ev_param->num_max_active_vdevs = ev->num_max_active_vdevs; 13323 13324 return QDF_STATUS_SUCCESS; 13325 } 13326 13327 /** 13328 * extract_dbglog_data_len_tlv() - extract debuglog data length 13329 * @wmi_handle: wmi handle 13330 * @evt_buf: pointer to event buffer 13331 * @len: length of the log 13332 * 13333 * Return: pointer to the debug log 13334 */ 13335 static uint8_t *extract_dbglog_data_len_tlv(wmi_unified_t wmi_handle, 13336 void *evt_buf, uint32_t *len) 13337 { 13338 WMI_DEBUG_MESG_EVENTID_param_tlvs *param_buf; 13339 13340 param_buf = (WMI_DEBUG_MESG_EVENTID_param_tlvs *) evt_buf; 13341 13342 *len = param_buf->num_bufp; 13343 13344 return param_buf->bufp; 13345 } 13346 13347 13348 #ifdef MGMT_FRAME_RX_DECRYPT_ERROR 13349 #define IS_WMI_RX_MGMT_FRAME_STATUS_INVALID(_status) false 13350 #else 13351 #define IS_WMI_RX_MGMT_FRAME_STATUS_INVALID(_status) \ 13352 ((_status) & WMI_RXERR_DECRYPT) 13353 #endif 13354 13355 /** 13356 * extract_mgmt_rx_params_tlv() - extract management rx params from event 13357 * @wmi_handle: wmi handle 13358 * @evt_buf: pointer to event buffer 13359 * @hdr: Pointer to hold header 13360 * @bufp: Pointer to hold pointer to rx param buffer 13361 * 13362 * Return: QDF_STATUS_SUCCESS for success or error code 13363 */ 13364 static QDF_STATUS extract_mgmt_rx_params_tlv(wmi_unified_t wmi_handle, 13365 void *evt_buf, struct mgmt_rx_event_params *hdr, 13366 uint8_t **bufp) 13367 { 13368 WMI_MGMT_RX_EVENTID_param_tlvs *param_tlvs = NULL; 13369 wmi_mgmt_rx_hdr *ev_hdr = NULL; 13370 int i; 13371 13372 param_tlvs = (WMI_MGMT_RX_EVENTID_param_tlvs *) evt_buf; 13373 if (!param_tlvs) { 13374 wmi_err_rl("Get NULL point message from FW"); 13375 return QDF_STATUS_E_INVAL; 13376 } 13377 13378 ev_hdr = param_tlvs->hdr; 13379 if (!hdr) { 13380 wmi_err_rl("Rx event is NULL"); 13381 return QDF_STATUS_E_INVAL; 13382 } 13383 13384 if (IS_WMI_RX_MGMT_FRAME_STATUS_INVALID(ev_hdr->status)) { 13385 wmi_err_rl("RX mgmt frame decrypt error, discard it"); 13386 return QDF_STATUS_E_INVAL; 13387 } 13388 if ((ev_hdr->status) & WMI_RXERR_MIC) { 13389 wmi_err_rl("RX mgmt frame MIC mismatch for beacon protected frame"); 13390 } 13391 13392 if (ev_hdr->buf_len > param_tlvs->num_bufp) { 13393 wmi_err_rl("Rx mgmt frame length mismatch, discard it"); 13394 return QDF_STATUS_E_INVAL; 13395 } 13396 13397 hdr->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host( 13398 wmi_handle, 13399 ev_hdr->pdev_id); 13400 hdr->chan_freq = ev_hdr->chan_freq; 13401 hdr->channel = ev_hdr->channel; 13402 hdr->snr = ev_hdr->snr; 13403 hdr->rate = ev_hdr->rate; 13404 hdr->phy_mode = ev_hdr->phy_mode; 13405 hdr->buf_len = ev_hdr->buf_len; 13406 hdr->status = ev_hdr->status; 13407 hdr->flags = ev_hdr->flags; 13408 hdr->rssi = ev_hdr->rssi; 13409 hdr->tsf_delta = ev_hdr->tsf_delta; 13410 hdr->tsf_l32 = ev_hdr->rx_tsf_l32; 13411 for (i = 0; i < ATH_MAX_ANTENNA; i++) 13412 hdr->rssi_ctl[i] = ev_hdr->rssi_ctl[i]; 13413 13414 *bufp = param_tlvs->bufp; 13415 13416 extract_mgmt_rx_mlo_link_removal_tlv_count( 13417 param_tlvs->num_link_removal_tbtt_count, hdr); 13418 13419 return QDF_STATUS_SUCCESS; 13420 } 13421 13422 static QDF_STATUS extract_mgmt_rx_ext_params_tlv(wmi_unified_t wmi_handle, 13423 void *evt_buf, struct mgmt_rx_event_ext_params *ext_params) 13424 { 13425 WMI_MGMT_RX_EVENTID_param_tlvs *param_tlvs; 13426 wmi_mgmt_rx_params_ext *ext_params_tlv; 13427 wmi_mgmt_rx_hdr *ev_hdr; 13428 wmi_mgmt_rx_params_ext_meta_t meta_id; 13429 uint8_t *ie_data; 13430 13431 /* initialize to zero and set it only if tlv has valid meta data */ 13432 ext_params->u.addba.ba_win_size = 0; 13433 ext_params->u.addba.reo_win_size = 0; 13434 13435 param_tlvs = (WMI_MGMT_RX_EVENTID_param_tlvs *) evt_buf; 13436 if (!param_tlvs) { 13437 wmi_err("param_tlvs is NULL"); 13438 return QDF_STATUS_E_INVAL; 13439 } 13440 13441 ev_hdr = param_tlvs->hdr; 13442 if (!ev_hdr) { 13443 wmi_err("Rx event is NULL"); 13444 return QDF_STATUS_E_INVAL; 13445 } 13446 13447 ext_params_tlv = param_tlvs->mgmt_rx_params_ext; 13448 if (ext_params_tlv) { 13449 meta_id = WMI_RX_PARAM_EXT_META_ID_GET( 13450 ext_params_tlv->mgmt_rx_params_ext_dword0); 13451 if (meta_id == WMI_RX_PARAMS_EXT_META_ADDBA) { 13452 ext_params->meta_id = MGMT_RX_PARAMS_EXT_META_ADDBA; 13453 ext_params->u.addba.ba_win_size = 13454 WMI_RX_PARAM_EXT_BA_WIN_SIZE_GET( 13455 ext_params_tlv->mgmt_rx_params_ext_dword1); 13456 if (ext_params->u.addba.ba_win_size > 1024) { 13457 wmi_info("ba win size %d from TLV is Invalid", 13458 ext_params->u.addba.ba_win_size); 13459 return QDF_STATUS_E_INVAL; 13460 } 13461 13462 ext_params->u.addba.reo_win_size = 13463 WMI_RX_PARAM_EXT_REO_WIN_SIZE_GET( 13464 ext_params_tlv->mgmt_rx_params_ext_dword1); 13465 if (ext_params->u.addba.reo_win_size > 2048) { 13466 wmi_info("reo win size %d from TLV is Invalid", 13467 ext_params->u.addba.reo_win_size); 13468 return QDF_STATUS_E_INVAL; 13469 } 13470 } 13471 if (meta_id == WMI_RX_PARAMS_EXT_META_TWT) { 13472 ext_params->meta_id = MGMT_RX_PARAMS_EXT_META_TWT; 13473 ext_params->u.twt.ie_len = 13474 ext_params_tlv->twt_ie_buf_len; 13475 ie_data = param_tlvs->ie_data; 13476 if (ext_params->u.twt.ie_len && 13477 (ext_params->u.twt.ie_len < 13478 MAX_TWT_IE_RX_PARAMS_LEN)) { 13479 qdf_mem_copy(ext_params->u.twt.ie_data, 13480 ie_data, 13481 ext_params_tlv->twt_ie_buf_len); 13482 } 13483 } 13484 } 13485 13486 return QDF_STATUS_SUCCESS; 13487 } 13488 13489 #ifdef WLAN_MGMT_RX_REO_SUPPORT 13490 /** 13491 * extract_mgmt_rx_fw_consumed_tlv() - extract MGMT Rx FW consumed event 13492 * @wmi_handle: wmi handle 13493 * @evt_buf: pointer to event buffer 13494 * @params: Pointer to MGMT Rx REO parameters 13495 * 13496 * Return: QDF_STATUS_SUCCESS for success or error code 13497 */ 13498 static QDF_STATUS 13499 extract_mgmt_rx_fw_consumed_tlv(wmi_unified_t wmi_handle, 13500 void *evt_buf, 13501 struct mgmt_rx_reo_params *params) 13502 { 13503 WMI_MGMT_RX_FW_CONSUMED_EVENTID_param_tlvs *param_tlvs; 13504 wmi_mgmt_rx_fw_consumed_hdr *ev_hdr; 13505 13506 param_tlvs = evt_buf; 13507 if (!param_tlvs) { 13508 wmi_err("param_tlvs is NULL"); 13509 return QDF_STATUS_E_INVAL; 13510 } 13511 13512 ev_hdr = param_tlvs->hdr; 13513 if (!params) { 13514 wmi_err("Rx REO parameters is NULL"); 13515 return QDF_STATUS_E_INVAL; 13516 } 13517 13518 params->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host( 13519 wmi_handle, 13520 ev_hdr->pdev_id); 13521 params->valid = WMI_MGMT_RX_FW_CONSUMED_PARAM_MGMT_PKT_CTR_VALID_GET( 13522 ev_hdr->mgmt_pkt_ctr_info); 13523 params->global_timestamp = ev_hdr->global_timestamp; 13524 params->mgmt_pkt_ctr = WMI_MGMT_RX_FW_CONSUMED_PARAM_MGMT_PKT_CTR_GET( 13525 ev_hdr->mgmt_pkt_ctr_info); 13526 params->duration_us = ev_hdr->rx_ppdu_duration_us; 13527 params->start_timestamp = params->global_timestamp; 13528 params->end_timestamp = params->start_timestamp + 13529 params->duration_us; 13530 13531 return QDF_STATUS_SUCCESS; 13532 } 13533 13534 /** 13535 * extract_mgmt_rx_reo_params_tlv() - extract MGMT Rx REO params from 13536 * MGMT_RX_EVENT_ID 13537 * @wmi_handle: wmi handle 13538 * @evt_buf: pointer to event buffer 13539 * @reo_params: Pointer to MGMT Rx REO parameters 13540 * 13541 * Return: QDF_STATUS_SUCCESS for success or error code 13542 */ 13543 static QDF_STATUS extract_mgmt_rx_reo_params_tlv(wmi_unified_t wmi_handle, 13544 void *evt_buf, struct mgmt_rx_reo_params *reo_params) 13545 { 13546 WMI_MGMT_RX_EVENTID_param_tlvs *param_tlvs; 13547 wmi_mgmt_rx_reo_params *reo_params_tlv; 13548 wmi_mgmt_rx_hdr *ev_hdr; 13549 13550 param_tlvs = evt_buf; 13551 if (!param_tlvs) { 13552 wmi_err("param_tlvs is NULL"); 13553 return QDF_STATUS_E_INVAL; 13554 } 13555 13556 ev_hdr = param_tlvs->hdr; 13557 if (!ev_hdr) { 13558 wmi_err("Rx event is NULL"); 13559 return QDF_STATUS_E_INVAL; 13560 } 13561 13562 reo_params_tlv = param_tlvs->reo_params; 13563 if (!reo_params_tlv) { 13564 wmi_err("mgmt_rx_reo_params TLV is not sent by FW"); 13565 return QDF_STATUS_E_INVAL; 13566 } 13567 13568 if (!reo_params) { 13569 wmi_err("MGMT Rx REO params is NULL"); 13570 return QDF_STATUS_E_INVAL; 13571 } 13572 13573 reo_params->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host( 13574 wmi_handle, 13575 ev_hdr->pdev_id); 13576 reo_params->valid = WMI_MGMT_RX_REO_PARAM_MGMT_PKT_CTR_VALID_GET( 13577 reo_params_tlv->mgmt_pkt_ctr_link_info); 13578 reo_params->global_timestamp = reo_params_tlv->global_timestamp; 13579 reo_params->mgmt_pkt_ctr = WMI_MGMT_RX_REO_PARAM_MGMT_PKT_CTR_GET( 13580 reo_params_tlv->mgmt_pkt_ctr_link_info); 13581 reo_params->duration_us = reo_params_tlv->rx_ppdu_duration_us; 13582 reo_params->start_timestamp = reo_params->global_timestamp; 13583 reo_params->end_timestamp = reo_params->start_timestamp + 13584 reo_params->duration_us; 13585 13586 return QDF_STATUS_SUCCESS; 13587 } 13588 13589 /** 13590 * send_mgmt_rx_reo_filter_config_cmd_tlv() - Send MGMT Rx REO filter 13591 * configuration command 13592 * @wmi_handle: wmi handle 13593 * @pdev_id: pdev ID of the radio 13594 * @filter: Pointer to MGMT Rx REO filter 13595 * 13596 * Return: QDF_STATUS_SUCCESS for success or error code 13597 */ 13598 static QDF_STATUS send_mgmt_rx_reo_filter_config_cmd_tlv( 13599 wmi_unified_t wmi_handle, 13600 uint8_t pdev_id, 13601 struct mgmt_rx_reo_filter *filter) 13602 { 13603 QDF_STATUS ret; 13604 wmi_buf_t buf; 13605 wmi_mgmt_rx_reo_filter_configuration_cmd_fixed_param *cmd; 13606 size_t len = sizeof(*cmd); 13607 13608 if (!filter) { 13609 wmi_err("mgmt_rx_reo_filter is NULL"); 13610 return QDF_STATUS_E_INVAL; 13611 } 13612 13613 buf = wmi_buf_alloc(wmi_handle, len); 13614 if (!buf) { 13615 wmi_err("wmi_buf_alloc failed"); 13616 return QDF_STATUS_E_NOMEM; 13617 } 13618 13619 cmd = (wmi_mgmt_rx_reo_filter_configuration_cmd_fixed_param *) 13620 wmi_buf_data(buf); 13621 13622 WMITLV_SET_HDR(&cmd->tlv_header, 13623 WMITLV_TAG_STRUC_wmi_mgmt_rx_reo_filter_configuration_cmd_fixed_param, 13624 WMITLV_GET_STRUCT_TLVLEN(wmi_mgmt_rx_reo_filter_configuration_cmd_fixed_param)); 13625 13626 cmd->pdev_id = wmi_handle->ops->convert_host_pdev_id_to_target( 13627 wmi_handle, 13628 pdev_id); 13629 cmd->filter_low = filter->low; 13630 cmd->filter_high = filter->high; 13631 13632 wmi_mtrace(WMI_MGMT_RX_REO_FILTER_CONFIGURATION_CMDID, NO_SESSION, 0); 13633 ret = wmi_unified_cmd_send( 13634 wmi_handle, buf, len, 13635 WMI_MGMT_RX_REO_FILTER_CONFIGURATION_CMDID); 13636 13637 if (QDF_IS_STATUS_ERROR(ret)) { 13638 wmi_err("Failed to send WMI command"); 13639 wmi_buf_free(buf); 13640 } 13641 13642 return ret; 13643 } 13644 #endif 13645 13646 /** 13647 * extract_frame_pn_params_tlv() - extract PN params from event 13648 * @wmi_handle: wmi handle 13649 * @evt_buf: pointer to event buffer 13650 * @pn_params: Pointer to Frame PN params 13651 * 13652 * Return: QDF_STATUS_SUCCESS for success or error code 13653 */ 13654 static QDF_STATUS extract_frame_pn_params_tlv(wmi_unified_t wmi_handle, 13655 void *evt_buf, 13656 struct frame_pn_params *pn_params) 13657 { 13658 WMI_MGMT_RX_EVENTID_param_tlvs *param_tlvs; 13659 wmi_frame_pn_params *pn_params_tlv; 13660 13661 if (!is_service_enabled_tlv(wmi_handle, 13662 WMI_SERVICE_PN_REPLAY_CHECK_SUPPORT)) 13663 return QDF_STATUS_SUCCESS; 13664 13665 param_tlvs = evt_buf; 13666 if (!param_tlvs) { 13667 wmi_err("Got NULL point message from FW"); 13668 return QDF_STATUS_E_INVAL; 13669 } 13670 13671 if (!pn_params) { 13672 wmi_err("PN Params is NULL"); 13673 return QDF_STATUS_E_INVAL; 13674 } 13675 13676 /* PN Params TLV will be populated only if WMI_RXERR_PN error is 13677 * found by target 13678 */ 13679 pn_params_tlv = param_tlvs->pn_params; 13680 if (!pn_params_tlv) 13681 return QDF_STATUS_SUCCESS; 13682 13683 qdf_mem_copy(pn_params->curr_pn, pn_params_tlv->cur_pn, 13684 sizeof(pn_params->curr_pn)); 13685 qdf_mem_copy(pn_params->prev_pn, pn_params_tlv->prev_pn, 13686 sizeof(pn_params->prev_pn)); 13687 13688 return QDF_STATUS_SUCCESS; 13689 } 13690 13691 /** 13692 * extract_is_conn_ap_frm_param_tlv() - extract is_conn_ap_frame param from 13693 * event 13694 * @wmi_handle: wmi handle 13695 * @evt_buf: pointer to event buffer 13696 * @is_conn_ap: Pointer for is_conn_ap frame 13697 * 13698 * Return: QDF_STATUS_SUCCESS for success or error code 13699 */ 13700 static QDF_STATUS extract_is_conn_ap_frm_param_tlv( 13701 wmi_unified_t wmi_handle, 13702 void *evt_buf, 13703 struct frm_conn_ap *is_conn_ap) 13704 { 13705 WMI_MGMT_RX_EVENTID_param_tlvs *param_tlvs; 13706 wmi_is_my_mgmt_frame *my_frame_tlv; 13707 13708 param_tlvs = evt_buf; 13709 if (!param_tlvs) { 13710 wmi_err("Got NULL point message from FW"); 13711 return QDF_STATUS_E_INVAL; 13712 } 13713 13714 if (!is_conn_ap) { 13715 wmi_err(" is connected ap param is NULL"); 13716 return QDF_STATUS_E_INVAL; 13717 } 13718 13719 my_frame_tlv = param_tlvs->my_frame; 13720 if (!my_frame_tlv) 13721 return QDF_STATUS_SUCCESS; 13722 13723 is_conn_ap->mgmt_frm_sub_type = my_frame_tlv->mgmt_frm_sub_type; 13724 is_conn_ap->is_conn_ap_frm = my_frame_tlv->is_my_frame; 13725 13726 return QDF_STATUS_SUCCESS; 13727 } 13728 13729 /** 13730 * extract_vdev_roam_param_tlv() - extract vdev roam param from event 13731 * @wmi_handle: wmi handle 13732 * @evt_buf: pointer to event buffer 13733 * @param: Pointer to hold roam param 13734 * 13735 * Return: QDF_STATUS_SUCCESS for success or error code 13736 */ 13737 static QDF_STATUS extract_vdev_roam_param_tlv(wmi_unified_t wmi_handle, 13738 void *evt_buf, wmi_host_roam_event *param) 13739 { 13740 WMI_ROAM_EVENTID_param_tlvs *param_buf; 13741 wmi_roam_event_fixed_param *evt; 13742 13743 param_buf = (WMI_ROAM_EVENTID_param_tlvs *) evt_buf; 13744 if (!param_buf) { 13745 wmi_err("Invalid roam event buffer"); 13746 return QDF_STATUS_E_INVAL; 13747 } 13748 13749 evt = param_buf->fixed_param; 13750 qdf_mem_zero(param, sizeof(*param)); 13751 13752 param->vdev_id = evt->vdev_id; 13753 param->reason = evt->reason; 13754 param->rssi = evt->rssi; 13755 13756 return QDF_STATUS_SUCCESS; 13757 } 13758 13759 /** 13760 * extract_vdev_scan_ev_param_tlv() - extract vdev scan param from event 13761 * @wmi_handle: wmi handle 13762 * @evt_buf: pointer to event buffer 13763 * @param: Pointer to hold vdev scan param 13764 * 13765 * Return: QDF_STATUS_SUCCESS for success or error code 13766 */ 13767 static QDF_STATUS extract_vdev_scan_ev_param_tlv(wmi_unified_t wmi_handle, 13768 void *evt_buf, struct scan_event *param) 13769 { 13770 WMI_SCAN_EVENTID_param_tlvs *param_buf = NULL; 13771 wmi_scan_event_fixed_param *evt = NULL; 13772 13773 param_buf = (WMI_SCAN_EVENTID_param_tlvs *) evt_buf; 13774 evt = param_buf->fixed_param; 13775 13776 qdf_mem_zero(param, sizeof(*param)); 13777 13778 switch (evt->event) { 13779 case WMI_SCAN_EVENT_STARTED: 13780 param->type = SCAN_EVENT_TYPE_STARTED; 13781 break; 13782 case WMI_SCAN_EVENT_COMPLETED: 13783 param->type = SCAN_EVENT_TYPE_COMPLETED; 13784 break; 13785 case WMI_SCAN_EVENT_BSS_CHANNEL: 13786 param->type = SCAN_EVENT_TYPE_BSS_CHANNEL; 13787 break; 13788 case WMI_SCAN_EVENT_FOREIGN_CHANNEL: 13789 param->type = SCAN_EVENT_TYPE_FOREIGN_CHANNEL; 13790 break; 13791 case WMI_SCAN_EVENT_DEQUEUED: 13792 param->type = SCAN_EVENT_TYPE_DEQUEUED; 13793 break; 13794 case WMI_SCAN_EVENT_PREEMPTED: 13795 param->type = SCAN_EVENT_TYPE_PREEMPTED; 13796 break; 13797 case WMI_SCAN_EVENT_START_FAILED: 13798 param->type = SCAN_EVENT_TYPE_START_FAILED; 13799 break; 13800 case WMI_SCAN_EVENT_RESTARTED: 13801 param->type = SCAN_EVENT_TYPE_RESTARTED; 13802 break; 13803 case WMI_SCAN_EVENT_FOREIGN_CHANNEL_EXIT: 13804 param->type = SCAN_EVENT_TYPE_FOREIGN_CHANNEL_EXIT; 13805 break; 13806 case WMI_SCAN_EVENT_MAX: 13807 default: 13808 param->type = SCAN_EVENT_TYPE_MAX; 13809 break; 13810 }; 13811 13812 switch (evt->reason) { 13813 case WMI_SCAN_REASON_NONE: 13814 param->reason = SCAN_REASON_NONE; 13815 break; 13816 case WMI_SCAN_REASON_COMPLETED: 13817 param->reason = SCAN_REASON_COMPLETED; 13818 break; 13819 case WMI_SCAN_REASON_CANCELLED: 13820 param->reason = SCAN_REASON_CANCELLED; 13821 break; 13822 case WMI_SCAN_REASON_PREEMPTED: 13823 param->reason = SCAN_REASON_PREEMPTED; 13824 break; 13825 case WMI_SCAN_REASON_TIMEDOUT: 13826 param->reason = SCAN_REASON_TIMEDOUT; 13827 break; 13828 case WMI_SCAN_REASON_INTERNAL_FAILURE: 13829 param->reason = SCAN_REASON_INTERNAL_FAILURE; 13830 break; 13831 case WMI_SCAN_REASON_SUSPENDED: 13832 param->reason = SCAN_REASON_SUSPENDED; 13833 break; 13834 case WMI_SCAN_REASON_DFS_VIOLATION: 13835 param->reason = SCAN_REASON_DFS_VIOLATION; 13836 break; 13837 case WMI_SCAN_REASON_MAX: 13838 param->reason = SCAN_REASON_MAX; 13839 break; 13840 default: 13841 param->reason = SCAN_REASON_MAX; 13842 break; 13843 }; 13844 13845 param->chan_freq = evt->channel_freq; 13846 param->requester = evt->requestor; 13847 param->scan_id = evt->scan_id; 13848 param->vdev_id = evt->vdev_id; 13849 param->timestamp = evt->tsf_timestamp; 13850 13851 return QDF_STATUS_SUCCESS; 13852 } 13853 13854 #ifdef FEATURE_WLAN_SCAN_PNO 13855 /** 13856 * extract_nlo_match_ev_param_tlv() - extract NLO match param from event 13857 * @wmi_handle: pointer to WMI handle 13858 * @evt_buf: pointer to WMI event buffer 13859 * @param: pointer to scan event param for NLO match 13860 * 13861 * Return: QDF_STATUS_SUCCESS for success or error code 13862 */ 13863 static QDF_STATUS extract_nlo_match_ev_param_tlv(wmi_unified_t wmi_handle, 13864 void *evt_buf, 13865 struct scan_event *param) 13866 { 13867 WMI_NLO_MATCH_EVENTID_param_tlvs *param_buf = evt_buf; 13868 wmi_nlo_event *evt = param_buf->fixed_param; 13869 13870 qdf_mem_zero(param, sizeof(*param)); 13871 13872 param->type = SCAN_EVENT_TYPE_NLO_MATCH; 13873 param->vdev_id = evt->vdev_id; 13874 13875 return QDF_STATUS_SUCCESS; 13876 } 13877 13878 /** 13879 * extract_nlo_complete_ev_param_tlv() - extract NLO complete param from event 13880 * @wmi_handle: pointer to WMI handle 13881 * @evt_buf: pointer to WMI event buffer 13882 * @param: pointer to scan event param for NLO complete 13883 * 13884 * Return: QDF_STATUS_SUCCESS for success or error code 13885 */ 13886 static QDF_STATUS extract_nlo_complete_ev_param_tlv(wmi_unified_t wmi_handle, 13887 void *evt_buf, 13888 struct scan_event *param) 13889 { 13890 WMI_NLO_SCAN_COMPLETE_EVENTID_param_tlvs *param_buf = evt_buf; 13891 wmi_nlo_event *evt = param_buf->fixed_param; 13892 13893 qdf_mem_zero(param, sizeof(*param)); 13894 13895 param->type = SCAN_EVENT_TYPE_NLO_COMPLETE; 13896 param->vdev_id = evt->vdev_id; 13897 13898 return QDF_STATUS_SUCCESS; 13899 } 13900 #endif 13901 13902 /** 13903 * extract_unit_test_tlv() - extract unit test data 13904 * @wmi_handle: wmi handle 13905 * @evt_buf: pointer to event buffer 13906 * @unit_test: pointer to hold unit test data 13907 * @maxspace: Amount of space in evt_buf 13908 * 13909 * Return: QDF_STATUS_SUCCESS for success or error code 13910 */ 13911 static QDF_STATUS extract_unit_test_tlv(wmi_unified_t wmi_handle, 13912 void *evt_buf, wmi_unit_test_event *unit_test, uint32_t maxspace) 13913 { 13914 WMI_UNIT_TEST_EVENTID_param_tlvs *param_buf; 13915 wmi_unit_test_event_fixed_param *ev_param; 13916 uint32_t num_bufp; 13917 uint32_t copy_size; 13918 uint8_t *bufp; 13919 13920 param_buf = (WMI_UNIT_TEST_EVENTID_param_tlvs *) evt_buf; 13921 ev_param = param_buf->fixed_param; 13922 bufp = param_buf->bufp; 13923 num_bufp = param_buf->num_bufp; 13924 unit_test->vdev_id = ev_param->vdev_id; 13925 unit_test->module_id = ev_param->module_id; 13926 unit_test->diag_token = ev_param->diag_token; 13927 unit_test->flag = ev_param->flag; 13928 unit_test->payload_len = ev_param->payload_len; 13929 wmi_debug("vdev_id:%d mod_id:%d diag_token:%d flag:%d", 13930 ev_param->vdev_id, 13931 ev_param->module_id, 13932 ev_param->diag_token, 13933 ev_param->flag); 13934 wmi_debug("Unit-test data given below %d", num_bufp); 13935 qdf_trace_hex_dump(QDF_MODULE_ID_WMI, QDF_TRACE_LEVEL_DEBUG, 13936 bufp, num_bufp); 13937 copy_size = (num_bufp < maxspace) ? num_bufp : maxspace; 13938 qdf_mem_copy(unit_test->buffer, bufp, copy_size); 13939 unit_test->buffer_len = copy_size; 13940 13941 return QDF_STATUS_SUCCESS; 13942 } 13943 13944 /** 13945 * extract_pdev_ext_stats_tlv() - extract extended pdev stats from event 13946 * @wmi_handle: wmi handle 13947 * @evt_buf: pointer to event buffer 13948 * @index: Index into extended pdev stats 13949 * @pdev_ext_stats: Pointer to hold extended pdev stats 13950 * 13951 * Return: QDF_STATUS_SUCCESS for success or error code 13952 */ 13953 static QDF_STATUS extract_pdev_ext_stats_tlv(wmi_unified_t wmi_handle, 13954 void *evt_buf, uint32_t index, wmi_host_pdev_ext_stats *pdev_ext_stats) 13955 { 13956 WMI_UPDATE_STATS_EVENTID_param_tlvs *param_buf; 13957 wmi_pdev_extd_stats *ev; 13958 13959 param_buf = evt_buf; 13960 if (!param_buf) 13961 return QDF_STATUS_E_FAILURE; 13962 13963 if (!param_buf->pdev_extd_stats) 13964 return QDF_STATUS_E_FAILURE; 13965 13966 ev = param_buf->pdev_extd_stats + index; 13967 13968 pdev_ext_stats->pdev_id = 13969 wmi_handle->ops->convert_target_pdev_id_to_host( 13970 wmi_handle, 13971 ev->pdev_id); 13972 pdev_ext_stats->my_rx_count = ev->my_rx_count; 13973 pdev_ext_stats->rx_matched_11ax_msdu_cnt = ev->rx_matched_11ax_msdu_cnt; 13974 pdev_ext_stats->rx_other_11ax_msdu_cnt = ev->rx_other_11ax_msdu_cnt; 13975 13976 return QDF_STATUS_SUCCESS; 13977 } 13978 13979 /** 13980 * extract_bcn_stats_tlv() - extract bcn stats from event 13981 * @wmi_handle: wmi handle 13982 * @evt_buf: pointer to event buffer 13983 * @index: Index into vdev stats 13984 * @bcn_stats: Pointer to hold bcn stats 13985 * 13986 * Return: QDF_STATUS_SUCCESS for success or error code 13987 */ 13988 static QDF_STATUS extract_bcn_stats_tlv(wmi_unified_t wmi_handle, 13989 void *evt_buf, uint32_t index, wmi_host_bcn_stats *bcn_stats) 13990 { 13991 WMI_UPDATE_STATS_EVENTID_param_tlvs *param_buf; 13992 wmi_stats_event_fixed_param *ev_param; 13993 uint8_t *data; 13994 13995 param_buf = (WMI_UPDATE_STATS_EVENTID_param_tlvs *) evt_buf; 13996 ev_param = (wmi_stats_event_fixed_param *) param_buf->fixed_param; 13997 data = (uint8_t *) param_buf->data; 13998 13999 if (index < ev_param->num_bcn_stats) { 14000 wmi_bcn_stats *ev = (wmi_bcn_stats *) ((data) + 14001 ((ev_param->num_pdev_stats) * sizeof(wmi_pdev_stats)) + 14002 ((ev_param->num_vdev_stats) * sizeof(wmi_vdev_stats)) + 14003 ((ev_param->num_peer_stats) * sizeof(wmi_peer_stats)) + 14004 ((ev_param->num_chan_stats) * sizeof(wmi_chan_stats)) + 14005 ((ev_param->num_mib_stats) * sizeof(wmi_mib_stats)) + 14006 (index * sizeof(wmi_bcn_stats))); 14007 14008 bcn_stats->vdev_id = ev->vdev_id; 14009 bcn_stats->tx_bcn_succ_cnt = ev->tx_bcn_succ_cnt; 14010 bcn_stats->tx_bcn_outage_cnt = ev->tx_bcn_outage_cnt; 14011 } 14012 14013 return QDF_STATUS_SUCCESS; 14014 } 14015 14016 #ifdef WLAN_FEATURE_11BE_MLO 14017 /** 14018 * wmi_is_mlo_vdev_active() - get if mlo vdev is active or not 14019 * @flag: vdev link status info 14020 * 14021 * Return: True if active, else False 14022 */ 14023 static bool wmi_is_mlo_vdev_active(uint32_t flag) 14024 { 14025 if ((flag & WMI_VDEV_STATS_FLAGS_LINK_ACTIVE_FLAG_IS_VALID_MASK) && 14026 (flag & WMI_VDEV_STATS_FLAGS_IS_LINK_ACTIVE_MASK)) 14027 return true; 14028 14029 return false; 14030 } 14031 14032 static QDF_STATUS 14033 extract_mlo_vdev_status_info(WMI_UPDATE_STATS_EVENTID_param_tlvs *param_buf, 14034 wmi_vdev_extd_stats *ev, 14035 struct wmi_host_vdev_prb_fils_stats *vdev_stats) 14036 { 14037 if (!param_buf->num_vdev_extd_stats) { 14038 wmi_err("No vdev_extd_stats in the event buffer"); 14039 return QDF_STATUS_E_INVAL; 14040 } 14041 14042 vdev_stats->is_mlo_vdev_active = wmi_is_mlo_vdev_active(ev->flags); 14043 return QDF_STATUS_SUCCESS; 14044 } 14045 #else 14046 static QDF_STATUS 14047 extract_mlo_vdev_status_info(WMI_UPDATE_STATS_EVENTID_param_tlvs *param_buf, 14048 wmi_vdev_extd_stats *ev, 14049 struct wmi_host_vdev_prb_fils_stats *vdev_stats) 14050 { 14051 return QDF_STATUS_SUCCESS; 14052 } 14053 #endif 14054 14055 /** 14056 * extract_vdev_prb_fils_stats_tlv() - extract vdev probe and fils 14057 * stats from event 14058 * @wmi_handle: wmi handle 14059 * @evt_buf: pointer to event buffer 14060 * @index: Index into vdev stats 14061 * @vdev_stats: Pointer to hold vdev probe and fils stats 14062 * 14063 * Return: QDF_STATUS_SUCCESS for success or error code 14064 */ 14065 static QDF_STATUS 14066 extract_vdev_prb_fils_stats_tlv(wmi_unified_t wmi_handle, 14067 void *evt_buf, uint32_t index, 14068 struct wmi_host_vdev_prb_fils_stats *vdev_stats) 14069 { 14070 WMI_UPDATE_STATS_EVENTID_param_tlvs *param_buf; 14071 wmi_vdev_extd_stats *ev; 14072 QDF_STATUS status = QDF_STATUS_SUCCESS; 14073 14074 param_buf = (WMI_UPDATE_STATS_EVENTID_param_tlvs *)evt_buf; 14075 14076 if (param_buf->vdev_extd_stats) { 14077 ev = (wmi_vdev_extd_stats *)(param_buf->vdev_extd_stats + 14078 index); 14079 vdev_stats->vdev_id = ev->vdev_id; 14080 vdev_stats->fd_succ_cnt = ev->fd_succ_cnt; 14081 vdev_stats->fd_fail_cnt = ev->fd_fail_cnt; 14082 vdev_stats->unsolicited_prb_succ_cnt = 14083 ev->unsolicited_prb_succ_cnt; 14084 vdev_stats->unsolicited_prb_fail_cnt = 14085 ev->unsolicited_prb_fail_cnt; 14086 status = extract_mlo_vdev_status_info(param_buf, ev, 14087 vdev_stats); 14088 vdev_stats->vdev_tx_power = ev->vdev_tx_power; 14089 wmi_debug("vdev: %d, fd_s: %d, fd_f: %d, prb_s: %d, prb_f: %d", 14090 ev->vdev_id, ev->fd_succ_cnt, ev->fd_fail_cnt, 14091 ev->unsolicited_prb_succ_cnt, 14092 ev->unsolicited_prb_fail_cnt); 14093 wmi_debug("vdev txpwr: %d", ev->vdev_tx_power); 14094 } 14095 14096 return status; 14097 } 14098 14099 /** 14100 * extract_bcnflt_stats_tlv() - extract bcn fault stats from event 14101 * @wmi_handle: wmi handle 14102 * @evt_buf: pointer to event buffer 14103 * @index: Index into bcn fault stats 14104 * @bcnflt_stats: Pointer to hold bcn fault stats 14105 * 14106 * Return: QDF_STATUS_SUCCESS for success or error code 14107 */ 14108 static QDF_STATUS extract_bcnflt_stats_tlv(wmi_unified_t wmi_handle, 14109 void *evt_buf, uint32_t index, wmi_host_bcnflt_stats *bcnflt_stats) 14110 { 14111 return QDF_STATUS_SUCCESS; 14112 } 14113 14114 /** 14115 * extract_chan_stats_tlv() - extract chan stats from event 14116 * @wmi_handle: wmi handle 14117 * @evt_buf: pointer to event buffer 14118 * @index: Index into chan stats 14119 * @chan_stats: Pointer to hold chan stats 14120 * 14121 * Return: QDF_STATUS_SUCCESS for success or error code 14122 */ 14123 static QDF_STATUS extract_chan_stats_tlv(wmi_unified_t wmi_handle, 14124 void *evt_buf, uint32_t index, wmi_host_chan_stats *chan_stats) 14125 { 14126 WMI_UPDATE_STATS_EVENTID_param_tlvs *param_buf; 14127 wmi_stats_event_fixed_param *ev_param; 14128 uint8_t *data; 14129 14130 param_buf = (WMI_UPDATE_STATS_EVENTID_param_tlvs *) evt_buf; 14131 ev_param = (wmi_stats_event_fixed_param *) param_buf->fixed_param; 14132 data = (uint8_t *) param_buf->data; 14133 14134 if (index < ev_param->num_chan_stats) { 14135 wmi_chan_stats *ev = (wmi_chan_stats *) ((data) + 14136 ((ev_param->num_pdev_stats) * sizeof(wmi_pdev_stats)) + 14137 ((ev_param->num_vdev_stats) * sizeof(wmi_vdev_stats)) + 14138 ((ev_param->num_peer_stats) * sizeof(wmi_peer_stats)) + 14139 (index * sizeof(wmi_chan_stats))); 14140 14141 14142 /* Non-TLV doesn't have num_chan_stats */ 14143 chan_stats->chan_mhz = ev->chan_mhz; 14144 chan_stats->sampling_period_us = ev->sampling_period_us; 14145 chan_stats->rx_clear_count = ev->rx_clear_count; 14146 chan_stats->tx_duration_us = ev->tx_duration_us; 14147 chan_stats->rx_duration_us = ev->rx_duration_us; 14148 } 14149 14150 return QDF_STATUS_SUCCESS; 14151 } 14152 14153 /** 14154 * extract_profile_ctx_tlv() - extract profile context from event 14155 * @wmi_handle: wmi handle 14156 * @evt_buf: pointer to event buffer 14157 * @profile_ctx: Pointer to hold profile context 14158 * 14159 * Return: QDF_STATUS_SUCCESS for success or error code 14160 */ 14161 static QDF_STATUS extract_profile_ctx_tlv(wmi_unified_t wmi_handle, 14162 void *evt_buf, wmi_host_wlan_profile_ctx_t *profile_ctx) 14163 { 14164 WMI_WLAN_PROFILE_DATA_EVENTID_param_tlvs *param_buf; 14165 14166 wmi_wlan_profile_ctx_t *ev; 14167 14168 param_buf = (WMI_WLAN_PROFILE_DATA_EVENTID_param_tlvs *)evt_buf; 14169 if (!param_buf) { 14170 wmi_err("Invalid profile data event buf"); 14171 return QDF_STATUS_E_INVAL; 14172 } 14173 14174 ev = param_buf->profile_ctx; 14175 14176 profile_ctx->tot = ev->tot; 14177 profile_ctx->tx_msdu_cnt = ev->tx_msdu_cnt; 14178 profile_ctx->tx_mpdu_cnt = ev->tx_mpdu_cnt; 14179 profile_ctx->tx_ppdu_cnt = ev->tx_ppdu_cnt; 14180 profile_ctx->rx_msdu_cnt = ev->rx_msdu_cnt; 14181 profile_ctx->rx_mpdu_cnt = ev->rx_mpdu_cnt; 14182 profile_ctx->bin_count = ev->bin_count; 14183 14184 return QDF_STATUS_SUCCESS; 14185 } 14186 14187 /** 14188 * extract_profile_data_tlv() - extract profile data from event 14189 * @wmi_handle: wmi handle 14190 * @evt_buf: pointer to event buffer 14191 * @idx: profile stats index to extract 14192 * @profile_data: Pointer to hold profile data 14193 * 14194 * Return: QDF_STATUS_SUCCESS for success or error code 14195 */ 14196 static QDF_STATUS extract_profile_data_tlv(wmi_unified_t wmi_handle, 14197 void *evt_buf, uint8_t idx, wmi_host_wlan_profile_t *profile_data) 14198 { 14199 WMI_WLAN_PROFILE_DATA_EVENTID_param_tlvs *param_buf; 14200 wmi_wlan_profile_t *ev; 14201 14202 param_buf = (WMI_WLAN_PROFILE_DATA_EVENTID_param_tlvs *)evt_buf; 14203 if (!param_buf) { 14204 wmi_err("Invalid profile data event buf"); 14205 return QDF_STATUS_E_INVAL; 14206 } 14207 14208 ev = ¶m_buf->profile_data[idx]; 14209 profile_data->id = ev->id; 14210 profile_data->cnt = ev->cnt; 14211 profile_data->tot = ev->tot; 14212 profile_data->min = ev->min; 14213 profile_data->max = ev->max; 14214 profile_data->hist_intvl = ev->hist_intvl; 14215 qdf_mem_copy(profile_data->hist, ev->hist, sizeof(profile_data->hist)); 14216 14217 return QDF_STATUS_SUCCESS; 14218 } 14219 14220 /** 14221 * extract_pdev_utf_event_tlv() - extract UTF data info from event 14222 * @wmi_handle: WMI handle 14223 * @evt_buf: Pointer to event buffer 14224 * @event: Pointer to hold data 14225 * 14226 * Return: QDF_STATUS_SUCCESS for success or error code 14227 */ 14228 static QDF_STATUS extract_pdev_utf_event_tlv(wmi_unified_t wmi_handle, 14229 uint8_t *evt_buf, 14230 struct wmi_host_pdev_utf_event *event) 14231 { 14232 WMI_PDEV_UTF_EVENTID_param_tlvs *param_buf; 14233 struct wmi_host_utf_seg_header_info *seg_hdr; 14234 14235 param_buf = (WMI_PDEV_UTF_EVENTID_param_tlvs *)evt_buf; 14236 event->data = param_buf->data; 14237 event->datalen = param_buf->num_data; 14238 14239 if (event->datalen < sizeof(struct wmi_host_utf_seg_header_info)) { 14240 wmi_err("Invalid datalen: %d", event->datalen); 14241 return QDF_STATUS_E_INVAL; 14242 } 14243 seg_hdr = (struct wmi_host_utf_seg_header_info *)param_buf->data; 14244 /* Set pdev_id=1 until FW adds support to include pdev_id */ 14245 event->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host( 14246 wmi_handle, 14247 seg_hdr->pdev_id); 14248 14249 return QDF_STATUS_SUCCESS; 14250 } 14251 14252 #ifdef WLAN_SUPPORT_RF_CHARACTERIZATION 14253 static QDF_STATUS extract_num_rf_characterization_entries_tlv(wmi_unified_t wmi_handle, 14254 uint8_t *event, 14255 uint32_t *num_rf_characterization_entries) 14256 { 14257 WMI_CHAN_RF_CHARACTERIZATION_INFO_EVENTID_param_tlvs *param_buf; 14258 14259 param_buf = (WMI_CHAN_RF_CHARACTERIZATION_INFO_EVENTID_param_tlvs *)event; 14260 if (!param_buf) 14261 return QDF_STATUS_E_INVAL; 14262 14263 *num_rf_characterization_entries = 14264 param_buf->num_wmi_chan_rf_characterization_info; 14265 14266 return QDF_STATUS_SUCCESS; 14267 } 14268 14269 static QDF_STATUS extract_rf_characterization_entries_tlv(wmi_unified_t wmi_handle, 14270 uint8_t *event, 14271 uint32_t num_rf_characterization_entries, 14272 struct wmi_host_rf_characterization_event_param *rf_characterization_entries) 14273 { 14274 WMI_CHAN_RF_CHARACTERIZATION_INFO_EVENTID_param_tlvs *param_buf; 14275 WMI_CHAN_RF_CHARACTERIZATION_INFO *wmi_rf_characterization_entry; 14276 uint8_t ix; 14277 14278 param_buf = (WMI_CHAN_RF_CHARACTERIZATION_INFO_EVENTID_param_tlvs *)event; 14279 if (!param_buf) 14280 return QDF_STATUS_E_INVAL; 14281 14282 wmi_rf_characterization_entry = 14283 param_buf->wmi_chan_rf_characterization_info; 14284 if (!wmi_rf_characterization_entry) 14285 return QDF_STATUS_E_INVAL; 14286 14287 /* 14288 * Using num_wmi_chan_rf_characterization instead of param_buf value 14289 * since memory for rf_characterization_entries was allocated using 14290 * the former. 14291 */ 14292 for (ix = 0; ix < num_rf_characterization_entries; ix++) { 14293 rf_characterization_entries[ix].freq = 14294 WMI_CHAN_RF_CHARACTERIZATION_FREQ_GET( 14295 &wmi_rf_characterization_entry[ix]); 14296 14297 rf_characterization_entries[ix].bw = 14298 WMI_CHAN_RF_CHARACTERIZATION_BW_GET( 14299 &wmi_rf_characterization_entry[ix]); 14300 14301 rf_characterization_entries[ix].chan_metric = 14302 WMI_CHAN_RF_CHARACTERIZATION_CHAN_METRIC_GET( 14303 &wmi_rf_characterization_entry[ix]); 14304 14305 wmi_nofl_debug("rf_characterization_entries[%u]: freq: %u, " 14306 "bw: %u, chan_metric: %u", 14307 ix, rf_characterization_entries[ix].freq, 14308 rf_characterization_entries[ix].bw, 14309 rf_characterization_entries[ix].chan_metric); 14310 } 14311 14312 return QDF_STATUS_SUCCESS; 14313 } 14314 #endif 14315 14316 #ifdef WLAN_FEATURE_11BE 14317 static void 14318 extract_11be_chainmask(struct wlan_psoc_host_chainmask_capabilities *cap, 14319 WMI_MAC_PHY_CHAINMASK_CAPABILITY *chainmask_caps) 14320 { 14321 cap->supports_chan_width_320 = 14322 WMI_SUPPORT_CHAN_WIDTH_320_GET(chainmask_caps->supported_flags); 14323 cap->supports_aDFS_320 = 14324 WMI_SUPPORT_ADFS_320_GET(chainmask_caps->supported_flags); 14325 } 14326 #else 14327 static void 14328 extract_11be_chainmask(struct wlan_psoc_host_chainmask_capabilities *cap, 14329 WMI_MAC_PHY_CHAINMASK_CAPABILITY *chainmask_caps) 14330 { 14331 } 14332 #endif /* WLAN_FEATURE_11BE */ 14333 14334 /** 14335 * extract_chainmask_tables_tlv() - extract chain mask tables from event 14336 * @wmi_handle: wmi handle 14337 * @event: pointer to event buffer 14338 * @chainmask_table: Pointer to hold extracted chainmask tables 14339 * 14340 * Return: QDF_STATUS_SUCCESS for success or error code 14341 */ 14342 static QDF_STATUS extract_chainmask_tables_tlv(wmi_unified_t wmi_handle, 14343 uint8_t *event, struct wlan_psoc_host_chainmask_table *chainmask_table) 14344 { 14345 WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *param_buf; 14346 WMI_MAC_PHY_CHAINMASK_CAPABILITY *chainmask_caps; 14347 WMI_SOC_MAC_PHY_HW_MODE_CAPS *hw_caps; 14348 uint8_t i = 0, j = 0; 14349 uint32_t num_mac_phy_chainmask_caps = 0; 14350 14351 param_buf = (WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *) event; 14352 if (!param_buf) 14353 return QDF_STATUS_E_INVAL; 14354 14355 hw_caps = param_buf->soc_hw_mode_caps; 14356 if (!hw_caps) 14357 return QDF_STATUS_E_INVAL; 14358 14359 if ((!hw_caps->num_chainmask_tables) || 14360 (hw_caps->num_chainmask_tables > PSOC_MAX_CHAINMASK_TABLES) || 14361 (hw_caps->num_chainmask_tables > 14362 param_buf->num_mac_phy_chainmask_combo)) 14363 return QDF_STATUS_E_INVAL; 14364 14365 chainmask_caps = param_buf->mac_phy_chainmask_caps; 14366 14367 if (!chainmask_caps) 14368 return QDF_STATUS_E_INVAL; 14369 14370 for (i = 0; i < hw_caps->num_chainmask_tables; i++) { 14371 if (chainmask_table[i].num_valid_chainmasks > 14372 (UINT_MAX - num_mac_phy_chainmask_caps)) { 14373 wmi_err_rl("integer overflow, num_mac_phy_chainmask_caps:%d, i:%d, um_valid_chainmasks:%d", 14374 num_mac_phy_chainmask_caps, i, 14375 chainmask_table[i].num_valid_chainmasks); 14376 return QDF_STATUS_E_INVAL; 14377 } 14378 num_mac_phy_chainmask_caps += 14379 chainmask_table[i].num_valid_chainmasks; 14380 } 14381 14382 if (num_mac_phy_chainmask_caps > 14383 param_buf->num_mac_phy_chainmask_caps) { 14384 wmi_err_rl("invalid chainmask caps num, num_mac_phy_chainmask_caps:%d, param_buf->num_mac_phy_chainmask_caps:%d", 14385 num_mac_phy_chainmask_caps, 14386 param_buf->num_mac_phy_chainmask_caps); 14387 return QDF_STATUS_E_INVAL; 14388 } 14389 14390 for (i = 0; i < hw_caps->num_chainmask_tables; i++) { 14391 14392 wmi_nofl_debug("Dumping chain mask combo data for table : %d", 14393 i); 14394 for (j = 0; j < chainmask_table[i].num_valid_chainmasks; j++) { 14395 14396 chainmask_table[i].cap_list[j].chainmask = 14397 chainmask_caps->chainmask; 14398 14399 chainmask_table[i].cap_list[j].supports_chan_width_20 = 14400 WMI_SUPPORT_CHAN_WIDTH_20_GET(chainmask_caps->supported_flags); 14401 14402 chainmask_table[i].cap_list[j].supports_chan_width_40 = 14403 WMI_SUPPORT_CHAN_WIDTH_40_GET(chainmask_caps->supported_flags); 14404 14405 chainmask_table[i].cap_list[j].supports_chan_width_80 = 14406 WMI_SUPPORT_CHAN_WIDTH_80_GET(chainmask_caps->supported_flags); 14407 14408 chainmask_table[i].cap_list[j].supports_chan_width_160 = 14409 WMI_SUPPORT_CHAN_WIDTH_160_GET(chainmask_caps->supported_flags); 14410 14411 chainmask_table[i].cap_list[j].supports_chan_width_80P80 = 14412 WMI_SUPPORT_CHAN_WIDTH_80P80_GET(chainmask_caps->supported_flags); 14413 14414 chainmask_table[i].cap_list[j].chain_mask_2G = 14415 WMI_SUPPORT_CHAIN_MASK_2G_GET(chainmask_caps->supported_flags); 14416 14417 chainmask_table[i].cap_list[j].chain_mask_5G = 14418 WMI_SUPPORT_CHAIN_MASK_5G_GET(chainmask_caps->supported_flags); 14419 14420 chainmask_table[i].cap_list[j].chain_mask_tx = 14421 WMI_SUPPORT_CHAIN_MASK_TX_GET(chainmask_caps->supported_flags); 14422 14423 chainmask_table[i].cap_list[j].chain_mask_rx = 14424 WMI_SUPPORT_CHAIN_MASK_RX_GET(chainmask_caps->supported_flags); 14425 14426 chainmask_table[i].cap_list[j].supports_aDFS = 14427 WMI_SUPPORT_CHAIN_MASK_ADFS_GET(chainmask_caps->supported_flags); 14428 14429 chainmask_table[i].cap_list[j].supports_aSpectral = 14430 WMI_SUPPORT_AGILE_SPECTRAL_GET(chainmask_caps->supported_flags); 14431 14432 chainmask_table[i].cap_list[j].supports_aSpectral_160 = 14433 WMI_SUPPORT_AGILE_SPECTRAL_160_GET(chainmask_caps->supported_flags); 14434 14435 chainmask_table[i].cap_list[j].supports_aDFS_160 = 14436 WMI_SUPPORT_ADFS_160_GET(chainmask_caps->supported_flags); 14437 14438 extract_11be_chainmask(&chainmask_table[i].cap_list[j], 14439 chainmask_caps); 14440 14441 wmi_nofl_debug("supported_flags: 0x%08x chainmasks: 0x%08x", 14442 chainmask_caps->supported_flags, 14443 chainmask_caps->chainmask); 14444 chainmask_caps++; 14445 } 14446 } 14447 14448 return QDF_STATUS_SUCCESS; 14449 } 14450 14451 /** 14452 * extract_service_ready_ext_tlv() - extract basic extended service ready params 14453 * from event 14454 * @wmi_handle: wmi handle 14455 * @event: pointer to event buffer 14456 * @param: Pointer to hold evt buf 14457 * 14458 * Return: QDF_STATUS_SUCCESS for success or error code 14459 */ 14460 static QDF_STATUS extract_service_ready_ext_tlv(wmi_unified_t wmi_handle, 14461 uint8_t *event, struct wlan_psoc_host_service_ext_param *param) 14462 { 14463 WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *param_buf; 14464 wmi_service_ready_ext_event_fixed_param *ev; 14465 WMI_SOC_MAC_PHY_HW_MODE_CAPS *hw_caps; 14466 WMI_SOC_HAL_REG_CAPABILITIES *reg_caps; 14467 WMI_MAC_PHY_CHAINMASK_COMBO *chain_mask_combo; 14468 uint8_t i = 0; 14469 14470 param_buf = (WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *) event; 14471 if (!param_buf) 14472 return QDF_STATUS_E_INVAL; 14473 14474 ev = param_buf->fixed_param; 14475 if (!ev) 14476 return QDF_STATUS_E_INVAL; 14477 14478 /* Move this to host based bitmap */ 14479 param->default_conc_scan_config_bits = 14480 ev->default_conc_scan_config_bits; 14481 param->default_fw_config_bits = ev->default_fw_config_bits; 14482 param->he_cap_info = ev->he_cap_info; 14483 param->mpdu_density = ev->mpdu_density; 14484 param->max_bssid_rx_filters = ev->max_bssid_rx_filters; 14485 param->fw_build_vers_ext = ev->fw_build_vers_ext; 14486 param->num_dbr_ring_caps = param_buf->num_dma_ring_caps; 14487 param->num_bin_scaling_params = param_buf->num_wmi_bin_scaling_params; 14488 param->max_bssid_indicator = ev->max_bssid_indicator; 14489 qdf_mem_copy(¶m->ppet, &ev->ppet, sizeof(param->ppet)); 14490 14491 hw_caps = param_buf->soc_hw_mode_caps; 14492 if (hw_caps) 14493 param->num_hw_modes = hw_caps->num_hw_modes; 14494 else 14495 param->num_hw_modes = 0; 14496 14497 reg_caps = param_buf->soc_hal_reg_caps; 14498 if (reg_caps) 14499 param->num_phy = reg_caps->num_phy; 14500 else 14501 param->num_phy = 0; 14502 14503 if (hw_caps) { 14504 param->num_chainmask_tables = hw_caps->num_chainmask_tables; 14505 wmi_nofl_debug("Num chain mask tables: %d", 14506 hw_caps->num_chainmask_tables); 14507 } else 14508 param->num_chainmask_tables = 0; 14509 14510 if (param->num_chainmask_tables > PSOC_MAX_CHAINMASK_TABLES || 14511 param->num_chainmask_tables > 14512 param_buf->num_mac_phy_chainmask_combo) { 14513 wmi_err_rl("num_chainmask_tables is OOB: %u", 14514 param->num_chainmask_tables); 14515 return QDF_STATUS_E_INVAL; 14516 } 14517 chain_mask_combo = param_buf->mac_phy_chainmask_combo; 14518 14519 if (!chain_mask_combo) 14520 return QDF_STATUS_SUCCESS; 14521 14522 wmi_nofl_info_high("Dumping chain mask combo data"); 14523 14524 for (i = 0; i < param->num_chainmask_tables; i++) { 14525 14526 wmi_nofl_info_high("table_id : %d Num valid chainmasks: %d", 14527 chain_mask_combo->chainmask_table_id, 14528 chain_mask_combo->num_valid_chainmask); 14529 14530 param->chainmask_table[i].table_id = 14531 chain_mask_combo->chainmask_table_id; 14532 param->chainmask_table[i].num_valid_chainmasks = 14533 chain_mask_combo->num_valid_chainmask; 14534 chain_mask_combo++; 14535 } 14536 wmi_nofl_info_high("chain mask combo end"); 14537 14538 return QDF_STATUS_SUCCESS; 14539 } 14540 14541 #if defined(CONFIG_AFC_SUPPORT) 14542 /** 14543 * extract_svc_rdy_ext2_afc_tlv() - extract service ready ext2 afc deployment 14544 * type from event 14545 * @ev: pointer to event fixed param 14546 * @param: Pointer to hold the params 14547 * 14548 * Return: void 14549 */ 14550 static void 14551 extract_svc_rdy_ext2_afc_tlv(wmi_service_ready_ext2_event_fixed_param *ev, 14552 struct wlan_psoc_host_service_ext2_param *param) 14553 { 14554 WMI_AFC_FEATURE_6G_DEPLOYMENT_TYPE tgt_afc_dev_type; 14555 enum reg_afc_dev_deploy_type reg_afc_dev_type; 14556 14557 tgt_afc_dev_type = ev->afc_deployment_type; 14558 switch (tgt_afc_dev_type) { 14559 case WMI_AFC_FEATURE_6G_DEPLOYMENT_UNSPECIFIED: 14560 reg_afc_dev_type = AFC_DEPLOYMENT_INDOOR; 14561 break; 14562 case WMI_AFC_FEATURE_6G_DEPLOYMENT_INDOOR_ONLY: 14563 reg_afc_dev_type = AFC_DEPLOYMENT_INDOOR; 14564 break; 14565 case WMI_AFC_FEATURE_6G_DEPLOYMENT_OUTDOOR_ONLY: 14566 reg_afc_dev_type = AFC_DEPLOYMENT_OUTDOOR; 14567 break; 14568 default: 14569 wmi_err("invalid afc deployment %d", tgt_afc_dev_type); 14570 reg_afc_dev_type = AFC_DEPLOYMENT_UNKNOWN; 14571 break; 14572 } 14573 param->afc_dev_type = reg_afc_dev_type; 14574 14575 wmi_debug("afc dev type:%d", ev->afc_deployment_type); 14576 } 14577 #else 14578 static inline void 14579 extract_svc_rdy_ext2_afc_tlv(wmi_service_ready_ext2_event_fixed_param *ev, 14580 struct wlan_psoc_host_service_ext2_param *param) 14581 { 14582 } 14583 #endif 14584 14585 /** 14586 * extract_ul_mumimo_support() - extract UL-MUMIMO capability from target cap 14587 * @param: Pointer to hold the params 14588 * 14589 * Return: Void 14590 */ 14591 static void 14592 extract_ul_mumimo_support(struct wlan_psoc_host_service_ext2_param *param) 14593 { 14594 uint32_t tgt_cap = param->target_cap_flags; 14595 14596 param->ul_mumimo_rx_2g = WMI_TARGET_CAP_UL_MU_MIMO_RX_SUPPORT_2GHZ_GET(tgt_cap); 14597 param->ul_mumimo_rx_5g = WMI_TARGET_CAP_UL_MU_MIMO_RX_SUPPORT_5GHZ_GET(tgt_cap); 14598 param->ul_mumimo_rx_6g = WMI_TARGET_CAP_UL_MU_MIMO_RX_SUPPORT_6GHZ_GET(tgt_cap); 14599 param->ul_mumimo_tx_2g = WMI_TARGET_CAP_UL_MU_MIMO_TX_SUPPORT_2GHZ_GET(tgt_cap); 14600 param->ul_mumimo_tx_5g = WMI_TARGET_CAP_UL_MU_MIMO_TX_SUPPORT_5GHZ_GET(tgt_cap); 14601 param->ul_mumimo_tx_6g = WMI_TARGET_CAP_UL_MU_MIMO_TX_SUPPORT_6GHZ_GET(tgt_cap); 14602 } 14603 14604 /** 14605 * extract_hw_bdf_status() - extract service ready ext2 BDF hw status 14606 * type from event 14607 * @ev: pointer to event fixed param 14608 * 14609 * Return: void 14610 */ 14611 14612 static void 14613 extract_hw_bdf_status(wmi_service_ready_ext2_event_fixed_param *ev) 14614 { 14615 uint8_t hw_bdf_s; 14616 14617 hw_bdf_s = ev->hw_bd_status; 14618 switch (hw_bdf_s) { 14619 case WMI_BDF_VERSION_CHECK_DISABLED: 14620 wmi_info("BDF VER is %d, FW and BDF ver check skipped", 14621 hw_bdf_s); 14622 break; 14623 case WMI_BDF_VERSION_CHECK_GOOD: 14624 wmi_info("BDF VER is %d, FW and BDF ver check good", 14625 hw_bdf_s); 14626 break; 14627 case WMI_BDF_VERSION_TEMPLATE_TOO_OLD: 14628 wmi_info("BDF VER is %d, BDF ver is older than the oldest version supported by FW", 14629 hw_bdf_s); 14630 break; 14631 case WMI_BDF_VERSION_TEMPLATE_TOO_NEW: 14632 wmi_info("BDF VER is %d, BDF ver is newer than the newest version supported by FW", 14633 hw_bdf_s); 14634 break; 14635 case WMI_BDF_VERSION_FW_TOO_OLD: 14636 wmi_info("BDF VER is %d, FW ver is older than the major version supported by BDF", 14637 hw_bdf_s); 14638 break; 14639 case WMI_BDF_VERSION_FW_TOO_NEW: 14640 wmi_info("BDF VER is %d, FW ver is newer than the minor version supported by BDF", 14641 hw_bdf_s); 14642 break; 14643 default: 14644 wmi_info("unknown BDF VER %d", hw_bdf_s); 14645 break; 14646 } 14647 } 14648 14649 #ifdef QCA_MULTIPASS_SUPPORT 14650 static void 14651 extract_multipass_sap_cap(struct wlan_psoc_host_service_ext2_param *param, 14652 uint32_t target_cap_flag) 14653 { 14654 param->is_multipass_sap = 14655 WMI_TARGET_CAP_MULTIPASS_SAP_SUPPORT_GET(target_cap_flag); 14656 } 14657 #else 14658 static void 14659 extract_multipass_sap_cap(struct wlan_psoc_host_service_ext2_param *param, 14660 uint32_t target_cap_flag) 14661 { 14662 } 14663 #endif 14664 14665 #if defined(WLAN_FEATURE_11BE_MLO_ADV_FEATURE) 14666 static inline void 14667 extract_num_max_mlo_link(wmi_service_ready_ext2_event_fixed_param *ev, 14668 struct wlan_psoc_host_service_ext2_param *param) 14669 { 14670 param->num_max_mlo_link_per_ml_bss_supp = 14671 ev->num_max_mlo_link_per_ml_bss_supp; 14672 14673 wmi_debug("Firmware Max MLO link support: %d", 14674 param->num_max_mlo_link_per_ml_bss_supp); 14675 } 14676 #else 14677 static inline void 14678 extract_num_max_mlo_link(wmi_service_ready_ext2_event_fixed_param *ev, 14679 struct wlan_psoc_host_service_ext2_param *param) 14680 { 14681 } 14682 #endif 14683 14684 /** 14685 * extract_service_ready_ext2_tlv() - extract service ready ext2 params from 14686 * event 14687 * @wmi_handle: wmi handle 14688 * @event: pointer to event buffer 14689 * @param: Pointer to hold the params 14690 * 14691 * Return: QDF_STATUS_SUCCESS for success or error code 14692 */ 14693 static QDF_STATUS 14694 extract_service_ready_ext2_tlv(wmi_unified_t wmi_handle, uint8_t *event, 14695 struct wlan_psoc_host_service_ext2_param *param) 14696 { 14697 WMI_SERVICE_READY_EXT2_EVENTID_param_tlvs *param_buf; 14698 wmi_service_ready_ext2_event_fixed_param *ev; 14699 14700 param_buf = (WMI_SERVICE_READY_EXT2_EVENTID_param_tlvs *)event; 14701 if (!param_buf) 14702 return QDF_STATUS_E_INVAL; 14703 14704 ev = param_buf->fixed_param; 14705 if (!ev) 14706 return QDF_STATUS_E_INVAL; 14707 14708 param->reg_db_version_major = 14709 WMI_REG_DB_VERSION_MAJOR_GET( 14710 ev->reg_db_version); 14711 param->reg_db_version_minor = 14712 WMI_REG_DB_VERSION_MINOR_GET( 14713 ev->reg_db_version); 14714 param->bdf_reg_db_version_major = 14715 WMI_BDF_REG_DB_VERSION_MAJOR_GET( 14716 ev->reg_db_version); 14717 param->bdf_reg_db_version_minor = 14718 WMI_BDF_REG_DB_VERSION_MINOR_GET( 14719 ev->reg_db_version); 14720 param->chwidth_num_peer_caps = ev->chwidth_num_peer_caps; 14721 14722 param->num_dbr_ring_caps = param_buf->num_dma_ring_caps; 14723 14724 param->num_msdu_idx_qtype_map = 14725 param_buf->num_htt_msdu_idx_to_qtype_map; 14726 14727 if (param_buf->nan_cap) { 14728 param->max_ndp_sessions = 14729 param_buf->nan_cap->max_ndp_sessions; 14730 param->max_nan_pairing_sessions = 14731 param_buf->nan_cap->max_pairing_sessions; 14732 } else { 14733 param->max_ndp_sessions = 0; 14734 param->max_nan_pairing_sessions = 0; 14735 } 14736 14737 param->preamble_puncture_bw_cap = ev->preamble_puncture_bw; 14738 param->num_scan_radio_caps = param_buf->num_wmi_scan_radio_caps; 14739 param->max_users_dl_ofdma = WMI_MAX_USER_PER_PPDU_DL_OFDMA_GET( 14740 ev->max_user_per_ppdu_ofdma); 14741 param->max_users_ul_ofdma = WMI_MAX_USER_PER_PPDU_UL_OFDMA_GET( 14742 ev->max_user_per_ppdu_ofdma); 14743 param->max_users_dl_mumimo = WMI_MAX_USER_PER_PPDU_DL_MUMIMO_GET( 14744 ev->max_user_per_ppdu_mumimo); 14745 param->max_users_ul_mumimo = WMI_MAX_USER_PER_PPDU_UL_MUMIMO_GET( 14746 ev->max_user_per_ppdu_mumimo); 14747 param->target_cap_flags = ev->target_cap_flags; 14748 14749 param->dp_peer_meta_data_ver = 14750 WMI_TARGET_CAP_FLAGS_RX_PEER_METADATA_VERSION_GET( 14751 ev->target_cap_flags); 14752 14753 extract_multipass_sap_cap(param, ev->target_cap_flags); 14754 14755 extract_ul_mumimo_support(param); 14756 wmi_debug("htt peer data :%d", ev->target_cap_flags); 14757 14758 extract_svc_rdy_ext2_afc_tlv(ev, param); 14759 14760 extract_hw_bdf_status(ev); 14761 14762 extract_num_max_mlo_link(ev, param); 14763 14764 param->num_aux_dev_caps = param_buf->num_aux_dev_caps; 14765 14766 return QDF_STATUS_SUCCESS; 14767 } 14768 14769 /* 14770 * extract_dbs_or_sbs_cap_service_ready_ext2_tlv() - extract dbs_or_sbs cap from 14771 * service ready ext 2 14772 * 14773 * @wmi_handle: wmi handle 14774 * @event: pointer to event buffer 14775 * @sbs_lower_band_end_freq: If sbs_lower_band_end_freq is set to non-zero, 14776 * it indicates async SBS mode is supported, and 14777 * lower-band/higher band to MAC mapping is 14778 * switch-able. unit: mhz. examples 5180, 5320 14779 * 14780 * Return: QDF_STATUS_SUCCESS on success, QDF_STATUS_E_** on error 14781 */ 14782 static QDF_STATUS extract_dbs_or_sbs_cap_service_ready_ext2_tlv( 14783 wmi_unified_t wmi_handle, uint8_t *event, 14784 uint32_t *sbs_lower_band_end_freq) 14785 { 14786 WMI_SERVICE_READY_EXT2_EVENTID_param_tlvs *param_buf; 14787 wmi_dbs_or_sbs_cap_ext *dbs_or_sbs_caps; 14788 14789 param_buf = (WMI_SERVICE_READY_EXT2_EVENTID_param_tlvs *)event; 14790 if (!param_buf) 14791 return QDF_STATUS_E_INVAL; 14792 14793 dbs_or_sbs_caps = param_buf->dbs_or_sbs_cap_ext; 14794 if (!dbs_or_sbs_caps) 14795 return QDF_STATUS_E_INVAL; 14796 14797 *sbs_lower_band_end_freq = dbs_or_sbs_caps->sbs_lower_band_end_freq; 14798 14799 return QDF_STATUS_SUCCESS; 14800 } 14801 14802 /** 14803 * extract_sar_cap_service_ready_ext_tlv() - 14804 * extract SAR cap from service ready event 14805 * @wmi_handle: wmi handle 14806 * @event: pointer to event buffer 14807 * @ext_param: extended target info 14808 * 14809 * Return: QDF_STATUS_SUCCESS for success or error code 14810 */ 14811 static QDF_STATUS extract_sar_cap_service_ready_ext_tlv( 14812 wmi_unified_t wmi_handle, 14813 uint8_t *event, 14814 struct wlan_psoc_host_service_ext_param *ext_param) 14815 { 14816 WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *param_buf; 14817 WMI_SAR_CAPABILITIES *sar_caps; 14818 14819 param_buf = (WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *)event; 14820 14821 if (!param_buf) 14822 return QDF_STATUS_E_INVAL; 14823 14824 sar_caps = param_buf->sar_caps; 14825 if (sar_caps) 14826 ext_param->sar_version = sar_caps->active_version; 14827 else 14828 ext_param->sar_version = 0; 14829 14830 return QDF_STATUS_SUCCESS; 14831 } 14832 14833 /** 14834 * extract_hw_mode_cap_service_ready_ext_tlv() - 14835 * extract HW mode cap from service ready event 14836 * @wmi_handle: wmi handle 14837 * @event: pointer to event buffer 14838 * @hw_mode_idx: hw mode idx should be less than num_mode 14839 * @param: Pointer to hold evt buf 14840 * 14841 * Return: QDF_STATUS_SUCCESS for success or error code 14842 */ 14843 static QDF_STATUS extract_hw_mode_cap_service_ready_ext_tlv( 14844 wmi_unified_t wmi_handle, 14845 uint8_t *event, uint8_t hw_mode_idx, 14846 struct wlan_psoc_host_hw_mode_caps *param) 14847 { 14848 WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *param_buf; 14849 WMI_SOC_MAC_PHY_HW_MODE_CAPS *hw_caps; 14850 14851 param_buf = (WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *) event; 14852 if (!param_buf) 14853 return QDF_STATUS_E_INVAL; 14854 14855 hw_caps = param_buf->soc_hw_mode_caps; 14856 if (!hw_caps) 14857 return QDF_STATUS_E_INVAL; 14858 14859 if (!hw_caps->num_hw_modes || 14860 !param_buf->hw_mode_caps || 14861 hw_caps->num_hw_modes > PSOC_MAX_HW_MODE || 14862 hw_caps->num_hw_modes > param_buf->num_hw_mode_caps) 14863 return QDF_STATUS_E_INVAL; 14864 14865 if (hw_mode_idx >= hw_caps->num_hw_modes) 14866 return QDF_STATUS_E_INVAL; 14867 14868 param->hw_mode_id = param_buf->hw_mode_caps[hw_mode_idx].hw_mode_id; 14869 param->phy_id_map = param_buf->hw_mode_caps[hw_mode_idx].phy_id_map; 14870 14871 param->hw_mode_config_type = 14872 param_buf->hw_mode_caps[hw_mode_idx].hw_mode_config_type; 14873 14874 return QDF_STATUS_SUCCESS; 14875 } 14876 14877 /** 14878 * extract_service_ready_11be_support() - api to extract 11be support 14879 * @param: host mac phy capabilities 14880 * @mac_phy_caps: mac phy capabilities 14881 * 14882 * Return: void 14883 */ 14884 #ifdef WLAN_FEATURE_11BE 14885 static void 14886 extract_service_ready_11be_support(struct wlan_psoc_host_mac_phy_caps *param, 14887 WMI_MAC_PHY_CAPABILITIES *mac_phy_caps) 14888 { 14889 param->supports_11be = 14890 WMI_SUPPORT_11BE_GET(mac_phy_caps->supported_flags); 14891 14892 wmi_debug("11be support %d", param->supports_11be); 14893 } 14894 #else 14895 static void 14896 extract_service_ready_11be_support(struct wlan_psoc_host_mac_phy_caps *param, 14897 WMI_MAC_PHY_CAPABILITIES *mac_phy_caps) 14898 { 14899 } 14900 #endif 14901 14902 #if defined(WLAN_FEATURE_11BE_MLO) && defined(WLAN_MLO_MULTI_CHIP) 14903 static void extract_hw_link_id(struct wlan_psoc_host_mac_phy_caps *param, 14904 WMI_MAC_PHY_CAPABILITIES *mac_phy_caps) 14905 { 14906 param->hw_link_id = WMI_PHY_GET_HW_LINK_ID(mac_phy_caps->pdev_id); 14907 } 14908 #else 14909 static void extract_hw_link_id(struct wlan_psoc_host_mac_phy_caps *param, 14910 WMI_MAC_PHY_CAPABILITIES *mac_phy_caps) 14911 { 14912 } 14913 #endif /*WLAN_FEATURE_11BE_MLO && WLAN_MLO_MULTI_CHIP*/ 14914 14915 /** 14916 * extract_mac_phy_cap_service_ready_ext_tlv() - 14917 * extract MAC phy cap from service ready event 14918 * @wmi_handle: wmi handle 14919 * @event: pointer to event buffer 14920 * @hw_mode_id: hw mode idx should be less than num_mode 14921 * @phy_id: phy id within hw_mode 14922 * @param: Pointer to hold evt buf 14923 * 14924 * Return: QDF_STATUS_SUCCESS for success or error code 14925 */ 14926 static QDF_STATUS extract_mac_phy_cap_service_ready_ext_tlv( 14927 wmi_unified_t wmi_handle, 14928 uint8_t *event, uint8_t hw_mode_id, uint8_t phy_id, 14929 struct wlan_psoc_host_mac_phy_caps *param) 14930 { 14931 WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *param_buf; 14932 WMI_MAC_PHY_CAPABILITIES *mac_phy_caps; 14933 WMI_SOC_MAC_PHY_HW_MODE_CAPS *hw_caps; 14934 uint32_t phy_map; 14935 uint8_t hw_idx, phy_idx = 0, pdev_id; 14936 14937 param_buf = (WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *) event; 14938 if (!param_buf) 14939 return QDF_STATUS_E_INVAL; 14940 14941 hw_caps = param_buf->soc_hw_mode_caps; 14942 if (!hw_caps) 14943 return QDF_STATUS_E_INVAL; 14944 if (hw_caps->num_hw_modes > PSOC_MAX_HW_MODE || 14945 hw_caps->num_hw_modes > param_buf->num_hw_mode_caps) { 14946 wmi_err_rl("invalid num_hw_modes %d, num_hw_mode_caps %d", 14947 hw_caps->num_hw_modes, param_buf->num_hw_mode_caps); 14948 return QDF_STATUS_E_INVAL; 14949 } 14950 14951 for (hw_idx = 0; hw_idx < hw_caps->num_hw_modes; hw_idx++) { 14952 if (hw_mode_id == param_buf->hw_mode_caps[hw_idx].hw_mode_id) 14953 break; 14954 14955 phy_map = param_buf->hw_mode_caps[hw_idx].phy_id_map; 14956 while (phy_map) { 14957 phy_map >>= 1; 14958 phy_idx++; 14959 } 14960 } 14961 14962 if (hw_idx == hw_caps->num_hw_modes) 14963 return QDF_STATUS_E_INVAL; 14964 14965 phy_idx += phy_id; 14966 if (phy_idx >= param_buf->num_mac_phy_caps) 14967 return QDF_STATUS_E_INVAL; 14968 14969 mac_phy_caps = ¶m_buf->mac_phy_caps[phy_idx]; 14970 14971 param->hw_mode_id = mac_phy_caps->hw_mode_id; 14972 param->phy_idx = phy_idx; 14973 pdev_id = WMI_PHY_GET_PDEV_ID(mac_phy_caps->pdev_id); 14974 param->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host( 14975 wmi_handle, 14976 pdev_id); 14977 param->tgt_pdev_id = pdev_id; 14978 extract_hw_link_id(param, mac_phy_caps); 14979 param->phy_id = mac_phy_caps->phy_id; 14980 param->supports_11b = 14981 WMI_SUPPORT_11B_GET(mac_phy_caps->supported_flags); 14982 param->supports_11g = 14983 WMI_SUPPORT_11G_GET(mac_phy_caps->supported_flags); 14984 param->supports_11a = 14985 WMI_SUPPORT_11A_GET(mac_phy_caps->supported_flags); 14986 param->supports_11n = 14987 WMI_SUPPORT_11N_GET(mac_phy_caps->supported_flags); 14988 param->supports_11ac = 14989 WMI_SUPPORT_11AC_GET(mac_phy_caps->supported_flags); 14990 param->supports_11ax = 14991 WMI_SUPPORT_11AX_GET(mac_phy_caps->supported_flags); 14992 14993 extract_service_ready_11be_support(param, mac_phy_caps); 14994 14995 param->supported_bands = mac_phy_caps->supported_bands; 14996 param->ampdu_density = mac_phy_caps->ampdu_density; 14997 param->max_bw_supported_2G = mac_phy_caps->max_bw_supported_2G; 14998 param->ht_cap_info_2G = mac_phy_caps->ht_cap_info_2G; 14999 param->vht_cap_info_2G = mac_phy_caps->vht_cap_info_2G; 15000 param->vht_supp_mcs_2G = mac_phy_caps->vht_supp_mcs_2G; 15001 param->he_cap_info_2G[WMI_HOST_HECAP_MAC_WORD1] = 15002 mac_phy_caps->he_cap_info_2G; 15003 param->he_cap_info_2G[WMI_HOST_HECAP_MAC_WORD2] = 15004 mac_phy_caps->he_cap_info_2G_ext; 15005 param->he_supp_mcs_2G = mac_phy_caps->he_supp_mcs_2G; 15006 param->tx_chain_mask_2G = mac_phy_caps->tx_chain_mask_2G; 15007 param->rx_chain_mask_2G = mac_phy_caps->rx_chain_mask_2G; 15008 param->max_bw_supported_5G = mac_phy_caps->max_bw_supported_5G; 15009 param->ht_cap_info_5G = mac_phy_caps->ht_cap_info_5G; 15010 param->vht_cap_info_5G = mac_phy_caps->vht_cap_info_5G; 15011 param->vht_supp_mcs_5G = mac_phy_caps->vht_supp_mcs_5G; 15012 param->he_cap_info_5G[WMI_HOST_HECAP_MAC_WORD1] = 15013 mac_phy_caps->he_cap_info_5G; 15014 param->he_cap_info_5G[WMI_HOST_HECAP_MAC_WORD2] = 15015 mac_phy_caps->he_cap_info_5G_ext; 15016 param->he_supp_mcs_5G = mac_phy_caps->he_supp_mcs_5G; 15017 param->he_cap_info_internal = mac_phy_caps->he_cap_info_internal; 15018 param->tx_chain_mask_5G = mac_phy_caps->tx_chain_mask_5G; 15019 param->rx_chain_mask_5G = mac_phy_caps->rx_chain_mask_5G; 15020 qdf_mem_copy(¶m->he_cap_phy_info_2G, 15021 &mac_phy_caps->he_cap_phy_info_2G, 15022 sizeof(param->he_cap_phy_info_2G)); 15023 qdf_mem_copy(¶m->he_cap_phy_info_5G, 15024 &mac_phy_caps->he_cap_phy_info_5G, 15025 sizeof(param->he_cap_phy_info_5G)); 15026 qdf_mem_copy(¶m->he_ppet2G, &mac_phy_caps->he_ppet2G, 15027 sizeof(param->he_ppet2G)); 15028 qdf_mem_copy(¶m->he_ppet5G, &mac_phy_caps->he_ppet5G, 15029 sizeof(param->he_ppet5G)); 15030 param->chainmask_table_id = mac_phy_caps->chainmask_table_id; 15031 param->lmac_id = mac_phy_caps->lmac_id; 15032 param->reg_cap_ext.wireless_modes = convert_wireless_modes_tlv 15033 (mac_phy_caps->wireless_modes); 15034 param->reg_cap_ext.low_2ghz_chan = mac_phy_caps->low_2ghz_chan_freq; 15035 param->reg_cap_ext.high_2ghz_chan = mac_phy_caps->high_2ghz_chan_freq; 15036 param->reg_cap_ext.low_5ghz_chan = mac_phy_caps->low_5ghz_chan_freq; 15037 param->reg_cap_ext.high_5ghz_chan = mac_phy_caps->high_5ghz_chan_freq; 15038 param->nss_ratio_enabled = WMI_NSS_RATIO_ENABLE_DISABLE_GET( 15039 mac_phy_caps->nss_ratio); 15040 param->nss_ratio_info = WMI_NSS_RATIO_INFO_GET(mac_phy_caps->nss_ratio); 15041 15042 return QDF_STATUS_SUCCESS; 15043 } 15044 15045 #ifdef WLAN_FEATURE_11BE_MLO 15046 /** 15047 * extract_mac_phy_emlcap() - API to extract EML Capabilities 15048 * @param: host ext2 mac phy capabilities 15049 * @mac_phy_caps: ext mac phy capabilities 15050 * 15051 * Return: void 15052 */ 15053 static void extract_mac_phy_emlcap(struct wlan_psoc_host_mac_phy_caps_ext2 *param, 15054 WMI_MAC_PHY_CAPABILITIES_EXT *mac_phy_caps) 15055 { 15056 if (!param || !mac_phy_caps) 15057 return; 15058 15059 param->emlcap.emlsr_supp = WMI_SUPPORT_EMLSR_GET(mac_phy_caps->eml_capability); 15060 param->emlcap.emlsr_pad_delay = WMI_EMLSR_PADDING_DELAY_GET(mac_phy_caps->eml_capability); 15061 param->emlcap.emlsr_trans_delay = WMI_EMLSR_TRANSITION_DELAY_GET(mac_phy_caps->eml_capability); 15062 param->emlcap.emlmr_supp = WMI_SUPPORT_EMLMR_GET(mac_phy_caps->eml_capability); 15063 param->emlcap.emlmr_delay = WMI_EMLMR_DELAY_GET(mac_phy_caps->eml_capability); 15064 param->emlcap.trans_timeout = WMI_TRANSITION_TIMEOUT_GET(mac_phy_caps->eml_capability); 15065 } 15066 15067 /** 15068 * extract_mac_phy_mldcap() - API to extract MLD Capabilities 15069 * @param: host ext2 mac phy capabilities 15070 * @mac_phy_caps: ext mac phy capabilities 15071 * 15072 * Return: void 15073 */ 15074 static void extract_mac_phy_mldcap(struct wlan_psoc_host_mac_phy_caps_ext2 *param, 15075 WMI_MAC_PHY_CAPABILITIES_EXT *mac_phy_caps) 15076 { 15077 if (!param || !mac_phy_caps) 15078 return; 15079 15080 param->mldcap.max_simult_link = WMI_MAX_NUM_SIMULTANEOUS_LINKS_GET(mac_phy_caps->mld_capability); 15081 param->mldcap.srs_support = WMI_SUPPORT_SRS_GET(mac_phy_caps->mld_capability); 15082 param->mldcap.tid2link_neg_support = WMI_TID_TO_LINK_NEGOTIATION_GET(mac_phy_caps->mld_capability); 15083 param->mldcap.str_freq_sep = WMI_FREQ_SEPERATION_STR_GET(mac_phy_caps->mld_capability); 15084 param->mldcap.aar_support = WMI_SUPPORT_AAR_GET(mac_phy_caps->mld_capability); 15085 } 15086 15087 /** 15088 * extract_mac_phy_msdcap() - API to extract MSD Capabilities 15089 * @param: host ext2 mac phy capabilities 15090 * @mac_phy_caps: ext mac phy capabilities 15091 * 15092 * Return: void 15093 */ 15094 static void extract_mac_phy_msdcap(struct wlan_psoc_host_mac_phy_caps_ext2 *param, 15095 WMI_MAC_PHY_CAPABILITIES_EXT *mac_phy_caps) 15096 { 15097 if (!param || !mac_phy_caps) 15098 return; 15099 15100 param->msdcap.medium_sync_duration = WMI_MEDIUM_SYNC_DURATION_GET(mac_phy_caps->msd_capability); 15101 param->msdcap.medium_sync_ofdm_ed_thresh = WMI_MEDIUM_SYNC_OFDM_ED_THRESHOLD_GET(mac_phy_caps->msd_capability); 15102 param->msdcap.medium_sync_max_txop_num = WMI_MEDIUM_SYNC_MAX_NO_TXOPS_GET(mac_phy_caps->msd_capability); 15103 } 15104 #else 15105 static void extract_mac_phy_emlcap(struct wlan_psoc_host_mac_phy_caps_ext2 *param, 15106 WMI_MAC_PHY_CAPABILITIES_EXT *mac_phy_caps) 15107 { 15108 } 15109 15110 static void extract_mac_phy_mldcap(struct wlan_psoc_host_mac_phy_caps_ext2 *param, 15111 WMI_MAC_PHY_CAPABILITIES_EXT *mac_phy_caps) 15112 { 15113 } 15114 15115 static void extract_mac_phy_msdcap(struct wlan_psoc_host_mac_phy_caps_ext2 *param, 15116 WMI_MAC_PHY_CAPABILITIES_EXT *mac_phy_caps) 15117 { 15118 } 15119 #endif 15120 15121 /** 15122 * extract_mac_phy_cap_ehtcaps- api to extract eht mac phy caps 15123 * @param: host ext2 mac phy capabilities 15124 * @mac_phy_caps: ext mac phy capabilities 15125 * 15126 * Return: void 15127 */ 15128 #ifdef WLAN_FEATURE_11BE 15129 static void extract_mac_phy_cap_ehtcaps( 15130 struct wlan_psoc_host_mac_phy_caps_ext2 *param, 15131 WMI_MAC_PHY_CAPABILITIES_EXT *mac_phy_caps) 15132 { 15133 uint32_t i; 15134 15135 param->eht_supp_mcs_2G = mac_phy_caps->eht_supp_mcs_2G; 15136 param->eht_supp_mcs_5G = mac_phy_caps->eht_supp_mcs_5G; 15137 param->eht_cap_info_internal = mac_phy_caps->eht_cap_info_internal; 15138 15139 qdf_mem_copy(¶m->eht_cap_info_2G, 15140 &mac_phy_caps->eht_cap_mac_info_2G, 15141 sizeof(param->eht_cap_info_2G)); 15142 qdf_mem_copy(¶m->eht_cap_info_5G, 15143 &mac_phy_caps->eht_cap_mac_info_5G, 15144 sizeof(param->eht_cap_info_5G)); 15145 15146 qdf_mem_copy(¶m->eht_cap_phy_info_2G, 15147 &mac_phy_caps->eht_cap_phy_info_2G, 15148 sizeof(param->eht_cap_phy_info_2G)); 15149 qdf_mem_copy(¶m->eht_cap_phy_info_5G, 15150 &mac_phy_caps->eht_cap_phy_info_5G, 15151 sizeof(param->eht_cap_phy_info_5G)); 15152 15153 qdf_mem_copy(¶m->eht_supp_mcs_ext_2G, 15154 &mac_phy_caps->eht_supp_mcs_ext_2G, 15155 sizeof(param->eht_supp_mcs_ext_2G)); 15156 qdf_mem_copy(¶m->eht_supp_mcs_ext_5G, 15157 &mac_phy_caps->eht_supp_mcs_ext_5G, 15158 sizeof(param->eht_supp_mcs_ext_5G)); 15159 15160 qdf_mem_copy(¶m->eht_ppet2G, &mac_phy_caps->eht_ppet2G, 15161 sizeof(param->eht_ppet2G)); 15162 qdf_mem_copy(¶m->eht_ppet5G, &mac_phy_caps->eht_ppet5G, 15163 sizeof(param->eht_ppet5G)); 15164 15165 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", 15166 mac_phy_caps->eht_cap_mac_info_2G[0], 15167 mac_phy_caps->eht_cap_mac_info_5G[0], 15168 mac_phy_caps->eht_supp_mcs_2G, mac_phy_caps->eht_supp_mcs_5G, 15169 mac_phy_caps->eht_cap_info_internal); 15170 15171 wmi_nofl_debug("EHT phy caps: "); 15172 15173 wmi_nofl_debug("2G:"); 15174 for (i = 0; i < PSOC_HOST_MAX_EHT_PHY_SIZE; i++) { 15175 wmi_nofl_debug("index %d value %x", 15176 i, param->eht_cap_phy_info_2G[i]); 15177 } 15178 wmi_nofl_debug("5G:"); 15179 for (i = 0; i < PSOC_HOST_MAX_EHT_PHY_SIZE; i++) { 15180 wmi_nofl_debug("index %d value %x", 15181 i, param->eht_cap_phy_info_5G[i]); 15182 } 15183 wmi_nofl_debug("2G MCS ext Map:"); 15184 for (i = 0; i < PSOC_HOST_EHT_MCS_NSS_MAP_2G_SIZE; i++) { 15185 wmi_nofl_debug("index %d value %x", 15186 i, param->eht_supp_mcs_ext_2G[i]); 15187 } 15188 wmi_nofl_debug("5G MCS ext Map:"); 15189 for (i = 0; i < PSOC_HOST_EHT_MCS_NSS_MAP_5G_SIZE; i++) { 15190 wmi_nofl_debug("index %d value %x", 15191 i, param->eht_supp_mcs_ext_5G[i]); 15192 } 15193 wmi_nofl_debug("2G PPET: numss_m1 %x ru_bit_mask %x", 15194 param->eht_ppet2G.numss_m1, 15195 param->eht_ppet2G.ru_bit_mask); 15196 for (i = 0; i < PSOC_HOST_MAX_NUM_SS; i++) { 15197 wmi_nofl_debug("index %d value %x", 15198 i, param->eht_ppet2G.ppet16_ppet8_ru3_ru0[i]); 15199 } 15200 wmi_nofl_debug("5G PPET: numss_m1 %x ru_bit_mask %x", 15201 param->eht_ppet5G.numss_m1, 15202 param->eht_ppet5G.ru_bit_mask); 15203 for (i = 0; i < PSOC_HOST_MAX_NUM_SS; i++) { 15204 wmi_nofl_debug("index %d value %x", 15205 i, param->eht_ppet5G.ppet16_ppet8_ru3_ru0[i]); 15206 } 15207 } 15208 #else 15209 static void extract_mac_phy_cap_ehtcaps( 15210 struct wlan_psoc_host_mac_phy_caps_ext2 *param, 15211 WMI_MAC_PHY_CAPABILITIES_EXT *mac_phy_caps) 15212 { 15213 } 15214 #endif 15215 15216 static QDF_STATUS extract_mac_phy_cap_service_ready_ext2_tlv( 15217 wmi_unified_t wmi_handle, 15218 uint8_t *event, uint8_t hw_mode_id, uint8_t phy_id, 15219 uint8_t phy_idx, 15220 struct wlan_psoc_host_mac_phy_caps_ext2 *param) 15221 { 15222 WMI_SERVICE_READY_EXT2_EVENTID_param_tlvs *param_buf; 15223 WMI_MAC_PHY_CAPABILITIES_EXT *mac_phy_caps; 15224 15225 if (!event) { 15226 wmi_err("null evt_buf"); 15227 return QDF_STATUS_E_INVAL; 15228 } 15229 15230 param_buf = (WMI_SERVICE_READY_EXT2_EVENTID_param_tlvs *)event; 15231 15232 if (!param_buf->num_mac_phy_caps) 15233 return QDF_STATUS_SUCCESS; 15234 15235 if (phy_idx >= param_buf->num_mac_phy_caps) 15236 return QDF_STATUS_E_INVAL; 15237 15238 mac_phy_caps = ¶m_buf->mac_phy_caps[phy_idx]; 15239 15240 if ((hw_mode_id != mac_phy_caps->hw_mode_id) || 15241 (phy_id != mac_phy_caps->phy_id)) 15242 return QDF_STATUS_E_INVAL; 15243 15244 param->hw_mode_id = mac_phy_caps->hw_mode_id; 15245 param->phy_id = mac_phy_caps->phy_id; 15246 param->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host( 15247 wmi_handle, WMI_PHY_GET_PDEV_ID(mac_phy_caps->pdev_id)); 15248 param->wireless_modes_ext = convert_wireless_modes_ext_tlv( 15249 mac_phy_caps->wireless_modes_ext); 15250 15251 extract_mac_phy_cap_ehtcaps(param, mac_phy_caps); 15252 extract_mac_phy_emlcap(param, mac_phy_caps); 15253 extract_mac_phy_mldcap(param, mac_phy_caps); 15254 extract_mac_phy_msdcap(param, mac_phy_caps); 15255 15256 return QDF_STATUS_SUCCESS; 15257 } 15258 15259 /** 15260 * extract_reg_cap_service_ready_ext_tlv() - 15261 * extract REG cap from service ready event 15262 * @wmi_handle: wmi handle 15263 * @event: pointer to event buffer 15264 * @phy_idx: phy idx should be less than num_mode 15265 * @param: Pointer to hold evt buf 15266 * 15267 * Return: QDF_STATUS_SUCCESS for success or error code 15268 */ 15269 static QDF_STATUS extract_reg_cap_service_ready_ext_tlv( 15270 wmi_unified_t wmi_handle, 15271 uint8_t *event, uint8_t phy_idx, 15272 struct wlan_psoc_host_hal_reg_capabilities_ext *param) 15273 { 15274 WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *param_buf; 15275 WMI_SOC_HAL_REG_CAPABILITIES *reg_caps; 15276 WMI_HAL_REG_CAPABILITIES_EXT *ext_reg_cap; 15277 15278 param_buf = (WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *) event; 15279 if (!param_buf) 15280 return QDF_STATUS_E_INVAL; 15281 15282 reg_caps = param_buf->soc_hal_reg_caps; 15283 if (!reg_caps) 15284 return QDF_STATUS_E_INVAL; 15285 15286 if (reg_caps->num_phy > param_buf->num_hal_reg_caps) 15287 return QDF_STATUS_E_INVAL; 15288 15289 if (phy_idx >= reg_caps->num_phy) 15290 return QDF_STATUS_E_INVAL; 15291 15292 if (!param_buf->hal_reg_caps) 15293 return QDF_STATUS_E_INVAL; 15294 15295 ext_reg_cap = ¶m_buf->hal_reg_caps[phy_idx]; 15296 15297 param->phy_id = ext_reg_cap->phy_id; 15298 param->eeprom_reg_domain = ext_reg_cap->eeprom_reg_domain; 15299 param->eeprom_reg_domain_ext = ext_reg_cap->eeprom_reg_domain_ext; 15300 param->regcap1 = ext_reg_cap->regcap1; 15301 param->regcap2 = ext_reg_cap->regcap2; 15302 param->wireless_modes = convert_wireless_modes_tlv( 15303 ext_reg_cap->wireless_modes); 15304 param->low_2ghz_chan = ext_reg_cap->low_2ghz_chan; 15305 param->high_2ghz_chan = ext_reg_cap->high_2ghz_chan; 15306 param->low_5ghz_chan = ext_reg_cap->low_5ghz_chan; 15307 param->high_5ghz_chan = ext_reg_cap->high_5ghz_chan; 15308 15309 return QDF_STATUS_SUCCESS; 15310 } 15311 15312 static QDF_STATUS validate_dbr_ring_caps_idx(uint8_t idx, 15313 uint8_t num_dma_ring_caps) 15314 { 15315 /* If dma_ring_caps is populated, num_dbr_ring_caps is non-zero */ 15316 if (!num_dma_ring_caps) { 15317 wmi_err("dma_ring_caps %d", num_dma_ring_caps); 15318 return QDF_STATUS_E_INVAL; 15319 } 15320 if (idx >= num_dma_ring_caps) { 15321 wmi_err("Index %d exceeds range", idx); 15322 return QDF_STATUS_E_INVAL; 15323 } 15324 return QDF_STATUS_SUCCESS; 15325 } 15326 15327 static void 15328 populate_dbr_ring_cap_elems(wmi_unified_t wmi_handle, 15329 struct wlan_psoc_host_dbr_ring_caps *param, 15330 WMI_DMA_RING_CAPABILITIES *dbr_ring_caps) 15331 { 15332 param->pdev_id = wmi_handle->ops->convert_target_pdev_id_to_host( 15333 wmi_handle, 15334 dbr_ring_caps->pdev_id); 15335 param->mod_id = dbr_ring_caps->mod_id; 15336 param->ring_elems_min = dbr_ring_caps->ring_elems_min; 15337 param->min_buf_size = dbr_ring_caps->min_buf_size; 15338 param->min_buf_align = dbr_ring_caps->min_buf_align; 15339 } 15340 15341 static QDF_STATUS extract_dbr_ring_cap_service_ready_ext_tlv( 15342 wmi_unified_t wmi_handle, 15343 uint8_t *event, uint8_t idx, 15344 struct wlan_psoc_host_dbr_ring_caps *param) 15345 { 15346 WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *param_buf; 15347 QDF_STATUS status; 15348 15349 param_buf = (WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *)event; 15350 if (!param_buf) 15351 return QDF_STATUS_E_INVAL; 15352 15353 status = validate_dbr_ring_caps_idx(idx, param_buf->num_dma_ring_caps); 15354 if (status != QDF_STATUS_SUCCESS) 15355 return status; 15356 15357 populate_dbr_ring_cap_elems(wmi_handle, param, 15358 ¶m_buf->dma_ring_caps[idx]); 15359 return QDF_STATUS_SUCCESS; 15360 } 15361 15362 static QDF_STATUS extract_dbr_ring_cap_service_ready_ext2_tlv( 15363 wmi_unified_t wmi_handle, 15364 uint8_t *event, uint8_t idx, 15365 struct wlan_psoc_host_dbr_ring_caps *param) 15366 { 15367 WMI_SERVICE_READY_EXT2_EVENTID_param_tlvs *param_buf; 15368 QDF_STATUS status; 15369 15370 param_buf = (WMI_SERVICE_READY_EXT2_EVENTID_param_tlvs *)event; 15371 if (!param_buf) 15372 return QDF_STATUS_E_INVAL; 15373 15374 status = validate_dbr_ring_caps_idx(idx, param_buf->num_dma_ring_caps); 15375 if (status != QDF_STATUS_SUCCESS) 15376 return status; 15377 15378 populate_dbr_ring_cap_elems(wmi_handle, param, 15379 ¶m_buf->dma_ring_caps[idx]); 15380 return QDF_STATUS_SUCCESS; 15381 } 15382 15383 static QDF_STATUS extract_scan_radio_cap_service_ready_ext2_tlv( 15384 wmi_unified_t wmi_handle, 15385 uint8_t *event, uint8_t idx, 15386 struct wlan_psoc_host_scan_radio_caps *param) 15387 { 15388 WMI_SERVICE_READY_EXT2_EVENTID_param_tlvs *param_buf; 15389 WMI_SCAN_RADIO_CAPABILITIES_EXT2 *scan_radio_caps; 15390 15391 param_buf = (WMI_SERVICE_READY_EXT2_EVENTID_param_tlvs *)event; 15392 if (!param_buf) 15393 return QDF_STATUS_E_INVAL; 15394 15395 if (idx >= param_buf->num_wmi_scan_radio_caps) 15396 return QDF_STATUS_E_INVAL; 15397 15398 scan_radio_caps = ¶m_buf->wmi_scan_radio_caps[idx]; 15399 param->phy_id = scan_radio_caps->phy_id; 15400 param->scan_radio_supported = 15401 WMI_SCAN_RADIO_CAP_SCAN_RADIO_FLAG_GET(scan_radio_caps->flags); 15402 param->dfs_en = 15403 WMI_SCAN_RADIO_CAP_DFS_FLAG_GET(scan_radio_caps->flags); 15404 param->blanking_en = 15405 WMI_SCAN_RADIO_CAP_BLANKING_SUPPORT_GET(scan_radio_caps->flags); 15406 15407 return QDF_STATUS_SUCCESS; 15408 } 15409 15410 static QDF_STATUS extract_msdu_idx_qtype_map_service_ready_ext2_tlv( 15411 wmi_unified_t wmi_handle, 15412 uint8_t *event, uint8_t idx, 15413 uint8_t *msdu_qtype) 15414 { 15415 WMI_SERVICE_READY_EXT2_EVENTID_param_tlvs *param_buf; 15416 wmi_htt_msdu_idx_to_htt_msdu_qtype *msdu_idx_to_qtype; 15417 uint8_t wmi_htt_msdu_idx; 15418 15419 param_buf = (WMI_SERVICE_READY_EXT2_EVENTID_param_tlvs *)event; 15420 if (!param_buf) 15421 return QDF_STATUS_E_INVAL; 15422 15423 if (idx >= param_buf->num_htt_msdu_idx_to_qtype_map) 15424 return QDF_STATUS_E_INVAL; 15425 15426 msdu_idx_to_qtype = ¶m_buf->htt_msdu_idx_to_qtype_map[idx]; 15427 wmi_htt_msdu_idx = 15428 WMI_HTT_MSDUQ_IDX_TO_MSDUQ_QTYPE_INDEX_GET( 15429 msdu_idx_to_qtype->index_and_type); 15430 if (wmi_htt_msdu_idx != idx) { 15431 wmi_err("wmi_htt_msdu_idx 0x%x is not same as idx 0x%x", 15432 wmi_htt_msdu_idx, idx); 15433 return QDF_STATUS_E_INVAL; 15434 } 15435 15436 *msdu_qtype = 15437 WMI_HTT_MSDUQ_IDX_TO_MSDUQ_QTYPE_TYPE_GET( 15438 msdu_idx_to_qtype->index_and_type); 15439 15440 return QDF_STATUS_SUCCESS; 15441 } 15442 15443 static QDF_STATUS extract_sw_cal_ver_ext2_tlv(wmi_unified_t wmi_handle, 15444 uint8_t *event, 15445 struct wmi_host_sw_cal_ver *cal) 15446 { 15447 WMI_SERVICE_READY_EXT2_EVENTID_param_tlvs *param_buf; 15448 wmi_sw_cal_ver_cap *fw_cap; 15449 15450 param_buf = (WMI_SERVICE_READY_EXT2_EVENTID_param_tlvs *)event; 15451 if (!param_buf) 15452 return QDF_STATUS_E_INVAL; 15453 15454 fw_cap = param_buf->sw_cal_ver_cap; 15455 if (!fw_cap) 15456 return QDF_STATUS_E_INVAL; 15457 15458 cal->bdf_cal_ver = fw_cap->bdf_cal_ver; 15459 cal->ftm_cal_ver = fw_cap->ftm_cal_ver; 15460 cal->status = fw_cap->status; 15461 15462 return QDF_STATUS_SUCCESS; 15463 } 15464 15465 static QDF_STATUS extract_aux_dev_cap_service_ready_ext2_tlv( 15466 wmi_unified_t wmi_handle, 15467 uint8_t *event, uint8_t idx, 15468 struct wlan_psoc_host_aux_dev_caps *param) 15469 15470 { 15471 WMI_SERVICE_READY_EXT2_EVENTID_param_tlvs *param_buf; 15472 wmi_aux_dev_capabilities *aux_dev_caps; 15473 15474 param_buf = (WMI_SERVICE_READY_EXT2_EVENTID_param_tlvs *)event; 15475 15476 if (!param_buf->num_aux_dev_caps) 15477 return QDF_STATUS_E_INVAL; 15478 15479 if (!param_buf->aux_dev_caps) { 15480 wmi_err("aux_dev_caps is NULL"); 15481 return QDF_STATUS_E_INVAL; 15482 } 15483 15484 if (idx >= param_buf->num_aux_dev_caps) 15485 return QDF_STATUS_E_INVAL; 15486 15487 aux_dev_caps = ¶m_buf->aux_dev_caps[idx]; 15488 15489 param->aux_index = aux_dev_caps->aux_index; 15490 param->hw_mode_id = aux_dev_caps->hw_mode_id; 15491 param->supported_modes_bitmap = aux_dev_caps->supported_modes_bitmap; 15492 param->listen_pdev_id_map = aux_dev_caps->listen_pdev_id_map; 15493 param->emlsr_pdev_id_map = aux_dev_caps->emlsr_pdev_id_map; 15494 15495 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", 15496 idx, aux_dev_caps->aux_index, 15497 aux_dev_caps->hw_mode_id, 15498 aux_dev_caps->supported_modes_bitmap, 15499 aux_dev_caps->listen_pdev_id_map, 15500 aux_dev_caps->emlsr_pdev_id_map); 15501 15502 return QDF_STATUS_SUCCESS; 15503 } 15504 15505 /** 15506 * wmi_tgt_thermal_level_to_host() - Convert target thermal level to host enum 15507 * @level: target thermal level from WMI_THERM_THROT_STATS_EVENTID event 15508 * 15509 * Return: host thermal throt level 15510 */ 15511 static enum thermal_throttle_level 15512 wmi_tgt_thermal_level_to_host(uint32_t level) 15513 { 15514 switch (level) { 15515 case WMI_THERMAL_FULLPERF: 15516 return THERMAL_FULLPERF; 15517 case WMI_THERMAL_MITIGATION: 15518 return THERMAL_MITIGATION; 15519 case WMI_THERMAL_SHUTOFF: 15520 return THERMAL_SHUTOFF; 15521 case WMI_THERMAL_SHUTDOWN_TGT: 15522 return THERMAL_SHUTDOWN_TARGET; 15523 default: 15524 return THERMAL_UNKNOWN; 15525 } 15526 } 15527 15528 #ifdef THERMAL_STATS_SUPPORT 15529 static void 15530 populate_thermal_stats(WMI_THERM_THROT_STATS_EVENTID_param_tlvs *param_buf, 15531 uint32_t *therm_throt_levels, 15532 struct thermal_throt_level_stats *tt_temp_range_stats) 15533 { 15534 uint8_t lvl_idx; 15535 wmi_therm_throt_stats_event_fixed_param *tt_stats_event; 15536 wmi_thermal_throt_temp_range_stats *wmi_tt_stats; 15537 15538 tt_stats_event = param_buf->fixed_param; 15539 *therm_throt_levels = (tt_stats_event->therm_throt_levels > 15540 WMI_THERMAL_STATS_TEMP_THRESH_LEVEL_MAX) ? 15541 WMI_THERMAL_STATS_TEMP_THRESH_LEVEL_MAX : 15542 tt_stats_event->therm_throt_levels; 15543 15544 if (*therm_throt_levels > param_buf->num_temp_range_stats) { 15545 wmi_err("therm_throt_levels:%u oob num_temp_range_stats:%u", 15546 *therm_throt_levels, 15547 param_buf->num_temp_range_stats); 15548 return; 15549 } 15550 15551 wmi_tt_stats = param_buf->temp_range_stats; 15552 if (!wmi_tt_stats) { 15553 wmi_err("wmi_tt_stats Null"); 15554 return; 15555 } 15556 15557 for (lvl_idx = 0; lvl_idx < *therm_throt_levels; lvl_idx++) { 15558 tt_temp_range_stats[lvl_idx].start_temp_level = 15559 wmi_tt_stats[lvl_idx].start_temp_level; 15560 tt_temp_range_stats[lvl_idx].end_temp_level = 15561 wmi_tt_stats[lvl_idx].end_temp_level; 15562 tt_temp_range_stats[lvl_idx].total_time_ms_lo = 15563 wmi_tt_stats[lvl_idx].total_time_ms_lo; 15564 tt_temp_range_stats[lvl_idx].total_time_ms_hi = 15565 wmi_tt_stats[lvl_idx].total_time_ms_hi; 15566 tt_temp_range_stats[lvl_idx].num_entry = 15567 wmi_tt_stats[lvl_idx].num_entry; 15568 wmi_debug("level %d, start temp %d, end temp %d, total time low %d, total time high %d, counter %d", 15569 lvl_idx, wmi_tt_stats[lvl_idx].start_temp_level, 15570 wmi_tt_stats[lvl_idx].end_temp_level, 15571 wmi_tt_stats[lvl_idx].total_time_ms_lo, 15572 wmi_tt_stats[lvl_idx].total_time_ms_hi, 15573 wmi_tt_stats[lvl_idx].num_entry); 15574 } 15575 } 15576 #else 15577 static void 15578 populate_thermal_stats(WMI_THERM_THROT_STATS_EVENTID_param_tlvs *param_buf, 15579 uint32_t *therm_throt_levels, 15580 struct thermal_throt_level_stats *tt_temp_range_stats) 15581 { 15582 } 15583 #endif 15584 15585 /** 15586 * extract_thermal_stats_tlv() - extract thermal stats from event 15587 * @wmi_handle: wmi handle 15588 * @evt_buf: Pointer to event buffer 15589 * @temp: Pointer to hold extracted temperature 15590 * @level: Pointer to hold extracted level in host enum 15591 * @therm_throt_levels: Pointer to hold extracted thermal throttle temp 15592 * range 15593 * @tt_temp_range_stats_event: Pointer to hold extracted thermal stats for 15594 * every level 15595 * @pdev_id: Pointer to hold extracted pdev id 15596 * 15597 * Return: QDF_STATUS_SUCCESS for success or error code 15598 */ 15599 static QDF_STATUS 15600 extract_thermal_stats_tlv(wmi_unified_t wmi_handle, 15601 void *evt_buf, uint32_t *temp, 15602 enum thermal_throttle_level *level, 15603 uint32_t *therm_throt_levels, 15604 struct thermal_throt_level_stats *tt_temp_range_stats_event, 15605 uint32_t *pdev_id) 15606 { 15607 WMI_THERM_THROT_STATS_EVENTID_param_tlvs *param_buf; 15608 wmi_therm_throt_stats_event_fixed_param *tt_stats_event; 15609 15610 param_buf = 15611 (WMI_THERM_THROT_STATS_EVENTID_param_tlvs *) evt_buf; 15612 if (!param_buf) 15613 return QDF_STATUS_E_INVAL; 15614 15615 tt_stats_event = param_buf->fixed_param; 15616 wmi_debug("thermal temperature %d level %d", 15617 tt_stats_event->temp, tt_stats_event->level); 15618 *pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host( 15619 wmi_handle, 15620 tt_stats_event->pdev_id); 15621 *temp = tt_stats_event->temp; 15622 *level = wmi_tgt_thermal_level_to_host(tt_stats_event->level); 15623 15624 if (tt_stats_event->therm_throt_levels) 15625 populate_thermal_stats(param_buf, therm_throt_levels, 15626 tt_temp_range_stats_event); 15627 15628 return QDF_STATUS_SUCCESS; 15629 } 15630 15631 /** 15632 * extract_thermal_level_stats_tlv() - extract thermal level stats from event 15633 * @wmi_handle: wmi handle 15634 * @evt_buf: pointer to event buffer 15635 * @idx: Index to level stats 15636 * @levelcount: Pointer to hold levelcount 15637 * @dccount: Pointer to hold dccount 15638 * 15639 * Return: QDF_STATUS_SUCCESS for success or error code 15640 */ 15641 static QDF_STATUS 15642 extract_thermal_level_stats_tlv(wmi_unified_t wmi_handle, 15643 void *evt_buf, uint8_t idx, uint32_t *levelcount, 15644 uint32_t *dccount) 15645 { 15646 WMI_THERM_THROT_STATS_EVENTID_param_tlvs *param_buf; 15647 wmi_therm_throt_level_stats_info *tt_level_info; 15648 15649 param_buf = 15650 (WMI_THERM_THROT_STATS_EVENTID_param_tlvs *) evt_buf; 15651 if (!param_buf) 15652 return QDF_STATUS_E_INVAL; 15653 15654 tt_level_info = param_buf->therm_throt_level_stats_info; 15655 15656 if (idx < THERMAL_LEVELS) { 15657 *levelcount = tt_level_info[idx].level_count; 15658 *dccount = tt_level_info[idx].dc_count; 15659 return QDF_STATUS_SUCCESS; 15660 } 15661 15662 return QDF_STATUS_E_FAILURE; 15663 } 15664 15665 /** 15666 * fips_conv_data_be() - LE to BE conversion of FIPS ev data 15667 * @data_len: data length 15668 * @data: pointer to data 15669 * 15670 * Return: QDF_STATUS - success or error status 15671 */ 15672 #ifdef BIG_ENDIAN_HOST 15673 static QDF_STATUS fips_conv_data_be(uint32_t data_len, uint8_t *data) 15674 { 15675 uint8_t *data_aligned = NULL; 15676 int c; 15677 unsigned char *data_unaligned; 15678 15679 data_unaligned = qdf_mem_malloc(((sizeof(uint8_t) * data_len) + 15680 FIPS_ALIGN)); 15681 /* Assigning unaligned space to copy the data */ 15682 /* Checking if kmalloc does successful allocation */ 15683 if (!data_unaligned) 15684 return QDF_STATUS_E_FAILURE; 15685 15686 /* Checking if space is aligned */ 15687 if (!FIPS_IS_ALIGNED(data_unaligned, FIPS_ALIGN)) { 15688 /* align the data space */ 15689 data_aligned = 15690 (uint8_t *)FIPS_ALIGNTO(data_unaligned, FIPS_ALIGN); 15691 } else { 15692 data_aligned = (u_int8_t *)data_unaligned; 15693 } 15694 15695 /* memset and copy content from data to data aligned */ 15696 OS_MEMSET(data_aligned, 0, data_len); 15697 OS_MEMCPY(data_aligned, data, data_len); 15698 /* Endianness to LE */ 15699 for (c = 0; c < data_len/4; c++) { 15700 *((u_int32_t *)data_aligned + c) = 15701 qdf_le32_to_cpu(*((u_int32_t *)data_aligned + c)); 15702 } 15703 15704 /* Copy content to event->data */ 15705 OS_MEMCPY(data, data_aligned, data_len); 15706 15707 /* clean up allocated space */ 15708 qdf_mem_free(data_unaligned); 15709 data_aligned = NULL; 15710 data_unaligned = NULL; 15711 15712 /*************************************************************/ 15713 15714 return QDF_STATUS_SUCCESS; 15715 } 15716 #else 15717 static QDF_STATUS fips_conv_data_be(uint32_t data_len, uint8_t *data) 15718 { 15719 return QDF_STATUS_SUCCESS; 15720 } 15721 #endif 15722 15723 /** 15724 * send_pdev_get_pn_cmd_tlv() - send get PN request params to fw 15725 * @wmi_handle: wmi handle 15726 * @params: PN request params for peer 15727 * 15728 * Return: QDF_STATUS - success or error status 15729 */ 15730 static QDF_STATUS 15731 send_pdev_get_pn_cmd_tlv(wmi_unified_t wmi_handle, 15732 struct peer_request_pn_param *params) 15733 { 15734 wmi_peer_tx_pn_request_cmd_fixed_param *cmd; 15735 wmi_buf_t buf; 15736 uint8_t *buf_ptr; 15737 uint32_t len = sizeof(wmi_peer_tx_pn_request_cmd_fixed_param); 15738 15739 buf = wmi_buf_alloc(wmi_handle, len); 15740 if (!buf) { 15741 wmi_err("wmi_buf_alloc failed"); 15742 return QDF_STATUS_E_FAILURE; 15743 } 15744 15745 buf_ptr = (uint8_t *)wmi_buf_data(buf); 15746 cmd = (wmi_peer_tx_pn_request_cmd_fixed_param *)buf_ptr; 15747 15748 WMITLV_SET_HDR(&cmd->tlv_header, 15749 WMITLV_TAG_STRUC_wmi_peer_tx_pn_request_cmd_fixed_param, 15750 WMITLV_GET_STRUCT_TLVLEN(wmi_peer_tx_pn_request_cmd_fixed_param)); 15751 15752 cmd->vdev_id = params->vdev_id; 15753 WMI_CHAR_ARRAY_TO_MAC_ADDR(params->peer_macaddr, &cmd->peer_macaddr); 15754 cmd->key_type = params->key_type; 15755 cmd->key_ix = params->keyix; 15756 if (wmi_unified_cmd_send(wmi_handle, buf, len, 15757 WMI_PEER_TX_PN_REQUEST_CMDID)) { 15758 wmi_err("Failed to send WMI command"); 15759 wmi_buf_free(buf); 15760 return QDF_STATUS_E_FAILURE; 15761 } 15762 return QDF_STATUS_SUCCESS; 15763 } 15764 15765 /** 15766 * extract_get_pn_data_tlv() - extract pn resp 15767 * @wmi_handle: wmi handle 15768 * @evt_buf: pointer to event buffer 15769 * @param: PN response params for peer 15770 * 15771 * Return: QDF_STATUS - success or error status 15772 */ 15773 static QDF_STATUS 15774 extract_get_pn_data_tlv(wmi_unified_t wmi_handle, void *evt_buf, 15775 struct wmi_host_get_pn_event *param) 15776 { 15777 WMI_PEER_TX_PN_RESPONSE_EVENTID_param_tlvs *param_buf; 15778 wmi_peer_tx_pn_response_event_fixed_param *event = NULL; 15779 15780 param_buf = (WMI_PEER_TX_PN_RESPONSE_EVENTID_param_tlvs *)evt_buf; 15781 event = 15782 (wmi_peer_tx_pn_response_event_fixed_param *)param_buf->fixed_param; 15783 15784 param->vdev_id = event->vdev_id; 15785 param->key_type = event->key_type; 15786 param->key_ix = event->key_ix; 15787 qdf_mem_copy(param->pn, event->pn, sizeof(event->pn)); 15788 WMI_MAC_ADDR_TO_CHAR_ARRAY(&event->peer_macaddr, param->mac_addr); 15789 15790 return QDF_STATUS_SUCCESS; 15791 } 15792 15793 /** 15794 * send_pdev_get_rxpn_cmd_tlv() - send get Rx PN request params to fw 15795 * @wmi_handle: wmi handle 15796 * @params: Rx PN request params for peer 15797 * 15798 * Return: QDF_STATUS - success or error status 15799 */ 15800 static QDF_STATUS 15801 send_pdev_get_rxpn_cmd_tlv(wmi_unified_t wmi_handle, 15802 struct peer_request_rxpn_param *params) 15803 { 15804 wmi_peer_rx_pn_request_cmd_fixed_param *cmd; 15805 wmi_buf_t buf; 15806 uint8_t *buf_ptr; 15807 uint32_t len = sizeof(wmi_peer_rx_pn_request_cmd_fixed_param); 15808 15809 if (!is_service_enabled_tlv(wmi_handle, 15810 WMI_SERVICE_PN_REPLAY_CHECK_SUPPORT)) { 15811 wmi_err("Rx PN Replay Check not supported by target"); 15812 return QDF_STATUS_E_NOSUPPORT; 15813 } 15814 15815 buf = wmi_buf_alloc(wmi_handle, len); 15816 if (!buf) { 15817 wmi_err("wmi_buf_alloc failed"); 15818 return QDF_STATUS_E_FAILURE; 15819 } 15820 15821 buf_ptr = (uint8_t *)wmi_buf_data(buf); 15822 cmd = (wmi_peer_rx_pn_request_cmd_fixed_param *)buf_ptr; 15823 15824 WMITLV_SET_HDR(&cmd->tlv_header, 15825 WMITLV_TAG_STRUC_wmi_peer_rx_pn_request_cmd_fixed_param, 15826 WMITLV_GET_STRUCT_TLVLEN(wmi_peer_rx_pn_request_cmd_fixed_param)); 15827 15828 cmd->vdev_id = params->vdev_id; 15829 WMI_CHAR_ARRAY_TO_MAC_ADDR(params->peer_macaddr, &cmd->peer_macaddr); 15830 cmd->key_ix = params->keyix; 15831 if (wmi_unified_cmd_send(wmi_handle, buf, len, 15832 WMI_PEER_RX_PN_REQUEST_CMDID)) { 15833 wmi_err("Failed to send WMI command"); 15834 wmi_buf_free(buf); 15835 return QDF_STATUS_E_FAILURE; 15836 } 15837 return QDF_STATUS_SUCCESS; 15838 } 15839 15840 /** 15841 * extract_get_rxpn_data_tlv() - extract Rx PN resp 15842 * @wmi_handle: wmi handle 15843 * @evt_buf: pointer to event buffer 15844 * @params: Rx PN response params for peer 15845 * 15846 * Return: QDF_STATUS - success or error status 15847 */ 15848 static QDF_STATUS 15849 extract_get_rxpn_data_tlv(wmi_unified_t wmi_handle, void *evt_buf, 15850 struct wmi_host_get_rxpn_event *params) 15851 { 15852 WMI_PEER_RX_PN_RESPONSE_EVENTID_param_tlvs *param_buf; 15853 wmi_peer_rx_pn_response_event_fixed_param *event; 15854 15855 param_buf = evt_buf; 15856 event = param_buf->fixed_param; 15857 15858 params->vdev_id = event->vdev_id; 15859 params->keyix = event->key_idx; 15860 qdf_mem_copy(params->pn, event->pn, sizeof(event->pn)); 15861 WMI_MAC_ADDR_TO_CHAR_ARRAY(&event->peer_macaddr, params->mac_addr); 15862 15863 return QDF_STATUS_SUCCESS; 15864 } 15865 15866 /** 15867 * extract_fips_event_data_tlv() - extract fips event data 15868 * @wmi_handle: wmi handle 15869 * @evt_buf: pointer to event buffer 15870 * @param: pointer FIPS event params 15871 * 15872 * Return: QDF_STATUS_SUCCESS for success or error code 15873 */ 15874 static QDF_STATUS extract_fips_event_data_tlv(wmi_unified_t wmi_handle, 15875 void *evt_buf, struct wmi_host_fips_event_param *param) 15876 { 15877 WMI_PDEV_FIPS_EVENTID_param_tlvs *param_buf; 15878 wmi_pdev_fips_event_fixed_param *event; 15879 15880 param_buf = (WMI_PDEV_FIPS_EVENTID_param_tlvs *) evt_buf; 15881 event = (wmi_pdev_fips_event_fixed_param *) param_buf->fixed_param; 15882 15883 if (event->data_len > param_buf->num_data) 15884 return QDF_STATUS_E_FAILURE; 15885 15886 if (fips_conv_data_be(event->data_len, param_buf->data) != 15887 QDF_STATUS_SUCCESS) 15888 return QDF_STATUS_E_FAILURE; 15889 15890 param->data = (uint32_t *)param_buf->data; 15891 param->data_len = event->data_len; 15892 param->error_status = event->error_status; 15893 param->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host( 15894 wmi_handle, 15895 event->pdev_id); 15896 15897 return QDF_STATUS_SUCCESS; 15898 } 15899 15900 #ifdef WLAN_FEATURE_FIPS_BER_CCMGCM 15901 /** 15902 * extract_fips_extend_event_data_tlv() - extract fips event data 15903 * @wmi_handle: wmi handle 15904 * @evt_buf: pointer to event buffer 15905 * @param: pointer FIPS event params 15906 * 15907 * Return: QDF_STATUS_SUCCESS for success or error code 15908 */ 15909 static QDF_STATUS 15910 extract_fips_extend_event_data_tlv(wmi_unified_t wmi_handle, 15911 void *evt_buf, 15912 struct wmi_host_fips_extend_event_param 15913 *param) 15914 { 15915 WMI_PDEV_FIPS_EXTEND_EVENTID_param_tlvs *param_buf; 15916 wmi_pdev_fips_extend_event_fixed_param *event; 15917 15918 param_buf = (WMI_PDEV_FIPS_EXTEND_EVENTID_param_tlvs *)evt_buf; 15919 event = (wmi_pdev_fips_extend_event_fixed_param *)param_buf->fixed_param; 15920 15921 if (fips_conv_data_be(event->data_len, param_buf->data) != 15922 QDF_STATUS_SUCCESS) 15923 return QDF_STATUS_E_FAILURE; 15924 15925 param->data = (uint32_t *)param_buf->data; 15926 param->data_len = event->data_len; 15927 param->error_status = event->error_status; 15928 param->fips_cookie = event->fips_cookie; 15929 param->cmd_frag_idx = event->cmd_frag_idx; 15930 param->more_bit = event->more_bit; 15931 param->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host( 15932 wmi_handle, 15933 event->pdev_id); 15934 15935 return QDF_STATUS_SUCCESS; 15936 } 15937 #endif 15938 15939 #ifdef WLAN_FEATURE_DISA 15940 /** 15941 * extract_encrypt_decrypt_resp_event_tlv() - extract encrypt decrypt resp 15942 * params from event 15943 * @wmi_handle: wmi handle 15944 * @evt_buf: pointer to event buffer 15945 * @resp: Pointer to hold resp parameters 15946 * 15947 * Return: QDF_STATUS_SUCCESS for success or error code 15948 */ 15949 static QDF_STATUS 15950 extract_encrypt_decrypt_resp_event_tlv(wmi_unified_t wmi_handle, 15951 void *evt_buf, 15952 struct disa_encrypt_decrypt_resp_params 15953 *resp) 15954 { 15955 WMI_VDEV_ENCRYPT_DECRYPT_DATA_RESP_EVENTID_param_tlvs *param_buf; 15956 wmi_vdev_encrypt_decrypt_data_resp_event_fixed_param *data_event; 15957 15958 param_buf = evt_buf; 15959 if (!param_buf) { 15960 wmi_err("encrypt decrypt resp evt_buf is NULL"); 15961 return QDF_STATUS_E_INVAL; 15962 } 15963 15964 data_event = param_buf->fixed_param; 15965 15966 resp->vdev_id = data_event->vdev_id; 15967 resp->status = data_event->status; 15968 15969 if ((data_event->data_length > param_buf->num_enc80211_frame) || 15970 (data_event->data_length > WMI_SVC_MSG_MAX_SIZE - 15971 WMI_TLV_HDR_SIZE - sizeof(*data_event))) { 15972 wmi_err("FW msg data_len %d more than TLV hdr %d", 15973 data_event->data_length, 15974 param_buf->num_enc80211_frame); 15975 return QDF_STATUS_E_INVAL; 15976 } 15977 15978 resp->data_len = data_event->data_length; 15979 15980 if (resp->data_len) 15981 resp->data = (uint8_t *)param_buf->enc80211_frame; 15982 15983 return QDF_STATUS_SUCCESS; 15984 } 15985 #endif /* WLAN_FEATURE_DISA */ 15986 15987 static bool is_management_record_tlv(uint32_t cmd_id) 15988 { 15989 switch (cmd_id) { 15990 case WMI_MGMT_TX_SEND_CMDID: 15991 case WMI_MGMT_TX_COMPLETION_EVENTID: 15992 case WMI_OFFCHAN_DATA_TX_SEND_CMDID: 15993 case WMI_MGMT_RX_EVENTID: 15994 return true; 15995 default: 15996 return false; 15997 } 15998 } 15999 16000 static bool is_diag_event_tlv(uint32_t event_id) 16001 { 16002 if (WMI_DIAG_EVENTID == event_id) 16003 return true; 16004 16005 return false; 16006 } 16007 16008 static uint16_t wmi_tag_fw_hang_cmd(wmi_unified_t wmi_handle) 16009 { 16010 uint16_t tag = 0; 16011 16012 if (qdf_atomic_read(&wmi_handle->is_target_suspended)) { 16013 qdf_nofl_err("%s: Target is already suspended, Ignore FW Hang Command", 16014 __func__); 16015 return tag; 16016 } 16017 16018 if (wmi_handle->tag_crash_inject) 16019 tag = HTC_TX_PACKET_TAG_AUTO_PM; 16020 16021 wmi_handle->tag_crash_inject = false; 16022 return tag; 16023 } 16024 16025 /** 16026 * wmi_set_htc_tx_tag_tlv() - set HTC TX tag for WMI commands 16027 * @wmi_handle: WMI handle 16028 * @buf: WMI buffer 16029 * @cmd_id: WMI command Id 16030 * 16031 * Return: htc_tx_tag 16032 */ 16033 static uint16_t wmi_set_htc_tx_tag_tlv(wmi_unified_t wmi_handle, 16034 wmi_buf_t buf, 16035 uint32_t cmd_id) 16036 { 16037 uint16_t htc_tx_tag = 0; 16038 16039 switch (cmd_id) { 16040 case WMI_WOW_ENABLE_CMDID: 16041 case WMI_PDEV_SUSPEND_CMDID: 16042 case WMI_WOW_HOSTWAKEUP_FROM_SLEEP_CMDID: 16043 case WMI_PDEV_RESUME_CMDID: 16044 case WMI_HB_SET_ENABLE_CMDID: 16045 case WMI_WOW_SET_ACTION_WAKE_UP_CMDID: 16046 #ifdef FEATURE_WLAN_D0WOW 16047 case WMI_D0_WOW_ENABLE_DISABLE_CMDID: 16048 #endif 16049 htc_tx_tag = HTC_TX_PACKET_TAG_AUTO_PM; 16050 break; 16051 case WMI_FORCE_FW_HANG_CMDID: 16052 htc_tx_tag = wmi_tag_fw_hang_cmd(wmi_handle); 16053 break; 16054 default: 16055 break; 16056 } 16057 16058 return htc_tx_tag; 16059 } 16060 16061 #ifdef CONFIG_BAND_6GHZ 16062 16063 static struct cur_reg_rule 16064 *create_ext_reg_rules_from_wmi(uint32_t num_reg_rules, 16065 wmi_regulatory_rule_ext_struct *wmi_reg_rule) 16066 { 16067 struct cur_reg_rule *reg_rule_ptr; 16068 uint32_t count; 16069 16070 if (!num_reg_rules) 16071 return NULL; 16072 16073 reg_rule_ptr = qdf_mem_malloc(num_reg_rules * 16074 sizeof(*reg_rule_ptr)); 16075 16076 if (!reg_rule_ptr) 16077 return NULL; 16078 16079 for (count = 0; count < num_reg_rules; count++) { 16080 reg_rule_ptr[count].start_freq = 16081 WMI_REG_RULE_START_FREQ_GET( 16082 wmi_reg_rule[count].freq_info); 16083 reg_rule_ptr[count].end_freq = 16084 WMI_REG_RULE_END_FREQ_GET( 16085 wmi_reg_rule[count].freq_info); 16086 reg_rule_ptr[count].max_bw = 16087 WMI_REG_RULE_MAX_BW_GET( 16088 wmi_reg_rule[count].bw_pwr_info); 16089 reg_rule_ptr[count].reg_power = 16090 WMI_REG_RULE_REG_POWER_GET( 16091 wmi_reg_rule[count].bw_pwr_info); 16092 reg_rule_ptr[count].ant_gain = 16093 WMI_REG_RULE_ANTENNA_GAIN_GET( 16094 wmi_reg_rule[count].bw_pwr_info); 16095 reg_rule_ptr[count].flags = 16096 WMI_REG_RULE_FLAGS_GET( 16097 wmi_reg_rule[count].flag_info); 16098 reg_rule_ptr[count].psd_flag = 16099 WMI_REG_RULE_PSD_FLAG_GET( 16100 wmi_reg_rule[count].psd_power_info); 16101 reg_rule_ptr[count].psd_eirp = 16102 WMI_REG_RULE_PSD_EIRP_GET( 16103 wmi_reg_rule[count].psd_power_info); 16104 } 16105 16106 return reg_rule_ptr; 16107 } 16108 #endif 16109 16110 static struct cur_reg_rule 16111 *create_reg_rules_from_wmi(uint32_t num_reg_rules, 16112 wmi_regulatory_rule_struct *wmi_reg_rule) 16113 { 16114 struct cur_reg_rule *reg_rule_ptr; 16115 uint32_t count; 16116 16117 if (!num_reg_rules) 16118 return NULL; 16119 16120 reg_rule_ptr = qdf_mem_malloc(num_reg_rules * 16121 sizeof(*reg_rule_ptr)); 16122 16123 if (!reg_rule_ptr) 16124 return NULL; 16125 16126 for (count = 0; count < num_reg_rules; count++) { 16127 reg_rule_ptr[count].start_freq = 16128 WMI_REG_RULE_START_FREQ_GET( 16129 wmi_reg_rule[count].freq_info); 16130 reg_rule_ptr[count].end_freq = 16131 WMI_REG_RULE_END_FREQ_GET( 16132 wmi_reg_rule[count].freq_info); 16133 reg_rule_ptr[count].max_bw = 16134 WMI_REG_RULE_MAX_BW_GET( 16135 wmi_reg_rule[count].bw_pwr_info); 16136 reg_rule_ptr[count].reg_power = 16137 WMI_REG_RULE_REG_POWER_GET( 16138 wmi_reg_rule[count].bw_pwr_info); 16139 reg_rule_ptr[count].ant_gain = 16140 WMI_REG_RULE_ANTENNA_GAIN_GET( 16141 wmi_reg_rule[count].bw_pwr_info); 16142 reg_rule_ptr[count].flags = 16143 WMI_REG_RULE_FLAGS_GET( 16144 wmi_reg_rule[count].flag_info); 16145 } 16146 16147 return reg_rule_ptr; 16148 } 16149 16150 static enum cc_setting_code wmi_reg_status_to_reg_status( 16151 WMI_REG_SET_CC_STATUS_CODE wmi_status_code) 16152 { 16153 if (wmi_status_code == WMI_REG_SET_CC_STATUS_PASS) { 16154 wmi_nofl_debug("REG_SET_CC_STATUS_PASS"); 16155 return REG_SET_CC_STATUS_PASS; 16156 } else if (wmi_status_code == WMI_REG_CURRENT_ALPHA2_NOT_FOUND) { 16157 wmi_nofl_debug("WMI_REG_CURRENT_ALPHA2_NOT_FOUND"); 16158 return REG_CURRENT_ALPHA2_NOT_FOUND; 16159 } else if (wmi_status_code == WMI_REG_INIT_ALPHA2_NOT_FOUND) { 16160 wmi_nofl_debug("WMI_REG_INIT_ALPHA2_NOT_FOUND"); 16161 return REG_INIT_ALPHA2_NOT_FOUND; 16162 } else if (wmi_status_code == WMI_REG_SET_CC_CHANGE_NOT_ALLOWED) { 16163 wmi_nofl_debug("WMI_REG_SET_CC_CHANGE_NOT_ALLOWED"); 16164 return REG_SET_CC_CHANGE_NOT_ALLOWED; 16165 } else if (wmi_status_code == WMI_REG_SET_CC_STATUS_NO_MEMORY) { 16166 wmi_nofl_debug("WMI_REG_SET_CC_STATUS_NO_MEMORY"); 16167 return REG_SET_CC_STATUS_NO_MEMORY; 16168 } else if (wmi_status_code == WMI_REG_SET_CC_STATUS_FAIL) { 16169 wmi_nofl_debug("WMI_REG_SET_CC_STATUS_FAIL"); 16170 return REG_SET_CC_STATUS_FAIL; 16171 } 16172 16173 wmi_debug("Unknown reg status code from WMI"); 16174 return REG_SET_CC_STATUS_FAIL; 16175 } 16176 16177 #ifdef CONFIG_BAND_6GHZ 16178 /** 16179 * reg_print_ap_power_type_6ghz - Prints the AP Power type 16180 * @ap_type: 6ghz-AP Power type 16181 * 16182 * Return: void 16183 */ 16184 static void reg_print_ap_power_type_6ghz(enum reg_6g_ap_type ap_type) 16185 { 16186 switch (ap_type) { 16187 case REG_INDOOR_AP: 16188 wmi_nofl_debug("AP Power type %s", "LOW POWER INDOOR"); 16189 break; 16190 case REG_STANDARD_POWER_AP: 16191 wmi_nofl_debug("AP Power type %s", "STANDARD POWER"); 16192 break; 16193 case REG_VERY_LOW_POWER_AP: 16194 wmi_nofl_debug("AP Power type %s", "VERY LOW POWER INDOOR"); 16195 break; 16196 default: 16197 wmi_nofl_debug("Invalid AP Power type %u", ap_type); 16198 } 16199 } 16200 16201 /** 16202 * reg_print_6ghz_client_type - Prints the client type 16203 * @client_type: 6ghz-client type 16204 * 16205 * Return: void 16206 */ 16207 static void reg_print_6ghz_client_type(enum reg_6g_client_type client_type) 16208 { 16209 switch (client_type) { 16210 case REG_DEFAULT_CLIENT: 16211 wmi_nofl_debug("Client type %s", "DEFAULT CLIENT"); 16212 break; 16213 case REG_SUBORDINATE_CLIENT: 16214 wmi_nofl_debug("Client type %s", "SUBORDINATE CLIENT"); 16215 break; 16216 default: 16217 wmi_nofl_debug("Invalid Client type %u", client_type); 16218 } 16219 } 16220 #else 16221 static inline void reg_print_ap_power_type_6ghz(enum reg_6g_ap_type ap_type) 16222 { 16223 } 16224 16225 static inline void reg_print_6ghz_client_type(enum reg_6g_client_type client_type) 16226 { 16227 } 16228 #endif /* CONFIG_BAND_6GHZ */ 16229 16230 #ifdef CONFIG_BAND_6GHZ 16231 16232 #ifdef CONFIG_REG_CLIENT 16233 #define MAX_NUM_FCC_RULES 2 16234 16235 /** 16236 * extract_ext_fcc_rules_from_wmi - extract fcc rules from WMI TLV 16237 * @num_fcc_rules: Number of FCC rules 16238 * @wmi_fcc_rule: WMI FCC rules TLV 16239 * 16240 * Return: fcc_rule_ptr 16241 */ 16242 static struct cur_fcc_rule 16243 *extract_ext_fcc_rules_from_wmi(uint32_t num_fcc_rules, 16244 wmi_regulatory_fcc_rule_struct *wmi_fcc_rule) 16245 { 16246 struct cur_fcc_rule *fcc_rule_ptr; 16247 uint32_t count; 16248 16249 if (!wmi_fcc_rule) 16250 return NULL; 16251 16252 fcc_rule_ptr = qdf_mem_malloc(num_fcc_rules * 16253 sizeof(*fcc_rule_ptr)); 16254 if (!fcc_rule_ptr) 16255 return NULL; 16256 16257 for (count = 0; count < num_fcc_rules; count++) { 16258 fcc_rule_ptr[count].center_freq = 16259 WMI_REG_FCC_RULE_CHAN_FREQ_GET( 16260 wmi_fcc_rule[count].freq_info); 16261 fcc_rule_ptr[count].tx_power = 16262 WMI_REG_FCC_RULE_FCC_TX_POWER_GET( 16263 wmi_fcc_rule[count].freq_info); 16264 } 16265 16266 return fcc_rule_ptr; 16267 } 16268 16269 /** 16270 * extract_reg_fcc_rules_tlv - Extract reg fcc rules TLV 16271 * @param_buf: Pointer to WMI params TLV 16272 * @ext_chan_list_event_hdr: Pointer to REG CHAN LIST CC EXT EVENT Fixed 16273 * Params TLV 16274 * @ext_wmi_reg_rule: Pointer to REG CHAN LIST CC EXT EVENT Reg Rules TLV 16275 * @ext_wmi_chan_priority: Pointer to REG CHAN LIST CC EXT EVENT Chan 16276 * Priority TLV 16277 * @evt_buf: Pointer to REG CHAN LIST CC EXT EVENT event buffer 16278 * @reg_info: Pointer to Regulatory Info 16279 * @len: Length of REG CHAN LIST CC EXT EVENT buffer 16280 * 16281 * Return: QDF_STATUS 16282 */ 16283 static QDF_STATUS extract_reg_fcc_rules_tlv( 16284 WMI_REG_CHAN_LIST_CC_EXT_EVENTID_param_tlvs *param_buf, 16285 wmi_reg_chan_list_cc_event_ext_fixed_param *ext_chan_list_event_hdr, 16286 wmi_regulatory_rule_ext_struct *ext_wmi_reg_rule, 16287 wmi_regulatory_chan_priority_struct *ext_wmi_chan_priority, 16288 uint8_t *evt_buf, 16289 struct cur_regulatory_info *reg_info, 16290 uint32_t len) 16291 { 16292 int i; 16293 wmi_regulatory_fcc_rule_struct *ext_wmi_fcc_rule; 16294 16295 if (!param_buf) { 16296 wmi_err("invalid channel list event buf"); 16297 return QDF_STATUS_E_INVAL; 16298 } 16299 16300 reg_info->num_fcc_rules = 0; 16301 if (param_buf->reg_fcc_rule) { 16302 if (param_buf->num_reg_fcc_rule > MAX_NUM_FCC_RULES) { 16303 wmi_err("Number of fcc rules is greater than MAX_NUM_FCC_RULES"); 16304 return QDF_STATUS_E_INVAL; 16305 } 16306 16307 ext_wmi_fcc_rule = 16308 (wmi_regulatory_fcc_rule_struct *) 16309 ((uint8_t *)ext_chan_list_event_hdr + 16310 sizeof(wmi_reg_chan_list_cc_event_ext_fixed_param) + 16311 WMI_TLV_HDR_SIZE + 16312 sizeof(wmi_regulatory_rule_ext_struct) * 16313 param_buf->num_reg_rule_array + 16314 WMI_TLV_HDR_SIZE + 16315 sizeof(wmi_regulatory_chan_priority_struct) * 16316 param_buf->num_reg_chan_priority + 16317 WMI_TLV_HDR_SIZE); 16318 16319 reg_info->fcc_rules_ptr = extract_ext_fcc_rules_from_wmi( 16320 param_buf->num_reg_fcc_rule, 16321 ext_wmi_fcc_rule); 16322 16323 reg_info->num_fcc_rules = param_buf->num_reg_fcc_rule; 16324 } else { 16325 wmi_err("Fcc rules not sent by fw"); 16326 } 16327 16328 if (reg_info->fcc_rules_ptr) { 16329 for (i = 0; i < reg_info->num_fcc_rules; i++) { 16330 wmi_nofl_debug("FCC rule %d center_freq %d tx_power %d", 16331 i, reg_info->fcc_rules_ptr[i].center_freq, 16332 reg_info->fcc_rules_ptr[i].tx_power); 16333 } 16334 } 16335 return QDF_STATUS_SUCCESS; 16336 } 16337 #else 16338 static QDF_STATUS extract_reg_fcc_rules_tlv( 16339 WMI_REG_CHAN_LIST_CC_EXT_EVENTID_param_tlvs *param_buf, 16340 wmi_reg_chan_list_cc_event_ext_fixed_param *ext_chan_list_event_hdr, 16341 wmi_regulatory_rule_ext_struct *ext_wmi_reg_rule, 16342 wmi_regulatory_chan_priority_struct *ext_wmi_chan_priority, 16343 uint8_t *evt_buf, 16344 struct cur_regulatory_info *reg_info, 16345 uint32_t len) 16346 { 16347 return QDF_STATUS_SUCCESS; 16348 } 16349 #endif 16350 16351 static QDF_STATUS extract_reg_chan_list_ext_update_event_tlv( 16352 wmi_unified_t wmi_handle, uint8_t *evt_buf, 16353 struct cur_regulatory_info *reg_info, uint32_t len) 16354 { 16355 uint32_t i, j, k; 16356 WMI_REG_CHAN_LIST_CC_EXT_EVENTID_param_tlvs *param_buf; 16357 wmi_reg_chan_list_cc_event_ext_fixed_param *ext_chan_list_event_hdr; 16358 wmi_regulatory_rule_ext_struct *ext_wmi_reg_rule; 16359 wmi_regulatory_chan_priority_struct *ext_wmi_chan_priority; 16360 uint32_t num_2g_reg_rules, num_5g_reg_rules; 16361 uint32_t num_6g_reg_rules_ap[REG_CURRENT_MAX_AP_TYPE]; 16362 uint32_t *num_6g_reg_rules_client[REG_CURRENT_MAX_AP_TYPE]; 16363 uint32_t total_reg_rules = 0; 16364 QDF_STATUS status; 16365 16366 param_buf = (WMI_REG_CHAN_LIST_CC_EXT_EVENTID_param_tlvs *)evt_buf; 16367 if (!param_buf) { 16368 wmi_err("invalid channel list event buf"); 16369 return QDF_STATUS_E_FAILURE; 16370 } 16371 16372 ext_chan_list_event_hdr = param_buf->fixed_param; 16373 ext_wmi_chan_priority = param_buf->reg_chan_priority; 16374 16375 if (ext_wmi_chan_priority) 16376 reg_info->reg_6g_thresh_priority_freq = 16377 WMI_GET_BITS(ext_wmi_chan_priority->freq_info, 0, 16); 16378 reg_info->num_2g_reg_rules = ext_chan_list_event_hdr->num_2g_reg_rules; 16379 reg_info->num_5g_reg_rules = ext_chan_list_event_hdr->num_5g_reg_rules; 16380 reg_info->num_6g_reg_rules_ap[REG_STANDARD_POWER_AP] = 16381 ext_chan_list_event_hdr->num_6g_reg_rules_ap_sp; 16382 reg_info->num_6g_reg_rules_ap[REG_INDOOR_AP] = 16383 ext_chan_list_event_hdr->num_6g_reg_rules_ap_lpi; 16384 reg_info->num_6g_reg_rules_ap[REG_VERY_LOW_POWER_AP] = 16385 ext_chan_list_event_hdr->num_6g_reg_rules_ap_vlp; 16386 16387 wmi_debug("num reg rules from fw, AP SP %d, LPI %d, VLP %d", 16388 reg_info->num_6g_reg_rules_ap[REG_STANDARD_POWER_AP], 16389 reg_info->num_6g_reg_rules_ap[REG_INDOOR_AP], 16390 reg_info->num_6g_reg_rules_ap[REG_VERY_LOW_POWER_AP]); 16391 16392 for (i = 0; i < REG_MAX_CLIENT_TYPE; i++) { 16393 reg_info->num_6g_reg_rules_client[REG_STANDARD_POWER_AP][i] = 16394 ext_chan_list_event_hdr->num_6g_reg_rules_client_sp[i]; 16395 reg_info->num_6g_reg_rules_client[REG_INDOOR_AP][i] = 16396 ext_chan_list_event_hdr->num_6g_reg_rules_client_lpi[i]; 16397 reg_info->num_6g_reg_rules_client[REG_VERY_LOW_POWER_AP][i] = 16398 ext_chan_list_event_hdr->num_6g_reg_rules_client_vlp[i]; 16399 wmi_nofl_debug("client %d SP %d, LPI %d, VLP %d", i, 16400 ext_chan_list_event_hdr->num_6g_reg_rules_client_sp[i], 16401 ext_chan_list_event_hdr->num_6g_reg_rules_client_lpi[i], 16402 ext_chan_list_event_hdr->num_6g_reg_rules_client_vlp[i]); 16403 } 16404 16405 num_2g_reg_rules = reg_info->num_2g_reg_rules; 16406 total_reg_rules += num_2g_reg_rules; 16407 num_5g_reg_rules = reg_info->num_5g_reg_rules; 16408 total_reg_rules += num_5g_reg_rules; 16409 for (i = 0; i < REG_CURRENT_MAX_AP_TYPE; i++) { 16410 num_6g_reg_rules_ap[i] = reg_info->num_6g_reg_rules_ap[i]; 16411 if (num_6g_reg_rules_ap[i] > MAX_6G_REG_RULES) { 16412 wmi_err_rl("Invalid num_6g_reg_rules_ap: %u", 16413 num_6g_reg_rules_ap[i]); 16414 return QDF_STATUS_E_FAILURE; 16415 } 16416 total_reg_rules += num_6g_reg_rules_ap[i]; 16417 num_6g_reg_rules_client[i] = 16418 reg_info->num_6g_reg_rules_client[i]; 16419 } 16420 16421 for (i = 0; i < REG_MAX_CLIENT_TYPE; i++) { 16422 total_reg_rules += 16423 num_6g_reg_rules_client[REG_STANDARD_POWER_AP][i]; 16424 total_reg_rules += num_6g_reg_rules_client[REG_INDOOR_AP][i]; 16425 total_reg_rules += 16426 num_6g_reg_rules_client[REG_VERY_LOW_POWER_AP][i]; 16427 if ((num_6g_reg_rules_client[REG_STANDARD_POWER_AP][i] > 16428 MAX_6G_REG_RULES) || 16429 (num_6g_reg_rules_client[REG_INDOOR_AP][i] > 16430 MAX_6G_REG_RULES) || 16431 (num_6g_reg_rules_client[REG_VERY_LOW_POWER_AP][i] > 16432 MAX_6G_REG_RULES)) { 16433 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", 16434 num_6g_reg_rules_client[REG_STANDARD_POWER_AP][i], 16435 num_6g_reg_rules_client[REG_INDOOR_AP][i], 16436 num_6g_reg_rules_client[REG_VERY_LOW_POWER_AP][i], 16437 i); 16438 return QDF_STATUS_E_FAILURE; 16439 } 16440 } 16441 16442 if (total_reg_rules != param_buf->num_reg_rule_array) { 16443 wmi_err_rl("Total reg rules %u does not match event params num reg rule %u", 16444 total_reg_rules, param_buf->num_reg_rule_array); 16445 return QDF_STATUS_E_FAILURE; 16446 } 16447 16448 if ((num_2g_reg_rules > MAX_REG_RULES) || 16449 (num_5g_reg_rules > MAX_REG_RULES)) { 16450 wmi_err_rl("Invalid num_2g_reg_rules: %u, num_5g_reg_rules: %u", 16451 num_2g_reg_rules, num_5g_reg_rules); 16452 return QDF_STATUS_E_FAILURE; 16453 } 16454 16455 if ((num_6g_reg_rules_ap[REG_STANDARD_POWER_AP] > MAX_6G_REG_RULES) || 16456 (num_6g_reg_rules_ap[REG_INDOOR_AP] > MAX_6G_REG_RULES) || 16457 (num_6g_reg_rules_ap[REG_VERY_LOW_POWER_AP] > MAX_6G_REG_RULES)) { 16458 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", 16459 num_6g_reg_rules_ap[REG_STANDARD_POWER_AP], 16460 num_6g_reg_rules_ap[REG_INDOOR_AP], 16461 num_6g_reg_rules_ap[REG_VERY_LOW_POWER_AP]); 16462 return QDF_STATUS_E_FAILURE; 16463 } 16464 16465 if (param_buf->num_reg_rule_array > 16466 (WMI_SVC_MSG_MAX_SIZE - sizeof(*ext_chan_list_event_hdr)) / 16467 sizeof(*ext_wmi_reg_rule)) { 16468 wmi_err_rl("Invalid ext_num_reg_rule_array: %u", 16469 param_buf->num_reg_rule_array); 16470 return QDF_STATUS_E_FAILURE; 16471 } 16472 16473 qdf_mem_copy(reg_info->alpha2, &ext_chan_list_event_hdr->alpha2, 16474 REG_ALPHA2_LEN); 16475 reg_info->dfs_region = ext_chan_list_event_hdr->dfs_region; 16476 reg_info->phybitmap = convert_phybitmap_tlv( 16477 ext_chan_list_event_hdr->phybitmap); 16478 reg_info->offload_enabled = true; 16479 reg_info->num_phy = ext_chan_list_event_hdr->num_phy; 16480 reg_info->phy_id = wmi_handle->ops->convert_phy_id_target_to_host( 16481 wmi_handle, ext_chan_list_event_hdr->phy_id); 16482 reg_info->ctry_code = ext_chan_list_event_hdr->country_id; 16483 reg_info->reg_dmn_pair = ext_chan_list_event_hdr->domain_code; 16484 16485 reg_info->status_code = 16486 wmi_reg_status_to_reg_status(ext_chan_list_event_hdr-> 16487 status_code); 16488 16489 reg_info->min_bw_2g = ext_chan_list_event_hdr->min_bw_2g; 16490 reg_info->max_bw_2g = ext_chan_list_event_hdr->max_bw_2g; 16491 reg_info->min_bw_5g = ext_chan_list_event_hdr->min_bw_5g; 16492 reg_info->max_bw_5g = ext_chan_list_event_hdr->max_bw_5g; 16493 reg_info->min_bw_6g_ap[REG_STANDARD_POWER_AP] = 16494 ext_chan_list_event_hdr->min_bw_6g_ap_sp; 16495 reg_info->max_bw_6g_ap[REG_STANDARD_POWER_AP] = 16496 ext_chan_list_event_hdr->max_bw_6g_ap_sp; 16497 reg_info->min_bw_6g_ap[REG_INDOOR_AP] = 16498 ext_chan_list_event_hdr->min_bw_6g_ap_lpi; 16499 reg_info->max_bw_6g_ap[REG_INDOOR_AP] = 16500 ext_chan_list_event_hdr->max_bw_6g_ap_lpi; 16501 reg_info->min_bw_6g_ap[REG_VERY_LOW_POWER_AP] = 16502 ext_chan_list_event_hdr->min_bw_6g_ap_vlp; 16503 reg_info->max_bw_6g_ap[REG_VERY_LOW_POWER_AP] = 16504 ext_chan_list_event_hdr->max_bw_6g_ap_vlp; 16505 16506 for (i = 0; i < REG_MAX_CLIENT_TYPE; i++) { 16507 reg_info->min_bw_6g_client[REG_STANDARD_POWER_AP][i] = 16508 ext_chan_list_event_hdr->min_bw_6g_client_sp[i]; 16509 reg_info->max_bw_6g_client[REG_STANDARD_POWER_AP][i] = 16510 ext_chan_list_event_hdr->max_bw_6g_client_sp[i]; 16511 reg_info->min_bw_6g_client[REG_INDOOR_AP][i] = 16512 ext_chan_list_event_hdr->min_bw_6g_client_lpi[i]; 16513 reg_info->max_bw_6g_client[REG_INDOOR_AP][i] = 16514 ext_chan_list_event_hdr->max_bw_6g_client_lpi[i]; 16515 reg_info->min_bw_6g_client[REG_VERY_LOW_POWER_AP][i] = 16516 ext_chan_list_event_hdr->min_bw_6g_client_vlp[i]; 16517 reg_info->max_bw_6g_client[REG_VERY_LOW_POWER_AP][i] = 16518 ext_chan_list_event_hdr->max_bw_6g_client_vlp[i]; 16519 } 16520 16521 wmi_nofl_debug("num_phys = %u and phy_id = %u", 16522 reg_info->num_phy, reg_info->phy_id); 16523 16524 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", 16525 reg_info->alpha2, reg_info->dfs_region, reg_info->reg_dmn_pair, 16526 reg_info->min_bw_2g, reg_info->max_bw_2g, reg_info->min_bw_5g, 16527 reg_info->max_bw_5g); 16528 16529 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", 16530 reg_info->min_bw_6g_ap[REG_STANDARD_POWER_AP], 16531 reg_info->max_bw_6g_ap[REG_STANDARD_POWER_AP], 16532 reg_info->min_bw_6g_ap[REG_INDOOR_AP], 16533 reg_info->max_bw_6g_ap[REG_INDOOR_AP], 16534 reg_info->min_bw_6g_ap[REG_VERY_LOW_POWER_AP], 16535 reg_info->max_bw_6g_ap[REG_VERY_LOW_POWER_AP]); 16536 16537 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", 16538 reg_info->min_bw_6g_client[REG_STANDARD_POWER_AP][REG_DEFAULT_CLIENT], 16539 reg_info->max_bw_6g_client[REG_STANDARD_POWER_AP][REG_DEFAULT_CLIENT], 16540 reg_info->min_bw_6g_client[REG_INDOOR_AP][REG_DEFAULT_CLIENT], 16541 reg_info->max_bw_6g_client[REG_INDOOR_AP][REG_DEFAULT_CLIENT], 16542 reg_info->min_bw_6g_client[REG_VERY_LOW_POWER_AP][REG_DEFAULT_CLIENT], 16543 reg_info->max_bw_6g_client[REG_VERY_LOW_POWER_AP][REG_DEFAULT_CLIENT]); 16544 16545 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", 16546 reg_info->min_bw_6g_client[REG_STANDARD_POWER_AP][REG_SUBORDINATE_CLIENT], 16547 reg_info->max_bw_6g_client[REG_STANDARD_POWER_AP][REG_SUBORDINATE_CLIENT], 16548 reg_info->min_bw_6g_client[REG_INDOOR_AP][REG_SUBORDINATE_CLIENT], 16549 reg_info->max_bw_6g_client[REG_INDOOR_AP][REG_SUBORDINATE_CLIENT], 16550 reg_info->min_bw_6g_client[REG_VERY_LOW_POWER_AP][REG_SUBORDINATE_CLIENT], 16551 reg_info->max_bw_6g_client[REG_VERY_LOW_POWER_AP][REG_SUBORDINATE_CLIENT]); 16552 16553 wmi_nofl_debug("num_2g_reg_rules %d num_5g_reg_rules %d", 16554 num_2g_reg_rules, num_5g_reg_rules); 16555 16556 wmi_nofl_debug("num_6g_ap_sp_reg_rules %d num_6g_ap_lpi_reg_rules %d num_6g_ap_vlp_reg_rules %d", 16557 reg_info->num_6g_reg_rules_ap[REG_STANDARD_POWER_AP], 16558 reg_info->num_6g_reg_rules_ap[REG_INDOOR_AP], 16559 reg_info->num_6g_reg_rules_ap[REG_VERY_LOW_POWER_AP]); 16560 16561 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", 16562 reg_info->num_6g_reg_rules_client[REG_STANDARD_POWER_AP][REG_DEFAULT_CLIENT], 16563 reg_info->num_6g_reg_rules_client[REG_INDOOR_AP][REG_DEFAULT_CLIENT], 16564 reg_info->num_6g_reg_rules_client[REG_VERY_LOW_POWER_AP][REG_DEFAULT_CLIENT]); 16565 16566 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", 16567 reg_info->num_6g_reg_rules_client[REG_STANDARD_POWER_AP][REG_SUBORDINATE_CLIENT], 16568 reg_info->num_6g_reg_rules_client[REG_INDOOR_AP][REG_SUBORDINATE_CLIENT], 16569 reg_info->num_6g_reg_rules_client[REG_VERY_LOW_POWER_AP][REG_SUBORDINATE_CLIENT]); 16570 16571 ext_wmi_reg_rule = 16572 (wmi_regulatory_rule_ext_struct *) 16573 ((uint8_t *)ext_chan_list_event_hdr + 16574 sizeof(wmi_reg_chan_list_cc_event_ext_fixed_param) + 16575 WMI_TLV_HDR_SIZE); 16576 reg_info->reg_rules_2g_ptr = 16577 create_ext_reg_rules_from_wmi(num_2g_reg_rules, 16578 ext_wmi_reg_rule); 16579 ext_wmi_reg_rule += num_2g_reg_rules; 16580 if (!num_2g_reg_rules) 16581 wmi_nofl_debug("No 2ghz reg rule"); 16582 for (i = 0; i < num_2g_reg_rules; i++) { 16583 if (!reg_info->reg_rules_2g_ptr) 16584 break; 16585 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", 16586 i, reg_info->reg_rules_2g_ptr[i].start_freq, 16587 reg_info->reg_rules_2g_ptr[i].end_freq, 16588 reg_info->reg_rules_2g_ptr[i].max_bw, 16589 reg_info->reg_rules_2g_ptr[i].reg_power, 16590 reg_info->reg_rules_2g_ptr[i].ant_gain, 16591 reg_info->reg_rules_2g_ptr[i].flags, 16592 reg_info->reg_rules_2g_ptr[i].psd_flag, 16593 reg_info->reg_rules_2g_ptr[i].psd_eirp); 16594 } 16595 reg_info->reg_rules_5g_ptr = 16596 create_ext_reg_rules_from_wmi(num_5g_reg_rules, 16597 ext_wmi_reg_rule); 16598 ext_wmi_reg_rule += num_5g_reg_rules; 16599 if (!num_5g_reg_rules) 16600 wmi_nofl_debug("No 5ghz reg rule"); 16601 for (i = 0; i < num_5g_reg_rules; i++) { 16602 if (!reg_info->reg_rules_5g_ptr) 16603 break; 16604 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", 16605 i, reg_info->reg_rules_5g_ptr[i].start_freq, 16606 reg_info->reg_rules_5g_ptr[i].end_freq, 16607 reg_info->reg_rules_5g_ptr[i].max_bw, 16608 reg_info->reg_rules_5g_ptr[i].reg_power, 16609 reg_info->reg_rules_5g_ptr[i].ant_gain, 16610 reg_info->reg_rules_5g_ptr[i].flags, 16611 reg_info->reg_rules_5g_ptr[i].psd_flag, 16612 reg_info->reg_rules_5g_ptr[i].psd_eirp); 16613 } 16614 16615 for (i = 0; i < REG_CURRENT_MAX_AP_TYPE; i++) { 16616 reg_print_ap_power_type_6ghz(i); 16617 reg_info->reg_rules_6g_ap_ptr[i] = 16618 create_ext_reg_rules_from_wmi(num_6g_reg_rules_ap[i], 16619 ext_wmi_reg_rule); 16620 16621 ext_wmi_reg_rule += num_6g_reg_rules_ap[i]; 16622 if (!num_6g_reg_rules_ap[i]) 16623 wmi_nofl_debug("No 6ghz reg rule"); 16624 for (j = 0; j < num_6g_reg_rules_ap[i]; j++) { 16625 if (!reg_info->reg_rules_6g_ap_ptr[i]) 16626 break; 16627 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", 16628 j, reg_info->reg_rules_6g_ap_ptr[i][j].start_freq, 16629 reg_info->reg_rules_6g_ap_ptr[i][j].end_freq, 16630 reg_info->reg_rules_6g_ap_ptr[i][j].max_bw, 16631 reg_info->reg_rules_6g_ap_ptr[i][j].reg_power, 16632 reg_info->reg_rules_6g_ap_ptr[i][j].ant_gain, 16633 reg_info->reg_rules_6g_ap_ptr[i][j].flags, 16634 reg_info->reg_rules_6g_ap_ptr[i][j].psd_flag, 16635 reg_info->reg_rules_6g_ap_ptr[i][j].psd_eirp); 16636 } 16637 } 16638 16639 for (j = 0; j < REG_CURRENT_MAX_AP_TYPE; j++) { 16640 reg_print_ap_power_type_6ghz(j); 16641 for (i = 0; i < REG_MAX_CLIENT_TYPE; i++) { 16642 reg_print_6ghz_client_type(i); 16643 reg_info->reg_rules_6g_client_ptr[j][i] = 16644 create_ext_reg_rules_from_wmi( 16645 num_6g_reg_rules_client[j][i], 16646 ext_wmi_reg_rule); 16647 16648 ext_wmi_reg_rule += num_6g_reg_rules_client[j][i]; 16649 if (!num_6g_reg_rules_client[j][i]) 16650 wmi_nofl_debug("No 6ghz reg rule for [%d][%d]", j, i); 16651 for (k = 0; k < num_6g_reg_rules_client[j][i]; k++) { 16652 if (!reg_info->reg_rules_6g_client_ptr[j][i]) 16653 break; 16654 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", 16655 k, reg_info->reg_rules_6g_client_ptr[j][i][k].start_freq, 16656 reg_info->reg_rules_6g_client_ptr[j][i][k].end_freq, 16657 reg_info->reg_rules_6g_client_ptr[j][i][k].max_bw, 16658 reg_info->reg_rules_6g_client_ptr[j][i][k].reg_power, 16659 reg_info->reg_rules_6g_client_ptr[j][i][k].ant_gain, 16660 reg_info->reg_rules_6g_client_ptr[j][i][k].flags, 16661 reg_info->reg_rules_6g_client_ptr[j][i][k].psd_flag, 16662 reg_info->reg_rules_6g_client_ptr[j][i][k].psd_eirp); 16663 } 16664 } 16665 } 16666 16667 reg_info->client_type = ext_chan_list_event_hdr->client_type; 16668 reg_info->rnr_tpe_usable = ext_chan_list_event_hdr->rnr_tpe_usable; 16669 reg_info->unspecified_ap_usable = 16670 ext_chan_list_event_hdr->unspecified_ap_usable; 16671 reg_info->domain_code_6g_ap[REG_STANDARD_POWER_AP] = 16672 ext_chan_list_event_hdr->domain_code_6g_ap_sp; 16673 reg_info->domain_code_6g_ap[REG_INDOOR_AP] = 16674 ext_chan_list_event_hdr->domain_code_6g_ap_lpi; 16675 reg_info->domain_code_6g_ap[REG_VERY_LOW_POWER_AP] = 16676 ext_chan_list_event_hdr->domain_code_6g_ap_vlp; 16677 16678 wmi_nofl_debug("client type %d, RNR TPE usable %d, unspecified AP usable %d, domain code AP SP %d, LPI %d, VLP %d", 16679 reg_info->client_type, reg_info->rnr_tpe_usable, 16680 reg_info->unspecified_ap_usable, 16681 reg_info->domain_code_6g_ap[REG_STANDARD_POWER_AP], 16682 reg_info->domain_code_6g_ap[REG_INDOOR_AP], 16683 reg_info->domain_code_6g_ap[REG_VERY_LOW_POWER_AP]); 16684 16685 for (i = 0; i < REG_MAX_CLIENT_TYPE; i++) { 16686 reg_info->domain_code_6g_client[REG_STANDARD_POWER_AP][i] = 16687 ext_chan_list_event_hdr->domain_code_6g_client_sp[i]; 16688 reg_info->domain_code_6g_client[REG_INDOOR_AP][i] = 16689 ext_chan_list_event_hdr->domain_code_6g_client_lpi[i]; 16690 reg_info->domain_code_6g_client[REG_VERY_LOW_POWER_AP][i] = 16691 ext_chan_list_event_hdr->domain_code_6g_client_vlp[i]; 16692 wmi_nofl_debug("domain code client %d SP %d, LPI %d, VLP %d", i, 16693 reg_info->domain_code_6g_client[REG_STANDARD_POWER_AP][i], 16694 reg_info->domain_code_6g_client[REG_INDOOR_AP][i], 16695 reg_info->domain_code_6g_client[REG_VERY_LOW_POWER_AP][i]); 16696 } 16697 16698 reg_info->domain_code_6g_super_id = 16699 ext_chan_list_event_hdr->domain_code_6g_super_id; 16700 16701 status = extract_reg_fcc_rules_tlv(param_buf, ext_chan_list_event_hdr, 16702 ext_wmi_reg_rule, ext_wmi_chan_priority, 16703 evt_buf, reg_info, len); 16704 if (status != QDF_STATUS_SUCCESS) 16705 return status; 16706 16707 return QDF_STATUS_SUCCESS; 16708 } 16709 16710 #ifdef CONFIG_AFC_SUPPORT 16711 /** 16712 * copy_afc_chan_eirp_info() - Copy the channel EIRP object from 16713 * chan_eirp_power_info_hdr to the internal buffer chan_eirp_info. Since the 16714 * cfi and eirp is continuously filled in chan_eirp_power_info_hdr, there is 16715 * an index pointer required to store the current index of 16716 * chan_eirp_power_info_hdr, to fill into the chan_eirp_info object. 16717 * @chan_eirp_info: pointer to chan_eirp_info 16718 * @num_chans: Number of channels 16719 * @chan_eirp_power_info_hdr: Pointer to chan_eirp_power_info_hdr 16720 * @index: Pointer to index 16721 * 16722 * Return: void 16723 */ 16724 static void 16725 copy_afc_chan_eirp_info(struct chan_eirp_obj *chan_eirp_info, 16726 uint8_t num_chans, 16727 wmi_afc_chan_eirp_power_info *chan_eirp_power_info_hdr, 16728 uint8_t *index) 16729 { 16730 uint8_t chan_idx; 16731 16732 for (chan_idx = 0; chan_idx < num_chans; chan_idx++, (*index)++) { 16733 chan_eirp_info[chan_idx].cfi = 16734 chan_eirp_power_info_hdr[*index].channel_cfi; 16735 chan_eirp_info[chan_idx].eirp_power = 16736 chan_eirp_power_info_hdr[*index].eirp_pwr; 16737 wmi_debug("Chan idx = %d chan freq idx = %d EIRP power = %d", 16738 chan_idx, 16739 chan_eirp_info[chan_idx].cfi, 16740 chan_eirp_info[chan_idx].eirp_power); 16741 } 16742 } 16743 16744 /** 16745 * copy_afc_chan_obj_info() - Copy the channel object from channel_info_hdr to 16746 * to the internal buffer afc_chan_info. 16747 * @afc_chan_info: pointer to afc_chan_info 16748 * @num_chan_objs: Number of channel objects 16749 * @channel_info_hdr: Pointer to channel_info_hdr 16750 * @chan_eirp_power_info_hdr: Pointer to chan_eirp_power_info_hdr 16751 * 16752 * Return: void 16753 */ 16754 static void 16755 copy_afc_chan_obj_info(struct afc_chan_obj *afc_chan_info, 16756 uint8_t num_chan_objs, 16757 wmi_6g_afc_channel_info *channel_info_hdr, 16758 wmi_afc_chan_eirp_power_info *chan_eirp_power_info_hdr) 16759 { 16760 uint8_t count; 16761 uint8_t src_pwr_index = 0; 16762 16763 for (count = 0; count < num_chan_objs; count++) { 16764 afc_chan_info[count].global_opclass = 16765 channel_info_hdr[count].global_operating_class; 16766 afc_chan_info[count].num_chans = 16767 channel_info_hdr[count].num_channels; 16768 wmi_debug("Chan object count = %d global opclasss = %d", 16769 count, 16770 afc_chan_info[count].global_opclass); 16771 wmi_debug("Number of Channel EIRP objects = %d", 16772 afc_chan_info[count].num_chans); 16773 16774 if (afc_chan_info[count].num_chans > 0) { 16775 struct chan_eirp_obj *chan_eirp_info; 16776 16777 chan_eirp_info = 16778 qdf_mem_malloc(afc_chan_info[count].num_chans * 16779 sizeof(*chan_eirp_info)); 16780 16781 if (!chan_eirp_info) 16782 return; 16783 16784 copy_afc_chan_eirp_info(chan_eirp_info, 16785 afc_chan_info[count].num_chans, 16786 chan_eirp_power_info_hdr, 16787 &src_pwr_index); 16788 afc_chan_info[count].chan_eirp_info = chan_eirp_info; 16789 } else { 16790 wmi_err("Number of channels is zero in object idx %d", 16791 count); 16792 } 16793 } 16794 } 16795 16796 static void copy_afc_freq_obj_info(struct afc_freq_obj *afc_freq_info, 16797 uint8_t num_freq_objs, 16798 wmi_6g_afc_frequency_info *freq_info_hdr) 16799 { 16800 uint8_t count; 16801 16802 for (count = 0; count < num_freq_objs; count++) { 16803 afc_freq_info[count].low_freq = 16804 WMI_REG_RULE_START_FREQ_GET(freq_info_hdr[count].freq_info); 16805 afc_freq_info[count].high_freq = 16806 WMI_REG_RULE_END_FREQ_GET(freq_info_hdr[count].freq_info); 16807 afc_freq_info[count].max_psd = 16808 freq_info_hdr[count].psd_power_info; 16809 wmi_debug("count = %d low_freq = %d high_freq = %d max_psd = %d", 16810 count, 16811 afc_freq_info[count].low_freq, 16812 afc_freq_info[count].high_freq, 16813 afc_freq_info[count].max_psd); 16814 } 16815 } 16816 16817 /** 16818 * copy_afc_event_fixed_hdr_power_info() - Copy the fixed header portion of 16819 * the power event info from the WMI AFC event buffer to the internal buffer 16820 * power_info. 16821 * @power_info: pointer to power_info 16822 * @afc_power_event_hdr: pointer to afc_power_event_hdr 16823 * 16824 * Return: void 16825 */ 16826 static void 16827 copy_afc_event_fixed_hdr_power_info( 16828 struct reg_fw_afc_power_event *power_info, 16829 wmi_afc_power_event_param *afc_power_event_hdr) 16830 { 16831 power_info->fw_status_code = afc_power_event_hdr->fw_status_code; 16832 power_info->resp_id = afc_power_event_hdr->resp_id; 16833 power_info->serv_resp_code = afc_power_event_hdr->afc_serv_resp_code; 16834 power_info->afc_wfa_version = 16835 WMI_AFC_WFA_MINOR_VERSION_GET(afc_power_event_hdr->afc_wfa_version); 16836 power_info->afc_wfa_version |= 16837 WMI_AFC_WFA_MAJOR_VERSION_GET(afc_power_event_hdr->afc_wfa_version); 16838 16839 power_info->avail_exp_time_d = 16840 WMI_AVAIL_EXPIRY_TIME_DAY_GET(afc_power_event_hdr->avail_exp_time_d); 16841 power_info->avail_exp_time_d |= 16842 WMI_AVAIL_EXPIRY_TIME_MONTH_GET(afc_power_event_hdr->avail_exp_time_d); 16843 power_info->avail_exp_time_d |= 16844 WMI_AVAIL_EXPIRY_TIME_YEAR_GET(afc_power_event_hdr->avail_exp_time_d); 16845 16846 power_info->avail_exp_time_t = 16847 WMI_AVAIL_EXPIRY_TIME_SEC_GET(afc_power_event_hdr->avail_exp_time_t); 16848 power_info->avail_exp_time_t |= 16849 WMI_AVAIL_EXPIRY_TIME_MINUTE_GET(afc_power_event_hdr->avail_exp_time_t); 16850 power_info->avail_exp_time_t |= 16851 WMI_AVAIL_EXPIRY_TIME_HOUR_GET(afc_power_event_hdr->avail_exp_time_t); 16852 wmi_debug("FW status = %d resp_id = %d serv_resp_code = %d", 16853 power_info->fw_status_code, 16854 power_info->resp_id, 16855 power_info->serv_resp_code); 16856 wmi_debug("AFC version = %u exp_date = %u exp_time = %u", 16857 power_info->afc_wfa_version, 16858 power_info->avail_exp_time_d, 16859 power_info->avail_exp_time_t); 16860 } 16861 16862 /** 16863 * copy_power_event() - Copy the power event parameters from the AFC event 16864 * buffer to the power_info within the afc_info. 16865 * @afc_info: pointer to afc_info 16866 * @param_buf: pointer to param_buf 16867 * 16868 * Return: void 16869 */ 16870 static void copy_power_event(struct afc_regulatory_info *afc_info, 16871 WMI_AFC_EVENTID_param_tlvs *param_buf) 16872 { 16873 struct reg_fw_afc_power_event *power_info; 16874 wmi_afc_power_event_param *afc_power_event_hdr; 16875 struct afc_freq_obj *afc_freq_info; 16876 16877 power_info = qdf_mem_malloc(sizeof(*power_info)); 16878 16879 if (!power_info) 16880 return; 16881 16882 afc_power_event_hdr = param_buf->afc_power_event_param; 16883 copy_afc_event_fixed_hdr_power_info(power_info, afc_power_event_hdr); 16884 afc_info->power_info = power_info; 16885 16886 power_info->num_freq_objs = param_buf->num_freq_info_array; 16887 wmi_debug("Number of frequency objects = %d", 16888 power_info->num_freq_objs); 16889 if (power_info->num_freq_objs > 0) { 16890 wmi_6g_afc_frequency_info *freq_info_hdr; 16891 16892 freq_info_hdr = param_buf->freq_info_array; 16893 afc_freq_info = qdf_mem_malloc(power_info->num_freq_objs * 16894 sizeof(*afc_freq_info)); 16895 16896 if (!afc_freq_info) 16897 return; 16898 16899 copy_afc_freq_obj_info(afc_freq_info, power_info->num_freq_objs, 16900 freq_info_hdr); 16901 power_info->afc_freq_info = afc_freq_info; 16902 } else { 16903 wmi_err("Number of frequency objects is zero"); 16904 } 16905 16906 power_info->num_chan_objs = param_buf->num_channel_info_array; 16907 wmi_debug("Number of channel objects = %d", power_info->num_chan_objs); 16908 if (power_info->num_chan_objs > 0) { 16909 struct afc_chan_obj *afc_chan_info; 16910 wmi_6g_afc_channel_info *channel_info_hdr; 16911 16912 channel_info_hdr = param_buf->channel_info_array; 16913 afc_chan_info = qdf_mem_malloc(power_info->num_chan_objs * 16914 sizeof(*afc_chan_info)); 16915 16916 if (!afc_chan_info) 16917 return; 16918 16919 copy_afc_chan_obj_info(afc_chan_info, 16920 power_info->num_chan_objs, 16921 channel_info_hdr, 16922 param_buf->chan_eirp_power_info_array); 16923 power_info->afc_chan_info = afc_chan_info; 16924 } else { 16925 wmi_err("Number of channel objects is zero"); 16926 } 16927 } 16928 16929 static void copy_expiry_event(struct afc_regulatory_info *afc_info, 16930 WMI_AFC_EVENTID_param_tlvs *param_buf) 16931 { 16932 struct reg_afc_expiry_event *expiry_info; 16933 16934 expiry_info = qdf_mem_malloc(sizeof(*expiry_info)); 16935 16936 if (!expiry_info) 16937 return; 16938 16939 expiry_info->request_id = 16940 param_buf->expiry_event_param->request_id; 16941 expiry_info->event_subtype = 16942 param_buf->expiry_event_param->event_subtype; 16943 wmi_debug("Event subtype %d request ID %d", 16944 expiry_info->event_subtype, 16945 expiry_info->request_id); 16946 afc_info->expiry_info = expiry_info; 16947 } 16948 16949 /** 16950 * copy_afc_event_common_info() - Copy the phy_id and event_type parameters 16951 * in the AFC event. 'Common' indicates that these parameters are common for 16952 * WMI_AFC_EVENT_POWER_INFO and WMI_AFC_EVENT_TIMER_EXPIRY. 16953 * @wmi_handle: wmi handle 16954 * @afc_info: pointer to afc_info 16955 * @event_fixed_hdr: pointer to event_fixed_hdr 16956 * 16957 * Return: void 16958 */ 16959 static void 16960 copy_afc_event_common_info(wmi_unified_t wmi_handle, 16961 struct afc_regulatory_info *afc_info, 16962 wmi_afc_event_fixed_param *event_fixed_hdr) 16963 { 16964 afc_info->phy_id = wmi_handle->ops->convert_phy_id_target_to_host( 16965 wmi_handle, event_fixed_hdr->phy_id); 16966 wmi_debug("phy_id %d", afc_info->phy_id); 16967 afc_info->event_type = event_fixed_hdr->event_type; 16968 } 16969 16970 static QDF_STATUS extract_afc_event_tlv(wmi_unified_t wmi_handle, 16971 uint8_t *evt_buf, 16972 struct afc_regulatory_info *afc_info, 16973 uint32_t len) 16974 { 16975 WMI_AFC_EVENTID_param_tlvs *param_buf; 16976 wmi_afc_event_fixed_param *event_fixed_hdr; 16977 16978 param_buf = (WMI_AFC_EVENTID_param_tlvs *)evt_buf; 16979 if (!param_buf) { 16980 wmi_err("Invalid AFC event buf"); 16981 return QDF_STATUS_E_FAILURE; 16982 } 16983 16984 event_fixed_hdr = param_buf->fixed_param; 16985 copy_afc_event_common_info(wmi_handle, afc_info, event_fixed_hdr); 16986 wmi_debug("AFC event type %d received", afc_info->event_type); 16987 16988 switch (afc_info->event_type) { 16989 case WMI_AFC_EVENT_POWER_INFO: 16990 copy_power_event(afc_info, param_buf); 16991 break; 16992 case WMI_AFC_EVENT_TIMER_EXPIRY: 16993 copy_expiry_event(afc_info, param_buf); 16994 return QDF_STATUS_SUCCESS; 16995 default: 16996 wmi_err("Invalid event type"); 16997 return QDF_STATUS_E_FAILURE; 16998 } 16999 17000 return QDF_STATUS_SUCCESS; 17001 } 17002 #endif 17003 #endif 17004 17005 static QDF_STATUS extract_reg_chan_list_update_event_tlv( 17006 wmi_unified_t wmi_handle, uint8_t *evt_buf, 17007 struct cur_regulatory_info *reg_info, uint32_t len) 17008 { 17009 uint32_t i; 17010 WMI_REG_CHAN_LIST_CC_EVENTID_param_tlvs *param_buf; 17011 wmi_reg_chan_list_cc_event_fixed_param *chan_list_event_hdr; 17012 wmi_regulatory_rule_struct *wmi_reg_rule; 17013 uint32_t num_2g_reg_rules, num_5g_reg_rules; 17014 17015 wmi_debug("processing regulatory channel list"); 17016 17017 param_buf = (WMI_REG_CHAN_LIST_CC_EVENTID_param_tlvs *)evt_buf; 17018 if (!param_buf) { 17019 wmi_err("invalid channel list event buf"); 17020 return QDF_STATUS_E_FAILURE; 17021 } 17022 17023 chan_list_event_hdr = param_buf->fixed_param; 17024 17025 reg_info->num_2g_reg_rules = chan_list_event_hdr->num_2g_reg_rules; 17026 reg_info->num_5g_reg_rules = chan_list_event_hdr->num_5g_reg_rules; 17027 num_2g_reg_rules = reg_info->num_2g_reg_rules; 17028 num_5g_reg_rules = reg_info->num_5g_reg_rules; 17029 if ((num_2g_reg_rules > MAX_REG_RULES) || 17030 (num_5g_reg_rules > MAX_REG_RULES) || 17031 (num_2g_reg_rules + num_5g_reg_rules > MAX_REG_RULES) || 17032 (num_2g_reg_rules + num_5g_reg_rules != 17033 param_buf->num_reg_rule_array)) { 17034 wmi_err_rl("Invalid num_2g_reg_rules: %u, num_5g_reg_rules: %u", 17035 num_2g_reg_rules, num_5g_reg_rules); 17036 return QDF_STATUS_E_FAILURE; 17037 } 17038 if (param_buf->num_reg_rule_array > 17039 (WMI_SVC_MSG_MAX_SIZE - sizeof(*chan_list_event_hdr)) / 17040 sizeof(*wmi_reg_rule)) { 17041 wmi_err_rl("Invalid num_reg_rule_array: %u", 17042 param_buf->num_reg_rule_array); 17043 return QDF_STATUS_E_FAILURE; 17044 } 17045 17046 qdf_mem_copy(reg_info->alpha2, &(chan_list_event_hdr->alpha2), 17047 REG_ALPHA2_LEN); 17048 reg_info->dfs_region = chan_list_event_hdr->dfs_region; 17049 reg_info->phybitmap = convert_phybitmap_tlv( 17050 chan_list_event_hdr->phybitmap); 17051 reg_info->offload_enabled = true; 17052 reg_info->num_phy = chan_list_event_hdr->num_phy; 17053 reg_info->phy_id = wmi_handle->ops->convert_phy_id_target_to_host( 17054 wmi_handle, chan_list_event_hdr->phy_id); 17055 reg_info->ctry_code = chan_list_event_hdr->country_id; 17056 reg_info->reg_dmn_pair = chan_list_event_hdr->domain_code; 17057 17058 reg_info->status_code = 17059 wmi_reg_status_to_reg_status(chan_list_event_hdr->status_code); 17060 17061 reg_info->min_bw_2g = chan_list_event_hdr->min_bw_2g; 17062 reg_info->max_bw_2g = chan_list_event_hdr->max_bw_2g; 17063 reg_info->min_bw_5g = chan_list_event_hdr->min_bw_5g; 17064 reg_info->max_bw_5g = chan_list_event_hdr->max_bw_5g; 17065 17066 wmi_debug("num_phys = %u and phy_id = %u", 17067 reg_info->num_phy, reg_info->phy_id); 17068 17069 wmi_debug("cc %s dfs_region %d reg_dmn_pair %x BW: min_2g %d max_2g %d min_5g %d max_5g %d", 17070 reg_info->alpha2, reg_info->dfs_region, reg_info->reg_dmn_pair, 17071 reg_info->min_bw_2g, reg_info->max_bw_2g, 17072 reg_info->min_bw_5g, reg_info->max_bw_5g); 17073 17074 wmi_debug("num_2g_reg_rules %d num_5g_reg_rules %d", 17075 num_2g_reg_rules, num_5g_reg_rules); 17076 wmi_reg_rule = 17077 (wmi_regulatory_rule_struct *)((uint8_t *)chan_list_event_hdr 17078 + sizeof(wmi_reg_chan_list_cc_event_fixed_param) 17079 + WMI_TLV_HDR_SIZE); 17080 reg_info->reg_rules_2g_ptr = create_reg_rules_from_wmi(num_2g_reg_rules, 17081 wmi_reg_rule); 17082 wmi_reg_rule += num_2g_reg_rules; 17083 if (!num_2g_reg_rules) 17084 wmi_nofl_debug("No 2ghz reg rule"); 17085 for (i = 0; i < num_2g_reg_rules; i++) { 17086 if (!reg_info->reg_rules_2g_ptr) 17087 break; 17088 wmi_nofl_debug("2 GHz rule %u start freq %u end freq %u max_bw %u reg_power %u ant_gain %u flags %u", 17089 i, reg_info->reg_rules_2g_ptr[i].start_freq, 17090 reg_info->reg_rules_2g_ptr[i].end_freq, 17091 reg_info->reg_rules_2g_ptr[i].max_bw, 17092 reg_info->reg_rules_2g_ptr[i].reg_power, 17093 reg_info->reg_rules_2g_ptr[i].ant_gain, 17094 reg_info->reg_rules_2g_ptr[i].flags); 17095 } 17096 17097 reg_info->reg_rules_5g_ptr = create_reg_rules_from_wmi(num_5g_reg_rules, 17098 wmi_reg_rule); 17099 if (!num_5g_reg_rules) 17100 wmi_nofl_debug("No 5ghz reg rule"); 17101 for (i = 0; i < num_5g_reg_rules; i++) { 17102 if (!reg_info->reg_rules_5g_ptr) 17103 break; 17104 wmi_nofl_debug("5 GHz rule %u start freq %u end freq %u max_bw %u reg_power %u ant_gain %u flags %u", 17105 i, reg_info->reg_rules_5g_ptr[i].start_freq, 17106 reg_info->reg_rules_5g_ptr[i].end_freq, 17107 reg_info->reg_rules_5g_ptr[i].max_bw, 17108 reg_info->reg_rules_5g_ptr[i].reg_power, 17109 reg_info->reg_rules_5g_ptr[i].ant_gain, 17110 reg_info->reg_rules_5g_ptr[i].flags); 17111 } 17112 17113 wmi_debug("processed regulatory channel list"); 17114 17115 return QDF_STATUS_SUCCESS; 17116 } 17117 17118 static QDF_STATUS extract_reg_11d_new_country_event_tlv( 17119 wmi_unified_t wmi_handle, uint8_t *evt_buf, 17120 struct reg_11d_new_country *reg_11d_country, uint32_t len) 17121 { 17122 wmi_11d_new_country_event_fixed_param *reg_11d_country_event; 17123 WMI_11D_NEW_COUNTRY_EVENTID_param_tlvs *param_buf; 17124 17125 param_buf = (WMI_11D_NEW_COUNTRY_EVENTID_param_tlvs *)evt_buf; 17126 if (!param_buf) { 17127 wmi_err("invalid 11d country event buf"); 17128 return QDF_STATUS_E_FAILURE; 17129 } 17130 17131 reg_11d_country_event = param_buf->fixed_param; 17132 17133 qdf_mem_copy(reg_11d_country->alpha2, 17134 ®_11d_country_event->new_alpha2, REG_ALPHA2_LEN); 17135 reg_11d_country->alpha2[REG_ALPHA2_LEN] = '\0'; 17136 17137 wmi_debug("processed 11d country event, new cc %s", 17138 reg_11d_country->alpha2); 17139 17140 return QDF_STATUS_SUCCESS; 17141 } 17142 17143 static QDF_STATUS extract_reg_ch_avoid_event_tlv( 17144 wmi_unified_t wmi_handle, uint8_t *evt_buf, 17145 struct ch_avoid_ind_type *ch_avoid_ind, uint32_t len) 17146 { 17147 wmi_avoid_freq_ranges_event_fixed_param *afr_fixed_param; 17148 wmi_avoid_freq_range_desc *afr_desc; 17149 uint32_t num_freq_ranges, freq_range_idx; 17150 WMI_WLAN_FREQ_AVOID_EVENTID_param_tlvs *param_buf = 17151 (WMI_WLAN_FREQ_AVOID_EVENTID_param_tlvs *) evt_buf; 17152 17153 if (!param_buf) { 17154 wmi_err("Invalid channel avoid event buffer"); 17155 return QDF_STATUS_E_INVAL; 17156 } 17157 17158 afr_fixed_param = param_buf->fixed_param; 17159 if (!afr_fixed_param) { 17160 wmi_err("Invalid channel avoid event fixed param buffer"); 17161 return QDF_STATUS_E_INVAL; 17162 } 17163 17164 if (!ch_avoid_ind) { 17165 wmi_err("Invalid channel avoid indication buffer"); 17166 return QDF_STATUS_E_INVAL; 17167 } 17168 if (param_buf->num_avd_freq_range < afr_fixed_param->num_freq_ranges) { 17169 wmi_err("no.of freq ranges exceeded the limit"); 17170 return QDF_STATUS_E_INVAL; 17171 } 17172 num_freq_ranges = (afr_fixed_param->num_freq_ranges > 17173 CH_AVOID_MAX_RANGE) ? CH_AVOID_MAX_RANGE : 17174 afr_fixed_param->num_freq_ranges; 17175 17176 wmi_debug("Channel avoid event received with %d ranges", 17177 num_freq_ranges); 17178 17179 ch_avoid_ind->ch_avoid_range_cnt = num_freq_ranges; 17180 afr_desc = (wmi_avoid_freq_range_desc *)(param_buf->avd_freq_range); 17181 for (freq_range_idx = 0; freq_range_idx < num_freq_ranges; 17182 freq_range_idx++) { 17183 ch_avoid_ind->avoid_freq_range[freq_range_idx].start_freq = 17184 afr_desc->start_freq; 17185 ch_avoid_ind->avoid_freq_range[freq_range_idx].end_freq = 17186 afr_desc->end_freq; 17187 wmi_debug("range %d tlv id %u, start freq %u, end freq %u", 17188 freq_range_idx, afr_desc->tlv_header, 17189 afr_desc->start_freq, afr_desc->end_freq); 17190 afr_desc++; 17191 } 17192 17193 return QDF_STATUS_SUCCESS; 17194 } 17195 17196 #ifdef DFS_COMPONENT_ENABLE 17197 /** 17198 * extract_dfs_cac_complete_event_tlv() - extract cac complete event 17199 * @wmi_handle: wma handle 17200 * @evt_buf: event buffer 17201 * @vdev_id: vdev id 17202 * @len: length of buffer 17203 * 17204 * Return: QDF_STATUS_SUCCESS for success or error code 17205 */ 17206 static QDF_STATUS extract_dfs_cac_complete_event_tlv(wmi_unified_t wmi_handle, 17207 uint8_t *evt_buf, 17208 uint32_t *vdev_id, 17209 uint32_t len) 17210 { 17211 WMI_VDEV_DFS_CAC_COMPLETE_EVENTID_param_tlvs *param_tlvs; 17212 wmi_vdev_dfs_cac_complete_event_fixed_param *cac_event; 17213 17214 param_tlvs = (WMI_VDEV_DFS_CAC_COMPLETE_EVENTID_param_tlvs *) evt_buf; 17215 if (!param_tlvs) { 17216 wmi_err("invalid cac complete event buf"); 17217 return QDF_STATUS_E_FAILURE; 17218 } 17219 17220 cac_event = param_tlvs->fixed_param; 17221 *vdev_id = cac_event->vdev_id; 17222 wmi_debug("processed cac complete event vdev %d", *vdev_id); 17223 17224 return QDF_STATUS_SUCCESS; 17225 } 17226 17227 /** 17228 * extract_dfs_ocac_complete_event_tlv() - extract cac complete event 17229 * @wmi_handle: wma handle 17230 * @evt_buf: event buffer 17231 * @param: extracted event 17232 * 17233 * Return: QDF_STATUS_SUCCESS for success or error code 17234 */ 17235 static QDF_STATUS 17236 extract_dfs_ocac_complete_event_tlv(wmi_unified_t wmi_handle, 17237 uint8_t *evt_buf, 17238 struct vdev_adfs_complete_status *param) 17239 { 17240 WMI_VDEV_ADFS_OCAC_COMPLETE_EVENTID_param_tlvs *param_tlvs; 17241 wmi_vdev_adfs_ocac_complete_event_fixed_param *ocac_complete_status; 17242 17243 param_tlvs = (WMI_VDEV_ADFS_OCAC_COMPLETE_EVENTID_param_tlvs *)evt_buf; 17244 if (!param_tlvs) { 17245 wmi_err("invalid ocac complete event buf"); 17246 return QDF_STATUS_E_FAILURE; 17247 } 17248 17249 if (!param_tlvs->fixed_param) { 17250 wmi_err("invalid param_tlvs->fixed_param"); 17251 return QDF_STATUS_E_FAILURE; 17252 } 17253 17254 ocac_complete_status = param_tlvs->fixed_param; 17255 param->vdev_id = ocac_complete_status->vdev_id; 17256 param->chan_freq = ocac_complete_status->chan_freq; 17257 param->center_freq1 = ocac_complete_status->center_freq1; 17258 param->center_freq2 = ocac_complete_status->center_freq2; 17259 param->ocac_status = ocac_complete_status->status; 17260 param->chan_width = ocac_complete_status->chan_width; 17261 wmi_debug("processed ocac complete event vdev %d" 17262 " agile chan %d %d width %d status %d", 17263 param->vdev_id, 17264 param->center_freq1, 17265 param->center_freq2, 17266 param->chan_width, 17267 param->ocac_status); 17268 17269 return QDF_STATUS_SUCCESS; 17270 } 17271 17272 /** 17273 * extract_dfs_radar_detection_event_tlv() - extract radar found event 17274 * @wmi_handle: wma handle 17275 * @evt_buf: event buffer 17276 * @radar_found: radar found event info 17277 * @len: length of buffer 17278 * 17279 * Return: QDF_STATUS_SUCCESS for success or error code 17280 */ 17281 static QDF_STATUS extract_dfs_radar_detection_event_tlv( 17282 wmi_unified_t wmi_handle, 17283 uint8_t *evt_buf, 17284 struct radar_found_info *radar_found, 17285 uint32_t len) 17286 { 17287 WMI_PDEV_DFS_RADAR_DETECTION_EVENTID_param_tlvs *param_tlv; 17288 wmi_pdev_dfs_radar_detection_event_fixed_param *radar_event; 17289 17290 param_tlv = (WMI_PDEV_DFS_RADAR_DETECTION_EVENTID_param_tlvs *) evt_buf; 17291 if (!param_tlv) { 17292 wmi_err("invalid radar detection event buf"); 17293 return QDF_STATUS_E_FAILURE; 17294 } 17295 17296 radar_event = param_tlv->fixed_param; 17297 17298 radar_found->pdev_id = convert_target_pdev_id_to_host_pdev_id( 17299 wmi_handle, 17300 radar_event->pdev_id); 17301 17302 if (radar_found->pdev_id == WMI_HOST_PDEV_ID_INVALID) 17303 return QDF_STATUS_E_FAILURE; 17304 17305 qdf_mem_zero(radar_found, sizeof(struct radar_found_info)); 17306 radar_found->detection_mode = radar_event->detection_mode; 17307 radar_found->chan_freq = radar_event->chan_freq; 17308 radar_found->chan_width = radar_event->chan_width; 17309 radar_found->detector_id = radar_event->detector_id; 17310 radar_found->segment_id = radar_event->segment_id; 17311 radar_found->timestamp = radar_event->timestamp; 17312 radar_found->is_chirp = radar_event->is_chirp; 17313 radar_found->freq_offset = radar_event->freq_offset; 17314 radar_found->sidx = radar_event->sidx; 17315 17316 if (is_service_enabled_tlv(wmi_handle, 17317 WMI_SERVICE_RADAR_FLAGS_SUPPORT)) { 17318 WMI_RADAR_FLAGS *radar_flags; 17319 17320 radar_flags = param_tlv->radar_flags; 17321 if (radar_flags) { 17322 radar_found->is_full_bw_nol = 17323 WMI_RADAR_FLAGS_FULL_BW_NOL_GET(radar_flags->flags); 17324 wmi_debug("Is full bw nol %d", 17325 radar_found->is_full_bw_nol); 17326 } 17327 } 17328 17329 wmi_debug("processed radar found event pdev %d," 17330 "Radar Event Info:pdev_id %d,timestamp %d,chan_freq (dur) %d," 17331 "chan_width (RSSI) %d,detector_id (false_radar) %d," 17332 "freq_offset (radar_check) %d,segment_id %d,sidx %d," 17333 "is_chirp %d,detection mode %d", 17334 radar_event->pdev_id, radar_found->pdev_id, 17335 radar_event->timestamp, radar_event->chan_freq, 17336 radar_event->chan_width, radar_event->detector_id, 17337 radar_event->freq_offset, radar_event->segment_id, 17338 radar_event->sidx, radar_event->is_chirp, 17339 radar_event->detection_mode); 17340 17341 return QDF_STATUS_SUCCESS; 17342 } 17343 17344 #ifdef MOBILE_DFS_SUPPORT 17345 /** 17346 * extract_wlan_radar_event_info_tlv() - extract radar pulse event 17347 * @wmi_handle: wma handle 17348 * @evt_buf: event buffer 17349 * @wlan_radar_event: Pointer to struct radar_event_info 17350 * @len: length of buffer 17351 * 17352 * Return: QDF_STATUS 17353 */ 17354 static QDF_STATUS extract_wlan_radar_event_info_tlv( 17355 wmi_unified_t wmi_handle, 17356 uint8_t *evt_buf, 17357 struct radar_event_info *wlan_radar_event, 17358 uint32_t len) 17359 { 17360 WMI_DFS_RADAR_EVENTID_param_tlvs *param_tlv; 17361 wmi_dfs_radar_event_fixed_param *radar_event; 17362 17363 param_tlv = (WMI_DFS_RADAR_EVENTID_param_tlvs *)evt_buf; 17364 if (!param_tlv) { 17365 wmi_err("invalid wlan radar event buf"); 17366 return QDF_STATUS_E_FAILURE; 17367 } 17368 17369 radar_event = param_tlv->fixed_param; 17370 wlan_radar_event->pulse_is_chirp = radar_event->pulse_is_chirp; 17371 wlan_radar_event->pulse_center_freq = radar_event->pulse_center_freq; 17372 wlan_radar_event->pulse_duration = radar_event->pulse_duration; 17373 wlan_radar_event->rssi = radar_event->rssi; 17374 wlan_radar_event->pulse_detect_ts = radar_event->pulse_detect_ts; 17375 wlan_radar_event->upload_fullts_high = radar_event->upload_fullts_high; 17376 wlan_radar_event->upload_fullts_low = radar_event->upload_fullts_low; 17377 wlan_radar_event->peak_sidx = radar_event->peak_sidx; 17378 wlan_radar_event->delta_peak = radar_event->pulse_delta_peak; 17379 wlan_radar_event->delta_diff = radar_event->pulse_delta_diff; 17380 if (radar_event->pulse_flags & 17381 WMI_DFS_RADAR_PULSE_FLAG_MASK_PSIDX_DIFF_VALID) { 17382 wlan_radar_event->is_psidx_diff_valid = true; 17383 wlan_radar_event->psidx_diff = radar_event->psidx_diff; 17384 } else { 17385 wlan_radar_event->is_psidx_diff_valid = false; 17386 } 17387 17388 wlan_radar_event->pdev_id = radar_event->pdev_id; 17389 17390 return QDF_STATUS_SUCCESS; 17391 } 17392 #else 17393 static QDF_STATUS extract_wlan_radar_event_info_tlv( 17394 wmi_unified_t wmi_handle, 17395 uint8_t *evt_buf, 17396 struct radar_event_info *wlan_radar_event, 17397 uint32_t len) 17398 { 17399 return QDF_STATUS_SUCCESS; 17400 } 17401 #endif 17402 #endif 17403 17404 /** 17405 * send_get_rcpi_cmd_tlv() - send request for rcpi value 17406 * @wmi_handle: wmi handle 17407 * @get_rcpi_param: rcpi params 17408 * 17409 * Return: QDF status 17410 */ 17411 static QDF_STATUS send_get_rcpi_cmd_tlv(wmi_unified_t wmi_handle, 17412 struct rcpi_req *get_rcpi_param) 17413 { 17414 wmi_buf_t buf; 17415 wmi_request_rcpi_cmd_fixed_param *cmd; 17416 uint8_t len = sizeof(wmi_request_rcpi_cmd_fixed_param); 17417 17418 buf = wmi_buf_alloc(wmi_handle, len); 17419 if (!buf) 17420 return QDF_STATUS_E_NOMEM; 17421 17422 cmd = (wmi_request_rcpi_cmd_fixed_param *) wmi_buf_data(buf); 17423 WMITLV_SET_HDR(&cmd->tlv_header, 17424 WMITLV_TAG_STRUC_wmi_request_rcpi_cmd_fixed_param, 17425 WMITLV_GET_STRUCT_TLVLEN 17426 (wmi_request_rcpi_cmd_fixed_param)); 17427 17428 cmd->vdev_id = get_rcpi_param->vdev_id; 17429 WMI_CHAR_ARRAY_TO_MAC_ADDR(get_rcpi_param->mac_addr, 17430 &cmd->peer_macaddr); 17431 17432 switch (get_rcpi_param->measurement_type) { 17433 17434 case RCPI_MEASUREMENT_TYPE_AVG_MGMT: 17435 cmd->measurement_type = WMI_RCPI_MEASUREMENT_TYPE_AVG_MGMT; 17436 break; 17437 17438 case RCPI_MEASUREMENT_TYPE_AVG_DATA: 17439 cmd->measurement_type = WMI_RCPI_MEASUREMENT_TYPE_AVG_DATA; 17440 break; 17441 17442 case RCPI_MEASUREMENT_TYPE_LAST_MGMT: 17443 cmd->measurement_type = WMI_RCPI_MEASUREMENT_TYPE_LAST_MGMT; 17444 break; 17445 17446 case RCPI_MEASUREMENT_TYPE_LAST_DATA: 17447 cmd->measurement_type = WMI_RCPI_MEASUREMENT_TYPE_LAST_DATA; 17448 break; 17449 17450 default: 17451 /* 17452 * invalid rcpi measurement type, fall back to 17453 * RCPI_MEASUREMENT_TYPE_AVG_MGMT 17454 */ 17455 cmd->measurement_type = WMI_RCPI_MEASUREMENT_TYPE_AVG_MGMT; 17456 break; 17457 } 17458 wmi_debug("RCPI REQ VDEV_ID:%d-->", cmd->vdev_id); 17459 wmi_mtrace(WMI_REQUEST_RCPI_CMDID, cmd->vdev_id, 0); 17460 if (wmi_unified_cmd_send(wmi_handle, buf, len, 17461 WMI_REQUEST_RCPI_CMDID)) { 17462 17463 wmi_err("Failed to send WMI_REQUEST_RCPI_CMDID"); 17464 wmi_buf_free(buf); 17465 return QDF_STATUS_E_FAILURE; 17466 } 17467 17468 return QDF_STATUS_SUCCESS; 17469 } 17470 17471 /** 17472 * extract_rcpi_response_event_tlv() - Extract RCPI event params 17473 * @wmi_handle: wmi handle 17474 * @evt_buf: pointer to event buffer 17475 * @res: pointer to hold rcpi response from firmware 17476 * 17477 * Return: QDF_STATUS_SUCCESS for successful event parse 17478 * else QDF_STATUS_E_INVAL or QDF_STATUS_E_FAILURE 17479 */ 17480 static QDF_STATUS 17481 extract_rcpi_response_event_tlv(wmi_unified_t wmi_handle, 17482 void *evt_buf, struct rcpi_res *res) 17483 { 17484 WMI_UPDATE_RCPI_EVENTID_param_tlvs *param_buf; 17485 wmi_update_rcpi_event_fixed_param *event; 17486 17487 param_buf = (WMI_UPDATE_RCPI_EVENTID_param_tlvs *)evt_buf; 17488 if (!param_buf) { 17489 wmi_err("Invalid rcpi event"); 17490 return QDF_STATUS_E_INVAL; 17491 } 17492 17493 event = param_buf->fixed_param; 17494 res->vdev_id = event->vdev_id; 17495 WMI_MAC_ADDR_TO_CHAR_ARRAY(&event->peer_macaddr, res->mac_addr); 17496 17497 switch (event->measurement_type) { 17498 17499 case WMI_RCPI_MEASUREMENT_TYPE_AVG_MGMT: 17500 res->measurement_type = RCPI_MEASUREMENT_TYPE_AVG_MGMT; 17501 break; 17502 17503 case WMI_RCPI_MEASUREMENT_TYPE_AVG_DATA: 17504 res->measurement_type = RCPI_MEASUREMENT_TYPE_AVG_DATA; 17505 break; 17506 17507 case WMI_RCPI_MEASUREMENT_TYPE_LAST_MGMT: 17508 res->measurement_type = RCPI_MEASUREMENT_TYPE_LAST_MGMT; 17509 break; 17510 17511 case WMI_RCPI_MEASUREMENT_TYPE_LAST_DATA: 17512 res->measurement_type = RCPI_MEASUREMENT_TYPE_LAST_DATA; 17513 break; 17514 17515 default: 17516 wmi_err("Invalid rcpi measurement type from firmware"); 17517 res->measurement_type = RCPI_MEASUREMENT_TYPE_INVALID; 17518 return QDF_STATUS_E_FAILURE; 17519 } 17520 17521 if (event->status) 17522 return QDF_STATUS_E_FAILURE; 17523 else 17524 return QDF_STATUS_SUCCESS; 17525 } 17526 17527 /** 17528 * convert_host_pdev_id_to_target_pdev_id_legacy() - Convert pdev_id from 17529 * host to target defines. For legacy there is not conversion 17530 * required. Just return pdev_id as it is. 17531 * @wmi_handle: handle to WMI. 17532 * @pdev_id: host pdev_id to be converted. 17533 * Return: target pdev_id after conversion. 17534 */ 17535 static uint32_t convert_host_pdev_id_to_target_pdev_id_legacy( 17536 wmi_unified_t wmi_handle, 17537 uint32_t pdev_id) 17538 { 17539 if (pdev_id == WMI_HOST_PDEV_ID_SOC) 17540 return WMI_PDEV_ID_SOC; 17541 17542 /*No conversion required*/ 17543 return pdev_id; 17544 } 17545 17546 /** 17547 * convert_target_pdev_id_to_host_pdev_id_legacy() - Convert pdev_id from 17548 * target to host defines. For legacy there is not conversion 17549 * required. Just return pdev_id as it is. 17550 * @wmi_handle: handle to WMI. 17551 * @pdev_id: target pdev_id to be converted. 17552 * Return: host pdev_id after conversion. 17553 */ 17554 static uint32_t convert_target_pdev_id_to_host_pdev_id_legacy( 17555 wmi_unified_t wmi_handle, 17556 uint32_t pdev_id) 17557 { 17558 /*No conversion required*/ 17559 return pdev_id; 17560 } 17561 17562 /** 17563 * convert_host_phy_id_to_target_phy_id_legacy() - Convert phy_id from 17564 * host to target defines. For legacy there is not conversion 17565 * required. Just return phy_id as it is. 17566 * @wmi_handle: handle to WMI. 17567 * @phy_id: host phy_id to be converted. 17568 * 17569 * Return: target phy_id after conversion. 17570 */ 17571 static uint32_t convert_host_phy_id_to_target_phy_id_legacy( 17572 wmi_unified_t wmi_handle, 17573 uint32_t phy_id) 17574 { 17575 /*No conversion required*/ 17576 return phy_id; 17577 } 17578 17579 /** 17580 * convert_target_phy_id_to_host_phy_id_legacy() - Convert phy_id from 17581 * target to host defines. For legacy there is not conversion 17582 * required. Just return phy_id as it is. 17583 * @wmi_handle: handle to WMI. 17584 * @phy_id: target phy_id to be converted. 17585 * 17586 * Return: host phy_id after conversion. 17587 */ 17588 static uint32_t convert_target_phy_id_to_host_phy_id_legacy( 17589 wmi_unified_t wmi_handle, 17590 uint32_t phy_id) 17591 { 17592 /*No conversion required*/ 17593 return phy_id; 17594 } 17595 17596 /** 17597 * send_set_country_cmd_tlv() - WMI scan channel list function 17598 * @wmi_handle: handle to WMI. 17599 * @params: pointer to hold scan channel list parameter 17600 * 17601 * Return: QDF_STATUS_SUCCESS for success or error code 17602 */ 17603 static QDF_STATUS send_set_country_cmd_tlv(wmi_unified_t wmi_handle, 17604 struct set_country *params) 17605 { 17606 wmi_buf_t buf; 17607 QDF_STATUS qdf_status; 17608 wmi_set_current_country_cmd_fixed_param *cmd; 17609 uint16_t len = sizeof(*cmd); 17610 uint8_t pdev_id = params->pdev_id; 17611 17612 buf = wmi_buf_alloc(wmi_handle, len); 17613 if (!buf) { 17614 qdf_status = QDF_STATUS_E_NOMEM; 17615 goto end; 17616 } 17617 17618 cmd = (wmi_set_current_country_cmd_fixed_param *)wmi_buf_data(buf); 17619 WMITLV_SET_HDR(&cmd->tlv_header, 17620 WMITLV_TAG_STRUC_wmi_set_current_country_cmd_fixed_param, 17621 WMITLV_GET_STRUCT_TLVLEN 17622 (wmi_set_current_country_cmd_fixed_param)); 17623 17624 cmd->pdev_id = wmi_handle->ops->convert_host_pdev_id_to_target( 17625 wmi_handle, 17626 pdev_id); 17627 wmi_debug("setting current country to %s and target pdev_id = %u", 17628 params->country, cmd->pdev_id); 17629 17630 qdf_mem_copy((uint8_t *)&cmd->new_alpha2, params->country, 3); 17631 17632 wmi_mtrace(WMI_SET_CURRENT_COUNTRY_CMDID, NO_SESSION, 0); 17633 qdf_status = wmi_unified_cmd_send(wmi_handle, 17634 buf, len, WMI_SET_CURRENT_COUNTRY_CMDID); 17635 17636 if (QDF_IS_STATUS_ERROR(qdf_status)) { 17637 wmi_err("Failed to send WMI_SET_CURRENT_COUNTRY_CMDID"); 17638 wmi_buf_free(buf); 17639 } 17640 17641 end: 17642 return qdf_status; 17643 } 17644 17645 #define WMI_REG_COUNTRY_ALPHA_SET(alpha, val0, val1, val2) do { \ 17646 WMI_SET_BITS(alpha, 0, 8, val0); \ 17647 WMI_SET_BITS(alpha, 8, 8, val1); \ 17648 WMI_SET_BITS(alpha, 16, 8, val2); \ 17649 } while (0) 17650 17651 static QDF_STATUS send_user_country_code_cmd_tlv(wmi_unified_t wmi_handle, 17652 uint8_t pdev_id, struct cc_regdmn_s *rd) 17653 { 17654 wmi_set_init_country_cmd_fixed_param *cmd; 17655 uint16_t len; 17656 wmi_buf_t buf; 17657 int ret; 17658 17659 len = sizeof(wmi_set_init_country_cmd_fixed_param); 17660 buf = wmi_buf_alloc(wmi_handle, len); 17661 if (!buf) 17662 return QDF_STATUS_E_NOMEM; 17663 17664 cmd = (wmi_set_init_country_cmd_fixed_param *) wmi_buf_data(buf); 17665 WMITLV_SET_HDR(&cmd->tlv_header, 17666 WMITLV_TAG_STRUC_wmi_set_init_country_cmd_fixed_param, 17667 WMITLV_GET_STRUCT_TLVLEN 17668 (wmi_set_init_country_cmd_fixed_param)); 17669 17670 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 17671 wmi_handle, 17672 pdev_id); 17673 17674 if (rd->flags == CC_IS_SET) { 17675 cmd->countrycode_type = WMI_COUNTRYCODE_COUNTRY_ID; 17676 cmd->country_code.country_id = rd->cc.country_code; 17677 } else if (rd->flags == ALPHA_IS_SET) { 17678 cmd->countrycode_type = WMI_COUNTRYCODE_ALPHA2; 17679 WMI_REG_COUNTRY_ALPHA_SET(cmd->country_code.alpha2, 17680 rd->cc.alpha[0], 17681 rd->cc.alpha[1], 17682 rd->cc.alpha[2]); 17683 } else if (rd->flags == REGDMN_IS_SET) { 17684 cmd->countrycode_type = WMI_COUNTRYCODE_DOMAIN_CODE; 17685 WMI_SET_BITS(cmd->country_code.domain_code, 0, 16, 17686 rd->cc.regdmn.reg_2g_5g_pair_id); 17687 WMI_SET_BITS(cmd->country_code.domain_code, 16, 16, 17688 rd->cc.regdmn.sixg_superdmn_id); 17689 } 17690 17691 wmi_mtrace(WMI_SET_INIT_COUNTRY_CMDID, NO_SESSION, 0); 17692 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 17693 WMI_SET_INIT_COUNTRY_CMDID); 17694 if (ret) { 17695 wmi_err("Failed to config wow wakeup event"); 17696 wmi_buf_free(buf); 17697 return QDF_STATUS_E_FAILURE; 17698 } 17699 17700 return QDF_STATUS_SUCCESS; 17701 } 17702 17703 /** 17704 * send_obss_detection_cfg_cmd_tlv() - send obss detection 17705 * configurations to firmware. 17706 * @wmi_handle: wmi handle 17707 * @obss_cfg_param: obss detection configurations 17708 * 17709 * Send WMI_SAP_OBSS_DETECTION_CFG_CMDID parameters to fw. 17710 * 17711 * Return: QDF_STATUS 17712 */ 17713 static QDF_STATUS send_obss_detection_cfg_cmd_tlv(wmi_unified_t wmi_handle, 17714 struct wmi_obss_detection_cfg_param *obss_cfg_param) 17715 { 17716 wmi_buf_t buf; 17717 wmi_sap_obss_detection_cfg_cmd_fixed_param *cmd; 17718 uint8_t len = sizeof(wmi_sap_obss_detection_cfg_cmd_fixed_param); 17719 17720 buf = wmi_buf_alloc(wmi_handle, len); 17721 if (!buf) 17722 return QDF_STATUS_E_NOMEM; 17723 17724 cmd = (wmi_sap_obss_detection_cfg_cmd_fixed_param *)wmi_buf_data(buf); 17725 WMITLV_SET_HDR(&cmd->tlv_header, 17726 WMITLV_TAG_STRUC_wmi_sap_obss_detection_cfg_cmd_fixed_param, 17727 WMITLV_GET_STRUCT_TLVLEN 17728 (wmi_sap_obss_detection_cfg_cmd_fixed_param)); 17729 17730 cmd->vdev_id = obss_cfg_param->vdev_id; 17731 cmd->detect_period_ms = obss_cfg_param->obss_detect_period_ms; 17732 cmd->b_ap_detect_mode = obss_cfg_param->obss_11b_ap_detect_mode; 17733 cmd->b_sta_detect_mode = obss_cfg_param->obss_11b_sta_detect_mode; 17734 cmd->g_ap_detect_mode = obss_cfg_param->obss_11g_ap_detect_mode; 17735 cmd->a_detect_mode = obss_cfg_param->obss_11a_detect_mode; 17736 cmd->ht_legacy_detect_mode = obss_cfg_param->obss_ht_legacy_detect_mode; 17737 cmd->ht_mixed_detect_mode = obss_cfg_param->obss_ht_mixed_detect_mode; 17738 cmd->ht_20mhz_detect_mode = obss_cfg_param->obss_ht_20mhz_detect_mode; 17739 17740 wmi_mtrace(WMI_SAP_OBSS_DETECTION_CFG_CMDID, cmd->vdev_id, 0); 17741 if (wmi_unified_cmd_send(wmi_handle, buf, len, 17742 WMI_SAP_OBSS_DETECTION_CFG_CMDID)) { 17743 wmi_err("Failed to send WMI_SAP_OBSS_DETECTION_CFG_CMDID"); 17744 wmi_buf_free(buf); 17745 return QDF_STATUS_E_FAILURE; 17746 } 17747 17748 return QDF_STATUS_SUCCESS; 17749 } 17750 17751 /** 17752 * extract_obss_detection_info_tlv() - Extract obss detection info 17753 * received from firmware. 17754 * @evt_buf: pointer to event buffer 17755 * @obss_detection: Pointer to hold obss detection info 17756 * 17757 * Return: QDF_STATUS 17758 */ 17759 static QDF_STATUS extract_obss_detection_info_tlv(uint8_t *evt_buf, 17760 struct wmi_obss_detect_info 17761 *obss_detection) 17762 { 17763 WMI_SAP_OBSS_DETECTION_REPORT_EVENTID_param_tlvs *param_buf; 17764 wmi_sap_obss_detection_info_evt_fixed_param *fix_param; 17765 17766 if (!obss_detection) { 17767 wmi_err("Invalid obss_detection event buffer"); 17768 return QDF_STATUS_E_INVAL; 17769 } 17770 17771 param_buf = (WMI_SAP_OBSS_DETECTION_REPORT_EVENTID_param_tlvs *)evt_buf; 17772 if (!param_buf) { 17773 wmi_err("Invalid evt_buf"); 17774 return QDF_STATUS_E_INVAL; 17775 } 17776 17777 fix_param = param_buf->fixed_param; 17778 obss_detection->vdev_id = fix_param->vdev_id; 17779 obss_detection->matched_detection_masks = 17780 fix_param->matched_detection_masks; 17781 WMI_MAC_ADDR_TO_CHAR_ARRAY(&fix_param->matched_bssid_addr, 17782 &obss_detection->matched_bssid_addr[0]); 17783 switch (fix_param->reason) { 17784 case WMI_SAP_OBSS_DETECTION_EVENT_REASON_NOT_SUPPORT: 17785 obss_detection->reason = OBSS_OFFLOAD_DETECTION_DISABLED; 17786 break; 17787 case WMI_SAP_OBSS_DETECTION_EVENT_REASON_PRESENT_NOTIFY: 17788 obss_detection->reason = OBSS_OFFLOAD_DETECTION_PRESENT; 17789 break; 17790 case WMI_SAP_OBSS_DETECTION_EVENT_REASON_ABSENT_TIMEOUT: 17791 obss_detection->reason = OBSS_OFFLOAD_DETECTION_ABSENT; 17792 break; 17793 default: 17794 wmi_err("Invalid reason: %d", fix_param->reason); 17795 return QDF_STATUS_E_INVAL; 17796 } 17797 17798 return QDF_STATUS_SUCCESS; 17799 } 17800 17801 /** 17802 * send_roam_scan_stats_cmd_tlv() - Send roam scan stats req command to fw 17803 * @wmi_handle: wmi handle 17804 * @params: pointer to request structure 17805 * 17806 * Return: QDF_STATUS 17807 */ 17808 static QDF_STATUS 17809 send_roam_scan_stats_cmd_tlv(wmi_unified_t wmi_handle, 17810 struct wmi_roam_scan_stats_req *params) 17811 { 17812 wmi_buf_t buf; 17813 wmi_request_roam_scan_stats_cmd_fixed_param *cmd; 17814 WMITLV_TAG_ID tag; 17815 uint32_t size; 17816 uint32_t len = sizeof(*cmd); 17817 17818 buf = wmi_buf_alloc(wmi_handle, len); 17819 if (!buf) 17820 return QDF_STATUS_E_FAILURE; 17821 17822 cmd = (wmi_request_roam_scan_stats_cmd_fixed_param *)wmi_buf_data(buf); 17823 17824 tag = WMITLV_TAG_STRUC_wmi_request_roam_scan_stats_cmd_fixed_param; 17825 size = WMITLV_GET_STRUCT_TLVLEN( 17826 wmi_request_roam_scan_stats_cmd_fixed_param); 17827 WMITLV_SET_HDR(&cmd->tlv_header, tag, size); 17828 17829 cmd->vdev_id = params->vdev_id; 17830 17831 wmi_debug("Roam Scan Stats Req vdev_id: %u", cmd->vdev_id); 17832 if (wmi_unified_cmd_send(wmi_handle, buf, len, 17833 WMI_REQUEST_ROAM_SCAN_STATS_CMDID)) { 17834 wmi_err("Failed to send WMI_REQUEST_ROAM_SCAN_STATS_CMDID"); 17835 wmi_buf_free(buf); 17836 return QDF_STATUS_E_FAILURE; 17837 } 17838 17839 return QDF_STATUS_SUCCESS; 17840 } 17841 17842 /** 17843 * send_roam_scan_ch_list_req_cmd_tlv() - send wmi cmd to get roam scan 17844 * channel list from firmware 17845 * @wmi_handle: wmi handler 17846 * @vdev_id: vdev id 17847 * 17848 * Return: QDF_STATUS 17849 */ 17850 static QDF_STATUS send_roam_scan_ch_list_req_cmd_tlv(wmi_unified_t wmi_handle, 17851 uint32_t vdev_id) 17852 { 17853 wmi_buf_t buf; 17854 wmi_roam_get_scan_channel_list_cmd_fixed_param *cmd; 17855 uint16_t len = sizeof(*cmd); 17856 int ret; 17857 17858 buf = wmi_buf_alloc(wmi_handle, len); 17859 if (!buf) { 17860 wmi_err("Failed to allocate wmi buffer"); 17861 return QDF_STATUS_E_NOMEM; 17862 } 17863 17864 cmd = (wmi_roam_get_scan_channel_list_cmd_fixed_param *) 17865 wmi_buf_data(buf); 17866 WMITLV_SET_HDR(&cmd->tlv_header, 17867 WMITLV_TAG_STRUC_wmi_roam_get_scan_channel_list_cmd_fixed_param, 17868 WMITLV_GET_STRUCT_TLVLEN( 17869 wmi_roam_get_scan_channel_list_cmd_fixed_param)); 17870 cmd->vdev_id = vdev_id; 17871 wmi_mtrace(WMI_ROAM_GET_SCAN_CHANNEL_LIST_CMDID, vdev_id, 0); 17872 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 17873 WMI_ROAM_GET_SCAN_CHANNEL_LIST_CMDID); 17874 if (QDF_IS_STATUS_ERROR(ret)) { 17875 wmi_err("Failed to send get roam scan channels request = %d", 17876 ret); 17877 wmi_buf_free(buf); 17878 } 17879 return ret; 17880 } 17881 17882 /** 17883 * extract_roam_scan_stats_res_evt_tlv() - Extract roam scan stats event 17884 * @wmi_handle: wmi handle 17885 * @evt_buf: pointer to event buffer 17886 * @vdev_id: output pointer to hold vdev id 17887 * @res_param: output pointer to hold the allocated response 17888 * 17889 * Return: QDF_STATUS 17890 */ 17891 static QDF_STATUS 17892 extract_roam_scan_stats_res_evt_tlv(wmi_unified_t wmi_handle, void *evt_buf, 17893 uint32_t *vdev_id, 17894 struct wmi_roam_scan_stats_res **res_param) 17895 { 17896 WMI_ROAM_SCAN_STATS_EVENTID_param_tlvs *param_buf; 17897 wmi_roam_scan_stats_event_fixed_param *fixed_param; 17898 uint32_t *client_id = NULL; 17899 wmi_roaming_timestamp *timestamp = NULL; 17900 uint32_t *num_channels = NULL; 17901 uint32_t *chan_info = NULL; 17902 wmi_mac_addr *old_bssid = NULL; 17903 uint32_t *is_roaming_success = NULL; 17904 wmi_mac_addr *new_bssid = NULL; 17905 uint32_t *num_roam_candidates = NULL; 17906 wmi_roam_scan_trigger_reason *roam_reason = NULL; 17907 wmi_mac_addr *bssid = NULL; 17908 uint32_t *score = NULL; 17909 uint32_t *channel = NULL; 17910 uint32_t *rssi = NULL; 17911 int chan_idx = 0, cand_idx = 0; 17912 uint32_t total_len; 17913 struct wmi_roam_scan_stats_res *res; 17914 uint32_t i, j; 17915 uint32_t num_scans, scan_param_size; 17916 17917 *res_param = NULL; 17918 *vdev_id = 0xFF; /* Initialize to invalid vdev id */ 17919 param_buf = (WMI_ROAM_SCAN_STATS_EVENTID_param_tlvs *)evt_buf; 17920 if (!param_buf) { 17921 wmi_err("Invalid roam scan stats event"); 17922 return QDF_STATUS_E_INVAL; 17923 } 17924 17925 fixed_param = param_buf->fixed_param; 17926 17927 num_scans = fixed_param->num_roam_scans; 17928 scan_param_size = sizeof(struct wmi_roam_scan_stats_params); 17929 *vdev_id = fixed_param->vdev_id; 17930 if (num_scans > WMI_ROAM_SCAN_STATS_MAX) { 17931 wmi_err_rl("%u exceeded maximum roam scan stats: %u", 17932 num_scans, WMI_ROAM_SCAN_STATS_MAX); 17933 return QDF_STATUS_E_INVAL; 17934 } 17935 17936 total_len = sizeof(*res) + num_scans * scan_param_size; 17937 17938 res = qdf_mem_malloc(total_len); 17939 if (!res) 17940 return QDF_STATUS_E_NOMEM; 17941 17942 if (!num_scans) { 17943 *res_param = res; 17944 return QDF_STATUS_SUCCESS; 17945 } 17946 17947 if (param_buf->client_id && 17948 param_buf->num_client_id == num_scans) 17949 client_id = param_buf->client_id; 17950 17951 if (param_buf->timestamp && 17952 param_buf->num_timestamp == num_scans) 17953 timestamp = param_buf->timestamp; 17954 17955 if (param_buf->old_bssid && 17956 param_buf->num_old_bssid == num_scans) 17957 old_bssid = param_buf->old_bssid; 17958 17959 if (param_buf->new_bssid && 17960 param_buf->num_new_bssid == num_scans) 17961 new_bssid = param_buf->new_bssid; 17962 17963 if (param_buf->is_roaming_success && 17964 param_buf->num_is_roaming_success == num_scans) 17965 is_roaming_success = param_buf->is_roaming_success; 17966 17967 if (param_buf->roam_reason && 17968 param_buf->num_roam_reason == num_scans) 17969 roam_reason = param_buf->roam_reason; 17970 17971 if (param_buf->num_channels && 17972 param_buf->num_num_channels == num_scans) { 17973 uint32_t count, chan_info_sum = 0; 17974 17975 num_channels = param_buf->num_channels; 17976 for (count = 0; count < param_buf->num_num_channels; count++) { 17977 if (param_buf->num_channels[count] > 17978 WMI_ROAM_SCAN_STATS_CHANNELS_MAX) { 17979 wmi_err_rl("%u exceeded max scan channels %u", 17980 param_buf->num_channels[count], 17981 WMI_ROAM_SCAN_STATS_CHANNELS_MAX); 17982 goto error; 17983 } 17984 chan_info_sum += param_buf->num_channels[count]; 17985 } 17986 17987 if (param_buf->chan_info && 17988 param_buf->num_chan_info == chan_info_sum) 17989 chan_info = param_buf->chan_info; 17990 } 17991 17992 if (param_buf->num_roam_candidates && 17993 param_buf->num_num_roam_candidates == num_scans) { 17994 uint32_t cnt, roam_cand_sum = 0; 17995 17996 num_roam_candidates = param_buf->num_roam_candidates; 17997 for (cnt = 0; cnt < param_buf->num_num_roam_candidates; cnt++) { 17998 if (param_buf->num_roam_candidates[cnt] > 17999 WMI_ROAM_SCAN_STATS_CANDIDATES_MAX) { 18000 wmi_err_rl("%u exceeded max scan cand %u", 18001 param_buf->num_roam_candidates[cnt], 18002 WMI_ROAM_SCAN_STATS_CANDIDATES_MAX); 18003 goto error; 18004 } 18005 roam_cand_sum += param_buf->num_roam_candidates[cnt]; 18006 } 18007 18008 if (param_buf->bssid && 18009 param_buf->num_bssid == roam_cand_sum) 18010 bssid = param_buf->bssid; 18011 18012 if (param_buf->score && 18013 param_buf->num_score == roam_cand_sum) 18014 score = param_buf->score; 18015 18016 if (param_buf->channel && 18017 param_buf->num_channel == roam_cand_sum) 18018 channel = param_buf->channel; 18019 18020 if (param_buf->rssi && 18021 param_buf->num_rssi == roam_cand_sum) 18022 rssi = param_buf->rssi; 18023 } 18024 18025 res->num_roam_scans = num_scans; 18026 for (i = 0; i < num_scans; i++) { 18027 struct wmi_roam_scan_stats_params *roam = &res->roam_scan[i]; 18028 18029 if (timestamp) 18030 roam->time_stamp = timestamp[i].lower32bit | 18031 (timestamp[i].upper32bit << 31); 18032 18033 if (client_id) 18034 roam->client_id = client_id[i]; 18035 18036 if (num_channels) { 18037 roam->num_scan_chans = num_channels[i]; 18038 if (chan_info) { 18039 for (j = 0; j < num_channels[i]; j++) 18040 roam->scan_freqs[j] = 18041 chan_info[chan_idx++]; 18042 } 18043 } 18044 18045 if (is_roaming_success) 18046 roam->is_roam_successful = is_roaming_success[i]; 18047 18048 if (roam_reason) { 18049 roam->trigger_id = roam_reason[i].trigger_id; 18050 roam->trigger_value = roam_reason[i].trigger_value; 18051 } 18052 18053 if (num_roam_candidates) { 18054 roam->num_roam_candidates = num_roam_candidates[i]; 18055 18056 for (j = 0; j < num_roam_candidates[i]; j++) { 18057 if (score) 18058 roam->cand[j].score = score[cand_idx]; 18059 if (rssi) 18060 roam->cand[j].rssi = rssi[cand_idx]; 18061 if (channel) 18062 roam->cand[j].freq = 18063 channel[cand_idx]; 18064 18065 if (bssid) 18066 WMI_MAC_ADDR_TO_CHAR_ARRAY( 18067 &bssid[cand_idx], 18068 roam->cand[j].bssid); 18069 18070 cand_idx++; 18071 } 18072 } 18073 18074 if (old_bssid) 18075 WMI_MAC_ADDR_TO_CHAR_ARRAY(&old_bssid[i], 18076 roam->old_bssid); 18077 18078 if (new_bssid) 18079 WMI_MAC_ADDR_TO_CHAR_ARRAY(&new_bssid[i], 18080 roam->new_bssid); 18081 } 18082 18083 *res_param = res; 18084 18085 return QDF_STATUS_SUCCESS; 18086 error: 18087 qdf_mem_free(res); 18088 return QDF_STATUS_E_FAILURE; 18089 } 18090 18091 /** 18092 * extract_offload_bcn_tx_status_evt() - Extract beacon-tx status event 18093 * @wmi_handle: wmi handle 18094 * @evt_buf: pointer to event buffer 18095 * @vdev_id: output pointer to hold vdev id 18096 * @tx_status: output pointer to hold the tx_status 18097 * 18098 * Return: QDF_STATUS 18099 */ 18100 static QDF_STATUS extract_offload_bcn_tx_status_evt(wmi_unified_t wmi_handle, 18101 void *evt_buf, 18102 uint32_t *vdev_id, 18103 uint32_t *tx_status) { 18104 WMI_OFFLOAD_BCN_TX_STATUS_EVENTID_param_tlvs *param_buf; 18105 wmi_offload_bcn_tx_status_event_fixed_param *bcn_tx_status_event; 18106 18107 param_buf = (WMI_OFFLOAD_BCN_TX_STATUS_EVENTID_param_tlvs *)evt_buf; 18108 if (!param_buf) { 18109 wmi_err("Invalid offload bcn tx status event buffer"); 18110 return QDF_STATUS_E_INVAL; 18111 } 18112 18113 bcn_tx_status_event = param_buf->fixed_param; 18114 *vdev_id = bcn_tx_status_event->vdev_id; 18115 *tx_status = bcn_tx_status_event->tx_status; 18116 18117 return QDF_STATUS_SUCCESS; 18118 } 18119 18120 #ifdef WLAN_SUPPORT_GREEN_AP 18121 static QDF_STATUS extract_green_ap_egap_status_info_tlv( 18122 uint8_t *evt_buf, 18123 struct wlan_green_ap_egap_status_info *egap_status_info_params) 18124 { 18125 WMI_AP_PS_EGAP_INFO_EVENTID_param_tlvs *param_buf; 18126 wmi_ap_ps_egap_info_event_fixed_param *egap_info_event; 18127 wmi_ap_ps_egap_info_chainmask_list *chainmask_event; 18128 18129 param_buf = (WMI_AP_PS_EGAP_INFO_EVENTID_param_tlvs *)evt_buf; 18130 if (!param_buf) { 18131 wmi_err("Invalid EGAP Info status event buffer"); 18132 return QDF_STATUS_E_INVAL; 18133 } 18134 18135 egap_info_event = (wmi_ap_ps_egap_info_event_fixed_param *) 18136 param_buf->fixed_param; 18137 chainmask_event = (wmi_ap_ps_egap_info_chainmask_list *) 18138 param_buf->chainmask_list; 18139 18140 if (!egap_info_event || !chainmask_event) { 18141 wmi_err("Invalid EGAP Info event or chainmask event"); 18142 return QDF_STATUS_E_INVAL; 18143 } 18144 18145 egap_status_info_params->status = egap_info_event->status; 18146 egap_status_info_params->mac_id = chainmask_event->mac_id; 18147 egap_status_info_params->tx_chainmask = chainmask_event->tx_chainmask; 18148 egap_status_info_params->rx_chainmask = chainmask_event->rx_chainmask; 18149 18150 return QDF_STATUS_SUCCESS; 18151 } 18152 #endif 18153 18154 #ifdef WLAN_SUPPORT_GAP_LL_PS_MODE 18155 static QDF_STATUS extract_green_ap_ll_ps_param_tlv( 18156 uint8_t *evt_buf, 18157 struct wlan_green_ap_ll_ps_event_param *ll_ps_params) 18158 { 18159 WMI_XGAP_ENABLE_COMPLETE_EVENTID_param_tlvs *param_buf; 18160 wmi_xgap_enable_complete_event_fixed_param *ll_ps_event; 18161 18162 param_buf = (WMI_XGAP_ENABLE_COMPLETE_EVENTID_param_tlvs *)evt_buf; 18163 if (!param_buf) { 18164 wmi_err("Invalid XGAP SAP info status"); 18165 return QDF_STATUS_E_INVAL; 18166 } 18167 18168 ll_ps_event = (wmi_xgap_enable_complete_event_fixed_param *) 18169 param_buf->fixed_param; 18170 if (!ll_ps_event) { 18171 wmi_err("Invalid low latency power save event buffer"); 18172 return QDF_STATUS_E_INVAL; 18173 } 18174 18175 ll_ps_params->dialog_token = ll_ps_event->dialog_token; 18176 ll_ps_params->next_tsf = 18177 ((uint64_t)ll_ps_event->next_tsf_high32 << 32) | 18178 ll_ps_event->next_tsf_low32; 18179 18180 wmi_debug("cookie : %u next_tsf %llu", ll_ps_params->dialog_token, 18181 ll_ps_params->next_tsf); 18182 18183 return QDF_STATUS_SUCCESS; 18184 } 18185 #endif 18186 18187 /* 18188 * extract_comb_phyerr_tlv() - extract comb phy error from event 18189 * @wmi_handle: wmi handle 18190 * @evt_buf: pointer to event buffer 18191 * @datalen: data length of event buffer 18192 * @buf_offset: Pointer to hold value of current event buffer offset 18193 * post extraction 18194 * @phyerr: Pointer to hold phyerr 18195 * 18196 * Return: QDF_STATUS 18197 */ 18198 static QDF_STATUS extract_comb_phyerr_tlv(wmi_unified_t wmi_handle, 18199 void *evt_buf, 18200 uint16_t datalen, 18201 uint16_t *buf_offset, 18202 wmi_host_phyerr_t *phyerr) 18203 { 18204 WMI_PHYERR_EVENTID_param_tlvs *param_tlvs; 18205 wmi_comb_phyerr_rx_hdr *pe_hdr; 18206 18207 param_tlvs = (WMI_PHYERR_EVENTID_param_tlvs *)evt_buf; 18208 if (!param_tlvs) { 18209 wmi_debug("Received null data from FW"); 18210 return QDF_STATUS_E_FAILURE; 18211 } 18212 18213 pe_hdr = param_tlvs->hdr; 18214 if (!pe_hdr) { 18215 wmi_debug("Received Data PE Header is NULL"); 18216 return QDF_STATUS_E_FAILURE; 18217 } 18218 18219 /* Ensure it's at least the size of the header */ 18220 if (datalen < sizeof(*pe_hdr)) { 18221 wmi_debug("Expected minimum size %zu, received %d", 18222 sizeof(*pe_hdr), datalen); 18223 return QDF_STATUS_E_FAILURE; 18224 } 18225 18226 phyerr->pdev_id = wmi_handle->ops-> 18227 convert_pdev_id_target_to_host(wmi_handle, pe_hdr->pdev_id); 18228 phyerr->tsf64 = pe_hdr->tsf_l32; 18229 phyerr->tsf64 |= (((uint64_t)pe_hdr->tsf_u32) << 32); 18230 phyerr->bufp = param_tlvs->bufp; 18231 18232 if (pe_hdr->buf_len > param_tlvs->num_bufp) { 18233 wmi_debug("Invalid buf_len %d, num_bufp %d", 18234 pe_hdr->buf_len, param_tlvs->num_bufp); 18235 return QDF_STATUS_E_FAILURE; 18236 } 18237 18238 phyerr->buf_len = pe_hdr->buf_len; 18239 phyerr->phy_err_mask0 = pe_hdr->rsPhyErrMask0; 18240 phyerr->phy_err_mask1 = pe_hdr->rsPhyErrMask1; 18241 *buf_offset = sizeof(*pe_hdr) + sizeof(uint32_t); 18242 18243 return QDF_STATUS_SUCCESS; 18244 } 18245 18246 /** 18247 * extract_single_phyerr_tlv() - extract single phy error from event 18248 * @wmi_handle: wmi handle 18249 * @evt_buf: pointer to event buffer 18250 * @datalen: data length of event buffer 18251 * @buf_offset: Pointer to hold value of current event buffer offset 18252 * post extraction 18253 * @phyerr: Pointer to hold phyerr 18254 * 18255 * Return: QDF_STATUS 18256 */ 18257 static QDF_STATUS extract_single_phyerr_tlv(wmi_unified_t wmi_handle, 18258 void *evt_buf, 18259 uint16_t datalen, 18260 uint16_t *buf_offset, 18261 wmi_host_phyerr_t *phyerr) 18262 { 18263 wmi_single_phyerr_rx_event *ev; 18264 uint16_t n = *buf_offset; 18265 uint8_t *data = (uint8_t *)evt_buf; 18266 18267 if (n < datalen) { 18268 if ((datalen - n) < sizeof(ev->hdr)) { 18269 wmi_debug("Not enough space. len=%d, n=%d, hdr=%zu", 18270 datalen, n, sizeof(ev->hdr)); 18271 return QDF_STATUS_E_FAILURE; 18272 } 18273 18274 /* 18275 * Obtain a pointer to the beginning of the current event. 18276 * data[0] is the beginning of the WMI payload. 18277 */ 18278 ev = (wmi_single_phyerr_rx_event *)&data[n]; 18279 18280 /* 18281 * Sanity check the buffer length of the event against 18282 * what we currently have. 18283 * 18284 * Since buf_len is 32 bits, we check if it overflows 18285 * a large 32 bit value. It's not 0x7fffffff because 18286 * we increase n by (buf_len + sizeof(hdr)), which would 18287 * in itself cause n to overflow. 18288 * 18289 * If "int" is 64 bits then this becomes a moot point. 18290 */ 18291 if (ev->hdr.buf_len > PHYERROR_MAX_BUFFER_LENGTH) { 18292 wmi_debug("buf_len is garbage 0x%x", ev->hdr.buf_len); 18293 return QDF_STATUS_E_FAILURE; 18294 } 18295 18296 if ((n + ev->hdr.buf_len) > datalen) { 18297 wmi_debug("len exceeds n=%d, buf_len=%d, datalen=%d", 18298 n, ev->hdr.buf_len, datalen); 18299 return QDF_STATUS_E_FAILURE; 18300 } 18301 18302 phyerr->phy_err_code = WMI_UNIFIED_PHYERRCODE_GET(&ev->hdr); 18303 phyerr->tsf_timestamp = ev->hdr.tsf_timestamp; 18304 phyerr->bufp = &ev->bufp[0]; 18305 phyerr->buf_len = ev->hdr.buf_len; 18306 phyerr->rf_info.rssi_comb = WMI_UNIFIED_RSSI_COMB_GET(&ev->hdr); 18307 18308 /* 18309 * Advance the buffer pointer to the next PHY error. 18310 * buflen is the length of this payload, so we need to 18311 * advance past the current header _AND_ the payload. 18312 */ 18313 n += sizeof(*ev) + ev->hdr.buf_len; 18314 } 18315 *buf_offset = n; 18316 18317 return QDF_STATUS_SUCCESS; 18318 } 18319 18320 /** 18321 * extract_esp_estimation_ev_param_tlv() - extract air time from event 18322 * @wmi_handle: wmi handle 18323 * @evt_buf: pointer to event buffer 18324 * @param: Pointer to hold esp event 18325 * 18326 * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_INVAL on failure 18327 */ 18328 static QDF_STATUS 18329 extract_esp_estimation_ev_param_tlv(wmi_unified_t wmi_handle, 18330 void *evt_buf, 18331 struct esp_estimation_event *param) 18332 { 18333 WMI_ESP_ESTIMATE_EVENTID_param_tlvs *param_buf; 18334 wmi_esp_estimate_event_fixed_param *esp_event; 18335 18336 param_buf = (WMI_ESP_ESTIMATE_EVENTID_param_tlvs *)evt_buf; 18337 if (!param_buf) { 18338 wmi_err("Invalid ESP Estimate Event buffer"); 18339 return QDF_STATUS_E_INVAL; 18340 } 18341 esp_event = param_buf->fixed_param; 18342 param->ac_airtime_percentage = esp_event->ac_airtime_percentage; 18343 18344 param->pdev_id = convert_target_pdev_id_to_host_pdev_id( 18345 wmi_handle, 18346 esp_event->pdev_id); 18347 18348 if (param->pdev_id == WMI_HOST_PDEV_ID_INVALID) 18349 return QDF_STATUS_E_FAILURE; 18350 18351 return QDF_STATUS_SUCCESS; 18352 } 18353 18354 /* 18355 * send_bss_color_change_enable_cmd_tlv() - Send command to enable or disable of 18356 * updating bss color change within firmware when AP announces bss color change. 18357 * @wmi_handle: wmi handle 18358 * @vdev_id: vdev ID 18359 * @enable: enable bss color change within firmware 18360 * 18361 * Send WMI_BSS_COLOR_CHANGE_ENABLE_CMDID parameters to fw. 18362 * 18363 * Return: QDF_STATUS 18364 */ 18365 static QDF_STATUS send_bss_color_change_enable_cmd_tlv(wmi_unified_t wmi_handle, 18366 uint32_t vdev_id, 18367 bool enable) 18368 { 18369 wmi_buf_t buf; 18370 wmi_bss_color_change_enable_fixed_param *cmd; 18371 uint8_t len = sizeof(wmi_bss_color_change_enable_fixed_param); 18372 18373 buf = wmi_buf_alloc(wmi_handle, len); 18374 if (!buf) 18375 return QDF_STATUS_E_NOMEM; 18376 18377 cmd = (wmi_bss_color_change_enable_fixed_param *)wmi_buf_data(buf); 18378 WMITLV_SET_HDR(&cmd->tlv_header, 18379 WMITLV_TAG_STRUC_wmi_bss_color_change_enable_fixed_param, 18380 WMITLV_GET_STRUCT_TLVLEN 18381 (wmi_bss_color_change_enable_fixed_param)); 18382 cmd->vdev_id = vdev_id; 18383 cmd->enable = enable; 18384 wmi_mtrace(WMI_BSS_COLOR_CHANGE_ENABLE_CMDID, cmd->vdev_id, 0); 18385 if (wmi_unified_cmd_send(wmi_handle, buf, len, 18386 WMI_BSS_COLOR_CHANGE_ENABLE_CMDID)) { 18387 wmi_err("Failed to send WMI_BSS_COLOR_CHANGE_ENABLE_CMDID"); 18388 wmi_buf_free(buf); 18389 return QDF_STATUS_E_FAILURE; 18390 } 18391 18392 return QDF_STATUS_SUCCESS; 18393 } 18394 18395 /** 18396 * send_obss_color_collision_cfg_cmd_tlv() - send bss color detection 18397 * configurations to firmware. 18398 * @wmi_handle: wmi handle 18399 * @cfg_param: obss detection configurations 18400 * 18401 * Send WMI_OBSS_COLOR_COLLISION_DET_CONFIG_CMDID parameters to fw. 18402 * 18403 * Return: QDF_STATUS 18404 */ 18405 static QDF_STATUS send_obss_color_collision_cfg_cmd_tlv( 18406 wmi_unified_t wmi_handle, 18407 struct wmi_obss_color_collision_cfg_param *cfg_param) 18408 { 18409 wmi_buf_t buf; 18410 wmi_obss_color_collision_det_config_fixed_param *cmd; 18411 uint8_t len = sizeof(wmi_obss_color_collision_det_config_fixed_param); 18412 18413 buf = wmi_buf_alloc(wmi_handle, len); 18414 if (!buf) 18415 return QDF_STATUS_E_NOMEM; 18416 18417 cmd = (wmi_obss_color_collision_det_config_fixed_param *)wmi_buf_data( 18418 buf); 18419 WMITLV_SET_HDR(&cmd->tlv_header, 18420 WMITLV_TAG_STRUC_wmi_obss_color_collision_det_config_fixed_param, 18421 WMITLV_GET_STRUCT_TLVLEN 18422 (wmi_obss_color_collision_det_config_fixed_param)); 18423 cmd->vdev_id = cfg_param->vdev_id; 18424 cmd->flags = cfg_param->flags; 18425 cmd->current_bss_color = cfg_param->current_bss_color; 18426 cmd->detection_period_ms = cfg_param->detection_period_ms; 18427 cmd->scan_period_ms = cfg_param->scan_period_ms; 18428 cmd->free_slot_expiry_time_ms = cfg_param->free_slot_expiry_time_ms; 18429 18430 switch (cfg_param->evt_type) { 18431 case OBSS_COLOR_COLLISION_DETECTION_DISABLE: 18432 cmd->evt_type = WMI_BSS_COLOR_COLLISION_DISABLE; 18433 break; 18434 case OBSS_COLOR_COLLISION_DETECTION: 18435 cmd->evt_type = WMI_BSS_COLOR_COLLISION_DETECTION; 18436 break; 18437 case OBSS_COLOR_FREE_SLOT_TIMER_EXPIRY: 18438 cmd->evt_type = WMI_BSS_COLOR_FREE_SLOT_TIMER_EXPIRY; 18439 break; 18440 case OBSS_COLOR_FREE_SLOT_AVAILABLE: 18441 cmd->evt_type = WMI_BSS_COLOR_FREE_SLOT_AVAILABLE; 18442 break; 18443 default: 18444 wmi_err("Invalid event type: %d", cfg_param->evt_type); 18445 wmi_buf_free(buf); 18446 return QDF_STATUS_E_FAILURE; 18447 } 18448 18449 wmi_debug("evt_type: %d vdev id: %d current_bss_color: %d " 18450 "detection_period_ms: %d scan_period_ms: %d " 18451 "free_slot_expiry_timer_ms: %d", 18452 cmd->evt_type, cmd->vdev_id, cmd->current_bss_color, 18453 cmd->detection_period_ms, cmd->scan_period_ms, 18454 cmd->free_slot_expiry_time_ms); 18455 18456 wmi_mtrace(WMI_OBSS_COLOR_COLLISION_DET_CONFIG_CMDID, cmd->vdev_id, 0); 18457 if (wmi_unified_cmd_send(wmi_handle, buf, len, 18458 WMI_OBSS_COLOR_COLLISION_DET_CONFIG_CMDID)) { 18459 wmi_err("Sending OBSS color det cmd failed, vdev_id: %d", 18460 cfg_param->vdev_id); 18461 wmi_buf_free(buf); 18462 return QDF_STATUS_E_FAILURE; 18463 } 18464 18465 return QDF_STATUS_SUCCESS; 18466 } 18467 18468 /** 18469 * extract_obss_color_collision_info_tlv() - Extract bss color collision info 18470 * received from firmware. 18471 * @evt_buf: pointer to event buffer 18472 * @info: Pointer to hold bss collision info 18473 * 18474 * Return: QDF_STATUS 18475 */ 18476 static QDF_STATUS extract_obss_color_collision_info_tlv(uint8_t *evt_buf, 18477 struct wmi_obss_color_collision_info *info) 18478 { 18479 WMI_OBSS_COLOR_COLLISION_DETECTION_EVENTID_param_tlvs *param_buf; 18480 wmi_obss_color_collision_evt_fixed_param *fix_param; 18481 18482 if (!info) { 18483 wmi_err("Invalid obss color buffer"); 18484 return QDF_STATUS_E_INVAL; 18485 } 18486 18487 param_buf = (WMI_OBSS_COLOR_COLLISION_DETECTION_EVENTID_param_tlvs *) 18488 evt_buf; 18489 if (!param_buf) { 18490 wmi_err("Invalid evt_buf"); 18491 return QDF_STATUS_E_INVAL; 18492 } 18493 18494 fix_param = param_buf->fixed_param; 18495 info->vdev_id = fix_param->vdev_id; 18496 info->obss_color_bitmap_bit0to31 = 18497 fix_param->bss_color_bitmap_bit0to31; 18498 info->obss_color_bitmap_bit32to63 = 18499 fix_param->bss_color_bitmap_bit32to63; 18500 18501 switch (fix_param->evt_type) { 18502 case WMI_BSS_COLOR_COLLISION_DISABLE: 18503 info->evt_type = OBSS_COLOR_COLLISION_DETECTION_DISABLE; 18504 break; 18505 case WMI_BSS_COLOR_COLLISION_DETECTION: 18506 info->evt_type = OBSS_COLOR_COLLISION_DETECTION; 18507 break; 18508 case WMI_BSS_COLOR_FREE_SLOT_TIMER_EXPIRY: 18509 info->evt_type = OBSS_COLOR_FREE_SLOT_TIMER_EXPIRY; 18510 break; 18511 case WMI_BSS_COLOR_FREE_SLOT_AVAILABLE: 18512 info->evt_type = OBSS_COLOR_FREE_SLOT_AVAILABLE; 18513 break; 18514 default: 18515 wmi_err("Invalid event type: %d, vdev_id: %d", 18516 fix_param->evt_type, fix_param->vdev_id); 18517 return QDF_STATUS_E_FAILURE; 18518 } 18519 18520 return QDF_STATUS_SUCCESS; 18521 } 18522 18523 static void wmi_11ax_bss_color_attach_tlv(struct wmi_unified *wmi_handle) 18524 { 18525 struct wmi_ops *ops = wmi_handle->ops; 18526 18527 ops->send_obss_color_collision_cfg_cmd = 18528 send_obss_color_collision_cfg_cmd_tlv; 18529 ops->extract_obss_color_collision_info = 18530 extract_obss_color_collision_info_tlv; 18531 } 18532 18533 #if defined(WLAN_SUPPORT_FILS) || defined(CONFIG_BAND_6GHZ) 18534 static QDF_STATUS 18535 send_vdev_fils_enable_cmd_send(struct wmi_unified *wmi_handle, 18536 struct config_fils_params *param) 18537 { 18538 wmi_buf_t buf; 18539 wmi_enable_fils_cmd_fixed_param *cmd; 18540 uint8_t len = sizeof(wmi_enable_fils_cmd_fixed_param); 18541 18542 buf = wmi_buf_alloc(wmi_handle, len); 18543 if (!buf) 18544 return QDF_STATUS_E_NOMEM; 18545 18546 cmd = (wmi_enable_fils_cmd_fixed_param *)wmi_buf_data( 18547 buf); 18548 WMITLV_SET_HDR(&cmd->tlv_header, 18549 WMITLV_TAG_STRUC_wmi_enable_fils_cmd_fixed_param, 18550 WMITLV_GET_STRUCT_TLVLEN 18551 (wmi_enable_fils_cmd_fixed_param)); 18552 cmd->vdev_id = param->vdev_id; 18553 cmd->fd_period = param->fd_period; 18554 if (param->send_prb_rsp_frame) 18555 cmd->flags |= WMI_FILS_FLAGS_BITMAP_BCAST_PROBE_RSP; 18556 wmi_debug("vdev id: %d fd_period: %d cmd->Flags %d", 18557 cmd->vdev_id, cmd->fd_period, cmd->flags); 18558 wmi_mtrace(WMI_ENABLE_FILS_CMDID, cmd->vdev_id, cmd->fd_period); 18559 if (wmi_unified_cmd_send(wmi_handle, buf, len, 18560 WMI_ENABLE_FILS_CMDID)) { 18561 wmi_err("Sending FILS cmd failed, vdev_id: %d", param->vdev_id); 18562 wmi_buf_free(buf); 18563 return QDF_STATUS_E_FAILURE; 18564 } 18565 18566 return QDF_STATUS_SUCCESS; 18567 } 18568 #endif 18569 18570 #ifdef WLAN_MWS_INFO_DEBUGFS 18571 /** 18572 * send_mws_coex_status_req_cmd_tlv() - send coex cmd to fw 18573 * 18574 * @wmi_handle: wmi handle 18575 * @vdev_id: vdev id 18576 * @cmd_id: Coex command id 18577 * 18578 * Send WMI_VDEV_GET_MWS_COEX_INFO_CMDID to fw. 18579 * 18580 * Return: QDF_STATUS 18581 */ 18582 static QDF_STATUS send_mws_coex_status_req_cmd_tlv(wmi_unified_t wmi_handle, 18583 uint32_t vdev_id, 18584 uint32_t cmd_id) 18585 { 18586 wmi_buf_t buf; 18587 wmi_vdev_get_mws_coex_info_cmd_fixed_param *cmd; 18588 uint16_t len = sizeof(*cmd); 18589 int ret; 18590 18591 buf = wmi_buf_alloc(wmi_handle, len); 18592 if (!buf) { 18593 wmi_err("Failed to allocate wmi buffer"); 18594 return QDF_STATUS_E_NOMEM; 18595 } 18596 18597 cmd = (wmi_vdev_get_mws_coex_info_cmd_fixed_param *)wmi_buf_data(buf); 18598 WMITLV_SET_HDR(&cmd->tlv_header, 18599 WMITLV_TAG_STRUC_wmi_vdev_get_mws_coex_info_cmd_fixed_param, 18600 WMITLV_GET_STRUCT_TLVLEN 18601 (wmi_vdev_get_mws_coex_info_cmd_fixed_param)); 18602 cmd->vdev_id = vdev_id; 18603 cmd->cmd_id = cmd_id; 18604 wmi_mtrace(WMI_VDEV_GET_MWS_COEX_INFO_CMDID, vdev_id, 0); 18605 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 18606 WMI_VDEV_GET_MWS_COEX_INFO_CMDID); 18607 if (QDF_IS_STATUS_ERROR(ret)) { 18608 wmi_err("Failed to send set param command ret = %d", ret); 18609 wmi_buf_free(buf); 18610 } 18611 return ret; 18612 } 18613 #endif 18614 18615 #ifdef FEATURE_MEC_OFFLOAD 18616 static QDF_STATUS 18617 send_pdev_set_mec_timer_cmd_tlv(struct wmi_unified *wmi_handle, 18618 struct set_mec_timer_params *param) 18619 { 18620 wmi_pdev_mec_aging_timer_config_cmd_fixed_param *cmd; 18621 wmi_buf_t buf; 18622 int32_t len = sizeof(*cmd); 18623 18624 buf = wmi_buf_alloc(wmi_handle, len); 18625 if (!buf) { 18626 wmi_err("wmi_buf_alloc failed"); 18627 return QDF_STATUS_E_FAILURE; 18628 } 18629 cmd = (wmi_pdev_mec_aging_timer_config_cmd_fixed_param *) 18630 wmi_buf_data(buf); 18631 WMITLV_SET_HDR(&cmd->tlv_header, 18632 WMITLV_TAG_STRUC_wmi_pdev_mec_aging_timer_config_cmd_fixed_param, 18633 WMITLV_GET_STRUCT_TLVLEN( 18634 wmi_pdev_mec_aging_timer_config_cmd_fixed_param)); 18635 cmd->pdev_id = param->pdev_id; 18636 cmd->mec_aging_timer_threshold = param->mec_aging_timer_threshold; 18637 18638 wmi_mtrace(WMI_PDEV_MEC_AGING_TIMER_CONFIG_CMDID, param->vdev_id, 0); 18639 if (wmi_unified_cmd_send(wmi_handle, buf, len, 18640 WMI_PDEV_MEC_AGING_TIMER_CONFIG_CMDID)) { 18641 wmi_err("Failed to set mec aging timer param"); 18642 wmi_buf_free(buf); 18643 return QDF_STATUS_E_FAILURE; 18644 } 18645 18646 return QDF_STATUS_SUCCESS; 18647 } 18648 #endif 18649 18650 #ifdef WIFI_POS_CONVERGED 18651 /** 18652 * extract_oem_response_param_tlv() - Extract oem response params 18653 * @wmi_handle: wmi handle 18654 * @resp_buf: response buffer 18655 * @oem_resp_param: pointer to hold oem response params 18656 * 18657 * Return: QDF_STATUS_SUCCESS on success or proper error code. 18658 */ 18659 static QDF_STATUS 18660 extract_oem_response_param_tlv(wmi_unified_t wmi_handle, void *resp_buf, 18661 struct wmi_oem_response_param *oem_resp_param) 18662 { 18663 uint64_t temp_addr; 18664 WMI_OEM_RESPONSE_EVENTID_param_tlvs *param_buf = 18665 (WMI_OEM_RESPONSE_EVENTID_param_tlvs *)resp_buf; 18666 18667 if (!param_buf) { 18668 wmi_err("Invalid OEM response"); 18669 return QDF_STATUS_E_INVAL; 18670 } 18671 18672 if (param_buf->num_data) { 18673 oem_resp_param->num_data1 = param_buf->num_data; 18674 oem_resp_param->data_1 = param_buf->data; 18675 } 18676 18677 if (param_buf->num_data2) { 18678 oem_resp_param->num_data2 = param_buf->num_data2; 18679 oem_resp_param->data_2 = param_buf->data2; 18680 } 18681 18682 if (param_buf->indirect_data) { 18683 oem_resp_param->indirect_data.pdev_id = 18684 param_buf->indirect_data->pdev_id; 18685 temp_addr = (param_buf->indirect_data->addr_hi) & 0xf; 18686 oem_resp_param->indirect_data.addr = 18687 param_buf->indirect_data->addr_lo + 18688 ((uint64_t)temp_addr << 32); 18689 oem_resp_param->indirect_data.len = 18690 param_buf->indirect_data->len; 18691 } 18692 18693 return QDF_STATUS_SUCCESS; 18694 } 18695 #endif /* WIFI_POS_CONVERGED */ 18696 18697 #if defined(WIFI_POS_CONVERGED) && defined(WLAN_FEATURE_RTT_11AZ_SUPPORT) 18698 #define WLAN_PASN_LTF_KEY_SEED_REQUIRED 0x2 18699 18700 static QDF_STATUS 18701 extract_pasn_peer_create_req_event_tlv(wmi_unified_t wmi_handle, void *evt_buf, 18702 struct wifi_pos_pasn_peer_data *dst) 18703 { 18704 WMI_RTT_PASN_PEER_CREATE_REQ_EVENTID_param_tlvs *param_buf; 18705 wmi_rtt_pasn_peer_create_req_event_fixed_param *fixed_param; 18706 wmi_rtt_pasn_peer_create_req_param *buf; 18707 uint8_t security_mode, i; 18708 18709 param_buf = (WMI_RTT_PASN_PEER_CREATE_REQ_EVENTID_param_tlvs *)evt_buf; 18710 if (!param_buf) { 18711 wmi_err("Invalid peer_create req buffer"); 18712 return QDF_STATUS_E_INVAL; 18713 } 18714 18715 fixed_param = param_buf->fixed_param; 18716 18717 if (param_buf->num_rtt_pasn_peer_param > 18718 ((WMI_SVC_MSG_MAX_SIZE - sizeof(*fixed_param)) / 18719 sizeof(wmi_rtt_pasn_peer_create_req_param))) { 18720 wmi_err("Invalid TLV size"); 18721 return QDF_STATUS_E_INVAL; 18722 } 18723 18724 if (!param_buf->num_rtt_pasn_peer_param || 18725 param_buf->num_rtt_pasn_peer_param > WLAN_MAX_11AZ_PEERS) { 18726 wmi_err("Invalid num TLV:%d", 18727 param_buf->num_rtt_pasn_peer_param); 18728 return QDF_STATUS_E_INVAL; 18729 } 18730 18731 dst->vdev_id = fixed_param->vdev_id; 18732 if (dst->vdev_id >= WLAN_UMAC_PDEV_MAX_VDEVS) { 18733 wmi_err("Invalid vdev id:%d", dst->vdev_id); 18734 return QDF_STATUS_E_INVAL; 18735 } 18736 18737 buf = param_buf->rtt_pasn_peer_param; 18738 if (!buf) { 18739 wmi_err("NULL peer param TLV"); 18740 return QDF_STATUS_E_INVAL; 18741 } 18742 18743 for (i = 0; i < param_buf->num_rtt_pasn_peer_param; i++) { 18744 WMI_MAC_ADDR_TO_CHAR_ARRAY(&buf->self_mac_addr, 18745 dst->peer_info[i].self_mac.bytes); 18746 WMI_MAC_ADDR_TO_CHAR_ARRAY(&buf->dest_mac_addr, 18747 dst->peer_info[i].peer_mac.bytes); 18748 security_mode = WMI_RTT_PASN_PEER_CREATE_SECURITY_MODE_GET( 18749 buf->control_flag); 18750 if (security_mode) 18751 dst->peer_info[i].peer_type = 18752 WLAN_WIFI_POS_PASN_SECURE_PEER; 18753 else 18754 dst->peer_info[i].peer_type = 18755 WLAN_WIFI_POS_PASN_UNSECURE_PEER; 18756 if (security_mode & WLAN_PASN_LTF_KEY_SEED_REQUIRED) 18757 dst->peer_info[i].is_ltf_keyseed_required = true; 18758 18759 dst->peer_info[i].force_self_mac_usage = 18760 WMI_RTT_PASN_PEER_CREATE_FORCE_SELF_MAC_USE_GET( 18761 buf->control_flag); 18762 dst->num_peers++; 18763 buf++; 18764 } 18765 18766 return QDF_STATUS_SUCCESS; 18767 } 18768 18769 static QDF_STATUS 18770 extract_pasn_peer_delete_req_event_tlv(wmi_unified_t wmi_handle, void *evt_buf, 18771 struct wifi_pos_pasn_peer_data *dst) 18772 { 18773 WMI_RTT_PASN_PEER_DELETE_EVENTID_param_tlvs *param_buf; 18774 wmi_rtt_pasn_peer_delete_event_fixed_param *fixed_param; 18775 wmi_rtt_pasn_peer_delete_param *buf; 18776 uint8_t i; 18777 18778 param_buf = (WMI_RTT_PASN_PEER_DELETE_EVENTID_param_tlvs *)evt_buf; 18779 if (!param_buf) { 18780 wmi_err("Invalid peer_delete evt buffer"); 18781 return QDF_STATUS_E_INVAL; 18782 } 18783 18784 fixed_param = param_buf->fixed_param; 18785 18786 if (param_buf->num_rtt_pasn_peer_param > 18787 ((WMI_SVC_MSG_MAX_SIZE - sizeof(*fixed_param)) / 18788 sizeof(wmi_rtt_pasn_peer_delete_param))) { 18789 wmi_err("Invalid TLV size"); 18790 return QDF_STATUS_E_INVAL; 18791 } 18792 18793 if (!param_buf->num_rtt_pasn_peer_param || 18794 param_buf->num_rtt_pasn_peer_param > WLAN_MAX_11AZ_PEERS) { 18795 wmi_err("Invalid num TLV:%d", 18796 param_buf->num_rtt_pasn_peer_param); 18797 return QDF_STATUS_E_INVAL; 18798 } 18799 18800 dst->vdev_id = fixed_param->vdev_id; 18801 if (dst->vdev_id >= WLAN_UMAC_PDEV_MAX_VDEVS) { 18802 wmi_err("Invalid vdev id:%d", dst->vdev_id); 18803 return QDF_STATUS_E_INVAL; 18804 } 18805 18806 buf = param_buf->rtt_pasn_peer_param; 18807 if (!buf) { 18808 wmi_err("NULL peer param TLV"); 18809 return QDF_STATUS_E_INVAL; 18810 } 18811 18812 for (i = 0; i < param_buf->num_rtt_pasn_peer_param; i++) { 18813 WMI_MAC_ADDR_TO_CHAR_ARRAY(&buf->peer_mac_addr, 18814 dst->peer_info[i].peer_mac.bytes); 18815 dst->peer_info[i].control_flags = buf->control_flag; 18816 18817 dst->num_peers++; 18818 buf++; 18819 } 18820 18821 return QDF_STATUS_SUCCESS; 18822 } 18823 18824 static QDF_STATUS 18825 send_rtt_pasn_auth_status_cmd_tlv(wmi_unified_t wmi_handle, 18826 struct wlan_pasn_auth_status *data) 18827 { 18828 QDF_STATUS status; 18829 wmi_buf_t buf; 18830 wmi_rtt_pasn_auth_status_cmd_fixed_param *fixed_param; 18831 uint8_t *buf_ptr; 18832 uint8_t i; 18833 size_t len = sizeof(*fixed_param) + 18834 data->num_peers * sizeof(wmi_rtt_pasn_auth_status_param) + 18835 WMI_TLV_HDR_SIZE; 18836 18837 buf = wmi_buf_alloc(wmi_handle, len); 18838 if (!buf) { 18839 wmi_err("wmi_buf_alloc failed"); 18840 return QDF_STATUS_E_FAILURE; 18841 } 18842 buf_ptr = (uint8_t *)wmi_buf_data(buf); 18843 fixed_param = 18844 (wmi_rtt_pasn_auth_status_cmd_fixed_param *)wmi_buf_data(buf); 18845 WMITLV_SET_HDR(&fixed_param->tlv_header, 18846 WMITLV_TAG_STRUC_wmi_rtt_pasn_auth_status_cmd_fixed_param, 18847 WMITLV_GET_STRUCT_TLVLEN( 18848 wmi_rtt_pasn_auth_status_cmd_fixed_param)); 18849 buf_ptr += sizeof(*fixed_param); 18850 18851 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 18852 (data->num_peers * 18853 sizeof(wmi_rtt_pasn_auth_status_param))); 18854 buf_ptr += WMI_TLV_HDR_SIZE; 18855 18856 for (i = 0; i < data->num_peers; i++) { 18857 wmi_rtt_pasn_auth_status_param *auth_status_tlv = 18858 (wmi_rtt_pasn_auth_status_param *)buf_ptr; 18859 18860 WMITLV_SET_HDR(&auth_status_tlv->tlv_header, 18861 WMITLV_TAG_STRUC_wmi_rtt_pasn_auth_status_param, 18862 WMITLV_GET_STRUCT_TLVLEN(wmi_rtt_pasn_auth_status_param)); 18863 18864 WMI_CHAR_ARRAY_TO_MAC_ADDR(data->auth_status[i].peer_mac.bytes, 18865 &auth_status_tlv->peer_mac_addr); 18866 WMI_CHAR_ARRAY_TO_MAC_ADDR(data->auth_status[i].self_mac.bytes, 18867 &auth_status_tlv->source_mac_addr); 18868 auth_status_tlv->status = data->auth_status[i].status; 18869 wmi_debug("peer_mac: " QDF_MAC_ADDR_FMT " self_mac:" QDF_MAC_ADDR_FMT " status:%d", 18870 QDF_MAC_ADDR_REF(data->auth_status[i].peer_mac.bytes), 18871 QDF_MAC_ADDR_REF(data->auth_status[i].self_mac.bytes), 18872 auth_status_tlv->status); 18873 18874 buf_ptr += sizeof(wmi_rtt_pasn_auth_status_param); 18875 } 18876 18877 wmi_mtrace(WMI_RTT_PASN_AUTH_STATUS_CMD, 0, 0); 18878 status = wmi_unified_cmd_send(wmi_handle, buf, len, 18879 WMI_RTT_PASN_AUTH_STATUS_CMD); 18880 if (QDF_IS_STATUS_ERROR(status)) { 18881 wmi_err("Failed to send Auth status command ret = %d", status); 18882 wmi_buf_free(buf); 18883 } 18884 18885 return status; 18886 } 18887 18888 static QDF_STATUS 18889 send_rtt_pasn_deauth_cmd_tlv(wmi_unified_t wmi_handle, 18890 struct qdf_mac_addr *peer_mac) 18891 { 18892 QDF_STATUS status; 18893 wmi_buf_t buf; 18894 wmi_rtt_pasn_deauth_cmd_fixed_param *fixed_param; 18895 size_t len = sizeof(*fixed_param); 18896 18897 buf = wmi_buf_alloc(wmi_handle, len); 18898 if (!buf) { 18899 wmi_err("wmi_buf_alloc failed"); 18900 return QDF_STATUS_E_FAILURE; 18901 } 18902 fixed_param = 18903 (wmi_rtt_pasn_deauth_cmd_fixed_param *)wmi_buf_data(buf); 18904 WMITLV_SET_HDR(&fixed_param->tlv_header, 18905 WMITLV_TAG_STRUC_wmi_rtt_pasn_deauth_cmd_fixed_param, 18906 WMITLV_GET_STRUCT_TLVLEN( 18907 wmi_rtt_pasn_deauth_cmd_fixed_param)); 18908 WMI_CHAR_ARRAY_TO_MAC_ADDR(peer_mac->bytes, 18909 &fixed_param->peer_mac_addr); 18910 18911 wmi_mtrace(WMI_RTT_PASN_DEAUTH_CMD, 0, 0); 18912 status = wmi_unified_cmd_send(wmi_handle, buf, len, 18913 WMI_RTT_PASN_DEAUTH_CMD); 18914 if (QDF_IS_STATUS_ERROR(status)) { 18915 wmi_err("Failed to send pasn deauth command ret = %d", status); 18916 wmi_buf_free(buf); 18917 } 18918 18919 return status; 18920 } 18921 #endif /* WLAN_FEATURE_RTT_11AZ_SUPPORT */ 18922 18923 static QDF_STATUS 18924 send_vdev_set_ltf_key_seed_cmd_tlv(wmi_unified_t wmi_handle, 18925 struct wlan_crypto_ltf_keyseed_data *data) 18926 { 18927 QDF_STATUS status; 18928 wmi_buf_t buf; 18929 wmi_vdev_set_ltf_key_seed_cmd_fixed_param *fixed_param; 18930 uint8_t *buf_ptr; 18931 size_t len = sizeof(*fixed_param) + data->key_seed_len + 18932 WMI_TLV_HDR_SIZE; 18933 18934 buf = wmi_buf_alloc(wmi_handle, len); 18935 if (!buf) { 18936 wmi_err("wmi_buf_alloc failed"); 18937 return QDF_STATUS_E_FAILURE; 18938 } 18939 18940 buf_ptr = (uint8_t *)wmi_buf_data(buf); 18941 fixed_param = 18942 (wmi_vdev_set_ltf_key_seed_cmd_fixed_param *)wmi_buf_data(buf); 18943 WMITLV_SET_HDR(&fixed_param->tlv_header, 18944 WMITLV_TAG_STRUC_wmi_vdev_set_ltf_key_seed_cmd_fixed_param, 18945 WMITLV_GET_STRUCT_TLVLEN( 18946 wmi_vdev_set_ltf_key_seed_cmd_fixed_param)); 18947 18948 fixed_param->vdev_id = data->vdev_id; 18949 WMI_CHAR_ARRAY_TO_MAC_ADDR(data->peer_mac_addr.bytes, 18950 &fixed_param->peer_macaddr); 18951 fixed_param->key_seed_len = data->key_seed_len; 18952 fixed_param->rsn_authmode = data->rsn_authmode; 18953 18954 buf_ptr += sizeof(*fixed_param); 18955 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, 18956 (fixed_param->key_seed_len * sizeof(A_UINT8))); 18957 buf_ptr += WMI_TLV_HDR_SIZE; 18958 18959 qdf_mem_copy(buf_ptr, data->key_seed, fixed_param->key_seed_len); 18960 18961 wmi_mtrace(WMI_VDEV_SET_LTF_KEY_SEED_CMDID, 0, 0); 18962 status = wmi_unified_cmd_send(wmi_handle, buf, len, 18963 WMI_VDEV_SET_LTF_KEY_SEED_CMDID); 18964 if (QDF_IS_STATUS_ERROR(status)) { 18965 wmi_err("Failed to send ltf keyseed command ret = %d", status); 18966 wmi_buf_free(buf); 18967 } 18968 18969 return status; 18970 } 18971 18972 /** 18973 * extract_hw_mode_resp_event_status_tlv() - Extract HW mode change status 18974 * @wmi_handle: wmi handle 18975 * @evt_buf: pointer to event buffer 18976 * @cmd_status: status of HW mode change command 18977 * 18978 * Return: QDF_STATUS_SUCCESS on success or proper error code. 18979 */ 18980 static QDF_STATUS 18981 extract_hw_mode_resp_event_status_tlv(wmi_unified_t wmi_handle, void *evt_buf, 18982 uint32_t *cmd_status) 18983 { 18984 WMI_PDEV_SET_HW_MODE_RESP_EVENTID_param_tlvs *param_buf; 18985 wmi_pdev_set_hw_mode_response_event_fixed_param *fixed_param; 18986 18987 param_buf = (WMI_PDEV_SET_HW_MODE_RESP_EVENTID_param_tlvs *)evt_buf; 18988 if (!param_buf) { 18989 wmi_err("Invalid mode change event buffer"); 18990 return QDF_STATUS_E_INVAL; 18991 } 18992 18993 fixed_param = param_buf->fixed_param; 18994 if (!fixed_param) { 18995 wmi_err("Invalid fixed param"); 18996 return QDF_STATUS_E_INVAL; 18997 } 18998 18999 *cmd_status = fixed_param->status; 19000 return QDF_STATUS_SUCCESS; 19001 } 19002 19003 /** 19004 * extract_rf_path_resp_tlv() - Extract RF path change status 19005 * @wmi_handle: wmi handle 19006 * @evt_buf: pointer to event buffer 19007 * @cmd_status: status of RF path change request 19008 * 19009 * Return: QDF_STATUS_SUCCESS on success or proper error code. 19010 */ 19011 static QDF_STATUS 19012 extract_rf_path_resp_tlv(wmi_unified_t wmi_handle, void *evt_buf, 19013 uint32_t *cmd_status) 19014 { 19015 WMI_PDEV_SET_RF_PATH_RESP_EVENTID_param_tlvs *param_buf; 19016 wmi_pdev_set_rf_path_event_fixed_param *fixed_param; 19017 19018 param_buf = (WMI_PDEV_SET_RF_PATH_RESP_EVENTID_param_tlvs *)evt_buf; 19019 if (!param_buf) { 19020 wmi_err("Invalid RF path event buffer"); 19021 return QDF_STATUS_E_INVAL; 19022 } 19023 19024 fixed_param = param_buf->fixed_param; 19025 if (!fixed_param) { 19026 wmi_err("Invalid fixed param"); 19027 return QDF_STATUS_E_INVAL; 19028 } 19029 19030 *cmd_status = fixed_param->status; 19031 return QDF_STATUS_SUCCESS; 19032 } 19033 19034 #ifdef FEATURE_ANI_LEVEL_REQUEST 19035 static QDF_STATUS send_ani_level_cmd_tlv(wmi_unified_t wmi_handle, 19036 uint32_t *freqs, 19037 uint8_t num_freqs) 19038 { 19039 wmi_buf_t buf; 19040 wmi_get_channel_ani_cmd_fixed_param *cmd; 19041 QDF_STATUS ret; 19042 uint32_t len; 19043 A_UINT32 *chan_list; 19044 uint8_t i, *buf_ptr; 19045 19046 len = sizeof(wmi_get_channel_ani_cmd_fixed_param) + 19047 WMI_TLV_HDR_SIZE + 19048 num_freqs * sizeof(A_UINT32); 19049 19050 buf = wmi_buf_alloc(wmi_handle, len); 19051 if (!buf) 19052 return QDF_STATUS_E_FAILURE; 19053 19054 buf_ptr = (uint8_t *)wmi_buf_data(buf); 19055 cmd = (wmi_get_channel_ani_cmd_fixed_param *)buf_ptr; 19056 WMITLV_SET_HDR(&cmd->tlv_header, 19057 WMITLV_TAG_STRUC_wmi_get_channel_ani_cmd_fixed_param, 19058 WMITLV_GET_STRUCT_TLVLEN( 19059 wmi_get_channel_ani_cmd_fixed_param)); 19060 19061 buf_ptr += sizeof(wmi_get_channel_ani_cmd_fixed_param); 19062 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, 19063 (num_freqs * sizeof(A_UINT32))); 19064 19065 chan_list = (A_UINT32 *)(buf_ptr + WMI_TLV_HDR_SIZE); 19066 for (i = 0; i < num_freqs; i++) { 19067 chan_list[i] = freqs[i]; 19068 wmi_debug("Requesting ANI for channel[%d]", chan_list[i]); 19069 } 19070 19071 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 19072 WMI_GET_CHANNEL_ANI_CMDID); 19073 19074 if (QDF_IS_STATUS_ERROR(ret)) { 19075 wmi_err("WMI_GET_CHANNEL_ANI_CMDID send error %d", ret); 19076 wmi_buf_free(buf); 19077 } 19078 19079 return ret; 19080 } 19081 19082 static QDF_STATUS extract_ani_level_tlv(uint8_t *evt_buf, 19083 struct wmi_host_ani_level_event **info, 19084 uint32_t *num_freqs) 19085 { 19086 WMI_GET_CHANNEL_ANI_EVENTID_param_tlvs *param_buf; 19087 wmi_get_channel_ani_event_fixed_param *fixed_param; 19088 wmi_channel_ani_info_tlv_param *tlv_params; 19089 uint8_t *buf_ptr, i; 19090 19091 param_buf = (WMI_GET_CHANNEL_ANI_EVENTID_param_tlvs *)evt_buf; 19092 if (!param_buf) { 19093 wmi_err("Invalid ani level event buffer"); 19094 return QDF_STATUS_E_INVAL; 19095 } 19096 19097 fixed_param = 19098 (wmi_get_channel_ani_event_fixed_param *)param_buf->fixed_param; 19099 if (!fixed_param) { 19100 wmi_err("Invalid fixed param"); 19101 return QDF_STATUS_E_INVAL; 19102 } 19103 19104 buf_ptr = (uint8_t *)fixed_param; 19105 buf_ptr += sizeof(wmi_get_channel_ani_event_fixed_param); 19106 buf_ptr += WMI_TLV_HDR_SIZE; 19107 19108 *num_freqs = param_buf->num_ani_info; 19109 if (*num_freqs > MAX_NUM_FREQS_FOR_ANI_LEVEL) { 19110 wmi_err("Invalid number of freqs received"); 19111 return QDF_STATUS_E_INVAL; 19112 } 19113 19114 *info = qdf_mem_malloc(*num_freqs * 19115 sizeof(struct wmi_host_ani_level_event)); 19116 if (!(*info)) 19117 return QDF_STATUS_E_NOMEM; 19118 19119 tlv_params = (wmi_channel_ani_info_tlv_param *)buf_ptr; 19120 for (i = 0; i < param_buf->num_ani_info; i++) { 19121 (*info)[i].ani_level = tlv_params->ani_level; 19122 (*info)[i].chan_freq = tlv_params->chan_freq; 19123 tlv_params++; 19124 } 19125 19126 return QDF_STATUS_SUCCESS; 19127 } 19128 #endif /* FEATURE_ANI_LEVEL_REQUEST */ 19129 19130 #ifdef WLAN_FEATURE_ROAM_OFFLOAD 19131 /** 19132 * convert_wtc_scan_mode() - Function to convert TLV specific 19133 * ROAM_TRIGGER_SCAN_MODE scan mode to unified Roam trigger scan mode enum 19134 * @scan_mode: scan freq scheme coming from firmware 19135 * 19136 * Return: ROAM_TRIGGER_SCAN_MODE 19137 */ 19138 static enum roam_scan_freq_scheme 19139 convert_wtc_scan_mode(WMI_ROAM_TRIGGER_SCAN_MODE scan_mode) 19140 { 19141 switch (scan_mode) { 19142 case ROAM_TRIGGER_SCAN_MODE_NO_SCAN_DISCONNECTION: 19143 return ROAM_SCAN_FREQ_SCHEME_NO_SCAN; 19144 case ROAM_TRIGGER_SCAN_MODE_PARTIAL: 19145 return ROAM_SCAN_FREQ_SCHEME_PARTIAL_SCAN; 19146 case ROAM_TRIGGER_SCAN_MODE_FULL: 19147 return ROAM_SCAN_FREQ_SCHEME_FULL_SCAN; 19148 default: 19149 return ROAM_SCAN_FREQ_SCHEME_NONE; 19150 } 19151 } 19152 19153 static uint32_t wmi_convert_fw_to_cm_trig_reason(uint32_t fw_trig_reason) 19154 { 19155 switch (fw_trig_reason) { 19156 case WMI_ROAM_TRIGGER_REASON_NONE: 19157 return ROAM_TRIGGER_REASON_NONE; 19158 case WMI_ROAM_TRIGGER_REASON_PER: 19159 return ROAM_TRIGGER_REASON_PER; 19160 case WMI_ROAM_TRIGGER_REASON_BMISS: 19161 return ROAM_TRIGGER_REASON_BMISS; 19162 case WMI_ROAM_TRIGGER_REASON_LOW_RSSI: 19163 return ROAM_TRIGGER_REASON_LOW_RSSI; 19164 case WMI_ROAM_TRIGGER_REASON_HIGH_RSSI: 19165 return ROAM_TRIGGER_REASON_HIGH_RSSI; 19166 case WMI_ROAM_TRIGGER_REASON_PERIODIC: 19167 return ROAM_TRIGGER_REASON_PERIODIC; 19168 case WMI_ROAM_TRIGGER_REASON_MAWC: 19169 return ROAM_TRIGGER_REASON_MAWC; 19170 case WMI_ROAM_TRIGGER_REASON_DENSE: 19171 return ROAM_TRIGGER_REASON_DENSE; 19172 case WMI_ROAM_TRIGGER_REASON_BACKGROUND: 19173 return ROAM_TRIGGER_REASON_BACKGROUND; 19174 case WMI_ROAM_TRIGGER_REASON_FORCED: 19175 return ROAM_TRIGGER_REASON_FORCED; 19176 case WMI_ROAM_TRIGGER_REASON_BTM: 19177 return ROAM_TRIGGER_REASON_BTM; 19178 case WMI_ROAM_TRIGGER_REASON_UNIT_TEST: 19179 return ROAM_TRIGGER_REASON_UNIT_TEST; 19180 case WMI_ROAM_TRIGGER_REASON_BSS_LOAD: 19181 return ROAM_TRIGGER_REASON_BSS_LOAD; 19182 case WMI_ROAM_TRIGGER_REASON_DEAUTH: 19183 return ROAM_TRIGGER_REASON_DEAUTH; 19184 case WMI_ROAM_TRIGGER_REASON_IDLE: 19185 return ROAM_TRIGGER_REASON_IDLE; 19186 case WMI_ROAM_TRIGGER_REASON_STA_KICKOUT: 19187 return ROAM_TRIGGER_REASON_STA_KICKOUT; 19188 case WMI_ROAM_TRIGGER_REASON_ESS_RSSI: 19189 return ROAM_TRIGGER_REASON_ESS_RSSI; 19190 case WMI_ROAM_TRIGGER_REASON_WTC_BTM: 19191 return ROAM_TRIGGER_REASON_WTC_BTM; 19192 case WMI_ROAM_TRIGGER_REASON_PMK_TIMEOUT: 19193 return ROAM_TRIGGER_REASON_PMK_TIMEOUT; 19194 case WMI_ROAM_TRIGGER_REASON_BTC: 19195 return ROAM_TRIGGER_REASON_BTC; 19196 case WMI_ROAM_TRIGGER_EXT_REASON_MAX: 19197 return ROAM_TRIGGER_REASON_MAX; 19198 default: 19199 return ROAM_TRIGGER_REASON_NONE; 19200 } 19201 } 19202 19203 /** 19204 * extract_roam_11kv_candidate_info - Extract btm candidate info 19205 * @wmi_handle: wmi_handle 19206 * @evt_buf: Event buffer 19207 * @dst_info: Destination buffer 19208 * @btm_idx: BTM index 19209 * @num_cand: Number of candidates 19210 * 19211 * Return: QDF_STATUS 19212 */ 19213 static QDF_STATUS 19214 extract_roam_11kv_candidate_info(wmi_unified_t wmi_handle, void *evt_buf, 19215 struct wmi_btm_req_candidate_info *dst_info, 19216 uint8_t btm_idx, uint16_t num_cand) 19217 { 19218 WMI_ROAM_STATS_EVENTID_param_tlvs *param_buf; 19219 wmi_roam_btm_request_candidate_info *src_data; 19220 uint8_t i; 19221 19222 param_buf = (WMI_ROAM_STATS_EVENTID_param_tlvs *)evt_buf; 19223 if (!param_buf || !param_buf->roam_btm_request_candidate_info || 19224 !param_buf->num_roam_btm_request_candidate_info || 19225 (btm_idx + 19226 num_cand) > param_buf->num_roam_btm_request_candidate_info) 19227 return QDF_STATUS_SUCCESS; 19228 19229 src_data = ¶m_buf->roam_btm_request_candidate_info[btm_idx]; 19230 if (num_cand > WLAN_MAX_BTM_CANDIDATE) 19231 num_cand = WLAN_MAX_BTM_CANDIDATE; 19232 for (i = 0; i < num_cand; i++) { 19233 WMI_MAC_ADDR_TO_CHAR_ARRAY(&src_data->btm_candidate_bssid, 19234 dst_info->candidate_bssid.bytes); 19235 dst_info->preference = src_data->preference; 19236 src_data++; 19237 dst_info++; 19238 } 19239 19240 return QDF_STATUS_SUCCESS; 19241 } 19242 19243 static enum roam_trigger_sub_reason 19244 wmi_convert_roam_sub_reason(WMI_ROAM_TRIGGER_SUB_REASON_ID subreason) 19245 { 19246 switch (subreason) { 19247 case WMI_ROAM_TRIGGER_SUB_REASON_PERIODIC_TIMER: 19248 return ROAM_TRIGGER_SUB_REASON_PERIODIC_TIMER; 19249 case WMI_ROAM_TRIGGER_SUB_REASON_INACTIVITY_TIMER: 19250 return ROAM_TRIGGER_SUB_REASON_INACTIVITY_TIMER_LOW_RSSI; 19251 case WMI_ROAM_TRIGGER_SUB_REASON_BTM_DI_TIMER: 19252 return ROAM_TRIGGER_SUB_REASON_BTM_DI_TIMER; 19253 case WMI_ROAM_TRIGGER_SUB_REASON_FULL_SCAN: 19254 return ROAM_TRIGGER_SUB_REASON_FULL_SCAN; 19255 case WMI_ROAM_TRIGGER_SUB_REASON_LOW_RSSI_PERIODIC: 19256 return ROAM_TRIGGER_SUB_REASON_LOW_RSSI_PERIODIC; 19257 case WMI_ROAM_TRIGGER_SUB_REASON_CU_PERIODIC: 19258 return ROAM_TRIGGER_SUB_REASON_CU_PERIODIC; 19259 case WMI_ROAM_TRIGGER_SUB_REASON_PERIODIC_TIMER_AFTER_INACTIVITY: 19260 return ROAM_TRIGGER_SUB_REASON_PERIODIC_TIMER_AFTER_INACTIVITY; 19261 case WMI_ROAM_TRIGGER_SUB_REASON_PERIODIC_TIMER_AFTER_INACTIVITY_CU: 19262 return ROAM_TRIGGER_SUB_REASON_PERIODIC_TIMER_AFTER_INACTIVITY_CU; 19263 case WMI_ROAM_TRIGGER_SUB_REASON_INACTIVITY_TIMER_CU: 19264 return ROAM_TRIGGER_SUB_REASON_INACTIVITY_TIMER_CU; 19265 default: 19266 break; 19267 } 19268 19269 return 0; 19270 } 19271 19272 /** 19273 * wlan_roam_fail_reason_code() - Convert FW enum to Host enum 19274 * @wmi_roam_fail_reason: roam fail enum 19275 * 19276 * Return: Roaming failure reason codes 19277 */ 19278 static enum wlan_roam_failure_reason_code 19279 wlan_roam_fail_reason_code(uint16_t wmi_roam_fail_reason) 19280 { 19281 switch (wmi_roam_fail_reason) { 19282 case WMI_ROAM_FAIL_REASON_NO_SCAN_START: 19283 return ROAM_FAIL_REASON_NO_SCAN_START; 19284 case WMI_ROAM_FAIL_REASON_NO_AP_FOUND: 19285 return ROAM_FAIL_REASON_NO_AP_FOUND; 19286 case WMI_ROAM_FAIL_REASON_NO_CAND_AP_FOUND: 19287 return ROAM_FAIL_REASON_NO_CAND_AP_FOUND; 19288 case WMI_ROAM_FAIL_REASON_HOST: 19289 return ROAM_FAIL_REASON_HOST; 19290 case WMI_ROAM_FAIL_REASON_AUTH_SEND: 19291 return ROAM_FAIL_REASON_AUTH_SEND; 19292 case WMI_ROAM_FAIL_REASON_AUTH_RECV: 19293 return ROAM_FAIL_REASON_AUTH_RECV; 19294 case WMI_ROAM_FAIL_REASON_NO_AUTH_RESP: 19295 return ROAM_FAIL_REASON_NO_AUTH_RESP; 19296 case WMI_ROAM_FAIL_REASON_REASSOC_SEND: 19297 return ROAM_FAIL_REASON_REASSOC_SEND; 19298 case WMI_ROAM_FAIL_REASON_REASSOC_RECV: 19299 return ROAM_FAIL_REASON_REASSOC_RECV; 19300 case WMI_ROAM_FAIL_REASON_NO_REASSOC_RESP: 19301 return ROAM_FAIL_REASON_NO_REASSOC_RESP; 19302 case WMI_ROAM_FAIL_REASON_EAPOL_TIMEOUT: 19303 return ROAM_FAIL_REASON_EAPOL_TIMEOUT; 19304 case WMI_ROAM_FAIL_REASON_MLME: 19305 return ROAM_FAIL_REASON_MLME; 19306 case WMI_ROAM_FAIL_REASON_INTERNAL_ABORT: 19307 return ROAM_FAIL_REASON_INTERNAL_ABORT; 19308 case WMI_ROAM_FAIL_REASON_SCAN_START: 19309 return ROAM_FAIL_REASON_SCAN_START; 19310 case WMI_ROAM_FAIL_REASON_AUTH_NO_ACK: 19311 return ROAM_FAIL_REASON_AUTH_NO_ACK; 19312 case WMI_ROAM_FAIL_REASON_AUTH_INTERNAL_DROP: 19313 return ROAM_FAIL_REASON_AUTH_INTERNAL_DROP; 19314 case WMI_ROAM_FAIL_REASON_REASSOC_NO_ACK: 19315 return ROAM_FAIL_REASON_REASSOC_NO_ACK; 19316 case WMI_ROAM_FAIL_REASON_REASSOC_INTERNAL_DROP: 19317 return ROAM_FAIL_REASON_REASSOC_INTERNAL_DROP; 19318 case WMI_ROAM_FAIL_REASON_EAPOL_M2_SEND: 19319 return ROAM_FAIL_REASON_EAPOL_M2_SEND; 19320 case WMI_ROAM_FAIL_REASON_EAPOL_M2_INTERNAL_DROP: 19321 return ROAM_FAIL_REASON_EAPOL_M2_INTERNAL_DROP; 19322 case WMI_ROAM_FAIL_REASON_EAPOL_M2_NO_ACK: 19323 return ROAM_FAIL_REASON_EAPOL_M2_NO_ACK; 19324 case WMI_ROAM_FAIL_REASON_EAPOL_M3_TIMEOUT: 19325 return ROAM_FAIL_REASON_EAPOL_M3_TIMEOUT; 19326 case WMI_ROAM_FAIL_REASON_EAPOL_M4_SEND: 19327 return ROAM_FAIL_REASON_EAPOL_M4_SEND; 19328 case WMI_ROAM_FAIL_REASON_EAPOL_M4_INTERNAL_DROP: 19329 return ROAM_FAIL_REASON_EAPOL_M4_INTERNAL_DROP; 19330 case WMI_ROAM_FAIL_REASON_EAPOL_M4_NO_ACK: 19331 return ROAM_FAIL_REASON_EAPOL_M4_NO_ACK; 19332 case WMI_ROAM_FAIL_REASON_NO_SCAN_FOR_FINAL_BMISS: 19333 return ROAM_FAIL_REASON_NO_SCAN_FOR_FINAL_BMISS; 19334 case WMI_ROAM_FAIL_REASON_DISCONNECT: 19335 return ROAM_FAIL_REASON_DISCONNECT; 19336 case WMI_ROAM_FAIL_REASON_SYNC: 19337 return ROAM_FAIL_REASON_SYNC; 19338 case WMI_ROAM_FAIL_REASON_SAE_INVALID_PMKID: 19339 return ROAM_FAIL_REASON_SAE_INVALID_PMKID; 19340 case WMI_ROAM_FAIL_REASON_SAE_PREAUTH_TIMEOUT: 19341 return ROAM_FAIL_REASON_SAE_PREAUTH_TIMEOUT; 19342 case WMI_ROAM_FAIL_REASON_SAE_PREAUTH_FAIL: 19343 return ROAM_FAIL_REASON_SAE_PREAUTH_FAIL; 19344 case WMI_ROAM_FAIL_REASON_UNABLE_TO_START_ROAM_HO: 19345 return ROAM_FAIL_REASON_UNABLE_TO_START_ROAM_HO; 19346 case WMI_ROAM_FAIL_REASON_NO_AP_FOUND_AND_FINAL_BMISS_SENT: 19347 return ROAM_FAIL_REASON_NO_AP_FOUND_AND_FINAL_BMISS_SENT; 19348 case WMI_ROAM_FAIL_REASON_NO_CAND_AP_FOUND_AND_FINAL_BMISS_SENT: 19349 return ROAM_FAIL_REASON_NO_CAND_AP_FOUND_AND_FINAL_BMISS_SENT; 19350 case WMI_ROAM_FAIL_REASON_CURR_AP_STILL_OK: 19351 return ROAM_FAIL_REASON_CURR_AP_STILL_OK; 19352 default: 19353 return ROAM_FAIL_REASON_UNKNOWN; 19354 } 19355 } 19356 19357 /** 19358 * wmi_convert_to_cm_roam_invoke_reason() - Convert FW enum to Host enum 19359 * @reason: roam invoke reason from fw 19360 * 19361 * Return: Roam invoke reason code defined in host driver 19362 */ 19363 static enum roam_invoke_reason 19364 wmi_convert_to_cm_roam_invoke_reason(enum wlan_roam_invoke_reason reason) 19365 { 19366 switch (reason) { 19367 case ROAM_INVOKE_REASON_UNDEFINED: 19368 return WLAN_ROAM_STATS_INVOKE_REASON_UNDEFINED; 19369 case ROAM_INVOKE_REASON_NUD_FAILURE: 19370 return WLAN_ROAM_STATS_INVOKE_REASON_NUD_FAILURE; 19371 case ROAM_INVOKE_REASON_USER_SPACE: 19372 return WLAN_ROAM_STATS_INVOKE_REASON_USER_SPACE; 19373 default: 19374 return WLAN_ROAM_STATS_INVOKE_REASON_UNDEFINED; 19375 } 19376 } 19377 19378 /** 19379 * wmi_convert_to_cm_roam_tx_fail_reason() - Convert FW enum to Host enum 19380 * @tx_fail_reason: roam tx fail reason from fw 19381 * 19382 * Return: Roam tx fail reason code defined in host driver 19383 */ 19384 static enum roam_tx_failures_reason 19385 wmi_convert_to_cm_roam_tx_fail_reason(PEER_KICKOUT_REASON tx_fail_reason) 19386 { 19387 switch (tx_fail_reason) { 19388 case WMI_PEER_STA_KICKOUT_REASON_UNSPECIFIED: 19389 return WLAN_ROAM_STATS_KICKOUT_REASON_UNSPECIFIED; 19390 case WMI_PEER_STA_KICKOUT_REASON_XRETRY: 19391 return WLAN_ROAM_STATS_KICKOUT_REASON_XRETRY; 19392 case WMI_PEER_STA_KICKOUT_REASON_INACTIVITY: 19393 return WLAN_ROAM_STATS_KICKOUT_REASON_INACTIVITY; 19394 case WMI_PEER_STA_KICKOUT_REASON_IBSS_DISCONNECT: 19395 return WLAN_ROAM_STATS_KICKOUT_REASON_IBSS_DISCONNECT; 19396 case WMI_PEER_STA_KICKOUT_REASON_TDLS_DISCONNECT: 19397 return WLAN_ROAM_STATS_KICKOUT_REASON_TDLS_DISCONNECT; 19398 case WMI_PEER_STA_KICKOUT_REASON_SA_QUERY_TIMEOUT: 19399 return WLAN_ROAM_STATS_KICKOUT_REASON_SA_QUERY_TIMEOUT; 19400 case WMI_PEER_STA_KICKOUT_REASON_ROAMING_EVENT: 19401 return WLAN_ROAM_STATS_KICKOUT_REASON_ROAMING_EVENT; 19402 default: 19403 return WLAN_ROAM_STATS_KICKOUT_REASON_UNSPECIFIED; 19404 } 19405 } 19406 19407 /** 19408 * wmi_convert_roam_abort_reason() - Convert FW enum to Host enum 19409 * @abort_reason: roam abort reason from fw 19410 * 19411 * Return: Roam abort reason code defined in host driver 19412 */ 19413 static enum roam_abort_reason 19414 wmi_convert_roam_abort_reason(WMI_ROAM_FAIL_SUB_REASON_ID abort_reason) 19415 { 19416 switch (abort_reason) { 19417 case WMI_ROAM_ABORT_UNSPECIFIED: 19418 return WLAN_ROAM_STATS_ABORT_UNSPECIFIED; 19419 case WMI_ROAM_ABORT_LOWRSSI_DATA_RSSI_HIGH: 19420 return WLAN_ROAM_STATS_ABORT_LOWRSSI_DATA_RSSI_HIGH; 19421 case WMI_ROAM_ABORT_LOWRSSI_LINK_SPEED_GOOD: 19422 return WLAN_ROAM_STATS_ABORT_LOWRSSI_LINK_SPEED_GOOD; 19423 case WMI_ROAM_ABORT_BG_DATA_RSSI_HIGH: 19424 return WLAN_ROAM_STATS_ABORT_BG_DATA_RSSI_HIGH; 19425 case WMI_ROAM_ABORT_BG_RSSI_ABOVE_THRESHOLD: 19426 return WLAN_ROAM_STATS_ABORT_BG_RSSI_ABOVE_THRESHOLD; 19427 default: 19428 return WLAN_ROAM_STATS_ABORT_UNSPECIFIED; 19429 } 19430 } 19431 19432 /** 19433 * wlan_roam_scan_type() - Convert FW enum to Host enum 19434 * @scan_type: roam scan type from fw 19435 * 19436 * Return: Roam scan type defined in host driver 19437 */ 19438 static enum roam_stats_scan_type 19439 wlan_roam_scan_type(uint32_t scan_type) 19440 { 19441 switch (scan_type) { 19442 case 0: 19443 return ROAM_STATS_SCAN_TYPE_PARTIAL; 19444 case 1: 19445 return ROAM_STATS_SCAN_TYPE_FULL; 19446 case 2: 19447 return ROAM_STATS_SCAN_TYPE_NO_SCAN; 19448 case 3: 19449 return ROAM_STATS_SCAN_TYPE_HIGHER_BAND_5GHZ_6GHZ; 19450 case 4: 19451 return ROAM_STATS_SCAN_TYPE_HIGHER_BAND_6GHZ; 19452 default: 19453 return ROAM_STATS_SCAN_TYPE_PARTIAL; 19454 } 19455 } 19456 19457 /** 19458 * wlan_roam_dwell_type() - Convert FW enum to Host enum 19459 * @dwell_type: roam channel scan dwell type from fw 19460 * 19461 * Return: Roam channel scan dwell type defined in host driver 19462 */ 19463 static enum roam_scan_dwell_type 19464 wlan_roam_dwell_type(uint32_t dwell_type) 19465 { 19466 switch (dwell_type) { 19467 case 0: 19468 return WLAN_ROAM_DWELL_TYPE_UNSPECIFIED; 19469 case 1: 19470 return WLAN_ROAM_DWELL_ACTIVE_TYPE; 19471 case 2: 19472 return WLAN_ROAM_DWELL_PASSIVE_TYPE; 19473 default: 19474 return WLAN_ROAM_DWELL_TYPE_UNSPECIFIED; 19475 } 19476 } 19477 19478 #define WLAN_ROAM_PER_TX_RATE_OFFSET 0 19479 #define WLAN_ROAM_PER_RX_RATE_OFFSET 16 19480 #define WLAN_ROAM_BMISS_FINNAL_OFFSET 0 19481 #define WLAN_ROAM_BMISS_CONSECUTIVE_OFFSET 7 19482 #define WLAN_ROAM_BMISS_QOSNULL_OFFSET 24 19483 #define WLAN_ROAM_DENSE_ROAMABLE_OFFSET 0 19484 19485 /** 19486 * extract_roam_trigger_stats_tlv() - Extract the Roam trigger stats 19487 * from the WMI_ROAM_STATS_EVENTID 19488 * @wmi_handle: wmi handle 19489 * @evt_buf: Pointer to the event buffer 19490 * @trig: Pointer to destination structure to fill data 19491 * @idx: TLV id 19492 * @btm_idx: BTM index 19493 */ 19494 static QDF_STATUS 19495 extract_roam_trigger_stats_tlv(wmi_unified_t wmi_handle, void *evt_buf, 19496 struct wmi_roam_trigger_info *trig, uint8_t idx, 19497 uint8_t btm_idx) 19498 { 19499 WMI_ROAM_STATS_EVENTID_param_tlvs *param_buf; 19500 wmi_roam_trigger_reason *src_data = NULL; 19501 uint32_t trig_reason = 0; 19502 uint32_t fail_reason = 0; 19503 uint32_t abort = 0; 19504 uint32_t invoke = 0; 19505 uint32_t tx_fail = 0; 19506 wmi_roam_trigger_reason_cmm *cmn_data = NULL; 19507 wmi_roam_trigger_per *per_data = NULL; 19508 wmi_roam_trigger_bmiss *bmiss_data = NULL; 19509 wmi_roam_trigger_hi_rssi *hi_rssi_data = NULL; 19510 wmi_roam_trigger_dense *dense_data = NULL; 19511 wmi_roam_trigger_force *force_data = NULL; 19512 wmi_roam_trigger_btm *btm_data = NULL; 19513 wmi_roam_trigger_bss_load *bss_load_data = NULL; 19514 wmi_roam_trigger_deauth *deauth_data = NULL; 19515 wmi_roam_trigger_periodic *periodic_data = NULL; 19516 wmi_roam_trigger_rssi *rssi_data = NULL; 19517 wmi_roam_trigger_kickout *kickout_data = NULL; 19518 wmi_roam_result *roam_result = NULL; 19519 wmi_roam_scan_info *scan_info = NULL; 19520 19521 param_buf = (WMI_ROAM_STATS_EVENTID_param_tlvs *)evt_buf; 19522 if (!param_buf) { 19523 wmi_err("Param buf is NULL"); 19524 return QDF_STATUS_E_FAILURE; 19525 } 19526 19527 if (!param_buf->roam_result || idx >= param_buf->num_roam_result) 19528 wmi_err("roam_result or idx error.%u", idx); 19529 19530 if (!param_buf->roam_scan_info || idx >= param_buf->num_roam_scan_info) 19531 wmi_err("roam_scan_info or idx error.%u", idx); 19532 19533 trig->present = true; 19534 19535 if (param_buf->roam_scan_info) 19536 scan_info = ¶m_buf->roam_scan_info[idx]; 19537 19538 if (param_buf->roam_trigger_reason_cmm) 19539 cmn_data = ¶m_buf->roam_trigger_reason_cmm[idx]; 19540 19541 if (param_buf->roam_trigger_reason) 19542 src_data = ¶m_buf->roam_trigger_reason[idx]; 19543 19544 if (cmn_data) { 19545 trig_reason = cmn_data->trigger_reason; 19546 trig->trigger_reason = 19547 wmi_convert_fw_to_cm_trig_reason(trig_reason); 19548 trig->trigger_sub_reason = 19549 wmi_convert_roam_sub_reason(cmn_data->trigger_sub_reason); 19550 trig->timestamp = cmn_data->timestamp; 19551 trig->common_roam = true; 19552 } else if (src_data) { 19553 trig_reason = src_data->trigger_reason; 19554 trig->trigger_reason = 19555 wmi_convert_fw_to_cm_trig_reason(trig_reason); 19556 trig->trigger_sub_reason = 19557 wmi_convert_roam_sub_reason(src_data->trigger_sub_reason); 19558 trig->current_rssi = src_data->current_rssi; 19559 trig->timestamp = src_data->timestamp; 19560 trig->common_roam = false; 19561 } 19562 19563 if (param_buf->roam_trigger_rssi) 19564 rssi_data = ¶m_buf->roam_trigger_rssi[idx]; 19565 19566 if (param_buf->roam_result) { 19567 roam_result = ¶m_buf->roam_result[idx]; 19568 19569 if (roam_result) { 19570 trig->roam_status = roam_result->roam_status; 19571 if (trig->roam_status) { 19572 fail_reason = roam_result->roam_fail_reason; 19573 trig->fail_reason = 19574 wlan_roam_fail_reason_code(fail_reason); 19575 19576 if (rssi_data) { 19577 abort = roam_result->roam_abort_reason; 19578 trig->abort_reason.abort_reason_code = 19579 wmi_convert_roam_abort_reason(abort); 19580 trig->abort_reason.data_rssi = 19581 rssi_data->data_rssi; 19582 trig->abort_reason.data_rssi_threshold = 19583 rssi_data->data_rssi_threshold; 19584 trig->abort_reason.rx_linkspeed_status = 19585 rssi_data->rx_linkspeed_status; 19586 } 19587 } 19588 } 19589 } 19590 19591 if (scan_info) 19592 trig->scan_type = 19593 wlan_roam_scan_type(scan_info->roam_scan_type); 19594 19595 switch (trig_reason) { 19596 case WMI_ROAM_TRIGGER_REASON_PER: 19597 if (param_buf->roam_trigger_per) 19598 per_data = ¶m_buf->roam_trigger_per[idx]; 19599 if (per_data) { 19600 trig->per_trig_data.tx_rate_thresh_percent = 19601 WMI_GET_BITS(per_data->rate_thresh_percnt, 19602 WLAN_ROAM_PER_RX_RATE_OFFSET, 8); 19603 trig->per_trig_data.rx_rate_thresh_percent = 19604 WMI_GET_BITS(per_data->rate_thresh_percnt, 19605 WLAN_ROAM_PER_TX_RATE_OFFSET, 8); 19606 } 19607 return QDF_STATUS_SUCCESS; 19608 19609 case WMI_ROAM_TRIGGER_REASON_BMISS: 19610 if (param_buf->roam_trigger_bmiss) 19611 bmiss_data = ¶m_buf->roam_trigger_bmiss[idx]; 19612 if (bmiss_data) { 19613 trig->bmiss_trig_data.final_bmiss_cnt = 19614 WMI_GET_BITS(bmiss_data->bmiss_status, 19615 WLAN_ROAM_BMISS_FINNAL_OFFSET, 7); 19616 trig->bmiss_trig_data.consecutive_bmiss_cnt = 19617 WMI_GET_BITS(bmiss_data->bmiss_status, 19618 WLAN_ROAM_BMISS_CONSECUTIVE_OFFSET, 19619 17); 19620 trig->bmiss_trig_data.qos_null_success = 19621 WMI_GET_BITS(bmiss_data->bmiss_status, 19622 WLAN_ROAM_BMISS_QOSNULL_OFFSET, 1); 19623 } 19624 return QDF_STATUS_SUCCESS; 19625 19626 case WMI_ROAM_TRIGGER_REASON_HIGH_RSSI: 19627 if (param_buf->roam_trigger_hi_rssi) 19628 hi_rssi_data = ¶m_buf->roam_trigger_hi_rssi[idx]; 19629 19630 if (hi_rssi_data && cmn_data) { 19631 trig->hi_rssi_trig_data.current_rssi = 19632 (uint8_t)cmn_data->current_rssi; 19633 trig->hi_rssi_trig_data.hirssi_threshold = 19634 (uint8_t)hi_rssi_data->hi_rssi_threshold; 19635 } 19636 return QDF_STATUS_SUCCESS; 19637 19638 case WMI_ROAM_TRIGGER_REASON_MAWC: 19639 case WMI_ROAM_TRIGGER_REASON_DENSE: 19640 if (param_buf->roam_trigger_dense) 19641 dense_data = ¶m_buf->roam_trigger_dense[idx]; 19642 if (dense_data) { 19643 trig->congestion_trig_data.rx_tput = 19644 dense_data->rx_tput; 19645 trig->congestion_trig_data.tx_tput = 19646 dense_data->tx_tput; 19647 trig->congestion_trig_data.roamable_count = 19648 WMI_GET_BITS(dense_data->dense_status, 19649 WLAN_ROAM_DENSE_ROAMABLE_OFFSET, 19650 8); 19651 } 19652 return QDF_STATUS_SUCCESS; 19653 19654 case WMI_ROAM_TRIGGER_REASON_BACKGROUND: 19655 if (cmn_data && rssi_data) { 19656 trig->background_trig_data.current_rssi = 19657 (uint8_t)cmn_data->current_rssi; 19658 trig->background_trig_data.data_rssi = 19659 (uint8_t)rssi_data->data_rssi; 19660 trig->background_trig_data.data_rssi_threshold = 19661 (uint8_t)rssi_data->data_rssi_threshold; 19662 } 19663 return QDF_STATUS_SUCCESS; 19664 19665 case WMI_ROAM_TRIGGER_REASON_IDLE: 19666 case WMI_ROAM_TRIGGER_REASON_FORCED: 19667 if (param_buf->roam_trigger_force) 19668 force_data = ¶m_buf->roam_trigger_force[idx]; 19669 if (force_data) { 19670 invoke = force_data->invoke_reason; 19671 trig->user_trig_data.invoke_reason = 19672 wmi_convert_to_cm_roam_invoke_reason(invoke); 19673 } 19674 return QDF_STATUS_SUCCESS; 19675 19676 case WMI_ROAM_TRIGGER_REASON_UNIT_TEST: 19677 case WMI_ROAM_TRIGGER_REASON_BTC: 19678 return QDF_STATUS_SUCCESS; 19679 19680 case WMI_ROAM_TRIGGER_REASON_BTM: 19681 if (param_buf->roam_trigger_btm) 19682 btm_data = ¶m_buf->roam_trigger_btm[idx]; 19683 if (btm_data) { 19684 trig->btm_trig_data.btm_request_mode = 19685 btm_data->btm_request_mode; 19686 trig->btm_trig_data.disassoc_timer = 19687 btm_data->disassoc_imminent_timer; 19688 trig->btm_trig_data.validity_interval = 19689 btm_data->validity_internal; 19690 trig->btm_trig_data.candidate_list_count = 19691 btm_data->candidate_list_count; 19692 trig->btm_trig_data.btm_resp_status = 19693 btm_data->btm_response_status_code; 19694 trig->btm_trig_data.btm_bss_termination_timeout = 19695 btm_data->btm_bss_termination_timeout; 19696 trig->btm_trig_data.btm_mbo_assoc_retry_timeout = 19697 btm_data->btm_mbo_assoc_retry_timeout; 19698 trig->btm_trig_data.token = 19699 (uint16_t)btm_data->btm_req_dialog_token; 19700 trig->btm_trig_data.band = 19701 WMI_GET_MLO_BAND(scan_info->flags); 19702 if (trig->btm_trig_data.band != WMI_MLO_BAND_NO_MLO) 19703 trig->btm_trig_data.is_mlo = true; 19704 } else if (src_data) { 19705 trig->btm_trig_data.btm_request_mode = 19706 src_data->btm_request_mode; 19707 trig->btm_trig_data.disassoc_timer = 19708 src_data->disassoc_imminent_timer; 19709 trig->btm_trig_data.validity_interval = 19710 src_data->validity_internal; 19711 trig->btm_trig_data.candidate_list_count = 19712 src_data->candidate_list_count; 19713 trig->btm_trig_data.btm_resp_status = 19714 src_data->btm_response_status_code; 19715 trig->btm_trig_data.btm_bss_termination_timeout = 19716 src_data->btm_bss_termination_timeout; 19717 trig->btm_trig_data.btm_mbo_assoc_retry_timeout = 19718 src_data->btm_mbo_assoc_retry_timeout; 19719 trig->btm_trig_data.token = 19720 src_data->btm_req_dialog_token; 19721 trig->btm_trig_data.band = 19722 WMI_GET_MLO_BAND(scan_info->flags); 19723 if (trig->btm_trig_data.band != WMI_MLO_BAND_NO_MLO) 19724 trig->btm_trig_data.is_mlo = true; 19725 if ((btm_idx + 19726 trig->btm_trig_data.candidate_list_count) <= 19727 param_buf->num_roam_btm_request_candidate_info) 19728 extract_roam_11kv_candidate_info( 19729 wmi_handle, evt_buf, 19730 trig->btm_trig_data.btm_cand, 19731 btm_idx, 19732 src_data->candidate_list_count); 19733 } 19734 19735 return QDF_STATUS_SUCCESS; 19736 19737 case WMI_ROAM_TRIGGER_REASON_BSS_LOAD: 19738 if (param_buf->roam_trigger_bss_load) 19739 bss_load_data = ¶m_buf->roam_trigger_bss_load[idx]; 19740 if (bss_load_data) 19741 trig->cu_trig_data.cu_load = bss_load_data->cu_load; 19742 else if (src_data) 19743 trig->cu_trig_data.cu_load = src_data->cu_load; 19744 return QDF_STATUS_SUCCESS; 19745 19746 case WMI_ROAM_TRIGGER_REASON_DEAUTH: 19747 if (param_buf->roam_trigger_deauth) 19748 deauth_data = ¶m_buf->roam_trigger_deauth[idx]; 19749 if (deauth_data) { 19750 trig->deauth_trig_data.type = deauth_data->deauth_type; 19751 trig->deauth_trig_data.reason = 19752 deauth_data->deauth_reason; 19753 } else if (src_data) { 19754 trig->deauth_trig_data.type = src_data->deauth_type; 19755 trig->deauth_trig_data.reason = src_data->deauth_reason; 19756 } 19757 return QDF_STATUS_SUCCESS; 19758 19759 case WMI_ROAM_TRIGGER_REASON_PERIODIC: 19760 if (param_buf->roam_trigger_periodic) 19761 periodic_data = ¶m_buf->roam_trigger_periodic[idx]; 19762 if (periodic_data) { 19763 trig->periodic_trig_data.periodic_timer_ms = 19764 periodic_data->periodic_timer_ms; 19765 } else if (src_data) 19766 trig->rssi_trig_data.threshold = 19767 src_data->roam_rssi_threshold; 19768 return QDF_STATUS_SUCCESS; 19769 19770 case WMI_ROAM_TRIGGER_REASON_LOW_RSSI: 19771 if (cmn_data && rssi_data) { 19772 trig->low_rssi_trig_data.current_rssi = 19773 (uint8_t)cmn_data->current_rssi; 19774 trig->low_rssi_trig_data.roam_rssi_threshold = 19775 (uint8_t)rssi_data->roam_rssi_threshold; 19776 trig->low_rssi_trig_data.rx_linkspeed_status = 19777 (uint8_t)rssi_data->rx_linkspeed_status; 19778 } else if (src_data) 19779 trig->rssi_trig_data.threshold = 19780 src_data->roam_rssi_threshold; 19781 19782 return QDF_STATUS_SUCCESS; 19783 19784 case WMI_ROAM_TRIGGER_REASON_STA_KICKOUT: 19785 if (param_buf->roam_trigger_kickout) 19786 kickout_data = ¶m_buf->roam_trigger_kickout[idx]; 19787 if (kickout_data) { 19788 tx_fail = kickout_data->kickout_reason; 19789 trig->tx_failures_trig_data.kickout_threshold = 19790 kickout_data->kickout_th; 19791 trig->tx_failures_trig_data.kickout_reason = 19792 wmi_convert_to_cm_roam_tx_fail_reason(tx_fail); 19793 } 19794 return QDF_STATUS_SUCCESS; 19795 19796 case WMI_ROAM_TRIGGER_REASON_WTC_BTM: 19797 if (src_data) { 19798 trig->wtc_btm_trig_data.roaming_mode = 19799 src_data->vendor_specific1[0]; 19800 trig->wtc_btm_trig_data.vsie_trigger_reason = 19801 src_data->vendor_specific1[1]; 19802 trig->wtc_btm_trig_data.sub_code = 19803 src_data->vendor_specific1[2]; 19804 trig->wtc_btm_trig_data.wtc_mode = 19805 src_data->vendor_specific1[3]; 19806 trig->wtc_btm_trig_data.wtc_scan_mode = 19807 convert_wtc_scan_mode(src_data->vendor_specific1[4]); 19808 trig->wtc_btm_trig_data.wtc_rssi_th = 19809 src_data->vendor_specific1[5]; 19810 trig->wtc_btm_trig_data.wtc_candi_rssi_th = 19811 src_data->vendor_specific1[6]; 19812 19813 trig->wtc_btm_trig_data.wtc_candi_rssi_ext_present = 19814 src_data->vendor_specific2[0]; 19815 trig->wtc_btm_trig_data.wtc_candi_rssi_th_5g = 19816 src_data->vendor_specific2[1]; 19817 trig->wtc_btm_trig_data.wtc_candi_rssi_th_6g = 19818 src_data->vendor_specific2[2]; 19819 trig->wtc_btm_trig_data.duration = 19820 src_data->vendor_specific2[3]; 19821 } 19822 return QDF_STATUS_SUCCESS; 19823 default: 19824 return QDF_STATUS_SUCCESS; 19825 } 19826 19827 return QDF_STATUS_SUCCESS; 19828 } 19829 19830 /** 19831 * extract_roam_scan_ap_stats_tlv() - Extract the Roam trigger stats 19832 * from the WMI_ROAM_STATS_EVENTID 19833 * @wmi_handle: wmi handle 19834 * @evt_buf: Pointer to the event buffer 19835 * @dst: Pointer to destination structure to fill data 19836 * @ap_idx: TLV index for this roam scan 19837 * @num_cand: number of candidates list in the roam scan 19838 */ 19839 static QDF_STATUS 19840 extract_roam_scan_ap_stats_tlv(wmi_unified_t wmi_handle, void *evt_buf, 19841 struct wmi_roam_candidate_info *dst, 19842 uint8_t ap_idx, uint16_t num_cand) 19843 { 19844 WMI_ROAM_STATS_EVENTID_param_tlvs *param_buf; 19845 wmi_roam_ap_info *src = NULL; 19846 uint8_t i; 19847 19848 param_buf = (WMI_ROAM_STATS_EVENTID_param_tlvs *)evt_buf; 19849 if (!param_buf) { 19850 wmi_err("Param buf is NULL"); 19851 return QDF_STATUS_E_FAILURE; 19852 } 19853 19854 if (ap_idx >= param_buf->num_roam_ap_info) { 19855 wmi_err("Invalid roam scan AP tlv ap_idx:%d total_ap:%d", 19856 ap_idx, param_buf->num_roam_ap_info); 19857 return QDF_STATUS_E_FAILURE; 19858 } 19859 19860 src = ¶m_buf->roam_ap_info[ap_idx]; 19861 19862 for (i = 0; i < num_cand; i++) { 19863 WMI_MAC_ADDR_TO_CHAR_ARRAY(&src->bssid, dst->bssid.bytes); 19864 dst->type = src->candidate_type; 19865 dst->freq = src->channel; 19866 dst->etp = src->etp; 19867 dst->rssi = src->rssi; 19868 dst->rssi_score = src->rssi_score; 19869 dst->cu_load = src->cu_load; 19870 dst->cu_score = src->cu_score; 19871 dst->total_score = src->total_score; 19872 dst->timestamp = src->timestamp; 19873 dst->dl_reason = src->bl_reason; 19874 dst->dl_source = src->bl_source; 19875 dst->dl_timestamp = src->bl_timestamp; 19876 dst->dl_original_timeout = src->bl_original_timeout; 19877 dst->is_mlo = WMI_GET_AP_INFO_MLO_STATUS(src->flags); 19878 19879 src++; 19880 dst++; 19881 } 19882 19883 return QDF_STATUS_SUCCESS; 19884 } 19885 19886 /** 19887 * extract_roam_scan_stats_tlv() - Extract the Roam trigger stats 19888 * from the WMI_ROAM_STATS_EVENTID 19889 * @wmi_handle: wmi handle 19890 * @evt_buf: Pointer to the event buffer 19891 * @dst: Pointer to destination structure to fill data 19892 * @idx: TLV id 19893 * @chan_idx: Index of the channel tlv for the current roam trigger 19894 * @ap_idx: Index of the candidate AP TLV for the current roam trigger 19895 */ 19896 static QDF_STATUS 19897 extract_roam_scan_stats_tlv(wmi_unified_t wmi_handle, void *evt_buf, 19898 struct wmi_roam_scan_data *dst, uint8_t idx, 19899 uint8_t chan_idx, uint8_t ap_idx) 19900 { 19901 WMI_ROAM_STATS_EVENTID_param_tlvs *param_buf; 19902 wmi_roam_scan_info *src_data = NULL; 19903 wmi_roam_scan_channel_info *src_chan = NULL; 19904 QDF_STATUS status; 19905 uint8_t i; 19906 19907 param_buf = (WMI_ROAM_STATS_EVENTID_param_tlvs *)evt_buf; 19908 if (!param_buf || !param_buf->roam_scan_info || 19909 idx >= param_buf->num_roam_scan_info) 19910 return QDF_STATUS_E_FAILURE; 19911 19912 src_data = ¶m_buf->roam_scan_info[idx]; 19913 19914 dst->present = true; 19915 dst->type = src_data->roam_scan_type; 19916 dst->num_chan = src_data->roam_scan_channel_count; 19917 dst->scan_complete_timestamp = src_data->scan_complete_timestamp; 19918 dst->next_rssi_threshold = src_data->next_rssi_trigger_threshold; 19919 dst->is_btcoex_active = WMI_GET_BTCONNECT_STATUS(src_data->flags); 19920 dst->frame_info_count = src_data->frame_info_count; 19921 if (dst->frame_info_count > WLAN_ROAM_MAX_FRAME_INFO) 19922 dst->frame_info_count = WLAN_ROAM_MAX_FRAME_INFO; 19923 19924 dst->band = WMI_GET_MLO_BAND(src_data->flags); 19925 if (dst->band != WMI_MLO_BAND_NO_MLO) 19926 dst->is_mlo = true; 19927 19928 /* Read the channel data only for dst->type is 0 (partial scan) */ 19929 if (dst->num_chan && !dst->type && param_buf->num_roam_scan_chan_info && 19930 chan_idx < param_buf->num_roam_scan_chan_info) { 19931 if (dst->num_chan > MAX_ROAM_SCAN_CHAN) 19932 dst->num_chan = MAX_ROAM_SCAN_CHAN; 19933 19934 src_chan = ¶m_buf->roam_scan_chan_info[chan_idx]; 19935 19936 if ((dst->num_chan + chan_idx) > 19937 param_buf->num_roam_scan_chan_info) { 19938 wmi_err("Invalid TLV. num_chan %d chan_idx %d num_roam_scan_chan_info %d", 19939 dst->num_chan, chan_idx, 19940 param_buf->num_roam_scan_chan_info); 19941 return QDF_STATUS_SUCCESS; 19942 } 19943 19944 for (i = 0; i < dst->num_chan; i++) { 19945 dst->chan_freq[i] = src_chan->channel; 19946 dst->dwell_type[i] = 19947 (uint8_t)wlan_roam_dwell_type(src_chan->ch_dwell_type); 19948 src_chan++; 19949 } 19950 } 19951 19952 if (!src_data->roam_ap_count || !param_buf->num_roam_ap_info) 19953 return QDF_STATUS_SUCCESS; 19954 19955 dst->num_ap = src_data->roam_ap_count; 19956 if (dst->num_ap > MAX_ROAM_CANDIDATE_AP) 19957 dst->num_ap = MAX_ROAM_CANDIDATE_AP; 19958 19959 status = extract_roam_scan_ap_stats_tlv(wmi_handle, evt_buf, dst->ap, 19960 ap_idx, dst->num_ap); 19961 if (QDF_IS_STATUS_ERROR(status)) { 19962 wmi_err("Extract candidate stats for tlv[%d] failed", idx); 19963 return status; 19964 } 19965 19966 return QDF_STATUS_SUCCESS; 19967 } 19968 19969 /** 19970 * extract_roam_result_stats_tlv() - Extract the Roam trigger stats 19971 * from the WMI_ROAM_STATS_EVENTID 19972 * @wmi_handle: wmi handle 19973 * @evt_buf: Pointer to the event buffer 19974 * @dst: Pointer to destination structure to fill data 19975 * @idx: TLV id 19976 */ 19977 static QDF_STATUS 19978 extract_roam_result_stats_tlv(wmi_unified_t wmi_handle, void *evt_buf, 19979 struct wmi_roam_result *dst, uint8_t idx) 19980 { 19981 WMI_ROAM_STATS_EVENTID_param_tlvs *param_buf; 19982 wmi_roam_result *src_data = NULL; 19983 19984 param_buf = (WMI_ROAM_STATS_EVENTID_param_tlvs *)evt_buf; 19985 if (!param_buf || !param_buf->roam_result || 19986 idx >= param_buf->num_roam_result) 19987 return QDF_STATUS_E_FAILURE; 19988 19989 src_data = ¶m_buf->roam_result[idx]; 19990 19991 dst->present = true; 19992 dst->status = src_data->roam_status; 19993 dst->timestamp = src_data->timestamp; 19994 dst->fail_reason = 19995 wlan_roam_fail_reason_code(src_data->roam_fail_reason); 19996 WMI_MAC_ADDR_TO_CHAR_ARRAY(&src_data->bssid, dst->fail_bssid.bytes); 19997 19998 return QDF_STATUS_SUCCESS; 19999 } 20000 20001 /** 20002 * extract_roam_11kv_stats_tlv() - Extract the Roam trigger stats 20003 * from the WMI_ROAM_STATS_EVENTID 20004 * @wmi_handle: wmi handle 20005 * @evt_buf: Pointer to the event buffer 20006 * @dst: Pointer to destination structure to fill data 20007 * @idx: TLV id 20008 * @rpt_idx: Neighbor report Channel index 20009 * @band: Band of the link on which packet is transmitted or received 20010 */ 20011 static QDF_STATUS 20012 extract_roam_11kv_stats_tlv(wmi_unified_t wmi_handle, void *evt_buf, 20013 struct wmi_neighbor_report_data *dst, 20014 uint8_t idx, uint8_t rpt_idx, uint8_t band) 20015 { 20016 WMI_ROAM_STATS_EVENTID_param_tlvs *param_buf; 20017 wmi_roam_neighbor_report_info *src_data = NULL; 20018 wmi_roam_neighbor_report_channel_info *src_freq = NULL; 20019 uint8_t i; 20020 20021 param_buf = (WMI_ROAM_STATS_EVENTID_param_tlvs *)evt_buf; 20022 if (!param_buf || !param_buf->roam_neighbor_report_info || 20023 !param_buf->num_roam_neighbor_report_info || 20024 idx >= param_buf->num_roam_neighbor_report_info) { 20025 wmi_debug("Invalid 1kv param buf"); 20026 return QDF_STATUS_E_FAILURE; 20027 } 20028 20029 src_data = ¶m_buf->roam_neighbor_report_info[idx]; 20030 20031 dst->present = true; 20032 dst->req_type = src_data->request_type; 20033 dst->num_freq = src_data->neighbor_report_channel_count; 20034 dst->req_time = src_data->neighbor_report_request_timestamp; 20035 dst->resp_time = src_data->neighbor_report_response_timestamp; 20036 dst->btm_query_token = src_data->btm_query_token; 20037 dst->btm_query_reason = src_data->btm_query_reason_code; 20038 dst->req_token = 20039 WMI_ROAM_NEIGHBOR_REPORT_INFO_REQUEST_TOKEN_GET(src_data->neighbor_report_detail); 20040 dst->resp_token = 20041 WMI_ROAM_NEIGHBOR_REPORT_INFO_RESPONSE_TOKEN_GET(src_data->neighbor_report_detail); 20042 dst->num_rpt = 20043 WMI_ROAM_NEIGHBOR_REPORT_INFO_NUM_OF_NRIE_GET(src_data->neighbor_report_detail); 20044 20045 dst->band = band; 20046 20047 if (dst->band != WMI_MLO_BAND_NO_MLO) 20048 dst->is_mlo = true; 20049 20050 if (!dst->num_freq || !param_buf->num_roam_neighbor_report_chan_info || 20051 rpt_idx >= param_buf->num_roam_neighbor_report_chan_info) 20052 return QDF_STATUS_SUCCESS; 20053 20054 if (!param_buf->roam_neighbor_report_chan_info) { 20055 wmi_debug("11kv channel present, but TLV is NULL num_freq:%d", 20056 dst->num_freq); 20057 dst->num_freq = 0; 20058 /* return success as its optional tlv and we can print neighbor 20059 * report received info 20060 */ 20061 return QDF_STATUS_SUCCESS; 20062 } 20063 20064 src_freq = ¶m_buf->roam_neighbor_report_chan_info[rpt_idx]; 20065 20066 if (dst->num_freq > MAX_ROAM_SCAN_CHAN) 20067 dst->num_freq = MAX_ROAM_SCAN_CHAN; 20068 20069 if ((dst->num_freq + rpt_idx) > 20070 param_buf->num_roam_neighbor_report_chan_info) { 20071 wmi_err("Invalid TLV. num_freq %d rpt_idx %d num_roam_neighbor_report_chan_info %d", 20072 dst->num_freq, rpt_idx, 20073 param_buf->num_roam_scan_chan_info); 20074 return QDF_STATUS_SUCCESS; 20075 } 20076 20077 for (i = 0; i < dst->num_freq; i++) { 20078 dst->freq[i] = src_freq->channel; 20079 src_freq++; 20080 } 20081 20082 return QDF_STATUS_SUCCESS; 20083 } 20084 20085 /** 20086 * send_roam_set_param_cmd_tlv() - WMI roam set parameter function 20087 * @wmi_handle: handle to WMI. 20088 * @roam_param: pointer to hold roam set parameter 20089 * 20090 * Return: QDF_STATUS_SUCCESS for success or error code 20091 */ 20092 static QDF_STATUS 20093 send_roam_set_param_cmd_tlv(wmi_unified_t wmi_handle, 20094 struct vdev_set_params *roam_param) 20095 { 20096 QDF_STATUS ret; 20097 wmi_roam_set_param_cmd_fixed_param *cmd; 20098 wmi_buf_t buf; 20099 uint16_t len = sizeof(*cmd); 20100 20101 buf = wmi_buf_alloc(wmi_handle, len); 20102 if (!buf) 20103 return QDF_STATUS_E_NOMEM; 20104 20105 cmd = (wmi_roam_set_param_cmd_fixed_param *)wmi_buf_data(buf); 20106 WMITLV_SET_HDR(&cmd->tlv_header, 20107 WMITLV_TAG_STRUC_wmi_roam_set_param_cmd_fixed_param, 20108 WMITLV_GET_STRUCT_TLVLEN 20109 (wmi_roam_set_param_cmd_fixed_param)); 20110 cmd->vdev_id = roam_param->vdev_id; 20111 cmd->param_id = roam_param->param_id; 20112 cmd->param_value = roam_param->param_value; 20113 wmi_debug("Setting vdev %d roam_param = %x, value = %u", 20114 cmd->vdev_id, cmd->param_id, cmd->param_value); 20115 wmi_mtrace(WMI_ROAM_SET_PARAM_CMDID, cmd->vdev_id, 0); 20116 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 20117 WMI_ROAM_SET_PARAM_CMDID); 20118 if (QDF_IS_STATUS_ERROR(ret)) { 20119 wmi_err("Failed to send roam set param command, ret = %d", ret); 20120 wmi_buf_free(buf); 20121 } 20122 20123 return ret; 20124 } 20125 #else 20126 static inline QDF_STATUS 20127 extract_roam_trigger_stats_tlv(wmi_unified_t wmi_handle, void *evt_buf, 20128 struct wmi_roam_trigger_info *trig, uint8_t idx, 20129 uint8_t btm_idx) 20130 { 20131 return QDF_STATUS_E_NOSUPPORT; 20132 } 20133 20134 static inline QDF_STATUS 20135 extract_roam_result_stats_tlv(wmi_unified_t wmi_handle, void *evt_buf, 20136 struct wmi_roam_result *dst, uint8_t idx) 20137 { 20138 return QDF_STATUS_E_NOSUPPORT; 20139 } 20140 20141 static QDF_STATUS 20142 extract_roam_11kv_stats_tlv(wmi_unified_t wmi_handle, void *evt_buf, 20143 struct wmi_neighbor_report_data *dst, 20144 uint8_t idx, uint8_t rpt_idx, uint8_t band) 20145 { 20146 return QDF_STATUS_E_NOSUPPORT; 20147 } 20148 20149 static QDF_STATUS 20150 extract_roam_scan_stats_tlv(wmi_unified_t wmi_handle, void *evt_buf, 20151 struct wmi_roam_scan_data *dst, uint8_t idx, 20152 uint8_t chan_idx, uint8_t ap_idx) 20153 { 20154 return QDF_STATUS_E_NOSUPPORT; 20155 } 20156 #endif 20157 20158 #ifdef WLAN_FEATURE_PKT_CAPTURE 20159 static QDF_STATUS 20160 extract_vdev_mgmt_offload_event_tlv(void *handle, void *evt_buf, 20161 struct mgmt_offload_event_params *params) 20162 { 20163 WMI_VDEV_MGMT_OFFLOAD_EVENTID_param_tlvs *param_tlvs; 20164 wmi_mgmt_hdr *hdr; 20165 20166 param_tlvs = (WMI_VDEV_MGMT_OFFLOAD_EVENTID_param_tlvs *)evt_buf; 20167 if (!param_tlvs) 20168 return QDF_STATUS_E_INVAL; 20169 20170 hdr = param_tlvs->fixed_param; 20171 if (!hdr) 20172 return QDF_STATUS_E_INVAL; 20173 20174 if (hdr->buf_len > param_tlvs->num_bufp) 20175 return QDF_STATUS_E_INVAL; 20176 20177 params->tsf_l32 = hdr->tsf_l32; 20178 params->chan_freq = hdr->chan_freq; 20179 params->rate_kbps = hdr->rate_kbps; 20180 params->rssi = hdr->rssi; 20181 params->buf_len = hdr->buf_len; 20182 params->tx_status = hdr->tx_status; 20183 params->buf = param_tlvs->bufp; 20184 params->tx_retry_cnt = hdr->tx_retry_cnt; 20185 return QDF_STATUS_SUCCESS; 20186 } 20187 #endif /* WLAN_FEATURE_PKT_CAPTURE */ 20188 20189 #ifdef WLAN_FEATURE_PKT_CAPTURE_V2 20190 static QDF_STATUS 20191 extract_smart_monitor_event_tlv(void *handle, void *evt_buf, 20192 struct smu_event_params *params) 20193 { 20194 WMI_VDEV_SMART_MONITOR_EVENTID_param_tlvs *param_buf = NULL; 20195 wmi_vdev_smart_monitor_event_fixed_param *smu_event = NULL; 20196 20197 param_buf = (WMI_VDEV_SMART_MONITOR_EVENTID_param_tlvs *)evt_buf; 20198 if (!param_buf) { 20199 wmi_err("Invalid smart monitor event"); 20200 return QDF_STATUS_E_INVAL; 20201 } 20202 20203 smu_event = param_buf->fixed_param; 20204 if (!smu_event) { 20205 wmi_err("smart monitor event fixed param is NULL"); 20206 return QDF_STATUS_E_INVAL; 20207 } 20208 20209 params->vdev_id = smu_event->vdev_id; 20210 if (params->vdev_id >= WLAN_UMAC_PDEV_MAX_VDEVS) 20211 return QDF_STATUS_E_INVAL; 20212 20213 params->rx_vht_sgi = smu_event->rx_vht_sgi; 20214 20215 return QDF_STATUS_SUCCESS; 20216 } 20217 #endif /* WLAN_FEATURE_PKT_CAPTURE_V2 */ 20218 20219 #ifdef FEATURE_WLAN_TIME_SYNC_FTM 20220 /** 20221 * send_wlan_ts_ftm_trigger_cmd_tlv(): send wlan time sync cmd to FW 20222 * 20223 * @wmi: wmi handle 20224 * @vdev_id: vdev id 20225 * @burst_mode: Indicates whether relation derived using FTM is needed for 20226 * each FTM frame or only aggregated result is required. 20227 * 20228 * Send WMI_AUDIO_SYNC_TRIGGER_CMDID to FW. 20229 * 20230 * Return: QDF_STATUS 20231 */ 20232 static QDF_STATUS send_wlan_ts_ftm_trigger_cmd_tlv(wmi_unified_t wmi, 20233 uint32_t vdev_id, 20234 bool burst_mode) 20235 { 20236 wmi_audio_sync_trigger_cmd_fixed_param *cmd; 20237 wmi_buf_t buf; 20238 int32_t len = sizeof(*cmd); 20239 20240 buf = wmi_buf_alloc(wmi, len); 20241 if (!buf) { 20242 wmi_err("wmi_buf_alloc failed"); 20243 return QDF_STATUS_E_NOMEM; 20244 } 20245 cmd = (wmi_audio_sync_trigger_cmd_fixed_param *)wmi_buf_data(buf); 20246 WMITLV_SET_HDR(&cmd->tlv_header, 20247 WMITLV_TAG_STRUC_wmi_audio_sync_trigger_cmd_fixed_param, 20248 WMITLV_GET_STRUCT_TLVLEN(wmi_audio_sync_trigger_cmd_fixed_param)); 20249 cmd->vdev_id = vdev_id; 20250 cmd->agg_relation = burst_mode ? false : true; 20251 if (wmi_unified_cmd_send(wmi, buf, len, WMI_VDEV_AUDIO_SYNC_TRIGGER_CMDID)) { 20252 wmi_err("Failed to send audio sync trigger cmd"); 20253 wmi_buf_free(buf); 20254 return QDF_STATUS_E_FAILURE; 20255 } 20256 20257 return QDF_STATUS_SUCCESS; 20258 } 20259 20260 static QDF_STATUS send_wlan_ts_qtime_cmd_tlv(wmi_unified_t wmi, 20261 uint32_t vdev_id, 20262 uint64_t lpass_ts) 20263 { 20264 wmi_audio_sync_qtimer_cmd_fixed_param *cmd; 20265 wmi_buf_t buf; 20266 int32_t len = sizeof(*cmd); 20267 20268 buf = wmi_buf_alloc(wmi, len); 20269 if (!buf) { 20270 wmi_err("wmi_buf_alloc failed"); 20271 return QDF_STATUS_E_NOMEM; 20272 } 20273 cmd = (wmi_audio_sync_qtimer_cmd_fixed_param *)wmi_buf_data(buf); 20274 WMITLV_SET_HDR(&cmd->tlv_header, 20275 WMITLV_TAG_STRUC_wmi_audio_sync_qtimer_cmd_fixed_param, 20276 WMITLV_GET_STRUCT_TLVLEN(wmi_audio_sync_qtimer_cmd_fixed_param)); 20277 cmd->vdev_id = vdev_id; 20278 cmd->qtimer_u32 = (uint32_t)((lpass_ts & 0xffffffff00000000LL) >> 32); 20279 cmd->qtimer_l32 = (uint32_t)(lpass_ts & 0xffffffffLL); 20280 20281 if (wmi_unified_cmd_send(wmi, buf, len, WMI_VDEV_AUDIO_SYNC_QTIMER_CMDID)) { 20282 wmi_err("Failed to send audio qtime command"); 20283 wmi_buf_free(buf); 20284 return QDF_STATUS_E_FAILURE; 20285 } 20286 20287 return QDF_STATUS_SUCCESS; 20288 } 20289 20290 static QDF_STATUS extract_time_sync_ftm_start_stop_event_tlv( 20291 wmi_unified_t wmi, void *buf, 20292 struct ftm_time_sync_start_stop_params *param) 20293 { 20294 WMI_VDEV_AUDIO_SYNC_START_STOP_EVENTID_param_tlvs *param_buf; 20295 wmi_audio_sync_start_stop_event_fixed_param *resp_event; 20296 20297 param_buf = (WMI_VDEV_AUDIO_SYNC_START_STOP_EVENTID_param_tlvs *)buf; 20298 if (!param_buf) { 20299 wmi_err("Invalid audio sync start stop event buffer"); 20300 return QDF_STATUS_E_FAILURE; 20301 } 20302 20303 resp_event = param_buf->fixed_param; 20304 if (!resp_event) { 20305 wmi_err("Invalid audio sync start stop fixed param buffer"); 20306 return QDF_STATUS_E_FAILURE; 20307 } 20308 20309 param->vdev_id = resp_event->vdev_id; 20310 param->timer_interval = resp_event->periodicity; 20311 param->num_reads = resp_event->reads_needed; 20312 param->qtime = ((uint64_t)resp_event->qtimer_u32 << 32) | 20313 resp_event->qtimer_l32; 20314 param->mac_time = ((uint64_t)resp_event->mac_timer_u32 << 32) | 20315 resp_event->mac_timer_l32; 20316 20317 wmi_debug("FTM time sync time_interval %d, num_reads %d", 20318 param->timer_interval, param->num_reads); 20319 20320 return QDF_STATUS_SUCCESS; 20321 } 20322 20323 static QDF_STATUS 20324 extract_time_sync_ftm_offset_event_tlv(wmi_unified_t wmi, void *buf, 20325 struct ftm_time_sync_offset *param) 20326 { 20327 WMI_VDEV_AUDIO_SYNC_Q_MASTER_SLAVE_OFFSET_EVENTID_param_tlvs *param_buf; 20328 wmi_audio_sync_q_master_slave_offset_event_fixed_param *resp_event; 20329 wmi_audio_sync_q_master_slave_times *q_pair; 20330 int iter; 20331 20332 param_buf = 20333 (WMI_VDEV_AUDIO_SYNC_Q_MASTER_SLAVE_OFFSET_EVENTID_param_tlvs *)buf; 20334 if (!param_buf) { 20335 wmi_err("Invalid timesync ftm offset event buffer"); 20336 return QDF_STATUS_E_FAILURE; 20337 } 20338 20339 resp_event = param_buf->fixed_param; 20340 if (!resp_event) { 20341 wmi_err("Invalid timesync ftm offset fixed param buffer"); 20342 return QDF_STATUS_E_FAILURE; 20343 } 20344 20345 param->vdev_id = resp_event->vdev_id; 20346 param->num_qtime = param_buf->num_audio_sync_q_master_slave_times; 20347 if (param->num_qtime > FTM_TIME_SYNC_QTIME_PAIR_MAX) 20348 param->num_qtime = FTM_TIME_SYNC_QTIME_PAIR_MAX; 20349 20350 q_pair = param_buf->audio_sync_q_master_slave_times; 20351 if (!q_pair) { 20352 wmi_err("Invalid q_master_slave_times buffer"); 20353 return QDF_STATUS_E_FAILURE; 20354 } 20355 20356 for (iter = 0; iter < param->num_qtime; iter++) { 20357 param->pairs[iter].qtime_initiator = ( 20358 (uint64_t)q_pair[iter].qmaster_u32 << 32) | 20359 q_pair[iter].qmaster_l32; 20360 param->pairs[iter].qtime_target = ( 20361 (uint64_t)q_pair[iter].qslave_u32 << 32) | 20362 q_pair[iter].qslave_l32; 20363 } 20364 return QDF_STATUS_SUCCESS; 20365 } 20366 #endif /* FEATURE_WLAN_TIME_SYNC_FTM */ 20367 20368 /** 20369 * send_vdev_tsf_tstamp_action_cmd_tlv() - send vdev tsf action command 20370 * @wmi: wmi handle 20371 * @vdev_id: vdev id 20372 * 20373 * TSF_TSTAMP_READ_VALUE is the only operation supported 20374 * Return: QDF_STATUS_SUCCESS for success or error code 20375 */ 20376 static QDF_STATUS 20377 send_vdev_tsf_tstamp_action_cmd_tlv(wmi_unified_t wmi, uint8_t vdev_id) 20378 { 20379 wmi_vdev_tsf_tstamp_action_cmd_fixed_param *cmd; 20380 wmi_buf_t buf; 20381 int32_t len = sizeof(*cmd); 20382 20383 buf = wmi_buf_alloc(wmi, len); 20384 if (!buf) 20385 return QDF_STATUS_E_NOMEM; 20386 20387 cmd = (wmi_vdev_tsf_tstamp_action_cmd_fixed_param *)wmi_buf_data(buf); 20388 WMITLV_SET_HDR(&cmd->tlv_header, 20389 WMITLV_TAG_STRUC_wmi_vdev_tsf_tstamp_action_cmd_fixed_param, 20390 WMITLV_GET_STRUCT_TLVLEN(wmi_vdev_tsf_tstamp_action_cmd_fixed_param)); 20391 cmd->vdev_id = vdev_id; 20392 cmd->tsf_action = TSF_TSTAMP_QTIMER_CAPTURE_REQ; 20393 wmi_mtrace(WMI_VDEV_TSF_TSTAMP_ACTION_CMDID, cmd->vdev_id, 0); 20394 if (wmi_unified_cmd_send(wmi, buf, len, 20395 WMI_VDEV_TSF_TSTAMP_ACTION_CMDID)) { 20396 wmi_err("%s: Failed to send WMI_VDEV_TSF_TSTAMP_ACTION_CMDID", 20397 __func__); 20398 wmi_buf_free(buf); 20399 return QDF_STATUS_E_FAILURE; 20400 } 20401 20402 return QDF_STATUS_SUCCESS; 20403 } 20404 20405 /** 20406 * extract_vdev_tsf_report_event_tlv() - extract vdev tsf report from event 20407 * @wmi_handle: wmi handle 20408 * @evt_buf: pointer to event buffer 20409 * @param: Pointer to struct to hold event info 20410 * 20411 * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure 20412 */ 20413 static QDF_STATUS 20414 extract_vdev_tsf_report_event_tlv(wmi_unified_t wmi_handle, void *evt_buf, 20415 struct wmi_host_tsf_event *param) 20416 { 20417 WMI_VDEV_TSF_REPORT_EVENTID_param_tlvs *param_buf; 20418 wmi_vdev_tsf_report_event_fixed_param *evt; 20419 20420 param_buf = (WMI_VDEV_TSF_REPORT_EVENTID_param_tlvs *)evt_buf; 20421 if (!param_buf) { 20422 wmi_err("Invalid tsf report event buffer"); 20423 return QDF_STATUS_E_INVAL; 20424 } 20425 20426 evt = param_buf->fixed_param; 20427 param->vdev_id = evt->vdev_id; 20428 param->tsf = ((uint64_t)(evt->tsf_high) << 32) | evt->tsf_low; 20429 param->tsf_low = evt->tsf_low; 20430 param->tsf_high = evt->tsf_high; 20431 param->qtimer_low = evt->qtimer_low; 20432 param->qtimer_high = evt->qtimer_high; 20433 param->tsf_id = evt->tsf_id; 20434 param->tsf_id_valid = evt->tsf_id_valid; 20435 param->mac_id = evt->mac_id; 20436 param->mac_id_valid = evt->mac_id_valid; 20437 param->wlan_global_tsf_low = evt->wlan_global_tsf_low; 20438 param->wlan_global_tsf_high = evt->wlan_global_tsf_high; 20439 param->tqm_timer_low = evt->tqm_timer_low; 20440 param->tqm_timer_high = evt->tqm_timer_high; 20441 param->use_tqm_timer = evt->use_tqm_timer; 20442 20443 return QDF_STATUS_SUCCESS; 20444 } 20445 20446 /** 20447 * extract_pdev_csa_switch_count_status_tlv() - extract pdev csa switch count 20448 * status tlv 20449 * @wmi_handle: wmi handle 20450 * @evt_buf: pointer to event buffer 20451 * @param: Pointer to hold csa switch count status event param 20452 * 20453 * Return: QDF_STATUS_SUCCESS for success or error code 20454 */ 20455 static QDF_STATUS extract_pdev_csa_switch_count_status_tlv( 20456 wmi_unified_t wmi_handle, 20457 void *evt_buf, 20458 struct pdev_csa_switch_count_status *param) 20459 { 20460 WMI_PDEV_CSA_SWITCH_COUNT_STATUS_EVENTID_param_tlvs *param_buf; 20461 wmi_pdev_csa_switch_count_status_event_fixed_param *csa_status; 20462 20463 param_buf = (WMI_PDEV_CSA_SWITCH_COUNT_STATUS_EVENTID_param_tlvs *) 20464 evt_buf; 20465 if (!param_buf) { 20466 wmi_err("Invalid CSA status event"); 20467 return QDF_STATUS_E_INVAL; 20468 } 20469 20470 csa_status = param_buf->fixed_param; 20471 20472 param->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host( 20473 wmi_handle, 20474 csa_status->pdev_id); 20475 param->current_switch_count = csa_status->current_switch_count; 20476 param->num_vdevs = csa_status->num_vdevs; 20477 param->vdev_ids = param_buf->vdev_ids; 20478 20479 return QDF_STATUS_SUCCESS; 20480 } 20481 20482 #ifdef CONFIG_AFC_SUPPORT 20483 /** 20484 * send_afc_cmd_tlv() - Sends the AFC indication to FW 20485 * @wmi_handle: wmi handle 20486 * @pdev_id: Pdev id 20487 * @param: Pointer to hold AFC indication. 20488 * 20489 * Return: QDF_STATUS_SUCCESS for success or error code 20490 */ 20491 static 20492 QDF_STATUS send_afc_cmd_tlv(wmi_unified_t wmi_handle, 20493 uint8_t pdev_id, 20494 struct reg_afc_resp_rx_ind_info *param) 20495 { 20496 wmi_buf_t buf; 20497 wmi_afc_cmd_fixed_param *cmd; 20498 uint32_t len; 20499 uint8_t *buf_ptr; 20500 QDF_STATUS ret; 20501 20502 len = sizeof(wmi_afc_cmd_fixed_param); 20503 buf = wmi_buf_alloc(wmi_handle, len); 20504 if (!buf) 20505 return QDF_STATUS_E_NOMEM; 20506 20507 buf_ptr = (uint8_t *)wmi_buf_data(buf); 20508 cmd = (wmi_afc_cmd_fixed_param *)buf_ptr; 20509 20510 WMITLV_SET_HDR(&cmd->tlv_header, 20511 WMITLV_TAG_STRUC_wmi_afc_cmd_fixed_param, 20512 WMITLV_GET_STRUCT_TLVLEN(wmi_afc_cmd_fixed_param)); 20513 20514 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 20515 wmi_handle, 20516 pdev_id); 20517 cmd->cmd_type = param->cmd_type; 20518 cmd->serv_resp_format = param->serv_resp_format; 20519 20520 wmi_mtrace(WMI_AFC_CMDID, NO_SESSION, 0); 20521 ret = wmi_unified_cmd_send(wmi_handle, buf, len, WMI_AFC_CMDID); 20522 if (QDF_IS_STATUS_ERROR(ret)) { 20523 wmi_err("Failed to send WMI_AFC_CMDID"); 20524 wmi_buf_free(buf); 20525 return QDF_STATUS_E_FAILURE; 20526 } 20527 20528 return QDF_STATUS_SUCCESS; 20529 } 20530 #endif 20531 20532 /** 20533 * send_set_tpc_power_cmd_tlv() - Sends the set TPC power level to FW 20534 * @wmi_handle: wmi handle 20535 * @vdev_id: vdev id 20536 * @param: Pointer to hold TX power info 20537 * 20538 * Return: QDF_STATUS_SUCCESS for success or error code 20539 */ 20540 static QDF_STATUS send_set_tpc_power_cmd_tlv(wmi_unified_t wmi_handle, 20541 uint8_t vdev_id, 20542 struct reg_tpc_power_info *param) 20543 { 20544 wmi_buf_t buf; 20545 wmi_vdev_set_tpc_power_fixed_param *tpc_power_info_param; 20546 wmi_vdev_ch_power_info *ch_power_info; 20547 uint8_t *buf_ptr; 20548 uint16_t idx; 20549 uint32_t len; 20550 QDF_STATUS ret; 20551 20552 len = sizeof(wmi_vdev_set_tpc_power_fixed_param) + WMI_TLV_HDR_SIZE; 20553 len += (sizeof(wmi_vdev_ch_power_info) * param->num_pwr_levels); 20554 20555 buf = wmi_buf_alloc(wmi_handle, len); 20556 if (!buf) 20557 return QDF_STATUS_E_NOMEM; 20558 20559 buf_ptr = (uint8_t *)wmi_buf_data(buf); 20560 tpc_power_info_param = (wmi_vdev_set_tpc_power_fixed_param *)buf_ptr; 20561 20562 WMITLV_SET_HDR(&tpc_power_info_param->tlv_header, 20563 WMITLV_TAG_STRUC_wmi_vdev_set_tpc_power_cmd_fixed_param, 20564 WMITLV_GET_STRUCT_TLVLEN(wmi_vdev_set_tpc_power_fixed_param)); 20565 20566 tpc_power_info_param->vdev_id = vdev_id; 20567 tpc_power_info_param->psd_power = param->is_psd_power; 20568 tpc_power_info_param->eirp_power = param->eirp_power; 20569 tpc_power_info_param->power_type_6ghz = param->power_type_6g; 20570 wmi_debug("eirp_power = %d is_psd_power = %d", 20571 tpc_power_info_param->eirp_power, 20572 tpc_power_info_param->psd_power); 20573 reg_print_ap_power_type_6ghz(tpc_power_info_param->power_type_6ghz); 20574 20575 buf_ptr += sizeof(wmi_vdev_set_tpc_power_fixed_param); 20576 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 20577 param->num_pwr_levels * sizeof(wmi_vdev_ch_power_info)); 20578 20579 buf_ptr += WMI_TLV_HDR_SIZE; 20580 ch_power_info = (wmi_vdev_ch_power_info *)buf_ptr; 20581 20582 for (idx = 0; idx < param->num_pwr_levels; ++idx) { 20583 WMITLV_SET_HDR(&ch_power_info[idx].tlv_header, 20584 WMITLV_TAG_STRUC_wmi_vdev_ch_power_info, 20585 WMITLV_GET_STRUCT_TLVLEN(wmi_vdev_ch_power_info)); 20586 ch_power_info[idx].chan_cfreq = 20587 param->chan_power_info[idx].chan_cfreq; 20588 ch_power_info[idx].tx_power = 20589 param->chan_power_info[idx].tx_power; 20590 wmi_debug("chan_cfreq = %d tx_power = %d", 20591 ch_power_info[idx].chan_cfreq, 20592 ch_power_info[idx].tx_power); 20593 buf_ptr += sizeof(wmi_vdev_ch_power_info); 20594 } 20595 20596 wmi_mtrace(WMI_VDEV_SET_TPC_POWER_CMDID, vdev_id, 0); 20597 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 20598 WMI_VDEV_SET_TPC_POWER_CMDID); 20599 if (QDF_IS_STATUS_ERROR(ret)) 20600 wmi_buf_free(buf); 20601 20602 20603 return ret; 20604 } 20605 20606 /** 20607 * extract_dpd_status_ev_param_tlv() - extract dpd status from FW event 20608 * @wmi_handle: wmi handle 20609 * @evt_buf: event buffer 20610 * @param: dpd status info 20611 * 20612 * Return: QDF_STATUS_SUCCESS for success or error code 20613 */ 20614 static QDF_STATUS 20615 extract_dpd_status_ev_param_tlv(wmi_unified_t wmi_handle, 20616 void *evt_buf, 20617 struct wmi_host_pdev_get_dpd_status_event *param) 20618 { 20619 WMI_PDEV_GET_DPD_STATUS_EVENTID_param_tlvs *param_buf; 20620 wmi_pdev_get_dpd_status_evt_fixed_param *dpd_status; 20621 20622 param_buf = (WMI_PDEV_GET_DPD_STATUS_EVENTID_param_tlvs *)evt_buf; 20623 if (!param_buf) { 20624 wmi_err("Invalid get dpd_status event"); 20625 return QDF_STATUS_E_INVAL; 20626 } 20627 20628 dpd_status = param_buf->fixed_param; 20629 param->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host 20630 (wmi_handle, dpd_status->pdev_id); 20631 param->dpd_status = dpd_status->dpd_status; 20632 20633 return QDF_STATUS_SUCCESS; 20634 } 20635 20636 static int 20637 convert_halphy_status(wmi_pdev_get_halphy_cal_status_evt_fixed_param *status, 20638 WMI_HALPHY_CAL_VALID_BITMAP_STATUS valid_bit) 20639 { 20640 if (status->halphy_cal_valid_bmap && valid_bit) 20641 return (status->halphy_cal_status && valid_bit); 20642 20643 return 0; 20644 } 20645 20646 static QDF_STATUS 20647 extract_halphy_cal_status_ev_param_tlv(wmi_unified_t wmi_handle, 20648 void *evt_buf, 20649 struct wmi_host_pdev_get_halphy_cal_status_event *param) 20650 { 20651 WMI_PDEV_GET_HALPHY_CAL_STATUS_EVENTID_param_tlvs *param_buf; 20652 wmi_pdev_get_halphy_cal_status_evt_fixed_param *halphy_cal_status; 20653 20654 param_buf = (WMI_PDEV_GET_HALPHY_CAL_STATUS_EVENTID_param_tlvs *)evt_buf; 20655 if (!param_buf) { 20656 wmi_err("Invalid get halphy cal status event"); 20657 return QDF_STATUS_E_INVAL; 20658 } 20659 20660 halphy_cal_status = param_buf->fixed_param; 20661 param->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host 20662 (wmi_handle, halphy_cal_status->pdev_id); 20663 param->halphy_cal_adc_status = 20664 convert_halphy_status(halphy_cal_status, 20665 WMI_HALPHY_CAL_ADC_BMAP); 20666 param->halphy_cal_bwfilter_status = 20667 convert_halphy_status(halphy_cal_status, 20668 WMI_HALPHY_CAL_BWFILTER_BMAP); 20669 param->halphy_cal_pdet_and_pal_status = 20670 convert_halphy_status(halphy_cal_status, 20671 WMI_HALPHY_CAL_PDET_AND_PAL_BMAP); 20672 param->halphy_cal_rxdco_status = 20673 convert_halphy_status(halphy_cal_status, 20674 WMI_HALPHY_CAL_RXDCO_BMAP); 20675 param->halphy_cal_comb_txiq_rxiq_status = 20676 convert_halphy_status(halphy_cal_status, 20677 WMI_HALPHY_CAL_COMB_TXLO_TXIQ_RXIQ_BMAP); 20678 param->halphy_cal_ibf_status = 20679 convert_halphy_status(halphy_cal_status, 20680 WMI_HALPHY_CAL_IBF_BMAP); 20681 param->halphy_cal_pa_droop_status = 20682 convert_halphy_status(halphy_cal_status, 20683 WMI_HALPHY_CAL_PA_DROOP_BMAP); 20684 param->halphy_cal_dac_status = 20685 convert_halphy_status(halphy_cal_status, 20686 WMI_HALPHY_CAL_DAC_BMAP); 20687 param->halphy_cal_ani_status = 20688 convert_halphy_status(halphy_cal_status, 20689 WMI_HALPHY_CAL_ANI_BMAP); 20690 param->halphy_cal_noise_floor_status = 20691 convert_halphy_status(halphy_cal_status, 20692 WMI_HALPHY_CAL_NOISE_FLOOR_BMAP); 20693 20694 return QDF_STATUS_SUCCESS; 20695 } 20696 20697 /** 20698 * set_halphy_cal_fw_status_to_host_status() - Convert set halphy cal status to host enum 20699 * @fw_status: set halphy cal status from WMI_PDEV_SET_HALPHY_CAL_BMAP_EVENTID event 20700 * 20701 * Return: host_set_halphy_cal_status 20702 */ 20703 static enum wmi_host_set_halphy_cal_status 20704 set_halphy_cal_fw_status_to_host_status(uint32_t fw_status) 20705 { 20706 if (fw_status == 0) 20707 return WMI_HOST_SET_HALPHY_CAL_STATUS_SUCCESS; 20708 else if (fw_status == 1) 20709 return WMI_HOST_SET_HALPHY_CAL_STATUS_FAIL; 20710 20711 wmi_debug("Unknown set halphy status code(%u) from WMI", fw_status); 20712 return WMI_HOST_SET_HALPHY_CAL_STATUS_FAIL; 20713 } 20714 20715 /** 20716 * extract_halphy_cal_ev_param_tlv() - extract dpd status from FW event 20717 * @wmi_handle: wmi handle 20718 * @evt_buf: event buffer 20719 * @param: set halphy cal status info 20720 * 20721 * Return: QDF_STATUS_SUCCESS for success or error code 20722 */ 20723 static QDF_STATUS 20724 extract_halphy_cal_ev_param_tlv(wmi_unified_t wmi_handle, 20725 void *evt_buf, 20726 struct wmi_host_pdev_set_halphy_cal_event *param) 20727 { 20728 WMI_PDEV_SET_HALPHY_CAL_BMAP_EVENTID_param_tlvs *param_buf; 20729 wmi_pdev_set_halphy_cal_bmap_evt_fixed_param *set_halphy_status; 20730 20731 param_buf = (WMI_PDEV_SET_HALPHY_CAL_BMAP_EVENTID_param_tlvs *)evt_buf; 20732 if (!param_buf) { 20733 wmi_err("Invalid set halphy_status event"); 20734 return QDF_STATUS_E_INVAL; 20735 } 20736 20737 set_halphy_status = param_buf->fixed_param; 20738 param->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host 20739 (wmi_handle, set_halphy_status->pdev_id); 20740 param->status = set_halphy_cal_fw_status_to_host_status(set_halphy_status->status); 20741 20742 return QDF_STATUS_SUCCESS; 20743 } 20744 20745 /** 20746 * extract_install_key_comp_event_tlv() - extract install key complete event tlv 20747 * @wmi_handle: wmi handle 20748 * @evt_buf: pointer to event buffer 20749 * @len: length of the event buffer 20750 * @param: Pointer to hold install key complete event param 20751 * 20752 * Return: QDF_STATUS_SUCCESS for success or error code 20753 */ 20754 static QDF_STATUS 20755 extract_install_key_comp_event_tlv(wmi_unified_t wmi_handle, 20756 void *evt_buf, uint32_t len, 20757 struct wmi_install_key_comp_event *param) 20758 { 20759 WMI_VDEV_INSTALL_KEY_COMPLETE_EVENTID_param_tlvs *param_buf; 20760 wmi_vdev_install_key_complete_event_fixed_param *key_fp; 20761 20762 if (len < sizeof(*param_buf)) { 20763 wmi_err("invalid event buf len %d", len); 20764 return QDF_STATUS_E_INVAL; 20765 } 20766 20767 param_buf = (WMI_VDEV_INSTALL_KEY_COMPLETE_EVENTID_param_tlvs *)evt_buf; 20768 if (!param_buf) { 20769 wmi_err("received null buf from target"); 20770 return QDF_STATUS_E_INVAL; 20771 } 20772 20773 key_fp = param_buf->fixed_param; 20774 if (!key_fp) { 20775 wmi_err("received null event data from target"); 20776 return QDF_STATUS_E_INVAL; 20777 } 20778 20779 param->vdev_id = key_fp->vdev_id; 20780 param->key_ix = key_fp->key_ix; 20781 param->key_flags = key_fp->key_flags; 20782 param->status = key_fp->status; 20783 WMI_MAC_ADDR_TO_CHAR_ARRAY(&key_fp->peer_macaddr, 20784 param->peer_macaddr); 20785 20786 return QDF_STATUS_SUCCESS; 20787 } 20788 20789 static QDF_STATUS 20790 send_set_halphy_cal_tlv(wmi_unified_t wmi_handle, 20791 struct wmi_host_send_set_halphy_cal_info *param) 20792 { 20793 wmi_buf_t buf; 20794 wmi_pdev_set_halphy_cal_bmap_cmd_fixed_param *cmd; 20795 QDF_STATUS ret; 20796 uint32_t len; 20797 20798 len = sizeof(*cmd); 20799 20800 buf = wmi_buf_alloc(wmi_handle, len); 20801 if (!buf) 20802 return QDF_STATUS_E_FAILURE; 20803 20804 cmd = (void *)wmi_buf_data(buf); 20805 20806 WMITLV_SET_HDR(&cmd->tlv_header, 20807 WMITLV_TAG_STRUC_wmi_pdev_set_halphy_cal_bmap_cmd_fixed_param, 20808 WMITLV_GET_STRUCT_TLVLEN(wmi_pdev_set_halphy_cal_bmap_cmd_fixed_param)); 20809 20810 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target(wmi_handle, 20811 param->pdev_id); 20812 cmd->online_halphy_cals_bmap = param->value; 20813 cmd->home_scan_channel = param->chan_sel; 20814 20815 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 20816 WMI_PDEV_SET_HALPHY_CAL_BMAP_CMDID); 20817 if (QDF_IS_STATUS_ERROR(ret)) { 20818 wmi_err("WMI_PDEV_SET_HALPHY_CAL_BMAP_CMDID send returned Error %d",ret); 20819 wmi_buf_free(buf); 20820 } 20821 20822 return ret; 20823 } 20824 20825 #ifdef WLAN_FEATURE_DYNAMIC_MAC_ADDR_UPDATE 20826 /** 20827 * send_set_mac_address_cmd_tlv() - send set MAC address command to fw 20828 * @wmi: wmi handle 20829 * @params: set MAC address command params 20830 * 20831 * Return: QDF_STATUS_SUCCESS for success or error code 20832 */ 20833 static QDF_STATUS 20834 send_set_mac_address_cmd_tlv(wmi_unified_t wmi, 20835 struct set_mac_addr_params *params) 20836 { 20837 wmi_vdev_update_mac_addr_cmd_fixed_param *cmd; 20838 wmi_buf_t buf; 20839 int32_t len = sizeof(*cmd); 20840 20841 buf = wmi_buf_alloc(wmi, len); 20842 if (!buf) 20843 return QDF_STATUS_E_NOMEM; 20844 20845 cmd = (wmi_vdev_update_mac_addr_cmd_fixed_param *)wmi_buf_data(buf); 20846 WMITLV_SET_HDR( 20847 &cmd->tlv_header, 20848 WMITLV_TAG_STRUC_wmi_vdev_update_mac_addr_cmd_fixed_param, 20849 WMITLV_GET_STRUCT_TLVLEN 20850 (wmi_vdev_update_mac_addr_cmd_fixed_param)); 20851 cmd->vdev_id = params->vdev_id; 20852 WMI_CHAR_ARRAY_TO_MAC_ADDR(params->mac_addr.bytes, &cmd->vdev_macaddr); 20853 WMI_CHAR_ARRAY_TO_MAC_ADDR(params->mld_addr.bytes, &cmd->mld_macaddr); 20854 20855 wmi_debug("vdev %d mac_addr " QDF_MAC_ADDR_FMT " mld_addr " 20856 QDF_MAC_ADDR_FMT, cmd->vdev_id, 20857 QDF_MAC_ADDR_REF(params->mac_addr.bytes), 20858 QDF_MAC_ADDR_REF(params->mld_addr.bytes)); 20859 wmi_mtrace(WMI_VDEV_UPDATE_MAC_ADDR_CMDID, cmd->vdev_id, 0); 20860 if (wmi_unified_cmd_send(wmi, buf, len, 20861 WMI_VDEV_UPDATE_MAC_ADDR_CMDID)) { 20862 wmi_buf_free(buf); 20863 return QDF_STATUS_E_FAILURE; 20864 } 20865 20866 return QDF_STATUS_SUCCESS; 20867 } 20868 20869 /** 20870 * extract_update_mac_address_event_tlv() - extract update MAC address event 20871 * @wmi_handle: WMI handle 20872 * @evt_buf: event buffer 20873 * @vdev_id: VDEV ID 20874 * @status: FW status of the set MAC address operation 20875 * 20876 * Return: QDF_STATUS 20877 */ 20878 static QDF_STATUS extract_update_mac_address_event_tlv( 20879 wmi_unified_t wmi_handle, void *evt_buf, 20880 uint8_t *vdev_id, uint8_t *status) 20881 { 20882 WMI_VDEV_UPDATE_MAC_ADDR_CONF_EVENTID_param_tlvs *param_buf; 20883 wmi_vdev_update_mac_addr_conf_event_fixed_param *event; 20884 20885 param_buf = 20886 (WMI_VDEV_UPDATE_MAC_ADDR_CONF_EVENTID_param_tlvs *)evt_buf; 20887 20888 event = param_buf->fixed_param; 20889 20890 *vdev_id = event->vdev_id; 20891 *status = event->status; 20892 20893 return QDF_STATUS_SUCCESS; 20894 } 20895 #endif 20896 20897 #ifdef WLAN_FEATURE_11BE_MLO 20898 /** 20899 * extract_quiet_offload_event_tlv() - extract quiet offload event 20900 * @wmi_handle: WMI handle 20901 * @evt_buf: event buffer 20902 * @quiet_event: quiet event extracted from the buffer 20903 * 20904 * Return: QDF_STATUS 20905 */ 20906 static QDF_STATUS extract_quiet_offload_event_tlv( 20907 wmi_unified_t wmi_handle, void *evt_buf, 20908 struct vdev_sta_quiet_event *quiet_event) 20909 { 20910 WMI_QUIET_HANDLING_EVENTID_param_tlvs *param_buf; 20911 wmi_quiet_event_fixed_param *event; 20912 20913 param_buf = (WMI_QUIET_HANDLING_EVENTID_param_tlvs *)evt_buf; 20914 20915 event = param_buf->fixed_param; 20916 20917 if (!(event->mld_mac_address_present && event->linkid_present) && 20918 !event->link_mac_address_present) { 20919 wmi_err("Invalid sta quiet offload event. present bit: mld mac %d link mac %d linkid %d", 20920 event->mld_mac_address_present, 20921 event->linkid_present, 20922 event->link_mac_address_present); 20923 return QDF_STATUS_E_INVAL; 20924 } 20925 20926 if (event->mld_mac_address_present) 20927 WMI_MAC_ADDR_TO_CHAR_ARRAY(&event->mld_mac_address, 20928 quiet_event->mld_mac.bytes); 20929 if (event->link_mac_address_present) 20930 WMI_MAC_ADDR_TO_CHAR_ARRAY(&event->link_mac_address, 20931 quiet_event->link_mac.bytes); 20932 if (event->linkid_present) 20933 quiet_event->link_id = event->linkid; 20934 quiet_event->quiet_status = (event->quiet_status == 20935 WMI_QUIET_EVENT_START); 20936 20937 return QDF_STATUS_SUCCESS; 20938 } 20939 #endif 20940 20941 /** 20942 * send_vdev_pn_mgmt_rxfilter_cmd_tlv() - Send PN mgmt RxFilter command to FW 20943 * @wmi_handle: wmi handle 20944 * @params: RxFilter params 20945 * 20946 * Return: QDF_STATUS_SUCCESS for success or error code 20947 */ 20948 static QDF_STATUS 20949 send_vdev_pn_mgmt_rxfilter_cmd_tlv(wmi_unified_t wmi_handle, 20950 struct vdev_pn_mgmt_rxfilter_params *params) 20951 { 20952 wmi_vdev_pn_mgmt_rx_filter_cmd_fixed_param *cmd; 20953 wmi_buf_t buf; 20954 uint32_t len = sizeof(wmi_vdev_pn_mgmt_rx_filter_cmd_fixed_param); 20955 20956 if (!is_service_enabled_tlv(wmi_handle, 20957 WMI_SERVICE_PN_REPLAY_CHECK_SUPPORT)) { 20958 wmi_err("Rx PN Replay Check not supported by target"); 20959 return QDF_STATUS_E_NOSUPPORT; 20960 } 20961 20962 buf = wmi_buf_alloc(wmi_handle, len); 20963 if (!buf) { 20964 wmi_err("wmi buf alloc failed"); 20965 return QDF_STATUS_E_NOMEM; 20966 } 20967 20968 cmd = (wmi_vdev_pn_mgmt_rx_filter_cmd_fixed_param *)wmi_buf_data(buf); 20969 WMITLV_SET_HDR( 20970 &cmd->tlv_header, 20971 WMITLV_TAG_STRUC_wmi_vdev_pn_mgmt_rx_filter_cmd_fixed_param, 20972 WMITLV_GET_STRUCT_TLVLEN 20973 (wmi_vdev_pn_mgmt_rx_filter_cmd_fixed_param)); 20974 20975 cmd->vdev_id = params->vdev_id; 20976 cmd->pn_rx_filter = params->pn_rxfilter; 20977 20978 if (wmi_unified_cmd_send(wmi_handle, buf, len, 20979 WMI_VDEV_PN_MGMT_RX_FILTER_CMDID)) { 20980 wmi_err("Failed to send WMI command"); 20981 wmi_buf_free(buf); 20982 return QDF_STATUS_E_FAILURE; 20983 } 20984 20985 return QDF_STATUS_SUCCESS; 20986 } 20987 20988 static QDF_STATUS 20989 send_egid_info_cmd_tlv(wmi_unified_t wmi_handle, 20990 struct esl_egid_params *param) 20991 { 20992 wmi_esl_egid_cmd_fixed_param *cmd; 20993 wmi_buf_t buf; 20994 20995 uint32_t len = sizeof(*cmd); 20996 20997 buf = wmi_buf_alloc(wmi_handle, len); 20998 if (!buf) { 20999 wmi_err("wmi_buf_alloc failed"); 21000 return QDF_STATUS_E_NOMEM; 21001 } 21002 21003 cmd = (wmi_esl_egid_cmd_fixed_param *)wmi_buf_data(buf); 21004 WMITLV_SET_HDR( 21005 &cmd->tlv_header, 21006 WMITLV_TAG_STRUC_wmi_esl_egid_cmd_fixed_param, 21007 WMITLV_GET_STRUCT_TLVLEN(wmi_esl_egid_cmd_fixed_param)); 21008 qdf_mem_copy(cmd->egid_info, 21009 param->egid_info, 21010 sizeof(param->egid_info)); 21011 if (wmi_unified_cmd_send(wmi_handle, buf, len, WMI_ESL_EGID_CMDID)) { 21012 wmi_err("Failed to send WMI command"); 21013 wmi_buf_free(buf); 21014 return QDF_STATUS_E_FAILURE; 21015 } 21016 21017 return QDF_STATUS_SUCCESS; 21018 } 21019 21020 static QDF_STATUS 21021 extract_pktlog_decode_info_event_tlv(wmi_unified_t wmi_handle, void *evt_buf, 21022 uint8_t *pdev_id, uint8_t *software_image, 21023 uint8_t *chip_info, 21024 uint32_t *pktlog_json_version) 21025 { 21026 WMI_PDEV_PKTLOG_DECODE_INFO_EVENTID_param_tlvs *param_buf; 21027 wmi_pdev_pktlog_decode_info_evt_fixed_param *event; 21028 21029 param_buf = 21030 (WMI_PDEV_PKTLOG_DECODE_INFO_EVENTID_param_tlvs *)evt_buf; 21031 21032 event = param_buf->fixed_param; 21033 21034 if ((event->software_image[0] == '\0') || 21035 (event->chip_info[0] == '\0')) { 21036 *pdev_id = event->pdev_id; 21037 return QDF_STATUS_E_INVAL; 21038 } 21039 21040 qdf_mem_copy(software_image, event->software_image, 40); 21041 qdf_mem_copy(chip_info, event->chip_info, 40); 21042 *pktlog_json_version = event->pktlog_defs_json_version; 21043 *pdev_id = event->pdev_id; 21044 return QDF_STATUS_SUCCESS; 21045 } 21046 21047 #ifdef HEALTH_MON_SUPPORT 21048 /** 21049 * extract_health_mon_init_done_info_event_tlv() - Extract health monitor from 21050 * fw 21051 * @wmi_handle: wmi handle 21052 * @evt_buf: pointer to event buffer 21053 * @param: health monitor params 21054 * 21055 * Return: QDF_STATUS_SUCCESS for success or error code 21056 */ 21057 static QDF_STATUS 21058 extract_health_mon_init_done_info_event_tlv(wmi_unified_t wmi_handle, 21059 void *evt_buf, 21060 struct wmi_health_mon_params *param) 21061 { 21062 WMI_HEALTH_MON_INIT_DONE_EVENTID_param_tlvs *param_buf; 21063 wmi_health_mon_init_done_fixed_param *event; 21064 21065 param_buf = 21066 (WMI_HEALTH_MON_INIT_DONE_EVENTID_param_tlvs *)evt_buf; 21067 21068 event = param_buf->fixed_param; 21069 21070 param->ring_buf_paddr_low = event->ring_buf_paddr_low; 21071 param->ring_buf_paddr_high = event->ring_buf_paddr_high; 21072 param->initial_upload_period_ms = event->initial_upload_period_ms; 21073 param->read_index = 0; 21074 21075 return QDF_STATUS_SUCCESS; 21076 } 21077 #endif /* HEALTH_MON_SUPPORT */ 21078 21079 /** 21080 * extract_pdev_telemetry_stats_tlv - extract pdev telemetry stats 21081 * @wmi_handle: wmi handle 21082 * @evt_buf: pointer to event buffer 21083 * @pdev_stats: Pointer to hold pdev telemetry stats 21084 * 21085 * Return: QDF_STATUS_SUCCESS for success or error code 21086 */ 21087 static QDF_STATUS 21088 extract_pdev_telemetry_stats_tlv( 21089 wmi_unified_t wmi_handle, void *evt_buf, 21090 struct wmi_host_pdev_telemetry_stats *pdev_stats) 21091 { 21092 WMI_UPDATE_STATS_EVENTID_param_tlvs *param_buf; 21093 wmi_pdev_telemetry_stats *ev; 21094 21095 param_buf = (WMI_UPDATE_STATS_EVENTID_param_tlvs *)evt_buf; 21096 21097 if (param_buf->pdev_telemetry_stats) { 21098 ev = (wmi_pdev_telemetry_stats *)(param_buf->pdev_telemetry_stats); 21099 qdf_mem_copy(pdev_stats->avg_chan_lat_per_ac, 21100 ev->avg_chan_lat_per_ac, 21101 sizeof(ev->avg_chan_lat_per_ac)); 21102 pdev_stats->estimated_air_time_per_ac = 21103 ev->estimated_air_time_per_ac; 21104 } 21105 21106 return QDF_STATUS_SUCCESS; 21107 } 21108 21109 static QDF_STATUS 21110 send_set_mac_addr_rx_filter_cmd_tlv(wmi_unified_t wmi_handle, 21111 struct set_rx_mac_filter *param) 21112 { 21113 wmi_vdev_add_mac_addr_to_rx_filter_cmd_fixed_param *cmd; 21114 uint32_t len; 21115 wmi_buf_t buf; 21116 int ret; 21117 21118 if (!wmi_handle) { 21119 wmi_err("WMA context is invalid!"); 21120 return QDF_STATUS_E_INVAL; 21121 } 21122 21123 len = sizeof(*cmd); 21124 buf = wmi_buf_alloc(wmi_handle, len); 21125 if (!buf) { 21126 wmi_err("Failed allocate wmi buffer"); 21127 return QDF_STATUS_E_NOMEM; 21128 } 21129 21130 cmd = (wmi_vdev_add_mac_addr_to_rx_filter_cmd_fixed_param *) 21131 wmi_buf_data(buf); 21132 21133 WMITLV_SET_HDR( 21134 &cmd->tlv_header, 21135 WMITLV_TAG_STRUC_wmi_vdev_add_mac_addr_to_rx_filter_cmd_fixed_param, 21136 WMITLV_GET_STRUCT_TLVLEN( 21137 wmi_vdev_add_mac_addr_to_rx_filter_cmd_fixed_param)); 21138 21139 cmd->vdev_id = param->vdev_id; 21140 cmd->freq = param->freq; 21141 WMI_CHAR_ARRAY_TO_MAC_ADDR(param->mac, &cmd->mac_addr); 21142 if (param->set) 21143 cmd->enable = 1; 21144 else 21145 cmd->enable = 0; 21146 wmi_debug("set random mac rx vdev:%d freq:%d set:%d " QDF_MAC_ADDR_FMT, 21147 param->vdev_id, param->freq, param->set, 21148 QDF_MAC_ADDR_REF(param->mac)); 21149 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 21150 WMI_VDEV_ADD_MAC_ADDR_TO_RX_FILTER_CMDID); 21151 if (ret) { 21152 wmi_err("Failed to send action frame random mac cmd"); 21153 wmi_buf_free(buf); 21154 return QDF_STATUS_E_FAILURE; 21155 } 21156 21157 return QDF_STATUS_SUCCESS; 21158 } 21159 21160 static QDF_STATUS 21161 extract_sap_coex_fix_chan_caps(wmi_unified_t wmi_handle, 21162 uint8_t *event, 21163 struct wmi_host_coex_fix_chan_cap *cap) 21164 { 21165 WMI_SERVICE_READY_EXT2_EVENTID_param_tlvs *param_buf; 21166 WMI_COEX_FIX_CHANNEL_CAPABILITIES *fw_cap; 21167 21168 param_buf = (WMI_SERVICE_READY_EXT2_EVENTID_param_tlvs *)event; 21169 if (!param_buf) 21170 return QDF_STATUS_E_INVAL; 21171 21172 fw_cap = param_buf->coex_fix_channel_caps; 21173 if (!fw_cap) 21174 return QDF_STATUS_E_INVAL; 21175 21176 cap->fix_chan_priority = fw_cap->fix_channel_priority; 21177 21178 return QDF_STATUS_SUCCESS; 21179 } 21180 21181 static QDF_STATUS extract_tgtr2p_table_event_tlv(wmi_unified_t wmi_handle, 21182 uint8_t *evt_buf, 21183 struct r2p_table_update_status_obj *update_status, 21184 uint32_t len) 21185 { 21186 WMI_PDEV_SET_TGTR2P_TABLE_EVENTID_param_tlvs *param_buf; 21187 wmi_pdev_set_tgtr2p_table_event_fixed_param *event_fixed_hdr; 21188 21189 param_buf = (WMI_PDEV_SET_TGTR2P_TABLE_EVENTID_param_tlvs *)evt_buf; 21190 if (!param_buf) { 21191 wmi_err("Invalid TGTR2P event buf"); 21192 return QDF_STATUS_E_FAILURE; 21193 } 21194 21195 event_fixed_hdr = param_buf->fixed_param; 21196 update_status->pdev_id = event_fixed_hdr->pdev_id; 21197 update_status->status = event_fixed_hdr->status; 21198 21199 if (update_status->status != WMI_PDEV_TGTR2P_SUCCESS && 21200 update_status->status != 21201 WMI_PDEV_TGTR2P_SUCCESS_WAITING_FOR_END_OF_UPDATE) { 21202 wmi_err("Rate2Power table update failed. Status = %d", 21203 update_status->status); 21204 } 21205 21206 return QDF_STATUS_SUCCESS; 21207 } 21208 21209 struct wmi_ops tlv_ops = { 21210 .send_vdev_create_cmd = send_vdev_create_cmd_tlv, 21211 .send_vdev_delete_cmd = send_vdev_delete_cmd_tlv, 21212 .send_vdev_nss_chain_params_cmd = send_vdev_nss_chain_params_cmd_tlv, 21213 .send_vdev_down_cmd = send_vdev_down_cmd_tlv, 21214 .send_vdev_start_cmd = send_vdev_start_cmd_tlv, 21215 .send_peer_flush_tids_cmd = send_peer_flush_tids_cmd_tlv, 21216 .send_peer_param_cmd = send_peer_param_cmd_tlv, 21217 .send_vdev_up_cmd = send_vdev_up_cmd_tlv, 21218 .send_vdev_stop_cmd = send_vdev_stop_cmd_tlv, 21219 .send_peer_create_cmd = send_peer_create_cmd_tlv, 21220 .send_peer_delete_cmd = send_peer_delete_cmd_tlv, 21221 .send_peer_delete_all_cmd = send_peer_delete_all_cmd_tlv, 21222 .send_peer_rx_reorder_queue_setup_cmd = 21223 send_peer_rx_reorder_queue_setup_cmd_tlv, 21224 .send_peer_rx_reorder_queue_remove_cmd = 21225 send_peer_rx_reorder_queue_remove_cmd_tlv, 21226 .send_pdev_utf_cmd = send_pdev_utf_cmd_tlv, 21227 .send_pdev_param_cmd = send_pdev_param_cmd_tlv, 21228 .send_multiple_pdev_param_cmd = send_multiple_pdev_param_cmd_tlv, 21229 .send_pdev_set_hw_mode_cmd = send_pdev_set_hw_mode_cmd_tlv, 21230 .send_pdev_set_rf_path_cmd = send_pdev_set_rf_path_cmd_tlv, 21231 .send_suspend_cmd = send_suspend_cmd_tlv, 21232 .send_resume_cmd = send_resume_cmd_tlv, 21233 .send_wow_enable_cmd = send_wow_enable_cmd_tlv, 21234 .send_set_ap_ps_param_cmd = send_set_ap_ps_param_cmd_tlv, 21235 .send_set_sta_ps_param_cmd = send_set_sta_ps_param_cmd_tlv, 21236 .send_crash_inject_cmd = send_crash_inject_cmd_tlv, 21237 .send_dbglog_cmd = send_dbglog_cmd_tlv, 21238 .send_vdev_set_param_cmd = send_vdev_set_param_cmd_tlv, 21239 .send_vdev_set_mu_snif_cmd = send_vdev_set_mu_snif_cmd_tlv, 21240 .send_packet_log_enable_cmd = send_packet_log_enable_cmd_tlv, 21241 .send_peer_based_pktlog_cmd = send_peer_based_pktlog_cmd, 21242 .send_time_stamp_sync_cmd = send_time_stamp_sync_cmd_tlv, 21243 .send_packet_log_disable_cmd = send_packet_log_disable_cmd_tlv, 21244 .send_beacon_tmpl_send_cmd = send_beacon_tmpl_send_cmd_tlv, 21245 .send_fd_tmpl_cmd = send_fd_tmpl_cmd_tlv, 21246 .send_peer_assoc_cmd = send_peer_assoc_cmd_tlv, 21247 .send_scan_start_cmd = send_scan_start_cmd_tlv, 21248 .send_scan_stop_cmd = send_scan_stop_cmd_tlv, 21249 .send_scan_chan_list_cmd = send_scan_chan_list_cmd_tlv, 21250 .send_mgmt_cmd = send_mgmt_cmd_tlv, 21251 .send_offchan_data_tx_cmd = send_offchan_data_tx_cmd_tlv, 21252 .send_modem_power_state_cmd = send_modem_power_state_cmd_tlv, 21253 .send_set_sta_ps_mode_cmd = send_set_sta_ps_mode_cmd_tlv, 21254 .send_idle_roam_monitor_cmd = send_idle_roam_monitor_cmd_tlv, 21255 .send_set_sta_uapsd_auto_trig_cmd = 21256 send_set_sta_uapsd_auto_trig_cmd_tlv, 21257 .send_get_temperature_cmd = send_get_temperature_cmd_tlv, 21258 .send_set_smps_params_cmd = send_set_smps_params_cmd_tlv, 21259 .send_set_mimops_cmd = send_set_mimops_cmd_tlv, 21260 .send_set_thermal_mgmt_cmd = send_set_thermal_mgmt_cmd_tlv, 21261 .send_lro_config_cmd = send_lro_config_cmd_tlv, 21262 .send_peer_rate_report_cmd = send_peer_rate_report_cmd_tlv, 21263 .send_probe_rsp_tmpl_send_cmd = 21264 send_probe_rsp_tmpl_send_cmd_tlv, 21265 .send_p2p_go_set_beacon_ie_cmd = 21266 send_p2p_go_set_beacon_ie_cmd_tlv, 21267 .send_setup_install_key_cmd = 21268 send_setup_install_key_cmd_tlv, 21269 .send_scan_probe_setoui_cmd = 21270 send_scan_probe_setoui_cmd_tlv, 21271 #ifdef IPA_OFFLOAD 21272 .send_ipa_offload_control_cmd = 21273 send_ipa_offload_control_cmd_tlv, 21274 #endif 21275 .send_pno_stop_cmd = send_pno_stop_cmd_tlv, 21276 .send_pno_start_cmd = send_pno_start_cmd_tlv, 21277 .send_obss_disable_cmd = send_obss_disable_cmd_tlv, 21278 .send_nlo_mawc_cmd = send_nlo_mawc_cmd_tlv, 21279 #ifdef WLAN_FEATURE_LINK_LAYER_STATS 21280 .send_process_ll_stats_clear_cmd = send_process_ll_stats_clear_cmd_tlv, 21281 .send_process_ll_stats_set_cmd = send_process_ll_stats_set_cmd_tlv, 21282 .send_process_ll_stats_get_cmd = send_process_ll_stats_get_cmd_tlv, 21283 #ifdef FEATURE_CLUB_LL_STATS_AND_GET_STATION 21284 .send_unified_ll_stats_get_sta_cmd = 21285 send_unified_ll_stats_get_sta_cmd_tlv, 21286 #endif /* FEATURE_CLUB_LL_STATS_AND_GET_STATION */ 21287 #endif /* WLAN_FEATURE_LINK_LAYER_STATS*/ 21288 .send_congestion_cmd = send_congestion_cmd_tlv, 21289 .send_snr_request_cmd = send_snr_request_cmd_tlv, 21290 .send_snr_cmd = send_snr_cmd_tlv, 21291 .send_link_status_req_cmd = send_link_status_req_cmd_tlv, 21292 #if !defined(REMOVE_PKT_LOG) && defined(FEATURE_PKTLOG) 21293 .send_pktlog_wmi_send_cmd = send_pktlog_wmi_send_cmd_tlv, 21294 #endif 21295 #ifdef WLAN_SUPPORT_GREEN_AP 21296 .send_egap_conf_params_cmd = send_egap_conf_params_cmd_tlv, 21297 .send_green_ap_ps_cmd = send_green_ap_ps_cmd_tlv, 21298 .extract_green_ap_egap_status_info = 21299 extract_green_ap_egap_status_info_tlv, 21300 #endif 21301 #ifdef WLAN_SUPPORT_GAP_LL_PS_MODE 21302 .send_green_ap_ll_ps_cmd = send_green_ap_ll_ps_cmd_tlv, 21303 .extract_green_ap_ll_ps_param = extract_green_ap_ll_ps_param_tlv, 21304 #endif 21305 .send_csa_offload_enable_cmd = send_csa_offload_enable_cmd_tlv, 21306 .send_start_oem_data_cmd = send_start_oem_data_cmd_tlv, 21307 #ifdef FEATURE_OEM_DATA 21308 .send_start_oemv2_data_cmd = send_start_oemv2_data_cmd_tlv, 21309 #endif 21310 #ifdef WLAN_FEATURE_CIF_CFR 21311 .send_oem_dma_cfg_cmd = send_oem_dma_cfg_cmd_tlv, 21312 #endif 21313 .send_dfs_phyerr_filter_offload_en_cmd = 21314 send_dfs_phyerr_filter_offload_en_cmd_tlv, 21315 .send_stats_ext_req_cmd = send_stats_ext_req_cmd_tlv, 21316 .send_process_dhcpserver_offload_cmd = 21317 send_process_dhcpserver_offload_cmd_tlv, 21318 .send_pdev_set_regdomain_cmd = 21319 send_pdev_set_regdomain_cmd_tlv, 21320 .send_regdomain_info_to_fw_cmd = send_regdomain_info_to_fw_cmd_tlv, 21321 .send_cfg_action_frm_tb_ppdu_cmd = send_cfg_action_frm_tb_ppdu_cmd_tlv, 21322 .save_fw_version_cmd = save_fw_version_cmd_tlv, 21323 .check_and_update_fw_version = 21324 check_and_update_fw_version_cmd_tlv, 21325 .send_log_supported_evt_cmd = send_log_supported_evt_cmd_tlv, 21326 .send_enable_specific_fw_logs_cmd = 21327 send_enable_specific_fw_logs_cmd_tlv, 21328 .send_flush_logs_to_fw_cmd = send_flush_logs_to_fw_cmd_tlv, 21329 .send_unit_test_cmd = send_unit_test_cmd_tlv, 21330 #ifdef FEATURE_WLAN_APF 21331 .send_set_active_apf_mode_cmd = wmi_send_set_active_apf_mode_cmd_tlv, 21332 .send_apf_enable_cmd = wmi_send_apf_enable_cmd_tlv, 21333 .send_apf_write_work_memory_cmd = 21334 wmi_send_apf_write_work_memory_cmd_tlv, 21335 .send_apf_read_work_memory_cmd = 21336 wmi_send_apf_read_work_memory_cmd_tlv, 21337 .extract_apf_read_memory_resp_event = 21338 wmi_extract_apf_read_memory_resp_event_tlv, 21339 #endif /* FEATURE_WLAN_APF */ 21340 .init_cmd_send = init_cmd_send_tlv, 21341 .send_vdev_set_custom_aggr_size_cmd = 21342 send_vdev_set_custom_aggr_size_cmd_tlv, 21343 .send_vdev_set_qdepth_thresh_cmd = 21344 send_vdev_set_qdepth_thresh_cmd_tlv, 21345 .send_set_vap_dscp_tid_map_cmd = send_set_vap_dscp_tid_map_cmd_tlv, 21346 .send_vdev_set_fwtest_param_cmd = send_vdev_set_fwtest_param_cmd_tlv, 21347 .send_phyerr_disable_cmd = send_phyerr_disable_cmd_tlv, 21348 .send_phyerr_enable_cmd = send_phyerr_enable_cmd_tlv, 21349 .send_periodic_chan_stats_config_cmd = 21350 send_periodic_chan_stats_config_cmd_tlv, 21351 #ifdef WLAN_IOT_SIM_SUPPORT 21352 .send_simulation_test_cmd = send_simulation_test_cmd_tlv, 21353 #endif 21354 .send_vdev_spectral_configure_cmd = 21355 send_vdev_spectral_configure_cmd_tlv, 21356 .send_vdev_spectral_enable_cmd = 21357 send_vdev_spectral_enable_cmd_tlv, 21358 #ifdef WLAN_CONV_SPECTRAL_ENABLE 21359 .extract_pdev_sscan_fw_cmd_fixed_param = 21360 extract_pdev_sscan_fw_cmd_fixed_param_tlv, 21361 .extract_pdev_sscan_fft_bin_index = 21362 extract_pdev_sscan_fft_bin_index_tlv, 21363 .extract_pdev_spectral_session_chan_info = 21364 extract_pdev_spectral_session_chan_info_tlv, 21365 .extract_pdev_spectral_session_detector_info = 21366 extract_pdev_spectral_session_detector_info_tlv, 21367 .extract_spectral_caps_fixed_param = 21368 extract_spectral_caps_fixed_param_tlv, 21369 .extract_spectral_scan_bw_caps = 21370 extract_spectral_scan_bw_caps_tlv, 21371 .extract_spectral_fft_size_caps = 21372 extract_spectral_fft_size_caps_tlv, 21373 #endif /* WLAN_CONV_SPECTRAL_ENABLE */ 21374 .send_thermal_mitigation_param_cmd = 21375 send_thermal_mitigation_param_cmd_tlv, 21376 .send_process_update_edca_param_cmd = 21377 send_process_update_edca_param_cmd_tlv, 21378 .send_bss_color_change_enable_cmd = 21379 send_bss_color_change_enable_cmd_tlv, 21380 .send_coex_config_cmd = send_coex_config_cmd_tlv, 21381 .send_set_country_cmd = send_set_country_cmd_tlv, 21382 .send_addba_send_cmd = send_addba_send_cmd_tlv, 21383 .send_delba_send_cmd = send_delba_send_cmd_tlv, 21384 .send_addba_clearresponse_cmd = send_addba_clearresponse_cmd_tlv, 21385 .get_target_cap_from_service_ready = extract_service_ready_tlv, 21386 .extract_hal_reg_cap = extract_hal_reg_cap_tlv, 21387 .extract_num_mem_reqs = extract_num_mem_reqs_tlv, 21388 .extract_host_mem_req = extract_host_mem_req_tlv, 21389 .save_service_bitmap = save_service_bitmap_tlv, 21390 .save_ext_service_bitmap = save_ext_service_bitmap_tlv, 21391 .is_service_enabled = is_service_enabled_tlv, 21392 .save_fw_version = save_fw_version_in_service_ready_tlv, 21393 .ready_extract_init_status = ready_extract_init_status_tlv, 21394 .ready_extract_mac_addr = ready_extract_mac_addr_tlv, 21395 .ready_extract_mac_addr_list = ready_extract_mac_addr_list_tlv, 21396 .extract_ready_event_params = extract_ready_event_params_tlv, 21397 .extract_dbglog_data_len = extract_dbglog_data_len_tlv, 21398 .extract_mgmt_rx_params = extract_mgmt_rx_params_tlv, 21399 .extract_frame_pn_params = extract_frame_pn_params_tlv, 21400 .extract_is_conn_ap_frame = extract_is_conn_ap_frm_param_tlv, 21401 .extract_vdev_roam_param = extract_vdev_roam_param_tlv, 21402 .extract_vdev_scan_ev_param = extract_vdev_scan_ev_param_tlv, 21403 #ifdef FEATURE_WLAN_SCAN_PNO 21404 .extract_nlo_match_ev_param = extract_nlo_match_ev_param_tlv, 21405 .extract_nlo_complete_ev_param = extract_nlo_complete_ev_param_tlv, 21406 #endif 21407 .extract_unit_test = extract_unit_test_tlv, 21408 .extract_pdev_ext_stats = extract_pdev_ext_stats_tlv, 21409 .extract_bcn_stats = extract_bcn_stats_tlv, 21410 .extract_bcnflt_stats = extract_bcnflt_stats_tlv, 21411 .extract_chan_stats = extract_chan_stats_tlv, 21412 .extract_vdev_prb_fils_stats = extract_vdev_prb_fils_stats_tlv, 21413 .extract_profile_ctx = extract_profile_ctx_tlv, 21414 .extract_profile_data = extract_profile_data_tlv, 21415 .send_fw_test_cmd = send_fw_test_cmd_tlv, 21416 .send_wfa_test_cmd = send_wfa_test_cmd_tlv, 21417 .send_power_dbg_cmd = send_power_dbg_cmd_tlv, 21418 .extract_service_ready_ext = extract_service_ready_ext_tlv, 21419 .extract_service_ready_ext2 = extract_service_ready_ext2_tlv, 21420 .extract_dbs_or_sbs_service_ready_ext2 = 21421 extract_dbs_or_sbs_cap_service_ready_ext2_tlv, 21422 .extract_hw_mode_cap_service_ready_ext = 21423 extract_hw_mode_cap_service_ready_ext_tlv, 21424 .extract_mac_phy_cap_service_ready_ext = 21425 extract_mac_phy_cap_service_ready_ext_tlv, 21426 .extract_mac_phy_cap_service_ready_ext2 = 21427 extract_mac_phy_cap_service_ready_ext2_tlv, 21428 .extract_reg_cap_service_ready_ext = 21429 extract_reg_cap_service_ready_ext_tlv, 21430 .extract_hal_reg_cap_ext2 = extract_hal_reg_cap_ext2_tlv, 21431 .extract_dbr_ring_cap_service_ready_ext = 21432 extract_dbr_ring_cap_service_ready_ext_tlv, 21433 .extract_dbr_ring_cap_service_ready_ext2 = 21434 extract_dbr_ring_cap_service_ready_ext2_tlv, 21435 .extract_scan_radio_cap_service_ready_ext2 = 21436 extract_scan_radio_cap_service_ready_ext2_tlv, 21437 .extract_msdu_idx_qtype_map_service_ready_ext2 = 21438 extract_msdu_idx_qtype_map_service_ready_ext2_tlv, 21439 .extract_sw_cal_ver_ext2 = extract_sw_cal_ver_ext2_tlv, 21440 .extract_aux_dev_cap_service_ready_ext2 = 21441 extract_aux_dev_cap_service_ready_ext2_tlv, 21442 .extract_sar_cap_service_ready_ext = 21443 extract_sar_cap_service_ready_ext_tlv, 21444 .extract_pdev_utf_event = extract_pdev_utf_event_tlv, 21445 .wmi_set_htc_tx_tag = wmi_set_htc_tx_tag_tlv, 21446 .extract_fips_event_data = extract_fips_event_data_tlv, 21447 #ifdef WLAN_FEATURE_FIPS_BER_CCMGCM 21448 .extract_fips_extend_ev_data = extract_fips_extend_event_data_tlv, 21449 #endif 21450 #if defined(WLAN_SUPPORT_FILS) || defined(CONFIG_BAND_6GHZ) 21451 .send_vdev_fils_enable_cmd = send_vdev_fils_enable_cmd_send, 21452 #endif 21453 #ifdef WLAN_FEATURE_DISA 21454 .extract_encrypt_decrypt_resp_event = 21455 extract_encrypt_decrypt_resp_event_tlv, 21456 #endif 21457 .send_pdev_fips_cmd = send_pdev_fips_cmd_tlv, 21458 #ifdef WLAN_FEATURE_FIPS_BER_CCMGCM 21459 .send_pdev_fips_extend_cmd = send_pdev_fips_extend_cmd_tlv, 21460 .send_pdev_fips_mode_set_cmd = send_pdev_fips_mode_set_cmd_tlv, 21461 #endif 21462 .extract_get_pn_data = extract_get_pn_data_tlv, 21463 .send_pdev_get_pn_cmd = send_pdev_get_pn_cmd_tlv, 21464 .extract_get_rxpn_data = extract_get_rxpn_data_tlv, 21465 .send_pdev_get_rxpn_cmd = send_pdev_get_rxpn_cmd_tlv, 21466 .send_wlan_profile_enable_cmd = send_wlan_profile_enable_cmd_tlv, 21467 #ifdef WLAN_FEATURE_DISA 21468 .send_encrypt_decrypt_send_cmd = send_encrypt_decrypt_send_cmd_tlv, 21469 #endif 21470 .send_wlan_profile_trigger_cmd = send_wlan_profile_trigger_cmd_tlv, 21471 .send_wlan_profile_hist_intvl_cmd = 21472 send_wlan_profile_hist_intvl_cmd_tlv, 21473 .is_management_record = is_management_record_tlv, 21474 .is_diag_event = is_diag_event_tlv, 21475 #ifdef WLAN_FEATURE_ACTION_OUI 21476 .send_action_oui_cmd = send_action_oui_cmd_tlv, 21477 #endif 21478 .send_dfs_phyerr_offload_en_cmd = send_dfs_phyerr_offload_en_cmd_tlv, 21479 #ifdef QCA_SUPPORT_AGILE_DFS 21480 .send_adfs_ch_cfg_cmd = send_adfs_ch_cfg_cmd_tlv, 21481 .send_adfs_ocac_abort_cmd = send_adfs_ocac_abort_cmd_tlv, 21482 #endif 21483 .send_dfs_phyerr_offload_dis_cmd = send_dfs_phyerr_offload_dis_cmd_tlv, 21484 .extract_reg_chan_list_update_event = 21485 extract_reg_chan_list_update_event_tlv, 21486 #ifdef CONFIG_BAND_6GHZ 21487 .extract_reg_chan_list_ext_update_event = 21488 extract_reg_chan_list_ext_update_event_tlv, 21489 #ifdef CONFIG_AFC_SUPPORT 21490 .extract_afc_event = extract_afc_event_tlv, 21491 #endif 21492 #endif 21493 #ifdef WLAN_SUPPORT_RF_CHARACTERIZATION 21494 .extract_num_rf_characterization_entries = 21495 extract_num_rf_characterization_entries_tlv, 21496 .extract_rf_characterization_entries = 21497 extract_rf_characterization_entries_tlv, 21498 #endif 21499 .extract_chainmask_tables = 21500 extract_chainmask_tables_tlv, 21501 .extract_thermal_stats = extract_thermal_stats_tlv, 21502 .extract_thermal_level_stats = extract_thermal_level_stats_tlv, 21503 .send_get_rcpi_cmd = send_get_rcpi_cmd_tlv, 21504 .extract_rcpi_response_event = extract_rcpi_response_event_tlv, 21505 #ifdef DFS_COMPONENT_ENABLE 21506 .extract_dfs_cac_complete_event = extract_dfs_cac_complete_event_tlv, 21507 .extract_dfs_ocac_complete_event = extract_dfs_ocac_complete_event_tlv, 21508 .extract_dfs_radar_detection_event = 21509 extract_dfs_radar_detection_event_tlv, 21510 .extract_wlan_radar_event_info = extract_wlan_radar_event_info_tlv, 21511 #endif 21512 .convert_pdev_id_host_to_target = 21513 convert_host_pdev_id_to_target_pdev_id_legacy, 21514 .convert_pdev_id_target_to_host = 21515 convert_target_pdev_id_to_host_pdev_id_legacy, 21516 21517 .convert_host_pdev_id_to_target = 21518 convert_host_pdev_id_to_target_pdev_id, 21519 .convert_target_pdev_id_to_host = 21520 convert_target_pdev_id_to_host_pdev_id, 21521 21522 .convert_host_vdev_param_tlv = convert_host_vdev_param_tlv, 21523 21524 .convert_phy_id_host_to_target = 21525 convert_host_phy_id_to_target_phy_id_legacy, 21526 .convert_phy_id_target_to_host = 21527 convert_target_phy_id_to_host_phy_id_legacy, 21528 21529 .convert_host_phy_id_to_target = 21530 convert_host_phy_id_to_target_phy_id, 21531 .convert_target_phy_id_to_host = 21532 convert_target_phy_id_to_host_phy_id, 21533 21534 .send_start_11d_scan_cmd = send_start_11d_scan_cmd_tlv, 21535 .send_stop_11d_scan_cmd = send_stop_11d_scan_cmd_tlv, 21536 .extract_reg_11d_new_country_event = 21537 extract_reg_11d_new_country_event_tlv, 21538 .send_user_country_code_cmd = send_user_country_code_cmd_tlv, 21539 .extract_reg_ch_avoid_event = 21540 extract_reg_ch_avoid_event_tlv, 21541 .send_obss_detection_cfg_cmd = send_obss_detection_cfg_cmd_tlv, 21542 .extract_obss_detection_info = extract_obss_detection_info_tlv, 21543 .wmi_pdev_id_conversion_enable = wmi_tlv_pdev_id_conversion_enable, 21544 .wmi_free_allocated_event = wmitlv_free_allocated_event_tlvs, 21545 .wmi_check_and_pad_event = wmitlv_check_and_pad_event_tlvs, 21546 .wmi_check_command_params = wmitlv_check_command_tlv_params, 21547 .extract_comb_phyerr = extract_comb_phyerr_tlv, 21548 .extract_single_phyerr = extract_single_phyerr_tlv, 21549 #ifdef QCA_SUPPORT_CP_STATS 21550 .extract_cca_stats = extract_cca_stats_tlv, 21551 #endif 21552 .extract_esp_estimation_ev_param = 21553 extract_esp_estimation_ev_param_tlv, 21554 .send_roam_scan_stats_cmd = send_roam_scan_stats_cmd_tlv, 21555 .extract_roam_scan_stats_res_evt = extract_roam_scan_stats_res_evt_tlv, 21556 #ifdef OBSS_PD 21557 .send_obss_spatial_reuse_set = send_obss_spatial_reuse_set_cmd_tlv, 21558 .send_obss_spatial_reuse_set_def_thresh = 21559 send_obss_spatial_reuse_set_def_thresh_cmd_tlv, 21560 .send_self_srg_bss_color_bitmap_set = 21561 send_self_srg_bss_color_bitmap_set_cmd_tlv, 21562 .send_self_srg_partial_bssid_bitmap_set = 21563 send_self_srg_partial_bssid_bitmap_set_cmd_tlv, 21564 .send_self_srg_obss_color_enable_bitmap = 21565 send_self_srg_obss_color_enable_bitmap_cmd_tlv, 21566 .send_self_srg_obss_bssid_enable_bitmap = 21567 send_self_srg_obss_bssid_enable_bitmap_cmd_tlv, 21568 .send_self_non_srg_obss_color_enable_bitmap = 21569 send_self_non_srg_obss_color_enable_bitmap_cmd_tlv, 21570 .send_self_non_srg_obss_bssid_enable_bitmap = 21571 send_self_non_srg_obss_bssid_enable_bitmap_cmd_tlv, 21572 #endif 21573 .extract_offload_bcn_tx_status_evt = extract_offload_bcn_tx_status_evt, 21574 .extract_ctl_failsafe_check_ev_param = 21575 extract_ctl_failsafe_check_ev_param_tlv, 21576 #ifdef WIFI_POS_CONVERGED 21577 .extract_oem_response_param = extract_oem_response_param_tlv, 21578 #endif /* WIFI_POS_CONVERGED */ 21579 #if defined(WIFI_POS_CONVERGED) && defined(WLAN_FEATURE_RTT_11AZ_SUPPORT) 21580 .extract_pasn_peer_create_req_event = 21581 extract_pasn_peer_create_req_event_tlv, 21582 .extract_pasn_peer_delete_req_event = 21583 extract_pasn_peer_delete_req_event_tlv, 21584 .send_rtt_pasn_auth_status_cmd = 21585 send_rtt_pasn_auth_status_cmd_tlv, 21586 .send_rtt_pasn_deauth_cmd = 21587 send_rtt_pasn_deauth_cmd_tlv, 21588 #endif 21589 #ifdef WLAN_MWS_INFO_DEBUGFS 21590 .send_mws_coex_status_req_cmd = send_mws_coex_status_req_cmd_tlv, 21591 #endif 21592 .extract_hw_mode_resp_event = extract_hw_mode_resp_event_status_tlv, 21593 #ifdef FEATURE_ANI_LEVEL_REQUEST 21594 .send_ani_level_cmd = send_ani_level_cmd_tlv, 21595 .extract_ani_level = extract_ani_level_tlv, 21596 #endif /* FEATURE_ANI_LEVEL_REQUEST */ 21597 .extract_roam_trigger_stats = extract_roam_trigger_stats_tlv, 21598 .extract_roam_scan_stats = extract_roam_scan_stats_tlv, 21599 .extract_roam_result_stats = extract_roam_result_stats_tlv, 21600 .extract_roam_11kv_stats = extract_roam_11kv_stats_tlv, 21601 #ifdef WLAN_FEATURE_PKT_CAPTURE 21602 .extract_vdev_mgmt_offload_event = extract_vdev_mgmt_offload_event_tlv, 21603 #endif 21604 #ifdef WLAN_FEATURE_PKT_CAPTURE_V2 21605 .extract_smart_monitor_event = extract_smart_monitor_event_tlv, 21606 #endif 21607 21608 #ifdef FEATURE_WLAN_TIME_SYNC_FTM 21609 .send_wlan_time_sync_ftm_trigger_cmd = send_wlan_ts_ftm_trigger_cmd_tlv, 21610 .send_wlan_ts_qtime_cmd = send_wlan_ts_qtime_cmd_tlv, 21611 .extract_time_sync_ftm_start_stop_event = 21612 extract_time_sync_ftm_start_stop_event_tlv, 21613 .extract_time_sync_ftm_offset_event = 21614 extract_time_sync_ftm_offset_event_tlv, 21615 #endif /* FEATURE_WLAN_TIME_SYNC_FTM */ 21616 .send_roam_scan_ch_list_req_cmd = send_roam_scan_ch_list_req_cmd_tlv, 21617 .send_injector_config_cmd = send_injector_config_cmd_tlv, 21618 .send_cp_stats_cmd = send_cp_stats_cmd_tlv, 21619 .send_halphy_stats_cmd = send_halphy_stats_cmd_tlv, 21620 #ifdef FEATURE_MEC_OFFLOAD 21621 .send_pdev_set_mec_timer_cmd = send_pdev_set_mec_timer_cmd_tlv, 21622 #endif 21623 #if defined(WLAN_SUPPORT_INFRA_CTRL_PATH_STATS) || defined(WLAN_CONFIG_TELEMETRY_AGENT) 21624 .extract_infra_cp_stats = extract_infra_cp_stats_tlv, 21625 #endif /* WLAN_SUPPORT_INFRA_CTRL_PATH_STATS */ 21626 .extract_cp_stats_more_pending = 21627 extract_cp_stats_more_pending_tlv, 21628 .extract_halphy_stats_end_of_event = 21629 extract_halphy_stats_end_of_event_tlv, 21630 .extract_halphy_stats_event_count = 21631 extract_halphy_stats_event_count_tlv, 21632 .send_vdev_tsf_tstamp_action_cmd = send_vdev_tsf_tstamp_action_cmd_tlv, 21633 .extract_vdev_tsf_report_event = extract_vdev_tsf_report_event_tlv, 21634 .extract_pdev_csa_switch_count_status = 21635 extract_pdev_csa_switch_count_status_tlv, 21636 .send_set_tpc_power_cmd = send_set_tpc_power_cmd_tlv, 21637 #ifdef CONFIG_AFC_SUPPORT 21638 .send_afc_cmd = send_afc_cmd_tlv, 21639 #endif 21640 .extract_dpd_status_ev_param = extract_dpd_status_ev_param_tlv, 21641 .extract_install_key_comp_event = extract_install_key_comp_event_tlv, 21642 .send_vdev_set_ltf_key_seed_cmd = 21643 send_vdev_set_ltf_key_seed_cmd_tlv, 21644 .extract_halphy_cal_status_ev_param = extract_halphy_cal_status_ev_param_tlv, 21645 .send_set_halphy_cal = send_set_halphy_cal_tlv, 21646 .extract_halphy_cal_ev_param = extract_halphy_cal_ev_param_tlv, 21647 #ifdef WLAN_MGMT_RX_REO_SUPPORT 21648 .extract_mgmt_rx_fw_consumed = extract_mgmt_rx_fw_consumed_tlv, 21649 .extract_mgmt_rx_reo_params = extract_mgmt_rx_reo_params_tlv, 21650 .send_mgmt_rx_reo_filter_config_cmd = 21651 send_mgmt_rx_reo_filter_config_cmd_tlv, 21652 #endif 21653 21654 #ifdef WLAN_FEATURE_ROAM_OFFLOAD 21655 .send_roam_set_param_cmd = send_roam_set_param_cmd_tlv, 21656 #endif /* WLAN_FEATURE_ROAM_OFFLOAD */ 21657 21658 #ifdef WLAN_FEATURE_DYNAMIC_MAC_ADDR_UPDATE 21659 .send_set_mac_address_cmd = send_set_mac_address_cmd_tlv, 21660 .extract_update_mac_address_event = 21661 extract_update_mac_address_event_tlv, 21662 #endif 21663 21664 #ifdef WLAN_FEATURE_11BE_MLO 21665 .extract_quiet_offload_event = 21666 extract_quiet_offload_event_tlv, 21667 #endif 21668 21669 #ifdef WLAN_SUPPORT_PPEDS 21670 .peer_ppe_ds_param_send = peer_ppe_ds_param_send_tlv, 21671 #endif /* WLAN_SUPPORT_PPEDS */ 21672 21673 .send_vdev_pn_mgmt_rxfilter_cmd = send_vdev_pn_mgmt_rxfilter_cmd_tlv, 21674 .extract_pktlog_decode_info_event = 21675 extract_pktlog_decode_info_event_tlv, 21676 .extract_pdev_telemetry_stats = extract_pdev_telemetry_stats_tlv, 21677 .extract_mgmt_rx_ext_params = extract_mgmt_rx_ext_params_tlv, 21678 #ifdef WLAN_FEATURE_PEER_TXQ_FLUSH_CONF 21679 .send_peer_txq_flush_config_cmd = send_peer_txq_flush_config_cmd_tlv, 21680 #endif 21681 #ifdef WLAN_FEATURE_DBAM_CONFIG 21682 .send_dbam_config_cmd = send_dbam_config_cmd_tlv, 21683 .extract_dbam_config_resp_event = extract_dbam_config_resp_event_tlv, 21684 #endif 21685 #ifdef FEATURE_SET 21686 .feature_set_cmd_send = feature_set_cmd_send_tlv, 21687 #endif 21688 #ifdef HEALTH_MON_SUPPORT 21689 .extract_health_mon_init_done_info_event = 21690 extract_health_mon_init_done_info_event_tlv, 21691 #endif /* HEALTH_MON_SUPPORT */ 21692 .send_multiple_vdev_param_cmd = send_multiple_vdev_param_cmd_tlv, 21693 .set_mac_addr_rx_filter = send_set_mac_addr_rx_filter_cmd_tlv, 21694 .send_update_edca_pifs_param_cmd = 21695 send_update_edca_pifs_param_cmd_tlv, 21696 .extract_sap_coex_cap_service_ready_ext2 = 21697 extract_sap_coex_fix_chan_caps, 21698 .extract_tgtr2p_table_event = extract_tgtr2p_table_event_tlv, 21699 .send_egid_info_cmd = send_egid_info_cmd_tlv, 21700 .extract_csa_ie_received_ev_params = 21701 extract_csa_ie_received_ev_params_tlv, 21702 .extract_rf_path_resp = extract_rf_path_resp_tlv, 21703 #ifdef WLAN_RCC_ENHANCED_AOA_SUPPORT 21704 .extract_aoa_caps_service_ready_ext2 = 21705 extract_aoa_caps_tlv, 21706 #endif /* WLAN_RCC_ENHANCED_AOA_SUPPORT */ 21707 }; 21708 21709 #ifdef WLAN_FEATURE_11BE_MLO 21710 static void populate_tlv_events_id_mlo(WMI_EVT_ID *event_ids) 21711 { 21712 event_ids[wmi_mlo_setup_complete_event_id] = 21713 WMI_MLO_SETUP_COMPLETE_EVENTID; 21714 event_ids[wmi_mlo_teardown_complete_event_id] = 21715 WMI_MLO_TEARDOWN_COMPLETE_EVENTID; 21716 event_ids[wmi_mlo_link_set_active_resp_eventid] = 21717 WMI_MLO_LINK_SET_ACTIVE_RESP_EVENTID; 21718 event_ids[wmi_vdev_quiet_offload_eventid] = 21719 WMI_QUIET_HANDLING_EVENTID; 21720 event_ids[wmi_mlo_ap_vdev_tid_to_link_map_eventid] = 21721 WMI_MLO_AP_VDEV_TID_TO_LINK_MAP_EVENTID; 21722 event_ids[wmi_mlo_link_removal_eventid] = 21723 WMI_MLO_LINK_REMOVAL_EVENTID; 21724 event_ids[wmi_mlo_link_state_info_eventid] = 21725 WMI_MLO_VDEV_LINK_INFO_EVENTID; 21726 event_ids[wmi_mlo_link_disable_request_eventid] = 21727 WMI_MLO_LINK_DISABLE_REQUEST_EVENTID; 21728 #ifdef WLAN_FEATURE_11BE_MLO_ADV_FEATURE 21729 event_ids[wmi_mlo_link_switch_request_eventid] = 21730 WMI_MLO_LINK_SWITCH_REQUEST_EVENTID; 21731 event_ids[wmi_mlo_link_state_switch_eventid] = 21732 WMI_MLO_LINK_STATE_SWITCH_EVENTID; 21733 #endif /* WLAN_FEATURE_11BE_MLO_ADV_FEATURE */ 21734 } 21735 #else /* WLAN_FEATURE_11BE_MLO */ 21736 static inline void populate_tlv_events_id_mlo(WMI_EVT_ID *event_ids) 21737 { 21738 } 21739 #endif /* WLAN_FEATURE_11BE_MLO */ 21740 21741 /** 21742 * populate_tlv_events_id() - populates wmi event ids 21743 * @event_ids: Pointer to hold event ids 21744 * 21745 * Return: None 21746 */ 21747 static void populate_tlv_events_id(WMI_EVT_ID *event_ids) 21748 { 21749 event_ids[wmi_service_ready_event_id] = WMI_SERVICE_READY_EVENTID; 21750 event_ids[wmi_ready_event_id] = WMI_READY_EVENTID; 21751 event_ids[wmi_scan_event_id] = WMI_SCAN_EVENTID; 21752 event_ids[wmi_pdev_tpc_config_event_id] = WMI_PDEV_TPC_CONFIG_EVENTID; 21753 event_ids[wmi_chan_info_event_id] = WMI_CHAN_INFO_EVENTID; 21754 event_ids[wmi_phyerr_event_id] = WMI_PHYERR_EVENTID; 21755 event_ids[wmi_pdev_dump_event_id] = WMI_PDEV_DUMP_EVENTID; 21756 event_ids[wmi_tx_pause_event_id] = WMI_TX_PAUSE_EVENTID; 21757 event_ids[wmi_dfs_radar_event_id] = WMI_DFS_RADAR_EVENTID; 21758 event_ids[wmi_pdev_l1ss_track_event_id] = WMI_PDEV_L1SS_TRACK_EVENTID; 21759 event_ids[wmi_pdev_temperature_event_id] = WMI_PDEV_TEMPERATURE_EVENTID; 21760 event_ids[wmi_service_ready_ext_event_id] = 21761 WMI_SERVICE_READY_EXT_EVENTID; 21762 event_ids[wmi_service_ready_ext2_event_id] = 21763 WMI_SERVICE_READY_EXT2_EVENTID; 21764 event_ids[wmi_vdev_start_resp_event_id] = WMI_VDEV_START_RESP_EVENTID; 21765 event_ids[wmi_vdev_stopped_event_id] = WMI_VDEV_STOPPED_EVENTID; 21766 event_ids[wmi_vdev_install_key_complete_event_id] = 21767 WMI_VDEV_INSTALL_KEY_COMPLETE_EVENTID; 21768 event_ids[wmi_vdev_mcc_bcn_intvl_change_req_event_id] = 21769 WMI_VDEV_MCC_BCN_INTERVAL_CHANGE_REQ_EVENTID; 21770 21771 event_ids[wmi_vdev_tsf_report_event_id] = WMI_VDEV_TSF_REPORT_EVENTID; 21772 event_ids[wmi_peer_sta_kickout_event_id] = WMI_PEER_STA_KICKOUT_EVENTID; 21773 event_ids[wmi_peer_info_event_id] = WMI_PEER_INFO_EVENTID; 21774 event_ids[wmi_peer_tx_fail_cnt_thr_event_id] = 21775 WMI_PEER_TX_FAIL_CNT_THR_EVENTID; 21776 event_ids[wmi_peer_estimated_linkspeed_event_id] = 21777 WMI_PEER_ESTIMATED_LINKSPEED_EVENTID; 21778 event_ids[wmi_peer_state_event_id] = WMI_PEER_STATE_EVENTID; 21779 event_ids[wmi_peer_create_conf_event_id] = 21780 WMI_PEER_CREATE_CONF_EVENTID; 21781 event_ids[wmi_peer_delete_response_event_id] = 21782 WMI_PEER_DELETE_RESP_EVENTID; 21783 event_ids[wmi_peer_delete_all_response_event_id] = 21784 WMI_VDEV_DELETE_ALL_PEER_RESP_EVENTID; 21785 event_ids[wmi_peer_oper_mode_change_event_id] = 21786 WMI_PEER_OPER_MODE_CHANGE_EVENTID; 21787 event_ids[wmi_mgmt_rx_event_id] = WMI_MGMT_RX_EVENTID; 21788 event_ids[wmi_host_swba_event_id] = WMI_HOST_SWBA_EVENTID; 21789 event_ids[wmi_tbttoffset_update_event_id] = 21790 WMI_TBTTOFFSET_UPDATE_EVENTID; 21791 event_ids[wmi_ext_tbttoffset_update_event_id] = 21792 WMI_TBTTOFFSET_EXT_UPDATE_EVENTID; 21793 event_ids[wmi_offload_bcn_tx_status_event_id] = 21794 WMI_OFFLOAD_BCN_TX_STATUS_EVENTID; 21795 event_ids[wmi_offload_prob_resp_tx_status_event_id] = 21796 WMI_OFFLOAD_PROB_RESP_TX_STATUS_EVENTID; 21797 event_ids[wmi_mgmt_tx_completion_event_id] = 21798 WMI_MGMT_TX_COMPLETION_EVENTID; 21799 event_ids[wmi_pdev_nfcal_power_all_channels_event_id] = 21800 WMI_PDEV_NFCAL_POWER_ALL_CHANNELS_EVENTID; 21801 event_ids[wmi_tx_delba_complete_event_id] = 21802 WMI_TX_DELBA_COMPLETE_EVENTID; 21803 event_ids[wmi_tx_addba_complete_event_id] = 21804 WMI_TX_ADDBA_COMPLETE_EVENTID; 21805 event_ids[wmi_ba_rsp_ssn_event_id] = WMI_BA_RSP_SSN_EVENTID; 21806 21807 event_ids[wmi_aggr_state_trig_event_id] = WMI_AGGR_STATE_TRIG_EVENTID; 21808 21809 event_ids[wmi_roam_event_id] = WMI_ROAM_EVENTID; 21810 event_ids[wmi_profile_match] = WMI_PROFILE_MATCH; 21811 21812 event_ids[wmi_roam_synch_event_id] = WMI_ROAM_SYNCH_EVENTID; 21813 event_ids[wmi_roam_synch_frame_event_id] = WMI_ROAM_SYNCH_FRAME_EVENTID; 21814 21815 event_ids[wmi_p2p_disc_event_id] = WMI_P2P_DISC_EVENTID; 21816 21817 event_ids[wmi_p2p_noa_event_id] = WMI_P2P_NOA_EVENTID; 21818 event_ids[wmi_p2p_lo_stop_event_id] = 21819 WMI_P2P_LISTEN_OFFLOAD_STOPPED_EVENTID; 21820 event_ids[wmi_vdev_add_macaddr_rx_filter_event_id] = 21821 WMI_VDEV_ADD_MAC_ADDR_TO_RX_FILTER_STATUS_EVENTID; 21822 event_ids[wmi_pdev_resume_event_id] = WMI_PDEV_RESUME_EVENTID; 21823 event_ids[wmi_wow_wakeup_host_event_id] = WMI_WOW_WAKEUP_HOST_EVENTID; 21824 event_ids[wmi_d0_wow_disable_ack_event_id] = 21825 WMI_D0_WOW_DISABLE_ACK_EVENTID; 21826 event_ids[wmi_wow_initial_wakeup_event_id] = 21827 WMI_WOW_INITIAL_WAKEUP_EVENTID; 21828 21829 event_ids[wmi_rtt_meas_report_event_id] = 21830 WMI_RTT_MEASUREMENT_REPORT_EVENTID; 21831 event_ids[wmi_tsf_meas_report_event_id] = 21832 WMI_TSF_MEASUREMENT_REPORT_EVENTID; 21833 event_ids[wmi_rtt_error_report_event_id] = WMI_RTT_ERROR_REPORT_EVENTID; 21834 event_ids[wmi_stats_ext_event_id] = WMI_STATS_EXT_EVENTID; 21835 event_ids[wmi_iface_link_stats_event_id] = WMI_IFACE_LINK_STATS_EVENTID; 21836 event_ids[wmi_peer_link_stats_event_id] = WMI_PEER_LINK_STATS_EVENTID; 21837 event_ids[wmi_radio_link_stats_link] = WMI_RADIO_LINK_STATS_EVENTID; 21838 event_ids[wmi_diag_event_id_log_supported_event_id] = 21839 WMI_DIAG_EVENT_LOG_SUPPORTED_EVENTID; 21840 event_ids[wmi_nlo_match_event_id] = WMI_NLO_MATCH_EVENTID; 21841 event_ids[wmi_nlo_scan_complete_event_id] = 21842 WMI_NLO_SCAN_COMPLETE_EVENTID; 21843 event_ids[wmi_apfind_event_id] = WMI_APFIND_EVENTID; 21844 event_ids[wmi_passpoint_match_event_id] = WMI_PASSPOINT_MATCH_EVENTID; 21845 21846 event_ids[wmi_gtk_offload_status_event_id] = 21847 WMI_GTK_OFFLOAD_STATUS_EVENTID; 21848 event_ids[wmi_gtk_rekey_fail_event_id] = WMI_GTK_REKEY_FAIL_EVENTID; 21849 event_ids[wmi_csa_handling_event_id] = WMI_CSA_HANDLING_EVENTID; 21850 event_ids[wmi_chatter_pc_query_event_id] = WMI_CHATTER_PC_QUERY_EVENTID; 21851 21852 event_ids[wmi_echo_event_id] = WMI_ECHO_EVENTID; 21853 21854 event_ids[wmi_pdev_utf_event_id] = WMI_PDEV_UTF_EVENTID; 21855 21856 event_ids[wmi_dbg_msg_event_id] = WMI_DEBUG_MESG_EVENTID; 21857 event_ids[wmi_update_stats_event_id] = WMI_UPDATE_STATS_EVENTID; 21858 event_ids[wmi_debug_print_event_id] = WMI_DEBUG_PRINT_EVENTID; 21859 event_ids[wmi_dcs_interference_event_id] = WMI_DCS_INTERFERENCE_EVENTID; 21860 event_ids[wmi_pdev_qvit_event_id] = WMI_PDEV_QVIT_EVENTID; 21861 event_ids[wmi_wlan_profile_data_event_id] = 21862 WMI_WLAN_PROFILE_DATA_EVENTID; 21863 event_ids[wmi_pdev_ftm_intg_event_id] = WMI_PDEV_FTM_INTG_EVENTID; 21864 event_ids[wmi_wlan_freq_avoid_event_id] = WMI_WLAN_FREQ_AVOID_EVENTID; 21865 event_ids[wmi_vdev_get_keepalive_event_id] = 21866 WMI_VDEV_GET_KEEPALIVE_EVENTID; 21867 event_ids[wmi_thermal_mgmt_event_id] = WMI_THERMAL_MGMT_EVENTID; 21868 21869 event_ids[wmi_diag_container_event_id] = 21870 WMI_DIAG_DATA_CONTAINER_EVENTID; 21871 21872 event_ids[wmi_host_auto_shutdown_event_id] = 21873 WMI_HOST_AUTO_SHUTDOWN_EVENTID; 21874 21875 event_ids[wmi_update_whal_mib_stats_event_id] = 21876 WMI_UPDATE_WHAL_MIB_STATS_EVENTID; 21877 21878 /*update ht/vht info based on vdev (rx and tx NSS and preamble) */ 21879 event_ids[wmi_update_vdev_rate_stats_event_id] = 21880 WMI_UPDATE_VDEV_RATE_STATS_EVENTID; 21881 21882 event_ids[wmi_diag_event_id] = WMI_DIAG_EVENTID; 21883 event_ids[wmi_unit_test_event_id] = WMI_UNIT_TEST_EVENTID; 21884 21885 /** Set OCB Sched Response, deprecated */ 21886 event_ids[wmi_ocb_set_sched_event_id] = WMI_OCB_SET_SCHED_EVENTID; 21887 21888 event_ids[wmi_dbg_mesg_flush_complete_event_id] = 21889 WMI_DEBUG_MESG_FLUSH_COMPLETE_EVENTID; 21890 event_ids[wmi_rssi_breach_event_id] = WMI_RSSI_BREACH_EVENTID; 21891 21892 /* GPIO Event */ 21893 event_ids[wmi_gpio_input_event_id] = WMI_GPIO_INPUT_EVENTID; 21894 event_ids[wmi_uploadh_event_id] = WMI_UPLOADH_EVENTID; 21895 21896 event_ids[wmi_captureh_event_id] = WMI_CAPTUREH_EVENTID; 21897 event_ids[wmi_rfkill_state_change_event_id] = 21898 WMI_RFKILL_STATE_CHANGE_EVENTID; 21899 21900 /* TDLS Event */ 21901 event_ids[wmi_tdls_peer_event_id] = WMI_TDLS_PEER_EVENTID; 21902 21903 event_ids[wmi_batch_scan_enabled_event_id] = 21904 WMI_BATCH_SCAN_ENABLED_EVENTID; 21905 event_ids[wmi_batch_scan_result_event_id] = 21906 WMI_BATCH_SCAN_RESULT_EVENTID; 21907 /* OEM Event */ 21908 event_ids[wmi_oem_cap_event_id] = WMI_OEM_CAPABILITY_EVENTID; 21909 event_ids[wmi_oem_meas_report_event_id] = 21910 WMI_OEM_MEASUREMENT_REPORT_EVENTID; 21911 event_ids[wmi_oem_report_event_id] = WMI_OEM_ERROR_REPORT_EVENTID; 21912 21913 /* NAN Event */ 21914 event_ids[wmi_nan_event_id] = WMI_NAN_EVENTID; 21915 21916 /* LPI Event */ 21917 event_ids[wmi_lpi_result_event_id] = WMI_LPI_RESULT_EVENTID; 21918 event_ids[wmi_lpi_status_event_id] = WMI_LPI_STATUS_EVENTID; 21919 event_ids[wmi_lpi_handoff_event_id] = WMI_LPI_HANDOFF_EVENTID; 21920 21921 /* ExtScan events */ 21922 event_ids[wmi_extscan_start_stop_event_id] = 21923 WMI_EXTSCAN_START_STOP_EVENTID; 21924 event_ids[wmi_extscan_operation_event_id] = 21925 WMI_EXTSCAN_OPERATION_EVENTID; 21926 event_ids[wmi_extscan_table_usage_event_id] = 21927 WMI_EXTSCAN_TABLE_USAGE_EVENTID; 21928 event_ids[wmi_extscan_cached_results_event_id] = 21929 WMI_EXTSCAN_CACHED_RESULTS_EVENTID; 21930 event_ids[wmi_extscan_wlan_change_results_event_id] = 21931 WMI_EXTSCAN_WLAN_CHANGE_RESULTS_EVENTID; 21932 event_ids[wmi_extscan_hotlist_match_event_id] = 21933 WMI_EXTSCAN_HOTLIST_MATCH_EVENTID; 21934 event_ids[wmi_extscan_capabilities_event_id] = 21935 WMI_EXTSCAN_CAPABILITIES_EVENTID; 21936 event_ids[wmi_extscan_hotlist_ssid_match_event_id] = 21937 WMI_EXTSCAN_HOTLIST_SSID_MATCH_EVENTID; 21938 21939 /* mDNS offload events */ 21940 event_ids[wmi_mdns_stats_event_id] = WMI_MDNS_STATS_EVENTID; 21941 21942 /* SAP Authentication offload events */ 21943 event_ids[wmi_sap_ofl_add_sta_event_id] = WMI_SAP_OFL_ADD_STA_EVENTID; 21944 event_ids[wmi_sap_ofl_del_sta_event_id] = WMI_SAP_OFL_DEL_STA_EVENTID; 21945 21946 /** Out-of-context-of-bss (OCB) events */ 21947 event_ids[wmi_ocb_set_config_resp_event_id] = 21948 WMI_OCB_SET_CONFIG_RESP_EVENTID; 21949 event_ids[wmi_ocb_get_tsf_timer_resp_event_id] = 21950 WMI_OCB_GET_TSF_TIMER_RESP_EVENTID; 21951 event_ids[wmi_dcc_get_stats_resp_event_id] = 21952 WMI_DCC_GET_STATS_RESP_EVENTID; 21953 event_ids[wmi_dcc_update_ndl_resp_event_id] = 21954 WMI_DCC_UPDATE_NDL_RESP_EVENTID; 21955 event_ids[wmi_dcc_stats_event_id] = WMI_DCC_STATS_EVENTID; 21956 /* System-On-Chip events */ 21957 event_ids[wmi_soc_set_hw_mode_resp_event_id] = 21958 WMI_SOC_SET_HW_MODE_RESP_EVENTID; 21959 event_ids[wmi_soc_hw_mode_transition_event_id] = 21960 WMI_SOC_HW_MODE_TRANSITION_EVENTID; 21961 event_ids[wmi_soc_set_dual_mac_config_resp_event_id] = 21962 WMI_SOC_SET_DUAL_MAC_CONFIG_RESP_EVENTID; 21963 event_ids[wmi_pdev_fips_event_id] = WMI_PDEV_FIPS_EVENTID; 21964 #ifdef WLAN_FEATURE_FIPS_BER_CCMGCM 21965 event_ids[wmi_pdev_fips_extend_event_id] = WMI_PDEV_FIPS_EXTEND_EVENTID; 21966 #endif 21967 event_ids[wmi_pdev_csa_switch_count_status_event_id] = 21968 WMI_PDEV_CSA_SWITCH_COUNT_STATUS_EVENTID; 21969 event_ids[wmi_vdev_ocac_complete_event_id] = 21970 WMI_VDEV_ADFS_OCAC_COMPLETE_EVENTID; 21971 event_ids[wmi_reg_chan_list_cc_event_id] = WMI_REG_CHAN_LIST_CC_EVENTID; 21972 event_ids[wmi_reg_chan_list_cc_ext_event_id] = 21973 WMI_REG_CHAN_LIST_CC_EXT_EVENTID; 21974 #ifdef CONFIG_AFC_SUPPORT 21975 event_ids[wmi_afc_event_id] = WMI_AFC_EVENTID, 21976 #endif 21977 event_ids[wmi_inst_rssi_stats_event_id] = WMI_INST_RSSI_STATS_EVENTID; 21978 event_ids[wmi_pdev_tpc_config_event_id] = WMI_PDEV_TPC_CONFIG_EVENTID; 21979 event_ids[wmi_peer_sta_ps_statechg_event_id] = 21980 WMI_PEER_STA_PS_STATECHG_EVENTID; 21981 event_ids[wmi_pdev_channel_hopping_event_id] = 21982 WMI_PDEV_CHANNEL_HOPPING_EVENTID; 21983 event_ids[wmi_offchan_data_tx_completion_event] = 21984 WMI_OFFCHAN_DATA_TX_COMPLETION_EVENTID; 21985 event_ids[wmi_dfs_cac_complete_id] = WMI_VDEV_DFS_CAC_COMPLETE_EVENTID; 21986 event_ids[wmi_dfs_radar_detection_event_id] = 21987 WMI_PDEV_DFS_RADAR_DETECTION_EVENTID; 21988 event_ids[wmi_tt_stats_event_id] = WMI_THERM_THROT_STATS_EVENTID; 21989 event_ids[wmi_11d_new_country_event_id] = WMI_11D_NEW_COUNTRY_EVENTID; 21990 event_ids[wmi_pdev_tpc_event_id] = WMI_PDEV_TPC_EVENTID; 21991 event_ids[wmi_get_arp_stats_req_id] = WMI_VDEV_GET_ARP_STAT_EVENTID; 21992 event_ids[wmi_service_available_event_id] = 21993 WMI_SERVICE_AVAILABLE_EVENTID; 21994 event_ids[wmi_update_rcpi_event_id] = WMI_UPDATE_RCPI_EVENTID; 21995 event_ids[wmi_pdev_check_cal_version_event_id] = WMI_PDEV_CHECK_CAL_VERSION_EVENTID; 21996 /* NDP events */ 21997 event_ids[wmi_ndp_initiator_rsp_event_id] = 21998 WMI_NDP_INITIATOR_RSP_EVENTID; 21999 event_ids[wmi_ndp_indication_event_id] = WMI_NDP_INDICATION_EVENTID; 22000 event_ids[wmi_ndp_confirm_event_id] = WMI_NDP_CONFIRM_EVENTID; 22001 event_ids[wmi_ndp_responder_rsp_event_id] = 22002 WMI_NDP_RESPONDER_RSP_EVENTID; 22003 event_ids[wmi_ndp_end_indication_event_id] = 22004 WMI_NDP_END_INDICATION_EVENTID; 22005 event_ids[wmi_ndp_end_rsp_event_id] = WMI_NDP_END_RSP_EVENTID; 22006 event_ids[wmi_ndl_schedule_update_event_id] = 22007 WMI_NDL_SCHEDULE_UPDATE_EVENTID; 22008 event_ids[wmi_ndp_event_id] = WMI_NDP_EVENTID; 22009 22010 event_ids[wmi_oem_response_event_id] = WMI_OEM_RESPONSE_EVENTID; 22011 event_ids[wmi_peer_stats_info_event_id] = WMI_PEER_STATS_INFO_EVENTID; 22012 event_ids[wmi_pdev_chip_power_stats_event_id] = 22013 WMI_PDEV_CHIP_POWER_STATS_EVENTID; 22014 event_ids[wmi_ap_ps_egap_info_event_id] = WMI_AP_PS_EGAP_INFO_EVENTID; 22015 event_ids[wmi_peer_assoc_conf_event_id] = WMI_PEER_ASSOC_CONF_EVENTID; 22016 event_ids[wmi_vdev_delete_resp_event_id] = WMI_VDEV_DELETE_RESP_EVENTID; 22017 event_ids[wmi_apf_capability_info_event_id] = 22018 WMI_BPF_CAPABILIY_INFO_EVENTID; 22019 event_ids[wmi_vdev_encrypt_decrypt_data_rsp_event_id] = 22020 WMI_VDEV_ENCRYPT_DECRYPT_DATA_RESP_EVENTID; 22021 event_ids[wmi_report_rx_aggr_failure_event_id] = 22022 WMI_REPORT_RX_AGGR_FAILURE_EVENTID; 22023 event_ids[wmi_pdev_chip_pwr_save_failure_detect_event_id] = 22024 WMI_PDEV_CHIP_POWER_SAVE_FAILURE_DETECTED_EVENTID; 22025 event_ids[wmi_peer_antdiv_info_event_id] = WMI_PEER_ANTDIV_INFO_EVENTID; 22026 event_ids[wmi_pdev_set_hw_mode_rsp_event_id] = 22027 WMI_PDEV_SET_HW_MODE_RESP_EVENTID; 22028 event_ids[wmi_pdev_hw_mode_transition_event_id] = 22029 WMI_PDEV_HW_MODE_TRANSITION_EVENTID; 22030 event_ids[wmi_pdev_set_mac_config_resp_event_id] = 22031 WMI_PDEV_SET_MAC_CONFIG_RESP_EVENTID; 22032 event_ids[wmi_coex_bt_activity_event_id] = 22033 WMI_WLAN_COEX_BT_ACTIVITY_EVENTID; 22034 event_ids[wmi_mgmt_tx_bundle_completion_event_id] = 22035 WMI_MGMT_TX_BUNDLE_COMPLETION_EVENTID; 22036 event_ids[wmi_radio_tx_power_level_stats_event_id] = 22037 WMI_RADIO_TX_POWER_LEVEL_STATS_EVENTID; 22038 event_ids[wmi_report_stats_event_id] = WMI_REPORT_STATS_EVENTID; 22039 event_ids[wmi_dma_buf_release_event_id] = 22040 WMI_PDEV_DMA_RING_BUF_RELEASE_EVENTID; 22041 event_ids[wmi_sap_obss_detection_report_event_id] = 22042 WMI_SAP_OBSS_DETECTION_REPORT_EVENTID; 22043 event_ids[wmi_host_swfda_event_id] = WMI_HOST_SWFDA_EVENTID; 22044 event_ids[wmi_sar_get_limits_event_id] = WMI_SAR_GET_LIMITS_EVENTID; 22045 event_ids[wmi_obss_color_collision_report_event_id] = 22046 WMI_OBSS_COLOR_COLLISION_DETECTION_EVENTID; 22047 event_ids[wmi_pdev_div_rssi_antid_event_id] = 22048 WMI_PDEV_DIV_RSSI_ANTID_EVENTID; 22049 #ifdef WLAN_SUPPORT_TWT 22050 event_ids[wmi_twt_enable_complete_event_id] = 22051 WMI_TWT_ENABLE_COMPLETE_EVENTID; 22052 event_ids[wmi_twt_disable_complete_event_id] = 22053 WMI_TWT_DISABLE_COMPLETE_EVENTID; 22054 event_ids[wmi_twt_add_dialog_complete_event_id] = 22055 WMI_TWT_ADD_DIALOG_COMPLETE_EVENTID; 22056 event_ids[wmi_twt_del_dialog_complete_event_id] = 22057 WMI_TWT_DEL_DIALOG_COMPLETE_EVENTID; 22058 event_ids[wmi_twt_pause_dialog_complete_event_id] = 22059 WMI_TWT_PAUSE_DIALOG_COMPLETE_EVENTID; 22060 event_ids[wmi_twt_resume_dialog_complete_event_id] = 22061 WMI_TWT_RESUME_DIALOG_COMPLETE_EVENTID; 22062 event_ids[wmi_twt_nudge_dialog_complete_event_id] = 22063 WMI_TWT_NUDGE_DIALOG_COMPLETE_EVENTID; 22064 event_ids[wmi_twt_session_stats_event_id] = 22065 WMI_TWT_SESSION_STATS_EVENTID; 22066 event_ids[wmi_twt_notify_event_id] = 22067 WMI_TWT_NOTIFY_EVENTID; 22068 event_ids[wmi_twt_ack_complete_event_id] = 22069 WMI_TWT_ACK_EVENTID; 22070 #endif 22071 event_ids[wmi_apf_get_vdev_work_memory_resp_event_id] = 22072 WMI_BPF_GET_VDEV_WORK_MEMORY_RESP_EVENTID; 22073 event_ids[wmi_wlan_sar2_result_event_id] = WMI_SAR2_RESULT_EVENTID; 22074 event_ids[wmi_esp_estimate_event_id] = WMI_ESP_ESTIMATE_EVENTID; 22075 event_ids[wmi_roam_scan_stats_event_id] = WMI_ROAM_SCAN_STATS_EVENTID; 22076 #ifdef WLAN_FEATURE_INTEROP_ISSUES_AP 22077 event_ids[wmi_pdev_interop_issues_ap_event_id] = 22078 WMI_PDEV_RAP_INFO_EVENTID; 22079 #endif 22080 #ifdef AST_HKV1_WORKAROUND 22081 event_ids[wmi_wds_peer_event_id] = WMI_WDS_PEER_EVENTID; 22082 #endif 22083 event_ids[wmi_pdev_ctl_failsafe_check_event_id] = 22084 WMI_PDEV_CTL_FAILSAFE_CHECK_EVENTID; 22085 event_ids[wmi_vdev_bcn_reception_stats_event_id] = 22086 WMI_VDEV_BCN_RECEPTION_STATS_EVENTID; 22087 event_ids[wmi_roam_denylist_event_id] = WMI_ROAM_BLACKLIST_EVENTID; 22088 event_ids[wmi_wlm_stats_event_id] = WMI_WLM_STATS_EVENTID; 22089 event_ids[wmi_peer_cfr_capture_event_id] = WMI_PEER_CFR_CAPTURE_EVENTID; 22090 event_ids[wmi_pdev_cold_boot_cal_event_id] = 22091 WMI_PDEV_COLD_BOOT_CAL_DATA_EVENTID; 22092 #ifdef WLAN_MWS_INFO_DEBUGFS 22093 event_ids[wmi_vdev_get_mws_coex_state_eventid] = 22094 WMI_VDEV_GET_MWS_COEX_STATE_EVENTID; 22095 event_ids[wmi_vdev_get_mws_coex_dpwb_state_eventid] = 22096 WMI_VDEV_GET_MWS_COEX_DPWB_STATE_EVENTID; 22097 event_ids[wmi_vdev_get_mws_coex_tdm_state_eventid] = 22098 WMI_VDEV_GET_MWS_COEX_TDM_STATE_EVENTID; 22099 event_ids[wmi_vdev_get_mws_coex_idrx_state_eventid] = 22100 WMI_VDEV_GET_MWS_COEX_IDRX_STATE_EVENTID; 22101 event_ids[wmi_vdev_get_mws_coex_antenna_sharing_state_eventid] = 22102 WMI_VDEV_GET_MWS_COEX_ANTENNA_SHARING_STATE_EVENTID; 22103 #endif 22104 event_ids[wmi_coex_report_antenna_isolation_event_id] = 22105 WMI_COEX_REPORT_ANTENNA_ISOLATION_EVENTID; 22106 event_ids[wmi_peer_ratecode_list_event_id] = 22107 WMI_PEER_RATECODE_LIST_EVENTID; 22108 event_ids[wmi_chan_rf_characterization_info_event_id] = 22109 WMI_CHAN_RF_CHARACTERIZATION_INFO_EVENTID; 22110 event_ids[wmi_roam_auth_offload_event_id] = 22111 WMI_ROAM_PREAUTH_START_EVENTID; 22112 event_ids[wmi_get_elna_bypass_event_id] = WMI_GET_ELNA_BYPASS_EVENTID; 22113 event_ids[wmi_motion_det_host_eventid] = WMI_MOTION_DET_HOST_EVENTID; 22114 event_ids[wmi_motion_det_base_line_host_eventid] = 22115 WMI_MOTION_DET_BASE_LINE_HOST_EVENTID; 22116 event_ids[wmi_get_ani_level_event_id] = WMI_GET_CHANNEL_ANI_EVENTID; 22117 event_ids[wmi_peer_tx_pn_response_event_id] = 22118 WMI_PEER_TX_PN_RESPONSE_EVENTID; 22119 event_ids[wmi_roam_stats_event_id] = WMI_ROAM_STATS_EVENTID; 22120 event_ids[wmi_oem_data_event_id] = WMI_OEM_DATA_EVENTID; 22121 event_ids[wmi_mgmt_offload_data_event_id] = 22122 WMI_VDEV_MGMT_OFFLOAD_EVENTID; 22123 event_ids[wmi_nan_dmesg_event_id] = 22124 WMI_NAN_DMESG_EVENTID; 22125 event_ids[wmi_pdev_multi_vdev_restart_response_event_id] = 22126 WMI_PDEV_MULTIPLE_VDEV_RESTART_RESP_EVENTID; 22127 event_ids[wmi_roam_pmkid_request_event_id] = 22128 WMI_ROAM_PMKID_REQUEST_EVENTID; 22129 #ifdef FEATURE_WLAN_TIME_SYNC_FTM 22130 event_ids[wmi_wlan_time_sync_ftm_start_stop_event_id] = 22131 WMI_VDEV_AUDIO_SYNC_START_STOP_EVENTID; 22132 event_ids[wmi_wlan_time_sync_q_initiator_target_offset_eventid] = 22133 WMI_VDEV_AUDIO_SYNC_Q_MASTER_SLAVE_OFFSET_EVENTID; 22134 #endif 22135 event_ids[wmi_roam_scan_chan_list_id] = 22136 WMI_ROAM_SCAN_CHANNEL_LIST_EVENTID; 22137 event_ids[wmi_muedca_params_config_eventid] = 22138 WMI_MUEDCA_PARAMS_CONFIG_EVENTID; 22139 event_ids[wmi_pdev_sscan_fw_param_eventid] = 22140 WMI_PDEV_SSCAN_FW_PARAM_EVENTID; 22141 event_ids[wmi_roam_cap_report_event_id] = 22142 WMI_ROAM_CAPABILITY_REPORT_EVENTID; 22143 event_ids[wmi_vdev_bcn_latency_event_id] = 22144 WMI_VDEV_BCN_LATENCY_EVENTID; 22145 event_ids[wmi_vdev_disconnect_event_id] = 22146 WMI_VDEV_DISCONNECT_EVENTID; 22147 event_ids[wmi_peer_create_conf_event_id] = 22148 WMI_PEER_CREATE_CONF_EVENTID; 22149 event_ids[wmi_pdev_cp_fwstats_eventid] = 22150 WMI_CTRL_PATH_STATS_EVENTID; 22151 event_ids[wmi_pdev_halphy_fwstats_eventid] = 22152 WMI_HALPHY_CTRL_PATH_STATS_EVENTID; 22153 event_ids[wmi_vdev_send_big_data_p2_eventid] = 22154 WMI_VDEV_SEND_BIG_DATA_P2_EVENTID; 22155 event_ids[wmi_pdev_get_dpd_status_event_id] = 22156 WMI_PDEV_GET_DPD_STATUS_EVENTID; 22157 #ifdef WLAN_FEATURE_PKT_CAPTURE_V2 22158 event_ids[wmi_vdev_smart_monitor_event_id] = 22159 WMI_VDEV_SMART_MONITOR_EVENTID; 22160 #endif 22161 event_ids[wmi_pdev_get_halphy_cal_status_event_id] = 22162 WMI_PDEV_GET_HALPHY_CAL_STATUS_EVENTID; 22163 event_ids[wmi_pdev_set_halphy_cal_event_id] = 22164 WMI_PDEV_SET_HALPHY_CAL_BMAP_EVENTID; 22165 event_ids[wmi_pdev_aoa_phasedelta_event_id] = 22166 WMI_PDEV_AOA_PHASEDELTA_EVENTID; 22167 #ifdef WLAN_MGMT_RX_REO_SUPPORT 22168 event_ids[wmi_mgmt_rx_fw_consumed_eventid] = 22169 WMI_MGMT_RX_FW_CONSUMED_EVENTID; 22170 #endif 22171 populate_tlv_events_id_mlo(event_ids); 22172 event_ids[wmi_roam_frame_event_id] = 22173 WMI_ROAM_FRAME_EVENTID; 22174 #ifdef WLAN_FEATURE_DYNAMIC_MAC_ADDR_UPDATE 22175 event_ids[wmi_vdev_update_mac_addr_conf_eventid] = 22176 WMI_VDEV_UPDATE_MAC_ADDR_CONF_EVENTID; 22177 #endif 22178 #ifdef WLAN_FEATURE_MCC_QUOTA 22179 event_ids[wmi_resmgr_chan_time_quota_changed_eventid] = 22180 WMI_RESMGR_CHAN_TIME_QUOTA_CHANGED_EVENTID; 22181 #endif 22182 event_ids[wmi_peer_rx_pn_response_event_id] = 22183 WMI_PEER_RX_PN_RESPONSE_EVENTID; 22184 event_ids[wmi_extract_pktlog_decode_info_eventid] = 22185 WMI_PDEV_PKTLOG_DECODE_INFO_EVENTID; 22186 #ifdef QCA_RSSI_DB2DBM 22187 event_ids[wmi_pdev_rssi_dbm_conversion_params_info_eventid] = 22188 WMI_PDEV_RSSI_DBM_CONVERSION_PARAMS_INFO_EVENTID; 22189 #endif 22190 #ifdef MULTI_CLIENT_LL_SUPPORT 22191 event_ids[wmi_vdev_latency_event_id] = WMI_VDEV_LATENCY_LEVEL_EVENTID; 22192 #endif 22193 #if defined(WIFI_POS_CONVERGED) && defined(WLAN_FEATURE_RTT_11AZ_SUPPORT) 22194 event_ids[wmi_rtt_pasn_peer_create_req_eventid] = 22195 WMI_RTT_PASN_PEER_CREATE_REQ_EVENTID; 22196 event_ids[wmi_rtt_pasn_peer_delete_eventid] = 22197 WMI_RTT_PASN_PEER_DELETE_EVENTID; 22198 #endif 22199 #ifdef WLAN_VENDOR_HANDOFF_CONTROL 22200 event_ids[wmi_get_roam_vendor_control_param_event_id] = 22201 WMI_ROAM_GET_VENDOR_CONTROL_PARAM_EVENTID; 22202 #endif 22203 #ifdef WLAN_FEATURE_DBAM_CONFIG 22204 event_ids[wmi_coex_dbam_complete_event_id] = 22205 WMI_COEX_DBAM_COMPLETE_EVENTID; 22206 #endif 22207 event_ids[wmi_spectral_capabilities_eventid] = 22208 WMI_SPECTRAL_CAPABILITIES_EVENTID; 22209 #ifdef WLAN_FEATURE_COAP 22210 event_ids[wmi_wow_coap_buf_info_eventid] = 22211 WMI_WOW_COAP_BUF_INFO_EVENTID; 22212 #endif 22213 #ifdef HEALTH_MON_SUPPORT 22214 event_ids[wmi_extract_health_mon_init_done_info_eventid] = 22215 WMI_HEALTH_MON_INIT_DONE_EVENTID; 22216 #endif /* HEALTH_MON_SUPPORT */ 22217 #ifdef WLAN_SUPPORT_GAP_LL_PS_MODE 22218 event_ids[wmi_xgap_enable_complete_eventid] = 22219 WMI_XGAP_ENABLE_COMPLETE_EVENTID; 22220 #endif 22221 event_ids[wmi_pdev_set_tgtr2p_table_eventid] = 22222 WMI_PDEV_SET_TGTR2P_TABLE_EVENTID; 22223 #ifdef QCA_MANUAL_TRIGGERED_ULOFDMA 22224 event_ids[wmi_manual_ul_ofdma_trig_feedback_eventid] = 22225 WMI_MANUAL_UL_OFDMA_TRIG_FEEDBACK_EVENTID; 22226 event_ids[wmi_manual_ul_ofdma_trig_rx_peer_userinfo_eventid] = 22227 WMI_MANUAL_UL_OFDMA_TRIG_RX_PEER_USERINFO_EVENTID; 22228 #endif 22229 #ifdef QCA_STANDALONE_SOUNDING_TRIGGER 22230 event_ids[wmi_vdev_standalone_sound_complete_eventid] = 22231 WMI_VDEV_STANDALONE_SOUND_COMPLETE_EVENTID; 22232 #endif 22233 event_ids[wmi_csa_ie_received_event_id] = WMI_CSA_IE_RECEIVED_EVENTID; 22234 #if defined(WLAN_FEATURE_ROAM_OFFLOAD) && defined(WLAN_FEATURE_11BE_MLO) 22235 event_ids[wmi_roam_synch_key_event_id] = WMI_ROAM_SYNCH_KEY_EVENTID; 22236 #endif 22237 #ifdef QCA_SUPPORT_PRIMARY_LINK_MIGRATE 22238 event_ids[wmi_peer_ptqm_migration_response_eventid] = 22239 WMI_MLO_PRIMARY_LINK_PEER_MIGRATION_EVENTID; 22240 #endif 22241 event_ids[wmi_pdev_set_rf_path_resp_eventid] = 22242 WMI_PDEV_SET_RF_PATH_RESP_EVENTID; 22243 #ifdef WLAN_RCC_ENHANCED_AOA_SUPPORT 22244 event_ids[wmi_pdev_enhanced_aoa_phasedelta_eventid] = 22245 WMI_PDEV_ENHANCED_AOA_PHASEDELTA_EVENTID; 22246 #endif 22247 } 22248 22249 #ifdef WLAN_FEATURE_LINK_LAYER_STATS 22250 #ifdef FEATURE_CLUB_LL_STATS_AND_GET_STATION 22251 static void wmi_populate_service_get_sta_in_ll_stats_req(uint32_t *wmi_service) 22252 { 22253 wmi_service[wmi_service_get_station_in_ll_stats_req] = 22254 WMI_SERVICE_UNIFIED_LL_GET_STA_CMD_SUPPORT; 22255 } 22256 #else 22257 static void wmi_populate_service_get_sta_in_ll_stats_req(uint32_t *wmi_service) 22258 { 22259 } 22260 #endif /* FEATURE_CLUB_LL_STATS_AND_GET_STATION */ 22261 #else 22262 static void wmi_populate_service_get_sta_in_ll_stats_req(uint32_t *wmi_service) 22263 { 22264 } 22265 #endif /* WLAN_FEATURE_LINK_LAYER_STATS */ 22266 22267 #ifdef WLAN_FEATURE_11BE_MLO 22268 static void populate_tlv_service_mlo(uint32_t *wmi_service) 22269 { 22270 wmi_service[wmi_service_mlo_sta_nan_ndi_support] = 22271 WMI_SERVICE_MLO_STA_NAN_NDI_SUPPORT; 22272 } 22273 #else /* WLAN_FEATURE_11BE_MLO */ 22274 static inline void populate_tlv_service_mlo(uint32_t *wmi_service) 22275 { 22276 } 22277 #endif /* WLAN_FEATURE_11BE_MLO */ 22278 22279 /** 22280 * populate_tlv_service() - populates wmi services 22281 * @wmi_service: Pointer to hold wmi_service 22282 * 22283 * Return: None 22284 */ 22285 static void populate_tlv_service(uint32_t *wmi_service) 22286 { 22287 wmi_service[wmi_service_beacon_offload] = WMI_SERVICE_BEACON_OFFLOAD; 22288 wmi_service[wmi_service_ack_timeout] = WMI_SERVICE_ACK_TIMEOUT; 22289 wmi_service[wmi_service_scan_offload] = WMI_SERVICE_SCAN_OFFLOAD; 22290 wmi_service[wmi_service_roam_scan_offload] = 22291 WMI_SERVICE_ROAM_SCAN_OFFLOAD; 22292 wmi_service[wmi_service_bcn_miss_offload] = 22293 WMI_SERVICE_BCN_MISS_OFFLOAD; 22294 wmi_service[wmi_service_sta_pwrsave] = WMI_SERVICE_STA_PWRSAVE; 22295 wmi_service[wmi_service_sta_advanced_pwrsave] = 22296 WMI_SERVICE_STA_ADVANCED_PWRSAVE; 22297 wmi_service[wmi_service_ap_uapsd] = WMI_SERVICE_AP_UAPSD; 22298 wmi_service[wmi_service_ap_dfs] = WMI_SERVICE_AP_DFS; 22299 wmi_service[wmi_service_11ac] = WMI_SERVICE_11AC; 22300 wmi_service[wmi_service_blockack] = WMI_SERVICE_BLOCKACK; 22301 wmi_service[wmi_service_phyerr] = WMI_SERVICE_PHYERR; 22302 wmi_service[wmi_service_bcn_filter] = WMI_SERVICE_BCN_FILTER; 22303 wmi_service[wmi_service_rtt] = WMI_SERVICE_RTT; 22304 wmi_service[wmi_service_wow] = WMI_SERVICE_WOW; 22305 wmi_service[wmi_service_ratectrl_cache] = WMI_SERVICE_RATECTRL_CACHE; 22306 wmi_service[wmi_service_iram_tids] = WMI_SERVICE_IRAM_TIDS; 22307 wmi_service[wmi_service_arpns_offload] = WMI_SERVICE_ARPNS_OFFLOAD; 22308 wmi_service[wmi_service_nlo] = WMI_SERVICE_NLO; 22309 wmi_service[wmi_service_gtk_offload] = WMI_SERVICE_GTK_OFFLOAD; 22310 wmi_service[wmi_service_scan_sch] = WMI_SERVICE_SCAN_SCH; 22311 wmi_service[wmi_service_csa_offload] = WMI_SERVICE_CSA_OFFLOAD; 22312 wmi_service[wmi_service_chatter] = WMI_SERVICE_CHATTER; 22313 wmi_service[wmi_service_coex_freqavoid] = WMI_SERVICE_COEX_FREQAVOID; 22314 wmi_service[wmi_service_packet_power_save] = 22315 WMI_SERVICE_PACKET_POWER_SAVE; 22316 wmi_service[wmi_service_force_fw_hang] = WMI_SERVICE_FORCE_FW_HANG; 22317 wmi_service[wmi_service_gpio] = WMI_SERVICE_GPIO; 22318 wmi_service[wmi_service_sta_dtim_ps_modulated_dtim] = 22319 WMI_SERVICE_STA_DTIM_PS_MODULATED_DTIM; 22320 wmi_service[wmi_sta_uapsd_basic_auto_trig] = 22321 WMI_STA_UAPSD_BASIC_AUTO_TRIG; 22322 wmi_service[wmi_sta_uapsd_var_auto_trig] = WMI_STA_UAPSD_VAR_AUTO_TRIG; 22323 wmi_service[wmi_service_sta_keep_alive] = WMI_SERVICE_STA_KEEP_ALIVE; 22324 wmi_service[wmi_service_tx_encap] = WMI_SERVICE_TX_ENCAP; 22325 wmi_service[wmi_service_ap_ps_detect_out_of_sync] = 22326 WMI_SERVICE_AP_PS_DETECT_OUT_OF_SYNC; 22327 wmi_service[wmi_service_early_rx] = WMI_SERVICE_EARLY_RX; 22328 wmi_service[wmi_service_sta_smps] = WMI_SERVICE_STA_SMPS; 22329 wmi_service[wmi_service_fwtest] = WMI_SERVICE_FWTEST; 22330 wmi_service[wmi_service_sta_wmmac] = WMI_SERVICE_STA_WMMAC; 22331 wmi_service[wmi_service_tdls] = WMI_SERVICE_TDLS; 22332 wmi_service[wmi_service_burst] = WMI_SERVICE_BURST; 22333 wmi_service[wmi_service_mcc_bcn_interval_change] = 22334 WMI_SERVICE_MCC_BCN_INTERVAL_CHANGE; 22335 wmi_service[wmi_service_adaptive_ocs] = WMI_SERVICE_ADAPTIVE_OCS; 22336 wmi_service[wmi_service_ba_ssn_support] = WMI_SERVICE_BA_SSN_SUPPORT; 22337 wmi_service[wmi_service_filter_ipsec_natkeepalive] = 22338 WMI_SERVICE_FILTER_IPSEC_NATKEEPALIVE; 22339 wmi_service[wmi_service_wlan_hb] = WMI_SERVICE_WLAN_HB; 22340 wmi_service[wmi_service_lte_ant_share_support] = 22341 WMI_SERVICE_LTE_ANT_SHARE_SUPPORT; 22342 wmi_service[wmi_service_batch_scan] = WMI_SERVICE_BATCH_SCAN; 22343 wmi_service[wmi_service_qpower] = WMI_SERVICE_QPOWER; 22344 wmi_service[wmi_service_plmreq] = WMI_SERVICE_PLMREQ; 22345 wmi_service[wmi_service_thermal_mgmt] = WMI_SERVICE_THERMAL_MGMT; 22346 wmi_service[wmi_service_rmc] = WMI_SERVICE_RMC; 22347 wmi_service[wmi_service_mhf_offload] = WMI_SERVICE_MHF_OFFLOAD; 22348 wmi_service[wmi_service_coex_sar] = WMI_SERVICE_COEX_SAR; 22349 wmi_service[wmi_service_bcn_txrate_override] = 22350 WMI_SERVICE_BCN_TXRATE_OVERRIDE; 22351 wmi_service[wmi_service_nan] = WMI_SERVICE_NAN; 22352 wmi_service[wmi_service_l1ss_stat] = WMI_SERVICE_L1SS_STAT; 22353 wmi_service[wmi_service_estimate_linkspeed] = 22354 WMI_SERVICE_ESTIMATE_LINKSPEED; 22355 wmi_service[wmi_service_obss_scan] = WMI_SERVICE_OBSS_SCAN; 22356 wmi_service[wmi_service_tdls_offchan] = WMI_SERVICE_TDLS_OFFCHAN; 22357 wmi_service[wmi_service_tdls_uapsd_buffer_sta] = 22358 WMI_SERVICE_TDLS_UAPSD_BUFFER_STA; 22359 wmi_service[wmi_service_tdls_uapsd_sleep_sta] = 22360 WMI_SERVICE_TDLS_UAPSD_SLEEP_STA; 22361 wmi_service[wmi_service_ibss_pwrsave] = WMI_SERVICE_IBSS_PWRSAVE; 22362 wmi_service[wmi_service_lpass] = WMI_SERVICE_LPASS; 22363 wmi_service[wmi_service_extscan] = WMI_SERVICE_EXTSCAN; 22364 wmi_service[wmi_service_d0wow] = WMI_SERVICE_D0WOW; 22365 wmi_service[wmi_service_hsoffload] = WMI_SERVICE_HSOFFLOAD; 22366 wmi_service[wmi_service_roam_ho_offload] = WMI_SERVICE_ROAM_HO_OFFLOAD; 22367 wmi_service[wmi_service_rx_full_reorder] = WMI_SERVICE_RX_FULL_REORDER; 22368 wmi_service[wmi_service_dhcp_offload] = WMI_SERVICE_DHCP_OFFLOAD; 22369 wmi_service[wmi_service_sta_rx_ipa_offload_support] = 22370 WMI_SERVICE_STA_RX_IPA_OFFLOAD_SUPPORT; 22371 wmi_service[wmi_service_mdns_offload] = WMI_SERVICE_MDNS_OFFLOAD; 22372 wmi_service[wmi_service_sap_auth_offload] = 22373 WMI_SERVICE_SAP_AUTH_OFFLOAD; 22374 wmi_service[wmi_service_dual_band_simultaneous_support] = 22375 WMI_SERVICE_DUAL_BAND_SIMULTANEOUS_SUPPORT; 22376 wmi_service[wmi_service_ocb] = WMI_SERVICE_OCB; 22377 wmi_service[wmi_service_ap_arpns_offload] = 22378 WMI_SERVICE_AP_ARPNS_OFFLOAD; 22379 wmi_service[wmi_service_per_band_chainmask_support] = 22380 WMI_SERVICE_PER_BAND_CHAINMASK_SUPPORT; 22381 wmi_service[wmi_service_packet_filter_offload] = 22382 WMI_SERVICE_PACKET_FILTER_OFFLOAD; 22383 wmi_service[wmi_service_mgmt_tx_htt] = WMI_SERVICE_MGMT_TX_HTT; 22384 wmi_service[wmi_service_mgmt_tx_wmi] = WMI_SERVICE_MGMT_TX_WMI; 22385 wmi_service[wmi_service_ext_msg] = WMI_SERVICE_EXT_MSG; 22386 wmi_service[wmi_service_ext2_msg] = WMI_SERVICE_EXT2_MSG; 22387 wmi_service[wmi_service_mawc] = WMI_SERVICE_MAWC; 22388 wmi_service[wmi_service_multiple_vdev_restart] = 22389 WMI_SERVICE_MULTIPLE_VDEV_RESTART; 22390 wmi_service[wmi_service_multiple_vdev_restart_bmap] = 22391 WMI_SERVICE_MULTIPLE_VDEV_RESTART_BITMAP_SUPPORT; 22392 wmi_service[wmi_service_smart_antenna_sw_support] = 22393 WMI_SERVICE_SMART_ANTENNA_SW_SUPPORT; 22394 wmi_service[wmi_service_smart_antenna_hw_support] = 22395 WMI_SERVICE_SMART_ANTENNA_HW_SUPPORT; 22396 22397 wmi_service[wmi_service_roam_offload] = WMI_SERVICE_UNAVAILABLE; 22398 wmi_service[wmi_service_ratectrl] = WMI_SERVICE_UNAVAILABLE; 22399 wmi_service[wmi_service_enhanced_proxy_sta] = WMI_SERVICE_UNAVAILABLE; 22400 wmi_service[wmi_service_tt] = WMI_SERVICE_THERM_THROT; 22401 wmi_service[wmi_service_atf] = WMI_SERVICE_ATF; 22402 wmi_service[wmi_service_peer_caching] = WMI_SERVICE_UNAVAILABLE; 22403 wmi_service[wmi_service_coex_gpio] = WMI_SERVICE_UNAVAILABLE; 22404 wmi_service[wmi_service_aux_spectral_intf] = WMI_SERVICE_UNAVAILABLE; 22405 wmi_service[wmi_service_aux_chan_load_intf] = WMI_SERVICE_UNAVAILABLE; 22406 wmi_service[wmi_service_bss_channel_info_64] = WMI_SERVICE_UNAVAILABLE; 22407 wmi_service[wmi_service_ext_res_cfg_support] = WMI_SERVICE_UNAVAILABLE; 22408 wmi_service[wmi_service_mesh] = WMI_SERVICE_UNAVAILABLE; 22409 wmi_service[wmi_service_restrt_chnl_support] = WMI_SERVICE_UNAVAILABLE; 22410 wmi_service[wmi_service_peer_stats] = WMI_SERVICE_UNAVAILABLE; 22411 wmi_service[wmi_service_mesh_11s] = WMI_SERVICE_UNAVAILABLE; 22412 wmi_service[wmi_service_periodic_chan_stat_support] = 22413 WMI_SERVICE_PERIODIC_CHAN_STAT_SUPPORT; 22414 wmi_service[wmi_service_tx_mode_push_only] = WMI_SERVICE_UNAVAILABLE; 22415 wmi_service[wmi_service_tx_mode_push_pull] = WMI_SERVICE_UNAVAILABLE; 22416 wmi_service[wmi_service_tx_mode_dynamic] = WMI_SERVICE_UNAVAILABLE; 22417 wmi_service[wmi_service_btcoex_duty_cycle] = WMI_SERVICE_UNAVAILABLE; 22418 wmi_service[wmi_service_4_wire_coex_support] = WMI_SERVICE_UNAVAILABLE; 22419 wmi_service[wmi_service_mesh] = WMI_SERVICE_ENTERPRISE_MESH; 22420 wmi_service[wmi_service_peer_assoc_conf] = WMI_SERVICE_PEER_ASSOC_CONF; 22421 wmi_service[wmi_service_egap] = WMI_SERVICE_EGAP; 22422 wmi_service[wmi_service_sta_pmf_offload] = WMI_SERVICE_STA_PMF_OFFLOAD; 22423 wmi_service[wmi_service_unified_wow_capability] = 22424 WMI_SERVICE_UNIFIED_WOW_CAPABILITY; 22425 wmi_service[wmi_service_enterprise_mesh] = WMI_SERVICE_ENTERPRISE_MESH; 22426 wmi_service[wmi_service_apf_offload] = WMI_SERVICE_BPF_OFFLOAD; 22427 wmi_service[wmi_service_sync_delete_cmds] = 22428 WMI_SERVICE_SYNC_DELETE_CMDS; 22429 wmi_service[wmi_service_ratectrl_limit_max_min_rates] = 22430 WMI_SERVICE_RATECTRL_LIMIT_MAX_MIN_RATES; 22431 wmi_service[wmi_service_nan_data] = WMI_SERVICE_NAN_DATA; 22432 wmi_service[wmi_service_nan_rtt] = WMI_SERVICE_NAN_RTT; 22433 wmi_service[wmi_service_11ax] = WMI_SERVICE_11AX; 22434 wmi_service[wmi_service_deprecated_replace] = 22435 WMI_SERVICE_DEPRECATED_REPLACE; 22436 wmi_service[wmi_service_tdls_conn_tracker_in_host_mode] = 22437 WMI_SERVICE_TDLS_CONN_TRACKER_IN_HOST_MODE; 22438 wmi_service[wmi_service_enhanced_mcast_filter] = 22439 WMI_SERVICE_ENHANCED_MCAST_FILTER; 22440 wmi_service[wmi_service_half_rate_quarter_rate_support] = 22441 WMI_SERVICE_HALF_RATE_QUARTER_RATE_SUPPORT; 22442 wmi_service[wmi_service_vdev_rx_filter] = WMI_SERVICE_VDEV_RX_FILTER; 22443 wmi_service[wmi_service_p2p_listen_offload_support] = 22444 WMI_SERVICE_P2P_LISTEN_OFFLOAD_SUPPORT; 22445 wmi_service[wmi_service_mark_first_wakeup_packet] = 22446 WMI_SERVICE_MARK_FIRST_WAKEUP_PACKET; 22447 wmi_service[wmi_service_multiple_mcast_filter_set] = 22448 WMI_SERVICE_MULTIPLE_MCAST_FILTER_SET; 22449 wmi_service[wmi_service_host_managed_rx_reorder] = 22450 WMI_SERVICE_HOST_MANAGED_RX_REORDER; 22451 wmi_service[wmi_service_flash_rdwr_support] = 22452 WMI_SERVICE_FLASH_RDWR_SUPPORT; 22453 wmi_service[wmi_service_wlan_stats_report] = 22454 WMI_SERVICE_WLAN_STATS_REPORT; 22455 wmi_service[wmi_service_tx_msdu_id_new_partition_support] = 22456 WMI_SERVICE_TX_MSDU_ID_NEW_PARTITION_SUPPORT; 22457 wmi_service[wmi_service_dfs_phyerr_offload] = 22458 WMI_SERVICE_DFS_PHYERR_OFFLOAD; 22459 wmi_service[wmi_service_rcpi_support] = WMI_SERVICE_RCPI_SUPPORT; 22460 wmi_service[wmi_service_fw_mem_dump_support] = 22461 WMI_SERVICE_FW_MEM_DUMP_SUPPORT; 22462 wmi_service[wmi_service_peer_stats_info] = WMI_SERVICE_PEER_STATS_INFO; 22463 wmi_service[wmi_service_regulatory_db] = WMI_SERVICE_REGULATORY_DB; 22464 wmi_service[wmi_service_11d_offload] = WMI_SERVICE_11D_OFFLOAD; 22465 wmi_service[wmi_service_hw_data_filtering] = 22466 WMI_SERVICE_HW_DATA_FILTERING; 22467 wmi_service[wmi_service_pkt_routing] = WMI_SERVICE_PKT_ROUTING; 22468 wmi_service[wmi_service_offchan_tx_wmi] = WMI_SERVICE_OFFCHAN_TX_WMI; 22469 wmi_service[wmi_service_chan_load_info] = WMI_SERVICE_CHAN_LOAD_INFO; 22470 wmi_service[wmi_service_extended_nss_support] = 22471 WMI_SERVICE_EXTENDED_NSS_SUPPORT; 22472 wmi_service[wmi_service_widebw_scan] = WMI_SERVICE_SCAN_PHYMODE_SUPPORT; 22473 wmi_service[wmi_service_bcn_offload_start_stop_support] = 22474 WMI_SERVICE_BCN_OFFLOAD_START_STOP_SUPPORT; 22475 wmi_service[wmi_service_offchan_data_tid_support] = 22476 WMI_SERVICE_OFFCHAN_DATA_TID_SUPPORT; 22477 wmi_service[wmi_service_support_dma] = 22478 WMI_SERVICE_SUPPORT_DIRECT_DMA; 22479 wmi_service[wmi_service_8ss_tx_bfee] = WMI_SERVICE_8SS_TX_BFEE; 22480 wmi_service[wmi_service_fils_support] = WMI_SERVICE_FILS_SUPPORT; 22481 wmi_service[wmi_service_mawc_support] = WMI_SERVICE_MAWC_SUPPORT; 22482 wmi_service[wmi_service_wow_wakeup_by_timer_pattern] = 22483 WMI_SERVICE_WOW_WAKEUP_BY_TIMER_PATTERN; 22484 wmi_service[wmi_service_11k_neighbour_report_support] = 22485 WMI_SERVICE_11K_NEIGHBOUR_REPORT_SUPPORT; 22486 wmi_service[wmi_service_ap_obss_detection_offload] = 22487 WMI_SERVICE_AP_OBSS_DETECTION_OFFLOAD; 22488 wmi_service[wmi_service_bss_color_offload] = 22489 WMI_SERVICE_BSS_COLOR_OFFLOAD; 22490 wmi_service[wmi_service_gmac_offload_support] = 22491 WMI_SERVICE_GMAC_OFFLOAD_SUPPORT; 22492 wmi_service[wmi_service_dual_beacon_on_single_mac_scc_support] = 22493 WMI_SERVICE_DUAL_BEACON_ON_SINGLE_MAC_SCC_SUPPORT; 22494 wmi_service[wmi_service_dual_beacon_on_single_mac_mcc_support] = 22495 WMI_SERVICE_DUAL_BEACON_ON_SINGLE_MAC_MCC_SUPPORT; 22496 wmi_service[wmi_service_twt_requestor] = WMI_SERVICE_STA_TWT; 22497 wmi_service[wmi_service_twt_responder] = WMI_SERVICE_AP_TWT; 22498 wmi_service[wmi_service_listen_interval_offload_support] = 22499 WMI_SERVICE_LISTEN_INTERVAL_OFFLOAD_SUPPORT; 22500 wmi_service[wmi_service_esp_support] = WMI_SERVICE_ESP_SUPPORT; 22501 wmi_service[wmi_service_obss_spatial_reuse] = 22502 WMI_SERVICE_OBSS_SPATIAL_REUSE; 22503 wmi_service[wmi_service_per_vdev_chain_support] = 22504 WMI_SERVICE_PER_VDEV_CHAINMASK_CONFIG_SUPPORT; 22505 wmi_service[wmi_service_new_htt_msg_format] = 22506 WMI_SERVICE_HTT_H2T_NO_HTC_HDR_LEN_IN_MSG_LEN; 22507 wmi_service[wmi_service_peer_unmap_cnf_support] = 22508 WMI_SERVICE_PEER_UNMAP_RESPONSE_SUPPORT; 22509 wmi_service[wmi_service_beacon_reception_stats] = 22510 WMI_SERVICE_BEACON_RECEPTION_STATS; 22511 wmi_service[wmi_service_vdev_latency_config] = 22512 WMI_SERVICE_VDEV_LATENCY_CONFIG; 22513 wmi_service[wmi_service_nan_dbs_support] = WMI_SERVICE_NAN_DBS_SUPPORT; 22514 wmi_service[wmi_service_ndi_dbs_support] = WMI_SERVICE_NDI_DBS_SUPPORT; 22515 wmi_service[wmi_service_nan_sap_support] = WMI_SERVICE_NAN_SAP_SUPPORT; 22516 wmi_service[wmi_service_ndi_sap_support] = WMI_SERVICE_NDI_SAP_SUPPORT; 22517 wmi_service[wmi_service_nan_disable_support] = 22518 WMI_SERVICE_NAN_DISABLE_SUPPORT; 22519 wmi_service[wmi_service_sta_plus_sta_support] = 22520 WMI_SERVICE_STA_PLUS_STA_SUPPORT; 22521 wmi_service[wmi_service_hw_db2dbm_support] = 22522 WMI_SERVICE_HW_DB2DBM_CONVERSION_SUPPORT; 22523 wmi_service[wmi_service_wlm_stats_support] = 22524 WMI_SERVICE_WLM_STATS_REQUEST; 22525 wmi_service[wmi_service_infra_mbssid] = WMI_SERVICE_INFRA_MBSSID; 22526 wmi_service[wmi_service_ema_ap_support] = WMI_SERVICE_EMA_AP_SUPPORT; 22527 wmi_service[wmi_service_ul_ru26_allowed] = WMI_SERVICE_UL_RU26_ALLOWED; 22528 wmi_service[wmi_service_cfr_capture_support] = 22529 WMI_SERVICE_CFR_CAPTURE_SUPPORT; 22530 wmi_service[wmi_service_cfr_capture_pdev_id_soc] = 22531 WMI_SERVICE_CFR_CAPTURE_PDEV_ID_SOC; 22532 wmi_service[wmi_service_bcast_twt_support] = 22533 WMI_SERVICE_BROADCAST_TWT; 22534 wmi_service[wmi_service_wpa3_ft_sae_support] = 22535 WMI_SERVICE_WPA3_FT_SAE_SUPPORT; 22536 wmi_service[wmi_service_wpa3_ft_suite_b_support] = 22537 WMI_SERVICE_WPA3_FT_SUITE_B_SUPPORT; 22538 wmi_service[wmi_service_ft_fils] = 22539 WMI_SERVICE_WPA3_FT_FILS; 22540 wmi_service[wmi_service_adaptive_11r_support] = 22541 WMI_SERVICE_ADAPTIVE_11R_ROAM; 22542 wmi_service[wmi_service_tx_compl_tsf64] = 22543 WMI_SERVICE_TX_COMPL_TSF64; 22544 wmi_service[wmi_service_data_stall_recovery_support] = 22545 WMI_SERVICE_DSM_ROAM_FILTER; 22546 wmi_service[wmi_service_vdev_delete_all_peer] = 22547 WMI_SERVICE_DELETE_ALL_PEER_SUPPORT; 22548 wmi_service[wmi_service_three_way_coex_config_legacy] = 22549 WMI_SERVICE_THREE_WAY_COEX_CONFIG_LEGACY; 22550 wmi_service[wmi_service_rx_fse_support] = 22551 WMI_SERVICE_RX_FSE_SUPPORT; 22552 wmi_service[wmi_service_sae_roam_support] = 22553 WMI_SERVICE_WPA3_SAE_ROAM_SUPPORT; 22554 wmi_service[wmi_service_owe_roam_support] = 22555 WMI_SERVICE_WPA3_OWE_ROAM_SUPPORT; 22556 wmi_service[wmi_service_6ghz_support] = 22557 WMI_SERVICE_6GHZ_SUPPORT; 22558 wmi_service[wmi_service_bw_165mhz_support] = 22559 WMI_SERVICE_BW_165MHZ_SUPPORT; 22560 wmi_service[wmi_service_bw_restricted_80p80_support] = 22561 WMI_SERVICE_BW_RESTRICTED_80P80_SUPPORT; 22562 wmi_service[wmi_service_packet_capture_support] = 22563 WMI_SERVICE_PACKET_CAPTURE_SUPPORT; 22564 wmi_service[wmi_service_nan_vdev] = WMI_SERVICE_NAN_VDEV_SUPPORT; 22565 wmi_service[wmi_service_peer_delete_no_peer_flush_tids_cmd] = 22566 WMI_SERVICE_PEER_DELETE_NO_PEER_FLUSH_TIDS_CMD; 22567 wmi_service[wmi_service_multiple_vdev_restart_ext] = 22568 WMI_SERVICE_UNAVAILABLE; 22569 wmi_service[wmi_service_time_sync_ftm] = 22570 WMI_SERVICE_AUDIO_SYNC_SUPPORT; 22571 wmi_service[wmi_service_nss_ratio_to_host_support] = 22572 WMI_SERVICE_NSS_RATIO_TO_HOST_SUPPORT; 22573 wmi_service[wmi_roam_scan_chan_list_to_host_support] = 22574 WMI_SERVICE_ROAM_SCAN_CHANNEL_LIST_TO_HOST_SUPPORT; 22575 wmi_service[wmi_beacon_protection_support] = 22576 WMI_SERVICE_BEACON_PROTECTION_SUPPORT; 22577 wmi_service[wmi_service_sta_nan_ndi_four_port] = 22578 WMI_SERVICE_NDI_NDI_STA_SUPPORT; 22579 wmi_service[wmi_service_host_scan_stop_vdev_all] = 22580 WMI_SERVICE_HOST_SCAN_STOP_VDEV_ALL_SUPPORT; 22581 wmi_service[wmi_support_extend_address] = 22582 WMI_SERVICE_SUPPORT_EXTEND_ADDRESS; 22583 wmi_service[wmi_service_srg_srp_spatial_reuse_support] = 22584 WMI_SERVICE_SRG_SRP_SPATIAL_REUSE_SUPPORT; 22585 wmi_service[wmi_service_suiteb_roam_support] = 22586 WMI_SERVICE_WPA3_SUITEB_ROAM_SUPPORT; 22587 wmi_service[wmi_service_no_interband_mcc_support] = 22588 WMI_SERVICE_NO_INTERBAND_MCC_SUPPORT; 22589 wmi_service[wmi_service_dual_sta_roam_support] = 22590 WMI_SERVICE_DUAL_STA_ROAM_SUPPORT; 22591 wmi_service[wmi_service_peer_create_conf] = 22592 WMI_SERVICE_PEER_CREATE_CONF; 22593 wmi_service[wmi_service_configure_roam_trigger_param_support] = 22594 WMI_SERVICE_CONFIGURE_ROAM_TRIGGER_PARAM_SUPPORT; 22595 wmi_service[wmi_service_5dot9_ghz_support] = 22596 WMI_SERVICE_5_DOT_9GHZ_SUPPORT; 22597 wmi_service[wmi_service_cfr_ta_ra_as_fp_support] = 22598 WMI_SERVICE_CFR_TA_RA_AS_FP_SUPPORT; 22599 wmi_service[wmi_service_cfr_capture_count_support] = 22600 WMI_SERVICE_CFR_CAPTURE_COUNT_SUPPORT; 22601 wmi_service[wmi_service_ocv_support] = 22602 WMI_SERVICE_OCV_SUPPORT; 22603 wmi_service[wmi_service_ll_stats_per_chan_rx_tx_time] = 22604 WMI_SERVICE_LL_STATS_PER_CHAN_RX_TX_TIME_SUPPORT; 22605 wmi_service[wmi_service_thermal_multi_client_support] = 22606 WMI_SERVICE_THERMAL_MULTI_CLIENT_SUPPORT; 22607 wmi_service[wmi_service_mbss_param_in_vdev_start_support] = 22608 WMI_SERVICE_MBSS_PARAM_IN_VDEV_START_SUPPORT; 22609 wmi_service[wmi_service_fse_cmem_alloc_support] = 22610 WMI_SERVICE_FSE_CMEM_ALLOC_SUPPORT; 22611 wmi_service[wmi_service_scan_conf_per_ch_support] = 22612 WMI_SERVICE_SCAN_CONFIG_PER_CHANNEL; 22613 wmi_service[wmi_service_csa_beacon_template] = 22614 WMI_SERVICE_CSA_BEACON_TEMPLATE; 22615 #if defined(WIFI_POS_CONVERGED) && defined(WLAN_FEATURE_RTT_11AZ_SUPPORT) 22616 wmi_service[wmi_service_rtt_11az_ntb_support] = 22617 WMI_SERVICE_RTT_11AZ_NTB_SUPPORT; 22618 wmi_service[wmi_service_rtt_11az_tb_support] = 22619 WMI_SERVICE_RTT_11AZ_TB_SUPPORT; 22620 wmi_service[wmi_service_rtt_11az_tb_rsta_support] = 22621 WMI_SERVICE_RTT_11AZ_TB_RSTA_SUPPORT; 22622 wmi_service[wmi_service_rtt_11az_mac_sec_support] = 22623 WMI_SERVICE_RTT_11AZ_MAC_SEC_SUPPORT; 22624 wmi_service[wmi_service_rtt_11az_mac_phy_sec_support] = 22625 WMI_SERVICE_RTT_11AZ_MAC_PHY_SEC_SUPPORT; 22626 #endif 22627 #ifdef WLAN_FEATURE_IGMP_OFFLOAD 22628 wmi_service[wmi_service_igmp_offload_support] = 22629 WMI_SERVICE_IGMP_OFFLOAD_SUPPORT; 22630 #endif 22631 22632 #ifdef FEATURE_WLAN_TDLS 22633 #ifdef WLAN_FEATURE_11AX 22634 wmi_service[wmi_service_tdls_ax_support] = 22635 WMI_SERVICE_11AX_TDLS_SUPPORT; 22636 wmi_service[wmi_service_tdls_6g_support] = 22637 WMI_SERVICE_TDLS_6GHZ_SUPPORT; 22638 #endif 22639 wmi_service[wmi_service_tdls_wideband_support] = 22640 WMI_SERVICE_TDLS_WIDEBAND_SUPPORT; 22641 wmi_service[wmi_service_tdls_concurrency_support] = 22642 WMI_SERVICE_TDLS_CONCURRENCY_SUPPORT; 22643 #endif 22644 #ifdef FEATURE_WLAN_TDLS 22645 #ifdef WLAN_FEATURE_11BE 22646 wmi_service[wmi_service_tdls_mlo_support] = 22647 WMI_SERVICE_11BE_MLO_TDLS_SUPPORT; 22648 #endif 22649 #endif 22650 #ifdef WLAN_SUPPORT_TWT 22651 wmi_service[wmi_service_twt_bcast_req_support] = 22652 WMI_SERVICE_BROADCAST_TWT_REQUESTER; 22653 wmi_service[wmi_service_twt_bcast_resp_support] = 22654 WMI_SERVICE_BROADCAST_TWT_RESPONDER; 22655 wmi_service[wmi_service_twt_nudge] = 22656 WMI_SERVICE_TWT_NUDGE; 22657 wmi_service[wmi_service_all_twt] = 22658 WMI_SERVICE_TWT_ALL_DIALOG_ID; 22659 wmi_service[wmi_service_twt_statistics] = 22660 WMI_SERVICE_TWT_STATS; 22661 wmi_service[wmi_service_restricted_twt] = WMI_SERVICE_RESTRICTED_TWT; 22662 #endif 22663 wmi_service[wmi_service_spectral_scan_disabled] = 22664 WMI_SERVICE_SPECTRAL_SCAN_DISABLED; 22665 wmi_service[wmi_service_sae_eapol_offload_support] = 22666 WMI_SERVICE_SAE_EAPOL_OFFLOAD_SUPPORT; 22667 wmi_populate_service_get_sta_in_ll_stats_req(wmi_service); 22668 22669 wmi_service[wmi_service_wapi_concurrency_supported] = 22670 WMI_SERVICE_WAPI_CONCURRENCY_SUPPORTED; 22671 wmi_service[wmi_service_sap_connected_d3_wow] = 22672 WMI_SERVICE_SAP_CONNECTED_D3WOW; 22673 wmi_service[wmi_service_go_connected_d3_wow] = 22674 WMI_SERVICE_SAP_CONNECTED_D3WOW; 22675 wmi_service[wmi_service_ext_tpc_reg_support] = 22676 WMI_SERVICE_EXT_TPC_REG_SUPPORT; 22677 wmi_service[wmi_service_eirp_preferred_support] = 22678 WMI_SERVICE_EIRP_PREFERRED_SUPPORT; 22679 wmi_service[wmi_service_ndi_txbf_support] = 22680 WMI_SERVICE_NDI_TXBF_SUPPORT; 22681 wmi_service[wmi_service_reg_cc_ext_event_support] = 22682 WMI_SERVICE_REG_CC_EXT_EVENT_SUPPORT; 22683 wmi_service[wmi_service_bang_radar_320_support] = 22684 WMI_SERVICE_BANG_RADAR_320_SUPPORT; 22685 #if defined(CONFIG_BAND_6GHZ) 22686 wmi_service[wmi_service_lower_6g_edge_ch_supp] = 22687 WMI_SERVICE_ENABLE_LOWER_6G_EDGE_CH_SUPP; 22688 wmi_service[wmi_service_disable_upper_6g_edge_ch_supp] = 22689 WMI_SERVICE_DISABLE_UPPER_6G_EDGE_CH_SUPP; 22690 #ifdef CONFIG_AFC_SUPPORT 22691 wmi_service[wmi_service_afc_support] = 22692 WMI_SERVICE_AFC_SUPPORT; 22693 #endif 22694 #endif 22695 wmi_service[wmi_service_dcs_awgn_int_support] = 22696 WMI_SERVICE_DCS_AWGN_INT_SUPPORT; 22697 wmi_populate_service_11be(wmi_service); 22698 22699 #ifdef WLAN_FEATURE_BIG_DATA_STATS 22700 wmi_service[wmi_service_big_data_support] = 22701 WMI_SERVICE_BIG_DATA_SUPPORT; 22702 #endif 22703 wmi_service[wmi_service_ampdu_tx_buf_size_256_support] = 22704 WMI_SERVICE_AMPDU_TX_BUF_SIZE_256_SUPPORT; 22705 wmi_service[wmi_service_halphy_cal_enable_disable_support] = 22706 WMI_SERVICE_HALPHY_CAL_ENABLE_DISABLE_SUPPORT; 22707 wmi_service[wmi_service_halphy_cal_status] = 22708 WMI_SERVICE_HALPHY_CAL_STATUS; 22709 wmi_service[wmi_service_rtt_ap_initiator_staggered_mode_supported] = 22710 WMI_SERVICE_RTT_AP_INITIATOR_STAGGERED_MODE_SUPPORTED; 22711 wmi_service[wmi_service_rtt_ap_initiator_bursted_mode_supported] = 22712 WMI_SERVICE_RTT_AP_INITIATOR_BURSTED_MODE_SUPPORTED; 22713 wmi_service[wmi_service_ema_multiple_group_supported] = 22714 WMI_SERVICE_EMA_MULTIPLE_GROUP_SUPPORT; 22715 wmi_service[wmi_service_large_beacon_supported] = 22716 WMI_SERVICE_LARGE_BEACON_SUPPORT; 22717 wmi_service[wmi_service_aoa_for_rcc_supported] = 22718 WMI_SERVICE_AOA_FOR_RCC_SUPPORTED; 22719 #ifdef WLAN_FEATURE_P2P_P2P_STA 22720 wmi_service[wmi_service_p2p_p2p_cc_support] = 22721 WMI_SERVICE_P2P_P2P_CONCURRENCY_SUPPORT; 22722 #endif 22723 #ifdef THERMAL_STATS_SUPPORT 22724 wmi_service[wmi_service_thermal_stats_temp_range_supported] = 22725 WMI_SERVICE_THERMAL_THROT_STATS_TEMP_RANGE_SUPPORT; 22726 #endif 22727 wmi_service[wmi_service_hw_mode_policy_offload_support] = 22728 WMI_SERVICE_HW_MODE_POLICY_OFFLOAD_SUPPORT; 22729 wmi_service[wmi_service_mgmt_rx_reo_supported] = 22730 WMI_SERVICE_MGMT_RX_REO_SUPPORTED; 22731 wmi_service[wmi_service_phy_dma_byte_swap_support] = 22732 WMI_SERVICE_UNAVAILABLE; 22733 wmi_service[wmi_service_spectral_session_info_support] = 22734 WMI_SERVICE_SPECTRAL_SESSION_INFO_SUPPORT; 22735 wmi_service[wmi_service_umac_hang_recovery_support] = 22736 WMI_SERVICE_UMAC_HANG_RECOVERY_SUPPORT; 22737 wmi_service[wmi_service_mu_snif] = WMI_SERVICE_MU_SNIF; 22738 #ifdef WLAN_FEATURE_DYNAMIC_MAC_ADDR_UPDATE 22739 wmi_service[wmi_service_dynamic_update_vdev_macaddr_support] = 22740 WMI_SERVICE_DYNAMIC_VDEV_MAC_ADDR_UPDATE_SUPPORT; 22741 #endif 22742 wmi_service[wmi_service_probe_all_bw_support] = 22743 WMI_SERVICE_PROBE_ALL_BW_SUPPORT; 22744 wmi_service[wmi_service_pno_scan_conf_per_ch_support] = 22745 WMI_SERVICE_PNO_SCAN_CONFIG_PER_CHANNEL; 22746 #ifdef QCA_UNDECODED_METADATA_SUPPORT 22747 wmi_service[wmi_service_fp_phy_err_filter_support] = 22748 WMI_SERVICE_FP_PHY_ERR_FILTER_SUPPORT; 22749 #endif 22750 populate_tlv_service_mlo(wmi_service); 22751 wmi_service[wmi_service_pdev_rate_config_support] = 22752 WMI_SERVICE_PDEV_RATE_CONFIG_SUPPORT; 22753 wmi_service[wmi_service_multi_peer_group_cmd_support] = 22754 WMI_SERVICE_MULTIPLE_PEER_GROUP_CMD_SUPPORT; 22755 #ifdef WLAN_FEATURE_11BE 22756 wmi_service[wmi_service_radar_found_chan_freq_eq_center_freq] = 22757 WMI_IS_RADAR_FOUND_CHAN_FREQ_IS_CENTER_FREQ; 22758 #endif 22759 #ifdef WLAN_PDEV_VDEV_SEND_MULTI_PARAM 22760 wmi_service[wmi_service_combined_set_param_support] = 22761 WMI_SERVICE_COMBINED_SET_PARAM_SUPPORT; 22762 #endif 22763 wmi_service[wmi_service_pn_replay_check_support] = 22764 WMI_SERVICE_PN_REPLAY_CHECK_SUPPORT; 22765 #ifdef QCA_RSSI_DB2DBM 22766 wmi_service[wmi_service_pdev_rssi_dbm_conv_event_support] = 22767 WMI_SERVICE_PDEV_RSSI_DBM_CONV_EVENT_SUPPORT; 22768 #endif 22769 wmi_service[wmi_service_pktlog_decode_info_support] = 22770 WMI_SERVICE_PKTLOG_DECODE_INFO_SUPPORT; 22771 #ifdef WLAN_FEATURE_ROAM_OFFLOAD 22772 wmi_service[wmi_service_roam_stats_per_candidate_frame_info] = 22773 WMI_SERVICE_ROAM_STAT_PER_CANDIDATE_FRAME_INFO_SUPPORT; 22774 #endif 22775 #ifdef MULTI_CLIENT_LL_SUPPORT 22776 wmi_service[wmi_service_configure_multi_client_ll_support] = 22777 WMI_SERVICE_MULTI_CLIENT_LL_SUPPORT; 22778 #endif 22779 #ifdef WLAN_VENDOR_HANDOFF_CONTROL 22780 wmi_service[wmi_service_configure_vendor_handoff_control_support] = 22781 WMI_SERVICE_FW_INI_PARSE_SUPPORT; 22782 #endif 22783 wmi_service[wmi_service_linkspeed_roam_trigger_support] = 22784 WMI_SERVICE_LINKSPEED_ROAM_TRIGGER_SUPPORT; 22785 #ifdef FEATURE_SET 22786 wmi_service[wmi_service_feature_set_event_support] = 22787 WMI_SERVICE_FEATURE_SET_EVENT_SUPPORT; 22788 #endif 22789 #ifdef WLAN_FEATURE_SR 22790 wmi_service[wmi_service_obss_per_packet_sr_support] = 22791 WMI_SERVICE_OBSS_PER_PACKET_SR_SUPPORT; 22792 #endif 22793 wmi_service[wmi_service_wpa3_sha384_roam_support] = 22794 WMI_SERVICE_WMI_SERVICE_WPA3_SHA384_ROAM_SUPPORT; 22795 wmi_service[wmi_service_self_mld_roam_between_dbs_and_hbs] = 22796 WMI_SERVICE_SELF_MLD_ROAM_BETWEEN_DBS_AND_HBS; 22797 /* TODO: Assign FW Enum after FW Shared header changes are merged */ 22798 wmi_service[wmi_service_v1a_v1b_supported] = 22799 WMI_SERVICE_PEER_METADATA_V1A_V1B_SUPPORT; 22800 #ifdef QCA_MANUAL_TRIGGERED_ULOFDMA 22801 wmi_service[wmi_service_manual_ulofdma_trigger_support] = 22802 WMI_SERVICE_MANUAL_ULOFDMA_TRIGGER_SUPPORT; 22803 #endif 22804 wmi_service[wmi_service_pre_rx_timeout] = 22805 WMI_SERVICE_PRE_RX_TO; 22806 #ifdef QCA_STANDALONE_SOUNDING_TRIGGER 22807 wmi_service[wmi_service_standalone_sound] = 22808 WMI_SERVICE_STANDALONE_SOUND; 22809 #endif 22810 wmi_service[wmi_service_cca_busy_info_for_each_20mhz] = 22811 WMI_SERVICE_CCA_BUSY_INFO_FOREACH_20MHZ; 22812 wmi_service[wmi_service_vdev_param_chwidth_with_notify_support] = 22813 WMI_SERVICE_VDEV_PARAM_CHWIDTH_WITH_NOTIFY_SUPPORT; 22814 #ifdef WLAN_FEATURE_11BE_MLO 22815 wmi_service[wmi_service_mlo_tsf_sync] = WMI_SERVICE_MLO_TSF_SYNC; 22816 wmi_service[wmi_service_n_link_mlo_support] = 22817 WMI_SERVICE_N_LINK_MLO_SUPPORT; 22818 wmi_service[wmi_service_per_link_stats_support] = 22819 WMI_SERVICE_PER_LINK_STATS_SUPPORT; 22820 wmi_service[wmi_service_pdev_wsi_stats_info_support] = 22821 WMI_SERVICE_PDEV_WSI_STATS_INFO_SUPPORT; 22822 #endif 22823 wmi_service[wmi_service_aux_mac_support] = WMI_SERVICE_AUX_MAC_SUPPORT; 22824 #ifdef WLAN_ATF_INCREASED_STA 22825 wmi_service[wmi_service_atf_max_client_512_support] = 22826 WMI_SERVICE_ATF_MAX_CLIENT_512_SUPPORT; 22827 #endif 22828 wmi_service[wmi_service_fisa_dynamic_msdu_aggr_size_support] = 22829 WMI_SERVICE_FISA_DYNAMIC_MSDU_AGGR_SIZE_SUPPORT; 22830 wmi_service[wmi_service_radar_flags_support] = 22831 WMI_SERVICE_RADAR_FLAGS_SUPPORT; 22832 } 22833 22834 /** 22835 * wmi_ocb_ut_attach() - Attach OCB test framework 22836 * @wmi_handle: wmi handle 22837 * 22838 * Return: None 22839 */ 22840 #ifdef WLAN_OCB_UT 22841 void wmi_ocb_ut_attach(struct wmi_unified *wmi_handle); 22842 #else 22843 static inline void wmi_ocb_ut_attach(struct wmi_unified *wmi_handle) 22844 { 22845 return; 22846 } 22847 #endif 22848 22849 /** 22850 * wmi_tlv_attach() - Attach TLV APIs 22851 * @wmi_handle: wmi handle 22852 * Return: None 22853 */ 22854 void wmi_tlv_attach(wmi_unified_t wmi_handle) 22855 { 22856 wmi_handle->ops = &tlv_ops; 22857 wmi_ocb_ut_attach(wmi_handle); 22858 wmi_handle->soc->svc_ids = &multi_svc_ids[0]; 22859 #ifdef WMI_INTERFACE_EVENT_LOGGING 22860 /* Skip saving WMI_CMD_HDR and TLV HDR */ 22861 wmi_handle->soc->buf_offset_command = 8; 22862 /* WMI_CMD_HDR is already stripped, skip saving TLV HDR */ 22863 wmi_handle->soc->buf_offset_event = 4; 22864 #endif 22865 populate_tlv_events_id(wmi_handle->wmi_events); 22866 populate_tlv_service(wmi_handle->services); 22867 wmi_wds_attach_tlv(wmi_handle); 22868 wmi_twt_attach_tlv(wmi_handle); 22869 wmi_extscan_attach_tlv(wmi_handle); 22870 wmi_smart_ant_attach_tlv(wmi_handle); 22871 wmi_dbr_attach_tlv(wmi_handle); 22872 wmi_atf_attach_tlv(wmi_handle); 22873 wmi_ap_attach_tlv(wmi_handle); 22874 wmi_bcn_attach_tlv(wmi_handle); 22875 wmi_ocb_attach_tlv(wmi_handle); 22876 wmi_nan_attach_tlv(wmi_handle); 22877 wmi_p2p_attach_tlv(wmi_handle); 22878 wmi_interop_issues_ap_attach_tlv(wmi_handle); 22879 wmi_dcs_attach_tlv(wmi_handle); 22880 wmi_roam_attach_tlv(wmi_handle); 22881 wmi_concurrency_attach_tlv(wmi_handle); 22882 wmi_pmo_attach_tlv(wmi_handle); 22883 wmi_sta_attach_tlv(wmi_handle); 22884 wmi_11ax_bss_color_attach_tlv(wmi_handle); 22885 wmi_fwol_attach_tlv(wmi_handle); 22886 wmi_vdev_attach_tlv(wmi_handle); 22887 wmi_cfr_attach_tlv(wmi_handle); 22888 wmi_cp_stats_attach_tlv(wmi_handle); 22889 wmi_gpio_attach_tlv(wmi_handle); 22890 wmi_11be_attach_tlv(wmi_handle); 22891 wmi_coap_attach_tlv(wmi_handle); 22892 } 22893 qdf_export_symbol(wmi_tlv_attach); 22894 22895 /** 22896 * wmi_tlv_init() - Initialize WMI TLV module by registering TLV attach routine 22897 * 22898 * Return: None 22899 */ 22900 void wmi_tlv_init(void) 22901 { 22902 wmi_unified_register_module(WMI_TLV_TARGET, &wmi_tlv_attach); 22903 } 22904