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 }; 129 130 #define PARAM_MAP(name, NAME) [wmi_ ## name] = WMI_ ##NAME 131 132 /* Populate pdev_param whose index is host param and value is target */ 133 static const uint32_t pdev_param_tlv[] = { 134 PARAM_MAP(pdev_param_tx_chain_mask, PDEV_PARAM_TX_CHAIN_MASK), 135 PARAM_MAP(pdev_param_rx_chain_mask, PDEV_PARAM_RX_CHAIN_MASK), 136 PARAM_MAP(pdev_param_txpower_limit2g, PDEV_PARAM_TXPOWER_LIMIT2G), 137 PARAM_MAP(pdev_param_txpower_limit5g, PDEV_PARAM_TXPOWER_LIMIT5G), 138 PARAM_MAP(pdev_param_txpower_scale, PDEV_PARAM_TXPOWER_SCALE), 139 PARAM_MAP(pdev_param_beacon_gen_mode, PDEV_PARAM_BEACON_GEN_MODE), 140 PARAM_MAP(pdev_param_beacon_tx_mode, PDEV_PARAM_BEACON_TX_MODE), 141 PARAM_MAP(pdev_param_resmgr_offchan_mode, 142 PDEV_PARAM_RESMGR_OFFCHAN_MODE), 143 PARAM_MAP(pdev_param_protection_mode, PDEV_PARAM_PROTECTION_MODE), 144 PARAM_MAP(pdev_param_dynamic_bw, PDEV_PARAM_DYNAMIC_BW), 145 PARAM_MAP(pdev_param_non_agg_sw_retry_th, 146 PDEV_PARAM_NON_AGG_SW_RETRY_TH), 147 PARAM_MAP(pdev_param_agg_sw_retry_th, PDEV_PARAM_AGG_SW_RETRY_TH), 148 PARAM_MAP(pdev_param_sta_kickout_th, PDEV_PARAM_STA_KICKOUT_TH), 149 PARAM_MAP(pdev_param_ac_aggrsize_scaling, 150 PDEV_PARAM_AC_AGGRSIZE_SCALING), 151 PARAM_MAP(pdev_param_ltr_enable, PDEV_PARAM_LTR_ENABLE), 152 PARAM_MAP(pdev_param_ltr_ac_latency_be, 153 PDEV_PARAM_LTR_AC_LATENCY_BE), 154 PARAM_MAP(pdev_param_ltr_ac_latency_bk, PDEV_PARAM_LTR_AC_LATENCY_BK), 155 PARAM_MAP(pdev_param_ltr_ac_latency_vi, PDEV_PARAM_LTR_AC_LATENCY_VI), 156 PARAM_MAP(pdev_param_ltr_ac_latency_vo, PDEV_PARAM_LTR_AC_LATENCY_VO), 157 PARAM_MAP(pdev_param_ltr_ac_latency_timeout, 158 PDEV_PARAM_LTR_AC_LATENCY_TIMEOUT), 159 PARAM_MAP(pdev_param_ltr_sleep_override, PDEV_PARAM_LTR_SLEEP_OVERRIDE), 160 PARAM_MAP(pdev_param_ltr_rx_override, PDEV_PARAM_LTR_RX_OVERRIDE), 161 PARAM_MAP(pdev_param_ltr_tx_activity_timeout, 162 PDEV_PARAM_LTR_TX_ACTIVITY_TIMEOUT), 163 PARAM_MAP(pdev_param_l1ss_enable, PDEV_PARAM_L1SS_ENABLE), 164 PARAM_MAP(pdev_param_dsleep_enable, PDEV_PARAM_DSLEEP_ENABLE), 165 PARAM_MAP(pdev_param_pcielp_txbuf_flush, PDEV_PARAM_PCIELP_TXBUF_FLUSH), 166 PARAM_MAP(pdev_param_pcielp_txbuf_watermark, 167 PDEV_PARAM_PCIELP_TXBUF_WATERMARK), 168 PARAM_MAP(pdev_param_pcielp_txbuf_tmo_en, 169 PDEV_PARAM_PCIELP_TXBUF_TMO_EN), 170 PARAM_MAP(pdev_param_pcielp_txbuf_tmo_value, 171 PDEV_PARAM_PCIELP_TXBUF_TMO_VALUE), 172 PARAM_MAP(pdev_param_pdev_stats_update_period, 173 PDEV_PARAM_PDEV_STATS_UPDATE_PERIOD), 174 PARAM_MAP(pdev_param_vdev_stats_update_period, 175 PDEV_PARAM_VDEV_STATS_UPDATE_PERIOD), 176 PARAM_MAP(pdev_param_peer_stats_update_period, 177 PDEV_PARAM_PEER_STATS_UPDATE_PERIOD), 178 PARAM_MAP(pdev_param_bcnflt_stats_update_period, 179 PDEV_PARAM_BCNFLT_STATS_UPDATE_PERIOD), 180 PARAM_MAP(pdev_param_pmf_qos, PDEV_PARAM_PMF_QOS), 181 PARAM_MAP(pdev_param_arp_ac_override, PDEV_PARAM_ARP_AC_OVERRIDE), 182 PARAM_MAP(pdev_param_dcs, PDEV_PARAM_DCS), 183 PARAM_MAP(pdev_param_ani_enable, PDEV_PARAM_ANI_ENABLE), 184 PARAM_MAP(pdev_param_ani_poll_period, PDEV_PARAM_ANI_POLL_PERIOD), 185 PARAM_MAP(pdev_param_ani_listen_period, PDEV_PARAM_ANI_LISTEN_PERIOD), 186 PARAM_MAP(pdev_param_ani_ofdm_level, PDEV_PARAM_ANI_OFDM_LEVEL), 187 PARAM_MAP(pdev_param_ani_cck_level, PDEV_PARAM_ANI_CCK_LEVEL), 188 PARAM_MAP(pdev_param_dyntxchain, PDEV_PARAM_DYNTXCHAIN), 189 PARAM_MAP(pdev_param_proxy_sta, PDEV_PARAM_PROXY_STA), 190 PARAM_MAP(pdev_param_idle_ps_config, PDEV_PARAM_IDLE_PS_CONFIG), 191 PARAM_MAP(pdev_param_power_gating_sleep, PDEV_PARAM_POWER_GATING_SLEEP), 192 PARAM_MAP(pdev_param_rfkill_enable, PDEV_PARAM_RFKILL_ENABLE), 193 PARAM_MAP(pdev_param_burst_dur, PDEV_PARAM_BURST_DUR), 194 PARAM_MAP(pdev_param_burst_enable, PDEV_PARAM_BURST_ENABLE), 195 PARAM_MAP(pdev_param_hw_rfkill_config, PDEV_PARAM_HW_RFKILL_CONFIG), 196 PARAM_MAP(pdev_param_low_power_rf_enable, 197 PDEV_PARAM_LOW_POWER_RF_ENABLE), 198 PARAM_MAP(pdev_param_l1ss_track, PDEV_PARAM_L1SS_TRACK), 199 PARAM_MAP(pdev_param_hyst_en, PDEV_PARAM_HYST_EN), 200 PARAM_MAP(pdev_param_power_collapse_enable, 201 PDEV_PARAM_POWER_COLLAPSE_ENABLE), 202 PARAM_MAP(pdev_param_led_sys_state, PDEV_PARAM_LED_SYS_STATE), 203 PARAM_MAP(pdev_param_led_enable, PDEV_PARAM_LED_ENABLE), 204 PARAM_MAP(pdev_param_audio_over_wlan_latency, 205 PDEV_PARAM_AUDIO_OVER_WLAN_LATENCY), 206 PARAM_MAP(pdev_param_audio_over_wlan_enable, 207 PDEV_PARAM_AUDIO_OVER_WLAN_ENABLE), 208 PARAM_MAP(pdev_param_whal_mib_stats_update_enable, 209 PDEV_PARAM_WHAL_MIB_STATS_UPDATE_ENABLE), 210 PARAM_MAP(pdev_param_vdev_rate_stats_update_period, 211 PDEV_PARAM_VDEV_RATE_STATS_UPDATE_PERIOD), 212 PARAM_MAP(pdev_param_cts_cbw, PDEV_PARAM_CTS_CBW), 213 PARAM_MAP(pdev_param_wnts_config, PDEV_PARAM_WNTS_CONFIG), 214 PARAM_MAP(pdev_param_adaptive_early_rx_enable, 215 PDEV_PARAM_ADAPTIVE_EARLY_RX_ENABLE), 216 PARAM_MAP(pdev_param_adaptive_early_rx_min_sleep_slop, 217 PDEV_PARAM_ADAPTIVE_EARLY_RX_MIN_SLEEP_SLOP), 218 PARAM_MAP(pdev_param_adaptive_early_rx_inc_dec_step, 219 PDEV_PARAM_ADAPTIVE_EARLY_RX_INC_DEC_STEP), 220 PARAM_MAP(pdev_param_early_rx_fix_sleep_slop, 221 PDEV_PARAM_EARLY_RX_FIX_SLEEP_SLOP), 222 PARAM_MAP(pdev_param_bmiss_based_adaptive_bto_enable, 223 PDEV_PARAM_BMISS_BASED_ADAPTIVE_BTO_ENABLE), 224 PARAM_MAP(pdev_param_bmiss_bto_min_bcn_timeout, 225 PDEV_PARAM_BMISS_BTO_MIN_BCN_TIMEOUT), 226 PARAM_MAP(pdev_param_bmiss_bto_inc_dec_step, 227 PDEV_PARAM_BMISS_BTO_INC_DEC_STEP), 228 PARAM_MAP(pdev_param_bto_fix_bcn_timeout, 229 PDEV_PARAM_BTO_FIX_BCN_TIMEOUT), 230 PARAM_MAP(pdev_param_ce_based_adaptive_bto_enable, 231 PDEV_PARAM_CE_BASED_ADAPTIVE_BTO_ENABLE), 232 PARAM_MAP(pdev_param_ce_bto_combo_ce_value, 233 PDEV_PARAM_CE_BTO_COMBO_CE_VALUE), 234 PARAM_MAP(pdev_param_tx_chain_mask_2g, PDEV_PARAM_TX_CHAIN_MASK_2G), 235 PARAM_MAP(pdev_param_rx_chain_mask_2g, PDEV_PARAM_RX_CHAIN_MASK_2G), 236 PARAM_MAP(pdev_param_tx_chain_mask_5g, PDEV_PARAM_TX_CHAIN_MASK_5G), 237 PARAM_MAP(pdev_param_rx_chain_mask_5g, PDEV_PARAM_RX_CHAIN_MASK_5G), 238 PARAM_MAP(pdev_param_tx_chain_mask_cck, PDEV_PARAM_TX_CHAIN_MASK_CCK), 239 PARAM_MAP(pdev_param_tx_chain_mask_1ss, PDEV_PARAM_TX_CHAIN_MASK_1SS), 240 PARAM_MAP(pdev_param_soft_tx_chain_mask, PDEV_PARAM_TX_CHAIN_MASK), 241 PARAM_MAP(pdev_param_rx_filter, PDEV_PARAM_RX_FILTER), 242 PARAM_MAP(pdev_set_mcast_to_ucast_tid, PDEV_SET_MCAST_TO_UCAST_TID), 243 PARAM_MAP(pdev_param_mgmt_retry_limit, PDEV_PARAM_MGMT_RETRY_LIMIT), 244 PARAM_MAP(pdev_param_aggr_burst, PDEV_PARAM_AGGR_BURST), 245 PARAM_MAP(pdev_peer_sta_ps_statechg_enable, 246 PDEV_PEER_STA_PS_STATECHG_ENABLE), 247 PARAM_MAP(pdev_param_proxy_sta_mode, PDEV_PARAM_PROXY_STA_MODE), 248 PARAM_MAP(pdev_param_mu_group_policy, PDEV_PARAM_MU_GROUP_POLICY), 249 PARAM_MAP(pdev_param_noise_detection, PDEV_PARAM_NOISE_DETECTION), 250 PARAM_MAP(pdev_param_noise_threshold, PDEV_PARAM_NOISE_THRESHOLD), 251 PARAM_MAP(pdev_param_dpd_enable, PDEV_PARAM_DPD_ENABLE), 252 PARAM_MAP(pdev_param_set_mcast_bcast_echo, 253 PDEV_PARAM_SET_MCAST_BCAST_ECHO), 254 PARAM_MAP(pdev_param_atf_strict_sch, PDEV_PARAM_ATF_STRICT_SCH), 255 PARAM_MAP(pdev_param_atf_sched_duration, PDEV_PARAM_ATF_SCHED_DURATION), 256 PARAM_MAP(pdev_param_ant_plzn, PDEV_PARAM_ANT_PLZN), 257 PARAM_MAP(pdev_param_sensitivity_level, PDEV_PARAM_SENSITIVITY_LEVEL), 258 PARAM_MAP(pdev_param_signed_txpower_2g, PDEV_PARAM_SIGNED_TXPOWER_2G), 259 PARAM_MAP(pdev_param_signed_txpower_5g, PDEV_PARAM_SIGNED_TXPOWER_5G), 260 PARAM_MAP(pdev_param_enable_per_tid_amsdu, 261 PDEV_PARAM_ENABLE_PER_TID_AMSDU), 262 PARAM_MAP(pdev_param_enable_per_tid_ampdu, 263 PDEV_PARAM_ENABLE_PER_TID_AMPDU), 264 PARAM_MAP(pdev_param_cca_threshold, PDEV_PARAM_CCA_THRESHOLD), 265 PARAM_MAP(pdev_param_rts_fixed_rate, PDEV_PARAM_RTS_FIXED_RATE), 266 PARAM_MAP(pdev_param_cal_period, UNAVAILABLE_PARAM), 267 PARAM_MAP(pdev_param_pdev_reset, PDEV_PARAM_PDEV_RESET), 268 PARAM_MAP(pdev_param_wapi_mbssid_offset, PDEV_PARAM_WAPI_MBSSID_OFFSET), 269 PARAM_MAP(pdev_param_arp_srcaddr, PDEV_PARAM_ARP_DBG_SRCADDR), 270 PARAM_MAP(pdev_param_arp_dstaddr, PDEV_PARAM_ARP_DBG_DSTADDR), 271 PARAM_MAP(pdev_param_txpower_decr_db, PDEV_PARAM_TXPOWER_DECR_DB), 272 PARAM_MAP(pdev_param_rx_batchmode, UNAVAILABLE_PARAM), 273 PARAM_MAP(pdev_param_packet_aggr_delay, UNAVAILABLE_PARAM), 274 PARAM_MAP(pdev_param_atf_obss_noise_sch, PDEV_PARAM_ATF_OBSS_NOISE_SCH), 275 PARAM_MAP(pdev_param_atf_obss_noise_scaling_factor, 276 PDEV_PARAM_ATF_OBSS_NOISE_SCALING_FACTOR), 277 PARAM_MAP(pdev_param_cust_txpower_scale, PDEV_PARAM_CUST_TXPOWER_SCALE), 278 PARAM_MAP(pdev_param_atf_dynamic_enable, PDEV_PARAM_ATF_DYNAMIC_ENABLE), 279 PARAM_MAP(pdev_param_atf_ssid_group_policy, UNAVAILABLE_PARAM), 280 PARAM_MAP(pdev_param_igmpmld_override, PDEV_PARAM_IGMPMLD_AC_OVERRIDE), 281 PARAM_MAP(pdev_param_igmpmld_tid, PDEV_PARAM_IGMPMLD_AC_OVERRIDE), 282 PARAM_MAP(pdev_param_antenna_gain, PDEV_PARAM_ANTENNA_GAIN), 283 PARAM_MAP(pdev_param_block_interbss, PDEV_PARAM_BLOCK_INTERBSS), 284 PARAM_MAP(pdev_param_set_disable_reset_cmdid, 285 PDEV_PARAM_SET_DISABLE_RESET_CMDID), 286 PARAM_MAP(pdev_param_set_msdu_ttl_cmdid, PDEV_PARAM_SET_MSDU_TTL_CMDID), 287 PARAM_MAP(pdev_param_txbf_sound_period_cmdid, 288 PDEV_PARAM_TXBF_SOUND_PERIOD_CMDID), 289 PARAM_MAP(pdev_param_set_burst_mode_cmdid, 290 PDEV_PARAM_SET_BURST_MODE_CMDID), 291 PARAM_MAP(pdev_param_en_stats, PDEV_PARAM_EN_STATS), 292 PARAM_MAP(pdev_param_mesh_mcast_enable, PDEV_PARAM_MESH_MCAST_ENABLE), 293 PARAM_MAP(pdev_param_set_promisc_mode_cmdid, 294 PDEV_PARAM_SET_PROMISC_MODE_CMDID), 295 PARAM_MAP(pdev_param_set_ppdu_duration_cmdid, 296 PDEV_PARAM_SET_PPDU_DURATION_CMDID), 297 PARAM_MAP(pdev_param_remove_mcast2ucast_buffer, 298 PDEV_PARAM_REMOVE_MCAST2UCAST_BUFFER), 299 PARAM_MAP(pdev_param_set_mcast2ucast_buffer, 300 PDEV_PARAM_SET_MCAST2UCAST_BUFFER), 301 PARAM_MAP(pdev_param_set_mcast2ucast_mode, 302 PDEV_PARAM_SET_MCAST2UCAST_MODE), 303 PARAM_MAP(pdev_param_smart_antenna_default_antenna, 304 PDEV_PARAM_SMART_ANTENNA_DEFAULT_ANTENNA), 305 PARAM_MAP(pdev_param_fast_channel_reset, 306 PDEV_PARAM_FAST_CHANNEL_RESET), 307 PARAM_MAP(pdev_param_rx_decap_mode, PDEV_PARAM_RX_DECAP_MODE), 308 PARAM_MAP(pdev_param_tx_ack_timeout, PDEV_PARAM_ACK_TIMEOUT), 309 PARAM_MAP(pdev_param_cck_tx_enable, PDEV_PARAM_CCK_TX_ENABLE), 310 PARAM_MAP(pdev_param_antenna_gain_half_db, 311 PDEV_PARAM_ANTENNA_GAIN_HALF_DB), 312 PARAM_MAP(pdev_param_esp_indication_period, 313 PDEV_PARAM_ESP_INDICATION_PERIOD), 314 PARAM_MAP(pdev_param_esp_ba_window, PDEV_PARAM_ESP_BA_WINDOW), 315 PARAM_MAP(pdev_param_esp_airtime_fraction, 316 PDEV_PARAM_ESP_AIRTIME_FRACTION), 317 PARAM_MAP(pdev_param_esp_ppdu_duration, PDEV_PARAM_ESP_PPDU_DURATION), 318 PARAM_MAP(pdev_param_ru26_allowed, PDEV_PARAM_UL_RU26_ALLOWED), 319 PARAM_MAP(pdev_param_use_nol, PDEV_PARAM_USE_NOL), 320 PARAM_MAP(pdev_param_ul_trig_int, PDEV_PARAM_SET_UL_BSR_TRIG_INTERVAL), 321 PARAM_MAP(pdev_param_sub_channel_marking, 322 PDEV_PARAM_SUB_CHANNEL_MARKING), 323 PARAM_MAP(pdev_param_ul_ppdu_duration, PDEV_PARAM_SET_UL_PPDU_DURATION), 324 PARAM_MAP(pdev_param_equal_ru_allocation_enable, 325 PDEV_PARAM_EQUAL_RU_ALLOCATION_ENABLE), 326 PARAM_MAP(pdev_param_per_peer_prd_cfr_enable, 327 PDEV_PARAM_PER_PEER_PERIODIC_CFR_ENABLE), 328 PARAM_MAP(pdev_param_nav_override_config, 329 PDEV_PARAM_NAV_OVERRIDE_CONFIG), 330 PARAM_MAP(pdev_param_set_mgmt_ttl, PDEV_PARAM_SET_MGMT_TTL), 331 PARAM_MAP(pdev_param_set_prb_rsp_ttl, 332 PDEV_PARAM_SET_PROBE_RESP_TTL), 333 PARAM_MAP(pdev_param_set_mu_ppdu_duration, 334 PDEV_PARAM_SET_MU_PPDU_DURATION), 335 PARAM_MAP(pdev_param_set_tbtt_ctrl, 336 PDEV_PARAM_SET_TBTT_CTRL), 337 PARAM_MAP(pdev_param_set_cmd_obss_pd_threshold, 338 PDEV_PARAM_SET_CMD_OBSS_PD_THRESHOLD), 339 PARAM_MAP(pdev_param_set_cmd_obss_pd_per_ac, 340 PDEV_PARAM_SET_CMD_OBSS_PD_PER_AC), 341 PARAM_MAP(pdev_param_set_cong_ctrl_max_msdus, 342 PDEV_PARAM_SET_CONG_CTRL_MAX_MSDUS), 343 PARAM_MAP(pdev_param_enable_fw_dynamic_he_edca, 344 PDEV_PARAM_ENABLE_FW_DYNAMIC_HE_EDCA), 345 PARAM_MAP(pdev_param_enable_srp, PDEV_PARAM_ENABLE_SRP), 346 PARAM_MAP(pdev_param_enable_sr_prohibit, PDEV_PARAM_ENABLE_SR_PROHIBIT), 347 PARAM_MAP(pdev_param_sr_trigger_margin, PDEV_PARAM_SR_TRIGGER_MARGIN), 348 PARAM_MAP(pdev_param_pream_punct_bw, PDEV_PARAM_SET_PREAM_PUNCT_BW), 349 PARAM_MAP(pdev_param_enable_mbssid_ctrl_frame, 350 PDEV_PARAM_ENABLE_MBSSID_CTRL_FRAME), 351 PARAM_MAP(pdev_param_set_mesh_params, PDEV_PARAM_SET_MESH_PARAMS), 352 PARAM_MAP(pdev_param_mpd_userpd_ssr, PDEV_PARAM_MPD_USERPD_SSR), 353 PARAM_MAP(pdev_param_low_latency_mode, 354 PDEV_PARAM_LOW_LATENCY_SCHED_MODE), 355 PARAM_MAP(pdev_param_scan_radio_tx_on_dfs, 356 PDEV_PARAM_SCAN_RADIO_TX_ON_DFS), 357 PARAM_MAP(pdev_param_en_probe_all_bw, 358 PDEV_PARAM_EN_PROBE_ALL_BW), 359 PARAM_MAP(pdev_param_obss_min_duration_check_for_sr, 360 PDEV_PARAM_OBSS_MIN_DURATION_CHECK_FOR_SR), 361 PARAM_MAP(pdev_param_truncate_sr, PDEV_PARAM_TRUNCATE_SR), 362 PARAM_MAP(pdev_param_ctrl_frame_obss_pd_threshold, 363 PDEV_PARAM_CTRL_FRAME_OBSS_PD_THRESHOLD), 364 PARAM_MAP(pdev_param_rate_upper_cap, PDEV_PARAM_RATE_UPPER_CAP), 365 PARAM_MAP(pdev_param_rate_retry_mcs_drop, 366 PDEV_PARAM_SET_RATE_DROP_DOWN_RETRY_THRESH), 367 PARAM_MAP(pdev_param_mcs_probe_intvl, 368 PDEV_PARAM_MIN_MAX_MCS_PROBE_INTERVAL), 369 PARAM_MAP(pdev_param_nss_probe_intvl, 370 PDEV_PARAM_MIN_MAX_NSS_PROBE_INTERVAL), 371 PARAM_MAP(pdev_param_dtim_synth, PDEV_PARAM_DTIM_SYNTH), 372 PARAM_MAP(pdev_param_1ch_dtim_optimized_chain_selection, 373 PDEV_PARAM_1CH_DTIM_OPTIMIZED_CHAIN_SELECTION), 374 PARAM_MAP(pdev_param_tx_sch_delay, PDEV_PARAM_TX_SCH_DELAY), 375 PARAM_MAP(pdev_param_en_update_scram_seed, 376 PDEV_PARAM_EN_UPDATE_SCRAM_SEED), 377 PARAM_MAP(pdev_param_secondary_retry_enable, 378 PDEV_PARAM_SECONDARY_RETRY_ENABLE), 379 PARAM_MAP(pdev_param_set_sap_xlna_bypass, 380 PDEV_PARAM_SET_SAP_XLNA_BYPASS), 381 PARAM_MAP(pdev_param_set_dfs_chan_ageout_time, 382 PDEV_PARAM_SET_DFS_CHAN_AGEOUT_TIME), 383 PARAM_MAP(pdev_param_pdev_stats_tx_xretry_ext, 384 PDEV_PARAM_PDEV_STATS_TX_XRETRY_EXT), 385 PARAM_MAP(pdev_param_smart_chainmask_scheme, 386 PDEV_PARAM_SMART_CHAINMASK_SCHEME), 387 PARAM_MAP(pdev_param_alternative_chainmask_scheme, 388 PDEV_PARAM_ALTERNATIVE_CHAINMASK_SCHEME), 389 PARAM_MAP(pdev_param_enable_rts_sifs_bursting, 390 PDEV_PARAM_ENABLE_RTS_SIFS_BURSTING), 391 PARAM_MAP(pdev_param_max_mpdus_in_ampdu, PDEV_PARAM_MAX_MPDUS_IN_AMPDU), 392 PARAM_MAP(pdev_param_set_iot_pattern, PDEV_PARAM_SET_IOT_PATTERN), 393 PARAM_MAP(pdev_param_mwscoex_scc_chavd_delay, 394 PDEV_PARAM_MWSCOEX_SCC_CHAVD_DELAY), 395 PARAM_MAP(pdev_param_mwscoex_pcc_chavd_delay, 396 PDEV_PARAM_MWSCOEX_PCC_CHAVD_DELAY), 397 PARAM_MAP(pdev_param_mwscoex_set_5gnr_pwr_limit, 398 PDEV_PARAM_MWSCOEX_SET_5GNR_PWR_LIMIT), 399 PARAM_MAP(pdev_param_mwscoex_4g_allow_quick_ftdm, 400 PDEV_PARAM_MWSCOEX_4G_ALLOW_QUICK_FTDM), 401 PARAM_MAP(pdev_param_fast_pwr_transition, 402 PDEV_PARAM_FAST_PWR_TRANSITION), 403 PARAM_MAP(pdev_auto_detect_power_failure, 404 PDEV_AUTO_DETECT_POWER_FAILURE), 405 PARAM_MAP(pdev_param_gcmp_support_enable, 406 PDEV_PARAM_GCMP_SUPPORT_ENABLE), 407 PARAM_MAP(pdev_param_abg_mode_tx_chain_num, 408 PDEV_PARAM_ABG_MODE_TX_CHAIN_NUM), 409 PARAM_MAP(pdev_param_peer_stats_info_enable, 410 PDEV_PARAM_PEER_STATS_INFO_ENABLE), 411 PARAM_MAP(pdev_param_enable_cck_txfir_override, 412 PDEV_PARAM_ENABLE_CCK_TXFIR_OVERRIDE), 413 PARAM_MAP(pdev_param_twt_ac_config, PDEV_PARAM_TWT_AC_CONFIG), 414 PARAM_MAP(pdev_param_pcie_hw_ilp, PDEV_PARAM_PCIE_HW_ILP), 415 PARAM_MAP(pdev_param_disable_hw_assist, PDEV_PARAM_DISABLE_HW_ASSIST), 416 PARAM_MAP(pdev_param_ant_div_usrcfg, PDEV_PARAM_ANT_DIV_USRCFG), 417 PARAM_MAP(pdev_param_ctrl_retry_limit, PDEV_PARAM_CTRL_RETRY_LIMIT), 418 PARAM_MAP(pdev_param_propagation_delay, PDEV_PARAM_PROPAGATION_DELAY), 419 PARAM_MAP(pdev_param_ena_ant_div, PDEV_PARAM_ENA_ANT_DIV), 420 PARAM_MAP(pdev_param_force_chain_ant, PDEV_PARAM_FORCE_CHAIN_ANT), 421 PARAM_MAP(pdev_param_ant_div_selftest, PDEV_PARAM_ANT_DIV_SELFTEST), 422 PARAM_MAP(pdev_param_ant_div_selftest_intvl, 423 PDEV_PARAM_ANT_DIV_SELFTEST_INTVL), 424 PARAM_MAP(pdev_param_1ch_dtim_optimized_chain_selection, 425 PDEV_PARAM_1CH_DTIM_OPTIMIZED_CHAIN_SELECTION), 426 PARAM_MAP(pdev_param_data_stall_detect_enable, 427 PDEV_PARAM_DATA_STALL_DETECT_ENABLE), 428 PARAM_MAP(pdev_param_max_mpdus_in_ampdu, 429 PDEV_PARAM_MAX_MPDUS_IN_AMPDU), 430 PARAM_MAP(pdev_param_stats_observation_period, 431 PDEV_PARAM_STATS_OBSERVATION_PERIOD), 432 PARAM_MAP(pdev_param_cts2self_for_p2p_go_config, 433 PDEV_PARAM_CTS2SELF_FOR_P2P_GO_CONFIG), 434 PARAM_MAP(pdev_param_txpower_reason_sar, PDEV_PARAM_TXPOWER_REASON_SAR), 435 PARAM_MAP(pdev_param_default_6ghz_rate, PDEV_PARAM_DEFAULT_6GHZ_RATE), 436 }; 437 438 /* Populate vdev_param array whose index is host param, value is target param */ 439 static const uint32_t vdev_param_tlv[] = { 440 PARAM_MAP(vdev_param_rts_threshold, VDEV_PARAM_RTS_THRESHOLD), 441 PARAM_MAP(vdev_param_fragmentation_threshold, 442 VDEV_PARAM_FRAGMENTATION_THRESHOLD), 443 PARAM_MAP(vdev_param_beacon_interval, VDEV_PARAM_BEACON_INTERVAL), 444 PARAM_MAP(vdev_param_listen_interval, VDEV_PARAM_LISTEN_INTERVAL), 445 PARAM_MAP(vdev_param_multicast_rate, VDEV_PARAM_MULTICAST_RATE), 446 PARAM_MAP(vdev_param_mgmt_tx_rate, VDEV_PARAM_MGMT_TX_RATE), 447 PARAM_MAP(vdev_param_slot_time, VDEV_PARAM_SLOT_TIME), 448 PARAM_MAP(vdev_param_preamble, VDEV_PARAM_PREAMBLE), 449 PARAM_MAP(vdev_param_swba_time, VDEV_PARAM_SWBA_TIME), 450 PARAM_MAP(vdev_stats_update_period, VDEV_STATS_UPDATE_PERIOD), 451 PARAM_MAP(vdev_pwrsave_ageout_time, VDEV_PWRSAVE_AGEOUT_TIME), 452 PARAM_MAP(vdev_host_swba_interval, VDEV_HOST_SWBA_INTERVAL), 453 PARAM_MAP(vdev_param_dtim_period, VDEV_PARAM_DTIM_PERIOD), 454 PARAM_MAP(vdev_oc_scheduler_air_time_limit, 455 VDEV_OC_SCHEDULER_AIR_TIME_LIMIT), 456 PARAM_MAP(vdev_param_wds, VDEV_PARAM_WDS), 457 PARAM_MAP(vdev_param_atim_window, VDEV_PARAM_ATIM_WINDOW), 458 PARAM_MAP(vdev_param_bmiss_count_max, VDEV_PARAM_BMISS_COUNT_MAX), 459 PARAM_MAP(vdev_param_bmiss_first_bcnt, VDEV_PARAM_BMISS_FIRST_BCNT), 460 PARAM_MAP(vdev_param_bmiss_final_bcnt, VDEV_PARAM_BMISS_FINAL_BCNT), 461 PARAM_MAP(vdev_param_feature_wmm, VDEV_PARAM_FEATURE_WMM), 462 PARAM_MAP(vdev_param_chwidth, VDEV_PARAM_CHWIDTH), 463 PARAM_MAP(vdev_param_chextoffset, VDEV_PARAM_CHEXTOFFSET), 464 PARAM_MAP(vdev_param_disable_htprotection, 465 VDEV_PARAM_DISABLE_HTPROTECTION), 466 PARAM_MAP(vdev_param_sta_quickkickout, VDEV_PARAM_STA_QUICKKICKOUT), 467 PARAM_MAP(vdev_param_mgmt_rate, VDEV_PARAM_MGMT_RATE), 468 PARAM_MAP(vdev_param_protection_mode, VDEV_PARAM_PROTECTION_MODE), 469 PARAM_MAP(vdev_param_fixed_rate, VDEV_PARAM_FIXED_RATE), 470 PARAM_MAP(vdev_param_sgi, VDEV_PARAM_SGI), 471 PARAM_MAP(vdev_param_ldpc, VDEV_PARAM_LDPC), 472 PARAM_MAP(vdev_param_tx_stbc, VDEV_PARAM_TX_STBC), 473 PARAM_MAP(vdev_param_rx_stbc, VDEV_PARAM_RX_STBC), 474 PARAM_MAP(vdev_param_intra_bss_fwd, VDEV_PARAM_INTRA_BSS_FWD), 475 PARAM_MAP(vdev_param_def_keyid, VDEV_PARAM_DEF_KEYID), 476 PARAM_MAP(vdev_param_nss, VDEV_PARAM_NSS), 477 PARAM_MAP(vdev_param_bcast_data_rate, VDEV_PARAM_BCAST_DATA_RATE), 478 PARAM_MAP(vdev_param_mcast_data_rate, VDEV_PARAM_MCAST_DATA_RATE), 479 PARAM_MAP(vdev_param_mcast_indicate, VDEV_PARAM_MCAST_INDICATE), 480 PARAM_MAP(vdev_param_dhcp_indicate, VDEV_PARAM_DHCP_INDICATE), 481 PARAM_MAP(vdev_param_unknown_dest_indicate, 482 VDEV_PARAM_UNKNOWN_DEST_INDICATE), 483 PARAM_MAP(vdev_param_ap_keepalive_min_idle_inactive_time_secs, 484 VDEV_PARAM_AP_KEEPALIVE_MIN_IDLE_INACTIVE_TIME_SECS), 485 PARAM_MAP(vdev_param_ap_keepalive_max_idle_inactive_time_secs, 486 VDEV_PARAM_AP_KEEPALIVE_MAX_IDLE_INACTIVE_TIME_SECS), 487 PARAM_MAP(vdev_param_ap_keepalive_max_unresponsive_time_secs, 488 VDEV_PARAM_AP_KEEPALIVE_MAX_UNRESPONSIVE_TIME_SECS), 489 PARAM_MAP(vdev_param_ap_enable_nawds, VDEV_PARAM_AP_ENABLE_NAWDS), 490 PARAM_MAP(vdev_param_enable_rtscts, VDEV_PARAM_ENABLE_RTSCTS), 491 PARAM_MAP(vdev_param_txbf, VDEV_PARAM_TXBF), 492 PARAM_MAP(vdev_param_packet_powersave, VDEV_PARAM_PACKET_POWERSAVE), 493 PARAM_MAP(vdev_param_drop_unencry, VDEV_PARAM_DROP_UNENCRY), 494 PARAM_MAP(vdev_param_tx_encap_type, VDEV_PARAM_TX_ENCAP_TYPE), 495 PARAM_MAP(vdev_param_ap_detect_out_of_sync_sleeping_sta_time_secs, 496 VDEV_PARAM_AP_DETECT_OUT_OF_SYNC_SLEEPING_STA_TIME_SECS), 497 PARAM_MAP(vdev_param_early_rx_adjust_enable, 498 VDEV_PARAM_EARLY_RX_ADJUST_ENABLE), 499 PARAM_MAP(vdev_param_early_rx_tgt_bmiss_num, 500 VDEV_PARAM_EARLY_RX_TGT_BMISS_NUM), 501 PARAM_MAP(vdev_param_early_rx_bmiss_sample_cycle, 502 VDEV_PARAM_EARLY_RX_BMISS_SAMPLE_CYCLE), 503 PARAM_MAP(vdev_param_early_rx_slop_step, VDEV_PARAM_EARLY_RX_SLOP_STEP), 504 PARAM_MAP(vdev_param_early_rx_init_slop, VDEV_PARAM_EARLY_RX_INIT_SLOP), 505 PARAM_MAP(vdev_param_early_rx_adjust_pause, 506 VDEV_PARAM_EARLY_RX_ADJUST_PAUSE), 507 PARAM_MAP(vdev_param_tx_pwrlimit, VDEV_PARAM_TX_PWRLIMIT), 508 PARAM_MAP(vdev_param_snr_num_for_cal, VDEV_PARAM_SNR_NUM_FOR_CAL), 509 PARAM_MAP(vdev_param_roam_fw_offload, VDEV_PARAM_ROAM_FW_OFFLOAD), 510 PARAM_MAP(vdev_param_enable_rmc, VDEV_PARAM_ENABLE_RMC), 511 PARAM_MAP(vdev_param_ibss_max_bcn_lost_ms, 512 VDEV_PARAM_IBSS_MAX_BCN_LOST_MS), 513 PARAM_MAP(vdev_param_max_rate, VDEV_PARAM_MAX_RATE), 514 PARAM_MAP(vdev_param_early_rx_drift_sample, 515 VDEV_PARAM_EARLY_RX_DRIFT_SAMPLE), 516 PARAM_MAP(vdev_param_set_ibss_tx_fail_cnt_thr, 517 VDEV_PARAM_SET_IBSS_TX_FAIL_CNT_THR), 518 PARAM_MAP(vdev_param_ebt_resync_timeout, 519 VDEV_PARAM_EBT_RESYNC_TIMEOUT), 520 PARAM_MAP(vdev_param_aggr_trig_event_enable, 521 VDEV_PARAM_AGGR_TRIG_EVENT_ENABLE), 522 PARAM_MAP(vdev_param_is_ibss_power_save_allowed, 523 VDEV_PARAM_IS_IBSS_POWER_SAVE_ALLOWED), 524 PARAM_MAP(vdev_param_is_power_collapse_allowed, 525 VDEV_PARAM_IS_POWER_COLLAPSE_ALLOWED), 526 PARAM_MAP(vdev_param_is_awake_on_txrx_enabled, 527 VDEV_PARAM_IS_AWAKE_ON_TXRX_ENABLED), 528 PARAM_MAP(vdev_param_inactivity_cnt, VDEV_PARAM_INACTIVITY_CNT), 529 PARAM_MAP(vdev_param_txsp_end_inactivity_time_ms, 530 VDEV_PARAM_TXSP_END_INACTIVITY_TIME_MS), 531 PARAM_MAP(vdev_param_dtim_policy, VDEV_PARAM_DTIM_POLICY), 532 PARAM_MAP(vdev_param_ibss_ps_warmup_time_secs, 533 VDEV_PARAM_IBSS_PS_WARMUP_TIME_SECS), 534 PARAM_MAP(vdev_param_ibss_ps_1rx_chain_in_atim_window_enable, 535 VDEV_PARAM_IBSS_PS_1RX_CHAIN_IN_ATIM_WINDOW_ENABLE), 536 PARAM_MAP(vdev_param_rx_leak_window, VDEV_PARAM_RX_LEAK_WINDOW), 537 PARAM_MAP(vdev_param_stats_avg_factor, 538 VDEV_PARAM_STATS_AVG_FACTOR), 539 PARAM_MAP(vdev_param_disconnect_th, VDEV_PARAM_DISCONNECT_TH), 540 PARAM_MAP(vdev_param_rtscts_rate, VDEV_PARAM_RTSCTS_RATE), 541 PARAM_MAP(vdev_param_mcc_rtscts_protection_enable, 542 VDEV_PARAM_MCC_RTSCTS_PROTECTION_ENABLE), 543 PARAM_MAP(vdev_param_mcc_broadcast_probe_enable, 544 VDEV_PARAM_MCC_BROADCAST_PROBE_ENABLE), 545 PARAM_MAP(vdev_param_mgmt_tx_power, VDEV_PARAM_MGMT_TX_POWER), 546 PARAM_MAP(vdev_param_beacon_rate, VDEV_PARAM_BEACON_RATE), 547 PARAM_MAP(vdev_param_rx_decap_type, VDEV_PARAM_RX_DECAP_TYPE), 548 PARAM_MAP(vdev_param_he_dcm_enable, VDEV_PARAM_HE_DCM), 549 PARAM_MAP(vdev_param_he_range_ext_enable, VDEV_PARAM_HE_RANGE_EXT), 550 PARAM_MAP(vdev_param_he_bss_color, VDEV_PARAM_BSS_COLOR), 551 PARAM_MAP(vdev_param_set_hemu_mode, VDEV_PARAM_SET_HEMU_MODE), 552 PARAM_MAP(vdev_param_set_he_sounding_mode, 553 VDEV_PARAM_SET_HE_SOUNDING_MODE), 554 PARAM_MAP(vdev_param_set_heop, VDEV_PARAM_HEOPS_0_31), 555 PARAM_MAP(vdev_param_set_ehtop, VDEV_PARAM_EHTOPS_0_31), 556 PARAM_MAP(vdev_param_set_eht_mu_mode, VDEV_PARAM_SET_EHT_MU_MODE), 557 PARAM_MAP(vdev_param_set_eht_puncturing_mode, 558 VDEV_PARAM_SET_EHT_PUNCTURING_MODE), 559 PARAM_MAP(vdev_param_set_eht_ltf, VDEV_PARAM_EHT_LTF), 560 PARAM_MAP(vdev_param_set_ul_eht_ltf, VDEV_PARAM_UL_EHT_LTF), 561 PARAM_MAP(vdev_param_set_eht_dcm, VDEV_PARAM_EHT_DCM), 562 PARAM_MAP(vdev_param_set_eht_range_ext, VDEV_PARAM_EHT_RANGE_EXT), 563 PARAM_MAP(vdev_param_set_non_data_eht_range_ext, 564 VDEV_PARAM_NON_DATA_EHT_RANGE_EXT), 565 PARAM_MAP(vdev_param_sensor_ap, VDEV_PARAM_SENSOR_AP), 566 PARAM_MAP(vdev_param_dtim_enable_cts, VDEV_PARAM_DTIM_ENABLE_CTS), 567 PARAM_MAP(vdev_param_atf_ssid_sched_policy, 568 VDEV_PARAM_ATF_SSID_SCHED_POLICY), 569 PARAM_MAP(vdev_param_disable_dyn_bw_rts, VDEV_PARAM_DISABLE_DYN_BW_RTS), 570 PARAM_MAP(vdev_param_mcast2ucast_set, VDEV_PARAM_MCAST2UCAST_SET), 571 PARAM_MAP(vdev_param_rc_num_retries, VDEV_PARAM_RC_NUM_RETRIES), 572 PARAM_MAP(vdev_param_cabq_maxdur, VDEV_PARAM_CABQ_MAXDUR), 573 PARAM_MAP(vdev_param_mfptest_set, VDEV_PARAM_MFPTEST_SET), 574 PARAM_MAP(vdev_param_rts_fixed_rate, VDEV_PARAM_RTS_FIXED_RATE), 575 PARAM_MAP(vdev_param_vht_sgimask, VDEV_PARAM_VHT_SGIMASK), 576 PARAM_MAP(vdev_param_vht80_ratemask, VDEV_PARAM_VHT80_RATEMASK), 577 PARAM_MAP(vdev_param_proxy_sta, VDEV_PARAM_PROXY_STA), 578 PARAM_MAP(vdev_param_bw_nss_ratemask, VDEV_PARAM_BW_NSS_RATEMASK), 579 PARAM_MAP(vdev_param_set_he_ltf, VDEV_PARAM_HE_LTF), 580 PARAM_MAP(vdev_param_disable_cabq, VDEV_PARAM_DISABLE_CABQ), 581 PARAM_MAP(vdev_param_rate_dropdown_bmap, VDEV_PARAM_RATE_DROPDOWN_BMAP), 582 PARAM_MAP(vdev_param_set_ba_mode, VDEV_PARAM_BA_MODE), 583 PARAM_MAP(vdev_param_capabilities, VDEV_PARAM_CAPABILITIES), 584 PARAM_MAP(vdev_param_autorate_misc_cfg, VDEV_PARAM_AUTORATE_MISC_CFG), 585 PARAM_MAP(vdev_param_ul_shortgi, VDEV_PARAM_UL_GI), 586 PARAM_MAP(vdev_param_ul_he_ltf, VDEV_PARAM_UL_HE_LTF), 587 PARAM_MAP(vdev_param_ul_nss, VDEV_PARAM_UL_NSS), 588 PARAM_MAP(vdev_param_ul_ppdu_bw, VDEV_PARAM_UL_PPDU_BW), 589 PARAM_MAP(vdev_param_ul_ldpc, VDEV_PARAM_UL_LDPC), 590 PARAM_MAP(vdev_param_ul_stbc, VDEV_PARAM_UL_STBC), 591 PARAM_MAP(vdev_param_ul_fixed_rate, VDEV_PARAM_UL_FIXED_RATE), 592 PARAM_MAP(vdev_param_rawmode_open_war, VDEV_PARAM_RAW_IS_ENCRYPTED), 593 PARAM_MAP(vdev_param_max_mtu_size, VDEV_PARAM_MAX_MTU_SIZE), 594 PARAM_MAP(vdev_param_mcast_rc_stale_period, 595 VDEV_PARAM_MCAST_RC_STALE_PERIOD), 596 PARAM_MAP(vdev_param_enable_multi_group_key, 597 VDEV_PARAM_ENABLE_MULTI_GROUP_KEY), 598 PARAM_MAP(vdev_param_max_group_keys, VDEV_PARAM_NUM_GROUP_KEYS), 599 PARAM_MAP(vdev_param_enable_mcast_rc, VDEV_PARAM_ENABLE_MCAST_RC), 600 PARAM_MAP(vdev_param_6ghz_params, VDEV_PARAM_6GHZ_PARAMS), 601 PARAM_MAP(vdev_param_enable_disable_roam_reason_vsie, 602 VDEV_PARAM_ENABLE_DISABLE_ROAM_REASON_VSIE), 603 PARAM_MAP(vdev_param_set_cmd_obss_pd_threshold, 604 VDEV_PARAM_SET_CMD_OBSS_PD_THRESHOLD), 605 PARAM_MAP(vdev_param_set_cmd_obss_pd_per_ac, 606 VDEV_PARAM_SET_CMD_OBSS_PD_PER_AC), 607 PARAM_MAP(vdev_param_enable_srp, VDEV_PARAM_ENABLE_SRP), 608 PARAM_MAP(vdev_param_nan_config_features, 609 VDEV_PARAM_ENABLE_DISABLE_NAN_CONFIG_FEATURES), 610 PARAM_MAP(vdev_param_enable_disable_rtt_responder_role, 611 VDEV_PARAM_ENABLE_DISABLE_RTT_RESPONDER_ROLE), 612 PARAM_MAP(vdev_param_enable_disable_rtt_initiator_role, 613 VDEV_PARAM_ENABLE_DISABLE_RTT_INITIATOR_ROLE), 614 PARAM_MAP(vdev_param_mcast_steer, VDEV_PARAM_MCAST_STEERING), 615 PARAM_MAP(vdev_param_set_normal_latency_flags_config, 616 VDEV_PARAM_NORMAL_LATENCY_FLAGS_CONFIGURATION), 617 PARAM_MAP(vdev_param_set_xr_latency_flags_config, 618 VDEV_PARAM_XR_LATENCY_FLAGS_CONFIGURATION), 619 PARAM_MAP(vdev_param_set_low_latency_flags_config, 620 VDEV_PARAM_LOW_LATENCY_FLAGS_CONFIGURATION), 621 PARAM_MAP(vdev_param_set_ultra_low_latency_flags_config, 622 VDEV_PARAM_ULTRA_LOW_LATENCY_FLAGS_CONFIGURATION), 623 PARAM_MAP(vdev_param_set_normal_latency_ul_dl_config, 624 VDEV_PARAM_NORMAL_LATENCY_UL_DL_CONFIGURATION), 625 PARAM_MAP(vdev_param_set_xr_latency_ul_dl_config, 626 VDEV_PARAM_XR_LATENCY_UL_DL_CONFIGURATION), 627 PARAM_MAP(vdev_param_set_low_latency_ul_dl_config, 628 VDEV_PARAM_LOW_LATENCY_UL_DL_CONFIGURATION), 629 PARAM_MAP(vdev_param_set_ultra_low_latency_ul_dl_config, 630 VDEV_PARAM_ULTRA_LOW_LATENCY_UL_DL_CONFIGURATION), 631 PARAM_MAP(vdev_param_set_default_ll_config, 632 VDEV_PARAM_DEFAULT_LATENCY_LEVEL_CONFIGURATION), 633 PARAM_MAP(vdev_param_set_multi_client_ll_feature_config, 634 VDEV_PARAM_MULTI_CLIENT_LL_FEATURE_CONFIGURATION), 635 PARAM_MAP(vdev_param_set_traffic_config, 636 VDEV_PARAM_VDEV_TRAFFIC_CONFIG), 637 PARAM_MAP(vdev_param_he_range_ext, VDEV_PARAM_HE_RANGE_EXT), 638 PARAM_MAP(vdev_param_non_data_he_range_ext, 639 VDEV_PARAM_NON_DATA_HE_RANGE_EXT), 640 PARAM_MAP(vdev_param_ndp_inactivity_timeout, 641 VDEV_PARAM_NDP_INACTIVITY_TIMEOUT), 642 PARAM_MAP(vdev_param_ndp_keepalive_timeout, 643 VDEV_PARAM_NDP_KEEPALIVE_TIMEOUT), 644 PARAM_MAP(vdev_param_final_bmiss_time_sec, 645 VDEV_PARAM_FINAL_BMISS_TIME_SEC), 646 PARAM_MAP(vdev_param_final_bmiss_time_wow_sec, 647 VDEV_PARAM_FINAL_BMISS_TIME_WOW_SEC), 648 PARAM_MAP(vdev_param_ap_keepalive_max_idle_inactive_secs, 649 VDEV_PARAM_AP_KEEPALIVE_MAX_IDLE_INACTIVE_TIME_SECS), 650 PARAM_MAP(vdev_param_per_band_mgmt_tx_rate, 651 VDEV_PARAM_PER_BAND_MGMT_TX_RATE), 652 PARAM_MAP(vdev_param_max_li_of_moddtim, 653 VDEV_PARAM_MAX_LI_OF_MODDTIM), 654 PARAM_MAP(vdev_param_moddtim_cnt, VDEV_PARAM_MODDTIM_CNT), 655 PARAM_MAP(vdev_param_max_li_of_moddtim_ms, 656 VDEV_PARAM_MAX_LI_OF_MODDTIM_MS), 657 PARAM_MAP(vdev_param_dyndtim_cnt, VDEV_PARAM_DYNDTIM_CNT), 658 PARAM_MAP(vdev_param_wmm_txop_enable, VDEV_PARAM_WMM_TXOP_ENABLE), 659 PARAM_MAP(vdev_param_enable_bcast_probe_response, 660 VDEV_PARAM_ENABLE_BCAST_PROBE_RESPONSE), 661 PARAM_MAP(vdev_param_fils_max_channel_guard_time, 662 VDEV_PARAM_FILS_MAX_CHANNEL_GUARD_TIME), 663 PARAM_MAP(vdev_param_probe_delay, VDEV_PARAM_PROBE_DELAY), 664 PARAM_MAP(vdev_param_repeat_probe_time, VDEV_PARAM_REPEAT_PROBE_TIME), 665 PARAM_MAP(vdev_param_enable_disable_oce_features, 666 VDEV_PARAM_ENABLE_DISABLE_OCE_FEATURES), 667 PARAM_MAP(vdev_param_enable_disable_nan_config_features, 668 VDEV_PARAM_ENABLE_DISABLE_NAN_CONFIG_FEATURES), 669 PARAM_MAP(vdev_param_rsn_capability, VDEV_PARAM_RSN_CAPABILITY), 670 PARAM_MAP(vdev_param_smps_intolerant, VDEV_PARAM_SMPS_INTOLERANT), 671 PARAM_MAP(vdev_param_abg_mode_tx_chain_num, 672 VDEV_PARAM_ABG_MODE_TX_CHAIN_NUM), 673 PARAM_MAP(vdev_param_nth_beacon_to_host, VDEV_PARAM_NTH_BEACON_TO_HOST), 674 PARAM_MAP(vdev_param_prohibit_data_mgmt, VDEV_PARAM_PROHIBIT_DATA_MGMT), 675 PARAM_MAP(vdev_param_skip_roam_eapol_4way_handshake, 676 VDEV_PARAM_SKIP_ROAM_EAPOL_4WAY_HANDSHAKE), 677 PARAM_MAP(vdev_param_skip_sae_roam_4way_handshake, 678 VDEV_PARAM_SKIP_SAE_ROAM_4WAY_HANDSHAKE), 679 PARAM_MAP(vdev_param_roam_11kv_ctrl, VDEV_PARAM_ROAM_11KV_CTRL), 680 PARAM_MAP(vdev_param_disable_noa_p2p_go, VDEV_PARAM_DISABLE_NOA_P2P_GO), 681 PARAM_MAP(vdev_param_packet_capture_mode, 682 VDEV_PARAM_PACKET_CAPTURE_MODE), 683 PARAM_MAP(vdev_param_smart_monitor_config, 684 VDEV_PARAM_SMART_MONITOR_CONFIG), 685 PARAM_MAP(vdev_param_force_dtim_cnt, VDEV_PARAM_FORCE_DTIM_CNT), 686 PARAM_MAP(vdev_param_sho_config, VDEV_PARAM_SHO_CONFIG), 687 PARAM_MAP(vdev_param_gtx_enable, VDEV_PARAM_GTX_ENABLE), 688 PARAM_MAP(vdev_param_mu_edca_fw_update_en, 689 VDEV_PARAM_MU_EDCA_FW_UPDATE_EN), 690 PARAM_MAP(vdev_param_enable_disable_rtt_initiator_random_mac, 691 VDEV_PARAM_ENABLE_DISABLE_RTT_INITIATOR_RANDOM_MAC), 692 PARAM_MAP(vdev_param_allow_nan_initial_discovery_of_mp0_cluster, 693 VDEV_PARAM_ALLOW_NAN_INITIAL_DISCOVERY_OF_MP0_CLUSTER), 694 PARAM_MAP(vdev_param_txpower_scale_decr_db, 695 VDEV_PARAM_TXPOWER_SCALE_DECR_DB), 696 PARAM_MAP(vdev_param_txpower_scale, VDEV_PARAM_TXPOWER_SCALE), 697 PARAM_MAP(vdev_param_agg_sw_retry_th, VDEV_PARAM_AGG_SW_RETRY_TH), 698 PARAM_MAP(vdev_param_obsspd, VDEV_PARAM_OBSSPD), 699 PARAM_MAP(vdev_param_amsdu_aggregation_size_optimization, 700 VDEV_PARAM_AMSDU_AGGREGATION_SIZE_OPTIMIZATION), 701 PARAM_MAP(vdev_param_non_agg_sw_retry_th, 702 VDEV_PARAM_NON_AGG_SW_RETRY_TH), 703 PARAM_MAP(vdev_param_set_cmd_obss_pd_threshold, 704 VDEV_PARAM_SET_CMD_OBSS_PD_THRESHOLD), 705 }; 706 #endif 707 708 #ifndef WMI_PKTLOG_EVENT_CBF 709 #define WMI_PKTLOG_EVENT_CBF 0x100 710 #endif 711 712 /* 713 * Populate the pktlog event tlv array, where 714 * the values are the FW WMI events, which host 715 * uses to communicate with FW for pktlog 716 */ 717 718 static const uint32_t pktlog_event_tlv[] = { 719 [WMI_HOST_PKTLOG_EVENT_RX_BIT] = WMI_PKTLOG_EVENT_RX, 720 [WMI_HOST_PKTLOG_EVENT_TX_BIT] = WMI_PKTLOG_EVENT_TX, 721 [WMI_HOST_PKTLOG_EVENT_RCF_BIT] = WMI_PKTLOG_EVENT_RCF, 722 [WMI_HOST_PKTLOG_EVENT_RCU_BIT] = WMI_PKTLOG_EVENT_RCU, 723 [WMI_HOST_PKTLOG_EVENT_DBG_PRINT_BIT] = 0, 724 [WMI_HOST_PKTLOG_EVENT_SMART_ANTENNA_BIT] = 725 WMI_PKTLOG_EVENT_SMART_ANTENNA, 726 [WMI_HOST_PKTLOG_EVENT_H_INFO_BIT] = 0, 727 [WMI_HOST_PKTLOG_EVENT_STEERING_BIT] = 0, 728 [WMI_HOST_PKTLOG_EVENT_TX_DATA_CAPTURE_BIT] = 0, 729 [WMI_HOST_PKTLOG_EVENT_PHY_LOGGING_BIT] = WMI_PKTLOG_EVENT_PHY, 730 [WMI_HOST_PKTLOG_EVENT_CBF_BIT] = WMI_PKTLOG_EVENT_CBF, 731 #ifdef BE_PKTLOG_SUPPORT 732 [WMI_HOST_PKTLOG_EVENT_HYBRID_TX_BIT] = WMI_PKTLOG_EVENT_HYBRID_TX, 733 #endif 734 }; 735 736 /** 737 * convert_host_pdev_id_to_target_pdev_id() - Convert pdev_id from 738 * host to target defines. 739 * @wmi_handle: pointer to wmi_handle 740 * @pdev_id: host pdev_id to be converted. 741 * Return: target pdev_id after conversion. 742 */ 743 static uint32_t convert_host_pdev_id_to_target_pdev_id(wmi_unified_t wmi_handle, 744 uint32_t pdev_id) 745 { 746 if (pdev_id <= WMI_HOST_PDEV_ID_2 && pdev_id >= WMI_HOST_PDEV_ID_0) { 747 if (!wmi_handle->soc->is_pdev_is_map_enable) { 748 switch (pdev_id) { 749 case WMI_HOST_PDEV_ID_0: 750 return WMI_PDEV_ID_1ST; 751 case WMI_HOST_PDEV_ID_1: 752 return WMI_PDEV_ID_2ND; 753 case WMI_HOST_PDEV_ID_2: 754 return WMI_PDEV_ID_3RD; 755 } 756 } else { 757 return wmi_handle->cmd_pdev_id_map[pdev_id]; 758 } 759 } else { 760 return WMI_PDEV_ID_SOC; 761 } 762 763 QDF_ASSERT(0); 764 765 return WMI_PDEV_ID_SOC; 766 } 767 768 /** 769 * convert_target_pdev_id_to_host_pdev_id() - Convert pdev_id from 770 * target to host defines. 771 * @wmi_handle: pointer to wmi_handle 772 * @pdev_id: target pdev_id to be converted. 773 * Return: host pdev_id after conversion. 774 */ 775 static uint32_t convert_target_pdev_id_to_host_pdev_id(wmi_unified_t wmi_handle, 776 uint32_t pdev_id) 777 { 778 779 if (pdev_id <= WMI_PDEV_ID_3RD && pdev_id >= WMI_PDEV_ID_1ST) { 780 if (!wmi_handle->soc->is_pdev_is_map_enable) { 781 switch (pdev_id) { 782 case WMI_PDEV_ID_1ST: 783 return WMI_HOST_PDEV_ID_0; 784 case WMI_PDEV_ID_2ND: 785 return WMI_HOST_PDEV_ID_1; 786 case WMI_PDEV_ID_3RD: 787 return WMI_HOST_PDEV_ID_2; 788 } 789 } else { 790 return wmi_handle->evt_pdev_id_map[pdev_id - 1]; 791 } 792 } else if (pdev_id == WMI_PDEV_ID_SOC) { 793 return WMI_HOST_PDEV_ID_SOC; 794 } else { 795 wmi_err("Invalid pdev_id"); 796 } 797 798 return WMI_HOST_PDEV_ID_INVALID; 799 } 800 801 /** 802 * convert_host_phy_id_to_target_phy_id() - Convert phy_id from 803 * host to target defines. 804 * @wmi_handle: pointer to wmi_handle 805 * @phy_id: host pdev_id to be converted. 806 * Return: target phy_id after conversion. 807 */ 808 static uint32_t convert_host_phy_id_to_target_phy_id(wmi_unified_t wmi_handle, 809 uint32_t phy_id) 810 { 811 if (!wmi_handle->soc->is_phy_id_map_enable || 812 phy_id >= WMI_MAX_RADIOS) { 813 return phy_id; 814 } 815 816 return wmi_handle->cmd_phy_id_map[phy_id]; 817 } 818 819 /** 820 * convert_target_phy_id_to_host_phy_id() - Convert phy_id from 821 * target to host defines. 822 * @wmi_handle: pointer to wmi_handle 823 * @phy_id: target phy_id to be converted. 824 * Return: host phy_id after conversion. 825 */ 826 static uint32_t convert_target_phy_id_to_host_phy_id(wmi_unified_t wmi_handle, 827 uint32_t phy_id) 828 { 829 if (!wmi_handle->soc->is_phy_id_map_enable || 830 phy_id >= WMI_MAX_RADIOS) { 831 return phy_id; 832 } 833 834 return wmi_handle->evt_phy_id_map[phy_id]; 835 } 836 837 /** 838 * wmi_tlv_pdev_id_conversion_enable() - Enable pdev_id conversion 839 * @wmi_handle: WMI handle 840 * @pdev_id_map: pointer to mapping table 841 * @size: number of entries in @pdev_id_map 842 * 843 * Return: None. 844 */ 845 static void wmi_tlv_pdev_id_conversion_enable(wmi_unified_t wmi_handle, 846 uint32_t *pdev_id_map, 847 uint8_t size) 848 { 849 int i = 0; 850 851 if (pdev_id_map && (size <= WMI_MAX_RADIOS)) { 852 for (i = 0; i < size; i++) { 853 wmi_handle->cmd_pdev_id_map[i] = pdev_id_map[i]; 854 wmi_handle->evt_pdev_id_map[i] = 855 WMI_HOST_PDEV_ID_INVALID; 856 wmi_handle->cmd_phy_id_map[i] = pdev_id_map[i] - 1; 857 wmi_handle->evt_phy_id_map[i] = 858 WMI_HOST_PDEV_ID_INVALID; 859 } 860 861 for (i = 0; i < size; i++) { 862 if (wmi_handle->cmd_pdev_id_map[i] != 863 WMI_HOST_PDEV_ID_INVALID) { 864 wmi_handle->evt_pdev_id_map 865 [wmi_handle->cmd_pdev_id_map[i] - 1] = i; 866 } 867 if (wmi_handle->cmd_phy_id_map[i] != 868 WMI_HOST_PDEV_ID_INVALID) { 869 wmi_handle->evt_phy_id_map 870 [wmi_handle->cmd_phy_id_map[i]] = i; 871 } 872 } 873 wmi_handle->soc->is_pdev_is_map_enable = true; 874 wmi_handle->soc->is_phy_id_map_enable = true; 875 } else { 876 wmi_handle->soc->is_pdev_is_map_enable = false; 877 wmi_handle->soc->is_phy_id_map_enable = false; 878 } 879 880 wmi_handle->ops->convert_pdev_id_host_to_target = 881 convert_host_pdev_id_to_target_pdev_id; 882 wmi_handle->ops->convert_pdev_id_target_to_host = 883 convert_target_pdev_id_to_host_pdev_id; 884 885 /* phy_id convert function assignments */ 886 wmi_handle->ops->convert_phy_id_host_to_target = 887 convert_host_phy_id_to_target_phy_id; 888 wmi_handle->ops->convert_phy_id_target_to_host = 889 convert_target_phy_id_to_host_phy_id; 890 } 891 892 /* copy_vdev_create_pdev_id() - copy pdev from host params to target command 893 * buffer. 894 * @wmi_handle: pointer to wmi_handle 895 * @cmd: pointer target vdev create command buffer 896 * @param: pointer host params for vdev create 897 * 898 * Return: None 899 */ 900 static inline void copy_vdev_create_pdev_id( 901 struct wmi_unified *wmi_handle, 902 wmi_vdev_create_cmd_fixed_param * cmd, 903 struct vdev_create_params *param) 904 { 905 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 906 wmi_handle, 907 param->pdev_id); 908 } 909 910 void wmi_mtrace(uint32_t message_id, uint16_t vdev_id, uint32_t data) 911 { 912 uint16_t mtrace_message_id; 913 914 mtrace_message_id = QDF_WMI_MTRACE_CMD_ID(message_id) | 915 (QDF_WMI_MTRACE_GRP_ID(message_id) << 916 QDF_WMI_MTRACE_CMD_NUM_BITS); 917 qdf_mtrace(QDF_MODULE_ID_WMI, QDF_MODULE_ID_TARGET, 918 mtrace_message_id, vdev_id, data); 919 } 920 qdf_export_symbol(wmi_mtrace); 921 922 QDF_STATUS wmi_unified_cmd_send_pm_chk(struct wmi_unified *wmi_handle, 923 wmi_buf_t buf, 924 uint32_t buflen, uint32_t cmd_id, 925 bool is_qmi_send_support) 926 { 927 if (!is_qmi_send_support) 928 goto send_over_wmi; 929 930 if (!wmi_is_qmi_stats_enabled(wmi_handle)) 931 goto send_over_wmi; 932 933 if (wmi_is_target_suspend_acked(wmi_handle)) { 934 if (QDF_IS_STATUS_SUCCESS( 935 wmi_unified_cmd_send_over_qmi(wmi_handle, buf, 936 buflen, cmd_id))) 937 return QDF_STATUS_SUCCESS; 938 } 939 940 send_over_wmi: 941 qdf_atomic_set(&wmi_handle->num_stats_over_qmi, 0); 942 943 return wmi_unified_cmd_send(wmi_handle, buf, buflen, cmd_id); 944 } 945 946 /** 947 * send_vdev_create_cmd_tlv() - send VDEV create command to fw 948 * @wmi_handle: wmi handle 949 * @param: pointer to hold vdev create parameter 950 * @macaddr: vdev mac address 951 * 952 * Return: QDF_STATUS_SUCCESS for success or error code 953 */ 954 static QDF_STATUS send_vdev_create_cmd_tlv(wmi_unified_t wmi_handle, 955 uint8_t macaddr[QDF_MAC_ADDR_SIZE], 956 struct vdev_create_params *param) 957 { 958 wmi_vdev_create_cmd_fixed_param *cmd; 959 wmi_buf_t buf; 960 int32_t len = sizeof(*cmd); 961 QDF_STATUS ret; 962 int num_bands = 2; 963 uint8_t *buf_ptr; 964 wmi_vdev_txrx_streams *txrx_streams; 965 966 len += (num_bands * sizeof(*txrx_streams) + WMI_TLV_HDR_SIZE); 967 len += vdev_create_mlo_params_size(param); 968 969 buf = wmi_buf_alloc(wmi_handle, len); 970 if (!buf) 971 return QDF_STATUS_E_NOMEM; 972 973 cmd = (wmi_vdev_create_cmd_fixed_param *) wmi_buf_data(buf); 974 WMITLV_SET_HDR(&cmd->tlv_header, 975 WMITLV_TAG_STRUC_wmi_vdev_create_cmd_fixed_param, 976 WMITLV_GET_STRUCT_TLVLEN 977 (wmi_vdev_create_cmd_fixed_param)); 978 cmd->vdev_id = param->vdev_id; 979 cmd->vdev_type = param->type; 980 cmd->vdev_subtype = param->subtype; 981 cmd->flags = param->mbssid_flags; 982 cmd->flags |= (param->special_vdev_mode ? VDEV_FLAGS_SCAN_MODE_VAP : 0); 983 cmd->vdevid_trans = param->vdevid_trans; 984 cmd->num_cfg_txrx_streams = num_bands; 985 #ifdef QCA_VDEV_STATS_HW_OFFLOAD_SUPPORT 986 cmd->vdev_stats_id_valid = param->vdev_stats_id_valid; 987 cmd->vdev_stats_id = param->vdev_stats_id; 988 #endif 989 copy_vdev_create_pdev_id(wmi_handle, cmd, param); 990 WMI_CHAR_ARRAY_TO_MAC_ADDR(macaddr, &cmd->vdev_macaddr); 991 wmi_debug("ID = %d[pdev:%d] VAP Addr = "QDF_MAC_ADDR_FMT, 992 param->vdev_id, cmd->pdev_id, 993 QDF_MAC_ADDR_REF(macaddr)); 994 buf_ptr = (uint8_t *)cmd + sizeof(*cmd); 995 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 996 (num_bands * sizeof(wmi_vdev_txrx_streams))); 997 buf_ptr += WMI_TLV_HDR_SIZE; 998 999 wmi_debug("type %d, subtype %d, nss_2g %d, nss_5g %d", 1000 param->type, param->subtype, 1001 param->nss_2g, param->nss_5g); 1002 txrx_streams = (wmi_vdev_txrx_streams *)buf_ptr; 1003 txrx_streams->band = WMI_TPC_CHAINMASK_CONFIG_BAND_2G; 1004 txrx_streams->supported_tx_streams = param->nss_2g; 1005 txrx_streams->supported_rx_streams = param->nss_2g; 1006 WMITLV_SET_HDR(&txrx_streams->tlv_header, 1007 WMITLV_TAG_STRUC_wmi_vdev_txrx_streams, 1008 WMITLV_GET_STRUCT_TLVLEN(wmi_vdev_txrx_streams)); 1009 1010 txrx_streams++; 1011 txrx_streams->band = WMI_TPC_CHAINMASK_CONFIG_BAND_5G; 1012 txrx_streams->supported_tx_streams = param->nss_5g; 1013 txrx_streams->supported_rx_streams = param->nss_5g; 1014 WMITLV_SET_HDR(&txrx_streams->tlv_header, 1015 WMITLV_TAG_STRUC_wmi_vdev_txrx_streams, 1016 WMITLV_GET_STRUCT_TLVLEN(wmi_vdev_txrx_streams)); 1017 1018 buf_ptr += (num_bands * sizeof(wmi_vdev_txrx_streams)); 1019 buf_ptr = vdev_create_add_mlo_params(buf_ptr, param); 1020 1021 wmi_mtrace(WMI_VDEV_CREATE_CMDID, cmd->vdev_id, 0); 1022 ret = wmi_unified_cmd_send(wmi_handle, buf, len, WMI_VDEV_CREATE_CMDID); 1023 if (QDF_IS_STATUS_ERROR(ret)) { 1024 wmi_err("Failed to send WMI_VDEV_CREATE_CMDID"); 1025 wmi_buf_free(buf); 1026 } 1027 1028 return ret; 1029 } 1030 1031 /** 1032 * send_vdev_delete_cmd_tlv() - send VDEV delete command to fw 1033 * @wmi_handle: wmi handle 1034 * @if_id: vdev id 1035 * 1036 * Return: QDF_STATUS_SUCCESS for success or error code 1037 */ 1038 static QDF_STATUS send_vdev_delete_cmd_tlv(wmi_unified_t wmi_handle, 1039 uint8_t if_id) 1040 { 1041 wmi_vdev_delete_cmd_fixed_param *cmd; 1042 wmi_buf_t buf; 1043 QDF_STATUS ret; 1044 1045 buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd)); 1046 if (!buf) 1047 return QDF_STATUS_E_NOMEM; 1048 1049 cmd = (wmi_vdev_delete_cmd_fixed_param *) wmi_buf_data(buf); 1050 WMITLV_SET_HDR(&cmd->tlv_header, 1051 WMITLV_TAG_STRUC_wmi_vdev_delete_cmd_fixed_param, 1052 WMITLV_GET_STRUCT_TLVLEN 1053 (wmi_vdev_delete_cmd_fixed_param)); 1054 cmd->vdev_id = if_id; 1055 wmi_mtrace(WMI_VDEV_DELETE_CMDID, cmd->vdev_id, 0); 1056 ret = wmi_unified_cmd_send(wmi_handle, buf, 1057 sizeof(wmi_vdev_delete_cmd_fixed_param), 1058 WMI_VDEV_DELETE_CMDID); 1059 if (QDF_IS_STATUS_ERROR(ret)) { 1060 wmi_err("Failed to send WMI_VDEV_DELETE_CMDID"); 1061 wmi_buf_free(buf); 1062 } 1063 wmi_debug("vdev id = %d", if_id); 1064 1065 return ret; 1066 } 1067 1068 /** 1069 * send_vdev_nss_chain_params_cmd_tlv() - send VDEV nss chain params to fw 1070 * @wmi_handle: wmi handle 1071 * @vdev_id: vdev id 1072 * @user_cfg: user configured nss chain params 1073 * 1074 * Return: QDF_STATUS_SUCCESS for success or error code 1075 */ 1076 static QDF_STATUS 1077 send_vdev_nss_chain_params_cmd_tlv(wmi_unified_t wmi_handle, 1078 uint8_t vdev_id, 1079 struct vdev_nss_chains *user_cfg) 1080 { 1081 wmi_vdev_chainmask_config_cmd_fixed_param *cmd; 1082 wmi_buf_t buf; 1083 QDF_STATUS ret; 1084 1085 buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd)); 1086 if (!buf) 1087 return QDF_STATUS_E_NOMEM; 1088 1089 cmd = (wmi_vdev_chainmask_config_cmd_fixed_param *)wmi_buf_data(buf); 1090 WMITLV_SET_HDR(&cmd->tlv_header, 1091 WMITLV_TAG_STRUC_wmi_vdev_chainmask_config_cmd_fixed_param, 1092 WMITLV_GET_STRUCT_TLVLEN 1093 (wmi_vdev_chainmask_config_cmd_fixed_param)); 1094 cmd->vdev_id = vdev_id; 1095 cmd->disable_rx_mrc_2g = user_cfg->disable_rx_mrc[NSS_CHAINS_BAND_2GHZ]; 1096 cmd->disable_tx_mrc_2g = user_cfg->disable_tx_mrc[NSS_CHAINS_BAND_2GHZ]; 1097 cmd->disable_rx_mrc_5g = user_cfg->disable_rx_mrc[NSS_CHAINS_BAND_5GHZ]; 1098 cmd->disable_tx_mrc_5g = user_cfg->disable_tx_mrc[NSS_CHAINS_BAND_5GHZ]; 1099 cmd->num_rx_chains_2g = user_cfg->num_rx_chains[NSS_CHAINS_BAND_2GHZ]; 1100 cmd->num_tx_chains_2g = user_cfg->num_tx_chains[NSS_CHAINS_BAND_2GHZ]; 1101 cmd->num_rx_chains_5g = user_cfg->num_rx_chains[NSS_CHAINS_BAND_5GHZ]; 1102 cmd->num_tx_chains_5g = user_cfg->num_tx_chains[NSS_CHAINS_BAND_5GHZ]; 1103 cmd->rx_nss_2g = user_cfg->rx_nss[NSS_CHAINS_BAND_2GHZ]; 1104 cmd->tx_nss_2g = user_cfg->tx_nss[NSS_CHAINS_BAND_2GHZ]; 1105 cmd->rx_nss_5g = user_cfg->rx_nss[NSS_CHAINS_BAND_5GHZ]; 1106 cmd->tx_nss_5g = user_cfg->tx_nss[NSS_CHAINS_BAND_5GHZ]; 1107 cmd->num_tx_chains_a = user_cfg->num_tx_chains_11a; 1108 cmd->num_tx_chains_b = user_cfg->num_tx_chains_11b; 1109 cmd->num_tx_chains_g = user_cfg->num_tx_chains_11g; 1110 1111 wmi_mtrace(WMI_VDEV_CHAINMASK_CONFIG_CMDID, cmd->vdev_id, 0); 1112 ret = wmi_unified_cmd_send(wmi_handle, buf, 1113 sizeof(wmi_vdev_chainmask_config_cmd_fixed_param), 1114 WMI_VDEV_CHAINMASK_CONFIG_CMDID); 1115 if (QDF_IS_STATUS_ERROR(ret)) { 1116 wmi_err("Failed to send WMI_VDEV_CHAINMASK_CONFIG_CMDID"); 1117 wmi_buf_free(buf); 1118 } 1119 wmi_debug("vdev_id %d", vdev_id); 1120 1121 return ret; 1122 } 1123 1124 /** 1125 * send_vdev_stop_cmd_tlv() - send vdev stop command to fw 1126 * @wmi: wmi handle 1127 * @vdev_id: vdev id 1128 * 1129 * Return: QDF_STATUS_SUCCESS for success or error code 1130 */ 1131 static QDF_STATUS send_vdev_stop_cmd_tlv(wmi_unified_t wmi, 1132 uint8_t vdev_id) 1133 { 1134 wmi_vdev_stop_cmd_fixed_param *cmd; 1135 wmi_buf_t buf; 1136 int32_t len = sizeof(*cmd); 1137 1138 buf = wmi_buf_alloc(wmi, len); 1139 if (!buf) 1140 return QDF_STATUS_E_NOMEM; 1141 1142 cmd = (wmi_vdev_stop_cmd_fixed_param *) wmi_buf_data(buf); 1143 WMITLV_SET_HDR(&cmd->tlv_header, 1144 WMITLV_TAG_STRUC_wmi_vdev_stop_cmd_fixed_param, 1145 WMITLV_GET_STRUCT_TLVLEN(wmi_vdev_stop_cmd_fixed_param)); 1146 cmd->vdev_id = vdev_id; 1147 wmi_mtrace(WMI_VDEV_STOP_CMDID, cmd->vdev_id, 0); 1148 if (wmi_unified_cmd_send(wmi, buf, len, WMI_VDEV_STOP_CMDID)) { 1149 wmi_err("Failed to send vdev stop command"); 1150 wmi_buf_free(buf); 1151 return QDF_STATUS_E_FAILURE; 1152 } 1153 wmi_debug("vdev id = %d", vdev_id); 1154 1155 return 0; 1156 } 1157 1158 /** 1159 * send_vdev_down_cmd_tlv() - send vdev down command to fw 1160 * @wmi: wmi handle 1161 * @vdev_id: vdev id 1162 * 1163 * Return: QDF_STATUS_SUCCESS for success or error code 1164 */ 1165 static QDF_STATUS send_vdev_down_cmd_tlv(wmi_unified_t wmi, uint8_t vdev_id) 1166 { 1167 wmi_vdev_down_cmd_fixed_param *cmd; 1168 wmi_buf_t buf; 1169 int32_t len = sizeof(*cmd); 1170 1171 buf = wmi_buf_alloc(wmi, len); 1172 if (!buf) 1173 return QDF_STATUS_E_NOMEM; 1174 1175 cmd = (wmi_vdev_down_cmd_fixed_param *) wmi_buf_data(buf); 1176 WMITLV_SET_HDR(&cmd->tlv_header, 1177 WMITLV_TAG_STRUC_wmi_vdev_down_cmd_fixed_param, 1178 WMITLV_GET_STRUCT_TLVLEN(wmi_vdev_down_cmd_fixed_param)); 1179 cmd->vdev_id = vdev_id; 1180 wmi_mtrace(WMI_VDEV_DOWN_CMDID, cmd->vdev_id, 0); 1181 if (wmi_unified_cmd_send(wmi, buf, len, WMI_VDEV_DOWN_CMDID)) { 1182 wmi_err("Failed to send vdev down"); 1183 wmi_buf_free(buf); 1184 return QDF_STATUS_E_FAILURE; 1185 } 1186 wmi_debug("vdev_id %d", vdev_id); 1187 1188 return 0; 1189 } 1190 1191 static inline void copy_channel_info( 1192 wmi_vdev_start_request_cmd_fixed_param * cmd, 1193 wmi_channel *chan, 1194 struct vdev_start_params *req) 1195 { 1196 chan->mhz = req->channel.mhz; 1197 1198 WMI_SET_CHANNEL_MODE(chan, req->channel.phy_mode); 1199 1200 chan->band_center_freq1 = req->channel.cfreq1; 1201 chan->band_center_freq2 = req->channel.cfreq2; 1202 1203 if (req->channel.half_rate) 1204 WMI_SET_CHANNEL_FLAG(chan, WMI_CHAN_FLAG_HALF_RATE); 1205 else if (req->channel.quarter_rate) 1206 WMI_SET_CHANNEL_FLAG(chan, WMI_CHAN_FLAG_QUARTER_RATE); 1207 1208 if (req->channel.dfs_set) { 1209 WMI_SET_CHANNEL_FLAG(chan, WMI_CHAN_FLAG_DFS); 1210 cmd->disable_hw_ack = req->disable_hw_ack; 1211 } 1212 1213 if (req->channel.dfs_set_cfreq2) 1214 WMI_SET_CHANNEL_FLAG(chan, WMI_CHAN_FLAG_DFS_CFREQ2); 1215 1216 if (req->channel.is_stadfs_en) 1217 WMI_SET_CHANNEL_FLAG(chan, WMI_CHAN_FLAG_STA_DFS); 1218 1219 /* According to firmware both reg power and max tx power 1220 * on set channel power is used and set it to max reg 1221 * power from regulatory. 1222 */ 1223 WMI_SET_CHANNEL_MIN_POWER(chan, req->channel.minpower); 1224 WMI_SET_CHANNEL_MAX_POWER(chan, req->channel.maxpower); 1225 WMI_SET_CHANNEL_REG_POWER(chan, req->channel.maxregpower); 1226 WMI_SET_CHANNEL_ANTENNA_MAX(chan, req->channel.antennamax); 1227 WMI_SET_CHANNEL_REG_CLASSID(chan, req->channel.reg_class_id); 1228 WMI_SET_CHANNEL_MAX_TX_POWER(chan, req->channel.maxregpower); 1229 1230 } 1231 1232 /** 1233 * vdev_start_cmd_fill_11be() - 11be information filling in vdev_start 1234 * @cmd: wmi cmd 1235 * @req: vdev start params 1236 * 1237 * Return: QDF status 1238 */ 1239 #ifdef WLAN_FEATURE_11BE 1240 static void 1241 vdev_start_cmd_fill_11be(wmi_vdev_start_request_cmd_fixed_param *cmd, 1242 struct vdev_start_params *req) 1243 { 1244 cmd->eht_ops = req->eht_ops; 1245 cmd->puncture_20mhz_bitmap = ~req->channel.puncture_bitmap; 1246 wmi_info("EHT ops: %x puncture_bitmap %x wmi cmd puncture bitmap %x", 1247 req->eht_ops, req->channel.puncture_bitmap, 1248 cmd->puncture_20mhz_bitmap); 1249 } 1250 #else 1251 static void 1252 vdev_start_cmd_fill_11be(wmi_vdev_start_request_cmd_fixed_param *cmd, 1253 struct vdev_start_params *req) 1254 { 1255 } 1256 #endif 1257 1258 /** 1259 * send_vdev_start_cmd_tlv() - send vdev start request to fw 1260 * @wmi_handle: wmi handle 1261 * @req: vdev start params 1262 * 1263 * Return: QDF status 1264 */ 1265 static QDF_STATUS send_vdev_start_cmd_tlv(wmi_unified_t wmi_handle, 1266 struct vdev_start_params *req) 1267 { 1268 wmi_vdev_start_request_cmd_fixed_param *cmd; 1269 wmi_buf_t buf; 1270 wmi_channel *chan; 1271 int32_t len, ret; 1272 uint8_t *buf_ptr; 1273 1274 len = sizeof(*cmd) + sizeof(wmi_channel) + WMI_TLV_HDR_SIZE; 1275 if (!req->is_restart) 1276 len += vdev_start_mlo_params_size(req); 1277 buf = wmi_buf_alloc(wmi_handle, len); 1278 if (!buf) 1279 return QDF_STATUS_E_NOMEM; 1280 1281 buf_ptr = (uint8_t *) wmi_buf_data(buf); 1282 cmd = (wmi_vdev_start_request_cmd_fixed_param *) buf_ptr; 1283 chan = (wmi_channel *) (buf_ptr + sizeof(*cmd)); 1284 WMITLV_SET_HDR(&cmd->tlv_header, 1285 WMITLV_TAG_STRUC_wmi_vdev_start_request_cmd_fixed_param, 1286 WMITLV_GET_STRUCT_TLVLEN 1287 (wmi_vdev_start_request_cmd_fixed_param)); 1288 WMITLV_SET_HDR(&chan->tlv_header, WMITLV_TAG_STRUC_wmi_channel, 1289 WMITLV_GET_STRUCT_TLVLEN(wmi_channel)); 1290 cmd->vdev_id = req->vdev_id; 1291 1292 /* Fill channel info */ 1293 copy_channel_info(cmd, chan, req); 1294 cmd->beacon_interval = req->beacon_interval; 1295 cmd->dtim_period = req->dtim_period; 1296 1297 cmd->bcn_tx_rate = req->bcn_tx_rate_code; 1298 if (req->bcn_tx_rate_code) 1299 wmi_enable_bcn_ratecode(&cmd->flags); 1300 1301 if (!req->is_restart) { 1302 if (req->pmf_enabled) 1303 cmd->flags |= WMI_UNIFIED_VDEV_START_PMF_ENABLED; 1304 1305 cmd->mbss_capability_flags = req->mbssid_flags; 1306 cmd->vdevid_trans = req->vdevid_trans; 1307 cmd->mbssid_multi_group_flag = req->mbssid_multi_group_flag; 1308 cmd->mbssid_multi_group_id = req->mbssid_multi_group_id; 1309 } 1310 1311 /* Copy the SSID */ 1312 if (req->ssid.length) { 1313 if (req->ssid.length < sizeof(cmd->ssid.ssid)) 1314 cmd->ssid.ssid_len = req->ssid.length; 1315 else 1316 cmd->ssid.ssid_len = sizeof(cmd->ssid.ssid); 1317 qdf_mem_copy(cmd->ssid.ssid, req->ssid.ssid, 1318 cmd->ssid.ssid_len); 1319 } 1320 1321 if (req->hidden_ssid) 1322 cmd->flags |= WMI_UNIFIED_VDEV_START_HIDDEN_SSID; 1323 1324 cmd->flags |= WMI_UNIFIED_VDEV_START_LDPC_RX_ENABLED; 1325 cmd->num_noa_descriptors = req->num_noa_descriptors; 1326 cmd->preferred_rx_streams = req->preferred_rx_streams; 1327 cmd->preferred_tx_streams = req->preferred_tx_streams; 1328 cmd->cac_duration_ms = req->cac_duration_ms; 1329 cmd->regdomain = req->regdomain; 1330 cmd->he_ops = req->he_ops; 1331 1332 buf_ptr = (uint8_t *) (((uintptr_t) cmd) + sizeof(*cmd) + 1333 sizeof(wmi_channel)); 1334 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 1335 cmd->num_noa_descriptors * 1336 sizeof(wmi_p2p_noa_descriptor)); 1337 if (!req->is_restart) { 1338 buf_ptr += WMI_TLV_HDR_SIZE + 1339 (cmd->num_noa_descriptors * sizeof(wmi_p2p_noa_descriptor)); 1340 1341 buf_ptr = vdev_start_add_mlo_params(buf_ptr, req); 1342 buf_ptr = vdev_start_add_ml_partner_links(buf_ptr, req); 1343 } 1344 wmi_info("vdev_id %d freq %d chanmode %d ch_info: 0x%x is_dfs %d " 1345 "beacon interval %d dtim %d center_chan %d center_freq2 %d " 1346 "reg_info_1: 0x%x reg_info_2: 0x%x, req->max_txpow: 0x%x " 1347 "Tx SS %d, Rx SS %d, ldpc_rx: %d, cac %d, regd %d, HE ops: %d" 1348 "req->dis_hw_ack: %d ", req->vdev_id, 1349 chan->mhz, req->channel.phy_mode, chan->info, 1350 req->channel.dfs_set, req->beacon_interval, cmd->dtim_period, 1351 chan->band_center_freq1, chan->band_center_freq2, 1352 chan->reg_info_1, chan->reg_info_2, req->channel.maxregpower, 1353 req->preferred_tx_streams, req->preferred_rx_streams, 1354 req->ldpc_rx_enabled, req->cac_duration_ms, 1355 req->regdomain, req->he_ops, 1356 req->disable_hw_ack); 1357 1358 vdev_start_cmd_fill_11be(cmd, req); 1359 1360 if (req->is_restart) { 1361 wmi_mtrace(WMI_VDEV_RESTART_REQUEST_CMDID, cmd->vdev_id, 0); 1362 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 1363 WMI_VDEV_RESTART_REQUEST_CMDID); 1364 } else { 1365 wmi_mtrace(WMI_VDEV_START_REQUEST_CMDID, cmd->vdev_id, 0); 1366 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 1367 WMI_VDEV_START_REQUEST_CMDID); 1368 } 1369 if (ret) { 1370 wmi_err("Failed to send vdev start command"); 1371 wmi_buf_free(buf); 1372 return QDF_STATUS_E_FAILURE; 1373 } 1374 1375 return QDF_STATUS_SUCCESS; 1376 } 1377 1378 /** 1379 * send_peer_flush_tids_cmd_tlv() - flush peer tids packets in fw 1380 * @wmi: wmi handle 1381 * @peer_addr: peer mac address 1382 * @param: pointer to hold peer flush tid parameter 1383 * 1384 * Return: QDF_STATUS_SUCCESS for success or error code 1385 */ 1386 static QDF_STATUS send_peer_flush_tids_cmd_tlv(wmi_unified_t wmi, 1387 uint8_t peer_addr[QDF_MAC_ADDR_SIZE], 1388 struct peer_flush_params *param) 1389 { 1390 wmi_peer_flush_tids_cmd_fixed_param *cmd; 1391 wmi_buf_t buf; 1392 int32_t len = sizeof(*cmd); 1393 1394 buf = wmi_buf_alloc(wmi, len); 1395 if (!buf) 1396 return QDF_STATUS_E_NOMEM; 1397 1398 cmd = (wmi_peer_flush_tids_cmd_fixed_param *) wmi_buf_data(buf); 1399 WMITLV_SET_HDR(&cmd->tlv_header, 1400 WMITLV_TAG_STRUC_wmi_peer_flush_tids_cmd_fixed_param, 1401 WMITLV_GET_STRUCT_TLVLEN 1402 (wmi_peer_flush_tids_cmd_fixed_param)); 1403 WMI_CHAR_ARRAY_TO_MAC_ADDR(peer_addr, &cmd->peer_macaddr); 1404 cmd->peer_tid_bitmap = param->peer_tid_bitmap; 1405 cmd->vdev_id = param->vdev_id; 1406 wmi_debug("peer_addr "QDF_MAC_ADDR_FMT" vdev_id %d and peer bitmap %d", 1407 QDF_MAC_ADDR_REF(peer_addr), param->vdev_id, 1408 param->peer_tid_bitmap); 1409 wmi_mtrace(WMI_PEER_FLUSH_TIDS_CMDID, cmd->vdev_id, 0); 1410 if (wmi_unified_cmd_send(wmi, buf, len, WMI_PEER_FLUSH_TIDS_CMDID)) { 1411 wmi_err("Failed to send flush tid command"); 1412 wmi_buf_free(buf); 1413 return QDF_STATUS_E_FAILURE; 1414 } 1415 1416 return 0; 1417 } 1418 1419 #ifdef WLAN_FEATURE_PEER_TXQ_FLUSH_CONF 1420 /** 1421 * map_to_wmi_flush_policy() - Map flush policy to firmware defined values 1422 * @policy: The target i/f flush policy value 1423 * 1424 * Return: WMI layer flush policy 1425 */ 1426 static wmi_peer_flush_policy 1427 map_to_wmi_flush_policy(enum peer_txq_flush_policy policy) 1428 { 1429 switch (policy) { 1430 case PEER_TXQ_FLUSH_POLICY_NONE: 1431 return WMI_NO_FLUSH; 1432 case PEER_TXQ_FLUSH_POLICY_TWT_SP_END: 1433 return WMI_TWT_FLUSH; 1434 default: 1435 return WMI_MAX_FLUSH_POLICY; 1436 } 1437 } 1438 1439 /** 1440 * send_peer_txq_flush_config_cmd_tlv() - Send peer TID queue flush config 1441 * @wmi: wmi handle 1442 * @param: Peer txq flush configuration 1443 * 1444 * Return: QDF_STATUS_SUCCESS for success or error code 1445 */ 1446 static QDF_STATUS 1447 send_peer_txq_flush_config_cmd_tlv(wmi_unified_t wmi, 1448 struct peer_txq_flush_config_params *param) 1449 { 1450 wmi_peer_flush_policy_cmd_fixed_param *cmd; 1451 wmi_buf_t buf; 1452 int32_t len = sizeof(*cmd); 1453 1454 buf = wmi_buf_alloc(wmi, len); 1455 if (!buf) 1456 return QDF_STATUS_E_NOMEM; 1457 1458 cmd = (wmi_peer_flush_policy_cmd_fixed_param *)wmi_buf_data(buf); 1459 1460 WMITLV_SET_HDR(&cmd->tlv_header, 1461 WMITLV_TAG_STRUC_wmi_peer_flush_policy_cmd_fixed_param, 1462 WMITLV_GET_STRUCT_TLVLEN 1463 (wmi_peer_flush_policy_cmd_fixed_param)); 1464 1465 WMI_CHAR_ARRAY_TO_MAC_ADDR(param->peer, &cmd->peer_macaddr); 1466 cmd->peer_tid_bitmap = param->tid_mask; 1467 cmd->vdev_id = param->vdev_id; 1468 cmd->flush_policy = map_to_wmi_flush_policy(param->policy); 1469 if (cmd->flush_policy == WMI_MAX_FLUSH_POLICY) { 1470 wmi_buf_free(buf); 1471 wmi_err("Invalid policy"); 1472 return QDF_STATUS_E_INVAL; 1473 } 1474 wmi_debug("peer_addr " QDF_MAC_ADDR_FMT "vdev %d tid %x policy %d", 1475 QDF_MAC_ADDR_REF(param->peer), param->vdev_id, 1476 param->tid_mask, param->policy); 1477 wmi_mtrace(WMI_PEER_FLUSH_POLICY_CMDID, cmd->vdev_id, 0); 1478 if (wmi_unified_cmd_send(wmi, buf, len, WMI_PEER_FLUSH_POLICY_CMDID)) { 1479 wmi_err("Failed to send flush policy command"); 1480 wmi_buf_free(buf); 1481 return QDF_STATUS_E_FAILURE; 1482 } 1483 1484 return QDF_STATUS_SUCCESS; 1485 } 1486 #endif 1487 /** 1488 * send_peer_delete_cmd_tlv() - send PEER delete command to fw 1489 * @wmi: wmi handle 1490 * @peer_addr: peer mac addr 1491 * @param: peer delete parameters 1492 * 1493 * Return: QDF_STATUS_SUCCESS for success or error code 1494 */ 1495 static QDF_STATUS send_peer_delete_cmd_tlv(wmi_unified_t wmi, 1496 uint8_t peer_addr[QDF_MAC_ADDR_SIZE], 1497 struct peer_delete_cmd_params *param) 1498 { 1499 wmi_peer_delete_cmd_fixed_param *cmd; 1500 wmi_buf_t buf; 1501 int32_t len = sizeof(*cmd); 1502 uint8_t *buf_ptr; 1503 1504 len += peer_delete_mlo_params_size(param); 1505 buf = wmi_buf_alloc(wmi, len); 1506 if (!buf) 1507 return QDF_STATUS_E_NOMEM; 1508 1509 buf_ptr = (uint8_t *)wmi_buf_data(buf); 1510 cmd = (wmi_peer_delete_cmd_fixed_param *)buf_ptr; 1511 WMITLV_SET_HDR(&cmd->tlv_header, 1512 WMITLV_TAG_STRUC_wmi_peer_delete_cmd_fixed_param, 1513 WMITLV_GET_STRUCT_TLVLEN 1514 (wmi_peer_delete_cmd_fixed_param)); 1515 WMI_CHAR_ARRAY_TO_MAC_ADDR(peer_addr, &cmd->peer_macaddr); 1516 cmd->vdev_id = param->vdev_id; 1517 buf_ptr = (uint8_t *)(((uintptr_t) cmd) + sizeof(*cmd)); 1518 buf_ptr = peer_delete_add_mlo_params(buf_ptr, param); 1519 wmi_debug("peer_addr "QDF_MAC_ADDR_FMT" vdev_id %d", 1520 QDF_MAC_ADDR_REF(peer_addr), param->vdev_id); 1521 wmi_mtrace(WMI_PEER_DELETE_CMDID, cmd->vdev_id, 0); 1522 if (wmi_unified_cmd_send(wmi, buf, len, WMI_PEER_DELETE_CMDID)) { 1523 wmi_err("Failed to send peer delete command"); 1524 wmi_buf_free(buf); 1525 return QDF_STATUS_E_FAILURE; 1526 } 1527 return 0; 1528 } 1529 1530 static void 1531 wmi_get_converted_peer_bitmap(uint32_t src_peer_bitmap, uint32_t *dst_bitmap) 1532 { 1533 if (QDF_HAS_PARAM(src_peer_bitmap, WLAN_PEER_SELF)) 1534 WMI_VDEV_DELETE_ALL_PEER_BITMAP_SET(dst_bitmap, 1535 WMI_PEER_TYPE_DEFAULT); 1536 1537 if (QDF_HAS_PARAM(src_peer_bitmap, WLAN_PEER_AP)) 1538 WMI_VDEV_DELETE_ALL_PEER_BITMAP_SET(dst_bitmap, 1539 WMI_PEER_TYPE_BSS); 1540 1541 if (QDF_HAS_PARAM(src_peer_bitmap, WLAN_PEER_TDLS)) 1542 WMI_VDEV_DELETE_ALL_PEER_BITMAP_SET(dst_bitmap, 1543 WMI_PEER_TYPE_TDLS); 1544 1545 if (QDF_HAS_PARAM(src_peer_bitmap, WLAN_PEER_NDP)) 1546 WMI_VDEV_DELETE_ALL_PEER_BITMAP_SET(dst_bitmap, 1547 WMI_PEER_TYPE_NAN_DATA); 1548 1549 if (QDF_HAS_PARAM(src_peer_bitmap, WLAN_PEER_RTT_PASN)) 1550 WMI_VDEV_DELETE_ALL_PEER_BITMAP_SET(dst_bitmap, 1551 WMI_PEER_TYPE_PASN); 1552 } 1553 1554 /** 1555 * send_peer_delete_all_cmd_tlv() - send PEER delete all command to fw 1556 * @wmi: wmi handle 1557 * @param: pointer to hold peer delete all parameter 1558 * 1559 * Return: QDF_STATUS_SUCCESS for success or error code 1560 */ 1561 static QDF_STATUS send_peer_delete_all_cmd_tlv( 1562 wmi_unified_t wmi, 1563 struct peer_delete_all_params *param) 1564 { 1565 wmi_vdev_delete_all_peer_cmd_fixed_param *cmd; 1566 wmi_buf_t buf; 1567 int32_t len = sizeof(*cmd); 1568 1569 buf = wmi_buf_alloc(wmi, len); 1570 if (!buf) 1571 return QDF_STATUS_E_NOMEM; 1572 1573 cmd = (wmi_vdev_delete_all_peer_cmd_fixed_param *)wmi_buf_data(buf); 1574 WMITLV_SET_HDR( 1575 &cmd->tlv_header, 1576 WMITLV_TAG_STRUC_wmi_vdev_delete_all_peer_cmd_fixed_param, 1577 WMITLV_GET_STRUCT_TLVLEN 1578 (wmi_vdev_delete_all_peer_cmd_fixed_param)); 1579 cmd->vdev_id = param->vdev_id; 1580 wmi_get_converted_peer_bitmap(param->peer_type_bitmap, 1581 cmd->peer_type_bitmap); 1582 1583 wmi_debug("vdev_id %d peer_type_bitmap:%d", cmd->vdev_id, 1584 param->peer_type_bitmap); 1585 wmi_mtrace(WMI_VDEV_DELETE_ALL_PEER_CMDID, cmd->vdev_id, 0); 1586 if (wmi_unified_cmd_send(wmi, buf, len, 1587 WMI_VDEV_DELETE_ALL_PEER_CMDID)) { 1588 wmi_err("Failed to send peer del all command"); 1589 wmi_buf_free(buf); 1590 return QDF_STATUS_E_FAILURE; 1591 } 1592 1593 return QDF_STATUS_SUCCESS; 1594 } 1595 1596 /** 1597 * convert_host_peer_param_id_to_target_id_tlv - convert host peer param_id 1598 * to target id. 1599 * @peer_param_id: host param id. 1600 * 1601 * Return: Target param id. 1602 */ 1603 #ifdef ENABLE_HOST_TO_TARGET_CONVERSION 1604 static inline uint32_t convert_host_peer_param_id_to_target_id_tlv( 1605 uint32_t peer_param_id) 1606 { 1607 if (peer_param_id < QDF_ARRAY_SIZE(peer_param_tlv)) 1608 return peer_param_tlv[peer_param_id]; 1609 return WMI_UNAVAILABLE_PARAM; 1610 } 1611 #else 1612 static inline uint32_t convert_host_peer_param_id_to_target_id_tlv( 1613 uint32_t peer_param_id) 1614 { 1615 return peer_param_id; 1616 } 1617 #endif 1618 1619 /** 1620 * wmi_host_chan_bw_to_target_chan_bw - convert wmi_host_channel_width to 1621 * wmi_channel_width 1622 * @bw: wmi_host_channel_width channel width 1623 * 1624 * Return: wmi_channel_width 1625 */ 1626 static wmi_channel_width wmi_host_chan_bw_to_target_chan_bw( 1627 wmi_host_channel_width bw) 1628 { 1629 wmi_channel_width target_bw = WMI_CHAN_WIDTH_20; 1630 1631 switch (bw) { 1632 case WMI_HOST_CHAN_WIDTH_20: 1633 target_bw = WMI_CHAN_WIDTH_20; 1634 break; 1635 case WMI_HOST_CHAN_WIDTH_40: 1636 target_bw = WMI_CHAN_WIDTH_40; 1637 break; 1638 case WMI_HOST_CHAN_WIDTH_80: 1639 target_bw = WMI_CHAN_WIDTH_80; 1640 break; 1641 case WMI_HOST_CHAN_WIDTH_160: 1642 target_bw = WMI_CHAN_WIDTH_160; 1643 break; 1644 case WMI_HOST_CHAN_WIDTH_80P80: 1645 target_bw = WMI_CHAN_WIDTH_80P80; 1646 break; 1647 case WMI_HOST_CHAN_WIDTH_5: 1648 target_bw = WMI_CHAN_WIDTH_5; 1649 break; 1650 case WMI_HOST_CHAN_WIDTH_10: 1651 target_bw = WMI_CHAN_WIDTH_10; 1652 break; 1653 case WMI_HOST_CHAN_WIDTH_165: 1654 target_bw = WMI_CHAN_WIDTH_165; 1655 break; 1656 case WMI_HOST_CHAN_WIDTH_160P160: 1657 target_bw = WMI_CHAN_WIDTH_160P160; 1658 break; 1659 case WMI_HOST_CHAN_WIDTH_320: 1660 target_bw = WMI_CHAN_WIDTH_320; 1661 break; 1662 default: 1663 break; 1664 } 1665 1666 return target_bw; 1667 } 1668 1669 /** 1670 * convert_host_peer_param_value_to_target_value_tlv() - convert host peer 1671 * param value to target 1672 * @param_id: target param id 1673 * @param_value: host param value 1674 * 1675 * Return: target param value 1676 */ 1677 static uint32_t convert_host_peer_param_value_to_target_value_tlv( 1678 uint32_t param_id, uint32_t param_value) 1679 { 1680 uint32_t fw_param_value = 0; 1681 wmi_host_channel_width bw; 1682 uint16_t punc; 1683 1684 switch (param_id) { 1685 case WMI_PEER_CHWIDTH_PUNCTURE_20MHZ_BITMAP: 1686 bw = QDF_GET_BITS(param_value, 0, 8); 1687 punc = QDF_GET_BITS(param_value, 8, 16); 1688 QDF_SET_BITS(fw_param_value, 0, 8, 1689 wmi_host_chan_bw_to_target_chan_bw(bw)); 1690 QDF_SET_BITS(fw_param_value, 8, 16, ~punc); 1691 break; 1692 default: 1693 fw_param_value = param_value; 1694 break; 1695 } 1696 1697 return fw_param_value; 1698 } 1699 1700 #ifdef WLAN_SUPPORT_PPEDS 1701 /** 1702 * peer_ppe_ds_param_send_tlv() - Set peer PPE DS config 1703 * @wmi: wmi handle 1704 * @param: pointer to hold PPE DS config 1705 * 1706 * Return: QDF_STATUS_SUCCESS for success or error code 1707 */ 1708 static QDF_STATUS peer_ppe_ds_param_send_tlv(wmi_unified_t wmi, 1709 struct peer_ppe_ds_param *param) 1710 { 1711 wmi_peer_config_ppe_ds_cmd_fixed_param *cmd; 1712 wmi_buf_t buf; 1713 int32_t err; 1714 uint32_t len = sizeof(wmi_peer_config_ppe_ds_cmd_fixed_param); 1715 1716 buf = wmi_buf_alloc(wmi, sizeof(*cmd)); 1717 if (!buf) 1718 return QDF_STATUS_E_NOMEM; 1719 1720 cmd = (wmi_peer_config_ppe_ds_cmd_fixed_param *)wmi_buf_data(buf); 1721 WMITLV_SET_HDR(&cmd->tlv_header, 1722 WMITLV_TAG_STRUC_wmi_peer_config_ppe_ds_cmd_fixed_param, 1723 WMITLV_GET_STRUCT_TLVLEN 1724 (wmi_peer_config_ppe_ds_cmd_fixed_param)); 1725 1726 WMI_CHAR_ARRAY_TO_MAC_ADDR(param->peer_macaddr, &cmd->peer_macaddr); 1727 1728 if (param->ppe_routing_enabled) 1729 cmd->ppe_routing_enable = param->use_ppe ? 1730 WMI_AST_USE_PPE_ENABLED : WMI_AST_USE_PPE_DISABLED; 1731 else 1732 cmd->ppe_routing_enable = WMI_PPE_ROUTING_DISABLED; 1733 1734 cmd->service_code = param->service_code; 1735 cmd->priority_valid = param->priority_valid; 1736 cmd->src_info = param->src_info; 1737 cmd->vdev_id = param->vdev_id; 1738 1739 wmi_debug("vdev_id %d peer_mac: QDF_MAC_ADDR_FMT\n" 1740 "ppe_routing_enable: %u service_code: %u\n" 1741 "priority_valid:%d src_info:%u", 1742 param->vdev_id, 1743 QDF_MAC_ADDR_REF(param->peer_macaddr), 1744 param->ppe_routing_enabled, 1745 param->service_code, 1746 param->priority_valid, 1747 param->src_info); 1748 1749 wmi_mtrace(WMI_PEER_CONFIG_PPE_DS_CMDID, cmd->vdev_id, 0); 1750 err = wmi_unified_cmd_send(wmi, buf, 1751 len, 1752 WMI_PEER_CONFIG_PPE_DS_CMDID); 1753 if (err) { 1754 wmi_err("Failed to send ppeds config cmd"); 1755 wmi_buf_free(buf); 1756 return QDF_STATUS_E_FAILURE; 1757 } 1758 1759 return 0; 1760 } 1761 #endif /* WLAN_SUPPORT_PPEDS */ 1762 1763 /** 1764 * send_peer_param_cmd_tlv() - set peer parameter in fw 1765 * @wmi: wmi handle 1766 * @peer_addr: peer mac address 1767 * @param: pointer to hold peer set parameter 1768 * 1769 * Return: QDF_STATUS_SUCCESS for success or error code 1770 */ 1771 static QDF_STATUS send_peer_param_cmd_tlv(wmi_unified_t wmi, 1772 uint8_t peer_addr[QDF_MAC_ADDR_SIZE], 1773 struct peer_set_params *param) 1774 { 1775 wmi_peer_set_param_cmd_fixed_param *cmd; 1776 wmi_buf_t buf; 1777 int32_t err; 1778 uint32_t param_id; 1779 uint32_t param_value; 1780 1781 param_id = convert_host_peer_param_id_to_target_id_tlv(param->param_id); 1782 if (param_id == WMI_UNAVAILABLE_PARAM) { 1783 wmi_err("Unavailable param %d", param->param_id); 1784 return QDF_STATUS_E_NOSUPPORT; 1785 } 1786 param_value = convert_host_peer_param_value_to_target_value_tlv( 1787 param_id, param->param_value); 1788 buf = wmi_buf_alloc(wmi, sizeof(*cmd)); 1789 if (!buf) 1790 return QDF_STATUS_E_NOMEM; 1791 1792 cmd = (wmi_peer_set_param_cmd_fixed_param *) wmi_buf_data(buf); 1793 WMITLV_SET_HDR(&cmd->tlv_header, 1794 WMITLV_TAG_STRUC_wmi_peer_set_param_cmd_fixed_param, 1795 WMITLV_GET_STRUCT_TLVLEN 1796 (wmi_peer_set_param_cmd_fixed_param)); 1797 cmd->vdev_id = param->vdev_id; 1798 WMI_CHAR_ARRAY_TO_MAC_ADDR(peer_addr, &cmd->peer_macaddr); 1799 cmd->param_id = param_id; 1800 cmd->param_value = param_value; 1801 1802 wmi_debug("vdev_id %d peer_mac: "QDF_MAC_ADDR_FMT" param_id: %u param_value: %x", 1803 cmd->vdev_id, 1804 QDF_MAC_ADDR_REF(peer_addr), param->param_id, 1805 cmd->param_value); 1806 1807 wmi_mtrace(WMI_PEER_SET_PARAM_CMDID, cmd->vdev_id, 0); 1808 err = wmi_unified_cmd_send(wmi, buf, 1809 sizeof(wmi_peer_set_param_cmd_fixed_param), 1810 WMI_PEER_SET_PARAM_CMDID); 1811 if (err) { 1812 wmi_err("Failed to send set_param cmd"); 1813 wmi_buf_free(buf); 1814 return QDF_STATUS_E_FAILURE; 1815 } 1816 1817 return 0; 1818 } 1819 1820 /** 1821 * send_vdev_up_cmd_tlv() - send vdev up command in fw 1822 * @wmi: wmi handle 1823 * @bssid: bssid 1824 * @params: pointer to hold vdev up parameter 1825 * 1826 * Return: QDF_STATUS_SUCCESS for success or error code 1827 */ 1828 static QDF_STATUS send_vdev_up_cmd_tlv(wmi_unified_t wmi, 1829 uint8_t bssid[QDF_MAC_ADDR_SIZE], 1830 struct vdev_up_params *params) 1831 { 1832 wmi_vdev_up_cmd_fixed_param *cmd; 1833 wmi_buf_t buf; 1834 int32_t len = sizeof(*cmd); 1835 1836 wmi_debug("VDEV_UP"); 1837 wmi_debug("vdev_id %d aid %d profile idx %d count %d bssid " 1838 QDF_MAC_ADDR_FMT, 1839 params->vdev_id, params->assoc_id, 1840 params->profile_idx, params->profile_num, 1841 QDF_MAC_ADDR_REF(bssid)); 1842 buf = wmi_buf_alloc(wmi, len); 1843 if (!buf) 1844 return QDF_STATUS_E_NOMEM; 1845 1846 cmd = (wmi_vdev_up_cmd_fixed_param *) wmi_buf_data(buf); 1847 WMITLV_SET_HDR(&cmd->tlv_header, 1848 WMITLV_TAG_STRUC_wmi_vdev_up_cmd_fixed_param, 1849 WMITLV_GET_STRUCT_TLVLEN(wmi_vdev_up_cmd_fixed_param)); 1850 cmd->vdev_id = params->vdev_id; 1851 cmd->vdev_assoc_id = params->assoc_id; 1852 cmd->profile_idx = params->profile_idx; 1853 cmd->profile_num = params->profile_num; 1854 WMI_CHAR_ARRAY_TO_MAC_ADDR(params->trans_bssid, &cmd->trans_bssid); 1855 WMI_CHAR_ARRAY_TO_MAC_ADDR(bssid, &cmd->vdev_bssid); 1856 wmi_mtrace(WMI_VDEV_UP_CMDID, cmd->vdev_id, 0); 1857 if (wmi_unified_cmd_send(wmi, buf, len, WMI_VDEV_UP_CMDID)) { 1858 wmi_err("Failed to send vdev up command"); 1859 wmi_buf_free(buf); 1860 return QDF_STATUS_E_FAILURE; 1861 } 1862 1863 return 0; 1864 } 1865 1866 #ifdef ENABLE_HOST_TO_TARGET_CONVERSION 1867 static uint32_t convert_peer_type_host_to_target(uint32_t peer_type) 1868 { 1869 /* Host sets the peer_type as 0 for the peer create command sent to FW 1870 * other than PASN peer create command. 1871 */ 1872 if (peer_type == WLAN_PEER_RTT_PASN) 1873 return WMI_PEER_TYPE_PASN; 1874 1875 return peer_type; 1876 } 1877 #else 1878 static uint32_t convert_peer_type_host_to_target(uint32_t peer_type) 1879 { 1880 return peer_type; 1881 } 1882 #endif 1883 /** 1884 * send_peer_create_cmd_tlv() - send peer create command to fw 1885 * @wmi: wmi handle 1886 * @param: peer create parameters 1887 * 1888 * Return: QDF_STATUS_SUCCESS for success or error code 1889 */ 1890 static QDF_STATUS send_peer_create_cmd_tlv(wmi_unified_t wmi, 1891 struct peer_create_params *param) 1892 { 1893 wmi_peer_create_cmd_fixed_param *cmd; 1894 wmi_buf_t buf; 1895 uint8_t *buf_ptr; 1896 int32_t len = sizeof(*cmd); 1897 1898 len += peer_create_mlo_params_size(param); 1899 buf = wmi_buf_alloc(wmi, len); 1900 if (!buf) 1901 return QDF_STATUS_E_NOMEM; 1902 1903 cmd = (wmi_peer_create_cmd_fixed_param *) wmi_buf_data(buf); 1904 WMITLV_SET_HDR(&cmd->tlv_header, 1905 WMITLV_TAG_STRUC_wmi_peer_create_cmd_fixed_param, 1906 WMITLV_GET_STRUCT_TLVLEN 1907 (wmi_peer_create_cmd_fixed_param)); 1908 WMI_CHAR_ARRAY_TO_MAC_ADDR(param->peer_addr, &cmd->peer_macaddr); 1909 cmd->peer_type = convert_peer_type_host_to_target(param->peer_type); 1910 cmd->vdev_id = param->vdev_id; 1911 1912 buf_ptr = (uint8_t *)wmi_buf_data(buf); 1913 buf_ptr += sizeof(*cmd); 1914 buf_ptr = peer_create_add_mlo_params(buf_ptr, param); 1915 wmi_mtrace(WMI_PEER_CREATE_CMDID, cmd->vdev_id, 0); 1916 if (wmi_unified_cmd_send(wmi, buf, len, WMI_PEER_CREATE_CMDID)) { 1917 wmi_err("Failed to send WMI_PEER_CREATE_CMDID"); 1918 wmi_buf_free(buf); 1919 return QDF_STATUS_E_FAILURE; 1920 } 1921 wmi_debug("peer_addr "QDF_MAC_ADDR_FMT" vdev_id %d", 1922 QDF_MAC_ADDR_REF(param->peer_addr), 1923 param->vdev_id); 1924 1925 return 0; 1926 } 1927 1928 /** 1929 * send_peer_rx_reorder_queue_setup_cmd_tlv() - send rx reorder setup 1930 * command to fw 1931 * @wmi: wmi handle 1932 * @param: Rx reorder queue setup parameters 1933 * 1934 * Return: QDF_STATUS_SUCCESS for success or error code 1935 */ 1936 static 1937 QDF_STATUS send_peer_rx_reorder_queue_setup_cmd_tlv(wmi_unified_t wmi, 1938 struct rx_reorder_queue_setup_params *param) 1939 { 1940 wmi_peer_reorder_queue_setup_cmd_fixed_param *cmd; 1941 wmi_buf_t buf; 1942 int32_t len = sizeof(*cmd); 1943 1944 buf = wmi_buf_alloc(wmi, len); 1945 if (!buf) 1946 return QDF_STATUS_E_NOMEM; 1947 1948 cmd = (wmi_peer_reorder_queue_setup_cmd_fixed_param *)wmi_buf_data(buf); 1949 WMITLV_SET_HDR(&cmd->tlv_header, 1950 WMITLV_TAG_STRUC_wmi_peer_reorder_queue_setup_cmd_fixed_param, 1951 WMITLV_GET_STRUCT_TLVLEN 1952 (wmi_peer_reorder_queue_setup_cmd_fixed_param)); 1953 WMI_CHAR_ARRAY_TO_MAC_ADDR(param->peer_macaddr, &cmd->peer_macaddr); 1954 cmd->vdev_id = param->vdev_id; 1955 cmd->tid = param->tid; 1956 cmd->queue_ptr_lo = param->hw_qdesc_paddr_lo; 1957 cmd->queue_ptr_hi = param->hw_qdesc_paddr_hi; 1958 cmd->queue_no = param->queue_no; 1959 cmd->ba_window_size_valid = param->ba_window_size_valid; 1960 cmd->ba_window_size = param->ba_window_size; 1961 1962 1963 wmi_mtrace(WMI_PEER_REORDER_QUEUE_SETUP_CMDID, cmd->vdev_id, 0); 1964 if (wmi_unified_cmd_send(wmi, buf, len, 1965 WMI_PEER_REORDER_QUEUE_SETUP_CMDID)) { 1966 wmi_err("Fail to send WMI_PEER_REORDER_QUEUE_SETUP_CMDID"); 1967 wmi_buf_free(buf); 1968 return QDF_STATUS_E_FAILURE; 1969 } 1970 wmi_debug("peer_macaddr "QDF_MAC_ADDR_FMT" vdev_id %d, tid %d", 1971 QDF_MAC_ADDR_REF(param->peer_macaddr), 1972 param->vdev_id, param->tid); 1973 1974 return QDF_STATUS_SUCCESS; 1975 } 1976 1977 /** 1978 * send_peer_rx_reorder_queue_remove_cmd_tlv() - send rx reorder remove 1979 * command to fw 1980 * @wmi: wmi handle 1981 * @param: Rx reorder queue remove parameters 1982 * 1983 * Return: QDF_STATUS_SUCCESS for success or error code 1984 */ 1985 static 1986 QDF_STATUS send_peer_rx_reorder_queue_remove_cmd_tlv(wmi_unified_t wmi, 1987 struct rx_reorder_queue_remove_params *param) 1988 { 1989 wmi_peer_reorder_queue_remove_cmd_fixed_param *cmd; 1990 wmi_buf_t buf; 1991 int32_t len = sizeof(*cmd); 1992 1993 buf = wmi_buf_alloc(wmi, len); 1994 if (!buf) 1995 return QDF_STATUS_E_NOMEM; 1996 1997 cmd = (wmi_peer_reorder_queue_remove_cmd_fixed_param *) 1998 wmi_buf_data(buf); 1999 WMITLV_SET_HDR(&cmd->tlv_header, 2000 WMITLV_TAG_STRUC_wmi_peer_reorder_queue_remove_cmd_fixed_param, 2001 WMITLV_GET_STRUCT_TLVLEN 2002 (wmi_peer_reorder_queue_remove_cmd_fixed_param)); 2003 WMI_CHAR_ARRAY_TO_MAC_ADDR(param->peer_macaddr, &cmd->peer_macaddr); 2004 cmd->vdev_id = param->vdev_id; 2005 cmd->tid_mask = param->peer_tid_bitmap; 2006 2007 wmi_mtrace(WMI_PEER_REORDER_QUEUE_REMOVE_CMDID, cmd->vdev_id, 0); 2008 if (wmi_unified_cmd_send(wmi, buf, len, 2009 WMI_PEER_REORDER_QUEUE_REMOVE_CMDID)) { 2010 wmi_err("Fail to send WMI_PEER_REORDER_QUEUE_REMOVE_CMDID"); 2011 wmi_buf_free(buf); 2012 return QDF_STATUS_E_FAILURE; 2013 } 2014 wmi_debug("peer_macaddr "QDF_MAC_ADDR_FMT" vdev_id %d, tid_map %d", 2015 QDF_MAC_ADDR_REF(param->peer_macaddr), 2016 param->vdev_id, param->peer_tid_bitmap); 2017 2018 return QDF_STATUS_SUCCESS; 2019 } 2020 2021 #ifdef WLAN_SUPPORT_GREEN_AP 2022 /** 2023 * send_green_ap_ps_cmd_tlv() - enable green ap powersave command 2024 * @wmi_handle: wmi handle 2025 * @value: value 2026 * @pdev_id: pdev id to have radio context 2027 * 2028 * Return: QDF_STATUS_SUCCESS for success or error code 2029 */ 2030 static QDF_STATUS send_green_ap_ps_cmd_tlv(wmi_unified_t wmi_handle, 2031 uint32_t value, uint8_t pdev_id) 2032 { 2033 wmi_pdev_green_ap_ps_enable_cmd_fixed_param *cmd; 2034 wmi_buf_t buf; 2035 int32_t len = sizeof(*cmd); 2036 2037 wmi_debug("Set Green AP PS val %d", value); 2038 2039 buf = wmi_buf_alloc(wmi_handle, len); 2040 if (!buf) 2041 return QDF_STATUS_E_NOMEM; 2042 2043 cmd = (wmi_pdev_green_ap_ps_enable_cmd_fixed_param *) wmi_buf_data(buf); 2044 WMITLV_SET_HDR(&cmd->tlv_header, 2045 WMITLV_TAG_STRUC_wmi_pdev_green_ap_ps_enable_cmd_fixed_param, 2046 WMITLV_GET_STRUCT_TLVLEN 2047 (wmi_pdev_green_ap_ps_enable_cmd_fixed_param)); 2048 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 2049 wmi_handle, 2050 pdev_id); 2051 cmd->enable = value; 2052 2053 wmi_mtrace(WMI_PDEV_GREEN_AP_PS_ENABLE_CMDID, NO_SESSION, 0); 2054 if (wmi_unified_cmd_send(wmi_handle, buf, len, 2055 WMI_PDEV_GREEN_AP_PS_ENABLE_CMDID)) { 2056 wmi_err("Set Green AP PS param Failed val %d", value); 2057 wmi_buf_free(buf); 2058 return QDF_STATUS_E_FAILURE; 2059 } 2060 2061 return 0; 2062 } 2063 #endif 2064 2065 #ifdef WLAN_SUPPORT_GAP_LL_PS_MODE 2066 static QDF_STATUS send_green_ap_ll_ps_cmd_tlv(wmi_unified_t wmi_handle, 2067 struct green_ap_ll_ps_cmd_param *green_ap_ll_ps_params) 2068 { 2069 uint32_t len; 2070 wmi_buf_t buf; 2071 wmi_xgap_enable_cmd_fixed_param *cmd; 2072 2073 len = sizeof(*cmd); 2074 2075 wmi_debug("Green AP low latency PS: bcn interval: %u state: %u cookie: %u", 2076 green_ap_ll_ps_params->bcn_interval, 2077 green_ap_ll_ps_params->state, 2078 green_ap_ll_ps_params->cookie); 2079 2080 buf = wmi_buf_alloc(wmi_handle, len); 2081 if (!buf) 2082 return QDF_STATUS_E_NOMEM; 2083 2084 cmd = (wmi_xgap_enable_cmd_fixed_param *)wmi_buf_data(buf); 2085 WMITLV_SET_HDR(&cmd->tlv_header, 2086 WMITLV_TAG_STRUC_wmi_xgap_enable_cmd_fixed_param, 2087 WMITLV_GET_STRUCT_TLVLEN 2088 (wmi_xgap_enable_cmd_fixed_param)); 2089 2090 cmd->beacon_interval = green_ap_ll_ps_params->bcn_interval; 2091 cmd->sap_lp_flag = green_ap_ll_ps_params->state; 2092 cmd->dialog_token = green_ap_ll_ps_params->cookie; 2093 2094 wmi_mtrace(WMI_XGAP_ENABLE_CMDID, NO_SESSION, 0); 2095 if (wmi_unified_cmd_send(wmi_handle, buf, len, 2096 WMI_XGAP_ENABLE_CMDID)) { 2097 wmi_err("Green AP Low latency PS cmd Failed"); 2098 wmi_buf_free(buf); 2099 return QDF_STATUS_E_FAILURE; 2100 } 2101 2102 return QDF_STATUS_SUCCESS; 2103 } 2104 #endif 2105 2106 /** 2107 * send_pdev_utf_cmd_tlv() - send utf command to fw 2108 * @wmi_handle: wmi handle 2109 * @param: pointer to pdev_utf_params 2110 * @mac_id: mac id to have radio context 2111 * 2112 * Return: QDF_STATUS_SUCCESS for success or error code 2113 */ 2114 static QDF_STATUS 2115 send_pdev_utf_cmd_tlv(wmi_unified_t wmi_handle, 2116 struct pdev_utf_params *param, 2117 uint8_t mac_id) 2118 { 2119 wmi_buf_t buf; 2120 uint8_t *cmd; 2121 /* if param->len is 0 no data is sent, return error */ 2122 QDF_STATUS ret = QDF_STATUS_E_INVAL; 2123 static uint8_t msgref = 1; 2124 uint8_t segNumber = 0, segInfo, numSegments; 2125 uint16_t chunk_len, total_bytes; 2126 uint8_t *bufpos; 2127 struct seg_hdr_info segHdrInfo; 2128 2129 bufpos = param->utf_payload; 2130 total_bytes = param->len; 2131 ASSERT(total_bytes / MAX_WMI_UTF_LEN == 2132 (uint8_t) (total_bytes / MAX_WMI_UTF_LEN)); 2133 numSegments = (uint8_t) (total_bytes / MAX_WMI_UTF_LEN); 2134 2135 if (param->len - (numSegments * MAX_WMI_UTF_LEN)) 2136 numSegments++; 2137 2138 while (param->len) { 2139 if (param->len > MAX_WMI_UTF_LEN) 2140 chunk_len = MAX_WMI_UTF_LEN; /* MAX message */ 2141 else 2142 chunk_len = param->len; 2143 2144 buf = wmi_buf_alloc(wmi_handle, 2145 (chunk_len + sizeof(segHdrInfo) + 2146 WMI_TLV_HDR_SIZE)); 2147 if (!buf) 2148 return QDF_STATUS_E_NOMEM; 2149 2150 cmd = (uint8_t *) wmi_buf_data(buf); 2151 2152 segHdrInfo.len = total_bytes; 2153 segHdrInfo.msgref = msgref; 2154 segInfo = ((numSegments << 4) & 0xF0) | (segNumber & 0xF); 2155 segHdrInfo.segmentInfo = segInfo; 2156 segHdrInfo.pad = 0; 2157 2158 wmi_debug("segHdrInfo.len = %d, segHdrInfo.msgref = %d," 2159 " segHdrInfo.segmentInfo = %d", 2160 segHdrInfo.len, segHdrInfo.msgref, 2161 segHdrInfo.segmentInfo); 2162 2163 wmi_debug("total_bytes %d segNumber %d totalSegments %d" 2164 " chunk len %d", total_bytes, segNumber, 2165 numSegments, chunk_len); 2166 2167 segNumber++; 2168 2169 WMITLV_SET_HDR(cmd, WMITLV_TAG_ARRAY_BYTE, 2170 (chunk_len + sizeof(segHdrInfo))); 2171 cmd += WMI_TLV_HDR_SIZE; 2172 memcpy(cmd, &segHdrInfo, sizeof(segHdrInfo)); /* 4 bytes */ 2173 WMI_HOST_IF_MSG_COPY_CHAR_ARRAY(&cmd[sizeof(segHdrInfo)], 2174 bufpos, chunk_len); 2175 2176 wmi_mtrace(WMI_PDEV_UTF_CMDID, NO_SESSION, 0); 2177 ret = wmi_unified_cmd_send(wmi_handle, buf, 2178 (chunk_len + sizeof(segHdrInfo) + 2179 WMI_TLV_HDR_SIZE), 2180 WMI_PDEV_UTF_CMDID); 2181 2182 if (QDF_IS_STATUS_ERROR(ret)) { 2183 wmi_err("Failed to send WMI_PDEV_UTF_CMDID command"); 2184 wmi_buf_free(buf); 2185 break; 2186 } 2187 2188 param->len -= chunk_len; 2189 bufpos += chunk_len; 2190 } 2191 2192 msgref++; 2193 2194 return ret; 2195 } 2196 2197 #ifdef ENABLE_HOST_TO_TARGET_CONVERSION 2198 static inline uint32_t convert_host_pdev_param_tlv(uint32_t host_param) 2199 { 2200 if (host_param < QDF_ARRAY_SIZE(pdev_param_tlv)) 2201 return pdev_param_tlv[host_param]; 2202 return WMI_UNAVAILABLE_PARAM; 2203 } 2204 2205 static inline uint32_t convert_host_vdev_param_tlv(uint32_t host_param) 2206 { 2207 if (host_param < QDF_ARRAY_SIZE(vdev_param_tlv)) 2208 return vdev_param_tlv[host_param]; 2209 return WMI_UNAVAILABLE_PARAM; 2210 } 2211 #else 2212 static inline uint32_t convert_host_pdev_param_tlv(uint32_t host_param) 2213 { 2214 return host_param; 2215 } 2216 2217 static inline uint32_t convert_host_vdev_param_tlv(uint32_t host_param) 2218 { 2219 return host_param; 2220 } 2221 #endif /* end of ENABLE_HOST_TO_TARGET_CONVERSION */ 2222 2223 /** 2224 * send_pdev_param_cmd_tlv() - set pdev parameters 2225 * @wmi_handle: wmi handle 2226 * @param: pointer to pdev parameter 2227 * @mac_id: radio context 2228 * 2229 * Return: QDF_STATUS_SUCCESS for success or error code 2230 */ 2231 static QDF_STATUS 2232 send_pdev_param_cmd_tlv(wmi_unified_t wmi_handle, 2233 struct pdev_params *param, 2234 uint8_t mac_id) 2235 { 2236 QDF_STATUS ret; 2237 wmi_pdev_set_param_cmd_fixed_param *cmd; 2238 wmi_buf_t buf; 2239 uint16_t len = sizeof(*cmd); 2240 uint32_t pdev_param; 2241 2242 pdev_param = convert_host_pdev_param_tlv(param->param_id); 2243 if (pdev_param == WMI_UNAVAILABLE_PARAM) { 2244 wmi_err("Unavailable param %d", param->param_id); 2245 return QDF_STATUS_E_INVAL; 2246 } 2247 2248 buf = wmi_buf_alloc(wmi_handle, len); 2249 if (!buf) 2250 return QDF_STATUS_E_NOMEM; 2251 2252 cmd = (wmi_pdev_set_param_cmd_fixed_param *) wmi_buf_data(buf); 2253 WMITLV_SET_HDR(&cmd->tlv_header, 2254 WMITLV_TAG_STRUC_wmi_pdev_set_param_cmd_fixed_param, 2255 WMITLV_GET_STRUCT_TLVLEN 2256 (wmi_pdev_set_param_cmd_fixed_param)); 2257 if (param->is_host_pdev_id) 2258 cmd->pdev_id = wmi_handle->ops->convert_host_pdev_id_to_target( 2259 wmi_handle, 2260 mac_id); 2261 else 2262 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 2263 wmi_handle, 2264 mac_id); 2265 cmd->param_id = pdev_param; 2266 cmd->param_value = param->param_value; 2267 wmi_nofl_debug("Set pdev %d param 0x%x to %u", cmd->pdev_id, 2268 cmd->param_id, cmd->param_value); 2269 wmi_mtrace(WMI_PDEV_SET_PARAM_CMDID, NO_SESSION, 0); 2270 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 2271 WMI_PDEV_SET_PARAM_CMDID); 2272 if (QDF_IS_STATUS_ERROR(ret)) { 2273 wmi_buf_free(buf); 2274 } 2275 return ret; 2276 } 2277 2278 /** 2279 * send_multi_param_cmd_using_pdev_set_param_tlv() - set pdev parameters 2280 * @wmi_handle: wmi handle 2281 * @params: pointer to hold set_multiple_pdev_vdev_param info 2282 * 2283 * Return: QDF_STATUS_SUCCESS for success or error code 2284 */ 2285 static QDF_STATUS 2286 send_multi_param_cmd_using_pdev_set_param_tlv(wmi_unified_t wmi_handle, 2287 struct set_multiple_pdev_vdev_param *params) 2288 { 2289 uint8_t index; 2290 struct pdev_params pdevparam; 2291 uint8_t n_params = params->n_params; 2292 2293 pdevparam.is_host_pdev_id = params->is_host_pdev_id; 2294 for (index = 0; index < n_params; index++) { 2295 pdevparam.param_id = params->params[index].param_id; 2296 pdevparam.param_value = params->params[index].param_value; 2297 if (QDF_IS_STATUS_ERROR(send_pdev_param_cmd_tlv(wmi_handle, 2298 &pdevparam, 2299 params->dev_id))) { 2300 wmi_err("failed to send pdev setparam:%d", 2301 pdevparam.param_id); 2302 return QDF_STATUS_E_FAILURE; 2303 } 2304 } 2305 return QDF_STATUS_SUCCESS; 2306 } 2307 2308 #ifdef WLAN_PDEV_VDEV_SEND_MULTI_PARAM 2309 2310 /** 2311 * convert_host_pdev_vdev_param_id_to_target()- convert host params to target params 2312 * @params: pointer to point set_multiple_pdev_vdev_param info 2313 * 2314 * Return: returns QDF_STATUS 2315 */ 2316 static QDF_STATUS 2317 convert_host_pdev_vdev_param_id_to_target(struct set_multiple_pdev_vdev_param *params) 2318 { 2319 uint8_t index; 2320 uint32_t dev_paramid; 2321 uint8_t num = params->n_params; 2322 2323 if (params->param_type == MLME_PDEV_SETPARAM) { 2324 for (index = 0; index < num; index++) { 2325 dev_paramid = convert_host_pdev_param_tlv(params->params[index].param_id); 2326 if (dev_paramid == WMI_UNAVAILABLE_PARAM) { 2327 wmi_err("pdev param %d not available", 2328 params->params[index].param_id); 2329 return QDF_STATUS_E_INVAL; 2330 } 2331 params->params[index].param_id = dev_paramid; 2332 } 2333 } else if (params->param_type == MLME_VDEV_SETPARAM) { 2334 for (index = 0; index < num; index++) { 2335 dev_paramid = convert_host_vdev_param_tlv(params->params[index].param_id); 2336 if (dev_paramid == WMI_UNAVAILABLE_PARAM) { 2337 wmi_err("vdev param %d not available", 2338 params->params[index].param_id); 2339 return QDF_STATUS_E_INVAL; 2340 } 2341 params->params[index].param_id = dev_paramid; 2342 } 2343 } else { 2344 wmi_err("invalid param type"); 2345 return QDF_STATUS_E_INVAL; 2346 } 2347 return QDF_STATUS_SUCCESS; 2348 } 2349 2350 /** 2351 * send_multi_pdev_vdev_set_param_cmd_tlv()-set pdev/vdev params 2352 * @wmi_handle: wmi handle 2353 * @params: pointer to hold set_multiple_pdev_vdev_param info 2354 * 2355 * Return: returns QDF_STATUS 2356 */ 2357 static QDF_STATUS 2358 send_multi_pdev_vdev_set_param_cmd_tlv( 2359 wmi_unified_t wmi_handle, 2360 struct set_multiple_pdev_vdev_param *params) 2361 { 2362 uint8_t *buf_ptr; 2363 QDF_STATUS ret; 2364 wmi_buf_t buf; 2365 wmi_set_param_info *setparam; 2366 wmi_set_multiple_pdev_vdev_param_cmd_fixed_param *cmd; 2367 uint8_t num = params->n_params; 2368 uint16_t len; 2369 uint8_t index = 0; 2370 const char *dev_string[] = {"pdev", "vdev"}; 2371 2372 if (convert_host_pdev_vdev_param_id_to_target(params)) 2373 return QDF_STATUS_E_INVAL; 2374 2375 len = sizeof(*cmd) + WMI_TLV_HDR_SIZE + (num * sizeof(*setparam)); 2376 buf = wmi_buf_alloc(wmi_handle, len); 2377 if (!buf) 2378 return QDF_STATUS_E_NOMEM; 2379 2380 buf_ptr = (uint8_t *)wmi_buf_data(buf); 2381 cmd = (wmi_set_multiple_pdev_vdev_param_cmd_fixed_param *)buf_ptr; 2382 2383 WMITLV_SET_HDR(&cmd->tlv_header, 2384 WMITLV_TAG_STRUC_wmi_set_multiple_pdev_vdev_param_cmd_fixed_param, 2385 WMITLV_GET_STRUCT_TLVLEN(wmi_set_multiple_pdev_vdev_param_cmd_fixed_param)); 2386 2387 cmd->is_vdev = params->param_type; 2388 if (params->param_type == MLME_PDEV_SETPARAM) { 2389 if (params->is_host_pdev_id) 2390 params->dev_id = wmi_handle->ops->convert_host_pdev_id_to_target(wmi_handle, 2391 params->dev_id); 2392 else 2393 params->dev_id = wmi_handle->ops->convert_pdev_id_host_to_target(wmi_handle, 2394 params->dev_id); 2395 } 2396 cmd->dev_id = params->dev_id; 2397 buf_ptr += sizeof(wmi_set_multiple_pdev_vdev_param_cmd_fixed_param); 2398 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, (num * sizeof(*setparam))); 2399 buf_ptr += WMI_TLV_HDR_SIZE; 2400 for (index = 0; index < num; index++) { 2401 setparam = (wmi_set_param_info *)buf_ptr; 2402 WMITLV_SET_HDR(&setparam->tlv_header, 2403 WMITLV_TAG_STRUC_wmi_set_param_info, 2404 WMITLV_GET_STRUCT_TLVLEN(*setparam)); 2405 setparam->param_id = params->params[index].param_id; 2406 setparam->param_value = params->params[index].param_value; 2407 wmi_nofl_debug("Set %s %d param 0x%x to %u", 2408 dev_string[cmd->is_vdev], params->dev_id, 2409 setparam->param_id, setparam->param_value); 2410 buf_ptr += sizeof(*setparam); 2411 } 2412 wmi_mtrace(WMI_SET_MULTIPLE_PDEV_VDEV_PARAM_CMDID, 2413 cmd->dev_id, 0); 2414 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 2415 WMI_SET_MULTIPLE_PDEV_VDEV_PARAM_CMDID); 2416 if (QDF_IS_STATUS_ERROR(ret)) { 2417 wmi_buf_free(buf); 2418 } 2419 return ret; 2420 } 2421 2422 /** 2423 * send_multiple_pdev_param_cmd_tlv() - set pdev parameters 2424 * @wmi_handle: wmi handle 2425 * @params: pointer to set_multiple_pdev_vdev_param structure 2426 * 2427 * Return: QDF_STATUS_SUCCESS for success or error code 2428 */ 2429 static QDF_STATUS 2430 send_multiple_pdev_param_cmd_tlv(wmi_unified_t wmi_handle, 2431 struct set_multiple_pdev_vdev_param *params) 2432 { 2433 if (!wmi_service_enabled(wmi_handle, 2434 wmi_service_combined_set_param_support)) 2435 return send_multi_param_cmd_using_pdev_set_param_tlv(wmi_handle, 2436 params); 2437 return send_multi_pdev_vdev_set_param_cmd_tlv(wmi_handle, params); 2438 } 2439 2440 #else /* WLAN_PDEV_VDEV_SEND_MULTI_PARAM */ 2441 /** 2442 * send_multiple_pdev_param_cmd_tlv() - set pdev parameters 2443 * @wmi_handle: wmi handle 2444 * @params: pointer to set_multiple_pdev_vdev_param structure 2445 * 2446 * Return: QDF_STATUS_SUCCESS for success or error code 2447 */ 2448 static QDF_STATUS 2449 send_multiple_pdev_param_cmd_tlv(wmi_unified_t wmi_handle, 2450 struct set_multiple_pdev_vdev_param *params) 2451 { 2452 return send_multi_param_cmd_using_pdev_set_param_tlv(wmi_handle, params); 2453 } 2454 #endif /* end of WLAN_PDEV_VDEV_SEND_MULTI_PARAM */ 2455 2456 /** 2457 * send_pdev_set_hw_mode_cmd_tlv() - Send WMI_PDEV_SET_HW_MODE_CMDID to FW 2458 * @wmi_handle: wmi handle 2459 * @hw_mode_index: The HW_Mode field is a enumerated type that is selected 2460 * from the HW_Mode table, which is returned in the WMI_SERVICE_READY_EVENTID. 2461 * 2462 * Provides notification to the WLAN firmware that host driver is requesting a 2463 * HardWare (HW) Mode change. This command is needed to support iHelium in the 2464 * configurations that include the Dual Band Simultaneous (DBS) feature. 2465 * 2466 * Return: Success if the cmd is sent successfully to the firmware 2467 */ 2468 static QDF_STATUS send_pdev_set_hw_mode_cmd_tlv(wmi_unified_t wmi_handle, 2469 uint32_t hw_mode_index) 2470 { 2471 wmi_pdev_set_hw_mode_cmd_fixed_param *cmd; 2472 wmi_buf_t buf; 2473 uint32_t len; 2474 2475 len = sizeof(*cmd); 2476 2477 buf = wmi_buf_alloc(wmi_handle, len); 2478 if (!buf) 2479 return QDF_STATUS_E_NOMEM; 2480 2481 cmd = (wmi_pdev_set_hw_mode_cmd_fixed_param *)wmi_buf_data(buf); 2482 WMITLV_SET_HDR(&cmd->tlv_header, 2483 WMITLV_TAG_STRUC_wmi_pdev_set_hw_mode_cmd_fixed_param, 2484 WMITLV_GET_STRUCT_TLVLEN( 2485 wmi_pdev_set_hw_mode_cmd_fixed_param)); 2486 2487 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 2488 wmi_handle, 2489 WMI_HOST_PDEV_ID_SOC); 2490 cmd->hw_mode_index = hw_mode_index; 2491 wmi_debug("HW mode index:%d", cmd->hw_mode_index); 2492 2493 wmi_mtrace(WMI_PDEV_SET_HW_MODE_CMDID, NO_SESSION, 0); 2494 if (wmi_unified_cmd_send(wmi_handle, buf, len, 2495 WMI_PDEV_SET_HW_MODE_CMDID)) { 2496 wmi_err("Failed to send WMI_PDEV_SET_HW_MODE_CMDID"); 2497 wmi_buf_free(buf); 2498 return QDF_STATUS_E_FAILURE; 2499 } 2500 2501 return QDF_STATUS_SUCCESS; 2502 } 2503 2504 /** 2505 * send_suspend_cmd_tlv() - WMI suspend function 2506 * @wmi_handle: handle to WMI. 2507 * @param: pointer to hold suspend parameter 2508 * @mac_id: radio context 2509 * 2510 * Return: QDF_STATUS_SUCCESS for success or error code 2511 */ 2512 static QDF_STATUS send_suspend_cmd_tlv(wmi_unified_t wmi_handle, 2513 struct suspend_params *param, 2514 uint8_t mac_id) 2515 { 2516 wmi_pdev_suspend_cmd_fixed_param *cmd; 2517 wmi_buf_t wmibuf; 2518 uint32_t len = sizeof(*cmd); 2519 int32_t ret; 2520 2521 /* 2522 * send the command to Target to ignore the 2523 * PCIE reset so as to ensure that Host and target 2524 * states are in sync 2525 */ 2526 wmibuf = wmi_buf_alloc(wmi_handle, len); 2527 if (!wmibuf) 2528 return QDF_STATUS_E_NOMEM; 2529 2530 cmd = (wmi_pdev_suspend_cmd_fixed_param *) wmi_buf_data(wmibuf); 2531 WMITLV_SET_HDR(&cmd->tlv_header, 2532 WMITLV_TAG_STRUC_wmi_pdev_suspend_cmd_fixed_param, 2533 WMITLV_GET_STRUCT_TLVLEN 2534 (wmi_pdev_suspend_cmd_fixed_param)); 2535 if (param->disable_target_intr) 2536 cmd->suspend_opt = WMI_PDEV_SUSPEND_AND_DISABLE_INTR; 2537 else 2538 cmd->suspend_opt = WMI_PDEV_SUSPEND; 2539 2540 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 2541 wmi_handle, 2542 mac_id); 2543 2544 wmi_mtrace(WMI_PDEV_SUSPEND_CMDID, NO_SESSION, 0); 2545 ret = wmi_unified_cmd_send(wmi_handle, wmibuf, len, 2546 WMI_PDEV_SUSPEND_CMDID); 2547 if (ret) { 2548 wmi_buf_free(wmibuf); 2549 wmi_err("Failed to send WMI_PDEV_SUSPEND_CMDID command"); 2550 } 2551 2552 return ret; 2553 } 2554 2555 /** 2556 * send_resume_cmd_tlv() - WMI resume function 2557 * @wmi_handle: handle to WMI. 2558 * @mac_id: radio context 2559 * 2560 * Return: QDF_STATUS_SUCCESS for success or error code 2561 */ 2562 static QDF_STATUS send_resume_cmd_tlv(wmi_unified_t wmi_handle, 2563 uint8_t mac_id) 2564 { 2565 wmi_buf_t wmibuf; 2566 wmi_pdev_resume_cmd_fixed_param *cmd; 2567 QDF_STATUS ret; 2568 2569 wmibuf = wmi_buf_alloc(wmi_handle, sizeof(*cmd)); 2570 if (!wmibuf) 2571 return QDF_STATUS_E_NOMEM; 2572 cmd = (wmi_pdev_resume_cmd_fixed_param *) wmi_buf_data(wmibuf); 2573 WMITLV_SET_HDR(&cmd->tlv_header, 2574 WMITLV_TAG_STRUC_wmi_pdev_resume_cmd_fixed_param, 2575 WMITLV_GET_STRUCT_TLVLEN 2576 (wmi_pdev_resume_cmd_fixed_param)); 2577 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 2578 wmi_handle, 2579 mac_id); 2580 wmi_mtrace(WMI_PDEV_RESUME_CMDID, NO_SESSION, 0); 2581 ret = wmi_unified_cmd_send(wmi_handle, wmibuf, sizeof(*cmd), 2582 WMI_PDEV_RESUME_CMDID); 2583 if (QDF_IS_STATUS_ERROR(ret)) { 2584 wmi_err("Failed to send WMI_PDEV_RESUME_CMDID command"); 2585 wmi_buf_free(wmibuf); 2586 } 2587 2588 return ret; 2589 } 2590 2591 /** 2592 * send_wow_enable_cmd_tlv() - WMI wow enable function 2593 * @wmi_handle: handle to WMI. 2594 * @param: pointer to hold wow enable parameter 2595 * @mac_id: radio context 2596 * 2597 * Return: QDF_STATUS_SUCCESS for success or error code 2598 */ 2599 static QDF_STATUS send_wow_enable_cmd_tlv(wmi_unified_t wmi_handle, 2600 struct wow_cmd_params *param, 2601 uint8_t mac_id) 2602 { 2603 wmi_wow_enable_cmd_fixed_param *cmd; 2604 wmi_buf_t buf; 2605 int32_t len; 2606 int32_t ret; 2607 2608 len = sizeof(wmi_wow_enable_cmd_fixed_param); 2609 2610 buf = wmi_buf_alloc(wmi_handle, len); 2611 if (!buf) 2612 return QDF_STATUS_E_NOMEM; 2613 2614 cmd = (wmi_wow_enable_cmd_fixed_param *) wmi_buf_data(buf); 2615 WMITLV_SET_HDR(&cmd->tlv_header, 2616 WMITLV_TAG_STRUC_wmi_wow_enable_cmd_fixed_param, 2617 WMITLV_GET_STRUCT_TLVLEN 2618 (wmi_wow_enable_cmd_fixed_param)); 2619 cmd->enable = param->enable; 2620 if (param->can_suspend_link) 2621 cmd->pause_iface_config = WOW_IFACE_PAUSE_ENABLED; 2622 else 2623 cmd->pause_iface_config = WOW_IFACE_PAUSE_DISABLED; 2624 cmd->flags = param->flags; 2625 2626 wmi_debug("suspend type: %s flag is 0x%x", 2627 cmd->pause_iface_config == WOW_IFACE_PAUSE_ENABLED ? 2628 "WOW_IFACE_PAUSE_ENABLED" : "WOW_IFACE_PAUSE_DISABLED", 2629 cmd->flags); 2630 2631 wmi_mtrace(WMI_WOW_ENABLE_CMDID, NO_SESSION, 0); 2632 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 2633 WMI_WOW_ENABLE_CMDID); 2634 if (ret) 2635 wmi_buf_free(buf); 2636 2637 return ret; 2638 } 2639 2640 /** 2641 * send_set_ap_ps_param_cmd_tlv() - set ap powersave parameters 2642 * @wmi_handle: wmi handle 2643 * @peer_addr: peer mac address 2644 * @param: pointer to ap_ps parameter structure 2645 * 2646 * Return: QDF_STATUS_SUCCESS for success or error code 2647 */ 2648 static QDF_STATUS send_set_ap_ps_param_cmd_tlv(wmi_unified_t wmi_handle, 2649 uint8_t *peer_addr, 2650 struct ap_ps_params *param) 2651 { 2652 wmi_ap_ps_peer_cmd_fixed_param *cmd; 2653 wmi_buf_t buf; 2654 int32_t err; 2655 2656 buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd)); 2657 if (!buf) 2658 return QDF_STATUS_E_NOMEM; 2659 2660 cmd = (wmi_ap_ps_peer_cmd_fixed_param *) wmi_buf_data(buf); 2661 WMITLV_SET_HDR(&cmd->tlv_header, 2662 WMITLV_TAG_STRUC_wmi_ap_ps_peer_cmd_fixed_param, 2663 WMITLV_GET_STRUCT_TLVLEN 2664 (wmi_ap_ps_peer_cmd_fixed_param)); 2665 cmd->vdev_id = param->vdev_id; 2666 WMI_CHAR_ARRAY_TO_MAC_ADDR(peer_addr, &cmd->peer_macaddr); 2667 cmd->param = param->param; 2668 cmd->value = param->value; 2669 wmi_mtrace(WMI_AP_PS_PEER_PARAM_CMDID, cmd->vdev_id, 0); 2670 err = wmi_unified_cmd_send(wmi_handle, buf, 2671 sizeof(*cmd), WMI_AP_PS_PEER_PARAM_CMDID); 2672 if (err) { 2673 wmi_err("Failed to send set_ap_ps_param cmd"); 2674 wmi_buf_free(buf); 2675 return QDF_STATUS_E_FAILURE; 2676 } 2677 2678 return 0; 2679 } 2680 2681 /** 2682 * send_set_sta_ps_param_cmd_tlv() - set sta powersave parameters 2683 * @wmi_handle: wmi handle 2684 * @param: pointer to sta_ps parameter structure 2685 * 2686 * Return: QDF_STATUS_SUCCESS for success or error code 2687 */ 2688 static QDF_STATUS send_set_sta_ps_param_cmd_tlv(wmi_unified_t wmi_handle, 2689 struct sta_ps_params *param) 2690 { 2691 wmi_sta_powersave_param_cmd_fixed_param *cmd; 2692 wmi_buf_t buf; 2693 int32_t len = sizeof(*cmd); 2694 2695 buf = wmi_buf_alloc(wmi_handle, len); 2696 if (!buf) 2697 return QDF_STATUS_E_NOMEM; 2698 2699 cmd = (wmi_sta_powersave_param_cmd_fixed_param *) wmi_buf_data(buf); 2700 WMITLV_SET_HDR(&cmd->tlv_header, 2701 WMITLV_TAG_STRUC_wmi_sta_powersave_param_cmd_fixed_param, 2702 WMITLV_GET_STRUCT_TLVLEN 2703 (wmi_sta_powersave_param_cmd_fixed_param)); 2704 cmd->vdev_id = param->vdev_id; 2705 cmd->param = param->param_id; 2706 cmd->value = param->value; 2707 2708 wmi_mtrace(WMI_STA_POWERSAVE_PARAM_CMDID, cmd->vdev_id, 0); 2709 if (wmi_unified_cmd_send(wmi_handle, buf, len, 2710 WMI_STA_POWERSAVE_PARAM_CMDID)) { 2711 wmi_err("Set Sta Ps param Failed vdevId %d Param %d val %d", 2712 param->vdev_id, param->param_id, param->value); 2713 wmi_buf_free(buf); 2714 return QDF_STATUS_E_FAILURE; 2715 } 2716 2717 return 0; 2718 } 2719 2720 /** 2721 * send_crash_inject_cmd_tlv() - inject fw crash 2722 * @wmi_handle: wmi handle 2723 * @param: ponirt to crash inject parameter structure 2724 * 2725 * Return: QDF_STATUS_SUCCESS for success or return error 2726 */ 2727 static QDF_STATUS send_crash_inject_cmd_tlv(wmi_unified_t wmi_handle, 2728 struct crash_inject *param) 2729 { 2730 int32_t ret = 0; 2731 WMI_FORCE_FW_HANG_CMD_fixed_param *cmd; 2732 uint16_t len = sizeof(*cmd); 2733 wmi_buf_t buf; 2734 2735 buf = wmi_buf_alloc(wmi_handle, len); 2736 if (!buf) 2737 return QDF_STATUS_E_NOMEM; 2738 2739 cmd = (WMI_FORCE_FW_HANG_CMD_fixed_param *) wmi_buf_data(buf); 2740 WMITLV_SET_HDR(&cmd->tlv_header, 2741 WMITLV_TAG_STRUC_WMI_FORCE_FW_HANG_CMD_fixed_param, 2742 WMITLV_GET_STRUCT_TLVLEN 2743 (WMI_FORCE_FW_HANG_CMD_fixed_param)); 2744 cmd->type = param->type; 2745 cmd->delay_time_ms = param->delay_time_ms; 2746 2747 wmi_mtrace(WMI_FORCE_FW_HANG_CMDID, NO_SESSION, 0); 2748 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 2749 WMI_FORCE_FW_HANG_CMDID); 2750 if (ret) { 2751 wmi_err("Failed to send set param command, ret = %d", ret); 2752 wmi_buf_free(buf); 2753 } 2754 2755 return ret; 2756 } 2757 2758 /** 2759 * send_dbglog_cmd_tlv() - set debug log level 2760 * @wmi_handle: handle to WMI. 2761 * @dbglog_param: pointer to hold dbglog level parameter 2762 * 2763 * Return: QDF_STATUS_SUCCESS on success, otherwise QDF_STATUS_E_* 2764 */ 2765 static QDF_STATUS 2766 send_dbglog_cmd_tlv(wmi_unified_t wmi_handle, 2767 struct dbglog_params *dbglog_param) 2768 { 2769 wmi_buf_t buf; 2770 wmi_debug_log_config_cmd_fixed_param *configmsg; 2771 QDF_STATUS status; 2772 int32_t i; 2773 int32_t len; 2774 int8_t *buf_ptr; 2775 int32_t *module_id_bitmap_array; /* Used to form the second tlv */ 2776 2777 ASSERT(dbglog_param->bitmap_len < MAX_MODULE_ID_BITMAP_WORDS); 2778 2779 /* Allocate size for 2 tlvs - including tlv hdr space for second tlv */ 2780 len = sizeof(wmi_debug_log_config_cmd_fixed_param) + WMI_TLV_HDR_SIZE + 2781 (sizeof(int32_t) * MAX_MODULE_ID_BITMAP_WORDS); 2782 buf = wmi_buf_alloc(wmi_handle, len); 2783 if (!buf) 2784 return QDF_STATUS_E_NOMEM; 2785 2786 configmsg = 2787 (wmi_debug_log_config_cmd_fixed_param *) (wmi_buf_data(buf)); 2788 buf_ptr = (int8_t *) configmsg; 2789 WMITLV_SET_HDR(&configmsg->tlv_header, 2790 WMITLV_TAG_STRUC_wmi_debug_log_config_cmd_fixed_param, 2791 WMITLV_GET_STRUCT_TLVLEN 2792 (wmi_debug_log_config_cmd_fixed_param)); 2793 configmsg->dbg_log_param = dbglog_param->param; 2794 configmsg->value = dbglog_param->val; 2795 /* Filling in the data part of second tlv -- should 2796 * follow first tlv _ WMI_TLV_HDR_SIZE */ 2797 module_id_bitmap_array = (uint32_t *) (buf_ptr + 2798 sizeof 2799 (wmi_debug_log_config_cmd_fixed_param) 2800 + WMI_TLV_HDR_SIZE); 2801 WMITLV_SET_HDR(buf_ptr + sizeof(wmi_debug_log_config_cmd_fixed_param), 2802 WMITLV_TAG_ARRAY_UINT32, 2803 sizeof(uint32_t) * MAX_MODULE_ID_BITMAP_WORDS); 2804 if (dbglog_param->module_id_bitmap) { 2805 for (i = 0; i < dbglog_param->bitmap_len; ++i) { 2806 module_id_bitmap_array[i] = 2807 dbglog_param->module_id_bitmap[i]; 2808 } 2809 } 2810 2811 wmi_mtrace(WMI_DBGLOG_CFG_CMDID, NO_SESSION, 0); 2812 status = wmi_unified_cmd_send(wmi_handle, buf, 2813 len, WMI_DBGLOG_CFG_CMDID); 2814 2815 if (status != QDF_STATUS_SUCCESS) 2816 wmi_buf_free(buf); 2817 2818 return status; 2819 } 2820 2821 /** 2822 * send_vdev_set_param_cmd_tlv() - WMI vdev set parameter function 2823 * @wmi_handle: handle to WMI. 2824 * @param: pointer to hold vdev set parameter 2825 * 2826 * Return: QDF_STATUS_SUCCESS for success or error code 2827 */ 2828 static QDF_STATUS send_vdev_set_param_cmd_tlv(wmi_unified_t wmi_handle, 2829 struct vdev_set_params *param) 2830 { 2831 QDF_STATUS ret; 2832 wmi_vdev_set_param_cmd_fixed_param *cmd; 2833 wmi_buf_t buf; 2834 uint16_t len = sizeof(*cmd); 2835 uint32_t vdev_param; 2836 2837 vdev_param = convert_host_vdev_param_tlv(param->param_id); 2838 if (vdev_param == WMI_UNAVAILABLE_PARAM) { 2839 wmi_err("Vdev param %d not available", param->param_id); 2840 return QDF_STATUS_E_INVAL; 2841 2842 } 2843 2844 buf = wmi_buf_alloc(wmi_handle, len); 2845 if (!buf) 2846 return QDF_STATUS_E_NOMEM; 2847 2848 cmd = (wmi_vdev_set_param_cmd_fixed_param *) wmi_buf_data(buf); 2849 WMITLV_SET_HDR(&cmd->tlv_header, 2850 WMITLV_TAG_STRUC_wmi_vdev_set_param_cmd_fixed_param, 2851 WMITLV_GET_STRUCT_TLVLEN(wmi_vdev_set_param_cmd_fixed_param)); 2852 cmd->vdev_id = param->vdev_id; 2853 cmd->param_id = vdev_param; 2854 cmd->param_value = param->param_value; 2855 wmi_nofl_debug("Set vdev %d param 0x%x to %u", 2856 cmd->vdev_id, cmd->param_id, cmd->param_value); 2857 wmi_mtrace(WMI_VDEV_SET_PARAM_CMDID, cmd->vdev_id, 0); 2858 ret = wmi_unified_cmd_send(wmi_handle, buf, len, WMI_VDEV_SET_PARAM_CMDID); 2859 if (QDF_IS_STATUS_ERROR(ret)) { 2860 wmi_buf_free(buf); 2861 } 2862 2863 return ret; 2864 } 2865 2866 /** 2867 * send_multi_param_cmd_using_vdev_param_tlv() - vdev set parameter function 2868 * @wmi_handle : handle to WMI. 2869 * @params: pointer to parameters to set 2870 * 2871 * Return: QDF_STATUS_SUCCESS on success, otherwise QDF_STATUS_E_* 2872 */ 2873 static QDF_STATUS 2874 send_multi_param_cmd_using_vdev_param_tlv(wmi_unified_t wmi_handle, 2875 struct set_multiple_pdev_vdev_param *params) 2876 { 2877 uint8_t index; 2878 struct vdev_set_params vdevparam; 2879 2880 for (index = 0; index < params->n_params; index++) { 2881 vdevparam.param_id = params->params[index].param_id; 2882 vdevparam.param_value = params->params[index].param_value; 2883 vdevparam.vdev_id = params->dev_id; 2884 if (QDF_IS_STATUS_ERROR(send_vdev_set_param_cmd_tlv(wmi_handle, &vdevparam))) { 2885 wmi_err("failed to send param:%d", vdevparam.param_id); 2886 return QDF_STATUS_E_FAILURE; 2887 } 2888 } 2889 return QDF_STATUS_SUCCESS; 2890 } 2891 2892 #ifdef WLAN_PDEV_VDEV_SEND_MULTI_PARAM 2893 /** 2894 * send_multiple_vdev_param_cmd_tlv() - WMI vdev set parameter function 2895 * @wmi_handle : handle to WMI. 2896 * @params: pointer to hold set_multiple_pdev_vdev_param info 2897 * 2898 * Return: QDF_STATUS_SUCCESS for success or error code 2899 */ 2900 static QDF_STATUS 2901 send_multiple_vdev_param_cmd_tlv(wmi_unified_t wmi_handle, 2902 struct set_multiple_pdev_vdev_param *params) 2903 { 2904 if (!wmi_service_enabled(wmi_handle, 2905 wmi_service_combined_set_param_support)) 2906 return send_multi_param_cmd_using_vdev_param_tlv(wmi_handle, 2907 params); 2908 return send_multi_pdev_vdev_set_param_cmd_tlv(wmi_handle, params); 2909 } 2910 2911 #else /* WLAN_PDEV_VDEV_SEND_MULTI_PARAM */ 2912 2913 /** 2914 * send_multiple_vdev_param_cmd_tlv() - WMI vdev set parameter function 2915 * @wmi_handle : handle to WMI. 2916 * @params: pointer to hold set_multiple_pdev_vdev_param info 2917 * 2918 * Return: QDF_STATUS_SUCCESS for success or error code 2919 */ 2920 static QDF_STATUS 2921 send_multiple_vdev_param_cmd_tlv(wmi_unified_t wmi_handle, 2922 struct set_multiple_pdev_vdev_param *params) 2923 { 2924 return send_multi_param_cmd_using_vdev_param_tlv(wmi_handle, params); 2925 } 2926 #endif /*end of WLAN_PDEV_VDEV_SEND_MULTI_PARAM */ 2927 2928 /** 2929 * send_vdev_set_mu_snif_cmd_tlv() - WMI vdev set mu snif function 2930 * @wmi_handle: handle to WMI. 2931 * @param: pointer to hold mu sniffer parameter 2932 * 2933 * Return: QDF_STATUS_SUCCESS for success or error code 2934 */ 2935 static 2936 QDF_STATUS send_vdev_set_mu_snif_cmd_tlv(wmi_unified_t wmi_handle, 2937 struct vdev_set_mu_snif_param *param) 2938 { 2939 QDF_STATUS ret; 2940 wmi_vdev_set_mu_snif_cmd_param *cmd; 2941 wmi_buf_t buf; 2942 uint32_t *tmp_ptr; 2943 uint16_t len = sizeof(*cmd); 2944 uint8_t *buf_ptr; 2945 uint32_t i; 2946 2947 /* Length TLV placeholder for array of uint32_t */ 2948 len += WMI_TLV_HDR_SIZE; 2949 2950 if (param->num_aid) 2951 len += param->num_aid * sizeof(uint32_t); 2952 2953 buf = wmi_buf_alloc(wmi_handle, len); 2954 if (!buf) 2955 return QDF_STATUS_E_NOMEM; 2956 2957 buf_ptr = (uint8_t *)wmi_buf_data(buf); 2958 cmd = (wmi_vdev_set_mu_snif_cmd_param *)buf_ptr; 2959 2960 WMITLV_SET_HDR(&cmd->tlv_header, 2961 WMITLV_TAG_STRUC_wmi_vdev_set_mu_snif_cmd_param, 2962 WMITLV_GET_STRUCT_TLVLEN 2963 (wmi_vdev_set_mu_snif_cmd_param)); 2964 2965 cmd->vdev_id = param->vdev_id; 2966 cmd->mode = param->mode; 2967 cmd->max_num_user = param->num_user; 2968 2969 buf_ptr += sizeof(*cmd); 2970 2971 tmp_ptr = (uint32_t *)(buf_ptr + WMI_TLV_HDR_SIZE); 2972 2973 for (i = 0; i < param->num_aid; ++i) 2974 tmp_ptr[i] = param->aid[i]; 2975 2976 WMITLV_SET_HDR(buf_ptr, 2977 WMITLV_TAG_ARRAY_UINT32, 2978 (param->num_aid * sizeof(uint32_t))); 2979 2980 wmi_debug("Setting vdev %d mode = %x, max user = %u aids= %u", 2981 cmd->vdev_id, cmd->mode, cmd->max_num_user, param->num_aid); 2982 wmi_mtrace(WMI_VDEV_SET_PARAM_CMDID, cmd->vdev_id, 0); 2983 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 2984 WMI_VDEV_SET_MU_SNIF_CMDID); 2985 if (QDF_IS_STATUS_ERROR(ret)) { 2986 wmi_err("Failed to send set param command ret = %d", ret); 2987 wmi_buf_free(buf); 2988 } 2989 2990 return ret; 2991 } 2992 2993 /** 2994 * send_peer_based_pktlog_cmd() - Send WMI command to enable packet-log 2995 * @wmi_handle: handle to WMI. 2996 * @macaddr: Peer mac address to be filter 2997 * @mac_id: mac id to have radio context 2998 * @enb_dsb: Enable MAC based filtering or Disable 2999 * 3000 * Return: QDF_STATUS 3001 */ 3002 static QDF_STATUS send_peer_based_pktlog_cmd(wmi_unified_t wmi_handle, 3003 uint8_t *macaddr, 3004 uint8_t mac_id, 3005 uint8_t enb_dsb) 3006 { 3007 int32_t ret; 3008 wmi_pdev_pktlog_filter_cmd_fixed_param *cmd; 3009 wmi_pdev_pktlog_filter_info *mac_info; 3010 wmi_buf_t buf; 3011 uint8_t *buf_ptr; 3012 uint16_t len = sizeof(wmi_pdev_pktlog_filter_cmd_fixed_param) + 3013 sizeof(wmi_pdev_pktlog_filter_info) + WMI_TLV_HDR_SIZE; 3014 3015 buf = wmi_buf_alloc(wmi_handle, len); 3016 if (!buf) 3017 return QDF_STATUS_E_NOMEM; 3018 3019 buf_ptr = (uint8_t *)wmi_buf_data(buf); 3020 cmd = (wmi_pdev_pktlog_filter_cmd_fixed_param *)buf_ptr; 3021 WMITLV_SET_HDR(&cmd->tlv_header, 3022 WMITLV_TAG_STRUC_wmi_pdev_pktlog_filter_cmd_fixed_param, 3023 WMITLV_GET_STRUCT_TLVLEN 3024 (wmi_pdev_pktlog_filter_cmd_fixed_param)); 3025 cmd->pdev_id = mac_id; 3026 cmd->enable = enb_dsb; 3027 cmd->num_of_mac_addresses = 1; 3028 wmi_mtrace(WMI_PDEV_PKTLOG_FILTER_CMDID, cmd->pdev_id, 0); 3029 3030 buf_ptr += sizeof(*cmd); 3031 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 3032 sizeof(wmi_pdev_pktlog_filter_info)); 3033 buf_ptr += WMI_TLV_HDR_SIZE; 3034 3035 mac_info = (wmi_pdev_pktlog_filter_info *)(buf_ptr); 3036 3037 WMITLV_SET_HDR(&mac_info->tlv_header, 3038 WMITLV_TAG_STRUC_wmi_pdev_pktlog_filter_info, 3039 WMITLV_GET_STRUCT_TLVLEN 3040 (wmi_pdev_pktlog_filter_info)); 3041 3042 WMI_CHAR_ARRAY_TO_MAC_ADDR(macaddr, &mac_info->peer_mac_address); 3043 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 3044 WMI_PDEV_PKTLOG_FILTER_CMDID); 3045 if (ret) { 3046 wmi_err("Failed to send peer based pktlog command to FW =%d" 3047 , ret); 3048 wmi_buf_free(buf); 3049 } 3050 3051 return ret; 3052 } 3053 3054 /** 3055 * send_packet_log_enable_cmd_tlv() - Send WMI command to enable packet-log 3056 * @wmi_handle: handle to WMI. 3057 * @PKTLOG_EVENT: packet log event 3058 * @mac_id: mac id to have radio context 3059 * 3060 * Return: QDF_STATUS_SUCCESS for success or error code 3061 */ 3062 static QDF_STATUS send_packet_log_enable_cmd_tlv(wmi_unified_t wmi_handle, 3063 WMI_HOST_PKTLOG_EVENT PKTLOG_EVENT, uint8_t mac_id) 3064 { 3065 int32_t ret, idx, max_idx; 3066 wmi_pdev_pktlog_enable_cmd_fixed_param *cmd; 3067 wmi_buf_t buf; 3068 uint16_t len = sizeof(wmi_pdev_pktlog_enable_cmd_fixed_param); 3069 3070 buf = wmi_buf_alloc(wmi_handle, len); 3071 if (!buf) 3072 return -QDF_STATUS_E_NOMEM; 3073 3074 cmd = (wmi_pdev_pktlog_enable_cmd_fixed_param *) wmi_buf_data(buf); 3075 WMITLV_SET_HDR(&cmd->tlv_header, 3076 WMITLV_TAG_STRUC_wmi_pdev_pktlog_enable_cmd_fixed_param, 3077 WMITLV_GET_STRUCT_TLVLEN 3078 (wmi_pdev_pktlog_enable_cmd_fixed_param)); 3079 max_idx = sizeof(pktlog_event_tlv) / (sizeof(pktlog_event_tlv[0])); 3080 cmd->evlist = 0; 3081 for (idx = 0; idx < max_idx; idx++) { 3082 if (PKTLOG_EVENT & (1 << idx)) 3083 cmd->evlist |= pktlog_event_tlv[idx]; 3084 } 3085 cmd->pdev_id = mac_id; 3086 wmi_mtrace(WMI_PDEV_PKTLOG_ENABLE_CMDID, cmd->pdev_id, 0); 3087 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 3088 WMI_PDEV_PKTLOG_ENABLE_CMDID); 3089 if (ret) { 3090 wmi_err("Failed to send pktlog enable cmd to FW =%d", ret); 3091 wmi_buf_free(buf); 3092 } 3093 3094 return ret; 3095 } 3096 3097 /** 3098 * send_packet_log_disable_cmd_tlv() - Send WMI command to disable packet-log 3099 * @wmi_handle: handle to WMI. 3100 * @mac_id: mac id to have radio context 3101 * 3102 * Return: QDF_STATUS_SUCCESS for success or error code 3103 */ 3104 static QDF_STATUS send_packet_log_disable_cmd_tlv(wmi_unified_t wmi_handle, 3105 uint8_t mac_id) 3106 { 3107 int32_t ret; 3108 wmi_pdev_pktlog_disable_cmd_fixed_param *cmd; 3109 wmi_buf_t buf; 3110 uint16_t len = sizeof(wmi_pdev_pktlog_disable_cmd_fixed_param); 3111 3112 buf = wmi_buf_alloc(wmi_handle, len); 3113 if (!buf) 3114 return -QDF_STATUS_E_NOMEM; 3115 3116 cmd = (wmi_pdev_pktlog_disable_cmd_fixed_param *) wmi_buf_data(buf); 3117 WMITLV_SET_HDR(&cmd->tlv_header, 3118 WMITLV_TAG_STRUC_wmi_pdev_pktlog_disable_cmd_fixed_param, 3119 WMITLV_GET_STRUCT_TLVLEN 3120 (wmi_pdev_pktlog_disable_cmd_fixed_param)); 3121 cmd->pdev_id = mac_id; 3122 wmi_mtrace(WMI_PDEV_PKTLOG_DISABLE_CMDID, cmd->pdev_id, 0); 3123 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 3124 WMI_PDEV_PKTLOG_DISABLE_CMDID); 3125 if (ret) { 3126 wmi_err("Failed to send pktlog disable cmd to FW =%d", ret); 3127 wmi_buf_free(buf); 3128 } 3129 3130 return ret; 3131 } 3132 3133 #define WMI_FW_TIME_STAMP_LOW_MASK 0xffffffff 3134 /** 3135 * send_time_stamp_sync_cmd_tlv() - Send WMI command to 3136 * sync time between between host and firmware 3137 * @wmi_handle: handle to WMI. 3138 * 3139 * Return: None 3140 */ 3141 static void send_time_stamp_sync_cmd_tlv(wmi_unified_t wmi_handle) 3142 { 3143 wmi_buf_t buf; 3144 QDF_STATUS status = QDF_STATUS_SUCCESS; 3145 WMI_DBGLOG_TIME_STAMP_SYNC_CMD_fixed_param *time_stamp; 3146 int32_t len; 3147 qdf_time_t time_ms; 3148 3149 len = sizeof(*time_stamp); 3150 buf = wmi_buf_alloc(wmi_handle, len); 3151 3152 if (!buf) 3153 return; 3154 3155 time_stamp = 3156 (WMI_DBGLOG_TIME_STAMP_SYNC_CMD_fixed_param *) 3157 (wmi_buf_data(buf)); 3158 WMITLV_SET_HDR(&time_stamp->tlv_header, 3159 WMITLV_TAG_STRUC_wmi_dbglog_time_stamp_sync_cmd_fixed_param, 3160 WMITLV_GET_STRUCT_TLVLEN( 3161 WMI_DBGLOG_TIME_STAMP_SYNC_CMD_fixed_param)); 3162 3163 time_ms = qdf_get_time_of_the_day_ms(); 3164 time_stamp->mode = WMI_TIME_STAMP_SYNC_MODE_MS; 3165 time_stamp->time_stamp_low = time_ms & 3166 WMI_FW_TIME_STAMP_LOW_MASK; 3167 /* 3168 * Send time_stamp_high 0 as the time converted from HR:MIN:SEC:MS to ms 3169 * won't exceed 27 bit 3170 */ 3171 time_stamp->time_stamp_high = 0; 3172 wmi_debug("WMA --> DBGLOG_TIME_STAMP_SYNC_CMDID mode %d time_stamp low %d high %d", 3173 time_stamp->mode, time_stamp->time_stamp_low, 3174 time_stamp->time_stamp_high); 3175 3176 wmi_mtrace(WMI_DBGLOG_TIME_STAMP_SYNC_CMDID, NO_SESSION, 0); 3177 status = wmi_unified_cmd_send(wmi_handle, buf, 3178 len, WMI_DBGLOG_TIME_STAMP_SYNC_CMDID); 3179 if (status) { 3180 wmi_err("Failed to send WMI_DBGLOG_TIME_STAMP_SYNC_CMDID command"); 3181 wmi_buf_free(buf); 3182 } 3183 3184 } 3185 3186 /** 3187 * send_fd_tmpl_cmd_tlv() - WMI FILS Discovery send function 3188 * @wmi_handle: handle to WMI. 3189 * @param: pointer to hold FILS Discovery send cmd parameter 3190 * 3191 * Return: QDF_STATUS_SUCCESS for success or error code 3192 */ 3193 static QDF_STATUS send_fd_tmpl_cmd_tlv(wmi_unified_t wmi_handle, 3194 struct fils_discovery_tmpl_params *param) 3195 { 3196 int32_t ret; 3197 wmi_fd_tmpl_cmd_fixed_param *cmd; 3198 wmi_buf_t wmi_buf; 3199 uint8_t *buf_ptr; 3200 uint32_t wmi_buf_len; 3201 3202 wmi_buf_len = sizeof(wmi_fd_tmpl_cmd_fixed_param) + 3203 WMI_TLV_HDR_SIZE + param->tmpl_len_aligned; 3204 wmi_buf = wmi_buf_alloc(wmi_handle, wmi_buf_len); 3205 if (!wmi_buf) 3206 return QDF_STATUS_E_NOMEM; 3207 3208 buf_ptr = (uint8_t *) wmi_buf_data(wmi_buf); 3209 cmd = (wmi_fd_tmpl_cmd_fixed_param *) buf_ptr; 3210 WMITLV_SET_HDR(&cmd->tlv_header, 3211 WMITLV_TAG_STRUC_wmi_fd_tmpl_cmd_fixed_param, 3212 WMITLV_GET_STRUCT_TLVLEN(wmi_fd_tmpl_cmd_fixed_param)); 3213 cmd->vdev_id = param->vdev_id; 3214 cmd->buf_len = param->tmpl_len; 3215 buf_ptr += sizeof(wmi_fd_tmpl_cmd_fixed_param); 3216 3217 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, param->tmpl_len_aligned); 3218 buf_ptr += WMI_TLV_HDR_SIZE; 3219 qdf_mem_copy(buf_ptr, param->frm, param->tmpl_len); 3220 3221 wmi_mtrace(WMI_FD_TMPL_CMDID, cmd->vdev_id, 0); 3222 ret = wmi_unified_cmd_send(wmi_handle, 3223 wmi_buf, wmi_buf_len, WMI_FD_TMPL_CMDID); 3224 3225 if (ret) { 3226 wmi_err("Failed to send fd tmpl: %d", ret); 3227 wmi_buf_free(wmi_buf); 3228 return ret; 3229 } 3230 3231 return 0; 3232 } 3233 3234 /** 3235 * send_beacon_tmpl_send_cmd_tlv() - WMI beacon send function 3236 * @wmi_handle: handle to WMI. 3237 * @param: pointer to hold beacon send cmd parameter 3238 * 3239 * Return: QDF_STATUS_SUCCESS for success or error code 3240 */ 3241 static QDF_STATUS send_beacon_tmpl_send_cmd_tlv(wmi_unified_t wmi_handle, 3242 struct beacon_tmpl_params *param) 3243 { 3244 int32_t ret; 3245 wmi_bcn_tmpl_cmd_fixed_param *cmd; 3246 wmi_bcn_prb_info *bcn_prb_info; 3247 wmi_buf_t wmi_buf; 3248 uint8_t *buf_ptr; 3249 uint32_t wmi_buf_len; 3250 3251 wmi_buf_len = sizeof(wmi_bcn_tmpl_cmd_fixed_param) + 3252 sizeof(wmi_bcn_prb_info) + WMI_TLV_HDR_SIZE + 3253 param->tmpl_len_aligned + 3254 bcn_tmpl_mlo_param_size(param) + 3255 bcn_tmpl_ml_info_size(param); 3256 3257 wmi_buf = wmi_buf_alloc(wmi_handle, wmi_buf_len); 3258 if (!wmi_buf) 3259 return QDF_STATUS_E_NOMEM; 3260 3261 buf_ptr = (uint8_t *) wmi_buf_data(wmi_buf); 3262 cmd = (wmi_bcn_tmpl_cmd_fixed_param *) buf_ptr; 3263 WMITLV_SET_HDR(&cmd->tlv_header, 3264 WMITLV_TAG_STRUC_wmi_bcn_tmpl_cmd_fixed_param, 3265 WMITLV_GET_STRUCT_TLVLEN(wmi_bcn_tmpl_cmd_fixed_param)); 3266 cmd->vdev_id = param->vdev_id; 3267 cmd->tim_ie_offset = param->tim_ie_offset; 3268 cmd->mbssid_ie_offset = param->mbssid_ie_offset; 3269 cmd->csa_switch_count_offset = param->csa_switch_count_offset; 3270 cmd->ext_csa_switch_count_offset = param->ext_csa_switch_count_offset; 3271 cmd->esp_ie_offset = param->esp_ie_offset; 3272 cmd->mu_edca_ie_offset = param->mu_edca_ie_offset; 3273 cmd->ema_params = param->ema_params; 3274 cmd->buf_len = param->tmpl_len; 3275 cmd->csa_event_bitmap = param->csa_event_bitmap; 3276 3277 WMI_BEACON_PROTECTION_EN_SET(cmd->feature_enable_bitmap, 3278 param->enable_bigtk); 3279 buf_ptr += sizeof(wmi_bcn_tmpl_cmd_fixed_param); 3280 3281 bcn_prb_info = (wmi_bcn_prb_info *) buf_ptr; 3282 WMITLV_SET_HDR(&bcn_prb_info->tlv_header, 3283 WMITLV_TAG_STRUC_wmi_bcn_prb_info, 3284 WMITLV_GET_STRUCT_TLVLEN(wmi_bcn_prb_info)); 3285 bcn_prb_info->caps = 0; 3286 bcn_prb_info->erp = 0; 3287 buf_ptr += sizeof(wmi_bcn_prb_info); 3288 3289 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, param->tmpl_len_aligned); 3290 buf_ptr += WMI_TLV_HDR_SIZE; 3291 3292 /* for big endian host, copy engine byte_swap is enabled 3293 * But the frame content is in network byte order 3294 * Need to byte swap the frame content - so when copy engine 3295 * does byte_swap - target gets frame content in the correct order 3296 */ 3297 WMI_HOST_IF_MSG_COPY_CHAR_ARRAY(buf_ptr, param->frm, 3298 param->tmpl_len); 3299 3300 buf_ptr += roundup(param->tmpl_len, sizeof(uint32_t)); 3301 buf_ptr = bcn_tmpl_add_ml_partner_links(buf_ptr, param); 3302 3303 buf_ptr = bcn_tmpl_add_ml_info(buf_ptr, param); 3304 3305 wmi_mtrace(WMI_BCN_TMPL_CMDID, cmd->vdev_id, 0); 3306 ret = wmi_unified_cmd_send(wmi_handle, 3307 wmi_buf, wmi_buf_len, WMI_BCN_TMPL_CMDID); 3308 if (ret) { 3309 wmi_err("Failed to send bcn tmpl: %d", ret); 3310 wmi_buf_free(wmi_buf); 3311 } 3312 3313 return 0; 3314 } 3315 3316 #ifdef WLAN_FEATURE_11BE 3317 static inline void copy_peer_flags_tlv_11be( 3318 wmi_peer_assoc_complete_cmd_fixed_param * cmd, 3319 struct peer_assoc_params *param) 3320 { 3321 if (param->bw_320) 3322 cmd->peer_flags_ext |= WMI_PEER_EXT_320MHZ; 3323 if (param->eht_flag) 3324 cmd->peer_flags_ext |= WMI_PEER_EXT_EHT; 3325 3326 wmi_debug("peer_flags_ext 0x%x", cmd->peer_flags_ext); 3327 } 3328 #else 3329 static inline void copy_peer_flags_tlv_11be( 3330 wmi_peer_assoc_complete_cmd_fixed_param * cmd, 3331 struct peer_assoc_params *param) 3332 { 3333 } 3334 #endif 3335 3336 static inline void copy_peer_flags_tlv( 3337 wmi_peer_assoc_complete_cmd_fixed_param * cmd, 3338 struct peer_assoc_params *param) 3339 { 3340 /* 3341 * The target only needs a subset of the flags maintained in the host. 3342 * Just populate those flags and send it down 3343 */ 3344 cmd->peer_flags = 0; 3345 if (param->peer_dms_capable) 3346 cmd->peer_flags_ext |= WMI_PEER_EXT_DMS_CAPABLE; 3347 /* 3348 * Do not enable HT/VHT if WMM/wme is disabled for vap. 3349 */ 3350 if (param->is_wme_set) { 3351 3352 if (param->qos_flag) 3353 cmd->peer_flags |= WMI_PEER_QOS; 3354 if (param->apsd_flag) 3355 cmd->peer_flags |= WMI_PEER_APSD; 3356 if (param->ht_flag) 3357 cmd->peer_flags |= WMI_PEER_HT; 3358 if (param->bw_40) 3359 cmd->peer_flags |= WMI_PEER_40MHZ; 3360 if (param->bw_80) 3361 cmd->peer_flags |= WMI_PEER_80MHZ; 3362 if (param->bw_160) 3363 cmd->peer_flags |= WMI_PEER_160MHZ; 3364 3365 copy_peer_flags_tlv_11be(cmd, param); 3366 3367 /* Typically if STBC is enabled for VHT it should be enabled 3368 * for HT as well 3369 **/ 3370 if (param->stbc_flag) 3371 cmd->peer_flags |= WMI_PEER_STBC; 3372 3373 /* Typically if LDPC is enabled for VHT it should be enabled 3374 * for HT as well 3375 **/ 3376 if (param->ldpc_flag) 3377 cmd->peer_flags |= WMI_PEER_LDPC; 3378 3379 if (param->static_mimops_flag) 3380 cmd->peer_flags |= WMI_PEER_STATIC_MIMOPS; 3381 if (param->dynamic_mimops_flag) 3382 cmd->peer_flags |= WMI_PEER_DYN_MIMOPS; 3383 if (param->spatial_mux_flag) 3384 cmd->peer_flags |= WMI_PEER_SPATIAL_MUX; 3385 if (param->vht_flag) 3386 cmd->peer_flags |= WMI_PEER_VHT; 3387 if (param->he_flag) 3388 cmd->peer_flags |= WMI_PEER_HE; 3389 if (param->p2p_capable_sta) 3390 cmd->peer_flags |= WMI_PEER_IS_P2P_CAPABLE; 3391 } 3392 3393 if (param->is_pmf_enabled) 3394 cmd->peer_flags |= WMI_PEER_PMF; 3395 /* 3396 * Suppress authorization for all AUTH modes that need 4-way handshake 3397 * (during re-association). 3398 * Authorization will be done for these modes on key installation. 3399 */ 3400 if (param->auth_flag) 3401 cmd->peer_flags |= WMI_PEER_AUTH; 3402 if (param->need_ptk_4_way) 3403 cmd->peer_flags |= WMI_PEER_NEED_PTK_4_WAY; 3404 else 3405 cmd->peer_flags &= ~WMI_PEER_NEED_PTK_4_WAY; 3406 if (param->need_gtk_2_way) 3407 cmd->peer_flags |= WMI_PEER_NEED_GTK_2_WAY; 3408 /* safe mode bypass the 4-way handshake */ 3409 if (param->safe_mode_enabled) 3410 cmd->peer_flags &= 3411 ~(WMI_PEER_NEED_PTK_4_WAY | WMI_PEER_NEED_GTK_2_WAY); 3412 /* inter BSS peer */ 3413 if (param->inter_bss_peer) 3414 cmd->peer_flags |= WMI_PEER_INTER_BSS_PEER; 3415 /* Disable AMSDU for station transmit, if user configures it */ 3416 /* Disable AMSDU for AP transmit to 11n Stations, if user configures 3417 * it 3418 * if (param->amsdu_disable) Add after FW support 3419 **/ 3420 3421 /* Target asserts if node is marked HT and all MCS is set to 0. 3422 * Mark the node as non-HT if all the mcs rates are disabled through 3423 * iwpriv 3424 **/ 3425 if (param->peer_ht_rates.num_rates == 0) 3426 cmd->peer_flags &= ~WMI_PEER_HT; 3427 3428 if (param->twt_requester) 3429 cmd->peer_flags |= WMI_PEER_TWT_REQ; 3430 3431 if (param->twt_responder) 3432 cmd->peer_flags |= WMI_PEER_TWT_RESP; 3433 } 3434 3435 static inline void copy_peer_mac_addr_tlv( 3436 wmi_peer_assoc_complete_cmd_fixed_param * cmd, 3437 struct peer_assoc_params *param) 3438 { 3439 WMI_CHAR_ARRAY_TO_MAC_ADDR(param->peer_mac, &cmd->peer_macaddr); 3440 } 3441 3442 #ifdef WLAN_FEATURE_11BE 3443 static uint8_t *update_peer_flags_tlv_ehtinfo( 3444 wmi_peer_assoc_complete_cmd_fixed_param * cmd, 3445 struct peer_assoc_params *param, uint8_t *buf_ptr) 3446 { 3447 wmi_eht_rate_set *eht_mcs; 3448 int i; 3449 3450 cmd->peer_eht_ops = param->peer_eht_ops; 3451 cmd->puncture_20mhz_bitmap = ~param->puncture_bitmap; 3452 3453 qdf_mem_copy(&cmd->peer_eht_cap_mac, ¶m->peer_eht_cap_macinfo, 3454 sizeof(param->peer_eht_cap_macinfo)); 3455 qdf_mem_copy(&cmd->peer_eht_cap_phy, ¶m->peer_eht_cap_phyinfo, 3456 sizeof(param->peer_eht_cap_phyinfo)); 3457 qdf_mem_copy(&cmd->peer_eht_ppet, ¶m->peer_eht_ppet, 3458 sizeof(param->peer_eht_ppet)); 3459 3460 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 3461 (param->peer_eht_mcs_count * sizeof(wmi_eht_rate_set))); 3462 buf_ptr += WMI_TLV_HDR_SIZE; 3463 3464 /* Loop through the EHT rate set */ 3465 for (i = 0; i < param->peer_eht_mcs_count; i++) { 3466 eht_mcs = (wmi_eht_rate_set *)buf_ptr; 3467 WMITLV_SET_HDR(eht_mcs, WMITLV_TAG_STRUC_wmi_eht_rate_set, 3468 WMITLV_GET_STRUCT_TLVLEN(wmi_eht_rate_set)); 3469 3470 eht_mcs->rx_mcs_set = param->peer_eht_rx_mcs_set[i]; 3471 eht_mcs->tx_mcs_set = param->peer_eht_tx_mcs_set[i]; 3472 wmi_debug("EHT idx %d RxMCSmap %x TxMCSmap %x ", 3473 i, eht_mcs->rx_mcs_set, eht_mcs->tx_mcs_set); 3474 buf_ptr += sizeof(wmi_eht_rate_set); 3475 } 3476 3477 wmi_debug("nss %d ru mask 0x%x", 3478 cmd->peer_eht_ppet.numss_m1, cmd->peer_eht_ppet.ru_mask); 3479 for (i = 0; i < WMI_MAX_NUM_SS; i++) { 3480 wmi_debug("ppet idx %d ppet %x ", 3481 i, cmd->peer_eht_ppet.ppet16_ppet8_ru3_ru0[i]); 3482 } 3483 3484 if ((param->eht_flag) && (param->peer_eht_mcs_count > 1) && 3485 (param->peer_eht_rx_mcs_set[WMI_HOST_EHT_TXRX_MCS_NSS_IDX_160] 3486 == WMI_HOST_EHT_INVALID_MCSNSSMAP || 3487 param->peer_eht_tx_mcs_set[WMI_HOST_EHT_TXRX_MCS_NSS_IDX_160] 3488 == WMI_HOST_HE_INVALID_MCSNSSMAP)) { 3489 wmi_debug("param->peer_eht_tx_mcs_set[160MHz]=%x", 3490 param->peer_eht_tx_mcs_set 3491 [WMI_HOST_HE_TXRX_MCS_NSS_IDX_160]); 3492 wmi_debug("param->peer_eht_rx_mcs_set[160MHz]=%x", 3493 param->peer_eht_rx_mcs_set 3494 [WMI_HOST_HE_TXRX_MCS_NSS_IDX_160]); 3495 wmi_debug("peer_mac="QDF_MAC_ADDR_FMT, 3496 QDF_MAC_ADDR_REF(param->peer_mac)); 3497 } 3498 3499 wmi_debug("EHT cap_mac %x %x ehtops %x EHT phy %x %x %x pp %x", 3500 cmd->peer_eht_cap_mac[0], 3501 cmd->peer_eht_cap_mac[1], cmd->peer_eht_ops, 3502 cmd->peer_eht_cap_phy[0], cmd->peer_eht_cap_phy[1], 3503 cmd->peer_eht_cap_phy[2], cmd->puncture_20mhz_bitmap); 3504 3505 return buf_ptr; 3506 } 3507 #else 3508 static uint8_t *update_peer_flags_tlv_ehtinfo( 3509 wmi_peer_assoc_complete_cmd_fixed_param * cmd, 3510 struct peer_assoc_params *param, uint8_t *buf_ptr) 3511 { 3512 return buf_ptr; 3513 } 3514 #endif 3515 3516 #ifdef WLAN_FEATURE_11BE 3517 static 3518 uint32_t wmi_eht_peer_assoc_params_len(struct peer_assoc_params *param) 3519 { 3520 return (sizeof(wmi_he_rate_set) * param->peer_eht_mcs_count 3521 + WMI_TLV_HDR_SIZE); 3522 } 3523 3524 static void wmi_populate_service_11be(uint32_t *wmi_service) 3525 { 3526 wmi_service[wmi_service_11be] = WMI_SERVICE_11BE; 3527 } 3528 3529 #else 3530 static 3531 uint32_t wmi_eht_peer_assoc_params_len(struct peer_assoc_params *param) 3532 { 3533 return 0; 3534 } 3535 3536 static void wmi_populate_service_11be(uint32_t *wmi_service) 3537 { 3538 } 3539 3540 #endif 3541 3542 /** 3543 * send_peer_assoc_cmd_tlv() - WMI peer assoc function 3544 * @wmi_handle: handle to WMI. 3545 * @param: pointer to peer assoc parameter 3546 * 3547 * Return: QDF_STATUS_SUCCESS for success or error code 3548 */ 3549 static QDF_STATUS send_peer_assoc_cmd_tlv(wmi_unified_t wmi_handle, 3550 struct peer_assoc_params *param) 3551 { 3552 wmi_peer_assoc_complete_cmd_fixed_param *cmd; 3553 wmi_vht_rate_set *mcs; 3554 wmi_he_rate_set *he_mcs; 3555 wmi_buf_t buf; 3556 int32_t len; 3557 uint8_t *buf_ptr; 3558 QDF_STATUS ret; 3559 uint32_t peer_legacy_rates_align; 3560 uint32_t peer_ht_rates_align; 3561 int32_t i; 3562 3563 3564 peer_legacy_rates_align = wmi_align(param->peer_legacy_rates.num_rates); 3565 peer_ht_rates_align = wmi_align(param->peer_ht_rates.num_rates); 3566 3567 len = sizeof(*cmd) + WMI_TLV_HDR_SIZE + 3568 (peer_legacy_rates_align * sizeof(uint8_t)) + 3569 WMI_TLV_HDR_SIZE + 3570 (peer_ht_rates_align * sizeof(uint8_t)) + 3571 sizeof(wmi_vht_rate_set) + 3572 (sizeof(wmi_he_rate_set) * param->peer_he_mcs_count 3573 + WMI_TLV_HDR_SIZE) 3574 + wmi_eht_peer_assoc_params_len(param) + 3575 peer_assoc_mlo_params_size(param) + 3576 peer_assoc_t2lm_params_size(param); 3577 3578 buf = wmi_buf_alloc(wmi_handle, len); 3579 if (!buf) 3580 return QDF_STATUS_E_NOMEM; 3581 3582 buf_ptr = (uint8_t *) wmi_buf_data(buf); 3583 cmd = (wmi_peer_assoc_complete_cmd_fixed_param *) buf_ptr; 3584 WMITLV_SET_HDR(&cmd->tlv_header, 3585 WMITLV_TAG_STRUC_wmi_peer_assoc_complete_cmd_fixed_param, 3586 WMITLV_GET_STRUCT_TLVLEN 3587 (wmi_peer_assoc_complete_cmd_fixed_param)); 3588 3589 cmd->vdev_id = param->vdev_id; 3590 3591 cmd->peer_new_assoc = param->peer_new_assoc; 3592 cmd->peer_associd = param->peer_associd; 3593 3594 copy_peer_flags_tlv(cmd, param); 3595 copy_peer_mac_addr_tlv(cmd, param); 3596 3597 cmd->peer_rate_caps = param->peer_rate_caps; 3598 cmd->peer_caps = param->peer_caps; 3599 cmd->peer_listen_intval = param->peer_listen_intval; 3600 cmd->peer_ht_caps = param->peer_ht_caps; 3601 cmd->peer_max_mpdu = param->peer_max_mpdu; 3602 cmd->peer_mpdu_density = param->peer_mpdu_density; 3603 cmd->peer_vht_caps = param->peer_vht_caps; 3604 cmd->peer_phymode = param->peer_phymode; 3605 cmd->bss_max_idle_option = param->peer_bss_max_idle_option; 3606 3607 /* Update 11ax capabilities */ 3608 cmd->peer_he_cap_info = 3609 param->peer_he_cap_macinfo[WMI_HOST_HECAP_MAC_WORD1]; 3610 cmd->peer_he_cap_info_ext = 3611 param->peer_he_cap_macinfo[WMI_HOST_HECAP_MAC_WORD2]; 3612 cmd->peer_he_cap_info_internal = param->peer_he_cap_info_internal; 3613 cmd->peer_he_ops = param->peer_he_ops; 3614 qdf_mem_copy(&cmd->peer_he_cap_phy, ¶m->peer_he_cap_phyinfo, 3615 sizeof(param->peer_he_cap_phyinfo)); 3616 qdf_mem_copy(&cmd->peer_ppet, ¶m->peer_ppet, 3617 sizeof(param->peer_ppet)); 3618 cmd->peer_he_caps_6ghz = param->peer_he_caps_6ghz; 3619 3620 /* Update peer legacy rate information */ 3621 buf_ptr += sizeof(*cmd); 3622 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, 3623 peer_legacy_rates_align); 3624 buf_ptr += WMI_TLV_HDR_SIZE; 3625 cmd->num_peer_legacy_rates = param->peer_legacy_rates.num_rates; 3626 qdf_mem_copy(buf_ptr, param->peer_legacy_rates.rates, 3627 param->peer_legacy_rates.num_rates); 3628 3629 /* Update peer HT rate information */ 3630 buf_ptr += peer_legacy_rates_align; 3631 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, 3632 peer_ht_rates_align); 3633 buf_ptr += WMI_TLV_HDR_SIZE; 3634 cmd->num_peer_ht_rates = param->peer_ht_rates.num_rates; 3635 qdf_mem_copy(buf_ptr, param->peer_ht_rates.rates, 3636 param->peer_ht_rates.num_rates); 3637 3638 /* VHT Rates */ 3639 buf_ptr += peer_ht_rates_align; 3640 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_STRUC_wmi_vht_rate_set, 3641 WMITLV_GET_STRUCT_TLVLEN(wmi_vht_rate_set)); 3642 3643 cmd->auth_mode = param->akm; 3644 cmd->peer_nss = param->peer_nss; 3645 3646 /* Update bandwidth-NSS mapping */ 3647 cmd->peer_bw_rxnss_override = 0; 3648 cmd->peer_bw_rxnss_override |= param->peer_bw_rxnss_override; 3649 3650 mcs = (wmi_vht_rate_set *) buf_ptr; 3651 if (param->vht_capable) { 3652 mcs->rx_max_rate = param->rx_max_rate; 3653 mcs->rx_mcs_set = param->rx_mcs_set; 3654 mcs->tx_max_rate = param->tx_max_rate; 3655 mcs->tx_mcs_set = param->tx_mcs_set; 3656 mcs->tx_max_mcs_nss = param->tx_max_mcs_nss; 3657 } 3658 3659 /* HE Rates */ 3660 cmd->min_data_rate = param->min_data_rate; 3661 cmd->peer_he_mcs = param->peer_he_mcs_count; 3662 buf_ptr += sizeof(wmi_vht_rate_set); 3663 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 3664 (param->peer_he_mcs_count * sizeof(wmi_he_rate_set))); 3665 buf_ptr += WMI_TLV_HDR_SIZE; 3666 3667 WMI_PEER_STA_TYPE_SET(cmd->sta_type, param->peer_bsscolor_rept_info); 3668 /* Loop through the HE rate set */ 3669 for (i = 0; i < param->peer_he_mcs_count; i++) { 3670 he_mcs = (wmi_he_rate_set *) buf_ptr; 3671 WMITLV_SET_HDR(he_mcs, WMITLV_TAG_STRUC_wmi_he_rate_set, 3672 WMITLV_GET_STRUCT_TLVLEN(wmi_he_rate_set)); 3673 3674 he_mcs->rx_mcs_set = param->peer_he_rx_mcs_set[i]; 3675 he_mcs->tx_mcs_set = param->peer_he_tx_mcs_set[i]; 3676 wmi_debug("HE idx %d RxMCSmap %x TxMCSmap %x ", 3677 i, he_mcs->rx_mcs_set, he_mcs->tx_mcs_set); 3678 buf_ptr += sizeof(wmi_he_rate_set); 3679 } 3680 3681 if ((param->he_flag) && (param->peer_he_mcs_count > 1) && 3682 (param->peer_he_rx_mcs_set[WMI_HOST_HE_TXRX_MCS_NSS_IDX_160] 3683 == WMI_HOST_HE_INVALID_MCSNSSMAP || 3684 param->peer_he_tx_mcs_set[WMI_HOST_HE_TXRX_MCS_NSS_IDX_160] 3685 == WMI_HOST_HE_INVALID_MCSNSSMAP)) { 3686 wmi_debug("param->peer_he_tx_mcs_set[160MHz]=%x", 3687 param->peer_he_tx_mcs_set[WMI_HOST_HE_TXRX_MCS_NSS_IDX_160]); 3688 wmi_debug("param->peer_he_rx_mcs_set[160MHz]=%x", 3689 param->peer_he_rx_mcs_set[WMI_HOST_HE_TXRX_MCS_NSS_IDX_160]); 3690 wmi_debug("peer_mac="QDF_MAC_ADDR_FMT, 3691 QDF_MAC_ADDR_REF(param->peer_mac)); 3692 } 3693 3694 wmi_debug("vdev_id %d associd %d peer_flags %x rate_caps %x " 3695 "peer_caps %x listen_intval %d ht_caps %x max_mpdu %d " 3696 "nss %d phymode %d peer_mpdu_density %d " 3697 "cmd->peer_vht_caps %x " 3698 "HE cap_info %x ops %x " 3699 "HE cap_info_ext %x " 3700 "HE phy %x %x %x " 3701 "peer_bw_rxnss_override %x", 3702 cmd->vdev_id, cmd->peer_associd, cmd->peer_flags, 3703 cmd->peer_rate_caps, cmd->peer_caps, 3704 cmd->peer_listen_intval, cmd->peer_ht_caps, 3705 cmd->peer_max_mpdu, cmd->peer_nss, cmd->peer_phymode, 3706 cmd->peer_mpdu_density, 3707 cmd->peer_vht_caps, cmd->peer_he_cap_info, 3708 cmd->peer_he_ops, cmd->peer_he_cap_info_ext, 3709 cmd->peer_he_cap_phy[0], cmd->peer_he_cap_phy[1], 3710 cmd->peer_he_cap_phy[2], 3711 cmd->peer_bw_rxnss_override); 3712 3713 buf_ptr = peer_assoc_add_mlo_params(buf_ptr, param); 3714 3715 buf_ptr = update_peer_flags_tlv_ehtinfo(cmd, param, buf_ptr); 3716 3717 buf_ptr = peer_assoc_add_ml_partner_links(buf_ptr, param); 3718 3719 buf_ptr = peer_assoc_add_tid_to_link_map(buf_ptr, param); 3720 3721 wmi_mtrace(WMI_PEER_ASSOC_CMDID, cmd->vdev_id, 0); 3722 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 3723 WMI_PEER_ASSOC_CMDID); 3724 if (QDF_IS_STATUS_ERROR(ret)) { 3725 wmi_err("Failed to send peer assoc command ret = %d", ret); 3726 wmi_buf_free(buf); 3727 } 3728 3729 return ret; 3730 } 3731 3732 /* copy_scan_notify_events() - Helper routine to copy scan notify events 3733 */ 3734 static inline void copy_scan_event_cntrl_flags( 3735 wmi_start_scan_cmd_fixed_param * cmd, 3736 struct scan_req_params *param) 3737 { 3738 3739 /* Scan events subscription */ 3740 if (param->scan_ev_started) 3741 cmd->notify_scan_events |= WMI_SCAN_EVENT_STARTED; 3742 if (param->scan_ev_completed) 3743 cmd->notify_scan_events |= WMI_SCAN_EVENT_COMPLETED; 3744 if (param->scan_ev_bss_chan) 3745 cmd->notify_scan_events |= WMI_SCAN_EVENT_BSS_CHANNEL; 3746 if (param->scan_ev_foreign_chan) 3747 cmd->notify_scan_events |= WMI_SCAN_EVENT_FOREIGN_CHANNEL; 3748 if (param->scan_ev_dequeued) 3749 cmd->notify_scan_events |= WMI_SCAN_EVENT_DEQUEUED; 3750 if (param->scan_ev_preempted) 3751 cmd->notify_scan_events |= WMI_SCAN_EVENT_PREEMPTED; 3752 if (param->scan_ev_start_failed) 3753 cmd->notify_scan_events |= WMI_SCAN_EVENT_START_FAILED; 3754 if (param->scan_ev_restarted) 3755 cmd->notify_scan_events |= WMI_SCAN_EVENT_RESTARTED; 3756 if (param->scan_ev_foreign_chn_exit) 3757 cmd->notify_scan_events |= WMI_SCAN_EVENT_FOREIGN_CHANNEL_EXIT; 3758 if (param->scan_ev_suspended) 3759 cmd->notify_scan_events |= WMI_SCAN_EVENT_SUSPENDED; 3760 if (param->scan_ev_resumed) 3761 cmd->notify_scan_events |= WMI_SCAN_EVENT_RESUMED; 3762 3763 /** Set scan control flags */ 3764 cmd->scan_ctrl_flags = 0; 3765 if (param->scan_f_passive) 3766 cmd->scan_ctrl_flags |= WMI_SCAN_FLAG_PASSIVE; 3767 if (param->scan_f_strict_passive_pch) 3768 cmd->scan_ctrl_flags |= WMI_SCAN_FLAG_STRICT_PASSIVE_ON_PCHN; 3769 if (param->scan_f_promisc_mode) 3770 cmd->scan_ctrl_flags |= WMI_SCAN_FILTER_PROMISCOUS; 3771 if (param->scan_f_capture_phy_err) 3772 cmd->scan_ctrl_flags |= WMI_SCAN_CAPTURE_PHY_ERROR; 3773 if (param->scan_f_half_rate) 3774 cmd->scan_ctrl_flags |= WMI_SCAN_FLAG_HALF_RATE_SUPPORT; 3775 if (param->scan_f_quarter_rate) 3776 cmd->scan_ctrl_flags |= WMI_SCAN_FLAG_QUARTER_RATE_SUPPORT; 3777 if (param->scan_f_cck_rates) 3778 cmd->scan_ctrl_flags |= WMI_SCAN_ADD_CCK_RATES; 3779 if (param->scan_f_ofdm_rates) 3780 cmd->scan_ctrl_flags |= WMI_SCAN_ADD_OFDM_RATES; 3781 if (param->scan_f_chan_stat_evnt) 3782 cmd->scan_ctrl_flags |= WMI_SCAN_CHAN_STAT_EVENT; 3783 if (param->scan_f_filter_prb_req) 3784 cmd->scan_ctrl_flags |= WMI_SCAN_FILTER_PROBE_REQ; 3785 if (param->scan_f_bcast_probe) 3786 cmd->scan_ctrl_flags |= WMI_SCAN_ADD_BCAST_PROBE_REQ; 3787 if (param->scan_f_offchan_mgmt_tx) 3788 cmd->scan_ctrl_flags |= WMI_SCAN_OFFCHAN_MGMT_TX; 3789 if (param->scan_f_offchan_data_tx) 3790 cmd->scan_ctrl_flags |= WMI_SCAN_OFFCHAN_DATA_TX; 3791 if (param->scan_f_force_active_dfs_chn) 3792 cmd->scan_ctrl_flags |= WMI_SCAN_FLAG_FORCE_ACTIVE_ON_DFS; 3793 if (param->scan_f_add_tpc_ie_in_probe) 3794 cmd->scan_ctrl_flags |= WMI_SCAN_ADD_TPC_IE_IN_PROBE_REQ; 3795 if (param->scan_f_add_ds_ie_in_probe) 3796 cmd->scan_ctrl_flags |= WMI_SCAN_ADD_DS_IE_IN_PROBE_REQ; 3797 if (param->scan_f_add_spoofed_mac_in_probe) 3798 cmd->scan_ctrl_flags |= WMI_SCAN_ADD_SPOOFED_MAC_IN_PROBE_REQ; 3799 if (param->scan_f_add_rand_seq_in_probe) 3800 cmd->scan_ctrl_flags |= WMI_SCAN_RANDOM_SEQ_NO_IN_PROBE_REQ; 3801 if (param->scan_f_en_ie_allowlist_in_probe) 3802 cmd->scan_ctrl_flags |= 3803 WMI_SCAN_ENABLE_IE_WHTELIST_IN_PROBE_REQ; 3804 3805 /* for adaptive scan mode using 3 bits (21 - 23 bits) */ 3806 WMI_SCAN_SET_DWELL_MODE(cmd->scan_ctrl_flags, 3807 param->adaptive_dwell_time_mode); 3808 } 3809 3810 /* scan_copy_ie_buffer() - Copy scan ie_data */ 3811 static inline void scan_copy_ie_buffer(uint8_t *buf_ptr, 3812 struct scan_req_params *params) 3813 { 3814 qdf_mem_copy(buf_ptr, params->extraie.ptr, params->extraie.len); 3815 } 3816 3817 /** 3818 * wmi_copy_scan_random_mac() - To copy scan randomization attrs to wmi buffer 3819 * @mac: random mac addr 3820 * @mask: random mac mask 3821 * @mac_addr: wmi random mac 3822 * @mac_mask: wmi random mac mask 3823 * 3824 * Return None. 3825 */ 3826 static inline 3827 void wmi_copy_scan_random_mac(uint8_t *mac, uint8_t *mask, 3828 wmi_mac_addr *mac_addr, wmi_mac_addr *mac_mask) 3829 { 3830 WMI_CHAR_ARRAY_TO_MAC_ADDR(mac, mac_addr); 3831 WMI_CHAR_ARRAY_TO_MAC_ADDR(mask, mac_mask); 3832 } 3833 3834 /* 3835 * wmi_fill_vendor_oui() - fill vendor OUIs 3836 * @buf_ptr: pointer to wmi tlv buffer 3837 * @num_vendor_oui: number of vendor OUIs to be filled 3838 * @param_voui: pointer to OUI buffer 3839 * 3840 * This function populates the wmi tlv buffer when vendor specific OUIs are 3841 * present. 3842 * 3843 * Return: None 3844 */ 3845 static inline 3846 void wmi_fill_vendor_oui(uint8_t *buf_ptr, uint32_t num_vendor_oui, 3847 uint32_t *pvoui) 3848 { 3849 wmi_vendor_oui *voui = NULL; 3850 uint32_t i; 3851 3852 voui = (wmi_vendor_oui *)buf_ptr; 3853 3854 for (i = 0; i < num_vendor_oui; i++) { 3855 WMITLV_SET_HDR(&voui[i].tlv_header, 3856 WMITLV_TAG_STRUC_wmi_vendor_oui, 3857 WMITLV_GET_STRUCT_TLVLEN(wmi_vendor_oui)); 3858 voui[i].oui_type_subtype = pvoui[i]; 3859 } 3860 } 3861 3862 /* 3863 * wmi_fill_ie_allowlist_attrs() - fill IE allowlist attrs 3864 * @ie_bitmap: output pointer to ie bit map in cmd 3865 * @num_vendor_oui: output pointer to num vendor OUIs 3866 * @ie_allowlist: input parameter 3867 * 3868 * This function populates the IE allowlist attrs of scan, pno and 3869 * scan oui commands for ie_allowlist parameter. 3870 * 3871 * Return: None 3872 */ 3873 static inline 3874 void wmi_fill_ie_allowlist_attrs(uint32_t *ie_bitmap, 3875 uint32_t *num_vendor_oui, 3876 struct probe_req_allowlist_attr *ie_allowlist) 3877 { 3878 uint32_t i = 0; 3879 3880 for (i = 0; i < PROBE_REQ_BITMAP_LEN; i++) 3881 ie_bitmap[i] = ie_allowlist->ie_bitmap[i]; 3882 3883 *num_vendor_oui = ie_allowlist->num_vendor_oui; 3884 } 3885 3886 /** 3887 * send_scan_start_cmd_tlv() - WMI scan start function 3888 * @wmi_handle: handle to WMI. 3889 * @params: pointer to hold scan start cmd parameter 3890 * 3891 * Return: QDF_STATUS_SUCCESS for success or error code 3892 */ 3893 static QDF_STATUS send_scan_start_cmd_tlv(wmi_unified_t wmi_handle, 3894 struct scan_req_params *params) 3895 { 3896 int32_t ret = 0; 3897 int32_t i; 3898 wmi_buf_t wmi_buf; 3899 wmi_start_scan_cmd_fixed_param *cmd; 3900 uint8_t *buf_ptr; 3901 uint32_t *tmp_ptr; 3902 wmi_ssid *ssid = NULL; 3903 wmi_mac_addr *bssid; 3904 size_t len = sizeof(*cmd); 3905 uint16_t extraie_len_with_pad = 0; 3906 uint8_t phymode_roundup = 0; 3907 struct probe_req_allowlist_attr *ie_allowlist = ¶ms->ie_allowlist; 3908 wmi_hint_freq_short_ssid *s_ssid = NULL; 3909 wmi_hint_freq_bssid *hint_bssid = NULL; 3910 3911 /* Length TLV placeholder for array of uint32_t */ 3912 len += WMI_TLV_HDR_SIZE; 3913 /* calculate the length of buffer required */ 3914 if (params->chan_list.num_chan) 3915 len += params->chan_list.num_chan * sizeof(uint32_t); 3916 3917 /* Length TLV placeholder for array of wmi_ssid structures */ 3918 len += WMI_TLV_HDR_SIZE; 3919 if (params->num_ssids) 3920 len += params->num_ssids * sizeof(wmi_ssid); 3921 3922 /* Length TLV placeholder for array of wmi_mac_addr structures */ 3923 len += WMI_TLV_HDR_SIZE; 3924 if (params->num_bssid) 3925 len += sizeof(wmi_mac_addr) * params->num_bssid; 3926 3927 /* Length TLV placeholder for array of bytes */ 3928 len += WMI_TLV_HDR_SIZE; 3929 if (params->extraie.len) 3930 extraie_len_with_pad = 3931 roundup(params->extraie.len, sizeof(uint32_t)); 3932 len += extraie_len_with_pad; 3933 3934 len += WMI_TLV_HDR_SIZE; /* Length of TLV for array of wmi_vendor_oui */ 3935 if (ie_allowlist->num_vendor_oui) 3936 len += ie_allowlist->num_vendor_oui * sizeof(wmi_vendor_oui); 3937 3938 len += WMI_TLV_HDR_SIZE; /* Length of TLV for array of scan phymode */ 3939 if (params->scan_f_wide_band) 3940 phymode_roundup = 3941 qdf_roundup(params->chan_list.num_chan * sizeof(uint8_t), 3942 sizeof(uint32_t)); 3943 len += phymode_roundup; 3944 3945 len += WMI_TLV_HDR_SIZE; 3946 if (params->num_hint_bssid) 3947 len += params->num_hint_bssid * sizeof(wmi_hint_freq_bssid); 3948 3949 len += WMI_TLV_HDR_SIZE; 3950 if (params->num_hint_s_ssid) 3951 len += params->num_hint_s_ssid * sizeof(wmi_hint_freq_short_ssid); 3952 3953 /* Allocate the memory */ 3954 wmi_buf = wmi_buf_alloc(wmi_handle, len); 3955 if (!wmi_buf) 3956 return QDF_STATUS_E_FAILURE; 3957 3958 buf_ptr = (uint8_t *) wmi_buf_data(wmi_buf); 3959 cmd = (wmi_start_scan_cmd_fixed_param *) buf_ptr; 3960 WMITLV_SET_HDR(&cmd->tlv_header, 3961 WMITLV_TAG_STRUC_wmi_start_scan_cmd_fixed_param, 3962 WMITLV_GET_STRUCT_TLVLEN 3963 (wmi_start_scan_cmd_fixed_param)); 3964 3965 cmd->scan_id = params->scan_id; 3966 cmd->scan_req_id = params->scan_req_id; 3967 cmd->vdev_id = params->vdev_id; 3968 cmd->scan_priority = params->scan_priority; 3969 3970 copy_scan_event_cntrl_flags(cmd, params); 3971 3972 cmd->dwell_time_active = params->dwell_time_active; 3973 cmd->dwell_time_active_2g = params->dwell_time_active_2g; 3974 cmd->dwell_time_passive = params->dwell_time_passive; 3975 cmd->min_dwell_time_6ghz = params->min_dwell_time_6g; 3976 cmd->dwell_time_active_6ghz = params->dwell_time_active_6g; 3977 cmd->dwell_time_passive_6ghz = params->dwell_time_passive_6g; 3978 cmd->scan_start_offset = params->scan_offset_time; 3979 cmd->min_rest_time = params->min_rest_time; 3980 cmd->max_rest_time = params->max_rest_time; 3981 cmd->repeat_probe_time = params->repeat_probe_time; 3982 cmd->probe_spacing_time = params->probe_spacing_time; 3983 cmd->idle_time = params->idle_time; 3984 cmd->max_scan_time = params->max_scan_time; 3985 cmd->probe_delay = params->probe_delay; 3986 cmd->burst_duration = params->burst_duration; 3987 cmd->num_chan = params->chan_list.num_chan; 3988 cmd->num_bssid = params->num_bssid; 3989 cmd->num_ssids = params->num_ssids; 3990 cmd->ie_len = params->extraie.len; 3991 cmd->n_probes = params->n_probes; 3992 cmd->scan_ctrl_flags_ext = params->scan_ctrl_flags_ext; 3993 3994 if (params->scan_random.randomize) 3995 wmi_copy_scan_random_mac(params->scan_random.mac_addr, 3996 params->scan_random.mac_mask, 3997 &cmd->mac_addr, 3998 &cmd->mac_mask); 3999 4000 if (ie_allowlist->allow_list) 4001 wmi_fill_ie_allowlist_attrs(cmd->ie_bitmap, 4002 &cmd->num_vendor_oui, 4003 ie_allowlist); 4004 4005 buf_ptr += sizeof(*cmd); 4006 tmp_ptr = (uint32_t *) (buf_ptr + WMI_TLV_HDR_SIZE); 4007 for (i = 0; i < params->chan_list.num_chan; ++i) { 4008 TARGET_SET_FREQ_IN_CHAN_LIST_TLV(tmp_ptr[i], 4009 params->chan_list.chan[i].freq); 4010 TARGET_SET_FLAGS_IN_CHAN_LIST_TLV(tmp_ptr[i], 4011 params->chan_list.chan[i].flags); 4012 } 4013 4014 WMITLV_SET_HDR(buf_ptr, 4015 WMITLV_TAG_ARRAY_UINT32, 4016 (params->chan_list.num_chan * sizeof(uint32_t))); 4017 buf_ptr += WMI_TLV_HDR_SIZE + 4018 (params->chan_list.num_chan * sizeof(uint32_t)); 4019 4020 if (params->num_ssids > WLAN_SCAN_MAX_NUM_SSID) { 4021 wmi_err("Invalid value for num_ssids %d", params->num_ssids); 4022 goto error; 4023 } 4024 4025 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_FIXED_STRUC, 4026 (params->num_ssids * sizeof(wmi_ssid))); 4027 4028 if (params->num_ssids) { 4029 ssid = (wmi_ssid *) (buf_ptr + WMI_TLV_HDR_SIZE); 4030 for (i = 0; i < params->num_ssids; ++i) { 4031 ssid->ssid_len = params->ssid[i].length; 4032 qdf_mem_copy(ssid->ssid, params->ssid[i].ssid, 4033 params->ssid[i].length); 4034 ssid++; 4035 } 4036 } 4037 buf_ptr += WMI_TLV_HDR_SIZE + (params->num_ssids * sizeof(wmi_ssid)); 4038 4039 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_FIXED_STRUC, 4040 (params->num_bssid * sizeof(wmi_mac_addr))); 4041 bssid = (wmi_mac_addr *) (buf_ptr + WMI_TLV_HDR_SIZE); 4042 4043 if (params->num_bssid) { 4044 for (i = 0; i < params->num_bssid; ++i) { 4045 WMI_CHAR_ARRAY_TO_MAC_ADDR( 4046 ¶ms->bssid_list[i].bytes[0], bssid); 4047 bssid++; 4048 } 4049 } 4050 4051 buf_ptr += WMI_TLV_HDR_SIZE + 4052 (params->num_bssid * sizeof(wmi_mac_addr)); 4053 4054 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, extraie_len_with_pad); 4055 if (params->extraie.len) 4056 scan_copy_ie_buffer(buf_ptr + WMI_TLV_HDR_SIZE, 4057 params); 4058 4059 buf_ptr += WMI_TLV_HDR_SIZE + extraie_len_with_pad; 4060 4061 /* probe req ie allowlisting */ 4062 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 4063 ie_allowlist->num_vendor_oui * sizeof(wmi_vendor_oui)); 4064 4065 buf_ptr += WMI_TLV_HDR_SIZE; 4066 4067 if (cmd->num_vendor_oui) { 4068 wmi_fill_vendor_oui(buf_ptr, cmd->num_vendor_oui, 4069 ie_allowlist->voui); 4070 buf_ptr += cmd->num_vendor_oui * sizeof(wmi_vendor_oui); 4071 } 4072 4073 /* Add phy mode TLV if it's a wide band scan */ 4074 if (params->scan_f_wide_band) { 4075 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, phymode_roundup); 4076 buf_ptr = (uint8_t *) (buf_ptr + WMI_TLV_HDR_SIZE); 4077 for (i = 0; i < params->chan_list.num_chan; ++i) 4078 buf_ptr[i] = 4079 WMI_SCAN_CHAN_SET_MODE(params->chan_list.chan[i].phymode); 4080 buf_ptr += phymode_roundup; 4081 } else { 4082 /* Add ZERO length phy mode TLV */ 4083 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, 0); 4084 buf_ptr += WMI_TLV_HDR_SIZE; 4085 } 4086 4087 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_FIXED_STRUC, 4088 (params->num_hint_s_ssid * sizeof(wmi_hint_freq_short_ssid))); 4089 if (params->num_hint_s_ssid) { 4090 s_ssid = (wmi_hint_freq_short_ssid *)(buf_ptr + WMI_TLV_HDR_SIZE); 4091 for (i = 0; i < params->num_hint_s_ssid; ++i) { 4092 s_ssid->freq_flags = params->hint_s_ssid[i].freq_flags; 4093 s_ssid->short_ssid = params->hint_s_ssid[i].short_ssid; 4094 s_ssid++; 4095 } 4096 } 4097 buf_ptr += WMI_TLV_HDR_SIZE + 4098 (params->num_hint_s_ssid * sizeof(wmi_hint_freq_short_ssid)); 4099 4100 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_FIXED_STRUC, 4101 (params->num_hint_bssid * sizeof(wmi_hint_freq_bssid))); 4102 if (params->num_hint_bssid) { 4103 hint_bssid = (wmi_hint_freq_bssid *)(buf_ptr + WMI_TLV_HDR_SIZE); 4104 for (i = 0; i < params->num_hint_bssid; ++i) { 4105 hint_bssid->freq_flags = 4106 params->hint_bssid[i].freq_flags; 4107 WMI_CHAR_ARRAY_TO_MAC_ADDR(¶ms->hint_bssid[i].bssid.bytes[0], 4108 &hint_bssid->bssid); 4109 hint_bssid++; 4110 } 4111 } 4112 4113 wmi_mtrace(WMI_START_SCAN_CMDID, cmd->vdev_id, 0); 4114 ret = wmi_unified_cmd_send(wmi_handle, wmi_buf, 4115 len, WMI_START_SCAN_CMDID); 4116 if (ret) { 4117 wmi_err("Failed to start scan: %d", ret); 4118 wmi_buf_free(wmi_buf); 4119 } 4120 return ret; 4121 error: 4122 wmi_buf_free(wmi_buf); 4123 return QDF_STATUS_E_FAILURE; 4124 } 4125 4126 /** 4127 * send_scan_stop_cmd_tlv() - WMI scan start function 4128 * @wmi_handle: handle to WMI. 4129 * @param: pointer to hold scan cancel cmd parameter 4130 * 4131 * Return: QDF_STATUS_SUCCESS for success or error code 4132 */ 4133 static QDF_STATUS send_scan_stop_cmd_tlv(wmi_unified_t wmi_handle, 4134 struct scan_cancel_param *param) 4135 { 4136 wmi_stop_scan_cmd_fixed_param *cmd; 4137 int ret; 4138 int len = sizeof(*cmd); 4139 wmi_buf_t wmi_buf; 4140 4141 /* Allocate the memory */ 4142 wmi_buf = wmi_buf_alloc(wmi_handle, len); 4143 if (!wmi_buf) { 4144 ret = QDF_STATUS_E_NOMEM; 4145 goto error; 4146 } 4147 4148 cmd = (wmi_stop_scan_cmd_fixed_param *) wmi_buf_data(wmi_buf); 4149 WMITLV_SET_HDR(&cmd->tlv_header, 4150 WMITLV_TAG_STRUC_wmi_stop_scan_cmd_fixed_param, 4151 WMITLV_GET_STRUCT_TLVLEN(wmi_stop_scan_cmd_fixed_param)); 4152 cmd->vdev_id = param->vdev_id; 4153 cmd->requestor = param->requester; 4154 cmd->scan_id = param->scan_id; 4155 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 4156 wmi_handle, 4157 param->pdev_id); 4158 /* stop the scan with the corresponding scan_id */ 4159 if (param->req_type == WLAN_SCAN_CANCEL_PDEV_ALL) { 4160 /* Cancelling all scans */ 4161 cmd->req_type = WMI_SCAN_STOP_ALL; 4162 } else if (param->req_type == WLAN_SCAN_CANCEL_VDEV_ALL) { 4163 /* Cancelling VAP scans */ 4164 cmd->req_type = WMI_SCN_STOP_VAP_ALL; 4165 } else if (param->req_type == WLAN_SCAN_CANCEL_SINGLE) { 4166 /* Cancelling specific scan */ 4167 cmd->req_type = WMI_SCAN_STOP_ONE; 4168 } else if (param->req_type == WLAN_SCAN_CANCEL_HOST_VDEV_ALL) { 4169 cmd->req_type = WMI_SCN_STOP_HOST_VAP_ALL; 4170 } else { 4171 wmi_err("Invalid Scan cancel req type: %d", param->req_type); 4172 wmi_buf_free(wmi_buf); 4173 return QDF_STATUS_E_INVAL; 4174 } 4175 4176 wmi_mtrace(WMI_STOP_SCAN_CMDID, cmd->vdev_id, 0); 4177 ret = wmi_unified_cmd_send(wmi_handle, wmi_buf, 4178 len, WMI_STOP_SCAN_CMDID); 4179 if (ret) { 4180 wmi_err("Failed to send stop scan: %d", ret); 4181 wmi_buf_free(wmi_buf); 4182 } 4183 4184 error: 4185 return ret; 4186 } 4187 4188 #define WMI_MAX_CHAN_INFO_LOG 192 4189 4190 /** 4191 * wmi_scan_chanlist_dump() - Dump scan channel list info 4192 * @scan_chan_list: scan channel list 4193 * 4194 * Return: void 4195 */ 4196 static void wmi_scan_chanlist_dump(struct scan_chan_list_params *scan_chan_list) 4197 { 4198 uint32_t i; 4199 uint8_t info[WMI_MAX_CHAN_INFO_LOG]; 4200 uint32_t len = 0; 4201 struct channel_param *chan; 4202 int ret; 4203 4204 wmi_debug("Total chan %d", scan_chan_list->nallchans); 4205 for (i = 0; i < scan_chan_list->nallchans; i++) { 4206 chan = &scan_chan_list->ch_param[i]; 4207 ret = qdf_scnprintf(info + len, sizeof(info) - len, 4208 " %d[%d][%d][%d]", chan->mhz, 4209 chan->maxregpower, 4210 chan->dfs_set, chan->nan_disabled); 4211 if (ret <= 0) 4212 break; 4213 len += ret; 4214 if (len >= (sizeof(info) - 20)) { 4215 wmi_nofl_debug("Chan[TXPwr][DFS][nan_disabled]:%s", 4216 info); 4217 len = 0; 4218 } 4219 } 4220 if (len) 4221 wmi_nofl_debug("Chan[TXPwr][DFS]:%s", info); 4222 } 4223 4224 static QDF_STATUS send_scan_chan_list_cmd_tlv(wmi_unified_t wmi_handle, 4225 struct scan_chan_list_params *chan_list) 4226 { 4227 wmi_buf_t buf; 4228 QDF_STATUS qdf_status = QDF_STATUS_SUCCESS; 4229 wmi_scan_chan_list_cmd_fixed_param *cmd; 4230 int i; 4231 uint8_t *buf_ptr; 4232 wmi_channel *chan_info; 4233 struct channel_param *tchan_info; 4234 uint16_t len; 4235 uint16_t num_send_chans, num_sends = 0; 4236 4237 wmi_scan_chanlist_dump(chan_list); 4238 tchan_info = &chan_list->ch_param[0]; 4239 while (chan_list->nallchans) { 4240 len = sizeof(*cmd) + WMI_TLV_HDR_SIZE; 4241 if (chan_list->nallchans > MAX_NUM_CHAN_PER_WMI_CMD) 4242 num_send_chans = MAX_NUM_CHAN_PER_WMI_CMD; 4243 else 4244 num_send_chans = chan_list->nallchans; 4245 4246 chan_list->nallchans -= num_send_chans; 4247 len += sizeof(wmi_channel) * num_send_chans; 4248 buf = wmi_buf_alloc(wmi_handle, len); 4249 if (!buf) { 4250 qdf_status = QDF_STATUS_E_NOMEM; 4251 goto end; 4252 } 4253 4254 buf_ptr = (uint8_t *)wmi_buf_data(buf); 4255 cmd = (wmi_scan_chan_list_cmd_fixed_param *)buf_ptr; 4256 WMITLV_SET_HDR(&cmd->tlv_header, 4257 WMITLV_TAG_STRUC_wmi_scan_chan_list_cmd_fixed_param, 4258 WMITLV_GET_STRUCT_TLVLEN 4259 (wmi_scan_chan_list_cmd_fixed_param)); 4260 4261 wmi_debug("no of channels = %d, len = %d", num_send_chans, len); 4262 4263 if (num_sends) 4264 cmd->flags |= APPEND_TO_EXISTING_CHAN_LIST; 4265 4266 if (chan_list->max_bw_support_present) 4267 cmd->flags |= CHANNEL_MAX_BANDWIDTH_VALID; 4268 4269 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 4270 wmi_handle, 4271 chan_list->pdev_id); 4272 4273 wmi_mtrace(WMI_SCAN_CHAN_LIST_CMDID, cmd->pdev_id, 0); 4274 4275 cmd->num_scan_chans = num_send_chans; 4276 WMITLV_SET_HDR((buf_ptr + 4277 sizeof(wmi_scan_chan_list_cmd_fixed_param)), 4278 WMITLV_TAG_ARRAY_STRUC, 4279 sizeof(wmi_channel) * num_send_chans); 4280 chan_info = (wmi_channel *)(buf_ptr + sizeof(*cmd) + 4281 WMI_TLV_HDR_SIZE); 4282 4283 for (i = 0; i < num_send_chans; ++i) { 4284 WMITLV_SET_HDR(&chan_info->tlv_header, 4285 WMITLV_TAG_STRUC_wmi_channel, 4286 WMITLV_GET_STRUCT_TLVLEN(wmi_channel)); 4287 chan_info->mhz = tchan_info->mhz; 4288 chan_info->band_center_freq1 = 4289 tchan_info->cfreq1; 4290 chan_info->band_center_freq2 = 4291 tchan_info->cfreq2; 4292 4293 if (tchan_info->is_chan_passive) 4294 WMI_SET_CHANNEL_FLAG(chan_info, 4295 WMI_CHAN_FLAG_PASSIVE); 4296 if (tchan_info->dfs_set) 4297 WMI_SET_CHANNEL_FLAG(chan_info, 4298 WMI_CHAN_FLAG_DFS); 4299 4300 if (tchan_info->dfs_set_cfreq2) 4301 WMI_SET_CHANNEL_FLAG(chan_info, 4302 WMI_CHAN_FLAG_DFS_CFREQ2); 4303 4304 if (tchan_info->allow_he) 4305 WMI_SET_CHANNEL_FLAG(chan_info, 4306 WMI_CHAN_FLAG_ALLOW_HE); 4307 4308 if (tchan_info->allow_eht) 4309 WMI_SET_CHANNEL_FLAG(chan_info, 4310 WMI_CHAN_FLAG_ALLOW_EHT); 4311 4312 if (tchan_info->allow_vht) 4313 WMI_SET_CHANNEL_FLAG(chan_info, 4314 WMI_CHAN_FLAG_ALLOW_VHT); 4315 4316 if (tchan_info->allow_ht) 4317 WMI_SET_CHANNEL_FLAG(chan_info, 4318 WMI_CHAN_FLAG_ALLOW_HT); 4319 WMI_SET_CHANNEL_MODE(chan_info, 4320 tchan_info->phy_mode); 4321 4322 if (tchan_info->half_rate) 4323 WMI_SET_CHANNEL_FLAG(chan_info, 4324 WMI_CHAN_FLAG_HALF_RATE); 4325 4326 if (tchan_info->quarter_rate) 4327 WMI_SET_CHANNEL_FLAG(chan_info, 4328 WMI_CHAN_FLAG_QUARTER_RATE); 4329 4330 if (tchan_info->psc_channel) 4331 WMI_SET_CHANNEL_FLAG(chan_info, 4332 WMI_CHAN_FLAG_PSC); 4333 4334 if (tchan_info->nan_disabled) 4335 WMI_SET_CHANNEL_FLAG(chan_info, 4336 WMI_CHAN_FLAG_NAN_DISABLED); 4337 4338 /* also fill in power information */ 4339 WMI_SET_CHANNEL_MIN_POWER(chan_info, 4340 tchan_info->minpower); 4341 WMI_SET_CHANNEL_MAX_POWER(chan_info, 4342 tchan_info->maxpower); 4343 WMI_SET_CHANNEL_REG_POWER(chan_info, 4344 tchan_info->maxregpower); 4345 WMI_SET_CHANNEL_ANTENNA_MAX(chan_info, 4346 tchan_info->antennamax); 4347 WMI_SET_CHANNEL_REG_CLASSID(chan_info, 4348 tchan_info->reg_class_id); 4349 WMI_SET_CHANNEL_MAX_TX_POWER(chan_info, 4350 tchan_info->maxregpower); 4351 WMI_SET_CHANNEL_MAX_BANDWIDTH(chan_info, 4352 tchan_info->max_bw_supported); 4353 4354 tchan_info++; 4355 chan_info++; 4356 } 4357 4358 qdf_status = wmi_unified_cmd_send( 4359 wmi_handle, 4360 buf, len, WMI_SCAN_CHAN_LIST_CMDID); 4361 4362 if (QDF_IS_STATUS_ERROR(qdf_status)) { 4363 wmi_err("Failed to send WMI_SCAN_CHAN_LIST_CMDID"); 4364 wmi_buf_free(buf); 4365 goto end; 4366 } 4367 num_sends++; 4368 } 4369 4370 end: 4371 return qdf_status; 4372 } 4373 4374 /** 4375 * populate_tx_send_params - Populate TX param TLV for mgmt and offchan tx 4376 * 4377 * @bufp: Pointer to buffer 4378 * @param: Pointer to tx param 4379 * 4380 * Return: QDF_STATUS_SUCCESS for success and QDF_STATUS_E_FAILURE for failure 4381 */ 4382 static inline QDF_STATUS populate_tx_send_params(uint8_t *bufp, 4383 struct tx_send_params param) 4384 { 4385 wmi_tx_send_params *tx_param; 4386 QDF_STATUS status = QDF_STATUS_SUCCESS; 4387 4388 if (!bufp) { 4389 status = QDF_STATUS_E_FAILURE; 4390 return status; 4391 } 4392 tx_param = (wmi_tx_send_params *)bufp; 4393 WMITLV_SET_HDR(&tx_param->tlv_header, 4394 WMITLV_TAG_STRUC_wmi_tx_send_params, 4395 WMITLV_GET_STRUCT_TLVLEN(wmi_tx_send_params)); 4396 WMI_TX_SEND_PARAM_PWR_SET(tx_param->tx_param_dword0, param.pwr); 4397 WMI_TX_SEND_PARAM_MCS_MASK_SET(tx_param->tx_param_dword0, 4398 param.mcs_mask); 4399 WMI_TX_SEND_PARAM_NSS_MASK_SET(tx_param->tx_param_dword0, 4400 param.nss_mask); 4401 WMI_TX_SEND_PARAM_RETRY_LIMIT_SET(tx_param->tx_param_dword0, 4402 param.retry_limit); 4403 WMI_TX_SEND_PARAM_CHAIN_MASK_SET(tx_param->tx_param_dword1, 4404 param.chain_mask); 4405 WMI_TX_SEND_PARAM_BW_MASK_SET(tx_param->tx_param_dword1, 4406 param.bw_mask); 4407 WMI_TX_SEND_PARAM_PREAMBLE_SET(tx_param->tx_param_dword1, 4408 param.preamble_type); 4409 WMI_TX_SEND_PARAM_FRAME_TYPE_SET(tx_param->tx_param_dword1, 4410 param.frame_type); 4411 WMI_TX_SEND_PARAM_CFR_CAPTURE_SET(tx_param->tx_param_dword1, 4412 param.cfr_enable); 4413 WMI_TX_SEND_PARAM_BEAMFORM_SET(tx_param->tx_param_dword1, 4414 param.en_beamforming); 4415 WMI_TX_SEND_PARAM_RETRY_LIMIT_EXT_SET(tx_param->tx_param_dword1, 4416 param.retry_limit_ext); 4417 4418 return status; 4419 } 4420 4421 #ifdef CONFIG_HL_SUPPORT 4422 /** 4423 * send_mgmt_cmd_tlv() - WMI scan start function 4424 * @wmi_handle: handle to WMI. 4425 * @param: pointer to hold mgmt cmd parameter 4426 * 4427 * Return: QDF_STATUS_SUCCESS for success or error code 4428 */ 4429 static QDF_STATUS send_mgmt_cmd_tlv(wmi_unified_t wmi_handle, 4430 struct wmi_mgmt_params *param) 4431 { 4432 wmi_buf_t buf; 4433 uint8_t *bufp; 4434 int32_t cmd_len; 4435 wmi_mgmt_tx_send_cmd_fixed_param *cmd; 4436 int32_t bufp_len = (param->frm_len < mgmt_tx_dl_frm_len) ? param->frm_len : 4437 mgmt_tx_dl_frm_len; 4438 4439 if (param->frm_len > mgmt_tx_dl_frm_len) { 4440 wmi_err("mgmt frame len %u exceeds %u", 4441 param->frm_len, mgmt_tx_dl_frm_len); 4442 return QDF_STATUS_E_INVAL; 4443 } 4444 4445 cmd_len = sizeof(wmi_mgmt_tx_send_cmd_fixed_param) + 4446 WMI_TLV_HDR_SIZE + 4447 roundup(bufp_len, sizeof(uint32_t)); 4448 4449 buf = wmi_buf_alloc(wmi_handle, sizeof(wmi_tx_send_params) + cmd_len); 4450 if (!buf) 4451 return QDF_STATUS_E_NOMEM; 4452 4453 cmd = (wmi_mgmt_tx_send_cmd_fixed_param *)wmi_buf_data(buf); 4454 bufp = (uint8_t *) cmd; 4455 WMITLV_SET_HDR(&cmd->tlv_header, 4456 WMITLV_TAG_STRUC_wmi_mgmt_tx_send_cmd_fixed_param, 4457 WMITLV_GET_STRUCT_TLVLEN 4458 (wmi_mgmt_tx_send_cmd_fixed_param)); 4459 4460 cmd->vdev_id = param->vdev_id; 4461 4462 cmd->desc_id = param->desc_id; 4463 cmd->chanfreq = param->chanfreq; 4464 bufp += sizeof(wmi_mgmt_tx_send_cmd_fixed_param); 4465 WMITLV_SET_HDR(bufp, WMITLV_TAG_ARRAY_BYTE, roundup(bufp_len, 4466 sizeof(uint32_t))); 4467 bufp += WMI_TLV_HDR_SIZE; 4468 qdf_mem_copy(bufp, param->pdata, bufp_len); 4469 4470 cmd->frame_len = param->frm_len; 4471 cmd->buf_len = bufp_len; 4472 cmd->tx_params_valid = param->tx_params_valid; 4473 cmd->tx_flags = param->tx_flags; 4474 cmd->peer_rssi = param->peer_rssi; 4475 4476 wmi_mgmt_cmd_record(wmi_handle, WMI_MGMT_TX_SEND_CMDID, 4477 bufp, cmd->vdev_id, cmd->chanfreq); 4478 4479 bufp += roundup(bufp_len, sizeof(uint32_t)); 4480 if (param->tx_params_valid) { 4481 if (populate_tx_send_params(bufp, param->tx_param) != 4482 QDF_STATUS_SUCCESS) { 4483 wmi_err("Populate TX send params failed"); 4484 goto free_buf; 4485 } 4486 cmd_len += sizeof(wmi_tx_send_params); 4487 } 4488 4489 wmi_mtrace(WMI_MGMT_TX_SEND_CMDID, cmd->vdev_id, 0); 4490 if (wmi_unified_cmd_send(wmi_handle, buf, cmd_len, 4491 WMI_MGMT_TX_SEND_CMDID)) { 4492 wmi_err("Failed to send mgmt Tx"); 4493 goto free_buf; 4494 } 4495 return QDF_STATUS_SUCCESS; 4496 4497 free_buf: 4498 wmi_buf_free(buf); 4499 return QDF_STATUS_E_FAILURE; 4500 } 4501 #else 4502 /** 4503 * send_mgmt_cmd_tlv() - WMI scan start function 4504 * @wmi_handle: handle to WMI. 4505 * @param: pointer to hold mgmt cmd parameter 4506 * 4507 * Return: QDF_STATUS_SUCCESS for success or error code 4508 */ 4509 static QDF_STATUS send_mgmt_cmd_tlv(wmi_unified_t wmi_handle, 4510 struct wmi_mgmt_params *param) 4511 { 4512 wmi_buf_t buf; 4513 wmi_mgmt_tx_send_cmd_fixed_param *cmd; 4514 int32_t cmd_len; 4515 uint64_t dma_addr; 4516 void *qdf_ctx = param->qdf_ctx; 4517 uint8_t *bufp; 4518 QDF_STATUS status = QDF_STATUS_SUCCESS; 4519 wmi_mlo_tx_send_params *mlo_params; 4520 int32_t bufp_len = (param->frm_len < mgmt_tx_dl_frm_len) ? param->frm_len : 4521 mgmt_tx_dl_frm_len; 4522 4523 cmd_len = sizeof(wmi_mgmt_tx_send_cmd_fixed_param) + 4524 WMI_TLV_HDR_SIZE + 4525 roundup(bufp_len, sizeof(uint32_t)); 4526 4527 buf = wmi_buf_alloc(wmi_handle, sizeof(wmi_tx_send_params) + cmd_len + 4528 WMI_TLV_HDR_SIZE + sizeof(wmi_mlo_tx_send_params)); 4529 if (!buf) 4530 return QDF_STATUS_E_NOMEM; 4531 4532 cmd = (wmi_mgmt_tx_send_cmd_fixed_param *)wmi_buf_data(buf); 4533 bufp = (uint8_t *) cmd; 4534 WMITLV_SET_HDR(&cmd->tlv_header, 4535 WMITLV_TAG_STRUC_wmi_mgmt_tx_send_cmd_fixed_param, 4536 WMITLV_GET_STRUCT_TLVLEN 4537 (wmi_mgmt_tx_send_cmd_fixed_param)); 4538 4539 cmd->vdev_id = param->vdev_id; 4540 4541 cmd->desc_id = param->desc_id; 4542 cmd->chanfreq = param->chanfreq; 4543 cmd->peer_rssi = param->peer_rssi; 4544 bufp += sizeof(wmi_mgmt_tx_send_cmd_fixed_param); 4545 WMITLV_SET_HDR(bufp, WMITLV_TAG_ARRAY_BYTE, roundup(bufp_len, 4546 sizeof(uint32_t))); 4547 bufp += WMI_TLV_HDR_SIZE; 4548 4549 /* for big endian host, copy engine byte_swap is enabled 4550 * But the frame content is in network byte order 4551 * Need to byte swap the frame content - so when copy engine 4552 * does byte_swap - target gets frame content in the correct order 4553 */ 4554 WMI_HOST_IF_MSG_COPY_CHAR_ARRAY(bufp, param->pdata, bufp_len); 4555 4556 status = qdf_nbuf_map_single(qdf_ctx, param->tx_frame, 4557 QDF_DMA_TO_DEVICE); 4558 if (status != QDF_STATUS_SUCCESS) { 4559 wmi_err("wmi buf map failed"); 4560 goto free_buf; 4561 } 4562 4563 dma_addr = qdf_nbuf_get_frag_paddr(param->tx_frame, 0); 4564 cmd->paddr_lo = (uint32_t)(dma_addr & 0xffffffff); 4565 #if defined(HTT_PADDR64) 4566 cmd->paddr_hi = (uint32_t)((dma_addr >> 32) & 0x1F); 4567 #endif 4568 cmd->frame_len = param->frm_len; 4569 cmd->buf_len = bufp_len; 4570 cmd->tx_params_valid = param->tx_params_valid; 4571 cmd->tx_flags = param->tx_flags; 4572 4573 wmi_mgmt_cmd_record(wmi_handle, WMI_MGMT_TX_SEND_CMDID, 4574 bufp, cmd->vdev_id, cmd->chanfreq); 4575 4576 bufp += roundup(bufp_len, sizeof(uint32_t)); 4577 if (param->tx_params_valid) { 4578 status = populate_tx_send_params(bufp, param->tx_param); 4579 if (status != QDF_STATUS_SUCCESS) { 4580 wmi_err("Populate TX send params failed"); 4581 goto unmap_tx_frame; 4582 } 4583 } else { 4584 WMITLV_SET_HDR(&((wmi_tx_send_params *)bufp)->tlv_header, 4585 WMITLV_TAG_STRUC_wmi_tx_send_params, 4586 WMITLV_GET_STRUCT_TLVLEN(wmi_tx_send_params)); 4587 } 4588 4589 /* Even tx_params_valid is false, still need reserve space to pass wmi 4590 * tag check */ 4591 cmd_len += sizeof(wmi_tx_send_params); 4592 bufp += sizeof(wmi_tx_send_params); 4593 /* wmi_mlo_tx_send_params */ 4594 if (param->mlo_link_agnostic) { 4595 wmi_debug("Set mlo mgmt tid"); 4596 WMITLV_SET_HDR(bufp, WMITLV_TAG_ARRAY_STRUC, 4597 sizeof(wmi_mlo_tx_send_params)); 4598 bufp += WMI_TLV_HDR_SIZE; 4599 mlo_params = (wmi_mlo_tx_send_params *)bufp; 4600 WMITLV_SET_HDR(&mlo_params->tlv_header, 4601 WMITLV_TAG_STRUC_wmi_mlo_tx_send_params, 4602 WMITLV_GET_STRUCT_TLVLEN(wmi_mlo_tx_send_params)); 4603 mlo_params->hw_link_id = WMI_MLO_MGMT_TID; 4604 cmd_len += WMI_TLV_HDR_SIZE + sizeof(wmi_mlo_tx_send_params); 4605 } 4606 4607 wmi_mtrace(WMI_MGMT_TX_SEND_CMDID, cmd->vdev_id, 0); 4608 if (wmi_unified_cmd_send(wmi_handle, buf, cmd_len, 4609 WMI_MGMT_TX_SEND_CMDID)) { 4610 wmi_err("Failed to send mgmt Tx"); 4611 goto unmap_tx_frame; 4612 } 4613 return QDF_STATUS_SUCCESS; 4614 4615 unmap_tx_frame: 4616 qdf_nbuf_unmap_single(qdf_ctx, param->tx_frame, 4617 QDF_DMA_TO_DEVICE); 4618 free_buf: 4619 wmi_buf_free(buf); 4620 return QDF_STATUS_E_FAILURE; 4621 } 4622 #endif /* CONFIG_HL_SUPPORT */ 4623 4624 /** 4625 * send_offchan_data_tx_cmd_tlv() - Send off-chan tx data 4626 * @wmi_handle: handle to WMI. 4627 * @param: pointer to offchan data tx cmd parameter 4628 * 4629 * Return: QDF_STATUS_SUCCESS on success and error on failure. 4630 */ 4631 static QDF_STATUS send_offchan_data_tx_cmd_tlv(wmi_unified_t wmi_handle, 4632 struct wmi_offchan_data_tx_params *param) 4633 { 4634 wmi_buf_t buf; 4635 wmi_offchan_data_tx_send_cmd_fixed_param *cmd; 4636 int32_t cmd_len; 4637 uint64_t dma_addr; 4638 void *qdf_ctx = param->qdf_ctx; 4639 uint8_t *bufp; 4640 int32_t bufp_len = (param->frm_len < mgmt_tx_dl_frm_len) ? 4641 param->frm_len : mgmt_tx_dl_frm_len; 4642 QDF_STATUS status = QDF_STATUS_SUCCESS; 4643 4644 cmd_len = sizeof(wmi_offchan_data_tx_send_cmd_fixed_param) + 4645 WMI_TLV_HDR_SIZE + 4646 roundup(bufp_len, sizeof(uint32_t)); 4647 4648 buf = wmi_buf_alloc(wmi_handle, sizeof(wmi_tx_send_params) + cmd_len); 4649 if (!buf) 4650 return QDF_STATUS_E_NOMEM; 4651 4652 cmd = (wmi_offchan_data_tx_send_cmd_fixed_param *) wmi_buf_data(buf); 4653 bufp = (uint8_t *) cmd; 4654 WMITLV_SET_HDR(&cmd->tlv_header, 4655 WMITLV_TAG_STRUC_wmi_offchan_data_tx_send_cmd_fixed_param, 4656 WMITLV_GET_STRUCT_TLVLEN 4657 (wmi_offchan_data_tx_send_cmd_fixed_param)); 4658 4659 cmd->vdev_id = param->vdev_id; 4660 4661 cmd->desc_id = param->desc_id; 4662 cmd->chanfreq = param->chanfreq; 4663 bufp += sizeof(wmi_offchan_data_tx_send_cmd_fixed_param); 4664 WMITLV_SET_HDR(bufp, WMITLV_TAG_ARRAY_BYTE, roundup(bufp_len, 4665 sizeof(uint32_t))); 4666 bufp += WMI_TLV_HDR_SIZE; 4667 qdf_mem_copy(bufp, param->pdata, bufp_len); 4668 qdf_nbuf_map_single(qdf_ctx, param->tx_frame, QDF_DMA_TO_DEVICE); 4669 dma_addr = qdf_nbuf_get_frag_paddr(param->tx_frame, 0); 4670 cmd->paddr_lo = (uint32_t)(dma_addr & 0xffffffff); 4671 #if defined(HTT_PADDR64) 4672 cmd->paddr_hi = (uint32_t)((dma_addr >> 32) & 0x1F); 4673 #endif 4674 cmd->frame_len = param->frm_len; 4675 cmd->buf_len = bufp_len; 4676 cmd->tx_params_valid = param->tx_params_valid; 4677 4678 wmi_mgmt_cmd_record(wmi_handle, WMI_OFFCHAN_DATA_TX_SEND_CMDID, 4679 bufp, cmd->vdev_id, cmd->chanfreq); 4680 4681 bufp += roundup(bufp_len, sizeof(uint32_t)); 4682 if (param->tx_params_valid) { 4683 status = populate_tx_send_params(bufp, param->tx_param); 4684 if (status != QDF_STATUS_SUCCESS) { 4685 wmi_err("Populate TX send params failed"); 4686 goto err1; 4687 } 4688 cmd_len += sizeof(wmi_tx_send_params); 4689 } 4690 4691 wmi_mtrace(WMI_OFFCHAN_DATA_TX_SEND_CMDID, cmd->vdev_id, 0); 4692 if (wmi_unified_cmd_send(wmi_handle, buf, cmd_len, 4693 WMI_OFFCHAN_DATA_TX_SEND_CMDID)) { 4694 wmi_err("Failed to offchan data Tx"); 4695 goto err1; 4696 } 4697 4698 return QDF_STATUS_SUCCESS; 4699 4700 err1: 4701 wmi_buf_free(buf); 4702 return QDF_STATUS_E_FAILURE; 4703 } 4704 4705 /** 4706 * send_modem_power_state_cmd_tlv() - set modem power state to fw 4707 * @wmi_handle: wmi handle 4708 * @param_value: parameter value 4709 * 4710 * Return: QDF_STATUS_SUCCESS for success or error code 4711 */ 4712 static QDF_STATUS send_modem_power_state_cmd_tlv(wmi_unified_t wmi_handle, 4713 uint32_t param_value) 4714 { 4715 QDF_STATUS ret; 4716 wmi_modem_power_state_cmd_param *cmd; 4717 wmi_buf_t buf; 4718 uint16_t len = sizeof(*cmd); 4719 4720 buf = wmi_buf_alloc(wmi_handle, len); 4721 if (!buf) 4722 return QDF_STATUS_E_NOMEM; 4723 4724 cmd = (wmi_modem_power_state_cmd_param *) wmi_buf_data(buf); 4725 WMITLV_SET_HDR(&cmd->tlv_header, 4726 WMITLV_TAG_STRUC_wmi_modem_power_state_cmd_param, 4727 WMITLV_GET_STRUCT_TLVLEN 4728 (wmi_modem_power_state_cmd_param)); 4729 cmd->modem_power_state = param_value; 4730 wmi_debug("Setting cmd->modem_power_state = %u", param_value); 4731 wmi_mtrace(WMI_MODEM_POWER_STATE_CMDID, NO_SESSION, 0); 4732 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 4733 WMI_MODEM_POWER_STATE_CMDID); 4734 if (QDF_IS_STATUS_ERROR(ret)) { 4735 wmi_err("Failed to send notify cmd ret = %d", ret); 4736 wmi_buf_free(buf); 4737 } 4738 4739 return ret; 4740 } 4741 4742 /** 4743 * send_set_sta_ps_mode_cmd_tlv() - set sta powersave mode in fw 4744 * @wmi_handle: wmi handle 4745 * @vdev_id: vdev id 4746 * @val: value 4747 * 4748 * Return: QDF_STATUS_SUCCESS for success or error code. 4749 */ 4750 static QDF_STATUS send_set_sta_ps_mode_cmd_tlv(wmi_unified_t wmi_handle, 4751 uint32_t vdev_id, uint8_t val) 4752 { 4753 wmi_sta_powersave_mode_cmd_fixed_param *cmd; 4754 wmi_buf_t buf; 4755 int32_t len = sizeof(*cmd); 4756 4757 wmi_debug("Set Sta Mode Ps vdevId %d val %d", vdev_id, val); 4758 4759 buf = wmi_buf_alloc(wmi_handle, len); 4760 if (!buf) 4761 return QDF_STATUS_E_NOMEM; 4762 4763 cmd = (wmi_sta_powersave_mode_cmd_fixed_param *) wmi_buf_data(buf); 4764 WMITLV_SET_HDR(&cmd->tlv_header, 4765 WMITLV_TAG_STRUC_wmi_sta_powersave_mode_cmd_fixed_param, 4766 WMITLV_GET_STRUCT_TLVLEN 4767 (wmi_sta_powersave_mode_cmd_fixed_param)); 4768 cmd->vdev_id = vdev_id; 4769 if (val) 4770 cmd->sta_ps_mode = WMI_STA_PS_MODE_ENABLED; 4771 else 4772 cmd->sta_ps_mode = WMI_STA_PS_MODE_DISABLED; 4773 4774 wmi_mtrace(WMI_STA_POWERSAVE_MODE_CMDID, cmd->vdev_id, 0); 4775 if (wmi_unified_cmd_send(wmi_handle, buf, len, 4776 WMI_STA_POWERSAVE_MODE_CMDID)) { 4777 wmi_err("Set Sta Mode Ps Failed vdevId %d val %d", 4778 vdev_id, val); 4779 wmi_buf_free(buf); 4780 return QDF_STATUS_E_FAILURE; 4781 } 4782 return QDF_STATUS_SUCCESS; 4783 } 4784 4785 /** 4786 * send_idle_roam_monitor_cmd_tlv() - send idle monitor command to fw 4787 * @wmi_handle: wmi handle 4788 * @val: non-zero to turn monitor on 4789 * 4790 * Return: QDF_STATUS_SUCCESS for success or error code. 4791 */ 4792 static QDF_STATUS send_idle_roam_monitor_cmd_tlv(wmi_unified_t wmi_handle, 4793 uint8_t val) 4794 { 4795 wmi_idle_trigger_monitor_cmd_fixed_param *cmd; 4796 wmi_buf_t buf; 4797 size_t len = sizeof(*cmd); 4798 4799 buf = wmi_buf_alloc(wmi_handle, len); 4800 if (!buf) 4801 return QDF_STATUS_E_NOMEM; 4802 4803 cmd = (wmi_idle_trigger_monitor_cmd_fixed_param *)wmi_buf_data(buf); 4804 WMITLV_SET_HDR(&cmd->tlv_header, 4805 WMITLV_TAG_STRUC_wmi_idle_trigger_monitor_cmd_fixed_param, 4806 WMITLV_GET_STRUCT_TLVLEN(wmi_idle_trigger_monitor_cmd_fixed_param)); 4807 4808 cmd->idle_trigger_monitor = (val ? WMI_IDLE_TRIGGER_MONITOR_ON : 4809 WMI_IDLE_TRIGGER_MONITOR_OFF); 4810 4811 wmi_debug("val: %d", cmd->idle_trigger_monitor); 4812 4813 if (wmi_unified_cmd_send(wmi_handle, buf, len, 4814 WMI_IDLE_TRIGGER_MONITOR_CMDID)) { 4815 wmi_buf_free(buf); 4816 return QDF_STATUS_E_FAILURE; 4817 } 4818 return QDF_STATUS_SUCCESS; 4819 } 4820 4821 /** 4822 * send_set_mimops_cmd_tlv() - set MIMO powersave 4823 * @wmi_handle: wmi handle 4824 * @vdev_id: vdev id 4825 * @value: value 4826 * 4827 * Return: QDF_STATUS_SUCCESS for success or error code. 4828 */ 4829 static QDF_STATUS send_set_mimops_cmd_tlv(wmi_unified_t wmi_handle, 4830 uint8_t vdev_id, int value) 4831 { 4832 QDF_STATUS ret; 4833 wmi_sta_smps_force_mode_cmd_fixed_param *cmd; 4834 wmi_buf_t buf; 4835 uint16_t len = sizeof(*cmd); 4836 4837 buf = wmi_buf_alloc(wmi_handle, len); 4838 if (!buf) 4839 return QDF_STATUS_E_NOMEM; 4840 4841 cmd = (wmi_sta_smps_force_mode_cmd_fixed_param *) wmi_buf_data(buf); 4842 WMITLV_SET_HDR(&cmd->tlv_header, 4843 WMITLV_TAG_STRUC_wmi_sta_smps_force_mode_cmd_fixed_param, 4844 WMITLV_GET_STRUCT_TLVLEN 4845 (wmi_sta_smps_force_mode_cmd_fixed_param)); 4846 4847 cmd->vdev_id = vdev_id; 4848 4849 /* WMI_SMPS_FORCED_MODE values do not directly map 4850 * to SM power save values defined in the specification. 4851 * Make sure to send the right mapping. 4852 */ 4853 switch (value) { 4854 case 0: 4855 cmd->forced_mode = WMI_SMPS_FORCED_MODE_NONE; 4856 break; 4857 case 1: 4858 cmd->forced_mode = WMI_SMPS_FORCED_MODE_DISABLED; 4859 break; 4860 case 2: 4861 cmd->forced_mode = WMI_SMPS_FORCED_MODE_STATIC; 4862 break; 4863 case 3: 4864 cmd->forced_mode = WMI_SMPS_FORCED_MODE_DYNAMIC; 4865 break; 4866 default: 4867 wmi_err("INVALID MIMO PS CONFIG: %d", value); 4868 wmi_buf_free(buf); 4869 return QDF_STATUS_E_FAILURE; 4870 } 4871 4872 wmi_debug("Setting vdev %d value = %u", vdev_id, value); 4873 4874 wmi_mtrace(WMI_STA_SMPS_FORCE_MODE_CMDID, cmd->vdev_id, 0); 4875 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 4876 WMI_STA_SMPS_FORCE_MODE_CMDID); 4877 if (QDF_IS_STATUS_ERROR(ret)) { 4878 wmi_err("Failed to send set Mimo PS ret = %d", ret); 4879 wmi_buf_free(buf); 4880 } 4881 4882 return ret; 4883 } 4884 4885 /** 4886 * send_set_smps_params_cmd_tlv() - set smps params 4887 * @wmi_handle: wmi handle 4888 * @vdev_id: vdev id 4889 * @value: value 4890 * 4891 * Return: QDF_STATUS_SUCCESS for success or error code. 4892 */ 4893 static QDF_STATUS send_set_smps_params_cmd_tlv(wmi_unified_t wmi_handle, uint8_t vdev_id, 4894 int value) 4895 { 4896 QDF_STATUS ret; 4897 wmi_sta_smps_param_cmd_fixed_param *cmd; 4898 wmi_buf_t buf; 4899 uint16_t len = sizeof(*cmd); 4900 4901 buf = wmi_buf_alloc(wmi_handle, len); 4902 if (!buf) 4903 return QDF_STATUS_E_NOMEM; 4904 4905 cmd = (wmi_sta_smps_param_cmd_fixed_param *) wmi_buf_data(buf); 4906 WMITLV_SET_HDR(&cmd->tlv_header, 4907 WMITLV_TAG_STRUC_wmi_sta_smps_param_cmd_fixed_param, 4908 WMITLV_GET_STRUCT_TLVLEN 4909 (wmi_sta_smps_param_cmd_fixed_param)); 4910 4911 cmd->vdev_id = vdev_id; 4912 cmd->value = value & WMI_SMPS_MASK_LOWER_16BITS; 4913 cmd->param = 4914 (value >> WMI_SMPS_PARAM_VALUE_S) & WMI_SMPS_MASK_UPPER_3BITS; 4915 4916 wmi_debug("Setting vdev %d value = %x param %x", vdev_id, cmd->value, 4917 cmd->param); 4918 4919 wmi_mtrace(WMI_STA_SMPS_PARAM_CMDID, cmd->vdev_id, 0); 4920 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 4921 WMI_STA_SMPS_PARAM_CMDID); 4922 if (QDF_IS_STATUS_ERROR(ret)) { 4923 wmi_err("Failed to send set Mimo PS ret = %d", ret); 4924 wmi_buf_free(buf); 4925 } 4926 4927 return ret; 4928 } 4929 4930 /** 4931 * send_get_temperature_cmd_tlv() - get pdev temperature req 4932 * @wmi_handle: wmi handle 4933 * 4934 * Return: QDF_STATUS_SUCCESS for success or error code. 4935 */ 4936 static QDF_STATUS send_get_temperature_cmd_tlv(wmi_unified_t wmi_handle) 4937 { 4938 wmi_pdev_get_temperature_cmd_fixed_param *cmd; 4939 wmi_buf_t wmi_buf; 4940 uint32_t len = sizeof(wmi_pdev_get_temperature_cmd_fixed_param); 4941 uint8_t *buf_ptr; 4942 4943 if (!wmi_handle) { 4944 wmi_err("WMI is closed, can not issue cmd"); 4945 return QDF_STATUS_E_INVAL; 4946 } 4947 4948 wmi_buf = wmi_buf_alloc(wmi_handle, len); 4949 if (!wmi_buf) 4950 return QDF_STATUS_E_NOMEM; 4951 4952 buf_ptr = (uint8_t *) wmi_buf_data(wmi_buf); 4953 4954 cmd = (wmi_pdev_get_temperature_cmd_fixed_param *) buf_ptr; 4955 WMITLV_SET_HDR(&cmd->tlv_header, 4956 WMITLV_TAG_STRUC_wmi_pdev_get_temperature_cmd_fixed_param, 4957 WMITLV_GET_STRUCT_TLVLEN 4958 (wmi_pdev_get_temperature_cmd_fixed_param)); 4959 4960 wmi_mtrace(WMI_PDEV_GET_TEMPERATURE_CMDID, NO_SESSION, 0); 4961 if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len, 4962 WMI_PDEV_GET_TEMPERATURE_CMDID)) { 4963 wmi_err("Failed to send get temperature command"); 4964 wmi_buf_free(wmi_buf); 4965 return QDF_STATUS_E_FAILURE; 4966 } 4967 4968 return QDF_STATUS_SUCCESS; 4969 } 4970 4971 /** 4972 * send_set_sta_uapsd_auto_trig_cmd_tlv() - set uapsd auto trigger command 4973 * @wmi_handle: wmi handle 4974 * @param: UAPSD trigger parameters 4975 * 4976 * This function sets the trigger 4977 * uapsd params such as service interval, delay interval 4978 * and suspend interval which will be used by the firmware 4979 * to send trigger frames periodically when there is no 4980 * traffic on the transmit side. 4981 * 4982 * Return: QDF_STATUS_SUCCESS for success or error code. 4983 */ 4984 static QDF_STATUS send_set_sta_uapsd_auto_trig_cmd_tlv(wmi_unified_t wmi_handle, 4985 struct sta_uapsd_trig_params *param) 4986 { 4987 wmi_sta_uapsd_auto_trig_cmd_fixed_param *cmd; 4988 QDF_STATUS ret; 4989 uint32_t param_len = param->num_ac * sizeof(wmi_sta_uapsd_auto_trig_param); 4990 uint32_t cmd_len = sizeof(*cmd) + param_len + WMI_TLV_HDR_SIZE; 4991 uint32_t i; 4992 wmi_buf_t buf; 4993 uint8_t *buf_ptr; 4994 struct sta_uapsd_params *uapsd_param; 4995 wmi_sta_uapsd_auto_trig_param *trig_param; 4996 4997 buf = wmi_buf_alloc(wmi_handle, cmd_len); 4998 if (!buf) 4999 return QDF_STATUS_E_NOMEM; 5000 5001 buf_ptr = (uint8_t *) wmi_buf_data(buf); 5002 cmd = (wmi_sta_uapsd_auto_trig_cmd_fixed_param *) buf_ptr; 5003 WMITLV_SET_HDR(&cmd->tlv_header, 5004 WMITLV_TAG_STRUC_wmi_sta_uapsd_auto_trig_cmd_fixed_param, 5005 WMITLV_GET_STRUCT_TLVLEN 5006 (wmi_sta_uapsd_auto_trig_cmd_fixed_param)); 5007 cmd->vdev_id = param->vdevid; 5008 cmd->num_ac = param->num_ac; 5009 WMI_CHAR_ARRAY_TO_MAC_ADDR(param->peer_addr, &cmd->peer_macaddr); 5010 5011 /* TLV indicating array of structures to follow */ 5012 buf_ptr += sizeof(*cmd); 5013 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, param_len); 5014 5015 buf_ptr += WMI_TLV_HDR_SIZE; 5016 5017 /* 5018 * Update tag and length for uapsd auto trigger params (this will take 5019 * care of updating tag and length if it is not pre-filled by caller). 5020 */ 5021 uapsd_param = (struct sta_uapsd_params *)param->auto_triggerparam; 5022 trig_param = (wmi_sta_uapsd_auto_trig_param *)buf_ptr; 5023 for (i = 0; i < param->num_ac; i++) { 5024 WMITLV_SET_HDR((buf_ptr + 5025 (i * sizeof(wmi_sta_uapsd_auto_trig_param))), 5026 WMITLV_TAG_STRUC_wmi_sta_uapsd_auto_trig_param, 5027 WMITLV_GET_STRUCT_TLVLEN 5028 (wmi_sta_uapsd_auto_trig_param)); 5029 trig_param->wmm_ac = uapsd_param->wmm_ac; 5030 trig_param->user_priority = uapsd_param->user_priority; 5031 trig_param->service_interval = uapsd_param->service_interval; 5032 trig_param->suspend_interval = uapsd_param->suspend_interval; 5033 trig_param->delay_interval = uapsd_param->delay_interval; 5034 trig_param++; 5035 uapsd_param++; 5036 } 5037 5038 wmi_mtrace(WMI_STA_UAPSD_AUTO_TRIG_CMDID, cmd->vdev_id, 0); 5039 ret = wmi_unified_cmd_send(wmi_handle, buf, cmd_len, 5040 WMI_STA_UAPSD_AUTO_TRIG_CMDID); 5041 if (QDF_IS_STATUS_ERROR(ret)) { 5042 wmi_err("Failed to send set uapsd param ret = %d", ret); 5043 wmi_buf_free(buf); 5044 } 5045 5046 return ret; 5047 } 5048 5049 /** 5050 * send_set_thermal_mgmt_cmd_tlv() - set thermal mgmt command to fw 5051 * @wmi_handle: Pointer to wmi handle 5052 * @thermal_info: Thermal command information 5053 * 5054 * This function sends the thermal management command 5055 * to the firmware 5056 * 5057 * Return: QDF_STATUS_SUCCESS for success otherwise failure 5058 */ 5059 static QDF_STATUS send_set_thermal_mgmt_cmd_tlv(wmi_unified_t wmi_handle, 5060 struct thermal_cmd_params *thermal_info) 5061 { 5062 wmi_thermal_mgmt_cmd_fixed_param *cmd = NULL; 5063 wmi_buf_t buf = NULL; 5064 QDF_STATUS status; 5065 uint32_t len = 0; 5066 uint8_t action; 5067 5068 switch (thermal_info->thermal_action) { 5069 case THERMAL_MGMT_ACTION_DEFAULT: 5070 action = WMI_THERMAL_MGMT_ACTION_DEFAULT; 5071 break; 5072 5073 case THERMAL_MGMT_ACTION_HALT_TRAFFIC: 5074 action = WMI_THERMAL_MGMT_ACTION_HALT_TRAFFIC; 5075 break; 5076 5077 case THERMAL_MGMT_ACTION_NOTIFY_HOST: 5078 action = WMI_THERMAL_MGMT_ACTION_NOTIFY_HOST; 5079 break; 5080 5081 case THERMAL_MGMT_ACTION_CHAINSCALING: 5082 action = WMI_THERMAL_MGMT_ACTION_CHAINSCALING; 5083 break; 5084 5085 default: 5086 wmi_err("Invalid thermal_action code %d", 5087 thermal_info->thermal_action); 5088 return QDF_STATUS_E_FAILURE; 5089 } 5090 5091 len = sizeof(*cmd); 5092 5093 buf = wmi_buf_alloc(wmi_handle, len); 5094 if (!buf) 5095 return QDF_STATUS_E_FAILURE; 5096 5097 cmd = (wmi_thermal_mgmt_cmd_fixed_param *) wmi_buf_data(buf); 5098 5099 WMITLV_SET_HDR(&cmd->tlv_header, 5100 WMITLV_TAG_STRUC_wmi_thermal_mgmt_cmd_fixed_param, 5101 WMITLV_GET_STRUCT_TLVLEN 5102 (wmi_thermal_mgmt_cmd_fixed_param)); 5103 5104 cmd->lower_thresh_degreeC = thermal_info->min_temp; 5105 cmd->upper_thresh_degreeC = thermal_info->max_temp; 5106 cmd->enable = thermal_info->thermal_enable; 5107 cmd->action = action; 5108 5109 wmi_debug("TM Sending thermal mgmt cmd: low temp %d, upper temp %d, enabled %d action %d", 5110 cmd->lower_thresh_degreeC, cmd->upper_thresh_degreeC, 5111 cmd->enable, cmd->action); 5112 5113 wmi_mtrace(WMI_THERMAL_MGMT_CMDID, NO_SESSION, 0); 5114 status = wmi_unified_cmd_send(wmi_handle, buf, len, 5115 WMI_THERMAL_MGMT_CMDID); 5116 if (QDF_IS_STATUS_ERROR(status)) { 5117 wmi_buf_free(buf); 5118 wmi_err("Failed to send thermal mgmt command"); 5119 } 5120 5121 return status; 5122 } 5123 5124 /** 5125 * send_lro_config_cmd_tlv() - process the LRO config command 5126 * @wmi_handle: Pointer to WMI handle 5127 * @wmi_lro_cmd: Pointer to LRO configuration parameters 5128 * 5129 * This function sends down the LRO configuration parameters to 5130 * the firmware to enable LRO, sets the TCP flags and sets the 5131 * seed values for the toeplitz hash generation 5132 * 5133 * Return: QDF_STATUS_SUCCESS for success otherwise failure 5134 */ 5135 static QDF_STATUS send_lro_config_cmd_tlv(wmi_unified_t wmi_handle, 5136 struct wmi_lro_config_cmd_t *wmi_lro_cmd) 5137 { 5138 wmi_lro_info_cmd_fixed_param *cmd; 5139 wmi_buf_t buf; 5140 QDF_STATUS status; 5141 uint8_t pdev_id = wmi_lro_cmd->pdev_id; 5142 5143 buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd)); 5144 if (!buf) 5145 return QDF_STATUS_E_FAILURE; 5146 5147 cmd = (wmi_lro_info_cmd_fixed_param *) wmi_buf_data(buf); 5148 5149 WMITLV_SET_HDR(&cmd->tlv_header, 5150 WMITLV_TAG_STRUC_wmi_lro_info_cmd_fixed_param, 5151 WMITLV_GET_STRUCT_TLVLEN(wmi_lro_info_cmd_fixed_param)); 5152 5153 cmd->lro_enable = wmi_lro_cmd->lro_enable; 5154 WMI_LRO_INFO_TCP_FLAG_VALS_SET(cmd->tcp_flag_u32, 5155 wmi_lro_cmd->tcp_flag); 5156 WMI_LRO_INFO_TCP_FLAGS_MASK_SET(cmd->tcp_flag_u32, 5157 wmi_lro_cmd->tcp_flag_mask); 5158 cmd->toeplitz_hash_ipv4_0_3 = 5159 wmi_lro_cmd->toeplitz_hash_ipv4[0]; 5160 cmd->toeplitz_hash_ipv4_4_7 = 5161 wmi_lro_cmd->toeplitz_hash_ipv4[1]; 5162 cmd->toeplitz_hash_ipv4_8_11 = 5163 wmi_lro_cmd->toeplitz_hash_ipv4[2]; 5164 cmd->toeplitz_hash_ipv4_12_15 = 5165 wmi_lro_cmd->toeplitz_hash_ipv4[3]; 5166 cmd->toeplitz_hash_ipv4_16 = 5167 wmi_lro_cmd->toeplitz_hash_ipv4[4]; 5168 5169 cmd->toeplitz_hash_ipv6_0_3 = 5170 wmi_lro_cmd->toeplitz_hash_ipv6[0]; 5171 cmd->toeplitz_hash_ipv6_4_7 = 5172 wmi_lro_cmd->toeplitz_hash_ipv6[1]; 5173 cmd->toeplitz_hash_ipv6_8_11 = 5174 wmi_lro_cmd->toeplitz_hash_ipv6[2]; 5175 cmd->toeplitz_hash_ipv6_12_15 = 5176 wmi_lro_cmd->toeplitz_hash_ipv6[3]; 5177 cmd->toeplitz_hash_ipv6_16_19 = 5178 wmi_lro_cmd->toeplitz_hash_ipv6[4]; 5179 cmd->toeplitz_hash_ipv6_20_23 = 5180 wmi_lro_cmd->toeplitz_hash_ipv6[5]; 5181 cmd->toeplitz_hash_ipv6_24_27 = 5182 wmi_lro_cmd->toeplitz_hash_ipv6[6]; 5183 cmd->toeplitz_hash_ipv6_28_31 = 5184 wmi_lro_cmd->toeplitz_hash_ipv6[7]; 5185 cmd->toeplitz_hash_ipv6_32_35 = 5186 wmi_lro_cmd->toeplitz_hash_ipv6[8]; 5187 cmd->toeplitz_hash_ipv6_36_39 = 5188 wmi_lro_cmd->toeplitz_hash_ipv6[9]; 5189 cmd->toeplitz_hash_ipv6_40 = 5190 wmi_lro_cmd->toeplitz_hash_ipv6[10]; 5191 5192 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 5193 wmi_handle, 5194 pdev_id); 5195 wmi_debug("WMI_LRO_CONFIG: lro_enable %d, tcp_flag 0x%x, pdev_id: %d", 5196 cmd->lro_enable, cmd->tcp_flag_u32, cmd->pdev_id); 5197 5198 wmi_mtrace(WMI_LRO_CONFIG_CMDID, NO_SESSION, 0); 5199 status = wmi_unified_cmd_send(wmi_handle, buf, 5200 sizeof(*cmd), WMI_LRO_CONFIG_CMDID); 5201 if (QDF_IS_STATUS_ERROR(status)) { 5202 wmi_buf_free(buf); 5203 wmi_err("Failed to send WMI_LRO_CONFIG_CMDID"); 5204 } 5205 5206 return status; 5207 } 5208 5209 /** 5210 * send_peer_rate_report_cmd_tlv() - process the peer rate report command 5211 * @wmi_handle: Pointer to wmi handle 5212 * @rate_report_params: Pointer to peer rate report parameters 5213 * 5214 * 5215 * Return: QDF_STATUS_SUCCESS for success otherwise failure 5216 */ 5217 static QDF_STATUS send_peer_rate_report_cmd_tlv(wmi_unified_t wmi_handle, 5218 struct wmi_peer_rate_report_params *rate_report_params) 5219 { 5220 wmi_peer_set_rate_report_condition_fixed_param *cmd = NULL; 5221 wmi_buf_t buf = NULL; 5222 QDF_STATUS status = 0; 5223 uint32_t len = 0; 5224 uint32_t i, j; 5225 5226 len = sizeof(*cmd); 5227 5228 buf = wmi_buf_alloc(wmi_handle, len); 5229 if (!buf) 5230 return QDF_STATUS_E_FAILURE; 5231 5232 cmd = (wmi_peer_set_rate_report_condition_fixed_param *) 5233 wmi_buf_data(buf); 5234 5235 WMITLV_SET_HDR( 5236 &cmd->tlv_header, 5237 WMITLV_TAG_STRUC_wmi_peer_set_rate_report_condition_fixed_param, 5238 WMITLV_GET_STRUCT_TLVLEN( 5239 wmi_peer_set_rate_report_condition_fixed_param)); 5240 5241 cmd->enable_rate_report = rate_report_params->rate_report_enable; 5242 cmd->report_backoff_time = rate_report_params->backoff_time; 5243 cmd->report_timer_period = rate_report_params->timer_period; 5244 for (i = 0; i < PEER_RATE_REPORT_COND_MAX_NUM; i++) { 5245 cmd->cond_per_phy[i].val_cond_flags = 5246 rate_report_params->report_per_phy[i].cond_flags; 5247 cmd->cond_per_phy[i].rate_delta.min_delta = 5248 rate_report_params->report_per_phy[i].delta.delta_min; 5249 cmd->cond_per_phy[i].rate_delta.percentage = 5250 rate_report_params->report_per_phy[i].delta.percent; 5251 for (j = 0; j < MAX_NUM_OF_RATE_THRESH; j++) { 5252 cmd->cond_per_phy[i].rate_threshold[j] = 5253 rate_report_params->report_per_phy[i]. 5254 report_rate_threshold[j]; 5255 } 5256 } 5257 5258 wmi_debug("enable %d backoff_time %d period %d", 5259 cmd->enable_rate_report, 5260 cmd->report_backoff_time, cmd->report_timer_period); 5261 5262 wmi_mtrace(WMI_PEER_SET_RATE_REPORT_CONDITION_CMDID, NO_SESSION, 0); 5263 status = wmi_unified_cmd_send(wmi_handle, buf, len, 5264 WMI_PEER_SET_RATE_REPORT_CONDITION_CMDID); 5265 if (QDF_IS_STATUS_ERROR(status)) { 5266 wmi_buf_free(buf); 5267 wmi_err("Failed to send peer_set_report_cond command"); 5268 } 5269 return status; 5270 } 5271 5272 /** 5273 * send_process_update_edca_param_cmd_tlv() - update EDCA params 5274 * @wmi_handle: wmi handle 5275 * @vdev_id: vdev id. 5276 * @mu_edca_param: true if these are MU EDCA params 5277 * @wmm_vparams: edca parameters 5278 * 5279 * This function updates EDCA parameters to the target 5280 * 5281 * Return: CDF Status 5282 */ 5283 static QDF_STATUS send_process_update_edca_param_cmd_tlv(wmi_unified_t wmi_handle, 5284 uint8_t vdev_id, bool mu_edca_param, 5285 struct wmi_host_wme_vparams wmm_vparams[WMI_MAX_NUM_AC]) 5286 { 5287 uint8_t *buf_ptr; 5288 wmi_buf_t buf; 5289 wmi_vdev_set_wmm_params_cmd_fixed_param *cmd; 5290 wmi_wmm_vparams *wmm_param; 5291 struct wmi_host_wme_vparams *twmm_param; 5292 int len = sizeof(*cmd); 5293 int ac; 5294 5295 buf = wmi_buf_alloc(wmi_handle, len); 5296 5297 if (!buf) 5298 return QDF_STATUS_E_NOMEM; 5299 5300 buf_ptr = (uint8_t *) wmi_buf_data(buf); 5301 cmd = (wmi_vdev_set_wmm_params_cmd_fixed_param *) buf_ptr; 5302 WMITLV_SET_HDR(&cmd->tlv_header, 5303 WMITLV_TAG_STRUC_wmi_vdev_set_wmm_params_cmd_fixed_param, 5304 WMITLV_GET_STRUCT_TLVLEN 5305 (wmi_vdev_set_wmm_params_cmd_fixed_param)); 5306 cmd->vdev_id = vdev_id; 5307 cmd->wmm_param_type = mu_edca_param; 5308 5309 for (ac = 0; ac < WMI_MAX_NUM_AC; ac++) { 5310 wmm_param = (wmi_wmm_vparams *) (&cmd->wmm_params[ac]); 5311 twmm_param = (struct wmi_host_wme_vparams *) (&wmm_vparams[ac]); 5312 WMITLV_SET_HDR(&wmm_param->tlv_header, 5313 WMITLV_TAG_STRUC_wmi_vdev_set_wmm_params_cmd_fixed_param, 5314 WMITLV_GET_STRUCT_TLVLEN(wmi_wmm_vparams)); 5315 wmm_param->cwmin = twmm_param->cwmin; 5316 wmm_param->cwmax = twmm_param->cwmax; 5317 wmm_param->aifs = twmm_param->aifs; 5318 if (mu_edca_param) 5319 wmm_param->mu_edca_timer = twmm_param->mu_edca_timer; 5320 else 5321 wmm_param->txoplimit = twmm_param->txoplimit; 5322 wmm_param->acm = twmm_param->acm; 5323 wmm_param->no_ack = twmm_param->noackpolicy; 5324 } 5325 5326 wmi_mtrace(WMI_VDEV_SET_WMM_PARAMS_CMDID, cmd->vdev_id, 0); 5327 if (wmi_unified_cmd_send(wmi_handle, buf, len, 5328 WMI_VDEV_SET_WMM_PARAMS_CMDID)) 5329 goto fail; 5330 5331 return QDF_STATUS_SUCCESS; 5332 5333 fail: 5334 wmi_buf_free(buf); 5335 wmi_err("Failed to set WMM Parameters"); 5336 return QDF_STATUS_E_FAILURE; 5337 } 5338 5339 static WMI_EDCA_PARAM_TYPE 5340 wmi_convert_edca_pifs_param_type(enum host_edca_param_type type) 5341 { 5342 switch (type) { 5343 case HOST_EDCA_PARAM_TYPE_AGGRESSIVE: 5344 return WMI_EDCA_PARAM_TYPE_AGGRESSIVE; 5345 case HOST_EDCA_PARAM_TYPE_PIFS: 5346 return WMI_EDCA_PARAM_TYPE_PIFS; 5347 default: 5348 return WMI_EDCA_PARAM_TYPE_AGGRESSIVE; 5349 } 5350 } 5351 5352 /** 5353 * send_update_edca_pifs_param_cmd_tlv() - update EDCA params 5354 * @wmi_handle: wmi handle 5355 * @edca_pifs: edca/pifs parameters 5356 * 5357 * This function updates EDCA/PIFS parameters to the target 5358 * 5359 * Return: QDF Status 5360 */ 5361 5362 static QDF_STATUS 5363 send_update_edca_pifs_param_cmd_tlv(wmi_unified_t wmi_handle, 5364 struct edca_pifs_vparam *edca_pifs) 5365 { 5366 uint8_t *buf_ptr; 5367 wmi_buf_t buf = NULL; 5368 wmi_vdev_set_twt_edca_params_cmd_fixed_param *cmd; 5369 wmi_wmm_params *wmm_params; 5370 wmi_pifs_params *pifs_params; 5371 uint16_t len; 5372 5373 if (!edca_pifs) { 5374 wmi_debug("edca_pifs is NULL"); 5375 return QDF_STATUS_E_FAILURE; 5376 } 5377 5378 len = sizeof(wmi_vdev_set_twt_edca_params_cmd_fixed_param); 5379 if (edca_pifs->param.edca_param_type == 5380 HOST_EDCA_PARAM_TYPE_AGGRESSIVE) { 5381 len += WMI_TLV_HDR_SIZE; 5382 len += sizeof(wmi_wmm_params); 5383 } else { 5384 len += WMI_TLV_HDR_SIZE; 5385 } 5386 if (edca_pifs->param.edca_param_type == 5387 HOST_EDCA_PARAM_TYPE_PIFS) { 5388 len += WMI_TLV_HDR_SIZE; 5389 len += sizeof(wmi_pifs_params); 5390 } else { 5391 len += WMI_TLV_HDR_SIZE; 5392 } 5393 5394 buf = wmi_buf_alloc(wmi_handle, len); 5395 5396 if (!buf) 5397 return QDF_STATUS_E_NOMEM; 5398 5399 cmd = (wmi_vdev_set_twt_edca_params_cmd_fixed_param *)wmi_buf_data(buf); 5400 buf_ptr = (uint8_t *)cmd; 5401 5402 WMITLV_SET_HDR(&cmd->tlv_header, 5403 WMITLV_TAG_STRUC_wmi_vdev_set_twt_edca_params_cmd_fixed_param, 5404 WMITLV_GET_STRUCT_TLVLEN 5405 (wmi_vdev_set_twt_edca_params_cmd_fixed_param)); 5406 5407 cmd->vdev_id = edca_pifs->vdev_id; 5408 cmd->type = wmi_convert_edca_pifs_param_type( 5409 edca_pifs->param.edca_param_type); 5410 buf_ptr += sizeof(wmi_vdev_set_twt_edca_params_cmd_fixed_param); 5411 5412 if (cmd->type == WMI_EDCA_PARAM_TYPE_AGGRESSIVE) { 5413 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 5414 sizeof(*wmm_params)); 5415 buf_ptr += WMI_TLV_HDR_SIZE; 5416 wmm_params = (wmi_wmm_params *)buf_ptr; 5417 WMITLV_SET_HDR(&wmm_params->tlv_header, 5418 WMITLV_TAG_STRUC_wmi_wmm_params, 5419 WMITLV_GET_STRUCT_TLVLEN(wmi_wmm_params)); 5420 5421 wmm_params->cwmin = 5422 BIT(edca_pifs->param.edca_pifs_param.eparam.acvo_cwmin) - 1; 5423 wmm_params->cwmax = 5424 BIT(edca_pifs->param.edca_pifs_param.eparam.acvo_cwmax) - 1; 5425 wmm_params->aifs = 5426 edca_pifs->param.edca_pifs_param.eparam.acvo_aifsn - 1; 5427 wmm_params->txoplimit = 5428 edca_pifs->param.edca_pifs_param.eparam.acvo_txoplimit; 5429 wmm_params->acm = 5430 edca_pifs->param.edca_pifs_param.eparam.acvo_acm; 5431 wmm_params->no_ack = 0; 5432 wmi_debug("vdev_id %d type %d cwmin %d cwmax %d aifsn %d txoplimit %d acm %d no_ack %d", 5433 cmd->vdev_id, cmd->type, wmm_params->cwmin, 5434 wmm_params->cwmax, wmm_params->aifs, 5435 wmm_params->txoplimit, wmm_params->acm, 5436 wmm_params->no_ack); 5437 buf_ptr += sizeof(*wmm_params); 5438 } else { 5439 /* set zero TLV's for wmm_params */ 5440 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 5441 WMITLV_GET_STRUCT_TLVLEN(0)); 5442 buf_ptr += WMI_TLV_HDR_SIZE; 5443 } 5444 if (cmd->type == WMI_EDCA_PARAM_TYPE_PIFS) { 5445 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 5446 sizeof(*pifs_params)); 5447 buf_ptr += WMI_TLV_HDR_SIZE; 5448 pifs_params = (wmi_pifs_params *)buf_ptr; 5449 WMITLV_SET_HDR(&pifs_params->tlv_header, 5450 WMITLV_TAG_STRUC_wmi_pifs_params, 5451 WMITLV_GET_STRUCT_TLVLEN(wmi_pifs_params)); 5452 5453 pifs_params->sap_pifs_offset = 5454 edca_pifs->param.edca_pifs_param.pparam.sap_pifs_offset; 5455 pifs_params->leb_pifs_offset = 5456 edca_pifs->param.edca_pifs_param.pparam.leb_pifs_offset; 5457 pifs_params->reb_pifs_offset = 5458 edca_pifs->param.edca_pifs_param.pparam.reb_pifs_offset; 5459 wmi_debug("vdev_id %d type %d sap_offset %d leb_offset %d reb_offset %d", 5460 cmd->vdev_id, cmd->type, pifs_params->sap_pifs_offset, 5461 pifs_params->leb_pifs_offset, 5462 pifs_params->reb_pifs_offset); 5463 } else { 5464 /* set zero TLV's for pifs_params */ 5465 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 5466 WMITLV_GET_STRUCT_TLVLEN(0)); 5467 buf_ptr += WMI_TLV_HDR_SIZE; 5468 } 5469 5470 wmi_mtrace(WMI_VDEV_SET_TWT_EDCA_PARAMS_CMDID, cmd->vdev_id, 0); 5471 if (wmi_unified_cmd_send(wmi_handle, buf, len, 5472 WMI_VDEV_SET_TWT_EDCA_PARAMS_CMDID)) 5473 goto fail; 5474 5475 return QDF_STATUS_SUCCESS; 5476 5477 fail: 5478 wmi_buf_free(buf); 5479 wmi_err("Failed to set EDCA/PIFS Parameters"); 5480 return QDF_STATUS_E_FAILURE; 5481 } 5482 5483 /** 5484 * send_probe_rsp_tmpl_send_cmd_tlv() - send probe response template to fw 5485 * @wmi_handle: wmi handle 5486 * @vdev_id: vdev id 5487 * @probe_rsp_info: probe response info 5488 * 5489 * Return: QDF_STATUS_SUCCESS for success or error code 5490 */ 5491 static QDF_STATUS send_probe_rsp_tmpl_send_cmd_tlv(wmi_unified_t wmi_handle, 5492 uint8_t vdev_id, 5493 struct wmi_probe_resp_params *probe_rsp_info) 5494 { 5495 wmi_prb_tmpl_cmd_fixed_param *cmd; 5496 wmi_bcn_prb_info *bcn_prb_info; 5497 wmi_buf_t wmi_buf; 5498 uint32_t tmpl_len, tmpl_len_aligned, wmi_buf_len; 5499 uint8_t *buf_ptr; 5500 QDF_STATUS ret; 5501 5502 wmi_debug("Send probe response template for vdev %d", vdev_id); 5503 5504 tmpl_len = probe_rsp_info->prb_rsp_template_len; 5505 tmpl_len_aligned = roundup(tmpl_len, sizeof(uint32_t)); 5506 5507 wmi_buf_len = sizeof(wmi_prb_tmpl_cmd_fixed_param) + 5508 sizeof(wmi_bcn_prb_info) + WMI_TLV_HDR_SIZE + 5509 tmpl_len_aligned + 5510 prb_resp_tmpl_ml_info_size(probe_rsp_info); 5511 5512 if (wmi_buf_len > WMI_BEACON_TX_BUFFER_SIZE) { 5513 wmi_err("wmi_buf_len: %d > %d. Can't send wmi cmd", 5514 wmi_buf_len, WMI_BEACON_TX_BUFFER_SIZE); 5515 return QDF_STATUS_E_INVAL; 5516 } 5517 5518 wmi_buf = wmi_buf_alloc(wmi_handle, wmi_buf_len); 5519 if (!wmi_buf) 5520 return QDF_STATUS_E_NOMEM; 5521 5522 buf_ptr = (uint8_t *) wmi_buf_data(wmi_buf); 5523 5524 cmd = (wmi_prb_tmpl_cmd_fixed_param *) buf_ptr; 5525 WMITLV_SET_HDR(&cmd->tlv_header, 5526 WMITLV_TAG_STRUC_wmi_prb_tmpl_cmd_fixed_param, 5527 WMITLV_GET_STRUCT_TLVLEN(wmi_prb_tmpl_cmd_fixed_param)); 5528 cmd->vdev_id = vdev_id; 5529 cmd->buf_len = tmpl_len; 5530 buf_ptr += sizeof(wmi_prb_tmpl_cmd_fixed_param); 5531 5532 bcn_prb_info = (wmi_bcn_prb_info *) buf_ptr; 5533 WMITLV_SET_HDR(&bcn_prb_info->tlv_header, 5534 WMITLV_TAG_STRUC_wmi_bcn_prb_info, 5535 WMITLV_GET_STRUCT_TLVLEN(wmi_bcn_prb_info)); 5536 bcn_prb_info->caps = 0; 5537 bcn_prb_info->erp = 0; 5538 buf_ptr += sizeof(wmi_bcn_prb_info); 5539 5540 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, tmpl_len_aligned); 5541 buf_ptr += WMI_TLV_HDR_SIZE; 5542 qdf_mem_copy(buf_ptr, probe_rsp_info->prb_rsp_template_frm, tmpl_len); 5543 buf_ptr += tmpl_len_aligned; 5544 buf_ptr = prb_resp_tmpl_add_ml_info(buf_ptr, probe_rsp_info); 5545 5546 wmi_mtrace(WMI_PRB_TMPL_CMDID, cmd->vdev_id, 0); 5547 ret = wmi_unified_cmd_send(wmi_handle, 5548 wmi_buf, wmi_buf_len, WMI_PRB_TMPL_CMDID); 5549 if (QDF_IS_STATUS_ERROR(ret)) { 5550 wmi_err("Failed to send PRB RSP tmpl: %d", ret); 5551 wmi_buf_free(wmi_buf); 5552 } 5553 5554 return ret; 5555 } 5556 5557 #if defined(ATH_SUPPORT_WAPI) || defined(FEATURE_WLAN_WAPI) 5558 #define WPI_IV_LEN 16 5559 5560 /** 5561 * wmi_update_wpi_key_counter() - update WAPI tsc and rsc key counters 5562 * 5563 * @dest_tx: destination address of tsc key counter 5564 * @src_tx: source address of tsc key counter 5565 * @dest_rx: destination address of rsc key counter 5566 * @src_rx: source address of rsc key counter 5567 * 5568 * This function copies WAPI tsc and rsc key counters in the wmi buffer. 5569 * 5570 * Return: None 5571 * 5572 */ 5573 static void wmi_update_wpi_key_counter(uint8_t *dest_tx, uint8_t *src_tx, 5574 uint8_t *dest_rx, uint8_t *src_rx) 5575 { 5576 qdf_mem_copy(dest_tx, src_tx, WPI_IV_LEN); 5577 qdf_mem_copy(dest_rx, src_rx, WPI_IV_LEN); 5578 } 5579 #else 5580 static void wmi_update_wpi_key_counter(uint8_t *dest_tx, uint8_t *src_tx, 5581 uint8_t *dest_rx, uint8_t *src_rx) 5582 { 5583 return; 5584 } 5585 #endif 5586 5587 /** 5588 * send_setup_install_key_cmd_tlv() - set key parameters 5589 * @wmi_handle: wmi handle 5590 * @key_params: key parameters 5591 * 5592 * This function fills structure from information 5593 * passed in key_params. 5594 * 5595 * Return: QDF_STATUS_SUCCESS - success 5596 * QDF_STATUS_E_FAILURE - failure 5597 * QDF_STATUS_E_NOMEM - not able to allocate buffer 5598 */ 5599 static QDF_STATUS send_setup_install_key_cmd_tlv(wmi_unified_t wmi_handle, 5600 struct set_key_params *key_params) 5601 { 5602 wmi_vdev_install_key_cmd_fixed_param *cmd; 5603 wmi_buf_t buf; 5604 uint8_t *buf_ptr; 5605 uint32_t len; 5606 uint8_t *key_data; 5607 QDF_STATUS status; 5608 5609 len = sizeof(*cmd) + roundup(key_params->key_len, sizeof(uint32_t)) + 5610 WMI_TLV_HDR_SIZE; 5611 5612 buf = wmi_buf_alloc(wmi_handle, len); 5613 if (!buf) 5614 return QDF_STATUS_E_NOMEM; 5615 5616 buf_ptr = (uint8_t *) wmi_buf_data(buf); 5617 cmd = (wmi_vdev_install_key_cmd_fixed_param *) buf_ptr; 5618 WMITLV_SET_HDR(&cmd->tlv_header, 5619 WMITLV_TAG_STRUC_wmi_vdev_install_key_cmd_fixed_param, 5620 WMITLV_GET_STRUCT_TLVLEN 5621 (wmi_vdev_install_key_cmd_fixed_param)); 5622 cmd->vdev_id = key_params->vdev_id; 5623 cmd->key_ix = key_params->key_idx; 5624 if (key_params->group_key_idx) { 5625 cmd->is_group_key_ix_valid = 1; 5626 cmd->group_key_ix = key_params->group_key_idx; 5627 } 5628 5629 WMI_CHAR_ARRAY_TO_MAC_ADDR(key_params->peer_mac, &cmd->peer_macaddr); 5630 cmd->key_flags |= key_params->key_flags; 5631 cmd->key_cipher = key_params->key_cipher; 5632 if ((key_params->key_txmic_len) && 5633 (key_params->key_rxmic_len)) { 5634 cmd->key_txmic_len = key_params->key_txmic_len; 5635 cmd->key_rxmic_len = key_params->key_rxmic_len; 5636 } 5637 #if defined(ATH_SUPPORT_WAPI) || defined(FEATURE_WLAN_WAPI) 5638 wmi_update_wpi_key_counter(cmd->wpi_key_tsc_counter, 5639 key_params->tx_iv, 5640 cmd->wpi_key_rsc_counter, 5641 key_params->rx_iv); 5642 #endif 5643 buf_ptr += sizeof(wmi_vdev_install_key_cmd_fixed_param); 5644 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, 5645 roundup(key_params->key_len, sizeof(uint32_t))); 5646 key_data = (uint8_t *) (buf_ptr + WMI_TLV_HDR_SIZE); 5647 5648 /* for big endian host, copy engine byte_swap is enabled 5649 * But key_data is in network byte order 5650 * Need to byte swap the key_data - so when copy engine 5651 * does byte_swap - target gets key_data in the correct order 5652 */ 5653 WMI_HOST_IF_MSG_COPY_CHAR_ARRAY((void *)key_data, 5654 (const void *)key_params->key_data, 5655 key_params->key_len); 5656 qdf_mem_copy(&cmd->key_rsc_counter, &key_params->key_rsc_counter, 5657 sizeof(wmi_key_seq_counter)); 5658 cmd->key_len = key_params->key_len; 5659 5660 qdf_mem_copy(&cmd->key_tsc_counter, &key_params->key_tsc_counter, 5661 sizeof(wmi_key_seq_counter)); 5662 wmi_mtrace(WMI_VDEV_INSTALL_KEY_CMDID, cmd->vdev_id, 0); 5663 status = wmi_unified_cmd_send(wmi_handle, buf, len, 5664 WMI_VDEV_INSTALL_KEY_CMDID); 5665 if (QDF_IS_STATUS_ERROR(status)) { 5666 qdf_mem_zero(wmi_buf_data(buf), len); 5667 wmi_buf_free(buf); 5668 } 5669 return status; 5670 } 5671 5672 /** 5673 * send_p2p_go_set_beacon_ie_cmd_tlv() - set beacon IE for p2p go 5674 * @wmi_handle: wmi handle 5675 * @vdev_id: vdev id 5676 * @p2p_ie: p2p IE 5677 * 5678 * Return: QDF_STATUS_SUCCESS for success or error code 5679 */ 5680 static QDF_STATUS send_p2p_go_set_beacon_ie_cmd_tlv(wmi_unified_t wmi_handle, 5681 uint32_t vdev_id, uint8_t *p2p_ie) 5682 { 5683 QDF_STATUS ret; 5684 wmi_p2p_go_set_beacon_ie_fixed_param *cmd; 5685 wmi_buf_t wmi_buf; 5686 uint32_t ie_len, ie_len_aligned, wmi_buf_len; 5687 uint8_t *buf_ptr; 5688 5689 ie_len = (uint32_t) (p2p_ie[1] + 2); 5690 5691 /* More than one P2P IE may be included in a single frame. 5692 If multiple P2P IEs are present, the complete P2P attribute 5693 data consists of the concatenation of the P2P Attribute 5694 fields of the P2P IEs. The P2P Attributes field of each 5695 P2P IE may be any length up to the maximum (251 octets). 5696 In this case host sends one P2P IE to firmware so the length 5697 should not exceed more than 251 bytes 5698 */ 5699 if (ie_len > 251) { 5700 wmi_err("Invalid p2p ie length %u", ie_len); 5701 return QDF_STATUS_E_INVAL; 5702 } 5703 5704 ie_len_aligned = roundup(ie_len, sizeof(uint32_t)); 5705 5706 wmi_buf_len = 5707 sizeof(wmi_p2p_go_set_beacon_ie_fixed_param) + ie_len_aligned + 5708 WMI_TLV_HDR_SIZE; 5709 5710 wmi_buf = wmi_buf_alloc(wmi_handle, wmi_buf_len); 5711 if (!wmi_buf) 5712 return QDF_STATUS_E_NOMEM; 5713 5714 buf_ptr = (uint8_t *) wmi_buf_data(wmi_buf); 5715 5716 cmd = (wmi_p2p_go_set_beacon_ie_fixed_param *) buf_ptr; 5717 WMITLV_SET_HDR(&cmd->tlv_header, 5718 WMITLV_TAG_STRUC_wmi_p2p_go_set_beacon_ie_fixed_param, 5719 WMITLV_GET_STRUCT_TLVLEN 5720 (wmi_p2p_go_set_beacon_ie_fixed_param)); 5721 cmd->vdev_id = vdev_id; 5722 cmd->ie_buf_len = ie_len; 5723 5724 buf_ptr += sizeof(wmi_p2p_go_set_beacon_ie_fixed_param); 5725 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, ie_len_aligned); 5726 buf_ptr += WMI_TLV_HDR_SIZE; 5727 qdf_mem_copy(buf_ptr, p2p_ie, ie_len); 5728 5729 wmi_debug("Sending WMI_P2P_GO_SET_BEACON_IE"); 5730 5731 wmi_mtrace(WMI_P2P_GO_SET_BEACON_IE, cmd->vdev_id, 0); 5732 ret = wmi_unified_cmd_send(wmi_handle, 5733 wmi_buf, wmi_buf_len, 5734 WMI_P2P_GO_SET_BEACON_IE); 5735 if (QDF_IS_STATUS_ERROR(ret)) { 5736 wmi_err("Failed to send bcn tmpl: %d", ret); 5737 wmi_buf_free(wmi_buf); 5738 } 5739 5740 wmi_debug("Successfully sent WMI_P2P_GO_SET_BEACON_IE"); 5741 return ret; 5742 } 5743 5744 /** 5745 * send_scan_probe_setoui_cmd_tlv() - set scan probe OUI 5746 * @wmi_handle: wmi handle 5747 * @psetoui: OUI parameters 5748 * 5749 * set scan probe OUI parameters in firmware 5750 * 5751 * Return: QDF status 5752 */ 5753 static QDF_STATUS send_scan_probe_setoui_cmd_tlv(wmi_unified_t wmi_handle, 5754 struct scan_mac_oui *psetoui) 5755 { 5756 wmi_scan_prob_req_oui_cmd_fixed_param *cmd; 5757 wmi_buf_t wmi_buf; 5758 uint32_t len; 5759 uint8_t *buf_ptr; 5760 uint32_t *oui_buf; 5761 struct probe_req_allowlist_attr *ie_allowlist = &psetoui->ie_allowlist; 5762 5763 len = sizeof(*cmd) + WMI_TLV_HDR_SIZE + 5764 ie_allowlist->num_vendor_oui * sizeof(wmi_vendor_oui); 5765 5766 wmi_buf = wmi_buf_alloc(wmi_handle, len); 5767 if (!wmi_buf) 5768 return QDF_STATUS_E_NOMEM; 5769 5770 buf_ptr = (uint8_t *) wmi_buf_data(wmi_buf); 5771 cmd = (wmi_scan_prob_req_oui_cmd_fixed_param *) buf_ptr; 5772 WMITLV_SET_HDR(&cmd->tlv_header, 5773 WMITLV_TAG_STRUC_wmi_scan_prob_req_oui_cmd_fixed_param, 5774 WMITLV_GET_STRUCT_TLVLEN 5775 (wmi_scan_prob_req_oui_cmd_fixed_param)); 5776 5777 oui_buf = &cmd->prob_req_oui; 5778 qdf_mem_zero(oui_buf, sizeof(cmd->prob_req_oui)); 5779 *oui_buf = psetoui->oui[0] << 16 | psetoui->oui[1] << 8 5780 | psetoui->oui[2]; 5781 wmi_debug("wmi:oui received from hdd %08x", cmd->prob_req_oui); 5782 5783 cmd->vdev_id = psetoui->vdev_id; 5784 cmd->flags = WMI_SCAN_PROBE_OUI_SPOOFED_MAC_IN_PROBE_REQ; 5785 if (psetoui->enb_probe_req_sno_randomization) 5786 cmd->flags |= WMI_SCAN_PROBE_OUI_RANDOM_SEQ_NO_IN_PROBE_REQ; 5787 5788 if (ie_allowlist->allow_list) { 5789 wmi_fill_ie_allowlist_attrs(cmd->ie_bitmap, 5790 &cmd->num_vendor_oui, 5791 ie_allowlist); 5792 cmd->flags |= 5793 WMI_SCAN_PROBE_OUI_ENABLE_IE_WHITELIST_IN_PROBE_REQ; 5794 } 5795 5796 buf_ptr += sizeof(*cmd); 5797 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 5798 ie_allowlist->num_vendor_oui * sizeof(wmi_vendor_oui)); 5799 buf_ptr += WMI_TLV_HDR_SIZE; 5800 5801 if (cmd->num_vendor_oui != 0) { 5802 wmi_fill_vendor_oui(buf_ptr, cmd->num_vendor_oui, 5803 ie_allowlist->voui); 5804 buf_ptr += cmd->num_vendor_oui * sizeof(wmi_vendor_oui); 5805 } 5806 5807 wmi_mtrace(WMI_SCAN_PROB_REQ_OUI_CMDID, cmd->vdev_id, 0); 5808 if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len, 5809 WMI_SCAN_PROB_REQ_OUI_CMDID)) { 5810 wmi_err("Failed to send command WMI_SCAN_PROB_REQ_OUI_CMDID"); 5811 wmi_buf_free(wmi_buf); 5812 return QDF_STATUS_E_FAILURE; 5813 } 5814 return QDF_STATUS_SUCCESS; 5815 } 5816 5817 #ifdef IPA_OFFLOAD 5818 /** send_ipa_offload_control_cmd_tlv() - ipa offload control parameter 5819 * @wmi_handle: wmi handle 5820 * @ipa_offload: ipa offload control parameter 5821 * 5822 * Returns: 0 on success, error number otherwise 5823 */ 5824 static QDF_STATUS send_ipa_offload_control_cmd_tlv(wmi_unified_t wmi_handle, 5825 struct ipa_uc_offload_control_params *ipa_offload) 5826 { 5827 wmi_ipa_offload_enable_disable_cmd_fixed_param *cmd; 5828 wmi_buf_t wmi_buf; 5829 uint32_t len; 5830 u_int8_t *buf_ptr; 5831 5832 len = sizeof(*cmd); 5833 wmi_buf = wmi_buf_alloc(wmi_handle, len); 5834 if (!wmi_buf) 5835 return QDF_STATUS_E_NOMEM; 5836 5837 wmi_debug("offload_type=%d, enable=%d", 5838 ipa_offload->offload_type, ipa_offload->enable); 5839 5840 buf_ptr = (u_int8_t *)wmi_buf_data(wmi_buf); 5841 5842 cmd = (wmi_ipa_offload_enable_disable_cmd_fixed_param *)buf_ptr; 5843 WMITLV_SET_HDR(&cmd->tlv_header, 5844 WMITLV_TAG_STRUCT_wmi_ipa_offload_enable_disable_cmd_fixed_param, 5845 WMITLV_GET_STRUCT_TLVLEN( 5846 wmi_ipa_offload_enable_disable_cmd_fixed_param)); 5847 5848 cmd->offload_type = ipa_offload->offload_type; 5849 cmd->vdev_id = ipa_offload->vdev_id; 5850 cmd->enable = ipa_offload->enable; 5851 5852 wmi_mtrace(WMI_IPA_OFFLOAD_ENABLE_DISABLE_CMDID, cmd->vdev_id, 0); 5853 if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len, 5854 WMI_IPA_OFFLOAD_ENABLE_DISABLE_CMDID)) { 5855 wmi_err("Failed to send WMI_IPA_OFFLOAD_ENABLE_DISABLE_CMDID"); 5856 wmi_buf_free(wmi_buf); 5857 return QDF_STATUS_E_FAILURE; 5858 } 5859 5860 return QDF_STATUS_SUCCESS; 5861 } 5862 #endif 5863 5864 /** 5865 * send_pno_stop_cmd_tlv() - PNO stop request 5866 * @wmi_handle: wmi handle 5867 * @vdev_id: vdev id 5868 * 5869 * This function request FW to stop ongoing PNO operation. 5870 * 5871 * Return: QDF status 5872 */ 5873 static QDF_STATUS send_pno_stop_cmd_tlv(wmi_unified_t wmi_handle, uint8_t vdev_id) 5874 { 5875 wmi_nlo_config_cmd_fixed_param *cmd; 5876 int32_t len = sizeof(*cmd); 5877 wmi_buf_t buf; 5878 uint8_t *buf_ptr; 5879 int ret; 5880 5881 /* 5882 * TLV place holder for array of structures nlo_configured_parameters 5883 * TLV place holder for array of uint32_t channel_list 5884 * TLV place holder for chnl prediction cfg 5885 */ 5886 len += WMI_TLV_HDR_SIZE + WMI_TLV_HDR_SIZE + WMI_TLV_HDR_SIZE; 5887 buf = wmi_buf_alloc(wmi_handle, len); 5888 if (!buf) 5889 return QDF_STATUS_E_NOMEM; 5890 5891 cmd = (wmi_nlo_config_cmd_fixed_param *) wmi_buf_data(buf); 5892 buf_ptr = (uint8_t *) cmd; 5893 5894 WMITLV_SET_HDR(&cmd->tlv_header, 5895 WMITLV_TAG_STRUC_wmi_nlo_config_cmd_fixed_param, 5896 WMITLV_GET_STRUCT_TLVLEN 5897 (wmi_nlo_config_cmd_fixed_param)); 5898 5899 cmd->vdev_id = vdev_id; 5900 cmd->flags = WMI_NLO_CONFIG_STOP; 5901 buf_ptr += sizeof(*cmd); 5902 5903 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0); 5904 buf_ptr += WMI_TLV_HDR_SIZE; 5905 5906 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, 0); 5907 buf_ptr += WMI_TLV_HDR_SIZE; 5908 5909 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0); 5910 buf_ptr += WMI_TLV_HDR_SIZE; 5911 5912 wmi_mtrace(WMI_NETWORK_LIST_OFFLOAD_CONFIG_CMDID, cmd->vdev_id, 0); 5913 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 5914 WMI_NETWORK_LIST_OFFLOAD_CONFIG_CMDID); 5915 if (ret) { 5916 wmi_err("Failed to send nlo wmi cmd"); 5917 wmi_buf_free(buf); 5918 return QDF_STATUS_E_FAILURE; 5919 } 5920 5921 return QDF_STATUS_SUCCESS; 5922 } 5923 5924 /** 5925 * send_obss_disable_cmd_tlv() - disable obss scan request 5926 * @wmi_handle: wmi handle 5927 * @vdev_id: vdev id 5928 * 5929 * This function request FW to disable ongoing obss scan operation. 5930 * 5931 * Return: QDF status 5932 */ 5933 static QDF_STATUS send_obss_disable_cmd_tlv(wmi_unified_t wmi_handle, 5934 uint8_t vdev_id) 5935 { 5936 QDF_STATUS status; 5937 wmi_buf_t buf; 5938 wmi_obss_scan_disable_cmd_fixed_param *cmd; 5939 int len = sizeof(*cmd); 5940 5941 buf = wmi_buf_alloc(wmi_handle, len); 5942 if (!buf) 5943 return QDF_STATUS_E_NOMEM; 5944 5945 wmi_debug("cmd %x vdev_id %d", WMI_OBSS_SCAN_DISABLE_CMDID, vdev_id); 5946 5947 cmd = (wmi_obss_scan_disable_cmd_fixed_param *)wmi_buf_data(buf); 5948 WMITLV_SET_HDR(&cmd->tlv_header, 5949 WMITLV_TAG_STRUC_wmi_obss_scan_disable_cmd_fixed_param, 5950 WMITLV_GET_STRUCT_TLVLEN( 5951 wmi_obss_scan_disable_cmd_fixed_param)); 5952 5953 cmd->vdev_id = vdev_id; 5954 status = wmi_unified_cmd_send(wmi_handle, buf, len, 5955 WMI_OBSS_SCAN_DISABLE_CMDID); 5956 if (QDF_IS_STATUS_ERROR(status)) 5957 wmi_buf_free(buf); 5958 5959 return status; 5960 } 5961 5962 /** 5963 * wmi_set_pno_channel_prediction() - Set PNO channel prediction 5964 * @buf_ptr: Buffer passed by upper layers 5965 * @pno: Buffer to be sent to the firmware 5966 * 5967 * Copy the PNO Channel prediction configuration parameters 5968 * passed by the upper layers to a WMI format TLV and send it 5969 * down to the firmware. 5970 * 5971 * Return: None 5972 */ 5973 static void wmi_set_pno_channel_prediction(uint8_t *buf_ptr, 5974 struct pno_scan_req_params *pno) 5975 { 5976 nlo_channel_prediction_cfg *channel_prediction_cfg = 5977 (nlo_channel_prediction_cfg *) buf_ptr; 5978 WMITLV_SET_HDR(&channel_prediction_cfg->tlv_header, 5979 WMITLV_TAG_ARRAY_BYTE, 5980 WMITLV_GET_STRUCT_TLVLEN(nlo_channel_prediction_cfg)); 5981 #ifdef FEATURE_WLAN_SCAN_PNO 5982 channel_prediction_cfg->enable = pno->pno_channel_prediction; 5983 channel_prediction_cfg->top_k_num = pno->top_k_num_of_channels; 5984 channel_prediction_cfg->stationary_threshold = pno->stationary_thresh; 5985 channel_prediction_cfg->full_scan_period_ms = 5986 pno->channel_prediction_full_scan; 5987 #endif 5988 buf_ptr += sizeof(nlo_channel_prediction_cfg); 5989 wmi_debug("enable: %d, top_k_num: %d, stat_thresh: %d, full_scan: %d", 5990 channel_prediction_cfg->enable, 5991 channel_prediction_cfg->top_k_num, 5992 channel_prediction_cfg->stationary_threshold, 5993 channel_prediction_cfg->full_scan_period_ms); 5994 } 5995 5996 /** 5997 * send_cp_stats_cmd_tlv() - Send cp stats wmi command 5998 * @wmi_handle: wmi handle 5999 * @buf_ptr: Buffer passed by upper layers 6000 * @buf_len: Length of passed buffer by upper layer 6001 * 6002 * Copy the buffer passed by the upper layers and send it 6003 * down to the firmware. 6004 * 6005 * Return: None 6006 */ 6007 static QDF_STATUS send_cp_stats_cmd_tlv(wmi_unified_t wmi_handle, 6008 void *buf_ptr, uint32_t buf_len) 6009 { 6010 wmi_buf_t buf = NULL; 6011 QDF_STATUS status; 6012 int len; 6013 uint8_t *data_ptr; 6014 6015 len = buf_len; 6016 buf = wmi_buf_alloc(wmi_handle, len); 6017 if (!buf) 6018 return QDF_STATUS_E_NOMEM; 6019 6020 data_ptr = (uint8_t *)wmi_buf_data(buf); 6021 qdf_mem_copy(data_ptr, buf_ptr, len); 6022 6023 wmi_mtrace(WMI_REQUEST_CTRL_PATH_STATS_CMDID, NO_SESSION, 0); 6024 status = wmi_unified_cmd_send(wmi_handle, buf, 6025 len, WMI_REQUEST_CTRL_PATH_STATS_CMDID); 6026 6027 if (QDF_IS_STATUS_ERROR(status)) { 6028 wmi_buf_free(buf); 6029 return QDF_STATUS_E_FAILURE; 6030 } 6031 return QDF_STATUS_SUCCESS; 6032 } 6033 6034 /** 6035 * send_halphy_stats_cmd_tlv() - Send halphy stats wmi command 6036 * @wmi_handle: wmi handle 6037 * @buf_ptr: Buffer passed by upper layers 6038 * @buf_len: Length of passed buffer by upper layer 6039 * 6040 * Copy the buffer passed by the upper layers and send it 6041 * down to the firmware. 6042 * 6043 * Return: None 6044 */ 6045 static QDF_STATUS send_halphy_stats_cmd_tlv(wmi_unified_t wmi_handle, 6046 void *buf_ptr, uint32_t buf_len) 6047 { 6048 wmi_buf_t buf = NULL; 6049 QDF_STATUS status; 6050 int len; 6051 uint8_t *data_ptr; 6052 6053 len = buf_len; 6054 buf = wmi_buf_alloc(wmi_handle, len); 6055 if (!buf) 6056 return QDF_STATUS_E_NOMEM; 6057 6058 data_ptr = (uint8_t *)wmi_buf_data(buf); 6059 qdf_mem_copy(data_ptr, buf_ptr, len); 6060 6061 wmi_mtrace(WMI_REQUEST_HALPHY_CTRL_PATH_STATS_CMDID, NO_SESSION, 0); 6062 status = wmi_unified_cmd_send(wmi_handle, buf, 6063 len, 6064 WMI_REQUEST_HALPHY_CTRL_PATH_STATS_CMDID); 6065 6066 if (QDF_IS_STATUS_ERROR(status)) { 6067 wmi_buf_free(buf); 6068 return QDF_STATUS_E_FAILURE; 6069 } 6070 return QDF_STATUS_SUCCESS; 6071 } 6072 6073 /** 6074 * extract_cp_stats_more_pending_tlv - api to extract more flag from event data 6075 * @wmi_handle: wmi handle 6076 * @evt_buf: event buffer 6077 * @more_flag: buffer to populate more flag 6078 * 6079 * Return: status of operation 6080 */ 6081 static QDF_STATUS 6082 extract_cp_stats_more_pending_tlv(wmi_unified_t wmi_handle, void *evt_buf, 6083 uint32_t *more_flag) 6084 { 6085 WMI_CTRL_PATH_STATS_EVENTID_param_tlvs *param_buf; 6086 wmi_ctrl_path_stats_event_fixed_param *ev; 6087 6088 param_buf = (WMI_CTRL_PATH_STATS_EVENTID_param_tlvs *)evt_buf; 6089 if (!param_buf) { 6090 wmi_err_rl("param_buf is NULL"); 6091 return QDF_STATUS_E_FAILURE; 6092 } 6093 ev = (wmi_ctrl_path_stats_event_fixed_param *)param_buf->fixed_param; 6094 6095 *more_flag = ev->more; 6096 return QDF_STATUS_SUCCESS; 6097 } 6098 6099 /** 6100 * extract_halphy_stats_end_of_event_tlv - api to extract end_of_event flag 6101 * from event data 6102 * @wmi_handle: wmi handle 6103 * @evt_buf: event buffer 6104 * @end_of_event_flag: buffer to populate end_of_event flag 6105 * 6106 * Return: status of operation 6107 */ 6108 static QDF_STATUS 6109 extract_halphy_stats_end_of_event_tlv(wmi_unified_t wmi_handle, void *evt_buf, 6110 uint32_t *end_of_event_flag) 6111 { 6112 WMI_HALPHY_CTRL_PATH_STATS_EVENTID_param_tlvs *param_buf; 6113 wmi_halphy_ctrl_path_stats_event_fixed_param *ev; 6114 6115 param_buf = (WMI_HALPHY_CTRL_PATH_STATS_EVENTID_param_tlvs *)evt_buf; 6116 if (!param_buf) { 6117 wmi_err_rl("param_buf is NULL"); 6118 return QDF_STATUS_E_FAILURE; 6119 } 6120 ev = (wmi_halphy_ctrl_path_stats_event_fixed_param *) 6121 param_buf->fixed_param; 6122 6123 *end_of_event_flag = ev->end_of_event; 6124 return QDF_STATUS_SUCCESS; 6125 } 6126 6127 /** 6128 * extract_halphy_stats_event_count_tlv() - api to extract event count flag 6129 * from event data 6130 * @wmi_handle: wmi handle 6131 * @evt_buf: event buffer 6132 * @event_count_flag: buffer to populate event_count flag 6133 * 6134 * Return: status of operation 6135 */ 6136 static QDF_STATUS 6137 extract_halphy_stats_event_count_tlv(wmi_unified_t wmi_handle, void *evt_buf, 6138 uint32_t *event_count_flag) 6139 { 6140 WMI_HALPHY_CTRL_PATH_STATS_EVENTID_param_tlvs *param_buf; 6141 wmi_halphy_ctrl_path_stats_event_fixed_param *ev; 6142 6143 param_buf = (WMI_HALPHY_CTRL_PATH_STATS_EVENTID_param_tlvs *)evt_buf; 6144 if (!param_buf) { 6145 wmi_err_rl("param_buf is NULL"); 6146 return QDF_STATUS_E_FAILURE; 6147 } 6148 ev = (wmi_halphy_ctrl_path_stats_event_fixed_param *) 6149 param_buf->fixed_param; 6150 6151 *event_count_flag = ev->event_count; 6152 return QDF_STATUS_SUCCESS; 6153 } 6154 6155 /** 6156 * send_nlo_mawc_cmd_tlv() - Send MAWC NLO configuration 6157 * @wmi_handle: wmi handle 6158 * @params: configuration parameters 6159 * 6160 * Return: QDF_STATUS 6161 */ 6162 static QDF_STATUS send_nlo_mawc_cmd_tlv(wmi_unified_t wmi_handle, 6163 struct nlo_mawc_params *params) 6164 { 6165 wmi_buf_t buf = NULL; 6166 QDF_STATUS status; 6167 int len; 6168 uint8_t *buf_ptr; 6169 wmi_nlo_configure_mawc_cmd_fixed_param *wmi_nlo_mawc_params; 6170 6171 len = sizeof(*wmi_nlo_mawc_params); 6172 buf = wmi_buf_alloc(wmi_handle, len); 6173 if (!buf) 6174 return QDF_STATUS_E_NOMEM; 6175 6176 buf_ptr = (uint8_t *) wmi_buf_data(buf); 6177 wmi_nlo_mawc_params = 6178 (wmi_nlo_configure_mawc_cmd_fixed_param *) buf_ptr; 6179 WMITLV_SET_HDR(&wmi_nlo_mawc_params->tlv_header, 6180 WMITLV_TAG_STRUC_wmi_nlo_configure_mawc_cmd_fixed_param, 6181 WMITLV_GET_STRUCT_TLVLEN 6182 (wmi_nlo_configure_mawc_cmd_fixed_param)); 6183 wmi_nlo_mawc_params->vdev_id = params->vdev_id; 6184 if (params->enable) 6185 wmi_nlo_mawc_params->enable = 1; 6186 else 6187 wmi_nlo_mawc_params->enable = 0; 6188 wmi_nlo_mawc_params->exp_backoff_ratio = params->exp_backoff_ratio; 6189 wmi_nlo_mawc_params->init_scan_interval = params->init_scan_interval; 6190 wmi_nlo_mawc_params->max_scan_interval = params->max_scan_interval; 6191 wmi_debug("MAWC NLO en=%d, vdev=%d, ratio=%d, SCAN init=%d, max=%d", 6192 wmi_nlo_mawc_params->enable, wmi_nlo_mawc_params->vdev_id, 6193 wmi_nlo_mawc_params->exp_backoff_ratio, 6194 wmi_nlo_mawc_params->init_scan_interval, 6195 wmi_nlo_mawc_params->max_scan_interval); 6196 6197 wmi_mtrace(WMI_NLO_CONFIGURE_MAWC_CMDID, NO_SESSION, 0); 6198 status = wmi_unified_cmd_send(wmi_handle, buf, 6199 len, WMI_NLO_CONFIGURE_MAWC_CMDID); 6200 if (QDF_IS_STATUS_ERROR(status)) { 6201 wmi_err("WMI_NLO_CONFIGURE_MAWC_CMDID failed, Error %d", 6202 status); 6203 wmi_buf_free(buf); 6204 return QDF_STATUS_E_FAILURE; 6205 } 6206 6207 return QDF_STATUS_SUCCESS; 6208 } 6209 6210 /** 6211 * wmi_dump_pno_scan_freq_list() - dump frequency list associated with pno 6212 * scan 6213 * @scan_freq_list: frequency list for pno scan 6214 * 6215 * Return: void 6216 */ 6217 static void wmi_dump_pno_scan_freq_list(struct chan_list *scan_freq_list) 6218 { 6219 uint32_t i; 6220 uint8_t info[WMI_MAX_CHAN_INFO_LOG]; 6221 uint32_t len = 0; 6222 struct chan_info *chan_info; 6223 int ret; 6224 6225 wmi_debug("[PNO_SCAN] Total freq %d", scan_freq_list->num_chan); 6226 for (i = 0; i < scan_freq_list->num_chan; i++) { 6227 chan_info = &scan_freq_list->chan[i]; 6228 ret = qdf_scnprintf(info + len, sizeof(info) - len, 6229 " %d[%d]", chan_info->freq, 6230 chan_info->flags); 6231 if (ret <= 0) 6232 break; 6233 len += ret; 6234 if (len >= (sizeof(info) - 20)) { 6235 wmi_nofl_debug("Freq[flag]:%s", 6236 info); 6237 len = 0; 6238 } 6239 } 6240 if (len) 6241 wmi_nofl_debug("Freq[flag]:%s", info); 6242 } 6243 6244 /** 6245 * send_pno_start_cmd_tlv() - PNO start request 6246 * @wmi_handle: wmi handle 6247 * @pno: PNO request 6248 * 6249 * This function request FW to start PNO request. 6250 * Request: QDF status 6251 */ 6252 static QDF_STATUS send_pno_start_cmd_tlv(wmi_unified_t wmi_handle, 6253 struct pno_scan_req_params *pno) 6254 { 6255 wmi_nlo_config_cmd_fixed_param *cmd; 6256 nlo_configured_parameters *nlo_list; 6257 uint32_t *channel_list; 6258 int32_t len; 6259 qdf_freq_t freq; 6260 wmi_buf_t buf; 6261 uint8_t *buf_ptr; 6262 uint8_t i; 6263 int ret; 6264 struct probe_req_allowlist_attr *ie_allowlist = &pno->ie_allowlist; 6265 connected_nlo_rssi_params *nlo_relative_rssi; 6266 connected_nlo_bss_band_rssi_pref *nlo_band_rssi; 6267 6268 /* 6269 * TLV place holder for array nlo_configured_parameters(nlo_list) 6270 * TLV place holder for array of uint32_t channel_list 6271 * TLV place holder for chnnl prediction cfg 6272 * TLV place holder for array of wmi_vendor_oui 6273 * TLV place holder for array of connected_nlo_bss_band_rssi_pref 6274 */ 6275 len = sizeof(*cmd) + 6276 WMI_TLV_HDR_SIZE + WMI_TLV_HDR_SIZE + WMI_TLV_HDR_SIZE + 6277 WMI_TLV_HDR_SIZE + WMI_TLV_HDR_SIZE; 6278 6279 len += sizeof(uint32_t) * pno->networks_list[0].pno_chan_list.num_chan; 6280 len += sizeof(nlo_configured_parameters) * 6281 QDF_MIN(pno->networks_cnt, WMI_NLO_MAX_SSIDS); 6282 len += sizeof(nlo_channel_prediction_cfg); 6283 len += sizeof(enlo_candidate_score_params); 6284 len += sizeof(wmi_vendor_oui) * ie_allowlist->num_vendor_oui; 6285 len += sizeof(connected_nlo_rssi_params); 6286 len += sizeof(connected_nlo_bss_band_rssi_pref); 6287 6288 buf = wmi_buf_alloc(wmi_handle, len); 6289 if (!buf) 6290 return QDF_STATUS_E_NOMEM; 6291 6292 cmd = (wmi_nlo_config_cmd_fixed_param *) wmi_buf_data(buf); 6293 6294 buf_ptr = (uint8_t *) cmd; 6295 WMITLV_SET_HDR(&cmd->tlv_header, 6296 WMITLV_TAG_STRUC_wmi_nlo_config_cmd_fixed_param, 6297 WMITLV_GET_STRUCT_TLVLEN 6298 (wmi_nlo_config_cmd_fixed_param)); 6299 cmd->vdev_id = pno->vdev_id; 6300 cmd->flags = WMI_NLO_CONFIG_START | WMI_NLO_CONFIG_SSID_HIDE_EN; 6301 6302 #ifdef FEATURE_WLAN_SCAN_PNO 6303 WMI_SCAN_SET_DWELL_MODE(cmd->flags, 6304 pno->adaptive_dwell_mode); 6305 #endif 6306 /* Current FW does not support min-max range for dwell time */ 6307 cmd->active_dwell_time = pno->active_dwell_time; 6308 cmd->passive_dwell_time = pno->passive_dwell_time; 6309 6310 if (pno->do_passive_scan) 6311 cmd->flags |= WMI_NLO_CONFIG_SCAN_PASSIVE; 6312 /* Copy scan interval */ 6313 cmd->fast_scan_period = pno->fast_scan_period; 6314 cmd->slow_scan_period = pno->slow_scan_period; 6315 cmd->delay_start_time = WMI_SEC_TO_MSEC(pno->delay_start_time); 6316 cmd->fast_scan_max_cycles = pno->fast_scan_max_cycles; 6317 cmd->scan_backoff_multiplier = pno->scan_backoff_multiplier; 6318 6319 /* mac randomization attributes */ 6320 if (pno->scan_random.randomize) { 6321 cmd->flags |= WMI_NLO_CONFIG_SPOOFED_MAC_IN_PROBE_REQ | 6322 WMI_NLO_CONFIG_RANDOM_SEQ_NO_IN_PROBE_REQ; 6323 wmi_copy_scan_random_mac(pno->scan_random.mac_addr, 6324 pno->scan_random.mac_mask, 6325 &cmd->mac_addr, 6326 &cmd->mac_mask); 6327 } 6328 6329 buf_ptr += sizeof(wmi_nlo_config_cmd_fixed_param); 6330 6331 cmd->no_of_ssids = QDF_MIN(pno->networks_cnt, WMI_NLO_MAX_SSIDS); 6332 6333 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 6334 cmd->no_of_ssids * sizeof(nlo_configured_parameters)); 6335 buf_ptr += WMI_TLV_HDR_SIZE; 6336 6337 nlo_list = (nlo_configured_parameters *) buf_ptr; 6338 for (i = 0; i < cmd->no_of_ssids; i++) { 6339 WMITLV_SET_HDR(&nlo_list[i].tlv_header, 6340 WMITLV_TAG_ARRAY_BYTE, 6341 WMITLV_GET_STRUCT_TLVLEN 6342 (nlo_configured_parameters)); 6343 /* Copy ssid and it's length */ 6344 nlo_list[i].ssid.valid = true; 6345 nlo_list[i].ssid.ssid.ssid_len = 6346 pno->networks_list[i].ssid.length; 6347 qdf_mem_copy(nlo_list[i].ssid.ssid.ssid, 6348 pno->networks_list[i].ssid.ssid, 6349 nlo_list[i].ssid.ssid.ssid_len); 6350 6351 /* Copy rssi threshold */ 6352 if (pno->networks_list[i].rssi_thresh && 6353 pno->networks_list[i].rssi_thresh > 6354 WMI_RSSI_THOLD_DEFAULT) { 6355 nlo_list[i].rssi_cond.valid = true; 6356 nlo_list[i].rssi_cond.rssi = 6357 pno->networks_list[i].rssi_thresh; 6358 } 6359 nlo_list[i].bcast_nw_type.valid = true; 6360 nlo_list[i].bcast_nw_type.bcast_nw_type = 6361 pno->networks_list[i].bc_new_type; 6362 } 6363 buf_ptr += cmd->no_of_ssids * sizeof(nlo_configured_parameters); 6364 6365 /* Copy channel info */ 6366 cmd->num_of_channels = pno->networks_list[0].pno_chan_list.num_chan; 6367 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, 6368 (cmd->num_of_channels * sizeof(uint32_t))); 6369 buf_ptr += WMI_TLV_HDR_SIZE; 6370 6371 channel_list = (uint32_t *) buf_ptr; 6372 for (i = 0; i < cmd->num_of_channels; i++) { 6373 TARGET_SET_FREQ_IN_CHAN_LIST_TLV(channel_list[i], 6374 pno->networks_list[0].pno_chan_list.chan[i].freq); 6375 6376 if (channel_list[i] < WMI_NLO_FREQ_THRESH) { 6377 freq = pno->networks_list[0].pno_chan_list.chan[i].freq; 6378 TARGET_SET_FREQ_IN_CHAN_LIST_TLV(channel_list[i], 6379 wlan_chan_to_freq(freq)); 6380 } 6381 6382 TARGET_SET_FLAGS_IN_CHAN_LIST_TLV(channel_list[i], 6383 pno->networks_list[0].pno_chan_list.chan[i].flags); 6384 } 6385 6386 wmi_dump_pno_scan_freq_list(&pno->networks_list[0].pno_chan_list); 6387 6388 buf_ptr += cmd->num_of_channels * sizeof(uint32_t); 6389 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 6390 sizeof(nlo_channel_prediction_cfg)); 6391 buf_ptr += WMI_TLV_HDR_SIZE; 6392 wmi_set_pno_channel_prediction(buf_ptr, pno); 6393 buf_ptr += sizeof(nlo_channel_prediction_cfg); 6394 /** TODO: Discrete firmware doesn't have command/option to configure 6395 * App IE which comes from wpa_supplicant as of part PNO start request. 6396 */ 6397 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_STRUC_enlo_candidate_score_param, 6398 WMITLV_GET_STRUCT_TLVLEN(enlo_candidate_score_params)); 6399 buf_ptr += sizeof(enlo_candidate_score_params); 6400 6401 if (ie_allowlist->allow_list) { 6402 cmd->flags |= WMI_NLO_CONFIG_ENABLE_IE_WHITELIST_IN_PROBE_REQ; 6403 wmi_fill_ie_allowlist_attrs(cmd->ie_bitmap, 6404 &cmd->num_vendor_oui, 6405 ie_allowlist); 6406 } 6407 6408 /* ie allow list */ 6409 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 6410 ie_allowlist->num_vendor_oui * sizeof(wmi_vendor_oui)); 6411 buf_ptr += WMI_TLV_HDR_SIZE; 6412 if (cmd->num_vendor_oui != 0) { 6413 wmi_fill_vendor_oui(buf_ptr, cmd->num_vendor_oui, 6414 ie_allowlist->voui); 6415 buf_ptr += cmd->num_vendor_oui * sizeof(wmi_vendor_oui); 6416 } 6417 6418 if (pno->relative_rssi_set) 6419 cmd->flags |= WMI_NLO_CONFIG_ENABLE_CNLO_RSSI_CONFIG; 6420 6421 /* 6422 * Firmware calculation using connected PNO params: 6423 * New AP's RSSI >= (Connected AP's RSSI + relative_rssi +/- rssi_pref) 6424 * deduction of rssi_pref for chosen band_pref and 6425 * addition of rssi_pref for remaining bands (other than chosen band). 6426 */ 6427 nlo_relative_rssi = (connected_nlo_rssi_params *) buf_ptr; 6428 WMITLV_SET_HDR(&nlo_relative_rssi->tlv_header, 6429 WMITLV_TAG_STRUC_wmi_connected_nlo_rssi_params, 6430 WMITLV_GET_STRUCT_TLVLEN(connected_nlo_rssi_params)); 6431 nlo_relative_rssi->relative_rssi = pno->relative_rssi; 6432 buf_ptr += sizeof(*nlo_relative_rssi); 6433 6434 /* 6435 * As of now Kernel and Host supports one band and rssi preference. 6436 * Firmware supports array of band and rssi preferences 6437 */ 6438 cmd->num_cnlo_band_pref = 1; 6439 WMITLV_SET_HDR(buf_ptr, 6440 WMITLV_TAG_ARRAY_STRUC, 6441 cmd->num_cnlo_band_pref * 6442 sizeof(connected_nlo_bss_band_rssi_pref)); 6443 buf_ptr += WMI_TLV_HDR_SIZE; 6444 6445 nlo_band_rssi = (connected_nlo_bss_band_rssi_pref *) buf_ptr; 6446 for (i = 0; i < cmd->num_cnlo_band_pref; i++) { 6447 WMITLV_SET_HDR(&nlo_band_rssi[i].tlv_header, 6448 WMITLV_TAG_STRUC_wmi_connected_nlo_bss_band_rssi_pref, 6449 WMITLV_GET_STRUCT_TLVLEN( 6450 connected_nlo_bss_band_rssi_pref)); 6451 nlo_band_rssi[i].band = pno->band_rssi_pref.band; 6452 nlo_band_rssi[i].rssi_pref = pno->band_rssi_pref.rssi; 6453 } 6454 buf_ptr += cmd->num_cnlo_band_pref * sizeof(*nlo_band_rssi); 6455 6456 wmi_mtrace(WMI_NETWORK_LIST_OFFLOAD_CONFIG_CMDID, cmd->vdev_id, 0); 6457 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 6458 WMI_NETWORK_LIST_OFFLOAD_CONFIG_CMDID); 6459 if (ret) { 6460 wmi_err("Failed to send nlo wmi cmd"); 6461 wmi_buf_free(buf); 6462 return QDF_STATUS_E_FAILURE; 6463 } 6464 6465 return QDF_STATUS_SUCCESS; 6466 } 6467 6468 /** 6469 * is_service_enabled_tlv() - Check if service enabled 6470 * @wmi_handle: wmi handle 6471 * @service_id: service identifier 6472 * 6473 * Return: 1 enabled, 0 disabled 6474 */ 6475 static bool is_service_enabled_tlv(wmi_unified_t wmi_handle, 6476 uint32_t service_id) 6477 { 6478 struct wmi_soc *soc = wmi_handle->soc; 6479 6480 if (!soc->wmi_service_bitmap) { 6481 wmi_err("WMI service bit map is not saved yet"); 6482 return false; 6483 } 6484 6485 /* if wmi_service_enabled was received with extended2 bitmap, 6486 * use WMI_SERVICE_EXT2_IS_ENABLED to check the services. 6487 */ 6488 if (soc->wmi_ext2_service_bitmap) { 6489 if (!soc->wmi_ext_service_bitmap) { 6490 wmi_err("WMI service ext bit map is not saved yet"); 6491 return false; 6492 } 6493 6494 return WMI_SERVICE_EXT2_IS_ENABLED(soc->wmi_service_bitmap, 6495 soc->wmi_ext_service_bitmap, 6496 soc->wmi_ext2_service_bitmap, 6497 service_id); 6498 } 6499 6500 if (service_id >= WMI_MAX_EXT_SERVICE) { 6501 wmi_err_rl("Service id %d but WMI ext2 service bitmap is NULL", 6502 service_id); 6503 return false; 6504 } 6505 /* if wmi_service_enabled was received with extended bitmap, 6506 * use WMI_SERVICE_EXT_IS_ENABLED to check the services. 6507 */ 6508 if (soc->wmi_ext_service_bitmap) 6509 return WMI_SERVICE_EXT_IS_ENABLED(soc->wmi_service_bitmap, 6510 soc->wmi_ext_service_bitmap, 6511 service_id); 6512 6513 if (service_id >= WMI_MAX_SERVICE) { 6514 wmi_err("Service id %d but WMI ext service bitmap is NULL", 6515 service_id); 6516 return false; 6517 } 6518 6519 return WMI_SERVICE_IS_ENABLED(soc->wmi_service_bitmap, 6520 service_id); 6521 } 6522 6523 #ifdef WLAN_FEATURE_LINK_LAYER_STATS 6524 /** 6525 * send_process_ll_stats_clear_cmd_tlv() - clear link layer stats 6526 * @wmi_handle: wmi handle 6527 * @clear_req: ll stats clear request command params 6528 * 6529 * Return: QDF_STATUS_SUCCESS for success or error code 6530 */ 6531 static QDF_STATUS send_process_ll_stats_clear_cmd_tlv(wmi_unified_t wmi_handle, 6532 const struct ll_stats_clear_params *clear_req) 6533 { 6534 wmi_clear_link_stats_cmd_fixed_param *cmd; 6535 int32_t len; 6536 wmi_buf_t buf; 6537 uint8_t *buf_ptr; 6538 int ret; 6539 6540 len = sizeof(*cmd); 6541 buf = wmi_buf_alloc(wmi_handle, len); 6542 6543 if (!buf) 6544 return QDF_STATUS_E_NOMEM; 6545 6546 buf_ptr = (uint8_t *) wmi_buf_data(buf); 6547 qdf_mem_zero(buf_ptr, len); 6548 cmd = (wmi_clear_link_stats_cmd_fixed_param *) buf_ptr; 6549 6550 WMITLV_SET_HDR(&cmd->tlv_header, 6551 WMITLV_TAG_STRUC_wmi_clear_link_stats_cmd_fixed_param, 6552 WMITLV_GET_STRUCT_TLVLEN 6553 (wmi_clear_link_stats_cmd_fixed_param)); 6554 6555 cmd->stop_stats_collection_req = clear_req->stop_req; 6556 cmd->vdev_id = clear_req->vdev_id; 6557 cmd->stats_clear_req_mask = clear_req->stats_clear_mask; 6558 6559 WMI_CHAR_ARRAY_TO_MAC_ADDR(clear_req->peer_macaddr.bytes, 6560 &cmd->peer_macaddr); 6561 6562 wmi_debug("LINK_LAYER_STATS - Clear Request Params"); 6563 wmi_debug("StopReq: %d Vdev Id: %d Clear Stat Mask: %d" 6564 " Peer MAC Addr: "QDF_MAC_ADDR_FMT, 6565 cmd->stop_stats_collection_req, 6566 cmd->vdev_id, cmd->stats_clear_req_mask, 6567 QDF_MAC_ADDR_REF(clear_req->peer_macaddr.bytes)); 6568 6569 wmi_mtrace(WMI_CLEAR_LINK_STATS_CMDID, cmd->vdev_id, 0); 6570 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 6571 WMI_CLEAR_LINK_STATS_CMDID); 6572 if (ret) { 6573 wmi_err("Failed to send clear link stats req"); 6574 wmi_buf_free(buf); 6575 return QDF_STATUS_E_FAILURE; 6576 } 6577 6578 wmi_debug("Clear Link Layer Stats request sent successfully"); 6579 return QDF_STATUS_SUCCESS; 6580 } 6581 6582 /** 6583 * send_process_ll_stats_set_cmd_tlv() - link layer stats set request 6584 * @wmi_handle: wmi handle 6585 * @set_req: ll stats set request command params 6586 * 6587 * Return: QDF_STATUS_SUCCESS for success or error code 6588 */ 6589 static QDF_STATUS send_process_ll_stats_set_cmd_tlv(wmi_unified_t wmi_handle, 6590 const struct ll_stats_set_params *set_req) 6591 { 6592 wmi_start_link_stats_cmd_fixed_param *cmd; 6593 int32_t len; 6594 wmi_buf_t buf; 6595 uint8_t *buf_ptr; 6596 int ret; 6597 6598 len = sizeof(*cmd); 6599 buf = wmi_buf_alloc(wmi_handle, len); 6600 6601 if (!buf) 6602 return QDF_STATUS_E_NOMEM; 6603 6604 buf_ptr = (uint8_t *) wmi_buf_data(buf); 6605 qdf_mem_zero(buf_ptr, len); 6606 cmd = (wmi_start_link_stats_cmd_fixed_param *) buf_ptr; 6607 6608 WMITLV_SET_HDR(&cmd->tlv_header, 6609 WMITLV_TAG_STRUC_wmi_start_link_stats_cmd_fixed_param, 6610 WMITLV_GET_STRUCT_TLVLEN 6611 (wmi_start_link_stats_cmd_fixed_param)); 6612 6613 cmd->mpdu_size_threshold = set_req->mpdu_size_threshold; 6614 cmd->aggressive_statistics_gathering = 6615 set_req->aggressive_statistics_gathering; 6616 6617 wmi_debug("LINK_LAYER_STATS - Start/Set Params MPDU Size Thresh : %d Aggressive Gather: %d", 6618 cmd->mpdu_size_threshold, 6619 cmd->aggressive_statistics_gathering); 6620 6621 wmi_mtrace(WMI_START_LINK_STATS_CMDID, NO_SESSION, 0); 6622 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 6623 WMI_START_LINK_STATS_CMDID); 6624 if (ret) { 6625 wmi_err("Failed to send set link stats request"); 6626 wmi_buf_free(buf); 6627 return QDF_STATUS_E_FAILURE; 6628 } 6629 6630 return QDF_STATUS_SUCCESS; 6631 } 6632 6633 /** 6634 * send_process_ll_stats_get_cmd_tlv() - link layer stats get request 6635 * @wmi_handle: wmi handle 6636 * @get_req: ll stats get request command params 6637 * 6638 * Return: QDF_STATUS_SUCCESS for success or error code 6639 */ 6640 static QDF_STATUS send_process_ll_stats_get_cmd_tlv(wmi_unified_t wmi_handle, 6641 const struct ll_stats_get_params *get_req) 6642 { 6643 wmi_request_link_stats_cmd_fixed_param *cmd; 6644 int32_t len; 6645 wmi_buf_t buf; 6646 uint8_t *buf_ptr; 6647 int ret; 6648 6649 len = sizeof(*cmd); 6650 buf = wmi_buf_alloc(wmi_handle, len); 6651 6652 if (!buf) 6653 return QDF_STATUS_E_NOMEM; 6654 6655 buf_ptr = (uint8_t *) wmi_buf_data(buf); 6656 qdf_mem_zero(buf_ptr, len); 6657 cmd = (wmi_request_link_stats_cmd_fixed_param *) buf_ptr; 6658 6659 WMITLV_SET_HDR(&cmd->tlv_header, 6660 WMITLV_TAG_STRUC_wmi_request_link_stats_cmd_fixed_param, 6661 WMITLV_GET_STRUCT_TLVLEN 6662 (wmi_request_link_stats_cmd_fixed_param)); 6663 6664 cmd->request_id = get_req->req_id; 6665 cmd->stats_type = get_req->param_id_mask; 6666 cmd->vdev_id = get_req->vdev_id; 6667 6668 WMI_CHAR_ARRAY_TO_MAC_ADDR(get_req->peer_macaddr.bytes, 6669 &cmd->peer_macaddr); 6670 6671 wmi_debug("LINK_LAYER_STATS - Get Request Params Request ID: %u Stats Type: %0x Vdev ID: %d Peer MAC Addr: "QDF_MAC_ADDR_FMT, 6672 cmd->request_id, cmd->stats_type, cmd->vdev_id, 6673 QDF_MAC_ADDR_REF(get_req->peer_macaddr.bytes)); 6674 6675 wmi_mtrace(WMI_REQUEST_LINK_STATS_CMDID, cmd->vdev_id, 0); 6676 ret = wmi_unified_cmd_send_pm_chk(wmi_handle, buf, len, 6677 WMI_REQUEST_LINK_STATS_CMDID, true); 6678 if (ret) { 6679 wmi_buf_free(buf); 6680 return QDF_STATUS_E_FAILURE; 6681 } 6682 6683 return QDF_STATUS_SUCCESS; 6684 } 6685 6686 #ifdef FEATURE_CLUB_LL_STATS_AND_GET_STATION 6687 #ifdef WLAN_FEATURE_11BE_MLO 6688 static int 6689 wmi_get_tlv_length_for_mlo_stats(const struct ll_stats_get_params *get_req) 6690 { 6691 int32_t len = 0; 6692 6693 /* In case of MLO connection, update the length of the buffer. 6694 * The wmi_inst_rssi_stats_params structure is not needed for MLO stats, 6695 * hence just update the TLV header, but allocate no memory for it. 6696 */ 6697 if (!get_req->is_mlo_req) 6698 return len; 6699 6700 len += WMI_TLV_HDR_SIZE + 0 * sizeof(wmi_inst_rssi_stats_params) + 6701 WMI_TLV_HDR_SIZE + 1 * sizeof(uint32_t) + 6702 WMI_TLV_HDR_SIZE + 1 * sizeof(wmi_mac_addr); 6703 6704 return len; 6705 } 6706 6707 static void 6708 wmi_update_tlv_headers_for_mlo_stats(const struct ll_stats_get_params *get_req, 6709 void *buf_ptr) 6710 { 6711 wmi_request_unified_ll_get_sta_cmd_fixed_param *unified_cmd; 6712 uint32_t *vdev_id_bitmap; 6713 wmi_mac_addr *mld_mac; 6714 6715 /* In case of MLO connection, update the TLV Headers */ 6716 if (!get_req->is_mlo_req) 6717 return; 6718 6719 buf_ptr += sizeof(*unified_cmd); 6720 6721 /* Fill TLV but no data for wmi_inst_rssi_stats_params */ 6722 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0); 6723 buf_ptr += WMI_TLV_HDR_SIZE; 6724 6725 /* Adding vdev_bitmap_id array TLV */ 6726 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, 6727 sizeof(*vdev_id_bitmap)); 6728 buf_ptr += WMI_TLV_HDR_SIZE; 6729 vdev_id_bitmap = buf_ptr; 6730 *(vdev_id_bitmap) = get_req->vdev_id_bitmap; 6731 buf_ptr += sizeof(*vdev_id_bitmap); 6732 6733 /* Adding mld_macaddr array TLV */ 6734 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_FIXED_STRUC, 6735 sizeof(*mld_mac)); 6736 buf_ptr += WMI_TLV_HDR_SIZE; 6737 mld_mac = buf_ptr; 6738 WMI_CHAR_ARRAY_TO_MAC_ADDR(get_req->mld_macaddr.bytes, mld_mac); 6739 6740 wmi_debug("MLO vdev_id_bitmap: 0x%x MLD MAC Addr: " 6741 QDF_MAC_ADDR_FMT, get_req->vdev_id_bitmap, 6742 QDF_MAC_ADDR_REF(get_req->mld_macaddr.bytes)); 6743 } 6744 #else 6745 static inline int 6746 wmi_get_tlv_length_for_mlo_stats(const struct ll_stats_get_params *get_req) 6747 { 6748 return 0; 6749 } 6750 6751 static inline void 6752 wmi_update_tlv_headers_for_mlo_stats(const struct ll_stats_get_params *get_req, 6753 void *buf_ptr) 6754 { 6755 } 6756 #endif 6757 6758 /** 6759 * send_unified_ll_stats_get_sta_cmd_tlv() - unified link layer stats and get 6760 * station request 6761 * @wmi_handle: wmi handle 6762 * @get_req: ll stats get request command params 6763 * 6764 * Return: QDF_STATUS_SUCCESS for success or error code 6765 */ 6766 static QDF_STATUS send_unified_ll_stats_get_sta_cmd_tlv( 6767 wmi_unified_t wmi_handle, 6768 const struct ll_stats_get_params *get_req) 6769 { 6770 wmi_request_unified_ll_get_sta_cmd_fixed_param *unified_cmd; 6771 int32_t len; 6772 wmi_buf_t buf; 6773 void *buf_ptr; 6774 QDF_STATUS ret; 6775 bool is_ll_get_sta_stats_over_qmi; 6776 6777 len = sizeof(*unified_cmd); 6778 len += wmi_get_tlv_length_for_mlo_stats(get_req); 6779 6780 buf = wmi_buf_alloc(wmi_handle, len); 6781 if (!buf) 6782 return QDF_STATUS_E_NOMEM; 6783 6784 buf_ptr = wmi_buf_data(buf); 6785 6786 unified_cmd = buf_ptr; 6787 WMITLV_SET_HDR( 6788 &unified_cmd->tlv_header, 6789 WMITLV_TAG_STRUC_wmi_request_unified_ll_get_sta_cmd_fixed_param, 6790 WMITLV_GET_STRUCT_TLVLEN 6791 (wmi_request_unified_ll_get_sta_cmd_fixed_param)); 6792 6793 unified_cmd->link_stats_type = get_req->param_id_mask; 6794 unified_cmd->get_sta_stats_id = (WMI_REQUEST_AP_STAT | 6795 WMI_REQUEST_PEER_STAT | 6796 WMI_REQUEST_VDEV_STAT | 6797 WMI_REQUEST_PDEV_STAT | 6798 WMI_REQUEST_PEER_EXTD2_STAT | 6799 WMI_REQUEST_RSSI_PER_CHAIN_STAT); 6800 unified_cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 6801 wmi_handle, 6802 WMI_HOST_PDEV_ID_SOC); 6803 6804 unified_cmd->vdev_id = get_req->vdev_id; 6805 unified_cmd->request_id = get_req->req_id; 6806 WMI_CHAR_ARRAY_TO_MAC_ADDR(get_req->peer_macaddr.bytes, 6807 &unified_cmd->peer_macaddr); 6808 6809 wmi_debug("UNIFIED_LINK_STATS_GET_STA - Get Request Params Request ID: %u Stats Type: %0x Vdev ID: %d Peer MAC Addr: " 6810 QDF_MAC_ADDR_FMT, 6811 get_req->req_id, get_req->param_id_mask, get_req->vdev_id, 6812 QDF_MAC_ADDR_REF(get_req->peer_macaddr.bytes)); 6813 6814 wmi_update_tlv_headers_for_mlo_stats(get_req, buf_ptr); 6815 wmi_mtrace(WMI_REQUEST_UNIFIED_LL_GET_STA_CMDID, get_req->vdev_id, 0); 6816 6817 /** 6818 * FW support for LL_get_sta command. True represents the unified 6819 * ll_get_sta command should be sent over QMI always irrespective of 6820 * WOW state. 6821 */ 6822 is_ll_get_sta_stats_over_qmi = is_service_enabled_tlv( 6823 wmi_handle, 6824 WMI_SERVICE_UNIFIED_LL_GET_STA_OVER_QMI_SUPPORT); 6825 6826 if (is_ll_get_sta_stats_over_qmi) { 6827 ret = wmi_unified_cmd_send_over_qmi( 6828 wmi_handle, buf, len, 6829 WMI_REQUEST_UNIFIED_LL_GET_STA_CMDID); 6830 } else { 6831 ret = wmi_unified_cmd_send_pm_chk( 6832 wmi_handle, buf, len, 6833 WMI_REQUEST_UNIFIED_LL_GET_STA_CMDID, 6834 true); 6835 } 6836 6837 if (QDF_IS_STATUS_ERROR(ret)) { 6838 wmi_buf_free(buf); 6839 return QDF_STATUS_E_FAILURE; 6840 } 6841 6842 return ret; 6843 } 6844 #endif 6845 #endif /* WLAN_FEATURE_LINK_LAYER_STATS */ 6846 6847 /** 6848 * send_congestion_cmd_tlv() - send request to fw to get CCA 6849 * @wmi_handle: wmi handle 6850 * @vdev_id: vdev id 6851 * 6852 * Return: QDF status 6853 */ 6854 static QDF_STATUS send_congestion_cmd_tlv(wmi_unified_t wmi_handle, 6855 uint8_t vdev_id) 6856 { 6857 wmi_buf_t buf; 6858 wmi_request_stats_cmd_fixed_param *cmd; 6859 uint8_t len; 6860 uint8_t *buf_ptr; 6861 6862 len = sizeof(*cmd); 6863 buf = wmi_buf_alloc(wmi_handle, len); 6864 if (!buf) 6865 return QDF_STATUS_E_FAILURE; 6866 6867 buf_ptr = wmi_buf_data(buf); 6868 cmd = (wmi_request_stats_cmd_fixed_param *)buf_ptr; 6869 WMITLV_SET_HDR(&cmd->tlv_header, 6870 WMITLV_TAG_STRUC_wmi_request_stats_cmd_fixed_param, 6871 WMITLV_GET_STRUCT_TLVLEN 6872 (wmi_request_stats_cmd_fixed_param)); 6873 6874 cmd->stats_id = WMI_REQUEST_CONGESTION_STAT; 6875 cmd->vdev_id = vdev_id; 6876 wmi_debug("STATS REQ VDEV_ID:%d stats_id %d -->", 6877 cmd->vdev_id, cmd->stats_id); 6878 6879 wmi_mtrace(WMI_REQUEST_STATS_CMDID, cmd->vdev_id, 0); 6880 if (wmi_unified_cmd_send(wmi_handle, buf, len, 6881 WMI_REQUEST_STATS_CMDID)) { 6882 wmi_err("Failed to send WMI_REQUEST_STATS_CMDID"); 6883 wmi_buf_free(buf); 6884 return QDF_STATUS_E_FAILURE; 6885 } 6886 6887 return QDF_STATUS_SUCCESS; 6888 } 6889 6890 /** 6891 * send_snr_request_cmd_tlv() - send request to fw to get RSSI stats 6892 * @wmi_handle: wmi handle 6893 * 6894 * Return: QDF status 6895 */ 6896 static QDF_STATUS send_snr_request_cmd_tlv(wmi_unified_t wmi_handle) 6897 { 6898 wmi_buf_t buf; 6899 wmi_request_stats_cmd_fixed_param *cmd; 6900 uint8_t len = sizeof(wmi_request_stats_cmd_fixed_param); 6901 6902 buf = wmi_buf_alloc(wmi_handle, len); 6903 if (!buf) 6904 return QDF_STATUS_E_FAILURE; 6905 6906 cmd = (wmi_request_stats_cmd_fixed_param *) wmi_buf_data(buf); 6907 WMITLV_SET_HDR(&cmd->tlv_header, 6908 WMITLV_TAG_STRUC_wmi_request_stats_cmd_fixed_param, 6909 WMITLV_GET_STRUCT_TLVLEN 6910 (wmi_request_stats_cmd_fixed_param)); 6911 cmd->stats_id = WMI_REQUEST_VDEV_STAT; 6912 wmi_mtrace(WMI_REQUEST_STATS_CMDID, cmd->vdev_id, 0); 6913 if (wmi_unified_cmd_send(wmi_handle, buf, len, 6914 WMI_REQUEST_STATS_CMDID)) { 6915 wmi_err("Failed to send host stats request to fw"); 6916 wmi_buf_free(buf); 6917 return QDF_STATUS_E_FAILURE; 6918 } 6919 6920 return QDF_STATUS_SUCCESS; 6921 } 6922 6923 /** 6924 * send_snr_cmd_tlv() - get RSSI from fw 6925 * @wmi_handle: wmi handle 6926 * @vdev_id: vdev id 6927 * 6928 * Return: QDF status 6929 */ 6930 static QDF_STATUS send_snr_cmd_tlv(wmi_unified_t wmi_handle, uint8_t vdev_id) 6931 { 6932 wmi_buf_t buf; 6933 wmi_request_stats_cmd_fixed_param *cmd; 6934 uint8_t len = sizeof(wmi_request_stats_cmd_fixed_param); 6935 6936 buf = wmi_buf_alloc(wmi_handle, len); 6937 if (!buf) 6938 return QDF_STATUS_E_FAILURE; 6939 6940 cmd = (wmi_request_stats_cmd_fixed_param *) wmi_buf_data(buf); 6941 cmd->vdev_id = vdev_id; 6942 6943 WMITLV_SET_HDR(&cmd->tlv_header, 6944 WMITLV_TAG_STRUC_wmi_request_stats_cmd_fixed_param, 6945 WMITLV_GET_STRUCT_TLVLEN 6946 (wmi_request_stats_cmd_fixed_param)); 6947 cmd->stats_id = WMI_REQUEST_VDEV_STAT; 6948 wmi_mtrace(WMI_REQUEST_STATS_CMDID, cmd->vdev_id, 0); 6949 if (wmi_unified_cmd_send(wmi_handle, buf, len, 6950 WMI_REQUEST_STATS_CMDID)) { 6951 wmi_err("Failed to send host stats request to fw"); 6952 wmi_buf_free(buf); 6953 return QDF_STATUS_E_FAILURE; 6954 } 6955 6956 return QDF_STATUS_SUCCESS; 6957 } 6958 6959 /** 6960 * send_link_status_req_cmd_tlv() - process link status request from UMAC 6961 * @wmi_handle: wmi handle 6962 * @link_status: get link params 6963 * 6964 * Return: QDF status 6965 */ 6966 static QDF_STATUS send_link_status_req_cmd_tlv(wmi_unified_t wmi_handle, 6967 struct link_status_params *link_status) 6968 { 6969 wmi_buf_t buf; 6970 wmi_request_stats_cmd_fixed_param *cmd; 6971 uint8_t len = sizeof(wmi_request_stats_cmd_fixed_param); 6972 6973 buf = wmi_buf_alloc(wmi_handle, len); 6974 if (!buf) 6975 return QDF_STATUS_E_FAILURE; 6976 6977 cmd = (wmi_request_stats_cmd_fixed_param *) wmi_buf_data(buf); 6978 WMITLV_SET_HDR(&cmd->tlv_header, 6979 WMITLV_TAG_STRUC_wmi_request_stats_cmd_fixed_param, 6980 WMITLV_GET_STRUCT_TLVLEN 6981 (wmi_request_stats_cmd_fixed_param)); 6982 cmd->stats_id = WMI_REQUEST_VDEV_RATE_STAT; 6983 cmd->vdev_id = link_status->vdev_id; 6984 wmi_mtrace(WMI_REQUEST_STATS_CMDID, cmd->vdev_id, 0); 6985 if (wmi_unified_cmd_send(wmi_handle, buf, len, 6986 WMI_REQUEST_STATS_CMDID)) { 6987 wmi_err("Failed to send WMI link status request to fw"); 6988 wmi_buf_free(buf); 6989 return QDF_STATUS_E_FAILURE; 6990 } 6991 6992 return QDF_STATUS_SUCCESS; 6993 } 6994 6995 #ifdef WLAN_SUPPORT_GREEN_AP 6996 /** 6997 * send_egap_conf_params_cmd_tlv() - send wmi cmd of egap configuration params 6998 * @wmi_handle: wmi handler 6999 * @egap_params: pointer to egap_params 7000 * 7001 * Return: 0 for success, otherwise appropriate error code 7002 */ 7003 static QDF_STATUS send_egap_conf_params_cmd_tlv(wmi_unified_t wmi_handle, 7004 struct wlan_green_ap_egap_params *egap_params) 7005 { 7006 wmi_ap_ps_egap_param_cmd_fixed_param *cmd; 7007 wmi_buf_t buf; 7008 int32_t err; 7009 7010 buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd)); 7011 if (!buf) 7012 return QDF_STATUS_E_NOMEM; 7013 7014 cmd = (wmi_ap_ps_egap_param_cmd_fixed_param *) wmi_buf_data(buf); 7015 WMITLV_SET_HDR(&cmd->tlv_header, 7016 WMITLV_TAG_STRUC_wmi_ap_ps_egap_param_cmd_fixed_param, 7017 WMITLV_GET_STRUCT_TLVLEN( 7018 wmi_ap_ps_egap_param_cmd_fixed_param)); 7019 7020 cmd->enable = egap_params->host_enable_egap; 7021 cmd->inactivity_time = egap_params->egap_inactivity_time; 7022 cmd->wait_time = egap_params->egap_wait_time; 7023 cmd->flags = egap_params->egap_feature_flags; 7024 wmi_mtrace(WMI_AP_PS_EGAP_PARAM_CMDID, NO_SESSION, 0); 7025 err = wmi_unified_cmd_send(wmi_handle, buf, 7026 sizeof(*cmd), WMI_AP_PS_EGAP_PARAM_CMDID); 7027 if (err) { 7028 wmi_err("Failed to send ap_ps_egap cmd"); 7029 wmi_buf_free(buf); 7030 return QDF_STATUS_E_FAILURE; 7031 } 7032 7033 return QDF_STATUS_SUCCESS; 7034 } 7035 #endif 7036 7037 /** 7038 * send_csa_offload_enable_cmd_tlv() - send CSA offload enable command 7039 * @wmi_handle: wmi handle 7040 * @vdev_id: vdev id 7041 * 7042 * Return: QDF_STATUS_SUCCESS for success or error code 7043 */ 7044 static QDF_STATUS send_csa_offload_enable_cmd_tlv(wmi_unified_t wmi_handle, 7045 uint8_t vdev_id) 7046 { 7047 wmi_csa_offload_enable_cmd_fixed_param *cmd; 7048 wmi_buf_t buf; 7049 int32_t len = sizeof(*cmd); 7050 7051 wmi_debug("vdev_id %d", vdev_id); 7052 buf = wmi_buf_alloc(wmi_handle, len); 7053 if (!buf) 7054 return QDF_STATUS_E_NOMEM; 7055 7056 cmd = (wmi_csa_offload_enable_cmd_fixed_param *) wmi_buf_data(buf); 7057 WMITLV_SET_HDR(&cmd->tlv_header, 7058 WMITLV_TAG_STRUC_wmi_csa_offload_enable_cmd_fixed_param, 7059 WMITLV_GET_STRUCT_TLVLEN 7060 (wmi_csa_offload_enable_cmd_fixed_param)); 7061 cmd->vdev_id = vdev_id; 7062 cmd->csa_offload_enable = WMI_CSA_OFFLOAD_ENABLE; 7063 wmi_mtrace(WMI_CSA_OFFLOAD_ENABLE_CMDID, cmd->vdev_id, 0); 7064 if (wmi_unified_cmd_send(wmi_handle, buf, len, 7065 WMI_CSA_OFFLOAD_ENABLE_CMDID)) { 7066 wmi_err("Failed to send CSA offload enable command"); 7067 wmi_buf_free(buf); 7068 return QDF_STATUS_E_FAILURE; 7069 } 7070 7071 return 0; 7072 } 7073 7074 #ifdef WLAN_FEATURE_CIF_CFR 7075 /** 7076 * send_oem_dma_cfg_cmd_tlv() - configure OEM DMA rings 7077 * @wmi_handle: wmi handle 7078 * @cfg: dma cfg req 7079 * 7080 * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure 7081 */ 7082 static QDF_STATUS send_oem_dma_cfg_cmd_tlv(wmi_unified_t wmi_handle, 7083 wmi_oem_dma_ring_cfg_req_fixed_param *cfg) 7084 { 7085 wmi_buf_t buf; 7086 uint8_t *cmd; 7087 QDF_STATUS ret; 7088 7089 WMITLV_SET_HDR(cfg, 7090 WMITLV_TAG_STRUC_wmi_oem_dma_ring_cfg_req_fixed_param, 7091 (sizeof(*cfg) - WMI_TLV_HDR_SIZE)); 7092 7093 buf = wmi_buf_alloc(wmi_handle, sizeof(*cfg)); 7094 if (!buf) 7095 return QDF_STATUS_E_FAILURE; 7096 7097 cmd = (uint8_t *) wmi_buf_data(buf); 7098 qdf_mem_copy(cmd, cfg, sizeof(*cfg)); 7099 wmi_debug("Sending OEM Data Request to target, data len %lu", 7100 sizeof(*cfg)); 7101 wmi_mtrace(WMI_OEM_DMA_RING_CFG_REQ_CMDID, NO_SESSION, 0); 7102 ret = wmi_unified_cmd_send(wmi_handle, buf, sizeof(*cfg), 7103 WMI_OEM_DMA_RING_CFG_REQ_CMDID); 7104 if (QDF_IS_STATUS_ERROR(ret)) { 7105 wmi_err("Failed to send WMI_OEM_DMA_RING_CFG_REQ_CMDID"); 7106 wmi_buf_free(buf); 7107 } 7108 7109 return ret; 7110 } 7111 #endif 7112 7113 /** 7114 * send_start_11d_scan_cmd_tlv() - start 11d scan request 7115 * @wmi_handle: wmi handle 7116 * @start_11d_scan: 11d scan start request parameters 7117 * 7118 * This function request FW to start 11d scan. 7119 * 7120 * Return: QDF status 7121 */ 7122 static QDF_STATUS send_start_11d_scan_cmd_tlv(wmi_unified_t wmi_handle, 7123 struct reg_start_11d_scan_req *start_11d_scan) 7124 { 7125 wmi_11d_scan_start_cmd_fixed_param *cmd; 7126 int32_t len; 7127 wmi_buf_t buf; 7128 int ret; 7129 7130 len = sizeof(*cmd); 7131 buf = wmi_buf_alloc(wmi_handle, len); 7132 if (!buf) 7133 return QDF_STATUS_E_NOMEM; 7134 7135 cmd = (wmi_11d_scan_start_cmd_fixed_param *)wmi_buf_data(buf); 7136 7137 WMITLV_SET_HDR(&cmd->tlv_header, 7138 WMITLV_TAG_STRUC_wmi_11d_scan_start_cmd_fixed_param, 7139 WMITLV_GET_STRUCT_TLVLEN 7140 (wmi_11d_scan_start_cmd_fixed_param)); 7141 7142 cmd->vdev_id = start_11d_scan->vdev_id; 7143 cmd->scan_period_msec = start_11d_scan->scan_period_msec; 7144 cmd->start_interval_msec = start_11d_scan->start_interval_msec; 7145 7146 wmi_debug("vdev %d sending 11D scan start req", cmd->vdev_id); 7147 7148 wmi_mtrace(WMI_11D_SCAN_START_CMDID, cmd->vdev_id, 0); 7149 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 7150 WMI_11D_SCAN_START_CMDID); 7151 if (ret) { 7152 wmi_err("Failed to send start 11d scan wmi cmd"); 7153 wmi_buf_free(buf); 7154 return QDF_STATUS_E_FAILURE; 7155 } 7156 7157 return QDF_STATUS_SUCCESS; 7158 } 7159 7160 /** 7161 * send_stop_11d_scan_cmd_tlv() - stop 11d scan request 7162 * @wmi_handle: wmi handle 7163 * @stop_11d_scan: 11d scan stop request parameters 7164 * 7165 * This function request FW to stop 11d scan. 7166 * 7167 * Return: QDF status 7168 */ 7169 static QDF_STATUS send_stop_11d_scan_cmd_tlv(wmi_unified_t wmi_handle, 7170 struct reg_stop_11d_scan_req *stop_11d_scan) 7171 { 7172 wmi_11d_scan_stop_cmd_fixed_param *cmd; 7173 int32_t len; 7174 wmi_buf_t buf; 7175 int ret; 7176 7177 len = sizeof(*cmd); 7178 buf = wmi_buf_alloc(wmi_handle, len); 7179 if (!buf) 7180 return QDF_STATUS_E_NOMEM; 7181 7182 cmd = (wmi_11d_scan_stop_cmd_fixed_param *)wmi_buf_data(buf); 7183 7184 WMITLV_SET_HDR(&cmd->tlv_header, 7185 WMITLV_TAG_STRUC_wmi_11d_scan_stop_cmd_fixed_param, 7186 WMITLV_GET_STRUCT_TLVLEN 7187 (wmi_11d_scan_stop_cmd_fixed_param)); 7188 7189 cmd->vdev_id = stop_11d_scan->vdev_id; 7190 7191 wmi_debug("vdev %d sending 11D scan stop req", cmd->vdev_id); 7192 7193 wmi_mtrace(WMI_11D_SCAN_STOP_CMDID, cmd->vdev_id, 0); 7194 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 7195 WMI_11D_SCAN_STOP_CMDID); 7196 if (ret) { 7197 wmi_err("Failed to send stop 11d scan wmi cmd"); 7198 wmi_buf_free(buf); 7199 return QDF_STATUS_E_FAILURE; 7200 } 7201 7202 return QDF_STATUS_SUCCESS; 7203 } 7204 7205 /** 7206 * send_start_oem_data_cmd_tlv() - start OEM data request to target 7207 * @wmi_handle: wmi handle 7208 * @data_len: the length of @data 7209 * @data: the pointer to data buf 7210 * 7211 * Return: QDF status 7212 */ 7213 static QDF_STATUS send_start_oem_data_cmd_tlv(wmi_unified_t wmi_handle, 7214 uint32_t data_len, 7215 uint8_t *data) 7216 { 7217 wmi_buf_t buf; 7218 uint8_t *cmd; 7219 QDF_STATUS ret; 7220 7221 buf = wmi_buf_alloc(wmi_handle, 7222 (data_len + WMI_TLV_HDR_SIZE)); 7223 if (!buf) 7224 return QDF_STATUS_E_FAILURE; 7225 7226 cmd = (uint8_t *) wmi_buf_data(buf); 7227 7228 WMITLV_SET_HDR(cmd, WMITLV_TAG_ARRAY_BYTE, data_len); 7229 cmd += WMI_TLV_HDR_SIZE; 7230 qdf_mem_copy(cmd, data, 7231 data_len); 7232 7233 wmi_debug("Sending OEM Data Request to target, data len %d", data_len); 7234 7235 wmi_mtrace(WMI_OEM_REQ_CMDID, NO_SESSION, 0); 7236 ret = wmi_unified_cmd_send(wmi_handle, buf, 7237 (data_len + 7238 WMI_TLV_HDR_SIZE), WMI_OEM_REQ_CMDID); 7239 7240 if (QDF_IS_STATUS_ERROR(ret)) { 7241 wmi_err("Failed to send WMI_OEM_REQ_CMDID"); 7242 wmi_buf_free(buf); 7243 } 7244 7245 return ret; 7246 } 7247 7248 #ifdef FEATURE_OEM_DATA 7249 /** 7250 * send_start_oemv2_data_cmd_tlv() - start OEM data to target 7251 * @wmi_handle: wmi handle 7252 * @oem_data: the pointer to oem data 7253 * 7254 * Return: QDF status 7255 */ 7256 static QDF_STATUS send_start_oemv2_data_cmd_tlv(wmi_unified_t wmi_handle, 7257 struct oem_data *oem_data) 7258 { 7259 QDF_STATUS ret; 7260 wmi_oem_data_cmd_fixed_param *cmd; 7261 struct wmi_ops *ops; 7262 wmi_buf_t buf; 7263 uint16_t len = sizeof(*cmd); 7264 uint16_t oem_data_len_aligned; 7265 uint8_t *buf_ptr; 7266 uint32_t pdev_id; 7267 7268 if (!oem_data || !oem_data->data) { 7269 wmi_err_rl("oem data is not valid"); 7270 return QDF_STATUS_E_FAILURE; 7271 } 7272 7273 oem_data_len_aligned = roundup(oem_data->data_len, sizeof(uint32_t)); 7274 if (oem_data_len_aligned < oem_data->data_len) { 7275 wmi_err_rl("integer overflow while rounding up data_len"); 7276 return QDF_STATUS_E_FAILURE; 7277 } 7278 7279 if (oem_data_len_aligned > WMI_SVC_MSG_MAX_SIZE - WMI_TLV_HDR_SIZE) { 7280 wmi_err_rl("wmi_max_msg_size overflow for given data_len"); 7281 return QDF_STATUS_E_FAILURE; 7282 } 7283 7284 len += WMI_TLV_HDR_SIZE + oem_data_len_aligned; 7285 buf = wmi_buf_alloc(wmi_handle, len); 7286 if (!buf) 7287 return QDF_STATUS_E_NOMEM; 7288 7289 buf_ptr = (uint8_t *)wmi_buf_data(buf); 7290 cmd = (wmi_oem_data_cmd_fixed_param *)buf_ptr; 7291 WMITLV_SET_HDR(&cmd->tlv_header, 7292 WMITLV_TAG_STRUC_wmi_oem_data_cmd_fixed_param, 7293 WMITLV_GET_STRUCT_TLVLEN(wmi_oem_data_cmd_fixed_param)); 7294 7295 pdev_id = oem_data->pdev_id; 7296 if (oem_data->pdev_vdev_flag) { 7297 ops = wmi_handle->ops; 7298 if (oem_data->is_host_pdev_id) 7299 pdev_id = 7300 ops->convert_host_pdev_id_to_target(wmi_handle, 7301 pdev_id); 7302 else 7303 pdev_id = 7304 ops->convert_pdev_id_host_to_target(wmi_handle, 7305 pdev_id); 7306 } 7307 7308 cmd->vdev_id = oem_data->vdev_id; 7309 cmd->data_len = oem_data->data_len; 7310 cmd->pdev_vdev_flag = oem_data->pdev_vdev_flag; 7311 cmd->pdev_id = pdev_id; 7312 7313 buf_ptr += sizeof(*cmd); 7314 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, oem_data_len_aligned); 7315 buf_ptr += WMI_TLV_HDR_SIZE; 7316 qdf_mem_copy(buf_ptr, oem_data->data, oem_data->data_len); 7317 7318 wmi_mtrace(WMI_OEM_DATA_CMDID, NO_SESSION, 0); 7319 ret = wmi_unified_cmd_send(wmi_handle, buf, len, WMI_OEM_DATA_CMDID); 7320 if (QDF_IS_STATUS_ERROR(ret)) { 7321 wmi_err_rl("Failed with ret = %d", ret); 7322 wmi_buf_free(buf); 7323 } 7324 7325 return ret; 7326 } 7327 #endif 7328 7329 /** 7330 * send_dfs_phyerr_filter_offload_en_cmd_tlv() - enable dfs phyerr filter 7331 * @wmi_handle: wmi handle 7332 * @dfs_phyerr_filter_offload: is dfs phyerr filter offload 7333 * 7334 * Send WMI_DFS_PHYERR_FILTER_ENA_CMDID or 7335 * WMI_DFS_PHYERR_FILTER_DIS_CMDID command 7336 * to firmware based on phyerr filtering 7337 * offload status. 7338 * 7339 * Return: 1 success, 0 failure 7340 */ 7341 static QDF_STATUS 7342 send_dfs_phyerr_filter_offload_en_cmd_tlv(wmi_unified_t wmi_handle, 7343 bool dfs_phyerr_filter_offload) 7344 { 7345 wmi_dfs_phyerr_filter_ena_cmd_fixed_param *enable_phyerr_offload_cmd; 7346 wmi_dfs_phyerr_filter_dis_cmd_fixed_param *disable_phyerr_offload_cmd; 7347 wmi_buf_t buf; 7348 uint16_t len; 7349 QDF_STATUS ret; 7350 7351 7352 if (false == dfs_phyerr_filter_offload) { 7353 wmi_debug("Phyerror Filtering offload is Disabled in ini"); 7354 len = sizeof(*disable_phyerr_offload_cmd); 7355 buf = wmi_buf_alloc(wmi_handle, len); 7356 if (!buf) 7357 return 0; 7358 7359 disable_phyerr_offload_cmd = 7360 (wmi_dfs_phyerr_filter_dis_cmd_fixed_param *) 7361 wmi_buf_data(buf); 7362 7363 WMITLV_SET_HDR(&disable_phyerr_offload_cmd->tlv_header, 7364 WMITLV_TAG_STRUC_wmi_dfs_phyerr_filter_dis_cmd_fixed_param, 7365 WMITLV_GET_STRUCT_TLVLEN 7366 (wmi_dfs_phyerr_filter_dis_cmd_fixed_param)); 7367 7368 /* 7369 * Send WMI_DFS_PHYERR_FILTER_DIS_CMDID 7370 * to the firmware to disable the phyerror 7371 * filtering offload. 7372 */ 7373 wmi_mtrace(WMI_DFS_PHYERR_FILTER_DIS_CMDID, NO_SESSION, 0); 7374 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 7375 WMI_DFS_PHYERR_FILTER_DIS_CMDID); 7376 if (QDF_IS_STATUS_ERROR(ret)) { 7377 wmi_err("Failed to send WMI_DFS_PHYERR_FILTER_DIS_CMDID ret=%d", 7378 ret); 7379 wmi_buf_free(buf); 7380 return QDF_STATUS_E_FAILURE; 7381 } 7382 wmi_debug("WMI_DFS_PHYERR_FILTER_DIS_CMDID Send Success"); 7383 } else { 7384 wmi_debug("Phyerror Filtering offload is Enabled in ini"); 7385 7386 len = sizeof(*enable_phyerr_offload_cmd); 7387 buf = wmi_buf_alloc(wmi_handle, len); 7388 if (!buf) 7389 return QDF_STATUS_E_FAILURE; 7390 7391 enable_phyerr_offload_cmd = 7392 (wmi_dfs_phyerr_filter_ena_cmd_fixed_param *) 7393 wmi_buf_data(buf); 7394 7395 WMITLV_SET_HDR(&enable_phyerr_offload_cmd->tlv_header, 7396 WMITLV_TAG_STRUC_wmi_dfs_phyerr_filter_ena_cmd_fixed_param, 7397 WMITLV_GET_STRUCT_TLVLEN 7398 (wmi_dfs_phyerr_filter_ena_cmd_fixed_param)); 7399 7400 /* 7401 * Send a WMI_DFS_PHYERR_FILTER_ENA_CMDID 7402 * to the firmware to enable the phyerror 7403 * filtering offload. 7404 */ 7405 wmi_mtrace(WMI_DFS_PHYERR_FILTER_ENA_CMDID, NO_SESSION, 0); 7406 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 7407 WMI_DFS_PHYERR_FILTER_ENA_CMDID); 7408 7409 if (QDF_IS_STATUS_ERROR(ret)) { 7410 wmi_err("Failed to send DFS PHYERR CMD ret=%d", ret); 7411 wmi_buf_free(buf); 7412 return QDF_STATUS_E_FAILURE; 7413 } 7414 wmi_debug("WMI_DFS_PHYERR_FILTER_ENA_CMDID Send Success"); 7415 } 7416 7417 return QDF_STATUS_SUCCESS; 7418 } 7419 7420 #if !defined(REMOVE_PKT_LOG) && defined(FEATURE_PKTLOG) 7421 /** 7422 * send_pktlog_wmi_send_cmd_tlv() - send pktlog enable/disable command to target 7423 * @wmi_handle: wmi handle 7424 * @pktlog_event: pktlog event 7425 * @cmd_id: pktlog cmd id 7426 * @user_triggered: user triggered input for PKTLOG enable mode 7427 * 7428 * Return: QDF status 7429 */ 7430 static QDF_STATUS send_pktlog_wmi_send_cmd_tlv(wmi_unified_t wmi_handle, 7431 WMI_PKTLOG_EVENT pktlog_event, 7432 WMI_CMD_ID cmd_id, uint8_t user_triggered) 7433 { 7434 WMI_PKTLOG_EVENT PKTLOG_EVENT; 7435 WMI_CMD_ID CMD_ID; 7436 wmi_pdev_pktlog_enable_cmd_fixed_param *cmd; 7437 wmi_pdev_pktlog_disable_cmd_fixed_param *disable_cmd; 7438 int len = 0; 7439 wmi_buf_t buf; 7440 int32_t idx, max_idx; 7441 7442 PKTLOG_EVENT = pktlog_event; 7443 CMD_ID = cmd_id; 7444 7445 max_idx = sizeof(pktlog_event_tlv) / (sizeof(pktlog_event_tlv[0])); 7446 switch (CMD_ID) { 7447 case WMI_PDEV_PKTLOG_ENABLE_CMDID: 7448 len = sizeof(*cmd); 7449 buf = wmi_buf_alloc(wmi_handle, len); 7450 if (!buf) 7451 return QDF_STATUS_E_NOMEM; 7452 7453 cmd = (wmi_pdev_pktlog_enable_cmd_fixed_param *) 7454 wmi_buf_data(buf); 7455 WMITLV_SET_HDR(&cmd->tlv_header, 7456 WMITLV_TAG_STRUC_wmi_pdev_pktlog_enable_cmd_fixed_param, 7457 WMITLV_GET_STRUCT_TLVLEN 7458 (wmi_pdev_pktlog_enable_cmd_fixed_param)); 7459 cmd->evlist = 0; 7460 for (idx = 0; idx < max_idx; idx++) { 7461 if (PKTLOG_EVENT & (1 << idx)) 7462 cmd->evlist |= pktlog_event_tlv[idx]; 7463 } 7464 cmd->enable = user_triggered ? WMI_PKTLOG_ENABLE_FORCE 7465 : WMI_PKTLOG_ENABLE_AUTO; 7466 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 7467 wmi_handle, 7468 WMI_HOST_PDEV_ID_SOC); 7469 wmi_mtrace(WMI_PDEV_PKTLOG_ENABLE_CMDID, NO_SESSION, 0); 7470 if (wmi_unified_cmd_send(wmi_handle, buf, len, 7471 WMI_PDEV_PKTLOG_ENABLE_CMDID)) { 7472 wmi_err("Failed to send pktlog enable cmdid"); 7473 goto wmi_send_failed; 7474 } 7475 break; 7476 case WMI_PDEV_PKTLOG_DISABLE_CMDID: 7477 len = sizeof(*disable_cmd); 7478 buf = wmi_buf_alloc(wmi_handle, len); 7479 if (!buf) 7480 return QDF_STATUS_E_NOMEM; 7481 7482 disable_cmd = (wmi_pdev_pktlog_disable_cmd_fixed_param *) 7483 wmi_buf_data(buf); 7484 WMITLV_SET_HDR(&disable_cmd->tlv_header, 7485 WMITLV_TAG_STRUC_wmi_pdev_pktlog_disable_cmd_fixed_param, 7486 WMITLV_GET_STRUCT_TLVLEN 7487 (wmi_pdev_pktlog_disable_cmd_fixed_param)); 7488 disable_cmd->pdev_id = 7489 wmi_handle->ops->convert_pdev_id_host_to_target( 7490 wmi_handle, 7491 WMI_HOST_PDEV_ID_SOC); 7492 wmi_mtrace(WMI_PDEV_PKTLOG_DISABLE_CMDID, NO_SESSION, 0); 7493 if (wmi_unified_cmd_send(wmi_handle, buf, len, 7494 WMI_PDEV_PKTLOG_DISABLE_CMDID)) { 7495 wmi_err("failed to send pktlog disable cmdid"); 7496 goto wmi_send_failed; 7497 } 7498 break; 7499 default: 7500 wmi_debug("Invalid PKTLOG command: %d", CMD_ID); 7501 break; 7502 } 7503 7504 return QDF_STATUS_SUCCESS; 7505 7506 wmi_send_failed: 7507 wmi_buf_free(buf); 7508 return QDF_STATUS_E_FAILURE; 7509 } 7510 #endif /* !REMOVE_PKT_LOG && FEATURE_PKTLOG */ 7511 7512 /** 7513 * send_stats_ext_req_cmd_tlv() - request ext stats from fw 7514 * @wmi_handle: wmi handle 7515 * @preq: stats ext params 7516 * 7517 * Return: QDF status 7518 */ 7519 static QDF_STATUS send_stats_ext_req_cmd_tlv(wmi_unified_t wmi_handle, 7520 struct stats_ext_params *preq) 7521 { 7522 QDF_STATUS ret; 7523 wmi_req_stats_ext_cmd_fixed_param *cmd; 7524 wmi_buf_t buf; 7525 size_t len; 7526 uint8_t *buf_ptr; 7527 uint16_t max_wmi_msg_size = wmi_get_max_msg_len(wmi_handle); 7528 uint32_t *vdev_bitmap; 7529 7530 if (preq->request_data_len > (max_wmi_msg_size - WMI_TLV_HDR_SIZE - 7531 sizeof(*cmd))) { 7532 wmi_err("Data length=%d is greater than max wmi msg size", 7533 preq->request_data_len); 7534 return QDF_STATUS_E_FAILURE; 7535 } 7536 7537 len = sizeof(*cmd) + WMI_TLV_HDR_SIZE + preq->request_data_len + 7538 WMI_TLV_HDR_SIZE + sizeof(uint32_t); 7539 7540 buf = wmi_buf_alloc(wmi_handle, len); 7541 if (!buf) 7542 return QDF_STATUS_E_NOMEM; 7543 7544 buf_ptr = (uint8_t *) wmi_buf_data(buf); 7545 cmd = (wmi_req_stats_ext_cmd_fixed_param *) buf_ptr; 7546 7547 WMITLV_SET_HDR(&cmd->tlv_header, 7548 WMITLV_TAG_STRUC_wmi_req_stats_ext_cmd_fixed_param, 7549 WMITLV_GET_STRUCT_TLVLEN 7550 (wmi_req_stats_ext_cmd_fixed_param)); 7551 cmd->vdev_id = preq->vdev_id; 7552 cmd->data_len = preq->request_data_len; 7553 7554 wmi_debug("The data len value is %u and vdev id set is %u", 7555 preq->request_data_len, preq->vdev_id); 7556 7557 buf_ptr += sizeof(wmi_req_stats_ext_cmd_fixed_param); 7558 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, cmd->data_len); 7559 7560 buf_ptr += WMI_TLV_HDR_SIZE; 7561 qdf_mem_copy(buf_ptr, preq->request_data, cmd->data_len); 7562 7563 buf_ptr += cmd->data_len; 7564 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, sizeof(uint32_t)); 7565 7566 buf_ptr += WMI_TLV_HDR_SIZE; 7567 7568 vdev_bitmap = (A_UINT32 *)buf_ptr; 7569 7570 vdev_bitmap[0] = preq->vdev_id_bitmap; 7571 7572 wmi_debug("Sending MLO vdev_id_bitmap:%x", vdev_bitmap[0]); 7573 7574 buf_ptr += sizeof(uint32_t); 7575 7576 wmi_mtrace(WMI_REQUEST_STATS_EXT_CMDID, cmd->vdev_id, 0); 7577 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 7578 WMI_REQUEST_STATS_EXT_CMDID); 7579 if (QDF_IS_STATUS_ERROR(ret)) { 7580 wmi_err("Failed to send notify cmd ret = %d", ret); 7581 wmi_buf_free(buf); 7582 } 7583 7584 return ret; 7585 } 7586 7587 /** 7588 * send_process_dhcpserver_offload_cmd_tlv() - enable DHCP server offload 7589 * @wmi_handle: wmi handle 7590 * @params: DHCP server offload info 7591 * 7592 * Return: QDF_STATUS_SUCCESS for success or error code 7593 */ 7594 static QDF_STATUS 7595 send_process_dhcpserver_offload_cmd_tlv(wmi_unified_t wmi_handle, 7596 struct dhcp_offload_info_params *params) 7597 { 7598 wmi_set_dhcp_server_offload_cmd_fixed_param *cmd; 7599 wmi_buf_t buf; 7600 QDF_STATUS status; 7601 7602 buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd)); 7603 if (!buf) 7604 return QDF_STATUS_E_NOMEM; 7605 7606 cmd = (wmi_set_dhcp_server_offload_cmd_fixed_param *) wmi_buf_data(buf); 7607 7608 WMITLV_SET_HDR(&cmd->tlv_header, 7609 WMITLV_TAG_STRUC_wmi_set_dhcp_server_offload_cmd_fixed_param, 7610 WMITLV_GET_STRUCT_TLVLEN 7611 (wmi_set_dhcp_server_offload_cmd_fixed_param)); 7612 cmd->vdev_id = params->vdev_id; 7613 cmd->enable = params->dhcp_offload_enabled; 7614 cmd->num_client = params->dhcp_client_num; 7615 cmd->srv_ipv4 = params->dhcp_srv_addr; 7616 cmd->start_lsb = 0; 7617 wmi_mtrace(WMI_SET_DHCP_SERVER_OFFLOAD_CMDID, cmd->vdev_id, 0); 7618 status = wmi_unified_cmd_send(wmi_handle, buf, 7619 sizeof(*cmd), 7620 WMI_SET_DHCP_SERVER_OFFLOAD_CMDID); 7621 if (QDF_IS_STATUS_ERROR(status)) { 7622 wmi_err("Failed to send set_dhcp_server_offload cmd"); 7623 wmi_buf_free(buf); 7624 return QDF_STATUS_E_FAILURE; 7625 } 7626 wmi_debug("Set dhcp server offload to vdevId %d", params->vdev_id); 7627 7628 return status; 7629 } 7630 7631 /** 7632 * send_pdev_set_regdomain_cmd_tlv() - send set regdomain command to fw 7633 * @wmi_handle: wmi handle 7634 * @param: pointer to pdev regdomain params 7635 * 7636 * Return: QDF_STATUS_SUCCESS for success or error code 7637 */ 7638 static QDF_STATUS 7639 send_pdev_set_regdomain_cmd_tlv(wmi_unified_t wmi_handle, 7640 struct pdev_set_regdomain_params *param) 7641 { 7642 wmi_buf_t buf; 7643 wmi_pdev_set_regdomain_cmd_fixed_param *cmd; 7644 int32_t len = sizeof(*cmd); 7645 7646 buf = wmi_buf_alloc(wmi_handle, len); 7647 if (!buf) 7648 return QDF_STATUS_E_NOMEM; 7649 7650 cmd = (wmi_pdev_set_regdomain_cmd_fixed_param *) wmi_buf_data(buf); 7651 WMITLV_SET_HDR(&cmd->tlv_header, 7652 WMITLV_TAG_STRUC_wmi_pdev_set_regdomain_cmd_fixed_param, 7653 WMITLV_GET_STRUCT_TLVLEN 7654 (wmi_pdev_set_regdomain_cmd_fixed_param)); 7655 7656 cmd->reg_domain = param->currentRDinuse; 7657 cmd->reg_domain_2G = param->currentRD2G; 7658 cmd->reg_domain_5G = param->currentRD5G; 7659 cmd->conformance_test_limit_2G = param->ctl_2G; 7660 cmd->conformance_test_limit_5G = param->ctl_5G; 7661 cmd->dfs_domain = param->dfsDomain; 7662 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 7663 wmi_handle, 7664 param->pdev_id); 7665 7666 wmi_mtrace(WMI_PDEV_SET_REGDOMAIN_CMDID, NO_SESSION, 0); 7667 if (wmi_unified_cmd_send(wmi_handle, buf, len, 7668 WMI_PDEV_SET_REGDOMAIN_CMDID)) { 7669 wmi_err("Failed to send pdev set regdomain command"); 7670 wmi_buf_free(buf); 7671 return QDF_STATUS_E_FAILURE; 7672 } 7673 7674 return QDF_STATUS_SUCCESS; 7675 } 7676 7677 /** 7678 * send_regdomain_info_to_fw_cmd_tlv() - send regdomain info to fw 7679 * @wmi_handle: wmi handle 7680 * @reg_dmn: reg domain 7681 * @regdmn2G: 2G reg domain 7682 * @regdmn5G: 5G reg domain 7683 * @ctl2G: 2G test limit 7684 * @ctl5G: 5G test limit 7685 * 7686 * Return: none 7687 */ 7688 static QDF_STATUS send_regdomain_info_to_fw_cmd_tlv(wmi_unified_t wmi_handle, 7689 uint32_t reg_dmn, uint16_t regdmn2G, 7690 uint16_t regdmn5G, uint8_t ctl2G, 7691 uint8_t ctl5G) 7692 { 7693 wmi_buf_t buf; 7694 wmi_pdev_set_regdomain_cmd_fixed_param *cmd; 7695 int32_t len = sizeof(*cmd); 7696 7697 7698 buf = wmi_buf_alloc(wmi_handle, len); 7699 if (!buf) 7700 return QDF_STATUS_E_NOMEM; 7701 7702 cmd = (wmi_pdev_set_regdomain_cmd_fixed_param *) wmi_buf_data(buf); 7703 WMITLV_SET_HDR(&cmd->tlv_header, 7704 WMITLV_TAG_STRUC_wmi_pdev_set_regdomain_cmd_fixed_param, 7705 WMITLV_GET_STRUCT_TLVLEN 7706 (wmi_pdev_set_regdomain_cmd_fixed_param)); 7707 cmd->reg_domain = reg_dmn; 7708 cmd->reg_domain_2G = regdmn2G; 7709 cmd->reg_domain_5G = regdmn5G; 7710 cmd->conformance_test_limit_2G = ctl2G; 7711 cmd->conformance_test_limit_5G = ctl5G; 7712 7713 wmi_debug("regd = %x, regd_2g = %x, regd_5g = %x, ctl_2g = %x, ctl_5g = %x", 7714 cmd->reg_domain, cmd->reg_domain_2G, cmd->reg_domain_5G, 7715 cmd->conformance_test_limit_2G, 7716 cmd->conformance_test_limit_5G); 7717 7718 wmi_mtrace(WMI_PDEV_SET_REGDOMAIN_CMDID, NO_SESSION, 0); 7719 if (wmi_unified_cmd_send(wmi_handle, buf, len, 7720 WMI_PDEV_SET_REGDOMAIN_CMDID)) { 7721 wmi_err("Failed to send pdev set regdomain command"); 7722 wmi_buf_free(buf); 7723 return QDF_STATUS_E_FAILURE; 7724 } 7725 7726 return QDF_STATUS_SUCCESS; 7727 } 7728 7729 /** 7730 * copy_custom_aggr_bitmap() - copies host side bitmap using FW APIs 7731 * @param: param sent from the host side 7732 * @cmd: param to be sent to the fw side 7733 */ 7734 static inline void copy_custom_aggr_bitmap( 7735 struct set_custom_aggr_size_params *param, 7736 wmi_vdev_set_custom_aggr_size_cmd_fixed_param *cmd) 7737 { 7738 WMI_VDEV_CUSTOM_AGGR_AC_SET(cmd->enable_bitmap, 7739 param->ac); 7740 WMI_VDEV_CUSTOM_AGGR_TYPE_SET(cmd->enable_bitmap, 7741 param->aggr_type); 7742 WMI_VDEV_CUSTOM_TX_AGGR_SZ_DIS_SET(cmd->enable_bitmap, 7743 param->tx_aggr_size_disable); 7744 WMI_VDEV_CUSTOM_RX_AGGR_SZ_DIS_SET(cmd->enable_bitmap, 7745 param->rx_aggr_size_disable); 7746 WMI_VDEV_CUSTOM_TX_AC_EN_SET(cmd->enable_bitmap, 7747 param->tx_ac_enable); 7748 WMI_VDEV_CUSTOM_AGGR_256_BA_EN_SET(cmd->enable_bitmap, 7749 param->aggr_ba_enable); 7750 } 7751 7752 /** 7753 * send_vdev_set_custom_aggr_size_cmd_tlv() - custom aggr size param in fw 7754 * @wmi_handle: wmi handle 7755 * @param: pointer to hold custom aggr size params 7756 * 7757 * Return: QDF_STATUS_SUCCESS for success or error code 7758 */ 7759 static QDF_STATUS send_vdev_set_custom_aggr_size_cmd_tlv( 7760 wmi_unified_t wmi_handle, 7761 struct set_custom_aggr_size_params *param) 7762 { 7763 wmi_vdev_set_custom_aggr_size_cmd_fixed_param *cmd; 7764 wmi_buf_t buf; 7765 int32_t len = sizeof(*cmd); 7766 7767 buf = wmi_buf_alloc(wmi_handle, len); 7768 if (!buf) 7769 return QDF_STATUS_E_FAILURE; 7770 7771 cmd = (wmi_vdev_set_custom_aggr_size_cmd_fixed_param *) 7772 wmi_buf_data(buf); 7773 WMITLV_SET_HDR(&cmd->tlv_header, 7774 WMITLV_TAG_STRUC_wmi_vdev_set_custom_aggr_size_cmd_fixed_param, 7775 WMITLV_GET_STRUCT_TLVLEN( 7776 wmi_vdev_set_custom_aggr_size_cmd_fixed_param)); 7777 cmd->vdev_id = param->vdev_id; 7778 cmd->tx_aggr_size = param->tx_aggr_size; 7779 cmd->rx_aggr_size = param->rx_aggr_size; 7780 copy_custom_aggr_bitmap(param, cmd); 7781 7782 wmi_debug("Set custom aggr: vdev id=0x%X, tx aggr size=0x%X " 7783 "rx_aggr_size=0x%X access category=0x%X, agg_type=0x%X " 7784 "tx_aggr_size_disable=0x%X, rx_aggr_size_disable=0x%X " 7785 "tx_ac_enable=0x%X", 7786 param->vdev_id, param->tx_aggr_size, param->rx_aggr_size, 7787 param->ac, param->aggr_type, param->tx_aggr_size_disable, 7788 param->rx_aggr_size_disable, param->tx_ac_enable); 7789 7790 wmi_mtrace(WMI_VDEV_SET_CUSTOM_AGGR_SIZE_CMDID, cmd->vdev_id, 0); 7791 if (wmi_unified_cmd_send(wmi_handle, buf, len, 7792 WMI_VDEV_SET_CUSTOM_AGGR_SIZE_CMDID)) { 7793 wmi_err("Setting custom aggregation size failed"); 7794 wmi_buf_free(buf); 7795 return QDF_STATUS_E_FAILURE; 7796 } 7797 7798 return QDF_STATUS_SUCCESS; 7799 } 7800 7801 /** 7802 * send_vdev_set_qdepth_thresh_cmd_tlv() - WMI set qdepth threshold 7803 * @wmi_handle: handle to WMI. 7804 * @param: pointer to tx antenna param 7805 * 7806 * Return: QDF_STATUS_SUCCESS for success or error code 7807 */ 7808 7809 static QDF_STATUS send_vdev_set_qdepth_thresh_cmd_tlv(wmi_unified_t wmi_handle, 7810 struct set_qdepth_thresh_params *param) 7811 { 7812 wmi_peer_tid_msduq_qdepth_thresh_update_cmd_fixed_param *cmd; 7813 wmi_msduq_qdepth_thresh_update *cmd_update; 7814 wmi_buf_t buf; 7815 int32_t len = 0; 7816 int i; 7817 uint8_t *buf_ptr; 7818 QDF_STATUS ret; 7819 7820 if (param->num_of_msduq_updates > QDEPTH_THRESH_MAX_UPDATES) { 7821 wmi_err("Invalid Update Count!"); 7822 return QDF_STATUS_E_INVAL; 7823 } 7824 7825 len = sizeof(*cmd) + WMI_TLV_HDR_SIZE; 7826 len += (sizeof(wmi_msduq_qdepth_thresh_update) * 7827 param->num_of_msduq_updates); 7828 buf = wmi_buf_alloc(wmi_handle, len); 7829 7830 if (!buf) 7831 return QDF_STATUS_E_NOMEM; 7832 7833 buf_ptr = (uint8_t *)wmi_buf_data(buf); 7834 cmd = (wmi_peer_tid_msduq_qdepth_thresh_update_cmd_fixed_param *) 7835 buf_ptr; 7836 7837 WMITLV_SET_HDR(&cmd->tlv_header, 7838 WMITLV_TAG_STRUC_wmi_peer_tid_msduq_qdepth_thresh_update_cmd_fixed_param 7839 , WMITLV_GET_STRUCT_TLVLEN( 7840 wmi_peer_tid_msduq_qdepth_thresh_update_cmd_fixed_param)); 7841 7842 cmd->pdev_id = 7843 wmi_handle->ops->convert_pdev_id_host_to_target( 7844 wmi_handle, 7845 param->pdev_id); 7846 cmd->vdev_id = param->vdev_id; 7847 WMI_CHAR_ARRAY_TO_MAC_ADDR(param->mac_addr, &cmd->peer_mac_address); 7848 cmd->num_of_msduq_updates = param->num_of_msduq_updates; 7849 7850 buf_ptr += sizeof( 7851 wmi_peer_tid_msduq_qdepth_thresh_update_cmd_fixed_param); 7852 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 7853 param->num_of_msduq_updates * 7854 sizeof(wmi_msduq_qdepth_thresh_update)); 7855 buf_ptr += WMI_TLV_HDR_SIZE; 7856 cmd_update = (wmi_msduq_qdepth_thresh_update *)buf_ptr; 7857 7858 for (i = 0; i < cmd->num_of_msduq_updates; i++) { 7859 WMITLV_SET_HDR(&cmd_update->tlv_header, 7860 WMITLV_TAG_STRUC_wmi_msduq_qdepth_thresh_update, 7861 WMITLV_GET_STRUCT_TLVLEN( 7862 wmi_msduq_qdepth_thresh_update)); 7863 cmd_update->tid_num = param->update_params[i].tid_num; 7864 cmd_update->msduq_update_mask = 7865 param->update_params[i].msduq_update_mask; 7866 cmd_update->qdepth_thresh_value = 7867 param->update_params[i].qdepth_thresh_value; 7868 wmi_debug("Set QDepth Threshold: vdev=0x%X pdev=0x%X, tid=0x%X " 7869 "mac_addr_upper4=%X, mac_addr_lower2:%X," 7870 " update mask=0x%X thresh val=0x%X", 7871 cmd->vdev_id, cmd->pdev_id, cmd_update->tid_num, 7872 cmd->peer_mac_address.mac_addr31to0, 7873 cmd->peer_mac_address.mac_addr47to32, 7874 cmd_update->msduq_update_mask, 7875 cmd_update->qdepth_thresh_value); 7876 cmd_update++; 7877 } 7878 7879 wmi_mtrace(WMI_PEER_TID_MSDUQ_QDEPTH_THRESH_UPDATE_CMDID, 7880 cmd->vdev_id, 0); 7881 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 7882 WMI_PEER_TID_MSDUQ_QDEPTH_THRESH_UPDATE_CMDID); 7883 7884 if (ret != 0) { 7885 wmi_err("Failed to send WMI_PEER_TID_MSDUQ_QDEPTH_THRESH_UPDATE_CMDID"); 7886 wmi_buf_free(buf); 7887 } 7888 7889 return ret; 7890 } 7891 7892 /** 7893 * send_set_vap_dscp_tid_map_cmd_tlv() - send vap dscp tid map cmd to fw 7894 * @wmi_handle: wmi handle 7895 * @param: pointer to hold vap dscp tid map param 7896 * 7897 * Return: QDF_STATUS_SUCCESS for success or error code 7898 */ 7899 static QDF_STATUS 7900 send_set_vap_dscp_tid_map_cmd_tlv(wmi_unified_t wmi_handle, 7901 struct vap_dscp_tid_map_params *param) 7902 { 7903 wmi_buf_t buf; 7904 wmi_vdev_set_dscp_tid_map_cmd_fixed_param *cmd; 7905 int32_t len = sizeof(*cmd); 7906 7907 buf = wmi_buf_alloc(wmi_handle, len); 7908 if (!buf) 7909 return QDF_STATUS_E_FAILURE; 7910 7911 cmd = (wmi_vdev_set_dscp_tid_map_cmd_fixed_param *)wmi_buf_data(buf); 7912 qdf_mem_copy(cmd->dscp_to_tid_map, param->dscp_to_tid_map, 7913 sizeof(uint32_t) * WMI_DSCP_MAP_MAX); 7914 7915 cmd->vdev_id = param->vdev_id; 7916 cmd->enable_override = 0; 7917 7918 wmi_debug("Setting dscp for vap id: %d", cmd->vdev_id); 7919 wmi_mtrace(WMI_VDEV_SET_DSCP_TID_MAP_CMDID, cmd->vdev_id, 0); 7920 if (wmi_unified_cmd_send(wmi_handle, buf, len, 7921 WMI_VDEV_SET_DSCP_TID_MAP_CMDID)) { 7922 wmi_err("Failed to set dscp cmd"); 7923 wmi_buf_free(buf); 7924 return QDF_STATUS_E_FAILURE; 7925 } 7926 7927 return QDF_STATUS_SUCCESS; 7928 } 7929 7930 /** 7931 * send_vdev_set_fwtest_param_cmd_tlv() - send fwtest param in fw 7932 * @wmi_handle: wmi handle 7933 * @param: pointer to hold fwtest param 7934 * 7935 * Return: QDF_STATUS_SUCCESS for success or error code 7936 */ 7937 static QDF_STATUS send_vdev_set_fwtest_param_cmd_tlv(wmi_unified_t wmi_handle, 7938 struct set_fwtest_params *param) 7939 { 7940 wmi_fwtest_set_param_cmd_fixed_param *cmd; 7941 wmi_buf_t buf; 7942 int32_t len = sizeof(*cmd); 7943 7944 buf = wmi_buf_alloc(wmi_handle, len); 7945 7946 if (!buf) 7947 return QDF_STATUS_E_FAILURE; 7948 7949 cmd = (wmi_fwtest_set_param_cmd_fixed_param *)wmi_buf_data(buf); 7950 WMITLV_SET_HDR(&cmd->tlv_header, 7951 WMITLV_TAG_STRUC_wmi_fwtest_set_param_cmd_fixed_param, 7952 WMITLV_GET_STRUCT_TLVLEN( 7953 wmi_fwtest_set_param_cmd_fixed_param)); 7954 cmd->param_id = param->arg; 7955 cmd->param_value = param->value; 7956 7957 wmi_mtrace(WMI_FWTEST_CMDID, NO_SESSION, 0); 7958 if (wmi_unified_cmd_send(wmi_handle, buf, len, WMI_FWTEST_CMDID)) { 7959 wmi_err("Setting FW test param failed"); 7960 wmi_buf_free(buf); 7961 return QDF_STATUS_E_FAILURE; 7962 } 7963 7964 return QDF_STATUS_SUCCESS; 7965 } 7966 7967 /** 7968 * send_phyerr_disable_cmd_tlv() - WMI phyerr disable function 7969 * @wmi_handle: handle to WMI. 7970 * 7971 * Return: QDF_STATUS_SUCCESS for success or error code 7972 */ 7973 static QDF_STATUS send_phyerr_disable_cmd_tlv(wmi_unified_t wmi_handle) 7974 { 7975 wmi_pdev_dfs_disable_cmd_fixed_param *cmd; 7976 wmi_buf_t buf; 7977 QDF_STATUS ret; 7978 int32_t len; 7979 7980 len = sizeof(*cmd); 7981 7982 buf = wmi_buf_alloc(wmi_handle, len); 7983 if (!buf) 7984 return QDF_STATUS_E_FAILURE; 7985 7986 cmd = (wmi_pdev_dfs_disable_cmd_fixed_param *)wmi_buf_data(buf); 7987 WMITLV_SET_HDR(&cmd->tlv_header, 7988 WMITLV_TAG_STRUC_wmi_pdev_dfs_disable_cmd_fixed_param, 7989 WMITLV_GET_STRUCT_TLVLEN( 7990 wmi_pdev_dfs_disable_cmd_fixed_param)); 7991 /* Filling it with WMI_PDEV_ID_SOC for now */ 7992 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 7993 wmi_handle, 7994 WMI_HOST_PDEV_ID_SOC); 7995 7996 wmi_mtrace(WMI_PDEV_DFS_DISABLE_CMDID, NO_SESSION, 0); 7997 ret = wmi_unified_cmd_send(wmi_handle, buf, sizeof(*cmd), 7998 WMI_PDEV_DFS_DISABLE_CMDID); 7999 8000 if (ret != 0) { 8001 wmi_err("Sending PDEV DFS disable cmd failed"); 8002 wmi_buf_free(buf); 8003 } 8004 8005 return ret; 8006 } 8007 8008 /** 8009 * send_phyerr_enable_cmd_tlv() - WMI phyerr disable function 8010 * @wmi_handle: handle to WMI. 8011 * 8012 * Return: QDF_STATUS_SUCCESS for success or error code 8013 */ 8014 static QDF_STATUS send_phyerr_enable_cmd_tlv(wmi_unified_t wmi_handle) 8015 { 8016 wmi_pdev_dfs_enable_cmd_fixed_param *cmd; 8017 wmi_buf_t buf; 8018 QDF_STATUS ret; 8019 int32_t len; 8020 8021 len = sizeof(*cmd); 8022 8023 buf = wmi_buf_alloc(wmi_handle, len); 8024 if (!buf) 8025 return QDF_STATUS_E_FAILURE; 8026 8027 cmd = (wmi_pdev_dfs_enable_cmd_fixed_param *)wmi_buf_data(buf); 8028 WMITLV_SET_HDR(&cmd->tlv_header, 8029 WMITLV_TAG_STRUC_wmi_pdev_dfs_enable_cmd_fixed_param, 8030 WMITLV_GET_STRUCT_TLVLEN( 8031 wmi_pdev_dfs_enable_cmd_fixed_param)); 8032 /* Reserved for future use */ 8033 cmd->reserved0 = 0; 8034 8035 wmi_mtrace(WMI_PDEV_DFS_ENABLE_CMDID, NO_SESSION, 0); 8036 ret = wmi_unified_cmd_send(wmi_handle, buf, sizeof(*cmd), 8037 WMI_PDEV_DFS_ENABLE_CMDID); 8038 8039 if (ret != 0) { 8040 wmi_err("Sending PDEV DFS enable cmd failed"); 8041 wmi_buf_free(buf); 8042 } 8043 8044 return ret; 8045 } 8046 8047 /** 8048 * send_periodic_chan_stats_config_cmd_tlv() - send periodic chan stats cmd 8049 * to fw 8050 * @wmi_handle: wmi handle 8051 * @param: pointer to hold periodic chan stats param 8052 * 8053 * Return: QDF_STATUS_SUCCESS for success or error code 8054 */ 8055 static QDF_STATUS 8056 send_periodic_chan_stats_config_cmd_tlv(wmi_unified_t wmi_handle, 8057 struct periodic_chan_stats_params *param) 8058 { 8059 wmi_set_periodic_channel_stats_config_fixed_param *cmd; 8060 wmi_buf_t buf; 8061 QDF_STATUS ret; 8062 int32_t len; 8063 8064 len = sizeof(*cmd); 8065 8066 buf = wmi_buf_alloc(wmi_handle, len); 8067 if (!buf) 8068 return QDF_STATUS_E_FAILURE; 8069 8070 cmd = (wmi_set_periodic_channel_stats_config_fixed_param *) 8071 wmi_buf_data(buf); 8072 WMITLV_SET_HDR(&cmd->tlv_header, 8073 WMITLV_TAG_STRUC_wmi_set_periodic_channel_stats_config_fixed_param, 8074 WMITLV_GET_STRUCT_TLVLEN( 8075 wmi_set_periodic_channel_stats_config_fixed_param)); 8076 cmd->enable = param->enable; 8077 cmd->stats_period = param->stats_period; 8078 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 8079 wmi_handle, 8080 param->pdev_id); 8081 8082 wmi_mtrace(WMI_SET_PERIODIC_CHANNEL_STATS_CONFIG_CMDID, NO_SESSION, 0); 8083 ret = wmi_unified_cmd_send(wmi_handle, buf, sizeof(*cmd), 8084 WMI_SET_PERIODIC_CHANNEL_STATS_CONFIG_CMDID); 8085 8086 if (ret != 0) { 8087 wmi_err("Sending periodic chan stats config failed"); 8088 wmi_buf_free(buf); 8089 } 8090 8091 return ret; 8092 } 8093 8094 #ifdef WLAN_IOT_SIM_SUPPORT 8095 /** 8096 * send_simulation_test_cmd_tlv() - send simulation test command to fw 8097 * 8098 * @wmi_handle: wmi handle 8099 * @param: pointer to hold simulation test parameter 8100 * 8101 * Return: QDF_STATUS_SUCCESS for success or error code 8102 */ 8103 static QDF_STATUS send_simulation_test_cmd_tlv(wmi_unified_t wmi_handle, 8104 struct simulation_test_params 8105 *param) 8106 { 8107 wmi_simulation_test_cmd_fixed_param *cmd; 8108 u32 wmi_buf_len; 8109 wmi_buf_t buf; 8110 u8 *buf_ptr; 8111 u32 aligned_len = 0; 8112 8113 wmi_buf_len = sizeof(*cmd); 8114 if (param->buf_len) { 8115 aligned_len = roundup(param->buf_len, sizeof(A_UINT32)); 8116 wmi_buf_len += WMI_TLV_HDR_SIZE + aligned_len; 8117 } 8118 8119 buf = wmi_buf_alloc(wmi_handle, wmi_buf_len); 8120 if (!buf) { 8121 wmi_err("wmi_buf_alloc failed"); 8122 return QDF_STATUS_E_NOMEM; 8123 } 8124 8125 buf_ptr = wmi_buf_data(buf); 8126 cmd = (wmi_simulation_test_cmd_fixed_param *)buf_ptr; 8127 WMITLV_SET_HDR(&cmd->tlv_header, 8128 WMITLV_TAG_STRUC_wmi_simulation_test_cmd_fixed_param, 8129 WMITLV_GET_STRUCT_TLVLEN( 8130 wmi_simulation_test_cmd_fixed_param)); 8131 cmd->pdev_id = param->pdev_id; 8132 cmd->vdev_id = param->vdev_id; 8133 WMI_CHAR_ARRAY_TO_MAC_ADDR(param->peer_mac, &cmd->peer_macaddr); 8134 cmd->test_cmd_type = param->test_cmd_type; 8135 cmd->test_subcmd_type = param->test_subcmd_type; 8136 WMI_SIM_FRAME_TYPE_SET(cmd->frame_type_subtype_seq, param->frame_type); 8137 WMI_SIM_FRAME_SUBTYPE_SET(cmd->frame_type_subtype_seq, 8138 param->frame_subtype); 8139 WMI_SIM_FRAME_SEQ_SET(cmd->frame_type_subtype_seq, param->seq); 8140 WMI_SIM_FRAME_OFFSET_SET(cmd->frame_offset_length, param->offset); 8141 WMI_SIM_FRAME_LENGTH_SET(cmd->frame_offset_length, param->frame_length); 8142 cmd->buf_len = param->buf_len; 8143 8144 if (param->buf_len) { 8145 buf_ptr += sizeof(*cmd); 8146 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, aligned_len); 8147 buf_ptr += WMI_TLV_HDR_SIZE; 8148 qdf_mem_copy(buf_ptr, param->bufp, param->buf_len); 8149 } 8150 8151 if (wmi_unified_cmd_send(wmi_handle, buf, wmi_buf_len, 8152 WMI_SIMULATION_TEST_CMDID)) { 8153 wmi_err("Failed to send test simulation cmd"); 8154 wmi_buf_free(buf); 8155 return QDF_STATUS_E_FAILURE; 8156 } 8157 8158 return QDF_STATUS_SUCCESS; 8159 } 8160 #endif 8161 8162 #ifdef WLAN_FEATURE_11BE 8163 #define WLAN_PHY_CH_WIDTH_320MHZ CH_WIDTH_320MHZ 8164 #else 8165 #define WLAN_PHY_CH_WIDTH_320MHZ CH_WIDTH_INVALID 8166 #endif 8167 enum phy_ch_width wmi_map_ch_width(A_UINT32 wmi_width) 8168 { 8169 switch (wmi_width) { 8170 case WMI_CHAN_WIDTH_20: 8171 return CH_WIDTH_20MHZ; 8172 case WMI_CHAN_WIDTH_40: 8173 return CH_WIDTH_40MHZ; 8174 case WMI_CHAN_WIDTH_80: 8175 return CH_WIDTH_80MHZ; 8176 case WMI_CHAN_WIDTH_160: 8177 return CH_WIDTH_160MHZ; 8178 case WMI_CHAN_WIDTH_80P80: 8179 return CH_WIDTH_80P80MHZ; 8180 case WMI_CHAN_WIDTH_5: 8181 return CH_WIDTH_5MHZ; 8182 case WMI_CHAN_WIDTH_10: 8183 return CH_WIDTH_10MHZ; 8184 case WMI_CHAN_WIDTH_320: 8185 return WLAN_PHY_CH_WIDTH_320MHZ; 8186 default: 8187 return CH_WIDTH_INVALID; 8188 } 8189 } 8190 8191 /* 8192 * convert_host_to_target_ch_width()- map host channel width(enum phy_ch_width) 8193 * to wmi channel width 8194 * @chan_width: Host channel width 8195 * 8196 * Return: wmi channel width 8197 */ 8198 static 8199 wmi_channel_width convert_host_to_target_ch_width(uint32_t chan_width) 8200 { 8201 switch (chan_width) { 8202 case CH_WIDTH_20MHZ: 8203 return WMI_CHAN_WIDTH_20; 8204 case CH_WIDTH_40MHZ: 8205 return WMI_CHAN_WIDTH_40; 8206 case CH_WIDTH_80MHZ: 8207 return WMI_CHAN_WIDTH_80; 8208 case CH_WIDTH_160MHZ: 8209 return WMI_CHAN_WIDTH_160; 8210 case CH_WIDTH_80P80MHZ: 8211 return WMI_CHAN_WIDTH_80P80; 8212 case CH_WIDTH_5MHZ: 8213 return WMI_CHAN_WIDTH_5; 8214 case CH_WIDTH_10MHZ: 8215 return WMI_CHAN_WIDTH_10; 8216 #ifdef WLAN_FEATURE_11BE 8217 case CH_WIDTH_320MHZ: 8218 return WMI_CHAN_WIDTH_320; 8219 #endif 8220 default: 8221 return WMI_CHAN_WIDTH_MAX; 8222 } 8223 } 8224 8225 /** 8226 * send_vdev_spectral_configure_cmd_tlv() - send VDEV spectral configure 8227 * command to fw 8228 * @wmi_handle: wmi handle 8229 * @param: pointer to hold spectral config parameter 8230 * 8231 * Return: QDF_STATUS_SUCCESS for success or error code 8232 */ 8233 static QDF_STATUS send_vdev_spectral_configure_cmd_tlv(wmi_unified_t wmi_handle, 8234 struct vdev_spectral_configure_params *param) 8235 { 8236 wmi_vdev_spectral_configure_cmd_fixed_param *cmd; 8237 wmi_buf_t buf; 8238 QDF_STATUS ret; 8239 int32_t len; 8240 8241 len = sizeof(*cmd); 8242 buf = wmi_buf_alloc(wmi_handle, len); 8243 if (!buf) 8244 return QDF_STATUS_E_FAILURE; 8245 8246 cmd = (wmi_vdev_spectral_configure_cmd_fixed_param *)wmi_buf_data(buf); 8247 WMITLV_SET_HDR(&cmd->tlv_header, 8248 WMITLV_TAG_STRUC_wmi_vdev_spectral_configure_cmd_fixed_param, 8249 WMITLV_GET_STRUCT_TLVLEN( 8250 wmi_vdev_spectral_configure_cmd_fixed_param)); 8251 8252 cmd->vdev_id = param->vdev_id; 8253 cmd->spectral_scan_count = param->count; 8254 cmd->spectral_scan_period = param->period; 8255 cmd->spectral_scan_priority = param->spectral_pri; 8256 cmd->spectral_scan_fft_size = param->fft_size; 8257 cmd->spectral_scan_gc_ena = param->gc_enable; 8258 cmd->spectral_scan_restart_ena = param->restart_enable; 8259 cmd->spectral_scan_noise_floor_ref = param->noise_floor_ref; 8260 cmd->spectral_scan_init_delay = param->init_delay; 8261 cmd->spectral_scan_nb_tone_thr = param->nb_tone_thr; 8262 cmd->spectral_scan_str_bin_thr = param->str_bin_thr; 8263 cmd->spectral_scan_wb_rpt_mode = param->wb_rpt_mode; 8264 cmd->spectral_scan_rssi_rpt_mode = param->rssi_rpt_mode; 8265 cmd->spectral_scan_rssi_thr = param->rssi_thr; 8266 cmd->spectral_scan_pwr_format = param->pwr_format; 8267 cmd->spectral_scan_rpt_mode = param->rpt_mode; 8268 cmd->spectral_scan_bin_scale = param->bin_scale; 8269 cmd->spectral_scan_dBm_adj = param->dbm_adj; 8270 cmd->spectral_scan_chn_mask = param->chn_mask; 8271 cmd->spectral_scan_mode = param->mode; 8272 cmd->spectral_scan_center_freq1 = param->center_freq1; 8273 cmd->spectral_scan_center_freq2 = param->center_freq2; 8274 cmd->spectral_scan_chan_width = 8275 convert_host_to_target_ch_width(param->chan_width); 8276 cmd->recapture_sample_on_gain_change = param->fft_recap; 8277 /* Not used, fill with zeros */ 8278 cmd->spectral_scan_chan_freq = 0; 8279 8280 wmi_mtrace(WMI_VDEV_SPECTRAL_SCAN_CONFIGURE_CMDID, cmd->vdev_id, 0); 8281 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 8282 WMI_VDEV_SPECTRAL_SCAN_CONFIGURE_CMDID); 8283 8284 if (ret != 0) { 8285 wmi_err("Sending set quiet cmd failed"); 8286 wmi_buf_free(buf); 8287 } 8288 8289 wmi_debug("Sent WMI_VDEV_SPECTRAL_SCAN_CONFIGURE_CMDID"); 8290 wmi_debug("vdev_id: %u spectral_scan_count: %u", 8291 param->vdev_id, param->count); 8292 wmi_debug("spectral_scan_period: %u spectral_scan_priority: %u", 8293 param->period, param->spectral_pri); 8294 wmi_debug("spectral_fft_recapture_cap: %u", param->fft_recap); 8295 wmi_debug("spectral_scan_fft_size: %u spectral_scan_gc_ena: %u", 8296 param->fft_size, param->gc_enable); 8297 wmi_debug("spectral_scan_restart_ena: %u", param->restart_enable); 8298 wmi_debug("spectral_scan_noise_floor_ref: %u", param->noise_floor_ref); 8299 wmi_debug("spectral_scan_init_delay: %u", param->init_delay); 8300 wmi_debug("spectral_scan_nb_tone_thr: %u", param->nb_tone_thr); 8301 wmi_debug("spectral_scan_str_bin_thr: %u", param->str_bin_thr); 8302 wmi_debug("spectral_scan_wb_rpt_mode: %u", param->wb_rpt_mode); 8303 wmi_debug("spectral_scan_rssi_rpt_mode: %u", param->rssi_rpt_mode); 8304 wmi_debug("spectral_scan_rssi_thr: %u spectral_scan_pwr_format: %u", 8305 param->rssi_thr, param->pwr_format); 8306 wmi_debug("spectral_scan_rpt_mode: %u spectral_scan_bin_scale: %u", 8307 param->rpt_mode, param->bin_scale); 8308 wmi_debug("spectral_scan_dBm_adj: %u spectral_scan_chn_mask: %u", 8309 param->dbm_adj, param->chn_mask); 8310 wmi_debug("spectral_scan_mode: %u spectral_scan_center_freq1: %u", 8311 param->mode, param->center_freq1); 8312 wmi_debug("spectral_scan_center_freq2: %u spectral_scan_chan_freq: %u", 8313 param->center_freq2, param->chan_freq); 8314 wmi_debug("spectral_scan_chan_width: %u Status: %d", 8315 param->chan_width, ret); 8316 8317 return ret; 8318 } 8319 8320 /** 8321 * send_vdev_spectral_enable_cmd_tlv() - send VDEV spectral configure 8322 * command to fw 8323 * @wmi_handle: wmi handle 8324 * @param: pointer to hold spectral enable parameter 8325 * 8326 * Return: QDF_STATUS_SUCCESS for success or error code 8327 */ 8328 static QDF_STATUS send_vdev_spectral_enable_cmd_tlv(wmi_unified_t wmi_handle, 8329 struct vdev_spectral_enable_params *param) 8330 { 8331 wmi_vdev_spectral_enable_cmd_fixed_param *cmd; 8332 wmi_buf_t buf; 8333 QDF_STATUS ret; 8334 int32_t len; 8335 8336 len = sizeof(*cmd); 8337 buf = wmi_buf_alloc(wmi_handle, len); 8338 if (!buf) 8339 return QDF_STATUS_E_FAILURE; 8340 8341 cmd = (wmi_vdev_spectral_enable_cmd_fixed_param *)wmi_buf_data(buf); 8342 WMITLV_SET_HDR(&cmd->tlv_header, 8343 WMITLV_TAG_STRUC_wmi_vdev_spectral_enable_cmd_fixed_param, 8344 WMITLV_GET_STRUCT_TLVLEN( 8345 wmi_vdev_spectral_enable_cmd_fixed_param)); 8346 8347 cmd->vdev_id = param->vdev_id; 8348 8349 if (param->active_valid) { 8350 cmd->trigger_cmd = param->active ? 1 : 2; 8351 /* 1: Trigger, 2: Clear Trigger */ 8352 } else { 8353 cmd->trigger_cmd = 0; /* 0: Ignore */ 8354 } 8355 8356 if (param->enabled_valid) { 8357 cmd->enable_cmd = param->enabled ? 1 : 2; 8358 /* 1: Enable 2: Disable */ 8359 } else { 8360 cmd->enable_cmd = 0; /* 0: Ignore */ 8361 } 8362 cmd->spectral_scan_mode = param->mode; 8363 8364 wmi_debug("vdev_id = %u trigger_cmd = %u enable_cmd = %u", 8365 cmd->vdev_id, cmd->trigger_cmd, cmd->enable_cmd); 8366 wmi_debug("spectral_scan_mode = %u", cmd->spectral_scan_mode); 8367 8368 wmi_mtrace(WMI_VDEV_SPECTRAL_SCAN_ENABLE_CMDID, cmd->vdev_id, 0); 8369 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 8370 WMI_VDEV_SPECTRAL_SCAN_ENABLE_CMDID); 8371 8372 if (ret != 0) { 8373 wmi_err("Sending scan enable CMD failed"); 8374 wmi_buf_free(buf); 8375 } 8376 8377 wmi_debug("Sent WMI_VDEV_SPECTRAL_SCAN_ENABLE_CMDID, Status: %d", 8378 ret); 8379 8380 return ret; 8381 } 8382 8383 #ifdef WLAN_CONV_SPECTRAL_ENABLE 8384 static QDF_STATUS 8385 extract_pdev_sscan_fw_cmd_fixed_param_tlv( 8386 wmi_unified_t wmi_handle, 8387 uint8_t *event, struct spectral_startscan_resp_params *param) 8388 { 8389 WMI_PDEV_SSCAN_FW_PARAM_EVENTID_param_tlvs *param_buf; 8390 wmi_pdev_sscan_fw_cmd_fixed_param *ev; 8391 8392 if (!wmi_handle) { 8393 wmi_err("WMI handle is null"); 8394 return QDF_STATUS_E_INVAL; 8395 } 8396 8397 if (!event) { 8398 wmi_err("WMI event is null"); 8399 return QDF_STATUS_E_INVAL; 8400 } 8401 8402 if (!param) { 8403 wmi_err("Spectral startscan response params is null"); 8404 return QDF_STATUS_E_INVAL; 8405 } 8406 8407 param_buf = (WMI_PDEV_SSCAN_FW_PARAM_EVENTID_param_tlvs *)event; 8408 if (!param_buf) 8409 return QDF_STATUS_E_INVAL; 8410 8411 ev = param_buf->fixed_param; 8412 if (!ev) 8413 return QDF_STATUS_E_INVAL; 8414 8415 param->pdev_id = wmi_handle->ops->convert_target_pdev_id_to_host( 8416 wmi_handle, 8417 ev->pdev_id); 8418 param->smode = ev->spectral_scan_mode; 8419 param->num_fft_bin_index = param_buf->num_fft_bin_index; 8420 param->num_det_info = param_buf->num_det_info; 8421 8422 wmi_debug("pdev id:%u smode:%u num_fft_bin_index:%u num_det_info:%u", 8423 ev->pdev_id, ev->spectral_scan_mode, 8424 param_buf->num_fft_bin_index, param_buf->num_det_info); 8425 8426 return QDF_STATUS_SUCCESS; 8427 } 8428 8429 static QDF_STATUS 8430 extract_pdev_sscan_fft_bin_index_tlv( 8431 wmi_unified_t wmi_handle, uint8_t *event, 8432 struct spectral_fft_bin_markers_160_165mhz *param) 8433 { 8434 WMI_PDEV_SSCAN_FW_PARAM_EVENTID_param_tlvs *param_buf; 8435 wmi_pdev_sscan_fft_bin_index *ev; 8436 8437 param_buf = (WMI_PDEV_SSCAN_FW_PARAM_EVENTID_param_tlvs *)event; 8438 if (!param_buf) 8439 return QDF_STATUS_E_INVAL; 8440 8441 ev = param_buf->fft_bin_index; 8442 if (!ev) 8443 return QDF_STATUS_E_INVAL; 8444 8445 param->start_pri80 = WMI_SSCAN_PRI80_START_BIN_GET(ev->pri80_bins); 8446 param->num_pri80 = WMI_SSCAN_PRI80_END_BIN_GET(ev->pri80_bins) - 8447 param->start_pri80 + 1; 8448 param->start_sec80 = WMI_SSCAN_SEC80_START_BIN_GET(ev->sec80_bins); 8449 param->num_sec80 = WMI_SSCAN_SEC80_END_BIN_GET(ev->sec80_bins) - 8450 param->start_sec80 + 1; 8451 param->start_5mhz = WMI_SSCAN_MID_5MHZ_START_BIN_GET(ev->mid_5mhz_bins); 8452 param->num_5mhz = WMI_SSCAN_MID_5MHZ_END_BIN_GET(ev->mid_5mhz_bins) - 8453 param->start_5mhz + 1; 8454 param->is_valid = true; 8455 8456 wmi_debug("start_pri80: %u num_pri80: %u start_sec80: %u num_sec80: %u start_5mhz: %u, num_5mhz: %u", 8457 param->start_pri80, param->num_pri80, 8458 param->start_sec80, param->num_sec80, 8459 param->start_5mhz, param->num_5mhz); 8460 8461 return QDF_STATUS_SUCCESS; 8462 } 8463 8464 /** 8465 * extract_pdev_spectral_session_chan_info_tlv() - Extract channel information 8466 * for a spectral scan session 8467 * @wmi_handle: handle to WMI. 8468 * @event: Event buffer 8469 * @chan_info: Spectral session channel information data structure to be filled 8470 * by this API 8471 * 8472 * Return: QDF_STATUS of operation 8473 */ 8474 static QDF_STATUS 8475 extract_pdev_spectral_session_chan_info_tlv( 8476 wmi_unified_t wmi_handle, void *event, 8477 struct spectral_session_chan_info *chan_info) 8478 { 8479 WMI_PDEV_SSCAN_FW_PARAM_EVENTID_param_tlvs *param_buf = event; 8480 wmi_pdev_sscan_chan_info *chan_info_tlv; 8481 8482 if (!param_buf) { 8483 wmi_err("param_buf is NULL"); 8484 return QDF_STATUS_E_NULL_VALUE; 8485 } 8486 8487 if (!chan_info) { 8488 wmi_err("chan_info is NULL"); 8489 return QDF_STATUS_E_NULL_VALUE; 8490 } 8491 8492 chan_info_tlv = param_buf->chan_info; 8493 if (!chan_info_tlv) { 8494 wmi_err("chan_info tlv is not present in the event"); 8495 return QDF_STATUS_E_NULL_VALUE; 8496 } 8497 8498 wmi_debug("operating_pri20_freq:%u operating_cfreq1:%u" 8499 "operating_cfreq2:%u operating_bw:%u" 8500 "operating_puncture_20mhz_bitmap:%u" 8501 "sscan_cfreq1:%u sscan_cfreq2:%u" 8502 "sscan_bw:%u sscan_puncture_20mhz_bitmap:%u", 8503 chan_info_tlv->operating_pri20_freq, 8504 chan_info_tlv->operating_cfreq1, 8505 chan_info_tlv->operating_cfreq2, chan_info_tlv->operating_bw, 8506 chan_info_tlv->operating_puncture_20mhz_bitmap, 8507 chan_info_tlv->sscan_cfreq1, chan_info_tlv->sscan_cfreq2, 8508 chan_info_tlv->sscan_bw, 8509 chan_info_tlv->sscan_puncture_20mhz_bitmap); 8510 8511 chan_info->operating_pri20_freq = 8512 (qdf_freq_t)chan_info_tlv->operating_pri20_freq; 8513 chan_info->operating_cfreq1 = 8514 (qdf_freq_t)chan_info_tlv->operating_cfreq1; 8515 chan_info->operating_cfreq2 = 8516 (qdf_freq_t)chan_info_tlv->operating_cfreq2; 8517 chan_info->operating_bw = wmi_map_ch_width(chan_info_tlv->operating_bw); 8518 chan_info->operating_puncture_20mhz_bitmap = 8519 chan_info_tlv->operating_puncture_20mhz_bitmap; 8520 8521 chan_info->sscan_cfreq1 = (qdf_freq_t)chan_info_tlv->sscan_cfreq1; 8522 chan_info->sscan_cfreq2 = (qdf_freq_t)chan_info_tlv->sscan_cfreq2; 8523 chan_info->sscan_bw = wmi_map_ch_width(chan_info_tlv->sscan_bw); 8524 chan_info->sscan_puncture_20mhz_bitmap = 8525 chan_info_tlv->sscan_puncture_20mhz_bitmap; 8526 8527 return QDF_STATUS_SUCCESS; 8528 } 8529 8530 static QDF_STATUS 8531 extract_pdev_spectral_session_detector_info_tlv( 8532 wmi_unified_t wmi_handle, void *event, 8533 struct spectral_session_det_info *det_info, uint8_t idx) 8534 { 8535 WMI_PDEV_SSCAN_FW_PARAM_EVENTID_param_tlvs *param_buf = event; 8536 wmi_pdev_sscan_per_detector_info *det_info_tlv; 8537 8538 if (!param_buf) { 8539 wmi_err("param_buf is NULL"); 8540 return QDF_STATUS_E_NULL_VALUE; 8541 } 8542 8543 if (!det_info) { 8544 wmi_err("chan_info is NULL"); 8545 return QDF_STATUS_E_NULL_VALUE; 8546 } 8547 8548 if (!param_buf->det_info) { 8549 wmi_err("det_info tlv is not present in the event"); 8550 return QDF_STATUS_E_NULL_VALUE; 8551 } 8552 8553 if (idx >= param_buf->num_det_info) { 8554 wmi_err("det_info index(%u) is greater than or equal to %u", 8555 idx, param_buf->num_det_info); 8556 return QDF_STATUS_E_FAILURE; 8557 } 8558 8559 det_info_tlv = ¶m_buf->det_info[idx]; 8560 8561 wmi_debug("det_info_idx: %u detector_id:%u start_freq:%u end_freq:%u", 8562 idx, det_info_tlv->detector_id, 8563 det_info_tlv->start_freq, det_info_tlv->end_freq); 8564 8565 det_info->det_id = det_info_tlv->detector_id; 8566 det_info->start_freq = (qdf_freq_t)det_info_tlv->start_freq; 8567 det_info->end_freq = (qdf_freq_t)det_info_tlv->end_freq; 8568 8569 return QDF_STATUS_SUCCESS; 8570 } 8571 8572 /** 8573 * extract_spectral_caps_fixed_param_tlv() - Extract fixed params from Spectral 8574 * capabilities WMI event 8575 * @wmi_handle: handle to WMI. 8576 * @event: Event buffer 8577 * @params: Spectral capabilities event parameters data structure to be filled 8578 * by this API 8579 * 8580 * Return: QDF_STATUS of operation 8581 */ 8582 static QDF_STATUS 8583 extract_spectral_caps_fixed_param_tlv( 8584 wmi_unified_t wmi_handle, void *event, 8585 struct spectral_capabilities_event_params *params) 8586 { 8587 WMI_SPECTRAL_CAPABILITIES_EVENTID_param_tlvs *param_buf = event; 8588 8589 if (!param_buf) { 8590 wmi_err("param_buf is NULL"); 8591 return QDF_STATUS_E_NULL_VALUE; 8592 } 8593 8594 if (!params) { 8595 wmi_err("event parameters is NULL"); 8596 return QDF_STATUS_E_NULL_VALUE; 8597 } 8598 8599 params->num_sscan_bw_caps = param_buf->num_sscan_bw_caps; 8600 params->num_fft_size_caps = param_buf->num_fft_size_caps; 8601 8602 wmi_debug("num_sscan_bw_caps:%u num_fft_size_caps:%u", 8603 params->num_sscan_bw_caps, params->num_fft_size_caps); 8604 8605 return QDF_STATUS_SUCCESS; 8606 } 8607 8608 /** 8609 * extract_spectral_scan_bw_caps_tlv() - Extract bandwidth caps from 8610 * Spectral capabilities WMI event 8611 * @wmi_handle: handle to WMI. 8612 * @event: Event buffer 8613 * @bw_caps: Data structure to be populated by this API after extraction 8614 * 8615 * Return: QDF_STATUS of operation 8616 */ 8617 static QDF_STATUS 8618 extract_spectral_scan_bw_caps_tlv( 8619 wmi_unified_t wmi_handle, void *event, 8620 struct spectral_scan_bw_capabilities *bw_caps) 8621 { 8622 WMI_SPECTRAL_CAPABILITIES_EVENTID_param_tlvs *param_buf = event; 8623 int idx; 8624 8625 if (!param_buf) { 8626 wmi_err("param_buf is NULL"); 8627 return QDF_STATUS_E_NULL_VALUE; 8628 } 8629 8630 if (!bw_caps) { 8631 wmi_err("bw_caps is null"); 8632 return QDF_STATUS_E_NULL_VALUE; 8633 } 8634 8635 for (idx = 0; idx < param_buf->num_sscan_bw_caps; idx++) { 8636 bw_caps[idx].pdev_id = 8637 wmi_handle->ops->convert_pdev_id_target_to_host( 8638 wmi_handle, 8639 param_buf->sscan_bw_caps[idx].pdev_id); 8640 bw_caps[idx].smode = param_buf->sscan_bw_caps[idx].sscan_mode; 8641 bw_caps[idx].operating_bw = wmi_map_ch_width( 8642 param_buf->sscan_bw_caps[idx].operating_bw); 8643 bw_caps[idx].supported_bws = 8644 param_buf->sscan_bw_caps[idx].supported_flags; 8645 8646 wmi_debug("bw_caps[%u]:: pdev_id:%u smode:%u" 8647 "operating_bw:%u supported_flags:0x%x", 8648 idx, param_buf->sscan_bw_caps[idx].pdev_id, 8649 param_buf->sscan_bw_caps[idx].sscan_mode, 8650 param_buf->sscan_bw_caps[idx].operating_bw, 8651 param_buf->sscan_bw_caps[idx].supported_flags); 8652 } 8653 8654 return QDF_STATUS_SUCCESS; 8655 } 8656 8657 /** 8658 * extract_spectral_fft_size_caps_tlv() - Extract FFT size caps from 8659 * Spectral capabilities WMI event 8660 * @wmi_handle: handle to WMI. 8661 * @event: Event buffer 8662 * @fft_size_caps: Data structure to be populated by this API after extraction 8663 * 8664 * Return: QDF_STATUS of operation 8665 */ 8666 static QDF_STATUS 8667 extract_spectral_fft_size_caps_tlv( 8668 wmi_unified_t wmi_handle, void *event, 8669 struct spectral_fft_size_capabilities *fft_size_caps) 8670 { 8671 WMI_SPECTRAL_CAPABILITIES_EVENTID_param_tlvs *param_buf = event; 8672 int idx; 8673 8674 if (!param_buf) { 8675 wmi_err("param_buf is NULL"); 8676 return QDF_STATUS_E_NULL_VALUE; 8677 } 8678 8679 if (!fft_size_caps) { 8680 wmi_err("fft size caps is NULL"); 8681 return QDF_STATUS_E_NULL_VALUE; 8682 } 8683 8684 for (idx = 0; idx < param_buf->num_fft_size_caps; idx++) { 8685 fft_size_caps[idx].pdev_id = 8686 wmi_handle->ops->convert_pdev_id_target_to_host( 8687 wmi_handle, 8688 param_buf->fft_size_caps[idx].pdev_id); 8689 fft_size_caps[idx].sscan_bw = wmi_map_ch_width( 8690 param_buf->fft_size_caps[idx].sscan_bw); 8691 fft_size_caps[idx].supports_fft_sizes = 8692 param_buf->fft_size_caps[idx].supported_flags; 8693 8694 wmi_debug("fft_size_caps[%u]:: pdev_id:%u sscan_bw:%u" 8695 "supported_flags:0x%x", 8696 idx, param_buf->fft_size_caps[idx].pdev_id, 8697 param_buf->fft_size_caps[idx].sscan_bw, 8698 param_buf->fft_size_caps[idx].supported_flags); 8699 } 8700 8701 return QDF_STATUS_SUCCESS; 8702 } 8703 #endif /* WLAN_CONV_SPECTRAL_ENABLE */ 8704 8705 #ifdef FEATURE_WPSS_THERMAL_MITIGATION 8706 static inline void 8707 wmi_fill_client_id_priority(wmi_therm_throt_config_request_fixed_param *tt_conf, 8708 struct thermal_mitigation_params *param) 8709 { 8710 tt_conf->client_id = param->client_id; 8711 tt_conf->priority = param->priority; 8712 } 8713 #else 8714 static inline void 8715 wmi_fill_client_id_priority(wmi_therm_throt_config_request_fixed_param *tt_conf, 8716 struct thermal_mitigation_params *param) 8717 { 8718 } 8719 #endif 8720 8721 /** 8722 * send_thermal_mitigation_param_cmd_tlv() - configure thermal mitigation params 8723 * @wmi_handle : handle to WMI. 8724 * @param : pointer to hold thermal mitigation param 8725 * 8726 * Return: QDF_STATUS_SUCCESS for success or error code 8727 */ 8728 static QDF_STATUS send_thermal_mitigation_param_cmd_tlv( 8729 wmi_unified_t wmi_handle, 8730 struct thermal_mitigation_params *param) 8731 { 8732 wmi_therm_throt_config_request_fixed_param *tt_conf = NULL; 8733 wmi_therm_throt_level_config_info *lvl_conf = NULL; 8734 wmi_buf_t buf = NULL; 8735 uint8_t *buf_ptr = NULL; 8736 int error; 8737 int32_t len; 8738 int i; 8739 8740 len = sizeof(*tt_conf) + WMI_TLV_HDR_SIZE + 8741 param->num_thermal_conf * 8742 sizeof(wmi_therm_throt_level_config_info); 8743 8744 buf = wmi_buf_alloc(wmi_handle, len); 8745 if (!buf) 8746 return QDF_STATUS_E_NOMEM; 8747 8748 tt_conf = (wmi_therm_throt_config_request_fixed_param *) wmi_buf_data(buf); 8749 8750 /* init fixed params */ 8751 WMITLV_SET_HDR(tt_conf, 8752 WMITLV_TAG_STRUC_wmi_therm_throt_config_request_fixed_param, 8753 (WMITLV_GET_STRUCT_TLVLEN(wmi_therm_throt_config_request_fixed_param))); 8754 8755 tt_conf->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 8756 wmi_handle, 8757 param->pdev_id); 8758 tt_conf->enable = param->enable; 8759 tt_conf->dc = param->dc; 8760 tt_conf->dc_per_event = param->dc_per_event; 8761 tt_conf->therm_throt_levels = param->num_thermal_conf; 8762 wmi_fill_client_id_priority(tt_conf, param); 8763 buf_ptr = (uint8_t *) ++tt_conf; 8764 /* init TLV params */ 8765 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 8766 (param->num_thermal_conf * 8767 sizeof(wmi_therm_throt_level_config_info))); 8768 8769 lvl_conf = (wmi_therm_throt_level_config_info *) (buf_ptr + WMI_TLV_HDR_SIZE); 8770 for (i = 0; i < param->num_thermal_conf; i++) { 8771 WMITLV_SET_HDR(&lvl_conf->tlv_header, 8772 WMITLV_TAG_STRUC_wmi_therm_throt_level_config_info, 8773 WMITLV_GET_STRUCT_TLVLEN(wmi_therm_throt_level_config_info)); 8774 lvl_conf->temp_lwm = param->levelconf[i].tmplwm; 8775 lvl_conf->temp_hwm = param->levelconf[i].tmphwm; 8776 lvl_conf->dc_off_percent = param->levelconf[i].dcoffpercent; 8777 lvl_conf->prio = param->levelconf[i].priority; 8778 lvl_conf++; 8779 } 8780 8781 wmi_mtrace(WMI_THERM_THROT_SET_CONF_CMDID, NO_SESSION, 0); 8782 error = wmi_unified_cmd_send(wmi_handle, buf, len, 8783 WMI_THERM_THROT_SET_CONF_CMDID); 8784 if (QDF_IS_STATUS_ERROR(error)) { 8785 wmi_buf_free(buf); 8786 wmi_err("Failed to send WMI_THERM_THROT_SET_CONF_CMDID command"); 8787 } 8788 8789 return error; 8790 } 8791 8792 /** 8793 * send_coex_config_cmd_tlv() - send coex config command to fw 8794 * @wmi_handle: wmi handle 8795 * @param: pointer to coex config param 8796 * 8797 * Return: QDF_STATUS_SUCCESS for success or error code 8798 */ 8799 static QDF_STATUS 8800 send_coex_config_cmd_tlv(wmi_unified_t wmi_handle, 8801 struct coex_config_params *param) 8802 { 8803 WMI_COEX_CONFIG_CMD_fixed_param *cmd; 8804 wmi_buf_t buf; 8805 QDF_STATUS ret; 8806 int32_t len; 8807 8808 len = sizeof(*cmd); 8809 buf = wmi_buf_alloc(wmi_handle, len); 8810 if (!buf) 8811 return QDF_STATUS_E_FAILURE; 8812 8813 cmd = (WMI_COEX_CONFIG_CMD_fixed_param *)wmi_buf_data(buf); 8814 WMITLV_SET_HDR(&cmd->tlv_header, 8815 WMITLV_TAG_STRUC_WMI_COEX_CONFIG_CMD_fixed_param, 8816 WMITLV_GET_STRUCT_TLVLEN( 8817 WMI_COEX_CONFIG_CMD_fixed_param)); 8818 8819 cmd->vdev_id = param->vdev_id; 8820 cmd->config_type = param->config_type; 8821 cmd->config_arg1 = param->config_arg1; 8822 cmd->config_arg2 = param->config_arg2; 8823 cmd->config_arg3 = param->config_arg3; 8824 cmd->config_arg4 = param->config_arg4; 8825 cmd->config_arg5 = param->config_arg5; 8826 cmd->config_arg6 = param->config_arg6; 8827 8828 wmi_mtrace(WMI_COEX_CONFIG_CMDID, cmd->vdev_id, 0); 8829 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 8830 WMI_COEX_CONFIG_CMDID); 8831 8832 if (ret != 0) { 8833 wmi_err("Sending COEX CONFIG CMD failed"); 8834 wmi_buf_free(buf); 8835 } 8836 8837 return ret; 8838 } 8839 8840 #ifdef WLAN_FEATURE_DBAM_CONFIG 8841 8842 static enum wmi_coex_dbam_mode_type 8843 map_to_wmi_coex_dbam_mode_type(enum coex_dbam_config_mode mode) 8844 { 8845 switch (mode) { 8846 case COEX_DBAM_ENABLE: 8847 return WMI_COEX_DBAM_ENABLE; 8848 case COEX_DBAM_FORCE_ENABLE: 8849 return WMI_COEX_DBAM_FORCED; 8850 case COEX_DBAM_DISABLE: 8851 default: 8852 return WMI_COEX_DBAM_DISABLE; 8853 } 8854 } 8855 8856 /** 8857 * send_dbam_config_cmd_tlv() - send coex DBAM config command to fw 8858 * @wmi_handle: wmi handle 8859 * @param: pointer to coex dbam config param 8860 * 8861 * Return: QDF_STATUS_SUCCESS for success or error code 8862 */ 8863 static QDF_STATUS 8864 send_dbam_config_cmd_tlv(wmi_unified_t wmi_handle, 8865 struct coex_dbam_config_params *param) 8866 { 8867 wmi_coex_dbam_cmd_fixed_param *cmd; 8868 wmi_buf_t buf; 8869 void *buf_ptr; 8870 QDF_STATUS ret; 8871 int32_t len; 8872 8873 len = sizeof(*cmd); 8874 buf = wmi_buf_alloc(wmi_handle, len); 8875 if (!buf) { 8876 wmi_err_rl("Failed to allocate wmi buffer"); 8877 return QDF_STATUS_E_NOMEM; 8878 } 8879 8880 buf_ptr = wmi_buf_data(buf); 8881 cmd = buf_ptr; 8882 WMITLV_SET_HDR(&cmd->tlv_header, 8883 WMITLV_TAG_STRUC_wmi_coex_dbam_cmd_fixed_param, 8884 WMITLV_GET_STRUCT_TLVLEN( 8885 wmi_coex_dbam_cmd_fixed_param)); 8886 8887 cmd->vdev_id = param->vdev_id; 8888 cmd->dbam_mode = map_to_wmi_coex_dbam_mode_type(param->dbam_mode); 8889 8890 wmi_mtrace(WMI_COEX_DBAM_CMDID, cmd->vdev_id, 0); 8891 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 8892 WMI_COEX_DBAM_CMDID); 8893 8894 if (QDF_IS_STATUS_ERROR(ret)) { 8895 wmi_err("Sending DBAM CONFIG CMD failed"); 8896 wmi_buf_free(buf); 8897 return QDF_STATUS_E_FAILURE; 8898 } 8899 8900 return ret; 8901 } 8902 8903 static enum coex_dbam_comp_status 8904 wmi_convert_dbam_comp_status(wmi_coex_dbam_comp_status status) 8905 { 8906 switch (status) { 8907 case WMI_COEX_DBAM_COMP_SUCCESS: 8908 case WMI_COEX_DBAM_COMP_ONGOING: 8909 case WMI_COEX_DBAM_COMP_DELAYED: 8910 return COEX_DBAM_COMP_SUCCESS; 8911 case WMI_COEX_DBAM_COMP_NOT_SUPPORT: 8912 return COEX_DBAM_COMP_NOT_SUPPORT; 8913 case WMI_COEX_DBAM_COMP_INVALID_PARAM: 8914 case WMI_COEX_DBAM_COMP_FAIL: 8915 default: 8916 return COEX_DBAM_COMP_FAIL; 8917 } 8918 } 8919 8920 /** 8921 * extract_dbam_config_resp_event_tlv() - extract dbam complete status event 8922 * @wmi_handle: WMI handle 8923 * @evt_buf: event buffer 8924 * @resp: pointer to coex dbam config response 8925 * 8926 * Return: QDF_STATUS 8927 */ 8928 static QDF_STATUS 8929 extract_dbam_config_resp_event_tlv(wmi_unified_t wmi_handle, void *evt_buf, 8930 struct coex_dbam_config_resp *resp) 8931 { 8932 WMI_COEX_DBAM_COMPLETE_EVENTID_param_tlvs *param_buf; 8933 wmi_coex_dbam_complete_event_fixed_param *event; 8934 8935 param_buf = (WMI_COEX_DBAM_COMPLETE_EVENTID_param_tlvs *)evt_buf; 8936 8937 event = param_buf->fixed_param; 8938 8939 resp->dbam_resp = wmi_convert_dbam_comp_status(event->comp_status); 8940 8941 return QDF_STATUS_SUCCESS; 8942 } 8943 #endif 8944 8945 #ifdef WLAN_SUPPORT_TWT 8946 static void wmi_copy_twt_resource_config(wmi_resource_config *resource_cfg, 8947 target_resource_config *tgt_res_cfg) 8948 { 8949 resource_cfg->twt_ap_pdev_count = tgt_res_cfg->twt_ap_pdev_count; 8950 resource_cfg->twt_ap_sta_count = tgt_res_cfg->twt_ap_sta_count; 8951 } 8952 #else 8953 static void wmi_copy_twt_resource_config(wmi_resource_config *resource_cfg, 8954 target_resource_config *tgt_res_cfg) 8955 { 8956 resource_cfg->twt_ap_pdev_count = 0; 8957 resource_cfg->twt_ap_sta_count = 0; 8958 } 8959 #endif 8960 8961 #ifdef WLAN_FEATURE_NAN 8962 static void wmi_set_nan_channel_support(wmi_resource_config *resource_cfg) 8963 { 8964 WMI_RSRC_CFG_HOST_SERVICE_FLAG_NAN_CHANNEL_SUPPORT_SET( 8965 resource_cfg->host_service_flags, 1); 8966 } 8967 #else 8968 static inline 8969 void wmi_set_nan_channel_support(wmi_resource_config *resource_cfg) 8970 { 8971 } 8972 #endif 8973 8974 #if defined(CONFIG_AFC_SUPPORT) 8975 static 8976 void wmi_copy_afc_deployment_config(wmi_resource_config *resource_cfg, 8977 target_resource_config *tgt_res_cfg) 8978 { 8979 WMI_RSRC_CFG_HOST_SERVICE_FLAG_AFC_INDOOR_SUPPORT_CHECK_SET( 8980 resource_cfg->host_service_flags, 8981 tgt_res_cfg->afc_indoor_support); 8982 8983 WMI_RSRC_CFG_HOST_SERVICE_FLAG_AFC_OUTDOOR_SUPPORT_CHECK_SET( 8984 resource_cfg->host_service_flags, 8985 tgt_res_cfg->afc_outdoor_support); 8986 } 8987 #else 8988 static 8989 void wmi_copy_afc_deployment_config(wmi_resource_config *resource_cfg, 8990 target_resource_config *tgt_res_cfg) 8991 { 8992 } 8993 #endif 8994 8995 static 8996 void wmi_copy_resource_config(wmi_resource_config *resource_cfg, 8997 target_resource_config *tgt_res_cfg) 8998 { 8999 resource_cfg->num_vdevs = tgt_res_cfg->num_vdevs; 9000 resource_cfg->num_peers = tgt_res_cfg->num_peers; 9001 resource_cfg->num_offload_peers = tgt_res_cfg->num_offload_peers; 9002 resource_cfg->num_offload_reorder_buffs = 9003 tgt_res_cfg->num_offload_reorder_buffs; 9004 resource_cfg->num_peer_keys = tgt_res_cfg->num_peer_keys; 9005 resource_cfg->num_tids = tgt_res_cfg->num_tids; 9006 resource_cfg->ast_skid_limit = tgt_res_cfg->ast_skid_limit; 9007 resource_cfg->tx_chain_mask = tgt_res_cfg->tx_chain_mask; 9008 resource_cfg->rx_chain_mask = tgt_res_cfg->rx_chain_mask; 9009 resource_cfg->rx_timeout_pri[0] = tgt_res_cfg->rx_timeout_pri[0]; 9010 resource_cfg->rx_timeout_pri[1] = tgt_res_cfg->rx_timeout_pri[1]; 9011 resource_cfg->rx_timeout_pri[2] = tgt_res_cfg->rx_timeout_pri[2]; 9012 resource_cfg->rx_timeout_pri[3] = tgt_res_cfg->rx_timeout_pri[3]; 9013 resource_cfg->rx_decap_mode = tgt_res_cfg->rx_decap_mode; 9014 resource_cfg->scan_max_pending_req = 9015 tgt_res_cfg->scan_max_pending_req; 9016 resource_cfg->bmiss_offload_max_vdev = 9017 tgt_res_cfg->bmiss_offload_max_vdev; 9018 resource_cfg->roam_offload_max_vdev = 9019 tgt_res_cfg->roam_offload_max_vdev; 9020 resource_cfg->roam_offload_max_ap_profiles = 9021 tgt_res_cfg->roam_offload_max_ap_profiles; 9022 resource_cfg->num_mcast_groups = tgt_res_cfg->num_mcast_groups; 9023 resource_cfg->num_mcast_table_elems = 9024 tgt_res_cfg->num_mcast_table_elems; 9025 resource_cfg->mcast2ucast_mode = tgt_res_cfg->mcast2ucast_mode; 9026 resource_cfg->tx_dbg_log_size = tgt_res_cfg->tx_dbg_log_size; 9027 resource_cfg->num_wds_entries = tgt_res_cfg->num_wds_entries; 9028 resource_cfg->dma_burst_size = tgt_res_cfg->dma_burst_size; 9029 resource_cfg->mac_aggr_delim = tgt_res_cfg->mac_aggr_delim; 9030 resource_cfg->rx_skip_defrag_timeout_dup_detection_check = 9031 tgt_res_cfg->rx_skip_defrag_timeout_dup_detection_check; 9032 resource_cfg->vow_config = tgt_res_cfg->vow_config; 9033 resource_cfg->gtk_offload_max_vdev = tgt_res_cfg->gtk_offload_max_vdev; 9034 resource_cfg->num_msdu_desc = tgt_res_cfg->num_msdu_desc; 9035 resource_cfg->max_frag_entries = tgt_res_cfg->max_frag_entries; 9036 resource_cfg->num_tdls_vdevs = tgt_res_cfg->num_tdls_vdevs; 9037 resource_cfg->num_tdls_conn_table_entries = 9038 tgt_res_cfg->num_tdls_conn_table_entries; 9039 resource_cfg->beacon_tx_offload_max_vdev = 9040 tgt_res_cfg->beacon_tx_offload_max_vdev; 9041 resource_cfg->num_multicast_filter_entries = 9042 tgt_res_cfg->num_multicast_filter_entries; 9043 resource_cfg->num_wow_filters = 9044 tgt_res_cfg->num_wow_filters; 9045 resource_cfg->num_keep_alive_pattern = 9046 tgt_res_cfg->num_keep_alive_pattern; 9047 resource_cfg->keep_alive_pattern_size = 9048 tgt_res_cfg->keep_alive_pattern_size; 9049 resource_cfg->max_tdls_concurrent_sleep_sta = 9050 tgt_res_cfg->max_tdls_concurrent_sleep_sta; 9051 resource_cfg->max_tdls_concurrent_buffer_sta = 9052 tgt_res_cfg->max_tdls_concurrent_buffer_sta; 9053 resource_cfg->wmi_send_separate = 9054 tgt_res_cfg->wmi_send_separate; 9055 resource_cfg->num_ocb_vdevs = 9056 tgt_res_cfg->num_ocb_vdevs; 9057 resource_cfg->num_ocb_channels = 9058 tgt_res_cfg->num_ocb_channels; 9059 resource_cfg->num_ocb_schedules = 9060 tgt_res_cfg->num_ocb_schedules; 9061 resource_cfg->bpf_instruction_size = tgt_res_cfg->apf_instruction_size; 9062 resource_cfg->max_bssid_rx_filters = tgt_res_cfg->max_bssid_rx_filters; 9063 resource_cfg->use_pdev_id = tgt_res_cfg->use_pdev_id; 9064 resource_cfg->max_num_dbs_scan_duty_cycle = 9065 tgt_res_cfg->max_num_dbs_scan_duty_cycle; 9066 resource_cfg->sched_params = tgt_res_cfg->scheduler_params; 9067 resource_cfg->num_packet_filters = tgt_res_cfg->num_packet_filters; 9068 resource_cfg->num_max_sta_vdevs = tgt_res_cfg->num_max_sta_vdevs; 9069 resource_cfg->max_bssid_indicator = tgt_res_cfg->max_bssid_indicator; 9070 resource_cfg->max_num_group_keys = tgt_res_cfg->max_num_group_keys; 9071 /* Deferred AI: Max rnr neighbors supported in multisoc case 9072 * where in SoC can support 6ghz. During WMI init of a SoC 9073 * currently there is no way to figure if another SOC is plugged in 9074 * and it can support 6Ghz. 9075 */ 9076 resource_cfg->max_rnr_neighbours = MAX_SUPPORTED_NEIGHBORS; 9077 resource_cfg->ema_max_vap_cnt = tgt_res_cfg->ema_max_vap_cnt; 9078 resource_cfg->ema_max_profile_period = 9079 tgt_res_cfg->ema_max_profile_period; 9080 resource_cfg->ema_init_config = tgt_res_cfg->ema_init_config; 9081 resource_cfg->carrier_config = tgt_res_cfg->carrier_profile_config; 9082 9083 if (tgt_res_cfg->max_ndp_sessions) 9084 resource_cfg->max_ndp_sessions = 9085 tgt_res_cfg->max_ndp_sessions; 9086 resource_cfg->max_ndi_interfaces = tgt_res_cfg->max_ndi; 9087 resource_cfg->num_max_active_vdevs = tgt_res_cfg->num_max_active_vdevs; 9088 9089 if (tgt_res_cfg->atf_config) 9090 WMI_RSRC_CFG_FLAG_ATF_CONFIG_ENABLE_SET(resource_cfg->flag1, 1); 9091 if (tgt_res_cfg->mgmt_comp_evt_bundle_support) 9092 WMI_RSRC_CFG_FLAG_MGMT_COMP_EVT_BUNDLE_SUPPORT_SET( 9093 resource_cfg->flag1, 1); 9094 if (tgt_res_cfg->tx_msdu_new_partition_id_support) 9095 WMI_RSRC_CFG_FLAG_TX_MSDU_ID_NEW_PARTITION_SUPPORT_SET( 9096 resource_cfg->flag1, 1); 9097 if (tgt_res_cfg->cce_disable) 9098 WMI_RSRC_CFG_FLAG_TCL_CCE_DISABLE_SET(resource_cfg->flag1, 1); 9099 if (tgt_res_cfg->enable_pci_gen) 9100 WMI_RSRC_CFG_FLAG_PCIE_GEN_SWITCH_CAPABLITY_SET( 9101 resource_cfg->flag1, 1); 9102 if (tgt_res_cfg->eapol_minrate_set) { 9103 WMI_RSRC_CFG_FLAG_EAPOL_REKEY_MINRATE_SUPPORT_ENABLE_SET( 9104 resource_cfg->flag1, 1); 9105 if (tgt_res_cfg->eapol_minrate_ac_set != 3) { 9106 WMI_RSRC_CFG_FLAG_EAPOL_AC_OVERRIDE_VALID_SET( 9107 resource_cfg->flag1, 1); 9108 WMI_RSRC_CFG_FLAG_EAPOL_AC_OVERRIDE_SET( 9109 resource_cfg->flag1, 9110 tgt_res_cfg->eapol_minrate_ac_set); 9111 } 9112 } 9113 if (tgt_res_cfg->new_htt_msg_format) { 9114 WMI_RSRC_CFG_FLAG_HTT_H2T_NO_HTC_HDR_LEN_IN_MSG_LEN_SET( 9115 resource_cfg->flag1, 1); 9116 } 9117 9118 if (tgt_res_cfg->peer_unmap_conf_support) 9119 WMI_RSRC_CFG_FLAG_PEER_UNMAP_RESPONSE_SUPPORT_SET( 9120 resource_cfg->flag1, 1); 9121 9122 if (tgt_res_cfg->tstamp64_en) 9123 WMI_RSRC_CFG_FLAG_TX_COMPLETION_TX_TSF64_ENABLE_SET( 9124 resource_cfg->flag1, 1); 9125 9126 if (tgt_res_cfg->three_way_coex_config_legacy_en) 9127 WMI_RSRC_CFG_FLAG_THREE_WAY_COEX_CONFIG_LEGACY_SUPPORT_SET( 9128 resource_cfg->flag1, 1); 9129 if (tgt_res_cfg->pktcapture_support) 9130 WMI_RSRC_CFG_FLAG_PACKET_CAPTURE_SUPPORT_SET( 9131 resource_cfg->flag1, 1); 9132 9133 /* 9134 * Control padding using config param/ini of iphdr_pad_config 9135 */ 9136 if (tgt_res_cfg->iphdr_pad_config) 9137 WMI_RSRC_CFG_FLAG_IPHR_PAD_CONFIG_ENABLE_SET( 9138 resource_cfg->flag1, 1); 9139 9140 WMI_RSRC_CFG_FLAG_IPA_DISABLE_SET(resource_cfg->flag1, 9141 tgt_res_cfg->ipa_disable); 9142 9143 if (tgt_res_cfg->time_sync_ftm) 9144 WMI_RSRC_CFG_FLAG_AUDIO_SYNC_SUPPORT_SET(resource_cfg->flag1, 9145 1); 9146 9147 wmi_copy_twt_resource_config(resource_cfg, tgt_res_cfg); 9148 resource_cfg->peer_map_unmap_versions = 9149 tgt_res_cfg->peer_map_unmap_version; 9150 resource_cfg->smart_ant_cap = tgt_res_cfg->smart_ant_cap; 9151 if (tgt_res_cfg->re_ul_resp) 9152 WMI_SET_BITS(resource_cfg->flags2, 0, 4, 9153 tgt_res_cfg->re_ul_resp); 9154 9155 /* 9156 * Enable Service Aware Wifi 9157 */ 9158 if (tgt_res_cfg->sawf) 9159 WMI_RSRC_CFG_FLAGS2_SAWF_CONFIG_ENABLE_SET(resource_cfg->flags2, 9160 tgt_res_cfg->sawf); 9161 9162 /* 9163 * Enable ast flow override per peer 9164 */ 9165 resource_cfg->msdu_flow_override_config0 = 0; 9166 WMI_MSDU_FLOW_AST_ENABLE_SET( 9167 resource_cfg->msdu_flow_override_config0, 9168 WMI_CONFIG_MSDU_AST_INDEX_1, 9169 tgt_res_cfg->ast_1_valid_mask_enable); 9170 9171 WMI_MSDU_FLOW_AST_ENABLE_SET( 9172 resource_cfg->msdu_flow_override_config0, 9173 WMI_CONFIG_MSDU_AST_INDEX_2, 9174 tgt_res_cfg->ast_2_valid_mask_enable); 9175 9176 WMI_MSDU_FLOW_AST_ENABLE_SET( 9177 resource_cfg->msdu_flow_override_config0, 9178 WMI_CONFIG_MSDU_AST_INDEX_3, 9179 tgt_res_cfg->ast_3_valid_mask_enable); 9180 9181 /* 9182 * Enable ast flow mask and TID valid mask configurations 9183 */ 9184 resource_cfg->msdu_flow_override_config1 = 0; 9185 9186 /*Enable UDP flow for Ast index 0*/ 9187 WMI_MSDU_FLOW_ASTX_MSDU_FLOW_MASKS_SET( 9188 resource_cfg->msdu_flow_override_config1, 9189 WMI_CONFIG_MSDU_AST_INDEX_0, 9190 tgt_res_cfg->ast_0_flow_mask_enable); 9191 9192 /*Enable Non UDP flow for Ast index 1*/ 9193 WMI_MSDU_FLOW_ASTX_MSDU_FLOW_MASKS_SET( 9194 resource_cfg->msdu_flow_override_config1, 9195 WMI_CONFIG_MSDU_AST_INDEX_1, 9196 tgt_res_cfg->ast_1_flow_mask_enable); 9197 9198 /*Enable Hi-Priority flow for Ast index 2*/ 9199 WMI_MSDU_FLOW_ASTX_MSDU_FLOW_MASKS_SET( 9200 resource_cfg->msdu_flow_override_config1, 9201 WMI_CONFIG_MSDU_AST_INDEX_2, 9202 tgt_res_cfg->ast_2_flow_mask_enable); 9203 9204 /*Enable Low-Priority flow for Ast index 3*/ 9205 WMI_MSDU_FLOW_ASTX_MSDU_FLOW_MASKS_SET( 9206 resource_cfg->msdu_flow_override_config1, 9207 WMI_CONFIG_MSDU_AST_INDEX_3, 9208 tgt_res_cfg->ast_3_flow_mask_enable); 9209 9210 /*Enable all 8 tid for Hi-Pririty Flow Queue*/ 9211 WMI_MSDU_FLOW_TID_VALID_HI_MASKS_SET( 9212 resource_cfg->msdu_flow_override_config1, 9213 tgt_res_cfg->ast_tid_high_mask_enable); 9214 9215 /*Enable all 8 tid for Low-Pririty Flow Queue*/ 9216 WMI_MSDU_FLOW_TID_VALID_LOW_MASKS_SET( 9217 resource_cfg->msdu_flow_override_config1, 9218 tgt_res_cfg->ast_tid_low_mask_enable); 9219 WMI_RSRC_CFG_HOST_SERVICE_FLAG_NAN_IFACE_SUPPORT_SET( 9220 resource_cfg->host_service_flags, 9221 tgt_res_cfg->nan_separate_iface_support); 9222 WMI_RSRC_CFG_HOST_SERVICE_FLAG_HOST_SUPPORT_MULTI_RADIO_EVTS_PER_RADIO_SET( 9223 resource_cfg->host_service_flags, 1); 9224 9225 WMI_RSRC_CFG_FLAG_VIDEO_OVER_WIFI_ENABLE_SET( 9226 resource_cfg->flag1, tgt_res_cfg->carrier_vow_optimization); 9227 9228 if (tgt_res_cfg->is_sap_connected_d3wow_enabled) 9229 WMI_RSRC_CFG_FLAGS2_IS_SAP_CONNECTED_D3WOW_ENABLED_SET( 9230 resource_cfg->flags2, 1); 9231 if (tgt_res_cfg->is_go_connected_d3wow_enabled) 9232 WMI_RSRC_CFG_FLAGS2_IS_GO_CONNECTED_D3WOW_ENABLED_SET( 9233 resource_cfg->flags2, 1); 9234 9235 if (tgt_res_cfg->sae_eapol_offload) 9236 WMI_RSRC_CFG_HOST_SERVICE_FLAG_SAE_EAPOL_OFFLOAD_SUPPORT_SET( 9237 resource_cfg->host_service_flags, 1); 9238 9239 WMI_RSRC_CFG_HOST_SERVICE_FLAG_REG_CC_EXT_SUPPORT_SET( 9240 resource_cfg->host_service_flags, 9241 tgt_res_cfg->is_reg_cc_ext_event_supported); 9242 9243 WMI_RSRC_CFG_HOST_SERVICE_FLAG_BANG_RADAR_320M_SUPPORT_SET( 9244 resource_cfg->host_service_flags, 9245 tgt_res_cfg->is_host_dfs_320mhz_bangradar_supported); 9246 9247 WMI_RSRC_CFG_HOST_SERVICE_FLAG_LPI_SP_MODE_SUPPORT_SET( 9248 resource_cfg->host_service_flags, 9249 tgt_res_cfg->is_6ghz_sp_pwrmode_supp_enabled); 9250 9251 WMI_RSRC_CFG_HOST_SERVICE_FLAG_REG_DISCARD_AFC_TIMER_CHECK_SET( 9252 resource_cfg->host_service_flags, 9253 tgt_res_cfg->afc_timer_check_disable); 9254 9255 WMI_RSRC_CFG_HOST_SERVICE_FLAG_REG_DISCARD_AFC_REQ_ID_CHECK_SET( 9256 resource_cfg->host_service_flags, 9257 tgt_res_cfg->afc_req_id_check_disable); 9258 9259 wmi_copy_afc_deployment_config(resource_cfg, tgt_res_cfg); 9260 9261 wmi_set_nan_channel_support(resource_cfg); 9262 9263 if (tgt_res_cfg->twt_ack_support_cap) 9264 WMI_RSRC_CFG_HOST_SERVICE_FLAG_STA_TWT_SYNC_EVT_SUPPORT_SET( 9265 resource_cfg->host_service_flags, 1); 9266 9267 if (tgt_res_cfg->reo_qdesc_shared_addr_table_enabled) 9268 WMI_RSRC_CFG_HOST_SERVICE_FLAG_REO_QREF_FEATURE_SUPPORT_SET( 9269 resource_cfg->host_service_flags, 1); 9270 9271 WMI_RSRC_CFG_FLAGS2_RX_PEER_METADATA_VERSION_SET(resource_cfg->flags2, 9272 tgt_res_cfg->target_cap_flags); 9273 if (tgt_res_cfg->notify_frame_support) 9274 WMI_RSRC_CFG_FLAGS2_NOTIFY_FRAME_CONFIG_ENABLE_SET( 9275 resource_cfg->flags2, 1); 9276 9277 } 9278 9279 #ifdef FEATURE_SET 9280 /** 9281 * convert_host_to_target_vendor1_req2_version() -Convert host vendor1 9282 * requirement2 version to target vendor1 requirement2 version 9283 * @vendor1_req2_ver: Host vendor1 requirement2 version 9284 * 9285 * Return: Target vendor1 requirement2 version 9286 */ 9287 static WMI_VENDOR1_REQ2_VERSION convert_host_to_target_vendor1_req2_version( 9288 WMI_HOST_VENDOR1_REQ2_VERSION vendor1_req2_ver) 9289 { 9290 switch (vendor1_req2_ver) { 9291 case WMI_HOST_VENDOR1_REQ2_VERSION_3_00: 9292 return WMI_VENDOR1_REQ2_VERSION_3_00; 9293 case WMI_HOST_VENDOR1_REQ2_VERSION_3_01: 9294 return WMI_VENDOR1_REQ2_VERSION_3_01; 9295 case WMI_HOST_VENDOR1_REQ2_VERSION_3_20: 9296 return WMI_VENDOR1_REQ2_VERSION_3_20; 9297 default: 9298 return WMI_VENDOR1_REQ2_VERSION_3_00; 9299 } 9300 } 9301 9302 /** 9303 * convert_host_to_target_vendor1_req1_version() -Convert host vendor1 9304 * requirement1 version to target vendor1 requirement1 version 9305 * @vendor1_req1_ver: Host vendor1 requirement1 version 9306 * 9307 * Return: Target vendor1 requirement1 version 9308 */ 9309 static WMI_VENDOR1_REQ1_VERSION convert_host_to_target_vendor1_req1_version( 9310 WMI_HOST_VENDOR1_REQ1_VERSION vendor1_req1_ver) 9311 { 9312 switch (vendor1_req1_ver) { 9313 case WMI_HOST_VENDOR1_REQ1_VERSION_3_00: 9314 return WMI_VENDOR1_REQ1_VERSION_3_00; 9315 case WMI_HOST_VENDOR1_REQ1_VERSION_3_01: 9316 return WMI_VENDOR1_REQ1_VERSION_3_01; 9317 case WMI_HOST_VENDOR1_REQ1_VERSION_3_20: 9318 return WMI_VENDOR1_REQ1_VERSION_3_20; 9319 case WMI_HOST_VENDOR1_REQ1_VERSION_3_30: 9320 return WMI_VENDOR1_REQ1_VERSION_3_30; 9321 case WMI_HOST_VENDOR1_REQ1_VERSION_3_40: 9322 return WMI_VENDOR1_REQ1_VERSION_3_40; 9323 default: 9324 return WMI_VENDOR1_REQ1_VERSION_3_00; 9325 } 9326 } 9327 9328 /** 9329 * convert_host_to_target_wifi_standard() -Convert host wifi standard to 9330 * target wifi standard 9331 * @wifi_standard: Host wifi standard 9332 * 9333 * Return: Target wifi standard 9334 */ 9335 static WMI_WIFI_STANDARD convert_host_to_target_wifi_standard( 9336 WMI_HOST_WIFI_STANDARD wifi_standard) 9337 { 9338 switch (wifi_standard) { 9339 case WMI_HOST_WIFI_STANDARD_4: 9340 return WMI_WIFI_STANDARD_4; 9341 case WMI_HOST_WIFI_STANDARD_5: 9342 return WMI_WIFI_STANDARD_5; 9343 case WMI_HOST_WIFI_STANDARD_6: 9344 return WMI_WIFI_STANDARD_6; 9345 case WMI_HOST_WIFI_STANDARD_6E: 9346 return WMI_WIFI_STANDARD_6E; 9347 case WMI_HOST_WIFI_STANDARD_7: 9348 return WMI_WIFI_STANDARD_7; 9349 default: 9350 return WMI_WIFI_STANDARD_4; 9351 } 9352 } 9353 9354 /** 9355 * convert_host_to_target_band_concurrency() -Convert host band concurrency to 9356 * target band concurrency 9357 * @band_concurrency: Host Band concurrency 9358 * 9359 * Return: Target band concurrency 9360 */ 9361 static WMI_BAND_CONCURRENCY convert_host_to_target_band_concurrency( 9362 WMI_HOST_BAND_CONCURRENCY band_concurrency) 9363 { 9364 switch (band_concurrency) { 9365 case WMI_HOST_BAND_CONCURRENCY_DBS: 9366 return WMI_HOST_DBS; 9367 case WMI_HOST_BAND_CONCURRENCY_DBS_SBS: 9368 return WMI_HOST_DBS_SBS; 9369 default: 9370 return WMI_HOST_NONE; 9371 } 9372 } 9373 9374 /** 9375 * convert_host_to_target_num_antennas() -Convert host num antennas to 9376 * target num antennas 9377 * @num_antennas: Host num antennas 9378 * 9379 * Return: Target num antennas 9380 */ 9381 static WMI_NUM_ANTENNAS convert_host_to_target_num_antennas( 9382 WMI_HOST_NUM_ANTENNAS num_antennas) 9383 { 9384 switch (num_antennas) { 9385 case WMI_HOST_SISO: 9386 return WMI_SISO; 9387 case WMI_HOST_MIMO_2X2: 9388 return WMI_MIMO_2X2; 9389 default: 9390 return WMI_SISO; 9391 } 9392 } 9393 9394 /** 9395 * convert_host_to_target_band_capability() -Convert host band capability to 9396 * target band capability 9397 * @host_band_capability: Host band capability 9398 * 9399 * Return: Target band capability bitmap 9400 */ 9401 static uint8_t 9402 convert_host_to_target_band_capability(uint32_t host_band_capability) 9403 { 9404 uint8_t band_capability; 9405 9406 band_capability = (host_band_capability & WMI_HOST_BAND_CAP_2GHZ) | 9407 (host_band_capability & WMI_HOST_BAND_CAP_5GHZ) | 9408 (host_band_capability & WMI_HOST_BAND_CAP_6GHZ); 9409 return band_capability; 9410 } 9411 9412 /** 9413 * copy_feature_set_info() -Copy feature set info from host to target 9414 * @feature_set_bitmap: Target feature set pointer 9415 * @feature_set: Host feature set structure 9416 * 9417 * Return: None 9418 */ 9419 static inline void copy_feature_set_info(uint32_t *feature_set_bitmap, 9420 struct target_feature_set *feature_set) 9421 { 9422 WMI_NUM_ANTENNAS num_antennas; 9423 WMI_BAND_CONCURRENCY band_concurrency; 9424 WMI_WIFI_STANDARD wifi_standard; 9425 WMI_VENDOR1_REQ1_VERSION vendor1_req1_version; 9426 WMI_VENDOR1_REQ2_VERSION vendor1_req2_version; 9427 uint8_t band_capability; 9428 9429 num_antennas = convert_host_to_target_num_antennas( 9430 feature_set->num_antennas); 9431 band_concurrency = convert_host_to_target_band_concurrency( 9432 feature_set->concurrency_support); 9433 wifi_standard = convert_host_to_target_wifi_standard( 9434 feature_set->wifi_standard); 9435 vendor1_req1_version = convert_host_to_target_vendor1_req1_version( 9436 feature_set->vendor_req_1_version); 9437 vendor1_req2_version = convert_host_to_target_vendor1_req2_version( 9438 feature_set->vendor_req_2_version); 9439 9440 band_capability = 9441 convert_host_to_target_band_capability( 9442 feature_set->band_capability); 9443 9444 WMI_SET_WIFI_STANDARD(feature_set_bitmap, wifi_standard); 9445 WMI_SET_BAND_CONCURRENCY_SUPPORT(feature_set_bitmap, band_concurrency); 9446 WMI_SET_PNO_SCAN_IN_UNASSOC_STATE(feature_set_bitmap, 9447 feature_set->pno_in_unassoc_state); 9448 WMI_SET_PNO_SCAN_IN_ASSOC_STATE(feature_set_bitmap, 9449 feature_set->pno_in_assoc_state); 9450 WMI_SET_TWT_FEATURE_SUPPORT(feature_set_bitmap, 9451 feature_set->enable_twt); 9452 WMI_SET_TWT_REQUESTER(feature_set_bitmap, 9453 feature_set->enable_twt_requester); 9454 WMI_SET_TWT_BROADCAST(feature_set_bitmap, 9455 feature_set->enable_twt_broadcast); 9456 WMI_SET_TWT_FLEXIBLE(feature_set_bitmap, 9457 feature_set->enable_twt_flexible); 9458 WMI_SET_WIFI_OPT_FEATURE_SUPPORT(feature_set_bitmap, 9459 feature_set->enable_wifi_optimizer); 9460 WMI_SET_RFC8325_FEATURE_SUPPORT(feature_set_bitmap, 9461 feature_set->enable_rfc835); 9462 WMI_SET_MHS_5G_SUPPORT(feature_set_bitmap, 9463 feature_set->sap_5g_supported); 9464 WMI_SET_MHS_6G_SUPPORT(feature_set_bitmap, 9465 feature_set->sap_6g_supported); 9466 WMI_SET_MHS_MAX_CLIENTS_SUPPORT(feature_set_bitmap, 9467 feature_set->sap_max_num_clients); 9468 WMI_SET_MHS_SET_COUNTRY_CODE_HAL_SUPPORT( 9469 feature_set_bitmap, 9470 feature_set->set_country_code_hal_supported); 9471 WMI_SET_MHS_GETVALID_CHANNELS_SUPPORT( 9472 feature_set_bitmap, 9473 feature_set->get_valid_channel_supported); 9474 WMI_SET_MHS_DOT11_MODE_SUPPORT(feature_set_bitmap, 9475 feature_set->supported_dot11mode); 9476 WMI_SET_MHS_WPA3_SUPPORT(feature_set_bitmap, 9477 feature_set->sap_wpa3_support); 9478 WMI_SET_VENDOR_REQ_1_VERSION(feature_set_bitmap, vendor1_req1_version); 9479 WMI_SET_ROAMING_HIGH_CU_ROAM_TRIGGER( 9480 feature_set_bitmap, 9481 feature_set->roaming_high_cu_roam_trigger); 9482 WMI_SET_ROAMING_EMERGENCY_TRIGGER( 9483 feature_set_bitmap, 9484 feature_set->roaming_emergency_trigger); 9485 WMI_SET_ROAMING_BTM_TRIGGER(feature_set_bitmap, 9486 feature_set->roaming_btm_trihgger); 9487 WMI_SET_ROAMING_IDLE_TRIGGER(feature_set_bitmap, 9488 feature_set->roaming_idle_trigger); 9489 WMI_SET_ROAMING_WTC_TRIGGER(feature_set_bitmap, 9490 feature_set->roaming_wtc_trigger); 9491 WMI_SET_ROAMING_BTCOEX_TRIGGER(feature_set_bitmap, 9492 feature_set->roaming_btcoex_trigger); 9493 WMI_SET_ROAMING_BTW_WPA_WPA2(feature_set_bitmap, 9494 feature_set->roaming_btw_wpa_wpa2); 9495 WMI_SET_ROAMING_MANAGE_CHAN_LIST_API( 9496 feature_set_bitmap, 9497 feature_set->roaming_manage_chan_list_api); 9498 WMI_SET_ROAMING_ADAPTIVE_11R(feature_set_bitmap, 9499 feature_set->roaming_adaptive_11r); 9500 WMI_SET_ROAMING_CTRL_API_GET_SET(feature_set_bitmap, 9501 feature_set->roaming_ctrl_api_get_set); 9502 WMI_SET_ROAMING_CTRL_API_REASSOC(feature_set_bitmap, 9503 feature_set->roaming_ctrl_api_reassoc); 9504 WMI_SET_ROAMING_CTRL_GET_CU(feature_set_bitmap, 9505 feature_set->roaming_ctrl_get_cu); 9506 WMI_SET_VENDOR_REQ_2_VERSION(feature_set_bitmap, vendor1_req2_version); 9507 WMI_SET_ASSURANCE_DISCONNECT_REASON_API( 9508 feature_set_bitmap, 9509 feature_set->assurance_disconnect_reason_api); 9510 WMI_SET_FRAME_PCAP_LOG_MGMT(feature_set_bitmap, 9511 feature_set->frame_pcap_log_mgmt); 9512 WMI_SET_FRAME_PCAP_LOG_CTRL(feature_set_bitmap, 9513 feature_set->frame_pcap_log_ctrl); 9514 WMI_SET_FRAME_PCAP_LOG_DATA(feature_set_bitmap, 9515 feature_set->frame_pcap_log_data); 9516 WMI_SET_SECURITY_WPA3_SAE_H2E(feature_set_bitmap, 9517 feature_set->security_wpa3_sae_h2e); 9518 WMI_SET_SECURITY_WPA3_SAE_FT(feature_set_bitmap, 9519 feature_set->security_wpa3_sae_ft); 9520 WMI_SET_SECURITY_WPA3_ENTERP_SUITEB( 9521 feature_set_bitmap, 9522 feature_set->security_wpa3_enterp_suitb); 9523 WMI_SET_SECURITY_WPA3_ENTERP_SUITEB_192bit( 9524 feature_set_bitmap, 9525 feature_set->security_wpa3_enterp_suitb_192bit); 9526 WMI_SET_SECURITY_FILS_SHA256(feature_set_bitmap, 9527 feature_set->security_fills_sha_256); 9528 WMI_SET_SECURITY_FILS_SHA384(feature_set_bitmap, 9529 feature_set->security_fills_sha_384); 9530 WMI_SET_SECURITY_FILS_SHA256_FT(feature_set_bitmap, 9531 feature_set->security_fills_sha_256_FT); 9532 WMI_SET_SECURITY_FILS_SHA384_FT(feature_set_bitmap, 9533 feature_set->security_fills_sha_384_FT); 9534 WMI_SET_SECURITY_ENCHANCED_OPEN(feature_set_bitmap, 9535 feature_set->security_enhanced_open); 9536 WMI_SET_NAN_SUPPORT(feature_set_bitmap, feature_set->enable_nan); 9537 WMI_SET_TDLS_SUPPORT(feature_set_bitmap, feature_set->enable_tdls); 9538 WMI_SET_P2P6E_SUPPORT(feature_set_bitmap, feature_set->enable_p2p_6e); 9539 WMI_SET_TDLS_OFFCHAN_SUPPORT(feature_set_bitmap, 9540 feature_set->enable_tdls_offchannel); 9541 WMI_SET_TDLS_CAP_ENHANCE(feature_set_bitmap, 9542 feature_set->enable_tdls_capability_enhance); 9543 WMI_SET_MAX_TDLS_PEERS_SUPPORT(feature_set_bitmap, 9544 feature_set->max_tdls_peers); 9545 WMI_SET_STA_DUAL_P2P_SUPPORT(feature_set_bitmap, 9546 feature_set->sta_dual_p2p_support); 9547 WMI_SET_PEER_BIGDATA_GETBSSINFO_API_SUPPORT( 9548 feature_set_bitmap, 9549 feature_set->peer_bigdata_getbssinfo_support); 9550 WMI_SET_PEER_BIGDATA_GETASSOCREJECTINFO_API_SUPPORT( 9551 feature_set_bitmap, 9552 feature_set->peer_bigdata_assocreject_info_support); 9553 WMI_SET_PEER_BIGDATA_GETSTAINFO_API_SUPPORT( 9554 feature_set_bitmap, 9555 feature_set->peer_getstainfo_support); 9556 WMI_SET_FEATURE_SET_VERSION(feature_set_bitmap, 9557 feature_set->feature_set_version); 9558 WMI_SET_NUM_ANTENNAS(feature_set_bitmap, num_antennas); 9559 WMI_SET_HOST_BAND_CAP(feature_set_bitmap, band_capability); 9560 } 9561 9562 /** 9563 * feature_set_cmd_send_tlv() -Send feature set command 9564 * @wmi_handle: WMI handle 9565 * @feature_set: Feature set structure 9566 * 9567 * Return: QDF_STATUS_SUCCESS on success else return failure 9568 */ 9569 static QDF_STATUS feature_set_cmd_send_tlv( 9570 struct wmi_unified *wmi_handle, 9571 struct target_feature_set *feature_set) 9572 { 9573 wmi_pdev_featureset_cmd_fixed_param *cmd; 9574 wmi_buf_t buf; 9575 uint16_t len; 9576 QDF_STATUS ret; 9577 uint8_t *buf_ptr; 9578 uint32_t *feature_set_bitmap; 9579 9580 len = sizeof(*cmd) + WMI_TLV_HDR_SIZE + 9581 WMI_FEATURE_SET_BITMAP_ARRAY_LEN32 * sizeof(uint32_t); 9582 buf = wmi_buf_alloc(wmi_handle, len); 9583 9584 if (!buf) 9585 return QDF_STATUS_E_NOMEM; 9586 9587 wmi_debug("Send feature set param"); 9588 9589 buf_ptr = (uint8_t *)wmi_buf_data(buf); 9590 9591 cmd = (wmi_pdev_featureset_cmd_fixed_param *)wmi_buf_data(buf); 9592 9593 WMITLV_SET_HDR(&cmd->tlv_header, 9594 WMITLV_TAG_STRUC_wmi_pdev_featureset_cmd_fixed_param, 9595 WMITLV_GET_STRUCT_TLVLEN( 9596 wmi_pdev_featureset_cmd_fixed_param)); 9597 9598 feature_set_bitmap = (uint32_t *)(buf_ptr + sizeof(*cmd) + 9599 WMI_TLV_HDR_SIZE); 9600 WMITLV_SET_HDR(buf_ptr + sizeof(*cmd), WMITLV_TAG_ARRAY_UINT32, 9601 (WMI_FEATURE_SET_BITMAP_ARRAY_LEN32 * sizeof(uint32_t))); 9602 copy_feature_set_info(feature_set_bitmap, feature_set); 9603 9604 qdf_trace_hex_dump(QDF_MODULE_ID_WMI, QDF_TRACE_LEVEL_DEBUG, 9605 feature_set_bitmap, 9606 WMI_FEATURE_SET_BITMAP_ARRAY_LEN32 * 9607 sizeof(uint32_t)); 9608 9609 wmi_mtrace(WMI_PDEV_FEATURESET_CMDID, NO_SESSION, 0); 9610 9611 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 9612 WMI_PDEV_FEATURESET_CMDID); 9613 if (QDF_IS_STATUS_ERROR(ret)) 9614 wmi_buf_free(buf); 9615 9616 return ret; 9617 } 9618 #endif 9619 9620 /* copy_hw_mode_id_in_init_cmd() - Helper routine to copy hw_mode in init cmd 9621 * @wmi_handle: pointer to wmi handle 9622 * @buf_ptr: pointer to current position in init command buffer 9623 * @len: pointer to length. This will be updated with current length of cmd 9624 * @param: point host parameters for init command 9625 * 9626 * Return: Updated pointer of buf_ptr. 9627 */ 9628 static inline uint8_t *copy_hw_mode_in_init_cmd(struct wmi_unified *wmi_handle, 9629 uint8_t *buf_ptr, int *len, struct wmi_init_cmd_param *param) 9630 { 9631 uint16_t idx; 9632 9633 if (param->hw_mode_id != WMI_HOST_HW_MODE_MAX) { 9634 wmi_pdev_set_hw_mode_cmd_fixed_param *hw_mode; 9635 wmi_pdev_band_to_mac *band_to_mac; 9636 9637 hw_mode = (wmi_pdev_set_hw_mode_cmd_fixed_param *) 9638 (buf_ptr + sizeof(wmi_init_cmd_fixed_param) + 9639 sizeof(wmi_resource_config) + 9640 WMI_TLV_HDR_SIZE + (param->num_mem_chunks * 9641 sizeof(wlan_host_memory_chunk))); 9642 9643 WMITLV_SET_HDR(&hw_mode->tlv_header, 9644 WMITLV_TAG_STRUC_wmi_pdev_set_hw_mode_cmd_fixed_param, 9645 (WMITLV_GET_STRUCT_TLVLEN 9646 (wmi_pdev_set_hw_mode_cmd_fixed_param))); 9647 9648 hw_mode->hw_mode_index = param->hw_mode_id; 9649 hw_mode->num_band_to_mac = param->num_band_to_mac; 9650 9651 buf_ptr = (uint8_t *) (hw_mode + 1); 9652 band_to_mac = (wmi_pdev_band_to_mac *) (buf_ptr + 9653 WMI_TLV_HDR_SIZE); 9654 for (idx = 0; idx < param->num_band_to_mac; idx++) { 9655 WMITLV_SET_HDR(&band_to_mac[idx].tlv_header, 9656 WMITLV_TAG_STRUC_wmi_pdev_band_to_mac, 9657 WMITLV_GET_STRUCT_TLVLEN 9658 (wmi_pdev_band_to_mac)); 9659 band_to_mac[idx].pdev_id = 9660 wmi_handle->ops->convert_pdev_id_host_to_target( 9661 wmi_handle, 9662 param->band_to_mac[idx].pdev_id); 9663 band_to_mac[idx].start_freq = 9664 param->band_to_mac[idx].start_freq; 9665 band_to_mac[idx].end_freq = 9666 param->band_to_mac[idx].end_freq; 9667 } 9668 *len += sizeof(wmi_pdev_set_hw_mode_cmd_fixed_param) + 9669 (param->num_band_to_mac * 9670 sizeof(wmi_pdev_band_to_mac)) + 9671 WMI_TLV_HDR_SIZE; 9672 9673 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 9674 (param->num_band_to_mac * 9675 sizeof(wmi_pdev_band_to_mac))); 9676 } 9677 9678 return buf_ptr; 9679 } 9680 9681 static inline void copy_fw_abi_version_tlv(wmi_unified_t wmi_handle, 9682 wmi_init_cmd_fixed_param *cmd) 9683 { 9684 int num_allowlist; 9685 wmi_abi_version my_vers; 9686 9687 num_allowlist = sizeof(version_whitelist) / 9688 sizeof(wmi_whitelist_version_info); 9689 my_vers.abi_version_0 = WMI_ABI_VERSION_0; 9690 my_vers.abi_version_1 = WMI_ABI_VERSION_1; 9691 my_vers.abi_version_ns_0 = WMI_ABI_VERSION_NS_0; 9692 my_vers.abi_version_ns_1 = WMI_ABI_VERSION_NS_1; 9693 my_vers.abi_version_ns_2 = WMI_ABI_VERSION_NS_2; 9694 my_vers.abi_version_ns_3 = WMI_ABI_VERSION_NS_3; 9695 9696 wmi_cmp_and_set_abi_version(num_allowlist, version_whitelist, 9697 &my_vers, 9698 (struct _wmi_abi_version *)&wmi_handle->fw_abi_version, 9699 &cmd->host_abi_vers); 9700 9701 wmi_debug("INIT_CMD version: %d, %d, 0x%x, 0x%x, 0x%x, 0x%x", 9702 WMI_VER_GET_MAJOR(cmd->host_abi_vers.abi_version_0), 9703 WMI_VER_GET_MINOR(cmd->host_abi_vers.abi_version_0), 9704 cmd->host_abi_vers.abi_version_ns_0, 9705 cmd->host_abi_vers.abi_version_ns_1, 9706 cmd->host_abi_vers.abi_version_ns_2, 9707 cmd->host_abi_vers.abi_version_ns_3); 9708 9709 /* Save version sent from host - 9710 * Will be used to check ready event 9711 */ 9712 qdf_mem_copy(&wmi_handle->final_abi_vers, &cmd->host_abi_vers, 9713 sizeof(wmi_abi_version)); 9714 } 9715 9716 /* 9717 * send_cfg_action_frm_tb_ppdu_cmd_tlv() - send action frame tb ppdu cfg to FW 9718 * @wmi_handle: Pointer to WMi handle 9719 * @ie_data: Pointer for ie data 9720 * 9721 * This function sends action frame tb ppdu cfg to FW 9722 * 9723 * Return: QDF_STATUS_SUCCESS for success otherwise failure 9724 * 9725 */ 9726 static QDF_STATUS send_cfg_action_frm_tb_ppdu_cmd_tlv(wmi_unified_t wmi_handle, 9727 struct cfg_action_frm_tb_ppdu_param *cfg_msg) 9728 { 9729 wmi_pdev_he_tb_action_frm_cmd_fixed_param *cmd; 9730 wmi_buf_t buf; 9731 uint8_t *buf_ptr; 9732 uint32_t len, frm_len_aligned; 9733 QDF_STATUS ret; 9734 9735 frm_len_aligned = roundup(cfg_msg->frm_len, sizeof(uint32_t)); 9736 /* Allocate memory for the WMI command */ 9737 len = sizeof(*cmd) + WMI_TLV_HDR_SIZE + frm_len_aligned; 9738 9739 buf = wmi_buf_alloc(wmi_handle, len); 9740 if (!buf) 9741 return QDF_STATUS_E_NOMEM; 9742 9743 buf_ptr = wmi_buf_data(buf); 9744 qdf_mem_zero(buf_ptr, len); 9745 9746 /* Populate the WMI command */ 9747 cmd = (wmi_pdev_he_tb_action_frm_cmd_fixed_param *)buf_ptr; 9748 9749 WMITLV_SET_HDR(&cmd->tlv_header, 9750 WMITLV_TAG_STRUC_wmi_pdev_he_tb_action_frm_cmd_fixed_param, 9751 WMITLV_GET_STRUCT_TLVLEN( 9752 wmi_pdev_he_tb_action_frm_cmd_fixed_param)); 9753 cmd->enable = cfg_msg->cfg; 9754 cmd->data_len = cfg_msg->frm_len; 9755 9756 buf_ptr += sizeof(*cmd); 9757 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, frm_len_aligned); 9758 buf_ptr += WMI_TLV_HDR_SIZE; 9759 9760 qdf_mem_copy(buf_ptr, cfg_msg->data, cmd->data_len); 9761 9762 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 9763 WMI_PDEV_HE_TB_ACTION_FRM_CMDID); 9764 if (QDF_IS_STATUS_ERROR(ret)) { 9765 wmi_err("HE TB action frame cmnd send fail, ret %d", ret); 9766 wmi_buf_free(buf); 9767 } 9768 9769 return ret; 9770 } 9771 9772 static QDF_STATUS save_fw_version_cmd_tlv(wmi_unified_t wmi_handle, void *evt_buf) 9773 { 9774 WMI_SERVICE_READY_EVENTID_param_tlvs *param_buf; 9775 wmi_service_ready_event_fixed_param *ev; 9776 9777 9778 param_buf = (WMI_SERVICE_READY_EVENTID_param_tlvs *) evt_buf; 9779 9780 ev = (wmi_service_ready_event_fixed_param *) param_buf->fixed_param; 9781 if (!ev) 9782 return QDF_STATUS_E_FAILURE; 9783 9784 /*Save fw version from service ready message */ 9785 /*This will be used while sending INIT message */ 9786 qdf_mem_copy(&wmi_handle->fw_abi_version, &ev->fw_abi_vers, 9787 sizeof(wmi_handle->fw_abi_version)); 9788 9789 return QDF_STATUS_SUCCESS; 9790 } 9791 9792 /** 9793 * check_and_update_fw_version_cmd_tlv() - save fw version 9794 * @wmi_handle: pointer to wmi handle 9795 * @evt_buf: pointer to the event buffer 9796 * 9797 * This function extracts and saves the firmware WMI ABI version 9798 * 9799 * Return: QDF_STATUS_SUCCESS for success otherwise failure 9800 * 9801 */ 9802 static QDF_STATUS check_and_update_fw_version_cmd_tlv(wmi_unified_t wmi_handle, 9803 void *evt_buf) 9804 { 9805 WMI_READY_EVENTID_param_tlvs *param_buf = NULL; 9806 wmi_ready_event_fixed_param *ev = NULL; 9807 9808 param_buf = (WMI_READY_EVENTID_param_tlvs *) evt_buf; 9809 ev = param_buf->fixed_param; 9810 if (!wmi_versions_are_compatible((struct _wmi_abi_version *) 9811 &wmi_handle->final_abi_vers, 9812 &ev->fw_abi_vers)) { 9813 /* 9814 * Error: Our host version and the given firmware version 9815 * are incompatible. 9816 **/ 9817 wmi_debug("Error: Incompatible WMI version." 9818 "Host: %d,%d,0x%x 0x%x 0x%x 0x%x, FW: %d,%d,0x%x 0x%x 0x%x 0x%x", 9819 WMI_VER_GET_MAJOR(wmi_handle->final_abi_vers. 9820 abi_version_0), 9821 WMI_VER_GET_MINOR(wmi_handle->final_abi_vers. 9822 abi_version_0), 9823 wmi_handle->final_abi_vers.abi_version_ns_0, 9824 wmi_handle->final_abi_vers.abi_version_ns_1, 9825 wmi_handle->final_abi_vers.abi_version_ns_2, 9826 wmi_handle->final_abi_vers.abi_version_ns_3, 9827 WMI_VER_GET_MAJOR(ev->fw_abi_vers.abi_version_0), 9828 WMI_VER_GET_MINOR(ev->fw_abi_vers.abi_version_0), 9829 ev->fw_abi_vers.abi_version_ns_0, 9830 ev->fw_abi_vers.abi_version_ns_1, 9831 ev->fw_abi_vers.abi_version_ns_2, 9832 ev->fw_abi_vers.abi_version_ns_3); 9833 9834 return QDF_STATUS_E_FAILURE; 9835 } 9836 qdf_mem_copy(&wmi_handle->final_abi_vers, &ev->fw_abi_vers, 9837 sizeof(wmi_abi_version)); 9838 qdf_mem_copy(&wmi_handle->fw_abi_version, &ev->fw_abi_vers, 9839 sizeof(wmi_abi_version)); 9840 9841 return QDF_STATUS_SUCCESS; 9842 } 9843 9844 /** 9845 * send_log_supported_evt_cmd_tlv() - Enable/Disable FW diag/log events 9846 * @wmi_handle: wmi handle 9847 * @event: Event received from FW 9848 * @len: Length of the event 9849 * 9850 * Enables the low frequency events and disables the high frequency 9851 * events. Bit 17 indicates if the event if low/high frequency. 9852 * 1 - high frequency, 0 - low frequency 9853 * 9854 * Return: QDF_STATUS_SUCCESS for success or error code 9855 */ 9856 static QDF_STATUS send_log_supported_evt_cmd_tlv(wmi_unified_t wmi_handle, 9857 uint8_t *event, 9858 uint32_t len) 9859 { 9860 uint32_t num_of_diag_events_logs; 9861 wmi_diag_event_log_config_fixed_param *cmd; 9862 wmi_buf_t buf; 9863 uint8_t *buf_ptr; 9864 uint32_t *cmd_args, *evt_args; 9865 uint32_t buf_len, i; 9866 9867 WMI_DIAG_EVENT_LOG_SUPPORTED_EVENTID_param_tlvs *param_buf; 9868 wmi_diag_event_log_supported_event_fixed_params *wmi_event; 9869 9870 wmi_debug("Received WMI_DIAG_EVENT_LOG_SUPPORTED_EVENTID"); 9871 9872 param_buf = (WMI_DIAG_EVENT_LOG_SUPPORTED_EVENTID_param_tlvs *) event; 9873 if (!param_buf) { 9874 wmi_err("Invalid log supported event buffer"); 9875 return QDF_STATUS_E_INVAL; 9876 } 9877 wmi_event = param_buf->fixed_param; 9878 num_of_diag_events_logs = wmi_event->num_of_diag_events_logs; 9879 9880 if (num_of_diag_events_logs > 9881 param_buf->num_diag_events_logs_list) { 9882 wmi_err("message number of events %d is more than tlv hdr content %d", 9883 num_of_diag_events_logs, 9884 param_buf->num_diag_events_logs_list); 9885 return QDF_STATUS_E_INVAL; 9886 } 9887 9888 evt_args = param_buf->diag_events_logs_list; 9889 if (!evt_args) { 9890 wmi_err("Event list is empty, num_of_diag_events_logs=%d", 9891 num_of_diag_events_logs); 9892 return QDF_STATUS_E_INVAL; 9893 } 9894 9895 wmi_debug("num_of_diag_events_logs=%d", num_of_diag_events_logs); 9896 9897 /* Free any previous allocation */ 9898 if (wmi_handle->events_logs_list) { 9899 qdf_mem_free(wmi_handle->events_logs_list); 9900 wmi_handle->events_logs_list = NULL; 9901 } 9902 9903 if (num_of_diag_events_logs > 9904 (WMI_SVC_MSG_MAX_SIZE / sizeof(uint32_t))) { 9905 wmi_err("excess num of logs: %d", num_of_diag_events_logs); 9906 QDF_ASSERT(0); 9907 return QDF_STATUS_E_INVAL; 9908 } 9909 /* Store the event list for run time enable/disable */ 9910 wmi_handle->events_logs_list = qdf_mem_malloc(num_of_diag_events_logs * 9911 sizeof(uint32_t)); 9912 if (!wmi_handle->events_logs_list) 9913 return QDF_STATUS_E_NOMEM; 9914 9915 wmi_handle->num_of_diag_events_logs = num_of_diag_events_logs; 9916 9917 /* Prepare the send buffer */ 9918 buf_len = sizeof(*cmd) + WMI_TLV_HDR_SIZE + 9919 (num_of_diag_events_logs * sizeof(uint32_t)); 9920 9921 buf = wmi_buf_alloc(wmi_handle, buf_len); 9922 if (!buf) { 9923 qdf_mem_free(wmi_handle->events_logs_list); 9924 wmi_handle->events_logs_list = NULL; 9925 return QDF_STATUS_E_NOMEM; 9926 } 9927 9928 cmd = (wmi_diag_event_log_config_fixed_param *) wmi_buf_data(buf); 9929 buf_ptr = (uint8_t *) cmd; 9930 9931 WMITLV_SET_HDR(&cmd->tlv_header, 9932 WMITLV_TAG_STRUC_wmi_diag_event_log_config_fixed_param, 9933 WMITLV_GET_STRUCT_TLVLEN( 9934 wmi_diag_event_log_config_fixed_param)); 9935 9936 cmd->num_of_diag_events_logs = num_of_diag_events_logs; 9937 9938 buf_ptr += sizeof(wmi_diag_event_log_config_fixed_param); 9939 9940 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, 9941 (num_of_diag_events_logs * sizeof(uint32_t))); 9942 9943 cmd_args = (uint32_t *) (buf_ptr + WMI_TLV_HDR_SIZE); 9944 9945 /* Populate the events */ 9946 for (i = 0; i < num_of_diag_events_logs; i++) { 9947 /* Low freq (0) - Enable (1) the event 9948 * High freq (1) - Disable (0) the event 9949 */ 9950 WMI_DIAG_ID_ENABLED_DISABLED_SET(cmd_args[i], 9951 !(WMI_DIAG_FREQUENCY_GET(evt_args[i]))); 9952 /* Set the event ID */ 9953 WMI_DIAG_ID_SET(cmd_args[i], 9954 WMI_DIAG_ID_GET(evt_args[i])); 9955 /* Set the type */ 9956 WMI_DIAG_TYPE_SET(cmd_args[i], 9957 WMI_DIAG_TYPE_GET(evt_args[i])); 9958 /* Storing the event/log list in WMI */ 9959 wmi_handle->events_logs_list[i] = evt_args[i]; 9960 } 9961 9962 wmi_mtrace(WMI_DIAG_EVENT_LOG_CONFIG_CMDID, NO_SESSION, 0); 9963 if (wmi_unified_cmd_send(wmi_handle, buf, buf_len, 9964 WMI_DIAG_EVENT_LOG_CONFIG_CMDID)) { 9965 wmi_err("WMI_DIAG_EVENT_LOG_CONFIG_CMDID failed"); 9966 wmi_buf_free(buf); 9967 /* Not clearing events_logs_list, though wmi cmd failed. 9968 * Host can still have this list 9969 */ 9970 return QDF_STATUS_E_INVAL; 9971 } 9972 9973 return 0; 9974 } 9975 9976 /** 9977 * send_enable_specific_fw_logs_cmd_tlv() - Start/Stop logging of diag log id 9978 * @wmi_handle: wmi handle 9979 * @start_log: Start logging related parameters 9980 * 9981 * Send the command to the FW based on which specific logging of diag 9982 * event/log id can be started/stopped 9983 * 9984 * Return: None 9985 */ 9986 static QDF_STATUS send_enable_specific_fw_logs_cmd_tlv(wmi_unified_t wmi_handle, 9987 struct wmi_wifi_start_log *start_log) 9988 { 9989 wmi_diag_event_log_config_fixed_param *cmd; 9990 wmi_buf_t buf; 9991 uint8_t *buf_ptr; 9992 uint32_t len, count, log_level, i; 9993 uint32_t *cmd_args; 9994 uint32_t total_len; 9995 count = 0; 9996 9997 if (!wmi_handle->events_logs_list) { 9998 wmi_debug("Not received event/log list from FW, yet"); 9999 return QDF_STATUS_E_NOMEM; 10000 } 10001 /* total_len stores the number of events where BITS 17 and 18 are set. 10002 * i.e., events of high frequency (17) and for extended debugging (18) 10003 */ 10004 total_len = 0; 10005 for (i = 0; i < wmi_handle->num_of_diag_events_logs; i++) { 10006 if ((WMI_DIAG_FREQUENCY_GET(wmi_handle->events_logs_list[i])) && 10007 (WMI_DIAG_EXT_FEATURE_GET(wmi_handle->events_logs_list[i]))) 10008 total_len++; 10009 } 10010 10011 len = sizeof(*cmd) + WMI_TLV_HDR_SIZE + 10012 (total_len * sizeof(uint32_t)); 10013 10014 buf = wmi_buf_alloc(wmi_handle, len); 10015 if (!buf) 10016 return QDF_STATUS_E_NOMEM; 10017 10018 cmd = (wmi_diag_event_log_config_fixed_param *) wmi_buf_data(buf); 10019 buf_ptr = (uint8_t *) cmd; 10020 10021 WMITLV_SET_HDR(&cmd->tlv_header, 10022 WMITLV_TAG_STRUC_wmi_diag_event_log_config_fixed_param, 10023 WMITLV_GET_STRUCT_TLVLEN( 10024 wmi_diag_event_log_config_fixed_param)); 10025 10026 cmd->num_of_diag_events_logs = total_len; 10027 10028 buf_ptr += sizeof(wmi_diag_event_log_config_fixed_param); 10029 10030 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, 10031 (total_len * sizeof(uint32_t))); 10032 10033 cmd_args = (uint32_t *) (buf_ptr + WMI_TLV_HDR_SIZE); 10034 10035 if (start_log->verbose_level >= WMI_LOG_LEVEL_ACTIVE) 10036 log_level = 1; 10037 else 10038 log_level = 0; 10039 10040 wmi_debug("Length: %d Log_level: %d", total_len, log_level); 10041 for (i = 0; i < wmi_handle->num_of_diag_events_logs; i++) { 10042 uint32_t val = wmi_handle->events_logs_list[i]; 10043 if ((WMI_DIAG_FREQUENCY_GET(val)) && 10044 (WMI_DIAG_EXT_FEATURE_GET(val))) { 10045 10046 WMI_DIAG_ID_SET(cmd_args[count], 10047 WMI_DIAG_ID_GET(val)); 10048 WMI_DIAG_TYPE_SET(cmd_args[count], 10049 WMI_DIAG_TYPE_GET(val)); 10050 WMI_DIAG_ID_ENABLED_DISABLED_SET(cmd_args[count], 10051 log_level); 10052 wmi_debug("Idx:%d, val:%x", i, val); 10053 count++; 10054 } 10055 } 10056 10057 wmi_mtrace(WMI_DIAG_EVENT_LOG_CONFIG_CMDID, NO_SESSION, 0); 10058 if (wmi_unified_cmd_send(wmi_handle, buf, len, 10059 WMI_DIAG_EVENT_LOG_CONFIG_CMDID)) { 10060 wmi_err("WMI_DIAG_EVENT_LOG_CONFIG_CMDID failed"); 10061 wmi_buf_free(buf); 10062 return QDF_STATUS_E_INVAL; 10063 } 10064 10065 return QDF_STATUS_SUCCESS; 10066 } 10067 10068 /** 10069 * send_flush_logs_to_fw_cmd_tlv() - Send log flush command to FW 10070 * @wmi_handle: WMI handle 10071 * 10072 * This function is used to send the flush command to the FW, 10073 * that will flush the fw logs that are residue in the FW 10074 * 10075 * Return: None 10076 */ 10077 static QDF_STATUS send_flush_logs_to_fw_cmd_tlv(wmi_unified_t wmi_handle) 10078 { 10079 wmi_debug_mesg_flush_fixed_param *cmd; 10080 wmi_buf_t buf; 10081 int len = sizeof(*cmd); 10082 QDF_STATUS ret; 10083 10084 buf = wmi_buf_alloc(wmi_handle, len); 10085 if (!buf) 10086 return QDF_STATUS_E_NOMEM; 10087 10088 cmd = (wmi_debug_mesg_flush_fixed_param *) wmi_buf_data(buf); 10089 WMITLV_SET_HDR(&cmd->tlv_header, 10090 WMITLV_TAG_STRUC_wmi_debug_mesg_flush_fixed_param, 10091 WMITLV_GET_STRUCT_TLVLEN( 10092 wmi_debug_mesg_flush_fixed_param)); 10093 cmd->reserved0 = 0; 10094 10095 wmi_mtrace(WMI_DEBUG_MESG_FLUSH_CMDID, NO_SESSION, 0); 10096 ret = wmi_unified_cmd_send(wmi_handle, 10097 buf, 10098 len, 10099 WMI_DEBUG_MESG_FLUSH_CMDID); 10100 if (QDF_IS_STATUS_ERROR(ret)) { 10101 wmi_err("Failed to send WMI_DEBUG_MESG_FLUSH_CMDID"); 10102 wmi_buf_free(buf); 10103 return QDF_STATUS_E_INVAL; 10104 } 10105 wmi_debug("Sent WMI_DEBUG_MESG_FLUSH_CMDID to FW"); 10106 10107 return ret; 10108 } 10109 10110 #ifdef BIG_ENDIAN_HOST 10111 #ifdef WLAN_FEATURE_FIPS_BER_CCMGCM 10112 /** 10113 * fips_extend_align_data_be() - LE to BE conversion of FIPS extend ev data 10114 * @wmi_handle: wmi handle 10115 * @param: fips extend param related parameters 10116 * 10117 * Return: QDF_STATUS - success or error status 10118 */ 10119 static QDF_STATUS fips_extend_align_data_be(wmi_unified_t wmi_handle, 10120 struct fips_extend_params *param) 10121 { 10122 unsigned char *key_unaligned, *nonce_iv_unaligned, *data_unaligned; 10123 int c; 10124 u_int8_t *key_aligned = NULL; 10125 u_int8_t *nonce_iv_aligned = NULL; 10126 u_int8_t *data_aligned = NULL; 10127 int ret = QDF_STATUS_SUCCESS; 10128 10129 /* Assigning unaligned space to copy the key */ 10130 key_unaligned = qdf_mem_malloc(sizeof(u_int8_t) * 10131 param->cmd_params.key_len + FIPS_ALIGN); 10132 /* Checking if kmalloc is successful to allocate space */ 10133 if (!key_unaligned) 10134 return QDF_STATUS_E_INVAL; 10135 10136 data_unaligned = qdf_mem_malloc(sizeof(u_int8_t) * param->data_len + 10137 FIPS_ALIGN); 10138 /* Checking if kmalloc is successful to allocate space */ 10139 if (!data_unaligned) { 10140 ret = QDF_STATUS_E_INVAL; 10141 goto fips_align_fail_data; 10142 } 10143 10144 /* Checking if space is aligned */ 10145 if (!FIPS_IS_ALIGNED(key_unaligned, FIPS_ALIGN)) { 10146 /* align to 4 */ 10147 key_aligned = (u_int8_t *)FIPS_ALIGNTO(key_unaligned, 10148 FIPS_ALIGN); 10149 } else { 10150 key_aligned = (u_int8_t *)key_unaligned; 10151 } 10152 10153 /* memset and copy content from key to key aligned */ 10154 OS_MEMSET(key_aligned, 0, param->cmd_params.key_len); 10155 OS_MEMCPY(key_aligned, param->cmd_params.key, 10156 param->cmd_params.key_len); 10157 10158 /* print a hexdump for host debug */ 10159 wmi_debug("Aligned and Copied Key: "); 10160 qdf_trace_hex_dump(QDF_MODULE_ID_WMI, QDF_TRACE_LEVEL_DEBUG, 10161 key_aligned, param->cmd_params.key_len); 10162 10163 /* Checking of space is aligned */ 10164 if (!FIPS_IS_ALIGNED(data_unaligned, FIPS_ALIGN)) { 10165 /* align to 4 */ 10166 data_aligned = 10167 (u_int8_t *)FIPS_ALIGNTO(data_unaligned, FIPS_ALIGN); 10168 } else { 10169 data_aligned = (u_int8_t *)data_unaligned; 10170 } 10171 10172 /* memset and copy content from data to data aligned */ 10173 OS_MEMSET(data_aligned, 0, param->data_len); 10174 OS_MEMCPY(data_aligned, param->data, param->data_len); 10175 10176 /* print a hexdump for host debug */ 10177 wmi_debug("\t Properly Aligned and Copied Data: "); 10178 qdf_trace_hex_dump(QDF_MODULE_ID_WMI, QDF_TRACE_LEVEL_DEBUG, 10179 data_aligned, param->data_len); 10180 10181 /* converting to little Endian */ 10182 for (c = 0; c < param->cmd_params.key_len / 4; c++) { 10183 *((u_int32_t *)key_aligned + c) = 10184 qdf_cpu_to_le32(*((u_int32_t *)key_aligned + c)); 10185 } 10186 for (c = 0; c < param->data_len / 4; c++) { 10187 *((u_int32_t *)data_aligned + c) = 10188 qdf_cpu_to_le32(*((u_int32_t *)data_aligned + c)); 10189 } 10190 10191 /* update endian data */ 10192 OS_MEMCPY(param->cmd_params.key, key_aligned, 10193 param->cmd_params.key_len); 10194 OS_MEMCPY(param->data, data_aligned, param->data_len); 10195 10196 if (param->cmd_params.nonce_iv_len) { 10197 nonce_iv_unaligned = qdf_mem_malloc(sizeof(u_int8_t) * 10198 param->cmd_params.nonce_iv_len + 10199 FIPS_ALIGN); 10200 10201 /* Checking if kmalloc is successful to allocate space */ 10202 if (!nonce_iv_unaligned) { 10203 ret = QDF_STATUS_E_INVAL; 10204 goto fips_align_fail_nonce_iv; 10205 } 10206 /* Checking if space is aligned */ 10207 if (!FIPS_IS_ALIGNED(nonce_iv_unaligned, FIPS_ALIGN)) { 10208 /* align to 4 */ 10209 nonce_iv_aligned = 10210 (u_int8_t *)FIPS_ALIGNTO(nonce_iv_unaligned, 10211 FIPS_ALIGN); 10212 } else { 10213 nonce_iv_aligned = (u_int8_t *)nonce_iv_unaligned; 10214 } 10215 10216 /* memset and copy content from iv to iv aligned */ 10217 OS_MEMSET(nonce_iv_aligned, 0, param->cmd_params.nonce_iv_len); 10218 OS_MEMCPY(nonce_iv_aligned, param->cmd_params.nonce_iv, 10219 param->cmd_params.nonce_iv_len); 10220 10221 /* print a hexdump for host debug */ 10222 wmi_debug("\t Aligned and Copied Nonce_IV: "); 10223 qdf_trace_hex_dump(QDF_MODULE_ID_WMI, QDF_TRACE_LEVEL_DEBUG, 10224 nonce_iv_aligned, 10225 param->cmd_params.nonce_iv_len); 10226 10227 for (c = 0; c < param->cmd_params.nonce_iv_len / 4; c++) { 10228 *((u_int32_t *)nonce_iv_aligned + c) = 10229 qdf_cpu_to_le32(*((u_int32_t *)nonce_iv_aligned + c)); 10230 } 10231 } 10232 10233 /* clean up allocated spaces */ 10234 qdf_mem_free(nonce_iv_unaligned); 10235 nonce_iv_unaligned = NULL; 10236 nonce_iv_aligned = NULL; 10237 10238 fips_align_fail_nonce_iv: 10239 qdf_mem_free(data_unaligned); 10240 data_unaligned = NULL; 10241 data_aligned = NULL; 10242 10243 fips_align_fail_data: 10244 qdf_mem_free(key_unaligned); 10245 key_unaligned = NULL; 10246 key_aligned = NULL; 10247 10248 return ret; 10249 } 10250 #endif 10251 10252 /** 10253 * fips_align_data_be() - LE to BE conversion of FIPS ev data 10254 * @wmi_handle: wmi handle 10255 * @param: fips param related parameters 10256 * 10257 * Return: QDF_STATUS - success or error status 10258 */ 10259 static QDF_STATUS fips_align_data_be(wmi_unified_t wmi_handle, 10260 struct fips_params *param) 10261 { 10262 unsigned char *key_unaligned, *data_unaligned; 10263 int c; 10264 u_int8_t *key_aligned = NULL; 10265 u_int8_t *data_aligned = NULL; 10266 10267 /* Assigning unaligned space to copy the key */ 10268 key_unaligned = qdf_mem_malloc( 10269 sizeof(u_int8_t)*param->key_len + FIPS_ALIGN); 10270 data_unaligned = qdf_mem_malloc( 10271 sizeof(u_int8_t)*param->data_len + FIPS_ALIGN); 10272 10273 /* Checking if kmalloc is successful to allocate space */ 10274 if (!key_unaligned) 10275 return QDF_STATUS_SUCCESS; 10276 /* Checking if space is aligned */ 10277 if (!FIPS_IS_ALIGNED(key_unaligned, FIPS_ALIGN)) { 10278 /* align to 4 */ 10279 key_aligned = 10280 (u_int8_t *)FIPS_ALIGNTO(key_unaligned, 10281 FIPS_ALIGN); 10282 } else { 10283 key_aligned = (u_int8_t *)key_unaligned; 10284 } 10285 10286 /* memset and copy content from key to key aligned */ 10287 OS_MEMSET(key_aligned, 0, param->key_len); 10288 OS_MEMCPY(key_aligned, param->key, param->key_len); 10289 10290 /* print a hexdump for host debug */ 10291 print_hex_dump(KERN_DEBUG, 10292 "\t Aligned and Copied Key:@@@@ ", 10293 DUMP_PREFIX_NONE, 10294 16, 1, key_aligned, param->key_len, true); 10295 10296 /* Checking if kmalloc is successful to allocate space */ 10297 if (!data_unaligned) 10298 return QDF_STATUS_SUCCESS; 10299 /* Checking of space is aligned */ 10300 if (!FIPS_IS_ALIGNED(data_unaligned, FIPS_ALIGN)) { 10301 /* align to 4 */ 10302 data_aligned = 10303 (u_int8_t *)FIPS_ALIGNTO(data_unaligned, 10304 FIPS_ALIGN); 10305 } else { 10306 data_aligned = (u_int8_t *)data_unaligned; 10307 } 10308 10309 /* memset and copy content from data to data aligned */ 10310 OS_MEMSET(data_aligned, 0, param->data_len); 10311 OS_MEMCPY(data_aligned, param->data, param->data_len); 10312 10313 /* print a hexdump for host debug */ 10314 print_hex_dump(KERN_DEBUG, 10315 "\t Properly Aligned and Copied Data:@@@@ ", 10316 DUMP_PREFIX_NONE, 10317 16, 1, data_aligned, param->data_len, true); 10318 10319 /* converting to little Endian both key_aligned and 10320 * data_aligned*/ 10321 for (c = 0; c < param->key_len/4; c++) { 10322 *((u_int32_t *)key_aligned+c) = 10323 qdf_cpu_to_le32(*((u_int32_t *)key_aligned+c)); 10324 } 10325 for (c = 0; c < param->data_len/4; c++) { 10326 *((u_int32_t *)data_aligned+c) = 10327 qdf_cpu_to_le32(*((u_int32_t *)data_aligned+c)); 10328 } 10329 10330 /* update endian data to key and data vectors */ 10331 OS_MEMCPY(param->key, key_aligned, param->key_len); 10332 OS_MEMCPY(param->data, data_aligned, param->data_len); 10333 10334 /* clean up allocated spaces */ 10335 qdf_mem_free(key_unaligned); 10336 key_unaligned = NULL; 10337 key_aligned = NULL; 10338 10339 qdf_mem_free(data_unaligned); 10340 data_unaligned = NULL; 10341 data_aligned = NULL; 10342 10343 return QDF_STATUS_SUCCESS; 10344 } 10345 #else 10346 #ifdef WLAN_FEATURE_FIPS_BER_CCMGCM 10347 static QDF_STATUS fips_extend_align_data_be(wmi_unified_t wmi_handle, 10348 struct fips_extend_params *param) 10349 { 10350 return QDF_STATUS_SUCCESS; 10351 } 10352 #endif 10353 10354 static QDF_STATUS fips_align_data_be(wmi_unified_t wmi_handle, 10355 struct fips_params *param) 10356 { 10357 return QDF_STATUS_SUCCESS; 10358 } 10359 #endif 10360 10361 #ifdef WLAN_FEATURE_DISA 10362 /** 10363 * send_encrypt_decrypt_send_cmd_tlv() - send encrypt/decrypt cmd to fw 10364 * @wmi_handle: wmi handle 10365 * @encrypt_decrypt_params: encrypt/decrypt params 10366 * 10367 * Return: QDF_STATUS_SUCCESS for success or error code 10368 */ 10369 static QDF_STATUS 10370 send_encrypt_decrypt_send_cmd_tlv(wmi_unified_t wmi_handle, 10371 struct disa_encrypt_decrypt_req_params 10372 *encrypt_decrypt_params) 10373 { 10374 wmi_vdev_encrypt_decrypt_data_req_cmd_fixed_param *cmd; 10375 wmi_buf_t wmi_buf; 10376 uint8_t *buf_ptr; 10377 QDF_STATUS ret; 10378 uint32_t len; 10379 10380 wmi_debug("Send encrypt decrypt cmd"); 10381 10382 len = sizeof(*cmd) + 10383 encrypt_decrypt_params->data_len + 10384 WMI_TLV_HDR_SIZE; 10385 wmi_buf = wmi_buf_alloc(wmi_handle, len); 10386 if (!wmi_buf) 10387 return QDF_STATUS_E_NOMEM; 10388 10389 buf_ptr = wmi_buf_data(wmi_buf); 10390 cmd = (wmi_vdev_encrypt_decrypt_data_req_cmd_fixed_param *)buf_ptr; 10391 10392 WMITLV_SET_HDR(&cmd->tlv_header, 10393 WMITLV_TAG_STRUC_wmi_vdev_encrypt_decrypt_data_req_cmd_fixed_param, 10394 WMITLV_GET_STRUCT_TLVLEN( 10395 wmi_vdev_encrypt_decrypt_data_req_cmd_fixed_param)); 10396 10397 cmd->vdev_id = encrypt_decrypt_params->vdev_id; 10398 cmd->key_flag = encrypt_decrypt_params->key_flag; 10399 cmd->key_idx = encrypt_decrypt_params->key_idx; 10400 cmd->key_cipher = encrypt_decrypt_params->key_cipher; 10401 cmd->key_len = encrypt_decrypt_params->key_len; 10402 cmd->key_txmic_len = encrypt_decrypt_params->key_txmic_len; 10403 cmd->key_rxmic_len = encrypt_decrypt_params->key_rxmic_len; 10404 10405 qdf_mem_copy(cmd->key_data, encrypt_decrypt_params->key_data, 10406 encrypt_decrypt_params->key_len); 10407 10408 qdf_mem_copy(cmd->mac_hdr, encrypt_decrypt_params->mac_header, 10409 MAX_MAC_HEADER_LEN); 10410 10411 cmd->data_len = encrypt_decrypt_params->data_len; 10412 10413 if (cmd->data_len) { 10414 buf_ptr += sizeof(*cmd); 10415 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, 10416 roundup(encrypt_decrypt_params->data_len, 10417 sizeof(uint32_t))); 10418 buf_ptr += WMI_TLV_HDR_SIZE; 10419 qdf_mem_copy(buf_ptr, encrypt_decrypt_params->data, 10420 encrypt_decrypt_params->data_len); 10421 } 10422 10423 /* This conversion is to facilitate data to FW in little endian */ 10424 cmd->pn[5] = encrypt_decrypt_params->pn[0]; 10425 cmd->pn[4] = encrypt_decrypt_params->pn[1]; 10426 cmd->pn[3] = encrypt_decrypt_params->pn[2]; 10427 cmd->pn[2] = encrypt_decrypt_params->pn[3]; 10428 cmd->pn[1] = encrypt_decrypt_params->pn[4]; 10429 cmd->pn[0] = encrypt_decrypt_params->pn[5]; 10430 10431 wmi_mtrace(WMI_VDEV_ENCRYPT_DECRYPT_DATA_REQ_CMDID, cmd->vdev_id, 0); 10432 ret = wmi_unified_cmd_send(wmi_handle, 10433 wmi_buf, len, 10434 WMI_VDEV_ENCRYPT_DECRYPT_DATA_REQ_CMDID); 10435 if (QDF_IS_STATUS_ERROR(ret)) { 10436 wmi_err("Failed to send ENCRYPT DECRYPT cmd: %d", ret); 10437 wmi_buf_free(wmi_buf); 10438 } 10439 10440 return ret; 10441 } 10442 #endif /* WLAN_FEATURE_DISA */ 10443 10444 /** 10445 * send_pdev_fips_cmd_tlv() - send pdev fips cmd to fw 10446 * @wmi_handle: wmi handle 10447 * @param: pointer to hold pdev fips param 10448 * 10449 * Return: QDF_STATUS_SUCCESS for success or error code 10450 */ 10451 static QDF_STATUS 10452 send_pdev_fips_cmd_tlv(wmi_unified_t wmi_handle, 10453 struct fips_params *param) 10454 { 10455 wmi_pdev_fips_cmd_fixed_param *cmd; 10456 wmi_buf_t buf; 10457 uint8_t *buf_ptr; 10458 uint32_t len = sizeof(wmi_pdev_fips_cmd_fixed_param); 10459 QDF_STATUS retval = QDF_STATUS_SUCCESS; 10460 10461 /* Length TLV placeholder for array of bytes */ 10462 len += WMI_TLV_HDR_SIZE; 10463 if (param->data_len) 10464 len += (param->data_len*sizeof(uint8_t)); 10465 10466 /* 10467 * Data length must be multiples of 16 bytes - checked against 0xF - 10468 * and must be less than WMI_SVC_MSG_SIZE - static size of 10469 * wmi_pdev_fips_cmd structure 10470 */ 10471 10472 /* do sanity on the input */ 10473 if (!(((param->data_len & 0xF) == 0) && 10474 ((param->data_len > 0) && 10475 (param->data_len < (WMI_HOST_MAX_BUFFER_SIZE - 10476 sizeof(wmi_pdev_fips_cmd_fixed_param)))))) { 10477 return QDF_STATUS_E_INVAL; 10478 } 10479 10480 buf = wmi_buf_alloc(wmi_handle, len); 10481 if (!buf) 10482 return QDF_STATUS_E_FAILURE; 10483 10484 buf_ptr = (uint8_t *) wmi_buf_data(buf); 10485 cmd = (wmi_pdev_fips_cmd_fixed_param *)buf_ptr; 10486 WMITLV_SET_HDR(&cmd->tlv_header, 10487 WMITLV_TAG_STRUC_wmi_pdev_fips_cmd_fixed_param, 10488 WMITLV_GET_STRUCT_TLVLEN 10489 (wmi_pdev_fips_cmd_fixed_param)); 10490 10491 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 10492 wmi_handle, 10493 param->pdev_id); 10494 if (param->key && param->data) { 10495 cmd->key_len = param->key_len; 10496 cmd->data_len = param->data_len; 10497 cmd->fips_cmd = !!(param->op); 10498 10499 if (fips_align_data_be(wmi_handle, param) != QDF_STATUS_SUCCESS) 10500 return QDF_STATUS_E_FAILURE; 10501 10502 qdf_mem_copy(cmd->key, param->key, param->key_len); 10503 10504 if (param->mode == FIPS_ENGINE_AES_CTR || 10505 param->mode == FIPS_ENGINE_AES_MIC) { 10506 cmd->mode = param->mode; 10507 } else { 10508 cmd->mode = FIPS_ENGINE_AES_CTR; 10509 } 10510 qdf_print("Key len = %d, Data len = %d", 10511 cmd->key_len, cmd->data_len); 10512 10513 print_hex_dump(KERN_DEBUG, "Key: ", DUMP_PREFIX_NONE, 16, 1, 10514 cmd->key, cmd->key_len, true); 10515 buf_ptr += sizeof(*cmd); 10516 10517 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, param->data_len); 10518 10519 buf_ptr += WMI_TLV_HDR_SIZE; 10520 if (param->data_len) 10521 qdf_mem_copy(buf_ptr, 10522 (uint8_t *) param->data, param->data_len); 10523 10524 print_hex_dump(KERN_DEBUG, "Plain text: ", DUMP_PREFIX_NONE, 10525 16, 1, buf_ptr, cmd->data_len, true); 10526 10527 buf_ptr += param->data_len; 10528 10529 wmi_mtrace(WMI_PDEV_FIPS_CMDID, NO_SESSION, 0); 10530 retval = wmi_unified_cmd_send(wmi_handle, buf, len, 10531 WMI_PDEV_FIPS_CMDID); 10532 qdf_print("%s return value %d", __func__, retval); 10533 } else { 10534 qdf_print("\n%s:%d Key or Data is NULL", __func__, __LINE__); 10535 wmi_buf_free(buf); 10536 retval = -QDF_STATUS_E_BADMSG; 10537 } 10538 10539 return retval; 10540 } 10541 10542 #ifdef WLAN_FEATURE_FIPS_BER_CCMGCM 10543 /** 10544 * send_pdev_fips_extend_cmd_tlv() - send pdev fips cmd to fw 10545 * @wmi_handle: wmi handle 10546 * @param: pointer to hold pdev fips param 10547 * 10548 * Return: QDF_STATUS_SUCCESS for success or error code 10549 */ 10550 static QDF_STATUS 10551 send_pdev_fips_extend_cmd_tlv(wmi_unified_t wmi_handle, 10552 struct fips_extend_params *param) 10553 { 10554 wmi_pdev_fips_extend_cmd_fixed_param *cmd; 10555 wmi_buf_t buf; 10556 uint8_t *buf_ptr; 10557 uint32_t len = sizeof(wmi_pdev_fips_extend_cmd_fixed_param); 10558 uint32_t data_len_aligned; 10559 QDF_STATUS retval = QDF_STATUS_SUCCESS; 10560 10561 len += WMI_TLV_HDR_SIZE; 10562 if (param->frag_idx == 0) 10563 len += sizeof(wmi_fips_extend_cmd_init_params); 10564 10565 /* Length TLV placeholder for array of bytes */ 10566 len += WMI_TLV_HDR_SIZE; 10567 if (param->data_len) { 10568 data_len_aligned = roundup(param->data_len, sizeof(uint32_t)); 10569 len += (data_len_aligned * sizeof(uint8_t)); 10570 } 10571 10572 buf = wmi_buf_alloc(wmi_handle, len); 10573 if (!buf) 10574 return QDF_STATUS_E_FAILURE; 10575 10576 buf_ptr = (uint8_t *)wmi_buf_data(buf); 10577 cmd = (wmi_pdev_fips_extend_cmd_fixed_param *)buf_ptr; 10578 WMITLV_SET_HDR(&cmd->tlv_header, 10579 WMITLV_TAG_STRUC_wmi_pdev_fips_extend_cmd_fixed_param, 10580 WMITLV_GET_STRUCT_TLVLEN 10581 (wmi_pdev_fips_extend_cmd_fixed_param)); 10582 10583 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 10584 wmi_handle, 10585 param->pdev_id); 10586 10587 cmd->fips_cookie = param->cookie; 10588 cmd->frag_idx = param->frag_idx; 10589 cmd->more_bit = param->more_bit; 10590 cmd->data_len = param->data_len; 10591 10592 if (fips_extend_align_data_be(wmi_handle, param) != 10593 QDF_STATUS_SUCCESS) { 10594 wmi_buf_free(buf); 10595 return QDF_STATUS_E_FAILURE; 10596 } 10597 10598 buf_ptr = (uint8_t *)(cmd + 1); 10599 if (cmd->frag_idx == 0) { 10600 wmi_fips_extend_cmd_init_params *cmd_params; 10601 10602 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 10603 sizeof(wmi_fips_extend_cmd_init_params)); 10604 buf_ptr += WMI_TLV_HDR_SIZE; 10605 cmd_params = (wmi_fips_extend_cmd_init_params *)buf_ptr; 10606 WMITLV_SET_HDR(buf_ptr, 10607 WMITLV_TAG_STRUC_wmi_fips_extend_cmd_init_params, 10608 WMITLV_GET_STRUCT_TLVLEN(wmi_fips_extend_cmd_init_params)); 10609 cmd_params->fips_cmd = param->cmd_params.fips_cmd; 10610 cmd_params->key_cipher = param->cmd_params.key_cipher; 10611 cmd_params->key_len = param->cmd_params.key_len; 10612 cmd_params->nonce_iv_len = param->cmd_params.nonce_iv_len; 10613 cmd_params->tag_len = param->cmd_params.tag_len; 10614 cmd_params->aad_len = param->cmd_params.aad_len; 10615 cmd_params->payload_len = param->cmd_params.payload_len; 10616 10617 qdf_mem_copy(cmd_params->key, param->cmd_params.key, 10618 param->cmd_params.key_len); 10619 qdf_mem_copy(cmd_params->nonce_iv, param->cmd_params.nonce_iv, 10620 param->cmd_params.nonce_iv_len); 10621 10622 wmi_debug("Key len = %d, IVNoncelen = %d, Tlen = %d, Alen = %d, Plen = %d", 10623 cmd_params->key_len, cmd_params->nonce_iv_len, 10624 cmd_params->tag_len, cmd_params->aad_len, 10625 cmd_params->payload_len); 10626 10627 buf_ptr += sizeof(wmi_fips_extend_cmd_init_params); 10628 } else { 10629 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0); 10630 buf_ptr += WMI_TLV_HDR_SIZE; 10631 } 10632 10633 if (param->data_len && param->data) { 10634 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, 10635 data_len_aligned); 10636 10637 buf_ptr += WMI_TLV_HDR_SIZE; 10638 if (param->data_len) 10639 qdf_mem_copy(buf_ptr, 10640 (uint8_t *)param->data, param->data_len); 10641 10642 wmi_debug("Data: "); 10643 qdf_trace_hex_dump(QDF_MODULE_ID_WMI, QDF_TRACE_LEVEL_DEBUG, 10644 buf_ptr, cmd->data_len); 10645 10646 if (param->data_len) 10647 buf_ptr += param->data_len; 10648 } else { 10649 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, 0); 10650 buf_ptr += WMI_TLV_HDR_SIZE; 10651 } 10652 10653 wmi_mtrace(WMI_PDEV_FIPS_EXTEND_CMDID, NO_SESSION, 0); 10654 retval = wmi_unified_cmd_send(wmi_handle, buf, len, 10655 WMI_PDEV_FIPS_EXTEND_CMDID); 10656 10657 if (retval) { 10658 wmi_err("Failed to send FIPS cmd"); 10659 wmi_buf_free(buf); 10660 } 10661 10662 return retval; 10663 } 10664 10665 /** 10666 * send_pdev_fips_mode_set_cmd_tlv() - send pdev fips cmd to fw 10667 * @wmi_handle: wmi handle 10668 * @param: pointer to hold pdev fips param 10669 * 10670 * Return: QDF_STATUS_SUCCESS for success or error code 10671 */ 10672 static QDF_STATUS 10673 send_pdev_fips_mode_set_cmd_tlv(wmi_unified_t wmi_handle, 10674 struct fips_mode_set_params *param) 10675 { 10676 wmi_pdev_fips_mode_set_cmd_fixed_param *cmd; 10677 wmi_buf_t buf; 10678 uint8_t *buf_ptr; 10679 uint32_t len = sizeof(wmi_pdev_fips_mode_set_cmd_fixed_param); 10680 QDF_STATUS retval = QDF_STATUS_SUCCESS; 10681 10682 buf = wmi_buf_alloc(wmi_handle, len); 10683 if (!buf) 10684 return QDF_STATUS_E_FAILURE; 10685 10686 buf_ptr = (uint8_t *)wmi_buf_data(buf); 10687 cmd = (wmi_pdev_fips_mode_set_cmd_fixed_param *)buf_ptr; 10688 WMITLV_SET_HDR(&cmd->tlv_header, 10689 WMITLV_TAG_STRUC_wmi_pdev_fips_mode_set_cmd_fixed_param, 10690 WMITLV_GET_STRUCT_TLVLEN 10691 (wmi_pdev_fips_mode_set_cmd_fixed_param)); 10692 10693 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 10694 wmi_handle, 10695 param->pdev_id); 10696 10697 cmd->fips_mode_set = param->mode; 10698 wmi_mtrace(WMI_PDEV_FIPS_MODE_SET_CMDID, NO_SESSION, 0); 10699 retval = wmi_unified_cmd_send(wmi_handle, buf, len, 10700 WMI_PDEV_FIPS_MODE_SET_CMDID); 10701 if (retval) { 10702 wmi_err("Failed to send FIPS mode enable cmd"); 10703 wmi_buf_free(buf); 10704 } 10705 return retval; 10706 } 10707 #endif 10708 10709 /** 10710 * send_wlan_profile_enable_cmd_tlv() - send wlan profile enable command 10711 * to fw 10712 * @wmi_handle: wmi handle 10713 * @param: pointer to wlan profile param 10714 * 10715 * Return: QDF_STATUS_SUCCESS for success or error code 10716 */ 10717 static QDF_STATUS 10718 send_wlan_profile_enable_cmd_tlv(wmi_unified_t wmi_handle, 10719 struct wlan_profile_params *param) 10720 { 10721 wmi_buf_t buf; 10722 uint16_t len; 10723 QDF_STATUS ret; 10724 wmi_wlan_profile_enable_profile_id_cmd_fixed_param *profile_enable_cmd; 10725 10726 len = sizeof(wmi_wlan_profile_enable_profile_id_cmd_fixed_param); 10727 buf = wmi_buf_alloc(wmi_handle, len); 10728 if (!buf) { 10729 wmi_err("Failed to send WMI_WLAN_PROFILE_ENABLE_PROFILE_ID_CMDID"); 10730 return QDF_STATUS_E_NOMEM; 10731 } 10732 10733 profile_enable_cmd = 10734 (wmi_wlan_profile_enable_profile_id_cmd_fixed_param *) 10735 wmi_buf_data(buf); 10736 WMITLV_SET_HDR(&profile_enable_cmd->tlv_header, 10737 WMITLV_TAG_STRUC_wmi_wlan_profile_enable_profile_id_cmd_fixed_param, 10738 WMITLV_GET_STRUCT_TLVLEN 10739 (wmi_wlan_profile_enable_profile_id_cmd_fixed_param)); 10740 10741 profile_enable_cmd->profile_id = param->profile_id; 10742 profile_enable_cmd->enable = param->enable; 10743 wmi_mtrace(WMI_WLAN_PROFILE_ENABLE_PROFILE_ID_CMDID, 10744 NO_SESSION, 0); 10745 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 10746 WMI_WLAN_PROFILE_ENABLE_PROFILE_ID_CMDID); 10747 if (ret) { 10748 wmi_err("Failed to send PROFILE_ENABLE_PROFILE_ID_CMDID"); 10749 wmi_buf_free(buf); 10750 } 10751 return ret; 10752 } 10753 10754 /** 10755 * send_wlan_profile_trigger_cmd_tlv() - send wlan profile trigger command 10756 * to fw 10757 * @wmi_handle: wmi handle 10758 * @param: pointer to wlan profile param 10759 * 10760 * Return: QDF_STATUS_SUCCESS for success or error code 10761 */ 10762 static QDF_STATUS 10763 send_wlan_profile_trigger_cmd_tlv(wmi_unified_t wmi_handle, 10764 struct wlan_profile_params *param) 10765 { 10766 wmi_buf_t buf; 10767 uint16_t len; 10768 QDF_STATUS ret; 10769 wmi_wlan_profile_trigger_cmd_fixed_param *prof_trig_cmd; 10770 10771 len = sizeof(wmi_wlan_profile_trigger_cmd_fixed_param); 10772 buf = wmi_buf_alloc(wmi_handle, len); 10773 if (!buf) { 10774 wmi_err("Failed to send WMI_WLAN_PROFILE_TRIGGER_CMDID"); 10775 return QDF_STATUS_E_NOMEM; 10776 } 10777 10778 prof_trig_cmd = 10779 (wmi_wlan_profile_trigger_cmd_fixed_param *) 10780 wmi_buf_data(buf); 10781 10782 WMITLV_SET_HDR(&prof_trig_cmd->tlv_header, 10783 WMITLV_TAG_STRUC_wmi_wlan_profile_trigger_cmd_fixed_param, 10784 WMITLV_GET_STRUCT_TLVLEN 10785 (wmi_wlan_profile_trigger_cmd_fixed_param)); 10786 10787 prof_trig_cmd->enable = param->enable; 10788 wmi_mtrace(WMI_WLAN_PROFILE_TRIGGER_CMDID, NO_SESSION, 0); 10789 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 10790 WMI_WLAN_PROFILE_TRIGGER_CMDID); 10791 if (ret) { 10792 wmi_err("Failed to send WMI_WLAN_PROFILE_TRIGGER_CMDID"); 10793 wmi_buf_free(buf); 10794 } 10795 return ret; 10796 } 10797 10798 /** 10799 * send_wlan_profile_hist_intvl_cmd_tlv() - send wlan profile interval command 10800 * to fw 10801 * @wmi_handle: wmi handle 10802 * @param: pointer to wlan profile param 10803 * 10804 * Return: QDF_STATUS_SUCCESS for success or error code 10805 */ 10806 static QDF_STATUS 10807 send_wlan_profile_hist_intvl_cmd_tlv(wmi_unified_t wmi_handle, 10808 struct wlan_profile_params *param) 10809 { 10810 wmi_buf_t buf; 10811 int32_t len = 0; 10812 QDF_STATUS ret; 10813 wmi_wlan_profile_set_hist_intvl_cmd_fixed_param *hist_intvl_cmd; 10814 10815 len = sizeof(wmi_wlan_profile_set_hist_intvl_cmd_fixed_param); 10816 buf = wmi_buf_alloc(wmi_handle, len); 10817 if (!buf) { 10818 wmi_err("Failed to send WMI_WLAN_PROFILE_SET_HIST_INTVL_CMDID"); 10819 return QDF_STATUS_E_NOMEM; 10820 } 10821 10822 hist_intvl_cmd = 10823 (wmi_wlan_profile_set_hist_intvl_cmd_fixed_param *) 10824 wmi_buf_data(buf); 10825 10826 WMITLV_SET_HDR(&hist_intvl_cmd->tlv_header, 10827 WMITLV_TAG_STRUC_wmi_wlan_profile_set_hist_intvl_cmd_fixed_param, 10828 WMITLV_GET_STRUCT_TLVLEN 10829 (wmi_wlan_profile_set_hist_intvl_cmd_fixed_param)); 10830 10831 hist_intvl_cmd->profile_id = param->profile_id; 10832 hist_intvl_cmd->value = param->enable; 10833 wmi_mtrace(WMI_WLAN_PROFILE_SET_HIST_INTVL_CMDID, 10834 NO_SESSION, 0); 10835 10836 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 10837 WMI_WLAN_PROFILE_SET_HIST_INTVL_CMDID); 10838 if (ret) { 10839 wmi_err("Failed to send PROFILE_SET_HIST_INTVL_CMDID"); 10840 wmi_buf_free(buf); 10841 } 10842 return ret; 10843 } 10844 10845 /** 10846 * send_fw_test_cmd_tlv() - send fw test command to fw. 10847 * @wmi_handle: wmi handle 10848 * @wmi_fwtest: fw test command 10849 * 10850 * This function sends fw test command to fw. 10851 * 10852 * Return: CDF STATUS 10853 */ 10854 static 10855 QDF_STATUS send_fw_test_cmd_tlv(wmi_unified_t wmi_handle, 10856 struct set_fwtest_params *wmi_fwtest) 10857 { 10858 wmi_fwtest_set_param_cmd_fixed_param *cmd; 10859 wmi_buf_t wmi_buf; 10860 uint16_t len; 10861 10862 len = sizeof(*cmd); 10863 10864 wmi_buf = wmi_buf_alloc(wmi_handle, len); 10865 if (!wmi_buf) 10866 return QDF_STATUS_E_NOMEM; 10867 10868 cmd = (wmi_fwtest_set_param_cmd_fixed_param *) wmi_buf_data(wmi_buf); 10869 WMITLV_SET_HDR(&cmd->tlv_header, 10870 WMITLV_TAG_STRUC_wmi_fwtest_set_param_cmd_fixed_param, 10871 WMITLV_GET_STRUCT_TLVLEN( 10872 wmi_fwtest_set_param_cmd_fixed_param)); 10873 cmd->param_id = wmi_fwtest->arg; 10874 cmd->param_value = wmi_fwtest->value; 10875 10876 wmi_mtrace(WMI_FWTEST_CMDID, NO_SESSION, 0); 10877 if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len, 10878 WMI_FWTEST_CMDID)) { 10879 wmi_err("Failed to send fw test command"); 10880 wmi_buf_free(wmi_buf); 10881 return QDF_STATUS_E_FAILURE; 10882 } 10883 10884 return QDF_STATUS_SUCCESS; 10885 } 10886 10887 static uint16_t wfa_config_param_len(enum wfa_test_cmds config) 10888 { 10889 uint16_t len = 0; 10890 10891 if (config == WFA_CONFIG_RXNE) 10892 len += WMI_TLV_HDR_SIZE + sizeof(wmi_wfa_config_rsnxe); 10893 else 10894 len += WMI_TLV_HDR_SIZE; 10895 10896 if (config == WFA_CONFIG_CSA) 10897 len += WMI_TLV_HDR_SIZE + sizeof(wmi_wfa_config_csa); 10898 else 10899 len += WMI_TLV_HDR_SIZE; 10900 10901 if (config == WFA_CONFIG_OCV) 10902 len += WMI_TLV_HDR_SIZE + sizeof(wmi_wfa_config_ocv); 10903 else 10904 len += WMI_TLV_HDR_SIZE; 10905 10906 if (config == WFA_CONFIG_SA_QUERY) 10907 len += WMI_TLV_HDR_SIZE + sizeof(wmi_wfa_config_saquery); 10908 else 10909 len += WMI_TLV_HDR_SIZE; 10910 10911 return len; 10912 } 10913 10914 /** 10915 * wmi_fill_ocv_frame_type() - Fill host ocv frm type into WMI ocv frm type. 10916 * @host_frmtype: Host defined OCV frame type 10917 * @ocv_frmtype: Pointer to hold WMI OCV frame type 10918 * 10919 * This function converts and fills host defined OCV frame type into WMI OCV 10920 * frame type. 10921 * 10922 * Return: CDF STATUS 10923 */ 10924 static QDF_STATUS 10925 wmi_fill_ocv_frame_type(uint32_t host_frmtype, uint32_t *ocv_frmtype) 10926 { 10927 switch (host_frmtype) { 10928 case WMI_HOST_WFA_CONFIG_OCV_FRMTYPE_SAQUERY_REQ: 10929 *ocv_frmtype = WMI_WFA_CONFIG_OCV_FRMTYPE_SAQUERY_REQ; 10930 break; 10931 10932 case WMI_HOST_WFA_CONFIG_OCV_FRMTYPE_SAQUERY_RSP: 10933 *ocv_frmtype = WMI_WFA_CONFIG_OCV_FRMTYPE_SAQUERY_RSP; 10934 break; 10935 10936 case WMI_HOST_WFA_CONFIG_OCV_FRMTYPE_FT_REASSOC_REQ: 10937 *ocv_frmtype = WMI_WFA_CONFIG_OCV_FRMTYPE_FT_REASSOC_REQ; 10938 break; 10939 10940 case WMI_HOST_WFA_CONFIG_OCV_FRMTYPE_FILS_REASSOC_REQ: 10941 *ocv_frmtype = WMI_WFA_CONFIG_OCV_FRMTYPE_FILS_REASSOC_REQ; 10942 break; 10943 10944 default: 10945 wmi_err("Invalid command type cmd %d", host_frmtype); 10946 return QDF_STATUS_E_FAILURE; 10947 } 10948 10949 return QDF_STATUS_SUCCESS; 10950 } 10951 10952 /** 10953 * send_wfa_test_cmd_tlv() - send wfa test command to fw. 10954 * @wmi_handle: wmi handle 10955 * @wmi_wfatest: wfa test command 10956 * 10957 * This function sends wfa test command to fw. 10958 * 10959 * Return: CDF STATUS 10960 */ 10961 static 10962 QDF_STATUS send_wfa_test_cmd_tlv(wmi_unified_t wmi_handle, 10963 struct set_wfatest_params *wmi_wfatest) 10964 { 10965 wmi_wfa_config_cmd_fixed_param *cmd; 10966 wmi_wfa_config_rsnxe *rxne; 10967 wmi_wfa_config_csa *csa; 10968 wmi_wfa_config_ocv *ocv; 10969 wmi_wfa_config_saquery *saquery; 10970 wmi_buf_t wmi_buf; 10971 uint16_t len = sizeof(*cmd); 10972 uint8_t *buf_ptr; 10973 10974 len += wfa_config_param_len(wmi_wfatest->cmd); 10975 wmi_buf = wmi_buf_alloc(wmi_handle, len); 10976 if (!wmi_buf) 10977 return QDF_STATUS_E_NOMEM; 10978 10979 cmd = (wmi_wfa_config_cmd_fixed_param *)wmi_buf_data(wmi_buf); 10980 WMITLV_SET_HDR(&cmd->tlv_header, 10981 WMITLV_TAG_STRUC_wmi_wfa_config_cmd_fixed_param, 10982 WMITLV_GET_STRUCT_TLVLEN( 10983 wmi_wfa_config_cmd_fixed_param)); 10984 10985 cmd->vdev_id = wmi_wfatest->vdev_id; 10986 buf_ptr = (uint8_t *)(cmd + 1); 10987 10988 if (wmi_wfatest->cmd == WFA_CONFIG_RXNE) { 10989 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 10990 sizeof(wmi_wfa_config_rsnxe)); 10991 buf_ptr += WMI_TLV_HDR_SIZE; 10992 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_STRUC_wmi_wfa_config_rsnxe, 10993 WMITLV_GET_STRUCT_TLVLEN(wmi_wfa_config_rsnxe)); 10994 rxne = (wmi_wfa_config_rsnxe *)buf_ptr; 10995 rxne->rsnxe_param = wmi_wfatest->value; 10996 buf_ptr += sizeof(wmi_wfa_config_rsnxe); 10997 } else { 10998 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0); 10999 buf_ptr += WMI_TLV_HDR_SIZE; 11000 } 11001 11002 if (wmi_wfatest->cmd == WFA_CONFIG_CSA) { 11003 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 11004 sizeof(wmi_wfa_config_csa)); 11005 buf_ptr += WMI_TLV_HDR_SIZE; 11006 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_STRUC_wmi_wfa_config_csa, 11007 WMITLV_GET_STRUCT_TLVLEN(wmi_wfa_config_csa)); 11008 csa = (wmi_wfa_config_csa *)buf_ptr; 11009 csa->ignore_csa = wmi_wfatest->value; 11010 buf_ptr += sizeof(wmi_wfa_config_csa); 11011 } else { 11012 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0); 11013 buf_ptr += WMI_TLV_HDR_SIZE; 11014 } 11015 11016 if (wmi_wfatest->cmd == WFA_CONFIG_OCV) { 11017 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 11018 sizeof(wmi_wfa_config_ocv)); 11019 buf_ptr += WMI_TLV_HDR_SIZE; 11020 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_STRUC_wmi_wfa_config_ocv, 11021 WMITLV_GET_STRUCT_TLVLEN(wmi_wfa_config_ocv)); 11022 ocv = (wmi_wfa_config_ocv *)buf_ptr; 11023 11024 if (wmi_fill_ocv_frame_type(wmi_wfatest->ocv_param->frame_type, 11025 &ocv->frame_types)) 11026 goto error; 11027 11028 ocv->chan_freq = wmi_wfatest->ocv_param->freq; 11029 buf_ptr += sizeof(wmi_wfa_config_ocv); 11030 } else { 11031 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0); 11032 buf_ptr += WMI_TLV_HDR_SIZE; 11033 } 11034 11035 if (wmi_wfatest->cmd == WFA_CONFIG_SA_QUERY) { 11036 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 11037 sizeof(wmi_wfa_config_saquery)); 11038 buf_ptr += WMI_TLV_HDR_SIZE; 11039 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_STRUC_wmi_wfa_config_saquery, 11040 WMITLV_GET_STRUCT_TLVLEN(wmi_wfa_config_saquery)); 11041 11042 saquery = (wmi_wfa_config_saquery *)buf_ptr; 11043 saquery->remain_connect_on_saquery_timeout = wmi_wfatest->value; 11044 } else { 11045 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0); 11046 buf_ptr += WMI_TLV_HDR_SIZE; 11047 } 11048 11049 wmi_mtrace(WMI_WFA_CONFIG_CMDID, wmi_wfatest->vdev_id, 0); 11050 if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len, 11051 WMI_WFA_CONFIG_CMDID)) { 11052 wmi_err("Failed to send wfa test command"); 11053 goto error; 11054 } 11055 11056 return QDF_STATUS_SUCCESS; 11057 11058 error: 11059 wmi_buf_free(wmi_buf); 11060 return QDF_STATUS_E_FAILURE; 11061 } 11062 11063 /** 11064 * send_unit_test_cmd_tlv() - send unit test command to fw. 11065 * @wmi_handle: wmi handle 11066 * @wmi_utest: unit test command 11067 * 11068 * This function send unit test command to fw. 11069 * 11070 * Return: CDF STATUS 11071 */ 11072 static QDF_STATUS send_unit_test_cmd_tlv(wmi_unified_t wmi_handle, 11073 struct wmi_unit_test_cmd *wmi_utest) 11074 { 11075 wmi_unit_test_cmd_fixed_param *cmd; 11076 wmi_buf_t wmi_buf; 11077 uint8_t *buf_ptr; 11078 int i; 11079 uint16_t len, args_tlv_len; 11080 uint32_t *unit_test_cmd_args; 11081 11082 args_tlv_len = 11083 WMI_TLV_HDR_SIZE + wmi_utest->num_args * sizeof(uint32_t); 11084 len = sizeof(wmi_unit_test_cmd_fixed_param) + args_tlv_len; 11085 11086 wmi_buf = wmi_buf_alloc(wmi_handle, len); 11087 if (!wmi_buf) 11088 return QDF_STATUS_E_NOMEM; 11089 11090 cmd = (wmi_unit_test_cmd_fixed_param *) wmi_buf_data(wmi_buf); 11091 buf_ptr = (uint8_t *) cmd; 11092 WMITLV_SET_HDR(&cmd->tlv_header, 11093 WMITLV_TAG_STRUC_wmi_unit_test_cmd_fixed_param, 11094 WMITLV_GET_STRUCT_TLVLEN(wmi_unit_test_cmd_fixed_param)); 11095 cmd->vdev_id = wmi_utest->vdev_id; 11096 cmd->module_id = wmi_utest->module_id; 11097 cmd->num_args = wmi_utest->num_args; 11098 cmd->diag_token = wmi_utest->diag_token; 11099 buf_ptr += sizeof(wmi_unit_test_cmd_fixed_param); 11100 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, 11101 (wmi_utest->num_args * sizeof(uint32_t))); 11102 unit_test_cmd_args = (uint32_t *) (buf_ptr + WMI_TLV_HDR_SIZE); 11103 wmi_debug("VDEV ID: %d MODULE ID: %d TOKEN: %d", 11104 cmd->vdev_id, cmd->module_id, cmd->diag_token); 11105 wmi_debug("%d num of args = ", wmi_utest->num_args); 11106 for (i = 0; (i < wmi_utest->num_args && i < WMI_UNIT_TEST_MAX_NUM_ARGS); i++) { 11107 unit_test_cmd_args[i] = wmi_utest->args[i]; 11108 wmi_debug("%d,", wmi_utest->args[i]); 11109 } 11110 wmi_mtrace(WMI_UNIT_TEST_CMDID, cmd->vdev_id, 0); 11111 if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len, 11112 WMI_UNIT_TEST_CMDID)) { 11113 wmi_err("Failed to send unit test command"); 11114 wmi_buf_free(wmi_buf); 11115 return QDF_STATUS_E_FAILURE; 11116 } 11117 11118 return QDF_STATUS_SUCCESS; 11119 } 11120 11121 /** 11122 * send_power_dbg_cmd_tlv() - send power debug commands 11123 * @wmi_handle: wmi handle 11124 * @param: wmi power debug parameter 11125 * 11126 * Send WMI_POWER_DEBUG_CMDID parameters to fw. 11127 * 11128 * Return: QDF_STATUS_SUCCESS on success, QDF_STATUS_E_** on error 11129 */ 11130 static QDF_STATUS send_power_dbg_cmd_tlv(wmi_unified_t wmi_handle, 11131 struct wmi_power_dbg_params *param) 11132 { 11133 wmi_buf_t buf = NULL; 11134 QDF_STATUS status; 11135 int len, args_tlv_len; 11136 uint8_t *buf_ptr; 11137 uint8_t i; 11138 wmi_pdev_wal_power_debug_cmd_fixed_param *cmd; 11139 uint32_t *cmd_args; 11140 11141 /* Prepare and send power debug cmd parameters */ 11142 args_tlv_len = WMI_TLV_HDR_SIZE + param->num_args * sizeof(uint32_t); 11143 len = sizeof(*cmd) + args_tlv_len; 11144 buf = wmi_buf_alloc(wmi_handle, len); 11145 if (!buf) 11146 return QDF_STATUS_E_NOMEM; 11147 11148 buf_ptr = (uint8_t *) wmi_buf_data(buf); 11149 cmd = (wmi_pdev_wal_power_debug_cmd_fixed_param *) buf_ptr; 11150 WMITLV_SET_HDR(&cmd->tlv_header, 11151 WMITLV_TAG_STRUC_wmi_pdev_wal_power_debug_cmd_fixed_param, 11152 WMITLV_GET_STRUCT_TLVLEN 11153 (wmi_pdev_wal_power_debug_cmd_fixed_param)); 11154 11155 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 11156 wmi_handle, 11157 param->pdev_id); 11158 cmd->module_id = param->module_id; 11159 cmd->num_args = param->num_args; 11160 buf_ptr += sizeof(*cmd); 11161 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, 11162 (param->num_args * sizeof(uint32_t))); 11163 cmd_args = (uint32_t *) (buf_ptr + WMI_TLV_HDR_SIZE); 11164 wmi_debug("%d num of args = ", param->num_args); 11165 for (i = 0; (i < param->num_args && i < WMI_MAX_POWER_DBG_ARGS); i++) { 11166 cmd_args[i] = param->args[i]; 11167 wmi_debug("%d,", param->args[i]); 11168 } 11169 11170 wmi_mtrace(WMI_PDEV_WAL_POWER_DEBUG_CMDID, NO_SESSION, 0); 11171 status = wmi_unified_cmd_send(wmi_handle, buf, 11172 len, WMI_PDEV_WAL_POWER_DEBUG_CMDID); 11173 if (QDF_IS_STATUS_ERROR(status)) { 11174 wmi_err("wmi_unified_cmd_send WMI_PDEV_WAL_POWER_DEBUG_CMDID returned Error %d", 11175 status); 11176 goto error; 11177 } 11178 11179 return QDF_STATUS_SUCCESS; 11180 error: 11181 wmi_buf_free(buf); 11182 11183 return status; 11184 } 11185 11186 /** 11187 * send_dfs_phyerr_offload_en_cmd_tlv() - send dfs phyerr offload enable cmd 11188 * @wmi_handle: wmi handle 11189 * @pdev_id: pdev id 11190 * 11191 * Send WMI_PDEV_DFS_PHYERR_OFFLOAD_ENABLE_CMDID command to firmware. 11192 * 11193 * Return: QDF_STATUS_SUCCESS on success, QDF_STATUS_E_** on error 11194 */ 11195 static QDF_STATUS send_dfs_phyerr_offload_en_cmd_tlv(wmi_unified_t wmi_handle, 11196 uint32_t pdev_id) 11197 { 11198 wmi_pdev_dfs_phyerr_offload_enable_cmd_fixed_param *cmd; 11199 wmi_buf_t buf; 11200 uint16_t len; 11201 QDF_STATUS ret; 11202 11203 len = sizeof(*cmd); 11204 buf = wmi_buf_alloc(wmi_handle, len); 11205 11206 wmi_debug("pdev_id=%d", pdev_id); 11207 11208 if (!buf) 11209 return QDF_STATUS_E_NOMEM; 11210 11211 cmd = (wmi_pdev_dfs_phyerr_offload_enable_cmd_fixed_param *) 11212 wmi_buf_data(buf); 11213 11214 WMITLV_SET_HDR(&cmd->tlv_header, 11215 WMITLV_TAG_STRUC_wmi_pdev_dfs_phyerr_offload_enable_cmd_fixed_param, 11216 WMITLV_GET_STRUCT_TLVLEN( 11217 wmi_pdev_dfs_phyerr_offload_enable_cmd_fixed_param)); 11218 11219 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 11220 wmi_handle, 11221 pdev_id); 11222 wmi_mtrace(WMI_PDEV_DFS_PHYERR_OFFLOAD_ENABLE_CMDID, NO_SESSION, 0); 11223 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 11224 WMI_PDEV_DFS_PHYERR_OFFLOAD_ENABLE_CMDID); 11225 if (QDF_IS_STATUS_ERROR(ret)) { 11226 wmi_err("Failed to send cmd to fw, ret=%d, pdev_id=%d", 11227 ret, pdev_id); 11228 wmi_buf_free(buf); 11229 return QDF_STATUS_E_FAILURE; 11230 } 11231 11232 return QDF_STATUS_SUCCESS; 11233 } 11234 11235 /** 11236 * send_dfs_phyerr_offload_dis_cmd_tlv() - send dfs phyerr offload disable cmd 11237 * @wmi_handle: wmi handle 11238 * @pdev_id: pdev id 11239 * 11240 * Send WMI_PDEV_DFS_PHYERR_OFFLOAD_DISABLE_CMDID command to firmware. 11241 * 11242 * Return: QDF_STATUS_SUCCESS on success, QDF_STATUS_E_** on error 11243 */ 11244 static QDF_STATUS send_dfs_phyerr_offload_dis_cmd_tlv(wmi_unified_t wmi_handle, 11245 uint32_t pdev_id) 11246 { 11247 wmi_pdev_dfs_phyerr_offload_disable_cmd_fixed_param *cmd; 11248 wmi_buf_t buf; 11249 uint16_t len; 11250 QDF_STATUS ret; 11251 11252 len = sizeof(*cmd); 11253 buf = wmi_buf_alloc(wmi_handle, len); 11254 11255 wmi_debug("pdev_id=%d", pdev_id); 11256 11257 if (!buf) 11258 return QDF_STATUS_E_NOMEM; 11259 11260 cmd = (wmi_pdev_dfs_phyerr_offload_disable_cmd_fixed_param *) 11261 wmi_buf_data(buf); 11262 11263 WMITLV_SET_HDR(&cmd->tlv_header, 11264 WMITLV_TAG_STRUC_wmi_pdev_dfs_phyerr_offload_disable_cmd_fixed_param, 11265 WMITLV_GET_STRUCT_TLVLEN( 11266 wmi_pdev_dfs_phyerr_offload_disable_cmd_fixed_param)); 11267 11268 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 11269 wmi_handle, 11270 pdev_id); 11271 wmi_mtrace(WMI_PDEV_DFS_PHYERR_OFFLOAD_DISABLE_CMDID, NO_SESSION, 0); 11272 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 11273 WMI_PDEV_DFS_PHYERR_OFFLOAD_DISABLE_CMDID); 11274 if (QDF_IS_STATUS_ERROR(ret)) { 11275 wmi_err("Failed to send cmd to fw, ret=%d, pdev_id=%d", 11276 ret, pdev_id); 11277 wmi_buf_free(buf); 11278 return QDF_STATUS_E_FAILURE; 11279 } 11280 11281 return QDF_STATUS_SUCCESS; 11282 } 11283 11284 #ifdef QCA_SUPPORT_AGILE_DFS 11285 static 11286 QDF_STATUS send_adfs_ch_cfg_cmd_tlv(wmi_unified_t wmi_handle, 11287 struct vdev_adfs_ch_cfg_params *param) 11288 { 11289 /* wmi_unified_cmd_send set request of agile ADFS channel*/ 11290 wmi_vdev_adfs_ch_cfg_cmd_fixed_param *cmd; 11291 wmi_buf_t buf; 11292 QDF_STATUS ret; 11293 uint16_t len; 11294 11295 len = sizeof(*cmd); 11296 buf = wmi_buf_alloc(wmi_handle, len); 11297 11298 if (!buf) { 11299 wmi_err("wmi_buf_alloc failed"); 11300 return QDF_STATUS_E_NOMEM; 11301 } 11302 11303 cmd = (wmi_vdev_adfs_ch_cfg_cmd_fixed_param *) 11304 wmi_buf_data(buf); 11305 11306 WMITLV_SET_HDR(&cmd->tlv_header, 11307 WMITLV_TAG_STRUC_wmi_vdev_adfs_ch_cfg_cmd_fixed_param, 11308 WMITLV_GET_STRUCT_TLVLEN 11309 (wmi_vdev_adfs_ch_cfg_cmd_fixed_param)); 11310 11311 cmd->vdev_id = param->vdev_id; 11312 cmd->ocac_mode = param->ocac_mode; 11313 cmd->center_freq1 = param->center_freq1; 11314 cmd->center_freq2 = param->center_freq2; 11315 cmd->chan_freq = param->chan_freq; 11316 cmd->chan_width = param->chan_width; 11317 cmd->min_duration_ms = param->min_duration_ms; 11318 cmd->max_duration_ms = param->max_duration_ms; 11319 wmi_debug("cmd->vdev_id: %d ,cmd->ocac_mode: %d cmd->center_freq: %d", 11320 cmd->vdev_id, cmd->ocac_mode, 11321 cmd->center_freq); 11322 11323 wmi_mtrace(WMI_VDEV_ADFS_CH_CFG_CMDID, NO_SESSION, 0); 11324 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 11325 WMI_VDEV_ADFS_CH_CFG_CMDID); 11326 11327 if (QDF_IS_STATUS_ERROR(ret)) { 11328 wmi_err("Failed to send cmd to fw, ret=%d", ret); 11329 wmi_buf_free(buf); 11330 return QDF_STATUS_E_FAILURE; 11331 } 11332 11333 return QDF_STATUS_SUCCESS; 11334 } 11335 11336 static 11337 QDF_STATUS send_adfs_ocac_abort_cmd_tlv(wmi_unified_t wmi_handle, 11338 struct vdev_adfs_abort_params *param) 11339 { 11340 /*wmi_unified_cmd_send with ocac abort on ADFS channel*/ 11341 wmi_vdev_adfs_ocac_abort_cmd_fixed_param *cmd; 11342 wmi_buf_t buf; 11343 QDF_STATUS ret; 11344 uint16_t len; 11345 11346 len = sizeof(*cmd); 11347 buf = wmi_buf_alloc(wmi_handle, len); 11348 11349 if (!buf) { 11350 wmi_err("wmi_buf_alloc failed"); 11351 return QDF_STATUS_E_NOMEM; 11352 } 11353 11354 cmd = (wmi_vdev_adfs_ocac_abort_cmd_fixed_param *) 11355 wmi_buf_data(buf); 11356 11357 WMITLV_SET_HDR 11358 (&cmd->tlv_header, 11359 WMITLV_TAG_STRUC_wmi_vdev_adfs_ocac_abort_cmd_fixed_param, 11360 WMITLV_GET_STRUCT_TLVLEN 11361 (wmi_vdev_adfs_ocac_abort_cmd_fixed_param)); 11362 11363 cmd->vdev_id = param->vdev_id; 11364 11365 wmi_mtrace(WMI_VDEV_ADFS_OCAC_ABORT_CMDID, NO_SESSION, 0); 11366 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 11367 WMI_VDEV_ADFS_OCAC_ABORT_CMDID); 11368 11369 if (QDF_IS_STATUS_ERROR(ret)) { 11370 wmi_err("Failed to send cmd to fw, ret=%d", ret); 11371 wmi_buf_free(buf); 11372 return QDF_STATUS_E_FAILURE; 11373 } 11374 11375 return QDF_STATUS_SUCCESS; 11376 } 11377 #endif 11378 11379 /** 11380 * init_cmd_send_tlv() - send initialization cmd to fw 11381 * @wmi_handle: wmi handle 11382 * @param: pointer to wmi init param 11383 * 11384 * Return: QDF_STATUS_SUCCESS for success or error code 11385 */ 11386 static QDF_STATUS init_cmd_send_tlv(wmi_unified_t wmi_handle, 11387 struct wmi_init_cmd_param *param) 11388 { 11389 wmi_buf_t buf; 11390 wmi_init_cmd_fixed_param *cmd; 11391 uint8_t *buf_ptr; 11392 wmi_resource_config *resource_cfg; 11393 wlan_host_memory_chunk *host_mem_chunks; 11394 uint32_t mem_chunk_len = 0, hw_mode_len = 0; 11395 uint16_t idx; 11396 int len; 11397 QDF_STATUS ret; 11398 11399 len = sizeof(*cmd) + sizeof(wmi_resource_config) + 11400 WMI_TLV_HDR_SIZE; 11401 mem_chunk_len = (sizeof(wlan_host_memory_chunk) * MAX_MEM_CHUNKS); 11402 11403 if (param->hw_mode_id != WMI_HOST_HW_MODE_MAX) 11404 hw_mode_len = sizeof(wmi_pdev_set_hw_mode_cmd_fixed_param) + 11405 WMI_TLV_HDR_SIZE + 11406 (param->num_band_to_mac * sizeof(wmi_pdev_band_to_mac)); 11407 11408 buf = wmi_buf_alloc(wmi_handle, len + mem_chunk_len + hw_mode_len); 11409 if (!buf) 11410 return QDF_STATUS_E_FAILURE; 11411 11412 buf_ptr = (uint8_t *) wmi_buf_data(buf); 11413 cmd = (wmi_init_cmd_fixed_param *) buf_ptr; 11414 resource_cfg = (wmi_resource_config *) (buf_ptr + sizeof(*cmd)); 11415 11416 host_mem_chunks = (wlan_host_memory_chunk *) 11417 (buf_ptr + sizeof(*cmd) + sizeof(wmi_resource_config) 11418 + WMI_TLV_HDR_SIZE); 11419 11420 WMITLV_SET_HDR(&cmd->tlv_header, 11421 WMITLV_TAG_STRUC_wmi_init_cmd_fixed_param, 11422 WMITLV_GET_STRUCT_TLVLEN(wmi_init_cmd_fixed_param)); 11423 wmi_copy_resource_config(resource_cfg, param->res_cfg); 11424 WMITLV_SET_HDR(&resource_cfg->tlv_header, 11425 WMITLV_TAG_STRUC_wmi_resource_config, 11426 WMITLV_GET_STRUCT_TLVLEN(wmi_resource_config)); 11427 11428 for (idx = 0; idx < param->num_mem_chunks; ++idx) { 11429 WMITLV_SET_HDR(&(host_mem_chunks[idx].tlv_header), 11430 WMITLV_TAG_STRUC_wlan_host_memory_chunk, 11431 WMITLV_GET_STRUCT_TLVLEN 11432 (wlan_host_memory_chunk)); 11433 host_mem_chunks[idx].ptr = param->mem_chunks[idx].paddr; 11434 host_mem_chunks[idx].size = param->mem_chunks[idx].len; 11435 host_mem_chunks[idx].req_id = param->mem_chunks[idx].req_id; 11436 if (is_service_enabled_tlv(wmi_handle, 11437 WMI_SERVICE_SUPPORT_EXTEND_ADDRESS)) 11438 host_mem_chunks[idx].ptr_high = 11439 qdf_get_upper_32_bits( 11440 param->mem_chunks[idx].paddr); 11441 QDF_TRACE(QDF_MODULE_ID_ANY, QDF_TRACE_LEVEL_DEBUG, 11442 "chunk %d len %d requested ,ptr 0x%x ", 11443 idx, host_mem_chunks[idx].size, 11444 host_mem_chunks[idx].ptr); 11445 } 11446 cmd->num_host_mem_chunks = param->num_mem_chunks; 11447 len += (param->num_mem_chunks * sizeof(wlan_host_memory_chunk)); 11448 11449 WMITLV_SET_HDR((buf_ptr + sizeof(*cmd) + sizeof(wmi_resource_config)), 11450 WMITLV_TAG_ARRAY_STRUC, 11451 (sizeof(wlan_host_memory_chunk) * 11452 param->num_mem_chunks)); 11453 11454 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", 11455 resource_cfg->num_peers, resource_cfg->num_offload_peers, 11456 resource_cfg->num_vdevs, resource_cfg->num_tids, 11457 resource_cfg->num_tdls_conn_table_entries, 11458 resource_cfg->num_tdls_vdevs); 11459 11460 /* Fill hw mode id config */ 11461 buf_ptr = copy_hw_mode_in_init_cmd(wmi_handle, buf_ptr, &len, param); 11462 11463 /* Fill fw_abi_vers */ 11464 copy_fw_abi_version_tlv(wmi_handle, cmd); 11465 11466 wmi_mtrace(WMI_INIT_CMDID, NO_SESSION, 0); 11467 ret = wmi_unified_cmd_send(wmi_handle, buf, len, WMI_INIT_CMDID); 11468 if (QDF_IS_STATUS_ERROR(ret)) { 11469 wmi_err("wmi_unified_cmd_send WMI_INIT_CMDID returned Error %d", 11470 ret); 11471 wmi_buf_free(buf); 11472 } 11473 11474 return ret; 11475 11476 } 11477 11478 /** 11479 * send_addba_send_cmd_tlv() - send addba send command to fw 11480 * @wmi_handle: wmi handle 11481 * @param: pointer to delba send params 11482 * @macaddr: peer mac address 11483 * 11484 * Send WMI_ADDBA_SEND_CMDID command to firmware 11485 * Return: QDF_STATUS_SUCCESS on success. QDF_STATUS_E** on error 11486 */ 11487 static QDF_STATUS 11488 send_addba_send_cmd_tlv(wmi_unified_t wmi_handle, 11489 uint8_t macaddr[QDF_MAC_ADDR_SIZE], 11490 struct addba_send_params *param) 11491 { 11492 wmi_addba_send_cmd_fixed_param *cmd; 11493 wmi_buf_t buf; 11494 uint16_t len; 11495 QDF_STATUS ret; 11496 11497 len = sizeof(*cmd); 11498 11499 buf = wmi_buf_alloc(wmi_handle, len); 11500 if (!buf) 11501 return QDF_STATUS_E_NOMEM; 11502 11503 cmd = (wmi_addba_send_cmd_fixed_param *)wmi_buf_data(buf); 11504 11505 WMITLV_SET_HDR(&cmd->tlv_header, 11506 WMITLV_TAG_STRUC_wmi_addba_send_cmd_fixed_param, 11507 WMITLV_GET_STRUCT_TLVLEN(wmi_addba_send_cmd_fixed_param)); 11508 11509 cmd->vdev_id = param->vdev_id; 11510 WMI_CHAR_ARRAY_TO_MAC_ADDR(macaddr, &cmd->peer_macaddr); 11511 cmd->tid = param->tidno; 11512 cmd->buffersize = param->buffersize; 11513 11514 wmi_mtrace(WMI_ADDBA_SEND_CMDID, cmd->vdev_id, 0); 11515 ret = wmi_unified_cmd_send(wmi_handle, buf, len, WMI_ADDBA_SEND_CMDID); 11516 if (QDF_IS_STATUS_ERROR(ret)) { 11517 wmi_err("Failed to send cmd to fw, ret=%d", ret); 11518 wmi_buf_free(buf); 11519 return QDF_STATUS_E_FAILURE; 11520 } 11521 11522 return QDF_STATUS_SUCCESS; 11523 } 11524 11525 /** 11526 * send_delba_send_cmd_tlv() - send delba send command to fw 11527 * @wmi_handle: wmi handle 11528 * @param: pointer to delba send params 11529 * @macaddr: peer mac address 11530 * 11531 * Send WMI_DELBA_SEND_CMDID command to firmware 11532 * Return: QDF_STATUS_SUCCESS on success. QDF_STATUS_E** on error 11533 */ 11534 static QDF_STATUS 11535 send_delba_send_cmd_tlv(wmi_unified_t wmi_handle, 11536 uint8_t macaddr[QDF_MAC_ADDR_SIZE], 11537 struct delba_send_params *param) 11538 { 11539 wmi_delba_send_cmd_fixed_param *cmd; 11540 wmi_buf_t buf; 11541 uint16_t len; 11542 QDF_STATUS ret; 11543 11544 len = sizeof(*cmd); 11545 11546 buf = wmi_buf_alloc(wmi_handle, len); 11547 if (!buf) 11548 return QDF_STATUS_E_NOMEM; 11549 11550 cmd = (wmi_delba_send_cmd_fixed_param *)wmi_buf_data(buf); 11551 11552 WMITLV_SET_HDR(&cmd->tlv_header, 11553 WMITLV_TAG_STRUC_wmi_delba_send_cmd_fixed_param, 11554 WMITLV_GET_STRUCT_TLVLEN(wmi_delba_send_cmd_fixed_param)); 11555 11556 cmd->vdev_id = param->vdev_id; 11557 WMI_CHAR_ARRAY_TO_MAC_ADDR(macaddr, &cmd->peer_macaddr); 11558 cmd->tid = param->tidno; 11559 cmd->initiator = param->initiator; 11560 cmd->reasoncode = param->reasoncode; 11561 11562 wmi_mtrace(WMI_DELBA_SEND_CMDID, cmd->vdev_id, 0); 11563 ret = wmi_unified_cmd_send(wmi_handle, buf, len, WMI_DELBA_SEND_CMDID); 11564 if (QDF_IS_STATUS_ERROR(ret)) { 11565 wmi_err("Failed to send cmd to fw, ret=%d", ret); 11566 wmi_buf_free(buf); 11567 return QDF_STATUS_E_FAILURE; 11568 } 11569 11570 return QDF_STATUS_SUCCESS; 11571 } 11572 11573 /** 11574 * send_addba_clearresponse_cmd_tlv() - send addba clear response command 11575 * to fw 11576 * @wmi_handle: wmi handle 11577 * @param: pointer to addba clearresp params 11578 * @macaddr: peer mac address 11579 * Return: QDF_STATUS_SUCCESS for success or error code 11580 */ 11581 static QDF_STATUS 11582 send_addba_clearresponse_cmd_tlv(wmi_unified_t wmi_handle, 11583 uint8_t macaddr[QDF_MAC_ADDR_SIZE], 11584 struct addba_clearresponse_params *param) 11585 { 11586 wmi_addba_clear_resp_cmd_fixed_param *cmd; 11587 wmi_buf_t buf; 11588 uint16_t len; 11589 QDF_STATUS ret; 11590 11591 len = sizeof(*cmd); 11592 11593 buf = wmi_buf_alloc(wmi_handle, len); 11594 if (!buf) 11595 return QDF_STATUS_E_FAILURE; 11596 11597 cmd = (wmi_addba_clear_resp_cmd_fixed_param *)wmi_buf_data(buf); 11598 11599 WMITLV_SET_HDR(&cmd->tlv_header, 11600 WMITLV_TAG_STRUC_wmi_addba_clear_resp_cmd_fixed_param, 11601 WMITLV_GET_STRUCT_TLVLEN(wmi_addba_clear_resp_cmd_fixed_param)); 11602 11603 cmd->vdev_id = param->vdev_id; 11604 WMI_CHAR_ARRAY_TO_MAC_ADDR(macaddr, &cmd->peer_macaddr); 11605 11606 wmi_mtrace(WMI_ADDBA_CLEAR_RESP_CMDID, cmd->vdev_id, 0); 11607 ret = wmi_unified_cmd_send(wmi_handle, 11608 buf, len, WMI_ADDBA_CLEAR_RESP_CMDID); 11609 if (QDF_IS_STATUS_ERROR(ret)) { 11610 wmi_err("Failed to send cmd to fw, ret=%d", ret); 11611 wmi_buf_free(buf); 11612 return QDF_STATUS_E_FAILURE; 11613 } 11614 11615 return QDF_STATUS_SUCCESS; 11616 } 11617 11618 #ifdef OBSS_PD 11619 /** 11620 * send_obss_spatial_reuse_set_def_thresh_cmd_tlv - send obss spatial reuse set 11621 * def thresh to fw 11622 * @wmi_handle: wmi handle 11623 * @thresh: pointer to obss_spatial_reuse_def_thresh 11624 * 11625 * Return: QDF_STATUS_SUCCESS for success or error code 11626 */ 11627 static 11628 QDF_STATUS send_obss_spatial_reuse_set_def_thresh_cmd_tlv( 11629 wmi_unified_t wmi_handle, 11630 struct wmi_host_obss_spatial_reuse_set_def_thresh 11631 *thresh) 11632 { 11633 wmi_buf_t buf; 11634 wmi_obss_spatial_reuse_set_def_obss_thresh_cmd_fixed_param *cmd; 11635 QDF_STATUS ret; 11636 uint32_t cmd_len; 11637 uint32_t tlv_len; 11638 11639 cmd_len = sizeof(*cmd); 11640 11641 buf = wmi_buf_alloc(wmi_handle, cmd_len); 11642 if (!buf) 11643 return QDF_STATUS_E_NOMEM; 11644 11645 cmd = (wmi_obss_spatial_reuse_set_def_obss_thresh_cmd_fixed_param *) 11646 wmi_buf_data(buf); 11647 11648 tlv_len = WMITLV_GET_STRUCT_TLVLEN( 11649 wmi_obss_spatial_reuse_set_def_obss_thresh_cmd_fixed_param); 11650 11651 WMITLV_SET_HDR(&cmd->tlv_header, 11652 WMITLV_TAG_STRUC_wmi_obss_spatial_reuse_set_def_obss_thresh_cmd_fixed_param, 11653 tlv_len); 11654 11655 cmd->obss_min = thresh->obss_min; 11656 cmd->obss_max = thresh->obss_max; 11657 cmd->vdev_type = thresh->vdev_type; 11658 ret = wmi_unified_cmd_send(wmi_handle, buf, cmd_len, 11659 WMI_PDEV_OBSS_PD_SPATIAL_REUSE_SET_DEF_OBSS_THRESH_CMDID); 11660 if (QDF_IS_STATUS_ERROR(ret)) 11661 wmi_buf_free(buf); 11662 11663 return ret; 11664 } 11665 11666 /** 11667 * send_obss_spatial_reuse_set_cmd_tlv - send obss spatial reuse set cmd to fw 11668 * @wmi_handle: wmi handle 11669 * @obss_spatial_reuse_param: pointer to obss_spatial_reuse_param 11670 * 11671 * Return: QDF_STATUS_SUCCESS for success or error code 11672 */ 11673 static 11674 QDF_STATUS send_obss_spatial_reuse_set_cmd_tlv(wmi_unified_t wmi_handle, 11675 struct wmi_host_obss_spatial_reuse_set_param 11676 *obss_spatial_reuse_param) 11677 { 11678 wmi_buf_t buf; 11679 wmi_obss_spatial_reuse_set_cmd_fixed_param *cmd; 11680 QDF_STATUS ret; 11681 uint32_t len; 11682 11683 len = sizeof(*cmd); 11684 11685 buf = wmi_buf_alloc(wmi_handle, len); 11686 if (!buf) 11687 return QDF_STATUS_E_FAILURE; 11688 11689 cmd = (wmi_obss_spatial_reuse_set_cmd_fixed_param *)wmi_buf_data(buf); 11690 WMITLV_SET_HDR(&cmd->tlv_header, 11691 WMITLV_TAG_STRUC_wmi_obss_spatial_reuse_set_cmd_fixed_param, 11692 WMITLV_GET_STRUCT_TLVLEN 11693 (wmi_obss_spatial_reuse_set_cmd_fixed_param)); 11694 11695 cmd->enable = obss_spatial_reuse_param->enable; 11696 cmd->obss_min = obss_spatial_reuse_param->obss_min; 11697 cmd->obss_max = obss_spatial_reuse_param->obss_max; 11698 cmd->vdev_id = obss_spatial_reuse_param->vdev_id; 11699 11700 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 11701 WMI_PDEV_OBSS_PD_SPATIAL_REUSE_CMDID); 11702 11703 if (QDF_IS_STATUS_ERROR(ret)) { 11704 wmi_err( 11705 "WMI_PDEV_OBSS_PD_SPATIAL_REUSE_CMDID send returned Error %d", 11706 ret); 11707 wmi_buf_free(buf); 11708 } 11709 11710 return ret; 11711 } 11712 11713 /** 11714 * send_self_srg_bss_color_bitmap_set_cmd_tlv() - Send 64-bit BSS color bitmap 11715 * to be used by SRG based Spatial Reuse feature to the FW 11716 * @wmi_handle: wmi handle 11717 * @bitmap_0: lower 32 bits in BSS color bitmap 11718 * @bitmap_1: upper 32 bits in BSS color bitmap 11719 * @pdev_id: pdev ID 11720 * 11721 * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure 11722 */ 11723 static QDF_STATUS 11724 send_self_srg_bss_color_bitmap_set_cmd_tlv( 11725 wmi_unified_t wmi_handle, uint32_t bitmap_0, 11726 uint32_t bitmap_1, uint8_t pdev_id) 11727 { 11728 wmi_buf_t buf; 11729 wmi_pdev_srg_bss_color_bitmap_cmd_fixed_param *cmd; 11730 QDF_STATUS ret; 11731 uint32_t len; 11732 11733 len = sizeof(*cmd); 11734 11735 buf = wmi_buf_alloc(wmi_handle, len); 11736 if (!buf) 11737 return QDF_STATUS_E_FAILURE; 11738 11739 cmd = (wmi_pdev_srg_bss_color_bitmap_cmd_fixed_param *) 11740 wmi_buf_data(buf); 11741 11742 WMITLV_SET_HDR( 11743 &cmd->tlv_header, 11744 WMITLV_TAG_STRUC_wmi_pdev_srg_bss_color_bitmap_cmd_fixed_param, 11745 WMITLV_GET_STRUCT_TLVLEN 11746 (wmi_pdev_srg_bss_color_bitmap_cmd_fixed_param)); 11747 11748 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 11749 wmi_handle, pdev_id); 11750 cmd->srg_bss_color_bitmap[0] = bitmap_0; 11751 cmd->srg_bss_color_bitmap[1] = bitmap_1; 11752 11753 ret = wmi_unified_cmd_send( 11754 wmi_handle, buf, len, 11755 WMI_PDEV_SET_SRG_BSS_COLOR_BITMAP_CMDID); 11756 11757 if (QDF_IS_STATUS_ERROR(ret)) { 11758 wmi_err( 11759 "WMI_PDEV_SET_SRG_BSS_COLOR_BITMAP_CMDID send returned Error %d", 11760 ret); 11761 wmi_buf_free(buf); 11762 } 11763 11764 return ret; 11765 } 11766 11767 /** 11768 * send_self_srg_partial_bssid_bitmap_set_cmd_tlv() - Send 64-bit partial BSSID 11769 * bitmap to be used by SRG based Spatial Reuse feature to the FW 11770 * @wmi_handle: wmi handle 11771 * @bitmap_0: lower 32 bits in partial BSSID bitmap 11772 * @bitmap_1: upper 32 bits in partial BSSID bitmap 11773 * @pdev_id: pdev ID 11774 * 11775 * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure 11776 */ 11777 static QDF_STATUS 11778 send_self_srg_partial_bssid_bitmap_set_cmd_tlv( 11779 wmi_unified_t wmi_handle, uint32_t bitmap_0, 11780 uint32_t bitmap_1, uint8_t pdev_id) 11781 { 11782 wmi_buf_t buf; 11783 wmi_pdev_srg_partial_bssid_bitmap_cmd_fixed_param *cmd; 11784 QDF_STATUS ret; 11785 uint32_t len; 11786 11787 len = sizeof(*cmd); 11788 11789 buf = wmi_buf_alloc(wmi_handle, len); 11790 if (!buf) 11791 return QDF_STATUS_E_FAILURE; 11792 11793 cmd = (wmi_pdev_srg_partial_bssid_bitmap_cmd_fixed_param *) 11794 wmi_buf_data(buf); 11795 11796 WMITLV_SET_HDR( 11797 &cmd->tlv_header, 11798 WMITLV_TAG_STRUC_wmi_pdev_srg_partial_bssid_bitmap_cmd_fixed_param, 11799 WMITLV_GET_STRUCT_TLVLEN 11800 (wmi_pdev_srg_partial_bssid_bitmap_cmd_fixed_param)); 11801 11802 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 11803 wmi_handle, pdev_id); 11804 11805 cmd->srg_partial_bssid_bitmap[0] = bitmap_0; 11806 cmd->srg_partial_bssid_bitmap[1] = bitmap_1; 11807 11808 ret = wmi_unified_cmd_send( 11809 wmi_handle, buf, len, 11810 WMI_PDEV_SET_SRG_PARTIAL_BSSID_BITMAP_CMDID); 11811 11812 if (QDF_IS_STATUS_ERROR(ret)) { 11813 wmi_err( 11814 "WMI_PDEV_SET_SRG_PARTIAL_BSSID_BITMAP_CMDID send returned Error %d", 11815 ret); 11816 wmi_buf_free(buf); 11817 } 11818 11819 return ret; 11820 } 11821 11822 /** 11823 * send_self_srg_obss_color_enable_bitmap_cmd_tlv() - Send 64-bit BSS color 11824 * enable bitmap to be used by SRG based Spatial Reuse feature to the FW 11825 * @wmi_handle: wmi handle 11826 * @bitmap_0: lower 32 bits in BSS color enable bitmap 11827 * @bitmap_1: upper 32 bits in BSS color enable bitmap 11828 * @pdev_id: pdev ID 11829 * 11830 * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure 11831 */ 11832 static QDF_STATUS 11833 send_self_srg_obss_color_enable_bitmap_cmd_tlv( 11834 wmi_unified_t wmi_handle, uint32_t bitmap_0, 11835 uint32_t bitmap_1, uint8_t pdev_id) 11836 { 11837 wmi_buf_t buf; 11838 wmi_pdev_srg_obss_color_enable_bitmap_cmd_fixed_param *cmd; 11839 QDF_STATUS ret; 11840 uint32_t len; 11841 11842 len = sizeof(*cmd); 11843 11844 buf = wmi_buf_alloc(wmi_handle, len); 11845 if (!buf) 11846 return QDF_STATUS_E_FAILURE; 11847 11848 cmd = (wmi_pdev_srg_obss_color_enable_bitmap_cmd_fixed_param *) 11849 wmi_buf_data(buf); 11850 11851 WMITLV_SET_HDR( 11852 &cmd->tlv_header, 11853 WMITLV_TAG_STRUC_wmi_pdev_srg_obss_color_enable_bitmap_cmd_fixed_param, 11854 WMITLV_GET_STRUCT_TLVLEN 11855 (wmi_pdev_srg_obss_color_enable_bitmap_cmd_fixed_param)); 11856 11857 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 11858 wmi_handle, pdev_id); 11859 cmd->srg_obss_en_color_bitmap[0] = bitmap_0; 11860 cmd->srg_obss_en_color_bitmap[1] = bitmap_1; 11861 11862 ret = wmi_unified_cmd_send( 11863 wmi_handle, buf, len, 11864 WMI_PDEV_SET_SRG_OBSS_COLOR_ENABLE_BITMAP_CMDID); 11865 11866 if (QDF_IS_STATUS_ERROR(ret)) { 11867 wmi_err( 11868 "WMI_PDEV_SET_SRG_OBSS_COLOR_ENABLE_BITMAP_CMDID send returned Error %d", 11869 ret); 11870 wmi_buf_free(buf); 11871 } 11872 11873 return ret; 11874 } 11875 11876 /** 11877 * send_self_srg_obss_bssid_enable_bitmap_cmd_tlv() - Send 64-bit OBSS BSSID 11878 * enable bitmap to be used by SRG based Spatial Reuse feature to the FW 11879 * @wmi_handle: wmi handle 11880 * @bitmap_0: lower 32 bits in BSSID enable bitmap 11881 * @bitmap_1: upper 32 bits in BSSID enable bitmap 11882 * @pdev_id: pdev ID 11883 * 11884 * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure 11885 */ 11886 static QDF_STATUS 11887 send_self_srg_obss_bssid_enable_bitmap_cmd_tlv( 11888 wmi_unified_t wmi_handle, uint32_t bitmap_0, 11889 uint32_t bitmap_1, uint8_t pdev_id) 11890 { 11891 wmi_buf_t buf; 11892 wmi_pdev_srg_obss_bssid_enable_bitmap_cmd_fixed_param *cmd; 11893 QDF_STATUS ret; 11894 uint32_t len; 11895 11896 len = sizeof(*cmd); 11897 11898 buf = wmi_buf_alloc(wmi_handle, len); 11899 if (!buf) 11900 return QDF_STATUS_E_FAILURE; 11901 11902 cmd = (wmi_pdev_srg_obss_bssid_enable_bitmap_cmd_fixed_param *) 11903 wmi_buf_data(buf); 11904 11905 WMITLV_SET_HDR( 11906 &cmd->tlv_header, 11907 WMITLV_TAG_STRUC_wmi_pdev_srg_obss_bssid_enable_bitmap_cmd_fixed_param, 11908 WMITLV_GET_STRUCT_TLVLEN 11909 (wmi_pdev_srg_obss_bssid_enable_bitmap_cmd_fixed_param)); 11910 11911 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 11912 wmi_handle, pdev_id); 11913 cmd->srg_obss_en_bssid_bitmap[0] = bitmap_0; 11914 cmd->srg_obss_en_bssid_bitmap[1] = bitmap_1; 11915 11916 ret = wmi_unified_cmd_send( 11917 wmi_handle, buf, len, 11918 WMI_PDEV_SET_SRG_OBSS_BSSID_ENABLE_BITMAP_CMDID); 11919 11920 if (QDF_IS_STATUS_ERROR(ret)) { 11921 wmi_err( 11922 "WMI_PDEV_SET_SRG_OBSS_BSSID_ENABLE_BITMAP_CMDID send returned Error %d", 11923 ret); 11924 wmi_buf_free(buf); 11925 } 11926 11927 return ret; 11928 } 11929 11930 /** 11931 * send_self_non_srg_obss_color_enable_bitmap_cmd_tlv() - Send 64-bit BSS color 11932 * enable bitmap to be used by Non-SRG based Spatial Reuse feature to the FW 11933 * @wmi_handle: wmi handle 11934 * @bitmap_0: lower 32 bits in BSS color enable bitmap 11935 * @bitmap_1: upper 32 bits in BSS color enable bitmap 11936 * @pdev_id: pdev ID 11937 * 11938 * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure 11939 */ 11940 static QDF_STATUS 11941 send_self_non_srg_obss_color_enable_bitmap_cmd_tlv( 11942 wmi_unified_t wmi_handle, uint32_t bitmap_0, 11943 uint32_t bitmap_1, uint8_t pdev_id) 11944 { 11945 wmi_buf_t buf; 11946 wmi_pdev_non_srg_obss_color_enable_bitmap_cmd_fixed_param *cmd; 11947 QDF_STATUS ret; 11948 uint32_t len; 11949 11950 len = sizeof(*cmd); 11951 11952 buf = wmi_buf_alloc(wmi_handle, len); 11953 if (!buf) 11954 return QDF_STATUS_E_FAILURE; 11955 11956 cmd = (wmi_pdev_non_srg_obss_color_enable_bitmap_cmd_fixed_param *) 11957 wmi_buf_data(buf); 11958 11959 WMITLV_SET_HDR( 11960 &cmd->tlv_header, 11961 WMITLV_TAG_STRUC_wmi_pdev_non_srg_obss_color_enable_bitmap_cmd_fixed_param, 11962 WMITLV_GET_STRUCT_TLVLEN 11963 (wmi_pdev_non_srg_obss_color_enable_bitmap_cmd_fixed_param)); 11964 11965 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 11966 wmi_handle, pdev_id); 11967 cmd->non_srg_obss_en_color_bitmap[0] = bitmap_0; 11968 cmd->non_srg_obss_en_color_bitmap[1] = bitmap_1; 11969 11970 ret = wmi_unified_cmd_send( 11971 wmi_handle, buf, len, 11972 WMI_PDEV_SET_NON_SRG_OBSS_COLOR_ENABLE_BITMAP_CMDID); 11973 11974 if (QDF_IS_STATUS_ERROR(ret)) { 11975 wmi_err( 11976 "WMI_PDEV_SET_NON_SRG_OBSS_COLOR_ENABLE_BITMAP_CMDID send returned Error %d", 11977 ret); 11978 wmi_buf_free(buf); 11979 } 11980 11981 return ret; 11982 } 11983 11984 /** 11985 * send_self_non_srg_obss_bssid_enable_bitmap_cmd_tlv() - Send 64-bit OBSS BSSID 11986 * enable bitmap to be used by Non-SRG based Spatial Reuse feature to the FW 11987 * @wmi_handle: wmi handle 11988 * @bitmap_0: lower 32 bits in BSSID enable bitmap 11989 * @bitmap_1: upper 32 bits in BSSID enable bitmap 11990 * @pdev_id: pdev ID 11991 * 11992 * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure 11993 */ 11994 static QDF_STATUS 11995 send_self_non_srg_obss_bssid_enable_bitmap_cmd_tlv( 11996 wmi_unified_t wmi_handle, uint32_t bitmap_0, 11997 uint32_t bitmap_1, uint8_t pdev_id) 11998 { 11999 wmi_buf_t buf; 12000 wmi_pdev_non_srg_obss_bssid_enable_bitmap_cmd_fixed_param *cmd; 12001 QDF_STATUS ret; 12002 uint32_t len; 12003 12004 len = sizeof(*cmd); 12005 12006 buf = wmi_buf_alloc(wmi_handle, len); 12007 if (!buf) 12008 return QDF_STATUS_E_FAILURE; 12009 12010 cmd = (wmi_pdev_non_srg_obss_bssid_enable_bitmap_cmd_fixed_param *) 12011 wmi_buf_data(buf); 12012 12013 WMITLV_SET_HDR( 12014 &cmd->tlv_header, 12015 WMITLV_TAG_STRUC_wmi_pdev_non_srg_obss_bssid_enable_bitmap_cmd_fixed_param, 12016 WMITLV_GET_STRUCT_TLVLEN 12017 (wmi_pdev_non_srg_obss_bssid_enable_bitmap_cmd_fixed_param)); 12018 12019 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 12020 wmi_handle, pdev_id); 12021 cmd->non_srg_obss_en_bssid_bitmap[0] = bitmap_0; 12022 cmd->non_srg_obss_en_bssid_bitmap[1] = bitmap_1; 12023 12024 ret = wmi_unified_cmd_send( 12025 wmi_handle, buf, len, 12026 WMI_PDEV_SET_NON_SRG_OBSS_BSSID_ENABLE_BITMAP_CMDID); 12027 12028 if (QDF_IS_STATUS_ERROR(ret)) { 12029 wmi_err( 12030 "WMI_PDEV_SET_NON_SRG_OBSS_BSSID_ENABLE_BITMAP_CMDID send returned Error %d", 12031 ret); 12032 wmi_buf_free(buf); 12033 } 12034 12035 return ret; 12036 } 12037 #endif 12038 12039 static 12040 QDF_STATUS send_injector_config_cmd_tlv(wmi_unified_t wmi_handle, 12041 struct wmi_host_injector_frame_params *inject_config_params) 12042 { 12043 wmi_buf_t buf; 12044 wmi_frame_inject_cmd_fixed_param *cmd; 12045 QDF_STATUS ret; 12046 uint32_t len; 12047 12048 len = sizeof(*cmd); 12049 12050 buf = wmi_buf_alloc(wmi_handle, len); 12051 if (!buf) 12052 return QDF_STATUS_E_NOMEM; 12053 12054 cmd = (wmi_frame_inject_cmd_fixed_param *)wmi_buf_data(buf); 12055 WMITLV_SET_HDR(&cmd->tlv_header, 12056 WMITLV_TAG_STRUC_wmi_frame_inject_cmd_fixed_param, 12057 WMITLV_GET_STRUCT_TLVLEN 12058 (wmi_frame_inject_cmd_fixed_param)); 12059 12060 cmd->vdev_id = inject_config_params->vdev_id; 12061 cmd->enable = inject_config_params->enable; 12062 cmd->frame_type = inject_config_params->frame_type; 12063 cmd->frame_inject_period = inject_config_params->frame_inject_period; 12064 cmd->fc_duration = inject_config_params->frame_duration; 12065 WMI_CHAR_ARRAY_TO_MAC_ADDR(inject_config_params->dstmac, 12066 &cmd->frame_addr1); 12067 12068 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 12069 WMI_PDEV_FRAME_INJECT_CMDID); 12070 12071 if (QDF_IS_STATUS_ERROR(ret)) { 12072 wmi_err( 12073 "WMI_PDEV_FRAME_INJECT_CMDID send returned Error %d", 12074 ret); 12075 wmi_buf_free(buf); 12076 } 12077 12078 return ret; 12079 } 12080 #ifdef QCA_SUPPORT_CP_STATS 12081 /** 12082 * extract_cca_stats_tlv - api to extract congestion stats from event buffer 12083 * @wmi_handle: wma handle 12084 * @evt_buf: event buffer 12085 * @out_buff: buffer to populated after stats extraction 12086 * 12087 * Return: status of operation 12088 */ 12089 static QDF_STATUS extract_cca_stats_tlv(wmi_unified_t wmi_handle, 12090 void *evt_buf, struct wmi_host_congestion_stats *out_buff) 12091 { 12092 WMI_UPDATE_STATS_EVENTID_param_tlvs *param_buf; 12093 wmi_congestion_stats *congestion_stats; 12094 12095 param_buf = (WMI_UPDATE_STATS_EVENTID_param_tlvs *)evt_buf; 12096 congestion_stats = param_buf->congestion_stats; 12097 if (!congestion_stats) 12098 return QDF_STATUS_E_INVAL; 12099 12100 out_buff->vdev_id = congestion_stats->vdev_id; 12101 out_buff->congestion = congestion_stats->congestion; 12102 12103 wmi_debug("cca stats event processed"); 12104 return QDF_STATUS_SUCCESS; 12105 } 12106 #endif /* QCA_SUPPORT_CP_STATS */ 12107 12108 /** 12109 * extract_ctl_failsafe_check_ev_param_tlv() - extract ctl data from 12110 * event 12111 * @wmi_handle: wmi handle 12112 * @evt_buf: pointer to event buffer 12113 * @param: Pointer to hold peer ctl data 12114 * 12115 * Return: QDF_STATUS_SUCCESS for success or error code 12116 */ 12117 static QDF_STATUS extract_ctl_failsafe_check_ev_param_tlv( 12118 wmi_unified_t wmi_handle, 12119 void *evt_buf, 12120 struct wmi_host_pdev_ctl_failsafe_event *param) 12121 { 12122 WMI_PDEV_CTL_FAILSAFE_CHECK_EVENTID_param_tlvs *param_buf; 12123 wmi_pdev_ctl_failsafe_check_fixed_param *fix_param; 12124 12125 param_buf = (WMI_PDEV_CTL_FAILSAFE_CHECK_EVENTID_param_tlvs *)evt_buf; 12126 if (!param_buf) { 12127 wmi_err("Invalid ctl_failsafe event buffer"); 12128 return QDF_STATUS_E_INVAL; 12129 } 12130 12131 fix_param = param_buf->fixed_param; 12132 param->ctl_failsafe_status = fix_param->ctl_FailsafeStatus; 12133 12134 return QDF_STATUS_SUCCESS; 12135 } 12136 12137 /** 12138 * save_service_bitmap_tlv() - save service bitmap 12139 * @wmi_handle: wmi handle 12140 * @evt_buf: pointer to event buffer 12141 * @bitmap_buf: bitmap buffer, for converged legacy support 12142 * 12143 * Return: QDF_STATUS 12144 */ 12145 static 12146 QDF_STATUS save_service_bitmap_tlv(wmi_unified_t wmi_handle, void *evt_buf, 12147 void *bitmap_buf) 12148 { 12149 WMI_SERVICE_READY_EVENTID_param_tlvs *param_buf; 12150 struct wmi_soc *soc = wmi_handle->soc; 12151 12152 param_buf = (WMI_SERVICE_READY_EVENTID_param_tlvs *) evt_buf; 12153 12154 /* If it is already allocated, use that buffer. This can happen 12155 * during target stop/start scenarios where host allocation is skipped. 12156 */ 12157 if (!soc->wmi_service_bitmap) { 12158 soc->wmi_service_bitmap = 12159 qdf_mem_malloc(WMI_SERVICE_BM_SIZE * sizeof(uint32_t)); 12160 if (!soc->wmi_service_bitmap) 12161 return QDF_STATUS_E_NOMEM; 12162 } 12163 12164 qdf_mem_copy(soc->wmi_service_bitmap, 12165 param_buf->wmi_service_bitmap, 12166 (WMI_SERVICE_BM_SIZE * sizeof(uint32_t))); 12167 12168 if (bitmap_buf) 12169 qdf_mem_copy(bitmap_buf, 12170 param_buf->wmi_service_bitmap, 12171 (WMI_SERVICE_BM_SIZE * sizeof(uint32_t))); 12172 12173 return QDF_STATUS_SUCCESS; 12174 } 12175 12176 /** 12177 * save_ext_service_bitmap_tlv() - save extendend service bitmap 12178 * @wmi_handle: wmi handle 12179 * @evt_buf: pointer to event buffer 12180 * @bitmap_buf: bitmap buffer, for converged legacy support 12181 * 12182 * Return: QDF_STATUS 12183 */ 12184 static 12185 QDF_STATUS save_ext_service_bitmap_tlv(wmi_unified_t wmi_handle, void *evt_buf, 12186 void *bitmap_buf) 12187 { 12188 WMI_SERVICE_AVAILABLE_EVENTID_param_tlvs *param_buf; 12189 wmi_service_available_event_fixed_param *ev; 12190 struct wmi_soc *soc = wmi_handle->soc; 12191 uint32_t i = 0; 12192 12193 param_buf = (WMI_SERVICE_AVAILABLE_EVENTID_param_tlvs *) evt_buf; 12194 12195 ev = param_buf->fixed_param; 12196 12197 /* If it is already allocated, use that buffer. This can happen 12198 * during target stop/start scenarios where host allocation is skipped. 12199 */ 12200 if (!soc->wmi_ext_service_bitmap) { 12201 soc->wmi_ext_service_bitmap = qdf_mem_malloc( 12202 WMI_SERVICE_SEGMENT_BM_SIZE32 * sizeof(uint32_t)); 12203 if (!soc->wmi_ext_service_bitmap) 12204 return QDF_STATUS_E_NOMEM; 12205 } 12206 12207 qdf_mem_copy(soc->wmi_ext_service_bitmap, 12208 ev->wmi_service_segment_bitmap, 12209 (WMI_SERVICE_SEGMENT_BM_SIZE32 * sizeof(uint32_t))); 12210 12211 wmi_debug("wmi_ext_service_bitmap 0:0x%x, 1:0x%x, 2:0x%x, 3:0x%x", 12212 soc->wmi_ext_service_bitmap[0], soc->wmi_ext_service_bitmap[1], 12213 soc->wmi_ext_service_bitmap[2], soc->wmi_ext_service_bitmap[3]); 12214 12215 if (bitmap_buf) 12216 qdf_mem_copy(bitmap_buf, 12217 soc->wmi_ext_service_bitmap, 12218 (WMI_SERVICE_SEGMENT_BM_SIZE32 * sizeof(uint32_t))); 12219 12220 if (!param_buf->wmi_service_ext_bitmap) { 12221 wmi_debug("wmi_service_ext_bitmap not available"); 12222 return QDF_STATUS_SUCCESS; 12223 } 12224 12225 if (!soc->wmi_ext2_service_bitmap || 12226 (param_buf->num_wmi_service_ext_bitmap > 12227 soc->wmi_ext2_service_bitmap_len)) { 12228 if (soc->wmi_ext2_service_bitmap) { 12229 qdf_mem_free(soc->wmi_ext2_service_bitmap); 12230 soc->wmi_ext2_service_bitmap = NULL; 12231 } 12232 soc->wmi_ext2_service_bitmap = 12233 qdf_mem_malloc(param_buf->num_wmi_service_ext_bitmap * 12234 sizeof(uint32_t)); 12235 if (!soc->wmi_ext2_service_bitmap) 12236 return QDF_STATUS_E_NOMEM; 12237 12238 soc->wmi_ext2_service_bitmap_len = 12239 param_buf->num_wmi_service_ext_bitmap; 12240 } 12241 12242 qdf_mem_copy(soc->wmi_ext2_service_bitmap, 12243 param_buf->wmi_service_ext_bitmap, 12244 (param_buf->num_wmi_service_ext_bitmap * 12245 sizeof(uint32_t))); 12246 12247 for (i = 0; i < param_buf->num_wmi_service_ext_bitmap; i++) { 12248 wmi_debug("wmi_ext2_service_bitmap %u:0x%x", 12249 i, soc->wmi_ext2_service_bitmap[i]); 12250 } 12251 12252 return QDF_STATUS_SUCCESS; 12253 } 12254 12255 static inline void copy_ht_cap_info(uint32_t ev_target_cap, 12256 struct wlan_psoc_target_capability_info *cap) 12257 { 12258 /* except LDPC all flags are common between legacy and here 12259 * also IBFEER is not defined for TLV 12260 */ 12261 cap->ht_cap_info |= ev_target_cap & ( 12262 WMI_HT_CAP_ENABLED 12263 | WMI_HT_CAP_HT20_SGI 12264 | WMI_HT_CAP_DYNAMIC_SMPS 12265 | WMI_HT_CAP_TX_STBC 12266 | WMI_HT_CAP_TX_STBC_MASK_SHIFT 12267 | WMI_HT_CAP_RX_STBC 12268 | WMI_HT_CAP_RX_STBC_MASK_SHIFT 12269 | WMI_HT_CAP_LDPC 12270 | WMI_HT_CAP_L_SIG_TXOP_PROT 12271 | WMI_HT_CAP_MPDU_DENSITY 12272 | WMI_HT_CAP_MPDU_DENSITY_MASK_SHIFT 12273 | WMI_HT_CAP_HT40_SGI); 12274 if (ev_target_cap & WMI_HT_CAP_LDPC) 12275 cap->ht_cap_info |= WMI_HOST_HT_CAP_RX_LDPC | 12276 WMI_HOST_HT_CAP_TX_LDPC; 12277 } 12278 /** 12279 * extract_service_ready_tlv() - extract service ready event 12280 * @wmi_handle: wmi handle 12281 * @evt_buf: pointer to received event buffer 12282 * @cap: pointer to hold target capability information extracted from even 12283 * 12284 * Return: QDF_STATUS_SUCCESS for success or error code 12285 */ 12286 static QDF_STATUS extract_service_ready_tlv(wmi_unified_t wmi_handle, 12287 void *evt_buf, struct wlan_psoc_target_capability_info *cap) 12288 { 12289 WMI_SERVICE_READY_EVENTID_param_tlvs *param_buf; 12290 wmi_service_ready_event_fixed_param *ev; 12291 12292 12293 param_buf = (WMI_SERVICE_READY_EVENTID_param_tlvs *) evt_buf; 12294 12295 ev = (wmi_service_ready_event_fixed_param *) param_buf->fixed_param; 12296 if (!ev) { 12297 qdf_print("%s: wmi_buf_alloc failed", __func__); 12298 return QDF_STATUS_E_FAILURE; 12299 } 12300 12301 cap->phy_capability = ev->phy_capability; 12302 cap->max_frag_entry = ev->max_frag_entry; 12303 cap->num_rf_chains = ev->num_rf_chains; 12304 copy_ht_cap_info(ev->ht_cap_info, cap); 12305 cap->vht_cap_info = ev->vht_cap_info; 12306 cap->vht_supp_mcs = ev->vht_supp_mcs; 12307 cap->hw_min_tx_power = ev->hw_min_tx_power; 12308 cap->hw_max_tx_power = ev->hw_max_tx_power; 12309 cap->sys_cap_info = ev->sys_cap_info; 12310 cap->min_pkt_size_enable = ev->min_pkt_size_enable; 12311 cap->max_bcn_ie_size = ev->max_bcn_ie_size; 12312 cap->max_num_scan_channels = ev->max_num_scan_channels; 12313 cap->max_supported_macs = ev->max_supported_macs; 12314 cap->wmi_fw_sub_feat_caps = ev->wmi_fw_sub_feat_caps; 12315 cap->txrx_chainmask = ev->txrx_chainmask; 12316 cap->default_dbs_hw_mode_index = ev->default_dbs_hw_mode_index; 12317 cap->num_msdu_desc = ev->num_msdu_desc; 12318 cap->fw_version = ev->fw_build_vers; 12319 /* fw_version_1 is not available in TLV. */ 12320 cap->fw_version_1 = 0; 12321 12322 return QDF_STATUS_SUCCESS; 12323 } 12324 12325 /* convert_wireless_modes_tlv() - Convert REGDMN_MODE values sent by target 12326 * to host internal HOST_REGDMN_MODE values. 12327 * REGULATORY TODO : REGDMN_MODE_11AC_VHT*_2G values are not used by the 12328 * host currently. Add this in the future if required. 12329 * 11AX (Phase II) : 11ax related values are not currently 12330 * advertised separately by FW. As part of phase II regulatory bring-up, 12331 * finalize the advertisement mechanism. 12332 * @target_wireless_mode: target wireless mode received in message 12333 * 12334 * Return: returns the host internal wireless mode. 12335 */ 12336 static inline uint32_t convert_wireless_modes_tlv(uint32_t target_wireless_mode) 12337 { 12338 12339 uint32_t wireless_modes = 0; 12340 12341 wmi_debug("Target wireless mode: 0x%x", target_wireless_mode); 12342 12343 if (target_wireless_mode & REGDMN_MODE_11A) 12344 wireless_modes |= HOST_REGDMN_MODE_11A; 12345 12346 if (target_wireless_mode & REGDMN_MODE_TURBO) 12347 wireless_modes |= HOST_REGDMN_MODE_TURBO; 12348 12349 if (target_wireless_mode & REGDMN_MODE_11B) 12350 wireless_modes |= HOST_REGDMN_MODE_11B; 12351 12352 if (target_wireless_mode & REGDMN_MODE_PUREG) 12353 wireless_modes |= HOST_REGDMN_MODE_PUREG; 12354 12355 if (target_wireless_mode & REGDMN_MODE_11G) 12356 wireless_modes |= HOST_REGDMN_MODE_11G; 12357 12358 if (target_wireless_mode & REGDMN_MODE_108G) 12359 wireless_modes |= HOST_REGDMN_MODE_108G; 12360 12361 if (target_wireless_mode & REGDMN_MODE_108A) 12362 wireless_modes |= HOST_REGDMN_MODE_108A; 12363 12364 if (target_wireless_mode & REGDMN_MODE_11AC_VHT20_2G) 12365 wireless_modes |= HOST_REGDMN_MODE_11AC_VHT20_2G; 12366 12367 if (target_wireless_mode & REGDMN_MODE_XR) 12368 wireless_modes |= HOST_REGDMN_MODE_XR; 12369 12370 if (target_wireless_mode & REGDMN_MODE_11A_HALF_RATE) 12371 wireless_modes |= HOST_REGDMN_MODE_11A_HALF_RATE; 12372 12373 if (target_wireless_mode & REGDMN_MODE_11A_QUARTER_RATE) 12374 wireless_modes |= HOST_REGDMN_MODE_11A_QUARTER_RATE; 12375 12376 if (target_wireless_mode & REGDMN_MODE_11NG_HT20) 12377 wireless_modes |= HOST_REGDMN_MODE_11NG_HT20; 12378 12379 if (target_wireless_mode & REGDMN_MODE_11NA_HT20) 12380 wireless_modes |= HOST_REGDMN_MODE_11NA_HT20; 12381 12382 if (target_wireless_mode & REGDMN_MODE_11NG_HT40PLUS) 12383 wireless_modes |= HOST_REGDMN_MODE_11NG_HT40PLUS; 12384 12385 if (target_wireless_mode & REGDMN_MODE_11NG_HT40MINUS) 12386 wireless_modes |= HOST_REGDMN_MODE_11NG_HT40MINUS; 12387 12388 if (target_wireless_mode & REGDMN_MODE_11NA_HT40PLUS) 12389 wireless_modes |= HOST_REGDMN_MODE_11NA_HT40PLUS; 12390 12391 if (target_wireless_mode & REGDMN_MODE_11NA_HT40MINUS) 12392 wireless_modes |= HOST_REGDMN_MODE_11NA_HT40MINUS; 12393 12394 if (target_wireless_mode & REGDMN_MODE_11AC_VHT20) 12395 wireless_modes |= HOST_REGDMN_MODE_11AC_VHT20; 12396 12397 if (target_wireless_mode & REGDMN_MODE_11AC_VHT40PLUS) 12398 wireless_modes |= HOST_REGDMN_MODE_11AC_VHT40PLUS; 12399 12400 if (target_wireless_mode & REGDMN_MODE_11AC_VHT40MINUS) 12401 wireless_modes |= HOST_REGDMN_MODE_11AC_VHT40MINUS; 12402 12403 if (target_wireless_mode & REGDMN_MODE_11AC_VHT80) 12404 wireless_modes |= HOST_REGDMN_MODE_11AC_VHT80; 12405 12406 if (target_wireless_mode & REGDMN_MODE_11AC_VHT160) 12407 wireless_modes |= HOST_REGDMN_MODE_11AC_VHT160; 12408 12409 if (target_wireless_mode & REGDMN_MODE_11AC_VHT80_80) 12410 wireless_modes |= HOST_REGDMN_MODE_11AC_VHT80_80; 12411 12412 return wireless_modes; 12413 } 12414 12415 /** 12416 * convert_11be_phybitmap_to_reg_flags() - Convert 11BE phybitmap to 12417 * to regulatory flags. 12418 * @target_phybitmap: target phybitmap. 12419 * @phybitmap: host internal REGULATORY_PHYMODE set based on target 12420 * phybitmap. 12421 * 12422 * Return: None 12423 */ 12424 12425 #ifdef WLAN_FEATURE_11BE 12426 static void convert_11be_phybitmap_to_reg_flags(uint32_t target_phybitmap, 12427 uint32_t *phybitmap) 12428 { 12429 if (target_phybitmap & WMI_REGULATORY_PHYMODE_NO11BE) 12430 *phybitmap |= REGULATORY_PHYMODE_NO11BE; 12431 } 12432 #else 12433 static void convert_11be_phybitmap_to_reg_flags(uint32_t target_phybitmap, 12434 uint32_t *phybitmap) 12435 { 12436 } 12437 #endif 12438 12439 /* convert_phybitmap_tlv() - Convert WMI_REGULATORY_PHYBITMAP values sent by 12440 * target to host internal REGULATORY_PHYMODE values. 12441 * 12442 * @target_target_phybitmap: target phybitmap received in the message. 12443 * 12444 * Return: returns the host internal REGULATORY_PHYMODE. 12445 */ 12446 static uint32_t convert_phybitmap_tlv(uint32_t target_phybitmap) 12447 { 12448 uint32_t phybitmap = 0; 12449 12450 wmi_debug("Target phybitmap: 0x%x", target_phybitmap); 12451 12452 if (target_phybitmap & WMI_REGULATORY_PHYMODE_NO11A) 12453 phybitmap |= REGULATORY_PHYMODE_NO11A; 12454 12455 if (target_phybitmap & WMI_REGULATORY_PHYMODE_NO11B) 12456 phybitmap |= REGULATORY_PHYMODE_NO11B; 12457 12458 if (target_phybitmap & WMI_REGULATORY_PHYMODE_NO11G) 12459 phybitmap |= REGULATORY_PHYMODE_NO11G; 12460 12461 if (target_phybitmap & WMI_REGULATORY_PHYMODE_NO11N) 12462 phybitmap |= REGULATORY_CHAN_NO11N; 12463 12464 if (target_phybitmap & WMI_REGULATORY_PHYMODE_NO11AC) 12465 phybitmap |= REGULATORY_PHYMODE_NO11AC; 12466 12467 if (target_phybitmap & WMI_REGULATORY_PHYMODE_NO11AX) 12468 phybitmap |= REGULATORY_PHYMODE_NO11AX; 12469 12470 convert_11be_phybitmap_to_reg_flags(target_phybitmap, &phybitmap); 12471 12472 return phybitmap; 12473 } 12474 12475 /** 12476 * convert_11be_flags_to_modes_ext() - Convert 11BE wireless mode flag 12477 * advertised by the target to wireless mode ext flags. 12478 * @target_wireless_modes_ext: Target wireless mode 12479 * @wireless_modes_ext: Variable to hold all the target wireless mode caps. 12480 * 12481 * Return: None 12482 */ 12483 #ifdef WLAN_FEATURE_11BE 12484 static void convert_11be_flags_to_modes_ext(uint32_t target_wireless_modes_ext, 12485 uint64_t *wireless_modes_ext) 12486 { 12487 if (target_wireless_modes_ext & REGDMN_MODE_U32_11BEG_EHT20) 12488 *wireless_modes_ext |= HOST_REGDMN_MODE_11BEG_EHT20; 12489 12490 if (target_wireless_modes_ext & REGDMN_MODE_U32_11BEG_EHT40PLUS) 12491 *wireless_modes_ext |= HOST_REGDMN_MODE_11BEG_EHT40PLUS; 12492 12493 if (target_wireless_modes_ext & REGDMN_MODE_U32_11BEG_EHT40MINUS) 12494 *wireless_modes_ext |= HOST_REGDMN_MODE_11BEG_EHT40MINUS; 12495 12496 if (target_wireless_modes_ext & REGDMN_MODE_U32_11BEA_EHT20) 12497 *wireless_modes_ext |= HOST_REGDMN_MODE_11BEA_EHT20; 12498 12499 if (target_wireless_modes_ext & REGDMN_MODE_U32_11BEA_EHT40PLUS) 12500 *wireless_modes_ext |= HOST_REGDMN_MODE_11BEA_EHT40PLUS; 12501 12502 if (target_wireless_modes_ext & REGDMN_MODE_U32_11BEA_EHT40MINUS) 12503 *wireless_modes_ext |= HOST_REGDMN_MODE_11BEA_EHT40MINUS; 12504 12505 if (target_wireless_modes_ext & REGDMN_MODE_U32_11BEA_EHT80) 12506 *wireless_modes_ext |= HOST_REGDMN_MODE_11BEA_EHT80; 12507 12508 if (target_wireless_modes_ext & REGDMN_MODE_U32_11BEA_EHT160) 12509 *wireless_modes_ext |= HOST_REGDMN_MODE_11BEA_EHT160; 12510 12511 if (target_wireless_modes_ext & REGDMN_MODE_U32_11BEA_EHT320) 12512 *wireless_modes_ext |= HOST_REGDMN_MODE_11BEA_EHT320; 12513 } 12514 #else 12515 static void convert_11be_flags_to_modes_ext(uint32_t target_wireless_modes_ext, 12516 uint64_t *wireless_modes_ext) 12517 { 12518 } 12519 #endif 12520 12521 static inline uint64_t convert_wireless_modes_ext_tlv( 12522 uint32_t target_wireless_modes_ext) 12523 { 12524 uint64_t wireless_modes_ext = 0; 12525 12526 wmi_debug("Target wireless mode: 0x%x", target_wireless_modes_ext); 12527 12528 if (target_wireless_modes_ext & REGDMN_MODE_U32_11AXG_HE20) 12529 wireless_modes_ext |= HOST_REGDMN_MODE_11AXG_HE20; 12530 12531 if (target_wireless_modes_ext & REGDMN_MODE_U32_11AXG_HE40PLUS) 12532 wireless_modes_ext |= HOST_REGDMN_MODE_11AXG_HE40PLUS; 12533 12534 if (target_wireless_modes_ext & REGDMN_MODE_U32_11AXG_HE40MINUS) 12535 wireless_modes_ext |= HOST_REGDMN_MODE_11AXG_HE40MINUS; 12536 12537 if (target_wireless_modes_ext & REGDMN_MODE_U32_11AXA_HE20) 12538 wireless_modes_ext |= HOST_REGDMN_MODE_11AXA_HE20; 12539 12540 if (target_wireless_modes_ext & REGDMN_MODE_U32_11AXA_HE40PLUS) 12541 wireless_modes_ext |= HOST_REGDMN_MODE_11AXA_HE40PLUS; 12542 12543 if (target_wireless_modes_ext & REGDMN_MODE_U32_11AXA_HE40MINUS) 12544 wireless_modes_ext |= HOST_REGDMN_MODE_11AXA_HE40MINUS; 12545 12546 if (target_wireless_modes_ext & REGDMN_MODE_U32_11AXA_HE80) 12547 wireless_modes_ext |= HOST_REGDMN_MODE_11AXA_HE80; 12548 12549 if (target_wireless_modes_ext & REGDMN_MODE_U32_11AXA_HE160) 12550 wireless_modes_ext |= HOST_REGDMN_MODE_11AXA_HE160; 12551 12552 if (target_wireless_modes_ext & REGDMN_MODE_U32_11AXA_HE80_80) 12553 wireless_modes_ext |= HOST_REGDMN_MODE_11AXA_HE80_80; 12554 12555 convert_11be_flags_to_modes_ext(target_wireless_modes_ext, 12556 &wireless_modes_ext); 12557 12558 return wireless_modes_ext; 12559 } 12560 12561 /** 12562 * extract_hal_reg_cap_tlv() - extract HAL registered capabilities 12563 * @wmi_handle: wmi handle 12564 * @evt_buf: Pointer to event buffer 12565 * @cap: pointer to hold HAL reg capabilities 12566 * 12567 * Return: QDF_STATUS_SUCCESS for success or error code 12568 */ 12569 static QDF_STATUS extract_hal_reg_cap_tlv(wmi_unified_t wmi_handle, 12570 void *evt_buf, struct wlan_psoc_hal_reg_capability *cap) 12571 { 12572 WMI_SERVICE_READY_EVENTID_param_tlvs *param_buf; 12573 12574 param_buf = (WMI_SERVICE_READY_EVENTID_param_tlvs *) evt_buf; 12575 if (!param_buf || !param_buf->hal_reg_capabilities) { 12576 wmi_err("Invalid arguments"); 12577 return QDF_STATUS_E_FAILURE; 12578 } 12579 qdf_mem_copy(cap, (((uint8_t *)param_buf->hal_reg_capabilities) + 12580 sizeof(uint32_t)), 12581 sizeof(struct wlan_psoc_hal_reg_capability)); 12582 12583 cap->wireless_modes = convert_wireless_modes_tlv( 12584 param_buf->hal_reg_capabilities->wireless_modes); 12585 12586 return QDF_STATUS_SUCCESS; 12587 } 12588 12589 /** 12590 * extract_hal_reg_cap_ext2_tlv() - extract HAL registered capability ext 12591 * @wmi_handle: wmi handle 12592 * @evt_buf: Pointer to event buffer 12593 * @phy_idx: Specific phy to extract 12594 * @param: pointer to hold HAL reg capabilities 12595 * 12596 * Return: QDF_STATUS_SUCCESS for success or error code 12597 */ 12598 static QDF_STATUS extract_hal_reg_cap_ext2_tlv( 12599 wmi_unified_t wmi_handle, void *evt_buf, uint8_t phy_idx, 12600 struct wlan_psoc_host_hal_reg_capabilities_ext2 *param) 12601 { 12602 WMI_SERVICE_READY_EXT2_EVENTID_param_tlvs *param_buf; 12603 WMI_HAL_REG_CAPABILITIES_EXT2 *reg_caps; 12604 12605 if (!evt_buf) { 12606 wmi_err("null evt_buf"); 12607 return QDF_STATUS_E_INVAL; 12608 } 12609 12610 param_buf = (WMI_SERVICE_READY_EXT2_EVENTID_param_tlvs *)evt_buf; 12611 12612 if (!param_buf->num_hal_reg_caps) 12613 return QDF_STATUS_SUCCESS; 12614 12615 if (phy_idx >= param_buf->num_hal_reg_caps) 12616 return QDF_STATUS_E_INVAL; 12617 12618 reg_caps = ¶m_buf->hal_reg_caps[phy_idx]; 12619 12620 param->phy_id = reg_caps->phy_id; 12621 param->wireless_modes_ext = convert_wireless_modes_ext_tlv( 12622 reg_caps->wireless_modes_ext); 12623 12624 return QDF_STATUS_SUCCESS; 12625 } 12626 12627 /** 12628 * extract_num_mem_reqs_tlv() - Extract number of memory entries requested 12629 * @wmi_handle: wmi handle 12630 * @evt_buf: pointer to event buffer 12631 * 12632 * Return: Number of entries requested 12633 */ 12634 static uint32_t extract_num_mem_reqs_tlv(wmi_unified_t wmi_handle, 12635 void *evt_buf) 12636 { 12637 WMI_SERVICE_READY_EVENTID_param_tlvs *param_buf; 12638 wmi_service_ready_event_fixed_param *ev; 12639 12640 param_buf = (WMI_SERVICE_READY_EVENTID_param_tlvs *) evt_buf; 12641 12642 ev = (wmi_service_ready_event_fixed_param *) param_buf->fixed_param; 12643 if (!ev) { 12644 qdf_print("%s: wmi_buf_alloc failed", __func__); 12645 return 0; 12646 } 12647 12648 if (ev->num_mem_reqs > param_buf->num_mem_reqs) { 12649 wmi_err("Invalid num_mem_reqs %d:%d", 12650 ev->num_mem_reqs, param_buf->num_mem_reqs); 12651 return 0; 12652 } 12653 12654 return ev->num_mem_reqs; 12655 } 12656 12657 /** 12658 * extract_host_mem_req_tlv() - Extract host memory required from 12659 * service ready event 12660 * @wmi_handle: wmi handle 12661 * @evt_buf: pointer to event buffer 12662 * @mem_reqs: pointer to host memory request structure 12663 * @num_active_peers: number of active peers for peer cache 12664 * @num_peers: number of peers 12665 * @fw_prio: FW priority 12666 * @idx: index for memory request 12667 * 12668 * Return: Host memory request parameters requested by target 12669 */ 12670 static QDF_STATUS extract_host_mem_req_tlv(wmi_unified_t wmi_handle, 12671 void *evt_buf, 12672 host_mem_req *mem_reqs, 12673 uint32_t num_active_peers, 12674 uint32_t num_peers, 12675 enum wmi_fw_mem_prio fw_prio, 12676 uint16_t idx) 12677 { 12678 WMI_SERVICE_READY_EVENTID_param_tlvs *param_buf; 12679 12680 param_buf = (WMI_SERVICE_READY_EVENTID_param_tlvs *)evt_buf; 12681 12682 mem_reqs->req_id = (uint32_t)param_buf->mem_reqs[idx].req_id; 12683 mem_reqs->unit_size = (uint32_t)param_buf->mem_reqs[idx].unit_size; 12684 mem_reqs->num_unit_info = 12685 (uint32_t)param_buf->mem_reqs[idx].num_unit_info; 12686 mem_reqs->num_units = (uint32_t)param_buf->mem_reqs[idx].num_units; 12687 mem_reqs->tgt_num_units = 0; 12688 12689 if (((fw_prio == WMI_FW_MEM_HIGH_PRIORITY) && 12690 (mem_reqs->num_unit_info & 12691 REQ_TO_HOST_FOR_CONT_MEMORY)) || 12692 ((fw_prio == WMI_FW_MEM_LOW_PRIORITY) && 12693 (!(mem_reqs->num_unit_info & 12694 REQ_TO_HOST_FOR_CONT_MEMORY)))) { 12695 /* First allocate the memory that requires contiguous memory */ 12696 mem_reqs->tgt_num_units = mem_reqs->num_units; 12697 if (mem_reqs->num_unit_info) { 12698 if (mem_reqs->num_unit_info & 12699 NUM_UNITS_IS_NUM_PEERS) { 12700 /* 12701 * number of units allocated is equal to number 12702 * of peers, 1 extra for self peer on target. 12703 * this needs to be fixed, host and target can 12704 * get out of sync 12705 */ 12706 mem_reqs->tgt_num_units = num_peers + 1; 12707 } 12708 if (mem_reqs->num_unit_info & 12709 NUM_UNITS_IS_NUM_ACTIVE_PEERS) { 12710 /* 12711 * Requesting allocation of memory using 12712 * num_active_peers in qcache. if qcache is 12713 * disabled in host, then it should allocate 12714 * memory for num_peers instead of 12715 * num_active_peers. 12716 */ 12717 if (num_active_peers) 12718 mem_reqs->tgt_num_units = 12719 num_active_peers + 1; 12720 else 12721 mem_reqs->tgt_num_units = 12722 num_peers + 1; 12723 } 12724 } 12725 12726 wmi_debug("idx %d req %d num_units %d num_unit_info %d" 12727 "unit size %d actual units %d", 12728 idx, mem_reqs->req_id, 12729 mem_reqs->num_units, 12730 mem_reqs->num_unit_info, 12731 mem_reqs->unit_size, 12732 mem_reqs->tgt_num_units); 12733 } 12734 12735 return QDF_STATUS_SUCCESS; 12736 } 12737 12738 /** 12739 * save_fw_version_in_service_ready_tlv() - Save fw version in service 12740 * ready function 12741 * @wmi_handle: wmi handle 12742 * @evt_buf: pointer to event buffer 12743 * 12744 * Return: QDF_STATUS_SUCCESS for success or error code 12745 */ 12746 static QDF_STATUS 12747 save_fw_version_in_service_ready_tlv(wmi_unified_t wmi_handle, void *evt_buf) 12748 { 12749 WMI_SERVICE_READY_EVENTID_param_tlvs *param_buf; 12750 wmi_service_ready_event_fixed_param *ev; 12751 12752 12753 param_buf = (WMI_SERVICE_READY_EVENTID_param_tlvs *) evt_buf; 12754 12755 ev = (wmi_service_ready_event_fixed_param *) param_buf->fixed_param; 12756 if (!ev) { 12757 qdf_print("%s: wmi_buf_alloc failed", __func__); 12758 return QDF_STATUS_E_FAILURE; 12759 } 12760 12761 /*Save fw version from service ready message */ 12762 /*This will be used while sending INIT message */ 12763 qdf_mem_copy(&wmi_handle->fw_abi_version, &ev->fw_abi_vers, 12764 sizeof(wmi_handle->fw_abi_version)); 12765 12766 return QDF_STATUS_SUCCESS; 12767 } 12768 12769 /** 12770 * ready_extract_init_status_tlv() - Extract init status from ready event 12771 * @wmi_handle: wmi handle 12772 * @evt_buf: Pointer to event buffer 12773 * 12774 * Return: ready status 12775 */ 12776 static uint32_t ready_extract_init_status_tlv(wmi_unified_t wmi_handle, 12777 void *evt_buf) 12778 { 12779 WMI_READY_EVENTID_param_tlvs *param_buf = NULL; 12780 wmi_ready_event_fixed_param *ev = NULL; 12781 12782 param_buf = (WMI_READY_EVENTID_param_tlvs *) evt_buf; 12783 ev = param_buf->fixed_param; 12784 12785 qdf_print("%s:%d", __func__, ev->status); 12786 12787 return ev->status; 12788 } 12789 12790 /** 12791 * ready_extract_mac_addr_tlv() - extract mac address from ready event 12792 * @wmi_handle: wmi handle 12793 * @evt_buf: pointer to event buffer 12794 * @macaddr: Pointer to hold MAC address 12795 * 12796 * Return: QDF_STATUS_SUCCESS for success or error code 12797 */ 12798 static QDF_STATUS ready_extract_mac_addr_tlv(wmi_unified_t wmi_handle, 12799 void *evt_buf, uint8_t *macaddr) 12800 { 12801 WMI_READY_EVENTID_param_tlvs *param_buf = NULL; 12802 wmi_ready_event_fixed_param *ev = NULL; 12803 12804 12805 param_buf = (WMI_READY_EVENTID_param_tlvs *) evt_buf; 12806 ev = param_buf->fixed_param; 12807 12808 WMI_MAC_ADDR_TO_CHAR_ARRAY(&ev->mac_addr, macaddr); 12809 12810 return QDF_STATUS_SUCCESS; 12811 } 12812 12813 /** 12814 * ready_extract_mac_addr_list_tlv() - extract MAC address list from ready event 12815 * @wmi_handle: wmi handle 12816 * @evt_buf: pointer to event buffer 12817 * @num_mac: Pointer to hold number of MAC addresses 12818 * 12819 * Return: Pointer to addr list 12820 */ 12821 static wmi_host_mac_addr * 12822 ready_extract_mac_addr_list_tlv(wmi_unified_t wmi_handle, 12823 void *evt_buf, uint8_t *num_mac) 12824 { 12825 WMI_READY_EVENTID_param_tlvs *param_buf = NULL; 12826 wmi_ready_event_fixed_param *ev = NULL; 12827 12828 param_buf = (WMI_READY_EVENTID_param_tlvs *) evt_buf; 12829 ev = param_buf->fixed_param; 12830 12831 *num_mac = ev->num_extra_mac_addr; 12832 12833 return (wmi_host_mac_addr *) param_buf->mac_addr_list; 12834 } 12835 12836 /** 12837 * extract_ready_event_params_tlv() - Extract data from ready event apart from 12838 * status, macaddr and version. 12839 * @wmi_handle: Pointer to WMI handle. 12840 * @evt_buf: Pointer to Ready event buffer. 12841 * @ev_param: Pointer to host defined struct to copy the data from event. 12842 * 12843 * Return: QDF_STATUS_SUCCESS on success. 12844 */ 12845 static QDF_STATUS extract_ready_event_params_tlv(wmi_unified_t wmi_handle, 12846 void *evt_buf, struct wmi_host_ready_ev_param *ev_param) 12847 { 12848 WMI_READY_EVENTID_param_tlvs *param_buf = NULL; 12849 wmi_ready_event_fixed_param *ev = NULL; 12850 12851 param_buf = (WMI_READY_EVENTID_param_tlvs *) evt_buf; 12852 ev = param_buf->fixed_param; 12853 12854 ev_param->status = ev->status; 12855 ev_param->num_dscp_table = ev->num_dscp_table; 12856 ev_param->num_extra_mac_addr = ev->num_extra_mac_addr; 12857 ev_param->num_total_peer = ev->num_total_peers; 12858 ev_param->num_extra_peer = ev->num_extra_peers; 12859 /* Agile_capability in ready event is supported in TLV target, 12860 * as per aDFS FR 12861 */ 12862 ev_param->max_ast_index = ev->max_ast_index; 12863 ev_param->pktlog_defs_checksum = ev->pktlog_defs_checksum; 12864 ev_param->agile_capability = 1; 12865 ev_param->num_max_active_vdevs = ev->num_max_active_vdevs; 12866 12867 return QDF_STATUS_SUCCESS; 12868 } 12869 12870 /** 12871 * extract_dbglog_data_len_tlv() - extract debuglog data length 12872 * @wmi_handle: wmi handle 12873 * @evt_buf: pointer to event buffer 12874 * @len: length of the log 12875 * 12876 * Return: pointer to the debug log 12877 */ 12878 static uint8_t *extract_dbglog_data_len_tlv(wmi_unified_t wmi_handle, 12879 void *evt_buf, uint32_t *len) 12880 { 12881 WMI_DEBUG_MESG_EVENTID_param_tlvs *param_buf; 12882 12883 param_buf = (WMI_DEBUG_MESG_EVENTID_param_tlvs *) evt_buf; 12884 12885 *len = param_buf->num_bufp; 12886 12887 return param_buf->bufp; 12888 } 12889 12890 12891 #ifdef MGMT_FRAME_RX_DECRYPT_ERROR 12892 #define IS_WMI_RX_MGMT_FRAME_STATUS_INVALID(_status) false 12893 #else 12894 #define IS_WMI_RX_MGMT_FRAME_STATUS_INVALID(_status) \ 12895 ((_status) & WMI_RXERR_DECRYPT) 12896 #endif 12897 12898 /** 12899 * extract_mgmt_rx_params_tlv() - extract management rx params from event 12900 * @wmi_handle: wmi handle 12901 * @evt_buf: pointer to event buffer 12902 * @hdr: Pointer to hold header 12903 * @bufp: Pointer to hold pointer to rx param buffer 12904 * 12905 * Return: QDF_STATUS_SUCCESS for success or error code 12906 */ 12907 static QDF_STATUS extract_mgmt_rx_params_tlv(wmi_unified_t wmi_handle, 12908 void *evt_buf, struct mgmt_rx_event_params *hdr, 12909 uint8_t **bufp) 12910 { 12911 WMI_MGMT_RX_EVENTID_param_tlvs *param_tlvs = NULL; 12912 wmi_mgmt_rx_hdr *ev_hdr = NULL; 12913 int i; 12914 12915 param_tlvs = (WMI_MGMT_RX_EVENTID_param_tlvs *) evt_buf; 12916 if (!param_tlvs) { 12917 wmi_err("Get NULL point message from FW"); 12918 return QDF_STATUS_E_INVAL; 12919 } 12920 12921 ev_hdr = param_tlvs->hdr; 12922 if (!hdr) { 12923 wmi_err("Rx event is NULL"); 12924 return QDF_STATUS_E_INVAL; 12925 } 12926 12927 if (IS_WMI_RX_MGMT_FRAME_STATUS_INVALID(ev_hdr->status)) { 12928 wmi_err("RX mgmt frame decrypt error, discard it"); 12929 return QDF_STATUS_E_INVAL; 12930 } 12931 if ((ev_hdr->status) & WMI_RXERR_MIC) { 12932 wmi_err("RX mgmt frame MIC mismatch for beacon protected frame"); 12933 } 12934 12935 if (ev_hdr->buf_len > param_tlvs->num_bufp) { 12936 wmi_err("Rx mgmt frame length mismatch, discard it"); 12937 return QDF_STATUS_E_INVAL; 12938 } 12939 12940 hdr->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host( 12941 wmi_handle, 12942 ev_hdr->pdev_id); 12943 hdr->chan_freq = ev_hdr->chan_freq; 12944 hdr->channel = ev_hdr->channel; 12945 hdr->snr = ev_hdr->snr; 12946 hdr->rate = ev_hdr->rate; 12947 hdr->phy_mode = ev_hdr->phy_mode; 12948 hdr->buf_len = ev_hdr->buf_len; 12949 hdr->status = ev_hdr->status; 12950 hdr->flags = ev_hdr->flags; 12951 hdr->rssi = ev_hdr->rssi; 12952 hdr->tsf_delta = ev_hdr->tsf_delta; 12953 hdr->tsf_l32 = ev_hdr->rx_tsf_l32; 12954 for (i = 0; i < ATH_MAX_ANTENNA; i++) 12955 hdr->rssi_ctl[i] = ev_hdr->rssi_ctl[i]; 12956 12957 *bufp = param_tlvs->bufp; 12958 12959 extract_mgmt_rx_mlo_link_removal_tlv_count( 12960 param_tlvs->num_link_removal_tbtt_count, hdr); 12961 12962 return QDF_STATUS_SUCCESS; 12963 } 12964 12965 static QDF_STATUS extract_mgmt_rx_ext_params_tlv(wmi_unified_t wmi_handle, 12966 void *evt_buf, struct mgmt_rx_event_ext_params *ext_params) 12967 { 12968 WMI_MGMT_RX_EVENTID_param_tlvs *param_tlvs; 12969 wmi_mgmt_rx_params_ext *ext_params_tlv; 12970 wmi_mgmt_rx_hdr *ev_hdr; 12971 12972 param_tlvs = (WMI_MGMT_RX_EVENTID_param_tlvs *) evt_buf; 12973 if (!param_tlvs) { 12974 wmi_err("param_tlvs is NULL"); 12975 return QDF_STATUS_E_INVAL; 12976 } 12977 12978 ev_hdr = param_tlvs->hdr; 12979 if (!ev_hdr) { 12980 wmi_err("Rx event is NULL"); 12981 return QDF_STATUS_E_INVAL; 12982 } 12983 12984 ext_params_tlv = param_tlvs->mgmt_rx_params_ext; 12985 if (ext_params_tlv) { 12986 ext_params->ba_win_size = WMI_RX_PARAM_EXT_BA_WIN_SIZE_GET( 12987 ext_params_tlv->mgmt_rx_params_ext_dword1); 12988 if (ext_params->ba_win_size > 1024) { 12989 wmi_err("ba win size from TLV is Invalid"); 12990 return QDF_STATUS_E_INVAL; 12991 } 12992 12993 ext_params->reo_win_size = WMI_RX_PARAM_EXT_REO_WIN_SIZE_GET( 12994 ext_params_tlv->mgmt_rx_params_ext_dword1); 12995 if (ext_params->reo_win_size > 2048) { 12996 wmi_err("reo win size from TLV is Invalid"); 12997 return QDF_STATUS_E_INVAL; 12998 } 12999 } else { 13000 ext_params->ba_win_size = 0; 13001 ext_params->reo_win_size = 0; 13002 } 13003 13004 return QDF_STATUS_SUCCESS; 13005 } 13006 13007 #ifdef WLAN_MGMT_RX_REO_SUPPORT 13008 /** 13009 * extract_mgmt_rx_fw_consumed_tlv() - extract MGMT Rx FW consumed event 13010 * @wmi_handle: wmi handle 13011 * @evt_buf: pointer to event buffer 13012 * @params: Pointer to MGMT Rx REO parameters 13013 * 13014 * Return: QDF_STATUS_SUCCESS for success or error code 13015 */ 13016 static QDF_STATUS 13017 extract_mgmt_rx_fw_consumed_tlv(wmi_unified_t wmi_handle, 13018 void *evt_buf, 13019 struct mgmt_rx_reo_params *params) 13020 { 13021 WMI_MGMT_RX_FW_CONSUMED_EVENTID_param_tlvs *param_tlvs; 13022 wmi_mgmt_rx_fw_consumed_hdr *ev_hdr; 13023 13024 param_tlvs = evt_buf; 13025 if (!param_tlvs) { 13026 wmi_err("param_tlvs is NULL"); 13027 return QDF_STATUS_E_INVAL; 13028 } 13029 13030 ev_hdr = param_tlvs->hdr; 13031 if (!params) { 13032 wmi_err("Rx REO parameters is NULL"); 13033 return QDF_STATUS_E_INVAL; 13034 } 13035 13036 params->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host( 13037 wmi_handle, 13038 ev_hdr->pdev_id); 13039 params->valid = WMI_MGMT_RX_FW_CONSUMED_PARAM_MGMT_PKT_CTR_VALID_GET( 13040 ev_hdr->mgmt_pkt_ctr_info); 13041 params->global_timestamp = ev_hdr->global_timestamp; 13042 params->mgmt_pkt_ctr = WMI_MGMT_RX_FW_CONSUMED_PARAM_MGMT_PKT_CTR_GET( 13043 ev_hdr->mgmt_pkt_ctr_info); 13044 params->duration_us = ev_hdr->rx_ppdu_duration_us; 13045 params->start_timestamp = params->global_timestamp; 13046 params->end_timestamp = params->start_timestamp + 13047 params->duration_us; 13048 13049 return QDF_STATUS_SUCCESS; 13050 } 13051 13052 /** 13053 * extract_mgmt_rx_reo_params_tlv() - extract MGMT Rx REO params from 13054 * MGMT_RX_EVENT_ID 13055 * @wmi_handle: wmi handle 13056 * @evt_buf: pointer to event buffer 13057 * @reo_params: Pointer to MGMT Rx REO parameters 13058 * 13059 * Return: QDF_STATUS_SUCCESS for success or error code 13060 */ 13061 static QDF_STATUS extract_mgmt_rx_reo_params_tlv(wmi_unified_t wmi_handle, 13062 void *evt_buf, struct mgmt_rx_reo_params *reo_params) 13063 { 13064 WMI_MGMT_RX_EVENTID_param_tlvs *param_tlvs; 13065 wmi_mgmt_rx_reo_params *reo_params_tlv; 13066 wmi_mgmt_rx_hdr *ev_hdr; 13067 13068 param_tlvs = evt_buf; 13069 if (!param_tlvs) { 13070 wmi_err("param_tlvs is NULL"); 13071 return QDF_STATUS_E_INVAL; 13072 } 13073 13074 ev_hdr = param_tlvs->hdr; 13075 if (!ev_hdr) { 13076 wmi_err("Rx event is NULL"); 13077 return QDF_STATUS_E_INVAL; 13078 } 13079 13080 reo_params_tlv = param_tlvs->reo_params; 13081 if (!reo_params_tlv) { 13082 wmi_err("mgmt_rx_reo_params TLV is not sent by FW"); 13083 return QDF_STATUS_E_INVAL; 13084 } 13085 13086 if (!reo_params) { 13087 wmi_err("MGMT Rx REO params is NULL"); 13088 return QDF_STATUS_E_INVAL; 13089 } 13090 13091 reo_params->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host( 13092 wmi_handle, 13093 ev_hdr->pdev_id); 13094 reo_params->valid = WMI_MGMT_RX_REO_PARAM_MGMT_PKT_CTR_VALID_GET( 13095 reo_params_tlv->mgmt_pkt_ctr_link_info); 13096 reo_params->global_timestamp = reo_params_tlv->global_timestamp; 13097 reo_params->mgmt_pkt_ctr = WMI_MGMT_RX_REO_PARAM_MGMT_PKT_CTR_GET( 13098 reo_params_tlv->mgmt_pkt_ctr_link_info); 13099 reo_params->duration_us = reo_params_tlv->rx_ppdu_duration_us; 13100 reo_params->start_timestamp = reo_params->global_timestamp; 13101 reo_params->end_timestamp = reo_params->start_timestamp + 13102 reo_params->duration_us; 13103 13104 return QDF_STATUS_SUCCESS; 13105 } 13106 13107 /** 13108 * send_mgmt_rx_reo_filter_config_cmd_tlv() - Send MGMT Rx REO filter 13109 * configuration command 13110 * @wmi_handle: wmi handle 13111 * @pdev_id: pdev ID of the radio 13112 * @filter: Pointer to MGMT Rx REO filter 13113 * 13114 * Return: QDF_STATUS_SUCCESS for success or error code 13115 */ 13116 static QDF_STATUS send_mgmt_rx_reo_filter_config_cmd_tlv( 13117 wmi_unified_t wmi_handle, 13118 uint8_t pdev_id, 13119 struct mgmt_rx_reo_filter *filter) 13120 { 13121 QDF_STATUS ret; 13122 wmi_buf_t buf; 13123 wmi_mgmt_rx_reo_filter_configuration_cmd_fixed_param *cmd; 13124 size_t len = sizeof(*cmd); 13125 13126 if (!filter) { 13127 wmi_err("mgmt_rx_reo_filter is NULL"); 13128 return QDF_STATUS_E_INVAL; 13129 } 13130 13131 buf = wmi_buf_alloc(wmi_handle, len); 13132 if (!buf) { 13133 wmi_err("wmi_buf_alloc failed"); 13134 return QDF_STATUS_E_NOMEM; 13135 } 13136 13137 cmd = (wmi_mgmt_rx_reo_filter_configuration_cmd_fixed_param *) 13138 wmi_buf_data(buf); 13139 13140 WMITLV_SET_HDR(&cmd->tlv_header, 13141 WMITLV_TAG_STRUC_wmi_mgmt_rx_reo_filter_configuration_cmd_fixed_param, 13142 WMITLV_GET_STRUCT_TLVLEN(wmi_mgmt_rx_reo_filter_configuration_cmd_fixed_param)); 13143 13144 cmd->pdev_id = wmi_handle->ops->convert_host_pdev_id_to_target( 13145 wmi_handle, 13146 pdev_id); 13147 cmd->filter_low = filter->low; 13148 cmd->filter_high = filter->high; 13149 13150 wmi_mtrace(WMI_MGMT_RX_REO_FILTER_CONFIGURATION_CMDID, NO_SESSION, 0); 13151 ret = wmi_unified_cmd_send( 13152 wmi_handle, buf, len, 13153 WMI_MGMT_RX_REO_FILTER_CONFIGURATION_CMDID); 13154 13155 if (QDF_IS_STATUS_ERROR(ret)) { 13156 wmi_err("Failed to send WMI command"); 13157 wmi_buf_free(buf); 13158 } 13159 13160 return ret; 13161 } 13162 #endif 13163 13164 /** 13165 * extract_frame_pn_params_tlv() - extract PN params from event 13166 * @wmi_handle: wmi handle 13167 * @evt_buf: pointer to event buffer 13168 * @pn_params: Pointer to Frame PN params 13169 * 13170 * Return: QDF_STATUS_SUCCESS for success or error code 13171 */ 13172 static QDF_STATUS extract_frame_pn_params_tlv(wmi_unified_t wmi_handle, 13173 void *evt_buf, 13174 struct frame_pn_params *pn_params) 13175 { 13176 WMI_MGMT_RX_EVENTID_param_tlvs *param_tlvs; 13177 wmi_frame_pn_params *pn_params_tlv; 13178 13179 if (!is_service_enabled_tlv(wmi_handle, 13180 WMI_SERVICE_PN_REPLAY_CHECK_SUPPORT)) 13181 return QDF_STATUS_SUCCESS; 13182 13183 param_tlvs = evt_buf; 13184 if (!param_tlvs) { 13185 wmi_err("Got NULL point message from FW"); 13186 return QDF_STATUS_E_INVAL; 13187 } 13188 13189 if (!pn_params) { 13190 wmi_err("PN Params is NULL"); 13191 return QDF_STATUS_E_INVAL; 13192 } 13193 13194 /* PN Params TLV will be populated only if WMI_RXERR_PN error is 13195 * found by target 13196 */ 13197 pn_params_tlv = param_tlvs->pn_params; 13198 if (!pn_params_tlv) 13199 return QDF_STATUS_SUCCESS; 13200 13201 qdf_mem_copy(pn_params->curr_pn, pn_params_tlv->cur_pn, 13202 sizeof(pn_params->curr_pn)); 13203 qdf_mem_copy(pn_params->prev_pn, pn_params_tlv->prev_pn, 13204 sizeof(pn_params->prev_pn)); 13205 13206 return QDF_STATUS_SUCCESS; 13207 } 13208 13209 /** 13210 * extract_is_conn_ap_frm_param_tlv() - extract is_conn_ap_frame param from 13211 * event 13212 * @wmi_handle: wmi handle 13213 * @evt_buf: pointer to event buffer 13214 * @is_conn_ap: Pointer for is_conn_ap frame 13215 * 13216 * Return: QDF_STATUS_SUCCESS for success or error code 13217 */ 13218 static QDF_STATUS extract_is_conn_ap_frm_param_tlv( 13219 wmi_unified_t wmi_handle, 13220 void *evt_buf, 13221 struct frm_conn_ap *is_conn_ap) 13222 { 13223 WMI_MGMT_RX_EVENTID_param_tlvs *param_tlvs; 13224 wmi_is_my_mgmt_frame *my_frame_tlv; 13225 13226 param_tlvs = evt_buf; 13227 if (!param_tlvs) { 13228 wmi_err("Got NULL point message from FW"); 13229 return QDF_STATUS_E_INVAL; 13230 } 13231 13232 if (!is_conn_ap) { 13233 wmi_err(" is connected ap param is NULL"); 13234 return QDF_STATUS_E_INVAL; 13235 } 13236 13237 my_frame_tlv = param_tlvs->my_frame; 13238 if (!my_frame_tlv) 13239 return QDF_STATUS_SUCCESS; 13240 13241 is_conn_ap->mgmt_frm_sub_type = my_frame_tlv->mgmt_frm_sub_type; 13242 is_conn_ap->is_conn_ap_frm = my_frame_tlv->is_my_frame; 13243 13244 return QDF_STATUS_SUCCESS; 13245 } 13246 13247 /** 13248 * extract_vdev_roam_param_tlv() - extract vdev roam param from event 13249 * @wmi_handle: wmi handle 13250 * @evt_buf: pointer to event buffer 13251 * @param: Pointer to hold roam param 13252 * 13253 * Return: QDF_STATUS_SUCCESS for success or error code 13254 */ 13255 static QDF_STATUS extract_vdev_roam_param_tlv(wmi_unified_t wmi_handle, 13256 void *evt_buf, wmi_host_roam_event *param) 13257 { 13258 WMI_ROAM_EVENTID_param_tlvs *param_buf; 13259 wmi_roam_event_fixed_param *evt; 13260 13261 param_buf = (WMI_ROAM_EVENTID_param_tlvs *) evt_buf; 13262 if (!param_buf) { 13263 wmi_err("Invalid roam event buffer"); 13264 return QDF_STATUS_E_INVAL; 13265 } 13266 13267 evt = param_buf->fixed_param; 13268 qdf_mem_zero(param, sizeof(*param)); 13269 13270 param->vdev_id = evt->vdev_id; 13271 param->reason = evt->reason; 13272 param->rssi = evt->rssi; 13273 13274 return QDF_STATUS_SUCCESS; 13275 } 13276 13277 /** 13278 * extract_vdev_scan_ev_param_tlv() - extract vdev scan param from event 13279 * @wmi_handle: wmi handle 13280 * @evt_buf: pointer to event buffer 13281 * @param: Pointer to hold vdev scan param 13282 * 13283 * Return: QDF_STATUS_SUCCESS for success or error code 13284 */ 13285 static QDF_STATUS extract_vdev_scan_ev_param_tlv(wmi_unified_t wmi_handle, 13286 void *evt_buf, struct scan_event *param) 13287 { 13288 WMI_SCAN_EVENTID_param_tlvs *param_buf = NULL; 13289 wmi_scan_event_fixed_param *evt = NULL; 13290 13291 param_buf = (WMI_SCAN_EVENTID_param_tlvs *) evt_buf; 13292 evt = param_buf->fixed_param; 13293 13294 qdf_mem_zero(param, sizeof(*param)); 13295 13296 switch (evt->event) { 13297 case WMI_SCAN_EVENT_STARTED: 13298 param->type = SCAN_EVENT_TYPE_STARTED; 13299 break; 13300 case WMI_SCAN_EVENT_COMPLETED: 13301 param->type = SCAN_EVENT_TYPE_COMPLETED; 13302 break; 13303 case WMI_SCAN_EVENT_BSS_CHANNEL: 13304 param->type = SCAN_EVENT_TYPE_BSS_CHANNEL; 13305 break; 13306 case WMI_SCAN_EVENT_FOREIGN_CHANNEL: 13307 param->type = SCAN_EVENT_TYPE_FOREIGN_CHANNEL; 13308 break; 13309 case WMI_SCAN_EVENT_DEQUEUED: 13310 param->type = SCAN_EVENT_TYPE_DEQUEUED; 13311 break; 13312 case WMI_SCAN_EVENT_PREEMPTED: 13313 param->type = SCAN_EVENT_TYPE_PREEMPTED; 13314 break; 13315 case WMI_SCAN_EVENT_START_FAILED: 13316 param->type = SCAN_EVENT_TYPE_START_FAILED; 13317 break; 13318 case WMI_SCAN_EVENT_RESTARTED: 13319 param->type = SCAN_EVENT_TYPE_RESTARTED; 13320 break; 13321 case WMI_SCAN_EVENT_FOREIGN_CHANNEL_EXIT: 13322 param->type = SCAN_EVENT_TYPE_FOREIGN_CHANNEL_EXIT; 13323 break; 13324 case WMI_SCAN_EVENT_MAX: 13325 default: 13326 param->type = SCAN_EVENT_TYPE_MAX; 13327 break; 13328 }; 13329 13330 switch (evt->reason) { 13331 case WMI_SCAN_REASON_NONE: 13332 param->reason = SCAN_REASON_NONE; 13333 break; 13334 case WMI_SCAN_REASON_COMPLETED: 13335 param->reason = SCAN_REASON_COMPLETED; 13336 break; 13337 case WMI_SCAN_REASON_CANCELLED: 13338 param->reason = SCAN_REASON_CANCELLED; 13339 break; 13340 case WMI_SCAN_REASON_PREEMPTED: 13341 param->reason = SCAN_REASON_PREEMPTED; 13342 break; 13343 case WMI_SCAN_REASON_TIMEDOUT: 13344 param->reason = SCAN_REASON_TIMEDOUT; 13345 break; 13346 case WMI_SCAN_REASON_INTERNAL_FAILURE: 13347 param->reason = SCAN_REASON_INTERNAL_FAILURE; 13348 break; 13349 case WMI_SCAN_REASON_SUSPENDED: 13350 param->reason = SCAN_REASON_SUSPENDED; 13351 break; 13352 case WMI_SCAN_REASON_DFS_VIOLATION: 13353 param->reason = SCAN_REASON_DFS_VIOLATION; 13354 break; 13355 case WMI_SCAN_REASON_MAX: 13356 param->reason = SCAN_REASON_MAX; 13357 break; 13358 default: 13359 param->reason = SCAN_REASON_MAX; 13360 break; 13361 }; 13362 13363 param->chan_freq = evt->channel_freq; 13364 param->requester = evt->requestor; 13365 param->scan_id = evt->scan_id; 13366 param->vdev_id = evt->vdev_id; 13367 param->timestamp = evt->tsf_timestamp; 13368 13369 return QDF_STATUS_SUCCESS; 13370 } 13371 13372 #ifdef FEATURE_WLAN_SCAN_PNO 13373 /** 13374 * extract_nlo_match_ev_param_tlv() - extract NLO match param from event 13375 * @wmi_handle: pointer to WMI handle 13376 * @evt_buf: pointer to WMI event buffer 13377 * @param: pointer to scan event param for NLO match 13378 * 13379 * Return: QDF_STATUS_SUCCESS for success or error code 13380 */ 13381 static QDF_STATUS extract_nlo_match_ev_param_tlv(wmi_unified_t wmi_handle, 13382 void *evt_buf, 13383 struct scan_event *param) 13384 { 13385 WMI_NLO_MATCH_EVENTID_param_tlvs *param_buf = evt_buf; 13386 wmi_nlo_event *evt = param_buf->fixed_param; 13387 13388 qdf_mem_zero(param, sizeof(*param)); 13389 13390 param->type = SCAN_EVENT_TYPE_NLO_MATCH; 13391 param->vdev_id = evt->vdev_id; 13392 13393 return QDF_STATUS_SUCCESS; 13394 } 13395 13396 /** 13397 * extract_nlo_complete_ev_param_tlv() - extract NLO complete param from event 13398 * @wmi_handle: pointer to WMI handle 13399 * @evt_buf: pointer to WMI event buffer 13400 * @param: pointer to scan event param for NLO complete 13401 * 13402 * Return: QDF_STATUS_SUCCESS for success or error code 13403 */ 13404 static QDF_STATUS extract_nlo_complete_ev_param_tlv(wmi_unified_t wmi_handle, 13405 void *evt_buf, 13406 struct scan_event *param) 13407 { 13408 WMI_NLO_SCAN_COMPLETE_EVENTID_param_tlvs *param_buf = evt_buf; 13409 wmi_nlo_event *evt = param_buf->fixed_param; 13410 13411 qdf_mem_zero(param, sizeof(*param)); 13412 13413 param->type = SCAN_EVENT_TYPE_NLO_COMPLETE; 13414 param->vdev_id = evt->vdev_id; 13415 13416 return QDF_STATUS_SUCCESS; 13417 } 13418 #endif 13419 13420 /** 13421 * extract_unit_test_tlv() - extract unit test data 13422 * @wmi_handle: wmi handle 13423 * @evt_buf: pointer to event buffer 13424 * @unit_test: pointer to hold unit test data 13425 * @maxspace: Amount of space in evt_buf 13426 * 13427 * Return: QDF_STATUS_SUCCESS for success or error code 13428 */ 13429 static QDF_STATUS extract_unit_test_tlv(wmi_unified_t wmi_handle, 13430 void *evt_buf, wmi_unit_test_event *unit_test, uint32_t maxspace) 13431 { 13432 WMI_UNIT_TEST_EVENTID_param_tlvs *param_buf; 13433 wmi_unit_test_event_fixed_param *ev_param; 13434 uint32_t num_bufp; 13435 uint32_t copy_size; 13436 uint8_t *bufp; 13437 13438 param_buf = (WMI_UNIT_TEST_EVENTID_param_tlvs *) evt_buf; 13439 ev_param = param_buf->fixed_param; 13440 bufp = param_buf->bufp; 13441 num_bufp = param_buf->num_bufp; 13442 unit_test->vdev_id = ev_param->vdev_id; 13443 unit_test->module_id = ev_param->module_id; 13444 unit_test->diag_token = ev_param->diag_token; 13445 unit_test->flag = ev_param->flag; 13446 unit_test->payload_len = ev_param->payload_len; 13447 wmi_debug("vdev_id:%d mod_id:%d diag_token:%d flag:%d", 13448 ev_param->vdev_id, 13449 ev_param->module_id, 13450 ev_param->diag_token, 13451 ev_param->flag); 13452 wmi_debug("Unit-test data given below %d", num_bufp); 13453 qdf_trace_hex_dump(QDF_MODULE_ID_WMI, QDF_TRACE_LEVEL_DEBUG, 13454 bufp, num_bufp); 13455 copy_size = (num_bufp < maxspace) ? num_bufp : maxspace; 13456 qdf_mem_copy(unit_test->buffer, bufp, copy_size); 13457 unit_test->buffer_len = copy_size; 13458 13459 return QDF_STATUS_SUCCESS; 13460 } 13461 13462 /** 13463 * extract_pdev_ext_stats_tlv() - extract extended pdev stats from event 13464 * @wmi_handle: wmi handle 13465 * @evt_buf: pointer to event buffer 13466 * @index: Index into extended pdev stats 13467 * @pdev_ext_stats: Pointer to hold extended pdev stats 13468 * 13469 * Return: QDF_STATUS_SUCCESS for success or error code 13470 */ 13471 static QDF_STATUS extract_pdev_ext_stats_tlv(wmi_unified_t wmi_handle, 13472 void *evt_buf, uint32_t index, wmi_host_pdev_ext_stats *pdev_ext_stats) 13473 { 13474 WMI_UPDATE_STATS_EVENTID_param_tlvs *param_buf; 13475 wmi_pdev_extd_stats *ev; 13476 13477 param_buf = evt_buf; 13478 if (!param_buf) 13479 return QDF_STATUS_E_FAILURE; 13480 13481 if (!param_buf->pdev_extd_stats) 13482 return QDF_STATUS_E_FAILURE; 13483 13484 ev = param_buf->pdev_extd_stats + index; 13485 13486 pdev_ext_stats->pdev_id = 13487 wmi_handle->ops->convert_target_pdev_id_to_host( 13488 wmi_handle, 13489 ev->pdev_id); 13490 pdev_ext_stats->my_rx_count = ev->my_rx_count; 13491 pdev_ext_stats->rx_matched_11ax_msdu_cnt = ev->rx_matched_11ax_msdu_cnt; 13492 pdev_ext_stats->rx_other_11ax_msdu_cnt = ev->rx_other_11ax_msdu_cnt; 13493 13494 return QDF_STATUS_SUCCESS; 13495 } 13496 13497 /** 13498 * extract_bcn_stats_tlv() - extract bcn stats from event 13499 * @wmi_handle: wmi handle 13500 * @evt_buf: pointer to event buffer 13501 * @index: Index into vdev stats 13502 * @bcn_stats: Pointer to hold bcn stats 13503 * 13504 * Return: QDF_STATUS_SUCCESS for success or error code 13505 */ 13506 static QDF_STATUS extract_bcn_stats_tlv(wmi_unified_t wmi_handle, 13507 void *evt_buf, uint32_t index, wmi_host_bcn_stats *bcn_stats) 13508 { 13509 WMI_UPDATE_STATS_EVENTID_param_tlvs *param_buf; 13510 wmi_stats_event_fixed_param *ev_param; 13511 uint8_t *data; 13512 13513 param_buf = (WMI_UPDATE_STATS_EVENTID_param_tlvs *) evt_buf; 13514 ev_param = (wmi_stats_event_fixed_param *) param_buf->fixed_param; 13515 data = (uint8_t *) param_buf->data; 13516 13517 if (index < ev_param->num_bcn_stats) { 13518 wmi_bcn_stats *ev = (wmi_bcn_stats *) ((data) + 13519 ((ev_param->num_pdev_stats) * sizeof(wmi_pdev_stats)) + 13520 ((ev_param->num_vdev_stats) * sizeof(wmi_vdev_stats)) + 13521 ((ev_param->num_peer_stats) * sizeof(wmi_peer_stats)) + 13522 ((ev_param->num_chan_stats) * sizeof(wmi_chan_stats)) + 13523 ((ev_param->num_mib_stats) * sizeof(wmi_mib_stats)) + 13524 (index * sizeof(wmi_bcn_stats))); 13525 13526 bcn_stats->vdev_id = ev->vdev_id; 13527 bcn_stats->tx_bcn_succ_cnt = ev->tx_bcn_succ_cnt; 13528 bcn_stats->tx_bcn_outage_cnt = ev->tx_bcn_outage_cnt; 13529 } 13530 13531 return QDF_STATUS_SUCCESS; 13532 } 13533 13534 /** 13535 * extract_vdev_prb_fils_stats_tlv() - extract vdev probe and fils 13536 * stats from event 13537 * @wmi_handle: wmi handle 13538 * @evt_buf: pointer to event buffer 13539 * @index: Index into vdev stats 13540 * @vdev_stats: Pointer to hold vdev probe and fils stats 13541 * 13542 * Return: QDF_STATUS_SUCCESS for success or error code 13543 */ 13544 static QDF_STATUS 13545 extract_vdev_prb_fils_stats_tlv(wmi_unified_t wmi_handle, 13546 void *evt_buf, uint32_t index, 13547 struct wmi_host_vdev_prb_fils_stats *vdev_stats) 13548 { 13549 WMI_UPDATE_STATS_EVENTID_param_tlvs *param_buf; 13550 wmi_vdev_extd_stats *ev; 13551 13552 param_buf = (WMI_UPDATE_STATS_EVENTID_param_tlvs *)evt_buf; 13553 13554 if (param_buf->vdev_extd_stats) { 13555 ev = (wmi_vdev_extd_stats *)(param_buf->vdev_extd_stats + 13556 index); 13557 vdev_stats->vdev_id = ev->vdev_id; 13558 vdev_stats->fd_succ_cnt = ev->fd_succ_cnt; 13559 vdev_stats->fd_fail_cnt = ev->fd_fail_cnt; 13560 vdev_stats->unsolicited_prb_succ_cnt = 13561 ev->unsolicited_prb_succ_cnt; 13562 vdev_stats->unsolicited_prb_fail_cnt = 13563 ev->unsolicited_prb_fail_cnt; 13564 wmi_debug("vdev: %d, fd_s: %d, fd_f: %d, prb_s: %d, prb_f: %d", 13565 ev->vdev_id, ev->fd_succ_cnt, ev->fd_fail_cnt, 13566 ev->unsolicited_prb_succ_cnt, 13567 ev->unsolicited_prb_fail_cnt); 13568 } 13569 13570 return QDF_STATUS_SUCCESS; 13571 } 13572 13573 /** 13574 * extract_bcnflt_stats_tlv() - extract bcn fault stats from event 13575 * @wmi_handle: wmi handle 13576 * @evt_buf: pointer to event buffer 13577 * @index: Index into bcn fault stats 13578 * @bcnflt_stats: Pointer to hold bcn fault stats 13579 * 13580 * Return: QDF_STATUS_SUCCESS for success or error code 13581 */ 13582 static QDF_STATUS extract_bcnflt_stats_tlv(wmi_unified_t wmi_handle, 13583 void *evt_buf, uint32_t index, wmi_host_bcnflt_stats *bcnflt_stats) 13584 { 13585 return QDF_STATUS_SUCCESS; 13586 } 13587 13588 /** 13589 * extract_chan_stats_tlv() - extract chan stats from event 13590 * @wmi_handle: wmi handle 13591 * @evt_buf: pointer to event buffer 13592 * @index: Index into chan stats 13593 * @chan_stats: Pointer to hold chan stats 13594 * 13595 * Return: QDF_STATUS_SUCCESS for success or error code 13596 */ 13597 static QDF_STATUS extract_chan_stats_tlv(wmi_unified_t wmi_handle, 13598 void *evt_buf, uint32_t index, wmi_host_chan_stats *chan_stats) 13599 { 13600 WMI_UPDATE_STATS_EVENTID_param_tlvs *param_buf; 13601 wmi_stats_event_fixed_param *ev_param; 13602 uint8_t *data; 13603 13604 param_buf = (WMI_UPDATE_STATS_EVENTID_param_tlvs *) evt_buf; 13605 ev_param = (wmi_stats_event_fixed_param *) param_buf->fixed_param; 13606 data = (uint8_t *) param_buf->data; 13607 13608 if (index < ev_param->num_chan_stats) { 13609 wmi_chan_stats *ev = (wmi_chan_stats *) ((data) + 13610 ((ev_param->num_pdev_stats) * sizeof(wmi_pdev_stats)) + 13611 ((ev_param->num_vdev_stats) * sizeof(wmi_vdev_stats)) + 13612 ((ev_param->num_peer_stats) * sizeof(wmi_peer_stats)) + 13613 (index * sizeof(wmi_chan_stats))); 13614 13615 13616 /* Non-TLV doesn't have num_chan_stats */ 13617 chan_stats->chan_mhz = ev->chan_mhz; 13618 chan_stats->sampling_period_us = ev->sampling_period_us; 13619 chan_stats->rx_clear_count = ev->rx_clear_count; 13620 chan_stats->tx_duration_us = ev->tx_duration_us; 13621 chan_stats->rx_duration_us = ev->rx_duration_us; 13622 } 13623 13624 return QDF_STATUS_SUCCESS; 13625 } 13626 13627 /** 13628 * extract_profile_ctx_tlv() - extract profile context from event 13629 * @wmi_handle: wmi handle 13630 * @evt_buf: pointer to event buffer 13631 * @profile_ctx: Pointer to hold profile context 13632 * 13633 * Return: QDF_STATUS_SUCCESS for success or error code 13634 */ 13635 static QDF_STATUS extract_profile_ctx_tlv(wmi_unified_t wmi_handle, 13636 void *evt_buf, wmi_host_wlan_profile_ctx_t *profile_ctx) 13637 { 13638 WMI_WLAN_PROFILE_DATA_EVENTID_param_tlvs *param_buf; 13639 13640 wmi_wlan_profile_ctx_t *ev; 13641 13642 param_buf = (WMI_WLAN_PROFILE_DATA_EVENTID_param_tlvs *)evt_buf; 13643 if (!param_buf) { 13644 wmi_err("Invalid profile data event buf"); 13645 return QDF_STATUS_E_INVAL; 13646 } 13647 13648 ev = param_buf->profile_ctx; 13649 13650 profile_ctx->tot = ev->tot; 13651 profile_ctx->tx_msdu_cnt = ev->tx_msdu_cnt; 13652 profile_ctx->tx_mpdu_cnt = ev->tx_mpdu_cnt; 13653 profile_ctx->tx_ppdu_cnt = ev->tx_ppdu_cnt; 13654 profile_ctx->rx_msdu_cnt = ev->rx_msdu_cnt; 13655 profile_ctx->rx_mpdu_cnt = ev->rx_mpdu_cnt; 13656 profile_ctx->bin_count = ev->bin_count; 13657 13658 return QDF_STATUS_SUCCESS; 13659 } 13660 13661 /** 13662 * extract_profile_data_tlv() - extract profile data from event 13663 * @wmi_handle: wmi handle 13664 * @evt_buf: pointer to event buffer 13665 * @idx: profile stats index to extract 13666 * @profile_data: Pointer to hold profile data 13667 * 13668 * Return: QDF_STATUS_SUCCESS for success or error code 13669 */ 13670 static QDF_STATUS extract_profile_data_tlv(wmi_unified_t wmi_handle, 13671 void *evt_buf, uint8_t idx, wmi_host_wlan_profile_t *profile_data) 13672 { 13673 WMI_WLAN_PROFILE_DATA_EVENTID_param_tlvs *param_buf; 13674 wmi_wlan_profile_t *ev; 13675 13676 param_buf = (WMI_WLAN_PROFILE_DATA_EVENTID_param_tlvs *)evt_buf; 13677 if (!param_buf) { 13678 wmi_err("Invalid profile data event buf"); 13679 return QDF_STATUS_E_INVAL; 13680 } 13681 13682 ev = ¶m_buf->profile_data[idx]; 13683 profile_data->id = ev->id; 13684 profile_data->cnt = ev->cnt; 13685 profile_data->tot = ev->tot; 13686 profile_data->min = ev->min; 13687 profile_data->max = ev->max; 13688 profile_data->hist_intvl = ev->hist_intvl; 13689 qdf_mem_copy(profile_data->hist, ev->hist, sizeof(profile_data->hist)); 13690 13691 return QDF_STATUS_SUCCESS; 13692 } 13693 13694 /** 13695 * extract_pdev_utf_event_tlv() - extract UTF data info from event 13696 * @wmi_handle: WMI handle 13697 * @evt_buf: Pointer to event buffer 13698 * @event: Pointer to hold data 13699 * 13700 * Return: QDF_STATUS_SUCCESS for success or error code 13701 */ 13702 static QDF_STATUS extract_pdev_utf_event_tlv(wmi_unified_t wmi_handle, 13703 uint8_t *evt_buf, 13704 struct wmi_host_pdev_utf_event *event) 13705 { 13706 WMI_PDEV_UTF_EVENTID_param_tlvs *param_buf; 13707 struct wmi_host_utf_seg_header_info *seg_hdr; 13708 13709 param_buf = (WMI_PDEV_UTF_EVENTID_param_tlvs *)evt_buf; 13710 event->data = param_buf->data; 13711 event->datalen = param_buf->num_data; 13712 13713 if (event->datalen < sizeof(struct wmi_host_utf_seg_header_info)) { 13714 wmi_err("Invalid datalen: %d", event->datalen); 13715 return QDF_STATUS_E_INVAL; 13716 } 13717 seg_hdr = (struct wmi_host_utf_seg_header_info *)param_buf->data; 13718 /* Set pdev_id=1 until FW adds support to include pdev_id */ 13719 event->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host( 13720 wmi_handle, 13721 seg_hdr->pdev_id); 13722 13723 return QDF_STATUS_SUCCESS; 13724 } 13725 13726 #ifdef WLAN_SUPPORT_RF_CHARACTERIZATION 13727 static QDF_STATUS extract_num_rf_characterization_entries_tlv(wmi_unified_t wmi_handle, 13728 uint8_t *event, 13729 uint32_t *num_rf_characterization_entries) 13730 { 13731 WMI_CHAN_RF_CHARACTERIZATION_INFO_EVENTID_param_tlvs *param_buf; 13732 13733 param_buf = (WMI_CHAN_RF_CHARACTERIZATION_INFO_EVENTID_param_tlvs *)event; 13734 if (!param_buf) 13735 return QDF_STATUS_E_INVAL; 13736 13737 *num_rf_characterization_entries = 13738 param_buf->num_wmi_chan_rf_characterization_info; 13739 13740 return QDF_STATUS_SUCCESS; 13741 } 13742 13743 static QDF_STATUS extract_rf_characterization_entries_tlv(wmi_unified_t wmi_handle, 13744 uint8_t *event, 13745 uint32_t num_rf_characterization_entries, 13746 struct wmi_host_rf_characterization_event_param *rf_characterization_entries) 13747 { 13748 WMI_CHAN_RF_CHARACTERIZATION_INFO_EVENTID_param_tlvs *param_buf; 13749 WMI_CHAN_RF_CHARACTERIZATION_INFO *wmi_rf_characterization_entry; 13750 uint8_t ix; 13751 13752 param_buf = (WMI_CHAN_RF_CHARACTERIZATION_INFO_EVENTID_param_tlvs *)event; 13753 if (!param_buf) 13754 return QDF_STATUS_E_INVAL; 13755 13756 wmi_rf_characterization_entry = 13757 param_buf->wmi_chan_rf_characterization_info; 13758 if (!wmi_rf_characterization_entry) 13759 return QDF_STATUS_E_INVAL; 13760 13761 /* 13762 * Using num_wmi_chan_rf_characterization instead of param_buf value 13763 * since memory for rf_characterization_entries was allocated using 13764 * the former. 13765 */ 13766 for (ix = 0; ix < num_rf_characterization_entries; ix++) { 13767 rf_characterization_entries[ix].freq = 13768 WMI_CHAN_RF_CHARACTERIZATION_FREQ_GET( 13769 &wmi_rf_characterization_entry[ix]); 13770 13771 rf_characterization_entries[ix].bw = 13772 WMI_CHAN_RF_CHARACTERIZATION_BW_GET( 13773 &wmi_rf_characterization_entry[ix]); 13774 13775 rf_characterization_entries[ix].chan_metric = 13776 WMI_CHAN_RF_CHARACTERIZATION_CHAN_METRIC_GET( 13777 &wmi_rf_characterization_entry[ix]); 13778 13779 wmi_nofl_debug("rf_characterization_entries[%u]: freq: %u, " 13780 "bw: %u, chan_metric: %u", 13781 ix, rf_characterization_entries[ix].freq, 13782 rf_characterization_entries[ix].bw, 13783 rf_characterization_entries[ix].chan_metric); 13784 } 13785 13786 return QDF_STATUS_SUCCESS; 13787 } 13788 #endif 13789 13790 #ifdef WLAN_FEATURE_11BE 13791 static void 13792 extract_11be_chainmask(struct wlan_psoc_host_chainmask_capabilities *cap, 13793 WMI_MAC_PHY_CHAINMASK_CAPABILITY *chainmask_caps) 13794 { 13795 cap->supports_chan_width_320 = 13796 WMI_SUPPORT_CHAN_WIDTH_320_GET(chainmask_caps->supported_flags); 13797 cap->supports_aDFS_320 = 13798 WMI_SUPPORT_ADFS_320_GET(chainmask_caps->supported_flags); 13799 } 13800 #else 13801 static void 13802 extract_11be_chainmask(struct wlan_psoc_host_chainmask_capabilities *cap, 13803 WMI_MAC_PHY_CHAINMASK_CAPABILITY *chainmask_caps) 13804 { 13805 } 13806 #endif /* WLAN_FEATURE_11BE */ 13807 13808 /** 13809 * extract_chainmask_tables_tlv() - extract chain mask tables from event 13810 * @wmi_handle: wmi handle 13811 * @event: pointer to event buffer 13812 * @chainmask_table: Pointer to hold extracted chainmask tables 13813 * 13814 * Return: QDF_STATUS_SUCCESS for success or error code 13815 */ 13816 static QDF_STATUS extract_chainmask_tables_tlv(wmi_unified_t wmi_handle, 13817 uint8_t *event, struct wlan_psoc_host_chainmask_table *chainmask_table) 13818 { 13819 WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *param_buf; 13820 WMI_MAC_PHY_CHAINMASK_CAPABILITY *chainmask_caps; 13821 WMI_SOC_MAC_PHY_HW_MODE_CAPS *hw_caps; 13822 uint8_t i = 0, j = 0; 13823 uint32_t num_mac_phy_chainmask_caps = 0; 13824 13825 param_buf = (WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *) event; 13826 if (!param_buf) 13827 return QDF_STATUS_E_INVAL; 13828 13829 hw_caps = param_buf->soc_hw_mode_caps; 13830 if (!hw_caps) 13831 return QDF_STATUS_E_INVAL; 13832 13833 if ((!hw_caps->num_chainmask_tables) || 13834 (hw_caps->num_chainmask_tables > PSOC_MAX_CHAINMASK_TABLES) || 13835 (hw_caps->num_chainmask_tables > 13836 param_buf->num_mac_phy_chainmask_combo)) 13837 return QDF_STATUS_E_INVAL; 13838 13839 chainmask_caps = param_buf->mac_phy_chainmask_caps; 13840 13841 if (!chainmask_caps) 13842 return QDF_STATUS_E_INVAL; 13843 13844 for (i = 0; i < hw_caps->num_chainmask_tables; i++) { 13845 if (chainmask_table[i].num_valid_chainmasks > 13846 (UINT_MAX - num_mac_phy_chainmask_caps)) { 13847 wmi_err_rl("integer overflow, num_mac_phy_chainmask_caps:%d, i:%d, um_valid_chainmasks:%d", 13848 num_mac_phy_chainmask_caps, i, 13849 chainmask_table[i].num_valid_chainmasks); 13850 return QDF_STATUS_E_INVAL; 13851 } 13852 num_mac_phy_chainmask_caps += 13853 chainmask_table[i].num_valid_chainmasks; 13854 } 13855 13856 if (num_mac_phy_chainmask_caps > 13857 param_buf->num_mac_phy_chainmask_caps) { 13858 wmi_err_rl("invalid chainmask caps num, num_mac_phy_chainmask_caps:%d, param_buf->num_mac_phy_chainmask_caps:%d", 13859 num_mac_phy_chainmask_caps, 13860 param_buf->num_mac_phy_chainmask_caps); 13861 return QDF_STATUS_E_INVAL; 13862 } 13863 13864 for (i = 0; i < hw_caps->num_chainmask_tables; i++) { 13865 13866 wmi_nofl_debug("Dumping chain mask combo data for table : %d", 13867 i); 13868 for (j = 0; j < chainmask_table[i].num_valid_chainmasks; j++) { 13869 13870 chainmask_table[i].cap_list[j].chainmask = 13871 chainmask_caps->chainmask; 13872 13873 chainmask_table[i].cap_list[j].supports_chan_width_20 = 13874 WMI_SUPPORT_CHAN_WIDTH_20_GET(chainmask_caps->supported_flags); 13875 13876 chainmask_table[i].cap_list[j].supports_chan_width_40 = 13877 WMI_SUPPORT_CHAN_WIDTH_40_GET(chainmask_caps->supported_flags); 13878 13879 chainmask_table[i].cap_list[j].supports_chan_width_80 = 13880 WMI_SUPPORT_CHAN_WIDTH_80_GET(chainmask_caps->supported_flags); 13881 13882 chainmask_table[i].cap_list[j].supports_chan_width_160 = 13883 WMI_SUPPORT_CHAN_WIDTH_160_GET(chainmask_caps->supported_flags); 13884 13885 chainmask_table[i].cap_list[j].supports_chan_width_80P80 = 13886 WMI_SUPPORT_CHAN_WIDTH_80P80_GET(chainmask_caps->supported_flags); 13887 13888 chainmask_table[i].cap_list[j].chain_mask_2G = 13889 WMI_SUPPORT_CHAIN_MASK_2G_GET(chainmask_caps->supported_flags); 13890 13891 chainmask_table[i].cap_list[j].chain_mask_5G = 13892 WMI_SUPPORT_CHAIN_MASK_5G_GET(chainmask_caps->supported_flags); 13893 13894 chainmask_table[i].cap_list[j].chain_mask_tx = 13895 WMI_SUPPORT_CHAIN_MASK_TX_GET(chainmask_caps->supported_flags); 13896 13897 chainmask_table[i].cap_list[j].chain_mask_rx = 13898 WMI_SUPPORT_CHAIN_MASK_RX_GET(chainmask_caps->supported_flags); 13899 13900 chainmask_table[i].cap_list[j].supports_aDFS = 13901 WMI_SUPPORT_CHAIN_MASK_ADFS_GET(chainmask_caps->supported_flags); 13902 13903 chainmask_table[i].cap_list[j].supports_aSpectral = 13904 WMI_SUPPORT_AGILE_SPECTRAL_GET(chainmask_caps->supported_flags); 13905 13906 chainmask_table[i].cap_list[j].supports_aSpectral_160 = 13907 WMI_SUPPORT_AGILE_SPECTRAL_160_GET(chainmask_caps->supported_flags); 13908 13909 chainmask_table[i].cap_list[j].supports_aDFS_160 = 13910 WMI_SUPPORT_ADFS_160_GET(chainmask_caps->supported_flags); 13911 13912 extract_11be_chainmask(&chainmask_table[i].cap_list[j], 13913 chainmask_caps); 13914 13915 wmi_nofl_debug("supported_flags: 0x%08x chainmasks: 0x%08x", 13916 chainmask_caps->supported_flags, 13917 chainmask_caps->chainmask); 13918 chainmask_caps++; 13919 } 13920 } 13921 13922 return QDF_STATUS_SUCCESS; 13923 } 13924 13925 /** 13926 * extract_service_ready_ext_tlv() - extract basic extended service ready params 13927 * from event 13928 * @wmi_handle: wmi handle 13929 * @event: pointer to event buffer 13930 * @param: Pointer to hold evt buf 13931 * 13932 * Return: QDF_STATUS_SUCCESS for success or error code 13933 */ 13934 static QDF_STATUS extract_service_ready_ext_tlv(wmi_unified_t wmi_handle, 13935 uint8_t *event, struct wlan_psoc_host_service_ext_param *param) 13936 { 13937 WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *param_buf; 13938 wmi_service_ready_ext_event_fixed_param *ev; 13939 WMI_SOC_MAC_PHY_HW_MODE_CAPS *hw_caps; 13940 WMI_SOC_HAL_REG_CAPABILITIES *reg_caps; 13941 WMI_MAC_PHY_CHAINMASK_COMBO *chain_mask_combo; 13942 uint8_t i = 0; 13943 13944 param_buf = (WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *) event; 13945 if (!param_buf) 13946 return QDF_STATUS_E_INVAL; 13947 13948 ev = param_buf->fixed_param; 13949 if (!ev) 13950 return QDF_STATUS_E_INVAL; 13951 13952 /* Move this to host based bitmap */ 13953 param->default_conc_scan_config_bits = 13954 ev->default_conc_scan_config_bits; 13955 param->default_fw_config_bits = ev->default_fw_config_bits; 13956 param->he_cap_info = ev->he_cap_info; 13957 param->mpdu_density = ev->mpdu_density; 13958 param->max_bssid_rx_filters = ev->max_bssid_rx_filters; 13959 param->fw_build_vers_ext = ev->fw_build_vers_ext; 13960 param->num_dbr_ring_caps = param_buf->num_dma_ring_caps; 13961 param->num_bin_scaling_params = param_buf->num_wmi_bin_scaling_params; 13962 param->max_bssid_indicator = ev->max_bssid_indicator; 13963 qdf_mem_copy(¶m->ppet, &ev->ppet, sizeof(param->ppet)); 13964 13965 hw_caps = param_buf->soc_hw_mode_caps; 13966 if (hw_caps) 13967 param->num_hw_modes = hw_caps->num_hw_modes; 13968 else 13969 param->num_hw_modes = 0; 13970 13971 reg_caps = param_buf->soc_hal_reg_caps; 13972 if (reg_caps) 13973 param->num_phy = reg_caps->num_phy; 13974 else 13975 param->num_phy = 0; 13976 13977 if (hw_caps) { 13978 param->num_chainmask_tables = hw_caps->num_chainmask_tables; 13979 wmi_nofl_debug("Num chain mask tables: %d", 13980 hw_caps->num_chainmask_tables); 13981 } else 13982 param->num_chainmask_tables = 0; 13983 13984 if (param->num_chainmask_tables > PSOC_MAX_CHAINMASK_TABLES || 13985 param->num_chainmask_tables > 13986 param_buf->num_mac_phy_chainmask_combo) { 13987 wmi_err_rl("num_chainmask_tables is OOB: %u", 13988 param->num_chainmask_tables); 13989 return QDF_STATUS_E_INVAL; 13990 } 13991 chain_mask_combo = param_buf->mac_phy_chainmask_combo; 13992 13993 if (!chain_mask_combo) 13994 return QDF_STATUS_SUCCESS; 13995 13996 wmi_nofl_debug("Dumping chain mask combo data"); 13997 13998 for (i = 0; i < param->num_chainmask_tables; i++) { 13999 14000 wmi_nofl_debug("table_id : %d Num valid chainmasks: %d", 14001 chain_mask_combo->chainmask_table_id, 14002 chain_mask_combo->num_valid_chainmask); 14003 14004 param->chainmask_table[i].table_id = 14005 chain_mask_combo->chainmask_table_id; 14006 param->chainmask_table[i].num_valid_chainmasks = 14007 chain_mask_combo->num_valid_chainmask; 14008 chain_mask_combo++; 14009 } 14010 wmi_nofl_debug("chain mask combo end"); 14011 14012 return QDF_STATUS_SUCCESS; 14013 } 14014 14015 #if defined(CONFIG_AFC_SUPPORT) 14016 /** 14017 * extract_svc_rdy_ext2_afc_tlv() - extract service ready ext2 afc deployment 14018 * type from event 14019 * @ev: pointer to event fixed param 14020 * @param: Pointer to hold the params 14021 * 14022 * Return: void 14023 */ 14024 static void 14025 extract_svc_rdy_ext2_afc_tlv(wmi_service_ready_ext2_event_fixed_param *ev, 14026 struct wlan_psoc_host_service_ext2_param *param) 14027 { 14028 WMI_AFC_FEATURE_6G_DEPLOYMENT_TYPE tgt_afc_dev_type; 14029 enum reg_afc_dev_deploy_type reg_afc_dev_type; 14030 14031 tgt_afc_dev_type = ev->afc_deployment_type; 14032 switch (tgt_afc_dev_type) { 14033 case WMI_AFC_FEATURE_6G_DEPLOYMENT_UNSPECIFIED: 14034 reg_afc_dev_type = AFC_DEPLOYMENT_INDOOR; 14035 break; 14036 case WMI_AFC_FEATURE_6G_DEPLOYMENT_INDOOR_ONLY: 14037 reg_afc_dev_type = AFC_DEPLOYMENT_INDOOR; 14038 break; 14039 case WMI_AFC_FEATURE_6G_DEPLOYMENT_OUTDOOR_ONLY: 14040 reg_afc_dev_type = AFC_DEPLOYMENT_OUTDOOR; 14041 break; 14042 default: 14043 wmi_err("invalid afc deployment %d", tgt_afc_dev_type); 14044 reg_afc_dev_type = AFC_DEPLOYMENT_UNKNOWN; 14045 break; 14046 } 14047 param->afc_dev_type = reg_afc_dev_type; 14048 14049 wmi_debug("afc dev type:%d", ev->afc_deployment_type); 14050 } 14051 #else 14052 static inline void 14053 extract_svc_rdy_ext2_afc_tlv(wmi_service_ready_ext2_event_fixed_param *ev, 14054 struct wlan_psoc_host_service_ext2_param *param) 14055 { 14056 } 14057 #endif 14058 14059 /** 14060 * extract_ul_mumimo_support() - extract UL-MUMIMO capability from target cap 14061 * @param: Pointer to hold the params 14062 * 14063 * Return: Void 14064 */ 14065 static void 14066 extract_ul_mumimo_support(struct wlan_psoc_host_service_ext2_param *param) 14067 { 14068 uint32_t tgt_cap = param->target_cap_flags; 14069 14070 param->ul_mumimo_rx_2g = WMI_TARGET_CAP_UL_MU_MIMO_RX_SUPPORT_2GHZ_GET(tgt_cap); 14071 param->ul_mumimo_rx_5g = WMI_TARGET_CAP_UL_MU_MIMO_RX_SUPPORT_5GHZ_GET(tgt_cap); 14072 param->ul_mumimo_rx_6g = WMI_TARGET_CAP_UL_MU_MIMO_RX_SUPPORT_6GHZ_GET(tgt_cap); 14073 param->ul_mumimo_tx_2g = WMI_TARGET_CAP_UL_MU_MIMO_TX_SUPPORT_2GHZ_GET(tgt_cap); 14074 param->ul_mumimo_tx_5g = WMI_TARGET_CAP_UL_MU_MIMO_TX_SUPPORT_5GHZ_GET(tgt_cap); 14075 param->ul_mumimo_tx_6g = WMI_TARGET_CAP_UL_MU_MIMO_TX_SUPPORT_6GHZ_GET(tgt_cap); 14076 } 14077 14078 /** 14079 * extract_hw_bdf_status() - extract service ready ext2 BDF hw status 14080 * type from event 14081 * @ev: pointer to event fixed param 14082 * 14083 * Return: void 14084 */ 14085 14086 static void 14087 extract_hw_bdf_status(wmi_service_ready_ext2_event_fixed_param *ev) 14088 { 14089 uint8_t hw_bdf_s; 14090 14091 hw_bdf_s = ev->hw_bd_status; 14092 switch (hw_bdf_s) { 14093 case WMI_BDF_VERSION_CHECK_DISABLED: 14094 wmi_info("BDF VER is %d, FW and BDF ver check skipped", 14095 hw_bdf_s); 14096 break; 14097 case WMI_BDF_VERSION_CHECK_GOOD: 14098 wmi_info("BDF VER is %d, FW and BDF ver check good", 14099 hw_bdf_s); 14100 break; 14101 case WMI_BDF_VERSION_TEMPLATE_TOO_OLD: 14102 wmi_info("BDF VER is %d, BDF ver is older than the oldest version supported by FW", 14103 hw_bdf_s); 14104 break; 14105 case WMI_BDF_VERSION_TEMPLATE_TOO_NEW: 14106 wmi_info("BDF VER is %d, BDF ver is newer than the newest version supported by FW", 14107 hw_bdf_s); 14108 break; 14109 case WMI_BDF_VERSION_FW_TOO_OLD: 14110 wmi_info("BDF VER is %d, FW ver is older than the major version supported by BDF", 14111 hw_bdf_s); 14112 break; 14113 case WMI_BDF_VERSION_FW_TOO_NEW: 14114 wmi_info("BDF VER is %d, FW ver is newer than the minor version supported by BDF", 14115 hw_bdf_s); 14116 break; 14117 default: 14118 wmi_info("unknown BDF VER %d", hw_bdf_s); 14119 break; 14120 } 14121 } 14122 14123 /** 14124 * extract_service_ready_ext2_tlv() - extract service ready ext2 params from 14125 * event 14126 * @wmi_handle: wmi handle 14127 * @event: pointer to event buffer 14128 * @param: Pointer to hold the params 14129 * 14130 * Return: QDF_STATUS_SUCCESS for success or error code 14131 */ 14132 static QDF_STATUS 14133 extract_service_ready_ext2_tlv(wmi_unified_t wmi_handle, uint8_t *event, 14134 struct wlan_psoc_host_service_ext2_param *param) 14135 { 14136 WMI_SERVICE_READY_EXT2_EVENTID_param_tlvs *param_buf; 14137 wmi_service_ready_ext2_event_fixed_param *ev; 14138 14139 param_buf = (WMI_SERVICE_READY_EXT2_EVENTID_param_tlvs *)event; 14140 if (!param_buf) 14141 return QDF_STATUS_E_INVAL; 14142 14143 ev = param_buf->fixed_param; 14144 if (!ev) 14145 return QDF_STATUS_E_INVAL; 14146 14147 param->reg_db_version_major = 14148 WMI_REG_DB_VERSION_MAJOR_GET( 14149 ev->reg_db_version); 14150 param->reg_db_version_minor = 14151 WMI_REG_DB_VERSION_MINOR_GET( 14152 ev->reg_db_version); 14153 param->bdf_reg_db_version_major = 14154 WMI_BDF_REG_DB_VERSION_MAJOR_GET( 14155 ev->reg_db_version); 14156 param->bdf_reg_db_version_minor = 14157 WMI_BDF_REG_DB_VERSION_MINOR_GET( 14158 ev->reg_db_version); 14159 param->chwidth_num_peer_caps = ev->chwidth_num_peer_caps; 14160 14161 param->num_dbr_ring_caps = param_buf->num_dma_ring_caps; 14162 14163 if (param_buf->nan_cap) 14164 param->max_ndp_sessions = 14165 param_buf->nan_cap->max_ndp_sessions; 14166 else 14167 param->max_ndp_sessions = 0; 14168 14169 param->preamble_puncture_bw_cap = ev->preamble_puncture_bw; 14170 param->num_scan_radio_caps = param_buf->num_wmi_scan_radio_caps; 14171 param->max_users_dl_ofdma = WMI_MAX_USER_PER_PPDU_DL_OFDMA_GET( 14172 ev->max_user_per_ppdu_ofdma); 14173 param->max_users_ul_ofdma = WMI_MAX_USER_PER_PPDU_UL_OFDMA_GET( 14174 ev->max_user_per_ppdu_ofdma); 14175 param->max_users_dl_mumimo = WMI_MAX_USER_PER_PPDU_DL_MUMIMO_GET( 14176 ev->max_user_per_ppdu_mumimo); 14177 param->max_users_ul_mumimo = WMI_MAX_USER_PER_PPDU_UL_MUMIMO_GET( 14178 ev->max_user_per_ppdu_mumimo); 14179 param->target_cap_flags = ev->target_cap_flags; 14180 extract_ul_mumimo_support(param); 14181 wmi_debug("htt peer data :%d", ev->target_cap_flags); 14182 14183 extract_svc_rdy_ext2_afc_tlv(ev, param); 14184 14185 extract_hw_bdf_status(ev); 14186 14187 return QDF_STATUS_SUCCESS; 14188 } 14189 14190 /* 14191 * extract_dbs_or_sbs_cap_service_ready_ext2_tlv() - extract dbs_or_sbs cap from 14192 * service ready ext 2 14193 * 14194 * @wmi_handle: wmi handle 14195 * @event: pointer to event buffer 14196 * @sbs_lower_band_end_freq: If sbs_lower_band_end_freq is set to non-zero, 14197 * it indicates async SBS mode is supported, and 14198 * lower-band/higher band to MAC mapping is 14199 * switch-able. unit: mhz. examples 5180, 5320 14200 * 14201 * Return: QDF_STATUS_SUCCESS on success, QDF_STATUS_E_** on error 14202 */ 14203 static QDF_STATUS extract_dbs_or_sbs_cap_service_ready_ext2_tlv( 14204 wmi_unified_t wmi_handle, uint8_t *event, 14205 uint32_t *sbs_lower_band_end_freq) 14206 { 14207 WMI_SERVICE_READY_EXT2_EVENTID_param_tlvs *param_buf; 14208 wmi_dbs_or_sbs_cap_ext *dbs_or_sbs_caps; 14209 14210 param_buf = (WMI_SERVICE_READY_EXT2_EVENTID_param_tlvs *)event; 14211 if (!param_buf) 14212 return QDF_STATUS_E_INVAL; 14213 14214 dbs_or_sbs_caps = param_buf->dbs_or_sbs_cap_ext; 14215 if (!dbs_or_sbs_caps) 14216 return QDF_STATUS_E_INVAL; 14217 14218 *sbs_lower_band_end_freq = dbs_or_sbs_caps->sbs_lower_band_end_freq; 14219 14220 return QDF_STATUS_SUCCESS; 14221 } 14222 14223 /** 14224 * extract_sar_cap_service_ready_ext_tlv() - 14225 * extract SAR cap from service ready event 14226 * @wmi_handle: wmi handle 14227 * @event: pointer to event buffer 14228 * @ext_param: extended target info 14229 * 14230 * Return: QDF_STATUS_SUCCESS for success or error code 14231 */ 14232 static QDF_STATUS extract_sar_cap_service_ready_ext_tlv( 14233 wmi_unified_t wmi_handle, 14234 uint8_t *event, 14235 struct wlan_psoc_host_service_ext_param *ext_param) 14236 { 14237 WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *param_buf; 14238 WMI_SAR_CAPABILITIES *sar_caps; 14239 14240 param_buf = (WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *)event; 14241 14242 if (!param_buf) 14243 return QDF_STATUS_E_INVAL; 14244 14245 sar_caps = param_buf->sar_caps; 14246 if (sar_caps) 14247 ext_param->sar_version = sar_caps->active_version; 14248 else 14249 ext_param->sar_version = 0; 14250 14251 return QDF_STATUS_SUCCESS; 14252 } 14253 14254 /** 14255 * extract_hw_mode_cap_service_ready_ext_tlv() - 14256 * extract HW mode cap from service ready event 14257 * @wmi_handle: wmi handle 14258 * @event: pointer to event buffer 14259 * @hw_mode_idx: hw mode idx should be less than num_mode 14260 * @param: Pointer to hold evt buf 14261 * 14262 * Return: QDF_STATUS_SUCCESS for success or error code 14263 */ 14264 static QDF_STATUS extract_hw_mode_cap_service_ready_ext_tlv( 14265 wmi_unified_t wmi_handle, 14266 uint8_t *event, uint8_t hw_mode_idx, 14267 struct wlan_psoc_host_hw_mode_caps *param) 14268 { 14269 WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *param_buf; 14270 WMI_SOC_MAC_PHY_HW_MODE_CAPS *hw_caps; 14271 14272 param_buf = (WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *) event; 14273 if (!param_buf) 14274 return QDF_STATUS_E_INVAL; 14275 14276 hw_caps = param_buf->soc_hw_mode_caps; 14277 if (!hw_caps) 14278 return QDF_STATUS_E_INVAL; 14279 14280 if (!hw_caps->num_hw_modes || 14281 !param_buf->hw_mode_caps || 14282 hw_caps->num_hw_modes > PSOC_MAX_HW_MODE || 14283 hw_caps->num_hw_modes > param_buf->num_hw_mode_caps) 14284 return QDF_STATUS_E_INVAL; 14285 14286 if (hw_mode_idx >= hw_caps->num_hw_modes) 14287 return QDF_STATUS_E_INVAL; 14288 14289 param->hw_mode_id = param_buf->hw_mode_caps[hw_mode_idx].hw_mode_id; 14290 param->phy_id_map = param_buf->hw_mode_caps[hw_mode_idx].phy_id_map; 14291 14292 param->hw_mode_config_type = 14293 param_buf->hw_mode_caps[hw_mode_idx].hw_mode_config_type; 14294 14295 return QDF_STATUS_SUCCESS; 14296 } 14297 14298 /** 14299 * extract_service_ready_11be_support() - api to extract 11be support 14300 * @param: host mac phy capabilities 14301 * @mac_phy_caps: mac phy capabilities 14302 * 14303 * Return: void 14304 */ 14305 #ifdef WLAN_FEATURE_11BE 14306 static void 14307 extract_service_ready_11be_support(struct wlan_psoc_host_mac_phy_caps *param, 14308 WMI_MAC_PHY_CAPABILITIES *mac_phy_caps) 14309 { 14310 param->supports_11be = 14311 WMI_SUPPORT_11BE_GET(mac_phy_caps->supported_flags); 14312 14313 wmi_debug("11be support %d", param->supports_11be); 14314 } 14315 #else 14316 static void 14317 extract_service_ready_11be_support(struct wlan_psoc_host_mac_phy_caps *param, 14318 WMI_MAC_PHY_CAPABILITIES *mac_phy_caps) 14319 { 14320 } 14321 #endif 14322 14323 #if defined(WLAN_FEATURE_11BE_MLO) && defined(WLAN_MLO_MULTI_CHIP) 14324 static void extract_hw_link_id(struct wlan_psoc_host_mac_phy_caps *param, 14325 WMI_MAC_PHY_CAPABILITIES *mac_phy_caps) 14326 { 14327 param->hw_link_id = WMI_PHY_GET_HW_LINK_ID(mac_phy_caps->pdev_id); 14328 } 14329 #else 14330 static void extract_hw_link_id(struct wlan_psoc_host_mac_phy_caps *param, 14331 WMI_MAC_PHY_CAPABILITIES *mac_phy_caps) 14332 { 14333 } 14334 #endif /*WLAN_FEATURE_11BE_MLO && WLAN_MLO_MULTI_CHIP*/ 14335 14336 /** 14337 * extract_mac_phy_cap_service_ready_ext_tlv() - 14338 * extract MAC phy cap from service ready event 14339 * @wmi_handle: wmi handle 14340 * @event: pointer to event buffer 14341 * @hw_mode_id: hw mode idx should be less than num_mode 14342 * @phy_id: phy id within hw_mode 14343 * @param: Pointer to hold evt buf 14344 * 14345 * Return: QDF_STATUS_SUCCESS for success or error code 14346 */ 14347 static QDF_STATUS extract_mac_phy_cap_service_ready_ext_tlv( 14348 wmi_unified_t wmi_handle, 14349 uint8_t *event, uint8_t hw_mode_id, uint8_t phy_id, 14350 struct wlan_psoc_host_mac_phy_caps *param) 14351 { 14352 WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *param_buf; 14353 WMI_MAC_PHY_CAPABILITIES *mac_phy_caps; 14354 WMI_SOC_MAC_PHY_HW_MODE_CAPS *hw_caps; 14355 uint32_t phy_map; 14356 uint8_t hw_idx, phy_idx = 0, pdev_id; 14357 14358 param_buf = (WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *) event; 14359 if (!param_buf) 14360 return QDF_STATUS_E_INVAL; 14361 14362 hw_caps = param_buf->soc_hw_mode_caps; 14363 if (!hw_caps) 14364 return QDF_STATUS_E_INVAL; 14365 if (hw_caps->num_hw_modes > PSOC_MAX_HW_MODE || 14366 hw_caps->num_hw_modes > param_buf->num_hw_mode_caps) { 14367 wmi_err_rl("invalid num_hw_modes %d, num_hw_mode_caps %d", 14368 hw_caps->num_hw_modes, param_buf->num_hw_mode_caps); 14369 return QDF_STATUS_E_INVAL; 14370 } 14371 14372 for (hw_idx = 0; hw_idx < hw_caps->num_hw_modes; hw_idx++) { 14373 if (hw_mode_id == param_buf->hw_mode_caps[hw_idx].hw_mode_id) 14374 break; 14375 14376 phy_map = param_buf->hw_mode_caps[hw_idx].phy_id_map; 14377 while (phy_map) { 14378 phy_map >>= 1; 14379 phy_idx++; 14380 } 14381 } 14382 14383 if (hw_idx == hw_caps->num_hw_modes) 14384 return QDF_STATUS_E_INVAL; 14385 14386 phy_idx += phy_id; 14387 if (phy_idx >= param_buf->num_mac_phy_caps) 14388 return QDF_STATUS_E_INVAL; 14389 14390 mac_phy_caps = ¶m_buf->mac_phy_caps[phy_idx]; 14391 14392 param->hw_mode_id = mac_phy_caps->hw_mode_id; 14393 param->phy_idx = phy_idx; 14394 pdev_id = WMI_PHY_GET_PDEV_ID(mac_phy_caps->pdev_id); 14395 param->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host( 14396 wmi_handle, 14397 pdev_id); 14398 param->tgt_pdev_id = pdev_id; 14399 extract_hw_link_id(param, mac_phy_caps); 14400 param->phy_id = mac_phy_caps->phy_id; 14401 param->supports_11b = 14402 WMI_SUPPORT_11B_GET(mac_phy_caps->supported_flags); 14403 param->supports_11g = 14404 WMI_SUPPORT_11G_GET(mac_phy_caps->supported_flags); 14405 param->supports_11a = 14406 WMI_SUPPORT_11A_GET(mac_phy_caps->supported_flags); 14407 param->supports_11n = 14408 WMI_SUPPORT_11N_GET(mac_phy_caps->supported_flags); 14409 param->supports_11ac = 14410 WMI_SUPPORT_11AC_GET(mac_phy_caps->supported_flags); 14411 param->supports_11ax = 14412 WMI_SUPPORT_11AX_GET(mac_phy_caps->supported_flags); 14413 14414 extract_service_ready_11be_support(param, mac_phy_caps); 14415 14416 param->supported_bands = mac_phy_caps->supported_bands; 14417 param->ampdu_density = mac_phy_caps->ampdu_density; 14418 param->max_bw_supported_2G = mac_phy_caps->max_bw_supported_2G; 14419 param->ht_cap_info_2G = mac_phy_caps->ht_cap_info_2G; 14420 param->vht_cap_info_2G = mac_phy_caps->vht_cap_info_2G; 14421 param->vht_supp_mcs_2G = mac_phy_caps->vht_supp_mcs_2G; 14422 param->he_cap_info_2G[WMI_HOST_HECAP_MAC_WORD1] = 14423 mac_phy_caps->he_cap_info_2G; 14424 param->he_cap_info_2G[WMI_HOST_HECAP_MAC_WORD2] = 14425 mac_phy_caps->he_cap_info_2G_ext; 14426 param->he_supp_mcs_2G = mac_phy_caps->he_supp_mcs_2G; 14427 param->tx_chain_mask_2G = mac_phy_caps->tx_chain_mask_2G; 14428 param->rx_chain_mask_2G = mac_phy_caps->rx_chain_mask_2G; 14429 param->max_bw_supported_5G = mac_phy_caps->max_bw_supported_5G; 14430 param->ht_cap_info_5G = mac_phy_caps->ht_cap_info_5G; 14431 param->vht_cap_info_5G = mac_phy_caps->vht_cap_info_5G; 14432 param->vht_supp_mcs_5G = mac_phy_caps->vht_supp_mcs_5G; 14433 param->he_cap_info_5G[WMI_HOST_HECAP_MAC_WORD1] = 14434 mac_phy_caps->he_cap_info_5G; 14435 param->he_cap_info_5G[WMI_HOST_HECAP_MAC_WORD2] = 14436 mac_phy_caps->he_cap_info_5G_ext; 14437 param->he_supp_mcs_5G = mac_phy_caps->he_supp_mcs_5G; 14438 param->he_cap_info_internal = mac_phy_caps->he_cap_info_internal; 14439 param->tx_chain_mask_5G = mac_phy_caps->tx_chain_mask_5G; 14440 param->rx_chain_mask_5G = mac_phy_caps->rx_chain_mask_5G; 14441 qdf_mem_copy(¶m->he_cap_phy_info_2G, 14442 &mac_phy_caps->he_cap_phy_info_2G, 14443 sizeof(param->he_cap_phy_info_2G)); 14444 qdf_mem_copy(¶m->he_cap_phy_info_5G, 14445 &mac_phy_caps->he_cap_phy_info_5G, 14446 sizeof(param->he_cap_phy_info_5G)); 14447 qdf_mem_copy(¶m->he_ppet2G, &mac_phy_caps->he_ppet2G, 14448 sizeof(param->he_ppet2G)); 14449 qdf_mem_copy(¶m->he_ppet5G, &mac_phy_caps->he_ppet5G, 14450 sizeof(param->he_ppet5G)); 14451 param->chainmask_table_id = mac_phy_caps->chainmask_table_id; 14452 param->lmac_id = mac_phy_caps->lmac_id; 14453 param->reg_cap_ext.wireless_modes = convert_wireless_modes_tlv 14454 (mac_phy_caps->wireless_modes); 14455 param->reg_cap_ext.low_2ghz_chan = mac_phy_caps->low_2ghz_chan_freq; 14456 param->reg_cap_ext.high_2ghz_chan = mac_phy_caps->high_2ghz_chan_freq; 14457 param->reg_cap_ext.low_5ghz_chan = mac_phy_caps->low_5ghz_chan_freq; 14458 param->reg_cap_ext.high_5ghz_chan = mac_phy_caps->high_5ghz_chan_freq; 14459 param->nss_ratio_enabled = WMI_NSS_RATIO_ENABLE_DISABLE_GET( 14460 mac_phy_caps->nss_ratio); 14461 param->nss_ratio_info = WMI_NSS_RATIO_INFO_GET(mac_phy_caps->nss_ratio); 14462 14463 return QDF_STATUS_SUCCESS; 14464 } 14465 14466 #ifdef WLAN_FEATURE_11BE_MLO 14467 /** 14468 * extract_mac_phy_emlcap() - API to extract EML Capabilities 14469 * @param: host ext2 mac phy capabilities 14470 * @mac_phy_caps: ext mac phy capabilities 14471 * 14472 * Return: void 14473 */ 14474 static void extract_mac_phy_emlcap(struct wlan_psoc_host_mac_phy_caps_ext2 *param, 14475 WMI_MAC_PHY_CAPABILITIES_EXT *mac_phy_caps) 14476 { 14477 if (!param || !mac_phy_caps) 14478 return; 14479 14480 param->emlcap.emlsr_supp = WMI_SUPPORT_EMLSR_GET(mac_phy_caps->eml_capability); 14481 param->emlcap.emlsr_pad_delay = WMI_EMLSR_PADDING_DELAY_GET(mac_phy_caps->eml_capability); 14482 param->emlcap.emlsr_trans_delay = WMI_EMLSR_TRANSITION_DELAY_GET(mac_phy_caps->eml_capability); 14483 param->emlcap.emlmr_supp = WMI_SUPPORT_EMLMR_GET(mac_phy_caps->eml_capability); 14484 param->emlcap.emlmr_delay = WMI_EMLMR_DELAY_GET(mac_phy_caps->eml_capability); 14485 param->emlcap.trans_timeout = WMI_TRANSITION_TIMEOUT_GET(mac_phy_caps->eml_capability); 14486 } 14487 14488 /** 14489 * extract_mac_phy_mldcap() - API to extract MLD Capabilities 14490 * @param: host ext2 mac phy capabilities 14491 * @mac_phy_caps: ext mac phy capabilities 14492 * 14493 * Return: void 14494 */ 14495 static void extract_mac_phy_mldcap(struct wlan_psoc_host_mac_phy_caps_ext2 *param, 14496 WMI_MAC_PHY_CAPABILITIES_EXT *mac_phy_caps) 14497 { 14498 if (!param || !mac_phy_caps) 14499 return; 14500 14501 param->mldcap.max_simult_link = WMI_MAX_NUM_SIMULTANEOUS_LINKS_GET(mac_phy_caps->mld_capability); 14502 param->mldcap.srs_support = WMI_SUPPORT_SRS_GET(mac_phy_caps->mld_capability); 14503 param->mldcap.tid2link_neg_support = WMI_TID_TO_LINK_NEGOTIATION_GET(mac_phy_caps->mld_capability); 14504 param->mldcap.str_freq_sep = WMI_FREQ_SEPERATION_STR_GET(mac_phy_caps->mld_capability); 14505 param->mldcap.aar_support = WMI_SUPPORT_AAR_GET(mac_phy_caps->mld_capability); 14506 } 14507 #else 14508 static void extract_mac_phy_emlcap(struct wlan_psoc_host_mac_phy_caps_ext2 *param, 14509 WMI_MAC_PHY_CAPABILITIES_EXT *mac_phy_caps) 14510 { 14511 } 14512 14513 static void extract_mac_phy_mldcap(struct wlan_psoc_host_mac_phy_caps_ext2 *param, 14514 WMI_MAC_PHY_CAPABILITIES_EXT *mac_phy_caps) 14515 { 14516 } 14517 #endif 14518 14519 /** 14520 * extract_mac_phy_cap_ehtcaps- api to extract eht mac phy caps 14521 * @param: host ext2 mac phy capabilities 14522 * @mac_phy_caps: ext mac phy capabilities 14523 * 14524 * Return: void 14525 */ 14526 #ifdef WLAN_FEATURE_11BE 14527 static void extract_mac_phy_cap_ehtcaps( 14528 struct wlan_psoc_host_mac_phy_caps_ext2 *param, 14529 WMI_MAC_PHY_CAPABILITIES_EXT *mac_phy_caps) 14530 { 14531 uint32_t i; 14532 14533 param->eht_supp_mcs_2G = mac_phy_caps->eht_supp_mcs_2G; 14534 param->eht_supp_mcs_5G = mac_phy_caps->eht_supp_mcs_5G; 14535 param->eht_cap_info_internal = mac_phy_caps->eht_cap_info_internal; 14536 14537 qdf_mem_copy(¶m->eht_cap_info_2G, 14538 &mac_phy_caps->eht_cap_mac_info_2G, 14539 sizeof(param->eht_cap_info_2G)); 14540 qdf_mem_copy(¶m->eht_cap_info_5G, 14541 &mac_phy_caps->eht_cap_mac_info_5G, 14542 sizeof(param->eht_cap_info_5G)); 14543 14544 qdf_mem_copy(¶m->eht_cap_phy_info_2G, 14545 &mac_phy_caps->eht_cap_phy_info_2G, 14546 sizeof(param->eht_cap_phy_info_2G)); 14547 qdf_mem_copy(¶m->eht_cap_phy_info_5G, 14548 &mac_phy_caps->eht_cap_phy_info_5G, 14549 sizeof(param->eht_cap_phy_info_5G)); 14550 14551 qdf_mem_copy(¶m->eht_supp_mcs_ext_2G, 14552 &mac_phy_caps->eht_supp_mcs_ext_2G, 14553 sizeof(param->eht_supp_mcs_ext_2G)); 14554 qdf_mem_copy(¶m->eht_supp_mcs_ext_5G, 14555 &mac_phy_caps->eht_supp_mcs_ext_5G, 14556 sizeof(param->eht_supp_mcs_ext_5G)); 14557 14558 qdf_mem_copy(¶m->eht_ppet2G, &mac_phy_caps->eht_ppet2G, 14559 sizeof(param->eht_ppet2G)); 14560 qdf_mem_copy(¶m->eht_ppet5G, &mac_phy_caps->eht_ppet5G, 14561 sizeof(param->eht_ppet5G)); 14562 14563 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", 14564 mac_phy_caps->eht_cap_mac_info_2G[0], 14565 mac_phy_caps->eht_cap_mac_info_5G[0], 14566 mac_phy_caps->eht_supp_mcs_2G, mac_phy_caps->eht_supp_mcs_5G, 14567 mac_phy_caps->eht_cap_info_internal); 14568 14569 wmi_nofl_debug("EHT phy caps: "); 14570 14571 wmi_nofl_debug("2G:"); 14572 for (i = 0; i < PSOC_HOST_MAX_EHT_PHY_SIZE; i++) { 14573 wmi_nofl_debug("index %d value %x", 14574 i, param->eht_cap_phy_info_2G[i]); 14575 } 14576 wmi_nofl_debug("5G:"); 14577 for (i = 0; i < PSOC_HOST_MAX_EHT_PHY_SIZE; i++) { 14578 wmi_nofl_debug("index %d value %x", 14579 i, param->eht_cap_phy_info_5G[i]); 14580 } 14581 wmi_nofl_debug("2G MCS ext Map:"); 14582 for (i = 0; i < PSOC_HOST_EHT_MCS_NSS_MAP_2G_SIZE; i++) { 14583 wmi_nofl_debug("index %d value %x", 14584 i, param->eht_supp_mcs_ext_2G[i]); 14585 } 14586 wmi_nofl_debug("5G MCS ext Map:"); 14587 for (i = 0; i < PSOC_HOST_EHT_MCS_NSS_MAP_5G_SIZE; i++) { 14588 wmi_nofl_debug("index %d value %x", 14589 i, param->eht_supp_mcs_ext_5G[i]); 14590 } 14591 wmi_nofl_debug("2G PPET: numss_m1 %x ru_bit_mask %x", 14592 param->eht_ppet2G.numss_m1, 14593 param->eht_ppet2G.ru_bit_mask); 14594 for (i = 0; i < PSOC_HOST_MAX_NUM_SS; i++) { 14595 wmi_nofl_debug("index %d value %x", 14596 i, param->eht_ppet2G.ppet16_ppet8_ru3_ru0[i]); 14597 } 14598 wmi_nofl_debug("5G PPET: numss_m1 %x ru_bit_mask %x", 14599 param->eht_ppet5G.numss_m1, 14600 param->eht_ppet5G.ru_bit_mask); 14601 for (i = 0; i < PSOC_HOST_MAX_NUM_SS; i++) { 14602 wmi_nofl_debug("index %d value %x", 14603 i, param->eht_ppet5G.ppet16_ppet8_ru3_ru0[i]); 14604 } 14605 } 14606 #else 14607 static void extract_mac_phy_cap_ehtcaps( 14608 struct wlan_psoc_host_mac_phy_caps_ext2 *param, 14609 WMI_MAC_PHY_CAPABILITIES_EXT *mac_phy_caps) 14610 { 14611 } 14612 #endif 14613 14614 static QDF_STATUS extract_mac_phy_cap_service_ready_ext2_tlv( 14615 wmi_unified_t wmi_handle, 14616 uint8_t *event, uint8_t hw_mode_id, uint8_t phy_id, 14617 uint8_t phy_idx, 14618 struct wlan_psoc_host_mac_phy_caps_ext2 *param) 14619 { 14620 WMI_SERVICE_READY_EXT2_EVENTID_param_tlvs *param_buf; 14621 WMI_MAC_PHY_CAPABILITIES_EXT *mac_phy_caps; 14622 14623 if (!event) { 14624 wmi_err("null evt_buf"); 14625 return QDF_STATUS_E_INVAL; 14626 } 14627 14628 param_buf = (WMI_SERVICE_READY_EXT2_EVENTID_param_tlvs *)event; 14629 14630 if (!param_buf->num_mac_phy_caps) 14631 return QDF_STATUS_SUCCESS; 14632 14633 if (phy_idx >= param_buf->num_mac_phy_caps) 14634 return QDF_STATUS_E_INVAL; 14635 14636 mac_phy_caps = ¶m_buf->mac_phy_caps[phy_idx]; 14637 14638 if ((hw_mode_id != mac_phy_caps->hw_mode_id) || 14639 (phy_id != mac_phy_caps->phy_id)) 14640 return QDF_STATUS_E_INVAL; 14641 14642 param->hw_mode_id = mac_phy_caps->hw_mode_id; 14643 param->phy_id = mac_phy_caps->phy_id; 14644 param->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host( 14645 wmi_handle, WMI_PHY_GET_PDEV_ID(mac_phy_caps->pdev_id)); 14646 param->wireless_modes_ext = convert_wireless_modes_ext_tlv( 14647 mac_phy_caps->wireless_modes_ext); 14648 14649 extract_mac_phy_cap_ehtcaps(param, mac_phy_caps); 14650 extract_mac_phy_emlcap(param, mac_phy_caps); 14651 extract_mac_phy_mldcap(param, mac_phy_caps); 14652 14653 return QDF_STATUS_SUCCESS; 14654 } 14655 14656 /** 14657 * extract_reg_cap_service_ready_ext_tlv() - 14658 * extract REG cap from service ready event 14659 * @wmi_handle: wmi handle 14660 * @event: pointer to event buffer 14661 * @phy_idx: phy idx should be less than num_mode 14662 * @param: Pointer to hold evt buf 14663 * 14664 * Return: QDF_STATUS_SUCCESS for success or error code 14665 */ 14666 static QDF_STATUS extract_reg_cap_service_ready_ext_tlv( 14667 wmi_unified_t wmi_handle, 14668 uint8_t *event, uint8_t phy_idx, 14669 struct wlan_psoc_host_hal_reg_capabilities_ext *param) 14670 { 14671 WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *param_buf; 14672 WMI_SOC_HAL_REG_CAPABILITIES *reg_caps; 14673 WMI_HAL_REG_CAPABILITIES_EXT *ext_reg_cap; 14674 14675 param_buf = (WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *) event; 14676 if (!param_buf) 14677 return QDF_STATUS_E_INVAL; 14678 14679 reg_caps = param_buf->soc_hal_reg_caps; 14680 if (!reg_caps) 14681 return QDF_STATUS_E_INVAL; 14682 14683 if (reg_caps->num_phy > param_buf->num_hal_reg_caps) 14684 return QDF_STATUS_E_INVAL; 14685 14686 if (phy_idx >= reg_caps->num_phy) 14687 return QDF_STATUS_E_INVAL; 14688 14689 if (!param_buf->hal_reg_caps) 14690 return QDF_STATUS_E_INVAL; 14691 14692 ext_reg_cap = ¶m_buf->hal_reg_caps[phy_idx]; 14693 14694 param->phy_id = ext_reg_cap->phy_id; 14695 param->eeprom_reg_domain = ext_reg_cap->eeprom_reg_domain; 14696 param->eeprom_reg_domain_ext = ext_reg_cap->eeprom_reg_domain_ext; 14697 param->regcap1 = ext_reg_cap->regcap1; 14698 param->regcap2 = ext_reg_cap->regcap2; 14699 param->wireless_modes = convert_wireless_modes_tlv( 14700 ext_reg_cap->wireless_modes); 14701 param->low_2ghz_chan = ext_reg_cap->low_2ghz_chan; 14702 param->high_2ghz_chan = ext_reg_cap->high_2ghz_chan; 14703 param->low_5ghz_chan = ext_reg_cap->low_5ghz_chan; 14704 param->high_5ghz_chan = ext_reg_cap->high_5ghz_chan; 14705 14706 return QDF_STATUS_SUCCESS; 14707 } 14708 14709 static QDF_STATUS validate_dbr_ring_caps_idx(uint8_t idx, 14710 uint8_t num_dma_ring_caps) 14711 { 14712 /* If dma_ring_caps is populated, num_dbr_ring_caps is non-zero */ 14713 if (!num_dma_ring_caps) { 14714 wmi_err("dma_ring_caps %d", num_dma_ring_caps); 14715 return QDF_STATUS_E_INVAL; 14716 } 14717 if (idx >= num_dma_ring_caps) { 14718 wmi_err("Index %d exceeds range", idx); 14719 return QDF_STATUS_E_INVAL; 14720 } 14721 return QDF_STATUS_SUCCESS; 14722 } 14723 14724 static void 14725 populate_dbr_ring_cap_elems(wmi_unified_t wmi_handle, 14726 struct wlan_psoc_host_dbr_ring_caps *param, 14727 WMI_DMA_RING_CAPABILITIES *dbr_ring_caps) 14728 { 14729 param->pdev_id = wmi_handle->ops->convert_target_pdev_id_to_host( 14730 wmi_handle, 14731 dbr_ring_caps->pdev_id); 14732 param->mod_id = dbr_ring_caps->mod_id; 14733 param->ring_elems_min = dbr_ring_caps->ring_elems_min; 14734 param->min_buf_size = dbr_ring_caps->min_buf_size; 14735 param->min_buf_align = dbr_ring_caps->min_buf_align; 14736 } 14737 14738 static QDF_STATUS extract_dbr_ring_cap_service_ready_ext_tlv( 14739 wmi_unified_t wmi_handle, 14740 uint8_t *event, uint8_t idx, 14741 struct wlan_psoc_host_dbr_ring_caps *param) 14742 { 14743 WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *param_buf; 14744 QDF_STATUS status; 14745 14746 param_buf = (WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *)event; 14747 if (!param_buf) 14748 return QDF_STATUS_E_INVAL; 14749 14750 status = validate_dbr_ring_caps_idx(idx, param_buf->num_dma_ring_caps); 14751 if (status != QDF_STATUS_SUCCESS) 14752 return status; 14753 14754 populate_dbr_ring_cap_elems(wmi_handle, param, 14755 ¶m_buf->dma_ring_caps[idx]); 14756 return QDF_STATUS_SUCCESS; 14757 } 14758 14759 static QDF_STATUS extract_dbr_ring_cap_service_ready_ext2_tlv( 14760 wmi_unified_t wmi_handle, 14761 uint8_t *event, uint8_t idx, 14762 struct wlan_psoc_host_dbr_ring_caps *param) 14763 { 14764 WMI_SERVICE_READY_EXT2_EVENTID_param_tlvs *param_buf; 14765 QDF_STATUS status; 14766 14767 param_buf = (WMI_SERVICE_READY_EXT2_EVENTID_param_tlvs *)event; 14768 if (!param_buf) 14769 return QDF_STATUS_E_INVAL; 14770 14771 status = validate_dbr_ring_caps_idx(idx, param_buf->num_dma_ring_caps); 14772 if (status != QDF_STATUS_SUCCESS) 14773 return status; 14774 14775 populate_dbr_ring_cap_elems(wmi_handle, param, 14776 ¶m_buf->dma_ring_caps[idx]); 14777 return QDF_STATUS_SUCCESS; 14778 } 14779 14780 static QDF_STATUS extract_scan_radio_cap_service_ready_ext2_tlv( 14781 wmi_unified_t wmi_handle, 14782 uint8_t *event, uint8_t idx, 14783 struct wlan_psoc_host_scan_radio_caps *param) 14784 { 14785 WMI_SERVICE_READY_EXT2_EVENTID_param_tlvs *param_buf; 14786 WMI_SCAN_RADIO_CAPABILITIES_EXT2 *scan_radio_caps; 14787 14788 param_buf = (WMI_SERVICE_READY_EXT2_EVENTID_param_tlvs *)event; 14789 if (!param_buf) 14790 return QDF_STATUS_E_INVAL; 14791 14792 if (idx >= param_buf->num_wmi_scan_radio_caps) 14793 return QDF_STATUS_E_INVAL; 14794 14795 scan_radio_caps = ¶m_buf->wmi_scan_radio_caps[idx]; 14796 param->phy_id = scan_radio_caps->phy_id; 14797 param->scan_radio_supported = 14798 WMI_SCAN_RADIO_CAP_SCAN_RADIO_FLAG_GET(scan_radio_caps->flags); 14799 param->dfs_en = 14800 WMI_SCAN_RADIO_CAP_DFS_FLAG_GET(scan_radio_caps->flags); 14801 14802 return QDF_STATUS_SUCCESS; 14803 } 14804 14805 static QDF_STATUS extract_sw_cal_ver_ext2_tlv(wmi_unified_t wmi_handle, 14806 uint8_t *event, 14807 struct wmi_host_sw_cal_ver *cal) 14808 { 14809 WMI_SERVICE_READY_EXT2_EVENTID_param_tlvs *param_buf; 14810 wmi_sw_cal_ver_cap *fw_cap; 14811 14812 param_buf = (WMI_SERVICE_READY_EXT2_EVENTID_param_tlvs *)event; 14813 if (!param_buf) 14814 return QDF_STATUS_E_INVAL; 14815 14816 fw_cap = param_buf->sw_cal_ver_cap; 14817 if (!fw_cap) 14818 return QDF_STATUS_E_INVAL; 14819 14820 cal->bdf_cal_ver = fw_cap->bdf_cal_ver; 14821 cal->ftm_cal_ver = fw_cap->ftm_cal_ver; 14822 cal->status = fw_cap->status; 14823 14824 return QDF_STATUS_SUCCESS; 14825 } 14826 14827 /** 14828 * wmi_tgt_thermal_level_to_host() - Convert target thermal level to host enum 14829 * @level: target thermal level from WMI_THERM_THROT_STATS_EVENTID event 14830 * 14831 * Return: host thermal throt level 14832 */ 14833 static enum thermal_throttle_level 14834 wmi_tgt_thermal_level_to_host(uint32_t level) 14835 { 14836 switch (level) { 14837 case WMI_THERMAL_FULLPERF: 14838 return THERMAL_FULLPERF; 14839 case WMI_THERMAL_MITIGATION: 14840 return THERMAL_MITIGATION; 14841 case WMI_THERMAL_SHUTOFF: 14842 return THERMAL_SHUTOFF; 14843 case WMI_THERMAL_SHUTDOWN_TGT: 14844 return THERMAL_SHUTDOWN_TARGET; 14845 default: 14846 return THERMAL_UNKNOWN; 14847 } 14848 } 14849 14850 #ifdef THERMAL_STATS_SUPPORT 14851 static void 14852 populate_thermal_stats(WMI_THERM_THROT_STATS_EVENTID_param_tlvs *param_buf, 14853 uint32_t *therm_throt_levels, 14854 struct thermal_throt_level_stats *tt_temp_range_stats) 14855 { 14856 uint8_t lvl_idx; 14857 wmi_therm_throt_stats_event_fixed_param *tt_stats_event; 14858 wmi_thermal_throt_temp_range_stats *wmi_tt_stats; 14859 14860 tt_stats_event = param_buf->fixed_param; 14861 *therm_throt_levels = (tt_stats_event->therm_throt_levels > 14862 WMI_THERMAL_STATS_TEMP_THRESH_LEVEL_MAX) ? 14863 WMI_THERMAL_STATS_TEMP_THRESH_LEVEL_MAX : 14864 tt_stats_event->therm_throt_levels; 14865 14866 if (*therm_throt_levels > param_buf->num_temp_range_stats) { 14867 wmi_err("therm_throt_levels:%u oob num_temp_range_stats:%u", 14868 *therm_throt_levels, 14869 param_buf->num_temp_range_stats); 14870 return; 14871 } 14872 14873 wmi_tt_stats = param_buf->temp_range_stats; 14874 if (!wmi_tt_stats) { 14875 wmi_err("wmi_tt_stats Null"); 14876 return; 14877 } 14878 14879 for (lvl_idx = 0; lvl_idx < *therm_throt_levels; lvl_idx++) { 14880 tt_temp_range_stats[lvl_idx].start_temp_level = 14881 wmi_tt_stats[lvl_idx].start_temp_level; 14882 tt_temp_range_stats[lvl_idx].end_temp_level = 14883 wmi_tt_stats[lvl_idx].end_temp_level; 14884 tt_temp_range_stats[lvl_idx].total_time_ms_lo = 14885 wmi_tt_stats[lvl_idx].total_time_ms_lo; 14886 tt_temp_range_stats[lvl_idx].total_time_ms_hi = 14887 wmi_tt_stats[lvl_idx].total_time_ms_hi; 14888 tt_temp_range_stats[lvl_idx].num_entry = 14889 wmi_tt_stats[lvl_idx].num_entry; 14890 wmi_debug("level %d, start temp %d, end temp %d, total time low %d, total time high %d, counter %d", 14891 lvl_idx, wmi_tt_stats[lvl_idx].start_temp_level, 14892 wmi_tt_stats[lvl_idx].end_temp_level, 14893 wmi_tt_stats[lvl_idx].total_time_ms_lo, 14894 wmi_tt_stats[lvl_idx].total_time_ms_hi, 14895 wmi_tt_stats[lvl_idx].num_entry); 14896 } 14897 } 14898 #else 14899 static void 14900 populate_thermal_stats(WMI_THERM_THROT_STATS_EVENTID_param_tlvs *param_buf, 14901 uint32_t *therm_throt_levels, 14902 struct thermal_throt_level_stats *tt_temp_range_stats) 14903 { 14904 } 14905 #endif 14906 14907 /** 14908 * extract_thermal_stats_tlv() - extract thermal stats from event 14909 * @wmi_handle: wmi handle 14910 * @evt_buf: Pointer to event buffer 14911 * @temp: Pointer to hold extracted temperature 14912 * @level: Pointer to hold extracted level in host enum 14913 * @therm_throt_levels: Pointer to hold extracted thermal throttle temp 14914 * range 14915 * @tt_temp_range_stats_event: Pointer to hold extracted thermal stats for 14916 * every level 14917 * @pdev_id: Pointer to hold extracted pdev id 14918 * 14919 * Return: QDF_STATUS_SUCCESS for success or error code 14920 */ 14921 static QDF_STATUS 14922 extract_thermal_stats_tlv(wmi_unified_t wmi_handle, 14923 void *evt_buf, uint32_t *temp, 14924 enum thermal_throttle_level *level, 14925 uint32_t *therm_throt_levels, 14926 struct thermal_throt_level_stats *tt_temp_range_stats_event, 14927 uint32_t *pdev_id) 14928 { 14929 WMI_THERM_THROT_STATS_EVENTID_param_tlvs *param_buf; 14930 wmi_therm_throt_stats_event_fixed_param *tt_stats_event; 14931 14932 param_buf = 14933 (WMI_THERM_THROT_STATS_EVENTID_param_tlvs *) evt_buf; 14934 if (!param_buf) 14935 return QDF_STATUS_E_INVAL; 14936 14937 tt_stats_event = param_buf->fixed_param; 14938 wmi_debug("thermal temperature %d level %d", 14939 tt_stats_event->temp, tt_stats_event->level); 14940 *pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host( 14941 wmi_handle, 14942 tt_stats_event->pdev_id); 14943 *temp = tt_stats_event->temp; 14944 *level = wmi_tgt_thermal_level_to_host(tt_stats_event->level); 14945 14946 if (tt_stats_event->therm_throt_levels) 14947 populate_thermal_stats(param_buf, therm_throt_levels, 14948 tt_temp_range_stats_event); 14949 14950 return QDF_STATUS_SUCCESS; 14951 } 14952 14953 /** 14954 * extract_thermal_level_stats_tlv() - extract thermal level stats from event 14955 * @wmi_handle: wmi handle 14956 * @evt_buf: pointer to event buffer 14957 * @idx: Index to level stats 14958 * @levelcount: Pointer to hold levelcount 14959 * @dccount: Pointer to hold dccount 14960 * 14961 * Return: QDF_STATUS_SUCCESS for success or error code 14962 */ 14963 static QDF_STATUS 14964 extract_thermal_level_stats_tlv(wmi_unified_t wmi_handle, 14965 void *evt_buf, uint8_t idx, uint32_t *levelcount, 14966 uint32_t *dccount) 14967 { 14968 WMI_THERM_THROT_STATS_EVENTID_param_tlvs *param_buf; 14969 wmi_therm_throt_level_stats_info *tt_level_info; 14970 14971 param_buf = 14972 (WMI_THERM_THROT_STATS_EVENTID_param_tlvs *) evt_buf; 14973 if (!param_buf) 14974 return QDF_STATUS_E_INVAL; 14975 14976 tt_level_info = param_buf->therm_throt_level_stats_info; 14977 14978 if (idx < THERMAL_LEVELS) { 14979 *levelcount = tt_level_info[idx].level_count; 14980 *dccount = tt_level_info[idx].dc_count; 14981 return QDF_STATUS_SUCCESS; 14982 } 14983 14984 return QDF_STATUS_E_FAILURE; 14985 } 14986 14987 /** 14988 * fips_conv_data_be() - LE to BE conversion of FIPS ev data 14989 * @data_len: data length 14990 * @data: pointer to data 14991 * 14992 * Return: QDF_STATUS - success or error status 14993 */ 14994 #ifdef BIG_ENDIAN_HOST 14995 static QDF_STATUS fips_conv_data_be(uint32_t data_len, uint8_t *data) 14996 { 14997 uint8_t *data_aligned = NULL; 14998 int c; 14999 unsigned char *data_unaligned; 15000 15001 data_unaligned = qdf_mem_malloc(((sizeof(uint8_t) * data_len) + 15002 FIPS_ALIGN)); 15003 /* Assigning unaligned space to copy the data */ 15004 /* Checking if kmalloc does successful allocation */ 15005 if (!data_unaligned) 15006 return QDF_STATUS_E_FAILURE; 15007 15008 /* Checking if space is aligned */ 15009 if (!FIPS_IS_ALIGNED(data_unaligned, FIPS_ALIGN)) { 15010 /* align the data space */ 15011 data_aligned = 15012 (uint8_t *)FIPS_ALIGNTO(data_unaligned, FIPS_ALIGN); 15013 } else { 15014 data_aligned = (u_int8_t *)data_unaligned; 15015 } 15016 15017 /* memset and copy content from data to data aligned */ 15018 OS_MEMSET(data_aligned, 0, data_len); 15019 OS_MEMCPY(data_aligned, data, data_len); 15020 /* Endianness to LE */ 15021 for (c = 0; c < data_len/4; c++) { 15022 *((u_int32_t *)data_aligned + c) = 15023 qdf_le32_to_cpu(*((u_int32_t *)data_aligned + c)); 15024 } 15025 15026 /* Copy content to event->data */ 15027 OS_MEMCPY(data, data_aligned, data_len); 15028 15029 /* clean up allocated space */ 15030 qdf_mem_free(data_unaligned); 15031 data_aligned = NULL; 15032 data_unaligned = NULL; 15033 15034 /*************************************************************/ 15035 15036 return QDF_STATUS_SUCCESS; 15037 } 15038 #else 15039 static QDF_STATUS fips_conv_data_be(uint32_t data_len, uint8_t *data) 15040 { 15041 return QDF_STATUS_SUCCESS; 15042 } 15043 #endif 15044 15045 /** 15046 * send_pdev_get_pn_cmd_tlv() - send get PN request params to fw 15047 * @wmi_handle: wmi handle 15048 * @params: PN request params for peer 15049 * 15050 * Return: QDF_STATUS - success or error status 15051 */ 15052 static QDF_STATUS 15053 send_pdev_get_pn_cmd_tlv(wmi_unified_t wmi_handle, 15054 struct peer_request_pn_param *params) 15055 { 15056 wmi_peer_tx_pn_request_cmd_fixed_param *cmd; 15057 wmi_buf_t buf; 15058 uint8_t *buf_ptr; 15059 uint32_t len = sizeof(wmi_peer_tx_pn_request_cmd_fixed_param); 15060 15061 buf = wmi_buf_alloc(wmi_handle, len); 15062 if (!buf) { 15063 wmi_err("wmi_buf_alloc failed"); 15064 return QDF_STATUS_E_FAILURE; 15065 } 15066 15067 buf_ptr = (uint8_t *)wmi_buf_data(buf); 15068 cmd = (wmi_peer_tx_pn_request_cmd_fixed_param *)buf_ptr; 15069 15070 WMITLV_SET_HDR(&cmd->tlv_header, 15071 WMITLV_TAG_STRUC_wmi_peer_tx_pn_request_cmd_fixed_param, 15072 WMITLV_GET_STRUCT_TLVLEN(wmi_peer_tx_pn_request_cmd_fixed_param)); 15073 15074 cmd->vdev_id = params->vdev_id; 15075 WMI_CHAR_ARRAY_TO_MAC_ADDR(params->peer_macaddr, &cmd->peer_macaddr); 15076 cmd->key_type = params->key_type; 15077 cmd->key_ix = params->keyix; 15078 if (wmi_unified_cmd_send(wmi_handle, buf, len, 15079 WMI_PEER_TX_PN_REQUEST_CMDID)) { 15080 wmi_err("Failed to send WMI command"); 15081 wmi_buf_free(buf); 15082 return QDF_STATUS_E_FAILURE; 15083 } 15084 return QDF_STATUS_SUCCESS; 15085 } 15086 15087 /** 15088 * extract_get_pn_data_tlv() - extract pn resp 15089 * @wmi_handle: wmi handle 15090 * @evt_buf: pointer to event buffer 15091 * @param: PN response params for peer 15092 * 15093 * Return: QDF_STATUS - success or error status 15094 */ 15095 static QDF_STATUS 15096 extract_get_pn_data_tlv(wmi_unified_t wmi_handle, void *evt_buf, 15097 struct wmi_host_get_pn_event *param) 15098 { 15099 WMI_PEER_TX_PN_RESPONSE_EVENTID_param_tlvs *param_buf; 15100 wmi_peer_tx_pn_response_event_fixed_param *event = NULL; 15101 15102 param_buf = (WMI_PEER_TX_PN_RESPONSE_EVENTID_param_tlvs *)evt_buf; 15103 event = 15104 (wmi_peer_tx_pn_response_event_fixed_param *)param_buf->fixed_param; 15105 15106 param->vdev_id = event->vdev_id; 15107 param->key_type = event->key_type; 15108 param->key_ix = event->key_ix; 15109 qdf_mem_copy(param->pn, event->pn, sizeof(event->pn)); 15110 WMI_MAC_ADDR_TO_CHAR_ARRAY(&event->peer_macaddr, param->mac_addr); 15111 15112 return QDF_STATUS_SUCCESS; 15113 } 15114 15115 /** 15116 * send_pdev_get_rxpn_cmd_tlv() - send get Rx PN request params to fw 15117 * @wmi_handle: wmi handle 15118 * @params: Rx PN request params for peer 15119 * 15120 * Return: QDF_STATUS - success or error status 15121 */ 15122 static QDF_STATUS 15123 send_pdev_get_rxpn_cmd_tlv(wmi_unified_t wmi_handle, 15124 struct peer_request_rxpn_param *params) 15125 { 15126 wmi_peer_rx_pn_request_cmd_fixed_param *cmd; 15127 wmi_buf_t buf; 15128 uint8_t *buf_ptr; 15129 uint32_t len = sizeof(wmi_peer_rx_pn_request_cmd_fixed_param); 15130 15131 if (!is_service_enabled_tlv(wmi_handle, 15132 WMI_SERVICE_PN_REPLAY_CHECK_SUPPORT)) { 15133 wmi_err("Rx PN Replay Check not supported by target"); 15134 return QDF_STATUS_E_NOSUPPORT; 15135 } 15136 15137 buf = wmi_buf_alloc(wmi_handle, len); 15138 if (!buf) { 15139 wmi_err("wmi_buf_alloc failed"); 15140 return QDF_STATUS_E_FAILURE; 15141 } 15142 15143 buf_ptr = (uint8_t *)wmi_buf_data(buf); 15144 cmd = (wmi_peer_rx_pn_request_cmd_fixed_param *)buf_ptr; 15145 15146 WMITLV_SET_HDR(&cmd->tlv_header, 15147 WMITLV_TAG_STRUC_wmi_peer_rx_pn_request_cmd_fixed_param, 15148 WMITLV_GET_STRUCT_TLVLEN(wmi_peer_rx_pn_request_cmd_fixed_param)); 15149 15150 cmd->vdev_id = params->vdev_id; 15151 WMI_CHAR_ARRAY_TO_MAC_ADDR(params->peer_macaddr, &cmd->peer_macaddr); 15152 cmd->key_ix = params->keyix; 15153 if (wmi_unified_cmd_send(wmi_handle, buf, len, 15154 WMI_PEER_RX_PN_REQUEST_CMDID)) { 15155 wmi_err("Failed to send WMI command"); 15156 wmi_buf_free(buf); 15157 return QDF_STATUS_E_FAILURE; 15158 } 15159 return QDF_STATUS_SUCCESS; 15160 } 15161 15162 /** 15163 * extract_get_rxpn_data_tlv() - extract Rx PN resp 15164 * @wmi_handle: wmi handle 15165 * @evt_buf: pointer to event buffer 15166 * @params: Rx PN response params for peer 15167 * 15168 * Return: QDF_STATUS - success or error status 15169 */ 15170 static QDF_STATUS 15171 extract_get_rxpn_data_tlv(wmi_unified_t wmi_handle, void *evt_buf, 15172 struct wmi_host_get_rxpn_event *params) 15173 { 15174 WMI_PEER_RX_PN_RESPONSE_EVENTID_param_tlvs *param_buf; 15175 wmi_peer_rx_pn_response_event_fixed_param *event; 15176 15177 param_buf = evt_buf; 15178 event = param_buf->fixed_param; 15179 15180 params->vdev_id = event->vdev_id; 15181 params->keyix = event->key_idx; 15182 qdf_mem_copy(params->pn, event->pn, sizeof(event->pn)); 15183 WMI_MAC_ADDR_TO_CHAR_ARRAY(&event->peer_macaddr, params->mac_addr); 15184 15185 return QDF_STATUS_SUCCESS; 15186 } 15187 15188 /** 15189 * extract_fips_event_data_tlv() - extract fips event data 15190 * @wmi_handle: wmi handle 15191 * @evt_buf: pointer to event buffer 15192 * @param: pointer FIPS event params 15193 * 15194 * Return: QDF_STATUS_SUCCESS for success or error code 15195 */ 15196 static QDF_STATUS extract_fips_event_data_tlv(wmi_unified_t wmi_handle, 15197 void *evt_buf, struct wmi_host_fips_event_param *param) 15198 { 15199 WMI_PDEV_FIPS_EVENTID_param_tlvs *param_buf; 15200 wmi_pdev_fips_event_fixed_param *event; 15201 15202 param_buf = (WMI_PDEV_FIPS_EVENTID_param_tlvs *) evt_buf; 15203 event = (wmi_pdev_fips_event_fixed_param *) param_buf->fixed_param; 15204 15205 if (event->data_len > param_buf->num_data) 15206 return QDF_STATUS_E_FAILURE; 15207 15208 if (fips_conv_data_be(event->data_len, param_buf->data) != 15209 QDF_STATUS_SUCCESS) 15210 return QDF_STATUS_E_FAILURE; 15211 15212 param->data = (uint32_t *)param_buf->data; 15213 param->data_len = event->data_len; 15214 param->error_status = event->error_status; 15215 param->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host( 15216 wmi_handle, 15217 event->pdev_id); 15218 15219 return QDF_STATUS_SUCCESS; 15220 } 15221 15222 #ifdef WLAN_FEATURE_FIPS_BER_CCMGCM 15223 /** 15224 * extract_fips_extend_event_data_tlv() - extract fips event data 15225 * @wmi_handle: wmi handle 15226 * @evt_buf: pointer to event buffer 15227 * @param: pointer FIPS event params 15228 * 15229 * Return: QDF_STATUS_SUCCESS for success or error code 15230 */ 15231 static QDF_STATUS 15232 extract_fips_extend_event_data_tlv(wmi_unified_t wmi_handle, 15233 void *evt_buf, 15234 struct wmi_host_fips_extend_event_param 15235 *param) 15236 { 15237 WMI_PDEV_FIPS_EXTEND_EVENTID_param_tlvs *param_buf; 15238 wmi_pdev_fips_extend_event_fixed_param *event; 15239 15240 param_buf = (WMI_PDEV_FIPS_EXTEND_EVENTID_param_tlvs *)evt_buf; 15241 event = (wmi_pdev_fips_extend_event_fixed_param *)param_buf->fixed_param; 15242 15243 if (fips_conv_data_be(event->data_len, param_buf->data) != 15244 QDF_STATUS_SUCCESS) 15245 return QDF_STATUS_E_FAILURE; 15246 15247 param->data = (uint32_t *)param_buf->data; 15248 param->data_len = event->data_len; 15249 param->error_status = event->error_status; 15250 param->fips_cookie = event->fips_cookie; 15251 param->cmd_frag_idx = event->cmd_frag_idx; 15252 param->more_bit = event->more_bit; 15253 param->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host( 15254 wmi_handle, 15255 event->pdev_id); 15256 15257 return QDF_STATUS_SUCCESS; 15258 } 15259 #endif 15260 15261 #ifdef WLAN_FEATURE_DISA 15262 /** 15263 * extract_encrypt_decrypt_resp_event_tlv() - extract encrypt decrypt resp 15264 * params from event 15265 * @wmi_handle: wmi handle 15266 * @evt_buf: pointer to event buffer 15267 * @resp: Pointer to hold resp parameters 15268 * 15269 * Return: QDF_STATUS_SUCCESS for success or error code 15270 */ 15271 static QDF_STATUS 15272 extract_encrypt_decrypt_resp_event_tlv(wmi_unified_t wmi_handle, 15273 void *evt_buf, 15274 struct disa_encrypt_decrypt_resp_params 15275 *resp) 15276 { 15277 WMI_VDEV_ENCRYPT_DECRYPT_DATA_RESP_EVENTID_param_tlvs *param_buf; 15278 wmi_vdev_encrypt_decrypt_data_resp_event_fixed_param *data_event; 15279 15280 param_buf = evt_buf; 15281 if (!param_buf) { 15282 wmi_err("encrypt decrypt resp evt_buf is NULL"); 15283 return QDF_STATUS_E_INVAL; 15284 } 15285 15286 data_event = param_buf->fixed_param; 15287 15288 resp->vdev_id = data_event->vdev_id; 15289 resp->status = data_event->status; 15290 15291 if ((data_event->data_length > param_buf->num_enc80211_frame) || 15292 (data_event->data_length > WMI_SVC_MSG_MAX_SIZE - 15293 WMI_TLV_HDR_SIZE - sizeof(*data_event))) { 15294 wmi_err("FW msg data_len %d more than TLV hdr %d", 15295 data_event->data_length, 15296 param_buf->num_enc80211_frame); 15297 return QDF_STATUS_E_INVAL; 15298 } 15299 15300 resp->data_len = data_event->data_length; 15301 15302 if (resp->data_len) 15303 resp->data = (uint8_t *)param_buf->enc80211_frame; 15304 15305 return QDF_STATUS_SUCCESS; 15306 } 15307 #endif /* WLAN_FEATURE_DISA */ 15308 15309 static bool is_management_record_tlv(uint32_t cmd_id) 15310 { 15311 switch (cmd_id) { 15312 case WMI_MGMT_TX_SEND_CMDID: 15313 case WMI_MGMT_TX_COMPLETION_EVENTID: 15314 case WMI_OFFCHAN_DATA_TX_SEND_CMDID: 15315 case WMI_MGMT_RX_EVENTID: 15316 return true; 15317 default: 15318 return false; 15319 } 15320 } 15321 15322 static bool is_diag_event_tlv(uint32_t event_id) 15323 { 15324 if (WMI_DIAG_EVENTID == event_id) 15325 return true; 15326 15327 return false; 15328 } 15329 15330 static uint16_t wmi_tag_fw_hang_cmd(wmi_unified_t wmi_handle) 15331 { 15332 uint16_t tag = 0; 15333 15334 if (qdf_atomic_read(&wmi_handle->is_target_suspended)) { 15335 qdf_nofl_err("%s: Target is already suspended, Ignore FW Hang Command", 15336 __func__); 15337 return tag; 15338 } 15339 15340 if (wmi_handle->tag_crash_inject) 15341 tag = HTC_TX_PACKET_TAG_AUTO_PM; 15342 15343 wmi_handle->tag_crash_inject = false; 15344 return tag; 15345 } 15346 15347 /** 15348 * wmi_set_htc_tx_tag_tlv() - set HTC TX tag for WMI commands 15349 * @wmi_handle: WMI handle 15350 * @buf: WMI buffer 15351 * @cmd_id: WMI command Id 15352 * 15353 * Return: htc_tx_tag 15354 */ 15355 static uint16_t wmi_set_htc_tx_tag_tlv(wmi_unified_t wmi_handle, 15356 wmi_buf_t buf, 15357 uint32_t cmd_id) 15358 { 15359 uint16_t htc_tx_tag = 0; 15360 15361 switch (cmd_id) { 15362 case WMI_WOW_ENABLE_CMDID: 15363 case WMI_PDEV_SUSPEND_CMDID: 15364 case WMI_WOW_HOSTWAKEUP_FROM_SLEEP_CMDID: 15365 case WMI_PDEV_RESUME_CMDID: 15366 case WMI_HB_SET_ENABLE_CMDID: 15367 case WMI_WOW_SET_ACTION_WAKE_UP_CMDID: 15368 #ifdef FEATURE_WLAN_D0WOW 15369 case WMI_D0_WOW_ENABLE_DISABLE_CMDID: 15370 #endif 15371 htc_tx_tag = HTC_TX_PACKET_TAG_AUTO_PM; 15372 break; 15373 case WMI_FORCE_FW_HANG_CMDID: 15374 htc_tx_tag = wmi_tag_fw_hang_cmd(wmi_handle); 15375 break; 15376 default: 15377 break; 15378 } 15379 15380 return htc_tx_tag; 15381 } 15382 15383 #ifdef CONFIG_BAND_6GHZ 15384 15385 static struct cur_reg_rule 15386 *create_ext_reg_rules_from_wmi(uint32_t num_reg_rules, 15387 wmi_regulatory_rule_ext_struct *wmi_reg_rule) 15388 { 15389 struct cur_reg_rule *reg_rule_ptr; 15390 uint32_t count; 15391 15392 if (!num_reg_rules) 15393 return NULL; 15394 15395 reg_rule_ptr = qdf_mem_malloc(num_reg_rules * 15396 sizeof(*reg_rule_ptr)); 15397 15398 if (!reg_rule_ptr) 15399 return NULL; 15400 15401 for (count = 0; count < num_reg_rules; count++) { 15402 reg_rule_ptr[count].start_freq = 15403 WMI_REG_RULE_START_FREQ_GET( 15404 wmi_reg_rule[count].freq_info); 15405 reg_rule_ptr[count].end_freq = 15406 WMI_REG_RULE_END_FREQ_GET( 15407 wmi_reg_rule[count].freq_info); 15408 reg_rule_ptr[count].max_bw = 15409 WMI_REG_RULE_MAX_BW_GET( 15410 wmi_reg_rule[count].bw_pwr_info); 15411 reg_rule_ptr[count].reg_power = 15412 WMI_REG_RULE_REG_POWER_GET( 15413 wmi_reg_rule[count].bw_pwr_info); 15414 reg_rule_ptr[count].ant_gain = 15415 WMI_REG_RULE_ANTENNA_GAIN_GET( 15416 wmi_reg_rule[count].bw_pwr_info); 15417 reg_rule_ptr[count].flags = 15418 WMI_REG_RULE_FLAGS_GET( 15419 wmi_reg_rule[count].flag_info); 15420 reg_rule_ptr[count].psd_flag = 15421 WMI_REG_RULE_PSD_FLAG_GET( 15422 wmi_reg_rule[count].psd_power_info); 15423 reg_rule_ptr[count].psd_eirp = 15424 WMI_REG_RULE_PSD_EIRP_GET( 15425 wmi_reg_rule[count].psd_power_info); 15426 } 15427 15428 return reg_rule_ptr; 15429 } 15430 #endif 15431 15432 static struct cur_reg_rule 15433 *create_reg_rules_from_wmi(uint32_t num_reg_rules, 15434 wmi_regulatory_rule_struct *wmi_reg_rule) 15435 { 15436 struct cur_reg_rule *reg_rule_ptr; 15437 uint32_t count; 15438 15439 if (!num_reg_rules) 15440 return NULL; 15441 15442 reg_rule_ptr = qdf_mem_malloc(num_reg_rules * 15443 sizeof(*reg_rule_ptr)); 15444 15445 if (!reg_rule_ptr) 15446 return NULL; 15447 15448 for (count = 0; count < num_reg_rules; count++) { 15449 reg_rule_ptr[count].start_freq = 15450 WMI_REG_RULE_START_FREQ_GET( 15451 wmi_reg_rule[count].freq_info); 15452 reg_rule_ptr[count].end_freq = 15453 WMI_REG_RULE_END_FREQ_GET( 15454 wmi_reg_rule[count].freq_info); 15455 reg_rule_ptr[count].max_bw = 15456 WMI_REG_RULE_MAX_BW_GET( 15457 wmi_reg_rule[count].bw_pwr_info); 15458 reg_rule_ptr[count].reg_power = 15459 WMI_REG_RULE_REG_POWER_GET( 15460 wmi_reg_rule[count].bw_pwr_info); 15461 reg_rule_ptr[count].ant_gain = 15462 WMI_REG_RULE_ANTENNA_GAIN_GET( 15463 wmi_reg_rule[count].bw_pwr_info); 15464 reg_rule_ptr[count].flags = 15465 WMI_REG_RULE_FLAGS_GET( 15466 wmi_reg_rule[count].flag_info); 15467 } 15468 15469 return reg_rule_ptr; 15470 } 15471 15472 static enum cc_setting_code wmi_reg_status_to_reg_status( 15473 WMI_REG_SET_CC_STATUS_CODE wmi_status_code) 15474 { 15475 if (wmi_status_code == WMI_REG_SET_CC_STATUS_PASS) { 15476 wmi_nofl_debug("REG_SET_CC_STATUS_PASS"); 15477 return REG_SET_CC_STATUS_PASS; 15478 } else if (wmi_status_code == WMI_REG_CURRENT_ALPHA2_NOT_FOUND) { 15479 wmi_nofl_debug("WMI_REG_CURRENT_ALPHA2_NOT_FOUND"); 15480 return REG_CURRENT_ALPHA2_NOT_FOUND; 15481 } else if (wmi_status_code == WMI_REG_INIT_ALPHA2_NOT_FOUND) { 15482 wmi_nofl_debug("WMI_REG_INIT_ALPHA2_NOT_FOUND"); 15483 return REG_INIT_ALPHA2_NOT_FOUND; 15484 } else if (wmi_status_code == WMI_REG_SET_CC_CHANGE_NOT_ALLOWED) { 15485 wmi_nofl_debug("WMI_REG_SET_CC_CHANGE_NOT_ALLOWED"); 15486 return REG_SET_CC_CHANGE_NOT_ALLOWED; 15487 } else if (wmi_status_code == WMI_REG_SET_CC_STATUS_NO_MEMORY) { 15488 wmi_nofl_debug("WMI_REG_SET_CC_STATUS_NO_MEMORY"); 15489 return REG_SET_CC_STATUS_NO_MEMORY; 15490 } else if (wmi_status_code == WMI_REG_SET_CC_STATUS_FAIL) { 15491 wmi_nofl_debug("WMI_REG_SET_CC_STATUS_FAIL"); 15492 return REG_SET_CC_STATUS_FAIL; 15493 } 15494 15495 wmi_debug("Unknown reg status code from WMI"); 15496 return REG_SET_CC_STATUS_FAIL; 15497 } 15498 15499 #ifdef CONFIG_BAND_6GHZ 15500 /** 15501 * reg_print_ap_power_type_6ghz - Prints the AP Power type 15502 * @ap_type: 6ghz-AP Power type 15503 * 15504 * Return: void 15505 */ 15506 static void reg_print_ap_power_type_6ghz(enum reg_6g_ap_type ap_type) 15507 { 15508 switch (ap_type) { 15509 case REG_INDOOR_AP: 15510 wmi_nofl_debug("AP Power type %s", "LOW POWER INDOOR"); 15511 break; 15512 case REG_STANDARD_POWER_AP: 15513 wmi_nofl_debug("AP Power type %s", "STANDARD POWER"); 15514 break; 15515 case REG_VERY_LOW_POWER_AP: 15516 wmi_nofl_debug("AP Power type %s", "VERY LOW POWER INDOOR"); 15517 break; 15518 default: 15519 wmi_nofl_debug("Invalid AP Power type %u", ap_type); 15520 } 15521 } 15522 15523 /** 15524 * reg_print_6ghz_client_type - Prints the client type 15525 * @client_type: 6ghz-client type 15526 * 15527 * Return: void 15528 */ 15529 static void reg_print_6ghz_client_type(enum reg_6g_client_type client_type) 15530 { 15531 switch (client_type) { 15532 case REG_DEFAULT_CLIENT: 15533 wmi_nofl_debug("Client type %s", "DEFAULT CLIENT"); 15534 break; 15535 case REG_SUBORDINATE_CLIENT: 15536 wmi_nofl_debug("Client type %s", "SUBORDINATE CLIENT"); 15537 break; 15538 default: 15539 wmi_nofl_debug("Invalid Client type %u", client_type); 15540 } 15541 } 15542 #else 15543 static inline void reg_print_ap_power_type_6ghz(enum reg_6g_ap_type ap_type) 15544 { 15545 } 15546 15547 static inline void reg_print_6ghz_client_type(enum reg_6g_client_type client_type) 15548 { 15549 } 15550 #endif /* CONFIG_BAND_6GHZ */ 15551 15552 #ifdef CONFIG_BAND_6GHZ 15553 15554 #ifdef CONFIG_REG_CLIENT 15555 #define MAX_NUM_FCC_RULES 2 15556 15557 /** 15558 * extract_ext_fcc_rules_from_wmi - extract fcc rules from WMI TLV 15559 * @num_fcc_rules: Number of FCC rules 15560 * @wmi_fcc_rule: WMI FCC rules TLV 15561 * 15562 * Return: fcc_rule_ptr 15563 */ 15564 static struct cur_fcc_rule 15565 *extract_ext_fcc_rules_from_wmi(uint32_t num_fcc_rules, 15566 wmi_regulatory_fcc_rule_struct *wmi_fcc_rule) 15567 { 15568 struct cur_fcc_rule *fcc_rule_ptr; 15569 uint32_t count; 15570 15571 if (!wmi_fcc_rule) 15572 return NULL; 15573 15574 fcc_rule_ptr = qdf_mem_malloc(num_fcc_rules * 15575 sizeof(*fcc_rule_ptr)); 15576 if (!fcc_rule_ptr) 15577 return NULL; 15578 15579 for (count = 0; count < num_fcc_rules; count++) { 15580 fcc_rule_ptr[count].center_freq = 15581 WMI_REG_FCC_RULE_CHAN_FREQ_GET( 15582 wmi_fcc_rule[count].freq_info); 15583 fcc_rule_ptr[count].tx_power = 15584 WMI_REG_FCC_RULE_FCC_TX_POWER_GET( 15585 wmi_fcc_rule[count].freq_info); 15586 } 15587 15588 return fcc_rule_ptr; 15589 } 15590 15591 /** 15592 * extract_reg_fcc_rules_tlv - Extract reg fcc rules TLV 15593 * @param_buf: Pointer to WMI params TLV 15594 * @ext_chan_list_event_hdr: Pointer to REG CHAN LIST CC EXT EVENT Fixed 15595 * Params TLV 15596 * @ext_wmi_reg_rule: Pointer to REG CHAN LIST CC EXT EVENT Reg Rules TLV 15597 * @ext_wmi_chan_priority: Pointer to REG CHAN LIST CC EXT EVENT Chan 15598 * Priority TLV 15599 * @evt_buf: Pointer to REG CHAN LIST CC EXT EVENT event buffer 15600 * @reg_info: Pointer to Regulatory Info 15601 * @len: Length of REG CHAN LIST CC EXT EVENT buffer 15602 * 15603 * Return: QDF_STATUS 15604 */ 15605 static QDF_STATUS extract_reg_fcc_rules_tlv( 15606 WMI_REG_CHAN_LIST_CC_EXT_EVENTID_param_tlvs *param_buf, 15607 wmi_reg_chan_list_cc_event_ext_fixed_param *ext_chan_list_event_hdr, 15608 wmi_regulatory_rule_ext_struct *ext_wmi_reg_rule, 15609 wmi_regulatory_chan_priority_struct *ext_wmi_chan_priority, 15610 uint8_t *evt_buf, 15611 struct cur_regulatory_info *reg_info, 15612 uint32_t len) 15613 { 15614 int i; 15615 wmi_regulatory_fcc_rule_struct *ext_wmi_fcc_rule; 15616 15617 if (!param_buf) { 15618 wmi_err("invalid channel list event buf"); 15619 return QDF_STATUS_E_INVAL; 15620 } 15621 15622 reg_info->num_fcc_rules = 0; 15623 if (param_buf->reg_fcc_rule) { 15624 if (param_buf->num_reg_fcc_rule > MAX_NUM_FCC_RULES) { 15625 wmi_err("Number of fcc rules is greater than MAX_NUM_FCC_RULES"); 15626 return QDF_STATUS_E_INVAL; 15627 } 15628 15629 ext_wmi_fcc_rule = 15630 (wmi_regulatory_fcc_rule_struct *) 15631 ((uint8_t *)ext_chan_list_event_hdr + 15632 sizeof(wmi_reg_chan_list_cc_event_ext_fixed_param) + 15633 WMI_TLV_HDR_SIZE + 15634 sizeof(wmi_regulatory_rule_ext_struct) * 15635 param_buf->num_reg_rule_array + 15636 WMI_TLV_HDR_SIZE + 15637 sizeof(wmi_regulatory_chan_priority_struct) * 15638 param_buf->num_reg_chan_priority + 15639 WMI_TLV_HDR_SIZE); 15640 15641 reg_info->fcc_rules_ptr = extract_ext_fcc_rules_from_wmi( 15642 param_buf->num_reg_fcc_rule, 15643 ext_wmi_fcc_rule); 15644 15645 reg_info->num_fcc_rules = param_buf->num_reg_fcc_rule; 15646 } else { 15647 wmi_err("Fcc rules not sent by fw"); 15648 } 15649 15650 if (reg_info->fcc_rules_ptr) { 15651 for (i = 0; i < reg_info->num_fcc_rules; i++) { 15652 wmi_nofl_debug("FCC rule %d center_freq %d tx_power %d", 15653 i, reg_info->fcc_rules_ptr[i].center_freq, 15654 reg_info->fcc_rules_ptr[i].tx_power); 15655 } 15656 } 15657 return QDF_STATUS_SUCCESS; 15658 } 15659 #else 15660 static QDF_STATUS extract_reg_fcc_rules_tlv( 15661 WMI_REG_CHAN_LIST_CC_EXT_EVENTID_param_tlvs *param_buf, 15662 wmi_reg_chan_list_cc_event_ext_fixed_param *ext_chan_list_event_hdr, 15663 wmi_regulatory_rule_ext_struct *ext_wmi_reg_rule, 15664 wmi_regulatory_chan_priority_struct *ext_wmi_chan_priority, 15665 uint8_t *evt_buf, 15666 struct cur_regulatory_info *reg_info, 15667 uint32_t len) 15668 { 15669 return QDF_STATUS_SUCCESS; 15670 } 15671 #endif 15672 15673 static QDF_STATUS extract_reg_chan_list_ext_update_event_tlv( 15674 wmi_unified_t wmi_handle, uint8_t *evt_buf, 15675 struct cur_regulatory_info *reg_info, uint32_t len) 15676 { 15677 uint32_t i, j, k; 15678 WMI_REG_CHAN_LIST_CC_EXT_EVENTID_param_tlvs *param_buf; 15679 wmi_reg_chan_list_cc_event_ext_fixed_param *ext_chan_list_event_hdr; 15680 wmi_regulatory_rule_ext_struct *ext_wmi_reg_rule; 15681 wmi_regulatory_chan_priority_struct *ext_wmi_chan_priority; 15682 uint32_t num_2g_reg_rules, num_5g_reg_rules; 15683 uint32_t num_6g_reg_rules_ap[REG_CURRENT_MAX_AP_TYPE]; 15684 uint32_t *num_6g_reg_rules_client[REG_CURRENT_MAX_AP_TYPE]; 15685 uint32_t total_reg_rules = 0; 15686 QDF_STATUS status; 15687 15688 param_buf = (WMI_REG_CHAN_LIST_CC_EXT_EVENTID_param_tlvs *)evt_buf; 15689 if (!param_buf) { 15690 wmi_err("invalid channel list event buf"); 15691 return QDF_STATUS_E_FAILURE; 15692 } 15693 15694 ext_chan_list_event_hdr = param_buf->fixed_param; 15695 ext_wmi_chan_priority = param_buf->reg_chan_priority; 15696 15697 if (ext_wmi_chan_priority) 15698 reg_info->reg_6g_thresh_priority_freq = 15699 WMI_GET_BITS(ext_wmi_chan_priority->freq_info, 0, 16); 15700 reg_info->num_2g_reg_rules = ext_chan_list_event_hdr->num_2g_reg_rules; 15701 reg_info->num_5g_reg_rules = ext_chan_list_event_hdr->num_5g_reg_rules; 15702 reg_info->num_6g_reg_rules_ap[REG_STANDARD_POWER_AP] = 15703 ext_chan_list_event_hdr->num_6g_reg_rules_ap_sp; 15704 reg_info->num_6g_reg_rules_ap[REG_INDOOR_AP] = 15705 ext_chan_list_event_hdr->num_6g_reg_rules_ap_lpi; 15706 reg_info->num_6g_reg_rules_ap[REG_VERY_LOW_POWER_AP] = 15707 ext_chan_list_event_hdr->num_6g_reg_rules_ap_vlp; 15708 15709 wmi_debug("num reg rules from fw, AP SP %d, LPI %d, VLP %d", 15710 reg_info->num_6g_reg_rules_ap[REG_STANDARD_POWER_AP], 15711 reg_info->num_6g_reg_rules_ap[REG_INDOOR_AP], 15712 reg_info->num_6g_reg_rules_ap[REG_VERY_LOW_POWER_AP]); 15713 15714 for (i = 0; i < REG_MAX_CLIENT_TYPE; i++) { 15715 reg_info->num_6g_reg_rules_client[REG_STANDARD_POWER_AP][i] = 15716 ext_chan_list_event_hdr->num_6g_reg_rules_client_sp[i]; 15717 reg_info->num_6g_reg_rules_client[REG_INDOOR_AP][i] = 15718 ext_chan_list_event_hdr->num_6g_reg_rules_client_lpi[i]; 15719 reg_info->num_6g_reg_rules_client[REG_VERY_LOW_POWER_AP][i] = 15720 ext_chan_list_event_hdr->num_6g_reg_rules_client_vlp[i]; 15721 wmi_nofl_debug("client %d SP %d, LPI %d, VLP %d", i, 15722 ext_chan_list_event_hdr->num_6g_reg_rules_client_sp[i], 15723 ext_chan_list_event_hdr->num_6g_reg_rules_client_lpi[i], 15724 ext_chan_list_event_hdr->num_6g_reg_rules_client_vlp[i]); 15725 } 15726 15727 num_2g_reg_rules = reg_info->num_2g_reg_rules; 15728 total_reg_rules += num_2g_reg_rules; 15729 num_5g_reg_rules = reg_info->num_5g_reg_rules; 15730 total_reg_rules += num_5g_reg_rules; 15731 for (i = 0; i < REG_CURRENT_MAX_AP_TYPE; i++) { 15732 num_6g_reg_rules_ap[i] = reg_info->num_6g_reg_rules_ap[i]; 15733 if (num_6g_reg_rules_ap[i] > MAX_6G_REG_RULES) { 15734 wmi_err_rl("Invalid num_6g_reg_rules_ap: %u", 15735 num_6g_reg_rules_ap[i]); 15736 return QDF_STATUS_E_FAILURE; 15737 } 15738 total_reg_rules += num_6g_reg_rules_ap[i]; 15739 num_6g_reg_rules_client[i] = 15740 reg_info->num_6g_reg_rules_client[i]; 15741 } 15742 15743 for (i = 0; i < REG_MAX_CLIENT_TYPE; i++) { 15744 total_reg_rules += 15745 num_6g_reg_rules_client[REG_STANDARD_POWER_AP][i]; 15746 total_reg_rules += num_6g_reg_rules_client[REG_INDOOR_AP][i]; 15747 total_reg_rules += 15748 num_6g_reg_rules_client[REG_VERY_LOW_POWER_AP][i]; 15749 if ((num_6g_reg_rules_client[REG_STANDARD_POWER_AP][i] > 15750 MAX_6G_REG_RULES) || 15751 (num_6g_reg_rules_client[REG_INDOOR_AP][i] > 15752 MAX_6G_REG_RULES) || 15753 (num_6g_reg_rules_client[REG_VERY_LOW_POWER_AP][i] > 15754 MAX_6G_REG_RULES)) { 15755 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", 15756 num_6g_reg_rules_client[REG_STANDARD_POWER_AP][i], 15757 num_6g_reg_rules_client[REG_INDOOR_AP][i], 15758 num_6g_reg_rules_client[REG_VERY_LOW_POWER_AP][i], 15759 i); 15760 return QDF_STATUS_E_FAILURE; 15761 } 15762 } 15763 15764 if (total_reg_rules != param_buf->num_reg_rule_array) { 15765 wmi_err_rl("Total reg rules %u does not match event params num reg rule %u", 15766 total_reg_rules, param_buf->num_reg_rule_array); 15767 return QDF_STATUS_E_FAILURE; 15768 } 15769 15770 if ((num_2g_reg_rules > MAX_REG_RULES) || 15771 (num_5g_reg_rules > MAX_REG_RULES)) { 15772 wmi_err_rl("Invalid num_2g_reg_rules: %u, num_5g_reg_rules: %u", 15773 num_2g_reg_rules, num_5g_reg_rules); 15774 return QDF_STATUS_E_FAILURE; 15775 } 15776 15777 if ((num_6g_reg_rules_ap[REG_STANDARD_POWER_AP] > MAX_6G_REG_RULES) || 15778 (num_6g_reg_rules_ap[REG_INDOOR_AP] > MAX_6G_REG_RULES) || 15779 (num_6g_reg_rules_ap[REG_VERY_LOW_POWER_AP] > MAX_6G_REG_RULES)) { 15780 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", 15781 num_6g_reg_rules_ap[REG_STANDARD_POWER_AP], 15782 num_6g_reg_rules_ap[REG_INDOOR_AP], 15783 num_6g_reg_rules_ap[REG_VERY_LOW_POWER_AP]); 15784 return QDF_STATUS_E_FAILURE; 15785 } 15786 15787 if (param_buf->num_reg_rule_array > 15788 (WMI_SVC_MSG_MAX_SIZE - sizeof(*ext_chan_list_event_hdr)) / 15789 sizeof(*ext_wmi_reg_rule)) { 15790 wmi_err_rl("Invalid ext_num_reg_rule_array: %u", 15791 param_buf->num_reg_rule_array); 15792 return QDF_STATUS_E_FAILURE; 15793 } 15794 15795 qdf_mem_copy(reg_info->alpha2, &ext_chan_list_event_hdr->alpha2, 15796 REG_ALPHA2_LEN); 15797 reg_info->dfs_region = ext_chan_list_event_hdr->dfs_region; 15798 reg_info->phybitmap = convert_phybitmap_tlv( 15799 ext_chan_list_event_hdr->phybitmap); 15800 reg_info->offload_enabled = true; 15801 reg_info->num_phy = ext_chan_list_event_hdr->num_phy; 15802 reg_info->phy_id = wmi_handle->ops->convert_phy_id_target_to_host( 15803 wmi_handle, ext_chan_list_event_hdr->phy_id); 15804 reg_info->ctry_code = ext_chan_list_event_hdr->country_id; 15805 reg_info->reg_dmn_pair = ext_chan_list_event_hdr->domain_code; 15806 15807 reg_info->status_code = 15808 wmi_reg_status_to_reg_status(ext_chan_list_event_hdr-> 15809 status_code); 15810 15811 reg_info->min_bw_2g = ext_chan_list_event_hdr->min_bw_2g; 15812 reg_info->max_bw_2g = ext_chan_list_event_hdr->max_bw_2g; 15813 reg_info->min_bw_5g = ext_chan_list_event_hdr->min_bw_5g; 15814 reg_info->max_bw_5g = ext_chan_list_event_hdr->max_bw_5g; 15815 reg_info->min_bw_6g_ap[REG_STANDARD_POWER_AP] = 15816 ext_chan_list_event_hdr->min_bw_6g_ap_sp; 15817 reg_info->max_bw_6g_ap[REG_STANDARD_POWER_AP] = 15818 ext_chan_list_event_hdr->max_bw_6g_ap_sp; 15819 reg_info->min_bw_6g_ap[REG_INDOOR_AP] = 15820 ext_chan_list_event_hdr->min_bw_6g_ap_lpi; 15821 reg_info->max_bw_6g_ap[REG_INDOOR_AP] = 15822 ext_chan_list_event_hdr->max_bw_6g_ap_lpi; 15823 reg_info->min_bw_6g_ap[REG_VERY_LOW_POWER_AP] = 15824 ext_chan_list_event_hdr->min_bw_6g_ap_vlp; 15825 reg_info->max_bw_6g_ap[REG_VERY_LOW_POWER_AP] = 15826 ext_chan_list_event_hdr->max_bw_6g_ap_vlp; 15827 15828 for (i = 0; i < REG_MAX_CLIENT_TYPE; i++) { 15829 reg_info->min_bw_6g_client[REG_STANDARD_POWER_AP][i] = 15830 ext_chan_list_event_hdr->min_bw_6g_client_sp[i]; 15831 reg_info->max_bw_6g_client[REG_STANDARD_POWER_AP][i] = 15832 ext_chan_list_event_hdr->max_bw_6g_client_sp[i]; 15833 reg_info->min_bw_6g_client[REG_INDOOR_AP][i] = 15834 ext_chan_list_event_hdr->min_bw_6g_client_lpi[i]; 15835 reg_info->max_bw_6g_client[REG_INDOOR_AP][i] = 15836 ext_chan_list_event_hdr->max_bw_6g_client_lpi[i]; 15837 reg_info->min_bw_6g_client[REG_VERY_LOW_POWER_AP][i] = 15838 ext_chan_list_event_hdr->min_bw_6g_client_vlp[i]; 15839 reg_info->max_bw_6g_client[REG_VERY_LOW_POWER_AP][i] = 15840 ext_chan_list_event_hdr->max_bw_6g_client_vlp[i]; 15841 } 15842 15843 wmi_nofl_debug("num_phys = %u and phy_id = %u", 15844 reg_info->num_phy, reg_info->phy_id); 15845 15846 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", 15847 reg_info->alpha2, reg_info->dfs_region, reg_info->reg_dmn_pair, 15848 reg_info->min_bw_2g, reg_info->max_bw_2g, reg_info->min_bw_5g, 15849 reg_info->max_bw_5g); 15850 15851 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", 15852 reg_info->min_bw_6g_ap[REG_STANDARD_POWER_AP], 15853 reg_info->max_bw_6g_ap[REG_STANDARD_POWER_AP], 15854 reg_info->min_bw_6g_ap[REG_INDOOR_AP], 15855 reg_info->max_bw_6g_ap[REG_INDOOR_AP], 15856 reg_info->min_bw_6g_ap[REG_VERY_LOW_POWER_AP], 15857 reg_info->max_bw_6g_ap[REG_VERY_LOW_POWER_AP]); 15858 15859 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", 15860 reg_info->min_bw_6g_client[REG_STANDARD_POWER_AP][REG_DEFAULT_CLIENT], 15861 reg_info->max_bw_6g_client[REG_STANDARD_POWER_AP][REG_DEFAULT_CLIENT], 15862 reg_info->min_bw_6g_client[REG_INDOOR_AP][REG_DEFAULT_CLIENT], 15863 reg_info->max_bw_6g_client[REG_INDOOR_AP][REG_DEFAULT_CLIENT], 15864 reg_info->min_bw_6g_client[REG_VERY_LOW_POWER_AP][REG_DEFAULT_CLIENT], 15865 reg_info->max_bw_6g_client[REG_VERY_LOW_POWER_AP][REG_DEFAULT_CLIENT]); 15866 15867 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", 15868 reg_info->min_bw_6g_client[REG_STANDARD_POWER_AP][REG_SUBORDINATE_CLIENT], 15869 reg_info->max_bw_6g_client[REG_STANDARD_POWER_AP][REG_SUBORDINATE_CLIENT], 15870 reg_info->min_bw_6g_client[REG_INDOOR_AP][REG_SUBORDINATE_CLIENT], 15871 reg_info->max_bw_6g_client[REG_INDOOR_AP][REG_SUBORDINATE_CLIENT], 15872 reg_info->min_bw_6g_client[REG_VERY_LOW_POWER_AP][REG_SUBORDINATE_CLIENT], 15873 reg_info->max_bw_6g_client[REG_VERY_LOW_POWER_AP][REG_SUBORDINATE_CLIENT]); 15874 15875 wmi_nofl_debug("num_2g_reg_rules %d num_5g_reg_rules %d", 15876 num_2g_reg_rules, num_5g_reg_rules); 15877 15878 wmi_nofl_debug("num_6g_ap_sp_reg_rules %d num_6g_ap_lpi_reg_rules %d num_6g_ap_vlp_reg_rules %d", 15879 reg_info->num_6g_reg_rules_ap[REG_STANDARD_POWER_AP], 15880 reg_info->num_6g_reg_rules_ap[REG_INDOOR_AP], 15881 reg_info->num_6g_reg_rules_ap[REG_VERY_LOW_POWER_AP]); 15882 15883 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", 15884 reg_info->num_6g_reg_rules_client[REG_STANDARD_POWER_AP][REG_DEFAULT_CLIENT], 15885 reg_info->num_6g_reg_rules_client[REG_INDOOR_AP][REG_DEFAULT_CLIENT], 15886 reg_info->num_6g_reg_rules_client[REG_VERY_LOW_POWER_AP][REG_DEFAULT_CLIENT]); 15887 15888 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", 15889 reg_info->num_6g_reg_rules_client[REG_STANDARD_POWER_AP][REG_SUBORDINATE_CLIENT], 15890 reg_info->num_6g_reg_rules_client[REG_INDOOR_AP][REG_SUBORDINATE_CLIENT], 15891 reg_info->num_6g_reg_rules_client[REG_VERY_LOW_POWER_AP][REG_SUBORDINATE_CLIENT]); 15892 15893 ext_wmi_reg_rule = 15894 (wmi_regulatory_rule_ext_struct *) 15895 ((uint8_t *)ext_chan_list_event_hdr + 15896 sizeof(wmi_reg_chan_list_cc_event_ext_fixed_param) + 15897 WMI_TLV_HDR_SIZE); 15898 reg_info->reg_rules_2g_ptr = 15899 create_ext_reg_rules_from_wmi(num_2g_reg_rules, 15900 ext_wmi_reg_rule); 15901 ext_wmi_reg_rule += num_2g_reg_rules; 15902 if (!num_2g_reg_rules) 15903 wmi_nofl_debug("No 2ghz reg rule"); 15904 for (i = 0; i < num_2g_reg_rules; i++) { 15905 if (!reg_info->reg_rules_2g_ptr) 15906 break; 15907 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", 15908 i, reg_info->reg_rules_2g_ptr[i].start_freq, 15909 reg_info->reg_rules_2g_ptr[i].end_freq, 15910 reg_info->reg_rules_2g_ptr[i].max_bw, 15911 reg_info->reg_rules_2g_ptr[i].reg_power, 15912 reg_info->reg_rules_2g_ptr[i].ant_gain, 15913 reg_info->reg_rules_2g_ptr[i].flags, 15914 reg_info->reg_rules_2g_ptr[i].psd_flag, 15915 reg_info->reg_rules_2g_ptr[i].psd_eirp); 15916 } 15917 reg_info->reg_rules_5g_ptr = 15918 create_ext_reg_rules_from_wmi(num_5g_reg_rules, 15919 ext_wmi_reg_rule); 15920 ext_wmi_reg_rule += num_5g_reg_rules; 15921 if (!num_5g_reg_rules) 15922 wmi_nofl_debug("No 5ghz reg rule"); 15923 for (i = 0; i < num_5g_reg_rules; i++) { 15924 if (!reg_info->reg_rules_5g_ptr) 15925 break; 15926 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", 15927 i, reg_info->reg_rules_5g_ptr[i].start_freq, 15928 reg_info->reg_rules_5g_ptr[i].end_freq, 15929 reg_info->reg_rules_5g_ptr[i].max_bw, 15930 reg_info->reg_rules_5g_ptr[i].reg_power, 15931 reg_info->reg_rules_5g_ptr[i].ant_gain, 15932 reg_info->reg_rules_5g_ptr[i].flags, 15933 reg_info->reg_rules_5g_ptr[i].psd_flag, 15934 reg_info->reg_rules_5g_ptr[i].psd_eirp); 15935 } 15936 15937 for (i = 0; i < REG_CURRENT_MAX_AP_TYPE; i++) { 15938 reg_print_ap_power_type_6ghz(i); 15939 reg_info->reg_rules_6g_ap_ptr[i] = 15940 create_ext_reg_rules_from_wmi(num_6g_reg_rules_ap[i], 15941 ext_wmi_reg_rule); 15942 15943 ext_wmi_reg_rule += num_6g_reg_rules_ap[i]; 15944 if (!num_6g_reg_rules_ap[i]) 15945 wmi_nofl_debug("No 6ghz reg rule"); 15946 for (j = 0; j < num_6g_reg_rules_ap[i]; j++) { 15947 if (!reg_info->reg_rules_6g_ap_ptr[i]) 15948 break; 15949 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", 15950 j, reg_info->reg_rules_6g_ap_ptr[i][j].start_freq, 15951 reg_info->reg_rules_6g_ap_ptr[i][j].end_freq, 15952 reg_info->reg_rules_6g_ap_ptr[i][j].max_bw, 15953 reg_info->reg_rules_6g_ap_ptr[i][j].reg_power, 15954 reg_info->reg_rules_6g_ap_ptr[i][j].ant_gain, 15955 reg_info->reg_rules_6g_ap_ptr[i][j].flags, 15956 reg_info->reg_rules_6g_ap_ptr[i][j].psd_flag, 15957 reg_info->reg_rules_6g_ap_ptr[i][j].psd_eirp); 15958 } 15959 } 15960 15961 for (j = 0; j < REG_CURRENT_MAX_AP_TYPE; j++) { 15962 reg_print_ap_power_type_6ghz(j); 15963 for (i = 0; i < REG_MAX_CLIENT_TYPE; i++) { 15964 reg_print_6ghz_client_type(i); 15965 reg_info->reg_rules_6g_client_ptr[j][i] = 15966 create_ext_reg_rules_from_wmi( 15967 num_6g_reg_rules_client[j][i], 15968 ext_wmi_reg_rule); 15969 15970 ext_wmi_reg_rule += num_6g_reg_rules_client[j][i]; 15971 if (!num_6g_reg_rules_client[j][i]) 15972 wmi_nofl_debug("No 6ghz reg rule for [%d][%d]", j, i); 15973 for (k = 0; k < num_6g_reg_rules_client[j][i]; k++) { 15974 if (!reg_info->reg_rules_6g_client_ptr[j][i]) 15975 break; 15976 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", 15977 k, reg_info->reg_rules_6g_client_ptr[j][i][k].start_freq, 15978 reg_info->reg_rules_6g_client_ptr[j][i][k].end_freq, 15979 reg_info->reg_rules_6g_client_ptr[j][i][k].max_bw, 15980 reg_info->reg_rules_6g_client_ptr[j][i][k].reg_power, 15981 reg_info->reg_rules_6g_client_ptr[j][i][k].ant_gain, 15982 reg_info->reg_rules_6g_client_ptr[j][i][k].flags, 15983 reg_info->reg_rules_6g_client_ptr[j][i][k].psd_flag, 15984 reg_info->reg_rules_6g_client_ptr[j][i][k].psd_eirp); 15985 } 15986 } 15987 } 15988 15989 reg_info->client_type = ext_chan_list_event_hdr->client_type; 15990 reg_info->rnr_tpe_usable = ext_chan_list_event_hdr->rnr_tpe_usable; 15991 reg_info->unspecified_ap_usable = 15992 ext_chan_list_event_hdr->unspecified_ap_usable; 15993 reg_info->domain_code_6g_ap[REG_STANDARD_POWER_AP] = 15994 ext_chan_list_event_hdr->domain_code_6g_ap_sp; 15995 reg_info->domain_code_6g_ap[REG_INDOOR_AP] = 15996 ext_chan_list_event_hdr->domain_code_6g_ap_lpi; 15997 reg_info->domain_code_6g_ap[REG_VERY_LOW_POWER_AP] = 15998 ext_chan_list_event_hdr->domain_code_6g_ap_vlp; 15999 16000 wmi_nofl_debug("client type %d, RNR TPE usable %d, unspecified AP usable %d, domain code AP SP %d, LPI %d, VLP %d", 16001 reg_info->client_type, reg_info->rnr_tpe_usable, 16002 reg_info->unspecified_ap_usable, 16003 reg_info->domain_code_6g_ap[REG_STANDARD_POWER_AP], 16004 reg_info->domain_code_6g_ap[REG_INDOOR_AP], 16005 reg_info->domain_code_6g_ap[REG_VERY_LOW_POWER_AP]); 16006 16007 for (i = 0; i < REG_MAX_CLIENT_TYPE; i++) { 16008 reg_info->domain_code_6g_client[REG_STANDARD_POWER_AP][i] = 16009 ext_chan_list_event_hdr->domain_code_6g_client_sp[i]; 16010 reg_info->domain_code_6g_client[REG_INDOOR_AP][i] = 16011 ext_chan_list_event_hdr->domain_code_6g_client_lpi[i]; 16012 reg_info->domain_code_6g_client[REG_VERY_LOW_POWER_AP][i] = 16013 ext_chan_list_event_hdr->domain_code_6g_client_vlp[i]; 16014 wmi_nofl_debug("domain code client %d SP %d, LPI %d, VLP %d", i, 16015 reg_info->domain_code_6g_client[REG_STANDARD_POWER_AP][i], 16016 reg_info->domain_code_6g_client[REG_INDOOR_AP][i], 16017 reg_info->domain_code_6g_client[REG_VERY_LOW_POWER_AP][i]); 16018 } 16019 16020 reg_info->domain_code_6g_super_id = 16021 ext_chan_list_event_hdr->domain_code_6g_super_id; 16022 16023 status = extract_reg_fcc_rules_tlv(param_buf, ext_chan_list_event_hdr, 16024 ext_wmi_reg_rule, ext_wmi_chan_priority, 16025 evt_buf, reg_info, len); 16026 if (status != QDF_STATUS_SUCCESS) 16027 return status; 16028 16029 return QDF_STATUS_SUCCESS; 16030 } 16031 16032 #ifdef CONFIG_AFC_SUPPORT 16033 /** 16034 * copy_afc_chan_eirp_info() - Copy the channel EIRP object from 16035 * chan_eirp_power_info_hdr to the internal buffer chan_eirp_info. Since the 16036 * cfi and eirp is continuously filled in chan_eirp_power_info_hdr, there is 16037 * an index pointer required to store the current index of 16038 * chan_eirp_power_info_hdr, to fill into the chan_eirp_info object. 16039 * @chan_eirp_info: pointer to chan_eirp_info 16040 * @num_chans: Number of channels 16041 * @chan_eirp_power_info_hdr: Pointer to chan_eirp_power_info_hdr 16042 * @index: Pointer to index 16043 * 16044 * Return: void 16045 */ 16046 static void 16047 copy_afc_chan_eirp_info(struct chan_eirp_obj *chan_eirp_info, 16048 uint8_t num_chans, 16049 wmi_afc_chan_eirp_power_info *chan_eirp_power_info_hdr, 16050 uint8_t *index) 16051 { 16052 uint8_t chan_idx; 16053 16054 for (chan_idx = 0; chan_idx < num_chans; chan_idx++, (*index)++) { 16055 chan_eirp_info[chan_idx].cfi = 16056 chan_eirp_power_info_hdr[*index].channel_cfi; 16057 chan_eirp_info[chan_idx].eirp_power = 16058 chan_eirp_power_info_hdr[*index].eirp_pwr; 16059 wmi_debug("Chan idx = %d chan freq idx = %d EIRP power = %d", 16060 chan_idx, 16061 chan_eirp_info[chan_idx].cfi, 16062 chan_eirp_info[chan_idx].eirp_power); 16063 } 16064 } 16065 16066 /** 16067 * copy_afc_chan_obj_info() - Copy the channel object from channel_info_hdr to 16068 * to the internal buffer afc_chan_info. 16069 * @afc_chan_info: pointer to afc_chan_info 16070 * @num_chan_objs: Number of channel objects 16071 * @channel_info_hdr: Pointer to channel_info_hdr 16072 * @chan_eirp_power_info_hdr: Pointer to chan_eirp_power_info_hdr 16073 * 16074 * Return: void 16075 */ 16076 static void 16077 copy_afc_chan_obj_info(struct afc_chan_obj *afc_chan_info, 16078 uint8_t num_chan_objs, 16079 wmi_6g_afc_channel_info *channel_info_hdr, 16080 wmi_afc_chan_eirp_power_info *chan_eirp_power_info_hdr) 16081 { 16082 uint8_t count; 16083 uint8_t src_pwr_index = 0; 16084 16085 for (count = 0; count < num_chan_objs; count++) { 16086 afc_chan_info[count].global_opclass = 16087 channel_info_hdr[count].global_operating_class; 16088 afc_chan_info[count].num_chans = 16089 channel_info_hdr[count].num_channels; 16090 wmi_debug("Chan object count = %d global opclasss = %d", 16091 count, 16092 afc_chan_info[count].global_opclass); 16093 wmi_debug("Number of Channel EIRP objects = %d", 16094 afc_chan_info[count].num_chans); 16095 16096 if (afc_chan_info[count].num_chans > 0) { 16097 struct chan_eirp_obj *chan_eirp_info; 16098 16099 chan_eirp_info = 16100 qdf_mem_malloc(afc_chan_info[count].num_chans * 16101 sizeof(*chan_eirp_info)); 16102 16103 if (!chan_eirp_info) 16104 return; 16105 16106 copy_afc_chan_eirp_info(chan_eirp_info, 16107 afc_chan_info[count].num_chans, 16108 chan_eirp_power_info_hdr, 16109 &src_pwr_index); 16110 afc_chan_info[count].chan_eirp_info = chan_eirp_info; 16111 } else { 16112 wmi_err("Number of channels is zero in object idx %d", 16113 count); 16114 } 16115 } 16116 } 16117 16118 static void copy_afc_freq_obj_info(struct afc_freq_obj *afc_freq_info, 16119 uint8_t num_freq_objs, 16120 wmi_6g_afc_frequency_info *freq_info_hdr) 16121 { 16122 uint8_t count; 16123 16124 for (count = 0; count < num_freq_objs; count++) { 16125 afc_freq_info[count].low_freq = 16126 WMI_REG_RULE_START_FREQ_GET(freq_info_hdr[count].freq_info); 16127 afc_freq_info[count].high_freq = 16128 WMI_REG_RULE_END_FREQ_GET(freq_info_hdr[count].freq_info); 16129 afc_freq_info[count].max_psd = 16130 freq_info_hdr[count].psd_power_info; 16131 wmi_debug("count = %d low_freq = %d high_freq = %d max_psd = %d", 16132 count, 16133 afc_freq_info[count].low_freq, 16134 afc_freq_info[count].high_freq, 16135 afc_freq_info[count].max_psd); 16136 } 16137 } 16138 16139 /** 16140 * copy_afc_event_fixed_hdr_power_info() - Copy the fixed header portion of 16141 * the power event info from the WMI AFC event buffer to the internal buffer 16142 * power_info. 16143 * @power_info: pointer to power_info 16144 * @afc_power_event_hdr: pointer to afc_power_event_hdr 16145 * 16146 * Return: void 16147 */ 16148 static void 16149 copy_afc_event_fixed_hdr_power_info( 16150 struct reg_fw_afc_power_event *power_info, 16151 wmi_afc_power_event_param *afc_power_event_hdr) 16152 { 16153 power_info->fw_status_code = afc_power_event_hdr->fw_status_code; 16154 power_info->resp_id = afc_power_event_hdr->resp_id; 16155 power_info->serv_resp_code = afc_power_event_hdr->afc_serv_resp_code; 16156 power_info->afc_wfa_version = 16157 WMI_AFC_WFA_MINOR_VERSION_GET(afc_power_event_hdr->afc_wfa_version); 16158 power_info->afc_wfa_version |= 16159 WMI_AFC_WFA_MAJOR_VERSION_GET(afc_power_event_hdr->afc_wfa_version); 16160 16161 power_info->avail_exp_time_d = 16162 WMI_AVAIL_EXPIRY_TIME_DAY_GET(afc_power_event_hdr->avail_exp_time_d); 16163 power_info->avail_exp_time_d |= 16164 WMI_AVAIL_EXPIRY_TIME_MONTH_GET(afc_power_event_hdr->avail_exp_time_d); 16165 power_info->avail_exp_time_d |= 16166 WMI_AVAIL_EXPIRY_TIME_YEAR_GET(afc_power_event_hdr->avail_exp_time_d); 16167 16168 power_info->avail_exp_time_t = 16169 WMI_AVAIL_EXPIRY_TIME_SEC_GET(afc_power_event_hdr->avail_exp_time_t); 16170 power_info->avail_exp_time_t |= 16171 WMI_AVAIL_EXPIRY_TIME_MINUTE_GET(afc_power_event_hdr->avail_exp_time_t); 16172 power_info->avail_exp_time_t |= 16173 WMI_AVAIL_EXPIRY_TIME_HOUR_GET(afc_power_event_hdr->avail_exp_time_t); 16174 wmi_debug("FW status = %d resp_id = %d serv_resp_code = %d", 16175 power_info->fw_status_code, 16176 power_info->resp_id, 16177 power_info->serv_resp_code); 16178 wmi_debug("AFC version = %u exp_date = %u exp_time = %u", 16179 power_info->afc_wfa_version, 16180 power_info->avail_exp_time_d, 16181 power_info->avail_exp_time_t); 16182 } 16183 16184 /** 16185 * copy_power_event() - Copy the power event parameters from the AFC event 16186 * buffer to the power_info within the afc_info. 16187 * @afc_info: pointer to afc_info 16188 * @param_buf: pointer to param_buf 16189 * 16190 * Return: void 16191 */ 16192 static void copy_power_event(struct afc_regulatory_info *afc_info, 16193 WMI_AFC_EVENTID_param_tlvs *param_buf) 16194 { 16195 struct reg_fw_afc_power_event *power_info; 16196 wmi_afc_power_event_param *afc_power_event_hdr; 16197 struct afc_freq_obj *afc_freq_info; 16198 16199 power_info = qdf_mem_malloc(sizeof(*power_info)); 16200 16201 if (!power_info) 16202 return; 16203 16204 afc_power_event_hdr = param_buf->afc_power_event_param; 16205 copy_afc_event_fixed_hdr_power_info(power_info, afc_power_event_hdr); 16206 afc_info->power_info = power_info; 16207 16208 power_info->num_freq_objs = param_buf->num_freq_info_array; 16209 wmi_debug("Number of frequency objects = %d", 16210 power_info->num_freq_objs); 16211 if (power_info->num_freq_objs > 0) { 16212 wmi_6g_afc_frequency_info *freq_info_hdr; 16213 16214 freq_info_hdr = param_buf->freq_info_array; 16215 afc_freq_info = qdf_mem_malloc(power_info->num_freq_objs * 16216 sizeof(*afc_freq_info)); 16217 16218 if (!afc_freq_info) 16219 return; 16220 16221 copy_afc_freq_obj_info(afc_freq_info, power_info->num_freq_objs, 16222 freq_info_hdr); 16223 power_info->afc_freq_info = afc_freq_info; 16224 } else { 16225 wmi_err("Number of frequency objects is zero"); 16226 } 16227 16228 power_info->num_chan_objs = param_buf->num_channel_info_array; 16229 wmi_debug("Number of channel objects = %d", power_info->num_chan_objs); 16230 if (power_info->num_chan_objs > 0) { 16231 struct afc_chan_obj *afc_chan_info; 16232 wmi_6g_afc_channel_info *channel_info_hdr; 16233 16234 channel_info_hdr = param_buf->channel_info_array; 16235 afc_chan_info = qdf_mem_malloc(power_info->num_chan_objs * 16236 sizeof(*afc_chan_info)); 16237 16238 if (!afc_chan_info) 16239 return; 16240 16241 copy_afc_chan_obj_info(afc_chan_info, 16242 power_info->num_chan_objs, 16243 channel_info_hdr, 16244 param_buf->chan_eirp_power_info_array); 16245 power_info->afc_chan_info = afc_chan_info; 16246 } else { 16247 wmi_err("Number of channel objects is zero"); 16248 } 16249 } 16250 16251 static void copy_expiry_event(struct afc_regulatory_info *afc_info, 16252 WMI_AFC_EVENTID_param_tlvs *param_buf) 16253 { 16254 struct reg_afc_expiry_event *expiry_info; 16255 16256 expiry_info = qdf_mem_malloc(sizeof(*expiry_info)); 16257 16258 if (!expiry_info) 16259 return; 16260 16261 expiry_info->request_id = 16262 param_buf->expiry_event_param->request_id; 16263 expiry_info->event_subtype = 16264 param_buf->expiry_event_param->event_subtype; 16265 wmi_debug("Event subtype %d request ID %d", 16266 expiry_info->event_subtype, 16267 expiry_info->request_id); 16268 afc_info->expiry_info = expiry_info; 16269 } 16270 16271 /** 16272 * copy_afc_event_common_info() - Copy the phy_id and event_type parameters 16273 * in the AFC event. 'Common' indicates that these parameters are common for 16274 * WMI_AFC_EVENT_POWER_INFO and WMI_AFC_EVENT_TIMER_EXPIRY. 16275 * @wmi_handle: wmi handle 16276 * @afc_info: pointer to afc_info 16277 * @event_fixed_hdr: pointer to event_fixed_hdr 16278 * 16279 * Return: void 16280 */ 16281 static void 16282 copy_afc_event_common_info(wmi_unified_t wmi_handle, 16283 struct afc_regulatory_info *afc_info, 16284 wmi_afc_event_fixed_param *event_fixed_hdr) 16285 { 16286 afc_info->phy_id = wmi_handle->ops->convert_phy_id_target_to_host( 16287 wmi_handle, event_fixed_hdr->phy_id); 16288 wmi_debug("phy_id %d", afc_info->phy_id); 16289 afc_info->event_type = event_fixed_hdr->event_type; 16290 } 16291 16292 static QDF_STATUS extract_afc_event_tlv(wmi_unified_t wmi_handle, 16293 uint8_t *evt_buf, 16294 struct afc_regulatory_info *afc_info, 16295 uint32_t len) 16296 { 16297 WMI_AFC_EVENTID_param_tlvs *param_buf; 16298 wmi_afc_event_fixed_param *event_fixed_hdr; 16299 16300 param_buf = (WMI_AFC_EVENTID_param_tlvs *)evt_buf; 16301 if (!param_buf) { 16302 wmi_err("Invalid AFC event buf"); 16303 return QDF_STATUS_E_FAILURE; 16304 } 16305 16306 event_fixed_hdr = param_buf->fixed_param; 16307 copy_afc_event_common_info(wmi_handle, afc_info, event_fixed_hdr); 16308 wmi_debug("AFC event type %d received", afc_info->event_type); 16309 16310 switch (afc_info->event_type) { 16311 case WMI_AFC_EVENT_POWER_INFO: 16312 copy_power_event(afc_info, param_buf); 16313 break; 16314 case WMI_AFC_EVENT_TIMER_EXPIRY: 16315 copy_expiry_event(afc_info, param_buf); 16316 return QDF_STATUS_SUCCESS; 16317 default: 16318 wmi_err("Invalid event type"); 16319 return QDF_STATUS_E_FAILURE; 16320 } 16321 16322 return QDF_STATUS_SUCCESS; 16323 } 16324 #endif 16325 #endif 16326 16327 static QDF_STATUS extract_reg_chan_list_update_event_tlv( 16328 wmi_unified_t wmi_handle, uint8_t *evt_buf, 16329 struct cur_regulatory_info *reg_info, uint32_t len) 16330 { 16331 uint32_t i; 16332 WMI_REG_CHAN_LIST_CC_EVENTID_param_tlvs *param_buf; 16333 wmi_reg_chan_list_cc_event_fixed_param *chan_list_event_hdr; 16334 wmi_regulatory_rule_struct *wmi_reg_rule; 16335 uint32_t num_2g_reg_rules, num_5g_reg_rules; 16336 16337 wmi_debug("processing regulatory channel list"); 16338 16339 param_buf = (WMI_REG_CHAN_LIST_CC_EVENTID_param_tlvs *)evt_buf; 16340 if (!param_buf) { 16341 wmi_err("invalid channel list event buf"); 16342 return QDF_STATUS_E_FAILURE; 16343 } 16344 16345 chan_list_event_hdr = param_buf->fixed_param; 16346 16347 reg_info->num_2g_reg_rules = chan_list_event_hdr->num_2g_reg_rules; 16348 reg_info->num_5g_reg_rules = chan_list_event_hdr->num_5g_reg_rules; 16349 num_2g_reg_rules = reg_info->num_2g_reg_rules; 16350 num_5g_reg_rules = reg_info->num_5g_reg_rules; 16351 if ((num_2g_reg_rules > MAX_REG_RULES) || 16352 (num_5g_reg_rules > MAX_REG_RULES) || 16353 (num_2g_reg_rules + num_5g_reg_rules > MAX_REG_RULES) || 16354 (num_2g_reg_rules + num_5g_reg_rules != 16355 param_buf->num_reg_rule_array)) { 16356 wmi_err_rl("Invalid num_2g_reg_rules: %u, num_5g_reg_rules: %u", 16357 num_2g_reg_rules, num_5g_reg_rules); 16358 return QDF_STATUS_E_FAILURE; 16359 } 16360 if (param_buf->num_reg_rule_array > 16361 (WMI_SVC_MSG_MAX_SIZE - sizeof(*chan_list_event_hdr)) / 16362 sizeof(*wmi_reg_rule)) { 16363 wmi_err_rl("Invalid num_reg_rule_array: %u", 16364 param_buf->num_reg_rule_array); 16365 return QDF_STATUS_E_FAILURE; 16366 } 16367 16368 qdf_mem_copy(reg_info->alpha2, &(chan_list_event_hdr->alpha2), 16369 REG_ALPHA2_LEN); 16370 reg_info->dfs_region = chan_list_event_hdr->dfs_region; 16371 reg_info->phybitmap = convert_phybitmap_tlv( 16372 chan_list_event_hdr->phybitmap); 16373 reg_info->offload_enabled = true; 16374 reg_info->num_phy = chan_list_event_hdr->num_phy; 16375 reg_info->phy_id = wmi_handle->ops->convert_phy_id_target_to_host( 16376 wmi_handle, chan_list_event_hdr->phy_id); 16377 reg_info->ctry_code = chan_list_event_hdr->country_id; 16378 reg_info->reg_dmn_pair = chan_list_event_hdr->domain_code; 16379 16380 reg_info->status_code = 16381 wmi_reg_status_to_reg_status(chan_list_event_hdr->status_code); 16382 16383 reg_info->min_bw_2g = chan_list_event_hdr->min_bw_2g; 16384 reg_info->max_bw_2g = chan_list_event_hdr->max_bw_2g; 16385 reg_info->min_bw_5g = chan_list_event_hdr->min_bw_5g; 16386 reg_info->max_bw_5g = chan_list_event_hdr->max_bw_5g; 16387 16388 wmi_debug("num_phys = %u and phy_id = %u", 16389 reg_info->num_phy, reg_info->phy_id); 16390 16391 wmi_debug("cc %s dfs_region %d reg_dmn_pair %x BW: min_2g %d max_2g %d min_5g %d max_5g %d", 16392 reg_info->alpha2, reg_info->dfs_region, reg_info->reg_dmn_pair, 16393 reg_info->min_bw_2g, reg_info->max_bw_2g, 16394 reg_info->min_bw_5g, reg_info->max_bw_5g); 16395 16396 wmi_debug("num_2g_reg_rules %d num_5g_reg_rules %d", 16397 num_2g_reg_rules, num_5g_reg_rules); 16398 wmi_reg_rule = 16399 (wmi_regulatory_rule_struct *)((uint8_t *)chan_list_event_hdr 16400 + sizeof(wmi_reg_chan_list_cc_event_fixed_param) 16401 + WMI_TLV_HDR_SIZE); 16402 reg_info->reg_rules_2g_ptr = create_reg_rules_from_wmi(num_2g_reg_rules, 16403 wmi_reg_rule); 16404 wmi_reg_rule += num_2g_reg_rules; 16405 if (!num_2g_reg_rules) 16406 wmi_nofl_debug("No 2ghz reg rule"); 16407 for (i = 0; i < num_2g_reg_rules; i++) { 16408 if (!reg_info->reg_rules_2g_ptr) 16409 break; 16410 wmi_nofl_debug("2 GHz rule %u start freq %u end freq %u max_bw %u reg_power %u ant_gain %u flags %u", 16411 i, reg_info->reg_rules_2g_ptr[i].start_freq, 16412 reg_info->reg_rules_2g_ptr[i].end_freq, 16413 reg_info->reg_rules_2g_ptr[i].max_bw, 16414 reg_info->reg_rules_2g_ptr[i].reg_power, 16415 reg_info->reg_rules_2g_ptr[i].ant_gain, 16416 reg_info->reg_rules_2g_ptr[i].flags); 16417 } 16418 16419 reg_info->reg_rules_5g_ptr = create_reg_rules_from_wmi(num_5g_reg_rules, 16420 wmi_reg_rule); 16421 if (!num_5g_reg_rules) 16422 wmi_nofl_debug("No 5ghz reg rule"); 16423 for (i = 0; i < num_5g_reg_rules; i++) { 16424 if (!reg_info->reg_rules_5g_ptr) 16425 break; 16426 wmi_nofl_debug("5 GHz rule %u start freq %u end freq %u max_bw %u reg_power %u ant_gain %u flags %u", 16427 i, reg_info->reg_rules_5g_ptr[i].start_freq, 16428 reg_info->reg_rules_5g_ptr[i].end_freq, 16429 reg_info->reg_rules_5g_ptr[i].max_bw, 16430 reg_info->reg_rules_5g_ptr[i].reg_power, 16431 reg_info->reg_rules_5g_ptr[i].ant_gain, 16432 reg_info->reg_rules_5g_ptr[i].flags); 16433 } 16434 16435 wmi_debug("processed regulatory channel list"); 16436 16437 return QDF_STATUS_SUCCESS; 16438 } 16439 16440 static QDF_STATUS extract_reg_11d_new_country_event_tlv( 16441 wmi_unified_t wmi_handle, uint8_t *evt_buf, 16442 struct reg_11d_new_country *reg_11d_country, uint32_t len) 16443 { 16444 wmi_11d_new_country_event_fixed_param *reg_11d_country_event; 16445 WMI_11D_NEW_COUNTRY_EVENTID_param_tlvs *param_buf; 16446 16447 param_buf = (WMI_11D_NEW_COUNTRY_EVENTID_param_tlvs *)evt_buf; 16448 if (!param_buf) { 16449 wmi_err("invalid 11d country event buf"); 16450 return QDF_STATUS_E_FAILURE; 16451 } 16452 16453 reg_11d_country_event = param_buf->fixed_param; 16454 16455 qdf_mem_copy(reg_11d_country->alpha2, 16456 ®_11d_country_event->new_alpha2, REG_ALPHA2_LEN); 16457 reg_11d_country->alpha2[REG_ALPHA2_LEN] = '\0'; 16458 16459 wmi_debug("processed 11d country event, new cc %s", 16460 reg_11d_country->alpha2); 16461 16462 return QDF_STATUS_SUCCESS; 16463 } 16464 16465 static QDF_STATUS extract_reg_ch_avoid_event_tlv( 16466 wmi_unified_t wmi_handle, uint8_t *evt_buf, 16467 struct ch_avoid_ind_type *ch_avoid_ind, uint32_t len) 16468 { 16469 wmi_avoid_freq_ranges_event_fixed_param *afr_fixed_param; 16470 wmi_avoid_freq_range_desc *afr_desc; 16471 uint32_t num_freq_ranges, freq_range_idx; 16472 WMI_WLAN_FREQ_AVOID_EVENTID_param_tlvs *param_buf = 16473 (WMI_WLAN_FREQ_AVOID_EVENTID_param_tlvs *) evt_buf; 16474 16475 if (!param_buf) { 16476 wmi_err("Invalid channel avoid event buffer"); 16477 return QDF_STATUS_E_INVAL; 16478 } 16479 16480 afr_fixed_param = param_buf->fixed_param; 16481 if (!afr_fixed_param) { 16482 wmi_err("Invalid channel avoid event fixed param buffer"); 16483 return QDF_STATUS_E_INVAL; 16484 } 16485 16486 if (!ch_avoid_ind) { 16487 wmi_err("Invalid channel avoid indication buffer"); 16488 return QDF_STATUS_E_INVAL; 16489 } 16490 if (param_buf->num_avd_freq_range < afr_fixed_param->num_freq_ranges) { 16491 wmi_err("no.of freq ranges exceeded the limit"); 16492 return QDF_STATUS_E_INVAL; 16493 } 16494 num_freq_ranges = (afr_fixed_param->num_freq_ranges > 16495 CH_AVOID_MAX_RANGE) ? CH_AVOID_MAX_RANGE : 16496 afr_fixed_param->num_freq_ranges; 16497 16498 wmi_debug("Channel avoid event received with %d ranges", 16499 num_freq_ranges); 16500 16501 ch_avoid_ind->ch_avoid_range_cnt = num_freq_ranges; 16502 afr_desc = (wmi_avoid_freq_range_desc *)(param_buf->avd_freq_range); 16503 for (freq_range_idx = 0; freq_range_idx < num_freq_ranges; 16504 freq_range_idx++) { 16505 ch_avoid_ind->avoid_freq_range[freq_range_idx].start_freq = 16506 afr_desc->start_freq; 16507 ch_avoid_ind->avoid_freq_range[freq_range_idx].end_freq = 16508 afr_desc->end_freq; 16509 wmi_debug("range %d tlv id %u, start freq %u, end freq %u", 16510 freq_range_idx, afr_desc->tlv_header, 16511 afr_desc->start_freq, afr_desc->end_freq); 16512 afr_desc++; 16513 } 16514 16515 return QDF_STATUS_SUCCESS; 16516 } 16517 16518 #ifdef DFS_COMPONENT_ENABLE 16519 /** 16520 * extract_dfs_cac_complete_event_tlv() - extract cac complete event 16521 * @wmi_handle: wma handle 16522 * @evt_buf: event buffer 16523 * @vdev_id: vdev id 16524 * @len: length of buffer 16525 * 16526 * Return: QDF_STATUS_SUCCESS for success or error code 16527 */ 16528 static QDF_STATUS extract_dfs_cac_complete_event_tlv(wmi_unified_t wmi_handle, 16529 uint8_t *evt_buf, 16530 uint32_t *vdev_id, 16531 uint32_t len) 16532 { 16533 WMI_VDEV_DFS_CAC_COMPLETE_EVENTID_param_tlvs *param_tlvs; 16534 wmi_vdev_dfs_cac_complete_event_fixed_param *cac_event; 16535 16536 param_tlvs = (WMI_VDEV_DFS_CAC_COMPLETE_EVENTID_param_tlvs *) evt_buf; 16537 if (!param_tlvs) { 16538 wmi_err("invalid cac complete event buf"); 16539 return QDF_STATUS_E_FAILURE; 16540 } 16541 16542 cac_event = param_tlvs->fixed_param; 16543 *vdev_id = cac_event->vdev_id; 16544 wmi_debug("processed cac complete event vdev %d", *vdev_id); 16545 16546 return QDF_STATUS_SUCCESS; 16547 } 16548 16549 /** 16550 * extract_dfs_ocac_complete_event_tlv() - extract cac complete event 16551 * @wmi_handle: wma handle 16552 * @evt_buf: event buffer 16553 * @param: extracted event 16554 * 16555 * Return: QDF_STATUS_SUCCESS for success or error code 16556 */ 16557 static QDF_STATUS 16558 extract_dfs_ocac_complete_event_tlv(wmi_unified_t wmi_handle, 16559 uint8_t *evt_buf, 16560 struct vdev_adfs_complete_status *param) 16561 { 16562 WMI_VDEV_ADFS_OCAC_COMPLETE_EVENTID_param_tlvs *param_tlvs; 16563 wmi_vdev_adfs_ocac_complete_event_fixed_param *ocac_complete_status; 16564 16565 param_tlvs = (WMI_VDEV_ADFS_OCAC_COMPLETE_EVENTID_param_tlvs *)evt_buf; 16566 if (!param_tlvs) { 16567 wmi_err("invalid ocac complete event buf"); 16568 return QDF_STATUS_E_FAILURE; 16569 } 16570 16571 if (!param_tlvs->fixed_param) { 16572 wmi_err("invalid param_tlvs->fixed_param"); 16573 return QDF_STATUS_E_FAILURE; 16574 } 16575 16576 ocac_complete_status = param_tlvs->fixed_param; 16577 param->vdev_id = ocac_complete_status->vdev_id; 16578 param->chan_freq = ocac_complete_status->chan_freq; 16579 param->center_freq1 = ocac_complete_status->center_freq1; 16580 param->center_freq2 = ocac_complete_status->center_freq2; 16581 param->ocac_status = ocac_complete_status->status; 16582 param->chan_width = ocac_complete_status->chan_width; 16583 wmi_debug("processed ocac complete event vdev %d" 16584 " agile chan %d %d width %d status %d", 16585 param->vdev_id, 16586 param->center_freq1, 16587 param->center_freq2, 16588 param->chan_width, 16589 param->ocac_status); 16590 16591 return QDF_STATUS_SUCCESS; 16592 } 16593 16594 /** 16595 * extract_dfs_radar_detection_event_tlv() - extract radar found event 16596 * @wmi_handle: wma handle 16597 * @evt_buf: event buffer 16598 * @radar_found: radar found event info 16599 * @len: length of buffer 16600 * 16601 * Return: QDF_STATUS_SUCCESS for success or error code 16602 */ 16603 static QDF_STATUS extract_dfs_radar_detection_event_tlv( 16604 wmi_unified_t wmi_handle, 16605 uint8_t *evt_buf, 16606 struct radar_found_info *radar_found, 16607 uint32_t len) 16608 { 16609 WMI_PDEV_DFS_RADAR_DETECTION_EVENTID_param_tlvs *param_tlv; 16610 wmi_pdev_dfs_radar_detection_event_fixed_param *radar_event; 16611 16612 param_tlv = (WMI_PDEV_DFS_RADAR_DETECTION_EVENTID_param_tlvs *) evt_buf; 16613 if (!param_tlv) { 16614 wmi_err("invalid radar detection event buf"); 16615 return QDF_STATUS_E_FAILURE; 16616 } 16617 16618 radar_event = param_tlv->fixed_param; 16619 16620 radar_found->pdev_id = convert_target_pdev_id_to_host_pdev_id( 16621 wmi_handle, 16622 radar_event->pdev_id); 16623 16624 if (radar_found->pdev_id == WMI_HOST_PDEV_ID_INVALID) 16625 return QDF_STATUS_E_FAILURE; 16626 16627 radar_found->detection_mode = radar_event->detection_mode; 16628 radar_found->chan_freq = radar_event->chan_freq; 16629 radar_found->chan_width = radar_event->chan_width; 16630 radar_found->detector_id = radar_event->detector_id; 16631 radar_found->segment_id = radar_event->segment_id; 16632 radar_found->timestamp = radar_event->timestamp; 16633 radar_found->is_chirp = radar_event->is_chirp; 16634 radar_found->freq_offset = radar_event->freq_offset; 16635 radar_found->sidx = radar_event->sidx; 16636 16637 wmi_debug("processed radar found event pdev %d," 16638 "Radar Event Info:pdev_id %d,timestamp %d,chan_freq (dur) %d," 16639 "chan_width (RSSI) %d,detector_id (false_radar) %d," 16640 "freq_offset (radar_check) %d,segment_id %d,sidx %d," 16641 "is_chirp %d,detection mode %d", 16642 radar_event->pdev_id, radar_found->pdev_id, 16643 radar_event->timestamp, radar_event->chan_freq, 16644 radar_event->chan_width, radar_event->detector_id, 16645 radar_event->freq_offset, radar_event->segment_id, 16646 radar_event->sidx, radar_event->is_chirp, 16647 radar_event->detection_mode); 16648 16649 return QDF_STATUS_SUCCESS; 16650 } 16651 16652 #ifdef MOBILE_DFS_SUPPORT 16653 /** 16654 * extract_wlan_radar_event_info_tlv() - extract radar pulse event 16655 * @wmi_handle: wma handle 16656 * @evt_buf: event buffer 16657 * @wlan_radar_event: Pointer to struct radar_event_info 16658 * @len: length of buffer 16659 * 16660 * Return: QDF_STATUS 16661 */ 16662 static QDF_STATUS extract_wlan_radar_event_info_tlv( 16663 wmi_unified_t wmi_handle, 16664 uint8_t *evt_buf, 16665 struct radar_event_info *wlan_radar_event, 16666 uint32_t len) 16667 { 16668 WMI_DFS_RADAR_EVENTID_param_tlvs *param_tlv; 16669 wmi_dfs_radar_event_fixed_param *radar_event; 16670 16671 param_tlv = (WMI_DFS_RADAR_EVENTID_param_tlvs *)evt_buf; 16672 if (!param_tlv) { 16673 wmi_err("invalid wlan radar event buf"); 16674 return QDF_STATUS_E_FAILURE; 16675 } 16676 16677 radar_event = param_tlv->fixed_param; 16678 wlan_radar_event->pulse_is_chirp = radar_event->pulse_is_chirp; 16679 wlan_radar_event->pulse_center_freq = radar_event->pulse_center_freq; 16680 wlan_radar_event->pulse_duration = radar_event->pulse_duration; 16681 wlan_radar_event->rssi = radar_event->rssi; 16682 wlan_radar_event->pulse_detect_ts = radar_event->pulse_detect_ts; 16683 wlan_radar_event->upload_fullts_high = radar_event->upload_fullts_high; 16684 wlan_radar_event->upload_fullts_low = radar_event->upload_fullts_low; 16685 wlan_radar_event->peak_sidx = radar_event->peak_sidx; 16686 wlan_radar_event->delta_peak = radar_event->pulse_delta_peak; 16687 wlan_radar_event->delta_diff = radar_event->pulse_delta_diff; 16688 if (radar_event->pulse_flags & 16689 WMI_DFS_RADAR_PULSE_FLAG_MASK_PSIDX_DIFF_VALID) { 16690 wlan_radar_event->is_psidx_diff_valid = true; 16691 wlan_radar_event->psidx_diff = radar_event->psidx_diff; 16692 } else { 16693 wlan_radar_event->is_psidx_diff_valid = false; 16694 } 16695 16696 wlan_radar_event->pdev_id = radar_event->pdev_id; 16697 16698 return QDF_STATUS_SUCCESS; 16699 } 16700 #else 16701 static QDF_STATUS extract_wlan_radar_event_info_tlv( 16702 wmi_unified_t wmi_handle, 16703 uint8_t *evt_buf, 16704 struct radar_event_info *wlan_radar_event, 16705 uint32_t len) 16706 { 16707 return QDF_STATUS_SUCCESS; 16708 } 16709 #endif 16710 #endif 16711 16712 /** 16713 * send_get_rcpi_cmd_tlv() - send request for rcpi value 16714 * @wmi_handle: wmi handle 16715 * @get_rcpi_param: rcpi params 16716 * 16717 * Return: QDF status 16718 */ 16719 static QDF_STATUS send_get_rcpi_cmd_tlv(wmi_unified_t wmi_handle, 16720 struct rcpi_req *get_rcpi_param) 16721 { 16722 wmi_buf_t buf; 16723 wmi_request_rcpi_cmd_fixed_param *cmd; 16724 uint8_t len = sizeof(wmi_request_rcpi_cmd_fixed_param); 16725 16726 buf = wmi_buf_alloc(wmi_handle, len); 16727 if (!buf) 16728 return QDF_STATUS_E_NOMEM; 16729 16730 cmd = (wmi_request_rcpi_cmd_fixed_param *) wmi_buf_data(buf); 16731 WMITLV_SET_HDR(&cmd->tlv_header, 16732 WMITLV_TAG_STRUC_wmi_request_rcpi_cmd_fixed_param, 16733 WMITLV_GET_STRUCT_TLVLEN 16734 (wmi_request_rcpi_cmd_fixed_param)); 16735 16736 cmd->vdev_id = get_rcpi_param->vdev_id; 16737 WMI_CHAR_ARRAY_TO_MAC_ADDR(get_rcpi_param->mac_addr, 16738 &cmd->peer_macaddr); 16739 16740 switch (get_rcpi_param->measurement_type) { 16741 16742 case RCPI_MEASUREMENT_TYPE_AVG_MGMT: 16743 cmd->measurement_type = WMI_RCPI_MEASUREMENT_TYPE_AVG_MGMT; 16744 break; 16745 16746 case RCPI_MEASUREMENT_TYPE_AVG_DATA: 16747 cmd->measurement_type = WMI_RCPI_MEASUREMENT_TYPE_AVG_DATA; 16748 break; 16749 16750 case RCPI_MEASUREMENT_TYPE_LAST_MGMT: 16751 cmd->measurement_type = WMI_RCPI_MEASUREMENT_TYPE_LAST_MGMT; 16752 break; 16753 16754 case RCPI_MEASUREMENT_TYPE_LAST_DATA: 16755 cmd->measurement_type = WMI_RCPI_MEASUREMENT_TYPE_LAST_DATA; 16756 break; 16757 16758 default: 16759 /* 16760 * invalid rcpi measurement type, fall back to 16761 * RCPI_MEASUREMENT_TYPE_AVG_MGMT 16762 */ 16763 cmd->measurement_type = WMI_RCPI_MEASUREMENT_TYPE_AVG_MGMT; 16764 break; 16765 } 16766 wmi_debug("RCPI REQ VDEV_ID:%d-->", cmd->vdev_id); 16767 wmi_mtrace(WMI_REQUEST_RCPI_CMDID, cmd->vdev_id, 0); 16768 if (wmi_unified_cmd_send(wmi_handle, buf, len, 16769 WMI_REQUEST_RCPI_CMDID)) { 16770 16771 wmi_err("Failed to send WMI_REQUEST_RCPI_CMDID"); 16772 wmi_buf_free(buf); 16773 return QDF_STATUS_E_FAILURE; 16774 } 16775 16776 return QDF_STATUS_SUCCESS; 16777 } 16778 16779 /** 16780 * extract_rcpi_response_event_tlv() - Extract RCPI event params 16781 * @wmi_handle: wmi handle 16782 * @evt_buf: pointer to event buffer 16783 * @res: pointer to hold rcpi response from firmware 16784 * 16785 * Return: QDF_STATUS_SUCCESS for successful event parse 16786 * else QDF_STATUS_E_INVAL or QDF_STATUS_E_FAILURE 16787 */ 16788 static QDF_STATUS 16789 extract_rcpi_response_event_tlv(wmi_unified_t wmi_handle, 16790 void *evt_buf, struct rcpi_res *res) 16791 { 16792 WMI_UPDATE_RCPI_EVENTID_param_tlvs *param_buf; 16793 wmi_update_rcpi_event_fixed_param *event; 16794 16795 param_buf = (WMI_UPDATE_RCPI_EVENTID_param_tlvs *)evt_buf; 16796 if (!param_buf) { 16797 wmi_err("Invalid rcpi event"); 16798 return QDF_STATUS_E_INVAL; 16799 } 16800 16801 event = param_buf->fixed_param; 16802 res->vdev_id = event->vdev_id; 16803 WMI_MAC_ADDR_TO_CHAR_ARRAY(&event->peer_macaddr, res->mac_addr); 16804 16805 switch (event->measurement_type) { 16806 16807 case WMI_RCPI_MEASUREMENT_TYPE_AVG_MGMT: 16808 res->measurement_type = RCPI_MEASUREMENT_TYPE_AVG_MGMT; 16809 break; 16810 16811 case WMI_RCPI_MEASUREMENT_TYPE_AVG_DATA: 16812 res->measurement_type = RCPI_MEASUREMENT_TYPE_AVG_DATA; 16813 break; 16814 16815 case WMI_RCPI_MEASUREMENT_TYPE_LAST_MGMT: 16816 res->measurement_type = RCPI_MEASUREMENT_TYPE_LAST_MGMT; 16817 break; 16818 16819 case WMI_RCPI_MEASUREMENT_TYPE_LAST_DATA: 16820 res->measurement_type = RCPI_MEASUREMENT_TYPE_LAST_DATA; 16821 break; 16822 16823 default: 16824 wmi_err("Invalid rcpi measurement type from firmware"); 16825 res->measurement_type = RCPI_MEASUREMENT_TYPE_INVALID; 16826 return QDF_STATUS_E_FAILURE; 16827 } 16828 16829 if (event->status) 16830 return QDF_STATUS_E_FAILURE; 16831 else 16832 return QDF_STATUS_SUCCESS; 16833 } 16834 16835 /** 16836 * convert_host_pdev_id_to_target_pdev_id_legacy() - Convert pdev_id from 16837 * host to target defines. For legacy there is not conversion 16838 * required. Just return pdev_id as it is. 16839 * @wmi_handle: handle to WMI. 16840 * @pdev_id: host pdev_id to be converted. 16841 * Return: target pdev_id after conversion. 16842 */ 16843 static uint32_t convert_host_pdev_id_to_target_pdev_id_legacy( 16844 wmi_unified_t wmi_handle, 16845 uint32_t pdev_id) 16846 { 16847 if (pdev_id == WMI_HOST_PDEV_ID_SOC) 16848 return WMI_PDEV_ID_SOC; 16849 16850 /*No conversion required*/ 16851 return pdev_id; 16852 } 16853 16854 /** 16855 * convert_target_pdev_id_to_host_pdev_id_legacy() - Convert pdev_id from 16856 * target to host defines. For legacy there is not conversion 16857 * required. Just return pdev_id as it is. 16858 * @wmi_handle: handle to WMI. 16859 * @pdev_id: target pdev_id to be converted. 16860 * Return: host pdev_id after conversion. 16861 */ 16862 static uint32_t convert_target_pdev_id_to_host_pdev_id_legacy( 16863 wmi_unified_t wmi_handle, 16864 uint32_t pdev_id) 16865 { 16866 /*No conversion required*/ 16867 return pdev_id; 16868 } 16869 16870 /** 16871 * convert_host_phy_id_to_target_phy_id_legacy() - Convert phy_id from 16872 * host to target defines. For legacy there is not conversion 16873 * required. Just return phy_id as it is. 16874 * @wmi_handle: handle to WMI. 16875 * @phy_id: host phy_id to be converted. 16876 * 16877 * Return: target phy_id after conversion. 16878 */ 16879 static uint32_t convert_host_phy_id_to_target_phy_id_legacy( 16880 wmi_unified_t wmi_handle, 16881 uint32_t phy_id) 16882 { 16883 /*No conversion required*/ 16884 return phy_id; 16885 } 16886 16887 /** 16888 * convert_target_phy_id_to_host_phy_id_legacy() - Convert phy_id from 16889 * target to host defines. For legacy there is not conversion 16890 * required. Just return phy_id as it is. 16891 * @wmi_handle: handle to WMI. 16892 * @phy_id: target phy_id to be converted. 16893 * 16894 * Return: host phy_id after conversion. 16895 */ 16896 static uint32_t convert_target_phy_id_to_host_phy_id_legacy( 16897 wmi_unified_t wmi_handle, 16898 uint32_t phy_id) 16899 { 16900 /*No conversion required*/ 16901 return phy_id; 16902 } 16903 16904 /** 16905 * send_set_country_cmd_tlv() - WMI scan channel list function 16906 * @wmi_handle: handle to WMI. 16907 * @params: pointer to hold scan channel list parameter 16908 * 16909 * Return: QDF_STATUS_SUCCESS for success or error code 16910 */ 16911 static QDF_STATUS send_set_country_cmd_tlv(wmi_unified_t wmi_handle, 16912 struct set_country *params) 16913 { 16914 wmi_buf_t buf; 16915 QDF_STATUS qdf_status; 16916 wmi_set_current_country_cmd_fixed_param *cmd; 16917 uint16_t len = sizeof(*cmd); 16918 uint8_t pdev_id = params->pdev_id; 16919 16920 buf = wmi_buf_alloc(wmi_handle, len); 16921 if (!buf) { 16922 qdf_status = QDF_STATUS_E_NOMEM; 16923 goto end; 16924 } 16925 16926 cmd = (wmi_set_current_country_cmd_fixed_param *)wmi_buf_data(buf); 16927 WMITLV_SET_HDR(&cmd->tlv_header, 16928 WMITLV_TAG_STRUC_wmi_set_current_country_cmd_fixed_param, 16929 WMITLV_GET_STRUCT_TLVLEN 16930 (wmi_set_current_country_cmd_fixed_param)); 16931 16932 cmd->pdev_id = wmi_handle->ops->convert_host_pdev_id_to_target( 16933 wmi_handle, 16934 pdev_id); 16935 wmi_debug("setting current country to %s and target pdev_id = %u", 16936 params->country, cmd->pdev_id); 16937 16938 qdf_mem_copy((uint8_t *)&cmd->new_alpha2, params->country, 3); 16939 16940 wmi_mtrace(WMI_SET_CURRENT_COUNTRY_CMDID, NO_SESSION, 0); 16941 qdf_status = wmi_unified_cmd_send(wmi_handle, 16942 buf, len, WMI_SET_CURRENT_COUNTRY_CMDID); 16943 16944 if (QDF_IS_STATUS_ERROR(qdf_status)) { 16945 wmi_err("Failed to send WMI_SET_CURRENT_COUNTRY_CMDID"); 16946 wmi_buf_free(buf); 16947 } 16948 16949 end: 16950 return qdf_status; 16951 } 16952 16953 #define WMI_REG_COUNTRY_ALPHA_SET(alpha, val0, val1, val2) do { \ 16954 WMI_SET_BITS(alpha, 0, 8, val0); \ 16955 WMI_SET_BITS(alpha, 8, 8, val1); \ 16956 WMI_SET_BITS(alpha, 16, 8, val2); \ 16957 } while (0) 16958 16959 static QDF_STATUS send_user_country_code_cmd_tlv(wmi_unified_t wmi_handle, 16960 uint8_t pdev_id, struct cc_regdmn_s *rd) 16961 { 16962 wmi_set_init_country_cmd_fixed_param *cmd; 16963 uint16_t len; 16964 wmi_buf_t buf; 16965 int ret; 16966 16967 len = sizeof(wmi_set_init_country_cmd_fixed_param); 16968 buf = wmi_buf_alloc(wmi_handle, len); 16969 if (!buf) 16970 return QDF_STATUS_E_NOMEM; 16971 16972 cmd = (wmi_set_init_country_cmd_fixed_param *) wmi_buf_data(buf); 16973 WMITLV_SET_HDR(&cmd->tlv_header, 16974 WMITLV_TAG_STRUC_wmi_set_init_country_cmd_fixed_param, 16975 WMITLV_GET_STRUCT_TLVLEN 16976 (wmi_set_init_country_cmd_fixed_param)); 16977 16978 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 16979 wmi_handle, 16980 pdev_id); 16981 16982 if (rd->flags == CC_IS_SET) { 16983 cmd->countrycode_type = WMI_COUNTRYCODE_COUNTRY_ID; 16984 cmd->country_code.country_id = rd->cc.country_code; 16985 } else if (rd->flags == ALPHA_IS_SET) { 16986 cmd->countrycode_type = WMI_COUNTRYCODE_ALPHA2; 16987 WMI_REG_COUNTRY_ALPHA_SET(cmd->country_code.alpha2, 16988 rd->cc.alpha[0], 16989 rd->cc.alpha[1], 16990 rd->cc.alpha[2]); 16991 } else if (rd->flags == REGDMN_IS_SET) { 16992 cmd->countrycode_type = WMI_COUNTRYCODE_DOMAIN_CODE; 16993 WMI_SET_BITS(cmd->country_code.domain_code, 0, 16, 16994 rd->cc.regdmn.reg_2g_5g_pair_id); 16995 WMI_SET_BITS(cmd->country_code.domain_code, 16, 16, 16996 rd->cc.regdmn.sixg_superdmn_id); 16997 } 16998 16999 wmi_mtrace(WMI_SET_INIT_COUNTRY_CMDID, NO_SESSION, 0); 17000 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 17001 WMI_SET_INIT_COUNTRY_CMDID); 17002 if (ret) { 17003 wmi_err("Failed to config wow wakeup event"); 17004 wmi_buf_free(buf); 17005 return QDF_STATUS_E_FAILURE; 17006 } 17007 17008 return QDF_STATUS_SUCCESS; 17009 } 17010 17011 /** 17012 * send_obss_detection_cfg_cmd_tlv() - send obss detection 17013 * configurations to firmware. 17014 * @wmi_handle: wmi handle 17015 * @obss_cfg_param: obss detection configurations 17016 * 17017 * Send WMI_SAP_OBSS_DETECTION_CFG_CMDID parameters to fw. 17018 * 17019 * Return: QDF_STATUS 17020 */ 17021 static QDF_STATUS send_obss_detection_cfg_cmd_tlv(wmi_unified_t wmi_handle, 17022 struct wmi_obss_detection_cfg_param *obss_cfg_param) 17023 { 17024 wmi_buf_t buf; 17025 wmi_sap_obss_detection_cfg_cmd_fixed_param *cmd; 17026 uint8_t len = sizeof(wmi_sap_obss_detection_cfg_cmd_fixed_param); 17027 17028 buf = wmi_buf_alloc(wmi_handle, len); 17029 if (!buf) 17030 return QDF_STATUS_E_NOMEM; 17031 17032 cmd = (wmi_sap_obss_detection_cfg_cmd_fixed_param *)wmi_buf_data(buf); 17033 WMITLV_SET_HDR(&cmd->tlv_header, 17034 WMITLV_TAG_STRUC_wmi_sap_obss_detection_cfg_cmd_fixed_param, 17035 WMITLV_GET_STRUCT_TLVLEN 17036 (wmi_sap_obss_detection_cfg_cmd_fixed_param)); 17037 17038 cmd->vdev_id = obss_cfg_param->vdev_id; 17039 cmd->detect_period_ms = obss_cfg_param->obss_detect_period_ms; 17040 cmd->b_ap_detect_mode = obss_cfg_param->obss_11b_ap_detect_mode; 17041 cmd->b_sta_detect_mode = obss_cfg_param->obss_11b_sta_detect_mode; 17042 cmd->g_ap_detect_mode = obss_cfg_param->obss_11g_ap_detect_mode; 17043 cmd->a_detect_mode = obss_cfg_param->obss_11a_detect_mode; 17044 cmd->ht_legacy_detect_mode = obss_cfg_param->obss_ht_legacy_detect_mode; 17045 cmd->ht_mixed_detect_mode = obss_cfg_param->obss_ht_mixed_detect_mode; 17046 cmd->ht_20mhz_detect_mode = obss_cfg_param->obss_ht_20mhz_detect_mode; 17047 17048 wmi_mtrace(WMI_SAP_OBSS_DETECTION_CFG_CMDID, cmd->vdev_id, 0); 17049 if (wmi_unified_cmd_send(wmi_handle, buf, len, 17050 WMI_SAP_OBSS_DETECTION_CFG_CMDID)) { 17051 wmi_err("Failed to send WMI_SAP_OBSS_DETECTION_CFG_CMDID"); 17052 wmi_buf_free(buf); 17053 return QDF_STATUS_E_FAILURE; 17054 } 17055 17056 return QDF_STATUS_SUCCESS; 17057 } 17058 17059 /** 17060 * extract_obss_detection_info_tlv() - Extract obss detection info 17061 * received from firmware. 17062 * @evt_buf: pointer to event buffer 17063 * @obss_detection: Pointer to hold obss detection info 17064 * 17065 * Return: QDF_STATUS 17066 */ 17067 static QDF_STATUS extract_obss_detection_info_tlv(uint8_t *evt_buf, 17068 struct wmi_obss_detect_info 17069 *obss_detection) 17070 { 17071 WMI_SAP_OBSS_DETECTION_REPORT_EVENTID_param_tlvs *param_buf; 17072 wmi_sap_obss_detection_info_evt_fixed_param *fix_param; 17073 17074 if (!obss_detection) { 17075 wmi_err("Invalid obss_detection event buffer"); 17076 return QDF_STATUS_E_INVAL; 17077 } 17078 17079 param_buf = (WMI_SAP_OBSS_DETECTION_REPORT_EVENTID_param_tlvs *)evt_buf; 17080 if (!param_buf) { 17081 wmi_err("Invalid evt_buf"); 17082 return QDF_STATUS_E_INVAL; 17083 } 17084 17085 fix_param = param_buf->fixed_param; 17086 obss_detection->vdev_id = fix_param->vdev_id; 17087 obss_detection->matched_detection_masks = 17088 fix_param->matched_detection_masks; 17089 WMI_MAC_ADDR_TO_CHAR_ARRAY(&fix_param->matched_bssid_addr, 17090 &obss_detection->matched_bssid_addr[0]); 17091 switch (fix_param->reason) { 17092 case WMI_SAP_OBSS_DETECTION_EVENT_REASON_NOT_SUPPORT: 17093 obss_detection->reason = OBSS_OFFLOAD_DETECTION_DISABLED; 17094 break; 17095 case WMI_SAP_OBSS_DETECTION_EVENT_REASON_PRESENT_NOTIFY: 17096 obss_detection->reason = OBSS_OFFLOAD_DETECTION_PRESENT; 17097 break; 17098 case WMI_SAP_OBSS_DETECTION_EVENT_REASON_ABSENT_TIMEOUT: 17099 obss_detection->reason = OBSS_OFFLOAD_DETECTION_ABSENT; 17100 break; 17101 default: 17102 wmi_err("Invalid reason: %d", fix_param->reason); 17103 return QDF_STATUS_E_INVAL; 17104 } 17105 17106 return QDF_STATUS_SUCCESS; 17107 } 17108 17109 /** 17110 * send_roam_scan_stats_cmd_tlv() - Send roam scan stats req command to fw 17111 * @wmi_handle: wmi handle 17112 * @params: pointer to request structure 17113 * 17114 * Return: QDF_STATUS 17115 */ 17116 static QDF_STATUS 17117 send_roam_scan_stats_cmd_tlv(wmi_unified_t wmi_handle, 17118 struct wmi_roam_scan_stats_req *params) 17119 { 17120 wmi_buf_t buf; 17121 wmi_request_roam_scan_stats_cmd_fixed_param *cmd; 17122 WMITLV_TAG_ID tag; 17123 uint32_t size; 17124 uint32_t len = sizeof(*cmd); 17125 17126 buf = wmi_buf_alloc(wmi_handle, len); 17127 if (!buf) 17128 return QDF_STATUS_E_FAILURE; 17129 17130 cmd = (wmi_request_roam_scan_stats_cmd_fixed_param *)wmi_buf_data(buf); 17131 17132 tag = WMITLV_TAG_STRUC_wmi_request_roam_scan_stats_cmd_fixed_param; 17133 size = WMITLV_GET_STRUCT_TLVLEN( 17134 wmi_request_roam_scan_stats_cmd_fixed_param); 17135 WMITLV_SET_HDR(&cmd->tlv_header, tag, size); 17136 17137 cmd->vdev_id = params->vdev_id; 17138 17139 wmi_debug("Roam Scan Stats Req vdev_id: %u", cmd->vdev_id); 17140 if (wmi_unified_cmd_send(wmi_handle, buf, len, 17141 WMI_REQUEST_ROAM_SCAN_STATS_CMDID)) { 17142 wmi_err("Failed to send WMI_REQUEST_ROAM_SCAN_STATS_CMDID"); 17143 wmi_buf_free(buf); 17144 return QDF_STATUS_E_FAILURE; 17145 } 17146 17147 return QDF_STATUS_SUCCESS; 17148 } 17149 17150 /** 17151 * send_roam_scan_ch_list_req_cmd_tlv() - send wmi cmd to get roam scan 17152 * channel list from firmware 17153 * @wmi_handle: wmi handler 17154 * @vdev_id: vdev id 17155 * 17156 * Return: QDF_STATUS 17157 */ 17158 static QDF_STATUS send_roam_scan_ch_list_req_cmd_tlv(wmi_unified_t wmi_handle, 17159 uint32_t vdev_id) 17160 { 17161 wmi_buf_t buf; 17162 wmi_roam_get_scan_channel_list_cmd_fixed_param *cmd; 17163 uint16_t len = sizeof(*cmd); 17164 int ret; 17165 17166 buf = wmi_buf_alloc(wmi_handle, len); 17167 if (!buf) { 17168 wmi_err("Failed to allocate wmi buffer"); 17169 return QDF_STATUS_E_NOMEM; 17170 } 17171 17172 cmd = (wmi_roam_get_scan_channel_list_cmd_fixed_param *) 17173 wmi_buf_data(buf); 17174 WMITLV_SET_HDR(&cmd->tlv_header, 17175 WMITLV_TAG_STRUC_wmi_roam_get_scan_channel_list_cmd_fixed_param, 17176 WMITLV_GET_STRUCT_TLVLEN( 17177 wmi_roam_get_scan_channel_list_cmd_fixed_param)); 17178 cmd->vdev_id = vdev_id; 17179 wmi_mtrace(WMI_ROAM_GET_SCAN_CHANNEL_LIST_CMDID, vdev_id, 0); 17180 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 17181 WMI_ROAM_GET_SCAN_CHANNEL_LIST_CMDID); 17182 if (QDF_IS_STATUS_ERROR(ret)) { 17183 wmi_err("Failed to send get roam scan channels request = %d", 17184 ret); 17185 wmi_buf_free(buf); 17186 } 17187 return ret; 17188 } 17189 17190 /** 17191 * extract_roam_scan_stats_res_evt_tlv() - Extract roam scan stats event 17192 * @wmi_handle: wmi handle 17193 * @evt_buf: pointer to event buffer 17194 * @vdev_id: output pointer to hold vdev id 17195 * @res_param: output pointer to hold the allocated response 17196 * 17197 * Return: QDF_STATUS 17198 */ 17199 static QDF_STATUS 17200 extract_roam_scan_stats_res_evt_tlv(wmi_unified_t wmi_handle, void *evt_buf, 17201 uint32_t *vdev_id, 17202 struct wmi_roam_scan_stats_res **res_param) 17203 { 17204 WMI_ROAM_SCAN_STATS_EVENTID_param_tlvs *param_buf; 17205 wmi_roam_scan_stats_event_fixed_param *fixed_param; 17206 uint32_t *client_id = NULL; 17207 wmi_roaming_timestamp *timestamp = NULL; 17208 uint32_t *num_channels = NULL; 17209 uint32_t *chan_info = NULL; 17210 wmi_mac_addr *old_bssid = NULL; 17211 uint32_t *is_roaming_success = NULL; 17212 wmi_mac_addr *new_bssid = NULL; 17213 uint32_t *num_roam_candidates = NULL; 17214 wmi_roam_scan_trigger_reason *roam_reason = NULL; 17215 wmi_mac_addr *bssid = NULL; 17216 uint32_t *score = NULL; 17217 uint32_t *channel = NULL; 17218 uint32_t *rssi = NULL; 17219 int chan_idx = 0, cand_idx = 0; 17220 uint32_t total_len; 17221 struct wmi_roam_scan_stats_res *res; 17222 uint32_t i, j; 17223 uint32_t num_scans, scan_param_size; 17224 17225 *res_param = NULL; 17226 *vdev_id = 0xFF; /* Initialize to invalid vdev id */ 17227 param_buf = (WMI_ROAM_SCAN_STATS_EVENTID_param_tlvs *)evt_buf; 17228 if (!param_buf) { 17229 wmi_err("Invalid roam scan stats event"); 17230 return QDF_STATUS_E_INVAL; 17231 } 17232 17233 fixed_param = param_buf->fixed_param; 17234 17235 num_scans = fixed_param->num_roam_scans; 17236 scan_param_size = sizeof(struct wmi_roam_scan_stats_params); 17237 *vdev_id = fixed_param->vdev_id; 17238 if (num_scans > WMI_ROAM_SCAN_STATS_MAX) { 17239 wmi_err_rl("%u exceeded maximum roam scan stats: %u", 17240 num_scans, WMI_ROAM_SCAN_STATS_MAX); 17241 return QDF_STATUS_E_INVAL; 17242 } 17243 17244 total_len = sizeof(*res) + num_scans * scan_param_size; 17245 17246 res = qdf_mem_malloc(total_len); 17247 if (!res) 17248 return QDF_STATUS_E_NOMEM; 17249 17250 if (!num_scans) { 17251 *res_param = res; 17252 return QDF_STATUS_SUCCESS; 17253 } 17254 17255 if (param_buf->client_id && 17256 param_buf->num_client_id == num_scans) 17257 client_id = param_buf->client_id; 17258 17259 if (param_buf->timestamp && 17260 param_buf->num_timestamp == num_scans) 17261 timestamp = param_buf->timestamp; 17262 17263 if (param_buf->old_bssid && 17264 param_buf->num_old_bssid == num_scans) 17265 old_bssid = param_buf->old_bssid; 17266 17267 if (param_buf->new_bssid && 17268 param_buf->num_new_bssid == num_scans) 17269 new_bssid = param_buf->new_bssid; 17270 17271 if (param_buf->is_roaming_success && 17272 param_buf->num_is_roaming_success == num_scans) 17273 is_roaming_success = param_buf->is_roaming_success; 17274 17275 if (param_buf->roam_reason && 17276 param_buf->num_roam_reason == num_scans) 17277 roam_reason = param_buf->roam_reason; 17278 17279 if (param_buf->num_channels && 17280 param_buf->num_num_channels == num_scans) { 17281 uint32_t count, chan_info_sum = 0; 17282 17283 num_channels = param_buf->num_channels; 17284 for (count = 0; count < param_buf->num_num_channels; count++) { 17285 if (param_buf->num_channels[count] > 17286 WMI_ROAM_SCAN_STATS_CHANNELS_MAX) { 17287 wmi_err_rl("%u exceeded max scan channels %u", 17288 param_buf->num_channels[count], 17289 WMI_ROAM_SCAN_STATS_CHANNELS_MAX); 17290 goto error; 17291 } 17292 chan_info_sum += param_buf->num_channels[count]; 17293 } 17294 17295 if (param_buf->chan_info && 17296 param_buf->num_chan_info == chan_info_sum) 17297 chan_info = param_buf->chan_info; 17298 } 17299 17300 if (param_buf->num_roam_candidates && 17301 param_buf->num_num_roam_candidates == num_scans) { 17302 uint32_t cnt, roam_cand_sum = 0; 17303 17304 num_roam_candidates = param_buf->num_roam_candidates; 17305 for (cnt = 0; cnt < param_buf->num_num_roam_candidates; cnt++) { 17306 if (param_buf->num_roam_candidates[cnt] > 17307 WMI_ROAM_SCAN_STATS_CANDIDATES_MAX) { 17308 wmi_err_rl("%u exceeded max scan cand %u", 17309 param_buf->num_roam_candidates[cnt], 17310 WMI_ROAM_SCAN_STATS_CANDIDATES_MAX); 17311 goto error; 17312 } 17313 roam_cand_sum += param_buf->num_roam_candidates[cnt]; 17314 } 17315 17316 if (param_buf->bssid && 17317 param_buf->num_bssid == roam_cand_sum) 17318 bssid = param_buf->bssid; 17319 17320 if (param_buf->score && 17321 param_buf->num_score == roam_cand_sum) 17322 score = param_buf->score; 17323 17324 if (param_buf->channel && 17325 param_buf->num_channel == roam_cand_sum) 17326 channel = param_buf->channel; 17327 17328 if (param_buf->rssi && 17329 param_buf->num_rssi == roam_cand_sum) 17330 rssi = param_buf->rssi; 17331 } 17332 17333 res->num_roam_scans = num_scans; 17334 for (i = 0; i < num_scans; i++) { 17335 struct wmi_roam_scan_stats_params *roam = &res->roam_scan[i]; 17336 17337 if (timestamp) 17338 roam->time_stamp = timestamp[i].lower32bit | 17339 (timestamp[i].upper32bit << 31); 17340 17341 if (client_id) 17342 roam->client_id = client_id[i]; 17343 17344 if (num_channels) { 17345 roam->num_scan_chans = num_channels[i]; 17346 if (chan_info) { 17347 for (j = 0; j < num_channels[i]; j++) 17348 roam->scan_freqs[j] = 17349 chan_info[chan_idx++]; 17350 } 17351 } 17352 17353 if (is_roaming_success) 17354 roam->is_roam_successful = is_roaming_success[i]; 17355 17356 if (roam_reason) { 17357 roam->trigger_id = roam_reason[i].trigger_id; 17358 roam->trigger_value = roam_reason[i].trigger_value; 17359 } 17360 17361 if (num_roam_candidates) { 17362 roam->num_roam_candidates = num_roam_candidates[i]; 17363 17364 for (j = 0; j < num_roam_candidates[i]; j++) { 17365 if (score) 17366 roam->cand[j].score = score[cand_idx]; 17367 if (rssi) 17368 roam->cand[j].rssi = rssi[cand_idx]; 17369 if (channel) 17370 roam->cand[j].freq = 17371 channel[cand_idx]; 17372 17373 if (bssid) 17374 WMI_MAC_ADDR_TO_CHAR_ARRAY( 17375 &bssid[cand_idx], 17376 roam->cand[j].bssid); 17377 17378 cand_idx++; 17379 } 17380 } 17381 17382 if (old_bssid) 17383 WMI_MAC_ADDR_TO_CHAR_ARRAY(&old_bssid[i], 17384 roam->old_bssid); 17385 17386 if (new_bssid) 17387 WMI_MAC_ADDR_TO_CHAR_ARRAY(&new_bssid[i], 17388 roam->new_bssid); 17389 } 17390 17391 *res_param = res; 17392 17393 return QDF_STATUS_SUCCESS; 17394 error: 17395 qdf_mem_free(res); 17396 return QDF_STATUS_E_FAILURE; 17397 } 17398 17399 /** 17400 * extract_offload_bcn_tx_status_evt() - Extract beacon-tx status event 17401 * @wmi_handle: wmi handle 17402 * @evt_buf: pointer to event buffer 17403 * @vdev_id: output pointer to hold vdev id 17404 * @tx_status: output pointer to hold the tx_status 17405 * 17406 * Return: QDF_STATUS 17407 */ 17408 static QDF_STATUS extract_offload_bcn_tx_status_evt(wmi_unified_t wmi_handle, 17409 void *evt_buf, 17410 uint32_t *vdev_id, 17411 uint32_t *tx_status) { 17412 WMI_OFFLOAD_BCN_TX_STATUS_EVENTID_param_tlvs *param_buf; 17413 wmi_offload_bcn_tx_status_event_fixed_param *bcn_tx_status_event; 17414 17415 param_buf = (WMI_OFFLOAD_BCN_TX_STATUS_EVENTID_param_tlvs *)evt_buf; 17416 if (!param_buf) { 17417 wmi_err("Invalid offload bcn tx status event buffer"); 17418 return QDF_STATUS_E_INVAL; 17419 } 17420 17421 bcn_tx_status_event = param_buf->fixed_param; 17422 *vdev_id = bcn_tx_status_event->vdev_id; 17423 *tx_status = bcn_tx_status_event->tx_status; 17424 17425 return QDF_STATUS_SUCCESS; 17426 } 17427 17428 #ifdef WLAN_SUPPORT_GREEN_AP 17429 static QDF_STATUS extract_green_ap_egap_status_info_tlv( 17430 uint8_t *evt_buf, 17431 struct wlan_green_ap_egap_status_info *egap_status_info_params) 17432 { 17433 WMI_AP_PS_EGAP_INFO_EVENTID_param_tlvs *param_buf; 17434 wmi_ap_ps_egap_info_event_fixed_param *egap_info_event; 17435 wmi_ap_ps_egap_info_chainmask_list *chainmask_event; 17436 17437 param_buf = (WMI_AP_PS_EGAP_INFO_EVENTID_param_tlvs *)evt_buf; 17438 if (!param_buf) { 17439 wmi_err("Invalid EGAP Info status event buffer"); 17440 return QDF_STATUS_E_INVAL; 17441 } 17442 17443 egap_info_event = (wmi_ap_ps_egap_info_event_fixed_param *) 17444 param_buf->fixed_param; 17445 chainmask_event = (wmi_ap_ps_egap_info_chainmask_list *) 17446 param_buf->chainmask_list; 17447 17448 if (!egap_info_event || !chainmask_event) { 17449 wmi_err("Invalid EGAP Info event or chainmask event"); 17450 return QDF_STATUS_E_INVAL; 17451 } 17452 17453 egap_status_info_params->status = egap_info_event->status; 17454 egap_status_info_params->mac_id = chainmask_event->mac_id; 17455 egap_status_info_params->tx_chainmask = chainmask_event->tx_chainmask; 17456 egap_status_info_params->rx_chainmask = chainmask_event->rx_chainmask; 17457 17458 return QDF_STATUS_SUCCESS; 17459 } 17460 #endif 17461 17462 #ifdef WLAN_SUPPORT_GAP_LL_PS_MODE 17463 static QDF_STATUS extract_green_ap_ll_ps_param_tlv( 17464 uint8_t *evt_buf, 17465 struct wlan_green_ap_ll_ps_event_param *ll_ps_params) 17466 { 17467 WMI_XGAP_ENABLE_COMPLETE_EVENTID_param_tlvs *param_buf; 17468 wmi_xgap_enable_complete_event_fixed_param *ll_ps_event; 17469 17470 param_buf = (WMI_XGAP_ENABLE_COMPLETE_EVENTID_param_tlvs *)evt_buf; 17471 if (!param_buf) { 17472 wmi_err("Invalid XGAP SAP info status"); 17473 return QDF_STATUS_E_INVAL; 17474 } 17475 17476 ll_ps_event = (wmi_xgap_enable_complete_event_fixed_param *) 17477 param_buf->fixed_param; 17478 if (!ll_ps_event) { 17479 wmi_err("Invalid low latency power save event buffer"); 17480 return QDF_STATUS_E_INVAL; 17481 } 17482 17483 ll_ps_params->dialog_token = ll_ps_event->dialog_token; 17484 ll_ps_params->next_tsf = 17485 ((uint64_t)ll_ps_event->next_tsf_high32 << 32) | 17486 ll_ps_event->next_tsf_low32; 17487 17488 wmi_debug("cookie : %llu next_tsf %llu", ll_ps_params->dialog_token, 17489 ll_ps_params->next_tsf); 17490 17491 return QDF_STATUS_SUCCESS; 17492 } 17493 #endif 17494 17495 /* 17496 * extract_comb_phyerr_tlv() - extract comb phy error from event 17497 * @wmi_handle: wmi handle 17498 * @evt_buf: pointer to event buffer 17499 * @datalen: data length of event buffer 17500 * @buf_offset: Pointer to hold value of current event buffer offset 17501 * post extraction 17502 * @phyerr: Pointer to hold phyerr 17503 * 17504 * Return: QDF_STATUS 17505 */ 17506 static QDF_STATUS extract_comb_phyerr_tlv(wmi_unified_t wmi_handle, 17507 void *evt_buf, 17508 uint16_t datalen, 17509 uint16_t *buf_offset, 17510 wmi_host_phyerr_t *phyerr) 17511 { 17512 WMI_PHYERR_EVENTID_param_tlvs *param_tlvs; 17513 wmi_comb_phyerr_rx_hdr *pe_hdr; 17514 17515 param_tlvs = (WMI_PHYERR_EVENTID_param_tlvs *)evt_buf; 17516 if (!param_tlvs) { 17517 wmi_debug("Received null data from FW"); 17518 return QDF_STATUS_E_FAILURE; 17519 } 17520 17521 pe_hdr = param_tlvs->hdr; 17522 if (!pe_hdr) { 17523 wmi_debug("Received Data PE Header is NULL"); 17524 return QDF_STATUS_E_FAILURE; 17525 } 17526 17527 /* Ensure it's at least the size of the header */ 17528 if (datalen < sizeof(*pe_hdr)) { 17529 wmi_debug("Expected minimum size %zu, received %d", 17530 sizeof(*pe_hdr), datalen); 17531 return QDF_STATUS_E_FAILURE; 17532 } 17533 17534 phyerr->pdev_id = wmi_handle->ops-> 17535 convert_pdev_id_target_to_host(wmi_handle, pe_hdr->pdev_id); 17536 phyerr->tsf64 = pe_hdr->tsf_l32; 17537 phyerr->tsf64 |= (((uint64_t)pe_hdr->tsf_u32) << 32); 17538 phyerr->bufp = param_tlvs->bufp; 17539 17540 if (pe_hdr->buf_len > param_tlvs->num_bufp) { 17541 wmi_debug("Invalid buf_len %d, num_bufp %d", 17542 pe_hdr->buf_len, param_tlvs->num_bufp); 17543 return QDF_STATUS_E_FAILURE; 17544 } 17545 17546 phyerr->buf_len = pe_hdr->buf_len; 17547 phyerr->phy_err_mask0 = pe_hdr->rsPhyErrMask0; 17548 phyerr->phy_err_mask1 = pe_hdr->rsPhyErrMask1; 17549 *buf_offset = sizeof(*pe_hdr) + sizeof(uint32_t); 17550 17551 return QDF_STATUS_SUCCESS; 17552 } 17553 17554 /** 17555 * extract_single_phyerr_tlv() - extract single phy error from event 17556 * @wmi_handle: wmi handle 17557 * @evt_buf: pointer to event buffer 17558 * @datalen: data length of event buffer 17559 * @buf_offset: Pointer to hold value of current event buffer offset 17560 * post extraction 17561 * @phyerr: Pointer to hold phyerr 17562 * 17563 * Return: QDF_STATUS 17564 */ 17565 static QDF_STATUS extract_single_phyerr_tlv(wmi_unified_t wmi_handle, 17566 void *evt_buf, 17567 uint16_t datalen, 17568 uint16_t *buf_offset, 17569 wmi_host_phyerr_t *phyerr) 17570 { 17571 wmi_single_phyerr_rx_event *ev; 17572 uint16_t n = *buf_offset; 17573 uint8_t *data = (uint8_t *)evt_buf; 17574 17575 if (n < datalen) { 17576 if ((datalen - n) < sizeof(ev->hdr)) { 17577 wmi_debug("Not enough space. len=%d, n=%d, hdr=%zu", 17578 datalen, n, sizeof(ev->hdr)); 17579 return QDF_STATUS_E_FAILURE; 17580 } 17581 17582 /* 17583 * Obtain a pointer to the beginning of the current event. 17584 * data[0] is the beginning of the WMI payload. 17585 */ 17586 ev = (wmi_single_phyerr_rx_event *)&data[n]; 17587 17588 /* 17589 * Sanity check the buffer length of the event against 17590 * what we currently have. 17591 * 17592 * Since buf_len is 32 bits, we check if it overflows 17593 * a large 32 bit value. It's not 0x7fffffff because 17594 * we increase n by (buf_len + sizeof(hdr)), which would 17595 * in itself cause n to overflow. 17596 * 17597 * If "int" is 64 bits then this becomes a moot point. 17598 */ 17599 if (ev->hdr.buf_len > PHYERROR_MAX_BUFFER_LENGTH) { 17600 wmi_debug("buf_len is garbage 0x%x", ev->hdr.buf_len); 17601 return QDF_STATUS_E_FAILURE; 17602 } 17603 17604 if ((n + ev->hdr.buf_len) > datalen) { 17605 wmi_debug("len exceeds n=%d, buf_len=%d, datalen=%d", 17606 n, ev->hdr.buf_len, datalen); 17607 return QDF_STATUS_E_FAILURE; 17608 } 17609 17610 phyerr->phy_err_code = WMI_UNIFIED_PHYERRCODE_GET(&ev->hdr); 17611 phyerr->tsf_timestamp = ev->hdr.tsf_timestamp; 17612 phyerr->bufp = &ev->bufp[0]; 17613 phyerr->buf_len = ev->hdr.buf_len; 17614 phyerr->rf_info.rssi_comb = WMI_UNIFIED_RSSI_COMB_GET(&ev->hdr); 17615 17616 /* 17617 * Advance the buffer pointer to the next PHY error. 17618 * buflen is the length of this payload, so we need to 17619 * advance past the current header _AND_ the payload. 17620 */ 17621 n += sizeof(*ev) + ev->hdr.buf_len; 17622 } 17623 *buf_offset = n; 17624 17625 return QDF_STATUS_SUCCESS; 17626 } 17627 17628 /** 17629 * extract_esp_estimation_ev_param_tlv() - extract air time from event 17630 * @wmi_handle: wmi handle 17631 * @evt_buf: pointer to event buffer 17632 * @param: Pointer to hold esp event 17633 * 17634 * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_INVAL on failure 17635 */ 17636 static QDF_STATUS 17637 extract_esp_estimation_ev_param_tlv(wmi_unified_t wmi_handle, 17638 void *evt_buf, 17639 struct esp_estimation_event *param) 17640 { 17641 WMI_ESP_ESTIMATE_EVENTID_param_tlvs *param_buf; 17642 wmi_esp_estimate_event_fixed_param *esp_event; 17643 17644 param_buf = (WMI_ESP_ESTIMATE_EVENTID_param_tlvs *)evt_buf; 17645 if (!param_buf) { 17646 wmi_err("Invalid ESP Estimate Event buffer"); 17647 return QDF_STATUS_E_INVAL; 17648 } 17649 esp_event = param_buf->fixed_param; 17650 param->ac_airtime_percentage = esp_event->ac_airtime_percentage; 17651 17652 param->pdev_id = convert_target_pdev_id_to_host_pdev_id( 17653 wmi_handle, 17654 esp_event->pdev_id); 17655 17656 if (param->pdev_id == WMI_HOST_PDEV_ID_INVALID) 17657 return QDF_STATUS_E_FAILURE; 17658 17659 return QDF_STATUS_SUCCESS; 17660 } 17661 17662 /* 17663 * send_bss_color_change_enable_cmd_tlv() - Send command to enable or disable of 17664 * updating bss color change within firmware when AP announces bss color change. 17665 * @wmi_handle: wmi handle 17666 * @vdev_id: vdev ID 17667 * @enable: enable bss color change within firmware 17668 * 17669 * Send WMI_BSS_COLOR_CHANGE_ENABLE_CMDID parameters to fw. 17670 * 17671 * Return: QDF_STATUS 17672 */ 17673 static QDF_STATUS send_bss_color_change_enable_cmd_tlv(wmi_unified_t wmi_handle, 17674 uint32_t vdev_id, 17675 bool enable) 17676 { 17677 wmi_buf_t buf; 17678 wmi_bss_color_change_enable_fixed_param *cmd; 17679 uint8_t len = sizeof(wmi_bss_color_change_enable_fixed_param); 17680 17681 buf = wmi_buf_alloc(wmi_handle, len); 17682 if (!buf) 17683 return QDF_STATUS_E_NOMEM; 17684 17685 cmd = (wmi_bss_color_change_enable_fixed_param *)wmi_buf_data(buf); 17686 WMITLV_SET_HDR(&cmd->tlv_header, 17687 WMITLV_TAG_STRUC_wmi_bss_color_change_enable_fixed_param, 17688 WMITLV_GET_STRUCT_TLVLEN 17689 (wmi_bss_color_change_enable_fixed_param)); 17690 cmd->vdev_id = vdev_id; 17691 cmd->enable = enable; 17692 wmi_mtrace(WMI_BSS_COLOR_CHANGE_ENABLE_CMDID, cmd->vdev_id, 0); 17693 if (wmi_unified_cmd_send(wmi_handle, buf, len, 17694 WMI_BSS_COLOR_CHANGE_ENABLE_CMDID)) { 17695 wmi_err("Failed to send WMI_BSS_COLOR_CHANGE_ENABLE_CMDID"); 17696 wmi_buf_free(buf); 17697 return QDF_STATUS_E_FAILURE; 17698 } 17699 17700 return QDF_STATUS_SUCCESS; 17701 } 17702 17703 /** 17704 * send_obss_color_collision_cfg_cmd_tlv() - send bss color detection 17705 * configurations to firmware. 17706 * @wmi_handle: wmi handle 17707 * @cfg_param: obss detection configurations 17708 * 17709 * Send WMI_OBSS_COLOR_COLLISION_DET_CONFIG_CMDID parameters to fw. 17710 * 17711 * Return: QDF_STATUS 17712 */ 17713 static QDF_STATUS send_obss_color_collision_cfg_cmd_tlv( 17714 wmi_unified_t wmi_handle, 17715 struct wmi_obss_color_collision_cfg_param *cfg_param) 17716 { 17717 wmi_buf_t buf; 17718 wmi_obss_color_collision_det_config_fixed_param *cmd; 17719 uint8_t len = sizeof(wmi_obss_color_collision_det_config_fixed_param); 17720 17721 buf = wmi_buf_alloc(wmi_handle, len); 17722 if (!buf) 17723 return QDF_STATUS_E_NOMEM; 17724 17725 cmd = (wmi_obss_color_collision_det_config_fixed_param *)wmi_buf_data( 17726 buf); 17727 WMITLV_SET_HDR(&cmd->tlv_header, 17728 WMITLV_TAG_STRUC_wmi_obss_color_collision_det_config_fixed_param, 17729 WMITLV_GET_STRUCT_TLVLEN 17730 (wmi_obss_color_collision_det_config_fixed_param)); 17731 cmd->vdev_id = cfg_param->vdev_id; 17732 cmd->flags = cfg_param->flags; 17733 cmd->current_bss_color = cfg_param->current_bss_color; 17734 cmd->detection_period_ms = cfg_param->detection_period_ms; 17735 cmd->scan_period_ms = cfg_param->scan_period_ms; 17736 cmd->free_slot_expiry_time_ms = cfg_param->free_slot_expiry_time_ms; 17737 17738 switch (cfg_param->evt_type) { 17739 case OBSS_COLOR_COLLISION_DETECTION_DISABLE: 17740 cmd->evt_type = WMI_BSS_COLOR_COLLISION_DISABLE; 17741 break; 17742 case OBSS_COLOR_COLLISION_DETECTION: 17743 cmd->evt_type = WMI_BSS_COLOR_COLLISION_DETECTION; 17744 break; 17745 case OBSS_COLOR_FREE_SLOT_TIMER_EXPIRY: 17746 cmd->evt_type = WMI_BSS_COLOR_FREE_SLOT_TIMER_EXPIRY; 17747 break; 17748 case OBSS_COLOR_FREE_SLOT_AVAILABLE: 17749 cmd->evt_type = WMI_BSS_COLOR_FREE_SLOT_AVAILABLE; 17750 break; 17751 default: 17752 wmi_err("Invalid event type: %d", cfg_param->evt_type); 17753 wmi_buf_free(buf); 17754 return QDF_STATUS_E_FAILURE; 17755 } 17756 17757 wmi_debug("evt_type: %d vdev id: %d current_bss_color: %d " 17758 "detection_period_ms: %d scan_period_ms: %d " 17759 "free_slot_expiry_timer_ms: %d", 17760 cmd->evt_type, cmd->vdev_id, cmd->current_bss_color, 17761 cmd->detection_period_ms, cmd->scan_period_ms, 17762 cmd->free_slot_expiry_time_ms); 17763 17764 wmi_mtrace(WMI_OBSS_COLOR_COLLISION_DET_CONFIG_CMDID, cmd->vdev_id, 0); 17765 if (wmi_unified_cmd_send(wmi_handle, buf, len, 17766 WMI_OBSS_COLOR_COLLISION_DET_CONFIG_CMDID)) { 17767 wmi_err("Sending OBSS color det cmd failed, vdev_id: %d", 17768 cfg_param->vdev_id); 17769 wmi_buf_free(buf); 17770 return QDF_STATUS_E_FAILURE; 17771 } 17772 17773 return QDF_STATUS_SUCCESS; 17774 } 17775 17776 /** 17777 * extract_obss_color_collision_info_tlv() - Extract bss color collision info 17778 * received from firmware. 17779 * @evt_buf: pointer to event buffer 17780 * @info: Pointer to hold bss collision info 17781 * 17782 * Return: QDF_STATUS 17783 */ 17784 static QDF_STATUS extract_obss_color_collision_info_tlv(uint8_t *evt_buf, 17785 struct wmi_obss_color_collision_info *info) 17786 { 17787 WMI_OBSS_COLOR_COLLISION_DETECTION_EVENTID_param_tlvs *param_buf; 17788 wmi_obss_color_collision_evt_fixed_param *fix_param; 17789 17790 if (!info) { 17791 wmi_err("Invalid obss color buffer"); 17792 return QDF_STATUS_E_INVAL; 17793 } 17794 17795 param_buf = (WMI_OBSS_COLOR_COLLISION_DETECTION_EVENTID_param_tlvs *) 17796 evt_buf; 17797 if (!param_buf) { 17798 wmi_err("Invalid evt_buf"); 17799 return QDF_STATUS_E_INVAL; 17800 } 17801 17802 fix_param = param_buf->fixed_param; 17803 info->vdev_id = fix_param->vdev_id; 17804 info->obss_color_bitmap_bit0to31 = 17805 fix_param->bss_color_bitmap_bit0to31; 17806 info->obss_color_bitmap_bit32to63 = 17807 fix_param->bss_color_bitmap_bit32to63; 17808 17809 switch (fix_param->evt_type) { 17810 case WMI_BSS_COLOR_COLLISION_DISABLE: 17811 info->evt_type = OBSS_COLOR_COLLISION_DETECTION_DISABLE; 17812 break; 17813 case WMI_BSS_COLOR_COLLISION_DETECTION: 17814 info->evt_type = OBSS_COLOR_COLLISION_DETECTION; 17815 break; 17816 case WMI_BSS_COLOR_FREE_SLOT_TIMER_EXPIRY: 17817 info->evt_type = OBSS_COLOR_FREE_SLOT_TIMER_EXPIRY; 17818 break; 17819 case WMI_BSS_COLOR_FREE_SLOT_AVAILABLE: 17820 info->evt_type = OBSS_COLOR_FREE_SLOT_AVAILABLE; 17821 break; 17822 default: 17823 wmi_err("Invalid event type: %d, vdev_id: %d", 17824 fix_param->evt_type, fix_param->vdev_id); 17825 return QDF_STATUS_E_FAILURE; 17826 } 17827 17828 return QDF_STATUS_SUCCESS; 17829 } 17830 17831 static void wmi_11ax_bss_color_attach_tlv(struct wmi_unified *wmi_handle) 17832 { 17833 struct wmi_ops *ops = wmi_handle->ops; 17834 17835 ops->send_obss_color_collision_cfg_cmd = 17836 send_obss_color_collision_cfg_cmd_tlv; 17837 ops->extract_obss_color_collision_info = 17838 extract_obss_color_collision_info_tlv; 17839 } 17840 17841 #if defined(WLAN_SUPPORT_FILS) || defined(CONFIG_BAND_6GHZ) 17842 static QDF_STATUS 17843 send_vdev_fils_enable_cmd_send(struct wmi_unified *wmi_handle, 17844 struct config_fils_params *param) 17845 { 17846 wmi_buf_t buf; 17847 wmi_enable_fils_cmd_fixed_param *cmd; 17848 uint8_t len = sizeof(wmi_enable_fils_cmd_fixed_param); 17849 17850 buf = wmi_buf_alloc(wmi_handle, len); 17851 if (!buf) 17852 return QDF_STATUS_E_NOMEM; 17853 17854 cmd = (wmi_enable_fils_cmd_fixed_param *)wmi_buf_data( 17855 buf); 17856 WMITLV_SET_HDR(&cmd->tlv_header, 17857 WMITLV_TAG_STRUC_wmi_enable_fils_cmd_fixed_param, 17858 WMITLV_GET_STRUCT_TLVLEN 17859 (wmi_enable_fils_cmd_fixed_param)); 17860 cmd->vdev_id = param->vdev_id; 17861 cmd->fd_period = param->fd_period; 17862 if (param->send_prb_rsp_frame) 17863 cmd->flags |= WMI_FILS_FLAGS_BITMAP_BCAST_PROBE_RSP; 17864 wmi_debug("vdev id: %d fd_period: %d cmd->Flags %d", 17865 cmd->vdev_id, cmd->fd_period, cmd->flags); 17866 wmi_mtrace(WMI_ENABLE_FILS_CMDID, cmd->vdev_id, cmd->fd_period); 17867 if (wmi_unified_cmd_send(wmi_handle, buf, len, 17868 WMI_ENABLE_FILS_CMDID)) { 17869 wmi_err("Sending FILS cmd failed, vdev_id: %d", param->vdev_id); 17870 wmi_buf_free(buf); 17871 return QDF_STATUS_E_FAILURE; 17872 } 17873 17874 return QDF_STATUS_SUCCESS; 17875 } 17876 #endif 17877 17878 #ifdef WLAN_MWS_INFO_DEBUGFS 17879 /** 17880 * send_mws_coex_status_req_cmd_tlv() - send coex cmd to fw 17881 * 17882 * @wmi_handle: wmi handle 17883 * @vdev_id: vdev id 17884 * @cmd_id: Coex command id 17885 * 17886 * Send WMI_VDEV_GET_MWS_COEX_INFO_CMDID to fw. 17887 * 17888 * Return: QDF_STATUS 17889 */ 17890 static QDF_STATUS send_mws_coex_status_req_cmd_tlv(wmi_unified_t wmi_handle, 17891 uint32_t vdev_id, 17892 uint32_t cmd_id) 17893 { 17894 wmi_buf_t buf; 17895 wmi_vdev_get_mws_coex_info_cmd_fixed_param *cmd; 17896 uint16_t len = sizeof(*cmd); 17897 int ret; 17898 17899 buf = wmi_buf_alloc(wmi_handle, len); 17900 if (!buf) { 17901 wmi_err("Failed to allocate wmi buffer"); 17902 return QDF_STATUS_E_NOMEM; 17903 } 17904 17905 cmd = (wmi_vdev_get_mws_coex_info_cmd_fixed_param *)wmi_buf_data(buf); 17906 WMITLV_SET_HDR(&cmd->tlv_header, 17907 WMITLV_TAG_STRUC_wmi_vdev_get_mws_coex_info_cmd_fixed_param, 17908 WMITLV_GET_STRUCT_TLVLEN 17909 (wmi_vdev_get_mws_coex_info_cmd_fixed_param)); 17910 cmd->vdev_id = vdev_id; 17911 cmd->cmd_id = cmd_id; 17912 wmi_mtrace(WMI_VDEV_GET_MWS_COEX_INFO_CMDID, vdev_id, 0); 17913 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 17914 WMI_VDEV_GET_MWS_COEX_INFO_CMDID); 17915 if (QDF_IS_STATUS_ERROR(ret)) { 17916 wmi_err("Failed to send set param command ret = %d", ret); 17917 wmi_buf_free(buf); 17918 } 17919 return ret; 17920 } 17921 #endif 17922 17923 #ifdef FEATURE_MEC_OFFLOAD 17924 static QDF_STATUS 17925 send_pdev_set_mec_timer_cmd_tlv(struct wmi_unified *wmi_handle, 17926 struct set_mec_timer_params *param) 17927 { 17928 wmi_pdev_mec_aging_timer_config_cmd_fixed_param *cmd; 17929 wmi_buf_t buf; 17930 int32_t len = sizeof(*cmd); 17931 17932 buf = wmi_buf_alloc(wmi_handle, len); 17933 if (!buf) { 17934 wmi_err("wmi_buf_alloc failed"); 17935 return QDF_STATUS_E_FAILURE; 17936 } 17937 cmd = (wmi_pdev_mec_aging_timer_config_cmd_fixed_param *) 17938 wmi_buf_data(buf); 17939 WMITLV_SET_HDR(&cmd->tlv_header, 17940 WMITLV_TAG_STRUC_wmi_pdev_mec_aging_timer_config_cmd_fixed_param, 17941 WMITLV_GET_STRUCT_TLVLEN( 17942 wmi_pdev_mec_aging_timer_config_cmd_fixed_param)); 17943 cmd->pdev_id = param->pdev_id; 17944 cmd->mec_aging_timer_threshold = param->mec_aging_timer_threshold; 17945 17946 wmi_mtrace(WMI_PDEV_MEC_AGING_TIMER_CONFIG_CMDID, param->vdev_id, 0); 17947 if (wmi_unified_cmd_send(wmi_handle, buf, len, 17948 WMI_PDEV_MEC_AGING_TIMER_CONFIG_CMDID)) { 17949 wmi_err("Failed to set mec aging timer param"); 17950 wmi_buf_free(buf); 17951 return QDF_STATUS_E_FAILURE; 17952 } 17953 17954 return QDF_STATUS_SUCCESS; 17955 } 17956 #endif 17957 17958 #ifdef WIFI_POS_CONVERGED 17959 /** 17960 * extract_oem_response_param_tlv() - Extract oem response params 17961 * @wmi_handle: wmi handle 17962 * @resp_buf: response buffer 17963 * @oem_resp_param: pointer to hold oem response params 17964 * 17965 * Return: QDF_STATUS_SUCCESS on success or proper error code. 17966 */ 17967 static QDF_STATUS 17968 extract_oem_response_param_tlv(wmi_unified_t wmi_handle, void *resp_buf, 17969 struct wmi_oem_response_param *oem_resp_param) 17970 { 17971 uint64_t temp_addr; 17972 WMI_OEM_RESPONSE_EVENTID_param_tlvs *param_buf = 17973 (WMI_OEM_RESPONSE_EVENTID_param_tlvs *)resp_buf; 17974 17975 if (!param_buf) { 17976 wmi_err("Invalid OEM response"); 17977 return QDF_STATUS_E_INVAL; 17978 } 17979 17980 if (param_buf->num_data) { 17981 oem_resp_param->num_data1 = param_buf->num_data; 17982 oem_resp_param->data_1 = param_buf->data; 17983 } 17984 17985 if (param_buf->num_data2) { 17986 oem_resp_param->num_data2 = param_buf->num_data2; 17987 oem_resp_param->data_2 = param_buf->data2; 17988 } 17989 17990 if (param_buf->indirect_data) { 17991 oem_resp_param->indirect_data.pdev_id = 17992 param_buf->indirect_data->pdev_id; 17993 temp_addr = (param_buf->indirect_data->addr_hi) & 0xf; 17994 oem_resp_param->indirect_data.addr = 17995 param_buf->indirect_data->addr_lo + 17996 ((uint64_t)temp_addr << 32); 17997 oem_resp_param->indirect_data.len = 17998 param_buf->indirect_data->len; 17999 } 18000 18001 return QDF_STATUS_SUCCESS; 18002 } 18003 #endif /* WIFI_POS_CONVERGED */ 18004 18005 #if defined(WIFI_POS_CONVERGED) && defined(WLAN_FEATURE_RTT_11AZ_SUPPORT) 18006 #define WLAN_PASN_LTF_KEY_SEED_REQUIRED 0x2 18007 18008 static QDF_STATUS 18009 extract_pasn_peer_create_req_event_tlv(wmi_unified_t wmi_handle, void *evt_buf, 18010 struct wifi_pos_pasn_peer_data *dst) 18011 { 18012 WMI_RTT_PASN_PEER_CREATE_REQ_EVENTID_param_tlvs *param_buf; 18013 wmi_rtt_pasn_peer_create_req_event_fixed_param *fixed_param; 18014 wmi_rtt_pasn_peer_create_req_param *buf; 18015 uint8_t security_mode, i; 18016 18017 param_buf = (WMI_RTT_PASN_PEER_CREATE_REQ_EVENTID_param_tlvs *)evt_buf; 18018 if (!param_buf) { 18019 wmi_err("Invalid peer_create req buffer"); 18020 return QDF_STATUS_E_INVAL; 18021 } 18022 18023 fixed_param = param_buf->fixed_param; 18024 18025 if (param_buf->num_rtt_pasn_peer_param > 18026 ((WMI_SVC_MSG_MAX_SIZE - sizeof(*fixed_param)) / 18027 sizeof(wmi_rtt_pasn_peer_create_req_param))) { 18028 wmi_err("Invalid TLV size"); 18029 return QDF_STATUS_E_INVAL; 18030 } 18031 18032 if (!param_buf->num_rtt_pasn_peer_param || 18033 param_buf->num_rtt_pasn_peer_param > WLAN_MAX_11AZ_PEERS) { 18034 wmi_err("Invalid num TLV:%d", 18035 param_buf->num_rtt_pasn_peer_param); 18036 return QDF_STATUS_E_INVAL; 18037 } 18038 18039 dst->vdev_id = fixed_param->vdev_id; 18040 if (dst->vdev_id >= WLAN_UMAC_PDEV_MAX_VDEVS) { 18041 wmi_err("Invalid vdev id:%d", dst->vdev_id); 18042 return QDF_STATUS_E_INVAL; 18043 } 18044 18045 buf = param_buf->rtt_pasn_peer_param; 18046 if (!buf) { 18047 wmi_err("NULL peer param TLV"); 18048 return QDF_STATUS_E_INVAL; 18049 } 18050 18051 for (i = 0; i < param_buf->num_rtt_pasn_peer_param; i++) { 18052 WMI_MAC_ADDR_TO_CHAR_ARRAY(&buf->self_mac_addr, 18053 dst->peer_info[i].self_mac.bytes); 18054 WMI_MAC_ADDR_TO_CHAR_ARRAY(&buf->dest_mac_addr, 18055 dst->peer_info[i].peer_mac.bytes); 18056 security_mode = WMI_RTT_PASN_PEER_CREATE_SECURITY_MODE_GET( 18057 buf->control_flag); 18058 if (security_mode) 18059 dst->peer_info[i].peer_type = 18060 WLAN_WIFI_POS_PASN_SECURE_PEER; 18061 else 18062 dst->peer_info[i].peer_type = 18063 WLAN_WIFI_POS_PASN_UNSECURE_PEER; 18064 if (security_mode & WLAN_PASN_LTF_KEY_SEED_REQUIRED) 18065 dst->peer_info[i].is_ltf_keyseed_required = true; 18066 18067 dst->peer_info[i].force_self_mac_usage = 18068 WMI_RTT_PASN_PEER_CREATE_FORCE_SELF_MAC_USE_GET( 18069 buf->control_flag); 18070 dst->num_peers++; 18071 buf++; 18072 } 18073 18074 return QDF_STATUS_SUCCESS; 18075 } 18076 18077 static QDF_STATUS 18078 extract_pasn_peer_delete_req_event_tlv(wmi_unified_t wmi_handle, void *evt_buf, 18079 struct wifi_pos_pasn_peer_data *dst) 18080 { 18081 WMI_RTT_PASN_PEER_DELETE_EVENTID_param_tlvs *param_buf; 18082 wmi_rtt_pasn_peer_delete_event_fixed_param *fixed_param; 18083 wmi_rtt_pasn_peer_delete_param *buf; 18084 uint8_t i; 18085 18086 param_buf = (WMI_RTT_PASN_PEER_DELETE_EVENTID_param_tlvs *)evt_buf; 18087 if (!param_buf) { 18088 wmi_err("Invalid peer_delete evt buffer"); 18089 return QDF_STATUS_E_INVAL; 18090 } 18091 18092 fixed_param = param_buf->fixed_param; 18093 18094 if (param_buf->num_rtt_pasn_peer_param > 18095 ((WMI_SVC_MSG_MAX_SIZE - sizeof(*fixed_param)) / 18096 sizeof(wmi_rtt_pasn_peer_delete_param))) { 18097 wmi_err("Invalid TLV size"); 18098 return QDF_STATUS_E_INVAL; 18099 } 18100 18101 if (!param_buf->num_rtt_pasn_peer_param || 18102 param_buf->num_rtt_pasn_peer_param > WLAN_MAX_11AZ_PEERS) { 18103 wmi_err("Invalid num TLV:%d", 18104 param_buf->num_rtt_pasn_peer_param); 18105 return QDF_STATUS_E_INVAL; 18106 } 18107 18108 dst->vdev_id = fixed_param->vdev_id; 18109 if (dst->vdev_id >= WLAN_UMAC_PDEV_MAX_VDEVS) { 18110 wmi_err("Invalid vdev id:%d", dst->vdev_id); 18111 return QDF_STATUS_E_INVAL; 18112 } 18113 18114 buf = param_buf->rtt_pasn_peer_param; 18115 if (!buf) { 18116 wmi_err("NULL peer param TLV"); 18117 return QDF_STATUS_E_INVAL; 18118 } 18119 18120 for (i = 0; i < param_buf->num_rtt_pasn_peer_param; i++) { 18121 WMI_MAC_ADDR_TO_CHAR_ARRAY(&buf->peer_mac_addr, 18122 dst->peer_info[i].peer_mac.bytes); 18123 dst->peer_info[i].control_flags = buf->control_flag; 18124 18125 dst->num_peers++; 18126 buf++; 18127 } 18128 18129 return QDF_STATUS_SUCCESS; 18130 } 18131 18132 static QDF_STATUS 18133 send_rtt_pasn_auth_status_cmd_tlv(wmi_unified_t wmi_handle, 18134 struct wlan_pasn_auth_status *data) 18135 { 18136 QDF_STATUS status; 18137 wmi_buf_t buf; 18138 wmi_rtt_pasn_auth_status_cmd_fixed_param *fixed_param; 18139 uint8_t *buf_ptr; 18140 uint8_t i; 18141 size_t len = sizeof(*fixed_param) + 18142 data->num_peers * sizeof(wmi_rtt_pasn_auth_status_param) + 18143 WMI_TLV_HDR_SIZE; 18144 18145 buf = wmi_buf_alloc(wmi_handle, len); 18146 if (!buf) { 18147 wmi_err("wmi_buf_alloc failed"); 18148 return QDF_STATUS_E_FAILURE; 18149 } 18150 buf_ptr = (uint8_t *)wmi_buf_data(buf); 18151 fixed_param = 18152 (wmi_rtt_pasn_auth_status_cmd_fixed_param *)wmi_buf_data(buf); 18153 WMITLV_SET_HDR(&fixed_param->tlv_header, 18154 WMITLV_TAG_STRUC_wmi_rtt_pasn_auth_status_cmd_fixed_param, 18155 WMITLV_GET_STRUCT_TLVLEN( 18156 wmi_rtt_pasn_auth_status_cmd_fixed_param)); 18157 buf_ptr += sizeof(*fixed_param); 18158 18159 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 18160 (data->num_peers * 18161 sizeof(wmi_rtt_pasn_auth_status_param))); 18162 buf_ptr += WMI_TLV_HDR_SIZE; 18163 18164 for (i = 0; i < data->num_peers; i++) { 18165 wmi_rtt_pasn_auth_status_param *auth_status_tlv = 18166 (wmi_rtt_pasn_auth_status_param *)buf_ptr; 18167 18168 WMITLV_SET_HDR(&auth_status_tlv->tlv_header, 18169 WMITLV_TAG_STRUC_wmi_rtt_pasn_auth_status_param, 18170 WMITLV_GET_STRUCT_TLVLEN(wmi_rtt_pasn_auth_status_param)); 18171 18172 WMI_CHAR_ARRAY_TO_MAC_ADDR(data->auth_status[i].peer_mac.bytes, 18173 &auth_status_tlv->peer_mac_addr); 18174 WMI_CHAR_ARRAY_TO_MAC_ADDR(data->auth_status[i].self_mac.bytes, 18175 &auth_status_tlv->source_mac_addr); 18176 auth_status_tlv->status = data->auth_status[i].status; 18177 wmi_debug("peer_mac: " QDF_MAC_ADDR_FMT " self_mac:" QDF_MAC_ADDR_FMT " status:%d", 18178 QDF_MAC_ADDR_REF(data->auth_status[i].peer_mac.bytes), 18179 QDF_MAC_ADDR_REF(data->auth_status[i].self_mac.bytes), 18180 auth_status_tlv->status); 18181 18182 buf_ptr += sizeof(wmi_rtt_pasn_auth_status_param); 18183 } 18184 18185 wmi_mtrace(WMI_RTT_PASN_AUTH_STATUS_CMD, 0, 0); 18186 status = wmi_unified_cmd_send(wmi_handle, buf, len, 18187 WMI_RTT_PASN_AUTH_STATUS_CMD); 18188 if (QDF_IS_STATUS_ERROR(status)) { 18189 wmi_err("Failed to send Auth status command ret = %d", status); 18190 wmi_buf_free(buf); 18191 } 18192 18193 return status; 18194 } 18195 18196 static QDF_STATUS 18197 send_rtt_pasn_deauth_cmd_tlv(wmi_unified_t wmi_handle, 18198 struct qdf_mac_addr *peer_mac) 18199 { 18200 QDF_STATUS status; 18201 wmi_buf_t buf; 18202 wmi_rtt_pasn_deauth_cmd_fixed_param *fixed_param; 18203 size_t len = sizeof(*fixed_param); 18204 18205 buf = wmi_buf_alloc(wmi_handle, len); 18206 if (!buf) { 18207 wmi_err("wmi_buf_alloc failed"); 18208 return QDF_STATUS_E_FAILURE; 18209 } 18210 fixed_param = 18211 (wmi_rtt_pasn_deauth_cmd_fixed_param *)wmi_buf_data(buf); 18212 WMITLV_SET_HDR(&fixed_param->tlv_header, 18213 WMITLV_TAG_STRUC_wmi_rtt_pasn_deauth_cmd_fixed_param, 18214 WMITLV_GET_STRUCT_TLVLEN( 18215 wmi_rtt_pasn_deauth_cmd_fixed_param)); 18216 WMI_CHAR_ARRAY_TO_MAC_ADDR(peer_mac->bytes, 18217 &fixed_param->peer_mac_addr); 18218 18219 wmi_mtrace(WMI_RTT_PASN_DEAUTH_CMD, 0, 0); 18220 status = wmi_unified_cmd_send(wmi_handle, buf, len, 18221 WMI_RTT_PASN_DEAUTH_CMD); 18222 if (QDF_IS_STATUS_ERROR(status)) { 18223 wmi_err("Failed to send pasn deauth command ret = %d", status); 18224 wmi_buf_free(buf); 18225 } 18226 18227 return status; 18228 } 18229 #endif /* WLAN_FEATURE_RTT_11AZ_SUPPORT */ 18230 18231 static QDF_STATUS 18232 send_vdev_set_ltf_key_seed_cmd_tlv(wmi_unified_t wmi_handle, 18233 struct wlan_crypto_ltf_keyseed_data *data) 18234 { 18235 QDF_STATUS status; 18236 wmi_buf_t buf; 18237 wmi_vdev_set_ltf_key_seed_cmd_fixed_param *fixed_param; 18238 uint8_t *buf_ptr; 18239 size_t len = sizeof(*fixed_param) + data->key_seed_len + 18240 WMI_TLV_HDR_SIZE; 18241 18242 buf = wmi_buf_alloc(wmi_handle, len); 18243 if (!buf) { 18244 wmi_err("wmi_buf_alloc failed"); 18245 return QDF_STATUS_E_FAILURE; 18246 } 18247 18248 buf_ptr = (uint8_t *)wmi_buf_data(buf); 18249 fixed_param = 18250 (wmi_vdev_set_ltf_key_seed_cmd_fixed_param *)wmi_buf_data(buf); 18251 WMITLV_SET_HDR(&fixed_param->tlv_header, 18252 WMITLV_TAG_STRUC_wmi_vdev_set_ltf_key_seed_cmd_fixed_param, 18253 WMITLV_GET_STRUCT_TLVLEN( 18254 wmi_vdev_set_ltf_key_seed_cmd_fixed_param)); 18255 18256 fixed_param->vdev_id = data->vdev_id; 18257 WMI_CHAR_ARRAY_TO_MAC_ADDR(data->peer_mac_addr.bytes, 18258 &fixed_param->peer_macaddr); 18259 fixed_param->key_seed_len = data->key_seed_len; 18260 fixed_param->rsn_authmode = data->rsn_authmode; 18261 18262 buf_ptr += sizeof(*fixed_param); 18263 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, 18264 (fixed_param->key_seed_len * sizeof(A_UINT8))); 18265 buf_ptr += WMI_TLV_HDR_SIZE; 18266 18267 qdf_mem_copy(buf_ptr, data->key_seed, fixed_param->key_seed_len); 18268 18269 wmi_mtrace(WMI_VDEV_SET_LTF_KEY_SEED_CMDID, 0, 0); 18270 status = wmi_unified_cmd_send(wmi_handle, buf, len, 18271 WMI_VDEV_SET_LTF_KEY_SEED_CMDID); 18272 if (QDF_IS_STATUS_ERROR(status)) { 18273 wmi_err("Failed to send ltf keyseed command ret = %d", status); 18274 wmi_buf_free(buf); 18275 } 18276 18277 return status; 18278 } 18279 18280 /** 18281 * extract_hw_mode_resp_event_status_tlv() - Extract HW mode change status 18282 * @wmi_handle: wmi handle 18283 * @evt_buf: pointer to event buffer 18284 * @cmd_status: status of HW mode change command 18285 * 18286 * Return: QDF_STATUS_SUCCESS on success or proper error code. 18287 */ 18288 static QDF_STATUS 18289 extract_hw_mode_resp_event_status_tlv(wmi_unified_t wmi_handle, void *evt_buf, 18290 uint32_t *cmd_status) 18291 { 18292 WMI_PDEV_SET_HW_MODE_RESP_EVENTID_param_tlvs *param_buf; 18293 wmi_pdev_set_hw_mode_response_event_fixed_param *fixed_param; 18294 18295 param_buf = (WMI_PDEV_SET_HW_MODE_RESP_EVENTID_param_tlvs *)evt_buf; 18296 if (!param_buf) { 18297 wmi_err("Invalid mode change event buffer"); 18298 return QDF_STATUS_E_INVAL; 18299 } 18300 18301 fixed_param = param_buf->fixed_param; 18302 if (!fixed_param) { 18303 wmi_err("Invalid fixed param"); 18304 return QDF_STATUS_E_INVAL; 18305 } 18306 18307 *cmd_status = fixed_param->status; 18308 return QDF_STATUS_SUCCESS; 18309 } 18310 18311 #ifdef FEATURE_ANI_LEVEL_REQUEST 18312 static QDF_STATUS send_ani_level_cmd_tlv(wmi_unified_t wmi_handle, 18313 uint32_t *freqs, 18314 uint8_t num_freqs) 18315 { 18316 wmi_buf_t buf; 18317 wmi_get_channel_ani_cmd_fixed_param *cmd; 18318 QDF_STATUS ret; 18319 uint32_t len; 18320 A_UINT32 *chan_list; 18321 uint8_t i, *buf_ptr; 18322 18323 len = sizeof(wmi_get_channel_ani_cmd_fixed_param) + 18324 WMI_TLV_HDR_SIZE + 18325 num_freqs * sizeof(A_UINT32); 18326 18327 buf = wmi_buf_alloc(wmi_handle, len); 18328 if (!buf) 18329 return QDF_STATUS_E_FAILURE; 18330 18331 buf_ptr = (uint8_t *)wmi_buf_data(buf); 18332 cmd = (wmi_get_channel_ani_cmd_fixed_param *)buf_ptr; 18333 WMITLV_SET_HDR(&cmd->tlv_header, 18334 WMITLV_TAG_STRUC_wmi_get_channel_ani_cmd_fixed_param, 18335 WMITLV_GET_STRUCT_TLVLEN( 18336 wmi_get_channel_ani_cmd_fixed_param)); 18337 18338 buf_ptr += sizeof(wmi_get_channel_ani_cmd_fixed_param); 18339 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, 18340 (num_freqs * sizeof(A_UINT32))); 18341 18342 chan_list = (A_UINT32 *)(buf_ptr + WMI_TLV_HDR_SIZE); 18343 for (i = 0; i < num_freqs; i++) { 18344 chan_list[i] = freqs[i]; 18345 wmi_debug("Requesting ANI for channel[%d]", chan_list[i]); 18346 } 18347 18348 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 18349 WMI_GET_CHANNEL_ANI_CMDID); 18350 18351 if (QDF_IS_STATUS_ERROR(ret)) { 18352 wmi_err("WMI_GET_CHANNEL_ANI_CMDID send error %d", ret); 18353 wmi_buf_free(buf); 18354 } 18355 18356 return ret; 18357 } 18358 18359 static QDF_STATUS extract_ani_level_tlv(uint8_t *evt_buf, 18360 struct wmi_host_ani_level_event **info, 18361 uint32_t *num_freqs) 18362 { 18363 WMI_GET_CHANNEL_ANI_EVENTID_param_tlvs *param_buf; 18364 wmi_get_channel_ani_event_fixed_param *fixed_param; 18365 wmi_channel_ani_info_tlv_param *tlv_params; 18366 uint8_t *buf_ptr, i; 18367 18368 param_buf = (WMI_GET_CHANNEL_ANI_EVENTID_param_tlvs *)evt_buf; 18369 if (!param_buf) { 18370 wmi_err("Invalid ani level event buffer"); 18371 return QDF_STATUS_E_INVAL; 18372 } 18373 18374 fixed_param = 18375 (wmi_get_channel_ani_event_fixed_param *)param_buf->fixed_param; 18376 if (!fixed_param) { 18377 wmi_err("Invalid fixed param"); 18378 return QDF_STATUS_E_INVAL; 18379 } 18380 18381 buf_ptr = (uint8_t *)fixed_param; 18382 buf_ptr += sizeof(wmi_get_channel_ani_event_fixed_param); 18383 buf_ptr += WMI_TLV_HDR_SIZE; 18384 18385 *num_freqs = param_buf->num_ani_info; 18386 if (*num_freqs > MAX_NUM_FREQS_FOR_ANI_LEVEL) { 18387 wmi_err("Invalid number of freqs received"); 18388 return QDF_STATUS_E_INVAL; 18389 } 18390 18391 *info = qdf_mem_malloc(*num_freqs * 18392 sizeof(struct wmi_host_ani_level_event)); 18393 if (!(*info)) 18394 return QDF_STATUS_E_NOMEM; 18395 18396 tlv_params = (wmi_channel_ani_info_tlv_param *)buf_ptr; 18397 for (i = 0; i < param_buf->num_ani_info; i++) { 18398 (*info)[i].ani_level = tlv_params->ani_level; 18399 (*info)[i].chan_freq = tlv_params->chan_freq; 18400 tlv_params++; 18401 } 18402 18403 return QDF_STATUS_SUCCESS; 18404 } 18405 #endif /* FEATURE_ANI_LEVEL_REQUEST */ 18406 18407 #ifdef WLAN_FEATURE_ROAM_OFFLOAD 18408 /** 18409 * convert_wtc_scan_mode() - Function to convert TLV specific 18410 * ROAM_TRIGGER_SCAN_MODE scan mode to unified Roam trigger scan mode enum 18411 * @scan_mode: scan freq scheme coming from firmware 18412 * 18413 * Return: ROAM_TRIGGER_SCAN_MODE 18414 */ 18415 static enum roam_scan_freq_scheme 18416 convert_wtc_scan_mode(WMI_ROAM_TRIGGER_SCAN_MODE scan_mode) 18417 { 18418 switch (scan_mode) { 18419 case ROAM_TRIGGER_SCAN_MODE_NO_SCAN_DISCONNECTION: 18420 return ROAM_SCAN_FREQ_SCHEME_NO_SCAN; 18421 case ROAM_TRIGGER_SCAN_MODE_PARTIAL: 18422 return ROAM_SCAN_FREQ_SCHEME_PARTIAL_SCAN; 18423 case ROAM_TRIGGER_SCAN_MODE_FULL: 18424 return ROAM_SCAN_FREQ_SCHEME_FULL_SCAN; 18425 default: 18426 return ROAM_SCAN_FREQ_SCHEME_NONE; 18427 } 18428 } 18429 18430 static uint32_t wmi_convert_fw_to_cm_trig_reason(uint32_t fw_trig_reason) 18431 { 18432 switch (fw_trig_reason) { 18433 case WMI_ROAM_TRIGGER_REASON_NONE: 18434 return ROAM_TRIGGER_REASON_NONE; 18435 case WMI_ROAM_TRIGGER_REASON_PER: 18436 return ROAM_TRIGGER_REASON_PER; 18437 case WMI_ROAM_TRIGGER_REASON_BMISS: 18438 return ROAM_TRIGGER_REASON_BMISS; 18439 case WMI_ROAM_TRIGGER_REASON_LOW_RSSI: 18440 return ROAM_TRIGGER_REASON_LOW_RSSI; 18441 case WMI_ROAM_TRIGGER_REASON_HIGH_RSSI: 18442 return ROAM_TRIGGER_REASON_HIGH_RSSI; 18443 case WMI_ROAM_TRIGGER_REASON_PERIODIC: 18444 return ROAM_TRIGGER_REASON_PERIODIC; 18445 case WMI_ROAM_TRIGGER_REASON_MAWC: 18446 return ROAM_TRIGGER_REASON_MAWC; 18447 case WMI_ROAM_TRIGGER_REASON_DENSE: 18448 return ROAM_TRIGGER_REASON_DENSE; 18449 case WMI_ROAM_TRIGGER_REASON_BACKGROUND: 18450 return ROAM_TRIGGER_REASON_BACKGROUND; 18451 case WMI_ROAM_TRIGGER_REASON_FORCED: 18452 return ROAM_TRIGGER_REASON_FORCED; 18453 case WMI_ROAM_TRIGGER_REASON_BTM: 18454 return ROAM_TRIGGER_REASON_BTM; 18455 case WMI_ROAM_TRIGGER_REASON_UNIT_TEST: 18456 return ROAM_TRIGGER_REASON_UNIT_TEST; 18457 case WMI_ROAM_TRIGGER_REASON_BSS_LOAD: 18458 return ROAM_TRIGGER_REASON_BSS_LOAD; 18459 case WMI_ROAM_TRIGGER_REASON_DEAUTH: 18460 return ROAM_TRIGGER_REASON_DEAUTH; 18461 case WMI_ROAM_TRIGGER_REASON_IDLE: 18462 return ROAM_TRIGGER_REASON_IDLE; 18463 case WMI_ROAM_TRIGGER_REASON_STA_KICKOUT: 18464 return ROAM_TRIGGER_REASON_STA_KICKOUT; 18465 case WMI_ROAM_TRIGGER_REASON_ESS_RSSI: 18466 return ROAM_TRIGGER_REASON_ESS_RSSI; 18467 case WMI_ROAM_TRIGGER_REASON_WTC_BTM: 18468 return ROAM_TRIGGER_REASON_WTC_BTM; 18469 case WMI_ROAM_TRIGGER_REASON_PMK_TIMEOUT: 18470 return ROAM_TRIGGER_REASON_PMK_TIMEOUT; 18471 case WMI_ROAM_TRIGGER_REASON_BTC: 18472 return ROAM_TRIGGER_REASON_BTC; 18473 case WMI_ROAM_TRIGGER_EXT_REASON_MAX: 18474 return ROAM_TRIGGER_REASON_MAX; 18475 default: 18476 return ROAM_TRIGGER_REASON_NONE; 18477 } 18478 } 18479 18480 /** 18481 * extract_roam_11kv_candidate_info - Extract btm candidate info 18482 * @wmi_handle: wmi_handle 18483 * @evt_buf: Event buffer 18484 * @dst_info: Destination buffer 18485 * @btm_idx: BTM index 18486 * @num_cand: Number of candidates 18487 * 18488 * Return: QDF_STATUS 18489 */ 18490 static QDF_STATUS 18491 extract_roam_11kv_candidate_info(wmi_unified_t wmi_handle, void *evt_buf, 18492 struct wmi_btm_req_candidate_info *dst_info, 18493 uint8_t btm_idx, uint16_t num_cand) 18494 { 18495 WMI_ROAM_STATS_EVENTID_param_tlvs *param_buf; 18496 wmi_roam_btm_request_candidate_info *src_data; 18497 uint8_t i; 18498 18499 param_buf = (WMI_ROAM_STATS_EVENTID_param_tlvs *)evt_buf; 18500 if (!param_buf || !param_buf->roam_btm_request_candidate_info || 18501 !param_buf->num_roam_btm_request_candidate_info || 18502 (btm_idx + 18503 num_cand) > param_buf->num_roam_btm_request_candidate_info) 18504 return QDF_STATUS_SUCCESS; 18505 18506 src_data = ¶m_buf->roam_btm_request_candidate_info[btm_idx]; 18507 if (num_cand > WLAN_MAX_BTM_CANDIDATE) 18508 num_cand = WLAN_MAX_BTM_CANDIDATE; 18509 for (i = 0; i < num_cand; i++) { 18510 WMI_MAC_ADDR_TO_CHAR_ARRAY(&src_data->btm_candidate_bssid, 18511 dst_info->candidate_bssid.bytes); 18512 dst_info->preference = src_data->preference; 18513 src_data++; 18514 dst_info++; 18515 } 18516 18517 return QDF_STATUS_SUCCESS; 18518 } 18519 18520 static enum roam_trigger_sub_reason 18521 wmi_convert_roam_sub_reason(WMI_ROAM_TRIGGER_SUB_REASON_ID subreason) 18522 { 18523 switch (subreason) { 18524 case WMI_ROAM_TRIGGER_SUB_REASON_PERIODIC_TIMER: 18525 return ROAM_TRIGGER_SUB_REASON_PERIODIC_TIMER; 18526 case WMI_ROAM_TRIGGER_SUB_REASON_INACTIVITY_TIMER: 18527 return ROAM_TRIGGER_SUB_REASON_INACTIVITY_TIMER_LOW_RSSI; 18528 case WMI_ROAM_TRIGGER_SUB_REASON_BTM_DI_TIMER: 18529 return ROAM_TRIGGER_SUB_REASON_BTM_DI_TIMER; 18530 case WMI_ROAM_TRIGGER_SUB_REASON_FULL_SCAN: 18531 return ROAM_TRIGGER_SUB_REASON_FULL_SCAN; 18532 case WMI_ROAM_TRIGGER_SUB_REASON_LOW_RSSI_PERIODIC: 18533 return ROAM_TRIGGER_SUB_REASON_LOW_RSSI_PERIODIC; 18534 case WMI_ROAM_TRIGGER_SUB_REASON_CU_PERIODIC: 18535 return ROAM_TRIGGER_SUB_REASON_CU_PERIODIC; 18536 case WMI_ROAM_TRIGGER_SUB_REASON_PERIODIC_TIMER_AFTER_INACTIVITY: 18537 return ROAM_TRIGGER_SUB_REASON_PERIODIC_TIMER_AFTER_INACTIVITY; 18538 case WMI_ROAM_TRIGGER_SUB_REASON_PERIODIC_TIMER_AFTER_INACTIVITY_CU: 18539 return ROAM_TRIGGER_SUB_REASON_PERIODIC_TIMER_AFTER_INACTIVITY_CU; 18540 case WMI_ROAM_TRIGGER_SUB_REASON_INACTIVITY_TIMER_CU: 18541 return ROAM_TRIGGER_SUB_REASON_INACTIVITY_TIMER_CU; 18542 default: 18543 break; 18544 } 18545 18546 return 0; 18547 } 18548 18549 /** 18550 * extract_roam_trigger_stats_tlv() - Extract the Roam trigger stats 18551 * from the WMI_ROAM_STATS_EVENTID 18552 * @wmi_handle: wmi handle 18553 * @evt_buf: Pointer to the event buffer 18554 * @trig: Pointer to destination structure to fill data 18555 * @idx: TLV id 18556 * @btm_idx: BTM index 18557 */ 18558 static QDF_STATUS 18559 extract_roam_trigger_stats_tlv(wmi_unified_t wmi_handle, void *evt_buf, 18560 struct wmi_roam_trigger_info *trig, uint8_t idx, 18561 uint8_t btm_idx) 18562 { 18563 WMI_ROAM_STATS_EVENTID_param_tlvs *param_buf; 18564 wmi_roam_trigger_reason *src_data = NULL; 18565 uint32_t trig_reason; 18566 18567 param_buf = (WMI_ROAM_STATS_EVENTID_param_tlvs *)evt_buf; 18568 if (!param_buf || !param_buf->roam_trigger_reason) 18569 return QDF_STATUS_E_FAILURE; 18570 18571 src_data = ¶m_buf->roam_trigger_reason[idx]; 18572 18573 trig->present = true; 18574 trig_reason = src_data->trigger_reason; 18575 trig->trigger_reason = wmi_convert_fw_to_cm_trig_reason(trig_reason); 18576 trig->trigger_sub_reason = 18577 wmi_convert_roam_sub_reason(src_data->trigger_sub_reason); 18578 trig->current_rssi = src_data->current_rssi; 18579 trig->timestamp = src_data->timestamp; 18580 18581 switch (trig_reason) { 18582 case WMI_ROAM_TRIGGER_REASON_PER: 18583 case WMI_ROAM_TRIGGER_REASON_BMISS: 18584 case WMI_ROAM_TRIGGER_REASON_HIGH_RSSI: 18585 case WMI_ROAM_TRIGGER_REASON_MAWC: 18586 case WMI_ROAM_TRIGGER_REASON_DENSE: 18587 case WMI_ROAM_TRIGGER_REASON_BACKGROUND: 18588 case WMI_ROAM_TRIGGER_REASON_IDLE: 18589 case WMI_ROAM_TRIGGER_REASON_FORCED: 18590 case WMI_ROAM_TRIGGER_REASON_UNIT_TEST: 18591 case WMI_ROAM_TRIGGER_REASON_BTC: 18592 return QDF_STATUS_SUCCESS; 18593 18594 case WMI_ROAM_TRIGGER_REASON_BTM: 18595 trig->btm_trig_data.btm_request_mode = 18596 src_data->btm_request_mode; 18597 trig->btm_trig_data.disassoc_timer = 18598 src_data->disassoc_imminent_timer; 18599 trig->btm_trig_data.validity_interval = 18600 src_data->validity_internal; 18601 trig->btm_trig_data.candidate_list_count = 18602 src_data->candidate_list_count; 18603 trig->btm_trig_data.btm_resp_status = 18604 src_data->btm_response_status_code; 18605 trig->btm_trig_data.btm_bss_termination_timeout = 18606 src_data->btm_bss_termination_timeout; 18607 trig->btm_trig_data.btm_mbo_assoc_retry_timeout = 18608 src_data->btm_mbo_assoc_retry_timeout; 18609 trig->btm_trig_data.token = src_data->btm_req_dialog_token; 18610 if ((btm_idx + trig->btm_trig_data.candidate_list_count) <= 18611 param_buf->num_roam_btm_request_candidate_info) 18612 extract_roam_11kv_candidate_info( 18613 wmi_handle, evt_buf, 18614 trig->btm_trig_data.btm_cand, 18615 btm_idx, 18616 src_data->candidate_list_count); 18617 18618 return QDF_STATUS_SUCCESS; 18619 18620 case WMI_ROAM_TRIGGER_REASON_BSS_LOAD: 18621 trig->cu_trig_data.cu_load = src_data->cu_load; 18622 return QDF_STATUS_SUCCESS; 18623 18624 case WMI_ROAM_TRIGGER_REASON_DEAUTH: 18625 trig->deauth_trig_data.type = src_data->deauth_type; 18626 trig->deauth_trig_data.reason = src_data->deauth_reason; 18627 return QDF_STATUS_SUCCESS; 18628 18629 case WMI_ROAM_TRIGGER_REASON_PERIODIC: 18630 case WMI_ROAM_TRIGGER_REASON_LOW_RSSI: 18631 trig->rssi_trig_data.threshold = src_data->roam_rssi_threshold; 18632 return QDF_STATUS_SUCCESS; 18633 18634 case WMI_ROAM_TRIGGER_REASON_WTC_BTM: 18635 trig->wtc_btm_trig_data.roaming_mode = 18636 src_data->vendor_specific1[0]; 18637 trig->wtc_btm_trig_data.vsie_trigger_reason = 18638 src_data->vendor_specific1[1]; 18639 trig->wtc_btm_trig_data.sub_code = 18640 src_data->vendor_specific1[2]; 18641 trig->wtc_btm_trig_data.wtc_mode = 18642 src_data->vendor_specific1[3]; 18643 trig->wtc_btm_trig_data.wtc_scan_mode = 18644 convert_wtc_scan_mode(src_data->vendor_specific1[4]); 18645 trig->wtc_btm_trig_data.wtc_rssi_th = 18646 src_data->vendor_specific1[5]; 18647 trig->wtc_btm_trig_data.wtc_candi_rssi_th = 18648 src_data->vendor_specific1[6]; 18649 18650 trig->wtc_btm_trig_data.wtc_candi_rssi_ext_present = 18651 src_data->vendor_specific2[0]; 18652 trig->wtc_btm_trig_data.wtc_candi_rssi_th_5g = 18653 src_data->vendor_specific2[1]; 18654 trig->wtc_btm_trig_data.wtc_candi_rssi_th_6g = 18655 src_data->vendor_specific2[2]; 18656 trig->wtc_btm_trig_data.duration = 18657 src_data->vendor_specific2[3]; 18658 18659 return QDF_STATUS_SUCCESS; 18660 default: 18661 return QDF_STATUS_SUCCESS; 18662 } 18663 18664 return QDF_STATUS_SUCCESS; 18665 } 18666 18667 /** 18668 * extract_roam_scan_ap_stats_tlv() - Extract the Roam trigger stats 18669 * from the WMI_ROAM_STATS_EVENTID 18670 * @wmi_handle: wmi handle 18671 * @evt_buf: Pointer to the event buffer 18672 * @dst: Pointer to destination structure to fill data 18673 * @ap_idx: TLV index for this roam scan 18674 * @num_cand: number of candidates list in the roam scan 18675 */ 18676 static QDF_STATUS 18677 extract_roam_scan_ap_stats_tlv(wmi_unified_t wmi_handle, void *evt_buf, 18678 struct wmi_roam_candidate_info *dst, 18679 uint8_t ap_idx, uint16_t num_cand) 18680 { 18681 WMI_ROAM_STATS_EVENTID_param_tlvs *param_buf; 18682 wmi_roam_ap_info *src = NULL; 18683 uint8_t i; 18684 18685 param_buf = (WMI_ROAM_STATS_EVENTID_param_tlvs *)evt_buf; 18686 if (!param_buf) { 18687 wmi_err("Param buf is NULL"); 18688 return QDF_STATUS_E_FAILURE; 18689 } 18690 18691 if (ap_idx >= param_buf->num_roam_ap_info) { 18692 wmi_err("Invalid roam scan AP tlv ap_idx:%d total_ap:%d", 18693 ap_idx, param_buf->num_roam_ap_info); 18694 return QDF_STATUS_E_FAILURE; 18695 } 18696 18697 src = ¶m_buf->roam_ap_info[ap_idx]; 18698 18699 for (i = 0; i < num_cand; i++) { 18700 WMI_MAC_ADDR_TO_CHAR_ARRAY(&src->bssid, dst->bssid.bytes); 18701 dst->type = src->candidate_type; 18702 dst->freq = src->channel; 18703 dst->etp = src->etp; 18704 dst->rssi = src->rssi; 18705 dst->rssi_score = src->rssi_score; 18706 dst->cu_load = src->cu_load; 18707 dst->cu_score = src->cu_score; 18708 dst->total_score = src->total_score; 18709 dst->timestamp = src->timestamp; 18710 dst->dl_reason = src->bl_reason; 18711 dst->dl_source = src->bl_source; 18712 dst->dl_timestamp = src->bl_timestamp; 18713 dst->dl_original_timeout = src->bl_original_timeout; 18714 18715 src++; 18716 dst++; 18717 } 18718 18719 return QDF_STATUS_SUCCESS; 18720 } 18721 18722 /** 18723 * extract_roam_scan_stats_tlv() - Extract the Roam trigger stats 18724 * from the WMI_ROAM_STATS_EVENTID 18725 * @wmi_handle: wmi handle 18726 * @evt_buf: Pointer to the event buffer 18727 * @dst: Pointer to destination structure to fill data 18728 * @idx: TLV id 18729 * @chan_idx: Index of the channel tlv for the current roam trigger 18730 * @ap_idx: Index of the candidate AP TLV for the current roam trigger 18731 */ 18732 static QDF_STATUS 18733 extract_roam_scan_stats_tlv(wmi_unified_t wmi_handle, void *evt_buf, 18734 struct wmi_roam_scan_data *dst, uint8_t idx, 18735 uint8_t chan_idx, uint8_t ap_idx) 18736 { 18737 WMI_ROAM_STATS_EVENTID_param_tlvs *param_buf; 18738 wmi_roam_scan_info *src_data = NULL; 18739 wmi_roam_scan_channel_info *src_chan = NULL; 18740 QDF_STATUS status; 18741 uint8_t i; 18742 18743 param_buf = (WMI_ROAM_STATS_EVENTID_param_tlvs *)evt_buf; 18744 if (!param_buf || !param_buf->roam_scan_info || 18745 idx >= param_buf->num_roam_scan_info) 18746 return QDF_STATUS_E_FAILURE; 18747 18748 src_data = ¶m_buf->roam_scan_info[idx]; 18749 18750 dst->present = true; 18751 dst->type = src_data->roam_scan_type; 18752 dst->num_chan = src_data->roam_scan_channel_count; 18753 dst->next_rssi_threshold = src_data->next_rssi_trigger_threshold; 18754 dst->is_btcoex_active = WMI_GET_BTCONNECT_STATUS(src_data->flags); 18755 dst->frame_info_count = src_data->frame_info_count; 18756 if (dst->frame_info_count > WLAN_ROAM_MAX_FRAME_INFO) 18757 dst->frame_info_count = WLAN_ROAM_MAX_FRAME_INFO; 18758 18759 /* Read the channel data only for dst->type is 0 (partial scan) */ 18760 if (dst->num_chan && !dst->type && param_buf->num_roam_scan_chan_info && 18761 chan_idx < param_buf->num_roam_scan_chan_info) { 18762 if (dst->num_chan > MAX_ROAM_SCAN_CHAN) 18763 dst->num_chan = MAX_ROAM_SCAN_CHAN; 18764 18765 src_chan = ¶m_buf->roam_scan_chan_info[chan_idx]; 18766 for (i = 0; i < dst->num_chan; i++) { 18767 dst->chan_freq[i] = src_chan->channel; 18768 src_chan++; 18769 } 18770 } 18771 18772 if (!src_data->roam_ap_count || !param_buf->num_roam_ap_info) 18773 return QDF_STATUS_SUCCESS; 18774 18775 dst->num_ap = src_data->roam_ap_count; 18776 if (dst->num_ap > MAX_ROAM_CANDIDATE_AP) 18777 dst->num_ap = MAX_ROAM_CANDIDATE_AP; 18778 18779 status = extract_roam_scan_ap_stats_tlv(wmi_handle, evt_buf, dst->ap, 18780 ap_idx, dst->num_ap); 18781 if (QDF_IS_STATUS_ERROR(status)) { 18782 wmi_err("Extract candidate stats for tlv[%d] failed", idx); 18783 return status; 18784 } 18785 18786 return QDF_STATUS_SUCCESS; 18787 } 18788 18789 /** 18790 * wlan_roam_fail_reason_code() - Convert FW enum to Host enum 18791 * @wmi_roam_fail_reason: roam fail enum 18792 * 18793 * Return: Roaming failure reason codes 18794 */ 18795 static enum wlan_roam_failure_reason_code 18796 wlan_roam_fail_reason_code(uint16_t wmi_roam_fail_reason) 18797 { 18798 switch (wmi_roam_fail_reason) { 18799 case WMI_ROAM_FAIL_REASON_NO_SCAN_START: 18800 return ROAM_FAIL_REASON_NO_SCAN_START; 18801 case WMI_ROAM_FAIL_REASON_NO_AP_FOUND: 18802 return ROAM_FAIL_REASON_NO_AP_FOUND; 18803 case WMI_ROAM_FAIL_REASON_NO_CAND_AP_FOUND: 18804 return ROAM_FAIL_REASON_NO_CAND_AP_FOUND; 18805 case WMI_ROAM_FAIL_REASON_HOST: 18806 return ROAM_FAIL_REASON_HOST; 18807 case WMI_ROAM_FAIL_REASON_AUTH_SEND: 18808 return ROAM_FAIL_REASON_AUTH_SEND; 18809 case WMI_ROAM_FAIL_REASON_AUTH_RECV: 18810 return ROAM_FAIL_REASON_AUTH_RECV; 18811 case WMI_ROAM_FAIL_REASON_NO_AUTH_RESP: 18812 return ROAM_FAIL_REASON_NO_AUTH_RESP; 18813 case WMI_ROAM_FAIL_REASON_REASSOC_SEND: 18814 return ROAM_FAIL_REASON_REASSOC_SEND; 18815 case WMI_ROAM_FAIL_REASON_REASSOC_RECV: 18816 return ROAM_FAIL_REASON_REASSOC_RECV; 18817 case WMI_ROAM_FAIL_REASON_NO_REASSOC_RESP: 18818 return ROAM_FAIL_REASON_NO_REASSOC_RESP; 18819 case WMI_ROAM_FAIL_REASON_EAPOL_TIMEOUT: 18820 return ROAM_FAIL_REASON_EAPOL_TIMEOUT; 18821 case WMI_ROAM_FAIL_REASON_MLME: 18822 return ROAM_FAIL_REASON_MLME; 18823 case WMI_ROAM_FAIL_REASON_INTERNAL_ABORT: 18824 return ROAM_FAIL_REASON_INTERNAL_ABORT; 18825 case WMI_ROAM_FAIL_REASON_SCAN_START: 18826 return ROAM_FAIL_REASON_SCAN_START; 18827 case WMI_ROAM_FAIL_REASON_AUTH_NO_ACK: 18828 return ROAM_FAIL_REASON_AUTH_NO_ACK; 18829 case WMI_ROAM_FAIL_REASON_AUTH_INTERNAL_DROP: 18830 return ROAM_FAIL_REASON_AUTH_INTERNAL_DROP; 18831 case WMI_ROAM_FAIL_REASON_REASSOC_NO_ACK: 18832 return ROAM_FAIL_REASON_REASSOC_NO_ACK; 18833 case WMI_ROAM_FAIL_REASON_REASSOC_INTERNAL_DROP: 18834 return ROAM_FAIL_REASON_REASSOC_INTERNAL_DROP; 18835 case WMI_ROAM_FAIL_REASON_EAPOL_M2_SEND: 18836 return ROAM_FAIL_REASON_EAPOL_M2_SEND; 18837 case WMI_ROAM_FAIL_REASON_EAPOL_M2_INTERNAL_DROP: 18838 return ROAM_FAIL_REASON_EAPOL_M2_INTERNAL_DROP; 18839 case WMI_ROAM_FAIL_REASON_EAPOL_M2_NO_ACK: 18840 return ROAM_FAIL_REASON_EAPOL_M2_NO_ACK; 18841 case WMI_ROAM_FAIL_REASON_EAPOL_M3_TIMEOUT: 18842 return ROAM_FAIL_REASON_EAPOL_M3_TIMEOUT; 18843 case WMI_ROAM_FAIL_REASON_EAPOL_M4_SEND: 18844 return ROAM_FAIL_REASON_EAPOL_M4_SEND; 18845 case WMI_ROAM_FAIL_REASON_EAPOL_M4_INTERNAL_DROP: 18846 return ROAM_FAIL_REASON_EAPOL_M4_INTERNAL_DROP; 18847 case WMI_ROAM_FAIL_REASON_EAPOL_M4_NO_ACK: 18848 return ROAM_FAIL_REASON_EAPOL_M4_NO_ACK; 18849 case WMI_ROAM_FAIL_REASON_NO_SCAN_FOR_FINAL_BMISS: 18850 return ROAM_FAIL_REASON_NO_SCAN_FOR_FINAL_BMISS; 18851 case WMI_ROAM_FAIL_REASON_DISCONNECT: 18852 return ROAM_FAIL_REASON_DISCONNECT; 18853 case WMI_ROAM_FAIL_REASON_SYNC: 18854 return ROAM_FAIL_REASON_SYNC; 18855 case WMI_ROAM_FAIL_REASON_SAE_INVALID_PMKID: 18856 return ROAM_FAIL_REASON_SAE_INVALID_PMKID; 18857 case WMI_ROAM_FAIL_REASON_SAE_PREAUTH_TIMEOUT: 18858 return ROAM_FAIL_REASON_SAE_PREAUTH_TIMEOUT; 18859 case WMI_ROAM_FAIL_REASON_SAE_PREAUTH_FAIL: 18860 return ROAM_FAIL_REASON_SAE_PREAUTH_FAIL; 18861 case WMI_ROAM_FAIL_REASON_UNABLE_TO_START_ROAM_HO: 18862 return ROAM_FAIL_REASON_UNABLE_TO_START_ROAM_HO; 18863 default: 18864 return ROAM_FAIL_REASON_UNKNOWN; 18865 } 18866 } 18867 18868 /** 18869 * extract_roam_result_stats_tlv() - Extract the Roam trigger stats 18870 * from the WMI_ROAM_STATS_EVENTID 18871 * @wmi_handle: wmi handle 18872 * @evt_buf: Pointer to the event buffer 18873 * @dst: Pointer to destination structure to fill data 18874 * @idx: TLV id 18875 */ 18876 static QDF_STATUS 18877 extract_roam_result_stats_tlv(wmi_unified_t wmi_handle, void *evt_buf, 18878 struct wmi_roam_result *dst, uint8_t idx) 18879 { 18880 WMI_ROAM_STATS_EVENTID_param_tlvs *param_buf; 18881 wmi_roam_result *src_data = NULL; 18882 18883 param_buf = (WMI_ROAM_STATS_EVENTID_param_tlvs *)evt_buf; 18884 if (!param_buf || !param_buf->roam_result || 18885 idx >= param_buf->num_roam_result) 18886 return QDF_STATUS_E_FAILURE; 18887 18888 src_data = ¶m_buf->roam_result[idx]; 18889 18890 dst->present = true; 18891 dst->status = src_data->roam_status; 18892 dst->timestamp = src_data->timestamp; 18893 dst->fail_reason = 18894 wlan_roam_fail_reason_code(src_data->roam_fail_reason); 18895 WMI_MAC_ADDR_TO_CHAR_ARRAY(&src_data->bssid, dst->fail_bssid.bytes); 18896 18897 return QDF_STATUS_SUCCESS; 18898 } 18899 18900 /** 18901 * extract_roam_11kv_stats_tlv() - Extract the Roam trigger stats 18902 * from the WMI_ROAM_STATS_EVENTID 18903 * @wmi_handle: wmi handle 18904 * @evt_buf: Pointer to the event buffer 18905 * @dst: Pointer to destination structure to fill data 18906 * @idx: TLV id 18907 * @rpt_idx: Neighbor report Channel index 18908 */ 18909 static QDF_STATUS 18910 extract_roam_11kv_stats_tlv(wmi_unified_t wmi_handle, void *evt_buf, 18911 struct wmi_neighbor_report_data *dst, 18912 uint8_t idx, uint8_t rpt_idx) 18913 { 18914 WMI_ROAM_STATS_EVENTID_param_tlvs *param_buf; 18915 wmi_roam_neighbor_report_info *src_data = NULL; 18916 wmi_roam_neighbor_report_channel_info *src_freq = NULL; 18917 uint8_t i; 18918 18919 param_buf = (WMI_ROAM_STATS_EVENTID_param_tlvs *)evt_buf; 18920 if (!param_buf || !param_buf->roam_neighbor_report_info || 18921 !param_buf->num_roam_neighbor_report_info || 18922 idx >= param_buf->num_roam_neighbor_report_info) { 18923 wmi_debug("Invalid 1kv param buf"); 18924 return QDF_STATUS_E_FAILURE; 18925 } 18926 18927 src_data = ¶m_buf->roam_neighbor_report_info[idx]; 18928 18929 dst->present = true; 18930 dst->req_type = src_data->request_type; 18931 dst->num_freq = src_data->neighbor_report_channel_count; 18932 dst->req_time = src_data->neighbor_report_request_timestamp; 18933 dst->resp_time = src_data->neighbor_report_response_timestamp; 18934 dst->btm_query_token = src_data->btm_query_token; 18935 dst->btm_query_reason = src_data->btm_query_reason_code; 18936 dst->req_token = 18937 WMI_ROAM_NEIGHBOR_REPORT_INFO_REQUEST_TOKEN_GET(src_data->neighbor_report_detail); 18938 dst->resp_token = 18939 WMI_ROAM_NEIGHBOR_REPORT_INFO_RESPONSE_TOKEN_GET(src_data->neighbor_report_detail); 18940 dst->num_rpt = 18941 WMI_ROAM_NEIGHBOR_REPORT_INFO_NUM_OF_NRIE_GET(src_data->neighbor_report_detail); 18942 18943 if (!dst->num_freq || !param_buf->num_roam_neighbor_report_chan_info || 18944 rpt_idx >= param_buf->num_roam_neighbor_report_chan_info) 18945 return QDF_STATUS_SUCCESS; 18946 18947 if (!param_buf->roam_neighbor_report_chan_info) { 18948 wmi_debug("11kv channel present, but TLV is NULL num_freq:%d", 18949 dst->num_freq); 18950 dst->num_freq = 0; 18951 /* return success as its optional tlv and we can print neighbor 18952 * report received info 18953 */ 18954 return QDF_STATUS_SUCCESS; 18955 } 18956 18957 src_freq = ¶m_buf->roam_neighbor_report_chan_info[rpt_idx]; 18958 18959 if (dst->num_freq > MAX_ROAM_SCAN_CHAN) 18960 dst->num_freq = MAX_ROAM_SCAN_CHAN; 18961 18962 for (i = 0; i < dst->num_freq; i++) { 18963 dst->freq[i] = src_freq->channel; 18964 src_freq++; 18965 } 18966 18967 return QDF_STATUS_SUCCESS; 18968 } 18969 18970 /** 18971 * send_roam_set_param_cmd_tlv() - WMI roam set parameter function 18972 * @wmi_handle: handle to WMI. 18973 * @roam_param: pointer to hold roam set parameter 18974 * 18975 * Return: QDF_STATUS_SUCCESS for success or error code 18976 */ 18977 static QDF_STATUS 18978 send_roam_set_param_cmd_tlv(wmi_unified_t wmi_handle, 18979 struct vdev_set_params *roam_param) 18980 { 18981 QDF_STATUS ret; 18982 wmi_roam_set_param_cmd_fixed_param *cmd; 18983 wmi_buf_t buf; 18984 uint16_t len = sizeof(*cmd); 18985 18986 buf = wmi_buf_alloc(wmi_handle, len); 18987 if (!buf) 18988 return QDF_STATUS_E_NOMEM; 18989 18990 cmd = (wmi_roam_set_param_cmd_fixed_param *)wmi_buf_data(buf); 18991 WMITLV_SET_HDR(&cmd->tlv_header, 18992 WMITLV_TAG_STRUC_wmi_roam_set_param_cmd_fixed_param, 18993 WMITLV_GET_STRUCT_TLVLEN 18994 (wmi_roam_set_param_cmd_fixed_param)); 18995 cmd->vdev_id = roam_param->vdev_id; 18996 cmd->param_id = roam_param->param_id; 18997 cmd->param_value = roam_param->param_value; 18998 wmi_debug("Setting vdev %d roam_param = %x, value = %u", 18999 cmd->vdev_id, cmd->param_id, cmd->param_value); 19000 wmi_mtrace(WMI_ROAM_SET_PARAM_CMDID, cmd->vdev_id, 0); 19001 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 19002 WMI_ROAM_SET_PARAM_CMDID); 19003 if (QDF_IS_STATUS_ERROR(ret)) { 19004 wmi_err("Failed to send roam set param command, ret = %d", ret); 19005 wmi_buf_free(buf); 19006 } 19007 19008 return ret; 19009 } 19010 #else 19011 static inline QDF_STATUS 19012 extract_roam_trigger_stats_tlv(wmi_unified_t wmi_handle, void *evt_buf, 19013 struct wmi_roam_trigger_info *trig, uint8_t idx, 19014 uint8_t btm_idx) 19015 { 19016 return QDF_STATUS_E_NOSUPPORT; 19017 } 19018 19019 static inline QDF_STATUS 19020 extract_roam_result_stats_tlv(wmi_unified_t wmi_handle, void *evt_buf, 19021 struct wmi_roam_result *dst, uint8_t idx) 19022 { 19023 return QDF_STATUS_E_NOSUPPORT; 19024 } 19025 19026 static QDF_STATUS 19027 extract_roam_11kv_stats_tlv(wmi_unified_t wmi_handle, void *evt_buf, 19028 struct wmi_neighbor_report_data *dst, 19029 uint8_t idx, uint8_t rpt_idx) 19030 { 19031 return QDF_STATUS_E_NOSUPPORT; 19032 } 19033 19034 static QDF_STATUS 19035 extract_roam_scan_stats_tlv(wmi_unified_t wmi_handle, void *evt_buf, 19036 struct wmi_roam_scan_data *dst, uint8_t idx, 19037 uint8_t chan_idx, uint8_t ap_idx) 19038 { 19039 return QDF_STATUS_E_NOSUPPORT; 19040 } 19041 #endif 19042 19043 #ifdef WLAN_FEATURE_PKT_CAPTURE 19044 static QDF_STATUS 19045 extract_vdev_mgmt_offload_event_tlv(void *handle, void *evt_buf, 19046 struct mgmt_offload_event_params *params) 19047 { 19048 WMI_VDEV_MGMT_OFFLOAD_EVENTID_param_tlvs *param_tlvs; 19049 wmi_mgmt_hdr *hdr; 19050 19051 param_tlvs = (WMI_VDEV_MGMT_OFFLOAD_EVENTID_param_tlvs *)evt_buf; 19052 if (!param_tlvs) 19053 return QDF_STATUS_E_INVAL; 19054 19055 hdr = param_tlvs->fixed_param; 19056 if (!hdr) 19057 return QDF_STATUS_E_INVAL; 19058 19059 if (hdr->buf_len > param_tlvs->num_bufp) 19060 return QDF_STATUS_E_INVAL; 19061 19062 params->tsf_l32 = hdr->tsf_l32; 19063 params->chan_freq = hdr->chan_freq; 19064 params->rate_kbps = hdr->rate_kbps; 19065 params->rssi = hdr->rssi; 19066 params->buf_len = hdr->buf_len; 19067 params->tx_status = hdr->tx_status; 19068 params->buf = param_tlvs->bufp; 19069 params->tx_retry_cnt = hdr->tx_retry_cnt; 19070 return QDF_STATUS_SUCCESS; 19071 } 19072 #endif /* WLAN_FEATURE_PKT_CAPTURE */ 19073 19074 #ifdef WLAN_FEATURE_PKT_CAPTURE_V2 19075 static QDF_STATUS 19076 extract_smart_monitor_event_tlv(void *handle, void *evt_buf, 19077 struct smu_event_params *params) 19078 { 19079 WMI_VDEV_SMART_MONITOR_EVENTID_param_tlvs *param_buf = NULL; 19080 wmi_vdev_smart_monitor_event_fixed_param *smu_event = NULL; 19081 19082 param_buf = (WMI_VDEV_SMART_MONITOR_EVENTID_param_tlvs *)evt_buf; 19083 if (!param_buf) { 19084 wmi_err("Invalid smart monitor event"); 19085 return QDF_STATUS_E_INVAL; 19086 } 19087 19088 smu_event = param_buf->fixed_param; 19089 if (!smu_event) { 19090 wmi_err("smart monitor event fixed param is NULL"); 19091 return QDF_STATUS_E_INVAL; 19092 } 19093 19094 params->vdev_id = smu_event->vdev_id; 19095 if (params->vdev_id >= WLAN_UMAC_PDEV_MAX_VDEVS) 19096 return QDF_STATUS_E_INVAL; 19097 19098 params->rx_avg_rssi = smu_event->avg_rssi_data_dbm; 19099 19100 return QDF_STATUS_SUCCESS; 19101 } 19102 #endif /* WLAN_FEATURE_PKT_CAPTURE_V2 */ 19103 19104 #ifdef FEATURE_WLAN_TIME_SYNC_FTM 19105 /** 19106 * send_wlan_ts_ftm_trigger_cmd_tlv(): send wlan time sync cmd to FW 19107 * 19108 * @wmi: wmi handle 19109 * @vdev_id: vdev id 19110 * @burst_mode: Indicates whether relation derived using FTM is needed for 19111 * each FTM frame or only aggregated result is required. 19112 * 19113 * Send WMI_AUDIO_SYNC_TRIGGER_CMDID to FW. 19114 * 19115 * Return: QDF_STATUS 19116 */ 19117 static QDF_STATUS send_wlan_ts_ftm_trigger_cmd_tlv(wmi_unified_t wmi, 19118 uint32_t vdev_id, 19119 bool burst_mode) 19120 { 19121 wmi_audio_sync_trigger_cmd_fixed_param *cmd; 19122 wmi_buf_t buf; 19123 int32_t len = sizeof(*cmd); 19124 19125 buf = wmi_buf_alloc(wmi, len); 19126 if (!buf) { 19127 wmi_err("wmi_buf_alloc failed"); 19128 return QDF_STATUS_E_NOMEM; 19129 } 19130 cmd = (wmi_audio_sync_trigger_cmd_fixed_param *)wmi_buf_data(buf); 19131 WMITLV_SET_HDR(&cmd->tlv_header, 19132 WMITLV_TAG_STRUC_wmi_audio_sync_trigger_cmd_fixed_param, 19133 WMITLV_GET_STRUCT_TLVLEN(wmi_audio_sync_trigger_cmd_fixed_param)); 19134 cmd->vdev_id = vdev_id; 19135 cmd->agg_relation = burst_mode ? false : true; 19136 if (wmi_unified_cmd_send(wmi, buf, len, WMI_VDEV_AUDIO_SYNC_TRIGGER_CMDID)) { 19137 wmi_err("Failed to send audio sync trigger cmd"); 19138 wmi_buf_free(buf); 19139 return QDF_STATUS_E_FAILURE; 19140 } 19141 19142 return QDF_STATUS_SUCCESS; 19143 } 19144 19145 static QDF_STATUS send_wlan_ts_qtime_cmd_tlv(wmi_unified_t wmi, 19146 uint32_t vdev_id, 19147 uint64_t lpass_ts) 19148 { 19149 wmi_audio_sync_qtimer_cmd_fixed_param *cmd; 19150 wmi_buf_t buf; 19151 int32_t len = sizeof(*cmd); 19152 19153 buf = wmi_buf_alloc(wmi, len); 19154 if (!buf) { 19155 wmi_err("wmi_buf_alloc failed"); 19156 return QDF_STATUS_E_NOMEM; 19157 } 19158 cmd = (wmi_audio_sync_qtimer_cmd_fixed_param *)wmi_buf_data(buf); 19159 WMITLV_SET_HDR(&cmd->tlv_header, 19160 WMITLV_TAG_STRUC_wmi_audio_sync_qtimer_cmd_fixed_param, 19161 WMITLV_GET_STRUCT_TLVLEN(wmi_audio_sync_qtimer_cmd_fixed_param)); 19162 cmd->vdev_id = vdev_id; 19163 cmd->qtimer_u32 = (uint32_t)((lpass_ts & 0xffffffff00000000LL) >> 32); 19164 cmd->qtimer_l32 = (uint32_t)(lpass_ts & 0xffffffffLL); 19165 19166 if (wmi_unified_cmd_send(wmi, buf, len, WMI_VDEV_AUDIO_SYNC_QTIMER_CMDID)) { 19167 wmi_err("Failed to send audio qtime command"); 19168 wmi_buf_free(buf); 19169 return QDF_STATUS_E_FAILURE; 19170 } 19171 19172 return QDF_STATUS_SUCCESS; 19173 } 19174 19175 static QDF_STATUS extract_time_sync_ftm_start_stop_event_tlv( 19176 wmi_unified_t wmi, void *buf, 19177 struct ftm_time_sync_start_stop_params *param) 19178 { 19179 WMI_VDEV_AUDIO_SYNC_START_STOP_EVENTID_param_tlvs *param_buf; 19180 wmi_audio_sync_start_stop_event_fixed_param *resp_event; 19181 19182 param_buf = (WMI_VDEV_AUDIO_SYNC_START_STOP_EVENTID_param_tlvs *)buf; 19183 if (!param_buf) { 19184 wmi_err("Invalid audio sync start stop event buffer"); 19185 return QDF_STATUS_E_FAILURE; 19186 } 19187 19188 resp_event = param_buf->fixed_param; 19189 if (!resp_event) { 19190 wmi_err("Invalid audio sync start stop fixed param buffer"); 19191 return QDF_STATUS_E_FAILURE; 19192 } 19193 19194 param->vdev_id = resp_event->vdev_id; 19195 param->timer_interval = resp_event->periodicity; 19196 param->num_reads = resp_event->reads_needed; 19197 param->qtime = ((uint64_t)resp_event->qtimer_u32 << 32) | 19198 resp_event->qtimer_l32; 19199 param->mac_time = ((uint64_t)resp_event->mac_timer_u32 << 32) | 19200 resp_event->mac_timer_l32; 19201 19202 wmi_debug("FTM time sync time_interval %d, num_reads %d", 19203 param->timer_interval, param->num_reads); 19204 19205 return QDF_STATUS_SUCCESS; 19206 } 19207 19208 static QDF_STATUS 19209 extract_time_sync_ftm_offset_event_tlv(wmi_unified_t wmi, void *buf, 19210 struct ftm_time_sync_offset *param) 19211 { 19212 WMI_VDEV_AUDIO_SYNC_Q_MASTER_SLAVE_OFFSET_EVENTID_param_tlvs *param_buf; 19213 wmi_audio_sync_q_master_slave_offset_event_fixed_param *resp_event; 19214 wmi_audio_sync_q_master_slave_times *q_pair; 19215 int iter; 19216 19217 param_buf = 19218 (WMI_VDEV_AUDIO_SYNC_Q_MASTER_SLAVE_OFFSET_EVENTID_param_tlvs *)buf; 19219 if (!param_buf) { 19220 wmi_err("Invalid timesync ftm offset event buffer"); 19221 return QDF_STATUS_E_FAILURE; 19222 } 19223 19224 resp_event = param_buf->fixed_param; 19225 if (!resp_event) { 19226 wmi_err("Invalid timesync ftm offset fixed param buffer"); 19227 return QDF_STATUS_E_FAILURE; 19228 } 19229 19230 param->vdev_id = resp_event->vdev_id; 19231 param->num_qtime = param_buf->num_audio_sync_q_master_slave_times; 19232 if (param->num_qtime > FTM_TIME_SYNC_QTIME_PAIR_MAX) 19233 param->num_qtime = FTM_TIME_SYNC_QTIME_PAIR_MAX; 19234 19235 q_pair = param_buf->audio_sync_q_master_slave_times; 19236 if (!q_pair) { 19237 wmi_err("Invalid q_master_slave_times buffer"); 19238 return QDF_STATUS_E_FAILURE; 19239 } 19240 19241 for (iter = 0; iter < param->num_qtime; iter++) { 19242 param->pairs[iter].qtime_initiator = ( 19243 (uint64_t)q_pair[iter].qmaster_u32 << 32) | 19244 q_pair[iter].qmaster_l32; 19245 param->pairs[iter].qtime_target = ( 19246 (uint64_t)q_pair[iter].qslave_u32 << 32) | 19247 q_pair[iter].qslave_l32; 19248 } 19249 return QDF_STATUS_SUCCESS; 19250 } 19251 #endif /* FEATURE_WLAN_TIME_SYNC_FTM */ 19252 19253 /** 19254 * send_vdev_tsf_tstamp_action_cmd_tlv() - send vdev tsf action command 19255 * @wmi: wmi handle 19256 * @vdev_id: vdev id 19257 * 19258 * TSF_TSTAMP_READ_VALUE is the only operation supported 19259 * Return: QDF_STATUS_SUCCESS for success or error code 19260 */ 19261 static QDF_STATUS 19262 send_vdev_tsf_tstamp_action_cmd_tlv(wmi_unified_t wmi, uint8_t vdev_id) 19263 { 19264 wmi_vdev_tsf_tstamp_action_cmd_fixed_param *cmd; 19265 wmi_buf_t buf; 19266 int32_t len = sizeof(*cmd); 19267 19268 buf = wmi_buf_alloc(wmi, len); 19269 if (!buf) 19270 return QDF_STATUS_E_NOMEM; 19271 19272 cmd = (wmi_vdev_tsf_tstamp_action_cmd_fixed_param *)wmi_buf_data(buf); 19273 WMITLV_SET_HDR(&cmd->tlv_header, 19274 WMITLV_TAG_STRUC_wmi_vdev_tsf_tstamp_action_cmd_fixed_param, 19275 WMITLV_GET_STRUCT_TLVLEN(wmi_vdev_tsf_tstamp_action_cmd_fixed_param)); 19276 cmd->vdev_id = vdev_id; 19277 cmd->tsf_action = TSF_TSTAMP_QTIMER_CAPTURE_REQ; 19278 wmi_mtrace(WMI_VDEV_TSF_TSTAMP_ACTION_CMDID, cmd->vdev_id, 0); 19279 if (wmi_unified_cmd_send(wmi, buf, len, 19280 WMI_VDEV_TSF_TSTAMP_ACTION_CMDID)) { 19281 wmi_err("%s: Failed to send WMI_VDEV_TSF_TSTAMP_ACTION_CMDID", 19282 __func__); 19283 wmi_buf_free(buf); 19284 return QDF_STATUS_E_FAILURE; 19285 } 19286 19287 return QDF_STATUS_SUCCESS; 19288 } 19289 19290 /** 19291 * extract_vdev_tsf_report_event_tlv() - extract vdev tsf report from event 19292 * @wmi_handle: wmi handle 19293 * @evt_buf: pointer to event buffer 19294 * @param: Pointer to struct to hold event info 19295 * 19296 * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure 19297 */ 19298 static QDF_STATUS 19299 extract_vdev_tsf_report_event_tlv(wmi_unified_t wmi_handle, void *evt_buf, 19300 struct wmi_host_tsf_event *param) 19301 { 19302 WMI_VDEV_TSF_REPORT_EVENTID_param_tlvs *param_buf; 19303 wmi_vdev_tsf_report_event_fixed_param *evt; 19304 19305 param_buf = (WMI_VDEV_TSF_REPORT_EVENTID_param_tlvs *)evt_buf; 19306 if (!param_buf) { 19307 wmi_err("Invalid tsf report event buffer"); 19308 return QDF_STATUS_E_INVAL; 19309 } 19310 19311 evt = param_buf->fixed_param; 19312 param->vdev_id = evt->vdev_id; 19313 param->tsf = ((uint64_t)(evt->tsf_high) << 32) | evt->tsf_low; 19314 param->tsf_low = evt->tsf_low; 19315 param->tsf_high = evt->tsf_high; 19316 param->qtimer_low = evt->qtimer_low; 19317 param->qtimer_high = evt->qtimer_high; 19318 param->tsf_id = evt->tsf_id; 19319 param->tsf_id_valid = evt->tsf_id_valid; 19320 param->mac_id = evt->mac_id; 19321 param->mac_id_valid = evt->mac_id_valid; 19322 param->wlan_global_tsf_low = evt->wlan_global_tsf_low; 19323 param->wlan_global_tsf_high = evt->wlan_global_tsf_high; 19324 param->tqm_timer_low = evt->tqm_timer_low; 19325 param->tqm_timer_high = evt->tqm_timer_high; 19326 param->use_tqm_timer = evt->use_tqm_timer; 19327 19328 return QDF_STATUS_SUCCESS; 19329 } 19330 19331 /** 19332 * extract_pdev_csa_switch_count_status_tlv() - extract pdev csa switch count 19333 * status tlv 19334 * @wmi_handle: wmi handle 19335 * @evt_buf: pointer to event buffer 19336 * @param: Pointer to hold csa switch count status event param 19337 * 19338 * Return: QDF_STATUS_SUCCESS for success or error code 19339 */ 19340 static QDF_STATUS extract_pdev_csa_switch_count_status_tlv( 19341 wmi_unified_t wmi_handle, 19342 void *evt_buf, 19343 struct pdev_csa_switch_count_status *param) 19344 { 19345 WMI_PDEV_CSA_SWITCH_COUNT_STATUS_EVENTID_param_tlvs *param_buf; 19346 wmi_pdev_csa_switch_count_status_event_fixed_param *csa_status; 19347 19348 param_buf = (WMI_PDEV_CSA_SWITCH_COUNT_STATUS_EVENTID_param_tlvs *) 19349 evt_buf; 19350 if (!param_buf) { 19351 wmi_err("Invalid CSA status event"); 19352 return QDF_STATUS_E_INVAL; 19353 } 19354 19355 csa_status = param_buf->fixed_param; 19356 19357 param->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host( 19358 wmi_handle, 19359 csa_status->pdev_id); 19360 param->current_switch_count = csa_status->current_switch_count; 19361 param->num_vdevs = csa_status->num_vdevs; 19362 param->vdev_ids = param_buf->vdev_ids; 19363 19364 return QDF_STATUS_SUCCESS; 19365 } 19366 19367 #ifdef CONFIG_AFC_SUPPORT 19368 /** 19369 * send_afc_cmd_tlv() - Sends the AFC indication to FW 19370 * @wmi_handle: wmi handle 19371 * @pdev_id: Pdev id 19372 * @param: Pointer to hold AFC indication. 19373 * 19374 * Return: QDF_STATUS_SUCCESS for success or error code 19375 */ 19376 static 19377 QDF_STATUS send_afc_cmd_tlv(wmi_unified_t wmi_handle, 19378 uint8_t pdev_id, 19379 struct reg_afc_resp_rx_ind_info *param) 19380 { 19381 wmi_buf_t buf; 19382 wmi_afc_cmd_fixed_param *cmd; 19383 uint32_t len; 19384 uint8_t *buf_ptr; 19385 QDF_STATUS ret; 19386 19387 len = sizeof(wmi_afc_cmd_fixed_param); 19388 buf = wmi_buf_alloc(wmi_handle, len); 19389 if (!buf) 19390 return QDF_STATUS_E_NOMEM; 19391 19392 buf_ptr = (uint8_t *)wmi_buf_data(buf); 19393 cmd = (wmi_afc_cmd_fixed_param *)buf_ptr; 19394 19395 WMITLV_SET_HDR(&cmd->tlv_header, 19396 WMITLV_TAG_STRUC_wmi_afc_cmd_fixed_param, 19397 WMITLV_GET_STRUCT_TLVLEN(wmi_afc_cmd_fixed_param)); 19398 19399 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 19400 wmi_handle, 19401 pdev_id); 19402 cmd->cmd_type = param->cmd_type; 19403 cmd->serv_resp_format = param->serv_resp_format; 19404 19405 wmi_mtrace(WMI_AFC_CMDID, NO_SESSION, 0); 19406 ret = wmi_unified_cmd_send(wmi_handle, buf, len, WMI_AFC_CMDID); 19407 if (QDF_IS_STATUS_ERROR(ret)) { 19408 wmi_err("Failed to send WMI_AFC_CMDID"); 19409 wmi_buf_free(buf); 19410 return QDF_STATUS_E_FAILURE; 19411 } 19412 19413 return QDF_STATUS_SUCCESS; 19414 } 19415 #endif 19416 19417 /** 19418 * send_set_tpc_power_cmd_tlv() - Sends the set TPC power level to FW 19419 * @wmi_handle: wmi handle 19420 * @vdev_id: vdev id 19421 * @param: Pointer to hold TX power info 19422 * 19423 * Return: QDF_STATUS_SUCCESS for success or error code 19424 */ 19425 static QDF_STATUS send_set_tpc_power_cmd_tlv(wmi_unified_t wmi_handle, 19426 uint8_t vdev_id, 19427 struct reg_tpc_power_info *param) 19428 { 19429 wmi_buf_t buf; 19430 wmi_vdev_set_tpc_power_fixed_param *tpc_power_info_param; 19431 wmi_vdev_ch_power_info *ch_power_info; 19432 uint8_t *buf_ptr; 19433 uint16_t idx; 19434 uint32_t len; 19435 QDF_STATUS ret; 19436 19437 len = sizeof(wmi_vdev_set_tpc_power_fixed_param) + WMI_TLV_HDR_SIZE; 19438 len += (sizeof(wmi_vdev_ch_power_info) * param->num_pwr_levels); 19439 19440 buf = wmi_buf_alloc(wmi_handle, len); 19441 if (!buf) 19442 return QDF_STATUS_E_NOMEM; 19443 19444 buf_ptr = (uint8_t *)wmi_buf_data(buf); 19445 tpc_power_info_param = (wmi_vdev_set_tpc_power_fixed_param *)buf_ptr; 19446 19447 WMITLV_SET_HDR(&tpc_power_info_param->tlv_header, 19448 WMITLV_TAG_STRUC_wmi_vdev_set_tpc_power_cmd_fixed_param, 19449 WMITLV_GET_STRUCT_TLVLEN(wmi_vdev_set_tpc_power_fixed_param)); 19450 19451 tpc_power_info_param->vdev_id = vdev_id; 19452 tpc_power_info_param->psd_power = param->is_psd_power; 19453 tpc_power_info_param->eirp_power = param->eirp_power; 19454 tpc_power_info_param->power_type_6ghz = param->power_type_6g; 19455 wmi_debug("eirp_power = %d is_psd_power = %d", 19456 tpc_power_info_param->eirp_power, 19457 tpc_power_info_param->psd_power); 19458 reg_print_ap_power_type_6ghz(tpc_power_info_param->power_type_6ghz); 19459 19460 buf_ptr += sizeof(wmi_vdev_set_tpc_power_fixed_param); 19461 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 19462 param->num_pwr_levels * sizeof(wmi_vdev_ch_power_info)); 19463 19464 buf_ptr += WMI_TLV_HDR_SIZE; 19465 ch_power_info = (wmi_vdev_ch_power_info *)buf_ptr; 19466 19467 for (idx = 0; idx < param->num_pwr_levels; ++idx) { 19468 WMITLV_SET_HDR(&ch_power_info[idx].tlv_header, 19469 WMITLV_TAG_STRUC_wmi_vdev_ch_power_info, 19470 WMITLV_GET_STRUCT_TLVLEN(wmi_vdev_ch_power_info)); 19471 ch_power_info[idx].chan_cfreq = 19472 param->chan_power_info[idx].chan_cfreq; 19473 ch_power_info[idx].tx_power = 19474 param->chan_power_info[idx].tx_power; 19475 wmi_debug("chan_cfreq = %d tx_power = %d", 19476 ch_power_info[idx].chan_cfreq, 19477 ch_power_info[idx].tx_power); 19478 buf_ptr += sizeof(wmi_vdev_ch_power_info); 19479 } 19480 19481 wmi_mtrace(WMI_VDEV_SET_TPC_POWER_CMDID, vdev_id, 0); 19482 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 19483 WMI_VDEV_SET_TPC_POWER_CMDID); 19484 if (QDF_IS_STATUS_ERROR(ret)) 19485 wmi_buf_free(buf); 19486 19487 19488 return ret; 19489 } 19490 19491 /** 19492 * extract_dpd_status_ev_param_tlv() - extract dpd status from FW event 19493 * @wmi_handle: wmi handle 19494 * @evt_buf: event buffer 19495 * @param: dpd status info 19496 * 19497 * Return: QDF_STATUS_SUCCESS for success or error code 19498 */ 19499 static QDF_STATUS 19500 extract_dpd_status_ev_param_tlv(wmi_unified_t wmi_handle, 19501 void *evt_buf, 19502 struct wmi_host_pdev_get_dpd_status_event *param) 19503 { 19504 WMI_PDEV_GET_DPD_STATUS_EVENTID_param_tlvs *param_buf; 19505 wmi_pdev_get_dpd_status_evt_fixed_param *dpd_status; 19506 19507 param_buf = (WMI_PDEV_GET_DPD_STATUS_EVENTID_param_tlvs *)evt_buf; 19508 if (!param_buf) { 19509 wmi_err("Invalid get dpd_status event"); 19510 return QDF_STATUS_E_INVAL; 19511 } 19512 19513 dpd_status = param_buf->fixed_param; 19514 param->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host 19515 (wmi_handle, dpd_status->pdev_id); 19516 param->dpd_status = dpd_status->dpd_status; 19517 19518 return QDF_STATUS_SUCCESS; 19519 } 19520 19521 static int 19522 convert_halphy_status(wmi_pdev_get_halphy_cal_status_evt_fixed_param *status, 19523 WMI_HALPHY_CAL_VALID_BITMAP_STATUS valid_bit) 19524 { 19525 if (status->halphy_cal_valid_bmap && valid_bit) 19526 return (status->halphy_cal_status && valid_bit); 19527 19528 return 0; 19529 } 19530 19531 static QDF_STATUS 19532 extract_halphy_cal_status_ev_param_tlv(wmi_unified_t wmi_handle, 19533 void *evt_buf, 19534 struct wmi_host_pdev_get_halphy_cal_status_event *param) 19535 { 19536 WMI_PDEV_GET_HALPHY_CAL_STATUS_EVENTID_param_tlvs *param_buf; 19537 wmi_pdev_get_halphy_cal_status_evt_fixed_param *halphy_cal_status; 19538 19539 param_buf = (WMI_PDEV_GET_HALPHY_CAL_STATUS_EVENTID_param_tlvs *)evt_buf; 19540 if (!param_buf) { 19541 wmi_err("Invalid get halphy cal status event"); 19542 return QDF_STATUS_E_INVAL; 19543 } 19544 19545 halphy_cal_status = param_buf->fixed_param; 19546 param->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host 19547 (wmi_handle, halphy_cal_status->pdev_id); 19548 param->halphy_cal_adc_status = 19549 convert_halphy_status(halphy_cal_status, 19550 WMI_HALPHY_CAL_ADC_BMAP); 19551 param->halphy_cal_bwfilter_status = 19552 convert_halphy_status(halphy_cal_status, 19553 WMI_HALPHY_CAL_BWFILTER_BMAP); 19554 param->halphy_cal_pdet_and_pal_status = 19555 convert_halphy_status(halphy_cal_status, 19556 WMI_HALPHY_CAL_PDET_AND_PAL_BMAP); 19557 param->halphy_cal_rxdco_status = 19558 convert_halphy_status(halphy_cal_status, 19559 WMI_HALPHY_CAL_RXDCO_BMAP); 19560 param->halphy_cal_comb_txiq_rxiq_status = 19561 convert_halphy_status(halphy_cal_status, 19562 WMI_HALPHY_CAL_COMB_TXLO_TXIQ_RXIQ_BMAP); 19563 param->halphy_cal_ibf_status = 19564 convert_halphy_status(halphy_cal_status, 19565 WMI_HALPHY_CAL_IBF_BMAP); 19566 param->halphy_cal_pa_droop_status = 19567 convert_halphy_status(halphy_cal_status, 19568 WMI_HALPHY_CAL_PA_DROOP_BMAP); 19569 param->halphy_cal_dac_status = 19570 convert_halphy_status(halphy_cal_status, 19571 WMI_HALPHY_CAL_DAC_BMAP); 19572 param->halphy_cal_ani_status = 19573 convert_halphy_status(halphy_cal_status, 19574 WMI_HALPHY_CAL_ANI_BMAP); 19575 param->halphy_cal_noise_floor_status = 19576 convert_halphy_status(halphy_cal_status, 19577 WMI_HALPHY_CAL_NOISE_FLOOR_BMAP); 19578 19579 return QDF_STATUS_SUCCESS; 19580 } 19581 19582 /** 19583 * set_halphy_cal_fw_status_to_host_status() - Convert set halphy cal status to host enum 19584 * @fw_status: set halphy cal status from WMI_PDEV_SET_HALPHY_CAL_BMAP_EVENTID event 19585 * 19586 * Return: host_set_halphy_cal_status 19587 */ 19588 static enum wmi_host_set_halphy_cal_status 19589 set_halphy_cal_fw_status_to_host_status(uint32_t fw_status) 19590 { 19591 if (fw_status == 0) 19592 return WMI_HOST_SET_HALPHY_CAL_STATUS_SUCCESS; 19593 else if (fw_status == 1) 19594 return WMI_HOST_SET_HALPHY_CAL_STATUS_FAIL; 19595 19596 wmi_debug("Unknown set halphy status code(%u) from WMI", fw_status); 19597 return WMI_HOST_SET_HALPHY_CAL_STATUS_FAIL; 19598 } 19599 19600 /** 19601 * extract_halphy_cal_ev_param_tlv() - extract dpd status from FW event 19602 * @wmi_handle: wmi handle 19603 * @evt_buf: event buffer 19604 * @param: set halphy cal status info 19605 * 19606 * Return: QDF_STATUS_SUCCESS for success or error code 19607 */ 19608 static QDF_STATUS 19609 extract_halphy_cal_ev_param_tlv(wmi_unified_t wmi_handle, 19610 void *evt_buf, 19611 struct wmi_host_pdev_set_halphy_cal_event *param) 19612 { 19613 WMI_PDEV_SET_HALPHY_CAL_BMAP_EVENTID_param_tlvs *param_buf; 19614 wmi_pdev_set_halphy_cal_bmap_evt_fixed_param *set_halphy_status; 19615 19616 param_buf = (WMI_PDEV_SET_HALPHY_CAL_BMAP_EVENTID_param_tlvs *)evt_buf; 19617 if (!param_buf) { 19618 wmi_err("Invalid set halphy_status event"); 19619 return QDF_STATUS_E_INVAL; 19620 } 19621 19622 set_halphy_status = param_buf->fixed_param; 19623 param->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host 19624 (wmi_handle, set_halphy_status->pdev_id); 19625 param->status = set_halphy_cal_fw_status_to_host_status(set_halphy_status->status); 19626 19627 return QDF_STATUS_SUCCESS; 19628 } 19629 19630 /** 19631 * extract_install_key_comp_event_tlv() - extract install key complete event tlv 19632 * @wmi_handle: wmi handle 19633 * @evt_buf: pointer to event buffer 19634 * @len: length of the event buffer 19635 * @param: Pointer to hold install key complete event param 19636 * 19637 * Return: QDF_STATUS_SUCCESS for success or error code 19638 */ 19639 static QDF_STATUS 19640 extract_install_key_comp_event_tlv(wmi_unified_t wmi_handle, 19641 void *evt_buf, uint32_t len, 19642 struct wmi_install_key_comp_event *param) 19643 { 19644 WMI_VDEV_INSTALL_KEY_COMPLETE_EVENTID_param_tlvs *param_buf; 19645 wmi_vdev_install_key_complete_event_fixed_param *key_fp; 19646 19647 if (len < sizeof(*param_buf)) { 19648 wmi_err("invalid event buf len %d", len); 19649 return QDF_STATUS_E_INVAL; 19650 } 19651 19652 param_buf = (WMI_VDEV_INSTALL_KEY_COMPLETE_EVENTID_param_tlvs *)evt_buf; 19653 if (!param_buf) { 19654 wmi_err("received null buf from target"); 19655 return QDF_STATUS_E_INVAL; 19656 } 19657 19658 key_fp = param_buf->fixed_param; 19659 if (!key_fp) { 19660 wmi_err("received null event data from target"); 19661 return QDF_STATUS_E_INVAL; 19662 } 19663 19664 param->vdev_id = key_fp->vdev_id; 19665 param->key_ix = key_fp->key_ix; 19666 param->key_flags = key_fp->key_flags; 19667 param->status = key_fp->status; 19668 WMI_MAC_ADDR_TO_CHAR_ARRAY(&key_fp->peer_macaddr, 19669 param->peer_macaddr); 19670 19671 return QDF_STATUS_SUCCESS; 19672 } 19673 19674 static QDF_STATUS 19675 send_set_halphy_cal_tlv(wmi_unified_t wmi_handle, 19676 struct wmi_host_send_set_halphy_cal_info *param) 19677 { 19678 wmi_buf_t buf; 19679 wmi_pdev_set_halphy_cal_bmap_cmd_fixed_param *cmd; 19680 QDF_STATUS ret; 19681 uint32_t len; 19682 19683 len = sizeof(*cmd); 19684 19685 buf = wmi_buf_alloc(wmi_handle, len); 19686 if (!buf) 19687 return QDF_STATUS_E_FAILURE; 19688 19689 cmd = (void *)wmi_buf_data(buf); 19690 19691 WMITLV_SET_HDR(&cmd->tlv_header, 19692 WMITLV_TAG_STRUC_wmi_pdev_set_halphy_cal_bmap_cmd_fixed_param, 19693 WMITLV_GET_STRUCT_TLVLEN(wmi_pdev_set_halphy_cal_bmap_cmd_fixed_param)); 19694 19695 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target(wmi_handle, 19696 param->pdev_id); 19697 cmd->online_halphy_cals_bmap = param->value; 19698 cmd->home_scan_channel = param->chan_sel; 19699 19700 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 19701 WMI_PDEV_SET_HALPHY_CAL_BMAP_CMDID); 19702 if (QDF_IS_STATUS_ERROR(ret)) { 19703 wmi_err("WMI_PDEV_SET_HALPHY_CAL_BMAP_CMDID send returned Error %d",ret); 19704 wmi_buf_free(buf); 19705 } 19706 19707 return ret; 19708 } 19709 19710 #ifdef WLAN_FEATURE_DYNAMIC_MAC_ADDR_UPDATE 19711 /** 19712 * send_set_mac_address_cmd_tlv() - send set MAC address command to fw 19713 * @wmi: wmi handle 19714 * @params: set MAC address command params 19715 * 19716 * Return: QDF_STATUS_SUCCESS for success or error code 19717 */ 19718 static QDF_STATUS 19719 send_set_mac_address_cmd_tlv(wmi_unified_t wmi, 19720 struct set_mac_addr_params *params) 19721 { 19722 wmi_vdev_update_mac_addr_cmd_fixed_param *cmd; 19723 wmi_buf_t buf; 19724 int32_t len = sizeof(*cmd); 19725 19726 buf = wmi_buf_alloc(wmi, len); 19727 if (!buf) 19728 return QDF_STATUS_E_NOMEM; 19729 19730 cmd = (wmi_vdev_update_mac_addr_cmd_fixed_param *)wmi_buf_data(buf); 19731 WMITLV_SET_HDR( 19732 &cmd->tlv_header, 19733 WMITLV_TAG_STRUC_wmi_vdev_update_mac_addr_cmd_fixed_param, 19734 WMITLV_GET_STRUCT_TLVLEN 19735 (wmi_vdev_update_mac_addr_cmd_fixed_param)); 19736 cmd->vdev_id = params->vdev_id; 19737 WMI_CHAR_ARRAY_TO_MAC_ADDR(params->mac_addr.bytes, &cmd->vdev_macaddr); 19738 WMI_CHAR_ARRAY_TO_MAC_ADDR(params->mld_addr.bytes, &cmd->mld_macaddr); 19739 19740 wmi_debug("vdev %d mac_addr " QDF_MAC_ADDR_FMT " mld_addr " 19741 QDF_MAC_ADDR_FMT, cmd->vdev_id, 19742 QDF_MAC_ADDR_REF(params->mac_addr.bytes), 19743 QDF_MAC_ADDR_REF(params->mld_addr.bytes)); 19744 wmi_mtrace(WMI_VDEV_UPDATE_MAC_ADDR_CMDID, cmd->vdev_id, 0); 19745 if (wmi_unified_cmd_send(wmi, buf, len, 19746 WMI_VDEV_UPDATE_MAC_ADDR_CMDID)) { 19747 wmi_buf_free(buf); 19748 return QDF_STATUS_E_FAILURE; 19749 } 19750 19751 return QDF_STATUS_SUCCESS; 19752 } 19753 19754 /** 19755 * extract_update_mac_address_event_tlv() - extract update MAC address event 19756 * @wmi_handle: WMI handle 19757 * @evt_buf: event buffer 19758 * @vdev_id: VDEV ID 19759 * @status: FW status of the set MAC address operation 19760 * 19761 * Return: QDF_STATUS 19762 */ 19763 static QDF_STATUS extract_update_mac_address_event_tlv( 19764 wmi_unified_t wmi_handle, void *evt_buf, 19765 uint8_t *vdev_id, uint8_t *status) 19766 { 19767 WMI_VDEV_UPDATE_MAC_ADDR_CONF_EVENTID_param_tlvs *param_buf; 19768 wmi_vdev_update_mac_addr_conf_event_fixed_param *event; 19769 19770 param_buf = 19771 (WMI_VDEV_UPDATE_MAC_ADDR_CONF_EVENTID_param_tlvs *)evt_buf; 19772 19773 event = param_buf->fixed_param; 19774 19775 *vdev_id = event->vdev_id; 19776 *status = event->status; 19777 19778 return QDF_STATUS_SUCCESS; 19779 } 19780 #endif 19781 19782 #ifdef WLAN_FEATURE_11BE_MLO 19783 /** 19784 * extract_quiet_offload_event_tlv() - extract quiet offload event 19785 * @wmi_handle: WMI handle 19786 * @evt_buf: event buffer 19787 * @quiet_event: quiet event extracted from the buffer 19788 * 19789 * Return: QDF_STATUS 19790 */ 19791 static QDF_STATUS extract_quiet_offload_event_tlv( 19792 wmi_unified_t wmi_handle, void *evt_buf, 19793 struct vdev_sta_quiet_event *quiet_event) 19794 { 19795 WMI_QUIET_HANDLING_EVENTID_param_tlvs *param_buf; 19796 wmi_quiet_event_fixed_param *event; 19797 19798 param_buf = (WMI_QUIET_HANDLING_EVENTID_param_tlvs *)evt_buf; 19799 19800 event = param_buf->fixed_param; 19801 19802 if (!(event->mld_mac_address_present && event->linkid_present) && 19803 !event->link_mac_address_present) { 19804 wmi_err("Invalid sta quiet offload event. present bit: mld mac %d link mac %d linkid %d", 19805 event->mld_mac_address_present, 19806 event->linkid_present, 19807 event->link_mac_address_present); 19808 return QDF_STATUS_E_INVAL; 19809 } 19810 19811 if (event->mld_mac_address_present) 19812 WMI_MAC_ADDR_TO_CHAR_ARRAY(&event->mld_mac_address, 19813 quiet_event->mld_mac.bytes); 19814 if (event->link_mac_address_present) 19815 WMI_MAC_ADDR_TO_CHAR_ARRAY(&event->link_mac_address, 19816 quiet_event->link_mac.bytes); 19817 if (event->linkid_present) 19818 quiet_event->link_id = event->linkid; 19819 quiet_event->quiet_status = (event->quiet_status == 19820 WMI_QUIET_EVENT_START); 19821 19822 return QDF_STATUS_SUCCESS; 19823 } 19824 #endif 19825 19826 /** 19827 * send_vdev_pn_mgmt_rxfilter_cmd_tlv() - Send PN mgmt RxFilter command to FW 19828 * @wmi_handle: wmi handle 19829 * @params: RxFilter params 19830 * 19831 * Return: QDF_STATUS_SUCCESS for success or error code 19832 */ 19833 static QDF_STATUS 19834 send_vdev_pn_mgmt_rxfilter_cmd_tlv(wmi_unified_t wmi_handle, 19835 struct vdev_pn_mgmt_rxfilter_params *params) 19836 { 19837 wmi_vdev_pn_mgmt_rx_filter_cmd_fixed_param *cmd; 19838 wmi_buf_t buf; 19839 uint32_t len = sizeof(wmi_vdev_pn_mgmt_rx_filter_cmd_fixed_param); 19840 19841 if (!is_service_enabled_tlv(wmi_handle, 19842 WMI_SERVICE_PN_REPLAY_CHECK_SUPPORT)) { 19843 wmi_err("Rx PN Replay Check not supported by target"); 19844 return QDF_STATUS_E_NOSUPPORT; 19845 } 19846 19847 buf = wmi_buf_alloc(wmi_handle, len); 19848 if (!buf) { 19849 wmi_err("wmi buf alloc failed"); 19850 return QDF_STATUS_E_NOMEM; 19851 } 19852 19853 cmd = (wmi_vdev_pn_mgmt_rx_filter_cmd_fixed_param *)wmi_buf_data(buf); 19854 WMITLV_SET_HDR( 19855 &cmd->tlv_header, 19856 WMITLV_TAG_STRUC_wmi_vdev_pn_mgmt_rx_filter_cmd_fixed_param, 19857 WMITLV_GET_STRUCT_TLVLEN 19858 (wmi_vdev_pn_mgmt_rx_filter_cmd_fixed_param)); 19859 19860 cmd->vdev_id = params->vdev_id; 19861 cmd->pn_rx_filter = params->pn_rxfilter; 19862 19863 if (wmi_unified_cmd_send(wmi_handle, buf, len, 19864 WMI_VDEV_PN_MGMT_RX_FILTER_CMDID)) { 19865 wmi_err("Failed to send WMI command"); 19866 wmi_buf_free(buf); 19867 return QDF_STATUS_E_FAILURE; 19868 } 19869 19870 return QDF_STATUS_SUCCESS; 19871 } 19872 19873 static QDF_STATUS 19874 extract_pktlog_decode_info_event_tlv(wmi_unified_t wmi_handle, void *evt_buf, 19875 uint8_t *pdev_id, uint8_t *software_image, 19876 uint8_t *chip_info, 19877 uint32_t *pktlog_json_version) 19878 { 19879 WMI_PDEV_PKTLOG_DECODE_INFO_EVENTID_param_tlvs *param_buf; 19880 wmi_pdev_pktlog_decode_info_evt_fixed_param *event; 19881 19882 param_buf = 19883 (WMI_PDEV_PKTLOG_DECODE_INFO_EVENTID_param_tlvs *)evt_buf; 19884 19885 event = param_buf->fixed_param; 19886 19887 if ((event->software_image[0] == '\0') || 19888 (event->chip_info[0] == '\0')) { 19889 *pdev_id = event->pdev_id; 19890 return QDF_STATUS_E_INVAL; 19891 } 19892 19893 qdf_mem_copy(software_image, event->software_image, 40); 19894 qdf_mem_copy(chip_info, event->chip_info, 40); 19895 *pktlog_json_version = event->pktlog_defs_json_version; 19896 *pdev_id = event->pdev_id; 19897 return QDF_STATUS_SUCCESS; 19898 } 19899 19900 #ifdef HEALTH_MON_SUPPORT 19901 /** 19902 * extract_health_mon_init_done_info_event_tlv() - Extract health monitor from 19903 * fw 19904 * @wmi_handle: wmi handle 19905 * @evt_buf: pointer to event buffer 19906 * @param: health monitor params 19907 * 19908 * Return: QDF_STATUS_SUCCESS for success or error code 19909 */ 19910 static QDF_STATUS 19911 extract_health_mon_init_done_info_event_tlv(wmi_unified_t wmi_handle, 19912 void *evt_buf, 19913 struct wmi_health_mon_params *param) 19914 { 19915 WMI_HEALTH_MON_INIT_DONE_EVENTID_param_tlvs *param_buf; 19916 wmi_health_mon_init_done_fixed_param *event; 19917 19918 param_buf = 19919 (WMI_HEALTH_MON_INIT_DONE_EVENTID_param_tlvs *)evt_buf; 19920 19921 event = param_buf->fixed_param; 19922 19923 param->ring_buf_paddr_low = event->ring_buf_paddr_low; 19924 param->ring_buf_paddr_high = event->ring_buf_paddr_high; 19925 param->initial_upload_period_ms = event->initial_upload_period_ms; 19926 param->read_index = 0; 19927 19928 return QDF_STATUS_SUCCESS; 19929 } 19930 #endif /* HEALTH_MON_SUPPORT */ 19931 19932 /** 19933 * extract_pdev_telemetry_stats_tlv - extract pdev telemetry stats 19934 * @wmi_handle: wmi handle 19935 * @evt_buf: pointer to event buffer 19936 * @pdev_stats: Pointer to hold pdev telemetry stats 19937 * 19938 * Return: QDF_STATUS_SUCCESS for success or error code 19939 */ 19940 static QDF_STATUS 19941 extract_pdev_telemetry_stats_tlv( 19942 wmi_unified_t wmi_handle, void *evt_buf, 19943 struct wmi_host_pdev_telemetry_stats *pdev_stats) 19944 { 19945 WMI_UPDATE_STATS_EVENTID_param_tlvs *param_buf; 19946 wmi_pdev_telemetry_stats *ev; 19947 19948 param_buf = (WMI_UPDATE_STATS_EVENTID_param_tlvs *)evt_buf; 19949 19950 if (param_buf->pdev_telemetry_stats) { 19951 ev = (wmi_pdev_telemetry_stats *)(param_buf->pdev_telemetry_stats); 19952 qdf_mem_copy(pdev_stats->avg_chan_lat_per_ac, 19953 ev->avg_chan_lat_per_ac, 19954 sizeof(ev->avg_chan_lat_per_ac)); 19955 pdev_stats->estimated_air_time_per_ac = 19956 ev->estimated_air_time_per_ac; 19957 } 19958 19959 return QDF_STATUS_SUCCESS; 19960 } 19961 19962 static QDF_STATUS 19963 send_set_mac_addr_rx_filter_cmd_tlv(wmi_unified_t wmi_handle, 19964 struct set_rx_mac_filter *param) 19965 { 19966 wmi_vdev_add_mac_addr_to_rx_filter_cmd_fixed_param *cmd; 19967 uint32_t len; 19968 wmi_buf_t buf; 19969 int ret; 19970 19971 if (!wmi_handle) { 19972 wmi_err("WMA context is invalid!"); 19973 return QDF_STATUS_E_INVAL; 19974 } 19975 19976 len = sizeof(*cmd); 19977 buf = wmi_buf_alloc(wmi_handle, len); 19978 if (!buf) { 19979 wmi_err("Failed allocate wmi buffer"); 19980 return QDF_STATUS_E_NOMEM; 19981 } 19982 19983 cmd = (wmi_vdev_add_mac_addr_to_rx_filter_cmd_fixed_param *) 19984 wmi_buf_data(buf); 19985 19986 WMITLV_SET_HDR( 19987 &cmd->tlv_header, 19988 WMITLV_TAG_STRUC_wmi_vdev_add_mac_addr_to_rx_filter_cmd_fixed_param, 19989 WMITLV_GET_STRUCT_TLVLEN( 19990 wmi_vdev_add_mac_addr_to_rx_filter_cmd_fixed_param)); 19991 19992 cmd->vdev_id = param->vdev_id; 19993 cmd->freq = param->freq; 19994 WMI_CHAR_ARRAY_TO_MAC_ADDR(param->mac, &cmd->mac_addr); 19995 if (param->set) 19996 cmd->enable = 1; 19997 else 19998 cmd->enable = 0; 19999 wmi_debug("set random mac rx vdev:%d freq:%d set:%d " QDF_MAC_ADDR_FMT, 20000 param->vdev_id, param->freq, param->set, 20001 QDF_MAC_ADDR_REF(param->mac)); 20002 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 20003 WMI_VDEV_ADD_MAC_ADDR_TO_RX_FILTER_CMDID); 20004 if (ret) { 20005 wmi_err("Failed to send action frame random mac cmd"); 20006 wmi_buf_free(buf); 20007 return QDF_STATUS_E_FAILURE; 20008 } 20009 20010 return QDF_STATUS_SUCCESS; 20011 } 20012 20013 static QDF_STATUS 20014 extract_sap_coex_fix_chan_caps(wmi_unified_t wmi_handle, 20015 uint8_t *event, 20016 struct wmi_host_coex_fix_chan_cap *cap) 20017 { 20018 WMI_SERVICE_READY_EXT2_EVENTID_param_tlvs *param_buf; 20019 WMI_COEX_FIX_CHANNEL_CAPABILITIES *fw_cap; 20020 20021 param_buf = (WMI_SERVICE_READY_EXT2_EVENTID_param_tlvs *)event; 20022 if (!param_buf) 20023 return QDF_STATUS_E_INVAL; 20024 20025 fw_cap = param_buf->coex_fix_channel_caps; 20026 if (!fw_cap) 20027 return QDF_STATUS_E_INVAL; 20028 20029 cap->fix_chan_priority = fw_cap->fix_channel_priority; 20030 20031 return QDF_STATUS_SUCCESS; 20032 } 20033 20034 struct wmi_ops tlv_ops = { 20035 .send_vdev_create_cmd = send_vdev_create_cmd_tlv, 20036 .send_vdev_delete_cmd = send_vdev_delete_cmd_tlv, 20037 .send_vdev_nss_chain_params_cmd = send_vdev_nss_chain_params_cmd_tlv, 20038 .send_vdev_down_cmd = send_vdev_down_cmd_tlv, 20039 .send_vdev_start_cmd = send_vdev_start_cmd_tlv, 20040 .send_peer_flush_tids_cmd = send_peer_flush_tids_cmd_tlv, 20041 .send_peer_param_cmd = send_peer_param_cmd_tlv, 20042 .send_vdev_up_cmd = send_vdev_up_cmd_tlv, 20043 .send_vdev_stop_cmd = send_vdev_stop_cmd_tlv, 20044 .send_peer_create_cmd = send_peer_create_cmd_tlv, 20045 .send_peer_delete_cmd = send_peer_delete_cmd_tlv, 20046 .send_peer_delete_all_cmd = send_peer_delete_all_cmd_tlv, 20047 .send_peer_rx_reorder_queue_setup_cmd = 20048 send_peer_rx_reorder_queue_setup_cmd_tlv, 20049 .send_peer_rx_reorder_queue_remove_cmd = 20050 send_peer_rx_reorder_queue_remove_cmd_tlv, 20051 .send_pdev_utf_cmd = send_pdev_utf_cmd_tlv, 20052 .send_pdev_param_cmd = send_pdev_param_cmd_tlv, 20053 .send_multiple_pdev_param_cmd = send_multiple_pdev_param_cmd_tlv, 20054 .send_pdev_set_hw_mode_cmd = send_pdev_set_hw_mode_cmd_tlv, 20055 .send_suspend_cmd = send_suspend_cmd_tlv, 20056 .send_resume_cmd = send_resume_cmd_tlv, 20057 .send_wow_enable_cmd = send_wow_enable_cmd_tlv, 20058 .send_set_ap_ps_param_cmd = send_set_ap_ps_param_cmd_tlv, 20059 .send_set_sta_ps_param_cmd = send_set_sta_ps_param_cmd_tlv, 20060 .send_crash_inject_cmd = send_crash_inject_cmd_tlv, 20061 .send_dbglog_cmd = send_dbglog_cmd_tlv, 20062 .send_vdev_set_param_cmd = send_vdev_set_param_cmd_tlv, 20063 .send_vdev_set_mu_snif_cmd = send_vdev_set_mu_snif_cmd_tlv, 20064 .send_packet_log_enable_cmd = send_packet_log_enable_cmd_tlv, 20065 .send_peer_based_pktlog_cmd = send_peer_based_pktlog_cmd, 20066 .send_time_stamp_sync_cmd = send_time_stamp_sync_cmd_tlv, 20067 .send_packet_log_disable_cmd = send_packet_log_disable_cmd_tlv, 20068 .send_beacon_tmpl_send_cmd = send_beacon_tmpl_send_cmd_tlv, 20069 .send_fd_tmpl_cmd = send_fd_tmpl_cmd_tlv, 20070 .send_peer_assoc_cmd = send_peer_assoc_cmd_tlv, 20071 .send_scan_start_cmd = send_scan_start_cmd_tlv, 20072 .send_scan_stop_cmd = send_scan_stop_cmd_tlv, 20073 .send_scan_chan_list_cmd = send_scan_chan_list_cmd_tlv, 20074 .send_mgmt_cmd = send_mgmt_cmd_tlv, 20075 .send_offchan_data_tx_cmd = send_offchan_data_tx_cmd_tlv, 20076 .send_modem_power_state_cmd = send_modem_power_state_cmd_tlv, 20077 .send_set_sta_ps_mode_cmd = send_set_sta_ps_mode_cmd_tlv, 20078 .send_idle_roam_monitor_cmd = send_idle_roam_monitor_cmd_tlv, 20079 .send_set_sta_uapsd_auto_trig_cmd = 20080 send_set_sta_uapsd_auto_trig_cmd_tlv, 20081 .send_get_temperature_cmd = send_get_temperature_cmd_tlv, 20082 .send_set_smps_params_cmd = send_set_smps_params_cmd_tlv, 20083 .send_set_mimops_cmd = send_set_mimops_cmd_tlv, 20084 .send_set_thermal_mgmt_cmd = send_set_thermal_mgmt_cmd_tlv, 20085 .send_lro_config_cmd = send_lro_config_cmd_tlv, 20086 .send_peer_rate_report_cmd = send_peer_rate_report_cmd_tlv, 20087 .send_probe_rsp_tmpl_send_cmd = 20088 send_probe_rsp_tmpl_send_cmd_tlv, 20089 .send_p2p_go_set_beacon_ie_cmd = 20090 send_p2p_go_set_beacon_ie_cmd_tlv, 20091 .send_setup_install_key_cmd = 20092 send_setup_install_key_cmd_tlv, 20093 .send_scan_probe_setoui_cmd = 20094 send_scan_probe_setoui_cmd_tlv, 20095 #ifdef IPA_OFFLOAD 20096 .send_ipa_offload_control_cmd = 20097 send_ipa_offload_control_cmd_tlv, 20098 #endif 20099 .send_pno_stop_cmd = send_pno_stop_cmd_tlv, 20100 .send_pno_start_cmd = send_pno_start_cmd_tlv, 20101 .send_obss_disable_cmd = send_obss_disable_cmd_tlv, 20102 .send_nlo_mawc_cmd = send_nlo_mawc_cmd_tlv, 20103 #ifdef WLAN_FEATURE_LINK_LAYER_STATS 20104 .send_process_ll_stats_clear_cmd = send_process_ll_stats_clear_cmd_tlv, 20105 .send_process_ll_stats_set_cmd = send_process_ll_stats_set_cmd_tlv, 20106 .send_process_ll_stats_get_cmd = send_process_ll_stats_get_cmd_tlv, 20107 #ifdef FEATURE_CLUB_LL_STATS_AND_GET_STATION 20108 .send_unified_ll_stats_get_sta_cmd = 20109 send_unified_ll_stats_get_sta_cmd_tlv, 20110 #endif /* FEATURE_CLUB_LL_STATS_AND_GET_STATION */ 20111 #endif /* WLAN_FEATURE_LINK_LAYER_STATS*/ 20112 .send_congestion_cmd = send_congestion_cmd_tlv, 20113 .send_snr_request_cmd = send_snr_request_cmd_tlv, 20114 .send_snr_cmd = send_snr_cmd_tlv, 20115 .send_link_status_req_cmd = send_link_status_req_cmd_tlv, 20116 #if !defined(REMOVE_PKT_LOG) && defined(FEATURE_PKTLOG) 20117 .send_pktlog_wmi_send_cmd = send_pktlog_wmi_send_cmd_tlv, 20118 #endif 20119 #ifdef WLAN_SUPPORT_GREEN_AP 20120 .send_egap_conf_params_cmd = send_egap_conf_params_cmd_tlv, 20121 .send_green_ap_ps_cmd = send_green_ap_ps_cmd_tlv, 20122 .extract_green_ap_egap_status_info = 20123 extract_green_ap_egap_status_info_tlv, 20124 #endif 20125 #ifdef WLAN_SUPPORT_GAP_LL_PS_MODE 20126 .send_green_ap_ll_ps_cmd = send_green_ap_ll_ps_cmd_tlv, 20127 .extract_green_ap_ll_ps_param = extract_green_ap_ll_ps_param_tlv, 20128 #endif 20129 .send_csa_offload_enable_cmd = send_csa_offload_enable_cmd_tlv, 20130 .send_start_oem_data_cmd = send_start_oem_data_cmd_tlv, 20131 #ifdef FEATURE_OEM_DATA 20132 .send_start_oemv2_data_cmd = send_start_oemv2_data_cmd_tlv, 20133 #endif 20134 #ifdef WLAN_FEATURE_CIF_CFR 20135 .send_oem_dma_cfg_cmd = send_oem_dma_cfg_cmd_tlv, 20136 #endif 20137 .send_dfs_phyerr_filter_offload_en_cmd = 20138 send_dfs_phyerr_filter_offload_en_cmd_tlv, 20139 .send_stats_ext_req_cmd = send_stats_ext_req_cmd_tlv, 20140 .send_process_dhcpserver_offload_cmd = 20141 send_process_dhcpserver_offload_cmd_tlv, 20142 .send_pdev_set_regdomain_cmd = 20143 send_pdev_set_regdomain_cmd_tlv, 20144 .send_regdomain_info_to_fw_cmd = send_regdomain_info_to_fw_cmd_tlv, 20145 .send_cfg_action_frm_tb_ppdu_cmd = send_cfg_action_frm_tb_ppdu_cmd_tlv, 20146 .save_fw_version_cmd = save_fw_version_cmd_tlv, 20147 .check_and_update_fw_version = 20148 check_and_update_fw_version_cmd_tlv, 20149 .send_log_supported_evt_cmd = send_log_supported_evt_cmd_tlv, 20150 .send_enable_specific_fw_logs_cmd = 20151 send_enable_specific_fw_logs_cmd_tlv, 20152 .send_flush_logs_to_fw_cmd = send_flush_logs_to_fw_cmd_tlv, 20153 .send_unit_test_cmd = send_unit_test_cmd_tlv, 20154 #ifdef FEATURE_WLAN_APF 20155 .send_set_active_apf_mode_cmd = wmi_send_set_active_apf_mode_cmd_tlv, 20156 .send_apf_enable_cmd = wmi_send_apf_enable_cmd_tlv, 20157 .send_apf_write_work_memory_cmd = 20158 wmi_send_apf_write_work_memory_cmd_tlv, 20159 .send_apf_read_work_memory_cmd = 20160 wmi_send_apf_read_work_memory_cmd_tlv, 20161 .extract_apf_read_memory_resp_event = 20162 wmi_extract_apf_read_memory_resp_event_tlv, 20163 #endif /* FEATURE_WLAN_APF */ 20164 .init_cmd_send = init_cmd_send_tlv, 20165 .send_vdev_set_custom_aggr_size_cmd = 20166 send_vdev_set_custom_aggr_size_cmd_tlv, 20167 .send_vdev_set_qdepth_thresh_cmd = 20168 send_vdev_set_qdepth_thresh_cmd_tlv, 20169 .send_set_vap_dscp_tid_map_cmd = send_set_vap_dscp_tid_map_cmd_tlv, 20170 .send_vdev_set_fwtest_param_cmd = send_vdev_set_fwtest_param_cmd_tlv, 20171 .send_phyerr_disable_cmd = send_phyerr_disable_cmd_tlv, 20172 .send_phyerr_enable_cmd = send_phyerr_enable_cmd_tlv, 20173 .send_periodic_chan_stats_config_cmd = 20174 send_periodic_chan_stats_config_cmd_tlv, 20175 #ifdef WLAN_IOT_SIM_SUPPORT 20176 .send_simulation_test_cmd = send_simulation_test_cmd_tlv, 20177 #endif 20178 .send_vdev_spectral_configure_cmd = 20179 send_vdev_spectral_configure_cmd_tlv, 20180 .send_vdev_spectral_enable_cmd = 20181 send_vdev_spectral_enable_cmd_tlv, 20182 #ifdef WLAN_CONV_SPECTRAL_ENABLE 20183 .extract_pdev_sscan_fw_cmd_fixed_param = 20184 extract_pdev_sscan_fw_cmd_fixed_param_tlv, 20185 .extract_pdev_sscan_fft_bin_index = 20186 extract_pdev_sscan_fft_bin_index_tlv, 20187 .extract_pdev_spectral_session_chan_info = 20188 extract_pdev_spectral_session_chan_info_tlv, 20189 .extract_pdev_spectral_session_detector_info = 20190 extract_pdev_spectral_session_detector_info_tlv, 20191 .extract_spectral_caps_fixed_param = 20192 extract_spectral_caps_fixed_param_tlv, 20193 .extract_spectral_scan_bw_caps = 20194 extract_spectral_scan_bw_caps_tlv, 20195 .extract_spectral_fft_size_caps = 20196 extract_spectral_fft_size_caps_tlv, 20197 #endif /* WLAN_CONV_SPECTRAL_ENABLE */ 20198 .send_thermal_mitigation_param_cmd = 20199 send_thermal_mitigation_param_cmd_tlv, 20200 .send_process_update_edca_param_cmd = 20201 send_process_update_edca_param_cmd_tlv, 20202 .send_bss_color_change_enable_cmd = 20203 send_bss_color_change_enable_cmd_tlv, 20204 .send_coex_config_cmd = send_coex_config_cmd_tlv, 20205 .send_set_country_cmd = send_set_country_cmd_tlv, 20206 .send_addba_send_cmd = send_addba_send_cmd_tlv, 20207 .send_delba_send_cmd = send_delba_send_cmd_tlv, 20208 .send_addba_clearresponse_cmd = send_addba_clearresponse_cmd_tlv, 20209 .get_target_cap_from_service_ready = extract_service_ready_tlv, 20210 .extract_hal_reg_cap = extract_hal_reg_cap_tlv, 20211 .extract_num_mem_reqs = extract_num_mem_reqs_tlv, 20212 .extract_host_mem_req = extract_host_mem_req_tlv, 20213 .save_service_bitmap = save_service_bitmap_tlv, 20214 .save_ext_service_bitmap = save_ext_service_bitmap_tlv, 20215 .is_service_enabled = is_service_enabled_tlv, 20216 .save_fw_version = save_fw_version_in_service_ready_tlv, 20217 .ready_extract_init_status = ready_extract_init_status_tlv, 20218 .ready_extract_mac_addr = ready_extract_mac_addr_tlv, 20219 .ready_extract_mac_addr_list = ready_extract_mac_addr_list_tlv, 20220 .extract_ready_event_params = extract_ready_event_params_tlv, 20221 .extract_dbglog_data_len = extract_dbglog_data_len_tlv, 20222 .extract_mgmt_rx_params = extract_mgmt_rx_params_tlv, 20223 .extract_frame_pn_params = extract_frame_pn_params_tlv, 20224 .extract_is_conn_ap_frame = extract_is_conn_ap_frm_param_tlv, 20225 .extract_vdev_roam_param = extract_vdev_roam_param_tlv, 20226 .extract_vdev_scan_ev_param = extract_vdev_scan_ev_param_tlv, 20227 #ifdef FEATURE_WLAN_SCAN_PNO 20228 .extract_nlo_match_ev_param = extract_nlo_match_ev_param_tlv, 20229 .extract_nlo_complete_ev_param = extract_nlo_complete_ev_param_tlv, 20230 #endif 20231 .extract_unit_test = extract_unit_test_tlv, 20232 .extract_pdev_ext_stats = extract_pdev_ext_stats_tlv, 20233 .extract_bcn_stats = extract_bcn_stats_tlv, 20234 .extract_bcnflt_stats = extract_bcnflt_stats_tlv, 20235 .extract_chan_stats = extract_chan_stats_tlv, 20236 .extract_vdev_prb_fils_stats = extract_vdev_prb_fils_stats_tlv, 20237 .extract_profile_ctx = extract_profile_ctx_tlv, 20238 .extract_profile_data = extract_profile_data_tlv, 20239 .send_fw_test_cmd = send_fw_test_cmd_tlv, 20240 .send_wfa_test_cmd = send_wfa_test_cmd_tlv, 20241 .send_power_dbg_cmd = send_power_dbg_cmd_tlv, 20242 .extract_service_ready_ext = extract_service_ready_ext_tlv, 20243 .extract_service_ready_ext2 = extract_service_ready_ext2_tlv, 20244 .extract_dbs_or_sbs_service_ready_ext2 = 20245 extract_dbs_or_sbs_cap_service_ready_ext2_tlv, 20246 .extract_hw_mode_cap_service_ready_ext = 20247 extract_hw_mode_cap_service_ready_ext_tlv, 20248 .extract_mac_phy_cap_service_ready_ext = 20249 extract_mac_phy_cap_service_ready_ext_tlv, 20250 .extract_mac_phy_cap_service_ready_ext2 = 20251 extract_mac_phy_cap_service_ready_ext2_tlv, 20252 .extract_reg_cap_service_ready_ext = 20253 extract_reg_cap_service_ready_ext_tlv, 20254 .extract_hal_reg_cap_ext2 = extract_hal_reg_cap_ext2_tlv, 20255 .extract_dbr_ring_cap_service_ready_ext = 20256 extract_dbr_ring_cap_service_ready_ext_tlv, 20257 .extract_dbr_ring_cap_service_ready_ext2 = 20258 extract_dbr_ring_cap_service_ready_ext2_tlv, 20259 .extract_scan_radio_cap_service_ready_ext2 = 20260 extract_scan_radio_cap_service_ready_ext2_tlv, 20261 .extract_sw_cal_ver_ext2 = extract_sw_cal_ver_ext2_tlv, 20262 .extract_sar_cap_service_ready_ext = 20263 extract_sar_cap_service_ready_ext_tlv, 20264 .extract_pdev_utf_event = extract_pdev_utf_event_tlv, 20265 .wmi_set_htc_tx_tag = wmi_set_htc_tx_tag_tlv, 20266 .extract_fips_event_data = extract_fips_event_data_tlv, 20267 #ifdef WLAN_FEATURE_FIPS_BER_CCMGCM 20268 .extract_fips_extend_ev_data = extract_fips_extend_event_data_tlv, 20269 #endif 20270 #if defined(WLAN_SUPPORT_FILS) || defined(CONFIG_BAND_6GHZ) 20271 .send_vdev_fils_enable_cmd = send_vdev_fils_enable_cmd_send, 20272 #endif 20273 #ifdef WLAN_FEATURE_DISA 20274 .extract_encrypt_decrypt_resp_event = 20275 extract_encrypt_decrypt_resp_event_tlv, 20276 #endif 20277 .send_pdev_fips_cmd = send_pdev_fips_cmd_tlv, 20278 #ifdef WLAN_FEATURE_FIPS_BER_CCMGCM 20279 .send_pdev_fips_extend_cmd = send_pdev_fips_extend_cmd_tlv, 20280 .send_pdev_fips_mode_set_cmd = send_pdev_fips_mode_set_cmd_tlv, 20281 #endif 20282 .extract_get_pn_data = extract_get_pn_data_tlv, 20283 .send_pdev_get_pn_cmd = send_pdev_get_pn_cmd_tlv, 20284 .extract_get_rxpn_data = extract_get_rxpn_data_tlv, 20285 .send_pdev_get_rxpn_cmd = send_pdev_get_rxpn_cmd_tlv, 20286 .send_wlan_profile_enable_cmd = send_wlan_profile_enable_cmd_tlv, 20287 #ifdef WLAN_FEATURE_DISA 20288 .send_encrypt_decrypt_send_cmd = send_encrypt_decrypt_send_cmd_tlv, 20289 #endif 20290 .send_wlan_profile_trigger_cmd = send_wlan_profile_trigger_cmd_tlv, 20291 .send_wlan_profile_hist_intvl_cmd = 20292 send_wlan_profile_hist_intvl_cmd_tlv, 20293 .is_management_record = is_management_record_tlv, 20294 .is_diag_event = is_diag_event_tlv, 20295 #ifdef WLAN_FEATURE_ACTION_OUI 20296 .send_action_oui_cmd = send_action_oui_cmd_tlv, 20297 #endif 20298 .send_dfs_phyerr_offload_en_cmd = send_dfs_phyerr_offload_en_cmd_tlv, 20299 #ifdef QCA_SUPPORT_AGILE_DFS 20300 .send_adfs_ch_cfg_cmd = send_adfs_ch_cfg_cmd_tlv, 20301 .send_adfs_ocac_abort_cmd = send_adfs_ocac_abort_cmd_tlv, 20302 #endif 20303 .send_dfs_phyerr_offload_dis_cmd = send_dfs_phyerr_offload_dis_cmd_tlv, 20304 .extract_reg_chan_list_update_event = 20305 extract_reg_chan_list_update_event_tlv, 20306 #ifdef CONFIG_BAND_6GHZ 20307 .extract_reg_chan_list_ext_update_event = 20308 extract_reg_chan_list_ext_update_event_tlv, 20309 #ifdef CONFIG_AFC_SUPPORT 20310 .extract_afc_event = extract_afc_event_tlv, 20311 #endif 20312 #endif 20313 #ifdef WLAN_SUPPORT_RF_CHARACTERIZATION 20314 .extract_num_rf_characterization_entries = 20315 extract_num_rf_characterization_entries_tlv, 20316 .extract_rf_characterization_entries = 20317 extract_rf_characterization_entries_tlv, 20318 #endif 20319 .extract_chainmask_tables = 20320 extract_chainmask_tables_tlv, 20321 .extract_thermal_stats = extract_thermal_stats_tlv, 20322 .extract_thermal_level_stats = extract_thermal_level_stats_tlv, 20323 .send_get_rcpi_cmd = send_get_rcpi_cmd_tlv, 20324 .extract_rcpi_response_event = extract_rcpi_response_event_tlv, 20325 #ifdef DFS_COMPONENT_ENABLE 20326 .extract_dfs_cac_complete_event = extract_dfs_cac_complete_event_tlv, 20327 .extract_dfs_ocac_complete_event = extract_dfs_ocac_complete_event_tlv, 20328 .extract_dfs_radar_detection_event = 20329 extract_dfs_radar_detection_event_tlv, 20330 .extract_wlan_radar_event_info = extract_wlan_radar_event_info_tlv, 20331 #endif 20332 .convert_pdev_id_host_to_target = 20333 convert_host_pdev_id_to_target_pdev_id_legacy, 20334 .convert_pdev_id_target_to_host = 20335 convert_target_pdev_id_to_host_pdev_id_legacy, 20336 20337 .convert_host_pdev_id_to_target = 20338 convert_host_pdev_id_to_target_pdev_id, 20339 .convert_target_pdev_id_to_host = 20340 convert_target_pdev_id_to_host_pdev_id, 20341 20342 .convert_host_vdev_param_tlv = convert_host_vdev_param_tlv, 20343 20344 .convert_phy_id_host_to_target = 20345 convert_host_phy_id_to_target_phy_id_legacy, 20346 .convert_phy_id_target_to_host = 20347 convert_target_phy_id_to_host_phy_id_legacy, 20348 20349 .convert_host_phy_id_to_target = 20350 convert_host_phy_id_to_target_phy_id, 20351 .convert_target_phy_id_to_host = 20352 convert_target_phy_id_to_host_phy_id, 20353 20354 .send_start_11d_scan_cmd = send_start_11d_scan_cmd_tlv, 20355 .send_stop_11d_scan_cmd = send_stop_11d_scan_cmd_tlv, 20356 .extract_reg_11d_new_country_event = 20357 extract_reg_11d_new_country_event_tlv, 20358 .send_user_country_code_cmd = send_user_country_code_cmd_tlv, 20359 .extract_reg_ch_avoid_event = 20360 extract_reg_ch_avoid_event_tlv, 20361 .send_obss_detection_cfg_cmd = send_obss_detection_cfg_cmd_tlv, 20362 .extract_obss_detection_info = extract_obss_detection_info_tlv, 20363 .wmi_pdev_id_conversion_enable = wmi_tlv_pdev_id_conversion_enable, 20364 .wmi_free_allocated_event = wmitlv_free_allocated_event_tlvs, 20365 .wmi_check_and_pad_event = wmitlv_check_and_pad_event_tlvs, 20366 .wmi_check_command_params = wmitlv_check_command_tlv_params, 20367 .extract_comb_phyerr = extract_comb_phyerr_tlv, 20368 .extract_single_phyerr = extract_single_phyerr_tlv, 20369 #ifdef QCA_SUPPORT_CP_STATS 20370 .extract_cca_stats = extract_cca_stats_tlv, 20371 #endif 20372 .extract_esp_estimation_ev_param = 20373 extract_esp_estimation_ev_param_tlv, 20374 .send_roam_scan_stats_cmd = send_roam_scan_stats_cmd_tlv, 20375 .extract_roam_scan_stats_res_evt = extract_roam_scan_stats_res_evt_tlv, 20376 #ifdef OBSS_PD 20377 .send_obss_spatial_reuse_set = send_obss_spatial_reuse_set_cmd_tlv, 20378 .send_obss_spatial_reuse_set_def_thresh = 20379 send_obss_spatial_reuse_set_def_thresh_cmd_tlv, 20380 .send_self_srg_bss_color_bitmap_set = 20381 send_self_srg_bss_color_bitmap_set_cmd_tlv, 20382 .send_self_srg_partial_bssid_bitmap_set = 20383 send_self_srg_partial_bssid_bitmap_set_cmd_tlv, 20384 .send_self_srg_obss_color_enable_bitmap = 20385 send_self_srg_obss_color_enable_bitmap_cmd_tlv, 20386 .send_self_srg_obss_bssid_enable_bitmap = 20387 send_self_srg_obss_bssid_enable_bitmap_cmd_tlv, 20388 .send_self_non_srg_obss_color_enable_bitmap = 20389 send_self_non_srg_obss_color_enable_bitmap_cmd_tlv, 20390 .send_self_non_srg_obss_bssid_enable_bitmap = 20391 send_self_non_srg_obss_bssid_enable_bitmap_cmd_tlv, 20392 #endif 20393 .extract_offload_bcn_tx_status_evt = extract_offload_bcn_tx_status_evt, 20394 .extract_ctl_failsafe_check_ev_param = 20395 extract_ctl_failsafe_check_ev_param_tlv, 20396 #ifdef WIFI_POS_CONVERGED 20397 .extract_oem_response_param = extract_oem_response_param_tlv, 20398 #endif /* WIFI_POS_CONVERGED */ 20399 #if defined(WIFI_POS_CONVERGED) && defined(WLAN_FEATURE_RTT_11AZ_SUPPORT) 20400 .extract_pasn_peer_create_req_event = 20401 extract_pasn_peer_create_req_event_tlv, 20402 .extract_pasn_peer_delete_req_event = 20403 extract_pasn_peer_delete_req_event_tlv, 20404 .send_rtt_pasn_auth_status_cmd = 20405 send_rtt_pasn_auth_status_cmd_tlv, 20406 .send_rtt_pasn_deauth_cmd = 20407 send_rtt_pasn_deauth_cmd_tlv, 20408 #endif 20409 #ifdef WLAN_MWS_INFO_DEBUGFS 20410 .send_mws_coex_status_req_cmd = send_mws_coex_status_req_cmd_tlv, 20411 #endif 20412 .extract_hw_mode_resp_event = extract_hw_mode_resp_event_status_tlv, 20413 #ifdef FEATURE_ANI_LEVEL_REQUEST 20414 .send_ani_level_cmd = send_ani_level_cmd_tlv, 20415 .extract_ani_level = extract_ani_level_tlv, 20416 #endif /* FEATURE_ANI_LEVEL_REQUEST */ 20417 .extract_roam_trigger_stats = extract_roam_trigger_stats_tlv, 20418 .extract_roam_scan_stats = extract_roam_scan_stats_tlv, 20419 .extract_roam_result_stats = extract_roam_result_stats_tlv, 20420 .extract_roam_11kv_stats = extract_roam_11kv_stats_tlv, 20421 #ifdef WLAN_FEATURE_PKT_CAPTURE 20422 .extract_vdev_mgmt_offload_event = extract_vdev_mgmt_offload_event_tlv, 20423 #endif 20424 #ifdef WLAN_FEATURE_PKT_CAPTURE_V2 20425 .extract_smart_monitor_event = extract_smart_monitor_event_tlv, 20426 #endif 20427 20428 #ifdef FEATURE_WLAN_TIME_SYNC_FTM 20429 .send_wlan_time_sync_ftm_trigger_cmd = send_wlan_ts_ftm_trigger_cmd_tlv, 20430 .send_wlan_ts_qtime_cmd = send_wlan_ts_qtime_cmd_tlv, 20431 .extract_time_sync_ftm_start_stop_event = 20432 extract_time_sync_ftm_start_stop_event_tlv, 20433 .extract_time_sync_ftm_offset_event = 20434 extract_time_sync_ftm_offset_event_tlv, 20435 #endif /* FEATURE_WLAN_TIME_SYNC_FTM */ 20436 .send_roam_scan_ch_list_req_cmd = send_roam_scan_ch_list_req_cmd_tlv, 20437 .send_injector_config_cmd = send_injector_config_cmd_tlv, 20438 .send_cp_stats_cmd = send_cp_stats_cmd_tlv, 20439 .send_halphy_stats_cmd = send_halphy_stats_cmd_tlv, 20440 #ifdef FEATURE_MEC_OFFLOAD 20441 .send_pdev_set_mec_timer_cmd = send_pdev_set_mec_timer_cmd_tlv, 20442 #endif 20443 #if defined(WLAN_SUPPORT_INFRA_CTRL_PATH_STATS) || defined(WLAN_TELEMETRY_STATS_SUPPORT) 20444 .extract_infra_cp_stats = extract_infra_cp_stats_tlv, 20445 #endif /* WLAN_SUPPORT_INFRA_CTRL_PATH_STATS */ 20446 .extract_cp_stats_more_pending = 20447 extract_cp_stats_more_pending_tlv, 20448 .extract_halphy_stats_end_of_event = 20449 extract_halphy_stats_end_of_event_tlv, 20450 .extract_halphy_stats_event_count = 20451 extract_halphy_stats_event_count_tlv, 20452 .send_vdev_tsf_tstamp_action_cmd = send_vdev_tsf_tstamp_action_cmd_tlv, 20453 .extract_vdev_tsf_report_event = extract_vdev_tsf_report_event_tlv, 20454 .extract_pdev_csa_switch_count_status = 20455 extract_pdev_csa_switch_count_status_tlv, 20456 .send_set_tpc_power_cmd = send_set_tpc_power_cmd_tlv, 20457 #ifdef CONFIG_AFC_SUPPORT 20458 .send_afc_cmd = send_afc_cmd_tlv, 20459 #endif 20460 .extract_dpd_status_ev_param = extract_dpd_status_ev_param_tlv, 20461 .extract_install_key_comp_event = extract_install_key_comp_event_tlv, 20462 .send_vdev_set_ltf_key_seed_cmd = 20463 send_vdev_set_ltf_key_seed_cmd_tlv, 20464 .extract_halphy_cal_status_ev_param = extract_halphy_cal_status_ev_param_tlv, 20465 .send_set_halphy_cal = send_set_halphy_cal_tlv, 20466 .extract_halphy_cal_ev_param = extract_halphy_cal_ev_param_tlv, 20467 #ifdef WLAN_MGMT_RX_REO_SUPPORT 20468 .extract_mgmt_rx_fw_consumed = extract_mgmt_rx_fw_consumed_tlv, 20469 .extract_mgmt_rx_reo_params = extract_mgmt_rx_reo_params_tlv, 20470 .send_mgmt_rx_reo_filter_config_cmd = 20471 send_mgmt_rx_reo_filter_config_cmd_tlv, 20472 #endif 20473 20474 #ifdef WLAN_FEATURE_ROAM_OFFLOAD 20475 .send_roam_set_param_cmd = send_roam_set_param_cmd_tlv, 20476 #endif /* WLAN_FEATURE_ROAM_OFFLOAD */ 20477 20478 #ifdef WLAN_FEATURE_DYNAMIC_MAC_ADDR_UPDATE 20479 .send_set_mac_address_cmd = send_set_mac_address_cmd_tlv, 20480 .extract_update_mac_address_event = 20481 extract_update_mac_address_event_tlv, 20482 #endif 20483 20484 #ifdef WLAN_FEATURE_11BE_MLO 20485 .extract_quiet_offload_event = 20486 extract_quiet_offload_event_tlv, 20487 #endif 20488 20489 #ifdef WLAN_SUPPORT_PPEDS 20490 .peer_ppe_ds_param_send = peer_ppe_ds_param_send_tlv, 20491 #endif /* WLAN_SUPPORT_PPEDS */ 20492 20493 .send_vdev_pn_mgmt_rxfilter_cmd = send_vdev_pn_mgmt_rxfilter_cmd_tlv, 20494 .extract_pktlog_decode_info_event = 20495 extract_pktlog_decode_info_event_tlv, 20496 .extract_pdev_telemetry_stats = extract_pdev_telemetry_stats_tlv, 20497 .extract_mgmt_rx_ext_params = extract_mgmt_rx_ext_params_tlv, 20498 #ifdef WLAN_FEATURE_PEER_TXQ_FLUSH_CONF 20499 .send_peer_txq_flush_config_cmd = send_peer_txq_flush_config_cmd_tlv, 20500 #endif 20501 #ifdef WLAN_FEATURE_DBAM_CONFIG 20502 .send_dbam_config_cmd = send_dbam_config_cmd_tlv, 20503 .extract_dbam_config_resp_event = extract_dbam_config_resp_event_tlv, 20504 #endif 20505 #ifdef FEATURE_SET 20506 .feature_set_cmd_send = feature_set_cmd_send_tlv, 20507 #endif 20508 #ifdef HEALTH_MON_SUPPORT 20509 .extract_health_mon_init_done_info_event = 20510 extract_health_mon_init_done_info_event_tlv, 20511 #endif /* HEALTH_MON_SUPPORT */ 20512 .send_multiple_vdev_param_cmd = send_multiple_vdev_param_cmd_tlv, 20513 .set_mac_addr_rx_filter = send_set_mac_addr_rx_filter_cmd_tlv, 20514 .send_update_edca_pifs_param_cmd = 20515 send_update_edca_pifs_param_cmd_tlv, 20516 .extract_sap_coex_cap_service_ready_ext2 = 20517 extract_sap_coex_fix_chan_caps, 20518 }; 20519 20520 #ifdef WLAN_FEATURE_11BE_MLO 20521 static void populate_tlv_events_id_mlo(WMI_EVT_ID *event_ids) 20522 { 20523 event_ids[wmi_mlo_setup_complete_event_id] = 20524 WMI_MLO_SETUP_COMPLETE_EVENTID; 20525 event_ids[wmi_mlo_teardown_complete_event_id] = 20526 WMI_MLO_TEARDOWN_COMPLETE_EVENTID; 20527 event_ids[wmi_mlo_link_set_active_resp_eventid] = 20528 WMI_MLO_LINK_SET_ACTIVE_RESP_EVENTID; 20529 event_ids[wmi_vdev_quiet_offload_eventid] = 20530 WMI_QUIET_HANDLING_EVENTID; 20531 event_ids[wmi_mlo_ap_vdev_tid_to_link_map_eventid] = 20532 WMI_MLO_AP_VDEV_TID_TO_LINK_MAP_EVENTID; 20533 event_ids[wmi_mlo_link_removal_eventid] = 20534 WMI_MLO_LINK_REMOVAL_EVENTID; 20535 } 20536 #else /* WLAN_FEATURE_11BE_MLO */ 20537 static inline void populate_tlv_events_id_mlo(WMI_EVT_ID *event_ids) 20538 { 20539 } 20540 #endif /* WLAN_FEATURE_11BE_MLO */ 20541 20542 /** 20543 * populate_tlv_events_id() - populates wmi event ids 20544 * @event_ids: Pointer to hold event ids 20545 * 20546 * Return: None 20547 */ 20548 static void populate_tlv_events_id(WMI_EVT_ID *event_ids) 20549 { 20550 event_ids[wmi_service_ready_event_id] = WMI_SERVICE_READY_EVENTID; 20551 event_ids[wmi_ready_event_id] = WMI_READY_EVENTID; 20552 event_ids[wmi_scan_event_id] = WMI_SCAN_EVENTID; 20553 event_ids[wmi_pdev_tpc_config_event_id] = WMI_PDEV_TPC_CONFIG_EVENTID; 20554 event_ids[wmi_chan_info_event_id] = WMI_CHAN_INFO_EVENTID; 20555 event_ids[wmi_phyerr_event_id] = WMI_PHYERR_EVENTID; 20556 event_ids[wmi_pdev_dump_event_id] = WMI_PDEV_DUMP_EVENTID; 20557 event_ids[wmi_tx_pause_event_id] = WMI_TX_PAUSE_EVENTID; 20558 event_ids[wmi_dfs_radar_event_id] = WMI_DFS_RADAR_EVENTID; 20559 event_ids[wmi_pdev_l1ss_track_event_id] = WMI_PDEV_L1SS_TRACK_EVENTID; 20560 event_ids[wmi_pdev_temperature_event_id] = WMI_PDEV_TEMPERATURE_EVENTID; 20561 event_ids[wmi_service_ready_ext_event_id] = 20562 WMI_SERVICE_READY_EXT_EVENTID; 20563 event_ids[wmi_service_ready_ext2_event_id] = 20564 WMI_SERVICE_READY_EXT2_EVENTID; 20565 event_ids[wmi_vdev_start_resp_event_id] = WMI_VDEV_START_RESP_EVENTID; 20566 event_ids[wmi_vdev_stopped_event_id] = WMI_VDEV_STOPPED_EVENTID; 20567 event_ids[wmi_vdev_install_key_complete_event_id] = 20568 WMI_VDEV_INSTALL_KEY_COMPLETE_EVENTID; 20569 event_ids[wmi_vdev_mcc_bcn_intvl_change_req_event_id] = 20570 WMI_VDEV_MCC_BCN_INTERVAL_CHANGE_REQ_EVENTID; 20571 20572 event_ids[wmi_vdev_tsf_report_event_id] = WMI_VDEV_TSF_REPORT_EVENTID; 20573 event_ids[wmi_peer_sta_kickout_event_id] = WMI_PEER_STA_KICKOUT_EVENTID; 20574 event_ids[wmi_peer_info_event_id] = WMI_PEER_INFO_EVENTID; 20575 event_ids[wmi_peer_tx_fail_cnt_thr_event_id] = 20576 WMI_PEER_TX_FAIL_CNT_THR_EVENTID; 20577 event_ids[wmi_peer_estimated_linkspeed_event_id] = 20578 WMI_PEER_ESTIMATED_LINKSPEED_EVENTID; 20579 event_ids[wmi_peer_state_event_id] = WMI_PEER_STATE_EVENTID; 20580 event_ids[wmi_peer_create_conf_event_id] = 20581 WMI_PEER_CREATE_CONF_EVENTID; 20582 event_ids[wmi_peer_delete_response_event_id] = 20583 WMI_PEER_DELETE_RESP_EVENTID; 20584 event_ids[wmi_peer_delete_all_response_event_id] = 20585 WMI_VDEV_DELETE_ALL_PEER_RESP_EVENTID; 20586 event_ids[wmi_mgmt_rx_event_id] = WMI_MGMT_RX_EVENTID; 20587 event_ids[wmi_host_swba_event_id] = WMI_HOST_SWBA_EVENTID; 20588 event_ids[wmi_tbttoffset_update_event_id] = 20589 WMI_TBTTOFFSET_UPDATE_EVENTID; 20590 event_ids[wmi_ext_tbttoffset_update_event_id] = 20591 WMI_TBTTOFFSET_EXT_UPDATE_EVENTID; 20592 event_ids[wmi_offload_bcn_tx_status_event_id] = 20593 WMI_OFFLOAD_BCN_TX_STATUS_EVENTID; 20594 event_ids[wmi_offload_prob_resp_tx_status_event_id] = 20595 WMI_OFFLOAD_PROB_RESP_TX_STATUS_EVENTID; 20596 event_ids[wmi_mgmt_tx_completion_event_id] = 20597 WMI_MGMT_TX_COMPLETION_EVENTID; 20598 event_ids[wmi_pdev_nfcal_power_all_channels_event_id] = 20599 WMI_PDEV_NFCAL_POWER_ALL_CHANNELS_EVENTID; 20600 event_ids[wmi_tx_delba_complete_event_id] = 20601 WMI_TX_DELBA_COMPLETE_EVENTID; 20602 event_ids[wmi_tx_addba_complete_event_id] = 20603 WMI_TX_ADDBA_COMPLETE_EVENTID; 20604 event_ids[wmi_ba_rsp_ssn_event_id] = WMI_BA_RSP_SSN_EVENTID; 20605 20606 event_ids[wmi_aggr_state_trig_event_id] = WMI_AGGR_STATE_TRIG_EVENTID; 20607 20608 event_ids[wmi_roam_event_id] = WMI_ROAM_EVENTID; 20609 event_ids[wmi_profile_match] = WMI_PROFILE_MATCH; 20610 20611 event_ids[wmi_roam_synch_event_id] = WMI_ROAM_SYNCH_EVENTID; 20612 event_ids[wmi_roam_synch_frame_event_id] = WMI_ROAM_SYNCH_FRAME_EVENTID; 20613 20614 event_ids[wmi_p2p_disc_event_id] = WMI_P2P_DISC_EVENTID; 20615 20616 event_ids[wmi_p2p_noa_event_id] = WMI_P2P_NOA_EVENTID; 20617 event_ids[wmi_p2p_lo_stop_event_id] = 20618 WMI_P2P_LISTEN_OFFLOAD_STOPPED_EVENTID; 20619 event_ids[wmi_vdev_add_macaddr_rx_filter_event_id] = 20620 WMI_VDEV_ADD_MAC_ADDR_TO_RX_FILTER_STATUS_EVENTID; 20621 event_ids[wmi_pdev_resume_event_id] = WMI_PDEV_RESUME_EVENTID; 20622 event_ids[wmi_wow_wakeup_host_event_id] = WMI_WOW_WAKEUP_HOST_EVENTID; 20623 event_ids[wmi_d0_wow_disable_ack_event_id] = 20624 WMI_D0_WOW_DISABLE_ACK_EVENTID; 20625 event_ids[wmi_wow_initial_wakeup_event_id] = 20626 WMI_WOW_INITIAL_WAKEUP_EVENTID; 20627 20628 event_ids[wmi_rtt_meas_report_event_id] = 20629 WMI_RTT_MEASUREMENT_REPORT_EVENTID; 20630 event_ids[wmi_tsf_meas_report_event_id] = 20631 WMI_TSF_MEASUREMENT_REPORT_EVENTID; 20632 event_ids[wmi_rtt_error_report_event_id] = WMI_RTT_ERROR_REPORT_EVENTID; 20633 event_ids[wmi_stats_ext_event_id] = WMI_STATS_EXT_EVENTID; 20634 event_ids[wmi_iface_link_stats_event_id] = WMI_IFACE_LINK_STATS_EVENTID; 20635 event_ids[wmi_peer_link_stats_event_id] = WMI_PEER_LINK_STATS_EVENTID; 20636 event_ids[wmi_radio_link_stats_link] = WMI_RADIO_LINK_STATS_EVENTID; 20637 event_ids[wmi_diag_event_id_log_supported_event_id] = 20638 WMI_DIAG_EVENT_LOG_SUPPORTED_EVENTID; 20639 event_ids[wmi_nlo_match_event_id] = WMI_NLO_MATCH_EVENTID; 20640 event_ids[wmi_nlo_scan_complete_event_id] = 20641 WMI_NLO_SCAN_COMPLETE_EVENTID; 20642 event_ids[wmi_apfind_event_id] = WMI_APFIND_EVENTID; 20643 event_ids[wmi_passpoint_match_event_id] = WMI_PASSPOINT_MATCH_EVENTID; 20644 20645 event_ids[wmi_gtk_offload_status_event_id] = 20646 WMI_GTK_OFFLOAD_STATUS_EVENTID; 20647 event_ids[wmi_gtk_rekey_fail_event_id] = WMI_GTK_REKEY_FAIL_EVENTID; 20648 event_ids[wmi_csa_handling_event_id] = WMI_CSA_HANDLING_EVENTID; 20649 event_ids[wmi_chatter_pc_query_event_id] = WMI_CHATTER_PC_QUERY_EVENTID; 20650 20651 event_ids[wmi_echo_event_id] = WMI_ECHO_EVENTID; 20652 20653 event_ids[wmi_pdev_utf_event_id] = WMI_PDEV_UTF_EVENTID; 20654 20655 event_ids[wmi_dbg_msg_event_id] = WMI_DEBUG_MESG_EVENTID; 20656 event_ids[wmi_update_stats_event_id] = WMI_UPDATE_STATS_EVENTID; 20657 event_ids[wmi_debug_print_event_id] = WMI_DEBUG_PRINT_EVENTID; 20658 event_ids[wmi_dcs_interference_event_id] = WMI_DCS_INTERFERENCE_EVENTID; 20659 event_ids[wmi_pdev_qvit_event_id] = WMI_PDEV_QVIT_EVENTID; 20660 event_ids[wmi_wlan_profile_data_event_id] = 20661 WMI_WLAN_PROFILE_DATA_EVENTID; 20662 event_ids[wmi_pdev_ftm_intg_event_id] = WMI_PDEV_FTM_INTG_EVENTID; 20663 event_ids[wmi_wlan_freq_avoid_event_id] = WMI_WLAN_FREQ_AVOID_EVENTID; 20664 event_ids[wmi_vdev_get_keepalive_event_id] = 20665 WMI_VDEV_GET_KEEPALIVE_EVENTID; 20666 event_ids[wmi_thermal_mgmt_event_id] = WMI_THERMAL_MGMT_EVENTID; 20667 20668 event_ids[wmi_diag_container_event_id] = 20669 WMI_DIAG_DATA_CONTAINER_EVENTID; 20670 20671 event_ids[wmi_host_auto_shutdown_event_id] = 20672 WMI_HOST_AUTO_SHUTDOWN_EVENTID; 20673 20674 event_ids[wmi_update_whal_mib_stats_event_id] = 20675 WMI_UPDATE_WHAL_MIB_STATS_EVENTID; 20676 20677 /*update ht/vht info based on vdev (rx and tx NSS and preamble) */ 20678 event_ids[wmi_update_vdev_rate_stats_event_id] = 20679 WMI_UPDATE_VDEV_RATE_STATS_EVENTID; 20680 20681 event_ids[wmi_diag_event_id] = WMI_DIAG_EVENTID; 20682 event_ids[wmi_unit_test_event_id] = WMI_UNIT_TEST_EVENTID; 20683 20684 /** Set OCB Sched Response, deprecated */ 20685 event_ids[wmi_ocb_set_sched_event_id] = WMI_OCB_SET_SCHED_EVENTID; 20686 20687 event_ids[wmi_dbg_mesg_flush_complete_event_id] = 20688 WMI_DEBUG_MESG_FLUSH_COMPLETE_EVENTID; 20689 event_ids[wmi_rssi_breach_event_id] = WMI_RSSI_BREACH_EVENTID; 20690 20691 /* GPIO Event */ 20692 event_ids[wmi_gpio_input_event_id] = WMI_GPIO_INPUT_EVENTID; 20693 event_ids[wmi_uploadh_event_id] = WMI_UPLOADH_EVENTID; 20694 20695 event_ids[wmi_captureh_event_id] = WMI_CAPTUREH_EVENTID; 20696 event_ids[wmi_rfkill_state_change_event_id] = 20697 WMI_RFKILL_STATE_CHANGE_EVENTID; 20698 20699 /* TDLS Event */ 20700 event_ids[wmi_tdls_peer_event_id] = WMI_TDLS_PEER_EVENTID; 20701 20702 event_ids[wmi_batch_scan_enabled_event_id] = 20703 WMI_BATCH_SCAN_ENABLED_EVENTID; 20704 event_ids[wmi_batch_scan_result_event_id] = 20705 WMI_BATCH_SCAN_RESULT_EVENTID; 20706 /* OEM Event */ 20707 event_ids[wmi_oem_cap_event_id] = WMI_OEM_CAPABILITY_EVENTID; 20708 event_ids[wmi_oem_meas_report_event_id] = 20709 WMI_OEM_MEASUREMENT_REPORT_EVENTID; 20710 event_ids[wmi_oem_report_event_id] = WMI_OEM_ERROR_REPORT_EVENTID; 20711 20712 /* NAN Event */ 20713 event_ids[wmi_nan_event_id] = WMI_NAN_EVENTID; 20714 20715 /* LPI Event */ 20716 event_ids[wmi_lpi_result_event_id] = WMI_LPI_RESULT_EVENTID; 20717 event_ids[wmi_lpi_status_event_id] = WMI_LPI_STATUS_EVENTID; 20718 event_ids[wmi_lpi_handoff_event_id] = WMI_LPI_HANDOFF_EVENTID; 20719 20720 /* ExtScan events */ 20721 event_ids[wmi_extscan_start_stop_event_id] = 20722 WMI_EXTSCAN_START_STOP_EVENTID; 20723 event_ids[wmi_extscan_operation_event_id] = 20724 WMI_EXTSCAN_OPERATION_EVENTID; 20725 event_ids[wmi_extscan_table_usage_event_id] = 20726 WMI_EXTSCAN_TABLE_USAGE_EVENTID; 20727 event_ids[wmi_extscan_cached_results_event_id] = 20728 WMI_EXTSCAN_CACHED_RESULTS_EVENTID; 20729 event_ids[wmi_extscan_wlan_change_results_event_id] = 20730 WMI_EXTSCAN_WLAN_CHANGE_RESULTS_EVENTID; 20731 event_ids[wmi_extscan_hotlist_match_event_id] = 20732 WMI_EXTSCAN_HOTLIST_MATCH_EVENTID; 20733 event_ids[wmi_extscan_capabilities_event_id] = 20734 WMI_EXTSCAN_CAPABILITIES_EVENTID; 20735 event_ids[wmi_extscan_hotlist_ssid_match_event_id] = 20736 WMI_EXTSCAN_HOTLIST_SSID_MATCH_EVENTID; 20737 20738 /* mDNS offload events */ 20739 event_ids[wmi_mdns_stats_event_id] = WMI_MDNS_STATS_EVENTID; 20740 20741 /* SAP Authentication offload events */ 20742 event_ids[wmi_sap_ofl_add_sta_event_id] = WMI_SAP_OFL_ADD_STA_EVENTID; 20743 event_ids[wmi_sap_ofl_del_sta_event_id] = WMI_SAP_OFL_DEL_STA_EVENTID; 20744 20745 /** Out-of-context-of-bss (OCB) events */ 20746 event_ids[wmi_ocb_set_config_resp_event_id] = 20747 WMI_OCB_SET_CONFIG_RESP_EVENTID; 20748 event_ids[wmi_ocb_get_tsf_timer_resp_event_id] = 20749 WMI_OCB_GET_TSF_TIMER_RESP_EVENTID; 20750 event_ids[wmi_dcc_get_stats_resp_event_id] = 20751 WMI_DCC_GET_STATS_RESP_EVENTID; 20752 event_ids[wmi_dcc_update_ndl_resp_event_id] = 20753 WMI_DCC_UPDATE_NDL_RESP_EVENTID; 20754 event_ids[wmi_dcc_stats_event_id] = WMI_DCC_STATS_EVENTID; 20755 /* System-On-Chip events */ 20756 event_ids[wmi_soc_set_hw_mode_resp_event_id] = 20757 WMI_SOC_SET_HW_MODE_RESP_EVENTID; 20758 event_ids[wmi_soc_hw_mode_transition_event_id] = 20759 WMI_SOC_HW_MODE_TRANSITION_EVENTID; 20760 event_ids[wmi_soc_set_dual_mac_config_resp_event_id] = 20761 WMI_SOC_SET_DUAL_MAC_CONFIG_RESP_EVENTID; 20762 event_ids[wmi_pdev_fips_event_id] = WMI_PDEV_FIPS_EVENTID; 20763 #ifdef WLAN_FEATURE_FIPS_BER_CCMGCM 20764 event_ids[wmi_pdev_fips_extend_event_id] = WMI_PDEV_FIPS_EXTEND_EVENTID; 20765 #endif 20766 event_ids[wmi_pdev_csa_switch_count_status_event_id] = 20767 WMI_PDEV_CSA_SWITCH_COUNT_STATUS_EVENTID; 20768 event_ids[wmi_vdev_ocac_complete_event_id] = 20769 WMI_VDEV_ADFS_OCAC_COMPLETE_EVENTID; 20770 event_ids[wmi_reg_chan_list_cc_event_id] = WMI_REG_CHAN_LIST_CC_EVENTID; 20771 event_ids[wmi_reg_chan_list_cc_ext_event_id] = 20772 WMI_REG_CHAN_LIST_CC_EXT_EVENTID; 20773 #ifdef CONFIG_AFC_SUPPORT 20774 event_ids[wmi_afc_event_id] = WMI_AFC_EVENTID, 20775 #endif 20776 event_ids[wmi_inst_rssi_stats_event_id] = WMI_INST_RSSI_STATS_EVENTID; 20777 event_ids[wmi_pdev_tpc_config_event_id] = WMI_PDEV_TPC_CONFIG_EVENTID; 20778 event_ids[wmi_peer_sta_ps_statechg_event_id] = 20779 WMI_PEER_STA_PS_STATECHG_EVENTID; 20780 event_ids[wmi_pdev_channel_hopping_event_id] = 20781 WMI_PDEV_CHANNEL_HOPPING_EVENTID; 20782 event_ids[wmi_offchan_data_tx_completion_event] = 20783 WMI_OFFCHAN_DATA_TX_COMPLETION_EVENTID; 20784 event_ids[wmi_dfs_cac_complete_id] = WMI_VDEV_DFS_CAC_COMPLETE_EVENTID; 20785 event_ids[wmi_dfs_radar_detection_event_id] = 20786 WMI_PDEV_DFS_RADAR_DETECTION_EVENTID; 20787 event_ids[wmi_tt_stats_event_id] = WMI_THERM_THROT_STATS_EVENTID; 20788 event_ids[wmi_11d_new_country_event_id] = WMI_11D_NEW_COUNTRY_EVENTID; 20789 event_ids[wmi_pdev_tpc_event_id] = WMI_PDEV_TPC_EVENTID; 20790 event_ids[wmi_get_arp_stats_req_id] = WMI_VDEV_GET_ARP_STAT_EVENTID; 20791 event_ids[wmi_service_available_event_id] = 20792 WMI_SERVICE_AVAILABLE_EVENTID; 20793 event_ids[wmi_update_rcpi_event_id] = WMI_UPDATE_RCPI_EVENTID; 20794 event_ids[wmi_pdev_check_cal_version_event_id] = WMI_PDEV_CHECK_CAL_VERSION_EVENTID; 20795 /* NDP events */ 20796 event_ids[wmi_ndp_initiator_rsp_event_id] = 20797 WMI_NDP_INITIATOR_RSP_EVENTID; 20798 event_ids[wmi_ndp_indication_event_id] = WMI_NDP_INDICATION_EVENTID; 20799 event_ids[wmi_ndp_confirm_event_id] = WMI_NDP_CONFIRM_EVENTID; 20800 event_ids[wmi_ndp_responder_rsp_event_id] = 20801 WMI_NDP_RESPONDER_RSP_EVENTID; 20802 event_ids[wmi_ndp_end_indication_event_id] = 20803 WMI_NDP_END_INDICATION_EVENTID; 20804 event_ids[wmi_ndp_end_rsp_event_id] = WMI_NDP_END_RSP_EVENTID; 20805 event_ids[wmi_ndl_schedule_update_event_id] = 20806 WMI_NDL_SCHEDULE_UPDATE_EVENTID; 20807 event_ids[wmi_ndp_event_id] = WMI_NDP_EVENTID; 20808 20809 event_ids[wmi_oem_response_event_id] = WMI_OEM_RESPONSE_EVENTID; 20810 event_ids[wmi_peer_stats_info_event_id] = WMI_PEER_STATS_INFO_EVENTID; 20811 event_ids[wmi_pdev_chip_power_stats_event_id] = 20812 WMI_PDEV_CHIP_POWER_STATS_EVENTID; 20813 event_ids[wmi_ap_ps_egap_info_event_id] = WMI_AP_PS_EGAP_INFO_EVENTID; 20814 event_ids[wmi_peer_assoc_conf_event_id] = WMI_PEER_ASSOC_CONF_EVENTID; 20815 event_ids[wmi_vdev_delete_resp_event_id] = WMI_VDEV_DELETE_RESP_EVENTID; 20816 event_ids[wmi_apf_capability_info_event_id] = 20817 WMI_BPF_CAPABILIY_INFO_EVENTID; 20818 event_ids[wmi_vdev_encrypt_decrypt_data_rsp_event_id] = 20819 WMI_VDEV_ENCRYPT_DECRYPT_DATA_RESP_EVENTID; 20820 event_ids[wmi_report_rx_aggr_failure_event_id] = 20821 WMI_REPORT_RX_AGGR_FAILURE_EVENTID; 20822 event_ids[wmi_pdev_chip_pwr_save_failure_detect_event_id] = 20823 WMI_PDEV_CHIP_POWER_SAVE_FAILURE_DETECTED_EVENTID; 20824 event_ids[wmi_peer_antdiv_info_event_id] = WMI_PEER_ANTDIV_INFO_EVENTID; 20825 event_ids[wmi_pdev_set_hw_mode_rsp_event_id] = 20826 WMI_PDEV_SET_HW_MODE_RESP_EVENTID; 20827 event_ids[wmi_pdev_hw_mode_transition_event_id] = 20828 WMI_PDEV_HW_MODE_TRANSITION_EVENTID; 20829 event_ids[wmi_pdev_set_mac_config_resp_event_id] = 20830 WMI_PDEV_SET_MAC_CONFIG_RESP_EVENTID; 20831 event_ids[wmi_coex_bt_activity_event_id] = 20832 WMI_WLAN_COEX_BT_ACTIVITY_EVENTID; 20833 event_ids[wmi_mgmt_tx_bundle_completion_event_id] = 20834 WMI_MGMT_TX_BUNDLE_COMPLETION_EVENTID; 20835 event_ids[wmi_radio_tx_power_level_stats_event_id] = 20836 WMI_RADIO_TX_POWER_LEVEL_STATS_EVENTID; 20837 event_ids[wmi_report_stats_event_id] = WMI_REPORT_STATS_EVENTID; 20838 event_ids[wmi_dma_buf_release_event_id] = 20839 WMI_PDEV_DMA_RING_BUF_RELEASE_EVENTID; 20840 event_ids[wmi_sap_obss_detection_report_event_id] = 20841 WMI_SAP_OBSS_DETECTION_REPORT_EVENTID; 20842 event_ids[wmi_host_swfda_event_id] = WMI_HOST_SWFDA_EVENTID; 20843 event_ids[wmi_sar_get_limits_event_id] = WMI_SAR_GET_LIMITS_EVENTID; 20844 event_ids[wmi_obss_color_collision_report_event_id] = 20845 WMI_OBSS_COLOR_COLLISION_DETECTION_EVENTID; 20846 event_ids[wmi_pdev_div_rssi_antid_event_id] = 20847 WMI_PDEV_DIV_RSSI_ANTID_EVENTID; 20848 #ifdef WLAN_SUPPORT_TWT 20849 event_ids[wmi_twt_enable_complete_event_id] = 20850 WMI_TWT_ENABLE_COMPLETE_EVENTID; 20851 event_ids[wmi_twt_disable_complete_event_id] = 20852 WMI_TWT_DISABLE_COMPLETE_EVENTID; 20853 event_ids[wmi_twt_add_dialog_complete_event_id] = 20854 WMI_TWT_ADD_DIALOG_COMPLETE_EVENTID; 20855 event_ids[wmi_twt_del_dialog_complete_event_id] = 20856 WMI_TWT_DEL_DIALOG_COMPLETE_EVENTID; 20857 event_ids[wmi_twt_pause_dialog_complete_event_id] = 20858 WMI_TWT_PAUSE_DIALOG_COMPLETE_EVENTID; 20859 event_ids[wmi_twt_resume_dialog_complete_event_id] = 20860 WMI_TWT_RESUME_DIALOG_COMPLETE_EVENTID; 20861 event_ids[wmi_twt_nudge_dialog_complete_event_id] = 20862 WMI_TWT_NUDGE_DIALOG_COMPLETE_EVENTID; 20863 event_ids[wmi_twt_session_stats_event_id] = 20864 WMI_TWT_SESSION_STATS_EVENTID; 20865 event_ids[wmi_twt_notify_event_id] = 20866 WMI_TWT_NOTIFY_EVENTID; 20867 event_ids[wmi_twt_ack_complete_event_id] = 20868 WMI_TWT_ACK_EVENTID; 20869 #endif 20870 event_ids[wmi_apf_get_vdev_work_memory_resp_event_id] = 20871 WMI_BPF_GET_VDEV_WORK_MEMORY_RESP_EVENTID; 20872 event_ids[wmi_wlan_sar2_result_event_id] = WMI_SAR2_RESULT_EVENTID; 20873 event_ids[wmi_esp_estimate_event_id] = WMI_ESP_ESTIMATE_EVENTID; 20874 event_ids[wmi_roam_scan_stats_event_id] = WMI_ROAM_SCAN_STATS_EVENTID; 20875 #ifdef WLAN_FEATURE_INTEROP_ISSUES_AP 20876 event_ids[wmi_pdev_interop_issues_ap_event_id] = 20877 WMI_PDEV_RAP_INFO_EVENTID; 20878 #endif 20879 #ifdef AST_HKV1_WORKAROUND 20880 event_ids[wmi_wds_peer_event_id] = WMI_WDS_PEER_EVENTID; 20881 #endif 20882 event_ids[wmi_pdev_ctl_failsafe_check_event_id] = 20883 WMI_PDEV_CTL_FAILSAFE_CHECK_EVENTID; 20884 event_ids[wmi_vdev_bcn_reception_stats_event_id] = 20885 WMI_VDEV_BCN_RECEPTION_STATS_EVENTID; 20886 event_ids[wmi_roam_denylist_event_id] = WMI_ROAM_BLACKLIST_EVENTID; 20887 event_ids[wmi_wlm_stats_event_id] = WMI_WLM_STATS_EVENTID; 20888 event_ids[wmi_peer_cfr_capture_event_id] = WMI_PEER_CFR_CAPTURE_EVENTID; 20889 event_ids[wmi_pdev_cold_boot_cal_event_id] = 20890 WMI_PDEV_COLD_BOOT_CAL_DATA_EVENTID; 20891 #ifdef WLAN_MWS_INFO_DEBUGFS 20892 event_ids[wmi_vdev_get_mws_coex_state_eventid] = 20893 WMI_VDEV_GET_MWS_COEX_STATE_EVENTID; 20894 event_ids[wmi_vdev_get_mws_coex_dpwb_state_eventid] = 20895 WMI_VDEV_GET_MWS_COEX_DPWB_STATE_EVENTID; 20896 event_ids[wmi_vdev_get_mws_coex_tdm_state_eventid] = 20897 WMI_VDEV_GET_MWS_COEX_TDM_STATE_EVENTID; 20898 event_ids[wmi_vdev_get_mws_coex_idrx_state_eventid] = 20899 WMI_VDEV_GET_MWS_COEX_IDRX_STATE_EVENTID; 20900 event_ids[wmi_vdev_get_mws_coex_antenna_sharing_state_eventid] = 20901 WMI_VDEV_GET_MWS_COEX_ANTENNA_SHARING_STATE_EVENTID; 20902 #endif 20903 event_ids[wmi_coex_report_antenna_isolation_event_id] = 20904 WMI_COEX_REPORT_ANTENNA_ISOLATION_EVENTID; 20905 event_ids[wmi_peer_ratecode_list_event_id] = 20906 WMI_PEER_RATECODE_LIST_EVENTID; 20907 event_ids[wmi_chan_rf_characterization_info_event_id] = 20908 WMI_CHAN_RF_CHARACTERIZATION_INFO_EVENTID; 20909 event_ids[wmi_roam_auth_offload_event_id] = 20910 WMI_ROAM_PREAUTH_START_EVENTID; 20911 event_ids[wmi_get_elna_bypass_event_id] = WMI_GET_ELNA_BYPASS_EVENTID; 20912 event_ids[wmi_motion_det_host_eventid] = WMI_MOTION_DET_HOST_EVENTID; 20913 event_ids[wmi_motion_det_base_line_host_eventid] = 20914 WMI_MOTION_DET_BASE_LINE_HOST_EVENTID; 20915 event_ids[wmi_get_ani_level_event_id] = WMI_GET_CHANNEL_ANI_EVENTID; 20916 event_ids[wmi_peer_tx_pn_response_event_id] = 20917 WMI_PEER_TX_PN_RESPONSE_EVENTID; 20918 event_ids[wmi_roam_stats_event_id] = WMI_ROAM_STATS_EVENTID; 20919 event_ids[wmi_oem_data_event_id] = WMI_OEM_DATA_EVENTID; 20920 event_ids[wmi_mgmt_offload_data_event_id] = 20921 WMI_VDEV_MGMT_OFFLOAD_EVENTID; 20922 event_ids[wmi_nan_dmesg_event_id] = 20923 WMI_NAN_DMESG_EVENTID; 20924 event_ids[wmi_pdev_multi_vdev_restart_response_event_id] = 20925 WMI_PDEV_MULTIPLE_VDEV_RESTART_RESP_EVENTID; 20926 event_ids[wmi_roam_pmkid_request_event_id] = 20927 WMI_ROAM_PMKID_REQUEST_EVENTID; 20928 #ifdef FEATURE_WLAN_TIME_SYNC_FTM 20929 event_ids[wmi_wlan_time_sync_ftm_start_stop_event_id] = 20930 WMI_VDEV_AUDIO_SYNC_START_STOP_EVENTID; 20931 event_ids[wmi_wlan_time_sync_q_initiator_target_offset_eventid] = 20932 WMI_VDEV_AUDIO_SYNC_Q_MASTER_SLAVE_OFFSET_EVENTID; 20933 #endif 20934 event_ids[wmi_roam_scan_chan_list_id] = 20935 WMI_ROAM_SCAN_CHANNEL_LIST_EVENTID; 20936 event_ids[wmi_muedca_params_config_eventid] = 20937 WMI_MUEDCA_PARAMS_CONFIG_EVENTID; 20938 event_ids[wmi_pdev_sscan_fw_param_eventid] = 20939 WMI_PDEV_SSCAN_FW_PARAM_EVENTID; 20940 event_ids[wmi_roam_cap_report_event_id] = 20941 WMI_ROAM_CAPABILITY_REPORT_EVENTID; 20942 event_ids[wmi_vdev_bcn_latency_event_id] = 20943 WMI_VDEV_BCN_LATENCY_EVENTID; 20944 event_ids[wmi_vdev_disconnect_event_id] = 20945 WMI_VDEV_DISCONNECT_EVENTID; 20946 event_ids[wmi_peer_create_conf_event_id] = 20947 WMI_PEER_CREATE_CONF_EVENTID; 20948 event_ids[wmi_pdev_cp_fwstats_eventid] = 20949 WMI_CTRL_PATH_STATS_EVENTID; 20950 event_ids[wmi_pdev_halphy_fwstats_eventid] = 20951 WMI_HALPHY_CTRL_PATH_STATS_EVENTID; 20952 event_ids[wmi_vdev_send_big_data_p2_eventid] = 20953 WMI_VDEV_SEND_BIG_DATA_P2_EVENTID; 20954 event_ids[wmi_pdev_get_dpd_status_event_id] = 20955 WMI_PDEV_GET_DPD_STATUS_EVENTID; 20956 #ifdef WLAN_FEATURE_PKT_CAPTURE_V2 20957 event_ids[wmi_vdev_smart_monitor_event_id] = 20958 WMI_VDEV_SMART_MONITOR_EVENTID; 20959 #endif 20960 event_ids[wmi_pdev_get_halphy_cal_status_event_id] = 20961 WMI_PDEV_GET_HALPHY_CAL_STATUS_EVENTID; 20962 event_ids[wmi_pdev_set_halphy_cal_event_id] = 20963 WMI_PDEV_SET_HALPHY_CAL_BMAP_EVENTID; 20964 event_ids[wmi_pdev_aoa_phasedelta_event_id] = 20965 WMI_PDEV_AOA_PHASEDELTA_EVENTID; 20966 #ifdef WLAN_MGMT_RX_REO_SUPPORT 20967 event_ids[wmi_mgmt_rx_fw_consumed_eventid] = 20968 WMI_MGMT_RX_FW_CONSUMED_EVENTID; 20969 #endif 20970 populate_tlv_events_id_mlo(event_ids); 20971 event_ids[wmi_roam_frame_event_id] = 20972 WMI_ROAM_FRAME_EVENTID; 20973 #ifdef WLAN_FEATURE_DYNAMIC_MAC_ADDR_UPDATE 20974 event_ids[wmi_vdev_update_mac_addr_conf_eventid] = 20975 WMI_VDEV_UPDATE_MAC_ADDR_CONF_EVENTID; 20976 #endif 20977 #ifdef WLAN_FEATURE_MCC_QUOTA 20978 event_ids[wmi_resmgr_chan_time_quota_changed_eventid] = 20979 WMI_RESMGR_CHAN_TIME_QUOTA_CHANGED_EVENTID; 20980 #endif 20981 event_ids[wmi_peer_rx_pn_response_event_id] = 20982 WMI_PEER_RX_PN_RESPONSE_EVENTID; 20983 event_ids[wmi_extract_pktlog_decode_info_eventid] = 20984 WMI_PDEV_PKTLOG_DECODE_INFO_EVENTID; 20985 #ifdef QCA_RSSI_DB2DBM 20986 event_ids[wmi_pdev_rssi_dbm_conversion_params_info_eventid] = 20987 WMI_PDEV_RSSI_DBM_CONVERSION_PARAMS_INFO_EVENTID; 20988 #endif 20989 #ifdef MULTI_CLIENT_LL_SUPPORT 20990 event_ids[wmi_vdev_latency_event_id] = WMI_VDEV_LATENCY_LEVEL_EVENTID; 20991 #endif 20992 #if defined(WIFI_POS_CONVERGED) && defined(WLAN_FEATURE_RTT_11AZ_SUPPORT) 20993 event_ids[wmi_rtt_pasn_peer_create_req_eventid] = 20994 WMI_RTT_PASN_PEER_CREATE_REQ_EVENTID; 20995 event_ids[wmi_rtt_pasn_peer_delete_eventid] = 20996 WMI_RTT_PASN_PEER_DELETE_EVENTID; 20997 #endif 20998 #ifdef WLAN_VENDOR_HANDOFF_CONTROL 20999 event_ids[wmi_get_roam_vendor_control_param_event_id] = 21000 WMI_ROAM_GET_VENDOR_CONTROL_PARAM_EVENTID; 21001 #endif 21002 #ifdef WLAN_FEATURE_DBAM_CONFIG 21003 event_ids[wmi_coex_dbam_complete_event_id] = 21004 WMI_COEX_DBAM_COMPLETE_EVENTID; 21005 #endif 21006 event_ids[wmi_spectral_capabilities_eventid] = 21007 WMI_SPECTRAL_CAPABILITIES_EVENTID; 21008 #ifdef WLAN_FEATURE_COAP 21009 event_ids[wmi_wow_coap_buf_info_eventid] = 21010 WMI_WOW_COAP_BUF_INFO_EVENTID; 21011 #endif 21012 #ifdef HEALTH_MON_SUPPORT 21013 event_ids[wmi_extract_health_mon_init_done_info_eventid] = 21014 WMI_HEALTH_MON_INIT_DONE_EVENTID; 21015 #endif /* HEALTH_MON_SUPPORT */ 21016 #ifdef WLAN_SUPPORT_GAP_LL_PS_MODE 21017 event_ids[wmi_xgap_enable_complete_eventid] = 21018 WMI_XGAP_ENABLE_COMPLETE_EVENTID; 21019 #endif 21020 } 21021 21022 #ifdef WLAN_FEATURE_LINK_LAYER_STATS 21023 #ifdef FEATURE_CLUB_LL_STATS_AND_GET_STATION 21024 static void wmi_populate_service_get_sta_in_ll_stats_req(uint32_t *wmi_service) 21025 { 21026 wmi_service[wmi_service_get_station_in_ll_stats_req] = 21027 WMI_SERVICE_UNIFIED_LL_GET_STA_CMD_SUPPORT; 21028 } 21029 #else 21030 static void wmi_populate_service_get_sta_in_ll_stats_req(uint32_t *wmi_service) 21031 { 21032 } 21033 #endif /* FEATURE_CLUB_LL_STATS_AND_GET_STATION */ 21034 #else 21035 static void wmi_populate_service_get_sta_in_ll_stats_req(uint32_t *wmi_service) 21036 { 21037 } 21038 #endif /* WLAN_FEATURE_LINK_LAYER_STATS */ 21039 21040 #ifdef WLAN_FEATURE_11BE_MLO 21041 static void populate_tlv_service_mlo(uint32_t *wmi_service) 21042 { 21043 wmi_service[wmi_service_mlo_sta_nan_ndi_support] = 21044 WMI_SERVICE_MLO_STA_NAN_NDI_SUPPORT; 21045 } 21046 #else /* WLAN_FEATURE_11BE_MLO */ 21047 static inline void populate_tlv_service_mlo(uint32_t *wmi_service) 21048 { 21049 } 21050 #endif /* WLAN_FEATURE_11BE_MLO */ 21051 21052 /** 21053 * populate_tlv_service() - populates wmi services 21054 * @wmi_service: Pointer to hold wmi_service 21055 * 21056 * Return: None 21057 */ 21058 static void populate_tlv_service(uint32_t *wmi_service) 21059 { 21060 wmi_service[wmi_service_beacon_offload] = WMI_SERVICE_BEACON_OFFLOAD; 21061 wmi_service[wmi_service_ack_timeout] = WMI_SERVICE_ACK_TIMEOUT; 21062 wmi_service[wmi_service_scan_offload] = WMI_SERVICE_SCAN_OFFLOAD; 21063 wmi_service[wmi_service_roam_scan_offload] = 21064 WMI_SERVICE_ROAM_SCAN_OFFLOAD; 21065 wmi_service[wmi_service_bcn_miss_offload] = 21066 WMI_SERVICE_BCN_MISS_OFFLOAD; 21067 wmi_service[wmi_service_sta_pwrsave] = WMI_SERVICE_STA_PWRSAVE; 21068 wmi_service[wmi_service_sta_advanced_pwrsave] = 21069 WMI_SERVICE_STA_ADVANCED_PWRSAVE; 21070 wmi_service[wmi_service_ap_uapsd] = WMI_SERVICE_AP_UAPSD; 21071 wmi_service[wmi_service_ap_dfs] = WMI_SERVICE_AP_DFS; 21072 wmi_service[wmi_service_11ac] = WMI_SERVICE_11AC; 21073 wmi_service[wmi_service_blockack] = WMI_SERVICE_BLOCKACK; 21074 wmi_service[wmi_service_phyerr] = WMI_SERVICE_PHYERR; 21075 wmi_service[wmi_service_bcn_filter] = WMI_SERVICE_BCN_FILTER; 21076 wmi_service[wmi_service_rtt] = WMI_SERVICE_RTT; 21077 wmi_service[wmi_service_wow] = WMI_SERVICE_WOW; 21078 wmi_service[wmi_service_ratectrl_cache] = WMI_SERVICE_RATECTRL_CACHE; 21079 wmi_service[wmi_service_iram_tids] = WMI_SERVICE_IRAM_TIDS; 21080 wmi_service[wmi_service_arpns_offload] = WMI_SERVICE_ARPNS_OFFLOAD; 21081 wmi_service[wmi_service_nlo] = WMI_SERVICE_NLO; 21082 wmi_service[wmi_service_gtk_offload] = WMI_SERVICE_GTK_OFFLOAD; 21083 wmi_service[wmi_service_scan_sch] = WMI_SERVICE_SCAN_SCH; 21084 wmi_service[wmi_service_csa_offload] = WMI_SERVICE_CSA_OFFLOAD; 21085 wmi_service[wmi_service_chatter] = WMI_SERVICE_CHATTER; 21086 wmi_service[wmi_service_coex_freqavoid] = WMI_SERVICE_COEX_FREQAVOID; 21087 wmi_service[wmi_service_packet_power_save] = 21088 WMI_SERVICE_PACKET_POWER_SAVE; 21089 wmi_service[wmi_service_force_fw_hang] = WMI_SERVICE_FORCE_FW_HANG; 21090 wmi_service[wmi_service_gpio] = WMI_SERVICE_GPIO; 21091 wmi_service[wmi_service_sta_dtim_ps_modulated_dtim] = 21092 WMI_SERVICE_STA_DTIM_PS_MODULATED_DTIM; 21093 wmi_service[wmi_sta_uapsd_basic_auto_trig] = 21094 WMI_STA_UAPSD_BASIC_AUTO_TRIG; 21095 wmi_service[wmi_sta_uapsd_var_auto_trig] = WMI_STA_UAPSD_VAR_AUTO_TRIG; 21096 wmi_service[wmi_service_sta_keep_alive] = WMI_SERVICE_STA_KEEP_ALIVE; 21097 wmi_service[wmi_service_tx_encap] = WMI_SERVICE_TX_ENCAP; 21098 wmi_service[wmi_service_ap_ps_detect_out_of_sync] = 21099 WMI_SERVICE_AP_PS_DETECT_OUT_OF_SYNC; 21100 wmi_service[wmi_service_early_rx] = WMI_SERVICE_EARLY_RX; 21101 wmi_service[wmi_service_sta_smps] = WMI_SERVICE_STA_SMPS; 21102 wmi_service[wmi_service_fwtest] = WMI_SERVICE_FWTEST; 21103 wmi_service[wmi_service_sta_wmmac] = WMI_SERVICE_STA_WMMAC; 21104 wmi_service[wmi_service_tdls] = WMI_SERVICE_TDLS; 21105 wmi_service[wmi_service_burst] = WMI_SERVICE_BURST; 21106 wmi_service[wmi_service_mcc_bcn_interval_change] = 21107 WMI_SERVICE_MCC_BCN_INTERVAL_CHANGE; 21108 wmi_service[wmi_service_adaptive_ocs] = WMI_SERVICE_ADAPTIVE_OCS; 21109 wmi_service[wmi_service_ba_ssn_support] = WMI_SERVICE_BA_SSN_SUPPORT; 21110 wmi_service[wmi_service_filter_ipsec_natkeepalive] = 21111 WMI_SERVICE_FILTER_IPSEC_NATKEEPALIVE; 21112 wmi_service[wmi_service_wlan_hb] = WMI_SERVICE_WLAN_HB; 21113 wmi_service[wmi_service_lte_ant_share_support] = 21114 WMI_SERVICE_LTE_ANT_SHARE_SUPPORT; 21115 wmi_service[wmi_service_batch_scan] = WMI_SERVICE_BATCH_SCAN; 21116 wmi_service[wmi_service_qpower] = WMI_SERVICE_QPOWER; 21117 wmi_service[wmi_service_plmreq] = WMI_SERVICE_PLMREQ; 21118 wmi_service[wmi_service_thermal_mgmt] = WMI_SERVICE_THERMAL_MGMT; 21119 wmi_service[wmi_service_rmc] = WMI_SERVICE_RMC; 21120 wmi_service[wmi_service_mhf_offload] = WMI_SERVICE_MHF_OFFLOAD; 21121 wmi_service[wmi_service_coex_sar] = WMI_SERVICE_COEX_SAR; 21122 wmi_service[wmi_service_bcn_txrate_override] = 21123 WMI_SERVICE_BCN_TXRATE_OVERRIDE; 21124 wmi_service[wmi_service_nan] = WMI_SERVICE_NAN; 21125 wmi_service[wmi_service_l1ss_stat] = WMI_SERVICE_L1SS_STAT; 21126 wmi_service[wmi_service_estimate_linkspeed] = 21127 WMI_SERVICE_ESTIMATE_LINKSPEED; 21128 wmi_service[wmi_service_obss_scan] = WMI_SERVICE_OBSS_SCAN; 21129 wmi_service[wmi_service_tdls_offchan] = WMI_SERVICE_TDLS_OFFCHAN; 21130 wmi_service[wmi_service_tdls_uapsd_buffer_sta] = 21131 WMI_SERVICE_TDLS_UAPSD_BUFFER_STA; 21132 wmi_service[wmi_service_tdls_uapsd_sleep_sta] = 21133 WMI_SERVICE_TDLS_UAPSD_SLEEP_STA; 21134 wmi_service[wmi_service_ibss_pwrsave] = WMI_SERVICE_IBSS_PWRSAVE; 21135 wmi_service[wmi_service_lpass] = WMI_SERVICE_LPASS; 21136 wmi_service[wmi_service_extscan] = WMI_SERVICE_EXTSCAN; 21137 wmi_service[wmi_service_d0wow] = WMI_SERVICE_D0WOW; 21138 wmi_service[wmi_service_hsoffload] = WMI_SERVICE_HSOFFLOAD; 21139 wmi_service[wmi_service_roam_ho_offload] = WMI_SERVICE_ROAM_HO_OFFLOAD; 21140 wmi_service[wmi_service_rx_full_reorder] = WMI_SERVICE_RX_FULL_REORDER; 21141 wmi_service[wmi_service_dhcp_offload] = WMI_SERVICE_DHCP_OFFLOAD; 21142 wmi_service[wmi_service_sta_rx_ipa_offload_support] = 21143 WMI_SERVICE_STA_RX_IPA_OFFLOAD_SUPPORT; 21144 wmi_service[wmi_service_mdns_offload] = WMI_SERVICE_MDNS_OFFLOAD; 21145 wmi_service[wmi_service_sap_auth_offload] = 21146 WMI_SERVICE_SAP_AUTH_OFFLOAD; 21147 wmi_service[wmi_service_dual_band_simultaneous_support] = 21148 WMI_SERVICE_DUAL_BAND_SIMULTANEOUS_SUPPORT; 21149 wmi_service[wmi_service_ocb] = WMI_SERVICE_OCB; 21150 wmi_service[wmi_service_ap_arpns_offload] = 21151 WMI_SERVICE_AP_ARPNS_OFFLOAD; 21152 wmi_service[wmi_service_per_band_chainmask_support] = 21153 WMI_SERVICE_PER_BAND_CHAINMASK_SUPPORT; 21154 wmi_service[wmi_service_packet_filter_offload] = 21155 WMI_SERVICE_PACKET_FILTER_OFFLOAD; 21156 wmi_service[wmi_service_mgmt_tx_htt] = WMI_SERVICE_MGMT_TX_HTT; 21157 wmi_service[wmi_service_mgmt_tx_wmi] = WMI_SERVICE_MGMT_TX_WMI; 21158 wmi_service[wmi_service_ext_msg] = WMI_SERVICE_EXT_MSG; 21159 wmi_service[wmi_service_ext2_msg] = WMI_SERVICE_EXT2_MSG; 21160 wmi_service[wmi_service_mawc] = WMI_SERVICE_MAWC; 21161 wmi_service[wmi_service_multiple_vdev_restart] = 21162 WMI_SERVICE_MULTIPLE_VDEV_RESTART; 21163 wmi_service[wmi_service_multiple_vdev_restart_bmap] = 21164 WMI_SERVICE_MULTIPLE_VDEV_RESTART_BITMAP_SUPPORT; 21165 wmi_service[wmi_service_smart_antenna_sw_support] = 21166 WMI_SERVICE_SMART_ANTENNA_SW_SUPPORT; 21167 wmi_service[wmi_service_smart_antenna_hw_support] = 21168 WMI_SERVICE_SMART_ANTENNA_HW_SUPPORT; 21169 21170 wmi_service[wmi_service_roam_offload] = WMI_SERVICE_UNAVAILABLE; 21171 wmi_service[wmi_service_ratectrl] = WMI_SERVICE_UNAVAILABLE; 21172 wmi_service[wmi_service_enhanced_proxy_sta] = WMI_SERVICE_UNAVAILABLE; 21173 wmi_service[wmi_service_tt] = WMI_SERVICE_THERM_THROT; 21174 wmi_service[wmi_service_atf] = WMI_SERVICE_ATF; 21175 wmi_service[wmi_service_peer_caching] = WMI_SERVICE_UNAVAILABLE; 21176 wmi_service[wmi_service_coex_gpio] = WMI_SERVICE_UNAVAILABLE; 21177 wmi_service[wmi_service_aux_spectral_intf] = WMI_SERVICE_UNAVAILABLE; 21178 wmi_service[wmi_service_aux_chan_load_intf] = WMI_SERVICE_UNAVAILABLE; 21179 wmi_service[wmi_service_bss_channel_info_64] = WMI_SERVICE_UNAVAILABLE; 21180 wmi_service[wmi_service_ext_res_cfg_support] = WMI_SERVICE_UNAVAILABLE; 21181 wmi_service[wmi_service_mesh] = WMI_SERVICE_UNAVAILABLE; 21182 wmi_service[wmi_service_restrt_chnl_support] = WMI_SERVICE_UNAVAILABLE; 21183 wmi_service[wmi_service_peer_stats] = WMI_SERVICE_UNAVAILABLE; 21184 wmi_service[wmi_service_mesh_11s] = WMI_SERVICE_UNAVAILABLE; 21185 wmi_service[wmi_service_periodic_chan_stat_support] = 21186 WMI_SERVICE_PERIODIC_CHAN_STAT_SUPPORT; 21187 wmi_service[wmi_service_tx_mode_push_only] = WMI_SERVICE_UNAVAILABLE; 21188 wmi_service[wmi_service_tx_mode_push_pull] = WMI_SERVICE_UNAVAILABLE; 21189 wmi_service[wmi_service_tx_mode_dynamic] = WMI_SERVICE_UNAVAILABLE; 21190 wmi_service[wmi_service_btcoex_duty_cycle] = WMI_SERVICE_UNAVAILABLE; 21191 wmi_service[wmi_service_4_wire_coex_support] = WMI_SERVICE_UNAVAILABLE; 21192 wmi_service[wmi_service_mesh] = WMI_SERVICE_ENTERPRISE_MESH; 21193 wmi_service[wmi_service_peer_assoc_conf] = WMI_SERVICE_PEER_ASSOC_CONF; 21194 wmi_service[wmi_service_egap] = WMI_SERVICE_EGAP; 21195 wmi_service[wmi_service_sta_pmf_offload] = WMI_SERVICE_STA_PMF_OFFLOAD; 21196 wmi_service[wmi_service_unified_wow_capability] = 21197 WMI_SERVICE_UNIFIED_WOW_CAPABILITY; 21198 wmi_service[wmi_service_enterprise_mesh] = WMI_SERVICE_ENTERPRISE_MESH; 21199 wmi_service[wmi_service_apf_offload] = WMI_SERVICE_BPF_OFFLOAD; 21200 wmi_service[wmi_service_sync_delete_cmds] = 21201 WMI_SERVICE_SYNC_DELETE_CMDS; 21202 wmi_service[wmi_service_ratectrl_limit_max_min_rates] = 21203 WMI_SERVICE_RATECTRL_LIMIT_MAX_MIN_RATES; 21204 wmi_service[wmi_service_nan_data] = WMI_SERVICE_NAN_DATA; 21205 wmi_service[wmi_service_nan_rtt] = WMI_SERVICE_NAN_RTT; 21206 wmi_service[wmi_service_11ax] = WMI_SERVICE_11AX; 21207 wmi_service[wmi_service_deprecated_replace] = 21208 WMI_SERVICE_DEPRECATED_REPLACE; 21209 wmi_service[wmi_service_tdls_conn_tracker_in_host_mode] = 21210 WMI_SERVICE_TDLS_CONN_TRACKER_IN_HOST_MODE; 21211 wmi_service[wmi_service_enhanced_mcast_filter] = 21212 WMI_SERVICE_ENHANCED_MCAST_FILTER; 21213 wmi_service[wmi_service_half_rate_quarter_rate_support] = 21214 WMI_SERVICE_HALF_RATE_QUARTER_RATE_SUPPORT; 21215 wmi_service[wmi_service_vdev_rx_filter] = WMI_SERVICE_VDEV_RX_FILTER; 21216 wmi_service[wmi_service_p2p_listen_offload_support] = 21217 WMI_SERVICE_P2P_LISTEN_OFFLOAD_SUPPORT; 21218 wmi_service[wmi_service_mark_first_wakeup_packet] = 21219 WMI_SERVICE_MARK_FIRST_WAKEUP_PACKET; 21220 wmi_service[wmi_service_multiple_mcast_filter_set] = 21221 WMI_SERVICE_MULTIPLE_MCAST_FILTER_SET; 21222 wmi_service[wmi_service_host_managed_rx_reorder] = 21223 WMI_SERVICE_HOST_MANAGED_RX_REORDER; 21224 wmi_service[wmi_service_flash_rdwr_support] = 21225 WMI_SERVICE_FLASH_RDWR_SUPPORT; 21226 wmi_service[wmi_service_wlan_stats_report] = 21227 WMI_SERVICE_WLAN_STATS_REPORT; 21228 wmi_service[wmi_service_tx_msdu_id_new_partition_support] = 21229 WMI_SERVICE_TX_MSDU_ID_NEW_PARTITION_SUPPORT; 21230 wmi_service[wmi_service_dfs_phyerr_offload] = 21231 WMI_SERVICE_DFS_PHYERR_OFFLOAD; 21232 wmi_service[wmi_service_rcpi_support] = WMI_SERVICE_RCPI_SUPPORT; 21233 wmi_service[wmi_service_fw_mem_dump_support] = 21234 WMI_SERVICE_FW_MEM_DUMP_SUPPORT; 21235 wmi_service[wmi_service_peer_stats_info] = WMI_SERVICE_PEER_STATS_INFO; 21236 wmi_service[wmi_service_regulatory_db] = WMI_SERVICE_REGULATORY_DB; 21237 wmi_service[wmi_service_11d_offload] = WMI_SERVICE_11D_OFFLOAD; 21238 wmi_service[wmi_service_hw_data_filtering] = 21239 WMI_SERVICE_HW_DATA_FILTERING; 21240 wmi_service[wmi_service_pkt_routing] = WMI_SERVICE_PKT_ROUTING; 21241 wmi_service[wmi_service_offchan_tx_wmi] = WMI_SERVICE_OFFCHAN_TX_WMI; 21242 wmi_service[wmi_service_chan_load_info] = WMI_SERVICE_CHAN_LOAD_INFO; 21243 wmi_service[wmi_service_extended_nss_support] = 21244 WMI_SERVICE_EXTENDED_NSS_SUPPORT; 21245 wmi_service[wmi_service_widebw_scan] = WMI_SERVICE_SCAN_PHYMODE_SUPPORT; 21246 wmi_service[wmi_service_bcn_offload_start_stop_support] = 21247 WMI_SERVICE_BCN_OFFLOAD_START_STOP_SUPPORT; 21248 wmi_service[wmi_service_offchan_data_tid_support] = 21249 WMI_SERVICE_OFFCHAN_DATA_TID_SUPPORT; 21250 wmi_service[wmi_service_support_dma] = 21251 WMI_SERVICE_SUPPORT_DIRECT_DMA; 21252 wmi_service[wmi_service_8ss_tx_bfee] = WMI_SERVICE_8SS_TX_BFEE; 21253 wmi_service[wmi_service_fils_support] = WMI_SERVICE_FILS_SUPPORT; 21254 wmi_service[wmi_service_mawc_support] = WMI_SERVICE_MAWC_SUPPORT; 21255 wmi_service[wmi_service_wow_wakeup_by_timer_pattern] = 21256 WMI_SERVICE_WOW_WAKEUP_BY_TIMER_PATTERN; 21257 wmi_service[wmi_service_11k_neighbour_report_support] = 21258 WMI_SERVICE_11K_NEIGHBOUR_REPORT_SUPPORT; 21259 wmi_service[wmi_service_ap_obss_detection_offload] = 21260 WMI_SERVICE_AP_OBSS_DETECTION_OFFLOAD; 21261 wmi_service[wmi_service_bss_color_offload] = 21262 WMI_SERVICE_BSS_COLOR_OFFLOAD; 21263 wmi_service[wmi_service_gmac_offload_support] = 21264 WMI_SERVICE_GMAC_OFFLOAD_SUPPORT; 21265 wmi_service[wmi_service_dual_beacon_on_single_mac_scc_support] = 21266 WMI_SERVICE_DUAL_BEACON_ON_SINGLE_MAC_SCC_SUPPORT; 21267 wmi_service[wmi_service_dual_beacon_on_single_mac_mcc_support] = 21268 WMI_SERVICE_DUAL_BEACON_ON_SINGLE_MAC_MCC_SUPPORT; 21269 wmi_service[wmi_service_twt_requestor] = WMI_SERVICE_STA_TWT; 21270 wmi_service[wmi_service_twt_responder] = WMI_SERVICE_AP_TWT; 21271 wmi_service[wmi_service_listen_interval_offload_support] = 21272 WMI_SERVICE_LISTEN_INTERVAL_OFFLOAD_SUPPORT; 21273 wmi_service[wmi_service_esp_support] = WMI_SERVICE_ESP_SUPPORT; 21274 wmi_service[wmi_service_obss_spatial_reuse] = 21275 WMI_SERVICE_OBSS_SPATIAL_REUSE; 21276 wmi_service[wmi_service_per_vdev_chain_support] = 21277 WMI_SERVICE_PER_VDEV_CHAINMASK_CONFIG_SUPPORT; 21278 wmi_service[wmi_service_new_htt_msg_format] = 21279 WMI_SERVICE_HTT_H2T_NO_HTC_HDR_LEN_IN_MSG_LEN; 21280 wmi_service[wmi_service_peer_unmap_cnf_support] = 21281 WMI_SERVICE_PEER_UNMAP_RESPONSE_SUPPORT; 21282 wmi_service[wmi_service_beacon_reception_stats] = 21283 WMI_SERVICE_BEACON_RECEPTION_STATS; 21284 wmi_service[wmi_service_vdev_latency_config] = 21285 WMI_SERVICE_VDEV_LATENCY_CONFIG; 21286 wmi_service[wmi_service_nan_dbs_support] = WMI_SERVICE_NAN_DBS_SUPPORT; 21287 wmi_service[wmi_service_ndi_dbs_support] = WMI_SERVICE_NDI_DBS_SUPPORT; 21288 wmi_service[wmi_service_nan_sap_support] = WMI_SERVICE_NAN_SAP_SUPPORT; 21289 wmi_service[wmi_service_ndi_sap_support] = WMI_SERVICE_NDI_SAP_SUPPORT; 21290 wmi_service[wmi_service_nan_disable_support] = 21291 WMI_SERVICE_NAN_DISABLE_SUPPORT; 21292 wmi_service[wmi_service_sta_plus_sta_support] = 21293 WMI_SERVICE_STA_PLUS_STA_SUPPORT; 21294 wmi_service[wmi_service_hw_db2dbm_support] = 21295 WMI_SERVICE_HW_DB2DBM_CONVERSION_SUPPORT; 21296 wmi_service[wmi_service_wlm_stats_support] = 21297 WMI_SERVICE_WLM_STATS_REQUEST; 21298 wmi_service[wmi_service_infra_mbssid] = WMI_SERVICE_INFRA_MBSSID; 21299 wmi_service[wmi_service_ema_ap_support] = WMI_SERVICE_EMA_AP_SUPPORT; 21300 wmi_service[wmi_service_ul_ru26_allowed] = WMI_SERVICE_UL_RU26_ALLOWED; 21301 wmi_service[wmi_service_cfr_capture_support] = 21302 WMI_SERVICE_CFR_CAPTURE_SUPPORT; 21303 wmi_service[wmi_service_bcast_twt_support] = 21304 WMI_SERVICE_BROADCAST_TWT; 21305 wmi_service[wmi_service_wpa3_ft_sae_support] = 21306 WMI_SERVICE_WPA3_FT_SAE_SUPPORT; 21307 wmi_service[wmi_service_wpa3_ft_suite_b_support] = 21308 WMI_SERVICE_WPA3_FT_SUITE_B_SUPPORT; 21309 wmi_service[wmi_service_ft_fils] = 21310 WMI_SERVICE_WPA3_FT_FILS; 21311 wmi_service[wmi_service_adaptive_11r_support] = 21312 WMI_SERVICE_ADAPTIVE_11R_ROAM; 21313 wmi_service[wmi_service_tx_compl_tsf64] = 21314 WMI_SERVICE_TX_COMPL_TSF64; 21315 wmi_service[wmi_service_data_stall_recovery_support] = 21316 WMI_SERVICE_DSM_ROAM_FILTER; 21317 wmi_service[wmi_service_vdev_delete_all_peer] = 21318 WMI_SERVICE_DELETE_ALL_PEER_SUPPORT; 21319 wmi_service[wmi_service_three_way_coex_config_legacy] = 21320 WMI_SERVICE_THREE_WAY_COEX_CONFIG_LEGACY; 21321 wmi_service[wmi_service_rx_fse_support] = 21322 WMI_SERVICE_RX_FSE_SUPPORT; 21323 wmi_service[wmi_service_sae_roam_support] = 21324 WMI_SERVICE_WPA3_SAE_ROAM_SUPPORT; 21325 wmi_service[wmi_service_owe_roam_support] = 21326 WMI_SERVICE_WPA3_OWE_ROAM_SUPPORT; 21327 wmi_service[wmi_service_6ghz_support] = 21328 WMI_SERVICE_6GHZ_SUPPORT; 21329 wmi_service[wmi_service_bw_165mhz_support] = 21330 WMI_SERVICE_BW_165MHZ_SUPPORT; 21331 wmi_service[wmi_service_bw_restricted_80p80_support] = 21332 WMI_SERVICE_BW_RESTRICTED_80P80_SUPPORT; 21333 wmi_service[wmi_service_packet_capture_support] = 21334 WMI_SERVICE_PACKET_CAPTURE_SUPPORT; 21335 wmi_service[wmi_service_nan_vdev] = WMI_SERVICE_NAN_VDEV_SUPPORT; 21336 wmi_service[wmi_service_peer_delete_no_peer_flush_tids_cmd] = 21337 WMI_SERVICE_PEER_DELETE_NO_PEER_FLUSH_TIDS_CMD; 21338 wmi_service[wmi_service_multiple_vdev_restart_ext] = 21339 WMI_SERVICE_UNAVAILABLE; 21340 wmi_service[wmi_service_time_sync_ftm] = 21341 WMI_SERVICE_AUDIO_SYNC_SUPPORT; 21342 wmi_service[wmi_service_nss_ratio_to_host_support] = 21343 WMI_SERVICE_NSS_RATIO_TO_HOST_SUPPORT; 21344 wmi_service[wmi_roam_scan_chan_list_to_host_support] = 21345 WMI_SERVICE_ROAM_SCAN_CHANNEL_LIST_TO_HOST_SUPPORT; 21346 wmi_service[wmi_beacon_protection_support] = 21347 WMI_SERVICE_BEACON_PROTECTION_SUPPORT; 21348 wmi_service[wmi_service_sta_nan_ndi_four_port] = 21349 WMI_SERVICE_NDI_NDI_STA_SUPPORT; 21350 wmi_service[wmi_service_host_scan_stop_vdev_all] = 21351 WMI_SERVICE_HOST_SCAN_STOP_VDEV_ALL_SUPPORT; 21352 wmi_service[wmi_support_extend_address] = 21353 WMI_SERVICE_SUPPORT_EXTEND_ADDRESS; 21354 wmi_service[wmi_service_srg_srp_spatial_reuse_support] = 21355 WMI_SERVICE_SRG_SRP_SPATIAL_REUSE_SUPPORT; 21356 wmi_service[wmi_service_suiteb_roam_support] = 21357 WMI_SERVICE_WPA3_SUITEB_ROAM_SUPPORT; 21358 wmi_service[wmi_service_no_interband_mcc_support] = 21359 WMI_SERVICE_NO_INTERBAND_MCC_SUPPORT; 21360 wmi_service[wmi_service_dual_sta_roam_support] = 21361 WMI_SERVICE_DUAL_STA_ROAM_SUPPORT; 21362 wmi_service[wmi_service_peer_create_conf] = 21363 WMI_SERVICE_PEER_CREATE_CONF; 21364 wmi_service[wmi_service_configure_roam_trigger_param_support] = 21365 WMI_SERVICE_CONFIGURE_ROAM_TRIGGER_PARAM_SUPPORT; 21366 wmi_service[wmi_service_5dot9_ghz_support] = 21367 WMI_SERVICE_5_DOT_9GHZ_SUPPORT; 21368 wmi_service[wmi_service_cfr_ta_ra_as_fp_support] = 21369 WMI_SERVICE_CFR_TA_RA_AS_FP_SUPPORT; 21370 wmi_service[wmi_service_cfr_capture_count_support] = 21371 WMI_SERVICE_CFR_CAPTURE_COUNT_SUPPORT; 21372 wmi_service[wmi_service_ocv_support] = 21373 WMI_SERVICE_OCV_SUPPORT; 21374 wmi_service[wmi_service_ll_stats_per_chan_rx_tx_time] = 21375 WMI_SERVICE_LL_STATS_PER_CHAN_RX_TX_TIME_SUPPORT; 21376 wmi_service[wmi_service_thermal_multi_client_support] = 21377 WMI_SERVICE_THERMAL_MULTI_CLIENT_SUPPORT; 21378 wmi_service[wmi_service_mbss_param_in_vdev_start_support] = 21379 WMI_SERVICE_MBSS_PARAM_IN_VDEV_START_SUPPORT; 21380 wmi_service[wmi_service_fse_cmem_alloc_support] = 21381 WMI_SERVICE_FSE_CMEM_ALLOC_SUPPORT; 21382 wmi_service[wmi_service_scan_conf_per_ch_support] = 21383 WMI_SERVICE_SCAN_CONFIG_PER_CHANNEL; 21384 wmi_service[wmi_service_csa_beacon_template] = 21385 WMI_SERVICE_CSA_BEACON_TEMPLATE; 21386 #if defined(WIFI_POS_CONVERGED) && defined(WLAN_FEATURE_RTT_11AZ_SUPPORT) 21387 wmi_service[wmi_service_rtt_11az_ntb_support] = 21388 WMI_SERVICE_RTT_11AZ_NTB_SUPPORT; 21389 wmi_service[wmi_service_rtt_11az_tb_support] = 21390 WMI_SERVICE_RTT_11AZ_TB_SUPPORT; 21391 wmi_service[wmi_service_rtt_11az_mac_sec_support] = 21392 WMI_SERVICE_RTT_11AZ_MAC_SEC_SUPPORT; 21393 wmi_service[wmi_service_rtt_11az_mac_phy_sec_support] = 21394 WMI_SERVICE_RTT_11AZ_MAC_PHY_SEC_SUPPORT; 21395 #endif 21396 #ifdef WLAN_FEATURE_IGMP_OFFLOAD 21397 wmi_service[wmi_service_igmp_offload_support] = 21398 WMI_SERVICE_IGMP_OFFLOAD_SUPPORT; 21399 #endif 21400 21401 #ifdef FEATURE_WLAN_TDLS 21402 #ifdef WLAN_FEATURE_11AX 21403 wmi_service[wmi_service_tdls_ax_support] = 21404 WMI_SERVICE_11AX_TDLS_SUPPORT; 21405 wmi_service[wmi_service_tdls_6g_support] = 21406 WMI_SERVICE_TDLS_6GHZ_SUPPORT; 21407 #endif 21408 wmi_service[wmi_service_tdls_wideband_support] = 21409 WMI_SERVICE_TDLS_WIDEBAND_SUPPORT; 21410 #endif 21411 21412 #ifdef WLAN_SUPPORT_TWT 21413 wmi_service[wmi_service_twt_bcast_req_support] = 21414 WMI_SERVICE_BROADCAST_TWT_REQUESTER; 21415 wmi_service[wmi_service_twt_bcast_resp_support] = 21416 WMI_SERVICE_BROADCAST_TWT_RESPONDER; 21417 wmi_service[wmi_service_twt_nudge] = 21418 WMI_SERVICE_TWT_NUDGE; 21419 wmi_service[wmi_service_all_twt] = 21420 WMI_SERVICE_TWT_ALL_DIALOG_ID; 21421 wmi_service[wmi_service_twt_statistics] = 21422 WMI_SERVICE_TWT_STATS; 21423 #endif 21424 wmi_service[wmi_service_spectral_scan_disabled] = 21425 WMI_SERVICE_SPECTRAL_SCAN_DISABLED; 21426 wmi_service[wmi_service_sae_eapol_offload_support] = 21427 WMI_SERVICE_SAE_EAPOL_OFFLOAD_SUPPORT; 21428 wmi_populate_service_get_sta_in_ll_stats_req(wmi_service); 21429 21430 wmi_service[wmi_service_wapi_concurrency_supported] = 21431 WMI_SERVICE_WAPI_CONCURRENCY_SUPPORTED; 21432 wmi_service[wmi_service_sap_connected_d3_wow] = 21433 WMI_SERVICE_SAP_CONNECTED_D3WOW; 21434 wmi_service[wmi_service_go_connected_d3_wow] = 21435 WMI_SERVICE_SAP_CONNECTED_D3WOW; 21436 wmi_service[wmi_service_ext_tpc_reg_support] = 21437 WMI_SERVICE_EXT_TPC_REG_SUPPORT; 21438 wmi_service[wmi_service_eirp_preferred_support] = 21439 WMI_SERVICE_EIRP_PREFERRED_SUPPORT; 21440 wmi_service[wmi_service_ndi_txbf_support] = 21441 WMI_SERVICE_NDI_TXBF_SUPPORT; 21442 wmi_service[wmi_service_reg_cc_ext_event_support] = 21443 WMI_SERVICE_REG_CC_EXT_EVENT_SUPPORT; 21444 wmi_service[wmi_service_bang_radar_320_support] = 21445 WMI_SERVICE_BANG_RADAR_320_SUPPORT; 21446 #if defined(CONFIG_BAND_6GHZ) 21447 wmi_service[wmi_service_lower_6g_edge_ch_supp] = 21448 WMI_SERVICE_ENABLE_LOWER_6G_EDGE_CH_SUPP; 21449 wmi_service[wmi_service_disable_upper_6g_edge_ch_supp] = 21450 WMI_SERVICE_DISABLE_UPPER_6G_EDGE_CH_SUPP; 21451 #ifdef CONFIG_AFC_SUPPORT 21452 wmi_service[wmi_service_afc_support] = 21453 WMI_SERVICE_AFC_SUPPORT; 21454 #endif 21455 #endif 21456 wmi_service[wmi_service_dcs_awgn_int_support] = 21457 WMI_SERVICE_DCS_AWGN_INT_SUPPORT; 21458 wmi_populate_service_11be(wmi_service); 21459 21460 #ifdef WLAN_FEATURE_BIG_DATA_STATS 21461 wmi_service[wmi_service_big_data_support] = 21462 WMI_SERVICE_BIG_DATA_SUPPORT; 21463 #endif 21464 wmi_service[wmi_service_ampdu_tx_buf_size_256_support] = 21465 WMI_SERVICE_AMPDU_TX_BUF_SIZE_256_SUPPORT; 21466 wmi_service[wmi_service_halphy_cal_enable_disable_support] = 21467 WMI_SERVICE_HALPHY_CAL_ENABLE_DISABLE_SUPPORT; 21468 wmi_service[wmi_service_halphy_cal_status] = 21469 WMI_SERVICE_HALPHY_CAL_STATUS; 21470 wmi_service[wmi_service_rtt_ap_initiator_staggered_mode_supported] = 21471 WMI_SERVICE_RTT_AP_INITIATOR_STAGGERED_MODE_SUPPORTED; 21472 wmi_service[wmi_service_rtt_ap_initiator_bursted_mode_supported] = 21473 WMI_SERVICE_RTT_AP_INITIATOR_BURSTED_MODE_SUPPORTED; 21474 wmi_service[wmi_service_ema_multiple_group_supported] = 21475 WMI_SERVICE_EMA_MULTIPLE_GROUP_SUPPORT; 21476 wmi_service[wmi_service_large_beacon_supported] = 21477 WMI_SERVICE_LARGE_BEACON_SUPPORT; 21478 wmi_service[wmi_service_aoa_for_rcc_supported] = 21479 WMI_SERVICE_AOA_FOR_RCC_SUPPORTED; 21480 #ifdef WLAN_FEATURE_P2P_P2P_STA 21481 wmi_service[wmi_service_p2p_p2p_cc_support] = 21482 WMI_SERVICE_P2P_P2P_CONCURRENCY_SUPPORT; 21483 #endif 21484 #ifdef THERMAL_STATS_SUPPORT 21485 wmi_service[wmi_service_thermal_stats_temp_range_supported] = 21486 WMI_SERVICE_THERMAL_THROT_STATS_TEMP_RANGE_SUPPORT; 21487 #endif 21488 wmi_service[wmi_service_hw_mode_policy_offload_support] = 21489 WMI_SERVICE_HW_MODE_POLICY_OFFLOAD_SUPPORT; 21490 wmi_service[wmi_service_mgmt_rx_reo_supported] = 21491 WMI_SERVICE_MGMT_RX_REO_SUPPORTED; 21492 wmi_service[wmi_service_phy_dma_byte_swap_support] = 21493 WMI_SERVICE_UNAVAILABLE; 21494 wmi_service[wmi_service_spectral_session_info_support] = 21495 WMI_SERVICE_SPECTRAL_SESSION_INFO_SUPPORT; 21496 wmi_service[wmi_service_umac_hang_recovery_support] = 21497 WMI_SERVICE_UMAC_HANG_RECOVERY_SUPPORT; 21498 wmi_service[wmi_service_mu_snif] = WMI_SERVICE_MU_SNIF; 21499 #ifdef WLAN_FEATURE_DYNAMIC_MAC_ADDR_UPDATE 21500 wmi_service[wmi_service_dynamic_update_vdev_macaddr_support] = 21501 WMI_SERVICE_DYNAMIC_VDEV_MAC_ADDR_UPDATE_SUPPORT; 21502 #endif 21503 wmi_service[wmi_service_probe_all_bw_support] = 21504 WMI_SERVICE_PROBE_ALL_BW_SUPPORT; 21505 wmi_service[wmi_service_pno_scan_conf_per_ch_support] = 21506 WMI_SERVICE_PNO_SCAN_CONFIG_PER_CHANNEL; 21507 #ifdef QCA_UNDECODED_METADATA_SUPPORT 21508 wmi_service[wmi_service_fp_phy_err_filter_support] = 21509 WMI_SERVICE_FP_PHY_ERR_FILTER_SUPPORT; 21510 #endif 21511 populate_tlv_service_mlo(wmi_service); 21512 wmi_service[wmi_service_pdev_rate_config_support] = 21513 WMI_SERVICE_PDEV_RATE_CONFIG_SUPPORT; 21514 wmi_service[wmi_service_multi_peer_group_cmd_support] = 21515 WMI_SERVICE_MULTIPLE_PEER_GROUP_CMD_SUPPORT; 21516 #ifdef WLAN_FEATURE_11BE 21517 wmi_service[wmi_service_radar_found_chan_freq_eq_center_freq] = 21518 WMI_IS_RADAR_FOUND_CHAN_FREQ_IS_CENTER_FREQ; 21519 #endif 21520 #ifdef WLAN_PDEV_VDEV_SEND_MULTI_PARAM 21521 wmi_service[wmi_service_combined_set_param_support] = 21522 WMI_SERVICE_COMBINED_SET_PARAM_SUPPORT; 21523 #endif 21524 wmi_service[wmi_service_pn_replay_check_support] = 21525 WMI_SERVICE_PN_REPLAY_CHECK_SUPPORT; 21526 #ifdef QCA_RSSI_DB2DBM 21527 wmi_service[wmi_service_pdev_rssi_dbm_conv_event_support] = 21528 WMI_SERVICE_PDEV_RSSI_DBM_CONV_EVENT_SUPPORT; 21529 #endif 21530 wmi_service[wmi_service_pktlog_decode_info_support] = 21531 WMI_SERVICE_PKTLOG_DECODE_INFO_SUPPORT; 21532 #ifdef WLAN_FEATURE_ROAM_OFFLOAD 21533 wmi_service[wmi_service_roam_stats_per_candidate_frame_info] = 21534 WMI_SERVICE_ROAM_STAT_PER_CANDIDATE_FRAME_INFO_SUPPORT; 21535 #endif 21536 #ifdef MULTI_CLIENT_LL_SUPPORT 21537 wmi_service[wmi_service_configure_multi_client_ll_support] = 21538 WMI_SERVICE_MULTI_CLIENT_LL_SUPPORT; 21539 #endif 21540 #ifdef WLAN_VENDOR_HANDOFF_CONTROL 21541 wmi_service[wmi_service_configure_vendor_handoff_control_support] = 21542 WMI_SERVICE_FW_INI_PARSE_SUPPORT; 21543 #endif 21544 wmi_service[wmi_service_linkspeed_roam_trigger_support] = 21545 WMI_SERVICE_LINKSPEED_ROAM_TRIGGER_SUPPORT; 21546 #ifdef FEATURE_SET 21547 wmi_service[wmi_service_feature_set_event_support] = 21548 WMI_SERVICE_FEATURE_SET_EVENT_SUPPORT; 21549 #endif 21550 #ifdef WLAN_FEATURE_SR 21551 wmi_service[wmi_service_obss_per_packet_sr_support] = 21552 WMI_SERVICE_OBSS_PER_PACKET_SR_SUPPORT; 21553 #endif 21554 wmi_service[wmi_service_wpa3_sha384_roam_support] = 21555 WMI_SERVICE_WMI_SERVICE_WPA3_SHA384_ROAM_SUPPORT; 21556 } 21557 21558 /** 21559 * wmi_ocb_ut_attach() - Attach OCB test framework 21560 * @wmi_handle: wmi handle 21561 * 21562 * Return: None 21563 */ 21564 #ifdef WLAN_OCB_UT 21565 void wmi_ocb_ut_attach(struct wmi_unified *wmi_handle); 21566 #else 21567 static inline void wmi_ocb_ut_attach(struct wmi_unified *wmi_handle) 21568 { 21569 return; 21570 } 21571 #endif 21572 21573 /** 21574 * wmi_tlv_attach() - Attach TLV APIs 21575 * @wmi_handle: wmi handle 21576 * Return: None 21577 */ 21578 void wmi_tlv_attach(wmi_unified_t wmi_handle) 21579 { 21580 wmi_handle->ops = &tlv_ops; 21581 wmi_ocb_ut_attach(wmi_handle); 21582 wmi_handle->soc->svc_ids = &multi_svc_ids[0]; 21583 #ifdef WMI_INTERFACE_EVENT_LOGGING 21584 /* Skip saving WMI_CMD_HDR and TLV HDR */ 21585 wmi_handle->soc->buf_offset_command = 8; 21586 /* WMI_CMD_HDR is already stripped, skip saving TLV HDR */ 21587 wmi_handle->soc->buf_offset_event = 4; 21588 #endif 21589 populate_tlv_events_id(wmi_handle->wmi_events); 21590 populate_tlv_service(wmi_handle->services); 21591 wmi_wds_attach_tlv(wmi_handle); 21592 wmi_twt_attach_tlv(wmi_handle); 21593 wmi_extscan_attach_tlv(wmi_handle); 21594 wmi_smart_ant_attach_tlv(wmi_handle); 21595 wmi_dbr_attach_tlv(wmi_handle); 21596 wmi_atf_attach_tlv(wmi_handle); 21597 wmi_ap_attach_tlv(wmi_handle); 21598 wmi_bcn_attach_tlv(wmi_handle); 21599 wmi_ocb_attach_tlv(wmi_handle); 21600 wmi_nan_attach_tlv(wmi_handle); 21601 wmi_p2p_attach_tlv(wmi_handle); 21602 wmi_interop_issues_ap_attach_tlv(wmi_handle); 21603 wmi_dcs_attach_tlv(wmi_handle); 21604 wmi_roam_attach_tlv(wmi_handle); 21605 wmi_concurrency_attach_tlv(wmi_handle); 21606 wmi_pmo_attach_tlv(wmi_handle); 21607 wmi_sta_attach_tlv(wmi_handle); 21608 wmi_11ax_bss_color_attach_tlv(wmi_handle); 21609 wmi_fwol_attach_tlv(wmi_handle); 21610 wmi_vdev_attach_tlv(wmi_handle); 21611 wmi_cfr_attach_tlv(wmi_handle); 21612 wmi_cp_stats_attach_tlv(wmi_handle); 21613 wmi_gpio_attach_tlv(wmi_handle); 21614 wmi_11be_attach_tlv(wmi_handle); 21615 wmi_coap_attach_tlv(wmi_handle); 21616 } 21617 qdf_export_symbol(wmi_tlv_attach); 21618 21619 /** 21620 * wmi_tlv_init() - Initialize WMI TLV module by registering TLV attach routine 21621 * 21622 * Return: None 21623 */ 21624 void wmi_tlv_init(void) 21625 { 21626 wmi_unified_register_module(WMI_TLV_TARGET, &wmi_tlv_attach); 21627 } 21628