1 /* 2 * Copyright (c) 2016-2021 The Linux Foundation. All rights reserved. 3 * Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved. 4 * 5 * Permission to use, copy, modify, and/or distribute this software for 6 * any purpose with or without fee is hereby granted, provided that the 7 * above copyright notice and this permission notice appear in all 8 * copies. 9 * 10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL 11 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED 12 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE 13 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL 14 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR 15 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 16 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 17 * PERFORMANCE OF THIS SOFTWARE. 18 */ 19 20 #include "wmi_unified_api.h" 21 #include "wmi.h" 22 #include "wmi_version.h" 23 #include "wmi_unified_priv.h" 24 #include "wmi_version_allowlist.h" 25 #include "wifi_pos_public_struct.h" 26 #include <qdf_module.h> 27 #include <wlan_defs.h> 28 #include <wlan_cmn.h> 29 #include <htc_services.h> 30 #ifdef FEATURE_WLAN_APF 31 #include "wmi_unified_apf_tlv.h" 32 #endif 33 #ifdef WLAN_FEATURE_ACTION_OUI 34 #include "wmi_unified_action_oui_tlv.h" 35 #endif 36 #ifdef WLAN_POWER_MANAGEMENT_OFFLOAD 37 #include "wlan_pmo_hw_filter_public_struct.h" 38 #endif 39 #include <wlan_utility.h> 40 #ifdef WLAN_SUPPORT_GREEN_AP 41 #include "wlan_green_ap_api.h" 42 #endif 43 44 #include "wmi_unified_twt_api.h" 45 #include "wmi_unified_wds_api.h" 46 47 #ifdef WLAN_POLICY_MGR_ENABLE 48 #include "wlan_policy_mgr_public_struct.h" 49 #endif 50 51 #ifdef WMI_SMART_ANT_SUPPORT 52 #include "wmi_unified_smart_ant_api.h" 53 #endif 54 55 #ifdef WMI_DBR_SUPPORT 56 #include "wmi_unified_dbr_api.h" 57 #endif 58 59 #ifdef WMI_ATF_SUPPORT 60 #include "wmi_unified_atf_api.h" 61 #endif 62 63 #ifdef WMI_AP_SUPPORT 64 #include "wmi_unified_ap_api.h" 65 #endif 66 67 #include <wmi_unified_vdev_api.h> 68 #include <wmi_unified_vdev_tlv.h> 69 #include <wmi_unified_11be_tlv.h> 70 71 /* 72 * If FW supports WMI_SERVICE_SCAN_CONFIG_PER_CHANNEL, 73 * then channel_list may fill the upper 12 bits with channel flags, 74 * while using only the lower 20 bits for channel frequency. 75 * If FW doesn't support WMI_SERVICE_SCAN_CONFIG_PER_CHANNEL, 76 * then channel_list only holds the frequency value. 77 */ 78 #define CHAN_LIST_FLAG_MASK_POS 20 79 #define TARGET_SET_FREQ_IN_CHAN_LIST_TLV(buf, freq) \ 80 ((buf) |= ((freq) & WMI_SCAN_CHANNEL_FREQ_MASK)) 81 #define TARGET_SET_FLAGS_IN_CHAN_LIST_TLV(buf, flags) \ 82 ((buf) |= ((flags) << CHAN_LIST_FLAG_MASK_POS)) 83 84 /* HTC service ids for WMI for multi-radio */ 85 static const uint32_t multi_svc_ids[] = {WMI_CONTROL_SVC, 86 WMI_CONTROL_SVC_WMAC1, 87 WMI_CONTROL_SVC_WMAC2}; 88 89 #ifdef ENABLE_HOST_TO_TARGET_CONVERSION 90 /*Populate peer_param array whose index as host id and 91 *value as target id 92 */ 93 static const uint32_t peer_param_tlv[] = { 94 [WMI_HOST_PEER_MIMO_PS_STATE] = WMI_PEER_MIMO_PS_STATE, 95 [WMI_HOST_PEER_AMPDU] = WMI_PEER_AMPDU, 96 [WMI_HOST_PEER_AUTHORIZE] = WMI_PEER_AUTHORIZE, 97 [WMI_HOST_PEER_CHWIDTH] = WMI_PEER_CHWIDTH, 98 [WMI_HOST_PEER_NSS] = WMI_PEER_NSS, 99 [WMI_HOST_PEER_USE_4ADDR] = WMI_PEER_USE_4ADDR, 100 [WMI_HOST_PEER_MEMBERSHIP] = WMI_PEER_MEMBERSHIP, 101 [WMI_HOST_PEER_USERPOS] = WMI_PEER_USERPOS, 102 [WMI_HOST_PEER_CRIT_PROTO_HINT_ENABLED] = 103 WMI_PEER_CRIT_PROTO_HINT_ENABLED, 104 [WMI_HOST_PEER_TX_FAIL_CNT_THR] = WMI_PEER_TX_FAIL_CNT_THR, 105 [WMI_HOST_PEER_SET_HW_RETRY_CTS2S] = WMI_PEER_SET_HW_RETRY_CTS2S, 106 [WMI_HOST_PEER_IBSS_ATIM_WINDOW_LENGTH] = 107 WMI_PEER_IBSS_ATIM_WINDOW_LENGTH, 108 [WMI_HOST_PEER_PHYMODE] = WMI_PEER_PHYMODE, 109 [WMI_HOST_PEER_USE_FIXED_PWR] = WMI_PEER_USE_FIXED_PWR, 110 [WMI_HOST_PEER_PARAM_FIXED_RATE] = WMI_PEER_PARAM_FIXED_RATE, 111 [WMI_HOST_PEER_SET_MU_ALLOWLIST] = WMI_PEER_SET_MU_ALLOWLIST, 112 [WMI_HOST_PEER_SET_MAX_TX_RATE] = WMI_PEER_SET_MAX_TX_RATE, 113 [WMI_HOST_PEER_SET_MIN_TX_RATE] = WMI_PEER_SET_MIN_TX_RATE, 114 [WMI_HOST_PEER_SET_DEFAULT_ROUTING] = WMI_PEER_SET_DEFAULT_ROUTING, 115 [WMI_HOST_PEER_NSS_VHT160] = WMI_PEER_NSS_VHT160, 116 [WMI_HOST_PEER_NSS_VHT80_80] = WMI_PEER_NSS_VHT80_80, 117 [WMI_HOST_PEER_PARAM_SU_TXBF_SOUNDING_INTERVAL] = 118 WMI_PEER_PARAM_SU_TXBF_SOUNDING_INTERVAL, 119 [WMI_HOST_PEER_PARAM_MU_TXBF_SOUNDING_INTERVAL] = 120 WMI_PEER_PARAM_MU_TXBF_SOUNDING_INTERVAL, 121 [WMI_HOST_PEER_PARAM_TXBF_SOUNDING_ENABLE] = 122 WMI_PEER_PARAM_TXBF_SOUNDING_ENABLE, 123 [WMI_HOST_PEER_PARAM_MU_ENABLE] = WMI_PEER_PARAM_MU_ENABLE, 124 [WMI_HOST_PEER_PARAM_OFDMA_ENABLE] = WMI_PEER_PARAM_OFDMA_ENABLE, 125 [WMI_HOST_PEER_PARAM_ENABLE_FT] = WMI_PEER_PARAM_ENABLE_FT, 126 [WMI_HOST_PEER_CHWIDTH_PUNCTURE_20MHZ_BITMAP] = 127 WMI_PEER_CHWIDTH_PUNCTURE_20MHZ_BITMAP, 128 }; 129 130 #define PARAM_MAP(name, NAME) [wmi_ ## name] = WMI_ ##NAME 131 132 /* Populate pdev_param whose index is host param and value is target */ 133 static const uint32_t pdev_param_tlv[] = { 134 PARAM_MAP(pdev_param_tx_chain_mask, PDEV_PARAM_TX_CHAIN_MASK), 135 PARAM_MAP(pdev_param_rx_chain_mask, PDEV_PARAM_RX_CHAIN_MASK), 136 PARAM_MAP(pdev_param_txpower_limit2g, PDEV_PARAM_TXPOWER_LIMIT2G), 137 PARAM_MAP(pdev_param_txpower_limit5g, PDEV_PARAM_TXPOWER_LIMIT5G), 138 PARAM_MAP(pdev_param_txpower_scale, PDEV_PARAM_TXPOWER_SCALE), 139 PARAM_MAP(pdev_param_beacon_gen_mode, PDEV_PARAM_BEACON_GEN_MODE), 140 PARAM_MAP(pdev_param_beacon_tx_mode, PDEV_PARAM_BEACON_TX_MODE), 141 PARAM_MAP(pdev_param_resmgr_offchan_mode, 142 PDEV_PARAM_RESMGR_OFFCHAN_MODE), 143 PARAM_MAP(pdev_param_protection_mode, PDEV_PARAM_PROTECTION_MODE), 144 PARAM_MAP(pdev_param_dynamic_bw, PDEV_PARAM_DYNAMIC_BW), 145 PARAM_MAP(pdev_param_non_agg_sw_retry_th, 146 PDEV_PARAM_NON_AGG_SW_RETRY_TH), 147 PARAM_MAP(pdev_param_agg_sw_retry_th, PDEV_PARAM_AGG_SW_RETRY_TH), 148 PARAM_MAP(pdev_param_sta_kickout_th, PDEV_PARAM_STA_KICKOUT_TH), 149 PARAM_MAP(pdev_param_ac_aggrsize_scaling, 150 PDEV_PARAM_AC_AGGRSIZE_SCALING), 151 PARAM_MAP(pdev_param_ltr_enable, PDEV_PARAM_LTR_ENABLE), 152 PARAM_MAP(pdev_param_ltr_ac_latency_be, 153 PDEV_PARAM_LTR_AC_LATENCY_BE), 154 PARAM_MAP(pdev_param_ltr_ac_latency_bk, PDEV_PARAM_LTR_AC_LATENCY_BK), 155 PARAM_MAP(pdev_param_ltr_ac_latency_vi, PDEV_PARAM_LTR_AC_LATENCY_VI), 156 PARAM_MAP(pdev_param_ltr_ac_latency_vo, PDEV_PARAM_LTR_AC_LATENCY_VO), 157 PARAM_MAP(pdev_param_ltr_ac_latency_timeout, 158 PDEV_PARAM_LTR_AC_LATENCY_TIMEOUT), 159 PARAM_MAP(pdev_param_ltr_sleep_override, PDEV_PARAM_LTR_SLEEP_OVERRIDE), 160 PARAM_MAP(pdev_param_ltr_rx_override, PDEV_PARAM_LTR_RX_OVERRIDE), 161 PARAM_MAP(pdev_param_ltr_tx_activity_timeout, 162 PDEV_PARAM_LTR_TX_ACTIVITY_TIMEOUT), 163 PARAM_MAP(pdev_param_l1ss_enable, PDEV_PARAM_L1SS_ENABLE), 164 PARAM_MAP(pdev_param_dsleep_enable, PDEV_PARAM_DSLEEP_ENABLE), 165 PARAM_MAP(pdev_param_pcielp_txbuf_flush, PDEV_PARAM_PCIELP_TXBUF_FLUSH), 166 PARAM_MAP(pdev_param_pcielp_txbuf_watermark, 167 PDEV_PARAM_PCIELP_TXBUF_WATERMARK), 168 PARAM_MAP(pdev_param_pcielp_txbuf_tmo_en, 169 PDEV_PARAM_PCIELP_TXBUF_TMO_EN), 170 PARAM_MAP(pdev_param_pcielp_txbuf_tmo_value, 171 PDEV_PARAM_PCIELP_TXBUF_TMO_VALUE), 172 PARAM_MAP(pdev_param_pdev_stats_update_period, 173 PDEV_PARAM_PDEV_STATS_UPDATE_PERIOD), 174 PARAM_MAP(pdev_param_vdev_stats_update_period, 175 PDEV_PARAM_VDEV_STATS_UPDATE_PERIOD), 176 PARAM_MAP(pdev_param_peer_stats_update_period, 177 PDEV_PARAM_PEER_STATS_UPDATE_PERIOD), 178 PARAM_MAP(pdev_param_bcnflt_stats_update_period, 179 PDEV_PARAM_BCNFLT_STATS_UPDATE_PERIOD), 180 PARAM_MAP(pdev_param_pmf_qos, PDEV_PARAM_PMF_QOS), 181 PARAM_MAP(pdev_param_arp_ac_override, PDEV_PARAM_ARP_AC_OVERRIDE), 182 PARAM_MAP(pdev_param_dcs, PDEV_PARAM_DCS), 183 PARAM_MAP(pdev_param_ani_enable, PDEV_PARAM_ANI_ENABLE), 184 PARAM_MAP(pdev_param_ani_poll_period, PDEV_PARAM_ANI_POLL_PERIOD), 185 PARAM_MAP(pdev_param_ani_listen_period, PDEV_PARAM_ANI_LISTEN_PERIOD), 186 PARAM_MAP(pdev_param_ani_ofdm_level, PDEV_PARAM_ANI_OFDM_LEVEL), 187 PARAM_MAP(pdev_param_ani_cck_level, PDEV_PARAM_ANI_CCK_LEVEL), 188 PARAM_MAP(pdev_param_dyntxchain, PDEV_PARAM_DYNTXCHAIN), 189 PARAM_MAP(pdev_param_proxy_sta, PDEV_PARAM_PROXY_STA), 190 PARAM_MAP(pdev_param_idle_ps_config, PDEV_PARAM_IDLE_PS_CONFIG), 191 PARAM_MAP(pdev_param_power_gating_sleep, PDEV_PARAM_POWER_GATING_SLEEP), 192 PARAM_MAP(pdev_param_rfkill_enable, PDEV_PARAM_RFKILL_ENABLE), 193 PARAM_MAP(pdev_param_burst_dur, PDEV_PARAM_BURST_DUR), 194 PARAM_MAP(pdev_param_burst_enable, PDEV_PARAM_BURST_ENABLE), 195 PARAM_MAP(pdev_param_hw_rfkill_config, PDEV_PARAM_HW_RFKILL_CONFIG), 196 PARAM_MAP(pdev_param_low_power_rf_enable, 197 PDEV_PARAM_LOW_POWER_RF_ENABLE), 198 PARAM_MAP(pdev_param_l1ss_track, PDEV_PARAM_L1SS_TRACK), 199 PARAM_MAP(pdev_param_hyst_en, PDEV_PARAM_HYST_EN), 200 PARAM_MAP(pdev_param_power_collapse_enable, 201 PDEV_PARAM_POWER_COLLAPSE_ENABLE), 202 PARAM_MAP(pdev_param_led_sys_state, PDEV_PARAM_LED_SYS_STATE), 203 PARAM_MAP(pdev_param_led_enable, PDEV_PARAM_LED_ENABLE), 204 PARAM_MAP(pdev_param_audio_over_wlan_latency, 205 PDEV_PARAM_AUDIO_OVER_WLAN_LATENCY), 206 PARAM_MAP(pdev_param_audio_over_wlan_enable, 207 PDEV_PARAM_AUDIO_OVER_WLAN_ENABLE), 208 PARAM_MAP(pdev_param_whal_mib_stats_update_enable, 209 PDEV_PARAM_WHAL_MIB_STATS_UPDATE_ENABLE), 210 PARAM_MAP(pdev_param_vdev_rate_stats_update_period, 211 PDEV_PARAM_VDEV_RATE_STATS_UPDATE_PERIOD), 212 PARAM_MAP(pdev_param_cts_cbw, PDEV_PARAM_CTS_CBW), 213 PARAM_MAP(pdev_param_wnts_config, PDEV_PARAM_WNTS_CONFIG), 214 PARAM_MAP(pdev_param_adaptive_early_rx_enable, 215 PDEV_PARAM_ADAPTIVE_EARLY_RX_ENABLE), 216 PARAM_MAP(pdev_param_adaptive_early_rx_min_sleep_slop, 217 PDEV_PARAM_ADAPTIVE_EARLY_RX_MIN_SLEEP_SLOP), 218 PARAM_MAP(pdev_param_adaptive_early_rx_inc_dec_step, 219 PDEV_PARAM_ADAPTIVE_EARLY_RX_INC_DEC_STEP), 220 PARAM_MAP(pdev_param_early_rx_fix_sleep_slop, 221 PDEV_PARAM_EARLY_RX_FIX_SLEEP_SLOP), 222 PARAM_MAP(pdev_param_bmiss_based_adaptive_bto_enable, 223 PDEV_PARAM_BMISS_BASED_ADAPTIVE_BTO_ENABLE), 224 PARAM_MAP(pdev_param_bmiss_bto_min_bcn_timeout, 225 PDEV_PARAM_BMISS_BTO_MIN_BCN_TIMEOUT), 226 PARAM_MAP(pdev_param_bmiss_bto_inc_dec_step, 227 PDEV_PARAM_BMISS_BTO_INC_DEC_STEP), 228 PARAM_MAP(pdev_param_bto_fix_bcn_timeout, 229 PDEV_PARAM_BTO_FIX_BCN_TIMEOUT), 230 PARAM_MAP(pdev_param_ce_based_adaptive_bto_enable, 231 PDEV_PARAM_CE_BASED_ADAPTIVE_BTO_ENABLE), 232 PARAM_MAP(pdev_param_ce_bto_combo_ce_value, 233 PDEV_PARAM_CE_BTO_COMBO_CE_VALUE), 234 PARAM_MAP(pdev_param_tx_chain_mask_2g, PDEV_PARAM_TX_CHAIN_MASK_2G), 235 PARAM_MAP(pdev_param_rx_chain_mask_2g, PDEV_PARAM_RX_CHAIN_MASK_2G), 236 PARAM_MAP(pdev_param_tx_chain_mask_5g, PDEV_PARAM_TX_CHAIN_MASK_5G), 237 PARAM_MAP(pdev_param_rx_chain_mask_5g, PDEV_PARAM_RX_CHAIN_MASK_5G), 238 PARAM_MAP(pdev_param_tx_chain_mask_cck, PDEV_PARAM_TX_CHAIN_MASK_CCK), 239 PARAM_MAP(pdev_param_tx_chain_mask_1ss, PDEV_PARAM_TX_CHAIN_MASK_1SS), 240 PARAM_MAP(pdev_param_soft_tx_chain_mask, PDEV_PARAM_TX_CHAIN_MASK), 241 PARAM_MAP(pdev_param_rx_filter, PDEV_PARAM_RX_FILTER), 242 PARAM_MAP(pdev_set_mcast_to_ucast_tid, PDEV_SET_MCAST_TO_UCAST_TID), 243 PARAM_MAP(pdev_param_mgmt_retry_limit, PDEV_PARAM_MGMT_RETRY_LIMIT), 244 PARAM_MAP(pdev_param_aggr_burst, PDEV_PARAM_AGGR_BURST), 245 PARAM_MAP(pdev_peer_sta_ps_statechg_enable, 246 PDEV_PEER_STA_PS_STATECHG_ENABLE), 247 PARAM_MAP(pdev_param_proxy_sta_mode, PDEV_PARAM_PROXY_STA_MODE), 248 PARAM_MAP(pdev_param_mu_group_policy, PDEV_PARAM_MU_GROUP_POLICY), 249 PARAM_MAP(pdev_param_noise_detection, PDEV_PARAM_NOISE_DETECTION), 250 PARAM_MAP(pdev_param_noise_threshold, PDEV_PARAM_NOISE_THRESHOLD), 251 PARAM_MAP(pdev_param_dpd_enable, PDEV_PARAM_DPD_ENABLE), 252 PARAM_MAP(pdev_param_set_mcast_bcast_echo, 253 PDEV_PARAM_SET_MCAST_BCAST_ECHO), 254 PARAM_MAP(pdev_param_atf_strict_sch, PDEV_PARAM_ATF_STRICT_SCH), 255 PARAM_MAP(pdev_param_atf_sched_duration, PDEV_PARAM_ATF_SCHED_DURATION), 256 PARAM_MAP(pdev_param_ant_plzn, PDEV_PARAM_ANT_PLZN), 257 PARAM_MAP(pdev_param_sensitivity_level, PDEV_PARAM_SENSITIVITY_LEVEL), 258 PARAM_MAP(pdev_param_signed_txpower_2g, PDEV_PARAM_SIGNED_TXPOWER_2G), 259 PARAM_MAP(pdev_param_signed_txpower_5g, PDEV_PARAM_SIGNED_TXPOWER_5G), 260 PARAM_MAP(pdev_param_enable_per_tid_amsdu, 261 PDEV_PARAM_ENABLE_PER_TID_AMSDU), 262 PARAM_MAP(pdev_param_enable_per_tid_ampdu, 263 PDEV_PARAM_ENABLE_PER_TID_AMPDU), 264 PARAM_MAP(pdev_param_cca_threshold, PDEV_PARAM_CCA_THRESHOLD), 265 PARAM_MAP(pdev_param_rts_fixed_rate, PDEV_PARAM_RTS_FIXED_RATE), 266 PARAM_MAP(pdev_param_cal_period, UNAVAILABLE_PARAM), 267 PARAM_MAP(pdev_param_pdev_reset, PDEV_PARAM_PDEV_RESET), 268 PARAM_MAP(pdev_param_wapi_mbssid_offset, PDEV_PARAM_WAPI_MBSSID_OFFSET), 269 PARAM_MAP(pdev_param_arp_srcaddr, PDEV_PARAM_ARP_DBG_SRCADDR), 270 PARAM_MAP(pdev_param_arp_dstaddr, PDEV_PARAM_ARP_DBG_DSTADDR), 271 PARAM_MAP(pdev_param_txpower_decr_db, PDEV_PARAM_TXPOWER_DECR_DB), 272 PARAM_MAP(pdev_param_rx_batchmode, UNAVAILABLE_PARAM), 273 PARAM_MAP(pdev_param_packet_aggr_delay, UNAVAILABLE_PARAM), 274 PARAM_MAP(pdev_param_atf_obss_noise_sch, PDEV_PARAM_ATF_OBSS_NOISE_SCH), 275 PARAM_MAP(pdev_param_atf_obss_noise_scaling_factor, 276 PDEV_PARAM_ATF_OBSS_NOISE_SCALING_FACTOR), 277 PARAM_MAP(pdev_param_cust_txpower_scale, PDEV_PARAM_CUST_TXPOWER_SCALE), 278 PARAM_MAP(pdev_param_atf_dynamic_enable, PDEV_PARAM_ATF_DYNAMIC_ENABLE), 279 PARAM_MAP(pdev_param_atf_ssid_group_policy, UNAVAILABLE_PARAM), 280 PARAM_MAP(pdev_param_igmpmld_override, PDEV_PARAM_IGMPMLD_AC_OVERRIDE), 281 PARAM_MAP(pdev_param_igmpmld_tid, PDEV_PARAM_IGMPMLD_AC_OVERRIDE), 282 PARAM_MAP(pdev_param_antenna_gain, PDEV_PARAM_ANTENNA_GAIN), 283 PARAM_MAP(pdev_param_block_interbss, PDEV_PARAM_BLOCK_INTERBSS), 284 PARAM_MAP(pdev_param_set_disable_reset_cmdid, 285 PDEV_PARAM_SET_DISABLE_RESET_CMDID), 286 PARAM_MAP(pdev_param_set_msdu_ttl_cmdid, PDEV_PARAM_SET_MSDU_TTL_CMDID), 287 PARAM_MAP(pdev_param_txbf_sound_period_cmdid, 288 PDEV_PARAM_TXBF_SOUND_PERIOD_CMDID), 289 PARAM_MAP(pdev_param_set_burst_mode_cmdid, 290 PDEV_PARAM_SET_BURST_MODE_CMDID), 291 PARAM_MAP(pdev_param_en_stats, PDEV_PARAM_EN_STATS), 292 PARAM_MAP(pdev_param_mesh_mcast_enable, PDEV_PARAM_MESH_MCAST_ENABLE), 293 PARAM_MAP(pdev_param_set_promisc_mode_cmdid, 294 PDEV_PARAM_SET_PROMISC_MODE_CMDID), 295 PARAM_MAP(pdev_param_set_ppdu_duration_cmdid, 296 PDEV_PARAM_SET_PPDU_DURATION_CMDID), 297 PARAM_MAP(pdev_param_remove_mcast2ucast_buffer, 298 PDEV_PARAM_REMOVE_MCAST2UCAST_BUFFER), 299 PARAM_MAP(pdev_param_set_mcast2ucast_buffer, 300 PDEV_PARAM_SET_MCAST2UCAST_BUFFER), 301 PARAM_MAP(pdev_param_set_mcast2ucast_mode, 302 PDEV_PARAM_SET_MCAST2UCAST_MODE), 303 PARAM_MAP(pdev_param_smart_antenna_default_antenna, 304 PDEV_PARAM_SMART_ANTENNA_DEFAULT_ANTENNA), 305 PARAM_MAP(pdev_param_fast_channel_reset, 306 PDEV_PARAM_FAST_CHANNEL_RESET), 307 PARAM_MAP(pdev_param_rx_decap_mode, PDEV_PARAM_RX_DECAP_MODE), 308 PARAM_MAP(pdev_param_tx_ack_timeout, PDEV_PARAM_ACK_TIMEOUT), 309 PARAM_MAP(pdev_param_cck_tx_enable, PDEV_PARAM_CCK_TX_ENABLE), 310 PARAM_MAP(pdev_param_antenna_gain_half_db, 311 PDEV_PARAM_ANTENNA_GAIN_HALF_DB), 312 PARAM_MAP(pdev_param_esp_indication_period, 313 PDEV_PARAM_ESP_INDICATION_PERIOD), 314 PARAM_MAP(pdev_param_esp_ba_window, PDEV_PARAM_ESP_BA_WINDOW), 315 PARAM_MAP(pdev_param_esp_airtime_fraction, 316 PDEV_PARAM_ESP_AIRTIME_FRACTION), 317 PARAM_MAP(pdev_param_esp_ppdu_duration, PDEV_PARAM_ESP_PPDU_DURATION), 318 PARAM_MAP(pdev_param_ru26_allowed, PDEV_PARAM_UL_RU26_ALLOWED), 319 PARAM_MAP(pdev_param_use_nol, PDEV_PARAM_USE_NOL), 320 PARAM_MAP(pdev_param_ul_trig_int, PDEV_PARAM_SET_UL_BSR_TRIG_INTERVAL), 321 PARAM_MAP(pdev_param_sub_channel_marking, 322 PDEV_PARAM_SUB_CHANNEL_MARKING), 323 PARAM_MAP(pdev_param_ul_ppdu_duration, PDEV_PARAM_SET_UL_PPDU_DURATION), 324 PARAM_MAP(pdev_param_equal_ru_allocation_enable, 325 PDEV_PARAM_EQUAL_RU_ALLOCATION_ENABLE), 326 PARAM_MAP(pdev_param_per_peer_prd_cfr_enable, 327 PDEV_PARAM_PER_PEER_PERIODIC_CFR_ENABLE), 328 PARAM_MAP(pdev_param_nav_override_config, 329 PDEV_PARAM_NAV_OVERRIDE_CONFIG), 330 PARAM_MAP(pdev_param_set_mgmt_ttl, PDEV_PARAM_SET_MGMT_TTL), 331 PARAM_MAP(pdev_param_set_prb_rsp_ttl, 332 PDEV_PARAM_SET_PROBE_RESP_TTL), 333 PARAM_MAP(pdev_param_set_mu_ppdu_duration, 334 PDEV_PARAM_SET_MU_PPDU_DURATION), 335 PARAM_MAP(pdev_param_set_tbtt_ctrl, 336 PDEV_PARAM_SET_TBTT_CTRL), 337 PARAM_MAP(pdev_param_set_cmd_obss_pd_threshold, 338 PDEV_PARAM_SET_CMD_OBSS_PD_THRESHOLD), 339 PARAM_MAP(pdev_param_set_cmd_obss_pd_per_ac, 340 PDEV_PARAM_SET_CMD_OBSS_PD_PER_AC), 341 PARAM_MAP(pdev_param_set_cong_ctrl_max_msdus, 342 PDEV_PARAM_SET_CONG_CTRL_MAX_MSDUS), 343 PARAM_MAP(pdev_param_enable_fw_dynamic_he_edca, 344 PDEV_PARAM_ENABLE_FW_DYNAMIC_HE_EDCA), 345 PARAM_MAP(pdev_param_enable_srp, PDEV_PARAM_ENABLE_SRP), 346 PARAM_MAP(pdev_param_enable_sr_prohibit, PDEV_PARAM_ENABLE_SR_PROHIBIT), 347 PARAM_MAP(pdev_param_sr_trigger_margin, PDEV_PARAM_SR_TRIGGER_MARGIN), 348 PARAM_MAP(pdev_param_pream_punct_bw, PDEV_PARAM_SET_PREAM_PUNCT_BW), 349 PARAM_MAP(pdev_param_enable_mbssid_ctrl_frame, 350 PDEV_PARAM_ENABLE_MBSSID_CTRL_FRAME), 351 PARAM_MAP(pdev_param_set_mesh_params, PDEV_PARAM_SET_MESH_PARAMS), 352 PARAM_MAP(pdev_param_mpd_userpd_ssr, PDEV_PARAM_MPD_USERPD_SSR), 353 PARAM_MAP(pdev_param_low_latency_mode, 354 PDEV_PARAM_LOW_LATENCY_SCHED_MODE), 355 PARAM_MAP(pdev_param_scan_radio_tx_on_dfs, 356 PDEV_PARAM_SCAN_RADIO_TX_ON_DFS), 357 PARAM_MAP(pdev_param_en_probe_all_bw, 358 PDEV_PARAM_EN_PROBE_ALL_BW), 359 PARAM_MAP(pdev_param_obss_min_duration_check_for_sr, 360 PDEV_PARAM_OBSS_MIN_DURATION_CHECK_FOR_SR), 361 PARAM_MAP(pdev_param_truncate_sr, PDEV_PARAM_TRUNCATE_SR), 362 PARAM_MAP(pdev_param_ctrl_frame_obss_pd_threshold, 363 PDEV_PARAM_CTRL_FRAME_OBSS_PD_THRESHOLD), 364 PARAM_MAP(pdev_param_rate_upper_cap, PDEV_PARAM_RATE_UPPER_CAP), 365 PARAM_MAP(pdev_param_rate_retry_mcs_drop, 366 PDEV_PARAM_SET_RATE_DROP_DOWN_RETRY_THRESH), 367 PARAM_MAP(pdev_param_mcs_probe_intvl, 368 PDEV_PARAM_MIN_MAX_MCS_PROBE_INTERVAL), 369 PARAM_MAP(pdev_param_nss_probe_intvl, 370 PDEV_PARAM_MIN_MAX_NSS_PROBE_INTERVAL), 371 PARAM_MAP(pdev_param_dtim_synth, PDEV_PARAM_DTIM_SYNTH), 372 PARAM_MAP(pdev_param_1ch_dtim_optimized_chain_selection, 373 PDEV_PARAM_1CH_DTIM_OPTIMIZED_CHAIN_SELECTION), 374 PARAM_MAP(pdev_param_tx_sch_delay, PDEV_PARAM_TX_SCH_DELAY), 375 PARAM_MAP(pdev_param_en_update_scram_seed, 376 PDEV_PARAM_EN_UPDATE_SCRAM_SEED), 377 PARAM_MAP(pdev_param_secondary_retry_enable, 378 PDEV_PARAM_SECONDARY_RETRY_ENABLE), 379 PARAM_MAP(pdev_param_set_sap_xlna_bypass, 380 PDEV_PARAM_SET_SAP_XLNA_BYPASS), 381 PARAM_MAP(pdev_param_set_dfs_chan_ageout_time, 382 PDEV_PARAM_SET_DFS_CHAN_AGEOUT_TIME), 383 PARAM_MAP(pdev_param_pdev_stats_tx_xretry_ext, 384 PDEV_PARAM_PDEV_STATS_TX_XRETRY_EXT), 385 PARAM_MAP(pdev_param_smart_chainmask_scheme, 386 PDEV_PARAM_SMART_CHAINMASK_SCHEME), 387 PARAM_MAP(pdev_param_alternative_chainmask_scheme, 388 PDEV_PARAM_ALTERNATIVE_CHAINMASK_SCHEME), 389 PARAM_MAP(pdev_param_enable_rts_sifs_bursting, 390 PDEV_PARAM_ENABLE_RTS_SIFS_BURSTING), 391 PARAM_MAP(pdev_param_max_mpdus_in_ampdu, PDEV_PARAM_MAX_MPDUS_IN_AMPDU), 392 PARAM_MAP(pdev_param_set_iot_pattern, PDEV_PARAM_SET_IOT_PATTERN), 393 PARAM_MAP(pdev_param_mwscoex_scc_chavd_delay, 394 PDEV_PARAM_MWSCOEX_SCC_CHAVD_DELAY), 395 PARAM_MAP(pdev_param_mwscoex_pcc_chavd_delay, 396 PDEV_PARAM_MWSCOEX_PCC_CHAVD_DELAY), 397 PARAM_MAP(pdev_param_mwscoex_set_5gnr_pwr_limit, 398 PDEV_PARAM_MWSCOEX_SET_5GNR_PWR_LIMIT), 399 PARAM_MAP(pdev_param_mwscoex_4g_allow_quick_ftdm, 400 PDEV_PARAM_MWSCOEX_4G_ALLOW_QUICK_FTDM), 401 PARAM_MAP(pdev_param_fast_pwr_transition, 402 PDEV_PARAM_FAST_PWR_TRANSITION), 403 PARAM_MAP(pdev_auto_detect_power_failure, 404 PDEV_AUTO_DETECT_POWER_FAILURE), 405 PARAM_MAP(pdev_param_gcmp_support_enable, 406 PDEV_PARAM_GCMP_SUPPORT_ENABLE), 407 PARAM_MAP(pdev_param_abg_mode_tx_chain_num, 408 PDEV_PARAM_ABG_MODE_TX_CHAIN_NUM), 409 PARAM_MAP(pdev_param_peer_stats_info_enable, 410 PDEV_PARAM_PEER_STATS_INFO_ENABLE), 411 PARAM_MAP(pdev_param_enable_cck_txfir_override, 412 PDEV_PARAM_ENABLE_CCK_TXFIR_OVERRIDE), 413 PARAM_MAP(pdev_param_twt_ac_config, PDEV_PARAM_TWT_AC_CONFIG), 414 PARAM_MAP(pdev_param_pcie_hw_ilp, PDEV_PARAM_PCIE_HW_ILP), 415 PARAM_MAP(pdev_param_disable_hw_assist, PDEV_PARAM_DISABLE_HW_ASSIST), 416 PARAM_MAP(pdev_param_ant_div_usrcfg, PDEV_PARAM_ANT_DIV_USRCFG), 417 PARAM_MAP(pdev_param_ctrl_retry_limit, PDEV_PARAM_CTRL_RETRY_LIMIT), 418 PARAM_MAP(pdev_param_propagation_delay, PDEV_PARAM_PROPAGATION_DELAY), 419 PARAM_MAP(pdev_param_ena_ant_div, PDEV_PARAM_ENA_ANT_DIV), 420 PARAM_MAP(pdev_param_force_chain_ant, PDEV_PARAM_FORCE_CHAIN_ANT), 421 PARAM_MAP(pdev_param_ant_div_selftest, PDEV_PARAM_ANT_DIV_SELFTEST), 422 PARAM_MAP(pdev_param_ant_div_selftest_intvl, 423 PDEV_PARAM_ANT_DIV_SELFTEST_INTVL), 424 PARAM_MAP(pdev_param_1ch_dtim_optimized_chain_selection, 425 PDEV_PARAM_1CH_DTIM_OPTIMIZED_CHAIN_SELECTION), 426 PARAM_MAP(pdev_param_data_stall_detect_enable, 427 PDEV_PARAM_DATA_STALL_DETECT_ENABLE), 428 PARAM_MAP(pdev_param_max_mpdus_in_ampdu, 429 PDEV_PARAM_MAX_MPDUS_IN_AMPDU), 430 PARAM_MAP(pdev_param_stats_observation_period, 431 PDEV_PARAM_STATS_OBSERVATION_PERIOD), 432 PARAM_MAP(pdev_param_cts2self_for_p2p_go_config, 433 PDEV_PARAM_CTS2SELF_FOR_P2P_GO_CONFIG), 434 PARAM_MAP(pdev_param_txpower_reason_sar, PDEV_PARAM_TXPOWER_REASON_SAR), 435 PARAM_MAP(pdev_param_default_6ghz_rate, PDEV_PARAM_DEFAULT_6GHZ_RATE), 436 }; 437 438 /* Populate vdev_param array whose index is host param, value is target param */ 439 static const uint32_t vdev_param_tlv[] = { 440 PARAM_MAP(vdev_param_rts_threshold, VDEV_PARAM_RTS_THRESHOLD), 441 PARAM_MAP(vdev_param_fragmentation_threshold, 442 VDEV_PARAM_FRAGMENTATION_THRESHOLD), 443 PARAM_MAP(vdev_param_beacon_interval, VDEV_PARAM_BEACON_INTERVAL), 444 PARAM_MAP(vdev_param_listen_interval, VDEV_PARAM_LISTEN_INTERVAL), 445 PARAM_MAP(vdev_param_multicast_rate, VDEV_PARAM_MULTICAST_RATE), 446 PARAM_MAP(vdev_param_mgmt_tx_rate, VDEV_PARAM_MGMT_TX_RATE), 447 PARAM_MAP(vdev_param_slot_time, VDEV_PARAM_SLOT_TIME), 448 PARAM_MAP(vdev_param_preamble, VDEV_PARAM_PREAMBLE), 449 PARAM_MAP(vdev_param_swba_time, VDEV_PARAM_SWBA_TIME), 450 PARAM_MAP(vdev_stats_update_period, VDEV_STATS_UPDATE_PERIOD), 451 PARAM_MAP(vdev_pwrsave_ageout_time, VDEV_PWRSAVE_AGEOUT_TIME), 452 PARAM_MAP(vdev_host_swba_interval, VDEV_HOST_SWBA_INTERVAL), 453 PARAM_MAP(vdev_param_dtim_period, VDEV_PARAM_DTIM_PERIOD), 454 PARAM_MAP(vdev_oc_scheduler_air_time_limit, 455 VDEV_OC_SCHEDULER_AIR_TIME_LIMIT), 456 PARAM_MAP(vdev_param_wds, VDEV_PARAM_WDS), 457 PARAM_MAP(vdev_param_atim_window, VDEV_PARAM_ATIM_WINDOW), 458 PARAM_MAP(vdev_param_bmiss_count_max, VDEV_PARAM_BMISS_COUNT_MAX), 459 PARAM_MAP(vdev_param_bmiss_first_bcnt, VDEV_PARAM_BMISS_FIRST_BCNT), 460 PARAM_MAP(vdev_param_bmiss_final_bcnt, VDEV_PARAM_BMISS_FINAL_BCNT), 461 PARAM_MAP(vdev_param_feature_wmm, VDEV_PARAM_FEATURE_WMM), 462 PARAM_MAP(vdev_param_chwidth, VDEV_PARAM_CHWIDTH), 463 PARAM_MAP(vdev_param_chextoffset, VDEV_PARAM_CHEXTOFFSET), 464 PARAM_MAP(vdev_param_disable_htprotection, 465 VDEV_PARAM_DISABLE_HTPROTECTION), 466 PARAM_MAP(vdev_param_sta_quickkickout, VDEV_PARAM_STA_QUICKKICKOUT), 467 PARAM_MAP(vdev_param_mgmt_rate, VDEV_PARAM_MGMT_RATE), 468 PARAM_MAP(vdev_param_protection_mode, VDEV_PARAM_PROTECTION_MODE), 469 PARAM_MAP(vdev_param_fixed_rate, VDEV_PARAM_FIXED_RATE), 470 PARAM_MAP(vdev_param_sgi, VDEV_PARAM_SGI), 471 PARAM_MAP(vdev_param_ldpc, VDEV_PARAM_LDPC), 472 PARAM_MAP(vdev_param_tx_stbc, VDEV_PARAM_TX_STBC), 473 PARAM_MAP(vdev_param_rx_stbc, VDEV_PARAM_RX_STBC), 474 PARAM_MAP(vdev_param_intra_bss_fwd, VDEV_PARAM_INTRA_BSS_FWD), 475 PARAM_MAP(vdev_param_def_keyid, VDEV_PARAM_DEF_KEYID), 476 PARAM_MAP(vdev_param_nss, VDEV_PARAM_NSS), 477 PARAM_MAP(vdev_param_bcast_data_rate, VDEV_PARAM_BCAST_DATA_RATE), 478 PARAM_MAP(vdev_param_mcast_data_rate, VDEV_PARAM_MCAST_DATA_RATE), 479 PARAM_MAP(vdev_param_mcast_indicate, VDEV_PARAM_MCAST_INDICATE), 480 PARAM_MAP(vdev_param_dhcp_indicate, VDEV_PARAM_DHCP_INDICATE), 481 PARAM_MAP(vdev_param_unknown_dest_indicate, 482 VDEV_PARAM_UNKNOWN_DEST_INDICATE), 483 PARAM_MAP(vdev_param_ap_keepalive_min_idle_inactive_time_secs, 484 VDEV_PARAM_AP_KEEPALIVE_MIN_IDLE_INACTIVE_TIME_SECS), 485 PARAM_MAP(vdev_param_ap_keepalive_max_idle_inactive_time_secs, 486 VDEV_PARAM_AP_KEEPALIVE_MAX_IDLE_INACTIVE_TIME_SECS), 487 PARAM_MAP(vdev_param_ap_keepalive_max_unresponsive_time_secs, 488 VDEV_PARAM_AP_KEEPALIVE_MAX_UNRESPONSIVE_TIME_SECS), 489 PARAM_MAP(vdev_param_ap_enable_nawds, VDEV_PARAM_AP_ENABLE_NAWDS), 490 PARAM_MAP(vdev_param_enable_rtscts, VDEV_PARAM_ENABLE_RTSCTS), 491 PARAM_MAP(vdev_param_txbf, VDEV_PARAM_TXBF), 492 PARAM_MAP(vdev_param_packet_powersave, VDEV_PARAM_PACKET_POWERSAVE), 493 PARAM_MAP(vdev_param_drop_unencry, VDEV_PARAM_DROP_UNENCRY), 494 PARAM_MAP(vdev_param_tx_encap_type, VDEV_PARAM_TX_ENCAP_TYPE), 495 PARAM_MAP(vdev_param_ap_detect_out_of_sync_sleeping_sta_time_secs, 496 VDEV_PARAM_AP_DETECT_OUT_OF_SYNC_SLEEPING_STA_TIME_SECS), 497 PARAM_MAP(vdev_param_early_rx_adjust_enable, 498 VDEV_PARAM_EARLY_RX_ADJUST_ENABLE), 499 PARAM_MAP(vdev_param_early_rx_tgt_bmiss_num, 500 VDEV_PARAM_EARLY_RX_TGT_BMISS_NUM), 501 PARAM_MAP(vdev_param_early_rx_bmiss_sample_cycle, 502 VDEV_PARAM_EARLY_RX_BMISS_SAMPLE_CYCLE), 503 PARAM_MAP(vdev_param_early_rx_slop_step, VDEV_PARAM_EARLY_RX_SLOP_STEP), 504 PARAM_MAP(vdev_param_early_rx_init_slop, VDEV_PARAM_EARLY_RX_INIT_SLOP), 505 PARAM_MAP(vdev_param_early_rx_adjust_pause, 506 VDEV_PARAM_EARLY_RX_ADJUST_PAUSE), 507 PARAM_MAP(vdev_param_tx_pwrlimit, VDEV_PARAM_TX_PWRLIMIT), 508 PARAM_MAP(vdev_param_snr_num_for_cal, VDEV_PARAM_SNR_NUM_FOR_CAL), 509 PARAM_MAP(vdev_param_roam_fw_offload, VDEV_PARAM_ROAM_FW_OFFLOAD), 510 PARAM_MAP(vdev_param_enable_rmc, VDEV_PARAM_ENABLE_RMC), 511 PARAM_MAP(vdev_param_ibss_max_bcn_lost_ms, 512 VDEV_PARAM_IBSS_MAX_BCN_LOST_MS), 513 PARAM_MAP(vdev_param_max_rate, VDEV_PARAM_MAX_RATE), 514 PARAM_MAP(vdev_param_early_rx_drift_sample, 515 VDEV_PARAM_EARLY_RX_DRIFT_SAMPLE), 516 PARAM_MAP(vdev_param_set_ibss_tx_fail_cnt_thr, 517 VDEV_PARAM_SET_IBSS_TX_FAIL_CNT_THR), 518 PARAM_MAP(vdev_param_ebt_resync_timeout, 519 VDEV_PARAM_EBT_RESYNC_TIMEOUT), 520 PARAM_MAP(vdev_param_aggr_trig_event_enable, 521 VDEV_PARAM_AGGR_TRIG_EVENT_ENABLE), 522 PARAM_MAP(vdev_param_is_ibss_power_save_allowed, 523 VDEV_PARAM_IS_IBSS_POWER_SAVE_ALLOWED), 524 PARAM_MAP(vdev_param_is_power_collapse_allowed, 525 VDEV_PARAM_IS_POWER_COLLAPSE_ALLOWED), 526 PARAM_MAP(vdev_param_is_awake_on_txrx_enabled, 527 VDEV_PARAM_IS_AWAKE_ON_TXRX_ENABLED), 528 PARAM_MAP(vdev_param_inactivity_cnt, VDEV_PARAM_INACTIVITY_CNT), 529 PARAM_MAP(vdev_param_txsp_end_inactivity_time_ms, 530 VDEV_PARAM_TXSP_END_INACTIVITY_TIME_MS), 531 PARAM_MAP(vdev_param_dtim_policy, VDEV_PARAM_DTIM_POLICY), 532 PARAM_MAP(vdev_param_ibss_ps_warmup_time_secs, 533 VDEV_PARAM_IBSS_PS_WARMUP_TIME_SECS), 534 PARAM_MAP(vdev_param_ibss_ps_1rx_chain_in_atim_window_enable, 535 VDEV_PARAM_IBSS_PS_1RX_CHAIN_IN_ATIM_WINDOW_ENABLE), 536 PARAM_MAP(vdev_param_rx_leak_window, VDEV_PARAM_RX_LEAK_WINDOW), 537 PARAM_MAP(vdev_param_stats_avg_factor, 538 VDEV_PARAM_STATS_AVG_FACTOR), 539 PARAM_MAP(vdev_param_disconnect_th, VDEV_PARAM_DISCONNECT_TH), 540 PARAM_MAP(vdev_param_rtscts_rate, VDEV_PARAM_RTSCTS_RATE), 541 PARAM_MAP(vdev_param_mcc_rtscts_protection_enable, 542 VDEV_PARAM_MCC_RTSCTS_PROTECTION_ENABLE), 543 PARAM_MAP(vdev_param_mcc_broadcast_probe_enable, 544 VDEV_PARAM_MCC_BROADCAST_PROBE_ENABLE), 545 PARAM_MAP(vdev_param_mgmt_tx_power, VDEV_PARAM_MGMT_TX_POWER), 546 PARAM_MAP(vdev_param_beacon_rate, VDEV_PARAM_BEACON_RATE), 547 PARAM_MAP(vdev_param_rx_decap_type, VDEV_PARAM_RX_DECAP_TYPE), 548 PARAM_MAP(vdev_param_he_dcm_enable, VDEV_PARAM_HE_DCM), 549 PARAM_MAP(vdev_param_he_range_ext_enable, VDEV_PARAM_HE_RANGE_EXT), 550 PARAM_MAP(vdev_param_he_bss_color, VDEV_PARAM_BSS_COLOR), 551 PARAM_MAP(vdev_param_set_hemu_mode, VDEV_PARAM_SET_HEMU_MODE), 552 PARAM_MAP(vdev_param_set_he_sounding_mode, 553 VDEV_PARAM_SET_HE_SOUNDING_MODE), 554 PARAM_MAP(vdev_param_set_heop, VDEV_PARAM_HEOPS_0_31), 555 PARAM_MAP(vdev_param_set_ehtop, VDEV_PARAM_EHTOPS_0_31), 556 PARAM_MAP(vdev_param_set_eht_mu_mode, VDEV_PARAM_SET_EHT_MU_MODE), 557 PARAM_MAP(vdev_param_set_eht_puncturing_mode, 558 VDEV_PARAM_SET_EHT_PUNCTURING_MODE), 559 PARAM_MAP(vdev_param_set_eht_ltf, VDEV_PARAM_EHT_LTF), 560 PARAM_MAP(vdev_param_set_ul_eht_ltf, VDEV_PARAM_UL_EHT_LTF), 561 PARAM_MAP(vdev_param_set_eht_dcm, VDEV_PARAM_EHT_DCM), 562 PARAM_MAP(vdev_param_set_eht_range_ext, VDEV_PARAM_EHT_RANGE_EXT), 563 PARAM_MAP(vdev_param_set_non_data_eht_range_ext, 564 VDEV_PARAM_NON_DATA_EHT_RANGE_EXT), 565 PARAM_MAP(vdev_param_sensor_ap, VDEV_PARAM_SENSOR_AP), 566 PARAM_MAP(vdev_param_dtim_enable_cts, VDEV_PARAM_DTIM_ENABLE_CTS), 567 PARAM_MAP(vdev_param_atf_ssid_sched_policy, 568 VDEV_PARAM_ATF_SSID_SCHED_POLICY), 569 PARAM_MAP(vdev_param_disable_dyn_bw_rts, VDEV_PARAM_DISABLE_DYN_BW_RTS), 570 PARAM_MAP(vdev_param_mcast2ucast_set, VDEV_PARAM_MCAST2UCAST_SET), 571 PARAM_MAP(vdev_param_rc_num_retries, VDEV_PARAM_RC_NUM_RETRIES), 572 PARAM_MAP(vdev_param_cabq_maxdur, VDEV_PARAM_CABQ_MAXDUR), 573 PARAM_MAP(vdev_param_mfptest_set, VDEV_PARAM_MFPTEST_SET), 574 PARAM_MAP(vdev_param_rts_fixed_rate, VDEV_PARAM_RTS_FIXED_RATE), 575 PARAM_MAP(vdev_param_vht_sgimask, VDEV_PARAM_VHT_SGIMASK), 576 PARAM_MAP(vdev_param_vht80_ratemask, VDEV_PARAM_VHT80_RATEMASK), 577 PARAM_MAP(vdev_param_proxy_sta, VDEV_PARAM_PROXY_STA), 578 PARAM_MAP(vdev_param_bw_nss_ratemask, VDEV_PARAM_BW_NSS_RATEMASK), 579 PARAM_MAP(vdev_param_set_he_ltf, VDEV_PARAM_HE_LTF), 580 PARAM_MAP(vdev_param_disable_cabq, VDEV_PARAM_DISABLE_CABQ), 581 PARAM_MAP(vdev_param_rate_dropdown_bmap, VDEV_PARAM_RATE_DROPDOWN_BMAP), 582 PARAM_MAP(vdev_param_set_ba_mode, VDEV_PARAM_BA_MODE), 583 PARAM_MAP(vdev_param_capabilities, VDEV_PARAM_CAPABILITIES), 584 PARAM_MAP(vdev_param_autorate_misc_cfg, VDEV_PARAM_AUTORATE_MISC_CFG), 585 PARAM_MAP(vdev_param_ul_shortgi, VDEV_PARAM_UL_GI), 586 PARAM_MAP(vdev_param_ul_he_ltf, VDEV_PARAM_UL_HE_LTF), 587 PARAM_MAP(vdev_param_ul_nss, VDEV_PARAM_UL_NSS), 588 PARAM_MAP(vdev_param_ul_ppdu_bw, VDEV_PARAM_UL_PPDU_BW), 589 PARAM_MAP(vdev_param_ul_ldpc, VDEV_PARAM_UL_LDPC), 590 PARAM_MAP(vdev_param_ul_stbc, VDEV_PARAM_UL_STBC), 591 PARAM_MAP(vdev_param_ul_fixed_rate, VDEV_PARAM_UL_FIXED_RATE), 592 PARAM_MAP(vdev_param_rawmode_open_war, VDEV_PARAM_RAW_IS_ENCRYPTED), 593 PARAM_MAP(vdev_param_max_mtu_size, VDEV_PARAM_MAX_MTU_SIZE), 594 PARAM_MAP(vdev_param_mcast_rc_stale_period, 595 VDEV_PARAM_MCAST_RC_STALE_PERIOD), 596 PARAM_MAP(vdev_param_enable_multi_group_key, 597 VDEV_PARAM_ENABLE_MULTI_GROUP_KEY), 598 PARAM_MAP(vdev_param_max_group_keys, VDEV_PARAM_NUM_GROUP_KEYS), 599 PARAM_MAP(vdev_param_enable_mcast_rc, VDEV_PARAM_ENABLE_MCAST_RC), 600 PARAM_MAP(vdev_param_6ghz_params, VDEV_PARAM_6GHZ_PARAMS), 601 PARAM_MAP(vdev_param_enable_disable_roam_reason_vsie, 602 VDEV_PARAM_ENABLE_DISABLE_ROAM_REASON_VSIE), 603 PARAM_MAP(vdev_param_set_cmd_obss_pd_threshold, 604 VDEV_PARAM_SET_CMD_OBSS_PD_THRESHOLD), 605 PARAM_MAP(vdev_param_set_cmd_obss_pd_per_ac, 606 VDEV_PARAM_SET_CMD_OBSS_PD_PER_AC), 607 PARAM_MAP(vdev_param_enable_srp, VDEV_PARAM_ENABLE_SRP), 608 PARAM_MAP(vdev_param_nan_config_features, 609 VDEV_PARAM_ENABLE_DISABLE_NAN_CONFIG_FEATURES), 610 PARAM_MAP(vdev_param_enable_disable_rtt_responder_role, 611 VDEV_PARAM_ENABLE_DISABLE_RTT_RESPONDER_ROLE), 612 PARAM_MAP(vdev_param_enable_disable_rtt_initiator_role, 613 VDEV_PARAM_ENABLE_DISABLE_RTT_INITIATOR_ROLE), 614 PARAM_MAP(vdev_param_mcast_steer, VDEV_PARAM_MCAST_STEERING), 615 PARAM_MAP(vdev_param_set_normal_latency_flags_config, 616 VDEV_PARAM_NORMAL_LATENCY_FLAGS_CONFIGURATION), 617 PARAM_MAP(vdev_param_set_xr_latency_flags_config, 618 VDEV_PARAM_XR_LATENCY_FLAGS_CONFIGURATION), 619 PARAM_MAP(vdev_param_set_low_latency_flags_config, 620 VDEV_PARAM_LOW_LATENCY_FLAGS_CONFIGURATION), 621 PARAM_MAP(vdev_param_set_ultra_low_latency_flags_config, 622 VDEV_PARAM_ULTRA_LOW_LATENCY_FLAGS_CONFIGURATION), 623 PARAM_MAP(vdev_param_set_normal_latency_ul_dl_config, 624 VDEV_PARAM_NORMAL_LATENCY_UL_DL_CONFIGURATION), 625 PARAM_MAP(vdev_param_set_xr_latency_ul_dl_config, 626 VDEV_PARAM_XR_LATENCY_UL_DL_CONFIGURATION), 627 PARAM_MAP(vdev_param_set_low_latency_ul_dl_config, 628 VDEV_PARAM_LOW_LATENCY_UL_DL_CONFIGURATION), 629 PARAM_MAP(vdev_param_set_ultra_low_latency_ul_dl_config, 630 VDEV_PARAM_ULTRA_LOW_LATENCY_UL_DL_CONFIGURATION), 631 PARAM_MAP(vdev_param_set_default_ll_config, 632 VDEV_PARAM_DEFAULT_LATENCY_LEVEL_CONFIGURATION), 633 PARAM_MAP(vdev_param_set_multi_client_ll_feature_config, 634 VDEV_PARAM_MULTI_CLIENT_LL_FEATURE_CONFIGURATION), 635 PARAM_MAP(vdev_param_set_traffic_config, 636 VDEV_PARAM_VDEV_TRAFFIC_CONFIG), 637 PARAM_MAP(vdev_param_he_range_ext, VDEV_PARAM_HE_RANGE_EXT), 638 PARAM_MAP(vdev_param_non_data_he_range_ext, 639 VDEV_PARAM_NON_DATA_HE_RANGE_EXT), 640 PARAM_MAP(vdev_param_ndp_inactivity_timeout, 641 VDEV_PARAM_NDP_INACTIVITY_TIMEOUT), 642 PARAM_MAP(vdev_param_ndp_keepalive_timeout, 643 VDEV_PARAM_NDP_KEEPALIVE_TIMEOUT), 644 PARAM_MAP(vdev_param_final_bmiss_time_sec, 645 VDEV_PARAM_FINAL_BMISS_TIME_SEC), 646 PARAM_MAP(vdev_param_final_bmiss_time_wow_sec, 647 VDEV_PARAM_FINAL_BMISS_TIME_WOW_SEC), 648 PARAM_MAP(vdev_param_ap_keepalive_max_idle_inactive_secs, 649 VDEV_PARAM_AP_KEEPALIVE_MAX_IDLE_INACTIVE_TIME_SECS), 650 PARAM_MAP(vdev_param_per_band_mgmt_tx_rate, 651 VDEV_PARAM_PER_BAND_MGMT_TX_RATE), 652 PARAM_MAP(vdev_param_max_li_of_moddtim, 653 VDEV_PARAM_MAX_LI_OF_MODDTIM), 654 PARAM_MAP(vdev_param_moddtim_cnt, VDEV_PARAM_MODDTIM_CNT), 655 PARAM_MAP(vdev_param_max_li_of_moddtim_ms, 656 VDEV_PARAM_MAX_LI_OF_MODDTIM_MS), 657 PARAM_MAP(vdev_param_dyndtim_cnt, VDEV_PARAM_DYNDTIM_CNT), 658 PARAM_MAP(vdev_param_wmm_txop_enable, VDEV_PARAM_WMM_TXOP_ENABLE), 659 PARAM_MAP(vdev_param_enable_bcast_probe_response, 660 VDEV_PARAM_ENABLE_BCAST_PROBE_RESPONSE), 661 PARAM_MAP(vdev_param_fils_max_channel_guard_time, 662 VDEV_PARAM_FILS_MAX_CHANNEL_GUARD_TIME), 663 PARAM_MAP(vdev_param_probe_delay, VDEV_PARAM_PROBE_DELAY), 664 PARAM_MAP(vdev_param_repeat_probe_time, VDEV_PARAM_REPEAT_PROBE_TIME), 665 PARAM_MAP(vdev_param_enable_disable_oce_features, 666 VDEV_PARAM_ENABLE_DISABLE_OCE_FEATURES), 667 PARAM_MAP(vdev_param_enable_disable_nan_config_features, 668 VDEV_PARAM_ENABLE_DISABLE_NAN_CONFIG_FEATURES), 669 PARAM_MAP(vdev_param_rsn_capability, VDEV_PARAM_RSN_CAPABILITY), 670 PARAM_MAP(vdev_param_smps_intolerant, VDEV_PARAM_SMPS_INTOLERANT), 671 PARAM_MAP(vdev_param_abg_mode_tx_chain_num, 672 VDEV_PARAM_ABG_MODE_TX_CHAIN_NUM), 673 PARAM_MAP(vdev_param_nth_beacon_to_host, VDEV_PARAM_NTH_BEACON_TO_HOST), 674 PARAM_MAP(vdev_param_prohibit_data_mgmt, VDEV_PARAM_PROHIBIT_DATA_MGMT), 675 PARAM_MAP(vdev_param_skip_roam_eapol_4way_handshake, 676 VDEV_PARAM_SKIP_ROAM_EAPOL_4WAY_HANDSHAKE), 677 PARAM_MAP(vdev_param_skip_sae_roam_4way_handshake, 678 VDEV_PARAM_SKIP_SAE_ROAM_4WAY_HANDSHAKE), 679 PARAM_MAP(vdev_param_roam_11kv_ctrl, VDEV_PARAM_ROAM_11KV_CTRL), 680 PARAM_MAP(vdev_param_disable_noa_p2p_go, VDEV_PARAM_DISABLE_NOA_P2P_GO), 681 PARAM_MAP(vdev_param_packet_capture_mode, 682 VDEV_PARAM_PACKET_CAPTURE_MODE), 683 PARAM_MAP(vdev_param_smart_monitor_config, 684 VDEV_PARAM_SMART_MONITOR_CONFIG), 685 PARAM_MAP(vdev_param_force_dtim_cnt, VDEV_PARAM_FORCE_DTIM_CNT), 686 PARAM_MAP(vdev_param_sho_config, VDEV_PARAM_SHO_CONFIG), 687 PARAM_MAP(vdev_param_gtx_enable, VDEV_PARAM_GTX_ENABLE), 688 PARAM_MAP(vdev_param_mu_edca_fw_update_en, 689 VDEV_PARAM_MU_EDCA_FW_UPDATE_EN), 690 PARAM_MAP(vdev_param_enable_disable_rtt_initiator_random_mac, 691 VDEV_PARAM_ENABLE_DISABLE_RTT_INITIATOR_RANDOM_MAC), 692 PARAM_MAP(vdev_param_allow_nan_initial_discovery_of_mp0_cluster, 693 VDEV_PARAM_ALLOW_NAN_INITIAL_DISCOVERY_OF_MP0_CLUSTER), 694 PARAM_MAP(vdev_param_txpower_scale_decr_db, 695 VDEV_PARAM_TXPOWER_SCALE_DECR_DB), 696 PARAM_MAP(vdev_param_txpower_scale, VDEV_PARAM_TXPOWER_SCALE), 697 PARAM_MAP(vdev_param_agg_sw_retry_th, VDEV_PARAM_AGG_SW_RETRY_TH), 698 PARAM_MAP(vdev_param_obsspd, VDEV_PARAM_OBSSPD), 699 PARAM_MAP(vdev_param_amsdu_aggregation_size_optimization, 700 VDEV_PARAM_AMSDU_AGGREGATION_SIZE_OPTIMIZATION), 701 PARAM_MAP(vdev_param_non_agg_sw_retry_th, 702 VDEV_PARAM_NON_AGG_SW_RETRY_TH), 703 PARAM_MAP(vdev_param_set_cmd_obss_pd_threshold, 704 VDEV_PARAM_SET_CMD_OBSS_PD_THRESHOLD), 705 }; 706 #endif 707 708 #ifndef WMI_PKTLOG_EVENT_CBF 709 #define WMI_PKTLOG_EVENT_CBF 0x100 710 #endif 711 712 /* 713 * Populate the pktlog event tlv array, where 714 * the values are the FW WMI events, which host 715 * uses to communicate with FW for pktlog 716 */ 717 718 static const uint32_t pktlog_event_tlv[] = { 719 [WMI_HOST_PKTLOG_EVENT_RX_BIT] = WMI_PKTLOG_EVENT_RX, 720 [WMI_HOST_PKTLOG_EVENT_TX_BIT] = WMI_PKTLOG_EVENT_TX, 721 [WMI_HOST_PKTLOG_EVENT_RCF_BIT] = WMI_PKTLOG_EVENT_RCF, 722 [WMI_HOST_PKTLOG_EVENT_RCU_BIT] = WMI_PKTLOG_EVENT_RCU, 723 [WMI_HOST_PKTLOG_EVENT_DBG_PRINT_BIT] = 0, 724 [WMI_HOST_PKTLOG_EVENT_SMART_ANTENNA_BIT] = 725 WMI_PKTLOG_EVENT_SMART_ANTENNA, 726 [WMI_HOST_PKTLOG_EVENT_H_INFO_BIT] = 0, 727 [WMI_HOST_PKTLOG_EVENT_STEERING_BIT] = 0, 728 [WMI_HOST_PKTLOG_EVENT_TX_DATA_CAPTURE_BIT] = 0, 729 [WMI_HOST_PKTLOG_EVENT_PHY_LOGGING_BIT] = WMI_PKTLOG_EVENT_PHY, 730 [WMI_HOST_PKTLOG_EVENT_CBF_BIT] = WMI_PKTLOG_EVENT_CBF, 731 #ifdef BE_PKTLOG_SUPPORT 732 [WMI_HOST_PKTLOG_EVENT_HYBRID_TX_BIT] = WMI_PKTLOG_EVENT_HYBRID_TX, 733 #endif 734 }; 735 736 /** 737 * convert_host_pdev_id_to_target_pdev_id() - Convert pdev_id from 738 * host to target defines. 739 * @wmi_handle: pointer to wmi_handle 740 * @pdev_id: host pdev_id to be converted. 741 * Return: target pdev_id after conversion. 742 */ 743 static uint32_t convert_host_pdev_id_to_target_pdev_id(wmi_unified_t wmi_handle, 744 uint32_t pdev_id) 745 { 746 if (pdev_id <= WMI_HOST_PDEV_ID_2 && pdev_id >= WMI_HOST_PDEV_ID_0) { 747 if (!wmi_handle->soc->is_pdev_is_map_enable) { 748 switch (pdev_id) { 749 case WMI_HOST_PDEV_ID_0: 750 return WMI_PDEV_ID_1ST; 751 case WMI_HOST_PDEV_ID_1: 752 return WMI_PDEV_ID_2ND; 753 case WMI_HOST_PDEV_ID_2: 754 return WMI_PDEV_ID_3RD; 755 } 756 } else { 757 return wmi_handle->cmd_pdev_id_map[pdev_id]; 758 } 759 } else { 760 return WMI_PDEV_ID_SOC; 761 } 762 763 QDF_ASSERT(0); 764 765 return WMI_PDEV_ID_SOC; 766 } 767 768 /** 769 * convert_target_pdev_id_to_host_pdev_id() - Convert pdev_id from 770 * target to host defines. 771 * @wmi_handle: pointer to wmi_handle 772 * @pdev_id: target pdev_id to be converted. 773 * Return: host pdev_id after conversion. 774 */ 775 static uint32_t convert_target_pdev_id_to_host_pdev_id(wmi_unified_t wmi_handle, 776 uint32_t pdev_id) 777 { 778 779 if (pdev_id <= WMI_PDEV_ID_3RD && pdev_id >= WMI_PDEV_ID_1ST) { 780 if (!wmi_handle->soc->is_pdev_is_map_enable) { 781 switch (pdev_id) { 782 case WMI_PDEV_ID_1ST: 783 return WMI_HOST_PDEV_ID_0; 784 case WMI_PDEV_ID_2ND: 785 return WMI_HOST_PDEV_ID_1; 786 case WMI_PDEV_ID_3RD: 787 return WMI_HOST_PDEV_ID_2; 788 } 789 } else { 790 return wmi_handle->evt_pdev_id_map[pdev_id - 1]; 791 } 792 } else if (pdev_id == WMI_PDEV_ID_SOC) { 793 return WMI_HOST_PDEV_ID_SOC; 794 } else { 795 wmi_err("Invalid pdev_id"); 796 } 797 798 return WMI_HOST_PDEV_ID_INVALID; 799 } 800 801 /** 802 * convert_host_phy_id_to_target_phy_id() - Convert phy_id from 803 * host to target defines. 804 * @wmi_handle: pointer to wmi_handle 805 * @phy_id: host pdev_id to be converted. 806 * Return: target phy_id after conversion. 807 */ 808 static uint32_t convert_host_phy_id_to_target_phy_id(wmi_unified_t wmi_handle, 809 uint32_t phy_id) 810 { 811 if (!wmi_handle->soc->is_phy_id_map_enable || 812 phy_id >= WMI_MAX_RADIOS) { 813 return phy_id; 814 } 815 816 return wmi_handle->cmd_phy_id_map[phy_id]; 817 } 818 819 /** 820 * convert_target_phy_id_to_host_phy_id() - Convert phy_id from 821 * target to host defines. 822 * @wmi_handle: pointer to wmi_handle 823 * @phy_id: target phy_id to be converted. 824 * Return: host phy_id after conversion. 825 */ 826 static uint32_t convert_target_phy_id_to_host_phy_id(wmi_unified_t wmi_handle, 827 uint32_t phy_id) 828 { 829 if (!wmi_handle->soc->is_phy_id_map_enable || 830 phy_id >= WMI_MAX_RADIOS) { 831 return phy_id; 832 } 833 834 return wmi_handle->evt_phy_id_map[phy_id]; 835 } 836 837 /** 838 * wmi_tlv_pdev_id_conversion_enable() - Enable pdev_id conversion 839 * @wmi_handle: WMI handle 840 * @pdev_id_map: pointer to mapping table 841 * @size: number of entries in @pdev_id_map 842 * 843 * Return: None. 844 */ 845 static void wmi_tlv_pdev_id_conversion_enable(wmi_unified_t wmi_handle, 846 uint32_t *pdev_id_map, 847 uint8_t size) 848 { 849 int i = 0; 850 851 if (pdev_id_map && (size <= WMI_MAX_RADIOS)) { 852 for (i = 0; i < size; i++) { 853 wmi_handle->cmd_pdev_id_map[i] = pdev_id_map[i]; 854 wmi_handle->evt_pdev_id_map[i] = 855 WMI_HOST_PDEV_ID_INVALID; 856 wmi_handle->cmd_phy_id_map[i] = pdev_id_map[i] - 1; 857 wmi_handle->evt_phy_id_map[i] = 858 WMI_HOST_PDEV_ID_INVALID; 859 } 860 861 for (i = 0; i < size; i++) { 862 if (wmi_handle->cmd_pdev_id_map[i] != 863 WMI_HOST_PDEV_ID_INVALID) { 864 wmi_handle->evt_pdev_id_map 865 [wmi_handle->cmd_pdev_id_map[i] - 1] = i; 866 } 867 if (wmi_handle->cmd_phy_id_map[i] != 868 WMI_HOST_PDEV_ID_INVALID) { 869 wmi_handle->evt_phy_id_map 870 [wmi_handle->cmd_phy_id_map[i]] = i; 871 } 872 } 873 wmi_handle->soc->is_pdev_is_map_enable = true; 874 wmi_handle->soc->is_phy_id_map_enable = true; 875 } else { 876 wmi_handle->soc->is_pdev_is_map_enable = false; 877 wmi_handle->soc->is_phy_id_map_enable = false; 878 } 879 880 wmi_handle->ops->convert_pdev_id_host_to_target = 881 convert_host_pdev_id_to_target_pdev_id; 882 wmi_handle->ops->convert_pdev_id_target_to_host = 883 convert_target_pdev_id_to_host_pdev_id; 884 885 /* phy_id convert function assignments */ 886 wmi_handle->ops->convert_phy_id_host_to_target = 887 convert_host_phy_id_to_target_phy_id; 888 wmi_handle->ops->convert_phy_id_target_to_host = 889 convert_target_phy_id_to_host_phy_id; 890 } 891 892 /* copy_vdev_create_pdev_id() - copy pdev from host params to target command 893 * buffer. 894 * @wmi_handle: pointer to wmi_handle 895 * @cmd: pointer target vdev create command buffer 896 * @param: pointer host params for vdev create 897 * 898 * Return: None 899 */ 900 static inline void copy_vdev_create_pdev_id( 901 struct wmi_unified *wmi_handle, 902 wmi_vdev_create_cmd_fixed_param * cmd, 903 struct vdev_create_params *param) 904 { 905 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 906 wmi_handle, 907 param->pdev_id); 908 } 909 910 void wmi_mtrace(uint32_t message_id, uint16_t vdev_id, uint32_t data) 911 { 912 uint16_t mtrace_message_id; 913 914 mtrace_message_id = QDF_WMI_MTRACE_CMD_ID(message_id) | 915 (QDF_WMI_MTRACE_GRP_ID(message_id) << 916 QDF_WMI_MTRACE_CMD_NUM_BITS); 917 qdf_mtrace(QDF_MODULE_ID_WMI, QDF_MODULE_ID_TARGET, 918 mtrace_message_id, vdev_id, data); 919 } 920 qdf_export_symbol(wmi_mtrace); 921 922 QDF_STATUS wmi_unified_cmd_send_pm_chk(struct wmi_unified *wmi_handle, 923 wmi_buf_t buf, 924 uint32_t buflen, uint32_t cmd_id, 925 bool is_qmi_send_support) 926 { 927 if (!is_qmi_send_support) 928 goto send_over_wmi; 929 930 if (!wmi_is_qmi_stats_enabled(wmi_handle)) 931 goto send_over_wmi; 932 933 if (wmi_is_target_suspend_acked(wmi_handle)) { 934 if (QDF_IS_STATUS_SUCCESS( 935 wmi_unified_cmd_send_over_qmi(wmi_handle, buf, 936 buflen, cmd_id))) 937 return QDF_STATUS_SUCCESS; 938 } 939 940 send_over_wmi: 941 qdf_atomic_set(&wmi_handle->num_stats_over_qmi, 0); 942 943 return wmi_unified_cmd_send(wmi_handle, buf, buflen, cmd_id); 944 } 945 946 /** 947 * send_vdev_create_cmd_tlv() - send VDEV create command to fw 948 * @wmi_handle: wmi handle 949 * @param: pointer to hold vdev create parameter 950 * @macaddr: vdev mac address 951 * 952 * Return: QDF_STATUS_SUCCESS for success or error code 953 */ 954 static QDF_STATUS send_vdev_create_cmd_tlv(wmi_unified_t wmi_handle, 955 uint8_t macaddr[QDF_MAC_ADDR_SIZE], 956 struct vdev_create_params *param) 957 { 958 wmi_vdev_create_cmd_fixed_param *cmd; 959 wmi_buf_t buf; 960 int32_t len = sizeof(*cmd); 961 QDF_STATUS ret; 962 int num_bands = 2; 963 uint8_t *buf_ptr; 964 wmi_vdev_txrx_streams *txrx_streams; 965 966 len += (num_bands * sizeof(*txrx_streams) + WMI_TLV_HDR_SIZE); 967 len += vdev_create_mlo_params_size(param); 968 969 buf = wmi_buf_alloc(wmi_handle, len); 970 if (!buf) 971 return QDF_STATUS_E_NOMEM; 972 973 cmd = (wmi_vdev_create_cmd_fixed_param *) wmi_buf_data(buf); 974 WMITLV_SET_HDR(&cmd->tlv_header, 975 WMITLV_TAG_STRUC_wmi_vdev_create_cmd_fixed_param, 976 WMITLV_GET_STRUCT_TLVLEN 977 (wmi_vdev_create_cmd_fixed_param)); 978 cmd->vdev_id = param->vdev_id; 979 cmd->vdev_type = param->type; 980 cmd->vdev_subtype = param->subtype; 981 cmd->flags = param->mbssid_flags; 982 cmd->flags |= (param->special_vdev_mode ? VDEV_FLAGS_SCAN_MODE_VAP : 0); 983 cmd->vdevid_trans = param->vdevid_trans; 984 cmd->num_cfg_txrx_streams = num_bands; 985 #ifdef QCA_VDEV_STATS_HW_OFFLOAD_SUPPORT 986 cmd->vdev_stats_id_valid = param->vdev_stats_id_valid; 987 cmd->vdev_stats_id = param->vdev_stats_id; 988 #endif 989 copy_vdev_create_pdev_id(wmi_handle, cmd, param); 990 WMI_CHAR_ARRAY_TO_MAC_ADDR(macaddr, &cmd->vdev_macaddr); 991 wmi_debug("ID = %d[pdev:%d] VAP Addr = "QDF_MAC_ADDR_FMT, 992 param->vdev_id, cmd->pdev_id, 993 QDF_MAC_ADDR_REF(macaddr)); 994 buf_ptr = (uint8_t *)cmd + sizeof(*cmd); 995 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 996 (num_bands * sizeof(wmi_vdev_txrx_streams))); 997 buf_ptr += WMI_TLV_HDR_SIZE; 998 999 wmi_debug("type %d, subtype %d, nss_2g %d, nss_5g %d", 1000 param->type, param->subtype, 1001 param->nss_2g, param->nss_5g); 1002 txrx_streams = (wmi_vdev_txrx_streams *)buf_ptr; 1003 txrx_streams->band = WMI_TPC_CHAINMASK_CONFIG_BAND_2G; 1004 txrx_streams->supported_tx_streams = param->nss_2g; 1005 txrx_streams->supported_rx_streams = param->nss_2g; 1006 WMITLV_SET_HDR(&txrx_streams->tlv_header, 1007 WMITLV_TAG_STRUC_wmi_vdev_txrx_streams, 1008 WMITLV_GET_STRUCT_TLVLEN(wmi_vdev_txrx_streams)); 1009 1010 txrx_streams++; 1011 txrx_streams->band = WMI_TPC_CHAINMASK_CONFIG_BAND_5G; 1012 txrx_streams->supported_tx_streams = param->nss_5g; 1013 txrx_streams->supported_rx_streams = param->nss_5g; 1014 WMITLV_SET_HDR(&txrx_streams->tlv_header, 1015 WMITLV_TAG_STRUC_wmi_vdev_txrx_streams, 1016 WMITLV_GET_STRUCT_TLVLEN(wmi_vdev_txrx_streams)); 1017 1018 buf_ptr += (num_bands * sizeof(wmi_vdev_txrx_streams)); 1019 buf_ptr = vdev_create_add_mlo_params(buf_ptr, param); 1020 1021 wmi_mtrace(WMI_VDEV_CREATE_CMDID, cmd->vdev_id, 0); 1022 ret = wmi_unified_cmd_send(wmi_handle, buf, len, WMI_VDEV_CREATE_CMDID); 1023 if (QDF_IS_STATUS_ERROR(ret)) { 1024 wmi_err("Failed to send WMI_VDEV_CREATE_CMDID"); 1025 wmi_buf_free(buf); 1026 } 1027 1028 return ret; 1029 } 1030 1031 /** 1032 * send_vdev_delete_cmd_tlv() - send VDEV delete command to fw 1033 * @wmi_handle: wmi handle 1034 * @if_id: vdev id 1035 * 1036 * Return: QDF_STATUS_SUCCESS for success or error code 1037 */ 1038 static QDF_STATUS send_vdev_delete_cmd_tlv(wmi_unified_t wmi_handle, 1039 uint8_t if_id) 1040 { 1041 wmi_vdev_delete_cmd_fixed_param *cmd; 1042 wmi_buf_t buf; 1043 QDF_STATUS ret; 1044 1045 buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd)); 1046 if (!buf) 1047 return QDF_STATUS_E_NOMEM; 1048 1049 cmd = (wmi_vdev_delete_cmd_fixed_param *) wmi_buf_data(buf); 1050 WMITLV_SET_HDR(&cmd->tlv_header, 1051 WMITLV_TAG_STRUC_wmi_vdev_delete_cmd_fixed_param, 1052 WMITLV_GET_STRUCT_TLVLEN 1053 (wmi_vdev_delete_cmd_fixed_param)); 1054 cmd->vdev_id = if_id; 1055 wmi_mtrace(WMI_VDEV_DELETE_CMDID, cmd->vdev_id, 0); 1056 ret = wmi_unified_cmd_send(wmi_handle, buf, 1057 sizeof(wmi_vdev_delete_cmd_fixed_param), 1058 WMI_VDEV_DELETE_CMDID); 1059 if (QDF_IS_STATUS_ERROR(ret)) { 1060 wmi_err("Failed to send WMI_VDEV_DELETE_CMDID"); 1061 wmi_buf_free(buf); 1062 } 1063 wmi_debug("vdev id = %d", if_id); 1064 1065 return ret; 1066 } 1067 1068 /** 1069 * send_vdev_nss_chain_params_cmd_tlv() - send VDEV nss chain params to fw 1070 * @wmi_handle: wmi handle 1071 * @vdev_id: vdev id 1072 * @user_cfg: user configured nss chain params 1073 * 1074 * Return: QDF_STATUS_SUCCESS for success or error code 1075 */ 1076 static QDF_STATUS 1077 send_vdev_nss_chain_params_cmd_tlv(wmi_unified_t wmi_handle, 1078 uint8_t vdev_id, 1079 struct vdev_nss_chains *user_cfg) 1080 { 1081 wmi_vdev_chainmask_config_cmd_fixed_param *cmd; 1082 wmi_buf_t buf; 1083 QDF_STATUS ret; 1084 1085 buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd)); 1086 if (!buf) 1087 return QDF_STATUS_E_NOMEM; 1088 1089 cmd = (wmi_vdev_chainmask_config_cmd_fixed_param *)wmi_buf_data(buf); 1090 WMITLV_SET_HDR(&cmd->tlv_header, 1091 WMITLV_TAG_STRUC_wmi_vdev_chainmask_config_cmd_fixed_param, 1092 WMITLV_GET_STRUCT_TLVLEN 1093 (wmi_vdev_chainmask_config_cmd_fixed_param)); 1094 cmd->vdev_id = vdev_id; 1095 cmd->disable_rx_mrc_2g = user_cfg->disable_rx_mrc[NSS_CHAINS_BAND_2GHZ]; 1096 cmd->disable_tx_mrc_2g = user_cfg->disable_tx_mrc[NSS_CHAINS_BAND_2GHZ]; 1097 cmd->disable_rx_mrc_5g = user_cfg->disable_rx_mrc[NSS_CHAINS_BAND_5GHZ]; 1098 cmd->disable_tx_mrc_5g = user_cfg->disable_tx_mrc[NSS_CHAINS_BAND_5GHZ]; 1099 cmd->num_rx_chains_2g = user_cfg->num_rx_chains[NSS_CHAINS_BAND_2GHZ]; 1100 cmd->num_tx_chains_2g = user_cfg->num_tx_chains[NSS_CHAINS_BAND_2GHZ]; 1101 cmd->num_rx_chains_5g = user_cfg->num_rx_chains[NSS_CHAINS_BAND_5GHZ]; 1102 cmd->num_tx_chains_5g = user_cfg->num_tx_chains[NSS_CHAINS_BAND_5GHZ]; 1103 cmd->rx_nss_2g = user_cfg->rx_nss[NSS_CHAINS_BAND_2GHZ]; 1104 cmd->tx_nss_2g = user_cfg->tx_nss[NSS_CHAINS_BAND_2GHZ]; 1105 cmd->rx_nss_5g = user_cfg->rx_nss[NSS_CHAINS_BAND_5GHZ]; 1106 cmd->tx_nss_5g = user_cfg->tx_nss[NSS_CHAINS_BAND_5GHZ]; 1107 cmd->num_tx_chains_a = user_cfg->num_tx_chains_11a; 1108 cmd->num_tx_chains_b = user_cfg->num_tx_chains_11b; 1109 cmd->num_tx_chains_g = user_cfg->num_tx_chains_11g; 1110 1111 wmi_mtrace(WMI_VDEV_CHAINMASK_CONFIG_CMDID, cmd->vdev_id, 0); 1112 ret = wmi_unified_cmd_send(wmi_handle, buf, 1113 sizeof(wmi_vdev_chainmask_config_cmd_fixed_param), 1114 WMI_VDEV_CHAINMASK_CONFIG_CMDID); 1115 if (QDF_IS_STATUS_ERROR(ret)) { 1116 wmi_err("Failed to send WMI_VDEV_CHAINMASK_CONFIG_CMDID"); 1117 wmi_buf_free(buf); 1118 } 1119 wmi_debug("vdev_id %d", vdev_id); 1120 1121 return ret; 1122 } 1123 1124 /** 1125 * send_vdev_stop_cmd_tlv() - send vdev stop command to fw 1126 * @wmi: wmi handle 1127 * @vdev_id: vdev id 1128 * 1129 * Return: QDF_STATUS_SUCCESS for success or error code 1130 */ 1131 static QDF_STATUS send_vdev_stop_cmd_tlv(wmi_unified_t wmi, 1132 uint8_t vdev_id) 1133 { 1134 wmi_vdev_stop_cmd_fixed_param *cmd; 1135 wmi_buf_t buf; 1136 int32_t len = sizeof(*cmd); 1137 1138 buf = wmi_buf_alloc(wmi, len); 1139 if (!buf) 1140 return QDF_STATUS_E_NOMEM; 1141 1142 cmd = (wmi_vdev_stop_cmd_fixed_param *) wmi_buf_data(buf); 1143 WMITLV_SET_HDR(&cmd->tlv_header, 1144 WMITLV_TAG_STRUC_wmi_vdev_stop_cmd_fixed_param, 1145 WMITLV_GET_STRUCT_TLVLEN(wmi_vdev_stop_cmd_fixed_param)); 1146 cmd->vdev_id = vdev_id; 1147 wmi_mtrace(WMI_VDEV_STOP_CMDID, cmd->vdev_id, 0); 1148 if (wmi_unified_cmd_send(wmi, buf, len, WMI_VDEV_STOP_CMDID)) { 1149 wmi_err("Failed to send vdev stop command"); 1150 wmi_buf_free(buf); 1151 return QDF_STATUS_E_FAILURE; 1152 } 1153 wmi_debug("vdev id = %d", vdev_id); 1154 1155 return 0; 1156 } 1157 1158 /** 1159 * send_vdev_down_cmd_tlv() - send vdev down command to fw 1160 * @wmi: wmi handle 1161 * @vdev_id: vdev id 1162 * 1163 * Return: QDF_STATUS_SUCCESS for success or error code 1164 */ 1165 static QDF_STATUS send_vdev_down_cmd_tlv(wmi_unified_t wmi, uint8_t vdev_id) 1166 { 1167 wmi_vdev_down_cmd_fixed_param *cmd; 1168 wmi_buf_t buf; 1169 int32_t len = sizeof(*cmd); 1170 1171 buf = wmi_buf_alloc(wmi, len); 1172 if (!buf) 1173 return QDF_STATUS_E_NOMEM; 1174 1175 cmd = (wmi_vdev_down_cmd_fixed_param *) wmi_buf_data(buf); 1176 WMITLV_SET_HDR(&cmd->tlv_header, 1177 WMITLV_TAG_STRUC_wmi_vdev_down_cmd_fixed_param, 1178 WMITLV_GET_STRUCT_TLVLEN(wmi_vdev_down_cmd_fixed_param)); 1179 cmd->vdev_id = vdev_id; 1180 wmi_mtrace(WMI_VDEV_DOWN_CMDID, cmd->vdev_id, 0); 1181 if (wmi_unified_cmd_send(wmi, buf, len, WMI_VDEV_DOWN_CMDID)) { 1182 wmi_err("Failed to send vdev down"); 1183 wmi_buf_free(buf); 1184 return QDF_STATUS_E_FAILURE; 1185 } 1186 wmi_debug("vdev_id %d", vdev_id); 1187 1188 return 0; 1189 } 1190 1191 static inline void copy_channel_info( 1192 wmi_vdev_start_request_cmd_fixed_param * cmd, 1193 wmi_channel *chan, 1194 struct vdev_start_params *req) 1195 { 1196 chan->mhz = req->channel.mhz; 1197 1198 WMI_SET_CHANNEL_MODE(chan, req->channel.phy_mode); 1199 1200 chan->band_center_freq1 = req->channel.cfreq1; 1201 chan->band_center_freq2 = req->channel.cfreq2; 1202 1203 if (req->channel.half_rate) 1204 WMI_SET_CHANNEL_FLAG(chan, WMI_CHAN_FLAG_HALF_RATE); 1205 else if (req->channel.quarter_rate) 1206 WMI_SET_CHANNEL_FLAG(chan, WMI_CHAN_FLAG_QUARTER_RATE); 1207 1208 if (req->channel.dfs_set) { 1209 WMI_SET_CHANNEL_FLAG(chan, WMI_CHAN_FLAG_DFS); 1210 cmd->disable_hw_ack = req->disable_hw_ack; 1211 } 1212 1213 if (req->channel.dfs_set_cfreq2) 1214 WMI_SET_CHANNEL_FLAG(chan, WMI_CHAN_FLAG_DFS_CFREQ2); 1215 1216 if (req->channel.is_stadfs_en) 1217 WMI_SET_CHANNEL_FLAG(chan, WMI_CHAN_FLAG_STA_DFS); 1218 1219 /* According to firmware both reg power and max tx power 1220 * on set channel power is used and set it to max reg 1221 * power from regulatory. 1222 */ 1223 WMI_SET_CHANNEL_MIN_POWER(chan, req->channel.minpower); 1224 WMI_SET_CHANNEL_MAX_POWER(chan, req->channel.maxpower); 1225 WMI_SET_CHANNEL_REG_POWER(chan, req->channel.maxregpower); 1226 WMI_SET_CHANNEL_ANTENNA_MAX(chan, req->channel.antennamax); 1227 WMI_SET_CHANNEL_REG_CLASSID(chan, req->channel.reg_class_id); 1228 WMI_SET_CHANNEL_MAX_TX_POWER(chan, req->channel.maxregpower); 1229 1230 } 1231 1232 /** 1233 * vdev_start_cmd_fill_11be() - 11be information filling in vdev_start 1234 * @cmd: wmi cmd 1235 * @req: vdev start params 1236 * 1237 * Return: QDF status 1238 */ 1239 #ifdef WLAN_FEATURE_11BE 1240 static void 1241 vdev_start_cmd_fill_11be(wmi_vdev_start_request_cmd_fixed_param *cmd, 1242 struct vdev_start_params *req) 1243 { 1244 cmd->eht_ops = req->eht_ops; 1245 cmd->puncture_20mhz_bitmap = ~req->channel.puncture_bitmap; 1246 wmi_info("EHT ops: %x puncture_bitmap %x wmi cmd puncture bitmap %x", 1247 req->eht_ops, req->channel.puncture_bitmap, 1248 cmd->puncture_20mhz_bitmap); 1249 } 1250 #else 1251 static void 1252 vdev_start_cmd_fill_11be(wmi_vdev_start_request_cmd_fixed_param *cmd, 1253 struct vdev_start_params *req) 1254 { 1255 } 1256 #endif 1257 1258 /** 1259 * send_vdev_start_cmd_tlv() - send vdev start request to fw 1260 * @wmi_handle: wmi handle 1261 * @req: vdev start params 1262 * 1263 * Return: QDF status 1264 */ 1265 static QDF_STATUS send_vdev_start_cmd_tlv(wmi_unified_t wmi_handle, 1266 struct vdev_start_params *req) 1267 { 1268 wmi_vdev_start_request_cmd_fixed_param *cmd; 1269 wmi_buf_t buf; 1270 wmi_channel *chan; 1271 int32_t len, ret; 1272 uint8_t *buf_ptr; 1273 1274 len = sizeof(*cmd) + sizeof(wmi_channel) + WMI_TLV_HDR_SIZE; 1275 if (!req->is_restart) 1276 len += vdev_start_mlo_params_size(req); 1277 buf = wmi_buf_alloc(wmi_handle, len); 1278 if (!buf) 1279 return QDF_STATUS_E_NOMEM; 1280 1281 buf_ptr = (uint8_t *) wmi_buf_data(buf); 1282 cmd = (wmi_vdev_start_request_cmd_fixed_param *) buf_ptr; 1283 chan = (wmi_channel *) (buf_ptr + sizeof(*cmd)); 1284 WMITLV_SET_HDR(&cmd->tlv_header, 1285 WMITLV_TAG_STRUC_wmi_vdev_start_request_cmd_fixed_param, 1286 WMITLV_GET_STRUCT_TLVLEN 1287 (wmi_vdev_start_request_cmd_fixed_param)); 1288 WMITLV_SET_HDR(&chan->tlv_header, WMITLV_TAG_STRUC_wmi_channel, 1289 WMITLV_GET_STRUCT_TLVLEN(wmi_channel)); 1290 cmd->vdev_id = req->vdev_id; 1291 1292 /* Fill channel info */ 1293 copy_channel_info(cmd, chan, req); 1294 cmd->beacon_interval = req->beacon_interval; 1295 cmd->dtim_period = req->dtim_period; 1296 1297 cmd->bcn_tx_rate = req->bcn_tx_rate_code; 1298 if (req->bcn_tx_rate_code) 1299 wmi_enable_bcn_ratecode(&cmd->flags); 1300 1301 if (!req->is_restart) { 1302 if (req->pmf_enabled) 1303 cmd->flags |= WMI_UNIFIED_VDEV_START_PMF_ENABLED; 1304 1305 cmd->mbss_capability_flags = req->mbssid_flags; 1306 cmd->vdevid_trans = req->vdevid_trans; 1307 cmd->mbssid_multi_group_flag = req->mbssid_multi_group_flag; 1308 cmd->mbssid_multi_group_id = req->mbssid_multi_group_id; 1309 } 1310 1311 /* Copy the SSID */ 1312 if (req->ssid.length) { 1313 if (req->ssid.length < sizeof(cmd->ssid.ssid)) 1314 cmd->ssid.ssid_len = req->ssid.length; 1315 else 1316 cmd->ssid.ssid_len = sizeof(cmd->ssid.ssid); 1317 qdf_mem_copy(cmd->ssid.ssid, req->ssid.ssid, 1318 cmd->ssid.ssid_len); 1319 } 1320 1321 if (req->hidden_ssid) 1322 cmd->flags |= WMI_UNIFIED_VDEV_START_HIDDEN_SSID; 1323 1324 cmd->flags |= WMI_UNIFIED_VDEV_START_LDPC_RX_ENABLED; 1325 cmd->num_noa_descriptors = req->num_noa_descriptors; 1326 cmd->preferred_rx_streams = req->preferred_rx_streams; 1327 cmd->preferred_tx_streams = req->preferred_tx_streams; 1328 cmd->cac_duration_ms = req->cac_duration_ms; 1329 cmd->regdomain = req->regdomain; 1330 cmd->he_ops = req->he_ops; 1331 1332 buf_ptr = (uint8_t *) (((uintptr_t) cmd) + sizeof(*cmd) + 1333 sizeof(wmi_channel)); 1334 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 1335 cmd->num_noa_descriptors * 1336 sizeof(wmi_p2p_noa_descriptor)); 1337 if (!req->is_restart) { 1338 buf_ptr += WMI_TLV_HDR_SIZE + 1339 (cmd->num_noa_descriptors * sizeof(wmi_p2p_noa_descriptor)); 1340 1341 buf_ptr = vdev_start_add_mlo_params(buf_ptr, req); 1342 buf_ptr = vdev_start_add_ml_partner_links(buf_ptr, req); 1343 } 1344 wmi_info("vdev_id %d freq %d chanmode %d ch_info: 0x%x is_dfs %d " 1345 "beacon interval %d dtim %d center_chan %d center_freq2 %d " 1346 "reg_info_1: 0x%x reg_info_2: 0x%x, req->max_txpow: 0x%x " 1347 "Tx SS %d, Rx SS %d, ldpc_rx: %d, cac %d, regd %d, HE ops: %d" 1348 "req->dis_hw_ack: %d ", req->vdev_id, 1349 chan->mhz, req->channel.phy_mode, chan->info, 1350 req->channel.dfs_set, req->beacon_interval, cmd->dtim_period, 1351 chan->band_center_freq1, chan->band_center_freq2, 1352 chan->reg_info_1, chan->reg_info_2, req->channel.maxregpower, 1353 req->preferred_tx_streams, req->preferred_rx_streams, 1354 req->ldpc_rx_enabled, req->cac_duration_ms, 1355 req->regdomain, req->he_ops, 1356 req->disable_hw_ack); 1357 1358 vdev_start_cmd_fill_11be(cmd, req); 1359 1360 if (req->is_restart) { 1361 wmi_mtrace(WMI_VDEV_RESTART_REQUEST_CMDID, cmd->vdev_id, 0); 1362 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 1363 WMI_VDEV_RESTART_REQUEST_CMDID); 1364 } else { 1365 wmi_mtrace(WMI_VDEV_START_REQUEST_CMDID, cmd->vdev_id, 0); 1366 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 1367 WMI_VDEV_START_REQUEST_CMDID); 1368 } 1369 if (ret) { 1370 wmi_err("Failed to send vdev start command"); 1371 wmi_buf_free(buf); 1372 return QDF_STATUS_E_FAILURE; 1373 } 1374 1375 return QDF_STATUS_SUCCESS; 1376 } 1377 1378 /** 1379 * send_peer_flush_tids_cmd_tlv() - flush peer tids packets in fw 1380 * @wmi: wmi handle 1381 * @peer_addr: peer mac address 1382 * @param: pointer to hold peer flush tid parameter 1383 * 1384 * Return: QDF_STATUS_SUCCESS for success or error code 1385 */ 1386 static QDF_STATUS send_peer_flush_tids_cmd_tlv(wmi_unified_t wmi, 1387 uint8_t peer_addr[QDF_MAC_ADDR_SIZE], 1388 struct peer_flush_params *param) 1389 { 1390 wmi_peer_flush_tids_cmd_fixed_param *cmd; 1391 wmi_buf_t buf; 1392 int32_t len = sizeof(*cmd); 1393 1394 buf = wmi_buf_alloc(wmi, len); 1395 if (!buf) 1396 return QDF_STATUS_E_NOMEM; 1397 1398 cmd = (wmi_peer_flush_tids_cmd_fixed_param *) wmi_buf_data(buf); 1399 WMITLV_SET_HDR(&cmd->tlv_header, 1400 WMITLV_TAG_STRUC_wmi_peer_flush_tids_cmd_fixed_param, 1401 WMITLV_GET_STRUCT_TLVLEN 1402 (wmi_peer_flush_tids_cmd_fixed_param)); 1403 WMI_CHAR_ARRAY_TO_MAC_ADDR(peer_addr, &cmd->peer_macaddr); 1404 cmd->peer_tid_bitmap = param->peer_tid_bitmap; 1405 cmd->vdev_id = param->vdev_id; 1406 wmi_debug("peer_addr "QDF_MAC_ADDR_FMT" vdev_id %d and peer bitmap %d", 1407 QDF_MAC_ADDR_REF(peer_addr), param->vdev_id, 1408 param->peer_tid_bitmap); 1409 wmi_mtrace(WMI_PEER_FLUSH_TIDS_CMDID, cmd->vdev_id, 0); 1410 if (wmi_unified_cmd_send(wmi, buf, len, WMI_PEER_FLUSH_TIDS_CMDID)) { 1411 wmi_err("Failed to send flush tid command"); 1412 wmi_buf_free(buf); 1413 return QDF_STATUS_E_FAILURE; 1414 } 1415 1416 return 0; 1417 } 1418 1419 #ifdef WLAN_FEATURE_PEER_TXQ_FLUSH_CONF 1420 /** 1421 * map_to_wmi_flush_policy() - Map flush policy to firmware defined values 1422 * @policy: The target i/f flush policy value 1423 * 1424 * Return: WMI layer flush policy 1425 */ 1426 static wmi_peer_flush_policy 1427 map_to_wmi_flush_policy(enum peer_txq_flush_policy policy) 1428 { 1429 switch (policy) { 1430 case PEER_TXQ_FLUSH_POLICY_NONE: 1431 return WMI_NO_FLUSH; 1432 case PEER_TXQ_FLUSH_POLICY_TWT_SP_END: 1433 return WMI_TWT_FLUSH; 1434 default: 1435 return WMI_MAX_FLUSH_POLICY; 1436 } 1437 } 1438 1439 /** 1440 * send_peer_txq_flush_config_cmd_tlv() - Send peer TID queue flush config 1441 * @wmi: wmi handle 1442 * @param: Peer txq flush configuration 1443 * 1444 * Return: QDF_STATUS_SUCCESS for success or error code 1445 */ 1446 static QDF_STATUS 1447 send_peer_txq_flush_config_cmd_tlv(wmi_unified_t wmi, 1448 struct peer_txq_flush_config_params *param) 1449 { 1450 wmi_peer_flush_policy_cmd_fixed_param *cmd; 1451 wmi_buf_t buf; 1452 int32_t len = sizeof(*cmd); 1453 1454 buf = wmi_buf_alloc(wmi, len); 1455 if (!buf) 1456 return QDF_STATUS_E_NOMEM; 1457 1458 cmd = (wmi_peer_flush_policy_cmd_fixed_param *)wmi_buf_data(buf); 1459 1460 WMITLV_SET_HDR(&cmd->tlv_header, 1461 WMITLV_TAG_STRUC_wmi_peer_flush_policy_cmd_fixed_param, 1462 WMITLV_GET_STRUCT_TLVLEN 1463 (wmi_peer_flush_policy_cmd_fixed_param)); 1464 1465 WMI_CHAR_ARRAY_TO_MAC_ADDR(param->peer, &cmd->peer_macaddr); 1466 cmd->peer_tid_bitmap = param->tid_mask; 1467 cmd->vdev_id = param->vdev_id; 1468 cmd->flush_policy = map_to_wmi_flush_policy(param->policy); 1469 if (cmd->flush_policy == WMI_MAX_FLUSH_POLICY) { 1470 wmi_buf_free(buf); 1471 wmi_err("Invalid policy"); 1472 return QDF_STATUS_E_INVAL; 1473 } 1474 wmi_debug("peer_addr " QDF_MAC_ADDR_FMT "vdev %d tid %x policy %d", 1475 QDF_MAC_ADDR_REF(param->peer), param->vdev_id, 1476 param->tid_mask, param->policy); 1477 wmi_mtrace(WMI_PEER_FLUSH_POLICY_CMDID, cmd->vdev_id, 0); 1478 if (wmi_unified_cmd_send(wmi, buf, len, WMI_PEER_FLUSH_POLICY_CMDID)) { 1479 wmi_err("Failed to send flush policy command"); 1480 wmi_buf_free(buf); 1481 return QDF_STATUS_E_FAILURE; 1482 } 1483 1484 return QDF_STATUS_SUCCESS; 1485 } 1486 #endif 1487 /** 1488 * send_peer_delete_cmd_tlv() - send PEER delete command to fw 1489 * @wmi: wmi handle 1490 * @peer_addr: peer mac addr 1491 * @param: peer delete parameters 1492 * 1493 * Return: QDF_STATUS_SUCCESS for success or error code 1494 */ 1495 static QDF_STATUS send_peer_delete_cmd_tlv(wmi_unified_t wmi, 1496 uint8_t peer_addr[QDF_MAC_ADDR_SIZE], 1497 struct peer_delete_cmd_params *param) 1498 { 1499 wmi_peer_delete_cmd_fixed_param *cmd; 1500 wmi_buf_t buf; 1501 int32_t len = sizeof(*cmd); 1502 uint8_t *buf_ptr; 1503 1504 len += peer_delete_mlo_params_size(param); 1505 buf = wmi_buf_alloc(wmi, len); 1506 if (!buf) 1507 return QDF_STATUS_E_NOMEM; 1508 1509 buf_ptr = (uint8_t *)wmi_buf_data(buf); 1510 cmd = (wmi_peer_delete_cmd_fixed_param *)buf_ptr; 1511 WMITLV_SET_HDR(&cmd->tlv_header, 1512 WMITLV_TAG_STRUC_wmi_peer_delete_cmd_fixed_param, 1513 WMITLV_GET_STRUCT_TLVLEN 1514 (wmi_peer_delete_cmd_fixed_param)); 1515 WMI_CHAR_ARRAY_TO_MAC_ADDR(peer_addr, &cmd->peer_macaddr); 1516 cmd->vdev_id = param->vdev_id; 1517 buf_ptr = (uint8_t *)(((uintptr_t) cmd) + sizeof(*cmd)); 1518 buf_ptr = peer_delete_add_mlo_params(buf_ptr, param); 1519 wmi_debug("peer_addr "QDF_MAC_ADDR_FMT" vdev_id %d", 1520 QDF_MAC_ADDR_REF(peer_addr), param->vdev_id); 1521 wmi_mtrace(WMI_PEER_DELETE_CMDID, cmd->vdev_id, 0); 1522 if (wmi_unified_cmd_send(wmi, buf, len, WMI_PEER_DELETE_CMDID)) { 1523 wmi_err("Failed to send peer delete command"); 1524 wmi_buf_free(buf); 1525 return QDF_STATUS_E_FAILURE; 1526 } 1527 return 0; 1528 } 1529 1530 static void 1531 wmi_get_converted_peer_bitmap(uint32_t src_peer_bitmap, uint32_t *dst_bitmap) 1532 { 1533 if (QDF_HAS_PARAM(src_peer_bitmap, WLAN_PEER_SELF)) 1534 WMI_VDEV_DELETE_ALL_PEER_BITMAP_SET(dst_bitmap, 1535 WMI_PEER_TYPE_DEFAULT); 1536 1537 if (QDF_HAS_PARAM(src_peer_bitmap, WLAN_PEER_AP)) 1538 WMI_VDEV_DELETE_ALL_PEER_BITMAP_SET(dst_bitmap, 1539 WMI_PEER_TYPE_BSS); 1540 1541 if (QDF_HAS_PARAM(src_peer_bitmap, WLAN_PEER_TDLS)) 1542 WMI_VDEV_DELETE_ALL_PEER_BITMAP_SET(dst_bitmap, 1543 WMI_PEER_TYPE_TDLS); 1544 1545 if (QDF_HAS_PARAM(src_peer_bitmap, WLAN_PEER_NDP)) 1546 WMI_VDEV_DELETE_ALL_PEER_BITMAP_SET(dst_bitmap, 1547 WMI_PEER_TYPE_NAN_DATA); 1548 1549 if (QDF_HAS_PARAM(src_peer_bitmap, WLAN_PEER_RTT_PASN)) 1550 WMI_VDEV_DELETE_ALL_PEER_BITMAP_SET(dst_bitmap, 1551 WMI_PEER_TYPE_PASN); 1552 } 1553 1554 /** 1555 * send_peer_delete_all_cmd_tlv() - send PEER delete all command to fw 1556 * @wmi: wmi handle 1557 * @param: pointer to hold peer delete all parameter 1558 * 1559 * Return: QDF_STATUS_SUCCESS for success or error code 1560 */ 1561 static QDF_STATUS send_peer_delete_all_cmd_tlv( 1562 wmi_unified_t wmi, 1563 struct peer_delete_all_params *param) 1564 { 1565 wmi_vdev_delete_all_peer_cmd_fixed_param *cmd; 1566 wmi_buf_t buf; 1567 int32_t len = sizeof(*cmd); 1568 1569 buf = wmi_buf_alloc(wmi, len); 1570 if (!buf) 1571 return QDF_STATUS_E_NOMEM; 1572 1573 cmd = (wmi_vdev_delete_all_peer_cmd_fixed_param *)wmi_buf_data(buf); 1574 WMITLV_SET_HDR( 1575 &cmd->tlv_header, 1576 WMITLV_TAG_STRUC_wmi_vdev_delete_all_peer_cmd_fixed_param, 1577 WMITLV_GET_STRUCT_TLVLEN 1578 (wmi_vdev_delete_all_peer_cmd_fixed_param)); 1579 cmd->vdev_id = param->vdev_id; 1580 wmi_get_converted_peer_bitmap(param->peer_type_bitmap, 1581 cmd->peer_type_bitmap); 1582 1583 wmi_debug("vdev_id %d peer_type_bitmap:%d", cmd->vdev_id, 1584 param->peer_type_bitmap); 1585 wmi_mtrace(WMI_VDEV_DELETE_ALL_PEER_CMDID, cmd->vdev_id, 0); 1586 if (wmi_unified_cmd_send(wmi, buf, len, 1587 WMI_VDEV_DELETE_ALL_PEER_CMDID)) { 1588 wmi_err("Failed to send peer del all command"); 1589 wmi_buf_free(buf); 1590 return QDF_STATUS_E_FAILURE; 1591 } 1592 1593 return QDF_STATUS_SUCCESS; 1594 } 1595 1596 /** 1597 * convert_host_peer_param_id_to_target_id_tlv - convert host peer param_id 1598 * to target id. 1599 * @peer_param_id: host param id. 1600 * 1601 * Return: Target param id. 1602 */ 1603 #ifdef ENABLE_HOST_TO_TARGET_CONVERSION 1604 static inline uint32_t convert_host_peer_param_id_to_target_id_tlv( 1605 uint32_t peer_param_id) 1606 { 1607 if (peer_param_id < QDF_ARRAY_SIZE(peer_param_tlv)) 1608 return peer_param_tlv[peer_param_id]; 1609 return WMI_UNAVAILABLE_PARAM; 1610 } 1611 #else 1612 static inline uint32_t convert_host_peer_param_id_to_target_id_tlv( 1613 uint32_t peer_param_id) 1614 { 1615 return peer_param_id; 1616 } 1617 #endif 1618 1619 /** 1620 * wmi_host_chan_bw_to_target_chan_bw - convert wmi_host_channel_width to 1621 * wmi_channel_width 1622 * @bw: wmi_host_channel_width channel width 1623 * 1624 * Return: wmi_channel_width 1625 */ 1626 static wmi_channel_width wmi_host_chan_bw_to_target_chan_bw( 1627 wmi_host_channel_width bw) 1628 { 1629 wmi_channel_width target_bw = WMI_CHAN_WIDTH_20; 1630 1631 switch (bw) { 1632 case WMI_HOST_CHAN_WIDTH_20: 1633 target_bw = WMI_CHAN_WIDTH_20; 1634 break; 1635 case WMI_HOST_CHAN_WIDTH_40: 1636 target_bw = WMI_CHAN_WIDTH_40; 1637 break; 1638 case WMI_HOST_CHAN_WIDTH_80: 1639 target_bw = WMI_CHAN_WIDTH_80; 1640 break; 1641 case WMI_HOST_CHAN_WIDTH_160: 1642 target_bw = WMI_CHAN_WIDTH_160; 1643 break; 1644 case WMI_HOST_CHAN_WIDTH_80P80: 1645 target_bw = WMI_CHAN_WIDTH_80P80; 1646 break; 1647 case WMI_HOST_CHAN_WIDTH_5: 1648 target_bw = WMI_CHAN_WIDTH_5; 1649 break; 1650 case WMI_HOST_CHAN_WIDTH_10: 1651 target_bw = WMI_CHAN_WIDTH_10; 1652 break; 1653 case WMI_HOST_CHAN_WIDTH_165: 1654 target_bw = WMI_CHAN_WIDTH_165; 1655 break; 1656 case WMI_HOST_CHAN_WIDTH_160P160: 1657 target_bw = WMI_CHAN_WIDTH_160P160; 1658 break; 1659 case WMI_HOST_CHAN_WIDTH_320: 1660 target_bw = WMI_CHAN_WIDTH_320; 1661 break; 1662 default: 1663 break; 1664 } 1665 1666 return target_bw; 1667 } 1668 1669 /** 1670 * convert_host_peer_param_value_to_target_value_tlv() - convert host peer 1671 * param value to target 1672 * @param_id: target param id 1673 * @param_value: host param value 1674 * 1675 * Return: target param value 1676 */ 1677 static uint32_t convert_host_peer_param_value_to_target_value_tlv( 1678 uint32_t param_id, uint32_t param_value) 1679 { 1680 uint32_t fw_param_value = 0; 1681 wmi_host_channel_width bw; 1682 uint16_t punc; 1683 1684 switch (param_id) { 1685 case WMI_PEER_CHWIDTH_PUNCTURE_20MHZ_BITMAP: 1686 bw = QDF_GET_BITS(param_value, 0, 8); 1687 punc = QDF_GET_BITS(param_value, 8, 16); 1688 QDF_SET_BITS(fw_param_value, 0, 8, 1689 wmi_host_chan_bw_to_target_chan_bw(bw)); 1690 QDF_SET_BITS(fw_param_value, 8, 16, ~punc); 1691 break; 1692 default: 1693 fw_param_value = param_value; 1694 break; 1695 } 1696 1697 return fw_param_value; 1698 } 1699 1700 #ifdef WLAN_SUPPORT_PPEDS 1701 /** 1702 * peer_ppe_ds_param_send_tlv() - Set peer PPE DS config 1703 * @wmi: wmi handle 1704 * @param: pointer to hold PPE DS config 1705 * 1706 * Return: QDF_STATUS_SUCCESS for success or error code 1707 */ 1708 static QDF_STATUS peer_ppe_ds_param_send_tlv(wmi_unified_t wmi, 1709 struct peer_ppe_ds_param *param) 1710 { 1711 wmi_peer_config_ppe_ds_cmd_fixed_param *cmd; 1712 wmi_buf_t buf; 1713 int32_t err; 1714 uint32_t len = sizeof(wmi_peer_config_ppe_ds_cmd_fixed_param); 1715 1716 buf = wmi_buf_alloc(wmi, sizeof(*cmd)); 1717 if (!buf) 1718 return QDF_STATUS_E_NOMEM; 1719 1720 cmd = (wmi_peer_config_ppe_ds_cmd_fixed_param *)wmi_buf_data(buf); 1721 WMITLV_SET_HDR(&cmd->tlv_header, 1722 WMITLV_TAG_STRUC_wmi_peer_config_ppe_ds_cmd_fixed_param, 1723 WMITLV_GET_STRUCT_TLVLEN 1724 (wmi_peer_config_ppe_ds_cmd_fixed_param)); 1725 1726 WMI_CHAR_ARRAY_TO_MAC_ADDR(param->peer_macaddr, &cmd->peer_macaddr); 1727 1728 if (param->ppe_routing_enabled) 1729 cmd->ppe_routing_enable = param->use_ppe ? 1730 WMI_AST_USE_PPE_ENABLED : WMI_AST_USE_PPE_DISABLED; 1731 else 1732 cmd->ppe_routing_enable = WMI_PPE_ROUTING_DISABLED; 1733 1734 cmd->service_code = param->service_code; 1735 cmd->priority_valid = param->priority_valid; 1736 cmd->src_info = param->src_info; 1737 cmd->vdev_id = param->vdev_id; 1738 1739 wmi_debug("vdev_id %d peer_mac: QDF_MAC_ADDR_FMT\n" 1740 "ppe_routing_enable: %u service_code: %u\n" 1741 "priority_valid:%d src_info:%u", 1742 param->vdev_id, 1743 QDF_MAC_ADDR_REF(param->peer_macaddr), 1744 param->ppe_routing_enabled, 1745 param->service_code, 1746 param->priority_valid, 1747 param->src_info); 1748 1749 wmi_mtrace(WMI_PEER_CONFIG_PPE_DS_CMDID, cmd->vdev_id, 0); 1750 err = wmi_unified_cmd_send(wmi, buf, 1751 len, 1752 WMI_PEER_CONFIG_PPE_DS_CMDID); 1753 if (err) { 1754 wmi_err("Failed to send ppeds config cmd"); 1755 wmi_buf_free(buf); 1756 return QDF_STATUS_E_FAILURE; 1757 } 1758 1759 return 0; 1760 } 1761 #endif /* WLAN_SUPPORT_PPEDS */ 1762 1763 /** 1764 * send_peer_param_cmd_tlv() - set peer parameter in fw 1765 * @wmi: wmi handle 1766 * @peer_addr: peer mac address 1767 * @param: pointer to hold peer set parameter 1768 * 1769 * Return: QDF_STATUS_SUCCESS for success or error code 1770 */ 1771 static QDF_STATUS send_peer_param_cmd_tlv(wmi_unified_t wmi, 1772 uint8_t peer_addr[QDF_MAC_ADDR_SIZE], 1773 struct peer_set_params *param) 1774 { 1775 wmi_peer_set_param_cmd_fixed_param *cmd; 1776 wmi_buf_t buf; 1777 int32_t err; 1778 uint32_t param_id; 1779 uint32_t param_value; 1780 1781 param_id = convert_host_peer_param_id_to_target_id_tlv(param->param_id); 1782 if (param_id == WMI_UNAVAILABLE_PARAM) { 1783 wmi_err("Unavailable param %d", param->param_id); 1784 return QDF_STATUS_E_NOSUPPORT; 1785 } 1786 param_value = convert_host_peer_param_value_to_target_value_tlv( 1787 param_id, param->param_value); 1788 buf = wmi_buf_alloc(wmi, sizeof(*cmd)); 1789 if (!buf) 1790 return QDF_STATUS_E_NOMEM; 1791 1792 cmd = (wmi_peer_set_param_cmd_fixed_param *) wmi_buf_data(buf); 1793 WMITLV_SET_HDR(&cmd->tlv_header, 1794 WMITLV_TAG_STRUC_wmi_peer_set_param_cmd_fixed_param, 1795 WMITLV_GET_STRUCT_TLVLEN 1796 (wmi_peer_set_param_cmd_fixed_param)); 1797 cmd->vdev_id = param->vdev_id; 1798 WMI_CHAR_ARRAY_TO_MAC_ADDR(peer_addr, &cmd->peer_macaddr); 1799 cmd->param_id = param_id; 1800 cmd->param_value = param_value; 1801 1802 wmi_debug("vdev_id %d peer_mac: "QDF_MAC_ADDR_FMT" param_id: %u param_value: %x", 1803 cmd->vdev_id, 1804 QDF_MAC_ADDR_REF(peer_addr), param->param_id, 1805 cmd->param_value); 1806 1807 wmi_mtrace(WMI_PEER_SET_PARAM_CMDID, cmd->vdev_id, 0); 1808 err = wmi_unified_cmd_send(wmi, buf, 1809 sizeof(wmi_peer_set_param_cmd_fixed_param), 1810 WMI_PEER_SET_PARAM_CMDID); 1811 if (err) { 1812 wmi_err("Failed to send set_param cmd"); 1813 wmi_buf_free(buf); 1814 return QDF_STATUS_E_FAILURE; 1815 } 1816 1817 return 0; 1818 } 1819 1820 /** 1821 * send_vdev_up_cmd_tlv() - send vdev up command in fw 1822 * @wmi: wmi handle 1823 * @bssid: bssid 1824 * @params: pointer to hold vdev up parameter 1825 * 1826 * Return: QDF_STATUS_SUCCESS for success or error code 1827 */ 1828 static QDF_STATUS send_vdev_up_cmd_tlv(wmi_unified_t wmi, 1829 uint8_t bssid[QDF_MAC_ADDR_SIZE], 1830 struct vdev_up_params *params) 1831 { 1832 wmi_vdev_up_cmd_fixed_param *cmd; 1833 wmi_buf_t buf; 1834 int32_t len = sizeof(*cmd); 1835 1836 wmi_debug("VDEV_UP"); 1837 wmi_debug("vdev_id %d aid %d profile idx %d count %d bssid " 1838 QDF_MAC_ADDR_FMT, 1839 params->vdev_id, params->assoc_id, 1840 params->profile_idx, params->profile_num, 1841 QDF_MAC_ADDR_REF(bssid)); 1842 buf = wmi_buf_alloc(wmi, len); 1843 if (!buf) 1844 return QDF_STATUS_E_NOMEM; 1845 1846 cmd = (wmi_vdev_up_cmd_fixed_param *) wmi_buf_data(buf); 1847 WMITLV_SET_HDR(&cmd->tlv_header, 1848 WMITLV_TAG_STRUC_wmi_vdev_up_cmd_fixed_param, 1849 WMITLV_GET_STRUCT_TLVLEN(wmi_vdev_up_cmd_fixed_param)); 1850 cmd->vdev_id = params->vdev_id; 1851 cmd->vdev_assoc_id = params->assoc_id; 1852 cmd->profile_idx = params->profile_idx; 1853 cmd->profile_num = params->profile_num; 1854 WMI_CHAR_ARRAY_TO_MAC_ADDR(params->trans_bssid, &cmd->trans_bssid); 1855 WMI_CHAR_ARRAY_TO_MAC_ADDR(bssid, &cmd->vdev_bssid); 1856 wmi_mtrace(WMI_VDEV_UP_CMDID, cmd->vdev_id, 0); 1857 if (wmi_unified_cmd_send(wmi, buf, len, WMI_VDEV_UP_CMDID)) { 1858 wmi_err("Failed to send vdev up command"); 1859 wmi_buf_free(buf); 1860 return QDF_STATUS_E_FAILURE; 1861 } 1862 1863 return 0; 1864 } 1865 1866 #ifdef ENABLE_HOST_TO_TARGET_CONVERSION 1867 static uint32_t convert_peer_type_host_to_target(uint32_t peer_type) 1868 { 1869 /* Host sets the peer_type as 0 for the peer create command sent to FW 1870 * other than PASN peer create command. 1871 */ 1872 if (peer_type == WLAN_PEER_RTT_PASN) 1873 return WMI_PEER_TYPE_PASN; 1874 1875 return peer_type; 1876 } 1877 #else 1878 static uint32_t convert_peer_type_host_to_target(uint32_t peer_type) 1879 { 1880 return peer_type; 1881 } 1882 #endif 1883 /** 1884 * send_peer_create_cmd_tlv() - send peer create command to fw 1885 * @wmi: wmi handle 1886 * @param: peer create parameters 1887 * 1888 * Return: QDF_STATUS_SUCCESS for success or error code 1889 */ 1890 static QDF_STATUS send_peer_create_cmd_tlv(wmi_unified_t wmi, 1891 struct peer_create_params *param) 1892 { 1893 wmi_peer_create_cmd_fixed_param *cmd; 1894 wmi_buf_t buf; 1895 uint8_t *buf_ptr; 1896 int32_t len = sizeof(*cmd); 1897 1898 len += peer_create_mlo_params_size(param); 1899 buf = wmi_buf_alloc(wmi, len); 1900 if (!buf) 1901 return QDF_STATUS_E_NOMEM; 1902 1903 cmd = (wmi_peer_create_cmd_fixed_param *) wmi_buf_data(buf); 1904 WMITLV_SET_HDR(&cmd->tlv_header, 1905 WMITLV_TAG_STRUC_wmi_peer_create_cmd_fixed_param, 1906 WMITLV_GET_STRUCT_TLVLEN 1907 (wmi_peer_create_cmd_fixed_param)); 1908 WMI_CHAR_ARRAY_TO_MAC_ADDR(param->peer_addr, &cmd->peer_macaddr); 1909 cmd->peer_type = convert_peer_type_host_to_target(param->peer_type); 1910 cmd->vdev_id = param->vdev_id; 1911 1912 buf_ptr = (uint8_t *)wmi_buf_data(buf); 1913 buf_ptr += sizeof(*cmd); 1914 buf_ptr = peer_create_add_mlo_params(buf_ptr, param); 1915 wmi_mtrace(WMI_PEER_CREATE_CMDID, cmd->vdev_id, 0); 1916 if (wmi_unified_cmd_send(wmi, buf, len, WMI_PEER_CREATE_CMDID)) { 1917 wmi_err("Failed to send WMI_PEER_CREATE_CMDID"); 1918 wmi_buf_free(buf); 1919 return QDF_STATUS_E_FAILURE; 1920 } 1921 wmi_debug("peer_addr "QDF_MAC_ADDR_FMT" vdev_id %d", 1922 QDF_MAC_ADDR_REF(param->peer_addr), 1923 param->vdev_id); 1924 1925 return 0; 1926 } 1927 1928 /** 1929 * send_peer_rx_reorder_queue_setup_cmd_tlv() - send rx reorder setup 1930 * command to fw 1931 * @wmi: wmi handle 1932 * @param: Rx reorder queue setup parameters 1933 * 1934 * Return: QDF_STATUS_SUCCESS for success or error code 1935 */ 1936 static 1937 QDF_STATUS send_peer_rx_reorder_queue_setup_cmd_tlv(wmi_unified_t wmi, 1938 struct rx_reorder_queue_setup_params *param) 1939 { 1940 wmi_peer_reorder_queue_setup_cmd_fixed_param *cmd; 1941 wmi_buf_t buf; 1942 int32_t len = sizeof(*cmd); 1943 1944 buf = wmi_buf_alloc(wmi, len); 1945 if (!buf) 1946 return QDF_STATUS_E_NOMEM; 1947 1948 cmd = (wmi_peer_reorder_queue_setup_cmd_fixed_param *)wmi_buf_data(buf); 1949 WMITLV_SET_HDR(&cmd->tlv_header, 1950 WMITLV_TAG_STRUC_wmi_peer_reorder_queue_setup_cmd_fixed_param, 1951 WMITLV_GET_STRUCT_TLVLEN 1952 (wmi_peer_reorder_queue_setup_cmd_fixed_param)); 1953 WMI_CHAR_ARRAY_TO_MAC_ADDR(param->peer_macaddr, &cmd->peer_macaddr); 1954 cmd->vdev_id = param->vdev_id; 1955 cmd->tid = param->tid; 1956 cmd->queue_ptr_lo = param->hw_qdesc_paddr_lo; 1957 cmd->queue_ptr_hi = param->hw_qdesc_paddr_hi; 1958 cmd->queue_no = param->queue_no; 1959 cmd->ba_window_size_valid = param->ba_window_size_valid; 1960 cmd->ba_window_size = param->ba_window_size; 1961 1962 1963 wmi_mtrace(WMI_PEER_REORDER_QUEUE_SETUP_CMDID, cmd->vdev_id, 0); 1964 if (wmi_unified_cmd_send(wmi, buf, len, 1965 WMI_PEER_REORDER_QUEUE_SETUP_CMDID)) { 1966 wmi_err("Fail to send WMI_PEER_REORDER_QUEUE_SETUP_CMDID"); 1967 wmi_buf_free(buf); 1968 return QDF_STATUS_E_FAILURE; 1969 } 1970 wmi_debug("peer_macaddr "QDF_MAC_ADDR_FMT" vdev_id %d, tid %d", 1971 QDF_MAC_ADDR_REF(param->peer_macaddr), 1972 param->vdev_id, param->tid); 1973 1974 return QDF_STATUS_SUCCESS; 1975 } 1976 1977 /** 1978 * send_peer_rx_reorder_queue_remove_cmd_tlv() - send rx reorder remove 1979 * command to fw 1980 * @wmi: wmi handle 1981 * @param: Rx reorder queue remove parameters 1982 * 1983 * Return: QDF_STATUS_SUCCESS for success or error code 1984 */ 1985 static 1986 QDF_STATUS send_peer_rx_reorder_queue_remove_cmd_tlv(wmi_unified_t wmi, 1987 struct rx_reorder_queue_remove_params *param) 1988 { 1989 wmi_peer_reorder_queue_remove_cmd_fixed_param *cmd; 1990 wmi_buf_t buf; 1991 int32_t len = sizeof(*cmd); 1992 1993 buf = wmi_buf_alloc(wmi, len); 1994 if (!buf) 1995 return QDF_STATUS_E_NOMEM; 1996 1997 cmd = (wmi_peer_reorder_queue_remove_cmd_fixed_param *) 1998 wmi_buf_data(buf); 1999 WMITLV_SET_HDR(&cmd->tlv_header, 2000 WMITLV_TAG_STRUC_wmi_peer_reorder_queue_remove_cmd_fixed_param, 2001 WMITLV_GET_STRUCT_TLVLEN 2002 (wmi_peer_reorder_queue_remove_cmd_fixed_param)); 2003 WMI_CHAR_ARRAY_TO_MAC_ADDR(param->peer_macaddr, &cmd->peer_macaddr); 2004 cmd->vdev_id = param->vdev_id; 2005 cmd->tid_mask = param->peer_tid_bitmap; 2006 2007 wmi_mtrace(WMI_PEER_REORDER_QUEUE_REMOVE_CMDID, cmd->vdev_id, 0); 2008 if (wmi_unified_cmd_send(wmi, buf, len, 2009 WMI_PEER_REORDER_QUEUE_REMOVE_CMDID)) { 2010 wmi_err("Fail to send WMI_PEER_REORDER_QUEUE_REMOVE_CMDID"); 2011 wmi_buf_free(buf); 2012 return QDF_STATUS_E_FAILURE; 2013 } 2014 wmi_debug("peer_macaddr "QDF_MAC_ADDR_FMT" vdev_id %d, tid_map %d", 2015 QDF_MAC_ADDR_REF(param->peer_macaddr), 2016 param->vdev_id, param->peer_tid_bitmap); 2017 2018 return QDF_STATUS_SUCCESS; 2019 } 2020 2021 #ifdef WLAN_SUPPORT_GREEN_AP 2022 /** 2023 * send_green_ap_ps_cmd_tlv() - enable green ap powersave command 2024 * @wmi_handle: wmi handle 2025 * @value: value 2026 * @pdev_id: pdev id to have radio context 2027 * 2028 * Return: QDF_STATUS_SUCCESS for success or error code 2029 */ 2030 static QDF_STATUS send_green_ap_ps_cmd_tlv(wmi_unified_t wmi_handle, 2031 uint32_t value, uint8_t pdev_id) 2032 { 2033 wmi_pdev_green_ap_ps_enable_cmd_fixed_param *cmd; 2034 wmi_buf_t buf; 2035 int32_t len = sizeof(*cmd); 2036 2037 wmi_debug("Set Green AP PS val %d", value); 2038 2039 buf = wmi_buf_alloc(wmi_handle, len); 2040 if (!buf) 2041 return QDF_STATUS_E_NOMEM; 2042 2043 cmd = (wmi_pdev_green_ap_ps_enable_cmd_fixed_param *) wmi_buf_data(buf); 2044 WMITLV_SET_HDR(&cmd->tlv_header, 2045 WMITLV_TAG_STRUC_wmi_pdev_green_ap_ps_enable_cmd_fixed_param, 2046 WMITLV_GET_STRUCT_TLVLEN 2047 (wmi_pdev_green_ap_ps_enable_cmd_fixed_param)); 2048 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 2049 wmi_handle, 2050 pdev_id); 2051 cmd->enable = value; 2052 2053 wmi_mtrace(WMI_PDEV_GREEN_AP_PS_ENABLE_CMDID, NO_SESSION, 0); 2054 if (wmi_unified_cmd_send(wmi_handle, buf, len, 2055 WMI_PDEV_GREEN_AP_PS_ENABLE_CMDID)) { 2056 wmi_err("Set Green AP PS param Failed val %d", value); 2057 wmi_buf_free(buf); 2058 return QDF_STATUS_E_FAILURE; 2059 } 2060 2061 return 0; 2062 } 2063 #endif 2064 2065 #ifdef WLAN_SUPPORT_GAP_LL_PS_MODE 2066 static QDF_STATUS send_green_ap_ll_ps_cmd_tlv(wmi_unified_t wmi_handle, 2067 struct green_ap_ll_ps_cmd_param *green_ap_ll_ps_params) 2068 { 2069 uint32_t len; 2070 wmi_buf_t buf; 2071 wmi_xgap_enable_cmd_fixed_param *cmd; 2072 2073 len = sizeof(*cmd); 2074 2075 wmi_debug("Green AP low latency PS: bcn interval: %u state: %u cookie: %u", 2076 green_ap_ll_ps_params->bcn_interval, 2077 green_ap_ll_ps_params->state, 2078 green_ap_ll_ps_params->cookie); 2079 2080 buf = wmi_buf_alloc(wmi_handle, len); 2081 if (!buf) 2082 return QDF_STATUS_E_NOMEM; 2083 2084 cmd = (wmi_xgap_enable_cmd_fixed_param *)wmi_buf_data(buf); 2085 WMITLV_SET_HDR(&cmd->tlv_header, 2086 WMITLV_TAG_STRUC_wmi_xgap_enable_cmd_fixed_param, 2087 WMITLV_GET_STRUCT_TLVLEN 2088 (wmi_xgap_enable_cmd_fixed_param)); 2089 2090 cmd->beacon_interval = green_ap_ll_ps_params->bcn_interval; 2091 cmd->sap_lp_flag = green_ap_ll_ps_params->state; 2092 cmd->dialog_token = green_ap_ll_ps_params->cookie; 2093 2094 wmi_mtrace(WMI_XGAP_ENABLE_CMDID, NO_SESSION, 0); 2095 if (wmi_unified_cmd_send(wmi_handle, buf, len, 2096 WMI_XGAP_ENABLE_CMDID)) { 2097 wmi_err("Green AP Low latency PS cmd Failed"); 2098 wmi_buf_free(buf); 2099 return QDF_STATUS_E_FAILURE; 2100 } 2101 2102 return QDF_STATUS_SUCCESS; 2103 } 2104 #endif 2105 2106 /** 2107 * send_pdev_utf_cmd_tlv() - send utf command to fw 2108 * @wmi_handle: wmi handle 2109 * @param: pointer to pdev_utf_params 2110 * @mac_id: mac id to have radio context 2111 * 2112 * Return: QDF_STATUS_SUCCESS for success or error code 2113 */ 2114 static QDF_STATUS 2115 send_pdev_utf_cmd_tlv(wmi_unified_t wmi_handle, 2116 struct pdev_utf_params *param, 2117 uint8_t mac_id) 2118 { 2119 wmi_buf_t buf; 2120 uint8_t *cmd; 2121 /* if param->len is 0 no data is sent, return error */ 2122 QDF_STATUS ret = QDF_STATUS_E_INVAL; 2123 static uint8_t msgref = 1; 2124 uint8_t segNumber = 0, segInfo, numSegments; 2125 uint16_t chunk_len, total_bytes; 2126 uint8_t *bufpos; 2127 struct seg_hdr_info segHdrInfo; 2128 2129 bufpos = param->utf_payload; 2130 total_bytes = param->len; 2131 ASSERT(total_bytes / MAX_WMI_UTF_LEN == 2132 (uint8_t) (total_bytes / MAX_WMI_UTF_LEN)); 2133 numSegments = (uint8_t) (total_bytes / MAX_WMI_UTF_LEN); 2134 2135 if (param->len - (numSegments * MAX_WMI_UTF_LEN)) 2136 numSegments++; 2137 2138 while (param->len) { 2139 if (param->len > MAX_WMI_UTF_LEN) 2140 chunk_len = MAX_WMI_UTF_LEN; /* MAX message */ 2141 else 2142 chunk_len = param->len; 2143 2144 buf = wmi_buf_alloc(wmi_handle, 2145 (chunk_len + sizeof(segHdrInfo) + 2146 WMI_TLV_HDR_SIZE)); 2147 if (!buf) 2148 return QDF_STATUS_E_NOMEM; 2149 2150 cmd = (uint8_t *) wmi_buf_data(buf); 2151 2152 segHdrInfo.len = total_bytes; 2153 segHdrInfo.msgref = msgref; 2154 segInfo = ((numSegments << 4) & 0xF0) | (segNumber & 0xF); 2155 segHdrInfo.segmentInfo = segInfo; 2156 segHdrInfo.pad = 0; 2157 2158 wmi_debug("segHdrInfo.len = %d, segHdrInfo.msgref = %d," 2159 " segHdrInfo.segmentInfo = %d", 2160 segHdrInfo.len, segHdrInfo.msgref, 2161 segHdrInfo.segmentInfo); 2162 2163 wmi_debug("total_bytes %d segNumber %d totalSegments %d" 2164 " chunk len %d", total_bytes, segNumber, 2165 numSegments, chunk_len); 2166 2167 segNumber++; 2168 2169 WMITLV_SET_HDR(cmd, WMITLV_TAG_ARRAY_BYTE, 2170 (chunk_len + sizeof(segHdrInfo))); 2171 cmd += WMI_TLV_HDR_SIZE; 2172 memcpy(cmd, &segHdrInfo, sizeof(segHdrInfo)); /* 4 bytes */ 2173 WMI_HOST_IF_MSG_COPY_CHAR_ARRAY(&cmd[sizeof(segHdrInfo)], 2174 bufpos, chunk_len); 2175 2176 wmi_mtrace(WMI_PDEV_UTF_CMDID, NO_SESSION, 0); 2177 ret = wmi_unified_cmd_send(wmi_handle, buf, 2178 (chunk_len + sizeof(segHdrInfo) + 2179 WMI_TLV_HDR_SIZE), 2180 WMI_PDEV_UTF_CMDID); 2181 2182 if (QDF_IS_STATUS_ERROR(ret)) { 2183 wmi_err("Failed to send WMI_PDEV_UTF_CMDID command"); 2184 wmi_buf_free(buf); 2185 break; 2186 } 2187 2188 param->len -= chunk_len; 2189 bufpos += chunk_len; 2190 } 2191 2192 msgref++; 2193 2194 return ret; 2195 } 2196 2197 #ifdef ENABLE_HOST_TO_TARGET_CONVERSION 2198 static inline uint32_t convert_host_pdev_param_tlv(uint32_t host_param) 2199 { 2200 if (host_param < QDF_ARRAY_SIZE(pdev_param_tlv)) 2201 return pdev_param_tlv[host_param]; 2202 return WMI_UNAVAILABLE_PARAM; 2203 } 2204 2205 static inline uint32_t convert_host_vdev_param_tlv(uint32_t host_param) 2206 { 2207 if (host_param < QDF_ARRAY_SIZE(vdev_param_tlv)) 2208 return vdev_param_tlv[host_param]; 2209 return WMI_UNAVAILABLE_PARAM; 2210 } 2211 #else 2212 static inline uint32_t convert_host_pdev_param_tlv(uint32_t host_param) 2213 { 2214 return host_param; 2215 } 2216 2217 static inline uint32_t convert_host_vdev_param_tlv(uint32_t host_param) 2218 { 2219 return host_param; 2220 } 2221 #endif /* end of ENABLE_HOST_TO_TARGET_CONVERSION */ 2222 2223 /** 2224 * send_pdev_param_cmd_tlv() - set pdev parameters 2225 * @wmi_handle: wmi handle 2226 * @param: pointer to pdev parameter 2227 * @mac_id: radio context 2228 * 2229 * Return: QDF_STATUS_SUCCESS for success or error code 2230 */ 2231 static QDF_STATUS 2232 send_pdev_param_cmd_tlv(wmi_unified_t wmi_handle, 2233 struct pdev_params *param, 2234 uint8_t mac_id) 2235 { 2236 QDF_STATUS ret; 2237 wmi_pdev_set_param_cmd_fixed_param *cmd; 2238 wmi_buf_t buf; 2239 uint16_t len = sizeof(*cmd); 2240 uint32_t pdev_param; 2241 2242 pdev_param = convert_host_pdev_param_tlv(param->param_id); 2243 if (pdev_param == WMI_UNAVAILABLE_PARAM) { 2244 wmi_err("Unavailable param %d", param->param_id); 2245 return QDF_STATUS_E_INVAL; 2246 } 2247 2248 buf = wmi_buf_alloc(wmi_handle, len); 2249 if (!buf) 2250 return QDF_STATUS_E_NOMEM; 2251 2252 cmd = (wmi_pdev_set_param_cmd_fixed_param *) wmi_buf_data(buf); 2253 WMITLV_SET_HDR(&cmd->tlv_header, 2254 WMITLV_TAG_STRUC_wmi_pdev_set_param_cmd_fixed_param, 2255 WMITLV_GET_STRUCT_TLVLEN 2256 (wmi_pdev_set_param_cmd_fixed_param)); 2257 if (param->is_host_pdev_id) 2258 cmd->pdev_id = wmi_handle->ops->convert_host_pdev_id_to_target( 2259 wmi_handle, 2260 mac_id); 2261 else 2262 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 2263 wmi_handle, 2264 mac_id); 2265 cmd->param_id = pdev_param; 2266 cmd->param_value = param->param_value; 2267 wmi_nofl_debug("Set pdev %d param 0x%x to %u", cmd->pdev_id, 2268 cmd->param_id, cmd->param_value); 2269 wmi_mtrace(WMI_PDEV_SET_PARAM_CMDID, NO_SESSION, 0); 2270 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 2271 WMI_PDEV_SET_PARAM_CMDID); 2272 if (QDF_IS_STATUS_ERROR(ret)) { 2273 wmi_buf_free(buf); 2274 } 2275 return ret; 2276 } 2277 2278 /** 2279 * send_multi_param_cmd_using_pdev_set_param_tlv() - set pdev parameters 2280 * @wmi_handle: wmi handle 2281 * @params: pointer to hold set_multiple_pdev_vdev_param info 2282 * 2283 * Return: QDF_STATUS_SUCCESS for success or error code 2284 */ 2285 static QDF_STATUS 2286 send_multi_param_cmd_using_pdev_set_param_tlv(wmi_unified_t wmi_handle, 2287 struct set_multiple_pdev_vdev_param *params) 2288 { 2289 uint8_t index; 2290 struct pdev_params pdevparam; 2291 uint8_t n_params = params->n_params; 2292 2293 pdevparam.is_host_pdev_id = params->is_host_pdev_id; 2294 for (index = 0; index < n_params; index++) { 2295 pdevparam.param_id = params->params[index].param_id; 2296 pdevparam.param_value = params->params[index].param_value; 2297 if (QDF_IS_STATUS_ERROR(send_pdev_param_cmd_tlv(wmi_handle, 2298 &pdevparam, 2299 params->dev_id))) { 2300 wmi_err("failed to send pdev setparam:%d", 2301 pdevparam.param_id); 2302 return QDF_STATUS_E_FAILURE; 2303 } 2304 } 2305 return QDF_STATUS_SUCCESS; 2306 } 2307 2308 #ifdef WLAN_PDEV_VDEV_SEND_MULTI_PARAM 2309 2310 /** 2311 * convert_host_pdev_vdev_param_id_to_target()- convert host params to target params 2312 * @params: pointer to point set_multiple_pdev_vdev_param info 2313 * 2314 * Return: returns QDF_STATUS 2315 */ 2316 static QDF_STATUS 2317 convert_host_pdev_vdev_param_id_to_target(struct set_multiple_pdev_vdev_param *params) 2318 { 2319 uint8_t index; 2320 uint32_t dev_paramid; 2321 uint8_t num = params->n_params; 2322 2323 if (params->param_type == MLME_PDEV_SETPARAM) { 2324 for (index = 0; index < num; index++) { 2325 dev_paramid = convert_host_pdev_param_tlv(params->params[index].param_id); 2326 if (dev_paramid == WMI_UNAVAILABLE_PARAM) { 2327 wmi_err("pdev param %d not available", 2328 params->params[index].param_id); 2329 return QDF_STATUS_E_INVAL; 2330 } 2331 params->params[index].param_id = dev_paramid; 2332 } 2333 } else if (params->param_type == MLME_VDEV_SETPARAM) { 2334 for (index = 0; index < num; index++) { 2335 dev_paramid = convert_host_vdev_param_tlv(params->params[index].param_id); 2336 if (dev_paramid == WMI_UNAVAILABLE_PARAM) { 2337 wmi_err("vdev param %d not available", 2338 params->params[index].param_id); 2339 return QDF_STATUS_E_INVAL; 2340 } 2341 params->params[index].param_id = dev_paramid; 2342 } 2343 } else { 2344 wmi_err("invalid param type"); 2345 return QDF_STATUS_E_INVAL; 2346 } 2347 return QDF_STATUS_SUCCESS; 2348 } 2349 2350 /** 2351 * send_multi_pdev_vdev_set_param_cmd_tlv()-set pdev/vdev params 2352 * @wmi_handle: wmi handle 2353 * @params: pointer to hold set_multiple_pdev_vdev_param info 2354 * 2355 * Return: returns QDF_STATUS 2356 */ 2357 static QDF_STATUS 2358 send_multi_pdev_vdev_set_param_cmd_tlv( 2359 wmi_unified_t wmi_handle, 2360 struct set_multiple_pdev_vdev_param *params) 2361 { 2362 uint8_t *buf_ptr; 2363 QDF_STATUS ret; 2364 wmi_buf_t buf; 2365 wmi_set_param_info *setparam; 2366 wmi_set_multiple_pdev_vdev_param_cmd_fixed_param *cmd; 2367 uint8_t num = params->n_params; 2368 uint16_t len; 2369 uint8_t index = 0; 2370 const char *dev_string[] = {"pdev", "vdev"}; 2371 2372 if (convert_host_pdev_vdev_param_id_to_target(params)) 2373 return QDF_STATUS_E_INVAL; 2374 2375 len = sizeof(*cmd) + WMI_TLV_HDR_SIZE + (num * sizeof(*setparam)); 2376 buf = wmi_buf_alloc(wmi_handle, len); 2377 if (!buf) 2378 return QDF_STATUS_E_NOMEM; 2379 2380 buf_ptr = (uint8_t *)wmi_buf_data(buf); 2381 cmd = (wmi_set_multiple_pdev_vdev_param_cmd_fixed_param *)buf_ptr; 2382 2383 WMITLV_SET_HDR(&cmd->tlv_header, 2384 WMITLV_TAG_STRUC_wmi_set_multiple_pdev_vdev_param_cmd_fixed_param, 2385 WMITLV_GET_STRUCT_TLVLEN(wmi_set_multiple_pdev_vdev_param_cmd_fixed_param)); 2386 2387 cmd->is_vdev = params->param_type; 2388 if (params->param_type == MLME_PDEV_SETPARAM) { 2389 if (params->is_host_pdev_id) 2390 params->dev_id = wmi_handle->ops->convert_host_pdev_id_to_target(wmi_handle, 2391 params->dev_id); 2392 else 2393 params->dev_id = wmi_handle->ops->convert_pdev_id_host_to_target(wmi_handle, 2394 params->dev_id); 2395 } 2396 cmd->dev_id = params->dev_id; 2397 buf_ptr += sizeof(wmi_set_multiple_pdev_vdev_param_cmd_fixed_param); 2398 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, (num * sizeof(*setparam))); 2399 buf_ptr += WMI_TLV_HDR_SIZE; 2400 for (index = 0; index < num; index++) { 2401 setparam = (wmi_set_param_info *)buf_ptr; 2402 WMITLV_SET_HDR(&setparam->tlv_header, 2403 WMITLV_TAG_STRUC_wmi_set_param_info, 2404 WMITLV_GET_STRUCT_TLVLEN(*setparam)); 2405 setparam->param_id = params->params[index].param_id; 2406 setparam->param_value = params->params[index].param_value; 2407 wmi_nofl_debug("Set %s %d param 0x%x to %u", 2408 dev_string[cmd->is_vdev], params->dev_id, 2409 setparam->param_id, setparam->param_value); 2410 buf_ptr += sizeof(*setparam); 2411 } 2412 wmi_mtrace(WMI_SET_MULTIPLE_PDEV_VDEV_PARAM_CMDID, 2413 cmd->dev_id, 0); 2414 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 2415 WMI_SET_MULTIPLE_PDEV_VDEV_PARAM_CMDID); 2416 if (QDF_IS_STATUS_ERROR(ret)) { 2417 wmi_buf_free(buf); 2418 } 2419 return ret; 2420 } 2421 2422 /** 2423 * send_multiple_pdev_param_cmd_tlv() - set pdev parameters 2424 * @wmi_handle: wmi handle 2425 * @params: pointer to set_multiple_pdev_vdev_param structure 2426 * 2427 * Return: QDF_STATUS_SUCCESS for success or error code 2428 */ 2429 static QDF_STATUS 2430 send_multiple_pdev_param_cmd_tlv(wmi_unified_t wmi_handle, 2431 struct set_multiple_pdev_vdev_param *params) 2432 { 2433 if (!wmi_service_enabled(wmi_handle, 2434 wmi_service_combined_set_param_support)) 2435 return send_multi_param_cmd_using_pdev_set_param_tlv(wmi_handle, 2436 params); 2437 return send_multi_pdev_vdev_set_param_cmd_tlv(wmi_handle, params); 2438 } 2439 2440 #else /* WLAN_PDEV_VDEV_SEND_MULTI_PARAM */ 2441 /** 2442 * send_multiple_pdev_param_cmd_tlv() - set pdev parameters 2443 * @wmi_handle: wmi handle 2444 * @params: pointer to set_multiple_pdev_vdev_param structure 2445 * 2446 * Return: QDF_STATUS_SUCCESS for success or error code 2447 */ 2448 static QDF_STATUS 2449 send_multiple_pdev_param_cmd_tlv(wmi_unified_t wmi_handle, 2450 struct set_multiple_pdev_vdev_param *params) 2451 { 2452 return send_multi_param_cmd_using_pdev_set_param_tlv(wmi_handle, params); 2453 } 2454 #endif /* end of WLAN_PDEV_VDEV_SEND_MULTI_PARAM */ 2455 2456 /** 2457 * send_pdev_set_hw_mode_cmd_tlv() - Send WMI_PDEV_SET_HW_MODE_CMDID to FW 2458 * @wmi_handle: wmi handle 2459 * @hw_mode_index: The HW_Mode field is a enumerated type that is selected 2460 * from the HW_Mode table, which is returned in the WMI_SERVICE_READY_EVENTID. 2461 * 2462 * Provides notification to the WLAN firmware that host driver is requesting a 2463 * HardWare (HW) Mode change. This command is needed to support iHelium in the 2464 * configurations that include the Dual Band Simultaneous (DBS) feature. 2465 * 2466 * Return: Success if the cmd is sent successfully to the firmware 2467 */ 2468 static QDF_STATUS send_pdev_set_hw_mode_cmd_tlv(wmi_unified_t wmi_handle, 2469 uint32_t hw_mode_index) 2470 { 2471 wmi_pdev_set_hw_mode_cmd_fixed_param *cmd; 2472 wmi_buf_t buf; 2473 uint32_t len; 2474 2475 len = sizeof(*cmd); 2476 2477 buf = wmi_buf_alloc(wmi_handle, len); 2478 if (!buf) 2479 return QDF_STATUS_E_NOMEM; 2480 2481 cmd = (wmi_pdev_set_hw_mode_cmd_fixed_param *)wmi_buf_data(buf); 2482 WMITLV_SET_HDR(&cmd->tlv_header, 2483 WMITLV_TAG_STRUC_wmi_pdev_set_hw_mode_cmd_fixed_param, 2484 WMITLV_GET_STRUCT_TLVLEN( 2485 wmi_pdev_set_hw_mode_cmd_fixed_param)); 2486 2487 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 2488 wmi_handle, 2489 WMI_HOST_PDEV_ID_SOC); 2490 cmd->hw_mode_index = hw_mode_index; 2491 wmi_debug("HW mode index:%d", cmd->hw_mode_index); 2492 2493 wmi_mtrace(WMI_PDEV_SET_HW_MODE_CMDID, NO_SESSION, 0); 2494 if (wmi_unified_cmd_send(wmi_handle, buf, len, 2495 WMI_PDEV_SET_HW_MODE_CMDID)) { 2496 wmi_err("Failed to send WMI_PDEV_SET_HW_MODE_CMDID"); 2497 wmi_buf_free(buf); 2498 return QDF_STATUS_E_FAILURE; 2499 } 2500 2501 return QDF_STATUS_SUCCESS; 2502 } 2503 2504 /** 2505 * send_suspend_cmd_tlv() - WMI suspend function 2506 * @wmi_handle: handle to WMI. 2507 * @param: pointer to hold suspend parameter 2508 * @mac_id: radio context 2509 * 2510 * Return: QDF_STATUS_SUCCESS for success or error code 2511 */ 2512 static QDF_STATUS send_suspend_cmd_tlv(wmi_unified_t wmi_handle, 2513 struct suspend_params *param, 2514 uint8_t mac_id) 2515 { 2516 wmi_pdev_suspend_cmd_fixed_param *cmd; 2517 wmi_buf_t wmibuf; 2518 uint32_t len = sizeof(*cmd); 2519 int32_t ret; 2520 2521 /* 2522 * send the command to Target to ignore the 2523 * PCIE reset so as to ensure that Host and target 2524 * states are in sync 2525 */ 2526 wmibuf = wmi_buf_alloc(wmi_handle, len); 2527 if (!wmibuf) 2528 return QDF_STATUS_E_NOMEM; 2529 2530 cmd = (wmi_pdev_suspend_cmd_fixed_param *) wmi_buf_data(wmibuf); 2531 WMITLV_SET_HDR(&cmd->tlv_header, 2532 WMITLV_TAG_STRUC_wmi_pdev_suspend_cmd_fixed_param, 2533 WMITLV_GET_STRUCT_TLVLEN 2534 (wmi_pdev_suspend_cmd_fixed_param)); 2535 if (param->disable_target_intr) 2536 cmd->suspend_opt = WMI_PDEV_SUSPEND_AND_DISABLE_INTR; 2537 else 2538 cmd->suspend_opt = WMI_PDEV_SUSPEND; 2539 2540 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 2541 wmi_handle, 2542 mac_id); 2543 2544 wmi_mtrace(WMI_PDEV_SUSPEND_CMDID, NO_SESSION, 0); 2545 ret = wmi_unified_cmd_send(wmi_handle, wmibuf, len, 2546 WMI_PDEV_SUSPEND_CMDID); 2547 if (ret) { 2548 wmi_buf_free(wmibuf); 2549 wmi_err("Failed to send WMI_PDEV_SUSPEND_CMDID command"); 2550 } 2551 2552 return ret; 2553 } 2554 2555 /** 2556 * send_resume_cmd_tlv() - WMI resume function 2557 * @wmi_handle: handle to WMI. 2558 * @mac_id: radio context 2559 * 2560 * Return: QDF_STATUS_SUCCESS for success or error code 2561 */ 2562 static QDF_STATUS send_resume_cmd_tlv(wmi_unified_t wmi_handle, 2563 uint8_t mac_id) 2564 { 2565 wmi_buf_t wmibuf; 2566 wmi_pdev_resume_cmd_fixed_param *cmd; 2567 QDF_STATUS ret; 2568 2569 wmibuf = wmi_buf_alloc(wmi_handle, sizeof(*cmd)); 2570 if (!wmibuf) 2571 return QDF_STATUS_E_NOMEM; 2572 cmd = (wmi_pdev_resume_cmd_fixed_param *) wmi_buf_data(wmibuf); 2573 WMITLV_SET_HDR(&cmd->tlv_header, 2574 WMITLV_TAG_STRUC_wmi_pdev_resume_cmd_fixed_param, 2575 WMITLV_GET_STRUCT_TLVLEN 2576 (wmi_pdev_resume_cmd_fixed_param)); 2577 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 2578 wmi_handle, 2579 mac_id); 2580 wmi_mtrace(WMI_PDEV_RESUME_CMDID, NO_SESSION, 0); 2581 ret = wmi_unified_cmd_send(wmi_handle, wmibuf, sizeof(*cmd), 2582 WMI_PDEV_RESUME_CMDID); 2583 if (QDF_IS_STATUS_ERROR(ret)) { 2584 wmi_err("Failed to send WMI_PDEV_RESUME_CMDID command"); 2585 wmi_buf_free(wmibuf); 2586 } 2587 2588 return ret; 2589 } 2590 2591 /** 2592 * send_wow_enable_cmd_tlv() - WMI wow enable function 2593 * @wmi_handle: handle to WMI. 2594 * @param: pointer to hold wow enable parameter 2595 * @mac_id: radio context 2596 * 2597 * Return: QDF_STATUS_SUCCESS for success or error code 2598 */ 2599 static QDF_STATUS send_wow_enable_cmd_tlv(wmi_unified_t wmi_handle, 2600 struct wow_cmd_params *param, 2601 uint8_t mac_id) 2602 { 2603 wmi_wow_enable_cmd_fixed_param *cmd; 2604 wmi_buf_t buf; 2605 int32_t len; 2606 int32_t ret; 2607 2608 len = sizeof(wmi_wow_enable_cmd_fixed_param); 2609 2610 buf = wmi_buf_alloc(wmi_handle, len); 2611 if (!buf) 2612 return QDF_STATUS_E_NOMEM; 2613 2614 cmd = (wmi_wow_enable_cmd_fixed_param *) wmi_buf_data(buf); 2615 WMITLV_SET_HDR(&cmd->tlv_header, 2616 WMITLV_TAG_STRUC_wmi_wow_enable_cmd_fixed_param, 2617 WMITLV_GET_STRUCT_TLVLEN 2618 (wmi_wow_enable_cmd_fixed_param)); 2619 cmd->enable = param->enable; 2620 if (param->can_suspend_link) 2621 cmd->pause_iface_config = WOW_IFACE_PAUSE_ENABLED; 2622 else 2623 cmd->pause_iface_config = WOW_IFACE_PAUSE_DISABLED; 2624 cmd->flags = param->flags; 2625 2626 wmi_debug("suspend type: %s flag is 0x%x", 2627 cmd->pause_iface_config == WOW_IFACE_PAUSE_ENABLED ? 2628 "WOW_IFACE_PAUSE_ENABLED" : "WOW_IFACE_PAUSE_DISABLED", 2629 cmd->flags); 2630 2631 wmi_mtrace(WMI_WOW_ENABLE_CMDID, NO_SESSION, 0); 2632 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 2633 WMI_WOW_ENABLE_CMDID); 2634 if (ret) 2635 wmi_buf_free(buf); 2636 2637 return ret; 2638 } 2639 2640 /** 2641 * send_set_ap_ps_param_cmd_tlv() - set ap powersave parameters 2642 * @wmi_handle: wmi handle 2643 * @peer_addr: peer mac address 2644 * @param: pointer to ap_ps parameter structure 2645 * 2646 * Return: QDF_STATUS_SUCCESS for success or error code 2647 */ 2648 static QDF_STATUS send_set_ap_ps_param_cmd_tlv(wmi_unified_t wmi_handle, 2649 uint8_t *peer_addr, 2650 struct ap_ps_params *param) 2651 { 2652 wmi_ap_ps_peer_cmd_fixed_param *cmd; 2653 wmi_buf_t buf; 2654 int32_t err; 2655 2656 buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd)); 2657 if (!buf) 2658 return QDF_STATUS_E_NOMEM; 2659 2660 cmd = (wmi_ap_ps_peer_cmd_fixed_param *) wmi_buf_data(buf); 2661 WMITLV_SET_HDR(&cmd->tlv_header, 2662 WMITLV_TAG_STRUC_wmi_ap_ps_peer_cmd_fixed_param, 2663 WMITLV_GET_STRUCT_TLVLEN 2664 (wmi_ap_ps_peer_cmd_fixed_param)); 2665 cmd->vdev_id = param->vdev_id; 2666 WMI_CHAR_ARRAY_TO_MAC_ADDR(peer_addr, &cmd->peer_macaddr); 2667 cmd->param = param->param; 2668 cmd->value = param->value; 2669 wmi_mtrace(WMI_AP_PS_PEER_PARAM_CMDID, cmd->vdev_id, 0); 2670 err = wmi_unified_cmd_send(wmi_handle, buf, 2671 sizeof(*cmd), WMI_AP_PS_PEER_PARAM_CMDID); 2672 if (err) { 2673 wmi_err("Failed to send set_ap_ps_param cmd"); 2674 wmi_buf_free(buf); 2675 return QDF_STATUS_E_FAILURE; 2676 } 2677 2678 return 0; 2679 } 2680 2681 /** 2682 * send_set_sta_ps_param_cmd_tlv() - set sta powersave parameters 2683 * @wmi_handle: wmi handle 2684 * @param: pointer to sta_ps parameter structure 2685 * 2686 * Return: QDF_STATUS_SUCCESS for success or error code 2687 */ 2688 static QDF_STATUS send_set_sta_ps_param_cmd_tlv(wmi_unified_t wmi_handle, 2689 struct sta_ps_params *param) 2690 { 2691 wmi_sta_powersave_param_cmd_fixed_param *cmd; 2692 wmi_buf_t buf; 2693 int32_t len = sizeof(*cmd); 2694 2695 buf = wmi_buf_alloc(wmi_handle, len); 2696 if (!buf) 2697 return QDF_STATUS_E_NOMEM; 2698 2699 cmd = (wmi_sta_powersave_param_cmd_fixed_param *) wmi_buf_data(buf); 2700 WMITLV_SET_HDR(&cmd->tlv_header, 2701 WMITLV_TAG_STRUC_wmi_sta_powersave_param_cmd_fixed_param, 2702 WMITLV_GET_STRUCT_TLVLEN 2703 (wmi_sta_powersave_param_cmd_fixed_param)); 2704 cmd->vdev_id = param->vdev_id; 2705 cmd->param = param->param_id; 2706 cmd->value = param->value; 2707 2708 wmi_mtrace(WMI_STA_POWERSAVE_PARAM_CMDID, cmd->vdev_id, 0); 2709 if (wmi_unified_cmd_send(wmi_handle, buf, len, 2710 WMI_STA_POWERSAVE_PARAM_CMDID)) { 2711 wmi_err("Set Sta Ps param Failed vdevId %d Param %d val %d", 2712 param->vdev_id, param->param_id, param->value); 2713 wmi_buf_free(buf); 2714 return QDF_STATUS_E_FAILURE; 2715 } 2716 2717 return 0; 2718 } 2719 2720 /** 2721 * send_crash_inject_cmd_tlv() - inject fw crash 2722 * @wmi_handle: wmi handle 2723 * @param: ponirt to crash inject parameter structure 2724 * 2725 * Return: QDF_STATUS_SUCCESS for success or return error 2726 */ 2727 static QDF_STATUS send_crash_inject_cmd_tlv(wmi_unified_t wmi_handle, 2728 struct crash_inject *param) 2729 { 2730 int32_t ret = 0; 2731 WMI_FORCE_FW_HANG_CMD_fixed_param *cmd; 2732 uint16_t len = sizeof(*cmd); 2733 wmi_buf_t buf; 2734 2735 buf = wmi_buf_alloc(wmi_handle, len); 2736 if (!buf) 2737 return QDF_STATUS_E_NOMEM; 2738 2739 cmd = (WMI_FORCE_FW_HANG_CMD_fixed_param *) wmi_buf_data(buf); 2740 WMITLV_SET_HDR(&cmd->tlv_header, 2741 WMITLV_TAG_STRUC_WMI_FORCE_FW_HANG_CMD_fixed_param, 2742 WMITLV_GET_STRUCT_TLVLEN 2743 (WMI_FORCE_FW_HANG_CMD_fixed_param)); 2744 cmd->type = param->type; 2745 cmd->delay_time_ms = param->delay_time_ms; 2746 2747 wmi_mtrace(WMI_FORCE_FW_HANG_CMDID, NO_SESSION, 0); 2748 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 2749 WMI_FORCE_FW_HANG_CMDID); 2750 if (ret) { 2751 wmi_err("Failed to send set param command, ret = %d", ret); 2752 wmi_buf_free(buf); 2753 } 2754 2755 return ret; 2756 } 2757 2758 /** 2759 * send_dbglog_cmd_tlv() - set debug log level 2760 * @wmi_handle: handle to WMI. 2761 * @dbglog_param: pointer to hold dbglog level parameter 2762 * 2763 * Return: QDF_STATUS_SUCCESS on success, otherwise QDF_STATUS_E_* 2764 */ 2765 static QDF_STATUS 2766 send_dbglog_cmd_tlv(wmi_unified_t wmi_handle, 2767 struct dbglog_params *dbglog_param) 2768 { 2769 wmi_buf_t buf; 2770 wmi_debug_log_config_cmd_fixed_param *configmsg; 2771 QDF_STATUS status; 2772 int32_t i; 2773 int32_t len; 2774 int8_t *buf_ptr; 2775 int32_t *module_id_bitmap_array; /* Used to form the second tlv */ 2776 2777 ASSERT(dbglog_param->bitmap_len < MAX_MODULE_ID_BITMAP_WORDS); 2778 2779 /* Allocate size for 2 tlvs - including tlv hdr space for second tlv */ 2780 len = sizeof(wmi_debug_log_config_cmd_fixed_param) + WMI_TLV_HDR_SIZE + 2781 (sizeof(int32_t) * MAX_MODULE_ID_BITMAP_WORDS); 2782 buf = wmi_buf_alloc(wmi_handle, len); 2783 if (!buf) 2784 return QDF_STATUS_E_NOMEM; 2785 2786 configmsg = 2787 (wmi_debug_log_config_cmd_fixed_param *) (wmi_buf_data(buf)); 2788 buf_ptr = (int8_t *) configmsg; 2789 WMITLV_SET_HDR(&configmsg->tlv_header, 2790 WMITLV_TAG_STRUC_wmi_debug_log_config_cmd_fixed_param, 2791 WMITLV_GET_STRUCT_TLVLEN 2792 (wmi_debug_log_config_cmd_fixed_param)); 2793 configmsg->dbg_log_param = dbglog_param->param; 2794 configmsg->value = dbglog_param->val; 2795 /* Filling in the data part of second tlv -- should 2796 * follow first tlv _ WMI_TLV_HDR_SIZE */ 2797 module_id_bitmap_array = (uint32_t *) (buf_ptr + 2798 sizeof 2799 (wmi_debug_log_config_cmd_fixed_param) 2800 + WMI_TLV_HDR_SIZE); 2801 WMITLV_SET_HDR(buf_ptr + sizeof(wmi_debug_log_config_cmd_fixed_param), 2802 WMITLV_TAG_ARRAY_UINT32, 2803 sizeof(uint32_t) * MAX_MODULE_ID_BITMAP_WORDS); 2804 if (dbglog_param->module_id_bitmap) { 2805 for (i = 0; i < dbglog_param->bitmap_len; ++i) { 2806 module_id_bitmap_array[i] = 2807 dbglog_param->module_id_bitmap[i]; 2808 } 2809 } 2810 2811 wmi_mtrace(WMI_DBGLOG_CFG_CMDID, NO_SESSION, 0); 2812 status = wmi_unified_cmd_send(wmi_handle, buf, 2813 len, WMI_DBGLOG_CFG_CMDID); 2814 2815 if (status != QDF_STATUS_SUCCESS) 2816 wmi_buf_free(buf); 2817 2818 return status; 2819 } 2820 2821 /** 2822 * send_vdev_set_param_cmd_tlv() - WMI vdev set parameter function 2823 * @wmi_handle: handle to WMI. 2824 * @param: pointer to hold vdev set parameter 2825 * 2826 * Return: QDF_STATUS_SUCCESS for success or error code 2827 */ 2828 static QDF_STATUS send_vdev_set_param_cmd_tlv(wmi_unified_t wmi_handle, 2829 struct vdev_set_params *param) 2830 { 2831 QDF_STATUS ret; 2832 wmi_vdev_set_param_cmd_fixed_param *cmd; 2833 wmi_buf_t buf; 2834 uint16_t len = sizeof(*cmd); 2835 uint32_t vdev_param; 2836 2837 vdev_param = convert_host_vdev_param_tlv(param->param_id); 2838 if (vdev_param == WMI_UNAVAILABLE_PARAM) { 2839 wmi_err("Vdev param %d not available", param->param_id); 2840 return QDF_STATUS_E_INVAL; 2841 2842 } 2843 2844 buf = wmi_buf_alloc(wmi_handle, len); 2845 if (!buf) 2846 return QDF_STATUS_E_NOMEM; 2847 2848 cmd = (wmi_vdev_set_param_cmd_fixed_param *) wmi_buf_data(buf); 2849 WMITLV_SET_HDR(&cmd->tlv_header, 2850 WMITLV_TAG_STRUC_wmi_vdev_set_param_cmd_fixed_param, 2851 WMITLV_GET_STRUCT_TLVLEN(wmi_vdev_set_param_cmd_fixed_param)); 2852 cmd->vdev_id = param->vdev_id; 2853 cmd->param_id = vdev_param; 2854 cmd->param_value = param->param_value; 2855 wmi_nofl_debug("Set vdev %d param 0x%x to %u", 2856 cmd->vdev_id, cmd->param_id, cmd->param_value); 2857 wmi_mtrace(WMI_VDEV_SET_PARAM_CMDID, cmd->vdev_id, 0); 2858 ret = wmi_unified_cmd_send(wmi_handle, buf, len, WMI_VDEV_SET_PARAM_CMDID); 2859 if (QDF_IS_STATUS_ERROR(ret)) { 2860 wmi_buf_free(buf); 2861 } 2862 2863 return ret; 2864 } 2865 2866 /** 2867 * send_multi_param_cmd_using_vdev_param_tlv() - vdev set parameter function 2868 * @wmi_handle : handle to WMI. 2869 * @params: pointer to parameters to set 2870 * 2871 * Return: QDF_STATUS_SUCCESS on success, otherwise QDF_STATUS_E_* 2872 */ 2873 static QDF_STATUS 2874 send_multi_param_cmd_using_vdev_param_tlv(wmi_unified_t wmi_handle, 2875 struct set_multiple_pdev_vdev_param *params) 2876 { 2877 uint8_t index; 2878 struct vdev_set_params vdevparam; 2879 2880 for (index = 0; index < params->n_params; index++) { 2881 vdevparam.param_id = params->params[index].param_id; 2882 vdevparam.param_value = params->params[index].param_value; 2883 vdevparam.vdev_id = params->dev_id; 2884 if (QDF_IS_STATUS_ERROR(send_vdev_set_param_cmd_tlv(wmi_handle, &vdevparam))) { 2885 wmi_err("failed to send param:%d", vdevparam.param_id); 2886 return QDF_STATUS_E_FAILURE; 2887 } 2888 } 2889 return QDF_STATUS_SUCCESS; 2890 } 2891 2892 #ifdef WLAN_PDEV_VDEV_SEND_MULTI_PARAM 2893 /** 2894 * send_multiple_vdev_param_cmd_tlv() - WMI vdev set parameter function 2895 * @wmi_handle : handle to WMI. 2896 * @params: pointer to hold set_multiple_pdev_vdev_param info 2897 * 2898 * Return: QDF_STATUS_SUCCESS for success or error code 2899 */ 2900 static QDF_STATUS 2901 send_multiple_vdev_param_cmd_tlv(wmi_unified_t wmi_handle, 2902 struct set_multiple_pdev_vdev_param *params) 2903 { 2904 if (!wmi_service_enabled(wmi_handle, 2905 wmi_service_combined_set_param_support)) 2906 return send_multi_param_cmd_using_vdev_param_tlv(wmi_handle, 2907 params); 2908 return send_multi_pdev_vdev_set_param_cmd_tlv(wmi_handle, params); 2909 } 2910 2911 #else /* WLAN_PDEV_VDEV_SEND_MULTI_PARAM */ 2912 2913 /** 2914 * send_multiple_vdev_param_cmd_tlv() - WMI vdev set parameter function 2915 * @wmi_handle : handle to WMI. 2916 * @params: pointer to hold set_multiple_pdev_vdev_param info 2917 * 2918 * Return: QDF_STATUS_SUCCESS for success or error code 2919 */ 2920 static QDF_STATUS 2921 send_multiple_vdev_param_cmd_tlv(wmi_unified_t wmi_handle, 2922 struct set_multiple_pdev_vdev_param *params) 2923 { 2924 return send_multi_param_cmd_using_vdev_param_tlv(wmi_handle, params); 2925 } 2926 #endif /*end of WLAN_PDEV_VDEV_SEND_MULTI_PARAM */ 2927 2928 /** 2929 * send_vdev_set_mu_snif_cmd_tlv() - WMI vdev set mu snif function 2930 * @wmi_handle: handle to WMI. 2931 * @param: pointer to hold mu sniffer parameter 2932 * 2933 * Return: QDF_STATUS_SUCCESS for success or error code 2934 */ 2935 static 2936 QDF_STATUS send_vdev_set_mu_snif_cmd_tlv(wmi_unified_t wmi_handle, 2937 struct vdev_set_mu_snif_param *param) 2938 { 2939 QDF_STATUS ret; 2940 wmi_vdev_set_mu_snif_cmd_param *cmd; 2941 wmi_buf_t buf; 2942 uint32_t *tmp_ptr; 2943 uint16_t len = sizeof(*cmd); 2944 uint8_t *buf_ptr; 2945 uint32_t i; 2946 2947 /* Length TLV placeholder for array of uint32_t */ 2948 len += WMI_TLV_HDR_SIZE; 2949 2950 if (param->num_aid) 2951 len += param->num_aid * sizeof(uint32_t); 2952 2953 buf = wmi_buf_alloc(wmi_handle, len); 2954 if (!buf) 2955 return QDF_STATUS_E_NOMEM; 2956 2957 buf_ptr = (uint8_t *)wmi_buf_data(buf); 2958 cmd = (wmi_vdev_set_mu_snif_cmd_param *)buf_ptr; 2959 2960 WMITLV_SET_HDR(&cmd->tlv_header, 2961 WMITLV_TAG_STRUC_wmi_vdev_set_mu_snif_cmd_param, 2962 WMITLV_GET_STRUCT_TLVLEN 2963 (wmi_vdev_set_mu_snif_cmd_param)); 2964 2965 cmd->vdev_id = param->vdev_id; 2966 cmd->mode = param->mode; 2967 cmd->max_num_user = param->num_user; 2968 2969 buf_ptr += sizeof(*cmd); 2970 2971 tmp_ptr = (uint32_t *)(buf_ptr + WMI_TLV_HDR_SIZE); 2972 2973 for (i = 0; i < param->num_aid; ++i) 2974 tmp_ptr[i] = param->aid[i]; 2975 2976 WMITLV_SET_HDR(buf_ptr, 2977 WMITLV_TAG_ARRAY_UINT32, 2978 (param->num_aid * sizeof(uint32_t))); 2979 2980 wmi_debug("Setting vdev %d mode = %x, max user = %u aids= %u", 2981 cmd->vdev_id, cmd->mode, cmd->max_num_user, param->num_aid); 2982 wmi_mtrace(WMI_VDEV_SET_PARAM_CMDID, cmd->vdev_id, 0); 2983 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 2984 WMI_VDEV_SET_MU_SNIF_CMDID); 2985 if (QDF_IS_STATUS_ERROR(ret)) { 2986 wmi_err("Failed to send set param command ret = %d", ret); 2987 wmi_buf_free(buf); 2988 } 2989 2990 return ret; 2991 } 2992 2993 /** 2994 * send_peer_based_pktlog_cmd() - Send WMI command to enable packet-log 2995 * @wmi_handle: handle to WMI. 2996 * @macaddr: Peer mac address to be filter 2997 * @mac_id: mac id to have radio context 2998 * @enb_dsb: Enable MAC based filtering or Disable 2999 * 3000 * Return: QDF_STATUS 3001 */ 3002 static QDF_STATUS send_peer_based_pktlog_cmd(wmi_unified_t wmi_handle, 3003 uint8_t *macaddr, 3004 uint8_t mac_id, 3005 uint8_t enb_dsb) 3006 { 3007 int32_t ret; 3008 wmi_pdev_pktlog_filter_cmd_fixed_param *cmd; 3009 wmi_pdev_pktlog_filter_info *mac_info; 3010 wmi_buf_t buf; 3011 uint8_t *buf_ptr; 3012 uint16_t len = sizeof(wmi_pdev_pktlog_filter_cmd_fixed_param) + 3013 sizeof(wmi_pdev_pktlog_filter_info) + WMI_TLV_HDR_SIZE; 3014 3015 buf = wmi_buf_alloc(wmi_handle, len); 3016 if (!buf) 3017 return QDF_STATUS_E_NOMEM; 3018 3019 buf_ptr = (uint8_t *)wmi_buf_data(buf); 3020 cmd = (wmi_pdev_pktlog_filter_cmd_fixed_param *)buf_ptr; 3021 WMITLV_SET_HDR(&cmd->tlv_header, 3022 WMITLV_TAG_STRUC_wmi_pdev_pktlog_filter_cmd_fixed_param, 3023 WMITLV_GET_STRUCT_TLVLEN 3024 (wmi_pdev_pktlog_filter_cmd_fixed_param)); 3025 cmd->pdev_id = mac_id; 3026 cmd->enable = enb_dsb; 3027 cmd->num_of_mac_addresses = 1; 3028 wmi_mtrace(WMI_PDEV_PKTLOG_FILTER_CMDID, cmd->pdev_id, 0); 3029 3030 buf_ptr += sizeof(*cmd); 3031 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 3032 sizeof(wmi_pdev_pktlog_filter_info)); 3033 buf_ptr += WMI_TLV_HDR_SIZE; 3034 3035 mac_info = (wmi_pdev_pktlog_filter_info *)(buf_ptr); 3036 3037 WMITLV_SET_HDR(&mac_info->tlv_header, 3038 WMITLV_TAG_STRUC_wmi_pdev_pktlog_filter_info, 3039 WMITLV_GET_STRUCT_TLVLEN 3040 (wmi_pdev_pktlog_filter_info)); 3041 3042 WMI_CHAR_ARRAY_TO_MAC_ADDR(macaddr, &mac_info->peer_mac_address); 3043 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 3044 WMI_PDEV_PKTLOG_FILTER_CMDID); 3045 if (ret) { 3046 wmi_err("Failed to send peer based pktlog command to FW =%d" 3047 , ret); 3048 wmi_buf_free(buf); 3049 } 3050 3051 return ret; 3052 } 3053 3054 /** 3055 * send_packet_log_enable_cmd_tlv() - Send WMI command to enable packet-log 3056 * @wmi_handle: handle to WMI. 3057 * @PKTLOG_EVENT: packet log event 3058 * @mac_id: mac id to have radio context 3059 * 3060 * Return: QDF_STATUS_SUCCESS for success or error code 3061 */ 3062 static QDF_STATUS send_packet_log_enable_cmd_tlv(wmi_unified_t wmi_handle, 3063 WMI_HOST_PKTLOG_EVENT PKTLOG_EVENT, uint8_t mac_id) 3064 { 3065 int32_t ret, idx, max_idx; 3066 wmi_pdev_pktlog_enable_cmd_fixed_param *cmd; 3067 wmi_buf_t buf; 3068 uint16_t len = sizeof(wmi_pdev_pktlog_enable_cmd_fixed_param); 3069 3070 buf = wmi_buf_alloc(wmi_handle, len); 3071 if (!buf) 3072 return -QDF_STATUS_E_NOMEM; 3073 3074 cmd = (wmi_pdev_pktlog_enable_cmd_fixed_param *) wmi_buf_data(buf); 3075 WMITLV_SET_HDR(&cmd->tlv_header, 3076 WMITLV_TAG_STRUC_wmi_pdev_pktlog_enable_cmd_fixed_param, 3077 WMITLV_GET_STRUCT_TLVLEN 3078 (wmi_pdev_pktlog_enable_cmd_fixed_param)); 3079 max_idx = sizeof(pktlog_event_tlv) / (sizeof(pktlog_event_tlv[0])); 3080 cmd->evlist = 0; 3081 for (idx = 0; idx < max_idx; idx++) { 3082 if (PKTLOG_EVENT & (1 << idx)) 3083 cmd->evlist |= pktlog_event_tlv[idx]; 3084 } 3085 cmd->pdev_id = mac_id; 3086 wmi_mtrace(WMI_PDEV_PKTLOG_ENABLE_CMDID, cmd->pdev_id, 0); 3087 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 3088 WMI_PDEV_PKTLOG_ENABLE_CMDID); 3089 if (ret) { 3090 wmi_err("Failed to send pktlog enable cmd to FW =%d", ret); 3091 wmi_buf_free(buf); 3092 } 3093 3094 return ret; 3095 } 3096 3097 /** 3098 * send_packet_log_disable_cmd_tlv() - Send WMI command to disable packet-log 3099 * @wmi_handle: handle to WMI. 3100 * @mac_id: mac id to have radio context 3101 * 3102 * Return: QDF_STATUS_SUCCESS for success or error code 3103 */ 3104 static QDF_STATUS send_packet_log_disable_cmd_tlv(wmi_unified_t wmi_handle, 3105 uint8_t mac_id) 3106 { 3107 int32_t ret; 3108 wmi_pdev_pktlog_disable_cmd_fixed_param *cmd; 3109 wmi_buf_t buf; 3110 uint16_t len = sizeof(wmi_pdev_pktlog_disable_cmd_fixed_param); 3111 3112 buf = wmi_buf_alloc(wmi_handle, len); 3113 if (!buf) 3114 return -QDF_STATUS_E_NOMEM; 3115 3116 cmd = (wmi_pdev_pktlog_disable_cmd_fixed_param *) wmi_buf_data(buf); 3117 WMITLV_SET_HDR(&cmd->tlv_header, 3118 WMITLV_TAG_STRUC_wmi_pdev_pktlog_disable_cmd_fixed_param, 3119 WMITLV_GET_STRUCT_TLVLEN 3120 (wmi_pdev_pktlog_disable_cmd_fixed_param)); 3121 cmd->pdev_id = mac_id; 3122 wmi_mtrace(WMI_PDEV_PKTLOG_DISABLE_CMDID, cmd->pdev_id, 0); 3123 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 3124 WMI_PDEV_PKTLOG_DISABLE_CMDID); 3125 if (ret) { 3126 wmi_err("Failed to send pktlog disable cmd to FW =%d", ret); 3127 wmi_buf_free(buf); 3128 } 3129 3130 return ret; 3131 } 3132 3133 #define WMI_FW_TIME_STAMP_LOW_MASK 0xffffffff 3134 /** 3135 * send_time_stamp_sync_cmd_tlv() - Send WMI command to 3136 * sync time between between host and firmware 3137 * @wmi_handle: handle to WMI. 3138 * 3139 * Return: None 3140 */ 3141 static void send_time_stamp_sync_cmd_tlv(wmi_unified_t wmi_handle) 3142 { 3143 wmi_buf_t buf; 3144 QDF_STATUS status = QDF_STATUS_SUCCESS; 3145 WMI_DBGLOG_TIME_STAMP_SYNC_CMD_fixed_param *time_stamp; 3146 int32_t len; 3147 qdf_time_t time_ms; 3148 3149 len = sizeof(*time_stamp); 3150 buf = wmi_buf_alloc(wmi_handle, len); 3151 3152 if (!buf) 3153 return; 3154 3155 time_stamp = 3156 (WMI_DBGLOG_TIME_STAMP_SYNC_CMD_fixed_param *) 3157 (wmi_buf_data(buf)); 3158 WMITLV_SET_HDR(&time_stamp->tlv_header, 3159 WMITLV_TAG_STRUC_wmi_dbglog_time_stamp_sync_cmd_fixed_param, 3160 WMITLV_GET_STRUCT_TLVLEN( 3161 WMI_DBGLOG_TIME_STAMP_SYNC_CMD_fixed_param)); 3162 3163 time_ms = qdf_get_time_of_the_day_ms(); 3164 time_stamp->mode = WMI_TIME_STAMP_SYNC_MODE_MS; 3165 time_stamp->time_stamp_low = time_ms & 3166 WMI_FW_TIME_STAMP_LOW_MASK; 3167 /* 3168 * Send time_stamp_high 0 as the time converted from HR:MIN:SEC:MS to ms 3169 * won't exceed 27 bit 3170 */ 3171 time_stamp->time_stamp_high = 0; 3172 wmi_debug("WMA --> DBGLOG_TIME_STAMP_SYNC_CMDID mode %d time_stamp low %d high %d", 3173 time_stamp->mode, time_stamp->time_stamp_low, 3174 time_stamp->time_stamp_high); 3175 3176 wmi_mtrace(WMI_DBGLOG_TIME_STAMP_SYNC_CMDID, NO_SESSION, 0); 3177 status = wmi_unified_cmd_send(wmi_handle, buf, 3178 len, WMI_DBGLOG_TIME_STAMP_SYNC_CMDID); 3179 if (status) { 3180 wmi_err("Failed to send WMI_DBGLOG_TIME_STAMP_SYNC_CMDID command"); 3181 wmi_buf_free(buf); 3182 } 3183 3184 } 3185 3186 /** 3187 * send_fd_tmpl_cmd_tlv() - WMI FILS Discovery send function 3188 * @wmi_handle: handle to WMI. 3189 * @param: pointer to hold FILS Discovery send cmd parameter 3190 * 3191 * Return: QDF_STATUS_SUCCESS for success or error code 3192 */ 3193 static QDF_STATUS send_fd_tmpl_cmd_tlv(wmi_unified_t wmi_handle, 3194 struct fils_discovery_tmpl_params *param) 3195 { 3196 int32_t ret; 3197 wmi_fd_tmpl_cmd_fixed_param *cmd; 3198 wmi_buf_t wmi_buf; 3199 uint8_t *buf_ptr; 3200 uint32_t wmi_buf_len; 3201 3202 wmi_buf_len = sizeof(wmi_fd_tmpl_cmd_fixed_param) + 3203 WMI_TLV_HDR_SIZE + param->tmpl_len_aligned; 3204 wmi_buf = wmi_buf_alloc(wmi_handle, wmi_buf_len); 3205 if (!wmi_buf) 3206 return QDF_STATUS_E_NOMEM; 3207 3208 buf_ptr = (uint8_t *) wmi_buf_data(wmi_buf); 3209 cmd = (wmi_fd_tmpl_cmd_fixed_param *) buf_ptr; 3210 WMITLV_SET_HDR(&cmd->tlv_header, 3211 WMITLV_TAG_STRUC_wmi_fd_tmpl_cmd_fixed_param, 3212 WMITLV_GET_STRUCT_TLVLEN(wmi_fd_tmpl_cmd_fixed_param)); 3213 cmd->vdev_id = param->vdev_id; 3214 cmd->buf_len = param->tmpl_len; 3215 buf_ptr += sizeof(wmi_fd_tmpl_cmd_fixed_param); 3216 3217 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, param->tmpl_len_aligned); 3218 buf_ptr += WMI_TLV_HDR_SIZE; 3219 qdf_mem_copy(buf_ptr, param->frm, param->tmpl_len); 3220 3221 wmi_mtrace(WMI_FD_TMPL_CMDID, cmd->vdev_id, 0); 3222 ret = wmi_unified_cmd_send(wmi_handle, 3223 wmi_buf, wmi_buf_len, WMI_FD_TMPL_CMDID); 3224 3225 if (ret) { 3226 wmi_err("Failed to send fd tmpl: %d", ret); 3227 wmi_buf_free(wmi_buf); 3228 return ret; 3229 } 3230 3231 return 0; 3232 } 3233 3234 /** 3235 * send_beacon_tmpl_send_cmd_tlv() - WMI beacon send function 3236 * @wmi_handle: handle to WMI. 3237 * @param: pointer to hold beacon send cmd parameter 3238 * 3239 * Return: QDF_STATUS_SUCCESS for success or error code 3240 */ 3241 static QDF_STATUS send_beacon_tmpl_send_cmd_tlv(wmi_unified_t wmi_handle, 3242 struct beacon_tmpl_params *param) 3243 { 3244 int32_t ret; 3245 wmi_bcn_tmpl_cmd_fixed_param *cmd; 3246 wmi_bcn_prb_info *bcn_prb_info; 3247 wmi_buf_t wmi_buf; 3248 uint8_t *buf_ptr; 3249 uint32_t wmi_buf_len; 3250 3251 wmi_buf_len = sizeof(wmi_bcn_tmpl_cmd_fixed_param) + 3252 sizeof(wmi_bcn_prb_info) + WMI_TLV_HDR_SIZE + 3253 param->tmpl_len_aligned + 3254 bcn_tmpl_mlo_param_size(param) + 3255 bcn_tmpl_ml_info_size(param); 3256 3257 wmi_buf = wmi_buf_alloc(wmi_handle, wmi_buf_len); 3258 if (!wmi_buf) 3259 return QDF_STATUS_E_NOMEM; 3260 3261 buf_ptr = (uint8_t *) wmi_buf_data(wmi_buf); 3262 cmd = (wmi_bcn_tmpl_cmd_fixed_param *) buf_ptr; 3263 WMITLV_SET_HDR(&cmd->tlv_header, 3264 WMITLV_TAG_STRUC_wmi_bcn_tmpl_cmd_fixed_param, 3265 WMITLV_GET_STRUCT_TLVLEN(wmi_bcn_tmpl_cmd_fixed_param)); 3266 cmd->vdev_id = param->vdev_id; 3267 cmd->tim_ie_offset = param->tim_ie_offset; 3268 cmd->mbssid_ie_offset = param->mbssid_ie_offset; 3269 cmd->csa_switch_count_offset = param->csa_switch_count_offset; 3270 cmd->ext_csa_switch_count_offset = param->ext_csa_switch_count_offset; 3271 cmd->esp_ie_offset = param->esp_ie_offset; 3272 cmd->mu_edca_ie_offset = param->mu_edca_ie_offset; 3273 cmd->ema_params = param->ema_params; 3274 cmd->buf_len = param->tmpl_len; 3275 cmd->csa_event_bitmap = param->csa_event_bitmap; 3276 3277 WMI_BEACON_PROTECTION_EN_SET(cmd->feature_enable_bitmap, 3278 param->enable_bigtk); 3279 buf_ptr += sizeof(wmi_bcn_tmpl_cmd_fixed_param); 3280 3281 bcn_prb_info = (wmi_bcn_prb_info *) buf_ptr; 3282 WMITLV_SET_HDR(&bcn_prb_info->tlv_header, 3283 WMITLV_TAG_STRUC_wmi_bcn_prb_info, 3284 WMITLV_GET_STRUCT_TLVLEN(wmi_bcn_prb_info)); 3285 bcn_prb_info->caps = 0; 3286 bcn_prb_info->erp = 0; 3287 buf_ptr += sizeof(wmi_bcn_prb_info); 3288 3289 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, param->tmpl_len_aligned); 3290 buf_ptr += WMI_TLV_HDR_SIZE; 3291 3292 /* for big endian host, copy engine byte_swap is enabled 3293 * But the frame content is in network byte order 3294 * Need to byte swap the frame content - so when copy engine 3295 * does byte_swap - target gets frame content in the correct order 3296 */ 3297 WMI_HOST_IF_MSG_COPY_CHAR_ARRAY(buf_ptr, param->frm, 3298 param->tmpl_len); 3299 3300 buf_ptr += roundup(param->tmpl_len, sizeof(uint32_t)); 3301 buf_ptr = bcn_tmpl_add_ml_partner_links(buf_ptr, param); 3302 3303 buf_ptr = bcn_tmpl_add_ml_info(buf_ptr, param); 3304 3305 wmi_mtrace(WMI_BCN_TMPL_CMDID, cmd->vdev_id, 0); 3306 ret = wmi_unified_cmd_send(wmi_handle, 3307 wmi_buf, wmi_buf_len, WMI_BCN_TMPL_CMDID); 3308 if (ret) { 3309 wmi_err("Failed to send bcn tmpl: %d", ret); 3310 wmi_buf_free(wmi_buf); 3311 } 3312 3313 return 0; 3314 } 3315 3316 #ifdef WLAN_FEATURE_11BE 3317 static inline void copy_peer_flags_tlv_11be( 3318 wmi_peer_assoc_complete_cmd_fixed_param * cmd, 3319 struct peer_assoc_params *param) 3320 { 3321 if (param->bw_320) 3322 cmd->peer_flags_ext |= WMI_PEER_EXT_320MHZ; 3323 if (param->eht_flag) 3324 cmd->peer_flags_ext |= WMI_PEER_EXT_EHT; 3325 3326 wmi_debug("peer_flags_ext 0x%x", cmd->peer_flags_ext); 3327 } 3328 #else 3329 static inline void copy_peer_flags_tlv_11be( 3330 wmi_peer_assoc_complete_cmd_fixed_param * cmd, 3331 struct peer_assoc_params *param) 3332 { 3333 } 3334 #endif 3335 3336 static inline void copy_peer_flags_tlv( 3337 wmi_peer_assoc_complete_cmd_fixed_param * cmd, 3338 struct peer_assoc_params *param) 3339 { 3340 /* 3341 * The target only needs a subset of the flags maintained in the host. 3342 * Just populate those flags and send it down 3343 */ 3344 cmd->peer_flags = 0; 3345 if (param->peer_dms_capable) 3346 cmd->peer_flags_ext |= WMI_PEER_EXT_DMS_CAPABLE; 3347 /* 3348 * Do not enable HT/VHT if WMM/wme is disabled for vap. 3349 */ 3350 if (param->is_wme_set) { 3351 3352 if (param->qos_flag) 3353 cmd->peer_flags |= WMI_PEER_QOS; 3354 if (param->apsd_flag) 3355 cmd->peer_flags |= WMI_PEER_APSD; 3356 if (param->ht_flag) 3357 cmd->peer_flags |= WMI_PEER_HT; 3358 if (param->bw_40) 3359 cmd->peer_flags |= WMI_PEER_40MHZ; 3360 if (param->bw_80) 3361 cmd->peer_flags |= WMI_PEER_80MHZ; 3362 if (param->bw_160) 3363 cmd->peer_flags |= WMI_PEER_160MHZ; 3364 3365 copy_peer_flags_tlv_11be(cmd, param); 3366 3367 /* Typically if STBC is enabled for VHT it should be enabled 3368 * for HT as well 3369 **/ 3370 if (param->stbc_flag) 3371 cmd->peer_flags |= WMI_PEER_STBC; 3372 3373 /* Typically if LDPC is enabled for VHT it should be enabled 3374 * for HT as well 3375 **/ 3376 if (param->ldpc_flag) 3377 cmd->peer_flags |= WMI_PEER_LDPC; 3378 3379 if (param->static_mimops_flag) 3380 cmd->peer_flags |= WMI_PEER_STATIC_MIMOPS; 3381 if (param->dynamic_mimops_flag) 3382 cmd->peer_flags |= WMI_PEER_DYN_MIMOPS; 3383 if (param->spatial_mux_flag) 3384 cmd->peer_flags |= WMI_PEER_SPATIAL_MUX; 3385 if (param->vht_flag) 3386 cmd->peer_flags |= WMI_PEER_VHT; 3387 if (param->he_flag) 3388 cmd->peer_flags |= WMI_PEER_HE; 3389 if (param->p2p_capable_sta) 3390 cmd->peer_flags |= WMI_PEER_IS_P2P_CAPABLE; 3391 } 3392 3393 if (param->is_pmf_enabled) 3394 cmd->peer_flags |= WMI_PEER_PMF; 3395 /* 3396 * Suppress authorization for all AUTH modes that need 4-way handshake 3397 * (during re-association). 3398 * Authorization will be done for these modes on key installation. 3399 */ 3400 if (param->auth_flag) 3401 cmd->peer_flags |= WMI_PEER_AUTH; 3402 if (param->need_ptk_4_way) 3403 cmd->peer_flags |= WMI_PEER_NEED_PTK_4_WAY; 3404 else 3405 cmd->peer_flags &= ~WMI_PEER_NEED_PTK_4_WAY; 3406 if (param->need_gtk_2_way) 3407 cmd->peer_flags |= WMI_PEER_NEED_GTK_2_WAY; 3408 /* safe mode bypass the 4-way handshake */ 3409 if (param->safe_mode_enabled) 3410 cmd->peer_flags &= 3411 ~(WMI_PEER_NEED_PTK_4_WAY | WMI_PEER_NEED_GTK_2_WAY); 3412 /* inter BSS peer */ 3413 if (param->inter_bss_peer) 3414 cmd->peer_flags |= WMI_PEER_INTER_BSS_PEER; 3415 /* Disable AMSDU for station transmit, if user configures it */ 3416 /* Disable AMSDU for AP transmit to 11n Stations, if user configures 3417 * it 3418 * if (param->amsdu_disable) Add after FW support 3419 **/ 3420 3421 /* Target asserts if node is marked HT and all MCS is set to 0. 3422 * Mark the node as non-HT if all the mcs rates are disabled through 3423 * iwpriv 3424 **/ 3425 if (param->peer_ht_rates.num_rates == 0) 3426 cmd->peer_flags &= ~WMI_PEER_HT; 3427 3428 if (param->twt_requester) 3429 cmd->peer_flags |= WMI_PEER_TWT_REQ; 3430 3431 if (param->twt_responder) 3432 cmd->peer_flags |= WMI_PEER_TWT_RESP; 3433 } 3434 3435 static inline void copy_peer_mac_addr_tlv( 3436 wmi_peer_assoc_complete_cmd_fixed_param * cmd, 3437 struct peer_assoc_params *param) 3438 { 3439 WMI_CHAR_ARRAY_TO_MAC_ADDR(param->peer_mac, &cmd->peer_macaddr); 3440 } 3441 3442 #ifdef WLAN_FEATURE_11BE 3443 static uint8_t *update_peer_flags_tlv_ehtinfo( 3444 wmi_peer_assoc_complete_cmd_fixed_param * cmd, 3445 struct peer_assoc_params *param, uint8_t *buf_ptr) 3446 { 3447 wmi_eht_rate_set *eht_mcs; 3448 int i; 3449 3450 cmd->peer_eht_ops = param->peer_eht_ops; 3451 cmd->puncture_20mhz_bitmap = ~param->puncture_bitmap; 3452 3453 qdf_mem_copy(&cmd->peer_eht_cap_mac, ¶m->peer_eht_cap_macinfo, 3454 sizeof(param->peer_eht_cap_macinfo)); 3455 qdf_mem_copy(&cmd->peer_eht_cap_phy, ¶m->peer_eht_cap_phyinfo, 3456 sizeof(param->peer_eht_cap_phyinfo)); 3457 qdf_mem_copy(&cmd->peer_eht_ppet, ¶m->peer_eht_ppet, 3458 sizeof(param->peer_eht_ppet)); 3459 3460 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 3461 (param->peer_eht_mcs_count * sizeof(wmi_eht_rate_set))); 3462 buf_ptr += WMI_TLV_HDR_SIZE; 3463 3464 /* Loop through the EHT rate set */ 3465 for (i = 0; i < param->peer_eht_mcs_count; i++) { 3466 eht_mcs = (wmi_eht_rate_set *)buf_ptr; 3467 WMITLV_SET_HDR(eht_mcs, WMITLV_TAG_STRUC_wmi_eht_rate_set, 3468 WMITLV_GET_STRUCT_TLVLEN(wmi_eht_rate_set)); 3469 3470 eht_mcs->rx_mcs_set = param->peer_eht_rx_mcs_set[i]; 3471 eht_mcs->tx_mcs_set = param->peer_eht_tx_mcs_set[i]; 3472 wmi_debug("EHT idx %d RxMCSmap %x TxMCSmap %x ", 3473 i, eht_mcs->rx_mcs_set, eht_mcs->tx_mcs_set); 3474 buf_ptr += sizeof(wmi_eht_rate_set); 3475 } 3476 3477 wmi_debug("nss %d ru mask 0x%x", 3478 cmd->peer_eht_ppet.numss_m1, cmd->peer_eht_ppet.ru_mask); 3479 for (i = 0; i < WMI_MAX_NUM_SS; i++) { 3480 wmi_debug("ppet idx %d ppet %x ", 3481 i, cmd->peer_eht_ppet.ppet16_ppet8_ru3_ru0[i]); 3482 } 3483 3484 if ((param->eht_flag) && (param->peer_eht_mcs_count > 1) && 3485 (param->peer_eht_rx_mcs_set[WMI_HOST_EHT_TXRX_MCS_NSS_IDX_160] 3486 == WMI_HOST_EHT_INVALID_MCSNSSMAP || 3487 param->peer_eht_tx_mcs_set[WMI_HOST_EHT_TXRX_MCS_NSS_IDX_160] 3488 == WMI_HOST_HE_INVALID_MCSNSSMAP)) { 3489 wmi_debug("param->peer_eht_tx_mcs_set[160MHz]=%x", 3490 param->peer_eht_tx_mcs_set 3491 [WMI_HOST_HE_TXRX_MCS_NSS_IDX_160]); 3492 wmi_debug("param->peer_eht_rx_mcs_set[160MHz]=%x", 3493 param->peer_eht_rx_mcs_set 3494 [WMI_HOST_HE_TXRX_MCS_NSS_IDX_160]); 3495 wmi_debug("peer_mac="QDF_MAC_ADDR_FMT, 3496 QDF_MAC_ADDR_REF(param->peer_mac)); 3497 } 3498 3499 wmi_debug("EHT cap_mac %x %x ehtops %x EHT phy %x %x %x pp %x", 3500 cmd->peer_eht_cap_mac[0], 3501 cmd->peer_eht_cap_mac[1], cmd->peer_eht_ops, 3502 cmd->peer_eht_cap_phy[0], cmd->peer_eht_cap_phy[1], 3503 cmd->peer_eht_cap_phy[2], cmd->puncture_20mhz_bitmap); 3504 3505 return buf_ptr; 3506 } 3507 #else 3508 static uint8_t *update_peer_flags_tlv_ehtinfo( 3509 wmi_peer_assoc_complete_cmd_fixed_param * cmd, 3510 struct peer_assoc_params *param, uint8_t *buf_ptr) 3511 { 3512 return buf_ptr; 3513 } 3514 #endif 3515 3516 #ifdef WLAN_FEATURE_11BE 3517 static 3518 uint32_t wmi_eht_peer_assoc_params_len(struct peer_assoc_params *param) 3519 { 3520 return (sizeof(wmi_he_rate_set) * param->peer_eht_mcs_count 3521 + WMI_TLV_HDR_SIZE); 3522 } 3523 3524 static void wmi_populate_service_11be(uint32_t *wmi_service) 3525 { 3526 wmi_service[wmi_service_11be] = WMI_SERVICE_11BE; 3527 } 3528 3529 #else 3530 static 3531 uint32_t wmi_eht_peer_assoc_params_len(struct peer_assoc_params *param) 3532 { 3533 return 0; 3534 } 3535 3536 static void wmi_populate_service_11be(uint32_t *wmi_service) 3537 { 3538 } 3539 3540 #endif 3541 3542 /** 3543 * send_peer_assoc_cmd_tlv() - WMI peer assoc function 3544 * @wmi_handle: handle to WMI. 3545 * @param: pointer to peer assoc parameter 3546 * 3547 * Return: QDF_STATUS_SUCCESS for success or error code 3548 */ 3549 static QDF_STATUS send_peer_assoc_cmd_tlv(wmi_unified_t wmi_handle, 3550 struct peer_assoc_params *param) 3551 { 3552 wmi_peer_assoc_complete_cmd_fixed_param *cmd; 3553 wmi_vht_rate_set *mcs; 3554 wmi_he_rate_set *he_mcs; 3555 wmi_buf_t buf; 3556 int32_t len; 3557 uint8_t *buf_ptr; 3558 QDF_STATUS ret; 3559 uint32_t peer_legacy_rates_align; 3560 uint32_t peer_ht_rates_align; 3561 int32_t i; 3562 3563 3564 peer_legacy_rates_align = wmi_align(param->peer_legacy_rates.num_rates); 3565 peer_ht_rates_align = wmi_align(param->peer_ht_rates.num_rates); 3566 3567 len = sizeof(*cmd) + WMI_TLV_HDR_SIZE + 3568 (peer_legacy_rates_align * sizeof(uint8_t)) + 3569 WMI_TLV_HDR_SIZE + 3570 (peer_ht_rates_align * sizeof(uint8_t)) + 3571 sizeof(wmi_vht_rate_set) + 3572 (sizeof(wmi_he_rate_set) * param->peer_he_mcs_count 3573 + WMI_TLV_HDR_SIZE) 3574 + wmi_eht_peer_assoc_params_len(param) + 3575 peer_assoc_mlo_params_size(param) + 3576 peer_assoc_t2lm_params_size(param); 3577 3578 buf = wmi_buf_alloc(wmi_handle, len); 3579 if (!buf) 3580 return QDF_STATUS_E_NOMEM; 3581 3582 buf_ptr = (uint8_t *) wmi_buf_data(buf); 3583 cmd = (wmi_peer_assoc_complete_cmd_fixed_param *) buf_ptr; 3584 WMITLV_SET_HDR(&cmd->tlv_header, 3585 WMITLV_TAG_STRUC_wmi_peer_assoc_complete_cmd_fixed_param, 3586 WMITLV_GET_STRUCT_TLVLEN 3587 (wmi_peer_assoc_complete_cmd_fixed_param)); 3588 3589 cmd->vdev_id = param->vdev_id; 3590 3591 cmd->peer_new_assoc = param->peer_new_assoc; 3592 cmd->peer_associd = param->peer_associd; 3593 3594 copy_peer_flags_tlv(cmd, param); 3595 copy_peer_mac_addr_tlv(cmd, param); 3596 3597 cmd->peer_rate_caps = param->peer_rate_caps; 3598 cmd->peer_caps = param->peer_caps; 3599 cmd->peer_listen_intval = param->peer_listen_intval; 3600 cmd->peer_ht_caps = param->peer_ht_caps; 3601 cmd->peer_max_mpdu = param->peer_max_mpdu; 3602 cmd->peer_mpdu_density = param->peer_mpdu_density; 3603 cmd->peer_vht_caps = param->peer_vht_caps; 3604 cmd->peer_phymode = param->peer_phymode; 3605 cmd->bss_max_idle_option = param->peer_bss_max_idle_option; 3606 3607 /* Update 11ax capabilities */ 3608 cmd->peer_he_cap_info = 3609 param->peer_he_cap_macinfo[WMI_HOST_HECAP_MAC_WORD1]; 3610 cmd->peer_he_cap_info_ext = 3611 param->peer_he_cap_macinfo[WMI_HOST_HECAP_MAC_WORD2]; 3612 cmd->peer_he_cap_info_internal = param->peer_he_cap_info_internal; 3613 cmd->peer_he_ops = param->peer_he_ops; 3614 qdf_mem_copy(&cmd->peer_he_cap_phy, ¶m->peer_he_cap_phyinfo, 3615 sizeof(param->peer_he_cap_phyinfo)); 3616 qdf_mem_copy(&cmd->peer_ppet, ¶m->peer_ppet, 3617 sizeof(param->peer_ppet)); 3618 cmd->peer_he_caps_6ghz = param->peer_he_caps_6ghz; 3619 3620 /* Update peer legacy rate information */ 3621 buf_ptr += sizeof(*cmd); 3622 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, 3623 peer_legacy_rates_align); 3624 buf_ptr += WMI_TLV_HDR_SIZE; 3625 cmd->num_peer_legacy_rates = param->peer_legacy_rates.num_rates; 3626 qdf_mem_copy(buf_ptr, param->peer_legacy_rates.rates, 3627 param->peer_legacy_rates.num_rates); 3628 3629 /* Update peer HT rate information */ 3630 buf_ptr += peer_legacy_rates_align; 3631 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, 3632 peer_ht_rates_align); 3633 buf_ptr += WMI_TLV_HDR_SIZE; 3634 cmd->num_peer_ht_rates = param->peer_ht_rates.num_rates; 3635 qdf_mem_copy(buf_ptr, param->peer_ht_rates.rates, 3636 param->peer_ht_rates.num_rates); 3637 3638 /* VHT Rates */ 3639 buf_ptr += peer_ht_rates_align; 3640 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_STRUC_wmi_vht_rate_set, 3641 WMITLV_GET_STRUCT_TLVLEN(wmi_vht_rate_set)); 3642 3643 cmd->auth_mode = param->akm; 3644 cmd->peer_nss = param->peer_nss; 3645 3646 /* Update bandwidth-NSS mapping */ 3647 cmd->peer_bw_rxnss_override = 0; 3648 cmd->peer_bw_rxnss_override |= param->peer_bw_rxnss_override; 3649 3650 mcs = (wmi_vht_rate_set *) buf_ptr; 3651 if (param->vht_capable) { 3652 mcs->rx_max_rate = param->rx_max_rate; 3653 mcs->rx_mcs_set = param->rx_mcs_set; 3654 mcs->tx_max_rate = param->tx_max_rate; 3655 mcs->tx_mcs_set = param->tx_mcs_set; 3656 mcs->tx_max_mcs_nss = param->tx_max_mcs_nss; 3657 } 3658 3659 /* HE Rates */ 3660 cmd->min_data_rate = param->min_data_rate; 3661 cmd->peer_he_mcs = param->peer_he_mcs_count; 3662 buf_ptr += sizeof(wmi_vht_rate_set); 3663 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 3664 (param->peer_he_mcs_count * sizeof(wmi_he_rate_set))); 3665 buf_ptr += WMI_TLV_HDR_SIZE; 3666 3667 WMI_PEER_STA_TYPE_SET(cmd->sta_type, param->peer_bsscolor_rept_info); 3668 /* Loop through the HE rate set */ 3669 for (i = 0; i < param->peer_he_mcs_count; i++) { 3670 he_mcs = (wmi_he_rate_set *) buf_ptr; 3671 WMITLV_SET_HDR(he_mcs, WMITLV_TAG_STRUC_wmi_he_rate_set, 3672 WMITLV_GET_STRUCT_TLVLEN(wmi_he_rate_set)); 3673 3674 he_mcs->rx_mcs_set = param->peer_he_rx_mcs_set[i]; 3675 he_mcs->tx_mcs_set = param->peer_he_tx_mcs_set[i]; 3676 wmi_debug("HE idx %d RxMCSmap %x TxMCSmap %x ", 3677 i, he_mcs->rx_mcs_set, he_mcs->tx_mcs_set); 3678 buf_ptr += sizeof(wmi_he_rate_set); 3679 } 3680 3681 if ((param->he_flag) && (param->peer_he_mcs_count > 1) && 3682 (param->peer_he_rx_mcs_set[WMI_HOST_HE_TXRX_MCS_NSS_IDX_160] 3683 == WMI_HOST_HE_INVALID_MCSNSSMAP || 3684 param->peer_he_tx_mcs_set[WMI_HOST_HE_TXRX_MCS_NSS_IDX_160] 3685 == WMI_HOST_HE_INVALID_MCSNSSMAP)) { 3686 wmi_debug("param->peer_he_tx_mcs_set[160MHz]=%x", 3687 param->peer_he_tx_mcs_set[WMI_HOST_HE_TXRX_MCS_NSS_IDX_160]); 3688 wmi_debug("param->peer_he_rx_mcs_set[160MHz]=%x", 3689 param->peer_he_rx_mcs_set[WMI_HOST_HE_TXRX_MCS_NSS_IDX_160]); 3690 wmi_debug("peer_mac="QDF_MAC_ADDR_FMT, 3691 QDF_MAC_ADDR_REF(param->peer_mac)); 3692 } 3693 3694 wmi_debug("vdev_id %d associd %d peer_flags %x rate_caps %x " 3695 "peer_caps %x listen_intval %d ht_caps %x max_mpdu %d " 3696 "nss %d phymode %d peer_mpdu_density %d " 3697 "cmd->peer_vht_caps %x " 3698 "HE cap_info %x ops %x " 3699 "HE cap_info_ext %x " 3700 "HE phy %x %x %x " 3701 "peer_bw_rxnss_override %x", 3702 cmd->vdev_id, cmd->peer_associd, cmd->peer_flags, 3703 cmd->peer_rate_caps, cmd->peer_caps, 3704 cmd->peer_listen_intval, cmd->peer_ht_caps, 3705 cmd->peer_max_mpdu, cmd->peer_nss, cmd->peer_phymode, 3706 cmd->peer_mpdu_density, 3707 cmd->peer_vht_caps, cmd->peer_he_cap_info, 3708 cmd->peer_he_ops, cmd->peer_he_cap_info_ext, 3709 cmd->peer_he_cap_phy[0], cmd->peer_he_cap_phy[1], 3710 cmd->peer_he_cap_phy[2], 3711 cmd->peer_bw_rxnss_override); 3712 3713 buf_ptr = peer_assoc_add_mlo_params(buf_ptr, param); 3714 3715 buf_ptr = update_peer_flags_tlv_ehtinfo(cmd, param, buf_ptr); 3716 3717 buf_ptr = peer_assoc_add_ml_partner_links(buf_ptr, param); 3718 3719 buf_ptr = peer_assoc_add_tid_to_link_map(buf_ptr, param); 3720 3721 wmi_mtrace(WMI_PEER_ASSOC_CMDID, cmd->vdev_id, 0); 3722 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 3723 WMI_PEER_ASSOC_CMDID); 3724 if (QDF_IS_STATUS_ERROR(ret)) { 3725 wmi_err("Failed to send peer assoc command ret = %d", ret); 3726 wmi_buf_free(buf); 3727 } 3728 3729 return ret; 3730 } 3731 3732 /* copy_scan_notify_events() - Helper routine to copy scan notify events 3733 */ 3734 static inline void copy_scan_event_cntrl_flags( 3735 wmi_start_scan_cmd_fixed_param * cmd, 3736 struct scan_req_params *param) 3737 { 3738 3739 /* Scan events subscription */ 3740 if (param->scan_ev_started) 3741 cmd->notify_scan_events |= WMI_SCAN_EVENT_STARTED; 3742 if (param->scan_ev_completed) 3743 cmd->notify_scan_events |= WMI_SCAN_EVENT_COMPLETED; 3744 if (param->scan_ev_bss_chan) 3745 cmd->notify_scan_events |= WMI_SCAN_EVENT_BSS_CHANNEL; 3746 if (param->scan_ev_foreign_chan) 3747 cmd->notify_scan_events |= WMI_SCAN_EVENT_FOREIGN_CHANNEL; 3748 if (param->scan_ev_dequeued) 3749 cmd->notify_scan_events |= WMI_SCAN_EVENT_DEQUEUED; 3750 if (param->scan_ev_preempted) 3751 cmd->notify_scan_events |= WMI_SCAN_EVENT_PREEMPTED; 3752 if (param->scan_ev_start_failed) 3753 cmd->notify_scan_events |= WMI_SCAN_EVENT_START_FAILED; 3754 if (param->scan_ev_restarted) 3755 cmd->notify_scan_events |= WMI_SCAN_EVENT_RESTARTED; 3756 if (param->scan_ev_foreign_chn_exit) 3757 cmd->notify_scan_events |= WMI_SCAN_EVENT_FOREIGN_CHANNEL_EXIT; 3758 if (param->scan_ev_suspended) 3759 cmd->notify_scan_events |= WMI_SCAN_EVENT_SUSPENDED; 3760 if (param->scan_ev_resumed) 3761 cmd->notify_scan_events |= WMI_SCAN_EVENT_RESUMED; 3762 3763 /** Set scan control flags */ 3764 cmd->scan_ctrl_flags = 0; 3765 if (param->scan_f_passive) 3766 cmd->scan_ctrl_flags |= WMI_SCAN_FLAG_PASSIVE; 3767 if (param->scan_f_strict_passive_pch) 3768 cmd->scan_ctrl_flags |= WMI_SCAN_FLAG_STRICT_PASSIVE_ON_PCHN; 3769 if (param->scan_f_promisc_mode) 3770 cmd->scan_ctrl_flags |= WMI_SCAN_FILTER_PROMISCOUS; 3771 if (param->scan_f_capture_phy_err) 3772 cmd->scan_ctrl_flags |= WMI_SCAN_CAPTURE_PHY_ERROR; 3773 if (param->scan_f_half_rate) 3774 cmd->scan_ctrl_flags |= WMI_SCAN_FLAG_HALF_RATE_SUPPORT; 3775 if (param->scan_f_quarter_rate) 3776 cmd->scan_ctrl_flags |= WMI_SCAN_FLAG_QUARTER_RATE_SUPPORT; 3777 if (param->scan_f_cck_rates) 3778 cmd->scan_ctrl_flags |= WMI_SCAN_ADD_CCK_RATES; 3779 if (param->scan_f_ofdm_rates) 3780 cmd->scan_ctrl_flags |= WMI_SCAN_ADD_OFDM_RATES; 3781 if (param->scan_f_chan_stat_evnt) 3782 cmd->scan_ctrl_flags |= WMI_SCAN_CHAN_STAT_EVENT; 3783 if (param->scan_f_filter_prb_req) 3784 cmd->scan_ctrl_flags |= WMI_SCAN_FILTER_PROBE_REQ; 3785 if (param->scan_f_bcast_probe) 3786 cmd->scan_ctrl_flags |= WMI_SCAN_ADD_BCAST_PROBE_REQ; 3787 if (param->scan_f_offchan_mgmt_tx) 3788 cmd->scan_ctrl_flags |= WMI_SCAN_OFFCHAN_MGMT_TX; 3789 if (param->scan_f_offchan_data_tx) 3790 cmd->scan_ctrl_flags |= WMI_SCAN_OFFCHAN_DATA_TX; 3791 if (param->scan_f_force_active_dfs_chn) 3792 cmd->scan_ctrl_flags |= WMI_SCAN_FLAG_FORCE_ACTIVE_ON_DFS; 3793 if (param->scan_f_add_tpc_ie_in_probe) 3794 cmd->scan_ctrl_flags |= WMI_SCAN_ADD_TPC_IE_IN_PROBE_REQ; 3795 if (param->scan_f_add_ds_ie_in_probe) 3796 cmd->scan_ctrl_flags |= WMI_SCAN_ADD_DS_IE_IN_PROBE_REQ; 3797 if (param->scan_f_add_spoofed_mac_in_probe) 3798 cmd->scan_ctrl_flags |= WMI_SCAN_ADD_SPOOFED_MAC_IN_PROBE_REQ; 3799 if (param->scan_f_add_rand_seq_in_probe) 3800 cmd->scan_ctrl_flags |= WMI_SCAN_RANDOM_SEQ_NO_IN_PROBE_REQ; 3801 if (param->scan_f_en_ie_allowlist_in_probe) 3802 cmd->scan_ctrl_flags |= 3803 WMI_SCAN_ENABLE_IE_WHTELIST_IN_PROBE_REQ; 3804 3805 /* for adaptive scan mode using 3 bits (21 - 23 bits) */ 3806 WMI_SCAN_SET_DWELL_MODE(cmd->scan_ctrl_flags, 3807 param->adaptive_dwell_time_mode); 3808 } 3809 3810 /* scan_copy_ie_buffer() - Copy scan ie_data */ 3811 static inline void scan_copy_ie_buffer(uint8_t *buf_ptr, 3812 struct scan_req_params *params) 3813 { 3814 qdf_mem_copy(buf_ptr, params->extraie.ptr, params->extraie.len); 3815 } 3816 3817 /** 3818 * wmi_copy_scan_random_mac() - To copy scan randomization attrs to wmi buffer 3819 * @mac: random mac addr 3820 * @mask: random mac mask 3821 * @mac_addr: wmi random mac 3822 * @mac_mask: wmi random mac mask 3823 * 3824 * Return None. 3825 */ 3826 static inline 3827 void wmi_copy_scan_random_mac(uint8_t *mac, uint8_t *mask, 3828 wmi_mac_addr *mac_addr, wmi_mac_addr *mac_mask) 3829 { 3830 WMI_CHAR_ARRAY_TO_MAC_ADDR(mac, mac_addr); 3831 WMI_CHAR_ARRAY_TO_MAC_ADDR(mask, mac_mask); 3832 } 3833 3834 /* 3835 * wmi_fill_vendor_oui() - fill vendor OUIs 3836 * @buf_ptr: pointer to wmi tlv buffer 3837 * @num_vendor_oui: number of vendor OUIs to be filled 3838 * @param_voui: pointer to OUI buffer 3839 * 3840 * This function populates the wmi tlv buffer when vendor specific OUIs are 3841 * present. 3842 * 3843 * Return: None 3844 */ 3845 static inline 3846 void wmi_fill_vendor_oui(uint8_t *buf_ptr, uint32_t num_vendor_oui, 3847 uint32_t *pvoui) 3848 { 3849 wmi_vendor_oui *voui = NULL; 3850 uint32_t i; 3851 3852 voui = (wmi_vendor_oui *)buf_ptr; 3853 3854 for (i = 0; i < num_vendor_oui; i++) { 3855 WMITLV_SET_HDR(&voui[i].tlv_header, 3856 WMITLV_TAG_STRUC_wmi_vendor_oui, 3857 WMITLV_GET_STRUCT_TLVLEN(wmi_vendor_oui)); 3858 voui[i].oui_type_subtype = pvoui[i]; 3859 } 3860 } 3861 3862 /* 3863 * wmi_fill_ie_allowlist_attrs() - fill IE allowlist attrs 3864 * @ie_bitmap: output pointer to ie bit map in cmd 3865 * @num_vendor_oui: output pointer to num vendor OUIs 3866 * @ie_allowlist: input parameter 3867 * 3868 * This function populates the IE allowlist attrs of scan, pno and 3869 * scan oui commands for ie_allowlist parameter. 3870 * 3871 * Return: None 3872 */ 3873 static inline 3874 void wmi_fill_ie_allowlist_attrs(uint32_t *ie_bitmap, 3875 uint32_t *num_vendor_oui, 3876 struct probe_req_allowlist_attr *ie_allowlist) 3877 { 3878 uint32_t i = 0; 3879 3880 for (i = 0; i < PROBE_REQ_BITMAP_LEN; i++) 3881 ie_bitmap[i] = ie_allowlist->ie_bitmap[i]; 3882 3883 *num_vendor_oui = ie_allowlist->num_vendor_oui; 3884 } 3885 3886 /** 3887 * send_scan_start_cmd_tlv() - WMI scan start function 3888 * @wmi_handle: handle to WMI. 3889 * @params: pointer to hold scan start cmd parameter 3890 * 3891 * Return: QDF_STATUS_SUCCESS for success or error code 3892 */ 3893 static QDF_STATUS send_scan_start_cmd_tlv(wmi_unified_t wmi_handle, 3894 struct scan_req_params *params) 3895 { 3896 int32_t ret = 0; 3897 int32_t i; 3898 wmi_buf_t wmi_buf; 3899 wmi_start_scan_cmd_fixed_param *cmd; 3900 uint8_t *buf_ptr; 3901 uint32_t *tmp_ptr; 3902 wmi_ssid *ssid = NULL; 3903 wmi_mac_addr *bssid; 3904 size_t len = sizeof(*cmd); 3905 uint16_t extraie_len_with_pad = 0; 3906 uint8_t phymode_roundup = 0; 3907 struct probe_req_allowlist_attr *ie_allowlist = ¶ms->ie_allowlist; 3908 wmi_hint_freq_short_ssid *s_ssid = NULL; 3909 wmi_hint_freq_bssid *hint_bssid = NULL; 3910 3911 /* Length TLV placeholder for array of uint32_t */ 3912 len += WMI_TLV_HDR_SIZE; 3913 /* calculate the length of buffer required */ 3914 if (params->chan_list.num_chan) 3915 len += params->chan_list.num_chan * sizeof(uint32_t); 3916 3917 /* Length TLV placeholder for array of wmi_ssid structures */ 3918 len += WMI_TLV_HDR_SIZE; 3919 if (params->num_ssids) 3920 len += params->num_ssids * sizeof(wmi_ssid); 3921 3922 /* Length TLV placeholder for array of wmi_mac_addr structures */ 3923 len += WMI_TLV_HDR_SIZE; 3924 if (params->num_bssid) 3925 len += sizeof(wmi_mac_addr) * params->num_bssid; 3926 3927 /* Length TLV placeholder for array of bytes */ 3928 len += WMI_TLV_HDR_SIZE; 3929 if (params->extraie.len) 3930 extraie_len_with_pad = 3931 roundup(params->extraie.len, sizeof(uint32_t)); 3932 len += extraie_len_with_pad; 3933 3934 len += WMI_TLV_HDR_SIZE; /* Length of TLV for array of wmi_vendor_oui */ 3935 if (ie_allowlist->num_vendor_oui) 3936 len += ie_allowlist->num_vendor_oui * sizeof(wmi_vendor_oui); 3937 3938 len += WMI_TLV_HDR_SIZE; /* Length of TLV for array of scan phymode */ 3939 if (params->scan_f_wide_band) 3940 phymode_roundup = 3941 qdf_roundup(params->chan_list.num_chan * sizeof(uint8_t), 3942 sizeof(uint32_t)); 3943 len += phymode_roundup; 3944 3945 len += WMI_TLV_HDR_SIZE; 3946 if (params->num_hint_bssid) 3947 len += params->num_hint_bssid * sizeof(wmi_hint_freq_bssid); 3948 3949 len += WMI_TLV_HDR_SIZE; 3950 if (params->num_hint_s_ssid) 3951 len += params->num_hint_s_ssid * sizeof(wmi_hint_freq_short_ssid); 3952 3953 /* Allocate the memory */ 3954 wmi_buf = wmi_buf_alloc(wmi_handle, len); 3955 if (!wmi_buf) 3956 return QDF_STATUS_E_FAILURE; 3957 3958 buf_ptr = (uint8_t *) wmi_buf_data(wmi_buf); 3959 cmd = (wmi_start_scan_cmd_fixed_param *) buf_ptr; 3960 WMITLV_SET_HDR(&cmd->tlv_header, 3961 WMITLV_TAG_STRUC_wmi_start_scan_cmd_fixed_param, 3962 WMITLV_GET_STRUCT_TLVLEN 3963 (wmi_start_scan_cmd_fixed_param)); 3964 3965 cmd->scan_id = params->scan_id; 3966 cmd->scan_req_id = params->scan_req_id; 3967 cmd->vdev_id = params->vdev_id; 3968 cmd->scan_priority = params->scan_priority; 3969 3970 copy_scan_event_cntrl_flags(cmd, params); 3971 3972 cmd->dwell_time_active = params->dwell_time_active; 3973 cmd->dwell_time_active_2g = params->dwell_time_active_2g; 3974 cmd->dwell_time_passive = params->dwell_time_passive; 3975 cmd->min_dwell_time_6ghz = params->min_dwell_time_6g; 3976 cmd->dwell_time_active_6ghz = params->dwell_time_active_6g; 3977 cmd->dwell_time_passive_6ghz = params->dwell_time_passive_6g; 3978 cmd->scan_start_offset = params->scan_offset_time; 3979 cmd->min_rest_time = params->min_rest_time; 3980 cmd->max_rest_time = params->max_rest_time; 3981 cmd->repeat_probe_time = params->repeat_probe_time; 3982 cmd->probe_spacing_time = params->probe_spacing_time; 3983 cmd->idle_time = params->idle_time; 3984 cmd->max_scan_time = params->max_scan_time; 3985 cmd->probe_delay = params->probe_delay; 3986 cmd->burst_duration = params->burst_duration; 3987 cmd->num_chan = params->chan_list.num_chan; 3988 cmd->num_bssid = params->num_bssid; 3989 cmd->num_ssids = params->num_ssids; 3990 cmd->ie_len = params->extraie.len; 3991 cmd->n_probes = params->n_probes; 3992 cmd->scan_ctrl_flags_ext = params->scan_ctrl_flags_ext; 3993 3994 if (params->scan_random.randomize) 3995 wmi_copy_scan_random_mac(params->scan_random.mac_addr, 3996 params->scan_random.mac_mask, 3997 &cmd->mac_addr, 3998 &cmd->mac_mask); 3999 4000 if (ie_allowlist->allow_list) 4001 wmi_fill_ie_allowlist_attrs(cmd->ie_bitmap, 4002 &cmd->num_vendor_oui, 4003 ie_allowlist); 4004 4005 buf_ptr += sizeof(*cmd); 4006 tmp_ptr = (uint32_t *) (buf_ptr + WMI_TLV_HDR_SIZE); 4007 for (i = 0; i < params->chan_list.num_chan; ++i) { 4008 TARGET_SET_FREQ_IN_CHAN_LIST_TLV(tmp_ptr[i], 4009 params->chan_list.chan[i].freq); 4010 TARGET_SET_FLAGS_IN_CHAN_LIST_TLV(tmp_ptr[i], 4011 params->chan_list.chan[i].flags); 4012 } 4013 4014 WMITLV_SET_HDR(buf_ptr, 4015 WMITLV_TAG_ARRAY_UINT32, 4016 (params->chan_list.num_chan * sizeof(uint32_t))); 4017 buf_ptr += WMI_TLV_HDR_SIZE + 4018 (params->chan_list.num_chan * sizeof(uint32_t)); 4019 4020 if (params->num_ssids > WLAN_SCAN_MAX_NUM_SSID) { 4021 wmi_err("Invalid value for num_ssids %d", params->num_ssids); 4022 goto error; 4023 } 4024 4025 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_FIXED_STRUC, 4026 (params->num_ssids * sizeof(wmi_ssid))); 4027 4028 if (params->num_ssids) { 4029 ssid = (wmi_ssid *) (buf_ptr + WMI_TLV_HDR_SIZE); 4030 for (i = 0; i < params->num_ssids; ++i) { 4031 ssid->ssid_len = params->ssid[i].length; 4032 qdf_mem_copy(ssid->ssid, params->ssid[i].ssid, 4033 params->ssid[i].length); 4034 ssid++; 4035 } 4036 } 4037 buf_ptr += WMI_TLV_HDR_SIZE + (params->num_ssids * sizeof(wmi_ssid)); 4038 4039 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_FIXED_STRUC, 4040 (params->num_bssid * sizeof(wmi_mac_addr))); 4041 bssid = (wmi_mac_addr *) (buf_ptr + WMI_TLV_HDR_SIZE); 4042 4043 if (params->num_bssid) { 4044 for (i = 0; i < params->num_bssid; ++i) { 4045 WMI_CHAR_ARRAY_TO_MAC_ADDR( 4046 ¶ms->bssid_list[i].bytes[0], bssid); 4047 bssid++; 4048 } 4049 } 4050 4051 buf_ptr += WMI_TLV_HDR_SIZE + 4052 (params->num_bssid * sizeof(wmi_mac_addr)); 4053 4054 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, extraie_len_with_pad); 4055 if (params->extraie.len) 4056 scan_copy_ie_buffer(buf_ptr + WMI_TLV_HDR_SIZE, 4057 params); 4058 4059 buf_ptr += WMI_TLV_HDR_SIZE + extraie_len_with_pad; 4060 4061 /* probe req ie allowlisting */ 4062 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 4063 ie_allowlist->num_vendor_oui * sizeof(wmi_vendor_oui)); 4064 4065 buf_ptr += WMI_TLV_HDR_SIZE; 4066 4067 if (cmd->num_vendor_oui) { 4068 wmi_fill_vendor_oui(buf_ptr, cmd->num_vendor_oui, 4069 ie_allowlist->voui); 4070 buf_ptr += cmd->num_vendor_oui * sizeof(wmi_vendor_oui); 4071 } 4072 4073 /* Add phy mode TLV if it's a wide band scan */ 4074 if (params->scan_f_wide_band) { 4075 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, phymode_roundup); 4076 buf_ptr = (uint8_t *) (buf_ptr + WMI_TLV_HDR_SIZE); 4077 for (i = 0; i < params->chan_list.num_chan; ++i) 4078 buf_ptr[i] = 4079 WMI_SCAN_CHAN_SET_MODE(params->chan_list.chan[i].phymode); 4080 buf_ptr += phymode_roundup; 4081 } else { 4082 /* Add ZERO length phy mode TLV */ 4083 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, 0); 4084 buf_ptr += WMI_TLV_HDR_SIZE; 4085 } 4086 4087 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_FIXED_STRUC, 4088 (params->num_hint_s_ssid * sizeof(wmi_hint_freq_short_ssid))); 4089 if (params->num_hint_s_ssid) { 4090 s_ssid = (wmi_hint_freq_short_ssid *)(buf_ptr + WMI_TLV_HDR_SIZE); 4091 for (i = 0; i < params->num_hint_s_ssid; ++i) { 4092 s_ssid->freq_flags = params->hint_s_ssid[i].freq_flags; 4093 s_ssid->short_ssid = params->hint_s_ssid[i].short_ssid; 4094 s_ssid++; 4095 } 4096 } 4097 buf_ptr += WMI_TLV_HDR_SIZE + 4098 (params->num_hint_s_ssid * sizeof(wmi_hint_freq_short_ssid)); 4099 4100 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_FIXED_STRUC, 4101 (params->num_hint_bssid * sizeof(wmi_hint_freq_bssid))); 4102 if (params->num_hint_bssid) { 4103 hint_bssid = (wmi_hint_freq_bssid *)(buf_ptr + WMI_TLV_HDR_SIZE); 4104 for (i = 0; i < params->num_hint_bssid; ++i) { 4105 hint_bssid->freq_flags = 4106 params->hint_bssid[i].freq_flags; 4107 WMI_CHAR_ARRAY_TO_MAC_ADDR(¶ms->hint_bssid[i].bssid.bytes[0], 4108 &hint_bssid->bssid); 4109 hint_bssid++; 4110 } 4111 } 4112 4113 wmi_mtrace(WMI_START_SCAN_CMDID, cmd->vdev_id, 0); 4114 ret = wmi_unified_cmd_send(wmi_handle, wmi_buf, 4115 len, WMI_START_SCAN_CMDID); 4116 if (ret) { 4117 wmi_err("Failed to start scan: %d", ret); 4118 wmi_buf_free(wmi_buf); 4119 } 4120 return ret; 4121 error: 4122 wmi_buf_free(wmi_buf); 4123 return QDF_STATUS_E_FAILURE; 4124 } 4125 4126 /** 4127 * send_scan_stop_cmd_tlv() - WMI scan start function 4128 * @wmi_handle: handle to WMI. 4129 * @param: pointer to hold scan cancel cmd parameter 4130 * 4131 * Return: QDF_STATUS_SUCCESS for success or error code 4132 */ 4133 static QDF_STATUS send_scan_stop_cmd_tlv(wmi_unified_t wmi_handle, 4134 struct scan_cancel_param *param) 4135 { 4136 wmi_stop_scan_cmd_fixed_param *cmd; 4137 int ret; 4138 int len = sizeof(*cmd); 4139 wmi_buf_t wmi_buf; 4140 4141 /* Allocate the memory */ 4142 wmi_buf = wmi_buf_alloc(wmi_handle, len); 4143 if (!wmi_buf) { 4144 ret = QDF_STATUS_E_NOMEM; 4145 goto error; 4146 } 4147 4148 cmd = (wmi_stop_scan_cmd_fixed_param *) wmi_buf_data(wmi_buf); 4149 WMITLV_SET_HDR(&cmd->tlv_header, 4150 WMITLV_TAG_STRUC_wmi_stop_scan_cmd_fixed_param, 4151 WMITLV_GET_STRUCT_TLVLEN(wmi_stop_scan_cmd_fixed_param)); 4152 cmd->vdev_id = param->vdev_id; 4153 cmd->requestor = param->requester; 4154 cmd->scan_id = param->scan_id; 4155 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 4156 wmi_handle, 4157 param->pdev_id); 4158 /* stop the scan with the corresponding scan_id */ 4159 if (param->req_type == WLAN_SCAN_CANCEL_PDEV_ALL) { 4160 /* Cancelling all scans */ 4161 cmd->req_type = WMI_SCAN_STOP_ALL; 4162 } else if (param->req_type == WLAN_SCAN_CANCEL_VDEV_ALL) { 4163 /* Cancelling VAP scans */ 4164 cmd->req_type = WMI_SCN_STOP_VAP_ALL; 4165 } else if (param->req_type == WLAN_SCAN_CANCEL_SINGLE) { 4166 /* Cancelling specific scan */ 4167 cmd->req_type = WMI_SCAN_STOP_ONE; 4168 } else if (param->req_type == WLAN_SCAN_CANCEL_HOST_VDEV_ALL) { 4169 cmd->req_type = WMI_SCN_STOP_HOST_VAP_ALL; 4170 } else { 4171 wmi_err("Invalid Scan cancel req type: %d", param->req_type); 4172 wmi_buf_free(wmi_buf); 4173 return QDF_STATUS_E_INVAL; 4174 } 4175 4176 wmi_mtrace(WMI_STOP_SCAN_CMDID, cmd->vdev_id, 0); 4177 ret = wmi_unified_cmd_send(wmi_handle, wmi_buf, 4178 len, WMI_STOP_SCAN_CMDID); 4179 if (ret) { 4180 wmi_err("Failed to send stop scan: %d", ret); 4181 wmi_buf_free(wmi_buf); 4182 } 4183 4184 error: 4185 return ret; 4186 } 4187 4188 #define WMI_MAX_CHAN_INFO_LOG 192 4189 4190 /** 4191 * wmi_scan_chanlist_dump() - Dump scan channel list info 4192 * @scan_chan_list: scan channel list 4193 * 4194 * Return: void 4195 */ 4196 static void wmi_scan_chanlist_dump(struct scan_chan_list_params *scan_chan_list) 4197 { 4198 uint32_t i; 4199 uint8_t info[WMI_MAX_CHAN_INFO_LOG]; 4200 uint32_t len = 0; 4201 struct channel_param *chan; 4202 int ret; 4203 4204 wmi_debug("Total chan %d", scan_chan_list->nallchans); 4205 for (i = 0; i < scan_chan_list->nallchans; i++) { 4206 chan = &scan_chan_list->ch_param[i]; 4207 ret = qdf_scnprintf(info + len, sizeof(info) - len, 4208 " %d[%d][%d][%d]", chan->mhz, 4209 chan->maxregpower, 4210 chan->dfs_set, chan->nan_disabled); 4211 if (ret <= 0) 4212 break; 4213 len += ret; 4214 if (len >= (sizeof(info) - 20)) { 4215 wmi_nofl_debug("Chan[TXPwr][DFS][nan_disabled]:%s", 4216 info); 4217 len = 0; 4218 } 4219 } 4220 if (len) 4221 wmi_nofl_debug("Chan[TXPwr][DFS]:%s", info); 4222 } 4223 4224 static QDF_STATUS send_scan_chan_list_cmd_tlv(wmi_unified_t wmi_handle, 4225 struct scan_chan_list_params *chan_list) 4226 { 4227 wmi_buf_t buf; 4228 QDF_STATUS qdf_status = QDF_STATUS_SUCCESS; 4229 wmi_scan_chan_list_cmd_fixed_param *cmd; 4230 int i; 4231 uint8_t *buf_ptr; 4232 wmi_channel *chan_info; 4233 struct channel_param *tchan_info; 4234 uint16_t len; 4235 uint16_t num_send_chans, num_sends = 0; 4236 4237 wmi_scan_chanlist_dump(chan_list); 4238 tchan_info = &chan_list->ch_param[0]; 4239 while (chan_list->nallchans) { 4240 len = sizeof(*cmd) + WMI_TLV_HDR_SIZE; 4241 if (chan_list->nallchans > MAX_NUM_CHAN_PER_WMI_CMD) 4242 num_send_chans = MAX_NUM_CHAN_PER_WMI_CMD; 4243 else 4244 num_send_chans = chan_list->nallchans; 4245 4246 chan_list->nallchans -= num_send_chans; 4247 len += sizeof(wmi_channel) * num_send_chans; 4248 buf = wmi_buf_alloc(wmi_handle, len); 4249 if (!buf) { 4250 qdf_status = QDF_STATUS_E_NOMEM; 4251 goto end; 4252 } 4253 4254 buf_ptr = (uint8_t *)wmi_buf_data(buf); 4255 cmd = (wmi_scan_chan_list_cmd_fixed_param *)buf_ptr; 4256 WMITLV_SET_HDR(&cmd->tlv_header, 4257 WMITLV_TAG_STRUC_wmi_scan_chan_list_cmd_fixed_param, 4258 WMITLV_GET_STRUCT_TLVLEN 4259 (wmi_scan_chan_list_cmd_fixed_param)); 4260 4261 wmi_debug("no of channels = %d, len = %d", num_send_chans, len); 4262 4263 if (num_sends) 4264 cmd->flags |= APPEND_TO_EXISTING_CHAN_LIST; 4265 4266 if (chan_list->max_bw_support_present) 4267 cmd->flags |= CHANNEL_MAX_BANDWIDTH_VALID; 4268 4269 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 4270 wmi_handle, 4271 chan_list->pdev_id); 4272 4273 wmi_mtrace(WMI_SCAN_CHAN_LIST_CMDID, cmd->pdev_id, 0); 4274 4275 cmd->num_scan_chans = num_send_chans; 4276 WMITLV_SET_HDR((buf_ptr + 4277 sizeof(wmi_scan_chan_list_cmd_fixed_param)), 4278 WMITLV_TAG_ARRAY_STRUC, 4279 sizeof(wmi_channel) * num_send_chans); 4280 chan_info = (wmi_channel *)(buf_ptr + sizeof(*cmd) + 4281 WMI_TLV_HDR_SIZE); 4282 4283 for (i = 0; i < num_send_chans; ++i) { 4284 WMITLV_SET_HDR(&chan_info->tlv_header, 4285 WMITLV_TAG_STRUC_wmi_channel, 4286 WMITLV_GET_STRUCT_TLVLEN(wmi_channel)); 4287 chan_info->mhz = tchan_info->mhz; 4288 chan_info->band_center_freq1 = 4289 tchan_info->cfreq1; 4290 chan_info->band_center_freq2 = 4291 tchan_info->cfreq2; 4292 4293 if (tchan_info->is_chan_passive) 4294 WMI_SET_CHANNEL_FLAG(chan_info, 4295 WMI_CHAN_FLAG_PASSIVE); 4296 if (tchan_info->dfs_set) 4297 WMI_SET_CHANNEL_FLAG(chan_info, 4298 WMI_CHAN_FLAG_DFS); 4299 4300 if (tchan_info->dfs_set_cfreq2) 4301 WMI_SET_CHANNEL_FLAG(chan_info, 4302 WMI_CHAN_FLAG_DFS_CFREQ2); 4303 4304 if (tchan_info->allow_he) 4305 WMI_SET_CHANNEL_FLAG(chan_info, 4306 WMI_CHAN_FLAG_ALLOW_HE); 4307 4308 if (tchan_info->allow_eht) 4309 WMI_SET_CHANNEL_FLAG(chan_info, 4310 WMI_CHAN_FLAG_ALLOW_EHT); 4311 4312 if (tchan_info->allow_vht) 4313 WMI_SET_CHANNEL_FLAG(chan_info, 4314 WMI_CHAN_FLAG_ALLOW_VHT); 4315 4316 if (tchan_info->allow_ht) 4317 WMI_SET_CHANNEL_FLAG(chan_info, 4318 WMI_CHAN_FLAG_ALLOW_HT); 4319 WMI_SET_CHANNEL_MODE(chan_info, 4320 tchan_info->phy_mode); 4321 4322 if (tchan_info->half_rate) 4323 WMI_SET_CHANNEL_FLAG(chan_info, 4324 WMI_CHAN_FLAG_HALF_RATE); 4325 4326 if (tchan_info->quarter_rate) 4327 WMI_SET_CHANNEL_FLAG(chan_info, 4328 WMI_CHAN_FLAG_QUARTER_RATE); 4329 4330 if (tchan_info->psc_channel) 4331 WMI_SET_CHANNEL_FLAG(chan_info, 4332 WMI_CHAN_FLAG_PSC); 4333 4334 if (tchan_info->nan_disabled) 4335 WMI_SET_CHANNEL_FLAG(chan_info, 4336 WMI_CHAN_FLAG_NAN_DISABLED); 4337 4338 /* also fill in power information */ 4339 WMI_SET_CHANNEL_MIN_POWER(chan_info, 4340 tchan_info->minpower); 4341 WMI_SET_CHANNEL_MAX_POWER(chan_info, 4342 tchan_info->maxpower); 4343 WMI_SET_CHANNEL_REG_POWER(chan_info, 4344 tchan_info->maxregpower); 4345 WMI_SET_CHANNEL_ANTENNA_MAX(chan_info, 4346 tchan_info->antennamax); 4347 WMI_SET_CHANNEL_REG_CLASSID(chan_info, 4348 tchan_info->reg_class_id); 4349 WMI_SET_CHANNEL_MAX_TX_POWER(chan_info, 4350 tchan_info->maxregpower); 4351 WMI_SET_CHANNEL_MAX_BANDWIDTH(chan_info, 4352 tchan_info->max_bw_supported); 4353 4354 tchan_info++; 4355 chan_info++; 4356 } 4357 4358 qdf_status = wmi_unified_cmd_send( 4359 wmi_handle, 4360 buf, len, WMI_SCAN_CHAN_LIST_CMDID); 4361 4362 if (QDF_IS_STATUS_ERROR(qdf_status)) { 4363 wmi_err("Failed to send WMI_SCAN_CHAN_LIST_CMDID"); 4364 wmi_buf_free(buf); 4365 goto end; 4366 } 4367 num_sends++; 4368 } 4369 4370 end: 4371 return qdf_status; 4372 } 4373 4374 /** 4375 * populate_tx_send_params - Populate TX param TLV for mgmt and offchan tx 4376 * 4377 * @bufp: Pointer to buffer 4378 * @param: Pointer to tx param 4379 * 4380 * Return: QDF_STATUS_SUCCESS for success and QDF_STATUS_E_FAILURE for failure 4381 */ 4382 static inline QDF_STATUS populate_tx_send_params(uint8_t *bufp, 4383 struct tx_send_params param) 4384 { 4385 wmi_tx_send_params *tx_param; 4386 QDF_STATUS status = QDF_STATUS_SUCCESS; 4387 4388 if (!bufp) { 4389 status = QDF_STATUS_E_FAILURE; 4390 return status; 4391 } 4392 tx_param = (wmi_tx_send_params *)bufp; 4393 WMITLV_SET_HDR(&tx_param->tlv_header, 4394 WMITLV_TAG_STRUC_wmi_tx_send_params, 4395 WMITLV_GET_STRUCT_TLVLEN(wmi_tx_send_params)); 4396 WMI_TX_SEND_PARAM_PWR_SET(tx_param->tx_param_dword0, param.pwr); 4397 WMI_TX_SEND_PARAM_MCS_MASK_SET(tx_param->tx_param_dword0, 4398 param.mcs_mask); 4399 WMI_TX_SEND_PARAM_NSS_MASK_SET(tx_param->tx_param_dword0, 4400 param.nss_mask); 4401 WMI_TX_SEND_PARAM_RETRY_LIMIT_SET(tx_param->tx_param_dword0, 4402 param.retry_limit); 4403 WMI_TX_SEND_PARAM_CHAIN_MASK_SET(tx_param->tx_param_dword1, 4404 param.chain_mask); 4405 WMI_TX_SEND_PARAM_BW_MASK_SET(tx_param->tx_param_dword1, 4406 param.bw_mask); 4407 WMI_TX_SEND_PARAM_PREAMBLE_SET(tx_param->tx_param_dword1, 4408 param.preamble_type); 4409 WMI_TX_SEND_PARAM_FRAME_TYPE_SET(tx_param->tx_param_dword1, 4410 param.frame_type); 4411 WMI_TX_SEND_PARAM_CFR_CAPTURE_SET(tx_param->tx_param_dword1, 4412 param.cfr_enable); 4413 WMI_TX_SEND_PARAM_BEAMFORM_SET(tx_param->tx_param_dword1, 4414 param.en_beamforming); 4415 WMI_TX_SEND_PARAM_RETRY_LIMIT_EXT_SET(tx_param->tx_param_dword1, 4416 param.retry_limit_ext); 4417 4418 return status; 4419 } 4420 4421 #ifdef CONFIG_HL_SUPPORT 4422 /** 4423 * send_mgmt_cmd_tlv() - WMI scan start function 4424 * @wmi_handle: handle to WMI. 4425 * @param: pointer to hold mgmt cmd parameter 4426 * 4427 * Return: QDF_STATUS_SUCCESS for success or error code 4428 */ 4429 static QDF_STATUS send_mgmt_cmd_tlv(wmi_unified_t wmi_handle, 4430 struct wmi_mgmt_params *param) 4431 { 4432 wmi_buf_t buf; 4433 uint8_t *bufp; 4434 int32_t cmd_len; 4435 wmi_mgmt_tx_send_cmd_fixed_param *cmd; 4436 int32_t bufp_len = (param->frm_len < mgmt_tx_dl_frm_len) ? param->frm_len : 4437 mgmt_tx_dl_frm_len; 4438 4439 if (param->frm_len > mgmt_tx_dl_frm_len) { 4440 wmi_err("mgmt frame len %u exceeds %u", 4441 param->frm_len, mgmt_tx_dl_frm_len); 4442 return QDF_STATUS_E_INVAL; 4443 } 4444 4445 cmd_len = sizeof(wmi_mgmt_tx_send_cmd_fixed_param) + 4446 WMI_TLV_HDR_SIZE + 4447 roundup(bufp_len, sizeof(uint32_t)); 4448 4449 buf = wmi_buf_alloc(wmi_handle, sizeof(wmi_tx_send_params) + cmd_len); 4450 if (!buf) 4451 return QDF_STATUS_E_NOMEM; 4452 4453 cmd = (wmi_mgmt_tx_send_cmd_fixed_param *)wmi_buf_data(buf); 4454 bufp = (uint8_t *) cmd; 4455 WMITLV_SET_HDR(&cmd->tlv_header, 4456 WMITLV_TAG_STRUC_wmi_mgmt_tx_send_cmd_fixed_param, 4457 WMITLV_GET_STRUCT_TLVLEN 4458 (wmi_mgmt_tx_send_cmd_fixed_param)); 4459 4460 cmd->vdev_id = param->vdev_id; 4461 4462 cmd->desc_id = param->desc_id; 4463 cmd->chanfreq = param->chanfreq; 4464 bufp += sizeof(wmi_mgmt_tx_send_cmd_fixed_param); 4465 WMITLV_SET_HDR(bufp, WMITLV_TAG_ARRAY_BYTE, roundup(bufp_len, 4466 sizeof(uint32_t))); 4467 bufp += WMI_TLV_HDR_SIZE; 4468 qdf_mem_copy(bufp, param->pdata, bufp_len); 4469 4470 cmd->frame_len = param->frm_len; 4471 cmd->buf_len = bufp_len; 4472 cmd->tx_params_valid = param->tx_params_valid; 4473 cmd->tx_flags = param->tx_flags; 4474 cmd->peer_rssi = param->peer_rssi; 4475 4476 wmi_mgmt_cmd_record(wmi_handle, WMI_MGMT_TX_SEND_CMDID, 4477 bufp, cmd->vdev_id, cmd->chanfreq); 4478 4479 bufp += roundup(bufp_len, sizeof(uint32_t)); 4480 if (param->tx_params_valid) { 4481 if (populate_tx_send_params(bufp, param->tx_param) != 4482 QDF_STATUS_SUCCESS) { 4483 wmi_err("Populate TX send params failed"); 4484 goto free_buf; 4485 } 4486 cmd_len += sizeof(wmi_tx_send_params); 4487 } 4488 4489 wmi_mtrace(WMI_MGMT_TX_SEND_CMDID, cmd->vdev_id, 0); 4490 if (wmi_unified_cmd_send(wmi_handle, buf, cmd_len, 4491 WMI_MGMT_TX_SEND_CMDID)) { 4492 wmi_err("Failed to send mgmt Tx"); 4493 goto free_buf; 4494 } 4495 return QDF_STATUS_SUCCESS; 4496 4497 free_buf: 4498 wmi_buf_free(buf); 4499 return QDF_STATUS_E_FAILURE; 4500 } 4501 #else 4502 /** 4503 * send_mgmt_cmd_tlv() - WMI scan start function 4504 * @wmi_handle: handle to WMI. 4505 * @param: pointer to hold mgmt cmd parameter 4506 * 4507 * Return: QDF_STATUS_SUCCESS for success or error code 4508 */ 4509 static QDF_STATUS send_mgmt_cmd_tlv(wmi_unified_t wmi_handle, 4510 struct wmi_mgmt_params *param) 4511 { 4512 wmi_buf_t buf; 4513 wmi_mgmt_tx_send_cmd_fixed_param *cmd; 4514 int32_t cmd_len; 4515 uint64_t dma_addr; 4516 void *qdf_ctx = param->qdf_ctx; 4517 uint8_t *bufp; 4518 QDF_STATUS status = QDF_STATUS_SUCCESS; 4519 wmi_mlo_tx_send_params *mlo_params; 4520 int32_t bufp_len = (param->frm_len < mgmt_tx_dl_frm_len) ? param->frm_len : 4521 mgmt_tx_dl_frm_len; 4522 4523 cmd_len = sizeof(wmi_mgmt_tx_send_cmd_fixed_param) + 4524 WMI_TLV_HDR_SIZE + 4525 roundup(bufp_len, sizeof(uint32_t)); 4526 4527 buf = wmi_buf_alloc(wmi_handle, sizeof(wmi_tx_send_params) + cmd_len + 4528 WMI_TLV_HDR_SIZE + sizeof(wmi_mlo_tx_send_params)); 4529 if (!buf) 4530 return QDF_STATUS_E_NOMEM; 4531 4532 cmd = (wmi_mgmt_tx_send_cmd_fixed_param *)wmi_buf_data(buf); 4533 bufp = (uint8_t *) cmd; 4534 WMITLV_SET_HDR(&cmd->tlv_header, 4535 WMITLV_TAG_STRUC_wmi_mgmt_tx_send_cmd_fixed_param, 4536 WMITLV_GET_STRUCT_TLVLEN 4537 (wmi_mgmt_tx_send_cmd_fixed_param)); 4538 4539 cmd->vdev_id = param->vdev_id; 4540 4541 cmd->desc_id = param->desc_id; 4542 cmd->chanfreq = param->chanfreq; 4543 cmd->peer_rssi = param->peer_rssi; 4544 bufp += sizeof(wmi_mgmt_tx_send_cmd_fixed_param); 4545 WMITLV_SET_HDR(bufp, WMITLV_TAG_ARRAY_BYTE, roundup(bufp_len, 4546 sizeof(uint32_t))); 4547 bufp += WMI_TLV_HDR_SIZE; 4548 4549 /* for big endian host, copy engine byte_swap is enabled 4550 * But the frame content is in network byte order 4551 * Need to byte swap the frame content - so when copy engine 4552 * does byte_swap - target gets frame content in the correct order 4553 */ 4554 WMI_HOST_IF_MSG_COPY_CHAR_ARRAY(bufp, param->pdata, bufp_len); 4555 4556 status = qdf_nbuf_map_single(qdf_ctx, param->tx_frame, 4557 QDF_DMA_TO_DEVICE); 4558 if (status != QDF_STATUS_SUCCESS) { 4559 wmi_err("wmi buf map failed"); 4560 goto free_buf; 4561 } 4562 4563 dma_addr = qdf_nbuf_get_frag_paddr(param->tx_frame, 0); 4564 cmd->paddr_lo = (uint32_t)(dma_addr & 0xffffffff); 4565 #if defined(HTT_PADDR64) 4566 cmd->paddr_hi = (uint32_t)((dma_addr >> 32) & 0x1F); 4567 #endif 4568 cmd->frame_len = param->frm_len; 4569 cmd->buf_len = bufp_len; 4570 cmd->tx_params_valid = param->tx_params_valid; 4571 cmd->tx_flags = param->tx_flags; 4572 4573 wmi_mgmt_cmd_record(wmi_handle, WMI_MGMT_TX_SEND_CMDID, 4574 bufp, cmd->vdev_id, cmd->chanfreq); 4575 4576 bufp += roundup(bufp_len, sizeof(uint32_t)); 4577 if (param->tx_params_valid) { 4578 status = populate_tx_send_params(bufp, param->tx_param); 4579 if (status != QDF_STATUS_SUCCESS) { 4580 wmi_err("Populate TX send params failed"); 4581 goto unmap_tx_frame; 4582 } 4583 } else { 4584 WMITLV_SET_HDR(&((wmi_tx_send_params *)bufp)->tlv_header, 4585 WMITLV_TAG_STRUC_wmi_tx_send_params, 4586 WMITLV_GET_STRUCT_TLVLEN(wmi_tx_send_params)); 4587 } 4588 4589 /* Even tx_params_valid is false, still need reserve space to pass wmi 4590 * tag check */ 4591 cmd_len += sizeof(wmi_tx_send_params); 4592 bufp += sizeof(wmi_tx_send_params); 4593 /* wmi_mlo_tx_send_params */ 4594 if (param->mlo_link_agnostic) { 4595 wmi_debug("Set mlo mgmt tid"); 4596 WMITLV_SET_HDR(bufp, WMITLV_TAG_ARRAY_STRUC, 4597 sizeof(wmi_mlo_tx_send_params)); 4598 bufp += WMI_TLV_HDR_SIZE; 4599 mlo_params = (wmi_mlo_tx_send_params *)bufp; 4600 WMITLV_SET_HDR(&mlo_params->tlv_header, 4601 WMITLV_TAG_STRUC_wmi_mlo_tx_send_params, 4602 WMITLV_GET_STRUCT_TLVLEN(wmi_mlo_tx_send_params)); 4603 mlo_params->hw_link_id = WMI_MLO_MGMT_TID; 4604 cmd_len += WMI_TLV_HDR_SIZE + sizeof(wmi_mlo_tx_send_params); 4605 } 4606 4607 wmi_mtrace(WMI_MGMT_TX_SEND_CMDID, cmd->vdev_id, 0); 4608 if (wmi_unified_cmd_send(wmi_handle, buf, cmd_len, 4609 WMI_MGMT_TX_SEND_CMDID)) { 4610 wmi_err("Failed to send mgmt Tx"); 4611 goto unmap_tx_frame; 4612 } 4613 return QDF_STATUS_SUCCESS; 4614 4615 unmap_tx_frame: 4616 qdf_nbuf_unmap_single(qdf_ctx, param->tx_frame, 4617 QDF_DMA_TO_DEVICE); 4618 free_buf: 4619 wmi_buf_free(buf); 4620 return QDF_STATUS_E_FAILURE; 4621 } 4622 #endif /* CONFIG_HL_SUPPORT */ 4623 4624 /** 4625 * send_offchan_data_tx_cmd_tlv() - Send off-chan tx data 4626 * @wmi_handle: handle to WMI. 4627 * @param: pointer to offchan data tx cmd parameter 4628 * 4629 * Return: QDF_STATUS_SUCCESS on success and error on failure. 4630 */ 4631 static QDF_STATUS send_offchan_data_tx_cmd_tlv(wmi_unified_t wmi_handle, 4632 struct wmi_offchan_data_tx_params *param) 4633 { 4634 wmi_buf_t buf; 4635 wmi_offchan_data_tx_send_cmd_fixed_param *cmd; 4636 int32_t cmd_len; 4637 uint64_t dma_addr; 4638 void *qdf_ctx = param->qdf_ctx; 4639 uint8_t *bufp; 4640 int32_t bufp_len = (param->frm_len < mgmt_tx_dl_frm_len) ? 4641 param->frm_len : mgmt_tx_dl_frm_len; 4642 QDF_STATUS status = QDF_STATUS_SUCCESS; 4643 4644 cmd_len = sizeof(wmi_offchan_data_tx_send_cmd_fixed_param) + 4645 WMI_TLV_HDR_SIZE + 4646 roundup(bufp_len, sizeof(uint32_t)); 4647 4648 buf = wmi_buf_alloc(wmi_handle, sizeof(wmi_tx_send_params) + cmd_len); 4649 if (!buf) 4650 return QDF_STATUS_E_NOMEM; 4651 4652 cmd = (wmi_offchan_data_tx_send_cmd_fixed_param *) wmi_buf_data(buf); 4653 bufp = (uint8_t *) cmd; 4654 WMITLV_SET_HDR(&cmd->tlv_header, 4655 WMITLV_TAG_STRUC_wmi_offchan_data_tx_send_cmd_fixed_param, 4656 WMITLV_GET_STRUCT_TLVLEN 4657 (wmi_offchan_data_tx_send_cmd_fixed_param)); 4658 4659 cmd->vdev_id = param->vdev_id; 4660 4661 cmd->desc_id = param->desc_id; 4662 cmd->chanfreq = param->chanfreq; 4663 bufp += sizeof(wmi_offchan_data_tx_send_cmd_fixed_param); 4664 WMITLV_SET_HDR(bufp, WMITLV_TAG_ARRAY_BYTE, roundup(bufp_len, 4665 sizeof(uint32_t))); 4666 bufp += WMI_TLV_HDR_SIZE; 4667 qdf_mem_copy(bufp, param->pdata, bufp_len); 4668 qdf_nbuf_map_single(qdf_ctx, param->tx_frame, QDF_DMA_TO_DEVICE); 4669 dma_addr = qdf_nbuf_get_frag_paddr(param->tx_frame, 0); 4670 cmd->paddr_lo = (uint32_t)(dma_addr & 0xffffffff); 4671 #if defined(HTT_PADDR64) 4672 cmd->paddr_hi = (uint32_t)((dma_addr >> 32) & 0x1F); 4673 #endif 4674 cmd->frame_len = param->frm_len; 4675 cmd->buf_len = bufp_len; 4676 cmd->tx_params_valid = param->tx_params_valid; 4677 4678 wmi_mgmt_cmd_record(wmi_handle, WMI_OFFCHAN_DATA_TX_SEND_CMDID, 4679 bufp, cmd->vdev_id, cmd->chanfreq); 4680 4681 bufp += roundup(bufp_len, sizeof(uint32_t)); 4682 if (param->tx_params_valid) { 4683 status = populate_tx_send_params(bufp, param->tx_param); 4684 if (status != QDF_STATUS_SUCCESS) { 4685 wmi_err("Populate TX send params failed"); 4686 goto err1; 4687 } 4688 cmd_len += sizeof(wmi_tx_send_params); 4689 } 4690 4691 wmi_mtrace(WMI_OFFCHAN_DATA_TX_SEND_CMDID, cmd->vdev_id, 0); 4692 if (wmi_unified_cmd_send(wmi_handle, buf, cmd_len, 4693 WMI_OFFCHAN_DATA_TX_SEND_CMDID)) { 4694 wmi_err("Failed to offchan data Tx"); 4695 goto err1; 4696 } 4697 4698 return QDF_STATUS_SUCCESS; 4699 4700 err1: 4701 wmi_buf_free(buf); 4702 return QDF_STATUS_E_FAILURE; 4703 } 4704 4705 /** 4706 * send_modem_power_state_cmd_tlv() - set modem power state to fw 4707 * @wmi_handle: wmi handle 4708 * @param_value: parameter value 4709 * 4710 * Return: QDF_STATUS_SUCCESS for success or error code 4711 */ 4712 static QDF_STATUS send_modem_power_state_cmd_tlv(wmi_unified_t wmi_handle, 4713 uint32_t param_value) 4714 { 4715 QDF_STATUS ret; 4716 wmi_modem_power_state_cmd_param *cmd; 4717 wmi_buf_t buf; 4718 uint16_t len = sizeof(*cmd); 4719 4720 buf = wmi_buf_alloc(wmi_handle, len); 4721 if (!buf) 4722 return QDF_STATUS_E_NOMEM; 4723 4724 cmd = (wmi_modem_power_state_cmd_param *) wmi_buf_data(buf); 4725 WMITLV_SET_HDR(&cmd->tlv_header, 4726 WMITLV_TAG_STRUC_wmi_modem_power_state_cmd_param, 4727 WMITLV_GET_STRUCT_TLVLEN 4728 (wmi_modem_power_state_cmd_param)); 4729 cmd->modem_power_state = param_value; 4730 wmi_debug("Setting cmd->modem_power_state = %u", param_value); 4731 wmi_mtrace(WMI_MODEM_POWER_STATE_CMDID, NO_SESSION, 0); 4732 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 4733 WMI_MODEM_POWER_STATE_CMDID); 4734 if (QDF_IS_STATUS_ERROR(ret)) { 4735 wmi_err("Failed to send notify cmd ret = %d", ret); 4736 wmi_buf_free(buf); 4737 } 4738 4739 return ret; 4740 } 4741 4742 /** 4743 * send_set_sta_ps_mode_cmd_tlv() - set sta powersave mode in fw 4744 * @wmi_handle: wmi handle 4745 * @vdev_id: vdev id 4746 * @val: value 4747 * 4748 * Return: QDF_STATUS_SUCCESS for success or error code. 4749 */ 4750 static QDF_STATUS send_set_sta_ps_mode_cmd_tlv(wmi_unified_t wmi_handle, 4751 uint32_t vdev_id, uint8_t val) 4752 { 4753 wmi_sta_powersave_mode_cmd_fixed_param *cmd; 4754 wmi_buf_t buf; 4755 int32_t len = sizeof(*cmd); 4756 4757 wmi_debug("Set Sta Mode Ps vdevId %d val %d", vdev_id, val); 4758 4759 buf = wmi_buf_alloc(wmi_handle, len); 4760 if (!buf) 4761 return QDF_STATUS_E_NOMEM; 4762 4763 cmd = (wmi_sta_powersave_mode_cmd_fixed_param *) wmi_buf_data(buf); 4764 WMITLV_SET_HDR(&cmd->tlv_header, 4765 WMITLV_TAG_STRUC_wmi_sta_powersave_mode_cmd_fixed_param, 4766 WMITLV_GET_STRUCT_TLVLEN 4767 (wmi_sta_powersave_mode_cmd_fixed_param)); 4768 cmd->vdev_id = vdev_id; 4769 if (val) 4770 cmd->sta_ps_mode = WMI_STA_PS_MODE_ENABLED; 4771 else 4772 cmd->sta_ps_mode = WMI_STA_PS_MODE_DISABLED; 4773 4774 wmi_mtrace(WMI_STA_POWERSAVE_MODE_CMDID, cmd->vdev_id, 0); 4775 if (wmi_unified_cmd_send(wmi_handle, buf, len, 4776 WMI_STA_POWERSAVE_MODE_CMDID)) { 4777 wmi_err("Set Sta Mode Ps Failed vdevId %d val %d", 4778 vdev_id, val); 4779 wmi_buf_free(buf); 4780 return QDF_STATUS_E_FAILURE; 4781 } 4782 return QDF_STATUS_SUCCESS; 4783 } 4784 4785 /** 4786 * send_idle_roam_monitor_cmd_tlv() - send idle monitor command to fw 4787 * @wmi_handle: wmi handle 4788 * @val: non-zero to turn monitor on 4789 * 4790 * Return: QDF_STATUS_SUCCESS for success or error code. 4791 */ 4792 static QDF_STATUS send_idle_roam_monitor_cmd_tlv(wmi_unified_t wmi_handle, 4793 uint8_t val) 4794 { 4795 wmi_idle_trigger_monitor_cmd_fixed_param *cmd; 4796 wmi_buf_t buf; 4797 size_t len = sizeof(*cmd); 4798 4799 buf = wmi_buf_alloc(wmi_handle, len); 4800 if (!buf) 4801 return QDF_STATUS_E_NOMEM; 4802 4803 cmd = (wmi_idle_trigger_monitor_cmd_fixed_param *)wmi_buf_data(buf); 4804 WMITLV_SET_HDR(&cmd->tlv_header, 4805 WMITLV_TAG_STRUC_wmi_idle_trigger_monitor_cmd_fixed_param, 4806 WMITLV_GET_STRUCT_TLVLEN(wmi_idle_trigger_monitor_cmd_fixed_param)); 4807 4808 cmd->idle_trigger_monitor = (val ? WMI_IDLE_TRIGGER_MONITOR_ON : 4809 WMI_IDLE_TRIGGER_MONITOR_OFF); 4810 4811 wmi_debug("val: %d", cmd->idle_trigger_monitor); 4812 4813 if (wmi_unified_cmd_send(wmi_handle, buf, len, 4814 WMI_IDLE_TRIGGER_MONITOR_CMDID)) { 4815 wmi_buf_free(buf); 4816 return QDF_STATUS_E_FAILURE; 4817 } 4818 return QDF_STATUS_SUCCESS; 4819 } 4820 4821 /** 4822 * send_set_mimops_cmd_tlv() - set MIMO powersave 4823 * @wmi_handle: wmi handle 4824 * @vdev_id: vdev id 4825 * @value: value 4826 * 4827 * Return: QDF_STATUS_SUCCESS for success or error code. 4828 */ 4829 static QDF_STATUS send_set_mimops_cmd_tlv(wmi_unified_t wmi_handle, 4830 uint8_t vdev_id, int value) 4831 { 4832 QDF_STATUS ret; 4833 wmi_sta_smps_force_mode_cmd_fixed_param *cmd; 4834 wmi_buf_t buf; 4835 uint16_t len = sizeof(*cmd); 4836 4837 buf = wmi_buf_alloc(wmi_handle, len); 4838 if (!buf) 4839 return QDF_STATUS_E_NOMEM; 4840 4841 cmd = (wmi_sta_smps_force_mode_cmd_fixed_param *) wmi_buf_data(buf); 4842 WMITLV_SET_HDR(&cmd->tlv_header, 4843 WMITLV_TAG_STRUC_wmi_sta_smps_force_mode_cmd_fixed_param, 4844 WMITLV_GET_STRUCT_TLVLEN 4845 (wmi_sta_smps_force_mode_cmd_fixed_param)); 4846 4847 cmd->vdev_id = vdev_id; 4848 4849 /* WMI_SMPS_FORCED_MODE values do not directly map 4850 * to SM power save values defined in the specification. 4851 * Make sure to send the right mapping. 4852 */ 4853 switch (value) { 4854 case 0: 4855 cmd->forced_mode = WMI_SMPS_FORCED_MODE_NONE; 4856 break; 4857 case 1: 4858 cmd->forced_mode = WMI_SMPS_FORCED_MODE_DISABLED; 4859 break; 4860 case 2: 4861 cmd->forced_mode = WMI_SMPS_FORCED_MODE_STATIC; 4862 break; 4863 case 3: 4864 cmd->forced_mode = WMI_SMPS_FORCED_MODE_DYNAMIC; 4865 break; 4866 default: 4867 wmi_err("INVALID MIMO PS CONFIG: %d", value); 4868 wmi_buf_free(buf); 4869 return QDF_STATUS_E_FAILURE; 4870 } 4871 4872 wmi_debug("Setting vdev %d value = %u", vdev_id, value); 4873 4874 wmi_mtrace(WMI_STA_SMPS_FORCE_MODE_CMDID, cmd->vdev_id, 0); 4875 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 4876 WMI_STA_SMPS_FORCE_MODE_CMDID); 4877 if (QDF_IS_STATUS_ERROR(ret)) { 4878 wmi_err("Failed to send set Mimo PS ret = %d", ret); 4879 wmi_buf_free(buf); 4880 } 4881 4882 return ret; 4883 } 4884 4885 /** 4886 * send_set_smps_params_cmd_tlv() - set smps params 4887 * @wmi_handle: wmi handle 4888 * @vdev_id: vdev id 4889 * @value: value 4890 * 4891 * Return: QDF_STATUS_SUCCESS for success or error code. 4892 */ 4893 static QDF_STATUS send_set_smps_params_cmd_tlv(wmi_unified_t wmi_handle, uint8_t vdev_id, 4894 int value) 4895 { 4896 QDF_STATUS ret; 4897 wmi_sta_smps_param_cmd_fixed_param *cmd; 4898 wmi_buf_t buf; 4899 uint16_t len = sizeof(*cmd); 4900 4901 buf = wmi_buf_alloc(wmi_handle, len); 4902 if (!buf) 4903 return QDF_STATUS_E_NOMEM; 4904 4905 cmd = (wmi_sta_smps_param_cmd_fixed_param *) wmi_buf_data(buf); 4906 WMITLV_SET_HDR(&cmd->tlv_header, 4907 WMITLV_TAG_STRUC_wmi_sta_smps_param_cmd_fixed_param, 4908 WMITLV_GET_STRUCT_TLVLEN 4909 (wmi_sta_smps_param_cmd_fixed_param)); 4910 4911 cmd->vdev_id = vdev_id; 4912 cmd->value = value & WMI_SMPS_MASK_LOWER_16BITS; 4913 cmd->param = 4914 (value >> WMI_SMPS_PARAM_VALUE_S) & WMI_SMPS_MASK_UPPER_3BITS; 4915 4916 wmi_debug("Setting vdev %d value = %x param %x", vdev_id, cmd->value, 4917 cmd->param); 4918 4919 wmi_mtrace(WMI_STA_SMPS_PARAM_CMDID, cmd->vdev_id, 0); 4920 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 4921 WMI_STA_SMPS_PARAM_CMDID); 4922 if (QDF_IS_STATUS_ERROR(ret)) { 4923 wmi_err("Failed to send set Mimo PS ret = %d", ret); 4924 wmi_buf_free(buf); 4925 } 4926 4927 return ret; 4928 } 4929 4930 /** 4931 * send_get_temperature_cmd_tlv() - get pdev temperature req 4932 * @wmi_handle: wmi handle 4933 * 4934 * Return: QDF_STATUS_SUCCESS for success or error code. 4935 */ 4936 static QDF_STATUS send_get_temperature_cmd_tlv(wmi_unified_t wmi_handle) 4937 { 4938 wmi_pdev_get_temperature_cmd_fixed_param *cmd; 4939 wmi_buf_t wmi_buf; 4940 uint32_t len = sizeof(wmi_pdev_get_temperature_cmd_fixed_param); 4941 uint8_t *buf_ptr; 4942 4943 if (!wmi_handle) { 4944 wmi_err("WMI is closed, can not issue cmd"); 4945 return QDF_STATUS_E_INVAL; 4946 } 4947 4948 wmi_buf = wmi_buf_alloc(wmi_handle, len); 4949 if (!wmi_buf) 4950 return QDF_STATUS_E_NOMEM; 4951 4952 buf_ptr = (uint8_t *) wmi_buf_data(wmi_buf); 4953 4954 cmd = (wmi_pdev_get_temperature_cmd_fixed_param *) buf_ptr; 4955 WMITLV_SET_HDR(&cmd->tlv_header, 4956 WMITLV_TAG_STRUC_wmi_pdev_get_temperature_cmd_fixed_param, 4957 WMITLV_GET_STRUCT_TLVLEN 4958 (wmi_pdev_get_temperature_cmd_fixed_param)); 4959 4960 wmi_mtrace(WMI_PDEV_GET_TEMPERATURE_CMDID, NO_SESSION, 0); 4961 if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len, 4962 WMI_PDEV_GET_TEMPERATURE_CMDID)) { 4963 wmi_err("Failed to send get temperature command"); 4964 wmi_buf_free(wmi_buf); 4965 return QDF_STATUS_E_FAILURE; 4966 } 4967 4968 return QDF_STATUS_SUCCESS; 4969 } 4970 4971 /** 4972 * send_set_sta_uapsd_auto_trig_cmd_tlv() - set uapsd auto trigger command 4973 * @wmi_handle: wmi handle 4974 * @param: UAPSD trigger parameters 4975 * 4976 * This function sets the trigger 4977 * uapsd params such as service interval, delay interval 4978 * and suspend interval which will be used by the firmware 4979 * to send trigger frames periodically when there is no 4980 * traffic on the transmit side. 4981 * 4982 * Return: QDF_STATUS_SUCCESS for success or error code. 4983 */ 4984 static QDF_STATUS send_set_sta_uapsd_auto_trig_cmd_tlv(wmi_unified_t wmi_handle, 4985 struct sta_uapsd_trig_params *param) 4986 { 4987 wmi_sta_uapsd_auto_trig_cmd_fixed_param *cmd; 4988 QDF_STATUS ret; 4989 uint32_t param_len = param->num_ac * sizeof(wmi_sta_uapsd_auto_trig_param); 4990 uint32_t cmd_len = sizeof(*cmd) + param_len + WMI_TLV_HDR_SIZE; 4991 uint32_t i; 4992 wmi_buf_t buf; 4993 uint8_t *buf_ptr; 4994 struct sta_uapsd_params *uapsd_param; 4995 wmi_sta_uapsd_auto_trig_param *trig_param; 4996 4997 buf = wmi_buf_alloc(wmi_handle, cmd_len); 4998 if (!buf) 4999 return QDF_STATUS_E_NOMEM; 5000 5001 buf_ptr = (uint8_t *) wmi_buf_data(buf); 5002 cmd = (wmi_sta_uapsd_auto_trig_cmd_fixed_param *) buf_ptr; 5003 WMITLV_SET_HDR(&cmd->tlv_header, 5004 WMITLV_TAG_STRUC_wmi_sta_uapsd_auto_trig_cmd_fixed_param, 5005 WMITLV_GET_STRUCT_TLVLEN 5006 (wmi_sta_uapsd_auto_trig_cmd_fixed_param)); 5007 cmd->vdev_id = param->vdevid; 5008 cmd->num_ac = param->num_ac; 5009 WMI_CHAR_ARRAY_TO_MAC_ADDR(param->peer_addr, &cmd->peer_macaddr); 5010 5011 /* TLV indicating array of structures to follow */ 5012 buf_ptr += sizeof(*cmd); 5013 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, param_len); 5014 5015 buf_ptr += WMI_TLV_HDR_SIZE; 5016 5017 /* 5018 * Update tag and length for uapsd auto trigger params (this will take 5019 * care of updating tag and length if it is not pre-filled by caller). 5020 */ 5021 uapsd_param = (struct sta_uapsd_params *)param->auto_triggerparam; 5022 trig_param = (wmi_sta_uapsd_auto_trig_param *)buf_ptr; 5023 for (i = 0; i < param->num_ac; i++) { 5024 WMITLV_SET_HDR((buf_ptr + 5025 (i * sizeof(wmi_sta_uapsd_auto_trig_param))), 5026 WMITLV_TAG_STRUC_wmi_sta_uapsd_auto_trig_param, 5027 WMITLV_GET_STRUCT_TLVLEN 5028 (wmi_sta_uapsd_auto_trig_param)); 5029 trig_param->wmm_ac = uapsd_param->wmm_ac; 5030 trig_param->user_priority = uapsd_param->user_priority; 5031 trig_param->service_interval = uapsd_param->service_interval; 5032 trig_param->suspend_interval = uapsd_param->suspend_interval; 5033 trig_param->delay_interval = uapsd_param->delay_interval; 5034 trig_param++; 5035 uapsd_param++; 5036 } 5037 5038 wmi_mtrace(WMI_STA_UAPSD_AUTO_TRIG_CMDID, cmd->vdev_id, 0); 5039 ret = wmi_unified_cmd_send(wmi_handle, buf, cmd_len, 5040 WMI_STA_UAPSD_AUTO_TRIG_CMDID); 5041 if (QDF_IS_STATUS_ERROR(ret)) { 5042 wmi_err("Failed to send set uapsd param ret = %d", ret); 5043 wmi_buf_free(buf); 5044 } 5045 5046 return ret; 5047 } 5048 5049 /** 5050 * send_set_thermal_mgmt_cmd_tlv() - set thermal mgmt command to fw 5051 * @wmi_handle: Pointer to wmi handle 5052 * @thermal_info: Thermal command information 5053 * 5054 * This function sends the thermal management command 5055 * to the firmware 5056 * 5057 * Return: QDF_STATUS_SUCCESS for success otherwise failure 5058 */ 5059 static QDF_STATUS send_set_thermal_mgmt_cmd_tlv(wmi_unified_t wmi_handle, 5060 struct thermal_cmd_params *thermal_info) 5061 { 5062 wmi_thermal_mgmt_cmd_fixed_param *cmd = NULL; 5063 wmi_buf_t buf = NULL; 5064 QDF_STATUS status; 5065 uint32_t len = 0; 5066 uint8_t action; 5067 5068 switch (thermal_info->thermal_action) { 5069 case THERMAL_MGMT_ACTION_DEFAULT: 5070 action = WMI_THERMAL_MGMT_ACTION_DEFAULT; 5071 break; 5072 5073 case THERMAL_MGMT_ACTION_HALT_TRAFFIC: 5074 action = WMI_THERMAL_MGMT_ACTION_HALT_TRAFFIC; 5075 break; 5076 5077 case THERMAL_MGMT_ACTION_NOTIFY_HOST: 5078 action = WMI_THERMAL_MGMT_ACTION_NOTIFY_HOST; 5079 break; 5080 5081 case THERMAL_MGMT_ACTION_CHAINSCALING: 5082 action = WMI_THERMAL_MGMT_ACTION_CHAINSCALING; 5083 break; 5084 5085 default: 5086 wmi_err("Invalid thermal_action code %d", 5087 thermal_info->thermal_action); 5088 return QDF_STATUS_E_FAILURE; 5089 } 5090 5091 len = sizeof(*cmd); 5092 5093 buf = wmi_buf_alloc(wmi_handle, len); 5094 if (!buf) 5095 return QDF_STATUS_E_FAILURE; 5096 5097 cmd = (wmi_thermal_mgmt_cmd_fixed_param *) wmi_buf_data(buf); 5098 5099 WMITLV_SET_HDR(&cmd->tlv_header, 5100 WMITLV_TAG_STRUC_wmi_thermal_mgmt_cmd_fixed_param, 5101 WMITLV_GET_STRUCT_TLVLEN 5102 (wmi_thermal_mgmt_cmd_fixed_param)); 5103 5104 cmd->lower_thresh_degreeC = thermal_info->min_temp; 5105 cmd->upper_thresh_degreeC = thermal_info->max_temp; 5106 cmd->enable = thermal_info->thermal_enable; 5107 cmd->action = action; 5108 5109 wmi_debug("TM Sending thermal mgmt cmd: low temp %d, upper temp %d, enabled %d action %d", 5110 cmd->lower_thresh_degreeC, cmd->upper_thresh_degreeC, 5111 cmd->enable, cmd->action); 5112 5113 wmi_mtrace(WMI_THERMAL_MGMT_CMDID, NO_SESSION, 0); 5114 status = wmi_unified_cmd_send(wmi_handle, buf, len, 5115 WMI_THERMAL_MGMT_CMDID); 5116 if (QDF_IS_STATUS_ERROR(status)) { 5117 wmi_buf_free(buf); 5118 wmi_err("Failed to send thermal mgmt command"); 5119 } 5120 5121 return status; 5122 } 5123 5124 /** 5125 * send_lro_config_cmd_tlv() - process the LRO config command 5126 * @wmi_handle: Pointer to WMI handle 5127 * @wmi_lro_cmd: Pointer to LRO configuration parameters 5128 * 5129 * This function sends down the LRO configuration parameters to 5130 * the firmware to enable LRO, sets the TCP flags and sets the 5131 * seed values for the toeplitz hash generation 5132 * 5133 * Return: QDF_STATUS_SUCCESS for success otherwise failure 5134 */ 5135 static QDF_STATUS send_lro_config_cmd_tlv(wmi_unified_t wmi_handle, 5136 struct wmi_lro_config_cmd_t *wmi_lro_cmd) 5137 { 5138 wmi_lro_info_cmd_fixed_param *cmd; 5139 wmi_buf_t buf; 5140 QDF_STATUS status; 5141 uint8_t pdev_id = wmi_lro_cmd->pdev_id; 5142 5143 buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd)); 5144 if (!buf) 5145 return QDF_STATUS_E_FAILURE; 5146 5147 cmd = (wmi_lro_info_cmd_fixed_param *) wmi_buf_data(buf); 5148 5149 WMITLV_SET_HDR(&cmd->tlv_header, 5150 WMITLV_TAG_STRUC_wmi_lro_info_cmd_fixed_param, 5151 WMITLV_GET_STRUCT_TLVLEN(wmi_lro_info_cmd_fixed_param)); 5152 5153 cmd->lro_enable = wmi_lro_cmd->lro_enable; 5154 WMI_LRO_INFO_TCP_FLAG_VALS_SET(cmd->tcp_flag_u32, 5155 wmi_lro_cmd->tcp_flag); 5156 WMI_LRO_INFO_TCP_FLAGS_MASK_SET(cmd->tcp_flag_u32, 5157 wmi_lro_cmd->tcp_flag_mask); 5158 cmd->toeplitz_hash_ipv4_0_3 = 5159 wmi_lro_cmd->toeplitz_hash_ipv4[0]; 5160 cmd->toeplitz_hash_ipv4_4_7 = 5161 wmi_lro_cmd->toeplitz_hash_ipv4[1]; 5162 cmd->toeplitz_hash_ipv4_8_11 = 5163 wmi_lro_cmd->toeplitz_hash_ipv4[2]; 5164 cmd->toeplitz_hash_ipv4_12_15 = 5165 wmi_lro_cmd->toeplitz_hash_ipv4[3]; 5166 cmd->toeplitz_hash_ipv4_16 = 5167 wmi_lro_cmd->toeplitz_hash_ipv4[4]; 5168 5169 cmd->toeplitz_hash_ipv6_0_3 = 5170 wmi_lro_cmd->toeplitz_hash_ipv6[0]; 5171 cmd->toeplitz_hash_ipv6_4_7 = 5172 wmi_lro_cmd->toeplitz_hash_ipv6[1]; 5173 cmd->toeplitz_hash_ipv6_8_11 = 5174 wmi_lro_cmd->toeplitz_hash_ipv6[2]; 5175 cmd->toeplitz_hash_ipv6_12_15 = 5176 wmi_lro_cmd->toeplitz_hash_ipv6[3]; 5177 cmd->toeplitz_hash_ipv6_16_19 = 5178 wmi_lro_cmd->toeplitz_hash_ipv6[4]; 5179 cmd->toeplitz_hash_ipv6_20_23 = 5180 wmi_lro_cmd->toeplitz_hash_ipv6[5]; 5181 cmd->toeplitz_hash_ipv6_24_27 = 5182 wmi_lro_cmd->toeplitz_hash_ipv6[6]; 5183 cmd->toeplitz_hash_ipv6_28_31 = 5184 wmi_lro_cmd->toeplitz_hash_ipv6[7]; 5185 cmd->toeplitz_hash_ipv6_32_35 = 5186 wmi_lro_cmd->toeplitz_hash_ipv6[8]; 5187 cmd->toeplitz_hash_ipv6_36_39 = 5188 wmi_lro_cmd->toeplitz_hash_ipv6[9]; 5189 cmd->toeplitz_hash_ipv6_40 = 5190 wmi_lro_cmd->toeplitz_hash_ipv6[10]; 5191 5192 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 5193 wmi_handle, 5194 pdev_id); 5195 wmi_debug("WMI_LRO_CONFIG: lro_enable %d, tcp_flag 0x%x, pdev_id: %d", 5196 cmd->lro_enable, cmd->tcp_flag_u32, cmd->pdev_id); 5197 5198 wmi_mtrace(WMI_LRO_CONFIG_CMDID, NO_SESSION, 0); 5199 status = wmi_unified_cmd_send(wmi_handle, buf, 5200 sizeof(*cmd), WMI_LRO_CONFIG_CMDID); 5201 if (QDF_IS_STATUS_ERROR(status)) { 5202 wmi_buf_free(buf); 5203 wmi_err("Failed to send WMI_LRO_CONFIG_CMDID"); 5204 } 5205 5206 return status; 5207 } 5208 5209 /** 5210 * send_peer_rate_report_cmd_tlv() - process the peer rate report command 5211 * @wmi_handle: Pointer to wmi handle 5212 * @rate_report_params: Pointer to peer rate report parameters 5213 * 5214 * 5215 * Return: QDF_STATUS_SUCCESS for success otherwise failure 5216 */ 5217 static QDF_STATUS send_peer_rate_report_cmd_tlv(wmi_unified_t wmi_handle, 5218 struct wmi_peer_rate_report_params *rate_report_params) 5219 { 5220 wmi_peer_set_rate_report_condition_fixed_param *cmd = NULL; 5221 wmi_buf_t buf = NULL; 5222 QDF_STATUS status = 0; 5223 uint32_t len = 0; 5224 uint32_t i, j; 5225 5226 len = sizeof(*cmd); 5227 5228 buf = wmi_buf_alloc(wmi_handle, len); 5229 if (!buf) 5230 return QDF_STATUS_E_FAILURE; 5231 5232 cmd = (wmi_peer_set_rate_report_condition_fixed_param *) 5233 wmi_buf_data(buf); 5234 5235 WMITLV_SET_HDR( 5236 &cmd->tlv_header, 5237 WMITLV_TAG_STRUC_wmi_peer_set_rate_report_condition_fixed_param, 5238 WMITLV_GET_STRUCT_TLVLEN( 5239 wmi_peer_set_rate_report_condition_fixed_param)); 5240 5241 cmd->enable_rate_report = rate_report_params->rate_report_enable; 5242 cmd->report_backoff_time = rate_report_params->backoff_time; 5243 cmd->report_timer_period = rate_report_params->timer_period; 5244 for (i = 0; i < PEER_RATE_REPORT_COND_MAX_NUM; i++) { 5245 cmd->cond_per_phy[i].val_cond_flags = 5246 rate_report_params->report_per_phy[i].cond_flags; 5247 cmd->cond_per_phy[i].rate_delta.min_delta = 5248 rate_report_params->report_per_phy[i].delta.delta_min; 5249 cmd->cond_per_phy[i].rate_delta.percentage = 5250 rate_report_params->report_per_phy[i].delta.percent; 5251 for (j = 0; j < MAX_NUM_OF_RATE_THRESH; j++) { 5252 cmd->cond_per_phy[i].rate_threshold[j] = 5253 rate_report_params->report_per_phy[i]. 5254 report_rate_threshold[j]; 5255 } 5256 } 5257 5258 wmi_debug("enable %d backoff_time %d period %d", 5259 cmd->enable_rate_report, 5260 cmd->report_backoff_time, cmd->report_timer_period); 5261 5262 wmi_mtrace(WMI_PEER_SET_RATE_REPORT_CONDITION_CMDID, NO_SESSION, 0); 5263 status = wmi_unified_cmd_send(wmi_handle, buf, len, 5264 WMI_PEER_SET_RATE_REPORT_CONDITION_CMDID); 5265 if (QDF_IS_STATUS_ERROR(status)) { 5266 wmi_buf_free(buf); 5267 wmi_err("Failed to send peer_set_report_cond command"); 5268 } 5269 return status; 5270 } 5271 5272 /** 5273 * send_process_update_edca_param_cmd_tlv() - update EDCA params 5274 * @wmi_handle: wmi handle 5275 * @vdev_id: vdev id. 5276 * @mu_edca_param: true if these are MU EDCA params 5277 * @wmm_vparams: edca parameters 5278 * 5279 * This function updates EDCA parameters to the target 5280 * 5281 * Return: CDF Status 5282 */ 5283 static QDF_STATUS send_process_update_edca_param_cmd_tlv(wmi_unified_t wmi_handle, 5284 uint8_t vdev_id, bool mu_edca_param, 5285 struct wmi_host_wme_vparams wmm_vparams[WMI_MAX_NUM_AC]) 5286 { 5287 uint8_t *buf_ptr; 5288 wmi_buf_t buf; 5289 wmi_vdev_set_wmm_params_cmd_fixed_param *cmd; 5290 wmi_wmm_vparams *wmm_param; 5291 struct wmi_host_wme_vparams *twmm_param; 5292 int len = sizeof(*cmd); 5293 int ac; 5294 5295 buf = wmi_buf_alloc(wmi_handle, len); 5296 5297 if (!buf) 5298 return QDF_STATUS_E_NOMEM; 5299 5300 buf_ptr = (uint8_t *) wmi_buf_data(buf); 5301 cmd = (wmi_vdev_set_wmm_params_cmd_fixed_param *) buf_ptr; 5302 WMITLV_SET_HDR(&cmd->tlv_header, 5303 WMITLV_TAG_STRUC_wmi_vdev_set_wmm_params_cmd_fixed_param, 5304 WMITLV_GET_STRUCT_TLVLEN 5305 (wmi_vdev_set_wmm_params_cmd_fixed_param)); 5306 cmd->vdev_id = vdev_id; 5307 cmd->wmm_param_type = mu_edca_param; 5308 5309 for (ac = 0; ac < WMI_MAX_NUM_AC; ac++) { 5310 wmm_param = (wmi_wmm_vparams *) (&cmd->wmm_params[ac]); 5311 twmm_param = (struct wmi_host_wme_vparams *) (&wmm_vparams[ac]); 5312 WMITLV_SET_HDR(&wmm_param->tlv_header, 5313 WMITLV_TAG_STRUC_wmi_vdev_set_wmm_params_cmd_fixed_param, 5314 WMITLV_GET_STRUCT_TLVLEN(wmi_wmm_vparams)); 5315 wmm_param->cwmin = twmm_param->cwmin; 5316 wmm_param->cwmax = twmm_param->cwmax; 5317 wmm_param->aifs = twmm_param->aifs; 5318 if (mu_edca_param) 5319 wmm_param->mu_edca_timer = twmm_param->mu_edca_timer; 5320 else 5321 wmm_param->txoplimit = twmm_param->txoplimit; 5322 wmm_param->acm = twmm_param->acm; 5323 wmm_param->no_ack = twmm_param->noackpolicy; 5324 } 5325 5326 wmi_mtrace(WMI_VDEV_SET_WMM_PARAMS_CMDID, cmd->vdev_id, 0); 5327 if (wmi_unified_cmd_send(wmi_handle, buf, len, 5328 WMI_VDEV_SET_WMM_PARAMS_CMDID)) 5329 goto fail; 5330 5331 return QDF_STATUS_SUCCESS; 5332 5333 fail: 5334 wmi_buf_free(buf); 5335 wmi_err("Failed to set WMM Parameters"); 5336 return QDF_STATUS_E_FAILURE; 5337 } 5338 5339 static WMI_EDCA_PARAM_TYPE 5340 wmi_convert_edca_pifs_param_type(enum host_edca_param_type type) 5341 { 5342 switch (type) { 5343 case HOST_EDCA_PARAM_TYPE_AGGRESSIVE: 5344 return WMI_EDCA_PARAM_TYPE_AGGRESSIVE; 5345 case HOST_EDCA_PARAM_TYPE_PIFS: 5346 return WMI_EDCA_PARAM_TYPE_PIFS; 5347 default: 5348 return WMI_EDCA_PARAM_TYPE_AGGRESSIVE; 5349 } 5350 } 5351 5352 /** 5353 * send_update_edca_pifs_param_cmd_tlv() - update EDCA params 5354 * @wmi_handle: wmi handle 5355 * @edca_pifs: edca/pifs parameters 5356 * 5357 * This function updates EDCA/PIFS parameters to the target 5358 * 5359 * Return: QDF Status 5360 */ 5361 5362 static QDF_STATUS 5363 send_update_edca_pifs_param_cmd_tlv(wmi_unified_t wmi_handle, 5364 struct edca_pifs_vparam *edca_pifs) 5365 { 5366 uint8_t *buf_ptr; 5367 wmi_buf_t buf = NULL; 5368 wmi_vdev_set_twt_edca_params_cmd_fixed_param *cmd; 5369 wmi_wmm_params *wmm_params; 5370 wmi_pifs_params *pifs_params; 5371 uint16_t len; 5372 5373 if (!edca_pifs) { 5374 wmi_debug("edca_pifs is NULL"); 5375 return QDF_STATUS_E_FAILURE; 5376 } 5377 5378 len = sizeof(wmi_vdev_set_twt_edca_params_cmd_fixed_param); 5379 if (edca_pifs->param.edca_param_type == 5380 HOST_EDCA_PARAM_TYPE_AGGRESSIVE) { 5381 len += WMI_TLV_HDR_SIZE; 5382 len += sizeof(wmi_wmm_params); 5383 } else { 5384 len += WMI_TLV_HDR_SIZE; 5385 } 5386 if (edca_pifs->param.edca_param_type == 5387 HOST_EDCA_PARAM_TYPE_PIFS) { 5388 len += WMI_TLV_HDR_SIZE; 5389 len += sizeof(wmi_pifs_params); 5390 } else { 5391 len += WMI_TLV_HDR_SIZE; 5392 } 5393 5394 buf = wmi_buf_alloc(wmi_handle, len); 5395 5396 if (!buf) 5397 return QDF_STATUS_E_NOMEM; 5398 5399 cmd = (wmi_vdev_set_twt_edca_params_cmd_fixed_param *)wmi_buf_data(buf); 5400 buf_ptr = (uint8_t *)cmd; 5401 5402 WMITLV_SET_HDR(&cmd->tlv_header, 5403 WMITLV_TAG_STRUC_wmi_vdev_set_twt_edca_params_cmd_fixed_param, 5404 WMITLV_GET_STRUCT_TLVLEN 5405 (wmi_vdev_set_twt_edca_params_cmd_fixed_param)); 5406 5407 cmd->vdev_id = edca_pifs->vdev_id; 5408 cmd->type = wmi_convert_edca_pifs_param_type( 5409 edca_pifs->param.edca_param_type); 5410 buf_ptr += sizeof(wmi_vdev_set_twt_edca_params_cmd_fixed_param); 5411 5412 if (cmd->type == WMI_EDCA_PARAM_TYPE_AGGRESSIVE) { 5413 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 5414 sizeof(*wmm_params)); 5415 buf_ptr += WMI_TLV_HDR_SIZE; 5416 wmm_params = (wmi_wmm_params *)buf_ptr; 5417 WMITLV_SET_HDR(&wmm_params->tlv_header, 5418 WMITLV_TAG_STRUC_wmi_wmm_params, 5419 WMITLV_GET_STRUCT_TLVLEN(wmi_wmm_params)); 5420 5421 wmm_params->cwmin = 5422 BIT(edca_pifs->param.edca_pifs_param.eparam.acvo_cwmin) - 1; 5423 wmm_params->cwmax = 5424 BIT(edca_pifs->param.edca_pifs_param.eparam.acvo_cwmax) - 1; 5425 wmm_params->aifs = 5426 edca_pifs->param.edca_pifs_param.eparam.acvo_aifsn - 1; 5427 wmm_params->txoplimit = 5428 edca_pifs->param.edca_pifs_param.eparam.acvo_txoplimit; 5429 wmm_params->acm = 5430 edca_pifs->param.edca_pifs_param.eparam.acvo_acm; 5431 wmm_params->no_ack = 0; 5432 wmi_debug("vdev_id %d type %d cwmin %d cwmax %d aifsn %d txoplimit %d acm %d no_ack %d", 5433 cmd->vdev_id, cmd->type, wmm_params->cwmin, 5434 wmm_params->cwmax, wmm_params->aifs, 5435 wmm_params->txoplimit, wmm_params->acm, 5436 wmm_params->no_ack); 5437 buf_ptr += sizeof(*wmm_params); 5438 } else { 5439 /* set zero TLV's for wmm_params */ 5440 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 5441 WMITLV_GET_STRUCT_TLVLEN(0)); 5442 buf_ptr += WMI_TLV_HDR_SIZE; 5443 } 5444 if (cmd->type == WMI_EDCA_PARAM_TYPE_PIFS) { 5445 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 5446 sizeof(*pifs_params)); 5447 buf_ptr += WMI_TLV_HDR_SIZE; 5448 pifs_params = (wmi_pifs_params *)buf_ptr; 5449 WMITLV_SET_HDR(&pifs_params->tlv_header, 5450 WMITLV_TAG_STRUC_wmi_pifs_params, 5451 WMITLV_GET_STRUCT_TLVLEN(wmi_pifs_params)); 5452 5453 pifs_params->sap_pifs_offset = 5454 edca_pifs->param.edca_pifs_param.pparam.sap_pifs_offset; 5455 pifs_params->leb_pifs_offset = 5456 edca_pifs->param.edca_pifs_param.pparam.leb_pifs_offset; 5457 pifs_params->reb_pifs_offset = 5458 edca_pifs->param.edca_pifs_param.pparam.reb_pifs_offset; 5459 wmi_debug("vdev_id %d type %d sap_offset %d leb_offset %d reb_offset %d", 5460 cmd->vdev_id, cmd->type, pifs_params->sap_pifs_offset, 5461 pifs_params->leb_pifs_offset, 5462 pifs_params->reb_pifs_offset); 5463 } else { 5464 /* set zero TLV's for pifs_params */ 5465 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 5466 WMITLV_GET_STRUCT_TLVLEN(0)); 5467 buf_ptr += WMI_TLV_HDR_SIZE; 5468 } 5469 5470 wmi_mtrace(WMI_VDEV_SET_TWT_EDCA_PARAMS_CMDID, cmd->vdev_id, 0); 5471 if (wmi_unified_cmd_send(wmi_handle, buf, len, 5472 WMI_VDEV_SET_TWT_EDCA_PARAMS_CMDID)) 5473 goto fail; 5474 5475 return QDF_STATUS_SUCCESS; 5476 5477 fail: 5478 wmi_buf_free(buf); 5479 wmi_err("Failed to set EDCA/PIFS Parameters"); 5480 return QDF_STATUS_E_FAILURE; 5481 } 5482 5483 /** 5484 * send_probe_rsp_tmpl_send_cmd_tlv() - send probe response template to fw 5485 * @wmi_handle: wmi handle 5486 * @vdev_id: vdev id 5487 * @probe_rsp_info: probe response info 5488 * 5489 * Return: QDF_STATUS_SUCCESS for success or error code 5490 */ 5491 static QDF_STATUS send_probe_rsp_tmpl_send_cmd_tlv(wmi_unified_t wmi_handle, 5492 uint8_t vdev_id, 5493 struct wmi_probe_resp_params *probe_rsp_info) 5494 { 5495 wmi_prb_tmpl_cmd_fixed_param *cmd; 5496 wmi_bcn_prb_info *bcn_prb_info; 5497 wmi_buf_t wmi_buf; 5498 uint32_t tmpl_len, tmpl_len_aligned, wmi_buf_len; 5499 uint8_t *buf_ptr; 5500 QDF_STATUS ret; 5501 5502 wmi_debug("Send probe response template for vdev %d", vdev_id); 5503 5504 tmpl_len = probe_rsp_info->prb_rsp_template_len; 5505 tmpl_len_aligned = roundup(tmpl_len, sizeof(uint32_t)); 5506 5507 wmi_buf_len = sizeof(wmi_prb_tmpl_cmd_fixed_param) + 5508 sizeof(wmi_bcn_prb_info) + WMI_TLV_HDR_SIZE + 5509 tmpl_len_aligned + 5510 prb_resp_tmpl_ml_info_size(probe_rsp_info); 5511 5512 if (wmi_buf_len > WMI_BEACON_TX_BUFFER_SIZE) { 5513 wmi_err("wmi_buf_len: %d > %d. Can't send wmi cmd", 5514 wmi_buf_len, WMI_BEACON_TX_BUFFER_SIZE); 5515 return QDF_STATUS_E_INVAL; 5516 } 5517 5518 wmi_buf = wmi_buf_alloc(wmi_handle, wmi_buf_len); 5519 if (!wmi_buf) 5520 return QDF_STATUS_E_NOMEM; 5521 5522 buf_ptr = (uint8_t *) wmi_buf_data(wmi_buf); 5523 5524 cmd = (wmi_prb_tmpl_cmd_fixed_param *) buf_ptr; 5525 WMITLV_SET_HDR(&cmd->tlv_header, 5526 WMITLV_TAG_STRUC_wmi_prb_tmpl_cmd_fixed_param, 5527 WMITLV_GET_STRUCT_TLVLEN(wmi_prb_tmpl_cmd_fixed_param)); 5528 cmd->vdev_id = vdev_id; 5529 cmd->buf_len = tmpl_len; 5530 buf_ptr += sizeof(wmi_prb_tmpl_cmd_fixed_param); 5531 5532 bcn_prb_info = (wmi_bcn_prb_info *) buf_ptr; 5533 WMITLV_SET_HDR(&bcn_prb_info->tlv_header, 5534 WMITLV_TAG_STRUC_wmi_bcn_prb_info, 5535 WMITLV_GET_STRUCT_TLVLEN(wmi_bcn_prb_info)); 5536 bcn_prb_info->caps = 0; 5537 bcn_prb_info->erp = 0; 5538 buf_ptr += sizeof(wmi_bcn_prb_info); 5539 5540 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, tmpl_len_aligned); 5541 buf_ptr += WMI_TLV_HDR_SIZE; 5542 qdf_mem_copy(buf_ptr, probe_rsp_info->prb_rsp_template_frm, tmpl_len); 5543 buf_ptr += tmpl_len_aligned; 5544 buf_ptr = prb_resp_tmpl_add_ml_info(buf_ptr, probe_rsp_info); 5545 5546 wmi_mtrace(WMI_PRB_TMPL_CMDID, cmd->vdev_id, 0); 5547 ret = wmi_unified_cmd_send(wmi_handle, 5548 wmi_buf, wmi_buf_len, WMI_PRB_TMPL_CMDID); 5549 if (QDF_IS_STATUS_ERROR(ret)) { 5550 wmi_err("Failed to send PRB RSP tmpl: %d", ret); 5551 wmi_buf_free(wmi_buf); 5552 } 5553 5554 return ret; 5555 } 5556 5557 #if defined(ATH_SUPPORT_WAPI) || defined(FEATURE_WLAN_WAPI) 5558 #define WPI_IV_LEN 16 5559 5560 /** 5561 * wmi_update_wpi_key_counter() - update WAPI tsc and rsc key counters 5562 * 5563 * @dest_tx: destination address of tsc key counter 5564 * @src_tx: source address of tsc key counter 5565 * @dest_rx: destination address of rsc key counter 5566 * @src_rx: source address of rsc key counter 5567 * 5568 * This function copies WAPI tsc and rsc key counters in the wmi buffer. 5569 * 5570 * Return: None 5571 * 5572 */ 5573 static void wmi_update_wpi_key_counter(uint8_t *dest_tx, uint8_t *src_tx, 5574 uint8_t *dest_rx, uint8_t *src_rx) 5575 { 5576 qdf_mem_copy(dest_tx, src_tx, WPI_IV_LEN); 5577 qdf_mem_copy(dest_rx, src_rx, WPI_IV_LEN); 5578 } 5579 #else 5580 static void wmi_update_wpi_key_counter(uint8_t *dest_tx, uint8_t *src_tx, 5581 uint8_t *dest_rx, uint8_t *src_rx) 5582 { 5583 return; 5584 } 5585 #endif 5586 5587 /** 5588 * send_setup_install_key_cmd_tlv() - set key parameters 5589 * @wmi_handle: wmi handle 5590 * @key_params: key parameters 5591 * 5592 * This function fills structure from information 5593 * passed in key_params. 5594 * 5595 * Return: QDF_STATUS_SUCCESS - success 5596 * QDF_STATUS_E_FAILURE - failure 5597 * QDF_STATUS_E_NOMEM - not able to allocate buffer 5598 */ 5599 static QDF_STATUS send_setup_install_key_cmd_tlv(wmi_unified_t wmi_handle, 5600 struct set_key_params *key_params) 5601 { 5602 wmi_vdev_install_key_cmd_fixed_param *cmd; 5603 wmi_buf_t buf; 5604 uint8_t *buf_ptr; 5605 uint32_t len; 5606 uint8_t *key_data; 5607 QDF_STATUS status; 5608 5609 len = sizeof(*cmd) + roundup(key_params->key_len, sizeof(uint32_t)) + 5610 WMI_TLV_HDR_SIZE; 5611 5612 buf = wmi_buf_alloc(wmi_handle, len); 5613 if (!buf) 5614 return QDF_STATUS_E_NOMEM; 5615 5616 buf_ptr = (uint8_t *) wmi_buf_data(buf); 5617 cmd = (wmi_vdev_install_key_cmd_fixed_param *) buf_ptr; 5618 WMITLV_SET_HDR(&cmd->tlv_header, 5619 WMITLV_TAG_STRUC_wmi_vdev_install_key_cmd_fixed_param, 5620 WMITLV_GET_STRUCT_TLVLEN 5621 (wmi_vdev_install_key_cmd_fixed_param)); 5622 cmd->vdev_id = key_params->vdev_id; 5623 cmd->key_ix = key_params->key_idx; 5624 if (key_params->group_key_idx) { 5625 cmd->is_group_key_ix_valid = 1; 5626 cmd->group_key_ix = key_params->group_key_idx; 5627 } 5628 5629 WMI_CHAR_ARRAY_TO_MAC_ADDR(key_params->peer_mac, &cmd->peer_macaddr); 5630 cmd->key_flags |= key_params->key_flags; 5631 cmd->key_cipher = key_params->key_cipher; 5632 if ((key_params->key_txmic_len) && 5633 (key_params->key_rxmic_len)) { 5634 cmd->key_txmic_len = key_params->key_txmic_len; 5635 cmd->key_rxmic_len = key_params->key_rxmic_len; 5636 } 5637 #if defined(ATH_SUPPORT_WAPI) || defined(FEATURE_WLAN_WAPI) 5638 wmi_update_wpi_key_counter(cmd->wpi_key_tsc_counter, 5639 key_params->tx_iv, 5640 cmd->wpi_key_rsc_counter, 5641 key_params->rx_iv); 5642 #endif 5643 buf_ptr += sizeof(wmi_vdev_install_key_cmd_fixed_param); 5644 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, 5645 roundup(key_params->key_len, sizeof(uint32_t))); 5646 key_data = (uint8_t *) (buf_ptr + WMI_TLV_HDR_SIZE); 5647 5648 /* for big endian host, copy engine byte_swap is enabled 5649 * But key_data is in network byte order 5650 * Need to byte swap the key_data - so when copy engine 5651 * does byte_swap - target gets key_data in the correct order 5652 */ 5653 WMI_HOST_IF_MSG_COPY_CHAR_ARRAY((void *)key_data, 5654 (const void *)key_params->key_data, 5655 key_params->key_len); 5656 qdf_mem_copy(&cmd->key_rsc_counter, &key_params->key_rsc_counter, 5657 sizeof(wmi_key_seq_counter)); 5658 cmd->key_len = key_params->key_len; 5659 5660 qdf_mem_copy(&cmd->key_tsc_counter, &key_params->key_tsc_counter, 5661 sizeof(wmi_key_seq_counter)); 5662 wmi_mtrace(WMI_VDEV_INSTALL_KEY_CMDID, cmd->vdev_id, 0); 5663 status = wmi_unified_cmd_send(wmi_handle, buf, len, 5664 WMI_VDEV_INSTALL_KEY_CMDID); 5665 if (QDF_IS_STATUS_ERROR(status)) { 5666 qdf_mem_zero(wmi_buf_data(buf), len); 5667 wmi_buf_free(buf); 5668 } 5669 return status; 5670 } 5671 5672 /** 5673 * send_p2p_go_set_beacon_ie_cmd_tlv() - set beacon IE for p2p go 5674 * @wmi_handle: wmi handle 5675 * @vdev_id: vdev id 5676 * @p2p_ie: p2p IE 5677 * 5678 * Return: QDF_STATUS_SUCCESS for success or error code 5679 */ 5680 static QDF_STATUS send_p2p_go_set_beacon_ie_cmd_tlv(wmi_unified_t wmi_handle, 5681 uint32_t vdev_id, uint8_t *p2p_ie) 5682 { 5683 QDF_STATUS ret; 5684 wmi_p2p_go_set_beacon_ie_fixed_param *cmd; 5685 wmi_buf_t wmi_buf; 5686 uint32_t ie_len, ie_len_aligned, wmi_buf_len; 5687 uint8_t *buf_ptr; 5688 5689 ie_len = (uint32_t) (p2p_ie[1] + 2); 5690 5691 /* More than one P2P IE may be included in a single frame. 5692 If multiple P2P IEs are present, the complete P2P attribute 5693 data consists of the concatenation of the P2P Attribute 5694 fields of the P2P IEs. The P2P Attributes field of each 5695 P2P IE may be any length up to the maximum (251 octets). 5696 In this case host sends one P2P IE to firmware so the length 5697 should not exceed more than 251 bytes 5698 */ 5699 if (ie_len > 251) { 5700 wmi_err("Invalid p2p ie length %u", ie_len); 5701 return QDF_STATUS_E_INVAL; 5702 } 5703 5704 ie_len_aligned = roundup(ie_len, sizeof(uint32_t)); 5705 5706 wmi_buf_len = 5707 sizeof(wmi_p2p_go_set_beacon_ie_fixed_param) + ie_len_aligned + 5708 WMI_TLV_HDR_SIZE; 5709 5710 wmi_buf = wmi_buf_alloc(wmi_handle, wmi_buf_len); 5711 if (!wmi_buf) 5712 return QDF_STATUS_E_NOMEM; 5713 5714 buf_ptr = (uint8_t *) wmi_buf_data(wmi_buf); 5715 5716 cmd = (wmi_p2p_go_set_beacon_ie_fixed_param *) buf_ptr; 5717 WMITLV_SET_HDR(&cmd->tlv_header, 5718 WMITLV_TAG_STRUC_wmi_p2p_go_set_beacon_ie_fixed_param, 5719 WMITLV_GET_STRUCT_TLVLEN 5720 (wmi_p2p_go_set_beacon_ie_fixed_param)); 5721 cmd->vdev_id = vdev_id; 5722 cmd->ie_buf_len = ie_len; 5723 5724 buf_ptr += sizeof(wmi_p2p_go_set_beacon_ie_fixed_param); 5725 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, ie_len_aligned); 5726 buf_ptr += WMI_TLV_HDR_SIZE; 5727 qdf_mem_copy(buf_ptr, p2p_ie, ie_len); 5728 5729 wmi_debug("Sending WMI_P2P_GO_SET_BEACON_IE"); 5730 5731 wmi_mtrace(WMI_P2P_GO_SET_BEACON_IE, cmd->vdev_id, 0); 5732 ret = wmi_unified_cmd_send(wmi_handle, 5733 wmi_buf, wmi_buf_len, 5734 WMI_P2P_GO_SET_BEACON_IE); 5735 if (QDF_IS_STATUS_ERROR(ret)) { 5736 wmi_err("Failed to send bcn tmpl: %d", ret); 5737 wmi_buf_free(wmi_buf); 5738 } 5739 5740 wmi_debug("Successfully sent WMI_P2P_GO_SET_BEACON_IE"); 5741 return ret; 5742 } 5743 5744 /** 5745 * send_scan_probe_setoui_cmd_tlv() - set scan probe OUI 5746 * @wmi_handle: wmi handle 5747 * @psetoui: OUI parameters 5748 * 5749 * set scan probe OUI parameters in firmware 5750 * 5751 * Return: QDF status 5752 */ 5753 static QDF_STATUS send_scan_probe_setoui_cmd_tlv(wmi_unified_t wmi_handle, 5754 struct scan_mac_oui *psetoui) 5755 { 5756 wmi_scan_prob_req_oui_cmd_fixed_param *cmd; 5757 wmi_buf_t wmi_buf; 5758 uint32_t len; 5759 uint8_t *buf_ptr; 5760 uint32_t *oui_buf; 5761 struct probe_req_allowlist_attr *ie_allowlist = &psetoui->ie_allowlist; 5762 5763 len = sizeof(*cmd) + WMI_TLV_HDR_SIZE + 5764 ie_allowlist->num_vendor_oui * sizeof(wmi_vendor_oui); 5765 5766 wmi_buf = wmi_buf_alloc(wmi_handle, len); 5767 if (!wmi_buf) 5768 return QDF_STATUS_E_NOMEM; 5769 5770 buf_ptr = (uint8_t *) wmi_buf_data(wmi_buf); 5771 cmd = (wmi_scan_prob_req_oui_cmd_fixed_param *) buf_ptr; 5772 WMITLV_SET_HDR(&cmd->tlv_header, 5773 WMITLV_TAG_STRUC_wmi_scan_prob_req_oui_cmd_fixed_param, 5774 WMITLV_GET_STRUCT_TLVLEN 5775 (wmi_scan_prob_req_oui_cmd_fixed_param)); 5776 5777 oui_buf = &cmd->prob_req_oui; 5778 qdf_mem_zero(oui_buf, sizeof(cmd->prob_req_oui)); 5779 *oui_buf = psetoui->oui[0] << 16 | psetoui->oui[1] << 8 5780 | psetoui->oui[2]; 5781 wmi_debug("wmi:oui received from hdd %08x", cmd->prob_req_oui); 5782 5783 cmd->vdev_id = psetoui->vdev_id; 5784 cmd->flags = WMI_SCAN_PROBE_OUI_SPOOFED_MAC_IN_PROBE_REQ; 5785 if (psetoui->enb_probe_req_sno_randomization) 5786 cmd->flags |= WMI_SCAN_PROBE_OUI_RANDOM_SEQ_NO_IN_PROBE_REQ; 5787 5788 if (ie_allowlist->allow_list) { 5789 wmi_fill_ie_allowlist_attrs(cmd->ie_bitmap, 5790 &cmd->num_vendor_oui, 5791 ie_allowlist); 5792 cmd->flags |= 5793 WMI_SCAN_PROBE_OUI_ENABLE_IE_WHITELIST_IN_PROBE_REQ; 5794 } 5795 5796 buf_ptr += sizeof(*cmd); 5797 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 5798 ie_allowlist->num_vendor_oui * sizeof(wmi_vendor_oui)); 5799 buf_ptr += WMI_TLV_HDR_SIZE; 5800 5801 if (cmd->num_vendor_oui != 0) { 5802 wmi_fill_vendor_oui(buf_ptr, cmd->num_vendor_oui, 5803 ie_allowlist->voui); 5804 buf_ptr += cmd->num_vendor_oui * sizeof(wmi_vendor_oui); 5805 } 5806 5807 wmi_mtrace(WMI_SCAN_PROB_REQ_OUI_CMDID, cmd->vdev_id, 0); 5808 if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len, 5809 WMI_SCAN_PROB_REQ_OUI_CMDID)) { 5810 wmi_err("Failed to send command WMI_SCAN_PROB_REQ_OUI_CMDID"); 5811 wmi_buf_free(wmi_buf); 5812 return QDF_STATUS_E_FAILURE; 5813 } 5814 return QDF_STATUS_SUCCESS; 5815 } 5816 5817 #ifdef IPA_OFFLOAD 5818 /** send_ipa_offload_control_cmd_tlv() - ipa offload control parameter 5819 * @wmi_handle: wmi handle 5820 * @ipa_offload: ipa offload control parameter 5821 * 5822 * Returns: 0 on success, error number otherwise 5823 */ 5824 static QDF_STATUS send_ipa_offload_control_cmd_tlv(wmi_unified_t wmi_handle, 5825 struct ipa_uc_offload_control_params *ipa_offload) 5826 { 5827 wmi_ipa_offload_enable_disable_cmd_fixed_param *cmd; 5828 wmi_buf_t wmi_buf; 5829 uint32_t len; 5830 u_int8_t *buf_ptr; 5831 5832 len = sizeof(*cmd); 5833 wmi_buf = wmi_buf_alloc(wmi_handle, len); 5834 if (!wmi_buf) 5835 return QDF_STATUS_E_NOMEM; 5836 5837 wmi_debug("offload_type=%d, enable=%d", 5838 ipa_offload->offload_type, ipa_offload->enable); 5839 5840 buf_ptr = (u_int8_t *)wmi_buf_data(wmi_buf); 5841 5842 cmd = (wmi_ipa_offload_enable_disable_cmd_fixed_param *)buf_ptr; 5843 WMITLV_SET_HDR(&cmd->tlv_header, 5844 WMITLV_TAG_STRUCT_wmi_ipa_offload_enable_disable_cmd_fixed_param, 5845 WMITLV_GET_STRUCT_TLVLEN( 5846 wmi_ipa_offload_enable_disable_cmd_fixed_param)); 5847 5848 cmd->offload_type = ipa_offload->offload_type; 5849 cmd->vdev_id = ipa_offload->vdev_id; 5850 cmd->enable = ipa_offload->enable; 5851 5852 wmi_mtrace(WMI_IPA_OFFLOAD_ENABLE_DISABLE_CMDID, cmd->vdev_id, 0); 5853 if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len, 5854 WMI_IPA_OFFLOAD_ENABLE_DISABLE_CMDID)) { 5855 wmi_err("Failed to send WMI_IPA_OFFLOAD_ENABLE_DISABLE_CMDID"); 5856 wmi_buf_free(wmi_buf); 5857 return QDF_STATUS_E_FAILURE; 5858 } 5859 5860 return QDF_STATUS_SUCCESS; 5861 } 5862 #endif 5863 5864 /** 5865 * send_pno_stop_cmd_tlv() - PNO stop request 5866 * @wmi_handle: wmi handle 5867 * @vdev_id: vdev id 5868 * 5869 * This function request FW to stop ongoing PNO operation. 5870 * 5871 * Return: QDF status 5872 */ 5873 static QDF_STATUS send_pno_stop_cmd_tlv(wmi_unified_t wmi_handle, uint8_t vdev_id) 5874 { 5875 wmi_nlo_config_cmd_fixed_param *cmd; 5876 int32_t len = sizeof(*cmd); 5877 wmi_buf_t buf; 5878 uint8_t *buf_ptr; 5879 int ret; 5880 5881 /* 5882 * TLV place holder for array of structures nlo_configured_parameters 5883 * TLV place holder for array of uint32_t channel_list 5884 * TLV place holder for chnl prediction cfg 5885 */ 5886 len += WMI_TLV_HDR_SIZE + WMI_TLV_HDR_SIZE + WMI_TLV_HDR_SIZE; 5887 buf = wmi_buf_alloc(wmi_handle, len); 5888 if (!buf) 5889 return QDF_STATUS_E_NOMEM; 5890 5891 cmd = (wmi_nlo_config_cmd_fixed_param *) wmi_buf_data(buf); 5892 buf_ptr = (uint8_t *) cmd; 5893 5894 WMITLV_SET_HDR(&cmd->tlv_header, 5895 WMITLV_TAG_STRUC_wmi_nlo_config_cmd_fixed_param, 5896 WMITLV_GET_STRUCT_TLVLEN 5897 (wmi_nlo_config_cmd_fixed_param)); 5898 5899 cmd->vdev_id = vdev_id; 5900 cmd->flags = WMI_NLO_CONFIG_STOP; 5901 buf_ptr += sizeof(*cmd); 5902 5903 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0); 5904 buf_ptr += WMI_TLV_HDR_SIZE; 5905 5906 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, 0); 5907 buf_ptr += WMI_TLV_HDR_SIZE; 5908 5909 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0); 5910 buf_ptr += WMI_TLV_HDR_SIZE; 5911 5912 wmi_mtrace(WMI_NETWORK_LIST_OFFLOAD_CONFIG_CMDID, cmd->vdev_id, 0); 5913 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 5914 WMI_NETWORK_LIST_OFFLOAD_CONFIG_CMDID); 5915 if (ret) { 5916 wmi_err("Failed to send nlo wmi cmd"); 5917 wmi_buf_free(buf); 5918 return QDF_STATUS_E_FAILURE; 5919 } 5920 5921 return QDF_STATUS_SUCCESS; 5922 } 5923 5924 /** 5925 * send_obss_disable_cmd_tlv() - disable obss scan request 5926 * @wmi_handle: wmi handle 5927 * @vdev_id: vdev id 5928 * 5929 * This function request FW to disable ongoing obss scan operation. 5930 * 5931 * Return: QDF status 5932 */ 5933 static QDF_STATUS send_obss_disable_cmd_tlv(wmi_unified_t wmi_handle, 5934 uint8_t vdev_id) 5935 { 5936 QDF_STATUS status; 5937 wmi_buf_t buf; 5938 wmi_obss_scan_disable_cmd_fixed_param *cmd; 5939 int len = sizeof(*cmd); 5940 5941 buf = wmi_buf_alloc(wmi_handle, len); 5942 if (!buf) 5943 return QDF_STATUS_E_NOMEM; 5944 5945 wmi_debug("cmd %x vdev_id %d", WMI_OBSS_SCAN_DISABLE_CMDID, vdev_id); 5946 5947 cmd = (wmi_obss_scan_disable_cmd_fixed_param *)wmi_buf_data(buf); 5948 WMITLV_SET_HDR(&cmd->tlv_header, 5949 WMITLV_TAG_STRUC_wmi_obss_scan_disable_cmd_fixed_param, 5950 WMITLV_GET_STRUCT_TLVLEN( 5951 wmi_obss_scan_disable_cmd_fixed_param)); 5952 5953 cmd->vdev_id = vdev_id; 5954 status = wmi_unified_cmd_send(wmi_handle, buf, len, 5955 WMI_OBSS_SCAN_DISABLE_CMDID); 5956 if (QDF_IS_STATUS_ERROR(status)) 5957 wmi_buf_free(buf); 5958 5959 return status; 5960 } 5961 5962 /** 5963 * wmi_set_pno_channel_prediction() - Set PNO channel prediction 5964 * @buf_ptr: Buffer passed by upper layers 5965 * @pno: Buffer to be sent to the firmware 5966 * 5967 * Copy the PNO Channel prediction configuration parameters 5968 * passed by the upper layers to a WMI format TLV and send it 5969 * down to the firmware. 5970 * 5971 * Return: None 5972 */ 5973 static void wmi_set_pno_channel_prediction(uint8_t *buf_ptr, 5974 struct pno_scan_req_params *pno) 5975 { 5976 nlo_channel_prediction_cfg *channel_prediction_cfg = 5977 (nlo_channel_prediction_cfg *) buf_ptr; 5978 WMITLV_SET_HDR(&channel_prediction_cfg->tlv_header, 5979 WMITLV_TAG_ARRAY_BYTE, 5980 WMITLV_GET_STRUCT_TLVLEN(nlo_channel_prediction_cfg)); 5981 #ifdef FEATURE_WLAN_SCAN_PNO 5982 channel_prediction_cfg->enable = pno->pno_channel_prediction; 5983 channel_prediction_cfg->top_k_num = pno->top_k_num_of_channels; 5984 channel_prediction_cfg->stationary_threshold = pno->stationary_thresh; 5985 channel_prediction_cfg->full_scan_period_ms = 5986 pno->channel_prediction_full_scan; 5987 #endif 5988 buf_ptr += sizeof(nlo_channel_prediction_cfg); 5989 wmi_debug("enable: %d, top_k_num: %d, stat_thresh: %d, full_scan: %d", 5990 channel_prediction_cfg->enable, 5991 channel_prediction_cfg->top_k_num, 5992 channel_prediction_cfg->stationary_threshold, 5993 channel_prediction_cfg->full_scan_period_ms); 5994 } 5995 5996 /** 5997 * send_cp_stats_cmd_tlv() - Send cp stats wmi command 5998 * @wmi_handle: wmi handle 5999 * @buf_ptr: Buffer passed by upper layers 6000 * @buf_len: Length of passed buffer by upper layer 6001 * 6002 * Copy the buffer passed by the upper layers and send it 6003 * down to the firmware. 6004 * 6005 * Return: None 6006 */ 6007 static QDF_STATUS send_cp_stats_cmd_tlv(wmi_unified_t wmi_handle, 6008 void *buf_ptr, uint32_t buf_len) 6009 { 6010 wmi_buf_t buf = NULL; 6011 QDF_STATUS status; 6012 int len; 6013 uint8_t *data_ptr; 6014 6015 len = buf_len; 6016 buf = wmi_buf_alloc(wmi_handle, len); 6017 if (!buf) 6018 return QDF_STATUS_E_NOMEM; 6019 6020 data_ptr = (uint8_t *)wmi_buf_data(buf); 6021 qdf_mem_copy(data_ptr, buf_ptr, len); 6022 6023 wmi_mtrace(WMI_REQUEST_CTRL_PATH_STATS_CMDID, NO_SESSION, 0); 6024 status = wmi_unified_cmd_send(wmi_handle, buf, 6025 len, WMI_REQUEST_CTRL_PATH_STATS_CMDID); 6026 6027 if (QDF_IS_STATUS_ERROR(status)) { 6028 wmi_buf_free(buf); 6029 return QDF_STATUS_E_FAILURE; 6030 } 6031 return QDF_STATUS_SUCCESS; 6032 } 6033 6034 /** 6035 * send_halphy_stats_cmd_tlv() - Send halphy stats wmi command 6036 * @wmi_handle: wmi handle 6037 * @buf_ptr: Buffer passed by upper layers 6038 * @buf_len: Length of passed buffer by upper layer 6039 * 6040 * Copy the buffer passed by the upper layers and send it 6041 * down to the firmware. 6042 * 6043 * Return: None 6044 */ 6045 static QDF_STATUS send_halphy_stats_cmd_tlv(wmi_unified_t wmi_handle, 6046 void *buf_ptr, uint32_t buf_len) 6047 { 6048 wmi_buf_t buf = NULL; 6049 QDF_STATUS status; 6050 int len; 6051 uint8_t *data_ptr; 6052 6053 len = buf_len; 6054 buf = wmi_buf_alloc(wmi_handle, len); 6055 if (!buf) 6056 return QDF_STATUS_E_NOMEM; 6057 6058 data_ptr = (uint8_t *)wmi_buf_data(buf); 6059 qdf_mem_copy(data_ptr, buf_ptr, len); 6060 6061 wmi_mtrace(WMI_REQUEST_HALPHY_CTRL_PATH_STATS_CMDID, NO_SESSION, 0); 6062 status = wmi_unified_cmd_send(wmi_handle, buf, 6063 len, 6064 WMI_REQUEST_HALPHY_CTRL_PATH_STATS_CMDID); 6065 6066 if (QDF_IS_STATUS_ERROR(status)) { 6067 wmi_buf_free(buf); 6068 return QDF_STATUS_E_FAILURE; 6069 } 6070 return QDF_STATUS_SUCCESS; 6071 } 6072 6073 /** 6074 * extract_cp_stats_more_pending_tlv - api to extract more flag from event data 6075 * @wmi_handle: wmi handle 6076 * @evt_buf: event buffer 6077 * @more_flag: buffer to populate more flag 6078 * 6079 * Return: status of operation 6080 */ 6081 static QDF_STATUS 6082 extract_cp_stats_more_pending_tlv(wmi_unified_t wmi_handle, void *evt_buf, 6083 uint32_t *more_flag) 6084 { 6085 WMI_CTRL_PATH_STATS_EVENTID_param_tlvs *param_buf; 6086 wmi_ctrl_path_stats_event_fixed_param *ev; 6087 6088 param_buf = (WMI_CTRL_PATH_STATS_EVENTID_param_tlvs *)evt_buf; 6089 if (!param_buf) { 6090 wmi_err_rl("param_buf is NULL"); 6091 return QDF_STATUS_E_FAILURE; 6092 } 6093 ev = (wmi_ctrl_path_stats_event_fixed_param *)param_buf->fixed_param; 6094 6095 *more_flag = ev->more; 6096 return QDF_STATUS_SUCCESS; 6097 } 6098 6099 /** 6100 * extract_halphy_stats_end_of_event_tlv - api to extract end_of_event flag 6101 * from event data 6102 * @wmi_handle: wmi handle 6103 * @evt_buf: event buffer 6104 * @end_of_event_flag: buffer to populate end_of_event flag 6105 * 6106 * Return: status of operation 6107 */ 6108 static QDF_STATUS 6109 extract_halphy_stats_end_of_event_tlv(wmi_unified_t wmi_handle, void *evt_buf, 6110 uint32_t *end_of_event_flag) 6111 { 6112 WMI_HALPHY_CTRL_PATH_STATS_EVENTID_param_tlvs *param_buf; 6113 wmi_halphy_ctrl_path_stats_event_fixed_param *ev; 6114 6115 param_buf = (WMI_HALPHY_CTRL_PATH_STATS_EVENTID_param_tlvs *)evt_buf; 6116 if (!param_buf) { 6117 wmi_err_rl("param_buf is NULL"); 6118 return QDF_STATUS_E_FAILURE; 6119 } 6120 ev = (wmi_halphy_ctrl_path_stats_event_fixed_param *) 6121 param_buf->fixed_param; 6122 6123 *end_of_event_flag = ev->end_of_event; 6124 return QDF_STATUS_SUCCESS; 6125 } 6126 6127 /** 6128 * extract_halphy_stats_event_count_tlv() - api to extract event count flag 6129 * from event data 6130 * @wmi_handle: wmi handle 6131 * @evt_buf: event buffer 6132 * @event_count_flag: buffer to populate event_count flag 6133 * 6134 * Return: status of operation 6135 */ 6136 static QDF_STATUS 6137 extract_halphy_stats_event_count_tlv(wmi_unified_t wmi_handle, void *evt_buf, 6138 uint32_t *event_count_flag) 6139 { 6140 WMI_HALPHY_CTRL_PATH_STATS_EVENTID_param_tlvs *param_buf; 6141 wmi_halphy_ctrl_path_stats_event_fixed_param *ev; 6142 6143 param_buf = (WMI_HALPHY_CTRL_PATH_STATS_EVENTID_param_tlvs *)evt_buf; 6144 if (!param_buf) { 6145 wmi_err_rl("param_buf is NULL"); 6146 return QDF_STATUS_E_FAILURE; 6147 } 6148 ev = (wmi_halphy_ctrl_path_stats_event_fixed_param *) 6149 param_buf->fixed_param; 6150 6151 *event_count_flag = ev->event_count; 6152 return QDF_STATUS_SUCCESS; 6153 } 6154 6155 /** 6156 * send_nlo_mawc_cmd_tlv() - Send MAWC NLO configuration 6157 * @wmi_handle: wmi handle 6158 * @params: configuration parameters 6159 * 6160 * Return: QDF_STATUS 6161 */ 6162 static QDF_STATUS send_nlo_mawc_cmd_tlv(wmi_unified_t wmi_handle, 6163 struct nlo_mawc_params *params) 6164 { 6165 wmi_buf_t buf = NULL; 6166 QDF_STATUS status; 6167 int len; 6168 uint8_t *buf_ptr; 6169 wmi_nlo_configure_mawc_cmd_fixed_param *wmi_nlo_mawc_params; 6170 6171 len = sizeof(*wmi_nlo_mawc_params); 6172 buf = wmi_buf_alloc(wmi_handle, len); 6173 if (!buf) 6174 return QDF_STATUS_E_NOMEM; 6175 6176 buf_ptr = (uint8_t *) wmi_buf_data(buf); 6177 wmi_nlo_mawc_params = 6178 (wmi_nlo_configure_mawc_cmd_fixed_param *) buf_ptr; 6179 WMITLV_SET_HDR(&wmi_nlo_mawc_params->tlv_header, 6180 WMITLV_TAG_STRUC_wmi_nlo_configure_mawc_cmd_fixed_param, 6181 WMITLV_GET_STRUCT_TLVLEN 6182 (wmi_nlo_configure_mawc_cmd_fixed_param)); 6183 wmi_nlo_mawc_params->vdev_id = params->vdev_id; 6184 if (params->enable) 6185 wmi_nlo_mawc_params->enable = 1; 6186 else 6187 wmi_nlo_mawc_params->enable = 0; 6188 wmi_nlo_mawc_params->exp_backoff_ratio = params->exp_backoff_ratio; 6189 wmi_nlo_mawc_params->init_scan_interval = params->init_scan_interval; 6190 wmi_nlo_mawc_params->max_scan_interval = params->max_scan_interval; 6191 wmi_debug("MAWC NLO en=%d, vdev=%d, ratio=%d, SCAN init=%d, max=%d", 6192 wmi_nlo_mawc_params->enable, wmi_nlo_mawc_params->vdev_id, 6193 wmi_nlo_mawc_params->exp_backoff_ratio, 6194 wmi_nlo_mawc_params->init_scan_interval, 6195 wmi_nlo_mawc_params->max_scan_interval); 6196 6197 wmi_mtrace(WMI_NLO_CONFIGURE_MAWC_CMDID, NO_SESSION, 0); 6198 status = wmi_unified_cmd_send(wmi_handle, buf, 6199 len, WMI_NLO_CONFIGURE_MAWC_CMDID); 6200 if (QDF_IS_STATUS_ERROR(status)) { 6201 wmi_err("WMI_NLO_CONFIGURE_MAWC_CMDID failed, Error %d", 6202 status); 6203 wmi_buf_free(buf); 6204 return QDF_STATUS_E_FAILURE; 6205 } 6206 6207 return QDF_STATUS_SUCCESS; 6208 } 6209 6210 /** 6211 * wmi_dump_pno_scan_freq_list() - dump frequency list associated with pno 6212 * scan 6213 * @scan_freq_list: frequency list for pno scan 6214 * 6215 * Return: void 6216 */ 6217 static void wmi_dump_pno_scan_freq_list(struct chan_list *scan_freq_list) 6218 { 6219 uint32_t i; 6220 uint8_t info[WMI_MAX_CHAN_INFO_LOG]; 6221 uint32_t len = 0; 6222 struct chan_info *chan_info; 6223 int ret; 6224 6225 wmi_debug("[PNO_SCAN] Total freq %d", scan_freq_list->num_chan); 6226 for (i = 0; i < scan_freq_list->num_chan; i++) { 6227 chan_info = &scan_freq_list->chan[i]; 6228 ret = qdf_scnprintf(info + len, sizeof(info) - len, 6229 " %d[%d]", chan_info->freq, 6230 chan_info->flags); 6231 if (ret <= 0) 6232 break; 6233 len += ret; 6234 if (len >= (sizeof(info) - 20)) { 6235 wmi_nofl_debug("Freq[flag]:%s", 6236 info); 6237 len = 0; 6238 } 6239 } 6240 if (len) 6241 wmi_nofl_debug("Freq[flag]:%s", info); 6242 } 6243 6244 /** 6245 * send_pno_start_cmd_tlv() - PNO start request 6246 * @wmi_handle: wmi handle 6247 * @pno: PNO request 6248 * 6249 * This function request FW to start PNO request. 6250 * Request: QDF status 6251 */ 6252 static QDF_STATUS send_pno_start_cmd_tlv(wmi_unified_t wmi_handle, 6253 struct pno_scan_req_params *pno) 6254 { 6255 wmi_nlo_config_cmd_fixed_param *cmd; 6256 nlo_configured_parameters *nlo_list; 6257 uint32_t *channel_list; 6258 int32_t len; 6259 qdf_freq_t freq; 6260 wmi_buf_t buf; 6261 uint8_t *buf_ptr; 6262 uint8_t i; 6263 int ret; 6264 struct probe_req_allowlist_attr *ie_allowlist = &pno->ie_allowlist; 6265 connected_nlo_rssi_params *nlo_relative_rssi; 6266 connected_nlo_bss_band_rssi_pref *nlo_band_rssi; 6267 6268 /* 6269 * TLV place holder for array nlo_configured_parameters(nlo_list) 6270 * TLV place holder for array of uint32_t channel_list 6271 * TLV place holder for chnnl prediction cfg 6272 * TLV place holder for array of wmi_vendor_oui 6273 * TLV place holder for array of connected_nlo_bss_band_rssi_pref 6274 */ 6275 len = sizeof(*cmd) + 6276 WMI_TLV_HDR_SIZE + WMI_TLV_HDR_SIZE + WMI_TLV_HDR_SIZE + 6277 WMI_TLV_HDR_SIZE + WMI_TLV_HDR_SIZE; 6278 6279 len += sizeof(uint32_t) * pno->networks_list[0].pno_chan_list.num_chan; 6280 len += sizeof(nlo_configured_parameters) * 6281 QDF_MIN(pno->networks_cnt, WMI_NLO_MAX_SSIDS); 6282 len += sizeof(nlo_channel_prediction_cfg); 6283 len += sizeof(enlo_candidate_score_params); 6284 len += sizeof(wmi_vendor_oui) * ie_allowlist->num_vendor_oui; 6285 len += sizeof(connected_nlo_rssi_params); 6286 len += sizeof(connected_nlo_bss_band_rssi_pref); 6287 6288 buf = wmi_buf_alloc(wmi_handle, len); 6289 if (!buf) 6290 return QDF_STATUS_E_NOMEM; 6291 6292 cmd = (wmi_nlo_config_cmd_fixed_param *) wmi_buf_data(buf); 6293 6294 buf_ptr = (uint8_t *) cmd; 6295 WMITLV_SET_HDR(&cmd->tlv_header, 6296 WMITLV_TAG_STRUC_wmi_nlo_config_cmd_fixed_param, 6297 WMITLV_GET_STRUCT_TLVLEN 6298 (wmi_nlo_config_cmd_fixed_param)); 6299 cmd->vdev_id = pno->vdev_id; 6300 cmd->flags = WMI_NLO_CONFIG_START | WMI_NLO_CONFIG_SSID_HIDE_EN; 6301 6302 #ifdef FEATURE_WLAN_SCAN_PNO 6303 WMI_SCAN_SET_DWELL_MODE(cmd->flags, 6304 pno->adaptive_dwell_mode); 6305 #endif 6306 /* Current FW does not support min-max range for dwell time */ 6307 cmd->active_dwell_time = pno->active_dwell_time; 6308 cmd->passive_dwell_time = pno->passive_dwell_time; 6309 6310 if (pno->do_passive_scan) 6311 cmd->flags |= WMI_NLO_CONFIG_SCAN_PASSIVE; 6312 /* Copy scan interval */ 6313 cmd->fast_scan_period = pno->fast_scan_period; 6314 cmd->slow_scan_period = pno->slow_scan_period; 6315 cmd->delay_start_time = WMI_SEC_TO_MSEC(pno->delay_start_time); 6316 cmd->fast_scan_max_cycles = pno->fast_scan_max_cycles; 6317 cmd->scan_backoff_multiplier = pno->scan_backoff_multiplier; 6318 6319 /* mac randomization attributes */ 6320 if (pno->scan_random.randomize) { 6321 cmd->flags |= WMI_NLO_CONFIG_SPOOFED_MAC_IN_PROBE_REQ | 6322 WMI_NLO_CONFIG_RANDOM_SEQ_NO_IN_PROBE_REQ; 6323 wmi_copy_scan_random_mac(pno->scan_random.mac_addr, 6324 pno->scan_random.mac_mask, 6325 &cmd->mac_addr, 6326 &cmd->mac_mask); 6327 } 6328 6329 buf_ptr += sizeof(wmi_nlo_config_cmd_fixed_param); 6330 6331 cmd->no_of_ssids = QDF_MIN(pno->networks_cnt, WMI_NLO_MAX_SSIDS); 6332 6333 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 6334 cmd->no_of_ssids * sizeof(nlo_configured_parameters)); 6335 buf_ptr += WMI_TLV_HDR_SIZE; 6336 6337 nlo_list = (nlo_configured_parameters *) buf_ptr; 6338 for (i = 0; i < cmd->no_of_ssids; i++) { 6339 WMITLV_SET_HDR(&nlo_list[i].tlv_header, 6340 WMITLV_TAG_ARRAY_BYTE, 6341 WMITLV_GET_STRUCT_TLVLEN 6342 (nlo_configured_parameters)); 6343 /* Copy ssid and it's length */ 6344 nlo_list[i].ssid.valid = true; 6345 nlo_list[i].ssid.ssid.ssid_len = 6346 pno->networks_list[i].ssid.length; 6347 qdf_mem_copy(nlo_list[i].ssid.ssid.ssid, 6348 pno->networks_list[i].ssid.ssid, 6349 nlo_list[i].ssid.ssid.ssid_len); 6350 6351 /* Copy rssi threshold */ 6352 if (pno->networks_list[i].rssi_thresh && 6353 pno->networks_list[i].rssi_thresh > 6354 WMI_RSSI_THOLD_DEFAULT) { 6355 nlo_list[i].rssi_cond.valid = true; 6356 nlo_list[i].rssi_cond.rssi = 6357 pno->networks_list[i].rssi_thresh; 6358 } 6359 nlo_list[i].bcast_nw_type.valid = true; 6360 nlo_list[i].bcast_nw_type.bcast_nw_type = 6361 pno->networks_list[i].bc_new_type; 6362 } 6363 buf_ptr += cmd->no_of_ssids * sizeof(nlo_configured_parameters); 6364 6365 /* Copy channel info */ 6366 cmd->num_of_channels = pno->networks_list[0].pno_chan_list.num_chan; 6367 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, 6368 (cmd->num_of_channels * sizeof(uint32_t))); 6369 buf_ptr += WMI_TLV_HDR_SIZE; 6370 6371 channel_list = (uint32_t *) buf_ptr; 6372 for (i = 0; i < cmd->num_of_channels; i++) { 6373 TARGET_SET_FREQ_IN_CHAN_LIST_TLV(channel_list[i], 6374 pno->networks_list[0].pno_chan_list.chan[i].freq); 6375 6376 if (channel_list[i] < WMI_NLO_FREQ_THRESH) { 6377 freq = pno->networks_list[0].pno_chan_list.chan[i].freq; 6378 TARGET_SET_FREQ_IN_CHAN_LIST_TLV(channel_list[i], 6379 wlan_chan_to_freq(freq)); 6380 } 6381 6382 TARGET_SET_FLAGS_IN_CHAN_LIST_TLV(channel_list[i], 6383 pno->networks_list[0].pno_chan_list.chan[i].flags); 6384 } 6385 6386 wmi_dump_pno_scan_freq_list(&pno->networks_list[0].pno_chan_list); 6387 6388 buf_ptr += cmd->num_of_channels * sizeof(uint32_t); 6389 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 6390 sizeof(nlo_channel_prediction_cfg)); 6391 buf_ptr += WMI_TLV_HDR_SIZE; 6392 wmi_set_pno_channel_prediction(buf_ptr, pno); 6393 buf_ptr += sizeof(nlo_channel_prediction_cfg); 6394 /** TODO: Discrete firmware doesn't have command/option to configure 6395 * App IE which comes from wpa_supplicant as of part PNO start request. 6396 */ 6397 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_STRUC_enlo_candidate_score_param, 6398 WMITLV_GET_STRUCT_TLVLEN(enlo_candidate_score_params)); 6399 buf_ptr += sizeof(enlo_candidate_score_params); 6400 6401 if (ie_allowlist->allow_list) { 6402 cmd->flags |= WMI_NLO_CONFIG_ENABLE_IE_WHITELIST_IN_PROBE_REQ; 6403 wmi_fill_ie_allowlist_attrs(cmd->ie_bitmap, 6404 &cmd->num_vendor_oui, 6405 ie_allowlist); 6406 } 6407 6408 /* ie allow list */ 6409 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 6410 ie_allowlist->num_vendor_oui * sizeof(wmi_vendor_oui)); 6411 buf_ptr += WMI_TLV_HDR_SIZE; 6412 if (cmd->num_vendor_oui != 0) { 6413 wmi_fill_vendor_oui(buf_ptr, cmd->num_vendor_oui, 6414 ie_allowlist->voui); 6415 buf_ptr += cmd->num_vendor_oui * sizeof(wmi_vendor_oui); 6416 } 6417 6418 if (pno->relative_rssi_set) 6419 cmd->flags |= WMI_NLO_CONFIG_ENABLE_CNLO_RSSI_CONFIG; 6420 6421 /* 6422 * Firmware calculation using connected PNO params: 6423 * New AP's RSSI >= (Connected AP's RSSI + relative_rssi +/- rssi_pref) 6424 * deduction of rssi_pref for chosen band_pref and 6425 * addition of rssi_pref for remaining bands (other than chosen band). 6426 */ 6427 nlo_relative_rssi = (connected_nlo_rssi_params *) buf_ptr; 6428 WMITLV_SET_HDR(&nlo_relative_rssi->tlv_header, 6429 WMITLV_TAG_STRUC_wmi_connected_nlo_rssi_params, 6430 WMITLV_GET_STRUCT_TLVLEN(connected_nlo_rssi_params)); 6431 nlo_relative_rssi->relative_rssi = pno->relative_rssi; 6432 buf_ptr += sizeof(*nlo_relative_rssi); 6433 6434 /* 6435 * As of now Kernel and Host supports one band and rssi preference. 6436 * Firmware supports array of band and rssi preferences 6437 */ 6438 cmd->num_cnlo_band_pref = 1; 6439 WMITLV_SET_HDR(buf_ptr, 6440 WMITLV_TAG_ARRAY_STRUC, 6441 cmd->num_cnlo_band_pref * 6442 sizeof(connected_nlo_bss_band_rssi_pref)); 6443 buf_ptr += WMI_TLV_HDR_SIZE; 6444 6445 nlo_band_rssi = (connected_nlo_bss_band_rssi_pref *) buf_ptr; 6446 for (i = 0; i < cmd->num_cnlo_band_pref; i++) { 6447 WMITLV_SET_HDR(&nlo_band_rssi[i].tlv_header, 6448 WMITLV_TAG_STRUC_wmi_connected_nlo_bss_band_rssi_pref, 6449 WMITLV_GET_STRUCT_TLVLEN( 6450 connected_nlo_bss_band_rssi_pref)); 6451 nlo_band_rssi[i].band = pno->band_rssi_pref.band; 6452 nlo_band_rssi[i].rssi_pref = pno->band_rssi_pref.rssi; 6453 } 6454 buf_ptr += cmd->num_cnlo_band_pref * sizeof(*nlo_band_rssi); 6455 6456 wmi_mtrace(WMI_NETWORK_LIST_OFFLOAD_CONFIG_CMDID, cmd->vdev_id, 0); 6457 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 6458 WMI_NETWORK_LIST_OFFLOAD_CONFIG_CMDID); 6459 if (ret) { 6460 wmi_err("Failed to send nlo wmi cmd"); 6461 wmi_buf_free(buf); 6462 return QDF_STATUS_E_FAILURE; 6463 } 6464 6465 return QDF_STATUS_SUCCESS; 6466 } 6467 6468 /** 6469 * is_service_enabled_tlv() - Check if service enabled 6470 * @wmi_handle: wmi handle 6471 * @service_id: service identifier 6472 * 6473 * Return: 1 enabled, 0 disabled 6474 */ 6475 static bool is_service_enabled_tlv(wmi_unified_t wmi_handle, 6476 uint32_t service_id) 6477 { 6478 struct wmi_soc *soc = wmi_handle->soc; 6479 6480 if (!soc->wmi_service_bitmap) { 6481 wmi_err("WMI service bit map is not saved yet"); 6482 return false; 6483 } 6484 6485 /* if wmi_service_enabled was received with extended2 bitmap, 6486 * use WMI_SERVICE_EXT2_IS_ENABLED to check the services. 6487 */ 6488 if (soc->wmi_ext2_service_bitmap) { 6489 if (!soc->wmi_ext_service_bitmap) { 6490 wmi_err("WMI service ext bit map is not saved yet"); 6491 return false; 6492 } 6493 6494 return WMI_SERVICE_EXT2_IS_ENABLED(soc->wmi_service_bitmap, 6495 soc->wmi_ext_service_bitmap, 6496 soc->wmi_ext2_service_bitmap, 6497 service_id); 6498 } 6499 6500 if (service_id >= WMI_MAX_EXT_SERVICE) { 6501 wmi_err_rl("Service id %d but WMI ext2 service bitmap is NULL", 6502 service_id); 6503 return false; 6504 } 6505 /* if wmi_service_enabled was received with extended bitmap, 6506 * use WMI_SERVICE_EXT_IS_ENABLED to check the services. 6507 */ 6508 if (soc->wmi_ext_service_bitmap) 6509 return WMI_SERVICE_EXT_IS_ENABLED(soc->wmi_service_bitmap, 6510 soc->wmi_ext_service_bitmap, 6511 service_id); 6512 6513 if (service_id >= WMI_MAX_SERVICE) { 6514 wmi_err("Service id %d but WMI ext service bitmap is NULL", 6515 service_id); 6516 return false; 6517 } 6518 6519 return WMI_SERVICE_IS_ENABLED(soc->wmi_service_bitmap, 6520 service_id); 6521 } 6522 6523 #ifdef WLAN_FEATURE_LINK_LAYER_STATS 6524 /** 6525 * send_process_ll_stats_clear_cmd_tlv() - clear link layer stats 6526 * @wmi_handle: wmi handle 6527 * @clear_req: ll stats clear request command params 6528 * 6529 * Return: QDF_STATUS_SUCCESS for success or error code 6530 */ 6531 static QDF_STATUS send_process_ll_stats_clear_cmd_tlv(wmi_unified_t wmi_handle, 6532 const struct ll_stats_clear_params *clear_req) 6533 { 6534 wmi_clear_link_stats_cmd_fixed_param *cmd; 6535 int32_t len; 6536 wmi_buf_t buf; 6537 uint8_t *buf_ptr; 6538 int ret; 6539 6540 len = sizeof(*cmd); 6541 buf = wmi_buf_alloc(wmi_handle, len); 6542 6543 if (!buf) 6544 return QDF_STATUS_E_NOMEM; 6545 6546 buf_ptr = (uint8_t *) wmi_buf_data(buf); 6547 qdf_mem_zero(buf_ptr, len); 6548 cmd = (wmi_clear_link_stats_cmd_fixed_param *) buf_ptr; 6549 6550 WMITLV_SET_HDR(&cmd->tlv_header, 6551 WMITLV_TAG_STRUC_wmi_clear_link_stats_cmd_fixed_param, 6552 WMITLV_GET_STRUCT_TLVLEN 6553 (wmi_clear_link_stats_cmd_fixed_param)); 6554 6555 cmd->stop_stats_collection_req = clear_req->stop_req; 6556 cmd->vdev_id = clear_req->vdev_id; 6557 cmd->stats_clear_req_mask = clear_req->stats_clear_mask; 6558 6559 WMI_CHAR_ARRAY_TO_MAC_ADDR(clear_req->peer_macaddr.bytes, 6560 &cmd->peer_macaddr); 6561 6562 wmi_debug("LINK_LAYER_STATS - Clear Request Params"); 6563 wmi_debug("StopReq: %d Vdev Id: %d Clear Stat Mask: %d" 6564 " Peer MAC Addr: "QDF_MAC_ADDR_FMT, 6565 cmd->stop_stats_collection_req, 6566 cmd->vdev_id, cmd->stats_clear_req_mask, 6567 QDF_MAC_ADDR_REF(clear_req->peer_macaddr.bytes)); 6568 6569 wmi_mtrace(WMI_CLEAR_LINK_STATS_CMDID, cmd->vdev_id, 0); 6570 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 6571 WMI_CLEAR_LINK_STATS_CMDID); 6572 if (ret) { 6573 wmi_err("Failed to send clear link stats req"); 6574 wmi_buf_free(buf); 6575 return QDF_STATUS_E_FAILURE; 6576 } 6577 6578 wmi_debug("Clear Link Layer Stats request sent successfully"); 6579 return QDF_STATUS_SUCCESS; 6580 } 6581 6582 /** 6583 * send_process_ll_stats_set_cmd_tlv() - link layer stats set request 6584 * @wmi_handle: wmi handle 6585 * @set_req: ll stats set request command params 6586 * 6587 * Return: QDF_STATUS_SUCCESS for success or error code 6588 */ 6589 static QDF_STATUS send_process_ll_stats_set_cmd_tlv(wmi_unified_t wmi_handle, 6590 const struct ll_stats_set_params *set_req) 6591 { 6592 wmi_start_link_stats_cmd_fixed_param *cmd; 6593 int32_t len; 6594 wmi_buf_t buf; 6595 uint8_t *buf_ptr; 6596 int ret; 6597 6598 len = sizeof(*cmd); 6599 buf = wmi_buf_alloc(wmi_handle, len); 6600 6601 if (!buf) 6602 return QDF_STATUS_E_NOMEM; 6603 6604 buf_ptr = (uint8_t *) wmi_buf_data(buf); 6605 qdf_mem_zero(buf_ptr, len); 6606 cmd = (wmi_start_link_stats_cmd_fixed_param *) buf_ptr; 6607 6608 WMITLV_SET_HDR(&cmd->tlv_header, 6609 WMITLV_TAG_STRUC_wmi_start_link_stats_cmd_fixed_param, 6610 WMITLV_GET_STRUCT_TLVLEN 6611 (wmi_start_link_stats_cmd_fixed_param)); 6612 6613 cmd->mpdu_size_threshold = set_req->mpdu_size_threshold; 6614 cmd->aggressive_statistics_gathering = 6615 set_req->aggressive_statistics_gathering; 6616 6617 wmi_debug("LINK_LAYER_STATS - Start/Set Params MPDU Size Thresh : %d Aggressive Gather: %d", 6618 cmd->mpdu_size_threshold, 6619 cmd->aggressive_statistics_gathering); 6620 6621 wmi_mtrace(WMI_START_LINK_STATS_CMDID, NO_SESSION, 0); 6622 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 6623 WMI_START_LINK_STATS_CMDID); 6624 if (ret) { 6625 wmi_err("Failed to send set link stats request"); 6626 wmi_buf_free(buf); 6627 return QDF_STATUS_E_FAILURE; 6628 } 6629 6630 return QDF_STATUS_SUCCESS; 6631 } 6632 6633 /** 6634 * send_process_ll_stats_get_cmd_tlv() - link layer stats get request 6635 * @wmi_handle: wmi handle 6636 * @get_req: ll stats get request command params 6637 * 6638 * Return: QDF_STATUS_SUCCESS for success or error code 6639 */ 6640 static QDF_STATUS send_process_ll_stats_get_cmd_tlv(wmi_unified_t wmi_handle, 6641 const struct ll_stats_get_params *get_req) 6642 { 6643 wmi_request_link_stats_cmd_fixed_param *cmd; 6644 int32_t len; 6645 wmi_buf_t buf; 6646 uint8_t *buf_ptr; 6647 int ret; 6648 6649 len = sizeof(*cmd); 6650 buf = wmi_buf_alloc(wmi_handle, len); 6651 6652 if (!buf) 6653 return QDF_STATUS_E_NOMEM; 6654 6655 buf_ptr = (uint8_t *) wmi_buf_data(buf); 6656 qdf_mem_zero(buf_ptr, len); 6657 cmd = (wmi_request_link_stats_cmd_fixed_param *) buf_ptr; 6658 6659 WMITLV_SET_HDR(&cmd->tlv_header, 6660 WMITLV_TAG_STRUC_wmi_request_link_stats_cmd_fixed_param, 6661 WMITLV_GET_STRUCT_TLVLEN 6662 (wmi_request_link_stats_cmd_fixed_param)); 6663 6664 cmd->request_id = get_req->req_id; 6665 cmd->stats_type = get_req->param_id_mask; 6666 cmd->vdev_id = get_req->vdev_id; 6667 6668 WMI_CHAR_ARRAY_TO_MAC_ADDR(get_req->peer_macaddr.bytes, 6669 &cmd->peer_macaddr); 6670 6671 wmi_debug("LINK_LAYER_STATS - Get Request Params Request ID: %u Stats Type: %0x Vdev ID: %d Peer MAC Addr: "QDF_MAC_ADDR_FMT, 6672 cmd->request_id, cmd->stats_type, cmd->vdev_id, 6673 QDF_MAC_ADDR_REF(get_req->peer_macaddr.bytes)); 6674 6675 wmi_mtrace(WMI_REQUEST_LINK_STATS_CMDID, cmd->vdev_id, 0); 6676 ret = wmi_unified_cmd_send_pm_chk(wmi_handle, buf, len, 6677 WMI_REQUEST_LINK_STATS_CMDID, true); 6678 if (ret) { 6679 wmi_buf_free(buf); 6680 return QDF_STATUS_E_FAILURE; 6681 } 6682 6683 return QDF_STATUS_SUCCESS; 6684 } 6685 6686 #ifdef FEATURE_CLUB_LL_STATS_AND_GET_STATION 6687 #ifdef WLAN_FEATURE_11BE_MLO 6688 static int 6689 wmi_get_tlv_length_for_mlo_stats(const struct ll_stats_get_params *get_req) 6690 { 6691 int32_t len = 0; 6692 6693 /* In case of MLO connection, update the length of the buffer. 6694 * The wmi_inst_rssi_stats_params structure is not needed for MLO stats, 6695 * hence just update the TLV header, but allocate no memory for it. 6696 */ 6697 if (!get_req->is_mlo_req) 6698 return len; 6699 6700 len += WMI_TLV_HDR_SIZE + 0 * sizeof(wmi_inst_rssi_stats_params) + 6701 WMI_TLV_HDR_SIZE + 1 * sizeof(uint32_t) + 6702 WMI_TLV_HDR_SIZE + 1 * sizeof(wmi_mac_addr); 6703 6704 return len; 6705 } 6706 6707 static void 6708 wmi_update_tlv_headers_for_mlo_stats(const struct ll_stats_get_params *get_req, 6709 void *buf_ptr) 6710 { 6711 wmi_request_unified_ll_get_sta_cmd_fixed_param *unified_cmd; 6712 uint32_t *vdev_id_bitmap; 6713 wmi_mac_addr *mld_mac; 6714 6715 /* In case of MLO connection, update the TLV Headers */ 6716 if (!get_req->is_mlo_req) 6717 return; 6718 6719 buf_ptr += sizeof(*unified_cmd); 6720 6721 /* Fill TLV but no data for wmi_inst_rssi_stats_params */ 6722 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0); 6723 buf_ptr += WMI_TLV_HDR_SIZE; 6724 6725 /* Adding vdev_bitmap_id array TLV */ 6726 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, 6727 sizeof(*vdev_id_bitmap)); 6728 buf_ptr += WMI_TLV_HDR_SIZE; 6729 vdev_id_bitmap = buf_ptr; 6730 *(vdev_id_bitmap) = get_req->vdev_id_bitmap; 6731 buf_ptr += sizeof(*vdev_id_bitmap); 6732 6733 /* Adding mld_macaddr array TLV */ 6734 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_FIXED_STRUC, 6735 sizeof(*mld_mac)); 6736 buf_ptr += WMI_TLV_HDR_SIZE; 6737 mld_mac = buf_ptr; 6738 WMI_CHAR_ARRAY_TO_MAC_ADDR(get_req->mld_macaddr.bytes, mld_mac); 6739 6740 wmi_debug("MLO vdev_id_bitmap: 0x%x MLD MAC Addr: " 6741 QDF_MAC_ADDR_FMT, get_req->vdev_id_bitmap, 6742 QDF_MAC_ADDR_REF(get_req->mld_macaddr.bytes)); 6743 } 6744 #else 6745 static inline int 6746 wmi_get_tlv_length_for_mlo_stats(const struct ll_stats_get_params *get_req) 6747 { 6748 return 0; 6749 } 6750 6751 static inline void 6752 wmi_update_tlv_headers_for_mlo_stats(const struct ll_stats_get_params *get_req, 6753 void *buf_ptr) 6754 { 6755 } 6756 #endif 6757 6758 /** 6759 * send_unified_ll_stats_get_sta_cmd_tlv() - unified link layer stats and get 6760 * station request 6761 * @wmi_handle: wmi handle 6762 * @get_req: ll stats get request command params 6763 * 6764 * Return: QDF_STATUS_SUCCESS for success or error code 6765 */ 6766 static QDF_STATUS send_unified_ll_stats_get_sta_cmd_tlv( 6767 wmi_unified_t wmi_handle, 6768 const struct ll_stats_get_params *get_req) 6769 { 6770 wmi_request_unified_ll_get_sta_cmd_fixed_param *unified_cmd; 6771 int32_t len; 6772 wmi_buf_t buf; 6773 void *buf_ptr; 6774 QDF_STATUS ret; 6775 bool is_ll_get_sta_stats_over_qmi; 6776 6777 len = sizeof(*unified_cmd); 6778 len += wmi_get_tlv_length_for_mlo_stats(get_req); 6779 6780 buf = wmi_buf_alloc(wmi_handle, len); 6781 if (!buf) 6782 return QDF_STATUS_E_NOMEM; 6783 6784 buf_ptr = wmi_buf_data(buf); 6785 6786 unified_cmd = buf_ptr; 6787 WMITLV_SET_HDR( 6788 &unified_cmd->tlv_header, 6789 WMITLV_TAG_STRUC_wmi_request_unified_ll_get_sta_cmd_fixed_param, 6790 WMITLV_GET_STRUCT_TLVLEN 6791 (wmi_request_unified_ll_get_sta_cmd_fixed_param)); 6792 6793 unified_cmd->link_stats_type = get_req->param_id_mask; 6794 unified_cmd->get_sta_stats_id = (WMI_REQUEST_AP_STAT | 6795 WMI_REQUEST_PEER_STAT | 6796 WMI_REQUEST_VDEV_STAT | 6797 WMI_REQUEST_PDEV_STAT | 6798 WMI_REQUEST_PEER_EXTD2_STAT | 6799 WMI_REQUEST_RSSI_PER_CHAIN_STAT); 6800 unified_cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 6801 wmi_handle, 6802 WMI_HOST_PDEV_ID_SOC); 6803 6804 unified_cmd->vdev_id = get_req->vdev_id; 6805 unified_cmd->request_id = get_req->req_id; 6806 WMI_CHAR_ARRAY_TO_MAC_ADDR(get_req->peer_macaddr.bytes, 6807 &unified_cmd->peer_macaddr); 6808 6809 wmi_debug("UNIFIED_LINK_STATS_GET_STA - Get Request Params Request ID: %u Stats Type: %0x Vdev ID: %d Peer MAC Addr: " 6810 QDF_MAC_ADDR_FMT, 6811 get_req->req_id, get_req->param_id_mask, get_req->vdev_id, 6812 QDF_MAC_ADDR_REF(get_req->peer_macaddr.bytes)); 6813 6814 wmi_update_tlv_headers_for_mlo_stats(get_req, buf_ptr); 6815 wmi_mtrace(WMI_REQUEST_UNIFIED_LL_GET_STA_CMDID, get_req->vdev_id, 0); 6816 6817 /** 6818 * FW support for LL_get_sta command. True represents the unified 6819 * ll_get_sta command should be sent over QMI always irrespective of 6820 * WOW state. 6821 */ 6822 is_ll_get_sta_stats_over_qmi = is_service_enabled_tlv( 6823 wmi_handle, 6824 WMI_SERVICE_UNIFIED_LL_GET_STA_OVER_QMI_SUPPORT); 6825 6826 if (is_ll_get_sta_stats_over_qmi) { 6827 ret = wmi_unified_cmd_send_over_qmi( 6828 wmi_handle, buf, len, 6829 WMI_REQUEST_UNIFIED_LL_GET_STA_CMDID); 6830 } else { 6831 ret = wmi_unified_cmd_send_pm_chk( 6832 wmi_handle, buf, len, 6833 WMI_REQUEST_UNIFIED_LL_GET_STA_CMDID, 6834 true); 6835 } 6836 6837 if (QDF_IS_STATUS_ERROR(ret)) { 6838 wmi_buf_free(buf); 6839 return QDF_STATUS_E_FAILURE; 6840 } 6841 6842 return ret; 6843 } 6844 #endif 6845 #endif /* WLAN_FEATURE_LINK_LAYER_STATS */ 6846 6847 /** 6848 * send_congestion_cmd_tlv() - send request to fw to get CCA 6849 * @wmi_handle: wmi handle 6850 * @vdev_id: vdev id 6851 * 6852 * Return: QDF status 6853 */ 6854 static QDF_STATUS send_congestion_cmd_tlv(wmi_unified_t wmi_handle, 6855 uint8_t vdev_id) 6856 { 6857 wmi_buf_t buf; 6858 wmi_request_stats_cmd_fixed_param *cmd; 6859 uint8_t len; 6860 uint8_t *buf_ptr; 6861 6862 len = sizeof(*cmd); 6863 buf = wmi_buf_alloc(wmi_handle, len); 6864 if (!buf) 6865 return QDF_STATUS_E_FAILURE; 6866 6867 buf_ptr = wmi_buf_data(buf); 6868 cmd = (wmi_request_stats_cmd_fixed_param *)buf_ptr; 6869 WMITLV_SET_HDR(&cmd->tlv_header, 6870 WMITLV_TAG_STRUC_wmi_request_stats_cmd_fixed_param, 6871 WMITLV_GET_STRUCT_TLVLEN 6872 (wmi_request_stats_cmd_fixed_param)); 6873 6874 cmd->stats_id = WMI_REQUEST_CONGESTION_STAT; 6875 cmd->vdev_id = vdev_id; 6876 wmi_debug("STATS REQ VDEV_ID:%d stats_id %d -->", 6877 cmd->vdev_id, cmd->stats_id); 6878 6879 wmi_mtrace(WMI_REQUEST_STATS_CMDID, cmd->vdev_id, 0); 6880 if (wmi_unified_cmd_send(wmi_handle, buf, len, 6881 WMI_REQUEST_STATS_CMDID)) { 6882 wmi_err("Failed to send WMI_REQUEST_STATS_CMDID"); 6883 wmi_buf_free(buf); 6884 return QDF_STATUS_E_FAILURE; 6885 } 6886 6887 return QDF_STATUS_SUCCESS; 6888 } 6889 6890 /** 6891 * send_snr_request_cmd_tlv() - send request to fw to get RSSI stats 6892 * @wmi_handle: wmi handle 6893 * 6894 * Return: QDF status 6895 */ 6896 static QDF_STATUS send_snr_request_cmd_tlv(wmi_unified_t wmi_handle) 6897 { 6898 wmi_buf_t buf; 6899 wmi_request_stats_cmd_fixed_param *cmd; 6900 uint8_t len = sizeof(wmi_request_stats_cmd_fixed_param); 6901 6902 buf = wmi_buf_alloc(wmi_handle, len); 6903 if (!buf) 6904 return QDF_STATUS_E_FAILURE; 6905 6906 cmd = (wmi_request_stats_cmd_fixed_param *) wmi_buf_data(buf); 6907 WMITLV_SET_HDR(&cmd->tlv_header, 6908 WMITLV_TAG_STRUC_wmi_request_stats_cmd_fixed_param, 6909 WMITLV_GET_STRUCT_TLVLEN 6910 (wmi_request_stats_cmd_fixed_param)); 6911 cmd->stats_id = WMI_REQUEST_VDEV_STAT; 6912 wmi_mtrace(WMI_REQUEST_STATS_CMDID, cmd->vdev_id, 0); 6913 if (wmi_unified_cmd_send(wmi_handle, buf, len, 6914 WMI_REQUEST_STATS_CMDID)) { 6915 wmi_err("Failed to send host stats request to fw"); 6916 wmi_buf_free(buf); 6917 return QDF_STATUS_E_FAILURE; 6918 } 6919 6920 return QDF_STATUS_SUCCESS; 6921 } 6922 6923 /** 6924 * send_snr_cmd_tlv() - get RSSI from fw 6925 * @wmi_handle: wmi handle 6926 * @vdev_id: vdev id 6927 * 6928 * Return: QDF status 6929 */ 6930 static QDF_STATUS send_snr_cmd_tlv(wmi_unified_t wmi_handle, uint8_t vdev_id) 6931 { 6932 wmi_buf_t buf; 6933 wmi_request_stats_cmd_fixed_param *cmd; 6934 uint8_t len = sizeof(wmi_request_stats_cmd_fixed_param); 6935 6936 buf = wmi_buf_alloc(wmi_handle, len); 6937 if (!buf) 6938 return QDF_STATUS_E_FAILURE; 6939 6940 cmd = (wmi_request_stats_cmd_fixed_param *) wmi_buf_data(buf); 6941 cmd->vdev_id = vdev_id; 6942 6943 WMITLV_SET_HDR(&cmd->tlv_header, 6944 WMITLV_TAG_STRUC_wmi_request_stats_cmd_fixed_param, 6945 WMITLV_GET_STRUCT_TLVLEN 6946 (wmi_request_stats_cmd_fixed_param)); 6947 cmd->stats_id = WMI_REQUEST_VDEV_STAT; 6948 wmi_mtrace(WMI_REQUEST_STATS_CMDID, cmd->vdev_id, 0); 6949 if (wmi_unified_cmd_send(wmi_handle, buf, len, 6950 WMI_REQUEST_STATS_CMDID)) { 6951 wmi_err("Failed to send host stats request to fw"); 6952 wmi_buf_free(buf); 6953 return QDF_STATUS_E_FAILURE; 6954 } 6955 6956 return QDF_STATUS_SUCCESS; 6957 } 6958 6959 /** 6960 * send_link_status_req_cmd_tlv() - process link status request from UMAC 6961 * @wmi_handle: wmi handle 6962 * @link_status: get link params 6963 * 6964 * Return: QDF status 6965 */ 6966 static QDF_STATUS send_link_status_req_cmd_tlv(wmi_unified_t wmi_handle, 6967 struct link_status_params *link_status) 6968 { 6969 wmi_buf_t buf; 6970 wmi_request_stats_cmd_fixed_param *cmd; 6971 uint8_t len = sizeof(wmi_request_stats_cmd_fixed_param); 6972 6973 buf = wmi_buf_alloc(wmi_handle, len); 6974 if (!buf) 6975 return QDF_STATUS_E_FAILURE; 6976 6977 cmd = (wmi_request_stats_cmd_fixed_param *) wmi_buf_data(buf); 6978 WMITLV_SET_HDR(&cmd->tlv_header, 6979 WMITLV_TAG_STRUC_wmi_request_stats_cmd_fixed_param, 6980 WMITLV_GET_STRUCT_TLVLEN 6981 (wmi_request_stats_cmd_fixed_param)); 6982 cmd->stats_id = WMI_REQUEST_VDEV_RATE_STAT; 6983 cmd->vdev_id = link_status->vdev_id; 6984 wmi_mtrace(WMI_REQUEST_STATS_CMDID, cmd->vdev_id, 0); 6985 if (wmi_unified_cmd_send(wmi_handle, buf, len, 6986 WMI_REQUEST_STATS_CMDID)) { 6987 wmi_err("Failed to send WMI link status request to fw"); 6988 wmi_buf_free(buf); 6989 return QDF_STATUS_E_FAILURE; 6990 } 6991 6992 return QDF_STATUS_SUCCESS; 6993 } 6994 6995 #ifdef WLAN_SUPPORT_GREEN_AP 6996 /** 6997 * send_egap_conf_params_cmd_tlv() - send wmi cmd of egap configuration params 6998 * @wmi_handle: wmi handler 6999 * @egap_params: pointer to egap_params 7000 * 7001 * Return: 0 for success, otherwise appropriate error code 7002 */ 7003 static QDF_STATUS send_egap_conf_params_cmd_tlv(wmi_unified_t wmi_handle, 7004 struct wlan_green_ap_egap_params *egap_params) 7005 { 7006 wmi_ap_ps_egap_param_cmd_fixed_param *cmd; 7007 wmi_buf_t buf; 7008 int32_t err; 7009 7010 buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd)); 7011 if (!buf) 7012 return QDF_STATUS_E_NOMEM; 7013 7014 cmd = (wmi_ap_ps_egap_param_cmd_fixed_param *) wmi_buf_data(buf); 7015 WMITLV_SET_HDR(&cmd->tlv_header, 7016 WMITLV_TAG_STRUC_wmi_ap_ps_egap_param_cmd_fixed_param, 7017 WMITLV_GET_STRUCT_TLVLEN( 7018 wmi_ap_ps_egap_param_cmd_fixed_param)); 7019 7020 cmd->enable = egap_params->host_enable_egap; 7021 cmd->inactivity_time = egap_params->egap_inactivity_time; 7022 cmd->wait_time = egap_params->egap_wait_time; 7023 cmd->flags = egap_params->egap_feature_flags; 7024 wmi_mtrace(WMI_AP_PS_EGAP_PARAM_CMDID, NO_SESSION, 0); 7025 err = wmi_unified_cmd_send(wmi_handle, buf, 7026 sizeof(*cmd), WMI_AP_PS_EGAP_PARAM_CMDID); 7027 if (err) { 7028 wmi_err("Failed to send ap_ps_egap cmd"); 7029 wmi_buf_free(buf); 7030 return QDF_STATUS_E_FAILURE; 7031 } 7032 7033 return QDF_STATUS_SUCCESS; 7034 } 7035 #endif 7036 7037 /** 7038 * send_csa_offload_enable_cmd_tlv() - send CSA offload enable command 7039 * @wmi_handle: wmi handle 7040 * @vdev_id: vdev id 7041 * 7042 * Return: QDF_STATUS_SUCCESS for success or error code 7043 */ 7044 static QDF_STATUS send_csa_offload_enable_cmd_tlv(wmi_unified_t wmi_handle, 7045 uint8_t vdev_id) 7046 { 7047 wmi_csa_offload_enable_cmd_fixed_param *cmd; 7048 wmi_buf_t buf; 7049 int32_t len = sizeof(*cmd); 7050 7051 wmi_debug("vdev_id %d", vdev_id); 7052 buf = wmi_buf_alloc(wmi_handle, len); 7053 if (!buf) 7054 return QDF_STATUS_E_NOMEM; 7055 7056 cmd = (wmi_csa_offload_enable_cmd_fixed_param *) wmi_buf_data(buf); 7057 WMITLV_SET_HDR(&cmd->tlv_header, 7058 WMITLV_TAG_STRUC_wmi_csa_offload_enable_cmd_fixed_param, 7059 WMITLV_GET_STRUCT_TLVLEN 7060 (wmi_csa_offload_enable_cmd_fixed_param)); 7061 cmd->vdev_id = vdev_id; 7062 cmd->csa_offload_enable = WMI_CSA_OFFLOAD_ENABLE; 7063 wmi_mtrace(WMI_CSA_OFFLOAD_ENABLE_CMDID, cmd->vdev_id, 0); 7064 if (wmi_unified_cmd_send(wmi_handle, buf, len, 7065 WMI_CSA_OFFLOAD_ENABLE_CMDID)) { 7066 wmi_err("Failed to send CSA offload enable command"); 7067 wmi_buf_free(buf); 7068 return QDF_STATUS_E_FAILURE; 7069 } 7070 7071 return 0; 7072 } 7073 7074 #ifdef WLAN_FEATURE_CIF_CFR 7075 /** 7076 * send_oem_dma_cfg_cmd_tlv() - configure OEM DMA rings 7077 * @wmi_handle: wmi handle 7078 * @cfg: dma cfg req 7079 * 7080 * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure 7081 */ 7082 static QDF_STATUS send_oem_dma_cfg_cmd_tlv(wmi_unified_t wmi_handle, 7083 wmi_oem_dma_ring_cfg_req_fixed_param *cfg) 7084 { 7085 wmi_buf_t buf; 7086 uint8_t *cmd; 7087 QDF_STATUS ret; 7088 7089 WMITLV_SET_HDR(cfg, 7090 WMITLV_TAG_STRUC_wmi_oem_dma_ring_cfg_req_fixed_param, 7091 (sizeof(*cfg) - WMI_TLV_HDR_SIZE)); 7092 7093 buf = wmi_buf_alloc(wmi_handle, sizeof(*cfg)); 7094 if (!buf) 7095 return QDF_STATUS_E_FAILURE; 7096 7097 cmd = (uint8_t *) wmi_buf_data(buf); 7098 qdf_mem_copy(cmd, cfg, sizeof(*cfg)); 7099 wmi_debug("Sending OEM Data Request to target, data len %lu", 7100 sizeof(*cfg)); 7101 wmi_mtrace(WMI_OEM_DMA_RING_CFG_REQ_CMDID, NO_SESSION, 0); 7102 ret = wmi_unified_cmd_send(wmi_handle, buf, sizeof(*cfg), 7103 WMI_OEM_DMA_RING_CFG_REQ_CMDID); 7104 if (QDF_IS_STATUS_ERROR(ret)) { 7105 wmi_err("Failed to send WMI_OEM_DMA_RING_CFG_REQ_CMDID"); 7106 wmi_buf_free(buf); 7107 } 7108 7109 return ret; 7110 } 7111 #endif 7112 7113 /** 7114 * send_start_11d_scan_cmd_tlv() - start 11d scan request 7115 * @wmi_handle: wmi handle 7116 * @start_11d_scan: 11d scan start request parameters 7117 * 7118 * This function request FW to start 11d scan. 7119 * 7120 * Return: QDF status 7121 */ 7122 static QDF_STATUS send_start_11d_scan_cmd_tlv(wmi_unified_t wmi_handle, 7123 struct reg_start_11d_scan_req *start_11d_scan) 7124 { 7125 wmi_11d_scan_start_cmd_fixed_param *cmd; 7126 int32_t len; 7127 wmi_buf_t buf; 7128 int ret; 7129 7130 len = sizeof(*cmd); 7131 buf = wmi_buf_alloc(wmi_handle, len); 7132 if (!buf) 7133 return QDF_STATUS_E_NOMEM; 7134 7135 cmd = (wmi_11d_scan_start_cmd_fixed_param *)wmi_buf_data(buf); 7136 7137 WMITLV_SET_HDR(&cmd->tlv_header, 7138 WMITLV_TAG_STRUC_wmi_11d_scan_start_cmd_fixed_param, 7139 WMITLV_GET_STRUCT_TLVLEN 7140 (wmi_11d_scan_start_cmd_fixed_param)); 7141 7142 cmd->vdev_id = start_11d_scan->vdev_id; 7143 cmd->scan_period_msec = start_11d_scan->scan_period_msec; 7144 cmd->start_interval_msec = start_11d_scan->start_interval_msec; 7145 7146 wmi_debug("vdev %d sending 11D scan start req", cmd->vdev_id); 7147 7148 wmi_mtrace(WMI_11D_SCAN_START_CMDID, cmd->vdev_id, 0); 7149 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 7150 WMI_11D_SCAN_START_CMDID); 7151 if (ret) { 7152 wmi_err("Failed to send start 11d scan wmi cmd"); 7153 wmi_buf_free(buf); 7154 return QDF_STATUS_E_FAILURE; 7155 } 7156 7157 return QDF_STATUS_SUCCESS; 7158 } 7159 7160 /** 7161 * send_stop_11d_scan_cmd_tlv() - stop 11d scan request 7162 * @wmi_handle: wmi handle 7163 * @stop_11d_scan: 11d scan stop request parameters 7164 * 7165 * This function request FW to stop 11d scan. 7166 * 7167 * Return: QDF status 7168 */ 7169 static QDF_STATUS send_stop_11d_scan_cmd_tlv(wmi_unified_t wmi_handle, 7170 struct reg_stop_11d_scan_req *stop_11d_scan) 7171 { 7172 wmi_11d_scan_stop_cmd_fixed_param *cmd; 7173 int32_t len; 7174 wmi_buf_t buf; 7175 int ret; 7176 7177 len = sizeof(*cmd); 7178 buf = wmi_buf_alloc(wmi_handle, len); 7179 if (!buf) 7180 return QDF_STATUS_E_NOMEM; 7181 7182 cmd = (wmi_11d_scan_stop_cmd_fixed_param *)wmi_buf_data(buf); 7183 7184 WMITLV_SET_HDR(&cmd->tlv_header, 7185 WMITLV_TAG_STRUC_wmi_11d_scan_stop_cmd_fixed_param, 7186 WMITLV_GET_STRUCT_TLVLEN 7187 (wmi_11d_scan_stop_cmd_fixed_param)); 7188 7189 cmd->vdev_id = stop_11d_scan->vdev_id; 7190 7191 wmi_debug("vdev %d sending 11D scan stop req", cmd->vdev_id); 7192 7193 wmi_mtrace(WMI_11D_SCAN_STOP_CMDID, cmd->vdev_id, 0); 7194 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 7195 WMI_11D_SCAN_STOP_CMDID); 7196 if (ret) { 7197 wmi_err("Failed to send stop 11d scan wmi cmd"); 7198 wmi_buf_free(buf); 7199 return QDF_STATUS_E_FAILURE; 7200 } 7201 7202 return QDF_STATUS_SUCCESS; 7203 } 7204 7205 /** 7206 * send_start_oem_data_cmd_tlv() - start OEM data request to target 7207 * @wmi_handle: wmi handle 7208 * @data_len: the length of @data 7209 * @data: the pointer to data buf 7210 * 7211 * Return: QDF status 7212 */ 7213 static QDF_STATUS send_start_oem_data_cmd_tlv(wmi_unified_t wmi_handle, 7214 uint32_t data_len, 7215 uint8_t *data) 7216 { 7217 wmi_buf_t buf; 7218 uint8_t *cmd; 7219 QDF_STATUS ret; 7220 7221 buf = wmi_buf_alloc(wmi_handle, 7222 (data_len + WMI_TLV_HDR_SIZE)); 7223 if (!buf) 7224 return QDF_STATUS_E_FAILURE; 7225 7226 cmd = (uint8_t *) wmi_buf_data(buf); 7227 7228 WMITLV_SET_HDR(cmd, WMITLV_TAG_ARRAY_BYTE, data_len); 7229 cmd += WMI_TLV_HDR_SIZE; 7230 qdf_mem_copy(cmd, data, 7231 data_len); 7232 7233 wmi_debug("Sending OEM Data Request to target, data len %d", data_len); 7234 7235 wmi_mtrace(WMI_OEM_REQ_CMDID, NO_SESSION, 0); 7236 ret = wmi_unified_cmd_send(wmi_handle, buf, 7237 (data_len + 7238 WMI_TLV_HDR_SIZE), WMI_OEM_REQ_CMDID); 7239 7240 if (QDF_IS_STATUS_ERROR(ret)) { 7241 wmi_err("Failed to send WMI_OEM_REQ_CMDID"); 7242 wmi_buf_free(buf); 7243 } 7244 7245 return ret; 7246 } 7247 7248 #ifdef FEATURE_OEM_DATA 7249 /** 7250 * send_start_oemv2_data_cmd_tlv() - start OEM data to target 7251 * @wmi_handle: wmi handle 7252 * @oem_data: the pointer to oem data 7253 * 7254 * Return: QDF status 7255 */ 7256 static QDF_STATUS send_start_oemv2_data_cmd_tlv(wmi_unified_t wmi_handle, 7257 struct oem_data *oem_data) 7258 { 7259 QDF_STATUS ret; 7260 wmi_oem_data_cmd_fixed_param *cmd; 7261 struct wmi_ops *ops; 7262 wmi_buf_t buf; 7263 uint16_t len = sizeof(*cmd); 7264 uint16_t oem_data_len_aligned; 7265 uint8_t *buf_ptr; 7266 uint32_t pdev_id; 7267 7268 if (!oem_data || !oem_data->data) { 7269 wmi_err_rl("oem data is not valid"); 7270 return QDF_STATUS_E_FAILURE; 7271 } 7272 7273 oem_data_len_aligned = roundup(oem_data->data_len, sizeof(uint32_t)); 7274 if (oem_data_len_aligned < oem_data->data_len) { 7275 wmi_err_rl("integer overflow while rounding up data_len"); 7276 return QDF_STATUS_E_FAILURE; 7277 } 7278 7279 if (oem_data_len_aligned > WMI_SVC_MSG_MAX_SIZE - WMI_TLV_HDR_SIZE) { 7280 wmi_err_rl("wmi_max_msg_size overflow for given data_len"); 7281 return QDF_STATUS_E_FAILURE; 7282 } 7283 7284 len += WMI_TLV_HDR_SIZE + oem_data_len_aligned; 7285 buf = wmi_buf_alloc(wmi_handle, len); 7286 if (!buf) 7287 return QDF_STATUS_E_NOMEM; 7288 7289 buf_ptr = (uint8_t *)wmi_buf_data(buf); 7290 cmd = (wmi_oem_data_cmd_fixed_param *)buf_ptr; 7291 WMITLV_SET_HDR(&cmd->tlv_header, 7292 WMITLV_TAG_STRUC_wmi_oem_data_cmd_fixed_param, 7293 WMITLV_GET_STRUCT_TLVLEN(wmi_oem_data_cmd_fixed_param)); 7294 7295 pdev_id = oem_data->pdev_id; 7296 if (oem_data->pdev_vdev_flag) { 7297 ops = wmi_handle->ops; 7298 if (oem_data->is_host_pdev_id) 7299 pdev_id = 7300 ops->convert_host_pdev_id_to_target(wmi_handle, 7301 pdev_id); 7302 else 7303 pdev_id = 7304 ops->convert_pdev_id_host_to_target(wmi_handle, 7305 pdev_id); 7306 } 7307 7308 cmd->vdev_id = oem_data->vdev_id; 7309 cmd->data_len = oem_data->data_len; 7310 cmd->pdev_vdev_flag = oem_data->pdev_vdev_flag; 7311 cmd->pdev_id = pdev_id; 7312 7313 buf_ptr += sizeof(*cmd); 7314 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, oem_data_len_aligned); 7315 buf_ptr += WMI_TLV_HDR_SIZE; 7316 qdf_mem_copy(buf_ptr, oem_data->data, oem_data->data_len); 7317 7318 wmi_mtrace(WMI_OEM_DATA_CMDID, NO_SESSION, 0); 7319 ret = wmi_unified_cmd_send(wmi_handle, buf, len, WMI_OEM_DATA_CMDID); 7320 if (QDF_IS_STATUS_ERROR(ret)) { 7321 wmi_err_rl("Failed with ret = %d", ret); 7322 wmi_buf_free(buf); 7323 } 7324 7325 return ret; 7326 } 7327 #endif 7328 7329 /** 7330 * send_dfs_phyerr_filter_offload_en_cmd_tlv() - enable dfs phyerr filter 7331 * @wmi_handle: wmi handle 7332 * @dfs_phyerr_filter_offload: is dfs phyerr filter offload 7333 * 7334 * Send WMI_DFS_PHYERR_FILTER_ENA_CMDID or 7335 * WMI_DFS_PHYERR_FILTER_DIS_CMDID command 7336 * to firmware based on phyerr filtering 7337 * offload status. 7338 * 7339 * Return: 1 success, 0 failure 7340 */ 7341 static QDF_STATUS 7342 send_dfs_phyerr_filter_offload_en_cmd_tlv(wmi_unified_t wmi_handle, 7343 bool dfs_phyerr_filter_offload) 7344 { 7345 wmi_dfs_phyerr_filter_ena_cmd_fixed_param *enable_phyerr_offload_cmd; 7346 wmi_dfs_phyerr_filter_dis_cmd_fixed_param *disable_phyerr_offload_cmd; 7347 wmi_buf_t buf; 7348 uint16_t len; 7349 QDF_STATUS ret; 7350 7351 7352 if (false == dfs_phyerr_filter_offload) { 7353 wmi_debug("Phyerror Filtering offload is Disabled in ini"); 7354 len = sizeof(*disable_phyerr_offload_cmd); 7355 buf = wmi_buf_alloc(wmi_handle, len); 7356 if (!buf) 7357 return 0; 7358 7359 disable_phyerr_offload_cmd = 7360 (wmi_dfs_phyerr_filter_dis_cmd_fixed_param *) 7361 wmi_buf_data(buf); 7362 7363 WMITLV_SET_HDR(&disable_phyerr_offload_cmd->tlv_header, 7364 WMITLV_TAG_STRUC_wmi_dfs_phyerr_filter_dis_cmd_fixed_param, 7365 WMITLV_GET_STRUCT_TLVLEN 7366 (wmi_dfs_phyerr_filter_dis_cmd_fixed_param)); 7367 7368 /* 7369 * Send WMI_DFS_PHYERR_FILTER_DIS_CMDID 7370 * to the firmware to disable the phyerror 7371 * filtering offload. 7372 */ 7373 wmi_mtrace(WMI_DFS_PHYERR_FILTER_DIS_CMDID, NO_SESSION, 0); 7374 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 7375 WMI_DFS_PHYERR_FILTER_DIS_CMDID); 7376 if (QDF_IS_STATUS_ERROR(ret)) { 7377 wmi_err("Failed to send WMI_DFS_PHYERR_FILTER_DIS_CMDID ret=%d", 7378 ret); 7379 wmi_buf_free(buf); 7380 return QDF_STATUS_E_FAILURE; 7381 } 7382 wmi_debug("WMI_DFS_PHYERR_FILTER_DIS_CMDID Send Success"); 7383 } else { 7384 wmi_debug("Phyerror Filtering offload is Enabled in ini"); 7385 7386 len = sizeof(*enable_phyerr_offload_cmd); 7387 buf = wmi_buf_alloc(wmi_handle, len); 7388 if (!buf) 7389 return QDF_STATUS_E_FAILURE; 7390 7391 enable_phyerr_offload_cmd = 7392 (wmi_dfs_phyerr_filter_ena_cmd_fixed_param *) 7393 wmi_buf_data(buf); 7394 7395 WMITLV_SET_HDR(&enable_phyerr_offload_cmd->tlv_header, 7396 WMITLV_TAG_STRUC_wmi_dfs_phyerr_filter_ena_cmd_fixed_param, 7397 WMITLV_GET_STRUCT_TLVLEN 7398 (wmi_dfs_phyerr_filter_ena_cmd_fixed_param)); 7399 7400 /* 7401 * Send a WMI_DFS_PHYERR_FILTER_ENA_CMDID 7402 * to the firmware to enable the phyerror 7403 * filtering offload. 7404 */ 7405 wmi_mtrace(WMI_DFS_PHYERR_FILTER_ENA_CMDID, NO_SESSION, 0); 7406 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 7407 WMI_DFS_PHYERR_FILTER_ENA_CMDID); 7408 7409 if (QDF_IS_STATUS_ERROR(ret)) { 7410 wmi_err("Failed to send DFS PHYERR CMD ret=%d", ret); 7411 wmi_buf_free(buf); 7412 return QDF_STATUS_E_FAILURE; 7413 } 7414 wmi_debug("WMI_DFS_PHYERR_FILTER_ENA_CMDID Send Success"); 7415 } 7416 7417 return QDF_STATUS_SUCCESS; 7418 } 7419 7420 #if !defined(REMOVE_PKT_LOG) && defined(FEATURE_PKTLOG) 7421 /** 7422 * send_pktlog_wmi_send_cmd_tlv() - send pktlog enable/disable command to target 7423 * @wmi_handle: wmi handle 7424 * @pktlog_event: pktlog event 7425 * @cmd_id: pktlog cmd id 7426 * @user_triggered: user triggered input for PKTLOG enable mode 7427 * 7428 * Return: QDF status 7429 */ 7430 static QDF_STATUS send_pktlog_wmi_send_cmd_tlv(wmi_unified_t wmi_handle, 7431 WMI_PKTLOG_EVENT pktlog_event, 7432 WMI_CMD_ID cmd_id, uint8_t user_triggered) 7433 { 7434 WMI_PKTLOG_EVENT PKTLOG_EVENT; 7435 WMI_CMD_ID CMD_ID; 7436 wmi_pdev_pktlog_enable_cmd_fixed_param *cmd; 7437 wmi_pdev_pktlog_disable_cmd_fixed_param *disable_cmd; 7438 int len = 0; 7439 wmi_buf_t buf; 7440 int32_t idx, max_idx; 7441 7442 PKTLOG_EVENT = pktlog_event; 7443 CMD_ID = cmd_id; 7444 7445 max_idx = sizeof(pktlog_event_tlv) / (sizeof(pktlog_event_tlv[0])); 7446 switch (CMD_ID) { 7447 case WMI_PDEV_PKTLOG_ENABLE_CMDID: 7448 len = sizeof(*cmd); 7449 buf = wmi_buf_alloc(wmi_handle, len); 7450 if (!buf) 7451 return QDF_STATUS_E_NOMEM; 7452 7453 cmd = (wmi_pdev_pktlog_enable_cmd_fixed_param *) 7454 wmi_buf_data(buf); 7455 WMITLV_SET_HDR(&cmd->tlv_header, 7456 WMITLV_TAG_STRUC_wmi_pdev_pktlog_enable_cmd_fixed_param, 7457 WMITLV_GET_STRUCT_TLVLEN 7458 (wmi_pdev_pktlog_enable_cmd_fixed_param)); 7459 cmd->evlist = 0; 7460 for (idx = 0; idx < max_idx; idx++) { 7461 if (PKTLOG_EVENT & (1 << idx)) 7462 cmd->evlist |= pktlog_event_tlv[idx]; 7463 } 7464 cmd->enable = user_triggered ? WMI_PKTLOG_ENABLE_FORCE 7465 : WMI_PKTLOG_ENABLE_AUTO; 7466 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 7467 wmi_handle, 7468 WMI_HOST_PDEV_ID_SOC); 7469 wmi_mtrace(WMI_PDEV_PKTLOG_ENABLE_CMDID, NO_SESSION, 0); 7470 if (wmi_unified_cmd_send(wmi_handle, buf, len, 7471 WMI_PDEV_PKTLOG_ENABLE_CMDID)) { 7472 wmi_err("Failed to send pktlog enable cmdid"); 7473 goto wmi_send_failed; 7474 } 7475 break; 7476 case WMI_PDEV_PKTLOG_DISABLE_CMDID: 7477 len = sizeof(*disable_cmd); 7478 buf = wmi_buf_alloc(wmi_handle, len); 7479 if (!buf) 7480 return QDF_STATUS_E_NOMEM; 7481 7482 disable_cmd = (wmi_pdev_pktlog_disable_cmd_fixed_param *) 7483 wmi_buf_data(buf); 7484 WMITLV_SET_HDR(&disable_cmd->tlv_header, 7485 WMITLV_TAG_STRUC_wmi_pdev_pktlog_disable_cmd_fixed_param, 7486 WMITLV_GET_STRUCT_TLVLEN 7487 (wmi_pdev_pktlog_disable_cmd_fixed_param)); 7488 disable_cmd->pdev_id = 7489 wmi_handle->ops->convert_pdev_id_host_to_target( 7490 wmi_handle, 7491 WMI_HOST_PDEV_ID_SOC); 7492 wmi_mtrace(WMI_PDEV_PKTLOG_DISABLE_CMDID, NO_SESSION, 0); 7493 if (wmi_unified_cmd_send(wmi_handle, buf, len, 7494 WMI_PDEV_PKTLOG_DISABLE_CMDID)) { 7495 wmi_err("failed to send pktlog disable cmdid"); 7496 goto wmi_send_failed; 7497 } 7498 break; 7499 default: 7500 wmi_debug("Invalid PKTLOG command: %d", CMD_ID); 7501 break; 7502 } 7503 7504 return QDF_STATUS_SUCCESS; 7505 7506 wmi_send_failed: 7507 wmi_buf_free(buf); 7508 return QDF_STATUS_E_FAILURE; 7509 } 7510 #endif /* !REMOVE_PKT_LOG && FEATURE_PKTLOG */ 7511 7512 /** 7513 * send_stats_ext_req_cmd_tlv() - request ext stats from fw 7514 * @wmi_handle: wmi handle 7515 * @preq: stats ext params 7516 * 7517 * Return: QDF status 7518 */ 7519 static QDF_STATUS send_stats_ext_req_cmd_tlv(wmi_unified_t wmi_handle, 7520 struct stats_ext_params *preq) 7521 { 7522 QDF_STATUS ret; 7523 wmi_req_stats_ext_cmd_fixed_param *cmd; 7524 wmi_buf_t buf; 7525 size_t len; 7526 uint8_t *buf_ptr; 7527 uint16_t max_wmi_msg_size = wmi_get_max_msg_len(wmi_handle); 7528 uint32_t *vdev_bitmap; 7529 7530 if (preq->request_data_len > (max_wmi_msg_size - WMI_TLV_HDR_SIZE - 7531 sizeof(*cmd))) { 7532 wmi_err("Data length=%d is greater than max wmi msg size", 7533 preq->request_data_len); 7534 return QDF_STATUS_E_FAILURE; 7535 } 7536 7537 len = sizeof(*cmd) + WMI_TLV_HDR_SIZE + preq->request_data_len + 7538 WMI_TLV_HDR_SIZE + sizeof(uint32_t); 7539 7540 buf = wmi_buf_alloc(wmi_handle, len); 7541 if (!buf) 7542 return QDF_STATUS_E_NOMEM; 7543 7544 buf_ptr = (uint8_t *) wmi_buf_data(buf); 7545 cmd = (wmi_req_stats_ext_cmd_fixed_param *) buf_ptr; 7546 7547 WMITLV_SET_HDR(&cmd->tlv_header, 7548 WMITLV_TAG_STRUC_wmi_req_stats_ext_cmd_fixed_param, 7549 WMITLV_GET_STRUCT_TLVLEN 7550 (wmi_req_stats_ext_cmd_fixed_param)); 7551 cmd->vdev_id = preq->vdev_id; 7552 cmd->data_len = preq->request_data_len; 7553 7554 wmi_debug("The data len value is %u and vdev id set is %u", 7555 preq->request_data_len, preq->vdev_id); 7556 7557 buf_ptr += sizeof(wmi_req_stats_ext_cmd_fixed_param); 7558 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, cmd->data_len); 7559 7560 buf_ptr += WMI_TLV_HDR_SIZE; 7561 qdf_mem_copy(buf_ptr, preq->request_data, cmd->data_len); 7562 7563 buf_ptr += cmd->data_len; 7564 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, sizeof(uint32_t)); 7565 7566 buf_ptr += WMI_TLV_HDR_SIZE; 7567 7568 vdev_bitmap = (A_UINT32 *)buf_ptr; 7569 7570 vdev_bitmap[0] = preq->vdev_id_bitmap; 7571 7572 wmi_debug("Sending MLO vdev_id_bitmap:%x", vdev_bitmap[0]); 7573 7574 buf_ptr += sizeof(uint32_t); 7575 7576 wmi_mtrace(WMI_REQUEST_STATS_EXT_CMDID, cmd->vdev_id, 0); 7577 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 7578 WMI_REQUEST_STATS_EXT_CMDID); 7579 if (QDF_IS_STATUS_ERROR(ret)) { 7580 wmi_err("Failed to send notify cmd ret = %d", ret); 7581 wmi_buf_free(buf); 7582 } 7583 7584 return ret; 7585 } 7586 7587 /** 7588 * send_process_dhcpserver_offload_cmd_tlv() - enable DHCP server offload 7589 * @wmi_handle: wmi handle 7590 * @params: DHCP server offload info 7591 * 7592 * Return: QDF_STATUS_SUCCESS for success or error code 7593 */ 7594 static QDF_STATUS 7595 send_process_dhcpserver_offload_cmd_tlv(wmi_unified_t wmi_handle, 7596 struct dhcp_offload_info_params *params) 7597 { 7598 wmi_set_dhcp_server_offload_cmd_fixed_param *cmd; 7599 wmi_buf_t buf; 7600 QDF_STATUS status; 7601 7602 buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd)); 7603 if (!buf) 7604 return QDF_STATUS_E_NOMEM; 7605 7606 cmd = (wmi_set_dhcp_server_offload_cmd_fixed_param *) wmi_buf_data(buf); 7607 7608 WMITLV_SET_HDR(&cmd->tlv_header, 7609 WMITLV_TAG_STRUC_wmi_set_dhcp_server_offload_cmd_fixed_param, 7610 WMITLV_GET_STRUCT_TLVLEN 7611 (wmi_set_dhcp_server_offload_cmd_fixed_param)); 7612 cmd->vdev_id = params->vdev_id; 7613 cmd->enable = params->dhcp_offload_enabled; 7614 cmd->num_client = params->dhcp_client_num; 7615 cmd->srv_ipv4 = params->dhcp_srv_addr; 7616 cmd->start_lsb = 0; 7617 wmi_mtrace(WMI_SET_DHCP_SERVER_OFFLOAD_CMDID, cmd->vdev_id, 0); 7618 status = wmi_unified_cmd_send(wmi_handle, buf, 7619 sizeof(*cmd), 7620 WMI_SET_DHCP_SERVER_OFFLOAD_CMDID); 7621 if (QDF_IS_STATUS_ERROR(status)) { 7622 wmi_err("Failed to send set_dhcp_server_offload cmd"); 7623 wmi_buf_free(buf); 7624 return QDF_STATUS_E_FAILURE; 7625 } 7626 wmi_debug("Set dhcp server offload to vdevId %d", params->vdev_id); 7627 7628 return status; 7629 } 7630 7631 /** 7632 * send_pdev_set_regdomain_cmd_tlv() - send set regdomain command to fw 7633 * @wmi_handle: wmi handle 7634 * @param: pointer to pdev regdomain params 7635 * 7636 * Return: QDF_STATUS_SUCCESS for success or error code 7637 */ 7638 static QDF_STATUS 7639 send_pdev_set_regdomain_cmd_tlv(wmi_unified_t wmi_handle, 7640 struct pdev_set_regdomain_params *param) 7641 { 7642 wmi_buf_t buf; 7643 wmi_pdev_set_regdomain_cmd_fixed_param *cmd; 7644 int32_t len = sizeof(*cmd); 7645 7646 buf = wmi_buf_alloc(wmi_handle, len); 7647 if (!buf) 7648 return QDF_STATUS_E_NOMEM; 7649 7650 cmd = (wmi_pdev_set_regdomain_cmd_fixed_param *) wmi_buf_data(buf); 7651 WMITLV_SET_HDR(&cmd->tlv_header, 7652 WMITLV_TAG_STRUC_wmi_pdev_set_regdomain_cmd_fixed_param, 7653 WMITLV_GET_STRUCT_TLVLEN 7654 (wmi_pdev_set_regdomain_cmd_fixed_param)); 7655 7656 cmd->reg_domain = param->currentRDinuse; 7657 cmd->reg_domain_2G = param->currentRD2G; 7658 cmd->reg_domain_5G = param->currentRD5G; 7659 cmd->conformance_test_limit_2G = param->ctl_2G; 7660 cmd->conformance_test_limit_5G = param->ctl_5G; 7661 cmd->dfs_domain = param->dfsDomain; 7662 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 7663 wmi_handle, 7664 param->pdev_id); 7665 7666 wmi_mtrace(WMI_PDEV_SET_REGDOMAIN_CMDID, NO_SESSION, 0); 7667 if (wmi_unified_cmd_send(wmi_handle, buf, len, 7668 WMI_PDEV_SET_REGDOMAIN_CMDID)) { 7669 wmi_err("Failed to send pdev set regdomain command"); 7670 wmi_buf_free(buf); 7671 return QDF_STATUS_E_FAILURE; 7672 } 7673 7674 return QDF_STATUS_SUCCESS; 7675 } 7676 7677 /** 7678 * send_regdomain_info_to_fw_cmd_tlv() - send regdomain info to fw 7679 * @wmi_handle: wmi handle 7680 * @reg_dmn: reg domain 7681 * @regdmn2G: 2G reg domain 7682 * @regdmn5G: 5G reg domain 7683 * @ctl2G: 2G test limit 7684 * @ctl5G: 5G test limit 7685 * 7686 * Return: none 7687 */ 7688 static QDF_STATUS send_regdomain_info_to_fw_cmd_tlv(wmi_unified_t wmi_handle, 7689 uint32_t reg_dmn, uint16_t regdmn2G, 7690 uint16_t regdmn5G, uint8_t ctl2G, 7691 uint8_t ctl5G) 7692 { 7693 wmi_buf_t buf; 7694 wmi_pdev_set_regdomain_cmd_fixed_param *cmd; 7695 int32_t len = sizeof(*cmd); 7696 7697 7698 buf = wmi_buf_alloc(wmi_handle, len); 7699 if (!buf) 7700 return QDF_STATUS_E_NOMEM; 7701 7702 cmd = (wmi_pdev_set_regdomain_cmd_fixed_param *) wmi_buf_data(buf); 7703 WMITLV_SET_HDR(&cmd->tlv_header, 7704 WMITLV_TAG_STRUC_wmi_pdev_set_regdomain_cmd_fixed_param, 7705 WMITLV_GET_STRUCT_TLVLEN 7706 (wmi_pdev_set_regdomain_cmd_fixed_param)); 7707 cmd->reg_domain = reg_dmn; 7708 cmd->reg_domain_2G = regdmn2G; 7709 cmd->reg_domain_5G = regdmn5G; 7710 cmd->conformance_test_limit_2G = ctl2G; 7711 cmd->conformance_test_limit_5G = ctl5G; 7712 7713 wmi_debug("regd = %x, regd_2g = %x, regd_5g = %x, ctl_2g = %x, ctl_5g = %x", 7714 cmd->reg_domain, cmd->reg_domain_2G, cmd->reg_domain_5G, 7715 cmd->conformance_test_limit_2G, 7716 cmd->conformance_test_limit_5G); 7717 7718 wmi_mtrace(WMI_PDEV_SET_REGDOMAIN_CMDID, NO_SESSION, 0); 7719 if (wmi_unified_cmd_send(wmi_handle, buf, len, 7720 WMI_PDEV_SET_REGDOMAIN_CMDID)) { 7721 wmi_err("Failed to send pdev set regdomain command"); 7722 wmi_buf_free(buf); 7723 return QDF_STATUS_E_FAILURE; 7724 } 7725 7726 return QDF_STATUS_SUCCESS; 7727 } 7728 7729 /** 7730 * copy_custom_aggr_bitmap() - copies host side bitmap using FW APIs 7731 * @param: param sent from the host side 7732 * @cmd: param to be sent to the fw side 7733 */ 7734 static inline void copy_custom_aggr_bitmap( 7735 struct set_custom_aggr_size_params *param, 7736 wmi_vdev_set_custom_aggr_size_cmd_fixed_param *cmd) 7737 { 7738 WMI_VDEV_CUSTOM_AGGR_AC_SET(cmd->enable_bitmap, 7739 param->ac); 7740 WMI_VDEV_CUSTOM_AGGR_TYPE_SET(cmd->enable_bitmap, 7741 param->aggr_type); 7742 WMI_VDEV_CUSTOM_TX_AGGR_SZ_DIS_SET(cmd->enable_bitmap, 7743 param->tx_aggr_size_disable); 7744 WMI_VDEV_CUSTOM_RX_AGGR_SZ_DIS_SET(cmd->enable_bitmap, 7745 param->rx_aggr_size_disable); 7746 WMI_VDEV_CUSTOM_TX_AC_EN_SET(cmd->enable_bitmap, 7747 param->tx_ac_enable); 7748 WMI_VDEV_CUSTOM_AGGR_256_BA_EN_SET(cmd->enable_bitmap, 7749 param->aggr_ba_enable); 7750 } 7751 7752 /** 7753 * send_vdev_set_custom_aggr_size_cmd_tlv() - custom aggr size param in fw 7754 * @wmi_handle: wmi handle 7755 * @param: pointer to hold custom aggr size params 7756 * 7757 * Return: QDF_STATUS_SUCCESS for success or error code 7758 */ 7759 static QDF_STATUS send_vdev_set_custom_aggr_size_cmd_tlv( 7760 wmi_unified_t wmi_handle, 7761 struct set_custom_aggr_size_params *param) 7762 { 7763 wmi_vdev_set_custom_aggr_size_cmd_fixed_param *cmd; 7764 wmi_buf_t buf; 7765 int32_t len = sizeof(*cmd); 7766 7767 buf = wmi_buf_alloc(wmi_handle, len); 7768 if (!buf) 7769 return QDF_STATUS_E_FAILURE; 7770 7771 cmd = (wmi_vdev_set_custom_aggr_size_cmd_fixed_param *) 7772 wmi_buf_data(buf); 7773 WMITLV_SET_HDR(&cmd->tlv_header, 7774 WMITLV_TAG_STRUC_wmi_vdev_set_custom_aggr_size_cmd_fixed_param, 7775 WMITLV_GET_STRUCT_TLVLEN( 7776 wmi_vdev_set_custom_aggr_size_cmd_fixed_param)); 7777 cmd->vdev_id = param->vdev_id; 7778 cmd->tx_aggr_size = param->tx_aggr_size; 7779 cmd->rx_aggr_size = param->rx_aggr_size; 7780 copy_custom_aggr_bitmap(param, cmd); 7781 7782 wmi_debug("Set custom aggr: vdev id=0x%X, tx aggr size=0x%X " 7783 "rx_aggr_size=0x%X access category=0x%X, agg_type=0x%X " 7784 "tx_aggr_size_disable=0x%X, rx_aggr_size_disable=0x%X " 7785 "tx_ac_enable=0x%X", 7786 param->vdev_id, param->tx_aggr_size, param->rx_aggr_size, 7787 param->ac, param->aggr_type, param->tx_aggr_size_disable, 7788 param->rx_aggr_size_disable, param->tx_ac_enable); 7789 7790 wmi_mtrace(WMI_VDEV_SET_CUSTOM_AGGR_SIZE_CMDID, cmd->vdev_id, 0); 7791 if (wmi_unified_cmd_send(wmi_handle, buf, len, 7792 WMI_VDEV_SET_CUSTOM_AGGR_SIZE_CMDID)) { 7793 wmi_err("Setting custom aggregation size failed"); 7794 wmi_buf_free(buf); 7795 return QDF_STATUS_E_FAILURE; 7796 } 7797 7798 return QDF_STATUS_SUCCESS; 7799 } 7800 7801 /** 7802 * send_vdev_set_qdepth_thresh_cmd_tlv() - WMI set qdepth threshold 7803 * @wmi_handle: handle to WMI. 7804 * @param: pointer to tx antenna param 7805 * 7806 * Return: QDF_STATUS_SUCCESS for success or error code 7807 */ 7808 7809 static QDF_STATUS send_vdev_set_qdepth_thresh_cmd_tlv(wmi_unified_t wmi_handle, 7810 struct set_qdepth_thresh_params *param) 7811 { 7812 wmi_peer_tid_msduq_qdepth_thresh_update_cmd_fixed_param *cmd; 7813 wmi_msduq_qdepth_thresh_update *cmd_update; 7814 wmi_buf_t buf; 7815 int32_t len = 0; 7816 int i; 7817 uint8_t *buf_ptr; 7818 QDF_STATUS ret; 7819 7820 if (param->num_of_msduq_updates > QDEPTH_THRESH_MAX_UPDATES) { 7821 wmi_err("Invalid Update Count!"); 7822 return QDF_STATUS_E_INVAL; 7823 } 7824 7825 len = sizeof(*cmd) + WMI_TLV_HDR_SIZE; 7826 len += (sizeof(wmi_msduq_qdepth_thresh_update) * 7827 param->num_of_msduq_updates); 7828 buf = wmi_buf_alloc(wmi_handle, len); 7829 7830 if (!buf) 7831 return QDF_STATUS_E_NOMEM; 7832 7833 buf_ptr = (uint8_t *)wmi_buf_data(buf); 7834 cmd = (wmi_peer_tid_msduq_qdepth_thresh_update_cmd_fixed_param *) 7835 buf_ptr; 7836 7837 WMITLV_SET_HDR(&cmd->tlv_header, 7838 WMITLV_TAG_STRUC_wmi_peer_tid_msduq_qdepth_thresh_update_cmd_fixed_param 7839 , WMITLV_GET_STRUCT_TLVLEN( 7840 wmi_peer_tid_msduq_qdepth_thresh_update_cmd_fixed_param)); 7841 7842 cmd->pdev_id = 7843 wmi_handle->ops->convert_pdev_id_host_to_target( 7844 wmi_handle, 7845 param->pdev_id); 7846 cmd->vdev_id = param->vdev_id; 7847 WMI_CHAR_ARRAY_TO_MAC_ADDR(param->mac_addr, &cmd->peer_mac_address); 7848 cmd->num_of_msduq_updates = param->num_of_msduq_updates; 7849 7850 buf_ptr += sizeof( 7851 wmi_peer_tid_msduq_qdepth_thresh_update_cmd_fixed_param); 7852 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 7853 param->num_of_msduq_updates * 7854 sizeof(wmi_msduq_qdepth_thresh_update)); 7855 buf_ptr += WMI_TLV_HDR_SIZE; 7856 cmd_update = (wmi_msduq_qdepth_thresh_update *)buf_ptr; 7857 7858 for (i = 0; i < cmd->num_of_msduq_updates; i++) { 7859 WMITLV_SET_HDR(&cmd_update->tlv_header, 7860 WMITLV_TAG_STRUC_wmi_msduq_qdepth_thresh_update, 7861 WMITLV_GET_STRUCT_TLVLEN( 7862 wmi_msduq_qdepth_thresh_update)); 7863 cmd_update->tid_num = param->update_params[i].tid_num; 7864 cmd_update->msduq_update_mask = 7865 param->update_params[i].msduq_update_mask; 7866 cmd_update->qdepth_thresh_value = 7867 param->update_params[i].qdepth_thresh_value; 7868 wmi_debug("Set QDepth Threshold: vdev=0x%X pdev=0x%X, tid=0x%X " 7869 "mac_addr_upper4=%X, mac_addr_lower2:%X," 7870 " update mask=0x%X thresh val=0x%X", 7871 cmd->vdev_id, cmd->pdev_id, cmd_update->tid_num, 7872 cmd->peer_mac_address.mac_addr31to0, 7873 cmd->peer_mac_address.mac_addr47to32, 7874 cmd_update->msduq_update_mask, 7875 cmd_update->qdepth_thresh_value); 7876 cmd_update++; 7877 } 7878 7879 wmi_mtrace(WMI_PEER_TID_MSDUQ_QDEPTH_THRESH_UPDATE_CMDID, 7880 cmd->vdev_id, 0); 7881 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 7882 WMI_PEER_TID_MSDUQ_QDEPTH_THRESH_UPDATE_CMDID); 7883 7884 if (ret != 0) { 7885 wmi_err("Failed to send WMI_PEER_TID_MSDUQ_QDEPTH_THRESH_UPDATE_CMDID"); 7886 wmi_buf_free(buf); 7887 } 7888 7889 return ret; 7890 } 7891 7892 /** 7893 * send_set_vap_dscp_tid_map_cmd_tlv() - send vap dscp tid map cmd to fw 7894 * @wmi_handle: wmi handle 7895 * @param: pointer to hold vap dscp tid map param 7896 * 7897 * Return: QDF_STATUS_SUCCESS for success or error code 7898 */ 7899 static QDF_STATUS 7900 send_set_vap_dscp_tid_map_cmd_tlv(wmi_unified_t wmi_handle, 7901 struct vap_dscp_tid_map_params *param) 7902 { 7903 wmi_buf_t buf; 7904 wmi_vdev_set_dscp_tid_map_cmd_fixed_param *cmd; 7905 int32_t len = sizeof(*cmd); 7906 7907 buf = wmi_buf_alloc(wmi_handle, len); 7908 if (!buf) 7909 return QDF_STATUS_E_FAILURE; 7910 7911 cmd = (wmi_vdev_set_dscp_tid_map_cmd_fixed_param *)wmi_buf_data(buf); 7912 qdf_mem_copy(cmd->dscp_to_tid_map, param->dscp_to_tid_map, 7913 sizeof(uint32_t) * WMI_DSCP_MAP_MAX); 7914 7915 cmd->vdev_id = param->vdev_id; 7916 cmd->enable_override = 0; 7917 7918 wmi_debug("Setting dscp for vap id: %d", cmd->vdev_id); 7919 wmi_mtrace(WMI_VDEV_SET_DSCP_TID_MAP_CMDID, cmd->vdev_id, 0); 7920 if (wmi_unified_cmd_send(wmi_handle, buf, len, 7921 WMI_VDEV_SET_DSCP_TID_MAP_CMDID)) { 7922 wmi_err("Failed to set dscp cmd"); 7923 wmi_buf_free(buf); 7924 return QDF_STATUS_E_FAILURE; 7925 } 7926 7927 return QDF_STATUS_SUCCESS; 7928 } 7929 7930 /** 7931 * send_vdev_set_fwtest_param_cmd_tlv() - send fwtest param in fw 7932 * @wmi_handle: wmi handle 7933 * @param: pointer to hold fwtest param 7934 * 7935 * Return: QDF_STATUS_SUCCESS for success or error code 7936 */ 7937 static QDF_STATUS send_vdev_set_fwtest_param_cmd_tlv(wmi_unified_t wmi_handle, 7938 struct set_fwtest_params *param) 7939 { 7940 wmi_fwtest_set_param_cmd_fixed_param *cmd; 7941 wmi_buf_t buf; 7942 int32_t len = sizeof(*cmd); 7943 7944 buf = wmi_buf_alloc(wmi_handle, len); 7945 7946 if (!buf) 7947 return QDF_STATUS_E_FAILURE; 7948 7949 cmd = (wmi_fwtest_set_param_cmd_fixed_param *)wmi_buf_data(buf); 7950 WMITLV_SET_HDR(&cmd->tlv_header, 7951 WMITLV_TAG_STRUC_wmi_fwtest_set_param_cmd_fixed_param, 7952 WMITLV_GET_STRUCT_TLVLEN( 7953 wmi_fwtest_set_param_cmd_fixed_param)); 7954 cmd->param_id = param->arg; 7955 cmd->param_value = param->value; 7956 7957 wmi_mtrace(WMI_FWTEST_CMDID, NO_SESSION, 0); 7958 if (wmi_unified_cmd_send(wmi_handle, buf, len, WMI_FWTEST_CMDID)) { 7959 wmi_err("Setting FW test param failed"); 7960 wmi_buf_free(buf); 7961 return QDF_STATUS_E_FAILURE; 7962 } 7963 7964 return QDF_STATUS_SUCCESS; 7965 } 7966 7967 /** 7968 * send_phyerr_disable_cmd_tlv() - WMI phyerr disable function 7969 * @wmi_handle: handle to WMI. 7970 * 7971 * Return: QDF_STATUS_SUCCESS for success or error code 7972 */ 7973 static QDF_STATUS send_phyerr_disable_cmd_tlv(wmi_unified_t wmi_handle) 7974 { 7975 wmi_pdev_dfs_disable_cmd_fixed_param *cmd; 7976 wmi_buf_t buf; 7977 QDF_STATUS ret; 7978 int32_t len; 7979 7980 len = sizeof(*cmd); 7981 7982 buf = wmi_buf_alloc(wmi_handle, len); 7983 if (!buf) 7984 return QDF_STATUS_E_FAILURE; 7985 7986 cmd = (wmi_pdev_dfs_disable_cmd_fixed_param *)wmi_buf_data(buf); 7987 WMITLV_SET_HDR(&cmd->tlv_header, 7988 WMITLV_TAG_STRUC_wmi_pdev_dfs_disable_cmd_fixed_param, 7989 WMITLV_GET_STRUCT_TLVLEN( 7990 wmi_pdev_dfs_disable_cmd_fixed_param)); 7991 /* Filling it with WMI_PDEV_ID_SOC for now */ 7992 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 7993 wmi_handle, 7994 WMI_HOST_PDEV_ID_SOC); 7995 7996 wmi_mtrace(WMI_PDEV_DFS_DISABLE_CMDID, NO_SESSION, 0); 7997 ret = wmi_unified_cmd_send(wmi_handle, buf, sizeof(*cmd), 7998 WMI_PDEV_DFS_DISABLE_CMDID); 7999 8000 if (ret != 0) { 8001 wmi_err("Sending PDEV DFS disable cmd failed"); 8002 wmi_buf_free(buf); 8003 } 8004 8005 return ret; 8006 } 8007 8008 /** 8009 * send_phyerr_enable_cmd_tlv() - WMI phyerr disable function 8010 * @wmi_handle: handle to WMI. 8011 * 8012 * Return: QDF_STATUS_SUCCESS for success or error code 8013 */ 8014 static QDF_STATUS send_phyerr_enable_cmd_tlv(wmi_unified_t wmi_handle) 8015 { 8016 wmi_pdev_dfs_enable_cmd_fixed_param *cmd; 8017 wmi_buf_t buf; 8018 QDF_STATUS ret; 8019 int32_t len; 8020 8021 len = sizeof(*cmd); 8022 8023 buf = wmi_buf_alloc(wmi_handle, len); 8024 if (!buf) 8025 return QDF_STATUS_E_FAILURE; 8026 8027 cmd = (wmi_pdev_dfs_enable_cmd_fixed_param *)wmi_buf_data(buf); 8028 WMITLV_SET_HDR(&cmd->tlv_header, 8029 WMITLV_TAG_STRUC_wmi_pdev_dfs_enable_cmd_fixed_param, 8030 WMITLV_GET_STRUCT_TLVLEN( 8031 wmi_pdev_dfs_enable_cmd_fixed_param)); 8032 /* Reserved for future use */ 8033 cmd->reserved0 = 0; 8034 8035 wmi_mtrace(WMI_PDEV_DFS_ENABLE_CMDID, NO_SESSION, 0); 8036 ret = wmi_unified_cmd_send(wmi_handle, buf, sizeof(*cmd), 8037 WMI_PDEV_DFS_ENABLE_CMDID); 8038 8039 if (ret != 0) { 8040 wmi_err("Sending PDEV DFS enable cmd failed"); 8041 wmi_buf_free(buf); 8042 } 8043 8044 return ret; 8045 } 8046 8047 /** 8048 * send_periodic_chan_stats_config_cmd_tlv() - send periodic chan stats cmd 8049 * to fw 8050 * @wmi_handle: wmi handle 8051 * @param: pointer to hold periodic chan stats param 8052 * 8053 * Return: QDF_STATUS_SUCCESS for success or error code 8054 */ 8055 static QDF_STATUS 8056 send_periodic_chan_stats_config_cmd_tlv(wmi_unified_t wmi_handle, 8057 struct periodic_chan_stats_params *param) 8058 { 8059 wmi_set_periodic_channel_stats_config_fixed_param *cmd; 8060 wmi_buf_t buf; 8061 QDF_STATUS ret; 8062 int32_t len; 8063 8064 len = sizeof(*cmd); 8065 8066 buf = wmi_buf_alloc(wmi_handle, len); 8067 if (!buf) 8068 return QDF_STATUS_E_FAILURE; 8069 8070 cmd = (wmi_set_periodic_channel_stats_config_fixed_param *) 8071 wmi_buf_data(buf); 8072 WMITLV_SET_HDR(&cmd->tlv_header, 8073 WMITLV_TAG_STRUC_wmi_set_periodic_channel_stats_config_fixed_param, 8074 WMITLV_GET_STRUCT_TLVLEN( 8075 wmi_set_periodic_channel_stats_config_fixed_param)); 8076 cmd->enable = param->enable; 8077 cmd->stats_period = param->stats_period; 8078 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 8079 wmi_handle, 8080 param->pdev_id); 8081 8082 wmi_mtrace(WMI_SET_PERIODIC_CHANNEL_STATS_CONFIG_CMDID, NO_SESSION, 0); 8083 ret = wmi_unified_cmd_send(wmi_handle, buf, sizeof(*cmd), 8084 WMI_SET_PERIODIC_CHANNEL_STATS_CONFIG_CMDID); 8085 8086 if (ret != 0) { 8087 wmi_err("Sending periodic chan stats config failed"); 8088 wmi_buf_free(buf); 8089 } 8090 8091 return ret; 8092 } 8093 8094 #ifdef WLAN_IOT_SIM_SUPPORT 8095 /** 8096 * send_simulation_test_cmd_tlv() - send simulation test command to fw 8097 * 8098 * @wmi_handle: wmi handle 8099 * @param: pointer to hold simulation test parameter 8100 * 8101 * Return: QDF_STATUS_SUCCESS for success or error code 8102 */ 8103 static QDF_STATUS send_simulation_test_cmd_tlv(wmi_unified_t wmi_handle, 8104 struct simulation_test_params 8105 *param) 8106 { 8107 wmi_simulation_test_cmd_fixed_param *cmd; 8108 u32 wmi_buf_len; 8109 wmi_buf_t buf; 8110 u8 *buf_ptr; 8111 u32 aligned_len = 0; 8112 8113 wmi_buf_len = sizeof(*cmd); 8114 if (param->buf_len) { 8115 aligned_len = roundup(param->buf_len, sizeof(A_UINT32)); 8116 wmi_buf_len += WMI_TLV_HDR_SIZE + aligned_len; 8117 } 8118 8119 buf = wmi_buf_alloc(wmi_handle, wmi_buf_len); 8120 if (!buf) { 8121 wmi_err("wmi_buf_alloc failed"); 8122 return QDF_STATUS_E_NOMEM; 8123 } 8124 8125 buf_ptr = wmi_buf_data(buf); 8126 cmd = (wmi_simulation_test_cmd_fixed_param *)buf_ptr; 8127 WMITLV_SET_HDR(&cmd->tlv_header, 8128 WMITLV_TAG_STRUC_wmi_simulation_test_cmd_fixed_param, 8129 WMITLV_GET_STRUCT_TLVLEN( 8130 wmi_simulation_test_cmd_fixed_param)); 8131 cmd->pdev_id = param->pdev_id; 8132 cmd->vdev_id = param->vdev_id; 8133 WMI_CHAR_ARRAY_TO_MAC_ADDR(param->peer_mac, &cmd->peer_macaddr); 8134 cmd->test_cmd_type = param->test_cmd_type; 8135 cmd->test_subcmd_type = param->test_subcmd_type; 8136 WMI_SIM_FRAME_TYPE_SET(cmd->frame_type_subtype_seq, param->frame_type); 8137 WMI_SIM_FRAME_SUBTYPE_SET(cmd->frame_type_subtype_seq, 8138 param->frame_subtype); 8139 WMI_SIM_FRAME_SEQ_SET(cmd->frame_type_subtype_seq, param->seq); 8140 WMI_SIM_FRAME_OFFSET_SET(cmd->frame_offset_length, param->offset); 8141 WMI_SIM_FRAME_LENGTH_SET(cmd->frame_offset_length, param->frame_length); 8142 cmd->buf_len = param->buf_len; 8143 8144 if (param->buf_len) { 8145 buf_ptr += sizeof(*cmd); 8146 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, aligned_len); 8147 buf_ptr += WMI_TLV_HDR_SIZE; 8148 qdf_mem_copy(buf_ptr, param->bufp, param->buf_len); 8149 } 8150 8151 if (wmi_unified_cmd_send(wmi_handle, buf, wmi_buf_len, 8152 WMI_SIMULATION_TEST_CMDID)) { 8153 wmi_err("Failed to send test simulation cmd"); 8154 wmi_buf_free(buf); 8155 return QDF_STATUS_E_FAILURE; 8156 } 8157 8158 return QDF_STATUS_SUCCESS; 8159 } 8160 #endif 8161 8162 #ifdef WLAN_FEATURE_11BE 8163 #define WLAN_PHY_CH_WIDTH_320MHZ CH_WIDTH_320MHZ 8164 #else 8165 #define WLAN_PHY_CH_WIDTH_320MHZ CH_WIDTH_INVALID 8166 #endif 8167 enum phy_ch_width wmi_map_ch_width(A_UINT32 wmi_width) 8168 { 8169 switch (wmi_width) { 8170 case WMI_CHAN_WIDTH_20: 8171 return CH_WIDTH_20MHZ; 8172 case WMI_CHAN_WIDTH_40: 8173 return CH_WIDTH_40MHZ; 8174 case WMI_CHAN_WIDTH_80: 8175 return CH_WIDTH_80MHZ; 8176 case WMI_CHAN_WIDTH_160: 8177 return CH_WIDTH_160MHZ; 8178 case WMI_CHAN_WIDTH_80P80: 8179 return CH_WIDTH_80P80MHZ; 8180 case WMI_CHAN_WIDTH_5: 8181 return CH_WIDTH_5MHZ; 8182 case WMI_CHAN_WIDTH_10: 8183 return CH_WIDTH_10MHZ; 8184 case WMI_CHAN_WIDTH_320: 8185 return WLAN_PHY_CH_WIDTH_320MHZ; 8186 default: 8187 return CH_WIDTH_INVALID; 8188 } 8189 } 8190 8191 /* 8192 * convert_host_to_target_ch_width()- map host channel width(enum phy_ch_width) 8193 * to wmi channel width 8194 * @chan_width: Host channel width 8195 * 8196 * Return: wmi channel width 8197 */ 8198 static 8199 wmi_channel_width convert_host_to_target_ch_width(uint32_t chan_width) 8200 { 8201 switch (chan_width) { 8202 case CH_WIDTH_20MHZ: 8203 return WMI_CHAN_WIDTH_20; 8204 case CH_WIDTH_40MHZ: 8205 return WMI_CHAN_WIDTH_40; 8206 case CH_WIDTH_80MHZ: 8207 return WMI_CHAN_WIDTH_80; 8208 case CH_WIDTH_160MHZ: 8209 return WMI_CHAN_WIDTH_160; 8210 case CH_WIDTH_80P80MHZ: 8211 return WMI_CHAN_WIDTH_80P80; 8212 case CH_WIDTH_5MHZ: 8213 return WMI_CHAN_WIDTH_5; 8214 case CH_WIDTH_10MHZ: 8215 return WMI_CHAN_WIDTH_10; 8216 #ifdef WLAN_FEATURE_11BE 8217 case CH_WIDTH_320MHZ: 8218 return WMI_CHAN_WIDTH_320; 8219 #endif 8220 default: 8221 return WMI_CHAN_WIDTH_MAX; 8222 } 8223 } 8224 8225 /** 8226 * send_vdev_spectral_configure_cmd_tlv() - send VDEV spectral configure 8227 * command to fw 8228 * @wmi_handle: wmi handle 8229 * @param: pointer to hold spectral config parameter 8230 * 8231 * Return: QDF_STATUS_SUCCESS for success or error code 8232 */ 8233 static QDF_STATUS send_vdev_spectral_configure_cmd_tlv(wmi_unified_t wmi_handle, 8234 struct vdev_spectral_configure_params *param) 8235 { 8236 wmi_vdev_spectral_configure_cmd_fixed_param *cmd; 8237 wmi_buf_t buf; 8238 QDF_STATUS ret; 8239 int32_t len; 8240 8241 len = sizeof(*cmd); 8242 buf = wmi_buf_alloc(wmi_handle, len); 8243 if (!buf) 8244 return QDF_STATUS_E_FAILURE; 8245 8246 cmd = (wmi_vdev_spectral_configure_cmd_fixed_param *)wmi_buf_data(buf); 8247 WMITLV_SET_HDR(&cmd->tlv_header, 8248 WMITLV_TAG_STRUC_wmi_vdev_spectral_configure_cmd_fixed_param, 8249 WMITLV_GET_STRUCT_TLVLEN( 8250 wmi_vdev_spectral_configure_cmd_fixed_param)); 8251 8252 cmd->vdev_id = param->vdev_id; 8253 cmd->spectral_scan_count = param->count; 8254 cmd->spectral_scan_period = param->period; 8255 cmd->spectral_scan_priority = param->spectral_pri; 8256 cmd->spectral_scan_fft_size = param->fft_size; 8257 cmd->spectral_scan_gc_ena = param->gc_enable; 8258 cmd->spectral_scan_restart_ena = param->restart_enable; 8259 cmd->spectral_scan_noise_floor_ref = param->noise_floor_ref; 8260 cmd->spectral_scan_init_delay = param->init_delay; 8261 cmd->spectral_scan_nb_tone_thr = param->nb_tone_thr; 8262 cmd->spectral_scan_str_bin_thr = param->str_bin_thr; 8263 cmd->spectral_scan_wb_rpt_mode = param->wb_rpt_mode; 8264 cmd->spectral_scan_rssi_rpt_mode = param->rssi_rpt_mode; 8265 cmd->spectral_scan_rssi_thr = param->rssi_thr; 8266 cmd->spectral_scan_pwr_format = param->pwr_format; 8267 cmd->spectral_scan_rpt_mode = param->rpt_mode; 8268 cmd->spectral_scan_bin_scale = param->bin_scale; 8269 cmd->spectral_scan_dBm_adj = param->dbm_adj; 8270 cmd->spectral_scan_chn_mask = param->chn_mask; 8271 cmd->spectral_scan_mode = param->mode; 8272 cmd->spectral_scan_center_freq1 = param->center_freq1; 8273 cmd->spectral_scan_center_freq2 = param->center_freq2; 8274 cmd->spectral_scan_chan_width = 8275 convert_host_to_target_ch_width(param->chan_width); 8276 cmd->recapture_sample_on_gain_change = param->fft_recap; 8277 /* Not used, fill with zeros */ 8278 cmd->spectral_scan_chan_freq = 0; 8279 8280 wmi_mtrace(WMI_VDEV_SPECTRAL_SCAN_CONFIGURE_CMDID, cmd->vdev_id, 0); 8281 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 8282 WMI_VDEV_SPECTRAL_SCAN_CONFIGURE_CMDID); 8283 8284 if (ret != 0) { 8285 wmi_err("Sending set quiet cmd failed"); 8286 wmi_buf_free(buf); 8287 } 8288 8289 wmi_debug("Sent WMI_VDEV_SPECTRAL_SCAN_CONFIGURE_CMDID"); 8290 wmi_debug("vdev_id: %u spectral_scan_count: %u", 8291 param->vdev_id, param->count); 8292 wmi_debug("spectral_scan_period: %u spectral_scan_priority: %u", 8293 param->period, param->spectral_pri); 8294 wmi_debug("spectral_fft_recapture_cap: %u", param->fft_recap); 8295 wmi_debug("spectral_scan_fft_size: %u spectral_scan_gc_ena: %u", 8296 param->fft_size, param->gc_enable); 8297 wmi_debug("spectral_scan_restart_ena: %u", param->restart_enable); 8298 wmi_debug("spectral_scan_noise_floor_ref: %u", param->noise_floor_ref); 8299 wmi_debug("spectral_scan_init_delay: %u", param->init_delay); 8300 wmi_debug("spectral_scan_nb_tone_thr: %u", param->nb_tone_thr); 8301 wmi_debug("spectral_scan_str_bin_thr: %u", param->str_bin_thr); 8302 wmi_debug("spectral_scan_wb_rpt_mode: %u", param->wb_rpt_mode); 8303 wmi_debug("spectral_scan_rssi_rpt_mode: %u", param->rssi_rpt_mode); 8304 wmi_debug("spectral_scan_rssi_thr: %u spectral_scan_pwr_format: %u", 8305 param->rssi_thr, param->pwr_format); 8306 wmi_debug("spectral_scan_rpt_mode: %u spectral_scan_bin_scale: %u", 8307 param->rpt_mode, param->bin_scale); 8308 wmi_debug("spectral_scan_dBm_adj: %u spectral_scan_chn_mask: %u", 8309 param->dbm_adj, param->chn_mask); 8310 wmi_debug("spectral_scan_mode: %u spectral_scan_center_freq1: %u", 8311 param->mode, param->center_freq1); 8312 wmi_debug("spectral_scan_center_freq2: %u spectral_scan_chan_freq: %u", 8313 param->center_freq2, param->chan_freq); 8314 wmi_debug("spectral_scan_chan_width: %u Status: %d", 8315 param->chan_width, ret); 8316 8317 return ret; 8318 } 8319 8320 /** 8321 * send_vdev_spectral_enable_cmd_tlv() - send VDEV spectral configure 8322 * command to fw 8323 * @wmi_handle: wmi handle 8324 * @param: pointer to hold spectral enable parameter 8325 * 8326 * Return: QDF_STATUS_SUCCESS for success or error code 8327 */ 8328 static QDF_STATUS send_vdev_spectral_enable_cmd_tlv(wmi_unified_t wmi_handle, 8329 struct vdev_spectral_enable_params *param) 8330 { 8331 wmi_vdev_spectral_enable_cmd_fixed_param *cmd; 8332 wmi_buf_t buf; 8333 QDF_STATUS ret; 8334 int32_t len; 8335 8336 len = sizeof(*cmd); 8337 buf = wmi_buf_alloc(wmi_handle, len); 8338 if (!buf) 8339 return QDF_STATUS_E_FAILURE; 8340 8341 cmd = (wmi_vdev_spectral_enable_cmd_fixed_param *)wmi_buf_data(buf); 8342 WMITLV_SET_HDR(&cmd->tlv_header, 8343 WMITLV_TAG_STRUC_wmi_vdev_spectral_enable_cmd_fixed_param, 8344 WMITLV_GET_STRUCT_TLVLEN( 8345 wmi_vdev_spectral_enable_cmd_fixed_param)); 8346 8347 cmd->vdev_id = param->vdev_id; 8348 8349 if (param->active_valid) { 8350 cmd->trigger_cmd = param->active ? 1 : 2; 8351 /* 1: Trigger, 2: Clear Trigger */ 8352 } else { 8353 cmd->trigger_cmd = 0; /* 0: Ignore */ 8354 } 8355 8356 if (param->enabled_valid) { 8357 cmd->enable_cmd = param->enabled ? 1 : 2; 8358 /* 1: Enable 2: Disable */ 8359 } else { 8360 cmd->enable_cmd = 0; /* 0: Ignore */ 8361 } 8362 cmd->spectral_scan_mode = param->mode; 8363 8364 wmi_debug("vdev_id = %u trigger_cmd = %u enable_cmd = %u", 8365 cmd->vdev_id, cmd->trigger_cmd, cmd->enable_cmd); 8366 wmi_debug("spectral_scan_mode = %u", cmd->spectral_scan_mode); 8367 8368 wmi_mtrace(WMI_VDEV_SPECTRAL_SCAN_ENABLE_CMDID, cmd->vdev_id, 0); 8369 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 8370 WMI_VDEV_SPECTRAL_SCAN_ENABLE_CMDID); 8371 8372 if (ret != 0) { 8373 wmi_err("Sending scan enable CMD failed"); 8374 wmi_buf_free(buf); 8375 } 8376 8377 wmi_debug("Sent WMI_VDEV_SPECTRAL_SCAN_ENABLE_CMDID, Status: %d", 8378 ret); 8379 8380 return ret; 8381 } 8382 8383 #ifdef WLAN_CONV_SPECTRAL_ENABLE 8384 static QDF_STATUS 8385 extract_pdev_sscan_fw_cmd_fixed_param_tlv( 8386 wmi_unified_t wmi_handle, 8387 uint8_t *event, struct spectral_startscan_resp_params *param) 8388 { 8389 WMI_PDEV_SSCAN_FW_PARAM_EVENTID_param_tlvs *param_buf; 8390 wmi_pdev_sscan_fw_cmd_fixed_param *ev; 8391 8392 if (!wmi_handle) { 8393 wmi_err("WMI handle is null"); 8394 return QDF_STATUS_E_INVAL; 8395 } 8396 8397 if (!event) { 8398 wmi_err("WMI event is null"); 8399 return QDF_STATUS_E_INVAL; 8400 } 8401 8402 if (!param) { 8403 wmi_err("Spectral startscan response params is null"); 8404 return QDF_STATUS_E_INVAL; 8405 } 8406 8407 param_buf = (WMI_PDEV_SSCAN_FW_PARAM_EVENTID_param_tlvs *)event; 8408 if (!param_buf) 8409 return QDF_STATUS_E_INVAL; 8410 8411 ev = param_buf->fixed_param; 8412 if (!ev) 8413 return QDF_STATUS_E_INVAL; 8414 8415 param->pdev_id = wmi_handle->ops->convert_target_pdev_id_to_host( 8416 wmi_handle, 8417 ev->pdev_id); 8418 param->smode = ev->spectral_scan_mode; 8419 param->num_fft_bin_index = param_buf->num_fft_bin_index; 8420 param->num_det_info = param_buf->num_det_info; 8421 8422 wmi_debug("pdev id:%u smode:%u num_fft_bin_index:%u num_det_info:%u", 8423 ev->pdev_id, ev->spectral_scan_mode, 8424 param_buf->num_fft_bin_index, param_buf->num_det_info); 8425 8426 return QDF_STATUS_SUCCESS; 8427 } 8428 8429 static QDF_STATUS 8430 extract_pdev_sscan_fft_bin_index_tlv( 8431 wmi_unified_t wmi_handle, uint8_t *event, 8432 struct spectral_fft_bin_markers_160_165mhz *param) 8433 { 8434 WMI_PDEV_SSCAN_FW_PARAM_EVENTID_param_tlvs *param_buf; 8435 wmi_pdev_sscan_fft_bin_index *ev; 8436 8437 param_buf = (WMI_PDEV_SSCAN_FW_PARAM_EVENTID_param_tlvs *)event; 8438 if (!param_buf) 8439 return QDF_STATUS_E_INVAL; 8440 8441 ev = param_buf->fft_bin_index; 8442 if (!ev) 8443 return QDF_STATUS_E_INVAL; 8444 8445 param->start_pri80 = WMI_SSCAN_PRI80_START_BIN_GET(ev->pri80_bins); 8446 param->num_pri80 = WMI_SSCAN_PRI80_END_BIN_GET(ev->pri80_bins) - 8447 param->start_pri80 + 1; 8448 param->start_sec80 = WMI_SSCAN_SEC80_START_BIN_GET(ev->sec80_bins); 8449 param->num_sec80 = WMI_SSCAN_SEC80_END_BIN_GET(ev->sec80_bins) - 8450 param->start_sec80 + 1; 8451 param->start_5mhz = WMI_SSCAN_MID_5MHZ_START_BIN_GET(ev->mid_5mhz_bins); 8452 param->num_5mhz = WMI_SSCAN_MID_5MHZ_END_BIN_GET(ev->mid_5mhz_bins) - 8453 param->start_5mhz + 1; 8454 param->is_valid = true; 8455 8456 wmi_debug("start_pri80: %u num_pri80: %u start_sec80: %u num_sec80: %u start_5mhz: %u, num_5mhz: %u", 8457 param->start_pri80, param->num_pri80, 8458 param->start_sec80, param->num_sec80, 8459 param->start_5mhz, param->num_5mhz); 8460 8461 return QDF_STATUS_SUCCESS; 8462 } 8463 8464 /** 8465 * extract_pdev_spectral_session_chan_info_tlv() - Extract channel information 8466 * for a spectral scan session 8467 * @wmi_handle: handle to WMI. 8468 * @event: Event buffer 8469 * @chan_info: Spectral session channel information data structure to be filled 8470 * by this API 8471 * 8472 * Return: QDF_STATUS of operation 8473 */ 8474 static QDF_STATUS 8475 extract_pdev_spectral_session_chan_info_tlv( 8476 wmi_unified_t wmi_handle, void *event, 8477 struct spectral_session_chan_info *chan_info) 8478 { 8479 WMI_PDEV_SSCAN_FW_PARAM_EVENTID_param_tlvs *param_buf = event; 8480 wmi_pdev_sscan_chan_info *chan_info_tlv; 8481 8482 if (!param_buf) { 8483 wmi_err("param_buf is NULL"); 8484 return QDF_STATUS_E_NULL_VALUE; 8485 } 8486 8487 if (!chan_info) { 8488 wmi_err("chan_info is NULL"); 8489 return QDF_STATUS_E_NULL_VALUE; 8490 } 8491 8492 chan_info_tlv = param_buf->chan_info; 8493 if (!chan_info_tlv) { 8494 wmi_err("chan_info tlv is not present in the event"); 8495 return QDF_STATUS_E_NULL_VALUE; 8496 } 8497 8498 wmi_debug("operating_pri20_freq:%u operating_cfreq1:%u" 8499 "operating_cfreq2:%u operating_bw:%u" 8500 "operating_puncture_20mhz_bitmap:%u" 8501 "sscan_cfreq1:%u sscan_cfreq2:%u" 8502 "sscan_bw:%u sscan_puncture_20mhz_bitmap:%u", 8503 chan_info_tlv->operating_pri20_freq, 8504 chan_info_tlv->operating_cfreq1, 8505 chan_info_tlv->operating_cfreq2, chan_info_tlv->operating_bw, 8506 chan_info_tlv->operating_puncture_20mhz_bitmap, 8507 chan_info_tlv->sscan_cfreq1, chan_info_tlv->sscan_cfreq2, 8508 chan_info_tlv->sscan_bw, 8509 chan_info_tlv->sscan_puncture_20mhz_bitmap); 8510 8511 chan_info->operating_pri20_freq = 8512 (qdf_freq_t)chan_info_tlv->operating_pri20_freq; 8513 chan_info->operating_cfreq1 = 8514 (qdf_freq_t)chan_info_tlv->operating_cfreq1; 8515 chan_info->operating_cfreq2 = 8516 (qdf_freq_t)chan_info_tlv->operating_cfreq2; 8517 chan_info->operating_bw = wmi_map_ch_width(chan_info_tlv->operating_bw); 8518 chan_info->operating_puncture_20mhz_bitmap = 8519 chan_info_tlv->operating_puncture_20mhz_bitmap; 8520 8521 chan_info->sscan_cfreq1 = (qdf_freq_t)chan_info_tlv->sscan_cfreq1; 8522 chan_info->sscan_cfreq2 = (qdf_freq_t)chan_info_tlv->sscan_cfreq2; 8523 chan_info->sscan_bw = wmi_map_ch_width(chan_info_tlv->sscan_bw); 8524 chan_info->sscan_puncture_20mhz_bitmap = 8525 chan_info_tlv->sscan_puncture_20mhz_bitmap; 8526 8527 return QDF_STATUS_SUCCESS; 8528 } 8529 8530 static QDF_STATUS 8531 extract_pdev_spectral_session_detector_info_tlv( 8532 wmi_unified_t wmi_handle, void *event, 8533 struct spectral_session_det_info *det_info, uint8_t idx) 8534 { 8535 WMI_PDEV_SSCAN_FW_PARAM_EVENTID_param_tlvs *param_buf = event; 8536 wmi_pdev_sscan_per_detector_info *det_info_tlv; 8537 8538 if (!param_buf) { 8539 wmi_err("param_buf is NULL"); 8540 return QDF_STATUS_E_NULL_VALUE; 8541 } 8542 8543 if (!det_info) { 8544 wmi_err("chan_info is NULL"); 8545 return QDF_STATUS_E_NULL_VALUE; 8546 } 8547 8548 if (!param_buf->det_info) { 8549 wmi_err("det_info tlv is not present in the event"); 8550 return QDF_STATUS_E_NULL_VALUE; 8551 } 8552 8553 if (idx >= param_buf->num_det_info) { 8554 wmi_err("det_info index(%u) is greater than or equal to %u", 8555 idx, param_buf->num_det_info); 8556 return QDF_STATUS_E_FAILURE; 8557 } 8558 8559 det_info_tlv = ¶m_buf->det_info[idx]; 8560 8561 wmi_debug("det_info_idx: %u detector_id:%u start_freq:%u end_freq:%u", 8562 idx, det_info_tlv->detector_id, 8563 det_info_tlv->start_freq, det_info_tlv->end_freq); 8564 8565 det_info->det_id = det_info_tlv->detector_id; 8566 det_info->start_freq = (qdf_freq_t)det_info_tlv->start_freq; 8567 det_info->end_freq = (qdf_freq_t)det_info_tlv->end_freq; 8568 8569 return QDF_STATUS_SUCCESS; 8570 } 8571 8572 /** 8573 * extract_spectral_caps_fixed_param_tlv() - Extract fixed params from Spectral 8574 * capabilities WMI event 8575 * @wmi_handle: handle to WMI. 8576 * @event: Event buffer 8577 * @params: Spectral capabilities event parameters data structure to be filled 8578 * by this API 8579 * 8580 * Return: QDF_STATUS of operation 8581 */ 8582 static QDF_STATUS 8583 extract_spectral_caps_fixed_param_tlv( 8584 wmi_unified_t wmi_handle, void *event, 8585 struct spectral_capabilities_event_params *params) 8586 { 8587 WMI_SPECTRAL_CAPABILITIES_EVENTID_param_tlvs *param_buf = event; 8588 8589 if (!param_buf) { 8590 wmi_err("param_buf is NULL"); 8591 return QDF_STATUS_E_NULL_VALUE; 8592 } 8593 8594 if (!params) { 8595 wmi_err("event parameters is NULL"); 8596 return QDF_STATUS_E_NULL_VALUE; 8597 } 8598 8599 params->num_sscan_bw_caps = param_buf->num_sscan_bw_caps; 8600 params->num_fft_size_caps = param_buf->num_fft_size_caps; 8601 8602 wmi_debug("num_sscan_bw_caps:%u num_fft_size_caps:%u", 8603 params->num_sscan_bw_caps, params->num_fft_size_caps); 8604 8605 return QDF_STATUS_SUCCESS; 8606 } 8607 8608 /** 8609 * extract_spectral_scan_bw_caps_tlv() - Extract bandwidth caps from 8610 * Spectral capabilities WMI event 8611 * @wmi_handle: handle to WMI. 8612 * @event: Event buffer 8613 * @bw_caps: Data structure to be populated by this API after extraction 8614 * 8615 * Return: QDF_STATUS of operation 8616 */ 8617 static QDF_STATUS 8618 extract_spectral_scan_bw_caps_tlv( 8619 wmi_unified_t wmi_handle, void *event, 8620 struct spectral_scan_bw_capabilities *bw_caps) 8621 { 8622 WMI_SPECTRAL_CAPABILITIES_EVENTID_param_tlvs *param_buf = event; 8623 int idx; 8624 8625 if (!param_buf) { 8626 wmi_err("param_buf is NULL"); 8627 return QDF_STATUS_E_NULL_VALUE; 8628 } 8629 8630 if (!bw_caps) { 8631 wmi_err("bw_caps is null"); 8632 return QDF_STATUS_E_NULL_VALUE; 8633 } 8634 8635 for (idx = 0; idx < param_buf->num_sscan_bw_caps; idx++) { 8636 bw_caps[idx].pdev_id = 8637 wmi_handle->ops->convert_pdev_id_target_to_host( 8638 wmi_handle, 8639 param_buf->sscan_bw_caps[idx].pdev_id); 8640 bw_caps[idx].smode = param_buf->sscan_bw_caps[idx].sscan_mode; 8641 bw_caps[idx].operating_bw = wmi_map_ch_width( 8642 param_buf->sscan_bw_caps[idx].operating_bw); 8643 bw_caps[idx].supported_bws = 8644 param_buf->sscan_bw_caps[idx].supported_flags; 8645 8646 wmi_debug("bw_caps[%u]:: pdev_id:%u smode:%u" 8647 "operating_bw:%u supported_flags:0x%x", 8648 idx, param_buf->sscan_bw_caps[idx].pdev_id, 8649 param_buf->sscan_bw_caps[idx].sscan_mode, 8650 param_buf->sscan_bw_caps[idx].operating_bw, 8651 param_buf->sscan_bw_caps[idx].supported_flags); 8652 } 8653 8654 return QDF_STATUS_SUCCESS; 8655 } 8656 8657 /** 8658 * extract_spectral_fft_size_caps_tlv() - Extract FFT size caps from 8659 * Spectral capabilities WMI event 8660 * @wmi_handle: handle to WMI. 8661 * @event: Event buffer 8662 * @fft_size_caps: Data structure to be populated by this API after extraction 8663 * 8664 * Return: QDF_STATUS of operation 8665 */ 8666 static QDF_STATUS 8667 extract_spectral_fft_size_caps_tlv( 8668 wmi_unified_t wmi_handle, void *event, 8669 struct spectral_fft_size_capabilities *fft_size_caps) 8670 { 8671 WMI_SPECTRAL_CAPABILITIES_EVENTID_param_tlvs *param_buf = event; 8672 int idx; 8673 8674 if (!param_buf) { 8675 wmi_err("param_buf is NULL"); 8676 return QDF_STATUS_E_NULL_VALUE; 8677 } 8678 8679 if (!fft_size_caps) { 8680 wmi_err("fft size caps is NULL"); 8681 return QDF_STATUS_E_NULL_VALUE; 8682 } 8683 8684 for (idx = 0; idx < param_buf->num_fft_size_caps; idx++) { 8685 fft_size_caps[idx].pdev_id = 8686 wmi_handle->ops->convert_pdev_id_target_to_host( 8687 wmi_handle, 8688 param_buf->fft_size_caps[idx].pdev_id); 8689 fft_size_caps[idx].sscan_bw = wmi_map_ch_width( 8690 param_buf->fft_size_caps[idx].sscan_bw); 8691 fft_size_caps[idx].supports_fft_sizes = 8692 param_buf->fft_size_caps[idx].supported_flags; 8693 8694 wmi_debug("fft_size_caps[%u]:: pdev_id:%u sscan_bw:%u" 8695 "supported_flags:0x%x", 8696 idx, param_buf->fft_size_caps[idx].pdev_id, 8697 param_buf->fft_size_caps[idx].sscan_bw, 8698 param_buf->fft_size_caps[idx].supported_flags); 8699 } 8700 8701 return QDF_STATUS_SUCCESS; 8702 } 8703 #endif /* WLAN_CONV_SPECTRAL_ENABLE */ 8704 8705 #ifdef FEATURE_WPSS_THERMAL_MITIGATION 8706 static inline void 8707 wmi_fill_client_id_priority(wmi_therm_throt_config_request_fixed_param *tt_conf, 8708 struct thermal_mitigation_params *param) 8709 { 8710 tt_conf->client_id = param->client_id; 8711 tt_conf->priority = param->priority; 8712 } 8713 #else 8714 static inline void 8715 wmi_fill_client_id_priority(wmi_therm_throt_config_request_fixed_param *tt_conf, 8716 struct thermal_mitigation_params *param) 8717 { 8718 } 8719 #endif 8720 8721 /** 8722 * send_thermal_mitigation_param_cmd_tlv() - configure thermal mitigation params 8723 * @wmi_handle : handle to WMI. 8724 * @param : pointer to hold thermal mitigation param 8725 * 8726 * Return: QDF_STATUS_SUCCESS for success or error code 8727 */ 8728 static QDF_STATUS send_thermal_mitigation_param_cmd_tlv( 8729 wmi_unified_t wmi_handle, 8730 struct thermal_mitigation_params *param) 8731 { 8732 wmi_therm_throt_config_request_fixed_param *tt_conf = NULL; 8733 wmi_therm_throt_level_config_info *lvl_conf = NULL; 8734 wmi_buf_t buf = NULL; 8735 uint8_t *buf_ptr = NULL; 8736 int error; 8737 int32_t len; 8738 int i; 8739 8740 len = sizeof(*tt_conf) + WMI_TLV_HDR_SIZE + 8741 param->num_thermal_conf * 8742 sizeof(wmi_therm_throt_level_config_info); 8743 8744 buf = wmi_buf_alloc(wmi_handle, len); 8745 if (!buf) 8746 return QDF_STATUS_E_NOMEM; 8747 8748 tt_conf = (wmi_therm_throt_config_request_fixed_param *) wmi_buf_data(buf); 8749 8750 /* init fixed params */ 8751 WMITLV_SET_HDR(tt_conf, 8752 WMITLV_TAG_STRUC_wmi_therm_throt_config_request_fixed_param, 8753 (WMITLV_GET_STRUCT_TLVLEN(wmi_therm_throt_config_request_fixed_param))); 8754 8755 tt_conf->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 8756 wmi_handle, 8757 param->pdev_id); 8758 tt_conf->enable = param->enable; 8759 tt_conf->dc = param->dc; 8760 tt_conf->dc_per_event = param->dc_per_event; 8761 tt_conf->therm_throt_levels = param->num_thermal_conf; 8762 wmi_fill_client_id_priority(tt_conf, param); 8763 buf_ptr = (uint8_t *) ++tt_conf; 8764 /* init TLV params */ 8765 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 8766 (param->num_thermal_conf * 8767 sizeof(wmi_therm_throt_level_config_info))); 8768 8769 lvl_conf = (wmi_therm_throt_level_config_info *) (buf_ptr + WMI_TLV_HDR_SIZE); 8770 for (i = 0; i < param->num_thermal_conf; i++) { 8771 WMITLV_SET_HDR(&lvl_conf->tlv_header, 8772 WMITLV_TAG_STRUC_wmi_therm_throt_level_config_info, 8773 WMITLV_GET_STRUCT_TLVLEN(wmi_therm_throt_level_config_info)); 8774 lvl_conf->temp_lwm = param->levelconf[i].tmplwm; 8775 lvl_conf->temp_hwm = param->levelconf[i].tmphwm; 8776 lvl_conf->dc_off_percent = param->levelconf[i].dcoffpercent; 8777 lvl_conf->prio = param->levelconf[i].priority; 8778 lvl_conf++; 8779 } 8780 8781 wmi_mtrace(WMI_THERM_THROT_SET_CONF_CMDID, NO_SESSION, 0); 8782 error = wmi_unified_cmd_send(wmi_handle, buf, len, 8783 WMI_THERM_THROT_SET_CONF_CMDID); 8784 if (QDF_IS_STATUS_ERROR(error)) { 8785 wmi_buf_free(buf); 8786 wmi_err("Failed to send WMI_THERM_THROT_SET_CONF_CMDID command"); 8787 } 8788 8789 return error; 8790 } 8791 8792 /** 8793 * send_coex_config_cmd_tlv() - send coex config command to fw 8794 * @wmi_handle: wmi handle 8795 * @param: pointer to coex config param 8796 * 8797 * Return: QDF_STATUS_SUCCESS for success or error code 8798 */ 8799 static QDF_STATUS 8800 send_coex_config_cmd_tlv(wmi_unified_t wmi_handle, 8801 struct coex_config_params *param) 8802 { 8803 WMI_COEX_CONFIG_CMD_fixed_param *cmd; 8804 wmi_buf_t buf; 8805 QDF_STATUS ret; 8806 int32_t len; 8807 8808 len = sizeof(*cmd); 8809 buf = wmi_buf_alloc(wmi_handle, len); 8810 if (!buf) 8811 return QDF_STATUS_E_FAILURE; 8812 8813 cmd = (WMI_COEX_CONFIG_CMD_fixed_param *)wmi_buf_data(buf); 8814 WMITLV_SET_HDR(&cmd->tlv_header, 8815 WMITLV_TAG_STRUC_WMI_COEX_CONFIG_CMD_fixed_param, 8816 WMITLV_GET_STRUCT_TLVLEN( 8817 WMI_COEX_CONFIG_CMD_fixed_param)); 8818 8819 cmd->vdev_id = param->vdev_id; 8820 cmd->config_type = param->config_type; 8821 cmd->config_arg1 = param->config_arg1; 8822 cmd->config_arg2 = param->config_arg2; 8823 cmd->config_arg3 = param->config_arg3; 8824 cmd->config_arg4 = param->config_arg4; 8825 cmd->config_arg5 = param->config_arg5; 8826 cmd->config_arg6 = param->config_arg6; 8827 8828 wmi_mtrace(WMI_COEX_CONFIG_CMDID, cmd->vdev_id, 0); 8829 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 8830 WMI_COEX_CONFIG_CMDID); 8831 8832 if (ret != 0) { 8833 wmi_err("Sending COEX CONFIG CMD failed"); 8834 wmi_buf_free(buf); 8835 } 8836 8837 return ret; 8838 } 8839 8840 #ifdef WLAN_FEATURE_DBAM_CONFIG 8841 8842 static enum wmi_coex_dbam_mode_type 8843 map_to_wmi_coex_dbam_mode_type(enum coex_dbam_config_mode mode) 8844 { 8845 switch (mode) { 8846 case COEX_DBAM_ENABLE: 8847 return WMI_COEX_DBAM_ENABLE; 8848 case COEX_DBAM_FORCE_ENABLE: 8849 return WMI_COEX_DBAM_FORCED; 8850 case COEX_DBAM_DISABLE: 8851 default: 8852 return WMI_COEX_DBAM_DISABLE; 8853 } 8854 } 8855 8856 /** 8857 * send_dbam_config_cmd_tlv() - send coex DBAM config command to fw 8858 * @wmi_handle: wmi handle 8859 * @param: pointer to coex dbam config param 8860 * 8861 * Return: QDF_STATUS_SUCCESS for success or error code 8862 */ 8863 static QDF_STATUS 8864 send_dbam_config_cmd_tlv(wmi_unified_t wmi_handle, 8865 struct coex_dbam_config_params *param) 8866 { 8867 wmi_coex_dbam_cmd_fixed_param *cmd; 8868 wmi_buf_t buf; 8869 void *buf_ptr; 8870 QDF_STATUS ret; 8871 int32_t len; 8872 8873 len = sizeof(*cmd); 8874 buf = wmi_buf_alloc(wmi_handle, len); 8875 if (!buf) { 8876 wmi_err_rl("Failed to allocate wmi buffer"); 8877 return QDF_STATUS_E_NOMEM; 8878 } 8879 8880 buf_ptr = wmi_buf_data(buf); 8881 cmd = buf_ptr; 8882 WMITLV_SET_HDR(&cmd->tlv_header, 8883 WMITLV_TAG_STRUC_wmi_coex_dbam_cmd_fixed_param, 8884 WMITLV_GET_STRUCT_TLVLEN( 8885 wmi_coex_dbam_cmd_fixed_param)); 8886 8887 cmd->vdev_id = param->vdev_id; 8888 cmd->dbam_mode = map_to_wmi_coex_dbam_mode_type(param->dbam_mode); 8889 8890 wmi_mtrace(WMI_COEX_DBAM_CMDID, cmd->vdev_id, 0); 8891 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 8892 WMI_COEX_DBAM_CMDID); 8893 8894 if (QDF_IS_STATUS_ERROR(ret)) { 8895 wmi_err("Sending DBAM CONFIG CMD failed"); 8896 wmi_buf_free(buf); 8897 return QDF_STATUS_E_FAILURE; 8898 } 8899 8900 return ret; 8901 } 8902 8903 static enum coex_dbam_comp_status 8904 wmi_convert_dbam_comp_status(wmi_coex_dbam_comp_status status) 8905 { 8906 switch (status) { 8907 case WMI_COEX_DBAM_COMP_SUCCESS: 8908 case WMI_COEX_DBAM_COMP_ONGOING: 8909 case WMI_COEX_DBAM_COMP_DELAYED: 8910 return COEX_DBAM_COMP_SUCCESS; 8911 case WMI_COEX_DBAM_COMP_NOT_SUPPORT: 8912 return COEX_DBAM_COMP_NOT_SUPPORT; 8913 case WMI_COEX_DBAM_COMP_INVALID_PARAM: 8914 case WMI_COEX_DBAM_COMP_FAIL: 8915 default: 8916 return COEX_DBAM_COMP_FAIL; 8917 } 8918 } 8919 8920 /** 8921 * extract_dbam_config_resp_event_tlv() - extract dbam complete status event 8922 * @wmi_handle: WMI handle 8923 * @evt_buf: event buffer 8924 * @resp: pointer to coex dbam config response 8925 * 8926 * Return: QDF_STATUS 8927 */ 8928 static QDF_STATUS 8929 extract_dbam_config_resp_event_tlv(wmi_unified_t wmi_handle, void *evt_buf, 8930 struct coex_dbam_config_resp *resp) 8931 { 8932 WMI_COEX_DBAM_COMPLETE_EVENTID_param_tlvs *param_buf; 8933 wmi_coex_dbam_complete_event_fixed_param *event; 8934 8935 param_buf = (WMI_COEX_DBAM_COMPLETE_EVENTID_param_tlvs *)evt_buf; 8936 8937 event = param_buf->fixed_param; 8938 8939 resp->dbam_resp = wmi_convert_dbam_comp_status(event->comp_status); 8940 8941 return QDF_STATUS_SUCCESS; 8942 } 8943 #endif 8944 8945 #ifdef WLAN_SUPPORT_TWT 8946 static void wmi_copy_twt_resource_config(wmi_resource_config *resource_cfg, 8947 target_resource_config *tgt_res_cfg) 8948 { 8949 resource_cfg->twt_ap_pdev_count = tgt_res_cfg->twt_ap_pdev_count; 8950 resource_cfg->twt_ap_sta_count = tgt_res_cfg->twt_ap_sta_count; 8951 } 8952 #else 8953 static void wmi_copy_twt_resource_config(wmi_resource_config *resource_cfg, 8954 target_resource_config *tgt_res_cfg) 8955 { 8956 resource_cfg->twt_ap_pdev_count = 0; 8957 resource_cfg->twt_ap_sta_count = 0; 8958 } 8959 #endif 8960 8961 #ifdef WLAN_FEATURE_NAN 8962 static void wmi_set_nan_channel_support(wmi_resource_config *resource_cfg) 8963 { 8964 WMI_RSRC_CFG_HOST_SERVICE_FLAG_NAN_CHANNEL_SUPPORT_SET( 8965 resource_cfg->host_service_flags, 1); 8966 } 8967 #else 8968 static inline 8969 void wmi_set_nan_channel_support(wmi_resource_config *resource_cfg) 8970 { 8971 } 8972 #endif 8973 8974 #if defined(CONFIG_AFC_SUPPORT) 8975 static 8976 void wmi_copy_afc_deployment_config(wmi_resource_config *resource_cfg, 8977 target_resource_config *tgt_res_cfg) 8978 { 8979 WMI_RSRC_CFG_HOST_SERVICE_FLAG_AFC_INDOOR_SUPPORT_CHECK_SET( 8980 resource_cfg->host_service_flags, 8981 tgt_res_cfg->afc_indoor_support); 8982 8983 WMI_RSRC_CFG_HOST_SERVICE_FLAG_AFC_OUTDOOR_SUPPORT_CHECK_SET( 8984 resource_cfg->host_service_flags, 8985 tgt_res_cfg->afc_outdoor_support); 8986 } 8987 #else 8988 static 8989 void wmi_copy_afc_deployment_config(wmi_resource_config *resource_cfg, 8990 target_resource_config *tgt_res_cfg) 8991 { 8992 } 8993 #endif 8994 8995 static 8996 void wmi_copy_resource_config(wmi_resource_config *resource_cfg, 8997 target_resource_config *tgt_res_cfg) 8998 { 8999 resource_cfg->num_vdevs = tgt_res_cfg->num_vdevs; 9000 resource_cfg->num_peers = tgt_res_cfg->num_peers; 9001 resource_cfg->num_offload_peers = tgt_res_cfg->num_offload_peers; 9002 resource_cfg->num_offload_reorder_buffs = 9003 tgt_res_cfg->num_offload_reorder_buffs; 9004 resource_cfg->num_peer_keys = tgt_res_cfg->num_peer_keys; 9005 resource_cfg->num_tids = tgt_res_cfg->num_tids; 9006 resource_cfg->ast_skid_limit = tgt_res_cfg->ast_skid_limit; 9007 resource_cfg->tx_chain_mask = tgt_res_cfg->tx_chain_mask; 9008 resource_cfg->rx_chain_mask = tgt_res_cfg->rx_chain_mask; 9009 resource_cfg->rx_timeout_pri[0] = tgt_res_cfg->rx_timeout_pri[0]; 9010 resource_cfg->rx_timeout_pri[1] = tgt_res_cfg->rx_timeout_pri[1]; 9011 resource_cfg->rx_timeout_pri[2] = tgt_res_cfg->rx_timeout_pri[2]; 9012 resource_cfg->rx_timeout_pri[3] = tgt_res_cfg->rx_timeout_pri[3]; 9013 resource_cfg->rx_decap_mode = tgt_res_cfg->rx_decap_mode; 9014 resource_cfg->scan_max_pending_req = 9015 tgt_res_cfg->scan_max_pending_req; 9016 resource_cfg->bmiss_offload_max_vdev = 9017 tgt_res_cfg->bmiss_offload_max_vdev; 9018 resource_cfg->roam_offload_max_vdev = 9019 tgt_res_cfg->roam_offload_max_vdev; 9020 resource_cfg->roam_offload_max_ap_profiles = 9021 tgt_res_cfg->roam_offload_max_ap_profiles; 9022 resource_cfg->num_mcast_groups = tgt_res_cfg->num_mcast_groups; 9023 resource_cfg->num_mcast_table_elems = 9024 tgt_res_cfg->num_mcast_table_elems; 9025 resource_cfg->mcast2ucast_mode = tgt_res_cfg->mcast2ucast_mode; 9026 resource_cfg->tx_dbg_log_size = tgt_res_cfg->tx_dbg_log_size; 9027 resource_cfg->num_wds_entries = tgt_res_cfg->num_wds_entries; 9028 resource_cfg->dma_burst_size = tgt_res_cfg->dma_burst_size; 9029 resource_cfg->mac_aggr_delim = tgt_res_cfg->mac_aggr_delim; 9030 resource_cfg->rx_skip_defrag_timeout_dup_detection_check = 9031 tgt_res_cfg->rx_skip_defrag_timeout_dup_detection_check; 9032 resource_cfg->vow_config = tgt_res_cfg->vow_config; 9033 resource_cfg->gtk_offload_max_vdev = tgt_res_cfg->gtk_offload_max_vdev; 9034 resource_cfg->num_msdu_desc = tgt_res_cfg->num_msdu_desc; 9035 resource_cfg->max_frag_entries = tgt_res_cfg->max_frag_entries; 9036 resource_cfg->num_tdls_vdevs = tgt_res_cfg->num_tdls_vdevs; 9037 resource_cfg->num_tdls_conn_table_entries = 9038 tgt_res_cfg->num_tdls_conn_table_entries; 9039 resource_cfg->beacon_tx_offload_max_vdev = 9040 tgt_res_cfg->beacon_tx_offload_max_vdev; 9041 resource_cfg->num_multicast_filter_entries = 9042 tgt_res_cfg->num_multicast_filter_entries; 9043 resource_cfg->num_wow_filters = 9044 tgt_res_cfg->num_wow_filters; 9045 resource_cfg->num_keep_alive_pattern = 9046 tgt_res_cfg->num_keep_alive_pattern; 9047 resource_cfg->keep_alive_pattern_size = 9048 tgt_res_cfg->keep_alive_pattern_size; 9049 resource_cfg->max_tdls_concurrent_sleep_sta = 9050 tgt_res_cfg->max_tdls_concurrent_sleep_sta; 9051 resource_cfg->max_tdls_concurrent_buffer_sta = 9052 tgt_res_cfg->max_tdls_concurrent_buffer_sta; 9053 resource_cfg->wmi_send_separate = 9054 tgt_res_cfg->wmi_send_separate; 9055 resource_cfg->num_ocb_vdevs = 9056 tgt_res_cfg->num_ocb_vdevs; 9057 resource_cfg->num_ocb_channels = 9058 tgt_res_cfg->num_ocb_channels; 9059 resource_cfg->num_ocb_schedules = 9060 tgt_res_cfg->num_ocb_schedules; 9061 resource_cfg->bpf_instruction_size = tgt_res_cfg->apf_instruction_size; 9062 resource_cfg->max_bssid_rx_filters = tgt_res_cfg->max_bssid_rx_filters; 9063 resource_cfg->use_pdev_id = tgt_res_cfg->use_pdev_id; 9064 resource_cfg->max_num_dbs_scan_duty_cycle = 9065 tgt_res_cfg->max_num_dbs_scan_duty_cycle; 9066 resource_cfg->sched_params = tgt_res_cfg->scheduler_params; 9067 resource_cfg->num_packet_filters = tgt_res_cfg->num_packet_filters; 9068 resource_cfg->num_max_sta_vdevs = tgt_res_cfg->num_max_sta_vdevs; 9069 resource_cfg->max_bssid_indicator = tgt_res_cfg->max_bssid_indicator; 9070 resource_cfg->max_num_group_keys = tgt_res_cfg->max_num_group_keys; 9071 /* Deferred AI: Max rnr neighbors supported in multisoc case 9072 * where in SoC can support 6ghz. During WMI init of a SoC 9073 * currently there is no way to figure if another SOC is plugged in 9074 * and it can support 6Ghz. 9075 */ 9076 resource_cfg->max_rnr_neighbours = MAX_SUPPORTED_NEIGHBORS; 9077 resource_cfg->ema_max_vap_cnt = tgt_res_cfg->ema_max_vap_cnt; 9078 resource_cfg->ema_max_profile_period = 9079 tgt_res_cfg->ema_max_profile_period; 9080 resource_cfg->ema_init_config = tgt_res_cfg->ema_init_config; 9081 resource_cfg->carrier_config = tgt_res_cfg->carrier_profile_config; 9082 9083 if (tgt_res_cfg->max_ndp_sessions) 9084 resource_cfg->max_ndp_sessions = 9085 tgt_res_cfg->max_ndp_sessions; 9086 resource_cfg->max_ndi_interfaces = tgt_res_cfg->max_ndi; 9087 resource_cfg->num_max_active_vdevs = tgt_res_cfg->num_max_active_vdevs; 9088 9089 if (tgt_res_cfg->atf_config) 9090 WMI_RSRC_CFG_FLAG_ATF_CONFIG_ENABLE_SET(resource_cfg->flag1, 1); 9091 if (tgt_res_cfg->mgmt_comp_evt_bundle_support) 9092 WMI_RSRC_CFG_FLAG_MGMT_COMP_EVT_BUNDLE_SUPPORT_SET( 9093 resource_cfg->flag1, 1); 9094 if (tgt_res_cfg->tx_msdu_new_partition_id_support) 9095 WMI_RSRC_CFG_FLAG_TX_MSDU_ID_NEW_PARTITION_SUPPORT_SET( 9096 resource_cfg->flag1, 1); 9097 if (tgt_res_cfg->cce_disable) 9098 WMI_RSRC_CFG_FLAG_TCL_CCE_DISABLE_SET(resource_cfg->flag1, 1); 9099 if (tgt_res_cfg->enable_pci_gen) 9100 WMI_RSRC_CFG_FLAG_PCIE_GEN_SWITCH_CAPABLITY_SET( 9101 resource_cfg->flag1, 1); 9102 if (tgt_res_cfg->eapol_minrate_set) { 9103 WMI_RSRC_CFG_FLAG_EAPOL_REKEY_MINRATE_SUPPORT_ENABLE_SET( 9104 resource_cfg->flag1, 1); 9105 if (tgt_res_cfg->eapol_minrate_ac_set != 3) { 9106 WMI_RSRC_CFG_FLAG_EAPOL_AC_OVERRIDE_VALID_SET( 9107 resource_cfg->flag1, 1); 9108 WMI_RSRC_CFG_FLAG_EAPOL_AC_OVERRIDE_SET( 9109 resource_cfg->flag1, 9110 tgt_res_cfg->eapol_minrate_ac_set); 9111 } 9112 } 9113 if (tgt_res_cfg->new_htt_msg_format) { 9114 WMI_RSRC_CFG_FLAG_HTT_H2T_NO_HTC_HDR_LEN_IN_MSG_LEN_SET( 9115 resource_cfg->flag1, 1); 9116 } 9117 9118 if (tgt_res_cfg->peer_unmap_conf_support) 9119 WMI_RSRC_CFG_FLAG_PEER_UNMAP_RESPONSE_SUPPORT_SET( 9120 resource_cfg->flag1, 1); 9121 9122 if (tgt_res_cfg->tstamp64_en) 9123 WMI_RSRC_CFG_FLAG_TX_COMPLETION_TX_TSF64_ENABLE_SET( 9124 resource_cfg->flag1, 1); 9125 9126 if (tgt_res_cfg->three_way_coex_config_legacy_en) 9127 WMI_RSRC_CFG_FLAG_THREE_WAY_COEX_CONFIG_LEGACY_SUPPORT_SET( 9128 resource_cfg->flag1, 1); 9129 if (tgt_res_cfg->pktcapture_support) 9130 WMI_RSRC_CFG_FLAG_PACKET_CAPTURE_SUPPORT_SET( 9131 resource_cfg->flag1, 1); 9132 9133 /* 9134 * Control padding using config param/ini of iphdr_pad_config 9135 */ 9136 if (tgt_res_cfg->iphdr_pad_config) 9137 WMI_RSRC_CFG_FLAG_IPHR_PAD_CONFIG_ENABLE_SET( 9138 resource_cfg->flag1, 1); 9139 9140 WMI_RSRC_CFG_FLAG_IPA_DISABLE_SET(resource_cfg->flag1, 9141 tgt_res_cfg->ipa_disable); 9142 9143 if (tgt_res_cfg->time_sync_ftm) 9144 WMI_RSRC_CFG_FLAG_AUDIO_SYNC_SUPPORT_SET(resource_cfg->flag1, 9145 1); 9146 9147 wmi_copy_twt_resource_config(resource_cfg, tgt_res_cfg); 9148 resource_cfg->peer_map_unmap_versions = 9149 tgt_res_cfg->peer_map_unmap_version; 9150 resource_cfg->smart_ant_cap = tgt_res_cfg->smart_ant_cap; 9151 if (tgt_res_cfg->re_ul_resp) 9152 WMI_SET_BITS(resource_cfg->flags2, 0, 4, 9153 tgt_res_cfg->re_ul_resp); 9154 9155 /* 9156 * Enable Service Aware Wifi 9157 */ 9158 if (tgt_res_cfg->sawf) 9159 WMI_RSRC_CFG_FLAGS2_SAWF_CONFIG_ENABLE_SET(resource_cfg->flags2, 9160 tgt_res_cfg->sawf); 9161 9162 /* 9163 * Enable ast flow override per peer 9164 */ 9165 resource_cfg->msdu_flow_override_config0 = 0; 9166 WMI_MSDU_FLOW_AST_ENABLE_SET( 9167 resource_cfg->msdu_flow_override_config0, 9168 WMI_CONFIG_MSDU_AST_INDEX_1, 9169 tgt_res_cfg->ast_1_valid_mask_enable); 9170 9171 WMI_MSDU_FLOW_AST_ENABLE_SET( 9172 resource_cfg->msdu_flow_override_config0, 9173 WMI_CONFIG_MSDU_AST_INDEX_2, 9174 tgt_res_cfg->ast_2_valid_mask_enable); 9175 9176 WMI_MSDU_FLOW_AST_ENABLE_SET( 9177 resource_cfg->msdu_flow_override_config0, 9178 WMI_CONFIG_MSDU_AST_INDEX_3, 9179 tgt_res_cfg->ast_3_valid_mask_enable); 9180 9181 /* 9182 * Enable ast flow mask and TID valid mask configurations 9183 */ 9184 resource_cfg->msdu_flow_override_config1 = 0; 9185 9186 /*Enable UDP flow for Ast index 0*/ 9187 WMI_MSDU_FLOW_ASTX_MSDU_FLOW_MASKS_SET( 9188 resource_cfg->msdu_flow_override_config1, 9189 WMI_CONFIG_MSDU_AST_INDEX_0, 9190 tgt_res_cfg->ast_0_flow_mask_enable); 9191 9192 /*Enable Non UDP flow for Ast index 1*/ 9193 WMI_MSDU_FLOW_ASTX_MSDU_FLOW_MASKS_SET( 9194 resource_cfg->msdu_flow_override_config1, 9195 WMI_CONFIG_MSDU_AST_INDEX_1, 9196 tgt_res_cfg->ast_1_flow_mask_enable); 9197 9198 /*Enable Hi-Priority flow for Ast index 2*/ 9199 WMI_MSDU_FLOW_ASTX_MSDU_FLOW_MASKS_SET( 9200 resource_cfg->msdu_flow_override_config1, 9201 WMI_CONFIG_MSDU_AST_INDEX_2, 9202 tgt_res_cfg->ast_2_flow_mask_enable); 9203 9204 /*Enable Low-Priority flow for Ast index 3*/ 9205 WMI_MSDU_FLOW_ASTX_MSDU_FLOW_MASKS_SET( 9206 resource_cfg->msdu_flow_override_config1, 9207 WMI_CONFIG_MSDU_AST_INDEX_3, 9208 tgt_res_cfg->ast_3_flow_mask_enable); 9209 9210 /*Enable all 8 tid for Hi-Pririty Flow Queue*/ 9211 WMI_MSDU_FLOW_TID_VALID_HI_MASKS_SET( 9212 resource_cfg->msdu_flow_override_config1, 9213 tgt_res_cfg->ast_tid_high_mask_enable); 9214 9215 /*Enable all 8 tid for Low-Pririty Flow Queue*/ 9216 WMI_MSDU_FLOW_TID_VALID_LOW_MASKS_SET( 9217 resource_cfg->msdu_flow_override_config1, 9218 tgt_res_cfg->ast_tid_low_mask_enable); 9219 WMI_RSRC_CFG_HOST_SERVICE_FLAG_NAN_IFACE_SUPPORT_SET( 9220 resource_cfg->host_service_flags, 9221 tgt_res_cfg->nan_separate_iface_support); 9222 WMI_RSRC_CFG_HOST_SERVICE_FLAG_HOST_SUPPORT_MULTI_RADIO_EVTS_PER_RADIO_SET( 9223 resource_cfg->host_service_flags, 1); 9224 9225 WMI_RSRC_CFG_FLAG_VIDEO_OVER_WIFI_ENABLE_SET( 9226 resource_cfg->flag1, tgt_res_cfg->carrier_vow_optimization); 9227 9228 if (tgt_res_cfg->is_sap_connected_d3wow_enabled) 9229 WMI_RSRC_CFG_FLAGS2_IS_SAP_CONNECTED_D3WOW_ENABLED_SET( 9230 resource_cfg->flags2, 1); 9231 if (tgt_res_cfg->is_go_connected_d3wow_enabled) 9232 WMI_RSRC_CFG_FLAGS2_IS_GO_CONNECTED_D3WOW_ENABLED_SET( 9233 resource_cfg->flags2, 1); 9234 9235 if (tgt_res_cfg->sae_eapol_offload) 9236 WMI_RSRC_CFG_HOST_SERVICE_FLAG_SAE_EAPOL_OFFLOAD_SUPPORT_SET( 9237 resource_cfg->host_service_flags, 1); 9238 9239 WMI_RSRC_CFG_HOST_SERVICE_FLAG_REG_CC_EXT_SUPPORT_SET( 9240 resource_cfg->host_service_flags, 9241 tgt_res_cfg->is_reg_cc_ext_event_supported); 9242 9243 WMI_RSRC_CFG_HOST_SERVICE_FLAG_BANG_RADAR_320M_SUPPORT_SET( 9244 resource_cfg->host_service_flags, 9245 tgt_res_cfg->is_host_dfs_320mhz_bangradar_supported); 9246 9247 WMI_RSRC_CFG_HOST_SERVICE_FLAG_LPI_SP_MODE_SUPPORT_SET( 9248 resource_cfg->host_service_flags, 9249 tgt_res_cfg->is_6ghz_sp_pwrmode_supp_enabled); 9250 9251 WMI_RSRC_CFG_HOST_SERVICE_FLAG_REG_DISCARD_AFC_TIMER_CHECK_SET( 9252 resource_cfg->host_service_flags, 9253 tgt_res_cfg->afc_timer_check_disable); 9254 9255 WMI_RSRC_CFG_HOST_SERVICE_FLAG_REG_DISCARD_AFC_REQ_ID_CHECK_SET( 9256 resource_cfg->host_service_flags, 9257 tgt_res_cfg->afc_req_id_check_disable); 9258 9259 wmi_copy_afc_deployment_config(resource_cfg, tgt_res_cfg); 9260 9261 wmi_set_nan_channel_support(resource_cfg); 9262 9263 if (tgt_res_cfg->twt_ack_support_cap) 9264 WMI_RSRC_CFG_HOST_SERVICE_FLAG_STA_TWT_SYNC_EVT_SUPPORT_SET( 9265 resource_cfg->host_service_flags, 1); 9266 9267 if (tgt_res_cfg->reo_qdesc_shared_addr_table_enabled) 9268 WMI_RSRC_CFG_HOST_SERVICE_FLAG_REO_QREF_FEATURE_SUPPORT_SET( 9269 resource_cfg->host_service_flags, 1); 9270 9271 WMI_RSRC_CFG_FLAGS2_RX_PEER_METADATA_VERSION_SET(resource_cfg->flags2, 9272 tgt_res_cfg->target_cap_flags); 9273 if (tgt_res_cfg->notify_frame_support) 9274 WMI_RSRC_CFG_FLAGS2_NOTIFY_FRAME_CONFIG_ENABLE_SET( 9275 resource_cfg->flags2, 1); 9276 9277 } 9278 9279 #ifdef FEATURE_SET 9280 /** 9281 * convert_host_to_target_vendor1_req2_version() -Convert host vendor1 9282 * requirement2 version to target vendor1 requirement2 version 9283 * @vendor1_req2_ver: Host vendor1 requirement2 version 9284 * 9285 * Return: Target vendor1 requirement2 version 9286 */ 9287 static WMI_VENDOR1_REQ2_VERSION convert_host_to_target_vendor1_req2_version( 9288 WMI_HOST_VENDOR1_REQ2_VERSION vendor1_req2_ver) 9289 { 9290 switch (vendor1_req2_ver) { 9291 case WMI_HOST_VENDOR1_REQ2_VERSION_3_00: 9292 return WMI_VENDOR1_REQ2_VERSION_3_00; 9293 case WMI_HOST_VENDOR1_REQ2_VERSION_3_01: 9294 return WMI_VENDOR1_REQ2_VERSION_3_01; 9295 case WMI_HOST_VENDOR1_REQ2_VERSION_3_20: 9296 return WMI_VENDOR1_REQ2_VERSION_3_20; 9297 default: 9298 return WMI_VENDOR1_REQ2_VERSION_3_00; 9299 } 9300 } 9301 9302 /** 9303 * convert_host_to_target_vendor1_req1_version() -Convert host vendor1 9304 * requirement1 version to target vendor1 requirement1 version 9305 * @vendor1_req1_ver: Host vendor1 requirement1 version 9306 * 9307 * Return: Target vendor1 requirement1 version 9308 */ 9309 static WMI_VENDOR1_REQ1_VERSION convert_host_to_target_vendor1_req1_version( 9310 WMI_HOST_VENDOR1_REQ1_VERSION vendor1_req1_ver) 9311 { 9312 switch (vendor1_req1_ver) { 9313 case WMI_HOST_VENDOR1_REQ1_VERSION_3_00: 9314 return WMI_VENDOR1_REQ1_VERSION_3_00; 9315 case WMI_HOST_VENDOR1_REQ1_VERSION_3_01: 9316 return WMI_VENDOR1_REQ1_VERSION_3_01; 9317 case WMI_HOST_VENDOR1_REQ1_VERSION_3_20: 9318 return WMI_VENDOR1_REQ1_VERSION_3_20; 9319 case WMI_HOST_VENDOR1_REQ1_VERSION_3_30: 9320 return WMI_VENDOR1_REQ1_VERSION_3_30; 9321 case WMI_HOST_VENDOR1_REQ1_VERSION_3_40: 9322 return WMI_VENDOR1_REQ1_VERSION_3_40; 9323 default: 9324 return WMI_VENDOR1_REQ1_VERSION_3_00; 9325 } 9326 } 9327 9328 /** 9329 * convert_host_to_target_wifi_standard() -Convert host wifi standard to 9330 * target wifi standard 9331 * @wifi_standard: Host wifi standard 9332 * 9333 * Return: Target wifi standard 9334 */ 9335 static WMI_WIFI_STANDARD convert_host_to_target_wifi_standard( 9336 WMI_HOST_WIFI_STANDARD wifi_standard) 9337 { 9338 switch (wifi_standard) { 9339 case WMI_HOST_WIFI_STANDARD_4: 9340 return WMI_WIFI_STANDARD_4; 9341 case WMI_HOST_WIFI_STANDARD_5: 9342 return WMI_WIFI_STANDARD_5; 9343 case WMI_HOST_WIFI_STANDARD_6: 9344 return WMI_WIFI_STANDARD_6; 9345 case WMI_HOST_WIFI_STANDARD_6E: 9346 return WMI_WIFI_STANDARD_6E; 9347 case WMI_HOST_WIFI_STANDARD_7: 9348 return WMI_WIFI_STANDARD_7; 9349 default: 9350 return WMI_WIFI_STANDARD_4; 9351 } 9352 } 9353 9354 /** 9355 * convert_host_to_target_band_concurrency() -Convert host band concurrency to 9356 * target band concurrency 9357 * @band_concurrency: Host Band concurrency 9358 * 9359 * Return: Target band concurrency 9360 */ 9361 static WMI_BAND_CONCURRENCY convert_host_to_target_band_concurrency( 9362 WMI_HOST_BAND_CONCURRENCY band_concurrency) 9363 { 9364 switch (band_concurrency) { 9365 case WMI_HOST_BAND_CONCURRENCY_DBS: 9366 return WMI_HOST_DBS; 9367 case WMI_HOST_BAND_CONCURRENCY_DBS_SBS: 9368 return WMI_HOST_DBS_SBS; 9369 default: 9370 return WMI_HOST_NONE; 9371 } 9372 } 9373 9374 /** 9375 * convert_host_to_target_num_antennas() -Convert host num antennas to 9376 * target num antennas 9377 * @num_antennas: Host num antennas 9378 * 9379 * Return: Target num antennas 9380 */ 9381 static WMI_NUM_ANTENNAS convert_host_to_target_num_antennas( 9382 WMI_HOST_NUM_ANTENNAS num_antennas) 9383 { 9384 switch (num_antennas) { 9385 case WMI_HOST_SISO: 9386 return WMI_SISO; 9387 case WMI_HOST_MIMO_2X2: 9388 return WMI_MIMO_2X2; 9389 default: 9390 return WMI_SISO; 9391 } 9392 } 9393 9394 /** 9395 * convert_host_to_target_band_capability() -Convert host band capability to 9396 * target band capability 9397 * @host_band_capability: Host band capability 9398 * 9399 * Return: Target band capability bitmap 9400 */ 9401 static uint8_t 9402 convert_host_to_target_band_capability(uint32_t host_band_capability) 9403 { 9404 uint8_t band_capability; 9405 9406 band_capability = (host_band_capability & WMI_HOST_BAND_CAP_2GHZ) | 9407 (host_band_capability & WMI_HOST_BAND_CAP_5GHZ) | 9408 (host_band_capability & WMI_HOST_BAND_CAP_6GHZ); 9409 return band_capability; 9410 } 9411 9412 /** 9413 * copy_feature_set_info() -Copy feature set info from host to target 9414 * @feature_set_bitmap: Target feature set pointer 9415 * @feature_set: Host feature set structure 9416 * 9417 * Return: None 9418 */ 9419 static inline void copy_feature_set_info(uint32_t *feature_set_bitmap, 9420 struct target_feature_set *feature_set) 9421 { 9422 WMI_NUM_ANTENNAS num_antennas; 9423 WMI_BAND_CONCURRENCY band_concurrency; 9424 WMI_WIFI_STANDARD wifi_standard; 9425 WMI_VENDOR1_REQ1_VERSION vendor1_req1_version; 9426 WMI_VENDOR1_REQ2_VERSION vendor1_req2_version; 9427 uint8_t band_capability; 9428 9429 num_antennas = convert_host_to_target_num_antennas( 9430 feature_set->num_antennas); 9431 band_concurrency = convert_host_to_target_band_concurrency( 9432 feature_set->concurrency_support); 9433 wifi_standard = convert_host_to_target_wifi_standard( 9434 feature_set->wifi_standard); 9435 vendor1_req1_version = convert_host_to_target_vendor1_req1_version( 9436 feature_set->vendor_req_1_version); 9437 vendor1_req2_version = convert_host_to_target_vendor1_req2_version( 9438 feature_set->vendor_req_2_version); 9439 9440 band_capability = 9441 convert_host_to_target_band_capability( 9442 feature_set->band_capability); 9443 9444 WMI_SET_WIFI_STANDARD(feature_set_bitmap, wifi_standard); 9445 WMI_SET_BAND_CONCURRENCY_SUPPORT(feature_set_bitmap, band_concurrency); 9446 WMI_SET_PNO_SCAN_IN_UNASSOC_STATE(feature_set_bitmap, 9447 feature_set->pno_in_unassoc_state); 9448 WMI_SET_PNO_SCAN_IN_ASSOC_STATE(feature_set_bitmap, 9449 feature_set->pno_in_assoc_state); 9450 WMI_SET_TWT_FEATURE_SUPPORT(feature_set_bitmap, 9451 feature_set->enable_twt); 9452 WMI_SET_TWT_REQUESTER(feature_set_bitmap, 9453 feature_set->enable_twt_requester); 9454 WMI_SET_TWT_BROADCAST(feature_set_bitmap, 9455 feature_set->enable_twt_broadcast); 9456 WMI_SET_TWT_FLEXIBLE(feature_set_bitmap, 9457 feature_set->enable_twt_flexible); 9458 WMI_SET_WIFI_OPT_FEATURE_SUPPORT(feature_set_bitmap, 9459 feature_set->enable_wifi_optimizer); 9460 WMI_SET_RFC8325_FEATURE_SUPPORT(feature_set_bitmap, 9461 feature_set->enable_rfc835); 9462 WMI_SET_MHS_5G_SUPPORT(feature_set_bitmap, 9463 feature_set->sap_5g_supported); 9464 WMI_SET_MHS_6G_SUPPORT(feature_set_bitmap, 9465 feature_set->sap_6g_supported); 9466 WMI_SET_MHS_MAX_CLIENTS_SUPPORT(feature_set_bitmap, 9467 feature_set->sap_max_num_clients); 9468 WMI_SET_MHS_SET_COUNTRY_CODE_HAL_SUPPORT( 9469 feature_set_bitmap, 9470 feature_set->set_country_code_hal_supported); 9471 WMI_SET_MHS_GETVALID_CHANNELS_SUPPORT( 9472 feature_set_bitmap, 9473 feature_set->get_valid_channel_supported); 9474 WMI_SET_MHS_DOT11_MODE_SUPPORT(feature_set_bitmap, 9475 feature_set->supported_dot11mode); 9476 WMI_SET_MHS_WPA3_SUPPORT(feature_set_bitmap, 9477 feature_set->sap_wpa3_support); 9478 WMI_SET_VENDOR_REQ_1_VERSION(feature_set_bitmap, vendor1_req1_version); 9479 WMI_SET_ROAMING_HIGH_CU_ROAM_TRIGGER( 9480 feature_set_bitmap, 9481 feature_set->roaming_high_cu_roam_trigger); 9482 WMI_SET_ROAMING_EMERGENCY_TRIGGER( 9483 feature_set_bitmap, 9484 feature_set->roaming_emergency_trigger); 9485 WMI_SET_ROAMING_BTM_TRIGGER(feature_set_bitmap, 9486 feature_set->roaming_btm_trihgger); 9487 WMI_SET_ROAMING_IDLE_TRIGGER(feature_set_bitmap, 9488 feature_set->roaming_idle_trigger); 9489 WMI_SET_ROAMING_WTC_TRIGGER(feature_set_bitmap, 9490 feature_set->roaming_wtc_trigger); 9491 WMI_SET_ROAMING_BTCOEX_TRIGGER(feature_set_bitmap, 9492 feature_set->roaming_btcoex_trigger); 9493 WMI_SET_ROAMING_BTW_WPA_WPA2(feature_set_bitmap, 9494 feature_set->roaming_btw_wpa_wpa2); 9495 WMI_SET_ROAMING_MANAGE_CHAN_LIST_API( 9496 feature_set_bitmap, 9497 feature_set->roaming_manage_chan_list_api); 9498 WMI_SET_ROAMING_ADAPTIVE_11R(feature_set_bitmap, 9499 feature_set->roaming_adaptive_11r); 9500 WMI_SET_ROAMING_CTRL_API_GET_SET(feature_set_bitmap, 9501 feature_set->roaming_ctrl_api_get_set); 9502 WMI_SET_ROAMING_CTRL_API_REASSOC(feature_set_bitmap, 9503 feature_set->roaming_ctrl_api_reassoc); 9504 WMI_SET_ROAMING_CTRL_GET_CU(feature_set_bitmap, 9505 feature_set->roaming_ctrl_get_cu); 9506 WMI_SET_VENDOR_REQ_2_VERSION(feature_set_bitmap, vendor1_req2_version); 9507 WMI_SET_ASSURANCE_DISCONNECT_REASON_API( 9508 feature_set_bitmap, 9509 feature_set->assurance_disconnect_reason_api); 9510 WMI_SET_FRAME_PCAP_LOG_MGMT(feature_set_bitmap, 9511 feature_set->frame_pcap_log_mgmt); 9512 WMI_SET_FRAME_PCAP_LOG_CTRL(feature_set_bitmap, 9513 feature_set->frame_pcap_log_ctrl); 9514 WMI_SET_FRAME_PCAP_LOG_DATA(feature_set_bitmap, 9515 feature_set->frame_pcap_log_data); 9516 WMI_SET_SECURITY_WPA3_SAE_H2E(feature_set_bitmap, 9517 feature_set->security_wpa3_sae_h2e); 9518 WMI_SET_SECURITY_WPA3_SAE_FT(feature_set_bitmap, 9519 feature_set->security_wpa3_sae_ft); 9520 WMI_SET_SECURITY_WPA3_ENTERP_SUITEB( 9521 feature_set_bitmap, 9522 feature_set->security_wpa3_enterp_suitb); 9523 WMI_SET_SECURITY_WPA3_ENTERP_SUITEB_192bit( 9524 feature_set_bitmap, 9525 feature_set->security_wpa3_enterp_suitb_192bit); 9526 WMI_SET_SECURITY_FILS_SHA256(feature_set_bitmap, 9527 feature_set->security_fills_sha_256); 9528 WMI_SET_SECURITY_FILS_SHA384(feature_set_bitmap, 9529 feature_set->security_fills_sha_384); 9530 WMI_SET_SECURITY_FILS_SHA256_FT(feature_set_bitmap, 9531 feature_set->security_fills_sha_256_FT); 9532 WMI_SET_SECURITY_FILS_SHA384_FT(feature_set_bitmap, 9533 feature_set->security_fills_sha_384_FT); 9534 WMI_SET_SECURITY_ENCHANCED_OPEN(feature_set_bitmap, 9535 feature_set->security_enhanced_open); 9536 WMI_SET_NAN_SUPPORT(feature_set_bitmap, feature_set->enable_nan); 9537 WMI_SET_TDLS_SUPPORT(feature_set_bitmap, feature_set->enable_tdls); 9538 WMI_SET_P2P6E_SUPPORT(feature_set_bitmap, feature_set->enable_p2p_6e); 9539 WMI_SET_TDLS_OFFCHAN_SUPPORT(feature_set_bitmap, 9540 feature_set->enable_tdls_offchannel); 9541 WMI_SET_TDLS_CAP_ENHANCE(feature_set_bitmap, 9542 feature_set->enable_tdls_capability_enhance); 9543 WMI_SET_MAX_TDLS_PEERS_SUPPORT(feature_set_bitmap, 9544 feature_set->max_tdls_peers); 9545 WMI_SET_STA_DUAL_P2P_SUPPORT(feature_set_bitmap, 9546 feature_set->sta_dual_p2p_support); 9547 WMI_SET_PEER_BIGDATA_GETBSSINFO_API_SUPPORT( 9548 feature_set_bitmap, 9549 feature_set->peer_bigdata_getbssinfo_support); 9550 WMI_SET_PEER_BIGDATA_GETASSOCREJECTINFO_API_SUPPORT( 9551 feature_set_bitmap, 9552 feature_set->peer_bigdata_assocreject_info_support); 9553 WMI_SET_PEER_BIGDATA_GETSTAINFO_API_SUPPORT( 9554 feature_set_bitmap, 9555 feature_set->peer_getstainfo_support); 9556 WMI_SET_FEATURE_SET_VERSION(feature_set_bitmap, 9557 feature_set->feature_set_version); 9558 WMI_SET_NUM_ANTENNAS(feature_set_bitmap, num_antennas); 9559 WMI_SET_HOST_BAND_CAP(feature_set_bitmap, band_capability); 9560 } 9561 9562 /** 9563 * feature_set_cmd_send_tlv() -Send feature set command 9564 * @wmi_handle: WMI handle 9565 * @feature_set: Feature set structure 9566 * 9567 * Return: QDF_STATUS_SUCCESS on success else return failure 9568 */ 9569 static QDF_STATUS feature_set_cmd_send_tlv( 9570 struct wmi_unified *wmi_handle, 9571 struct target_feature_set *feature_set) 9572 { 9573 wmi_pdev_featureset_cmd_fixed_param *cmd; 9574 wmi_buf_t buf; 9575 uint16_t len; 9576 QDF_STATUS ret; 9577 uint8_t *buf_ptr; 9578 uint32_t *feature_set_bitmap; 9579 9580 len = sizeof(*cmd) + WMI_TLV_HDR_SIZE + 9581 WMI_FEATURE_SET_BITMAP_ARRAY_LEN32 * sizeof(uint32_t); 9582 buf = wmi_buf_alloc(wmi_handle, len); 9583 9584 if (!buf) 9585 return QDF_STATUS_E_NOMEM; 9586 9587 wmi_debug("Send feature set param"); 9588 9589 buf_ptr = (uint8_t *)wmi_buf_data(buf); 9590 9591 cmd = (wmi_pdev_featureset_cmd_fixed_param *)wmi_buf_data(buf); 9592 9593 WMITLV_SET_HDR(&cmd->tlv_header, 9594 WMITLV_TAG_STRUC_wmi_pdev_featureset_cmd_fixed_param, 9595 WMITLV_GET_STRUCT_TLVLEN( 9596 wmi_pdev_featureset_cmd_fixed_param)); 9597 9598 feature_set_bitmap = (uint32_t *)(buf_ptr + sizeof(*cmd) + 9599 WMI_TLV_HDR_SIZE); 9600 WMITLV_SET_HDR(buf_ptr + sizeof(*cmd), WMITLV_TAG_ARRAY_UINT32, 9601 (WMI_FEATURE_SET_BITMAP_ARRAY_LEN32 * sizeof(uint32_t))); 9602 copy_feature_set_info(feature_set_bitmap, feature_set); 9603 9604 qdf_trace_hex_dump(QDF_MODULE_ID_WMI, QDF_TRACE_LEVEL_DEBUG, 9605 feature_set_bitmap, 9606 WMI_FEATURE_SET_BITMAP_ARRAY_LEN32 * 9607 sizeof(uint32_t)); 9608 9609 wmi_mtrace(WMI_PDEV_FEATURESET_CMDID, NO_SESSION, 0); 9610 9611 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 9612 WMI_PDEV_FEATURESET_CMDID); 9613 if (QDF_IS_STATUS_ERROR(ret)) 9614 wmi_buf_free(buf); 9615 9616 return ret; 9617 } 9618 #endif 9619 9620 /* copy_hw_mode_id_in_init_cmd() - Helper routine to copy hw_mode in init cmd 9621 * @wmi_handle: pointer to wmi handle 9622 * @buf_ptr: pointer to current position in init command buffer 9623 * @len: pointer to length. This will be updated with current length of cmd 9624 * @param: point host parameters for init command 9625 * 9626 * Return: Updated pointer of buf_ptr. 9627 */ 9628 static inline uint8_t *copy_hw_mode_in_init_cmd(struct wmi_unified *wmi_handle, 9629 uint8_t *buf_ptr, int *len, struct wmi_init_cmd_param *param) 9630 { 9631 uint16_t idx; 9632 9633 if (param->hw_mode_id != WMI_HOST_HW_MODE_MAX) { 9634 wmi_pdev_set_hw_mode_cmd_fixed_param *hw_mode; 9635 wmi_pdev_band_to_mac *band_to_mac; 9636 9637 hw_mode = (wmi_pdev_set_hw_mode_cmd_fixed_param *) 9638 (buf_ptr + sizeof(wmi_init_cmd_fixed_param) + 9639 sizeof(wmi_resource_config) + 9640 WMI_TLV_HDR_SIZE + (param->num_mem_chunks * 9641 sizeof(wlan_host_memory_chunk))); 9642 9643 WMITLV_SET_HDR(&hw_mode->tlv_header, 9644 WMITLV_TAG_STRUC_wmi_pdev_set_hw_mode_cmd_fixed_param, 9645 (WMITLV_GET_STRUCT_TLVLEN 9646 (wmi_pdev_set_hw_mode_cmd_fixed_param))); 9647 9648 hw_mode->hw_mode_index = param->hw_mode_id; 9649 hw_mode->num_band_to_mac = param->num_band_to_mac; 9650 9651 buf_ptr = (uint8_t *) (hw_mode + 1); 9652 band_to_mac = (wmi_pdev_band_to_mac *) (buf_ptr + 9653 WMI_TLV_HDR_SIZE); 9654 for (idx = 0; idx < param->num_band_to_mac; idx++) { 9655 WMITLV_SET_HDR(&band_to_mac[idx].tlv_header, 9656 WMITLV_TAG_STRUC_wmi_pdev_band_to_mac, 9657 WMITLV_GET_STRUCT_TLVLEN 9658 (wmi_pdev_band_to_mac)); 9659 band_to_mac[idx].pdev_id = 9660 wmi_handle->ops->convert_pdev_id_host_to_target( 9661 wmi_handle, 9662 param->band_to_mac[idx].pdev_id); 9663 band_to_mac[idx].start_freq = 9664 param->band_to_mac[idx].start_freq; 9665 band_to_mac[idx].end_freq = 9666 param->band_to_mac[idx].end_freq; 9667 } 9668 *len += sizeof(wmi_pdev_set_hw_mode_cmd_fixed_param) + 9669 (param->num_band_to_mac * 9670 sizeof(wmi_pdev_band_to_mac)) + 9671 WMI_TLV_HDR_SIZE; 9672 9673 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 9674 (param->num_band_to_mac * 9675 sizeof(wmi_pdev_band_to_mac))); 9676 } 9677 9678 return buf_ptr; 9679 } 9680 9681 static inline void copy_fw_abi_version_tlv(wmi_unified_t wmi_handle, 9682 wmi_init_cmd_fixed_param *cmd) 9683 { 9684 int num_allowlist; 9685 wmi_abi_version my_vers; 9686 9687 num_allowlist = sizeof(version_whitelist) / 9688 sizeof(wmi_whitelist_version_info); 9689 my_vers.abi_version_0 = WMI_ABI_VERSION_0; 9690 my_vers.abi_version_1 = WMI_ABI_VERSION_1; 9691 my_vers.abi_version_ns_0 = WMI_ABI_VERSION_NS_0; 9692 my_vers.abi_version_ns_1 = WMI_ABI_VERSION_NS_1; 9693 my_vers.abi_version_ns_2 = WMI_ABI_VERSION_NS_2; 9694 my_vers.abi_version_ns_3 = WMI_ABI_VERSION_NS_3; 9695 9696 wmi_cmp_and_set_abi_version(num_allowlist, version_whitelist, 9697 &my_vers, 9698 (struct _wmi_abi_version *)&wmi_handle->fw_abi_version, 9699 &cmd->host_abi_vers); 9700 9701 wmi_debug("INIT_CMD version: %d, %d, 0x%x, 0x%x, 0x%x, 0x%x", 9702 WMI_VER_GET_MAJOR(cmd->host_abi_vers.abi_version_0), 9703 WMI_VER_GET_MINOR(cmd->host_abi_vers.abi_version_0), 9704 cmd->host_abi_vers.abi_version_ns_0, 9705 cmd->host_abi_vers.abi_version_ns_1, 9706 cmd->host_abi_vers.abi_version_ns_2, 9707 cmd->host_abi_vers.abi_version_ns_3); 9708 9709 /* Save version sent from host - 9710 * Will be used to check ready event 9711 */ 9712 qdf_mem_copy(&wmi_handle->final_abi_vers, &cmd->host_abi_vers, 9713 sizeof(wmi_abi_version)); 9714 } 9715 9716 /* 9717 * send_cfg_action_frm_tb_ppdu_cmd_tlv() - send action frame tb ppdu cfg to FW 9718 * @wmi_handle: Pointer to WMi handle 9719 * @ie_data: Pointer for ie data 9720 * 9721 * This function sends action frame tb ppdu cfg to FW 9722 * 9723 * Return: QDF_STATUS_SUCCESS for success otherwise failure 9724 * 9725 */ 9726 static QDF_STATUS send_cfg_action_frm_tb_ppdu_cmd_tlv(wmi_unified_t wmi_handle, 9727 struct cfg_action_frm_tb_ppdu_param *cfg_msg) 9728 { 9729 wmi_pdev_he_tb_action_frm_cmd_fixed_param *cmd; 9730 wmi_buf_t buf; 9731 uint8_t *buf_ptr; 9732 uint32_t len, frm_len_aligned; 9733 QDF_STATUS ret; 9734 9735 frm_len_aligned = roundup(cfg_msg->frm_len, sizeof(uint32_t)); 9736 /* Allocate memory for the WMI command */ 9737 len = sizeof(*cmd) + WMI_TLV_HDR_SIZE + frm_len_aligned; 9738 9739 buf = wmi_buf_alloc(wmi_handle, len); 9740 if (!buf) 9741 return QDF_STATUS_E_NOMEM; 9742 9743 buf_ptr = wmi_buf_data(buf); 9744 qdf_mem_zero(buf_ptr, len); 9745 9746 /* Populate the WMI command */ 9747 cmd = (wmi_pdev_he_tb_action_frm_cmd_fixed_param *)buf_ptr; 9748 9749 WMITLV_SET_HDR(&cmd->tlv_header, 9750 WMITLV_TAG_STRUC_wmi_pdev_he_tb_action_frm_cmd_fixed_param, 9751 WMITLV_GET_STRUCT_TLVLEN( 9752 wmi_pdev_he_tb_action_frm_cmd_fixed_param)); 9753 cmd->enable = cfg_msg->cfg; 9754 cmd->data_len = cfg_msg->frm_len; 9755 9756 buf_ptr += sizeof(*cmd); 9757 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, frm_len_aligned); 9758 buf_ptr += WMI_TLV_HDR_SIZE; 9759 9760 qdf_mem_copy(buf_ptr, cfg_msg->data, cmd->data_len); 9761 9762 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 9763 WMI_PDEV_HE_TB_ACTION_FRM_CMDID); 9764 if (QDF_IS_STATUS_ERROR(ret)) { 9765 wmi_err("HE TB action frame cmnd send fail, ret %d", ret); 9766 wmi_buf_free(buf); 9767 } 9768 9769 return ret; 9770 } 9771 9772 static QDF_STATUS save_fw_version_cmd_tlv(wmi_unified_t wmi_handle, void *evt_buf) 9773 { 9774 WMI_SERVICE_READY_EVENTID_param_tlvs *param_buf; 9775 wmi_service_ready_event_fixed_param *ev; 9776 9777 9778 param_buf = (WMI_SERVICE_READY_EVENTID_param_tlvs *) evt_buf; 9779 9780 ev = (wmi_service_ready_event_fixed_param *) param_buf->fixed_param; 9781 if (!ev) 9782 return QDF_STATUS_E_FAILURE; 9783 9784 /*Save fw version from service ready message */ 9785 /*This will be used while sending INIT message */ 9786 qdf_mem_copy(&wmi_handle->fw_abi_version, &ev->fw_abi_vers, 9787 sizeof(wmi_handle->fw_abi_version)); 9788 9789 return QDF_STATUS_SUCCESS; 9790 } 9791 9792 /** 9793 * check_and_update_fw_version_cmd_tlv() - save fw version 9794 * @wmi_handle: pointer to wmi handle 9795 * @evt_buf: pointer to the event buffer 9796 * 9797 * This function extracts and saves the firmware WMI ABI version 9798 * 9799 * Return: QDF_STATUS_SUCCESS for success otherwise failure 9800 * 9801 */ 9802 static QDF_STATUS check_and_update_fw_version_cmd_tlv(wmi_unified_t wmi_handle, 9803 void *evt_buf) 9804 { 9805 WMI_READY_EVENTID_param_tlvs *param_buf = NULL; 9806 wmi_ready_event_fixed_param *ev = NULL; 9807 9808 param_buf = (WMI_READY_EVENTID_param_tlvs *) evt_buf; 9809 ev = param_buf->fixed_param; 9810 if (!wmi_versions_are_compatible((struct _wmi_abi_version *) 9811 &wmi_handle->final_abi_vers, 9812 &ev->fw_abi_vers)) { 9813 /* 9814 * Error: Our host version and the given firmware version 9815 * are incompatible. 9816 **/ 9817 wmi_debug("Error: Incompatible WMI version." 9818 "Host: %d,%d,0x%x 0x%x 0x%x 0x%x, FW: %d,%d,0x%x 0x%x 0x%x 0x%x", 9819 WMI_VER_GET_MAJOR(wmi_handle->final_abi_vers. 9820 abi_version_0), 9821 WMI_VER_GET_MINOR(wmi_handle->final_abi_vers. 9822 abi_version_0), 9823 wmi_handle->final_abi_vers.abi_version_ns_0, 9824 wmi_handle->final_abi_vers.abi_version_ns_1, 9825 wmi_handle->final_abi_vers.abi_version_ns_2, 9826 wmi_handle->final_abi_vers.abi_version_ns_3, 9827 WMI_VER_GET_MAJOR(ev->fw_abi_vers.abi_version_0), 9828 WMI_VER_GET_MINOR(ev->fw_abi_vers.abi_version_0), 9829 ev->fw_abi_vers.abi_version_ns_0, 9830 ev->fw_abi_vers.abi_version_ns_1, 9831 ev->fw_abi_vers.abi_version_ns_2, 9832 ev->fw_abi_vers.abi_version_ns_3); 9833 9834 return QDF_STATUS_E_FAILURE; 9835 } 9836 qdf_mem_copy(&wmi_handle->final_abi_vers, &ev->fw_abi_vers, 9837 sizeof(wmi_abi_version)); 9838 qdf_mem_copy(&wmi_handle->fw_abi_version, &ev->fw_abi_vers, 9839 sizeof(wmi_abi_version)); 9840 9841 return QDF_STATUS_SUCCESS; 9842 } 9843 9844 /** 9845 * send_log_supported_evt_cmd_tlv() - Enable/Disable FW diag/log events 9846 * @wmi_handle: wmi handle 9847 * @event: Event received from FW 9848 * @len: Length of the event 9849 * 9850 * Enables the low frequency events and disables the high frequency 9851 * events. Bit 17 indicates if the event if low/high frequency. 9852 * 1 - high frequency, 0 - low frequency 9853 * 9854 * Return: QDF_STATUS_SUCCESS for success or error code 9855 */ 9856 static QDF_STATUS send_log_supported_evt_cmd_tlv(wmi_unified_t wmi_handle, 9857 uint8_t *event, 9858 uint32_t len) 9859 { 9860 uint32_t num_of_diag_events_logs; 9861 wmi_diag_event_log_config_fixed_param *cmd; 9862 wmi_buf_t buf; 9863 uint8_t *buf_ptr; 9864 uint32_t *cmd_args, *evt_args; 9865 uint32_t buf_len, i; 9866 9867 WMI_DIAG_EVENT_LOG_SUPPORTED_EVENTID_param_tlvs *param_buf; 9868 wmi_diag_event_log_supported_event_fixed_params *wmi_event; 9869 9870 wmi_debug("Received WMI_DIAG_EVENT_LOG_SUPPORTED_EVENTID"); 9871 9872 param_buf = (WMI_DIAG_EVENT_LOG_SUPPORTED_EVENTID_param_tlvs *) event; 9873 if (!param_buf) { 9874 wmi_err("Invalid log supported event buffer"); 9875 return QDF_STATUS_E_INVAL; 9876 } 9877 wmi_event = param_buf->fixed_param; 9878 num_of_diag_events_logs = wmi_event->num_of_diag_events_logs; 9879 9880 if (num_of_diag_events_logs > 9881 param_buf->num_diag_events_logs_list) { 9882 wmi_err("message number of events %d is more than tlv hdr content %d", 9883 num_of_diag_events_logs, 9884 param_buf->num_diag_events_logs_list); 9885 return QDF_STATUS_E_INVAL; 9886 } 9887 9888 evt_args = param_buf->diag_events_logs_list; 9889 if (!evt_args) { 9890 wmi_err("Event list is empty, num_of_diag_events_logs=%d", 9891 num_of_diag_events_logs); 9892 return QDF_STATUS_E_INVAL; 9893 } 9894 9895 wmi_debug("num_of_diag_events_logs=%d", num_of_diag_events_logs); 9896 9897 /* Free any previous allocation */ 9898 if (wmi_handle->events_logs_list) { 9899 qdf_mem_free(wmi_handle->events_logs_list); 9900 wmi_handle->events_logs_list = NULL; 9901 } 9902 9903 if (num_of_diag_events_logs > 9904 (WMI_SVC_MSG_MAX_SIZE / sizeof(uint32_t))) { 9905 wmi_err("excess num of logs: %d", num_of_diag_events_logs); 9906 QDF_ASSERT(0); 9907 return QDF_STATUS_E_INVAL; 9908 } 9909 /* Store the event list for run time enable/disable */ 9910 wmi_handle->events_logs_list = qdf_mem_malloc(num_of_diag_events_logs * 9911 sizeof(uint32_t)); 9912 if (!wmi_handle->events_logs_list) 9913 return QDF_STATUS_E_NOMEM; 9914 9915 wmi_handle->num_of_diag_events_logs = num_of_diag_events_logs; 9916 9917 /* Prepare the send buffer */ 9918 buf_len = sizeof(*cmd) + WMI_TLV_HDR_SIZE + 9919 (num_of_diag_events_logs * sizeof(uint32_t)); 9920 9921 buf = wmi_buf_alloc(wmi_handle, buf_len); 9922 if (!buf) { 9923 qdf_mem_free(wmi_handle->events_logs_list); 9924 wmi_handle->events_logs_list = NULL; 9925 return QDF_STATUS_E_NOMEM; 9926 } 9927 9928 cmd = (wmi_diag_event_log_config_fixed_param *) wmi_buf_data(buf); 9929 buf_ptr = (uint8_t *) cmd; 9930 9931 WMITLV_SET_HDR(&cmd->tlv_header, 9932 WMITLV_TAG_STRUC_wmi_diag_event_log_config_fixed_param, 9933 WMITLV_GET_STRUCT_TLVLEN( 9934 wmi_diag_event_log_config_fixed_param)); 9935 9936 cmd->num_of_diag_events_logs = num_of_diag_events_logs; 9937 9938 buf_ptr += sizeof(wmi_diag_event_log_config_fixed_param); 9939 9940 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, 9941 (num_of_diag_events_logs * sizeof(uint32_t))); 9942 9943 cmd_args = (uint32_t *) (buf_ptr + WMI_TLV_HDR_SIZE); 9944 9945 /* Populate the events */ 9946 for (i = 0; i < num_of_diag_events_logs; i++) { 9947 /* Low freq (0) - Enable (1) the event 9948 * High freq (1) - Disable (0) the event 9949 */ 9950 WMI_DIAG_ID_ENABLED_DISABLED_SET(cmd_args[i], 9951 !(WMI_DIAG_FREQUENCY_GET(evt_args[i]))); 9952 /* Set the event ID */ 9953 WMI_DIAG_ID_SET(cmd_args[i], 9954 WMI_DIAG_ID_GET(evt_args[i])); 9955 /* Set the type */ 9956 WMI_DIAG_TYPE_SET(cmd_args[i], 9957 WMI_DIAG_TYPE_GET(evt_args[i])); 9958 /* Storing the event/log list in WMI */ 9959 wmi_handle->events_logs_list[i] = evt_args[i]; 9960 } 9961 9962 wmi_mtrace(WMI_DIAG_EVENT_LOG_CONFIG_CMDID, NO_SESSION, 0); 9963 if (wmi_unified_cmd_send(wmi_handle, buf, buf_len, 9964 WMI_DIAG_EVENT_LOG_CONFIG_CMDID)) { 9965 wmi_err("WMI_DIAG_EVENT_LOG_CONFIG_CMDID failed"); 9966 wmi_buf_free(buf); 9967 /* Not clearing events_logs_list, though wmi cmd failed. 9968 * Host can still have this list 9969 */ 9970 return QDF_STATUS_E_INVAL; 9971 } 9972 9973 return 0; 9974 } 9975 9976 /** 9977 * send_enable_specific_fw_logs_cmd_tlv() - Start/Stop logging of diag log id 9978 * @wmi_handle: wmi handle 9979 * @start_log: Start logging related parameters 9980 * 9981 * Send the command to the FW based on which specific logging of diag 9982 * event/log id can be started/stopped 9983 * 9984 * Return: None 9985 */ 9986 static QDF_STATUS send_enable_specific_fw_logs_cmd_tlv(wmi_unified_t wmi_handle, 9987 struct wmi_wifi_start_log *start_log) 9988 { 9989 wmi_diag_event_log_config_fixed_param *cmd; 9990 wmi_buf_t buf; 9991 uint8_t *buf_ptr; 9992 uint32_t len, count, log_level, i; 9993 uint32_t *cmd_args; 9994 uint32_t total_len; 9995 count = 0; 9996 9997 if (!wmi_handle->events_logs_list) { 9998 wmi_debug("Not received event/log list from FW, yet"); 9999 return QDF_STATUS_E_NOMEM; 10000 } 10001 /* total_len stores the number of events where BITS 17 and 18 are set. 10002 * i.e., events of high frequency (17) and for extended debugging (18) 10003 */ 10004 total_len = 0; 10005 for (i = 0; i < wmi_handle->num_of_diag_events_logs; i++) { 10006 if ((WMI_DIAG_FREQUENCY_GET(wmi_handle->events_logs_list[i])) && 10007 (WMI_DIAG_EXT_FEATURE_GET(wmi_handle->events_logs_list[i]))) 10008 total_len++; 10009 } 10010 10011 len = sizeof(*cmd) + WMI_TLV_HDR_SIZE + 10012 (total_len * sizeof(uint32_t)); 10013 10014 buf = wmi_buf_alloc(wmi_handle, len); 10015 if (!buf) 10016 return QDF_STATUS_E_NOMEM; 10017 10018 cmd = (wmi_diag_event_log_config_fixed_param *) wmi_buf_data(buf); 10019 buf_ptr = (uint8_t *) cmd; 10020 10021 WMITLV_SET_HDR(&cmd->tlv_header, 10022 WMITLV_TAG_STRUC_wmi_diag_event_log_config_fixed_param, 10023 WMITLV_GET_STRUCT_TLVLEN( 10024 wmi_diag_event_log_config_fixed_param)); 10025 10026 cmd->num_of_diag_events_logs = total_len; 10027 10028 buf_ptr += sizeof(wmi_diag_event_log_config_fixed_param); 10029 10030 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, 10031 (total_len * sizeof(uint32_t))); 10032 10033 cmd_args = (uint32_t *) (buf_ptr + WMI_TLV_HDR_SIZE); 10034 10035 if (start_log->verbose_level >= WMI_LOG_LEVEL_ACTIVE) 10036 log_level = 1; 10037 else 10038 log_level = 0; 10039 10040 wmi_debug("Length: %d Log_level: %d", total_len, log_level); 10041 for (i = 0; i < wmi_handle->num_of_diag_events_logs; i++) { 10042 uint32_t val = wmi_handle->events_logs_list[i]; 10043 if ((WMI_DIAG_FREQUENCY_GET(val)) && 10044 (WMI_DIAG_EXT_FEATURE_GET(val))) { 10045 10046 WMI_DIAG_ID_SET(cmd_args[count], 10047 WMI_DIAG_ID_GET(val)); 10048 WMI_DIAG_TYPE_SET(cmd_args[count], 10049 WMI_DIAG_TYPE_GET(val)); 10050 WMI_DIAG_ID_ENABLED_DISABLED_SET(cmd_args[count], 10051 log_level); 10052 wmi_debug("Idx:%d, val:%x", i, val); 10053 count++; 10054 } 10055 } 10056 10057 wmi_mtrace(WMI_DIAG_EVENT_LOG_CONFIG_CMDID, NO_SESSION, 0); 10058 if (wmi_unified_cmd_send(wmi_handle, buf, len, 10059 WMI_DIAG_EVENT_LOG_CONFIG_CMDID)) { 10060 wmi_err("WMI_DIAG_EVENT_LOG_CONFIG_CMDID failed"); 10061 wmi_buf_free(buf); 10062 return QDF_STATUS_E_INVAL; 10063 } 10064 10065 return QDF_STATUS_SUCCESS; 10066 } 10067 10068 /** 10069 * send_flush_logs_to_fw_cmd_tlv() - Send log flush command to FW 10070 * @wmi_handle: WMI handle 10071 * 10072 * This function is used to send the flush command to the FW, 10073 * that will flush the fw logs that are residue in the FW 10074 * 10075 * Return: None 10076 */ 10077 static QDF_STATUS send_flush_logs_to_fw_cmd_tlv(wmi_unified_t wmi_handle) 10078 { 10079 wmi_debug_mesg_flush_fixed_param *cmd; 10080 wmi_buf_t buf; 10081 int len = sizeof(*cmd); 10082 QDF_STATUS ret; 10083 10084 buf = wmi_buf_alloc(wmi_handle, len); 10085 if (!buf) 10086 return QDF_STATUS_E_NOMEM; 10087 10088 cmd = (wmi_debug_mesg_flush_fixed_param *) wmi_buf_data(buf); 10089 WMITLV_SET_HDR(&cmd->tlv_header, 10090 WMITLV_TAG_STRUC_wmi_debug_mesg_flush_fixed_param, 10091 WMITLV_GET_STRUCT_TLVLEN( 10092 wmi_debug_mesg_flush_fixed_param)); 10093 cmd->reserved0 = 0; 10094 10095 wmi_mtrace(WMI_DEBUG_MESG_FLUSH_CMDID, NO_SESSION, 0); 10096 ret = wmi_unified_cmd_send(wmi_handle, 10097 buf, 10098 len, 10099 WMI_DEBUG_MESG_FLUSH_CMDID); 10100 if (QDF_IS_STATUS_ERROR(ret)) { 10101 wmi_err("Failed to send WMI_DEBUG_MESG_FLUSH_CMDID"); 10102 wmi_buf_free(buf); 10103 return QDF_STATUS_E_INVAL; 10104 } 10105 wmi_debug("Sent WMI_DEBUG_MESG_FLUSH_CMDID to FW"); 10106 10107 return ret; 10108 } 10109 10110 #ifdef BIG_ENDIAN_HOST 10111 #ifdef WLAN_FEATURE_FIPS_BER_CCMGCM 10112 /** 10113 * fips_extend_align_data_be() - LE to BE conversion of FIPS extend ev data 10114 * @wmi_handle: wmi handle 10115 * @param: fips extend param related parameters 10116 * 10117 * Return: QDF_STATUS - success or error status 10118 */ 10119 static QDF_STATUS fips_extend_align_data_be(wmi_unified_t wmi_handle, 10120 struct fips_extend_params *param) 10121 { 10122 unsigned char *key_unaligned, *nonce_iv_unaligned, *data_unaligned; 10123 int c; 10124 u_int8_t *key_aligned = NULL; 10125 u_int8_t *nonce_iv_aligned = NULL; 10126 u_int8_t *data_aligned = NULL; 10127 int ret = QDF_STATUS_SUCCESS; 10128 10129 /* Assigning unaligned space to copy the key */ 10130 key_unaligned = qdf_mem_malloc(sizeof(u_int8_t) * 10131 param->cmd_params.key_len + FIPS_ALIGN); 10132 /* Checking if kmalloc is successful to allocate space */ 10133 if (!key_unaligned) 10134 return QDF_STATUS_E_INVAL; 10135 10136 data_unaligned = qdf_mem_malloc(sizeof(u_int8_t) * param->data_len + 10137 FIPS_ALIGN); 10138 /* Checking if kmalloc is successful to allocate space */ 10139 if (!data_unaligned) { 10140 ret = QDF_STATUS_E_INVAL; 10141 goto fips_align_fail_data; 10142 } 10143 10144 /* Checking if space is aligned */ 10145 if (!FIPS_IS_ALIGNED(key_unaligned, FIPS_ALIGN)) { 10146 /* align to 4 */ 10147 key_aligned = (u_int8_t *)FIPS_ALIGNTO(key_unaligned, 10148 FIPS_ALIGN); 10149 } else { 10150 key_aligned = (u_int8_t *)key_unaligned; 10151 } 10152 10153 /* memset and copy content from key to key aligned */ 10154 OS_MEMSET(key_aligned, 0, param->cmd_params.key_len); 10155 OS_MEMCPY(key_aligned, param->cmd_params.key, 10156 param->cmd_params.key_len); 10157 10158 /* print a hexdump for host debug */ 10159 wmi_debug("Aligned and Copied Key: "); 10160 qdf_trace_hex_dump(QDF_MODULE_ID_WMI, QDF_TRACE_LEVEL_DEBUG, 10161 key_aligned, param->cmd_params.key_len); 10162 10163 /* Checking of space is aligned */ 10164 if (!FIPS_IS_ALIGNED(data_unaligned, FIPS_ALIGN)) { 10165 /* align to 4 */ 10166 data_aligned = 10167 (u_int8_t *)FIPS_ALIGNTO(data_unaligned, FIPS_ALIGN); 10168 } else { 10169 data_aligned = (u_int8_t *)data_unaligned; 10170 } 10171 10172 /* memset and copy content from data to data aligned */ 10173 OS_MEMSET(data_aligned, 0, param->data_len); 10174 OS_MEMCPY(data_aligned, param->data, param->data_len); 10175 10176 /* print a hexdump for host debug */ 10177 wmi_debug("\t Properly Aligned and Copied Data: "); 10178 qdf_trace_hex_dump(QDF_MODULE_ID_WMI, QDF_TRACE_LEVEL_DEBUG, 10179 data_aligned, param->data_len); 10180 10181 /* converting to little Endian */ 10182 for (c = 0; c < param->cmd_params.key_len / 4; c++) { 10183 *((u_int32_t *)key_aligned + c) = 10184 qdf_cpu_to_le32(*((u_int32_t *)key_aligned + c)); 10185 } 10186 for (c = 0; c < param->data_len / 4; c++) { 10187 *((u_int32_t *)data_aligned + c) = 10188 qdf_cpu_to_le32(*((u_int32_t *)data_aligned + c)); 10189 } 10190 10191 /* update endian data */ 10192 OS_MEMCPY(param->cmd_params.key, key_aligned, 10193 param->cmd_params.key_len); 10194 OS_MEMCPY(param->data, data_aligned, param->data_len); 10195 10196 if (param->cmd_params.nonce_iv_len) { 10197 nonce_iv_unaligned = qdf_mem_malloc(sizeof(u_int8_t) * 10198 param->cmd_params.nonce_iv_len + 10199 FIPS_ALIGN); 10200 10201 /* Checking if kmalloc is successful to allocate space */ 10202 if (!nonce_iv_unaligned) { 10203 ret = QDF_STATUS_E_INVAL; 10204 goto fips_align_fail_nonce_iv; 10205 } 10206 /* Checking if space is aligned */ 10207 if (!FIPS_IS_ALIGNED(nonce_iv_unaligned, FIPS_ALIGN)) { 10208 /* align to 4 */ 10209 nonce_iv_aligned = 10210 (u_int8_t *)FIPS_ALIGNTO(nonce_iv_unaligned, 10211 FIPS_ALIGN); 10212 } else { 10213 nonce_iv_aligned = (u_int8_t *)nonce_iv_unaligned; 10214 } 10215 10216 /* memset and copy content from iv to iv aligned */ 10217 OS_MEMSET(nonce_iv_aligned, 0, param->cmd_params.nonce_iv_len); 10218 OS_MEMCPY(nonce_iv_aligned, param->cmd_params.nonce_iv, 10219 param->cmd_params.nonce_iv_len); 10220 10221 /* print a hexdump for host debug */ 10222 wmi_debug("\t Aligned and Copied Nonce_IV: "); 10223 qdf_trace_hex_dump(QDF_MODULE_ID_WMI, QDF_TRACE_LEVEL_DEBUG, 10224 nonce_iv_aligned, 10225 param->cmd_params.nonce_iv_len); 10226 10227 for (c = 0; c < param->cmd_params.nonce_iv_len / 4; c++) { 10228 *((u_int32_t *)nonce_iv_aligned + c) = 10229 qdf_cpu_to_le32(*((u_int32_t *)nonce_iv_aligned + c)); 10230 } 10231 } 10232 10233 /* clean up allocated spaces */ 10234 qdf_mem_free(nonce_iv_unaligned); 10235 nonce_iv_unaligned = NULL; 10236 nonce_iv_aligned = NULL; 10237 10238 fips_align_fail_nonce_iv: 10239 qdf_mem_free(data_unaligned); 10240 data_unaligned = NULL; 10241 data_aligned = NULL; 10242 10243 fips_align_fail_data: 10244 qdf_mem_free(key_unaligned); 10245 key_unaligned = NULL; 10246 key_aligned = NULL; 10247 10248 return ret; 10249 } 10250 #endif 10251 10252 /** 10253 * fips_align_data_be() - LE to BE conversion of FIPS ev data 10254 * @wmi_handle: wmi handle 10255 * @param: fips param related parameters 10256 * 10257 * Return: QDF_STATUS - success or error status 10258 */ 10259 static QDF_STATUS fips_align_data_be(wmi_unified_t wmi_handle, 10260 struct fips_params *param) 10261 { 10262 unsigned char *key_unaligned, *data_unaligned; 10263 int c; 10264 u_int8_t *key_aligned = NULL; 10265 u_int8_t *data_aligned = NULL; 10266 10267 /* Assigning unaligned space to copy the key */ 10268 key_unaligned = qdf_mem_malloc( 10269 sizeof(u_int8_t)*param->key_len + FIPS_ALIGN); 10270 data_unaligned = qdf_mem_malloc( 10271 sizeof(u_int8_t)*param->data_len + FIPS_ALIGN); 10272 10273 /* Checking if kmalloc is successful to allocate space */ 10274 if (!key_unaligned) 10275 return QDF_STATUS_SUCCESS; 10276 /* Checking if space is aligned */ 10277 if (!FIPS_IS_ALIGNED(key_unaligned, FIPS_ALIGN)) { 10278 /* align to 4 */ 10279 key_aligned = 10280 (u_int8_t *)FIPS_ALIGNTO(key_unaligned, 10281 FIPS_ALIGN); 10282 } else { 10283 key_aligned = (u_int8_t *)key_unaligned; 10284 } 10285 10286 /* memset and copy content from key to key aligned */ 10287 OS_MEMSET(key_aligned, 0, param->key_len); 10288 OS_MEMCPY(key_aligned, param->key, param->key_len); 10289 10290 /* print a hexdump for host debug */ 10291 print_hex_dump(KERN_DEBUG, 10292 "\t Aligned and Copied Key:@@@@ ", 10293 DUMP_PREFIX_NONE, 10294 16, 1, key_aligned, param->key_len, true); 10295 10296 /* Checking if kmalloc is successful to allocate space */ 10297 if (!data_unaligned) 10298 return QDF_STATUS_SUCCESS; 10299 /* Checking of space is aligned */ 10300 if (!FIPS_IS_ALIGNED(data_unaligned, FIPS_ALIGN)) { 10301 /* align to 4 */ 10302 data_aligned = 10303 (u_int8_t *)FIPS_ALIGNTO(data_unaligned, 10304 FIPS_ALIGN); 10305 } else { 10306 data_aligned = (u_int8_t *)data_unaligned; 10307 } 10308 10309 /* memset and copy content from data to data aligned */ 10310 OS_MEMSET(data_aligned, 0, param->data_len); 10311 OS_MEMCPY(data_aligned, param->data, param->data_len); 10312 10313 /* print a hexdump for host debug */ 10314 print_hex_dump(KERN_DEBUG, 10315 "\t Properly Aligned and Copied Data:@@@@ ", 10316 DUMP_PREFIX_NONE, 10317 16, 1, data_aligned, param->data_len, true); 10318 10319 /* converting to little Endian both key_aligned and 10320 * data_aligned*/ 10321 for (c = 0; c < param->key_len/4; c++) { 10322 *((u_int32_t *)key_aligned+c) = 10323 qdf_cpu_to_le32(*((u_int32_t *)key_aligned+c)); 10324 } 10325 for (c = 0; c < param->data_len/4; c++) { 10326 *((u_int32_t *)data_aligned+c) = 10327 qdf_cpu_to_le32(*((u_int32_t *)data_aligned+c)); 10328 } 10329 10330 /* update endian data to key and data vectors */ 10331 OS_MEMCPY(param->key, key_aligned, param->key_len); 10332 OS_MEMCPY(param->data, data_aligned, param->data_len); 10333 10334 /* clean up allocated spaces */ 10335 qdf_mem_free(key_unaligned); 10336 key_unaligned = NULL; 10337 key_aligned = NULL; 10338 10339 qdf_mem_free(data_unaligned); 10340 data_unaligned = NULL; 10341 data_aligned = NULL; 10342 10343 return QDF_STATUS_SUCCESS; 10344 } 10345 #else 10346 #ifdef WLAN_FEATURE_FIPS_BER_CCMGCM 10347 static QDF_STATUS fips_extend_align_data_be(wmi_unified_t wmi_handle, 10348 struct fips_extend_params *param) 10349 { 10350 return QDF_STATUS_SUCCESS; 10351 } 10352 #endif 10353 10354 static QDF_STATUS fips_align_data_be(wmi_unified_t wmi_handle, 10355 struct fips_params *param) 10356 { 10357 return QDF_STATUS_SUCCESS; 10358 } 10359 #endif 10360 10361 #ifdef WLAN_FEATURE_DISA 10362 /** 10363 * send_encrypt_decrypt_send_cmd_tlv() - send encrypt/decrypt cmd to fw 10364 * @wmi_handle: wmi handle 10365 * @encrypt_decrypt_params: encrypt/decrypt params 10366 * 10367 * Return: QDF_STATUS_SUCCESS for success or error code 10368 */ 10369 static QDF_STATUS 10370 send_encrypt_decrypt_send_cmd_tlv(wmi_unified_t wmi_handle, 10371 struct disa_encrypt_decrypt_req_params 10372 *encrypt_decrypt_params) 10373 { 10374 wmi_vdev_encrypt_decrypt_data_req_cmd_fixed_param *cmd; 10375 wmi_buf_t wmi_buf; 10376 uint8_t *buf_ptr; 10377 QDF_STATUS ret; 10378 uint32_t len; 10379 10380 wmi_debug("Send encrypt decrypt cmd"); 10381 10382 len = sizeof(*cmd) + 10383 encrypt_decrypt_params->data_len + 10384 WMI_TLV_HDR_SIZE; 10385 wmi_buf = wmi_buf_alloc(wmi_handle, len); 10386 if (!wmi_buf) 10387 return QDF_STATUS_E_NOMEM; 10388 10389 buf_ptr = wmi_buf_data(wmi_buf); 10390 cmd = (wmi_vdev_encrypt_decrypt_data_req_cmd_fixed_param *)buf_ptr; 10391 10392 WMITLV_SET_HDR(&cmd->tlv_header, 10393 WMITLV_TAG_STRUC_wmi_vdev_encrypt_decrypt_data_req_cmd_fixed_param, 10394 WMITLV_GET_STRUCT_TLVLEN( 10395 wmi_vdev_encrypt_decrypt_data_req_cmd_fixed_param)); 10396 10397 cmd->vdev_id = encrypt_decrypt_params->vdev_id; 10398 cmd->key_flag = encrypt_decrypt_params->key_flag; 10399 cmd->key_idx = encrypt_decrypt_params->key_idx; 10400 cmd->key_cipher = encrypt_decrypt_params->key_cipher; 10401 cmd->key_len = encrypt_decrypt_params->key_len; 10402 cmd->key_txmic_len = encrypt_decrypt_params->key_txmic_len; 10403 cmd->key_rxmic_len = encrypt_decrypt_params->key_rxmic_len; 10404 10405 qdf_mem_copy(cmd->key_data, encrypt_decrypt_params->key_data, 10406 encrypt_decrypt_params->key_len); 10407 10408 qdf_mem_copy(cmd->mac_hdr, encrypt_decrypt_params->mac_header, 10409 MAX_MAC_HEADER_LEN); 10410 10411 cmd->data_len = encrypt_decrypt_params->data_len; 10412 10413 if (cmd->data_len) { 10414 buf_ptr += sizeof(*cmd); 10415 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, 10416 roundup(encrypt_decrypt_params->data_len, 10417 sizeof(uint32_t))); 10418 buf_ptr += WMI_TLV_HDR_SIZE; 10419 qdf_mem_copy(buf_ptr, encrypt_decrypt_params->data, 10420 encrypt_decrypt_params->data_len); 10421 } 10422 10423 /* This conversion is to facilitate data to FW in little endian */ 10424 cmd->pn[5] = encrypt_decrypt_params->pn[0]; 10425 cmd->pn[4] = encrypt_decrypt_params->pn[1]; 10426 cmd->pn[3] = encrypt_decrypt_params->pn[2]; 10427 cmd->pn[2] = encrypt_decrypt_params->pn[3]; 10428 cmd->pn[1] = encrypt_decrypt_params->pn[4]; 10429 cmd->pn[0] = encrypt_decrypt_params->pn[5]; 10430 10431 wmi_mtrace(WMI_VDEV_ENCRYPT_DECRYPT_DATA_REQ_CMDID, cmd->vdev_id, 0); 10432 ret = wmi_unified_cmd_send(wmi_handle, 10433 wmi_buf, len, 10434 WMI_VDEV_ENCRYPT_DECRYPT_DATA_REQ_CMDID); 10435 if (QDF_IS_STATUS_ERROR(ret)) { 10436 wmi_err("Failed to send ENCRYPT DECRYPT cmd: %d", ret); 10437 wmi_buf_free(wmi_buf); 10438 } 10439 10440 return ret; 10441 } 10442 #endif /* WLAN_FEATURE_DISA */ 10443 10444 /** 10445 * send_pdev_fips_cmd_tlv() - send pdev fips cmd to fw 10446 * @wmi_handle: wmi handle 10447 * @param: pointer to hold pdev fips param 10448 * 10449 * Return: QDF_STATUS_SUCCESS for success or error code 10450 */ 10451 static QDF_STATUS 10452 send_pdev_fips_cmd_tlv(wmi_unified_t wmi_handle, 10453 struct fips_params *param) 10454 { 10455 wmi_pdev_fips_cmd_fixed_param *cmd; 10456 wmi_buf_t buf; 10457 uint8_t *buf_ptr; 10458 uint32_t len = sizeof(wmi_pdev_fips_cmd_fixed_param); 10459 QDF_STATUS retval = QDF_STATUS_SUCCESS; 10460 10461 /* Length TLV placeholder for array of bytes */ 10462 len += WMI_TLV_HDR_SIZE; 10463 if (param->data_len) 10464 len += (param->data_len*sizeof(uint8_t)); 10465 10466 /* 10467 * Data length must be multiples of 16 bytes - checked against 0xF - 10468 * and must be less than WMI_SVC_MSG_SIZE - static size of 10469 * wmi_pdev_fips_cmd structure 10470 */ 10471 10472 /* do sanity on the input */ 10473 if (!(((param->data_len & 0xF) == 0) && 10474 ((param->data_len > 0) && 10475 (param->data_len < (WMI_HOST_MAX_BUFFER_SIZE - 10476 sizeof(wmi_pdev_fips_cmd_fixed_param)))))) { 10477 return QDF_STATUS_E_INVAL; 10478 } 10479 10480 buf = wmi_buf_alloc(wmi_handle, len); 10481 if (!buf) 10482 return QDF_STATUS_E_FAILURE; 10483 10484 buf_ptr = (uint8_t *) wmi_buf_data(buf); 10485 cmd = (wmi_pdev_fips_cmd_fixed_param *)buf_ptr; 10486 WMITLV_SET_HDR(&cmd->tlv_header, 10487 WMITLV_TAG_STRUC_wmi_pdev_fips_cmd_fixed_param, 10488 WMITLV_GET_STRUCT_TLVLEN 10489 (wmi_pdev_fips_cmd_fixed_param)); 10490 10491 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 10492 wmi_handle, 10493 param->pdev_id); 10494 if (param->key && param->data) { 10495 cmd->key_len = param->key_len; 10496 cmd->data_len = param->data_len; 10497 cmd->fips_cmd = !!(param->op); 10498 10499 if (fips_align_data_be(wmi_handle, param) != QDF_STATUS_SUCCESS) 10500 return QDF_STATUS_E_FAILURE; 10501 10502 qdf_mem_copy(cmd->key, param->key, param->key_len); 10503 10504 if (param->mode == FIPS_ENGINE_AES_CTR || 10505 param->mode == FIPS_ENGINE_AES_MIC) { 10506 cmd->mode = param->mode; 10507 } else { 10508 cmd->mode = FIPS_ENGINE_AES_CTR; 10509 } 10510 qdf_print("Key len = %d, Data len = %d", 10511 cmd->key_len, cmd->data_len); 10512 10513 print_hex_dump(KERN_DEBUG, "Key: ", DUMP_PREFIX_NONE, 16, 1, 10514 cmd->key, cmd->key_len, true); 10515 buf_ptr += sizeof(*cmd); 10516 10517 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, param->data_len); 10518 10519 buf_ptr += WMI_TLV_HDR_SIZE; 10520 if (param->data_len) 10521 qdf_mem_copy(buf_ptr, 10522 (uint8_t *) param->data, param->data_len); 10523 10524 print_hex_dump(KERN_DEBUG, "Plain text: ", DUMP_PREFIX_NONE, 10525 16, 1, buf_ptr, cmd->data_len, true); 10526 10527 buf_ptr += param->data_len; 10528 10529 wmi_mtrace(WMI_PDEV_FIPS_CMDID, NO_SESSION, 0); 10530 retval = wmi_unified_cmd_send(wmi_handle, buf, len, 10531 WMI_PDEV_FIPS_CMDID); 10532 qdf_print("%s return value %d", __func__, retval); 10533 } else { 10534 qdf_print("\n%s:%d Key or Data is NULL", __func__, __LINE__); 10535 wmi_buf_free(buf); 10536 retval = -QDF_STATUS_E_BADMSG; 10537 } 10538 10539 return retval; 10540 } 10541 10542 #ifdef WLAN_FEATURE_FIPS_BER_CCMGCM 10543 /** 10544 * send_pdev_fips_extend_cmd_tlv() - send pdev fips cmd to fw 10545 * @wmi_handle: wmi handle 10546 * @param: pointer to hold pdev fips param 10547 * 10548 * Return: QDF_STATUS_SUCCESS for success or error code 10549 */ 10550 static QDF_STATUS 10551 send_pdev_fips_extend_cmd_tlv(wmi_unified_t wmi_handle, 10552 struct fips_extend_params *param) 10553 { 10554 wmi_pdev_fips_extend_cmd_fixed_param *cmd; 10555 wmi_buf_t buf; 10556 uint8_t *buf_ptr; 10557 uint32_t len = sizeof(wmi_pdev_fips_extend_cmd_fixed_param); 10558 uint32_t data_len_aligned; 10559 QDF_STATUS retval = QDF_STATUS_SUCCESS; 10560 10561 len += WMI_TLV_HDR_SIZE; 10562 if (param->frag_idx == 0) 10563 len += sizeof(wmi_fips_extend_cmd_init_params); 10564 10565 /* Length TLV placeholder for array of bytes */ 10566 len += WMI_TLV_HDR_SIZE; 10567 if (param->data_len) { 10568 data_len_aligned = roundup(param->data_len, sizeof(uint32_t)); 10569 len += (data_len_aligned * sizeof(uint8_t)); 10570 } 10571 10572 buf = wmi_buf_alloc(wmi_handle, len); 10573 if (!buf) 10574 return QDF_STATUS_E_FAILURE; 10575 10576 buf_ptr = (uint8_t *)wmi_buf_data(buf); 10577 cmd = (wmi_pdev_fips_extend_cmd_fixed_param *)buf_ptr; 10578 WMITLV_SET_HDR(&cmd->tlv_header, 10579 WMITLV_TAG_STRUC_wmi_pdev_fips_extend_cmd_fixed_param, 10580 WMITLV_GET_STRUCT_TLVLEN 10581 (wmi_pdev_fips_extend_cmd_fixed_param)); 10582 10583 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 10584 wmi_handle, 10585 param->pdev_id); 10586 10587 cmd->fips_cookie = param->cookie; 10588 cmd->frag_idx = param->frag_idx; 10589 cmd->more_bit = param->more_bit; 10590 cmd->data_len = param->data_len; 10591 10592 if (fips_extend_align_data_be(wmi_handle, param) != 10593 QDF_STATUS_SUCCESS) { 10594 wmi_buf_free(buf); 10595 return QDF_STATUS_E_FAILURE; 10596 } 10597 10598 buf_ptr = (uint8_t *)(cmd + 1); 10599 if (cmd->frag_idx == 0) { 10600 wmi_fips_extend_cmd_init_params *cmd_params; 10601 10602 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 10603 sizeof(wmi_fips_extend_cmd_init_params)); 10604 buf_ptr += WMI_TLV_HDR_SIZE; 10605 cmd_params = (wmi_fips_extend_cmd_init_params *)buf_ptr; 10606 WMITLV_SET_HDR(buf_ptr, 10607 WMITLV_TAG_STRUC_wmi_fips_extend_cmd_init_params, 10608 WMITLV_GET_STRUCT_TLVLEN(wmi_fips_extend_cmd_init_params)); 10609 cmd_params->fips_cmd = param->cmd_params.fips_cmd; 10610 cmd_params->key_cipher = param->cmd_params.key_cipher; 10611 cmd_params->key_len = param->cmd_params.key_len; 10612 cmd_params->nonce_iv_len = param->cmd_params.nonce_iv_len; 10613 cmd_params->tag_len = param->cmd_params.tag_len; 10614 cmd_params->aad_len = param->cmd_params.aad_len; 10615 cmd_params->payload_len = param->cmd_params.payload_len; 10616 10617 qdf_mem_copy(cmd_params->key, param->cmd_params.key, 10618 param->cmd_params.key_len); 10619 qdf_mem_copy(cmd_params->nonce_iv, param->cmd_params.nonce_iv, 10620 param->cmd_params.nonce_iv_len); 10621 10622 wmi_debug("Key len = %d, IVNoncelen = %d, Tlen = %d, Alen = %d, Plen = %d", 10623 cmd_params->key_len, cmd_params->nonce_iv_len, 10624 cmd_params->tag_len, cmd_params->aad_len, 10625 cmd_params->payload_len); 10626 10627 buf_ptr += sizeof(wmi_fips_extend_cmd_init_params); 10628 } else { 10629 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0); 10630 buf_ptr += WMI_TLV_HDR_SIZE; 10631 } 10632 10633 if (param->data_len && param->data) { 10634 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, 10635 data_len_aligned); 10636 10637 buf_ptr += WMI_TLV_HDR_SIZE; 10638 if (param->data_len) 10639 qdf_mem_copy(buf_ptr, 10640 (uint8_t *)param->data, param->data_len); 10641 10642 wmi_debug("Data: "); 10643 qdf_trace_hex_dump(QDF_MODULE_ID_WMI, QDF_TRACE_LEVEL_DEBUG, 10644 buf_ptr, cmd->data_len); 10645 10646 if (param->data_len) 10647 buf_ptr += param->data_len; 10648 } else { 10649 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, 0); 10650 buf_ptr += WMI_TLV_HDR_SIZE; 10651 } 10652 10653 wmi_mtrace(WMI_PDEV_FIPS_EXTEND_CMDID, NO_SESSION, 0); 10654 retval = wmi_unified_cmd_send(wmi_handle, buf, len, 10655 WMI_PDEV_FIPS_EXTEND_CMDID); 10656 10657 if (retval) { 10658 wmi_err("Failed to send FIPS cmd"); 10659 wmi_buf_free(buf); 10660 } 10661 10662 return retval; 10663 } 10664 10665 /** 10666 * send_pdev_fips_mode_set_cmd_tlv() - send pdev fips cmd to fw 10667 * @wmi_handle: wmi handle 10668 * @param: pointer to hold pdev fips param 10669 * 10670 * Return: QDF_STATUS_SUCCESS for success or error code 10671 */ 10672 static QDF_STATUS 10673 send_pdev_fips_mode_set_cmd_tlv(wmi_unified_t wmi_handle, 10674 struct fips_mode_set_params *param) 10675 { 10676 wmi_pdev_fips_mode_set_cmd_fixed_param *cmd; 10677 wmi_buf_t buf; 10678 uint8_t *buf_ptr; 10679 uint32_t len = sizeof(wmi_pdev_fips_mode_set_cmd_fixed_param); 10680 QDF_STATUS retval = QDF_STATUS_SUCCESS; 10681 10682 buf = wmi_buf_alloc(wmi_handle, len); 10683 if (!buf) 10684 return QDF_STATUS_E_FAILURE; 10685 10686 buf_ptr = (uint8_t *)wmi_buf_data(buf); 10687 cmd = (wmi_pdev_fips_mode_set_cmd_fixed_param *)buf_ptr; 10688 WMITLV_SET_HDR(&cmd->tlv_header, 10689 WMITLV_TAG_STRUC_wmi_pdev_fips_mode_set_cmd_fixed_param, 10690 WMITLV_GET_STRUCT_TLVLEN 10691 (wmi_pdev_fips_mode_set_cmd_fixed_param)); 10692 10693 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 10694 wmi_handle, 10695 param->pdev_id); 10696 10697 cmd->fips_mode_set = param->mode; 10698 wmi_mtrace(WMI_PDEV_FIPS_MODE_SET_CMDID, NO_SESSION, 0); 10699 retval = wmi_unified_cmd_send(wmi_handle, buf, len, 10700 WMI_PDEV_FIPS_MODE_SET_CMDID); 10701 if (retval) { 10702 wmi_err("Failed to send FIPS mode enable cmd"); 10703 wmi_buf_free(buf); 10704 } 10705 return retval; 10706 } 10707 #endif 10708 10709 /** 10710 * send_wlan_profile_enable_cmd_tlv() - send wlan profile enable command 10711 * to fw 10712 * @wmi_handle: wmi handle 10713 * @param: pointer to wlan profile param 10714 * 10715 * Return: QDF_STATUS_SUCCESS for success or error code 10716 */ 10717 static QDF_STATUS 10718 send_wlan_profile_enable_cmd_tlv(wmi_unified_t wmi_handle, 10719 struct wlan_profile_params *param) 10720 { 10721 wmi_buf_t buf; 10722 uint16_t len; 10723 QDF_STATUS ret; 10724 wmi_wlan_profile_enable_profile_id_cmd_fixed_param *profile_enable_cmd; 10725 10726 len = sizeof(wmi_wlan_profile_enable_profile_id_cmd_fixed_param); 10727 buf = wmi_buf_alloc(wmi_handle, len); 10728 if (!buf) { 10729 wmi_err("Failed to send WMI_WLAN_PROFILE_ENABLE_PROFILE_ID_CMDID"); 10730 return QDF_STATUS_E_NOMEM; 10731 } 10732 10733 profile_enable_cmd = 10734 (wmi_wlan_profile_enable_profile_id_cmd_fixed_param *) 10735 wmi_buf_data(buf); 10736 WMITLV_SET_HDR(&profile_enable_cmd->tlv_header, 10737 WMITLV_TAG_STRUC_wmi_wlan_profile_enable_profile_id_cmd_fixed_param, 10738 WMITLV_GET_STRUCT_TLVLEN 10739 (wmi_wlan_profile_enable_profile_id_cmd_fixed_param)); 10740 10741 profile_enable_cmd->profile_id = param->profile_id; 10742 profile_enable_cmd->enable = param->enable; 10743 wmi_mtrace(WMI_WLAN_PROFILE_ENABLE_PROFILE_ID_CMDID, 10744 NO_SESSION, 0); 10745 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 10746 WMI_WLAN_PROFILE_ENABLE_PROFILE_ID_CMDID); 10747 if (ret) { 10748 wmi_err("Failed to send PROFILE_ENABLE_PROFILE_ID_CMDID"); 10749 wmi_buf_free(buf); 10750 } 10751 return ret; 10752 } 10753 10754 /** 10755 * send_wlan_profile_trigger_cmd_tlv() - send wlan profile trigger command 10756 * to fw 10757 * @wmi_handle: wmi handle 10758 * @param: pointer to wlan profile param 10759 * 10760 * Return: QDF_STATUS_SUCCESS for success or error code 10761 */ 10762 static QDF_STATUS 10763 send_wlan_profile_trigger_cmd_tlv(wmi_unified_t wmi_handle, 10764 struct wlan_profile_params *param) 10765 { 10766 wmi_buf_t buf; 10767 uint16_t len; 10768 QDF_STATUS ret; 10769 wmi_wlan_profile_trigger_cmd_fixed_param *prof_trig_cmd; 10770 10771 len = sizeof(wmi_wlan_profile_trigger_cmd_fixed_param); 10772 buf = wmi_buf_alloc(wmi_handle, len); 10773 if (!buf) { 10774 wmi_err("Failed to send WMI_WLAN_PROFILE_TRIGGER_CMDID"); 10775 return QDF_STATUS_E_NOMEM; 10776 } 10777 10778 prof_trig_cmd = 10779 (wmi_wlan_profile_trigger_cmd_fixed_param *) 10780 wmi_buf_data(buf); 10781 10782 WMITLV_SET_HDR(&prof_trig_cmd->tlv_header, 10783 WMITLV_TAG_STRUC_wmi_wlan_profile_trigger_cmd_fixed_param, 10784 WMITLV_GET_STRUCT_TLVLEN 10785 (wmi_wlan_profile_trigger_cmd_fixed_param)); 10786 10787 prof_trig_cmd->enable = param->enable; 10788 wmi_mtrace(WMI_WLAN_PROFILE_TRIGGER_CMDID, NO_SESSION, 0); 10789 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 10790 WMI_WLAN_PROFILE_TRIGGER_CMDID); 10791 if (ret) { 10792 wmi_err("Failed to send WMI_WLAN_PROFILE_TRIGGER_CMDID"); 10793 wmi_buf_free(buf); 10794 } 10795 return ret; 10796 } 10797 10798 /** 10799 * send_wlan_profile_hist_intvl_cmd_tlv() - send wlan profile interval command 10800 * to fw 10801 * @wmi_handle: wmi handle 10802 * @param: pointer to wlan profile param 10803 * 10804 * Return: QDF_STATUS_SUCCESS for success or error code 10805 */ 10806 static QDF_STATUS 10807 send_wlan_profile_hist_intvl_cmd_tlv(wmi_unified_t wmi_handle, 10808 struct wlan_profile_params *param) 10809 { 10810 wmi_buf_t buf; 10811 int32_t len = 0; 10812 QDF_STATUS ret; 10813 wmi_wlan_profile_set_hist_intvl_cmd_fixed_param *hist_intvl_cmd; 10814 10815 len = sizeof(wmi_wlan_profile_set_hist_intvl_cmd_fixed_param); 10816 buf = wmi_buf_alloc(wmi_handle, len); 10817 if (!buf) { 10818 wmi_err("Failed to send WMI_WLAN_PROFILE_SET_HIST_INTVL_CMDID"); 10819 return QDF_STATUS_E_NOMEM; 10820 } 10821 10822 hist_intvl_cmd = 10823 (wmi_wlan_profile_set_hist_intvl_cmd_fixed_param *) 10824 wmi_buf_data(buf); 10825 10826 WMITLV_SET_HDR(&hist_intvl_cmd->tlv_header, 10827 WMITLV_TAG_STRUC_wmi_wlan_profile_set_hist_intvl_cmd_fixed_param, 10828 WMITLV_GET_STRUCT_TLVLEN 10829 (wmi_wlan_profile_set_hist_intvl_cmd_fixed_param)); 10830 10831 hist_intvl_cmd->profile_id = param->profile_id; 10832 hist_intvl_cmd->value = param->enable; 10833 wmi_mtrace(WMI_WLAN_PROFILE_SET_HIST_INTVL_CMDID, 10834 NO_SESSION, 0); 10835 10836 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 10837 WMI_WLAN_PROFILE_SET_HIST_INTVL_CMDID); 10838 if (ret) { 10839 wmi_err("Failed to send PROFILE_SET_HIST_INTVL_CMDID"); 10840 wmi_buf_free(buf); 10841 } 10842 return ret; 10843 } 10844 10845 /** 10846 * send_fw_test_cmd_tlv() - send fw test command to fw. 10847 * @wmi_handle: wmi handle 10848 * @wmi_fwtest: fw test command 10849 * 10850 * This function sends fw test command to fw. 10851 * 10852 * Return: CDF STATUS 10853 */ 10854 static 10855 QDF_STATUS send_fw_test_cmd_tlv(wmi_unified_t wmi_handle, 10856 struct set_fwtest_params *wmi_fwtest) 10857 { 10858 wmi_fwtest_set_param_cmd_fixed_param *cmd; 10859 wmi_buf_t wmi_buf; 10860 uint16_t len; 10861 10862 len = sizeof(*cmd); 10863 10864 wmi_buf = wmi_buf_alloc(wmi_handle, len); 10865 if (!wmi_buf) 10866 return QDF_STATUS_E_NOMEM; 10867 10868 cmd = (wmi_fwtest_set_param_cmd_fixed_param *) wmi_buf_data(wmi_buf); 10869 WMITLV_SET_HDR(&cmd->tlv_header, 10870 WMITLV_TAG_STRUC_wmi_fwtest_set_param_cmd_fixed_param, 10871 WMITLV_GET_STRUCT_TLVLEN( 10872 wmi_fwtest_set_param_cmd_fixed_param)); 10873 cmd->param_id = wmi_fwtest->arg; 10874 cmd->param_value = wmi_fwtest->value; 10875 10876 wmi_mtrace(WMI_FWTEST_CMDID, NO_SESSION, 0); 10877 if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len, 10878 WMI_FWTEST_CMDID)) { 10879 wmi_err("Failed to send fw test command"); 10880 wmi_buf_free(wmi_buf); 10881 return QDF_STATUS_E_FAILURE; 10882 } 10883 10884 return QDF_STATUS_SUCCESS; 10885 } 10886 10887 static uint16_t wfa_config_param_len(enum wfa_test_cmds config) 10888 { 10889 uint16_t len = 0; 10890 10891 if (config == WFA_CONFIG_RXNE) 10892 len += WMI_TLV_HDR_SIZE + sizeof(wmi_wfa_config_rsnxe); 10893 else 10894 len += WMI_TLV_HDR_SIZE; 10895 10896 if (config == WFA_CONFIG_CSA) 10897 len += WMI_TLV_HDR_SIZE + sizeof(wmi_wfa_config_csa); 10898 else 10899 len += WMI_TLV_HDR_SIZE; 10900 10901 if (config == WFA_CONFIG_OCV) 10902 len += WMI_TLV_HDR_SIZE + sizeof(wmi_wfa_config_ocv); 10903 else 10904 len += WMI_TLV_HDR_SIZE; 10905 10906 if (config == WFA_CONFIG_SA_QUERY) 10907 len += WMI_TLV_HDR_SIZE + sizeof(wmi_wfa_config_saquery); 10908 else 10909 len += WMI_TLV_HDR_SIZE; 10910 10911 return len; 10912 } 10913 10914 /** 10915 * wmi_fill_ocv_frame_type() - Fill host ocv frm type into WMI ocv frm type. 10916 * @host_frmtype: Host defined OCV frame type 10917 * @ocv_frmtype: Pointer to hold WMI OCV frame type 10918 * 10919 * This function converts and fills host defined OCV frame type into WMI OCV 10920 * frame type. 10921 * 10922 * Return: CDF STATUS 10923 */ 10924 static QDF_STATUS 10925 wmi_fill_ocv_frame_type(uint32_t host_frmtype, uint32_t *ocv_frmtype) 10926 { 10927 switch (host_frmtype) { 10928 case WMI_HOST_WFA_CONFIG_OCV_FRMTYPE_SAQUERY_REQ: 10929 *ocv_frmtype = WMI_WFA_CONFIG_OCV_FRMTYPE_SAQUERY_REQ; 10930 break; 10931 10932 case WMI_HOST_WFA_CONFIG_OCV_FRMTYPE_SAQUERY_RSP: 10933 *ocv_frmtype = WMI_WFA_CONFIG_OCV_FRMTYPE_SAQUERY_RSP; 10934 break; 10935 10936 case WMI_HOST_WFA_CONFIG_OCV_FRMTYPE_FT_REASSOC_REQ: 10937 *ocv_frmtype = WMI_WFA_CONFIG_OCV_FRMTYPE_FT_REASSOC_REQ; 10938 break; 10939 10940 case WMI_HOST_WFA_CONFIG_OCV_FRMTYPE_FILS_REASSOC_REQ: 10941 *ocv_frmtype = WMI_WFA_CONFIG_OCV_FRMTYPE_FILS_REASSOC_REQ; 10942 break; 10943 10944 default: 10945 wmi_err("Invalid command type cmd %d", host_frmtype); 10946 return QDF_STATUS_E_FAILURE; 10947 } 10948 10949 return QDF_STATUS_SUCCESS; 10950 } 10951 10952 /** 10953 * send_wfa_test_cmd_tlv() - send wfa test command to fw. 10954 * @wmi_handle: wmi handle 10955 * @wmi_wfatest: wfa test command 10956 * 10957 * This function sends wfa test command to fw. 10958 * 10959 * Return: CDF STATUS 10960 */ 10961 static 10962 QDF_STATUS send_wfa_test_cmd_tlv(wmi_unified_t wmi_handle, 10963 struct set_wfatest_params *wmi_wfatest) 10964 { 10965 wmi_wfa_config_cmd_fixed_param *cmd; 10966 wmi_wfa_config_rsnxe *rxne; 10967 wmi_wfa_config_csa *csa; 10968 wmi_wfa_config_ocv *ocv; 10969 wmi_wfa_config_saquery *saquery; 10970 wmi_buf_t wmi_buf; 10971 uint16_t len = sizeof(*cmd); 10972 uint8_t *buf_ptr; 10973 10974 len += wfa_config_param_len(wmi_wfatest->cmd); 10975 wmi_buf = wmi_buf_alloc(wmi_handle, len); 10976 if (!wmi_buf) 10977 return QDF_STATUS_E_NOMEM; 10978 10979 cmd = (wmi_wfa_config_cmd_fixed_param *)wmi_buf_data(wmi_buf); 10980 WMITLV_SET_HDR(&cmd->tlv_header, 10981 WMITLV_TAG_STRUC_wmi_wfa_config_cmd_fixed_param, 10982 WMITLV_GET_STRUCT_TLVLEN( 10983 wmi_wfa_config_cmd_fixed_param)); 10984 10985 cmd->vdev_id = wmi_wfatest->vdev_id; 10986 buf_ptr = (uint8_t *)(cmd + 1); 10987 10988 if (wmi_wfatest->cmd == WFA_CONFIG_RXNE) { 10989 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 10990 sizeof(wmi_wfa_config_rsnxe)); 10991 buf_ptr += WMI_TLV_HDR_SIZE; 10992 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_STRUC_wmi_wfa_config_rsnxe, 10993 WMITLV_GET_STRUCT_TLVLEN(wmi_wfa_config_rsnxe)); 10994 rxne = (wmi_wfa_config_rsnxe *)buf_ptr; 10995 rxne->rsnxe_param = wmi_wfatest->value; 10996 buf_ptr += sizeof(wmi_wfa_config_rsnxe); 10997 } else { 10998 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0); 10999 buf_ptr += WMI_TLV_HDR_SIZE; 11000 } 11001 11002 if (wmi_wfatest->cmd == WFA_CONFIG_CSA) { 11003 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 11004 sizeof(wmi_wfa_config_csa)); 11005 buf_ptr += WMI_TLV_HDR_SIZE; 11006 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_STRUC_wmi_wfa_config_csa, 11007 WMITLV_GET_STRUCT_TLVLEN(wmi_wfa_config_csa)); 11008 csa = (wmi_wfa_config_csa *)buf_ptr; 11009 csa->ignore_csa = wmi_wfatest->value; 11010 buf_ptr += sizeof(wmi_wfa_config_csa); 11011 } else { 11012 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0); 11013 buf_ptr += WMI_TLV_HDR_SIZE; 11014 } 11015 11016 if (wmi_wfatest->cmd == WFA_CONFIG_OCV) { 11017 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 11018 sizeof(wmi_wfa_config_ocv)); 11019 buf_ptr += WMI_TLV_HDR_SIZE; 11020 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_STRUC_wmi_wfa_config_ocv, 11021 WMITLV_GET_STRUCT_TLVLEN(wmi_wfa_config_ocv)); 11022 ocv = (wmi_wfa_config_ocv *)buf_ptr; 11023 11024 if (wmi_fill_ocv_frame_type(wmi_wfatest->ocv_param->frame_type, 11025 &ocv->frame_types)) 11026 goto error; 11027 11028 ocv->chan_freq = wmi_wfatest->ocv_param->freq; 11029 buf_ptr += sizeof(wmi_wfa_config_ocv); 11030 } else { 11031 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0); 11032 buf_ptr += WMI_TLV_HDR_SIZE; 11033 } 11034 11035 if (wmi_wfatest->cmd == WFA_CONFIG_SA_QUERY) { 11036 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 11037 sizeof(wmi_wfa_config_saquery)); 11038 buf_ptr += WMI_TLV_HDR_SIZE; 11039 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_STRUC_wmi_wfa_config_saquery, 11040 WMITLV_GET_STRUCT_TLVLEN(wmi_wfa_config_saquery)); 11041 11042 saquery = (wmi_wfa_config_saquery *)buf_ptr; 11043 saquery->remain_connect_on_saquery_timeout = wmi_wfatest->value; 11044 } else { 11045 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0); 11046 buf_ptr += WMI_TLV_HDR_SIZE; 11047 } 11048 11049 wmi_mtrace(WMI_WFA_CONFIG_CMDID, wmi_wfatest->vdev_id, 0); 11050 if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len, 11051 WMI_WFA_CONFIG_CMDID)) { 11052 wmi_err("Failed to send wfa test command"); 11053 goto error; 11054 } 11055 11056 return QDF_STATUS_SUCCESS; 11057 11058 error: 11059 wmi_buf_free(wmi_buf); 11060 return QDF_STATUS_E_FAILURE; 11061 } 11062 11063 /** 11064 * send_unit_test_cmd_tlv() - send unit test command to fw. 11065 * @wmi_handle: wmi handle 11066 * @wmi_utest: unit test command 11067 * 11068 * This function send unit test command to fw. 11069 * 11070 * Return: CDF STATUS 11071 */ 11072 static QDF_STATUS send_unit_test_cmd_tlv(wmi_unified_t wmi_handle, 11073 struct wmi_unit_test_cmd *wmi_utest) 11074 { 11075 wmi_unit_test_cmd_fixed_param *cmd; 11076 wmi_buf_t wmi_buf; 11077 uint8_t *buf_ptr; 11078 int i; 11079 uint16_t len, args_tlv_len; 11080 uint32_t *unit_test_cmd_args; 11081 11082 args_tlv_len = 11083 WMI_TLV_HDR_SIZE + wmi_utest->num_args * sizeof(uint32_t); 11084 len = sizeof(wmi_unit_test_cmd_fixed_param) + args_tlv_len; 11085 11086 wmi_buf = wmi_buf_alloc(wmi_handle, len); 11087 if (!wmi_buf) 11088 return QDF_STATUS_E_NOMEM; 11089 11090 cmd = (wmi_unit_test_cmd_fixed_param *) wmi_buf_data(wmi_buf); 11091 buf_ptr = (uint8_t *) cmd; 11092 WMITLV_SET_HDR(&cmd->tlv_header, 11093 WMITLV_TAG_STRUC_wmi_unit_test_cmd_fixed_param, 11094 WMITLV_GET_STRUCT_TLVLEN(wmi_unit_test_cmd_fixed_param)); 11095 cmd->vdev_id = wmi_utest->vdev_id; 11096 cmd->module_id = wmi_utest->module_id; 11097 cmd->num_args = wmi_utest->num_args; 11098 cmd->diag_token = wmi_utest->diag_token; 11099 buf_ptr += sizeof(wmi_unit_test_cmd_fixed_param); 11100 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, 11101 (wmi_utest->num_args * sizeof(uint32_t))); 11102 unit_test_cmd_args = (uint32_t *) (buf_ptr + WMI_TLV_HDR_SIZE); 11103 wmi_debug("VDEV ID: %d MODULE ID: %d TOKEN: %d", 11104 cmd->vdev_id, cmd->module_id, cmd->diag_token); 11105 wmi_debug("%d num of args = ", wmi_utest->num_args); 11106 for (i = 0; (i < wmi_utest->num_args && i < WMI_UNIT_TEST_MAX_NUM_ARGS); i++) { 11107 unit_test_cmd_args[i] = wmi_utest->args[i]; 11108 wmi_debug("%d,", wmi_utest->args[i]); 11109 } 11110 wmi_mtrace(WMI_UNIT_TEST_CMDID, cmd->vdev_id, 0); 11111 if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len, 11112 WMI_UNIT_TEST_CMDID)) { 11113 wmi_err("Failed to send unit test command"); 11114 wmi_buf_free(wmi_buf); 11115 return QDF_STATUS_E_FAILURE; 11116 } 11117 11118 return QDF_STATUS_SUCCESS; 11119 } 11120 11121 /** 11122 * send_power_dbg_cmd_tlv() - send power debug commands 11123 * @wmi_handle: wmi handle 11124 * @param: wmi power debug parameter 11125 * 11126 * Send WMI_POWER_DEBUG_CMDID parameters to fw. 11127 * 11128 * Return: QDF_STATUS_SUCCESS on success, QDF_STATUS_E_** on error 11129 */ 11130 static QDF_STATUS send_power_dbg_cmd_tlv(wmi_unified_t wmi_handle, 11131 struct wmi_power_dbg_params *param) 11132 { 11133 wmi_buf_t buf = NULL; 11134 QDF_STATUS status; 11135 int len, args_tlv_len; 11136 uint8_t *buf_ptr; 11137 uint8_t i; 11138 wmi_pdev_wal_power_debug_cmd_fixed_param *cmd; 11139 uint32_t *cmd_args; 11140 11141 /* Prepare and send power debug cmd parameters */ 11142 args_tlv_len = WMI_TLV_HDR_SIZE + param->num_args * sizeof(uint32_t); 11143 len = sizeof(*cmd) + args_tlv_len; 11144 buf = wmi_buf_alloc(wmi_handle, len); 11145 if (!buf) 11146 return QDF_STATUS_E_NOMEM; 11147 11148 buf_ptr = (uint8_t *) wmi_buf_data(buf); 11149 cmd = (wmi_pdev_wal_power_debug_cmd_fixed_param *) buf_ptr; 11150 WMITLV_SET_HDR(&cmd->tlv_header, 11151 WMITLV_TAG_STRUC_wmi_pdev_wal_power_debug_cmd_fixed_param, 11152 WMITLV_GET_STRUCT_TLVLEN 11153 (wmi_pdev_wal_power_debug_cmd_fixed_param)); 11154 11155 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 11156 wmi_handle, 11157 param->pdev_id); 11158 cmd->module_id = param->module_id; 11159 cmd->num_args = param->num_args; 11160 buf_ptr += sizeof(*cmd); 11161 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, 11162 (param->num_args * sizeof(uint32_t))); 11163 cmd_args = (uint32_t *) (buf_ptr + WMI_TLV_HDR_SIZE); 11164 wmi_debug("%d num of args = ", param->num_args); 11165 for (i = 0; (i < param->num_args && i < WMI_MAX_POWER_DBG_ARGS); i++) { 11166 cmd_args[i] = param->args[i]; 11167 wmi_debug("%d,", param->args[i]); 11168 } 11169 11170 wmi_mtrace(WMI_PDEV_WAL_POWER_DEBUG_CMDID, NO_SESSION, 0); 11171 status = wmi_unified_cmd_send(wmi_handle, buf, 11172 len, WMI_PDEV_WAL_POWER_DEBUG_CMDID); 11173 if (QDF_IS_STATUS_ERROR(status)) { 11174 wmi_err("wmi_unified_cmd_send WMI_PDEV_WAL_POWER_DEBUG_CMDID returned Error %d", 11175 status); 11176 goto error; 11177 } 11178 11179 return QDF_STATUS_SUCCESS; 11180 error: 11181 wmi_buf_free(buf); 11182 11183 return status; 11184 } 11185 11186 /** 11187 * send_dfs_phyerr_offload_en_cmd_tlv() - send dfs phyerr offload enable cmd 11188 * @wmi_handle: wmi handle 11189 * @pdev_id: pdev id 11190 * 11191 * Send WMI_PDEV_DFS_PHYERR_OFFLOAD_ENABLE_CMDID command to firmware. 11192 * 11193 * Return: QDF_STATUS_SUCCESS on success, QDF_STATUS_E_** on error 11194 */ 11195 static QDF_STATUS send_dfs_phyerr_offload_en_cmd_tlv(wmi_unified_t wmi_handle, 11196 uint32_t pdev_id) 11197 { 11198 wmi_pdev_dfs_phyerr_offload_enable_cmd_fixed_param *cmd; 11199 wmi_buf_t buf; 11200 uint16_t len; 11201 QDF_STATUS ret; 11202 11203 len = sizeof(*cmd); 11204 buf = wmi_buf_alloc(wmi_handle, len); 11205 11206 wmi_debug("pdev_id=%d", pdev_id); 11207 11208 if (!buf) 11209 return QDF_STATUS_E_NOMEM; 11210 11211 cmd = (wmi_pdev_dfs_phyerr_offload_enable_cmd_fixed_param *) 11212 wmi_buf_data(buf); 11213 11214 WMITLV_SET_HDR(&cmd->tlv_header, 11215 WMITLV_TAG_STRUC_wmi_pdev_dfs_phyerr_offload_enable_cmd_fixed_param, 11216 WMITLV_GET_STRUCT_TLVLEN( 11217 wmi_pdev_dfs_phyerr_offload_enable_cmd_fixed_param)); 11218 11219 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 11220 wmi_handle, 11221 pdev_id); 11222 wmi_mtrace(WMI_PDEV_DFS_PHYERR_OFFLOAD_ENABLE_CMDID, NO_SESSION, 0); 11223 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 11224 WMI_PDEV_DFS_PHYERR_OFFLOAD_ENABLE_CMDID); 11225 if (QDF_IS_STATUS_ERROR(ret)) { 11226 wmi_err("Failed to send cmd to fw, ret=%d, pdev_id=%d", 11227 ret, pdev_id); 11228 wmi_buf_free(buf); 11229 return QDF_STATUS_E_FAILURE; 11230 } 11231 11232 return QDF_STATUS_SUCCESS; 11233 } 11234 11235 /** 11236 * send_dfs_phyerr_offload_dis_cmd_tlv() - send dfs phyerr offload disable cmd 11237 * @wmi_handle: wmi handle 11238 * @pdev_id: pdev id 11239 * 11240 * Send WMI_PDEV_DFS_PHYERR_OFFLOAD_DISABLE_CMDID command to firmware. 11241 * 11242 * Return: QDF_STATUS_SUCCESS on success, QDF_STATUS_E_** on error 11243 */ 11244 static QDF_STATUS send_dfs_phyerr_offload_dis_cmd_tlv(wmi_unified_t wmi_handle, 11245 uint32_t pdev_id) 11246 { 11247 wmi_pdev_dfs_phyerr_offload_disable_cmd_fixed_param *cmd; 11248 wmi_buf_t buf; 11249 uint16_t len; 11250 QDF_STATUS ret; 11251 11252 len = sizeof(*cmd); 11253 buf = wmi_buf_alloc(wmi_handle, len); 11254 11255 wmi_debug("pdev_id=%d", pdev_id); 11256 11257 if (!buf) 11258 return QDF_STATUS_E_NOMEM; 11259 11260 cmd = (wmi_pdev_dfs_phyerr_offload_disable_cmd_fixed_param *) 11261 wmi_buf_data(buf); 11262 11263 WMITLV_SET_HDR(&cmd->tlv_header, 11264 WMITLV_TAG_STRUC_wmi_pdev_dfs_phyerr_offload_disable_cmd_fixed_param, 11265 WMITLV_GET_STRUCT_TLVLEN( 11266 wmi_pdev_dfs_phyerr_offload_disable_cmd_fixed_param)); 11267 11268 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 11269 wmi_handle, 11270 pdev_id); 11271 wmi_mtrace(WMI_PDEV_DFS_PHYERR_OFFLOAD_DISABLE_CMDID, NO_SESSION, 0); 11272 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 11273 WMI_PDEV_DFS_PHYERR_OFFLOAD_DISABLE_CMDID); 11274 if (QDF_IS_STATUS_ERROR(ret)) { 11275 wmi_err("Failed to send cmd to fw, ret=%d, pdev_id=%d", 11276 ret, pdev_id); 11277 wmi_buf_free(buf); 11278 return QDF_STATUS_E_FAILURE; 11279 } 11280 11281 return QDF_STATUS_SUCCESS; 11282 } 11283 11284 #ifdef QCA_SUPPORT_AGILE_DFS 11285 static 11286 QDF_STATUS send_adfs_ch_cfg_cmd_tlv(wmi_unified_t wmi_handle, 11287 struct vdev_adfs_ch_cfg_params *param) 11288 { 11289 /* wmi_unified_cmd_send set request of agile ADFS channel*/ 11290 wmi_vdev_adfs_ch_cfg_cmd_fixed_param *cmd; 11291 wmi_buf_t buf; 11292 QDF_STATUS ret; 11293 uint16_t len; 11294 11295 len = sizeof(*cmd); 11296 buf = wmi_buf_alloc(wmi_handle, len); 11297 11298 if (!buf) { 11299 wmi_err("wmi_buf_alloc failed"); 11300 return QDF_STATUS_E_NOMEM; 11301 } 11302 11303 cmd = (wmi_vdev_adfs_ch_cfg_cmd_fixed_param *) 11304 wmi_buf_data(buf); 11305 11306 WMITLV_SET_HDR(&cmd->tlv_header, 11307 WMITLV_TAG_STRUC_wmi_vdev_adfs_ch_cfg_cmd_fixed_param, 11308 WMITLV_GET_STRUCT_TLVLEN 11309 (wmi_vdev_adfs_ch_cfg_cmd_fixed_param)); 11310 11311 cmd->vdev_id = param->vdev_id; 11312 cmd->ocac_mode = param->ocac_mode; 11313 cmd->center_freq1 = param->center_freq1; 11314 cmd->center_freq2 = param->center_freq2; 11315 cmd->chan_freq = param->chan_freq; 11316 cmd->chan_width = param->chan_width; 11317 cmd->min_duration_ms = param->min_duration_ms; 11318 cmd->max_duration_ms = param->max_duration_ms; 11319 wmi_debug("cmd->vdev_id: %d ,cmd->ocac_mode: %d cmd->center_freq: %d", 11320 cmd->vdev_id, cmd->ocac_mode, 11321 cmd->center_freq); 11322 11323 wmi_mtrace(WMI_VDEV_ADFS_CH_CFG_CMDID, NO_SESSION, 0); 11324 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 11325 WMI_VDEV_ADFS_CH_CFG_CMDID); 11326 11327 if (QDF_IS_STATUS_ERROR(ret)) { 11328 wmi_err("Failed to send cmd to fw, ret=%d", ret); 11329 wmi_buf_free(buf); 11330 return QDF_STATUS_E_FAILURE; 11331 } 11332 11333 return QDF_STATUS_SUCCESS; 11334 } 11335 11336 static 11337 QDF_STATUS send_adfs_ocac_abort_cmd_tlv(wmi_unified_t wmi_handle, 11338 struct vdev_adfs_abort_params *param) 11339 { 11340 /*wmi_unified_cmd_send with ocac abort on ADFS channel*/ 11341 wmi_vdev_adfs_ocac_abort_cmd_fixed_param *cmd; 11342 wmi_buf_t buf; 11343 QDF_STATUS ret; 11344 uint16_t len; 11345 11346 len = sizeof(*cmd); 11347 buf = wmi_buf_alloc(wmi_handle, len); 11348 11349 if (!buf) { 11350 wmi_err("wmi_buf_alloc failed"); 11351 return QDF_STATUS_E_NOMEM; 11352 } 11353 11354 cmd = (wmi_vdev_adfs_ocac_abort_cmd_fixed_param *) 11355 wmi_buf_data(buf); 11356 11357 WMITLV_SET_HDR 11358 (&cmd->tlv_header, 11359 WMITLV_TAG_STRUC_wmi_vdev_adfs_ocac_abort_cmd_fixed_param, 11360 WMITLV_GET_STRUCT_TLVLEN 11361 (wmi_vdev_adfs_ocac_abort_cmd_fixed_param)); 11362 11363 cmd->vdev_id = param->vdev_id; 11364 11365 wmi_mtrace(WMI_VDEV_ADFS_OCAC_ABORT_CMDID, NO_SESSION, 0); 11366 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 11367 WMI_VDEV_ADFS_OCAC_ABORT_CMDID); 11368 11369 if (QDF_IS_STATUS_ERROR(ret)) { 11370 wmi_err("Failed to send cmd to fw, ret=%d", ret); 11371 wmi_buf_free(buf); 11372 return QDF_STATUS_E_FAILURE; 11373 } 11374 11375 return QDF_STATUS_SUCCESS; 11376 } 11377 #endif 11378 11379 /** 11380 * init_cmd_send_tlv() - send initialization cmd to fw 11381 * @wmi_handle: wmi handle 11382 * @param: pointer to wmi init param 11383 * 11384 * Return: QDF_STATUS_SUCCESS for success or error code 11385 */ 11386 static QDF_STATUS init_cmd_send_tlv(wmi_unified_t wmi_handle, 11387 struct wmi_init_cmd_param *param) 11388 { 11389 wmi_buf_t buf; 11390 wmi_init_cmd_fixed_param *cmd; 11391 uint8_t *buf_ptr; 11392 wmi_resource_config *resource_cfg; 11393 wlan_host_memory_chunk *host_mem_chunks; 11394 uint32_t mem_chunk_len = 0, hw_mode_len = 0; 11395 uint16_t idx; 11396 int len; 11397 QDF_STATUS ret; 11398 11399 len = sizeof(*cmd) + sizeof(wmi_resource_config) + 11400 WMI_TLV_HDR_SIZE; 11401 mem_chunk_len = (sizeof(wlan_host_memory_chunk) * MAX_MEM_CHUNKS); 11402 11403 if (param->hw_mode_id != WMI_HOST_HW_MODE_MAX) 11404 hw_mode_len = sizeof(wmi_pdev_set_hw_mode_cmd_fixed_param) + 11405 WMI_TLV_HDR_SIZE + 11406 (param->num_band_to_mac * sizeof(wmi_pdev_band_to_mac)); 11407 11408 buf = wmi_buf_alloc(wmi_handle, len + mem_chunk_len + hw_mode_len); 11409 if (!buf) 11410 return QDF_STATUS_E_FAILURE; 11411 11412 buf_ptr = (uint8_t *) wmi_buf_data(buf); 11413 cmd = (wmi_init_cmd_fixed_param *) buf_ptr; 11414 resource_cfg = (wmi_resource_config *) (buf_ptr + sizeof(*cmd)); 11415 11416 host_mem_chunks = (wlan_host_memory_chunk *) 11417 (buf_ptr + sizeof(*cmd) + sizeof(wmi_resource_config) 11418 + WMI_TLV_HDR_SIZE); 11419 11420 WMITLV_SET_HDR(&cmd->tlv_header, 11421 WMITLV_TAG_STRUC_wmi_init_cmd_fixed_param, 11422 WMITLV_GET_STRUCT_TLVLEN(wmi_init_cmd_fixed_param)); 11423 wmi_copy_resource_config(resource_cfg, param->res_cfg); 11424 WMITLV_SET_HDR(&resource_cfg->tlv_header, 11425 WMITLV_TAG_STRUC_wmi_resource_config, 11426 WMITLV_GET_STRUCT_TLVLEN(wmi_resource_config)); 11427 11428 for (idx = 0; idx < param->num_mem_chunks; ++idx) { 11429 WMITLV_SET_HDR(&(host_mem_chunks[idx].tlv_header), 11430 WMITLV_TAG_STRUC_wlan_host_memory_chunk, 11431 WMITLV_GET_STRUCT_TLVLEN 11432 (wlan_host_memory_chunk)); 11433 host_mem_chunks[idx].ptr = param->mem_chunks[idx].paddr; 11434 host_mem_chunks[idx].size = param->mem_chunks[idx].len; 11435 host_mem_chunks[idx].req_id = param->mem_chunks[idx].req_id; 11436 if (is_service_enabled_tlv(wmi_handle, 11437 WMI_SERVICE_SUPPORT_EXTEND_ADDRESS)) 11438 host_mem_chunks[idx].ptr_high = 11439 qdf_get_upper_32_bits( 11440 param->mem_chunks[idx].paddr); 11441 QDF_TRACE(QDF_MODULE_ID_ANY, QDF_TRACE_LEVEL_DEBUG, 11442 "chunk %d len %d requested ,ptr 0x%x ", 11443 idx, host_mem_chunks[idx].size, 11444 host_mem_chunks[idx].ptr); 11445 } 11446 cmd->num_host_mem_chunks = param->num_mem_chunks; 11447 len += (param->num_mem_chunks * sizeof(wlan_host_memory_chunk)); 11448 11449 WMITLV_SET_HDR((buf_ptr + sizeof(*cmd) + sizeof(wmi_resource_config)), 11450 WMITLV_TAG_ARRAY_STRUC, 11451 (sizeof(wlan_host_memory_chunk) * 11452 param->num_mem_chunks)); 11453 11454 wmi_debug("num peers: %d , num offload peers: %d, num vdevs: %d, num tids: %d, num tdls conn tb entries: %d, num tdls vdevs: %d", 11455 resource_cfg->num_peers, resource_cfg->num_offload_peers, 11456 resource_cfg->num_vdevs, resource_cfg->num_tids, 11457 resource_cfg->num_tdls_conn_table_entries, 11458 resource_cfg->num_tdls_vdevs); 11459 11460 /* Fill hw mode id config */ 11461 buf_ptr = copy_hw_mode_in_init_cmd(wmi_handle, buf_ptr, &len, param); 11462 11463 /* Fill fw_abi_vers */ 11464 copy_fw_abi_version_tlv(wmi_handle, cmd); 11465 11466 wmi_mtrace(WMI_INIT_CMDID, NO_SESSION, 0); 11467 ret = wmi_unified_cmd_send(wmi_handle, buf, len, WMI_INIT_CMDID); 11468 if (QDF_IS_STATUS_ERROR(ret)) { 11469 wmi_err("wmi_unified_cmd_send WMI_INIT_CMDID returned Error %d", 11470 ret); 11471 wmi_buf_free(buf); 11472 } 11473 11474 return ret; 11475 11476 } 11477 11478 /** 11479 * send_addba_send_cmd_tlv() - send addba send command to fw 11480 * @wmi_handle: wmi handle 11481 * @param: pointer to delba send params 11482 * @macaddr: peer mac address 11483 * 11484 * Send WMI_ADDBA_SEND_CMDID command to firmware 11485 * Return: QDF_STATUS_SUCCESS on success. QDF_STATUS_E** on error 11486 */ 11487 static QDF_STATUS 11488 send_addba_send_cmd_tlv(wmi_unified_t wmi_handle, 11489 uint8_t macaddr[QDF_MAC_ADDR_SIZE], 11490 struct addba_send_params *param) 11491 { 11492 wmi_addba_send_cmd_fixed_param *cmd; 11493 wmi_buf_t buf; 11494 uint16_t len; 11495 QDF_STATUS ret; 11496 11497 len = sizeof(*cmd); 11498 11499 buf = wmi_buf_alloc(wmi_handle, len); 11500 if (!buf) 11501 return QDF_STATUS_E_NOMEM; 11502 11503 cmd = (wmi_addba_send_cmd_fixed_param *)wmi_buf_data(buf); 11504 11505 WMITLV_SET_HDR(&cmd->tlv_header, 11506 WMITLV_TAG_STRUC_wmi_addba_send_cmd_fixed_param, 11507 WMITLV_GET_STRUCT_TLVLEN(wmi_addba_send_cmd_fixed_param)); 11508 11509 cmd->vdev_id = param->vdev_id; 11510 WMI_CHAR_ARRAY_TO_MAC_ADDR(macaddr, &cmd->peer_macaddr); 11511 cmd->tid = param->tidno; 11512 cmd->buffersize = param->buffersize; 11513 11514 wmi_mtrace(WMI_ADDBA_SEND_CMDID, cmd->vdev_id, 0); 11515 ret = wmi_unified_cmd_send(wmi_handle, buf, len, WMI_ADDBA_SEND_CMDID); 11516 if (QDF_IS_STATUS_ERROR(ret)) { 11517 wmi_err("Failed to send cmd to fw, ret=%d", ret); 11518 wmi_buf_free(buf); 11519 return QDF_STATUS_E_FAILURE; 11520 } 11521 11522 return QDF_STATUS_SUCCESS; 11523 } 11524 11525 /** 11526 * send_delba_send_cmd_tlv() - send delba send command to fw 11527 * @wmi_handle: wmi handle 11528 * @param: pointer to delba send params 11529 * @macaddr: peer mac address 11530 * 11531 * Send WMI_DELBA_SEND_CMDID command to firmware 11532 * Return: QDF_STATUS_SUCCESS on success. QDF_STATUS_E** on error 11533 */ 11534 static QDF_STATUS 11535 send_delba_send_cmd_tlv(wmi_unified_t wmi_handle, 11536 uint8_t macaddr[QDF_MAC_ADDR_SIZE], 11537 struct delba_send_params *param) 11538 { 11539 wmi_delba_send_cmd_fixed_param *cmd; 11540 wmi_buf_t buf; 11541 uint16_t len; 11542 QDF_STATUS ret; 11543 11544 len = sizeof(*cmd); 11545 11546 buf = wmi_buf_alloc(wmi_handle, len); 11547 if (!buf) 11548 return QDF_STATUS_E_NOMEM; 11549 11550 cmd = (wmi_delba_send_cmd_fixed_param *)wmi_buf_data(buf); 11551 11552 WMITLV_SET_HDR(&cmd->tlv_header, 11553 WMITLV_TAG_STRUC_wmi_delba_send_cmd_fixed_param, 11554 WMITLV_GET_STRUCT_TLVLEN(wmi_delba_send_cmd_fixed_param)); 11555 11556 cmd->vdev_id = param->vdev_id; 11557 WMI_CHAR_ARRAY_TO_MAC_ADDR(macaddr, &cmd->peer_macaddr); 11558 cmd->tid = param->tidno; 11559 cmd->initiator = param->initiator; 11560 cmd->reasoncode = param->reasoncode; 11561 11562 wmi_mtrace(WMI_DELBA_SEND_CMDID, cmd->vdev_id, 0); 11563 ret = wmi_unified_cmd_send(wmi_handle, buf, len, WMI_DELBA_SEND_CMDID); 11564 if (QDF_IS_STATUS_ERROR(ret)) { 11565 wmi_err("Failed to send cmd to fw, ret=%d", ret); 11566 wmi_buf_free(buf); 11567 return QDF_STATUS_E_FAILURE; 11568 } 11569 11570 return QDF_STATUS_SUCCESS; 11571 } 11572 11573 /** 11574 * send_addba_clearresponse_cmd_tlv() - send addba clear response command 11575 * to fw 11576 * @wmi_handle: wmi handle 11577 * @param: pointer to addba clearresp params 11578 * @macaddr: peer mac address 11579 * Return: QDF_STATUS_SUCCESS for success or error code 11580 */ 11581 static QDF_STATUS 11582 send_addba_clearresponse_cmd_tlv(wmi_unified_t wmi_handle, 11583 uint8_t macaddr[QDF_MAC_ADDR_SIZE], 11584 struct addba_clearresponse_params *param) 11585 { 11586 wmi_addba_clear_resp_cmd_fixed_param *cmd; 11587 wmi_buf_t buf; 11588 uint16_t len; 11589 QDF_STATUS ret; 11590 11591 len = sizeof(*cmd); 11592 11593 buf = wmi_buf_alloc(wmi_handle, len); 11594 if (!buf) 11595 return QDF_STATUS_E_FAILURE; 11596 11597 cmd = (wmi_addba_clear_resp_cmd_fixed_param *)wmi_buf_data(buf); 11598 11599 WMITLV_SET_HDR(&cmd->tlv_header, 11600 WMITLV_TAG_STRUC_wmi_addba_clear_resp_cmd_fixed_param, 11601 WMITLV_GET_STRUCT_TLVLEN(wmi_addba_clear_resp_cmd_fixed_param)); 11602 11603 cmd->vdev_id = param->vdev_id; 11604 WMI_CHAR_ARRAY_TO_MAC_ADDR(macaddr, &cmd->peer_macaddr); 11605 11606 wmi_mtrace(WMI_ADDBA_CLEAR_RESP_CMDID, cmd->vdev_id, 0); 11607 ret = wmi_unified_cmd_send(wmi_handle, 11608 buf, len, WMI_ADDBA_CLEAR_RESP_CMDID); 11609 if (QDF_IS_STATUS_ERROR(ret)) { 11610 wmi_err("Failed to send cmd to fw, ret=%d", ret); 11611 wmi_buf_free(buf); 11612 return QDF_STATUS_E_FAILURE; 11613 } 11614 11615 return QDF_STATUS_SUCCESS; 11616 } 11617 11618 #ifdef OBSS_PD 11619 /** 11620 * send_obss_spatial_reuse_set_def_thresh_cmd_tlv - send obss spatial reuse set 11621 * def thresh to fw 11622 * @wmi_handle: wmi handle 11623 * @thresh: pointer to obss_spatial_reuse_def_thresh 11624 * 11625 * Return: QDF_STATUS_SUCCESS for success or error code 11626 */ 11627 static 11628 QDF_STATUS send_obss_spatial_reuse_set_def_thresh_cmd_tlv( 11629 wmi_unified_t wmi_handle, 11630 struct wmi_host_obss_spatial_reuse_set_def_thresh 11631 *thresh) 11632 { 11633 wmi_buf_t buf; 11634 wmi_obss_spatial_reuse_set_def_obss_thresh_cmd_fixed_param *cmd; 11635 QDF_STATUS ret; 11636 uint32_t cmd_len; 11637 uint32_t tlv_len; 11638 11639 cmd_len = sizeof(*cmd); 11640 11641 buf = wmi_buf_alloc(wmi_handle, cmd_len); 11642 if (!buf) 11643 return QDF_STATUS_E_NOMEM; 11644 11645 cmd = (wmi_obss_spatial_reuse_set_def_obss_thresh_cmd_fixed_param *) 11646 wmi_buf_data(buf); 11647 11648 tlv_len = WMITLV_GET_STRUCT_TLVLEN( 11649 wmi_obss_spatial_reuse_set_def_obss_thresh_cmd_fixed_param); 11650 11651 WMITLV_SET_HDR(&cmd->tlv_header, 11652 WMITLV_TAG_STRUC_wmi_obss_spatial_reuse_set_def_obss_thresh_cmd_fixed_param, 11653 tlv_len); 11654 11655 cmd->obss_min = thresh->obss_min; 11656 cmd->obss_max = thresh->obss_max; 11657 cmd->vdev_type = thresh->vdev_type; 11658 ret = wmi_unified_cmd_send(wmi_handle, buf, cmd_len, 11659 WMI_PDEV_OBSS_PD_SPATIAL_REUSE_SET_DEF_OBSS_THRESH_CMDID); 11660 if (QDF_IS_STATUS_ERROR(ret)) 11661 wmi_buf_free(buf); 11662 11663 return ret; 11664 } 11665 11666 /** 11667 * send_obss_spatial_reuse_set_cmd_tlv - send obss spatial reuse set cmd to fw 11668 * @wmi_handle: wmi handle 11669 * @obss_spatial_reuse_param: pointer to obss_spatial_reuse_param 11670 * 11671 * Return: QDF_STATUS_SUCCESS for success or error code 11672 */ 11673 static 11674 QDF_STATUS send_obss_spatial_reuse_set_cmd_tlv(wmi_unified_t wmi_handle, 11675 struct wmi_host_obss_spatial_reuse_set_param 11676 *obss_spatial_reuse_param) 11677 { 11678 wmi_buf_t buf; 11679 wmi_obss_spatial_reuse_set_cmd_fixed_param *cmd; 11680 QDF_STATUS ret; 11681 uint32_t len; 11682 11683 len = sizeof(*cmd); 11684 11685 buf = wmi_buf_alloc(wmi_handle, len); 11686 if (!buf) 11687 return QDF_STATUS_E_FAILURE; 11688 11689 cmd = (wmi_obss_spatial_reuse_set_cmd_fixed_param *)wmi_buf_data(buf); 11690 WMITLV_SET_HDR(&cmd->tlv_header, 11691 WMITLV_TAG_STRUC_wmi_obss_spatial_reuse_set_cmd_fixed_param, 11692 WMITLV_GET_STRUCT_TLVLEN 11693 (wmi_obss_spatial_reuse_set_cmd_fixed_param)); 11694 11695 cmd->enable = obss_spatial_reuse_param->enable; 11696 cmd->obss_min = obss_spatial_reuse_param->obss_min; 11697 cmd->obss_max = obss_spatial_reuse_param->obss_max; 11698 cmd->vdev_id = obss_spatial_reuse_param->vdev_id; 11699 11700 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 11701 WMI_PDEV_OBSS_PD_SPATIAL_REUSE_CMDID); 11702 11703 if (QDF_IS_STATUS_ERROR(ret)) { 11704 wmi_err( 11705 "WMI_PDEV_OBSS_PD_SPATIAL_REUSE_CMDID send returned Error %d", 11706 ret); 11707 wmi_buf_free(buf); 11708 } 11709 11710 return ret; 11711 } 11712 11713 /** 11714 * send_self_srg_bss_color_bitmap_set_cmd_tlv() - Send 64-bit BSS color bitmap 11715 * to be used by SRG based Spatial Reuse feature to the FW 11716 * @wmi_handle: wmi handle 11717 * @bitmap_0: lower 32 bits in BSS color bitmap 11718 * @bitmap_1: upper 32 bits in BSS color bitmap 11719 * @pdev_id: pdev ID 11720 * 11721 * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure 11722 */ 11723 static QDF_STATUS 11724 send_self_srg_bss_color_bitmap_set_cmd_tlv( 11725 wmi_unified_t wmi_handle, uint32_t bitmap_0, 11726 uint32_t bitmap_1, uint8_t pdev_id) 11727 { 11728 wmi_buf_t buf; 11729 wmi_pdev_srg_bss_color_bitmap_cmd_fixed_param *cmd; 11730 QDF_STATUS ret; 11731 uint32_t len; 11732 11733 len = sizeof(*cmd); 11734 11735 buf = wmi_buf_alloc(wmi_handle, len); 11736 if (!buf) 11737 return QDF_STATUS_E_FAILURE; 11738 11739 cmd = (wmi_pdev_srg_bss_color_bitmap_cmd_fixed_param *) 11740 wmi_buf_data(buf); 11741 11742 WMITLV_SET_HDR( 11743 &cmd->tlv_header, 11744 WMITLV_TAG_STRUC_wmi_pdev_srg_bss_color_bitmap_cmd_fixed_param, 11745 WMITLV_GET_STRUCT_TLVLEN 11746 (wmi_pdev_srg_bss_color_bitmap_cmd_fixed_param)); 11747 11748 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 11749 wmi_handle, pdev_id); 11750 cmd->srg_bss_color_bitmap[0] = bitmap_0; 11751 cmd->srg_bss_color_bitmap[1] = bitmap_1; 11752 11753 ret = wmi_unified_cmd_send( 11754 wmi_handle, buf, len, 11755 WMI_PDEV_SET_SRG_BSS_COLOR_BITMAP_CMDID); 11756 11757 if (QDF_IS_STATUS_ERROR(ret)) { 11758 wmi_err( 11759 "WMI_PDEV_SET_SRG_BSS_COLOR_BITMAP_CMDID send returned Error %d", 11760 ret); 11761 wmi_buf_free(buf); 11762 } 11763 11764 return ret; 11765 } 11766 11767 /** 11768 * send_self_srg_partial_bssid_bitmap_set_cmd_tlv() - Send 64-bit partial BSSID 11769 * bitmap to be used by SRG based Spatial Reuse feature to the FW 11770 * @wmi_handle: wmi handle 11771 * @bitmap_0: lower 32 bits in partial BSSID bitmap 11772 * @bitmap_1: upper 32 bits in partial BSSID bitmap 11773 * @pdev_id: pdev ID 11774 * 11775 * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure 11776 */ 11777 static QDF_STATUS 11778 send_self_srg_partial_bssid_bitmap_set_cmd_tlv( 11779 wmi_unified_t wmi_handle, uint32_t bitmap_0, 11780 uint32_t bitmap_1, uint8_t pdev_id) 11781 { 11782 wmi_buf_t buf; 11783 wmi_pdev_srg_partial_bssid_bitmap_cmd_fixed_param *cmd; 11784 QDF_STATUS ret; 11785 uint32_t len; 11786 11787 len = sizeof(*cmd); 11788 11789 buf = wmi_buf_alloc(wmi_handle, len); 11790 if (!buf) 11791 return QDF_STATUS_E_FAILURE; 11792 11793 cmd = (wmi_pdev_srg_partial_bssid_bitmap_cmd_fixed_param *) 11794 wmi_buf_data(buf); 11795 11796 WMITLV_SET_HDR( 11797 &cmd->tlv_header, 11798 WMITLV_TAG_STRUC_wmi_pdev_srg_partial_bssid_bitmap_cmd_fixed_param, 11799 WMITLV_GET_STRUCT_TLVLEN 11800 (wmi_pdev_srg_partial_bssid_bitmap_cmd_fixed_param)); 11801 11802 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 11803 wmi_handle, pdev_id); 11804 11805 cmd->srg_partial_bssid_bitmap[0] = bitmap_0; 11806 cmd->srg_partial_bssid_bitmap[1] = bitmap_1; 11807 11808 ret = wmi_unified_cmd_send( 11809 wmi_handle, buf, len, 11810 WMI_PDEV_SET_SRG_PARTIAL_BSSID_BITMAP_CMDID); 11811 11812 if (QDF_IS_STATUS_ERROR(ret)) { 11813 wmi_err( 11814 "WMI_PDEV_SET_SRG_PARTIAL_BSSID_BITMAP_CMDID send returned Error %d", 11815 ret); 11816 wmi_buf_free(buf); 11817 } 11818 11819 return ret; 11820 } 11821 11822 /** 11823 * send_self_srg_obss_color_enable_bitmap_cmd_tlv() - Send 64-bit BSS color 11824 * enable bitmap to be used by SRG based Spatial Reuse feature to the FW 11825 * @wmi_handle: wmi handle 11826 * @bitmap_0: lower 32 bits in BSS color enable bitmap 11827 * @bitmap_1: upper 32 bits in BSS color enable bitmap 11828 * @pdev_id: pdev ID 11829 * 11830 * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure 11831 */ 11832 static QDF_STATUS 11833 send_self_srg_obss_color_enable_bitmap_cmd_tlv( 11834 wmi_unified_t wmi_handle, uint32_t bitmap_0, 11835 uint32_t bitmap_1, uint8_t pdev_id) 11836 { 11837 wmi_buf_t buf; 11838 wmi_pdev_srg_obss_color_enable_bitmap_cmd_fixed_param *cmd; 11839 QDF_STATUS ret; 11840 uint32_t len; 11841 11842 len = sizeof(*cmd); 11843 11844 buf = wmi_buf_alloc(wmi_handle, len); 11845 if (!buf) 11846 return QDF_STATUS_E_FAILURE; 11847 11848 cmd = (wmi_pdev_srg_obss_color_enable_bitmap_cmd_fixed_param *) 11849 wmi_buf_data(buf); 11850 11851 WMITLV_SET_HDR( 11852 &cmd->tlv_header, 11853 WMITLV_TAG_STRUC_wmi_pdev_srg_obss_color_enable_bitmap_cmd_fixed_param, 11854 WMITLV_GET_STRUCT_TLVLEN 11855 (wmi_pdev_srg_obss_color_enable_bitmap_cmd_fixed_param)); 11856 11857 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 11858 wmi_handle, pdev_id); 11859 cmd->srg_obss_en_color_bitmap[0] = bitmap_0; 11860 cmd->srg_obss_en_color_bitmap[1] = bitmap_1; 11861 11862 ret = wmi_unified_cmd_send( 11863 wmi_handle, buf, len, 11864 WMI_PDEV_SET_SRG_OBSS_COLOR_ENABLE_BITMAP_CMDID); 11865 11866 if (QDF_IS_STATUS_ERROR(ret)) { 11867 wmi_err( 11868 "WMI_PDEV_SET_SRG_OBSS_COLOR_ENABLE_BITMAP_CMDID send returned Error %d", 11869 ret); 11870 wmi_buf_free(buf); 11871 } 11872 11873 return ret; 11874 } 11875 11876 /** 11877 * send_self_srg_obss_bssid_enable_bitmap_cmd_tlv() - Send 64-bit OBSS BSSID 11878 * enable bitmap to be used by SRG based Spatial Reuse feature to the FW 11879 * @wmi_handle: wmi handle 11880 * @bitmap_0: lower 32 bits in BSSID enable bitmap 11881 * @bitmap_1: upper 32 bits in BSSID enable bitmap 11882 * @pdev_id: pdev ID 11883 * 11884 * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure 11885 */ 11886 static QDF_STATUS 11887 send_self_srg_obss_bssid_enable_bitmap_cmd_tlv( 11888 wmi_unified_t wmi_handle, uint32_t bitmap_0, 11889 uint32_t bitmap_1, uint8_t pdev_id) 11890 { 11891 wmi_buf_t buf; 11892 wmi_pdev_srg_obss_bssid_enable_bitmap_cmd_fixed_param *cmd; 11893 QDF_STATUS ret; 11894 uint32_t len; 11895 11896 len = sizeof(*cmd); 11897 11898 buf = wmi_buf_alloc(wmi_handle, len); 11899 if (!buf) 11900 return QDF_STATUS_E_FAILURE; 11901 11902 cmd = (wmi_pdev_srg_obss_bssid_enable_bitmap_cmd_fixed_param *) 11903 wmi_buf_data(buf); 11904 11905 WMITLV_SET_HDR( 11906 &cmd->tlv_header, 11907 WMITLV_TAG_STRUC_wmi_pdev_srg_obss_bssid_enable_bitmap_cmd_fixed_param, 11908 WMITLV_GET_STRUCT_TLVLEN 11909 (wmi_pdev_srg_obss_bssid_enable_bitmap_cmd_fixed_param)); 11910 11911 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 11912 wmi_handle, pdev_id); 11913 cmd->srg_obss_en_bssid_bitmap[0] = bitmap_0; 11914 cmd->srg_obss_en_bssid_bitmap[1] = bitmap_1; 11915 11916 ret = wmi_unified_cmd_send( 11917 wmi_handle, buf, len, 11918 WMI_PDEV_SET_SRG_OBSS_BSSID_ENABLE_BITMAP_CMDID); 11919 11920 if (QDF_IS_STATUS_ERROR(ret)) { 11921 wmi_err( 11922 "WMI_PDEV_SET_SRG_OBSS_BSSID_ENABLE_BITMAP_CMDID send returned Error %d", 11923 ret); 11924 wmi_buf_free(buf); 11925 } 11926 11927 return ret; 11928 } 11929 11930 /** 11931 * send_self_non_srg_obss_color_enable_bitmap_cmd_tlv() - Send 64-bit BSS color 11932 * enable bitmap to be used by Non-SRG based Spatial Reuse feature to the FW 11933 * @wmi_handle: wmi handle 11934 * @bitmap_0: lower 32 bits in BSS color enable bitmap 11935 * @bitmap_1: upper 32 bits in BSS color enable bitmap 11936 * @pdev_id: pdev ID 11937 * 11938 * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure 11939 */ 11940 static QDF_STATUS 11941 send_self_non_srg_obss_color_enable_bitmap_cmd_tlv( 11942 wmi_unified_t wmi_handle, uint32_t bitmap_0, 11943 uint32_t bitmap_1, uint8_t pdev_id) 11944 { 11945 wmi_buf_t buf; 11946 wmi_pdev_non_srg_obss_color_enable_bitmap_cmd_fixed_param *cmd; 11947 QDF_STATUS ret; 11948 uint32_t len; 11949 11950 len = sizeof(*cmd); 11951 11952 buf = wmi_buf_alloc(wmi_handle, len); 11953 if (!buf) 11954 return QDF_STATUS_E_FAILURE; 11955 11956 cmd = (wmi_pdev_non_srg_obss_color_enable_bitmap_cmd_fixed_param *) 11957 wmi_buf_data(buf); 11958 11959 WMITLV_SET_HDR( 11960 &cmd->tlv_header, 11961 WMITLV_TAG_STRUC_wmi_pdev_non_srg_obss_color_enable_bitmap_cmd_fixed_param, 11962 WMITLV_GET_STRUCT_TLVLEN 11963 (wmi_pdev_non_srg_obss_color_enable_bitmap_cmd_fixed_param)); 11964 11965 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 11966 wmi_handle, pdev_id); 11967 cmd->non_srg_obss_en_color_bitmap[0] = bitmap_0; 11968 cmd->non_srg_obss_en_color_bitmap[1] = bitmap_1; 11969 11970 ret = wmi_unified_cmd_send( 11971 wmi_handle, buf, len, 11972 WMI_PDEV_SET_NON_SRG_OBSS_COLOR_ENABLE_BITMAP_CMDID); 11973 11974 if (QDF_IS_STATUS_ERROR(ret)) { 11975 wmi_err( 11976 "WMI_PDEV_SET_NON_SRG_OBSS_COLOR_ENABLE_BITMAP_CMDID send returned Error %d", 11977 ret); 11978 wmi_buf_free(buf); 11979 } 11980 11981 return ret; 11982 } 11983 11984 /** 11985 * send_self_non_srg_obss_bssid_enable_bitmap_cmd_tlv() - Send 64-bit OBSS BSSID 11986 * enable bitmap to be used by Non-SRG based Spatial Reuse feature to the FW 11987 * @wmi_handle: wmi handle 11988 * @bitmap_0: lower 32 bits in BSSID enable bitmap 11989 * @bitmap_1: upper 32 bits in BSSID enable bitmap 11990 * @pdev_id: pdev ID 11991 * 11992 * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure 11993 */ 11994 static QDF_STATUS 11995 send_self_non_srg_obss_bssid_enable_bitmap_cmd_tlv( 11996 wmi_unified_t wmi_handle, uint32_t bitmap_0, 11997 uint32_t bitmap_1, uint8_t pdev_id) 11998 { 11999 wmi_buf_t buf; 12000 wmi_pdev_non_srg_obss_bssid_enable_bitmap_cmd_fixed_param *cmd; 12001 QDF_STATUS ret; 12002 uint32_t len; 12003 12004 len = sizeof(*cmd); 12005 12006 buf = wmi_buf_alloc(wmi_handle, len); 12007 if (!buf) 12008 return QDF_STATUS_E_FAILURE; 12009 12010 cmd = (wmi_pdev_non_srg_obss_bssid_enable_bitmap_cmd_fixed_param *) 12011 wmi_buf_data(buf); 12012 12013 WMITLV_SET_HDR( 12014 &cmd->tlv_header, 12015 WMITLV_TAG_STRUC_wmi_pdev_non_srg_obss_bssid_enable_bitmap_cmd_fixed_param, 12016 WMITLV_GET_STRUCT_TLVLEN 12017 (wmi_pdev_non_srg_obss_bssid_enable_bitmap_cmd_fixed_param)); 12018 12019 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 12020 wmi_handle, pdev_id); 12021 cmd->non_srg_obss_en_bssid_bitmap[0] = bitmap_0; 12022 cmd->non_srg_obss_en_bssid_bitmap[1] = bitmap_1; 12023 12024 ret = wmi_unified_cmd_send( 12025 wmi_handle, buf, len, 12026 WMI_PDEV_SET_NON_SRG_OBSS_BSSID_ENABLE_BITMAP_CMDID); 12027 12028 if (QDF_IS_STATUS_ERROR(ret)) { 12029 wmi_err( 12030 "WMI_PDEV_SET_NON_SRG_OBSS_BSSID_ENABLE_BITMAP_CMDID send returned Error %d", 12031 ret); 12032 wmi_buf_free(buf); 12033 } 12034 12035 return ret; 12036 } 12037 #endif 12038 12039 static 12040 QDF_STATUS send_injector_config_cmd_tlv(wmi_unified_t wmi_handle, 12041 struct wmi_host_injector_frame_params *inject_config_params) 12042 { 12043 wmi_buf_t buf; 12044 wmi_frame_inject_cmd_fixed_param *cmd; 12045 QDF_STATUS ret; 12046 uint32_t len; 12047 12048 len = sizeof(*cmd); 12049 12050 buf = wmi_buf_alloc(wmi_handle, len); 12051 if (!buf) 12052 return QDF_STATUS_E_NOMEM; 12053 12054 cmd = (wmi_frame_inject_cmd_fixed_param *)wmi_buf_data(buf); 12055 WMITLV_SET_HDR(&cmd->tlv_header, 12056 WMITLV_TAG_STRUC_wmi_frame_inject_cmd_fixed_param, 12057 WMITLV_GET_STRUCT_TLVLEN 12058 (wmi_frame_inject_cmd_fixed_param)); 12059 12060 cmd->vdev_id = inject_config_params->vdev_id; 12061 cmd->enable = inject_config_params->enable; 12062 cmd->frame_type = inject_config_params->frame_type; 12063 cmd->frame_inject_period = inject_config_params->frame_inject_period; 12064 cmd->fc_duration = inject_config_params->frame_duration; 12065 WMI_CHAR_ARRAY_TO_MAC_ADDR(inject_config_params->dstmac, 12066 &cmd->frame_addr1); 12067 12068 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 12069 WMI_PDEV_FRAME_INJECT_CMDID); 12070 12071 if (QDF_IS_STATUS_ERROR(ret)) { 12072 wmi_err( 12073 "WMI_PDEV_FRAME_INJECT_CMDID send returned Error %d", 12074 ret); 12075 wmi_buf_free(buf); 12076 } 12077 12078 return ret; 12079 } 12080 #ifdef QCA_SUPPORT_CP_STATS 12081 /** 12082 * extract_cca_stats_tlv - api to extract congestion stats from event buffer 12083 * @wmi_handle: wma handle 12084 * @evt_buf: event buffer 12085 * @out_buff: buffer to populated after stats extraction 12086 * 12087 * Return: status of operation 12088 */ 12089 static QDF_STATUS extract_cca_stats_tlv(wmi_unified_t wmi_handle, 12090 void *evt_buf, struct wmi_host_congestion_stats *out_buff) 12091 { 12092 WMI_UPDATE_STATS_EVENTID_param_tlvs *param_buf; 12093 wmi_congestion_stats *congestion_stats; 12094 12095 param_buf = (WMI_UPDATE_STATS_EVENTID_param_tlvs *)evt_buf; 12096 congestion_stats = param_buf->congestion_stats; 12097 if (!congestion_stats) 12098 return QDF_STATUS_E_INVAL; 12099 12100 out_buff->vdev_id = congestion_stats->vdev_id; 12101 out_buff->congestion = congestion_stats->congestion; 12102 12103 wmi_debug("cca stats event processed"); 12104 return QDF_STATUS_SUCCESS; 12105 } 12106 #endif /* QCA_SUPPORT_CP_STATS */ 12107 12108 /** 12109 * extract_ctl_failsafe_check_ev_param_tlv() - extract ctl data from 12110 * event 12111 * @wmi_handle: wmi handle 12112 * @evt_buf: pointer to event buffer 12113 * @param: Pointer to hold peer ctl data 12114 * 12115 * Return: QDF_STATUS_SUCCESS for success or error code 12116 */ 12117 static QDF_STATUS extract_ctl_failsafe_check_ev_param_tlv( 12118 wmi_unified_t wmi_handle, 12119 void *evt_buf, 12120 struct wmi_host_pdev_ctl_failsafe_event *param) 12121 { 12122 WMI_PDEV_CTL_FAILSAFE_CHECK_EVENTID_param_tlvs *param_buf; 12123 wmi_pdev_ctl_failsafe_check_fixed_param *fix_param; 12124 12125 param_buf = (WMI_PDEV_CTL_FAILSAFE_CHECK_EVENTID_param_tlvs *)evt_buf; 12126 if (!param_buf) { 12127 wmi_err("Invalid ctl_failsafe event buffer"); 12128 return QDF_STATUS_E_INVAL; 12129 } 12130 12131 fix_param = param_buf->fixed_param; 12132 param->ctl_failsafe_status = fix_param->ctl_FailsafeStatus; 12133 12134 return QDF_STATUS_SUCCESS; 12135 } 12136 12137 /** 12138 * save_service_bitmap_tlv() - save service bitmap 12139 * @wmi_handle: wmi handle 12140 * @evt_buf: pointer to event buffer 12141 * @bitmap_buf: bitmap buffer, for converged legacy support 12142 * 12143 * Return: QDF_STATUS 12144 */ 12145 static 12146 QDF_STATUS save_service_bitmap_tlv(wmi_unified_t wmi_handle, void *evt_buf, 12147 void *bitmap_buf) 12148 { 12149 WMI_SERVICE_READY_EVENTID_param_tlvs *param_buf; 12150 struct wmi_soc *soc = wmi_handle->soc; 12151 12152 param_buf = (WMI_SERVICE_READY_EVENTID_param_tlvs *) evt_buf; 12153 12154 /* If it is already allocated, use that buffer. This can happen 12155 * during target stop/start scenarios where host allocation is skipped. 12156 */ 12157 if (!soc->wmi_service_bitmap) { 12158 soc->wmi_service_bitmap = 12159 qdf_mem_malloc(WMI_SERVICE_BM_SIZE * sizeof(uint32_t)); 12160 if (!soc->wmi_service_bitmap) 12161 return QDF_STATUS_E_NOMEM; 12162 } 12163 12164 qdf_mem_copy(soc->wmi_service_bitmap, 12165 param_buf->wmi_service_bitmap, 12166 (WMI_SERVICE_BM_SIZE * sizeof(uint32_t))); 12167 12168 if (bitmap_buf) 12169 qdf_mem_copy(bitmap_buf, 12170 param_buf->wmi_service_bitmap, 12171 (WMI_SERVICE_BM_SIZE * sizeof(uint32_t))); 12172 12173 return QDF_STATUS_SUCCESS; 12174 } 12175 12176 /** 12177 * save_ext_service_bitmap_tlv() - save extendend service bitmap 12178 * @wmi_handle: wmi handle 12179 * @evt_buf: pointer to event buffer 12180 * @bitmap_buf: bitmap buffer, for converged legacy support 12181 * 12182 * Return: QDF_STATUS 12183 */ 12184 static 12185 QDF_STATUS save_ext_service_bitmap_tlv(wmi_unified_t wmi_handle, void *evt_buf, 12186 void *bitmap_buf) 12187 { 12188 WMI_SERVICE_AVAILABLE_EVENTID_param_tlvs *param_buf; 12189 wmi_service_available_event_fixed_param *ev; 12190 struct wmi_soc *soc = wmi_handle->soc; 12191 uint32_t i = 0; 12192 12193 param_buf = (WMI_SERVICE_AVAILABLE_EVENTID_param_tlvs *) evt_buf; 12194 12195 ev = param_buf->fixed_param; 12196 12197 /* If it is already allocated, use that buffer. This can happen 12198 * during target stop/start scenarios where host allocation is skipped. 12199 */ 12200 if (!soc->wmi_ext_service_bitmap) { 12201 soc->wmi_ext_service_bitmap = qdf_mem_malloc( 12202 WMI_SERVICE_SEGMENT_BM_SIZE32 * sizeof(uint32_t)); 12203 if (!soc->wmi_ext_service_bitmap) 12204 return QDF_STATUS_E_NOMEM; 12205 } 12206 12207 qdf_mem_copy(soc->wmi_ext_service_bitmap, 12208 ev->wmi_service_segment_bitmap, 12209 (WMI_SERVICE_SEGMENT_BM_SIZE32 * sizeof(uint32_t))); 12210 12211 wmi_debug("wmi_ext_service_bitmap 0:0x%x, 1:0x%x, 2:0x%x, 3:0x%x", 12212 soc->wmi_ext_service_bitmap[0], soc->wmi_ext_service_bitmap[1], 12213 soc->wmi_ext_service_bitmap[2], soc->wmi_ext_service_bitmap[3]); 12214 12215 if (bitmap_buf) 12216 qdf_mem_copy(bitmap_buf, 12217 soc->wmi_ext_service_bitmap, 12218 (WMI_SERVICE_SEGMENT_BM_SIZE32 * sizeof(uint32_t))); 12219 12220 if (!param_buf->wmi_service_ext_bitmap) { 12221 wmi_debug("wmi_service_ext_bitmap not available"); 12222 return QDF_STATUS_SUCCESS; 12223 } 12224 12225 if (!soc->wmi_ext2_service_bitmap || 12226 (param_buf->num_wmi_service_ext_bitmap > 12227 soc->wmi_ext2_service_bitmap_len)) { 12228 if (soc->wmi_ext2_service_bitmap) { 12229 qdf_mem_free(soc->wmi_ext2_service_bitmap); 12230 soc->wmi_ext2_service_bitmap = NULL; 12231 } 12232 soc->wmi_ext2_service_bitmap = 12233 qdf_mem_malloc(param_buf->num_wmi_service_ext_bitmap * 12234 sizeof(uint32_t)); 12235 if (!soc->wmi_ext2_service_bitmap) 12236 return QDF_STATUS_E_NOMEM; 12237 12238 soc->wmi_ext2_service_bitmap_len = 12239 param_buf->num_wmi_service_ext_bitmap; 12240 } 12241 12242 qdf_mem_copy(soc->wmi_ext2_service_bitmap, 12243 param_buf->wmi_service_ext_bitmap, 12244 (param_buf->num_wmi_service_ext_bitmap * 12245 sizeof(uint32_t))); 12246 12247 for (i = 0; i < param_buf->num_wmi_service_ext_bitmap; i++) { 12248 wmi_debug("wmi_ext2_service_bitmap %u:0x%x", 12249 i, soc->wmi_ext2_service_bitmap[i]); 12250 } 12251 12252 return QDF_STATUS_SUCCESS; 12253 } 12254 12255 static inline void copy_ht_cap_info(uint32_t ev_target_cap, 12256 struct wlan_psoc_target_capability_info *cap) 12257 { 12258 /* except LDPC all flags are common between legacy and here 12259 * also IBFEER is not defined for TLV 12260 */ 12261 cap->ht_cap_info |= ev_target_cap & ( 12262 WMI_HT_CAP_ENABLED 12263 | WMI_HT_CAP_HT20_SGI 12264 | WMI_HT_CAP_DYNAMIC_SMPS 12265 | WMI_HT_CAP_TX_STBC 12266 | WMI_HT_CAP_TX_STBC_MASK_SHIFT 12267 | WMI_HT_CAP_RX_STBC 12268 | WMI_HT_CAP_RX_STBC_MASK_SHIFT 12269 | WMI_HT_CAP_LDPC 12270 | WMI_HT_CAP_L_SIG_TXOP_PROT 12271 | WMI_HT_CAP_MPDU_DENSITY 12272 | WMI_HT_CAP_MPDU_DENSITY_MASK_SHIFT 12273 | WMI_HT_CAP_HT40_SGI); 12274 if (ev_target_cap & WMI_HT_CAP_LDPC) 12275 cap->ht_cap_info |= WMI_HOST_HT_CAP_RX_LDPC | 12276 WMI_HOST_HT_CAP_TX_LDPC; 12277 } 12278 /** 12279 * extract_service_ready_tlv() - extract service ready event 12280 * @wmi_handle: wmi handle 12281 * @evt_buf: pointer to received event buffer 12282 * @cap: pointer to hold target capability information extracted from even 12283 * 12284 * Return: QDF_STATUS_SUCCESS for success or error code 12285 */ 12286 static QDF_STATUS extract_service_ready_tlv(wmi_unified_t wmi_handle, 12287 void *evt_buf, struct wlan_psoc_target_capability_info *cap) 12288 { 12289 WMI_SERVICE_READY_EVENTID_param_tlvs *param_buf; 12290 wmi_service_ready_event_fixed_param *ev; 12291 12292 12293 param_buf = (WMI_SERVICE_READY_EVENTID_param_tlvs *) evt_buf; 12294 12295 ev = (wmi_service_ready_event_fixed_param *) param_buf->fixed_param; 12296 if (!ev) { 12297 qdf_print("%s: wmi_buf_alloc failed", __func__); 12298 return QDF_STATUS_E_FAILURE; 12299 } 12300 12301 cap->phy_capability = ev->phy_capability; 12302 cap->max_frag_entry = ev->max_frag_entry; 12303 cap->num_rf_chains = ev->num_rf_chains; 12304 copy_ht_cap_info(ev->ht_cap_info, cap); 12305 cap->vht_cap_info = ev->vht_cap_info; 12306 cap->vht_supp_mcs = ev->vht_supp_mcs; 12307 cap->hw_min_tx_power = ev->hw_min_tx_power; 12308 cap->hw_max_tx_power = ev->hw_max_tx_power; 12309 cap->sys_cap_info = ev->sys_cap_info; 12310 cap->min_pkt_size_enable = ev->min_pkt_size_enable; 12311 cap->max_bcn_ie_size = ev->max_bcn_ie_size; 12312 cap->max_num_scan_channels = ev->max_num_scan_channels; 12313 cap->max_supported_macs = ev->max_supported_macs; 12314 cap->wmi_fw_sub_feat_caps = ev->wmi_fw_sub_feat_caps; 12315 cap->txrx_chainmask = ev->txrx_chainmask; 12316 cap->default_dbs_hw_mode_index = ev->default_dbs_hw_mode_index; 12317 cap->num_msdu_desc = ev->num_msdu_desc; 12318 cap->fw_version = ev->fw_build_vers; 12319 /* fw_version_1 is not available in TLV. */ 12320 cap->fw_version_1 = 0; 12321 12322 return QDF_STATUS_SUCCESS; 12323 } 12324 12325 /* convert_wireless_modes_tlv() - Convert REGDMN_MODE values sent by target 12326 * to host internal HOST_REGDMN_MODE values. 12327 * REGULATORY TODO : REGDMN_MODE_11AC_VHT*_2G values are not used by the 12328 * host currently. Add this in the future if required. 12329 * 11AX (Phase II) : 11ax related values are not currently 12330 * advertised separately by FW. As part of phase II regulatory bring-up, 12331 * finalize the advertisement mechanism. 12332 * @target_wireless_mode: target wireless mode received in message 12333 * 12334 * Return: returns the host internal wireless mode. 12335 */ 12336 static inline uint32_t convert_wireless_modes_tlv(uint32_t target_wireless_mode) 12337 { 12338 12339 uint32_t wireless_modes = 0; 12340 12341 wmi_debug("Target wireless mode: 0x%x", target_wireless_mode); 12342 12343 if (target_wireless_mode & REGDMN_MODE_11A) 12344 wireless_modes |= HOST_REGDMN_MODE_11A; 12345 12346 if (target_wireless_mode & REGDMN_MODE_TURBO) 12347 wireless_modes |= HOST_REGDMN_MODE_TURBO; 12348 12349 if (target_wireless_mode & REGDMN_MODE_11B) 12350 wireless_modes |= HOST_REGDMN_MODE_11B; 12351 12352 if (target_wireless_mode & REGDMN_MODE_PUREG) 12353 wireless_modes |= HOST_REGDMN_MODE_PUREG; 12354 12355 if (target_wireless_mode & REGDMN_MODE_11G) 12356 wireless_modes |= HOST_REGDMN_MODE_11G; 12357 12358 if (target_wireless_mode & REGDMN_MODE_108G) 12359 wireless_modes |= HOST_REGDMN_MODE_108G; 12360 12361 if (target_wireless_mode & REGDMN_MODE_108A) 12362 wireless_modes |= HOST_REGDMN_MODE_108A; 12363 12364 if (target_wireless_mode & REGDMN_MODE_11AC_VHT20_2G) 12365 wireless_modes |= HOST_REGDMN_MODE_11AC_VHT20_2G; 12366 12367 if (target_wireless_mode & REGDMN_MODE_XR) 12368 wireless_modes |= HOST_REGDMN_MODE_XR; 12369 12370 if (target_wireless_mode & REGDMN_MODE_11A_HALF_RATE) 12371 wireless_modes |= HOST_REGDMN_MODE_11A_HALF_RATE; 12372 12373 if (target_wireless_mode & REGDMN_MODE_11A_QUARTER_RATE) 12374 wireless_modes |= HOST_REGDMN_MODE_11A_QUARTER_RATE; 12375 12376 if (target_wireless_mode & REGDMN_MODE_11NG_HT20) 12377 wireless_modes |= HOST_REGDMN_MODE_11NG_HT20; 12378 12379 if (target_wireless_mode & REGDMN_MODE_11NA_HT20) 12380 wireless_modes |= HOST_REGDMN_MODE_11NA_HT20; 12381 12382 if (target_wireless_mode & REGDMN_MODE_11NG_HT40PLUS) 12383 wireless_modes |= HOST_REGDMN_MODE_11NG_HT40PLUS; 12384 12385 if (target_wireless_mode & REGDMN_MODE_11NG_HT40MINUS) 12386 wireless_modes |= HOST_REGDMN_MODE_11NG_HT40MINUS; 12387 12388 if (target_wireless_mode & REGDMN_MODE_11NA_HT40PLUS) 12389 wireless_modes |= HOST_REGDMN_MODE_11NA_HT40PLUS; 12390 12391 if (target_wireless_mode & REGDMN_MODE_11NA_HT40MINUS) 12392 wireless_modes |= HOST_REGDMN_MODE_11NA_HT40MINUS; 12393 12394 if (target_wireless_mode & REGDMN_MODE_11AC_VHT20) 12395 wireless_modes |= HOST_REGDMN_MODE_11AC_VHT20; 12396 12397 if (target_wireless_mode & REGDMN_MODE_11AC_VHT40PLUS) 12398 wireless_modes |= HOST_REGDMN_MODE_11AC_VHT40PLUS; 12399 12400 if (target_wireless_mode & REGDMN_MODE_11AC_VHT40MINUS) 12401 wireless_modes |= HOST_REGDMN_MODE_11AC_VHT40MINUS; 12402 12403 if (target_wireless_mode & REGDMN_MODE_11AC_VHT80) 12404 wireless_modes |= HOST_REGDMN_MODE_11AC_VHT80; 12405 12406 if (target_wireless_mode & REGDMN_MODE_11AC_VHT160) 12407 wireless_modes |= HOST_REGDMN_MODE_11AC_VHT160; 12408 12409 if (target_wireless_mode & REGDMN_MODE_11AC_VHT80_80) 12410 wireless_modes |= HOST_REGDMN_MODE_11AC_VHT80_80; 12411 12412 return wireless_modes; 12413 } 12414 12415 /** 12416 * convert_11be_phybitmap_to_reg_flags() - Convert 11BE phybitmap to 12417 * to regulatory flags. 12418 * @target_phybitmap: target phybitmap. 12419 * @phybitmap: host internal REGULATORY_PHYMODE set based on target 12420 * phybitmap. 12421 * 12422 * Return: None 12423 */ 12424 12425 #ifdef WLAN_FEATURE_11BE 12426 static void convert_11be_phybitmap_to_reg_flags(uint32_t target_phybitmap, 12427 uint32_t *phybitmap) 12428 { 12429 if (target_phybitmap & WMI_REGULATORY_PHYMODE_NO11BE) 12430 *phybitmap |= REGULATORY_PHYMODE_NO11BE; 12431 } 12432 #else 12433 static void convert_11be_phybitmap_to_reg_flags(uint32_t target_phybitmap, 12434 uint32_t *phybitmap) 12435 { 12436 } 12437 #endif 12438 12439 /* convert_phybitmap_tlv() - Convert WMI_REGULATORY_PHYBITMAP values sent by 12440 * target to host internal REGULATORY_PHYMODE values. 12441 * 12442 * @target_target_phybitmap: target phybitmap received in the message. 12443 * 12444 * Return: returns the host internal REGULATORY_PHYMODE. 12445 */ 12446 static uint32_t convert_phybitmap_tlv(uint32_t target_phybitmap) 12447 { 12448 uint32_t phybitmap = 0; 12449 12450 wmi_debug("Target phybitmap: 0x%x", target_phybitmap); 12451 12452 if (target_phybitmap & WMI_REGULATORY_PHYMODE_NO11A) 12453 phybitmap |= REGULATORY_PHYMODE_NO11A; 12454 12455 if (target_phybitmap & WMI_REGULATORY_PHYMODE_NO11B) 12456 phybitmap |= REGULATORY_PHYMODE_NO11B; 12457 12458 if (target_phybitmap & WMI_REGULATORY_PHYMODE_NO11G) 12459 phybitmap |= REGULATORY_PHYMODE_NO11G; 12460 12461 if (target_phybitmap & WMI_REGULATORY_PHYMODE_NO11N) 12462 phybitmap |= REGULATORY_CHAN_NO11N; 12463 12464 if (target_phybitmap & WMI_REGULATORY_PHYMODE_NO11AC) 12465 phybitmap |= REGULATORY_PHYMODE_NO11AC; 12466 12467 if (target_phybitmap & WMI_REGULATORY_PHYMODE_NO11AX) 12468 phybitmap |= REGULATORY_PHYMODE_NO11AX; 12469 12470 convert_11be_phybitmap_to_reg_flags(target_phybitmap, &phybitmap); 12471 12472 return phybitmap; 12473 } 12474 12475 /** 12476 * convert_11be_flags_to_modes_ext() - Convert 11BE wireless mode flag 12477 * advertised by the target to wireless mode ext flags. 12478 * @target_wireless_modes_ext: Target wireless mode 12479 * @wireless_modes_ext: Variable to hold all the target wireless mode caps. 12480 * 12481 * Return: None 12482 */ 12483 #ifdef WLAN_FEATURE_11BE 12484 static void convert_11be_flags_to_modes_ext(uint32_t target_wireless_modes_ext, 12485 uint64_t *wireless_modes_ext) 12486 { 12487 if (target_wireless_modes_ext & REGDMN_MODE_U32_11BEG_EHT20) 12488 *wireless_modes_ext |= HOST_REGDMN_MODE_11BEG_EHT20; 12489 12490 if (target_wireless_modes_ext & REGDMN_MODE_U32_11BEG_EHT40PLUS) 12491 *wireless_modes_ext |= HOST_REGDMN_MODE_11BEG_EHT40PLUS; 12492 12493 if (target_wireless_modes_ext & REGDMN_MODE_U32_11BEG_EHT40MINUS) 12494 *wireless_modes_ext |= HOST_REGDMN_MODE_11BEG_EHT40MINUS; 12495 12496 if (target_wireless_modes_ext & REGDMN_MODE_U32_11BEA_EHT20) 12497 *wireless_modes_ext |= HOST_REGDMN_MODE_11BEA_EHT20; 12498 12499 if (target_wireless_modes_ext & REGDMN_MODE_U32_11BEA_EHT40PLUS) 12500 *wireless_modes_ext |= HOST_REGDMN_MODE_11BEA_EHT40PLUS; 12501 12502 if (target_wireless_modes_ext & REGDMN_MODE_U32_11BEA_EHT40MINUS) 12503 *wireless_modes_ext |= HOST_REGDMN_MODE_11BEA_EHT40MINUS; 12504 12505 if (target_wireless_modes_ext & REGDMN_MODE_U32_11BEA_EHT80) 12506 *wireless_modes_ext |= HOST_REGDMN_MODE_11BEA_EHT80; 12507 12508 if (target_wireless_modes_ext & REGDMN_MODE_U32_11BEA_EHT160) 12509 *wireless_modes_ext |= HOST_REGDMN_MODE_11BEA_EHT160; 12510 12511 if (target_wireless_modes_ext & REGDMN_MODE_U32_11BEA_EHT320) 12512 *wireless_modes_ext |= HOST_REGDMN_MODE_11BEA_EHT320; 12513 } 12514 #else 12515 static void convert_11be_flags_to_modes_ext(uint32_t target_wireless_modes_ext, 12516 uint64_t *wireless_modes_ext) 12517 { 12518 } 12519 #endif 12520 12521 static inline uint64_t convert_wireless_modes_ext_tlv( 12522 uint32_t target_wireless_modes_ext) 12523 { 12524 uint64_t wireless_modes_ext = 0; 12525 12526 wmi_debug("Target wireless mode: 0x%x", target_wireless_modes_ext); 12527 12528 if (target_wireless_modes_ext & REGDMN_MODE_U32_11AXG_HE20) 12529 wireless_modes_ext |= HOST_REGDMN_MODE_11AXG_HE20; 12530 12531 if (target_wireless_modes_ext & REGDMN_MODE_U32_11AXG_HE40PLUS) 12532 wireless_modes_ext |= HOST_REGDMN_MODE_11AXG_HE40PLUS; 12533 12534 if (target_wireless_modes_ext & REGDMN_MODE_U32_11AXG_HE40MINUS) 12535 wireless_modes_ext |= HOST_REGDMN_MODE_11AXG_HE40MINUS; 12536 12537 if (target_wireless_modes_ext & REGDMN_MODE_U32_11AXA_HE20) 12538 wireless_modes_ext |= HOST_REGDMN_MODE_11AXA_HE20; 12539 12540 if (target_wireless_modes_ext & REGDMN_MODE_U32_11AXA_HE40PLUS) 12541 wireless_modes_ext |= HOST_REGDMN_MODE_11AXA_HE40PLUS; 12542 12543 if (target_wireless_modes_ext & REGDMN_MODE_U32_11AXA_HE40MINUS) 12544 wireless_modes_ext |= HOST_REGDMN_MODE_11AXA_HE40MINUS; 12545 12546 if (target_wireless_modes_ext & REGDMN_MODE_U32_11AXA_HE80) 12547 wireless_modes_ext |= HOST_REGDMN_MODE_11AXA_HE80; 12548 12549 if (target_wireless_modes_ext & REGDMN_MODE_U32_11AXA_HE160) 12550 wireless_modes_ext |= HOST_REGDMN_MODE_11AXA_HE160; 12551 12552 if (target_wireless_modes_ext & REGDMN_MODE_U32_11AXA_HE80_80) 12553 wireless_modes_ext |= HOST_REGDMN_MODE_11AXA_HE80_80; 12554 12555 convert_11be_flags_to_modes_ext(target_wireless_modes_ext, 12556 &wireless_modes_ext); 12557 12558 return wireless_modes_ext; 12559 } 12560 12561 /** 12562 * extract_hal_reg_cap_tlv() - extract HAL registered capabilities 12563 * @wmi_handle: wmi handle 12564 * @evt_buf: Pointer to event buffer 12565 * @cap: pointer to hold HAL reg capabilities 12566 * 12567 * Return: QDF_STATUS_SUCCESS for success or error code 12568 */ 12569 static QDF_STATUS extract_hal_reg_cap_tlv(wmi_unified_t wmi_handle, 12570 void *evt_buf, struct wlan_psoc_hal_reg_capability *cap) 12571 { 12572 WMI_SERVICE_READY_EVENTID_param_tlvs *param_buf; 12573 12574 param_buf = (WMI_SERVICE_READY_EVENTID_param_tlvs *) evt_buf; 12575 if (!param_buf || !param_buf->hal_reg_capabilities) { 12576 wmi_err("Invalid arguments"); 12577 return QDF_STATUS_E_FAILURE; 12578 } 12579 qdf_mem_copy(cap, (((uint8_t *)param_buf->hal_reg_capabilities) + 12580 sizeof(uint32_t)), 12581 sizeof(struct wlan_psoc_hal_reg_capability)); 12582 12583 cap->wireless_modes = convert_wireless_modes_tlv( 12584 param_buf->hal_reg_capabilities->wireless_modes); 12585 12586 return QDF_STATUS_SUCCESS; 12587 } 12588 12589 /** 12590 * extract_hal_reg_cap_ext2_tlv() - extract HAL registered capability ext 12591 * @wmi_handle: wmi handle 12592 * @evt_buf: Pointer to event buffer 12593 * @phy_idx: Specific phy to extract 12594 * @param: pointer to hold HAL reg capabilities 12595 * 12596 * Return: QDF_STATUS_SUCCESS for success or error code 12597 */ 12598 static QDF_STATUS extract_hal_reg_cap_ext2_tlv( 12599 wmi_unified_t wmi_handle, void *evt_buf, uint8_t phy_idx, 12600 struct wlan_psoc_host_hal_reg_capabilities_ext2 *param) 12601 { 12602 WMI_SERVICE_READY_EXT2_EVENTID_param_tlvs *param_buf; 12603 WMI_HAL_REG_CAPABILITIES_EXT2 *reg_caps; 12604 12605 if (!evt_buf) { 12606 wmi_err("null evt_buf"); 12607 return QDF_STATUS_E_INVAL; 12608 } 12609 12610 param_buf = (WMI_SERVICE_READY_EXT2_EVENTID_param_tlvs *)evt_buf; 12611 12612 if (!param_buf->num_hal_reg_caps) 12613 return QDF_STATUS_SUCCESS; 12614 12615 if (phy_idx >= param_buf->num_hal_reg_caps) 12616 return QDF_STATUS_E_INVAL; 12617 12618 reg_caps = ¶m_buf->hal_reg_caps[phy_idx]; 12619 12620 param->phy_id = reg_caps->phy_id; 12621 param->wireless_modes_ext = convert_wireless_modes_ext_tlv( 12622 reg_caps->wireless_modes_ext); 12623 12624 return QDF_STATUS_SUCCESS; 12625 } 12626 12627 /** 12628 * extract_num_mem_reqs_tlv() - Extract number of memory entries requested 12629 * @wmi_handle: wmi handle 12630 * @evt_buf: pointer to event buffer 12631 * 12632 * Return: Number of entries requested 12633 */ 12634 static uint32_t extract_num_mem_reqs_tlv(wmi_unified_t wmi_handle, 12635 void *evt_buf) 12636 { 12637 WMI_SERVICE_READY_EVENTID_param_tlvs *param_buf; 12638 wmi_service_ready_event_fixed_param *ev; 12639 12640 param_buf = (WMI_SERVICE_READY_EVENTID_param_tlvs *) evt_buf; 12641 12642 ev = (wmi_service_ready_event_fixed_param *) param_buf->fixed_param; 12643 if (!ev) { 12644 qdf_print("%s: wmi_buf_alloc failed", __func__); 12645 return 0; 12646 } 12647 12648 if (ev->num_mem_reqs > param_buf->num_mem_reqs) { 12649 wmi_err("Invalid num_mem_reqs %d:%d", 12650 ev->num_mem_reqs, param_buf->num_mem_reqs); 12651 return 0; 12652 } 12653 12654 return ev->num_mem_reqs; 12655 } 12656 12657 /** 12658 * extract_host_mem_req_tlv() - Extract host memory required from 12659 * service ready event 12660 * @wmi_handle: wmi handle 12661 * @evt_buf: pointer to event buffer 12662 * @mem_reqs: pointer to host memory request structure 12663 * @num_active_peers: number of active peers for peer cache 12664 * @num_peers: number of peers 12665 * @fw_prio: FW priority 12666 * @idx: index for memory request 12667 * 12668 * Return: Host memory request parameters requested by target 12669 */ 12670 static QDF_STATUS extract_host_mem_req_tlv(wmi_unified_t wmi_handle, 12671 void *evt_buf, 12672 host_mem_req *mem_reqs, 12673 uint32_t num_active_peers, 12674 uint32_t num_peers, 12675 enum wmi_fw_mem_prio fw_prio, 12676 uint16_t idx) 12677 { 12678 WMI_SERVICE_READY_EVENTID_param_tlvs *param_buf; 12679 12680 param_buf = (WMI_SERVICE_READY_EVENTID_param_tlvs *)evt_buf; 12681 12682 mem_reqs->req_id = (uint32_t)param_buf->mem_reqs[idx].req_id; 12683 mem_reqs->unit_size = (uint32_t)param_buf->mem_reqs[idx].unit_size; 12684 mem_reqs->num_unit_info = 12685 (uint32_t)param_buf->mem_reqs[idx].num_unit_info; 12686 mem_reqs->num_units = (uint32_t)param_buf->mem_reqs[idx].num_units; 12687 mem_reqs->tgt_num_units = 0; 12688 12689 if (((fw_prio == WMI_FW_MEM_HIGH_PRIORITY) && 12690 (mem_reqs->num_unit_info & 12691 REQ_TO_HOST_FOR_CONT_MEMORY)) || 12692 ((fw_prio == WMI_FW_MEM_LOW_PRIORITY) && 12693 (!(mem_reqs->num_unit_info & 12694 REQ_TO_HOST_FOR_CONT_MEMORY)))) { 12695 /* First allocate the memory that requires contiguous memory */ 12696 mem_reqs->tgt_num_units = mem_reqs->num_units; 12697 if (mem_reqs->num_unit_info) { 12698 if (mem_reqs->num_unit_info & 12699 NUM_UNITS_IS_NUM_PEERS) { 12700 /* 12701 * number of units allocated is equal to number 12702 * of peers, 1 extra for self peer on target. 12703 * this needs to be fixed, host and target can 12704 * get out of sync 12705 */ 12706 mem_reqs->tgt_num_units = num_peers + 1; 12707 } 12708 if (mem_reqs->num_unit_info & 12709 NUM_UNITS_IS_NUM_ACTIVE_PEERS) { 12710 /* 12711 * Requesting allocation of memory using 12712 * num_active_peers in qcache. if qcache is 12713 * disabled in host, then it should allocate 12714 * memory for num_peers instead of 12715 * num_active_peers. 12716 */ 12717 if (num_active_peers) 12718 mem_reqs->tgt_num_units = 12719 num_active_peers + 1; 12720 else 12721 mem_reqs->tgt_num_units = 12722 num_peers + 1; 12723 } 12724 } 12725 12726 wmi_debug("idx %d req %d num_units %d num_unit_info %d" 12727 "unit size %d actual units %d", 12728 idx, mem_reqs->req_id, 12729 mem_reqs->num_units, 12730 mem_reqs->num_unit_info, 12731 mem_reqs->unit_size, 12732 mem_reqs->tgt_num_units); 12733 } 12734 12735 return QDF_STATUS_SUCCESS; 12736 } 12737 12738 /** 12739 * save_fw_version_in_service_ready_tlv() - Save fw version in service 12740 * ready function 12741 * @wmi_handle: wmi handle 12742 * @evt_buf: pointer to event buffer 12743 * 12744 * Return: QDF_STATUS_SUCCESS for success or error code 12745 */ 12746 static QDF_STATUS 12747 save_fw_version_in_service_ready_tlv(wmi_unified_t wmi_handle, void *evt_buf) 12748 { 12749 WMI_SERVICE_READY_EVENTID_param_tlvs *param_buf; 12750 wmi_service_ready_event_fixed_param *ev; 12751 12752 12753 param_buf = (WMI_SERVICE_READY_EVENTID_param_tlvs *) evt_buf; 12754 12755 ev = (wmi_service_ready_event_fixed_param *) param_buf->fixed_param; 12756 if (!ev) { 12757 qdf_print("%s: wmi_buf_alloc failed", __func__); 12758 return QDF_STATUS_E_FAILURE; 12759 } 12760 12761 /*Save fw version from service ready message */ 12762 /*This will be used while sending INIT message */ 12763 qdf_mem_copy(&wmi_handle->fw_abi_version, &ev->fw_abi_vers, 12764 sizeof(wmi_handle->fw_abi_version)); 12765 12766 return QDF_STATUS_SUCCESS; 12767 } 12768 12769 /** 12770 * ready_extract_init_status_tlv() - Extract init status from ready event 12771 * @wmi_handle: wmi handle 12772 * @evt_buf: Pointer to event buffer 12773 * 12774 * Return: ready status 12775 */ 12776 static uint32_t ready_extract_init_status_tlv(wmi_unified_t wmi_handle, 12777 void *evt_buf) 12778 { 12779 WMI_READY_EVENTID_param_tlvs *param_buf = NULL; 12780 wmi_ready_event_fixed_param *ev = NULL; 12781 12782 param_buf = (WMI_READY_EVENTID_param_tlvs *) evt_buf; 12783 ev = param_buf->fixed_param; 12784 12785 qdf_print("%s:%d", __func__, ev->status); 12786 12787 return ev->status; 12788 } 12789 12790 /** 12791 * ready_extract_mac_addr_tlv() - extract mac address from ready event 12792 * @wmi_handle: wmi handle 12793 * @evt_buf: pointer to event buffer 12794 * @macaddr: Pointer to hold MAC address 12795 * 12796 * Return: QDF_STATUS_SUCCESS for success or error code 12797 */ 12798 static QDF_STATUS ready_extract_mac_addr_tlv(wmi_unified_t wmi_handle, 12799 void *evt_buf, uint8_t *macaddr) 12800 { 12801 WMI_READY_EVENTID_param_tlvs *param_buf = NULL; 12802 wmi_ready_event_fixed_param *ev = NULL; 12803 12804 12805 param_buf = (WMI_READY_EVENTID_param_tlvs *) evt_buf; 12806 ev = param_buf->fixed_param; 12807 12808 WMI_MAC_ADDR_TO_CHAR_ARRAY(&ev->mac_addr, macaddr); 12809 12810 return QDF_STATUS_SUCCESS; 12811 } 12812 12813 /** 12814 * ready_extract_mac_addr_list_tlv() - extract MAC address list from ready event 12815 * @wmi_handle: wmi handle 12816 * @evt_buf: pointer to event buffer 12817 * @num_mac: Pointer to hold number of MAC addresses 12818 * 12819 * Return: Pointer to addr list 12820 */ 12821 static wmi_host_mac_addr * 12822 ready_extract_mac_addr_list_tlv(wmi_unified_t wmi_handle, 12823 void *evt_buf, uint8_t *num_mac) 12824 { 12825 WMI_READY_EVENTID_param_tlvs *param_buf = NULL; 12826 wmi_ready_event_fixed_param *ev = NULL; 12827 12828 param_buf = (WMI_READY_EVENTID_param_tlvs *) evt_buf; 12829 ev = param_buf->fixed_param; 12830 12831 *num_mac = ev->num_extra_mac_addr; 12832 12833 return (wmi_host_mac_addr *) param_buf->mac_addr_list; 12834 } 12835 12836 /** 12837 * extract_ready_event_params_tlv() - Extract data from ready event apart from 12838 * status, macaddr and version. 12839 * @wmi_handle: Pointer to WMI handle. 12840 * @evt_buf: Pointer to Ready event buffer. 12841 * @ev_param: Pointer to host defined struct to copy the data from event. 12842 * 12843 * Return: QDF_STATUS_SUCCESS on success. 12844 */ 12845 static QDF_STATUS extract_ready_event_params_tlv(wmi_unified_t wmi_handle, 12846 void *evt_buf, struct wmi_host_ready_ev_param *ev_param) 12847 { 12848 WMI_READY_EVENTID_param_tlvs *param_buf = NULL; 12849 wmi_ready_event_fixed_param *ev = NULL; 12850 12851 param_buf = (WMI_READY_EVENTID_param_tlvs *) evt_buf; 12852 ev = param_buf->fixed_param; 12853 12854 ev_param->status = ev->status; 12855 ev_param->num_dscp_table = ev->num_dscp_table; 12856 ev_param->num_extra_mac_addr = ev->num_extra_mac_addr; 12857 ev_param->num_total_peer = ev->num_total_peers; 12858 ev_param->num_extra_peer = ev->num_extra_peers; 12859 /* Agile_capability in ready event is supported in TLV target, 12860 * as per aDFS FR 12861 */ 12862 ev_param->max_ast_index = ev->max_ast_index; 12863 ev_param->pktlog_defs_checksum = ev->pktlog_defs_checksum; 12864 ev_param->agile_capability = 1; 12865 ev_param->num_max_active_vdevs = ev->num_max_active_vdevs; 12866 12867 return QDF_STATUS_SUCCESS; 12868 } 12869 12870 /** 12871 * extract_dbglog_data_len_tlv() - extract debuglog data length 12872 * @wmi_handle: wmi handle 12873 * @evt_buf: pointer to event buffer 12874 * @len: length of the log 12875 * 12876 * Return: pointer to the debug log 12877 */ 12878 static uint8_t *extract_dbglog_data_len_tlv(wmi_unified_t wmi_handle, 12879 void *evt_buf, uint32_t *len) 12880 { 12881 WMI_DEBUG_MESG_EVENTID_param_tlvs *param_buf; 12882 12883 param_buf = (WMI_DEBUG_MESG_EVENTID_param_tlvs *) evt_buf; 12884 12885 *len = param_buf->num_bufp; 12886 12887 return param_buf->bufp; 12888 } 12889 12890 12891 #ifdef MGMT_FRAME_RX_DECRYPT_ERROR 12892 #define IS_WMI_RX_MGMT_FRAME_STATUS_INVALID(_status) false 12893 #else 12894 #define IS_WMI_RX_MGMT_FRAME_STATUS_INVALID(_status) \ 12895 ((_status) & WMI_RXERR_DECRYPT) 12896 #endif 12897 12898 /** 12899 * extract_mgmt_rx_params_tlv() - extract management rx params from event 12900 * @wmi_handle: wmi handle 12901 * @evt_buf: pointer to event buffer 12902 * @hdr: Pointer to hold header 12903 * @bufp: Pointer to hold pointer to rx param buffer 12904 * 12905 * Return: QDF_STATUS_SUCCESS for success or error code 12906 */ 12907 static QDF_STATUS extract_mgmt_rx_params_tlv(wmi_unified_t wmi_handle, 12908 void *evt_buf, struct mgmt_rx_event_params *hdr, 12909 uint8_t **bufp) 12910 { 12911 WMI_MGMT_RX_EVENTID_param_tlvs *param_tlvs = NULL; 12912 wmi_mgmt_rx_hdr *ev_hdr = NULL; 12913 int i; 12914 12915 param_tlvs = (WMI_MGMT_RX_EVENTID_param_tlvs *) evt_buf; 12916 if (!param_tlvs) { 12917 wmi_err_rl("Get NULL point message from FW"); 12918 return QDF_STATUS_E_INVAL; 12919 } 12920 12921 ev_hdr = param_tlvs->hdr; 12922 if (!hdr) { 12923 wmi_err_rl("Rx event is NULL"); 12924 return QDF_STATUS_E_INVAL; 12925 } 12926 12927 if (IS_WMI_RX_MGMT_FRAME_STATUS_INVALID(ev_hdr->status)) { 12928 wmi_err_rl("RX mgmt frame decrypt error, discard it"); 12929 return QDF_STATUS_E_INVAL; 12930 } 12931 if ((ev_hdr->status) & WMI_RXERR_MIC) { 12932 wmi_err_rl("RX mgmt frame MIC mismatch for beacon protected frame"); 12933 } 12934 12935 if (ev_hdr->buf_len > param_tlvs->num_bufp) { 12936 wmi_err_rl("Rx mgmt frame length mismatch, discard it"); 12937 return QDF_STATUS_E_INVAL; 12938 } 12939 12940 hdr->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host( 12941 wmi_handle, 12942 ev_hdr->pdev_id); 12943 hdr->chan_freq = ev_hdr->chan_freq; 12944 hdr->channel = ev_hdr->channel; 12945 hdr->snr = ev_hdr->snr; 12946 hdr->rate = ev_hdr->rate; 12947 hdr->phy_mode = ev_hdr->phy_mode; 12948 hdr->buf_len = ev_hdr->buf_len; 12949 hdr->status = ev_hdr->status; 12950 hdr->flags = ev_hdr->flags; 12951 hdr->rssi = ev_hdr->rssi; 12952 hdr->tsf_delta = ev_hdr->tsf_delta; 12953 hdr->tsf_l32 = ev_hdr->rx_tsf_l32; 12954 for (i = 0; i < ATH_MAX_ANTENNA; i++) 12955 hdr->rssi_ctl[i] = ev_hdr->rssi_ctl[i]; 12956 12957 *bufp = param_tlvs->bufp; 12958 12959 extract_mgmt_rx_mlo_link_removal_tlv_count( 12960 param_tlvs->num_link_removal_tbtt_count, hdr); 12961 12962 return QDF_STATUS_SUCCESS; 12963 } 12964 12965 static QDF_STATUS extract_mgmt_rx_ext_params_tlv(wmi_unified_t wmi_handle, 12966 void *evt_buf, struct mgmt_rx_event_ext_params *ext_params) 12967 { 12968 WMI_MGMT_RX_EVENTID_param_tlvs *param_tlvs; 12969 wmi_mgmt_rx_params_ext *ext_params_tlv; 12970 wmi_mgmt_rx_hdr *ev_hdr; 12971 12972 param_tlvs = (WMI_MGMT_RX_EVENTID_param_tlvs *) evt_buf; 12973 if (!param_tlvs) { 12974 wmi_err("param_tlvs is NULL"); 12975 return QDF_STATUS_E_INVAL; 12976 } 12977 12978 ev_hdr = param_tlvs->hdr; 12979 if (!ev_hdr) { 12980 wmi_err("Rx event is NULL"); 12981 return QDF_STATUS_E_INVAL; 12982 } 12983 12984 ext_params_tlv = param_tlvs->mgmt_rx_params_ext; 12985 if (ext_params_tlv) { 12986 ext_params->ba_win_size = WMI_RX_PARAM_EXT_BA_WIN_SIZE_GET( 12987 ext_params_tlv->mgmt_rx_params_ext_dword1); 12988 if (ext_params->ba_win_size > 1024) { 12989 wmi_info("ba win size %d from TLV is Invalid", 12990 ext_params->ba_win_size); 12991 return QDF_STATUS_E_INVAL; 12992 } 12993 12994 ext_params->reo_win_size = WMI_RX_PARAM_EXT_REO_WIN_SIZE_GET( 12995 ext_params_tlv->mgmt_rx_params_ext_dword1); 12996 if (ext_params->reo_win_size > 2048) { 12997 wmi_info("reo win size %d from TLV is Invalid", 12998 ext_params->reo_win_size); 12999 return QDF_STATUS_E_INVAL; 13000 } 13001 } else { 13002 ext_params->ba_win_size = 0; 13003 ext_params->reo_win_size = 0; 13004 } 13005 13006 return QDF_STATUS_SUCCESS; 13007 } 13008 13009 #ifdef WLAN_MGMT_RX_REO_SUPPORT 13010 /** 13011 * extract_mgmt_rx_fw_consumed_tlv() - extract MGMT Rx FW consumed event 13012 * @wmi_handle: wmi handle 13013 * @evt_buf: pointer to event buffer 13014 * @params: Pointer to MGMT Rx REO parameters 13015 * 13016 * Return: QDF_STATUS_SUCCESS for success or error code 13017 */ 13018 static QDF_STATUS 13019 extract_mgmt_rx_fw_consumed_tlv(wmi_unified_t wmi_handle, 13020 void *evt_buf, 13021 struct mgmt_rx_reo_params *params) 13022 { 13023 WMI_MGMT_RX_FW_CONSUMED_EVENTID_param_tlvs *param_tlvs; 13024 wmi_mgmt_rx_fw_consumed_hdr *ev_hdr; 13025 13026 param_tlvs = evt_buf; 13027 if (!param_tlvs) { 13028 wmi_err("param_tlvs is NULL"); 13029 return QDF_STATUS_E_INVAL; 13030 } 13031 13032 ev_hdr = param_tlvs->hdr; 13033 if (!params) { 13034 wmi_err("Rx REO parameters is NULL"); 13035 return QDF_STATUS_E_INVAL; 13036 } 13037 13038 params->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host( 13039 wmi_handle, 13040 ev_hdr->pdev_id); 13041 params->valid = WMI_MGMT_RX_FW_CONSUMED_PARAM_MGMT_PKT_CTR_VALID_GET( 13042 ev_hdr->mgmt_pkt_ctr_info); 13043 params->global_timestamp = ev_hdr->global_timestamp; 13044 params->mgmt_pkt_ctr = WMI_MGMT_RX_FW_CONSUMED_PARAM_MGMT_PKT_CTR_GET( 13045 ev_hdr->mgmt_pkt_ctr_info); 13046 params->duration_us = ev_hdr->rx_ppdu_duration_us; 13047 params->start_timestamp = params->global_timestamp; 13048 params->end_timestamp = params->start_timestamp + 13049 params->duration_us; 13050 13051 return QDF_STATUS_SUCCESS; 13052 } 13053 13054 /** 13055 * extract_mgmt_rx_reo_params_tlv() - extract MGMT Rx REO params from 13056 * MGMT_RX_EVENT_ID 13057 * @wmi_handle: wmi handle 13058 * @evt_buf: pointer to event buffer 13059 * @reo_params: Pointer to MGMT Rx REO parameters 13060 * 13061 * Return: QDF_STATUS_SUCCESS for success or error code 13062 */ 13063 static QDF_STATUS extract_mgmt_rx_reo_params_tlv(wmi_unified_t wmi_handle, 13064 void *evt_buf, struct mgmt_rx_reo_params *reo_params) 13065 { 13066 WMI_MGMT_RX_EVENTID_param_tlvs *param_tlvs; 13067 wmi_mgmt_rx_reo_params *reo_params_tlv; 13068 wmi_mgmt_rx_hdr *ev_hdr; 13069 13070 param_tlvs = evt_buf; 13071 if (!param_tlvs) { 13072 wmi_err("param_tlvs is NULL"); 13073 return QDF_STATUS_E_INVAL; 13074 } 13075 13076 ev_hdr = param_tlvs->hdr; 13077 if (!ev_hdr) { 13078 wmi_err("Rx event is NULL"); 13079 return QDF_STATUS_E_INVAL; 13080 } 13081 13082 reo_params_tlv = param_tlvs->reo_params; 13083 if (!reo_params_tlv) { 13084 wmi_err("mgmt_rx_reo_params TLV is not sent by FW"); 13085 return QDF_STATUS_E_INVAL; 13086 } 13087 13088 if (!reo_params) { 13089 wmi_err("MGMT Rx REO params is NULL"); 13090 return QDF_STATUS_E_INVAL; 13091 } 13092 13093 reo_params->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host( 13094 wmi_handle, 13095 ev_hdr->pdev_id); 13096 reo_params->valid = WMI_MGMT_RX_REO_PARAM_MGMT_PKT_CTR_VALID_GET( 13097 reo_params_tlv->mgmt_pkt_ctr_link_info); 13098 reo_params->global_timestamp = reo_params_tlv->global_timestamp; 13099 reo_params->mgmt_pkt_ctr = WMI_MGMT_RX_REO_PARAM_MGMT_PKT_CTR_GET( 13100 reo_params_tlv->mgmt_pkt_ctr_link_info); 13101 reo_params->duration_us = reo_params_tlv->rx_ppdu_duration_us; 13102 reo_params->start_timestamp = reo_params->global_timestamp; 13103 reo_params->end_timestamp = reo_params->start_timestamp + 13104 reo_params->duration_us; 13105 13106 return QDF_STATUS_SUCCESS; 13107 } 13108 13109 /** 13110 * send_mgmt_rx_reo_filter_config_cmd_tlv() - Send MGMT Rx REO filter 13111 * configuration command 13112 * @wmi_handle: wmi handle 13113 * @pdev_id: pdev ID of the radio 13114 * @filter: Pointer to MGMT Rx REO filter 13115 * 13116 * Return: QDF_STATUS_SUCCESS for success or error code 13117 */ 13118 static QDF_STATUS send_mgmt_rx_reo_filter_config_cmd_tlv( 13119 wmi_unified_t wmi_handle, 13120 uint8_t pdev_id, 13121 struct mgmt_rx_reo_filter *filter) 13122 { 13123 QDF_STATUS ret; 13124 wmi_buf_t buf; 13125 wmi_mgmt_rx_reo_filter_configuration_cmd_fixed_param *cmd; 13126 size_t len = sizeof(*cmd); 13127 13128 if (!filter) { 13129 wmi_err("mgmt_rx_reo_filter is NULL"); 13130 return QDF_STATUS_E_INVAL; 13131 } 13132 13133 buf = wmi_buf_alloc(wmi_handle, len); 13134 if (!buf) { 13135 wmi_err("wmi_buf_alloc failed"); 13136 return QDF_STATUS_E_NOMEM; 13137 } 13138 13139 cmd = (wmi_mgmt_rx_reo_filter_configuration_cmd_fixed_param *) 13140 wmi_buf_data(buf); 13141 13142 WMITLV_SET_HDR(&cmd->tlv_header, 13143 WMITLV_TAG_STRUC_wmi_mgmt_rx_reo_filter_configuration_cmd_fixed_param, 13144 WMITLV_GET_STRUCT_TLVLEN(wmi_mgmt_rx_reo_filter_configuration_cmd_fixed_param)); 13145 13146 cmd->pdev_id = wmi_handle->ops->convert_host_pdev_id_to_target( 13147 wmi_handle, 13148 pdev_id); 13149 cmd->filter_low = filter->low; 13150 cmd->filter_high = filter->high; 13151 13152 wmi_mtrace(WMI_MGMT_RX_REO_FILTER_CONFIGURATION_CMDID, NO_SESSION, 0); 13153 ret = wmi_unified_cmd_send( 13154 wmi_handle, buf, len, 13155 WMI_MGMT_RX_REO_FILTER_CONFIGURATION_CMDID); 13156 13157 if (QDF_IS_STATUS_ERROR(ret)) { 13158 wmi_err("Failed to send WMI command"); 13159 wmi_buf_free(buf); 13160 } 13161 13162 return ret; 13163 } 13164 #endif 13165 13166 /** 13167 * extract_frame_pn_params_tlv() - extract PN params from event 13168 * @wmi_handle: wmi handle 13169 * @evt_buf: pointer to event buffer 13170 * @pn_params: Pointer to Frame PN params 13171 * 13172 * Return: QDF_STATUS_SUCCESS for success or error code 13173 */ 13174 static QDF_STATUS extract_frame_pn_params_tlv(wmi_unified_t wmi_handle, 13175 void *evt_buf, 13176 struct frame_pn_params *pn_params) 13177 { 13178 WMI_MGMT_RX_EVENTID_param_tlvs *param_tlvs; 13179 wmi_frame_pn_params *pn_params_tlv; 13180 13181 if (!is_service_enabled_tlv(wmi_handle, 13182 WMI_SERVICE_PN_REPLAY_CHECK_SUPPORT)) 13183 return QDF_STATUS_SUCCESS; 13184 13185 param_tlvs = evt_buf; 13186 if (!param_tlvs) { 13187 wmi_err("Got NULL point message from FW"); 13188 return QDF_STATUS_E_INVAL; 13189 } 13190 13191 if (!pn_params) { 13192 wmi_err("PN Params is NULL"); 13193 return QDF_STATUS_E_INVAL; 13194 } 13195 13196 /* PN Params TLV will be populated only if WMI_RXERR_PN error is 13197 * found by target 13198 */ 13199 pn_params_tlv = param_tlvs->pn_params; 13200 if (!pn_params_tlv) 13201 return QDF_STATUS_SUCCESS; 13202 13203 qdf_mem_copy(pn_params->curr_pn, pn_params_tlv->cur_pn, 13204 sizeof(pn_params->curr_pn)); 13205 qdf_mem_copy(pn_params->prev_pn, pn_params_tlv->prev_pn, 13206 sizeof(pn_params->prev_pn)); 13207 13208 return QDF_STATUS_SUCCESS; 13209 } 13210 13211 /** 13212 * extract_is_conn_ap_frm_param_tlv() - extract is_conn_ap_frame param from 13213 * event 13214 * @wmi_handle: wmi handle 13215 * @evt_buf: pointer to event buffer 13216 * @is_conn_ap: Pointer for is_conn_ap frame 13217 * 13218 * Return: QDF_STATUS_SUCCESS for success or error code 13219 */ 13220 static QDF_STATUS extract_is_conn_ap_frm_param_tlv( 13221 wmi_unified_t wmi_handle, 13222 void *evt_buf, 13223 struct frm_conn_ap *is_conn_ap) 13224 { 13225 WMI_MGMT_RX_EVENTID_param_tlvs *param_tlvs; 13226 wmi_is_my_mgmt_frame *my_frame_tlv; 13227 13228 param_tlvs = evt_buf; 13229 if (!param_tlvs) { 13230 wmi_err("Got NULL point message from FW"); 13231 return QDF_STATUS_E_INVAL; 13232 } 13233 13234 if (!is_conn_ap) { 13235 wmi_err(" is connected ap param is NULL"); 13236 return QDF_STATUS_E_INVAL; 13237 } 13238 13239 my_frame_tlv = param_tlvs->my_frame; 13240 if (!my_frame_tlv) 13241 return QDF_STATUS_SUCCESS; 13242 13243 is_conn_ap->mgmt_frm_sub_type = my_frame_tlv->mgmt_frm_sub_type; 13244 is_conn_ap->is_conn_ap_frm = my_frame_tlv->is_my_frame; 13245 13246 return QDF_STATUS_SUCCESS; 13247 } 13248 13249 /** 13250 * extract_vdev_roam_param_tlv() - extract vdev roam param from event 13251 * @wmi_handle: wmi handle 13252 * @evt_buf: pointer to event buffer 13253 * @param: Pointer to hold roam param 13254 * 13255 * Return: QDF_STATUS_SUCCESS for success or error code 13256 */ 13257 static QDF_STATUS extract_vdev_roam_param_tlv(wmi_unified_t wmi_handle, 13258 void *evt_buf, wmi_host_roam_event *param) 13259 { 13260 WMI_ROAM_EVENTID_param_tlvs *param_buf; 13261 wmi_roam_event_fixed_param *evt; 13262 13263 param_buf = (WMI_ROAM_EVENTID_param_tlvs *) evt_buf; 13264 if (!param_buf) { 13265 wmi_err("Invalid roam event buffer"); 13266 return QDF_STATUS_E_INVAL; 13267 } 13268 13269 evt = param_buf->fixed_param; 13270 qdf_mem_zero(param, sizeof(*param)); 13271 13272 param->vdev_id = evt->vdev_id; 13273 param->reason = evt->reason; 13274 param->rssi = evt->rssi; 13275 13276 return QDF_STATUS_SUCCESS; 13277 } 13278 13279 /** 13280 * extract_vdev_scan_ev_param_tlv() - extract vdev scan param from event 13281 * @wmi_handle: wmi handle 13282 * @evt_buf: pointer to event buffer 13283 * @param: Pointer to hold vdev scan param 13284 * 13285 * Return: QDF_STATUS_SUCCESS for success or error code 13286 */ 13287 static QDF_STATUS extract_vdev_scan_ev_param_tlv(wmi_unified_t wmi_handle, 13288 void *evt_buf, struct scan_event *param) 13289 { 13290 WMI_SCAN_EVENTID_param_tlvs *param_buf = NULL; 13291 wmi_scan_event_fixed_param *evt = NULL; 13292 13293 param_buf = (WMI_SCAN_EVENTID_param_tlvs *) evt_buf; 13294 evt = param_buf->fixed_param; 13295 13296 qdf_mem_zero(param, sizeof(*param)); 13297 13298 switch (evt->event) { 13299 case WMI_SCAN_EVENT_STARTED: 13300 param->type = SCAN_EVENT_TYPE_STARTED; 13301 break; 13302 case WMI_SCAN_EVENT_COMPLETED: 13303 param->type = SCAN_EVENT_TYPE_COMPLETED; 13304 break; 13305 case WMI_SCAN_EVENT_BSS_CHANNEL: 13306 param->type = SCAN_EVENT_TYPE_BSS_CHANNEL; 13307 break; 13308 case WMI_SCAN_EVENT_FOREIGN_CHANNEL: 13309 param->type = SCAN_EVENT_TYPE_FOREIGN_CHANNEL; 13310 break; 13311 case WMI_SCAN_EVENT_DEQUEUED: 13312 param->type = SCAN_EVENT_TYPE_DEQUEUED; 13313 break; 13314 case WMI_SCAN_EVENT_PREEMPTED: 13315 param->type = SCAN_EVENT_TYPE_PREEMPTED; 13316 break; 13317 case WMI_SCAN_EVENT_START_FAILED: 13318 param->type = SCAN_EVENT_TYPE_START_FAILED; 13319 break; 13320 case WMI_SCAN_EVENT_RESTARTED: 13321 param->type = SCAN_EVENT_TYPE_RESTARTED; 13322 break; 13323 case WMI_SCAN_EVENT_FOREIGN_CHANNEL_EXIT: 13324 param->type = SCAN_EVENT_TYPE_FOREIGN_CHANNEL_EXIT; 13325 break; 13326 case WMI_SCAN_EVENT_MAX: 13327 default: 13328 param->type = SCAN_EVENT_TYPE_MAX; 13329 break; 13330 }; 13331 13332 switch (evt->reason) { 13333 case WMI_SCAN_REASON_NONE: 13334 param->reason = SCAN_REASON_NONE; 13335 break; 13336 case WMI_SCAN_REASON_COMPLETED: 13337 param->reason = SCAN_REASON_COMPLETED; 13338 break; 13339 case WMI_SCAN_REASON_CANCELLED: 13340 param->reason = SCAN_REASON_CANCELLED; 13341 break; 13342 case WMI_SCAN_REASON_PREEMPTED: 13343 param->reason = SCAN_REASON_PREEMPTED; 13344 break; 13345 case WMI_SCAN_REASON_TIMEDOUT: 13346 param->reason = SCAN_REASON_TIMEDOUT; 13347 break; 13348 case WMI_SCAN_REASON_INTERNAL_FAILURE: 13349 param->reason = SCAN_REASON_INTERNAL_FAILURE; 13350 break; 13351 case WMI_SCAN_REASON_SUSPENDED: 13352 param->reason = SCAN_REASON_SUSPENDED; 13353 break; 13354 case WMI_SCAN_REASON_DFS_VIOLATION: 13355 param->reason = SCAN_REASON_DFS_VIOLATION; 13356 break; 13357 case WMI_SCAN_REASON_MAX: 13358 param->reason = SCAN_REASON_MAX; 13359 break; 13360 default: 13361 param->reason = SCAN_REASON_MAX; 13362 break; 13363 }; 13364 13365 param->chan_freq = evt->channel_freq; 13366 param->requester = evt->requestor; 13367 param->scan_id = evt->scan_id; 13368 param->vdev_id = evt->vdev_id; 13369 param->timestamp = evt->tsf_timestamp; 13370 13371 return QDF_STATUS_SUCCESS; 13372 } 13373 13374 #ifdef FEATURE_WLAN_SCAN_PNO 13375 /** 13376 * extract_nlo_match_ev_param_tlv() - extract NLO match param from event 13377 * @wmi_handle: pointer to WMI handle 13378 * @evt_buf: pointer to WMI event buffer 13379 * @param: pointer to scan event param for NLO match 13380 * 13381 * Return: QDF_STATUS_SUCCESS for success or error code 13382 */ 13383 static QDF_STATUS extract_nlo_match_ev_param_tlv(wmi_unified_t wmi_handle, 13384 void *evt_buf, 13385 struct scan_event *param) 13386 { 13387 WMI_NLO_MATCH_EVENTID_param_tlvs *param_buf = evt_buf; 13388 wmi_nlo_event *evt = param_buf->fixed_param; 13389 13390 qdf_mem_zero(param, sizeof(*param)); 13391 13392 param->type = SCAN_EVENT_TYPE_NLO_MATCH; 13393 param->vdev_id = evt->vdev_id; 13394 13395 return QDF_STATUS_SUCCESS; 13396 } 13397 13398 /** 13399 * extract_nlo_complete_ev_param_tlv() - extract NLO complete param from event 13400 * @wmi_handle: pointer to WMI handle 13401 * @evt_buf: pointer to WMI event buffer 13402 * @param: pointer to scan event param for NLO complete 13403 * 13404 * Return: QDF_STATUS_SUCCESS for success or error code 13405 */ 13406 static QDF_STATUS extract_nlo_complete_ev_param_tlv(wmi_unified_t wmi_handle, 13407 void *evt_buf, 13408 struct scan_event *param) 13409 { 13410 WMI_NLO_SCAN_COMPLETE_EVENTID_param_tlvs *param_buf = evt_buf; 13411 wmi_nlo_event *evt = param_buf->fixed_param; 13412 13413 qdf_mem_zero(param, sizeof(*param)); 13414 13415 param->type = SCAN_EVENT_TYPE_NLO_COMPLETE; 13416 param->vdev_id = evt->vdev_id; 13417 13418 return QDF_STATUS_SUCCESS; 13419 } 13420 #endif 13421 13422 /** 13423 * extract_unit_test_tlv() - extract unit test data 13424 * @wmi_handle: wmi handle 13425 * @evt_buf: pointer to event buffer 13426 * @unit_test: pointer to hold unit test data 13427 * @maxspace: Amount of space in evt_buf 13428 * 13429 * Return: QDF_STATUS_SUCCESS for success or error code 13430 */ 13431 static QDF_STATUS extract_unit_test_tlv(wmi_unified_t wmi_handle, 13432 void *evt_buf, wmi_unit_test_event *unit_test, uint32_t maxspace) 13433 { 13434 WMI_UNIT_TEST_EVENTID_param_tlvs *param_buf; 13435 wmi_unit_test_event_fixed_param *ev_param; 13436 uint32_t num_bufp; 13437 uint32_t copy_size; 13438 uint8_t *bufp; 13439 13440 param_buf = (WMI_UNIT_TEST_EVENTID_param_tlvs *) evt_buf; 13441 ev_param = param_buf->fixed_param; 13442 bufp = param_buf->bufp; 13443 num_bufp = param_buf->num_bufp; 13444 unit_test->vdev_id = ev_param->vdev_id; 13445 unit_test->module_id = ev_param->module_id; 13446 unit_test->diag_token = ev_param->diag_token; 13447 unit_test->flag = ev_param->flag; 13448 unit_test->payload_len = ev_param->payload_len; 13449 wmi_debug("vdev_id:%d mod_id:%d diag_token:%d flag:%d", 13450 ev_param->vdev_id, 13451 ev_param->module_id, 13452 ev_param->diag_token, 13453 ev_param->flag); 13454 wmi_debug("Unit-test data given below %d", num_bufp); 13455 qdf_trace_hex_dump(QDF_MODULE_ID_WMI, QDF_TRACE_LEVEL_DEBUG, 13456 bufp, num_bufp); 13457 copy_size = (num_bufp < maxspace) ? num_bufp : maxspace; 13458 qdf_mem_copy(unit_test->buffer, bufp, copy_size); 13459 unit_test->buffer_len = copy_size; 13460 13461 return QDF_STATUS_SUCCESS; 13462 } 13463 13464 /** 13465 * extract_pdev_ext_stats_tlv() - extract extended pdev stats from event 13466 * @wmi_handle: wmi handle 13467 * @evt_buf: pointer to event buffer 13468 * @index: Index into extended pdev stats 13469 * @pdev_ext_stats: Pointer to hold extended pdev stats 13470 * 13471 * Return: QDF_STATUS_SUCCESS for success or error code 13472 */ 13473 static QDF_STATUS extract_pdev_ext_stats_tlv(wmi_unified_t wmi_handle, 13474 void *evt_buf, uint32_t index, wmi_host_pdev_ext_stats *pdev_ext_stats) 13475 { 13476 WMI_UPDATE_STATS_EVENTID_param_tlvs *param_buf; 13477 wmi_pdev_extd_stats *ev; 13478 13479 param_buf = evt_buf; 13480 if (!param_buf) 13481 return QDF_STATUS_E_FAILURE; 13482 13483 if (!param_buf->pdev_extd_stats) 13484 return QDF_STATUS_E_FAILURE; 13485 13486 ev = param_buf->pdev_extd_stats + index; 13487 13488 pdev_ext_stats->pdev_id = 13489 wmi_handle->ops->convert_target_pdev_id_to_host( 13490 wmi_handle, 13491 ev->pdev_id); 13492 pdev_ext_stats->my_rx_count = ev->my_rx_count; 13493 pdev_ext_stats->rx_matched_11ax_msdu_cnt = ev->rx_matched_11ax_msdu_cnt; 13494 pdev_ext_stats->rx_other_11ax_msdu_cnt = ev->rx_other_11ax_msdu_cnt; 13495 13496 return QDF_STATUS_SUCCESS; 13497 } 13498 13499 /** 13500 * extract_bcn_stats_tlv() - extract bcn stats from event 13501 * @wmi_handle: wmi handle 13502 * @evt_buf: pointer to event buffer 13503 * @index: Index into vdev stats 13504 * @bcn_stats: Pointer to hold bcn stats 13505 * 13506 * Return: QDF_STATUS_SUCCESS for success or error code 13507 */ 13508 static QDF_STATUS extract_bcn_stats_tlv(wmi_unified_t wmi_handle, 13509 void *evt_buf, uint32_t index, wmi_host_bcn_stats *bcn_stats) 13510 { 13511 WMI_UPDATE_STATS_EVENTID_param_tlvs *param_buf; 13512 wmi_stats_event_fixed_param *ev_param; 13513 uint8_t *data; 13514 13515 param_buf = (WMI_UPDATE_STATS_EVENTID_param_tlvs *) evt_buf; 13516 ev_param = (wmi_stats_event_fixed_param *) param_buf->fixed_param; 13517 data = (uint8_t *) param_buf->data; 13518 13519 if (index < ev_param->num_bcn_stats) { 13520 wmi_bcn_stats *ev = (wmi_bcn_stats *) ((data) + 13521 ((ev_param->num_pdev_stats) * sizeof(wmi_pdev_stats)) + 13522 ((ev_param->num_vdev_stats) * sizeof(wmi_vdev_stats)) + 13523 ((ev_param->num_peer_stats) * sizeof(wmi_peer_stats)) + 13524 ((ev_param->num_chan_stats) * sizeof(wmi_chan_stats)) + 13525 ((ev_param->num_mib_stats) * sizeof(wmi_mib_stats)) + 13526 (index * sizeof(wmi_bcn_stats))); 13527 13528 bcn_stats->vdev_id = ev->vdev_id; 13529 bcn_stats->tx_bcn_succ_cnt = ev->tx_bcn_succ_cnt; 13530 bcn_stats->tx_bcn_outage_cnt = ev->tx_bcn_outage_cnt; 13531 } 13532 13533 return QDF_STATUS_SUCCESS; 13534 } 13535 13536 /** 13537 * extract_vdev_prb_fils_stats_tlv() - extract vdev probe and fils 13538 * stats from event 13539 * @wmi_handle: wmi handle 13540 * @evt_buf: pointer to event buffer 13541 * @index: Index into vdev stats 13542 * @vdev_stats: Pointer to hold vdev probe and fils stats 13543 * 13544 * Return: QDF_STATUS_SUCCESS for success or error code 13545 */ 13546 static QDF_STATUS 13547 extract_vdev_prb_fils_stats_tlv(wmi_unified_t wmi_handle, 13548 void *evt_buf, uint32_t index, 13549 struct wmi_host_vdev_prb_fils_stats *vdev_stats) 13550 { 13551 WMI_UPDATE_STATS_EVENTID_param_tlvs *param_buf; 13552 wmi_vdev_extd_stats *ev; 13553 13554 param_buf = (WMI_UPDATE_STATS_EVENTID_param_tlvs *)evt_buf; 13555 13556 if (param_buf->vdev_extd_stats) { 13557 ev = (wmi_vdev_extd_stats *)(param_buf->vdev_extd_stats + 13558 index); 13559 vdev_stats->vdev_id = ev->vdev_id; 13560 vdev_stats->fd_succ_cnt = ev->fd_succ_cnt; 13561 vdev_stats->fd_fail_cnt = ev->fd_fail_cnt; 13562 vdev_stats->unsolicited_prb_succ_cnt = 13563 ev->unsolicited_prb_succ_cnt; 13564 vdev_stats->unsolicited_prb_fail_cnt = 13565 ev->unsolicited_prb_fail_cnt; 13566 wmi_debug("vdev: %d, fd_s: %d, fd_f: %d, prb_s: %d, prb_f: %d", 13567 ev->vdev_id, ev->fd_succ_cnt, ev->fd_fail_cnt, 13568 ev->unsolicited_prb_succ_cnt, 13569 ev->unsolicited_prb_fail_cnt); 13570 } 13571 13572 return QDF_STATUS_SUCCESS; 13573 } 13574 13575 /** 13576 * extract_bcnflt_stats_tlv() - extract bcn fault stats from event 13577 * @wmi_handle: wmi handle 13578 * @evt_buf: pointer to event buffer 13579 * @index: Index into bcn fault stats 13580 * @bcnflt_stats: Pointer to hold bcn fault stats 13581 * 13582 * Return: QDF_STATUS_SUCCESS for success or error code 13583 */ 13584 static QDF_STATUS extract_bcnflt_stats_tlv(wmi_unified_t wmi_handle, 13585 void *evt_buf, uint32_t index, wmi_host_bcnflt_stats *bcnflt_stats) 13586 { 13587 return QDF_STATUS_SUCCESS; 13588 } 13589 13590 /** 13591 * extract_chan_stats_tlv() - extract chan stats from event 13592 * @wmi_handle: wmi handle 13593 * @evt_buf: pointer to event buffer 13594 * @index: Index into chan stats 13595 * @chan_stats: Pointer to hold chan stats 13596 * 13597 * Return: QDF_STATUS_SUCCESS for success or error code 13598 */ 13599 static QDF_STATUS extract_chan_stats_tlv(wmi_unified_t wmi_handle, 13600 void *evt_buf, uint32_t index, wmi_host_chan_stats *chan_stats) 13601 { 13602 WMI_UPDATE_STATS_EVENTID_param_tlvs *param_buf; 13603 wmi_stats_event_fixed_param *ev_param; 13604 uint8_t *data; 13605 13606 param_buf = (WMI_UPDATE_STATS_EVENTID_param_tlvs *) evt_buf; 13607 ev_param = (wmi_stats_event_fixed_param *) param_buf->fixed_param; 13608 data = (uint8_t *) param_buf->data; 13609 13610 if (index < ev_param->num_chan_stats) { 13611 wmi_chan_stats *ev = (wmi_chan_stats *) ((data) + 13612 ((ev_param->num_pdev_stats) * sizeof(wmi_pdev_stats)) + 13613 ((ev_param->num_vdev_stats) * sizeof(wmi_vdev_stats)) + 13614 ((ev_param->num_peer_stats) * sizeof(wmi_peer_stats)) + 13615 (index * sizeof(wmi_chan_stats))); 13616 13617 13618 /* Non-TLV doesn't have num_chan_stats */ 13619 chan_stats->chan_mhz = ev->chan_mhz; 13620 chan_stats->sampling_period_us = ev->sampling_period_us; 13621 chan_stats->rx_clear_count = ev->rx_clear_count; 13622 chan_stats->tx_duration_us = ev->tx_duration_us; 13623 chan_stats->rx_duration_us = ev->rx_duration_us; 13624 } 13625 13626 return QDF_STATUS_SUCCESS; 13627 } 13628 13629 /** 13630 * extract_profile_ctx_tlv() - extract profile context from event 13631 * @wmi_handle: wmi handle 13632 * @evt_buf: pointer to event buffer 13633 * @profile_ctx: Pointer to hold profile context 13634 * 13635 * Return: QDF_STATUS_SUCCESS for success or error code 13636 */ 13637 static QDF_STATUS extract_profile_ctx_tlv(wmi_unified_t wmi_handle, 13638 void *evt_buf, wmi_host_wlan_profile_ctx_t *profile_ctx) 13639 { 13640 WMI_WLAN_PROFILE_DATA_EVENTID_param_tlvs *param_buf; 13641 13642 wmi_wlan_profile_ctx_t *ev; 13643 13644 param_buf = (WMI_WLAN_PROFILE_DATA_EVENTID_param_tlvs *)evt_buf; 13645 if (!param_buf) { 13646 wmi_err("Invalid profile data event buf"); 13647 return QDF_STATUS_E_INVAL; 13648 } 13649 13650 ev = param_buf->profile_ctx; 13651 13652 profile_ctx->tot = ev->tot; 13653 profile_ctx->tx_msdu_cnt = ev->tx_msdu_cnt; 13654 profile_ctx->tx_mpdu_cnt = ev->tx_mpdu_cnt; 13655 profile_ctx->tx_ppdu_cnt = ev->tx_ppdu_cnt; 13656 profile_ctx->rx_msdu_cnt = ev->rx_msdu_cnt; 13657 profile_ctx->rx_mpdu_cnt = ev->rx_mpdu_cnt; 13658 profile_ctx->bin_count = ev->bin_count; 13659 13660 return QDF_STATUS_SUCCESS; 13661 } 13662 13663 /** 13664 * extract_profile_data_tlv() - extract profile data from event 13665 * @wmi_handle: wmi handle 13666 * @evt_buf: pointer to event buffer 13667 * @idx: profile stats index to extract 13668 * @profile_data: Pointer to hold profile data 13669 * 13670 * Return: QDF_STATUS_SUCCESS for success or error code 13671 */ 13672 static QDF_STATUS extract_profile_data_tlv(wmi_unified_t wmi_handle, 13673 void *evt_buf, uint8_t idx, wmi_host_wlan_profile_t *profile_data) 13674 { 13675 WMI_WLAN_PROFILE_DATA_EVENTID_param_tlvs *param_buf; 13676 wmi_wlan_profile_t *ev; 13677 13678 param_buf = (WMI_WLAN_PROFILE_DATA_EVENTID_param_tlvs *)evt_buf; 13679 if (!param_buf) { 13680 wmi_err("Invalid profile data event buf"); 13681 return QDF_STATUS_E_INVAL; 13682 } 13683 13684 ev = ¶m_buf->profile_data[idx]; 13685 profile_data->id = ev->id; 13686 profile_data->cnt = ev->cnt; 13687 profile_data->tot = ev->tot; 13688 profile_data->min = ev->min; 13689 profile_data->max = ev->max; 13690 profile_data->hist_intvl = ev->hist_intvl; 13691 qdf_mem_copy(profile_data->hist, ev->hist, sizeof(profile_data->hist)); 13692 13693 return QDF_STATUS_SUCCESS; 13694 } 13695 13696 /** 13697 * extract_pdev_utf_event_tlv() - extract UTF data info from event 13698 * @wmi_handle: WMI handle 13699 * @evt_buf: Pointer to event buffer 13700 * @event: Pointer to hold data 13701 * 13702 * Return: QDF_STATUS_SUCCESS for success or error code 13703 */ 13704 static QDF_STATUS extract_pdev_utf_event_tlv(wmi_unified_t wmi_handle, 13705 uint8_t *evt_buf, 13706 struct wmi_host_pdev_utf_event *event) 13707 { 13708 WMI_PDEV_UTF_EVENTID_param_tlvs *param_buf; 13709 struct wmi_host_utf_seg_header_info *seg_hdr; 13710 13711 param_buf = (WMI_PDEV_UTF_EVENTID_param_tlvs *)evt_buf; 13712 event->data = param_buf->data; 13713 event->datalen = param_buf->num_data; 13714 13715 if (event->datalen < sizeof(struct wmi_host_utf_seg_header_info)) { 13716 wmi_err("Invalid datalen: %d", event->datalen); 13717 return QDF_STATUS_E_INVAL; 13718 } 13719 seg_hdr = (struct wmi_host_utf_seg_header_info *)param_buf->data; 13720 /* Set pdev_id=1 until FW adds support to include pdev_id */ 13721 event->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host( 13722 wmi_handle, 13723 seg_hdr->pdev_id); 13724 13725 return QDF_STATUS_SUCCESS; 13726 } 13727 13728 #ifdef WLAN_SUPPORT_RF_CHARACTERIZATION 13729 static QDF_STATUS extract_num_rf_characterization_entries_tlv(wmi_unified_t wmi_handle, 13730 uint8_t *event, 13731 uint32_t *num_rf_characterization_entries) 13732 { 13733 WMI_CHAN_RF_CHARACTERIZATION_INFO_EVENTID_param_tlvs *param_buf; 13734 13735 param_buf = (WMI_CHAN_RF_CHARACTERIZATION_INFO_EVENTID_param_tlvs *)event; 13736 if (!param_buf) 13737 return QDF_STATUS_E_INVAL; 13738 13739 *num_rf_characterization_entries = 13740 param_buf->num_wmi_chan_rf_characterization_info; 13741 13742 return QDF_STATUS_SUCCESS; 13743 } 13744 13745 static QDF_STATUS extract_rf_characterization_entries_tlv(wmi_unified_t wmi_handle, 13746 uint8_t *event, 13747 uint32_t num_rf_characterization_entries, 13748 struct wmi_host_rf_characterization_event_param *rf_characterization_entries) 13749 { 13750 WMI_CHAN_RF_CHARACTERIZATION_INFO_EVENTID_param_tlvs *param_buf; 13751 WMI_CHAN_RF_CHARACTERIZATION_INFO *wmi_rf_characterization_entry; 13752 uint8_t ix; 13753 13754 param_buf = (WMI_CHAN_RF_CHARACTERIZATION_INFO_EVENTID_param_tlvs *)event; 13755 if (!param_buf) 13756 return QDF_STATUS_E_INVAL; 13757 13758 wmi_rf_characterization_entry = 13759 param_buf->wmi_chan_rf_characterization_info; 13760 if (!wmi_rf_characterization_entry) 13761 return QDF_STATUS_E_INVAL; 13762 13763 /* 13764 * Using num_wmi_chan_rf_characterization instead of param_buf value 13765 * since memory for rf_characterization_entries was allocated using 13766 * the former. 13767 */ 13768 for (ix = 0; ix < num_rf_characterization_entries; ix++) { 13769 rf_characterization_entries[ix].freq = 13770 WMI_CHAN_RF_CHARACTERIZATION_FREQ_GET( 13771 &wmi_rf_characterization_entry[ix]); 13772 13773 rf_characterization_entries[ix].bw = 13774 WMI_CHAN_RF_CHARACTERIZATION_BW_GET( 13775 &wmi_rf_characterization_entry[ix]); 13776 13777 rf_characterization_entries[ix].chan_metric = 13778 WMI_CHAN_RF_CHARACTERIZATION_CHAN_METRIC_GET( 13779 &wmi_rf_characterization_entry[ix]); 13780 13781 wmi_nofl_debug("rf_characterization_entries[%u]: freq: %u, " 13782 "bw: %u, chan_metric: %u", 13783 ix, rf_characterization_entries[ix].freq, 13784 rf_characterization_entries[ix].bw, 13785 rf_characterization_entries[ix].chan_metric); 13786 } 13787 13788 return QDF_STATUS_SUCCESS; 13789 } 13790 #endif 13791 13792 #ifdef WLAN_FEATURE_11BE 13793 static void 13794 extract_11be_chainmask(struct wlan_psoc_host_chainmask_capabilities *cap, 13795 WMI_MAC_PHY_CHAINMASK_CAPABILITY *chainmask_caps) 13796 { 13797 cap->supports_chan_width_320 = 13798 WMI_SUPPORT_CHAN_WIDTH_320_GET(chainmask_caps->supported_flags); 13799 cap->supports_aDFS_320 = 13800 WMI_SUPPORT_ADFS_320_GET(chainmask_caps->supported_flags); 13801 } 13802 #else 13803 static void 13804 extract_11be_chainmask(struct wlan_psoc_host_chainmask_capabilities *cap, 13805 WMI_MAC_PHY_CHAINMASK_CAPABILITY *chainmask_caps) 13806 { 13807 } 13808 #endif /* WLAN_FEATURE_11BE */ 13809 13810 /** 13811 * extract_chainmask_tables_tlv() - extract chain mask tables from event 13812 * @wmi_handle: wmi handle 13813 * @event: pointer to event buffer 13814 * @chainmask_table: Pointer to hold extracted chainmask tables 13815 * 13816 * Return: QDF_STATUS_SUCCESS for success or error code 13817 */ 13818 static QDF_STATUS extract_chainmask_tables_tlv(wmi_unified_t wmi_handle, 13819 uint8_t *event, struct wlan_psoc_host_chainmask_table *chainmask_table) 13820 { 13821 WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *param_buf; 13822 WMI_MAC_PHY_CHAINMASK_CAPABILITY *chainmask_caps; 13823 WMI_SOC_MAC_PHY_HW_MODE_CAPS *hw_caps; 13824 uint8_t i = 0, j = 0; 13825 uint32_t num_mac_phy_chainmask_caps = 0; 13826 13827 param_buf = (WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *) event; 13828 if (!param_buf) 13829 return QDF_STATUS_E_INVAL; 13830 13831 hw_caps = param_buf->soc_hw_mode_caps; 13832 if (!hw_caps) 13833 return QDF_STATUS_E_INVAL; 13834 13835 if ((!hw_caps->num_chainmask_tables) || 13836 (hw_caps->num_chainmask_tables > PSOC_MAX_CHAINMASK_TABLES) || 13837 (hw_caps->num_chainmask_tables > 13838 param_buf->num_mac_phy_chainmask_combo)) 13839 return QDF_STATUS_E_INVAL; 13840 13841 chainmask_caps = param_buf->mac_phy_chainmask_caps; 13842 13843 if (!chainmask_caps) 13844 return QDF_STATUS_E_INVAL; 13845 13846 for (i = 0; i < hw_caps->num_chainmask_tables; i++) { 13847 if (chainmask_table[i].num_valid_chainmasks > 13848 (UINT_MAX - num_mac_phy_chainmask_caps)) { 13849 wmi_err_rl("integer overflow, num_mac_phy_chainmask_caps:%d, i:%d, um_valid_chainmasks:%d", 13850 num_mac_phy_chainmask_caps, i, 13851 chainmask_table[i].num_valid_chainmasks); 13852 return QDF_STATUS_E_INVAL; 13853 } 13854 num_mac_phy_chainmask_caps += 13855 chainmask_table[i].num_valid_chainmasks; 13856 } 13857 13858 if (num_mac_phy_chainmask_caps > 13859 param_buf->num_mac_phy_chainmask_caps) { 13860 wmi_err_rl("invalid chainmask caps num, num_mac_phy_chainmask_caps:%d, param_buf->num_mac_phy_chainmask_caps:%d", 13861 num_mac_phy_chainmask_caps, 13862 param_buf->num_mac_phy_chainmask_caps); 13863 return QDF_STATUS_E_INVAL; 13864 } 13865 13866 for (i = 0; i < hw_caps->num_chainmask_tables; i++) { 13867 13868 wmi_nofl_debug("Dumping chain mask combo data for table : %d", 13869 i); 13870 for (j = 0; j < chainmask_table[i].num_valid_chainmasks; j++) { 13871 13872 chainmask_table[i].cap_list[j].chainmask = 13873 chainmask_caps->chainmask; 13874 13875 chainmask_table[i].cap_list[j].supports_chan_width_20 = 13876 WMI_SUPPORT_CHAN_WIDTH_20_GET(chainmask_caps->supported_flags); 13877 13878 chainmask_table[i].cap_list[j].supports_chan_width_40 = 13879 WMI_SUPPORT_CHAN_WIDTH_40_GET(chainmask_caps->supported_flags); 13880 13881 chainmask_table[i].cap_list[j].supports_chan_width_80 = 13882 WMI_SUPPORT_CHAN_WIDTH_80_GET(chainmask_caps->supported_flags); 13883 13884 chainmask_table[i].cap_list[j].supports_chan_width_160 = 13885 WMI_SUPPORT_CHAN_WIDTH_160_GET(chainmask_caps->supported_flags); 13886 13887 chainmask_table[i].cap_list[j].supports_chan_width_80P80 = 13888 WMI_SUPPORT_CHAN_WIDTH_80P80_GET(chainmask_caps->supported_flags); 13889 13890 chainmask_table[i].cap_list[j].chain_mask_2G = 13891 WMI_SUPPORT_CHAIN_MASK_2G_GET(chainmask_caps->supported_flags); 13892 13893 chainmask_table[i].cap_list[j].chain_mask_5G = 13894 WMI_SUPPORT_CHAIN_MASK_5G_GET(chainmask_caps->supported_flags); 13895 13896 chainmask_table[i].cap_list[j].chain_mask_tx = 13897 WMI_SUPPORT_CHAIN_MASK_TX_GET(chainmask_caps->supported_flags); 13898 13899 chainmask_table[i].cap_list[j].chain_mask_rx = 13900 WMI_SUPPORT_CHAIN_MASK_RX_GET(chainmask_caps->supported_flags); 13901 13902 chainmask_table[i].cap_list[j].supports_aDFS = 13903 WMI_SUPPORT_CHAIN_MASK_ADFS_GET(chainmask_caps->supported_flags); 13904 13905 chainmask_table[i].cap_list[j].supports_aSpectral = 13906 WMI_SUPPORT_AGILE_SPECTRAL_GET(chainmask_caps->supported_flags); 13907 13908 chainmask_table[i].cap_list[j].supports_aSpectral_160 = 13909 WMI_SUPPORT_AGILE_SPECTRAL_160_GET(chainmask_caps->supported_flags); 13910 13911 chainmask_table[i].cap_list[j].supports_aDFS_160 = 13912 WMI_SUPPORT_ADFS_160_GET(chainmask_caps->supported_flags); 13913 13914 extract_11be_chainmask(&chainmask_table[i].cap_list[j], 13915 chainmask_caps); 13916 13917 wmi_nofl_debug("supported_flags: 0x%08x chainmasks: 0x%08x", 13918 chainmask_caps->supported_flags, 13919 chainmask_caps->chainmask); 13920 chainmask_caps++; 13921 } 13922 } 13923 13924 return QDF_STATUS_SUCCESS; 13925 } 13926 13927 /** 13928 * extract_service_ready_ext_tlv() - extract basic extended service ready params 13929 * from event 13930 * @wmi_handle: wmi handle 13931 * @event: pointer to event buffer 13932 * @param: Pointer to hold evt buf 13933 * 13934 * Return: QDF_STATUS_SUCCESS for success or error code 13935 */ 13936 static QDF_STATUS extract_service_ready_ext_tlv(wmi_unified_t wmi_handle, 13937 uint8_t *event, struct wlan_psoc_host_service_ext_param *param) 13938 { 13939 WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *param_buf; 13940 wmi_service_ready_ext_event_fixed_param *ev; 13941 WMI_SOC_MAC_PHY_HW_MODE_CAPS *hw_caps; 13942 WMI_SOC_HAL_REG_CAPABILITIES *reg_caps; 13943 WMI_MAC_PHY_CHAINMASK_COMBO *chain_mask_combo; 13944 uint8_t i = 0; 13945 13946 param_buf = (WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *) event; 13947 if (!param_buf) 13948 return QDF_STATUS_E_INVAL; 13949 13950 ev = param_buf->fixed_param; 13951 if (!ev) 13952 return QDF_STATUS_E_INVAL; 13953 13954 /* Move this to host based bitmap */ 13955 param->default_conc_scan_config_bits = 13956 ev->default_conc_scan_config_bits; 13957 param->default_fw_config_bits = ev->default_fw_config_bits; 13958 param->he_cap_info = ev->he_cap_info; 13959 param->mpdu_density = ev->mpdu_density; 13960 param->max_bssid_rx_filters = ev->max_bssid_rx_filters; 13961 param->fw_build_vers_ext = ev->fw_build_vers_ext; 13962 param->num_dbr_ring_caps = param_buf->num_dma_ring_caps; 13963 param->num_bin_scaling_params = param_buf->num_wmi_bin_scaling_params; 13964 param->max_bssid_indicator = ev->max_bssid_indicator; 13965 qdf_mem_copy(¶m->ppet, &ev->ppet, sizeof(param->ppet)); 13966 13967 hw_caps = param_buf->soc_hw_mode_caps; 13968 if (hw_caps) 13969 param->num_hw_modes = hw_caps->num_hw_modes; 13970 else 13971 param->num_hw_modes = 0; 13972 13973 reg_caps = param_buf->soc_hal_reg_caps; 13974 if (reg_caps) 13975 param->num_phy = reg_caps->num_phy; 13976 else 13977 param->num_phy = 0; 13978 13979 if (hw_caps) { 13980 param->num_chainmask_tables = hw_caps->num_chainmask_tables; 13981 wmi_nofl_debug("Num chain mask tables: %d", 13982 hw_caps->num_chainmask_tables); 13983 } else 13984 param->num_chainmask_tables = 0; 13985 13986 if (param->num_chainmask_tables > PSOC_MAX_CHAINMASK_TABLES || 13987 param->num_chainmask_tables > 13988 param_buf->num_mac_phy_chainmask_combo) { 13989 wmi_err_rl("num_chainmask_tables is OOB: %u", 13990 param->num_chainmask_tables); 13991 return QDF_STATUS_E_INVAL; 13992 } 13993 chain_mask_combo = param_buf->mac_phy_chainmask_combo; 13994 13995 if (!chain_mask_combo) 13996 return QDF_STATUS_SUCCESS; 13997 13998 wmi_nofl_debug("Dumping chain mask combo data"); 13999 14000 for (i = 0; i < param->num_chainmask_tables; i++) { 14001 14002 wmi_nofl_debug("table_id : %d Num valid chainmasks: %d", 14003 chain_mask_combo->chainmask_table_id, 14004 chain_mask_combo->num_valid_chainmask); 14005 14006 param->chainmask_table[i].table_id = 14007 chain_mask_combo->chainmask_table_id; 14008 param->chainmask_table[i].num_valid_chainmasks = 14009 chain_mask_combo->num_valid_chainmask; 14010 chain_mask_combo++; 14011 } 14012 wmi_nofl_debug("chain mask combo end"); 14013 14014 return QDF_STATUS_SUCCESS; 14015 } 14016 14017 #if defined(CONFIG_AFC_SUPPORT) 14018 /** 14019 * extract_svc_rdy_ext2_afc_tlv() - extract service ready ext2 afc deployment 14020 * type from event 14021 * @ev: pointer to event fixed param 14022 * @param: Pointer to hold the params 14023 * 14024 * Return: void 14025 */ 14026 static void 14027 extract_svc_rdy_ext2_afc_tlv(wmi_service_ready_ext2_event_fixed_param *ev, 14028 struct wlan_psoc_host_service_ext2_param *param) 14029 { 14030 WMI_AFC_FEATURE_6G_DEPLOYMENT_TYPE tgt_afc_dev_type; 14031 enum reg_afc_dev_deploy_type reg_afc_dev_type; 14032 14033 tgt_afc_dev_type = ev->afc_deployment_type; 14034 switch (tgt_afc_dev_type) { 14035 case WMI_AFC_FEATURE_6G_DEPLOYMENT_UNSPECIFIED: 14036 reg_afc_dev_type = AFC_DEPLOYMENT_INDOOR; 14037 break; 14038 case WMI_AFC_FEATURE_6G_DEPLOYMENT_INDOOR_ONLY: 14039 reg_afc_dev_type = AFC_DEPLOYMENT_INDOOR; 14040 break; 14041 case WMI_AFC_FEATURE_6G_DEPLOYMENT_OUTDOOR_ONLY: 14042 reg_afc_dev_type = AFC_DEPLOYMENT_OUTDOOR; 14043 break; 14044 default: 14045 wmi_err("invalid afc deployment %d", tgt_afc_dev_type); 14046 reg_afc_dev_type = AFC_DEPLOYMENT_UNKNOWN; 14047 break; 14048 } 14049 param->afc_dev_type = reg_afc_dev_type; 14050 14051 wmi_debug("afc dev type:%d", ev->afc_deployment_type); 14052 } 14053 #else 14054 static inline void 14055 extract_svc_rdy_ext2_afc_tlv(wmi_service_ready_ext2_event_fixed_param *ev, 14056 struct wlan_psoc_host_service_ext2_param *param) 14057 { 14058 } 14059 #endif 14060 14061 /** 14062 * extract_ul_mumimo_support() - extract UL-MUMIMO capability from target cap 14063 * @param: Pointer to hold the params 14064 * 14065 * Return: Void 14066 */ 14067 static void 14068 extract_ul_mumimo_support(struct wlan_psoc_host_service_ext2_param *param) 14069 { 14070 uint32_t tgt_cap = param->target_cap_flags; 14071 14072 param->ul_mumimo_rx_2g = WMI_TARGET_CAP_UL_MU_MIMO_RX_SUPPORT_2GHZ_GET(tgt_cap); 14073 param->ul_mumimo_rx_5g = WMI_TARGET_CAP_UL_MU_MIMO_RX_SUPPORT_5GHZ_GET(tgt_cap); 14074 param->ul_mumimo_rx_6g = WMI_TARGET_CAP_UL_MU_MIMO_RX_SUPPORT_6GHZ_GET(tgt_cap); 14075 param->ul_mumimo_tx_2g = WMI_TARGET_CAP_UL_MU_MIMO_TX_SUPPORT_2GHZ_GET(tgt_cap); 14076 param->ul_mumimo_tx_5g = WMI_TARGET_CAP_UL_MU_MIMO_TX_SUPPORT_5GHZ_GET(tgt_cap); 14077 param->ul_mumimo_tx_6g = WMI_TARGET_CAP_UL_MU_MIMO_TX_SUPPORT_6GHZ_GET(tgt_cap); 14078 } 14079 14080 /** 14081 * extract_hw_bdf_status() - extract service ready ext2 BDF hw status 14082 * type from event 14083 * @ev: pointer to event fixed param 14084 * 14085 * Return: void 14086 */ 14087 14088 static void 14089 extract_hw_bdf_status(wmi_service_ready_ext2_event_fixed_param *ev) 14090 { 14091 uint8_t hw_bdf_s; 14092 14093 hw_bdf_s = ev->hw_bd_status; 14094 switch (hw_bdf_s) { 14095 case WMI_BDF_VERSION_CHECK_DISABLED: 14096 wmi_info("BDF VER is %d, FW and BDF ver check skipped", 14097 hw_bdf_s); 14098 break; 14099 case WMI_BDF_VERSION_CHECK_GOOD: 14100 wmi_info("BDF VER is %d, FW and BDF ver check good", 14101 hw_bdf_s); 14102 break; 14103 case WMI_BDF_VERSION_TEMPLATE_TOO_OLD: 14104 wmi_info("BDF VER is %d, BDF ver is older than the oldest version supported by FW", 14105 hw_bdf_s); 14106 break; 14107 case WMI_BDF_VERSION_TEMPLATE_TOO_NEW: 14108 wmi_info("BDF VER is %d, BDF ver is newer than the newest version supported by FW", 14109 hw_bdf_s); 14110 break; 14111 case WMI_BDF_VERSION_FW_TOO_OLD: 14112 wmi_info("BDF VER is %d, FW ver is older than the major version supported by BDF", 14113 hw_bdf_s); 14114 break; 14115 case WMI_BDF_VERSION_FW_TOO_NEW: 14116 wmi_info("BDF VER is %d, FW ver is newer than the minor version supported by BDF", 14117 hw_bdf_s); 14118 break; 14119 default: 14120 wmi_info("unknown BDF VER %d", hw_bdf_s); 14121 break; 14122 } 14123 } 14124 14125 /** 14126 * extract_service_ready_ext2_tlv() - extract service ready ext2 params from 14127 * event 14128 * @wmi_handle: wmi handle 14129 * @event: pointer to event buffer 14130 * @param: Pointer to hold the params 14131 * 14132 * Return: QDF_STATUS_SUCCESS for success or error code 14133 */ 14134 static QDF_STATUS 14135 extract_service_ready_ext2_tlv(wmi_unified_t wmi_handle, uint8_t *event, 14136 struct wlan_psoc_host_service_ext2_param *param) 14137 { 14138 WMI_SERVICE_READY_EXT2_EVENTID_param_tlvs *param_buf; 14139 wmi_service_ready_ext2_event_fixed_param *ev; 14140 14141 param_buf = (WMI_SERVICE_READY_EXT2_EVENTID_param_tlvs *)event; 14142 if (!param_buf) 14143 return QDF_STATUS_E_INVAL; 14144 14145 ev = param_buf->fixed_param; 14146 if (!ev) 14147 return QDF_STATUS_E_INVAL; 14148 14149 param->reg_db_version_major = 14150 WMI_REG_DB_VERSION_MAJOR_GET( 14151 ev->reg_db_version); 14152 param->reg_db_version_minor = 14153 WMI_REG_DB_VERSION_MINOR_GET( 14154 ev->reg_db_version); 14155 param->bdf_reg_db_version_major = 14156 WMI_BDF_REG_DB_VERSION_MAJOR_GET( 14157 ev->reg_db_version); 14158 param->bdf_reg_db_version_minor = 14159 WMI_BDF_REG_DB_VERSION_MINOR_GET( 14160 ev->reg_db_version); 14161 param->chwidth_num_peer_caps = ev->chwidth_num_peer_caps; 14162 14163 param->num_dbr_ring_caps = param_buf->num_dma_ring_caps; 14164 14165 if (param_buf->nan_cap) 14166 param->max_ndp_sessions = 14167 param_buf->nan_cap->max_ndp_sessions; 14168 else 14169 param->max_ndp_sessions = 0; 14170 14171 param->preamble_puncture_bw_cap = ev->preamble_puncture_bw; 14172 param->num_scan_radio_caps = param_buf->num_wmi_scan_radio_caps; 14173 param->max_users_dl_ofdma = WMI_MAX_USER_PER_PPDU_DL_OFDMA_GET( 14174 ev->max_user_per_ppdu_ofdma); 14175 param->max_users_ul_ofdma = WMI_MAX_USER_PER_PPDU_UL_OFDMA_GET( 14176 ev->max_user_per_ppdu_ofdma); 14177 param->max_users_dl_mumimo = WMI_MAX_USER_PER_PPDU_DL_MUMIMO_GET( 14178 ev->max_user_per_ppdu_mumimo); 14179 param->max_users_ul_mumimo = WMI_MAX_USER_PER_PPDU_UL_MUMIMO_GET( 14180 ev->max_user_per_ppdu_mumimo); 14181 param->target_cap_flags = ev->target_cap_flags; 14182 extract_ul_mumimo_support(param); 14183 wmi_debug("htt peer data :%d", ev->target_cap_flags); 14184 14185 extract_svc_rdy_ext2_afc_tlv(ev, param); 14186 14187 extract_hw_bdf_status(ev); 14188 14189 return QDF_STATUS_SUCCESS; 14190 } 14191 14192 /* 14193 * extract_dbs_or_sbs_cap_service_ready_ext2_tlv() - extract dbs_or_sbs cap from 14194 * service ready ext 2 14195 * 14196 * @wmi_handle: wmi handle 14197 * @event: pointer to event buffer 14198 * @sbs_lower_band_end_freq: If sbs_lower_band_end_freq is set to non-zero, 14199 * it indicates async SBS mode is supported, and 14200 * lower-band/higher band to MAC mapping is 14201 * switch-able. unit: mhz. examples 5180, 5320 14202 * 14203 * Return: QDF_STATUS_SUCCESS on success, QDF_STATUS_E_** on error 14204 */ 14205 static QDF_STATUS extract_dbs_or_sbs_cap_service_ready_ext2_tlv( 14206 wmi_unified_t wmi_handle, uint8_t *event, 14207 uint32_t *sbs_lower_band_end_freq) 14208 { 14209 WMI_SERVICE_READY_EXT2_EVENTID_param_tlvs *param_buf; 14210 wmi_dbs_or_sbs_cap_ext *dbs_or_sbs_caps; 14211 14212 param_buf = (WMI_SERVICE_READY_EXT2_EVENTID_param_tlvs *)event; 14213 if (!param_buf) 14214 return QDF_STATUS_E_INVAL; 14215 14216 dbs_or_sbs_caps = param_buf->dbs_or_sbs_cap_ext; 14217 if (!dbs_or_sbs_caps) 14218 return QDF_STATUS_E_INVAL; 14219 14220 *sbs_lower_band_end_freq = dbs_or_sbs_caps->sbs_lower_band_end_freq; 14221 14222 return QDF_STATUS_SUCCESS; 14223 } 14224 14225 /** 14226 * extract_sar_cap_service_ready_ext_tlv() - 14227 * extract SAR cap from service ready event 14228 * @wmi_handle: wmi handle 14229 * @event: pointer to event buffer 14230 * @ext_param: extended target info 14231 * 14232 * Return: QDF_STATUS_SUCCESS for success or error code 14233 */ 14234 static QDF_STATUS extract_sar_cap_service_ready_ext_tlv( 14235 wmi_unified_t wmi_handle, 14236 uint8_t *event, 14237 struct wlan_psoc_host_service_ext_param *ext_param) 14238 { 14239 WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *param_buf; 14240 WMI_SAR_CAPABILITIES *sar_caps; 14241 14242 param_buf = (WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *)event; 14243 14244 if (!param_buf) 14245 return QDF_STATUS_E_INVAL; 14246 14247 sar_caps = param_buf->sar_caps; 14248 if (sar_caps) 14249 ext_param->sar_version = sar_caps->active_version; 14250 else 14251 ext_param->sar_version = 0; 14252 14253 return QDF_STATUS_SUCCESS; 14254 } 14255 14256 /** 14257 * extract_hw_mode_cap_service_ready_ext_tlv() - 14258 * extract HW mode cap from service ready event 14259 * @wmi_handle: wmi handle 14260 * @event: pointer to event buffer 14261 * @hw_mode_idx: hw mode idx should be less than num_mode 14262 * @param: Pointer to hold evt buf 14263 * 14264 * Return: QDF_STATUS_SUCCESS for success or error code 14265 */ 14266 static QDF_STATUS extract_hw_mode_cap_service_ready_ext_tlv( 14267 wmi_unified_t wmi_handle, 14268 uint8_t *event, uint8_t hw_mode_idx, 14269 struct wlan_psoc_host_hw_mode_caps *param) 14270 { 14271 WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *param_buf; 14272 WMI_SOC_MAC_PHY_HW_MODE_CAPS *hw_caps; 14273 14274 param_buf = (WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *) event; 14275 if (!param_buf) 14276 return QDF_STATUS_E_INVAL; 14277 14278 hw_caps = param_buf->soc_hw_mode_caps; 14279 if (!hw_caps) 14280 return QDF_STATUS_E_INVAL; 14281 14282 if (!hw_caps->num_hw_modes || 14283 !param_buf->hw_mode_caps || 14284 hw_caps->num_hw_modes > PSOC_MAX_HW_MODE || 14285 hw_caps->num_hw_modes > param_buf->num_hw_mode_caps) 14286 return QDF_STATUS_E_INVAL; 14287 14288 if (hw_mode_idx >= hw_caps->num_hw_modes) 14289 return QDF_STATUS_E_INVAL; 14290 14291 param->hw_mode_id = param_buf->hw_mode_caps[hw_mode_idx].hw_mode_id; 14292 param->phy_id_map = param_buf->hw_mode_caps[hw_mode_idx].phy_id_map; 14293 14294 param->hw_mode_config_type = 14295 param_buf->hw_mode_caps[hw_mode_idx].hw_mode_config_type; 14296 14297 return QDF_STATUS_SUCCESS; 14298 } 14299 14300 /** 14301 * extract_service_ready_11be_support() - api to extract 11be support 14302 * @param: host mac phy capabilities 14303 * @mac_phy_caps: mac phy capabilities 14304 * 14305 * Return: void 14306 */ 14307 #ifdef WLAN_FEATURE_11BE 14308 static void 14309 extract_service_ready_11be_support(struct wlan_psoc_host_mac_phy_caps *param, 14310 WMI_MAC_PHY_CAPABILITIES *mac_phy_caps) 14311 { 14312 param->supports_11be = 14313 WMI_SUPPORT_11BE_GET(mac_phy_caps->supported_flags); 14314 14315 wmi_debug("11be support %d", param->supports_11be); 14316 } 14317 #else 14318 static void 14319 extract_service_ready_11be_support(struct wlan_psoc_host_mac_phy_caps *param, 14320 WMI_MAC_PHY_CAPABILITIES *mac_phy_caps) 14321 { 14322 } 14323 #endif 14324 14325 #if defined(WLAN_FEATURE_11BE_MLO) && defined(WLAN_MLO_MULTI_CHIP) 14326 static void extract_hw_link_id(struct wlan_psoc_host_mac_phy_caps *param, 14327 WMI_MAC_PHY_CAPABILITIES *mac_phy_caps) 14328 { 14329 param->hw_link_id = WMI_PHY_GET_HW_LINK_ID(mac_phy_caps->pdev_id); 14330 } 14331 #else 14332 static void extract_hw_link_id(struct wlan_psoc_host_mac_phy_caps *param, 14333 WMI_MAC_PHY_CAPABILITIES *mac_phy_caps) 14334 { 14335 } 14336 #endif /*WLAN_FEATURE_11BE_MLO && WLAN_MLO_MULTI_CHIP*/ 14337 14338 /** 14339 * extract_mac_phy_cap_service_ready_ext_tlv() - 14340 * extract MAC phy cap from service ready event 14341 * @wmi_handle: wmi handle 14342 * @event: pointer to event buffer 14343 * @hw_mode_id: hw mode idx should be less than num_mode 14344 * @phy_id: phy id within hw_mode 14345 * @param: Pointer to hold evt buf 14346 * 14347 * Return: QDF_STATUS_SUCCESS for success or error code 14348 */ 14349 static QDF_STATUS extract_mac_phy_cap_service_ready_ext_tlv( 14350 wmi_unified_t wmi_handle, 14351 uint8_t *event, uint8_t hw_mode_id, uint8_t phy_id, 14352 struct wlan_psoc_host_mac_phy_caps *param) 14353 { 14354 WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *param_buf; 14355 WMI_MAC_PHY_CAPABILITIES *mac_phy_caps; 14356 WMI_SOC_MAC_PHY_HW_MODE_CAPS *hw_caps; 14357 uint32_t phy_map; 14358 uint8_t hw_idx, phy_idx = 0, pdev_id; 14359 14360 param_buf = (WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *) event; 14361 if (!param_buf) 14362 return QDF_STATUS_E_INVAL; 14363 14364 hw_caps = param_buf->soc_hw_mode_caps; 14365 if (!hw_caps) 14366 return QDF_STATUS_E_INVAL; 14367 if (hw_caps->num_hw_modes > PSOC_MAX_HW_MODE || 14368 hw_caps->num_hw_modes > param_buf->num_hw_mode_caps) { 14369 wmi_err_rl("invalid num_hw_modes %d, num_hw_mode_caps %d", 14370 hw_caps->num_hw_modes, param_buf->num_hw_mode_caps); 14371 return QDF_STATUS_E_INVAL; 14372 } 14373 14374 for (hw_idx = 0; hw_idx < hw_caps->num_hw_modes; hw_idx++) { 14375 if (hw_mode_id == param_buf->hw_mode_caps[hw_idx].hw_mode_id) 14376 break; 14377 14378 phy_map = param_buf->hw_mode_caps[hw_idx].phy_id_map; 14379 while (phy_map) { 14380 phy_map >>= 1; 14381 phy_idx++; 14382 } 14383 } 14384 14385 if (hw_idx == hw_caps->num_hw_modes) 14386 return QDF_STATUS_E_INVAL; 14387 14388 phy_idx += phy_id; 14389 if (phy_idx >= param_buf->num_mac_phy_caps) 14390 return QDF_STATUS_E_INVAL; 14391 14392 mac_phy_caps = ¶m_buf->mac_phy_caps[phy_idx]; 14393 14394 param->hw_mode_id = mac_phy_caps->hw_mode_id; 14395 param->phy_idx = phy_idx; 14396 pdev_id = WMI_PHY_GET_PDEV_ID(mac_phy_caps->pdev_id); 14397 param->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host( 14398 wmi_handle, 14399 pdev_id); 14400 param->tgt_pdev_id = pdev_id; 14401 extract_hw_link_id(param, mac_phy_caps); 14402 param->phy_id = mac_phy_caps->phy_id; 14403 param->supports_11b = 14404 WMI_SUPPORT_11B_GET(mac_phy_caps->supported_flags); 14405 param->supports_11g = 14406 WMI_SUPPORT_11G_GET(mac_phy_caps->supported_flags); 14407 param->supports_11a = 14408 WMI_SUPPORT_11A_GET(mac_phy_caps->supported_flags); 14409 param->supports_11n = 14410 WMI_SUPPORT_11N_GET(mac_phy_caps->supported_flags); 14411 param->supports_11ac = 14412 WMI_SUPPORT_11AC_GET(mac_phy_caps->supported_flags); 14413 param->supports_11ax = 14414 WMI_SUPPORT_11AX_GET(mac_phy_caps->supported_flags); 14415 14416 extract_service_ready_11be_support(param, mac_phy_caps); 14417 14418 param->supported_bands = mac_phy_caps->supported_bands; 14419 param->ampdu_density = mac_phy_caps->ampdu_density; 14420 param->max_bw_supported_2G = mac_phy_caps->max_bw_supported_2G; 14421 param->ht_cap_info_2G = mac_phy_caps->ht_cap_info_2G; 14422 param->vht_cap_info_2G = mac_phy_caps->vht_cap_info_2G; 14423 param->vht_supp_mcs_2G = mac_phy_caps->vht_supp_mcs_2G; 14424 param->he_cap_info_2G[WMI_HOST_HECAP_MAC_WORD1] = 14425 mac_phy_caps->he_cap_info_2G; 14426 param->he_cap_info_2G[WMI_HOST_HECAP_MAC_WORD2] = 14427 mac_phy_caps->he_cap_info_2G_ext; 14428 param->he_supp_mcs_2G = mac_phy_caps->he_supp_mcs_2G; 14429 param->tx_chain_mask_2G = mac_phy_caps->tx_chain_mask_2G; 14430 param->rx_chain_mask_2G = mac_phy_caps->rx_chain_mask_2G; 14431 param->max_bw_supported_5G = mac_phy_caps->max_bw_supported_5G; 14432 param->ht_cap_info_5G = mac_phy_caps->ht_cap_info_5G; 14433 param->vht_cap_info_5G = mac_phy_caps->vht_cap_info_5G; 14434 param->vht_supp_mcs_5G = mac_phy_caps->vht_supp_mcs_5G; 14435 param->he_cap_info_5G[WMI_HOST_HECAP_MAC_WORD1] = 14436 mac_phy_caps->he_cap_info_5G; 14437 param->he_cap_info_5G[WMI_HOST_HECAP_MAC_WORD2] = 14438 mac_phy_caps->he_cap_info_5G_ext; 14439 param->he_supp_mcs_5G = mac_phy_caps->he_supp_mcs_5G; 14440 param->he_cap_info_internal = mac_phy_caps->he_cap_info_internal; 14441 param->tx_chain_mask_5G = mac_phy_caps->tx_chain_mask_5G; 14442 param->rx_chain_mask_5G = mac_phy_caps->rx_chain_mask_5G; 14443 qdf_mem_copy(¶m->he_cap_phy_info_2G, 14444 &mac_phy_caps->he_cap_phy_info_2G, 14445 sizeof(param->he_cap_phy_info_2G)); 14446 qdf_mem_copy(¶m->he_cap_phy_info_5G, 14447 &mac_phy_caps->he_cap_phy_info_5G, 14448 sizeof(param->he_cap_phy_info_5G)); 14449 qdf_mem_copy(¶m->he_ppet2G, &mac_phy_caps->he_ppet2G, 14450 sizeof(param->he_ppet2G)); 14451 qdf_mem_copy(¶m->he_ppet5G, &mac_phy_caps->he_ppet5G, 14452 sizeof(param->he_ppet5G)); 14453 param->chainmask_table_id = mac_phy_caps->chainmask_table_id; 14454 param->lmac_id = mac_phy_caps->lmac_id; 14455 param->reg_cap_ext.wireless_modes = convert_wireless_modes_tlv 14456 (mac_phy_caps->wireless_modes); 14457 param->reg_cap_ext.low_2ghz_chan = mac_phy_caps->low_2ghz_chan_freq; 14458 param->reg_cap_ext.high_2ghz_chan = mac_phy_caps->high_2ghz_chan_freq; 14459 param->reg_cap_ext.low_5ghz_chan = mac_phy_caps->low_5ghz_chan_freq; 14460 param->reg_cap_ext.high_5ghz_chan = mac_phy_caps->high_5ghz_chan_freq; 14461 param->nss_ratio_enabled = WMI_NSS_RATIO_ENABLE_DISABLE_GET( 14462 mac_phy_caps->nss_ratio); 14463 param->nss_ratio_info = WMI_NSS_RATIO_INFO_GET(mac_phy_caps->nss_ratio); 14464 14465 return QDF_STATUS_SUCCESS; 14466 } 14467 14468 #ifdef WLAN_FEATURE_11BE_MLO 14469 /** 14470 * extract_mac_phy_emlcap() - API to extract EML Capabilities 14471 * @param: host ext2 mac phy capabilities 14472 * @mac_phy_caps: ext mac phy capabilities 14473 * 14474 * Return: void 14475 */ 14476 static void extract_mac_phy_emlcap(struct wlan_psoc_host_mac_phy_caps_ext2 *param, 14477 WMI_MAC_PHY_CAPABILITIES_EXT *mac_phy_caps) 14478 { 14479 if (!param || !mac_phy_caps) 14480 return; 14481 14482 param->emlcap.emlsr_supp = WMI_SUPPORT_EMLSR_GET(mac_phy_caps->eml_capability); 14483 param->emlcap.emlsr_pad_delay = WMI_EMLSR_PADDING_DELAY_GET(mac_phy_caps->eml_capability); 14484 param->emlcap.emlsr_trans_delay = WMI_EMLSR_TRANSITION_DELAY_GET(mac_phy_caps->eml_capability); 14485 param->emlcap.emlmr_supp = WMI_SUPPORT_EMLMR_GET(mac_phy_caps->eml_capability); 14486 param->emlcap.emlmr_delay = WMI_EMLMR_DELAY_GET(mac_phy_caps->eml_capability); 14487 param->emlcap.trans_timeout = WMI_TRANSITION_TIMEOUT_GET(mac_phy_caps->eml_capability); 14488 } 14489 14490 /** 14491 * extract_mac_phy_mldcap() - API to extract MLD Capabilities 14492 * @param: host ext2 mac phy capabilities 14493 * @mac_phy_caps: ext mac phy capabilities 14494 * 14495 * Return: void 14496 */ 14497 static void extract_mac_phy_mldcap(struct wlan_psoc_host_mac_phy_caps_ext2 *param, 14498 WMI_MAC_PHY_CAPABILITIES_EXT *mac_phy_caps) 14499 { 14500 if (!param || !mac_phy_caps) 14501 return; 14502 14503 param->mldcap.max_simult_link = WMI_MAX_NUM_SIMULTANEOUS_LINKS_GET(mac_phy_caps->mld_capability); 14504 param->mldcap.srs_support = WMI_SUPPORT_SRS_GET(mac_phy_caps->mld_capability); 14505 param->mldcap.tid2link_neg_support = WMI_TID_TO_LINK_NEGOTIATION_GET(mac_phy_caps->mld_capability); 14506 param->mldcap.str_freq_sep = WMI_FREQ_SEPERATION_STR_GET(mac_phy_caps->mld_capability); 14507 param->mldcap.aar_support = WMI_SUPPORT_AAR_GET(mac_phy_caps->mld_capability); 14508 } 14509 #else 14510 static void extract_mac_phy_emlcap(struct wlan_psoc_host_mac_phy_caps_ext2 *param, 14511 WMI_MAC_PHY_CAPABILITIES_EXT *mac_phy_caps) 14512 { 14513 } 14514 14515 static void extract_mac_phy_mldcap(struct wlan_psoc_host_mac_phy_caps_ext2 *param, 14516 WMI_MAC_PHY_CAPABILITIES_EXT *mac_phy_caps) 14517 { 14518 } 14519 #endif 14520 14521 /** 14522 * extract_mac_phy_cap_ehtcaps- api to extract eht mac phy caps 14523 * @param: host ext2 mac phy capabilities 14524 * @mac_phy_caps: ext mac phy capabilities 14525 * 14526 * Return: void 14527 */ 14528 #ifdef WLAN_FEATURE_11BE 14529 static void extract_mac_phy_cap_ehtcaps( 14530 struct wlan_psoc_host_mac_phy_caps_ext2 *param, 14531 WMI_MAC_PHY_CAPABILITIES_EXT *mac_phy_caps) 14532 { 14533 uint32_t i; 14534 14535 param->eht_supp_mcs_2G = mac_phy_caps->eht_supp_mcs_2G; 14536 param->eht_supp_mcs_5G = mac_phy_caps->eht_supp_mcs_5G; 14537 param->eht_cap_info_internal = mac_phy_caps->eht_cap_info_internal; 14538 14539 qdf_mem_copy(¶m->eht_cap_info_2G, 14540 &mac_phy_caps->eht_cap_mac_info_2G, 14541 sizeof(param->eht_cap_info_2G)); 14542 qdf_mem_copy(¶m->eht_cap_info_5G, 14543 &mac_phy_caps->eht_cap_mac_info_5G, 14544 sizeof(param->eht_cap_info_5G)); 14545 14546 qdf_mem_copy(¶m->eht_cap_phy_info_2G, 14547 &mac_phy_caps->eht_cap_phy_info_2G, 14548 sizeof(param->eht_cap_phy_info_2G)); 14549 qdf_mem_copy(¶m->eht_cap_phy_info_5G, 14550 &mac_phy_caps->eht_cap_phy_info_5G, 14551 sizeof(param->eht_cap_phy_info_5G)); 14552 14553 qdf_mem_copy(¶m->eht_supp_mcs_ext_2G, 14554 &mac_phy_caps->eht_supp_mcs_ext_2G, 14555 sizeof(param->eht_supp_mcs_ext_2G)); 14556 qdf_mem_copy(¶m->eht_supp_mcs_ext_5G, 14557 &mac_phy_caps->eht_supp_mcs_ext_5G, 14558 sizeof(param->eht_supp_mcs_ext_5G)); 14559 14560 qdf_mem_copy(¶m->eht_ppet2G, &mac_phy_caps->eht_ppet2G, 14561 sizeof(param->eht_ppet2G)); 14562 qdf_mem_copy(¶m->eht_ppet5G, &mac_phy_caps->eht_ppet5G, 14563 sizeof(param->eht_ppet5G)); 14564 14565 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", 14566 mac_phy_caps->eht_cap_mac_info_2G[0], 14567 mac_phy_caps->eht_cap_mac_info_5G[0], 14568 mac_phy_caps->eht_supp_mcs_2G, mac_phy_caps->eht_supp_mcs_5G, 14569 mac_phy_caps->eht_cap_info_internal); 14570 14571 wmi_nofl_debug("EHT phy caps: "); 14572 14573 wmi_nofl_debug("2G:"); 14574 for (i = 0; i < PSOC_HOST_MAX_EHT_PHY_SIZE; i++) { 14575 wmi_nofl_debug("index %d value %x", 14576 i, param->eht_cap_phy_info_2G[i]); 14577 } 14578 wmi_nofl_debug("5G:"); 14579 for (i = 0; i < PSOC_HOST_MAX_EHT_PHY_SIZE; i++) { 14580 wmi_nofl_debug("index %d value %x", 14581 i, param->eht_cap_phy_info_5G[i]); 14582 } 14583 wmi_nofl_debug("2G MCS ext Map:"); 14584 for (i = 0; i < PSOC_HOST_EHT_MCS_NSS_MAP_2G_SIZE; i++) { 14585 wmi_nofl_debug("index %d value %x", 14586 i, param->eht_supp_mcs_ext_2G[i]); 14587 } 14588 wmi_nofl_debug("5G MCS ext Map:"); 14589 for (i = 0; i < PSOC_HOST_EHT_MCS_NSS_MAP_5G_SIZE; i++) { 14590 wmi_nofl_debug("index %d value %x", 14591 i, param->eht_supp_mcs_ext_5G[i]); 14592 } 14593 wmi_nofl_debug("2G PPET: numss_m1 %x ru_bit_mask %x", 14594 param->eht_ppet2G.numss_m1, 14595 param->eht_ppet2G.ru_bit_mask); 14596 for (i = 0; i < PSOC_HOST_MAX_NUM_SS; i++) { 14597 wmi_nofl_debug("index %d value %x", 14598 i, param->eht_ppet2G.ppet16_ppet8_ru3_ru0[i]); 14599 } 14600 wmi_nofl_debug("5G PPET: numss_m1 %x ru_bit_mask %x", 14601 param->eht_ppet5G.numss_m1, 14602 param->eht_ppet5G.ru_bit_mask); 14603 for (i = 0; i < PSOC_HOST_MAX_NUM_SS; i++) { 14604 wmi_nofl_debug("index %d value %x", 14605 i, param->eht_ppet5G.ppet16_ppet8_ru3_ru0[i]); 14606 } 14607 } 14608 #else 14609 static void extract_mac_phy_cap_ehtcaps( 14610 struct wlan_psoc_host_mac_phy_caps_ext2 *param, 14611 WMI_MAC_PHY_CAPABILITIES_EXT *mac_phy_caps) 14612 { 14613 } 14614 #endif 14615 14616 static QDF_STATUS extract_mac_phy_cap_service_ready_ext2_tlv( 14617 wmi_unified_t wmi_handle, 14618 uint8_t *event, uint8_t hw_mode_id, uint8_t phy_id, 14619 uint8_t phy_idx, 14620 struct wlan_psoc_host_mac_phy_caps_ext2 *param) 14621 { 14622 WMI_SERVICE_READY_EXT2_EVENTID_param_tlvs *param_buf; 14623 WMI_MAC_PHY_CAPABILITIES_EXT *mac_phy_caps; 14624 14625 if (!event) { 14626 wmi_err("null evt_buf"); 14627 return QDF_STATUS_E_INVAL; 14628 } 14629 14630 param_buf = (WMI_SERVICE_READY_EXT2_EVENTID_param_tlvs *)event; 14631 14632 if (!param_buf->num_mac_phy_caps) 14633 return QDF_STATUS_SUCCESS; 14634 14635 if (phy_idx >= param_buf->num_mac_phy_caps) 14636 return QDF_STATUS_E_INVAL; 14637 14638 mac_phy_caps = ¶m_buf->mac_phy_caps[phy_idx]; 14639 14640 if ((hw_mode_id != mac_phy_caps->hw_mode_id) || 14641 (phy_id != mac_phy_caps->phy_id)) 14642 return QDF_STATUS_E_INVAL; 14643 14644 param->hw_mode_id = mac_phy_caps->hw_mode_id; 14645 param->phy_id = mac_phy_caps->phy_id; 14646 param->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host( 14647 wmi_handle, WMI_PHY_GET_PDEV_ID(mac_phy_caps->pdev_id)); 14648 param->wireless_modes_ext = convert_wireless_modes_ext_tlv( 14649 mac_phy_caps->wireless_modes_ext); 14650 14651 extract_mac_phy_cap_ehtcaps(param, mac_phy_caps); 14652 extract_mac_phy_emlcap(param, mac_phy_caps); 14653 extract_mac_phy_mldcap(param, mac_phy_caps); 14654 14655 return QDF_STATUS_SUCCESS; 14656 } 14657 14658 /** 14659 * extract_reg_cap_service_ready_ext_tlv() - 14660 * extract REG cap from service ready event 14661 * @wmi_handle: wmi handle 14662 * @event: pointer to event buffer 14663 * @phy_idx: phy idx should be less than num_mode 14664 * @param: Pointer to hold evt buf 14665 * 14666 * Return: QDF_STATUS_SUCCESS for success or error code 14667 */ 14668 static QDF_STATUS extract_reg_cap_service_ready_ext_tlv( 14669 wmi_unified_t wmi_handle, 14670 uint8_t *event, uint8_t phy_idx, 14671 struct wlan_psoc_host_hal_reg_capabilities_ext *param) 14672 { 14673 WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *param_buf; 14674 WMI_SOC_HAL_REG_CAPABILITIES *reg_caps; 14675 WMI_HAL_REG_CAPABILITIES_EXT *ext_reg_cap; 14676 14677 param_buf = (WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *) event; 14678 if (!param_buf) 14679 return QDF_STATUS_E_INVAL; 14680 14681 reg_caps = param_buf->soc_hal_reg_caps; 14682 if (!reg_caps) 14683 return QDF_STATUS_E_INVAL; 14684 14685 if (reg_caps->num_phy > param_buf->num_hal_reg_caps) 14686 return QDF_STATUS_E_INVAL; 14687 14688 if (phy_idx >= reg_caps->num_phy) 14689 return QDF_STATUS_E_INVAL; 14690 14691 if (!param_buf->hal_reg_caps) 14692 return QDF_STATUS_E_INVAL; 14693 14694 ext_reg_cap = ¶m_buf->hal_reg_caps[phy_idx]; 14695 14696 param->phy_id = ext_reg_cap->phy_id; 14697 param->eeprom_reg_domain = ext_reg_cap->eeprom_reg_domain; 14698 param->eeprom_reg_domain_ext = ext_reg_cap->eeprom_reg_domain_ext; 14699 param->regcap1 = ext_reg_cap->regcap1; 14700 param->regcap2 = ext_reg_cap->regcap2; 14701 param->wireless_modes = convert_wireless_modes_tlv( 14702 ext_reg_cap->wireless_modes); 14703 param->low_2ghz_chan = ext_reg_cap->low_2ghz_chan; 14704 param->high_2ghz_chan = ext_reg_cap->high_2ghz_chan; 14705 param->low_5ghz_chan = ext_reg_cap->low_5ghz_chan; 14706 param->high_5ghz_chan = ext_reg_cap->high_5ghz_chan; 14707 14708 return QDF_STATUS_SUCCESS; 14709 } 14710 14711 static QDF_STATUS validate_dbr_ring_caps_idx(uint8_t idx, 14712 uint8_t num_dma_ring_caps) 14713 { 14714 /* If dma_ring_caps is populated, num_dbr_ring_caps is non-zero */ 14715 if (!num_dma_ring_caps) { 14716 wmi_err("dma_ring_caps %d", num_dma_ring_caps); 14717 return QDF_STATUS_E_INVAL; 14718 } 14719 if (idx >= num_dma_ring_caps) { 14720 wmi_err("Index %d exceeds range", idx); 14721 return QDF_STATUS_E_INVAL; 14722 } 14723 return QDF_STATUS_SUCCESS; 14724 } 14725 14726 static void 14727 populate_dbr_ring_cap_elems(wmi_unified_t wmi_handle, 14728 struct wlan_psoc_host_dbr_ring_caps *param, 14729 WMI_DMA_RING_CAPABILITIES *dbr_ring_caps) 14730 { 14731 param->pdev_id = wmi_handle->ops->convert_target_pdev_id_to_host( 14732 wmi_handle, 14733 dbr_ring_caps->pdev_id); 14734 param->mod_id = dbr_ring_caps->mod_id; 14735 param->ring_elems_min = dbr_ring_caps->ring_elems_min; 14736 param->min_buf_size = dbr_ring_caps->min_buf_size; 14737 param->min_buf_align = dbr_ring_caps->min_buf_align; 14738 } 14739 14740 static QDF_STATUS extract_dbr_ring_cap_service_ready_ext_tlv( 14741 wmi_unified_t wmi_handle, 14742 uint8_t *event, uint8_t idx, 14743 struct wlan_psoc_host_dbr_ring_caps *param) 14744 { 14745 WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *param_buf; 14746 QDF_STATUS status; 14747 14748 param_buf = (WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *)event; 14749 if (!param_buf) 14750 return QDF_STATUS_E_INVAL; 14751 14752 status = validate_dbr_ring_caps_idx(idx, param_buf->num_dma_ring_caps); 14753 if (status != QDF_STATUS_SUCCESS) 14754 return status; 14755 14756 populate_dbr_ring_cap_elems(wmi_handle, param, 14757 ¶m_buf->dma_ring_caps[idx]); 14758 return QDF_STATUS_SUCCESS; 14759 } 14760 14761 static QDF_STATUS extract_dbr_ring_cap_service_ready_ext2_tlv( 14762 wmi_unified_t wmi_handle, 14763 uint8_t *event, uint8_t idx, 14764 struct wlan_psoc_host_dbr_ring_caps *param) 14765 { 14766 WMI_SERVICE_READY_EXT2_EVENTID_param_tlvs *param_buf; 14767 QDF_STATUS status; 14768 14769 param_buf = (WMI_SERVICE_READY_EXT2_EVENTID_param_tlvs *)event; 14770 if (!param_buf) 14771 return QDF_STATUS_E_INVAL; 14772 14773 status = validate_dbr_ring_caps_idx(idx, param_buf->num_dma_ring_caps); 14774 if (status != QDF_STATUS_SUCCESS) 14775 return status; 14776 14777 populate_dbr_ring_cap_elems(wmi_handle, param, 14778 ¶m_buf->dma_ring_caps[idx]); 14779 return QDF_STATUS_SUCCESS; 14780 } 14781 14782 static QDF_STATUS extract_scan_radio_cap_service_ready_ext2_tlv( 14783 wmi_unified_t wmi_handle, 14784 uint8_t *event, uint8_t idx, 14785 struct wlan_psoc_host_scan_radio_caps *param) 14786 { 14787 WMI_SERVICE_READY_EXT2_EVENTID_param_tlvs *param_buf; 14788 WMI_SCAN_RADIO_CAPABILITIES_EXT2 *scan_radio_caps; 14789 14790 param_buf = (WMI_SERVICE_READY_EXT2_EVENTID_param_tlvs *)event; 14791 if (!param_buf) 14792 return QDF_STATUS_E_INVAL; 14793 14794 if (idx >= param_buf->num_wmi_scan_radio_caps) 14795 return QDF_STATUS_E_INVAL; 14796 14797 scan_radio_caps = ¶m_buf->wmi_scan_radio_caps[idx]; 14798 param->phy_id = scan_radio_caps->phy_id; 14799 param->scan_radio_supported = 14800 WMI_SCAN_RADIO_CAP_SCAN_RADIO_FLAG_GET(scan_radio_caps->flags); 14801 param->dfs_en = 14802 WMI_SCAN_RADIO_CAP_DFS_FLAG_GET(scan_radio_caps->flags); 14803 14804 return QDF_STATUS_SUCCESS; 14805 } 14806 14807 static QDF_STATUS extract_sw_cal_ver_ext2_tlv(wmi_unified_t wmi_handle, 14808 uint8_t *event, 14809 struct wmi_host_sw_cal_ver *cal) 14810 { 14811 WMI_SERVICE_READY_EXT2_EVENTID_param_tlvs *param_buf; 14812 wmi_sw_cal_ver_cap *fw_cap; 14813 14814 param_buf = (WMI_SERVICE_READY_EXT2_EVENTID_param_tlvs *)event; 14815 if (!param_buf) 14816 return QDF_STATUS_E_INVAL; 14817 14818 fw_cap = param_buf->sw_cal_ver_cap; 14819 if (!fw_cap) 14820 return QDF_STATUS_E_INVAL; 14821 14822 cal->bdf_cal_ver = fw_cap->bdf_cal_ver; 14823 cal->ftm_cal_ver = fw_cap->ftm_cal_ver; 14824 cal->status = fw_cap->status; 14825 14826 return QDF_STATUS_SUCCESS; 14827 } 14828 14829 /** 14830 * wmi_tgt_thermal_level_to_host() - Convert target thermal level to host enum 14831 * @level: target thermal level from WMI_THERM_THROT_STATS_EVENTID event 14832 * 14833 * Return: host thermal throt level 14834 */ 14835 static enum thermal_throttle_level 14836 wmi_tgt_thermal_level_to_host(uint32_t level) 14837 { 14838 switch (level) { 14839 case WMI_THERMAL_FULLPERF: 14840 return THERMAL_FULLPERF; 14841 case WMI_THERMAL_MITIGATION: 14842 return THERMAL_MITIGATION; 14843 case WMI_THERMAL_SHUTOFF: 14844 return THERMAL_SHUTOFF; 14845 case WMI_THERMAL_SHUTDOWN_TGT: 14846 return THERMAL_SHUTDOWN_TARGET; 14847 default: 14848 return THERMAL_UNKNOWN; 14849 } 14850 } 14851 14852 #ifdef THERMAL_STATS_SUPPORT 14853 static void 14854 populate_thermal_stats(WMI_THERM_THROT_STATS_EVENTID_param_tlvs *param_buf, 14855 uint32_t *therm_throt_levels, 14856 struct thermal_throt_level_stats *tt_temp_range_stats) 14857 { 14858 uint8_t lvl_idx; 14859 wmi_therm_throt_stats_event_fixed_param *tt_stats_event; 14860 wmi_thermal_throt_temp_range_stats *wmi_tt_stats; 14861 14862 tt_stats_event = param_buf->fixed_param; 14863 *therm_throt_levels = (tt_stats_event->therm_throt_levels > 14864 WMI_THERMAL_STATS_TEMP_THRESH_LEVEL_MAX) ? 14865 WMI_THERMAL_STATS_TEMP_THRESH_LEVEL_MAX : 14866 tt_stats_event->therm_throt_levels; 14867 14868 if (*therm_throt_levels > param_buf->num_temp_range_stats) { 14869 wmi_err("therm_throt_levels:%u oob num_temp_range_stats:%u", 14870 *therm_throt_levels, 14871 param_buf->num_temp_range_stats); 14872 return; 14873 } 14874 14875 wmi_tt_stats = param_buf->temp_range_stats; 14876 if (!wmi_tt_stats) { 14877 wmi_err("wmi_tt_stats Null"); 14878 return; 14879 } 14880 14881 for (lvl_idx = 0; lvl_idx < *therm_throt_levels; lvl_idx++) { 14882 tt_temp_range_stats[lvl_idx].start_temp_level = 14883 wmi_tt_stats[lvl_idx].start_temp_level; 14884 tt_temp_range_stats[lvl_idx].end_temp_level = 14885 wmi_tt_stats[lvl_idx].end_temp_level; 14886 tt_temp_range_stats[lvl_idx].total_time_ms_lo = 14887 wmi_tt_stats[lvl_idx].total_time_ms_lo; 14888 tt_temp_range_stats[lvl_idx].total_time_ms_hi = 14889 wmi_tt_stats[lvl_idx].total_time_ms_hi; 14890 tt_temp_range_stats[lvl_idx].num_entry = 14891 wmi_tt_stats[lvl_idx].num_entry; 14892 wmi_debug("level %d, start temp %d, end temp %d, total time low %d, total time high %d, counter %d", 14893 lvl_idx, wmi_tt_stats[lvl_idx].start_temp_level, 14894 wmi_tt_stats[lvl_idx].end_temp_level, 14895 wmi_tt_stats[lvl_idx].total_time_ms_lo, 14896 wmi_tt_stats[lvl_idx].total_time_ms_hi, 14897 wmi_tt_stats[lvl_idx].num_entry); 14898 } 14899 } 14900 #else 14901 static void 14902 populate_thermal_stats(WMI_THERM_THROT_STATS_EVENTID_param_tlvs *param_buf, 14903 uint32_t *therm_throt_levels, 14904 struct thermal_throt_level_stats *tt_temp_range_stats) 14905 { 14906 } 14907 #endif 14908 14909 /** 14910 * extract_thermal_stats_tlv() - extract thermal stats from event 14911 * @wmi_handle: wmi handle 14912 * @evt_buf: Pointer to event buffer 14913 * @temp: Pointer to hold extracted temperature 14914 * @level: Pointer to hold extracted level in host enum 14915 * @therm_throt_levels: Pointer to hold extracted thermal throttle temp 14916 * range 14917 * @tt_temp_range_stats_event: Pointer to hold extracted thermal stats for 14918 * every level 14919 * @pdev_id: Pointer to hold extracted pdev id 14920 * 14921 * Return: QDF_STATUS_SUCCESS for success or error code 14922 */ 14923 static QDF_STATUS 14924 extract_thermal_stats_tlv(wmi_unified_t wmi_handle, 14925 void *evt_buf, uint32_t *temp, 14926 enum thermal_throttle_level *level, 14927 uint32_t *therm_throt_levels, 14928 struct thermal_throt_level_stats *tt_temp_range_stats_event, 14929 uint32_t *pdev_id) 14930 { 14931 WMI_THERM_THROT_STATS_EVENTID_param_tlvs *param_buf; 14932 wmi_therm_throt_stats_event_fixed_param *tt_stats_event; 14933 14934 param_buf = 14935 (WMI_THERM_THROT_STATS_EVENTID_param_tlvs *) evt_buf; 14936 if (!param_buf) 14937 return QDF_STATUS_E_INVAL; 14938 14939 tt_stats_event = param_buf->fixed_param; 14940 wmi_debug("thermal temperature %d level %d", 14941 tt_stats_event->temp, tt_stats_event->level); 14942 *pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host( 14943 wmi_handle, 14944 tt_stats_event->pdev_id); 14945 *temp = tt_stats_event->temp; 14946 *level = wmi_tgt_thermal_level_to_host(tt_stats_event->level); 14947 14948 if (tt_stats_event->therm_throt_levels) 14949 populate_thermal_stats(param_buf, therm_throt_levels, 14950 tt_temp_range_stats_event); 14951 14952 return QDF_STATUS_SUCCESS; 14953 } 14954 14955 /** 14956 * extract_thermal_level_stats_tlv() - extract thermal level stats from event 14957 * @wmi_handle: wmi handle 14958 * @evt_buf: pointer to event buffer 14959 * @idx: Index to level stats 14960 * @levelcount: Pointer to hold levelcount 14961 * @dccount: Pointer to hold dccount 14962 * 14963 * Return: QDF_STATUS_SUCCESS for success or error code 14964 */ 14965 static QDF_STATUS 14966 extract_thermal_level_stats_tlv(wmi_unified_t wmi_handle, 14967 void *evt_buf, uint8_t idx, uint32_t *levelcount, 14968 uint32_t *dccount) 14969 { 14970 WMI_THERM_THROT_STATS_EVENTID_param_tlvs *param_buf; 14971 wmi_therm_throt_level_stats_info *tt_level_info; 14972 14973 param_buf = 14974 (WMI_THERM_THROT_STATS_EVENTID_param_tlvs *) evt_buf; 14975 if (!param_buf) 14976 return QDF_STATUS_E_INVAL; 14977 14978 tt_level_info = param_buf->therm_throt_level_stats_info; 14979 14980 if (idx < THERMAL_LEVELS) { 14981 *levelcount = tt_level_info[idx].level_count; 14982 *dccount = tt_level_info[idx].dc_count; 14983 return QDF_STATUS_SUCCESS; 14984 } 14985 14986 return QDF_STATUS_E_FAILURE; 14987 } 14988 14989 /** 14990 * fips_conv_data_be() - LE to BE conversion of FIPS ev data 14991 * @data_len: data length 14992 * @data: pointer to data 14993 * 14994 * Return: QDF_STATUS - success or error status 14995 */ 14996 #ifdef BIG_ENDIAN_HOST 14997 static QDF_STATUS fips_conv_data_be(uint32_t data_len, uint8_t *data) 14998 { 14999 uint8_t *data_aligned = NULL; 15000 int c; 15001 unsigned char *data_unaligned; 15002 15003 data_unaligned = qdf_mem_malloc(((sizeof(uint8_t) * data_len) + 15004 FIPS_ALIGN)); 15005 /* Assigning unaligned space to copy the data */ 15006 /* Checking if kmalloc does successful allocation */ 15007 if (!data_unaligned) 15008 return QDF_STATUS_E_FAILURE; 15009 15010 /* Checking if space is aligned */ 15011 if (!FIPS_IS_ALIGNED(data_unaligned, FIPS_ALIGN)) { 15012 /* align the data space */ 15013 data_aligned = 15014 (uint8_t *)FIPS_ALIGNTO(data_unaligned, FIPS_ALIGN); 15015 } else { 15016 data_aligned = (u_int8_t *)data_unaligned; 15017 } 15018 15019 /* memset and copy content from data to data aligned */ 15020 OS_MEMSET(data_aligned, 0, data_len); 15021 OS_MEMCPY(data_aligned, data, data_len); 15022 /* Endianness to LE */ 15023 for (c = 0; c < data_len/4; c++) { 15024 *((u_int32_t *)data_aligned + c) = 15025 qdf_le32_to_cpu(*((u_int32_t *)data_aligned + c)); 15026 } 15027 15028 /* Copy content to event->data */ 15029 OS_MEMCPY(data, data_aligned, data_len); 15030 15031 /* clean up allocated space */ 15032 qdf_mem_free(data_unaligned); 15033 data_aligned = NULL; 15034 data_unaligned = NULL; 15035 15036 /*************************************************************/ 15037 15038 return QDF_STATUS_SUCCESS; 15039 } 15040 #else 15041 static QDF_STATUS fips_conv_data_be(uint32_t data_len, uint8_t *data) 15042 { 15043 return QDF_STATUS_SUCCESS; 15044 } 15045 #endif 15046 15047 /** 15048 * send_pdev_get_pn_cmd_tlv() - send get PN request params to fw 15049 * @wmi_handle: wmi handle 15050 * @params: PN request params for peer 15051 * 15052 * Return: QDF_STATUS - success or error status 15053 */ 15054 static QDF_STATUS 15055 send_pdev_get_pn_cmd_tlv(wmi_unified_t wmi_handle, 15056 struct peer_request_pn_param *params) 15057 { 15058 wmi_peer_tx_pn_request_cmd_fixed_param *cmd; 15059 wmi_buf_t buf; 15060 uint8_t *buf_ptr; 15061 uint32_t len = sizeof(wmi_peer_tx_pn_request_cmd_fixed_param); 15062 15063 buf = wmi_buf_alloc(wmi_handle, len); 15064 if (!buf) { 15065 wmi_err("wmi_buf_alloc failed"); 15066 return QDF_STATUS_E_FAILURE; 15067 } 15068 15069 buf_ptr = (uint8_t *)wmi_buf_data(buf); 15070 cmd = (wmi_peer_tx_pn_request_cmd_fixed_param *)buf_ptr; 15071 15072 WMITLV_SET_HDR(&cmd->tlv_header, 15073 WMITLV_TAG_STRUC_wmi_peer_tx_pn_request_cmd_fixed_param, 15074 WMITLV_GET_STRUCT_TLVLEN(wmi_peer_tx_pn_request_cmd_fixed_param)); 15075 15076 cmd->vdev_id = params->vdev_id; 15077 WMI_CHAR_ARRAY_TO_MAC_ADDR(params->peer_macaddr, &cmd->peer_macaddr); 15078 cmd->key_type = params->key_type; 15079 cmd->key_ix = params->keyix; 15080 if (wmi_unified_cmd_send(wmi_handle, buf, len, 15081 WMI_PEER_TX_PN_REQUEST_CMDID)) { 15082 wmi_err("Failed to send WMI command"); 15083 wmi_buf_free(buf); 15084 return QDF_STATUS_E_FAILURE; 15085 } 15086 return QDF_STATUS_SUCCESS; 15087 } 15088 15089 /** 15090 * extract_get_pn_data_tlv() - extract pn resp 15091 * @wmi_handle: wmi handle 15092 * @evt_buf: pointer to event buffer 15093 * @param: PN response params for peer 15094 * 15095 * Return: QDF_STATUS - success or error status 15096 */ 15097 static QDF_STATUS 15098 extract_get_pn_data_tlv(wmi_unified_t wmi_handle, void *evt_buf, 15099 struct wmi_host_get_pn_event *param) 15100 { 15101 WMI_PEER_TX_PN_RESPONSE_EVENTID_param_tlvs *param_buf; 15102 wmi_peer_tx_pn_response_event_fixed_param *event = NULL; 15103 15104 param_buf = (WMI_PEER_TX_PN_RESPONSE_EVENTID_param_tlvs *)evt_buf; 15105 event = 15106 (wmi_peer_tx_pn_response_event_fixed_param *)param_buf->fixed_param; 15107 15108 param->vdev_id = event->vdev_id; 15109 param->key_type = event->key_type; 15110 param->key_ix = event->key_ix; 15111 qdf_mem_copy(param->pn, event->pn, sizeof(event->pn)); 15112 WMI_MAC_ADDR_TO_CHAR_ARRAY(&event->peer_macaddr, param->mac_addr); 15113 15114 return QDF_STATUS_SUCCESS; 15115 } 15116 15117 /** 15118 * send_pdev_get_rxpn_cmd_tlv() - send get Rx PN request params to fw 15119 * @wmi_handle: wmi handle 15120 * @params: Rx PN request params for peer 15121 * 15122 * Return: QDF_STATUS - success or error status 15123 */ 15124 static QDF_STATUS 15125 send_pdev_get_rxpn_cmd_tlv(wmi_unified_t wmi_handle, 15126 struct peer_request_rxpn_param *params) 15127 { 15128 wmi_peer_rx_pn_request_cmd_fixed_param *cmd; 15129 wmi_buf_t buf; 15130 uint8_t *buf_ptr; 15131 uint32_t len = sizeof(wmi_peer_rx_pn_request_cmd_fixed_param); 15132 15133 if (!is_service_enabled_tlv(wmi_handle, 15134 WMI_SERVICE_PN_REPLAY_CHECK_SUPPORT)) { 15135 wmi_err("Rx PN Replay Check not supported by target"); 15136 return QDF_STATUS_E_NOSUPPORT; 15137 } 15138 15139 buf = wmi_buf_alloc(wmi_handle, len); 15140 if (!buf) { 15141 wmi_err("wmi_buf_alloc failed"); 15142 return QDF_STATUS_E_FAILURE; 15143 } 15144 15145 buf_ptr = (uint8_t *)wmi_buf_data(buf); 15146 cmd = (wmi_peer_rx_pn_request_cmd_fixed_param *)buf_ptr; 15147 15148 WMITLV_SET_HDR(&cmd->tlv_header, 15149 WMITLV_TAG_STRUC_wmi_peer_rx_pn_request_cmd_fixed_param, 15150 WMITLV_GET_STRUCT_TLVLEN(wmi_peer_rx_pn_request_cmd_fixed_param)); 15151 15152 cmd->vdev_id = params->vdev_id; 15153 WMI_CHAR_ARRAY_TO_MAC_ADDR(params->peer_macaddr, &cmd->peer_macaddr); 15154 cmd->key_ix = params->keyix; 15155 if (wmi_unified_cmd_send(wmi_handle, buf, len, 15156 WMI_PEER_RX_PN_REQUEST_CMDID)) { 15157 wmi_err("Failed to send WMI command"); 15158 wmi_buf_free(buf); 15159 return QDF_STATUS_E_FAILURE; 15160 } 15161 return QDF_STATUS_SUCCESS; 15162 } 15163 15164 /** 15165 * extract_get_rxpn_data_tlv() - extract Rx PN resp 15166 * @wmi_handle: wmi handle 15167 * @evt_buf: pointer to event buffer 15168 * @params: Rx PN response params for peer 15169 * 15170 * Return: QDF_STATUS - success or error status 15171 */ 15172 static QDF_STATUS 15173 extract_get_rxpn_data_tlv(wmi_unified_t wmi_handle, void *evt_buf, 15174 struct wmi_host_get_rxpn_event *params) 15175 { 15176 WMI_PEER_RX_PN_RESPONSE_EVENTID_param_tlvs *param_buf; 15177 wmi_peer_rx_pn_response_event_fixed_param *event; 15178 15179 param_buf = evt_buf; 15180 event = param_buf->fixed_param; 15181 15182 params->vdev_id = event->vdev_id; 15183 params->keyix = event->key_idx; 15184 qdf_mem_copy(params->pn, event->pn, sizeof(event->pn)); 15185 WMI_MAC_ADDR_TO_CHAR_ARRAY(&event->peer_macaddr, params->mac_addr); 15186 15187 return QDF_STATUS_SUCCESS; 15188 } 15189 15190 /** 15191 * extract_fips_event_data_tlv() - extract fips event data 15192 * @wmi_handle: wmi handle 15193 * @evt_buf: pointer to event buffer 15194 * @param: pointer FIPS event params 15195 * 15196 * Return: QDF_STATUS_SUCCESS for success or error code 15197 */ 15198 static QDF_STATUS extract_fips_event_data_tlv(wmi_unified_t wmi_handle, 15199 void *evt_buf, struct wmi_host_fips_event_param *param) 15200 { 15201 WMI_PDEV_FIPS_EVENTID_param_tlvs *param_buf; 15202 wmi_pdev_fips_event_fixed_param *event; 15203 15204 param_buf = (WMI_PDEV_FIPS_EVENTID_param_tlvs *) evt_buf; 15205 event = (wmi_pdev_fips_event_fixed_param *) param_buf->fixed_param; 15206 15207 if (event->data_len > param_buf->num_data) 15208 return QDF_STATUS_E_FAILURE; 15209 15210 if (fips_conv_data_be(event->data_len, param_buf->data) != 15211 QDF_STATUS_SUCCESS) 15212 return QDF_STATUS_E_FAILURE; 15213 15214 param->data = (uint32_t *)param_buf->data; 15215 param->data_len = event->data_len; 15216 param->error_status = event->error_status; 15217 param->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host( 15218 wmi_handle, 15219 event->pdev_id); 15220 15221 return QDF_STATUS_SUCCESS; 15222 } 15223 15224 #ifdef WLAN_FEATURE_FIPS_BER_CCMGCM 15225 /** 15226 * extract_fips_extend_event_data_tlv() - extract fips event data 15227 * @wmi_handle: wmi handle 15228 * @evt_buf: pointer to event buffer 15229 * @param: pointer FIPS event params 15230 * 15231 * Return: QDF_STATUS_SUCCESS for success or error code 15232 */ 15233 static QDF_STATUS 15234 extract_fips_extend_event_data_tlv(wmi_unified_t wmi_handle, 15235 void *evt_buf, 15236 struct wmi_host_fips_extend_event_param 15237 *param) 15238 { 15239 WMI_PDEV_FIPS_EXTEND_EVENTID_param_tlvs *param_buf; 15240 wmi_pdev_fips_extend_event_fixed_param *event; 15241 15242 param_buf = (WMI_PDEV_FIPS_EXTEND_EVENTID_param_tlvs *)evt_buf; 15243 event = (wmi_pdev_fips_extend_event_fixed_param *)param_buf->fixed_param; 15244 15245 if (fips_conv_data_be(event->data_len, param_buf->data) != 15246 QDF_STATUS_SUCCESS) 15247 return QDF_STATUS_E_FAILURE; 15248 15249 param->data = (uint32_t *)param_buf->data; 15250 param->data_len = event->data_len; 15251 param->error_status = event->error_status; 15252 param->fips_cookie = event->fips_cookie; 15253 param->cmd_frag_idx = event->cmd_frag_idx; 15254 param->more_bit = event->more_bit; 15255 param->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host( 15256 wmi_handle, 15257 event->pdev_id); 15258 15259 return QDF_STATUS_SUCCESS; 15260 } 15261 #endif 15262 15263 #ifdef WLAN_FEATURE_DISA 15264 /** 15265 * extract_encrypt_decrypt_resp_event_tlv() - extract encrypt decrypt resp 15266 * params from event 15267 * @wmi_handle: wmi handle 15268 * @evt_buf: pointer to event buffer 15269 * @resp: Pointer to hold resp parameters 15270 * 15271 * Return: QDF_STATUS_SUCCESS for success or error code 15272 */ 15273 static QDF_STATUS 15274 extract_encrypt_decrypt_resp_event_tlv(wmi_unified_t wmi_handle, 15275 void *evt_buf, 15276 struct disa_encrypt_decrypt_resp_params 15277 *resp) 15278 { 15279 WMI_VDEV_ENCRYPT_DECRYPT_DATA_RESP_EVENTID_param_tlvs *param_buf; 15280 wmi_vdev_encrypt_decrypt_data_resp_event_fixed_param *data_event; 15281 15282 param_buf = evt_buf; 15283 if (!param_buf) { 15284 wmi_err("encrypt decrypt resp evt_buf is NULL"); 15285 return QDF_STATUS_E_INVAL; 15286 } 15287 15288 data_event = param_buf->fixed_param; 15289 15290 resp->vdev_id = data_event->vdev_id; 15291 resp->status = data_event->status; 15292 15293 if ((data_event->data_length > param_buf->num_enc80211_frame) || 15294 (data_event->data_length > WMI_SVC_MSG_MAX_SIZE - 15295 WMI_TLV_HDR_SIZE - sizeof(*data_event))) { 15296 wmi_err("FW msg data_len %d more than TLV hdr %d", 15297 data_event->data_length, 15298 param_buf->num_enc80211_frame); 15299 return QDF_STATUS_E_INVAL; 15300 } 15301 15302 resp->data_len = data_event->data_length; 15303 15304 if (resp->data_len) 15305 resp->data = (uint8_t *)param_buf->enc80211_frame; 15306 15307 return QDF_STATUS_SUCCESS; 15308 } 15309 #endif /* WLAN_FEATURE_DISA */ 15310 15311 static bool is_management_record_tlv(uint32_t cmd_id) 15312 { 15313 switch (cmd_id) { 15314 case WMI_MGMT_TX_SEND_CMDID: 15315 case WMI_MGMT_TX_COMPLETION_EVENTID: 15316 case WMI_OFFCHAN_DATA_TX_SEND_CMDID: 15317 case WMI_MGMT_RX_EVENTID: 15318 return true; 15319 default: 15320 return false; 15321 } 15322 } 15323 15324 static bool is_diag_event_tlv(uint32_t event_id) 15325 { 15326 if (WMI_DIAG_EVENTID == event_id) 15327 return true; 15328 15329 return false; 15330 } 15331 15332 static uint16_t wmi_tag_fw_hang_cmd(wmi_unified_t wmi_handle) 15333 { 15334 uint16_t tag = 0; 15335 15336 if (qdf_atomic_read(&wmi_handle->is_target_suspended)) { 15337 qdf_nofl_err("%s: Target is already suspended, Ignore FW Hang Command", 15338 __func__); 15339 return tag; 15340 } 15341 15342 if (wmi_handle->tag_crash_inject) 15343 tag = HTC_TX_PACKET_TAG_AUTO_PM; 15344 15345 wmi_handle->tag_crash_inject = false; 15346 return tag; 15347 } 15348 15349 /** 15350 * wmi_set_htc_tx_tag_tlv() - set HTC TX tag for WMI commands 15351 * @wmi_handle: WMI handle 15352 * @buf: WMI buffer 15353 * @cmd_id: WMI command Id 15354 * 15355 * Return: htc_tx_tag 15356 */ 15357 static uint16_t wmi_set_htc_tx_tag_tlv(wmi_unified_t wmi_handle, 15358 wmi_buf_t buf, 15359 uint32_t cmd_id) 15360 { 15361 uint16_t htc_tx_tag = 0; 15362 15363 switch (cmd_id) { 15364 case WMI_WOW_ENABLE_CMDID: 15365 case WMI_PDEV_SUSPEND_CMDID: 15366 case WMI_WOW_HOSTWAKEUP_FROM_SLEEP_CMDID: 15367 case WMI_PDEV_RESUME_CMDID: 15368 case WMI_HB_SET_ENABLE_CMDID: 15369 case WMI_WOW_SET_ACTION_WAKE_UP_CMDID: 15370 #ifdef FEATURE_WLAN_D0WOW 15371 case WMI_D0_WOW_ENABLE_DISABLE_CMDID: 15372 #endif 15373 htc_tx_tag = HTC_TX_PACKET_TAG_AUTO_PM; 15374 break; 15375 case WMI_FORCE_FW_HANG_CMDID: 15376 htc_tx_tag = wmi_tag_fw_hang_cmd(wmi_handle); 15377 break; 15378 default: 15379 break; 15380 } 15381 15382 return htc_tx_tag; 15383 } 15384 15385 #ifdef CONFIG_BAND_6GHZ 15386 15387 static struct cur_reg_rule 15388 *create_ext_reg_rules_from_wmi(uint32_t num_reg_rules, 15389 wmi_regulatory_rule_ext_struct *wmi_reg_rule) 15390 { 15391 struct cur_reg_rule *reg_rule_ptr; 15392 uint32_t count; 15393 15394 if (!num_reg_rules) 15395 return NULL; 15396 15397 reg_rule_ptr = qdf_mem_malloc(num_reg_rules * 15398 sizeof(*reg_rule_ptr)); 15399 15400 if (!reg_rule_ptr) 15401 return NULL; 15402 15403 for (count = 0; count < num_reg_rules; count++) { 15404 reg_rule_ptr[count].start_freq = 15405 WMI_REG_RULE_START_FREQ_GET( 15406 wmi_reg_rule[count].freq_info); 15407 reg_rule_ptr[count].end_freq = 15408 WMI_REG_RULE_END_FREQ_GET( 15409 wmi_reg_rule[count].freq_info); 15410 reg_rule_ptr[count].max_bw = 15411 WMI_REG_RULE_MAX_BW_GET( 15412 wmi_reg_rule[count].bw_pwr_info); 15413 reg_rule_ptr[count].reg_power = 15414 WMI_REG_RULE_REG_POWER_GET( 15415 wmi_reg_rule[count].bw_pwr_info); 15416 reg_rule_ptr[count].ant_gain = 15417 WMI_REG_RULE_ANTENNA_GAIN_GET( 15418 wmi_reg_rule[count].bw_pwr_info); 15419 reg_rule_ptr[count].flags = 15420 WMI_REG_RULE_FLAGS_GET( 15421 wmi_reg_rule[count].flag_info); 15422 reg_rule_ptr[count].psd_flag = 15423 WMI_REG_RULE_PSD_FLAG_GET( 15424 wmi_reg_rule[count].psd_power_info); 15425 reg_rule_ptr[count].psd_eirp = 15426 WMI_REG_RULE_PSD_EIRP_GET( 15427 wmi_reg_rule[count].psd_power_info); 15428 } 15429 15430 return reg_rule_ptr; 15431 } 15432 #endif 15433 15434 static struct cur_reg_rule 15435 *create_reg_rules_from_wmi(uint32_t num_reg_rules, 15436 wmi_regulatory_rule_struct *wmi_reg_rule) 15437 { 15438 struct cur_reg_rule *reg_rule_ptr; 15439 uint32_t count; 15440 15441 if (!num_reg_rules) 15442 return NULL; 15443 15444 reg_rule_ptr = qdf_mem_malloc(num_reg_rules * 15445 sizeof(*reg_rule_ptr)); 15446 15447 if (!reg_rule_ptr) 15448 return NULL; 15449 15450 for (count = 0; count < num_reg_rules; count++) { 15451 reg_rule_ptr[count].start_freq = 15452 WMI_REG_RULE_START_FREQ_GET( 15453 wmi_reg_rule[count].freq_info); 15454 reg_rule_ptr[count].end_freq = 15455 WMI_REG_RULE_END_FREQ_GET( 15456 wmi_reg_rule[count].freq_info); 15457 reg_rule_ptr[count].max_bw = 15458 WMI_REG_RULE_MAX_BW_GET( 15459 wmi_reg_rule[count].bw_pwr_info); 15460 reg_rule_ptr[count].reg_power = 15461 WMI_REG_RULE_REG_POWER_GET( 15462 wmi_reg_rule[count].bw_pwr_info); 15463 reg_rule_ptr[count].ant_gain = 15464 WMI_REG_RULE_ANTENNA_GAIN_GET( 15465 wmi_reg_rule[count].bw_pwr_info); 15466 reg_rule_ptr[count].flags = 15467 WMI_REG_RULE_FLAGS_GET( 15468 wmi_reg_rule[count].flag_info); 15469 } 15470 15471 return reg_rule_ptr; 15472 } 15473 15474 static enum cc_setting_code wmi_reg_status_to_reg_status( 15475 WMI_REG_SET_CC_STATUS_CODE wmi_status_code) 15476 { 15477 if (wmi_status_code == WMI_REG_SET_CC_STATUS_PASS) { 15478 wmi_nofl_debug("REG_SET_CC_STATUS_PASS"); 15479 return REG_SET_CC_STATUS_PASS; 15480 } else if (wmi_status_code == WMI_REG_CURRENT_ALPHA2_NOT_FOUND) { 15481 wmi_nofl_debug("WMI_REG_CURRENT_ALPHA2_NOT_FOUND"); 15482 return REG_CURRENT_ALPHA2_NOT_FOUND; 15483 } else if (wmi_status_code == WMI_REG_INIT_ALPHA2_NOT_FOUND) { 15484 wmi_nofl_debug("WMI_REG_INIT_ALPHA2_NOT_FOUND"); 15485 return REG_INIT_ALPHA2_NOT_FOUND; 15486 } else if (wmi_status_code == WMI_REG_SET_CC_CHANGE_NOT_ALLOWED) { 15487 wmi_nofl_debug("WMI_REG_SET_CC_CHANGE_NOT_ALLOWED"); 15488 return REG_SET_CC_CHANGE_NOT_ALLOWED; 15489 } else if (wmi_status_code == WMI_REG_SET_CC_STATUS_NO_MEMORY) { 15490 wmi_nofl_debug("WMI_REG_SET_CC_STATUS_NO_MEMORY"); 15491 return REG_SET_CC_STATUS_NO_MEMORY; 15492 } else if (wmi_status_code == WMI_REG_SET_CC_STATUS_FAIL) { 15493 wmi_nofl_debug("WMI_REG_SET_CC_STATUS_FAIL"); 15494 return REG_SET_CC_STATUS_FAIL; 15495 } 15496 15497 wmi_debug("Unknown reg status code from WMI"); 15498 return REG_SET_CC_STATUS_FAIL; 15499 } 15500 15501 #ifdef CONFIG_BAND_6GHZ 15502 /** 15503 * reg_print_ap_power_type_6ghz - Prints the AP Power type 15504 * @ap_type: 6ghz-AP Power type 15505 * 15506 * Return: void 15507 */ 15508 static void reg_print_ap_power_type_6ghz(enum reg_6g_ap_type ap_type) 15509 { 15510 switch (ap_type) { 15511 case REG_INDOOR_AP: 15512 wmi_nofl_debug("AP Power type %s", "LOW POWER INDOOR"); 15513 break; 15514 case REG_STANDARD_POWER_AP: 15515 wmi_nofl_debug("AP Power type %s", "STANDARD POWER"); 15516 break; 15517 case REG_VERY_LOW_POWER_AP: 15518 wmi_nofl_debug("AP Power type %s", "VERY LOW POWER INDOOR"); 15519 break; 15520 default: 15521 wmi_nofl_debug("Invalid AP Power type %u", ap_type); 15522 } 15523 } 15524 15525 /** 15526 * reg_print_6ghz_client_type - Prints the client type 15527 * @client_type: 6ghz-client type 15528 * 15529 * Return: void 15530 */ 15531 static void reg_print_6ghz_client_type(enum reg_6g_client_type client_type) 15532 { 15533 switch (client_type) { 15534 case REG_DEFAULT_CLIENT: 15535 wmi_nofl_debug("Client type %s", "DEFAULT CLIENT"); 15536 break; 15537 case REG_SUBORDINATE_CLIENT: 15538 wmi_nofl_debug("Client type %s", "SUBORDINATE CLIENT"); 15539 break; 15540 default: 15541 wmi_nofl_debug("Invalid Client type %u", client_type); 15542 } 15543 } 15544 #else 15545 static inline void reg_print_ap_power_type_6ghz(enum reg_6g_ap_type ap_type) 15546 { 15547 } 15548 15549 static inline void reg_print_6ghz_client_type(enum reg_6g_client_type client_type) 15550 { 15551 } 15552 #endif /* CONFIG_BAND_6GHZ */ 15553 15554 #ifdef CONFIG_BAND_6GHZ 15555 15556 #ifdef CONFIG_REG_CLIENT 15557 #define MAX_NUM_FCC_RULES 2 15558 15559 /** 15560 * extract_ext_fcc_rules_from_wmi - extract fcc rules from WMI TLV 15561 * @num_fcc_rules: Number of FCC rules 15562 * @wmi_fcc_rule: WMI FCC rules TLV 15563 * 15564 * Return: fcc_rule_ptr 15565 */ 15566 static struct cur_fcc_rule 15567 *extract_ext_fcc_rules_from_wmi(uint32_t num_fcc_rules, 15568 wmi_regulatory_fcc_rule_struct *wmi_fcc_rule) 15569 { 15570 struct cur_fcc_rule *fcc_rule_ptr; 15571 uint32_t count; 15572 15573 if (!wmi_fcc_rule) 15574 return NULL; 15575 15576 fcc_rule_ptr = qdf_mem_malloc(num_fcc_rules * 15577 sizeof(*fcc_rule_ptr)); 15578 if (!fcc_rule_ptr) 15579 return NULL; 15580 15581 for (count = 0; count < num_fcc_rules; count++) { 15582 fcc_rule_ptr[count].center_freq = 15583 WMI_REG_FCC_RULE_CHAN_FREQ_GET( 15584 wmi_fcc_rule[count].freq_info); 15585 fcc_rule_ptr[count].tx_power = 15586 WMI_REG_FCC_RULE_FCC_TX_POWER_GET( 15587 wmi_fcc_rule[count].freq_info); 15588 } 15589 15590 return fcc_rule_ptr; 15591 } 15592 15593 /** 15594 * extract_reg_fcc_rules_tlv - Extract reg fcc rules TLV 15595 * @param_buf: Pointer to WMI params TLV 15596 * @ext_chan_list_event_hdr: Pointer to REG CHAN LIST CC EXT EVENT Fixed 15597 * Params TLV 15598 * @ext_wmi_reg_rule: Pointer to REG CHAN LIST CC EXT EVENT Reg Rules TLV 15599 * @ext_wmi_chan_priority: Pointer to REG CHAN LIST CC EXT EVENT Chan 15600 * Priority TLV 15601 * @evt_buf: Pointer to REG CHAN LIST CC EXT EVENT event buffer 15602 * @reg_info: Pointer to Regulatory Info 15603 * @len: Length of REG CHAN LIST CC EXT EVENT buffer 15604 * 15605 * Return: QDF_STATUS 15606 */ 15607 static QDF_STATUS extract_reg_fcc_rules_tlv( 15608 WMI_REG_CHAN_LIST_CC_EXT_EVENTID_param_tlvs *param_buf, 15609 wmi_reg_chan_list_cc_event_ext_fixed_param *ext_chan_list_event_hdr, 15610 wmi_regulatory_rule_ext_struct *ext_wmi_reg_rule, 15611 wmi_regulatory_chan_priority_struct *ext_wmi_chan_priority, 15612 uint8_t *evt_buf, 15613 struct cur_regulatory_info *reg_info, 15614 uint32_t len) 15615 { 15616 int i; 15617 wmi_regulatory_fcc_rule_struct *ext_wmi_fcc_rule; 15618 15619 if (!param_buf) { 15620 wmi_err("invalid channel list event buf"); 15621 return QDF_STATUS_E_INVAL; 15622 } 15623 15624 reg_info->num_fcc_rules = 0; 15625 if (param_buf->reg_fcc_rule) { 15626 if (param_buf->num_reg_fcc_rule > MAX_NUM_FCC_RULES) { 15627 wmi_err("Number of fcc rules is greater than MAX_NUM_FCC_RULES"); 15628 return QDF_STATUS_E_INVAL; 15629 } 15630 15631 ext_wmi_fcc_rule = 15632 (wmi_regulatory_fcc_rule_struct *) 15633 ((uint8_t *)ext_chan_list_event_hdr + 15634 sizeof(wmi_reg_chan_list_cc_event_ext_fixed_param) + 15635 WMI_TLV_HDR_SIZE + 15636 sizeof(wmi_regulatory_rule_ext_struct) * 15637 param_buf->num_reg_rule_array + 15638 WMI_TLV_HDR_SIZE + 15639 sizeof(wmi_regulatory_chan_priority_struct) * 15640 param_buf->num_reg_chan_priority + 15641 WMI_TLV_HDR_SIZE); 15642 15643 reg_info->fcc_rules_ptr = extract_ext_fcc_rules_from_wmi( 15644 param_buf->num_reg_fcc_rule, 15645 ext_wmi_fcc_rule); 15646 15647 reg_info->num_fcc_rules = param_buf->num_reg_fcc_rule; 15648 } else { 15649 wmi_err("Fcc rules not sent by fw"); 15650 } 15651 15652 if (reg_info->fcc_rules_ptr) { 15653 for (i = 0; i < reg_info->num_fcc_rules; i++) { 15654 wmi_nofl_debug("FCC rule %d center_freq %d tx_power %d", 15655 i, reg_info->fcc_rules_ptr[i].center_freq, 15656 reg_info->fcc_rules_ptr[i].tx_power); 15657 } 15658 } 15659 return QDF_STATUS_SUCCESS; 15660 } 15661 #else 15662 static QDF_STATUS extract_reg_fcc_rules_tlv( 15663 WMI_REG_CHAN_LIST_CC_EXT_EVENTID_param_tlvs *param_buf, 15664 wmi_reg_chan_list_cc_event_ext_fixed_param *ext_chan_list_event_hdr, 15665 wmi_regulatory_rule_ext_struct *ext_wmi_reg_rule, 15666 wmi_regulatory_chan_priority_struct *ext_wmi_chan_priority, 15667 uint8_t *evt_buf, 15668 struct cur_regulatory_info *reg_info, 15669 uint32_t len) 15670 { 15671 return QDF_STATUS_SUCCESS; 15672 } 15673 #endif 15674 15675 static QDF_STATUS extract_reg_chan_list_ext_update_event_tlv( 15676 wmi_unified_t wmi_handle, uint8_t *evt_buf, 15677 struct cur_regulatory_info *reg_info, uint32_t len) 15678 { 15679 uint32_t i, j, k; 15680 WMI_REG_CHAN_LIST_CC_EXT_EVENTID_param_tlvs *param_buf; 15681 wmi_reg_chan_list_cc_event_ext_fixed_param *ext_chan_list_event_hdr; 15682 wmi_regulatory_rule_ext_struct *ext_wmi_reg_rule; 15683 wmi_regulatory_chan_priority_struct *ext_wmi_chan_priority; 15684 uint32_t num_2g_reg_rules, num_5g_reg_rules; 15685 uint32_t num_6g_reg_rules_ap[REG_CURRENT_MAX_AP_TYPE]; 15686 uint32_t *num_6g_reg_rules_client[REG_CURRENT_MAX_AP_TYPE]; 15687 uint32_t total_reg_rules = 0; 15688 QDF_STATUS status; 15689 15690 param_buf = (WMI_REG_CHAN_LIST_CC_EXT_EVENTID_param_tlvs *)evt_buf; 15691 if (!param_buf) { 15692 wmi_err("invalid channel list event buf"); 15693 return QDF_STATUS_E_FAILURE; 15694 } 15695 15696 ext_chan_list_event_hdr = param_buf->fixed_param; 15697 ext_wmi_chan_priority = param_buf->reg_chan_priority; 15698 15699 if (ext_wmi_chan_priority) 15700 reg_info->reg_6g_thresh_priority_freq = 15701 WMI_GET_BITS(ext_wmi_chan_priority->freq_info, 0, 16); 15702 reg_info->num_2g_reg_rules = ext_chan_list_event_hdr->num_2g_reg_rules; 15703 reg_info->num_5g_reg_rules = ext_chan_list_event_hdr->num_5g_reg_rules; 15704 reg_info->num_6g_reg_rules_ap[REG_STANDARD_POWER_AP] = 15705 ext_chan_list_event_hdr->num_6g_reg_rules_ap_sp; 15706 reg_info->num_6g_reg_rules_ap[REG_INDOOR_AP] = 15707 ext_chan_list_event_hdr->num_6g_reg_rules_ap_lpi; 15708 reg_info->num_6g_reg_rules_ap[REG_VERY_LOW_POWER_AP] = 15709 ext_chan_list_event_hdr->num_6g_reg_rules_ap_vlp; 15710 15711 wmi_debug("num reg rules from fw, AP SP %d, LPI %d, VLP %d", 15712 reg_info->num_6g_reg_rules_ap[REG_STANDARD_POWER_AP], 15713 reg_info->num_6g_reg_rules_ap[REG_INDOOR_AP], 15714 reg_info->num_6g_reg_rules_ap[REG_VERY_LOW_POWER_AP]); 15715 15716 for (i = 0; i < REG_MAX_CLIENT_TYPE; i++) { 15717 reg_info->num_6g_reg_rules_client[REG_STANDARD_POWER_AP][i] = 15718 ext_chan_list_event_hdr->num_6g_reg_rules_client_sp[i]; 15719 reg_info->num_6g_reg_rules_client[REG_INDOOR_AP][i] = 15720 ext_chan_list_event_hdr->num_6g_reg_rules_client_lpi[i]; 15721 reg_info->num_6g_reg_rules_client[REG_VERY_LOW_POWER_AP][i] = 15722 ext_chan_list_event_hdr->num_6g_reg_rules_client_vlp[i]; 15723 wmi_nofl_debug("client %d SP %d, LPI %d, VLP %d", i, 15724 ext_chan_list_event_hdr->num_6g_reg_rules_client_sp[i], 15725 ext_chan_list_event_hdr->num_6g_reg_rules_client_lpi[i], 15726 ext_chan_list_event_hdr->num_6g_reg_rules_client_vlp[i]); 15727 } 15728 15729 num_2g_reg_rules = reg_info->num_2g_reg_rules; 15730 total_reg_rules += num_2g_reg_rules; 15731 num_5g_reg_rules = reg_info->num_5g_reg_rules; 15732 total_reg_rules += num_5g_reg_rules; 15733 for (i = 0; i < REG_CURRENT_MAX_AP_TYPE; i++) { 15734 num_6g_reg_rules_ap[i] = reg_info->num_6g_reg_rules_ap[i]; 15735 if (num_6g_reg_rules_ap[i] > MAX_6G_REG_RULES) { 15736 wmi_err_rl("Invalid num_6g_reg_rules_ap: %u", 15737 num_6g_reg_rules_ap[i]); 15738 return QDF_STATUS_E_FAILURE; 15739 } 15740 total_reg_rules += num_6g_reg_rules_ap[i]; 15741 num_6g_reg_rules_client[i] = 15742 reg_info->num_6g_reg_rules_client[i]; 15743 } 15744 15745 for (i = 0; i < REG_MAX_CLIENT_TYPE; i++) { 15746 total_reg_rules += 15747 num_6g_reg_rules_client[REG_STANDARD_POWER_AP][i]; 15748 total_reg_rules += num_6g_reg_rules_client[REG_INDOOR_AP][i]; 15749 total_reg_rules += 15750 num_6g_reg_rules_client[REG_VERY_LOW_POWER_AP][i]; 15751 if ((num_6g_reg_rules_client[REG_STANDARD_POWER_AP][i] > 15752 MAX_6G_REG_RULES) || 15753 (num_6g_reg_rules_client[REG_INDOOR_AP][i] > 15754 MAX_6G_REG_RULES) || 15755 (num_6g_reg_rules_client[REG_VERY_LOW_POWER_AP][i] > 15756 MAX_6G_REG_RULES)) { 15757 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", 15758 num_6g_reg_rules_client[REG_STANDARD_POWER_AP][i], 15759 num_6g_reg_rules_client[REG_INDOOR_AP][i], 15760 num_6g_reg_rules_client[REG_VERY_LOW_POWER_AP][i], 15761 i); 15762 return QDF_STATUS_E_FAILURE; 15763 } 15764 } 15765 15766 if (total_reg_rules != param_buf->num_reg_rule_array) { 15767 wmi_err_rl("Total reg rules %u does not match event params num reg rule %u", 15768 total_reg_rules, param_buf->num_reg_rule_array); 15769 return QDF_STATUS_E_FAILURE; 15770 } 15771 15772 if ((num_2g_reg_rules > MAX_REG_RULES) || 15773 (num_5g_reg_rules > MAX_REG_RULES)) { 15774 wmi_err_rl("Invalid num_2g_reg_rules: %u, num_5g_reg_rules: %u", 15775 num_2g_reg_rules, num_5g_reg_rules); 15776 return QDF_STATUS_E_FAILURE; 15777 } 15778 15779 if ((num_6g_reg_rules_ap[REG_STANDARD_POWER_AP] > MAX_6G_REG_RULES) || 15780 (num_6g_reg_rules_ap[REG_INDOOR_AP] > MAX_6G_REG_RULES) || 15781 (num_6g_reg_rules_ap[REG_VERY_LOW_POWER_AP] > MAX_6G_REG_RULES)) { 15782 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", 15783 num_6g_reg_rules_ap[REG_STANDARD_POWER_AP], 15784 num_6g_reg_rules_ap[REG_INDOOR_AP], 15785 num_6g_reg_rules_ap[REG_VERY_LOW_POWER_AP]); 15786 return QDF_STATUS_E_FAILURE; 15787 } 15788 15789 if (param_buf->num_reg_rule_array > 15790 (WMI_SVC_MSG_MAX_SIZE - sizeof(*ext_chan_list_event_hdr)) / 15791 sizeof(*ext_wmi_reg_rule)) { 15792 wmi_err_rl("Invalid ext_num_reg_rule_array: %u", 15793 param_buf->num_reg_rule_array); 15794 return QDF_STATUS_E_FAILURE; 15795 } 15796 15797 qdf_mem_copy(reg_info->alpha2, &ext_chan_list_event_hdr->alpha2, 15798 REG_ALPHA2_LEN); 15799 reg_info->dfs_region = ext_chan_list_event_hdr->dfs_region; 15800 reg_info->phybitmap = convert_phybitmap_tlv( 15801 ext_chan_list_event_hdr->phybitmap); 15802 reg_info->offload_enabled = true; 15803 reg_info->num_phy = ext_chan_list_event_hdr->num_phy; 15804 reg_info->phy_id = wmi_handle->ops->convert_phy_id_target_to_host( 15805 wmi_handle, ext_chan_list_event_hdr->phy_id); 15806 reg_info->ctry_code = ext_chan_list_event_hdr->country_id; 15807 reg_info->reg_dmn_pair = ext_chan_list_event_hdr->domain_code; 15808 15809 reg_info->status_code = 15810 wmi_reg_status_to_reg_status(ext_chan_list_event_hdr-> 15811 status_code); 15812 15813 reg_info->min_bw_2g = ext_chan_list_event_hdr->min_bw_2g; 15814 reg_info->max_bw_2g = ext_chan_list_event_hdr->max_bw_2g; 15815 reg_info->min_bw_5g = ext_chan_list_event_hdr->min_bw_5g; 15816 reg_info->max_bw_5g = ext_chan_list_event_hdr->max_bw_5g; 15817 reg_info->min_bw_6g_ap[REG_STANDARD_POWER_AP] = 15818 ext_chan_list_event_hdr->min_bw_6g_ap_sp; 15819 reg_info->max_bw_6g_ap[REG_STANDARD_POWER_AP] = 15820 ext_chan_list_event_hdr->max_bw_6g_ap_sp; 15821 reg_info->min_bw_6g_ap[REG_INDOOR_AP] = 15822 ext_chan_list_event_hdr->min_bw_6g_ap_lpi; 15823 reg_info->max_bw_6g_ap[REG_INDOOR_AP] = 15824 ext_chan_list_event_hdr->max_bw_6g_ap_lpi; 15825 reg_info->min_bw_6g_ap[REG_VERY_LOW_POWER_AP] = 15826 ext_chan_list_event_hdr->min_bw_6g_ap_vlp; 15827 reg_info->max_bw_6g_ap[REG_VERY_LOW_POWER_AP] = 15828 ext_chan_list_event_hdr->max_bw_6g_ap_vlp; 15829 15830 for (i = 0; i < REG_MAX_CLIENT_TYPE; i++) { 15831 reg_info->min_bw_6g_client[REG_STANDARD_POWER_AP][i] = 15832 ext_chan_list_event_hdr->min_bw_6g_client_sp[i]; 15833 reg_info->max_bw_6g_client[REG_STANDARD_POWER_AP][i] = 15834 ext_chan_list_event_hdr->max_bw_6g_client_sp[i]; 15835 reg_info->min_bw_6g_client[REG_INDOOR_AP][i] = 15836 ext_chan_list_event_hdr->min_bw_6g_client_lpi[i]; 15837 reg_info->max_bw_6g_client[REG_INDOOR_AP][i] = 15838 ext_chan_list_event_hdr->max_bw_6g_client_lpi[i]; 15839 reg_info->min_bw_6g_client[REG_VERY_LOW_POWER_AP][i] = 15840 ext_chan_list_event_hdr->min_bw_6g_client_vlp[i]; 15841 reg_info->max_bw_6g_client[REG_VERY_LOW_POWER_AP][i] = 15842 ext_chan_list_event_hdr->max_bw_6g_client_vlp[i]; 15843 } 15844 15845 wmi_nofl_debug("num_phys = %u and phy_id = %u", 15846 reg_info->num_phy, reg_info->phy_id); 15847 15848 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", 15849 reg_info->alpha2, reg_info->dfs_region, reg_info->reg_dmn_pair, 15850 reg_info->min_bw_2g, reg_info->max_bw_2g, reg_info->min_bw_5g, 15851 reg_info->max_bw_5g); 15852 15853 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", 15854 reg_info->min_bw_6g_ap[REG_STANDARD_POWER_AP], 15855 reg_info->max_bw_6g_ap[REG_STANDARD_POWER_AP], 15856 reg_info->min_bw_6g_ap[REG_INDOOR_AP], 15857 reg_info->max_bw_6g_ap[REG_INDOOR_AP], 15858 reg_info->min_bw_6g_ap[REG_VERY_LOW_POWER_AP], 15859 reg_info->max_bw_6g_ap[REG_VERY_LOW_POWER_AP]); 15860 15861 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", 15862 reg_info->min_bw_6g_client[REG_STANDARD_POWER_AP][REG_DEFAULT_CLIENT], 15863 reg_info->max_bw_6g_client[REG_STANDARD_POWER_AP][REG_DEFAULT_CLIENT], 15864 reg_info->min_bw_6g_client[REG_INDOOR_AP][REG_DEFAULT_CLIENT], 15865 reg_info->max_bw_6g_client[REG_INDOOR_AP][REG_DEFAULT_CLIENT], 15866 reg_info->min_bw_6g_client[REG_VERY_LOW_POWER_AP][REG_DEFAULT_CLIENT], 15867 reg_info->max_bw_6g_client[REG_VERY_LOW_POWER_AP][REG_DEFAULT_CLIENT]); 15868 15869 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", 15870 reg_info->min_bw_6g_client[REG_STANDARD_POWER_AP][REG_SUBORDINATE_CLIENT], 15871 reg_info->max_bw_6g_client[REG_STANDARD_POWER_AP][REG_SUBORDINATE_CLIENT], 15872 reg_info->min_bw_6g_client[REG_INDOOR_AP][REG_SUBORDINATE_CLIENT], 15873 reg_info->max_bw_6g_client[REG_INDOOR_AP][REG_SUBORDINATE_CLIENT], 15874 reg_info->min_bw_6g_client[REG_VERY_LOW_POWER_AP][REG_SUBORDINATE_CLIENT], 15875 reg_info->max_bw_6g_client[REG_VERY_LOW_POWER_AP][REG_SUBORDINATE_CLIENT]); 15876 15877 wmi_nofl_debug("num_2g_reg_rules %d num_5g_reg_rules %d", 15878 num_2g_reg_rules, num_5g_reg_rules); 15879 15880 wmi_nofl_debug("num_6g_ap_sp_reg_rules %d num_6g_ap_lpi_reg_rules %d num_6g_ap_vlp_reg_rules %d", 15881 reg_info->num_6g_reg_rules_ap[REG_STANDARD_POWER_AP], 15882 reg_info->num_6g_reg_rules_ap[REG_INDOOR_AP], 15883 reg_info->num_6g_reg_rules_ap[REG_VERY_LOW_POWER_AP]); 15884 15885 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", 15886 reg_info->num_6g_reg_rules_client[REG_STANDARD_POWER_AP][REG_DEFAULT_CLIENT], 15887 reg_info->num_6g_reg_rules_client[REG_INDOOR_AP][REG_DEFAULT_CLIENT], 15888 reg_info->num_6g_reg_rules_client[REG_VERY_LOW_POWER_AP][REG_DEFAULT_CLIENT]); 15889 15890 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", 15891 reg_info->num_6g_reg_rules_client[REG_STANDARD_POWER_AP][REG_SUBORDINATE_CLIENT], 15892 reg_info->num_6g_reg_rules_client[REG_INDOOR_AP][REG_SUBORDINATE_CLIENT], 15893 reg_info->num_6g_reg_rules_client[REG_VERY_LOW_POWER_AP][REG_SUBORDINATE_CLIENT]); 15894 15895 ext_wmi_reg_rule = 15896 (wmi_regulatory_rule_ext_struct *) 15897 ((uint8_t *)ext_chan_list_event_hdr + 15898 sizeof(wmi_reg_chan_list_cc_event_ext_fixed_param) + 15899 WMI_TLV_HDR_SIZE); 15900 reg_info->reg_rules_2g_ptr = 15901 create_ext_reg_rules_from_wmi(num_2g_reg_rules, 15902 ext_wmi_reg_rule); 15903 ext_wmi_reg_rule += num_2g_reg_rules; 15904 if (!num_2g_reg_rules) 15905 wmi_nofl_debug("No 2ghz reg rule"); 15906 for (i = 0; i < num_2g_reg_rules; i++) { 15907 if (!reg_info->reg_rules_2g_ptr) 15908 break; 15909 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", 15910 i, reg_info->reg_rules_2g_ptr[i].start_freq, 15911 reg_info->reg_rules_2g_ptr[i].end_freq, 15912 reg_info->reg_rules_2g_ptr[i].max_bw, 15913 reg_info->reg_rules_2g_ptr[i].reg_power, 15914 reg_info->reg_rules_2g_ptr[i].ant_gain, 15915 reg_info->reg_rules_2g_ptr[i].flags, 15916 reg_info->reg_rules_2g_ptr[i].psd_flag, 15917 reg_info->reg_rules_2g_ptr[i].psd_eirp); 15918 } 15919 reg_info->reg_rules_5g_ptr = 15920 create_ext_reg_rules_from_wmi(num_5g_reg_rules, 15921 ext_wmi_reg_rule); 15922 ext_wmi_reg_rule += num_5g_reg_rules; 15923 if (!num_5g_reg_rules) 15924 wmi_nofl_debug("No 5ghz reg rule"); 15925 for (i = 0; i < num_5g_reg_rules; i++) { 15926 if (!reg_info->reg_rules_5g_ptr) 15927 break; 15928 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", 15929 i, reg_info->reg_rules_5g_ptr[i].start_freq, 15930 reg_info->reg_rules_5g_ptr[i].end_freq, 15931 reg_info->reg_rules_5g_ptr[i].max_bw, 15932 reg_info->reg_rules_5g_ptr[i].reg_power, 15933 reg_info->reg_rules_5g_ptr[i].ant_gain, 15934 reg_info->reg_rules_5g_ptr[i].flags, 15935 reg_info->reg_rules_5g_ptr[i].psd_flag, 15936 reg_info->reg_rules_5g_ptr[i].psd_eirp); 15937 } 15938 15939 for (i = 0; i < REG_CURRENT_MAX_AP_TYPE; i++) { 15940 reg_print_ap_power_type_6ghz(i); 15941 reg_info->reg_rules_6g_ap_ptr[i] = 15942 create_ext_reg_rules_from_wmi(num_6g_reg_rules_ap[i], 15943 ext_wmi_reg_rule); 15944 15945 ext_wmi_reg_rule += num_6g_reg_rules_ap[i]; 15946 if (!num_6g_reg_rules_ap[i]) 15947 wmi_nofl_debug("No 6ghz reg rule"); 15948 for (j = 0; j < num_6g_reg_rules_ap[i]; j++) { 15949 if (!reg_info->reg_rules_6g_ap_ptr[i]) 15950 break; 15951 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", 15952 j, reg_info->reg_rules_6g_ap_ptr[i][j].start_freq, 15953 reg_info->reg_rules_6g_ap_ptr[i][j].end_freq, 15954 reg_info->reg_rules_6g_ap_ptr[i][j].max_bw, 15955 reg_info->reg_rules_6g_ap_ptr[i][j].reg_power, 15956 reg_info->reg_rules_6g_ap_ptr[i][j].ant_gain, 15957 reg_info->reg_rules_6g_ap_ptr[i][j].flags, 15958 reg_info->reg_rules_6g_ap_ptr[i][j].psd_flag, 15959 reg_info->reg_rules_6g_ap_ptr[i][j].psd_eirp); 15960 } 15961 } 15962 15963 for (j = 0; j < REG_CURRENT_MAX_AP_TYPE; j++) { 15964 reg_print_ap_power_type_6ghz(j); 15965 for (i = 0; i < REG_MAX_CLIENT_TYPE; i++) { 15966 reg_print_6ghz_client_type(i); 15967 reg_info->reg_rules_6g_client_ptr[j][i] = 15968 create_ext_reg_rules_from_wmi( 15969 num_6g_reg_rules_client[j][i], 15970 ext_wmi_reg_rule); 15971 15972 ext_wmi_reg_rule += num_6g_reg_rules_client[j][i]; 15973 if (!num_6g_reg_rules_client[j][i]) 15974 wmi_nofl_debug("No 6ghz reg rule for [%d][%d]", j, i); 15975 for (k = 0; k < num_6g_reg_rules_client[j][i]; k++) { 15976 if (!reg_info->reg_rules_6g_client_ptr[j][i]) 15977 break; 15978 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", 15979 k, reg_info->reg_rules_6g_client_ptr[j][i][k].start_freq, 15980 reg_info->reg_rules_6g_client_ptr[j][i][k].end_freq, 15981 reg_info->reg_rules_6g_client_ptr[j][i][k].max_bw, 15982 reg_info->reg_rules_6g_client_ptr[j][i][k].reg_power, 15983 reg_info->reg_rules_6g_client_ptr[j][i][k].ant_gain, 15984 reg_info->reg_rules_6g_client_ptr[j][i][k].flags, 15985 reg_info->reg_rules_6g_client_ptr[j][i][k].psd_flag, 15986 reg_info->reg_rules_6g_client_ptr[j][i][k].psd_eirp); 15987 } 15988 } 15989 } 15990 15991 reg_info->client_type = ext_chan_list_event_hdr->client_type; 15992 reg_info->rnr_tpe_usable = ext_chan_list_event_hdr->rnr_tpe_usable; 15993 reg_info->unspecified_ap_usable = 15994 ext_chan_list_event_hdr->unspecified_ap_usable; 15995 reg_info->domain_code_6g_ap[REG_STANDARD_POWER_AP] = 15996 ext_chan_list_event_hdr->domain_code_6g_ap_sp; 15997 reg_info->domain_code_6g_ap[REG_INDOOR_AP] = 15998 ext_chan_list_event_hdr->domain_code_6g_ap_lpi; 15999 reg_info->domain_code_6g_ap[REG_VERY_LOW_POWER_AP] = 16000 ext_chan_list_event_hdr->domain_code_6g_ap_vlp; 16001 16002 wmi_nofl_debug("client type %d, RNR TPE usable %d, unspecified AP usable %d, domain code AP SP %d, LPI %d, VLP %d", 16003 reg_info->client_type, reg_info->rnr_tpe_usable, 16004 reg_info->unspecified_ap_usable, 16005 reg_info->domain_code_6g_ap[REG_STANDARD_POWER_AP], 16006 reg_info->domain_code_6g_ap[REG_INDOOR_AP], 16007 reg_info->domain_code_6g_ap[REG_VERY_LOW_POWER_AP]); 16008 16009 for (i = 0; i < REG_MAX_CLIENT_TYPE; i++) { 16010 reg_info->domain_code_6g_client[REG_STANDARD_POWER_AP][i] = 16011 ext_chan_list_event_hdr->domain_code_6g_client_sp[i]; 16012 reg_info->domain_code_6g_client[REG_INDOOR_AP][i] = 16013 ext_chan_list_event_hdr->domain_code_6g_client_lpi[i]; 16014 reg_info->domain_code_6g_client[REG_VERY_LOW_POWER_AP][i] = 16015 ext_chan_list_event_hdr->domain_code_6g_client_vlp[i]; 16016 wmi_nofl_debug("domain code client %d SP %d, LPI %d, VLP %d", i, 16017 reg_info->domain_code_6g_client[REG_STANDARD_POWER_AP][i], 16018 reg_info->domain_code_6g_client[REG_INDOOR_AP][i], 16019 reg_info->domain_code_6g_client[REG_VERY_LOW_POWER_AP][i]); 16020 } 16021 16022 reg_info->domain_code_6g_super_id = 16023 ext_chan_list_event_hdr->domain_code_6g_super_id; 16024 16025 status = extract_reg_fcc_rules_tlv(param_buf, ext_chan_list_event_hdr, 16026 ext_wmi_reg_rule, ext_wmi_chan_priority, 16027 evt_buf, reg_info, len); 16028 if (status != QDF_STATUS_SUCCESS) 16029 return status; 16030 16031 return QDF_STATUS_SUCCESS; 16032 } 16033 16034 #ifdef CONFIG_AFC_SUPPORT 16035 /** 16036 * copy_afc_chan_eirp_info() - Copy the channel EIRP object from 16037 * chan_eirp_power_info_hdr to the internal buffer chan_eirp_info. Since the 16038 * cfi and eirp is continuously filled in chan_eirp_power_info_hdr, there is 16039 * an index pointer required to store the current index of 16040 * chan_eirp_power_info_hdr, to fill into the chan_eirp_info object. 16041 * @chan_eirp_info: pointer to chan_eirp_info 16042 * @num_chans: Number of channels 16043 * @chan_eirp_power_info_hdr: Pointer to chan_eirp_power_info_hdr 16044 * @index: Pointer to index 16045 * 16046 * Return: void 16047 */ 16048 static void 16049 copy_afc_chan_eirp_info(struct chan_eirp_obj *chan_eirp_info, 16050 uint8_t num_chans, 16051 wmi_afc_chan_eirp_power_info *chan_eirp_power_info_hdr, 16052 uint8_t *index) 16053 { 16054 uint8_t chan_idx; 16055 16056 for (chan_idx = 0; chan_idx < num_chans; chan_idx++, (*index)++) { 16057 chan_eirp_info[chan_idx].cfi = 16058 chan_eirp_power_info_hdr[*index].channel_cfi; 16059 chan_eirp_info[chan_idx].eirp_power = 16060 chan_eirp_power_info_hdr[*index].eirp_pwr; 16061 wmi_debug("Chan idx = %d chan freq idx = %d EIRP power = %d", 16062 chan_idx, 16063 chan_eirp_info[chan_idx].cfi, 16064 chan_eirp_info[chan_idx].eirp_power); 16065 } 16066 } 16067 16068 /** 16069 * copy_afc_chan_obj_info() - Copy the channel object from channel_info_hdr to 16070 * to the internal buffer afc_chan_info. 16071 * @afc_chan_info: pointer to afc_chan_info 16072 * @num_chan_objs: Number of channel objects 16073 * @channel_info_hdr: Pointer to channel_info_hdr 16074 * @chan_eirp_power_info_hdr: Pointer to chan_eirp_power_info_hdr 16075 * 16076 * Return: void 16077 */ 16078 static void 16079 copy_afc_chan_obj_info(struct afc_chan_obj *afc_chan_info, 16080 uint8_t num_chan_objs, 16081 wmi_6g_afc_channel_info *channel_info_hdr, 16082 wmi_afc_chan_eirp_power_info *chan_eirp_power_info_hdr) 16083 { 16084 uint8_t count; 16085 uint8_t src_pwr_index = 0; 16086 16087 for (count = 0; count < num_chan_objs; count++) { 16088 afc_chan_info[count].global_opclass = 16089 channel_info_hdr[count].global_operating_class; 16090 afc_chan_info[count].num_chans = 16091 channel_info_hdr[count].num_channels; 16092 wmi_debug("Chan object count = %d global opclasss = %d", 16093 count, 16094 afc_chan_info[count].global_opclass); 16095 wmi_debug("Number of Channel EIRP objects = %d", 16096 afc_chan_info[count].num_chans); 16097 16098 if (afc_chan_info[count].num_chans > 0) { 16099 struct chan_eirp_obj *chan_eirp_info; 16100 16101 chan_eirp_info = 16102 qdf_mem_malloc(afc_chan_info[count].num_chans * 16103 sizeof(*chan_eirp_info)); 16104 16105 if (!chan_eirp_info) 16106 return; 16107 16108 copy_afc_chan_eirp_info(chan_eirp_info, 16109 afc_chan_info[count].num_chans, 16110 chan_eirp_power_info_hdr, 16111 &src_pwr_index); 16112 afc_chan_info[count].chan_eirp_info = chan_eirp_info; 16113 } else { 16114 wmi_err("Number of channels is zero in object idx %d", 16115 count); 16116 } 16117 } 16118 } 16119 16120 static void copy_afc_freq_obj_info(struct afc_freq_obj *afc_freq_info, 16121 uint8_t num_freq_objs, 16122 wmi_6g_afc_frequency_info *freq_info_hdr) 16123 { 16124 uint8_t count; 16125 16126 for (count = 0; count < num_freq_objs; count++) { 16127 afc_freq_info[count].low_freq = 16128 WMI_REG_RULE_START_FREQ_GET(freq_info_hdr[count].freq_info); 16129 afc_freq_info[count].high_freq = 16130 WMI_REG_RULE_END_FREQ_GET(freq_info_hdr[count].freq_info); 16131 afc_freq_info[count].max_psd = 16132 freq_info_hdr[count].psd_power_info; 16133 wmi_debug("count = %d low_freq = %d high_freq = %d max_psd = %d", 16134 count, 16135 afc_freq_info[count].low_freq, 16136 afc_freq_info[count].high_freq, 16137 afc_freq_info[count].max_psd); 16138 } 16139 } 16140 16141 /** 16142 * copy_afc_event_fixed_hdr_power_info() - Copy the fixed header portion of 16143 * the power event info from the WMI AFC event buffer to the internal buffer 16144 * power_info. 16145 * @power_info: pointer to power_info 16146 * @afc_power_event_hdr: pointer to afc_power_event_hdr 16147 * 16148 * Return: void 16149 */ 16150 static void 16151 copy_afc_event_fixed_hdr_power_info( 16152 struct reg_fw_afc_power_event *power_info, 16153 wmi_afc_power_event_param *afc_power_event_hdr) 16154 { 16155 power_info->fw_status_code = afc_power_event_hdr->fw_status_code; 16156 power_info->resp_id = afc_power_event_hdr->resp_id; 16157 power_info->serv_resp_code = afc_power_event_hdr->afc_serv_resp_code; 16158 power_info->afc_wfa_version = 16159 WMI_AFC_WFA_MINOR_VERSION_GET(afc_power_event_hdr->afc_wfa_version); 16160 power_info->afc_wfa_version |= 16161 WMI_AFC_WFA_MAJOR_VERSION_GET(afc_power_event_hdr->afc_wfa_version); 16162 16163 power_info->avail_exp_time_d = 16164 WMI_AVAIL_EXPIRY_TIME_DAY_GET(afc_power_event_hdr->avail_exp_time_d); 16165 power_info->avail_exp_time_d |= 16166 WMI_AVAIL_EXPIRY_TIME_MONTH_GET(afc_power_event_hdr->avail_exp_time_d); 16167 power_info->avail_exp_time_d |= 16168 WMI_AVAIL_EXPIRY_TIME_YEAR_GET(afc_power_event_hdr->avail_exp_time_d); 16169 16170 power_info->avail_exp_time_t = 16171 WMI_AVAIL_EXPIRY_TIME_SEC_GET(afc_power_event_hdr->avail_exp_time_t); 16172 power_info->avail_exp_time_t |= 16173 WMI_AVAIL_EXPIRY_TIME_MINUTE_GET(afc_power_event_hdr->avail_exp_time_t); 16174 power_info->avail_exp_time_t |= 16175 WMI_AVAIL_EXPIRY_TIME_HOUR_GET(afc_power_event_hdr->avail_exp_time_t); 16176 wmi_debug("FW status = %d resp_id = %d serv_resp_code = %d", 16177 power_info->fw_status_code, 16178 power_info->resp_id, 16179 power_info->serv_resp_code); 16180 wmi_debug("AFC version = %u exp_date = %u exp_time = %u", 16181 power_info->afc_wfa_version, 16182 power_info->avail_exp_time_d, 16183 power_info->avail_exp_time_t); 16184 } 16185 16186 /** 16187 * copy_power_event() - Copy the power event parameters from the AFC event 16188 * buffer to the power_info within the afc_info. 16189 * @afc_info: pointer to afc_info 16190 * @param_buf: pointer to param_buf 16191 * 16192 * Return: void 16193 */ 16194 static void copy_power_event(struct afc_regulatory_info *afc_info, 16195 WMI_AFC_EVENTID_param_tlvs *param_buf) 16196 { 16197 struct reg_fw_afc_power_event *power_info; 16198 wmi_afc_power_event_param *afc_power_event_hdr; 16199 struct afc_freq_obj *afc_freq_info; 16200 16201 power_info = qdf_mem_malloc(sizeof(*power_info)); 16202 16203 if (!power_info) 16204 return; 16205 16206 afc_power_event_hdr = param_buf->afc_power_event_param; 16207 copy_afc_event_fixed_hdr_power_info(power_info, afc_power_event_hdr); 16208 afc_info->power_info = power_info; 16209 16210 power_info->num_freq_objs = param_buf->num_freq_info_array; 16211 wmi_debug("Number of frequency objects = %d", 16212 power_info->num_freq_objs); 16213 if (power_info->num_freq_objs > 0) { 16214 wmi_6g_afc_frequency_info *freq_info_hdr; 16215 16216 freq_info_hdr = param_buf->freq_info_array; 16217 afc_freq_info = qdf_mem_malloc(power_info->num_freq_objs * 16218 sizeof(*afc_freq_info)); 16219 16220 if (!afc_freq_info) 16221 return; 16222 16223 copy_afc_freq_obj_info(afc_freq_info, power_info->num_freq_objs, 16224 freq_info_hdr); 16225 power_info->afc_freq_info = afc_freq_info; 16226 } else { 16227 wmi_err("Number of frequency objects is zero"); 16228 } 16229 16230 power_info->num_chan_objs = param_buf->num_channel_info_array; 16231 wmi_debug("Number of channel objects = %d", power_info->num_chan_objs); 16232 if (power_info->num_chan_objs > 0) { 16233 struct afc_chan_obj *afc_chan_info; 16234 wmi_6g_afc_channel_info *channel_info_hdr; 16235 16236 channel_info_hdr = param_buf->channel_info_array; 16237 afc_chan_info = qdf_mem_malloc(power_info->num_chan_objs * 16238 sizeof(*afc_chan_info)); 16239 16240 if (!afc_chan_info) 16241 return; 16242 16243 copy_afc_chan_obj_info(afc_chan_info, 16244 power_info->num_chan_objs, 16245 channel_info_hdr, 16246 param_buf->chan_eirp_power_info_array); 16247 power_info->afc_chan_info = afc_chan_info; 16248 } else { 16249 wmi_err("Number of channel objects is zero"); 16250 } 16251 } 16252 16253 static void copy_expiry_event(struct afc_regulatory_info *afc_info, 16254 WMI_AFC_EVENTID_param_tlvs *param_buf) 16255 { 16256 struct reg_afc_expiry_event *expiry_info; 16257 16258 expiry_info = qdf_mem_malloc(sizeof(*expiry_info)); 16259 16260 if (!expiry_info) 16261 return; 16262 16263 expiry_info->request_id = 16264 param_buf->expiry_event_param->request_id; 16265 expiry_info->event_subtype = 16266 param_buf->expiry_event_param->event_subtype; 16267 wmi_debug("Event subtype %d request ID %d", 16268 expiry_info->event_subtype, 16269 expiry_info->request_id); 16270 afc_info->expiry_info = expiry_info; 16271 } 16272 16273 /** 16274 * copy_afc_event_common_info() - Copy the phy_id and event_type parameters 16275 * in the AFC event. 'Common' indicates that these parameters are common for 16276 * WMI_AFC_EVENT_POWER_INFO and WMI_AFC_EVENT_TIMER_EXPIRY. 16277 * @wmi_handle: wmi handle 16278 * @afc_info: pointer to afc_info 16279 * @event_fixed_hdr: pointer to event_fixed_hdr 16280 * 16281 * Return: void 16282 */ 16283 static void 16284 copy_afc_event_common_info(wmi_unified_t wmi_handle, 16285 struct afc_regulatory_info *afc_info, 16286 wmi_afc_event_fixed_param *event_fixed_hdr) 16287 { 16288 afc_info->phy_id = wmi_handle->ops->convert_phy_id_target_to_host( 16289 wmi_handle, event_fixed_hdr->phy_id); 16290 wmi_debug("phy_id %d", afc_info->phy_id); 16291 afc_info->event_type = event_fixed_hdr->event_type; 16292 } 16293 16294 static QDF_STATUS extract_afc_event_tlv(wmi_unified_t wmi_handle, 16295 uint8_t *evt_buf, 16296 struct afc_regulatory_info *afc_info, 16297 uint32_t len) 16298 { 16299 WMI_AFC_EVENTID_param_tlvs *param_buf; 16300 wmi_afc_event_fixed_param *event_fixed_hdr; 16301 16302 param_buf = (WMI_AFC_EVENTID_param_tlvs *)evt_buf; 16303 if (!param_buf) { 16304 wmi_err("Invalid AFC event buf"); 16305 return QDF_STATUS_E_FAILURE; 16306 } 16307 16308 event_fixed_hdr = param_buf->fixed_param; 16309 copy_afc_event_common_info(wmi_handle, afc_info, event_fixed_hdr); 16310 wmi_debug("AFC event type %d received", afc_info->event_type); 16311 16312 switch (afc_info->event_type) { 16313 case WMI_AFC_EVENT_POWER_INFO: 16314 copy_power_event(afc_info, param_buf); 16315 break; 16316 case WMI_AFC_EVENT_TIMER_EXPIRY: 16317 copy_expiry_event(afc_info, param_buf); 16318 return QDF_STATUS_SUCCESS; 16319 default: 16320 wmi_err("Invalid event type"); 16321 return QDF_STATUS_E_FAILURE; 16322 } 16323 16324 return QDF_STATUS_SUCCESS; 16325 } 16326 #endif 16327 #endif 16328 16329 static QDF_STATUS extract_reg_chan_list_update_event_tlv( 16330 wmi_unified_t wmi_handle, uint8_t *evt_buf, 16331 struct cur_regulatory_info *reg_info, uint32_t len) 16332 { 16333 uint32_t i; 16334 WMI_REG_CHAN_LIST_CC_EVENTID_param_tlvs *param_buf; 16335 wmi_reg_chan_list_cc_event_fixed_param *chan_list_event_hdr; 16336 wmi_regulatory_rule_struct *wmi_reg_rule; 16337 uint32_t num_2g_reg_rules, num_5g_reg_rules; 16338 16339 wmi_debug("processing regulatory channel list"); 16340 16341 param_buf = (WMI_REG_CHAN_LIST_CC_EVENTID_param_tlvs *)evt_buf; 16342 if (!param_buf) { 16343 wmi_err("invalid channel list event buf"); 16344 return QDF_STATUS_E_FAILURE; 16345 } 16346 16347 chan_list_event_hdr = param_buf->fixed_param; 16348 16349 reg_info->num_2g_reg_rules = chan_list_event_hdr->num_2g_reg_rules; 16350 reg_info->num_5g_reg_rules = chan_list_event_hdr->num_5g_reg_rules; 16351 num_2g_reg_rules = reg_info->num_2g_reg_rules; 16352 num_5g_reg_rules = reg_info->num_5g_reg_rules; 16353 if ((num_2g_reg_rules > MAX_REG_RULES) || 16354 (num_5g_reg_rules > MAX_REG_RULES) || 16355 (num_2g_reg_rules + num_5g_reg_rules > MAX_REG_RULES) || 16356 (num_2g_reg_rules + num_5g_reg_rules != 16357 param_buf->num_reg_rule_array)) { 16358 wmi_err_rl("Invalid num_2g_reg_rules: %u, num_5g_reg_rules: %u", 16359 num_2g_reg_rules, num_5g_reg_rules); 16360 return QDF_STATUS_E_FAILURE; 16361 } 16362 if (param_buf->num_reg_rule_array > 16363 (WMI_SVC_MSG_MAX_SIZE - sizeof(*chan_list_event_hdr)) / 16364 sizeof(*wmi_reg_rule)) { 16365 wmi_err_rl("Invalid num_reg_rule_array: %u", 16366 param_buf->num_reg_rule_array); 16367 return QDF_STATUS_E_FAILURE; 16368 } 16369 16370 qdf_mem_copy(reg_info->alpha2, &(chan_list_event_hdr->alpha2), 16371 REG_ALPHA2_LEN); 16372 reg_info->dfs_region = chan_list_event_hdr->dfs_region; 16373 reg_info->phybitmap = convert_phybitmap_tlv( 16374 chan_list_event_hdr->phybitmap); 16375 reg_info->offload_enabled = true; 16376 reg_info->num_phy = chan_list_event_hdr->num_phy; 16377 reg_info->phy_id = wmi_handle->ops->convert_phy_id_target_to_host( 16378 wmi_handle, chan_list_event_hdr->phy_id); 16379 reg_info->ctry_code = chan_list_event_hdr->country_id; 16380 reg_info->reg_dmn_pair = chan_list_event_hdr->domain_code; 16381 16382 reg_info->status_code = 16383 wmi_reg_status_to_reg_status(chan_list_event_hdr->status_code); 16384 16385 reg_info->min_bw_2g = chan_list_event_hdr->min_bw_2g; 16386 reg_info->max_bw_2g = chan_list_event_hdr->max_bw_2g; 16387 reg_info->min_bw_5g = chan_list_event_hdr->min_bw_5g; 16388 reg_info->max_bw_5g = chan_list_event_hdr->max_bw_5g; 16389 16390 wmi_debug("num_phys = %u and phy_id = %u", 16391 reg_info->num_phy, reg_info->phy_id); 16392 16393 wmi_debug("cc %s dfs_region %d reg_dmn_pair %x BW: min_2g %d max_2g %d min_5g %d max_5g %d", 16394 reg_info->alpha2, reg_info->dfs_region, reg_info->reg_dmn_pair, 16395 reg_info->min_bw_2g, reg_info->max_bw_2g, 16396 reg_info->min_bw_5g, reg_info->max_bw_5g); 16397 16398 wmi_debug("num_2g_reg_rules %d num_5g_reg_rules %d", 16399 num_2g_reg_rules, num_5g_reg_rules); 16400 wmi_reg_rule = 16401 (wmi_regulatory_rule_struct *)((uint8_t *)chan_list_event_hdr 16402 + sizeof(wmi_reg_chan_list_cc_event_fixed_param) 16403 + WMI_TLV_HDR_SIZE); 16404 reg_info->reg_rules_2g_ptr = create_reg_rules_from_wmi(num_2g_reg_rules, 16405 wmi_reg_rule); 16406 wmi_reg_rule += num_2g_reg_rules; 16407 if (!num_2g_reg_rules) 16408 wmi_nofl_debug("No 2ghz reg rule"); 16409 for (i = 0; i < num_2g_reg_rules; i++) { 16410 if (!reg_info->reg_rules_2g_ptr) 16411 break; 16412 wmi_nofl_debug("2 GHz rule %u start freq %u end freq %u max_bw %u reg_power %u ant_gain %u flags %u", 16413 i, reg_info->reg_rules_2g_ptr[i].start_freq, 16414 reg_info->reg_rules_2g_ptr[i].end_freq, 16415 reg_info->reg_rules_2g_ptr[i].max_bw, 16416 reg_info->reg_rules_2g_ptr[i].reg_power, 16417 reg_info->reg_rules_2g_ptr[i].ant_gain, 16418 reg_info->reg_rules_2g_ptr[i].flags); 16419 } 16420 16421 reg_info->reg_rules_5g_ptr = create_reg_rules_from_wmi(num_5g_reg_rules, 16422 wmi_reg_rule); 16423 if (!num_5g_reg_rules) 16424 wmi_nofl_debug("No 5ghz reg rule"); 16425 for (i = 0; i < num_5g_reg_rules; i++) { 16426 if (!reg_info->reg_rules_5g_ptr) 16427 break; 16428 wmi_nofl_debug("5 GHz rule %u start freq %u end freq %u max_bw %u reg_power %u ant_gain %u flags %u", 16429 i, reg_info->reg_rules_5g_ptr[i].start_freq, 16430 reg_info->reg_rules_5g_ptr[i].end_freq, 16431 reg_info->reg_rules_5g_ptr[i].max_bw, 16432 reg_info->reg_rules_5g_ptr[i].reg_power, 16433 reg_info->reg_rules_5g_ptr[i].ant_gain, 16434 reg_info->reg_rules_5g_ptr[i].flags); 16435 } 16436 16437 wmi_debug("processed regulatory channel list"); 16438 16439 return QDF_STATUS_SUCCESS; 16440 } 16441 16442 static QDF_STATUS extract_reg_11d_new_country_event_tlv( 16443 wmi_unified_t wmi_handle, uint8_t *evt_buf, 16444 struct reg_11d_new_country *reg_11d_country, uint32_t len) 16445 { 16446 wmi_11d_new_country_event_fixed_param *reg_11d_country_event; 16447 WMI_11D_NEW_COUNTRY_EVENTID_param_tlvs *param_buf; 16448 16449 param_buf = (WMI_11D_NEW_COUNTRY_EVENTID_param_tlvs *)evt_buf; 16450 if (!param_buf) { 16451 wmi_err("invalid 11d country event buf"); 16452 return QDF_STATUS_E_FAILURE; 16453 } 16454 16455 reg_11d_country_event = param_buf->fixed_param; 16456 16457 qdf_mem_copy(reg_11d_country->alpha2, 16458 ®_11d_country_event->new_alpha2, REG_ALPHA2_LEN); 16459 reg_11d_country->alpha2[REG_ALPHA2_LEN] = '\0'; 16460 16461 wmi_debug("processed 11d country event, new cc %s", 16462 reg_11d_country->alpha2); 16463 16464 return QDF_STATUS_SUCCESS; 16465 } 16466 16467 static QDF_STATUS extract_reg_ch_avoid_event_tlv( 16468 wmi_unified_t wmi_handle, uint8_t *evt_buf, 16469 struct ch_avoid_ind_type *ch_avoid_ind, uint32_t len) 16470 { 16471 wmi_avoid_freq_ranges_event_fixed_param *afr_fixed_param; 16472 wmi_avoid_freq_range_desc *afr_desc; 16473 uint32_t num_freq_ranges, freq_range_idx; 16474 WMI_WLAN_FREQ_AVOID_EVENTID_param_tlvs *param_buf = 16475 (WMI_WLAN_FREQ_AVOID_EVENTID_param_tlvs *) evt_buf; 16476 16477 if (!param_buf) { 16478 wmi_err("Invalid channel avoid event buffer"); 16479 return QDF_STATUS_E_INVAL; 16480 } 16481 16482 afr_fixed_param = param_buf->fixed_param; 16483 if (!afr_fixed_param) { 16484 wmi_err("Invalid channel avoid event fixed param buffer"); 16485 return QDF_STATUS_E_INVAL; 16486 } 16487 16488 if (!ch_avoid_ind) { 16489 wmi_err("Invalid channel avoid indication buffer"); 16490 return QDF_STATUS_E_INVAL; 16491 } 16492 if (param_buf->num_avd_freq_range < afr_fixed_param->num_freq_ranges) { 16493 wmi_err("no.of freq ranges exceeded the limit"); 16494 return QDF_STATUS_E_INVAL; 16495 } 16496 num_freq_ranges = (afr_fixed_param->num_freq_ranges > 16497 CH_AVOID_MAX_RANGE) ? CH_AVOID_MAX_RANGE : 16498 afr_fixed_param->num_freq_ranges; 16499 16500 wmi_debug("Channel avoid event received with %d ranges", 16501 num_freq_ranges); 16502 16503 ch_avoid_ind->ch_avoid_range_cnt = num_freq_ranges; 16504 afr_desc = (wmi_avoid_freq_range_desc *)(param_buf->avd_freq_range); 16505 for (freq_range_idx = 0; freq_range_idx < num_freq_ranges; 16506 freq_range_idx++) { 16507 ch_avoid_ind->avoid_freq_range[freq_range_idx].start_freq = 16508 afr_desc->start_freq; 16509 ch_avoid_ind->avoid_freq_range[freq_range_idx].end_freq = 16510 afr_desc->end_freq; 16511 wmi_debug("range %d tlv id %u, start freq %u, end freq %u", 16512 freq_range_idx, afr_desc->tlv_header, 16513 afr_desc->start_freq, afr_desc->end_freq); 16514 afr_desc++; 16515 } 16516 16517 return QDF_STATUS_SUCCESS; 16518 } 16519 16520 #ifdef DFS_COMPONENT_ENABLE 16521 /** 16522 * extract_dfs_cac_complete_event_tlv() - extract cac complete event 16523 * @wmi_handle: wma handle 16524 * @evt_buf: event buffer 16525 * @vdev_id: vdev id 16526 * @len: length of buffer 16527 * 16528 * Return: QDF_STATUS_SUCCESS for success or error code 16529 */ 16530 static QDF_STATUS extract_dfs_cac_complete_event_tlv(wmi_unified_t wmi_handle, 16531 uint8_t *evt_buf, 16532 uint32_t *vdev_id, 16533 uint32_t len) 16534 { 16535 WMI_VDEV_DFS_CAC_COMPLETE_EVENTID_param_tlvs *param_tlvs; 16536 wmi_vdev_dfs_cac_complete_event_fixed_param *cac_event; 16537 16538 param_tlvs = (WMI_VDEV_DFS_CAC_COMPLETE_EVENTID_param_tlvs *) evt_buf; 16539 if (!param_tlvs) { 16540 wmi_err("invalid cac complete event buf"); 16541 return QDF_STATUS_E_FAILURE; 16542 } 16543 16544 cac_event = param_tlvs->fixed_param; 16545 *vdev_id = cac_event->vdev_id; 16546 wmi_debug("processed cac complete event vdev %d", *vdev_id); 16547 16548 return QDF_STATUS_SUCCESS; 16549 } 16550 16551 /** 16552 * extract_dfs_ocac_complete_event_tlv() - extract cac complete event 16553 * @wmi_handle: wma handle 16554 * @evt_buf: event buffer 16555 * @param: extracted event 16556 * 16557 * Return: QDF_STATUS_SUCCESS for success or error code 16558 */ 16559 static QDF_STATUS 16560 extract_dfs_ocac_complete_event_tlv(wmi_unified_t wmi_handle, 16561 uint8_t *evt_buf, 16562 struct vdev_adfs_complete_status *param) 16563 { 16564 WMI_VDEV_ADFS_OCAC_COMPLETE_EVENTID_param_tlvs *param_tlvs; 16565 wmi_vdev_adfs_ocac_complete_event_fixed_param *ocac_complete_status; 16566 16567 param_tlvs = (WMI_VDEV_ADFS_OCAC_COMPLETE_EVENTID_param_tlvs *)evt_buf; 16568 if (!param_tlvs) { 16569 wmi_err("invalid ocac complete event buf"); 16570 return QDF_STATUS_E_FAILURE; 16571 } 16572 16573 if (!param_tlvs->fixed_param) { 16574 wmi_err("invalid param_tlvs->fixed_param"); 16575 return QDF_STATUS_E_FAILURE; 16576 } 16577 16578 ocac_complete_status = param_tlvs->fixed_param; 16579 param->vdev_id = ocac_complete_status->vdev_id; 16580 param->chan_freq = ocac_complete_status->chan_freq; 16581 param->center_freq1 = ocac_complete_status->center_freq1; 16582 param->center_freq2 = ocac_complete_status->center_freq2; 16583 param->ocac_status = ocac_complete_status->status; 16584 param->chan_width = ocac_complete_status->chan_width; 16585 wmi_debug("processed ocac complete event vdev %d" 16586 " agile chan %d %d width %d status %d", 16587 param->vdev_id, 16588 param->center_freq1, 16589 param->center_freq2, 16590 param->chan_width, 16591 param->ocac_status); 16592 16593 return QDF_STATUS_SUCCESS; 16594 } 16595 16596 /** 16597 * extract_dfs_radar_detection_event_tlv() - extract radar found event 16598 * @wmi_handle: wma handle 16599 * @evt_buf: event buffer 16600 * @radar_found: radar found event info 16601 * @len: length of buffer 16602 * 16603 * Return: QDF_STATUS_SUCCESS for success or error code 16604 */ 16605 static QDF_STATUS extract_dfs_radar_detection_event_tlv( 16606 wmi_unified_t wmi_handle, 16607 uint8_t *evt_buf, 16608 struct radar_found_info *radar_found, 16609 uint32_t len) 16610 { 16611 WMI_PDEV_DFS_RADAR_DETECTION_EVENTID_param_tlvs *param_tlv; 16612 wmi_pdev_dfs_radar_detection_event_fixed_param *radar_event; 16613 16614 param_tlv = (WMI_PDEV_DFS_RADAR_DETECTION_EVENTID_param_tlvs *) evt_buf; 16615 if (!param_tlv) { 16616 wmi_err("invalid radar detection event buf"); 16617 return QDF_STATUS_E_FAILURE; 16618 } 16619 16620 radar_event = param_tlv->fixed_param; 16621 16622 radar_found->pdev_id = convert_target_pdev_id_to_host_pdev_id( 16623 wmi_handle, 16624 radar_event->pdev_id); 16625 16626 if (radar_found->pdev_id == WMI_HOST_PDEV_ID_INVALID) 16627 return QDF_STATUS_E_FAILURE; 16628 16629 radar_found->detection_mode = radar_event->detection_mode; 16630 radar_found->chan_freq = radar_event->chan_freq; 16631 radar_found->chan_width = radar_event->chan_width; 16632 radar_found->detector_id = radar_event->detector_id; 16633 radar_found->segment_id = radar_event->segment_id; 16634 radar_found->timestamp = radar_event->timestamp; 16635 radar_found->is_chirp = radar_event->is_chirp; 16636 radar_found->freq_offset = radar_event->freq_offset; 16637 radar_found->sidx = radar_event->sidx; 16638 16639 wmi_debug("processed radar found event pdev %d," 16640 "Radar Event Info:pdev_id %d,timestamp %d,chan_freq (dur) %d," 16641 "chan_width (RSSI) %d,detector_id (false_radar) %d," 16642 "freq_offset (radar_check) %d,segment_id %d,sidx %d," 16643 "is_chirp %d,detection mode %d", 16644 radar_event->pdev_id, radar_found->pdev_id, 16645 radar_event->timestamp, radar_event->chan_freq, 16646 radar_event->chan_width, radar_event->detector_id, 16647 radar_event->freq_offset, radar_event->segment_id, 16648 radar_event->sidx, radar_event->is_chirp, 16649 radar_event->detection_mode); 16650 16651 return QDF_STATUS_SUCCESS; 16652 } 16653 16654 #ifdef MOBILE_DFS_SUPPORT 16655 /** 16656 * extract_wlan_radar_event_info_tlv() - extract radar pulse event 16657 * @wmi_handle: wma handle 16658 * @evt_buf: event buffer 16659 * @wlan_radar_event: Pointer to struct radar_event_info 16660 * @len: length of buffer 16661 * 16662 * Return: QDF_STATUS 16663 */ 16664 static QDF_STATUS extract_wlan_radar_event_info_tlv( 16665 wmi_unified_t wmi_handle, 16666 uint8_t *evt_buf, 16667 struct radar_event_info *wlan_radar_event, 16668 uint32_t len) 16669 { 16670 WMI_DFS_RADAR_EVENTID_param_tlvs *param_tlv; 16671 wmi_dfs_radar_event_fixed_param *radar_event; 16672 16673 param_tlv = (WMI_DFS_RADAR_EVENTID_param_tlvs *)evt_buf; 16674 if (!param_tlv) { 16675 wmi_err("invalid wlan radar event buf"); 16676 return QDF_STATUS_E_FAILURE; 16677 } 16678 16679 radar_event = param_tlv->fixed_param; 16680 wlan_radar_event->pulse_is_chirp = radar_event->pulse_is_chirp; 16681 wlan_radar_event->pulse_center_freq = radar_event->pulse_center_freq; 16682 wlan_radar_event->pulse_duration = radar_event->pulse_duration; 16683 wlan_radar_event->rssi = radar_event->rssi; 16684 wlan_radar_event->pulse_detect_ts = radar_event->pulse_detect_ts; 16685 wlan_radar_event->upload_fullts_high = radar_event->upload_fullts_high; 16686 wlan_radar_event->upload_fullts_low = radar_event->upload_fullts_low; 16687 wlan_radar_event->peak_sidx = radar_event->peak_sidx; 16688 wlan_radar_event->delta_peak = radar_event->pulse_delta_peak; 16689 wlan_radar_event->delta_diff = radar_event->pulse_delta_diff; 16690 if (radar_event->pulse_flags & 16691 WMI_DFS_RADAR_PULSE_FLAG_MASK_PSIDX_DIFF_VALID) { 16692 wlan_radar_event->is_psidx_diff_valid = true; 16693 wlan_radar_event->psidx_diff = radar_event->psidx_diff; 16694 } else { 16695 wlan_radar_event->is_psidx_diff_valid = false; 16696 } 16697 16698 wlan_radar_event->pdev_id = radar_event->pdev_id; 16699 16700 return QDF_STATUS_SUCCESS; 16701 } 16702 #else 16703 static QDF_STATUS extract_wlan_radar_event_info_tlv( 16704 wmi_unified_t wmi_handle, 16705 uint8_t *evt_buf, 16706 struct radar_event_info *wlan_radar_event, 16707 uint32_t len) 16708 { 16709 return QDF_STATUS_SUCCESS; 16710 } 16711 #endif 16712 #endif 16713 16714 /** 16715 * send_get_rcpi_cmd_tlv() - send request for rcpi value 16716 * @wmi_handle: wmi handle 16717 * @get_rcpi_param: rcpi params 16718 * 16719 * Return: QDF status 16720 */ 16721 static QDF_STATUS send_get_rcpi_cmd_tlv(wmi_unified_t wmi_handle, 16722 struct rcpi_req *get_rcpi_param) 16723 { 16724 wmi_buf_t buf; 16725 wmi_request_rcpi_cmd_fixed_param *cmd; 16726 uint8_t len = sizeof(wmi_request_rcpi_cmd_fixed_param); 16727 16728 buf = wmi_buf_alloc(wmi_handle, len); 16729 if (!buf) 16730 return QDF_STATUS_E_NOMEM; 16731 16732 cmd = (wmi_request_rcpi_cmd_fixed_param *) wmi_buf_data(buf); 16733 WMITLV_SET_HDR(&cmd->tlv_header, 16734 WMITLV_TAG_STRUC_wmi_request_rcpi_cmd_fixed_param, 16735 WMITLV_GET_STRUCT_TLVLEN 16736 (wmi_request_rcpi_cmd_fixed_param)); 16737 16738 cmd->vdev_id = get_rcpi_param->vdev_id; 16739 WMI_CHAR_ARRAY_TO_MAC_ADDR(get_rcpi_param->mac_addr, 16740 &cmd->peer_macaddr); 16741 16742 switch (get_rcpi_param->measurement_type) { 16743 16744 case RCPI_MEASUREMENT_TYPE_AVG_MGMT: 16745 cmd->measurement_type = WMI_RCPI_MEASUREMENT_TYPE_AVG_MGMT; 16746 break; 16747 16748 case RCPI_MEASUREMENT_TYPE_AVG_DATA: 16749 cmd->measurement_type = WMI_RCPI_MEASUREMENT_TYPE_AVG_DATA; 16750 break; 16751 16752 case RCPI_MEASUREMENT_TYPE_LAST_MGMT: 16753 cmd->measurement_type = WMI_RCPI_MEASUREMENT_TYPE_LAST_MGMT; 16754 break; 16755 16756 case RCPI_MEASUREMENT_TYPE_LAST_DATA: 16757 cmd->measurement_type = WMI_RCPI_MEASUREMENT_TYPE_LAST_DATA; 16758 break; 16759 16760 default: 16761 /* 16762 * invalid rcpi measurement type, fall back to 16763 * RCPI_MEASUREMENT_TYPE_AVG_MGMT 16764 */ 16765 cmd->measurement_type = WMI_RCPI_MEASUREMENT_TYPE_AVG_MGMT; 16766 break; 16767 } 16768 wmi_debug("RCPI REQ VDEV_ID:%d-->", cmd->vdev_id); 16769 wmi_mtrace(WMI_REQUEST_RCPI_CMDID, cmd->vdev_id, 0); 16770 if (wmi_unified_cmd_send(wmi_handle, buf, len, 16771 WMI_REQUEST_RCPI_CMDID)) { 16772 16773 wmi_err("Failed to send WMI_REQUEST_RCPI_CMDID"); 16774 wmi_buf_free(buf); 16775 return QDF_STATUS_E_FAILURE; 16776 } 16777 16778 return QDF_STATUS_SUCCESS; 16779 } 16780 16781 /** 16782 * extract_rcpi_response_event_tlv() - Extract RCPI event params 16783 * @wmi_handle: wmi handle 16784 * @evt_buf: pointer to event buffer 16785 * @res: pointer to hold rcpi response from firmware 16786 * 16787 * Return: QDF_STATUS_SUCCESS for successful event parse 16788 * else QDF_STATUS_E_INVAL or QDF_STATUS_E_FAILURE 16789 */ 16790 static QDF_STATUS 16791 extract_rcpi_response_event_tlv(wmi_unified_t wmi_handle, 16792 void *evt_buf, struct rcpi_res *res) 16793 { 16794 WMI_UPDATE_RCPI_EVENTID_param_tlvs *param_buf; 16795 wmi_update_rcpi_event_fixed_param *event; 16796 16797 param_buf = (WMI_UPDATE_RCPI_EVENTID_param_tlvs *)evt_buf; 16798 if (!param_buf) { 16799 wmi_err("Invalid rcpi event"); 16800 return QDF_STATUS_E_INVAL; 16801 } 16802 16803 event = param_buf->fixed_param; 16804 res->vdev_id = event->vdev_id; 16805 WMI_MAC_ADDR_TO_CHAR_ARRAY(&event->peer_macaddr, res->mac_addr); 16806 16807 switch (event->measurement_type) { 16808 16809 case WMI_RCPI_MEASUREMENT_TYPE_AVG_MGMT: 16810 res->measurement_type = RCPI_MEASUREMENT_TYPE_AVG_MGMT; 16811 break; 16812 16813 case WMI_RCPI_MEASUREMENT_TYPE_AVG_DATA: 16814 res->measurement_type = RCPI_MEASUREMENT_TYPE_AVG_DATA; 16815 break; 16816 16817 case WMI_RCPI_MEASUREMENT_TYPE_LAST_MGMT: 16818 res->measurement_type = RCPI_MEASUREMENT_TYPE_LAST_MGMT; 16819 break; 16820 16821 case WMI_RCPI_MEASUREMENT_TYPE_LAST_DATA: 16822 res->measurement_type = RCPI_MEASUREMENT_TYPE_LAST_DATA; 16823 break; 16824 16825 default: 16826 wmi_err("Invalid rcpi measurement type from firmware"); 16827 res->measurement_type = RCPI_MEASUREMENT_TYPE_INVALID; 16828 return QDF_STATUS_E_FAILURE; 16829 } 16830 16831 if (event->status) 16832 return QDF_STATUS_E_FAILURE; 16833 else 16834 return QDF_STATUS_SUCCESS; 16835 } 16836 16837 /** 16838 * convert_host_pdev_id_to_target_pdev_id_legacy() - Convert pdev_id from 16839 * host to target defines. For legacy there is not conversion 16840 * required. Just return pdev_id as it is. 16841 * @wmi_handle: handle to WMI. 16842 * @pdev_id: host pdev_id to be converted. 16843 * Return: target pdev_id after conversion. 16844 */ 16845 static uint32_t convert_host_pdev_id_to_target_pdev_id_legacy( 16846 wmi_unified_t wmi_handle, 16847 uint32_t pdev_id) 16848 { 16849 if (pdev_id == WMI_HOST_PDEV_ID_SOC) 16850 return WMI_PDEV_ID_SOC; 16851 16852 /*No conversion required*/ 16853 return pdev_id; 16854 } 16855 16856 /** 16857 * convert_target_pdev_id_to_host_pdev_id_legacy() - Convert pdev_id from 16858 * target to host defines. For legacy there is not conversion 16859 * required. Just return pdev_id as it is. 16860 * @wmi_handle: handle to WMI. 16861 * @pdev_id: target pdev_id to be converted. 16862 * Return: host pdev_id after conversion. 16863 */ 16864 static uint32_t convert_target_pdev_id_to_host_pdev_id_legacy( 16865 wmi_unified_t wmi_handle, 16866 uint32_t pdev_id) 16867 { 16868 /*No conversion required*/ 16869 return pdev_id; 16870 } 16871 16872 /** 16873 * convert_host_phy_id_to_target_phy_id_legacy() - Convert phy_id from 16874 * host to target defines. For legacy there is not conversion 16875 * required. Just return phy_id as it is. 16876 * @wmi_handle: handle to WMI. 16877 * @phy_id: host phy_id to be converted. 16878 * 16879 * Return: target phy_id after conversion. 16880 */ 16881 static uint32_t convert_host_phy_id_to_target_phy_id_legacy( 16882 wmi_unified_t wmi_handle, 16883 uint32_t phy_id) 16884 { 16885 /*No conversion required*/ 16886 return phy_id; 16887 } 16888 16889 /** 16890 * convert_target_phy_id_to_host_phy_id_legacy() - Convert phy_id from 16891 * target to host defines. For legacy there is not conversion 16892 * required. Just return phy_id as it is. 16893 * @wmi_handle: handle to WMI. 16894 * @phy_id: target phy_id to be converted. 16895 * 16896 * Return: host phy_id after conversion. 16897 */ 16898 static uint32_t convert_target_phy_id_to_host_phy_id_legacy( 16899 wmi_unified_t wmi_handle, 16900 uint32_t phy_id) 16901 { 16902 /*No conversion required*/ 16903 return phy_id; 16904 } 16905 16906 /** 16907 * send_set_country_cmd_tlv() - WMI scan channel list function 16908 * @wmi_handle: handle to WMI. 16909 * @params: pointer to hold scan channel list parameter 16910 * 16911 * Return: QDF_STATUS_SUCCESS for success or error code 16912 */ 16913 static QDF_STATUS send_set_country_cmd_tlv(wmi_unified_t wmi_handle, 16914 struct set_country *params) 16915 { 16916 wmi_buf_t buf; 16917 QDF_STATUS qdf_status; 16918 wmi_set_current_country_cmd_fixed_param *cmd; 16919 uint16_t len = sizeof(*cmd); 16920 uint8_t pdev_id = params->pdev_id; 16921 16922 buf = wmi_buf_alloc(wmi_handle, len); 16923 if (!buf) { 16924 qdf_status = QDF_STATUS_E_NOMEM; 16925 goto end; 16926 } 16927 16928 cmd = (wmi_set_current_country_cmd_fixed_param *)wmi_buf_data(buf); 16929 WMITLV_SET_HDR(&cmd->tlv_header, 16930 WMITLV_TAG_STRUC_wmi_set_current_country_cmd_fixed_param, 16931 WMITLV_GET_STRUCT_TLVLEN 16932 (wmi_set_current_country_cmd_fixed_param)); 16933 16934 cmd->pdev_id = wmi_handle->ops->convert_host_pdev_id_to_target( 16935 wmi_handle, 16936 pdev_id); 16937 wmi_debug("setting current country to %s and target pdev_id = %u", 16938 params->country, cmd->pdev_id); 16939 16940 qdf_mem_copy((uint8_t *)&cmd->new_alpha2, params->country, 3); 16941 16942 wmi_mtrace(WMI_SET_CURRENT_COUNTRY_CMDID, NO_SESSION, 0); 16943 qdf_status = wmi_unified_cmd_send(wmi_handle, 16944 buf, len, WMI_SET_CURRENT_COUNTRY_CMDID); 16945 16946 if (QDF_IS_STATUS_ERROR(qdf_status)) { 16947 wmi_err("Failed to send WMI_SET_CURRENT_COUNTRY_CMDID"); 16948 wmi_buf_free(buf); 16949 } 16950 16951 end: 16952 return qdf_status; 16953 } 16954 16955 #define WMI_REG_COUNTRY_ALPHA_SET(alpha, val0, val1, val2) do { \ 16956 WMI_SET_BITS(alpha, 0, 8, val0); \ 16957 WMI_SET_BITS(alpha, 8, 8, val1); \ 16958 WMI_SET_BITS(alpha, 16, 8, val2); \ 16959 } while (0) 16960 16961 static QDF_STATUS send_user_country_code_cmd_tlv(wmi_unified_t wmi_handle, 16962 uint8_t pdev_id, struct cc_regdmn_s *rd) 16963 { 16964 wmi_set_init_country_cmd_fixed_param *cmd; 16965 uint16_t len; 16966 wmi_buf_t buf; 16967 int ret; 16968 16969 len = sizeof(wmi_set_init_country_cmd_fixed_param); 16970 buf = wmi_buf_alloc(wmi_handle, len); 16971 if (!buf) 16972 return QDF_STATUS_E_NOMEM; 16973 16974 cmd = (wmi_set_init_country_cmd_fixed_param *) wmi_buf_data(buf); 16975 WMITLV_SET_HDR(&cmd->tlv_header, 16976 WMITLV_TAG_STRUC_wmi_set_init_country_cmd_fixed_param, 16977 WMITLV_GET_STRUCT_TLVLEN 16978 (wmi_set_init_country_cmd_fixed_param)); 16979 16980 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 16981 wmi_handle, 16982 pdev_id); 16983 16984 if (rd->flags == CC_IS_SET) { 16985 cmd->countrycode_type = WMI_COUNTRYCODE_COUNTRY_ID; 16986 cmd->country_code.country_id = rd->cc.country_code; 16987 } else if (rd->flags == ALPHA_IS_SET) { 16988 cmd->countrycode_type = WMI_COUNTRYCODE_ALPHA2; 16989 WMI_REG_COUNTRY_ALPHA_SET(cmd->country_code.alpha2, 16990 rd->cc.alpha[0], 16991 rd->cc.alpha[1], 16992 rd->cc.alpha[2]); 16993 } else if (rd->flags == REGDMN_IS_SET) { 16994 cmd->countrycode_type = WMI_COUNTRYCODE_DOMAIN_CODE; 16995 WMI_SET_BITS(cmd->country_code.domain_code, 0, 16, 16996 rd->cc.regdmn.reg_2g_5g_pair_id); 16997 WMI_SET_BITS(cmd->country_code.domain_code, 16, 16, 16998 rd->cc.regdmn.sixg_superdmn_id); 16999 } 17000 17001 wmi_mtrace(WMI_SET_INIT_COUNTRY_CMDID, NO_SESSION, 0); 17002 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 17003 WMI_SET_INIT_COUNTRY_CMDID); 17004 if (ret) { 17005 wmi_err("Failed to config wow wakeup event"); 17006 wmi_buf_free(buf); 17007 return QDF_STATUS_E_FAILURE; 17008 } 17009 17010 return QDF_STATUS_SUCCESS; 17011 } 17012 17013 /** 17014 * send_obss_detection_cfg_cmd_tlv() - send obss detection 17015 * configurations to firmware. 17016 * @wmi_handle: wmi handle 17017 * @obss_cfg_param: obss detection configurations 17018 * 17019 * Send WMI_SAP_OBSS_DETECTION_CFG_CMDID parameters to fw. 17020 * 17021 * Return: QDF_STATUS 17022 */ 17023 static QDF_STATUS send_obss_detection_cfg_cmd_tlv(wmi_unified_t wmi_handle, 17024 struct wmi_obss_detection_cfg_param *obss_cfg_param) 17025 { 17026 wmi_buf_t buf; 17027 wmi_sap_obss_detection_cfg_cmd_fixed_param *cmd; 17028 uint8_t len = sizeof(wmi_sap_obss_detection_cfg_cmd_fixed_param); 17029 17030 buf = wmi_buf_alloc(wmi_handle, len); 17031 if (!buf) 17032 return QDF_STATUS_E_NOMEM; 17033 17034 cmd = (wmi_sap_obss_detection_cfg_cmd_fixed_param *)wmi_buf_data(buf); 17035 WMITLV_SET_HDR(&cmd->tlv_header, 17036 WMITLV_TAG_STRUC_wmi_sap_obss_detection_cfg_cmd_fixed_param, 17037 WMITLV_GET_STRUCT_TLVLEN 17038 (wmi_sap_obss_detection_cfg_cmd_fixed_param)); 17039 17040 cmd->vdev_id = obss_cfg_param->vdev_id; 17041 cmd->detect_period_ms = obss_cfg_param->obss_detect_period_ms; 17042 cmd->b_ap_detect_mode = obss_cfg_param->obss_11b_ap_detect_mode; 17043 cmd->b_sta_detect_mode = obss_cfg_param->obss_11b_sta_detect_mode; 17044 cmd->g_ap_detect_mode = obss_cfg_param->obss_11g_ap_detect_mode; 17045 cmd->a_detect_mode = obss_cfg_param->obss_11a_detect_mode; 17046 cmd->ht_legacy_detect_mode = obss_cfg_param->obss_ht_legacy_detect_mode; 17047 cmd->ht_mixed_detect_mode = obss_cfg_param->obss_ht_mixed_detect_mode; 17048 cmd->ht_20mhz_detect_mode = obss_cfg_param->obss_ht_20mhz_detect_mode; 17049 17050 wmi_mtrace(WMI_SAP_OBSS_DETECTION_CFG_CMDID, cmd->vdev_id, 0); 17051 if (wmi_unified_cmd_send(wmi_handle, buf, len, 17052 WMI_SAP_OBSS_DETECTION_CFG_CMDID)) { 17053 wmi_err("Failed to send WMI_SAP_OBSS_DETECTION_CFG_CMDID"); 17054 wmi_buf_free(buf); 17055 return QDF_STATUS_E_FAILURE; 17056 } 17057 17058 return QDF_STATUS_SUCCESS; 17059 } 17060 17061 /** 17062 * extract_obss_detection_info_tlv() - Extract obss detection info 17063 * received from firmware. 17064 * @evt_buf: pointer to event buffer 17065 * @obss_detection: Pointer to hold obss detection info 17066 * 17067 * Return: QDF_STATUS 17068 */ 17069 static QDF_STATUS extract_obss_detection_info_tlv(uint8_t *evt_buf, 17070 struct wmi_obss_detect_info 17071 *obss_detection) 17072 { 17073 WMI_SAP_OBSS_DETECTION_REPORT_EVENTID_param_tlvs *param_buf; 17074 wmi_sap_obss_detection_info_evt_fixed_param *fix_param; 17075 17076 if (!obss_detection) { 17077 wmi_err("Invalid obss_detection event buffer"); 17078 return QDF_STATUS_E_INVAL; 17079 } 17080 17081 param_buf = (WMI_SAP_OBSS_DETECTION_REPORT_EVENTID_param_tlvs *)evt_buf; 17082 if (!param_buf) { 17083 wmi_err("Invalid evt_buf"); 17084 return QDF_STATUS_E_INVAL; 17085 } 17086 17087 fix_param = param_buf->fixed_param; 17088 obss_detection->vdev_id = fix_param->vdev_id; 17089 obss_detection->matched_detection_masks = 17090 fix_param->matched_detection_masks; 17091 WMI_MAC_ADDR_TO_CHAR_ARRAY(&fix_param->matched_bssid_addr, 17092 &obss_detection->matched_bssid_addr[0]); 17093 switch (fix_param->reason) { 17094 case WMI_SAP_OBSS_DETECTION_EVENT_REASON_NOT_SUPPORT: 17095 obss_detection->reason = OBSS_OFFLOAD_DETECTION_DISABLED; 17096 break; 17097 case WMI_SAP_OBSS_DETECTION_EVENT_REASON_PRESENT_NOTIFY: 17098 obss_detection->reason = OBSS_OFFLOAD_DETECTION_PRESENT; 17099 break; 17100 case WMI_SAP_OBSS_DETECTION_EVENT_REASON_ABSENT_TIMEOUT: 17101 obss_detection->reason = OBSS_OFFLOAD_DETECTION_ABSENT; 17102 break; 17103 default: 17104 wmi_err("Invalid reason: %d", fix_param->reason); 17105 return QDF_STATUS_E_INVAL; 17106 } 17107 17108 return QDF_STATUS_SUCCESS; 17109 } 17110 17111 /** 17112 * send_roam_scan_stats_cmd_tlv() - Send roam scan stats req command to fw 17113 * @wmi_handle: wmi handle 17114 * @params: pointer to request structure 17115 * 17116 * Return: QDF_STATUS 17117 */ 17118 static QDF_STATUS 17119 send_roam_scan_stats_cmd_tlv(wmi_unified_t wmi_handle, 17120 struct wmi_roam_scan_stats_req *params) 17121 { 17122 wmi_buf_t buf; 17123 wmi_request_roam_scan_stats_cmd_fixed_param *cmd; 17124 WMITLV_TAG_ID tag; 17125 uint32_t size; 17126 uint32_t len = sizeof(*cmd); 17127 17128 buf = wmi_buf_alloc(wmi_handle, len); 17129 if (!buf) 17130 return QDF_STATUS_E_FAILURE; 17131 17132 cmd = (wmi_request_roam_scan_stats_cmd_fixed_param *)wmi_buf_data(buf); 17133 17134 tag = WMITLV_TAG_STRUC_wmi_request_roam_scan_stats_cmd_fixed_param; 17135 size = WMITLV_GET_STRUCT_TLVLEN( 17136 wmi_request_roam_scan_stats_cmd_fixed_param); 17137 WMITLV_SET_HDR(&cmd->tlv_header, tag, size); 17138 17139 cmd->vdev_id = params->vdev_id; 17140 17141 wmi_debug("Roam Scan Stats Req vdev_id: %u", cmd->vdev_id); 17142 if (wmi_unified_cmd_send(wmi_handle, buf, len, 17143 WMI_REQUEST_ROAM_SCAN_STATS_CMDID)) { 17144 wmi_err("Failed to send WMI_REQUEST_ROAM_SCAN_STATS_CMDID"); 17145 wmi_buf_free(buf); 17146 return QDF_STATUS_E_FAILURE; 17147 } 17148 17149 return QDF_STATUS_SUCCESS; 17150 } 17151 17152 /** 17153 * send_roam_scan_ch_list_req_cmd_tlv() - send wmi cmd to get roam scan 17154 * channel list from firmware 17155 * @wmi_handle: wmi handler 17156 * @vdev_id: vdev id 17157 * 17158 * Return: QDF_STATUS 17159 */ 17160 static QDF_STATUS send_roam_scan_ch_list_req_cmd_tlv(wmi_unified_t wmi_handle, 17161 uint32_t vdev_id) 17162 { 17163 wmi_buf_t buf; 17164 wmi_roam_get_scan_channel_list_cmd_fixed_param *cmd; 17165 uint16_t len = sizeof(*cmd); 17166 int ret; 17167 17168 buf = wmi_buf_alloc(wmi_handle, len); 17169 if (!buf) { 17170 wmi_err("Failed to allocate wmi buffer"); 17171 return QDF_STATUS_E_NOMEM; 17172 } 17173 17174 cmd = (wmi_roam_get_scan_channel_list_cmd_fixed_param *) 17175 wmi_buf_data(buf); 17176 WMITLV_SET_HDR(&cmd->tlv_header, 17177 WMITLV_TAG_STRUC_wmi_roam_get_scan_channel_list_cmd_fixed_param, 17178 WMITLV_GET_STRUCT_TLVLEN( 17179 wmi_roam_get_scan_channel_list_cmd_fixed_param)); 17180 cmd->vdev_id = vdev_id; 17181 wmi_mtrace(WMI_ROAM_GET_SCAN_CHANNEL_LIST_CMDID, vdev_id, 0); 17182 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 17183 WMI_ROAM_GET_SCAN_CHANNEL_LIST_CMDID); 17184 if (QDF_IS_STATUS_ERROR(ret)) { 17185 wmi_err("Failed to send get roam scan channels request = %d", 17186 ret); 17187 wmi_buf_free(buf); 17188 } 17189 return ret; 17190 } 17191 17192 /** 17193 * extract_roam_scan_stats_res_evt_tlv() - Extract roam scan stats event 17194 * @wmi_handle: wmi handle 17195 * @evt_buf: pointer to event buffer 17196 * @vdev_id: output pointer to hold vdev id 17197 * @res_param: output pointer to hold the allocated response 17198 * 17199 * Return: QDF_STATUS 17200 */ 17201 static QDF_STATUS 17202 extract_roam_scan_stats_res_evt_tlv(wmi_unified_t wmi_handle, void *evt_buf, 17203 uint32_t *vdev_id, 17204 struct wmi_roam_scan_stats_res **res_param) 17205 { 17206 WMI_ROAM_SCAN_STATS_EVENTID_param_tlvs *param_buf; 17207 wmi_roam_scan_stats_event_fixed_param *fixed_param; 17208 uint32_t *client_id = NULL; 17209 wmi_roaming_timestamp *timestamp = NULL; 17210 uint32_t *num_channels = NULL; 17211 uint32_t *chan_info = NULL; 17212 wmi_mac_addr *old_bssid = NULL; 17213 uint32_t *is_roaming_success = NULL; 17214 wmi_mac_addr *new_bssid = NULL; 17215 uint32_t *num_roam_candidates = NULL; 17216 wmi_roam_scan_trigger_reason *roam_reason = NULL; 17217 wmi_mac_addr *bssid = NULL; 17218 uint32_t *score = NULL; 17219 uint32_t *channel = NULL; 17220 uint32_t *rssi = NULL; 17221 int chan_idx = 0, cand_idx = 0; 17222 uint32_t total_len; 17223 struct wmi_roam_scan_stats_res *res; 17224 uint32_t i, j; 17225 uint32_t num_scans, scan_param_size; 17226 17227 *res_param = NULL; 17228 *vdev_id = 0xFF; /* Initialize to invalid vdev id */ 17229 param_buf = (WMI_ROAM_SCAN_STATS_EVENTID_param_tlvs *)evt_buf; 17230 if (!param_buf) { 17231 wmi_err("Invalid roam scan stats event"); 17232 return QDF_STATUS_E_INVAL; 17233 } 17234 17235 fixed_param = param_buf->fixed_param; 17236 17237 num_scans = fixed_param->num_roam_scans; 17238 scan_param_size = sizeof(struct wmi_roam_scan_stats_params); 17239 *vdev_id = fixed_param->vdev_id; 17240 if (num_scans > WMI_ROAM_SCAN_STATS_MAX) { 17241 wmi_err_rl("%u exceeded maximum roam scan stats: %u", 17242 num_scans, WMI_ROAM_SCAN_STATS_MAX); 17243 return QDF_STATUS_E_INVAL; 17244 } 17245 17246 total_len = sizeof(*res) + num_scans * scan_param_size; 17247 17248 res = qdf_mem_malloc(total_len); 17249 if (!res) 17250 return QDF_STATUS_E_NOMEM; 17251 17252 if (!num_scans) { 17253 *res_param = res; 17254 return QDF_STATUS_SUCCESS; 17255 } 17256 17257 if (param_buf->client_id && 17258 param_buf->num_client_id == num_scans) 17259 client_id = param_buf->client_id; 17260 17261 if (param_buf->timestamp && 17262 param_buf->num_timestamp == num_scans) 17263 timestamp = param_buf->timestamp; 17264 17265 if (param_buf->old_bssid && 17266 param_buf->num_old_bssid == num_scans) 17267 old_bssid = param_buf->old_bssid; 17268 17269 if (param_buf->new_bssid && 17270 param_buf->num_new_bssid == num_scans) 17271 new_bssid = param_buf->new_bssid; 17272 17273 if (param_buf->is_roaming_success && 17274 param_buf->num_is_roaming_success == num_scans) 17275 is_roaming_success = param_buf->is_roaming_success; 17276 17277 if (param_buf->roam_reason && 17278 param_buf->num_roam_reason == num_scans) 17279 roam_reason = param_buf->roam_reason; 17280 17281 if (param_buf->num_channels && 17282 param_buf->num_num_channels == num_scans) { 17283 uint32_t count, chan_info_sum = 0; 17284 17285 num_channels = param_buf->num_channels; 17286 for (count = 0; count < param_buf->num_num_channels; count++) { 17287 if (param_buf->num_channels[count] > 17288 WMI_ROAM_SCAN_STATS_CHANNELS_MAX) { 17289 wmi_err_rl("%u exceeded max scan channels %u", 17290 param_buf->num_channels[count], 17291 WMI_ROAM_SCAN_STATS_CHANNELS_MAX); 17292 goto error; 17293 } 17294 chan_info_sum += param_buf->num_channels[count]; 17295 } 17296 17297 if (param_buf->chan_info && 17298 param_buf->num_chan_info == chan_info_sum) 17299 chan_info = param_buf->chan_info; 17300 } 17301 17302 if (param_buf->num_roam_candidates && 17303 param_buf->num_num_roam_candidates == num_scans) { 17304 uint32_t cnt, roam_cand_sum = 0; 17305 17306 num_roam_candidates = param_buf->num_roam_candidates; 17307 for (cnt = 0; cnt < param_buf->num_num_roam_candidates; cnt++) { 17308 if (param_buf->num_roam_candidates[cnt] > 17309 WMI_ROAM_SCAN_STATS_CANDIDATES_MAX) { 17310 wmi_err_rl("%u exceeded max scan cand %u", 17311 param_buf->num_roam_candidates[cnt], 17312 WMI_ROAM_SCAN_STATS_CANDIDATES_MAX); 17313 goto error; 17314 } 17315 roam_cand_sum += param_buf->num_roam_candidates[cnt]; 17316 } 17317 17318 if (param_buf->bssid && 17319 param_buf->num_bssid == roam_cand_sum) 17320 bssid = param_buf->bssid; 17321 17322 if (param_buf->score && 17323 param_buf->num_score == roam_cand_sum) 17324 score = param_buf->score; 17325 17326 if (param_buf->channel && 17327 param_buf->num_channel == roam_cand_sum) 17328 channel = param_buf->channel; 17329 17330 if (param_buf->rssi && 17331 param_buf->num_rssi == roam_cand_sum) 17332 rssi = param_buf->rssi; 17333 } 17334 17335 res->num_roam_scans = num_scans; 17336 for (i = 0; i < num_scans; i++) { 17337 struct wmi_roam_scan_stats_params *roam = &res->roam_scan[i]; 17338 17339 if (timestamp) 17340 roam->time_stamp = timestamp[i].lower32bit | 17341 (timestamp[i].upper32bit << 31); 17342 17343 if (client_id) 17344 roam->client_id = client_id[i]; 17345 17346 if (num_channels) { 17347 roam->num_scan_chans = num_channels[i]; 17348 if (chan_info) { 17349 for (j = 0; j < num_channels[i]; j++) 17350 roam->scan_freqs[j] = 17351 chan_info[chan_idx++]; 17352 } 17353 } 17354 17355 if (is_roaming_success) 17356 roam->is_roam_successful = is_roaming_success[i]; 17357 17358 if (roam_reason) { 17359 roam->trigger_id = roam_reason[i].trigger_id; 17360 roam->trigger_value = roam_reason[i].trigger_value; 17361 } 17362 17363 if (num_roam_candidates) { 17364 roam->num_roam_candidates = num_roam_candidates[i]; 17365 17366 for (j = 0; j < num_roam_candidates[i]; j++) { 17367 if (score) 17368 roam->cand[j].score = score[cand_idx]; 17369 if (rssi) 17370 roam->cand[j].rssi = rssi[cand_idx]; 17371 if (channel) 17372 roam->cand[j].freq = 17373 channel[cand_idx]; 17374 17375 if (bssid) 17376 WMI_MAC_ADDR_TO_CHAR_ARRAY( 17377 &bssid[cand_idx], 17378 roam->cand[j].bssid); 17379 17380 cand_idx++; 17381 } 17382 } 17383 17384 if (old_bssid) 17385 WMI_MAC_ADDR_TO_CHAR_ARRAY(&old_bssid[i], 17386 roam->old_bssid); 17387 17388 if (new_bssid) 17389 WMI_MAC_ADDR_TO_CHAR_ARRAY(&new_bssid[i], 17390 roam->new_bssid); 17391 } 17392 17393 *res_param = res; 17394 17395 return QDF_STATUS_SUCCESS; 17396 error: 17397 qdf_mem_free(res); 17398 return QDF_STATUS_E_FAILURE; 17399 } 17400 17401 /** 17402 * extract_offload_bcn_tx_status_evt() - Extract beacon-tx status event 17403 * @wmi_handle: wmi handle 17404 * @evt_buf: pointer to event buffer 17405 * @vdev_id: output pointer to hold vdev id 17406 * @tx_status: output pointer to hold the tx_status 17407 * 17408 * Return: QDF_STATUS 17409 */ 17410 static QDF_STATUS extract_offload_bcn_tx_status_evt(wmi_unified_t wmi_handle, 17411 void *evt_buf, 17412 uint32_t *vdev_id, 17413 uint32_t *tx_status) { 17414 WMI_OFFLOAD_BCN_TX_STATUS_EVENTID_param_tlvs *param_buf; 17415 wmi_offload_bcn_tx_status_event_fixed_param *bcn_tx_status_event; 17416 17417 param_buf = (WMI_OFFLOAD_BCN_TX_STATUS_EVENTID_param_tlvs *)evt_buf; 17418 if (!param_buf) { 17419 wmi_err("Invalid offload bcn tx status event buffer"); 17420 return QDF_STATUS_E_INVAL; 17421 } 17422 17423 bcn_tx_status_event = param_buf->fixed_param; 17424 *vdev_id = bcn_tx_status_event->vdev_id; 17425 *tx_status = bcn_tx_status_event->tx_status; 17426 17427 return QDF_STATUS_SUCCESS; 17428 } 17429 17430 #ifdef WLAN_SUPPORT_GREEN_AP 17431 static QDF_STATUS extract_green_ap_egap_status_info_tlv( 17432 uint8_t *evt_buf, 17433 struct wlan_green_ap_egap_status_info *egap_status_info_params) 17434 { 17435 WMI_AP_PS_EGAP_INFO_EVENTID_param_tlvs *param_buf; 17436 wmi_ap_ps_egap_info_event_fixed_param *egap_info_event; 17437 wmi_ap_ps_egap_info_chainmask_list *chainmask_event; 17438 17439 param_buf = (WMI_AP_PS_EGAP_INFO_EVENTID_param_tlvs *)evt_buf; 17440 if (!param_buf) { 17441 wmi_err("Invalid EGAP Info status event buffer"); 17442 return QDF_STATUS_E_INVAL; 17443 } 17444 17445 egap_info_event = (wmi_ap_ps_egap_info_event_fixed_param *) 17446 param_buf->fixed_param; 17447 chainmask_event = (wmi_ap_ps_egap_info_chainmask_list *) 17448 param_buf->chainmask_list; 17449 17450 if (!egap_info_event || !chainmask_event) { 17451 wmi_err("Invalid EGAP Info event or chainmask event"); 17452 return QDF_STATUS_E_INVAL; 17453 } 17454 17455 egap_status_info_params->status = egap_info_event->status; 17456 egap_status_info_params->mac_id = chainmask_event->mac_id; 17457 egap_status_info_params->tx_chainmask = chainmask_event->tx_chainmask; 17458 egap_status_info_params->rx_chainmask = chainmask_event->rx_chainmask; 17459 17460 return QDF_STATUS_SUCCESS; 17461 } 17462 #endif 17463 17464 #ifdef WLAN_SUPPORT_GAP_LL_PS_MODE 17465 static QDF_STATUS extract_green_ap_ll_ps_param_tlv( 17466 uint8_t *evt_buf, 17467 struct wlan_green_ap_ll_ps_event_param *ll_ps_params) 17468 { 17469 WMI_XGAP_ENABLE_COMPLETE_EVENTID_param_tlvs *param_buf; 17470 wmi_xgap_enable_complete_event_fixed_param *ll_ps_event; 17471 17472 param_buf = (WMI_XGAP_ENABLE_COMPLETE_EVENTID_param_tlvs *)evt_buf; 17473 if (!param_buf) { 17474 wmi_err("Invalid XGAP SAP info status"); 17475 return QDF_STATUS_E_INVAL; 17476 } 17477 17478 ll_ps_event = (wmi_xgap_enable_complete_event_fixed_param *) 17479 param_buf->fixed_param; 17480 if (!ll_ps_event) { 17481 wmi_err("Invalid low latency power save event buffer"); 17482 return QDF_STATUS_E_INVAL; 17483 } 17484 17485 ll_ps_params->dialog_token = ll_ps_event->dialog_token; 17486 ll_ps_params->next_tsf = 17487 ((uint64_t)ll_ps_event->next_tsf_high32 << 32) | 17488 ll_ps_event->next_tsf_low32; 17489 17490 wmi_debug("cookie : %llu next_tsf %llu", ll_ps_params->dialog_token, 17491 ll_ps_params->next_tsf); 17492 17493 return QDF_STATUS_SUCCESS; 17494 } 17495 #endif 17496 17497 /* 17498 * extract_comb_phyerr_tlv() - extract comb phy error from event 17499 * @wmi_handle: wmi handle 17500 * @evt_buf: pointer to event buffer 17501 * @datalen: data length of event buffer 17502 * @buf_offset: Pointer to hold value of current event buffer offset 17503 * post extraction 17504 * @phyerr: Pointer to hold phyerr 17505 * 17506 * Return: QDF_STATUS 17507 */ 17508 static QDF_STATUS extract_comb_phyerr_tlv(wmi_unified_t wmi_handle, 17509 void *evt_buf, 17510 uint16_t datalen, 17511 uint16_t *buf_offset, 17512 wmi_host_phyerr_t *phyerr) 17513 { 17514 WMI_PHYERR_EVENTID_param_tlvs *param_tlvs; 17515 wmi_comb_phyerr_rx_hdr *pe_hdr; 17516 17517 param_tlvs = (WMI_PHYERR_EVENTID_param_tlvs *)evt_buf; 17518 if (!param_tlvs) { 17519 wmi_debug("Received null data from FW"); 17520 return QDF_STATUS_E_FAILURE; 17521 } 17522 17523 pe_hdr = param_tlvs->hdr; 17524 if (!pe_hdr) { 17525 wmi_debug("Received Data PE Header is NULL"); 17526 return QDF_STATUS_E_FAILURE; 17527 } 17528 17529 /* Ensure it's at least the size of the header */ 17530 if (datalen < sizeof(*pe_hdr)) { 17531 wmi_debug("Expected minimum size %zu, received %d", 17532 sizeof(*pe_hdr), datalen); 17533 return QDF_STATUS_E_FAILURE; 17534 } 17535 17536 phyerr->pdev_id = wmi_handle->ops-> 17537 convert_pdev_id_target_to_host(wmi_handle, pe_hdr->pdev_id); 17538 phyerr->tsf64 = pe_hdr->tsf_l32; 17539 phyerr->tsf64 |= (((uint64_t)pe_hdr->tsf_u32) << 32); 17540 phyerr->bufp = param_tlvs->bufp; 17541 17542 if (pe_hdr->buf_len > param_tlvs->num_bufp) { 17543 wmi_debug("Invalid buf_len %d, num_bufp %d", 17544 pe_hdr->buf_len, param_tlvs->num_bufp); 17545 return QDF_STATUS_E_FAILURE; 17546 } 17547 17548 phyerr->buf_len = pe_hdr->buf_len; 17549 phyerr->phy_err_mask0 = pe_hdr->rsPhyErrMask0; 17550 phyerr->phy_err_mask1 = pe_hdr->rsPhyErrMask1; 17551 *buf_offset = sizeof(*pe_hdr) + sizeof(uint32_t); 17552 17553 return QDF_STATUS_SUCCESS; 17554 } 17555 17556 /** 17557 * extract_single_phyerr_tlv() - extract single phy error from event 17558 * @wmi_handle: wmi handle 17559 * @evt_buf: pointer to event buffer 17560 * @datalen: data length of event buffer 17561 * @buf_offset: Pointer to hold value of current event buffer offset 17562 * post extraction 17563 * @phyerr: Pointer to hold phyerr 17564 * 17565 * Return: QDF_STATUS 17566 */ 17567 static QDF_STATUS extract_single_phyerr_tlv(wmi_unified_t wmi_handle, 17568 void *evt_buf, 17569 uint16_t datalen, 17570 uint16_t *buf_offset, 17571 wmi_host_phyerr_t *phyerr) 17572 { 17573 wmi_single_phyerr_rx_event *ev; 17574 uint16_t n = *buf_offset; 17575 uint8_t *data = (uint8_t *)evt_buf; 17576 17577 if (n < datalen) { 17578 if ((datalen - n) < sizeof(ev->hdr)) { 17579 wmi_debug("Not enough space. len=%d, n=%d, hdr=%zu", 17580 datalen, n, sizeof(ev->hdr)); 17581 return QDF_STATUS_E_FAILURE; 17582 } 17583 17584 /* 17585 * Obtain a pointer to the beginning of the current event. 17586 * data[0] is the beginning of the WMI payload. 17587 */ 17588 ev = (wmi_single_phyerr_rx_event *)&data[n]; 17589 17590 /* 17591 * Sanity check the buffer length of the event against 17592 * what we currently have. 17593 * 17594 * Since buf_len is 32 bits, we check if it overflows 17595 * a large 32 bit value. It's not 0x7fffffff because 17596 * we increase n by (buf_len + sizeof(hdr)), which would 17597 * in itself cause n to overflow. 17598 * 17599 * If "int" is 64 bits then this becomes a moot point. 17600 */ 17601 if (ev->hdr.buf_len > PHYERROR_MAX_BUFFER_LENGTH) { 17602 wmi_debug("buf_len is garbage 0x%x", ev->hdr.buf_len); 17603 return QDF_STATUS_E_FAILURE; 17604 } 17605 17606 if ((n + ev->hdr.buf_len) > datalen) { 17607 wmi_debug("len exceeds n=%d, buf_len=%d, datalen=%d", 17608 n, ev->hdr.buf_len, datalen); 17609 return QDF_STATUS_E_FAILURE; 17610 } 17611 17612 phyerr->phy_err_code = WMI_UNIFIED_PHYERRCODE_GET(&ev->hdr); 17613 phyerr->tsf_timestamp = ev->hdr.tsf_timestamp; 17614 phyerr->bufp = &ev->bufp[0]; 17615 phyerr->buf_len = ev->hdr.buf_len; 17616 phyerr->rf_info.rssi_comb = WMI_UNIFIED_RSSI_COMB_GET(&ev->hdr); 17617 17618 /* 17619 * Advance the buffer pointer to the next PHY error. 17620 * buflen is the length of this payload, so we need to 17621 * advance past the current header _AND_ the payload. 17622 */ 17623 n += sizeof(*ev) + ev->hdr.buf_len; 17624 } 17625 *buf_offset = n; 17626 17627 return QDF_STATUS_SUCCESS; 17628 } 17629 17630 /** 17631 * extract_esp_estimation_ev_param_tlv() - extract air time from event 17632 * @wmi_handle: wmi handle 17633 * @evt_buf: pointer to event buffer 17634 * @param: Pointer to hold esp event 17635 * 17636 * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_INVAL on failure 17637 */ 17638 static QDF_STATUS 17639 extract_esp_estimation_ev_param_tlv(wmi_unified_t wmi_handle, 17640 void *evt_buf, 17641 struct esp_estimation_event *param) 17642 { 17643 WMI_ESP_ESTIMATE_EVENTID_param_tlvs *param_buf; 17644 wmi_esp_estimate_event_fixed_param *esp_event; 17645 17646 param_buf = (WMI_ESP_ESTIMATE_EVENTID_param_tlvs *)evt_buf; 17647 if (!param_buf) { 17648 wmi_err("Invalid ESP Estimate Event buffer"); 17649 return QDF_STATUS_E_INVAL; 17650 } 17651 esp_event = param_buf->fixed_param; 17652 param->ac_airtime_percentage = esp_event->ac_airtime_percentage; 17653 17654 param->pdev_id = convert_target_pdev_id_to_host_pdev_id( 17655 wmi_handle, 17656 esp_event->pdev_id); 17657 17658 if (param->pdev_id == WMI_HOST_PDEV_ID_INVALID) 17659 return QDF_STATUS_E_FAILURE; 17660 17661 return QDF_STATUS_SUCCESS; 17662 } 17663 17664 /* 17665 * send_bss_color_change_enable_cmd_tlv() - Send command to enable or disable of 17666 * updating bss color change within firmware when AP announces bss color change. 17667 * @wmi_handle: wmi handle 17668 * @vdev_id: vdev ID 17669 * @enable: enable bss color change within firmware 17670 * 17671 * Send WMI_BSS_COLOR_CHANGE_ENABLE_CMDID parameters to fw. 17672 * 17673 * Return: QDF_STATUS 17674 */ 17675 static QDF_STATUS send_bss_color_change_enable_cmd_tlv(wmi_unified_t wmi_handle, 17676 uint32_t vdev_id, 17677 bool enable) 17678 { 17679 wmi_buf_t buf; 17680 wmi_bss_color_change_enable_fixed_param *cmd; 17681 uint8_t len = sizeof(wmi_bss_color_change_enable_fixed_param); 17682 17683 buf = wmi_buf_alloc(wmi_handle, len); 17684 if (!buf) 17685 return QDF_STATUS_E_NOMEM; 17686 17687 cmd = (wmi_bss_color_change_enable_fixed_param *)wmi_buf_data(buf); 17688 WMITLV_SET_HDR(&cmd->tlv_header, 17689 WMITLV_TAG_STRUC_wmi_bss_color_change_enable_fixed_param, 17690 WMITLV_GET_STRUCT_TLVLEN 17691 (wmi_bss_color_change_enable_fixed_param)); 17692 cmd->vdev_id = vdev_id; 17693 cmd->enable = enable; 17694 wmi_mtrace(WMI_BSS_COLOR_CHANGE_ENABLE_CMDID, cmd->vdev_id, 0); 17695 if (wmi_unified_cmd_send(wmi_handle, buf, len, 17696 WMI_BSS_COLOR_CHANGE_ENABLE_CMDID)) { 17697 wmi_err("Failed to send WMI_BSS_COLOR_CHANGE_ENABLE_CMDID"); 17698 wmi_buf_free(buf); 17699 return QDF_STATUS_E_FAILURE; 17700 } 17701 17702 return QDF_STATUS_SUCCESS; 17703 } 17704 17705 /** 17706 * send_obss_color_collision_cfg_cmd_tlv() - send bss color detection 17707 * configurations to firmware. 17708 * @wmi_handle: wmi handle 17709 * @cfg_param: obss detection configurations 17710 * 17711 * Send WMI_OBSS_COLOR_COLLISION_DET_CONFIG_CMDID parameters to fw. 17712 * 17713 * Return: QDF_STATUS 17714 */ 17715 static QDF_STATUS send_obss_color_collision_cfg_cmd_tlv( 17716 wmi_unified_t wmi_handle, 17717 struct wmi_obss_color_collision_cfg_param *cfg_param) 17718 { 17719 wmi_buf_t buf; 17720 wmi_obss_color_collision_det_config_fixed_param *cmd; 17721 uint8_t len = sizeof(wmi_obss_color_collision_det_config_fixed_param); 17722 17723 buf = wmi_buf_alloc(wmi_handle, len); 17724 if (!buf) 17725 return QDF_STATUS_E_NOMEM; 17726 17727 cmd = (wmi_obss_color_collision_det_config_fixed_param *)wmi_buf_data( 17728 buf); 17729 WMITLV_SET_HDR(&cmd->tlv_header, 17730 WMITLV_TAG_STRUC_wmi_obss_color_collision_det_config_fixed_param, 17731 WMITLV_GET_STRUCT_TLVLEN 17732 (wmi_obss_color_collision_det_config_fixed_param)); 17733 cmd->vdev_id = cfg_param->vdev_id; 17734 cmd->flags = cfg_param->flags; 17735 cmd->current_bss_color = cfg_param->current_bss_color; 17736 cmd->detection_period_ms = cfg_param->detection_period_ms; 17737 cmd->scan_period_ms = cfg_param->scan_period_ms; 17738 cmd->free_slot_expiry_time_ms = cfg_param->free_slot_expiry_time_ms; 17739 17740 switch (cfg_param->evt_type) { 17741 case OBSS_COLOR_COLLISION_DETECTION_DISABLE: 17742 cmd->evt_type = WMI_BSS_COLOR_COLLISION_DISABLE; 17743 break; 17744 case OBSS_COLOR_COLLISION_DETECTION: 17745 cmd->evt_type = WMI_BSS_COLOR_COLLISION_DETECTION; 17746 break; 17747 case OBSS_COLOR_FREE_SLOT_TIMER_EXPIRY: 17748 cmd->evt_type = WMI_BSS_COLOR_FREE_SLOT_TIMER_EXPIRY; 17749 break; 17750 case OBSS_COLOR_FREE_SLOT_AVAILABLE: 17751 cmd->evt_type = WMI_BSS_COLOR_FREE_SLOT_AVAILABLE; 17752 break; 17753 default: 17754 wmi_err("Invalid event type: %d", cfg_param->evt_type); 17755 wmi_buf_free(buf); 17756 return QDF_STATUS_E_FAILURE; 17757 } 17758 17759 wmi_debug("evt_type: %d vdev id: %d current_bss_color: %d " 17760 "detection_period_ms: %d scan_period_ms: %d " 17761 "free_slot_expiry_timer_ms: %d", 17762 cmd->evt_type, cmd->vdev_id, cmd->current_bss_color, 17763 cmd->detection_period_ms, cmd->scan_period_ms, 17764 cmd->free_slot_expiry_time_ms); 17765 17766 wmi_mtrace(WMI_OBSS_COLOR_COLLISION_DET_CONFIG_CMDID, cmd->vdev_id, 0); 17767 if (wmi_unified_cmd_send(wmi_handle, buf, len, 17768 WMI_OBSS_COLOR_COLLISION_DET_CONFIG_CMDID)) { 17769 wmi_err("Sending OBSS color det cmd failed, vdev_id: %d", 17770 cfg_param->vdev_id); 17771 wmi_buf_free(buf); 17772 return QDF_STATUS_E_FAILURE; 17773 } 17774 17775 return QDF_STATUS_SUCCESS; 17776 } 17777 17778 /** 17779 * extract_obss_color_collision_info_tlv() - Extract bss color collision info 17780 * received from firmware. 17781 * @evt_buf: pointer to event buffer 17782 * @info: Pointer to hold bss collision info 17783 * 17784 * Return: QDF_STATUS 17785 */ 17786 static QDF_STATUS extract_obss_color_collision_info_tlv(uint8_t *evt_buf, 17787 struct wmi_obss_color_collision_info *info) 17788 { 17789 WMI_OBSS_COLOR_COLLISION_DETECTION_EVENTID_param_tlvs *param_buf; 17790 wmi_obss_color_collision_evt_fixed_param *fix_param; 17791 17792 if (!info) { 17793 wmi_err("Invalid obss color buffer"); 17794 return QDF_STATUS_E_INVAL; 17795 } 17796 17797 param_buf = (WMI_OBSS_COLOR_COLLISION_DETECTION_EVENTID_param_tlvs *) 17798 evt_buf; 17799 if (!param_buf) { 17800 wmi_err("Invalid evt_buf"); 17801 return QDF_STATUS_E_INVAL; 17802 } 17803 17804 fix_param = param_buf->fixed_param; 17805 info->vdev_id = fix_param->vdev_id; 17806 info->obss_color_bitmap_bit0to31 = 17807 fix_param->bss_color_bitmap_bit0to31; 17808 info->obss_color_bitmap_bit32to63 = 17809 fix_param->bss_color_bitmap_bit32to63; 17810 17811 switch (fix_param->evt_type) { 17812 case WMI_BSS_COLOR_COLLISION_DISABLE: 17813 info->evt_type = OBSS_COLOR_COLLISION_DETECTION_DISABLE; 17814 break; 17815 case WMI_BSS_COLOR_COLLISION_DETECTION: 17816 info->evt_type = OBSS_COLOR_COLLISION_DETECTION; 17817 break; 17818 case WMI_BSS_COLOR_FREE_SLOT_TIMER_EXPIRY: 17819 info->evt_type = OBSS_COLOR_FREE_SLOT_TIMER_EXPIRY; 17820 break; 17821 case WMI_BSS_COLOR_FREE_SLOT_AVAILABLE: 17822 info->evt_type = OBSS_COLOR_FREE_SLOT_AVAILABLE; 17823 break; 17824 default: 17825 wmi_err("Invalid event type: %d, vdev_id: %d", 17826 fix_param->evt_type, fix_param->vdev_id); 17827 return QDF_STATUS_E_FAILURE; 17828 } 17829 17830 return QDF_STATUS_SUCCESS; 17831 } 17832 17833 static void wmi_11ax_bss_color_attach_tlv(struct wmi_unified *wmi_handle) 17834 { 17835 struct wmi_ops *ops = wmi_handle->ops; 17836 17837 ops->send_obss_color_collision_cfg_cmd = 17838 send_obss_color_collision_cfg_cmd_tlv; 17839 ops->extract_obss_color_collision_info = 17840 extract_obss_color_collision_info_tlv; 17841 } 17842 17843 #if defined(WLAN_SUPPORT_FILS) || defined(CONFIG_BAND_6GHZ) 17844 static QDF_STATUS 17845 send_vdev_fils_enable_cmd_send(struct wmi_unified *wmi_handle, 17846 struct config_fils_params *param) 17847 { 17848 wmi_buf_t buf; 17849 wmi_enable_fils_cmd_fixed_param *cmd; 17850 uint8_t len = sizeof(wmi_enable_fils_cmd_fixed_param); 17851 17852 buf = wmi_buf_alloc(wmi_handle, len); 17853 if (!buf) 17854 return QDF_STATUS_E_NOMEM; 17855 17856 cmd = (wmi_enable_fils_cmd_fixed_param *)wmi_buf_data( 17857 buf); 17858 WMITLV_SET_HDR(&cmd->tlv_header, 17859 WMITLV_TAG_STRUC_wmi_enable_fils_cmd_fixed_param, 17860 WMITLV_GET_STRUCT_TLVLEN 17861 (wmi_enable_fils_cmd_fixed_param)); 17862 cmd->vdev_id = param->vdev_id; 17863 cmd->fd_period = param->fd_period; 17864 if (param->send_prb_rsp_frame) 17865 cmd->flags |= WMI_FILS_FLAGS_BITMAP_BCAST_PROBE_RSP; 17866 wmi_debug("vdev id: %d fd_period: %d cmd->Flags %d", 17867 cmd->vdev_id, cmd->fd_period, cmd->flags); 17868 wmi_mtrace(WMI_ENABLE_FILS_CMDID, cmd->vdev_id, cmd->fd_period); 17869 if (wmi_unified_cmd_send(wmi_handle, buf, len, 17870 WMI_ENABLE_FILS_CMDID)) { 17871 wmi_err("Sending FILS cmd failed, vdev_id: %d", param->vdev_id); 17872 wmi_buf_free(buf); 17873 return QDF_STATUS_E_FAILURE; 17874 } 17875 17876 return QDF_STATUS_SUCCESS; 17877 } 17878 #endif 17879 17880 #ifdef WLAN_MWS_INFO_DEBUGFS 17881 /** 17882 * send_mws_coex_status_req_cmd_tlv() - send coex cmd to fw 17883 * 17884 * @wmi_handle: wmi handle 17885 * @vdev_id: vdev id 17886 * @cmd_id: Coex command id 17887 * 17888 * Send WMI_VDEV_GET_MWS_COEX_INFO_CMDID to fw. 17889 * 17890 * Return: QDF_STATUS 17891 */ 17892 static QDF_STATUS send_mws_coex_status_req_cmd_tlv(wmi_unified_t wmi_handle, 17893 uint32_t vdev_id, 17894 uint32_t cmd_id) 17895 { 17896 wmi_buf_t buf; 17897 wmi_vdev_get_mws_coex_info_cmd_fixed_param *cmd; 17898 uint16_t len = sizeof(*cmd); 17899 int ret; 17900 17901 buf = wmi_buf_alloc(wmi_handle, len); 17902 if (!buf) { 17903 wmi_err("Failed to allocate wmi buffer"); 17904 return QDF_STATUS_E_NOMEM; 17905 } 17906 17907 cmd = (wmi_vdev_get_mws_coex_info_cmd_fixed_param *)wmi_buf_data(buf); 17908 WMITLV_SET_HDR(&cmd->tlv_header, 17909 WMITLV_TAG_STRUC_wmi_vdev_get_mws_coex_info_cmd_fixed_param, 17910 WMITLV_GET_STRUCT_TLVLEN 17911 (wmi_vdev_get_mws_coex_info_cmd_fixed_param)); 17912 cmd->vdev_id = vdev_id; 17913 cmd->cmd_id = cmd_id; 17914 wmi_mtrace(WMI_VDEV_GET_MWS_COEX_INFO_CMDID, vdev_id, 0); 17915 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 17916 WMI_VDEV_GET_MWS_COEX_INFO_CMDID); 17917 if (QDF_IS_STATUS_ERROR(ret)) { 17918 wmi_err("Failed to send set param command ret = %d", ret); 17919 wmi_buf_free(buf); 17920 } 17921 return ret; 17922 } 17923 #endif 17924 17925 #ifdef FEATURE_MEC_OFFLOAD 17926 static QDF_STATUS 17927 send_pdev_set_mec_timer_cmd_tlv(struct wmi_unified *wmi_handle, 17928 struct set_mec_timer_params *param) 17929 { 17930 wmi_pdev_mec_aging_timer_config_cmd_fixed_param *cmd; 17931 wmi_buf_t buf; 17932 int32_t len = sizeof(*cmd); 17933 17934 buf = wmi_buf_alloc(wmi_handle, len); 17935 if (!buf) { 17936 wmi_err("wmi_buf_alloc failed"); 17937 return QDF_STATUS_E_FAILURE; 17938 } 17939 cmd = (wmi_pdev_mec_aging_timer_config_cmd_fixed_param *) 17940 wmi_buf_data(buf); 17941 WMITLV_SET_HDR(&cmd->tlv_header, 17942 WMITLV_TAG_STRUC_wmi_pdev_mec_aging_timer_config_cmd_fixed_param, 17943 WMITLV_GET_STRUCT_TLVLEN( 17944 wmi_pdev_mec_aging_timer_config_cmd_fixed_param)); 17945 cmd->pdev_id = param->pdev_id; 17946 cmd->mec_aging_timer_threshold = param->mec_aging_timer_threshold; 17947 17948 wmi_mtrace(WMI_PDEV_MEC_AGING_TIMER_CONFIG_CMDID, param->vdev_id, 0); 17949 if (wmi_unified_cmd_send(wmi_handle, buf, len, 17950 WMI_PDEV_MEC_AGING_TIMER_CONFIG_CMDID)) { 17951 wmi_err("Failed to set mec aging timer param"); 17952 wmi_buf_free(buf); 17953 return QDF_STATUS_E_FAILURE; 17954 } 17955 17956 return QDF_STATUS_SUCCESS; 17957 } 17958 #endif 17959 17960 #ifdef WIFI_POS_CONVERGED 17961 /** 17962 * extract_oem_response_param_tlv() - Extract oem response params 17963 * @wmi_handle: wmi handle 17964 * @resp_buf: response buffer 17965 * @oem_resp_param: pointer to hold oem response params 17966 * 17967 * Return: QDF_STATUS_SUCCESS on success or proper error code. 17968 */ 17969 static QDF_STATUS 17970 extract_oem_response_param_tlv(wmi_unified_t wmi_handle, void *resp_buf, 17971 struct wmi_oem_response_param *oem_resp_param) 17972 { 17973 uint64_t temp_addr; 17974 WMI_OEM_RESPONSE_EVENTID_param_tlvs *param_buf = 17975 (WMI_OEM_RESPONSE_EVENTID_param_tlvs *)resp_buf; 17976 17977 if (!param_buf) { 17978 wmi_err("Invalid OEM response"); 17979 return QDF_STATUS_E_INVAL; 17980 } 17981 17982 if (param_buf->num_data) { 17983 oem_resp_param->num_data1 = param_buf->num_data; 17984 oem_resp_param->data_1 = param_buf->data; 17985 } 17986 17987 if (param_buf->num_data2) { 17988 oem_resp_param->num_data2 = param_buf->num_data2; 17989 oem_resp_param->data_2 = param_buf->data2; 17990 } 17991 17992 if (param_buf->indirect_data) { 17993 oem_resp_param->indirect_data.pdev_id = 17994 param_buf->indirect_data->pdev_id; 17995 temp_addr = (param_buf->indirect_data->addr_hi) & 0xf; 17996 oem_resp_param->indirect_data.addr = 17997 param_buf->indirect_data->addr_lo + 17998 ((uint64_t)temp_addr << 32); 17999 oem_resp_param->indirect_data.len = 18000 param_buf->indirect_data->len; 18001 } 18002 18003 return QDF_STATUS_SUCCESS; 18004 } 18005 #endif /* WIFI_POS_CONVERGED */ 18006 18007 #if defined(WIFI_POS_CONVERGED) && defined(WLAN_FEATURE_RTT_11AZ_SUPPORT) 18008 #define WLAN_PASN_LTF_KEY_SEED_REQUIRED 0x2 18009 18010 static QDF_STATUS 18011 extract_pasn_peer_create_req_event_tlv(wmi_unified_t wmi_handle, void *evt_buf, 18012 struct wifi_pos_pasn_peer_data *dst) 18013 { 18014 WMI_RTT_PASN_PEER_CREATE_REQ_EVENTID_param_tlvs *param_buf; 18015 wmi_rtt_pasn_peer_create_req_event_fixed_param *fixed_param; 18016 wmi_rtt_pasn_peer_create_req_param *buf; 18017 uint8_t security_mode, i; 18018 18019 param_buf = (WMI_RTT_PASN_PEER_CREATE_REQ_EVENTID_param_tlvs *)evt_buf; 18020 if (!param_buf) { 18021 wmi_err("Invalid peer_create req buffer"); 18022 return QDF_STATUS_E_INVAL; 18023 } 18024 18025 fixed_param = param_buf->fixed_param; 18026 18027 if (param_buf->num_rtt_pasn_peer_param > 18028 ((WMI_SVC_MSG_MAX_SIZE - sizeof(*fixed_param)) / 18029 sizeof(wmi_rtt_pasn_peer_create_req_param))) { 18030 wmi_err("Invalid TLV size"); 18031 return QDF_STATUS_E_INVAL; 18032 } 18033 18034 if (!param_buf->num_rtt_pasn_peer_param || 18035 param_buf->num_rtt_pasn_peer_param > WLAN_MAX_11AZ_PEERS) { 18036 wmi_err("Invalid num TLV:%d", 18037 param_buf->num_rtt_pasn_peer_param); 18038 return QDF_STATUS_E_INVAL; 18039 } 18040 18041 dst->vdev_id = fixed_param->vdev_id; 18042 if (dst->vdev_id >= WLAN_UMAC_PDEV_MAX_VDEVS) { 18043 wmi_err("Invalid vdev id:%d", dst->vdev_id); 18044 return QDF_STATUS_E_INVAL; 18045 } 18046 18047 buf = param_buf->rtt_pasn_peer_param; 18048 if (!buf) { 18049 wmi_err("NULL peer param TLV"); 18050 return QDF_STATUS_E_INVAL; 18051 } 18052 18053 for (i = 0; i < param_buf->num_rtt_pasn_peer_param; i++) { 18054 WMI_MAC_ADDR_TO_CHAR_ARRAY(&buf->self_mac_addr, 18055 dst->peer_info[i].self_mac.bytes); 18056 WMI_MAC_ADDR_TO_CHAR_ARRAY(&buf->dest_mac_addr, 18057 dst->peer_info[i].peer_mac.bytes); 18058 security_mode = WMI_RTT_PASN_PEER_CREATE_SECURITY_MODE_GET( 18059 buf->control_flag); 18060 if (security_mode) 18061 dst->peer_info[i].peer_type = 18062 WLAN_WIFI_POS_PASN_SECURE_PEER; 18063 else 18064 dst->peer_info[i].peer_type = 18065 WLAN_WIFI_POS_PASN_UNSECURE_PEER; 18066 if (security_mode & WLAN_PASN_LTF_KEY_SEED_REQUIRED) 18067 dst->peer_info[i].is_ltf_keyseed_required = true; 18068 18069 dst->peer_info[i].force_self_mac_usage = 18070 WMI_RTT_PASN_PEER_CREATE_FORCE_SELF_MAC_USE_GET( 18071 buf->control_flag); 18072 dst->num_peers++; 18073 buf++; 18074 } 18075 18076 return QDF_STATUS_SUCCESS; 18077 } 18078 18079 static QDF_STATUS 18080 extract_pasn_peer_delete_req_event_tlv(wmi_unified_t wmi_handle, void *evt_buf, 18081 struct wifi_pos_pasn_peer_data *dst) 18082 { 18083 WMI_RTT_PASN_PEER_DELETE_EVENTID_param_tlvs *param_buf; 18084 wmi_rtt_pasn_peer_delete_event_fixed_param *fixed_param; 18085 wmi_rtt_pasn_peer_delete_param *buf; 18086 uint8_t i; 18087 18088 param_buf = (WMI_RTT_PASN_PEER_DELETE_EVENTID_param_tlvs *)evt_buf; 18089 if (!param_buf) { 18090 wmi_err("Invalid peer_delete evt buffer"); 18091 return QDF_STATUS_E_INVAL; 18092 } 18093 18094 fixed_param = param_buf->fixed_param; 18095 18096 if (param_buf->num_rtt_pasn_peer_param > 18097 ((WMI_SVC_MSG_MAX_SIZE - sizeof(*fixed_param)) / 18098 sizeof(wmi_rtt_pasn_peer_delete_param))) { 18099 wmi_err("Invalid TLV size"); 18100 return QDF_STATUS_E_INVAL; 18101 } 18102 18103 if (!param_buf->num_rtt_pasn_peer_param || 18104 param_buf->num_rtt_pasn_peer_param > WLAN_MAX_11AZ_PEERS) { 18105 wmi_err("Invalid num TLV:%d", 18106 param_buf->num_rtt_pasn_peer_param); 18107 return QDF_STATUS_E_INVAL; 18108 } 18109 18110 dst->vdev_id = fixed_param->vdev_id; 18111 if (dst->vdev_id >= WLAN_UMAC_PDEV_MAX_VDEVS) { 18112 wmi_err("Invalid vdev id:%d", dst->vdev_id); 18113 return QDF_STATUS_E_INVAL; 18114 } 18115 18116 buf = param_buf->rtt_pasn_peer_param; 18117 if (!buf) { 18118 wmi_err("NULL peer param TLV"); 18119 return QDF_STATUS_E_INVAL; 18120 } 18121 18122 for (i = 0; i < param_buf->num_rtt_pasn_peer_param; i++) { 18123 WMI_MAC_ADDR_TO_CHAR_ARRAY(&buf->peer_mac_addr, 18124 dst->peer_info[i].peer_mac.bytes); 18125 dst->peer_info[i].control_flags = buf->control_flag; 18126 18127 dst->num_peers++; 18128 buf++; 18129 } 18130 18131 return QDF_STATUS_SUCCESS; 18132 } 18133 18134 static QDF_STATUS 18135 send_rtt_pasn_auth_status_cmd_tlv(wmi_unified_t wmi_handle, 18136 struct wlan_pasn_auth_status *data) 18137 { 18138 QDF_STATUS status; 18139 wmi_buf_t buf; 18140 wmi_rtt_pasn_auth_status_cmd_fixed_param *fixed_param; 18141 uint8_t *buf_ptr; 18142 uint8_t i; 18143 size_t len = sizeof(*fixed_param) + 18144 data->num_peers * sizeof(wmi_rtt_pasn_auth_status_param) + 18145 WMI_TLV_HDR_SIZE; 18146 18147 buf = wmi_buf_alloc(wmi_handle, len); 18148 if (!buf) { 18149 wmi_err("wmi_buf_alloc failed"); 18150 return QDF_STATUS_E_FAILURE; 18151 } 18152 buf_ptr = (uint8_t *)wmi_buf_data(buf); 18153 fixed_param = 18154 (wmi_rtt_pasn_auth_status_cmd_fixed_param *)wmi_buf_data(buf); 18155 WMITLV_SET_HDR(&fixed_param->tlv_header, 18156 WMITLV_TAG_STRUC_wmi_rtt_pasn_auth_status_cmd_fixed_param, 18157 WMITLV_GET_STRUCT_TLVLEN( 18158 wmi_rtt_pasn_auth_status_cmd_fixed_param)); 18159 buf_ptr += sizeof(*fixed_param); 18160 18161 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 18162 (data->num_peers * 18163 sizeof(wmi_rtt_pasn_auth_status_param))); 18164 buf_ptr += WMI_TLV_HDR_SIZE; 18165 18166 for (i = 0; i < data->num_peers; i++) { 18167 wmi_rtt_pasn_auth_status_param *auth_status_tlv = 18168 (wmi_rtt_pasn_auth_status_param *)buf_ptr; 18169 18170 WMITLV_SET_HDR(&auth_status_tlv->tlv_header, 18171 WMITLV_TAG_STRUC_wmi_rtt_pasn_auth_status_param, 18172 WMITLV_GET_STRUCT_TLVLEN(wmi_rtt_pasn_auth_status_param)); 18173 18174 WMI_CHAR_ARRAY_TO_MAC_ADDR(data->auth_status[i].peer_mac.bytes, 18175 &auth_status_tlv->peer_mac_addr); 18176 WMI_CHAR_ARRAY_TO_MAC_ADDR(data->auth_status[i].self_mac.bytes, 18177 &auth_status_tlv->source_mac_addr); 18178 auth_status_tlv->status = data->auth_status[i].status; 18179 wmi_debug("peer_mac: " QDF_MAC_ADDR_FMT " self_mac:" QDF_MAC_ADDR_FMT " status:%d", 18180 QDF_MAC_ADDR_REF(data->auth_status[i].peer_mac.bytes), 18181 QDF_MAC_ADDR_REF(data->auth_status[i].self_mac.bytes), 18182 auth_status_tlv->status); 18183 18184 buf_ptr += sizeof(wmi_rtt_pasn_auth_status_param); 18185 } 18186 18187 wmi_mtrace(WMI_RTT_PASN_AUTH_STATUS_CMD, 0, 0); 18188 status = wmi_unified_cmd_send(wmi_handle, buf, len, 18189 WMI_RTT_PASN_AUTH_STATUS_CMD); 18190 if (QDF_IS_STATUS_ERROR(status)) { 18191 wmi_err("Failed to send Auth status command ret = %d", status); 18192 wmi_buf_free(buf); 18193 } 18194 18195 return status; 18196 } 18197 18198 static QDF_STATUS 18199 send_rtt_pasn_deauth_cmd_tlv(wmi_unified_t wmi_handle, 18200 struct qdf_mac_addr *peer_mac) 18201 { 18202 QDF_STATUS status; 18203 wmi_buf_t buf; 18204 wmi_rtt_pasn_deauth_cmd_fixed_param *fixed_param; 18205 size_t len = sizeof(*fixed_param); 18206 18207 buf = wmi_buf_alloc(wmi_handle, len); 18208 if (!buf) { 18209 wmi_err("wmi_buf_alloc failed"); 18210 return QDF_STATUS_E_FAILURE; 18211 } 18212 fixed_param = 18213 (wmi_rtt_pasn_deauth_cmd_fixed_param *)wmi_buf_data(buf); 18214 WMITLV_SET_HDR(&fixed_param->tlv_header, 18215 WMITLV_TAG_STRUC_wmi_rtt_pasn_deauth_cmd_fixed_param, 18216 WMITLV_GET_STRUCT_TLVLEN( 18217 wmi_rtt_pasn_deauth_cmd_fixed_param)); 18218 WMI_CHAR_ARRAY_TO_MAC_ADDR(peer_mac->bytes, 18219 &fixed_param->peer_mac_addr); 18220 18221 wmi_mtrace(WMI_RTT_PASN_DEAUTH_CMD, 0, 0); 18222 status = wmi_unified_cmd_send(wmi_handle, buf, len, 18223 WMI_RTT_PASN_DEAUTH_CMD); 18224 if (QDF_IS_STATUS_ERROR(status)) { 18225 wmi_err("Failed to send pasn deauth command ret = %d", status); 18226 wmi_buf_free(buf); 18227 } 18228 18229 return status; 18230 } 18231 #endif /* WLAN_FEATURE_RTT_11AZ_SUPPORT */ 18232 18233 static QDF_STATUS 18234 send_vdev_set_ltf_key_seed_cmd_tlv(wmi_unified_t wmi_handle, 18235 struct wlan_crypto_ltf_keyseed_data *data) 18236 { 18237 QDF_STATUS status; 18238 wmi_buf_t buf; 18239 wmi_vdev_set_ltf_key_seed_cmd_fixed_param *fixed_param; 18240 uint8_t *buf_ptr; 18241 size_t len = sizeof(*fixed_param) + data->key_seed_len + 18242 WMI_TLV_HDR_SIZE; 18243 18244 buf = wmi_buf_alloc(wmi_handle, len); 18245 if (!buf) { 18246 wmi_err("wmi_buf_alloc failed"); 18247 return QDF_STATUS_E_FAILURE; 18248 } 18249 18250 buf_ptr = (uint8_t *)wmi_buf_data(buf); 18251 fixed_param = 18252 (wmi_vdev_set_ltf_key_seed_cmd_fixed_param *)wmi_buf_data(buf); 18253 WMITLV_SET_HDR(&fixed_param->tlv_header, 18254 WMITLV_TAG_STRUC_wmi_vdev_set_ltf_key_seed_cmd_fixed_param, 18255 WMITLV_GET_STRUCT_TLVLEN( 18256 wmi_vdev_set_ltf_key_seed_cmd_fixed_param)); 18257 18258 fixed_param->vdev_id = data->vdev_id; 18259 WMI_CHAR_ARRAY_TO_MAC_ADDR(data->peer_mac_addr.bytes, 18260 &fixed_param->peer_macaddr); 18261 fixed_param->key_seed_len = data->key_seed_len; 18262 fixed_param->rsn_authmode = data->rsn_authmode; 18263 18264 buf_ptr += sizeof(*fixed_param); 18265 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, 18266 (fixed_param->key_seed_len * sizeof(A_UINT8))); 18267 buf_ptr += WMI_TLV_HDR_SIZE; 18268 18269 qdf_mem_copy(buf_ptr, data->key_seed, fixed_param->key_seed_len); 18270 18271 wmi_mtrace(WMI_VDEV_SET_LTF_KEY_SEED_CMDID, 0, 0); 18272 status = wmi_unified_cmd_send(wmi_handle, buf, len, 18273 WMI_VDEV_SET_LTF_KEY_SEED_CMDID); 18274 if (QDF_IS_STATUS_ERROR(status)) { 18275 wmi_err("Failed to send ltf keyseed command ret = %d", status); 18276 wmi_buf_free(buf); 18277 } 18278 18279 return status; 18280 } 18281 18282 /** 18283 * extract_hw_mode_resp_event_status_tlv() - Extract HW mode change status 18284 * @wmi_handle: wmi handle 18285 * @evt_buf: pointer to event buffer 18286 * @cmd_status: status of HW mode change command 18287 * 18288 * Return: QDF_STATUS_SUCCESS on success or proper error code. 18289 */ 18290 static QDF_STATUS 18291 extract_hw_mode_resp_event_status_tlv(wmi_unified_t wmi_handle, void *evt_buf, 18292 uint32_t *cmd_status) 18293 { 18294 WMI_PDEV_SET_HW_MODE_RESP_EVENTID_param_tlvs *param_buf; 18295 wmi_pdev_set_hw_mode_response_event_fixed_param *fixed_param; 18296 18297 param_buf = (WMI_PDEV_SET_HW_MODE_RESP_EVENTID_param_tlvs *)evt_buf; 18298 if (!param_buf) { 18299 wmi_err("Invalid mode change event buffer"); 18300 return QDF_STATUS_E_INVAL; 18301 } 18302 18303 fixed_param = param_buf->fixed_param; 18304 if (!fixed_param) { 18305 wmi_err("Invalid fixed param"); 18306 return QDF_STATUS_E_INVAL; 18307 } 18308 18309 *cmd_status = fixed_param->status; 18310 return QDF_STATUS_SUCCESS; 18311 } 18312 18313 #ifdef FEATURE_ANI_LEVEL_REQUEST 18314 static QDF_STATUS send_ani_level_cmd_tlv(wmi_unified_t wmi_handle, 18315 uint32_t *freqs, 18316 uint8_t num_freqs) 18317 { 18318 wmi_buf_t buf; 18319 wmi_get_channel_ani_cmd_fixed_param *cmd; 18320 QDF_STATUS ret; 18321 uint32_t len; 18322 A_UINT32 *chan_list; 18323 uint8_t i, *buf_ptr; 18324 18325 len = sizeof(wmi_get_channel_ani_cmd_fixed_param) + 18326 WMI_TLV_HDR_SIZE + 18327 num_freqs * sizeof(A_UINT32); 18328 18329 buf = wmi_buf_alloc(wmi_handle, len); 18330 if (!buf) 18331 return QDF_STATUS_E_FAILURE; 18332 18333 buf_ptr = (uint8_t *)wmi_buf_data(buf); 18334 cmd = (wmi_get_channel_ani_cmd_fixed_param *)buf_ptr; 18335 WMITLV_SET_HDR(&cmd->tlv_header, 18336 WMITLV_TAG_STRUC_wmi_get_channel_ani_cmd_fixed_param, 18337 WMITLV_GET_STRUCT_TLVLEN( 18338 wmi_get_channel_ani_cmd_fixed_param)); 18339 18340 buf_ptr += sizeof(wmi_get_channel_ani_cmd_fixed_param); 18341 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, 18342 (num_freqs * sizeof(A_UINT32))); 18343 18344 chan_list = (A_UINT32 *)(buf_ptr + WMI_TLV_HDR_SIZE); 18345 for (i = 0; i < num_freqs; i++) { 18346 chan_list[i] = freqs[i]; 18347 wmi_debug("Requesting ANI for channel[%d]", chan_list[i]); 18348 } 18349 18350 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 18351 WMI_GET_CHANNEL_ANI_CMDID); 18352 18353 if (QDF_IS_STATUS_ERROR(ret)) { 18354 wmi_err("WMI_GET_CHANNEL_ANI_CMDID send error %d", ret); 18355 wmi_buf_free(buf); 18356 } 18357 18358 return ret; 18359 } 18360 18361 static QDF_STATUS extract_ani_level_tlv(uint8_t *evt_buf, 18362 struct wmi_host_ani_level_event **info, 18363 uint32_t *num_freqs) 18364 { 18365 WMI_GET_CHANNEL_ANI_EVENTID_param_tlvs *param_buf; 18366 wmi_get_channel_ani_event_fixed_param *fixed_param; 18367 wmi_channel_ani_info_tlv_param *tlv_params; 18368 uint8_t *buf_ptr, i; 18369 18370 param_buf = (WMI_GET_CHANNEL_ANI_EVENTID_param_tlvs *)evt_buf; 18371 if (!param_buf) { 18372 wmi_err("Invalid ani level event buffer"); 18373 return QDF_STATUS_E_INVAL; 18374 } 18375 18376 fixed_param = 18377 (wmi_get_channel_ani_event_fixed_param *)param_buf->fixed_param; 18378 if (!fixed_param) { 18379 wmi_err("Invalid fixed param"); 18380 return QDF_STATUS_E_INVAL; 18381 } 18382 18383 buf_ptr = (uint8_t *)fixed_param; 18384 buf_ptr += sizeof(wmi_get_channel_ani_event_fixed_param); 18385 buf_ptr += WMI_TLV_HDR_SIZE; 18386 18387 *num_freqs = param_buf->num_ani_info; 18388 if (*num_freqs > MAX_NUM_FREQS_FOR_ANI_LEVEL) { 18389 wmi_err("Invalid number of freqs received"); 18390 return QDF_STATUS_E_INVAL; 18391 } 18392 18393 *info = qdf_mem_malloc(*num_freqs * 18394 sizeof(struct wmi_host_ani_level_event)); 18395 if (!(*info)) 18396 return QDF_STATUS_E_NOMEM; 18397 18398 tlv_params = (wmi_channel_ani_info_tlv_param *)buf_ptr; 18399 for (i = 0; i < param_buf->num_ani_info; i++) { 18400 (*info)[i].ani_level = tlv_params->ani_level; 18401 (*info)[i].chan_freq = tlv_params->chan_freq; 18402 tlv_params++; 18403 } 18404 18405 return QDF_STATUS_SUCCESS; 18406 } 18407 #endif /* FEATURE_ANI_LEVEL_REQUEST */ 18408 18409 #ifdef WLAN_FEATURE_ROAM_OFFLOAD 18410 /** 18411 * convert_wtc_scan_mode() - Function to convert TLV specific 18412 * ROAM_TRIGGER_SCAN_MODE scan mode to unified Roam trigger scan mode enum 18413 * @scan_mode: scan freq scheme coming from firmware 18414 * 18415 * Return: ROAM_TRIGGER_SCAN_MODE 18416 */ 18417 static enum roam_scan_freq_scheme 18418 convert_wtc_scan_mode(WMI_ROAM_TRIGGER_SCAN_MODE scan_mode) 18419 { 18420 switch (scan_mode) { 18421 case ROAM_TRIGGER_SCAN_MODE_NO_SCAN_DISCONNECTION: 18422 return ROAM_SCAN_FREQ_SCHEME_NO_SCAN; 18423 case ROAM_TRIGGER_SCAN_MODE_PARTIAL: 18424 return ROAM_SCAN_FREQ_SCHEME_PARTIAL_SCAN; 18425 case ROAM_TRIGGER_SCAN_MODE_FULL: 18426 return ROAM_SCAN_FREQ_SCHEME_FULL_SCAN; 18427 default: 18428 return ROAM_SCAN_FREQ_SCHEME_NONE; 18429 } 18430 } 18431 18432 static uint32_t wmi_convert_fw_to_cm_trig_reason(uint32_t fw_trig_reason) 18433 { 18434 switch (fw_trig_reason) { 18435 case WMI_ROAM_TRIGGER_REASON_NONE: 18436 return ROAM_TRIGGER_REASON_NONE; 18437 case WMI_ROAM_TRIGGER_REASON_PER: 18438 return ROAM_TRIGGER_REASON_PER; 18439 case WMI_ROAM_TRIGGER_REASON_BMISS: 18440 return ROAM_TRIGGER_REASON_BMISS; 18441 case WMI_ROAM_TRIGGER_REASON_LOW_RSSI: 18442 return ROAM_TRIGGER_REASON_LOW_RSSI; 18443 case WMI_ROAM_TRIGGER_REASON_HIGH_RSSI: 18444 return ROAM_TRIGGER_REASON_HIGH_RSSI; 18445 case WMI_ROAM_TRIGGER_REASON_PERIODIC: 18446 return ROAM_TRIGGER_REASON_PERIODIC; 18447 case WMI_ROAM_TRIGGER_REASON_MAWC: 18448 return ROAM_TRIGGER_REASON_MAWC; 18449 case WMI_ROAM_TRIGGER_REASON_DENSE: 18450 return ROAM_TRIGGER_REASON_DENSE; 18451 case WMI_ROAM_TRIGGER_REASON_BACKGROUND: 18452 return ROAM_TRIGGER_REASON_BACKGROUND; 18453 case WMI_ROAM_TRIGGER_REASON_FORCED: 18454 return ROAM_TRIGGER_REASON_FORCED; 18455 case WMI_ROAM_TRIGGER_REASON_BTM: 18456 return ROAM_TRIGGER_REASON_BTM; 18457 case WMI_ROAM_TRIGGER_REASON_UNIT_TEST: 18458 return ROAM_TRIGGER_REASON_UNIT_TEST; 18459 case WMI_ROAM_TRIGGER_REASON_BSS_LOAD: 18460 return ROAM_TRIGGER_REASON_BSS_LOAD; 18461 case WMI_ROAM_TRIGGER_REASON_DEAUTH: 18462 return ROAM_TRIGGER_REASON_DEAUTH; 18463 case WMI_ROAM_TRIGGER_REASON_IDLE: 18464 return ROAM_TRIGGER_REASON_IDLE; 18465 case WMI_ROAM_TRIGGER_REASON_STA_KICKOUT: 18466 return ROAM_TRIGGER_REASON_STA_KICKOUT; 18467 case WMI_ROAM_TRIGGER_REASON_ESS_RSSI: 18468 return ROAM_TRIGGER_REASON_ESS_RSSI; 18469 case WMI_ROAM_TRIGGER_REASON_WTC_BTM: 18470 return ROAM_TRIGGER_REASON_WTC_BTM; 18471 case WMI_ROAM_TRIGGER_REASON_PMK_TIMEOUT: 18472 return ROAM_TRIGGER_REASON_PMK_TIMEOUT; 18473 case WMI_ROAM_TRIGGER_REASON_BTC: 18474 return ROAM_TRIGGER_REASON_BTC; 18475 case WMI_ROAM_TRIGGER_EXT_REASON_MAX: 18476 return ROAM_TRIGGER_REASON_MAX; 18477 default: 18478 return ROAM_TRIGGER_REASON_NONE; 18479 } 18480 } 18481 18482 /** 18483 * extract_roam_11kv_candidate_info - Extract btm candidate info 18484 * @wmi_handle: wmi_handle 18485 * @evt_buf: Event buffer 18486 * @dst_info: Destination buffer 18487 * @btm_idx: BTM index 18488 * @num_cand: Number of candidates 18489 * 18490 * Return: QDF_STATUS 18491 */ 18492 static QDF_STATUS 18493 extract_roam_11kv_candidate_info(wmi_unified_t wmi_handle, void *evt_buf, 18494 struct wmi_btm_req_candidate_info *dst_info, 18495 uint8_t btm_idx, uint16_t num_cand) 18496 { 18497 WMI_ROAM_STATS_EVENTID_param_tlvs *param_buf; 18498 wmi_roam_btm_request_candidate_info *src_data; 18499 uint8_t i; 18500 18501 param_buf = (WMI_ROAM_STATS_EVENTID_param_tlvs *)evt_buf; 18502 if (!param_buf || !param_buf->roam_btm_request_candidate_info || 18503 !param_buf->num_roam_btm_request_candidate_info || 18504 (btm_idx + 18505 num_cand) > param_buf->num_roam_btm_request_candidate_info) 18506 return QDF_STATUS_SUCCESS; 18507 18508 src_data = ¶m_buf->roam_btm_request_candidate_info[btm_idx]; 18509 if (num_cand > WLAN_MAX_BTM_CANDIDATE) 18510 num_cand = WLAN_MAX_BTM_CANDIDATE; 18511 for (i = 0; i < num_cand; i++) { 18512 WMI_MAC_ADDR_TO_CHAR_ARRAY(&src_data->btm_candidate_bssid, 18513 dst_info->candidate_bssid.bytes); 18514 dst_info->preference = src_data->preference; 18515 src_data++; 18516 dst_info++; 18517 } 18518 18519 return QDF_STATUS_SUCCESS; 18520 } 18521 18522 static enum roam_trigger_sub_reason 18523 wmi_convert_roam_sub_reason(WMI_ROAM_TRIGGER_SUB_REASON_ID subreason) 18524 { 18525 switch (subreason) { 18526 case WMI_ROAM_TRIGGER_SUB_REASON_PERIODIC_TIMER: 18527 return ROAM_TRIGGER_SUB_REASON_PERIODIC_TIMER; 18528 case WMI_ROAM_TRIGGER_SUB_REASON_INACTIVITY_TIMER: 18529 return ROAM_TRIGGER_SUB_REASON_INACTIVITY_TIMER_LOW_RSSI; 18530 case WMI_ROAM_TRIGGER_SUB_REASON_BTM_DI_TIMER: 18531 return ROAM_TRIGGER_SUB_REASON_BTM_DI_TIMER; 18532 case WMI_ROAM_TRIGGER_SUB_REASON_FULL_SCAN: 18533 return ROAM_TRIGGER_SUB_REASON_FULL_SCAN; 18534 case WMI_ROAM_TRIGGER_SUB_REASON_LOW_RSSI_PERIODIC: 18535 return ROAM_TRIGGER_SUB_REASON_LOW_RSSI_PERIODIC; 18536 case WMI_ROAM_TRIGGER_SUB_REASON_CU_PERIODIC: 18537 return ROAM_TRIGGER_SUB_REASON_CU_PERIODIC; 18538 case WMI_ROAM_TRIGGER_SUB_REASON_PERIODIC_TIMER_AFTER_INACTIVITY: 18539 return ROAM_TRIGGER_SUB_REASON_PERIODIC_TIMER_AFTER_INACTIVITY; 18540 case WMI_ROAM_TRIGGER_SUB_REASON_PERIODIC_TIMER_AFTER_INACTIVITY_CU: 18541 return ROAM_TRIGGER_SUB_REASON_PERIODIC_TIMER_AFTER_INACTIVITY_CU; 18542 case WMI_ROAM_TRIGGER_SUB_REASON_INACTIVITY_TIMER_CU: 18543 return ROAM_TRIGGER_SUB_REASON_INACTIVITY_TIMER_CU; 18544 default: 18545 break; 18546 } 18547 18548 return 0; 18549 } 18550 18551 /** 18552 * wlan_roam_fail_reason_code() - Convert FW enum to Host enum 18553 * @wmi_roam_fail_reason: roam fail enum 18554 * 18555 * Return: Roaming failure reason codes 18556 */ 18557 static enum wlan_roam_failure_reason_code 18558 wlan_roam_fail_reason_code(uint16_t wmi_roam_fail_reason) 18559 { 18560 switch (wmi_roam_fail_reason) { 18561 case WMI_ROAM_FAIL_REASON_NO_SCAN_START: 18562 return ROAM_FAIL_REASON_NO_SCAN_START; 18563 case WMI_ROAM_FAIL_REASON_NO_AP_FOUND: 18564 return ROAM_FAIL_REASON_NO_AP_FOUND; 18565 case WMI_ROAM_FAIL_REASON_NO_CAND_AP_FOUND: 18566 return ROAM_FAIL_REASON_NO_CAND_AP_FOUND; 18567 case WMI_ROAM_FAIL_REASON_HOST: 18568 return ROAM_FAIL_REASON_HOST; 18569 case WMI_ROAM_FAIL_REASON_AUTH_SEND: 18570 return ROAM_FAIL_REASON_AUTH_SEND; 18571 case WMI_ROAM_FAIL_REASON_AUTH_RECV: 18572 return ROAM_FAIL_REASON_AUTH_RECV; 18573 case WMI_ROAM_FAIL_REASON_NO_AUTH_RESP: 18574 return ROAM_FAIL_REASON_NO_AUTH_RESP; 18575 case WMI_ROAM_FAIL_REASON_REASSOC_SEND: 18576 return ROAM_FAIL_REASON_REASSOC_SEND; 18577 case WMI_ROAM_FAIL_REASON_REASSOC_RECV: 18578 return ROAM_FAIL_REASON_REASSOC_RECV; 18579 case WMI_ROAM_FAIL_REASON_NO_REASSOC_RESP: 18580 return ROAM_FAIL_REASON_NO_REASSOC_RESP; 18581 case WMI_ROAM_FAIL_REASON_EAPOL_TIMEOUT: 18582 return ROAM_FAIL_REASON_EAPOL_TIMEOUT; 18583 case WMI_ROAM_FAIL_REASON_MLME: 18584 return ROAM_FAIL_REASON_MLME; 18585 case WMI_ROAM_FAIL_REASON_INTERNAL_ABORT: 18586 return ROAM_FAIL_REASON_INTERNAL_ABORT; 18587 case WMI_ROAM_FAIL_REASON_SCAN_START: 18588 return ROAM_FAIL_REASON_SCAN_START; 18589 case WMI_ROAM_FAIL_REASON_AUTH_NO_ACK: 18590 return ROAM_FAIL_REASON_AUTH_NO_ACK; 18591 case WMI_ROAM_FAIL_REASON_AUTH_INTERNAL_DROP: 18592 return ROAM_FAIL_REASON_AUTH_INTERNAL_DROP; 18593 case WMI_ROAM_FAIL_REASON_REASSOC_NO_ACK: 18594 return ROAM_FAIL_REASON_REASSOC_NO_ACK; 18595 case WMI_ROAM_FAIL_REASON_REASSOC_INTERNAL_DROP: 18596 return ROAM_FAIL_REASON_REASSOC_INTERNAL_DROP; 18597 case WMI_ROAM_FAIL_REASON_EAPOL_M2_SEND: 18598 return ROAM_FAIL_REASON_EAPOL_M2_SEND; 18599 case WMI_ROAM_FAIL_REASON_EAPOL_M2_INTERNAL_DROP: 18600 return ROAM_FAIL_REASON_EAPOL_M2_INTERNAL_DROP; 18601 case WMI_ROAM_FAIL_REASON_EAPOL_M2_NO_ACK: 18602 return ROAM_FAIL_REASON_EAPOL_M2_NO_ACK; 18603 case WMI_ROAM_FAIL_REASON_EAPOL_M3_TIMEOUT: 18604 return ROAM_FAIL_REASON_EAPOL_M3_TIMEOUT; 18605 case WMI_ROAM_FAIL_REASON_EAPOL_M4_SEND: 18606 return ROAM_FAIL_REASON_EAPOL_M4_SEND; 18607 case WMI_ROAM_FAIL_REASON_EAPOL_M4_INTERNAL_DROP: 18608 return ROAM_FAIL_REASON_EAPOL_M4_INTERNAL_DROP; 18609 case WMI_ROAM_FAIL_REASON_EAPOL_M4_NO_ACK: 18610 return ROAM_FAIL_REASON_EAPOL_M4_NO_ACK; 18611 case WMI_ROAM_FAIL_REASON_NO_SCAN_FOR_FINAL_BMISS: 18612 return ROAM_FAIL_REASON_NO_SCAN_FOR_FINAL_BMISS; 18613 case WMI_ROAM_FAIL_REASON_DISCONNECT: 18614 return ROAM_FAIL_REASON_DISCONNECT; 18615 case WMI_ROAM_FAIL_REASON_SYNC: 18616 return ROAM_FAIL_REASON_SYNC; 18617 case WMI_ROAM_FAIL_REASON_SAE_INVALID_PMKID: 18618 return ROAM_FAIL_REASON_SAE_INVALID_PMKID; 18619 case WMI_ROAM_FAIL_REASON_SAE_PREAUTH_TIMEOUT: 18620 return ROAM_FAIL_REASON_SAE_PREAUTH_TIMEOUT; 18621 case WMI_ROAM_FAIL_REASON_SAE_PREAUTH_FAIL: 18622 return ROAM_FAIL_REASON_SAE_PREAUTH_FAIL; 18623 case WMI_ROAM_FAIL_REASON_UNABLE_TO_START_ROAM_HO: 18624 return ROAM_FAIL_REASON_UNABLE_TO_START_ROAM_HO; 18625 default: 18626 return ROAM_FAIL_REASON_UNKNOWN; 18627 } 18628 } 18629 18630 /** 18631 * wmi_convert_to_cm_roam_invoke_reason() - Convert FW enum to Host enum 18632 * @reason: roam invoke reason from fw 18633 * 18634 * Return: Roam invoke reason code defined in host driver 18635 */ 18636 static enum roam_invoke_reason 18637 wmi_convert_to_cm_roam_invoke_reason(enum wlan_roam_invoke_reason reason) 18638 { 18639 switch (reason) { 18640 case ROAM_INVOKE_REASON_UNDEFINED: 18641 return WLAN_ROAM_STATS_INVOKE_REASON_UNDEFINED; 18642 case ROAM_INVOKE_REASON_NUD_FAILURE: 18643 return WLAN_ROAM_STATS_INVOKE_REASON_NUD_FAILURE; 18644 case ROAM_INVOKE_REASON_USER_SPACE: 18645 return WLAN_ROAM_STATS_INVOKE_REASON_USER_SPACE; 18646 default: 18647 return WLAN_ROAM_STATS_INVOKE_REASON_UNDEFINED; 18648 } 18649 } 18650 18651 /** 18652 * wmi_convert_to_cm_roam_tx_fail_reason() - Convert FW enum to Host enum 18653 * @tx_fail_reason: roam tx fail reason from fw 18654 * 18655 * Return: Roam tx fail reason code defined in host driver 18656 */ 18657 static enum roam_tx_failures_reason 18658 wmi_convert_to_cm_roam_tx_fail_reason(PEER_KICKOUT_REASON tx_fail_reason) 18659 { 18660 switch (tx_fail_reason) { 18661 case WMI_PEER_STA_KICKOUT_REASON_UNSPECIFIED: 18662 return WLAN_ROAM_STATS_KICKOUT_REASON_UNSPECIFIED; 18663 case WMI_PEER_STA_KICKOUT_REASON_XRETRY: 18664 return WLAN_ROAM_STATS_KICKOUT_REASON_XRETRY; 18665 case WMI_PEER_STA_KICKOUT_REASON_INACTIVITY: 18666 return WLAN_ROAM_STATS_KICKOUT_REASON_INACTIVITY; 18667 case WMI_PEER_STA_KICKOUT_REASON_IBSS_DISCONNECT: 18668 return WLAN_ROAM_STATS_KICKOUT_REASON_IBSS_DISCONNECT; 18669 case WMI_PEER_STA_KICKOUT_REASON_TDLS_DISCONNECT: 18670 return WLAN_ROAM_STATS_KICKOUT_REASON_TDLS_DISCONNECT; 18671 case WMI_PEER_STA_KICKOUT_REASON_SA_QUERY_TIMEOUT: 18672 return WLAN_ROAM_STATS_KICKOUT_REASON_SA_QUERY_TIMEOUT; 18673 case WMI_PEER_STA_KICKOUT_REASON_ROAMING_EVENT: 18674 return WLAN_ROAM_STATS_KICKOUT_REASON_ROAMING_EVENT; 18675 default: 18676 return WLAN_ROAM_STATS_KICKOUT_REASON_UNSPECIFIED; 18677 } 18678 } 18679 18680 /** 18681 * wmi_convert_roam_abort_reason() - Convert FW enum to Host enum 18682 * @abort_reason: roam abort reason from fw 18683 * 18684 * Return: Roam abort reason code defined in host driver 18685 */ 18686 static enum roam_abort_reason 18687 wmi_convert_roam_abort_reason(WMI_ROAM_FAIL_SUB_REASON_ID abort_reason) 18688 { 18689 switch (abort_reason) { 18690 case WMI_ROAM_ABORT_UNSPECIFIED: 18691 return WLAN_ROAM_STATS_ABORT_UNSPECIFIED; 18692 case WMI_ROAM_ABORT_LOWRSSI_DATA_RSSI_HIGH: 18693 return WLAN_ROAM_STATS_ABORT_LOWRSSI_DATA_RSSI_HIGH; 18694 case WMI_ROAM_ABORT_LOWRSSI_LINK_SPEED_GOOD: 18695 return WLAN_ROAM_STATS_ABORT_LOWRSSI_LINK_SPEED_GOOD; 18696 case WMI_ROAM_ABORT_BG_DATA_RSSI_HIGH: 18697 return WLAN_ROAM_STATS_ABORT_BG_DATA_RSSI_HIGH; 18698 case WMI_ROAM_ABORT_BG_RSSI_ABOVE_THRESHOLD: 18699 return WLAN_ROAM_STATS_ABORT_BG_RSSI_ABOVE_THRESHOLD; 18700 default: 18701 return WLAN_ROAM_STATS_ABORT_UNSPECIFIED; 18702 } 18703 } 18704 18705 /** 18706 * wlan_roam_scan_type() - Convert FW enum to Host enum 18707 * @scan_type: roam scan type from fw 18708 * 18709 * Return: Roam scan type defined in host driver 18710 */ 18711 static enum roam_stats_scan_type 18712 wlan_roam_scan_type(uint32_t scan_type) 18713 { 18714 switch (scan_type) { 18715 case 0: 18716 return ROAM_STATS_SCAN_TYPE_PARTIAL; 18717 case 1: 18718 return ROAM_STATS_SCAN_TYPE_FULL; 18719 case 2: 18720 return ROAM_STATS_SCAN_TYPE_NO_SCAN; 18721 case 3: 18722 return ROAM_STATS_SCAN_TYPE_HIGHER_BAND_5GHZ_6GHZ; 18723 case 4: 18724 return ROAM_STATS_SCAN_TYPE_HIGHER_BAND_6GHZ; 18725 default: 18726 return ROAM_STATS_SCAN_TYPE_PARTIAL; 18727 } 18728 } 18729 18730 /** 18731 * wlan_roam_dwell_type() - Convert FW enum to Host enum 18732 * @dwell_type: roam channel scan dwell type from fw 18733 * 18734 * Return: Roam channel scan dwell type defined in host driver 18735 */ 18736 static enum roam_scan_dwell_type 18737 wlan_roam_dwell_type(uint32_t dwell_type) 18738 { 18739 switch (dwell_type) { 18740 case 0: 18741 return WLAN_ROAM_DWELL_TYPE_UNSPECIFIED; 18742 case 1: 18743 return WLAN_ROAM_DWELL_ACTIVE_TYPE; 18744 case 2: 18745 return WLAN_ROAM_DWELL_PASSIVE_TYPE; 18746 default: 18747 return WLAN_ROAM_DWELL_TYPE_UNSPECIFIED; 18748 } 18749 } 18750 18751 #define WLAN_ROAM_PER_TX_RATE_OFFSET 0 18752 #define WLAN_ROAM_PER_RX_RATE_OFFSET 16 18753 #define WLAN_ROAM_BMISS_FINNAL_OFFSET 0 18754 #define WLAN_ROAM_BMISS_CONSECUTIVE_OFFSET 7 18755 #define WLAN_ROAM_BMISS_QOSNULL_OFFSET 24 18756 #define WLAN_ROAM_DENSE_ROAMABLE_OFFSET 0 18757 18758 /** 18759 * extract_roam_trigger_stats_tlv() - Extract the Roam trigger stats 18760 * from the WMI_ROAM_STATS_EVENTID 18761 * @wmi_handle: wmi handle 18762 * @evt_buf: Pointer to the event buffer 18763 * @trig: Pointer to destination structure to fill data 18764 * @idx: TLV id 18765 * @btm_idx: BTM index 18766 */ 18767 static QDF_STATUS 18768 extract_roam_trigger_stats_tlv(wmi_unified_t wmi_handle, void *evt_buf, 18769 struct wmi_roam_trigger_info *trig, uint8_t idx, 18770 uint8_t btm_idx) 18771 { 18772 WMI_ROAM_STATS_EVENTID_param_tlvs *param_buf; 18773 wmi_roam_trigger_reason *src_data = NULL; 18774 uint32_t trig_reason = 0; 18775 uint32_t fail_reason = 0; 18776 uint32_t abort = 0; 18777 uint32_t invoke = 0; 18778 uint32_t tx_fail = 0; 18779 wmi_roam_trigger_reason_cmm *cmn_data = NULL; 18780 wmi_roam_trigger_per *per_data = NULL; 18781 wmi_roam_trigger_bmiss *bmiss_data = NULL; 18782 wmi_roam_trigger_hi_rssi *hi_rssi_data = NULL; 18783 wmi_roam_trigger_dense *dense_data = NULL; 18784 wmi_roam_trigger_force *force_data = NULL; 18785 wmi_roam_trigger_btm *btm_data = NULL; 18786 wmi_roam_trigger_bss_load *bss_load_data = NULL; 18787 wmi_roam_trigger_deauth *deauth_data = NULL; 18788 wmi_roam_trigger_periodic *periodic_data = NULL; 18789 wmi_roam_trigger_rssi *rssi_data = NULL; 18790 wmi_roam_trigger_kickout *kickout_data = NULL; 18791 wmi_roam_result *roam_result = NULL; 18792 wmi_roam_scan_info *scan_info = NULL; 18793 18794 param_buf = (WMI_ROAM_STATS_EVENTID_param_tlvs *)evt_buf; 18795 if (!param_buf) { 18796 wmi_err("Param buf is NULL"); 18797 return QDF_STATUS_E_FAILURE; 18798 } 18799 18800 if (!param_buf->roam_result || idx >= param_buf->num_roam_result) 18801 wmi_err("roam_result or idx error.%u", idx); 18802 18803 if (!param_buf->roam_scan_info || idx >= param_buf->num_roam_scan_info) 18804 wmi_err("roam_scan_info or idx error.%u", idx); 18805 18806 trig->present = true; 18807 18808 if (param_buf->roam_scan_info) 18809 scan_info = ¶m_buf->roam_scan_info[idx]; 18810 18811 if (param_buf->roam_trigger_reason_cmm) 18812 cmn_data = ¶m_buf->roam_trigger_reason_cmm[idx]; 18813 18814 if (param_buf->roam_trigger_reason) 18815 src_data = ¶m_buf->roam_trigger_reason[idx]; 18816 18817 if (cmn_data) { 18818 trig_reason = cmn_data->trigger_reason; 18819 trig->trigger_reason = 18820 wmi_convert_fw_to_cm_trig_reason(trig_reason); 18821 trig->timestamp = cmn_data->timestamp; 18822 } else if (src_data) { 18823 trig_reason = src_data->trigger_reason; 18824 trig->trigger_reason = 18825 wmi_convert_fw_to_cm_trig_reason(trig_reason); 18826 trig->trigger_sub_reason = 18827 wmi_convert_roam_sub_reason(src_data->trigger_sub_reason); 18828 trig->current_rssi = src_data->current_rssi; 18829 trig->timestamp = src_data->timestamp; 18830 } 18831 18832 if (param_buf->roam_trigger_rssi) 18833 rssi_data = ¶m_buf->roam_trigger_rssi[idx]; 18834 18835 if (param_buf->roam_result) { 18836 roam_result = ¶m_buf->roam_result[idx]; 18837 18838 if (roam_result) { 18839 trig->roam_status = roam_result->roam_status; 18840 if (trig->roam_status) { 18841 fail_reason = roam_result->roam_fail_reason; 18842 trig->fail_reason = 18843 wlan_roam_fail_reason_code(fail_reason); 18844 18845 if (rssi_data) { 18846 abort = roam_result->roam_abort_reason; 18847 trig->abort_reason.abort_reason_code = 18848 wmi_convert_roam_abort_reason(abort); 18849 trig->abort_reason.data_rssi = 18850 rssi_data->data_rssi; 18851 trig->abort_reason.data_rssi_threshold = 18852 rssi_data->data_rssi_threshold; 18853 trig->abort_reason.rx_linkspeed_status = 18854 rssi_data->rx_linkspeed_status; 18855 } 18856 } 18857 } 18858 } 18859 18860 if (scan_info) 18861 trig->scan_type = 18862 wlan_roam_scan_type(scan_info->roam_scan_type); 18863 18864 switch (trig_reason) { 18865 case WMI_ROAM_TRIGGER_REASON_PER: 18866 if (param_buf->roam_trigger_per) 18867 per_data = ¶m_buf->roam_trigger_per[idx]; 18868 if (per_data) { 18869 trig->per_trig_data.tx_rate_thresh_percent = 18870 WMI_GET_BITS(per_data->rate_thresh_percnt, 18871 WLAN_ROAM_PER_RX_RATE_OFFSET, 8); 18872 trig->per_trig_data.rx_rate_thresh_percent = 18873 WMI_GET_BITS(per_data->rate_thresh_percnt, 18874 WLAN_ROAM_PER_TX_RATE_OFFSET, 8); 18875 } 18876 return QDF_STATUS_SUCCESS; 18877 18878 case WMI_ROAM_TRIGGER_REASON_BMISS: 18879 if (param_buf->roam_trigger_bmiss) 18880 bmiss_data = ¶m_buf->roam_trigger_bmiss[idx]; 18881 if (bmiss_data) { 18882 trig->bmiss_trig_data.final_bmiss_cnt = 18883 WMI_GET_BITS(bmiss_data->bmiss_status, 18884 WLAN_ROAM_BMISS_FINNAL_OFFSET, 7); 18885 trig->bmiss_trig_data.consecutive_bmiss_cnt = 18886 WMI_GET_BITS(bmiss_data->bmiss_status, 18887 WLAN_ROAM_BMISS_CONSECUTIVE_OFFSET, 18888 17); 18889 trig->bmiss_trig_data.qos_null_success = 18890 WMI_GET_BITS(bmiss_data->bmiss_status, 18891 WLAN_ROAM_BMISS_QOSNULL_OFFSET, 1); 18892 } 18893 return QDF_STATUS_SUCCESS; 18894 18895 case WMI_ROAM_TRIGGER_REASON_HIGH_RSSI: 18896 if (param_buf->roam_trigger_hi_rssi) 18897 hi_rssi_data = ¶m_buf->roam_trigger_hi_rssi[idx]; 18898 18899 if (hi_rssi_data && cmn_data) { 18900 trig->hi_rssi_trig_data.current_rssi = 18901 (uint8_t)cmn_data->current_rssi; 18902 trig->hi_rssi_trig_data.hirssi_threshold = 18903 (uint8_t)hi_rssi_data->hi_rssi_threshold; 18904 } 18905 return QDF_STATUS_SUCCESS; 18906 18907 case WMI_ROAM_TRIGGER_REASON_MAWC: 18908 case WMI_ROAM_TRIGGER_REASON_DENSE: 18909 if (param_buf->roam_trigger_dense) 18910 dense_data = ¶m_buf->roam_trigger_dense[idx]; 18911 if (dense_data) { 18912 trig->congestion_trig_data.rx_tput = 18913 dense_data->rx_tput; 18914 trig->congestion_trig_data.tx_tput = 18915 dense_data->tx_tput; 18916 trig->congestion_trig_data.roamable_count = 18917 WMI_GET_BITS(dense_data->dense_status, 18918 WLAN_ROAM_DENSE_ROAMABLE_OFFSET, 18919 8); 18920 } 18921 return QDF_STATUS_SUCCESS; 18922 18923 case WMI_ROAM_TRIGGER_REASON_BACKGROUND: 18924 if (cmn_data && rssi_data) { 18925 trig->background_trig_data.current_rssi = 18926 (uint8_t)cmn_data->current_rssi; 18927 trig->background_trig_data.data_rssi = 18928 (uint8_t)rssi_data->data_rssi; 18929 trig->background_trig_data.data_rssi_threshold = 18930 (uint8_t)rssi_data->data_rssi_threshold; 18931 } 18932 return QDF_STATUS_SUCCESS; 18933 18934 case WMI_ROAM_TRIGGER_REASON_IDLE: 18935 case WMI_ROAM_TRIGGER_REASON_FORCED: 18936 if (param_buf->roam_trigger_force) 18937 force_data = ¶m_buf->roam_trigger_force[idx]; 18938 if (force_data) { 18939 invoke = force_data->invoke_reason; 18940 trig->user_trig_data.invoke_reason = 18941 wmi_convert_to_cm_roam_invoke_reason(invoke); 18942 } 18943 return QDF_STATUS_SUCCESS; 18944 18945 case WMI_ROAM_TRIGGER_REASON_UNIT_TEST: 18946 case WMI_ROAM_TRIGGER_REASON_BTC: 18947 return QDF_STATUS_SUCCESS; 18948 18949 case WMI_ROAM_TRIGGER_REASON_BTM: 18950 if (param_buf->roam_trigger_btm) 18951 btm_data = ¶m_buf->roam_trigger_btm[idx]; 18952 if (btm_data) { 18953 trig->btm_trig_data.btm_request_mode = 18954 btm_data->btm_request_mode; 18955 trig->btm_trig_data.disassoc_timer = 18956 btm_data->disassoc_imminent_timer; 18957 trig->btm_trig_data.validity_interval = 18958 btm_data->validity_internal; 18959 trig->btm_trig_data.candidate_list_count = 18960 btm_data->candidate_list_count; 18961 trig->btm_trig_data.btm_resp_status = 18962 btm_data->btm_response_status_code; 18963 trig->btm_trig_data.btm_bss_termination_timeout = 18964 btm_data->btm_bss_termination_timeout; 18965 trig->btm_trig_data.btm_mbo_assoc_retry_timeout = 18966 btm_data->btm_mbo_assoc_retry_timeout; 18967 trig->btm_trig_data.token = 18968 (uint16_t)btm_data->btm_req_dialog_token; 18969 } else if (src_data) { 18970 trig->btm_trig_data.btm_request_mode = 18971 src_data->btm_request_mode; 18972 trig->btm_trig_data.disassoc_timer = 18973 src_data->disassoc_imminent_timer; 18974 trig->btm_trig_data.validity_interval = 18975 src_data->validity_internal; 18976 trig->btm_trig_data.candidate_list_count = 18977 src_data->candidate_list_count; 18978 trig->btm_trig_data.btm_resp_status = 18979 src_data->btm_response_status_code; 18980 trig->btm_trig_data.btm_bss_termination_timeout = 18981 src_data->btm_bss_termination_timeout; 18982 trig->btm_trig_data.btm_mbo_assoc_retry_timeout = 18983 src_data->btm_mbo_assoc_retry_timeout; 18984 trig->btm_trig_data.token = 18985 src_data->btm_req_dialog_token; 18986 if ((btm_idx + 18987 trig->btm_trig_data.candidate_list_count) <= 18988 param_buf->num_roam_btm_request_candidate_info) 18989 extract_roam_11kv_candidate_info( 18990 wmi_handle, evt_buf, 18991 trig->btm_trig_data.btm_cand, 18992 btm_idx, 18993 src_data->candidate_list_count); 18994 } 18995 18996 return QDF_STATUS_SUCCESS; 18997 18998 case WMI_ROAM_TRIGGER_REASON_BSS_LOAD: 18999 if (param_buf->roam_trigger_bss_load) 19000 bss_load_data = ¶m_buf->roam_trigger_bss_load[idx]; 19001 if (bss_load_data) 19002 trig->cu_trig_data.cu_load = bss_load_data->cu_load; 19003 else if (src_data) 19004 trig->cu_trig_data.cu_load = src_data->cu_load; 19005 return QDF_STATUS_SUCCESS; 19006 19007 case WMI_ROAM_TRIGGER_REASON_DEAUTH: 19008 if (param_buf->roam_trigger_deauth) 19009 deauth_data = ¶m_buf->roam_trigger_deauth[idx]; 19010 if (deauth_data) { 19011 trig->deauth_trig_data.type = deauth_data->deauth_type; 19012 trig->deauth_trig_data.reason = 19013 deauth_data->deauth_reason; 19014 } else if (src_data) { 19015 trig->deauth_trig_data.type = src_data->deauth_type; 19016 trig->deauth_trig_data.reason = src_data->deauth_reason; 19017 } 19018 return QDF_STATUS_SUCCESS; 19019 19020 case WMI_ROAM_TRIGGER_REASON_PERIODIC: 19021 if (param_buf->roam_trigger_periodic) 19022 periodic_data = ¶m_buf->roam_trigger_periodic[idx]; 19023 if (periodic_data) { 19024 trig->periodic_trig_data.periodic_timer_ms = 19025 periodic_data->periodic_timer_ms; 19026 } 19027 return QDF_STATUS_SUCCESS; 19028 19029 case WMI_ROAM_TRIGGER_REASON_LOW_RSSI: 19030 if (cmn_data && rssi_data) { 19031 trig->low_rssi_trig_data.current_rssi = 19032 (uint8_t)cmn_data->current_rssi; 19033 trig->low_rssi_trig_data.roam_rssi_threshold = 19034 (uint8_t)rssi_data->roam_rssi_threshold; 19035 trig->low_rssi_trig_data.rx_linkspeed_status = 19036 (uint8_t)rssi_data->rx_linkspeed_status; 19037 } else if (src_data) 19038 trig->rssi_trig_data.threshold = 19039 src_data->roam_rssi_threshold; 19040 19041 return QDF_STATUS_SUCCESS; 19042 19043 case WMI_ROAM_TRIGGER_REASON_STA_KICKOUT: 19044 if (param_buf->roam_trigger_kickout) 19045 kickout_data = ¶m_buf->roam_trigger_kickout[idx]; 19046 if (kickout_data) { 19047 tx_fail = kickout_data->kickout_reason; 19048 trig->tx_failures_trig_data.kickout_threshold = 19049 kickout_data->kickout_th; 19050 trig->tx_failures_trig_data.kickout_reason = 19051 wmi_convert_to_cm_roam_tx_fail_reason(tx_fail); 19052 } 19053 return QDF_STATUS_SUCCESS; 19054 19055 case WMI_ROAM_TRIGGER_REASON_WTC_BTM: 19056 if (src_data) { 19057 trig->wtc_btm_trig_data.roaming_mode = 19058 src_data->vendor_specific1[0]; 19059 trig->wtc_btm_trig_data.vsie_trigger_reason = 19060 src_data->vendor_specific1[1]; 19061 trig->wtc_btm_trig_data.sub_code = 19062 src_data->vendor_specific1[2]; 19063 trig->wtc_btm_trig_data.wtc_mode = 19064 src_data->vendor_specific1[3]; 19065 trig->wtc_btm_trig_data.wtc_scan_mode = 19066 convert_wtc_scan_mode(src_data->vendor_specific1[4]); 19067 trig->wtc_btm_trig_data.wtc_rssi_th = 19068 src_data->vendor_specific1[5]; 19069 trig->wtc_btm_trig_data.wtc_candi_rssi_th = 19070 src_data->vendor_specific1[6]; 19071 19072 trig->wtc_btm_trig_data.wtc_candi_rssi_ext_present = 19073 src_data->vendor_specific2[0]; 19074 trig->wtc_btm_trig_data.wtc_candi_rssi_th_5g = 19075 src_data->vendor_specific2[1]; 19076 trig->wtc_btm_trig_data.wtc_candi_rssi_th_6g = 19077 src_data->vendor_specific2[2]; 19078 trig->wtc_btm_trig_data.duration = 19079 src_data->vendor_specific2[3]; 19080 } 19081 return QDF_STATUS_SUCCESS; 19082 default: 19083 return QDF_STATUS_SUCCESS; 19084 } 19085 19086 return QDF_STATUS_SUCCESS; 19087 } 19088 19089 /** 19090 * extract_roam_scan_ap_stats_tlv() - Extract the Roam trigger stats 19091 * from the WMI_ROAM_STATS_EVENTID 19092 * @wmi_handle: wmi handle 19093 * @evt_buf: Pointer to the event buffer 19094 * @dst: Pointer to destination structure to fill data 19095 * @ap_idx: TLV index for this roam scan 19096 * @num_cand: number of candidates list in the roam scan 19097 */ 19098 static QDF_STATUS 19099 extract_roam_scan_ap_stats_tlv(wmi_unified_t wmi_handle, void *evt_buf, 19100 struct wmi_roam_candidate_info *dst, 19101 uint8_t ap_idx, uint16_t num_cand) 19102 { 19103 WMI_ROAM_STATS_EVENTID_param_tlvs *param_buf; 19104 wmi_roam_ap_info *src = NULL; 19105 uint8_t i; 19106 19107 param_buf = (WMI_ROAM_STATS_EVENTID_param_tlvs *)evt_buf; 19108 if (!param_buf) { 19109 wmi_err("Param buf is NULL"); 19110 return QDF_STATUS_E_FAILURE; 19111 } 19112 19113 if (ap_idx >= param_buf->num_roam_ap_info) { 19114 wmi_err("Invalid roam scan AP tlv ap_idx:%d total_ap:%d", 19115 ap_idx, param_buf->num_roam_ap_info); 19116 return QDF_STATUS_E_FAILURE; 19117 } 19118 19119 src = ¶m_buf->roam_ap_info[ap_idx]; 19120 19121 for (i = 0; i < num_cand; i++) { 19122 WMI_MAC_ADDR_TO_CHAR_ARRAY(&src->bssid, dst->bssid.bytes); 19123 dst->type = src->candidate_type; 19124 dst->freq = src->channel; 19125 dst->etp = src->etp; 19126 dst->rssi = src->rssi; 19127 dst->rssi_score = src->rssi_score; 19128 dst->cu_load = src->cu_load; 19129 dst->cu_score = src->cu_score; 19130 dst->total_score = src->total_score; 19131 dst->timestamp = src->timestamp; 19132 dst->dl_reason = src->bl_reason; 19133 dst->dl_source = src->bl_source; 19134 dst->dl_timestamp = src->bl_timestamp; 19135 dst->dl_original_timeout = src->bl_original_timeout; 19136 19137 src++; 19138 dst++; 19139 } 19140 19141 return QDF_STATUS_SUCCESS; 19142 } 19143 19144 /** 19145 * extract_roam_scan_stats_tlv() - Extract the Roam trigger stats 19146 * from the WMI_ROAM_STATS_EVENTID 19147 * @wmi_handle: wmi handle 19148 * @evt_buf: Pointer to the event buffer 19149 * @dst: Pointer to destination structure to fill data 19150 * @idx: TLV id 19151 * @chan_idx: Index of the channel tlv for the current roam trigger 19152 * @ap_idx: Index of the candidate AP TLV for the current roam trigger 19153 */ 19154 static QDF_STATUS 19155 extract_roam_scan_stats_tlv(wmi_unified_t wmi_handle, void *evt_buf, 19156 struct wmi_roam_scan_data *dst, uint8_t idx, 19157 uint8_t chan_idx, uint8_t ap_idx) 19158 { 19159 WMI_ROAM_STATS_EVENTID_param_tlvs *param_buf; 19160 wmi_roam_scan_info *src_data = NULL; 19161 wmi_roam_scan_channel_info *src_chan = NULL; 19162 QDF_STATUS status; 19163 uint8_t i; 19164 19165 param_buf = (WMI_ROAM_STATS_EVENTID_param_tlvs *)evt_buf; 19166 if (!param_buf || !param_buf->roam_scan_info || 19167 idx >= param_buf->num_roam_scan_info) 19168 return QDF_STATUS_E_FAILURE; 19169 19170 src_data = ¶m_buf->roam_scan_info[idx]; 19171 19172 dst->present = true; 19173 dst->type = src_data->roam_scan_type; 19174 dst->num_chan = src_data->roam_scan_channel_count; 19175 dst->scan_complete_timestamp = src_data->scan_complete_timestamp; 19176 dst->next_rssi_threshold = src_data->next_rssi_trigger_threshold; 19177 dst->is_btcoex_active = WMI_GET_BTCONNECT_STATUS(src_data->flags); 19178 dst->frame_info_count = src_data->frame_info_count; 19179 if (dst->frame_info_count > WLAN_ROAM_MAX_FRAME_INFO) 19180 dst->frame_info_count = WLAN_ROAM_MAX_FRAME_INFO; 19181 19182 /* Read the channel data only for dst->type is 0 (partial scan) */ 19183 if (dst->num_chan && !dst->type && param_buf->num_roam_scan_chan_info && 19184 chan_idx < param_buf->num_roam_scan_chan_info) { 19185 if (dst->num_chan > MAX_ROAM_SCAN_CHAN) 19186 dst->num_chan = MAX_ROAM_SCAN_CHAN; 19187 19188 src_chan = ¶m_buf->roam_scan_chan_info[chan_idx]; 19189 for (i = 0; i < dst->num_chan; i++) { 19190 dst->chan_freq[i] = src_chan->channel; 19191 dst->dwell_type[i] = 19192 (uint8_t)wlan_roam_dwell_type(src_chan->ch_dwell_type); 19193 src_chan++; 19194 } 19195 } 19196 19197 if (!src_data->roam_ap_count || !param_buf->num_roam_ap_info) 19198 return QDF_STATUS_SUCCESS; 19199 19200 dst->num_ap = src_data->roam_ap_count; 19201 if (dst->num_ap > MAX_ROAM_CANDIDATE_AP) 19202 dst->num_ap = MAX_ROAM_CANDIDATE_AP; 19203 19204 status = extract_roam_scan_ap_stats_tlv(wmi_handle, evt_buf, dst->ap, 19205 ap_idx, dst->num_ap); 19206 if (QDF_IS_STATUS_ERROR(status)) { 19207 wmi_err("Extract candidate stats for tlv[%d] failed", idx); 19208 return status; 19209 } 19210 19211 return QDF_STATUS_SUCCESS; 19212 } 19213 19214 /** 19215 * extract_roam_result_stats_tlv() - Extract the Roam trigger stats 19216 * from the WMI_ROAM_STATS_EVENTID 19217 * @wmi_handle: wmi handle 19218 * @evt_buf: Pointer to the event buffer 19219 * @dst: Pointer to destination structure to fill data 19220 * @idx: TLV id 19221 */ 19222 static QDF_STATUS 19223 extract_roam_result_stats_tlv(wmi_unified_t wmi_handle, void *evt_buf, 19224 struct wmi_roam_result *dst, uint8_t idx) 19225 { 19226 WMI_ROAM_STATS_EVENTID_param_tlvs *param_buf; 19227 wmi_roam_result *src_data = NULL; 19228 19229 param_buf = (WMI_ROAM_STATS_EVENTID_param_tlvs *)evt_buf; 19230 if (!param_buf || !param_buf->roam_result || 19231 idx >= param_buf->num_roam_result) 19232 return QDF_STATUS_E_FAILURE; 19233 19234 src_data = ¶m_buf->roam_result[idx]; 19235 19236 dst->present = true; 19237 dst->status = src_data->roam_status; 19238 dst->timestamp = src_data->timestamp; 19239 dst->fail_reason = 19240 wlan_roam_fail_reason_code(src_data->roam_fail_reason); 19241 WMI_MAC_ADDR_TO_CHAR_ARRAY(&src_data->bssid, dst->fail_bssid.bytes); 19242 19243 return QDF_STATUS_SUCCESS; 19244 } 19245 19246 /** 19247 * extract_roam_11kv_stats_tlv() - Extract the Roam trigger stats 19248 * from the WMI_ROAM_STATS_EVENTID 19249 * @wmi_handle: wmi handle 19250 * @evt_buf: Pointer to the event buffer 19251 * @dst: Pointer to destination structure to fill data 19252 * @idx: TLV id 19253 * @rpt_idx: Neighbor report Channel index 19254 */ 19255 static QDF_STATUS 19256 extract_roam_11kv_stats_tlv(wmi_unified_t wmi_handle, void *evt_buf, 19257 struct wmi_neighbor_report_data *dst, 19258 uint8_t idx, uint8_t rpt_idx) 19259 { 19260 WMI_ROAM_STATS_EVENTID_param_tlvs *param_buf; 19261 wmi_roam_neighbor_report_info *src_data = NULL; 19262 wmi_roam_neighbor_report_channel_info *src_freq = NULL; 19263 uint8_t i; 19264 19265 param_buf = (WMI_ROAM_STATS_EVENTID_param_tlvs *)evt_buf; 19266 if (!param_buf || !param_buf->roam_neighbor_report_info || 19267 !param_buf->num_roam_neighbor_report_info || 19268 idx >= param_buf->num_roam_neighbor_report_info) { 19269 wmi_debug("Invalid 1kv param buf"); 19270 return QDF_STATUS_E_FAILURE; 19271 } 19272 19273 src_data = ¶m_buf->roam_neighbor_report_info[idx]; 19274 19275 dst->present = true; 19276 dst->req_type = src_data->request_type; 19277 dst->num_freq = src_data->neighbor_report_channel_count; 19278 dst->req_time = src_data->neighbor_report_request_timestamp; 19279 dst->resp_time = src_data->neighbor_report_response_timestamp; 19280 dst->btm_query_token = src_data->btm_query_token; 19281 dst->btm_query_reason = src_data->btm_query_reason_code; 19282 dst->req_token = 19283 WMI_ROAM_NEIGHBOR_REPORT_INFO_REQUEST_TOKEN_GET(src_data->neighbor_report_detail); 19284 dst->resp_token = 19285 WMI_ROAM_NEIGHBOR_REPORT_INFO_RESPONSE_TOKEN_GET(src_data->neighbor_report_detail); 19286 dst->num_rpt = 19287 WMI_ROAM_NEIGHBOR_REPORT_INFO_NUM_OF_NRIE_GET(src_data->neighbor_report_detail); 19288 19289 if (!dst->num_freq || !param_buf->num_roam_neighbor_report_chan_info || 19290 rpt_idx >= param_buf->num_roam_neighbor_report_chan_info) 19291 return QDF_STATUS_SUCCESS; 19292 19293 if (!param_buf->roam_neighbor_report_chan_info) { 19294 wmi_debug("11kv channel present, but TLV is NULL num_freq:%d", 19295 dst->num_freq); 19296 dst->num_freq = 0; 19297 /* return success as its optional tlv and we can print neighbor 19298 * report received info 19299 */ 19300 return QDF_STATUS_SUCCESS; 19301 } 19302 19303 src_freq = ¶m_buf->roam_neighbor_report_chan_info[rpt_idx]; 19304 19305 if (dst->num_freq > MAX_ROAM_SCAN_CHAN) 19306 dst->num_freq = MAX_ROAM_SCAN_CHAN; 19307 19308 for (i = 0; i < dst->num_freq; i++) { 19309 dst->freq[i] = src_freq->channel; 19310 src_freq++; 19311 } 19312 19313 return QDF_STATUS_SUCCESS; 19314 } 19315 19316 /** 19317 * send_roam_set_param_cmd_tlv() - WMI roam set parameter function 19318 * @wmi_handle: handle to WMI. 19319 * @roam_param: pointer to hold roam set parameter 19320 * 19321 * Return: QDF_STATUS_SUCCESS for success or error code 19322 */ 19323 static QDF_STATUS 19324 send_roam_set_param_cmd_tlv(wmi_unified_t wmi_handle, 19325 struct vdev_set_params *roam_param) 19326 { 19327 QDF_STATUS ret; 19328 wmi_roam_set_param_cmd_fixed_param *cmd; 19329 wmi_buf_t buf; 19330 uint16_t len = sizeof(*cmd); 19331 19332 buf = wmi_buf_alloc(wmi_handle, len); 19333 if (!buf) 19334 return QDF_STATUS_E_NOMEM; 19335 19336 cmd = (wmi_roam_set_param_cmd_fixed_param *)wmi_buf_data(buf); 19337 WMITLV_SET_HDR(&cmd->tlv_header, 19338 WMITLV_TAG_STRUC_wmi_roam_set_param_cmd_fixed_param, 19339 WMITLV_GET_STRUCT_TLVLEN 19340 (wmi_roam_set_param_cmd_fixed_param)); 19341 cmd->vdev_id = roam_param->vdev_id; 19342 cmd->param_id = roam_param->param_id; 19343 cmd->param_value = roam_param->param_value; 19344 wmi_debug("Setting vdev %d roam_param = %x, value = %u", 19345 cmd->vdev_id, cmd->param_id, cmd->param_value); 19346 wmi_mtrace(WMI_ROAM_SET_PARAM_CMDID, cmd->vdev_id, 0); 19347 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 19348 WMI_ROAM_SET_PARAM_CMDID); 19349 if (QDF_IS_STATUS_ERROR(ret)) { 19350 wmi_err("Failed to send roam set param command, ret = %d", ret); 19351 wmi_buf_free(buf); 19352 } 19353 19354 return ret; 19355 } 19356 #else 19357 static inline QDF_STATUS 19358 extract_roam_trigger_stats_tlv(wmi_unified_t wmi_handle, void *evt_buf, 19359 struct wmi_roam_trigger_info *trig, uint8_t idx, 19360 uint8_t btm_idx) 19361 { 19362 return QDF_STATUS_E_NOSUPPORT; 19363 } 19364 19365 static inline QDF_STATUS 19366 extract_roam_result_stats_tlv(wmi_unified_t wmi_handle, void *evt_buf, 19367 struct wmi_roam_result *dst, uint8_t idx) 19368 { 19369 return QDF_STATUS_E_NOSUPPORT; 19370 } 19371 19372 static QDF_STATUS 19373 extract_roam_11kv_stats_tlv(wmi_unified_t wmi_handle, void *evt_buf, 19374 struct wmi_neighbor_report_data *dst, 19375 uint8_t idx, uint8_t rpt_idx) 19376 { 19377 return QDF_STATUS_E_NOSUPPORT; 19378 } 19379 19380 static QDF_STATUS 19381 extract_roam_scan_stats_tlv(wmi_unified_t wmi_handle, void *evt_buf, 19382 struct wmi_roam_scan_data *dst, uint8_t idx, 19383 uint8_t chan_idx, uint8_t ap_idx) 19384 { 19385 return QDF_STATUS_E_NOSUPPORT; 19386 } 19387 #endif 19388 19389 #ifdef WLAN_FEATURE_PKT_CAPTURE 19390 static QDF_STATUS 19391 extract_vdev_mgmt_offload_event_tlv(void *handle, void *evt_buf, 19392 struct mgmt_offload_event_params *params) 19393 { 19394 WMI_VDEV_MGMT_OFFLOAD_EVENTID_param_tlvs *param_tlvs; 19395 wmi_mgmt_hdr *hdr; 19396 19397 param_tlvs = (WMI_VDEV_MGMT_OFFLOAD_EVENTID_param_tlvs *)evt_buf; 19398 if (!param_tlvs) 19399 return QDF_STATUS_E_INVAL; 19400 19401 hdr = param_tlvs->fixed_param; 19402 if (!hdr) 19403 return QDF_STATUS_E_INVAL; 19404 19405 if (hdr->buf_len > param_tlvs->num_bufp) 19406 return QDF_STATUS_E_INVAL; 19407 19408 params->tsf_l32 = hdr->tsf_l32; 19409 params->chan_freq = hdr->chan_freq; 19410 params->rate_kbps = hdr->rate_kbps; 19411 params->rssi = hdr->rssi; 19412 params->buf_len = hdr->buf_len; 19413 params->tx_status = hdr->tx_status; 19414 params->buf = param_tlvs->bufp; 19415 params->tx_retry_cnt = hdr->tx_retry_cnt; 19416 return QDF_STATUS_SUCCESS; 19417 } 19418 #endif /* WLAN_FEATURE_PKT_CAPTURE */ 19419 19420 #ifdef WLAN_FEATURE_PKT_CAPTURE_V2 19421 static QDF_STATUS 19422 extract_smart_monitor_event_tlv(void *handle, void *evt_buf, 19423 struct smu_event_params *params) 19424 { 19425 WMI_VDEV_SMART_MONITOR_EVENTID_param_tlvs *param_buf = NULL; 19426 wmi_vdev_smart_monitor_event_fixed_param *smu_event = NULL; 19427 19428 param_buf = (WMI_VDEV_SMART_MONITOR_EVENTID_param_tlvs *)evt_buf; 19429 if (!param_buf) { 19430 wmi_err("Invalid smart monitor event"); 19431 return QDF_STATUS_E_INVAL; 19432 } 19433 19434 smu_event = param_buf->fixed_param; 19435 if (!smu_event) { 19436 wmi_err("smart monitor event fixed param is NULL"); 19437 return QDF_STATUS_E_INVAL; 19438 } 19439 19440 params->vdev_id = smu_event->vdev_id; 19441 if (params->vdev_id >= WLAN_UMAC_PDEV_MAX_VDEVS) 19442 return QDF_STATUS_E_INVAL; 19443 19444 params->rx_avg_rssi = smu_event->avg_rssi_data_dbm; 19445 19446 return QDF_STATUS_SUCCESS; 19447 } 19448 #endif /* WLAN_FEATURE_PKT_CAPTURE_V2 */ 19449 19450 #ifdef FEATURE_WLAN_TIME_SYNC_FTM 19451 /** 19452 * send_wlan_ts_ftm_trigger_cmd_tlv(): send wlan time sync cmd to FW 19453 * 19454 * @wmi: wmi handle 19455 * @vdev_id: vdev id 19456 * @burst_mode: Indicates whether relation derived using FTM is needed for 19457 * each FTM frame or only aggregated result is required. 19458 * 19459 * Send WMI_AUDIO_SYNC_TRIGGER_CMDID to FW. 19460 * 19461 * Return: QDF_STATUS 19462 */ 19463 static QDF_STATUS send_wlan_ts_ftm_trigger_cmd_tlv(wmi_unified_t wmi, 19464 uint32_t vdev_id, 19465 bool burst_mode) 19466 { 19467 wmi_audio_sync_trigger_cmd_fixed_param *cmd; 19468 wmi_buf_t buf; 19469 int32_t len = sizeof(*cmd); 19470 19471 buf = wmi_buf_alloc(wmi, len); 19472 if (!buf) { 19473 wmi_err("wmi_buf_alloc failed"); 19474 return QDF_STATUS_E_NOMEM; 19475 } 19476 cmd = (wmi_audio_sync_trigger_cmd_fixed_param *)wmi_buf_data(buf); 19477 WMITLV_SET_HDR(&cmd->tlv_header, 19478 WMITLV_TAG_STRUC_wmi_audio_sync_trigger_cmd_fixed_param, 19479 WMITLV_GET_STRUCT_TLVLEN(wmi_audio_sync_trigger_cmd_fixed_param)); 19480 cmd->vdev_id = vdev_id; 19481 cmd->agg_relation = burst_mode ? false : true; 19482 if (wmi_unified_cmd_send(wmi, buf, len, WMI_VDEV_AUDIO_SYNC_TRIGGER_CMDID)) { 19483 wmi_err("Failed to send audio sync trigger cmd"); 19484 wmi_buf_free(buf); 19485 return QDF_STATUS_E_FAILURE; 19486 } 19487 19488 return QDF_STATUS_SUCCESS; 19489 } 19490 19491 static QDF_STATUS send_wlan_ts_qtime_cmd_tlv(wmi_unified_t wmi, 19492 uint32_t vdev_id, 19493 uint64_t lpass_ts) 19494 { 19495 wmi_audio_sync_qtimer_cmd_fixed_param *cmd; 19496 wmi_buf_t buf; 19497 int32_t len = sizeof(*cmd); 19498 19499 buf = wmi_buf_alloc(wmi, len); 19500 if (!buf) { 19501 wmi_err("wmi_buf_alloc failed"); 19502 return QDF_STATUS_E_NOMEM; 19503 } 19504 cmd = (wmi_audio_sync_qtimer_cmd_fixed_param *)wmi_buf_data(buf); 19505 WMITLV_SET_HDR(&cmd->tlv_header, 19506 WMITLV_TAG_STRUC_wmi_audio_sync_qtimer_cmd_fixed_param, 19507 WMITLV_GET_STRUCT_TLVLEN(wmi_audio_sync_qtimer_cmd_fixed_param)); 19508 cmd->vdev_id = vdev_id; 19509 cmd->qtimer_u32 = (uint32_t)((lpass_ts & 0xffffffff00000000LL) >> 32); 19510 cmd->qtimer_l32 = (uint32_t)(lpass_ts & 0xffffffffLL); 19511 19512 if (wmi_unified_cmd_send(wmi, buf, len, WMI_VDEV_AUDIO_SYNC_QTIMER_CMDID)) { 19513 wmi_err("Failed to send audio qtime command"); 19514 wmi_buf_free(buf); 19515 return QDF_STATUS_E_FAILURE; 19516 } 19517 19518 return QDF_STATUS_SUCCESS; 19519 } 19520 19521 static QDF_STATUS extract_time_sync_ftm_start_stop_event_tlv( 19522 wmi_unified_t wmi, void *buf, 19523 struct ftm_time_sync_start_stop_params *param) 19524 { 19525 WMI_VDEV_AUDIO_SYNC_START_STOP_EVENTID_param_tlvs *param_buf; 19526 wmi_audio_sync_start_stop_event_fixed_param *resp_event; 19527 19528 param_buf = (WMI_VDEV_AUDIO_SYNC_START_STOP_EVENTID_param_tlvs *)buf; 19529 if (!param_buf) { 19530 wmi_err("Invalid audio sync start stop event buffer"); 19531 return QDF_STATUS_E_FAILURE; 19532 } 19533 19534 resp_event = param_buf->fixed_param; 19535 if (!resp_event) { 19536 wmi_err("Invalid audio sync start stop fixed param buffer"); 19537 return QDF_STATUS_E_FAILURE; 19538 } 19539 19540 param->vdev_id = resp_event->vdev_id; 19541 param->timer_interval = resp_event->periodicity; 19542 param->num_reads = resp_event->reads_needed; 19543 param->qtime = ((uint64_t)resp_event->qtimer_u32 << 32) | 19544 resp_event->qtimer_l32; 19545 param->mac_time = ((uint64_t)resp_event->mac_timer_u32 << 32) | 19546 resp_event->mac_timer_l32; 19547 19548 wmi_debug("FTM time sync time_interval %d, num_reads %d", 19549 param->timer_interval, param->num_reads); 19550 19551 return QDF_STATUS_SUCCESS; 19552 } 19553 19554 static QDF_STATUS 19555 extract_time_sync_ftm_offset_event_tlv(wmi_unified_t wmi, void *buf, 19556 struct ftm_time_sync_offset *param) 19557 { 19558 WMI_VDEV_AUDIO_SYNC_Q_MASTER_SLAVE_OFFSET_EVENTID_param_tlvs *param_buf; 19559 wmi_audio_sync_q_master_slave_offset_event_fixed_param *resp_event; 19560 wmi_audio_sync_q_master_slave_times *q_pair; 19561 int iter; 19562 19563 param_buf = 19564 (WMI_VDEV_AUDIO_SYNC_Q_MASTER_SLAVE_OFFSET_EVENTID_param_tlvs *)buf; 19565 if (!param_buf) { 19566 wmi_err("Invalid timesync ftm offset event buffer"); 19567 return QDF_STATUS_E_FAILURE; 19568 } 19569 19570 resp_event = param_buf->fixed_param; 19571 if (!resp_event) { 19572 wmi_err("Invalid timesync ftm offset fixed param buffer"); 19573 return QDF_STATUS_E_FAILURE; 19574 } 19575 19576 param->vdev_id = resp_event->vdev_id; 19577 param->num_qtime = param_buf->num_audio_sync_q_master_slave_times; 19578 if (param->num_qtime > FTM_TIME_SYNC_QTIME_PAIR_MAX) 19579 param->num_qtime = FTM_TIME_SYNC_QTIME_PAIR_MAX; 19580 19581 q_pair = param_buf->audio_sync_q_master_slave_times; 19582 if (!q_pair) { 19583 wmi_err("Invalid q_master_slave_times buffer"); 19584 return QDF_STATUS_E_FAILURE; 19585 } 19586 19587 for (iter = 0; iter < param->num_qtime; iter++) { 19588 param->pairs[iter].qtime_initiator = ( 19589 (uint64_t)q_pair[iter].qmaster_u32 << 32) | 19590 q_pair[iter].qmaster_l32; 19591 param->pairs[iter].qtime_target = ( 19592 (uint64_t)q_pair[iter].qslave_u32 << 32) | 19593 q_pair[iter].qslave_l32; 19594 } 19595 return QDF_STATUS_SUCCESS; 19596 } 19597 #endif /* FEATURE_WLAN_TIME_SYNC_FTM */ 19598 19599 /** 19600 * send_vdev_tsf_tstamp_action_cmd_tlv() - send vdev tsf action command 19601 * @wmi: wmi handle 19602 * @vdev_id: vdev id 19603 * 19604 * TSF_TSTAMP_READ_VALUE is the only operation supported 19605 * Return: QDF_STATUS_SUCCESS for success or error code 19606 */ 19607 static QDF_STATUS 19608 send_vdev_tsf_tstamp_action_cmd_tlv(wmi_unified_t wmi, uint8_t vdev_id) 19609 { 19610 wmi_vdev_tsf_tstamp_action_cmd_fixed_param *cmd; 19611 wmi_buf_t buf; 19612 int32_t len = sizeof(*cmd); 19613 19614 buf = wmi_buf_alloc(wmi, len); 19615 if (!buf) 19616 return QDF_STATUS_E_NOMEM; 19617 19618 cmd = (wmi_vdev_tsf_tstamp_action_cmd_fixed_param *)wmi_buf_data(buf); 19619 WMITLV_SET_HDR(&cmd->tlv_header, 19620 WMITLV_TAG_STRUC_wmi_vdev_tsf_tstamp_action_cmd_fixed_param, 19621 WMITLV_GET_STRUCT_TLVLEN(wmi_vdev_tsf_tstamp_action_cmd_fixed_param)); 19622 cmd->vdev_id = vdev_id; 19623 cmd->tsf_action = TSF_TSTAMP_QTIMER_CAPTURE_REQ; 19624 wmi_mtrace(WMI_VDEV_TSF_TSTAMP_ACTION_CMDID, cmd->vdev_id, 0); 19625 if (wmi_unified_cmd_send(wmi, buf, len, 19626 WMI_VDEV_TSF_TSTAMP_ACTION_CMDID)) { 19627 wmi_err("%s: Failed to send WMI_VDEV_TSF_TSTAMP_ACTION_CMDID", 19628 __func__); 19629 wmi_buf_free(buf); 19630 return QDF_STATUS_E_FAILURE; 19631 } 19632 19633 return QDF_STATUS_SUCCESS; 19634 } 19635 19636 /** 19637 * extract_vdev_tsf_report_event_tlv() - extract vdev tsf report from event 19638 * @wmi_handle: wmi handle 19639 * @evt_buf: pointer to event buffer 19640 * @param: Pointer to struct to hold event info 19641 * 19642 * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure 19643 */ 19644 static QDF_STATUS 19645 extract_vdev_tsf_report_event_tlv(wmi_unified_t wmi_handle, void *evt_buf, 19646 struct wmi_host_tsf_event *param) 19647 { 19648 WMI_VDEV_TSF_REPORT_EVENTID_param_tlvs *param_buf; 19649 wmi_vdev_tsf_report_event_fixed_param *evt; 19650 19651 param_buf = (WMI_VDEV_TSF_REPORT_EVENTID_param_tlvs *)evt_buf; 19652 if (!param_buf) { 19653 wmi_err("Invalid tsf report event buffer"); 19654 return QDF_STATUS_E_INVAL; 19655 } 19656 19657 evt = param_buf->fixed_param; 19658 param->vdev_id = evt->vdev_id; 19659 param->tsf = ((uint64_t)(evt->tsf_high) << 32) | evt->tsf_low; 19660 param->tsf_low = evt->tsf_low; 19661 param->tsf_high = evt->tsf_high; 19662 param->qtimer_low = evt->qtimer_low; 19663 param->qtimer_high = evt->qtimer_high; 19664 param->tsf_id = evt->tsf_id; 19665 param->tsf_id_valid = evt->tsf_id_valid; 19666 param->mac_id = evt->mac_id; 19667 param->mac_id_valid = evt->mac_id_valid; 19668 param->wlan_global_tsf_low = evt->wlan_global_tsf_low; 19669 param->wlan_global_tsf_high = evt->wlan_global_tsf_high; 19670 param->tqm_timer_low = evt->tqm_timer_low; 19671 param->tqm_timer_high = evt->tqm_timer_high; 19672 param->use_tqm_timer = evt->use_tqm_timer; 19673 19674 return QDF_STATUS_SUCCESS; 19675 } 19676 19677 /** 19678 * extract_pdev_csa_switch_count_status_tlv() - extract pdev csa switch count 19679 * status tlv 19680 * @wmi_handle: wmi handle 19681 * @evt_buf: pointer to event buffer 19682 * @param: Pointer to hold csa switch count status event param 19683 * 19684 * Return: QDF_STATUS_SUCCESS for success or error code 19685 */ 19686 static QDF_STATUS extract_pdev_csa_switch_count_status_tlv( 19687 wmi_unified_t wmi_handle, 19688 void *evt_buf, 19689 struct pdev_csa_switch_count_status *param) 19690 { 19691 WMI_PDEV_CSA_SWITCH_COUNT_STATUS_EVENTID_param_tlvs *param_buf; 19692 wmi_pdev_csa_switch_count_status_event_fixed_param *csa_status; 19693 19694 param_buf = (WMI_PDEV_CSA_SWITCH_COUNT_STATUS_EVENTID_param_tlvs *) 19695 evt_buf; 19696 if (!param_buf) { 19697 wmi_err("Invalid CSA status event"); 19698 return QDF_STATUS_E_INVAL; 19699 } 19700 19701 csa_status = param_buf->fixed_param; 19702 19703 param->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host( 19704 wmi_handle, 19705 csa_status->pdev_id); 19706 param->current_switch_count = csa_status->current_switch_count; 19707 param->num_vdevs = csa_status->num_vdevs; 19708 param->vdev_ids = param_buf->vdev_ids; 19709 19710 return QDF_STATUS_SUCCESS; 19711 } 19712 19713 #ifdef CONFIG_AFC_SUPPORT 19714 /** 19715 * send_afc_cmd_tlv() - Sends the AFC indication to FW 19716 * @wmi_handle: wmi handle 19717 * @pdev_id: Pdev id 19718 * @param: Pointer to hold AFC indication. 19719 * 19720 * Return: QDF_STATUS_SUCCESS for success or error code 19721 */ 19722 static 19723 QDF_STATUS send_afc_cmd_tlv(wmi_unified_t wmi_handle, 19724 uint8_t pdev_id, 19725 struct reg_afc_resp_rx_ind_info *param) 19726 { 19727 wmi_buf_t buf; 19728 wmi_afc_cmd_fixed_param *cmd; 19729 uint32_t len; 19730 uint8_t *buf_ptr; 19731 QDF_STATUS ret; 19732 19733 len = sizeof(wmi_afc_cmd_fixed_param); 19734 buf = wmi_buf_alloc(wmi_handle, len); 19735 if (!buf) 19736 return QDF_STATUS_E_NOMEM; 19737 19738 buf_ptr = (uint8_t *)wmi_buf_data(buf); 19739 cmd = (wmi_afc_cmd_fixed_param *)buf_ptr; 19740 19741 WMITLV_SET_HDR(&cmd->tlv_header, 19742 WMITLV_TAG_STRUC_wmi_afc_cmd_fixed_param, 19743 WMITLV_GET_STRUCT_TLVLEN(wmi_afc_cmd_fixed_param)); 19744 19745 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 19746 wmi_handle, 19747 pdev_id); 19748 cmd->cmd_type = param->cmd_type; 19749 cmd->serv_resp_format = param->serv_resp_format; 19750 19751 wmi_mtrace(WMI_AFC_CMDID, NO_SESSION, 0); 19752 ret = wmi_unified_cmd_send(wmi_handle, buf, len, WMI_AFC_CMDID); 19753 if (QDF_IS_STATUS_ERROR(ret)) { 19754 wmi_err("Failed to send WMI_AFC_CMDID"); 19755 wmi_buf_free(buf); 19756 return QDF_STATUS_E_FAILURE; 19757 } 19758 19759 return QDF_STATUS_SUCCESS; 19760 } 19761 #endif 19762 19763 /** 19764 * send_set_tpc_power_cmd_tlv() - Sends the set TPC power level to FW 19765 * @wmi_handle: wmi handle 19766 * @vdev_id: vdev id 19767 * @param: Pointer to hold TX power info 19768 * 19769 * Return: QDF_STATUS_SUCCESS for success or error code 19770 */ 19771 static QDF_STATUS send_set_tpc_power_cmd_tlv(wmi_unified_t wmi_handle, 19772 uint8_t vdev_id, 19773 struct reg_tpc_power_info *param) 19774 { 19775 wmi_buf_t buf; 19776 wmi_vdev_set_tpc_power_fixed_param *tpc_power_info_param; 19777 wmi_vdev_ch_power_info *ch_power_info; 19778 uint8_t *buf_ptr; 19779 uint16_t idx; 19780 uint32_t len; 19781 QDF_STATUS ret; 19782 19783 len = sizeof(wmi_vdev_set_tpc_power_fixed_param) + WMI_TLV_HDR_SIZE; 19784 len += (sizeof(wmi_vdev_ch_power_info) * param->num_pwr_levels); 19785 19786 buf = wmi_buf_alloc(wmi_handle, len); 19787 if (!buf) 19788 return QDF_STATUS_E_NOMEM; 19789 19790 buf_ptr = (uint8_t *)wmi_buf_data(buf); 19791 tpc_power_info_param = (wmi_vdev_set_tpc_power_fixed_param *)buf_ptr; 19792 19793 WMITLV_SET_HDR(&tpc_power_info_param->tlv_header, 19794 WMITLV_TAG_STRUC_wmi_vdev_set_tpc_power_cmd_fixed_param, 19795 WMITLV_GET_STRUCT_TLVLEN(wmi_vdev_set_tpc_power_fixed_param)); 19796 19797 tpc_power_info_param->vdev_id = vdev_id; 19798 tpc_power_info_param->psd_power = param->is_psd_power; 19799 tpc_power_info_param->eirp_power = param->eirp_power; 19800 tpc_power_info_param->power_type_6ghz = param->power_type_6g; 19801 wmi_debug("eirp_power = %d is_psd_power = %d", 19802 tpc_power_info_param->eirp_power, 19803 tpc_power_info_param->psd_power); 19804 reg_print_ap_power_type_6ghz(tpc_power_info_param->power_type_6ghz); 19805 19806 buf_ptr += sizeof(wmi_vdev_set_tpc_power_fixed_param); 19807 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 19808 param->num_pwr_levels * sizeof(wmi_vdev_ch_power_info)); 19809 19810 buf_ptr += WMI_TLV_HDR_SIZE; 19811 ch_power_info = (wmi_vdev_ch_power_info *)buf_ptr; 19812 19813 for (idx = 0; idx < param->num_pwr_levels; ++idx) { 19814 WMITLV_SET_HDR(&ch_power_info[idx].tlv_header, 19815 WMITLV_TAG_STRUC_wmi_vdev_ch_power_info, 19816 WMITLV_GET_STRUCT_TLVLEN(wmi_vdev_ch_power_info)); 19817 ch_power_info[idx].chan_cfreq = 19818 param->chan_power_info[idx].chan_cfreq; 19819 ch_power_info[idx].tx_power = 19820 param->chan_power_info[idx].tx_power; 19821 wmi_debug("chan_cfreq = %d tx_power = %d", 19822 ch_power_info[idx].chan_cfreq, 19823 ch_power_info[idx].tx_power); 19824 buf_ptr += sizeof(wmi_vdev_ch_power_info); 19825 } 19826 19827 wmi_mtrace(WMI_VDEV_SET_TPC_POWER_CMDID, vdev_id, 0); 19828 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 19829 WMI_VDEV_SET_TPC_POWER_CMDID); 19830 if (QDF_IS_STATUS_ERROR(ret)) 19831 wmi_buf_free(buf); 19832 19833 19834 return ret; 19835 } 19836 19837 /** 19838 * extract_dpd_status_ev_param_tlv() - extract dpd status from FW event 19839 * @wmi_handle: wmi handle 19840 * @evt_buf: event buffer 19841 * @param: dpd status info 19842 * 19843 * Return: QDF_STATUS_SUCCESS for success or error code 19844 */ 19845 static QDF_STATUS 19846 extract_dpd_status_ev_param_tlv(wmi_unified_t wmi_handle, 19847 void *evt_buf, 19848 struct wmi_host_pdev_get_dpd_status_event *param) 19849 { 19850 WMI_PDEV_GET_DPD_STATUS_EVENTID_param_tlvs *param_buf; 19851 wmi_pdev_get_dpd_status_evt_fixed_param *dpd_status; 19852 19853 param_buf = (WMI_PDEV_GET_DPD_STATUS_EVENTID_param_tlvs *)evt_buf; 19854 if (!param_buf) { 19855 wmi_err("Invalid get dpd_status event"); 19856 return QDF_STATUS_E_INVAL; 19857 } 19858 19859 dpd_status = param_buf->fixed_param; 19860 param->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host 19861 (wmi_handle, dpd_status->pdev_id); 19862 param->dpd_status = dpd_status->dpd_status; 19863 19864 return QDF_STATUS_SUCCESS; 19865 } 19866 19867 static int 19868 convert_halphy_status(wmi_pdev_get_halphy_cal_status_evt_fixed_param *status, 19869 WMI_HALPHY_CAL_VALID_BITMAP_STATUS valid_bit) 19870 { 19871 if (status->halphy_cal_valid_bmap && valid_bit) 19872 return (status->halphy_cal_status && valid_bit); 19873 19874 return 0; 19875 } 19876 19877 static QDF_STATUS 19878 extract_halphy_cal_status_ev_param_tlv(wmi_unified_t wmi_handle, 19879 void *evt_buf, 19880 struct wmi_host_pdev_get_halphy_cal_status_event *param) 19881 { 19882 WMI_PDEV_GET_HALPHY_CAL_STATUS_EVENTID_param_tlvs *param_buf; 19883 wmi_pdev_get_halphy_cal_status_evt_fixed_param *halphy_cal_status; 19884 19885 param_buf = (WMI_PDEV_GET_HALPHY_CAL_STATUS_EVENTID_param_tlvs *)evt_buf; 19886 if (!param_buf) { 19887 wmi_err("Invalid get halphy cal status event"); 19888 return QDF_STATUS_E_INVAL; 19889 } 19890 19891 halphy_cal_status = param_buf->fixed_param; 19892 param->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host 19893 (wmi_handle, halphy_cal_status->pdev_id); 19894 param->halphy_cal_adc_status = 19895 convert_halphy_status(halphy_cal_status, 19896 WMI_HALPHY_CAL_ADC_BMAP); 19897 param->halphy_cal_bwfilter_status = 19898 convert_halphy_status(halphy_cal_status, 19899 WMI_HALPHY_CAL_BWFILTER_BMAP); 19900 param->halphy_cal_pdet_and_pal_status = 19901 convert_halphy_status(halphy_cal_status, 19902 WMI_HALPHY_CAL_PDET_AND_PAL_BMAP); 19903 param->halphy_cal_rxdco_status = 19904 convert_halphy_status(halphy_cal_status, 19905 WMI_HALPHY_CAL_RXDCO_BMAP); 19906 param->halphy_cal_comb_txiq_rxiq_status = 19907 convert_halphy_status(halphy_cal_status, 19908 WMI_HALPHY_CAL_COMB_TXLO_TXIQ_RXIQ_BMAP); 19909 param->halphy_cal_ibf_status = 19910 convert_halphy_status(halphy_cal_status, 19911 WMI_HALPHY_CAL_IBF_BMAP); 19912 param->halphy_cal_pa_droop_status = 19913 convert_halphy_status(halphy_cal_status, 19914 WMI_HALPHY_CAL_PA_DROOP_BMAP); 19915 param->halphy_cal_dac_status = 19916 convert_halphy_status(halphy_cal_status, 19917 WMI_HALPHY_CAL_DAC_BMAP); 19918 param->halphy_cal_ani_status = 19919 convert_halphy_status(halphy_cal_status, 19920 WMI_HALPHY_CAL_ANI_BMAP); 19921 param->halphy_cal_noise_floor_status = 19922 convert_halphy_status(halphy_cal_status, 19923 WMI_HALPHY_CAL_NOISE_FLOOR_BMAP); 19924 19925 return QDF_STATUS_SUCCESS; 19926 } 19927 19928 /** 19929 * set_halphy_cal_fw_status_to_host_status() - Convert set halphy cal status to host enum 19930 * @fw_status: set halphy cal status from WMI_PDEV_SET_HALPHY_CAL_BMAP_EVENTID event 19931 * 19932 * Return: host_set_halphy_cal_status 19933 */ 19934 static enum wmi_host_set_halphy_cal_status 19935 set_halphy_cal_fw_status_to_host_status(uint32_t fw_status) 19936 { 19937 if (fw_status == 0) 19938 return WMI_HOST_SET_HALPHY_CAL_STATUS_SUCCESS; 19939 else if (fw_status == 1) 19940 return WMI_HOST_SET_HALPHY_CAL_STATUS_FAIL; 19941 19942 wmi_debug("Unknown set halphy status code(%u) from WMI", fw_status); 19943 return WMI_HOST_SET_HALPHY_CAL_STATUS_FAIL; 19944 } 19945 19946 /** 19947 * extract_halphy_cal_ev_param_tlv() - extract dpd status from FW event 19948 * @wmi_handle: wmi handle 19949 * @evt_buf: event buffer 19950 * @param: set halphy cal status info 19951 * 19952 * Return: QDF_STATUS_SUCCESS for success or error code 19953 */ 19954 static QDF_STATUS 19955 extract_halphy_cal_ev_param_tlv(wmi_unified_t wmi_handle, 19956 void *evt_buf, 19957 struct wmi_host_pdev_set_halphy_cal_event *param) 19958 { 19959 WMI_PDEV_SET_HALPHY_CAL_BMAP_EVENTID_param_tlvs *param_buf; 19960 wmi_pdev_set_halphy_cal_bmap_evt_fixed_param *set_halphy_status; 19961 19962 param_buf = (WMI_PDEV_SET_HALPHY_CAL_BMAP_EVENTID_param_tlvs *)evt_buf; 19963 if (!param_buf) { 19964 wmi_err("Invalid set halphy_status event"); 19965 return QDF_STATUS_E_INVAL; 19966 } 19967 19968 set_halphy_status = param_buf->fixed_param; 19969 param->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host 19970 (wmi_handle, set_halphy_status->pdev_id); 19971 param->status = set_halphy_cal_fw_status_to_host_status(set_halphy_status->status); 19972 19973 return QDF_STATUS_SUCCESS; 19974 } 19975 19976 /** 19977 * extract_install_key_comp_event_tlv() - extract install key complete event tlv 19978 * @wmi_handle: wmi handle 19979 * @evt_buf: pointer to event buffer 19980 * @len: length of the event buffer 19981 * @param: Pointer to hold install key complete event param 19982 * 19983 * Return: QDF_STATUS_SUCCESS for success or error code 19984 */ 19985 static QDF_STATUS 19986 extract_install_key_comp_event_tlv(wmi_unified_t wmi_handle, 19987 void *evt_buf, uint32_t len, 19988 struct wmi_install_key_comp_event *param) 19989 { 19990 WMI_VDEV_INSTALL_KEY_COMPLETE_EVENTID_param_tlvs *param_buf; 19991 wmi_vdev_install_key_complete_event_fixed_param *key_fp; 19992 19993 if (len < sizeof(*param_buf)) { 19994 wmi_err("invalid event buf len %d", len); 19995 return QDF_STATUS_E_INVAL; 19996 } 19997 19998 param_buf = (WMI_VDEV_INSTALL_KEY_COMPLETE_EVENTID_param_tlvs *)evt_buf; 19999 if (!param_buf) { 20000 wmi_err("received null buf from target"); 20001 return QDF_STATUS_E_INVAL; 20002 } 20003 20004 key_fp = param_buf->fixed_param; 20005 if (!key_fp) { 20006 wmi_err("received null event data from target"); 20007 return QDF_STATUS_E_INVAL; 20008 } 20009 20010 param->vdev_id = key_fp->vdev_id; 20011 param->key_ix = key_fp->key_ix; 20012 param->key_flags = key_fp->key_flags; 20013 param->status = key_fp->status; 20014 WMI_MAC_ADDR_TO_CHAR_ARRAY(&key_fp->peer_macaddr, 20015 param->peer_macaddr); 20016 20017 return QDF_STATUS_SUCCESS; 20018 } 20019 20020 static QDF_STATUS 20021 send_set_halphy_cal_tlv(wmi_unified_t wmi_handle, 20022 struct wmi_host_send_set_halphy_cal_info *param) 20023 { 20024 wmi_buf_t buf; 20025 wmi_pdev_set_halphy_cal_bmap_cmd_fixed_param *cmd; 20026 QDF_STATUS ret; 20027 uint32_t len; 20028 20029 len = sizeof(*cmd); 20030 20031 buf = wmi_buf_alloc(wmi_handle, len); 20032 if (!buf) 20033 return QDF_STATUS_E_FAILURE; 20034 20035 cmd = (void *)wmi_buf_data(buf); 20036 20037 WMITLV_SET_HDR(&cmd->tlv_header, 20038 WMITLV_TAG_STRUC_wmi_pdev_set_halphy_cal_bmap_cmd_fixed_param, 20039 WMITLV_GET_STRUCT_TLVLEN(wmi_pdev_set_halphy_cal_bmap_cmd_fixed_param)); 20040 20041 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target(wmi_handle, 20042 param->pdev_id); 20043 cmd->online_halphy_cals_bmap = param->value; 20044 cmd->home_scan_channel = param->chan_sel; 20045 20046 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 20047 WMI_PDEV_SET_HALPHY_CAL_BMAP_CMDID); 20048 if (QDF_IS_STATUS_ERROR(ret)) { 20049 wmi_err("WMI_PDEV_SET_HALPHY_CAL_BMAP_CMDID send returned Error %d",ret); 20050 wmi_buf_free(buf); 20051 } 20052 20053 return ret; 20054 } 20055 20056 #ifdef WLAN_FEATURE_DYNAMIC_MAC_ADDR_UPDATE 20057 /** 20058 * send_set_mac_address_cmd_tlv() - send set MAC address command to fw 20059 * @wmi: wmi handle 20060 * @params: set MAC address command params 20061 * 20062 * Return: QDF_STATUS_SUCCESS for success or error code 20063 */ 20064 static QDF_STATUS 20065 send_set_mac_address_cmd_tlv(wmi_unified_t wmi, 20066 struct set_mac_addr_params *params) 20067 { 20068 wmi_vdev_update_mac_addr_cmd_fixed_param *cmd; 20069 wmi_buf_t buf; 20070 int32_t len = sizeof(*cmd); 20071 20072 buf = wmi_buf_alloc(wmi, len); 20073 if (!buf) 20074 return QDF_STATUS_E_NOMEM; 20075 20076 cmd = (wmi_vdev_update_mac_addr_cmd_fixed_param *)wmi_buf_data(buf); 20077 WMITLV_SET_HDR( 20078 &cmd->tlv_header, 20079 WMITLV_TAG_STRUC_wmi_vdev_update_mac_addr_cmd_fixed_param, 20080 WMITLV_GET_STRUCT_TLVLEN 20081 (wmi_vdev_update_mac_addr_cmd_fixed_param)); 20082 cmd->vdev_id = params->vdev_id; 20083 WMI_CHAR_ARRAY_TO_MAC_ADDR(params->mac_addr.bytes, &cmd->vdev_macaddr); 20084 WMI_CHAR_ARRAY_TO_MAC_ADDR(params->mld_addr.bytes, &cmd->mld_macaddr); 20085 20086 wmi_debug("vdev %d mac_addr " QDF_MAC_ADDR_FMT " mld_addr " 20087 QDF_MAC_ADDR_FMT, cmd->vdev_id, 20088 QDF_MAC_ADDR_REF(params->mac_addr.bytes), 20089 QDF_MAC_ADDR_REF(params->mld_addr.bytes)); 20090 wmi_mtrace(WMI_VDEV_UPDATE_MAC_ADDR_CMDID, cmd->vdev_id, 0); 20091 if (wmi_unified_cmd_send(wmi, buf, len, 20092 WMI_VDEV_UPDATE_MAC_ADDR_CMDID)) { 20093 wmi_buf_free(buf); 20094 return QDF_STATUS_E_FAILURE; 20095 } 20096 20097 return QDF_STATUS_SUCCESS; 20098 } 20099 20100 /** 20101 * extract_update_mac_address_event_tlv() - extract update MAC address event 20102 * @wmi_handle: WMI handle 20103 * @evt_buf: event buffer 20104 * @vdev_id: VDEV ID 20105 * @status: FW status of the set MAC address operation 20106 * 20107 * Return: QDF_STATUS 20108 */ 20109 static QDF_STATUS extract_update_mac_address_event_tlv( 20110 wmi_unified_t wmi_handle, void *evt_buf, 20111 uint8_t *vdev_id, uint8_t *status) 20112 { 20113 WMI_VDEV_UPDATE_MAC_ADDR_CONF_EVENTID_param_tlvs *param_buf; 20114 wmi_vdev_update_mac_addr_conf_event_fixed_param *event; 20115 20116 param_buf = 20117 (WMI_VDEV_UPDATE_MAC_ADDR_CONF_EVENTID_param_tlvs *)evt_buf; 20118 20119 event = param_buf->fixed_param; 20120 20121 *vdev_id = event->vdev_id; 20122 *status = event->status; 20123 20124 return QDF_STATUS_SUCCESS; 20125 } 20126 #endif 20127 20128 #ifdef WLAN_FEATURE_11BE_MLO 20129 /** 20130 * extract_quiet_offload_event_tlv() - extract quiet offload event 20131 * @wmi_handle: WMI handle 20132 * @evt_buf: event buffer 20133 * @quiet_event: quiet event extracted from the buffer 20134 * 20135 * Return: QDF_STATUS 20136 */ 20137 static QDF_STATUS extract_quiet_offload_event_tlv( 20138 wmi_unified_t wmi_handle, void *evt_buf, 20139 struct vdev_sta_quiet_event *quiet_event) 20140 { 20141 WMI_QUIET_HANDLING_EVENTID_param_tlvs *param_buf; 20142 wmi_quiet_event_fixed_param *event; 20143 20144 param_buf = (WMI_QUIET_HANDLING_EVENTID_param_tlvs *)evt_buf; 20145 20146 event = param_buf->fixed_param; 20147 20148 if (!(event->mld_mac_address_present && event->linkid_present) && 20149 !event->link_mac_address_present) { 20150 wmi_err("Invalid sta quiet offload event. present bit: mld mac %d link mac %d linkid %d", 20151 event->mld_mac_address_present, 20152 event->linkid_present, 20153 event->link_mac_address_present); 20154 return QDF_STATUS_E_INVAL; 20155 } 20156 20157 if (event->mld_mac_address_present) 20158 WMI_MAC_ADDR_TO_CHAR_ARRAY(&event->mld_mac_address, 20159 quiet_event->mld_mac.bytes); 20160 if (event->link_mac_address_present) 20161 WMI_MAC_ADDR_TO_CHAR_ARRAY(&event->link_mac_address, 20162 quiet_event->link_mac.bytes); 20163 if (event->linkid_present) 20164 quiet_event->link_id = event->linkid; 20165 quiet_event->quiet_status = (event->quiet_status == 20166 WMI_QUIET_EVENT_START); 20167 20168 return QDF_STATUS_SUCCESS; 20169 } 20170 #endif 20171 20172 /** 20173 * send_vdev_pn_mgmt_rxfilter_cmd_tlv() - Send PN mgmt RxFilter command to FW 20174 * @wmi_handle: wmi handle 20175 * @params: RxFilter params 20176 * 20177 * Return: QDF_STATUS_SUCCESS for success or error code 20178 */ 20179 static QDF_STATUS 20180 send_vdev_pn_mgmt_rxfilter_cmd_tlv(wmi_unified_t wmi_handle, 20181 struct vdev_pn_mgmt_rxfilter_params *params) 20182 { 20183 wmi_vdev_pn_mgmt_rx_filter_cmd_fixed_param *cmd; 20184 wmi_buf_t buf; 20185 uint32_t len = sizeof(wmi_vdev_pn_mgmt_rx_filter_cmd_fixed_param); 20186 20187 if (!is_service_enabled_tlv(wmi_handle, 20188 WMI_SERVICE_PN_REPLAY_CHECK_SUPPORT)) { 20189 wmi_err("Rx PN Replay Check not supported by target"); 20190 return QDF_STATUS_E_NOSUPPORT; 20191 } 20192 20193 buf = wmi_buf_alloc(wmi_handle, len); 20194 if (!buf) { 20195 wmi_err("wmi buf alloc failed"); 20196 return QDF_STATUS_E_NOMEM; 20197 } 20198 20199 cmd = (wmi_vdev_pn_mgmt_rx_filter_cmd_fixed_param *)wmi_buf_data(buf); 20200 WMITLV_SET_HDR( 20201 &cmd->tlv_header, 20202 WMITLV_TAG_STRUC_wmi_vdev_pn_mgmt_rx_filter_cmd_fixed_param, 20203 WMITLV_GET_STRUCT_TLVLEN 20204 (wmi_vdev_pn_mgmt_rx_filter_cmd_fixed_param)); 20205 20206 cmd->vdev_id = params->vdev_id; 20207 cmd->pn_rx_filter = params->pn_rxfilter; 20208 20209 if (wmi_unified_cmd_send(wmi_handle, buf, len, 20210 WMI_VDEV_PN_MGMT_RX_FILTER_CMDID)) { 20211 wmi_err("Failed to send WMI command"); 20212 wmi_buf_free(buf); 20213 return QDF_STATUS_E_FAILURE; 20214 } 20215 20216 return QDF_STATUS_SUCCESS; 20217 } 20218 20219 static QDF_STATUS 20220 extract_pktlog_decode_info_event_tlv(wmi_unified_t wmi_handle, void *evt_buf, 20221 uint8_t *pdev_id, uint8_t *software_image, 20222 uint8_t *chip_info, 20223 uint32_t *pktlog_json_version) 20224 { 20225 WMI_PDEV_PKTLOG_DECODE_INFO_EVENTID_param_tlvs *param_buf; 20226 wmi_pdev_pktlog_decode_info_evt_fixed_param *event; 20227 20228 param_buf = 20229 (WMI_PDEV_PKTLOG_DECODE_INFO_EVENTID_param_tlvs *)evt_buf; 20230 20231 event = param_buf->fixed_param; 20232 20233 if ((event->software_image[0] == '\0') || 20234 (event->chip_info[0] == '\0')) { 20235 *pdev_id = event->pdev_id; 20236 return QDF_STATUS_E_INVAL; 20237 } 20238 20239 qdf_mem_copy(software_image, event->software_image, 40); 20240 qdf_mem_copy(chip_info, event->chip_info, 40); 20241 *pktlog_json_version = event->pktlog_defs_json_version; 20242 *pdev_id = event->pdev_id; 20243 return QDF_STATUS_SUCCESS; 20244 } 20245 20246 #ifdef HEALTH_MON_SUPPORT 20247 /** 20248 * extract_health_mon_init_done_info_event_tlv() - Extract health monitor from 20249 * fw 20250 * @wmi_handle: wmi handle 20251 * @evt_buf: pointer to event buffer 20252 * @param: health monitor params 20253 * 20254 * Return: QDF_STATUS_SUCCESS for success or error code 20255 */ 20256 static QDF_STATUS 20257 extract_health_mon_init_done_info_event_tlv(wmi_unified_t wmi_handle, 20258 void *evt_buf, 20259 struct wmi_health_mon_params *param) 20260 { 20261 WMI_HEALTH_MON_INIT_DONE_EVENTID_param_tlvs *param_buf; 20262 wmi_health_mon_init_done_fixed_param *event; 20263 20264 param_buf = 20265 (WMI_HEALTH_MON_INIT_DONE_EVENTID_param_tlvs *)evt_buf; 20266 20267 event = param_buf->fixed_param; 20268 20269 param->ring_buf_paddr_low = event->ring_buf_paddr_low; 20270 param->ring_buf_paddr_high = event->ring_buf_paddr_high; 20271 param->initial_upload_period_ms = event->initial_upload_period_ms; 20272 param->read_index = 0; 20273 20274 return QDF_STATUS_SUCCESS; 20275 } 20276 #endif /* HEALTH_MON_SUPPORT */ 20277 20278 /** 20279 * extract_pdev_telemetry_stats_tlv - extract pdev telemetry stats 20280 * @wmi_handle: wmi handle 20281 * @evt_buf: pointer to event buffer 20282 * @pdev_stats: Pointer to hold pdev telemetry stats 20283 * 20284 * Return: QDF_STATUS_SUCCESS for success or error code 20285 */ 20286 static QDF_STATUS 20287 extract_pdev_telemetry_stats_tlv( 20288 wmi_unified_t wmi_handle, void *evt_buf, 20289 struct wmi_host_pdev_telemetry_stats *pdev_stats) 20290 { 20291 WMI_UPDATE_STATS_EVENTID_param_tlvs *param_buf; 20292 wmi_pdev_telemetry_stats *ev; 20293 20294 param_buf = (WMI_UPDATE_STATS_EVENTID_param_tlvs *)evt_buf; 20295 20296 if (param_buf->pdev_telemetry_stats) { 20297 ev = (wmi_pdev_telemetry_stats *)(param_buf->pdev_telemetry_stats); 20298 qdf_mem_copy(pdev_stats->avg_chan_lat_per_ac, 20299 ev->avg_chan_lat_per_ac, 20300 sizeof(ev->avg_chan_lat_per_ac)); 20301 pdev_stats->estimated_air_time_per_ac = 20302 ev->estimated_air_time_per_ac; 20303 } 20304 20305 return QDF_STATUS_SUCCESS; 20306 } 20307 20308 static QDF_STATUS 20309 send_set_mac_addr_rx_filter_cmd_tlv(wmi_unified_t wmi_handle, 20310 struct set_rx_mac_filter *param) 20311 { 20312 wmi_vdev_add_mac_addr_to_rx_filter_cmd_fixed_param *cmd; 20313 uint32_t len; 20314 wmi_buf_t buf; 20315 int ret; 20316 20317 if (!wmi_handle) { 20318 wmi_err("WMA context is invalid!"); 20319 return QDF_STATUS_E_INVAL; 20320 } 20321 20322 len = sizeof(*cmd); 20323 buf = wmi_buf_alloc(wmi_handle, len); 20324 if (!buf) { 20325 wmi_err("Failed allocate wmi buffer"); 20326 return QDF_STATUS_E_NOMEM; 20327 } 20328 20329 cmd = (wmi_vdev_add_mac_addr_to_rx_filter_cmd_fixed_param *) 20330 wmi_buf_data(buf); 20331 20332 WMITLV_SET_HDR( 20333 &cmd->tlv_header, 20334 WMITLV_TAG_STRUC_wmi_vdev_add_mac_addr_to_rx_filter_cmd_fixed_param, 20335 WMITLV_GET_STRUCT_TLVLEN( 20336 wmi_vdev_add_mac_addr_to_rx_filter_cmd_fixed_param)); 20337 20338 cmd->vdev_id = param->vdev_id; 20339 cmd->freq = param->freq; 20340 WMI_CHAR_ARRAY_TO_MAC_ADDR(param->mac, &cmd->mac_addr); 20341 if (param->set) 20342 cmd->enable = 1; 20343 else 20344 cmd->enable = 0; 20345 wmi_debug("set random mac rx vdev:%d freq:%d set:%d " QDF_MAC_ADDR_FMT, 20346 param->vdev_id, param->freq, param->set, 20347 QDF_MAC_ADDR_REF(param->mac)); 20348 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 20349 WMI_VDEV_ADD_MAC_ADDR_TO_RX_FILTER_CMDID); 20350 if (ret) { 20351 wmi_err("Failed to send action frame random mac cmd"); 20352 wmi_buf_free(buf); 20353 return QDF_STATUS_E_FAILURE; 20354 } 20355 20356 return QDF_STATUS_SUCCESS; 20357 } 20358 20359 static QDF_STATUS 20360 extract_sap_coex_fix_chan_caps(wmi_unified_t wmi_handle, 20361 uint8_t *event, 20362 struct wmi_host_coex_fix_chan_cap *cap) 20363 { 20364 WMI_SERVICE_READY_EXT2_EVENTID_param_tlvs *param_buf; 20365 WMI_COEX_FIX_CHANNEL_CAPABILITIES *fw_cap; 20366 20367 param_buf = (WMI_SERVICE_READY_EXT2_EVENTID_param_tlvs *)event; 20368 if (!param_buf) 20369 return QDF_STATUS_E_INVAL; 20370 20371 fw_cap = param_buf->coex_fix_channel_caps; 20372 if (!fw_cap) 20373 return QDF_STATUS_E_INVAL; 20374 20375 cap->fix_chan_priority = fw_cap->fix_channel_priority; 20376 20377 return QDF_STATUS_SUCCESS; 20378 } 20379 20380 struct wmi_ops tlv_ops = { 20381 .send_vdev_create_cmd = send_vdev_create_cmd_tlv, 20382 .send_vdev_delete_cmd = send_vdev_delete_cmd_tlv, 20383 .send_vdev_nss_chain_params_cmd = send_vdev_nss_chain_params_cmd_tlv, 20384 .send_vdev_down_cmd = send_vdev_down_cmd_tlv, 20385 .send_vdev_start_cmd = send_vdev_start_cmd_tlv, 20386 .send_peer_flush_tids_cmd = send_peer_flush_tids_cmd_tlv, 20387 .send_peer_param_cmd = send_peer_param_cmd_tlv, 20388 .send_vdev_up_cmd = send_vdev_up_cmd_tlv, 20389 .send_vdev_stop_cmd = send_vdev_stop_cmd_tlv, 20390 .send_peer_create_cmd = send_peer_create_cmd_tlv, 20391 .send_peer_delete_cmd = send_peer_delete_cmd_tlv, 20392 .send_peer_delete_all_cmd = send_peer_delete_all_cmd_tlv, 20393 .send_peer_rx_reorder_queue_setup_cmd = 20394 send_peer_rx_reorder_queue_setup_cmd_tlv, 20395 .send_peer_rx_reorder_queue_remove_cmd = 20396 send_peer_rx_reorder_queue_remove_cmd_tlv, 20397 .send_pdev_utf_cmd = send_pdev_utf_cmd_tlv, 20398 .send_pdev_param_cmd = send_pdev_param_cmd_tlv, 20399 .send_multiple_pdev_param_cmd = send_multiple_pdev_param_cmd_tlv, 20400 .send_pdev_set_hw_mode_cmd = send_pdev_set_hw_mode_cmd_tlv, 20401 .send_suspend_cmd = send_suspend_cmd_tlv, 20402 .send_resume_cmd = send_resume_cmd_tlv, 20403 .send_wow_enable_cmd = send_wow_enable_cmd_tlv, 20404 .send_set_ap_ps_param_cmd = send_set_ap_ps_param_cmd_tlv, 20405 .send_set_sta_ps_param_cmd = send_set_sta_ps_param_cmd_tlv, 20406 .send_crash_inject_cmd = send_crash_inject_cmd_tlv, 20407 .send_dbglog_cmd = send_dbglog_cmd_tlv, 20408 .send_vdev_set_param_cmd = send_vdev_set_param_cmd_tlv, 20409 .send_vdev_set_mu_snif_cmd = send_vdev_set_mu_snif_cmd_tlv, 20410 .send_packet_log_enable_cmd = send_packet_log_enable_cmd_tlv, 20411 .send_peer_based_pktlog_cmd = send_peer_based_pktlog_cmd, 20412 .send_time_stamp_sync_cmd = send_time_stamp_sync_cmd_tlv, 20413 .send_packet_log_disable_cmd = send_packet_log_disable_cmd_tlv, 20414 .send_beacon_tmpl_send_cmd = send_beacon_tmpl_send_cmd_tlv, 20415 .send_fd_tmpl_cmd = send_fd_tmpl_cmd_tlv, 20416 .send_peer_assoc_cmd = send_peer_assoc_cmd_tlv, 20417 .send_scan_start_cmd = send_scan_start_cmd_tlv, 20418 .send_scan_stop_cmd = send_scan_stop_cmd_tlv, 20419 .send_scan_chan_list_cmd = send_scan_chan_list_cmd_tlv, 20420 .send_mgmt_cmd = send_mgmt_cmd_tlv, 20421 .send_offchan_data_tx_cmd = send_offchan_data_tx_cmd_tlv, 20422 .send_modem_power_state_cmd = send_modem_power_state_cmd_tlv, 20423 .send_set_sta_ps_mode_cmd = send_set_sta_ps_mode_cmd_tlv, 20424 .send_idle_roam_monitor_cmd = send_idle_roam_monitor_cmd_tlv, 20425 .send_set_sta_uapsd_auto_trig_cmd = 20426 send_set_sta_uapsd_auto_trig_cmd_tlv, 20427 .send_get_temperature_cmd = send_get_temperature_cmd_tlv, 20428 .send_set_smps_params_cmd = send_set_smps_params_cmd_tlv, 20429 .send_set_mimops_cmd = send_set_mimops_cmd_tlv, 20430 .send_set_thermal_mgmt_cmd = send_set_thermal_mgmt_cmd_tlv, 20431 .send_lro_config_cmd = send_lro_config_cmd_tlv, 20432 .send_peer_rate_report_cmd = send_peer_rate_report_cmd_tlv, 20433 .send_probe_rsp_tmpl_send_cmd = 20434 send_probe_rsp_tmpl_send_cmd_tlv, 20435 .send_p2p_go_set_beacon_ie_cmd = 20436 send_p2p_go_set_beacon_ie_cmd_tlv, 20437 .send_setup_install_key_cmd = 20438 send_setup_install_key_cmd_tlv, 20439 .send_scan_probe_setoui_cmd = 20440 send_scan_probe_setoui_cmd_tlv, 20441 #ifdef IPA_OFFLOAD 20442 .send_ipa_offload_control_cmd = 20443 send_ipa_offload_control_cmd_tlv, 20444 #endif 20445 .send_pno_stop_cmd = send_pno_stop_cmd_tlv, 20446 .send_pno_start_cmd = send_pno_start_cmd_tlv, 20447 .send_obss_disable_cmd = send_obss_disable_cmd_tlv, 20448 .send_nlo_mawc_cmd = send_nlo_mawc_cmd_tlv, 20449 #ifdef WLAN_FEATURE_LINK_LAYER_STATS 20450 .send_process_ll_stats_clear_cmd = send_process_ll_stats_clear_cmd_tlv, 20451 .send_process_ll_stats_set_cmd = send_process_ll_stats_set_cmd_tlv, 20452 .send_process_ll_stats_get_cmd = send_process_ll_stats_get_cmd_tlv, 20453 #ifdef FEATURE_CLUB_LL_STATS_AND_GET_STATION 20454 .send_unified_ll_stats_get_sta_cmd = 20455 send_unified_ll_stats_get_sta_cmd_tlv, 20456 #endif /* FEATURE_CLUB_LL_STATS_AND_GET_STATION */ 20457 #endif /* WLAN_FEATURE_LINK_LAYER_STATS*/ 20458 .send_congestion_cmd = send_congestion_cmd_tlv, 20459 .send_snr_request_cmd = send_snr_request_cmd_tlv, 20460 .send_snr_cmd = send_snr_cmd_tlv, 20461 .send_link_status_req_cmd = send_link_status_req_cmd_tlv, 20462 #if !defined(REMOVE_PKT_LOG) && defined(FEATURE_PKTLOG) 20463 .send_pktlog_wmi_send_cmd = send_pktlog_wmi_send_cmd_tlv, 20464 #endif 20465 #ifdef WLAN_SUPPORT_GREEN_AP 20466 .send_egap_conf_params_cmd = send_egap_conf_params_cmd_tlv, 20467 .send_green_ap_ps_cmd = send_green_ap_ps_cmd_tlv, 20468 .extract_green_ap_egap_status_info = 20469 extract_green_ap_egap_status_info_tlv, 20470 #endif 20471 #ifdef WLAN_SUPPORT_GAP_LL_PS_MODE 20472 .send_green_ap_ll_ps_cmd = send_green_ap_ll_ps_cmd_tlv, 20473 .extract_green_ap_ll_ps_param = extract_green_ap_ll_ps_param_tlv, 20474 #endif 20475 .send_csa_offload_enable_cmd = send_csa_offload_enable_cmd_tlv, 20476 .send_start_oem_data_cmd = send_start_oem_data_cmd_tlv, 20477 #ifdef FEATURE_OEM_DATA 20478 .send_start_oemv2_data_cmd = send_start_oemv2_data_cmd_tlv, 20479 #endif 20480 #ifdef WLAN_FEATURE_CIF_CFR 20481 .send_oem_dma_cfg_cmd = send_oem_dma_cfg_cmd_tlv, 20482 #endif 20483 .send_dfs_phyerr_filter_offload_en_cmd = 20484 send_dfs_phyerr_filter_offload_en_cmd_tlv, 20485 .send_stats_ext_req_cmd = send_stats_ext_req_cmd_tlv, 20486 .send_process_dhcpserver_offload_cmd = 20487 send_process_dhcpserver_offload_cmd_tlv, 20488 .send_pdev_set_regdomain_cmd = 20489 send_pdev_set_regdomain_cmd_tlv, 20490 .send_regdomain_info_to_fw_cmd = send_regdomain_info_to_fw_cmd_tlv, 20491 .send_cfg_action_frm_tb_ppdu_cmd = send_cfg_action_frm_tb_ppdu_cmd_tlv, 20492 .save_fw_version_cmd = save_fw_version_cmd_tlv, 20493 .check_and_update_fw_version = 20494 check_and_update_fw_version_cmd_tlv, 20495 .send_log_supported_evt_cmd = send_log_supported_evt_cmd_tlv, 20496 .send_enable_specific_fw_logs_cmd = 20497 send_enable_specific_fw_logs_cmd_tlv, 20498 .send_flush_logs_to_fw_cmd = send_flush_logs_to_fw_cmd_tlv, 20499 .send_unit_test_cmd = send_unit_test_cmd_tlv, 20500 #ifdef FEATURE_WLAN_APF 20501 .send_set_active_apf_mode_cmd = wmi_send_set_active_apf_mode_cmd_tlv, 20502 .send_apf_enable_cmd = wmi_send_apf_enable_cmd_tlv, 20503 .send_apf_write_work_memory_cmd = 20504 wmi_send_apf_write_work_memory_cmd_tlv, 20505 .send_apf_read_work_memory_cmd = 20506 wmi_send_apf_read_work_memory_cmd_tlv, 20507 .extract_apf_read_memory_resp_event = 20508 wmi_extract_apf_read_memory_resp_event_tlv, 20509 #endif /* FEATURE_WLAN_APF */ 20510 .init_cmd_send = init_cmd_send_tlv, 20511 .send_vdev_set_custom_aggr_size_cmd = 20512 send_vdev_set_custom_aggr_size_cmd_tlv, 20513 .send_vdev_set_qdepth_thresh_cmd = 20514 send_vdev_set_qdepth_thresh_cmd_tlv, 20515 .send_set_vap_dscp_tid_map_cmd = send_set_vap_dscp_tid_map_cmd_tlv, 20516 .send_vdev_set_fwtest_param_cmd = send_vdev_set_fwtest_param_cmd_tlv, 20517 .send_phyerr_disable_cmd = send_phyerr_disable_cmd_tlv, 20518 .send_phyerr_enable_cmd = send_phyerr_enable_cmd_tlv, 20519 .send_periodic_chan_stats_config_cmd = 20520 send_periodic_chan_stats_config_cmd_tlv, 20521 #ifdef WLAN_IOT_SIM_SUPPORT 20522 .send_simulation_test_cmd = send_simulation_test_cmd_tlv, 20523 #endif 20524 .send_vdev_spectral_configure_cmd = 20525 send_vdev_spectral_configure_cmd_tlv, 20526 .send_vdev_spectral_enable_cmd = 20527 send_vdev_spectral_enable_cmd_tlv, 20528 #ifdef WLAN_CONV_SPECTRAL_ENABLE 20529 .extract_pdev_sscan_fw_cmd_fixed_param = 20530 extract_pdev_sscan_fw_cmd_fixed_param_tlv, 20531 .extract_pdev_sscan_fft_bin_index = 20532 extract_pdev_sscan_fft_bin_index_tlv, 20533 .extract_pdev_spectral_session_chan_info = 20534 extract_pdev_spectral_session_chan_info_tlv, 20535 .extract_pdev_spectral_session_detector_info = 20536 extract_pdev_spectral_session_detector_info_tlv, 20537 .extract_spectral_caps_fixed_param = 20538 extract_spectral_caps_fixed_param_tlv, 20539 .extract_spectral_scan_bw_caps = 20540 extract_spectral_scan_bw_caps_tlv, 20541 .extract_spectral_fft_size_caps = 20542 extract_spectral_fft_size_caps_tlv, 20543 #endif /* WLAN_CONV_SPECTRAL_ENABLE */ 20544 .send_thermal_mitigation_param_cmd = 20545 send_thermal_mitigation_param_cmd_tlv, 20546 .send_process_update_edca_param_cmd = 20547 send_process_update_edca_param_cmd_tlv, 20548 .send_bss_color_change_enable_cmd = 20549 send_bss_color_change_enable_cmd_tlv, 20550 .send_coex_config_cmd = send_coex_config_cmd_tlv, 20551 .send_set_country_cmd = send_set_country_cmd_tlv, 20552 .send_addba_send_cmd = send_addba_send_cmd_tlv, 20553 .send_delba_send_cmd = send_delba_send_cmd_tlv, 20554 .send_addba_clearresponse_cmd = send_addba_clearresponse_cmd_tlv, 20555 .get_target_cap_from_service_ready = extract_service_ready_tlv, 20556 .extract_hal_reg_cap = extract_hal_reg_cap_tlv, 20557 .extract_num_mem_reqs = extract_num_mem_reqs_tlv, 20558 .extract_host_mem_req = extract_host_mem_req_tlv, 20559 .save_service_bitmap = save_service_bitmap_tlv, 20560 .save_ext_service_bitmap = save_ext_service_bitmap_tlv, 20561 .is_service_enabled = is_service_enabled_tlv, 20562 .save_fw_version = save_fw_version_in_service_ready_tlv, 20563 .ready_extract_init_status = ready_extract_init_status_tlv, 20564 .ready_extract_mac_addr = ready_extract_mac_addr_tlv, 20565 .ready_extract_mac_addr_list = ready_extract_mac_addr_list_tlv, 20566 .extract_ready_event_params = extract_ready_event_params_tlv, 20567 .extract_dbglog_data_len = extract_dbglog_data_len_tlv, 20568 .extract_mgmt_rx_params = extract_mgmt_rx_params_tlv, 20569 .extract_frame_pn_params = extract_frame_pn_params_tlv, 20570 .extract_is_conn_ap_frame = extract_is_conn_ap_frm_param_tlv, 20571 .extract_vdev_roam_param = extract_vdev_roam_param_tlv, 20572 .extract_vdev_scan_ev_param = extract_vdev_scan_ev_param_tlv, 20573 #ifdef FEATURE_WLAN_SCAN_PNO 20574 .extract_nlo_match_ev_param = extract_nlo_match_ev_param_tlv, 20575 .extract_nlo_complete_ev_param = extract_nlo_complete_ev_param_tlv, 20576 #endif 20577 .extract_unit_test = extract_unit_test_tlv, 20578 .extract_pdev_ext_stats = extract_pdev_ext_stats_tlv, 20579 .extract_bcn_stats = extract_bcn_stats_tlv, 20580 .extract_bcnflt_stats = extract_bcnflt_stats_tlv, 20581 .extract_chan_stats = extract_chan_stats_tlv, 20582 .extract_vdev_prb_fils_stats = extract_vdev_prb_fils_stats_tlv, 20583 .extract_profile_ctx = extract_profile_ctx_tlv, 20584 .extract_profile_data = extract_profile_data_tlv, 20585 .send_fw_test_cmd = send_fw_test_cmd_tlv, 20586 .send_wfa_test_cmd = send_wfa_test_cmd_tlv, 20587 .send_power_dbg_cmd = send_power_dbg_cmd_tlv, 20588 .extract_service_ready_ext = extract_service_ready_ext_tlv, 20589 .extract_service_ready_ext2 = extract_service_ready_ext2_tlv, 20590 .extract_dbs_or_sbs_service_ready_ext2 = 20591 extract_dbs_or_sbs_cap_service_ready_ext2_tlv, 20592 .extract_hw_mode_cap_service_ready_ext = 20593 extract_hw_mode_cap_service_ready_ext_tlv, 20594 .extract_mac_phy_cap_service_ready_ext = 20595 extract_mac_phy_cap_service_ready_ext_tlv, 20596 .extract_mac_phy_cap_service_ready_ext2 = 20597 extract_mac_phy_cap_service_ready_ext2_tlv, 20598 .extract_reg_cap_service_ready_ext = 20599 extract_reg_cap_service_ready_ext_tlv, 20600 .extract_hal_reg_cap_ext2 = extract_hal_reg_cap_ext2_tlv, 20601 .extract_dbr_ring_cap_service_ready_ext = 20602 extract_dbr_ring_cap_service_ready_ext_tlv, 20603 .extract_dbr_ring_cap_service_ready_ext2 = 20604 extract_dbr_ring_cap_service_ready_ext2_tlv, 20605 .extract_scan_radio_cap_service_ready_ext2 = 20606 extract_scan_radio_cap_service_ready_ext2_tlv, 20607 .extract_sw_cal_ver_ext2 = extract_sw_cal_ver_ext2_tlv, 20608 .extract_sar_cap_service_ready_ext = 20609 extract_sar_cap_service_ready_ext_tlv, 20610 .extract_pdev_utf_event = extract_pdev_utf_event_tlv, 20611 .wmi_set_htc_tx_tag = wmi_set_htc_tx_tag_tlv, 20612 .extract_fips_event_data = extract_fips_event_data_tlv, 20613 #ifdef WLAN_FEATURE_FIPS_BER_CCMGCM 20614 .extract_fips_extend_ev_data = extract_fips_extend_event_data_tlv, 20615 #endif 20616 #if defined(WLAN_SUPPORT_FILS) || defined(CONFIG_BAND_6GHZ) 20617 .send_vdev_fils_enable_cmd = send_vdev_fils_enable_cmd_send, 20618 #endif 20619 #ifdef WLAN_FEATURE_DISA 20620 .extract_encrypt_decrypt_resp_event = 20621 extract_encrypt_decrypt_resp_event_tlv, 20622 #endif 20623 .send_pdev_fips_cmd = send_pdev_fips_cmd_tlv, 20624 #ifdef WLAN_FEATURE_FIPS_BER_CCMGCM 20625 .send_pdev_fips_extend_cmd = send_pdev_fips_extend_cmd_tlv, 20626 .send_pdev_fips_mode_set_cmd = send_pdev_fips_mode_set_cmd_tlv, 20627 #endif 20628 .extract_get_pn_data = extract_get_pn_data_tlv, 20629 .send_pdev_get_pn_cmd = send_pdev_get_pn_cmd_tlv, 20630 .extract_get_rxpn_data = extract_get_rxpn_data_tlv, 20631 .send_pdev_get_rxpn_cmd = send_pdev_get_rxpn_cmd_tlv, 20632 .send_wlan_profile_enable_cmd = send_wlan_profile_enable_cmd_tlv, 20633 #ifdef WLAN_FEATURE_DISA 20634 .send_encrypt_decrypt_send_cmd = send_encrypt_decrypt_send_cmd_tlv, 20635 #endif 20636 .send_wlan_profile_trigger_cmd = send_wlan_profile_trigger_cmd_tlv, 20637 .send_wlan_profile_hist_intvl_cmd = 20638 send_wlan_profile_hist_intvl_cmd_tlv, 20639 .is_management_record = is_management_record_tlv, 20640 .is_diag_event = is_diag_event_tlv, 20641 #ifdef WLAN_FEATURE_ACTION_OUI 20642 .send_action_oui_cmd = send_action_oui_cmd_tlv, 20643 #endif 20644 .send_dfs_phyerr_offload_en_cmd = send_dfs_phyerr_offload_en_cmd_tlv, 20645 #ifdef QCA_SUPPORT_AGILE_DFS 20646 .send_adfs_ch_cfg_cmd = send_adfs_ch_cfg_cmd_tlv, 20647 .send_adfs_ocac_abort_cmd = send_adfs_ocac_abort_cmd_tlv, 20648 #endif 20649 .send_dfs_phyerr_offload_dis_cmd = send_dfs_phyerr_offload_dis_cmd_tlv, 20650 .extract_reg_chan_list_update_event = 20651 extract_reg_chan_list_update_event_tlv, 20652 #ifdef CONFIG_BAND_6GHZ 20653 .extract_reg_chan_list_ext_update_event = 20654 extract_reg_chan_list_ext_update_event_tlv, 20655 #ifdef CONFIG_AFC_SUPPORT 20656 .extract_afc_event = extract_afc_event_tlv, 20657 #endif 20658 #endif 20659 #ifdef WLAN_SUPPORT_RF_CHARACTERIZATION 20660 .extract_num_rf_characterization_entries = 20661 extract_num_rf_characterization_entries_tlv, 20662 .extract_rf_characterization_entries = 20663 extract_rf_characterization_entries_tlv, 20664 #endif 20665 .extract_chainmask_tables = 20666 extract_chainmask_tables_tlv, 20667 .extract_thermal_stats = extract_thermal_stats_tlv, 20668 .extract_thermal_level_stats = extract_thermal_level_stats_tlv, 20669 .send_get_rcpi_cmd = send_get_rcpi_cmd_tlv, 20670 .extract_rcpi_response_event = extract_rcpi_response_event_tlv, 20671 #ifdef DFS_COMPONENT_ENABLE 20672 .extract_dfs_cac_complete_event = extract_dfs_cac_complete_event_tlv, 20673 .extract_dfs_ocac_complete_event = extract_dfs_ocac_complete_event_tlv, 20674 .extract_dfs_radar_detection_event = 20675 extract_dfs_radar_detection_event_tlv, 20676 .extract_wlan_radar_event_info = extract_wlan_radar_event_info_tlv, 20677 #endif 20678 .convert_pdev_id_host_to_target = 20679 convert_host_pdev_id_to_target_pdev_id_legacy, 20680 .convert_pdev_id_target_to_host = 20681 convert_target_pdev_id_to_host_pdev_id_legacy, 20682 20683 .convert_host_pdev_id_to_target = 20684 convert_host_pdev_id_to_target_pdev_id, 20685 .convert_target_pdev_id_to_host = 20686 convert_target_pdev_id_to_host_pdev_id, 20687 20688 .convert_host_vdev_param_tlv = convert_host_vdev_param_tlv, 20689 20690 .convert_phy_id_host_to_target = 20691 convert_host_phy_id_to_target_phy_id_legacy, 20692 .convert_phy_id_target_to_host = 20693 convert_target_phy_id_to_host_phy_id_legacy, 20694 20695 .convert_host_phy_id_to_target = 20696 convert_host_phy_id_to_target_phy_id, 20697 .convert_target_phy_id_to_host = 20698 convert_target_phy_id_to_host_phy_id, 20699 20700 .send_start_11d_scan_cmd = send_start_11d_scan_cmd_tlv, 20701 .send_stop_11d_scan_cmd = send_stop_11d_scan_cmd_tlv, 20702 .extract_reg_11d_new_country_event = 20703 extract_reg_11d_new_country_event_tlv, 20704 .send_user_country_code_cmd = send_user_country_code_cmd_tlv, 20705 .extract_reg_ch_avoid_event = 20706 extract_reg_ch_avoid_event_tlv, 20707 .send_obss_detection_cfg_cmd = send_obss_detection_cfg_cmd_tlv, 20708 .extract_obss_detection_info = extract_obss_detection_info_tlv, 20709 .wmi_pdev_id_conversion_enable = wmi_tlv_pdev_id_conversion_enable, 20710 .wmi_free_allocated_event = wmitlv_free_allocated_event_tlvs, 20711 .wmi_check_and_pad_event = wmitlv_check_and_pad_event_tlvs, 20712 .wmi_check_command_params = wmitlv_check_command_tlv_params, 20713 .extract_comb_phyerr = extract_comb_phyerr_tlv, 20714 .extract_single_phyerr = extract_single_phyerr_tlv, 20715 #ifdef QCA_SUPPORT_CP_STATS 20716 .extract_cca_stats = extract_cca_stats_tlv, 20717 #endif 20718 .extract_esp_estimation_ev_param = 20719 extract_esp_estimation_ev_param_tlv, 20720 .send_roam_scan_stats_cmd = send_roam_scan_stats_cmd_tlv, 20721 .extract_roam_scan_stats_res_evt = extract_roam_scan_stats_res_evt_tlv, 20722 #ifdef OBSS_PD 20723 .send_obss_spatial_reuse_set = send_obss_spatial_reuse_set_cmd_tlv, 20724 .send_obss_spatial_reuse_set_def_thresh = 20725 send_obss_spatial_reuse_set_def_thresh_cmd_tlv, 20726 .send_self_srg_bss_color_bitmap_set = 20727 send_self_srg_bss_color_bitmap_set_cmd_tlv, 20728 .send_self_srg_partial_bssid_bitmap_set = 20729 send_self_srg_partial_bssid_bitmap_set_cmd_tlv, 20730 .send_self_srg_obss_color_enable_bitmap = 20731 send_self_srg_obss_color_enable_bitmap_cmd_tlv, 20732 .send_self_srg_obss_bssid_enable_bitmap = 20733 send_self_srg_obss_bssid_enable_bitmap_cmd_tlv, 20734 .send_self_non_srg_obss_color_enable_bitmap = 20735 send_self_non_srg_obss_color_enable_bitmap_cmd_tlv, 20736 .send_self_non_srg_obss_bssid_enable_bitmap = 20737 send_self_non_srg_obss_bssid_enable_bitmap_cmd_tlv, 20738 #endif 20739 .extract_offload_bcn_tx_status_evt = extract_offload_bcn_tx_status_evt, 20740 .extract_ctl_failsafe_check_ev_param = 20741 extract_ctl_failsafe_check_ev_param_tlv, 20742 #ifdef WIFI_POS_CONVERGED 20743 .extract_oem_response_param = extract_oem_response_param_tlv, 20744 #endif /* WIFI_POS_CONVERGED */ 20745 #if defined(WIFI_POS_CONVERGED) && defined(WLAN_FEATURE_RTT_11AZ_SUPPORT) 20746 .extract_pasn_peer_create_req_event = 20747 extract_pasn_peer_create_req_event_tlv, 20748 .extract_pasn_peer_delete_req_event = 20749 extract_pasn_peer_delete_req_event_tlv, 20750 .send_rtt_pasn_auth_status_cmd = 20751 send_rtt_pasn_auth_status_cmd_tlv, 20752 .send_rtt_pasn_deauth_cmd = 20753 send_rtt_pasn_deauth_cmd_tlv, 20754 #endif 20755 #ifdef WLAN_MWS_INFO_DEBUGFS 20756 .send_mws_coex_status_req_cmd = send_mws_coex_status_req_cmd_tlv, 20757 #endif 20758 .extract_hw_mode_resp_event = extract_hw_mode_resp_event_status_tlv, 20759 #ifdef FEATURE_ANI_LEVEL_REQUEST 20760 .send_ani_level_cmd = send_ani_level_cmd_tlv, 20761 .extract_ani_level = extract_ani_level_tlv, 20762 #endif /* FEATURE_ANI_LEVEL_REQUEST */ 20763 .extract_roam_trigger_stats = extract_roam_trigger_stats_tlv, 20764 .extract_roam_scan_stats = extract_roam_scan_stats_tlv, 20765 .extract_roam_result_stats = extract_roam_result_stats_tlv, 20766 .extract_roam_11kv_stats = extract_roam_11kv_stats_tlv, 20767 #ifdef WLAN_FEATURE_PKT_CAPTURE 20768 .extract_vdev_mgmt_offload_event = extract_vdev_mgmt_offload_event_tlv, 20769 #endif 20770 #ifdef WLAN_FEATURE_PKT_CAPTURE_V2 20771 .extract_smart_monitor_event = extract_smart_monitor_event_tlv, 20772 #endif 20773 20774 #ifdef FEATURE_WLAN_TIME_SYNC_FTM 20775 .send_wlan_time_sync_ftm_trigger_cmd = send_wlan_ts_ftm_trigger_cmd_tlv, 20776 .send_wlan_ts_qtime_cmd = send_wlan_ts_qtime_cmd_tlv, 20777 .extract_time_sync_ftm_start_stop_event = 20778 extract_time_sync_ftm_start_stop_event_tlv, 20779 .extract_time_sync_ftm_offset_event = 20780 extract_time_sync_ftm_offset_event_tlv, 20781 #endif /* FEATURE_WLAN_TIME_SYNC_FTM */ 20782 .send_roam_scan_ch_list_req_cmd = send_roam_scan_ch_list_req_cmd_tlv, 20783 .send_injector_config_cmd = send_injector_config_cmd_tlv, 20784 .send_cp_stats_cmd = send_cp_stats_cmd_tlv, 20785 .send_halphy_stats_cmd = send_halphy_stats_cmd_tlv, 20786 #ifdef FEATURE_MEC_OFFLOAD 20787 .send_pdev_set_mec_timer_cmd = send_pdev_set_mec_timer_cmd_tlv, 20788 #endif 20789 #if defined(WLAN_SUPPORT_INFRA_CTRL_PATH_STATS) || defined(WLAN_TELEMETRY_STATS_SUPPORT) 20790 .extract_infra_cp_stats = extract_infra_cp_stats_tlv, 20791 #endif /* WLAN_SUPPORT_INFRA_CTRL_PATH_STATS */ 20792 .extract_cp_stats_more_pending = 20793 extract_cp_stats_more_pending_tlv, 20794 .extract_halphy_stats_end_of_event = 20795 extract_halphy_stats_end_of_event_tlv, 20796 .extract_halphy_stats_event_count = 20797 extract_halphy_stats_event_count_tlv, 20798 .send_vdev_tsf_tstamp_action_cmd = send_vdev_tsf_tstamp_action_cmd_tlv, 20799 .extract_vdev_tsf_report_event = extract_vdev_tsf_report_event_tlv, 20800 .extract_pdev_csa_switch_count_status = 20801 extract_pdev_csa_switch_count_status_tlv, 20802 .send_set_tpc_power_cmd = send_set_tpc_power_cmd_tlv, 20803 #ifdef CONFIG_AFC_SUPPORT 20804 .send_afc_cmd = send_afc_cmd_tlv, 20805 #endif 20806 .extract_dpd_status_ev_param = extract_dpd_status_ev_param_tlv, 20807 .extract_install_key_comp_event = extract_install_key_comp_event_tlv, 20808 .send_vdev_set_ltf_key_seed_cmd = 20809 send_vdev_set_ltf_key_seed_cmd_tlv, 20810 .extract_halphy_cal_status_ev_param = extract_halphy_cal_status_ev_param_tlv, 20811 .send_set_halphy_cal = send_set_halphy_cal_tlv, 20812 .extract_halphy_cal_ev_param = extract_halphy_cal_ev_param_tlv, 20813 #ifdef WLAN_MGMT_RX_REO_SUPPORT 20814 .extract_mgmt_rx_fw_consumed = extract_mgmt_rx_fw_consumed_tlv, 20815 .extract_mgmt_rx_reo_params = extract_mgmt_rx_reo_params_tlv, 20816 .send_mgmt_rx_reo_filter_config_cmd = 20817 send_mgmt_rx_reo_filter_config_cmd_tlv, 20818 #endif 20819 20820 #ifdef WLAN_FEATURE_ROAM_OFFLOAD 20821 .send_roam_set_param_cmd = send_roam_set_param_cmd_tlv, 20822 #endif /* WLAN_FEATURE_ROAM_OFFLOAD */ 20823 20824 #ifdef WLAN_FEATURE_DYNAMIC_MAC_ADDR_UPDATE 20825 .send_set_mac_address_cmd = send_set_mac_address_cmd_tlv, 20826 .extract_update_mac_address_event = 20827 extract_update_mac_address_event_tlv, 20828 #endif 20829 20830 #ifdef WLAN_FEATURE_11BE_MLO 20831 .extract_quiet_offload_event = 20832 extract_quiet_offload_event_tlv, 20833 #endif 20834 20835 #ifdef WLAN_SUPPORT_PPEDS 20836 .peer_ppe_ds_param_send = peer_ppe_ds_param_send_tlv, 20837 #endif /* WLAN_SUPPORT_PPEDS */ 20838 20839 .send_vdev_pn_mgmt_rxfilter_cmd = send_vdev_pn_mgmt_rxfilter_cmd_tlv, 20840 .extract_pktlog_decode_info_event = 20841 extract_pktlog_decode_info_event_tlv, 20842 .extract_pdev_telemetry_stats = extract_pdev_telemetry_stats_tlv, 20843 .extract_mgmt_rx_ext_params = extract_mgmt_rx_ext_params_tlv, 20844 #ifdef WLAN_FEATURE_PEER_TXQ_FLUSH_CONF 20845 .send_peer_txq_flush_config_cmd = send_peer_txq_flush_config_cmd_tlv, 20846 #endif 20847 #ifdef WLAN_FEATURE_DBAM_CONFIG 20848 .send_dbam_config_cmd = send_dbam_config_cmd_tlv, 20849 .extract_dbam_config_resp_event = extract_dbam_config_resp_event_tlv, 20850 #endif 20851 #ifdef FEATURE_SET 20852 .feature_set_cmd_send = feature_set_cmd_send_tlv, 20853 #endif 20854 #ifdef HEALTH_MON_SUPPORT 20855 .extract_health_mon_init_done_info_event = 20856 extract_health_mon_init_done_info_event_tlv, 20857 #endif /* HEALTH_MON_SUPPORT */ 20858 .send_multiple_vdev_param_cmd = send_multiple_vdev_param_cmd_tlv, 20859 .set_mac_addr_rx_filter = send_set_mac_addr_rx_filter_cmd_tlv, 20860 .send_update_edca_pifs_param_cmd = 20861 send_update_edca_pifs_param_cmd_tlv, 20862 .extract_sap_coex_cap_service_ready_ext2 = 20863 extract_sap_coex_fix_chan_caps, 20864 }; 20865 20866 #ifdef WLAN_FEATURE_11BE_MLO 20867 static void populate_tlv_events_id_mlo(WMI_EVT_ID *event_ids) 20868 { 20869 event_ids[wmi_mlo_setup_complete_event_id] = 20870 WMI_MLO_SETUP_COMPLETE_EVENTID; 20871 event_ids[wmi_mlo_teardown_complete_event_id] = 20872 WMI_MLO_TEARDOWN_COMPLETE_EVENTID; 20873 event_ids[wmi_mlo_link_set_active_resp_eventid] = 20874 WMI_MLO_LINK_SET_ACTIVE_RESP_EVENTID; 20875 event_ids[wmi_vdev_quiet_offload_eventid] = 20876 WMI_QUIET_HANDLING_EVENTID; 20877 event_ids[wmi_mlo_ap_vdev_tid_to_link_map_eventid] = 20878 WMI_MLO_AP_VDEV_TID_TO_LINK_MAP_EVENTID; 20879 event_ids[wmi_mlo_link_removal_eventid] = 20880 WMI_MLO_LINK_REMOVAL_EVENTID; 20881 } 20882 #else /* WLAN_FEATURE_11BE_MLO */ 20883 static inline void populate_tlv_events_id_mlo(WMI_EVT_ID *event_ids) 20884 { 20885 } 20886 #endif /* WLAN_FEATURE_11BE_MLO */ 20887 20888 /** 20889 * populate_tlv_events_id() - populates wmi event ids 20890 * @event_ids: Pointer to hold event ids 20891 * 20892 * Return: None 20893 */ 20894 static void populate_tlv_events_id(WMI_EVT_ID *event_ids) 20895 { 20896 event_ids[wmi_service_ready_event_id] = WMI_SERVICE_READY_EVENTID; 20897 event_ids[wmi_ready_event_id] = WMI_READY_EVENTID; 20898 event_ids[wmi_scan_event_id] = WMI_SCAN_EVENTID; 20899 event_ids[wmi_pdev_tpc_config_event_id] = WMI_PDEV_TPC_CONFIG_EVENTID; 20900 event_ids[wmi_chan_info_event_id] = WMI_CHAN_INFO_EVENTID; 20901 event_ids[wmi_phyerr_event_id] = WMI_PHYERR_EVENTID; 20902 event_ids[wmi_pdev_dump_event_id] = WMI_PDEV_DUMP_EVENTID; 20903 event_ids[wmi_tx_pause_event_id] = WMI_TX_PAUSE_EVENTID; 20904 event_ids[wmi_dfs_radar_event_id] = WMI_DFS_RADAR_EVENTID; 20905 event_ids[wmi_pdev_l1ss_track_event_id] = WMI_PDEV_L1SS_TRACK_EVENTID; 20906 event_ids[wmi_pdev_temperature_event_id] = WMI_PDEV_TEMPERATURE_EVENTID; 20907 event_ids[wmi_service_ready_ext_event_id] = 20908 WMI_SERVICE_READY_EXT_EVENTID; 20909 event_ids[wmi_service_ready_ext2_event_id] = 20910 WMI_SERVICE_READY_EXT2_EVENTID; 20911 event_ids[wmi_vdev_start_resp_event_id] = WMI_VDEV_START_RESP_EVENTID; 20912 event_ids[wmi_vdev_stopped_event_id] = WMI_VDEV_STOPPED_EVENTID; 20913 event_ids[wmi_vdev_install_key_complete_event_id] = 20914 WMI_VDEV_INSTALL_KEY_COMPLETE_EVENTID; 20915 event_ids[wmi_vdev_mcc_bcn_intvl_change_req_event_id] = 20916 WMI_VDEV_MCC_BCN_INTERVAL_CHANGE_REQ_EVENTID; 20917 20918 event_ids[wmi_vdev_tsf_report_event_id] = WMI_VDEV_TSF_REPORT_EVENTID; 20919 event_ids[wmi_peer_sta_kickout_event_id] = WMI_PEER_STA_KICKOUT_EVENTID; 20920 event_ids[wmi_peer_info_event_id] = WMI_PEER_INFO_EVENTID; 20921 event_ids[wmi_peer_tx_fail_cnt_thr_event_id] = 20922 WMI_PEER_TX_FAIL_CNT_THR_EVENTID; 20923 event_ids[wmi_peer_estimated_linkspeed_event_id] = 20924 WMI_PEER_ESTIMATED_LINKSPEED_EVENTID; 20925 event_ids[wmi_peer_state_event_id] = WMI_PEER_STATE_EVENTID; 20926 event_ids[wmi_peer_create_conf_event_id] = 20927 WMI_PEER_CREATE_CONF_EVENTID; 20928 event_ids[wmi_peer_delete_response_event_id] = 20929 WMI_PEER_DELETE_RESP_EVENTID; 20930 event_ids[wmi_peer_delete_all_response_event_id] = 20931 WMI_VDEV_DELETE_ALL_PEER_RESP_EVENTID; 20932 event_ids[wmi_mgmt_rx_event_id] = WMI_MGMT_RX_EVENTID; 20933 event_ids[wmi_host_swba_event_id] = WMI_HOST_SWBA_EVENTID; 20934 event_ids[wmi_tbttoffset_update_event_id] = 20935 WMI_TBTTOFFSET_UPDATE_EVENTID; 20936 event_ids[wmi_ext_tbttoffset_update_event_id] = 20937 WMI_TBTTOFFSET_EXT_UPDATE_EVENTID; 20938 event_ids[wmi_offload_bcn_tx_status_event_id] = 20939 WMI_OFFLOAD_BCN_TX_STATUS_EVENTID; 20940 event_ids[wmi_offload_prob_resp_tx_status_event_id] = 20941 WMI_OFFLOAD_PROB_RESP_TX_STATUS_EVENTID; 20942 event_ids[wmi_mgmt_tx_completion_event_id] = 20943 WMI_MGMT_TX_COMPLETION_EVENTID; 20944 event_ids[wmi_pdev_nfcal_power_all_channels_event_id] = 20945 WMI_PDEV_NFCAL_POWER_ALL_CHANNELS_EVENTID; 20946 event_ids[wmi_tx_delba_complete_event_id] = 20947 WMI_TX_DELBA_COMPLETE_EVENTID; 20948 event_ids[wmi_tx_addba_complete_event_id] = 20949 WMI_TX_ADDBA_COMPLETE_EVENTID; 20950 event_ids[wmi_ba_rsp_ssn_event_id] = WMI_BA_RSP_SSN_EVENTID; 20951 20952 event_ids[wmi_aggr_state_trig_event_id] = WMI_AGGR_STATE_TRIG_EVENTID; 20953 20954 event_ids[wmi_roam_event_id] = WMI_ROAM_EVENTID; 20955 event_ids[wmi_profile_match] = WMI_PROFILE_MATCH; 20956 20957 event_ids[wmi_roam_synch_event_id] = WMI_ROAM_SYNCH_EVENTID; 20958 event_ids[wmi_roam_synch_frame_event_id] = WMI_ROAM_SYNCH_FRAME_EVENTID; 20959 20960 event_ids[wmi_p2p_disc_event_id] = WMI_P2P_DISC_EVENTID; 20961 20962 event_ids[wmi_p2p_noa_event_id] = WMI_P2P_NOA_EVENTID; 20963 event_ids[wmi_p2p_lo_stop_event_id] = 20964 WMI_P2P_LISTEN_OFFLOAD_STOPPED_EVENTID; 20965 event_ids[wmi_vdev_add_macaddr_rx_filter_event_id] = 20966 WMI_VDEV_ADD_MAC_ADDR_TO_RX_FILTER_STATUS_EVENTID; 20967 event_ids[wmi_pdev_resume_event_id] = WMI_PDEV_RESUME_EVENTID; 20968 event_ids[wmi_wow_wakeup_host_event_id] = WMI_WOW_WAKEUP_HOST_EVENTID; 20969 event_ids[wmi_d0_wow_disable_ack_event_id] = 20970 WMI_D0_WOW_DISABLE_ACK_EVENTID; 20971 event_ids[wmi_wow_initial_wakeup_event_id] = 20972 WMI_WOW_INITIAL_WAKEUP_EVENTID; 20973 20974 event_ids[wmi_rtt_meas_report_event_id] = 20975 WMI_RTT_MEASUREMENT_REPORT_EVENTID; 20976 event_ids[wmi_tsf_meas_report_event_id] = 20977 WMI_TSF_MEASUREMENT_REPORT_EVENTID; 20978 event_ids[wmi_rtt_error_report_event_id] = WMI_RTT_ERROR_REPORT_EVENTID; 20979 event_ids[wmi_stats_ext_event_id] = WMI_STATS_EXT_EVENTID; 20980 event_ids[wmi_iface_link_stats_event_id] = WMI_IFACE_LINK_STATS_EVENTID; 20981 event_ids[wmi_peer_link_stats_event_id] = WMI_PEER_LINK_STATS_EVENTID; 20982 event_ids[wmi_radio_link_stats_link] = WMI_RADIO_LINK_STATS_EVENTID; 20983 event_ids[wmi_diag_event_id_log_supported_event_id] = 20984 WMI_DIAG_EVENT_LOG_SUPPORTED_EVENTID; 20985 event_ids[wmi_nlo_match_event_id] = WMI_NLO_MATCH_EVENTID; 20986 event_ids[wmi_nlo_scan_complete_event_id] = 20987 WMI_NLO_SCAN_COMPLETE_EVENTID; 20988 event_ids[wmi_apfind_event_id] = WMI_APFIND_EVENTID; 20989 event_ids[wmi_passpoint_match_event_id] = WMI_PASSPOINT_MATCH_EVENTID; 20990 20991 event_ids[wmi_gtk_offload_status_event_id] = 20992 WMI_GTK_OFFLOAD_STATUS_EVENTID; 20993 event_ids[wmi_gtk_rekey_fail_event_id] = WMI_GTK_REKEY_FAIL_EVENTID; 20994 event_ids[wmi_csa_handling_event_id] = WMI_CSA_HANDLING_EVENTID; 20995 event_ids[wmi_chatter_pc_query_event_id] = WMI_CHATTER_PC_QUERY_EVENTID; 20996 20997 event_ids[wmi_echo_event_id] = WMI_ECHO_EVENTID; 20998 20999 event_ids[wmi_pdev_utf_event_id] = WMI_PDEV_UTF_EVENTID; 21000 21001 event_ids[wmi_dbg_msg_event_id] = WMI_DEBUG_MESG_EVENTID; 21002 event_ids[wmi_update_stats_event_id] = WMI_UPDATE_STATS_EVENTID; 21003 event_ids[wmi_debug_print_event_id] = WMI_DEBUG_PRINT_EVENTID; 21004 event_ids[wmi_dcs_interference_event_id] = WMI_DCS_INTERFERENCE_EVENTID; 21005 event_ids[wmi_pdev_qvit_event_id] = WMI_PDEV_QVIT_EVENTID; 21006 event_ids[wmi_wlan_profile_data_event_id] = 21007 WMI_WLAN_PROFILE_DATA_EVENTID; 21008 event_ids[wmi_pdev_ftm_intg_event_id] = WMI_PDEV_FTM_INTG_EVENTID; 21009 event_ids[wmi_wlan_freq_avoid_event_id] = WMI_WLAN_FREQ_AVOID_EVENTID; 21010 event_ids[wmi_vdev_get_keepalive_event_id] = 21011 WMI_VDEV_GET_KEEPALIVE_EVENTID; 21012 event_ids[wmi_thermal_mgmt_event_id] = WMI_THERMAL_MGMT_EVENTID; 21013 21014 event_ids[wmi_diag_container_event_id] = 21015 WMI_DIAG_DATA_CONTAINER_EVENTID; 21016 21017 event_ids[wmi_host_auto_shutdown_event_id] = 21018 WMI_HOST_AUTO_SHUTDOWN_EVENTID; 21019 21020 event_ids[wmi_update_whal_mib_stats_event_id] = 21021 WMI_UPDATE_WHAL_MIB_STATS_EVENTID; 21022 21023 /*update ht/vht info based on vdev (rx and tx NSS and preamble) */ 21024 event_ids[wmi_update_vdev_rate_stats_event_id] = 21025 WMI_UPDATE_VDEV_RATE_STATS_EVENTID; 21026 21027 event_ids[wmi_diag_event_id] = WMI_DIAG_EVENTID; 21028 event_ids[wmi_unit_test_event_id] = WMI_UNIT_TEST_EVENTID; 21029 21030 /** Set OCB Sched Response, deprecated */ 21031 event_ids[wmi_ocb_set_sched_event_id] = WMI_OCB_SET_SCHED_EVENTID; 21032 21033 event_ids[wmi_dbg_mesg_flush_complete_event_id] = 21034 WMI_DEBUG_MESG_FLUSH_COMPLETE_EVENTID; 21035 event_ids[wmi_rssi_breach_event_id] = WMI_RSSI_BREACH_EVENTID; 21036 21037 /* GPIO Event */ 21038 event_ids[wmi_gpio_input_event_id] = WMI_GPIO_INPUT_EVENTID; 21039 event_ids[wmi_uploadh_event_id] = WMI_UPLOADH_EVENTID; 21040 21041 event_ids[wmi_captureh_event_id] = WMI_CAPTUREH_EVENTID; 21042 event_ids[wmi_rfkill_state_change_event_id] = 21043 WMI_RFKILL_STATE_CHANGE_EVENTID; 21044 21045 /* TDLS Event */ 21046 event_ids[wmi_tdls_peer_event_id] = WMI_TDLS_PEER_EVENTID; 21047 21048 event_ids[wmi_batch_scan_enabled_event_id] = 21049 WMI_BATCH_SCAN_ENABLED_EVENTID; 21050 event_ids[wmi_batch_scan_result_event_id] = 21051 WMI_BATCH_SCAN_RESULT_EVENTID; 21052 /* OEM Event */ 21053 event_ids[wmi_oem_cap_event_id] = WMI_OEM_CAPABILITY_EVENTID; 21054 event_ids[wmi_oem_meas_report_event_id] = 21055 WMI_OEM_MEASUREMENT_REPORT_EVENTID; 21056 event_ids[wmi_oem_report_event_id] = WMI_OEM_ERROR_REPORT_EVENTID; 21057 21058 /* NAN Event */ 21059 event_ids[wmi_nan_event_id] = WMI_NAN_EVENTID; 21060 21061 /* LPI Event */ 21062 event_ids[wmi_lpi_result_event_id] = WMI_LPI_RESULT_EVENTID; 21063 event_ids[wmi_lpi_status_event_id] = WMI_LPI_STATUS_EVENTID; 21064 event_ids[wmi_lpi_handoff_event_id] = WMI_LPI_HANDOFF_EVENTID; 21065 21066 /* ExtScan events */ 21067 event_ids[wmi_extscan_start_stop_event_id] = 21068 WMI_EXTSCAN_START_STOP_EVENTID; 21069 event_ids[wmi_extscan_operation_event_id] = 21070 WMI_EXTSCAN_OPERATION_EVENTID; 21071 event_ids[wmi_extscan_table_usage_event_id] = 21072 WMI_EXTSCAN_TABLE_USAGE_EVENTID; 21073 event_ids[wmi_extscan_cached_results_event_id] = 21074 WMI_EXTSCAN_CACHED_RESULTS_EVENTID; 21075 event_ids[wmi_extscan_wlan_change_results_event_id] = 21076 WMI_EXTSCAN_WLAN_CHANGE_RESULTS_EVENTID; 21077 event_ids[wmi_extscan_hotlist_match_event_id] = 21078 WMI_EXTSCAN_HOTLIST_MATCH_EVENTID; 21079 event_ids[wmi_extscan_capabilities_event_id] = 21080 WMI_EXTSCAN_CAPABILITIES_EVENTID; 21081 event_ids[wmi_extscan_hotlist_ssid_match_event_id] = 21082 WMI_EXTSCAN_HOTLIST_SSID_MATCH_EVENTID; 21083 21084 /* mDNS offload events */ 21085 event_ids[wmi_mdns_stats_event_id] = WMI_MDNS_STATS_EVENTID; 21086 21087 /* SAP Authentication offload events */ 21088 event_ids[wmi_sap_ofl_add_sta_event_id] = WMI_SAP_OFL_ADD_STA_EVENTID; 21089 event_ids[wmi_sap_ofl_del_sta_event_id] = WMI_SAP_OFL_DEL_STA_EVENTID; 21090 21091 /** Out-of-context-of-bss (OCB) events */ 21092 event_ids[wmi_ocb_set_config_resp_event_id] = 21093 WMI_OCB_SET_CONFIG_RESP_EVENTID; 21094 event_ids[wmi_ocb_get_tsf_timer_resp_event_id] = 21095 WMI_OCB_GET_TSF_TIMER_RESP_EVENTID; 21096 event_ids[wmi_dcc_get_stats_resp_event_id] = 21097 WMI_DCC_GET_STATS_RESP_EVENTID; 21098 event_ids[wmi_dcc_update_ndl_resp_event_id] = 21099 WMI_DCC_UPDATE_NDL_RESP_EVENTID; 21100 event_ids[wmi_dcc_stats_event_id] = WMI_DCC_STATS_EVENTID; 21101 /* System-On-Chip events */ 21102 event_ids[wmi_soc_set_hw_mode_resp_event_id] = 21103 WMI_SOC_SET_HW_MODE_RESP_EVENTID; 21104 event_ids[wmi_soc_hw_mode_transition_event_id] = 21105 WMI_SOC_HW_MODE_TRANSITION_EVENTID; 21106 event_ids[wmi_soc_set_dual_mac_config_resp_event_id] = 21107 WMI_SOC_SET_DUAL_MAC_CONFIG_RESP_EVENTID; 21108 event_ids[wmi_pdev_fips_event_id] = WMI_PDEV_FIPS_EVENTID; 21109 #ifdef WLAN_FEATURE_FIPS_BER_CCMGCM 21110 event_ids[wmi_pdev_fips_extend_event_id] = WMI_PDEV_FIPS_EXTEND_EVENTID; 21111 #endif 21112 event_ids[wmi_pdev_csa_switch_count_status_event_id] = 21113 WMI_PDEV_CSA_SWITCH_COUNT_STATUS_EVENTID; 21114 event_ids[wmi_vdev_ocac_complete_event_id] = 21115 WMI_VDEV_ADFS_OCAC_COMPLETE_EVENTID; 21116 event_ids[wmi_reg_chan_list_cc_event_id] = WMI_REG_CHAN_LIST_CC_EVENTID; 21117 event_ids[wmi_reg_chan_list_cc_ext_event_id] = 21118 WMI_REG_CHAN_LIST_CC_EXT_EVENTID; 21119 #ifdef CONFIG_AFC_SUPPORT 21120 event_ids[wmi_afc_event_id] = WMI_AFC_EVENTID, 21121 #endif 21122 event_ids[wmi_inst_rssi_stats_event_id] = WMI_INST_RSSI_STATS_EVENTID; 21123 event_ids[wmi_pdev_tpc_config_event_id] = WMI_PDEV_TPC_CONFIG_EVENTID; 21124 event_ids[wmi_peer_sta_ps_statechg_event_id] = 21125 WMI_PEER_STA_PS_STATECHG_EVENTID; 21126 event_ids[wmi_pdev_channel_hopping_event_id] = 21127 WMI_PDEV_CHANNEL_HOPPING_EVENTID; 21128 event_ids[wmi_offchan_data_tx_completion_event] = 21129 WMI_OFFCHAN_DATA_TX_COMPLETION_EVENTID; 21130 event_ids[wmi_dfs_cac_complete_id] = WMI_VDEV_DFS_CAC_COMPLETE_EVENTID; 21131 event_ids[wmi_dfs_radar_detection_event_id] = 21132 WMI_PDEV_DFS_RADAR_DETECTION_EVENTID; 21133 event_ids[wmi_tt_stats_event_id] = WMI_THERM_THROT_STATS_EVENTID; 21134 event_ids[wmi_11d_new_country_event_id] = WMI_11D_NEW_COUNTRY_EVENTID; 21135 event_ids[wmi_pdev_tpc_event_id] = WMI_PDEV_TPC_EVENTID; 21136 event_ids[wmi_get_arp_stats_req_id] = WMI_VDEV_GET_ARP_STAT_EVENTID; 21137 event_ids[wmi_service_available_event_id] = 21138 WMI_SERVICE_AVAILABLE_EVENTID; 21139 event_ids[wmi_update_rcpi_event_id] = WMI_UPDATE_RCPI_EVENTID; 21140 event_ids[wmi_pdev_check_cal_version_event_id] = WMI_PDEV_CHECK_CAL_VERSION_EVENTID; 21141 /* NDP events */ 21142 event_ids[wmi_ndp_initiator_rsp_event_id] = 21143 WMI_NDP_INITIATOR_RSP_EVENTID; 21144 event_ids[wmi_ndp_indication_event_id] = WMI_NDP_INDICATION_EVENTID; 21145 event_ids[wmi_ndp_confirm_event_id] = WMI_NDP_CONFIRM_EVENTID; 21146 event_ids[wmi_ndp_responder_rsp_event_id] = 21147 WMI_NDP_RESPONDER_RSP_EVENTID; 21148 event_ids[wmi_ndp_end_indication_event_id] = 21149 WMI_NDP_END_INDICATION_EVENTID; 21150 event_ids[wmi_ndp_end_rsp_event_id] = WMI_NDP_END_RSP_EVENTID; 21151 event_ids[wmi_ndl_schedule_update_event_id] = 21152 WMI_NDL_SCHEDULE_UPDATE_EVENTID; 21153 event_ids[wmi_ndp_event_id] = WMI_NDP_EVENTID; 21154 21155 event_ids[wmi_oem_response_event_id] = WMI_OEM_RESPONSE_EVENTID; 21156 event_ids[wmi_peer_stats_info_event_id] = WMI_PEER_STATS_INFO_EVENTID; 21157 event_ids[wmi_pdev_chip_power_stats_event_id] = 21158 WMI_PDEV_CHIP_POWER_STATS_EVENTID; 21159 event_ids[wmi_ap_ps_egap_info_event_id] = WMI_AP_PS_EGAP_INFO_EVENTID; 21160 event_ids[wmi_peer_assoc_conf_event_id] = WMI_PEER_ASSOC_CONF_EVENTID; 21161 event_ids[wmi_vdev_delete_resp_event_id] = WMI_VDEV_DELETE_RESP_EVENTID; 21162 event_ids[wmi_apf_capability_info_event_id] = 21163 WMI_BPF_CAPABILIY_INFO_EVENTID; 21164 event_ids[wmi_vdev_encrypt_decrypt_data_rsp_event_id] = 21165 WMI_VDEV_ENCRYPT_DECRYPT_DATA_RESP_EVENTID; 21166 event_ids[wmi_report_rx_aggr_failure_event_id] = 21167 WMI_REPORT_RX_AGGR_FAILURE_EVENTID; 21168 event_ids[wmi_pdev_chip_pwr_save_failure_detect_event_id] = 21169 WMI_PDEV_CHIP_POWER_SAVE_FAILURE_DETECTED_EVENTID; 21170 event_ids[wmi_peer_antdiv_info_event_id] = WMI_PEER_ANTDIV_INFO_EVENTID; 21171 event_ids[wmi_pdev_set_hw_mode_rsp_event_id] = 21172 WMI_PDEV_SET_HW_MODE_RESP_EVENTID; 21173 event_ids[wmi_pdev_hw_mode_transition_event_id] = 21174 WMI_PDEV_HW_MODE_TRANSITION_EVENTID; 21175 event_ids[wmi_pdev_set_mac_config_resp_event_id] = 21176 WMI_PDEV_SET_MAC_CONFIG_RESP_EVENTID; 21177 event_ids[wmi_coex_bt_activity_event_id] = 21178 WMI_WLAN_COEX_BT_ACTIVITY_EVENTID; 21179 event_ids[wmi_mgmt_tx_bundle_completion_event_id] = 21180 WMI_MGMT_TX_BUNDLE_COMPLETION_EVENTID; 21181 event_ids[wmi_radio_tx_power_level_stats_event_id] = 21182 WMI_RADIO_TX_POWER_LEVEL_STATS_EVENTID; 21183 event_ids[wmi_report_stats_event_id] = WMI_REPORT_STATS_EVENTID; 21184 event_ids[wmi_dma_buf_release_event_id] = 21185 WMI_PDEV_DMA_RING_BUF_RELEASE_EVENTID; 21186 event_ids[wmi_sap_obss_detection_report_event_id] = 21187 WMI_SAP_OBSS_DETECTION_REPORT_EVENTID; 21188 event_ids[wmi_host_swfda_event_id] = WMI_HOST_SWFDA_EVENTID; 21189 event_ids[wmi_sar_get_limits_event_id] = WMI_SAR_GET_LIMITS_EVENTID; 21190 event_ids[wmi_obss_color_collision_report_event_id] = 21191 WMI_OBSS_COLOR_COLLISION_DETECTION_EVENTID; 21192 event_ids[wmi_pdev_div_rssi_antid_event_id] = 21193 WMI_PDEV_DIV_RSSI_ANTID_EVENTID; 21194 #ifdef WLAN_SUPPORT_TWT 21195 event_ids[wmi_twt_enable_complete_event_id] = 21196 WMI_TWT_ENABLE_COMPLETE_EVENTID; 21197 event_ids[wmi_twt_disable_complete_event_id] = 21198 WMI_TWT_DISABLE_COMPLETE_EVENTID; 21199 event_ids[wmi_twt_add_dialog_complete_event_id] = 21200 WMI_TWT_ADD_DIALOG_COMPLETE_EVENTID; 21201 event_ids[wmi_twt_del_dialog_complete_event_id] = 21202 WMI_TWT_DEL_DIALOG_COMPLETE_EVENTID; 21203 event_ids[wmi_twt_pause_dialog_complete_event_id] = 21204 WMI_TWT_PAUSE_DIALOG_COMPLETE_EVENTID; 21205 event_ids[wmi_twt_resume_dialog_complete_event_id] = 21206 WMI_TWT_RESUME_DIALOG_COMPLETE_EVENTID; 21207 event_ids[wmi_twt_nudge_dialog_complete_event_id] = 21208 WMI_TWT_NUDGE_DIALOG_COMPLETE_EVENTID; 21209 event_ids[wmi_twt_session_stats_event_id] = 21210 WMI_TWT_SESSION_STATS_EVENTID; 21211 event_ids[wmi_twt_notify_event_id] = 21212 WMI_TWT_NOTIFY_EVENTID; 21213 event_ids[wmi_twt_ack_complete_event_id] = 21214 WMI_TWT_ACK_EVENTID; 21215 #endif 21216 event_ids[wmi_apf_get_vdev_work_memory_resp_event_id] = 21217 WMI_BPF_GET_VDEV_WORK_MEMORY_RESP_EVENTID; 21218 event_ids[wmi_wlan_sar2_result_event_id] = WMI_SAR2_RESULT_EVENTID; 21219 event_ids[wmi_esp_estimate_event_id] = WMI_ESP_ESTIMATE_EVENTID; 21220 event_ids[wmi_roam_scan_stats_event_id] = WMI_ROAM_SCAN_STATS_EVENTID; 21221 #ifdef WLAN_FEATURE_INTEROP_ISSUES_AP 21222 event_ids[wmi_pdev_interop_issues_ap_event_id] = 21223 WMI_PDEV_RAP_INFO_EVENTID; 21224 #endif 21225 #ifdef AST_HKV1_WORKAROUND 21226 event_ids[wmi_wds_peer_event_id] = WMI_WDS_PEER_EVENTID; 21227 #endif 21228 event_ids[wmi_pdev_ctl_failsafe_check_event_id] = 21229 WMI_PDEV_CTL_FAILSAFE_CHECK_EVENTID; 21230 event_ids[wmi_vdev_bcn_reception_stats_event_id] = 21231 WMI_VDEV_BCN_RECEPTION_STATS_EVENTID; 21232 event_ids[wmi_roam_denylist_event_id] = WMI_ROAM_BLACKLIST_EVENTID; 21233 event_ids[wmi_wlm_stats_event_id] = WMI_WLM_STATS_EVENTID; 21234 event_ids[wmi_peer_cfr_capture_event_id] = WMI_PEER_CFR_CAPTURE_EVENTID; 21235 event_ids[wmi_pdev_cold_boot_cal_event_id] = 21236 WMI_PDEV_COLD_BOOT_CAL_DATA_EVENTID; 21237 #ifdef WLAN_MWS_INFO_DEBUGFS 21238 event_ids[wmi_vdev_get_mws_coex_state_eventid] = 21239 WMI_VDEV_GET_MWS_COEX_STATE_EVENTID; 21240 event_ids[wmi_vdev_get_mws_coex_dpwb_state_eventid] = 21241 WMI_VDEV_GET_MWS_COEX_DPWB_STATE_EVENTID; 21242 event_ids[wmi_vdev_get_mws_coex_tdm_state_eventid] = 21243 WMI_VDEV_GET_MWS_COEX_TDM_STATE_EVENTID; 21244 event_ids[wmi_vdev_get_mws_coex_idrx_state_eventid] = 21245 WMI_VDEV_GET_MWS_COEX_IDRX_STATE_EVENTID; 21246 event_ids[wmi_vdev_get_mws_coex_antenna_sharing_state_eventid] = 21247 WMI_VDEV_GET_MWS_COEX_ANTENNA_SHARING_STATE_EVENTID; 21248 #endif 21249 event_ids[wmi_coex_report_antenna_isolation_event_id] = 21250 WMI_COEX_REPORT_ANTENNA_ISOLATION_EVENTID; 21251 event_ids[wmi_peer_ratecode_list_event_id] = 21252 WMI_PEER_RATECODE_LIST_EVENTID; 21253 event_ids[wmi_chan_rf_characterization_info_event_id] = 21254 WMI_CHAN_RF_CHARACTERIZATION_INFO_EVENTID; 21255 event_ids[wmi_roam_auth_offload_event_id] = 21256 WMI_ROAM_PREAUTH_START_EVENTID; 21257 event_ids[wmi_get_elna_bypass_event_id] = WMI_GET_ELNA_BYPASS_EVENTID; 21258 event_ids[wmi_motion_det_host_eventid] = WMI_MOTION_DET_HOST_EVENTID; 21259 event_ids[wmi_motion_det_base_line_host_eventid] = 21260 WMI_MOTION_DET_BASE_LINE_HOST_EVENTID; 21261 event_ids[wmi_get_ani_level_event_id] = WMI_GET_CHANNEL_ANI_EVENTID; 21262 event_ids[wmi_peer_tx_pn_response_event_id] = 21263 WMI_PEER_TX_PN_RESPONSE_EVENTID; 21264 event_ids[wmi_roam_stats_event_id] = WMI_ROAM_STATS_EVENTID; 21265 event_ids[wmi_oem_data_event_id] = WMI_OEM_DATA_EVENTID; 21266 event_ids[wmi_mgmt_offload_data_event_id] = 21267 WMI_VDEV_MGMT_OFFLOAD_EVENTID; 21268 event_ids[wmi_nan_dmesg_event_id] = 21269 WMI_NAN_DMESG_EVENTID; 21270 event_ids[wmi_pdev_multi_vdev_restart_response_event_id] = 21271 WMI_PDEV_MULTIPLE_VDEV_RESTART_RESP_EVENTID; 21272 event_ids[wmi_roam_pmkid_request_event_id] = 21273 WMI_ROAM_PMKID_REQUEST_EVENTID; 21274 #ifdef FEATURE_WLAN_TIME_SYNC_FTM 21275 event_ids[wmi_wlan_time_sync_ftm_start_stop_event_id] = 21276 WMI_VDEV_AUDIO_SYNC_START_STOP_EVENTID; 21277 event_ids[wmi_wlan_time_sync_q_initiator_target_offset_eventid] = 21278 WMI_VDEV_AUDIO_SYNC_Q_MASTER_SLAVE_OFFSET_EVENTID; 21279 #endif 21280 event_ids[wmi_roam_scan_chan_list_id] = 21281 WMI_ROAM_SCAN_CHANNEL_LIST_EVENTID; 21282 event_ids[wmi_muedca_params_config_eventid] = 21283 WMI_MUEDCA_PARAMS_CONFIG_EVENTID; 21284 event_ids[wmi_pdev_sscan_fw_param_eventid] = 21285 WMI_PDEV_SSCAN_FW_PARAM_EVENTID; 21286 event_ids[wmi_roam_cap_report_event_id] = 21287 WMI_ROAM_CAPABILITY_REPORT_EVENTID; 21288 event_ids[wmi_vdev_bcn_latency_event_id] = 21289 WMI_VDEV_BCN_LATENCY_EVENTID; 21290 event_ids[wmi_vdev_disconnect_event_id] = 21291 WMI_VDEV_DISCONNECT_EVENTID; 21292 event_ids[wmi_peer_create_conf_event_id] = 21293 WMI_PEER_CREATE_CONF_EVENTID; 21294 event_ids[wmi_pdev_cp_fwstats_eventid] = 21295 WMI_CTRL_PATH_STATS_EVENTID; 21296 event_ids[wmi_pdev_halphy_fwstats_eventid] = 21297 WMI_HALPHY_CTRL_PATH_STATS_EVENTID; 21298 event_ids[wmi_vdev_send_big_data_p2_eventid] = 21299 WMI_VDEV_SEND_BIG_DATA_P2_EVENTID; 21300 event_ids[wmi_pdev_get_dpd_status_event_id] = 21301 WMI_PDEV_GET_DPD_STATUS_EVENTID; 21302 #ifdef WLAN_FEATURE_PKT_CAPTURE_V2 21303 event_ids[wmi_vdev_smart_monitor_event_id] = 21304 WMI_VDEV_SMART_MONITOR_EVENTID; 21305 #endif 21306 event_ids[wmi_pdev_get_halphy_cal_status_event_id] = 21307 WMI_PDEV_GET_HALPHY_CAL_STATUS_EVENTID; 21308 event_ids[wmi_pdev_set_halphy_cal_event_id] = 21309 WMI_PDEV_SET_HALPHY_CAL_BMAP_EVENTID; 21310 event_ids[wmi_pdev_aoa_phasedelta_event_id] = 21311 WMI_PDEV_AOA_PHASEDELTA_EVENTID; 21312 #ifdef WLAN_MGMT_RX_REO_SUPPORT 21313 event_ids[wmi_mgmt_rx_fw_consumed_eventid] = 21314 WMI_MGMT_RX_FW_CONSUMED_EVENTID; 21315 #endif 21316 populate_tlv_events_id_mlo(event_ids); 21317 event_ids[wmi_roam_frame_event_id] = 21318 WMI_ROAM_FRAME_EVENTID; 21319 #ifdef WLAN_FEATURE_DYNAMIC_MAC_ADDR_UPDATE 21320 event_ids[wmi_vdev_update_mac_addr_conf_eventid] = 21321 WMI_VDEV_UPDATE_MAC_ADDR_CONF_EVENTID; 21322 #endif 21323 #ifdef WLAN_FEATURE_MCC_QUOTA 21324 event_ids[wmi_resmgr_chan_time_quota_changed_eventid] = 21325 WMI_RESMGR_CHAN_TIME_QUOTA_CHANGED_EVENTID; 21326 #endif 21327 event_ids[wmi_peer_rx_pn_response_event_id] = 21328 WMI_PEER_RX_PN_RESPONSE_EVENTID; 21329 event_ids[wmi_extract_pktlog_decode_info_eventid] = 21330 WMI_PDEV_PKTLOG_DECODE_INFO_EVENTID; 21331 #ifdef QCA_RSSI_DB2DBM 21332 event_ids[wmi_pdev_rssi_dbm_conversion_params_info_eventid] = 21333 WMI_PDEV_RSSI_DBM_CONVERSION_PARAMS_INFO_EVENTID; 21334 #endif 21335 #ifdef MULTI_CLIENT_LL_SUPPORT 21336 event_ids[wmi_vdev_latency_event_id] = WMI_VDEV_LATENCY_LEVEL_EVENTID; 21337 #endif 21338 #if defined(WIFI_POS_CONVERGED) && defined(WLAN_FEATURE_RTT_11AZ_SUPPORT) 21339 event_ids[wmi_rtt_pasn_peer_create_req_eventid] = 21340 WMI_RTT_PASN_PEER_CREATE_REQ_EVENTID; 21341 event_ids[wmi_rtt_pasn_peer_delete_eventid] = 21342 WMI_RTT_PASN_PEER_DELETE_EVENTID; 21343 #endif 21344 #ifdef WLAN_VENDOR_HANDOFF_CONTROL 21345 event_ids[wmi_get_roam_vendor_control_param_event_id] = 21346 WMI_ROAM_GET_VENDOR_CONTROL_PARAM_EVENTID; 21347 #endif 21348 #ifdef WLAN_FEATURE_DBAM_CONFIG 21349 event_ids[wmi_coex_dbam_complete_event_id] = 21350 WMI_COEX_DBAM_COMPLETE_EVENTID; 21351 #endif 21352 event_ids[wmi_spectral_capabilities_eventid] = 21353 WMI_SPECTRAL_CAPABILITIES_EVENTID; 21354 #ifdef WLAN_FEATURE_COAP 21355 event_ids[wmi_wow_coap_buf_info_eventid] = 21356 WMI_WOW_COAP_BUF_INFO_EVENTID; 21357 #endif 21358 #ifdef HEALTH_MON_SUPPORT 21359 event_ids[wmi_extract_health_mon_init_done_info_eventid] = 21360 WMI_HEALTH_MON_INIT_DONE_EVENTID; 21361 #endif /* HEALTH_MON_SUPPORT */ 21362 #ifdef WLAN_SUPPORT_GAP_LL_PS_MODE 21363 event_ids[wmi_xgap_enable_complete_eventid] = 21364 WMI_XGAP_ENABLE_COMPLETE_EVENTID; 21365 #endif 21366 } 21367 21368 #ifdef WLAN_FEATURE_LINK_LAYER_STATS 21369 #ifdef FEATURE_CLUB_LL_STATS_AND_GET_STATION 21370 static void wmi_populate_service_get_sta_in_ll_stats_req(uint32_t *wmi_service) 21371 { 21372 wmi_service[wmi_service_get_station_in_ll_stats_req] = 21373 WMI_SERVICE_UNIFIED_LL_GET_STA_CMD_SUPPORT; 21374 } 21375 #else 21376 static void wmi_populate_service_get_sta_in_ll_stats_req(uint32_t *wmi_service) 21377 { 21378 } 21379 #endif /* FEATURE_CLUB_LL_STATS_AND_GET_STATION */ 21380 #else 21381 static void wmi_populate_service_get_sta_in_ll_stats_req(uint32_t *wmi_service) 21382 { 21383 } 21384 #endif /* WLAN_FEATURE_LINK_LAYER_STATS */ 21385 21386 #ifdef WLAN_FEATURE_11BE_MLO 21387 static void populate_tlv_service_mlo(uint32_t *wmi_service) 21388 { 21389 wmi_service[wmi_service_mlo_sta_nan_ndi_support] = 21390 WMI_SERVICE_MLO_STA_NAN_NDI_SUPPORT; 21391 } 21392 #else /* WLAN_FEATURE_11BE_MLO */ 21393 static inline void populate_tlv_service_mlo(uint32_t *wmi_service) 21394 { 21395 } 21396 #endif /* WLAN_FEATURE_11BE_MLO */ 21397 21398 /** 21399 * populate_tlv_service() - populates wmi services 21400 * @wmi_service: Pointer to hold wmi_service 21401 * 21402 * Return: None 21403 */ 21404 static void populate_tlv_service(uint32_t *wmi_service) 21405 { 21406 wmi_service[wmi_service_beacon_offload] = WMI_SERVICE_BEACON_OFFLOAD; 21407 wmi_service[wmi_service_ack_timeout] = WMI_SERVICE_ACK_TIMEOUT; 21408 wmi_service[wmi_service_scan_offload] = WMI_SERVICE_SCAN_OFFLOAD; 21409 wmi_service[wmi_service_roam_scan_offload] = 21410 WMI_SERVICE_ROAM_SCAN_OFFLOAD; 21411 wmi_service[wmi_service_bcn_miss_offload] = 21412 WMI_SERVICE_BCN_MISS_OFFLOAD; 21413 wmi_service[wmi_service_sta_pwrsave] = WMI_SERVICE_STA_PWRSAVE; 21414 wmi_service[wmi_service_sta_advanced_pwrsave] = 21415 WMI_SERVICE_STA_ADVANCED_PWRSAVE; 21416 wmi_service[wmi_service_ap_uapsd] = WMI_SERVICE_AP_UAPSD; 21417 wmi_service[wmi_service_ap_dfs] = WMI_SERVICE_AP_DFS; 21418 wmi_service[wmi_service_11ac] = WMI_SERVICE_11AC; 21419 wmi_service[wmi_service_blockack] = WMI_SERVICE_BLOCKACK; 21420 wmi_service[wmi_service_phyerr] = WMI_SERVICE_PHYERR; 21421 wmi_service[wmi_service_bcn_filter] = WMI_SERVICE_BCN_FILTER; 21422 wmi_service[wmi_service_rtt] = WMI_SERVICE_RTT; 21423 wmi_service[wmi_service_wow] = WMI_SERVICE_WOW; 21424 wmi_service[wmi_service_ratectrl_cache] = WMI_SERVICE_RATECTRL_CACHE; 21425 wmi_service[wmi_service_iram_tids] = WMI_SERVICE_IRAM_TIDS; 21426 wmi_service[wmi_service_arpns_offload] = WMI_SERVICE_ARPNS_OFFLOAD; 21427 wmi_service[wmi_service_nlo] = WMI_SERVICE_NLO; 21428 wmi_service[wmi_service_gtk_offload] = WMI_SERVICE_GTK_OFFLOAD; 21429 wmi_service[wmi_service_scan_sch] = WMI_SERVICE_SCAN_SCH; 21430 wmi_service[wmi_service_csa_offload] = WMI_SERVICE_CSA_OFFLOAD; 21431 wmi_service[wmi_service_chatter] = WMI_SERVICE_CHATTER; 21432 wmi_service[wmi_service_coex_freqavoid] = WMI_SERVICE_COEX_FREQAVOID; 21433 wmi_service[wmi_service_packet_power_save] = 21434 WMI_SERVICE_PACKET_POWER_SAVE; 21435 wmi_service[wmi_service_force_fw_hang] = WMI_SERVICE_FORCE_FW_HANG; 21436 wmi_service[wmi_service_gpio] = WMI_SERVICE_GPIO; 21437 wmi_service[wmi_service_sta_dtim_ps_modulated_dtim] = 21438 WMI_SERVICE_STA_DTIM_PS_MODULATED_DTIM; 21439 wmi_service[wmi_sta_uapsd_basic_auto_trig] = 21440 WMI_STA_UAPSD_BASIC_AUTO_TRIG; 21441 wmi_service[wmi_sta_uapsd_var_auto_trig] = WMI_STA_UAPSD_VAR_AUTO_TRIG; 21442 wmi_service[wmi_service_sta_keep_alive] = WMI_SERVICE_STA_KEEP_ALIVE; 21443 wmi_service[wmi_service_tx_encap] = WMI_SERVICE_TX_ENCAP; 21444 wmi_service[wmi_service_ap_ps_detect_out_of_sync] = 21445 WMI_SERVICE_AP_PS_DETECT_OUT_OF_SYNC; 21446 wmi_service[wmi_service_early_rx] = WMI_SERVICE_EARLY_RX; 21447 wmi_service[wmi_service_sta_smps] = WMI_SERVICE_STA_SMPS; 21448 wmi_service[wmi_service_fwtest] = WMI_SERVICE_FWTEST; 21449 wmi_service[wmi_service_sta_wmmac] = WMI_SERVICE_STA_WMMAC; 21450 wmi_service[wmi_service_tdls] = WMI_SERVICE_TDLS; 21451 wmi_service[wmi_service_burst] = WMI_SERVICE_BURST; 21452 wmi_service[wmi_service_mcc_bcn_interval_change] = 21453 WMI_SERVICE_MCC_BCN_INTERVAL_CHANGE; 21454 wmi_service[wmi_service_adaptive_ocs] = WMI_SERVICE_ADAPTIVE_OCS; 21455 wmi_service[wmi_service_ba_ssn_support] = WMI_SERVICE_BA_SSN_SUPPORT; 21456 wmi_service[wmi_service_filter_ipsec_natkeepalive] = 21457 WMI_SERVICE_FILTER_IPSEC_NATKEEPALIVE; 21458 wmi_service[wmi_service_wlan_hb] = WMI_SERVICE_WLAN_HB; 21459 wmi_service[wmi_service_lte_ant_share_support] = 21460 WMI_SERVICE_LTE_ANT_SHARE_SUPPORT; 21461 wmi_service[wmi_service_batch_scan] = WMI_SERVICE_BATCH_SCAN; 21462 wmi_service[wmi_service_qpower] = WMI_SERVICE_QPOWER; 21463 wmi_service[wmi_service_plmreq] = WMI_SERVICE_PLMREQ; 21464 wmi_service[wmi_service_thermal_mgmt] = WMI_SERVICE_THERMAL_MGMT; 21465 wmi_service[wmi_service_rmc] = WMI_SERVICE_RMC; 21466 wmi_service[wmi_service_mhf_offload] = WMI_SERVICE_MHF_OFFLOAD; 21467 wmi_service[wmi_service_coex_sar] = WMI_SERVICE_COEX_SAR; 21468 wmi_service[wmi_service_bcn_txrate_override] = 21469 WMI_SERVICE_BCN_TXRATE_OVERRIDE; 21470 wmi_service[wmi_service_nan] = WMI_SERVICE_NAN; 21471 wmi_service[wmi_service_l1ss_stat] = WMI_SERVICE_L1SS_STAT; 21472 wmi_service[wmi_service_estimate_linkspeed] = 21473 WMI_SERVICE_ESTIMATE_LINKSPEED; 21474 wmi_service[wmi_service_obss_scan] = WMI_SERVICE_OBSS_SCAN; 21475 wmi_service[wmi_service_tdls_offchan] = WMI_SERVICE_TDLS_OFFCHAN; 21476 wmi_service[wmi_service_tdls_uapsd_buffer_sta] = 21477 WMI_SERVICE_TDLS_UAPSD_BUFFER_STA; 21478 wmi_service[wmi_service_tdls_uapsd_sleep_sta] = 21479 WMI_SERVICE_TDLS_UAPSD_SLEEP_STA; 21480 wmi_service[wmi_service_ibss_pwrsave] = WMI_SERVICE_IBSS_PWRSAVE; 21481 wmi_service[wmi_service_lpass] = WMI_SERVICE_LPASS; 21482 wmi_service[wmi_service_extscan] = WMI_SERVICE_EXTSCAN; 21483 wmi_service[wmi_service_d0wow] = WMI_SERVICE_D0WOW; 21484 wmi_service[wmi_service_hsoffload] = WMI_SERVICE_HSOFFLOAD; 21485 wmi_service[wmi_service_roam_ho_offload] = WMI_SERVICE_ROAM_HO_OFFLOAD; 21486 wmi_service[wmi_service_rx_full_reorder] = WMI_SERVICE_RX_FULL_REORDER; 21487 wmi_service[wmi_service_dhcp_offload] = WMI_SERVICE_DHCP_OFFLOAD; 21488 wmi_service[wmi_service_sta_rx_ipa_offload_support] = 21489 WMI_SERVICE_STA_RX_IPA_OFFLOAD_SUPPORT; 21490 wmi_service[wmi_service_mdns_offload] = WMI_SERVICE_MDNS_OFFLOAD; 21491 wmi_service[wmi_service_sap_auth_offload] = 21492 WMI_SERVICE_SAP_AUTH_OFFLOAD; 21493 wmi_service[wmi_service_dual_band_simultaneous_support] = 21494 WMI_SERVICE_DUAL_BAND_SIMULTANEOUS_SUPPORT; 21495 wmi_service[wmi_service_ocb] = WMI_SERVICE_OCB; 21496 wmi_service[wmi_service_ap_arpns_offload] = 21497 WMI_SERVICE_AP_ARPNS_OFFLOAD; 21498 wmi_service[wmi_service_per_band_chainmask_support] = 21499 WMI_SERVICE_PER_BAND_CHAINMASK_SUPPORT; 21500 wmi_service[wmi_service_packet_filter_offload] = 21501 WMI_SERVICE_PACKET_FILTER_OFFLOAD; 21502 wmi_service[wmi_service_mgmt_tx_htt] = WMI_SERVICE_MGMT_TX_HTT; 21503 wmi_service[wmi_service_mgmt_tx_wmi] = WMI_SERVICE_MGMT_TX_WMI; 21504 wmi_service[wmi_service_ext_msg] = WMI_SERVICE_EXT_MSG; 21505 wmi_service[wmi_service_ext2_msg] = WMI_SERVICE_EXT2_MSG; 21506 wmi_service[wmi_service_mawc] = WMI_SERVICE_MAWC; 21507 wmi_service[wmi_service_multiple_vdev_restart] = 21508 WMI_SERVICE_MULTIPLE_VDEV_RESTART; 21509 wmi_service[wmi_service_multiple_vdev_restart_bmap] = 21510 WMI_SERVICE_MULTIPLE_VDEV_RESTART_BITMAP_SUPPORT; 21511 wmi_service[wmi_service_smart_antenna_sw_support] = 21512 WMI_SERVICE_SMART_ANTENNA_SW_SUPPORT; 21513 wmi_service[wmi_service_smart_antenna_hw_support] = 21514 WMI_SERVICE_SMART_ANTENNA_HW_SUPPORT; 21515 21516 wmi_service[wmi_service_roam_offload] = WMI_SERVICE_UNAVAILABLE; 21517 wmi_service[wmi_service_ratectrl] = WMI_SERVICE_UNAVAILABLE; 21518 wmi_service[wmi_service_enhanced_proxy_sta] = WMI_SERVICE_UNAVAILABLE; 21519 wmi_service[wmi_service_tt] = WMI_SERVICE_THERM_THROT; 21520 wmi_service[wmi_service_atf] = WMI_SERVICE_ATF; 21521 wmi_service[wmi_service_peer_caching] = WMI_SERVICE_UNAVAILABLE; 21522 wmi_service[wmi_service_coex_gpio] = WMI_SERVICE_UNAVAILABLE; 21523 wmi_service[wmi_service_aux_spectral_intf] = WMI_SERVICE_UNAVAILABLE; 21524 wmi_service[wmi_service_aux_chan_load_intf] = WMI_SERVICE_UNAVAILABLE; 21525 wmi_service[wmi_service_bss_channel_info_64] = WMI_SERVICE_UNAVAILABLE; 21526 wmi_service[wmi_service_ext_res_cfg_support] = WMI_SERVICE_UNAVAILABLE; 21527 wmi_service[wmi_service_mesh] = WMI_SERVICE_UNAVAILABLE; 21528 wmi_service[wmi_service_restrt_chnl_support] = WMI_SERVICE_UNAVAILABLE; 21529 wmi_service[wmi_service_peer_stats] = WMI_SERVICE_UNAVAILABLE; 21530 wmi_service[wmi_service_mesh_11s] = WMI_SERVICE_UNAVAILABLE; 21531 wmi_service[wmi_service_periodic_chan_stat_support] = 21532 WMI_SERVICE_PERIODIC_CHAN_STAT_SUPPORT; 21533 wmi_service[wmi_service_tx_mode_push_only] = WMI_SERVICE_UNAVAILABLE; 21534 wmi_service[wmi_service_tx_mode_push_pull] = WMI_SERVICE_UNAVAILABLE; 21535 wmi_service[wmi_service_tx_mode_dynamic] = WMI_SERVICE_UNAVAILABLE; 21536 wmi_service[wmi_service_btcoex_duty_cycle] = WMI_SERVICE_UNAVAILABLE; 21537 wmi_service[wmi_service_4_wire_coex_support] = WMI_SERVICE_UNAVAILABLE; 21538 wmi_service[wmi_service_mesh] = WMI_SERVICE_ENTERPRISE_MESH; 21539 wmi_service[wmi_service_peer_assoc_conf] = WMI_SERVICE_PEER_ASSOC_CONF; 21540 wmi_service[wmi_service_egap] = WMI_SERVICE_EGAP; 21541 wmi_service[wmi_service_sta_pmf_offload] = WMI_SERVICE_STA_PMF_OFFLOAD; 21542 wmi_service[wmi_service_unified_wow_capability] = 21543 WMI_SERVICE_UNIFIED_WOW_CAPABILITY; 21544 wmi_service[wmi_service_enterprise_mesh] = WMI_SERVICE_ENTERPRISE_MESH; 21545 wmi_service[wmi_service_apf_offload] = WMI_SERVICE_BPF_OFFLOAD; 21546 wmi_service[wmi_service_sync_delete_cmds] = 21547 WMI_SERVICE_SYNC_DELETE_CMDS; 21548 wmi_service[wmi_service_ratectrl_limit_max_min_rates] = 21549 WMI_SERVICE_RATECTRL_LIMIT_MAX_MIN_RATES; 21550 wmi_service[wmi_service_nan_data] = WMI_SERVICE_NAN_DATA; 21551 wmi_service[wmi_service_nan_rtt] = WMI_SERVICE_NAN_RTT; 21552 wmi_service[wmi_service_11ax] = WMI_SERVICE_11AX; 21553 wmi_service[wmi_service_deprecated_replace] = 21554 WMI_SERVICE_DEPRECATED_REPLACE; 21555 wmi_service[wmi_service_tdls_conn_tracker_in_host_mode] = 21556 WMI_SERVICE_TDLS_CONN_TRACKER_IN_HOST_MODE; 21557 wmi_service[wmi_service_enhanced_mcast_filter] = 21558 WMI_SERVICE_ENHANCED_MCAST_FILTER; 21559 wmi_service[wmi_service_half_rate_quarter_rate_support] = 21560 WMI_SERVICE_HALF_RATE_QUARTER_RATE_SUPPORT; 21561 wmi_service[wmi_service_vdev_rx_filter] = WMI_SERVICE_VDEV_RX_FILTER; 21562 wmi_service[wmi_service_p2p_listen_offload_support] = 21563 WMI_SERVICE_P2P_LISTEN_OFFLOAD_SUPPORT; 21564 wmi_service[wmi_service_mark_first_wakeup_packet] = 21565 WMI_SERVICE_MARK_FIRST_WAKEUP_PACKET; 21566 wmi_service[wmi_service_multiple_mcast_filter_set] = 21567 WMI_SERVICE_MULTIPLE_MCAST_FILTER_SET; 21568 wmi_service[wmi_service_host_managed_rx_reorder] = 21569 WMI_SERVICE_HOST_MANAGED_RX_REORDER; 21570 wmi_service[wmi_service_flash_rdwr_support] = 21571 WMI_SERVICE_FLASH_RDWR_SUPPORT; 21572 wmi_service[wmi_service_wlan_stats_report] = 21573 WMI_SERVICE_WLAN_STATS_REPORT; 21574 wmi_service[wmi_service_tx_msdu_id_new_partition_support] = 21575 WMI_SERVICE_TX_MSDU_ID_NEW_PARTITION_SUPPORT; 21576 wmi_service[wmi_service_dfs_phyerr_offload] = 21577 WMI_SERVICE_DFS_PHYERR_OFFLOAD; 21578 wmi_service[wmi_service_rcpi_support] = WMI_SERVICE_RCPI_SUPPORT; 21579 wmi_service[wmi_service_fw_mem_dump_support] = 21580 WMI_SERVICE_FW_MEM_DUMP_SUPPORT; 21581 wmi_service[wmi_service_peer_stats_info] = WMI_SERVICE_PEER_STATS_INFO; 21582 wmi_service[wmi_service_regulatory_db] = WMI_SERVICE_REGULATORY_DB; 21583 wmi_service[wmi_service_11d_offload] = WMI_SERVICE_11D_OFFLOAD; 21584 wmi_service[wmi_service_hw_data_filtering] = 21585 WMI_SERVICE_HW_DATA_FILTERING; 21586 wmi_service[wmi_service_pkt_routing] = WMI_SERVICE_PKT_ROUTING; 21587 wmi_service[wmi_service_offchan_tx_wmi] = WMI_SERVICE_OFFCHAN_TX_WMI; 21588 wmi_service[wmi_service_chan_load_info] = WMI_SERVICE_CHAN_LOAD_INFO; 21589 wmi_service[wmi_service_extended_nss_support] = 21590 WMI_SERVICE_EXTENDED_NSS_SUPPORT; 21591 wmi_service[wmi_service_widebw_scan] = WMI_SERVICE_SCAN_PHYMODE_SUPPORT; 21592 wmi_service[wmi_service_bcn_offload_start_stop_support] = 21593 WMI_SERVICE_BCN_OFFLOAD_START_STOP_SUPPORT; 21594 wmi_service[wmi_service_offchan_data_tid_support] = 21595 WMI_SERVICE_OFFCHAN_DATA_TID_SUPPORT; 21596 wmi_service[wmi_service_support_dma] = 21597 WMI_SERVICE_SUPPORT_DIRECT_DMA; 21598 wmi_service[wmi_service_8ss_tx_bfee] = WMI_SERVICE_8SS_TX_BFEE; 21599 wmi_service[wmi_service_fils_support] = WMI_SERVICE_FILS_SUPPORT; 21600 wmi_service[wmi_service_mawc_support] = WMI_SERVICE_MAWC_SUPPORT; 21601 wmi_service[wmi_service_wow_wakeup_by_timer_pattern] = 21602 WMI_SERVICE_WOW_WAKEUP_BY_TIMER_PATTERN; 21603 wmi_service[wmi_service_11k_neighbour_report_support] = 21604 WMI_SERVICE_11K_NEIGHBOUR_REPORT_SUPPORT; 21605 wmi_service[wmi_service_ap_obss_detection_offload] = 21606 WMI_SERVICE_AP_OBSS_DETECTION_OFFLOAD; 21607 wmi_service[wmi_service_bss_color_offload] = 21608 WMI_SERVICE_BSS_COLOR_OFFLOAD; 21609 wmi_service[wmi_service_gmac_offload_support] = 21610 WMI_SERVICE_GMAC_OFFLOAD_SUPPORT; 21611 wmi_service[wmi_service_dual_beacon_on_single_mac_scc_support] = 21612 WMI_SERVICE_DUAL_BEACON_ON_SINGLE_MAC_SCC_SUPPORT; 21613 wmi_service[wmi_service_dual_beacon_on_single_mac_mcc_support] = 21614 WMI_SERVICE_DUAL_BEACON_ON_SINGLE_MAC_MCC_SUPPORT; 21615 wmi_service[wmi_service_twt_requestor] = WMI_SERVICE_STA_TWT; 21616 wmi_service[wmi_service_twt_responder] = WMI_SERVICE_AP_TWT; 21617 wmi_service[wmi_service_listen_interval_offload_support] = 21618 WMI_SERVICE_LISTEN_INTERVAL_OFFLOAD_SUPPORT; 21619 wmi_service[wmi_service_esp_support] = WMI_SERVICE_ESP_SUPPORT; 21620 wmi_service[wmi_service_obss_spatial_reuse] = 21621 WMI_SERVICE_OBSS_SPATIAL_REUSE; 21622 wmi_service[wmi_service_per_vdev_chain_support] = 21623 WMI_SERVICE_PER_VDEV_CHAINMASK_CONFIG_SUPPORT; 21624 wmi_service[wmi_service_new_htt_msg_format] = 21625 WMI_SERVICE_HTT_H2T_NO_HTC_HDR_LEN_IN_MSG_LEN; 21626 wmi_service[wmi_service_peer_unmap_cnf_support] = 21627 WMI_SERVICE_PEER_UNMAP_RESPONSE_SUPPORT; 21628 wmi_service[wmi_service_beacon_reception_stats] = 21629 WMI_SERVICE_BEACON_RECEPTION_STATS; 21630 wmi_service[wmi_service_vdev_latency_config] = 21631 WMI_SERVICE_VDEV_LATENCY_CONFIG; 21632 wmi_service[wmi_service_nan_dbs_support] = WMI_SERVICE_NAN_DBS_SUPPORT; 21633 wmi_service[wmi_service_ndi_dbs_support] = WMI_SERVICE_NDI_DBS_SUPPORT; 21634 wmi_service[wmi_service_nan_sap_support] = WMI_SERVICE_NAN_SAP_SUPPORT; 21635 wmi_service[wmi_service_ndi_sap_support] = WMI_SERVICE_NDI_SAP_SUPPORT; 21636 wmi_service[wmi_service_nan_disable_support] = 21637 WMI_SERVICE_NAN_DISABLE_SUPPORT; 21638 wmi_service[wmi_service_sta_plus_sta_support] = 21639 WMI_SERVICE_STA_PLUS_STA_SUPPORT; 21640 wmi_service[wmi_service_hw_db2dbm_support] = 21641 WMI_SERVICE_HW_DB2DBM_CONVERSION_SUPPORT; 21642 wmi_service[wmi_service_wlm_stats_support] = 21643 WMI_SERVICE_WLM_STATS_REQUEST; 21644 wmi_service[wmi_service_infra_mbssid] = WMI_SERVICE_INFRA_MBSSID; 21645 wmi_service[wmi_service_ema_ap_support] = WMI_SERVICE_EMA_AP_SUPPORT; 21646 wmi_service[wmi_service_ul_ru26_allowed] = WMI_SERVICE_UL_RU26_ALLOWED; 21647 wmi_service[wmi_service_cfr_capture_support] = 21648 WMI_SERVICE_CFR_CAPTURE_SUPPORT; 21649 wmi_service[wmi_service_bcast_twt_support] = 21650 WMI_SERVICE_BROADCAST_TWT; 21651 wmi_service[wmi_service_wpa3_ft_sae_support] = 21652 WMI_SERVICE_WPA3_FT_SAE_SUPPORT; 21653 wmi_service[wmi_service_wpa3_ft_suite_b_support] = 21654 WMI_SERVICE_WPA3_FT_SUITE_B_SUPPORT; 21655 wmi_service[wmi_service_ft_fils] = 21656 WMI_SERVICE_WPA3_FT_FILS; 21657 wmi_service[wmi_service_adaptive_11r_support] = 21658 WMI_SERVICE_ADAPTIVE_11R_ROAM; 21659 wmi_service[wmi_service_tx_compl_tsf64] = 21660 WMI_SERVICE_TX_COMPL_TSF64; 21661 wmi_service[wmi_service_data_stall_recovery_support] = 21662 WMI_SERVICE_DSM_ROAM_FILTER; 21663 wmi_service[wmi_service_vdev_delete_all_peer] = 21664 WMI_SERVICE_DELETE_ALL_PEER_SUPPORT; 21665 wmi_service[wmi_service_three_way_coex_config_legacy] = 21666 WMI_SERVICE_THREE_WAY_COEX_CONFIG_LEGACY; 21667 wmi_service[wmi_service_rx_fse_support] = 21668 WMI_SERVICE_RX_FSE_SUPPORT; 21669 wmi_service[wmi_service_sae_roam_support] = 21670 WMI_SERVICE_WPA3_SAE_ROAM_SUPPORT; 21671 wmi_service[wmi_service_owe_roam_support] = 21672 WMI_SERVICE_WPA3_OWE_ROAM_SUPPORT; 21673 wmi_service[wmi_service_6ghz_support] = 21674 WMI_SERVICE_6GHZ_SUPPORT; 21675 wmi_service[wmi_service_bw_165mhz_support] = 21676 WMI_SERVICE_BW_165MHZ_SUPPORT; 21677 wmi_service[wmi_service_bw_restricted_80p80_support] = 21678 WMI_SERVICE_BW_RESTRICTED_80P80_SUPPORT; 21679 wmi_service[wmi_service_packet_capture_support] = 21680 WMI_SERVICE_PACKET_CAPTURE_SUPPORT; 21681 wmi_service[wmi_service_nan_vdev] = WMI_SERVICE_NAN_VDEV_SUPPORT; 21682 wmi_service[wmi_service_peer_delete_no_peer_flush_tids_cmd] = 21683 WMI_SERVICE_PEER_DELETE_NO_PEER_FLUSH_TIDS_CMD; 21684 wmi_service[wmi_service_multiple_vdev_restart_ext] = 21685 WMI_SERVICE_UNAVAILABLE; 21686 wmi_service[wmi_service_time_sync_ftm] = 21687 WMI_SERVICE_AUDIO_SYNC_SUPPORT; 21688 wmi_service[wmi_service_nss_ratio_to_host_support] = 21689 WMI_SERVICE_NSS_RATIO_TO_HOST_SUPPORT; 21690 wmi_service[wmi_roam_scan_chan_list_to_host_support] = 21691 WMI_SERVICE_ROAM_SCAN_CHANNEL_LIST_TO_HOST_SUPPORT; 21692 wmi_service[wmi_beacon_protection_support] = 21693 WMI_SERVICE_BEACON_PROTECTION_SUPPORT; 21694 wmi_service[wmi_service_sta_nan_ndi_four_port] = 21695 WMI_SERVICE_NDI_NDI_STA_SUPPORT; 21696 wmi_service[wmi_service_host_scan_stop_vdev_all] = 21697 WMI_SERVICE_HOST_SCAN_STOP_VDEV_ALL_SUPPORT; 21698 wmi_service[wmi_support_extend_address] = 21699 WMI_SERVICE_SUPPORT_EXTEND_ADDRESS; 21700 wmi_service[wmi_service_srg_srp_spatial_reuse_support] = 21701 WMI_SERVICE_SRG_SRP_SPATIAL_REUSE_SUPPORT; 21702 wmi_service[wmi_service_suiteb_roam_support] = 21703 WMI_SERVICE_WPA3_SUITEB_ROAM_SUPPORT; 21704 wmi_service[wmi_service_no_interband_mcc_support] = 21705 WMI_SERVICE_NO_INTERBAND_MCC_SUPPORT; 21706 wmi_service[wmi_service_dual_sta_roam_support] = 21707 WMI_SERVICE_DUAL_STA_ROAM_SUPPORT; 21708 wmi_service[wmi_service_peer_create_conf] = 21709 WMI_SERVICE_PEER_CREATE_CONF; 21710 wmi_service[wmi_service_configure_roam_trigger_param_support] = 21711 WMI_SERVICE_CONFIGURE_ROAM_TRIGGER_PARAM_SUPPORT; 21712 wmi_service[wmi_service_5dot9_ghz_support] = 21713 WMI_SERVICE_5_DOT_9GHZ_SUPPORT; 21714 wmi_service[wmi_service_cfr_ta_ra_as_fp_support] = 21715 WMI_SERVICE_CFR_TA_RA_AS_FP_SUPPORT; 21716 wmi_service[wmi_service_cfr_capture_count_support] = 21717 WMI_SERVICE_CFR_CAPTURE_COUNT_SUPPORT; 21718 wmi_service[wmi_service_ocv_support] = 21719 WMI_SERVICE_OCV_SUPPORT; 21720 wmi_service[wmi_service_ll_stats_per_chan_rx_tx_time] = 21721 WMI_SERVICE_LL_STATS_PER_CHAN_RX_TX_TIME_SUPPORT; 21722 wmi_service[wmi_service_thermal_multi_client_support] = 21723 WMI_SERVICE_THERMAL_MULTI_CLIENT_SUPPORT; 21724 wmi_service[wmi_service_mbss_param_in_vdev_start_support] = 21725 WMI_SERVICE_MBSS_PARAM_IN_VDEV_START_SUPPORT; 21726 wmi_service[wmi_service_fse_cmem_alloc_support] = 21727 WMI_SERVICE_FSE_CMEM_ALLOC_SUPPORT; 21728 wmi_service[wmi_service_scan_conf_per_ch_support] = 21729 WMI_SERVICE_SCAN_CONFIG_PER_CHANNEL; 21730 wmi_service[wmi_service_csa_beacon_template] = 21731 WMI_SERVICE_CSA_BEACON_TEMPLATE; 21732 #if defined(WIFI_POS_CONVERGED) && defined(WLAN_FEATURE_RTT_11AZ_SUPPORT) 21733 wmi_service[wmi_service_rtt_11az_ntb_support] = 21734 WMI_SERVICE_RTT_11AZ_NTB_SUPPORT; 21735 wmi_service[wmi_service_rtt_11az_tb_support] = 21736 WMI_SERVICE_RTT_11AZ_TB_SUPPORT; 21737 wmi_service[wmi_service_rtt_11az_mac_sec_support] = 21738 WMI_SERVICE_RTT_11AZ_MAC_SEC_SUPPORT; 21739 wmi_service[wmi_service_rtt_11az_mac_phy_sec_support] = 21740 WMI_SERVICE_RTT_11AZ_MAC_PHY_SEC_SUPPORT; 21741 #endif 21742 #ifdef WLAN_FEATURE_IGMP_OFFLOAD 21743 wmi_service[wmi_service_igmp_offload_support] = 21744 WMI_SERVICE_IGMP_OFFLOAD_SUPPORT; 21745 #endif 21746 21747 #ifdef FEATURE_WLAN_TDLS 21748 #ifdef WLAN_FEATURE_11AX 21749 wmi_service[wmi_service_tdls_ax_support] = 21750 WMI_SERVICE_11AX_TDLS_SUPPORT; 21751 wmi_service[wmi_service_tdls_6g_support] = 21752 WMI_SERVICE_TDLS_6GHZ_SUPPORT; 21753 #endif 21754 wmi_service[wmi_service_tdls_wideband_support] = 21755 WMI_SERVICE_TDLS_WIDEBAND_SUPPORT; 21756 #endif 21757 21758 #ifdef WLAN_SUPPORT_TWT 21759 wmi_service[wmi_service_twt_bcast_req_support] = 21760 WMI_SERVICE_BROADCAST_TWT_REQUESTER; 21761 wmi_service[wmi_service_twt_bcast_resp_support] = 21762 WMI_SERVICE_BROADCAST_TWT_RESPONDER; 21763 wmi_service[wmi_service_twt_nudge] = 21764 WMI_SERVICE_TWT_NUDGE; 21765 wmi_service[wmi_service_all_twt] = 21766 WMI_SERVICE_TWT_ALL_DIALOG_ID; 21767 wmi_service[wmi_service_twt_statistics] = 21768 WMI_SERVICE_TWT_STATS; 21769 #endif 21770 wmi_service[wmi_service_spectral_scan_disabled] = 21771 WMI_SERVICE_SPECTRAL_SCAN_DISABLED; 21772 wmi_service[wmi_service_sae_eapol_offload_support] = 21773 WMI_SERVICE_SAE_EAPOL_OFFLOAD_SUPPORT; 21774 wmi_populate_service_get_sta_in_ll_stats_req(wmi_service); 21775 21776 wmi_service[wmi_service_wapi_concurrency_supported] = 21777 WMI_SERVICE_WAPI_CONCURRENCY_SUPPORTED; 21778 wmi_service[wmi_service_sap_connected_d3_wow] = 21779 WMI_SERVICE_SAP_CONNECTED_D3WOW; 21780 wmi_service[wmi_service_go_connected_d3_wow] = 21781 WMI_SERVICE_SAP_CONNECTED_D3WOW; 21782 wmi_service[wmi_service_ext_tpc_reg_support] = 21783 WMI_SERVICE_EXT_TPC_REG_SUPPORT; 21784 wmi_service[wmi_service_eirp_preferred_support] = 21785 WMI_SERVICE_EIRP_PREFERRED_SUPPORT; 21786 wmi_service[wmi_service_ndi_txbf_support] = 21787 WMI_SERVICE_NDI_TXBF_SUPPORT; 21788 wmi_service[wmi_service_reg_cc_ext_event_support] = 21789 WMI_SERVICE_REG_CC_EXT_EVENT_SUPPORT; 21790 wmi_service[wmi_service_bang_radar_320_support] = 21791 WMI_SERVICE_BANG_RADAR_320_SUPPORT; 21792 #if defined(CONFIG_BAND_6GHZ) 21793 wmi_service[wmi_service_lower_6g_edge_ch_supp] = 21794 WMI_SERVICE_ENABLE_LOWER_6G_EDGE_CH_SUPP; 21795 wmi_service[wmi_service_disable_upper_6g_edge_ch_supp] = 21796 WMI_SERVICE_DISABLE_UPPER_6G_EDGE_CH_SUPP; 21797 #ifdef CONFIG_AFC_SUPPORT 21798 wmi_service[wmi_service_afc_support] = 21799 WMI_SERVICE_AFC_SUPPORT; 21800 #endif 21801 #endif 21802 wmi_service[wmi_service_dcs_awgn_int_support] = 21803 WMI_SERVICE_DCS_AWGN_INT_SUPPORT; 21804 wmi_populate_service_11be(wmi_service); 21805 21806 #ifdef WLAN_FEATURE_BIG_DATA_STATS 21807 wmi_service[wmi_service_big_data_support] = 21808 WMI_SERVICE_BIG_DATA_SUPPORT; 21809 #endif 21810 wmi_service[wmi_service_ampdu_tx_buf_size_256_support] = 21811 WMI_SERVICE_AMPDU_TX_BUF_SIZE_256_SUPPORT; 21812 wmi_service[wmi_service_halphy_cal_enable_disable_support] = 21813 WMI_SERVICE_HALPHY_CAL_ENABLE_DISABLE_SUPPORT; 21814 wmi_service[wmi_service_halphy_cal_status] = 21815 WMI_SERVICE_HALPHY_CAL_STATUS; 21816 wmi_service[wmi_service_rtt_ap_initiator_staggered_mode_supported] = 21817 WMI_SERVICE_RTT_AP_INITIATOR_STAGGERED_MODE_SUPPORTED; 21818 wmi_service[wmi_service_rtt_ap_initiator_bursted_mode_supported] = 21819 WMI_SERVICE_RTT_AP_INITIATOR_BURSTED_MODE_SUPPORTED; 21820 wmi_service[wmi_service_ema_multiple_group_supported] = 21821 WMI_SERVICE_EMA_MULTIPLE_GROUP_SUPPORT; 21822 wmi_service[wmi_service_large_beacon_supported] = 21823 WMI_SERVICE_LARGE_BEACON_SUPPORT; 21824 wmi_service[wmi_service_aoa_for_rcc_supported] = 21825 WMI_SERVICE_AOA_FOR_RCC_SUPPORTED; 21826 #ifdef WLAN_FEATURE_P2P_P2P_STA 21827 wmi_service[wmi_service_p2p_p2p_cc_support] = 21828 WMI_SERVICE_P2P_P2P_CONCURRENCY_SUPPORT; 21829 #endif 21830 #ifdef THERMAL_STATS_SUPPORT 21831 wmi_service[wmi_service_thermal_stats_temp_range_supported] = 21832 WMI_SERVICE_THERMAL_THROT_STATS_TEMP_RANGE_SUPPORT; 21833 #endif 21834 wmi_service[wmi_service_hw_mode_policy_offload_support] = 21835 WMI_SERVICE_HW_MODE_POLICY_OFFLOAD_SUPPORT; 21836 wmi_service[wmi_service_mgmt_rx_reo_supported] = 21837 WMI_SERVICE_MGMT_RX_REO_SUPPORTED; 21838 wmi_service[wmi_service_phy_dma_byte_swap_support] = 21839 WMI_SERVICE_UNAVAILABLE; 21840 wmi_service[wmi_service_spectral_session_info_support] = 21841 WMI_SERVICE_SPECTRAL_SESSION_INFO_SUPPORT; 21842 wmi_service[wmi_service_umac_hang_recovery_support] = 21843 WMI_SERVICE_UMAC_HANG_RECOVERY_SUPPORT; 21844 wmi_service[wmi_service_mu_snif] = WMI_SERVICE_MU_SNIF; 21845 #ifdef WLAN_FEATURE_DYNAMIC_MAC_ADDR_UPDATE 21846 wmi_service[wmi_service_dynamic_update_vdev_macaddr_support] = 21847 WMI_SERVICE_DYNAMIC_VDEV_MAC_ADDR_UPDATE_SUPPORT; 21848 #endif 21849 wmi_service[wmi_service_probe_all_bw_support] = 21850 WMI_SERVICE_PROBE_ALL_BW_SUPPORT; 21851 wmi_service[wmi_service_pno_scan_conf_per_ch_support] = 21852 WMI_SERVICE_PNO_SCAN_CONFIG_PER_CHANNEL; 21853 #ifdef QCA_UNDECODED_METADATA_SUPPORT 21854 wmi_service[wmi_service_fp_phy_err_filter_support] = 21855 WMI_SERVICE_FP_PHY_ERR_FILTER_SUPPORT; 21856 #endif 21857 populate_tlv_service_mlo(wmi_service); 21858 wmi_service[wmi_service_pdev_rate_config_support] = 21859 WMI_SERVICE_PDEV_RATE_CONFIG_SUPPORT; 21860 wmi_service[wmi_service_multi_peer_group_cmd_support] = 21861 WMI_SERVICE_MULTIPLE_PEER_GROUP_CMD_SUPPORT; 21862 #ifdef WLAN_FEATURE_11BE 21863 wmi_service[wmi_service_radar_found_chan_freq_eq_center_freq] = 21864 WMI_IS_RADAR_FOUND_CHAN_FREQ_IS_CENTER_FREQ; 21865 #endif 21866 #ifdef WLAN_PDEV_VDEV_SEND_MULTI_PARAM 21867 wmi_service[wmi_service_combined_set_param_support] = 21868 WMI_SERVICE_COMBINED_SET_PARAM_SUPPORT; 21869 #endif 21870 wmi_service[wmi_service_pn_replay_check_support] = 21871 WMI_SERVICE_PN_REPLAY_CHECK_SUPPORT; 21872 #ifdef QCA_RSSI_DB2DBM 21873 wmi_service[wmi_service_pdev_rssi_dbm_conv_event_support] = 21874 WMI_SERVICE_PDEV_RSSI_DBM_CONV_EVENT_SUPPORT; 21875 #endif 21876 wmi_service[wmi_service_pktlog_decode_info_support] = 21877 WMI_SERVICE_PKTLOG_DECODE_INFO_SUPPORT; 21878 #ifdef WLAN_FEATURE_ROAM_OFFLOAD 21879 wmi_service[wmi_service_roam_stats_per_candidate_frame_info] = 21880 WMI_SERVICE_ROAM_STAT_PER_CANDIDATE_FRAME_INFO_SUPPORT; 21881 #endif 21882 #ifdef MULTI_CLIENT_LL_SUPPORT 21883 wmi_service[wmi_service_configure_multi_client_ll_support] = 21884 WMI_SERVICE_MULTI_CLIENT_LL_SUPPORT; 21885 #endif 21886 #ifdef WLAN_VENDOR_HANDOFF_CONTROL 21887 wmi_service[wmi_service_configure_vendor_handoff_control_support] = 21888 WMI_SERVICE_FW_INI_PARSE_SUPPORT; 21889 #endif 21890 wmi_service[wmi_service_linkspeed_roam_trigger_support] = 21891 WMI_SERVICE_LINKSPEED_ROAM_TRIGGER_SUPPORT; 21892 #ifdef FEATURE_SET 21893 wmi_service[wmi_service_feature_set_event_support] = 21894 WMI_SERVICE_FEATURE_SET_EVENT_SUPPORT; 21895 #endif 21896 #ifdef WLAN_FEATURE_SR 21897 wmi_service[wmi_service_obss_per_packet_sr_support] = 21898 WMI_SERVICE_OBSS_PER_PACKET_SR_SUPPORT; 21899 #endif 21900 wmi_service[wmi_service_wpa3_sha384_roam_support] = 21901 WMI_SERVICE_WMI_SERVICE_WPA3_SHA384_ROAM_SUPPORT; 21902 } 21903 21904 /** 21905 * wmi_ocb_ut_attach() - Attach OCB test framework 21906 * @wmi_handle: wmi handle 21907 * 21908 * Return: None 21909 */ 21910 #ifdef WLAN_OCB_UT 21911 void wmi_ocb_ut_attach(struct wmi_unified *wmi_handle); 21912 #else 21913 static inline void wmi_ocb_ut_attach(struct wmi_unified *wmi_handle) 21914 { 21915 return; 21916 } 21917 #endif 21918 21919 /** 21920 * wmi_tlv_attach() - Attach TLV APIs 21921 * @wmi_handle: wmi handle 21922 * Return: None 21923 */ 21924 void wmi_tlv_attach(wmi_unified_t wmi_handle) 21925 { 21926 wmi_handle->ops = &tlv_ops; 21927 wmi_ocb_ut_attach(wmi_handle); 21928 wmi_handle->soc->svc_ids = &multi_svc_ids[0]; 21929 #ifdef WMI_INTERFACE_EVENT_LOGGING 21930 /* Skip saving WMI_CMD_HDR and TLV HDR */ 21931 wmi_handle->soc->buf_offset_command = 8; 21932 /* WMI_CMD_HDR is already stripped, skip saving TLV HDR */ 21933 wmi_handle->soc->buf_offset_event = 4; 21934 #endif 21935 populate_tlv_events_id(wmi_handle->wmi_events); 21936 populate_tlv_service(wmi_handle->services); 21937 wmi_wds_attach_tlv(wmi_handle); 21938 wmi_twt_attach_tlv(wmi_handle); 21939 wmi_extscan_attach_tlv(wmi_handle); 21940 wmi_smart_ant_attach_tlv(wmi_handle); 21941 wmi_dbr_attach_tlv(wmi_handle); 21942 wmi_atf_attach_tlv(wmi_handle); 21943 wmi_ap_attach_tlv(wmi_handle); 21944 wmi_bcn_attach_tlv(wmi_handle); 21945 wmi_ocb_attach_tlv(wmi_handle); 21946 wmi_nan_attach_tlv(wmi_handle); 21947 wmi_p2p_attach_tlv(wmi_handle); 21948 wmi_interop_issues_ap_attach_tlv(wmi_handle); 21949 wmi_dcs_attach_tlv(wmi_handle); 21950 wmi_roam_attach_tlv(wmi_handle); 21951 wmi_concurrency_attach_tlv(wmi_handle); 21952 wmi_pmo_attach_tlv(wmi_handle); 21953 wmi_sta_attach_tlv(wmi_handle); 21954 wmi_11ax_bss_color_attach_tlv(wmi_handle); 21955 wmi_fwol_attach_tlv(wmi_handle); 21956 wmi_vdev_attach_tlv(wmi_handle); 21957 wmi_cfr_attach_tlv(wmi_handle); 21958 wmi_cp_stats_attach_tlv(wmi_handle); 21959 wmi_gpio_attach_tlv(wmi_handle); 21960 wmi_11be_attach_tlv(wmi_handle); 21961 wmi_coap_attach_tlv(wmi_handle); 21962 } 21963 qdf_export_symbol(wmi_tlv_attach); 21964 21965 /** 21966 * wmi_tlv_init() - Initialize WMI TLV module by registering TLV attach routine 21967 * 21968 * Return: None 21969 */ 21970 void wmi_tlv_init(void) 21971 { 21972 wmi_unified_register_module(WMI_TLV_TARGET, &wmi_tlv_attach); 21973 } 21974