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 default: 9322 return WMI_VENDOR1_REQ1_VERSION_3_00; 9323 } 9324 } 9325 9326 /** 9327 * convert_host_to_target_wifi_standard() -Convert host wifi standard to 9328 * target wifi standard 9329 * @wifi_standard: Host wifi standard 9330 * 9331 * Return: Target wifi standard 9332 */ 9333 static WMI_WIFI_STANDARD convert_host_to_target_wifi_standard( 9334 WMI_HOST_WIFI_STANDARD wifi_standard) 9335 { 9336 switch (wifi_standard) { 9337 case WMI_HOST_WIFI_STANDARD_4: 9338 return WMI_WIFI_STANDARD_4; 9339 case WMI_HOST_WIFI_STANDARD_5: 9340 return WMI_WIFI_STANDARD_5; 9341 case WMI_HOST_WIFI_STANDARD_6: 9342 return WMI_WIFI_STANDARD_6; 9343 case WMI_HOST_WIFI_STANDARD_6E: 9344 return WMI_WIFI_STANDARD_6E; 9345 case WMI_HOST_WIFI_STANDARD_7: 9346 return WMI_WIFI_STANDARD_7; 9347 default: 9348 return WMI_WIFI_STANDARD_4; 9349 } 9350 } 9351 9352 /** 9353 * convert_host_to_target_band_concurrency() -Convert host band concurrency to 9354 * target band concurrency 9355 * @band_concurrency: Host Band concurrency 9356 * 9357 * Return: Target band concurrency 9358 */ 9359 static WMI_BAND_CONCURRENCY convert_host_to_target_band_concurrency( 9360 WMI_HOST_BAND_CONCURRENCY band_concurrency) 9361 { 9362 switch (band_concurrency) { 9363 case WMI_HOST_BAND_CONCURRENCY_DBS: 9364 return WMI_HOST_DBS; 9365 case WMI_HOST_BAND_CONCURRENCY_DBS_SBS: 9366 return WMI_HOST_DBS_SBS; 9367 default: 9368 return WMI_HOST_NONE; 9369 } 9370 } 9371 9372 /** 9373 * convert_host_to_target_num_antennas() -Convert host num antennas to 9374 * target num antennas 9375 * @num_antennas: Host num antennas 9376 * 9377 * Return: Target num antennas 9378 */ 9379 static WMI_NUM_ANTENNAS convert_host_to_target_num_antennas( 9380 WMI_HOST_NUM_ANTENNAS num_antennas) 9381 { 9382 switch (num_antennas) { 9383 case WMI_HOST_SISO: 9384 return WMI_SISO; 9385 case WMI_HOST_MIMO_2X2: 9386 return WMI_MIMO_2X2; 9387 default: 9388 return WMI_SISO; 9389 } 9390 } 9391 9392 /** 9393 * convert_host_to_target_band_capability() -Convert host band capability to 9394 * target band capability 9395 * @host_band_capability: Host band capability 9396 * 9397 * Return: Target band capability bitmap 9398 */ 9399 static uint8_t 9400 convert_host_to_target_band_capability(uint32_t host_band_capability) 9401 { 9402 uint8_t band_capability; 9403 9404 band_capability = (host_band_capability & WMI_HOST_BAND_CAP_2GHZ) | 9405 (host_band_capability & WMI_HOST_BAND_CAP_5GHZ) | 9406 (host_band_capability & WMI_HOST_BAND_CAP_6GHZ); 9407 return band_capability; 9408 } 9409 9410 /** 9411 * copy_feature_set_info() -Copy feature set info from host to target 9412 * @feature_set_bitmap: Target feature set pointer 9413 * @feature_set: Host feature set structure 9414 * 9415 * Return: None 9416 */ 9417 static inline void copy_feature_set_info(uint32_t *feature_set_bitmap, 9418 struct target_feature_set *feature_set) 9419 { 9420 WMI_NUM_ANTENNAS num_antennas; 9421 WMI_BAND_CONCURRENCY band_concurrency; 9422 WMI_WIFI_STANDARD wifi_standard; 9423 WMI_VENDOR1_REQ1_VERSION vendor1_req1_version; 9424 WMI_VENDOR1_REQ2_VERSION vendor1_req2_version; 9425 uint8_t band_capability; 9426 9427 num_antennas = convert_host_to_target_num_antennas( 9428 feature_set->num_antennas); 9429 band_concurrency = convert_host_to_target_band_concurrency( 9430 feature_set->concurrency_support); 9431 wifi_standard = convert_host_to_target_wifi_standard( 9432 feature_set->wifi_standard); 9433 vendor1_req1_version = convert_host_to_target_vendor1_req1_version( 9434 feature_set->vendor_req_1_version); 9435 vendor1_req2_version = convert_host_to_target_vendor1_req2_version( 9436 feature_set->vendor_req_2_version); 9437 9438 band_capability = 9439 convert_host_to_target_band_capability( 9440 feature_set->band_capability); 9441 9442 WMI_SET_WIFI_STANDARD(feature_set_bitmap, wifi_standard); 9443 WMI_SET_BAND_CONCURRENCY_SUPPORT(feature_set_bitmap, band_concurrency); 9444 WMI_SET_PNO_SCAN_IN_UNASSOC_STATE(feature_set_bitmap, 9445 feature_set->pno_in_unassoc_state); 9446 WMI_SET_PNO_SCAN_IN_ASSOC_STATE(feature_set_bitmap, 9447 feature_set->pno_in_assoc_state); 9448 WMI_SET_TWT_FEATURE_SUPPORT(feature_set_bitmap, 9449 feature_set->enable_twt); 9450 WMI_SET_TWT_REQUESTER(feature_set_bitmap, 9451 feature_set->enable_twt_requester); 9452 WMI_SET_TWT_BROADCAST(feature_set_bitmap, 9453 feature_set->enable_twt_broadcast); 9454 WMI_SET_TWT_FLEXIBLE(feature_set_bitmap, 9455 feature_set->enable_twt_flexible); 9456 WMI_SET_WIFI_OPT_FEATURE_SUPPORT(feature_set_bitmap, 9457 feature_set->enable_wifi_optimizer); 9458 WMI_SET_RFC8325_FEATURE_SUPPORT(feature_set_bitmap, 9459 feature_set->enable_rfc835); 9460 WMI_SET_MHS_5G_SUPPORT(feature_set_bitmap, 9461 feature_set->sap_5g_supported); 9462 WMI_SET_MHS_6G_SUPPORT(feature_set_bitmap, 9463 feature_set->sap_6g_supported); 9464 WMI_SET_MHS_MAX_CLIENTS_SUPPORT(feature_set_bitmap, 9465 feature_set->sap_max_num_clients); 9466 WMI_SET_MHS_SET_COUNTRY_CODE_HAL_SUPPORT( 9467 feature_set_bitmap, 9468 feature_set->set_country_code_hal_supported); 9469 WMI_SET_MHS_GETVALID_CHANNELS_SUPPORT( 9470 feature_set_bitmap, 9471 feature_set->get_valid_channel_supported); 9472 WMI_SET_MHS_DOT11_MODE_SUPPORT(feature_set_bitmap, 9473 feature_set->supported_dot11mode); 9474 WMI_SET_MHS_WPA3_SUPPORT(feature_set_bitmap, 9475 feature_set->sap_wpa3_support); 9476 WMI_SET_VENDOR_REQ_1_VERSION(feature_set_bitmap, vendor1_req1_version); 9477 WMI_SET_ROAMING_HIGH_CU_ROAM_TRIGGER( 9478 feature_set_bitmap, 9479 feature_set->roaming_high_cu_roam_trigger); 9480 WMI_SET_ROAMING_EMERGENCY_TRIGGER( 9481 feature_set_bitmap, 9482 feature_set->roaming_emergency_trigger); 9483 WMI_SET_ROAMING_BTM_TRIGGER(feature_set_bitmap, 9484 feature_set->roaming_btm_trihgger); 9485 WMI_SET_ROAMING_IDLE_TRIGGER(feature_set_bitmap, 9486 feature_set->roaming_idle_trigger); 9487 WMI_SET_ROAMING_WTC_TRIGGER(feature_set_bitmap, 9488 feature_set->roaming_wtc_trigger); 9489 WMI_SET_ROAMING_BTCOEX_TRIGGER(feature_set_bitmap, 9490 feature_set->roaming_btcoex_trigger); 9491 WMI_SET_ROAMING_BTW_WPA_WPA2(feature_set_bitmap, 9492 feature_set->roaming_btw_wpa_wpa2); 9493 WMI_SET_ROAMING_MANAGE_CHAN_LIST_API( 9494 feature_set_bitmap, 9495 feature_set->roaming_manage_chan_list_api); 9496 WMI_SET_ROAMING_ADAPTIVE_11R(feature_set_bitmap, 9497 feature_set->roaming_adaptive_11r); 9498 WMI_SET_ROAMING_CTRL_API_GET_SET(feature_set_bitmap, 9499 feature_set->roaming_ctrl_api_get_set); 9500 WMI_SET_ROAMING_CTRL_API_REASSOC(feature_set_bitmap, 9501 feature_set->roaming_ctrl_api_reassoc); 9502 WMI_SET_ROAMING_CTRL_GET_CU(feature_set_bitmap, 9503 feature_set->roaming_ctrl_get_cu); 9504 WMI_SET_VENDOR_REQ_2_VERSION(feature_set_bitmap, vendor1_req2_version); 9505 WMI_SET_ASSURANCE_DISCONNECT_REASON_API( 9506 feature_set_bitmap, 9507 feature_set->assurance_disconnect_reason_api); 9508 WMI_SET_FRAME_PCAP_LOG_MGMT(feature_set_bitmap, 9509 feature_set->frame_pcap_log_mgmt); 9510 WMI_SET_FRAME_PCAP_LOG_CTRL(feature_set_bitmap, 9511 feature_set->frame_pcap_log_ctrl); 9512 WMI_SET_FRAME_PCAP_LOG_DATA(feature_set_bitmap, 9513 feature_set->frame_pcap_log_data); 9514 WMI_SET_SECURITY_WPA3_SAE_H2E(feature_set_bitmap, 9515 feature_set->security_wpa3_sae_h2e); 9516 WMI_SET_SECURITY_WPA3_SAE_FT(feature_set_bitmap, 9517 feature_set->security_wpa3_sae_ft); 9518 WMI_SET_SECURITY_WPA3_ENTERP_SUITEB( 9519 feature_set_bitmap, 9520 feature_set->security_wpa3_enterp_suitb); 9521 WMI_SET_SECURITY_WPA3_ENTERP_SUITEB_192bit( 9522 feature_set_bitmap, 9523 feature_set->security_wpa3_enterp_suitb_192bit); 9524 WMI_SET_SECURITY_FILS_SHA256(feature_set_bitmap, 9525 feature_set->security_fills_sha_256); 9526 WMI_SET_SECURITY_FILS_SHA384(feature_set_bitmap, 9527 feature_set->security_fills_sha_384); 9528 WMI_SET_SECURITY_FILS_SHA256_FT(feature_set_bitmap, 9529 feature_set->security_fills_sha_256_FT); 9530 WMI_SET_SECURITY_FILS_SHA384_FT(feature_set_bitmap, 9531 feature_set->security_fills_sha_384_FT); 9532 WMI_SET_SECURITY_ENCHANCED_OPEN(feature_set_bitmap, 9533 feature_set->security_enhanced_open); 9534 WMI_SET_NAN_SUPPORT(feature_set_bitmap, feature_set->enable_nan); 9535 WMI_SET_TDLS_SUPPORT(feature_set_bitmap, feature_set->enable_tdls); 9536 WMI_SET_P2P6E_SUPPORT(feature_set_bitmap, feature_set->enable_p2p_6e); 9537 WMI_SET_TDLS_OFFCHAN_SUPPORT(feature_set_bitmap, 9538 feature_set->enable_tdls_offchannel); 9539 WMI_SET_TDLS_CAP_ENHANCE(feature_set_bitmap, 9540 feature_set->enable_tdls_capability_enhance); 9541 WMI_SET_MAX_TDLS_PEERS_SUPPORT(feature_set_bitmap, 9542 feature_set->max_tdls_peers); 9543 WMI_SET_STA_DUAL_P2P_SUPPORT(feature_set_bitmap, 9544 feature_set->sta_dual_p2p_support); 9545 WMI_SET_PEER_BIGDATA_GETBSSINFO_API_SUPPORT( 9546 feature_set_bitmap, 9547 feature_set->peer_bigdata_getbssinfo_support); 9548 WMI_SET_PEER_BIGDATA_GETASSOCREJECTINFO_API_SUPPORT( 9549 feature_set_bitmap, 9550 feature_set->peer_bigdata_assocreject_info_support); 9551 WMI_SET_PEER_BIGDATA_GETSTAINFO_API_SUPPORT( 9552 feature_set_bitmap, 9553 feature_set->peer_getstainfo_support); 9554 WMI_SET_FEATURE_SET_VERSION(feature_set_bitmap, 9555 feature_set->feature_set_version); 9556 WMI_SET_NUM_ANTENNAS(feature_set_bitmap, num_antennas); 9557 WMI_SET_HOST_BAND_CAP(feature_set_bitmap, band_capability); 9558 } 9559 9560 /** 9561 * feature_set_cmd_send_tlv() -Send feature set command 9562 * @wmi_handle: WMI handle 9563 * @feature_set: Feature set structure 9564 * 9565 * Return: QDF_STATUS_SUCCESS on success else return failure 9566 */ 9567 static QDF_STATUS feature_set_cmd_send_tlv( 9568 struct wmi_unified *wmi_handle, 9569 struct target_feature_set *feature_set) 9570 { 9571 wmi_pdev_featureset_cmd_fixed_param *cmd; 9572 wmi_buf_t buf; 9573 uint16_t len; 9574 QDF_STATUS ret; 9575 uint8_t *buf_ptr; 9576 uint32_t *feature_set_bitmap; 9577 9578 len = sizeof(*cmd) + WMI_TLV_HDR_SIZE + 9579 WMI_FEATURE_SET_BITMAP_ARRAY_LEN32 * sizeof(uint32_t); 9580 buf = wmi_buf_alloc(wmi_handle, len); 9581 9582 if (!buf) 9583 return QDF_STATUS_E_NOMEM; 9584 9585 wmi_debug("Send feature set param"); 9586 9587 buf_ptr = (uint8_t *)wmi_buf_data(buf); 9588 9589 cmd = (wmi_pdev_featureset_cmd_fixed_param *)wmi_buf_data(buf); 9590 9591 WMITLV_SET_HDR(&cmd->tlv_header, 9592 WMITLV_TAG_STRUC_wmi_pdev_featureset_cmd_fixed_param, 9593 WMITLV_GET_STRUCT_TLVLEN( 9594 wmi_pdev_featureset_cmd_fixed_param)); 9595 9596 feature_set_bitmap = (uint32_t *)(buf_ptr + sizeof(*cmd) + 9597 WMI_TLV_HDR_SIZE); 9598 WMITLV_SET_HDR(buf_ptr + sizeof(*cmd), WMITLV_TAG_ARRAY_UINT32, 9599 (WMI_FEATURE_SET_BITMAP_ARRAY_LEN32 * sizeof(uint32_t))); 9600 copy_feature_set_info(feature_set_bitmap, feature_set); 9601 9602 qdf_trace_hex_dump(QDF_MODULE_ID_WMI, QDF_TRACE_LEVEL_DEBUG, 9603 feature_set_bitmap, 9604 WMI_FEATURE_SET_BITMAP_ARRAY_LEN32 * 9605 sizeof(uint32_t)); 9606 9607 wmi_mtrace(WMI_PDEV_FEATURESET_CMDID, NO_SESSION, 0); 9608 9609 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 9610 WMI_PDEV_FEATURESET_CMDID); 9611 if (QDF_IS_STATUS_ERROR(ret)) 9612 wmi_buf_free(buf); 9613 9614 return ret; 9615 } 9616 #endif 9617 9618 /* copy_hw_mode_id_in_init_cmd() - Helper routine to copy hw_mode in init cmd 9619 * @wmi_handle: pointer to wmi handle 9620 * @buf_ptr: pointer to current position in init command buffer 9621 * @len: pointer to length. This will be updated with current length of cmd 9622 * @param: point host parameters for init command 9623 * 9624 * Return: Updated pointer of buf_ptr. 9625 */ 9626 static inline uint8_t *copy_hw_mode_in_init_cmd(struct wmi_unified *wmi_handle, 9627 uint8_t *buf_ptr, int *len, struct wmi_init_cmd_param *param) 9628 { 9629 uint16_t idx; 9630 9631 if (param->hw_mode_id != WMI_HOST_HW_MODE_MAX) { 9632 wmi_pdev_set_hw_mode_cmd_fixed_param *hw_mode; 9633 wmi_pdev_band_to_mac *band_to_mac; 9634 9635 hw_mode = (wmi_pdev_set_hw_mode_cmd_fixed_param *) 9636 (buf_ptr + sizeof(wmi_init_cmd_fixed_param) + 9637 sizeof(wmi_resource_config) + 9638 WMI_TLV_HDR_SIZE + (param->num_mem_chunks * 9639 sizeof(wlan_host_memory_chunk))); 9640 9641 WMITLV_SET_HDR(&hw_mode->tlv_header, 9642 WMITLV_TAG_STRUC_wmi_pdev_set_hw_mode_cmd_fixed_param, 9643 (WMITLV_GET_STRUCT_TLVLEN 9644 (wmi_pdev_set_hw_mode_cmd_fixed_param))); 9645 9646 hw_mode->hw_mode_index = param->hw_mode_id; 9647 hw_mode->num_band_to_mac = param->num_band_to_mac; 9648 9649 buf_ptr = (uint8_t *) (hw_mode + 1); 9650 band_to_mac = (wmi_pdev_band_to_mac *) (buf_ptr + 9651 WMI_TLV_HDR_SIZE); 9652 for (idx = 0; idx < param->num_band_to_mac; idx++) { 9653 WMITLV_SET_HDR(&band_to_mac[idx].tlv_header, 9654 WMITLV_TAG_STRUC_wmi_pdev_band_to_mac, 9655 WMITLV_GET_STRUCT_TLVLEN 9656 (wmi_pdev_band_to_mac)); 9657 band_to_mac[idx].pdev_id = 9658 wmi_handle->ops->convert_pdev_id_host_to_target( 9659 wmi_handle, 9660 param->band_to_mac[idx].pdev_id); 9661 band_to_mac[idx].start_freq = 9662 param->band_to_mac[idx].start_freq; 9663 band_to_mac[idx].end_freq = 9664 param->band_to_mac[idx].end_freq; 9665 } 9666 *len += sizeof(wmi_pdev_set_hw_mode_cmd_fixed_param) + 9667 (param->num_band_to_mac * 9668 sizeof(wmi_pdev_band_to_mac)) + 9669 WMI_TLV_HDR_SIZE; 9670 9671 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 9672 (param->num_band_to_mac * 9673 sizeof(wmi_pdev_band_to_mac))); 9674 } 9675 9676 return buf_ptr; 9677 } 9678 9679 static inline void copy_fw_abi_version_tlv(wmi_unified_t wmi_handle, 9680 wmi_init_cmd_fixed_param *cmd) 9681 { 9682 int num_allowlist; 9683 wmi_abi_version my_vers; 9684 9685 num_allowlist = sizeof(version_whitelist) / 9686 sizeof(wmi_whitelist_version_info); 9687 my_vers.abi_version_0 = WMI_ABI_VERSION_0; 9688 my_vers.abi_version_1 = WMI_ABI_VERSION_1; 9689 my_vers.abi_version_ns_0 = WMI_ABI_VERSION_NS_0; 9690 my_vers.abi_version_ns_1 = WMI_ABI_VERSION_NS_1; 9691 my_vers.abi_version_ns_2 = WMI_ABI_VERSION_NS_2; 9692 my_vers.abi_version_ns_3 = WMI_ABI_VERSION_NS_3; 9693 9694 wmi_cmp_and_set_abi_version(num_allowlist, version_whitelist, 9695 &my_vers, 9696 (struct _wmi_abi_version *)&wmi_handle->fw_abi_version, 9697 &cmd->host_abi_vers); 9698 9699 wmi_debug("INIT_CMD version: %d, %d, 0x%x, 0x%x, 0x%x, 0x%x", 9700 WMI_VER_GET_MAJOR(cmd->host_abi_vers.abi_version_0), 9701 WMI_VER_GET_MINOR(cmd->host_abi_vers.abi_version_0), 9702 cmd->host_abi_vers.abi_version_ns_0, 9703 cmd->host_abi_vers.abi_version_ns_1, 9704 cmd->host_abi_vers.abi_version_ns_2, 9705 cmd->host_abi_vers.abi_version_ns_3); 9706 9707 /* Save version sent from host - 9708 * Will be used to check ready event 9709 */ 9710 qdf_mem_copy(&wmi_handle->final_abi_vers, &cmd->host_abi_vers, 9711 sizeof(wmi_abi_version)); 9712 } 9713 9714 /* 9715 * send_cfg_action_frm_tb_ppdu_cmd_tlv() - send action frame tb ppdu cfg to FW 9716 * @wmi_handle: Pointer to WMi handle 9717 * @ie_data: Pointer for ie data 9718 * 9719 * This function sends action frame tb ppdu cfg to FW 9720 * 9721 * Return: QDF_STATUS_SUCCESS for success otherwise failure 9722 * 9723 */ 9724 static QDF_STATUS send_cfg_action_frm_tb_ppdu_cmd_tlv(wmi_unified_t wmi_handle, 9725 struct cfg_action_frm_tb_ppdu_param *cfg_msg) 9726 { 9727 wmi_pdev_he_tb_action_frm_cmd_fixed_param *cmd; 9728 wmi_buf_t buf; 9729 uint8_t *buf_ptr; 9730 uint32_t len, frm_len_aligned; 9731 QDF_STATUS ret; 9732 9733 frm_len_aligned = roundup(cfg_msg->frm_len, sizeof(uint32_t)); 9734 /* Allocate memory for the WMI command */ 9735 len = sizeof(*cmd) + WMI_TLV_HDR_SIZE + frm_len_aligned; 9736 9737 buf = wmi_buf_alloc(wmi_handle, len); 9738 if (!buf) 9739 return QDF_STATUS_E_NOMEM; 9740 9741 buf_ptr = wmi_buf_data(buf); 9742 qdf_mem_zero(buf_ptr, len); 9743 9744 /* Populate the WMI command */ 9745 cmd = (wmi_pdev_he_tb_action_frm_cmd_fixed_param *)buf_ptr; 9746 9747 WMITLV_SET_HDR(&cmd->tlv_header, 9748 WMITLV_TAG_STRUC_wmi_pdev_he_tb_action_frm_cmd_fixed_param, 9749 WMITLV_GET_STRUCT_TLVLEN( 9750 wmi_pdev_he_tb_action_frm_cmd_fixed_param)); 9751 cmd->enable = cfg_msg->cfg; 9752 cmd->data_len = cfg_msg->frm_len; 9753 9754 buf_ptr += sizeof(*cmd); 9755 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, frm_len_aligned); 9756 buf_ptr += WMI_TLV_HDR_SIZE; 9757 9758 qdf_mem_copy(buf_ptr, cfg_msg->data, cmd->data_len); 9759 9760 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 9761 WMI_PDEV_HE_TB_ACTION_FRM_CMDID); 9762 if (QDF_IS_STATUS_ERROR(ret)) { 9763 wmi_err("HE TB action frame cmnd send fail, ret %d", ret); 9764 wmi_buf_free(buf); 9765 } 9766 9767 return ret; 9768 } 9769 9770 static QDF_STATUS save_fw_version_cmd_tlv(wmi_unified_t wmi_handle, void *evt_buf) 9771 { 9772 WMI_SERVICE_READY_EVENTID_param_tlvs *param_buf; 9773 wmi_service_ready_event_fixed_param *ev; 9774 9775 9776 param_buf = (WMI_SERVICE_READY_EVENTID_param_tlvs *) evt_buf; 9777 9778 ev = (wmi_service_ready_event_fixed_param *) param_buf->fixed_param; 9779 if (!ev) 9780 return QDF_STATUS_E_FAILURE; 9781 9782 /*Save fw version from service ready message */ 9783 /*This will be used while sending INIT message */ 9784 qdf_mem_copy(&wmi_handle->fw_abi_version, &ev->fw_abi_vers, 9785 sizeof(wmi_handle->fw_abi_version)); 9786 9787 return QDF_STATUS_SUCCESS; 9788 } 9789 9790 /** 9791 * check_and_update_fw_version_cmd_tlv() - save fw version 9792 * @wmi_handle: pointer to wmi handle 9793 * @evt_buf: pointer to the event buffer 9794 * 9795 * This function extracts and saves the firmware WMI ABI version 9796 * 9797 * Return: QDF_STATUS_SUCCESS for success otherwise failure 9798 * 9799 */ 9800 static QDF_STATUS check_and_update_fw_version_cmd_tlv(wmi_unified_t wmi_handle, 9801 void *evt_buf) 9802 { 9803 WMI_READY_EVENTID_param_tlvs *param_buf = NULL; 9804 wmi_ready_event_fixed_param *ev = NULL; 9805 9806 param_buf = (WMI_READY_EVENTID_param_tlvs *) evt_buf; 9807 ev = param_buf->fixed_param; 9808 if (!wmi_versions_are_compatible((struct _wmi_abi_version *) 9809 &wmi_handle->final_abi_vers, 9810 &ev->fw_abi_vers)) { 9811 /* 9812 * Error: Our host version and the given firmware version 9813 * are incompatible. 9814 **/ 9815 wmi_debug("Error: Incompatible WMI version." 9816 "Host: %d,%d,0x%x 0x%x 0x%x 0x%x, FW: %d,%d,0x%x 0x%x 0x%x 0x%x", 9817 WMI_VER_GET_MAJOR(wmi_handle->final_abi_vers. 9818 abi_version_0), 9819 WMI_VER_GET_MINOR(wmi_handle->final_abi_vers. 9820 abi_version_0), 9821 wmi_handle->final_abi_vers.abi_version_ns_0, 9822 wmi_handle->final_abi_vers.abi_version_ns_1, 9823 wmi_handle->final_abi_vers.abi_version_ns_2, 9824 wmi_handle->final_abi_vers.abi_version_ns_3, 9825 WMI_VER_GET_MAJOR(ev->fw_abi_vers.abi_version_0), 9826 WMI_VER_GET_MINOR(ev->fw_abi_vers.abi_version_0), 9827 ev->fw_abi_vers.abi_version_ns_0, 9828 ev->fw_abi_vers.abi_version_ns_1, 9829 ev->fw_abi_vers.abi_version_ns_2, 9830 ev->fw_abi_vers.abi_version_ns_3); 9831 9832 return QDF_STATUS_E_FAILURE; 9833 } 9834 qdf_mem_copy(&wmi_handle->final_abi_vers, &ev->fw_abi_vers, 9835 sizeof(wmi_abi_version)); 9836 qdf_mem_copy(&wmi_handle->fw_abi_version, &ev->fw_abi_vers, 9837 sizeof(wmi_abi_version)); 9838 9839 return QDF_STATUS_SUCCESS; 9840 } 9841 9842 /** 9843 * send_log_supported_evt_cmd_tlv() - Enable/Disable FW diag/log events 9844 * @wmi_handle: wmi handle 9845 * @event: Event received from FW 9846 * @len: Length of the event 9847 * 9848 * Enables the low frequency events and disables the high frequency 9849 * events. Bit 17 indicates if the event if low/high frequency. 9850 * 1 - high frequency, 0 - low frequency 9851 * 9852 * Return: QDF_STATUS_SUCCESS for success or error code 9853 */ 9854 static QDF_STATUS send_log_supported_evt_cmd_tlv(wmi_unified_t wmi_handle, 9855 uint8_t *event, 9856 uint32_t len) 9857 { 9858 uint32_t num_of_diag_events_logs; 9859 wmi_diag_event_log_config_fixed_param *cmd; 9860 wmi_buf_t buf; 9861 uint8_t *buf_ptr; 9862 uint32_t *cmd_args, *evt_args; 9863 uint32_t buf_len, i; 9864 9865 WMI_DIAG_EVENT_LOG_SUPPORTED_EVENTID_param_tlvs *param_buf; 9866 wmi_diag_event_log_supported_event_fixed_params *wmi_event; 9867 9868 wmi_debug("Received WMI_DIAG_EVENT_LOG_SUPPORTED_EVENTID"); 9869 9870 param_buf = (WMI_DIAG_EVENT_LOG_SUPPORTED_EVENTID_param_tlvs *) event; 9871 if (!param_buf) { 9872 wmi_err("Invalid log supported event buffer"); 9873 return QDF_STATUS_E_INVAL; 9874 } 9875 wmi_event = param_buf->fixed_param; 9876 num_of_diag_events_logs = wmi_event->num_of_diag_events_logs; 9877 9878 if (num_of_diag_events_logs > 9879 param_buf->num_diag_events_logs_list) { 9880 wmi_err("message number of events %d is more than tlv hdr content %d", 9881 num_of_diag_events_logs, 9882 param_buf->num_diag_events_logs_list); 9883 return QDF_STATUS_E_INVAL; 9884 } 9885 9886 evt_args = param_buf->diag_events_logs_list; 9887 if (!evt_args) { 9888 wmi_err("Event list is empty, num_of_diag_events_logs=%d", 9889 num_of_diag_events_logs); 9890 return QDF_STATUS_E_INVAL; 9891 } 9892 9893 wmi_debug("num_of_diag_events_logs=%d", num_of_diag_events_logs); 9894 9895 /* Free any previous allocation */ 9896 if (wmi_handle->events_logs_list) { 9897 qdf_mem_free(wmi_handle->events_logs_list); 9898 wmi_handle->events_logs_list = NULL; 9899 } 9900 9901 if (num_of_diag_events_logs > 9902 (WMI_SVC_MSG_MAX_SIZE / sizeof(uint32_t))) { 9903 wmi_err("excess num of logs: %d", num_of_diag_events_logs); 9904 QDF_ASSERT(0); 9905 return QDF_STATUS_E_INVAL; 9906 } 9907 /* Store the event list for run time enable/disable */ 9908 wmi_handle->events_logs_list = qdf_mem_malloc(num_of_diag_events_logs * 9909 sizeof(uint32_t)); 9910 if (!wmi_handle->events_logs_list) 9911 return QDF_STATUS_E_NOMEM; 9912 9913 wmi_handle->num_of_diag_events_logs = num_of_diag_events_logs; 9914 9915 /* Prepare the send buffer */ 9916 buf_len = sizeof(*cmd) + WMI_TLV_HDR_SIZE + 9917 (num_of_diag_events_logs * sizeof(uint32_t)); 9918 9919 buf = wmi_buf_alloc(wmi_handle, buf_len); 9920 if (!buf) { 9921 qdf_mem_free(wmi_handle->events_logs_list); 9922 wmi_handle->events_logs_list = NULL; 9923 return QDF_STATUS_E_NOMEM; 9924 } 9925 9926 cmd = (wmi_diag_event_log_config_fixed_param *) wmi_buf_data(buf); 9927 buf_ptr = (uint8_t *) cmd; 9928 9929 WMITLV_SET_HDR(&cmd->tlv_header, 9930 WMITLV_TAG_STRUC_wmi_diag_event_log_config_fixed_param, 9931 WMITLV_GET_STRUCT_TLVLEN( 9932 wmi_diag_event_log_config_fixed_param)); 9933 9934 cmd->num_of_diag_events_logs = num_of_diag_events_logs; 9935 9936 buf_ptr += sizeof(wmi_diag_event_log_config_fixed_param); 9937 9938 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, 9939 (num_of_diag_events_logs * sizeof(uint32_t))); 9940 9941 cmd_args = (uint32_t *) (buf_ptr + WMI_TLV_HDR_SIZE); 9942 9943 /* Populate the events */ 9944 for (i = 0; i < num_of_diag_events_logs; i++) { 9945 /* Low freq (0) - Enable (1) the event 9946 * High freq (1) - Disable (0) the event 9947 */ 9948 WMI_DIAG_ID_ENABLED_DISABLED_SET(cmd_args[i], 9949 !(WMI_DIAG_FREQUENCY_GET(evt_args[i]))); 9950 /* Set the event ID */ 9951 WMI_DIAG_ID_SET(cmd_args[i], 9952 WMI_DIAG_ID_GET(evt_args[i])); 9953 /* Set the type */ 9954 WMI_DIAG_TYPE_SET(cmd_args[i], 9955 WMI_DIAG_TYPE_GET(evt_args[i])); 9956 /* Storing the event/log list in WMI */ 9957 wmi_handle->events_logs_list[i] = evt_args[i]; 9958 } 9959 9960 wmi_mtrace(WMI_DIAG_EVENT_LOG_CONFIG_CMDID, NO_SESSION, 0); 9961 if (wmi_unified_cmd_send(wmi_handle, buf, buf_len, 9962 WMI_DIAG_EVENT_LOG_CONFIG_CMDID)) { 9963 wmi_err("WMI_DIAG_EVENT_LOG_CONFIG_CMDID failed"); 9964 wmi_buf_free(buf); 9965 /* Not clearing events_logs_list, though wmi cmd failed. 9966 * Host can still have this list 9967 */ 9968 return QDF_STATUS_E_INVAL; 9969 } 9970 9971 return 0; 9972 } 9973 9974 /** 9975 * send_enable_specific_fw_logs_cmd_tlv() - Start/Stop logging of diag log id 9976 * @wmi_handle: wmi handle 9977 * @start_log: Start logging related parameters 9978 * 9979 * Send the command to the FW based on which specific logging of diag 9980 * event/log id can be started/stopped 9981 * 9982 * Return: None 9983 */ 9984 static QDF_STATUS send_enable_specific_fw_logs_cmd_tlv(wmi_unified_t wmi_handle, 9985 struct wmi_wifi_start_log *start_log) 9986 { 9987 wmi_diag_event_log_config_fixed_param *cmd; 9988 wmi_buf_t buf; 9989 uint8_t *buf_ptr; 9990 uint32_t len, count, log_level, i; 9991 uint32_t *cmd_args; 9992 uint32_t total_len; 9993 count = 0; 9994 9995 if (!wmi_handle->events_logs_list) { 9996 wmi_debug("Not received event/log list from FW, yet"); 9997 return QDF_STATUS_E_NOMEM; 9998 } 9999 /* total_len stores the number of events where BITS 17 and 18 are set. 10000 * i.e., events of high frequency (17) and for extended debugging (18) 10001 */ 10002 total_len = 0; 10003 for (i = 0; i < wmi_handle->num_of_diag_events_logs; i++) { 10004 if ((WMI_DIAG_FREQUENCY_GET(wmi_handle->events_logs_list[i])) && 10005 (WMI_DIAG_EXT_FEATURE_GET(wmi_handle->events_logs_list[i]))) 10006 total_len++; 10007 } 10008 10009 len = sizeof(*cmd) + WMI_TLV_HDR_SIZE + 10010 (total_len * sizeof(uint32_t)); 10011 10012 buf = wmi_buf_alloc(wmi_handle, len); 10013 if (!buf) 10014 return QDF_STATUS_E_NOMEM; 10015 10016 cmd = (wmi_diag_event_log_config_fixed_param *) wmi_buf_data(buf); 10017 buf_ptr = (uint8_t *) cmd; 10018 10019 WMITLV_SET_HDR(&cmd->tlv_header, 10020 WMITLV_TAG_STRUC_wmi_diag_event_log_config_fixed_param, 10021 WMITLV_GET_STRUCT_TLVLEN( 10022 wmi_diag_event_log_config_fixed_param)); 10023 10024 cmd->num_of_diag_events_logs = total_len; 10025 10026 buf_ptr += sizeof(wmi_diag_event_log_config_fixed_param); 10027 10028 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, 10029 (total_len * sizeof(uint32_t))); 10030 10031 cmd_args = (uint32_t *) (buf_ptr + WMI_TLV_HDR_SIZE); 10032 10033 if (start_log->verbose_level >= WMI_LOG_LEVEL_ACTIVE) 10034 log_level = 1; 10035 else 10036 log_level = 0; 10037 10038 wmi_debug("Length: %d Log_level: %d", total_len, log_level); 10039 for (i = 0; i < wmi_handle->num_of_diag_events_logs; i++) { 10040 uint32_t val = wmi_handle->events_logs_list[i]; 10041 if ((WMI_DIAG_FREQUENCY_GET(val)) && 10042 (WMI_DIAG_EXT_FEATURE_GET(val))) { 10043 10044 WMI_DIAG_ID_SET(cmd_args[count], 10045 WMI_DIAG_ID_GET(val)); 10046 WMI_DIAG_TYPE_SET(cmd_args[count], 10047 WMI_DIAG_TYPE_GET(val)); 10048 WMI_DIAG_ID_ENABLED_DISABLED_SET(cmd_args[count], 10049 log_level); 10050 wmi_debug("Idx:%d, val:%x", i, val); 10051 count++; 10052 } 10053 } 10054 10055 wmi_mtrace(WMI_DIAG_EVENT_LOG_CONFIG_CMDID, NO_SESSION, 0); 10056 if (wmi_unified_cmd_send(wmi_handle, buf, len, 10057 WMI_DIAG_EVENT_LOG_CONFIG_CMDID)) { 10058 wmi_err("WMI_DIAG_EVENT_LOG_CONFIG_CMDID failed"); 10059 wmi_buf_free(buf); 10060 return QDF_STATUS_E_INVAL; 10061 } 10062 10063 return QDF_STATUS_SUCCESS; 10064 } 10065 10066 /** 10067 * send_flush_logs_to_fw_cmd_tlv() - Send log flush command to FW 10068 * @wmi_handle: WMI handle 10069 * 10070 * This function is used to send the flush command to the FW, 10071 * that will flush the fw logs that are residue in the FW 10072 * 10073 * Return: None 10074 */ 10075 static QDF_STATUS send_flush_logs_to_fw_cmd_tlv(wmi_unified_t wmi_handle) 10076 { 10077 wmi_debug_mesg_flush_fixed_param *cmd; 10078 wmi_buf_t buf; 10079 int len = sizeof(*cmd); 10080 QDF_STATUS ret; 10081 10082 buf = wmi_buf_alloc(wmi_handle, len); 10083 if (!buf) 10084 return QDF_STATUS_E_NOMEM; 10085 10086 cmd = (wmi_debug_mesg_flush_fixed_param *) wmi_buf_data(buf); 10087 WMITLV_SET_HDR(&cmd->tlv_header, 10088 WMITLV_TAG_STRUC_wmi_debug_mesg_flush_fixed_param, 10089 WMITLV_GET_STRUCT_TLVLEN( 10090 wmi_debug_mesg_flush_fixed_param)); 10091 cmd->reserved0 = 0; 10092 10093 wmi_mtrace(WMI_DEBUG_MESG_FLUSH_CMDID, NO_SESSION, 0); 10094 ret = wmi_unified_cmd_send(wmi_handle, 10095 buf, 10096 len, 10097 WMI_DEBUG_MESG_FLUSH_CMDID); 10098 if (QDF_IS_STATUS_ERROR(ret)) { 10099 wmi_err("Failed to send WMI_DEBUG_MESG_FLUSH_CMDID"); 10100 wmi_buf_free(buf); 10101 return QDF_STATUS_E_INVAL; 10102 } 10103 wmi_debug("Sent WMI_DEBUG_MESG_FLUSH_CMDID to FW"); 10104 10105 return ret; 10106 } 10107 10108 #ifdef BIG_ENDIAN_HOST 10109 #ifdef WLAN_FEATURE_FIPS_BER_CCMGCM 10110 /** 10111 * fips_extend_align_data_be() - LE to BE conversion of FIPS extend ev data 10112 * @wmi_handle: wmi handle 10113 * @param: fips extend param related parameters 10114 * 10115 * Return: QDF_STATUS - success or error status 10116 */ 10117 static QDF_STATUS fips_extend_align_data_be(wmi_unified_t wmi_handle, 10118 struct fips_extend_params *param) 10119 { 10120 unsigned char *key_unaligned, *nonce_iv_unaligned, *data_unaligned; 10121 int c; 10122 u_int8_t *key_aligned = NULL; 10123 u_int8_t *nonce_iv_aligned = NULL; 10124 u_int8_t *data_aligned = NULL; 10125 int ret = QDF_STATUS_SUCCESS; 10126 10127 /* Assigning unaligned space to copy the key */ 10128 key_unaligned = qdf_mem_malloc(sizeof(u_int8_t) * 10129 param->cmd_params.key_len + FIPS_ALIGN); 10130 /* Checking if kmalloc is successful to allocate space */ 10131 if (!key_unaligned) 10132 return QDF_STATUS_E_INVAL; 10133 10134 data_unaligned = qdf_mem_malloc(sizeof(u_int8_t) * param->data_len + 10135 FIPS_ALIGN); 10136 /* Checking if kmalloc is successful to allocate space */ 10137 if (!data_unaligned) { 10138 ret = QDF_STATUS_E_INVAL; 10139 goto fips_align_fail_data; 10140 } 10141 10142 /* Checking if space is aligned */ 10143 if (!FIPS_IS_ALIGNED(key_unaligned, FIPS_ALIGN)) { 10144 /* align to 4 */ 10145 key_aligned = (u_int8_t *)FIPS_ALIGNTO(key_unaligned, 10146 FIPS_ALIGN); 10147 } else { 10148 key_aligned = (u_int8_t *)key_unaligned; 10149 } 10150 10151 /* memset and copy content from key to key aligned */ 10152 OS_MEMSET(key_aligned, 0, param->cmd_params.key_len); 10153 OS_MEMCPY(key_aligned, param->cmd_params.key, 10154 param->cmd_params.key_len); 10155 10156 /* print a hexdump for host debug */ 10157 wmi_debug("Aligned and Copied Key: "); 10158 qdf_trace_hex_dump(QDF_MODULE_ID_WMI, QDF_TRACE_LEVEL_DEBUG, 10159 key_aligned, param->cmd_params.key_len); 10160 10161 /* Checking of space is aligned */ 10162 if (!FIPS_IS_ALIGNED(data_unaligned, FIPS_ALIGN)) { 10163 /* align to 4 */ 10164 data_aligned = 10165 (u_int8_t *)FIPS_ALIGNTO(data_unaligned, FIPS_ALIGN); 10166 } else { 10167 data_aligned = (u_int8_t *)data_unaligned; 10168 } 10169 10170 /* memset and copy content from data to data aligned */ 10171 OS_MEMSET(data_aligned, 0, param->data_len); 10172 OS_MEMCPY(data_aligned, param->data, param->data_len); 10173 10174 /* print a hexdump for host debug */ 10175 wmi_debug("\t Properly Aligned and Copied Data: "); 10176 qdf_trace_hex_dump(QDF_MODULE_ID_WMI, QDF_TRACE_LEVEL_DEBUG, 10177 data_aligned, param->data_len); 10178 10179 /* converting to little Endian */ 10180 for (c = 0; c < param->cmd_params.key_len / 4; c++) { 10181 *((u_int32_t *)key_aligned + c) = 10182 qdf_cpu_to_le32(*((u_int32_t *)key_aligned + c)); 10183 } 10184 for (c = 0; c < param->data_len / 4; c++) { 10185 *((u_int32_t *)data_aligned + c) = 10186 qdf_cpu_to_le32(*((u_int32_t *)data_aligned + c)); 10187 } 10188 10189 /* update endian data */ 10190 OS_MEMCPY(param->cmd_params.key, key_aligned, 10191 param->cmd_params.key_len); 10192 OS_MEMCPY(param->data, data_aligned, param->data_len); 10193 10194 if (param->cmd_params.nonce_iv_len) { 10195 nonce_iv_unaligned = qdf_mem_malloc(sizeof(u_int8_t) * 10196 param->cmd_params.nonce_iv_len + 10197 FIPS_ALIGN); 10198 10199 /* Checking if kmalloc is successful to allocate space */ 10200 if (!nonce_iv_unaligned) { 10201 ret = QDF_STATUS_E_INVAL; 10202 goto fips_align_fail_nonce_iv; 10203 } 10204 /* Checking if space is aligned */ 10205 if (!FIPS_IS_ALIGNED(nonce_iv_unaligned, FIPS_ALIGN)) { 10206 /* align to 4 */ 10207 nonce_iv_aligned = 10208 (u_int8_t *)FIPS_ALIGNTO(nonce_iv_unaligned, 10209 FIPS_ALIGN); 10210 } else { 10211 nonce_iv_aligned = (u_int8_t *)nonce_iv_unaligned; 10212 } 10213 10214 /* memset and copy content from iv to iv aligned */ 10215 OS_MEMSET(nonce_iv_aligned, 0, param->cmd_params.nonce_iv_len); 10216 OS_MEMCPY(nonce_iv_aligned, param->cmd_params.nonce_iv, 10217 param->cmd_params.nonce_iv_len); 10218 10219 /* print a hexdump for host debug */ 10220 wmi_debug("\t Aligned and Copied Nonce_IV: "); 10221 qdf_trace_hex_dump(QDF_MODULE_ID_WMI, QDF_TRACE_LEVEL_DEBUG, 10222 nonce_iv_aligned, 10223 param->cmd_params.nonce_iv_len); 10224 10225 for (c = 0; c < param->cmd_params.nonce_iv_len / 4; c++) { 10226 *((u_int32_t *)nonce_iv_aligned + c) = 10227 qdf_cpu_to_le32(*((u_int32_t *)nonce_iv_aligned + c)); 10228 } 10229 } 10230 10231 /* clean up allocated spaces */ 10232 qdf_mem_free(nonce_iv_unaligned); 10233 nonce_iv_unaligned = NULL; 10234 nonce_iv_aligned = NULL; 10235 10236 fips_align_fail_nonce_iv: 10237 qdf_mem_free(data_unaligned); 10238 data_unaligned = NULL; 10239 data_aligned = NULL; 10240 10241 fips_align_fail_data: 10242 qdf_mem_free(key_unaligned); 10243 key_unaligned = NULL; 10244 key_aligned = NULL; 10245 10246 return ret; 10247 } 10248 #endif 10249 10250 /** 10251 * fips_align_data_be() - LE to BE conversion of FIPS ev data 10252 * @wmi_handle: wmi handle 10253 * @param: fips param related parameters 10254 * 10255 * Return: QDF_STATUS - success or error status 10256 */ 10257 static QDF_STATUS fips_align_data_be(wmi_unified_t wmi_handle, 10258 struct fips_params *param) 10259 { 10260 unsigned char *key_unaligned, *data_unaligned; 10261 int c; 10262 u_int8_t *key_aligned = NULL; 10263 u_int8_t *data_aligned = NULL; 10264 10265 /* Assigning unaligned space to copy the key */ 10266 key_unaligned = qdf_mem_malloc( 10267 sizeof(u_int8_t)*param->key_len + FIPS_ALIGN); 10268 data_unaligned = qdf_mem_malloc( 10269 sizeof(u_int8_t)*param->data_len + FIPS_ALIGN); 10270 10271 /* Checking if kmalloc is successful to allocate space */ 10272 if (!key_unaligned) 10273 return QDF_STATUS_SUCCESS; 10274 /* Checking if space is aligned */ 10275 if (!FIPS_IS_ALIGNED(key_unaligned, FIPS_ALIGN)) { 10276 /* align to 4 */ 10277 key_aligned = 10278 (u_int8_t *)FIPS_ALIGNTO(key_unaligned, 10279 FIPS_ALIGN); 10280 } else { 10281 key_aligned = (u_int8_t *)key_unaligned; 10282 } 10283 10284 /* memset and copy content from key to key aligned */ 10285 OS_MEMSET(key_aligned, 0, param->key_len); 10286 OS_MEMCPY(key_aligned, param->key, param->key_len); 10287 10288 /* print a hexdump for host debug */ 10289 print_hex_dump(KERN_DEBUG, 10290 "\t Aligned and Copied Key:@@@@ ", 10291 DUMP_PREFIX_NONE, 10292 16, 1, key_aligned, param->key_len, true); 10293 10294 /* Checking if kmalloc is successful to allocate space */ 10295 if (!data_unaligned) 10296 return QDF_STATUS_SUCCESS; 10297 /* Checking of space is aligned */ 10298 if (!FIPS_IS_ALIGNED(data_unaligned, FIPS_ALIGN)) { 10299 /* align to 4 */ 10300 data_aligned = 10301 (u_int8_t *)FIPS_ALIGNTO(data_unaligned, 10302 FIPS_ALIGN); 10303 } else { 10304 data_aligned = (u_int8_t *)data_unaligned; 10305 } 10306 10307 /* memset and copy content from data to data aligned */ 10308 OS_MEMSET(data_aligned, 0, param->data_len); 10309 OS_MEMCPY(data_aligned, param->data, param->data_len); 10310 10311 /* print a hexdump for host debug */ 10312 print_hex_dump(KERN_DEBUG, 10313 "\t Properly Aligned and Copied Data:@@@@ ", 10314 DUMP_PREFIX_NONE, 10315 16, 1, data_aligned, param->data_len, true); 10316 10317 /* converting to little Endian both key_aligned and 10318 * data_aligned*/ 10319 for (c = 0; c < param->key_len/4; c++) { 10320 *((u_int32_t *)key_aligned+c) = 10321 qdf_cpu_to_le32(*((u_int32_t *)key_aligned+c)); 10322 } 10323 for (c = 0; c < param->data_len/4; c++) { 10324 *((u_int32_t *)data_aligned+c) = 10325 qdf_cpu_to_le32(*((u_int32_t *)data_aligned+c)); 10326 } 10327 10328 /* update endian data to key and data vectors */ 10329 OS_MEMCPY(param->key, key_aligned, param->key_len); 10330 OS_MEMCPY(param->data, data_aligned, param->data_len); 10331 10332 /* clean up allocated spaces */ 10333 qdf_mem_free(key_unaligned); 10334 key_unaligned = NULL; 10335 key_aligned = NULL; 10336 10337 qdf_mem_free(data_unaligned); 10338 data_unaligned = NULL; 10339 data_aligned = NULL; 10340 10341 return QDF_STATUS_SUCCESS; 10342 } 10343 #else 10344 #ifdef WLAN_FEATURE_FIPS_BER_CCMGCM 10345 static QDF_STATUS fips_extend_align_data_be(wmi_unified_t wmi_handle, 10346 struct fips_extend_params *param) 10347 { 10348 return QDF_STATUS_SUCCESS; 10349 } 10350 #endif 10351 10352 static QDF_STATUS fips_align_data_be(wmi_unified_t wmi_handle, 10353 struct fips_params *param) 10354 { 10355 return QDF_STATUS_SUCCESS; 10356 } 10357 #endif 10358 10359 #ifdef WLAN_FEATURE_DISA 10360 /** 10361 * send_encrypt_decrypt_send_cmd_tlv() - send encrypt/decrypt cmd to fw 10362 * @wmi_handle: wmi handle 10363 * @encrypt_decrypt_params: encrypt/decrypt params 10364 * 10365 * Return: QDF_STATUS_SUCCESS for success or error code 10366 */ 10367 static QDF_STATUS 10368 send_encrypt_decrypt_send_cmd_tlv(wmi_unified_t wmi_handle, 10369 struct disa_encrypt_decrypt_req_params 10370 *encrypt_decrypt_params) 10371 { 10372 wmi_vdev_encrypt_decrypt_data_req_cmd_fixed_param *cmd; 10373 wmi_buf_t wmi_buf; 10374 uint8_t *buf_ptr; 10375 QDF_STATUS ret; 10376 uint32_t len; 10377 10378 wmi_debug("Send encrypt decrypt cmd"); 10379 10380 len = sizeof(*cmd) + 10381 encrypt_decrypt_params->data_len + 10382 WMI_TLV_HDR_SIZE; 10383 wmi_buf = wmi_buf_alloc(wmi_handle, len); 10384 if (!wmi_buf) 10385 return QDF_STATUS_E_NOMEM; 10386 10387 buf_ptr = wmi_buf_data(wmi_buf); 10388 cmd = (wmi_vdev_encrypt_decrypt_data_req_cmd_fixed_param *)buf_ptr; 10389 10390 WMITLV_SET_HDR(&cmd->tlv_header, 10391 WMITLV_TAG_STRUC_wmi_vdev_encrypt_decrypt_data_req_cmd_fixed_param, 10392 WMITLV_GET_STRUCT_TLVLEN( 10393 wmi_vdev_encrypt_decrypt_data_req_cmd_fixed_param)); 10394 10395 cmd->vdev_id = encrypt_decrypt_params->vdev_id; 10396 cmd->key_flag = encrypt_decrypt_params->key_flag; 10397 cmd->key_idx = encrypt_decrypt_params->key_idx; 10398 cmd->key_cipher = encrypt_decrypt_params->key_cipher; 10399 cmd->key_len = encrypt_decrypt_params->key_len; 10400 cmd->key_txmic_len = encrypt_decrypt_params->key_txmic_len; 10401 cmd->key_rxmic_len = encrypt_decrypt_params->key_rxmic_len; 10402 10403 qdf_mem_copy(cmd->key_data, encrypt_decrypt_params->key_data, 10404 encrypt_decrypt_params->key_len); 10405 10406 qdf_mem_copy(cmd->mac_hdr, encrypt_decrypt_params->mac_header, 10407 MAX_MAC_HEADER_LEN); 10408 10409 cmd->data_len = encrypt_decrypt_params->data_len; 10410 10411 if (cmd->data_len) { 10412 buf_ptr += sizeof(*cmd); 10413 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, 10414 roundup(encrypt_decrypt_params->data_len, 10415 sizeof(uint32_t))); 10416 buf_ptr += WMI_TLV_HDR_SIZE; 10417 qdf_mem_copy(buf_ptr, encrypt_decrypt_params->data, 10418 encrypt_decrypt_params->data_len); 10419 } 10420 10421 /* This conversion is to facilitate data to FW in little endian */ 10422 cmd->pn[5] = encrypt_decrypt_params->pn[0]; 10423 cmd->pn[4] = encrypt_decrypt_params->pn[1]; 10424 cmd->pn[3] = encrypt_decrypt_params->pn[2]; 10425 cmd->pn[2] = encrypt_decrypt_params->pn[3]; 10426 cmd->pn[1] = encrypt_decrypt_params->pn[4]; 10427 cmd->pn[0] = encrypt_decrypt_params->pn[5]; 10428 10429 wmi_mtrace(WMI_VDEV_ENCRYPT_DECRYPT_DATA_REQ_CMDID, cmd->vdev_id, 0); 10430 ret = wmi_unified_cmd_send(wmi_handle, 10431 wmi_buf, len, 10432 WMI_VDEV_ENCRYPT_DECRYPT_DATA_REQ_CMDID); 10433 if (QDF_IS_STATUS_ERROR(ret)) { 10434 wmi_err("Failed to send ENCRYPT DECRYPT cmd: %d", ret); 10435 wmi_buf_free(wmi_buf); 10436 } 10437 10438 return ret; 10439 } 10440 #endif /* WLAN_FEATURE_DISA */ 10441 10442 /** 10443 * send_pdev_fips_cmd_tlv() - send pdev fips cmd to fw 10444 * @wmi_handle: wmi handle 10445 * @param: pointer to hold pdev fips param 10446 * 10447 * Return: QDF_STATUS_SUCCESS for success or error code 10448 */ 10449 static QDF_STATUS 10450 send_pdev_fips_cmd_tlv(wmi_unified_t wmi_handle, 10451 struct fips_params *param) 10452 { 10453 wmi_pdev_fips_cmd_fixed_param *cmd; 10454 wmi_buf_t buf; 10455 uint8_t *buf_ptr; 10456 uint32_t len = sizeof(wmi_pdev_fips_cmd_fixed_param); 10457 QDF_STATUS retval = QDF_STATUS_SUCCESS; 10458 10459 /* Length TLV placeholder for array of bytes */ 10460 len += WMI_TLV_HDR_SIZE; 10461 if (param->data_len) 10462 len += (param->data_len*sizeof(uint8_t)); 10463 10464 /* 10465 * Data length must be multiples of 16 bytes - checked against 0xF - 10466 * and must be less than WMI_SVC_MSG_SIZE - static size of 10467 * wmi_pdev_fips_cmd structure 10468 */ 10469 10470 /* do sanity on the input */ 10471 if (!(((param->data_len & 0xF) == 0) && 10472 ((param->data_len > 0) && 10473 (param->data_len < (WMI_HOST_MAX_BUFFER_SIZE - 10474 sizeof(wmi_pdev_fips_cmd_fixed_param)))))) { 10475 return QDF_STATUS_E_INVAL; 10476 } 10477 10478 buf = wmi_buf_alloc(wmi_handle, len); 10479 if (!buf) 10480 return QDF_STATUS_E_FAILURE; 10481 10482 buf_ptr = (uint8_t *) wmi_buf_data(buf); 10483 cmd = (wmi_pdev_fips_cmd_fixed_param *)buf_ptr; 10484 WMITLV_SET_HDR(&cmd->tlv_header, 10485 WMITLV_TAG_STRUC_wmi_pdev_fips_cmd_fixed_param, 10486 WMITLV_GET_STRUCT_TLVLEN 10487 (wmi_pdev_fips_cmd_fixed_param)); 10488 10489 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 10490 wmi_handle, 10491 param->pdev_id); 10492 if (param->key && param->data) { 10493 cmd->key_len = param->key_len; 10494 cmd->data_len = param->data_len; 10495 cmd->fips_cmd = !!(param->op); 10496 10497 if (fips_align_data_be(wmi_handle, param) != QDF_STATUS_SUCCESS) 10498 return QDF_STATUS_E_FAILURE; 10499 10500 qdf_mem_copy(cmd->key, param->key, param->key_len); 10501 10502 if (param->mode == FIPS_ENGINE_AES_CTR || 10503 param->mode == FIPS_ENGINE_AES_MIC) { 10504 cmd->mode = param->mode; 10505 } else { 10506 cmd->mode = FIPS_ENGINE_AES_CTR; 10507 } 10508 qdf_print("Key len = %d, Data len = %d", 10509 cmd->key_len, cmd->data_len); 10510 10511 print_hex_dump(KERN_DEBUG, "Key: ", DUMP_PREFIX_NONE, 16, 1, 10512 cmd->key, cmd->key_len, true); 10513 buf_ptr += sizeof(*cmd); 10514 10515 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, param->data_len); 10516 10517 buf_ptr += WMI_TLV_HDR_SIZE; 10518 if (param->data_len) 10519 qdf_mem_copy(buf_ptr, 10520 (uint8_t *) param->data, param->data_len); 10521 10522 print_hex_dump(KERN_DEBUG, "Plain text: ", DUMP_PREFIX_NONE, 10523 16, 1, buf_ptr, cmd->data_len, true); 10524 10525 buf_ptr += param->data_len; 10526 10527 wmi_mtrace(WMI_PDEV_FIPS_CMDID, NO_SESSION, 0); 10528 retval = wmi_unified_cmd_send(wmi_handle, buf, len, 10529 WMI_PDEV_FIPS_CMDID); 10530 qdf_print("%s return value %d", __func__, retval); 10531 } else { 10532 qdf_print("\n%s:%d Key or Data is NULL", __func__, __LINE__); 10533 wmi_buf_free(buf); 10534 retval = -QDF_STATUS_E_BADMSG; 10535 } 10536 10537 return retval; 10538 } 10539 10540 #ifdef WLAN_FEATURE_FIPS_BER_CCMGCM 10541 /** 10542 * send_pdev_fips_extend_cmd_tlv() - send pdev fips cmd to fw 10543 * @wmi_handle: wmi handle 10544 * @param: pointer to hold pdev fips param 10545 * 10546 * Return: QDF_STATUS_SUCCESS for success or error code 10547 */ 10548 static QDF_STATUS 10549 send_pdev_fips_extend_cmd_tlv(wmi_unified_t wmi_handle, 10550 struct fips_extend_params *param) 10551 { 10552 wmi_pdev_fips_extend_cmd_fixed_param *cmd; 10553 wmi_buf_t buf; 10554 uint8_t *buf_ptr; 10555 uint32_t len = sizeof(wmi_pdev_fips_extend_cmd_fixed_param); 10556 uint32_t data_len_aligned; 10557 QDF_STATUS retval = QDF_STATUS_SUCCESS; 10558 10559 len += WMI_TLV_HDR_SIZE; 10560 if (param->frag_idx == 0) 10561 len += sizeof(wmi_fips_extend_cmd_init_params); 10562 10563 /* Length TLV placeholder for array of bytes */ 10564 len += WMI_TLV_HDR_SIZE; 10565 if (param->data_len) { 10566 data_len_aligned = roundup(param->data_len, sizeof(uint32_t)); 10567 len += (data_len_aligned * sizeof(uint8_t)); 10568 } 10569 10570 buf = wmi_buf_alloc(wmi_handle, len); 10571 if (!buf) 10572 return QDF_STATUS_E_FAILURE; 10573 10574 buf_ptr = (uint8_t *)wmi_buf_data(buf); 10575 cmd = (wmi_pdev_fips_extend_cmd_fixed_param *)buf_ptr; 10576 WMITLV_SET_HDR(&cmd->tlv_header, 10577 WMITLV_TAG_STRUC_wmi_pdev_fips_extend_cmd_fixed_param, 10578 WMITLV_GET_STRUCT_TLVLEN 10579 (wmi_pdev_fips_extend_cmd_fixed_param)); 10580 10581 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 10582 wmi_handle, 10583 param->pdev_id); 10584 10585 cmd->fips_cookie = param->cookie; 10586 cmd->frag_idx = param->frag_idx; 10587 cmd->more_bit = param->more_bit; 10588 cmd->data_len = param->data_len; 10589 10590 if (fips_extend_align_data_be(wmi_handle, param) != 10591 QDF_STATUS_SUCCESS) { 10592 wmi_buf_free(buf); 10593 return QDF_STATUS_E_FAILURE; 10594 } 10595 10596 buf_ptr = (uint8_t *)(cmd + 1); 10597 if (cmd->frag_idx == 0) { 10598 wmi_fips_extend_cmd_init_params *cmd_params; 10599 10600 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 10601 sizeof(wmi_fips_extend_cmd_init_params)); 10602 buf_ptr += WMI_TLV_HDR_SIZE; 10603 cmd_params = (wmi_fips_extend_cmd_init_params *)buf_ptr; 10604 WMITLV_SET_HDR(buf_ptr, 10605 WMITLV_TAG_STRUC_wmi_fips_extend_cmd_init_params, 10606 WMITLV_GET_STRUCT_TLVLEN(wmi_fips_extend_cmd_init_params)); 10607 cmd_params->fips_cmd = param->cmd_params.fips_cmd; 10608 cmd_params->key_cipher = param->cmd_params.key_cipher; 10609 cmd_params->key_len = param->cmd_params.key_len; 10610 cmd_params->nonce_iv_len = param->cmd_params.nonce_iv_len; 10611 cmd_params->tag_len = param->cmd_params.tag_len; 10612 cmd_params->aad_len = param->cmd_params.aad_len; 10613 cmd_params->payload_len = param->cmd_params.payload_len; 10614 10615 qdf_mem_copy(cmd_params->key, param->cmd_params.key, 10616 param->cmd_params.key_len); 10617 qdf_mem_copy(cmd_params->nonce_iv, param->cmd_params.nonce_iv, 10618 param->cmd_params.nonce_iv_len); 10619 10620 wmi_debug("Key len = %d, IVNoncelen = %d, Tlen = %d, Alen = %d, Plen = %d", 10621 cmd_params->key_len, cmd_params->nonce_iv_len, 10622 cmd_params->tag_len, cmd_params->aad_len, 10623 cmd_params->payload_len); 10624 10625 buf_ptr += sizeof(wmi_fips_extend_cmd_init_params); 10626 } else { 10627 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0); 10628 buf_ptr += WMI_TLV_HDR_SIZE; 10629 } 10630 10631 if (param->data_len && param->data) { 10632 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, 10633 data_len_aligned); 10634 10635 buf_ptr += WMI_TLV_HDR_SIZE; 10636 if (param->data_len) 10637 qdf_mem_copy(buf_ptr, 10638 (uint8_t *)param->data, param->data_len); 10639 10640 wmi_debug("Data: "); 10641 qdf_trace_hex_dump(QDF_MODULE_ID_WMI, QDF_TRACE_LEVEL_DEBUG, 10642 buf_ptr, cmd->data_len); 10643 10644 if (param->data_len) 10645 buf_ptr += param->data_len; 10646 } else { 10647 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, 0); 10648 buf_ptr += WMI_TLV_HDR_SIZE; 10649 } 10650 10651 wmi_mtrace(WMI_PDEV_FIPS_EXTEND_CMDID, NO_SESSION, 0); 10652 retval = wmi_unified_cmd_send(wmi_handle, buf, len, 10653 WMI_PDEV_FIPS_EXTEND_CMDID); 10654 10655 if (retval) { 10656 wmi_err("Failed to send FIPS cmd"); 10657 wmi_buf_free(buf); 10658 } 10659 10660 return retval; 10661 } 10662 10663 /** 10664 * send_pdev_fips_mode_set_cmd_tlv() - send pdev fips cmd to fw 10665 * @wmi_handle: wmi handle 10666 * @param: pointer to hold pdev fips param 10667 * 10668 * Return: QDF_STATUS_SUCCESS for success or error code 10669 */ 10670 static QDF_STATUS 10671 send_pdev_fips_mode_set_cmd_tlv(wmi_unified_t wmi_handle, 10672 struct fips_mode_set_params *param) 10673 { 10674 wmi_pdev_fips_mode_set_cmd_fixed_param *cmd; 10675 wmi_buf_t buf; 10676 uint8_t *buf_ptr; 10677 uint32_t len = sizeof(wmi_pdev_fips_mode_set_cmd_fixed_param); 10678 QDF_STATUS retval = QDF_STATUS_SUCCESS; 10679 10680 buf = wmi_buf_alloc(wmi_handle, len); 10681 if (!buf) 10682 return QDF_STATUS_E_FAILURE; 10683 10684 buf_ptr = (uint8_t *)wmi_buf_data(buf); 10685 cmd = (wmi_pdev_fips_mode_set_cmd_fixed_param *)buf_ptr; 10686 WMITLV_SET_HDR(&cmd->tlv_header, 10687 WMITLV_TAG_STRUC_wmi_pdev_fips_mode_set_cmd_fixed_param, 10688 WMITLV_GET_STRUCT_TLVLEN 10689 (wmi_pdev_fips_mode_set_cmd_fixed_param)); 10690 10691 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 10692 wmi_handle, 10693 param->pdev_id); 10694 10695 cmd->fips_mode_set = param->mode; 10696 wmi_mtrace(WMI_PDEV_FIPS_MODE_SET_CMDID, NO_SESSION, 0); 10697 retval = wmi_unified_cmd_send(wmi_handle, buf, len, 10698 WMI_PDEV_FIPS_MODE_SET_CMDID); 10699 if (retval) { 10700 wmi_err("Failed to send FIPS mode enable cmd"); 10701 wmi_buf_free(buf); 10702 } 10703 return retval; 10704 } 10705 #endif 10706 10707 /** 10708 * send_wlan_profile_enable_cmd_tlv() - send wlan profile enable command 10709 * to fw 10710 * @wmi_handle: wmi handle 10711 * @param: pointer to wlan profile param 10712 * 10713 * Return: QDF_STATUS_SUCCESS for success or error code 10714 */ 10715 static QDF_STATUS 10716 send_wlan_profile_enable_cmd_tlv(wmi_unified_t wmi_handle, 10717 struct wlan_profile_params *param) 10718 { 10719 wmi_buf_t buf; 10720 uint16_t len; 10721 QDF_STATUS ret; 10722 wmi_wlan_profile_enable_profile_id_cmd_fixed_param *profile_enable_cmd; 10723 10724 len = sizeof(wmi_wlan_profile_enable_profile_id_cmd_fixed_param); 10725 buf = wmi_buf_alloc(wmi_handle, len); 10726 if (!buf) { 10727 wmi_err("Failed to send WMI_WLAN_PROFILE_ENABLE_PROFILE_ID_CMDID"); 10728 return QDF_STATUS_E_NOMEM; 10729 } 10730 10731 profile_enable_cmd = 10732 (wmi_wlan_profile_enable_profile_id_cmd_fixed_param *) 10733 wmi_buf_data(buf); 10734 WMITLV_SET_HDR(&profile_enable_cmd->tlv_header, 10735 WMITLV_TAG_STRUC_wmi_wlan_profile_enable_profile_id_cmd_fixed_param, 10736 WMITLV_GET_STRUCT_TLVLEN 10737 (wmi_wlan_profile_enable_profile_id_cmd_fixed_param)); 10738 10739 profile_enable_cmd->profile_id = param->profile_id; 10740 profile_enable_cmd->enable = param->enable; 10741 wmi_mtrace(WMI_WLAN_PROFILE_ENABLE_PROFILE_ID_CMDID, 10742 NO_SESSION, 0); 10743 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 10744 WMI_WLAN_PROFILE_ENABLE_PROFILE_ID_CMDID); 10745 if (ret) { 10746 wmi_err("Failed to send PROFILE_ENABLE_PROFILE_ID_CMDID"); 10747 wmi_buf_free(buf); 10748 } 10749 return ret; 10750 } 10751 10752 /** 10753 * send_wlan_profile_trigger_cmd_tlv() - send wlan profile trigger command 10754 * to fw 10755 * @wmi_handle: wmi handle 10756 * @param: pointer to wlan profile param 10757 * 10758 * Return: QDF_STATUS_SUCCESS for success or error code 10759 */ 10760 static QDF_STATUS 10761 send_wlan_profile_trigger_cmd_tlv(wmi_unified_t wmi_handle, 10762 struct wlan_profile_params *param) 10763 { 10764 wmi_buf_t buf; 10765 uint16_t len; 10766 QDF_STATUS ret; 10767 wmi_wlan_profile_trigger_cmd_fixed_param *prof_trig_cmd; 10768 10769 len = sizeof(wmi_wlan_profile_trigger_cmd_fixed_param); 10770 buf = wmi_buf_alloc(wmi_handle, len); 10771 if (!buf) { 10772 wmi_err("Failed to send WMI_WLAN_PROFILE_TRIGGER_CMDID"); 10773 return QDF_STATUS_E_NOMEM; 10774 } 10775 10776 prof_trig_cmd = 10777 (wmi_wlan_profile_trigger_cmd_fixed_param *) 10778 wmi_buf_data(buf); 10779 10780 WMITLV_SET_HDR(&prof_trig_cmd->tlv_header, 10781 WMITLV_TAG_STRUC_wmi_wlan_profile_trigger_cmd_fixed_param, 10782 WMITLV_GET_STRUCT_TLVLEN 10783 (wmi_wlan_profile_trigger_cmd_fixed_param)); 10784 10785 prof_trig_cmd->enable = param->enable; 10786 wmi_mtrace(WMI_WLAN_PROFILE_TRIGGER_CMDID, NO_SESSION, 0); 10787 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 10788 WMI_WLAN_PROFILE_TRIGGER_CMDID); 10789 if (ret) { 10790 wmi_err("Failed to send WMI_WLAN_PROFILE_TRIGGER_CMDID"); 10791 wmi_buf_free(buf); 10792 } 10793 return ret; 10794 } 10795 10796 /** 10797 * send_wlan_profile_hist_intvl_cmd_tlv() - send wlan profile interval command 10798 * to fw 10799 * @wmi_handle: wmi handle 10800 * @param: pointer to wlan profile param 10801 * 10802 * Return: QDF_STATUS_SUCCESS for success or error code 10803 */ 10804 static QDF_STATUS 10805 send_wlan_profile_hist_intvl_cmd_tlv(wmi_unified_t wmi_handle, 10806 struct wlan_profile_params *param) 10807 { 10808 wmi_buf_t buf; 10809 int32_t len = 0; 10810 QDF_STATUS ret; 10811 wmi_wlan_profile_set_hist_intvl_cmd_fixed_param *hist_intvl_cmd; 10812 10813 len = sizeof(wmi_wlan_profile_set_hist_intvl_cmd_fixed_param); 10814 buf = wmi_buf_alloc(wmi_handle, len); 10815 if (!buf) { 10816 wmi_err("Failed to send WMI_WLAN_PROFILE_SET_HIST_INTVL_CMDID"); 10817 return QDF_STATUS_E_NOMEM; 10818 } 10819 10820 hist_intvl_cmd = 10821 (wmi_wlan_profile_set_hist_intvl_cmd_fixed_param *) 10822 wmi_buf_data(buf); 10823 10824 WMITLV_SET_HDR(&hist_intvl_cmd->tlv_header, 10825 WMITLV_TAG_STRUC_wmi_wlan_profile_set_hist_intvl_cmd_fixed_param, 10826 WMITLV_GET_STRUCT_TLVLEN 10827 (wmi_wlan_profile_set_hist_intvl_cmd_fixed_param)); 10828 10829 hist_intvl_cmd->profile_id = param->profile_id; 10830 hist_intvl_cmd->value = param->enable; 10831 wmi_mtrace(WMI_WLAN_PROFILE_SET_HIST_INTVL_CMDID, 10832 NO_SESSION, 0); 10833 10834 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 10835 WMI_WLAN_PROFILE_SET_HIST_INTVL_CMDID); 10836 if (ret) { 10837 wmi_err("Failed to send PROFILE_SET_HIST_INTVL_CMDID"); 10838 wmi_buf_free(buf); 10839 } 10840 return ret; 10841 } 10842 10843 /** 10844 * send_fw_test_cmd_tlv() - send fw test command to fw. 10845 * @wmi_handle: wmi handle 10846 * @wmi_fwtest: fw test command 10847 * 10848 * This function sends fw test command to fw. 10849 * 10850 * Return: CDF STATUS 10851 */ 10852 static 10853 QDF_STATUS send_fw_test_cmd_tlv(wmi_unified_t wmi_handle, 10854 struct set_fwtest_params *wmi_fwtest) 10855 { 10856 wmi_fwtest_set_param_cmd_fixed_param *cmd; 10857 wmi_buf_t wmi_buf; 10858 uint16_t len; 10859 10860 len = sizeof(*cmd); 10861 10862 wmi_buf = wmi_buf_alloc(wmi_handle, len); 10863 if (!wmi_buf) 10864 return QDF_STATUS_E_NOMEM; 10865 10866 cmd = (wmi_fwtest_set_param_cmd_fixed_param *) wmi_buf_data(wmi_buf); 10867 WMITLV_SET_HDR(&cmd->tlv_header, 10868 WMITLV_TAG_STRUC_wmi_fwtest_set_param_cmd_fixed_param, 10869 WMITLV_GET_STRUCT_TLVLEN( 10870 wmi_fwtest_set_param_cmd_fixed_param)); 10871 cmd->param_id = wmi_fwtest->arg; 10872 cmd->param_value = wmi_fwtest->value; 10873 10874 wmi_mtrace(WMI_FWTEST_CMDID, NO_SESSION, 0); 10875 if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len, 10876 WMI_FWTEST_CMDID)) { 10877 wmi_err("Failed to send fw test command"); 10878 wmi_buf_free(wmi_buf); 10879 return QDF_STATUS_E_FAILURE; 10880 } 10881 10882 return QDF_STATUS_SUCCESS; 10883 } 10884 10885 static uint16_t wfa_config_param_len(enum wfa_test_cmds config) 10886 { 10887 uint16_t len = 0; 10888 10889 if (config == WFA_CONFIG_RXNE) 10890 len += WMI_TLV_HDR_SIZE + sizeof(wmi_wfa_config_rsnxe); 10891 else 10892 len += WMI_TLV_HDR_SIZE; 10893 10894 if (config == WFA_CONFIG_CSA) 10895 len += WMI_TLV_HDR_SIZE + sizeof(wmi_wfa_config_csa); 10896 else 10897 len += WMI_TLV_HDR_SIZE; 10898 10899 if (config == WFA_CONFIG_OCV) 10900 len += WMI_TLV_HDR_SIZE + sizeof(wmi_wfa_config_ocv); 10901 else 10902 len += WMI_TLV_HDR_SIZE; 10903 10904 if (config == WFA_CONFIG_SA_QUERY) 10905 len += WMI_TLV_HDR_SIZE + sizeof(wmi_wfa_config_saquery); 10906 else 10907 len += WMI_TLV_HDR_SIZE; 10908 10909 return len; 10910 } 10911 10912 /** 10913 * wmi_fill_ocv_frame_type() - Fill host ocv frm type into WMI ocv frm type. 10914 * @host_frmtype: Host defined OCV frame type 10915 * @ocv_frmtype: Pointer to hold WMI OCV frame type 10916 * 10917 * This function converts and fills host defined OCV frame type into WMI OCV 10918 * frame type. 10919 * 10920 * Return: CDF STATUS 10921 */ 10922 static QDF_STATUS 10923 wmi_fill_ocv_frame_type(uint32_t host_frmtype, uint32_t *ocv_frmtype) 10924 { 10925 switch (host_frmtype) { 10926 case WMI_HOST_WFA_CONFIG_OCV_FRMTYPE_SAQUERY_REQ: 10927 *ocv_frmtype = WMI_WFA_CONFIG_OCV_FRMTYPE_SAQUERY_REQ; 10928 break; 10929 10930 case WMI_HOST_WFA_CONFIG_OCV_FRMTYPE_SAQUERY_RSP: 10931 *ocv_frmtype = WMI_WFA_CONFIG_OCV_FRMTYPE_SAQUERY_RSP; 10932 break; 10933 10934 case WMI_HOST_WFA_CONFIG_OCV_FRMTYPE_FT_REASSOC_REQ: 10935 *ocv_frmtype = WMI_WFA_CONFIG_OCV_FRMTYPE_FT_REASSOC_REQ; 10936 break; 10937 10938 case WMI_HOST_WFA_CONFIG_OCV_FRMTYPE_FILS_REASSOC_REQ: 10939 *ocv_frmtype = WMI_WFA_CONFIG_OCV_FRMTYPE_FILS_REASSOC_REQ; 10940 break; 10941 10942 default: 10943 wmi_err("Invalid command type cmd %d", host_frmtype); 10944 return QDF_STATUS_E_FAILURE; 10945 } 10946 10947 return QDF_STATUS_SUCCESS; 10948 } 10949 10950 /** 10951 * send_wfa_test_cmd_tlv() - send wfa test command to fw. 10952 * @wmi_handle: wmi handle 10953 * @wmi_wfatest: wfa test command 10954 * 10955 * This function sends wfa test command to fw. 10956 * 10957 * Return: CDF STATUS 10958 */ 10959 static 10960 QDF_STATUS send_wfa_test_cmd_tlv(wmi_unified_t wmi_handle, 10961 struct set_wfatest_params *wmi_wfatest) 10962 { 10963 wmi_wfa_config_cmd_fixed_param *cmd; 10964 wmi_wfa_config_rsnxe *rxne; 10965 wmi_wfa_config_csa *csa; 10966 wmi_wfa_config_ocv *ocv; 10967 wmi_wfa_config_saquery *saquery; 10968 wmi_buf_t wmi_buf; 10969 uint16_t len = sizeof(*cmd); 10970 uint8_t *buf_ptr; 10971 10972 len += wfa_config_param_len(wmi_wfatest->cmd); 10973 wmi_buf = wmi_buf_alloc(wmi_handle, len); 10974 if (!wmi_buf) 10975 return QDF_STATUS_E_NOMEM; 10976 10977 cmd = (wmi_wfa_config_cmd_fixed_param *)wmi_buf_data(wmi_buf); 10978 WMITLV_SET_HDR(&cmd->tlv_header, 10979 WMITLV_TAG_STRUC_wmi_wfa_config_cmd_fixed_param, 10980 WMITLV_GET_STRUCT_TLVLEN( 10981 wmi_wfa_config_cmd_fixed_param)); 10982 10983 cmd->vdev_id = wmi_wfatest->vdev_id; 10984 buf_ptr = (uint8_t *)(cmd + 1); 10985 10986 if (wmi_wfatest->cmd == WFA_CONFIG_RXNE) { 10987 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 10988 sizeof(wmi_wfa_config_rsnxe)); 10989 buf_ptr += WMI_TLV_HDR_SIZE; 10990 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_STRUC_wmi_wfa_config_rsnxe, 10991 WMITLV_GET_STRUCT_TLVLEN(wmi_wfa_config_rsnxe)); 10992 rxne = (wmi_wfa_config_rsnxe *)buf_ptr; 10993 rxne->rsnxe_param = wmi_wfatest->value; 10994 buf_ptr += sizeof(wmi_wfa_config_rsnxe); 10995 } else { 10996 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0); 10997 buf_ptr += WMI_TLV_HDR_SIZE; 10998 } 10999 11000 if (wmi_wfatest->cmd == WFA_CONFIG_CSA) { 11001 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 11002 sizeof(wmi_wfa_config_csa)); 11003 buf_ptr += WMI_TLV_HDR_SIZE; 11004 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_STRUC_wmi_wfa_config_csa, 11005 WMITLV_GET_STRUCT_TLVLEN(wmi_wfa_config_csa)); 11006 csa = (wmi_wfa_config_csa *)buf_ptr; 11007 csa->ignore_csa = wmi_wfatest->value; 11008 buf_ptr += sizeof(wmi_wfa_config_csa); 11009 } else { 11010 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0); 11011 buf_ptr += WMI_TLV_HDR_SIZE; 11012 } 11013 11014 if (wmi_wfatest->cmd == WFA_CONFIG_OCV) { 11015 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 11016 sizeof(wmi_wfa_config_ocv)); 11017 buf_ptr += WMI_TLV_HDR_SIZE; 11018 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_STRUC_wmi_wfa_config_ocv, 11019 WMITLV_GET_STRUCT_TLVLEN(wmi_wfa_config_ocv)); 11020 ocv = (wmi_wfa_config_ocv *)buf_ptr; 11021 11022 if (wmi_fill_ocv_frame_type(wmi_wfatest->ocv_param->frame_type, 11023 &ocv->frame_types)) 11024 goto error; 11025 11026 ocv->chan_freq = wmi_wfatest->ocv_param->freq; 11027 buf_ptr += sizeof(wmi_wfa_config_ocv); 11028 } else { 11029 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0); 11030 buf_ptr += WMI_TLV_HDR_SIZE; 11031 } 11032 11033 if (wmi_wfatest->cmd == WFA_CONFIG_SA_QUERY) { 11034 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 11035 sizeof(wmi_wfa_config_saquery)); 11036 buf_ptr += WMI_TLV_HDR_SIZE; 11037 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_STRUC_wmi_wfa_config_saquery, 11038 WMITLV_GET_STRUCT_TLVLEN(wmi_wfa_config_saquery)); 11039 11040 saquery = (wmi_wfa_config_saquery *)buf_ptr; 11041 saquery->remain_connect_on_saquery_timeout = wmi_wfatest->value; 11042 } else { 11043 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0); 11044 buf_ptr += WMI_TLV_HDR_SIZE; 11045 } 11046 11047 wmi_mtrace(WMI_WFA_CONFIG_CMDID, wmi_wfatest->vdev_id, 0); 11048 if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len, 11049 WMI_WFA_CONFIG_CMDID)) { 11050 wmi_err("Failed to send wfa test command"); 11051 goto error; 11052 } 11053 11054 return QDF_STATUS_SUCCESS; 11055 11056 error: 11057 wmi_buf_free(wmi_buf); 11058 return QDF_STATUS_E_FAILURE; 11059 } 11060 11061 /** 11062 * send_unit_test_cmd_tlv() - send unit test command to fw. 11063 * @wmi_handle: wmi handle 11064 * @wmi_utest: unit test command 11065 * 11066 * This function send unit test command to fw. 11067 * 11068 * Return: CDF STATUS 11069 */ 11070 static QDF_STATUS send_unit_test_cmd_tlv(wmi_unified_t wmi_handle, 11071 struct wmi_unit_test_cmd *wmi_utest) 11072 { 11073 wmi_unit_test_cmd_fixed_param *cmd; 11074 wmi_buf_t wmi_buf; 11075 uint8_t *buf_ptr; 11076 int i; 11077 uint16_t len, args_tlv_len; 11078 uint32_t *unit_test_cmd_args; 11079 11080 args_tlv_len = 11081 WMI_TLV_HDR_SIZE + wmi_utest->num_args * sizeof(uint32_t); 11082 len = sizeof(wmi_unit_test_cmd_fixed_param) + args_tlv_len; 11083 11084 wmi_buf = wmi_buf_alloc(wmi_handle, len); 11085 if (!wmi_buf) 11086 return QDF_STATUS_E_NOMEM; 11087 11088 cmd = (wmi_unit_test_cmd_fixed_param *) wmi_buf_data(wmi_buf); 11089 buf_ptr = (uint8_t *) cmd; 11090 WMITLV_SET_HDR(&cmd->tlv_header, 11091 WMITLV_TAG_STRUC_wmi_unit_test_cmd_fixed_param, 11092 WMITLV_GET_STRUCT_TLVLEN(wmi_unit_test_cmd_fixed_param)); 11093 cmd->vdev_id = wmi_utest->vdev_id; 11094 cmd->module_id = wmi_utest->module_id; 11095 cmd->num_args = wmi_utest->num_args; 11096 cmd->diag_token = wmi_utest->diag_token; 11097 buf_ptr += sizeof(wmi_unit_test_cmd_fixed_param); 11098 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, 11099 (wmi_utest->num_args * sizeof(uint32_t))); 11100 unit_test_cmd_args = (uint32_t *) (buf_ptr + WMI_TLV_HDR_SIZE); 11101 wmi_debug("VDEV ID: %d MODULE ID: %d TOKEN: %d", 11102 cmd->vdev_id, cmd->module_id, cmd->diag_token); 11103 wmi_debug("%d num of args = ", wmi_utest->num_args); 11104 for (i = 0; (i < wmi_utest->num_args && i < WMI_UNIT_TEST_MAX_NUM_ARGS); i++) { 11105 unit_test_cmd_args[i] = wmi_utest->args[i]; 11106 wmi_debug("%d,", wmi_utest->args[i]); 11107 } 11108 wmi_mtrace(WMI_UNIT_TEST_CMDID, cmd->vdev_id, 0); 11109 if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len, 11110 WMI_UNIT_TEST_CMDID)) { 11111 wmi_err("Failed to send unit test command"); 11112 wmi_buf_free(wmi_buf); 11113 return QDF_STATUS_E_FAILURE; 11114 } 11115 11116 return QDF_STATUS_SUCCESS; 11117 } 11118 11119 /** 11120 * send_power_dbg_cmd_tlv() - send power debug commands 11121 * @wmi_handle: wmi handle 11122 * @param: wmi power debug parameter 11123 * 11124 * Send WMI_POWER_DEBUG_CMDID parameters to fw. 11125 * 11126 * Return: QDF_STATUS_SUCCESS on success, QDF_STATUS_E_** on error 11127 */ 11128 static QDF_STATUS send_power_dbg_cmd_tlv(wmi_unified_t wmi_handle, 11129 struct wmi_power_dbg_params *param) 11130 { 11131 wmi_buf_t buf = NULL; 11132 QDF_STATUS status; 11133 int len, args_tlv_len; 11134 uint8_t *buf_ptr; 11135 uint8_t i; 11136 wmi_pdev_wal_power_debug_cmd_fixed_param *cmd; 11137 uint32_t *cmd_args; 11138 11139 /* Prepare and send power debug cmd parameters */ 11140 args_tlv_len = WMI_TLV_HDR_SIZE + param->num_args * sizeof(uint32_t); 11141 len = sizeof(*cmd) + args_tlv_len; 11142 buf = wmi_buf_alloc(wmi_handle, len); 11143 if (!buf) 11144 return QDF_STATUS_E_NOMEM; 11145 11146 buf_ptr = (uint8_t *) wmi_buf_data(buf); 11147 cmd = (wmi_pdev_wal_power_debug_cmd_fixed_param *) buf_ptr; 11148 WMITLV_SET_HDR(&cmd->tlv_header, 11149 WMITLV_TAG_STRUC_wmi_pdev_wal_power_debug_cmd_fixed_param, 11150 WMITLV_GET_STRUCT_TLVLEN 11151 (wmi_pdev_wal_power_debug_cmd_fixed_param)); 11152 11153 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 11154 wmi_handle, 11155 param->pdev_id); 11156 cmd->module_id = param->module_id; 11157 cmd->num_args = param->num_args; 11158 buf_ptr += sizeof(*cmd); 11159 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, 11160 (param->num_args * sizeof(uint32_t))); 11161 cmd_args = (uint32_t *) (buf_ptr + WMI_TLV_HDR_SIZE); 11162 wmi_debug("%d num of args = ", param->num_args); 11163 for (i = 0; (i < param->num_args && i < WMI_MAX_POWER_DBG_ARGS); i++) { 11164 cmd_args[i] = param->args[i]; 11165 wmi_debug("%d,", param->args[i]); 11166 } 11167 11168 wmi_mtrace(WMI_PDEV_WAL_POWER_DEBUG_CMDID, NO_SESSION, 0); 11169 status = wmi_unified_cmd_send(wmi_handle, buf, 11170 len, WMI_PDEV_WAL_POWER_DEBUG_CMDID); 11171 if (QDF_IS_STATUS_ERROR(status)) { 11172 wmi_err("wmi_unified_cmd_send WMI_PDEV_WAL_POWER_DEBUG_CMDID returned Error %d", 11173 status); 11174 goto error; 11175 } 11176 11177 return QDF_STATUS_SUCCESS; 11178 error: 11179 wmi_buf_free(buf); 11180 11181 return status; 11182 } 11183 11184 /** 11185 * send_dfs_phyerr_offload_en_cmd_tlv() - send dfs phyerr offload enable cmd 11186 * @wmi_handle: wmi handle 11187 * @pdev_id: pdev id 11188 * 11189 * Send WMI_PDEV_DFS_PHYERR_OFFLOAD_ENABLE_CMDID command to firmware. 11190 * 11191 * Return: QDF_STATUS_SUCCESS on success, QDF_STATUS_E_** on error 11192 */ 11193 static QDF_STATUS send_dfs_phyerr_offload_en_cmd_tlv(wmi_unified_t wmi_handle, 11194 uint32_t pdev_id) 11195 { 11196 wmi_pdev_dfs_phyerr_offload_enable_cmd_fixed_param *cmd; 11197 wmi_buf_t buf; 11198 uint16_t len; 11199 QDF_STATUS ret; 11200 11201 len = sizeof(*cmd); 11202 buf = wmi_buf_alloc(wmi_handle, len); 11203 11204 wmi_debug("pdev_id=%d", pdev_id); 11205 11206 if (!buf) 11207 return QDF_STATUS_E_NOMEM; 11208 11209 cmd = (wmi_pdev_dfs_phyerr_offload_enable_cmd_fixed_param *) 11210 wmi_buf_data(buf); 11211 11212 WMITLV_SET_HDR(&cmd->tlv_header, 11213 WMITLV_TAG_STRUC_wmi_pdev_dfs_phyerr_offload_enable_cmd_fixed_param, 11214 WMITLV_GET_STRUCT_TLVLEN( 11215 wmi_pdev_dfs_phyerr_offload_enable_cmd_fixed_param)); 11216 11217 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 11218 wmi_handle, 11219 pdev_id); 11220 wmi_mtrace(WMI_PDEV_DFS_PHYERR_OFFLOAD_ENABLE_CMDID, NO_SESSION, 0); 11221 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 11222 WMI_PDEV_DFS_PHYERR_OFFLOAD_ENABLE_CMDID); 11223 if (QDF_IS_STATUS_ERROR(ret)) { 11224 wmi_err("Failed to send cmd to fw, ret=%d, pdev_id=%d", 11225 ret, pdev_id); 11226 wmi_buf_free(buf); 11227 return QDF_STATUS_E_FAILURE; 11228 } 11229 11230 return QDF_STATUS_SUCCESS; 11231 } 11232 11233 /** 11234 * send_dfs_phyerr_offload_dis_cmd_tlv() - send dfs phyerr offload disable cmd 11235 * @wmi_handle: wmi handle 11236 * @pdev_id: pdev id 11237 * 11238 * Send WMI_PDEV_DFS_PHYERR_OFFLOAD_DISABLE_CMDID command to firmware. 11239 * 11240 * Return: QDF_STATUS_SUCCESS on success, QDF_STATUS_E_** on error 11241 */ 11242 static QDF_STATUS send_dfs_phyerr_offload_dis_cmd_tlv(wmi_unified_t wmi_handle, 11243 uint32_t pdev_id) 11244 { 11245 wmi_pdev_dfs_phyerr_offload_disable_cmd_fixed_param *cmd; 11246 wmi_buf_t buf; 11247 uint16_t len; 11248 QDF_STATUS ret; 11249 11250 len = sizeof(*cmd); 11251 buf = wmi_buf_alloc(wmi_handle, len); 11252 11253 wmi_debug("pdev_id=%d", pdev_id); 11254 11255 if (!buf) 11256 return QDF_STATUS_E_NOMEM; 11257 11258 cmd = (wmi_pdev_dfs_phyerr_offload_disable_cmd_fixed_param *) 11259 wmi_buf_data(buf); 11260 11261 WMITLV_SET_HDR(&cmd->tlv_header, 11262 WMITLV_TAG_STRUC_wmi_pdev_dfs_phyerr_offload_disable_cmd_fixed_param, 11263 WMITLV_GET_STRUCT_TLVLEN( 11264 wmi_pdev_dfs_phyerr_offload_disable_cmd_fixed_param)); 11265 11266 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 11267 wmi_handle, 11268 pdev_id); 11269 wmi_mtrace(WMI_PDEV_DFS_PHYERR_OFFLOAD_DISABLE_CMDID, NO_SESSION, 0); 11270 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 11271 WMI_PDEV_DFS_PHYERR_OFFLOAD_DISABLE_CMDID); 11272 if (QDF_IS_STATUS_ERROR(ret)) { 11273 wmi_err("Failed to send cmd to fw, ret=%d, pdev_id=%d", 11274 ret, pdev_id); 11275 wmi_buf_free(buf); 11276 return QDF_STATUS_E_FAILURE; 11277 } 11278 11279 return QDF_STATUS_SUCCESS; 11280 } 11281 11282 #ifdef QCA_SUPPORT_AGILE_DFS 11283 static 11284 QDF_STATUS send_adfs_ch_cfg_cmd_tlv(wmi_unified_t wmi_handle, 11285 struct vdev_adfs_ch_cfg_params *param) 11286 { 11287 /* wmi_unified_cmd_send set request of agile ADFS channel*/ 11288 wmi_vdev_adfs_ch_cfg_cmd_fixed_param *cmd; 11289 wmi_buf_t buf; 11290 QDF_STATUS ret; 11291 uint16_t len; 11292 11293 len = sizeof(*cmd); 11294 buf = wmi_buf_alloc(wmi_handle, len); 11295 11296 if (!buf) { 11297 wmi_err("wmi_buf_alloc failed"); 11298 return QDF_STATUS_E_NOMEM; 11299 } 11300 11301 cmd = (wmi_vdev_adfs_ch_cfg_cmd_fixed_param *) 11302 wmi_buf_data(buf); 11303 11304 WMITLV_SET_HDR(&cmd->tlv_header, 11305 WMITLV_TAG_STRUC_wmi_vdev_adfs_ch_cfg_cmd_fixed_param, 11306 WMITLV_GET_STRUCT_TLVLEN 11307 (wmi_vdev_adfs_ch_cfg_cmd_fixed_param)); 11308 11309 cmd->vdev_id = param->vdev_id; 11310 cmd->ocac_mode = param->ocac_mode; 11311 cmd->center_freq1 = param->center_freq1; 11312 cmd->center_freq2 = param->center_freq2; 11313 cmd->chan_freq = param->chan_freq; 11314 cmd->chan_width = param->chan_width; 11315 cmd->min_duration_ms = param->min_duration_ms; 11316 cmd->max_duration_ms = param->max_duration_ms; 11317 wmi_debug("cmd->vdev_id: %d ,cmd->ocac_mode: %d cmd->center_freq: %d", 11318 cmd->vdev_id, cmd->ocac_mode, 11319 cmd->center_freq); 11320 11321 wmi_mtrace(WMI_VDEV_ADFS_CH_CFG_CMDID, NO_SESSION, 0); 11322 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 11323 WMI_VDEV_ADFS_CH_CFG_CMDID); 11324 11325 if (QDF_IS_STATUS_ERROR(ret)) { 11326 wmi_err("Failed to send cmd to fw, ret=%d", ret); 11327 wmi_buf_free(buf); 11328 return QDF_STATUS_E_FAILURE; 11329 } 11330 11331 return QDF_STATUS_SUCCESS; 11332 } 11333 11334 static 11335 QDF_STATUS send_adfs_ocac_abort_cmd_tlv(wmi_unified_t wmi_handle, 11336 struct vdev_adfs_abort_params *param) 11337 { 11338 /*wmi_unified_cmd_send with ocac abort on ADFS channel*/ 11339 wmi_vdev_adfs_ocac_abort_cmd_fixed_param *cmd; 11340 wmi_buf_t buf; 11341 QDF_STATUS ret; 11342 uint16_t len; 11343 11344 len = sizeof(*cmd); 11345 buf = wmi_buf_alloc(wmi_handle, len); 11346 11347 if (!buf) { 11348 wmi_err("wmi_buf_alloc failed"); 11349 return QDF_STATUS_E_NOMEM; 11350 } 11351 11352 cmd = (wmi_vdev_adfs_ocac_abort_cmd_fixed_param *) 11353 wmi_buf_data(buf); 11354 11355 WMITLV_SET_HDR 11356 (&cmd->tlv_header, 11357 WMITLV_TAG_STRUC_wmi_vdev_adfs_ocac_abort_cmd_fixed_param, 11358 WMITLV_GET_STRUCT_TLVLEN 11359 (wmi_vdev_adfs_ocac_abort_cmd_fixed_param)); 11360 11361 cmd->vdev_id = param->vdev_id; 11362 11363 wmi_mtrace(WMI_VDEV_ADFS_OCAC_ABORT_CMDID, NO_SESSION, 0); 11364 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 11365 WMI_VDEV_ADFS_OCAC_ABORT_CMDID); 11366 11367 if (QDF_IS_STATUS_ERROR(ret)) { 11368 wmi_err("Failed to send cmd to fw, ret=%d", ret); 11369 wmi_buf_free(buf); 11370 return QDF_STATUS_E_FAILURE; 11371 } 11372 11373 return QDF_STATUS_SUCCESS; 11374 } 11375 #endif 11376 11377 /** 11378 * init_cmd_send_tlv() - send initialization cmd to fw 11379 * @wmi_handle: wmi handle 11380 * @param: pointer to wmi init param 11381 * 11382 * Return: QDF_STATUS_SUCCESS for success or error code 11383 */ 11384 static QDF_STATUS init_cmd_send_tlv(wmi_unified_t wmi_handle, 11385 struct wmi_init_cmd_param *param) 11386 { 11387 wmi_buf_t buf; 11388 wmi_init_cmd_fixed_param *cmd; 11389 uint8_t *buf_ptr; 11390 wmi_resource_config *resource_cfg; 11391 wlan_host_memory_chunk *host_mem_chunks; 11392 uint32_t mem_chunk_len = 0, hw_mode_len = 0; 11393 uint16_t idx; 11394 int len; 11395 QDF_STATUS ret; 11396 11397 len = sizeof(*cmd) + sizeof(wmi_resource_config) + 11398 WMI_TLV_HDR_SIZE; 11399 mem_chunk_len = (sizeof(wlan_host_memory_chunk) * MAX_MEM_CHUNKS); 11400 11401 if (param->hw_mode_id != WMI_HOST_HW_MODE_MAX) 11402 hw_mode_len = sizeof(wmi_pdev_set_hw_mode_cmd_fixed_param) + 11403 WMI_TLV_HDR_SIZE + 11404 (param->num_band_to_mac * sizeof(wmi_pdev_band_to_mac)); 11405 11406 buf = wmi_buf_alloc(wmi_handle, len + mem_chunk_len + hw_mode_len); 11407 if (!buf) 11408 return QDF_STATUS_E_FAILURE; 11409 11410 buf_ptr = (uint8_t *) wmi_buf_data(buf); 11411 cmd = (wmi_init_cmd_fixed_param *) buf_ptr; 11412 resource_cfg = (wmi_resource_config *) (buf_ptr + sizeof(*cmd)); 11413 11414 host_mem_chunks = (wlan_host_memory_chunk *) 11415 (buf_ptr + sizeof(*cmd) + sizeof(wmi_resource_config) 11416 + WMI_TLV_HDR_SIZE); 11417 11418 WMITLV_SET_HDR(&cmd->tlv_header, 11419 WMITLV_TAG_STRUC_wmi_init_cmd_fixed_param, 11420 WMITLV_GET_STRUCT_TLVLEN(wmi_init_cmd_fixed_param)); 11421 wmi_copy_resource_config(resource_cfg, param->res_cfg); 11422 WMITLV_SET_HDR(&resource_cfg->tlv_header, 11423 WMITLV_TAG_STRUC_wmi_resource_config, 11424 WMITLV_GET_STRUCT_TLVLEN(wmi_resource_config)); 11425 11426 for (idx = 0; idx < param->num_mem_chunks; ++idx) { 11427 WMITLV_SET_HDR(&(host_mem_chunks[idx].tlv_header), 11428 WMITLV_TAG_STRUC_wlan_host_memory_chunk, 11429 WMITLV_GET_STRUCT_TLVLEN 11430 (wlan_host_memory_chunk)); 11431 host_mem_chunks[idx].ptr = param->mem_chunks[idx].paddr; 11432 host_mem_chunks[idx].size = param->mem_chunks[idx].len; 11433 host_mem_chunks[idx].req_id = param->mem_chunks[idx].req_id; 11434 if (is_service_enabled_tlv(wmi_handle, 11435 WMI_SERVICE_SUPPORT_EXTEND_ADDRESS)) 11436 host_mem_chunks[idx].ptr_high = 11437 qdf_get_upper_32_bits( 11438 param->mem_chunks[idx].paddr); 11439 QDF_TRACE(QDF_MODULE_ID_ANY, QDF_TRACE_LEVEL_DEBUG, 11440 "chunk %d len %d requested ,ptr 0x%x ", 11441 idx, host_mem_chunks[idx].size, 11442 host_mem_chunks[idx].ptr); 11443 } 11444 cmd->num_host_mem_chunks = param->num_mem_chunks; 11445 len += (param->num_mem_chunks * sizeof(wlan_host_memory_chunk)); 11446 11447 WMITLV_SET_HDR((buf_ptr + sizeof(*cmd) + sizeof(wmi_resource_config)), 11448 WMITLV_TAG_ARRAY_STRUC, 11449 (sizeof(wlan_host_memory_chunk) * 11450 param->num_mem_chunks)); 11451 11452 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", 11453 resource_cfg->num_peers, resource_cfg->num_offload_peers, 11454 resource_cfg->num_vdevs, resource_cfg->num_tids, 11455 resource_cfg->num_tdls_conn_table_entries, 11456 resource_cfg->num_tdls_vdevs); 11457 11458 /* Fill hw mode id config */ 11459 buf_ptr = copy_hw_mode_in_init_cmd(wmi_handle, buf_ptr, &len, param); 11460 11461 /* Fill fw_abi_vers */ 11462 copy_fw_abi_version_tlv(wmi_handle, cmd); 11463 11464 wmi_mtrace(WMI_INIT_CMDID, NO_SESSION, 0); 11465 ret = wmi_unified_cmd_send(wmi_handle, buf, len, WMI_INIT_CMDID); 11466 if (QDF_IS_STATUS_ERROR(ret)) { 11467 wmi_err("wmi_unified_cmd_send WMI_INIT_CMDID returned Error %d", 11468 ret); 11469 wmi_buf_free(buf); 11470 } 11471 11472 return ret; 11473 11474 } 11475 11476 /** 11477 * send_addba_send_cmd_tlv() - send addba send command to fw 11478 * @wmi_handle: wmi handle 11479 * @param: pointer to delba send params 11480 * @macaddr: peer mac address 11481 * 11482 * Send WMI_ADDBA_SEND_CMDID command to firmware 11483 * Return: QDF_STATUS_SUCCESS on success. QDF_STATUS_E** on error 11484 */ 11485 static QDF_STATUS 11486 send_addba_send_cmd_tlv(wmi_unified_t wmi_handle, 11487 uint8_t macaddr[QDF_MAC_ADDR_SIZE], 11488 struct addba_send_params *param) 11489 { 11490 wmi_addba_send_cmd_fixed_param *cmd; 11491 wmi_buf_t buf; 11492 uint16_t len; 11493 QDF_STATUS ret; 11494 11495 len = sizeof(*cmd); 11496 11497 buf = wmi_buf_alloc(wmi_handle, len); 11498 if (!buf) 11499 return QDF_STATUS_E_NOMEM; 11500 11501 cmd = (wmi_addba_send_cmd_fixed_param *)wmi_buf_data(buf); 11502 11503 WMITLV_SET_HDR(&cmd->tlv_header, 11504 WMITLV_TAG_STRUC_wmi_addba_send_cmd_fixed_param, 11505 WMITLV_GET_STRUCT_TLVLEN(wmi_addba_send_cmd_fixed_param)); 11506 11507 cmd->vdev_id = param->vdev_id; 11508 WMI_CHAR_ARRAY_TO_MAC_ADDR(macaddr, &cmd->peer_macaddr); 11509 cmd->tid = param->tidno; 11510 cmd->buffersize = param->buffersize; 11511 11512 wmi_mtrace(WMI_ADDBA_SEND_CMDID, cmd->vdev_id, 0); 11513 ret = wmi_unified_cmd_send(wmi_handle, buf, len, WMI_ADDBA_SEND_CMDID); 11514 if (QDF_IS_STATUS_ERROR(ret)) { 11515 wmi_err("Failed to send cmd to fw, ret=%d", ret); 11516 wmi_buf_free(buf); 11517 return QDF_STATUS_E_FAILURE; 11518 } 11519 11520 return QDF_STATUS_SUCCESS; 11521 } 11522 11523 /** 11524 * send_delba_send_cmd_tlv() - send delba send command to fw 11525 * @wmi_handle: wmi handle 11526 * @param: pointer to delba send params 11527 * @macaddr: peer mac address 11528 * 11529 * Send WMI_DELBA_SEND_CMDID command to firmware 11530 * Return: QDF_STATUS_SUCCESS on success. QDF_STATUS_E** on error 11531 */ 11532 static QDF_STATUS 11533 send_delba_send_cmd_tlv(wmi_unified_t wmi_handle, 11534 uint8_t macaddr[QDF_MAC_ADDR_SIZE], 11535 struct delba_send_params *param) 11536 { 11537 wmi_delba_send_cmd_fixed_param *cmd; 11538 wmi_buf_t buf; 11539 uint16_t len; 11540 QDF_STATUS ret; 11541 11542 len = sizeof(*cmd); 11543 11544 buf = wmi_buf_alloc(wmi_handle, len); 11545 if (!buf) 11546 return QDF_STATUS_E_NOMEM; 11547 11548 cmd = (wmi_delba_send_cmd_fixed_param *)wmi_buf_data(buf); 11549 11550 WMITLV_SET_HDR(&cmd->tlv_header, 11551 WMITLV_TAG_STRUC_wmi_delba_send_cmd_fixed_param, 11552 WMITLV_GET_STRUCT_TLVLEN(wmi_delba_send_cmd_fixed_param)); 11553 11554 cmd->vdev_id = param->vdev_id; 11555 WMI_CHAR_ARRAY_TO_MAC_ADDR(macaddr, &cmd->peer_macaddr); 11556 cmd->tid = param->tidno; 11557 cmd->initiator = param->initiator; 11558 cmd->reasoncode = param->reasoncode; 11559 11560 wmi_mtrace(WMI_DELBA_SEND_CMDID, cmd->vdev_id, 0); 11561 ret = wmi_unified_cmd_send(wmi_handle, buf, len, WMI_DELBA_SEND_CMDID); 11562 if (QDF_IS_STATUS_ERROR(ret)) { 11563 wmi_err("Failed to send cmd to fw, ret=%d", ret); 11564 wmi_buf_free(buf); 11565 return QDF_STATUS_E_FAILURE; 11566 } 11567 11568 return QDF_STATUS_SUCCESS; 11569 } 11570 11571 /** 11572 * send_addba_clearresponse_cmd_tlv() - send addba clear response command 11573 * to fw 11574 * @wmi_handle: wmi handle 11575 * @param: pointer to addba clearresp params 11576 * @macaddr: peer mac address 11577 * Return: QDF_STATUS_SUCCESS for success or error code 11578 */ 11579 static QDF_STATUS 11580 send_addba_clearresponse_cmd_tlv(wmi_unified_t wmi_handle, 11581 uint8_t macaddr[QDF_MAC_ADDR_SIZE], 11582 struct addba_clearresponse_params *param) 11583 { 11584 wmi_addba_clear_resp_cmd_fixed_param *cmd; 11585 wmi_buf_t buf; 11586 uint16_t len; 11587 QDF_STATUS ret; 11588 11589 len = sizeof(*cmd); 11590 11591 buf = wmi_buf_alloc(wmi_handle, len); 11592 if (!buf) 11593 return QDF_STATUS_E_FAILURE; 11594 11595 cmd = (wmi_addba_clear_resp_cmd_fixed_param *)wmi_buf_data(buf); 11596 11597 WMITLV_SET_HDR(&cmd->tlv_header, 11598 WMITLV_TAG_STRUC_wmi_addba_clear_resp_cmd_fixed_param, 11599 WMITLV_GET_STRUCT_TLVLEN(wmi_addba_clear_resp_cmd_fixed_param)); 11600 11601 cmd->vdev_id = param->vdev_id; 11602 WMI_CHAR_ARRAY_TO_MAC_ADDR(macaddr, &cmd->peer_macaddr); 11603 11604 wmi_mtrace(WMI_ADDBA_CLEAR_RESP_CMDID, cmd->vdev_id, 0); 11605 ret = wmi_unified_cmd_send(wmi_handle, 11606 buf, len, WMI_ADDBA_CLEAR_RESP_CMDID); 11607 if (QDF_IS_STATUS_ERROR(ret)) { 11608 wmi_err("Failed to send cmd to fw, ret=%d", ret); 11609 wmi_buf_free(buf); 11610 return QDF_STATUS_E_FAILURE; 11611 } 11612 11613 return QDF_STATUS_SUCCESS; 11614 } 11615 11616 #ifdef OBSS_PD 11617 /** 11618 * send_obss_spatial_reuse_set_def_thresh_cmd_tlv - send obss spatial reuse set 11619 * def thresh to fw 11620 * @wmi_handle: wmi handle 11621 * @thresh: pointer to obss_spatial_reuse_def_thresh 11622 * 11623 * Return: QDF_STATUS_SUCCESS for success or error code 11624 */ 11625 static 11626 QDF_STATUS send_obss_spatial_reuse_set_def_thresh_cmd_tlv( 11627 wmi_unified_t wmi_handle, 11628 struct wmi_host_obss_spatial_reuse_set_def_thresh 11629 *thresh) 11630 { 11631 wmi_buf_t buf; 11632 wmi_obss_spatial_reuse_set_def_obss_thresh_cmd_fixed_param *cmd; 11633 QDF_STATUS ret; 11634 uint32_t cmd_len; 11635 uint32_t tlv_len; 11636 11637 cmd_len = sizeof(*cmd); 11638 11639 buf = wmi_buf_alloc(wmi_handle, cmd_len); 11640 if (!buf) 11641 return QDF_STATUS_E_NOMEM; 11642 11643 cmd = (wmi_obss_spatial_reuse_set_def_obss_thresh_cmd_fixed_param *) 11644 wmi_buf_data(buf); 11645 11646 tlv_len = WMITLV_GET_STRUCT_TLVLEN( 11647 wmi_obss_spatial_reuse_set_def_obss_thresh_cmd_fixed_param); 11648 11649 WMITLV_SET_HDR(&cmd->tlv_header, 11650 WMITLV_TAG_STRUC_wmi_obss_spatial_reuse_set_def_obss_thresh_cmd_fixed_param, 11651 tlv_len); 11652 11653 cmd->obss_min = thresh->obss_min; 11654 cmd->obss_max = thresh->obss_max; 11655 cmd->vdev_type = thresh->vdev_type; 11656 ret = wmi_unified_cmd_send(wmi_handle, buf, cmd_len, 11657 WMI_PDEV_OBSS_PD_SPATIAL_REUSE_SET_DEF_OBSS_THRESH_CMDID); 11658 if (QDF_IS_STATUS_ERROR(ret)) 11659 wmi_buf_free(buf); 11660 11661 return ret; 11662 } 11663 11664 /** 11665 * send_obss_spatial_reuse_set_cmd_tlv - send obss spatial reuse set cmd to fw 11666 * @wmi_handle: wmi handle 11667 * @obss_spatial_reuse_param: pointer to obss_spatial_reuse_param 11668 * 11669 * Return: QDF_STATUS_SUCCESS for success or error code 11670 */ 11671 static 11672 QDF_STATUS send_obss_spatial_reuse_set_cmd_tlv(wmi_unified_t wmi_handle, 11673 struct wmi_host_obss_spatial_reuse_set_param 11674 *obss_spatial_reuse_param) 11675 { 11676 wmi_buf_t buf; 11677 wmi_obss_spatial_reuse_set_cmd_fixed_param *cmd; 11678 QDF_STATUS ret; 11679 uint32_t len; 11680 11681 len = sizeof(*cmd); 11682 11683 buf = wmi_buf_alloc(wmi_handle, len); 11684 if (!buf) 11685 return QDF_STATUS_E_FAILURE; 11686 11687 cmd = (wmi_obss_spatial_reuse_set_cmd_fixed_param *)wmi_buf_data(buf); 11688 WMITLV_SET_HDR(&cmd->tlv_header, 11689 WMITLV_TAG_STRUC_wmi_obss_spatial_reuse_set_cmd_fixed_param, 11690 WMITLV_GET_STRUCT_TLVLEN 11691 (wmi_obss_spatial_reuse_set_cmd_fixed_param)); 11692 11693 cmd->enable = obss_spatial_reuse_param->enable; 11694 cmd->obss_min = obss_spatial_reuse_param->obss_min; 11695 cmd->obss_max = obss_spatial_reuse_param->obss_max; 11696 cmd->vdev_id = obss_spatial_reuse_param->vdev_id; 11697 11698 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 11699 WMI_PDEV_OBSS_PD_SPATIAL_REUSE_CMDID); 11700 11701 if (QDF_IS_STATUS_ERROR(ret)) { 11702 wmi_err( 11703 "WMI_PDEV_OBSS_PD_SPATIAL_REUSE_CMDID send returned Error %d", 11704 ret); 11705 wmi_buf_free(buf); 11706 } 11707 11708 return ret; 11709 } 11710 11711 /** 11712 * send_self_srg_bss_color_bitmap_set_cmd_tlv() - Send 64-bit BSS color bitmap 11713 * to be used by SRG based Spatial Reuse feature to the FW 11714 * @wmi_handle: wmi handle 11715 * @bitmap_0: lower 32 bits in BSS color bitmap 11716 * @bitmap_1: upper 32 bits in BSS color bitmap 11717 * @pdev_id: pdev ID 11718 * 11719 * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure 11720 */ 11721 static QDF_STATUS 11722 send_self_srg_bss_color_bitmap_set_cmd_tlv( 11723 wmi_unified_t wmi_handle, uint32_t bitmap_0, 11724 uint32_t bitmap_1, uint8_t pdev_id) 11725 { 11726 wmi_buf_t buf; 11727 wmi_pdev_srg_bss_color_bitmap_cmd_fixed_param *cmd; 11728 QDF_STATUS ret; 11729 uint32_t len; 11730 11731 len = sizeof(*cmd); 11732 11733 buf = wmi_buf_alloc(wmi_handle, len); 11734 if (!buf) 11735 return QDF_STATUS_E_FAILURE; 11736 11737 cmd = (wmi_pdev_srg_bss_color_bitmap_cmd_fixed_param *) 11738 wmi_buf_data(buf); 11739 11740 WMITLV_SET_HDR( 11741 &cmd->tlv_header, 11742 WMITLV_TAG_STRUC_wmi_pdev_srg_bss_color_bitmap_cmd_fixed_param, 11743 WMITLV_GET_STRUCT_TLVLEN 11744 (wmi_pdev_srg_bss_color_bitmap_cmd_fixed_param)); 11745 11746 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 11747 wmi_handle, pdev_id); 11748 cmd->srg_bss_color_bitmap[0] = bitmap_0; 11749 cmd->srg_bss_color_bitmap[1] = bitmap_1; 11750 11751 ret = wmi_unified_cmd_send( 11752 wmi_handle, buf, len, 11753 WMI_PDEV_SET_SRG_BSS_COLOR_BITMAP_CMDID); 11754 11755 if (QDF_IS_STATUS_ERROR(ret)) { 11756 wmi_err( 11757 "WMI_PDEV_SET_SRG_BSS_COLOR_BITMAP_CMDID send returned Error %d", 11758 ret); 11759 wmi_buf_free(buf); 11760 } 11761 11762 return ret; 11763 } 11764 11765 /** 11766 * send_self_srg_partial_bssid_bitmap_set_cmd_tlv() - Send 64-bit partial BSSID 11767 * bitmap to be used by SRG based Spatial Reuse feature to the FW 11768 * @wmi_handle: wmi handle 11769 * @bitmap_0: lower 32 bits in partial BSSID bitmap 11770 * @bitmap_1: upper 32 bits in partial BSSID bitmap 11771 * @pdev_id: pdev ID 11772 * 11773 * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure 11774 */ 11775 static QDF_STATUS 11776 send_self_srg_partial_bssid_bitmap_set_cmd_tlv( 11777 wmi_unified_t wmi_handle, uint32_t bitmap_0, 11778 uint32_t bitmap_1, uint8_t pdev_id) 11779 { 11780 wmi_buf_t buf; 11781 wmi_pdev_srg_partial_bssid_bitmap_cmd_fixed_param *cmd; 11782 QDF_STATUS ret; 11783 uint32_t len; 11784 11785 len = sizeof(*cmd); 11786 11787 buf = wmi_buf_alloc(wmi_handle, len); 11788 if (!buf) 11789 return QDF_STATUS_E_FAILURE; 11790 11791 cmd = (wmi_pdev_srg_partial_bssid_bitmap_cmd_fixed_param *) 11792 wmi_buf_data(buf); 11793 11794 WMITLV_SET_HDR( 11795 &cmd->tlv_header, 11796 WMITLV_TAG_STRUC_wmi_pdev_srg_partial_bssid_bitmap_cmd_fixed_param, 11797 WMITLV_GET_STRUCT_TLVLEN 11798 (wmi_pdev_srg_partial_bssid_bitmap_cmd_fixed_param)); 11799 11800 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 11801 wmi_handle, pdev_id); 11802 11803 cmd->srg_partial_bssid_bitmap[0] = bitmap_0; 11804 cmd->srg_partial_bssid_bitmap[1] = bitmap_1; 11805 11806 ret = wmi_unified_cmd_send( 11807 wmi_handle, buf, len, 11808 WMI_PDEV_SET_SRG_PARTIAL_BSSID_BITMAP_CMDID); 11809 11810 if (QDF_IS_STATUS_ERROR(ret)) { 11811 wmi_err( 11812 "WMI_PDEV_SET_SRG_PARTIAL_BSSID_BITMAP_CMDID send returned Error %d", 11813 ret); 11814 wmi_buf_free(buf); 11815 } 11816 11817 return ret; 11818 } 11819 11820 /** 11821 * send_self_srg_obss_color_enable_bitmap_cmd_tlv() - Send 64-bit BSS color 11822 * enable bitmap to be used by SRG based Spatial Reuse feature to the FW 11823 * @wmi_handle: wmi handle 11824 * @bitmap_0: lower 32 bits in BSS color enable bitmap 11825 * @bitmap_1: upper 32 bits in BSS color enable bitmap 11826 * @pdev_id: pdev ID 11827 * 11828 * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure 11829 */ 11830 static QDF_STATUS 11831 send_self_srg_obss_color_enable_bitmap_cmd_tlv( 11832 wmi_unified_t wmi_handle, uint32_t bitmap_0, 11833 uint32_t bitmap_1, uint8_t pdev_id) 11834 { 11835 wmi_buf_t buf; 11836 wmi_pdev_srg_obss_color_enable_bitmap_cmd_fixed_param *cmd; 11837 QDF_STATUS ret; 11838 uint32_t len; 11839 11840 len = sizeof(*cmd); 11841 11842 buf = wmi_buf_alloc(wmi_handle, len); 11843 if (!buf) 11844 return QDF_STATUS_E_FAILURE; 11845 11846 cmd = (wmi_pdev_srg_obss_color_enable_bitmap_cmd_fixed_param *) 11847 wmi_buf_data(buf); 11848 11849 WMITLV_SET_HDR( 11850 &cmd->tlv_header, 11851 WMITLV_TAG_STRUC_wmi_pdev_srg_obss_color_enable_bitmap_cmd_fixed_param, 11852 WMITLV_GET_STRUCT_TLVLEN 11853 (wmi_pdev_srg_obss_color_enable_bitmap_cmd_fixed_param)); 11854 11855 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 11856 wmi_handle, pdev_id); 11857 cmd->srg_obss_en_color_bitmap[0] = bitmap_0; 11858 cmd->srg_obss_en_color_bitmap[1] = bitmap_1; 11859 11860 ret = wmi_unified_cmd_send( 11861 wmi_handle, buf, len, 11862 WMI_PDEV_SET_SRG_OBSS_COLOR_ENABLE_BITMAP_CMDID); 11863 11864 if (QDF_IS_STATUS_ERROR(ret)) { 11865 wmi_err( 11866 "WMI_PDEV_SET_SRG_OBSS_COLOR_ENABLE_BITMAP_CMDID send returned Error %d", 11867 ret); 11868 wmi_buf_free(buf); 11869 } 11870 11871 return ret; 11872 } 11873 11874 /** 11875 * send_self_srg_obss_bssid_enable_bitmap_cmd_tlv() - Send 64-bit OBSS BSSID 11876 * enable bitmap to be used by SRG based Spatial Reuse feature to the FW 11877 * @wmi_handle: wmi handle 11878 * @bitmap_0: lower 32 bits in BSSID enable bitmap 11879 * @bitmap_1: upper 32 bits in BSSID enable bitmap 11880 * @pdev_id: pdev ID 11881 * 11882 * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure 11883 */ 11884 static QDF_STATUS 11885 send_self_srg_obss_bssid_enable_bitmap_cmd_tlv( 11886 wmi_unified_t wmi_handle, uint32_t bitmap_0, 11887 uint32_t bitmap_1, uint8_t pdev_id) 11888 { 11889 wmi_buf_t buf; 11890 wmi_pdev_srg_obss_bssid_enable_bitmap_cmd_fixed_param *cmd; 11891 QDF_STATUS ret; 11892 uint32_t len; 11893 11894 len = sizeof(*cmd); 11895 11896 buf = wmi_buf_alloc(wmi_handle, len); 11897 if (!buf) 11898 return QDF_STATUS_E_FAILURE; 11899 11900 cmd = (wmi_pdev_srg_obss_bssid_enable_bitmap_cmd_fixed_param *) 11901 wmi_buf_data(buf); 11902 11903 WMITLV_SET_HDR( 11904 &cmd->tlv_header, 11905 WMITLV_TAG_STRUC_wmi_pdev_srg_obss_bssid_enable_bitmap_cmd_fixed_param, 11906 WMITLV_GET_STRUCT_TLVLEN 11907 (wmi_pdev_srg_obss_bssid_enable_bitmap_cmd_fixed_param)); 11908 11909 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 11910 wmi_handle, pdev_id); 11911 cmd->srg_obss_en_bssid_bitmap[0] = bitmap_0; 11912 cmd->srg_obss_en_bssid_bitmap[1] = bitmap_1; 11913 11914 ret = wmi_unified_cmd_send( 11915 wmi_handle, buf, len, 11916 WMI_PDEV_SET_SRG_OBSS_BSSID_ENABLE_BITMAP_CMDID); 11917 11918 if (QDF_IS_STATUS_ERROR(ret)) { 11919 wmi_err( 11920 "WMI_PDEV_SET_SRG_OBSS_BSSID_ENABLE_BITMAP_CMDID send returned Error %d", 11921 ret); 11922 wmi_buf_free(buf); 11923 } 11924 11925 return ret; 11926 } 11927 11928 /** 11929 * send_self_non_srg_obss_color_enable_bitmap_cmd_tlv() - Send 64-bit BSS color 11930 * enable bitmap to be used by Non-SRG based Spatial Reuse feature to the FW 11931 * @wmi_handle: wmi handle 11932 * @bitmap_0: lower 32 bits in BSS color enable bitmap 11933 * @bitmap_1: upper 32 bits in BSS color enable bitmap 11934 * @pdev_id: pdev ID 11935 * 11936 * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure 11937 */ 11938 static QDF_STATUS 11939 send_self_non_srg_obss_color_enable_bitmap_cmd_tlv( 11940 wmi_unified_t wmi_handle, uint32_t bitmap_0, 11941 uint32_t bitmap_1, uint8_t pdev_id) 11942 { 11943 wmi_buf_t buf; 11944 wmi_pdev_non_srg_obss_color_enable_bitmap_cmd_fixed_param *cmd; 11945 QDF_STATUS ret; 11946 uint32_t len; 11947 11948 len = sizeof(*cmd); 11949 11950 buf = wmi_buf_alloc(wmi_handle, len); 11951 if (!buf) 11952 return QDF_STATUS_E_FAILURE; 11953 11954 cmd = (wmi_pdev_non_srg_obss_color_enable_bitmap_cmd_fixed_param *) 11955 wmi_buf_data(buf); 11956 11957 WMITLV_SET_HDR( 11958 &cmd->tlv_header, 11959 WMITLV_TAG_STRUC_wmi_pdev_non_srg_obss_color_enable_bitmap_cmd_fixed_param, 11960 WMITLV_GET_STRUCT_TLVLEN 11961 (wmi_pdev_non_srg_obss_color_enable_bitmap_cmd_fixed_param)); 11962 11963 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 11964 wmi_handle, pdev_id); 11965 cmd->non_srg_obss_en_color_bitmap[0] = bitmap_0; 11966 cmd->non_srg_obss_en_color_bitmap[1] = bitmap_1; 11967 11968 ret = wmi_unified_cmd_send( 11969 wmi_handle, buf, len, 11970 WMI_PDEV_SET_NON_SRG_OBSS_COLOR_ENABLE_BITMAP_CMDID); 11971 11972 if (QDF_IS_STATUS_ERROR(ret)) { 11973 wmi_err( 11974 "WMI_PDEV_SET_NON_SRG_OBSS_COLOR_ENABLE_BITMAP_CMDID send returned Error %d", 11975 ret); 11976 wmi_buf_free(buf); 11977 } 11978 11979 return ret; 11980 } 11981 11982 /** 11983 * send_self_non_srg_obss_bssid_enable_bitmap_cmd_tlv() - Send 64-bit OBSS BSSID 11984 * enable bitmap to be used by Non-SRG based Spatial Reuse feature to the FW 11985 * @wmi_handle: wmi handle 11986 * @bitmap_0: lower 32 bits in BSSID enable bitmap 11987 * @bitmap_1: upper 32 bits in BSSID enable bitmap 11988 * @pdev_id: pdev ID 11989 * 11990 * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure 11991 */ 11992 static QDF_STATUS 11993 send_self_non_srg_obss_bssid_enable_bitmap_cmd_tlv( 11994 wmi_unified_t wmi_handle, uint32_t bitmap_0, 11995 uint32_t bitmap_1, uint8_t pdev_id) 11996 { 11997 wmi_buf_t buf; 11998 wmi_pdev_non_srg_obss_bssid_enable_bitmap_cmd_fixed_param *cmd; 11999 QDF_STATUS ret; 12000 uint32_t len; 12001 12002 len = sizeof(*cmd); 12003 12004 buf = wmi_buf_alloc(wmi_handle, len); 12005 if (!buf) 12006 return QDF_STATUS_E_FAILURE; 12007 12008 cmd = (wmi_pdev_non_srg_obss_bssid_enable_bitmap_cmd_fixed_param *) 12009 wmi_buf_data(buf); 12010 12011 WMITLV_SET_HDR( 12012 &cmd->tlv_header, 12013 WMITLV_TAG_STRUC_wmi_pdev_non_srg_obss_bssid_enable_bitmap_cmd_fixed_param, 12014 WMITLV_GET_STRUCT_TLVLEN 12015 (wmi_pdev_non_srg_obss_bssid_enable_bitmap_cmd_fixed_param)); 12016 12017 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 12018 wmi_handle, pdev_id); 12019 cmd->non_srg_obss_en_bssid_bitmap[0] = bitmap_0; 12020 cmd->non_srg_obss_en_bssid_bitmap[1] = bitmap_1; 12021 12022 ret = wmi_unified_cmd_send( 12023 wmi_handle, buf, len, 12024 WMI_PDEV_SET_NON_SRG_OBSS_BSSID_ENABLE_BITMAP_CMDID); 12025 12026 if (QDF_IS_STATUS_ERROR(ret)) { 12027 wmi_err( 12028 "WMI_PDEV_SET_NON_SRG_OBSS_BSSID_ENABLE_BITMAP_CMDID send returned Error %d", 12029 ret); 12030 wmi_buf_free(buf); 12031 } 12032 12033 return ret; 12034 } 12035 #endif 12036 12037 static 12038 QDF_STATUS send_injector_config_cmd_tlv(wmi_unified_t wmi_handle, 12039 struct wmi_host_injector_frame_params *inject_config_params) 12040 { 12041 wmi_buf_t buf; 12042 wmi_frame_inject_cmd_fixed_param *cmd; 12043 QDF_STATUS ret; 12044 uint32_t len; 12045 12046 len = sizeof(*cmd); 12047 12048 buf = wmi_buf_alloc(wmi_handle, len); 12049 if (!buf) 12050 return QDF_STATUS_E_NOMEM; 12051 12052 cmd = (wmi_frame_inject_cmd_fixed_param *)wmi_buf_data(buf); 12053 WMITLV_SET_HDR(&cmd->tlv_header, 12054 WMITLV_TAG_STRUC_wmi_frame_inject_cmd_fixed_param, 12055 WMITLV_GET_STRUCT_TLVLEN 12056 (wmi_frame_inject_cmd_fixed_param)); 12057 12058 cmd->vdev_id = inject_config_params->vdev_id; 12059 cmd->enable = inject_config_params->enable; 12060 cmd->frame_type = inject_config_params->frame_type; 12061 cmd->frame_inject_period = inject_config_params->frame_inject_period; 12062 cmd->fc_duration = inject_config_params->frame_duration; 12063 WMI_CHAR_ARRAY_TO_MAC_ADDR(inject_config_params->dstmac, 12064 &cmd->frame_addr1); 12065 12066 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 12067 WMI_PDEV_FRAME_INJECT_CMDID); 12068 12069 if (QDF_IS_STATUS_ERROR(ret)) { 12070 wmi_err( 12071 "WMI_PDEV_FRAME_INJECT_CMDID send returned Error %d", 12072 ret); 12073 wmi_buf_free(buf); 12074 } 12075 12076 return ret; 12077 } 12078 #ifdef QCA_SUPPORT_CP_STATS 12079 /** 12080 * extract_cca_stats_tlv - api to extract congestion stats from event buffer 12081 * @wmi_handle: wma handle 12082 * @evt_buf: event buffer 12083 * @out_buff: buffer to populated after stats extraction 12084 * 12085 * Return: status of operation 12086 */ 12087 static QDF_STATUS extract_cca_stats_tlv(wmi_unified_t wmi_handle, 12088 void *evt_buf, struct wmi_host_congestion_stats *out_buff) 12089 { 12090 WMI_UPDATE_STATS_EVENTID_param_tlvs *param_buf; 12091 wmi_congestion_stats *congestion_stats; 12092 12093 param_buf = (WMI_UPDATE_STATS_EVENTID_param_tlvs *)evt_buf; 12094 congestion_stats = param_buf->congestion_stats; 12095 if (!congestion_stats) 12096 return QDF_STATUS_E_INVAL; 12097 12098 out_buff->vdev_id = congestion_stats->vdev_id; 12099 out_buff->congestion = congestion_stats->congestion; 12100 12101 wmi_debug("cca stats event processed"); 12102 return QDF_STATUS_SUCCESS; 12103 } 12104 #endif /* QCA_SUPPORT_CP_STATS */ 12105 12106 /** 12107 * extract_ctl_failsafe_check_ev_param_tlv() - extract ctl data from 12108 * event 12109 * @wmi_handle: wmi handle 12110 * @evt_buf: pointer to event buffer 12111 * @param: Pointer to hold peer ctl data 12112 * 12113 * Return: QDF_STATUS_SUCCESS for success or error code 12114 */ 12115 static QDF_STATUS extract_ctl_failsafe_check_ev_param_tlv( 12116 wmi_unified_t wmi_handle, 12117 void *evt_buf, 12118 struct wmi_host_pdev_ctl_failsafe_event *param) 12119 { 12120 WMI_PDEV_CTL_FAILSAFE_CHECK_EVENTID_param_tlvs *param_buf; 12121 wmi_pdev_ctl_failsafe_check_fixed_param *fix_param; 12122 12123 param_buf = (WMI_PDEV_CTL_FAILSAFE_CHECK_EVENTID_param_tlvs *)evt_buf; 12124 if (!param_buf) { 12125 wmi_err("Invalid ctl_failsafe event buffer"); 12126 return QDF_STATUS_E_INVAL; 12127 } 12128 12129 fix_param = param_buf->fixed_param; 12130 param->ctl_failsafe_status = fix_param->ctl_FailsafeStatus; 12131 12132 return QDF_STATUS_SUCCESS; 12133 } 12134 12135 /** 12136 * save_service_bitmap_tlv() - save service bitmap 12137 * @wmi_handle: wmi handle 12138 * @evt_buf: pointer to event buffer 12139 * @bitmap_buf: bitmap buffer, for converged legacy support 12140 * 12141 * Return: QDF_STATUS 12142 */ 12143 static 12144 QDF_STATUS save_service_bitmap_tlv(wmi_unified_t wmi_handle, void *evt_buf, 12145 void *bitmap_buf) 12146 { 12147 WMI_SERVICE_READY_EVENTID_param_tlvs *param_buf; 12148 struct wmi_soc *soc = wmi_handle->soc; 12149 12150 param_buf = (WMI_SERVICE_READY_EVENTID_param_tlvs *) evt_buf; 12151 12152 /* If it is already allocated, use that buffer. This can happen 12153 * during target stop/start scenarios where host allocation is skipped. 12154 */ 12155 if (!soc->wmi_service_bitmap) { 12156 soc->wmi_service_bitmap = 12157 qdf_mem_malloc(WMI_SERVICE_BM_SIZE * sizeof(uint32_t)); 12158 if (!soc->wmi_service_bitmap) 12159 return QDF_STATUS_E_NOMEM; 12160 } 12161 12162 qdf_mem_copy(soc->wmi_service_bitmap, 12163 param_buf->wmi_service_bitmap, 12164 (WMI_SERVICE_BM_SIZE * sizeof(uint32_t))); 12165 12166 if (bitmap_buf) 12167 qdf_mem_copy(bitmap_buf, 12168 param_buf->wmi_service_bitmap, 12169 (WMI_SERVICE_BM_SIZE * sizeof(uint32_t))); 12170 12171 return QDF_STATUS_SUCCESS; 12172 } 12173 12174 /** 12175 * save_ext_service_bitmap_tlv() - save extendend service bitmap 12176 * @wmi_handle: wmi handle 12177 * @evt_buf: pointer to event buffer 12178 * @bitmap_buf: bitmap buffer, for converged legacy support 12179 * 12180 * Return: QDF_STATUS 12181 */ 12182 static 12183 QDF_STATUS save_ext_service_bitmap_tlv(wmi_unified_t wmi_handle, void *evt_buf, 12184 void *bitmap_buf) 12185 { 12186 WMI_SERVICE_AVAILABLE_EVENTID_param_tlvs *param_buf; 12187 wmi_service_available_event_fixed_param *ev; 12188 struct wmi_soc *soc = wmi_handle->soc; 12189 uint32_t i = 0; 12190 12191 param_buf = (WMI_SERVICE_AVAILABLE_EVENTID_param_tlvs *) evt_buf; 12192 12193 ev = param_buf->fixed_param; 12194 12195 /* If it is already allocated, use that buffer. This can happen 12196 * during target stop/start scenarios where host allocation is skipped. 12197 */ 12198 if (!soc->wmi_ext_service_bitmap) { 12199 soc->wmi_ext_service_bitmap = qdf_mem_malloc( 12200 WMI_SERVICE_SEGMENT_BM_SIZE32 * sizeof(uint32_t)); 12201 if (!soc->wmi_ext_service_bitmap) 12202 return QDF_STATUS_E_NOMEM; 12203 } 12204 12205 qdf_mem_copy(soc->wmi_ext_service_bitmap, 12206 ev->wmi_service_segment_bitmap, 12207 (WMI_SERVICE_SEGMENT_BM_SIZE32 * sizeof(uint32_t))); 12208 12209 wmi_debug("wmi_ext_service_bitmap 0:0x%x, 1:0x%x, 2:0x%x, 3:0x%x", 12210 soc->wmi_ext_service_bitmap[0], soc->wmi_ext_service_bitmap[1], 12211 soc->wmi_ext_service_bitmap[2], soc->wmi_ext_service_bitmap[3]); 12212 12213 if (bitmap_buf) 12214 qdf_mem_copy(bitmap_buf, 12215 soc->wmi_ext_service_bitmap, 12216 (WMI_SERVICE_SEGMENT_BM_SIZE32 * sizeof(uint32_t))); 12217 12218 if (!param_buf->wmi_service_ext_bitmap) { 12219 wmi_debug("wmi_service_ext_bitmap not available"); 12220 return QDF_STATUS_SUCCESS; 12221 } 12222 12223 if (!soc->wmi_ext2_service_bitmap || 12224 (param_buf->num_wmi_service_ext_bitmap > 12225 soc->wmi_ext2_service_bitmap_len)) { 12226 if (soc->wmi_ext2_service_bitmap) { 12227 qdf_mem_free(soc->wmi_ext2_service_bitmap); 12228 soc->wmi_ext2_service_bitmap = NULL; 12229 } 12230 soc->wmi_ext2_service_bitmap = 12231 qdf_mem_malloc(param_buf->num_wmi_service_ext_bitmap * 12232 sizeof(uint32_t)); 12233 if (!soc->wmi_ext2_service_bitmap) 12234 return QDF_STATUS_E_NOMEM; 12235 12236 soc->wmi_ext2_service_bitmap_len = 12237 param_buf->num_wmi_service_ext_bitmap; 12238 } 12239 12240 qdf_mem_copy(soc->wmi_ext2_service_bitmap, 12241 param_buf->wmi_service_ext_bitmap, 12242 (param_buf->num_wmi_service_ext_bitmap * 12243 sizeof(uint32_t))); 12244 12245 for (i = 0; i < param_buf->num_wmi_service_ext_bitmap; i++) { 12246 wmi_debug("wmi_ext2_service_bitmap %u:0x%x", 12247 i, soc->wmi_ext2_service_bitmap[i]); 12248 } 12249 12250 return QDF_STATUS_SUCCESS; 12251 } 12252 12253 static inline void copy_ht_cap_info(uint32_t ev_target_cap, 12254 struct wlan_psoc_target_capability_info *cap) 12255 { 12256 /* except LDPC all flags are common between legacy and here 12257 * also IBFEER is not defined for TLV 12258 */ 12259 cap->ht_cap_info |= ev_target_cap & ( 12260 WMI_HT_CAP_ENABLED 12261 | WMI_HT_CAP_HT20_SGI 12262 | WMI_HT_CAP_DYNAMIC_SMPS 12263 | WMI_HT_CAP_TX_STBC 12264 | WMI_HT_CAP_TX_STBC_MASK_SHIFT 12265 | WMI_HT_CAP_RX_STBC 12266 | WMI_HT_CAP_RX_STBC_MASK_SHIFT 12267 | WMI_HT_CAP_LDPC 12268 | WMI_HT_CAP_L_SIG_TXOP_PROT 12269 | WMI_HT_CAP_MPDU_DENSITY 12270 | WMI_HT_CAP_MPDU_DENSITY_MASK_SHIFT 12271 | WMI_HT_CAP_HT40_SGI); 12272 if (ev_target_cap & WMI_HT_CAP_LDPC) 12273 cap->ht_cap_info |= WMI_HOST_HT_CAP_RX_LDPC | 12274 WMI_HOST_HT_CAP_TX_LDPC; 12275 } 12276 /** 12277 * extract_service_ready_tlv() - extract service ready event 12278 * @wmi_handle: wmi handle 12279 * @evt_buf: pointer to received event buffer 12280 * @cap: pointer to hold target capability information extracted from even 12281 * 12282 * Return: QDF_STATUS_SUCCESS for success or error code 12283 */ 12284 static QDF_STATUS extract_service_ready_tlv(wmi_unified_t wmi_handle, 12285 void *evt_buf, struct wlan_psoc_target_capability_info *cap) 12286 { 12287 WMI_SERVICE_READY_EVENTID_param_tlvs *param_buf; 12288 wmi_service_ready_event_fixed_param *ev; 12289 12290 12291 param_buf = (WMI_SERVICE_READY_EVENTID_param_tlvs *) evt_buf; 12292 12293 ev = (wmi_service_ready_event_fixed_param *) param_buf->fixed_param; 12294 if (!ev) { 12295 qdf_print("%s: wmi_buf_alloc failed", __func__); 12296 return QDF_STATUS_E_FAILURE; 12297 } 12298 12299 cap->phy_capability = ev->phy_capability; 12300 cap->max_frag_entry = ev->max_frag_entry; 12301 cap->num_rf_chains = ev->num_rf_chains; 12302 copy_ht_cap_info(ev->ht_cap_info, cap); 12303 cap->vht_cap_info = ev->vht_cap_info; 12304 cap->vht_supp_mcs = ev->vht_supp_mcs; 12305 cap->hw_min_tx_power = ev->hw_min_tx_power; 12306 cap->hw_max_tx_power = ev->hw_max_tx_power; 12307 cap->sys_cap_info = ev->sys_cap_info; 12308 cap->min_pkt_size_enable = ev->min_pkt_size_enable; 12309 cap->max_bcn_ie_size = ev->max_bcn_ie_size; 12310 cap->max_num_scan_channels = ev->max_num_scan_channels; 12311 cap->max_supported_macs = ev->max_supported_macs; 12312 cap->wmi_fw_sub_feat_caps = ev->wmi_fw_sub_feat_caps; 12313 cap->txrx_chainmask = ev->txrx_chainmask; 12314 cap->default_dbs_hw_mode_index = ev->default_dbs_hw_mode_index; 12315 cap->num_msdu_desc = ev->num_msdu_desc; 12316 cap->fw_version = ev->fw_build_vers; 12317 /* fw_version_1 is not available in TLV. */ 12318 cap->fw_version_1 = 0; 12319 12320 return QDF_STATUS_SUCCESS; 12321 } 12322 12323 /* convert_wireless_modes_tlv() - Convert REGDMN_MODE values sent by target 12324 * to host internal HOST_REGDMN_MODE values. 12325 * REGULATORY TODO : REGDMN_MODE_11AC_VHT*_2G values are not used by the 12326 * host currently. Add this in the future if required. 12327 * 11AX (Phase II) : 11ax related values are not currently 12328 * advertised separately by FW. As part of phase II regulatory bring-up, 12329 * finalize the advertisement mechanism. 12330 * @target_wireless_mode: target wireless mode received in message 12331 * 12332 * Return: returns the host internal wireless mode. 12333 */ 12334 static inline uint32_t convert_wireless_modes_tlv(uint32_t target_wireless_mode) 12335 { 12336 12337 uint32_t wireless_modes = 0; 12338 12339 wmi_debug("Target wireless mode: 0x%x", target_wireless_mode); 12340 12341 if (target_wireless_mode & REGDMN_MODE_11A) 12342 wireless_modes |= HOST_REGDMN_MODE_11A; 12343 12344 if (target_wireless_mode & REGDMN_MODE_TURBO) 12345 wireless_modes |= HOST_REGDMN_MODE_TURBO; 12346 12347 if (target_wireless_mode & REGDMN_MODE_11B) 12348 wireless_modes |= HOST_REGDMN_MODE_11B; 12349 12350 if (target_wireless_mode & REGDMN_MODE_PUREG) 12351 wireless_modes |= HOST_REGDMN_MODE_PUREG; 12352 12353 if (target_wireless_mode & REGDMN_MODE_11G) 12354 wireless_modes |= HOST_REGDMN_MODE_11G; 12355 12356 if (target_wireless_mode & REGDMN_MODE_108G) 12357 wireless_modes |= HOST_REGDMN_MODE_108G; 12358 12359 if (target_wireless_mode & REGDMN_MODE_108A) 12360 wireless_modes |= HOST_REGDMN_MODE_108A; 12361 12362 if (target_wireless_mode & REGDMN_MODE_11AC_VHT20_2G) 12363 wireless_modes |= HOST_REGDMN_MODE_11AC_VHT20_2G; 12364 12365 if (target_wireless_mode & REGDMN_MODE_XR) 12366 wireless_modes |= HOST_REGDMN_MODE_XR; 12367 12368 if (target_wireless_mode & REGDMN_MODE_11A_HALF_RATE) 12369 wireless_modes |= HOST_REGDMN_MODE_11A_HALF_RATE; 12370 12371 if (target_wireless_mode & REGDMN_MODE_11A_QUARTER_RATE) 12372 wireless_modes |= HOST_REGDMN_MODE_11A_QUARTER_RATE; 12373 12374 if (target_wireless_mode & REGDMN_MODE_11NG_HT20) 12375 wireless_modes |= HOST_REGDMN_MODE_11NG_HT20; 12376 12377 if (target_wireless_mode & REGDMN_MODE_11NA_HT20) 12378 wireless_modes |= HOST_REGDMN_MODE_11NA_HT20; 12379 12380 if (target_wireless_mode & REGDMN_MODE_11NG_HT40PLUS) 12381 wireless_modes |= HOST_REGDMN_MODE_11NG_HT40PLUS; 12382 12383 if (target_wireless_mode & REGDMN_MODE_11NG_HT40MINUS) 12384 wireless_modes |= HOST_REGDMN_MODE_11NG_HT40MINUS; 12385 12386 if (target_wireless_mode & REGDMN_MODE_11NA_HT40PLUS) 12387 wireless_modes |= HOST_REGDMN_MODE_11NA_HT40PLUS; 12388 12389 if (target_wireless_mode & REGDMN_MODE_11NA_HT40MINUS) 12390 wireless_modes |= HOST_REGDMN_MODE_11NA_HT40MINUS; 12391 12392 if (target_wireless_mode & REGDMN_MODE_11AC_VHT20) 12393 wireless_modes |= HOST_REGDMN_MODE_11AC_VHT20; 12394 12395 if (target_wireless_mode & REGDMN_MODE_11AC_VHT40PLUS) 12396 wireless_modes |= HOST_REGDMN_MODE_11AC_VHT40PLUS; 12397 12398 if (target_wireless_mode & REGDMN_MODE_11AC_VHT40MINUS) 12399 wireless_modes |= HOST_REGDMN_MODE_11AC_VHT40MINUS; 12400 12401 if (target_wireless_mode & REGDMN_MODE_11AC_VHT80) 12402 wireless_modes |= HOST_REGDMN_MODE_11AC_VHT80; 12403 12404 if (target_wireless_mode & REGDMN_MODE_11AC_VHT160) 12405 wireless_modes |= HOST_REGDMN_MODE_11AC_VHT160; 12406 12407 if (target_wireless_mode & REGDMN_MODE_11AC_VHT80_80) 12408 wireless_modes |= HOST_REGDMN_MODE_11AC_VHT80_80; 12409 12410 return wireless_modes; 12411 } 12412 12413 /** 12414 * convert_11be_phybitmap_to_reg_flags() - Convert 11BE phybitmap to 12415 * to regulatory flags. 12416 * @target_phybitmap: target phybitmap. 12417 * @phybitmap: host internal REGULATORY_PHYMODE set based on target 12418 * phybitmap. 12419 * 12420 * Return: None 12421 */ 12422 12423 #ifdef WLAN_FEATURE_11BE 12424 static void convert_11be_phybitmap_to_reg_flags(uint32_t target_phybitmap, 12425 uint32_t *phybitmap) 12426 { 12427 if (target_phybitmap & WMI_REGULATORY_PHYMODE_NO11BE) 12428 *phybitmap |= REGULATORY_PHYMODE_NO11BE; 12429 } 12430 #else 12431 static void convert_11be_phybitmap_to_reg_flags(uint32_t target_phybitmap, 12432 uint32_t *phybitmap) 12433 { 12434 } 12435 #endif 12436 12437 /* convert_phybitmap_tlv() - Convert WMI_REGULATORY_PHYBITMAP values sent by 12438 * target to host internal REGULATORY_PHYMODE values. 12439 * 12440 * @target_target_phybitmap: target phybitmap received in the message. 12441 * 12442 * Return: returns the host internal REGULATORY_PHYMODE. 12443 */ 12444 static uint32_t convert_phybitmap_tlv(uint32_t target_phybitmap) 12445 { 12446 uint32_t phybitmap = 0; 12447 12448 wmi_debug("Target phybitmap: 0x%x", target_phybitmap); 12449 12450 if (target_phybitmap & WMI_REGULATORY_PHYMODE_NO11A) 12451 phybitmap |= REGULATORY_PHYMODE_NO11A; 12452 12453 if (target_phybitmap & WMI_REGULATORY_PHYMODE_NO11B) 12454 phybitmap |= REGULATORY_PHYMODE_NO11B; 12455 12456 if (target_phybitmap & WMI_REGULATORY_PHYMODE_NO11G) 12457 phybitmap |= REGULATORY_PHYMODE_NO11G; 12458 12459 if (target_phybitmap & WMI_REGULATORY_PHYMODE_NO11N) 12460 phybitmap |= REGULATORY_CHAN_NO11N; 12461 12462 if (target_phybitmap & WMI_REGULATORY_PHYMODE_NO11AC) 12463 phybitmap |= REGULATORY_PHYMODE_NO11AC; 12464 12465 if (target_phybitmap & WMI_REGULATORY_PHYMODE_NO11AX) 12466 phybitmap |= REGULATORY_PHYMODE_NO11AX; 12467 12468 convert_11be_phybitmap_to_reg_flags(target_phybitmap, &phybitmap); 12469 12470 return phybitmap; 12471 } 12472 12473 /** 12474 * convert_11be_flags_to_modes_ext() - Convert 11BE wireless mode flag 12475 * advertised by the target to wireless mode ext flags. 12476 * @target_wireless_modes_ext: Target wireless mode 12477 * @wireless_modes_ext: Variable to hold all the target wireless mode caps. 12478 * 12479 * Return: None 12480 */ 12481 #ifdef WLAN_FEATURE_11BE 12482 static void convert_11be_flags_to_modes_ext(uint32_t target_wireless_modes_ext, 12483 uint64_t *wireless_modes_ext) 12484 { 12485 if (target_wireless_modes_ext & REGDMN_MODE_U32_11BEG_EHT20) 12486 *wireless_modes_ext |= HOST_REGDMN_MODE_11BEG_EHT20; 12487 12488 if (target_wireless_modes_ext & REGDMN_MODE_U32_11BEG_EHT40PLUS) 12489 *wireless_modes_ext |= HOST_REGDMN_MODE_11BEG_EHT40PLUS; 12490 12491 if (target_wireless_modes_ext & REGDMN_MODE_U32_11BEG_EHT40MINUS) 12492 *wireless_modes_ext |= HOST_REGDMN_MODE_11BEG_EHT40MINUS; 12493 12494 if (target_wireless_modes_ext & REGDMN_MODE_U32_11BEA_EHT20) 12495 *wireless_modes_ext |= HOST_REGDMN_MODE_11BEA_EHT20; 12496 12497 if (target_wireless_modes_ext & REGDMN_MODE_U32_11BEA_EHT40PLUS) 12498 *wireless_modes_ext |= HOST_REGDMN_MODE_11BEA_EHT40PLUS; 12499 12500 if (target_wireless_modes_ext & REGDMN_MODE_U32_11BEA_EHT40MINUS) 12501 *wireless_modes_ext |= HOST_REGDMN_MODE_11BEA_EHT40MINUS; 12502 12503 if (target_wireless_modes_ext & REGDMN_MODE_U32_11BEA_EHT80) 12504 *wireless_modes_ext |= HOST_REGDMN_MODE_11BEA_EHT80; 12505 12506 if (target_wireless_modes_ext & REGDMN_MODE_U32_11BEA_EHT160) 12507 *wireless_modes_ext |= HOST_REGDMN_MODE_11BEA_EHT160; 12508 12509 if (target_wireless_modes_ext & REGDMN_MODE_U32_11BEA_EHT320) 12510 *wireless_modes_ext |= HOST_REGDMN_MODE_11BEA_EHT320; 12511 } 12512 #else 12513 static void convert_11be_flags_to_modes_ext(uint32_t target_wireless_modes_ext, 12514 uint64_t *wireless_modes_ext) 12515 { 12516 } 12517 #endif 12518 12519 static inline uint64_t convert_wireless_modes_ext_tlv( 12520 uint32_t target_wireless_modes_ext) 12521 { 12522 uint64_t wireless_modes_ext = 0; 12523 12524 wmi_debug("Target wireless mode: 0x%x", target_wireless_modes_ext); 12525 12526 if (target_wireless_modes_ext & REGDMN_MODE_U32_11AXG_HE20) 12527 wireless_modes_ext |= HOST_REGDMN_MODE_11AXG_HE20; 12528 12529 if (target_wireless_modes_ext & REGDMN_MODE_U32_11AXG_HE40PLUS) 12530 wireless_modes_ext |= HOST_REGDMN_MODE_11AXG_HE40PLUS; 12531 12532 if (target_wireless_modes_ext & REGDMN_MODE_U32_11AXG_HE40MINUS) 12533 wireless_modes_ext |= HOST_REGDMN_MODE_11AXG_HE40MINUS; 12534 12535 if (target_wireless_modes_ext & REGDMN_MODE_U32_11AXA_HE20) 12536 wireless_modes_ext |= HOST_REGDMN_MODE_11AXA_HE20; 12537 12538 if (target_wireless_modes_ext & REGDMN_MODE_U32_11AXA_HE40PLUS) 12539 wireless_modes_ext |= HOST_REGDMN_MODE_11AXA_HE40PLUS; 12540 12541 if (target_wireless_modes_ext & REGDMN_MODE_U32_11AXA_HE40MINUS) 12542 wireless_modes_ext |= HOST_REGDMN_MODE_11AXA_HE40MINUS; 12543 12544 if (target_wireless_modes_ext & REGDMN_MODE_U32_11AXA_HE80) 12545 wireless_modes_ext |= HOST_REGDMN_MODE_11AXA_HE80; 12546 12547 if (target_wireless_modes_ext & REGDMN_MODE_U32_11AXA_HE160) 12548 wireless_modes_ext |= HOST_REGDMN_MODE_11AXA_HE160; 12549 12550 if (target_wireless_modes_ext & REGDMN_MODE_U32_11AXA_HE80_80) 12551 wireless_modes_ext |= HOST_REGDMN_MODE_11AXA_HE80_80; 12552 12553 convert_11be_flags_to_modes_ext(target_wireless_modes_ext, 12554 &wireless_modes_ext); 12555 12556 return wireless_modes_ext; 12557 } 12558 12559 /** 12560 * extract_hal_reg_cap_tlv() - extract HAL registered capabilities 12561 * @wmi_handle: wmi handle 12562 * @evt_buf: Pointer to event buffer 12563 * @cap: pointer to hold HAL reg capabilities 12564 * 12565 * Return: QDF_STATUS_SUCCESS for success or error code 12566 */ 12567 static QDF_STATUS extract_hal_reg_cap_tlv(wmi_unified_t wmi_handle, 12568 void *evt_buf, struct wlan_psoc_hal_reg_capability *cap) 12569 { 12570 WMI_SERVICE_READY_EVENTID_param_tlvs *param_buf; 12571 12572 param_buf = (WMI_SERVICE_READY_EVENTID_param_tlvs *) evt_buf; 12573 if (!param_buf || !param_buf->hal_reg_capabilities) { 12574 wmi_err("Invalid arguments"); 12575 return QDF_STATUS_E_FAILURE; 12576 } 12577 qdf_mem_copy(cap, (((uint8_t *)param_buf->hal_reg_capabilities) + 12578 sizeof(uint32_t)), 12579 sizeof(struct wlan_psoc_hal_reg_capability)); 12580 12581 cap->wireless_modes = convert_wireless_modes_tlv( 12582 param_buf->hal_reg_capabilities->wireless_modes); 12583 12584 return QDF_STATUS_SUCCESS; 12585 } 12586 12587 /** 12588 * extract_hal_reg_cap_ext2_tlv() - extract HAL registered capability ext 12589 * @wmi_handle: wmi handle 12590 * @evt_buf: Pointer to event buffer 12591 * @phy_idx: Specific phy to extract 12592 * @param: pointer to hold HAL reg capabilities 12593 * 12594 * Return: QDF_STATUS_SUCCESS for success or error code 12595 */ 12596 static QDF_STATUS extract_hal_reg_cap_ext2_tlv( 12597 wmi_unified_t wmi_handle, void *evt_buf, uint8_t phy_idx, 12598 struct wlan_psoc_host_hal_reg_capabilities_ext2 *param) 12599 { 12600 WMI_SERVICE_READY_EXT2_EVENTID_param_tlvs *param_buf; 12601 WMI_HAL_REG_CAPABILITIES_EXT2 *reg_caps; 12602 12603 if (!evt_buf) { 12604 wmi_err("null evt_buf"); 12605 return QDF_STATUS_E_INVAL; 12606 } 12607 12608 param_buf = (WMI_SERVICE_READY_EXT2_EVENTID_param_tlvs *)evt_buf; 12609 12610 if (!param_buf->num_hal_reg_caps) 12611 return QDF_STATUS_SUCCESS; 12612 12613 if (phy_idx >= param_buf->num_hal_reg_caps) 12614 return QDF_STATUS_E_INVAL; 12615 12616 reg_caps = ¶m_buf->hal_reg_caps[phy_idx]; 12617 12618 param->phy_id = reg_caps->phy_id; 12619 param->wireless_modes_ext = convert_wireless_modes_ext_tlv( 12620 reg_caps->wireless_modes_ext); 12621 12622 return QDF_STATUS_SUCCESS; 12623 } 12624 12625 /** 12626 * extract_num_mem_reqs_tlv() - Extract number of memory entries requested 12627 * @wmi_handle: wmi handle 12628 * @evt_buf: pointer to event buffer 12629 * 12630 * Return: Number of entries requested 12631 */ 12632 static uint32_t extract_num_mem_reqs_tlv(wmi_unified_t wmi_handle, 12633 void *evt_buf) 12634 { 12635 WMI_SERVICE_READY_EVENTID_param_tlvs *param_buf; 12636 wmi_service_ready_event_fixed_param *ev; 12637 12638 param_buf = (WMI_SERVICE_READY_EVENTID_param_tlvs *) evt_buf; 12639 12640 ev = (wmi_service_ready_event_fixed_param *) param_buf->fixed_param; 12641 if (!ev) { 12642 qdf_print("%s: wmi_buf_alloc failed", __func__); 12643 return 0; 12644 } 12645 12646 if (ev->num_mem_reqs > param_buf->num_mem_reqs) { 12647 wmi_err("Invalid num_mem_reqs %d:%d", 12648 ev->num_mem_reqs, param_buf->num_mem_reqs); 12649 return 0; 12650 } 12651 12652 return ev->num_mem_reqs; 12653 } 12654 12655 /** 12656 * extract_host_mem_req_tlv() - Extract host memory required from 12657 * service ready event 12658 * @wmi_handle: wmi handle 12659 * @evt_buf: pointer to event buffer 12660 * @mem_reqs: pointer to host memory request structure 12661 * @num_active_peers: number of active peers for peer cache 12662 * @num_peers: number of peers 12663 * @fw_prio: FW priority 12664 * @idx: index for memory request 12665 * 12666 * Return: Host memory request parameters requested by target 12667 */ 12668 static QDF_STATUS extract_host_mem_req_tlv(wmi_unified_t wmi_handle, 12669 void *evt_buf, 12670 host_mem_req *mem_reqs, 12671 uint32_t num_active_peers, 12672 uint32_t num_peers, 12673 enum wmi_fw_mem_prio fw_prio, 12674 uint16_t idx) 12675 { 12676 WMI_SERVICE_READY_EVENTID_param_tlvs *param_buf; 12677 12678 param_buf = (WMI_SERVICE_READY_EVENTID_param_tlvs *)evt_buf; 12679 12680 mem_reqs->req_id = (uint32_t)param_buf->mem_reqs[idx].req_id; 12681 mem_reqs->unit_size = (uint32_t)param_buf->mem_reqs[idx].unit_size; 12682 mem_reqs->num_unit_info = 12683 (uint32_t)param_buf->mem_reqs[idx].num_unit_info; 12684 mem_reqs->num_units = (uint32_t)param_buf->mem_reqs[idx].num_units; 12685 mem_reqs->tgt_num_units = 0; 12686 12687 if (((fw_prio == WMI_FW_MEM_HIGH_PRIORITY) && 12688 (mem_reqs->num_unit_info & 12689 REQ_TO_HOST_FOR_CONT_MEMORY)) || 12690 ((fw_prio == WMI_FW_MEM_LOW_PRIORITY) && 12691 (!(mem_reqs->num_unit_info & 12692 REQ_TO_HOST_FOR_CONT_MEMORY)))) { 12693 /* First allocate the memory that requires contiguous memory */ 12694 mem_reqs->tgt_num_units = mem_reqs->num_units; 12695 if (mem_reqs->num_unit_info) { 12696 if (mem_reqs->num_unit_info & 12697 NUM_UNITS_IS_NUM_PEERS) { 12698 /* 12699 * number of units allocated is equal to number 12700 * of peers, 1 extra for self peer on target. 12701 * this needs to be fixed, host and target can 12702 * get out of sync 12703 */ 12704 mem_reqs->tgt_num_units = num_peers + 1; 12705 } 12706 if (mem_reqs->num_unit_info & 12707 NUM_UNITS_IS_NUM_ACTIVE_PEERS) { 12708 /* 12709 * Requesting allocation of memory using 12710 * num_active_peers in qcache. if qcache is 12711 * disabled in host, then it should allocate 12712 * memory for num_peers instead of 12713 * num_active_peers. 12714 */ 12715 if (num_active_peers) 12716 mem_reqs->tgt_num_units = 12717 num_active_peers + 1; 12718 else 12719 mem_reqs->tgt_num_units = 12720 num_peers + 1; 12721 } 12722 } 12723 12724 wmi_debug("idx %d req %d num_units %d num_unit_info %d" 12725 "unit size %d actual units %d", 12726 idx, mem_reqs->req_id, 12727 mem_reqs->num_units, 12728 mem_reqs->num_unit_info, 12729 mem_reqs->unit_size, 12730 mem_reqs->tgt_num_units); 12731 } 12732 12733 return QDF_STATUS_SUCCESS; 12734 } 12735 12736 /** 12737 * save_fw_version_in_service_ready_tlv() - Save fw version in service 12738 * ready function 12739 * @wmi_handle: wmi handle 12740 * @evt_buf: pointer to event buffer 12741 * 12742 * Return: QDF_STATUS_SUCCESS for success or error code 12743 */ 12744 static QDF_STATUS 12745 save_fw_version_in_service_ready_tlv(wmi_unified_t wmi_handle, void *evt_buf) 12746 { 12747 WMI_SERVICE_READY_EVENTID_param_tlvs *param_buf; 12748 wmi_service_ready_event_fixed_param *ev; 12749 12750 12751 param_buf = (WMI_SERVICE_READY_EVENTID_param_tlvs *) evt_buf; 12752 12753 ev = (wmi_service_ready_event_fixed_param *) param_buf->fixed_param; 12754 if (!ev) { 12755 qdf_print("%s: wmi_buf_alloc failed", __func__); 12756 return QDF_STATUS_E_FAILURE; 12757 } 12758 12759 /*Save fw version from service ready message */ 12760 /*This will be used while sending INIT message */ 12761 qdf_mem_copy(&wmi_handle->fw_abi_version, &ev->fw_abi_vers, 12762 sizeof(wmi_handle->fw_abi_version)); 12763 12764 return QDF_STATUS_SUCCESS; 12765 } 12766 12767 /** 12768 * ready_extract_init_status_tlv() - Extract init status from ready event 12769 * @wmi_handle: wmi handle 12770 * @evt_buf: Pointer to event buffer 12771 * 12772 * Return: ready status 12773 */ 12774 static uint32_t ready_extract_init_status_tlv(wmi_unified_t wmi_handle, 12775 void *evt_buf) 12776 { 12777 WMI_READY_EVENTID_param_tlvs *param_buf = NULL; 12778 wmi_ready_event_fixed_param *ev = NULL; 12779 12780 param_buf = (WMI_READY_EVENTID_param_tlvs *) evt_buf; 12781 ev = param_buf->fixed_param; 12782 12783 qdf_print("%s:%d", __func__, ev->status); 12784 12785 return ev->status; 12786 } 12787 12788 /** 12789 * ready_extract_mac_addr_tlv() - extract mac address from ready event 12790 * @wmi_handle: wmi handle 12791 * @evt_buf: pointer to event buffer 12792 * @macaddr: Pointer to hold MAC address 12793 * 12794 * Return: QDF_STATUS_SUCCESS for success or error code 12795 */ 12796 static QDF_STATUS ready_extract_mac_addr_tlv(wmi_unified_t wmi_handle, 12797 void *evt_buf, uint8_t *macaddr) 12798 { 12799 WMI_READY_EVENTID_param_tlvs *param_buf = NULL; 12800 wmi_ready_event_fixed_param *ev = NULL; 12801 12802 12803 param_buf = (WMI_READY_EVENTID_param_tlvs *) evt_buf; 12804 ev = param_buf->fixed_param; 12805 12806 WMI_MAC_ADDR_TO_CHAR_ARRAY(&ev->mac_addr, macaddr); 12807 12808 return QDF_STATUS_SUCCESS; 12809 } 12810 12811 /** 12812 * ready_extract_mac_addr_list_tlv() - extract MAC address list from ready event 12813 * @wmi_handle: wmi handle 12814 * @evt_buf: pointer to event buffer 12815 * @num_mac: Pointer to hold number of MAC addresses 12816 * 12817 * Return: Pointer to addr list 12818 */ 12819 static wmi_host_mac_addr * 12820 ready_extract_mac_addr_list_tlv(wmi_unified_t wmi_handle, 12821 void *evt_buf, uint8_t *num_mac) 12822 { 12823 WMI_READY_EVENTID_param_tlvs *param_buf = NULL; 12824 wmi_ready_event_fixed_param *ev = NULL; 12825 12826 param_buf = (WMI_READY_EVENTID_param_tlvs *) evt_buf; 12827 ev = param_buf->fixed_param; 12828 12829 *num_mac = ev->num_extra_mac_addr; 12830 12831 return (wmi_host_mac_addr *) param_buf->mac_addr_list; 12832 } 12833 12834 /** 12835 * extract_ready_event_params_tlv() - Extract data from ready event apart from 12836 * status, macaddr and version. 12837 * @wmi_handle: Pointer to WMI handle. 12838 * @evt_buf: Pointer to Ready event buffer. 12839 * @ev_param: Pointer to host defined struct to copy the data from event. 12840 * 12841 * Return: QDF_STATUS_SUCCESS on success. 12842 */ 12843 static QDF_STATUS extract_ready_event_params_tlv(wmi_unified_t wmi_handle, 12844 void *evt_buf, struct wmi_host_ready_ev_param *ev_param) 12845 { 12846 WMI_READY_EVENTID_param_tlvs *param_buf = NULL; 12847 wmi_ready_event_fixed_param *ev = NULL; 12848 12849 param_buf = (WMI_READY_EVENTID_param_tlvs *) evt_buf; 12850 ev = param_buf->fixed_param; 12851 12852 ev_param->status = ev->status; 12853 ev_param->num_dscp_table = ev->num_dscp_table; 12854 ev_param->num_extra_mac_addr = ev->num_extra_mac_addr; 12855 ev_param->num_total_peer = ev->num_total_peers; 12856 ev_param->num_extra_peer = ev->num_extra_peers; 12857 /* Agile_capability in ready event is supported in TLV target, 12858 * as per aDFS FR 12859 */ 12860 ev_param->max_ast_index = ev->max_ast_index; 12861 ev_param->pktlog_defs_checksum = ev->pktlog_defs_checksum; 12862 ev_param->agile_capability = 1; 12863 ev_param->num_max_active_vdevs = ev->num_max_active_vdevs; 12864 12865 return QDF_STATUS_SUCCESS; 12866 } 12867 12868 /** 12869 * extract_dbglog_data_len_tlv() - extract debuglog data length 12870 * @wmi_handle: wmi handle 12871 * @evt_buf: pointer to event buffer 12872 * @len: length of the log 12873 * 12874 * Return: pointer to the debug log 12875 */ 12876 static uint8_t *extract_dbglog_data_len_tlv(wmi_unified_t wmi_handle, 12877 void *evt_buf, uint32_t *len) 12878 { 12879 WMI_DEBUG_MESG_EVENTID_param_tlvs *param_buf; 12880 12881 param_buf = (WMI_DEBUG_MESG_EVENTID_param_tlvs *) evt_buf; 12882 12883 *len = param_buf->num_bufp; 12884 12885 return param_buf->bufp; 12886 } 12887 12888 12889 #ifdef MGMT_FRAME_RX_DECRYPT_ERROR 12890 #define IS_WMI_RX_MGMT_FRAME_STATUS_INVALID(_status) false 12891 #else 12892 #define IS_WMI_RX_MGMT_FRAME_STATUS_INVALID(_status) \ 12893 ((_status) & WMI_RXERR_DECRYPT) 12894 #endif 12895 12896 /** 12897 * extract_mgmt_rx_params_tlv() - extract management rx params from event 12898 * @wmi_handle: wmi handle 12899 * @evt_buf: pointer to event buffer 12900 * @hdr: Pointer to hold header 12901 * @bufp: Pointer to hold pointer to rx param buffer 12902 * 12903 * Return: QDF_STATUS_SUCCESS for success or error code 12904 */ 12905 static QDF_STATUS extract_mgmt_rx_params_tlv(wmi_unified_t wmi_handle, 12906 void *evt_buf, struct mgmt_rx_event_params *hdr, 12907 uint8_t **bufp) 12908 { 12909 WMI_MGMT_RX_EVENTID_param_tlvs *param_tlvs = NULL; 12910 wmi_mgmt_rx_hdr *ev_hdr = NULL; 12911 int i; 12912 12913 param_tlvs = (WMI_MGMT_RX_EVENTID_param_tlvs *) evt_buf; 12914 if (!param_tlvs) { 12915 wmi_err("Get NULL point message from FW"); 12916 return QDF_STATUS_E_INVAL; 12917 } 12918 12919 ev_hdr = param_tlvs->hdr; 12920 if (!hdr) { 12921 wmi_err("Rx event is NULL"); 12922 return QDF_STATUS_E_INVAL; 12923 } 12924 12925 if (IS_WMI_RX_MGMT_FRAME_STATUS_INVALID(ev_hdr->status)) { 12926 wmi_err("RX mgmt frame decrypt error, discard it"); 12927 return QDF_STATUS_E_INVAL; 12928 } 12929 if ((ev_hdr->status) & WMI_RXERR_MIC) { 12930 wmi_err("RX mgmt frame MIC mismatch for beacon protected frame"); 12931 } 12932 12933 if (ev_hdr->buf_len > param_tlvs->num_bufp) { 12934 wmi_err("Rx mgmt frame length mismatch, discard it"); 12935 return QDF_STATUS_E_INVAL; 12936 } 12937 12938 hdr->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host( 12939 wmi_handle, 12940 ev_hdr->pdev_id); 12941 hdr->chan_freq = ev_hdr->chan_freq; 12942 hdr->channel = ev_hdr->channel; 12943 hdr->snr = ev_hdr->snr; 12944 hdr->rate = ev_hdr->rate; 12945 hdr->phy_mode = ev_hdr->phy_mode; 12946 hdr->buf_len = ev_hdr->buf_len; 12947 hdr->status = ev_hdr->status; 12948 hdr->flags = ev_hdr->flags; 12949 hdr->rssi = ev_hdr->rssi; 12950 hdr->tsf_delta = ev_hdr->tsf_delta; 12951 hdr->tsf_l32 = ev_hdr->rx_tsf_l32; 12952 for (i = 0; i < ATH_MAX_ANTENNA; i++) 12953 hdr->rssi_ctl[i] = ev_hdr->rssi_ctl[i]; 12954 12955 *bufp = param_tlvs->bufp; 12956 12957 extract_mgmt_rx_mlo_link_removal_tlv_count( 12958 param_tlvs->num_link_removal_tbtt_count, hdr); 12959 12960 return QDF_STATUS_SUCCESS; 12961 } 12962 12963 static QDF_STATUS extract_mgmt_rx_ext_params_tlv(wmi_unified_t wmi_handle, 12964 void *evt_buf, struct mgmt_rx_event_ext_params *ext_params) 12965 { 12966 WMI_MGMT_RX_EVENTID_param_tlvs *param_tlvs; 12967 wmi_mgmt_rx_params_ext *ext_params_tlv; 12968 wmi_mgmt_rx_hdr *ev_hdr; 12969 12970 param_tlvs = (WMI_MGMT_RX_EVENTID_param_tlvs *) evt_buf; 12971 if (!param_tlvs) { 12972 wmi_err("param_tlvs is NULL"); 12973 return QDF_STATUS_E_INVAL; 12974 } 12975 12976 ev_hdr = param_tlvs->hdr; 12977 if (!ev_hdr) { 12978 wmi_err("Rx event is NULL"); 12979 return QDF_STATUS_E_INVAL; 12980 } 12981 12982 ext_params_tlv = param_tlvs->mgmt_rx_params_ext; 12983 if (ext_params_tlv) { 12984 ext_params->ba_win_size = WMI_RX_PARAM_EXT_BA_WIN_SIZE_GET( 12985 ext_params_tlv->mgmt_rx_params_ext_dword1); 12986 if (ext_params->ba_win_size > 1024) { 12987 wmi_err("ba win size from TLV is Invalid"); 12988 return QDF_STATUS_E_INVAL; 12989 } 12990 12991 ext_params->reo_win_size = WMI_RX_PARAM_EXT_REO_WIN_SIZE_GET( 12992 ext_params_tlv->mgmt_rx_params_ext_dword1); 12993 if (ext_params->reo_win_size > 2048) { 12994 wmi_err("reo win size from TLV is Invalid"); 12995 return QDF_STATUS_E_INVAL; 12996 } 12997 } else { 12998 ext_params->ba_win_size = 0; 12999 ext_params->reo_win_size = 0; 13000 } 13001 13002 return QDF_STATUS_SUCCESS; 13003 } 13004 13005 #ifdef WLAN_MGMT_RX_REO_SUPPORT 13006 /** 13007 * extract_mgmt_rx_fw_consumed_tlv() - extract MGMT Rx FW consumed event 13008 * @wmi_handle: wmi handle 13009 * @evt_buf: pointer to event buffer 13010 * @params: Pointer to MGMT Rx REO parameters 13011 * 13012 * Return: QDF_STATUS_SUCCESS for success or error code 13013 */ 13014 static QDF_STATUS 13015 extract_mgmt_rx_fw_consumed_tlv(wmi_unified_t wmi_handle, 13016 void *evt_buf, 13017 struct mgmt_rx_reo_params *params) 13018 { 13019 WMI_MGMT_RX_FW_CONSUMED_EVENTID_param_tlvs *param_tlvs; 13020 wmi_mgmt_rx_fw_consumed_hdr *ev_hdr; 13021 13022 param_tlvs = evt_buf; 13023 if (!param_tlvs) { 13024 wmi_err("param_tlvs is NULL"); 13025 return QDF_STATUS_E_INVAL; 13026 } 13027 13028 ev_hdr = param_tlvs->hdr; 13029 if (!params) { 13030 wmi_err("Rx REO parameters is NULL"); 13031 return QDF_STATUS_E_INVAL; 13032 } 13033 13034 params->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host( 13035 wmi_handle, 13036 ev_hdr->pdev_id); 13037 params->valid = WMI_MGMT_RX_FW_CONSUMED_PARAM_MGMT_PKT_CTR_VALID_GET( 13038 ev_hdr->mgmt_pkt_ctr_info); 13039 params->global_timestamp = ev_hdr->global_timestamp; 13040 params->mgmt_pkt_ctr = WMI_MGMT_RX_FW_CONSUMED_PARAM_MGMT_PKT_CTR_GET( 13041 ev_hdr->mgmt_pkt_ctr_info); 13042 params->duration_us = ev_hdr->rx_ppdu_duration_us; 13043 params->start_timestamp = params->global_timestamp; 13044 params->end_timestamp = params->start_timestamp + 13045 params->duration_us; 13046 13047 return QDF_STATUS_SUCCESS; 13048 } 13049 13050 /** 13051 * extract_mgmt_rx_reo_params_tlv() - extract MGMT Rx REO params from 13052 * MGMT_RX_EVENT_ID 13053 * @wmi_handle: wmi handle 13054 * @evt_buf: pointer to event buffer 13055 * @reo_params: Pointer to MGMT Rx REO parameters 13056 * 13057 * Return: QDF_STATUS_SUCCESS for success or error code 13058 */ 13059 static QDF_STATUS extract_mgmt_rx_reo_params_tlv(wmi_unified_t wmi_handle, 13060 void *evt_buf, struct mgmt_rx_reo_params *reo_params) 13061 { 13062 WMI_MGMT_RX_EVENTID_param_tlvs *param_tlvs; 13063 wmi_mgmt_rx_reo_params *reo_params_tlv; 13064 wmi_mgmt_rx_hdr *ev_hdr; 13065 13066 param_tlvs = evt_buf; 13067 if (!param_tlvs) { 13068 wmi_err("param_tlvs is NULL"); 13069 return QDF_STATUS_E_INVAL; 13070 } 13071 13072 ev_hdr = param_tlvs->hdr; 13073 if (!ev_hdr) { 13074 wmi_err("Rx event is NULL"); 13075 return QDF_STATUS_E_INVAL; 13076 } 13077 13078 reo_params_tlv = param_tlvs->reo_params; 13079 if (!reo_params_tlv) { 13080 wmi_err("mgmt_rx_reo_params TLV is not sent by FW"); 13081 return QDF_STATUS_E_INVAL; 13082 } 13083 13084 if (!reo_params) { 13085 wmi_err("MGMT Rx REO params is NULL"); 13086 return QDF_STATUS_E_INVAL; 13087 } 13088 13089 reo_params->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host( 13090 wmi_handle, 13091 ev_hdr->pdev_id); 13092 reo_params->valid = WMI_MGMT_RX_REO_PARAM_MGMT_PKT_CTR_VALID_GET( 13093 reo_params_tlv->mgmt_pkt_ctr_link_info); 13094 reo_params->global_timestamp = reo_params_tlv->global_timestamp; 13095 reo_params->mgmt_pkt_ctr = WMI_MGMT_RX_REO_PARAM_MGMT_PKT_CTR_GET( 13096 reo_params_tlv->mgmt_pkt_ctr_link_info); 13097 reo_params->duration_us = reo_params_tlv->rx_ppdu_duration_us; 13098 reo_params->start_timestamp = reo_params->global_timestamp; 13099 reo_params->end_timestamp = reo_params->start_timestamp + 13100 reo_params->duration_us; 13101 13102 return QDF_STATUS_SUCCESS; 13103 } 13104 13105 /** 13106 * send_mgmt_rx_reo_filter_config_cmd_tlv() - Send MGMT Rx REO filter 13107 * configuration command 13108 * @wmi_handle: wmi handle 13109 * @pdev_id: pdev ID of the radio 13110 * @filter: Pointer to MGMT Rx REO filter 13111 * 13112 * Return: QDF_STATUS_SUCCESS for success or error code 13113 */ 13114 static QDF_STATUS send_mgmt_rx_reo_filter_config_cmd_tlv( 13115 wmi_unified_t wmi_handle, 13116 uint8_t pdev_id, 13117 struct mgmt_rx_reo_filter *filter) 13118 { 13119 QDF_STATUS ret; 13120 wmi_buf_t buf; 13121 wmi_mgmt_rx_reo_filter_configuration_cmd_fixed_param *cmd; 13122 size_t len = sizeof(*cmd); 13123 13124 if (!filter) { 13125 wmi_err("mgmt_rx_reo_filter is NULL"); 13126 return QDF_STATUS_E_INVAL; 13127 } 13128 13129 buf = wmi_buf_alloc(wmi_handle, len); 13130 if (!buf) { 13131 wmi_err("wmi_buf_alloc failed"); 13132 return QDF_STATUS_E_NOMEM; 13133 } 13134 13135 cmd = (wmi_mgmt_rx_reo_filter_configuration_cmd_fixed_param *) 13136 wmi_buf_data(buf); 13137 13138 WMITLV_SET_HDR(&cmd->tlv_header, 13139 WMITLV_TAG_STRUC_wmi_mgmt_rx_reo_filter_configuration_cmd_fixed_param, 13140 WMITLV_GET_STRUCT_TLVLEN(wmi_mgmt_rx_reo_filter_configuration_cmd_fixed_param)); 13141 13142 cmd->pdev_id = wmi_handle->ops->convert_host_pdev_id_to_target( 13143 wmi_handle, 13144 pdev_id); 13145 cmd->filter_low = filter->low; 13146 cmd->filter_high = filter->high; 13147 13148 wmi_mtrace(WMI_MGMT_RX_REO_FILTER_CONFIGURATION_CMDID, NO_SESSION, 0); 13149 ret = wmi_unified_cmd_send( 13150 wmi_handle, buf, len, 13151 WMI_MGMT_RX_REO_FILTER_CONFIGURATION_CMDID); 13152 13153 if (QDF_IS_STATUS_ERROR(ret)) { 13154 wmi_err("Failed to send WMI command"); 13155 wmi_buf_free(buf); 13156 } 13157 13158 return ret; 13159 } 13160 #endif 13161 13162 /** 13163 * extract_frame_pn_params_tlv() - extract PN params from event 13164 * @wmi_handle: wmi handle 13165 * @evt_buf: pointer to event buffer 13166 * @pn_params: Pointer to Frame PN params 13167 * 13168 * Return: QDF_STATUS_SUCCESS for success or error code 13169 */ 13170 static QDF_STATUS extract_frame_pn_params_tlv(wmi_unified_t wmi_handle, 13171 void *evt_buf, 13172 struct frame_pn_params *pn_params) 13173 { 13174 WMI_MGMT_RX_EVENTID_param_tlvs *param_tlvs; 13175 wmi_frame_pn_params *pn_params_tlv; 13176 13177 if (!is_service_enabled_tlv(wmi_handle, 13178 WMI_SERVICE_PN_REPLAY_CHECK_SUPPORT)) 13179 return QDF_STATUS_SUCCESS; 13180 13181 param_tlvs = evt_buf; 13182 if (!param_tlvs) { 13183 wmi_err("Got NULL point message from FW"); 13184 return QDF_STATUS_E_INVAL; 13185 } 13186 13187 if (!pn_params) { 13188 wmi_err("PN Params is NULL"); 13189 return QDF_STATUS_E_INVAL; 13190 } 13191 13192 /* PN Params TLV will be populated only if WMI_RXERR_PN error is 13193 * found by target 13194 */ 13195 pn_params_tlv = param_tlvs->pn_params; 13196 if (!pn_params_tlv) 13197 return QDF_STATUS_SUCCESS; 13198 13199 qdf_mem_copy(pn_params->curr_pn, pn_params_tlv->cur_pn, 13200 sizeof(pn_params->curr_pn)); 13201 qdf_mem_copy(pn_params->prev_pn, pn_params_tlv->prev_pn, 13202 sizeof(pn_params->prev_pn)); 13203 13204 return QDF_STATUS_SUCCESS; 13205 } 13206 13207 /** 13208 * extract_is_conn_ap_frm_param_tlv() - extract is_conn_ap_frame param from 13209 * event 13210 * @wmi_handle: wmi handle 13211 * @evt_buf: pointer to event buffer 13212 * @is_conn_ap: Pointer for is_conn_ap frame 13213 * 13214 * Return: QDF_STATUS_SUCCESS for success or error code 13215 */ 13216 static QDF_STATUS extract_is_conn_ap_frm_param_tlv( 13217 wmi_unified_t wmi_handle, 13218 void *evt_buf, 13219 struct frm_conn_ap *is_conn_ap) 13220 { 13221 WMI_MGMT_RX_EVENTID_param_tlvs *param_tlvs; 13222 wmi_is_my_mgmt_frame *my_frame_tlv; 13223 13224 param_tlvs = evt_buf; 13225 if (!param_tlvs) { 13226 wmi_err("Got NULL point message from FW"); 13227 return QDF_STATUS_E_INVAL; 13228 } 13229 13230 if (!is_conn_ap) { 13231 wmi_err(" is connected ap param is NULL"); 13232 return QDF_STATUS_E_INVAL; 13233 } 13234 13235 my_frame_tlv = param_tlvs->my_frame; 13236 if (!my_frame_tlv) 13237 return QDF_STATUS_SUCCESS; 13238 13239 is_conn_ap->mgmt_frm_sub_type = my_frame_tlv->mgmt_frm_sub_type; 13240 is_conn_ap->is_conn_ap_frm = my_frame_tlv->is_my_frame; 13241 13242 return QDF_STATUS_SUCCESS; 13243 } 13244 13245 /** 13246 * extract_vdev_roam_param_tlv() - extract vdev roam param from event 13247 * @wmi_handle: wmi handle 13248 * @evt_buf: pointer to event buffer 13249 * @param: Pointer to hold roam param 13250 * 13251 * Return: QDF_STATUS_SUCCESS for success or error code 13252 */ 13253 static QDF_STATUS extract_vdev_roam_param_tlv(wmi_unified_t wmi_handle, 13254 void *evt_buf, wmi_host_roam_event *param) 13255 { 13256 WMI_ROAM_EVENTID_param_tlvs *param_buf; 13257 wmi_roam_event_fixed_param *evt; 13258 13259 param_buf = (WMI_ROAM_EVENTID_param_tlvs *) evt_buf; 13260 if (!param_buf) { 13261 wmi_err("Invalid roam event buffer"); 13262 return QDF_STATUS_E_INVAL; 13263 } 13264 13265 evt = param_buf->fixed_param; 13266 qdf_mem_zero(param, sizeof(*param)); 13267 13268 param->vdev_id = evt->vdev_id; 13269 param->reason = evt->reason; 13270 param->rssi = evt->rssi; 13271 13272 return QDF_STATUS_SUCCESS; 13273 } 13274 13275 /** 13276 * extract_vdev_scan_ev_param_tlv() - extract vdev scan param from event 13277 * @wmi_handle: wmi handle 13278 * @evt_buf: pointer to event buffer 13279 * @param: Pointer to hold vdev scan param 13280 * 13281 * Return: QDF_STATUS_SUCCESS for success or error code 13282 */ 13283 static QDF_STATUS extract_vdev_scan_ev_param_tlv(wmi_unified_t wmi_handle, 13284 void *evt_buf, struct scan_event *param) 13285 { 13286 WMI_SCAN_EVENTID_param_tlvs *param_buf = NULL; 13287 wmi_scan_event_fixed_param *evt = NULL; 13288 13289 param_buf = (WMI_SCAN_EVENTID_param_tlvs *) evt_buf; 13290 evt = param_buf->fixed_param; 13291 13292 qdf_mem_zero(param, sizeof(*param)); 13293 13294 switch (evt->event) { 13295 case WMI_SCAN_EVENT_STARTED: 13296 param->type = SCAN_EVENT_TYPE_STARTED; 13297 break; 13298 case WMI_SCAN_EVENT_COMPLETED: 13299 param->type = SCAN_EVENT_TYPE_COMPLETED; 13300 break; 13301 case WMI_SCAN_EVENT_BSS_CHANNEL: 13302 param->type = SCAN_EVENT_TYPE_BSS_CHANNEL; 13303 break; 13304 case WMI_SCAN_EVENT_FOREIGN_CHANNEL: 13305 param->type = SCAN_EVENT_TYPE_FOREIGN_CHANNEL; 13306 break; 13307 case WMI_SCAN_EVENT_DEQUEUED: 13308 param->type = SCAN_EVENT_TYPE_DEQUEUED; 13309 break; 13310 case WMI_SCAN_EVENT_PREEMPTED: 13311 param->type = SCAN_EVENT_TYPE_PREEMPTED; 13312 break; 13313 case WMI_SCAN_EVENT_START_FAILED: 13314 param->type = SCAN_EVENT_TYPE_START_FAILED; 13315 break; 13316 case WMI_SCAN_EVENT_RESTARTED: 13317 param->type = SCAN_EVENT_TYPE_RESTARTED; 13318 break; 13319 case WMI_SCAN_EVENT_FOREIGN_CHANNEL_EXIT: 13320 param->type = SCAN_EVENT_TYPE_FOREIGN_CHANNEL_EXIT; 13321 break; 13322 case WMI_SCAN_EVENT_MAX: 13323 default: 13324 param->type = SCAN_EVENT_TYPE_MAX; 13325 break; 13326 }; 13327 13328 switch (evt->reason) { 13329 case WMI_SCAN_REASON_NONE: 13330 param->reason = SCAN_REASON_NONE; 13331 break; 13332 case WMI_SCAN_REASON_COMPLETED: 13333 param->reason = SCAN_REASON_COMPLETED; 13334 break; 13335 case WMI_SCAN_REASON_CANCELLED: 13336 param->reason = SCAN_REASON_CANCELLED; 13337 break; 13338 case WMI_SCAN_REASON_PREEMPTED: 13339 param->reason = SCAN_REASON_PREEMPTED; 13340 break; 13341 case WMI_SCAN_REASON_TIMEDOUT: 13342 param->reason = SCAN_REASON_TIMEDOUT; 13343 break; 13344 case WMI_SCAN_REASON_INTERNAL_FAILURE: 13345 param->reason = SCAN_REASON_INTERNAL_FAILURE; 13346 break; 13347 case WMI_SCAN_REASON_SUSPENDED: 13348 param->reason = SCAN_REASON_SUSPENDED; 13349 break; 13350 case WMI_SCAN_REASON_DFS_VIOLATION: 13351 param->reason = SCAN_REASON_DFS_VIOLATION; 13352 break; 13353 case WMI_SCAN_REASON_MAX: 13354 param->reason = SCAN_REASON_MAX; 13355 break; 13356 default: 13357 param->reason = SCAN_REASON_MAX; 13358 break; 13359 }; 13360 13361 param->chan_freq = evt->channel_freq; 13362 param->requester = evt->requestor; 13363 param->scan_id = evt->scan_id; 13364 param->vdev_id = evt->vdev_id; 13365 param->timestamp = evt->tsf_timestamp; 13366 13367 return QDF_STATUS_SUCCESS; 13368 } 13369 13370 #ifdef FEATURE_WLAN_SCAN_PNO 13371 /** 13372 * extract_nlo_match_ev_param_tlv() - extract NLO match param from event 13373 * @wmi_handle: pointer to WMI handle 13374 * @evt_buf: pointer to WMI event buffer 13375 * @param: pointer to scan event param for NLO match 13376 * 13377 * Return: QDF_STATUS_SUCCESS for success or error code 13378 */ 13379 static QDF_STATUS extract_nlo_match_ev_param_tlv(wmi_unified_t wmi_handle, 13380 void *evt_buf, 13381 struct scan_event *param) 13382 { 13383 WMI_NLO_MATCH_EVENTID_param_tlvs *param_buf = evt_buf; 13384 wmi_nlo_event *evt = param_buf->fixed_param; 13385 13386 qdf_mem_zero(param, sizeof(*param)); 13387 13388 param->type = SCAN_EVENT_TYPE_NLO_MATCH; 13389 param->vdev_id = evt->vdev_id; 13390 13391 return QDF_STATUS_SUCCESS; 13392 } 13393 13394 /** 13395 * extract_nlo_complete_ev_param_tlv() - extract NLO complete param from event 13396 * @wmi_handle: pointer to WMI handle 13397 * @evt_buf: pointer to WMI event buffer 13398 * @param: pointer to scan event param for NLO complete 13399 * 13400 * Return: QDF_STATUS_SUCCESS for success or error code 13401 */ 13402 static QDF_STATUS extract_nlo_complete_ev_param_tlv(wmi_unified_t wmi_handle, 13403 void *evt_buf, 13404 struct scan_event *param) 13405 { 13406 WMI_NLO_SCAN_COMPLETE_EVENTID_param_tlvs *param_buf = evt_buf; 13407 wmi_nlo_event *evt = param_buf->fixed_param; 13408 13409 qdf_mem_zero(param, sizeof(*param)); 13410 13411 param->type = SCAN_EVENT_TYPE_NLO_COMPLETE; 13412 param->vdev_id = evt->vdev_id; 13413 13414 return QDF_STATUS_SUCCESS; 13415 } 13416 #endif 13417 13418 /** 13419 * extract_unit_test_tlv() - extract unit test data 13420 * @wmi_handle: wmi handle 13421 * @evt_buf: pointer to event buffer 13422 * @unit_test: pointer to hold unit test data 13423 * @maxspace: Amount of space in evt_buf 13424 * 13425 * Return: QDF_STATUS_SUCCESS for success or error code 13426 */ 13427 static QDF_STATUS extract_unit_test_tlv(wmi_unified_t wmi_handle, 13428 void *evt_buf, wmi_unit_test_event *unit_test, uint32_t maxspace) 13429 { 13430 WMI_UNIT_TEST_EVENTID_param_tlvs *param_buf; 13431 wmi_unit_test_event_fixed_param *ev_param; 13432 uint32_t num_bufp; 13433 uint32_t copy_size; 13434 uint8_t *bufp; 13435 13436 param_buf = (WMI_UNIT_TEST_EVENTID_param_tlvs *) evt_buf; 13437 ev_param = param_buf->fixed_param; 13438 bufp = param_buf->bufp; 13439 num_bufp = param_buf->num_bufp; 13440 unit_test->vdev_id = ev_param->vdev_id; 13441 unit_test->module_id = ev_param->module_id; 13442 unit_test->diag_token = ev_param->diag_token; 13443 unit_test->flag = ev_param->flag; 13444 unit_test->payload_len = ev_param->payload_len; 13445 wmi_debug("vdev_id:%d mod_id:%d diag_token:%d flag:%d", 13446 ev_param->vdev_id, 13447 ev_param->module_id, 13448 ev_param->diag_token, 13449 ev_param->flag); 13450 wmi_debug("Unit-test data given below %d", num_bufp); 13451 qdf_trace_hex_dump(QDF_MODULE_ID_WMI, QDF_TRACE_LEVEL_DEBUG, 13452 bufp, num_bufp); 13453 copy_size = (num_bufp < maxspace) ? num_bufp : maxspace; 13454 qdf_mem_copy(unit_test->buffer, bufp, copy_size); 13455 unit_test->buffer_len = copy_size; 13456 13457 return QDF_STATUS_SUCCESS; 13458 } 13459 13460 /** 13461 * extract_pdev_ext_stats_tlv() - extract extended pdev stats from event 13462 * @wmi_handle: wmi handle 13463 * @evt_buf: pointer to event buffer 13464 * @index: Index into extended pdev stats 13465 * @pdev_ext_stats: Pointer to hold extended pdev stats 13466 * 13467 * Return: QDF_STATUS_SUCCESS for success or error code 13468 */ 13469 static QDF_STATUS extract_pdev_ext_stats_tlv(wmi_unified_t wmi_handle, 13470 void *evt_buf, uint32_t index, wmi_host_pdev_ext_stats *pdev_ext_stats) 13471 { 13472 WMI_UPDATE_STATS_EVENTID_param_tlvs *param_buf; 13473 wmi_pdev_extd_stats *ev; 13474 13475 param_buf = evt_buf; 13476 if (!param_buf) 13477 return QDF_STATUS_E_FAILURE; 13478 13479 if (!param_buf->pdev_extd_stats) 13480 return QDF_STATUS_E_FAILURE; 13481 13482 ev = param_buf->pdev_extd_stats + index; 13483 13484 pdev_ext_stats->pdev_id = 13485 wmi_handle->ops->convert_target_pdev_id_to_host( 13486 wmi_handle, 13487 ev->pdev_id); 13488 pdev_ext_stats->my_rx_count = ev->my_rx_count; 13489 pdev_ext_stats->rx_matched_11ax_msdu_cnt = ev->rx_matched_11ax_msdu_cnt; 13490 pdev_ext_stats->rx_other_11ax_msdu_cnt = ev->rx_other_11ax_msdu_cnt; 13491 13492 return QDF_STATUS_SUCCESS; 13493 } 13494 13495 /** 13496 * extract_bcn_stats_tlv() - extract bcn stats from event 13497 * @wmi_handle: wmi handle 13498 * @evt_buf: pointer to event buffer 13499 * @index: Index into vdev stats 13500 * @bcn_stats: Pointer to hold bcn stats 13501 * 13502 * Return: QDF_STATUS_SUCCESS for success or error code 13503 */ 13504 static QDF_STATUS extract_bcn_stats_tlv(wmi_unified_t wmi_handle, 13505 void *evt_buf, uint32_t index, wmi_host_bcn_stats *bcn_stats) 13506 { 13507 WMI_UPDATE_STATS_EVENTID_param_tlvs *param_buf; 13508 wmi_stats_event_fixed_param *ev_param; 13509 uint8_t *data; 13510 13511 param_buf = (WMI_UPDATE_STATS_EVENTID_param_tlvs *) evt_buf; 13512 ev_param = (wmi_stats_event_fixed_param *) param_buf->fixed_param; 13513 data = (uint8_t *) param_buf->data; 13514 13515 if (index < ev_param->num_bcn_stats) { 13516 wmi_bcn_stats *ev = (wmi_bcn_stats *) ((data) + 13517 ((ev_param->num_pdev_stats) * sizeof(wmi_pdev_stats)) + 13518 ((ev_param->num_vdev_stats) * sizeof(wmi_vdev_stats)) + 13519 ((ev_param->num_peer_stats) * sizeof(wmi_peer_stats)) + 13520 ((ev_param->num_chan_stats) * sizeof(wmi_chan_stats)) + 13521 ((ev_param->num_mib_stats) * sizeof(wmi_mib_stats)) + 13522 (index * sizeof(wmi_bcn_stats))); 13523 13524 bcn_stats->vdev_id = ev->vdev_id; 13525 bcn_stats->tx_bcn_succ_cnt = ev->tx_bcn_succ_cnt; 13526 bcn_stats->tx_bcn_outage_cnt = ev->tx_bcn_outage_cnt; 13527 } 13528 13529 return QDF_STATUS_SUCCESS; 13530 } 13531 13532 /** 13533 * extract_vdev_prb_fils_stats_tlv() - extract vdev probe and fils 13534 * stats from event 13535 * @wmi_handle: wmi handle 13536 * @evt_buf: pointer to event buffer 13537 * @index: Index into vdev stats 13538 * @vdev_stats: Pointer to hold vdev probe and fils stats 13539 * 13540 * Return: QDF_STATUS_SUCCESS for success or error code 13541 */ 13542 static QDF_STATUS 13543 extract_vdev_prb_fils_stats_tlv(wmi_unified_t wmi_handle, 13544 void *evt_buf, uint32_t index, 13545 struct wmi_host_vdev_prb_fils_stats *vdev_stats) 13546 { 13547 WMI_UPDATE_STATS_EVENTID_param_tlvs *param_buf; 13548 wmi_vdev_extd_stats *ev; 13549 13550 param_buf = (WMI_UPDATE_STATS_EVENTID_param_tlvs *)evt_buf; 13551 13552 if (param_buf->vdev_extd_stats) { 13553 ev = (wmi_vdev_extd_stats *)(param_buf->vdev_extd_stats + 13554 index); 13555 vdev_stats->vdev_id = ev->vdev_id; 13556 vdev_stats->fd_succ_cnt = ev->fd_succ_cnt; 13557 vdev_stats->fd_fail_cnt = ev->fd_fail_cnt; 13558 vdev_stats->unsolicited_prb_succ_cnt = 13559 ev->unsolicited_prb_succ_cnt; 13560 vdev_stats->unsolicited_prb_fail_cnt = 13561 ev->unsolicited_prb_fail_cnt; 13562 wmi_debug("vdev: %d, fd_s: %d, fd_f: %d, prb_s: %d, prb_f: %d", 13563 ev->vdev_id, ev->fd_succ_cnt, ev->fd_fail_cnt, 13564 ev->unsolicited_prb_succ_cnt, 13565 ev->unsolicited_prb_fail_cnt); 13566 } 13567 13568 return QDF_STATUS_SUCCESS; 13569 } 13570 13571 /** 13572 * extract_bcnflt_stats_tlv() - extract bcn fault stats from event 13573 * @wmi_handle: wmi handle 13574 * @evt_buf: pointer to event buffer 13575 * @index: Index into bcn fault stats 13576 * @bcnflt_stats: Pointer to hold bcn fault stats 13577 * 13578 * Return: QDF_STATUS_SUCCESS for success or error code 13579 */ 13580 static QDF_STATUS extract_bcnflt_stats_tlv(wmi_unified_t wmi_handle, 13581 void *evt_buf, uint32_t index, wmi_host_bcnflt_stats *bcnflt_stats) 13582 { 13583 return QDF_STATUS_SUCCESS; 13584 } 13585 13586 /** 13587 * extract_chan_stats_tlv() - extract chan stats from event 13588 * @wmi_handle: wmi handle 13589 * @evt_buf: pointer to event buffer 13590 * @index: Index into chan stats 13591 * @chan_stats: Pointer to hold chan stats 13592 * 13593 * Return: QDF_STATUS_SUCCESS for success or error code 13594 */ 13595 static QDF_STATUS extract_chan_stats_tlv(wmi_unified_t wmi_handle, 13596 void *evt_buf, uint32_t index, wmi_host_chan_stats *chan_stats) 13597 { 13598 WMI_UPDATE_STATS_EVENTID_param_tlvs *param_buf; 13599 wmi_stats_event_fixed_param *ev_param; 13600 uint8_t *data; 13601 13602 param_buf = (WMI_UPDATE_STATS_EVENTID_param_tlvs *) evt_buf; 13603 ev_param = (wmi_stats_event_fixed_param *) param_buf->fixed_param; 13604 data = (uint8_t *) param_buf->data; 13605 13606 if (index < ev_param->num_chan_stats) { 13607 wmi_chan_stats *ev = (wmi_chan_stats *) ((data) + 13608 ((ev_param->num_pdev_stats) * sizeof(wmi_pdev_stats)) + 13609 ((ev_param->num_vdev_stats) * sizeof(wmi_vdev_stats)) + 13610 ((ev_param->num_peer_stats) * sizeof(wmi_peer_stats)) + 13611 (index * sizeof(wmi_chan_stats))); 13612 13613 13614 /* Non-TLV doesn't have num_chan_stats */ 13615 chan_stats->chan_mhz = ev->chan_mhz; 13616 chan_stats->sampling_period_us = ev->sampling_period_us; 13617 chan_stats->rx_clear_count = ev->rx_clear_count; 13618 chan_stats->tx_duration_us = ev->tx_duration_us; 13619 chan_stats->rx_duration_us = ev->rx_duration_us; 13620 } 13621 13622 return QDF_STATUS_SUCCESS; 13623 } 13624 13625 /** 13626 * extract_profile_ctx_tlv() - extract profile context from event 13627 * @wmi_handle: wmi handle 13628 * @evt_buf: pointer to event buffer 13629 * @profile_ctx: Pointer to hold profile context 13630 * 13631 * Return: QDF_STATUS_SUCCESS for success or error code 13632 */ 13633 static QDF_STATUS extract_profile_ctx_tlv(wmi_unified_t wmi_handle, 13634 void *evt_buf, wmi_host_wlan_profile_ctx_t *profile_ctx) 13635 { 13636 WMI_WLAN_PROFILE_DATA_EVENTID_param_tlvs *param_buf; 13637 13638 wmi_wlan_profile_ctx_t *ev; 13639 13640 param_buf = (WMI_WLAN_PROFILE_DATA_EVENTID_param_tlvs *)evt_buf; 13641 if (!param_buf) { 13642 wmi_err("Invalid profile data event buf"); 13643 return QDF_STATUS_E_INVAL; 13644 } 13645 13646 ev = param_buf->profile_ctx; 13647 13648 profile_ctx->tot = ev->tot; 13649 profile_ctx->tx_msdu_cnt = ev->tx_msdu_cnt; 13650 profile_ctx->tx_mpdu_cnt = ev->tx_mpdu_cnt; 13651 profile_ctx->tx_ppdu_cnt = ev->tx_ppdu_cnt; 13652 profile_ctx->rx_msdu_cnt = ev->rx_msdu_cnt; 13653 profile_ctx->rx_mpdu_cnt = ev->rx_mpdu_cnt; 13654 profile_ctx->bin_count = ev->bin_count; 13655 13656 return QDF_STATUS_SUCCESS; 13657 } 13658 13659 /** 13660 * extract_profile_data_tlv() - extract profile data from event 13661 * @wmi_handle: wmi handle 13662 * @evt_buf: pointer to event buffer 13663 * @idx: profile stats index to extract 13664 * @profile_data: Pointer to hold profile data 13665 * 13666 * Return: QDF_STATUS_SUCCESS for success or error code 13667 */ 13668 static QDF_STATUS extract_profile_data_tlv(wmi_unified_t wmi_handle, 13669 void *evt_buf, uint8_t idx, wmi_host_wlan_profile_t *profile_data) 13670 { 13671 WMI_WLAN_PROFILE_DATA_EVENTID_param_tlvs *param_buf; 13672 wmi_wlan_profile_t *ev; 13673 13674 param_buf = (WMI_WLAN_PROFILE_DATA_EVENTID_param_tlvs *)evt_buf; 13675 if (!param_buf) { 13676 wmi_err("Invalid profile data event buf"); 13677 return QDF_STATUS_E_INVAL; 13678 } 13679 13680 ev = ¶m_buf->profile_data[idx]; 13681 profile_data->id = ev->id; 13682 profile_data->cnt = ev->cnt; 13683 profile_data->tot = ev->tot; 13684 profile_data->min = ev->min; 13685 profile_data->max = ev->max; 13686 profile_data->hist_intvl = ev->hist_intvl; 13687 qdf_mem_copy(profile_data->hist, ev->hist, sizeof(profile_data->hist)); 13688 13689 return QDF_STATUS_SUCCESS; 13690 } 13691 13692 /** 13693 * extract_pdev_utf_event_tlv() - extract UTF data info from event 13694 * @wmi_handle: WMI handle 13695 * @evt_buf: Pointer to event buffer 13696 * @event: Pointer to hold data 13697 * 13698 * Return: QDF_STATUS_SUCCESS for success or error code 13699 */ 13700 static QDF_STATUS extract_pdev_utf_event_tlv(wmi_unified_t wmi_handle, 13701 uint8_t *evt_buf, 13702 struct wmi_host_pdev_utf_event *event) 13703 { 13704 WMI_PDEV_UTF_EVENTID_param_tlvs *param_buf; 13705 struct wmi_host_utf_seg_header_info *seg_hdr; 13706 13707 param_buf = (WMI_PDEV_UTF_EVENTID_param_tlvs *)evt_buf; 13708 event->data = param_buf->data; 13709 event->datalen = param_buf->num_data; 13710 13711 if (event->datalen < sizeof(struct wmi_host_utf_seg_header_info)) { 13712 wmi_err("Invalid datalen: %d", event->datalen); 13713 return QDF_STATUS_E_INVAL; 13714 } 13715 seg_hdr = (struct wmi_host_utf_seg_header_info *)param_buf->data; 13716 /* Set pdev_id=1 until FW adds support to include pdev_id */ 13717 event->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host( 13718 wmi_handle, 13719 seg_hdr->pdev_id); 13720 13721 return QDF_STATUS_SUCCESS; 13722 } 13723 13724 #ifdef WLAN_SUPPORT_RF_CHARACTERIZATION 13725 static QDF_STATUS extract_num_rf_characterization_entries_tlv(wmi_unified_t wmi_handle, 13726 uint8_t *event, 13727 uint32_t *num_rf_characterization_entries) 13728 { 13729 WMI_CHAN_RF_CHARACTERIZATION_INFO_EVENTID_param_tlvs *param_buf; 13730 13731 param_buf = (WMI_CHAN_RF_CHARACTERIZATION_INFO_EVENTID_param_tlvs *)event; 13732 if (!param_buf) 13733 return QDF_STATUS_E_INVAL; 13734 13735 *num_rf_characterization_entries = 13736 param_buf->num_wmi_chan_rf_characterization_info; 13737 13738 return QDF_STATUS_SUCCESS; 13739 } 13740 13741 static QDF_STATUS extract_rf_characterization_entries_tlv(wmi_unified_t wmi_handle, 13742 uint8_t *event, 13743 uint32_t num_rf_characterization_entries, 13744 struct wmi_host_rf_characterization_event_param *rf_characterization_entries) 13745 { 13746 WMI_CHAN_RF_CHARACTERIZATION_INFO_EVENTID_param_tlvs *param_buf; 13747 WMI_CHAN_RF_CHARACTERIZATION_INFO *wmi_rf_characterization_entry; 13748 uint8_t ix; 13749 13750 param_buf = (WMI_CHAN_RF_CHARACTERIZATION_INFO_EVENTID_param_tlvs *)event; 13751 if (!param_buf) 13752 return QDF_STATUS_E_INVAL; 13753 13754 wmi_rf_characterization_entry = 13755 param_buf->wmi_chan_rf_characterization_info; 13756 if (!wmi_rf_characterization_entry) 13757 return QDF_STATUS_E_INVAL; 13758 13759 /* 13760 * Using num_wmi_chan_rf_characterization instead of param_buf value 13761 * since memory for rf_characterization_entries was allocated using 13762 * the former. 13763 */ 13764 for (ix = 0; ix < num_rf_characterization_entries; ix++) { 13765 rf_characterization_entries[ix].freq = 13766 WMI_CHAN_RF_CHARACTERIZATION_FREQ_GET( 13767 &wmi_rf_characterization_entry[ix]); 13768 13769 rf_characterization_entries[ix].bw = 13770 WMI_CHAN_RF_CHARACTERIZATION_BW_GET( 13771 &wmi_rf_characterization_entry[ix]); 13772 13773 rf_characterization_entries[ix].chan_metric = 13774 WMI_CHAN_RF_CHARACTERIZATION_CHAN_METRIC_GET( 13775 &wmi_rf_characterization_entry[ix]); 13776 13777 wmi_nofl_debug("rf_characterization_entries[%u]: freq: %u, " 13778 "bw: %u, chan_metric: %u", 13779 ix, rf_characterization_entries[ix].freq, 13780 rf_characterization_entries[ix].bw, 13781 rf_characterization_entries[ix].chan_metric); 13782 } 13783 13784 return QDF_STATUS_SUCCESS; 13785 } 13786 #endif 13787 13788 #ifdef WLAN_FEATURE_11BE 13789 static void 13790 extract_11be_chainmask(struct wlan_psoc_host_chainmask_capabilities *cap, 13791 WMI_MAC_PHY_CHAINMASK_CAPABILITY *chainmask_caps) 13792 { 13793 cap->supports_chan_width_320 = 13794 WMI_SUPPORT_CHAN_WIDTH_320_GET(chainmask_caps->supported_flags); 13795 cap->supports_aDFS_320 = 13796 WMI_SUPPORT_ADFS_320_GET(chainmask_caps->supported_flags); 13797 } 13798 #else 13799 static void 13800 extract_11be_chainmask(struct wlan_psoc_host_chainmask_capabilities *cap, 13801 WMI_MAC_PHY_CHAINMASK_CAPABILITY *chainmask_caps) 13802 { 13803 } 13804 #endif /* WLAN_FEATURE_11BE */ 13805 13806 /** 13807 * extract_chainmask_tables_tlv() - extract chain mask tables from event 13808 * @wmi_handle: wmi handle 13809 * @event: pointer to event buffer 13810 * @chainmask_table: Pointer to hold extracted chainmask tables 13811 * 13812 * Return: QDF_STATUS_SUCCESS for success or error code 13813 */ 13814 static QDF_STATUS extract_chainmask_tables_tlv(wmi_unified_t wmi_handle, 13815 uint8_t *event, struct wlan_psoc_host_chainmask_table *chainmask_table) 13816 { 13817 WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *param_buf; 13818 WMI_MAC_PHY_CHAINMASK_CAPABILITY *chainmask_caps; 13819 WMI_SOC_MAC_PHY_HW_MODE_CAPS *hw_caps; 13820 uint8_t i = 0, j = 0; 13821 uint32_t num_mac_phy_chainmask_caps = 0; 13822 13823 param_buf = (WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *) event; 13824 if (!param_buf) 13825 return QDF_STATUS_E_INVAL; 13826 13827 hw_caps = param_buf->soc_hw_mode_caps; 13828 if (!hw_caps) 13829 return QDF_STATUS_E_INVAL; 13830 13831 if ((!hw_caps->num_chainmask_tables) || 13832 (hw_caps->num_chainmask_tables > PSOC_MAX_CHAINMASK_TABLES) || 13833 (hw_caps->num_chainmask_tables > 13834 param_buf->num_mac_phy_chainmask_combo)) 13835 return QDF_STATUS_E_INVAL; 13836 13837 chainmask_caps = param_buf->mac_phy_chainmask_caps; 13838 13839 if (!chainmask_caps) 13840 return QDF_STATUS_E_INVAL; 13841 13842 for (i = 0; i < hw_caps->num_chainmask_tables; i++) { 13843 if (chainmask_table[i].num_valid_chainmasks > 13844 (UINT_MAX - num_mac_phy_chainmask_caps)) { 13845 wmi_err_rl("integer overflow, num_mac_phy_chainmask_caps:%d, i:%d, um_valid_chainmasks:%d", 13846 num_mac_phy_chainmask_caps, i, 13847 chainmask_table[i].num_valid_chainmasks); 13848 return QDF_STATUS_E_INVAL; 13849 } 13850 num_mac_phy_chainmask_caps += 13851 chainmask_table[i].num_valid_chainmasks; 13852 } 13853 13854 if (num_mac_phy_chainmask_caps > 13855 param_buf->num_mac_phy_chainmask_caps) { 13856 wmi_err_rl("invalid chainmask caps num, num_mac_phy_chainmask_caps:%d, param_buf->num_mac_phy_chainmask_caps:%d", 13857 num_mac_phy_chainmask_caps, 13858 param_buf->num_mac_phy_chainmask_caps); 13859 return QDF_STATUS_E_INVAL; 13860 } 13861 13862 for (i = 0; i < hw_caps->num_chainmask_tables; i++) { 13863 13864 wmi_nofl_debug("Dumping chain mask combo data for table : %d", 13865 i); 13866 for (j = 0; j < chainmask_table[i].num_valid_chainmasks; j++) { 13867 13868 chainmask_table[i].cap_list[j].chainmask = 13869 chainmask_caps->chainmask; 13870 13871 chainmask_table[i].cap_list[j].supports_chan_width_20 = 13872 WMI_SUPPORT_CHAN_WIDTH_20_GET(chainmask_caps->supported_flags); 13873 13874 chainmask_table[i].cap_list[j].supports_chan_width_40 = 13875 WMI_SUPPORT_CHAN_WIDTH_40_GET(chainmask_caps->supported_flags); 13876 13877 chainmask_table[i].cap_list[j].supports_chan_width_80 = 13878 WMI_SUPPORT_CHAN_WIDTH_80_GET(chainmask_caps->supported_flags); 13879 13880 chainmask_table[i].cap_list[j].supports_chan_width_160 = 13881 WMI_SUPPORT_CHAN_WIDTH_160_GET(chainmask_caps->supported_flags); 13882 13883 chainmask_table[i].cap_list[j].supports_chan_width_80P80 = 13884 WMI_SUPPORT_CHAN_WIDTH_80P80_GET(chainmask_caps->supported_flags); 13885 13886 chainmask_table[i].cap_list[j].chain_mask_2G = 13887 WMI_SUPPORT_CHAIN_MASK_2G_GET(chainmask_caps->supported_flags); 13888 13889 chainmask_table[i].cap_list[j].chain_mask_5G = 13890 WMI_SUPPORT_CHAIN_MASK_5G_GET(chainmask_caps->supported_flags); 13891 13892 chainmask_table[i].cap_list[j].chain_mask_tx = 13893 WMI_SUPPORT_CHAIN_MASK_TX_GET(chainmask_caps->supported_flags); 13894 13895 chainmask_table[i].cap_list[j].chain_mask_rx = 13896 WMI_SUPPORT_CHAIN_MASK_RX_GET(chainmask_caps->supported_flags); 13897 13898 chainmask_table[i].cap_list[j].supports_aDFS = 13899 WMI_SUPPORT_CHAIN_MASK_ADFS_GET(chainmask_caps->supported_flags); 13900 13901 chainmask_table[i].cap_list[j].supports_aSpectral = 13902 WMI_SUPPORT_AGILE_SPECTRAL_GET(chainmask_caps->supported_flags); 13903 13904 chainmask_table[i].cap_list[j].supports_aSpectral_160 = 13905 WMI_SUPPORT_AGILE_SPECTRAL_160_GET(chainmask_caps->supported_flags); 13906 13907 chainmask_table[i].cap_list[j].supports_aDFS_160 = 13908 WMI_SUPPORT_ADFS_160_GET(chainmask_caps->supported_flags); 13909 13910 extract_11be_chainmask(&chainmask_table[i].cap_list[j], 13911 chainmask_caps); 13912 13913 wmi_nofl_debug("supported_flags: 0x%08x chainmasks: 0x%08x", 13914 chainmask_caps->supported_flags, 13915 chainmask_caps->chainmask); 13916 chainmask_caps++; 13917 } 13918 } 13919 13920 return QDF_STATUS_SUCCESS; 13921 } 13922 13923 /** 13924 * extract_service_ready_ext_tlv() - extract basic extended service ready params 13925 * from event 13926 * @wmi_handle: wmi handle 13927 * @event: pointer to event buffer 13928 * @param: Pointer to hold evt buf 13929 * 13930 * Return: QDF_STATUS_SUCCESS for success or error code 13931 */ 13932 static QDF_STATUS extract_service_ready_ext_tlv(wmi_unified_t wmi_handle, 13933 uint8_t *event, struct wlan_psoc_host_service_ext_param *param) 13934 { 13935 WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *param_buf; 13936 wmi_service_ready_ext_event_fixed_param *ev; 13937 WMI_SOC_MAC_PHY_HW_MODE_CAPS *hw_caps; 13938 WMI_SOC_HAL_REG_CAPABILITIES *reg_caps; 13939 WMI_MAC_PHY_CHAINMASK_COMBO *chain_mask_combo; 13940 uint8_t i = 0; 13941 13942 param_buf = (WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *) event; 13943 if (!param_buf) 13944 return QDF_STATUS_E_INVAL; 13945 13946 ev = param_buf->fixed_param; 13947 if (!ev) 13948 return QDF_STATUS_E_INVAL; 13949 13950 /* Move this to host based bitmap */ 13951 param->default_conc_scan_config_bits = 13952 ev->default_conc_scan_config_bits; 13953 param->default_fw_config_bits = ev->default_fw_config_bits; 13954 param->he_cap_info = ev->he_cap_info; 13955 param->mpdu_density = ev->mpdu_density; 13956 param->max_bssid_rx_filters = ev->max_bssid_rx_filters; 13957 param->fw_build_vers_ext = ev->fw_build_vers_ext; 13958 param->num_dbr_ring_caps = param_buf->num_dma_ring_caps; 13959 param->num_bin_scaling_params = param_buf->num_wmi_bin_scaling_params; 13960 param->max_bssid_indicator = ev->max_bssid_indicator; 13961 qdf_mem_copy(¶m->ppet, &ev->ppet, sizeof(param->ppet)); 13962 13963 hw_caps = param_buf->soc_hw_mode_caps; 13964 if (hw_caps) 13965 param->num_hw_modes = hw_caps->num_hw_modes; 13966 else 13967 param->num_hw_modes = 0; 13968 13969 reg_caps = param_buf->soc_hal_reg_caps; 13970 if (reg_caps) 13971 param->num_phy = reg_caps->num_phy; 13972 else 13973 param->num_phy = 0; 13974 13975 if (hw_caps) { 13976 param->num_chainmask_tables = hw_caps->num_chainmask_tables; 13977 wmi_nofl_debug("Num chain mask tables: %d", 13978 hw_caps->num_chainmask_tables); 13979 } else 13980 param->num_chainmask_tables = 0; 13981 13982 if (param->num_chainmask_tables > PSOC_MAX_CHAINMASK_TABLES || 13983 param->num_chainmask_tables > 13984 param_buf->num_mac_phy_chainmask_combo) { 13985 wmi_err_rl("num_chainmask_tables is OOB: %u", 13986 param->num_chainmask_tables); 13987 return QDF_STATUS_E_INVAL; 13988 } 13989 chain_mask_combo = param_buf->mac_phy_chainmask_combo; 13990 13991 if (!chain_mask_combo) 13992 return QDF_STATUS_SUCCESS; 13993 13994 wmi_nofl_debug("Dumping chain mask combo data"); 13995 13996 for (i = 0; i < param->num_chainmask_tables; i++) { 13997 13998 wmi_nofl_debug("table_id : %d Num valid chainmasks: %d", 13999 chain_mask_combo->chainmask_table_id, 14000 chain_mask_combo->num_valid_chainmask); 14001 14002 param->chainmask_table[i].table_id = 14003 chain_mask_combo->chainmask_table_id; 14004 param->chainmask_table[i].num_valid_chainmasks = 14005 chain_mask_combo->num_valid_chainmask; 14006 chain_mask_combo++; 14007 } 14008 wmi_nofl_debug("chain mask combo end"); 14009 14010 return QDF_STATUS_SUCCESS; 14011 } 14012 14013 #if defined(CONFIG_AFC_SUPPORT) 14014 /** 14015 * extract_svc_rdy_ext2_afc_tlv() - extract service ready ext2 afc deployment 14016 * type from event 14017 * @ev: pointer to event fixed param 14018 * @param: Pointer to hold the params 14019 * 14020 * Return: void 14021 */ 14022 static void 14023 extract_svc_rdy_ext2_afc_tlv(wmi_service_ready_ext2_event_fixed_param *ev, 14024 struct wlan_psoc_host_service_ext2_param *param) 14025 { 14026 WMI_AFC_FEATURE_6G_DEPLOYMENT_TYPE tgt_afc_dev_type; 14027 enum reg_afc_dev_deploy_type reg_afc_dev_type; 14028 14029 tgt_afc_dev_type = ev->afc_deployment_type; 14030 switch (tgt_afc_dev_type) { 14031 case WMI_AFC_FEATURE_6G_DEPLOYMENT_UNSPECIFIED: 14032 reg_afc_dev_type = AFC_DEPLOYMENT_INDOOR; 14033 break; 14034 case WMI_AFC_FEATURE_6G_DEPLOYMENT_INDOOR_ONLY: 14035 reg_afc_dev_type = AFC_DEPLOYMENT_INDOOR; 14036 break; 14037 case WMI_AFC_FEATURE_6G_DEPLOYMENT_OUTDOOR_ONLY: 14038 reg_afc_dev_type = AFC_DEPLOYMENT_OUTDOOR; 14039 break; 14040 default: 14041 wmi_err("invalid afc deployment %d", tgt_afc_dev_type); 14042 reg_afc_dev_type = AFC_DEPLOYMENT_UNKNOWN; 14043 break; 14044 } 14045 param->afc_dev_type = reg_afc_dev_type; 14046 14047 wmi_debug("afc dev type:%d", ev->afc_deployment_type); 14048 } 14049 #else 14050 static inline void 14051 extract_svc_rdy_ext2_afc_tlv(wmi_service_ready_ext2_event_fixed_param *ev, 14052 struct wlan_psoc_host_service_ext2_param *param) 14053 { 14054 } 14055 #endif 14056 14057 /** 14058 * extract_ul_mumimo_support() - extract UL-MUMIMO capability from target cap 14059 * @param: Pointer to hold the params 14060 * 14061 * Return: Void 14062 */ 14063 static void 14064 extract_ul_mumimo_support(struct wlan_psoc_host_service_ext2_param *param) 14065 { 14066 uint32_t tgt_cap = param->target_cap_flags; 14067 14068 param->ul_mumimo_rx_2g = WMI_TARGET_CAP_UL_MU_MIMO_RX_SUPPORT_2GHZ_GET(tgt_cap); 14069 param->ul_mumimo_rx_5g = WMI_TARGET_CAP_UL_MU_MIMO_RX_SUPPORT_5GHZ_GET(tgt_cap); 14070 param->ul_mumimo_rx_6g = WMI_TARGET_CAP_UL_MU_MIMO_RX_SUPPORT_6GHZ_GET(tgt_cap); 14071 param->ul_mumimo_tx_2g = WMI_TARGET_CAP_UL_MU_MIMO_TX_SUPPORT_2GHZ_GET(tgt_cap); 14072 param->ul_mumimo_tx_5g = WMI_TARGET_CAP_UL_MU_MIMO_TX_SUPPORT_5GHZ_GET(tgt_cap); 14073 param->ul_mumimo_tx_6g = WMI_TARGET_CAP_UL_MU_MIMO_TX_SUPPORT_6GHZ_GET(tgt_cap); 14074 } 14075 14076 /** 14077 * extract_hw_bdf_status() - extract service ready ext2 BDF hw status 14078 * type from event 14079 * @ev: pointer to event fixed param 14080 * 14081 * Return: void 14082 */ 14083 14084 static void 14085 extract_hw_bdf_status(wmi_service_ready_ext2_event_fixed_param *ev) 14086 { 14087 uint8_t hw_bdf_s; 14088 14089 hw_bdf_s = ev->hw_bd_status; 14090 switch (hw_bdf_s) { 14091 case WMI_BDF_VERSION_CHECK_DISABLED: 14092 wmi_info("BDF VER is %d, FW and BDF ver check skipped", 14093 hw_bdf_s); 14094 break; 14095 case WMI_BDF_VERSION_CHECK_GOOD: 14096 wmi_info("BDF VER is %d, FW and BDF ver check good", 14097 hw_bdf_s); 14098 break; 14099 case WMI_BDF_VERSION_TEMPLATE_TOO_OLD: 14100 wmi_info("BDF VER is %d, BDF ver is older than the oldest version supported by FW", 14101 hw_bdf_s); 14102 break; 14103 case WMI_BDF_VERSION_TEMPLATE_TOO_NEW: 14104 wmi_info("BDF VER is %d, BDF ver is newer than the newest version supported by FW", 14105 hw_bdf_s); 14106 break; 14107 case WMI_BDF_VERSION_FW_TOO_OLD: 14108 wmi_info("BDF VER is %d, FW ver is older than the major version supported by BDF", 14109 hw_bdf_s); 14110 break; 14111 case WMI_BDF_VERSION_FW_TOO_NEW: 14112 wmi_info("BDF VER is %d, FW ver is newer than the minor version supported by BDF", 14113 hw_bdf_s); 14114 break; 14115 default: 14116 wmi_info("unknown BDF VER %d", hw_bdf_s); 14117 break; 14118 } 14119 } 14120 14121 /** 14122 * extract_service_ready_ext2_tlv() - extract service ready ext2 params from 14123 * event 14124 * @wmi_handle: wmi handle 14125 * @event: pointer to event buffer 14126 * @param: Pointer to hold the params 14127 * 14128 * Return: QDF_STATUS_SUCCESS for success or error code 14129 */ 14130 static QDF_STATUS 14131 extract_service_ready_ext2_tlv(wmi_unified_t wmi_handle, uint8_t *event, 14132 struct wlan_psoc_host_service_ext2_param *param) 14133 { 14134 WMI_SERVICE_READY_EXT2_EVENTID_param_tlvs *param_buf; 14135 wmi_service_ready_ext2_event_fixed_param *ev; 14136 14137 param_buf = (WMI_SERVICE_READY_EXT2_EVENTID_param_tlvs *)event; 14138 if (!param_buf) 14139 return QDF_STATUS_E_INVAL; 14140 14141 ev = param_buf->fixed_param; 14142 if (!ev) 14143 return QDF_STATUS_E_INVAL; 14144 14145 param->reg_db_version_major = 14146 WMI_REG_DB_VERSION_MAJOR_GET( 14147 ev->reg_db_version); 14148 param->reg_db_version_minor = 14149 WMI_REG_DB_VERSION_MINOR_GET( 14150 ev->reg_db_version); 14151 param->bdf_reg_db_version_major = 14152 WMI_BDF_REG_DB_VERSION_MAJOR_GET( 14153 ev->reg_db_version); 14154 param->bdf_reg_db_version_minor = 14155 WMI_BDF_REG_DB_VERSION_MINOR_GET( 14156 ev->reg_db_version); 14157 param->chwidth_num_peer_caps = ev->chwidth_num_peer_caps; 14158 14159 param->num_dbr_ring_caps = param_buf->num_dma_ring_caps; 14160 14161 if (param_buf->nan_cap) 14162 param->max_ndp_sessions = 14163 param_buf->nan_cap->max_ndp_sessions; 14164 else 14165 param->max_ndp_sessions = 0; 14166 14167 param->preamble_puncture_bw_cap = ev->preamble_puncture_bw; 14168 param->num_scan_radio_caps = param_buf->num_wmi_scan_radio_caps; 14169 param->max_users_dl_ofdma = WMI_MAX_USER_PER_PPDU_DL_OFDMA_GET( 14170 ev->max_user_per_ppdu_ofdma); 14171 param->max_users_ul_ofdma = WMI_MAX_USER_PER_PPDU_UL_OFDMA_GET( 14172 ev->max_user_per_ppdu_ofdma); 14173 param->max_users_dl_mumimo = WMI_MAX_USER_PER_PPDU_DL_MUMIMO_GET( 14174 ev->max_user_per_ppdu_mumimo); 14175 param->max_users_ul_mumimo = WMI_MAX_USER_PER_PPDU_UL_MUMIMO_GET( 14176 ev->max_user_per_ppdu_mumimo); 14177 param->target_cap_flags = ev->target_cap_flags; 14178 extract_ul_mumimo_support(param); 14179 wmi_debug("htt peer data :%d", ev->target_cap_flags); 14180 14181 extract_svc_rdy_ext2_afc_tlv(ev, param); 14182 14183 extract_hw_bdf_status(ev); 14184 14185 return QDF_STATUS_SUCCESS; 14186 } 14187 14188 /* 14189 * extract_dbs_or_sbs_cap_service_ready_ext2_tlv() - extract dbs_or_sbs cap from 14190 * service ready ext 2 14191 * 14192 * @wmi_handle: wmi handle 14193 * @event: pointer to event buffer 14194 * @sbs_lower_band_end_freq: If sbs_lower_band_end_freq is set to non-zero, 14195 * it indicates async SBS mode is supported, and 14196 * lower-band/higher band to MAC mapping is 14197 * switch-able. unit: mhz. examples 5180, 5320 14198 * 14199 * Return: QDF_STATUS_SUCCESS on success, QDF_STATUS_E_** on error 14200 */ 14201 static QDF_STATUS extract_dbs_or_sbs_cap_service_ready_ext2_tlv( 14202 wmi_unified_t wmi_handle, uint8_t *event, 14203 uint32_t *sbs_lower_band_end_freq) 14204 { 14205 WMI_SERVICE_READY_EXT2_EVENTID_param_tlvs *param_buf; 14206 wmi_dbs_or_sbs_cap_ext *dbs_or_sbs_caps; 14207 14208 param_buf = (WMI_SERVICE_READY_EXT2_EVENTID_param_tlvs *)event; 14209 if (!param_buf) 14210 return QDF_STATUS_E_INVAL; 14211 14212 dbs_or_sbs_caps = param_buf->dbs_or_sbs_cap_ext; 14213 if (!dbs_or_sbs_caps) 14214 return QDF_STATUS_E_INVAL; 14215 14216 *sbs_lower_band_end_freq = dbs_or_sbs_caps->sbs_lower_band_end_freq; 14217 14218 return QDF_STATUS_SUCCESS; 14219 } 14220 14221 /** 14222 * extract_sar_cap_service_ready_ext_tlv() - 14223 * extract SAR cap from service ready event 14224 * @wmi_handle: wmi handle 14225 * @event: pointer to event buffer 14226 * @ext_param: extended target info 14227 * 14228 * Return: QDF_STATUS_SUCCESS for success or error code 14229 */ 14230 static QDF_STATUS extract_sar_cap_service_ready_ext_tlv( 14231 wmi_unified_t wmi_handle, 14232 uint8_t *event, 14233 struct wlan_psoc_host_service_ext_param *ext_param) 14234 { 14235 WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *param_buf; 14236 WMI_SAR_CAPABILITIES *sar_caps; 14237 14238 param_buf = (WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *)event; 14239 14240 if (!param_buf) 14241 return QDF_STATUS_E_INVAL; 14242 14243 sar_caps = param_buf->sar_caps; 14244 if (sar_caps) 14245 ext_param->sar_version = sar_caps->active_version; 14246 else 14247 ext_param->sar_version = 0; 14248 14249 return QDF_STATUS_SUCCESS; 14250 } 14251 14252 /** 14253 * extract_hw_mode_cap_service_ready_ext_tlv() - 14254 * extract HW mode cap from service ready event 14255 * @wmi_handle: wmi handle 14256 * @event: pointer to event buffer 14257 * @hw_mode_idx: hw mode idx should be less than num_mode 14258 * @param: Pointer to hold evt buf 14259 * 14260 * Return: QDF_STATUS_SUCCESS for success or error code 14261 */ 14262 static QDF_STATUS extract_hw_mode_cap_service_ready_ext_tlv( 14263 wmi_unified_t wmi_handle, 14264 uint8_t *event, uint8_t hw_mode_idx, 14265 struct wlan_psoc_host_hw_mode_caps *param) 14266 { 14267 WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *param_buf; 14268 WMI_SOC_MAC_PHY_HW_MODE_CAPS *hw_caps; 14269 14270 param_buf = (WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *) event; 14271 if (!param_buf) 14272 return QDF_STATUS_E_INVAL; 14273 14274 hw_caps = param_buf->soc_hw_mode_caps; 14275 if (!hw_caps) 14276 return QDF_STATUS_E_INVAL; 14277 14278 if (!hw_caps->num_hw_modes || 14279 !param_buf->hw_mode_caps || 14280 hw_caps->num_hw_modes > PSOC_MAX_HW_MODE || 14281 hw_caps->num_hw_modes > param_buf->num_hw_mode_caps) 14282 return QDF_STATUS_E_INVAL; 14283 14284 if (hw_mode_idx >= hw_caps->num_hw_modes) 14285 return QDF_STATUS_E_INVAL; 14286 14287 param->hw_mode_id = param_buf->hw_mode_caps[hw_mode_idx].hw_mode_id; 14288 param->phy_id_map = param_buf->hw_mode_caps[hw_mode_idx].phy_id_map; 14289 14290 param->hw_mode_config_type = 14291 param_buf->hw_mode_caps[hw_mode_idx].hw_mode_config_type; 14292 14293 return QDF_STATUS_SUCCESS; 14294 } 14295 14296 /** 14297 * extract_service_ready_11be_support() - api to extract 11be support 14298 * @param: host mac phy capabilities 14299 * @mac_phy_caps: mac phy capabilities 14300 * 14301 * Return: void 14302 */ 14303 #ifdef WLAN_FEATURE_11BE 14304 static void 14305 extract_service_ready_11be_support(struct wlan_psoc_host_mac_phy_caps *param, 14306 WMI_MAC_PHY_CAPABILITIES *mac_phy_caps) 14307 { 14308 param->supports_11be = 14309 WMI_SUPPORT_11BE_GET(mac_phy_caps->supported_flags); 14310 14311 wmi_debug("11be support %d", param->supports_11be); 14312 } 14313 #else 14314 static void 14315 extract_service_ready_11be_support(struct wlan_psoc_host_mac_phy_caps *param, 14316 WMI_MAC_PHY_CAPABILITIES *mac_phy_caps) 14317 { 14318 } 14319 #endif 14320 14321 #if defined(WLAN_FEATURE_11BE_MLO) && defined(WLAN_MLO_MULTI_CHIP) 14322 static void extract_hw_link_id(struct wlan_psoc_host_mac_phy_caps *param, 14323 WMI_MAC_PHY_CAPABILITIES *mac_phy_caps) 14324 { 14325 param->hw_link_id = WMI_PHY_GET_HW_LINK_ID(mac_phy_caps->pdev_id); 14326 } 14327 #else 14328 static void extract_hw_link_id(struct wlan_psoc_host_mac_phy_caps *param, 14329 WMI_MAC_PHY_CAPABILITIES *mac_phy_caps) 14330 { 14331 } 14332 #endif /*WLAN_FEATURE_11BE_MLO && WLAN_MLO_MULTI_CHIP*/ 14333 14334 /** 14335 * extract_mac_phy_cap_service_ready_ext_tlv() - 14336 * extract MAC phy cap from service ready event 14337 * @wmi_handle: wmi handle 14338 * @event: pointer to event buffer 14339 * @hw_mode_id: hw mode idx should be less than num_mode 14340 * @phy_id: phy id within hw_mode 14341 * @param: Pointer to hold evt buf 14342 * 14343 * Return: QDF_STATUS_SUCCESS for success or error code 14344 */ 14345 static QDF_STATUS extract_mac_phy_cap_service_ready_ext_tlv( 14346 wmi_unified_t wmi_handle, 14347 uint8_t *event, uint8_t hw_mode_id, uint8_t phy_id, 14348 struct wlan_psoc_host_mac_phy_caps *param) 14349 { 14350 WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *param_buf; 14351 WMI_MAC_PHY_CAPABILITIES *mac_phy_caps; 14352 WMI_SOC_MAC_PHY_HW_MODE_CAPS *hw_caps; 14353 uint32_t phy_map; 14354 uint8_t hw_idx, phy_idx = 0, pdev_id; 14355 14356 param_buf = (WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *) event; 14357 if (!param_buf) 14358 return QDF_STATUS_E_INVAL; 14359 14360 hw_caps = param_buf->soc_hw_mode_caps; 14361 if (!hw_caps) 14362 return QDF_STATUS_E_INVAL; 14363 if (hw_caps->num_hw_modes > PSOC_MAX_HW_MODE || 14364 hw_caps->num_hw_modes > param_buf->num_hw_mode_caps) { 14365 wmi_err_rl("invalid num_hw_modes %d, num_hw_mode_caps %d", 14366 hw_caps->num_hw_modes, param_buf->num_hw_mode_caps); 14367 return QDF_STATUS_E_INVAL; 14368 } 14369 14370 for (hw_idx = 0; hw_idx < hw_caps->num_hw_modes; hw_idx++) { 14371 if (hw_mode_id == param_buf->hw_mode_caps[hw_idx].hw_mode_id) 14372 break; 14373 14374 phy_map = param_buf->hw_mode_caps[hw_idx].phy_id_map; 14375 while (phy_map) { 14376 phy_map >>= 1; 14377 phy_idx++; 14378 } 14379 } 14380 14381 if (hw_idx == hw_caps->num_hw_modes) 14382 return QDF_STATUS_E_INVAL; 14383 14384 phy_idx += phy_id; 14385 if (phy_idx >= param_buf->num_mac_phy_caps) 14386 return QDF_STATUS_E_INVAL; 14387 14388 mac_phy_caps = ¶m_buf->mac_phy_caps[phy_idx]; 14389 14390 param->hw_mode_id = mac_phy_caps->hw_mode_id; 14391 param->phy_idx = phy_idx; 14392 pdev_id = WMI_PHY_GET_PDEV_ID(mac_phy_caps->pdev_id); 14393 param->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host( 14394 wmi_handle, 14395 pdev_id); 14396 param->tgt_pdev_id = pdev_id; 14397 extract_hw_link_id(param, mac_phy_caps); 14398 param->phy_id = mac_phy_caps->phy_id; 14399 param->supports_11b = 14400 WMI_SUPPORT_11B_GET(mac_phy_caps->supported_flags); 14401 param->supports_11g = 14402 WMI_SUPPORT_11G_GET(mac_phy_caps->supported_flags); 14403 param->supports_11a = 14404 WMI_SUPPORT_11A_GET(mac_phy_caps->supported_flags); 14405 param->supports_11n = 14406 WMI_SUPPORT_11N_GET(mac_phy_caps->supported_flags); 14407 param->supports_11ac = 14408 WMI_SUPPORT_11AC_GET(mac_phy_caps->supported_flags); 14409 param->supports_11ax = 14410 WMI_SUPPORT_11AX_GET(mac_phy_caps->supported_flags); 14411 14412 extract_service_ready_11be_support(param, mac_phy_caps); 14413 14414 param->supported_bands = mac_phy_caps->supported_bands; 14415 param->ampdu_density = mac_phy_caps->ampdu_density; 14416 param->max_bw_supported_2G = mac_phy_caps->max_bw_supported_2G; 14417 param->ht_cap_info_2G = mac_phy_caps->ht_cap_info_2G; 14418 param->vht_cap_info_2G = mac_phy_caps->vht_cap_info_2G; 14419 param->vht_supp_mcs_2G = mac_phy_caps->vht_supp_mcs_2G; 14420 param->he_cap_info_2G[WMI_HOST_HECAP_MAC_WORD1] = 14421 mac_phy_caps->he_cap_info_2G; 14422 param->he_cap_info_2G[WMI_HOST_HECAP_MAC_WORD2] = 14423 mac_phy_caps->he_cap_info_2G_ext; 14424 param->he_supp_mcs_2G = mac_phy_caps->he_supp_mcs_2G; 14425 param->tx_chain_mask_2G = mac_phy_caps->tx_chain_mask_2G; 14426 param->rx_chain_mask_2G = mac_phy_caps->rx_chain_mask_2G; 14427 param->max_bw_supported_5G = mac_phy_caps->max_bw_supported_5G; 14428 param->ht_cap_info_5G = mac_phy_caps->ht_cap_info_5G; 14429 param->vht_cap_info_5G = mac_phy_caps->vht_cap_info_5G; 14430 param->vht_supp_mcs_5G = mac_phy_caps->vht_supp_mcs_5G; 14431 param->he_cap_info_5G[WMI_HOST_HECAP_MAC_WORD1] = 14432 mac_phy_caps->he_cap_info_5G; 14433 param->he_cap_info_5G[WMI_HOST_HECAP_MAC_WORD2] = 14434 mac_phy_caps->he_cap_info_5G_ext; 14435 param->he_supp_mcs_5G = mac_phy_caps->he_supp_mcs_5G; 14436 param->he_cap_info_internal = mac_phy_caps->he_cap_info_internal; 14437 param->tx_chain_mask_5G = mac_phy_caps->tx_chain_mask_5G; 14438 param->rx_chain_mask_5G = mac_phy_caps->rx_chain_mask_5G; 14439 qdf_mem_copy(¶m->he_cap_phy_info_2G, 14440 &mac_phy_caps->he_cap_phy_info_2G, 14441 sizeof(param->he_cap_phy_info_2G)); 14442 qdf_mem_copy(¶m->he_cap_phy_info_5G, 14443 &mac_phy_caps->he_cap_phy_info_5G, 14444 sizeof(param->he_cap_phy_info_5G)); 14445 qdf_mem_copy(¶m->he_ppet2G, &mac_phy_caps->he_ppet2G, 14446 sizeof(param->he_ppet2G)); 14447 qdf_mem_copy(¶m->he_ppet5G, &mac_phy_caps->he_ppet5G, 14448 sizeof(param->he_ppet5G)); 14449 param->chainmask_table_id = mac_phy_caps->chainmask_table_id; 14450 param->lmac_id = mac_phy_caps->lmac_id; 14451 param->reg_cap_ext.wireless_modes = convert_wireless_modes_tlv 14452 (mac_phy_caps->wireless_modes); 14453 param->reg_cap_ext.low_2ghz_chan = mac_phy_caps->low_2ghz_chan_freq; 14454 param->reg_cap_ext.high_2ghz_chan = mac_phy_caps->high_2ghz_chan_freq; 14455 param->reg_cap_ext.low_5ghz_chan = mac_phy_caps->low_5ghz_chan_freq; 14456 param->reg_cap_ext.high_5ghz_chan = mac_phy_caps->high_5ghz_chan_freq; 14457 param->nss_ratio_enabled = WMI_NSS_RATIO_ENABLE_DISABLE_GET( 14458 mac_phy_caps->nss_ratio); 14459 param->nss_ratio_info = WMI_NSS_RATIO_INFO_GET(mac_phy_caps->nss_ratio); 14460 14461 return QDF_STATUS_SUCCESS; 14462 } 14463 14464 #ifdef WLAN_FEATURE_11BE_MLO 14465 /** 14466 * extract_mac_phy_emlcap() - API to extract EML Capabilities 14467 * @param: host ext2 mac phy capabilities 14468 * @mac_phy_caps: ext mac phy capabilities 14469 * 14470 * Return: void 14471 */ 14472 static void extract_mac_phy_emlcap(struct wlan_psoc_host_mac_phy_caps_ext2 *param, 14473 WMI_MAC_PHY_CAPABILITIES_EXT *mac_phy_caps) 14474 { 14475 if (!param || !mac_phy_caps) 14476 return; 14477 14478 param->emlcap.emlsr_supp = WMI_SUPPORT_EMLSR_GET(mac_phy_caps->eml_capability); 14479 param->emlcap.emlsr_pad_delay = WMI_EMLSR_PADDING_DELAY_GET(mac_phy_caps->eml_capability); 14480 param->emlcap.emlsr_trans_delay = WMI_EMLSR_TRANSITION_DELAY_GET(mac_phy_caps->eml_capability); 14481 param->emlcap.emlmr_supp = WMI_SUPPORT_EMLMR_GET(mac_phy_caps->eml_capability); 14482 param->emlcap.emlmr_delay = WMI_EMLMR_DELAY_GET(mac_phy_caps->eml_capability); 14483 param->emlcap.trans_timeout = WMI_TRANSITION_TIMEOUT_GET(mac_phy_caps->eml_capability); 14484 } 14485 14486 /** 14487 * extract_mac_phy_mldcap() - API to extract MLD Capabilities 14488 * @param: host ext2 mac phy capabilities 14489 * @mac_phy_caps: ext mac phy capabilities 14490 * 14491 * Return: void 14492 */ 14493 static void extract_mac_phy_mldcap(struct wlan_psoc_host_mac_phy_caps_ext2 *param, 14494 WMI_MAC_PHY_CAPABILITIES_EXT *mac_phy_caps) 14495 { 14496 if (!param || !mac_phy_caps) 14497 return; 14498 14499 param->mldcap.max_simult_link = WMI_MAX_NUM_SIMULTANEOUS_LINKS_GET(mac_phy_caps->mld_capability); 14500 param->mldcap.srs_support = WMI_SUPPORT_SRS_GET(mac_phy_caps->mld_capability); 14501 param->mldcap.tid2link_neg_support = WMI_TID_TO_LINK_NEGOTIATION_GET(mac_phy_caps->mld_capability); 14502 param->mldcap.str_freq_sep = WMI_FREQ_SEPERATION_STR_GET(mac_phy_caps->mld_capability); 14503 param->mldcap.aar_support = WMI_SUPPORT_AAR_GET(mac_phy_caps->mld_capability); 14504 } 14505 #else 14506 static void extract_mac_phy_emlcap(struct wlan_psoc_host_mac_phy_caps_ext2 *param, 14507 WMI_MAC_PHY_CAPABILITIES_EXT *mac_phy_caps) 14508 { 14509 } 14510 14511 static void extract_mac_phy_mldcap(struct wlan_psoc_host_mac_phy_caps_ext2 *param, 14512 WMI_MAC_PHY_CAPABILITIES_EXT *mac_phy_caps) 14513 { 14514 } 14515 #endif 14516 14517 /** 14518 * extract_mac_phy_cap_ehtcaps- api to extract eht mac phy caps 14519 * @param: host ext2 mac phy capabilities 14520 * @mac_phy_caps: ext mac phy capabilities 14521 * 14522 * Return: void 14523 */ 14524 #ifdef WLAN_FEATURE_11BE 14525 static void extract_mac_phy_cap_ehtcaps( 14526 struct wlan_psoc_host_mac_phy_caps_ext2 *param, 14527 WMI_MAC_PHY_CAPABILITIES_EXT *mac_phy_caps) 14528 { 14529 uint32_t i; 14530 14531 param->eht_supp_mcs_2G = mac_phy_caps->eht_supp_mcs_2G; 14532 param->eht_supp_mcs_5G = mac_phy_caps->eht_supp_mcs_5G; 14533 param->eht_cap_info_internal = mac_phy_caps->eht_cap_info_internal; 14534 14535 qdf_mem_copy(¶m->eht_cap_info_2G, 14536 &mac_phy_caps->eht_cap_mac_info_2G, 14537 sizeof(param->eht_cap_info_2G)); 14538 qdf_mem_copy(¶m->eht_cap_info_5G, 14539 &mac_phy_caps->eht_cap_mac_info_5G, 14540 sizeof(param->eht_cap_info_5G)); 14541 14542 qdf_mem_copy(¶m->eht_cap_phy_info_2G, 14543 &mac_phy_caps->eht_cap_phy_info_2G, 14544 sizeof(param->eht_cap_phy_info_2G)); 14545 qdf_mem_copy(¶m->eht_cap_phy_info_5G, 14546 &mac_phy_caps->eht_cap_phy_info_5G, 14547 sizeof(param->eht_cap_phy_info_5G)); 14548 14549 qdf_mem_copy(¶m->eht_supp_mcs_ext_2G, 14550 &mac_phy_caps->eht_supp_mcs_ext_2G, 14551 sizeof(param->eht_supp_mcs_ext_2G)); 14552 qdf_mem_copy(¶m->eht_supp_mcs_ext_5G, 14553 &mac_phy_caps->eht_supp_mcs_ext_5G, 14554 sizeof(param->eht_supp_mcs_ext_5G)); 14555 14556 qdf_mem_copy(¶m->eht_ppet2G, &mac_phy_caps->eht_ppet2G, 14557 sizeof(param->eht_ppet2G)); 14558 qdf_mem_copy(¶m->eht_ppet5G, &mac_phy_caps->eht_ppet5G, 14559 sizeof(param->eht_ppet5G)); 14560 14561 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", 14562 mac_phy_caps->eht_cap_mac_info_2G[0], 14563 mac_phy_caps->eht_cap_mac_info_5G[0], 14564 mac_phy_caps->eht_supp_mcs_2G, mac_phy_caps->eht_supp_mcs_5G, 14565 mac_phy_caps->eht_cap_info_internal); 14566 14567 wmi_nofl_debug("EHT phy caps: "); 14568 14569 wmi_nofl_debug("2G:"); 14570 for (i = 0; i < PSOC_HOST_MAX_EHT_PHY_SIZE; i++) { 14571 wmi_nofl_debug("index %d value %x", 14572 i, param->eht_cap_phy_info_2G[i]); 14573 } 14574 wmi_nofl_debug("5G:"); 14575 for (i = 0; i < PSOC_HOST_MAX_EHT_PHY_SIZE; i++) { 14576 wmi_nofl_debug("index %d value %x", 14577 i, param->eht_cap_phy_info_5G[i]); 14578 } 14579 wmi_nofl_debug("2G MCS ext Map:"); 14580 for (i = 0; i < PSOC_HOST_EHT_MCS_NSS_MAP_2G_SIZE; i++) { 14581 wmi_nofl_debug("index %d value %x", 14582 i, param->eht_supp_mcs_ext_2G[i]); 14583 } 14584 wmi_nofl_debug("5G MCS ext Map:"); 14585 for (i = 0; i < PSOC_HOST_EHT_MCS_NSS_MAP_5G_SIZE; i++) { 14586 wmi_nofl_debug("index %d value %x", 14587 i, param->eht_supp_mcs_ext_5G[i]); 14588 } 14589 wmi_nofl_debug("2G PPET: numss_m1 %x ru_bit_mask %x", 14590 param->eht_ppet2G.numss_m1, 14591 param->eht_ppet2G.ru_bit_mask); 14592 for (i = 0; i < PSOC_HOST_MAX_NUM_SS; i++) { 14593 wmi_nofl_debug("index %d value %x", 14594 i, param->eht_ppet2G.ppet16_ppet8_ru3_ru0[i]); 14595 } 14596 wmi_nofl_debug("5G PPET: numss_m1 %x ru_bit_mask %x", 14597 param->eht_ppet5G.numss_m1, 14598 param->eht_ppet5G.ru_bit_mask); 14599 for (i = 0; i < PSOC_HOST_MAX_NUM_SS; i++) { 14600 wmi_nofl_debug("index %d value %x", 14601 i, param->eht_ppet5G.ppet16_ppet8_ru3_ru0[i]); 14602 } 14603 } 14604 #else 14605 static void extract_mac_phy_cap_ehtcaps( 14606 struct wlan_psoc_host_mac_phy_caps_ext2 *param, 14607 WMI_MAC_PHY_CAPABILITIES_EXT *mac_phy_caps) 14608 { 14609 } 14610 #endif 14611 14612 static QDF_STATUS extract_mac_phy_cap_service_ready_ext2_tlv( 14613 wmi_unified_t wmi_handle, 14614 uint8_t *event, uint8_t hw_mode_id, uint8_t phy_id, 14615 uint8_t phy_idx, 14616 struct wlan_psoc_host_mac_phy_caps_ext2 *param) 14617 { 14618 WMI_SERVICE_READY_EXT2_EVENTID_param_tlvs *param_buf; 14619 WMI_MAC_PHY_CAPABILITIES_EXT *mac_phy_caps; 14620 14621 if (!event) { 14622 wmi_err("null evt_buf"); 14623 return QDF_STATUS_E_INVAL; 14624 } 14625 14626 param_buf = (WMI_SERVICE_READY_EXT2_EVENTID_param_tlvs *)event; 14627 14628 if (!param_buf->num_mac_phy_caps) 14629 return QDF_STATUS_SUCCESS; 14630 14631 if (phy_idx >= param_buf->num_mac_phy_caps) 14632 return QDF_STATUS_E_INVAL; 14633 14634 mac_phy_caps = ¶m_buf->mac_phy_caps[phy_idx]; 14635 14636 if ((hw_mode_id != mac_phy_caps->hw_mode_id) || 14637 (phy_id != mac_phy_caps->phy_id)) 14638 return QDF_STATUS_E_INVAL; 14639 14640 param->hw_mode_id = mac_phy_caps->hw_mode_id; 14641 param->phy_id = mac_phy_caps->phy_id; 14642 param->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host( 14643 wmi_handle, WMI_PHY_GET_PDEV_ID(mac_phy_caps->pdev_id)); 14644 param->wireless_modes_ext = convert_wireless_modes_ext_tlv( 14645 mac_phy_caps->wireless_modes_ext); 14646 14647 extract_mac_phy_cap_ehtcaps(param, mac_phy_caps); 14648 extract_mac_phy_emlcap(param, mac_phy_caps); 14649 extract_mac_phy_mldcap(param, mac_phy_caps); 14650 14651 return QDF_STATUS_SUCCESS; 14652 } 14653 14654 /** 14655 * extract_reg_cap_service_ready_ext_tlv() - 14656 * extract REG cap from service ready event 14657 * @wmi_handle: wmi handle 14658 * @event: pointer to event buffer 14659 * @phy_idx: phy idx should be less than num_mode 14660 * @param: Pointer to hold evt buf 14661 * 14662 * Return: QDF_STATUS_SUCCESS for success or error code 14663 */ 14664 static QDF_STATUS extract_reg_cap_service_ready_ext_tlv( 14665 wmi_unified_t wmi_handle, 14666 uint8_t *event, uint8_t phy_idx, 14667 struct wlan_psoc_host_hal_reg_capabilities_ext *param) 14668 { 14669 WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *param_buf; 14670 WMI_SOC_HAL_REG_CAPABILITIES *reg_caps; 14671 WMI_HAL_REG_CAPABILITIES_EXT *ext_reg_cap; 14672 14673 param_buf = (WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *) event; 14674 if (!param_buf) 14675 return QDF_STATUS_E_INVAL; 14676 14677 reg_caps = param_buf->soc_hal_reg_caps; 14678 if (!reg_caps) 14679 return QDF_STATUS_E_INVAL; 14680 14681 if (reg_caps->num_phy > param_buf->num_hal_reg_caps) 14682 return QDF_STATUS_E_INVAL; 14683 14684 if (phy_idx >= reg_caps->num_phy) 14685 return QDF_STATUS_E_INVAL; 14686 14687 if (!param_buf->hal_reg_caps) 14688 return QDF_STATUS_E_INVAL; 14689 14690 ext_reg_cap = ¶m_buf->hal_reg_caps[phy_idx]; 14691 14692 param->phy_id = ext_reg_cap->phy_id; 14693 param->eeprom_reg_domain = ext_reg_cap->eeprom_reg_domain; 14694 param->eeprom_reg_domain_ext = ext_reg_cap->eeprom_reg_domain_ext; 14695 param->regcap1 = ext_reg_cap->regcap1; 14696 param->regcap2 = ext_reg_cap->regcap2; 14697 param->wireless_modes = convert_wireless_modes_tlv( 14698 ext_reg_cap->wireless_modes); 14699 param->low_2ghz_chan = ext_reg_cap->low_2ghz_chan; 14700 param->high_2ghz_chan = ext_reg_cap->high_2ghz_chan; 14701 param->low_5ghz_chan = ext_reg_cap->low_5ghz_chan; 14702 param->high_5ghz_chan = ext_reg_cap->high_5ghz_chan; 14703 14704 return QDF_STATUS_SUCCESS; 14705 } 14706 14707 static QDF_STATUS validate_dbr_ring_caps_idx(uint8_t idx, 14708 uint8_t num_dma_ring_caps) 14709 { 14710 /* If dma_ring_caps is populated, num_dbr_ring_caps is non-zero */ 14711 if (!num_dma_ring_caps) { 14712 wmi_err("dma_ring_caps %d", num_dma_ring_caps); 14713 return QDF_STATUS_E_INVAL; 14714 } 14715 if (idx >= num_dma_ring_caps) { 14716 wmi_err("Index %d exceeds range", idx); 14717 return QDF_STATUS_E_INVAL; 14718 } 14719 return QDF_STATUS_SUCCESS; 14720 } 14721 14722 static void 14723 populate_dbr_ring_cap_elems(wmi_unified_t wmi_handle, 14724 struct wlan_psoc_host_dbr_ring_caps *param, 14725 WMI_DMA_RING_CAPABILITIES *dbr_ring_caps) 14726 { 14727 param->pdev_id = wmi_handle->ops->convert_target_pdev_id_to_host( 14728 wmi_handle, 14729 dbr_ring_caps->pdev_id); 14730 param->mod_id = dbr_ring_caps->mod_id; 14731 param->ring_elems_min = dbr_ring_caps->ring_elems_min; 14732 param->min_buf_size = dbr_ring_caps->min_buf_size; 14733 param->min_buf_align = dbr_ring_caps->min_buf_align; 14734 } 14735 14736 static QDF_STATUS extract_dbr_ring_cap_service_ready_ext_tlv( 14737 wmi_unified_t wmi_handle, 14738 uint8_t *event, uint8_t idx, 14739 struct wlan_psoc_host_dbr_ring_caps *param) 14740 { 14741 WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *param_buf; 14742 QDF_STATUS status; 14743 14744 param_buf = (WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *)event; 14745 if (!param_buf) 14746 return QDF_STATUS_E_INVAL; 14747 14748 status = validate_dbr_ring_caps_idx(idx, param_buf->num_dma_ring_caps); 14749 if (status != QDF_STATUS_SUCCESS) 14750 return status; 14751 14752 populate_dbr_ring_cap_elems(wmi_handle, param, 14753 ¶m_buf->dma_ring_caps[idx]); 14754 return QDF_STATUS_SUCCESS; 14755 } 14756 14757 static QDF_STATUS extract_dbr_ring_cap_service_ready_ext2_tlv( 14758 wmi_unified_t wmi_handle, 14759 uint8_t *event, uint8_t idx, 14760 struct wlan_psoc_host_dbr_ring_caps *param) 14761 { 14762 WMI_SERVICE_READY_EXT2_EVENTID_param_tlvs *param_buf; 14763 QDF_STATUS status; 14764 14765 param_buf = (WMI_SERVICE_READY_EXT2_EVENTID_param_tlvs *)event; 14766 if (!param_buf) 14767 return QDF_STATUS_E_INVAL; 14768 14769 status = validate_dbr_ring_caps_idx(idx, param_buf->num_dma_ring_caps); 14770 if (status != QDF_STATUS_SUCCESS) 14771 return status; 14772 14773 populate_dbr_ring_cap_elems(wmi_handle, param, 14774 ¶m_buf->dma_ring_caps[idx]); 14775 return QDF_STATUS_SUCCESS; 14776 } 14777 14778 static QDF_STATUS extract_scan_radio_cap_service_ready_ext2_tlv( 14779 wmi_unified_t wmi_handle, 14780 uint8_t *event, uint8_t idx, 14781 struct wlan_psoc_host_scan_radio_caps *param) 14782 { 14783 WMI_SERVICE_READY_EXT2_EVENTID_param_tlvs *param_buf; 14784 WMI_SCAN_RADIO_CAPABILITIES_EXT2 *scan_radio_caps; 14785 14786 param_buf = (WMI_SERVICE_READY_EXT2_EVENTID_param_tlvs *)event; 14787 if (!param_buf) 14788 return QDF_STATUS_E_INVAL; 14789 14790 if (idx >= param_buf->num_wmi_scan_radio_caps) 14791 return QDF_STATUS_E_INVAL; 14792 14793 scan_radio_caps = ¶m_buf->wmi_scan_radio_caps[idx]; 14794 param->phy_id = scan_radio_caps->phy_id; 14795 param->scan_radio_supported = 14796 WMI_SCAN_RADIO_CAP_SCAN_RADIO_FLAG_GET(scan_radio_caps->flags); 14797 param->dfs_en = 14798 WMI_SCAN_RADIO_CAP_DFS_FLAG_GET(scan_radio_caps->flags); 14799 14800 return QDF_STATUS_SUCCESS; 14801 } 14802 14803 static QDF_STATUS extract_sw_cal_ver_ext2_tlv(wmi_unified_t wmi_handle, 14804 uint8_t *event, 14805 struct wmi_host_sw_cal_ver *cal) 14806 { 14807 WMI_SERVICE_READY_EXT2_EVENTID_param_tlvs *param_buf; 14808 wmi_sw_cal_ver_cap *fw_cap; 14809 14810 param_buf = (WMI_SERVICE_READY_EXT2_EVENTID_param_tlvs *)event; 14811 if (!param_buf) 14812 return QDF_STATUS_E_INVAL; 14813 14814 fw_cap = param_buf->sw_cal_ver_cap; 14815 if (!fw_cap) 14816 return QDF_STATUS_E_INVAL; 14817 14818 cal->bdf_cal_ver = fw_cap->bdf_cal_ver; 14819 cal->ftm_cal_ver = fw_cap->ftm_cal_ver; 14820 cal->status = fw_cap->status; 14821 14822 return QDF_STATUS_SUCCESS; 14823 } 14824 14825 /** 14826 * wmi_tgt_thermal_level_to_host() - Convert target thermal level to host enum 14827 * @level: target thermal level from WMI_THERM_THROT_STATS_EVENTID event 14828 * 14829 * Return: host thermal throt level 14830 */ 14831 static enum thermal_throttle_level 14832 wmi_tgt_thermal_level_to_host(uint32_t level) 14833 { 14834 switch (level) { 14835 case WMI_THERMAL_FULLPERF: 14836 return THERMAL_FULLPERF; 14837 case WMI_THERMAL_MITIGATION: 14838 return THERMAL_MITIGATION; 14839 case WMI_THERMAL_SHUTOFF: 14840 return THERMAL_SHUTOFF; 14841 case WMI_THERMAL_SHUTDOWN_TGT: 14842 return THERMAL_SHUTDOWN_TARGET; 14843 default: 14844 return THERMAL_UNKNOWN; 14845 } 14846 } 14847 14848 #ifdef THERMAL_STATS_SUPPORT 14849 static void 14850 populate_thermal_stats(WMI_THERM_THROT_STATS_EVENTID_param_tlvs *param_buf, 14851 uint32_t *therm_throt_levels, 14852 struct thermal_throt_level_stats *tt_temp_range_stats) 14853 { 14854 uint8_t lvl_idx; 14855 wmi_therm_throt_stats_event_fixed_param *tt_stats_event; 14856 wmi_thermal_throt_temp_range_stats *wmi_tt_stats; 14857 14858 tt_stats_event = param_buf->fixed_param; 14859 *therm_throt_levels = (tt_stats_event->therm_throt_levels > 14860 WMI_THERMAL_STATS_TEMP_THRESH_LEVEL_MAX) ? 14861 WMI_THERMAL_STATS_TEMP_THRESH_LEVEL_MAX : 14862 tt_stats_event->therm_throt_levels; 14863 14864 if (*therm_throt_levels > param_buf->num_temp_range_stats) { 14865 wmi_err("therm_throt_levels:%u oob num_temp_range_stats:%u", 14866 *therm_throt_levels, 14867 param_buf->num_temp_range_stats); 14868 return; 14869 } 14870 14871 wmi_tt_stats = param_buf->temp_range_stats; 14872 if (!wmi_tt_stats) { 14873 wmi_err("wmi_tt_stats Null"); 14874 return; 14875 } 14876 14877 for (lvl_idx = 0; lvl_idx < *therm_throt_levels; lvl_idx++) { 14878 tt_temp_range_stats[lvl_idx].start_temp_level = 14879 wmi_tt_stats[lvl_idx].start_temp_level; 14880 tt_temp_range_stats[lvl_idx].end_temp_level = 14881 wmi_tt_stats[lvl_idx].end_temp_level; 14882 tt_temp_range_stats[lvl_idx].total_time_ms_lo = 14883 wmi_tt_stats[lvl_idx].total_time_ms_lo; 14884 tt_temp_range_stats[lvl_idx].total_time_ms_hi = 14885 wmi_tt_stats[lvl_idx].total_time_ms_hi; 14886 tt_temp_range_stats[lvl_idx].num_entry = 14887 wmi_tt_stats[lvl_idx].num_entry; 14888 wmi_debug("level %d, start temp %d, end temp %d, total time low %d, total time high %d, counter %d", 14889 lvl_idx, wmi_tt_stats[lvl_idx].start_temp_level, 14890 wmi_tt_stats[lvl_idx].end_temp_level, 14891 wmi_tt_stats[lvl_idx].total_time_ms_lo, 14892 wmi_tt_stats[lvl_idx].total_time_ms_hi, 14893 wmi_tt_stats[lvl_idx].num_entry); 14894 } 14895 } 14896 #else 14897 static void 14898 populate_thermal_stats(WMI_THERM_THROT_STATS_EVENTID_param_tlvs *param_buf, 14899 uint32_t *therm_throt_levels, 14900 struct thermal_throt_level_stats *tt_temp_range_stats) 14901 { 14902 } 14903 #endif 14904 14905 /** 14906 * extract_thermal_stats_tlv() - extract thermal stats from event 14907 * @wmi_handle: wmi handle 14908 * @evt_buf: Pointer to event buffer 14909 * @temp: Pointer to hold extracted temperature 14910 * @level: Pointer to hold extracted level in host enum 14911 * @therm_throt_levels: Pointer to hold extracted thermal throttle temp 14912 * range 14913 * @tt_temp_range_stats_event: Pointer to hold extracted thermal stats for 14914 * every level 14915 * @pdev_id: Pointer to hold extracted pdev id 14916 * 14917 * Return: QDF_STATUS_SUCCESS for success or error code 14918 */ 14919 static QDF_STATUS 14920 extract_thermal_stats_tlv(wmi_unified_t wmi_handle, 14921 void *evt_buf, uint32_t *temp, 14922 enum thermal_throttle_level *level, 14923 uint32_t *therm_throt_levels, 14924 struct thermal_throt_level_stats *tt_temp_range_stats_event, 14925 uint32_t *pdev_id) 14926 { 14927 WMI_THERM_THROT_STATS_EVENTID_param_tlvs *param_buf; 14928 wmi_therm_throt_stats_event_fixed_param *tt_stats_event; 14929 14930 param_buf = 14931 (WMI_THERM_THROT_STATS_EVENTID_param_tlvs *) evt_buf; 14932 if (!param_buf) 14933 return QDF_STATUS_E_INVAL; 14934 14935 tt_stats_event = param_buf->fixed_param; 14936 wmi_debug("thermal temperature %d level %d", 14937 tt_stats_event->temp, tt_stats_event->level); 14938 *pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host( 14939 wmi_handle, 14940 tt_stats_event->pdev_id); 14941 *temp = tt_stats_event->temp; 14942 *level = wmi_tgt_thermal_level_to_host(tt_stats_event->level); 14943 14944 if (tt_stats_event->therm_throt_levels) 14945 populate_thermal_stats(param_buf, therm_throt_levels, 14946 tt_temp_range_stats_event); 14947 14948 return QDF_STATUS_SUCCESS; 14949 } 14950 14951 /** 14952 * extract_thermal_level_stats_tlv() - extract thermal level stats from event 14953 * @wmi_handle: wmi handle 14954 * @evt_buf: pointer to event buffer 14955 * @idx: Index to level stats 14956 * @levelcount: Pointer to hold levelcount 14957 * @dccount: Pointer to hold dccount 14958 * 14959 * Return: QDF_STATUS_SUCCESS for success or error code 14960 */ 14961 static QDF_STATUS 14962 extract_thermal_level_stats_tlv(wmi_unified_t wmi_handle, 14963 void *evt_buf, uint8_t idx, uint32_t *levelcount, 14964 uint32_t *dccount) 14965 { 14966 WMI_THERM_THROT_STATS_EVENTID_param_tlvs *param_buf; 14967 wmi_therm_throt_level_stats_info *tt_level_info; 14968 14969 param_buf = 14970 (WMI_THERM_THROT_STATS_EVENTID_param_tlvs *) evt_buf; 14971 if (!param_buf) 14972 return QDF_STATUS_E_INVAL; 14973 14974 tt_level_info = param_buf->therm_throt_level_stats_info; 14975 14976 if (idx < THERMAL_LEVELS) { 14977 *levelcount = tt_level_info[idx].level_count; 14978 *dccount = tt_level_info[idx].dc_count; 14979 return QDF_STATUS_SUCCESS; 14980 } 14981 14982 return QDF_STATUS_E_FAILURE; 14983 } 14984 14985 /** 14986 * fips_conv_data_be() - LE to BE conversion of FIPS ev data 14987 * @data_len: data length 14988 * @data: pointer to data 14989 * 14990 * Return: QDF_STATUS - success or error status 14991 */ 14992 #ifdef BIG_ENDIAN_HOST 14993 static QDF_STATUS fips_conv_data_be(uint32_t data_len, uint8_t *data) 14994 { 14995 uint8_t *data_aligned = NULL; 14996 int c; 14997 unsigned char *data_unaligned; 14998 14999 data_unaligned = qdf_mem_malloc(((sizeof(uint8_t) * data_len) + 15000 FIPS_ALIGN)); 15001 /* Assigning unaligned space to copy the data */ 15002 /* Checking if kmalloc does successful allocation */ 15003 if (!data_unaligned) 15004 return QDF_STATUS_E_FAILURE; 15005 15006 /* Checking if space is aligned */ 15007 if (!FIPS_IS_ALIGNED(data_unaligned, FIPS_ALIGN)) { 15008 /* align the data space */ 15009 data_aligned = 15010 (uint8_t *)FIPS_ALIGNTO(data_unaligned, FIPS_ALIGN); 15011 } else { 15012 data_aligned = (u_int8_t *)data_unaligned; 15013 } 15014 15015 /* memset and copy content from data to data aligned */ 15016 OS_MEMSET(data_aligned, 0, data_len); 15017 OS_MEMCPY(data_aligned, data, data_len); 15018 /* Endianness to LE */ 15019 for (c = 0; c < data_len/4; c++) { 15020 *((u_int32_t *)data_aligned + c) = 15021 qdf_le32_to_cpu(*((u_int32_t *)data_aligned + c)); 15022 } 15023 15024 /* Copy content to event->data */ 15025 OS_MEMCPY(data, data_aligned, data_len); 15026 15027 /* clean up allocated space */ 15028 qdf_mem_free(data_unaligned); 15029 data_aligned = NULL; 15030 data_unaligned = NULL; 15031 15032 /*************************************************************/ 15033 15034 return QDF_STATUS_SUCCESS; 15035 } 15036 #else 15037 static QDF_STATUS fips_conv_data_be(uint32_t data_len, uint8_t *data) 15038 { 15039 return QDF_STATUS_SUCCESS; 15040 } 15041 #endif 15042 15043 /** 15044 * send_pdev_get_pn_cmd_tlv() - send get PN request params to fw 15045 * @wmi_handle: wmi handle 15046 * @params: PN request params for peer 15047 * 15048 * Return: QDF_STATUS - success or error status 15049 */ 15050 static QDF_STATUS 15051 send_pdev_get_pn_cmd_tlv(wmi_unified_t wmi_handle, 15052 struct peer_request_pn_param *params) 15053 { 15054 wmi_peer_tx_pn_request_cmd_fixed_param *cmd; 15055 wmi_buf_t buf; 15056 uint8_t *buf_ptr; 15057 uint32_t len = sizeof(wmi_peer_tx_pn_request_cmd_fixed_param); 15058 15059 buf = wmi_buf_alloc(wmi_handle, len); 15060 if (!buf) { 15061 wmi_err("wmi_buf_alloc failed"); 15062 return QDF_STATUS_E_FAILURE; 15063 } 15064 15065 buf_ptr = (uint8_t *)wmi_buf_data(buf); 15066 cmd = (wmi_peer_tx_pn_request_cmd_fixed_param *)buf_ptr; 15067 15068 WMITLV_SET_HDR(&cmd->tlv_header, 15069 WMITLV_TAG_STRUC_wmi_peer_tx_pn_request_cmd_fixed_param, 15070 WMITLV_GET_STRUCT_TLVLEN(wmi_peer_tx_pn_request_cmd_fixed_param)); 15071 15072 cmd->vdev_id = params->vdev_id; 15073 WMI_CHAR_ARRAY_TO_MAC_ADDR(params->peer_macaddr, &cmd->peer_macaddr); 15074 cmd->key_type = params->key_type; 15075 cmd->key_ix = params->keyix; 15076 if (wmi_unified_cmd_send(wmi_handle, buf, len, 15077 WMI_PEER_TX_PN_REQUEST_CMDID)) { 15078 wmi_err("Failed to send WMI command"); 15079 wmi_buf_free(buf); 15080 return QDF_STATUS_E_FAILURE; 15081 } 15082 return QDF_STATUS_SUCCESS; 15083 } 15084 15085 /** 15086 * extract_get_pn_data_tlv() - extract pn resp 15087 * @wmi_handle: wmi handle 15088 * @evt_buf: pointer to event buffer 15089 * @param: PN response params for peer 15090 * 15091 * Return: QDF_STATUS - success or error status 15092 */ 15093 static QDF_STATUS 15094 extract_get_pn_data_tlv(wmi_unified_t wmi_handle, void *evt_buf, 15095 struct wmi_host_get_pn_event *param) 15096 { 15097 WMI_PEER_TX_PN_RESPONSE_EVENTID_param_tlvs *param_buf; 15098 wmi_peer_tx_pn_response_event_fixed_param *event = NULL; 15099 15100 param_buf = (WMI_PEER_TX_PN_RESPONSE_EVENTID_param_tlvs *)evt_buf; 15101 event = 15102 (wmi_peer_tx_pn_response_event_fixed_param *)param_buf->fixed_param; 15103 15104 param->vdev_id = event->vdev_id; 15105 param->key_type = event->key_type; 15106 param->key_ix = event->key_ix; 15107 qdf_mem_copy(param->pn, event->pn, sizeof(event->pn)); 15108 WMI_MAC_ADDR_TO_CHAR_ARRAY(&event->peer_macaddr, param->mac_addr); 15109 15110 return QDF_STATUS_SUCCESS; 15111 } 15112 15113 /** 15114 * send_pdev_get_rxpn_cmd_tlv() - send get Rx PN request params to fw 15115 * @wmi_handle: wmi handle 15116 * @params: Rx PN request params for peer 15117 * 15118 * Return: QDF_STATUS - success or error status 15119 */ 15120 static QDF_STATUS 15121 send_pdev_get_rxpn_cmd_tlv(wmi_unified_t wmi_handle, 15122 struct peer_request_rxpn_param *params) 15123 { 15124 wmi_peer_rx_pn_request_cmd_fixed_param *cmd; 15125 wmi_buf_t buf; 15126 uint8_t *buf_ptr; 15127 uint32_t len = sizeof(wmi_peer_rx_pn_request_cmd_fixed_param); 15128 15129 if (!is_service_enabled_tlv(wmi_handle, 15130 WMI_SERVICE_PN_REPLAY_CHECK_SUPPORT)) { 15131 wmi_err("Rx PN Replay Check not supported by target"); 15132 return QDF_STATUS_E_NOSUPPORT; 15133 } 15134 15135 buf = wmi_buf_alloc(wmi_handle, len); 15136 if (!buf) { 15137 wmi_err("wmi_buf_alloc failed"); 15138 return QDF_STATUS_E_FAILURE; 15139 } 15140 15141 buf_ptr = (uint8_t *)wmi_buf_data(buf); 15142 cmd = (wmi_peer_rx_pn_request_cmd_fixed_param *)buf_ptr; 15143 15144 WMITLV_SET_HDR(&cmd->tlv_header, 15145 WMITLV_TAG_STRUC_wmi_peer_rx_pn_request_cmd_fixed_param, 15146 WMITLV_GET_STRUCT_TLVLEN(wmi_peer_rx_pn_request_cmd_fixed_param)); 15147 15148 cmd->vdev_id = params->vdev_id; 15149 WMI_CHAR_ARRAY_TO_MAC_ADDR(params->peer_macaddr, &cmd->peer_macaddr); 15150 cmd->key_ix = params->keyix; 15151 if (wmi_unified_cmd_send(wmi_handle, buf, len, 15152 WMI_PEER_RX_PN_REQUEST_CMDID)) { 15153 wmi_err("Failed to send WMI command"); 15154 wmi_buf_free(buf); 15155 return QDF_STATUS_E_FAILURE; 15156 } 15157 return QDF_STATUS_SUCCESS; 15158 } 15159 15160 /** 15161 * extract_get_rxpn_data_tlv() - extract Rx PN resp 15162 * @wmi_handle: wmi handle 15163 * @evt_buf: pointer to event buffer 15164 * @params: Rx PN response params for peer 15165 * 15166 * Return: QDF_STATUS - success or error status 15167 */ 15168 static QDF_STATUS 15169 extract_get_rxpn_data_tlv(wmi_unified_t wmi_handle, void *evt_buf, 15170 struct wmi_host_get_rxpn_event *params) 15171 { 15172 WMI_PEER_RX_PN_RESPONSE_EVENTID_param_tlvs *param_buf; 15173 wmi_peer_rx_pn_response_event_fixed_param *event; 15174 15175 param_buf = evt_buf; 15176 event = param_buf->fixed_param; 15177 15178 params->vdev_id = event->vdev_id; 15179 params->keyix = event->key_idx; 15180 qdf_mem_copy(params->pn, event->pn, sizeof(event->pn)); 15181 WMI_MAC_ADDR_TO_CHAR_ARRAY(&event->peer_macaddr, params->mac_addr); 15182 15183 return QDF_STATUS_SUCCESS; 15184 } 15185 15186 /** 15187 * extract_fips_event_data_tlv() - extract fips event data 15188 * @wmi_handle: wmi handle 15189 * @evt_buf: pointer to event buffer 15190 * @param: pointer FIPS event params 15191 * 15192 * Return: QDF_STATUS_SUCCESS for success or error code 15193 */ 15194 static QDF_STATUS extract_fips_event_data_tlv(wmi_unified_t wmi_handle, 15195 void *evt_buf, struct wmi_host_fips_event_param *param) 15196 { 15197 WMI_PDEV_FIPS_EVENTID_param_tlvs *param_buf; 15198 wmi_pdev_fips_event_fixed_param *event; 15199 15200 param_buf = (WMI_PDEV_FIPS_EVENTID_param_tlvs *) evt_buf; 15201 event = (wmi_pdev_fips_event_fixed_param *) param_buf->fixed_param; 15202 15203 if (event->data_len > param_buf->num_data) 15204 return QDF_STATUS_E_FAILURE; 15205 15206 if (fips_conv_data_be(event->data_len, param_buf->data) != 15207 QDF_STATUS_SUCCESS) 15208 return QDF_STATUS_E_FAILURE; 15209 15210 param->data = (uint32_t *)param_buf->data; 15211 param->data_len = event->data_len; 15212 param->error_status = event->error_status; 15213 param->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host( 15214 wmi_handle, 15215 event->pdev_id); 15216 15217 return QDF_STATUS_SUCCESS; 15218 } 15219 15220 #ifdef WLAN_FEATURE_FIPS_BER_CCMGCM 15221 /** 15222 * extract_fips_extend_event_data_tlv() - extract fips event data 15223 * @wmi_handle: wmi handle 15224 * @evt_buf: pointer to event buffer 15225 * @param: pointer FIPS event params 15226 * 15227 * Return: QDF_STATUS_SUCCESS for success or error code 15228 */ 15229 static QDF_STATUS 15230 extract_fips_extend_event_data_tlv(wmi_unified_t wmi_handle, 15231 void *evt_buf, 15232 struct wmi_host_fips_extend_event_param 15233 *param) 15234 { 15235 WMI_PDEV_FIPS_EXTEND_EVENTID_param_tlvs *param_buf; 15236 wmi_pdev_fips_extend_event_fixed_param *event; 15237 15238 param_buf = (WMI_PDEV_FIPS_EXTEND_EVENTID_param_tlvs *)evt_buf; 15239 event = (wmi_pdev_fips_extend_event_fixed_param *)param_buf->fixed_param; 15240 15241 if (fips_conv_data_be(event->data_len, param_buf->data) != 15242 QDF_STATUS_SUCCESS) 15243 return QDF_STATUS_E_FAILURE; 15244 15245 param->data = (uint32_t *)param_buf->data; 15246 param->data_len = event->data_len; 15247 param->error_status = event->error_status; 15248 param->fips_cookie = event->fips_cookie; 15249 param->cmd_frag_idx = event->cmd_frag_idx; 15250 param->more_bit = event->more_bit; 15251 param->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host( 15252 wmi_handle, 15253 event->pdev_id); 15254 15255 return QDF_STATUS_SUCCESS; 15256 } 15257 #endif 15258 15259 #ifdef WLAN_FEATURE_DISA 15260 /** 15261 * extract_encrypt_decrypt_resp_event_tlv() - extract encrypt decrypt resp 15262 * params from event 15263 * @wmi_handle: wmi handle 15264 * @evt_buf: pointer to event buffer 15265 * @resp: Pointer to hold resp parameters 15266 * 15267 * Return: QDF_STATUS_SUCCESS for success or error code 15268 */ 15269 static QDF_STATUS 15270 extract_encrypt_decrypt_resp_event_tlv(wmi_unified_t wmi_handle, 15271 void *evt_buf, 15272 struct disa_encrypt_decrypt_resp_params 15273 *resp) 15274 { 15275 WMI_VDEV_ENCRYPT_DECRYPT_DATA_RESP_EVENTID_param_tlvs *param_buf; 15276 wmi_vdev_encrypt_decrypt_data_resp_event_fixed_param *data_event; 15277 15278 param_buf = evt_buf; 15279 if (!param_buf) { 15280 wmi_err("encrypt decrypt resp evt_buf is NULL"); 15281 return QDF_STATUS_E_INVAL; 15282 } 15283 15284 data_event = param_buf->fixed_param; 15285 15286 resp->vdev_id = data_event->vdev_id; 15287 resp->status = data_event->status; 15288 15289 if ((data_event->data_length > param_buf->num_enc80211_frame) || 15290 (data_event->data_length > WMI_SVC_MSG_MAX_SIZE - 15291 WMI_TLV_HDR_SIZE - sizeof(*data_event))) { 15292 wmi_err("FW msg data_len %d more than TLV hdr %d", 15293 data_event->data_length, 15294 param_buf->num_enc80211_frame); 15295 return QDF_STATUS_E_INVAL; 15296 } 15297 15298 resp->data_len = data_event->data_length; 15299 15300 if (resp->data_len) 15301 resp->data = (uint8_t *)param_buf->enc80211_frame; 15302 15303 return QDF_STATUS_SUCCESS; 15304 } 15305 #endif /* WLAN_FEATURE_DISA */ 15306 15307 static bool is_management_record_tlv(uint32_t cmd_id) 15308 { 15309 switch (cmd_id) { 15310 case WMI_MGMT_TX_SEND_CMDID: 15311 case WMI_MGMT_TX_COMPLETION_EVENTID: 15312 case WMI_OFFCHAN_DATA_TX_SEND_CMDID: 15313 case WMI_MGMT_RX_EVENTID: 15314 return true; 15315 default: 15316 return false; 15317 } 15318 } 15319 15320 static bool is_diag_event_tlv(uint32_t event_id) 15321 { 15322 if (WMI_DIAG_EVENTID == event_id) 15323 return true; 15324 15325 return false; 15326 } 15327 15328 static uint16_t wmi_tag_fw_hang_cmd(wmi_unified_t wmi_handle) 15329 { 15330 uint16_t tag = 0; 15331 15332 if (qdf_atomic_read(&wmi_handle->is_target_suspended)) { 15333 qdf_nofl_err("%s: Target is already suspended, Ignore FW Hang Command", 15334 __func__); 15335 return tag; 15336 } 15337 15338 if (wmi_handle->tag_crash_inject) 15339 tag = HTC_TX_PACKET_TAG_AUTO_PM; 15340 15341 wmi_handle->tag_crash_inject = false; 15342 return tag; 15343 } 15344 15345 /** 15346 * wmi_set_htc_tx_tag_tlv() - set HTC TX tag for WMI commands 15347 * @wmi_handle: WMI handle 15348 * @buf: WMI buffer 15349 * @cmd_id: WMI command Id 15350 * 15351 * Return: htc_tx_tag 15352 */ 15353 static uint16_t wmi_set_htc_tx_tag_tlv(wmi_unified_t wmi_handle, 15354 wmi_buf_t buf, 15355 uint32_t cmd_id) 15356 { 15357 uint16_t htc_tx_tag = 0; 15358 15359 switch (cmd_id) { 15360 case WMI_WOW_ENABLE_CMDID: 15361 case WMI_PDEV_SUSPEND_CMDID: 15362 case WMI_WOW_HOSTWAKEUP_FROM_SLEEP_CMDID: 15363 case WMI_PDEV_RESUME_CMDID: 15364 case WMI_HB_SET_ENABLE_CMDID: 15365 case WMI_WOW_SET_ACTION_WAKE_UP_CMDID: 15366 #ifdef FEATURE_WLAN_D0WOW 15367 case WMI_D0_WOW_ENABLE_DISABLE_CMDID: 15368 #endif 15369 htc_tx_tag = HTC_TX_PACKET_TAG_AUTO_PM; 15370 break; 15371 case WMI_FORCE_FW_HANG_CMDID: 15372 htc_tx_tag = wmi_tag_fw_hang_cmd(wmi_handle); 15373 break; 15374 default: 15375 break; 15376 } 15377 15378 return htc_tx_tag; 15379 } 15380 15381 #ifdef CONFIG_BAND_6GHZ 15382 15383 static struct cur_reg_rule 15384 *create_ext_reg_rules_from_wmi(uint32_t num_reg_rules, 15385 wmi_regulatory_rule_ext_struct *wmi_reg_rule) 15386 { 15387 struct cur_reg_rule *reg_rule_ptr; 15388 uint32_t count; 15389 15390 if (!num_reg_rules) 15391 return NULL; 15392 15393 reg_rule_ptr = qdf_mem_malloc(num_reg_rules * 15394 sizeof(*reg_rule_ptr)); 15395 15396 if (!reg_rule_ptr) 15397 return NULL; 15398 15399 for (count = 0; count < num_reg_rules; count++) { 15400 reg_rule_ptr[count].start_freq = 15401 WMI_REG_RULE_START_FREQ_GET( 15402 wmi_reg_rule[count].freq_info); 15403 reg_rule_ptr[count].end_freq = 15404 WMI_REG_RULE_END_FREQ_GET( 15405 wmi_reg_rule[count].freq_info); 15406 reg_rule_ptr[count].max_bw = 15407 WMI_REG_RULE_MAX_BW_GET( 15408 wmi_reg_rule[count].bw_pwr_info); 15409 reg_rule_ptr[count].reg_power = 15410 WMI_REG_RULE_REG_POWER_GET( 15411 wmi_reg_rule[count].bw_pwr_info); 15412 reg_rule_ptr[count].ant_gain = 15413 WMI_REG_RULE_ANTENNA_GAIN_GET( 15414 wmi_reg_rule[count].bw_pwr_info); 15415 reg_rule_ptr[count].flags = 15416 WMI_REG_RULE_FLAGS_GET( 15417 wmi_reg_rule[count].flag_info); 15418 reg_rule_ptr[count].psd_flag = 15419 WMI_REG_RULE_PSD_FLAG_GET( 15420 wmi_reg_rule[count].psd_power_info); 15421 reg_rule_ptr[count].psd_eirp = 15422 WMI_REG_RULE_PSD_EIRP_GET( 15423 wmi_reg_rule[count].psd_power_info); 15424 } 15425 15426 return reg_rule_ptr; 15427 } 15428 #endif 15429 15430 static struct cur_reg_rule 15431 *create_reg_rules_from_wmi(uint32_t num_reg_rules, 15432 wmi_regulatory_rule_struct *wmi_reg_rule) 15433 { 15434 struct cur_reg_rule *reg_rule_ptr; 15435 uint32_t count; 15436 15437 if (!num_reg_rules) 15438 return NULL; 15439 15440 reg_rule_ptr = qdf_mem_malloc(num_reg_rules * 15441 sizeof(*reg_rule_ptr)); 15442 15443 if (!reg_rule_ptr) 15444 return NULL; 15445 15446 for (count = 0; count < num_reg_rules; count++) { 15447 reg_rule_ptr[count].start_freq = 15448 WMI_REG_RULE_START_FREQ_GET( 15449 wmi_reg_rule[count].freq_info); 15450 reg_rule_ptr[count].end_freq = 15451 WMI_REG_RULE_END_FREQ_GET( 15452 wmi_reg_rule[count].freq_info); 15453 reg_rule_ptr[count].max_bw = 15454 WMI_REG_RULE_MAX_BW_GET( 15455 wmi_reg_rule[count].bw_pwr_info); 15456 reg_rule_ptr[count].reg_power = 15457 WMI_REG_RULE_REG_POWER_GET( 15458 wmi_reg_rule[count].bw_pwr_info); 15459 reg_rule_ptr[count].ant_gain = 15460 WMI_REG_RULE_ANTENNA_GAIN_GET( 15461 wmi_reg_rule[count].bw_pwr_info); 15462 reg_rule_ptr[count].flags = 15463 WMI_REG_RULE_FLAGS_GET( 15464 wmi_reg_rule[count].flag_info); 15465 } 15466 15467 return reg_rule_ptr; 15468 } 15469 15470 static enum cc_setting_code wmi_reg_status_to_reg_status( 15471 WMI_REG_SET_CC_STATUS_CODE wmi_status_code) 15472 { 15473 if (wmi_status_code == WMI_REG_SET_CC_STATUS_PASS) { 15474 wmi_nofl_debug("REG_SET_CC_STATUS_PASS"); 15475 return REG_SET_CC_STATUS_PASS; 15476 } else if (wmi_status_code == WMI_REG_CURRENT_ALPHA2_NOT_FOUND) { 15477 wmi_nofl_debug("WMI_REG_CURRENT_ALPHA2_NOT_FOUND"); 15478 return REG_CURRENT_ALPHA2_NOT_FOUND; 15479 } else if (wmi_status_code == WMI_REG_INIT_ALPHA2_NOT_FOUND) { 15480 wmi_nofl_debug("WMI_REG_INIT_ALPHA2_NOT_FOUND"); 15481 return REG_INIT_ALPHA2_NOT_FOUND; 15482 } else if (wmi_status_code == WMI_REG_SET_CC_CHANGE_NOT_ALLOWED) { 15483 wmi_nofl_debug("WMI_REG_SET_CC_CHANGE_NOT_ALLOWED"); 15484 return REG_SET_CC_CHANGE_NOT_ALLOWED; 15485 } else if (wmi_status_code == WMI_REG_SET_CC_STATUS_NO_MEMORY) { 15486 wmi_nofl_debug("WMI_REG_SET_CC_STATUS_NO_MEMORY"); 15487 return REG_SET_CC_STATUS_NO_MEMORY; 15488 } else if (wmi_status_code == WMI_REG_SET_CC_STATUS_FAIL) { 15489 wmi_nofl_debug("WMI_REG_SET_CC_STATUS_FAIL"); 15490 return REG_SET_CC_STATUS_FAIL; 15491 } 15492 15493 wmi_debug("Unknown reg status code from WMI"); 15494 return REG_SET_CC_STATUS_FAIL; 15495 } 15496 15497 #ifdef CONFIG_BAND_6GHZ 15498 /** 15499 * reg_print_ap_power_type_6ghz - Prints the AP Power type 15500 * @ap_type: 6ghz-AP Power type 15501 * 15502 * Return: void 15503 */ 15504 static void reg_print_ap_power_type_6ghz(enum reg_6g_ap_type ap_type) 15505 { 15506 switch (ap_type) { 15507 case REG_INDOOR_AP: 15508 wmi_nofl_debug("AP Power type %s", "LOW POWER INDOOR"); 15509 break; 15510 case REG_STANDARD_POWER_AP: 15511 wmi_nofl_debug("AP Power type %s", "STANDARD POWER"); 15512 break; 15513 case REG_VERY_LOW_POWER_AP: 15514 wmi_nofl_debug("AP Power type %s", "VERY LOW POWER INDOOR"); 15515 break; 15516 default: 15517 wmi_nofl_debug("Invalid AP Power type %u", ap_type); 15518 } 15519 } 15520 15521 /** 15522 * reg_print_6ghz_client_type - Prints the client type 15523 * @client_type: 6ghz-client type 15524 * 15525 * Return: void 15526 */ 15527 static void reg_print_6ghz_client_type(enum reg_6g_client_type client_type) 15528 { 15529 switch (client_type) { 15530 case REG_DEFAULT_CLIENT: 15531 wmi_nofl_debug("Client type %s", "DEFAULT CLIENT"); 15532 break; 15533 case REG_SUBORDINATE_CLIENT: 15534 wmi_nofl_debug("Client type %s", "SUBORDINATE CLIENT"); 15535 break; 15536 default: 15537 wmi_nofl_debug("Invalid Client type %u", client_type); 15538 } 15539 } 15540 #else 15541 static inline void reg_print_ap_power_type_6ghz(enum reg_6g_ap_type ap_type) 15542 { 15543 } 15544 15545 static inline void reg_print_6ghz_client_type(enum reg_6g_client_type client_type) 15546 { 15547 } 15548 #endif /* CONFIG_BAND_6GHZ */ 15549 15550 #ifdef CONFIG_BAND_6GHZ 15551 15552 #ifdef CONFIG_REG_CLIENT 15553 #define MAX_NUM_FCC_RULES 2 15554 15555 /** 15556 * extract_ext_fcc_rules_from_wmi - extract fcc rules from WMI TLV 15557 * @num_fcc_rules: Number of FCC rules 15558 * @wmi_fcc_rule: WMI FCC rules TLV 15559 * 15560 * Return: fcc_rule_ptr 15561 */ 15562 static struct cur_fcc_rule 15563 *extract_ext_fcc_rules_from_wmi(uint32_t num_fcc_rules, 15564 wmi_regulatory_fcc_rule_struct *wmi_fcc_rule) 15565 { 15566 struct cur_fcc_rule *fcc_rule_ptr; 15567 uint32_t count; 15568 15569 if (!wmi_fcc_rule) 15570 return NULL; 15571 15572 fcc_rule_ptr = qdf_mem_malloc(num_fcc_rules * 15573 sizeof(*fcc_rule_ptr)); 15574 if (!fcc_rule_ptr) 15575 return NULL; 15576 15577 for (count = 0; count < num_fcc_rules; count++) { 15578 fcc_rule_ptr[count].center_freq = 15579 WMI_REG_FCC_RULE_CHAN_FREQ_GET( 15580 wmi_fcc_rule[count].freq_info); 15581 fcc_rule_ptr[count].tx_power = 15582 WMI_REG_FCC_RULE_FCC_TX_POWER_GET( 15583 wmi_fcc_rule[count].freq_info); 15584 } 15585 15586 return fcc_rule_ptr; 15587 } 15588 15589 /** 15590 * extract_reg_fcc_rules_tlv - Extract reg fcc rules TLV 15591 * @param_buf: Pointer to WMI params TLV 15592 * @ext_chan_list_event_hdr: Pointer to REG CHAN LIST CC EXT EVENT Fixed 15593 * Params TLV 15594 * @ext_wmi_reg_rule: Pointer to REG CHAN LIST CC EXT EVENT Reg Rules TLV 15595 * @ext_wmi_chan_priority: Pointer to REG CHAN LIST CC EXT EVENT Chan 15596 * Priority TLV 15597 * @evt_buf: Pointer to REG CHAN LIST CC EXT EVENT event buffer 15598 * @reg_info: Pointer to Regulatory Info 15599 * @len: Length of REG CHAN LIST CC EXT EVENT buffer 15600 * 15601 * Return: QDF_STATUS 15602 */ 15603 static QDF_STATUS extract_reg_fcc_rules_tlv( 15604 WMI_REG_CHAN_LIST_CC_EXT_EVENTID_param_tlvs *param_buf, 15605 wmi_reg_chan_list_cc_event_ext_fixed_param *ext_chan_list_event_hdr, 15606 wmi_regulatory_rule_ext_struct *ext_wmi_reg_rule, 15607 wmi_regulatory_chan_priority_struct *ext_wmi_chan_priority, 15608 uint8_t *evt_buf, 15609 struct cur_regulatory_info *reg_info, 15610 uint32_t len) 15611 { 15612 int i; 15613 wmi_regulatory_fcc_rule_struct *ext_wmi_fcc_rule; 15614 15615 if (!param_buf) { 15616 wmi_err("invalid channel list event buf"); 15617 return QDF_STATUS_E_INVAL; 15618 } 15619 15620 reg_info->num_fcc_rules = 0; 15621 if (param_buf->reg_fcc_rule) { 15622 if (param_buf->num_reg_fcc_rule > MAX_NUM_FCC_RULES) { 15623 wmi_err("Number of fcc rules is greater than MAX_NUM_FCC_RULES"); 15624 return QDF_STATUS_E_INVAL; 15625 } 15626 15627 ext_wmi_fcc_rule = 15628 (wmi_regulatory_fcc_rule_struct *) 15629 ((uint8_t *)ext_chan_list_event_hdr + 15630 sizeof(wmi_reg_chan_list_cc_event_ext_fixed_param) + 15631 WMI_TLV_HDR_SIZE + 15632 sizeof(wmi_regulatory_rule_ext_struct) * 15633 param_buf->num_reg_rule_array + 15634 WMI_TLV_HDR_SIZE + 15635 sizeof(wmi_regulatory_chan_priority_struct) * 15636 param_buf->num_reg_chan_priority + 15637 WMI_TLV_HDR_SIZE); 15638 15639 reg_info->fcc_rules_ptr = extract_ext_fcc_rules_from_wmi( 15640 param_buf->num_reg_fcc_rule, 15641 ext_wmi_fcc_rule); 15642 15643 reg_info->num_fcc_rules = param_buf->num_reg_fcc_rule; 15644 } else { 15645 wmi_err("Fcc rules not sent by fw"); 15646 } 15647 15648 if (reg_info->fcc_rules_ptr) { 15649 for (i = 0; i < reg_info->num_fcc_rules; i++) { 15650 wmi_nofl_debug("FCC rule %d center_freq %d tx_power %d", 15651 i, reg_info->fcc_rules_ptr[i].center_freq, 15652 reg_info->fcc_rules_ptr[i].tx_power); 15653 } 15654 } 15655 return QDF_STATUS_SUCCESS; 15656 } 15657 #else 15658 static QDF_STATUS extract_reg_fcc_rules_tlv( 15659 WMI_REG_CHAN_LIST_CC_EXT_EVENTID_param_tlvs *param_buf, 15660 wmi_reg_chan_list_cc_event_ext_fixed_param *ext_chan_list_event_hdr, 15661 wmi_regulatory_rule_ext_struct *ext_wmi_reg_rule, 15662 wmi_regulatory_chan_priority_struct *ext_wmi_chan_priority, 15663 uint8_t *evt_buf, 15664 struct cur_regulatory_info *reg_info, 15665 uint32_t len) 15666 { 15667 return QDF_STATUS_SUCCESS; 15668 } 15669 #endif 15670 15671 static QDF_STATUS extract_reg_chan_list_ext_update_event_tlv( 15672 wmi_unified_t wmi_handle, uint8_t *evt_buf, 15673 struct cur_regulatory_info *reg_info, uint32_t len) 15674 { 15675 uint32_t i, j, k; 15676 WMI_REG_CHAN_LIST_CC_EXT_EVENTID_param_tlvs *param_buf; 15677 wmi_reg_chan_list_cc_event_ext_fixed_param *ext_chan_list_event_hdr; 15678 wmi_regulatory_rule_ext_struct *ext_wmi_reg_rule; 15679 wmi_regulatory_chan_priority_struct *ext_wmi_chan_priority; 15680 uint32_t num_2g_reg_rules, num_5g_reg_rules; 15681 uint32_t num_6g_reg_rules_ap[REG_CURRENT_MAX_AP_TYPE]; 15682 uint32_t *num_6g_reg_rules_client[REG_CURRENT_MAX_AP_TYPE]; 15683 uint32_t total_reg_rules = 0; 15684 QDF_STATUS status; 15685 15686 param_buf = (WMI_REG_CHAN_LIST_CC_EXT_EVENTID_param_tlvs *)evt_buf; 15687 if (!param_buf) { 15688 wmi_err("invalid channel list event buf"); 15689 return QDF_STATUS_E_FAILURE; 15690 } 15691 15692 ext_chan_list_event_hdr = param_buf->fixed_param; 15693 ext_wmi_chan_priority = param_buf->reg_chan_priority; 15694 15695 if (ext_wmi_chan_priority) 15696 reg_info->reg_6g_thresh_priority_freq = 15697 WMI_GET_BITS(ext_wmi_chan_priority->freq_info, 0, 16); 15698 reg_info->num_2g_reg_rules = ext_chan_list_event_hdr->num_2g_reg_rules; 15699 reg_info->num_5g_reg_rules = ext_chan_list_event_hdr->num_5g_reg_rules; 15700 reg_info->num_6g_reg_rules_ap[REG_STANDARD_POWER_AP] = 15701 ext_chan_list_event_hdr->num_6g_reg_rules_ap_sp; 15702 reg_info->num_6g_reg_rules_ap[REG_INDOOR_AP] = 15703 ext_chan_list_event_hdr->num_6g_reg_rules_ap_lpi; 15704 reg_info->num_6g_reg_rules_ap[REG_VERY_LOW_POWER_AP] = 15705 ext_chan_list_event_hdr->num_6g_reg_rules_ap_vlp; 15706 15707 wmi_debug("num reg rules from fw, AP SP %d, LPI %d, VLP %d", 15708 reg_info->num_6g_reg_rules_ap[REG_STANDARD_POWER_AP], 15709 reg_info->num_6g_reg_rules_ap[REG_INDOOR_AP], 15710 reg_info->num_6g_reg_rules_ap[REG_VERY_LOW_POWER_AP]); 15711 15712 for (i = 0; i < REG_MAX_CLIENT_TYPE; i++) { 15713 reg_info->num_6g_reg_rules_client[REG_STANDARD_POWER_AP][i] = 15714 ext_chan_list_event_hdr->num_6g_reg_rules_client_sp[i]; 15715 reg_info->num_6g_reg_rules_client[REG_INDOOR_AP][i] = 15716 ext_chan_list_event_hdr->num_6g_reg_rules_client_lpi[i]; 15717 reg_info->num_6g_reg_rules_client[REG_VERY_LOW_POWER_AP][i] = 15718 ext_chan_list_event_hdr->num_6g_reg_rules_client_vlp[i]; 15719 wmi_nofl_debug("client %d SP %d, LPI %d, VLP %d", i, 15720 ext_chan_list_event_hdr->num_6g_reg_rules_client_sp[i], 15721 ext_chan_list_event_hdr->num_6g_reg_rules_client_lpi[i], 15722 ext_chan_list_event_hdr->num_6g_reg_rules_client_vlp[i]); 15723 } 15724 15725 num_2g_reg_rules = reg_info->num_2g_reg_rules; 15726 total_reg_rules += num_2g_reg_rules; 15727 num_5g_reg_rules = reg_info->num_5g_reg_rules; 15728 total_reg_rules += num_5g_reg_rules; 15729 for (i = 0; i < REG_CURRENT_MAX_AP_TYPE; i++) { 15730 num_6g_reg_rules_ap[i] = reg_info->num_6g_reg_rules_ap[i]; 15731 if (num_6g_reg_rules_ap[i] > MAX_6G_REG_RULES) { 15732 wmi_err_rl("Invalid num_6g_reg_rules_ap: %u", 15733 num_6g_reg_rules_ap[i]); 15734 return QDF_STATUS_E_FAILURE; 15735 } 15736 total_reg_rules += num_6g_reg_rules_ap[i]; 15737 num_6g_reg_rules_client[i] = 15738 reg_info->num_6g_reg_rules_client[i]; 15739 } 15740 15741 for (i = 0; i < REG_MAX_CLIENT_TYPE; i++) { 15742 total_reg_rules += 15743 num_6g_reg_rules_client[REG_STANDARD_POWER_AP][i]; 15744 total_reg_rules += num_6g_reg_rules_client[REG_INDOOR_AP][i]; 15745 total_reg_rules += 15746 num_6g_reg_rules_client[REG_VERY_LOW_POWER_AP][i]; 15747 if ((num_6g_reg_rules_client[REG_STANDARD_POWER_AP][i] > 15748 MAX_6G_REG_RULES) || 15749 (num_6g_reg_rules_client[REG_INDOOR_AP][i] > 15750 MAX_6G_REG_RULES) || 15751 (num_6g_reg_rules_client[REG_VERY_LOW_POWER_AP][i] > 15752 MAX_6G_REG_RULES)) { 15753 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", 15754 num_6g_reg_rules_client[REG_STANDARD_POWER_AP][i], 15755 num_6g_reg_rules_client[REG_INDOOR_AP][i], 15756 num_6g_reg_rules_client[REG_VERY_LOW_POWER_AP][i], 15757 i); 15758 return QDF_STATUS_E_FAILURE; 15759 } 15760 } 15761 15762 if (total_reg_rules != param_buf->num_reg_rule_array) { 15763 wmi_err_rl("Total reg rules %u does not match event params num reg rule %u", 15764 total_reg_rules, param_buf->num_reg_rule_array); 15765 return QDF_STATUS_E_FAILURE; 15766 } 15767 15768 if ((num_2g_reg_rules > MAX_REG_RULES) || 15769 (num_5g_reg_rules > MAX_REG_RULES)) { 15770 wmi_err_rl("Invalid num_2g_reg_rules: %u, num_5g_reg_rules: %u", 15771 num_2g_reg_rules, num_5g_reg_rules); 15772 return QDF_STATUS_E_FAILURE; 15773 } 15774 15775 if ((num_6g_reg_rules_ap[REG_STANDARD_POWER_AP] > MAX_6G_REG_RULES) || 15776 (num_6g_reg_rules_ap[REG_INDOOR_AP] > MAX_6G_REG_RULES) || 15777 (num_6g_reg_rules_ap[REG_VERY_LOW_POWER_AP] > MAX_6G_REG_RULES)) { 15778 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", 15779 num_6g_reg_rules_ap[REG_STANDARD_POWER_AP], 15780 num_6g_reg_rules_ap[REG_INDOOR_AP], 15781 num_6g_reg_rules_ap[REG_VERY_LOW_POWER_AP]); 15782 return QDF_STATUS_E_FAILURE; 15783 } 15784 15785 if (param_buf->num_reg_rule_array > 15786 (WMI_SVC_MSG_MAX_SIZE - sizeof(*ext_chan_list_event_hdr)) / 15787 sizeof(*ext_wmi_reg_rule)) { 15788 wmi_err_rl("Invalid ext_num_reg_rule_array: %u", 15789 param_buf->num_reg_rule_array); 15790 return QDF_STATUS_E_FAILURE; 15791 } 15792 15793 qdf_mem_copy(reg_info->alpha2, &ext_chan_list_event_hdr->alpha2, 15794 REG_ALPHA2_LEN); 15795 reg_info->dfs_region = ext_chan_list_event_hdr->dfs_region; 15796 reg_info->phybitmap = convert_phybitmap_tlv( 15797 ext_chan_list_event_hdr->phybitmap); 15798 reg_info->offload_enabled = true; 15799 reg_info->num_phy = ext_chan_list_event_hdr->num_phy; 15800 reg_info->phy_id = wmi_handle->ops->convert_phy_id_target_to_host( 15801 wmi_handle, ext_chan_list_event_hdr->phy_id); 15802 reg_info->ctry_code = ext_chan_list_event_hdr->country_id; 15803 reg_info->reg_dmn_pair = ext_chan_list_event_hdr->domain_code; 15804 15805 reg_info->status_code = 15806 wmi_reg_status_to_reg_status(ext_chan_list_event_hdr-> 15807 status_code); 15808 15809 reg_info->min_bw_2g = ext_chan_list_event_hdr->min_bw_2g; 15810 reg_info->max_bw_2g = ext_chan_list_event_hdr->max_bw_2g; 15811 reg_info->min_bw_5g = ext_chan_list_event_hdr->min_bw_5g; 15812 reg_info->max_bw_5g = ext_chan_list_event_hdr->max_bw_5g; 15813 reg_info->min_bw_6g_ap[REG_STANDARD_POWER_AP] = 15814 ext_chan_list_event_hdr->min_bw_6g_ap_sp; 15815 reg_info->max_bw_6g_ap[REG_STANDARD_POWER_AP] = 15816 ext_chan_list_event_hdr->max_bw_6g_ap_sp; 15817 reg_info->min_bw_6g_ap[REG_INDOOR_AP] = 15818 ext_chan_list_event_hdr->min_bw_6g_ap_lpi; 15819 reg_info->max_bw_6g_ap[REG_INDOOR_AP] = 15820 ext_chan_list_event_hdr->max_bw_6g_ap_lpi; 15821 reg_info->min_bw_6g_ap[REG_VERY_LOW_POWER_AP] = 15822 ext_chan_list_event_hdr->min_bw_6g_ap_vlp; 15823 reg_info->max_bw_6g_ap[REG_VERY_LOW_POWER_AP] = 15824 ext_chan_list_event_hdr->max_bw_6g_ap_vlp; 15825 15826 for (i = 0; i < REG_MAX_CLIENT_TYPE; i++) { 15827 reg_info->min_bw_6g_client[REG_STANDARD_POWER_AP][i] = 15828 ext_chan_list_event_hdr->min_bw_6g_client_sp[i]; 15829 reg_info->max_bw_6g_client[REG_STANDARD_POWER_AP][i] = 15830 ext_chan_list_event_hdr->max_bw_6g_client_sp[i]; 15831 reg_info->min_bw_6g_client[REG_INDOOR_AP][i] = 15832 ext_chan_list_event_hdr->min_bw_6g_client_lpi[i]; 15833 reg_info->max_bw_6g_client[REG_INDOOR_AP][i] = 15834 ext_chan_list_event_hdr->max_bw_6g_client_lpi[i]; 15835 reg_info->min_bw_6g_client[REG_VERY_LOW_POWER_AP][i] = 15836 ext_chan_list_event_hdr->min_bw_6g_client_vlp[i]; 15837 reg_info->max_bw_6g_client[REG_VERY_LOW_POWER_AP][i] = 15838 ext_chan_list_event_hdr->max_bw_6g_client_vlp[i]; 15839 } 15840 15841 wmi_nofl_debug("num_phys = %u and phy_id = %u", 15842 reg_info->num_phy, reg_info->phy_id); 15843 15844 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", 15845 reg_info->alpha2, reg_info->dfs_region, reg_info->reg_dmn_pair, 15846 reg_info->min_bw_2g, reg_info->max_bw_2g, reg_info->min_bw_5g, 15847 reg_info->max_bw_5g); 15848 15849 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", 15850 reg_info->min_bw_6g_ap[REG_STANDARD_POWER_AP], 15851 reg_info->max_bw_6g_ap[REG_STANDARD_POWER_AP], 15852 reg_info->min_bw_6g_ap[REG_INDOOR_AP], 15853 reg_info->max_bw_6g_ap[REG_INDOOR_AP], 15854 reg_info->min_bw_6g_ap[REG_VERY_LOW_POWER_AP], 15855 reg_info->max_bw_6g_ap[REG_VERY_LOW_POWER_AP]); 15856 15857 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", 15858 reg_info->min_bw_6g_client[REG_STANDARD_POWER_AP][REG_DEFAULT_CLIENT], 15859 reg_info->max_bw_6g_client[REG_STANDARD_POWER_AP][REG_DEFAULT_CLIENT], 15860 reg_info->min_bw_6g_client[REG_INDOOR_AP][REG_DEFAULT_CLIENT], 15861 reg_info->max_bw_6g_client[REG_INDOOR_AP][REG_DEFAULT_CLIENT], 15862 reg_info->min_bw_6g_client[REG_VERY_LOW_POWER_AP][REG_DEFAULT_CLIENT], 15863 reg_info->max_bw_6g_client[REG_VERY_LOW_POWER_AP][REG_DEFAULT_CLIENT]); 15864 15865 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", 15866 reg_info->min_bw_6g_client[REG_STANDARD_POWER_AP][REG_SUBORDINATE_CLIENT], 15867 reg_info->max_bw_6g_client[REG_STANDARD_POWER_AP][REG_SUBORDINATE_CLIENT], 15868 reg_info->min_bw_6g_client[REG_INDOOR_AP][REG_SUBORDINATE_CLIENT], 15869 reg_info->max_bw_6g_client[REG_INDOOR_AP][REG_SUBORDINATE_CLIENT], 15870 reg_info->min_bw_6g_client[REG_VERY_LOW_POWER_AP][REG_SUBORDINATE_CLIENT], 15871 reg_info->max_bw_6g_client[REG_VERY_LOW_POWER_AP][REG_SUBORDINATE_CLIENT]); 15872 15873 wmi_nofl_debug("num_2g_reg_rules %d num_5g_reg_rules %d", 15874 num_2g_reg_rules, num_5g_reg_rules); 15875 15876 wmi_nofl_debug("num_6g_ap_sp_reg_rules %d num_6g_ap_lpi_reg_rules %d num_6g_ap_vlp_reg_rules %d", 15877 reg_info->num_6g_reg_rules_ap[REG_STANDARD_POWER_AP], 15878 reg_info->num_6g_reg_rules_ap[REG_INDOOR_AP], 15879 reg_info->num_6g_reg_rules_ap[REG_VERY_LOW_POWER_AP]); 15880 15881 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", 15882 reg_info->num_6g_reg_rules_client[REG_STANDARD_POWER_AP][REG_DEFAULT_CLIENT], 15883 reg_info->num_6g_reg_rules_client[REG_INDOOR_AP][REG_DEFAULT_CLIENT], 15884 reg_info->num_6g_reg_rules_client[REG_VERY_LOW_POWER_AP][REG_DEFAULT_CLIENT]); 15885 15886 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", 15887 reg_info->num_6g_reg_rules_client[REG_STANDARD_POWER_AP][REG_SUBORDINATE_CLIENT], 15888 reg_info->num_6g_reg_rules_client[REG_INDOOR_AP][REG_SUBORDINATE_CLIENT], 15889 reg_info->num_6g_reg_rules_client[REG_VERY_LOW_POWER_AP][REG_SUBORDINATE_CLIENT]); 15890 15891 ext_wmi_reg_rule = 15892 (wmi_regulatory_rule_ext_struct *) 15893 ((uint8_t *)ext_chan_list_event_hdr + 15894 sizeof(wmi_reg_chan_list_cc_event_ext_fixed_param) + 15895 WMI_TLV_HDR_SIZE); 15896 reg_info->reg_rules_2g_ptr = 15897 create_ext_reg_rules_from_wmi(num_2g_reg_rules, 15898 ext_wmi_reg_rule); 15899 ext_wmi_reg_rule += num_2g_reg_rules; 15900 if (!num_2g_reg_rules) 15901 wmi_nofl_debug("No 2ghz reg rule"); 15902 for (i = 0; i < num_2g_reg_rules; i++) { 15903 if (!reg_info->reg_rules_2g_ptr) 15904 break; 15905 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", 15906 i, reg_info->reg_rules_2g_ptr[i].start_freq, 15907 reg_info->reg_rules_2g_ptr[i].end_freq, 15908 reg_info->reg_rules_2g_ptr[i].max_bw, 15909 reg_info->reg_rules_2g_ptr[i].reg_power, 15910 reg_info->reg_rules_2g_ptr[i].ant_gain, 15911 reg_info->reg_rules_2g_ptr[i].flags, 15912 reg_info->reg_rules_2g_ptr[i].psd_flag, 15913 reg_info->reg_rules_2g_ptr[i].psd_eirp); 15914 } 15915 reg_info->reg_rules_5g_ptr = 15916 create_ext_reg_rules_from_wmi(num_5g_reg_rules, 15917 ext_wmi_reg_rule); 15918 ext_wmi_reg_rule += num_5g_reg_rules; 15919 if (!num_5g_reg_rules) 15920 wmi_nofl_debug("No 5ghz reg rule"); 15921 for (i = 0; i < num_5g_reg_rules; i++) { 15922 if (!reg_info->reg_rules_5g_ptr) 15923 break; 15924 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", 15925 i, reg_info->reg_rules_5g_ptr[i].start_freq, 15926 reg_info->reg_rules_5g_ptr[i].end_freq, 15927 reg_info->reg_rules_5g_ptr[i].max_bw, 15928 reg_info->reg_rules_5g_ptr[i].reg_power, 15929 reg_info->reg_rules_5g_ptr[i].ant_gain, 15930 reg_info->reg_rules_5g_ptr[i].flags, 15931 reg_info->reg_rules_5g_ptr[i].psd_flag, 15932 reg_info->reg_rules_5g_ptr[i].psd_eirp); 15933 } 15934 15935 for (i = 0; i < REG_CURRENT_MAX_AP_TYPE; i++) { 15936 reg_print_ap_power_type_6ghz(i); 15937 reg_info->reg_rules_6g_ap_ptr[i] = 15938 create_ext_reg_rules_from_wmi(num_6g_reg_rules_ap[i], 15939 ext_wmi_reg_rule); 15940 15941 ext_wmi_reg_rule += num_6g_reg_rules_ap[i]; 15942 if (!num_6g_reg_rules_ap[i]) 15943 wmi_nofl_debug("No 6ghz reg rule"); 15944 for (j = 0; j < num_6g_reg_rules_ap[i]; j++) { 15945 if (!reg_info->reg_rules_6g_ap_ptr[i]) 15946 break; 15947 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", 15948 j, reg_info->reg_rules_6g_ap_ptr[i][j].start_freq, 15949 reg_info->reg_rules_6g_ap_ptr[i][j].end_freq, 15950 reg_info->reg_rules_6g_ap_ptr[i][j].max_bw, 15951 reg_info->reg_rules_6g_ap_ptr[i][j].reg_power, 15952 reg_info->reg_rules_6g_ap_ptr[i][j].ant_gain, 15953 reg_info->reg_rules_6g_ap_ptr[i][j].flags, 15954 reg_info->reg_rules_6g_ap_ptr[i][j].psd_flag, 15955 reg_info->reg_rules_6g_ap_ptr[i][j].psd_eirp); 15956 } 15957 } 15958 15959 for (j = 0; j < REG_CURRENT_MAX_AP_TYPE; j++) { 15960 reg_print_ap_power_type_6ghz(j); 15961 for (i = 0; i < REG_MAX_CLIENT_TYPE; i++) { 15962 reg_print_6ghz_client_type(i); 15963 reg_info->reg_rules_6g_client_ptr[j][i] = 15964 create_ext_reg_rules_from_wmi( 15965 num_6g_reg_rules_client[j][i], 15966 ext_wmi_reg_rule); 15967 15968 ext_wmi_reg_rule += num_6g_reg_rules_client[j][i]; 15969 if (!num_6g_reg_rules_client[j][i]) 15970 wmi_nofl_debug("No 6ghz reg rule for [%d][%d]", j, i); 15971 for (k = 0; k < num_6g_reg_rules_client[j][i]; k++) { 15972 if (!reg_info->reg_rules_6g_client_ptr[j][i]) 15973 break; 15974 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", 15975 k, reg_info->reg_rules_6g_client_ptr[j][i][k].start_freq, 15976 reg_info->reg_rules_6g_client_ptr[j][i][k].end_freq, 15977 reg_info->reg_rules_6g_client_ptr[j][i][k].max_bw, 15978 reg_info->reg_rules_6g_client_ptr[j][i][k].reg_power, 15979 reg_info->reg_rules_6g_client_ptr[j][i][k].ant_gain, 15980 reg_info->reg_rules_6g_client_ptr[j][i][k].flags, 15981 reg_info->reg_rules_6g_client_ptr[j][i][k].psd_flag, 15982 reg_info->reg_rules_6g_client_ptr[j][i][k].psd_eirp); 15983 } 15984 } 15985 } 15986 15987 reg_info->client_type = ext_chan_list_event_hdr->client_type; 15988 reg_info->rnr_tpe_usable = ext_chan_list_event_hdr->rnr_tpe_usable; 15989 reg_info->unspecified_ap_usable = 15990 ext_chan_list_event_hdr->unspecified_ap_usable; 15991 reg_info->domain_code_6g_ap[REG_STANDARD_POWER_AP] = 15992 ext_chan_list_event_hdr->domain_code_6g_ap_sp; 15993 reg_info->domain_code_6g_ap[REG_INDOOR_AP] = 15994 ext_chan_list_event_hdr->domain_code_6g_ap_lpi; 15995 reg_info->domain_code_6g_ap[REG_VERY_LOW_POWER_AP] = 15996 ext_chan_list_event_hdr->domain_code_6g_ap_vlp; 15997 15998 wmi_nofl_debug("client type %d, RNR TPE usable %d, unspecified AP usable %d, domain code AP SP %d, LPI %d, VLP %d", 15999 reg_info->client_type, reg_info->rnr_tpe_usable, 16000 reg_info->unspecified_ap_usable, 16001 reg_info->domain_code_6g_ap[REG_STANDARD_POWER_AP], 16002 reg_info->domain_code_6g_ap[REG_INDOOR_AP], 16003 reg_info->domain_code_6g_ap[REG_VERY_LOW_POWER_AP]); 16004 16005 for (i = 0; i < REG_MAX_CLIENT_TYPE; i++) { 16006 reg_info->domain_code_6g_client[REG_STANDARD_POWER_AP][i] = 16007 ext_chan_list_event_hdr->domain_code_6g_client_sp[i]; 16008 reg_info->domain_code_6g_client[REG_INDOOR_AP][i] = 16009 ext_chan_list_event_hdr->domain_code_6g_client_lpi[i]; 16010 reg_info->domain_code_6g_client[REG_VERY_LOW_POWER_AP][i] = 16011 ext_chan_list_event_hdr->domain_code_6g_client_vlp[i]; 16012 wmi_nofl_debug("domain code client %d SP %d, LPI %d, VLP %d", i, 16013 reg_info->domain_code_6g_client[REG_STANDARD_POWER_AP][i], 16014 reg_info->domain_code_6g_client[REG_INDOOR_AP][i], 16015 reg_info->domain_code_6g_client[REG_VERY_LOW_POWER_AP][i]); 16016 } 16017 16018 reg_info->domain_code_6g_super_id = 16019 ext_chan_list_event_hdr->domain_code_6g_super_id; 16020 16021 status = extract_reg_fcc_rules_tlv(param_buf, ext_chan_list_event_hdr, 16022 ext_wmi_reg_rule, ext_wmi_chan_priority, 16023 evt_buf, reg_info, len); 16024 if (status != QDF_STATUS_SUCCESS) 16025 return status; 16026 16027 return QDF_STATUS_SUCCESS; 16028 } 16029 16030 #ifdef CONFIG_AFC_SUPPORT 16031 /** 16032 * copy_afc_chan_eirp_info() - Copy the channel EIRP object from 16033 * chan_eirp_power_info_hdr to the internal buffer chan_eirp_info. Since the 16034 * cfi and eirp is continuously filled in chan_eirp_power_info_hdr, there is 16035 * an index pointer required to store the current index of 16036 * chan_eirp_power_info_hdr, to fill into the chan_eirp_info object. 16037 * @chan_eirp_info: pointer to chan_eirp_info 16038 * @num_chans: Number of channels 16039 * @chan_eirp_power_info_hdr: Pointer to chan_eirp_power_info_hdr 16040 * @index: Pointer to index 16041 * 16042 * Return: void 16043 */ 16044 static void 16045 copy_afc_chan_eirp_info(struct chan_eirp_obj *chan_eirp_info, 16046 uint8_t num_chans, 16047 wmi_afc_chan_eirp_power_info *chan_eirp_power_info_hdr, 16048 uint8_t *index) 16049 { 16050 uint8_t chan_idx; 16051 16052 for (chan_idx = 0; chan_idx < num_chans; chan_idx++, (*index)++) { 16053 chan_eirp_info[chan_idx].cfi = 16054 chan_eirp_power_info_hdr[*index].channel_cfi; 16055 chan_eirp_info[chan_idx].eirp_power = 16056 chan_eirp_power_info_hdr[*index].eirp_pwr; 16057 wmi_debug("Chan idx = %d chan freq idx = %d EIRP power = %d", 16058 chan_idx, 16059 chan_eirp_info[chan_idx].cfi, 16060 chan_eirp_info[chan_idx].eirp_power); 16061 } 16062 } 16063 16064 /** 16065 * copy_afc_chan_obj_info() - Copy the channel object from channel_info_hdr to 16066 * to the internal buffer afc_chan_info. 16067 * @afc_chan_info: pointer to afc_chan_info 16068 * @num_chan_objs: Number of channel objects 16069 * @channel_info_hdr: Pointer to channel_info_hdr 16070 * @chan_eirp_power_info_hdr: Pointer to chan_eirp_power_info_hdr 16071 * 16072 * Return: void 16073 */ 16074 static void 16075 copy_afc_chan_obj_info(struct afc_chan_obj *afc_chan_info, 16076 uint8_t num_chan_objs, 16077 wmi_6g_afc_channel_info *channel_info_hdr, 16078 wmi_afc_chan_eirp_power_info *chan_eirp_power_info_hdr) 16079 { 16080 uint8_t count; 16081 uint8_t src_pwr_index = 0; 16082 16083 for (count = 0; count < num_chan_objs; count++) { 16084 afc_chan_info[count].global_opclass = 16085 channel_info_hdr[count].global_operating_class; 16086 afc_chan_info[count].num_chans = 16087 channel_info_hdr[count].num_channels; 16088 wmi_debug("Chan object count = %d global opclasss = %d", 16089 count, 16090 afc_chan_info[count].global_opclass); 16091 wmi_debug("Number of Channel EIRP objects = %d", 16092 afc_chan_info[count].num_chans); 16093 16094 if (afc_chan_info[count].num_chans > 0) { 16095 struct chan_eirp_obj *chan_eirp_info; 16096 16097 chan_eirp_info = 16098 qdf_mem_malloc(afc_chan_info[count].num_chans * 16099 sizeof(*chan_eirp_info)); 16100 16101 if (!chan_eirp_info) 16102 return; 16103 16104 copy_afc_chan_eirp_info(chan_eirp_info, 16105 afc_chan_info[count].num_chans, 16106 chan_eirp_power_info_hdr, 16107 &src_pwr_index); 16108 afc_chan_info[count].chan_eirp_info = chan_eirp_info; 16109 } else { 16110 wmi_err("Number of channels is zero in object idx %d", 16111 count); 16112 } 16113 } 16114 } 16115 16116 static void copy_afc_freq_obj_info(struct afc_freq_obj *afc_freq_info, 16117 uint8_t num_freq_objs, 16118 wmi_6g_afc_frequency_info *freq_info_hdr) 16119 { 16120 uint8_t count; 16121 16122 for (count = 0; count < num_freq_objs; count++) { 16123 afc_freq_info[count].low_freq = 16124 WMI_REG_RULE_START_FREQ_GET(freq_info_hdr[count].freq_info); 16125 afc_freq_info[count].high_freq = 16126 WMI_REG_RULE_END_FREQ_GET(freq_info_hdr[count].freq_info); 16127 afc_freq_info[count].max_psd = 16128 freq_info_hdr[count].psd_power_info; 16129 wmi_debug("count = %d low_freq = %d high_freq = %d max_psd = %d", 16130 count, 16131 afc_freq_info[count].low_freq, 16132 afc_freq_info[count].high_freq, 16133 afc_freq_info[count].max_psd); 16134 } 16135 } 16136 16137 /** 16138 * copy_afc_event_fixed_hdr_power_info() - Copy the fixed header portion of 16139 * the power event info from the WMI AFC event buffer to the internal buffer 16140 * power_info. 16141 * @power_info: pointer to power_info 16142 * @afc_power_event_hdr: pointer to afc_power_event_hdr 16143 * 16144 * Return: void 16145 */ 16146 static void 16147 copy_afc_event_fixed_hdr_power_info( 16148 struct reg_fw_afc_power_event *power_info, 16149 wmi_afc_power_event_param *afc_power_event_hdr) 16150 { 16151 power_info->fw_status_code = afc_power_event_hdr->fw_status_code; 16152 power_info->resp_id = afc_power_event_hdr->resp_id; 16153 power_info->serv_resp_code = afc_power_event_hdr->afc_serv_resp_code; 16154 power_info->afc_wfa_version = 16155 WMI_AFC_WFA_MINOR_VERSION_GET(afc_power_event_hdr->afc_wfa_version); 16156 power_info->afc_wfa_version |= 16157 WMI_AFC_WFA_MAJOR_VERSION_GET(afc_power_event_hdr->afc_wfa_version); 16158 16159 power_info->avail_exp_time_d = 16160 WMI_AVAIL_EXPIRY_TIME_DAY_GET(afc_power_event_hdr->avail_exp_time_d); 16161 power_info->avail_exp_time_d |= 16162 WMI_AVAIL_EXPIRY_TIME_MONTH_GET(afc_power_event_hdr->avail_exp_time_d); 16163 power_info->avail_exp_time_d |= 16164 WMI_AVAIL_EXPIRY_TIME_YEAR_GET(afc_power_event_hdr->avail_exp_time_d); 16165 16166 power_info->avail_exp_time_t = 16167 WMI_AVAIL_EXPIRY_TIME_SEC_GET(afc_power_event_hdr->avail_exp_time_t); 16168 power_info->avail_exp_time_t |= 16169 WMI_AVAIL_EXPIRY_TIME_MINUTE_GET(afc_power_event_hdr->avail_exp_time_t); 16170 power_info->avail_exp_time_t |= 16171 WMI_AVAIL_EXPIRY_TIME_HOUR_GET(afc_power_event_hdr->avail_exp_time_t); 16172 wmi_debug("FW status = %d resp_id = %d serv_resp_code = %d", 16173 power_info->fw_status_code, 16174 power_info->resp_id, 16175 power_info->serv_resp_code); 16176 wmi_debug("AFC version = %u exp_date = %u exp_time = %u", 16177 power_info->afc_wfa_version, 16178 power_info->avail_exp_time_d, 16179 power_info->avail_exp_time_t); 16180 } 16181 16182 /** 16183 * copy_power_event() - Copy the power event parameters from the AFC event 16184 * buffer to the power_info within the afc_info. 16185 * @afc_info: pointer to afc_info 16186 * @param_buf: pointer to param_buf 16187 * 16188 * Return: void 16189 */ 16190 static void copy_power_event(struct afc_regulatory_info *afc_info, 16191 WMI_AFC_EVENTID_param_tlvs *param_buf) 16192 { 16193 struct reg_fw_afc_power_event *power_info; 16194 wmi_afc_power_event_param *afc_power_event_hdr; 16195 struct afc_freq_obj *afc_freq_info; 16196 16197 power_info = qdf_mem_malloc(sizeof(*power_info)); 16198 16199 if (!power_info) 16200 return; 16201 16202 afc_power_event_hdr = param_buf->afc_power_event_param; 16203 copy_afc_event_fixed_hdr_power_info(power_info, afc_power_event_hdr); 16204 afc_info->power_info = power_info; 16205 16206 power_info->num_freq_objs = param_buf->num_freq_info_array; 16207 wmi_debug("Number of frequency objects = %d", 16208 power_info->num_freq_objs); 16209 if (power_info->num_freq_objs > 0) { 16210 wmi_6g_afc_frequency_info *freq_info_hdr; 16211 16212 freq_info_hdr = param_buf->freq_info_array; 16213 afc_freq_info = qdf_mem_malloc(power_info->num_freq_objs * 16214 sizeof(*afc_freq_info)); 16215 16216 if (!afc_freq_info) 16217 return; 16218 16219 copy_afc_freq_obj_info(afc_freq_info, power_info->num_freq_objs, 16220 freq_info_hdr); 16221 power_info->afc_freq_info = afc_freq_info; 16222 } else { 16223 wmi_err("Number of frequency objects is zero"); 16224 } 16225 16226 power_info->num_chan_objs = param_buf->num_channel_info_array; 16227 wmi_debug("Number of channel objects = %d", power_info->num_chan_objs); 16228 if (power_info->num_chan_objs > 0) { 16229 struct afc_chan_obj *afc_chan_info; 16230 wmi_6g_afc_channel_info *channel_info_hdr; 16231 16232 channel_info_hdr = param_buf->channel_info_array; 16233 afc_chan_info = qdf_mem_malloc(power_info->num_chan_objs * 16234 sizeof(*afc_chan_info)); 16235 16236 if (!afc_chan_info) 16237 return; 16238 16239 copy_afc_chan_obj_info(afc_chan_info, 16240 power_info->num_chan_objs, 16241 channel_info_hdr, 16242 param_buf->chan_eirp_power_info_array); 16243 power_info->afc_chan_info = afc_chan_info; 16244 } else { 16245 wmi_err("Number of channel objects is zero"); 16246 } 16247 } 16248 16249 static void copy_expiry_event(struct afc_regulatory_info *afc_info, 16250 WMI_AFC_EVENTID_param_tlvs *param_buf) 16251 { 16252 struct reg_afc_expiry_event *expiry_info; 16253 16254 expiry_info = qdf_mem_malloc(sizeof(*expiry_info)); 16255 16256 if (!expiry_info) 16257 return; 16258 16259 expiry_info->request_id = 16260 param_buf->expiry_event_param->request_id; 16261 expiry_info->event_subtype = 16262 param_buf->expiry_event_param->event_subtype; 16263 wmi_debug("Event subtype %d request ID %d", 16264 expiry_info->event_subtype, 16265 expiry_info->request_id); 16266 afc_info->expiry_info = expiry_info; 16267 } 16268 16269 /** 16270 * copy_afc_event_common_info() - Copy the phy_id and event_type parameters 16271 * in the AFC event. 'Common' indicates that these parameters are common for 16272 * WMI_AFC_EVENT_POWER_INFO and WMI_AFC_EVENT_TIMER_EXPIRY. 16273 * @wmi_handle: wmi handle 16274 * @afc_info: pointer to afc_info 16275 * @event_fixed_hdr: pointer to event_fixed_hdr 16276 * 16277 * Return: void 16278 */ 16279 static void 16280 copy_afc_event_common_info(wmi_unified_t wmi_handle, 16281 struct afc_regulatory_info *afc_info, 16282 wmi_afc_event_fixed_param *event_fixed_hdr) 16283 { 16284 afc_info->phy_id = wmi_handle->ops->convert_phy_id_target_to_host( 16285 wmi_handle, event_fixed_hdr->phy_id); 16286 wmi_debug("phy_id %d", afc_info->phy_id); 16287 afc_info->event_type = event_fixed_hdr->event_type; 16288 } 16289 16290 static QDF_STATUS extract_afc_event_tlv(wmi_unified_t wmi_handle, 16291 uint8_t *evt_buf, 16292 struct afc_regulatory_info *afc_info, 16293 uint32_t len) 16294 { 16295 WMI_AFC_EVENTID_param_tlvs *param_buf; 16296 wmi_afc_event_fixed_param *event_fixed_hdr; 16297 16298 param_buf = (WMI_AFC_EVENTID_param_tlvs *)evt_buf; 16299 if (!param_buf) { 16300 wmi_err("Invalid AFC event buf"); 16301 return QDF_STATUS_E_FAILURE; 16302 } 16303 16304 event_fixed_hdr = param_buf->fixed_param; 16305 copy_afc_event_common_info(wmi_handle, afc_info, event_fixed_hdr); 16306 wmi_debug("AFC event type %d received", afc_info->event_type); 16307 16308 switch (afc_info->event_type) { 16309 case WMI_AFC_EVENT_POWER_INFO: 16310 copy_power_event(afc_info, param_buf); 16311 break; 16312 case WMI_AFC_EVENT_TIMER_EXPIRY: 16313 copy_expiry_event(afc_info, param_buf); 16314 return QDF_STATUS_SUCCESS; 16315 default: 16316 wmi_err("Invalid event type"); 16317 return QDF_STATUS_E_FAILURE; 16318 } 16319 16320 return QDF_STATUS_SUCCESS; 16321 } 16322 #endif 16323 #endif 16324 16325 static QDF_STATUS extract_reg_chan_list_update_event_tlv( 16326 wmi_unified_t wmi_handle, uint8_t *evt_buf, 16327 struct cur_regulatory_info *reg_info, uint32_t len) 16328 { 16329 uint32_t i; 16330 WMI_REG_CHAN_LIST_CC_EVENTID_param_tlvs *param_buf; 16331 wmi_reg_chan_list_cc_event_fixed_param *chan_list_event_hdr; 16332 wmi_regulatory_rule_struct *wmi_reg_rule; 16333 uint32_t num_2g_reg_rules, num_5g_reg_rules; 16334 16335 wmi_debug("processing regulatory channel list"); 16336 16337 param_buf = (WMI_REG_CHAN_LIST_CC_EVENTID_param_tlvs *)evt_buf; 16338 if (!param_buf) { 16339 wmi_err("invalid channel list event buf"); 16340 return QDF_STATUS_E_FAILURE; 16341 } 16342 16343 chan_list_event_hdr = param_buf->fixed_param; 16344 16345 reg_info->num_2g_reg_rules = chan_list_event_hdr->num_2g_reg_rules; 16346 reg_info->num_5g_reg_rules = chan_list_event_hdr->num_5g_reg_rules; 16347 num_2g_reg_rules = reg_info->num_2g_reg_rules; 16348 num_5g_reg_rules = reg_info->num_5g_reg_rules; 16349 if ((num_2g_reg_rules > MAX_REG_RULES) || 16350 (num_5g_reg_rules > MAX_REG_RULES) || 16351 (num_2g_reg_rules + num_5g_reg_rules > MAX_REG_RULES) || 16352 (num_2g_reg_rules + num_5g_reg_rules != 16353 param_buf->num_reg_rule_array)) { 16354 wmi_err_rl("Invalid num_2g_reg_rules: %u, num_5g_reg_rules: %u", 16355 num_2g_reg_rules, num_5g_reg_rules); 16356 return QDF_STATUS_E_FAILURE; 16357 } 16358 if (param_buf->num_reg_rule_array > 16359 (WMI_SVC_MSG_MAX_SIZE - sizeof(*chan_list_event_hdr)) / 16360 sizeof(*wmi_reg_rule)) { 16361 wmi_err_rl("Invalid num_reg_rule_array: %u", 16362 param_buf->num_reg_rule_array); 16363 return QDF_STATUS_E_FAILURE; 16364 } 16365 16366 qdf_mem_copy(reg_info->alpha2, &(chan_list_event_hdr->alpha2), 16367 REG_ALPHA2_LEN); 16368 reg_info->dfs_region = chan_list_event_hdr->dfs_region; 16369 reg_info->phybitmap = convert_phybitmap_tlv( 16370 chan_list_event_hdr->phybitmap); 16371 reg_info->offload_enabled = true; 16372 reg_info->num_phy = chan_list_event_hdr->num_phy; 16373 reg_info->phy_id = wmi_handle->ops->convert_phy_id_target_to_host( 16374 wmi_handle, chan_list_event_hdr->phy_id); 16375 reg_info->ctry_code = chan_list_event_hdr->country_id; 16376 reg_info->reg_dmn_pair = chan_list_event_hdr->domain_code; 16377 16378 reg_info->status_code = 16379 wmi_reg_status_to_reg_status(chan_list_event_hdr->status_code); 16380 16381 reg_info->min_bw_2g = chan_list_event_hdr->min_bw_2g; 16382 reg_info->max_bw_2g = chan_list_event_hdr->max_bw_2g; 16383 reg_info->min_bw_5g = chan_list_event_hdr->min_bw_5g; 16384 reg_info->max_bw_5g = chan_list_event_hdr->max_bw_5g; 16385 16386 wmi_debug("num_phys = %u and phy_id = %u", 16387 reg_info->num_phy, reg_info->phy_id); 16388 16389 wmi_debug("cc %s dfs_region %d reg_dmn_pair %x BW: min_2g %d max_2g %d min_5g %d max_5g %d", 16390 reg_info->alpha2, reg_info->dfs_region, reg_info->reg_dmn_pair, 16391 reg_info->min_bw_2g, reg_info->max_bw_2g, 16392 reg_info->min_bw_5g, reg_info->max_bw_5g); 16393 16394 wmi_debug("num_2g_reg_rules %d num_5g_reg_rules %d", 16395 num_2g_reg_rules, num_5g_reg_rules); 16396 wmi_reg_rule = 16397 (wmi_regulatory_rule_struct *)((uint8_t *)chan_list_event_hdr 16398 + sizeof(wmi_reg_chan_list_cc_event_fixed_param) 16399 + WMI_TLV_HDR_SIZE); 16400 reg_info->reg_rules_2g_ptr = create_reg_rules_from_wmi(num_2g_reg_rules, 16401 wmi_reg_rule); 16402 wmi_reg_rule += num_2g_reg_rules; 16403 if (!num_2g_reg_rules) 16404 wmi_nofl_debug("No 2ghz reg rule"); 16405 for (i = 0; i < num_2g_reg_rules; i++) { 16406 if (!reg_info->reg_rules_2g_ptr) 16407 break; 16408 wmi_nofl_debug("2 GHz rule %u start freq %u end freq %u max_bw %u reg_power %u ant_gain %u flags %u", 16409 i, reg_info->reg_rules_2g_ptr[i].start_freq, 16410 reg_info->reg_rules_2g_ptr[i].end_freq, 16411 reg_info->reg_rules_2g_ptr[i].max_bw, 16412 reg_info->reg_rules_2g_ptr[i].reg_power, 16413 reg_info->reg_rules_2g_ptr[i].ant_gain, 16414 reg_info->reg_rules_2g_ptr[i].flags); 16415 } 16416 16417 reg_info->reg_rules_5g_ptr = create_reg_rules_from_wmi(num_5g_reg_rules, 16418 wmi_reg_rule); 16419 if (!num_5g_reg_rules) 16420 wmi_nofl_debug("No 5ghz reg rule"); 16421 for (i = 0; i < num_5g_reg_rules; i++) { 16422 if (!reg_info->reg_rules_5g_ptr) 16423 break; 16424 wmi_nofl_debug("5 GHz rule %u start freq %u end freq %u max_bw %u reg_power %u ant_gain %u flags %u", 16425 i, reg_info->reg_rules_5g_ptr[i].start_freq, 16426 reg_info->reg_rules_5g_ptr[i].end_freq, 16427 reg_info->reg_rules_5g_ptr[i].max_bw, 16428 reg_info->reg_rules_5g_ptr[i].reg_power, 16429 reg_info->reg_rules_5g_ptr[i].ant_gain, 16430 reg_info->reg_rules_5g_ptr[i].flags); 16431 } 16432 16433 wmi_debug("processed regulatory channel list"); 16434 16435 return QDF_STATUS_SUCCESS; 16436 } 16437 16438 static QDF_STATUS extract_reg_11d_new_country_event_tlv( 16439 wmi_unified_t wmi_handle, uint8_t *evt_buf, 16440 struct reg_11d_new_country *reg_11d_country, uint32_t len) 16441 { 16442 wmi_11d_new_country_event_fixed_param *reg_11d_country_event; 16443 WMI_11D_NEW_COUNTRY_EVENTID_param_tlvs *param_buf; 16444 16445 param_buf = (WMI_11D_NEW_COUNTRY_EVENTID_param_tlvs *)evt_buf; 16446 if (!param_buf) { 16447 wmi_err("invalid 11d country event buf"); 16448 return QDF_STATUS_E_FAILURE; 16449 } 16450 16451 reg_11d_country_event = param_buf->fixed_param; 16452 16453 qdf_mem_copy(reg_11d_country->alpha2, 16454 ®_11d_country_event->new_alpha2, REG_ALPHA2_LEN); 16455 reg_11d_country->alpha2[REG_ALPHA2_LEN] = '\0'; 16456 16457 wmi_debug("processed 11d country event, new cc %s", 16458 reg_11d_country->alpha2); 16459 16460 return QDF_STATUS_SUCCESS; 16461 } 16462 16463 static QDF_STATUS extract_reg_ch_avoid_event_tlv( 16464 wmi_unified_t wmi_handle, uint8_t *evt_buf, 16465 struct ch_avoid_ind_type *ch_avoid_ind, uint32_t len) 16466 { 16467 wmi_avoid_freq_ranges_event_fixed_param *afr_fixed_param; 16468 wmi_avoid_freq_range_desc *afr_desc; 16469 uint32_t num_freq_ranges, freq_range_idx; 16470 WMI_WLAN_FREQ_AVOID_EVENTID_param_tlvs *param_buf = 16471 (WMI_WLAN_FREQ_AVOID_EVENTID_param_tlvs *) evt_buf; 16472 16473 if (!param_buf) { 16474 wmi_err("Invalid channel avoid event buffer"); 16475 return QDF_STATUS_E_INVAL; 16476 } 16477 16478 afr_fixed_param = param_buf->fixed_param; 16479 if (!afr_fixed_param) { 16480 wmi_err("Invalid channel avoid event fixed param buffer"); 16481 return QDF_STATUS_E_INVAL; 16482 } 16483 16484 if (!ch_avoid_ind) { 16485 wmi_err("Invalid channel avoid indication buffer"); 16486 return QDF_STATUS_E_INVAL; 16487 } 16488 if (param_buf->num_avd_freq_range < afr_fixed_param->num_freq_ranges) { 16489 wmi_err("no.of freq ranges exceeded the limit"); 16490 return QDF_STATUS_E_INVAL; 16491 } 16492 num_freq_ranges = (afr_fixed_param->num_freq_ranges > 16493 CH_AVOID_MAX_RANGE) ? CH_AVOID_MAX_RANGE : 16494 afr_fixed_param->num_freq_ranges; 16495 16496 wmi_debug("Channel avoid event received with %d ranges", 16497 num_freq_ranges); 16498 16499 ch_avoid_ind->ch_avoid_range_cnt = num_freq_ranges; 16500 afr_desc = (wmi_avoid_freq_range_desc *)(param_buf->avd_freq_range); 16501 for (freq_range_idx = 0; freq_range_idx < num_freq_ranges; 16502 freq_range_idx++) { 16503 ch_avoid_ind->avoid_freq_range[freq_range_idx].start_freq = 16504 afr_desc->start_freq; 16505 ch_avoid_ind->avoid_freq_range[freq_range_idx].end_freq = 16506 afr_desc->end_freq; 16507 wmi_debug("range %d tlv id %u, start freq %u, end freq %u", 16508 freq_range_idx, afr_desc->tlv_header, 16509 afr_desc->start_freq, afr_desc->end_freq); 16510 afr_desc++; 16511 } 16512 16513 return QDF_STATUS_SUCCESS; 16514 } 16515 16516 #ifdef DFS_COMPONENT_ENABLE 16517 /** 16518 * extract_dfs_cac_complete_event_tlv() - extract cac complete event 16519 * @wmi_handle: wma handle 16520 * @evt_buf: event buffer 16521 * @vdev_id: vdev id 16522 * @len: length of buffer 16523 * 16524 * Return: QDF_STATUS_SUCCESS for success or error code 16525 */ 16526 static QDF_STATUS extract_dfs_cac_complete_event_tlv(wmi_unified_t wmi_handle, 16527 uint8_t *evt_buf, 16528 uint32_t *vdev_id, 16529 uint32_t len) 16530 { 16531 WMI_VDEV_DFS_CAC_COMPLETE_EVENTID_param_tlvs *param_tlvs; 16532 wmi_vdev_dfs_cac_complete_event_fixed_param *cac_event; 16533 16534 param_tlvs = (WMI_VDEV_DFS_CAC_COMPLETE_EVENTID_param_tlvs *) evt_buf; 16535 if (!param_tlvs) { 16536 wmi_err("invalid cac complete event buf"); 16537 return QDF_STATUS_E_FAILURE; 16538 } 16539 16540 cac_event = param_tlvs->fixed_param; 16541 *vdev_id = cac_event->vdev_id; 16542 wmi_debug("processed cac complete event vdev %d", *vdev_id); 16543 16544 return QDF_STATUS_SUCCESS; 16545 } 16546 16547 /** 16548 * extract_dfs_ocac_complete_event_tlv() - extract cac complete event 16549 * @wmi_handle: wma handle 16550 * @evt_buf: event buffer 16551 * @param: extracted event 16552 * 16553 * Return: QDF_STATUS_SUCCESS for success or error code 16554 */ 16555 static QDF_STATUS 16556 extract_dfs_ocac_complete_event_tlv(wmi_unified_t wmi_handle, 16557 uint8_t *evt_buf, 16558 struct vdev_adfs_complete_status *param) 16559 { 16560 WMI_VDEV_ADFS_OCAC_COMPLETE_EVENTID_param_tlvs *param_tlvs; 16561 wmi_vdev_adfs_ocac_complete_event_fixed_param *ocac_complete_status; 16562 16563 param_tlvs = (WMI_VDEV_ADFS_OCAC_COMPLETE_EVENTID_param_tlvs *)evt_buf; 16564 if (!param_tlvs) { 16565 wmi_err("invalid ocac complete event buf"); 16566 return QDF_STATUS_E_FAILURE; 16567 } 16568 16569 if (!param_tlvs->fixed_param) { 16570 wmi_err("invalid param_tlvs->fixed_param"); 16571 return QDF_STATUS_E_FAILURE; 16572 } 16573 16574 ocac_complete_status = param_tlvs->fixed_param; 16575 param->vdev_id = ocac_complete_status->vdev_id; 16576 param->chan_freq = ocac_complete_status->chan_freq; 16577 param->center_freq1 = ocac_complete_status->center_freq1; 16578 param->center_freq2 = ocac_complete_status->center_freq2; 16579 param->ocac_status = ocac_complete_status->status; 16580 param->chan_width = ocac_complete_status->chan_width; 16581 wmi_debug("processed ocac complete event vdev %d" 16582 " agile chan %d %d width %d status %d", 16583 param->vdev_id, 16584 param->center_freq1, 16585 param->center_freq2, 16586 param->chan_width, 16587 param->ocac_status); 16588 16589 return QDF_STATUS_SUCCESS; 16590 } 16591 16592 /** 16593 * extract_dfs_radar_detection_event_tlv() - extract radar found event 16594 * @wmi_handle: wma handle 16595 * @evt_buf: event buffer 16596 * @radar_found: radar found event info 16597 * @len: length of buffer 16598 * 16599 * Return: QDF_STATUS_SUCCESS for success or error code 16600 */ 16601 static QDF_STATUS extract_dfs_radar_detection_event_tlv( 16602 wmi_unified_t wmi_handle, 16603 uint8_t *evt_buf, 16604 struct radar_found_info *radar_found, 16605 uint32_t len) 16606 { 16607 WMI_PDEV_DFS_RADAR_DETECTION_EVENTID_param_tlvs *param_tlv; 16608 wmi_pdev_dfs_radar_detection_event_fixed_param *radar_event; 16609 16610 param_tlv = (WMI_PDEV_DFS_RADAR_DETECTION_EVENTID_param_tlvs *) evt_buf; 16611 if (!param_tlv) { 16612 wmi_err("invalid radar detection event buf"); 16613 return QDF_STATUS_E_FAILURE; 16614 } 16615 16616 radar_event = param_tlv->fixed_param; 16617 16618 radar_found->pdev_id = convert_target_pdev_id_to_host_pdev_id( 16619 wmi_handle, 16620 radar_event->pdev_id); 16621 16622 if (radar_found->pdev_id == WMI_HOST_PDEV_ID_INVALID) 16623 return QDF_STATUS_E_FAILURE; 16624 16625 radar_found->detection_mode = radar_event->detection_mode; 16626 radar_found->chan_freq = radar_event->chan_freq; 16627 radar_found->chan_width = radar_event->chan_width; 16628 radar_found->detector_id = radar_event->detector_id; 16629 radar_found->segment_id = radar_event->segment_id; 16630 radar_found->timestamp = radar_event->timestamp; 16631 radar_found->is_chirp = radar_event->is_chirp; 16632 radar_found->freq_offset = radar_event->freq_offset; 16633 radar_found->sidx = radar_event->sidx; 16634 16635 wmi_debug("processed radar found event pdev %d," 16636 "Radar Event Info:pdev_id %d,timestamp %d,chan_freq (dur) %d," 16637 "chan_width (RSSI) %d,detector_id (false_radar) %d," 16638 "freq_offset (radar_check) %d,segment_id %d,sidx %d," 16639 "is_chirp %d,detection mode %d", 16640 radar_event->pdev_id, radar_found->pdev_id, 16641 radar_event->timestamp, radar_event->chan_freq, 16642 radar_event->chan_width, radar_event->detector_id, 16643 radar_event->freq_offset, radar_event->segment_id, 16644 radar_event->sidx, radar_event->is_chirp, 16645 radar_event->detection_mode); 16646 16647 return QDF_STATUS_SUCCESS; 16648 } 16649 16650 #ifdef MOBILE_DFS_SUPPORT 16651 /** 16652 * extract_wlan_radar_event_info_tlv() - extract radar pulse event 16653 * @wmi_handle: wma handle 16654 * @evt_buf: event buffer 16655 * @wlan_radar_event: Pointer to struct radar_event_info 16656 * @len: length of buffer 16657 * 16658 * Return: QDF_STATUS 16659 */ 16660 static QDF_STATUS extract_wlan_radar_event_info_tlv( 16661 wmi_unified_t wmi_handle, 16662 uint8_t *evt_buf, 16663 struct radar_event_info *wlan_radar_event, 16664 uint32_t len) 16665 { 16666 WMI_DFS_RADAR_EVENTID_param_tlvs *param_tlv; 16667 wmi_dfs_radar_event_fixed_param *radar_event; 16668 16669 param_tlv = (WMI_DFS_RADAR_EVENTID_param_tlvs *)evt_buf; 16670 if (!param_tlv) { 16671 wmi_err("invalid wlan radar event buf"); 16672 return QDF_STATUS_E_FAILURE; 16673 } 16674 16675 radar_event = param_tlv->fixed_param; 16676 wlan_radar_event->pulse_is_chirp = radar_event->pulse_is_chirp; 16677 wlan_radar_event->pulse_center_freq = radar_event->pulse_center_freq; 16678 wlan_radar_event->pulse_duration = radar_event->pulse_duration; 16679 wlan_radar_event->rssi = radar_event->rssi; 16680 wlan_radar_event->pulse_detect_ts = radar_event->pulse_detect_ts; 16681 wlan_radar_event->upload_fullts_high = radar_event->upload_fullts_high; 16682 wlan_radar_event->upload_fullts_low = radar_event->upload_fullts_low; 16683 wlan_radar_event->peak_sidx = radar_event->peak_sidx; 16684 wlan_radar_event->delta_peak = radar_event->pulse_delta_peak; 16685 wlan_radar_event->delta_diff = radar_event->pulse_delta_diff; 16686 if (radar_event->pulse_flags & 16687 WMI_DFS_RADAR_PULSE_FLAG_MASK_PSIDX_DIFF_VALID) { 16688 wlan_radar_event->is_psidx_diff_valid = true; 16689 wlan_radar_event->psidx_diff = radar_event->psidx_diff; 16690 } else { 16691 wlan_radar_event->is_psidx_diff_valid = false; 16692 } 16693 16694 wlan_radar_event->pdev_id = radar_event->pdev_id; 16695 16696 return QDF_STATUS_SUCCESS; 16697 } 16698 #else 16699 static QDF_STATUS extract_wlan_radar_event_info_tlv( 16700 wmi_unified_t wmi_handle, 16701 uint8_t *evt_buf, 16702 struct radar_event_info *wlan_radar_event, 16703 uint32_t len) 16704 { 16705 return QDF_STATUS_SUCCESS; 16706 } 16707 #endif 16708 #endif 16709 16710 /** 16711 * send_get_rcpi_cmd_tlv() - send request for rcpi value 16712 * @wmi_handle: wmi handle 16713 * @get_rcpi_param: rcpi params 16714 * 16715 * Return: QDF status 16716 */ 16717 static QDF_STATUS send_get_rcpi_cmd_tlv(wmi_unified_t wmi_handle, 16718 struct rcpi_req *get_rcpi_param) 16719 { 16720 wmi_buf_t buf; 16721 wmi_request_rcpi_cmd_fixed_param *cmd; 16722 uint8_t len = sizeof(wmi_request_rcpi_cmd_fixed_param); 16723 16724 buf = wmi_buf_alloc(wmi_handle, len); 16725 if (!buf) 16726 return QDF_STATUS_E_NOMEM; 16727 16728 cmd = (wmi_request_rcpi_cmd_fixed_param *) wmi_buf_data(buf); 16729 WMITLV_SET_HDR(&cmd->tlv_header, 16730 WMITLV_TAG_STRUC_wmi_request_rcpi_cmd_fixed_param, 16731 WMITLV_GET_STRUCT_TLVLEN 16732 (wmi_request_rcpi_cmd_fixed_param)); 16733 16734 cmd->vdev_id = get_rcpi_param->vdev_id; 16735 WMI_CHAR_ARRAY_TO_MAC_ADDR(get_rcpi_param->mac_addr, 16736 &cmd->peer_macaddr); 16737 16738 switch (get_rcpi_param->measurement_type) { 16739 16740 case RCPI_MEASUREMENT_TYPE_AVG_MGMT: 16741 cmd->measurement_type = WMI_RCPI_MEASUREMENT_TYPE_AVG_MGMT; 16742 break; 16743 16744 case RCPI_MEASUREMENT_TYPE_AVG_DATA: 16745 cmd->measurement_type = WMI_RCPI_MEASUREMENT_TYPE_AVG_DATA; 16746 break; 16747 16748 case RCPI_MEASUREMENT_TYPE_LAST_MGMT: 16749 cmd->measurement_type = WMI_RCPI_MEASUREMENT_TYPE_LAST_MGMT; 16750 break; 16751 16752 case RCPI_MEASUREMENT_TYPE_LAST_DATA: 16753 cmd->measurement_type = WMI_RCPI_MEASUREMENT_TYPE_LAST_DATA; 16754 break; 16755 16756 default: 16757 /* 16758 * invalid rcpi measurement type, fall back to 16759 * RCPI_MEASUREMENT_TYPE_AVG_MGMT 16760 */ 16761 cmd->measurement_type = WMI_RCPI_MEASUREMENT_TYPE_AVG_MGMT; 16762 break; 16763 } 16764 wmi_debug("RCPI REQ VDEV_ID:%d-->", cmd->vdev_id); 16765 wmi_mtrace(WMI_REQUEST_RCPI_CMDID, cmd->vdev_id, 0); 16766 if (wmi_unified_cmd_send(wmi_handle, buf, len, 16767 WMI_REQUEST_RCPI_CMDID)) { 16768 16769 wmi_err("Failed to send WMI_REQUEST_RCPI_CMDID"); 16770 wmi_buf_free(buf); 16771 return QDF_STATUS_E_FAILURE; 16772 } 16773 16774 return QDF_STATUS_SUCCESS; 16775 } 16776 16777 /** 16778 * extract_rcpi_response_event_tlv() - Extract RCPI event params 16779 * @wmi_handle: wmi handle 16780 * @evt_buf: pointer to event buffer 16781 * @res: pointer to hold rcpi response from firmware 16782 * 16783 * Return: QDF_STATUS_SUCCESS for successful event parse 16784 * else QDF_STATUS_E_INVAL or QDF_STATUS_E_FAILURE 16785 */ 16786 static QDF_STATUS 16787 extract_rcpi_response_event_tlv(wmi_unified_t wmi_handle, 16788 void *evt_buf, struct rcpi_res *res) 16789 { 16790 WMI_UPDATE_RCPI_EVENTID_param_tlvs *param_buf; 16791 wmi_update_rcpi_event_fixed_param *event; 16792 16793 param_buf = (WMI_UPDATE_RCPI_EVENTID_param_tlvs *)evt_buf; 16794 if (!param_buf) { 16795 wmi_err("Invalid rcpi event"); 16796 return QDF_STATUS_E_INVAL; 16797 } 16798 16799 event = param_buf->fixed_param; 16800 res->vdev_id = event->vdev_id; 16801 WMI_MAC_ADDR_TO_CHAR_ARRAY(&event->peer_macaddr, res->mac_addr); 16802 16803 switch (event->measurement_type) { 16804 16805 case WMI_RCPI_MEASUREMENT_TYPE_AVG_MGMT: 16806 res->measurement_type = RCPI_MEASUREMENT_TYPE_AVG_MGMT; 16807 break; 16808 16809 case WMI_RCPI_MEASUREMENT_TYPE_AVG_DATA: 16810 res->measurement_type = RCPI_MEASUREMENT_TYPE_AVG_DATA; 16811 break; 16812 16813 case WMI_RCPI_MEASUREMENT_TYPE_LAST_MGMT: 16814 res->measurement_type = RCPI_MEASUREMENT_TYPE_LAST_MGMT; 16815 break; 16816 16817 case WMI_RCPI_MEASUREMENT_TYPE_LAST_DATA: 16818 res->measurement_type = RCPI_MEASUREMENT_TYPE_LAST_DATA; 16819 break; 16820 16821 default: 16822 wmi_err("Invalid rcpi measurement type from firmware"); 16823 res->measurement_type = RCPI_MEASUREMENT_TYPE_INVALID; 16824 return QDF_STATUS_E_FAILURE; 16825 } 16826 16827 if (event->status) 16828 return QDF_STATUS_E_FAILURE; 16829 else 16830 return QDF_STATUS_SUCCESS; 16831 } 16832 16833 /** 16834 * convert_host_pdev_id_to_target_pdev_id_legacy() - Convert pdev_id from 16835 * host to target defines. For legacy there is not conversion 16836 * required. Just return pdev_id as it is. 16837 * @wmi_handle: handle to WMI. 16838 * @pdev_id: host pdev_id to be converted. 16839 * Return: target pdev_id after conversion. 16840 */ 16841 static uint32_t convert_host_pdev_id_to_target_pdev_id_legacy( 16842 wmi_unified_t wmi_handle, 16843 uint32_t pdev_id) 16844 { 16845 if (pdev_id == WMI_HOST_PDEV_ID_SOC) 16846 return WMI_PDEV_ID_SOC; 16847 16848 /*No conversion required*/ 16849 return pdev_id; 16850 } 16851 16852 /** 16853 * convert_target_pdev_id_to_host_pdev_id_legacy() - Convert pdev_id from 16854 * target to host defines. For legacy there is not conversion 16855 * required. Just return pdev_id as it is. 16856 * @wmi_handle: handle to WMI. 16857 * @pdev_id: target pdev_id to be converted. 16858 * Return: host pdev_id after conversion. 16859 */ 16860 static uint32_t convert_target_pdev_id_to_host_pdev_id_legacy( 16861 wmi_unified_t wmi_handle, 16862 uint32_t pdev_id) 16863 { 16864 /*No conversion required*/ 16865 return pdev_id; 16866 } 16867 16868 /** 16869 * convert_host_phy_id_to_target_phy_id_legacy() - Convert phy_id from 16870 * host to target defines. For legacy there is not conversion 16871 * required. Just return phy_id as it is. 16872 * @wmi_handle: handle to WMI. 16873 * @phy_id: host phy_id to be converted. 16874 * 16875 * Return: target phy_id after conversion. 16876 */ 16877 static uint32_t convert_host_phy_id_to_target_phy_id_legacy( 16878 wmi_unified_t wmi_handle, 16879 uint32_t phy_id) 16880 { 16881 /*No conversion required*/ 16882 return phy_id; 16883 } 16884 16885 /** 16886 * convert_target_phy_id_to_host_phy_id_legacy() - Convert phy_id from 16887 * target to host defines. For legacy there is not conversion 16888 * required. Just return phy_id as it is. 16889 * @wmi_handle: handle to WMI. 16890 * @phy_id: target phy_id to be converted. 16891 * 16892 * Return: host phy_id after conversion. 16893 */ 16894 static uint32_t convert_target_phy_id_to_host_phy_id_legacy( 16895 wmi_unified_t wmi_handle, 16896 uint32_t phy_id) 16897 { 16898 /*No conversion required*/ 16899 return phy_id; 16900 } 16901 16902 /** 16903 * send_set_country_cmd_tlv() - WMI scan channel list function 16904 * @wmi_handle: handle to WMI. 16905 * @params: pointer to hold scan channel list parameter 16906 * 16907 * Return: QDF_STATUS_SUCCESS for success or error code 16908 */ 16909 static QDF_STATUS send_set_country_cmd_tlv(wmi_unified_t wmi_handle, 16910 struct set_country *params) 16911 { 16912 wmi_buf_t buf; 16913 QDF_STATUS qdf_status; 16914 wmi_set_current_country_cmd_fixed_param *cmd; 16915 uint16_t len = sizeof(*cmd); 16916 uint8_t pdev_id = params->pdev_id; 16917 16918 buf = wmi_buf_alloc(wmi_handle, len); 16919 if (!buf) { 16920 qdf_status = QDF_STATUS_E_NOMEM; 16921 goto end; 16922 } 16923 16924 cmd = (wmi_set_current_country_cmd_fixed_param *)wmi_buf_data(buf); 16925 WMITLV_SET_HDR(&cmd->tlv_header, 16926 WMITLV_TAG_STRUC_wmi_set_current_country_cmd_fixed_param, 16927 WMITLV_GET_STRUCT_TLVLEN 16928 (wmi_set_current_country_cmd_fixed_param)); 16929 16930 cmd->pdev_id = wmi_handle->ops->convert_host_pdev_id_to_target( 16931 wmi_handle, 16932 pdev_id); 16933 wmi_debug("setting current country to %s and target pdev_id = %u", 16934 params->country, cmd->pdev_id); 16935 16936 qdf_mem_copy((uint8_t *)&cmd->new_alpha2, params->country, 3); 16937 16938 wmi_mtrace(WMI_SET_CURRENT_COUNTRY_CMDID, NO_SESSION, 0); 16939 qdf_status = wmi_unified_cmd_send(wmi_handle, 16940 buf, len, WMI_SET_CURRENT_COUNTRY_CMDID); 16941 16942 if (QDF_IS_STATUS_ERROR(qdf_status)) { 16943 wmi_err("Failed to send WMI_SET_CURRENT_COUNTRY_CMDID"); 16944 wmi_buf_free(buf); 16945 } 16946 16947 end: 16948 return qdf_status; 16949 } 16950 16951 #define WMI_REG_COUNTRY_ALPHA_SET(alpha, val0, val1, val2) do { \ 16952 WMI_SET_BITS(alpha, 0, 8, val0); \ 16953 WMI_SET_BITS(alpha, 8, 8, val1); \ 16954 WMI_SET_BITS(alpha, 16, 8, val2); \ 16955 } while (0) 16956 16957 static QDF_STATUS send_user_country_code_cmd_tlv(wmi_unified_t wmi_handle, 16958 uint8_t pdev_id, struct cc_regdmn_s *rd) 16959 { 16960 wmi_set_init_country_cmd_fixed_param *cmd; 16961 uint16_t len; 16962 wmi_buf_t buf; 16963 int ret; 16964 16965 len = sizeof(wmi_set_init_country_cmd_fixed_param); 16966 buf = wmi_buf_alloc(wmi_handle, len); 16967 if (!buf) 16968 return QDF_STATUS_E_NOMEM; 16969 16970 cmd = (wmi_set_init_country_cmd_fixed_param *) wmi_buf_data(buf); 16971 WMITLV_SET_HDR(&cmd->tlv_header, 16972 WMITLV_TAG_STRUC_wmi_set_init_country_cmd_fixed_param, 16973 WMITLV_GET_STRUCT_TLVLEN 16974 (wmi_set_init_country_cmd_fixed_param)); 16975 16976 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 16977 wmi_handle, 16978 pdev_id); 16979 16980 if (rd->flags == CC_IS_SET) { 16981 cmd->countrycode_type = WMI_COUNTRYCODE_COUNTRY_ID; 16982 cmd->country_code.country_id = rd->cc.country_code; 16983 } else if (rd->flags == ALPHA_IS_SET) { 16984 cmd->countrycode_type = WMI_COUNTRYCODE_ALPHA2; 16985 WMI_REG_COUNTRY_ALPHA_SET(cmd->country_code.alpha2, 16986 rd->cc.alpha[0], 16987 rd->cc.alpha[1], 16988 rd->cc.alpha[2]); 16989 } else if (rd->flags == REGDMN_IS_SET) { 16990 cmd->countrycode_type = WMI_COUNTRYCODE_DOMAIN_CODE; 16991 WMI_SET_BITS(cmd->country_code.domain_code, 0, 16, 16992 rd->cc.regdmn.reg_2g_5g_pair_id); 16993 WMI_SET_BITS(cmd->country_code.domain_code, 16, 16, 16994 rd->cc.regdmn.sixg_superdmn_id); 16995 } 16996 16997 wmi_mtrace(WMI_SET_INIT_COUNTRY_CMDID, NO_SESSION, 0); 16998 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 16999 WMI_SET_INIT_COUNTRY_CMDID); 17000 if (ret) { 17001 wmi_err("Failed to config wow wakeup event"); 17002 wmi_buf_free(buf); 17003 return QDF_STATUS_E_FAILURE; 17004 } 17005 17006 return QDF_STATUS_SUCCESS; 17007 } 17008 17009 /** 17010 * send_obss_detection_cfg_cmd_tlv() - send obss detection 17011 * configurations to firmware. 17012 * @wmi_handle: wmi handle 17013 * @obss_cfg_param: obss detection configurations 17014 * 17015 * Send WMI_SAP_OBSS_DETECTION_CFG_CMDID parameters to fw. 17016 * 17017 * Return: QDF_STATUS 17018 */ 17019 static QDF_STATUS send_obss_detection_cfg_cmd_tlv(wmi_unified_t wmi_handle, 17020 struct wmi_obss_detection_cfg_param *obss_cfg_param) 17021 { 17022 wmi_buf_t buf; 17023 wmi_sap_obss_detection_cfg_cmd_fixed_param *cmd; 17024 uint8_t len = sizeof(wmi_sap_obss_detection_cfg_cmd_fixed_param); 17025 17026 buf = wmi_buf_alloc(wmi_handle, len); 17027 if (!buf) 17028 return QDF_STATUS_E_NOMEM; 17029 17030 cmd = (wmi_sap_obss_detection_cfg_cmd_fixed_param *)wmi_buf_data(buf); 17031 WMITLV_SET_HDR(&cmd->tlv_header, 17032 WMITLV_TAG_STRUC_wmi_sap_obss_detection_cfg_cmd_fixed_param, 17033 WMITLV_GET_STRUCT_TLVLEN 17034 (wmi_sap_obss_detection_cfg_cmd_fixed_param)); 17035 17036 cmd->vdev_id = obss_cfg_param->vdev_id; 17037 cmd->detect_period_ms = obss_cfg_param->obss_detect_period_ms; 17038 cmd->b_ap_detect_mode = obss_cfg_param->obss_11b_ap_detect_mode; 17039 cmd->b_sta_detect_mode = obss_cfg_param->obss_11b_sta_detect_mode; 17040 cmd->g_ap_detect_mode = obss_cfg_param->obss_11g_ap_detect_mode; 17041 cmd->a_detect_mode = obss_cfg_param->obss_11a_detect_mode; 17042 cmd->ht_legacy_detect_mode = obss_cfg_param->obss_ht_legacy_detect_mode; 17043 cmd->ht_mixed_detect_mode = obss_cfg_param->obss_ht_mixed_detect_mode; 17044 cmd->ht_20mhz_detect_mode = obss_cfg_param->obss_ht_20mhz_detect_mode; 17045 17046 wmi_mtrace(WMI_SAP_OBSS_DETECTION_CFG_CMDID, cmd->vdev_id, 0); 17047 if (wmi_unified_cmd_send(wmi_handle, buf, len, 17048 WMI_SAP_OBSS_DETECTION_CFG_CMDID)) { 17049 wmi_err("Failed to send WMI_SAP_OBSS_DETECTION_CFG_CMDID"); 17050 wmi_buf_free(buf); 17051 return QDF_STATUS_E_FAILURE; 17052 } 17053 17054 return QDF_STATUS_SUCCESS; 17055 } 17056 17057 /** 17058 * extract_obss_detection_info_tlv() - Extract obss detection info 17059 * received from firmware. 17060 * @evt_buf: pointer to event buffer 17061 * @obss_detection: Pointer to hold obss detection info 17062 * 17063 * Return: QDF_STATUS 17064 */ 17065 static QDF_STATUS extract_obss_detection_info_tlv(uint8_t *evt_buf, 17066 struct wmi_obss_detect_info 17067 *obss_detection) 17068 { 17069 WMI_SAP_OBSS_DETECTION_REPORT_EVENTID_param_tlvs *param_buf; 17070 wmi_sap_obss_detection_info_evt_fixed_param *fix_param; 17071 17072 if (!obss_detection) { 17073 wmi_err("Invalid obss_detection event buffer"); 17074 return QDF_STATUS_E_INVAL; 17075 } 17076 17077 param_buf = (WMI_SAP_OBSS_DETECTION_REPORT_EVENTID_param_tlvs *)evt_buf; 17078 if (!param_buf) { 17079 wmi_err("Invalid evt_buf"); 17080 return QDF_STATUS_E_INVAL; 17081 } 17082 17083 fix_param = param_buf->fixed_param; 17084 obss_detection->vdev_id = fix_param->vdev_id; 17085 obss_detection->matched_detection_masks = 17086 fix_param->matched_detection_masks; 17087 WMI_MAC_ADDR_TO_CHAR_ARRAY(&fix_param->matched_bssid_addr, 17088 &obss_detection->matched_bssid_addr[0]); 17089 switch (fix_param->reason) { 17090 case WMI_SAP_OBSS_DETECTION_EVENT_REASON_NOT_SUPPORT: 17091 obss_detection->reason = OBSS_OFFLOAD_DETECTION_DISABLED; 17092 break; 17093 case WMI_SAP_OBSS_DETECTION_EVENT_REASON_PRESENT_NOTIFY: 17094 obss_detection->reason = OBSS_OFFLOAD_DETECTION_PRESENT; 17095 break; 17096 case WMI_SAP_OBSS_DETECTION_EVENT_REASON_ABSENT_TIMEOUT: 17097 obss_detection->reason = OBSS_OFFLOAD_DETECTION_ABSENT; 17098 break; 17099 default: 17100 wmi_err("Invalid reason: %d", fix_param->reason); 17101 return QDF_STATUS_E_INVAL; 17102 } 17103 17104 return QDF_STATUS_SUCCESS; 17105 } 17106 17107 /** 17108 * send_roam_scan_stats_cmd_tlv() - Send roam scan stats req command to fw 17109 * @wmi_handle: wmi handle 17110 * @params: pointer to request structure 17111 * 17112 * Return: QDF_STATUS 17113 */ 17114 static QDF_STATUS 17115 send_roam_scan_stats_cmd_tlv(wmi_unified_t wmi_handle, 17116 struct wmi_roam_scan_stats_req *params) 17117 { 17118 wmi_buf_t buf; 17119 wmi_request_roam_scan_stats_cmd_fixed_param *cmd; 17120 WMITLV_TAG_ID tag; 17121 uint32_t size; 17122 uint32_t len = sizeof(*cmd); 17123 17124 buf = wmi_buf_alloc(wmi_handle, len); 17125 if (!buf) 17126 return QDF_STATUS_E_FAILURE; 17127 17128 cmd = (wmi_request_roam_scan_stats_cmd_fixed_param *)wmi_buf_data(buf); 17129 17130 tag = WMITLV_TAG_STRUC_wmi_request_roam_scan_stats_cmd_fixed_param; 17131 size = WMITLV_GET_STRUCT_TLVLEN( 17132 wmi_request_roam_scan_stats_cmd_fixed_param); 17133 WMITLV_SET_HDR(&cmd->tlv_header, tag, size); 17134 17135 cmd->vdev_id = params->vdev_id; 17136 17137 wmi_debug("Roam Scan Stats Req vdev_id: %u", cmd->vdev_id); 17138 if (wmi_unified_cmd_send(wmi_handle, buf, len, 17139 WMI_REQUEST_ROAM_SCAN_STATS_CMDID)) { 17140 wmi_err("Failed to send WMI_REQUEST_ROAM_SCAN_STATS_CMDID"); 17141 wmi_buf_free(buf); 17142 return QDF_STATUS_E_FAILURE; 17143 } 17144 17145 return QDF_STATUS_SUCCESS; 17146 } 17147 17148 /** 17149 * send_roam_scan_ch_list_req_cmd_tlv() - send wmi cmd to get roam scan 17150 * channel list from firmware 17151 * @wmi_handle: wmi handler 17152 * @vdev_id: vdev id 17153 * 17154 * Return: QDF_STATUS 17155 */ 17156 static QDF_STATUS send_roam_scan_ch_list_req_cmd_tlv(wmi_unified_t wmi_handle, 17157 uint32_t vdev_id) 17158 { 17159 wmi_buf_t buf; 17160 wmi_roam_get_scan_channel_list_cmd_fixed_param *cmd; 17161 uint16_t len = sizeof(*cmd); 17162 int ret; 17163 17164 buf = wmi_buf_alloc(wmi_handle, len); 17165 if (!buf) { 17166 wmi_err("Failed to allocate wmi buffer"); 17167 return QDF_STATUS_E_NOMEM; 17168 } 17169 17170 cmd = (wmi_roam_get_scan_channel_list_cmd_fixed_param *) 17171 wmi_buf_data(buf); 17172 WMITLV_SET_HDR(&cmd->tlv_header, 17173 WMITLV_TAG_STRUC_wmi_roam_get_scan_channel_list_cmd_fixed_param, 17174 WMITLV_GET_STRUCT_TLVLEN( 17175 wmi_roam_get_scan_channel_list_cmd_fixed_param)); 17176 cmd->vdev_id = vdev_id; 17177 wmi_mtrace(WMI_ROAM_GET_SCAN_CHANNEL_LIST_CMDID, vdev_id, 0); 17178 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 17179 WMI_ROAM_GET_SCAN_CHANNEL_LIST_CMDID); 17180 if (QDF_IS_STATUS_ERROR(ret)) { 17181 wmi_err("Failed to send get roam scan channels request = %d", 17182 ret); 17183 wmi_buf_free(buf); 17184 } 17185 return ret; 17186 } 17187 17188 /** 17189 * extract_roam_scan_stats_res_evt_tlv() - Extract roam scan stats event 17190 * @wmi_handle: wmi handle 17191 * @evt_buf: pointer to event buffer 17192 * @vdev_id: output pointer to hold vdev id 17193 * @res_param: output pointer to hold the allocated response 17194 * 17195 * Return: QDF_STATUS 17196 */ 17197 static QDF_STATUS 17198 extract_roam_scan_stats_res_evt_tlv(wmi_unified_t wmi_handle, void *evt_buf, 17199 uint32_t *vdev_id, 17200 struct wmi_roam_scan_stats_res **res_param) 17201 { 17202 WMI_ROAM_SCAN_STATS_EVENTID_param_tlvs *param_buf; 17203 wmi_roam_scan_stats_event_fixed_param *fixed_param; 17204 uint32_t *client_id = NULL; 17205 wmi_roaming_timestamp *timestamp = NULL; 17206 uint32_t *num_channels = NULL; 17207 uint32_t *chan_info = NULL; 17208 wmi_mac_addr *old_bssid = NULL; 17209 uint32_t *is_roaming_success = NULL; 17210 wmi_mac_addr *new_bssid = NULL; 17211 uint32_t *num_roam_candidates = NULL; 17212 wmi_roam_scan_trigger_reason *roam_reason = NULL; 17213 wmi_mac_addr *bssid = NULL; 17214 uint32_t *score = NULL; 17215 uint32_t *channel = NULL; 17216 uint32_t *rssi = NULL; 17217 int chan_idx = 0, cand_idx = 0; 17218 uint32_t total_len; 17219 struct wmi_roam_scan_stats_res *res; 17220 uint32_t i, j; 17221 uint32_t num_scans, scan_param_size; 17222 17223 *res_param = NULL; 17224 *vdev_id = 0xFF; /* Initialize to invalid vdev id */ 17225 param_buf = (WMI_ROAM_SCAN_STATS_EVENTID_param_tlvs *)evt_buf; 17226 if (!param_buf) { 17227 wmi_err("Invalid roam scan stats event"); 17228 return QDF_STATUS_E_INVAL; 17229 } 17230 17231 fixed_param = param_buf->fixed_param; 17232 17233 num_scans = fixed_param->num_roam_scans; 17234 scan_param_size = sizeof(struct wmi_roam_scan_stats_params); 17235 *vdev_id = fixed_param->vdev_id; 17236 if (num_scans > WMI_ROAM_SCAN_STATS_MAX) { 17237 wmi_err_rl("%u exceeded maximum roam scan stats: %u", 17238 num_scans, WMI_ROAM_SCAN_STATS_MAX); 17239 return QDF_STATUS_E_INVAL; 17240 } 17241 17242 total_len = sizeof(*res) + num_scans * scan_param_size; 17243 17244 res = qdf_mem_malloc(total_len); 17245 if (!res) 17246 return QDF_STATUS_E_NOMEM; 17247 17248 if (!num_scans) { 17249 *res_param = res; 17250 return QDF_STATUS_SUCCESS; 17251 } 17252 17253 if (param_buf->client_id && 17254 param_buf->num_client_id == num_scans) 17255 client_id = param_buf->client_id; 17256 17257 if (param_buf->timestamp && 17258 param_buf->num_timestamp == num_scans) 17259 timestamp = param_buf->timestamp; 17260 17261 if (param_buf->old_bssid && 17262 param_buf->num_old_bssid == num_scans) 17263 old_bssid = param_buf->old_bssid; 17264 17265 if (param_buf->new_bssid && 17266 param_buf->num_new_bssid == num_scans) 17267 new_bssid = param_buf->new_bssid; 17268 17269 if (param_buf->is_roaming_success && 17270 param_buf->num_is_roaming_success == num_scans) 17271 is_roaming_success = param_buf->is_roaming_success; 17272 17273 if (param_buf->roam_reason && 17274 param_buf->num_roam_reason == num_scans) 17275 roam_reason = param_buf->roam_reason; 17276 17277 if (param_buf->num_channels && 17278 param_buf->num_num_channels == num_scans) { 17279 uint32_t count, chan_info_sum = 0; 17280 17281 num_channels = param_buf->num_channels; 17282 for (count = 0; count < param_buf->num_num_channels; count++) { 17283 if (param_buf->num_channels[count] > 17284 WMI_ROAM_SCAN_STATS_CHANNELS_MAX) { 17285 wmi_err_rl("%u exceeded max scan channels %u", 17286 param_buf->num_channels[count], 17287 WMI_ROAM_SCAN_STATS_CHANNELS_MAX); 17288 goto error; 17289 } 17290 chan_info_sum += param_buf->num_channels[count]; 17291 } 17292 17293 if (param_buf->chan_info && 17294 param_buf->num_chan_info == chan_info_sum) 17295 chan_info = param_buf->chan_info; 17296 } 17297 17298 if (param_buf->num_roam_candidates && 17299 param_buf->num_num_roam_candidates == num_scans) { 17300 uint32_t cnt, roam_cand_sum = 0; 17301 17302 num_roam_candidates = param_buf->num_roam_candidates; 17303 for (cnt = 0; cnt < param_buf->num_num_roam_candidates; cnt++) { 17304 if (param_buf->num_roam_candidates[cnt] > 17305 WMI_ROAM_SCAN_STATS_CANDIDATES_MAX) { 17306 wmi_err_rl("%u exceeded max scan cand %u", 17307 param_buf->num_roam_candidates[cnt], 17308 WMI_ROAM_SCAN_STATS_CANDIDATES_MAX); 17309 goto error; 17310 } 17311 roam_cand_sum += param_buf->num_roam_candidates[cnt]; 17312 } 17313 17314 if (param_buf->bssid && 17315 param_buf->num_bssid == roam_cand_sum) 17316 bssid = param_buf->bssid; 17317 17318 if (param_buf->score && 17319 param_buf->num_score == roam_cand_sum) 17320 score = param_buf->score; 17321 17322 if (param_buf->channel && 17323 param_buf->num_channel == roam_cand_sum) 17324 channel = param_buf->channel; 17325 17326 if (param_buf->rssi && 17327 param_buf->num_rssi == roam_cand_sum) 17328 rssi = param_buf->rssi; 17329 } 17330 17331 res->num_roam_scans = num_scans; 17332 for (i = 0; i < num_scans; i++) { 17333 struct wmi_roam_scan_stats_params *roam = &res->roam_scan[i]; 17334 17335 if (timestamp) 17336 roam->time_stamp = timestamp[i].lower32bit | 17337 (timestamp[i].upper32bit << 31); 17338 17339 if (client_id) 17340 roam->client_id = client_id[i]; 17341 17342 if (num_channels) { 17343 roam->num_scan_chans = num_channels[i]; 17344 if (chan_info) { 17345 for (j = 0; j < num_channels[i]; j++) 17346 roam->scan_freqs[j] = 17347 chan_info[chan_idx++]; 17348 } 17349 } 17350 17351 if (is_roaming_success) 17352 roam->is_roam_successful = is_roaming_success[i]; 17353 17354 if (roam_reason) { 17355 roam->trigger_id = roam_reason[i].trigger_id; 17356 roam->trigger_value = roam_reason[i].trigger_value; 17357 } 17358 17359 if (num_roam_candidates) { 17360 roam->num_roam_candidates = num_roam_candidates[i]; 17361 17362 for (j = 0; j < num_roam_candidates[i]; j++) { 17363 if (score) 17364 roam->cand[j].score = score[cand_idx]; 17365 if (rssi) 17366 roam->cand[j].rssi = rssi[cand_idx]; 17367 if (channel) 17368 roam->cand[j].freq = 17369 channel[cand_idx]; 17370 17371 if (bssid) 17372 WMI_MAC_ADDR_TO_CHAR_ARRAY( 17373 &bssid[cand_idx], 17374 roam->cand[j].bssid); 17375 17376 cand_idx++; 17377 } 17378 } 17379 17380 if (old_bssid) 17381 WMI_MAC_ADDR_TO_CHAR_ARRAY(&old_bssid[i], 17382 roam->old_bssid); 17383 17384 if (new_bssid) 17385 WMI_MAC_ADDR_TO_CHAR_ARRAY(&new_bssid[i], 17386 roam->new_bssid); 17387 } 17388 17389 *res_param = res; 17390 17391 return QDF_STATUS_SUCCESS; 17392 error: 17393 qdf_mem_free(res); 17394 return QDF_STATUS_E_FAILURE; 17395 } 17396 17397 /** 17398 * extract_offload_bcn_tx_status_evt() - Extract beacon-tx status event 17399 * @wmi_handle: wmi handle 17400 * @evt_buf: pointer to event buffer 17401 * @vdev_id: output pointer to hold vdev id 17402 * @tx_status: output pointer to hold the tx_status 17403 * 17404 * Return: QDF_STATUS 17405 */ 17406 static QDF_STATUS extract_offload_bcn_tx_status_evt(wmi_unified_t wmi_handle, 17407 void *evt_buf, 17408 uint32_t *vdev_id, 17409 uint32_t *tx_status) { 17410 WMI_OFFLOAD_BCN_TX_STATUS_EVENTID_param_tlvs *param_buf; 17411 wmi_offload_bcn_tx_status_event_fixed_param *bcn_tx_status_event; 17412 17413 param_buf = (WMI_OFFLOAD_BCN_TX_STATUS_EVENTID_param_tlvs *)evt_buf; 17414 if (!param_buf) { 17415 wmi_err("Invalid offload bcn tx status event buffer"); 17416 return QDF_STATUS_E_INVAL; 17417 } 17418 17419 bcn_tx_status_event = param_buf->fixed_param; 17420 *vdev_id = bcn_tx_status_event->vdev_id; 17421 *tx_status = bcn_tx_status_event->tx_status; 17422 17423 return QDF_STATUS_SUCCESS; 17424 } 17425 17426 #ifdef WLAN_SUPPORT_GREEN_AP 17427 static QDF_STATUS extract_green_ap_egap_status_info_tlv( 17428 uint8_t *evt_buf, 17429 struct wlan_green_ap_egap_status_info *egap_status_info_params) 17430 { 17431 WMI_AP_PS_EGAP_INFO_EVENTID_param_tlvs *param_buf; 17432 wmi_ap_ps_egap_info_event_fixed_param *egap_info_event; 17433 wmi_ap_ps_egap_info_chainmask_list *chainmask_event; 17434 17435 param_buf = (WMI_AP_PS_EGAP_INFO_EVENTID_param_tlvs *)evt_buf; 17436 if (!param_buf) { 17437 wmi_err("Invalid EGAP Info status event buffer"); 17438 return QDF_STATUS_E_INVAL; 17439 } 17440 17441 egap_info_event = (wmi_ap_ps_egap_info_event_fixed_param *) 17442 param_buf->fixed_param; 17443 chainmask_event = (wmi_ap_ps_egap_info_chainmask_list *) 17444 param_buf->chainmask_list; 17445 17446 if (!egap_info_event || !chainmask_event) { 17447 wmi_err("Invalid EGAP Info event or chainmask event"); 17448 return QDF_STATUS_E_INVAL; 17449 } 17450 17451 egap_status_info_params->status = egap_info_event->status; 17452 egap_status_info_params->mac_id = chainmask_event->mac_id; 17453 egap_status_info_params->tx_chainmask = chainmask_event->tx_chainmask; 17454 egap_status_info_params->rx_chainmask = chainmask_event->rx_chainmask; 17455 17456 return QDF_STATUS_SUCCESS; 17457 } 17458 #endif 17459 17460 #ifdef WLAN_SUPPORT_GAP_LL_PS_MODE 17461 static QDF_STATUS extract_green_ap_ll_ps_param_tlv( 17462 uint8_t *evt_buf, 17463 struct wlan_green_ap_ll_ps_event_param *ll_ps_params) 17464 { 17465 WMI_XGAP_ENABLE_COMPLETE_EVENTID_param_tlvs *param_buf; 17466 wmi_xgap_enable_complete_event_fixed_param *ll_ps_event; 17467 17468 param_buf = (WMI_XGAP_ENABLE_COMPLETE_EVENTID_param_tlvs *)evt_buf; 17469 if (!param_buf) { 17470 wmi_err("Invalid XGAP SAP info status"); 17471 return QDF_STATUS_E_INVAL; 17472 } 17473 17474 ll_ps_event = (wmi_xgap_enable_complete_event_fixed_param *) 17475 param_buf->fixed_param; 17476 if (!ll_ps_event) { 17477 wmi_err("Invalid low latency power save event buffer"); 17478 return QDF_STATUS_E_INVAL; 17479 } 17480 17481 ll_ps_params->dialog_token = ll_ps_event->dialog_token; 17482 ll_ps_params->next_tsf = 17483 ((uint64_t)ll_ps_event->next_tsf_high32 << 32) | 17484 ll_ps_event->next_tsf_low32; 17485 17486 wmi_debug("cookie : %llu next_tsf %llu", ll_ps_params->dialog_token, 17487 ll_ps_params->next_tsf); 17488 17489 return QDF_STATUS_SUCCESS; 17490 } 17491 #endif 17492 17493 /* 17494 * extract_comb_phyerr_tlv() - extract comb phy error from event 17495 * @wmi_handle: wmi handle 17496 * @evt_buf: pointer to event buffer 17497 * @datalen: data length of event buffer 17498 * @buf_offset: Pointer to hold value of current event buffer offset 17499 * post extraction 17500 * @phyerr: Pointer to hold phyerr 17501 * 17502 * Return: QDF_STATUS 17503 */ 17504 static QDF_STATUS extract_comb_phyerr_tlv(wmi_unified_t wmi_handle, 17505 void *evt_buf, 17506 uint16_t datalen, 17507 uint16_t *buf_offset, 17508 wmi_host_phyerr_t *phyerr) 17509 { 17510 WMI_PHYERR_EVENTID_param_tlvs *param_tlvs; 17511 wmi_comb_phyerr_rx_hdr *pe_hdr; 17512 17513 param_tlvs = (WMI_PHYERR_EVENTID_param_tlvs *)evt_buf; 17514 if (!param_tlvs) { 17515 wmi_debug("Received null data from FW"); 17516 return QDF_STATUS_E_FAILURE; 17517 } 17518 17519 pe_hdr = param_tlvs->hdr; 17520 if (!pe_hdr) { 17521 wmi_debug("Received Data PE Header is NULL"); 17522 return QDF_STATUS_E_FAILURE; 17523 } 17524 17525 /* Ensure it's at least the size of the header */ 17526 if (datalen < sizeof(*pe_hdr)) { 17527 wmi_debug("Expected minimum size %zu, received %d", 17528 sizeof(*pe_hdr), datalen); 17529 return QDF_STATUS_E_FAILURE; 17530 } 17531 17532 phyerr->pdev_id = wmi_handle->ops-> 17533 convert_pdev_id_target_to_host(wmi_handle, pe_hdr->pdev_id); 17534 phyerr->tsf64 = pe_hdr->tsf_l32; 17535 phyerr->tsf64 |= (((uint64_t)pe_hdr->tsf_u32) << 32); 17536 phyerr->bufp = param_tlvs->bufp; 17537 17538 if (pe_hdr->buf_len > param_tlvs->num_bufp) { 17539 wmi_debug("Invalid buf_len %d, num_bufp %d", 17540 pe_hdr->buf_len, param_tlvs->num_bufp); 17541 return QDF_STATUS_E_FAILURE; 17542 } 17543 17544 phyerr->buf_len = pe_hdr->buf_len; 17545 phyerr->phy_err_mask0 = pe_hdr->rsPhyErrMask0; 17546 phyerr->phy_err_mask1 = pe_hdr->rsPhyErrMask1; 17547 *buf_offset = sizeof(*pe_hdr) + sizeof(uint32_t); 17548 17549 return QDF_STATUS_SUCCESS; 17550 } 17551 17552 /** 17553 * extract_single_phyerr_tlv() - extract single phy error from event 17554 * @wmi_handle: wmi handle 17555 * @evt_buf: pointer to event buffer 17556 * @datalen: data length of event buffer 17557 * @buf_offset: Pointer to hold value of current event buffer offset 17558 * post extraction 17559 * @phyerr: Pointer to hold phyerr 17560 * 17561 * Return: QDF_STATUS 17562 */ 17563 static QDF_STATUS extract_single_phyerr_tlv(wmi_unified_t wmi_handle, 17564 void *evt_buf, 17565 uint16_t datalen, 17566 uint16_t *buf_offset, 17567 wmi_host_phyerr_t *phyerr) 17568 { 17569 wmi_single_phyerr_rx_event *ev; 17570 uint16_t n = *buf_offset; 17571 uint8_t *data = (uint8_t *)evt_buf; 17572 17573 if (n < datalen) { 17574 if ((datalen - n) < sizeof(ev->hdr)) { 17575 wmi_debug("Not enough space. len=%d, n=%d, hdr=%zu", 17576 datalen, n, sizeof(ev->hdr)); 17577 return QDF_STATUS_E_FAILURE; 17578 } 17579 17580 /* 17581 * Obtain a pointer to the beginning of the current event. 17582 * data[0] is the beginning of the WMI payload. 17583 */ 17584 ev = (wmi_single_phyerr_rx_event *)&data[n]; 17585 17586 /* 17587 * Sanity check the buffer length of the event against 17588 * what we currently have. 17589 * 17590 * Since buf_len is 32 bits, we check if it overflows 17591 * a large 32 bit value. It's not 0x7fffffff because 17592 * we increase n by (buf_len + sizeof(hdr)), which would 17593 * in itself cause n to overflow. 17594 * 17595 * If "int" is 64 bits then this becomes a moot point. 17596 */ 17597 if (ev->hdr.buf_len > PHYERROR_MAX_BUFFER_LENGTH) { 17598 wmi_debug("buf_len is garbage 0x%x", ev->hdr.buf_len); 17599 return QDF_STATUS_E_FAILURE; 17600 } 17601 17602 if ((n + ev->hdr.buf_len) > datalen) { 17603 wmi_debug("len exceeds n=%d, buf_len=%d, datalen=%d", 17604 n, ev->hdr.buf_len, datalen); 17605 return QDF_STATUS_E_FAILURE; 17606 } 17607 17608 phyerr->phy_err_code = WMI_UNIFIED_PHYERRCODE_GET(&ev->hdr); 17609 phyerr->tsf_timestamp = ev->hdr.tsf_timestamp; 17610 phyerr->bufp = &ev->bufp[0]; 17611 phyerr->buf_len = ev->hdr.buf_len; 17612 phyerr->rf_info.rssi_comb = WMI_UNIFIED_RSSI_COMB_GET(&ev->hdr); 17613 17614 /* 17615 * Advance the buffer pointer to the next PHY error. 17616 * buflen is the length of this payload, so we need to 17617 * advance past the current header _AND_ the payload. 17618 */ 17619 n += sizeof(*ev) + ev->hdr.buf_len; 17620 } 17621 *buf_offset = n; 17622 17623 return QDF_STATUS_SUCCESS; 17624 } 17625 17626 /** 17627 * extract_esp_estimation_ev_param_tlv() - extract air time from event 17628 * @wmi_handle: wmi handle 17629 * @evt_buf: pointer to event buffer 17630 * @param: Pointer to hold esp event 17631 * 17632 * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_INVAL on failure 17633 */ 17634 static QDF_STATUS 17635 extract_esp_estimation_ev_param_tlv(wmi_unified_t wmi_handle, 17636 void *evt_buf, 17637 struct esp_estimation_event *param) 17638 { 17639 WMI_ESP_ESTIMATE_EVENTID_param_tlvs *param_buf; 17640 wmi_esp_estimate_event_fixed_param *esp_event; 17641 17642 param_buf = (WMI_ESP_ESTIMATE_EVENTID_param_tlvs *)evt_buf; 17643 if (!param_buf) { 17644 wmi_err("Invalid ESP Estimate Event buffer"); 17645 return QDF_STATUS_E_INVAL; 17646 } 17647 esp_event = param_buf->fixed_param; 17648 param->ac_airtime_percentage = esp_event->ac_airtime_percentage; 17649 17650 param->pdev_id = convert_target_pdev_id_to_host_pdev_id( 17651 wmi_handle, 17652 esp_event->pdev_id); 17653 17654 if (param->pdev_id == WMI_HOST_PDEV_ID_INVALID) 17655 return QDF_STATUS_E_FAILURE; 17656 17657 return QDF_STATUS_SUCCESS; 17658 } 17659 17660 /* 17661 * send_bss_color_change_enable_cmd_tlv() - Send command to enable or disable of 17662 * updating bss color change within firmware when AP announces bss color change. 17663 * @wmi_handle: wmi handle 17664 * @vdev_id: vdev ID 17665 * @enable: enable bss color change within firmware 17666 * 17667 * Send WMI_BSS_COLOR_CHANGE_ENABLE_CMDID parameters to fw. 17668 * 17669 * Return: QDF_STATUS 17670 */ 17671 static QDF_STATUS send_bss_color_change_enable_cmd_tlv(wmi_unified_t wmi_handle, 17672 uint32_t vdev_id, 17673 bool enable) 17674 { 17675 wmi_buf_t buf; 17676 wmi_bss_color_change_enable_fixed_param *cmd; 17677 uint8_t len = sizeof(wmi_bss_color_change_enable_fixed_param); 17678 17679 buf = wmi_buf_alloc(wmi_handle, len); 17680 if (!buf) 17681 return QDF_STATUS_E_NOMEM; 17682 17683 cmd = (wmi_bss_color_change_enable_fixed_param *)wmi_buf_data(buf); 17684 WMITLV_SET_HDR(&cmd->tlv_header, 17685 WMITLV_TAG_STRUC_wmi_bss_color_change_enable_fixed_param, 17686 WMITLV_GET_STRUCT_TLVLEN 17687 (wmi_bss_color_change_enable_fixed_param)); 17688 cmd->vdev_id = vdev_id; 17689 cmd->enable = enable; 17690 wmi_mtrace(WMI_BSS_COLOR_CHANGE_ENABLE_CMDID, cmd->vdev_id, 0); 17691 if (wmi_unified_cmd_send(wmi_handle, buf, len, 17692 WMI_BSS_COLOR_CHANGE_ENABLE_CMDID)) { 17693 wmi_err("Failed to send WMI_BSS_COLOR_CHANGE_ENABLE_CMDID"); 17694 wmi_buf_free(buf); 17695 return QDF_STATUS_E_FAILURE; 17696 } 17697 17698 return QDF_STATUS_SUCCESS; 17699 } 17700 17701 /** 17702 * send_obss_color_collision_cfg_cmd_tlv() - send bss color detection 17703 * configurations to firmware. 17704 * @wmi_handle: wmi handle 17705 * @cfg_param: obss detection configurations 17706 * 17707 * Send WMI_OBSS_COLOR_COLLISION_DET_CONFIG_CMDID parameters to fw. 17708 * 17709 * Return: QDF_STATUS 17710 */ 17711 static QDF_STATUS send_obss_color_collision_cfg_cmd_tlv( 17712 wmi_unified_t wmi_handle, 17713 struct wmi_obss_color_collision_cfg_param *cfg_param) 17714 { 17715 wmi_buf_t buf; 17716 wmi_obss_color_collision_det_config_fixed_param *cmd; 17717 uint8_t len = sizeof(wmi_obss_color_collision_det_config_fixed_param); 17718 17719 buf = wmi_buf_alloc(wmi_handle, len); 17720 if (!buf) 17721 return QDF_STATUS_E_NOMEM; 17722 17723 cmd = (wmi_obss_color_collision_det_config_fixed_param *)wmi_buf_data( 17724 buf); 17725 WMITLV_SET_HDR(&cmd->tlv_header, 17726 WMITLV_TAG_STRUC_wmi_obss_color_collision_det_config_fixed_param, 17727 WMITLV_GET_STRUCT_TLVLEN 17728 (wmi_obss_color_collision_det_config_fixed_param)); 17729 cmd->vdev_id = cfg_param->vdev_id; 17730 cmd->flags = cfg_param->flags; 17731 cmd->current_bss_color = cfg_param->current_bss_color; 17732 cmd->detection_period_ms = cfg_param->detection_period_ms; 17733 cmd->scan_period_ms = cfg_param->scan_period_ms; 17734 cmd->free_slot_expiry_time_ms = cfg_param->free_slot_expiry_time_ms; 17735 17736 switch (cfg_param->evt_type) { 17737 case OBSS_COLOR_COLLISION_DETECTION_DISABLE: 17738 cmd->evt_type = WMI_BSS_COLOR_COLLISION_DISABLE; 17739 break; 17740 case OBSS_COLOR_COLLISION_DETECTION: 17741 cmd->evt_type = WMI_BSS_COLOR_COLLISION_DETECTION; 17742 break; 17743 case OBSS_COLOR_FREE_SLOT_TIMER_EXPIRY: 17744 cmd->evt_type = WMI_BSS_COLOR_FREE_SLOT_TIMER_EXPIRY; 17745 break; 17746 case OBSS_COLOR_FREE_SLOT_AVAILABLE: 17747 cmd->evt_type = WMI_BSS_COLOR_FREE_SLOT_AVAILABLE; 17748 break; 17749 default: 17750 wmi_err("Invalid event type: %d", cfg_param->evt_type); 17751 wmi_buf_free(buf); 17752 return QDF_STATUS_E_FAILURE; 17753 } 17754 17755 wmi_debug("evt_type: %d vdev id: %d current_bss_color: %d " 17756 "detection_period_ms: %d scan_period_ms: %d " 17757 "free_slot_expiry_timer_ms: %d", 17758 cmd->evt_type, cmd->vdev_id, cmd->current_bss_color, 17759 cmd->detection_period_ms, cmd->scan_period_ms, 17760 cmd->free_slot_expiry_time_ms); 17761 17762 wmi_mtrace(WMI_OBSS_COLOR_COLLISION_DET_CONFIG_CMDID, cmd->vdev_id, 0); 17763 if (wmi_unified_cmd_send(wmi_handle, buf, len, 17764 WMI_OBSS_COLOR_COLLISION_DET_CONFIG_CMDID)) { 17765 wmi_err("Sending OBSS color det cmd failed, vdev_id: %d", 17766 cfg_param->vdev_id); 17767 wmi_buf_free(buf); 17768 return QDF_STATUS_E_FAILURE; 17769 } 17770 17771 return QDF_STATUS_SUCCESS; 17772 } 17773 17774 /** 17775 * extract_obss_color_collision_info_tlv() - Extract bss color collision info 17776 * received from firmware. 17777 * @evt_buf: pointer to event buffer 17778 * @info: Pointer to hold bss collision info 17779 * 17780 * Return: QDF_STATUS 17781 */ 17782 static QDF_STATUS extract_obss_color_collision_info_tlv(uint8_t *evt_buf, 17783 struct wmi_obss_color_collision_info *info) 17784 { 17785 WMI_OBSS_COLOR_COLLISION_DETECTION_EVENTID_param_tlvs *param_buf; 17786 wmi_obss_color_collision_evt_fixed_param *fix_param; 17787 17788 if (!info) { 17789 wmi_err("Invalid obss color buffer"); 17790 return QDF_STATUS_E_INVAL; 17791 } 17792 17793 param_buf = (WMI_OBSS_COLOR_COLLISION_DETECTION_EVENTID_param_tlvs *) 17794 evt_buf; 17795 if (!param_buf) { 17796 wmi_err("Invalid evt_buf"); 17797 return QDF_STATUS_E_INVAL; 17798 } 17799 17800 fix_param = param_buf->fixed_param; 17801 info->vdev_id = fix_param->vdev_id; 17802 info->obss_color_bitmap_bit0to31 = 17803 fix_param->bss_color_bitmap_bit0to31; 17804 info->obss_color_bitmap_bit32to63 = 17805 fix_param->bss_color_bitmap_bit32to63; 17806 17807 switch (fix_param->evt_type) { 17808 case WMI_BSS_COLOR_COLLISION_DISABLE: 17809 info->evt_type = OBSS_COLOR_COLLISION_DETECTION_DISABLE; 17810 break; 17811 case WMI_BSS_COLOR_COLLISION_DETECTION: 17812 info->evt_type = OBSS_COLOR_COLLISION_DETECTION; 17813 break; 17814 case WMI_BSS_COLOR_FREE_SLOT_TIMER_EXPIRY: 17815 info->evt_type = OBSS_COLOR_FREE_SLOT_TIMER_EXPIRY; 17816 break; 17817 case WMI_BSS_COLOR_FREE_SLOT_AVAILABLE: 17818 info->evt_type = OBSS_COLOR_FREE_SLOT_AVAILABLE; 17819 break; 17820 default: 17821 wmi_err("Invalid event type: %d, vdev_id: %d", 17822 fix_param->evt_type, fix_param->vdev_id); 17823 return QDF_STATUS_E_FAILURE; 17824 } 17825 17826 return QDF_STATUS_SUCCESS; 17827 } 17828 17829 static void wmi_11ax_bss_color_attach_tlv(struct wmi_unified *wmi_handle) 17830 { 17831 struct wmi_ops *ops = wmi_handle->ops; 17832 17833 ops->send_obss_color_collision_cfg_cmd = 17834 send_obss_color_collision_cfg_cmd_tlv; 17835 ops->extract_obss_color_collision_info = 17836 extract_obss_color_collision_info_tlv; 17837 } 17838 17839 #if defined(WLAN_SUPPORT_FILS) || defined(CONFIG_BAND_6GHZ) 17840 static QDF_STATUS 17841 send_vdev_fils_enable_cmd_send(struct wmi_unified *wmi_handle, 17842 struct config_fils_params *param) 17843 { 17844 wmi_buf_t buf; 17845 wmi_enable_fils_cmd_fixed_param *cmd; 17846 uint8_t len = sizeof(wmi_enable_fils_cmd_fixed_param); 17847 17848 buf = wmi_buf_alloc(wmi_handle, len); 17849 if (!buf) 17850 return QDF_STATUS_E_NOMEM; 17851 17852 cmd = (wmi_enable_fils_cmd_fixed_param *)wmi_buf_data( 17853 buf); 17854 WMITLV_SET_HDR(&cmd->tlv_header, 17855 WMITLV_TAG_STRUC_wmi_enable_fils_cmd_fixed_param, 17856 WMITLV_GET_STRUCT_TLVLEN 17857 (wmi_enable_fils_cmd_fixed_param)); 17858 cmd->vdev_id = param->vdev_id; 17859 cmd->fd_period = param->fd_period; 17860 if (param->send_prb_rsp_frame) 17861 cmd->flags |= WMI_FILS_FLAGS_BITMAP_BCAST_PROBE_RSP; 17862 wmi_debug("vdev id: %d fd_period: %d cmd->Flags %d", 17863 cmd->vdev_id, cmd->fd_period, cmd->flags); 17864 wmi_mtrace(WMI_ENABLE_FILS_CMDID, cmd->vdev_id, cmd->fd_period); 17865 if (wmi_unified_cmd_send(wmi_handle, buf, len, 17866 WMI_ENABLE_FILS_CMDID)) { 17867 wmi_err("Sending FILS cmd failed, vdev_id: %d", param->vdev_id); 17868 wmi_buf_free(buf); 17869 return QDF_STATUS_E_FAILURE; 17870 } 17871 17872 return QDF_STATUS_SUCCESS; 17873 } 17874 #endif 17875 17876 #ifdef WLAN_MWS_INFO_DEBUGFS 17877 /** 17878 * send_mws_coex_status_req_cmd_tlv() - send coex cmd to fw 17879 * 17880 * @wmi_handle: wmi handle 17881 * @vdev_id: vdev id 17882 * @cmd_id: Coex command id 17883 * 17884 * Send WMI_VDEV_GET_MWS_COEX_INFO_CMDID to fw. 17885 * 17886 * Return: QDF_STATUS 17887 */ 17888 static QDF_STATUS send_mws_coex_status_req_cmd_tlv(wmi_unified_t wmi_handle, 17889 uint32_t vdev_id, 17890 uint32_t cmd_id) 17891 { 17892 wmi_buf_t buf; 17893 wmi_vdev_get_mws_coex_info_cmd_fixed_param *cmd; 17894 uint16_t len = sizeof(*cmd); 17895 int ret; 17896 17897 buf = wmi_buf_alloc(wmi_handle, len); 17898 if (!buf) { 17899 wmi_err("Failed to allocate wmi buffer"); 17900 return QDF_STATUS_E_NOMEM; 17901 } 17902 17903 cmd = (wmi_vdev_get_mws_coex_info_cmd_fixed_param *)wmi_buf_data(buf); 17904 WMITLV_SET_HDR(&cmd->tlv_header, 17905 WMITLV_TAG_STRUC_wmi_vdev_get_mws_coex_info_cmd_fixed_param, 17906 WMITLV_GET_STRUCT_TLVLEN 17907 (wmi_vdev_get_mws_coex_info_cmd_fixed_param)); 17908 cmd->vdev_id = vdev_id; 17909 cmd->cmd_id = cmd_id; 17910 wmi_mtrace(WMI_VDEV_GET_MWS_COEX_INFO_CMDID, vdev_id, 0); 17911 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 17912 WMI_VDEV_GET_MWS_COEX_INFO_CMDID); 17913 if (QDF_IS_STATUS_ERROR(ret)) { 17914 wmi_err("Failed to send set param command ret = %d", ret); 17915 wmi_buf_free(buf); 17916 } 17917 return ret; 17918 } 17919 #endif 17920 17921 #ifdef FEATURE_MEC_OFFLOAD 17922 static QDF_STATUS 17923 send_pdev_set_mec_timer_cmd_tlv(struct wmi_unified *wmi_handle, 17924 struct set_mec_timer_params *param) 17925 { 17926 wmi_pdev_mec_aging_timer_config_cmd_fixed_param *cmd; 17927 wmi_buf_t buf; 17928 int32_t len = sizeof(*cmd); 17929 17930 buf = wmi_buf_alloc(wmi_handle, len); 17931 if (!buf) { 17932 wmi_err("wmi_buf_alloc failed"); 17933 return QDF_STATUS_E_FAILURE; 17934 } 17935 cmd = (wmi_pdev_mec_aging_timer_config_cmd_fixed_param *) 17936 wmi_buf_data(buf); 17937 WMITLV_SET_HDR(&cmd->tlv_header, 17938 WMITLV_TAG_STRUC_wmi_pdev_mec_aging_timer_config_cmd_fixed_param, 17939 WMITLV_GET_STRUCT_TLVLEN( 17940 wmi_pdev_mec_aging_timer_config_cmd_fixed_param)); 17941 cmd->pdev_id = param->pdev_id; 17942 cmd->mec_aging_timer_threshold = param->mec_aging_timer_threshold; 17943 17944 wmi_mtrace(WMI_PDEV_MEC_AGING_TIMER_CONFIG_CMDID, param->vdev_id, 0); 17945 if (wmi_unified_cmd_send(wmi_handle, buf, len, 17946 WMI_PDEV_MEC_AGING_TIMER_CONFIG_CMDID)) { 17947 wmi_err("Failed to set mec aging timer param"); 17948 wmi_buf_free(buf); 17949 return QDF_STATUS_E_FAILURE; 17950 } 17951 17952 return QDF_STATUS_SUCCESS; 17953 } 17954 #endif 17955 17956 #ifdef WIFI_POS_CONVERGED 17957 /** 17958 * extract_oem_response_param_tlv() - Extract oem response params 17959 * @wmi_handle: wmi handle 17960 * @resp_buf: response buffer 17961 * @oem_resp_param: pointer to hold oem response params 17962 * 17963 * Return: QDF_STATUS_SUCCESS on success or proper error code. 17964 */ 17965 static QDF_STATUS 17966 extract_oem_response_param_tlv(wmi_unified_t wmi_handle, void *resp_buf, 17967 struct wmi_oem_response_param *oem_resp_param) 17968 { 17969 uint64_t temp_addr; 17970 WMI_OEM_RESPONSE_EVENTID_param_tlvs *param_buf = 17971 (WMI_OEM_RESPONSE_EVENTID_param_tlvs *)resp_buf; 17972 17973 if (!param_buf) { 17974 wmi_err("Invalid OEM response"); 17975 return QDF_STATUS_E_INVAL; 17976 } 17977 17978 if (param_buf->num_data) { 17979 oem_resp_param->num_data1 = param_buf->num_data; 17980 oem_resp_param->data_1 = param_buf->data; 17981 } 17982 17983 if (param_buf->num_data2) { 17984 oem_resp_param->num_data2 = param_buf->num_data2; 17985 oem_resp_param->data_2 = param_buf->data2; 17986 } 17987 17988 if (param_buf->indirect_data) { 17989 oem_resp_param->indirect_data.pdev_id = 17990 param_buf->indirect_data->pdev_id; 17991 temp_addr = (param_buf->indirect_data->addr_hi) & 0xf; 17992 oem_resp_param->indirect_data.addr = 17993 param_buf->indirect_data->addr_lo + 17994 ((uint64_t)temp_addr << 32); 17995 oem_resp_param->indirect_data.len = 17996 param_buf->indirect_data->len; 17997 } 17998 17999 return QDF_STATUS_SUCCESS; 18000 } 18001 #endif /* WIFI_POS_CONVERGED */ 18002 18003 #if defined(WIFI_POS_CONVERGED) && defined(WLAN_FEATURE_RTT_11AZ_SUPPORT) 18004 #define WLAN_PASN_LTF_KEY_SEED_REQUIRED 0x2 18005 18006 static QDF_STATUS 18007 extract_pasn_peer_create_req_event_tlv(wmi_unified_t wmi_handle, void *evt_buf, 18008 struct wifi_pos_pasn_peer_data *dst) 18009 { 18010 WMI_RTT_PASN_PEER_CREATE_REQ_EVENTID_param_tlvs *param_buf; 18011 wmi_rtt_pasn_peer_create_req_event_fixed_param *fixed_param; 18012 wmi_rtt_pasn_peer_create_req_param *buf; 18013 uint8_t security_mode, i; 18014 18015 param_buf = (WMI_RTT_PASN_PEER_CREATE_REQ_EVENTID_param_tlvs *)evt_buf; 18016 if (!param_buf) { 18017 wmi_err("Invalid peer_create req buffer"); 18018 return QDF_STATUS_E_INVAL; 18019 } 18020 18021 fixed_param = param_buf->fixed_param; 18022 18023 if (param_buf->num_rtt_pasn_peer_param > 18024 ((WMI_SVC_MSG_MAX_SIZE - sizeof(*fixed_param)) / 18025 sizeof(wmi_rtt_pasn_peer_create_req_param))) { 18026 wmi_err("Invalid TLV size"); 18027 return QDF_STATUS_E_INVAL; 18028 } 18029 18030 if (!param_buf->num_rtt_pasn_peer_param || 18031 param_buf->num_rtt_pasn_peer_param > WLAN_MAX_11AZ_PEERS) { 18032 wmi_err("Invalid num TLV:%d", 18033 param_buf->num_rtt_pasn_peer_param); 18034 return QDF_STATUS_E_INVAL; 18035 } 18036 18037 dst->vdev_id = fixed_param->vdev_id; 18038 if (dst->vdev_id >= WLAN_UMAC_PDEV_MAX_VDEVS) { 18039 wmi_err("Invalid vdev id:%d", dst->vdev_id); 18040 return QDF_STATUS_E_INVAL; 18041 } 18042 18043 buf = param_buf->rtt_pasn_peer_param; 18044 if (!buf) { 18045 wmi_err("NULL peer param TLV"); 18046 return QDF_STATUS_E_INVAL; 18047 } 18048 18049 for (i = 0; i < param_buf->num_rtt_pasn_peer_param; i++) { 18050 WMI_MAC_ADDR_TO_CHAR_ARRAY(&buf->self_mac_addr, 18051 dst->peer_info[i].self_mac.bytes); 18052 WMI_MAC_ADDR_TO_CHAR_ARRAY(&buf->dest_mac_addr, 18053 dst->peer_info[i].peer_mac.bytes); 18054 security_mode = WMI_RTT_PASN_PEER_CREATE_SECURITY_MODE_GET( 18055 buf->control_flag); 18056 if (security_mode) 18057 dst->peer_info[i].peer_type = 18058 WLAN_WIFI_POS_PASN_SECURE_PEER; 18059 else 18060 dst->peer_info[i].peer_type = 18061 WLAN_WIFI_POS_PASN_UNSECURE_PEER; 18062 if (security_mode & WLAN_PASN_LTF_KEY_SEED_REQUIRED) 18063 dst->peer_info[i].is_ltf_keyseed_required = true; 18064 18065 dst->peer_info[i].force_self_mac_usage = 18066 WMI_RTT_PASN_PEER_CREATE_FORCE_SELF_MAC_USE_GET( 18067 buf->control_flag); 18068 dst->num_peers++; 18069 buf++; 18070 } 18071 18072 return QDF_STATUS_SUCCESS; 18073 } 18074 18075 static QDF_STATUS 18076 extract_pasn_peer_delete_req_event_tlv(wmi_unified_t wmi_handle, void *evt_buf, 18077 struct wifi_pos_pasn_peer_data *dst) 18078 { 18079 WMI_RTT_PASN_PEER_DELETE_EVENTID_param_tlvs *param_buf; 18080 wmi_rtt_pasn_peer_delete_event_fixed_param *fixed_param; 18081 wmi_rtt_pasn_peer_delete_param *buf; 18082 uint8_t i; 18083 18084 param_buf = (WMI_RTT_PASN_PEER_DELETE_EVENTID_param_tlvs *)evt_buf; 18085 if (!param_buf) { 18086 wmi_err("Invalid peer_delete evt buffer"); 18087 return QDF_STATUS_E_INVAL; 18088 } 18089 18090 fixed_param = param_buf->fixed_param; 18091 18092 if (param_buf->num_rtt_pasn_peer_param > 18093 ((WMI_SVC_MSG_MAX_SIZE - sizeof(*fixed_param)) / 18094 sizeof(wmi_rtt_pasn_peer_delete_param))) { 18095 wmi_err("Invalid TLV size"); 18096 return QDF_STATUS_E_INVAL; 18097 } 18098 18099 if (!param_buf->num_rtt_pasn_peer_param || 18100 param_buf->num_rtt_pasn_peer_param > WLAN_MAX_11AZ_PEERS) { 18101 wmi_err("Invalid num TLV:%d", 18102 param_buf->num_rtt_pasn_peer_param); 18103 return QDF_STATUS_E_INVAL; 18104 } 18105 18106 dst->vdev_id = fixed_param->vdev_id; 18107 if (dst->vdev_id >= WLAN_UMAC_PDEV_MAX_VDEVS) { 18108 wmi_err("Invalid vdev id:%d", dst->vdev_id); 18109 return QDF_STATUS_E_INVAL; 18110 } 18111 18112 buf = param_buf->rtt_pasn_peer_param; 18113 if (!buf) { 18114 wmi_err("NULL peer param TLV"); 18115 return QDF_STATUS_E_INVAL; 18116 } 18117 18118 for (i = 0; i < param_buf->num_rtt_pasn_peer_param; i++) { 18119 WMI_MAC_ADDR_TO_CHAR_ARRAY(&buf->peer_mac_addr, 18120 dst->peer_info[i].peer_mac.bytes); 18121 dst->peer_info[i].control_flags = buf->control_flag; 18122 18123 dst->num_peers++; 18124 buf++; 18125 } 18126 18127 return QDF_STATUS_SUCCESS; 18128 } 18129 18130 static QDF_STATUS 18131 send_rtt_pasn_auth_status_cmd_tlv(wmi_unified_t wmi_handle, 18132 struct wlan_pasn_auth_status *data) 18133 { 18134 QDF_STATUS status; 18135 wmi_buf_t buf; 18136 wmi_rtt_pasn_auth_status_cmd_fixed_param *fixed_param; 18137 uint8_t *buf_ptr; 18138 uint8_t i; 18139 size_t len = sizeof(*fixed_param) + 18140 data->num_peers * sizeof(wmi_rtt_pasn_auth_status_param) + 18141 WMI_TLV_HDR_SIZE; 18142 18143 buf = wmi_buf_alloc(wmi_handle, len); 18144 if (!buf) { 18145 wmi_err("wmi_buf_alloc failed"); 18146 return QDF_STATUS_E_FAILURE; 18147 } 18148 buf_ptr = (uint8_t *)wmi_buf_data(buf); 18149 fixed_param = 18150 (wmi_rtt_pasn_auth_status_cmd_fixed_param *)wmi_buf_data(buf); 18151 WMITLV_SET_HDR(&fixed_param->tlv_header, 18152 WMITLV_TAG_STRUC_wmi_rtt_pasn_auth_status_cmd_fixed_param, 18153 WMITLV_GET_STRUCT_TLVLEN( 18154 wmi_rtt_pasn_auth_status_cmd_fixed_param)); 18155 buf_ptr += sizeof(*fixed_param); 18156 18157 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 18158 (data->num_peers * 18159 sizeof(wmi_rtt_pasn_auth_status_param))); 18160 buf_ptr += WMI_TLV_HDR_SIZE; 18161 18162 for (i = 0; i < data->num_peers; i++) { 18163 wmi_rtt_pasn_auth_status_param *auth_status_tlv = 18164 (wmi_rtt_pasn_auth_status_param *)buf_ptr; 18165 18166 WMITLV_SET_HDR(&auth_status_tlv->tlv_header, 18167 WMITLV_TAG_STRUC_wmi_rtt_pasn_auth_status_param, 18168 WMITLV_GET_STRUCT_TLVLEN(wmi_rtt_pasn_auth_status_param)); 18169 18170 WMI_CHAR_ARRAY_TO_MAC_ADDR(data->auth_status[i].peer_mac.bytes, 18171 &auth_status_tlv->peer_mac_addr); 18172 WMI_CHAR_ARRAY_TO_MAC_ADDR(data->auth_status[i].self_mac.bytes, 18173 &auth_status_tlv->source_mac_addr); 18174 auth_status_tlv->status = data->auth_status[i].status; 18175 wmi_debug("peer_mac: " QDF_MAC_ADDR_FMT " self_mac:" QDF_MAC_ADDR_FMT " status:%d", 18176 QDF_MAC_ADDR_REF(data->auth_status[i].peer_mac.bytes), 18177 QDF_MAC_ADDR_REF(data->auth_status[i].self_mac.bytes), 18178 auth_status_tlv->status); 18179 18180 buf_ptr += sizeof(wmi_rtt_pasn_auth_status_param); 18181 } 18182 18183 wmi_mtrace(WMI_RTT_PASN_AUTH_STATUS_CMD, 0, 0); 18184 status = wmi_unified_cmd_send(wmi_handle, buf, len, 18185 WMI_RTT_PASN_AUTH_STATUS_CMD); 18186 if (QDF_IS_STATUS_ERROR(status)) { 18187 wmi_err("Failed to send Auth status command ret = %d", status); 18188 wmi_buf_free(buf); 18189 } 18190 18191 return status; 18192 } 18193 18194 static QDF_STATUS 18195 send_rtt_pasn_deauth_cmd_tlv(wmi_unified_t wmi_handle, 18196 struct qdf_mac_addr *peer_mac) 18197 { 18198 QDF_STATUS status; 18199 wmi_buf_t buf; 18200 wmi_rtt_pasn_deauth_cmd_fixed_param *fixed_param; 18201 size_t len = sizeof(*fixed_param); 18202 18203 buf = wmi_buf_alloc(wmi_handle, len); 18204 if (!buf) { 18205 wmi_err("wmi_buf_alloc failed"); 18206 return QDF_STATUS_E_FAILURE; 18207 } 18208 fixed_param = 18209 (wmi_rtt_pasn_deauth_cmd_fixed_param *)wmi_buf_data(buf); 18210 WMITLV_SET_HDR(&fixed_param->tlv_header, 18211 WMITLV_TAG_STRUC_wmi_rtt_pasn_deauth_cmd_fixed_param, 18212 WMITLV_GET_STRUCT_TLVLEN( 18213 wmi_rtt_pasn_deauth_cmd_fixed_param)); 18214 WMI_CHAR_ARRAY_TO_MAC_ADDR(peer_mac->bytes, 18215 &fixed_param->peer_mac_addr); 18216 18217 wmi_mtrace(WMI_RTT_PASN_DEAUTH_CMD, 0, 0); 18218 status = wmi_unified_cmd_send(wmi_handle, buf, len, 18219 WMI_RTT_PASN_DEAUTH_CMD); 18220 if (QDF_IS_STATUS_ERROR(status)) { 18221 wmi_err("Failed to send pasn deauth command ret = %d", status); 18222 wmi_buf_free(buf); 18223 } 18224 18225 return status; 18226 } 18227 #endif /* WLAN_FEATURE_RTT_11AZ_SUPPORT */ 18228 18229 static QDF_STATUS 18230 send_vdev_set_ltf_key_seed_cmd_tlv(wmi_unified_t wmi_handle, 18231 struct wlan_crypto_ltf_keyseed_data *data) 18232 { 18233 QDF_STATUS status; 18234 wmi_buf_t buf; 18235 wmi_vdev_set_ltf_key_seed_cmd_fixed_param *fixed_param; 18236 uint8_t *buf_ptr; 18237 size_t len = sizeof(*fixed_param) + data->key_seed_len + 18238 WMI_TLV_HDR_SIZE; 18239 18240 buf = wmi_buf_alloc(wmi_handle, len); 18241 if (!buf) { 18242 wmi_err("wmi_buf_alloc failed"); 18243 return QDF_STATUS_E_FAILURE; 18244 } 18245 18246 buf_ptr = (uint8_t *)wmi_buf_data(buf); 18247 fixed_param = 18248 (wmi_vdev_set_ltf_key_seed_cmd_fixed_param *)wmi_buf_data(buf); 18249 WMITLV_SET_HDR(&fixed_param->tlv_header, 18250 WMITLV_TAG_STRUC_wmi_vdev_set_ltf_key_seed_cmd_fixed_param, 18251 WMITLV_GET_STRUCT_TLVLEN( 18252 wmi_vdev_set_ltf_key_seed_cmd_fixed_param)); 18253 18254 fixed_param->vdev_id = data->vdev_id; 18255 WMI_CHAR_ARRAY_TO_MAC_ADDR(data->peer_mac_addr.bytes, 18256 &fixed_param->peer_macaddr); 18257 fixed_param->key_seed_len = data->key_seed_len; 18258 fixed_param->rsn_authmode = data->rsn_authmode; 18259 18260 buf_ptr += sizeof(*fixed_param); 18261 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, 18262 (fixed_param->key_seed_len * sizeof(A_UINT8))); 18263 buf_ptr += WMI_TLV_HDR_SIZE; 18264 18265 qdf_mem_copy(buf_ptr, data->key_seed, fixed_param->key_seed_len); 18266 18267 wmi_mtrace(WMI_VDEV_SET_LTF_KEY_SEED_CMDID, 0, 0); 18268 status = wmi_unified_cmd_send(wmi_handle, buf, len, 18269 WMI_VDEV_SET_LTF_KEY_SEED_CMDID); 18270 if (QDF_IS_STATUS_ERROR(status)) { 18271 wmi_err("Failed to send ltf keyseed command ret = %d", status); 18272 wmi_buf_free(buf); 18273 } 18274 18275 return status; 18276 } 18277 18278 /** 18279 * extract_hw_mode_resp_event_status_tlv() - Extract HW mode change status 18280 * @wmi_handle: wmi handle 18281 * @evt_buf: pointer to event buffer 18282 * @cmd_status: status of HW mode change command 18283 * 18284 * Return: QDF_STATUS_SUCCESS on success or proper error code. 18285 */ 18286 static QDF_STATUS 18287 extract_hw_mode_resp_event_status_tlv(wmi_unified_t wmi_handle, void *evt_buf, 18288 uint32_t *cmd_status) 18289 { 18290 WMI_PDEV_SET_HW_MODE_RESP_EVENTID_param_tlvs *param_buf; 18291 wmi_pdev_set_hw_mode_response_event_fixed_param *fixed_param; 18292 18293 param_buf = (WMI_PDEV_SET_HW_MODE_RESP_EVENTID_param_tlvs *)evt_buf; 18294 if (!param_buf) { 18295 wmi_err("Invalid mode change event buffer"); 18296 return QDF_STATUS_E_INVAL; 18297 } 18298 18299 fixed_param = param_buf->fixed_param; 18300 if (!fixed_param) { 18301 wmi_err("Invalid fixed param"); 18302 return QDF_STATUS_E_INVAL; 18303 } 18304 18305 *cmd_status = fixed_param->status; 18306 return QDF_STATUS_SUCCESS; 18307 } 18308 18309 #ifdef FEATURE_ANI_LEVEL_REQUEST 18310 static QDF_STATUS send_ani_level_cmd_tlv(wmi_unified_t wmi_handle, 18311 uint32_t *freqs, 18312 uint8_t num_freqs) 18313 { 18314 wmi_buf_t buf; 18315 wmi_get_channel_ani_cmd_fixed_param *cmd; 18316 QDF_STATUS ret; 18317 uint32_t len; 18318 A_UINT32 *chan_list; 18319 uint8_t i, *buf_ptr; 18320 18321 len = sizeof(wmi_get_channel_ani_cmd_fixed_param) + 18322 WMI_TLV_HDR_SIZE + 18323 num_freqs * sizeof(A_UINT32); 18324 18325 buf = wmi_buf_alloc(wmi_handle, len); 18326 if (!buf) 18327 return QDF_STATUS_E_FAILURE; 18328 18329 buf_ptr = (uint8_t *)wmi_buf_data(buf); 18330 cmd = (wmi_get_channel_ani_cmd_fixed_param *)buf_ptr; 18331 WMITLV_SET_HDR(&cmd->tlv_header, 18332 WMITLV_TAG_STRUC_wmi_get_channel_ani_cmd_fixed_param, 18333 WMITLV_GET_STRUCT_TLVLEN( 18334 wmi_get_channel_ani_cmd_fixed_param)); 18335 18336 buf_ptr += sizeof(wmi_get_channel_ani_cmd_fixed_param); 18337 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, 18338 (num_freqs * sizeof(A_UINT32))); 18339 18340 chan_list = (A_UINT32 *)(buf_ptr + WMI_TLV_HDR_SIZE); 18341 for (i = 0; i < num_freqs; i++) { 18342 chan_list[i] = freqs[i]; 18343 wmi_debug("Requesting ANI for channel[%d]", chan_list[i]); 18344 } 18345 18346 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 18347 WMI_GET_CHANNEL_ANI_CMDID); 18348 18349 if (QDF_IS_STATUS_ERROR(ret)) { 18350 wmi_err("WMI_GET_CHANNEL_ANI_CMDID send error %d", ret); 18351 wmi_buf_free(buf); 18352 } 18353 18354 return ret; 18355 } 18356 18357 static QDF_STATUS extract_ani_level_tlv(uint8_t *evt_buf, 18358 struct wmi_host_ani_level_event **info, 18359 uint32_t *num_freqs) 18360 { 18361 WMI_GET_CHANNEL_ANI_EVENTID_param_tlvs *param_buf; 18362 wmi_get_channel_ani_event_fixed_param *fixed_param; 18363 wmi_channel_ani_info_tlv_param *tlv_params; 18364 uint8_t *buf_ptr, i; 18365 18366 param_buf = (WMI_GET_CHANNEL_ANI_EVENTID_param_tlvs *)evt_buf; 18367 if (!param_buf) { 18368 wmi_err("Invalid ani level event buffer"); 18369 return QDF_STATUS_E_INVAL; 18370 } 18371 18372 fixed_param = 18373 (wmi_get_channel_ani_event_fixed_param *)param_buf->fixed_param; 18374 if (!fixed_param) { 18375 wmi_err("Invalid fixed param"); 18376 return QDF_STATUS_E_INVAL; 18377 } 18378 18379 buf_ptr = (uint8_t *)fixed_param; 18380 buf_ptr += sizeof(wmi_get_channel_ani_event_fixed_param); 18381 buf_ptr += WMI_TLV_HDR_SIZE; 18382 18383 *num_freqs = param_buf->num_ani_info; 18384 if (*num_freqs > MAX_NUM_FREQS_FOR_ANI_LEVEL) { 18385 wmi_err("Invalid number of freqs received"); 18386 return QDF_STATUS_E_INVAL; 18387 } 18388 18389 *info = qdf_mem_malloc(*num_freqs * 18390 sizeof(struct wmi_host_ani_level_event)); 18391 if (!(*info)) 18392 return QDF_STATUS_E_NOMEM; 18393 18394 tlv_params = (wmi_channel_ani_info_tlv_param *)buf_ptr; 18395 for (i = 0; i < param_buf->num_ani_info; i++) { 18396 (*info)[i].ani_level = tlv_params->ani_level; 18397 (*info)[i].chan_freq = tlv_params->chan_freq; 18398 tlv_params++; 18399 } 18400 18401 return QDF_STATUS_SUCCESS; 18402 } 18403 #endif /* FEATURE_ANI_LEVEL_REQUEST */ 18404 18405 #ifdef WLAN_FEATURE_ROAM_OFFLOAD 18406 /** 18407 * convert_wtc_scan_mode() - Function to convert TLV specific 18408 * ROAM_TRIGGER_SCAN_MODE scan mode to unified Roam trigger scan mode enum 18409 * @scan_mode: scan freq scheme coming from firmware 18410 * 18411 * Return: ROAM_TRIGGER_SCAN_MODE 18412 */ 18413 static enum roam_scan_freq_scheme 18414 convert_wtc_scan_mode(WMI_ROAM_TRIGGER_SCAN_MODE scan_mode) 18415 { 18416 switch (scan_mode) { 18417 case ROAM_TRIGGER_SCAN_MODE_NO_SCAN_DISCONNECTION: 18418 return ROAM_SCAN_FREQ_SCHEME_NO_SCAN; 18419 case ROAM_TRIGGER_SCAN_MODE_PARTIAL: 18420 return ROAM_SCAN_FREQ_SCHEME_PARTIAL_SCAN; 18421 case ROAM_TRIGGER_SCAN_MODE_FULL: 18422 return ROAM_SCAN_FREQ_SCHEME_FULL_SCAN; 18423 default: 18424 return ROAM_SCAN_FREQ_SCHEME_NONE; 18425 } 18426 } 18427 18428 static uint32_t wmi_convert_fw_to_cm_trig_reason(uint32_t fw_trig_reason) 18429 { 18430 switch (fw_trig_reason) { 18431 case WMI_ROAM_TRIGGER_REASON_NONE: 18432 return ROAM_TRIGGER_REASON_NONE; 18433 case WMI_ROAM_TRIGGER_REASON_PER: 18434 return ROAM_TRIGGER_REASON_PER; 18435 case WMI_ROAM_TRIGGER_REASON_BMISS: 18436 return ROAM_TRIGGER_REASON_BMISS; 18437 case WMI_ROAM_TRIGGER_REASON_LOW_RSSI: 18438 return ROAM_TRIGGER_REASON_LOW_RSSI; 18439 case WMI_ROAM_TRIGGER_REASON_HIGH_RSSI: 18440 return ROAM_TRIGGER_REASON_HIGH_RSSI; 18441 case WMI_ROAM_TRIGGER_REASON_PERIODIC: 18442 return ROAM_TRIGGER_REASON_PERIODIC; 18443 case WMI_ROAM_TRIGGER_REASON_MAWC: 18444 return ROAM_TRIGGER_REASON_MAWC; 18445 case WMI_ROAM_TRIGGER_REASON_DENSE: 18446 return ROAM_TRIGGER_REASON_DENSE; 18447 case WMI_ROAM_TRIGGER_REASON_BACKGROUND: 18448 return ROAM_TRIGGER_REASON_BACKGROUND; 18449 case WMI_ROAM_TRIGGER_REASON_FORCED: 18450 return ROAM_TRIGGER_REASON_FORCED; 18451 case WMI_ROAM_TRIGGER_REASON_BTM: 18452 return ROAM_TRIGGER_REASON_BTM; 18453 case WMI_ROAM_TRIGGER_REASON_UNIT_TEST: 18454 return ROAM_TRIGGER_REASON_UNIT_TEST; 18455 case WMI_ROAM_TRIGGER_REASON_BSS_LOAD: 18456 return ROAM_TRIGGER_REASON_BSS_LOAD; 18457 case WMI_ROAM_TRIGGER_REASON_DEAUTH: 18458 return ROAM_TRIGGER_REASON_DEAUTH; 18459 case WMI_ROAM_TRIGGER_REASON_IDLE: 18460 return ROAM_TRIGGER_REASON_IDLE; 18461 case WMI_ROAM_TRIGGER_REASON_STA_KICKOUT: 18462 return ROAM_TRIGGER_REASON_STA_KICKOUT; 18463 case WMI_ROAM_TRIGGER_REASON_ESS_RSSI: 18464 return ROAM_TRIGGER_REASON_ESS_RSSI; 18465 case WMI_ROAM_TRIGGER_REASON_WTC_BTM: 18466 return ROAM_TRIGGER_REASON_WTC_BTM; 18467 case WMI_ROAM_TRIGGER_REASON_PMK_TIMEOUT: 18468 return ROAM_TRIGGER_REASON_PMK_TIMEOUT; 18469 case WMI_ROAM_TRIGGER_REASON_BTC: 18470 return ROAM_TRIGGER_REASON_BTC; 18471 case WMI_ROAM_TRIGGER_EXT_REASON_MAX: 18472 return ROAM_TRIGGER_REASON_MAX; 18473 default: 18474 return ROAM_TRIGGER_REASON_NONE; 18475 } 18476 } 18477 18478 /** 18479 * extract_roam_11kv_candidate_info - Extract btm candidate info 18480 * @wmi_handle: wmi_handle 18481 * @evt_buf: Event buffer 18482 * @dst_info: Destination buffer 18483 * @btm_idx: BTM index 18484 * @num_cand: Number of candidates 18485 * 18486 * Return: QDF_STATUS 18487 */ 18488 static QDF_STATUS 18489 extract_roam_11kv_candidate_info(wmi_unified_t wmi_handle, void *evt_buf, 18490 struct wmi_btm_req_candidate_info *dst_info, 18491 uint8_t btm_idx, uint16_t num_cand) 18492 { 18493 WMI_ROAM_STATS_EVENTID_param_tlvs *param_buf; 18494 wmi_roam_btm_request_candidate_info *src_data; 18495 uint8_t i; 18496 18497 param_buf = (WMI_ROAM_STATS_EVENTID_param_tlvs *)evt_buf; 18498 if (!param_buf || !param_buf->roam_btm_request_candidate_info || 18499 !param_buf->num_roam_btm_request_candidate_info || 18500 (btm_idx + 18501 num_cand) > param_buf->num_roam_btm_request_candidate_info) 18502 return QDF_STATUS_SUCCESS; 18503 18504 src_data = ¶m_buf->roam_btm_request_candidate_info[btm_idx]; 18505 if (num_cand > WLAN_MAX_BTM_CANDIDATE) 18506 num_cand = WLAN_MAX_BTM_CANDIDATE; 18507 for (i = 0; i < num_cand; i++) { 18508 WMI_MAC_ADDR_TO_CHAR_ARRAY(&src_data->btm_candidate_bssid, 18509 dst_info->candidate_bssid.bytes); 18510 dst_info->preference = src_data->preference; 18511 src_data++; 18512 dst_info++; 18513 } 18514 18515 return QDF_STATUS_SUCCESS; 18516 } 18517 18518 static enum roam_trigger_sub_reason 18519 wmi_convert_roam_sub_reason(WMI_ROAM_TRIGGER_SUB_REASON_ID subreason) 18520 { 18521 switch (subreason) { 18522 case WMI_ROAM_TRIGGER_SUB_REASON_PERIODIC_TIMER: 18523 return ROAM_TRIGGER_SUB_REASON_PERIODIC_TIMER; 18524 case WMI_ROAM_TRIGGER_SUB_REASON_INACTIVITY_TIMER: 18525 return ROAM_TRIGGER_SUB_REASON_INACTIVITY_TIMER_LOW_RSSI; 18526 case WMI_ROAM_TRIGGER_SUB_REASON_BTM_DI_TIMER: 18527 return ROAM_TRIGGER_SUB_REASON_BTM_DI_TIMER; 18528 case WMI_ROAM_TRIGGER_SUB_REASON_FULL_SCAN: 18529 return ROAM_TRIGGER_SUB_REASON_FULL_SCAN; 18530 case WMI_ROAM_TRIGGER_SUB_REASON_LOW_RSSI_PERIODIC: 18531 return ROAM_TRIGGER_SUB_REASON_LOW_RSSI_PERIODIC; 18532 case WMI_ROAM_TRIGGER_SUB_REASON_CU_PERIODIC: 18533 return ROAM_TRIGGER_SUB_REASON_CU_PERIODIC; 18534 case WMI_ROAM_TRIGGER_SUB_REASON_PERIODIC_TIMER_AFTER_INACTIVITY: 18535 return ROAM_TRIGGER_SUB_REASON_PERIODIC_TIMER_AFTER_INACTIVITY; 18536 case WMI_ROAM_TRIGGER_SUB_REASON_PERIODIC_TIMER_AFTER_INACTIVITY_CU: 18537 return ROAM_TRIGGER_SUB_REASON_PERIODIC_TIMER_AFTER_INACTIVITY_CU; 18538 case WMI_ROAM_TRIGGER_SUB_REASON_INACTIVITY_TIMER_CU: 18539 return ROAM_TRIGGER_SUB_REASON_INACTIVITY_TIMER_CU; 18540 default: 18541 break; 18542 } 18543 18544 return 0; 18545 } 18546 18547 /** 18548 * extract_roam_trigger_stats_tlv() - Extract the Roam trigger stats 18549 * from the WMI_ROAM_STATS_EVENTID 18550 * @wmi_handle: wmi handle 18551 * @evt_buf: Pointer to the event buffer 18552 * @trig: Pointer to destination structure to fill data 18553 * @idx: TLV id 18554 * @btm_idx: BTM index 18555 */ 18556 static QDF_STATUS 18557 extract_roam_trigger_stats_tlv(wmi_unified_t wmi_handle, void *evt_buf, 18558 struct wmi_roam_trigger_info *trig, uint8_t idx, 18559 uint8_t btm_idx) 18560 { 18561 WMI_ROAM_STATS_EVENTID_param_tlvs *param_buf; 18562 wmi_roam_trigger_reason *src_data = NULL; 18563 uint32_t trig_reason; 18564 18565 param_buf = (WMI_ROAM_STATS_EVENTID_param_tlvs *)evt_buf; 18566 if (!param_buf || !param_buf->roam_trigger_reason) 18567 return QDF_STATUS_E_FAILURE; 18568 18569 src_data = ¶m_buf->roam_trigger_reason[idx]; 18570 18571 trig->present = true; 18572 trig_reason = src_data->trigger_reason; 18573 trig->trigger_reason = wmi_convert_fw_to_cm_trig_reason(trig_reason); 18574 trig->trigger_sub_reason = 18575 wmi_convert_roam_sub_reason(src_data->trigger_sub_reason); 18576 trig->current_rssi = src_data->current_rssi; 18577 trig->timestamp = src_data->timestamp; 18578 18579 switch (trig_reason) { 18580 case WMI_ROAM_TRIGGER_REASON_PER: 18581 case WMI_ROAM_TRIGGER_REASON_BMISS: 18582 case WMI_ROAM_TRIGGER_REASON_HIGH_RSSI: 18583 case WMI_ROAM_TRIGGER_REASON_MAWC: 18584 case WMI_ROAM_TRIGGER_REASON_DENSE: 18585 case WMI_ROAM_TRIGGER_REASON_BACKGROUND: 18586 case WMI_ROAM_TRIGGER_REASON_IDLE: 18587 case WMI_ROAM_TRIGGER_REASON_FORCED: 18588 case WMI_ROAM_TRIGGER_REASON_UNIT_TEST: 18589 case WMI_ROAM_TRIGGER_REASON_BTC: 18590 return QDF_STATUS_SUCCESS; 18591 18592 case WMI_ROAM_TRIGGER_REASON_BTM: 18593 trig->btm_trig_data.btm_request_mode = 18594 src_data->btm_request_mode; 18595 trig->btm_trig_data.disassoc_timer = 18596 src_data->disassoc_imminent_timer; 18597 trig->btm_trig_data.validity_interval = 18598 src_data->validity_internal; 18599 trig->btm_trig_data.candidate_list_count = 18600 src_data->candidate_list_count; 18601 trig->btm_trig_data.btm_resp_status = 18602 src_data->btm_response_status_code; 18603 trig->btm_trig_data.btm_bss_termination_timeout = 18604 src_data->btm_bss_termination_timeout; 18605 trig->btm_trig_data.btm_mbo_assoc_retry_timeout = 18606 src_data->btm_mbo_assoc_retry_timeout; 18607 trig->btm_trig_data.token = src_data->btm_req_dialog_token; 18608 if ((btm_idx + trig->btm_trig_data.candidate_list_count) <= 18609 param_buf->num_roam_btm_request_candidate_info) 18610 extract_roam_11kv_candidate_info( 18611 wmi_handle, evt_buf, 18612 trig->btm_trig_data.btm_cand, 18613 btm_idx, 18614 src_data->candidate_list_count); 18615 18616 return QDF_STATUS_SUCCESS; 18617 18618 case WMI_ROAM_TRIGGER_REASON_BSS_LOAD: 18619 trig->cu_trig_data.cu_load = src_data->cu_load; 18620 return QDF_STATUS_SUCCESS; 18621 18622 case WMI_ROAM_TRIGGER_REASON_DEAUTH: 18623 trig->deauth_trig_data.type = src_data->deauth_type; 18624 trig->deauth_trig_data.reason = src_data->deauth_reason; 18625 return QDF_STATUS_SUCCESS; 18626 18627 case WMI_ROAM_TRIGGER_REASON_PERIODIC: 18628 case WMI_ROAM_TRIGGER_REASON_LOW_RSSI: 18629 trig->rssi_trig_data.threshold = src_data->roam_rssi_threshold; 18630 return QDF_STATUS_SUCCESS; 18631 18632 case WMI_ROAM_TRIGGER_REASON_WTC_BTM: 18633 trig->wtc_btm_trig_data.roaming_mode = 18634 src_data->vendor_specific1[0]; 18635 trig->wtc_btm_trig_data.vsie_trigger_reason = 18636 src_data->vendor_specific1[1]; 18637 trig->wtc_btm_trig_data.sub_code = 18638 src_data->vendor_specific1[2]; 18639 trig->wtc_btm_trig_data.wtc_mode = 18640 src_data->vendor_specific1[3]; 18641 trig->wtc_btm_trig_data.wtc_scan_mode = 18642 convert_wtc_scan_mode(src_data->vendor_specific1[4]); 18643 trig->wtc_btm_trig_data.wtc_rssi_th = 18644 src_data->vendor_specific1[5]; 18645 trig->wtc_btm_trig_data.wtc_candi_rssi_th = 18646 src_data->vendor_specific1[6]; 18647 18648 trig->wtc_btm_trig_data.wtc_candi_rssi_ext_present = 18649 src_data->vendor_specific2[0]; 18650 trig->wtc_btm_trig_data.wtc_candi_rssi_th_5g = 18651 src_data->vendor_specific2[1]; 18652 trig->wtc_btm_trig_data.wtc_candi_rssi_th_6g = 18653 src_data->vendor_specific2[2]; 18654 trig->wtc_btm_trig_data.duration = 18655 src_data->vendor_specific2[3]; 18656 18657 return QDF_STATUS_SUCCESS; 18658 default: 18659 return QDF_STATUS_SUCCESS; 18660 } 18661 18662 return QDF_STATUS_SUCCESS; 18663 } 18664 18665 /** 18666 * extract_roam_scan_ap_stats_tlv() - Extract the Roam trigger stats 18667 * from the WMI_ROAM_STATS_EVENTID 18668 * @wmi_handle: wmi handle 18669 * @evt_buf: Pointer to the event buffer 18670 * @dst: Pointer to destination structure to fill data 18671 * @ap_idx: TLV index for this roam scan 18672 * @num_cand: number of candidates list in the roam scan 18673 */ 18674 static QDF_STATUS 18675 extract_roam_scan_ap_stats_tlv(wmi_unified_t wmi_handle, void *evt_buf, 18676 struct wmi_roam_candidate_info *dst, 18677 uint8_t ap_idx, uint16_t num_cand) 18678 { 18679 WMI_ROAM_STATS_EVENTID_param_tlvs *param_buf; 18680 wmi_roam_ap_info *src = NULL; 18681 uint8_t i; 18682 18683 param_buf = (WMI_ROAM_STATS_EVENTID_param_tlvs *)evt_buf; 18684 if (!param_buf) { 18685 wmi_err("Param buf is NULL"); 18686 return QDF_STATUS_E_FAILURE; 18687 } 18688 18689 if (ap_idx >= param_buf->num_roam_ap_info) { 18690 wmi_err("Invalid roam scan AP tlv ap_idx:%d total_ap:%d", 18691 ap_idx, param_buf->num_roam_ap_info); 18692 return QDF_STATUS_E_FAILURE; 18693 } 18694 18695 src = ¶m_buf->roam_ap_info[ap_idx]; 18696 18697 for (i = 0; i < num_cand; i++) { 18698 WMI_MAC_ADDR_TO_CHAR_ARRAY(&src->bssid, dst->bssid.bytes); 18699 dst->type = src->candidate_type; 18700 dst->freq = src->channel; 18701 dst->etp = src->etp; 18702 dst->rssi = src->rssi; 18703 dst->rssi_score = src->rssi_score; 18704 dst->cu_load = src->cu_load; 18705 dst->cu_score = src->cu_score; 18706 dst->total_score = src->total_score; 18707 dst->timestamp = src->timestamp; 18708 dst->dl_reason = src->bl_reason; 18709 dst->dl_source = src->bl_source; 18710 dst->dl_timestamp = src->bl_timestamp; 18711 dst->dl_original_timeout = src->bl_original_timeout; 18712 18713 src++; 18714 dst++; 18715 } 18716 18717 return QDF_STATUS_SUCCESS; 18718 } 18719 18720 /** 18721 * extract_roam_scan_stats_tlv() - Extract the Roam trigger stats 18722 * from the WMI_ROAM_STATS_EVENTID 18723 * @wmi_handle: wmi handle 18724 * @evt_buf: Pointer to the event buffer 18725 * @dst: Pointer to destination structure to fill data 18726 * @idx: TLV id 18727 * @chan_idx: Index of the channel tlv for the current roam trigger 18728 * @ap_idx: Index of the candidate AP TLV for the current roam trigger 18729 */ 18730 static QDF_STATUS 18731 extract_roam_scan_stats_tlv(wmi_unified_t wmi_handle, void *evt_buf, 18732 struct wmi_roam_scan_data *dst, uint8_t idx, 18733 uint8_t chan_idx, uint8_t ap_idx) 18734 { 18735 WMI_ROAM_STATS_EVENTID_param_tlvs *param_buf; 18736 wmi_roam_scan_info *src_data = NULL; 18737 wmi_roam_scan_channel_info *src_chan = NULL; 18738 QDF_STATUS status; 18739 uint8_t i; 18740 18741 param_buf = (WMI_ROAM_STATS_EVENTID_param_tlvs *)evt_buf; 18742 if (!param_buf || !param_buf->roam_scan_info || 18743 idx >= param_buf->num_roam_scan_info) 18744 return QDF_STATUS_E_FAILURE; 18745 18746 src_data = ¶m_buf->roam_scan_info[idx]; 18747 18748 dst->present = true; 18749 dst->type = src_data->roam_scan_type; 18750 dst->num_chan = src_data->roam_scan_channel_count; 18751 dst->next_rssi_threshold = src_data->next_rssi_trigger_threshold; 18752 dst->is_btcoex_active = WMI_GET_BTCONNECT_STATUS(src_data->flags); 18753 dst->frame_info_count = src_data->frame_info_count; 18754 if (dst->frame_info_count > WLAN_ROAM_MAX_FRAME_INFO) 18755 dst->frame_info_count = WLAN_ROAM_MAX_FRAME_INFO; 18756 18757 /* Read the channel data only for dst->type is 0 (partial scan) */ 18758 if (dst->num_chan && !dst->type && param_buf->num_roam_scan_chan_info && 18759 chan_idx < param_buf->num_roam_scan_chan_info) { 18760 if (dst->num_chan > MAX_ROAM_SCAN_CHAN) 18761 dst->num_chan = MAX_ROAM_SCAN_CHAN; 18762 18763 src_chan = ¶m_buf->roam_scan_chan_info[chan_idx]; 18764 for (i = 0; i < dst->num_chan; i++) { 18765 dst->chan_freq[i] = src_chan->channel; 18766 src_chan++; 18767 } 18768 } 18769 18770 if (!src_data->roam_ap_count || !param_buf->num_roam_ap_info) 18771 return QDF_STATUS_SUCCESS; 18772 18773 dst->num_ap = src_data->roam_ap_count; 18774 if (dst->num_ap > MAX_ROAM_CANDIDATE_AP) 18775 dst->num_ap = MAX_ROAM_CANDIDATE_AP; 18776 18777 status = extract_roam_scan_ap_stats_tlv(wmi_handle, evt_buf, dst->ap, 18778 ap_idx, dst->num_ap); 18779 if (QDF_IS_STATUS_ERROR(status)) { 18780 wmi_err("Extract candidate stats for tlv[%d] failed", idx); 18781 return status; 18782 } 18783 18784 return QDF_STATUS_SUCCESS; 18785 } 18786 18787 /** 18788 * wlan_roam_fail_reason_code() - Convert FW enum to Host enum 18789 * @wmi_roam_fail_reason: roam fail enum 18790 * 18791 * Return: Roaming failure reason codes 18792 */ 18793 static enum wlan_roam_failure_reason_code 18794 wlan_roam_fail_reason_code(uint16_t wmi_roam_fail_reason) 18795 { 18796 switch (wmi_roam_fail_reason) { 18797 case WMI_ROAM_FAIL_REASON_NO_SCAN_START: 18798 return ROAM_FAIL_REASON_NO_SCAN_START; 18799 case WMI_ROAM_FAIL_REASON_NO_AP_FOUND: 18800 return ROAM_FAIL_REASON_NO_AP_FOUND; 18801 case WMI_ROAM_FAIL_REASON_NO_CAND_AP_FOUND: 18802 return ROAM_FAIL_REASON_NO_CAND_AP_FOUND; 18803 case WMI_ROAM_FAIL_REASON_HOST: 18804 return ROAM_FAIL_REASON_HOST; 18805 case WMI_ROAM_FAIL_REASON_AUTH_SEND: 18806 return ROAM_FAIL_REASON_AUTH_SEND; 18807 case WMI_ROAM_FAIL_REASON_AUTH_RECV: 18808 return ROAM_FAIL_REASON_AUTH_RECV; 18809 case WMI_ROAM_FAIL_REASON_NO_AUTH_RESP: 18810 return ROAM_FAIL_REASON_NO_AUTH_RESP; 18811 case WMI_ROAM_FAIL_REASON_REASSOC_SEND: 18812 return ROAM_FAIL_REASON_REASSOC_SEND; 18813 case WMI_ROAM_FAIL_REASON_REASSOC_RECV: 18814 return ROAM_FAIL_REASON_REASSOC_RECV; 18815 case WMI_ROAM_FAIL_REASON_NO_REASSOC_RESP: 18816 return ROAM_FAIL_REASON_NO_REASSOC_RESP; 18817 case WMI_ROAM_FAIL_REASON_EAPOL_TIMEOUT: 18818 return ROAM_FAIL_REASON_EAPOL_TIMEOUT; 18819 case WMI_ROAM_FAIL_REASON_MLME: 18820 return ROAM_FAIL_REASON_MLME; 18821 case WMI_ROAM_FAIL_REASON_INTERNAL_ABORT: 18822 return ROAM_FAIL_REASON_INTERNAL_ABORT; 18823 case WMI_ROAM_FAIL_REASON_SCAN_START: 18824 return ROAM_FAIL_REASON_SCAN_START; 18825 case WMI_ROAM_FAIL_REASON_AUTH_NO_ACK: 18826 return ROAM_FAIL_REASON_AUTH_NO_ACK; 18827 case WMI_ROAM_FAIL_REASON_AUTH_INTERNAL_DROP: 18828 return ROAM_FAIL_REASON_AUTH_INTERNAL_DROP; 18829 case WMI_ROAM_FAIL_REASON_REASSOC_NO_ACK: 18830 return ROAM_FAIL_REASON_REASSOC_NO_ACK; 18831 case WMI_ROAM_FAIL_REASON_REASSOC_INTERNAL_DROP: 18832 return ROAM_FAIL_REASON_REASSOC_INTERNAL_DROP; 18833 case WMI_ROAM_FAIL_REASON_EAPOL_M2_SEND: 18834 return ROAM_FAIL_REASON_EAPOL_M2_SEND; 18835 case WMI_ROAM_FAIL_REASON_EAPOL_M2_INTERNAL_DROP: 18836 return ROAM_FAIL_REASON_EAPOL_M2_INTERNAL_DROP; 18837 case WMI_ROAM_FAIL_REASON_EAPOL_M2_NO_ACK: 18838 return ROAM_FAIL_REASON_EAPOL_M2_NO_ACK; 18839 case WMI_ROAM_FAIL_REASON_EAPOL_M3_TIMEOUT: 18840 return ROAM_FAIL_REASON_EAPOL_M3_TIMEOUT; 18841 case WMI_ROAM_FAIL_REASON_EAPOL_M4_SEND: 18842 return ROAM_FAIL_REASON_EAPOL_M4_SEND; 18843 case WMI_ROAM_FAIL_REASON_EAPOL_M4_INTERNAL_DROP: 18844 return ROAM_FAIL_REASON_EAPOL_M4_INTERNAL_DROP; 18845 case WMI_ROAM_FAIL_REASON_EAPOL_M4_NO_ACK: 18846 return ROAM_FAIL_REASON_EAPOL_M4_NO_ACK; 18847 case WMI_ROAM_FAIL_REASON_NO_SCAN_FOR_FINAL_BMISS: 18848 return ROAM_FAIL_REASON_NO_SCAN_FOR_FINAL_BMISS; 18849 case WMI_ROAM_FAIL_REASON_DISCONNECT: 18850 return ROAM_FAIL_REASON_DISCONNECT; 18851 case WMI_ROAM_FAIL_REASON_SYNC: 18852 return ROAM_FAIL_REASON_SYNC; 18853 case WMI_ROAM_FAIL_REASON_SAE_INVALID_PMKID: 18854 return ROAM_FAIL_REASON_SAE_INVALID_PMKID; 18855 case WMI_ROAM_FAIL_REASON_SAE_PREAUTH_TIMEOUT: 18856 return ROAM_FAIL_REASON_SAE_PREAUTH_TIMEOUT; 18857 case WMI_ROAM_FAIL_REASON_SAE_PREAUTH_FAIL: 18858 return ROAM_FAIL_REASON_SAE_PREAUTH_FAIL; 18859 case WMI_ROAM_FAIL_REASON_UNABLE_TO_START_ROAM_HO: 18860 return ROAM_FAIL_REASON_UNABLE_TO_START_ROAM_HO; 18861 default: 18862 return ROAM_FAIL_REASON_UNKNOWN; 18863 } 18864 } 18865 18866 /** 18867 * extract_roam_result_stats_tlv() - Extract the Roam trigger stats 18868 * from the WMI_ROAM_STATS_EVENTID 18869 * @wmi_handle: wmi handle 18870 * @evt_buf: Pointer to the event buffer 18871 * @dst: Pointer to destination structure to fill data 18872 * @idx: TLV id 18873 */ 18874 static QDF_STATUS 18875 extract_roam_result_stats_tlv(wmi_unified_t wmi_handle, void *evt_buf, 18876 struct wmi_roam_result *dst, uint8_t idx) 18877 { 18878 WMI_ROAM_STATS_EVENTID_param_tlvs *param_buf; 18879 wmi_roam_result *src_data = NULL; 18880 18881 param_buf = (WMI_ROAM_STATS_EVENTID_param_tlvs *)evt_buf; 18882 if (!param_buf || !param_buf->roam_result || 18883 idx >= param_buf->num_roam_result) 18884 return QDF_STATUS_E_FAILURE; 18885 18886 src_data = ¶m_buf->roam_result[idx]; 18887 18888 dst->present = true; 18889 dst->status = src_data->roam_status; 18890 dst->timestamp = src_data->timestamp; 18891 dst->fail_reason = 18892 wlan_roam_fail_reason_code(src_data->roam_fail_reason); 18893 WMI_MAC_ADDR_TO_CHAR_ARRAY(&src_data->bssid, dst->fail_bssid.bytes); 18894 18895 return QDF_STATUS_SUCCESS; 18896 } 18897 18898 /** 18899 * extract_roam_11kv_stats_tlv() - Extract the Roam trigger stats 18900 * from the WMI_ROAM_STATS_EVENTID 18901 * @wmi_handle: wmi handle 18902 * @evt_buf: Pointer to the event buffer 18903 * @dst: Pointer to destination structure to fill data 18904 * @idx: TLV id 18905 * @rpt_idx: Neighbor report Channel index 18906 */ 18907 static QDF_STATUS 18908 extract_roam_11kv_stats_tlv(wmi_unified_t wmi_handle, void *evt_buf, 18909 struct wmi_neighbor_report_data *dst, 18910 uint8_t idx, uint8_t rpt_idx) 18911 { 18912 WMI_ROAM_STATS_EVENTID_param_tlvs *param_buf; 18913 wmi_roam_neighbor_report_info *src_data = NULL; 18914 wmi_roam_neighbor_report_channel_info *src_freq = NULL; 18915 uint8_t i; 18916 18917 param_buf = (WMI_ROAM_STATS_EVENTID_param_tlvs *)evt_buf; 18918 if (!param_buf || !param_buf->roam_neighbor_report_info || 18919 !param_buf->num_roam_neighbor_report_info || 18920 idx >= param_buf->num_roam_neighbor_report_info) { 18921 wmi_debug("Invalid 1kv param buf"); 18922 return QDF_STATUS_E_FAILURE; 18923 } 18924 18925 src_data = ¶m_buf->roam_neighbor_report_info[idx]; 18926 18927 dst->present = true; 18928 dst->req_type = src_data->request_type; 18929 dst->num_freq = src_data->neighbor_report_channel_count; 18930 dst->req_time = src_data->neighbor_report_request_timestamp; 18931 dst->resp_time = src_data->neighbor_report_response_timestamp; 18932 dst->btm_query_token = src_data->btm_query_token; 18933 dst->btm_query_reason = src_data->btm_query_reason_code; 18934 dst->req_token = 18935 WMI_ROAM_NEIGHBOR_REPORT_INFO_REQUEST_TOKEN_GET(src_data->neighbor_report_detail); 18936 dst->resp_token = 18937 WMI_ROAM_NEIGHBOR_REPORT_INFO_RESPONSE_TOKEN_GET(src_data->neighbor_report_detail); 18938 dst->num_rpt = 18939 WMI_ROAM_NEIGHBOR_REPORT_INFO_NUM_OF_NRIE_GET(src_data->neighbor_report_detail); 18940 18941 if (!dst->num_freq || !param_buf->num_roam_neighbor_report_chan_info || 18942 rpt_idx >= param_buf->num_roam_neighbor_report_chan_info) 18943 return QDF_STATUS_SUCCESS; 18944 18945 if (!param_buf->roam_neighbor_report_chan_info) { 18946 wmi_debug("11kv channel present, but TLV is NULL num_freq:%d", 18947 dst->num_freq); 18948 dst->num_freq = 0; 18949 /* return success as its optional tlv and we can print neighbor 18950 * report received info 18951 */ 18952 return QDF_STATUS_SUCCESS; 18953 } 18954 18955 src_freq = ¶m_buf->roam_neighbor_report_chan_info[rpt_idx]; 18956 18957 if (dst->num_freq > MAX_ROAM_SCAN_CHAN) 18958 dst->num_freq = MAX_ROAM_SCAN_CHAN; 18959 18960 for (i = 0; i < dst->num_freq; i++) { 18961 dst->freq[i] = src_freq->channel; 18962 src_freq++; 18963 } 18964 18965 return QDF_STATUS_SUCCESS; 18966 } 18967 18968 /** 18969 * send_roam_set_param_cmd_tlv() - WMI roam set parameter function 18970 * @wmi_handle: handle to WMI. 18971 * @roam_param: pointer to hold roam set parameter 18972 * 18973 * Return: QDF_STATUS_SUCCESS for success or error code 18974 */ 18975 static QDF_STATUS 18976 send_roam_set_param_cmd_tlv(wmi_unified_t wmi_handle, 18977 struct vdev_set_params *roam_param) 18978 { 18979 QDF_STATUS ret; 18980 wmi_roam_set_param_cmd_fixed_param *cmd; 18981 wmi_buf_t buf; 18982 uint16_t len = sizeof(*cmd); 18983 18984 buf = wmi_buf_alloc(wmi_handle, len); 18985 if (!buf) 18986 return QDF_STATUS_E_NOMEM; 18987 18988 cmd = (wmi_roam_set_param_cmd_fixed_param *)wmi_buf_data(buf); 18989 WMITLV_SET_HDR(&cmd->tlv_header, 18990 WMITLV_TAG_STRUC_wmi_roam_set_param_cmd_fixed_param, 18991 WMITLV_GET_STRUCT_TLVLEN 18992 (wmi_roam_set_param_cmd_fixed_param)); 18993 cmd->vdev_id = roam_param->vdev_id; 18994 cmd->param_id = roam_param->param_id; 18995 cmd->param_value = roam_param->param_value; 18996 wmi_debug("Setting vdev %d roam_param = %x, value = %u", 18997 cmd->vdev_id, cmd->param_id, cmd->param_value); 18998 wmi_mtrace(WMI_ROAM_SET_PARAM_CMDID, cmd->vdev_id, 0); 18999 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 19000 WMI_ROAM_SET_PARAM_CMDID); 19001 if (QDF_IS_STATUS_ERROR(ret)) { 19002 wmi_err("Failed to send roam set param command, ret = %d", ret); 19003 wmi_buf_free(buf); 19004 } 19005 19006 return ret; 19007 } 19008 #else 19009 static inline QDF_STATUS 19010 extract_roam_trigger_stats_tlv(wmi_unified_t wmi_handle, void *evt_buf, 19011 struct wmi_roam_trigger_info *trig, uint8_t idx, 19012 uint8_t btm_idx) 19013 { 19014 return QDF_STATUS_E_NOSUPPORT; 19015 } 19016 19017 static inline QDF_STATUS 19018 extract_roam_result_stats_tlv(wmi_unified_t wmi_handle, void *evt_buf, 19019 struct wmi_roam_result *dst, uint8_t idx) 19020 { 19021 return QDF_STATUS_E_NOSUPPORT; 19022 } 19023 19024 static QDF_STATUS 19025 extract_roam_11kv_stats_tlv(wmi_unified_t wmi_handle, void *evt_buf, 19026 struct wmi_neighbor_report_data *dst, 19027 uint8_t idx, uint8_t rpt_idx) 19028 { 19029 return QDF_STATUS_E_NOSUPPORT; 19030 } 19031 19032 static QDF_STATUS 19033 extract_roam_scan_stats_tlv(wmi_unified_t wmi_handle, void *evt_buf, 19034 struct wmi_roam_scan_data *dst, uint8_t idx, 19035 uint8_t chan_idx, uint8_t ap_idx) 19036 { 19037 return QDF_STATUS_E_NOSUPPORT; 19038 } 19039 #endif 19040 19041 #ifdef WLAN_FEATURE_PKT_CAPTURE 19042 static QDF_STATUS 19043 extract_vdev_mgmt_offload_event_tlv(void *handle, void *evt_buf, 19044 struct mgmt_offload_event_params *params) 19045 { 19046 WMI_VDEV_MGMT_OFFLOAD_EVENTID_param_tlvs *param_tlvs; 19047 wmi_mgmt_hdr *hdr; 19048 19049 param_tlvs = (WMI_VDEV_MGMT_OFFLOAD_EVENTID_param_tlvs *)evt_buf; 19050 if (!param_tlvs) 19051 return QDF_STATUS_E_INVAL; 19052 19053 hdr = param_tlvs->fixed_param; 19054 if (!hdr) 19055 return QDF_STATUS_E_INVAL; 19056 19057 if (hdr->buf_len > param_tlvs->num_bufp) 19058 return QDF_STATUS_E_INVAL; 19059 19060 params->tsf_l32 = hdr->tsf_l32; 19061 params->chan_freq = hdr->chan_freq; 19062 params->rate_kbps = hdr->rate_kbps; 19063 params->rssi = hdr->rssi; 19064 params->buf_len = hdr->buf_len; 19065 params->tx_status = hdr->tx_status; 19066 params->buf = param_tlvs->bufp; 19067 params->tx_retry_cnt = hdr->tx_retry_cnt; 19068 return QDF_STATUS_SUCCESS; 19069 } 19070 #endif /* WLAN_FEATURE_PKT_CAPTURE */ 19071 19072 #ifdef WLAN_FEATURE_PKT_CAPTURE_V2 19073 static QDF_STATUS 19074 extract_smart_monitor_event_tlv(void *handle, void *evt_buf, 19075 struct smu_event_params *params) 19076 { 19077 WMI_VDEV_SMART_MONITOR_EVENTID_param_tlvs *param_buf = NULL; 19078 wmi_vdev_smart_monitor_event_fixed_param *smu_event = NULL; 19079 19080 param_buf = (WMI_VDEV_SMART_MONITOR_EVENTID_param_tlvs *)evt_buf; 19081 if (!param_buf) { 19082 wmi_err("Invalid smart monitor event"); 19083 return QDF_STATUS_E_INVAL; 19084 } 19085 19086 smu_event = param_buf->fixed_param; 19087 if (!smu_event) { 19088 wmi_err("smart monitor event fixed param is NULL"); 19089 return QDF_STATUS_E_INVAL; 19090 } 19091 19092 params->vdev_id = smu_event->vdev_id; 19093 if (params->vdev_id >= WLAN_UMAC_PDEV_MAX_VDEVS) 19094 return QDF_STATUS_E_INVAL; 19095 19096 params->rx_avg_rssi = smu_event->avg_rssi_data_dbm; 19097 19098 return QDF_STATUS_SUCCESS; 19099 } 19100 #endif /* WLAN_FEATURE_PKT_CAPTURE_V2 */ 19101 19102 #ifdef FEATURE_WLAN_TIME_SYNC_FTM 19103 /** 19104 * send_wlan_ts_ftm_trigger_cmd_tlv(): send wlan time sync cmd to FW 19105 * 19106 * @wmi: wmi handle 19107 * @vdev_id: vdev id 19108 * @burst_mode: Indicates whether relation derived using FTM is needed for 19109 * each FTM frame or only aggregated result is required. 19110 * 19111 * Send WMI_AUDIO_SYNC_TRIGGER_CMDID to FW. 19112 * 19113 * Return: QDF_STATUS 19114 */ 19115 static QDF_STATUS send_wlan_ts_ftm_trigger_cmd_tlv(wmi_unified_t wmi, 19116 uint32_t vdev_id, 19117 bool burst_mode) 19118 { 19119 wmi_audio_sync_trigger_cmd_fixed_param *cmd; 19120 wmi_buf_t buf; 19121 int32_t len = sizeof(*cmd); 19122 19123 buf = wmi_buf_alloc(wmi, len); 19124 if (!buf) { 19125 wmi_err("wmi_buf_alloc failed"); 19126 return QDF_STATUS_E_NOMEM; 19127 } 19128 cmd = (wmi_audio_sync_trigger_cmd_fixed_param *)wmi_buf_data(buf); 19129 WMITLV_SET_HDR(&cmd->tlv_header, 19130 WMITLV_TAG_STRUC_wmi_audio_sync_trigger_cmd_fixed_param, 19131 WMITLV_GET_STRUCT_TLVLEN(wmi_audio_sync_trigger_cmd_fixed_param)); 19132 cmd->vdev_id = vdev_id; 19133 cmd->agg_relation = burst_mode ? false : true; 19134 if (wmi_unified_cmd_send(wmi, buf, len, WMI_VDEV_AUDIO_SYNC_TRIGGER_CMDID)) { 19135 wmi_err("Failed to send audio sync trigger cmd"); 19136 wmi_buf_free(buf); 19137 return QDF_STATUS_E_FAILURE; 19138 } 19139 19140 return QDF_STATUS_SUCCESS; 19141 } 19142 19143 static QDF_STATUS send_wlan_ts_qtime_cmd_tlv(wmi_unified_t wmi, 19144 uint32_t vdev_id, 19145 uint64_t lpass_ts) 19146 { 19147 wmi_audio_sync_qtimer_cmd_fixed_param *cmd; 19148 wmi_buf_t buf; 19149 int32_t len = sizeof(*cmd); 19150 19151 buf = wmi_buf_alloc(wmi, len); 19152 if (!buf) { 19153 wmi_err("wmi_buf_alloc failed"); 19154 return QDF_STATUS_E_NOMEM; 19155 } 19156 cmd = (wmi_audio_sync_qtimer_cmd_fixed_param *)wmi_buf_data(buf); 19157 WMITLV_SET_HDR(&cmd->tlv_header, 19158 WMITLV_TAG_STRUC_wmi_audio_sync_qtimer_cmd_fixed_param, 19159 WMITLV_GET_STRUCT_TLVLEN(wmi_audio_sync_qtimer_cmd_fixed_param)); 19160 cmd->vdev_id = vdev_id; 19161 cmd->qtimer_u32 = (uint32_t)((lpass_ts & 0xffffffff00000000LL) >> 32); 19162 cmd->qtimer_l32 = (uint32_t)(lpass_ts & 0xffffffffLL); 19163 19164 if (wmi_unified_cmd_send(wmi, buf, len, WMI_VDEV_AUDIO_SYNC_QTIMER_CMDID)) { 19165 wmi_err("Failed to send audio qtime command"); 19166 wmi_buf_free(buf); 19167 return QDF_STATUS_E_FAILURE; 19168 } 19169 19170 return QDF_STATUS_SUCCESS; 19171 } 19172 19173 static QDF_STATUS extract_time_sync_ftm_start_stop_event_tlv( 19174 wmi_unified_t wmi, void *buf, 19175 struct ftm_time_sync_start_stop_params *param) 19176 { 19177 WMI_VDEV_AUDIO_SYNC_START_STOP_EVENTID_param_tlvs *param_buf; 19178 wmi_audio_sync_start_stop_event_fixed_param *resp_event; 19179 19180 param_buf = (WMI_VDEV_AUDIO_SYNC_START_STOP_EVENTID_param_tlvs *)buf; 19181 if (!param_buf) { 19182 wmi_err("Invalid audio sync start stop event buffer"); 19183 return QDF_STATUS_E_FAILURE; 19184 } 19185 19186 resp_event = param_buf->fixed_param; 19187 if (!resp_event) { 19188 wmi_err("Invalid audio sync start stop fixed param buffer"); 19189 return QDF_STATUS_E_FAILURE; 19190 } 19191 19192 param->vdev_id = resp_event->vdev_id; 19193 param->timer_interval = resp_event->periodicity; 19194 param->num_reads = resp_event->reads_needed; 19195 param->qtime = ((uint64_t)resp_event->qtimer_u32 << 32) | 19196 resp_event->qtimer_l32; 19197 param->mac_time = ((uint64_t)resp_event->mac_timer_u32 << 32) | 19198 resp_event->mac_timer_l32; 19199 19200 wmi_debug("FTM time sync time_interval %d, num_reads %d", 19201 param->timer_interval, param->num_reads); 19202 19203 return QDF_STATUS_SUCCESS; 19204 } 19205 19206 static QDF_STATUS 19207 extract_time_sync_ftm_offset_event_tlv(wmi_unified_t wmi, void *buf, 19208 struct ftm_time_sync_offset *param) 19209 { 19210 WMI_VDEV_AUDIO_SYNC_Q_MASTER_SLAVE_OFFSET_EVENTID_param_tlvs *param_buf; 19211 wmi_audio_sync_q_master_slave_offset_event_fixed_param *resp_event; 19212 wmi_audio_sync_q_master_slave_times *q_pair; 19213 int iter; 19214 19215 param_buf = 19216 (WMI_VDEV_AUDIO_SYNC_Q_MASTER_SLAVE_OFFSET_EVENTID_param_tlvs *)buf; 19217 if (!param_buf) { 19218 wmi_err("Invalid timesync ftm offset event buffer"); 19219 return QDF_STATUS_E_FAILURE; 19220 } 19221 19222 resp_event = param_buf->fixed_param; 19223 if (!resp_event) { 19224 wmi_err("Invalid timesync ftm offset fixed param buffer"); 19225 return QDF_STATUS_E_FAILURE; 19226 } 19227 19228 param->vdev_id = resp_event->vdev_id; 19229 param->num_qtime = param_buf->num_audio_sync_q_master_slave_times; 19230 if (param->num_qtime > FTM_TIME_SYNC_QTIME_PAIR_MAX) 19231 param->num_qtime = FTM_TIME_SYNC_QTIME_PAIR_MAX; 19232 19233 q_pair = param_buf->audio_sync_q_master_slave_times; 19234 if (!q_pair) { 19235 wmi_err("Invalid q_master_slave_times buffer"); 19236 return QDF_STATUS_E_FAILURE; 19237 } 19238 19239 for (iter = 0; iter < param->num_qtime; iter++) { 19240 param->pairs[iter].qtime_initiator = ( 19241 (uint64_t)q_pair[iter].qmaster_u32 << 32) | 19242 q_pair[iter].qmaster_l32; 19243 param->pairs[iter].qtime_target = ( 19244 (uint64_t)q_pair[iter].qslave_u32 << 32) | 19245 q_pair[iter].qslave_l32; 19246 } 19247 return QDF_STATUS_SUCCESS; 19248 } 19249 #endif /* FEATURE_WLAN_TIME_SYNC_FTM */ 19250 19251 /** 19252 * send_vdev_tsf_tstamp_action_cmd_tlv() - send vdev tsf action command 19253 * @wmi: wmi handle 19254 * @vdev_id: vdev id 19255 * 19256 * TSF_TSTAMP_READ_VALUE is the only operation supported 19257 * Return: QDF_STATUS_SUCCESS for success or error code 19258 */ 19259 static QDF_STATUS 19260 send_vdev_tsf_tstamp_action_cmd_tlv(wmi_unified_t wmi, uint8_t vdev_id) 19261 { 19262 wmi_vdev_tsf_tstamp_action_cmd_fixed_param *cmd; 19263 wmi_buf_t buf; 19264 int32_t len = sizeof(*cmd); 19265 19266 buf = wmi_buf_alloc(wmi, len); 19267 if (!buf) 19268 return QDF_STATUS_E_NOMEM; 19269 19270 cmd = (wmi_vdev_tsf_tstamp_action_cmd_fixed_param *)wmi_buf_data(buf); 19271 WMITLV_SET_HDR(&cmd->tlv_header, 19272 WMITLV_TAG_STRUC_wmi_vdev_tsf_tstamp_action_cmd_fixed_param, 19273 WMITLV_GET_STRUCT_TLVLEN(wmi_vdev_tsf_tstamp_action_cmd_fixed_param)); 19274 cmd->vdev_id = vdev_id; 19275 cmd->tsf_action = TSF_TSTAMP_QTIMER_CAPTURE_REQ; 19276 wmi_mtrace(WMI_VDEV_TSF_TSTAMP_ACTION_CMDID, cmd->vdev_id, 0); 19277 if (wmi_unified_cmd_send(wmi, buf, len, 19278 WMI_VDEV_TSF_TSTAMP_ACTION_CMDID)) { 19279 wmi_err("%s: Failed to send WMI_VDEV_TSF_TSTAMP_ACTION_CMDID", 19280 __func__); 19281 wmi_buf_free(buf); 19282 return QDF_STATUS_E_FAILURE; 19283 } 19284 19285 return QDF_STATUS_SUCCESS; 19286 } 19287 19288 /** 19289 * extract_vdev_tsf_report_event_tlv() - extract vdev tsf report from event 19290 * @wmi_handle: wmi handle 19291 * @evt_buf: pointer to event buffer 19292 * @param: Pointer to struct to hold event info 19293 * 19294 * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure 19295 */ 19296 static QDF_STATUS 19297 extract_vdev_tsf_report_event_tlv(wmi_unified_t wmi_handle, void *evt_buf, 19298 struct wmi_host_tsf_event *param) 19299 { 19300 WMI_VDEV_TSF_REPORT_EVENTID_param_tlvs *param_buf; 19301 wmi_vdev_tsf_report_event_fixed_param *evt; 19302 19303 param_buf = (WMI_VDEV_TSF_REPORT_EVENTID_param_tlvs *)evt_buf; 19304 if (!param_buf) { 19305 wmi_err("Invalid tsf report event buffer"); 19306 return QDF_STATUS_E_INVAL; 19307 } 19308 19309 evt = param_buf->fixed_param; 19310 param->vdev_id = evt->vdev_id; 19311 param->tsf = ((uint64_t)(evt->tsf_high) << 32) | evt->tsf_low; 19312 param->tsf_low = evt->tsf_low; 19313 param->tsf_high = evt->tsf_high; 19314 param->qtimer_low = evt->qtimer_low; 19315 param->qtimer_high = evt->qtimer_high; 19316 param->tsf_id = evt->tsf_id; 19317 param->tsf_id_valid = evt->tsf_id_valid; 19318 param->mac_id = evt->mac_id; 19319 param->mac_id_valid = evt->mac_id_valid; 19320 param->wlan_global_tsf_low = evt->wlan_global_tsf_low; 19321 param->wlan_global_tsf_high = evt->wlan_global_tsf_high; 19322 param->tqm_timer_low = evt->tqm_timer_low; 19323 param->tqm_timer_high = evt->tqm_timer_high; 19324 param->use_tqm_timer = evt->use_tqm_timer; 19325 19326 return QDF_STATUS_SUCCESS; 19327 } 19328 19329 /** 19330 * extract_pdev_csa_switch_count_status_tlv() - extract pdev csa switch count 19331 * status tlv 19332 * @wmi_handle: wmi handle 19333 * @evt_buf: pointer to event buffer 19334 * @param: Pointer to hold csa switch count status event param 19335 * 19336 * Return: QDF_STATUS_SUCCESS for success or error code 19337 */ 19338 static QDF_STATUS extract_pdev_csa_switch_count_status_tlv( 19339 wmi_unified_t wmi_handle, 19340 void *evt_buf, 19341 struct pdev_csa_switch_count_status *param) 19342 { 19343 WMI_PDEV_CSA_SWITCH_COUNT_STATUS_EVENTID_param_tlvs *param_buf; 19344 wmi_pdev_csa_switch_count_status_event_fixed_param *csa_status; 19345 19346 param_buf = (WMI_PDEV_CSA_SWITCH_COUNT_STATUS_EVENTID_param_tlvs *) 19347 evt_buf; 19348 if (!param_buf) { 19349 wmi_err("Invalid CSA status event"); 19350 return QDF_STATUS_E_INVAL; 19351 } 19352 19353 csa_status = param_buf->fixed_param; 19354 19355 param->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host( 19356 wmi_handle, 19357 csa_status->pdev_id); 19358 param->current_switch_count = csa_status->current_switch_count; 19359 param->num_vdevs = csa_status->num_vdevs; 19360 param->vdev_ids = param_buf->vdev_ids; 19361 19362 return QDF_STATUS_SUCCESS; 19363 } 19364 19365 #ifdef CONFIG_AFC_SUPPORT 19366 /** 19367 * send_afc_cmd_tlv() - Sends the AFC indication to FW 19368 * @wmi_handle: wmi handle 19369 * @pdev_id: Pdev id 19370 * @param: Pointer to hold AFC indication. 19371 * 19372 * Return: QDF_STATUS_SUCCESS for success or error code 19373 */ 19374 static 19375 QDF_STATUS send_afc_cmd_tlv(wmi_unified_t wmi_handle, 19376 uint8_t pdev_id, 19377 struct reg_afc_resp_rx_ind_info *param) 19378 { 19379 wmi_buf_t buf; 19380 wmi_afc_cmd_fixed_param *cmd; 19381 uint32_t len; 19382 uint8_t *buf_ptr; 19383 QDF_STATUS ret; 19384 19385 len = sizeof(wmi_afc_cmd_fixed_param); 19386 buf = wmi_buf_alloc(wmi_handle, len); 19387 if (!buf) 19388 return QDF_STATUS_E_NOMEM; 19389 19390 buf_ptr = (uint8_t *)wmi_buf_data(buf); 19391 cmd = (wmi_afc_cmd_fixed_param *)buf_ptr; 19392 19393 WMITLV_SET_HDR(&cmd->tlv_header, 19394 WMITLV_TAG_STRUC_wmi_afc_cmd_fixed_param, 19395 WMITLV_GET_STRUCT_TLVLEN(wmi_afc_cmd_fixed_param)); 19396 19397 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 19398 wmi_handle, 19399 pdev_id); 19400 cmd->cmd_type = param->cmd_type; 19401 cmd->serv_resp_format = param->serv_resp_format; 19402 19403 wmi_mtrace(WMI_AFC_CMDID, NO_SESSION, 0); 19404 ret = wmi_unified_cmd_send(wmi_handle, buf, len, WMI_AFC_CMDID); 19405 if (QDF_IS_STATUS_ERROR(ret)) { 19406 wmi_err("Failed to send WMI_AFC_CMDID"); 19407 wmi_buf_free(buf); 19408 return QDF_STATUS_E_FAILURE; 19409 } 19410 19411 return QDF_STATUS_SUCCESS; 19412 } 19413 #endif 19414 19415 /** 19416 * send_set_tpc_power_cmd_tlv() - Sends the set TPC power level to FW 19417 * @wmi_handle: wmi handle 19418 * @vdev_id: vdev id 19419 * @param: Pointer to hold TX power info 19420 * 19421 * Return: QDF_STATUS_SUCCESS for success or error code 19422 */ 19423 static QDF_STATUS send_set_tpc_power_cmd_tlv(wmi_unified_t wmi_handle, 19424 uint8_t vdev_id, 19425 struct reg_tpc_power_info *param) 19426 { 19427 wmi_buf_t buf; 19428 wmi_vdev_set_tpc_power_fixed_param *tpc_power_info_param; 19429 wmi_vdev_ch_power_info *ch_power_info; 19430 uint8_t *buf_ptr; 19431 uint16_t idx; 19432 uint32_t len; 19433 QDF_STATUS ret; 19434 19435 len = sizeof(wmi_vdev_set_tpc_power_fixed_param) + WMI_TLV_HDR_SIZE; 19436 len += (sizeof(wmi_vdev_ch_power_info) * param->num_pwr_levels); 19437 19438 buf = wmi_buf_alloc(wmi_handle, len); 19439 if (!buf) 19440 return QDF_STATUS_E_NOMEM; 19441 19442 buf_ptr = (uint8_t *)wmi_buf_data(buf); 19443 tpc_power_info_param = (wmi_vdev_set_tpc_power_fixed_param *)buf_ptr; 19444 19445 WMITLV_SET_HDR(&tpc_power_info_param->tlv_header, 19446 WMITLV_TAG_STRUC_wmi_vdev_set_tpc_power_cmd_fixed_param, 19447 WMITLV_GET_STRUCT_TLVLEN(wmi_vdev_set_tpc_power_fixed_param)); 19448 19449 tpc_power_info_param->vdev_id = vdev_id; 19450 tpc_power_info_param->psd_power = param->is_psd_power; 19451 tpc_power_info_param->eirp_power = param->eirp_power; 19452 tpc_power_info_param->power_type_6ghz = param->power_type_6g; 19453 wmi_debug("eirp_power = %d is_psd_power = %d", 19454 tpc_power_info_param->eirp_power, 19455 tpc_power_info_param->psd_power); 19456 reg_print_ap_power_type_6ghz(tpc_power_info_param->power_type_6ghz); 19457 19458 buf_ptr += sizeof(wmi_vdev_set_tpc_power_fixed_param); 19459 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 19460 param->num_pwr_levels * sizeof(wmi_vdev_ch_power_info)); 19461 19462 buf_ptr += WMI_TLV_HDR_SIZE; 19463 ch_power_info = (wmi_vdev_ch_power_info *)buf_ptr; 19464 19465 for (idx = 0; idx < param->num_pwr_levels; ++idx) { 19466 WMITLV_SET_HDR(&ch_power_info[idx].tlv_header, 19467 WMITLV_TAG_STRUC_wmi_vdev_ch_power_info, 19468 WMITLV_GET_STRUCT_TLVLEN(wmi_vdev_ch_power_info)); 19469 ch_power_info[idx].chan_cfreq = 19470 param->chan_power_info[idx].chan_cfreq; 19471 ch_power_info[idx].tx_power = 19472 param->chan_power_info[idx].tx_power; 19473 wmi_debug("chan_cfreq = %d tx_power = %d", 19474 ch_power_info[idx].chan_cfreq, 19475 ch_power_info[idx].tx_power); 19476 buf_ptr += sizeof(wmi_vdev_ch_power_info); 19477 } 19478 19479 wmi_mtrace(WMI_VDEV_SET_TPC_POWER_CMDID, vdev_id, 0); 19480 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 19481 WMI_VDEV_SET_TPC_POWER_CMDID); 19482 if (QDF_IS_STATUS_ERROR(ret)) 19483 wmi_buf_free(buf); 19484 19485 19486 return ret; 19487 } 19488 19489 /** 19490 * extract_dpd_status_ev_param_tlv() - extract dpd status from FW event 19491 * @wmi_handle: wmi handle 19492 * @evt_buf: event buffer 19493 * @param: dpd status info 19494 * 19495 * Return: QDF_STATUS_SUCCESS for success or error code 19496 */ 19497 static QDF_STATUS 19498 extract_dpd_status_ev_param_tlv(wmi_unified_t wmi_handle, 19499 void *evt_buf, 19500 struct wmi_host_pdev_get_dpd_status_event *param) 19501 { 19502 WMI_PDEV_GET_DPD_STATUS_EVENTID_param_tlvs *param_buf; 19503 wmi_pdev_get_dpd_status_evt_fixed_param *dpd_status; 19504 19505 param_buf = (WMI_PDEV_GET_DPD_STATUS_EVENTID_param_tlvs *)evt_buf; 19506 if (!param_buf) { 19507 wmi_err("Invalid get dpd_status event"); 19508 return QDF_STATUS_E_INVAL; 19509 } 19510 19511 dpd_status = param_buf->fixed_param; 19512 param->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host 19513 (wmi_handle, dpd_status->pdev_id); 19514 param->dpd_status = dpd_status->dpd_status; 19515 19516 return QDF_STATUS_SUCCESS; 19517 } 19518 19519 static int 19520 convert_halphy_status(wmi_pdev_get_halphy_cal_status_evt_fixed_param *status, 19521 WMI_HALPHY_CAL_VALID_BITMAP_STATUS valid_bit) 19522 { 19523 if (status->halphy_cal_valid_bmap && valid_bit) 19524 return (status->halphy_cal_status && valid_bit); 19525 19526 return 0; 19527 } 19528 19529 static QDF_STATUS 19530 extract_halphy_cal_status_ev_param_tlv(wmi_unified_t wmi_handle, 19531 void *evt_buf, 19532 struct wmi_host_pdev_get_halphy_cal_status_event *param) 19533 { 19534 WMI_PDEV_GET_HALPHY_CAL_STATUS_EVENTID_param_tlvs *param_buf; 19535 wmi_pdev_get_halphy_cal_status_evt_fixed_param *halphy_cal_status; 19536 19537 param_buf = (WMI_PDEV_GET_HALPHY_CAL_STATUS_EVENTID_param_tlvs *)evt_buf; 19538 if (!param_buf) { 19539 wmi_err("Invalid get halphy cal status event"); 19540 return QDF_STATUS_E_INVAL; 19541 } 19542 19543 halphy_cal_status = param_buf->fixed_param; 19544 param->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host 19545 (wmi_handle, halphy_cal_status->pdev_id); 19546 param->halphy_cal_adc_status = 19547 convert_halphy_status(halphy_cal_status, 19548 WMI_HALPHY_CAL_ADC_BMAP); 19549 param->halphy_cal_bwfilter_status = 19550 convert_halphy_status(halphy_cal_status, 19551 WMI_HALPHY_CAL_BWFILTER_BMAP); 19552 param->halphy_cal_pdet_and_pal_status = 19553 convert_halphy_status(halphy_cal_status, 19554 WMI_HALPHY_CAL_PDET_AND_PAL_BMAP); 19555 param->halphy_cal_rxdco_status = 19556 convert_halphy_status(halphy_cal_status, 19557 WMI_HALPHY_CAL_RXDCO_BMAP); 19558 param->halphy_cal_comb_txiq_rxiq_status = 19559 convert_halphy_status(halphy_cal_status, 19560 WMI_HALPHY_CAL_COMB_TXLO_TXIQ_RXIQ_BMAP); 19561 param->halphy_cal_ibf_status = 19562 convert_halphy_status(halphy_cal_status, 19563 WMI_HALPHY_CAL_IBF_BMAP); 19564 param->halphy_cal_pa_droop_status = 19565 convert_halphy_status(halphy_cal_status, 19566 WMI_HALPHY_CAL_PA_DROOP_BMAP); 19567 param->halphy_cal_dac_status = 19568 convert_halphy_status(halphy_cal_status, 19569 WMI_HALPHY_CAL_DAC_BMAP); 19570 param->halphy_cal_ani_status = 19571 convert_halphy_status(halphy_cal_status, 19572 WMI_HALPHY_CAL_ANI_BMAP); 19573 param->halphy_cal_noise_floor_status = 19574 convert_halphy_status(halphy_cal_status, 19575 WMI_HALPHY_CAL_NOISE_FLOOR_BMAP); 19576 19577 return QDF_STATUS_SUCCESS; 19578 } 19579 19580 /** 19581 * set_halphy_cal_fw_status_to_host_status() - Convert set halphy cal status to host enum 19582 * @fw_status: set halphy cal status from WMI_PDEV_SET_HALPHY_CAL_BMAP_EVENTID event 19583 * 19584 * Return: host_set_halphy_cal_status 19585 */ 19586 static enum wmi_host_set_halphy_cal_status 19587 set_halphy_cal_fw_status_to_host_status(uint32_t fw_status) 19588 { 19589 if (fw_status == 0) 19590 return WMI_HOST_SET_HALPHY_CAL_STATUS_SUCCESS; 19591 else if (fw_status == 1) 19592 return WMI_HOST_SET_HALPHY_CAL_STATUS_FAIL; 19593 19594 wmi_debug("Unknown set halphy status code(%u) from WMI", fw_status); 19595 return WMI_HOST_SET_HALPHY_CAL_STATUS_FAIL; 19596 } 19597 19598 /** 19599 * extract_halphy_cal_ev_param_tlv() - extract dpd status from FW event 19600 * @wmi_handle: wmi handle 19601 * @evt_buf: event buffer 19602 * @param: set halphy cal status info 19603 * 19604 * Return: QDF_STATUS_SUCCESS for success or error code 19605 */ 19606 static QDF_STATUS 19607 extract_halphy_cal_ev_param_tlv(wmi_unified_t wmi_handle, 19608 void *evt_buf, 19609 struct wmi_host_pdev_set_halphy_cal_event *param) 19610 { 19611 WMI_PDEV_SET_HALPHY_CAL_BMAP_EVENTID_param_tlvs *param_buf; 19612 wmi_pdev_set_halphy_cal_bmap_evt_fixed_param *set_halphy_status; 19613 19614 param_buf = (WMI_PDEV_SET_HALPHY_CAL_BMAP_EVENTID_param_tlvs *)evt_buf; 19615 if (!param_buf) { 19616 wmi_err("Invalid set halphy_status event"); 19617 return QDF_STATUS_E_INVAL; 19618 } 19619 19620 set_halphy_status = param_buf->fixed_param; 19621 param->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host 19622 (wmi_handle, set_halphy_status->pdev_id); 19623 param->status = set_halphy_cal_fw_status_to_host_status(set_halphy_status->status); 19624 19625 return QDF_STATUS_SUCCESS; 19626 } 19627 19628 /** 19629 * extract_install_key_comp_event_tlv() - extract install key complete event tlv 19630 * @wmi_handle: wmi handle 19631 * @evt_buf: pointer to event buffer 19632 * @len: length of the event buffer 19633 * @param: Pointer to hold install key complete event param 19634 * 19635 * Return: QDF_STATUS_SUCCESS for success or error code 19636 */ 19637 static QDF_STATUS 19638 extract_install_key_comp_event_tlv(wmi_unified_t wmi_handle, 19639 void *evt_buf, uint32_t len, 19640 struct wmi_install_key_comp_event *param) 19641 { 19642 WMI_VDEV_INSTALL_KEY_COMPLETE_EVENTID_param_tlvs *param_buf; 19643 wmi_vdev_install_key_complete_event_fixed_param *key_fp; 19644 19645 if (len < sizeof(*param_buf)) { 19646 wmi_err("invalid event buf len %d", len); 19647 return QDF_STATUS_E_INVAL; 19648 } 19649 19650 param_buf = (WMI_VDEV_INSTALL_KEY_COMPLETE_EVENTID_param_tlvs *)evt_buf; 19651 if (!param_buf) { 19652 wmi_err("received null buf from target"); 19653 return QDF_STATUS_E_INVAL; 19654 } 19655 19656 key_fp = param_buf->fixed_param; 19657 if (!key_fp) { 19658 wmi_err("received null event data from target"); 19659 return QDF_STATUS_E_INVAL; 19660 } 19661 19662 param->vdev_id = key_fp->vdev_id; 19663 param->key_ix = key_fp->key_ix; 19664 param->key_flags = key_fp->key_flags; 19665 param->status = key_fp->status; 19666 WMI_MAC_ADDR_TO_CHAR_ARRAY(&key_fp->peer_macaddr, 19667 param->peer_macaddr); 19668 19669 return QDF_STATUS_SUCCESS; 19670 } 19671 19672 static QDF_STATUS 19673 send_set_halphy_cal_tlv(wmi_unified_t wmi_handle, 19674 struct wmi_host_send_set_halphy_cal_info *param) 19675 { 19676 wmi_buf_t buf; 19677 wmi_pdev_set_halphy_cal_bmap_cmd_fixed_param *cmd; 19678 QDF_STATUS ret; 19679 uint32_t len; 19680 19681 len = sizeof(*cmd); 19682 19683 buf = wmi_buf_alloc(wmi_handle, len); 19684 if (!buf) 19685 return QDF_STATUS_E_FAILURE; 19686 19687 cmd = (void *)wmi_buf_data(buf); 19688 19689 WMITLV_SET_HDR(&cmd->tlv_header, 19690 WMITLV_TAG_STRUC_wmi_pdev_set_halphy_cal_bmap_cmd_fixed_param, 19691 WMITLV_GET_STRUCT_TLVLEN(wmi_pdev_set_halphy_cal_bmap_cmd_fixed_param)); 19692 19693 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target(wmi_handle, 19694 param->pdev_id); 19695 cmd->online_halphy_cals_bmap = param->value; 19696 cmd->home_scan_channel = param->chan_sel; 19697 19698 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 19699 WMI_PDEV_SET_HALPHY_CAL_BMAP_CMDID); 19700 if (QDF_IS_STATUS_ERROR(ret)) { 19701 wmi_err("WMI_PDEV_SET_HALPHY_CAL_BMAP_CMDID send returned Error %d",ret); 19702 wmi_buf_free(buf); 19703 } 19704 19705 return ret; 19706 } 19707 19708 #ifdef WLAN_FEATURE_DYNAMIC_MAC_ADDR_UPDATE 19709 /** 19710 * send_set_mac_address_cmd_tlv() - send set MAC address command to fw 19711 * @wmi: wmi handle 19712 * @params: set MAC address command params 19713 * 19714 * Return: QDF_STATUS_SUCCESS for success or error code 19715 */ 19716 static QDF_STATUS 19717 send_set_mac_address_cmd_tlv(wmi_unified_t wmi, 19718 struct set_mac_addr_params *params) 19719 { 19720 wmi_vdev_update_mac_addr_cmd_fixed_param *cmd; 19721 wmi_buf_t buf; 19722 int32_t len = sizeof(*cmd); 19723 19724 buf = wmi_buf_alloc(wmi, len); 19725 if (!buf) 19726 return QDF_STATUS_E_NOMEM; 19727 19728 cmd = (wmi_vdev_update_mac_addr_cmd_fixed_param *)wmi_buf_data(buf); 19729 WMITLV_SET_HDR( 19730 &cmd->tlv_header, 19731 WMITLV_TAG_STRUC_wmi_vdev_update_mac_addr_cmd_fixed_param, 19732 WMITLV_GET_STRUCT_TLVLEN 19733 (wmi_vdev_update_mac_addr_cmd_fixed_param)); 19734 cmd->vdev_id = params->vdev_id; 19735 WMI_CHAR_ARRAY_TO_MAC_ADDR(params->mac_addr.bytes, &cmd->vdev_macaddr); 19736 WMI_CHAR_ARRAY_TO_MAC_ADDR(params->mld_addr.bytes, &cmd->mld_macaddr); 19737 19738 wmi_debug("vdev %d mac_addr " QDF_MAC_ADDR_FMT " mld_addr " 19739 QDF_MAC_ADDR_FMT, cmd->vdev_id, 19740 QDF_MAC_ADDR_REF(params->mac_addr.bytes), 19741 QDF_MAC_ADDR_REF(params->mld_addr.bytes)); 19742 wmi_mtrace(WMI_VDEV_UPDATE_MAC_ADDR_CMDID, cmd->vdev_id, 0); 19743 if (wmi_unified_cmd_send(wmi, buf, len, 19744 WMI_VDEV_UPDATE_MAC_ADDR_CMDID)) { 19745 wmi_buf_free(buf); 19746 return QDF_STATUS_E_FAILURE; 19747 } 19748 19749 return QDF_STATUS_SUCCESS; 19750 } 19751 19752 /** 19753 * extract_update_mac_address_event_tlv() - extract update MAC address event 19754 * @wmi_handle: WMI handle 19755 * @evt_buf: event buffer 19756 * @vdev_id: VDEV ID 19757 * @status: FW status of the set MAC address operation 19758 * 19759 * Return: QDF_STATUS 19760 */ 19761 static QDF_STATUS extract_update_mac_address_event_tlv( 19762 wmi_unified_t wmi_handle, void *evt_buf, 19763 uint8_t *vdev_id, uint8_t *status) 19764 { 19765 WMI_VDEV_UPDATE_MAC_ADDR_CONF_EVENTID_param_tlvs *param_buf; 19766 wmi_vdev_update_mac_addr_conf_event_fixed_param *event; 19767 19768 param_buf = 19769 (WMI_VDEV_UPDATE_MAC_ADDR_CONF_EVENTID_param_tlvs *)evt_buf; 19770 19771 event = param_buf->fixed_param; 19772 19773 *vdev_id = event->vdev_id; 19774 *status = event->status; 19775 19776 return QDF_STATUS_SUCCESS; 19777 } 19778 #endif 19779 19780 #ifdef WLAN_FEATURE_11BE_MLO 19781 /** 19782 * extract_quiet_offload_event_tlv() - extract quiet offload event 19783 * @wmi_handle: WMI handle 19784 * @evt_buf: event buffer 19785 * @quiet_event: quiet event extracted from the buffer 19786 * 19787 * Return: QDF_STATUS 19788 */ 19789 static QDF_STATUS extract_quiet_offload_event_tlv( 19790 wmi_unified_t wmi_handle, void *evt_buf, 19791 struct vdev_sta_quiet_event *quiet_event) 19792 { 19793 WMI_QUIET_HANDLING_EVENTID_param_tlvs *param_buf; 19794 wmi_quiet_event_fixed_param *event; 19795 19796 param_buf = (WMI_QUIET_HANDLING_EVENTID_param_tlvs *)evt_buf; 19797 19798 event = param_buf->fixed_param; 19799 19800 if (!(event->mld_mac_address_present && event->linkid_present) && 19801 !event->link_mac_address_present) { 19802 wmi_err("Invalid sta quiet offload event. present bit: mld mac %d link mac %d linkid %d", 19803 event->mld_mac_address_present, 19804 event->linkid_present, 19805 event->link_mac_address_present); 19806 return QDF_STATUS_E_INVAL; 19807 } 19808 19809 if (event->mld_mac_address_present) 19810 WMI_MAC_ADDR_TO_CHAR_ARRAY(&event->mld_mac_address, 19811 quiet_event->mld_mac.bytes); 19812 if (event->link_mac_address_present) 19813 WMI_MAC_ADDR_TO_CHAR_ARRAY(&event->link_mac_address, 19814 quiet_event->link_mac.bytes); 19815 if (event->linkid_present) 19816 quiet_event->link_id = event->linkid; 19817 quiet_event->quiet_status = (event->quiet_status == 19818 WMI_QUIET_EVENT_START); 19819 19820 return QDF_STATUS_SUCCESS; 19821 } 19822 #endif 19823 19824 /** 19825 * send_vdev_pn_mgmt_rxfilter_cmd_tlv() - Send PN mgmt RxFilter command to FW 19826 * @wmi_handle: wmi handle 19827 * @params: RxFilter params 19828 * 19829 * Return: QDF_STATUS_SUCCESS for success or error code 19830 */ 19831 static QDF_STATUS 19832 send_vdev_pn_mgmt_rxfilter_cmd_tlv(wmi_unified_t wmi_handle, 19833 struct vdev_pn_mgmt_rxfilter_params *params) 19834 { 19835 wmi_vdev_pn_mgmt_rx_filter_cmd_fixed_param *cmd; 19836 wmi_buf_t buf; 19837 uint32_t len = sizeof(wmi_vdev_pn_mgmt_rx_filter_cmd_fixed_param); 19838 19839 if (!is_service_enabled_tlv(wmi_handle, 19840 WMI_SERVICE_PN_REPLAY_CHECK_SUPPORT)) { 19841 wmi_err("Rx PN Replay Check not supported by target"); 19842 return QDF_STATUS_E_NOSUPPORT; 19843 } 19844 19845 buf = wmi_buf_alloc(wmi_handle, len); 19846 if (!buf) { 19847 wmi_err("wmi buf alloc failed"); 19848 return QDF_STATUS_E_NOMEM; 19849 } 19850 19851 cmd = (wmi_vdev_pn_mgmt_rx_filter_cmd_fixed_param *)wmi_buf_data(buf); 19852 WMITLV_SET_HDR( 19853 &cmd->tlv_header, 19854 WMITLV_TAG_STRUC_wmi_vdev_pn_mgmt_rx_filter_cmd_fixed_param, 19855 WMITLV_GET_STRUCT_TLVLEN 19856 (wmi_vdev_pn_mgmt_rx_filter_cmd_fixed_param)); 19857 19858 cmd->vdev_id = params->vdev_id; 19859 cmd->pn_rx_filter = params->pn_rxfilter; 19860 19861 if (wmi_unified_cmd_send(wmi_handle, buf, len, 19862 WMI_VDEV_PN_MGMT_RX_FILTER_CMDID)) { 19863 wmi_err("Failed to send WMI command"); 19864 wmi_buf_free(buf); 19865 return QDF_STATUS_E_FAILURE; 19866 } 19867 19868 return QDF_STATUS_SUCCESS; 19869 } 19870 19871 static QDF_STATUS 19872 extract_pktlog_decode_info_event_tlv(wmi_unified_t wmi_handle, void *evt_buf, 19873 uint8_t *pdev_id, uint8_t *software_image, 19874 uint8_t *chip_info, 19875 uint32_t *pktlog_json_version) 19876 { 19877 WMI_PDEV_PKTLOG_DECODE_INFO_EVENTID_param_tlvs *param_buf; 19878 wmi_pdev_pktlog_decode_info_evt_fixed_param *event; 19879 19880 param_buf = 19881 (WMI_PDEV_PKTLOG_DECODE_INFO_EVENTID_param_tlvs *)evt_buf; 19882 19883 event = param_buf->fixed_param; 19884 19885 if ((event->software_image[0] == '\0') || 19886 (event->chip_info[0] == '\0')) { 19887 *pdev_id = event->pdev_id; 19888 return QDF_STATUS_E_INVAL; 19889 } 19890 19891 qdf_mem_copy(software_image, event->software_image, 40); 19892 qdf_mem_copy(chip_info, event->chip_info, 40); 19893 *pktlog_json_version = event->pktlog_defs_json_version; 19894 *pdev_id = event->pdev_id; 19895 return QDF_STATUS_SUCCESS; 19896 } 19897 19898 #ifdef HEALTH_MON_SUPPORT 19899 /** 19900 * extract_health_mon_init_done_info_event_tlv() - Extract health monitor from 19901 * fw 19902 * @wmi_handle: wmi handle 19903 * @evt_buf: pointer to event buffer 19904 * @param: health monitor params 19905 * 19906 * Return: QDF_STATUS_SUCCESS for success or error code 19907 */ 19908 static QDF_STATUS 19909 extract_health_mon_init_done_info_event_tlv(wmi_unified_t wmi_handle, 19910 void *evt_buf, 19911 struct wmi_health_mon_params *param) 19912 { 19913 WMI_HEALTH_MON_INIT_DONE_EVENTID_param_tlvs *param_buf; 19914 wmi_health_mon_init_done_fixed_param *event; 19915 19916 param_buf = 19917 (WMI_HEALTH_MON_INIT_DONE_EVENTID_param_tlvs *)evt_buf; 19918 19919 event = param_buf->fixed_param; 19920 19921 param->ring_buf_paddr_low = event->ring_buf_paddr_low; 19922 param->ring_buf_paddr_high = event->ring_buf_paddr_high; 19923 param->initial_upload_period_ms = event->initial_upload_period_ms; 19924 param->read_index = 0; 19925 19926 return QDF_STATUS_SUCCESS; 19927 } 19928 #endif /* HEALTH_MON_SUPPORT */ 19929 19930 /** 19931 * extract_pdev_telemetry_stats_tlv - extract pdev telemetry stats 19932 * @wmi_handle: wmi handle 19933 * @evt_buf: pointer to event buffer 19934 * @pdev_stats: Pointer to hold pdev telemetry stats 19935 * 19936 * Return: QDF_STATUS_SUCCESS for success or error code 19937 */ 19938 static QDF_STATUS 19939 extract_pdev_telemetry_stats_tlv( 19940 wmi_unified_t wmi_handle, void *evt_buf, 19941 struct wmi_host_pdev_telemetry_stats *pdev_stats) 19942 { 19943 WMI_UPDATE_STATS_EVENTID_param_tlvs *param_buf; 19944 wmi_pdev_telemetry_stats *ev; 19945 19946 param_buf = (WMI_UPDATE_STATS_EVENTID_param_tlvs *)evt_buf; 19947 19948 if (param_buf->pdev_telemetry_stats) { 19949 ev = (wmi_pdev_telemetry_stats *)(param_buf->pdev_telemetry_stats); 19950 qdf_mem_copy(pdev_stats->avg_chan_lat_per_ac, 19951 ev->avg_chan_lat_per_ac, 19952 sizeof(ev->avg_chan_lat_per_ac)); 19953 pdev_stats->estimated_air_time_per_ac = 19954 ev->estimated_air_time_per_ac; 19955 } 19956 19957 return QDF_STATUS_SUCCESS; 19958 } 19959 19960 static QDF_STATUS 19961 send_set_mac_addr_rx_filter_cmd_tlv(wmi_unified_t wmi_handle, 19962 struct set_rx_mac_filter *param) 19963 { 19964 wmi_vdev_add_mac_addr_to_rx_filter_cmd_fixed_param *cmd; 19965 uint32_t len; 19966 wmi_buf_t buf; 19967 int ret; 19968 19969 if (!wmi_handle) { 19970 wmi_err("WMA context is invalid!"); 19971 return QDF_STATUS_E_INVAL; 19972 } 19973 19974 len = sizeof(*cmd); 19975 buf = wmi_buf_alloc(wmi_handle, len); 19976 if (!buf) { 19977 wmi_err("Failed allocate wmi buffer"); 19978 return QDF_STATUS_E_NOMEM; 19979 } 19980 19981 cmd = (wmi_vdev_add_mac_addr_to_rx_filter_cmd_fixed_param *) 19982 wmi_buf_data(buf); 19983 19984 WMITLV_SET_HDR( 19985 &cmd->tlv_header, 19986 WMITLV_TAG_STRUC_wmi_vdev_add_mac_addr_to_rx_filter_cmd_fixed_param, 19987 WMITLV_GET_STRUCT_TLVLEN( 19988 wmi_vdev_add_mac_addr_to_rx_filter_cmd_fixed_param)); 19989 19990 cmd->vdev_id = param->vdev_id; 19991 cmd->freq = param->freq; 19992 WMI_CHAR_ARRAY_TO_MAC_ADDR(param->mac, &cmd->mac_addr); 19993 if (param->set) 19994 cmd->enable = 1; 19995 else 19996 cmd->enable = 0; 19997 wmi_debug("set random mac rx vdev:%d freq:%d set:%d " QDF_MAC_ADDR_FMT, 19998 param->vdev_id, param->freq, param->set, 19999 QDF_MAC_ADDR_REF(param->mac)); 20000 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 20001 WMI_VDEV_ADD_MAC_ADDR_TO_RX_FILTER_CMDID); 20002 if (ret) { 20003 wmi_err("Failed to send action frame random mac cmd"); 20004 wmi_buf_free(buf); 20005 return QDF_STATUS_E_FAILURE; 20006 } 20007 20008 return QDF_STATUS_SUCCESS; 20009 } 20010 20011 struct wmi_ops tlv_ops = { 20012 .send_vdev_create_cmd = send_vdev_create_cmd_tlv, 20013 .send_vdev_delete_cmd = send_vdev_delete_cmd_tlv, 20014 .send_vdev_nss_chain_params_cmd = send_vdev_nss_chain_params_cmd_tlv, 20015 .send_vdev_down_cmd = send_vdev_down_cmd_tlv, 20016 .send_vdev_start_cmd = send_vdev_start_cmd_tlv, 20017 .send_peer_flush_tids_cmd = send_peer_flush_tids_cmd_tlv, 20018 .send_peer_param_cmd = send_peer_param_cmd_tlv, 20019 .send_vdev_up_cmd = send_vdev_up_cmd_tlv, 20020 .send_vdev_stop_cmd = send_vdev_stop_cmd_tlv, 20021 .send_peer_create_cmd = send_peer_create_cmd_tlv, 20022 .send_peer_delete_cmd = send_peer_delete_cmd_tlv, 20023 .send_peer_delete_all_cmd = send_peer_delete_all_cmd_tlv, 20024 .send_peer_rx_reorder_queue_setup_cmd = 20025 send_peer_rx_reorder_queue_setup_cmd_tlv, 20026 .send_peer_rx_reorder_queue_remove_cmd = 20027 send_peer_rx_reorder_queue_remove_cmd_tlv, 20028 .send_pdev_utf_cmd = send_pdev_utf_cmd_tlv, 20029 .send_pdev_param_cmd = send_pdev_param_cmd_tlv, 20030 .send_multiple_pdev_param_cmd = send_multiple_pdev_param_cmd_tlv, 20031 .send_pdev_set_hw_mode_cmd = send_pdev_set_hw_mode_cmd_tlv, 20032 .send_suspend_cmd = send_suspend_cmd_tlv, 20033 .send_resume_cmd = send_resume_cmd_tlv, 20034 .send_wow_enable_cmd = send_wow_enable_cmd_tlv, 20035 .send_set_ap_ps_param_cmd = send_set_ap_ps_param_cmd_tlv, 20036 .send_set_sta_ps_param_cmd = send_set_sta_ps_param_cmd_tlv, 20037 .send_crash_inject_cmd = send_crash_inject_cmd_tlv, 20038 .send_dbglog_cmd = send_dbglog_cmd_tlv, 20039 .send_vdev_set_param_cmd = send_vdev_set_param_cmd_tlv, 20040 .send_vdev_set_mu_snif_cmd = send_vdev_set_mu_snif_cmd_tlv, 20041 .send_packet_log_enable_cmd = send_packet_log_enable_cmd_tlv, 20042 .send_peer_based_pktlog_cmd = send_peer_based_pktlog_cmd, 20043 .send_time_stamp_sync_cmd = send_time_stamp_sync_cmd_tlv, 20044 .send_packet_log_disable_cmd = send_packet_log_disable_cmd_tlv, 20045 .send_beacon_tmpl_send_cmd = send_beacon_tmpl_send_cmd_tlv, 20046 .send_fd_tmpl_cmd = send_fd_tmpl_cmd_tlv, 20047 .send_peer_assoc_cmd = send_peer_assoc_cmd_tlv, 20048 .send_scan_start_cmd = send_scan_start_cmd_tlv, 20049 .send_scan_stop_cmd = send_scan_stop_cmd_tlv, 20050 .send_scan_chan_list_cmd = send_scan_chan_list_cmd_tlv, 20051 .send_mgmt_cmd = send_mgmt_cmd_tlv, 20052 .send_offchan_data_tx_cmd = send_offchan_data_tx_cmd_tlv, 20053 .send_modem_power_state_cmd = send_modem_power_state_cmd_tlv, 20054 .send_set_sta_ps_mode_cmd = send_set_sta_ps_mode_cmd_tlv, 20055 .send_idle_roam_monitor_cmd = send_idle_roam_monitor_cmd_tlv, 20056 .send_set_sta_uapsd_auto_trig_cmd = 20057 send_set_sta_uapsd_auto_trig_cmd_tlv, 20058 .send_get_temperature_cmd = send_get_temperature_cmd_tlv, 20059 .send_set_smps_params_cmd = send_set_smps_params_cmd_tlv, 20060 .send_set_mimops_cmd = send_set_mimops_cmd_tlv, 20061 .send_set_thermal_mgmt_cmd = send_set_thermal_mgmt_cmd_tlv, 20062 .send_lro_config_cmd = send_lro_config_cmd_tlv, 20063 .send_peer_rate_report_cmd = send_peer_rate_report_cmd_tlv, 20064 .send_probe_rsp_tmpl_send_cmd = 20065 send_probe_rsp_tmpl_send_cmd_tlv, 20066 .send_p2p_go_set_beacon_ie_cmd = 20067 send_p2p_go_set_beacon_ie_cmd_tlv, 20068 .send_setup_install_key_cmd = 20069 send_setup_install_key_cmd_tlv, 20070 .send_scan_probe_setoui_cmd = 20071 send_scan_probe_setoui_cmd_tlv, 20072 #ifdef IPA_OFFLOAD 20073 .send_ipa_offload_control_cmd = 20074 send_ipa_offload_control_cmd_tlv, 20075 #endif 20076 .send_pno_stop_cmd = send_pno_stop_cmd_tlv, 20077 .send_pno_start_cmd = send_pno_start_cmd_tlv, 20078 .send_obss_disable_cmd = send_obss_disable_cmd_tlv, 20079 .send_nlo_mawc_cmd = send_nlo_mawc_cmd_tlv, 20080 #ifdef WLAN_FEATURE_LINK_LAYER_STATS 20081 .send_process_ll_stats_clear_cmd = send_process_ll_stats_clear_cmd_tlv, 20082 .send_process_ll_stats_set_cmd = send_process_ll_stats_set_cmd_tlv, 20083 .send_process_ll_stats_get_cmd = send_process_ll_stats_get_cmd_tlv, 20084 #ifdef FEATURE_CLUB_LL_STATS_AND_GET_STATION 20085 .send_unified_ll_stats_get_sta_cmd = 20086 send_unified_ll_stats_get_sta_cmd_tlv, 20087 #endif /* FEATURE_CLUB_LL_STATS_AND_GET_STATION */ 20088 #endif /* WLAN_FEATURE_LINK_LAYER_STATS*/ 20089 .send_congestion_cmd = send_congestion_cmd_tlv, 20090 .send_snr_request_cmd = send_snr_request_cmd_tlv, 20091 .send_snr_cmd = send_snr_cmd_tlv, 20092 .send_link_status_req_cmd = send_link_status_req_cmd_tlv, 20093 #if !defined(REMOVE_PKT_LOG) && defined(FEATURE_PKTLOG) 20094 .send_pktlog_wmi_send_cmd = send_pktlog_wmi_send_cmd_tlv, 20095 #endif 20096 #ifdef WLAN_SUPPORT_GREEN_AP 20097 .send_egap_conf_params_cmd = send_egap_conf_params_cmd_tlv, 20098 .send_green_ap_ps_cmd = send_green_ap_ps_cmd_tlv, 20099 .extract_green_ap_egap_status_info = 20100 extract_green_ap_egap_status_info_tlv, 20101 #endif 20102 #ifdef WLAN_SUPPORT_GAP_LL_PS_MODE 20103 .send_green_ap_ll_ps_cmd = send_green_ap_ll_ps_cmd_tlv, 20104 .extract_green_ap_ll_ps_param = extract_green_ap_ll_ps_param_tlv, 20105 #endif 20106 .send_csa_offload_enable_cmd = send_csa_offload_enable_cmd_tlv, 20107 .send_start_oem_data_cmd = send_start_oem_data_cmd_tlv, 20108 #ifdef FEATURE_OEM_DATA 20109 .send_start_oemv2_data_cmd = send_start_oemv2_data_cmd_tlv, 20110 #endif 20111 #ifdef WLAN_FEATURE_CIF_CFR 20112 .send_oem_dma_cfg_cmd = send_oem_dma_cfg_cmd_tlv, 20113 #endif 20114 .send_dfs_phyerr_filter_offload_en_cmd = 20115 send_dfs_phyerr_filter_offload_en_cmd_tlv, 20116 .send_stats_ext_req_cmd = send_stats_ext_req_cmd_tlv, 20117 .send_process_dhcpserver_offload_cmd = 20118 send_process_dhcpserver_offload_cmd_tlv, 20119 .send_pdev_set_regdomain_cmd = 20120 send_pdev_set_regdomain_cmd_tlv, 20121 .send_regdomain_info_to_fw_cmd = send_regdomain_info_to_fw_cmd_tlv, 20122 .send_cfg_action_frm_tb_ppdu_cmd = send_cfg_action_frm_tb_ppdu_cmd_tlv, 20123 .save_fw_version_cmd = save_fw_version_cmd_tlv, 20124 .check_and_update_fw_version = 20125 check_and_update_fw_version_cmd_tlv, 20126 .send_log_supported_evt_cmd = send_log_supported_evt_cmd_tlv, 20127 .send_enable_specific_fw_logs_cmd = 20128 send_enable_specific_fw_logs_cmd_tlv, 20129 .send_flush_logs_to_fw_cmd = send_flush_logs_to_fw_cmd_tlv, 20130 .send_unit_test_cmd = send_unit_test_cmd_tlv, 20131 #ifdef FEATURE_WLAN_APF 20132 .send_set_active_apf_mode_cmd = wmi_send_set_active_apf_mode_cmd_tlv, 20133 .send_apf_enable_cmd = wmi_send_apf_enable_cmd_tlv, 20134 .send_apf_write_work_memory_cmd = 20135 wmi_send_apf_write_work_memory_cmd_tlv, 20136 .send_apf_read_work_memory_cmd = 20137 wmi_send_apf_read_work_memory_cmd_tlv, 20138 .extract_apf_read_memory_resp_event = 20139 wmi_extract_apf_read_memory_resp_event_tlv, 20140 #endif /* FEATURE_WLAN_APF */ 20141 .init_cmd_send = init_cmd_send_tlv, 20142 .send_vdev_set_custom_aggr_size_cmd = 20143 send_vdev_set_custom_aggr_size_cmd_tlv, 20144 .send_vdev_set_qdepth_thresh_cmd = 20145 send_vdev_set_qdepth_thresh_cmd_tlv, 20146 .send_set_vap_dscp_tid_map_cmd = send_set_vap_dscp_tid_map_cmd_tlv, 20147 .send_vdev_set_fwtest_param_cmd = send_vdev_set_fwtest_param_cmd_tlv, 20148 .send_phyerr_disable_cmd = send_phyerr_disable_cmd_tlv, 20149 .send_phyerr_enable_cmd = send_phyerr_enable_cmd_tlv, 20150 .send_periodic_chan_stats_config_cmd = 20151 send_periodic_chan_stats_config_cmd_tlv, 20152 #ifdef WLAN_IOT_SIM_SUPPORT 20153 .send_simulation_test_cmd = send_simulation_test_cmd_tlv, 20154 #endif 20155 .send_vdev_spectral_configure_cmd = 20156 send_vdev_spectral_configure_cmd_tlv, 20157 .send_vdev_spectral_enable_cmd = 20158 send_vdev_spectral_enable_cmd_tlv, 20159 #ifdef WLAN_CONV_SPECTRAL_ENABLE 20160 .extract_pdev_sscan_fw_cmd_fixed_param = 20161 extract_pdev_sscan_fw_cmd_fixed_param_tlv, 20162 .extract_pdev_sscan_fft_bin_index = 20163 extract_pdev_sscan_fft_bin_index_tlv, 20164 .extract_pdev_spectral_session_chan_info = 20165 extract_pdev_spectral_session_chan_info_tlv, 20166 .extract_pdev_spectral_session_detector_info = 20167 extract_pdev_spectral_session_detector_info_tlv, 20168 .extract_spectral_caps_fixed_param = 20169 extract_spectral_caps_fixed_param_tlv, 20170 .extract_spectral_scan_bw_caps = 20171 extract_spectral_scan_bw_caps_tlv, 20172 .extract_spectral_fft_size_caps = 20173 extract_spectral_fft_size_caps_tlv, 20174 #endif /* WLAN_CONV_SPECTRAL_ENABLE */ 20175 .send_thermal_mitigation_param_cmd = 20176 send_thermal_mitigation_param_cmd_tlv, 20177 .send_process_update_edca_param_cmd = 20178 send_process_update_edca_param_cmd_tlv, 20179 .send_bss_color_change_enable_cmd = 20180 send_bss_color_change_enable_cmd_tlv, 20181 .send_coex_config_cmd = send_coex_config_cmd_tlv, 20182 .send_set_country_cmd = send_set_country_cmd_tlv, 20183 .send_addba_send_cmd = send_addba_send_cmd_tlv, 20184 .send_delba_send_cmd = send_delba_send_cmd_tlv, 20185 .send_addba_clearresponse_cmd = send_addba_clearresponse_cmd_tlv, 20186 .get_target_cap_from_service_ready = extract_service_ready_tlv, 20187 .extract_hal_reg_cap = extract_hal_reg_cap_tlv, 20188 .extract_num_mem_reqs = extract_num_mem_reqs_tlv, 20189 .extract_host_mem_req = extract_host_mem_req_tlv, 20190 .save_service_bitmap = save_service_bitmap_tlv, 20191 .save_ext_service_bitmap = save_ext_service_bitmap_tlv, 20192 .is_service_enabled = is_service_enabled_tlv, 20193 .save_fw_version = save_fw_version_in_service_ready_tlv, 20194 .ready_extract_init_status = ready_extract_init_status_tlv, 20195 .ready_extract_mac_addr = ready_extract_mac_addr_tlv, 20196 .ready_extract_mac_addr_list = ready_extract_mac_addr_list_tlv, 20197 .extract_ready_event_params = extract_ready_event_params_tlv, 20198 .extract_dbglog_data_len = extract_dbglog_data_len_tlv, 20199 .extract_mgmt_rx_params = extract_mgmt_rx_params_tlv, 20200 .extract_frame_pn_params = extract_frame_pn_params_tlv, 20201 .extract_is_conn_ap_frame = extract_is_conn_ap_frm_param_tlv, 20202 .extract_vdev_roam_param = extract_vdev_roam_param_tlv, 20203 .extract_vdev_scan_ev_param = extract_vdev_scan_ev_param_tlv, 20204 #ifdef FEATURE_WLAN_SCAN_PNO 20205 .extract_nlo_match_ev_param = extract_nlo_match_ev_param_tlv, 20206 .extract_nlo_complete_ev_param = extract_nlo_complete_ev_param_tlv, 20207 #endif 20208 .extract_unit_test = extract_unit_test_tlv, 20209 .extract_pdev_ext_stats = extract_pdev_ext_stats_tlv, 20210 .extract_bcn_stats = extract_bcn_stats_tlv, 20211 .extract_bcnflt_stats = extract_bcnflt_stats_tlv, 20212 .extract_chan_stats = extract_chan_stats_tlv, 20213 .extract_vdev_prb_fils_stats = extract_vdev_prb_fils_stats_tlv, 20214 .extract_profile_ctx = extract_profile_ctx_tlv, 20215 .extract_profile_data = extract_profile_data_tlv, 20216 .send_fw_test_cmd = send_fw_test_cmd_tlv, 20217 .send_wfa_test_cmd = send_wfa_test_cmd_tlv, 20218 .send_power_dbg_cmd = send_power_dbg_cmd_tlv, 20219 .extract_service_ready_ext = extract_service_ready_ext_tlv, 20220 .extract_service_ready_ext2 = extract_service_ready_ext2_tlv, 20221 .extract_dbs_or_sbs_service_ready_ext2 = 20222 extract_dbs_or_sbs_cap_service_ready_ext2_tlv, 20223 .extract_hw_mode_cap_service_ready_ext = 20224 extract_hw_mode_cap_service_ready_ext_tlv, 20225 .extract_mac_phy_cap_service_ready_ext = 20226 extract_mac_phy_cap_service_ready_ext_tlv, 20227 .extract_mac_phy_cap_service_ready_ext2 = 20228 extract_mac_phy_cap_service_ready_ext2_tlv, 20229 .extract_reg_cap_service_ready_ext = 20230 extract_reg_cap_service_ready_ext_tlv, 20231 .extract_hal_reg_cap_ext2 = extract_hal_reg_cap_ext2_tlv, 20232 .extract_dbr_ring_cap_service_ready_ext = 20233 extract_dbr_ring_cap_service_ready_ext_tlv, 20234 .extract_dbr_ring_cap_service_ready_ext2 = 20235 extract_dbr_ring_cap_service_ready_ext2_tlv, 20236 .extract_scan_radio_cap_service_ready_ext2 = 20237 extract_scan_radio_cap_service_ready_ext2_tlv, 20238 .extract_sw_cal_ver_ext2 = extract_sw_cal_ver_ext2_tlv, 20239 .extract_sar_cap_service_ready_ext = 20240 extract_sar_cap_service_ready_ext_tlv, 20241 .extract_pdev_utf_event = extract_pdev_utf_event_tlv, 20242 .wmi_set_htc_tx_tag = wmi_set_htc_tx_tag_tlv, 20243 .extract_fips_event_data = extract_fips_event_data_tlv, 20244 #ifdef WLAN_FEATURE_FIPS_BER_CCMGCM 20245 .extract_fips_extend_ev_data = extract_fips_extend_event_data_tlv, 20246 #endif 20247 #if defined(WLAN_SUPPORT_FILS) || defined(CONFIG_BAND_6GHZ) 20248 .send_vdev_fils_enable_cmd = send_vdev_fils_enable_cmd_send, 20249 #endif 20250 #ifdef WLAN_FEATURE_DISA 20251 .extract_encrypt_decrypt_resp_event = 20252 extract_encrypt_decrypt_resp_event_tlv, 20253 #endif 20254 .send_pdev_fips_cmd = send_pdev_fips_cmd_tlv, 20255 #ifdef WLAN_FEATURE_FIPS_BER_CCMGCM 20256 .send_pdev_fips_extend_cmd = send_pdev_fips_extend_cmd_tlv, 20257 .send_pdev_fips_mode_set_cmd = send_pdev_fips_mode_set_cmd_tlv, 20258 #endif 20259 .extract_get_pn_data = extract_get_pn_data_tlv, 20260 .send_pdev_get_pn_cmd = send_pdev_get_pn_cmd_tlv, 20261 .extract_get_rxpn_data = extract_get_rxpn_data_tlv, 20262 .send_pdev_get_rxpn_cmd = send_pdev_get_rxpn_cmd_tlv, 20263 .send_wlan_profile_enable_cmd = send_wlan_profile_enable_cmd_tlv, 20264 #ifdef WLAN_FEATURE_DISA 20265 .send_encrypt_decrypt_send_cmd = send_encrypt_decrypt_send_cmd_tlv, 20266 #endif 20267 .send_wlan_profile_trigger_cmd = send_wlan_profile_trigger_cmd_tlv, 20268 .send_wlan_profile_hist_intvl_cmd = 20269 send_wlan_profile_hist_intvl_cmd_tlv, 20270 .is_management_record = is_management_record_tlv, 20271 .is_diag_event = is_diag_event_tlv, 20272 #ifdef WLAN_FEATURE_ACTION_OUI 20273 .send_action_oui_cmd = send_action_oui_cmd_tlv, 20274 #endif 20275 .send_dfs_phyerr_offload_en_cmd = send_dfs_phyerr_offload_en_cmd_tlv, 20276 #ifdef QCA_SUPPORT_AGILE_DFS 20277 .send_adfs_ch_cfg_cmd = send_adfs_ch_cfg_cmd_tlv, 20278 .send_adfs_ocac_abort_cmd = send_adfs_ocac_abort_cmd_tlv, 20279 #endif 20280 .send_dfs_phyerr_offload_dis_cmd = send_dfs_phyerr_offload_dis_cmd_tlv, 20281 .extract_reg_chan_list_update_event = 20282 extract_reg_chan_list_update_event_tlv, 20283 #ifdef CONFIG_BAND_6GHZ 20284 .extract_reg_chan_list_ext_update_event = 20285 extract_reg_chan_list_ext_update_event_tlv, 20286 #ifdef CONFIG_AFC_SUPPORT 20287 .extract_afc_event = extract_afc_event_tlv, 20288 #endif 20289 #endif 20290 #ifdef WLAN_SUPPORT_RF_CHARACTERIZATION 20291 .extract_num_rf_characterization_entries = 20292 extract_num_rf_characterization_entries_tlv, 20293 .extract_rf_characterization_entries = 20294 extract_rf_characterization_entries_tlv, 20295 #endif 20296 .extract_chainmask_tables = 20297 extract_chainmask_tables_tlv, 20298 .extract_thermal_stats = extract_thermal_stats_tlv, 20299 .extract_thermal_level_stats = extract_thermal_level_stats_tlv, 20300 .send_get_rcpi_cmd = send_get_rcpi_cmd_tlv, 20301 .extract_rcpi_response_event = extract_rcpi_response_event_tlv, 20302 #ifdef DFS_COMPONENT_ENABLE 20303 .extract_dfs_cac_complete_event = extract_dfs_cac_complete_event_tlv, 20304 .extract_dfs_ocac_complete_event = extract_dfs_ocac_complete_event_tlv, 20305 .extract_dfs_radar_detection_event = 20306 extract_dfs_radar_detection_event_tlv, 20307 .extract_wlan_radar_event_info = extract_wlan_radar_event_info_tlv, 20308 #endif 20309 .convert_pdev_id_host_to_target = 20310 convert_host_pdev_id_to_target_pdev_id_legacy, 20311 .convert_pdev_id_target_to_host = 20312 convert_target_pdev_id_to_host_pdev_id_legacy, 20313 20314 .convert_host_pdev_id_to_target = 20315 convert_host_pdev_id_to_target_pdev_id, 20316 .convert_target_pdev_id_to_host = 20317 convert_target_pdev_id_to_host_pdev_id, 20318 20319 .convert_host_vdev_param_tlv = convert_host_vdev_param_tlv, 20320 20321 .convert_phy_id_host_to_target = 20322 convert_host_phy_id_to_target_phy_id_legacy, 20323 .convert_phy_id_target_to_host = 20324 convert_target_phy_id_to_host_phy_id_legacy, 20325 20326 .convert_host_phy_id_to_target = 20327 convert_host_phy_id_to_target_phy_id, 20328 .convert_target_phy_id_to_host = 20329 convert_target_phy_id_to_host_phy_id, 20330 20331 .send_start_11d_scan_cmd = send_start_11d_scan_cmd_tlv, 20332 .send_stop_11d_scan_cmd = send_stop_11d_scan_cmd_tlv, 20333 .extract_reg_11d_new_country_event = 20334 extract_reg_11d_new_country_event_tlv, 20335 .send_user_country_code_cmd = send_user_country_code_cmd_tlv, 20336 .extract_reg_ch_avoid_event = 20337 extract_reg_ch_avoid_event_tlv, 20338 .send_obss_detection_cfg_cmd = send_obss_detection_cfg_cmd_tlv, 20339 .extract_obss_detection_info = extract_obss_detection_info_tlv, 20340 .wmi_pdev_id_conversion_enable = wmi_tlv_pdev_id_conversion_enable, 20341 .wmi_free_allocated_event = wmitlv_free_allocated_event_tlvs, 20342 .wmi_check_and_pad_event = wmitlv_check_and_pad_event_tlvs, 20343 .wmi_check_command_params = wmitlv_check_command_tlv_params, 20344 .extract_comb_phyerr = extract_comb_phyerr_tlv, 20345 .extract_single_phyerr = extract_single_phyerr_tlv, 20346 #ifdef QCA_SUPPORT_CP_STATS 20347 .extract_cca_stats = extract_cca_stats_tlv, 20348 #endif 20349 .extract_esp_estimation_ev_param = 20350 extract_esp_estimation_ev_param_tlv, 20351 .send_roam_scan_stats_cmd = send_roam_scan_stats_cmd_tlv, 20352 .extract_roam_scan_stats_res_evt = extract_roam_scan_stats_res_evt_tlv, 20353 #ifdef OBSS_PD 20354 .send_obss_spatial_reuse_set = send_obss_spatial_reuse_set_cmd_tlv, 20355 .send_obss_spatial_reuse_set_def_thresh = 20356 send_obss_spatial_reuse_set_def_thresh_cmd_tlv, 20357 .send_self_srg_bss_color_bitmap_set = 20358 send_self_srg_bss_color_bitmap_set_cmd_tlv, 20359 .send_self_srg_partial_bssid_bitmap_set = 20360 send_self_srg_partial_bssid_bitmap_set_cmd_tlv, 20361 .send_self_srg_obss_color_enable_bitmap = 20362 send_self_srg_obss_color_enable_bitmap_cmd_tlv, 20363 .send_self_srg_obss_bssid_enable_bitmap = 20364 send_self_srg_obss_bssid_enable_bitmap_cmd_tlv, 20365 .send_self_non_srg_obss_color_enable_bitmap = 20366 send_self_non_srg_obss_color_enable_bitmap_cmd_tlv, 20367 .send_self_non_srg_obss_bssid_enable_bitmap = 20368 send_self_non_srg_obss_bssid_enable_bitmap_cmd_tlv, 20369 #endif 20370 .extract_offload_bcn_tx_status_evt = extract_offload_bcn_tx_status_evt, 20371 .extract_ctl_failsafe_check_ev_param = 20372 extract_ctl_failsafe_check_ev_param_tlv, 20373 #ifdef WIFI_POS_CONVERGED 20374 .extract_oem_response_param = extract_oem_response_param_tlv, 20375 #endif /* WIFI_POS_CONVERGED */ 20376 #if defined(WIFI_POS_CONVERGED) && defined(WLAN_FEATURE_RTT_11AZ_SUPPORT) 20377 .extract_pasn_peer_create_req_event = 20378 extract_pasn_peer_create_req_event_tlv, 20379 .extract_pasn_peer_delete_req_event = 20380 extract_pasn_peer_delete_req_event_tlv, 20381 .send_rtt_pasn_auth_status_cmd = 20382 send_rtt_pasn_auth_status_cmd_tlv, 20383 .send_rtt_pasn_deauth_cmd = 20384 send_rtt_pasn_deauth_cmd_tlv, 20385 #endif 20386 #ifdef WLAN_MWS_INFO_DEBUGFS 20387 .send_mws_coex_status_req_cmd = send_mws_coex_status_req_cmd_tlv, 20388 #endif 20389 .extract_hw_mode_resp_event = extract_hw_mode_resp_event_status_tlv, 20390 #ifdef FEATURE_ANI_LEVEL_REQUEST 20391 .send_ani_level_cmd = send_ani_level_cmd_tlv, 20392 .extract_ani_level = extract_ani_level_tlv, 20393 #endif /* FEATURE_ANI_LEVEL_REQUEST */ 20394 .extract_roam_trigger_stats = extract_roam_trigger_stats_tlv, 20395 .extract_roam_scan_stats = extract_roam_scan_stats_tlv, 20396 .extract_roam_result_stats = extract_roam_result_stats_tlv, 20397 .extract_roam_11kv_stats = extract_roam_11kv_stats_tlv, 20398 #ifdef WLAN_FEATURE_PKT_CAPTURE 20399 .extract_vdev_mgmt_offload_event = extract_vdev_mgmt_offload_event_tlv, 20400 #endif 20401 #ifdef WLAN_FEATURE_PKT_CAPTURE_V2 20402 .extract_smart_monitor_event = extract_smart_monitor_event_tlv, 20403 #endif 20404 20405 #ifdef FEATURE_WLAN_TIME_SYNC_FTM 20406 .send_wlan_time_sync_ftm_trigger_cmd = send_wlan_ts_ftm_trigger_cmd_tlv, 20407 .send_wlan_ts_qtime_cmd = send_wlan_ts_qtime_cmd_tlv, 20408 .extract_time_sync_ftm_start_stop_event = 20409 extract_time_sync_ftm_start_stop_event_tlv, 20410 .extract_time_sync_ftm_offset_event = 20411 extract_time_sync_ftm_offset_event_tlv, 20412 #endif /* FEATURE_WLAN_TIME_SYNC_FTM */ 20413 .send_roam_scan_ch_list_req_cmd = send_roam_scan_ch_list_req_cmd_tlv, 20414 .send_injector_config_cmd = send_injector_config_cmd_tlv, 20415 .send_cp_stats_cmd = send_cp_stats_cmd_tlv, 20416 .send_halphy_stats_cmd = send_halphy_stats_cmd_tlv, 20417 #ifdef FEATURE_MEC_OFFLOAD 20418 .send_pdev_set_mec_timer_cmd = send_pdev_set_mec_timer_cmd_tlv, 20419 #endif 20420 #ifdef WLAN_SUPPORT_INFRA_CTRL_PATH_STATS 20421 .extract_infra_cp_stats = extract_infra_cp_stats_tlv, 20422 #endif /* WLAN_SUPPORT_INFRA_CTRL_PATH_STATS */ 20423 .extract_cp_stats_more_pending = 20424 extract_cp_stats_more_pending_tlv, 20425 .extract_halphy_stats_end_of_event = 20426 extract_halphy_stats_end_of_event_tlv, 20427 .extract_halphy_stats_event_count = 20428 extract_halphy_stats_event_count_tlv, 20429 .send_vdev_tsf_tstamp_action_cmd = send_vdev_tsf_tstamp_action_cmd_tlv, 20430 .extract_vdev_tsf_report_event = extract_vdev_tsf_report_event_tlv, 20431 .extract_pdev_csa_switch_count_status = 20432 extract_pdev_csa_switch_count_status_tlv, 20433 .send_set_tpc_power_cmd = send_set_tpc_power_cmd_tlv, 20434 #ifdef CONFIG_AFC_SUPPORT 20435 .send_afc_cmd = send_afc_cmd_tlv, 20436 #endif 20437 .extract_dpd_status_ev_param = extract_dpd_status_ev_param_tlv, 20438 .extract_install_key_comp_event = extract_install_key_comp_event_tlv, 20439 .send_vdev_set_ltf_key_seed_cmd = 20440 send_vdev_set_ltf_key_seed_cmd_tlv, 20441 .extract_halphy_cal_status_ev_param = extract_halphy_cal_status_ev_param_tlv, 20442 .send_set_halphy_cal = send_set_halphy_cal_tlv, 20443 .extract_halphy_cal_ev_param = extract_halphy_cal_ev_param_tlv, 20444 #ifdef WLAN_MGMT_RX_REO_SUPPORT 20445 .extract_mgmt_rx_fw_consumed = extract_mgmt_rx_fw_consumed_tlv, 20446 .extract_mgmt_rx_reo_params = extract_mgmt_rx_reo_params_tlv, 20447 .send_mgmt_rx_reo_filter_config_cmd = 20448 send_mgmt_rx_reo_filter_config_cmd_tlv, 20449 #endif 20450 20451 #ifdef WLAN_FEATURE_ROAM_OFFLOAD 20452 .send_roam_set_param_cmd = send_roam_set_param_cmd_tlv, 20453 #endif /* WLAN_FEATURE_ROAM_OFFLOAD */ 20454 20455 #ifdef WLAN_FEATURE_DYNAMIC_MAC_ADDR_UPDATE 20456 .send_set_mac_address_cmd = send_set_mac_address_cmd_tlv, 20457 .extract_update_mac_address_event = 20458 extract_update_mac_address_event_tlv, 20459 #endif 20460 20461 #ifdef WLAN_FEATURE_11BE_MLO 20462 .extract_quiet_offload_event = 20463 extract_quiet_offload_event_tlv, 20464 #endif 20465 20466 #ifdef WLAN_SUPPORT_PPEDS 20467 .peer_ppe_ds_param_send = peer_ppe_ds_param_send_tlv, 20468 #endif /* WLAN_SUPPORT_PPEDS */ 20469 20470 .send_vdev_pn_mgmt_rxfilter_cmd = send_vdev_pn_mgmt_rxfilter_cmd_tlv, 20471 .extract_pktlog_decode_info_event = 20472 extract_pktlog_decode_info_event_tlv, 20473 .extract_pdev_telemetry_stats = extract_pdev_telemetry_stats_tlv, 20474 .extract_mgmt_rx_ext_params = extract_mgmt_rx_ext_params_tlv, 20475 #ifdef WLAN_FEATURE_PEER_TXQ_FLUSH_CONF 20476 .send_peer_txq_flush_config_cmd = send_peer_txq_flush_config_cmd_tlv, 20477 #endif 20478 #ifdef WLAN_FEATURE_DBAM_CONFIG 20479 .send_dbam_config_cmd = send_dbam_config_cmd_tlv, 20480 .extract_dbam_config_resp_event = extract_dbam_config_resp_event_tlv, 20481 #endif 20482 #ifdef FEATURE_SET 20483 .feature_set_cmd_send = feature_set_cmd_send_tlv, 20484 #endif 20485 #ifdef HEALTH_MON_SUPPORT 20486 .extract_health_mon_init_done_info_event = 20487 extract_health_mon_init_done_info_event_tlv, 20488 #endif /* HEALTH_MON_SUPPORT */ 20489 .send_multiple_vdev_param_cmd = send_multiple_vdev_param_cmd_tlv, 20490 .set_mac_addr_rx_filter = send_set_mac_addr_rx_filter_cmd_tlv, 20491 .send_update_edca_pifs_param_cmd = 20492 send_update_edca_pifs_param_cmd_tlv, 20493 }; 20494 20495 #ifdef WLAN_FEATURE_11BE_MLO 20496 static void populate_tlv_events_id_mlo(uint32_t *event_ids) 20497 { 20498 event_ids[wmi_mlo_setup_complete_event_id] = 20499 WMI_MLO_SETUP_COMPLETE_EVENTID; 20500 event_ids[wmi_mlo_teardown_complete_event_id] = 20501 WMI_MLO_TEARDOWN_COMPLETE_EVENTID; 20502 event_ids[wmi_mlo_link_set_active_resp_eventid] = 20503 WMI_MLO_LINK_SET_ACTIVE_RESP_EVENTID; 20504 event_ids[wmi_vdev_quiet_offload_eventid] = 20505 WMI_QUIET_HANDLING_EVENTID; 20506 event_ids[wmi_mlo_ap_vdev_tid_to_link_map_eventid] = 20507 WMI_MLO_AP_VDEV_TID_TO_LINK_MAP_EVENTID; 20508 event_ids[wmi_mlo_link_removal_eventid] = 20509 WMI_MLO_LINK_REMOVAL_EVENTID; 20510 } 20511 #else /* WLAN_FEATURE_11BE_MLO */ 20512 static inline void populate_tlv_events_id_mlo(uint32_t *event_ids) 20513 { 20514 } 20515 #endif /* WLAN_FEATURE_11BE_MLO */ 20516 20517 /** 20518 * populate_tlv_events_id() - populates wmi event ids 20519 * @event_ids: Pointer to hold event ids 20520 * 20521 * Return: None 20522 */ 20523 static void populate_tlv_events_id(uint32_t *event_ids) 20524 { 20525 event_ids[wmi_service_ready_event_id] = WMI_SERVICE_READY_EVENTID; 20526 event_ids[wmi_ready_event_id] = WMI_READY_EVENTID; 20527 event_ids[wmi_scan_event_id] = WMI_SCAN_EVENTID; 20528 event_ids[wmi_pdev_tpc_config_event_id] = WMI_PDEV_TPC_CONFIG_EVENTID; 20529 event_ids[wmi_chan_info_event_id] = WMI_CHAN_INFO_EVENTID; 20530 event_ids[wmi_phyerr_event_id] = WMI_PHYERR_EVENTID; 20531 event_ids[wmi_pdev_dump_event_id] = WMI_PDEV_DUMP_EVENTID; 20532 event_ids[wmi_tx_pause_event_id] = WMI_TX_PAUSE_EVENTID; 20533 event_ids[wmi_dfs_radar_event_id] = WMI_DFS_RADAR_EVENTID; 20534 event_ids[wmi_pdev_l1ss_track_event_id] = WMI_PDEV_L1SS_TRACK_EVENTID; 20535 event_ids[wmi_pdev_temperature_event_id] = WMI_PDEV_TEMPERATURE_EVENTID; 20536 event_ids[wmi_service_ready_ext_event_id] = 20537 WMI_SERVICE_READY_EXT_EVENTID; 20538 event_ids[wmi_service_ready_ext2_event_id] = 20539 WMI_SERVICE_READY_EXT2_EVENTID; 20540 event_ids[wmi_vdev_start_resp_event_id] = WMI_VDEV_START_RESP_EVENTID; 20541 event_ids[wmi_vdev_stopped_event_id] = WMI_VDEV_STOPPED_EVENTID; 20542 event_ids[wmi_vdev_install_key_complete_event_id] = 20543 WMI_VDEV_INSTALL_KEY_COMPLETE_EVENTID; 20544 event_ids[wmi_vdev_mcc_bcn_intvl_change_req_event_id] = 20545 WMI_VDEV_MCC_BCN_INTERVAL_CHANGE_REQ_EVENTID; 20546 20547 event_ids[wmi_vdev_tsf_report_event_id] = WMI_VDEV_TSF_REPORT_EVENTID; 20548 event_ids[wmi_peer_sta_kickout_event_id] = WMI_PEER_STA_KICKOUT_EVENTID; 20549 event_ids[wmi_peer_info_event_id] = WMI_PEER_INFO_EVENTID; 20550 event_ids[wmi_peer_tx_fail_cnt_thr_event_id] = 20551 WMI_PEER_TX_FAIL_CNT_THR_EVENTID; 20552 event_ids[wmi_peer_estimated_linkspeed_event_id] = 20553 WMI_PEER_ESTIMATED_LINKSPEED_EVENTID; 20554 event_ids[wmi_peer_state_event_id] = WMI_PEER_STATE_EVENTID; 20555 event_ids[wmi_peer_create_conf_event_id] = 20556 WMI_PEER_CREATE_CONF_EVENTID; 20557 event_ids[wmi_peer_delete_response_event_id] = 20558 WMI_PEER_DELETE_RESP_EVENTID; 20559 event_ids[wmi_peer_delete_all_response_event_id] = 20560 WMI_VDEV_DELETE_ALL_PEER_RESP_EVENTID; 20561 event_ids[wmi_mgmt_rx_event_id] = WMI_MGMT_RX_EVENTID; 20562 event_ids[wmi_host_swba_event_id] = WMI_HOST_SWBA_EVENTID; 20563 event_ids[wmi_tbttoffset_update_event_id] = 20564 WMI_TBTTOFFSET_UPDATE_EVENTID; 20565 event_ids[wmi_ext_tbttoffset_update_event_id] = 20566 WMI_TBTTOFFSET_EXT_UPDATE_EVENTID; 20567 event_ids[wmi_offload_bcn_tx_status_event_id] = 20568 WMI_OFFLOAD_BCN_TX_STATUS_EVENTID; 20569 event_ids[wmi_offload_prob_resp_tx_status_event_id] = 20570 WMI_OFFLOAD_PROB_RESP_TX_STATUS_EVENTID; 20571 event_ids[wmi_mgmt_tx_completion_event_id] = 20572 WMI_MGMT_TX_COMPLETION_EVENTID; 20573 event_ids[wmi_pdev_nfcal_power_all_channels_event_id] = 20574 WMI_PDEV_NFCAL_POWER_ALL_CHANNELS_EVENTID; 20575 event_ids[wmi_tx_delba_complete_event_id] = 20576 WMI_TX_DELBA_COMPLETE_EVENTID; 20577 event_ids[wmi_tx_addba_complete_event_id] = 20578 WMI_TX_ADDBA_COMPLETE_EVENTID; 20579 event_ids[wmi_ba_rsp_ssn_event_id] = WMI_BA_RSP_SSN_EVENTID; 20580 20581 event_ids[wmi_aggr_state_trig_event_id] = WMI_AGGR_STATE_TRIG_EVENTID; 20582 20583 event_ids[wmi_roam_event_id] = WMI_ROAM_EVENTID; 20584 event_ids[wmi_profile_match] = WMI_PROFILE_MATCH; 20585 20586 event_ids[wmi_roam_synch_event_id] = WMI_ROAM_SYNCH_EVENTID; 20587 event_ids[wmi_roam_synch_frame_event_id] = WMI_ROAM_SYNCH_FRAME_EVENTID; 20588 20589 event_ids[wmi_p2p_disc_event_id] = WMI_P2P_DISC_EVENTID; 20590 20591 event_ids[wmi_p2p_noa_event_id] = WMI_P2P_NOA_EVENTID; 20592 event_ids[wmi_p2p_lo_stop_event_id] = 20593 WMI_P2P_LISTEN_OFFLOAD_STOPPED_EVENTID; 20594 event_ids[wmi_vdev_add_macaddr_rx_filter_event_id] = 20595 WMI_VDEV_ADD_MAC_ADDR_TO_RX_FILTER_STATUS_EVENTID; 20596 event_ids[wmi_pdev_resume_event_id] = WMI_PDEV_RESUME_EVENTID; 20597 event_ids[wmi_wow_wakeup_host_event_id] = WMI_WOW_WAKEUP_HOST_EVENTID; 20598 event_ids[wmi_d0_wow_disable_ack_event_id] = 20599 WMI_D0_WOW_DISABLE_ACK_EVENTID; 20600 event_ids[wmi_wow_initial_wakeup_event_id] = 20601 WMI_WOW_INITIAL_WAKEUP_EVENTID; 20602 20603 event_ids[wmi_rtt_meas_report_event_id] = 20604 WMI_RTT_MEASUREMENT_REPORT_EVENTID; 20605 event_ids[wmi_tsf_meas_report_event_id] = 20606 WMI_TSF_MEASUREMENT_REPORT_EVENTID; 20607 event_ids[wmi_rtt_error_report_event_id] = WMI_RTT_ERROR_REPORT_EVENTID; 20608 event_ids[wmi_stats_ext_event_id] = WMI_STATS_EXT_EVENTID; 20609 event_ids[wmi_iface_link_stats_event_id] = WMI_IFACE_LINK_STATS_EVENTID; 20610 event_ids[wmi_peer_link_stats_event_id] = WMI_PEER_LINK_STATS_EVENTID; 20611 event_ids[wmi_radio_link_stats_link] = WMI_RADIO_LINK_STATS_EVENTID; 20612 event_ids[wmi_diag_event_id_log_supported_event_id] = 20613 WMI_DIAG_EVENT_LOG_SUPPORTED_EVENTID; 20614 event_ids[wmi_nlo_match_event_id] = WMI_NLO_MATCH_EVENTID; 20615 event_ids[wmi_nlo_scan_complete_event_id] = 20616 WMI_NLO_SCAN_COMPLETE_EVENTID; 20617 event_ids[wmi_apfind_event_id] = WMI_APFIND_EVENTID; 20618 event_ids[wmi_passpoint_match_event_id] = WMI_PASSPOINT_MATCH_EVENTID; 20619 20620 event_ids[wmi_gtk_offload_status_event_id] = 20621 WMI_GTK_OFFLOAD_STATUS_EVENTID; 20622 event_ids[wmi_gtk_rekey_fail_event_id] = WMI_GTK_REKEY_FAIL_EVENTID; 20623 event_ids[wmi_csa_handling_event_id] = WMI_CSA_HANDLING_EVENTID; 20624 event_ids[wmi_chatter_pc_query_event_id] = WMI_CHATTER_PC_QUERY_EVENTID; 20625 20626 event_ids[wmi_echo_event_id] = WMI_ECHO_EVENTID; 20627 20628 event_ids[wmi_pdev_utf_event_id] = WMI_PDEV_UTF_EVENTID; 20629 20630 event_ids[wmi_dbg_msg_event_id] = WMI_DEBUG_MESG_EVENTID; 20631 event_ids[wmi_update_stats_event_id] = WMI_UPDATE_STATS_EVENTID; 20632 event_ids[wmi_debug_print_event_id] = WMI_DEBUG_PRINT_EVENTID; 20633 event_ids[wmi_dcs_interference_event_id] = WMI_DCS_INTERFERENCE_EVENTID; 20634 event_ids[wmi_pdev_qvit_event_id] = WMI_PDEV_QVIT_EVENTID; 20635 event_ids[wmi_wlan_profile_data_event_id] = 20636 WMI_WLAN_PROFILE_DATA_EVENTID; 20637 event_ids[wmi_pdev_ftm_intg_event_id] = WMI_PDEV_FTM_INTG_EVENTID; 20638 event_ids[wmi_wlan_freq_avoid_event_id] = WMI_WLAN_FREQ_AVOID_EVENTID; 20639 event_ids[wmi_vdev_get_keepalive_event_id] = 20640 WMI_VDEV_GET_KEEPALIVE_EVENTID; 20641 event_ids[wmi_thermal_mgmt_event_id] = WMI_THERMAL_MGMT_EVENTID; 20642 20643 event_ids[wmi_diag_container_event_id] = 20644 WMI_DIAG_DATA_CONTAINER_EVENTID; 20645 20646 event_ids[wmi_host_auto_shutdown_event_id] = 20647 WMI_HOST_AUTO_SHUTDOWN_EVENTID; 20648 20649 event_ids[wmi_update_whal_mib_stats_event_id] = 20650 WMI_UPDATE_WHAL_MIB_STATS_EVENTID; 20651 20652 /*update ht/vht info based on vdev (rx and tx NSS and preamble) */ 20653 event_ids[wmi_update_vdev_rate_stats_event_id] = 20654 WMI_UPDATE_VDEV_RATE_STATS_EVENTID; 20655 20656 event_ids[wmi_diag_event_id] = WMI_DIAG_EVENTID; 20657 event_ids[wmi_unit_test_event_id] = WMI_UNIT_TEST_EVENTID; 20658 20659 /** Set OCB Sched Response, deprecated */ 20660 event_ids[wmi_ocb_set_sched_event_id] = WMI_OCB_SET_SCHED_EVENTID; 20661 20662 event_ids[wmi_dbg_mesg_flush_complete_event_id] = 20663 WMI_DEBUG_MESG_FLUSH_COMPLETE_EVENTID; 20664 event_ids[wmi_rssi_breach_event_id] = WMI_RSSI_BREACH_EVENTID; 20665 20666 /* GPIO Event */ 20667 event_ids[wmi_gpio_input_event_id] = WMI_GPIO_INPUT_EVENTID; 20668 event_ids[wmi_uploadh_event_id] = WMI_UPLOADH_EVENTID; 20669 20670 event_ids[wmi_captureh_event_id] = WMI_CAPTUREH_EVENTID; 20671 event_ids[wmi_rfkill_state_change_event_id] = 20672 WMI_RFKILL_STATE_CHANGE_EVENTID; 20673 20674 /* TDLS Event */ 20675 event_ids[wmi_tdls_peer_event_id] = WMI_TDLS_PEER_EVENTID; 20676 20677 event_ids[wmi_batch_scan_enabled_event_id] = 20678 WMI_BATCH_SCAN_ENABLED_EVENTID; 20679 event_ids[wmi_batch_scan_result_event_id] = 20680 WMI_BATCH_SCAN_RESULT_EVENTID; 20681 /* OEM Event */ 20682 event_ids[wmi_oem_cap_event_id] = WMI_OEM_CAPABILITY_EVENTID; 20683 event_ids[wmi_oem_meas_report_event_id] = 20684 WMI_OEM_MEASUREMENT_REPORT_EVENTID; 20685 event_ids[wmi_oem_report_event_id] = WMI_OEM_ERROR_REPORT_EVENTID; 20686 20687 /* NAN Event */ 20688 event_ids[wmi_nan_event_id] = WMI_NAN_EVENTID; 20689 20690 /* LPI Event */ 20691 event_ids[wmi_lpi_result_event_id] = WMI_LPI_RESULT_EVENTID; 20692 event_ids[wmi_lpi_status_event_id] = WMI_LPI_STATUS_EVENTID; 20693 event_ids[wmi_lpi_handoff_event_id] = WMI_LPI_HANDOFF_EVENTID; 20694 20695 /* ExtScan events */ 20696 event_ids[wmi_extscan_start_stop_event_id] = 20697 WMI_EXTSCAN_START_STOP_EVENTID; 20698 event_ids[wmi_extscan_operation_event_id] = 20699 WMI_EXTSCAN_OPERATION_EVENTID; 20700 event_ids[wmi_extscan_table_usage_event_id] = 20701 WMI_EXTSCAN_TABLE_USAGE_EVENTID; 20702 event_ids[wmi_extscan_cached_results_event_id] = 20703 WMI_EXTSCAN_CACHED_RESULTS_EVENTID; 20704 event_ids[wmi_extscan_wlan_change_results_event_id] = 20705 WMI_EXTSCAN_WLAN_CHANGE_RESULTS_EVENTID; 20706 event_ids[wmi_extscan_hotlist_match_event_id] = 20707 WMI_EXTSCAN_HOTLIST_MATCH_EVENTID; 20708 event_ids[wmi_extscan_capabilities_event_id] = 20709 WMI_EXTSCAN_CAPABILITIES_EVENTID; 20710 event_ids[wmi_extscan_hotlist_ssid_match_event_id] = 20711 WMI_EXTSCAN_HOTLIST_SSID_MATCH_EVENTID; 20712 20713 /* mDNS offload events */ 20714 event_ids[wmi_mdns_stats_event_id] = WMI_MDNS_STATS_EVENTID; 20715 20716 /* SAP Authentication offload events */ 20717 event_ids[wmi_sap_ofl_add_sta_event_id] = WMI_SAP_OFL_ADD_STA_EVENTID; 20718 event_ids[wmi_sap_ofl_del_sta_event_id] = WMI_SAP_OFL_DEL_STA_EVENTID; 20719 20720 /** Out-of-context-of-bss (OCB) events */ 20721 event_ids[wmi_ocb_set_config_resp_event_id] = 20722 WMI_OCB_SET_CONFIG_RESP_EVENTID; 20723 event_ids[wmi_ocb_get_tsf_timer_resp_event_id] = 20724 WMI_OCB_GET_TSF_TIMER_RESP_EVENTID; 20725 event_ids[wmi_dcc_get_stats_resp_event_id] = 20726 WMI_DCC_GET_STATS_RESP_EVENTID; 20727 event_ids[wmi_dcc_update_ndl_resp_event_id] = 20728 WMI_DCC_UPDATE_NDL_RESP_EVENTID; 20729 event_ids[wmi_dcc_stats_event_id] = WMI_DCC_STATS_EVENTID; 20730 /* System-On-Chip events */ 20731 event_ids[wmi_soc_set_hw_mode_resp_event_id] = 20732 WMI_SOC_SET_HW_MODE_RESP_EVENTID; 20733 event_ids[wmi_soc_hw_mode_transition_event_id] = 20734 WMI_SOC_HW_MODE_TRANSITION_EVENTID; 20735 event_ids[wmi_soc_set_dual_mac_config_resp_event_id] = 20736 WMI_SOC_SET_DUAL_MAC_CONFIG_RESP_EVENTID; 20737 event_ids[wmi_pdev_fips_event_id] = WMI_PDEV_FIPS_EVENTID; 20738 #ifdef WLAN_FEATURE_FIPS_BER_CCMGCM 20739 event_ids[wmi_pdev_fips_extend_event_id] = WMI_PDEV_FIPS_EXTEND_EVENTID; 20740 #endif 20741 event_ids[wmi_pdev_csa_switch_count_status_event_id] = 20742 WMI_PDEV_CSA_SWITCH_COUNT_STATUS_EVENTID; 20743 event_ids[wmi_vdev_ocac_complete_event_id] = 20744 WMI_VDEV_ADFS_OCAC_COMPLETE_EVENTID; 20745 event_ids[wmi_reg_chan_list_cc_event_id] = WMI_REG_CHAN_LIST_CC_EVENTID; 20746 event_ids[wmi_reg_chan_list_cc_ext_event_id] = 20747 WMI_REG_CHAN_LIST_CC_EXT_EVENTID; 20748 #ifdef CONFIG_AFC_SUPPORT 20749 event_ids[wmi_afc_event_id] = WMI_AFC_EVENTID, 20750 #endif 20751 event_ids[wmi_inst_rssi_stats_event_id] = WMI_INST_RSSI_STATS_EVENTID; 20752 event_ids[wmi_pdev_tpc_config_event_id] = WMI_PDEV_TPC_CONFIG_EVENTID; 20753 event_ids[wmi_peer_sta_ps_statechg_event_id] = 20754 WMI_PEER_STA_PS_STATECHG_EVENTID; 20755 event_ids[wmi_pdev_channel_hopping_event_id] = 20756 WMI_PDEV_CHANNEL_HOPPING_EVENTID; 20757 event_ids[wmi_offchan_data_tx_completion_event] = 20758 WMI_OFFCHAN_DATA_TX_COMPLETION_EVENTID; 20759 event_ids[wmi_dfs_cac_complete_id] = WMI_VDEV_DFS_CAC_COMPLETE_EVENTID; 20760 event_ids[wmi_dfs_radar_detection_event_id] = 20761 WMI_PDEV_DFS_RADAR_DETECTION_EVENTID; 20762 event_ids[wmi_tt_stats_event_id] = WMI_THERM_THROT_STATS_EVENTID; 20763 event_ids[wmi_11d_new_country_event_id] = WMI_11D_NEW_COUNTRY_EVENTID; 20764 event_ids[wmi_pdev_tpc_event_id] = WMI_PDEV_TPC_EVENTID; 20765 event_ids[wmi_get_arp_stats_req_id] = WMI_VDEV_GET_ARP_STAT_EVENTID; 20766 event_ids[wmi_service_available_event_id] = 20767 WMI_SERVICE_AVAILABLE_EVENTID; 20768 event_ids[wmi_update_rcpi_event_id] = WMI_UPDATE_RCPI_EVENTID; 20769 event_ids[wmi_pdev_check_cal_version_event_id] = WMI_PDEV_CHECK_CAL_VERSION_EVENTID; 20770 /* NDP events */ 20771 event_ids[wmi_ndp_initiator_rsp_event_id] = 20772 WMI_NDP_INITIATOR_RSP_EVENTID; 20773 event_ids[wmi_ndp_indication_event_id] = WMI_NDP_INDICATION_EVENTID; 20774 event_ids[wmi_ndp_confirm_event_id] = WMI_NDP_CONFIRM_EVENTID; 20775 event_ids[wmi_ndp_responder_rsp_event_id] = 20776 WMI_NDP_RESPONDER_RSP_EVENTID; 20777 event_ids[wmi_ndp_end_indication_event_id] = 20778 WMI_NDP_END_INDICATION_EVENTID; 20779 event_ids[wmi_ndp_end_rsp_event_id] = WMI_NDP_END_RSP_EVENTID; 20780 event_ids[wmi_ndl_schedule_update_event_id] = 20781 WMI_NDL_SCHEDULE_UPDATE_EVENTID; 20782 event_ids[wmi_ndp_event_id] = WMI_NDP_EVENTID; 20783 20784 event_ids[wmi_oem_response_event_id] = WMI_OEM_RESPONSE_EVENTID; 20785 event_ids[wmi_peer_stats_info_event_id] = WMI_PEER_STATS_INFO_EVENTID; 20786 event_ids[wmi_pdev_chip_power_stats_event_id] = 20787 WMI_PDEV_CHIP_POWER_STATS_EVENTID; 20788 event_ids[wmi_ap_ps_egap_info_event_id] = WMI_AP_PS_EGAP_INFO_EVENTID; 20789 event_ids[wmi_peer_assoc_conf_event_id] = WMI_PEER_ASSOC_CONF_EVENTID; 20790 event_ids[wmi_vdev_delete_resp_event_id] = WMI_VDEV_DELETE_RESP_EVENTID; 20791 event_ids[wmi_apf_capability_info_event_id] = 20792 WMI_BPF_CAPABILIY_INFO_EVENTID; 20793 event_ids[wmi_vdev_encrypt_decrypt_data_rsp_event_id] = 20794 WMI_VDEV_ENCRYPT_DECRYPT_DATA_RESP_EVENTID; 20795 event_ids[wmi_report_rx_aggr_failure_event_id] = 20796 WMI_REPORT_RX_AGGR_FAILURE_EVENTID; 20797 event_ids[wmi_pdev_chip_pwr_save_failure_detect_event_id] = 20798 WMI_PDEV_CHIP_POWER_SAVE_FAILURE_DETECTED_EVENTID; 20799 event_ids[wmi_peer_antdiv_info_event_id] = WMI_PEER_ANTDIV_INFO_EVENTID; 20800 event_ids[wmi_pdev_set_hw_mode_rsp_event_id] = 20801 WMI_PDEV_SET_HW_MODE_RESP_EVENTID; 20802 event_ids[wmi_pdev_hw_mode_transition_event_id] = 20803 WMI_PDEV_HW_MODE_TRANSITION_EVENTID; 20804 event_ids[wmi_pdev_set_mac_config_resp_event_id] = 20805 WMI_PDEV_SET_MAC_CONFIG_RESP_EVENTID; 20806 event_ids[wmi_coex_bt_activity_event_id] = 20807 WMI_WLAN_COEX_BT_ACTIVITY_EVENTID; 20808 event_ids[wmi_mgmt_tx_bundle_completion_event_id] = 20809 WMI_MGMT_TX_BUNDLE_COMPLETION_EVENTID; 20810 event_ids[wmi_radio_tx_power_level_stats_event_id] = 20811 WMI_RADIO_TX_POWER_LEVEL_STATS_EVENTID; 20812 event_ids[wmi_report_stats_event_id] = WMI_REPORT_STATS_EVENTID; 20813 event_ids[wmi_dma_buf_release_event_id] = 20814 WMI_PDEV_DMA_RING_BUF_RELEASE_EVENTID; 20815 event_ids[wmi_sap_obss_detection_report_event_id] = 20816 WMI_SAP_OBSS_DETECTION_REPORT_EVENTID; 20817 event_ids[wmi_host_swfda_event_id] = WMI_HOST_SWFDA_EVENTID; 20818 event_ids[wmi_sar_get_limits_event_id] = WMI_SAR_GET_LIMITS_EVENTID; 20819 event_ids[wmi_obss_color_collision_report_event_id] = 20820 WMI_OBSS_COLOR_COLLISION_DETECTION_EVENTID; 20821 event_ids[wmi_pdev_div_rssi_antid_event_id] = 20822 WMI_PDEV_DIV_RSSI_ANTID_EVENTID; 20823 #ifdef WLAN_SUPPORT_TWT 20824 event_ids[wmi_twt_enable_complete_event_id] = 20825 WMI_TWT_ENABLE_COMPLETE_EVENTID; 20826 event_ids[wmi_twt_disable_complete_event_id] = 20827 WMI_TWT_DISABLE_COMPLETE_EVENTID; 20828 event_ids[wmi_twt_add_dialog_complete_event_id] = 20829 WMI_TWT_ADD_DIALOG_COMPLETE_EVENTID; 20830 event_ids[wmi_twt_del_dialog_complete_event_id] = 20831 WMI_TWT_DEL_DIALOG_COMPLETE_EVENTID; 20832 event_ids[wmi_twt_pause_dialog_complete_event_id] = 20833 WMI_TWT_PAUSE_DIALOG_COMPLETE_EVENTID; 20834 event_ids[wmi_twt_resume_dialog_complete_event_id] = 20835 WMI_TWT_RESUME_DIALOG_COMPLETE_EVENTID; 20836 event_ids[wmi_twt_nudge_dialog_complete_event_id] = 20837 WMI_TWT_NUDGE_DIALOG_COMPLETE_EVENTID; 20838 event_ids[wmi_twt_session_stats_event_id] = 20839 WMI_TWT_SESSION_STATS_EVENTID; 20840 event_ids[wmi_twt_notify_event_id] = 20841 WMI_TWT_NOTIFY_EVENTID; 20842 event_ids[wmi_twt_ack_complete_event_id] = 20843 WMI_TWT_ACK_EVENTID; 20844 #endif 20845 event_ids[wmi_apf_get_vdev_work_memory_resp_event_id] = 20846 WMI_BPF_GET_VDEV_WORK_MEMORY_RESP_EVENTID; 20847 event_ids[wmi_wlan_sar2_result_event_id] = WMI_SAR2_RESULT_EVENTID; 20848 event_ids[wmi_esp_estimate_event_id] = WMI_ESP_ESTIMATE_EVENTID; 20849 event_ids[wmi_roam_scan_stats_event_id] = WMI_ROAM_SCAN_STATS_EVENTID; 20850 #ifdef WLAN_FEATURE_INTEROP_ISSUES_AP 20851 event_ids[wmi_pdev_interop_issues_ap_event_id] = 20852 WMI_PDEV_RAP_INFO_EVENTID; 20853 #endif 20854 #ifdef AST_HKV1_WORKAROUND 20855 event_ids[wmi_wds_peer_event_id] = WMI_WDS_PEER_EVENTID; 20856 #endif 20857 event_ids[wmi_pdev_ctl_failsafe_check_event_id] = 20858 WMI_PDEV_CTL_FAILSAFE_CHECK_EVENTID; 20859 event_ids[wmi_vdev_bcn_reception_stats_event_id] = 20860 WMI_VDEV_BCN_RECEPTION_STATS_EVENTID; 20861 event_ids[wmi_roam_denylist_event_id] = WMI_ROAM_BLACKLIST_EVENTID; 20862 event_ids[wmi_wlm_stats_event_id] = WMI_WLM_STATS_EVENTID; 20863 event_ids[wmi_peer_cfr_capture_event_id] = WMI_PEER_CFR_CAPTURE_EVENTID; 20864 event_ids[wmi_pdev_cold_boot_cal_event_id] = 20865 WMI_PDEV_COLD_BOOT_CAL_DATA_EVENTID; 20866 #ifdef WLAN_MWS_INFO_DEBUGFS 20867 event_ids[wmi_vdev_get_mws_coex_state_eventid] = 20868 WMI_VDEV_GET_MWS_COEX_STATE_EVENTID; 20869 event_ids[wmi_vdev_get_mws_coex_dpwb_state_eventid] = 20870 WMI_VDEV_GET_MWS_COEX_DPWB_STATE_EVENTID; 20871 event_ids[wmi_vdev_get_mws_coex_tdm_state_eventid] = 20872 WMI_VDEV_GET_MWS_COEX_TDM_STATE_EVENTID; 20873 event_ids[wmi_vdev_get_mws_coex_idrx_state_eventid] = 20874 WMI_VDEV_GET_MWS_COEX_IDRX_STATE_EVENTID; 20875 event_ids[wmi_vdev_get_mws_coex_antenna_sharing_state_eventid] = 20876 WMI_VDEV_GET_MWS_COEX_ANTENNA_SHARING_STATE_EVENTID; 20877 #endif 20878 event_ids[wmi_coex_report_antenna_isolation_event_id] = 20879 WMI_COEX_REPORT_ANTENNA_ISOLATION_EVENTID; 20880 event_ids[wmi_peer_ratecode_list_event_id] = 20881 WMI_PEER_RATECODE_LIST_EVENTID; 20882 event_ids[wmi_chan_rf_characterization_info_event_id] = 20883 WMI_CHAN_RF_CHARACTERIZATION_INFO_EVENTID; 20884 event_ids[wmi_roam_auth_offload_event_id] = 20885 WMI_ROAM_PREAUTH_START_EVENTID; 20886 event_ids[wmi_get_elna_bypass_event_id] = WMI_GET_ELNA_BYPASS_EVENTID; 20887 event_ids[wmi_motion_det_host_eventid] = WMI_MOTION_DET_HOST_EVENTID; 20888 event_ids[wmi_motion_det_base_line_host_eventid] = 20889 WMI_MOTION_DET_BASE_LINE_HOST_EVENTID; 20890 event_ids[wmi_get_ani_level_event_id] = WMI_GET_CHANNEL_ANI_EVENTID; 20891 event_ids[wmi_peer_tx_pn_response_event_id] = 20892 WMI_PEER_TX_PN_RESPONSE_EVENTID; 20893 event_ids[wmi_roam_stats_event_id] = WMI_ROAM_STATS_EVENTID; 20894 event_ids[wmi_oem_data_event_id] = WMI_OEM_DATA_EVENTID; 20895 event_ids[wmi_mgmt_offload_data_event_id] = 20896 WMI_VDEV_MGMT_OFFLOAD_EVENTID; 20897 event_ids[wmi_nan_dmesg_event_id] = 20898 WMI_NAN_DMESG_EVENTID; 20899 event_ids[wmi_pdev_multi_vdev_restart_response_event_id] = 20900 WMI_PDEV_MULTIPLE_VDEV_RESTART_RESP_EVENTID; 20901 event_ids[wmi_roam_pmkid_request_event_id] = 20902 WMI_ROAM_PMKID_REQUEST_EVENTID; 20903 #ifdef FEATURE_WLAN_TIME_SYNC_FTM 20904 event_ids[wmi_wlan_time_sync_ftm_start_stop_event_id] = 20905 WMI_VDEV_AUDIO_SYNC_START_STOP_EVENTID; 20906 event_ids[wmi_wlan_time_sync_q_initiator_target_offset_eventid] = 20907 WMI_VDEV_AUDIO_SYNC_Q_MASTER_SLAVE_OFFSET_EVENTID; 20908 #endif 20909 event_ids[wmi_roam_scan_chan_list_id] = 20910 WMI_ROAM_SCAN_CHANNEL_LIST_EVENTID; 20911 event_ids[wmi_muedca_params_config_eventid] = 20912 WMI_MUEDCA_PARAMS_CONFIG_EVENTID; 20913 event_ids[wmi_pdev_sscan_fw_param_eventid] = 20914 WMI_PDEV_SSCAN_FW_PARAM_EVENTID; 20915 event_ids[wmi_roam_cap_report_event_id] = 20916 WMI_ROAM_CAPABILITY_REPORT_EVENTID; 20917 event_ids[wmi_vdev_bcn_latency_event_id] = 20918 WMI_VDEV_BCN_LATENCY_EVENTID; 20919 event_ids[wmi_vdev_disconnect_event_id] = 20920 WMI_VDEV_DISCONNECT_EVENTID; 20921 event_ids[wmi_peer_create_conf_event_id] = 20922 WMI_PEER_CREATE_CONF_EVENTID; 20923 event_ids[wmi_pdev_cp_fwstats_eventid] = 20924 WMI_CTRL_PATH_STATS_EVENTID; 20925 event_ids[wmi_pdev_halphy_fwstats_eventid] = 20926 WMI_HALPHY_CTRL_PATH_STATS_EVENTID; 20927 event_ids[wmi_vdev_send_big_data_p2_eventid] = 20928 WMI_VDEV_SEND_BIG_DATA_P2_EVENTID; 20929 event_ids[wmi_pdev_get_dpd_status_event_id] = 20930 WMI_PDEV_GET_DPD_STATUS_EVENTID; 20931 #ifdef WLAN_FEATURE_PKT_CAPTURE_V2 20932 event_ids[wmi_vdev_smart_monitor_event_id] = 20933 WMI_VDEV_SMART_MONITOR_EVENTID; 20934 #endif 20935 event_ids[wmi_pdev_get_halphy_cal_status_event_id] = 20936 WMI_PDEV_GET_HALPHY_CAL_STATUS_EVENTID; 20937 event_ids[wmi_pdev_set_halphy_cal_event_id] = 20938 WMI_PDEV_SET_HALPHY_CAL_BMAP_EVENTID; 20939 event_ids[wmi_pdev_aoa_phasedelta_event_id] = 20940 WMI_PDEV_AOA_PHASEDELTA_EVENTID; 20941 #ifdef WLAN_MGMT_RX_REO_SUPPORT 20942 event_ids[wmi_mgmt_rx_fw_consumed_eventid] = 20943 WMI_MGMT_RX_FW_CONSUMED_EVENTID; 20944 #endif 20945 populate_tlv_events_id_mlo(event_ids); 20946 event_ids[wmi_roam_frame_event_id] = 20947 WMI_ROAM_FRAME_EVENTID; 20948 #ifdef WLAN_FEATURE_DYNAMIC_MAC_ADDR_UPDATE 20949 event_ids[wmi_vdev_update_mac_addr_conf_eventid] = 20950 WMI_VDEV_UPDATE_MAC_ADDR_CONF_EVENTID; 20951 #endif 20952 #ifdef WLAN_FEATURE_MCC_QUOTA 20953 event_ids[wmi_resmgr_chan_time_quota_changed_eventid] = 20954 WMI_RESMGR_CHAN_TIME_QUOTA_CHANGED_EVENTID; 20955 #endif 20956 event_ids[wmi_peer_rx_pn_response_event_id] = 20957 WMI_PEER_RX_PN_RESPONSE_EVENTID; 20958 event_ids[wmi_extract_pktlog_decode_info_eventid] = 20959 WMI_PDEV_PKTLOG_DECODE_INFO_EVENTID; 20960 #ifdef QCA_RSSI_DB2DBM 20961 event_ids[wmi_pdev_rssi_dbm_conversion_params_info_eventid] = 20962 WMI_PDEV_RSSI_DBM_CONVERSION_PARAMS_INFO_EVENTID; 20963 #endif 20964 #ifdef MULTI_CLIENT_LL_SUPPORT 20965 event_ids[wmi_vdev_latency_event_id] = WMI_VDEV_LATENCY_LEVEL_EVENTID; 20966 #endif 20967 #if defined(WIFI_POS_CONVERGED) && defined(WLAN_FEATURE_RTT_11AZ_SUPPORT) 20968 event_ids[wmi_rtt_pasn_peer_create_req_eventid] = 20969 WMI_RTT_PASN_PEER_CREATE_REQ_EVENTID; 20970 event_ids[wmi_rtt_pasn_peer_delete_eventid] = 20971 WMI_RTT_PASN_PEER_DELETE_EVENTID; 20972 #endif 20973 #ifdef WLAN_VENDOR_HANDOFF_CONTROL 20974 event_ids[wmi_get_roam_vendor_control_param_event_id] = 20975 WMI_ROAM_GET_VENDOR_CONTROL_PARAM_EVENTID; 20976 #endif 20977 #ifdef WLAN_FEATURE_DBAM_CONFIG 20978 event_ids[wmi_coex_dbam_complete_event_id] = 20979 WMI_COEX_DBAM_COMPLETE_EVENTID; 20980 #endif 20981 event_ids[wmi_spectral_capabilities_eventid] = 20982 WMI_SPECTRAL_CAPABILITIES_EVENTID; 20983 #ifdef WLAN_FEATURE_COAP 20984 event_ids[wmi_wow_coap_buf_info_eventid] = 20985 WMI_WOW_COAP_BUF_INFO_EVENTID; 20986 #endif 20987 #ifdef HEALTH_MON_SUPPORT 20988 event_ids[wmi_extract_health_mon_init_done_info_eventid] = 20989 WMI_HEALTH_MON_INIT_DONE_EVENTID; 20990 #endif /* HEALTH_MON_SUPPORT */ 20991 #ifdef WLAN_SUPPORT_GAP_LL_PS_MODE 20992 event_ids[wmi_xgap_enable_complete_eventid] = 20993 WMI_XGAP_ENABLE_COMPLETE_EVENTID; 20994 #endif 20995 } 20996 20997 #ifdef WLAN_FEATURE_LINK_LAYER_STATS 20998 #ifdef FEATURE_CLUB_LL_STATS_AND_GET_STATION 20999 static void wmi_populate_service_get_sta_in_ll_stats_req(uint32_t *wmi_service) 21000 { 21001 wmi_service[wmi_service_get_station_in_ll_stats_req] = 21002 WMI_SERVICE_UNIFIED_LL_GET_STA_CMD_SUPPORT; 21003 } 21004 #else 21005 static void wmi_populate_service_get_sta_in_ll_stats_req(uint32_t *wmi_service) 21006 { 21007 } 21008 #endif /* FEATURE_CLUB_LL_STATS_AND_GET_STATION */ 21009 #else 21010 static void wmi_populate_service_get_sta_in_ll_stats_req(uint32_t *wmi_service) 21011 { 21012 } 21013 #endif /* WLAN_FEATURE_LINK_LAYER_STATS */ 21014 21015 #ifdef WLAN_FEATURE_11BE_MLO 21016 static void populate_tlv_service_mlo(uint32_t *wmi_service) 21017 { 21018 wmi_service[wmi_service_mlo_sta_nan_ndi_support] = 21019 WMI_SERVICE_MLO_STA_NAN_NDI_SUPPORT; 21020 } 21021 #else /* WLAN_FEATURE_11BE_MLO */ 21022 static inline void populate_tlv_service_mlo(uint32_t *wmi_service) 21023 { 21024 } 21025 #endif /* WLAN_FEATURE_11BE_MLO */ 21026 21027 /** 21028 * populate_tlv_service() - populates wmi services 21029 * @wmi_service: Pointer to hold wmi_service 21030 * 21031 * Return: None 21032 */ 21033 static void populate_tlv_service(uint32_t *wmi_service) 21034 { 21035 wmi_service[wmi_service_beacon_offload] = WMI_SERVICE_BEACON_OFFLOAD; 21036 wmi_service[wmi_service_ack_timeout] = WMI_SERVICE_ACK_TIMEOUT; 21037 wmi_service[wmi_service_scan_offload] = WMI_SERVICE_SCAN_OFFLOAD; 21038 wmi_service[wmi_service_roam_scan_offload] = 21039 WMI_SERVICE_ROAM_SCAN_OFFLOAD; 21040 wmi_service[wmi_service_bcn_miss_offload] = 21041 WMI_SERVICE_BCN_MISS_OFFLOAD; 21042 wmi_service[wmi_service_sta_pwrsave] = WMI_SERVICE_STA_PWRSAVE; 21043 wmi_service[wmi_service_sta_advanced_pwrsave] = 21044 WMI_SERVICE_STA_ADVANCED_PWRSAVE; 21045 wmi_service[wmi_service_ap_uapsd] = WMI_SERVICE_AP_UAPSD; 21046 wmi_service[wmi_service_ap_dfs] = WMI_SERVICE_AP_DFS; 21047 wmi_service[wmi_service_11ac] = WMI_SERVICE_11AC; 21048 wmi_service[wmi_service_blockack] = WMI_SERVICE_BLOCKACK; 21049 wmi_service[wmi_service_phyerr] = WMI_SERVICE_PHYERR; 21050 wmi_service[wmi_service_bcn_filter] = WMI_SERVICE_BCN_FILTER; 21051 wmi_service[wmi_service_rtt] = WMI_SERVICE_RTT; 21052 wmi_service[wmi_service_wow] = WMI_SERVICE_WOW; 21053 wmi_service[wmi_service_ratectrl_cache] = WMI_SERVICE_RATECTRL_CACHE; 21054 wmi_service[wmi_service_iram_tids] = WMI_SERVICE_IRAM_TIDS; 21055 wmi_service[wmi_service_arpns_offload] = WMI_SERVICE_ARPNS_OFFLOAD; 21056 wmi_service[wmi_service_nlo] = WMI_SERVICE_NLO; 21057 wmi_service[wmi_service_gtk_offload] = WMI_SERVICE_GTK_OFFLOAD; 21058 wmi_service[wmi_service_scan_sch] = WMI_SERVICE_SCAN_SCH; 21059 wmi_service[wmi_service_csa_offload] = WMI_SERVICE_CSA_OFFLOAD; 21060 wmi_service[wmi_service_chatter] = WMI_SERVICE_CHATTER; 21061 wmi_service[wmi_service_coex_freqavoid] = WMI_SERVICE_COEX_FREQAVOID; 21062 wmi_service[wmi_service_packet_power_save] = 21063 WMI_SERVICE_PACKET_POWER_SAVE; 21064 wmi_service[wmi_service_force_fw_hang] = WMI_SERVICE_FORCE_FW_HANG; 21065 wmi_service[wmi_service_gpio] = WMI_SERVICE_GPIO; 21066 wmi_service[wmi_service_sta_dtim_ps_modulated_dtim] = 21067 WMI_SERVICE_STA_DTIM_PS_MODULATED_DTIM; 21068 wmi_service[wmi_sta_uapsd_basic_auto_trig] = 21069 WMI_STA_UAPSD_BASIC_AUTO_TRIG; 21070 wmi_service[wmi_sta_uapsd_var_auto_trig] = WMI_STA_UAPSD_VAR_AUTO_TRIG; 21071 wmi_service[wmi_service_sta_keep_alive] = WMI_SERVICE_STA_KEEP_ALIVE; 21072 wmi_service[wmi_service_tx_encap] = WMI_SERVICE_TX_ENCAP; 21073 wmi_service[wmi_service_ap_ps_detect_out_of_sync] = 21074 WMI_SERVICE_AP_PS_DETECT_OUT_OF_SYNC; 21075 wmi_service[wmi_service_early_rx] = WMI_SERVICE_EARLY_RX; 21076 wmi_service[wmi_service_sta_smps] = WMI_SERVICE_STA_SMPS; 21077 wmi_service[wmi_service_fwtest] = WMI_SERVICE_FWTEST; 21078 wmi_service[wmi_service_sta_wmmac] = WMI_SERVICE_STA_WMMAC; 21079 wmi_service[wmi_service_tdls] = WMI_SERVICE_TDLS; 21080 wmi_service[wmi_service_burst] = WMI_SERVICE_BURST; 21081 wmi_service[wmi_service_mcc_bcn_interval_change] = 21082 WMI_SERVICE_MCC_BCN_INTERVAL_CHANGE; 21083 wmi_service[wmi_service_adaptive_ocs] = WMI_SERVICE_ADAPTIVE_OCS; 21084 wmi_service[wmi_service_ba_ssn_support] = WMI_SERVICE_BA_SSN_SUPPORT; 21085 wmi_service[wmi_service_filter_ipsec_natkeepalive] = 21086 WMI_SERVICE_FILTER_IPSEC_NATKEEPALIVE; 21087 wmi_service[wmi_service_wlan_hb] = WMI_SERVICE_WLAN_HB; 21088 wmi_service[wmi_service_lte_ant_share_support] = 21089 WMI_SERVICE_LTE_ANT_SHARE_SUPPORT; 21090 wmi_service[wmi_service_batch_scan] = WMI_SERVICE_BATCH_SCAN; 21091 wmi_service[wmi_service_qpower] = WMI_SERVICE_QPOWER; 21092 wmi_service[wmi_service_plmreq] = WMI_SERVICE_PLMREQ; 21093 wmi_service[wmi_service_thermal_mgmt] = WMI_SERVICE_THERMAL_MGMT; 21094 wmi_service[wmi_service_rmc] = WMI_SERVICE_RMC; 21095 wmi_service[wmi_service_mhf_offload] = WMI_SERVICE_MHF_OFFLOAD; 21096 wmi_service[wmi_service_coex_sar] = WMI_SERVICE_COEX_SAR; 21097 wmi_service[wmi_service_bcn_txrate_override] = 21098 WMI_SERVICE_BCN_TXRATE_OVERRIDE; 21099 wmi_service[wmi_service_nan] = WMI_SERVICE_NAN; 21100 wmi_service[wmi_service_l1ss_stat] = WMI_SERVICE_L1SS_STAT; 21101 wmi_service[wmi_service_estimate_linkspeed] = 21102 WMI_SERVICE_ESTIMATE_LINKSPEED; 21103 wmi_service[wmi_service_obss_scan] = WMI_SERVICE_OBSS_SCAN; 21104 wmi_service[wmi_service_tdls_offchan] = WMI_SERVICE_TDLS_OFFCHAN; 21105 wmi_service[wmi_service_tdls_uapsd_buffer_sta] = 21106 WMI_SERVICE_TDLS_UAPSD_BUFFER_STA; 21107 wmi_service[wmi_service_tdls_uapsd_sleep_sta] = 21108 WMI_SERVICE_TDLS_UAPSD_SLEEP_STA; 21109 wmi_service[wmi_service_ibss_pwrsave] = WMI_SERVICE_IBSS_PWRSAVE; 21110 wmi_service[wmi_service_lpass] = WMI_SERVICE_LPASS; 21111 wmi_service[wmi_service_extscan] = WMI_SERVICE_EXTSCAN; 21112 wmi_service[wmi_service_d0wow] = WMI_SERVICE_D0WOW; 21113 wmi_service[wmi_service_hsoffload] = WMI_SERVICE_HSOFFLOAD; 21114 wmi_service[wmi_service_roam_ho_offload] = WMI_SERVICE_ROAM_HO_OFFLOAD; 21115 wmi_service[wmi_service_rx_full_reorder] = WMI_SERVICE_RX_FULL_REORDER; 21116 wmi_service[wmi_service_dhcp_offload] = WMI_SERVICE_DHCP_OFFLOAD; 21117 wmi_service[wmi_service_sta_rx_ipa_offload_support] = 21118 WMI_SERVICE_STA_RX_IPA_OFFLOAD_SUPPORT; 21119 wmi_service[wmi_service_mdns_offload] = WMI_SERVICE_MDNS_OFFLOAD; 21120 wmi_service[wmi_service_sap_auth_offload] = 21121 WMI_SERVICE_SAP_AUTH_OFFLOAD; 21122 wmi_service[wmi_service_dual_band_simultaneous_support] = 21123 WMI_SERVICE_DUAL_BAND_SIMULTANEOUS_SUPPORT; 21124 wmi_service[wmi_service_ocb] = WMI_SERVICE_OCB; 21125 wmi_service[wmi_service_ap_arpns_offload] = 21126 WMI_SERVICE_AP_ARPNS_OFFLOAD; 21127 wmi_service[wmi_service_per_band_chainmask_support] = 21128 WMI_SERVICE_PER_BAND_CHAINMASK_SUPPORT; 21129 wmi_service[wmi_service_packet_filter_offload] = 21130 WMI_SERVICE_PACKET_FILTER_OFFLOAD; 21131 wmi_service[wmi_service_mgmt_tx_htt] = WMI_SERVICE_MGMT_TX_HTT; 21132 wmi_service[wmi_service_mgmt_tx_wmi] = WMI_SERVICE_MGMT_TX_WMI; 21133 wmi_service[wmi_service_ext_msg] = WMI_SERVICE_EXT_MSG; 21134 wmi_service[wmi_service_ext2_msg] = WMI_SERVICE_EXT2_MSG; 21135 wmi_service[wmi_service_mawc] = WMI_SERVICE_MAWC; 21136 wmi_service[wmi_service_multiple_vdev_restart] = 21137 WMI_SERVICE_MULTIPLE_VDEV_RESTART; 21138 wmi_service[wmi_service_multiple_vdev_restart_bmap] = 21139 WMI_SERVICE_MULTIPLE_VDEV_RESTART_BITMAP_SUPPORT; 21140 wmi_service[wmi_service_smart_antenna_sw_support] = 21141 WMI_SERVICE_SMART_ANTENNA_SW_SUPPORT; 21142 wmi_service[wmi_service_smart_antenna_hw_support] = 21143 WMI_SERVICE_SMART_ANTENNA_HW_SUPPORT; 21144 21145 wmi_service[wmi_service_roam_offload] = WMI_SERVICE_UNAVAILABLE; 21146 wmi_service[wmi_service_ratectrl] = WMI_SERVICE_UNAVAILABLE; 21147 wmi_service[wmi_service_enhanced_proxy_sta] = WMI_SERVICE_UNAVAILABLE; 21148 wmi_service[wmi_service_tt] = WMI_SERVICE_THERM_THROT; 21149 wmi_service[wmi_service_atf] = WMI_SERVICE_ATF; 21150 wmi_service[wmi_service_peer_caching] = WMI_SERVICE_UNAVAILABLE; 21151 wmi_service[wmi_service_coex_gpio] = WMI_SERVICE_UNAVAILABLE; 21152 wmi_service[wmi_service_aux_spectral_intf] = WMI_SERVICE_UNAVAILABLE; 21153 wmi_service[wmi_service_aux_chan_load_intf] = WMI_SERVICE_UNAVAILABLE; 21154 wmi_service[wmi_service_bss_channel_info_64] = WMI_SERVICE_UNAVAILABLE; 21155 wmi_service[wmi_service_ext_res_cfg_support] = WMI_SERVICE_UNAVAILABLE; 21156 wmi_service[wmi_service_mesh] = WMI_SERVICE_UNAVAILABLE; 21157 wmi_service[wmi_service_restrt_chnl_support] = WMI_SERVICE_UNAVAILABLE; 21158 wmi_service[wmi_service_peer_stats] = WMI_SERVICE_UNAVAILABLE; 21159 wmi_service[wmi_service_mesh_11s] = WMI_SERVICE_UNAVAILABLE; 21160 wmi_service[wmi_service_periodic_chan_stat_support] = 21161 WMI_SERVICE_PERIODIC_CHAN_STAT_SUPPORT; 21162 wmi_service[wmi_service_tx_mode_push_only] = WMI_SERVICE_UNAVAILABLE; 21163 wmi_service[wmi_service_tx_mode_push_pull] = WMI_SERVICE_UNAVAILABLE; 21164 wmi_service[wmi_service_tx_mode_dynamic] = WMI_SERVICE_UNAVAILABLE; 21165 wmi_service[wmi_service_btcoex_duty_cycle] = WMI_SERVICE_UNAVAILABLE; 21166 wmi_service[wmi_service_4_wire_coex_support] = WMI_SERVICE_UNAVAILABLE; 21167 wmi_service[wmi_service_mesh] = WMI_SERVICE_ENTERPRISE_MESH; 21168 wmi_service[wmi_service_peer_assoc_conf] = WMI_SERVICE_PEER_ASSOC_CONF; 21169 wmi_service[wmi_service_egap] = WMI_SERVICE_EGAP; 21170 wmi_service[wmi_service_sta_pmf_offload] = WMI_SERVICE_STA_PMF_OFFLOAD; 21171 wmi_service[wmi_service_unified_wow_capability] = 21172 WMI_SERVICE_UNIFIED_WOW_CAPABILITY; 21173 wmi_service[wmi_service_enterprise_mesh] = WMI_SERVICE_ENTERPRISE_MESH; 21174 wmi_service[wmi_service_apf_offload] = WMI_SERVICE_BPF_OFFLOAD; 21175 wmi_service[wmi_service_sync_delete_cmds] = 21176 WMI_SERVICE_SYNC_DELETE_CMDS; 21177 wmi_service[wmi_service_ratectrl_limit_max_min_rates] = 21178 WMI_SERVICE_RATECTRL_LIMIT_MAX_MIN_RATES; 21179 wmi_service[wmi_service_nan_data] = WMI_SERVICE_NAN_DATA; 21180 wmi_service[wmi_service_nan_rtt] = WMI_SERVICE_NAN_RTT; 21181 wmi_service[wmi_service_11ax] = WMI_SERVICE_11AX; 21182 wmi_service[wmi_service_deprecated_replace] = 21183 WMI_SERVICE_DEPRECATED_REPLACE; 21184 wmi_service[wmi_service_tdls_conn_tracker_in_host_mode] = 21185 WMI_SERVICE_TDLS_CONN_TRACKER_IN_HOST_MODE; 21186 wmi_service[wmi_service_enhanced_mcast_filter] = 21187 WMI_SERVICE_ENHANCED_MCAST_FILTER; 21188 wmi_service[wmi_service_half_rate_quarter_rate_support] = 21189 WMI_SERVICE_HALF_RATE_QUARTER_RATE_SUPPORT; 21190 wmi_service[wmi_service_vdev_rx_filter] = WMI_SERVICE_VDEV_RX_FILTER; 21191 wmi_service[wmi_service_p2p_listen_offload_support] = 21192 WMI_SERVICE_P2P_LISTEN_OFFLOAD_SUPPORT; 21193 wmi_service[wmi_service_mark_first_wakeup_packet] = 21194 WMI_SERVICE_MARK_FIRST_WAKEUP_PACKET; 21195 wmi_service[wmi_service_multiple_mcast_filter_set] = 21196 WMI_SERVICE_MULTIPLE_MCAST_FILTER_SET; 21197 wmi_service[wmi_service_host_managed_rx_reorder] = 21198 WMI_SERVICE_HOST_MANAGED_RX_REORDER; 21199 wmi_service[wmi_service_flash_rdwr_support] = 21200 WMI_SERVICE_FLASH_RDWR_SUPPORT; 21201 wmi_service[wmi_service_wlan_stats_report] = 21202 WMI_SERVICE_WLAN_STATS_REPORT; 21203 wmi_service[wmi_service_tx_msdu_id_new_partition_support] = 21204 WMI_SERVICE_TX_MSDU_ID_NEW_PARTITION_SUPPORT; 21205 wmi_service[wmi_service_dfs_phyerr_offload] = 21206 WMI_SERVICE_DFS_PHYERR_OFFLOAD; 21207 wmi_service[wmi_service_rcpi_support] = WMI_SERVICE_RCPI_SUPPORT; 21208 wmi_service[wmi_service_fw_mem_dump_support] = 21209 WMI_SERVICE_FW_MEM_DUMP_SUPPORT; 21210 wmi_service[wmi_service_peer_stats_info] = WMI_SERVICE_PEER_STATS_INFO; 21211 wmi_service[wmi_service_regulatory_db] = WMI_SERVICE_REGULATORY_DB; 21212 wmi_service[wmi_service_11d_offload] = WMI_SERVICE_11D_OFFLOAD; 21213 wmi_service[wmi_service_hw_data_filtering] = 21214 WMI_SERVICE_HW_DATA_FILTERING; 21215 wmi_service[wmi_service_pkt_routing] = WMI_SERVICE_PKT_ROUTING; 21216 wmi_service[wmi_service_offchan_tx_wmi] = WMI_SERVICE_OFFCHAN_TX_WMI; 21217 wmi_service[wmi_service_chan_load_info] = WMI_SERVICE_CHAN_LOAD_INFO; 21218 wmi_service[wmi_service_extended_nss_support] = 21219 WMI_SERVICE_EXTENDED_NSS_SUPPORT; 21220 wmi_service[wmi_service_widebw_scan] = WMI_SERVICE_SCAN_PHYMODE_SUPPORT; 21221 wmi_service[wmi_service_bcn_offload_start_stop_support] = 21222 WMI_SERVICE_BCN_OFFLOAD_START_STOP_SUPPORT; 21223 wmi_service[wmi_service_offchan_data_tid_support] = 21224 WMI_SERVICE_OFFCHAN_DATA_TID_SUPPORT; 21225 wmi_service[wmi_service_support_dma] = 21226 WMI_SERVICE_SUPPORT_DIRECT_DMA; 21227 wmi_service[wmi_service_8ss_tx_bfee] = WMI_SERVICE_8SS_TX_BFEE; 21228 wmi_service[wmi_service_fils_support] = WMI_SERVICE_FILS_SUPPORT; 21229 wmi_service[wmi_service_mawc_support] = WMI_SERVICE_MAWC_SUPPORT; 21230 wmi_service[wmi_service_wow_wakeup_by_timer_pattern] = 21231 WMI_SERVICE_WOW_WAKEUP_BY_TIMER_PATTERN; 21232 wmi_service[wmi_service_11k_neighbour_report_support] = 21233 WMI_SERVICE_11K_NEIGHBOUR_REPORT_SUPPORT; 21234 wmi_service[wmi_service_ap_obss_detection_offload] = 21235 WMI_SERVICE_AP_OBSS_DETECTION_OFFLOAD; 21236 wmi_service[wmi_service_bss_color_offload] = 21237 WMI_SERVICE_BSS_COLOR_OFFLOAD; 21238 wmi_service[wmi_service_gmac_offload_support] = 21239 WMI_SERVICE_GMAC_OFFLOAD_SUPPORT; 21240 wmi_service[wmi_service_dual_beacon_on_single_mac_scc_support] = 21241 WMI_SERVICE_DUAL_BEACON_ON_SINGLE_MAC_SCC_SUPPORT; 21242 wmi_service[wmi_service_dual_beacon_on_single_mac_mcc_support] = 21243 WMI_SERVICE_DUAL_BEACON_ON_SINGLE_MAC_MCC_SUPPORT; 21244 wmi_service[wmi_service_twt_requestor] = WMI_SERVICE_STA_TWT; 21245 wmi_service[wmi_service_twt_responder] = WMI_SERVICE_AP_TWT; 21246 wmi_service[wmi_service_listen_interval_offload_support] = 21247 WMI_SERVICE_LISTEN_INTERVAL_OFFLOAD_SUPPORT; 21248 wmi_service[wmi_service_esp_support] = WMI_SERVICE_ESP_SUPPORT; 21249 wmi_service[wmi_service_obss_spatial_reuse] = 21250 WMI_SERVICE_OBSS_SPATIAL_REUSE; 21251 wmi_service[wmi_service_per_vdev_chain_support] = 21252 WMI_SERVICE_PER_VDEV_CHAINMASK_CONFIG_SUPPORT; 21253 wmi_service[wmi_service_new_htt_msg_format] = 21254 WMI_SERVICE_HTT_H2T_NO_HTC_HDR_LEN_IN_MSG_LEN; 21255 wmi_service[wmi_service_peer_unmap_cnf_support] = 21256 WMI_SERVICE_PEER_UNMAP_RESPONSE_SUPPORT; 21257 wmi_service[wmi_service_beacon_reception_stats] = 21258 WMI_SERVICE_BEACON_RECEPTION_STATS; 21259 wmi_service[wmi_service_vdev_latency_config] = 21260 WMI_SERVICE_VDEV_LATENCY_CONFIG; 21261 wmi_service[wmi_service_nan_dbs_support] = WMI_SERVICE_NAN_DBS_SUPPORT; 21262 wmi_service[wmi_service_ndi_dbs_support] = WMI_SERVICE_NDI_DBS_SUPPORT; 21263 wmi_service[wmi_service_nan_sap_support] = WMI_SERVICE_NAN_SAP_SUPPORT; 21264 wmi_service[wmi_service_ndi_sap_support] = WMI_SERVICE_NDI_SAP_SUPPORT; 21265 wmi_service[wmi_service_nan_disable_support] = 21266 WMI_SERVICE_NAN_DISABLE_SUPPORT; 21267 wmi_service[wmi_service_sta_plus_sta_support] = 21268 WMI_SERVICE_STA_PLUS_STA_SUPPORT; 21269 wmi_service[wmi_service_hw_db2dbm_support] = 21270 WMI_SERVICE_HW_DB2DBM_CONVERSION_SUPPORT; 21271 wmi_service[wmi_service_wlm_stats_support] = 21272 WMI_SERVICE_WLM_STATS_REQUEST; 21273 wmi_service[wmi_service_infra_mbssid] = WMI_SERVICE_INFRA_MBSSID; 21274 wmi_service[wmi_service_ema_ap_support] = WMI_SERVICE_EMA_AP_SUPPORT; 21275 wmi_service[wmi_service_ul_ru26_allowed] = WMI_SERVICE_UL_RU26_ALLOWED; 21276 wmi_service[wmi_service_cfr_capture_support] = 21277 WMI_SERVICE_CFR_CAPTURE_SUPPORT; 21278 wmi_service[wmi_service_bcast_twt_support] = 21279 WMI_SERVICE_BROADCAST_TWT; 21280 wmi_service[wmi_service_wpa3_ft_sae_support] = 21281 WMI_SERVICE_WPA3_FT_SAE_SUPPORT; 21282 wmi_service[wmi_service_wpa3_ft_suite_b_support] = 21283 WMI_SERVICE_WPA3_FT_SUITE_B_SUPPORT; 21284 wmi_service[wmi_service_ft_fils] = 21285 WMI_SERVICE_WPA3_FT_FILS; 21286 wmi_service[wmi_service_adaptive_11r_support] = 21287 WMI_SERVICE_ADAPTIVE_11R_ROAM; 21288 wmi_service[wmi_service_tx_compl_tsf64] = 21289 WMI_SERVICE_TX_COMPL_TSF64; 21290 wmi_service[wmi_service_data_stall_recovery_support] = 21291 WMI_SERVICE_DSM_ROAM_FILTER; 21292 wmi_service[wmi_service_vdev_delete_all_peer] = 21293 WMI_SERVICE_DELETE_ALL_PEER_SUPPORT; 21294 wmi_service[wmi_service_three_way_coex_config_legacy] = 21295 WMI_SERVICE_THREE_WAY_COEX_CONFIG_LEGACY; 21296 wmi_service[wmi_service_rx_fse_support] = 21297 WMI_SERVICE_RX_FSE_SUPPORT; 21298 wmi_service[wmi_service_sae_roam_support] = 21299 WMI_SERVICE_WPA3_SAE_ROAM_SUPPORT; 21300 wmi_service[wmi_service_owe_roam_support] = 21301 WMI_SERVICE_WPA3_OWE_ROAM_SUPPORT; 21302 wmi_service[wmi_service_6ghz_support] = 21303 WMI_SERVICE_6GHZ_SUPPORT; 21304 wmi_service[wmi_service_bw_165mhz_support] = 21305 WMI_SERVICE_BW_165MHZ_SUPPORT; 21306 wmi_service[wmi_service_bw_restricted_80p80_support] = 21307 WMI_SERVICE_BW_RESTRICTED_80P80_SUPPORT; 21308 wmi_service[wmi_service_packet_capture_support] = 21309 WMI_SERVICE_PACKET_CAPTURE_SUPPORT; 21310 wmi_service[wmi_service_nan_vdev] = WMI_SERVICE_NAN_VDEV_SUPPORT; 21311 wmi_service[wmi_service_peer_delete_no_peer_flush_tids_cmd] = 21312 WMI_SERVICE_PEER_DELETE_NO_PEER_FLUSH_TIDS_CMD; 21313 wmi_service[wmi_service_multiple_vdev_restart_ext] = 21314 WMI_SERVICE_UNAVAILABLE; 21315 wmi_service[wmi_service_time_sync_ftm] = 21316 WMI_SERVICE_AUDIO_SYNC_SUPPORT; 21317 wmi_service[wmi_service_nss_ratio_to_host_support] = 21318 WMI_SERVICE_NSS_RATIO_TO_HOST_SUPPORT; 21319 wmi_service[wmi_roam_scan_chan_list_to_host_support] = 21320 WMI_SERVICE_ROAM_SCAN_CHANNEL_LIST_TO_HOST_SUPPORT; 21321 wmi_service[wmi_beacon_protection_support] = 21322 WMI_SERVICE_BEACON_PROTECTION_SUPPORT; 21323 wmi_service[wmi_service_sta_nan_ndi_four_port] = 21324 WMI_SERVICE_NDI_NDI_STA_SUPPORT; 21325 wmi_service[wmi_service_host_scan_stop_vdev_all] = 21326 WMI_SERVICE_HOST_SCAN_STOP_VDEV_ALL_SUPPORT; 21327 wmi_service[wmi_support_extend_address] = 21328 WMI_SERVICE_SUPPORT_EXTEND_ADDRESS; 21329 wmi_service[wmi_service_srg_srp_spatial_reuse_support] = 21330 WMI_SERVICE_SRG_SRP_SPATIAL_REUSE_SUPPORT; 21331 wmi_service[wmi_service_suiteb_roam_support] = 21332 WMI_SERVICE_WPA3_SUITEB_ROAM_SUPPORT; 21333 wmi_service[wmi_service_no_interband_mcc_support] = 21334 WMI_SERVICE_NO_INTERBAND_MCC_SUPPORT; 21335 wmi_service[wmi_service_dual_sta_roam_support] = 21336 WMI_SERVICE_DUAL_STA_ROAM_SUPPORT; 21337 wmi_service[wmi_service_peer_create_conf] = 21338 WMI_SERVICE_PEER_CREATE_CONF; 21339 wmi_service[wmi_service_configure_roam_trigger_param_support] = 21340 WMI_SERVICE_CONFIGURE_ROAM_TRIGGER_PARAM_SUPPORT; 21341 wmi_service[wmi_service_5dot9_ghz_support] = 21342 WMI_SERVICE_5_DOT_9GHZ_SUPPORT; 21343 wmi_service[wmi_service_cfr_ta_ra_as_fp_support] = 21344 WMI_SERVICE_CFR_TA_RA_AS_FP_SUPPORT; 21345 wmi_service[wmi_service_cfr_capture_count_support] = 21346 WMI_SERVICE_CFR_CAPTURE_COUNT_SUPPORT; 21347 wmi_service[wmi_service_ocv_support] = 21348 WMI_SERVICE_OCV_SUPPORT; 21349 wmi_service[wmi_service_ll_stats_per_chan_rx_tx_time] = 21350 WMI_SERVICE_LL_STATS_PER_CHAN_RX_TX_TIME_SUPPORT; 21351 wmi_service[wmi_service_thermal_multi_client_support] = 21352 WMI_SERVICE_THERMAL_MULTI_CLIENT_SUPPORT; 21353 wmi_service[wmi_service_mbss_param_in_vdev_start_support] = 21354 WMI_SERVICE_MBSS_PARAM_IN_VDEV_START_SUPPORT; 21355 wmi_service[wmi_service_fse_cmem_alloc_support] = 21356 WMI_SERVICE_FSE_CMEM_ALLOC_SUPPORT; 21357 wmi_service[wmi_service_scan_conf_per_ch_support] = 21358 WMI_SERVICE_SCAN_CONFIG_PER_CHANNEL; 21359 wmi_service[wmi_service_csa_beacon_template] = 21360 WMI_SERVICE_CSA_BEACON_TEMPLATE; 21361 #if defined(WIFI_POS_CONVERGED) && defined(WLAN_FEATURE_RTT_11AZ_SUPPORT) 21362 wmi_service[wmi_service_rtt_11az_ntb_support] = 21363 WMI_SERVICE_RTT_11AZ_NTB_SUPPORT; 21364 wmi_service[wmi_service_rtt_11az_tb_support] = 21365 WMI_SERVICE_RTT_11AZ_TB_SUPPORT; 21366 wmi_service[wmi_service_rtt_11az_mac_sec_support] = 21367 WMI_SERVICE_RTT_11AZ_MAC_SEC_SUPPORT; 21368 wmi_service[wmi_service_rtt_11az_mac_phy_sec_support] = 21369 WMI_SERVICE_RTT_11AZ_MAC_PHY_SEC_SUPPORT; 21370 #endif 21371 #ifdef WLAN_FEATURE_IGMP_OFFLOAD 21372 wmi_service[wmi_service_igmp_offload_support] = 21373 WMI_SERVICE_IGMP_OFFLOAD_SUPPORT; 21374 #endif 21375 21376 #ifdef FEATURE_WLAN_TDLS 21377 #ifdef WLAN_FEATURE_11AX 21378 wmi_service[wmi_service_tdls_ax_support] = 21379 WMI_SERVICE_11AX_TDLS_SUPPORT; 21380 wmi_service[wmi_service_tdls_6g_support] = 21381 WMI_SERVICE_TDLS_6GHZ_SUPPORT; 21382 #endif 21383 wmi_service[wmi_service_tdls_wideband_support] = 21384 WMI_SERVICE_TDLS_WIDEBAND_SUPPORT; 21385 #endif 21386 21387 #ifdef WLAN_SUPPORT_TWT 21388 wmi_service[wmi_service_twt_bcast_req_support] = 21389 WMI_SERVICE_BROADCAST_TWT_REQUESTER; 21390 wmi_service[wmi_service_twt_bcast_resp_support] = 21391 WMI_SERVICE_BROADCAST_TWT_RESPONDER; 21392 wmi_service[wmi_service_twt_nudge] = 21393 WMI_SERVICE_TWT_NUDGE; 21394 wmi_service[wmi_service_all_twt] = 21395 WMI_SERVICE_TWT_ALL_DIALOG_ID; 21396 wmi_service[wmi_service_twt_statistics] = 21397 WMI_SERVICE_TWT_STATS; 21398 #endif 21399 wmi_service[wmi_service_spectral_scan_disabled] = 21400 WMI_SERVICE_SPECTRAL_SCAN_DISABLED; 21401 wmi_service[wmi_service_sae_eapol_offload_support] = 21402 WMI_SERVICE_SAE_EAPOL_OFFLOAD_SUPPORT; 21403 wmi_populate_service_get_sta_in_ll_stats_req(wmi_service); 21404 21405 wmi_service[wmi_service_wapi_concurrency_supported] = 21406 WMI_SERVICE_WAPI_CONCURRENCY_SUPPORTED; 21407 wmi_service[wmi_service_sap_connected_d3_wow] = 21408 WMI_SERVICE_SAP_CONNECTED_D3WOW; 21409 wmi_service[wmi_service_go_connected_d3_wow] = 21410 WMI_SERVICE_SAP_CONNECTED_D3WOW; 21411 wmi_service[wmi_service_ext_tpc_reg_support] = 21412 WMI_SERVICE_EXT_TPC_REG_SUPPORT; 21413 wmi_service[wmi_service_eirp_preferred_support] = 21414 WMI_SERVICE_EIRP_PREFERRED_SUPPORT; 21415 wmi_service[wmi_service_ndi_txbf_support] = 21416 WMI_SERVICE_NDI_TXBF_SUPPORT; 21417 wmi_service[wmi_service_reg_cc_ext_event_support] = 21418 WMI_SERVICE_REG_CC_EXT_EVENT_SUPPORT; 21419 wmi_service[wmi_service_bang_radar_320_support] = 21420 WMI_SERVICE_BANG_RADAR_320_SUPPORT; 21421 #if defined(CONFIG_BAND_6GHZ) 21422 wmi_service[wmi_service_lower_6g_edge_ch_supp] = 21423 WMI_SERVICE_ENABLE_LOWER_6G_EDGE_CH_SUPP; 21424 wmi_service[wmi_service_disable_upper_6g_edge_ch_supp] = 21425 WMI_SERVICE_DISABLE_UPPER_6G_EDGE_CH_SUPP; 21426 #ifdef CONFIG_AFC_SUPPORT 21427 wmi_service[wmi_service_afc_support] = 21428 WMI_SERVICE_AFC_SUPPORT; 21429 #endif 21430 #endif 21431 wmi_service[wmi_service_dcs_awgn_int_support] = 21432 WMI_SERVICE_DCS_AWGN_INT_SUPPORT; 21433 wmi_populate_service_11be(wmi_service); 21434 21435 #ifdef WLAN_FEATURE_BIG_DATA_STATS 21436 wmi_service[wmi_service_big_data_support] = 21437 WMI_SERVICE_BIG_DATA_SUPPORT; 21438 #endif 21439 wmi_service[wmi_service_ampdu_tx_buf_size_256_support] = 21440 WMI_SERVICE_AMPDU_TX_BUF_SIZE_256_SUPPORT; 21441 wmi_service[wmi_service_halphy_cal_enable_disable_support] = 21442 WMI_SERVICE_HALPHY_CAL_ENABLE_DISABLE_SUPPORT; 21443 wmi_service[wmi_service_halphy_cal_status] = 21444 WMI_SERVICE_HALPHY_CAL_STATUS; 21445 wmi_service[wmi_service_rtt_ap_initiator_staggered_mode_supported] = 21446 WMI_SERVICE_RTT_AP_INITIATOR_STAGGERED_MODE_SUPPORTED; 21447 wmi_service[wmi_service_rtt_ap_initiator_bursted_mode_supported] = 21448 WMI_SERVICE_RTT_AP_INITIATOR_BURSTED_MODE_SUPPORTED; 21449 wmi_service[wmi_service_ema_multiple_group_supported] = 21450 WMI_SERVICE_EMA_MULTIPLE_GROUP_SUPPORT; 21451 wmi_service[wmi_service_large_beacon_supported] = 21452 WMI_SERVICE_LARGE_BEACON_SUPPORT; 21453 wmi_service[wmi_service_aoa_for_rcc_supported] = 21454 WMI_SERVICE_AOA_FOR_RCC_SUPPORTED; 21455 #ifdef WLAN_FEATURE_P2P_P2P_STA 21456 wmi_service[wmi_service_p2p_p2p_cc_support] = 21457 WMI_SERVICE_P2P_P2P_CONCURRENCY_SUPPORT; 21458 #endif 21459 #ifdef THERMAL_STATS_SUPPORT 21460 wmi_service[wmi_service_thermal_stats_temp_range_supported] = 21461 WMI_SERVICE_THERMAL_THROT_STATS_TEMP_RANGE_SUPPORT; 21462 #endif 21463 wmi_service[wmi_service_hw_mode_policy_offload_support] = 21464 WMI_SERVICE_HW_MODE_POLICY_OFFLOAD_SUPPORT; 21465 wmi_service[wmi_service_mgmt_rx_reo_supported] = 21466 WMI_SERVICE_MGMT_RX_REO_SUPPORTED; 21467 wmi_service[wmi_service_phy_dma_byte_swap_support] = 21468 WMI_SERVICE_UNAVAILABLE; 21469 wmi_service[wmi_service_spectral_session_info_support] = 21470 WMI_SERVICE_SPECTRAL_SESSION_INFO_SUPPORT; 21471 wmi_service[wmi_service_umac_hang_recovery_support] = 21472 WMI_SERVICE_UMAC_HANG_RECOVERY_SUPPORT; 21473 wmi_service[wmi_service_mu_snif] = WMI_SERVICE_MU_SNIF; 21474 #ifdef WLAN_FEATURE_DYNAMIC_MAC_ADDR_UPDATE 21475 wmi_service[wmi_service_dynamic_update_vdev_macaddr_support] = 21476 WMI_SERVICE_DYNAMIC_VDEV_MAC_ADDR_UPDATE_SUPPORT; 21477 #endif 21478 wmi_service[wmi_service_probe_all_bw_support] = 21479 WMI_SERVICE_PROBE_ALL_BW_SUPPORT; 21480 wmi_service[wmi_service_pno_scan_conf_per_ch_support] = 21481 WMI_SERVICE_PNO_SCAN_CONFIG_PER_CHANNEL; 21482 #ifdef QCA_UNDECODED_METADATA_SUPPORT 21483 wmi_service[wmi_service_fp_phy_err_filter_support] = 21484 WMI_SERVICE_FP_PHY_ERR_FILTER_SUPPORT; 21485 #endif 21486 populate_tlv_service_mlo(wmi_service); 21487 wmi_service[wmi_service_pdev_rate_config_support] = 21488 WMI_SERVICE_PDEV_RATE_CONFIG_SUPPORT; 21489 wmi_service[wmi_service_multi_peer_group_cmd_support] = 21490 WMI_SERVICE_MULTIPLE_PEER_GROUP_CMD_SUPPORT; 21491 #ifdef WLAN_FEATURE_11BE 21492 wmi_service[wmi_service_radar_found_chan_freq_eq_center_freq] = 21493 WMI_IS_RADAR_FOUND_CHAN_FREQ_IS_CENTER_FREQ; 21494 #endif 21495 #ifdef WLAN_PDEV_VDEV_SEND_MULTI_PARAM 21496 wmi_service[wmi_service_combined_set_param_support] = 21497 WMI_SERVICE_COMBINED_SET_PARAM_SUPPORT; 21498 #endif 21499 wmi_service[wmi_service_pn_replay_check_support] = 21500 WMI_SERVICE_PN_REPLAY_CHECK_SUPPORT; 21501 #ifdef QCA_RSSI_DB2DBM 21502 wmi_service[wmi_service_pdev_rssi_dbm_conv_event_support] = 21503 WMI_SERVICE_PDEV_RSSI_DBM_CONV_EVENT_SUPPORT; 21504 #endif 21505 wmi_service[wmi_service_pktlog_decode_info_support] = 21506 WMI_SERVICE_PKTLOG_DECODE_INFO_SUPPORT; 21507 #ifdef WLAN_FEATURE_ROAM_OFFLOAD 21508 wmi_service[wmi_service_roam_stats_per_candidate_frame_info] = 21509 WMI_SERVICE_ROAM_STAT_PER_CANDIDATE_FRAME_INFO_SUPPORT; 21510 #endif 21511 #ifdef MULTI_CLIENT_LL_SUPPORT 21512 wmi_service[wmi_service_configure_multi_client_ll_support] = 21513 WMI_SERVICE_MULTI_CLIENT_LL_SUPPORT; 21514 #endif 21515 #ifdef WLAN_VENDOR_HANDOFF_CONTROL 21516 wmi_service[wmi_service_configure_vendor_handoff_control_support] = 21517 WMI_SERVICE_FW_INI_PARSE_SUPPORT; 21518 #endif 21519 wmi_service[wmi_service_linkspeed_roam_trigger_support] = 21520 WMI_SERVICE_LINKSPEED_ROAM_TRIGGER_SUPPORT; 21521 #ifdef FEATURE_SET 21522 wmi_service[wmi_service_feature_set_event_support] = 21523 WMI_SERVICE_FEATURE_SET_EVENT_SUPPORT; 21524 #endif 21525 #ifdef WLAN_FEATURE_SR 21526 wmi_service[wmi_service_obss_per_packet_sr_support] = 21527 WMI_SERVICE_OBSS_PER_PACKET_SR_SUPPORT; 21528 #endif 21529 wmi_service[wmi_service_wpa3_sha384_roam_support] = 21530 WMI_SERVICE_WMI_SERVICE_WPA3_SHA384_ROAM_SUPPORT; 21531 } 21532 21533 /** 21534 * wmi_ocb_ut_attach() - Attach OCB test framework 21535 * @wmi_handle: wmi handle 21536 * 21537 * Return: None 21538 */ 21539 #ifdef WLAN_OCB_UT 21540 void wmi_ocb_ut_attach(struct wmi_unified *wmi_handle); 21541 #else 21542 static inline void wmi_ocb_ut_attach(struct wmi_unified *wmi_handle) 21543 { 21544 return; 21545 } 21546 #endif 21547 21548 /** 21549 * wmi_tlv_attach() - Attach TLV APIs 21550 * @wmi_handle: wmi handle 21551 * Return: None 21552 */ 21553 void wmi_tlv_attach(wmi_unified_t wmi_handle) 21554 { 21555 wmi_handle->ops = &tlv_ops; 21556 wmi_ocb_ut_attach(wmi_handle); 21557 wmi_handle->soc->svc_ids = &multi_svc_ids[0]; 21558 #ifdef WMI_INTERFACE_EVENT_LOGGING 21559 /* Skip saving WMI_CMD_HDR and TLV HDR */ 21560 wmi_handle->soc->buf_offset_command = 8; 21561 /* WMI_CMD_HDR is already stripped, skip saving TLV HDR */ 21562 wmi_handle->soc->buf_offset_event = 4; 21563 #endif 21564 populate_tlv_events_id(wmi_handle->wmi_events); 21565 populate_tlv_service(wmi_handle->services); 21566 wmi_wds_attach_tlv(wmi_handle); 21567 wmi_twt_attach_tlv(wmi_handle); 21568 wmi_extscan_attach_tlv(wmi_handle); 21569 wmi_smart_ant_attach_tlv(wmi_handle); 21570 wmi_dbr_attach_tlv(wmi_handle); 21571 wmi_atf_attach_tlv(wmi_handle); 21572 wmi_ap_attach_tlv(wmi_handle); 21573 wmi_bcn_attach_tlv(wmi_handle); 21574 wmi_ocb_attach_tlv(wmi_handle); 21575 wmi_nan_attach_tlv(wmi_handle); 21576 wmi_p2p_attach_tlv(wmi_handle); 21577 wmi_interop_issues_ap_attach_tlv(wmi_handle); 21578 wmi_dcs_attach_tlv(wmi_handle); 21579 wmi_roam_attach_tlv(wmi_handle); 21580 wmi_concurrency_attach_tlv(wmi_handle); 21581 wmi_pmo_attach_tlv(wmi_handle); 21582 wmi_sta_attach_tlv(wmi_handle); 21583 wmi_11ax_bss_color_attach_tlv(wmi_handle); 21584 wmi_fwol_attach_tlv(wmi_handle); 21585 wmi_vdev_attach_tlv(wmi_handle); 21586 wmi_cfr_attach_tlv(wmi_handle); 21587 wmi_cp_stats_attach_tlv(wmi_handle); 21588 wmi_gpio_attach_tlv(wmi_handle); 21589 wmi_11be_attach_tlv(wmi_handle); 21590 wmi_coap_attach_tlv(wmi_handle); 21591 } 21592 qdf_export_symbol(wmi_tlv_attach); 21593 21594 /** 21595 * wmi_tlv_init() - Initialize WMI TLV module by registering TLV attach routine 21596 * 21597 * Return: None 21598 */ 21599 void wmi_tlv_init(void) 21600 { 21601 wmi_unified_register_module(WMI_TLV_TARGET, &wmi_tlv_attach); 21602 } 21603