blob: 0a11afc7a500f0c1e7fd1316e3b4adc3ad937a3f [file] [log] [blame]
/*
* Copyright (c) 2016-2020 The Linux Foundation. All rights reserved.
*
* Permission to use, copy, modify, and/or distribute this software for
* any purpose with or without fee is hereby granted, provided that the
* above copyright notice and this permission notice appear in all
* copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
* WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
* AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
* PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
*/
#include "wmi_unified_api.h"
#include "wmi.h"
#include "wmi_version.h"
#include "wmi_unified_priv.h"
#include "wmi_version_whitelist.h"
#include <qdf_module.h>
#include <wlan_defs.h>
#include <wlan_cmn.h>
#include <htc_services.h>
#ifdef FEATURE_WLAN_APF
#include "wmi_unified_apf_tlv.h"
#endif
#ifdef WLAN_FEATURE_ACTION_OUI
#include "wmi_unified_action_oui_tlv.h"
#endif
#ifdef WLAN_POWER_MANAGEMENT_OFFLOAD
#include "wlan_pmo_hw_filter_public_struct.h"
#endif
#include <wlan_utility.h>
#ifdef WLAN_SUPPORT_GREEN_AP
#include "wlan_green_ap_api.h"
#endif
#include "wmi_unified_twt_api.h"
#ifdef WLAN_POLICY_MGR_ENABLE
#include "wlan_policy_mgr_public_struct.h"
#endif
#ifdef WMI_SMART_ANT_SUPPORT
#include "wmi_unified_smart_ant_api.h"
#endif
#ifdef WMI_DBR_SUPPORT
#include "wmi_unified_dbr_api.h"
#endif
#ifdef WMI_ATF_SUPPORT
#include "wmi_unified_atf_api.h"
#endif
#ifdef WMI_AP_SUPPORT
#include "wmi_unified_ap_api.h"
#endif
/* HTC service ids for WMI for multi-radio */
static const uint32_t multi_svc_ids[] = {WMI_CONTROL_SVC,
WMI_CONTROL_SVC_WMAC1,
WMI_CONTROL_SVC_WMAC2};
#ifdef ENABLE_HOST_TO_TARGET_CONVERSION
/*Populate peer_param array whose index as host id and
*value as target id
*/
static const uint32_t peer_param_tlv[] = {
[WMI_HOST_PEER_MIMO_PS_STATE] = WMI_PEER_MIMO_PS_STATE,
[WMI_HOST_PEER_AMPDU] = WMI_PEER_AMPDU,
[WMI_HOST_PEER_AUTHORIZE] = WMI_PEER_AUTHORIZE,
[WMI_HOST_PEER_CHWIDTH] = WMI_PEER_CHWIDTH,
[WMI_HOST_PEER_NSS] = WMI_PEER_NSS,
[WMI_HOST_PEER_USE_4ADDR] = WMI_PEER_USE_4ADDR,
[WMI_HOST_PEER_MEMBERSHIP] = WMI_PEER_MEMBERSHIP,
[WMI_HOST_PEER_USERPOS] = WMI_PEER_USERPOS,
[WMI_HOST_PEER_CRIT_PROTO_HINT_ENABLED] =
WMI_PEER_CRIT_PROTO_HINT_ENABLED,
[WMI_HOST_PEER_TX_FAIL_CNT_THR] = WMI_PEER_TX_FAIL_CNT_THR,
[WMI_HOST_PEER_SET_HW_RETRY_CTS2S] = WMI_PEER_SET_HW_RETRY_CTS2S,
[WMI_HOST_PEER_IBSS_ATIM_WINDOW_LENGTH] =
WMI_PEER_IBSS_ATIM_WINDOW_LENGTH,
[WMI_HOST_PEER_PHYMODE] = WMI_PEER_PHYMODE,
[WMI_HOST_PEER_USE_FIXED_PWR] = WMI_PEER_USE_FIXED_PWR,
[WMI_HOST_PEER_PARAM_FIXED_RATE] = WMI_PEER_PARAM_FIXED_RATE,
[WMI_HOST_PEER_SET_MU_WHITELIST] = WMI_PEER_SET_MU_WHITELIST,
[WMI_HOST_PEER_SET_MAC_TX_RATE] = WMI_PEER_SET_MAX_TX_RATE,
[WMI_HOST_PEER_SET_MIN_TX_RATE] = WMI_PEER_SET_MIN_TX_RATE,
[WMI_HOST_PEER_SET_DEFAULT_ROUTING] = WMI_PEER_SET_DEFAULT_ROUTING,
[WMI_HOST_PEER_NSS_VHT160] = WMI_PEER_NSS_VHT160,
[WMI_HOST_PEER_NSS_VHT80_80] = WMI_PEER_NSS_VHT80_80,
[WMI_HOST_PEER_PARAM_SU_TXBF_SOUNDING_INTERVAL] =
WMI_PEER_PARAM_SU_TXBF_SOUNDING_INTERVAL,
[WMI_HOST_PEER_PARAM_MU_TXBF_SOUNDING_INTERVAL] =
WMI_PEER_PARAM_MU_TXBF_SOUNDING_INTERVAL,
[WMI_HOST_PEER_PARAM_TXBF_SOUNDING_ENABLE] =
WMI_PEER_PARAM_TXBF_SOUNDING_ENABLE,
[WMI_HOST_PEER_PARAM_MU_ENABLE] = WMI_PEER_PARAM_MU_ENABLE,
[WMI_HOST_PEER_PARAM_OFDMA_ENABLE] = WMI_PEER_PARAM_OFDMA_ENABLE,
[WMI_HOST_PEER_PARAM_ENABLE_FT] = WMI_PEER_PARAM_ENABLE_FT,
};
/**
* Populate pdev_param_value whose index is host param and value is target
* param
*/
static const uint32_t pdev_param_tlv[] = {
[wmi_pdev_param_tx_chain_mask] = WMI_PDEV_PARAM_TX_CHAIN_MASK,
[wmi_pdev_param_rx_chain_mask] = WMI_PDEV_PARAM_RX_CHAIN_MASK,
[wmi_pdev_param_txpower_limit2g] = WMI_PDEV_PARAM_TXPOWER_LIMIT2G,
[wmi_pdev_param_txpower_limit5g] = WMI_PDEV_PARAM_TXPOWER_LIMIT5G,
[wmi_pdev_param_txpower_scale] = WMI_PDEV_PARAM_TXPOWER_SCALE,
[wmi_pdev_param_beacon_gen_mode] = WMI_PDEV_PARAM_BEACON_GEN_MODE,
[wmi_pdev_param_beacon_tx_mode] = WMI_PDEV_PARAM_BEACON_TX_MODE,
[wmi_pdev_param_resmgr_offchan_mode] =
WMI_PDEV_PARAM_RESMGR_OFFCHAN_MODE,
[wmi_pdev_param_protection_mode] = WMI_PDEV_PARAM_PROTECTION_MODE,
[wmi_pdev_param_dynamic_bw] = WMI_PDEV_PARAM_DYNAMIC_BW,
[wmi_pdev_param_non_agg_sw_retry_th] =
WMI_PDEV_PARAM_NON_AGG_SW_RETRY_TH,
[wmi_pdev_param_agg_sw_retry_th] = WMI_PDEV_PARAM_AGG_SW_RETRY_TH,
[wmi_pdev_param_sta_kickout_th] = WMI_PDEV_PARAM_STA_KICKOUT_TH,
[wmi_pdev_param_ac_aggrsize_scaling] =
WMI_PDEV_PARAM_AC_AGGRSIZE_SCALING,
[wmi_pdev_param_ltr_enable] = WMI_PDEV_PARAM_LTR_ENABLE,
[wmi_pdev_param_ltr_ac_latency_be] =
WMI_PDEV_PARAM_LTR_AC_LATENCY_BE,
[wmi_pdev_param_ltr_ac_latency_bk] = WMI_PDEV_PARAM_LTR_AC_LATENCY_BK,
[wmi_pdev_param_ltr_ac_latency_vi] = WMI_PDEV_PARAM_LTR_AC_LATENCY_VI,
[wmi_pdev_param_ltr_ac_latency_vo] = WMI_PDEV_PARAM_LTR_AC_LATENCY_VO,
[wmi_pdev_param_ltr_ac_latency_timeout] =
WMI_PDEV_PARAM_LTR_AC_LATENCY_TIMEOUT,
[wmi_pdev_param_ltr_sleep_override] = WMI_PDEV_PARAM_LTR_SLEEP_OVERRIDE,
[wmi_pdev_param_ltr_rx_override] = WMI_PDEV_PARAM_LTR_RX_OVERRIDE,
[wmi_pdev_param_ltr_tx_activity_timeout] =
WMI_PDEV_PARAM_LTR_TX_ACTIVITY_TIMEOUT,
[wmi_pdev_param_l1ss_enable] = WMI_PDEV_PARAM_L1SS_ENABLE,
[wmi_pdev_param_dsleep_enable] = WMI_PDEV_PARAM_DSLEEP_ENABLE,
[wmi_pdev_param_pcielp_txbuf_flush] = WMI_PDEV_PARAM_PCIELP_TXBUF_FLUSH,
[wmi_pdev_param_pcielp_txbuf_watermark] =
WMI_PDEV_PARAM_PCIELP_TXBUF_WATERMARK,
[wmi_pdev_param_pcielp_txbuf_tmo_en] =
WMI_PDEV_PARAM_PCIELP_TXBUF_TMO_EN,
[wmi_pdev_param_pcielp_txbuf_tmo_value] =
WMI_PDEV_PARAM_PCIELP_TXBUF_TMO_VALUE,
[wmi_pdev_param_pdev_stats_update_period] =
WMI_PDEV_PARAM_PDEV_STATS_UPDATE_PERIOD,
[wmi_pdev_param_vdev_stats_update_period] =
WMI_PDEV_PARAM_VDEV_STATS_UPDATE_PERIOD,
[wmi_pdev_param_peer_stats_update_period] =
WMI_PDEV_PARAM_PEER_STATS_UPDATE_PERIOD,
[wmi_pdev_param_bcnflt_stats_update_period] =
WMI_PDEV_PARAM_BCNFLT_STATS_UPDATE_PERIOD,
[wmi_pdev_param_pmf_qos] = WMI_PDEV_PARAM_PMF_QOS,
[wmi_pdev_param_arp_ac_override] = WMI_PDEV_PARAM_ARP_AC_OVERRIDE,
[wmi_pdev_param_dcs] = WMI_PDEV_PARAM_DCS,
[wmi_pdev_param_ani_enable] = WMI_PDEV_PARAM_ANI_ENABLE,
[wmi_pdev_param_ani_poll_period] = WMI_PDEV_PARAM_ANI_POLL_PERIOD,
[wmi_pdev_param_ani_listen_period] = WMI_PDEV_PARAM_ANI_LISTEN_PERIOD,
[wmi_pdev_param_ani_ofdm_level] = WMI_PDEV_PARAM_ANI_OFDM_LEVEL,
[wmi_pdev_param_ani_cck_level] = WMI_PDEV_PARAM_ANI_CCK_LEVEL,
[wmi_pdev_param_dyntxchain] = WMI_PDEV_PARAM_DYNTXCHAIN,
[wmi_pdev_param_proxy_sta] = WMI_PDEV_PARAM_PROXY_STA,
[wmi_pdev_param_idle_ps_config] = WMI_PDEV_PARAM_IDLE_PS_CONFIG,
[wmi_pdev_param_power_gating_sleep] = WMI_PDEV_PARAM_POWER_GATING_SLEEP,
[wmi_pdev_param_rfkill_enable] = WMI_PDEV_PARAM_RFKILL_ENABLE,
[wmi_pdev_param_burst_dur] = WMI_PDEV_PARAM_BURST_DUR,
[wmi_pdev_param_burst_enable] = WMI_PDEV_PARAM_BURST_ENABLE,
[wmi_pdev_param_hw_rfkill_config] = WMI_PDEV_PARAM_HW_RFKILL_CONFIG,
[wmi_pdev_param_low_power_rf_enable] =
WMI_PDEV_PARAM_LOW_POWER_RF_ENABLE,
[wmi_pdev_param_l1ss_track] = WMI_PDEV_PARAM_L1SS_TRACK,
[wmi_pdev_param_hyst_en] = WMI_PDEV_PARAM_HYST_EN,
[wmi_pdev_param_power_collapse_enable] =
WMI_PDEV_PARAM_POWER_COLLAPSE_ENABLE,
[wmi_pdev_param_led_sys_state] = WMI_PDEV_PARAM_LED_SYS_STATE,
[wmi_pdev_param_led_enable] = WMI_PDEV_PARAM_LED_ENABLE,
[wmi_pdev_param_audio_over_wlan_latency] =
WMI_PDEV_PARAM_AUDIO_OVER_WLAN_LATENCY,
[wmi_pdev_param_audio_over_wlan_enable] =
WMI_PDEV_PARAM_AUDIO_OVER_WLAN_ENABLE,
[wmi_pdev_param_whal_mib_stats_update_enable] =
WMI_PDEV_PARAM_WHAL_MIB_STATS_UPDATE_ENABLE,
[wmi_pdev_param_vdev_rate_stats_update_period] =
WMI_PDEV_PARAM_VDEV_RATE_STATS_UPDATE_PERIOD,
[wmi_pdev_param_cts_cbw] = WMI_PDEV_PARAM_CTS_CBW,
[wmi_pdev_param_wnts_config] = WMI_PDEV_PARAM_WNTS_CONFIG,
[wmi_pdev_param_adaptive_early_rx_enable] =
WMI_PDEV_PARAM_ADAPTIVE_EARLY_RX_ENABLE,
[wmi_pdev_param_adaptive_early_rx_min_sleep_slop] =
WMI_PDEV_PARAM_ADAPTIVE_EARLY_RX_MIN_SLEEP_SLOP,
[wmi_pdev_param_adaptive_early_rx_inc_dec_step] =
WMI_PDEV_PARAM_ADAPTIVE_EARLY_RX_INC_DEC_STEP,
[wmi_pdev_param_early_rx_fix_sleep_slop] =
WMI_PDEV_PARAM_EARLY_RX_FIX_SLEEP_SLOP,
[wmi_pdev_param_bmiss_based_adaptive_bto_enable] =
WMI_PDEV_PARAM_BMISS_BASED_ADAPTIVE_BTO_ENABLE,
[wmi_pdev_param_bmiss_bto_min_bcn_timeout] =
WMI_PDEV_PARAM_BMISS_BTO_MIN_BCN_TIMEOUT,
[wmi_pdev_param_bmiss_bto_inc_dec_step] =
WMI_PDEV_PARAM_BMISS_BTO_INC_DEC_STEP,
[wmi_pdev_param_bto_fix_bcn_timeout] =
WMI_PDEV_PARAM_BTO_FIX_BCN_TIMEOUT,
[wmi_pdev_param_ce_based_adaptive_bto_enable] =
WMI_PDEV_PARAM_CE_BASED_ADAPTIVE_BTO_ENABLE,
[wmi_pdev_param_ce_bto_combo_ce_value] =
WMI_PDEV_PARAM_CE_BTO_COMBO_CE_VALUE,
[wmi_pdev_param_tx_chain_mask_2g] = WMI_PDEV_PARAM_TX_CHAIN_MASK_2G,
[wmi_pdev_param_rx_chain_mask_2g] = WMI_PDEV_PARAM_RX_CHAIN_MASK_2G,
[wmi_pdev_param_tx_chain_mask_5g] = WMI_PDEV_PARAM_TX_CHAIN_MASK_5G,
[wmi_pdev_param_rx_chain_mask_5g] = WMI_PDEV_PARAM_RX_CHAIN_MASK_5G,
[wmi_pdev_param_tx_chain_mask_cck] = WMI_PDEV_PARAM_TX_CHAIN_MASK_CCK,
[wmi_pdev_param_tx_chain_mask_1ss] = WMI_PDEV_PARAM_TX_CHAIN_MASK_1SS,
[wmi_pdev_param_rx_filter] = WMI_PDEV_PARAM_RX_FILTER,
[wmi_pdev_set_mcast_to_ucast_tid] = WMI_PDEV_SET_MCAST_TO_UCAST_TID,
[wmi_pdev_param_mgmt_retry_limit] = WMI_PDEV_PARAM_MGMT_RETRY_LIMIT,
[wmi_pdev_param_aggr_burst] = WMI_PDEV_PARAM_AGGR_BURST,
[wmi_pdev_peer_sta_ps_statechg_enable] =
WMI_PDEV_PEER_STA_PS_STATECHG_ENABLE,
[wmi_pdev_param_proxy_sta_mode] = WMI_PDEV_PARAM_PROXY_STA_MODE,
[wmi_pdev_param_mu_group_policy] = WMI_PDEV_PARAM_MU_GROUP_POLICY,
[wmi_pdev_param_noise_detection] = WMI_PDEV_PARAM_NOISE_DETECTION,
[wmi_pdev_param_noise_threshold] = WMI_PDEV_PARAM_NOISE_THRESHOLD,
[wmi_pdev_param_dpd_enable] = WMI_PDEV_PARAM_DPD_ENABLE,
[wmi_pdev_param_set_mcast_bcast_echo] =
WMI_PDEV_PARAM_SET_MCAST_BCAST_ECHO,
[wmi_pdev_param_atf_strict_sch] = WMI_PDEV_PARAM_ATF_STRICT_SCH,
[wmi_pdev_param_atf_sched_duration] = WMI_PDEV_PARAM_ATF_SCHED_DURATION,
[wmi_pdev_param_ant_plzn] = WMI_PDEV_PARAM_ANT_PLZN,
[wmi_pdev_param_sensitivity_level] = WMI_PDEV_PARAM_SENSITIVITY_LEVEL,
[wmi_pdev_param_signed_txpower_2g] = WMI_PDEV_PARAM_SIGNED_TXPOWER_2G,
[wmi_pdev_param_signed_txpower_5g] = WMI_PDEV_PARAM_SIGNED_TXPOWER_5G,
[wmi_pdev_param_enable_per_tid_amsdu] =
WMI_PDEV_PARAM_ENABLE_PER_TID_AMSDU,
[wmi_pdev_param_enable_per_tid_ampdu] =
WMI_PDEV_PARAM_ENABLE_PER_TID_AMPDU,
[wmi_pdev_param_cca_threshold] = WMI_PDEV_PARAM_CCA_THRESHOLD,
[wmi_pdev_param_rts_fixed_rate] = WMI_PDEV_PARAM_RTS_FIXED_RATE,
[wmi_pdev_param_cal_period] = WMI_UNAVAILABLE_PARAM,
[wmi_pdev_param_pdev_reset] = WMI_PDEV_PARAM_PDEV_RESET,
[wmi_pdev_param_wapi_mbssid_offset] = WMI_PDEV_PARAM_WAPI_MBSSID_OFFSET,
[wmi_pdev_param_arp_srcaddr] = WMI_PDEV_PARAM_ARP_DBG_SRCADDR,
[wmi_pdev_param_arp_dstaddr] = WMI_PDEV_PARAM_ARP_DBG_DSTADDR,
[wmi_pdev_param_txpower_decr_db] = WMI_PDEV_PARAM_TXPOWER_DECR_DB,
[wmi_pdev_param_rx_batchmode] = WMI_UNAVAILABLE_PARAM,
[wmi_pdev_param_packet_aggr_delay] = WMI_UNAVAILABLE_PARAM,
[wmi_pdev_param_atf_obss_noise_sch] =
WMI_PDEV_PARAM_ATF_OBSS_NOISE_SCH,
[wmi_pdev_param_atf_obss_noise_scaling_factor] =
WMI_PDEV_PARAM_ATF_OBSS_NOISE_SCALING_FACTOR,
[wmi_pdev_param_cust_txpower_scale] = WMI_PDEV_PARAM_CUST_TXPOWER_SCALE,
[wmi_pdev_param_atf_dynamic_enable] = WMI_PDEV_PARAM_ATF_DYNAMIC_ENABLE,
[wmi_pdev_param_atf_ssid_group_policy] = WMI_UNAVAILABLE_PARAM,
[wmi_pdev_param_igmpmld_override] = WMI_PDEV_PARAM_IGMPMLD_AC_OVERRIDE,
[wmi_pdev_param_igmpmld_tid] = WMI_PDEV_PARAM_IGMPMLD_AC_OVERRIDE,
[wmi_pdev_param_antenna_gain] = WMI_PDEV_PARAM_ANTENNA_GAIN,
[wmi_pdev_param_block_interbss] = WMI_PDEV_PARAM_BLOCK_INTERBSS,
[wmi_pdev_param_set_disable_reset_cmdid] =
WMI_PDEV_PARAM_SET_DISABLE_RESET_CMDID,
[wmi_pdev_param_set_msdu_ttl_cmdid] = WMI_PDEV_PARAM_SET_MSDU_TTL_CMDID,
[wmi_pdev_param_txbf_sound_period_cmdid] =
WMI_PDEV_PARAM_TXBF_SOUND_PERIOD_CMDID,
[wmi_pdev_param_set_burst_mode_cmdid] =
WMI_PDEV_PARAM_SET_BURST_MODE_CMDID,
[wmi_pdev_param_en_stats] = WMI_PDEV_PARAM_EN_STATS,
[wmi_pdev_param_mesh_mcast_enable] = WMI_PDEV_PARAM_MESH_MCAST_ENABLE,
[wmi_pdev_param_set_promisc_mode_cmdid] =
WMI_PDEV_PARAM_SET_PROMISC_MODE_CMDID,
[wmi_pdev_param_set_ppdu_duration_cmdid] =
WMI_PDEV_PARAM_SET_PPDU_DURATION_CMDID,
[wmi_pdev_param_remove_mcast2ucast_buffer] =
WMI_PDEV_PARAM_REMOVE_MCAST2UCAST_BUFFER,
[wmi_pdev_param_set_mcast2ucast_buffer] =
WMI_PDEV_PARAM_SET_MCAST2UCAST_BUFFER,
[wmi_pdev_param_set_mcast2ucast_mode] =
WMI_PDEV_PARAM_SET_MCAST2UCAST_MODE,
[wmi_pdev_param_smart_antenna_default_antenna] =
WMI_PDEV_PARAM_SMART_ANTENNA_DEFAULT_ANTENNA,
[wmi_pdev_param_fast_channel_reset] =
WMI_PDEV_PARAM_FAST_CHANNEL_RESET,
[wmi_pdev_param_rx_decap_mode] = WMI_PDEV_PARAM_RX_DECAP_MODE,
[wmi_pdev_param_tx_ack_timeout] = WMI_PDEV_PARAM_ACK_TIMEOUT,
[wmi_pdev_param_cck_tx_enable] = WMI_PDEV_PARAM_CCK_TX_ENABLE,
[wmi_pdev_param_antenna_gain_half_db] =
WMI_PDEV_PARAM_ANTENNA_GAIN_HALF_DB,
[wmi_pdev_param_esp_indication_period] =
WMI_PDEV_PARAM_ESP_INDICATION_PERIOD,
[wmi_pdev_param_esp_ba_window] = WMI_PDEV_PARAM_ESP_BA_WINDOW,
[wmi_pdev_param_esp_airtime_fraction] =
WMI_PDEV_PARAM_ESP_AIRTIME_FRACTION,
[wmi_pdev_param_esp_ppdu_duration] = WMI_PDEV_PARAM_ESP_PPDU_DURATION,
[wmi_pdev_param_ru26_allowed] = WMI_PDEV_PARAM_UL_RU26_ALLOWED,
[wmi_pdev_param_use_nol] = WMI_PDEV_PARAM_USE_NOL,
/* Trigger interval for all trigger types. */
[wmi_pdev_param_ul_trig_int] = WMI_PDEV_PARAM_SET_UL_BSR_TRIG_INTERVAL,
[wmi_pdev_param_sub_channel_marking] =
WMI_PDEV_PARAM_SUB_CHANNEL_MARKING,
[wmi_pdev_param_ul_ppdu_duration] = WMI_PDEV_PARAM_SET_UL_PPDU_DURATION,
[wmi_pdev_param_equal_ru_allocation_enable] =
WMI_PDEV_PARAM_EQUAL_RU_ALLOCATION_ENABLE,
[wmi_pdev_param_per_peer_prd_cfr_enable] =
WMI_PDEV_PARAM_PER_PEER_PERIODIC_CFR_ENABLE,
[wmi_pdev_param_set_mgmt_ttl] = WMI_PDEV_PARAM_SET_MGMT_TTL,
[wmi_pdev_param_set_prb_rsp_ttl] =
WMI_PDEV_PARAM_SET_PROBE_RESP_TTL,
[wmi_pdev_param_set_mu_ppdu_duration] =
WMI_PDEV_PARAM_SET_MU_PPDU_DURATION,
[wmi_pdev_param_set_tbtt_ctrl] =
WMI_PDEV_PARAM_SET_TBTT_CTRL,
};
/**
* Populate vdev_param_value_tlv array whose index is host param
* and value is target param
*/
static const uint32_t vdev_param_tlv[] = {
[wmi_vdev_param_rts_threshold] = WMI_VDEV_PARAM_RTS_THRESHOLD,
[wmi_vdev_param_fragmentation_threshold] =
WMI_VDEV_PARAM_FRAGMENTATION_THRESHOLD,
[wmi_vdev_param_beacon_interval] = WMI_VDEV_PARAM_BEACON_INTERVAL,
[wmi_vdev_param_listen_interval] = WMI_VDEV_PARAM_LISTEN_INTERVAL,
[wmi_vdev_param_multicast_rate] = WMI_VDEV_PARAM_MULTICAST_RATE,
[wmi_vdev_param_mgmt_tx_rate] = WMI_VDEV_PARAM_MGMT_TX_RATE,
[wmi_vdev_param_slot_time] = WMI_VDEV_PARAM_SLOT_TIME,
[wmi_vdev_param_preamble] = WMI_VDEV_PARAM_PREAMBLE,
[wmi_vdev_param_swba_time] = WMI_VDEV_PARAM_SWBA_TIME,
[wmi_vdev_stats_update_period] = WMI_VDEV_STATS_UPDATE_PERIOD,
[wmi_vdev_pwrsave_ageout_time] = WMI_VDEV_PWRSAVE_AGEOUT_TIME,
[wmi_vdev_host_swba_interval] = WMI_VDEV_HOST_SWBA_INTERVAL,
[wmi_vdev_param_dtim_period] = WMI_VDEV_PARAM_DTIM_PERIOD,
[wmi_vdev_oc_scheduler_air_time_limit] =
WMI_VDEV_OC_SCHEDULER_AIR_TIME_LIMIT,
[wmi_vdev_param_wds] = WMI_VDEV_PARAM_WDS,
[wmi_vdev_param_atim_window] = WMI_VDEV_PARAM_ATIM_WINDOW,
[wmi_vdev_param_bmiss_count_max] = WMI_VDEV_PARAM_BMISS_COUNT_MAX,
[wmi_vdev_param_bmiss_first_bcnt] = WMI_VDEV_PARAM_BMISS_FIRST_BCNT,
[wmi_vdev_param_bmiss_final_bcnt] = WMI_VDEV_PARAM_BMISS_FINAL_BCNT,
[wmi_vdev_param_feature_wmm] = WMI_VDEV_PARAM_FEATURE_WMM,
[wmi_vdev_param_chwidth] = WMI_VDEV_PARAM_CHWIDTH,
[wmi_vdev_param_chextoffset] = WMI_VDEV_PARAM_CHEXTOFFSET,
[wmi_vdev_param_disable_htprotection] =
WMI_VDEV_PARAM_DISABLE_HTPROTECTION,
[wmi_vdev_param_sta_quickkickout] = WMI_VDEV_PARAM_STA_QUICKKICKOUT,
[wmi_vdev_param_mgmt_rate] = WMI_VDEV_PARAM_MGMT_RATE,
[wmi_vdev_param_protection_mode] = WMI_VDEV_PARAM_PROTECTION_MODE,
[wmi_vdev_param_fixed_rate] = WMI_VDEV_PARAM_FIXED_RATE,
[wmi_vdev_param_sgi] = WMI_VDEV_PARAM_SGI,
[wmi_vdev_param_ldpc] = WMI_VDEV_PARAM_LDPC,
[wmi_vdev_param_tx_stbc] = WMI_VDEV_PARAM_TX_STBC,
[wmi_vdev_param_rx_stbc] = WMI_VDEV_PARAM_RX_STBC,
[wmi_vdev_param_intra_bss_fwd] = WMI_VDEV_PARAM_INTRA_BSS_FWD,
[wmi_vdev_param_def_keyid] = WMI_VDEV_PARAM_DEF_KEYID,
[wmi_vdev_param_nss] = WMI_VDEV_PARAM_NSS,
[wmi_vdev_param_bcast_data_rate] = WMI_VDEV_PARAM_BCAST_DATA_RATE,
[wmi_vdev_param_mcast_data_rate] = WMI_VDEV_PARAM_MCAST_DATA_RATE,
[wmi_vdev_param_mcast_indicate] = WMI_VDEV_PARAM_MCAST_INDICATE,
[wmi_vdev_param_dhcp_indicate] = WMI_VDEV_PARAM_DHCP_INDICATE,
[wmi_vdev_param_unknown_dest_indicate] =
WMI_VDEV_PARAM_UNKNOWN_DEST_INDICATE,
[wmi_vdev_param_ap_keepalive_min_idle_inactive_time_secs] =
WMI_VDEV_PARAM_AP_KEEPALIVE_MIN_IDLE_INACTIVE_TIME_SECS,
[wmi_vdev_param_ap_keepalive_max_idle_inactive_time_secs] =
WMI_VDEV_PARAM_AP_KEEPALIVE_MAX_IDLE_INACTIVE_TIME_SECS,
[wmi_vdev_param_ap_keepalive_max_unresponsive_time_secs] =
WMI_VDEV_PARAM_AP_KEEPALIVE_MAX_UNRESPONSIVE_TIME_SECS,
[wmi_vdev_param_ap_enable_nawds] = WMI_VDEV_PARAM_AP_ENABLE_NAWDS,
[wmi_vdev_param_enable_rtscts] = WMI_VDEV_PARAM_ENABLE_RTSCTS,
[wmi_vdev_param_txbf] = WMI_VDEV_PARAM_TXBF,
[wmi_vdev_param_packet_powersave] = WMI_VDEV_PARAM_PACKET_POWERSAVE,
[wmi_vdev_param_drop_unencry] = WMI_VDEV_PARAM_DROP_UNENCRY,
[wmi_vdev_param_tx_encap_type] = WMI_VDEV_PARAM_TX_ENCAP_TYPE,
[wmi_vdev_param_ap_detect_out_of_sync_sleeping_sta_time_secs] =
WMI_VDEV_PARAM_AP_DETECT_OUT_OF_SYNC_SLEEPING_STA_TIME_SECS,
[wmi_vdev_param_early_rx_adjust_enable] =
WMI_VDEV_PARAM_EARLY_RX_ADJUST_ENABLE,
[wmi_vdev_param_early_rx_tgt_bmiss_num] =
WMI_VDEV_PARAM_EARLY_RX_TGT_BMISS_NUM,
[wmi_vdev_param_early_rx_bmiss_sample_cycle] =
WMI_VDEV_PARAM_EARLY_RX_BMISS_SAMPLE_CYCLE,
[wmi_vdev_param_early_rx_slop_step] = WMI_VDEV_PARAM_EARLY_RX_SLOP_STEP,
[wmi_vdev_param_early_rx_init_slop] = WMI_VDEV_PARAM_EARLY_RX_INIT_SLOP,
[wmi_vdev_param_early_rx_adjust_pause] =
WMI_VDEV_PARAM_EARLY_RX_ADJUST_PAUSE,
[wmi_vdev_param_tx_pwrlimit] = WMI_VDEV_PARAM_TX_PWRLIMIT,
[wmi_vdev_param_snr_num_for_cal] = WMI_VDEV_PARAM_SNR_NUM_FOR_CAL,
[wmi_vdev_param_roam_fw_offload] = WMI_VDEV_PARAM_ROAM_FW_OFFLOAD,
[wmi_vdev_param_enable_rmc] = WMI_VDEV_PARAM_ENABLE_RMC,
[wmi_vdev_param_ibss_max_bcn_lost_ms] =
WMI_VDEV_PARAM_IBSS_MAX_BCN_LOST_MS,
[wmi_vdev_param_max_rate] = WMI_VDEV_PARAM_MAX_RATE,
[wmi_vdev_param_early_rx_drift_sample] =
WMI_VDEV_PARAM_EARLY_RX_DRIFT_SAMPLE,
[wmi_vdev_param_set_ibss_tx_fail_cnt_thr] =
WMI_VDEV_PARAM_SET_IBSS_TX_FAIL_CNT_THR,
[wmi_vdev_param_ebt_resync_timeout] =
WMI_VDEV_PARAM_EBT_RESYNC_TIMEOUT,
[wmi_vdev_param_aggr_trig_event_enable] =
WMI_VDEV_PARAM_AGGR_TRIG_EVENT_ENABLE,
[wmi_vdev_param_is_ibss_power_save_allowed] =
WMI_VDEV_PARAM_IS_IBSS_POWER_SAVE_ALLOWED,
[wmi_vdev_param_is_power_collapse_allowed] =
WMI_VDEV_PARAM_IS_POWER_COLLAPSE_ALLOWED,
[wmi_vdev_param_is_awake_on_txrx_enabled] =
WMI_VDEV_PARAM_IS_AWAKE_ON_TXRX_ENABLED,
[wmi_vdev_param_inactivity_cnt] = WMI_VDEV_PARAM_INACTIVITY_CNT,
[wmi_vdev_param_txsp_end_inactivity_time_ms] =
WMI_VDEV_PARAM_TXSP_END_INACTIVITY_TIME_MS,
[wmi_vdev_param_dtim_policy] = WMI_VDEV_PARAM_DTIM_POLICY,
[wmi_vdev_param_ibss_ps_warmup_time_secs] =
WMI_VDEV_PARAM_IBSS_PS_WARMUP_TIME_SECS,
[wmi_vdev_param_ibss_ps_1rx_chain_in_atim_window_enable] =
WMI_VDEV_PARAM_IBSS_PS_1RX_CHAIN_IN_ATIM_WINDOW_ENABLE,
[wmi_vdev_param_rx_leak_window] = WMI_VDEV_PARAM_RX_LEAK_WINDOW,
[wmi_vdev_param_stats_avg_factor] =
WMI_VDEV_PARAM_STATS_AVG_FACTOR,
[wmi_vdev_param_disconnect_th] = WMI_VDEV_PARAM_DISCONNECT_TH,
[wmi_vdev_param_rtscts_rate] = WMI_VDEV_PARAM_RTSCTS_RATE,
[wmi_vdev_param_mcc_rtscts_protection_enable] =
WMI_VDEV_PARAM_MCC_RTSCTS_PROTECTION_ENABLE,
[wmi_vdev_param_mcc_broadcast_probe_enable] =
WMI_VDEV_PARAM_MCC_BROADCAST_PROBE_ENABLE,
[wmi_vdev_param_mgmt_tx_power] = WMI_VDEV_PARAM_MGMT_TX_POWER,
[wmi_vdev_param_beacon_rate] = WMI_VDEV_PARAM_BEACON_RATE,
[wmi_vdev_param_rx_decap_type] = WMI_VDEV_PARAM_RX_DECAP_TYPE,
[wmi_vdev_param_he_dcm_enable] = WMI_VDEV_PARAM_HE_DCM,
[wmi_vdev_param_he_range_ext_enable] = WMI_VDEV_PARAM_HE_RANGE_EXT,
[wmi_vdev_param_he_bss_color] = WMI_VDEV_PARAM_BSS_COLOR,
[wmi_vdev_param_set_hemu_mode] = WMI_VDEV_PARAM_SET_HEMU_MODE,
[wmi_vdev_param_set_he_sounding_mode] =
WMI_VDEV_PARAM_SET_HE_SOUNDING_MODE,
[wmi_vdev_param_set_heop] = WMI_VDEV_PARAM_HEOPS_0_31,
[wmi_vdev_param_sensor_ap] = WMI_VDEV_PARAM_SENSOR_AP,
[wmi_vdev_param_dtim_enable_cts] = WMI_VDEV_PARAM_DTIM_ENABLE_CTS,
[wmi_vdev_param_atf_ssid_sched_policy] =
WMI_VDEV_PARAM_ATF_SSID_SCHED_POLICY,
[wmi_vdev_param_disable_dyn_bw_rts] = WMI_VDEV_PARAM_DISABLE_DYN_BW_RTS,
[wmi_vdev_param_mcast2ucast_set] = WMI_VDEV_PARAM_MCAST2UCAST_SET,
[wmi_vdev_param_rc_num_retries] = WMI_VDEV_PARAM_RC_NUM_RETRIES,
[wmi_vdev_param_cabq_maxdur] = WMI_VDEV_PARAM_CABQ_MAXDUR,
[wmi_vdev_param_mfptest_set] = WMI_VDEV_PARAM_MFPTEST_SET,
[wmi_vdev_param_rts_fixed_rate] = WMI_VDEV_PARAM_RTS_FIXED_RATE,
[wmi_vdev_param_vht_sgimask] = WMI_VDEV_PARAM_VHT_SGIMASK,
[wmi_vdev_param_vht80_ratemask] = WMI_VDEV_PARAM_VHT80_RATEMASK,
[wmi_vdev_param_proxy_sta] = WMI_VDEV_PARAM_PROXY_STA,
[wmi_vdev_param_bw_nss_ratemask] = WMI_VDEV_PARAM_BW_NSS_RATEMASK,
[wmi_vdev_param_set_he_ltf] = WMI_VDEV_PARAM_HE_LTF,
[wmi_vdev_param_disable_cabq] = WMI_VDEV_PARAM_DISABLE_CABQ,
[wmi_vdev_param_rate_dropdown_bmap] = WMI_VDEV_PARAM_RATE_DROPDOWN_BMAP,
[wmi_vdev_param_set_ba_mode] = WMI_VDEV_PARAM_BA_MODE,
[wmi_vdev_param_capabilities] = WMI_VDEV_PARAM_CAPABILITIES,
[wmi_vdev_param_autorate_misc_cfg] = WMI_VDEV_PARAM_AUTORATE_MISC_CFG,
[wmi_vdev_param_ul_shortgi] = WMI_VDEV_PARAM_UL_GI,
[wmi_vdev_param_ul_he_ltf] = WMI_VDEV_PARAM_UL_HE_LTF,
[wmi_vdev_param_ul_nss] = WMI_VDEV_PARAM_UL_NSS,
[wmi_vdev_param_ul_ppdu_bw] = WMI_VDEV_PARAM_UL_PPDU_BW,
[wmi_vdev_param_ul_ldpc] = WMI_VDEV_PARAM_UL_LDPC,
[wmi_vdev_param_ul_stbc] = WMI_VDEV_PARAM_UL_STBC,
[wmi_vdev_param_ul_fixed_rate] = WMI_VDEV_PARAM_UL_FIXED_RATE,
[wmi_vdev_param_rawmode_open_war] = WMI_VDEV_PARAM_RAW_IS_ENCRYPTED,
[wmi_vdev_param_max_mtu_size] = WMI_VDEV_PARAM_MAX_MTU_SIZE,
};
#endif
/**
* convert_host_pdev_id_to_target_pdev_id() - Convert pdev_id from
* host to target defines.
* @param pdev_id: host pdev_id to be converted.
* Return: target pdev_id after conversion.
*/
static uint32_t convert_host_pdev_id_to_target_pdev_id(uint32_t pdev_id)
{
switch (pdev_id) {
case WMI_HOST_PDEV_ID_SOC:
return WMI_PDEV_ID_SOC;
case WMI_HOST_PDEV_ID_0:
return WMI_PDEV_ID_1ST;
case WMI_HOST_PDEV_ID_1:
return WMI_PDEV_ID_2ND;
case WMI_HOST_PDEV_ID_2:
return WMI_PDEV_ID_3RD;
}
QDF_ASSERT(0);
return WMI_PDEV_ID_SOC;
}
/**
* convert_target_pdev_id_to_host_pdev_id() - Convert pdev_id from
* target to host defines.
* @param pdev_id: target pdev_id to be converted.
* Return: host pdev_id after conversion.
*/
static uint32_t convert_target_pdev_id_to_host_pdev_id(uint32_t pdev_id)
{
switch (pdev_id) {
case WMI_PDEV_ID_SOC:
return WMI_HOST_PDEV_ID_SOC;
case WMI_PDEV_ID_1ST:
return WMI_HOST_PDEV_ID_0;
case WMI_PDEV_ID_2ND:
return WMI_HOST_PDEV_ID_1;
case WMI_PDEV_ID_3RD:
return WMI_HOST_PDEV_ID_2;
}
WMI_LOGE("Invalid pdev_id");
return WMI_HOST_PDEV_ID_INVALID;
}
/**
* wmi_tlv_pdev_id_conversion_enable() - Enable pdev_id conversion
*
* Return None.
*/
static void wmi_tlv_pdev_id_conversion_enable(wmi_unified_t wmi_handle)
{
wmi_handle->ops->convert_pdev_id_host_to_target =
convert_host_pdev_id_to_target_pdev_id;
wmi_handle->ops->convert_pdev_id_target_to_host =
convert_target_pdev_id_to_host_pdev_id;
}
/* copy_vdev_create_pdev_id() - copy pdev from host params to target command
* buffer.
* @wmi_handle: pointer to wmi_handle
* @cmd: pointer target vdev create command buffer
* @param: pointer host params for vdev create
*
* Return: None
*/
#ifdef CONFIG_MCL
static inline void copy_vdev_create_pdev_id(
struct wmi_unified *wmi_handle,
wmi_vdev_create_cmd_fixed_param * cmd,
struct vdev_create_params *param)
{
cmd->pdev_id = WMI_PDEV_ID_SOC;
}
#else
static inline void copy_vdev_create_pdev_id(
struct wmi_unified *wmi_handle,
wmi_vdev_create_cmd_fixed_param * cmd,
struct vdev_create_params *param)
{
cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target(
param->pdev_id);
}
#endif
void wmi_mtrace(uint32_t message_id, uint16_t vdev_id, uint32_t data)
{
uint16_t mtrace_message_id;
mtrace_message_id = QDF_WMI_MTRACE_CMD_ID(message_id) |
(QDF_WMI_MTRACE_GRP_ID(message_id) <<
QDF_WMI_MTRACE_CMD_NUM_BITS);
qdf_mtrace(QDF_MODULE_ID_WMI, QDF_MODULE_ID_TARGET,
mtrace_message_id, vdev_id, data);
}
qdf_export_symbol(wmi_mtrace);
#ifdef WLAN_FEATURE_WMI_SEND_RECV_QMI
static QDF_STATUS wmi_unified_cmd_send_pm_chk(struct wmi_unified *wmi_handle,
wmi_buf_t buf,
uint32_t buflen, uint32_t cmd_id)
{
if (wmi_is_target_suspended(wmi_handle)) {
if (QDF_IS_STATUS_SUCCESS(
wmi_unified_cmd_send_over_qmi(wmi_handle, buf,
buflen, cmd_id)))
return QDF_STATUS_SUCCESS;
}
qdf_atomic_set(&wmi_handle->num_stats_over_qmi, 0);
return wmi_unified_cmd_send(wmi_handle, buf, buflen, cmd_id);
}
#else
static inline
QDF_STATUS wmi_unified_cmd_send_pm_chk(struct wmi_unified *wmi_handle,
wmi_buf_t buf,
uint32_t buflen, uint32_t cmd_id)
{
return wmi_unified_cmd_send(wmi_handle, buf, buflen, cmd_id);
}
#endif
/**
* send_vdev_create_cmd_tlv() - send VDEV create command to fw
* @wmi_handle: wmi handle
* @param: pointer to hold vdev create parameter
* @macaddr: vdev mac address
*
* Return: QDF_STATUS_SUCCESS for success or error code
*/
static QDF_STATUS send_vdev_create_cmd_tlv(wmi_unified_t wmi_handle,
uint8_t macaddr[QDF_MAC_ADDR_SIZE],
struct vdev_create_params *param)
{
wmi_vdev_create_cmd_fixed_param *cmd;
wmi_buf_t buf;
int32_t len = sizeof(*cmd);
QDF_STATUS ret;
int num_bands = 2;
uint8_t *buf_ptr;
wmi_vdev_txrx_streams *txrx_streams;
len += (num_bands * sizeof(*txrx_streams) + WMI_TLV_HDR_SIZE);
buf = wmi_buf_alloc(wmi_handle, len);
if (!buf)
return QDF_STATUS_E_NOMEM;
cmd = (wmi_vdev_create_cmd_fixed_param *) wmi_buf_data(buf);
WMITLV_SET_HDR(&cmd->tlv_header,
WMITLV_TAG_STRUC_wmi_vdev_create_cmd_fixed_param,
WMITLV_GET_STRUCT_TLVLEN
(wmi_vdev_create_cmd_fixed_param));
#ifdef CMN_VDEV_MGR_TGT_IF_ENABLE
cmd->vdev_id = param->vdev_id;
#else
cmd->vdev_id = param->if_id;
#endif
cmd->vdev_type = param->type;
cmd->vdev_subtype = param->subtype;
cmd->flags = param->mbssid_flags;
cmd->vdevid_trans = param->vdevid_trans;
cmd->num_cfg_txrx_streams = num_bands;
copy_vdev_create_pdev_id(wmi_handle, cmd, param);
WMI_CHAR_ARRAY_TO_MAC_ADDR(macaddr, &cmd->vdev_macaddr);
WMI_LOGD("%s: ID = %d[pdev:%d] VAP Addr = %02x:%02x:%02x:%02x:%02x:%02x",
#ifdef CMN_VDEV_MGR_TGT_IF_ENABLE
__func__, param->vdev_id, cmd->pdev_id,
#else
__func__, param->if_id, cmd->pdev_id,
#endif
macaddr[0], macaddr[1], macaddr[2],
macaddr[3], macaddr[4], macaddr[5]);
buf_ptr = (uint8_t *)cmd + sizeof(*cmd);
WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
(num_bands * sizeof(wmi_vdev_txrx_streams)));
buf_ptr += WMI_TLV_HDR_SIZE;
WMI_LOGD("%s: type %d, subtype %d, nss_2g %d, nss_5g %d", __func__,
param->type, param->subtype,
param->nss_2g, param->nss_5g);
txrx_streams = (wmi_vdev_txrx_streams *)buf_ptr;
txrx_streams->band = WMI_TPC_CHAINMASK_CONFIG_BAND_2G;
txrx_streams->supported_tx_streams = param->nss_2g;
txrx_streams->supported_rx_streams = param->nss_2g;
WMITLV_SET_HDR(&txrx_streams->tlv_header,
WMITLV_TAG_STRUC_wmi_vdev_txrx_streams,
WMITLV_GET_STRUCT_TLVLEN(wmi_vdev_txrx_streams));
txrx_streams++;
txrx_streams->band = WMI_TPC_CHAINMASK_CONFIG_BAND_5G;
txrx_streams->supported_tx_streams = param->nss_5g;
txrx_streams->supported_rx_streams = param->nss_5g;
WMITLV_SET_HDR(&txrx_streams->tlv_header,
WMITLV_TAG_STRUC_wmi_vdev_txrx_streams,
WMITLV_GET_STRUCT_TLVLEN(wmi_vdev_txrx_streams));
wmi_mtrace(WMI_VDEV_CREATE_CMDID, cmd->vdev_id, 0);
ret = wmi_unified_cmd_send(wmi_handle, buf, len, WMI_VDEV_CREATE_CMDID);
if (QDF_IS_STATUS_ERROR(ret)) {
WMI_LOGE("Failed to send WMI_VDEV_CREATE_CMDID");
wmi_buf_free(buf);
}
return ret;
}
/**
* send_vdev_delete_cmd_tlv() - send VDEV delete command to fw
* @wmi_handle: wmi handle
* @if_id: vdev id
*
* Return: QDF_STATUS_SUCCESS for success or error code
*/
static QDF_STATUS send_vdev_delete_cmd_tlv(wmi_unified_t wmi_handle,
uint8_t if_id)
{
wmi_vdev_delete_cmd_fixed_param *cmd;
wmi_buf_t buf;
QDF_STATUS ret;
buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd));
if (!buf)
return QDF_STATUS_E_NOMEM;
cmd = (wmi_vdev_delete_cmd_fixed_param *) wmi_buf_data(buf);
WMITLV_SET_HDR(&cmd->tlv_header,
WMITLV_TAG_STRUC_wmi_vdev_delete_cmd_fixed_param,
WMITLV_GET_STRUCT_TLVLEN
(wmi_vdev_delete_cmd_fixed_param));
cmd->vdev_id = if_id;
wmi_mtrace(WMI_VDEV_DELETE_CMDID, cmd->vdev_id, 0);
ret = wmi_unified_cmd_send(wmi_handle, buf,
sizeof(wmi_vdev_delete_cmd_fixed_param),
WMI_VDEV_DELETE_CMDID);
if (QDF_IS_STATUS_ERROR(ret)) {
WMI_LOGE("Failed to send WMI_VDEV_DELETE_CMDID");
wmi_buf_free(buf);
}
WMI_LOGD("%s:vdev id = %d", __func__, if_id);
return ret;
}
/**
* send_vdev_nss_chain_params_cmd_tlv() - send VDEV nss chain params to fw
* @wmi_handle: wmi handle
* @vdev_id: vdev id
* @nss_chains_user_cfg: user configured nss chain params
*
* Return: QDF_STATUS_SUCCESS for success or error code
*/
static QDF_STATUS
send_vdev_nss_chain_params_cmd_tlv(wmi_unified_t wmi_handle,
uint8_t vdev_id,
struct vdev_nss_chains *user_cfg)
{
wmi_vdev_chainmask_config_cmd_fixed_param *cmd;
wmi_buf_t buf;
QDF_STATUS ret;
buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd));
if (!buf)
return QDF_STATUS_E_NOMEM;
cmd = (wmi_vdev_chainmask_config_cmd_fixed_param *)wmi_buf_data(buf);
WMITLV_SET_HDR(&cmd->tlv_header,
WMITLV_TAG_STRUC_wmi_vdev_chainmask_config_cmd_fixed_param,
WMITLV_GET_STRUCT_TLVLEN
(wmi_vdev_chainmask_config_cmd_fixed_param));
cmd->vdev_id = vdev_id;
cmd->disable_rx_mrc_2g = user_cfg->disable_rx_mrc[NSS_CHAINS_BAND_2GHZ];
cmd->disable_tx_mrc_2g = user_cfg->disable_tx_mrc[NSS_CHAINS_BAND_2GHZ];
cmd->disable_rx_mrc_5g = user_cfg->disable_rx_mrc[NSS_CHAINS_BAND_5GHZ];
cmd->disable_tx_mrc_5g = user_cfg->disable_tx_mrc[NSS_CHAINS_BAND_5GHZ];
cmd->num_rx_chains_2g = user_cfg->num_rx_chains[NSS_CHAINS_BAND_2GHZ];
cmd->num_tx_chains_2g = user_cfg->num_tx_chains[NSS_CHAINS_BAND_2GHZ];
cmd->num_rx_chains_5g = user_cfg->num_rx_chains[NSS_CHAINS_BAND_5GHZ];
cmd->num_tx_chains_5g = user_cfg->num_tx_chains[NSS_CHAINS_BAND_5GHZ];
cmd->rx_nss_2g = user_cfg->rx_nss[NSS_CHAINS_BAND_2GHZ];
cmd->tx_nss_2g = user_cfg->tx_nss[NSS_CHAINS_BAND_2GHZ];
cmd->rx_nss_5g = user_cfg->rx_nss[NSS_CHAINS_BAND_5GHZ];
cmd->tx_nss_5g = user_cfg->tx_nss[NSS_CHAINS_BAND_5GHZ];
cmd->num_tx_chains_a = user_cfg->num_tx_chains_11a;
cmd->num_tx_chains_b = user_cfg->num_tx_chains_11b;
cmd->num_tx_chains_g = user_cfg->num_tx_chains_11g;
wmi_mtrace(WMI_VDEV_CHAINMASK_CONFIG_CMDID, cmd->vdev_id, 0);
ret = wmi_unified_cmd_send(wmi_handle, buf,
sizeof(wmi_vdev_chainmask_config_cmd_fixed_param),
WMI_VDEV_CHAINMASK_CONFIG_CMDID);
if (QDF_IS_STATUS_ERROR(ret)) {
WMI_LOGE("Failed to send WMI_VDEV_CHAINMASK_CONFIG_CMDID");
wmi_buf_free(buf);
}
WMI_LOGD("%s: vdev_id %d", __func__, vdev_id);
return ret;
}
/**
* send_vdev_stop_cmd_tlv() - send vdev stop command to fw
* @wmi: wmi handle
* @vdev_id: vdev id
*
* Return: QDF_STATUS_SUCCESS for success or erro code
*/
static QDF_STATUS send_vdev_stop_cmd_tlv(wmi_unified_t wmi,
uint8_t vdev_id)
{
wmi_vdev_stop_cmd_fixed_param *cmd;
wmi_buf_t buf;
int32_t len = sizeof(*cmd);
buf = wmi_buf_alloc(wmi, len);
if (!buf)
return QDF_STATUS_E_NOMEM;
cmd = (wmi_vdev_stop_cmd_fixed_param *) wmi_buf_data(buf);
WMITLV_SET_HDR(&cmd->tlv_header,
WMITLV_TAG_STRUC_wmi_vdev_stop_cmd_fixed_param,
WMITLV_GET_STRUCT_TLVLEN(wmi_vdev_stop_cmd_fixed_param));
cmd->vdev_id = vdev_id;
wmi_mtrace(WMI_VDEV_STOP_CMDID, cmd->vdev_id, 0);
if (wmi_unified_cmd_send(wmi, buf, len, WMI_VDEV_STOP_CMDID)) {
WMI_LOGP("%s: Failed to send vdev stop command", __func__);
wmi_buf_free(buf);
return QDF_STATUS_E_FAILURE;
}
WMI_LOGD("%s:vdev id = %d", __func__, vdev_id);
return 0;
}
/**
* send_vdev_down_cmd_tlv() - send vdev down command to fw
* @wmi: wmi handle
* @vdev_id: vdev id
*
* Return: QDF_STATUS_SUCCESS for success or error code
*/
static QDF_STATUS send_vdev_down_cmd_tlv(wmi_unified_t wmi, uint8_t vdev_id)
{
wmi_vdev_down_cmd_fixed_param *cmd;
wmi_buf_t buf;
int32_t len = sizeof(*cmd);
buf = wmi_buf_alloc(wmi, len);
if (!buf)
return QDF_STATUS_E_NOMEM;
cmd = (wmi_vdev_down_cmd_fixed_param *) wmi_buf_data(buf);
WMITLV_SET_HDR(&cmd->tlv_header,
WMITLV_TAG_STRUC_wmi_vdev_down_cmd_fixed_param,
WMITLV_GET_STRUCT_TLVLEN(wmi_vdev_down_cmd_fixed_param));
cmd->vdev_id = vdev_id;
wmi_mtrace(WMI_VDEV_DOWN_CMDID, cmd->vdev_id, 0);
if (wmi_unified_cmd_send(wmi, buf, len, WMI_VDEV_DOWN_CMDID)) {
WMI_LOGP("%s: Failed to send vdev down", __func__);
wmi_buf_free(buf);
return QDF_STATUS_E_FAILURE;
}
WMI_LOGD("%s: vdev_id %d", __func__, vdev_id);
return 0;
}
static inline void copy_channel_info(
wmi_vdev_start_request_cmd_fixed_param * cmd,
wmi_channel *chan,
struct vdev_start_params *req)
{
chan->mhz = req->channel.mhz;
WMI_SET_CHANNEL_MODE(chan, req->channel.phy_mode);
chan->band_center_freq1 = req->channel.cfreq1;
chan->band_center_freq2 = req->channel.cfreq2;
if (req->channel.half_rate)
WMI_SET_CHANNEL_FLAG(chan, WMI_CHAN_FLAG_HALF_RATE);
else if (req->channel.quarter_rate)
WMI_SET_CHANNEL_FLAG(chan, WMI_CHAN_FLAG_QUARTER_RATE);
if (req->channel.dfs_set) {
WMI_SET_CHANNEL_FLAG(chan, WMI_CHAN_FLAG_DFS);
cmd->disable_hw_ack = req->disable_hw_ack;
}
if (req->channel.dfs_set_cfreq2)
WMI_SET_CHANNEL_FLAG(chan, WMI_CHAN_FLAG_DFS_CFREQ2);
/* According to firmware both reg power and max tx power
* on set channel power is used and set it to max reg
* power from regulatory.
*/
WMI_SET_CHANNEL_MIN_POWER(chan, req->channel.minpower);
WMI_SET_CHANNEL_MAX_POWER(chan, req->channel.maxpower);
WMI_SET_CHANNEL_REG_POWER(chan, req->channel.maxregpower);
WMI_SET_CHANNEL_ANTENNA_MAX(chan, req->channel.antennamax);
WMI_SET_CHANNEL_REG_CLASSID(chan, req->channel.reg_class_id);
WMI_SET_CHANNEL_MAX_TX_POWER(chan, req->channel.maxregpower);
}
/**
* send_vdev_start_cmd_tlv() - send vdev start request to fw
* @wmi_handle: wmi handle
* @req: vdev start params
*
* Return: QDF status
*/
static QDF_STATUS send_vdev_start_cmd_tlv(wmi_unified_t wmi_handle,
struct vdev_start_params *req)
{
wmi_vdev_start_request_cmd_fixed_param *cmd;
wmi_buf_t buf;
wmi_channel *chan;
int32_t len, ret;
uint8_t *buf_ptr;
len = sizeof(*cmd) + sizeof(wmi_channel) + WMI_TLV_HDR_SIZE;
buf = wmi_buf_alloc(wmi_handle, len);
if (!buf)
return QDF_STATUS_E_NOMEM;
buf_ptr = (uint8_t *) wmi_buf_data(buf);
cmd = (wmi_vdev_start_request_cmd_fixed_param *) buf_ptr;
chan = (wmi_channel *) (buf_ptr + sizeof(*cmd));
WMITLV_SET_HDR(&cmd->tlv_header,
WMITLV_TAG_STRUC_wmi_vdev_start_request_cmd_fixed_param,
WMITLV_GET_STRUCT_TLVLEN
(wmi_vdev_start_request_cmd_fixed_param));
WMITLV_SET_HDR(&chan->tlv_header, WMITLV_TAG_STRUC_wmi_channel,
WMITLV_GET_STRUCT_TLVLEN(wmi_channel));
cmd->vdev_id = req->vdev_id;
/* Fill channel info */
copy_channel_info(cmd, chan, req);
#ifdef CMN_VDEV_MGR_TGT_IF_ENABLE
cmd->beacon_interval = req->beacon_interval;
#else
cmd->beacon_interval = req->beacon_intval;
#endif
cmd->dtim_period = req->dtim_period;
cmd->bcn_tx_rate = req->bcn_tx_rate_code;
if (req->bcn_tx_rate_code)
cmd->flags |= WMI_UNIFIED_VDEV_START_BCN_TX_RATE_PRESENT;
if (!req->is_restart) {
#ifdef CMN_VDEV_MGR_TGT_IF_ENABLE
cmd->beacon_interval = req->beacon_interval;
#else
cmd->beacon_interval = req->beacon_intval;
#endif
cmd->dtim_period = req->dtim_period;
/* Copy the SSID */
if (req->ssid.length) {
if (req->ssid.length < sizeof(cmd->ssid.ssid))
cmd->ssid.ssid_len = req->ssid.length;
else
cmd->ssid.ssid_len = sizeof(cmd->ssid.ssid);
qdf_mem_copy(cmd->ssid.ssid, req->ssid.mac_ssid,
cmd->ssid.ssid_len);
}
if (req->pmf_enabled)
cmd->flags |= WMI_UNIFIED_VDEV_START_PMF_ENABLED;
}
if (req->hidden_ssid)
cmd->flags |= WMI_UNIFIED_VDEV_START_HIDDEN_SSID;
cmd->flags |= WMI_UNIFIED_VDEV_START_LDPC_RX_ENABLED;
cmd->num_noa_descriptors = req->num_noa_descriptors;
cmd->preferred_rx_streams = req->preferred_rx_streams;
cmd->preferred_tx_streams = req->preferred_tx_streams;
cmd->cac_duration_ms = req->cac_duration_ms;
cmd->regdomain = req->regdomain;
cmd->he_ops = req->he_ops;
buf_ptr = (uint8_t *) (((uintptr_t) cmd) + sizeof(*cmd) +
sizeof(wmi_channel));
WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
cmd->num_noa_descriptors *
sizeof(wmi_p2p_noa_descriptor));
wmi_info("%s: vdev_id %d freq %d chanmode %d ch_info: 0x%x is_dfs %d "
"beacon interval %d dtim %d center_chan %d center_freq2 %d "
"reg_info_1: 0x%x reg_info_2: 0x%x, req->max_txpow: 0x%x "
"Tx SS %d, Rx SS %d, ldpc_rx: %d, cac %d, regd %d, HE ops: %d"
"req->dis_hw_ack: %d ", __func__, req->vdev_id,
chan->mhz, req->channel.phy_mode, chan->info,
#ifdef CMN_VDEV_MGR_TGT_IF_ENABLE
req->channel.dfs_set, req->beacon_interval, cmd->dtim_period,
#else
req->channel.dfs_set, req->beacon_intval, cmd->dtim_period,
#endif
chan->band_center_freq1, chan->band_center_freq2,
chan->reg_info_1, chan->reg_info_2, req->channel.maxregpower,
req->preferred_tx_streams, req->preferred_rx_streams,
req->ldpc_rx_enabled, req->cac_duration_ms,
req->regdomain, req->he_ops,
req->disable_hw_ack);
if (req->is_restart) {
wmi_mtrace(WMI_VDEV_RESTART_REQUEST_CMDID, cmd->vdev_id, 0);
ret = wmi_unified_cmd_send(wmi_handle, buf, len,
WMI_VDEV_RESTART_REQUEST_CMDID);
} else {
wmi_mtrace(WMI_VDEV_START_REQUEST_CMDID, cmd->vdev_id, 0);
ret = wmi_unified_cmd_send(wmi_handle, buf, len,
WMI_VDEV_START_REQUEST_CMDID);
}
if (ret) {
WMI_LOGP("%s: Failed to send vdev start command", __func__);
wmi_buf_free(buf);
return QDF_STATUS_E_FAILURE;
}
return QDF_STATUS_SUCCESS;
}
/**
* send_hidden_ssid_vdev_restart_cmd_tlv() - restart vdev to set hidden ssid
* @wmi_handle: wmi handle
* @restart_params: vdev restart params
*
* Return: QDF_STATUS_SUCCESS for success or error code
*/
static QDF_STATUS send_hidden_ssid_vdev_restart_cmd_tlv(wmi_unified_t wmi_handle,
struct hidden_ssid_vdev_restart_params *restart_params)
{
wmi_vdev_start_request_cmd_fixed_param *cmd;
wmi_buf_t buf;
wmi_channel *chan;
int32_t len;
uint8_t *buf_ptr;
QDF_STATUS ret = 0;
len = sizeof(*cmd) + sizeof(wmi_channel) + WMI_TLV_HDR_SIZE;
buf = wmi_buf_alloc(wmi_handle, len);
if (!buf)
return QDF_STATUS_E_NOMEM;
buf_ptr = (uint8_t *) wmi_buf_data(buf);
cmd = (wmi_vdev_start_request_cmd_fixed_param *) buf_ptr;
chan = (wmi_channel *) (buf_ptr + sizeof(*cmd));
WMITLV_SET_HDR(&cmd->tlv_header,
WMITLV_TAG_STRUC_wmi_vdev_start_request_cmd_fixed_param,
WMITLV_GET_STRUCT_TLVLEN
(wmi_vdev_start_request_cmd_fixed_param));
WMITLV_SET_HDR(&chan->tlv_header,
WMITLV_TAG_STRUC_wmi_channel,
WMITLV_GET_STRUCT_TLVLEN(wmi_channel));
cmd->vdev_id = restart_params->vdev_id;
cmd->ssid.ssid_len = restart_params->ssid_len;
qdf_mem_copy(cmd->ssid.ssid,
restart_params->ssid,
cmd->ssid.ssid_len);
cmd->flags = restart_params->flags;
cmd->requestor_id = restart_params->requestor_id;
cmd->disable_hw_ack = restart_params->disable_hw_ack;
chan->mhz = restart_params->mhz;
chan->band_center_freq1 =
restart_params->band_center_freq1;
chan->band_center_freq2 =
restart_params->band_center_freq2;
chan->info = restart_params->info;
chan->reg_info_1 = restart_params->reg_info_1;
chan->reg_info_2 = restart_params->reg_info_2;
cmd->num_noa_descriptors = 0;
buf_ptr = (uint8_t *) (((uint8_t *) cmd) + sizeof(*cmd) +
sizeof(wmi_channel));
WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
cmd->num_noa_descriptors *
sizeof(wmi_p2p_noa_descriptor));
wmi_mtrace(WMI_VDEV_RESTART_REQUEST_CMDID, cmd->vdev_id, 0);
ret = wmi_unified_cmd_send(wmi_handle, buf, len,
WMI_VDEV_RESTART_REQUEST_CMDID);
if (QDF_IS_STATUS_ERROR(ret)) {
wmi_buf_free(buf);
return QDF_STATUS_E_FAILURE;
}
return QDF_STATUS_SUCCESS;
}
/**
* send_peer_flush_tids_cmd_tlv() - flush peer tids packets in fw
* @wmi: wmi handle
* @peer_addr: peer mac address
* @param: pointer to hold peer flush tid parameter
*
* Return: 0 for success or error code
*/
static QDF_STATUS send_peer_flush_tids_cmd_tlv(wmi_unified_t wmi,
uint8_t peer_addr[QDF_MAC_ADDR_SIZE],
struct peer_flush_params *param)
{
wmi_peer_flush_tids_cmd_fixed_param *cmd;
wmi_buf_t buf;
int32_t len = sizeof(*cmd);
buf = wmi_buf_alloc(wmi, len);
if (!buf)
return QDF_STATUS_E_NOMEM;
cmd = (wmi_peer_flush_tids_cmd_fixed_param *) wmi_buf_data(buf);
WMITLV_SET_HDR(&cmd->tlv_header,
WMITLV_TAG_STRUC_wmi_peer_flush_tids_cmd_fixed_param,
WMITLV_GET_STRUCT_TLVLEN
(wmi_peer_flush_tids_cmd_fixed_param));
WMI_CHAR_ARRAY_TO_MAC_ADDR(peer_addr, &cmd->peer_macaddr);
cmd->peer_tid_bitmap = param->peer_tid_bitmap;
cmd->vdev_id = param->vdev_id;
WMI_LOGD("%s: peer_addr %pM vdev_id %d and peer bitmap %d", __func__,
peer_addr, param->vdev_id,
param->peer_tid_bitmap);
wmi_mtrace(WMI_PEER_FLUSH_TIDS_CMDID, cmd->vdev_id, 0);
if (wmi_unified_cmd_send(wmi, buf, len, WMI_PEER_FLUSH_TIDS_CMDID)) {
WMI_LOGP("%s: Failed to send flush tid command", __func__);
wmi_buf_free(buf);
return QDF_STATUS_E_FAILURE;
}
return 0;
}
/**
* send_peer_delete_cmd_tlv() - send PEER delete command to fw
* @wmi: wmi handle
* @peer_addr: peer mac addr
* @vdev_id: vdev id
*
* Return: QDF_STATUS_SUCCESS for success or error code
*/
static QDF_STATUS send_peer_delete_cmd_tlv(wmi_unified_t wmi,
uint8_t peer_addr[QDF_MAC_ADDR_SIZE],
uint8_t vdev_id)
{
wmi_peer_delete_cmd_fixed_param *cmd;
wmi_buf_t buf;
int32_t len = sizeof(*cmd);
buf = wmi_buf_alloc(wmi, len);
if (!buf)
return QDF_STATUS_E_NOMEM;
cmd = (wmi_peer_delete_cmd_fixed_param *) wmi_buf_data(buf);
WMITLV_SET_HDR(&cmd->tlv_header,
WMITLV_TAG_STRUC_wmi_peer_delete_cmd_fixed_param,
WMITLV_GET_STRUCT_TLVLEN
(wmi_peer_delete_cmd_fixed_param));
WMI_CHAR_ARRAY_TO_MAC_ADDR(peer_addr, &cmd->peer_macaddr);
cmd->vdev_id = vdev_id;
WMI_LOGD("%s: peer_addr %pM vdev_id %d", __func__, peer_addr, vdev_id);
wmi_mtrace(WMI_PEER_DELETE_CMDID, cmd->vdev_id, 0);
if (wmi_unified_cmd_send(wmi, buf, len, WMI_PEER_DELETE_CMDID)) {
WMI_LOGP("%s: Failed to send peer delete command", __func__);
wmi_buf_free(buf);
return QDF_STATUS_E_FAILURE;
}
return 0;
}
/**
* crash_on_send_peer_rx_reorder_queue_remove_cmd() - crash on reorder queue cmd
*
* On MCL side, we are suspecting this cmd to trigger drop of ARP
* response frames from REO by the FW. This function causes a crash if this
* command is sent out by the host, so we can track this issue. Ideally no one
* should be calling this API from the MCL side
*
* Return: None
*/
#ifdef CONFIG_MCL
static void crash_on_send_peer_rx_reorder_queue_remove_cmd(void)
{
QDF_BUG(0);
}
#else
static void crash_on_send_peer_rx_reorder_queue_remove_cmd(void)
{
/* No-OP */
}
#endif
/**
* convert_host_peer_param_id_to_target_id_tlv - convert host peer param_id
* to target id.
* @peer_param_id: host param id.
*
* Return: Target param id.
*/
#ifdef ENABLE_HOST_TO_TARGET_CONVERSION
static inline uint32_t convert_host_peer_param_id_to_target_id_tlv(
uint32_t peer_param_id)
{
if (peer_param_id < QDF_ARRAY_SIZE(peer_param_tlv))
return peer_param_tlv[peer_param_id];
return WMI_UNAVAILABLE_PARAM;
}
#else
static inline uint32_t convert_host_peer_param_id_to_target_id_tlv(
uint32_t peer_param_id)
{
return peer_param_id;
}
#endif
/**
* send_peer_param_cmd_tlv() - set peer parameter in fw
* @wmi: wmi handle
* @peer_addr: peer mac address
* @param : pointer to hold peer set parameter
*
* Return: QDF_STATUS_SUCCESS for success or error code
*/
static QDF_STATUS send_peer_param_cmd_tlv(wmi_unified_t wmi,
uint8_t peer_addr[QDF_MAC_ADDR_SIZE],
struct peer_set_params *param)
{
wmi_peer_set_param_cmd_fixed_param *cmd;
wmi_buf_t buf;
int32_t err;
uint32_t param_id;
param_id = convert_host_peer_param_id_to_target_id_tlv(param->param_id);
if (param_id == WMI_UNAVAILABLE_PARAM) {
WMI_LOGW("%s: Unavailable param %d", __func__, param->param_id);
return QDF_STATUS_E_NOSUPPORT;
}
buf = wmi_buf_alloc(wmi, sizeof(*cmd));
if (!buf)
return QDF_STATUS_E_NOMEM;
cmd = (wmi_peer_set_param_cmd_fixed_param *) wmi_buf_data(buf);
WMITLV_SET_HDR(&cmd->tlv_header,
WMITLV_TAG_STRUC_wmi_peer_set_param_cmd_fixed_param,
WMITLV_GET_STRUCT_TLVLEN
(wmi_peer_set_param_cmd_fixed_param));
cmd->vdev_id = param->vdev_id;
WMI_CHAR_ARRAY_TO_MAC_ADDR(peer_addr, &cmd->peer_macaddr);
cmd->param_id = param_id;
cmd->param_value = param->param_value;
wmi_mtrace(WMI_PEER_SET_PARAM_CMDID, cmd->vdev_id, 0);
err = wmi_unified_cmd_send(wmi, buf,
sizeof(wmi_peer_set_param_cmd_fixed_param),
WMI_PEER_SET_PARAM_CMDID);
if (err) {
WMI_LOGE("Failed to send set_param cmd");
wmi_buf_free(buf);
return QDF_STATUS_E_FAILURE;
}
return 0;
}
/**
* send_vdev_up_cmd_tlv() - send vdev up command in fw
* @wmi: wmi handle
* @bssid: bssid
* @vdev_up_params: pointer to hold vdev up parameter
*
* Return: QDF_STATUS_SUCCESS for success or error code
*/
static QDF_STATUS send_vdev_up_cmd_tlv(wmi_unified_t wmi,
uint8_t bssid[QDF_MAC_ADDR_SIZE],
struct vdev_up_params *params)
{
wmi_vdev_up_cmd_fixed_param *cmd;
wmi_buf_t buf;
int32_t len = sizeof(*cmd);
WMI_LOGD("%s: VDEV_UP", __func__);
WMI_LOGD("%s: vdev_id %d aid %d bssid %pM", __func__,
params->vdev_id, params->assoc_id, bssid);
buf = wmi_buf_alloc(wmi, len);
if (!buf)
return QDF_STATUS_E_NOMEM;
cmd = (wmi_vdev_up_cmd_fixed_param *) wmi_buf_data(buf);
WMITLV_SET_HDR(&cmd->tlv_header,
WMITLV_TAG_STRUC_wmi_vdev_up_cmd_fixed_param,
WMITLV_GET_STRUCT_TLVLEN(wmi_vdev_up_cmd_fixed_param));
cmd->vdev_id = params->vdev_id;
cmd->vdev_assoc_id = params->assoc_id;
cmd->profile_idx = params->profile_idx;
cmd->profile_num = params->profile_num;
WMI_CHAR_ARRAY_TO_MAC_ADDR(params->trans_bssid, &cmd->trans_bssid);
WMI_CHAR_ARRAY_TO_MAC_ADDR(bssid, &cmd->vdev_bssid);
wmi_mtrace(WMI_VDEV_UP_CMDID, cmd->vdev_id, 0);
if (wmi_unified_cmd_send(wmi, buf, len, WMI_VDEV_UP_CMDID)) {
WMI_LOGP("%s: Failed to send vdev up command", __func__);
wmi_buf_free(buf);
return QDF_STATUS_E_FAILURE;
}
return 0;
}
/**
* send_peer_create_cmd_tlv() - send peer create command to fw
* @wmi: wmi handle
* @peer_addr: peer mac address
* @peer_type: peer type
* @vdev_id: vdev id
*
* Return: QDF_STATUS_SUCCESS for success or error code
*/
static QDF_STATUS send_peer_create_cmd_tlv(wmi_unified_t wmi,
struct peer_create_params *param)
{
wmi_peer_create_cmd_fixed_param *cmd;
wmi_buf_t buf;
int32_t len = sizeof(*cmd);
buf = wmi_buf_alloc(wmi, len);
if (!buf)
return QDF_STATUS_E_NOMEM;
cmd = (wmi_peer_create_cmd_fixed_param *) wmi_buf_data(buf);
WMITLV_SET_HDR(&cmd->tlv_header,
WMITLV_TAG_STRUC_wmi_peer_create_cmd_fixed_param,
WMITLV_GET_STRUCT_TLVLEN
(wmi_peer_create_cmd_fixed_param));
WMI_CHAR_ARRAY_TO_MAC_ADDR(param->peer_addr, &cmd->peer_macaddr);
cmd->peer_type = param->peer_type;
cmd->vdev_id = param->vdev_id;
wmi_mtrace(WMI_PEER_CREATE_CMDID, cmd->vdev_id, 0);
if (wmi_unified_cmd_send(wmi, buf, len, WMI_PEER_CREATE_CMDID)) {
WMI_LOGP("%s: failed to send WMI_PEER_CREATE_CMDID", __func__);
wmi_buf_free(buf);
return QDF_STATUS_E_FAILURE;
}
WMI_LOGD("%s: peer_addr %pM vdev_id %d", __func__, param->peer_addr,
param->vdev_id);
return 0;
}
/**
* send_peer_rx_reorder_queue_setup_cmd_tlv() - send rx reorder setup
* command to fw
* @wmi: wmi handle
* @rx_reorder_queue_setup_params: Rx reorder queue setup parameters
*
* Return: 0 for success or error code
*/
static
QDF_STATUS send_peer_rx_reorder_queue_setup_cmd_tlv(wmi_unified_t wmi,
struct rx_reorder_queue_setup_params *param)
{
wmi_peer_reorder_queue_setup_cmd_fixed_param *cmd;
wmi_buf_t buf;
int32_t len = sizeof(*cmd);
buf = wmi_buf_alloc(wmi, len);
if (!buf)
return QDF_STATUS_E_NOMEM;
cmd = (wmi_peer_reorder_queue_setup_cmd_fixed_param *)wmi_buf_data(buf);
WMITLV_SET_HDR(&cmd->tlv_header,
WMITLV_TAG_STRUC_wmi_peer_reorder_queue_setup_cmd_fixed_param,
WMITLV_GET_STRUCT_TLVLEN
(wmi_peer_reorder_queue_setup_cmd_fixed_param));
WMI_CHAR_ARRAY_TO_MAC_ADDR(param->peer_macaddr, &cmd->peer_macaddr);
cmd->vdev_id = param->vdev_id;
cmd->tid = param->tid;
cmd->queue_ptr_lo = param->hw_qdesc_paddr_lo;
cmd->queue_ptr_hi = param->hw_qdesc_paddr_hi;
cmd->queue_no = param->queue_no;
cmd->ba_window_size_valid = param->ba_window_size_valid;
cmd->ba_window_size = param->ba_window_size;
wmi_mtrace(WMI_PEER_REORDER_QUEUE_SETUP_CMDID, cmd->vdev_id, 0);
if (wmi_unified_cmd_send(wmi, buf, len,
WMI_PEER_REORDER_QUEUE_SETUP_CMDID)) {
WMI_LOGP("%s: fail to send WMI_PEER_REORDER_QUEUE_SETUP_CMDID",
__func__);
wmi_buf_free(buf);
return QDF_STATUS_E_FAILURE;
}
WMI_LOGD("%s: peer_macaddr %pM vdev_id %d, tid %d", __func__,
param->peer_macaddr, param->vdev_id, param->tid);
return QDF_STATUS_SUCCESS;
}
/**
* send_peer_rx_reorder_queue_remove_cmd_tlv() - send rx reorder remove
* command to fw
* @wmi: wmi handle
* @rx_reorder_queue_remove_params: Rx reorder queue remove parameters
*
* Return: 0 for success or error code
*/
static
QDF_STATUS send_peer_rx_reorder_queue_remove_cmd_tlv(wmi_unified_t wmi,
struct rx_reorder_queue_remove_params *param)
{
wmi_peer_reorder_queue_remove_cmd_fixed_param *cmd;
wmi_buf_t buf;
int32_t len = sizeof(*cmd);
crash_on_send_peer_rx_reorder_queue_remove_cmd();
buf = wmi_buf_alloc(wmi, len);
if (!buf)
return QDF_STATUS_E_NOMEM;
cmd = (wmi_peer_reorder_queue_remove_cmd_fixed_param *)
wmi_buf_data(buf);
WMITLV_SET_HDR(&cmd->tlv_header,
WMITLV_TAG_STRUC_wmi_peer_reorder_queue_remove_cmd_fixed_param,
WMITLV_GET_STRUCT_TLVLEN
(wmi_peer_reorder_queue_remove_cmd_fixed_param));
WMI_CHAR_ARRAY_TO_MAC_ADDR(param->peer_macaddr, &cmd->peer_macaddr);
cmd->vdev_id = param->vdev_id;
cmd->tid_mask = param->peer_tid_bitmap;
wmi_mtrace(WMI_PEER_REORDER_QUEUE_REMOVE_CMDID, cmd->vdev_id, 0);
if (wmi_unified_cmd_send(wmi, buf, len,
WMI_PEER_REORDER_QUEUE_REMOVE_CMDID)) {
WMI_LOGP("%s: fail to send WMI_PEER_REORDER_QUEUE_REMOVE_CMDID",
__func__);
wmi_buf_free(buf);
return QDF_STATUS_E_FAILURE;
}
WMI_LOGD("%s: peer_macaddr %pM vdev_id %d, tid_map %d", __func__,
param->peer_macaddr, param->vdev_id, param->peer_tid_bitmap);
return QDF_STATUS_SUCCESS;
}
#ifdef WLAN_SUPPORT_GREEN_AP
/**
* send_green_ap_ps_cmd_tlv() - enable green ap powersave command
* @wmi_handle: wmi handle
* @value: value
* @pdev_id: pdev id to have radio context
*
* Return: QDF_STATUS_SUCCESS for success or error code
*/
static QDF_STATUS send_green_ap_ps_cmd_tlv(wmi_unified_t wmi_handle,
uint32_t value, uint8_t pdev_id)
{
wmi_pdev_green_ap_ps_enable_cmd_fixed_param *cmd;
wmi_buf_t buf;
int32_t len = sizeof(*cmd);
WMI_LOGD("Set Green AP PS val %d", value);
buf = wmi_buf_alloc(wmi_handle, len);
if (!buf)
return QDF_STATUS_E_NOMEM;
cmd = (wmi_pdev_green_ap_ps_enable_cmd_fixed_param *) wmi_buf_data(buf);
WMITLV_SET_HDR(&cmd->tlv_header,
WMITLV_TAG_STRUC_wmi_pdev_green_ap_ps_enable_cmd_fixed_param,
WMITLV_GET_STRUCT_TLVLEN
(wmi_pdev_green_ap_ps_enable_cmd_fixed_param));
cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target(pdev_id);
cmd->enable = value;
wmi_mtrace(WMI_PDEV_GREEN_AP_PS_ENABLE_CMDID, NO_SESSION, 0);
if (wmi_unified_cmd_send(wmi_handle, buf, len,
WMI_PDEV_GREEN_AP_PS_ENABLE_CMDID)) {
WMI_LOGE("Set Green AP PS param Failed val %d", value);
wmi_buf_free(buf);
return QDF_STATUS_E_FAILURE;
}
return 0;
}
#endif
/**
* send_pdev_utf_cmd_tlv() - send utf command to fw
* @wmi_handle: wmi handle
* @param: pointer to pdev_utf_params
* @mac_id: mac id to have radio context
*
* Return: QDF_STATUS_SUCCESS for success or error code
*/
static QDF_STATUS
send_pdev_utf_cmd_tlv(wmi_unified_t wmi_handle,
struct pdev_utf_params *param,
uint8_t mac_id)
{
wmi_buf_t buf;
uint8_t *cmd;
/* if param->len is 0 no data is sent, return error */
QDF_STATUS ret = QDF_STATUS_E_INVAL;
static uint8_t msgref = 1;
uint8_t segNumber = 0, segInfo, numSegments;
uint16_t chunk_len, total_bytes;
uint8_t *bufpos;
struct seg_hdr_info segHdrInfo;
bufpos = param->utf_payload;
total_bytes = param->len;
ASSERT(total_bytes / MAX_WMI_UTF_LEN ==
(uint8_t) (total_bytes / MAX_WMI_UTF_LEN));
numSegments = (uint8_t) (total_bytes / MAX_WMI_UTF_LEN);
if (param->len - (numSegments * MAX_WMI_UTF_LEN))
numSegments++;
while (param->len) {
if (param->len > MAX_WMI_UTF_LEN)
chunk_len = MAX_WMI_UTF_LEN; /* MAX message */
else
chunk_len = param->len;
buf = wmi_buf_alloc(wmi_handle,
(chunk_len + sizeof(segHdrInfo) +
WMI_TLV_HDR_SIZE));
if (!buf)
return QDF_STATUS_E_NOMEM;
cmd = (uint8_t *) wmi_buf_data(buf);
segHdrInfo.len = total_bytes;
segHdrInfo.msgref = msgref;
segInfo = ((numSegments << 4) & 0xF0) | (segNumber & 0xF);
segHdrInfo.segmentInfo = segInfo;
segHdrInfo.pad = 0;
WMI_LOGD("%s:segHdrInfo.len = %d, segHdrInfo.msgref = %d,"
" segHdrInfo.segmentInfo = %d",
__func__, segHdrInfo.len, segHdrInfo.msgref,
segHdrInfo.segmentInfo);
WMI_LOGD("%s:total_bytes %d segNumber %d totalSegments %d"
"chunk len %d", __func__, total_bytes, segNumber,
numSegments, chunk_len);
segNumber++;
WMITLV_SET_HDR(cmd, WMITLV_TAG_ARRAY_BYTE,
(chunk_len + sizeof(segHdrInfo)));
cmd += WMI_TLV_HDR_SIZE;
memcpy(cmd, &segHdrInfo, sizeof(segHdrInfo)); /* 4 bytes */
memcpy(&cmd[sizeof(segHdrInfo)], bufpos, chunk_len);
wmi_mtrace(WMI_PDEV_UTF_CMDID, NO_SESSION, 0);
ret = wmi_unified_cmd_send(wmi_handle, buf,
(chunk_len + sizeof(segHdrInfo) +
WMI_TLV_HDR_SIZE),
WMI_PDEV_UTF_CMDID);
if (QDF_IS_STATUS_ERROR(ret)) {
WMI_LOGE("Failed to send WMI_PDEV_UTF_CMDID command");
wmi_buf_free(buf);
break;
}
param->len -= chunk_len;
bufpos += chunk_len;
}
msgref++;
return ret;
}
#ifdef ENABLE_HOST_TO_TARGET_CONVERSION
static inline uint32_t convert_host_pdev_param_tlv(uint32_t host_param)
{
if (host_param < QDF_ARRAY_SIZE(pdev_param_tlv))
return pdev_param_tlv[host_param];
return WMI_UNAVAILABLE_PARAM;
}
#else
static inline uint32_t convert_host_pdev_param_tlv(uint32_t host_param)
{
return host_param;
}
#endif
/**
* send_pdev_param_cmd_tlv() - set pdev parameters
* @wmi_handle: wmi handle
* @param: pointer to pdev parameter
* @mac_id: radio context
*
* Return: 0 on success, errno on failure
*/
static QDF_STATUS
send_pdev_param_cmd_tlv(wmi_unified_t wmi_handle,
struct pdev_params *param,
uint8_t mac_id)
{
QDF_STATUS ret;
wmi_pdev_set_param_cmd_fixed_param *cmd;
wmi_buf_t buf;
uint16_t len = sizeof(*cmd);
uint32_t pdev_param;
pdev_param = convert_host_pdev_param_tlv(param->param_id);
if (pdev_param == WMI_UNAVAILABLE_PARAM) {
WMI_LOGW("%s: Unavailable param %d",
__func__, param->param_id);
return QDF_STATUS_E_INVAL;
}
buf = wmi_buf_alloc(wmi_handle, len);
if (!buf)
return QDF_STATUS_E_NOMEM;
cmd = (wmi_pdev_set_param_cmd_fixed_param *) wmi_buf_data(buf);
WMITLV_SET_HDR(&cmd->tlv_header,
WMITLV_TAG_STRUC_wmi_pdev_set_param_cmd_fixed_param,
WMITLV_GET_STRUCT_TLVLEN
(wmi_pdev_set_param_cmd_fixed_param));
cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target(mac_id);
cmd->param_id = pdev_param;
cmd->param_value = param->param_value;
WMI_LOGD("Setting pdev param = %x, value = %u", param->param_id,
param->param_value);
wmi_mtrace(WMI_PDEV_SET_PARAM_CMDID, NO_SESSION, 0);
ret = wmi_unified_cmd_send(wmi_handle, buf, len,
WMI_PDEV_SET_PARAM_CMDID);
if (QDF_IS_STATUS_ERROR(ret)) {
WMI_LOGE("Failed to send set param command ret = %d", ret);
wmi_buf_free(buf);
}
return ret;
}
/**
* send_suspend_cmd_tlv() - WMI suspend function
* @param wmi_handle : handle to WMI.
* @param param : pointer to hold suspend parameter
* @mac_id: radio context
*
* Return 0 on success and -ve on failure.
*/
static QDF_STATUS send_suspend_cmd_tlv(wmi_unified_t wmi_handle,
struct suspend_params *param,
uint8_t mac_id)
{
wmi_pdev_suspend_cmd_fixed_param *cmd;
wmi_buf_t wmibuf;
uint32_t len = sizeof(*cmd);
int32_t ret;
/*
* send the command to Target to ignore the
* PCIE reset so as to ensure that Host and target
* states are in sync
*/
wmibuf = wmi_buf_alloc(wmi_handle, len);
if (!wmibuf)
return QDF_STATUS_E_NOMEM;
cmd = (wmi_pdev_suspend_cmd_fixed_param *) wmi_buf_data(wmibuf);
WMITLV_SET_HDR(&cmd->tlv_header,
WMITLV_TAG_STRUC_wmi_pdev_suspend_cmd_fixed_param,
WMITLV_GET_STRUCT_TLVLEN
(wmi_pdev_suspend_cmd_fixed_param));
if (param->disable_target_intr)
cmd->suspend_opt = WMI_PDEV_SUSPEND_AND_DISABLE_INTR;
else
cmd->suspend_opt = WMI_PDEV_SUSPEND;
cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target(mac_id);
wmi_mtrace(WMI_PDEV_SUSPEND_CMDID, NO_SESSION, 0);
ret = wmi_unified_cmd_send(wmi_handle, wmibuf, len,
WMI_PDEV_SUSPEND_CMDID);
if (ret) {
wmi_buf_free(wmibuf);
WMI_LOGE("Failed to send WMI_PDEV_SUSPEND_CMDID command");
}
return ret;
}
/**
* send_resume_cmd_tlv() - WMI resume function
* @param wmi_handle : handle to WMI.
* @mac_id: radio context
*
* Return: 0 on success and -ve on failure.
*/
static QDF_STATUS send_resume_cmd_tlv(wmi_unified_t wmi_handle,
uint8_t mac_id)
{
wmi_buf_t wmibuf;
wmi_pdev_resume_cmd_fixed_param *cmd;
QDF_STATUS ret;
wmibuf = wmi_buf_alloc(wmi_handle, sizeof(*cmd));
if (!wmibuf)
return QDF_STATUS_E_NOMEM;
cmd = (wmi_pdev_resume_cmd_fixed_param *) wmi_buf_data(wmibuf);
WMITLV_SET_HDR(&cmd->tlv_header,
WMITLV_TAG_STRUC_wmi_pdev_resume_cmd_fixed_param,
WMITLV_GET_STRUCT_TLVLEN
(wmi_pdev_resume_cmd_fixed_param));
cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target(mac_id);
wmi_mtrace(WMI_PDEV_RESUME_CMDID, NO_SESSION, 0);
ret = wmi_unified_cmd_send(wmi_handle, wmibuf, sizeof(*cmd),
WMI_PDEV_RESUME_CMDID);
if (QDF_IS_STATUS_ERROR(ret)) {
WMI_LOGE("Failed to send WMI_PDEV_RESUME_CMDID command");
wmi_buf_free(wmibuf);
}
return ret;
}
/**
* send_wow_enable_cmd_tlv() - WMI wow enable function
* @param wmi_handle : handle to WMI.
* @param param : pointer to hold wow enable parameter
* @mac_id: radio context
*
* Return: 0 on success and -ve on failure.
*/
static QDF_STATUS send_wow_enable_cmd_tlv(wmi_unified_t wmi_handle,
struct wow_cmd_params *param,
uint8_t mac_id)
{
wmi_wow_enable_cmd_fixed_param *cmd;
wmi_buf_t buf;
int32_t len;
int32_t ret;
len = sizeof(wmi_wow_enable_cmd_fixed_param);
buf = wmi_buf_alloc(wmi_handle, len);
if (!buf)
return QDF_STATUS_E_NOMEM;
cmd = (wmi_wow_enable_cmd_fixed_param *) wmi_buf_data(buf);
WMITLV_SET_HDR(&cmd->tlv_header,
WMITLV_TAG_STRUC_wmi_wow_enable_cmd_fixed_param,
WMITLV_GET_STRUCT_TLVLEN
(wmi_wow_enable_cmd_fixed_param));
cmd->enable = param->enable;
if (param->can_suspend_link)
cmd->pause_iface_config = WOW_IFACE_PAUSE_ENABLED;
else
cmd->pause_iface_config = WOW_IFACE_PAUSE_DISABLED;
cmd->flags = param->flags;
WMI_LOGI("suspend type: %s",
cmd->pause_iface_config == WOW_IFACE_PAUSE_ENABLED ?
"WOW_IFACE_PAUSE_ENABLED" : "WOW_IFACE_PAUSE_DISABLED");
wmi_mtrace(WMI_WOW_ENABLE_CMDID, NO_SESSION, 0);
ret = wmi_unified_cmd_send(wmi_handle, buf, len,
WMI_WOW_ENABLE_CMDID);
if (ret)
wmi_buf_free(buf);
return ret;
}
/**
* send_set_ap_ps_param_cmd_tlv() - set ap powersave parameters
* @wmi_handle: wmi handle
* @peer_addr: peer mac address
* @param: pointer to ap_ps parameter structure
*
* Return: QDF_STATUS_SUCCESS for success or error code
*/
static QDF_STATUS send_set_ap_ps_param_cmd_tlv(wmi_unified_t wmi_handle,
uint8_t *peer_addr,
struct ap_ps_params *param)
{
wmi_ap_ps_peer_cmd_fixed_param *cmd;
wmi_buf_t buf;
int32_t err;
buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd));
if (!buf)
return QDF_STATUS_E_NOMEM;
cmd = (wmi_ap_ps_peer_cmd_fixed_param *) wmi_buf_data(buf);
WMITLV_SET_HDR(&cmd->tlv_header,
WMITLV_TAG_STRUC_wmi_ap_ps_peer_cmd_fixed_param,
WMITLV_GET_STRUCT_TLVLEN
(wmi_ap_ps_peer_cmd_fixed_param));
cmd->vdev_id = param->vdev_id;
WMI_CHAR_ARRAY_TO_MAC_ADDR(peer_addr, &cmd->peer_macaddr);
cmd->param = param->param;
cmd->value = param->value;
wmi_mtrace(WMI_AP_PS_PEER_PARAM_CMDID, cmd->vdev_id, 0);
err = wmi_unified_cmd_send(wmi_handle, buf,
sizeof(*cmd), WMI_AP_PS_PEER_PARAM_CMDID);
if (err) {
WMI_LOGE("Failed to send set_ap_ps_param cmd");
wmi_buf_free(buf);
return QDF_STATUS_E_FAILURE;
}
return 0;
}
/**
* send_set_sta_ps_param_cmd_tlv() - set sta powersave parameters
* @wmi_handle: wmi handle
* @peer_addr: peer mac address
* @param: pointer to sta_ps parameter structure
*
* Return: QDF_STATUS_SUCCESS for success or error code
*/
static QDF_STATUS send_set_sta_ps_param_cmd_tlv(wmi_unified_t wmi_handle,
struct sta_ps_params *param)
{
wmi_sta_powersave_param_cmd_fixed_param *cmd;
wmi_buf_t buf;
int32_t len = sizeof(*cmd);
buf = wmi_buf_alloc(wmi_handle, len);
if (!buf)
return QDF_STATUS_E_NOMEM;
cmd = (wmi_sta_powersave_param_cmd_fixed_param *) wmi_buf_data(buf);
WMITLV_SET_HDR(&cmd->tlv_header,
WMITLV_TAG_STRUC_wmi_sta_powersave_param_cmd_fixed_param,
WMITLV_GET_STRUCT_TLVLEN
(wmi_sta_powersave_param_cmd_fixed_param));
cmd->vdev_id = param->vdev_id;
#ifdef CMN_VDEV_MGR_TGT_IF_ENABLE
cmd->param = param->param_id;
#else
cmd->param = param->param;
#endif
cmd->value = param->value;
wmi_mtrace(WMI_STA_POWERSAVE_PARAM_CMDID, cmd->vdev_id, 0);
if (wmi_unified_cmd_send(wmi_handle, buf, len,
WMI_STA_POWERSAVE_PARAM_CMDID)) {
#ifdef CMN_VDEV_MGR_TGT_IF_ENABLE
WMI_LOGE("Set Sta Ps param Failed vdevId %d Param %d val %d",
param->vdev_id, param->param_id, param->value);
#else
WMI_LOGE("Set Sta Ps param Failed vdevId %d Param %d val %d",
param->vdev_id, param->param, param->value);
#endif
wmi_buf_free(buf);
return QDF_STATUS_E_FAILURE;
}
return 0;
}
/**
* send_crash_inject_cmd_tlv() - inject fw crash
* @wmi_handle: wmi handle
* @param: ponirt to crash inject parameter structure
*
* Return: QDF_STATUS_SUCCESS for success or return error
*/
static QDF_STATUS send_crash_inject_cmd_tlv(wmi_unified_t wmi_handle,
struct crash_inject *param)
{
int32_t ret = 0;
WMI_FORCE_FW_HANG_CMD_fixed_param *cmd;
uint16_t len = sizeof(*cmd);
wmi_buf_t buf;
buf = wmi_buf_alloc(wmi_handle, len);
if (!buf)
return QDF_STATUS_E_NOMEM;
cmd = (WMI_FORCE_FW_HANG_CMD_fixed_param *) wmi_buf_data(buf);
WMITLV_SET_HDR(&cmd->tlv_header,
WMITLV_TAG_STRUC_WMI_FORCE_FW_HANG_CMD_fixed_param,
WMITLV_GET_STRUCT_TLVLEN
(WMI_FORCE_FW_HANG_CMD_fixed_param));
cmd->type = param->type;
cmd->delay_time_ms = param->delay_time_ms;
wmi_mtrace(WMI_FORCE_FW_HANG_CMDID, NO_SESSION, 0);
ret = wmi_unified_cmd_send(wmi_handle, buf, len,
WMI_FORCE_FW_HANG_CMDID);
if (ret) {
WMI_LOGE("%s: Failed to send set param command, ret = %d",
__func__, ret);
wmi_buf_free(buf);
}
return ret;
}
#ifdef FEATURE_FW_LOG_PARSING
/**
* send_dbglog_cmd_tlv() - set debug log level
* @param wmi_handle : handle to WMI.
* @param param : pointer to hold dbglog level parameter
*
* Return: 0 on success and -ve on failure.
*/
static QDF_STATUS
send_dbglog_cmd_tlv(wmi_unified_t wmi_handle,
struct dbglog_params *dbglog_param)
{
wmi_buf_t buf;
wmi_debug_log_config_cmd_fixed_param *configmsg;
QDF_STATUS status;
int32_t i;
int32_t len;
int8_t *buf_ptr;
int32_t *module_id_bitmap_array; /* Used to fomr the second tlv */
ASSERT(dbglog_param->bitmap_len < MAX_MODULE_ID_BITMAP_WORDS);
/* Allocate size for 2 tlvs - including tlv hdr space for second tlv */
len = sizeof(wmi_debug_log_config_cmd_fixed_param) + WMI_TLV_HDR_SIZE +
(sizeof(int32_t) * MAX_MODULE_ID_BITMAP_WORDS);
buf = wmi_buf_alloc(wmi_handle, len);
if (!buf)
return QDF_STATUS_E_NOMEM;
configmsg =
(wmi_debug_log_config_cmd_fixed_param *) (wmi_buf_data(buf));
buf_ptr = (int8_t *) configmsg;
WMITLV_SET_HDR(&configmsg->tlv_header,
WMITLV_TAG_STRUC_wmi_debug_log_config_cmd_fixed_param,
WMITLV_GET_STRUCT_TLVLEN
(wmi_debug_log_config_cmd_fixed_param));
configmsg->dbg_log_param = dbglog_param->param;
configmsg->value = dbglog_param->val;
/* Filling in the data part of second tlv -- should
* follow first tlv _ WMI_TLV_HDR_SIZE */
module_id_bitmap_array = (uint32_t *) (buf_ptr +
sizeof
(wmi_debug_log_config_cmd_fixed_param)
+ WMI_TLV_HDR_SIZE);
WMITLV_SET_HDR(buf_ptr + sizeof(wmi_debug_log_config_cmd_fixed_param),
WMITLV_TAG_ARRAY_UINT32,
sizeof(uint32_t) * MAX_MODULE_ID_BITMAP_WORDS);
if (dbglog_param->module_id_bitmap) {
for (i = 0; i < dbglog_param->bitmap_len; ++i) {
module_id_bitmap_array[i] =
dbglog_param->module_id_bitmap[i];
}
}
wmi_mtrace(WMI_DBGLOG_CFG_CMDID, NO_SESSION, 0);
status = wmi_unified_cmd_send(wmi_handle, buf,
len, WMI_DBGLOG_CFG_CMDID);
if (status != QDF_STATUS_SUCCESS)
wmi_buf_free(buf);
return status;
}
#endif
#ifdef ENABLE_HOST_TO_TARGET_CONVERSION
static inline uint32_t convert_host_vdev_param_tlv(uint32_t host_param)
{
if (host_param < QDF_ARRAY_SIZE(vdev_param_tlv))
return vdev_param_tlv[host_param];
return WMI_UNAVAILABLE_PARAM;
}
#else
static inline uint32_t convert_host_vdev_param_tlv(uint32_t host_param)
{
return host_param;
}
#endif
/**
* send_vdev_set_param_cmd_tlv() - WMI vdev set parameter function
* @param wmi_handle : handle to WMI.
* @param macaddr : MAC address
* @param param : pointer to hold vdev set parameter
*
* Return: 0 on success and -ve on failure.
*/
static QDF_STATUS send_vdev_set_param_cmd_tlv(wmi_unified_t wmi_handle,
struct vdev_set_params *param)
{
QDF_STATUS ret;
wmi_vdev_set_param_cmd_fixed_param *cmd;
wmi_buf_t buf;
uint16_t len = sizeof(*cmd);
uint32_t vdev_param;
vdev_param = convert_host_vdev_param_tlv(param->param_id);
if (vdev_param == WMI_UNAVAILABLE_PARAM) {
WMI_LOGW("%s:Vdev param %d not available", __func__,
param->param_id);
return QDF_STATUS_E_INVAL;
}
buf = wmi_buf_alloc(wmi_handle, len);
if (!buf)
return QDF_STATUS_E_NOMEM;
cmd = (wmi_vdev_set_param_cmd_fixed_param *) wmi_buf_data(buf);
WMITLV_SET_HDR(&cmd->tlv_header,
WMITLV_TAG_STRUC_wmi_vdev_set_param_cmd_fixed_param,
WMITLV_GET_STRUCT_TLVLEN
(wmi_vdev_set_param_cmd_fixed_param));
#ifdef CMN_VDEV_MGR_TGT_IF_ENABLE
cmd->vdev_id = param->vdev_id;
#else
cmd->vdev_id = param->if_id;
#endif
cmd->param_id = vdev_param;
cmd->param_value = param->param_value;
WMI_LOGD("Setting vdev %d param = %x, value = %u",
cmd->vdev_id, cmd->param_id, cmd->param_value);
wmi_mtrace(WMI_VDEV_SET_PARAM_CMDID, cmd->vdev_id, 0);
ret = wmi_unified_cmd_send(wmi_handle, buf, len,
WMI_VDEV_SET_PARAM_CMDID);
if (QDF_IS_STATUS_ERROR(ret)) {
WMI_LOGE("Failed to send set param command ret = %d", ret);
wmi_buf_free(buf);
}
return ret;
}
/**
* send_stats_request_cmd_tlv() - WMI request stats function
* @param wmi_handle : handle to WMI.
* @param macaddr : MAC address
* @param param : pointer to hold stats request parameter
*
* Return: 0 on success and -ve on failure.
*/
static QDF_STATUS send_stats_request_cmd_tlv(wmi_unified_t wmi_handle,
uint8_t macaddr[QDF_MAC_ADDR_SIZE],
struct stats_request_params *param)
{
int32_t ret;
wmi_request_stats_cmd_fixed_param *cmd;
wmi_buf_t buf;
uint16_t len = sizeof(wmi_request_stats_cmd_fixed_param);
buf = wmi_buf_alloc(wmi_handle, len);
if (!buf)
return -QDF_STATUS_E_NOMEM;
cmd = (wmi_request_stats_cmd_fixed_param *) wmi_buf_data(buf);
WMITLV_SET_HDR(&cmd->tlv_header,
WMITLV_TAG_STRUC_wmi_request_stats_cmd_fixed_param,
WMITLV_GET_STRUCT_TLVLEN
(wmi_request_stats_cmd_fixed_param));
cmd->stats_id = param->stats_id;
cmd->vdev_id = param->vdev_id;
cmd->pdev_id = wmi_handle->ops->convert_host_pdev_id_to_target(
param->pdev_id);
WMI_CHAR_ARRAY_TO_MAC_ADDR(macaddr, &cmd->peer_macaddr);
WMI_LOGD("STATS REQ STATS_ID:%d VDEV_ID:%d PDEV_ID:%d-->",
cmd->stats_id, cmd->vdev_id, cmd->pdev_id);
wmi_mtrace(WMI_REQUEST_STATS_CMDID, cmd->vdev_id, 0);
ret = wmi_unified_cmd_send_pm_chk(wmi_handle, buf, len,
WMI_REQUEST_STATS_CMDID);
if (ret) {
WMI_LOGE("Failed to send status request to fw =%d", ret);
wmi_buf_free(buf);
}
return ret;
}
#ifdef CONFIG_WIN
/**
* send_peer_based_pktlog_cmd() - Send WMI command to enable packet-log
* @wmi_handle: handle to WMI.
* @macaddr: Peer mac address to be filter
* @mac_id: mac id to have radio context
* @enb_dsb: Enable MAC based filtering or Disable
*
* Return: QDF_STATUS
*/
static QDF_STATUS send_peer_based_pktlog_cmd(wmi_unified_t wmi_handle,
uint8_t *macaddr,
uint8_t mac_id,
uint8_t enb_dsb)
{
int32_t ret;
wmi_pdev_pktlog_filter_cmd_fixed_param *cmd;
wmi_pdev_pktlog_filter_info *mac_info;
wmi_buf_t buf;
uint8_t *buf_ptr;
uint16_t len = sizeof(wmi_pdev_pktlog_filter_cmd_fixed_param) +
sizeof(wmi_pdev_pktlog_filter_info) + WMI_TLV_HDR_SIZE;
buf = wmi_buf_alloc(wmi_handle, len);
if (!buf)
return QDF_STATUS_E_NOMEM;
buf_ptr = (uint8_t *)wmi_buf_data(buf);
cmd = (wmi_pdev_pktlog_filter_cmd_fixed_param *)buf_ptr;
WMITLV_SET_HDR(&cmd->tlv_header,
WMITLV_TAG_STRUC_wmi_pdev_pktlog_filter_cmd_fixed_param,
WMITLV_GET_STRUCT_TLVLEN
(wmi_pdev_pktlog_filter_cmd_fixed_param));
cmd->pdev_id = mac_id;
cmd->enable = enb_dsb;
cmd->num_of_mac_addresses = 1;
wmi_mtrace(WMI_PDEV_PKTLOG_FILTER_CMDID, cmd->pdev_id, 0);
buf_ptr += sizeof(*cmd);
WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
sizeof(wmi_pdev_pktlog_filter_info));
buf_ptr += WMI_TLV_HDR_SIZE;
mac_info = (wmi_pdev_pktlog_filter_info *)(buf_ptr);
WMITLV_SET_HDR(&mac_info->tlv_header,
WMITLV_TAG_STRUC_wmi_pdev_pktlog_filter_info,
WMITLV_GET_STRUCT_TLVLEN
(wmi_pdev_pktlog_filter_info));
WMI_CHAR_ARRAY_TO_MAC_ADDR(macaddr, &mac_info->peer_mac_address);
ret = wmi_unified_cmd_send(wmi_handle, buf, len,
WMI_PDEV_PKTLOG_FILTER_CMDID);
if (ret) {
WMI_LOGE("Failed to send peer based pktlog command to FW =%d"
, ret);
wmi_buf_free(buf);
}
return ret;
}
/**
* send_packet_log_enable_cmd_tlv() - Send WMI command to enable packet-log
* @param wmi_handle : handle to WMI.
* @param PKTLOG_EVENT : packet log event
* @mac_id: mac id to have radio context
*
* Return: 0 on success and -ve on failure.
*/
static QDF_STATUS send_packet_log_enable_cmd_tlv(wmi_unified_t wmi_handle,
WMI_HOST_PKTLOG_EVENT PKTLOG_EVENT, uint8_t mac_id)
{
int32_t ret;
wmi_pdev_pktlog_enable_cmd_fixed_param *cmd;
wmi_buf_t buf;
uint16_t len = sizeof(wmi_pdev_pktlog_enable_cmd_fixed_param);
buf = wmi_buf_alloc(wmi_handle, len);
if (!buf)
return -QDF_STATUS_E_NOMEM;
cmd = (wmi_pdev_pktlog_enable_cmd_fixed_param *) wmi_buf_data(buf);
WMITLV_SET_HDR(&cmd->tlv_header,
WMITLV_TAG_STRUC_wmi_pdev_pktlog_enable_cmd_fixed_param,
WMITLV_GET_STRUCT_TLVLEN
(wmi_pdev_pktlog_enable_cmd_fixed_param));
cmd->evlist = PKTLOG_EVENT;
cmd->pdev_id = mac_id;
wmi_mtrace(WMI_PDEV_PKTLOG_ENABLE_CMDID, cmd->pdev_id, 0);
ret = wmi_unified_cmd_send(wmi_handle, buf, len,
WMI_PDEV_PKTLOG_ENABLE_CMDID);
if (ret) {
WMI_LOGE("Failed to send pktlog enable cmd to FW =%d", ret);
wmi_buf_free(buf);
}
return ret;
}
/**
* send_packet_log_disable_cmd_tlv() - Send WMI command to disable packet-log
* @param wmi_handle : handle to WMI.
* @mac_id: mac id to have radio context
*
* Return: 0 on success and -ve on failure.
*/
static QDF_STATUS send_packet_log_disable_cmd_tlv(wmi_unified_t wmi_handle,
uint8_t mac_id)
{
int32_t ret;
wmi_pdev_pktlog_disable_cmd_fixed_param *cmd;
wmi_buf_t buf;
uint16_t len = sizeof(wmi_pdev_pktlog_disable_cmd_fixed_param);
buf = wmi_buf_alloc(wmi_handle, len);
if (!buf)
return -QDF_STATUS_E_NOMEM;
cmd = (wmi_pdev_pktlog_disable_cmd_fixed_param *) wmi_buf_data(buf);
WMITLV_SET_HDR(&cmd->tlv_header,
WMITLV_TAG_STRUC_wmi_pdev_pktlog_disable_cmd_fixed_param,
WMITLV_GET_STRUCT_TLVLEN
(wmi_pdev_pktlog_disable_cmd_fixed_param));
cmd->pdev_id = mac_id;
wmi_mtrace(WMI_PDEV_PKTLOG_DISABLE_CMDID, cmd->pdev_id, 0);
ret = wmi_unified_cmd_send(wmi_handle, buf, len,
WMI_PDEV_PKTLOG_DISABLE_CMDID);
if (ret) {
WMI_LOGE("Failed to send pktlog disable cmd to FW =%d", ret);
wmi_buf_free(buf);
}
return ret;
}
#else
/**
* send_packet_log_enable_cmd_tlv() - Send WMI command to enable
* packet-log
* @param wmi_handle : handle to WMI.
* @param macaddr : MAC address
* @param param : pointer to hold stats request parameter
*
* Return: QDF_STATUS.
*/
static QDF_STATUS send_packet_log_enable_cmd_tlv(wmi_unified_t wmi_handle,
uint8_t macaddr[QDF_MAC_ADDR_SIZE],
struct packet_enable_params *param)
{
return QDF_STATUS_SUCCESS;
}
/**
* send_peer_based_pktlog_cmd() - Send WMI command to enable packet-log
* @wmi_handle: handle to WMI.
* @macaddr: Peer mac address to be filter
* @mac_id: mac id to have radio context
* @enb_dsb: Enable MAC based filtering or Disable
*
* Return: QDF_STATUS
*/
static QDF_STATUS send_peer_based_pktlog_cmd(wmi_unified_t wmi_handle,
uint8_t *macaddr,
uint8_t mac_id,
uint8_t enb_dsb)
{
return QDF_STATUS_SUCCESS;
}
/**
* send_packet_log_disable_cmd_tlv() - Send WMI command to disable
* packet-log
* @param wmi_handle : handle to WMI.
* @mac_id: mac id to have radio context
*
* Return: QDF_STATUS.
*/
static QDF_STATUS send_packet_log_disable_cmd_tlv(wmi_unified_t wmi_handle,
uint8_t mac_id)
{
return QDF_STATUS_SUCCESS;
}
#endif
#define WMI_FW_TIME_STAMP_LOW_MASK 0xffffffff
/**
* send_time_stamp_sync_cmd_tlv() - Send WMI command to
* sync time between bwtween host and firmware
* @param wmi_handle : handle to WMI.
*
* Return: None
*/
static void send_time_stamp_sync_cmd_tlv(wmi_unified_t wmi_handle)
{
wmi_buf_t buf;
QDF_STATUS status = QDF_STATUS_SUCCESS;
WMI_DBGLOG_TIME_STAMP_SYNC_CMD_fixed_param *time_stamp;
int32_t len;
qdf_time_t time_ms;
len = sizeof(*time_stamp);
buf = wmi_buf_alloc(wmi_handle, len);
if (!buf)
return;
time_stamp =
(WMI_DBGLOG_TIME_STAMP_SYNC_CMD_fixed_param *)
(wmi_buf_data(buf));
WMITLV_SET_HDR(&time_stamp->tlv_header,
WMITLV_TAG_STRUC_wmi_dbglog_time_stamp_sync_cmd_fixed_param,
WMITLV_GET_STRUCT_TLVLEN(
WMI_DBGLOG_TIME_STAMP_SYNC_CMD_fixed_param));
time_ms = qdf_get_time_of_the_day_ms();
time_stamp->mode = WMI_TIME_STAMP_SYNC_MODE_MS;
time_stamp->time_stamp_low = time_ms &
WMI_FW_TIME_STAMP_LOW_MASK;
/*
* Send time_stamp_high 0 as the time converted from HR:MIN:SEC:MS to ms
* wont exceed 27 bit
*/
time_stamp->time_stamp_high = 0;
WMI_LOGD(FL("WMA --> DBGLOG_TIME_STAMP_SYNC_CMDID mode %d time_stamp low %d high %d"),
time_stamp->mode, time_stamp->time_stamp_low,
time_stamp->time_stamp_high);
wmi_mtrace(WMI_DBGLOG_TIME_STAMP_SYNC_CMDID, NO_SESSION, 0);
status = wmi_unified_cmd_send(wmi_handle, buf,
len, WMI_DBGLOG_TIME_STAMP_SYNC_CMDID);
if (status) {
WMI_LOGE("Failed to send WMI_DBGLOG_TIME_STAMP_SYNC_CMDID command");
wmi_buf_free(buf);
}
}
/**
* send_beacon_send_tmpl_cmd_tlv() - WMI beacon send function
* @param wmi_handle : handle to WMI.
* @param param : pointer to hold beacon send cmd parameter
*
* Return: 0 on success and -ve on failure.
*/
static QDF_STATUS send_beacon_tmpl_send_cmd_tlv(wmi_unified_t wmi_handle,
struct beacon_tmpl_params *param)
{
int32_t ret;
wmi_bcn_tmpl_cmd_fixed_param *cmd;
wmi_bcn_prb_info *bcn_prb_info;
wmi_buf_t wmi_buf;
uint8_t *buf_ptr;
uint32_t wmi_buf_len;
wmi_buf_len = sizeof(wmi_bcn_tmpl_cmd_fixed_param) +
sizeof(wmi_bcn_prb_info) + WMI_TLV_HDR_SIZE +
param->tmpl_len_aligned;
wmi_buf = wmi_buf_alloc(wmi_handle, wmi_buf_len);
if (!wmi_buf)
return QDF_STATUS_E_NOMEM;
buf_ptr = (uint8_t *) wmi_buf_data(wmi_buf);
cmd = (wmi_bcn_tmpl_cmd_fixed_param *) buf_ptr;
WMITLV_SET_HDR(&cmd->tlv_header,
WMITLV_TAG_STRUC_wmi_bcn_tmpl_cmd_fixed_param,
WMITLV_GET_STRUCT_TLVLEN(wmi_bcn_tmpl_cmd_fixed_param));
cmd->vdev_id = param->vdev_id;
cmd->tim_ie_offset = param->tim_ie_offset;
cmd->mbssid_ie_offset = param->mbssid_ie_offset;
cmd->csa_switch_count_offset = param->csa_switch_count_offset;
cmd->ext_csa_switch_count_offset = param->ext_csa_switch_count_offset;
cmd->esp_ie_offset = param->esp_ie_offset;
cmd->buf_len = param->tmpl_len;
buf_ptr += sizeof(wmi_bcn_tmpl_cmd_fixed_param);
bcn_prb_info = (wmi_bcn_prb_info *) buf_ptr;
WMITLV_SET_HDR(&bcn_prb_info->tlv_header,
WMITLV_TAG_STRUC_wmi_bcn_prb_info,
WMITLV_GET_STRUCT_TLVLEN(wmi_bcn_prb_info));
bcn_prb_info->caps = 0;
bcn_prb_info->erp = 0;
buf_ptr += sizeof(wmi_bcn_prb_info);
WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, param->tmpl_len_aligned);
buf_ptr += WMI_TLV_HDR_SIZE;
qdf_mem_copy(buf_ptr, param->frm, param->tmpl_len);
wmi_mtrace(WMI_BCN_TMPL_CMDID, cmd->vdev_id, 0);
ret = wmi_unified_cmd_send(wmi_handle,
wmi_buf, wmi_buf_len, WMI_BCN_TMPL_CMDID);
if (ret) {
WMI_LOGE("%s: Failed to send bcn tmpl: %d", __func__, ret);
wmi_buf_free(wmi_buf);
}
return 0;
}
#ifdef CONFIG_MCL
static inline void copy_peer_flags_tlv(
wmi_peer_assoc_complete_cmd_fixed_param * cmd,
struct peer_assoc_params *param)
{
cmd->peer_flags = param->peer_flags;
}
#else
static inline void copy_peer_flags_tlv(
wmi_peer_assoc_complete_cmd_fixed_param * cmd,
struct peer_assoc_params *param)
{
/*
* The target only needs a subset of the flags maintained in the host.
* Just populate those flags and send it down
*/
cmd->peer_flags = 0;
/*
* Do not enable HT/VHT if WMM/wme is disabled for vap.
*/
if (param->is_wme_set) {
if (param->qos_flag)
cmd->peer_flags |= WMI_PEER_QOS;
if (param->apsd_flag)
cmd->peer_flags |= WMI_PEER_APSD;
if (param->ht_flag)
cmd->peer_flags |= WMI_PEER_HT;
if (param->bw_40)
cmd->peer_flags |= WMI_PEER_40MHZ;
if (param->bw_80)
cmd->peer_flags |= WMI_PEER_80MHZ;
if (param->bw_160)
cmd->peer_flags |= WMI_PEER_160MHZ;
/* Typically if STBC is enabled for VHT it should be enabled
* for HT as well
**/
if (param->stbc_flag)
cmd->peer_flags |= WMI_PEER_STBC;
/* Typically if LDPC is enabled for VHT it should be enabled
* for HT as well
**/
if (param->ldpc_flag)
cmd->peer_flags |= WMI_PEER_LDPC;
if (param->static_mimops_flag)
cmd->peer_flags |= WMI_PEER_STATIC_MIMOPS;
if (param->dynamic_mimops_flag)
cmd->peer_flags |= WMI_PEER_DYN_MIMOPS;
if (param->spatial_mux_flag)
cmd->peer_flags |= WMI_PEER_SPATIAL_MUX;
if (param->vht_flag)
cmd->peer_flags |= WMI_PEER_VHT;
if (param->he_flag)
cmd->peer_flags |= WMI_PEER_HE;
}
if (param->is_pmf_enabled)
cmd->peer_flags |= WMI_PEER_PMF;
/*
* Suppress authorization for all AUTH modes that need 4-way handshake
* (during re-association).
* Authorization will be done for these modes on key installation.
*/
if (param->auth_flag)
cmd->peer_flags |= WMI_PEER_AUTH;
if (param->need_ptk_4_way)
cmd->peer_flags |= WMI_PEER_NEED_PTK_4_WAY;
else
cmd->peer_flags &= ~WMI_PEER_NEED_PTK_4_WAY;
if (param->need_gtk_2_way)
cmd->peer_flags |= WMI_PEER_NEED_GTK_2_WAY;
/* safe mode bypass the 4-way handshake */
if (param->safe_mode_enabled)
cmd->peer_flags &=
~(WMI_PEER_NEED_PTK_4_WAY | WMI_PEER_NEED_GTK_2_WAY);
/* Disable AMSDU for station transmit, if user configures it */
/* Disable AMSDU for AP transmit to 11n Stations, if user configures
* it
* if (param->amsdu_disable) Add after FW support
**/
/* Target asserts if node is marked HT and all MCS is set to 0.
* Mark the node as non-HT if all the mcs rates are disabled through
* iwpriv
**/
if (param->peer_ht_rates.num_rates == 0)
cmd->peer_flags &= ~WMI_PEER_HT;
if (param->twt_requester)
cmd->peer_flags |= WMI_PEER_TWT_REQ;
if (param->twt_responder)
cmd->peer_flags |= WMI_PEER_TWT_RESP;
}
#endif
static inline void copy_peer_mac_addr_tlv(
wmi_peer_assoc_complete_cmd_fixed_param * cmd,
struct peer_assoc_params *param)
{
WMI_CHAR_ARRAY_TO_MAC_ADDR(param->peer_mac, &cmd->peer_macaddr);
}
/**
* send_peer_assoc_cmd_tlv() - WMI peer assoc function
* @param wmi_handle : handle to WMI.
* @param param : pointer to peer assoc parameter
*
* Return: 0 on success and -ve on failure.
*/
static QDF_STATUS send_peer_assoc_cmd_tlv(wmi_unified_t wmi_handle,
struct peer_assoc_params *param)
{
wmi_peer_assoc_complete_cmd_fixed_param *cmd;
wmi_vht_rate_set *mcs;
wmi_he_rate_set *he_mcs;
wmi_buf_t buf;
int32_t len;
uint8_t *buf_ptr;
QDF_STATUS ret;
uint32_t peer_legacy_rates_align;
uint32_t peer_ht_rates_align;
int32_t i;
peer_legacy_rates_align = wmi_align(param->peer_legacy_rates.num_rates);
peer_ht_rates_align = wmi_align(param->peer_ht_rates.num_rates);
len = sizeof(*cmd) + WMI_TLV_HDR_SIZE +
(peer_legacy_rates_align * sizeof(uint8_t)) +
WMI_TLV_HDR_SIZE +
(peer_ht_rates_align * sizeof(uint8_t)) +
sizeof(wmi_vht_rate_set) +
(sizeof(wmi_he_rate_set) * param->peer_he_mcs_count
+ WMI_TLV_HDR_SIZE);
buf = wmi_buf_alloc(wmi_handle, len);
if (!buf)
return QDF_STATUS_E_NOMEM;
buf_ptr = (uint8_t *) wmi_buf_data(buf);
cmd = (wmi_peer_assoc_complete_cmd_fixed_param *) buf_ptr;
WMITLV_SET_HDR(&cmd->tlv_header,
WMITLV_TAG_STRUC_wmi_peer_assoc_complete_cmd_fixed_param,
WMITLV_GET_STRUCT_TLVLEN
(wmi_peer_assoc_complete_cmd_fixed_param));
cmd->vdev_id = param->vdev_id;
cmd->peer_new_assoc = param->peer_new_assoc;
cmd->peer_associd = param->peer_associd;
copy_peer_flags_tlv(cmd, param);
copy_peer_mac_addr_tlv(cmd, param);
cmd->peer_rate_caps = param->peer_rate_caps;
cmd->peer_caps = param->peer_caps;
cmd->peer_listen_intval = param->peer_listen_intval;
cmd->peer_ht_caps = param->peer_ht_caps;
cmd->peer_max_mpdu = param->peer_max_mpdu;
cmd->peer_mpdu_density = param->peer_mpdu_density;
cmd->peer_vht_caps = param->peer_vht_caps;
cmd->peer_phymode = param->peer_phymode;
/* Update 11ax capabilities */
cmd->peer_he_cap_info =
param->peer_he_cap_macinfo[WMI_HOST_HECAP_MAC_WORD1];
cmd->peer_he_cap_info_ext =
param->peer_he_cap_macinfo[WMI_HOST_HECAP_MAC_WORD2];
cmd->peer_he_cap_info_internal = param->peer_he_cap_info_internal;
cmd->peer_he_ops = param->peer_he_ops;
qdf_mem_copy(&cmd->peer_he_cap_phy, &param->peer_he_cap_phyinfo,
sizeof(param->peer_he_cap_phyinfo));
qdf_mem_copy(&cmd->peer_ppet, &param->peer_ppet,
sizeof(param->peer_ppet));
/* Update peer legacy rate information */
buf_ptr += sizeof(*cmd);
WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE,
peer_legacy_rates_align);
buf_ptr += WMI_TLV_HDR_SIZE;
cmd->num_peer_legacy_rates = param->peer_legacy_rates.num_rates;
qdf_mem_copy(buf_ptr, param->peer_legacy_rates.rates,
param->peer_legacy_rates.num_rates);
/* Update peer HT rate information */
buf_ptr += peer_legacy_rates_align;
WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE,
peer_ht_rates_align);
buf_ptr += WMI_TLV_HDR_SIZE;
cmd->num_peer_ht_rates = param->peer_ht_rates.num_rates;
qdf_mem_copy(buf_ptr, param->peer_ht_rates.rates,
param->peer_ht_rates.num_rates);
/* VHT Rates */
buf_ptr += peer_ht_rates_align;
WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_STRUC_wmi_vht_rate_set,
WMITLV_GET_STRUCT_TLVLEN(wmi_vht_rate_set));
cmd->peer_nss = param->peer_nss;
/* Update bandwidth-NSS mapping */
cmd->peer_bw_rxnss_override = 0;
cmd->peer_bw_rxnss_override |= param->peer_bw_rxnss_override;
mcs = (wmi_vht_rate_set *) buf_ptr;
if (param->vht_capable) {
mcs->rx_max_rate = param->rx_max_rate;
mcs->rx_mcs_set = param->rx_mcs_set;
mcs->tx_max_rate = param->tx_max_rate;
mcs->tx_mcs_set = param->tx_mcs_set;
}
/* HE Rates */
cmd->peer_he_mcs = param->peer_he_mcs_count;
buf_ptr += sizeof(wmi_vht_rate_set);
WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
(param->peer_he_mcs_count * sizeof(wmi_he_rate_set)));
buf_ptr += WMI_TLV_HDR_SIZE;
/* Loop through the HE rate set */
for (i = 0; i < param->peer_he_mcs_count; i++) {
he_mcs = (wmi_he_rate_set *) buf_ptr;
WMITLV_SET_HDR(he_mcs, WMITLV_TAG_STRUC_wmi_he_rate_set,
WMITLV_GET_STRUCT_TLVLEN(wmi_he_rate_set));
he_mcs->rx_mcs_set = param->peer_he_rx_mcs_set[i];
he_mcs->tx_mcs_set = param->peer_he_tx_mcs_set[i];
WMI_LOGD("%s:HE idx %d RxMCSmap %x TxMCSmap %x ", __func__,
i, he_mcs->rx_mcs_set, he_mcs->tx_mcs_set);
buf_ptr += sizeof(wmi_he_rate_set);
}
WMI_LOGD("%s: vdev_id %d associd %d peer_flags %x rate_caps %x "
"peer_caps %x listen_intval %d ht_caps %x max_mpdu %d "
"nss %d phymode %d peer_mpdu_density %d "
"cmd->peer_vht_caps %x "
"HE cap_info %x ops %x "
"HE cap_info_ext %x "
"HE phy %x %x %x "
"peer_bw_rxnss_override %x", __func__,
cmd->vdev_id, cmd->peer_associd, cmd->peer_flags,
cmd->peer_rate_caps, cmd->peer_caps,
cmd->peer_listen_intval, cmd->peer_ht_caps,
cmd->peer_max_mpdu, cmd->peer_nss, cmd->peer_phymode,
cmd->peer_mpdu_density,
cmd->peer_vht_caps, cmd->peer_he_cap_info,
cmd->peer_he_ops, cmd->peer_he_cap_info_ext,
cmd->peer_he_cap_phy[0], cmd->peer_he_cap_phy[1],
cmd->peer_he_cap_phy[2],
cmd->peer_bw_rxnss_override);
wmi_mtrace(WMI_PEER_ASSOC_CMDID, cmd->vdev_id, 0);
ret = wmi_unified_cmd_send(wmi_handle, buf, len,
WMI_PEER_ASSOC_CMDID);
if (QDF_IS_STATUS_ERROR(ret)) {
WMI_LOGP("%s: Failed to send peer assoc command ret = %d",
__func__, ret);
wmi_buf_free(buf);
}
return ret;
}
/* copy_scan_notify_events() - Helper routine to copy scan notify events
*/
static inline void copy_scan_event_cntrl_flags(
wmi_start_scan_cmd_fixed_param * cmd,
struct scan_req_params *param)
{
/* Scan events subscription */
if (param->scan_ev_started)
cmd->notify_scan_events |= WMI_SCAN_EVENT_STARTED;
if (param->scan_ev_completed)
cmd->notify_scan_events |= WMI_SCAN_EVENT_COMPLETED;
if (param->scan_ev_bss_chan)
cmd->notify_scan_events |= WMI_SCAN_EVENT_BSS_CHANNEL;
if (param->scan_ev_foreign_chan)
cmd->notify_scan_events |= WMI_SCAN_EVENT_FOREIGN_CHANNEL;
if (param->scan_ev_dequeued)
cmd->notify_scan_events |= WMI_SCAN_EVENT_DEQUEUED;
if (param->scan_ev_preempted)
cmd->notify_scan_events |= WMI_SCAN_EVENT_PREEMPTED;
if (param->scan_ev_start_failed)
cmd->notify_scan_events |= WMI_SCAN_EVENT_START_FAILED;
if (param->scan_ev_restarted)
cmd->notify_scan_events |= WMI_SCAN_EVENT_RESTARTED;
if (param->scan_ev_foreign_chn_exit)
cmd->notify_scan_events |= WMI_SCAN_EVENT_FOREIGN_CHANNEL_EXIT;
if (param->scan_ev_suspended)
cmd->notify_scan_events |= WMI_SCAN_EVENT_SUSPENDED;
if (param->scan_ev_resumed)
cmd->notify_scan_events |= WMI_SCAN_EVENT_RESUMED;
/** Set scan control flags */
cmd->scan_ctrl_flags = 0;
if (param->scan_f_passive)
cmd->scan_ctrl_flags |= WMI_SCAN_FLAG_PASSIVE;
if (param->scan_f_strict_passive_pch)
cmd->scan_ctrl_flags |= WMI_SCAN_FLAG_STRICT_PASSIVE_ON_PCHN;
if (param->scan_f_promisc_mode)
cmd->scan_ctrl_flags |= WMI_SCAN_FILTER_PROMISCOUS;
if (param->scan_f_capture_phy_err)
cmd->scan_ctrl_flags |= WMI_SCAN_CAPTURE_PHY_ERROR;
if (param->scan_f_half_rate)
cmd->scan_ctrl_flags |= WMI_SCAN_FLAG_HALF_RATE_SUPPORT;
if (param->scan_f_quarter_rate)
cmd->scan_ctrl_flags |= WMI_SCAN_FLAG_QUARTER_RATE_SUPPORT;
if (param->scan_f_cck_rates)
cmd->scan_ctrl_flags |= WMI_SCAN_ADD_CCK_RATES;
if (param->scan_f_ofdm_rates)
cmd->scan_ctrl_flags |= WMI_SCAN_ADD_OFDM_RATES;
if (param->scan_f_chan_stat_evnt)
cmd->scan_ctrl_flags |= WMI_SCAN_CHAN_STAT_EVENT;
if (param->scan_f_filter_prb_req)
cmd->scan_ctrl_flags |= WMI_SCAN_FILTER_PROBE_REQ;
if (param->scan_f_bcast_probe)
cmd->scan_ctrl_flags |= WMI_SCAN_ADD_BCAST_PROBE_REQ;
if (param->scan_f_offchan_mgmt_tx)
cmd->scan_ctrl_flags |= WMI_SCAN_OFFCHAN_MGMT_TX;
if (param->scan_f_offchan_data_tx)
cmd->scan_ctrl_flags |= WMI_SCAN_OFFCHAN_DATA_TX;
if (param->scan_f_force_active_dfs_chn)
cmd->scan_ctrl_flags |= WMI_SCAN_FLAG_FORCE_ACTIVE_ON_DFS;
if (param->scan_f_add_tpc_ie_in_probe)
cmd->scan_ctrl_flags |= WMI_SCAN_ADD_TPC_IE_IN_PROBE_REQ;
if (param->scan_f_add_ds_ie_in_probe)
cmd->scan_ctrl_flags |= WMI_SCAN_ADD_DS_IE_IN_PROBE_REQ;
if (param->scan_f_add_spoofed_mac_in_probe)
cmd->scan_ctrl_flags |= WMI_SCAN_ADD_SPOOFED_MAC_IN_PROBE_REQ;
if (param->scan_f_add_rand_seq_in_probe)
cmd->scan_ctrl_flags |= WMI_SCAN_RANDOM_SEQ_NO_IN_PROBE_REQ;
if (param->scan_f_en_ie_whitelist_in_probe)
cmd->scan_ctrl_flags |=
WMI_SCAN_ENABLE_IE_WHTELIST_IN_PROBE_REQ;
/* for adaptive scan mode using 3 bits (21 - 23 bits) */
WMI_SCAN_SET_DWELL_MODE(cmd->scan_ctrl_flags,
param->adaptive_dwell_time_mode);
}
/* scan_copy_ie_buffer() - Copy scan ie_data */
static inline void scan_copy_ie_buffer(uint8_t *buf_ptr,
struct scan_req_params *params)
{
qdf_mem_copy(buf_ptr, params->extraie.ptr, params->extraie.len);
}
/**
* wmi_copy_scan_random_mac() - To copy scan randomization attrs to wmi buffer
* @mac: random mac addr
* @mask: random mac mask
* @mac_addr: wmi random mac
* @mac_mask: wmi random mac mask
*
* Return None.
*/
static inline
void wmi_copy_scan_random_mac(uint8_t *mac, uint8_t *mask,
wmi_mac_addr *mac_addr, wmi_mac_addr *mac_mask)
{
WMI_CHAR_ARRAY_TO_MAC_ADDR(mac, mac_addr);
WMI_CHAR_ARRAY_TO_MAC_ADDR(mask, mac_mask);
}
/*
* wmi_fill_vendor_oui() - fill vendor OUIs
* @buf_ptr: pointer to wmi tlv buffer
* @num_vendor_oui: number of vendor OUIs to be filled
* @param_voui: pointer to OUI buffer
*
* This function populates the wmi tlv buffer when vendor specific OUIs are
* present.
*
* Return: None
*/
static inline
void wmi_fill_vendor_oui(uint8_t *buf_ptr, uint32_t num_vendor_oui,
uint32_t *pvoui)
{
wmi_vendor_oui *voui = NULL;
uint32_t i;
voui = (wmi_vendor_oui *)buf_ptr;
for (i = 0; i < num_vendor_oui; i++) {
WMITLV_SET_HDR(&voui[i].tlv_header,
WMITLV_TAG_STRUC_wmi_vendor_oui,
WMITLV_GET_STRUCT_TLVLEN(wmi_vendor_oui));
voui[i].oui_type_subtype = pvoui[i];
}
}
/*
* wmi_fill_ie_whitelist_attrs() - fill IE whitelist attrs
* @ie_bitmap: output pointer to ie bit map in cmd
* @num_vendor_oui: output pointer to num vendor OUIs
* @ie_whitelist: input parameter
*
* This function populates the IE whitelist attrs of scan, pno and
* scan oui commands for ie_whitelist parameter.
*
* Return: None
*/
static inline
void wmi_fill_ie_whitelist_attrs(uint32_t *ie_bitmap,
uint32_t *num_vendor_oui,
struct probe_req_whitelist_attr *ie_whitelist)
{
uint32_t i = 0;
for (i = 0; i < PROBE_REQ_BITMAP_LEN; i++)
ie_bitmap[i] = ie_whitelist->ie_bitmap[i];
*num_vendor_oui = ie_whitelist->num_vendor_oui;
}
/**
* send_scan_start_cmd_tlv() - WMI scan start function
* @param wmi_handle : handle to WMI.
* @param param : pointer to hold scan start cmd parameter
*
* Return: 0 on success and -ve on failure.
*/
static QDF_STATUS send_scan_start_cmd_tlv(wmi_unified_t wmi_handle,
struct scan_req_params *params)
{
int32_t ret = 0;
int32_t i;
wmi_buf_t wmi_buf;
wmi_start_scan_cmd_fixed_param *cmd;
uint8_t *buf_ptr;
uint32_t *tmp_ptr;
wmi_ssid *ssid = NULL;
wmi_mac_addr *bssid;
size_t len = sizeof(*cmd);
uint16_t extraie_len_with_pad = 0;
uint8_t phymode_roundup = 0;
struct probe_req_whitelist_attr *ie_whitelist = &params->ie_whitelist;
/* Length TLV placeholder for array of uint32_t */
len += WMI_TLV_HDR_SIZE;
/* calculate the length of buffer required */
if (params->chan_list.num_chan)
len += params->chan_list.num_chan * sizeof(uint32_t);
/* Length TLV placeholder for array of wmi_ssid structures */
len += WMI_TLV_HDR_SIZE;
if (params->num_ssids)
len += params->num_ssids * sizeof(wmi_ssid);
/* Length TLV placeholder for array of wmi_mac_addr structures */
len += WMI_TLV_HDR_SIZE;
if (params->num_bssid)
len += sizeof(wmi_mac_addr) * params->num_bssid;
/* Length TLV placeholder for array of bytes */
len += WMI_TLV_HDR_SIZE;
if (params->extraie.len)
extraie_len_with_pad =
roundup(params->extraie.len, sizeof(uint32_t));
len += extraie_len_with_pad;
len += WMI_TLV_HDR_SIZE; /* Length of TLV for array of wmi_vendor_oui */
if (ie_whitelist->num_vendor_oui)
len += ie_whitelist->num_vendor_oui * sizeof(wmi_vendor_oui);
len += WMI_TLV_HDR_SIZE; /* Length of TLV for array of scan phymode */
if (params->scan_f_wide_band)
phymode_roundup =
qdf_roundup(params->chan_list.num_chan * sizeof(uint8_t),
sizeof(uint32_t));
len += phymode_roundup;
/* Allocate the memory */
wmi_buf = wmi_buf_alloc(wmi_handle, len);
if (!wmi_buf)
return QDF_STATUS_E_FAILURE;
buf_ptr = (uint8_t *) wmi_buf_data(wmi_buf);
cmd = (wmi_start_scan_cmd_fixed_param *) buf_ptr;
WMITLV_SET_HDR(&cmd->tlv_header,
WMITLV_TAG_STRUC_wmi_start_scan_cmd_fixed_param,
WMITLV_GET_STRUCT_TLVLEN
(wmi_start_scan_cmd_fixed_param));
cmd->scan_id = params->scan_id;
cmd->scan_req_id = params->scan_req_id;
cmd->vdev_id = params->vdev_id;
cmd->scan_priority = params->scan_priority;
copy_scan_event_cntrl_flags(cmd, params);
cmd->dwell_time_active = params->dwell_time_active;
cmd->dwell_time_active_2g = params->dwell_time_active_2g;
cmd->dwell_time_passive = params->dwell_time_passive;
cmd->min_rest_time = params->min_rest_time;
cmd->max_rest_time = params->max_rest_time;
cmd->repeat_probe_time = params->repeat_probe_time;
cmd->probe_spacing_time = params->probe_spacing_time;
cmd->idle_time = params->idle_time;
cmd->max_scan_time = params->max_scan_time;
cmd->probe_delay = params->probe_delay;
cmd->burst_duration = params->burst_duration;
cmd->num_chan = params->chan_list.num_chan;
cmd->num_bssid = params->num_bssid;
cmd->num_ssids = params->num_ssids;
cmd->ie_len = params->extraie.len;
cmd->n_probes = params->n_probes;
cmd->scan_ctrl_flags_ext = params->scan_ctrl_flags_ext;
if (params->scan_random.randomize)
wmi_copy_scan_random_mac(params->scan_random.mac_addr,
params->scan_random.mac_mask,
&cmd->mac_addr,
&cmd->mac_mask);
if (ie_whitelist->white_list)
wmi_fill_ie_whitelist_attrs(cmd->ie_bitmap,
&cmd->num_vendor_oui,
ie_whitelist);
buf_ptr += sizeof(*cmd);
tmp_ptr = (uint32_t *) (buf_ptr + WMI_TLV_HDR_SIZE);
for (i = 0; i < params->chan_list.num_chan; ++i)
tmp_ptr[i] = params->chan_list.chan[i].freq;
WMITLV_SET_HDR(buf_ptr,
WMITLV_TAG_ARRAY_UINT32,
(params->chan_list.num_chan * sizeof(uint32_t)));
buf_ptr += WMI_TLV_HDR_SIZE +
(params->chan_list.num_chan * sizeof(uint32_t));
if (params->num_ssids > WLAN_SCAN_MAX_NUM_SSID) {
WMI_LOGE("Invalid value for num_ssids %d", params->num_ssids);
goto error;
}
WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_FIXED_STRUC,
(params->num_ssids * sizeof(wmi_ssid)));
if (params->num_ssids) {
ssid = (wmi_ssid *) (buf_ptr + WMI_TLV_HDR_SIZE);
for (i = 0; i < params->num_ssids; ++i) {
ssid->ssid_len = params->ssid[i].length;
qdf_mem_copy(ssid->ssid, params->ssid[i].ssid,
params->ssid[i].length);
ssid++;
}
}
buf_ptr += WMI_TLV_HDR_SIZE + (params->num_ssids * sizeof(wmi_ssid));
WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_FIXED_STRUC,
(params->num_bssid * sizeof(wmi_mac_addr)));
bssid = (wmi_mac_addr *) (buf_ptr + WMI_TLV_HDR_SIZE);
if (params->num_bssid) {
for (i = 0; i < params->num_bssid; ++i) {
WMI_CHAR_ARRAY_TO_MAC_ADDR(
&params->bssid_list[i].bytes[0], bssid);
bssid++;
}
}
buf_ptr += WMI_TLV_HDR_SIZE +
(params->num_bssid * sizeof(wmi_mac_addr));
WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, extraie_len_with_pad);
if (params->extraie.len)
scan_copy_ie_buffer(buf_ptr + WMI_TLV_HDR_SIZE,
params);
buf_ptr += WMI_TLV_HDR_SIZE + extraie_len_with_pad;
/* probe req ie whitelisting */
WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
ie_whitelist->num_vendor_oui * sizeof(wmi_vendor_oui));
buf_ptr += WMI_TLV_HDR_SIZE;
if (cmd->num_vendor_oui) {
wmi_fill_vendor_oui(buf_ptr, cmd->num_vendor_oui,
ie_whitelist->voui);
buf_ptr += cmd->num_vendor_oui * sizeof(wmi_vendor_oui);
}
/* Add phy mode TLV if it's a wide band scan */
if (params->scan_f_wide_band) {
WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, phymode_roundup);
buf_ptr = (uint8_t *) (buf_ptr + WMI_TLV_HDR_SIZE);
for (i = 0; i < params->chan_list.num_chan; ++i)
buf_ptr[i] =
WMI_SCAN_CHAN_SET_MODE(params->chan_list.chan[i].phymode);
buf_ptr += phymode_roundup;
} else {
/* Add ZERO legth phy mode TLV */
WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, 0);
}
wmi_mtrace(WMI_START_SCAN_CMDID, cmd->vdev_id, 0);
ret = wmi_unified_cmd_send(wmi_handle, wmi_buf,
len, WMI_START_SCAN_CMDID);
if (ret) {
WMI_LOGE("%s: Failed to start scan: %d", __func__, ret);
wmi_buf_free(wmi_buf);
}
return ret;
error:
wmi_buf_free(wmi_buf);
return QDF_STATUS_E_FAILURE;
}
/**
* send_scan_stop_cmd_tlv() - WMI scan start function
* @param wmi_handle : handle to WMI.
* @param param : pointer to hold scan cancel cmd parameter
*
* Return: 0 on success and -ve on failure.
*/
static QDF_STATUS send_scan_stop_cmd_tlv(wmi_unified_t wmi_handle,
struct scan_cancel_param *param)
{
wmi_stop_scan_cmd_fixed_param *cmd;
int ret;
int len = sizeof(*cmd);
wmi_buf_t wmi_buf;
/* Allocate the memory */
wmi_buf = wmi_buf_alloc(wmi_handle, len);
if (!wmi_buf) {
ret = QDF_STATUS_E_NOMEM;
goto error;
}
cmd = (wmi_stop_scan_cmd_fixed_param *) wmi_buf_data(wmi_buf);
WMITLV_SET_HDR(&cmd->tlv_header,
WMITLV_TAG_STRUC_wmi_stop_scan_cmd_fixed_param,
WMITLV_GET_STRUCT_TLVLEN(wmi_stop_scan_cmd_fixed_param));
cmd->vdev_id = param->vdev_id;
cmd->requestor = param->requester;
cmd->scan_id = param->scan_id;
cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target(
param->pdev_id);
/* stop the scan with the corresponding scan_id */
if (param->req_type == WLAN_SCAN_CANCEL_PDEV_ALL) {
/* Cancelling all scans */
cmd->req_type = WMI_SCAN_STOP_ALL;
} else if (param->req_type == WLAN_SCAN_CANCEL_VDEV_ALL) {
/* Cancelling VAP scans */
cmd->req_type = WMI_SCN_STOP_VAP_ALL;
} else if (param->req_type == WLAN_SCAN_CANCEL_SINGLE) {
/* Cancelling specific scan */
cmd->req_type = WMI_SCAN_STOP_ONE;
} else {
WMI_LOGE("%s: Invalid Command : ", __func__);
wmi_buf_free(wmi_buf);
return QDF_STATUS_E_INVAL;
}
wmi_mtrace(WMI_STOP_SCAN_CMDID, cmd->vdev_id, 0);
ret = wmi_unified_cmd_send(wmi_handle, wmi_buf,
len, WMI_STOP_SCAN_CMDID);
if (ret) {
WMI_LOGE("%s: Failed to send stop scan: %d", __func__, ret);
wmi_buf_free(wmi_buf);
}
error:
return ret;
}
#define WMI_MAX_CHAN_INFO_LOG 192
/**
* wmi_scan_chanlist_dump() - Dump scan channel list info
* @scan_chan_list: scan channel list
*
* Return: void
*/
static void wmi_scan_chanlist_dump(struct scan_chan_list_params *scan_chan_list)
{
uint32_t i;
uint8_t info[WMI_MAX_CHAN_INFO_LOG];
uint32_t len = 0;
struct channel_param *chan;
int ret;
wmi_debug("Total chan %d", scan_chan_list->nallchans);
for (i = 0; i < scan_chan_list->nallchans; i++) {
chan = &scan_chan_list->ch_param[i];
ret = qdf_scnprintf(info + len, sizeof(info) - len,
" %d[%d][%d]", chan->mhz, chan->maxregpower,
chan->dfs_set);
if (ret <= 0)
break;
len += ret;
if (len >= (sizeof(info) - 20)) {
wmi_nofl_debug("Chan[TXPwr][DFS]:%s", info);
len = 0;
}
}
if (len)
wmi_nofl_debug("Chan[TXPwr][DFS]:%s", info);
}
static QDF_STATUS send_scan_chan_list_cmd_tlv(wmi_unified_t wmi_handle,
struct scan_chan_list_params *chan_list)
{
wmi_buf_t buf;
QDF_STATUS qdf_status;
wmi_scan_chan_list_cmd_fixed_param *cmd;
int i;
uint8_t *buf_ptr;
wmi_channel *chan_info;
struct channel_param *tchan_info;
uint16_t len = sizeof(*cmd) + WMI_TLV_HDR_SIZE;
wmi_scan_chanlist_dump(chan_list);
len += sizeof(wmi_channel) * chan_list->nallchans;
buf = wmi_buf_alloc(wmi_handle, len);
if (!buf) {
qdf_status = QDF_STATUS_E_NOMEM;
goto end;
}
buf_ptr = (uint8_t *) wmi_buf_data(buf);
cmd = (wmi_scan_chan_list_cmd_fixed_param *) buf_ptr;
WMITLV_SET_HDR(&cmd->tlv_header,
WMITLV_TAG_STRUC_wmi_scan_chan_list_cmd_fixed_param,
WMITLV_GET_STRUCT_TLVLEN
(wmi_scan_chan_list_cmd_fixed_param));
if (chan_list->append)
cmd->flags |= APPEND_TO_EXISTING_CHAN_LIST;
if (chan_list->max_bw_support_present)
cmd->flags |= CHANNEL_MAX_BANDWIDTH_VALID;
cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target(
chan_list->pdev_id);
cmd->num_scan_chans = chan_list->nallchans;
WMITLV_SET_HDR((buf_ptr + sizeof(wmi_scan_chan_list_cmd_fixed_param)),
WMITLV_TAG_ARRAY_STRUC,
sizeof(wmi_channel) * chan_list->nallchans);
chan_info = (wmi_channel *) (buf_ptr + sizeof(*cmd) + WMI_TLV_HDR_SIZE);
tchan_info = &(chan_list->ch_param[0]);
for (i = 0; i < chan_list->nallchans; ++i) {
WMITLV_SET_HDR(&chan_info->tlv_header,
WMITLV_TAG_STRUC_wmi_channel,
WMITLV_GET_STRUCT_TLVLEN(wmi_channel));
chan_info->mhz = tchan_info->mhz;
chan_info->band_center_freq1 =
tchan_info->cfreq1;
chan_info->band_center_freq2 =
tchan_info->cfreq2;