162306a36Sopenharmony_ci// SPDX-License-Identifier: ISC 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci * Copyright (c) 2005-2011 Atheros Communications Inc. 462306a36Sopenharmony_ci * Copyright (c) 2011-2017 Qualcomm Atheros, Inc. 562306a36Sopenharmony_ci * Copyright (c) 2018-2019, The Linux Foundation. All rights reserved. 662306a36Sopenharmony_ci */ 762306a36Sopenharmony_ci#include "core.h" 862306a36Sopenharmony_ci#include "debug.h" 962306a36Sopenharmony_ci#include "mac.h" 1062306a36Sopenharmony_ci#include "hw.h" 1162306a36Sopenharmony_ci#include "wmi.h" 1262306a36Sopenharmony_ci#include "wmi-ops.h" 1362306a36Sopenharmony_ci#include "wmi-tlv.h" 1462306a36Sopenharmony_ci#include "p2p.h" 1562306a36Sopenharmony_ci#include "testmode.h" 1662306a36Sopenharmony_ci#include <linux/bitfield.h> 1762306a36Sopenharmony_ci 1862306a36Sopenharmony_ci/***************/ 1962306a36Sopenharmony_ci/* TLV helpers */ 2062306a36Sopenharmony_ci/**************/ 2162306a36Sopenharmony_ci 2262306a36Sopenharmony_cistruct wmi_tlv_policy { 2362306a36Sopenharmony_ci size_t min_len; 2462306a36Sopenharmony_ci}; 2562306a36Sopenharmony_ci 2662306a36Sopenharmony_cistatic const struct wmi_tlv_policy wmi_tlv_policies[] = { 2762306a36Sopenharmony_ci [WMI_TLV_TAG_ARRAY_BYTE] 2862306a36Sopenharmony_ci = { .min_len = 0 }, 2962306a36Sopenharmony_ci [WMI_TLV_TAG_ARRAY_UINT32] 3062306a36Sopenharmony_ci = { .min_len = 0 }, 3162306a36Sopenharmony_ci [WMI_TLV_TAG_STRUCT_SCAN_EVENT] 3262306a36Sopenharmony_ci = { .min_len = sizeof(struct wmi_scan_event) }, 3362306a36Sopenharmony_ci [WMI_TLV_TAG_STRUCT_MGMT_RX_HDR] 3462306a36Sopenharmony_ci = { .min_len = sizeof(struct wmi_tlv_mgmt_rx_ev) }, 3562306a36Sopenharmony_ci [WMI_TLV_TAG_STRUCT_CHAN_INFO_EVENT] 3662306a36Sopenharmony_ci = { .min_len = sizeof(struct wmi_chan_info_event) }, 3762306a36Sopenharmony_ci [WMI_TLV_TAG_STRUCT_VDEV_START_RESPONSE_EVENT] 3862306a36Sopenharmony_ci = { .min_len = sizeof(struct wmi_vdev_start_response_event) }, 3962306a36Sopenharmony_ci [WMI_TLV_TAG_STRUCT_PEER_STA_KICKOUT_EVENT] 4062306a36Sopenharmony_ci = { .min_len = sizeof(struct wmi_peer_sta_kickout_event) }, 4162306a36Sopenharmony_ci [WMI_TLV_TAG_STRUCT_HOST_SWBA_EVENT] 4262306a36Sopenharmony_ci = { .min_len = sizeof(struct wmi_host_swba_event) }, 4362306a36Sopenharmony_ci [WMI_TLV_TAG_STRUCT_TIM_INFO] 4462306a36Sopenharmony_ci = { .min_len = sizeof(struct wmi_tim_info) }, 4562306a36Sopenharmony_ci [WMI_TLV_TAG_STRUCT_P2P_NOA_INFO] 4662306a36Sopenharmony_ci = { .min_len = sizeof(struct wmi_p2p_noa_info) }, 4762306a36Sopenharmony_ci [WMI_TLV_TAG_STRUCT_SERVICE_READY_EVENT] 4862306a36Sopenharmony_ci = { .min_len = sizeof(struct wmi_tlv_svc_rdy_ev) }, 4962306a36Sopenharmony_ci [WMI_TLV_TAG_STRUCT_HAL_REG_CAPABILITIES] 5062306a36Sopenharmony_ci = { .min_len = sizeof(struct hal_reg_capabilities) }, 5162306a36Sopenharmony_ci [WMI_TLV_TAG_STRUCT_WLAN_HOST_MEM_REQ] 5262306a36Sopenharmony_ci = { .min_len = sizeof(struct wlan_host_mem_req) }, 5362306a36Sopenharmony_ci [WMI_TLV_TAG_STRUCT_READY_EVENT] 5462306a36Sopenharmony_ci = { .min_len = sizeof(struct wmi_tlv_rdy_ev) }, 5562306a36Sopenharmony_ci [WMI_TLV_TAG_STRUCT_OFFLOAD_BCN_TX_STATUS_EVENT] 5662306a36Sopenharmony_ci = { .min_len = sizeof(struct wmi_tlv_bcn_tx_status_ev) }, 5762306a36Sopenharmony_ci [WMI_TLV_TAG_STRUCT_DIAG_DATA_CONTAINER_EVENT] 5862306a36Sopenharmony_ci = { .min_len = sizeof(struct wmi_tlv_diag_data_ev) }, 5962306a36Sopenharmony_ci [WMI_TLV_TAG_STRUCT_P2P_NOA_EVENT] 6062306a36Sopenharmony_ci = { .min_len = sizeof(struct wmi_tlv_p2p_noa_ev) }, 6162306a36Sopenharmony_ci [WMI_TLV_TAG_STRUCT_ROAM_EVENT] 6262306a36Sopenharmony_ci = { .min_len = sizeof(struct wmi_tlv_roam_ev) }, 6362306a36Sopenharmony_ci [WMI_TLV_TAG_STRUCT_WOW_EVENT_INFO] 6462306a36Sopenharmony_ci = { .min_len = sizeof(struct wmi_tlv_wow_event_info) }, 6562306a36Sopenharmony_ci [WMI_TLV_TAG_STRUCT_TX_PAUSE_EVENT] 6662306a36Sopenharmony_ci = { .min_len = sizeof(struct wmi_tlv_tx_pause_ev) }, 6762306a36Sopenharmony_ci}; 6862306a36Sopenharmony_ci 6962306a36Sopenharmony_cistatic int 7062306a36Sopenharmony_ciath10k_wmi_tlv_iter(struct ath10k *ar, const void *ptr, size_t len, 7162306a36Sopenharmony_ci int (*iter)(struct ath10k *ar, u16 tag, u16 len, 7262306a36Sopenharmony_ci const void *ptr, void *data), 7362306a36Sopenharmony_ci void *data) 7462306a36Sopenharmony_ci{ 7562306a36Sopenharmony_ci const void *begin = ptr; 7662306a36Sopenharmony_ci const struct wmi_tlv *tlv; 7762306a36Sopenharmony_ci u16 tlv_tag, tlv_len; 7862306a36Sopenharmony_ci int ret; 7962306a36Sopenharmony_ci 8062306a36Sopenharmony_ci while (len > 0) { 8162306a36Sopenharmony_ci if (len < sizeof(*tlv)) { 8262306a36Sopenharmony_ci ath10k_dbg(ar, ATH10K_DBG_WMI, 8362306a36Sopenharmony_ci "wmi tlv parse failure at byte %zd (%zu bytes left, %zu expected)\n", 8462306a36Sopenharmony_ci ptr - begin, len, sizeof(*tlv)); 8562306a36Sopenharmony_ci return -EINVAL; 8662306a36Sopenharmony_ci } 8762306a36Sopenharmony_ci 8862306a36Sopenharmony_ci tlv = ptr; 8962306a36Sopenharmony_ci tlv_tag = __le16_to_cpu(tlv->tag); 9062306a36Sopenharmony_ci tlv_len = __le16_to_cpu(tlv->len); 9162306a36Sopenharmony_ci ptr += sizeof(*tlv); 9262306a36Sopenharmony_ci len -= sizeof(*tlv); 9362306a36Sopenharmony_ci 9462306a36Sopenharmony_ci if (tlv_len > len) { 9562306a36Sopenharmony_ci ath10k_dbg(ar, ATH10K_DBG_WMI, 9662306a36Sopenharmony_ci "wmi tlv parse failure of tag %u at byte %zd (%zu bytes left, %u expected)\n", 9762306a36Sopenharmony_ci tlv_tag, ptr - begin, len, tlv_len); 9862306a36Sopenharmony_ci return -EINVAL; 9962306a36Sopenharmony_ci } 10062306a36Sopenharmony_ci 10162306a36Sopenharmony_ci if (tlv_tag < ARRAY_SIZE(wmi_tlv_policies) && 10262306a36Sopenharmony_ci wmi_tlv_policies[tlv_tag].min_len && 10362306a36Sopenharmony_ci wmi_tlv_policies[tlv_tag].min_len > tlv_len) { 10462306a36Sopenharmony_ci ath10k_dbg(ar, ATH10K_DBG_WMI, 10562306a36Sopenharmony_ci "wmi tlv parse failure of tag %u at byte %zd (%u bytes is less than min length %zu)\n", 10662306a36Sopenharmony_ci tlv_tag, ptr - begin, tlv_len, 10762306a36Sopenharmony_ci wmi_tlv_policies[tlv_tag].min_len); 10862306a36Sopenharmony_ci return -EINVAL; 10962306a36Sopenharmony_ci } 11062306a36Sopenharmony_ci 11162306a36Sopenharmony_ci ret = iter(ar, tlv_tag, tlv_len, ptr, data); 11262306a36Sopenharmony_ci if (ret) 11362306a36Sopenharmony_ci return ret; 11462306a36Sopenharmony_ci 11562306a36Sopenharmony_ci ptr += tlv_len; 11662306a36Sopenharmony_ci len -= tlv_len; 11762306a36Sopenharmony_ci } 11862306a36Sopenharmony_ci 11962306a36Sopenharmony_ci return 0; 12062306a36Sopenharmony_ci} 12162306a36Sopenharmony_ci 12262306a36Sopenharmony_cistatic int ath10k_wmi_tlv_iter_parse(struct ath10k *ar, u16 tag, u16 len, 12362306a36Sopenharmony_ci const void *ptr, void *data) 12462306a36Sopenharmony_ci{ 12562306a36Sopenharmony_ci const void **tb = data; 12662306a36Sopenharmony_ci 12762306a36Sopenharmony_ci if (tag < WMI_TLV_TAG_MAX) 12862306a36Sopenharmony_ci tb[tag] = ptr; 12962306a36Sopenharmony_ci 13062306a36Sopenharmony_ci return 0; 13162306a36Sopenharmony_ci} 13262306a36Sopenharmony_ci 13362306a36Sopenharmony_cistatic int ath10k_wmi_tlv_parse(struct ath10k *ar, const void **tb, 13462306a36Sopenharmony_ci const void *ptr, size_t len) 13562306a36Sopenharmony_ci{ 13662306a36Sopenharmony_ci return ath10k_wmi_tlv_iter(ar, ptr, len, ath10k_wmi_tlv_iter_parse, 13762306a36Sopenharmony_ci (void *)tb); 13862306a36Sopenharmony_ci} 13962306a36Sopenharmony_ci 14062306a36Sopenharmony_cistatic const void ** 14162306a36Sopenharmony_ciath10k_wmi_tlv_parse_alloc(struct ath10k *ar, const void *ptr, 14262306a36Sopenharmony_ci size_t len, gfp_t gfp) 14362306a36Sopenharmony_ci{ 14462306a36Sopenharmony_ci const void **tb; 14562306a36Sopenharmony_ci int ret; 14662306a36Sopenharmony_ci 14762306a36Sopenharmony_ci tb = kcalloc(WMI_TLV_TAG_MAX, sizeof(*tb), gfp); 14862306a36Sopenharmony_ci if (!tb) 14962306a36Sopenharmony_ci return ERR_PTR(-ENOMEM); 15062306a36Sopenharmony_ci 15162306a36Sopenharmony_ci ret = ath10k_wmi_tlv_parse(ar, tb, ptr, len); 15262306a36Sopenharmony_ci if (ret) { 15362306a36Sopenharmony_ci kfree(tb); 15462306a36Sopenharmony_ci return ERR_PTR(ret); 15562306a36Sopenharmony_ci } 15662306a36Sopenharmony_ci 15762306a36Sopenharmony_ci return tb; 15862306a36Sopenharmony_ci} 15962306a36Sopenharmony_ci 16062306a36Sopenharmony_cistatic u16 ath10k_wmi_tlv_len(const void *ptr) 16162306a36Sopenharmony_ci{ 16262306a36Sopenharmony_ci return __le16_to_cpu((((const struct wmi_tlv *)ptr) - 1)->len); 16362306a36Sopenharmony_ci} 16462306a36Sopenharmony_ci 16562306a36Sopenharmony_ci/**************/ 16662306a36Sopenharmony_ci/* TLV events */ 16762306a36Sopenharmony_ci/**************/ 16862306a36Sopenharmony_cistatic int ath10k_wmi_tlv_event_bcn_tx_status(struct ath10k *ar, 16962306a36Sopenharmony_ci struct sk_buff *skb) 17062306a36Sopenharmony_ci{ 17162306a36Sopenharmony_ci const void **tb; 17262306a36Sopenharmony_ci const struct wmi_tlv_bcn_tx_status_ev *ev; 17362306a36Sopenharmony_ci struct ath10k_vif *arvif; 17462306a36Sopenharmony_ci u32 vdev_id, tx_status; 17562306a36Sopenharmony_ci int ret; 17662306a36Sopenharmony_ci 17762306a36Sopenharmony_ci tb = ath10k_wmi_tlv_parse_alloc(ar, skb->data, skb->len, GFP_ATOMIC); 17862306a36Sopenharmony_ci if (IS_ERR(tb)) { 17962306a36Sopenharmony_ci ret = PTR_ERR(tb); 18062306a36Sopenharmony_ci ath10k_warn(ar, "failed to parse tlv: %d\n", ret); 18162306a36Sopenharmony_ci return ret; 18262306a36Sopenharmony_ci } 18362306a36Sopenharmony_ci 18462306a36Sopenharmony_ci ev = tb[WMI_TLV_TAG_STRUCT_OFFLOAD_BCN_TX_STATUS_EVENT]; 18562306a36Sopenharmony_ci if (!ev) { 18662306a36Sopenharmony_ci kfree(tb); 18762306a36Sopenharmony_ci return -EPROTO; 18862306a36Sopenharmony_ci } 18962306a36Sopenharmony_ci 19062306a36Sopenharmony_ci tx_status = __le32_to_cpu(ev->tx_status); 19162306a36Sopenharmony_ci vdev_id = __le32_to_cpu(ev->vdev_id); 19262306a36Sopenharmony_ci 19362306a36Sopenharmony_ci switch (tx_status) { 19462306a36Sopenharmony_ci case WMI_TLV_BCN_TX_STATUS_OK: 19562306a36Sopenharmony_ci break; 19662306a36Sopenharmony_ci case WMI_TLV_BCN_TX_STATUS_XRETRY: 19762306a36Sopenharmony_ci case WMI_TLV_BCN_TX_STATUS_DROP: 19862306a36Sopenharmony_ci case WMI_TLV_BCN_TX_STATUS_FILTERED: 19962306a36Sopenharmony_ci /* FIXME: It's probably worth telling mac80211 to stop the 20062306a36Sopenharmony_ci * interface as it is crippled. 20162306a36Sopenharmony_ci */ 20262306a36Sopenharmony_ci ath10k_warn(ar, "received bcn tmpl tx status on vdev %i: %d", 20362306a36Sopenharmony_ci vdev_id, tx_status); 20462306a36Sopenharmony_ci break; 20562306a36Sopenharmony_ci } 20662306a36Sopenharmony_ci 20762306a36Sopenharmony_ci arvif = ath10k_get_arvif(ar, vdev_id); 20862306a36Sopenharmony_ci if (arvif && arvif->is_up && arvif->vif->bss_conf.csa_active) 20962306a36Sopenharmony_ci ieee80211_queue_work(ar->hw, &arvif->ap_csa_work); 21062306a36Sopenharmony_ci 21162306a36Sopenharmony_ci kfree(tb); 21262306a36Sopenharmony_ci return 0; 21362306a36Sopenharmony_ci} 21462306a36Sopenharmony_ci 21562306a36Sopenharmony_cistatic void ath10k_wmi_tlv_event_vdev_delete_resp(struct ath10k *ar, 21662306a36Sopenharmony_ci struct sk_buff *skb) 21762306a36Sopenharmony_ci{ 21862306a36Sopenharmony_ci ath10k_dbg(ar, ATH10K_DBG_WMI, "WMI_VDEV_DELETE_RESP_EVENTID\n"); 21962306a36Sopenharmony_ci complete(&ar->vdev_delete_done); 22062306a36Sopenharmony_ci} 22162306a36Sopenharmony_ci 22262306a36Sopenharmony_cistatic int ath10k_wmi_tlv_parse_peer_stats_info(struct ath10k *ar, u16 tag, u16 len, 22362306a36Sopenharmony_ci const void *ptr, void *data) 22462306a36Sopenharmony_ci{ 22562306a36Sopenharmony_ci const struct wmi_tlv_peer_stats_info *stat = ptr; 22662306a36Sopenharmony_ci struct ieee80211_sta *sta; 22762306a36Sopenharmony_ci struct ath10k_sta *arsta; 22862306a36Sopenharmony_ci 22962306a36Sopenharmony_ci if (tag != WMI_TLV_TAG_STRUCT_PEER_STATS_INFO) 23062306a36Sopenharmony_ci return -EPROTO; 23162306a36Sopenharmony_ci 23262306a36Sopenharmony_ci ath10k_dbg(ar, ATH10K_DBG_WMI, 23362306a36Sopenharmony_ci "wmi tlv stats peer addr %pMF rx rate code 0x%x bit rate %d kbps\n", 23462306a36Sopenharmony_ci stat->peer_macaddr.addr, 23562306a36Sopenharmony_ci __le32_to_cpu(stat->last_rx_rate_code), 23662306a36Sopenharmony_ci __le32_to_cpu(stat->last_rx_bitrate_kbps)); 23762306a36Sopenharmony_ci 23862306a36Sopenharmony_ci ath10k_dbg(ar, ATH10K_DBG_WMI, 23962306a36Sopenharmony_ci "wmi tlv stats tx rate code 0x%x bit rate %d kbps\n", 24062306a36Sopenharmony_ci __le32_to_cpu(stat->last_tx_rate_code), 24162306a36Sopenharmony_ci __le32_to_cpu(stat->last_tx_bitrate_kbps)); 24262306a36Sopenharmony_ci 24362306a36Sopenharmony_ci rcu_read_lock(); 24462306a36Sopenharmony_ci sta = ieee80211_find_sta_by_ifaddr(ar->hw, stat->peer_macaddr.addr, NULL); 24562306a36Sopenharmony_ci if (!sta) { 24662306a36Sopenharmony_ci rcu_read_unlock(); 24762306a36Sopenharmony_ci ath10k_warn(ar, "not found station for peer stats\n"); 24862306a36Sopenharmony_ci return -EINVAL; 24962306a36Sopenharmony_ci } 25062306a36Sopenharmony_ci 25162306a36Sopenharmony_ci arsta = (struct ath10k_sta *)sta->drv_priv; 25262306a36Sopenharmony_ci arsta->rx_rate_code = __le32_to_cpu(stat->last_rx_rate_code); 25362306a36Sopenharmony_ci arsta->rx_bitrate_kbps = __le32_to_cpu(stat->last_rx_bitrate_kbps); 25462306a36Sopenharmony_ci arsta->tx_rate_code = __le32_to_cpu(stat->last_tx_rate_code); 25562306a36Sopenharmony_ci arsta->tx_bitrate_kbps = __le32_to_cpu(stat->last_tx_bitrate_kbps); 25662306a36Sopenharmony_ci rcu_read_unlock(); 25762306a36Sopenharmony_ci 25862306a36Sopenharmony_ci return 0; 25962306a36Sopenharmony_ci} 26062306a36Sopenharmony_ci 26162306a36Sopenharmony_cistatic int ath10k_wmi_tlv_op_pull_peer_stats_info(struct ath10k *ar, 26262306a36Sopenharmony_ci struct sk_buff *skb) 26362306a36Sopenharmony_ci{ 26462306a36Sopenharmony_ci const void **tb; 26562306a36Sopenharmony_ci const struct wmi_tlv_peer_stats_info_ev *ev; 26662306a36Sopenharmony_ci const void *data; 26762306a36Sopenharmony_ci u32 num_peer_stats; 26862306a36Sopenharmony_ci int ret; 26962306a36Sopenharmony_ci 27062306a36Sopenharmony_ci tb = ath10k_wmi_tlv_parse_alloc(ar, skb->data, skb->len, GFP_ATOMIC); 27162306a36Sopenharmony_ci if (IS_ERR(tb)) { 27262306a36Sopenharmony_ci ret = PTR_ERR(tb); 27362306a36Sopenharmony_ci ath10k_warn(ar, "failed to parse tlv: %d\n", ret); 27462306a36Sopenharmony_ci return ret; 27562306a36Sopenharmony_ci } 27662306a36Sopenharmony_ci 27762306a36Sopenharmony_ci ev = tb[WMI_TLV_TAG_STRUCT_PEER_STATS_INFO_EVENT]; 27862306a36Sopenharmony_ci data = tb[WMI_TLV_TAG_ARRAY_STRUCT]; 27962306a36Sopenharmony_ci 28062306a36Sopenharmony_ci if (!ev || !data) { 28162306a36Sopenharmony_ci kfree(tb); 28262306a36Sopenharmony_ci return -EPROTO; 28362306a36Sopenharmony_ci } 28462306a36Sopenharmony_ci 28562306a36Sopenharmony_ci num_peer_stats = __le32_to_cpu(ev->num_peers); 28662306a36Sopenharmony_ci 28762306a36Sopenharmony_ci ath10k_dbg(ar, ATH10K_DBG_WMI, 28862306a36Sopenharmony_ci "wmi tlv peer stats info update peer vdev id %d peers %i more data %d\n", 28962306a36Sopenharmony_ci __le32_to_cpu(ev->vdev_id), 29062306a36Sopenharmony_ci num_peer_stats, 29162306a36Sopenharmony_ci __le32_to_cpu(ev->more_data)); 29262306a36Sopenharmony_ci 29362306a36Sopenharmony_ci ret = ath10k_wmi_tlv_iter(ar, data, ath10k_wmi_tlv_len(data), 29462306a36Sopenharmony_ci ath10k_wmi_tlv_parse_peer_stats_info, NULL); 29562306a36Sopenharmony_ci if (ret) 29662306a36Sopenharmony_ci ath10k_warn(ar, "failed to parse stats info tlv: %d\n", ret); 29762306a36Sopenharmony_ci 29862306a36Sopenharmony_ci kfree(tb); 29962306a36Sopenharmony_ci return 0; 30062306a36Sopenharmony_ci} 30162306a36Sopenharmony_ci 30262306a36Sopenharmony_cistatic void ath10k_wmi_tlv_event_peer_stats_info(struct ath10k *ar, 30362306a36Sopenharmony_ci struct sk_buff *skb) 30462306a36Sopenharmony_ci{ 30562306a36Sopenharmony_ci ath10k_dbg(ar, ATH10K_DBG_WMI, "WMI_PEER_STATS_INFO_EVENTID\n"); 30662306a36Sopenharmony_ci ath10k_wmi_tlv_op_pull_peer_stats_info(ar, skb); 30762306a36Sopenharmony_ci complete(&ar->peer_stats_info_complete); 30862306a36Sopenharmony_ci} 30962306a36Sopenharmony_ci 31062306a36Sopenharmony_cistatic int ath10k_wmi_tlv_event_diag_data(struct ath10k *ar, 31162306a36Sopenharmony_ci struct sk_buff *skb) 31262306a36Sopenharmony_ci{ 31362306a36Sopenharmony_ci const void **tb; 31462306a36Sopenharmony_ci const struct wmi_tlv_diag_data_ev *ev; 31562306a36Sopenharmony_ci const struct wmi_tlv_diag_item *item; 31662306a36Sopenharmony_ci const void *data; 31762306a36Sopenharmony_ci int ret, num_items, len; 31862306a36Sopenharmony_ci 31962306a36Sopenharmony_ci tb = ath10k_wmi_tlv_parse_alloc(ar, skb->data, skb->len, GFP_ATOMIC); 32062306a36Sopenharmony_ci if (IS_ERR(tb)) { 32162306a36Sopenharmony_ci ret = PTR_ERR(tb); 32262306a36Sopenharmony_ci ath10k_warn(ar, "failed to parse tlv: %d\n", ret); 32362306a36Sopenharmony_ci return ret; 32462306a36Sopenharmony_ci } 32562306a36Sopenharmony_ci 32662306a36Sopenharmony_ci ev = tb[WMI_TLV_TAG_STRUCT_DIAG_DATA_CONTAINER_EVENT]; 32762306a36Sopenharmony_ci data = tb[WMI_TLV_TAG_ARRAY_BYTE]; 32862306a36Sopenharmony_ci if (!ev || !data) { 32962306a36Sopenharmony_ci kfree(tb); 33062306a36Sopenharmony_ci return -EPROTO; 33162306a36Sopenharmony_ci } 33262306a36Sopenharmony_ci 33362306a36Sopenharmony_ci num_items = __le32_to_cpu(ev->num_items); 33462306a36Sopenharmony_ci len = ath10k_wmi_tlv_len(data); 33562306a36Sopenharmony_ci 33662306a36Sopenharmony_ci while (num_items--) { 33762306a36Sopenharmony_ci if (len == 0) 33862306a36Sopenharmony_ci break; 33962306a36Sopenharmony_ci if (len < sizeof(*item)) { 34062306a36Sopenharmony_ci ath10k_warn(ar, "failed to parse diag data: can't fit item header\n"); 34162306a36Sopenharmony_ci break; 34262306a36Sopenharmony_ci } 34362306a36Sopenharmony_ci 34462306a36Sopenharmony_ci item = data; 34562306a36Sopenharmony_ci 34662306a36Sopenharmony_ci if (len < sizeof(*item) + __le16_to_cpu(item->len)) { 34762306a36Sopenharmony_ci ath10k_warn(ar, "failed to parse diag data: item is too long\n"); 34862306a36Sopenharmony_ci break; 34962306a36Sopenharmony_ci } 35062306a36Sopenharmony_ci 35162306a36Sopenharmony_ci trace_ath10k_wmi_diag_container(ar, 35262306a36Sopenharmony_ci item->type, 35362306a36Sopenharmony_ci __le32_to_cpu(item->timestamp), 35462306a36Sopenharmony_ci __le32_to_cpu(item->code), 35562306a36Sopenharmony_ci __le16_to_cpu(item->len), 35662306a36Sopenharmony_ci item->payload); 35762306a36Sopenharmony_ci 35862306a36Sopenharmony_ci len -= sizeof(*item); 35962306a36Sopenharmony_ci len -= roundup(__le16_to_cpu(item->len), 4); 36062306a36Sopenharmony_ci 36162306a36Sopenharmony_ci data += sizeof(*item); 36262306a36Sopenharmony_ci data += roundup(__le16_to_cpu(item->len), 4); 36362306a36Sopenharmony_ci } 36462306a36Sopenharmony_ci 36562306a36Sopenharmony_ci if (num_items != -1 || len != 0) 36662306a36Sopenharmony_ci ath10k_warn(ar, "failed to parse diag data event: num_items %d len %d\n", 36762306a36Sopenharmony_ci num_items, len); 36862306a36Sopenharmony_ci 36962306a36Sopenharmony_ci kfree(tb); 37062306a36Sopenharmony_ci return 0; 37162306a36Sopenharmony_ci} 37262306a36Sopenharmony_ci 37362306a36Sopenharmony_cistatic int ath10k_wmi_tlv_event_diag(struct ath10k *ar, 37462306a36Sopenharmony_ci struct sk_buff *skb) 37562306a36Sopenharmony_ci{ 37662306a36Sopenharmony_ci const void **tb; 37762306a36Sopenharmony_ci const void *data; 37862306a36Sopenharmony_ci int ret, len; 37962306a36Sopenharmony_ci 38062306a36Sopenharmony_ci tb = ath10k_wmi_tlv_parse_alloc(ar, skb->data, skb->len, GFP_ATOMIC); 38162306a36Sopenharmony_ci if (IS_ERR(tb)) { 38262306a36Sopenharmony_ci ret = PTR_ERR(tb); 38362306a36Sopenharmony_ci ath10k_warn(ar, "failed to parse tlv: %d\n", ret); 38462306a36Sopenharmony_ci return ret; 38562306a36Sopenharmony_ci } 38662306a36Sopenharmony_ci 38762306a36Sopenharmony_ci data = tb[WMI_TLV_TAG_ARRAY_BYTE]; 38862306a36Sopenharmony_ci if (!data) { 38962306a36Sopenharmony_ci kfree(tb); 39062306a36Sopenharmony_ci return -EPROTO; 39162306a36Sopenharmony_ci } 39262306a36Sopenharmony_ci len = ath10k_wmi_tlv_len(data); 39362306a36Sopenharmony_ci 39462306a36Sopenharmony_ci ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv diag event len %d\n", len); 39562306a36Sopenharmony_ci trace_ath10k_wmi_diag(ar, data, len); 39662306a36Sopenharmony_ci 39762306a36Sopenharmony_ci kfree(tb); 39862306a36Sopenharmony_ci return 0; 39962306a36Sopenharmony_ci} 40062306a36Sopenharmony_ci 40162306a36Sopenharmony_cistatic int ath10k_wmi_tlv_event_p2p_noa(struct ath10k *ar, 40262306a36Sopenharmony_ci struct sk_buff *skb) 40362306a36Sopenharmony_ci{ 40462306a36Sopenharmony_ci const void **tb; 40562306a36Sopenharmony_ci const struct wmi_tlv_p2p_noa_ev *ev; 40662306a36Sopenharmony_ci const struct wmi_p2p_noa_info *noa; 40762306a36Sopenharmony_ci int ret, vdev_id; 40862306a36Sopenharmony_ci 40962306a36Sopenharmony_ci tb = ath10k_wmi_tlv_parse_alloc(ar, skb->data, skb->len, GFP_ATOMIC); 41062306a36Sopenharmony_ci if (IS_ERR(tb)) { 41162306a36Sopenharmony_ci ret = PTR_ERR(tb); 41262306a36Sopenharmony_ci ath10k_warn(ar, "failed to parse tlv: %d\n", ret); 41362306a36Sopenharmony_ci return ret; 41462306a36Sopenharmony_ci } 41562306a36Sopenharmony_ci 41662306a36Sopenharmony_ci ev = tb[WMI_TLV_TAG_STRUCT_P2P_NOA_EVENT]; 41762306a36Sopenharmony_ci noa = tb[WMI_TLV_TAG_STRUCT_P2P_NOA_INFO]; 41862306a36Sopenharmony_ci 41962306a36Sopenharmony_ci if (!ev || !noa) { 42062306a36Sopenharmony_ci kfree(tb); 42162306a36Sopenharmony_ci return -EPROTO; 42262306a36Sopenharmony_ci } 42362306a36Sopenharmony_ci 42462306a36Sopenharmony_ci vdev_id = __le32_to_cpu(ev->vdev_id); 42562306a36Sopenharmony_ci 42662306a36Sopenharmony_ci ath10k_dbg(ar, ATH10K_DBG_WMI, 42762306a36Sopenharmony_ci "wmi tlv p2p noa vdev_id %i descriptors %u\n", 42862306a36Sopenharmony_ci vdev_id, noa->num_descriptors); 42962306a36Sopenharmony_ci 43062306a36Sopenharmony_ci ath10k_p2p_noa_update_by_vdev_id(ar, vdev_id, noa); 43162306a36Sopenharmony_ci kfree(tb); 43262306a36Sopenharmony_ci return 0; 43362306a36Sopenharmony_ci} 43462306a36Sopenharmony_ci 43562306a36Sopenharmony_cistatic int ath10k_wmi_tlv_event_tx_pause(struct ath10k *ar, 43662306a36Sopenharmony_ci struct sk_buff *skb) 43762306a36Sopenharmony_ci{ 43862306a36Sopenharmony_ci const void **tb; 43962306a36Sopenharmony_ci const struct wmi_tlv_tx_pause_ev *ev; 44062306a36Sopenharmony_ci int ret, vdev_id; 44162306a36Sopenharmony_ci u32 pause_id, action, vdev_map, peer_id, tid_map; 44262306a36Sopenharmony_ci 44362306a36Sopenharmony_ci tb = ath10k_wmi_tlv_parse_alloc(ar, skb->data, skb->len, GFP_ATOMIC); 44462306a36Sopenharmony_ci if (IS_ERR(tb)) { 44562306a36Sopenharmony_ci ret = PTR_ERR(tb); 44662306a36Sopenharmony_ci ath10k_warn(ar, "failed to parse tlv: %d\n", ret); 44762306a36Sopenharmony_ci return ret; 44862306a36Sopenharmony_ci } 44962306a36Sopenharmony_ci 45062306a36Sopenharmony_ci ev = tb[WMI_TLV_TAG_STRUCT_TX_PAUSE_EVENT]; 45162306a36Sopenharmony_ci if (!ev) { 45262306a36Sopenharmony_ci kfree(tb); 45362306a36Sopenharmony_ci return -EPROTO; 45462306a36Sopenharmony_ci } 45562306a36Sopenharmony_ci 45662306a36Sopenharmony_ci pause_id = __le32_to_cpu(ev->pause_id); 45762306a36Sopenharmony_ci action = __le32_to_cpu(ev->action); 45862306a36Sopenharmony_ci vdev_map = __le32_to_cpu(ev->vdev_map); 45962306a36Sopenharmony_ci peer_id = __le32_to_cpu(ev->peer_id); 46062306a36Sopenharmony_ci tid_map = __le32_to_cpu(ev->tid_map); 46162306a36Sopenharmony_ci 46262306a36Sopenharmony_ci ath10k_dbg(ar, ATH10K_DBG_WMI, 46362306a36Sopenharmony_ci "wmi tlv tx pause pause_id %u action %u vdev_map 0x%08x peer_id %u tid_map 0x%08x\n", 46462306a36Sopenharmony_ci pause_id, action, vdev_map, peer_id, tid_map); 46562306a36Sopenharmony_ci 46662306a36Sopenharmony_ci switch (pause_id) { 46762306a36Sopenharmony_ci case WMI_TLV_TX_PAUSE_ID_MCC: 46862306a36Sopenharmony_ci case WMI_TLV_TX_PAUSE_ID_P2P_CLI_NOA: 46962306a36Sopenharmony_ci case WMI_TLV_TX_PAUSE_ID_P2P_GO_PS: 47062306a36Sopenharmony_ci case WMI_TLV_TX_PAUSE_ID_AP_PS: 47162306a36Sopenharmony_ci case WMI_TLV_TX_PAUSE_ID_IBSS_PS: 47262306a36Sopenharmony_ci for (vdev_id = 0; vdev_map; vdev_id++) { 47362306a36Sopenharmony_ci if (!(vdev_map & BIT(vdev_id))) 47462306a36Sopenharmony_ci continue; 47562306a36Sopenharmony_ci 47662306a36Sopenharmony_ci vdev_map &= ~BIT(vdev_id); 47762306a36Sopenharmony_ci ath10k_mac_handle_tx_pause_vdev(ar, vdev_id, pause_id, 47862306a36Sopenharmony_ci action); 47962306a36Sopenharmony_ci } 48062306a36Sopenharmony_ci break; 48162306a36Sopenharmony_ci case WMI_TLV_TX_PAUSE_ID_AP_PEER_PS: 48262306a36Sopenharmony_ci case WMI_TLV_TX_PAUSE_ID_AP_PEER_UAPSD: 48362306a36Sopenharmony_ci case WMI_TLV_TX_PAUSE_ID_STA_ADD_BA: 48462306a36Sopenharmony_ci case WMI_TLV_TX_PAUSE_ID_HOST: 48562306a36Sopenharmony_ci ath10k_dbg(ar, ATH10K_DBG_MAC, 48662306a36Sopenharmony_ci "mac ignoring unsupported tx pause id %d\n", 48762306a36Sopenharmony_ci pause_id); 48862306a36Sopenharmony_ci break; 48962306a36Sopenharmony_ci default: 49062306a36Sopenharmony_ci ath10k_dbg(ar, ATH10K_DBG_MAC, 49162306a36Sopenharmony_ci "mac ignoring unknown tx pause vdev %d\n", 49262306a36Sopenharmony_ci pause_id); 49362306a36Sopenharmony_ci break; 49462306a36Sopenharmony_ci } 49562306a36Sopenharmony_ci 49662306a36Sopenharmony_ci kfree(tb); 49762306a36Sopenharmony_ci return 0; 49862306a36Sopenharmony_ci} 49962306a36Sopenharmony_ci 50062306a36Sopenharmony_cistatic void ath10k_wmi_tlv_event_rfkill_state_change(struct ath10k *ar, 50162306a36Sopenharmony_ci struct sk_buff *skb) 50262306a36Sopenharmony_ci{ 50362306a36Sopenharmony_ci const struct wmi_tlv_rfkill_state_change_ev *ev; 50462306a36Sopenharmony_ci const void **tb; 50562306a36Sopenharmony_ci bool radio; 50662306a36Sopenharmony_ci int ret; 50762306a36Sopenharmony_ci 50862306a36Sopenharmony_ci tb = ath10k_wmi_tlv_parse_alloc(ar, skb->data, skb->len, GFP_ATOMIC); 50962306a36Sopenharmony_ci if (IS_ERR(tb)) { 51062306a36Sopenharmony_ci ret = PTR_ERR(tb); 51162306a36Sopenharmony_ci ath10k_warn(ar, 51262306a36Sopenharmony_ci "failed to parse rfkill state change event: %d\n", 51362306a36Sopenharmony_ci ret); 51462306a36Sopenharmony_ci return; 51562306a36Sopenharmony_ci } 51662306a36Sopenharmony_ci 51762306a36Sopenharmony_ci ev = tb[WMI_TLV_TAG_STRUCT_RFKILL_EVENT]; 51862306a36Sopenharmony_ci if (!ev) { 51962306a36Sopenharmony_ci kfree(tb); 52062306a36Sopenharmony_ci return; 52162306a36Sopenharmony_ci } 52262306a36Sopenharmony_ci 52362306a36Sopenharmony_ci ath10k_dbg(ar, ATH10K_DBG_MAC, 52462306a36Sopenharmony_ci "wmi tlv rfkill state change gpio %d type %d radio_state %d\n", 52562306a36Sopenharmony_ci __le32_to_cpu(ev->gpio_pin_num), 52662306a36Sopenharmony_ci __le32_to_cpu(ev->int_type), 52762306a36Sopenharmony_ci __le32_to_cpu(ev->radio_state)); 52862306a36Sopenharmony_ci 52962306a36Sopenharmony_ci radio = (__le32_to_cpu(ev->radio_state) == WMI_TLV_RFKILL_RADIO_STATE_ON); 53062306a36Sopenharmony_ci 53162306a36Sopenharmony_ci spin_lock_bh(&ar->data_lock); 53262306a36Sopenharmony_ci 53362306a36Sopenharmony_ci if (!radio) 53462306a36Sopenharmony_ci ar->hw_rfkill_on = true; 53562306a36Sopenharmony_ci 53662306a36Sopenharmony_ci spin_unlock_bh(&ar->data_lock); 53762306a36Sopenharmony_ci 53862306a36Sopenharmony_ci /* notify cfg80211 radio state change */ 53962306a36Sopenharmony_ci ath10k_mac_rfkill_enable_radio(ar, radio); 54062306a36Sopenharmony_ci wiphy_rfkill_set_hw_state(ar->hw->wiphy, !radio); 54162306a36Sopenharmony_ci} 54262306a36Sopenharmony_ci 54362306a36Sopenharmony_cistatic int ath10k_wmi_tlv_event_temperature(struct ath10k *ar, 54462306a36Sopenharmony_ci struct sk_buff *skb) 54562306a36Sopenharmony_ci{ 54662306a36Sopenharmony_ci const struct wmi_tlv_pdev_temperature_event *ev; 54762306a36Sopenharmony_ci 54862306a36Sopenharmony_ci ev = (struct wmi_tlv_pdev_temperature_event *)skb->data; 54962306a36Sopenharmony_ci if (WARN_ON(skb->len < sizeof(*ev))) 55062306a36Sopenharmony_ci return -EPROTO; 55162306a36Sopenharmony_ci 55262306a36Sopenharmony_ci ath10k_thermal_event_temperature(ar, __le32_to_cpu(ev->temperature)); 55362306a36Sopenharmony_ci return 0; 55462306a36Sopenharmony_ci} 55562306a36Sopenharmony_ci 55662306a36Sopenharmony_cistatic void ath10k_wmi_event_tdls_peer(struct ath10k *ar, struct sk_buff *skb) 55762306a36Sopenharmony_ci{ 55862306a36Sopenharmony_ci struct ieee80211_sta *station; 55962306a36Sopenharmony_ci const struct wmi_tlv_tdls_peer_event *ev; 56062306a36Sopenharmony_ci const void **tb; 56162306a36Sopenharmony_ci struct ath10k_vif *arvif; 56262306a36Sopenharmony_ci 56362306a36Sopenharmony_ci tb = ath10k_wmi_tlv_parse_alloc(ar, skb->data, skb->len, GFP_ATOMIC); 56462306a36Sopenharmony_ci if (IS_ERR(tb)) { 56562306a36Sopenharmony_ci ath10k_warn(ar, "tdls peer failed to parse tlv"); 56662306a36Sopenharmony_ci return; 56762306a36Sopenharmony_ci } 56862306a36Sopenharmony_ci ev = tb[WMI_TLV_TAG_STRUCT_TDLS_PEER_EVENT]; 56962306a36Sopenharmony_ci if (!ev) { 57062306a36Sopenharmony_ci kfree(tb); 57162306a36Sopenharmony_ci ath10k_warn(ar, "tdls peer NULL event"); 57262306a36Sopenharmony_ci return; 57362306a36Sopenharmony_ci } 57462306a36Sopenharmony_ci 57562306a36Sopenharmony_ci switch (__le32_to_cpu(ev->peer_reason)) { 57662306a36Sopenharmony_ci case WMI_TDLS_TEARDOWN_REASON_TX: 57762306a36Sopenharmony_ci case WMI_TDLS_TEARDOWN_REASON_RSSI: 57862306a36Sopenharmony_ci case WMI_TDLS_TEARDOWN_REASON_PTR_TIMEOUT: 57962306a36Sopenharmony_ci rcu_read_lock(); 58062306a36Sopenharmony_ci station = ieee80211_find_sta_by_ifaddr(ar->hw, 58162306a36Sopenharmony_ci ev->peer_macaddr.addr, 58262306a36Sopenharmony_ci NULL); 58362306a36Sopenharmony_ci if (!station) { 58462306a36Sopenharmony_ci ath10k_warn(ar, "did not find station from tdls peer event"); 58562306a36Sopenharmony_ci goto exit; 58662306a36Sopenharmony_ci } 58762306a36Sopenharmony_ci 58862306a36Sopenharmony_ci arvif = ath10k_get_arvif(ar, __le32_to_cpu(ev->vdev_id)); 58962306a36Sopenharmony_ci if (!arvif) { 59062306a36Sopenharmony_ci ath10k_warn(ar, "no vif for vdev_id %d found", 59162306a36Sopenharmony_ci __le32_to_cpu(ev->vdev_id)); 59262306a36Sopenharmony_ci goto exit; 59362306a36Sopenharmony_ci } 59462306a36Sopenharmony_ci 59562306a36Sopenharmony_ci ieee80211_tdls_oper_request( 59662306a36Sopenharmony_ci arvif->vif, station->addr, 59762306a36Sopenharmony_ci NL80211_TDLS_TEARDOWN, 59862306a36Sopenharmony_ci WLAN_REASON_TDLS_TEARDOWN_UNREACHABLE, 59962306a36Sopenharmony_ci GFP_ATOMIC 60062306a36Sopenharmony_ci ); 60162306a36Sopenharmony_ci break; 60262306a36Sopenharmony_ci default: 60362306a36Sopenharmony_ci kfree(tb); 60462306a36Sopenharmony_ci return; 60562306a36Sopenharmony_ci } 60662306a36Sopenharmony_ci 60762306a36Sopenharmony_ciexit: 60862306a36Sopenharmony_ci rcu_read_unlock(); 60962306a36Sopenharmony_ci kfree(tb); 61062306a36Sopenharmony_ci} 61162306a36Sopenharmony_ci 61262306a36Sopenharmony_cistatic int ath10k_wmi_tlv_event_peer_delete_resp(struct ath10k *ar, 61362306a36Sopenharmony_ci struct sk_buff *skb) 61462306a36Sopenharmony_ci{ 61562306a36Sopenharmony_ci struct wmi_peer_delete_resp_ev_arg *arg; 61662306a36Sopenharmony_ci struct wmi_tlv *tlv_hdr; 61762306a36Sopenharmony_ci 61862306a36Sopenharmony_ci tlv_hdr = (struct wmi_tlv *)skb->data; 61962306a36Sopenharmony_ci arg = (struct wmi_peer_delete_resp_ev_arg *)tlv_hdr->value; 62062306a36Sopenharmony_ci 62162306a36Sopenharmony_ci ath10k_dbg(ar, ATH10K_DBG_WMI, "vdev id %d", arg->vdev_id); 62262306a36Sopenharmony_ci ath10k_dbg(ar, ATH10K_DBG_WMI, "peer mac addr %pM", &arg->peer_addr); 62362306a36Sopenharmony_ci ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv peer delete response\n"); 62462306a36Sopenharmony_ci 62562306a36Sopenharmony_ci complete(&ar->peer_delete_done); 62662306a36Sopenharmony_ci 62762306a36Sopenharmony_ci return 0; 62862306a36Sopenharmony_ci} 62962306a36Sopenharmony_ci 63062306a36Sopenharmony_ci/***********/ 63162306a36Sopenharmony_ci/* TLV ops */ 63262306a36Sopenharmony_ci/***********/ 63362306a36Sopenharmony_ci 63462306a36Sopenharmony_cistatic void ath10k_wmi_tlv_op_rx(struct ath10k *ar, struct sk_buff *skb) 63562306a36Sopenharmony_ci{ 63662306a36Sopenharmony_ci struct wmi_cmd_hdr *cmd_hdr; 63762306a36Sopenharmony_ci enum wmi_tlv_event_id id; 63862306a36Sopenharmony_ci bool consumed; 63962306a36Sopenharmony_ci 64062306a36Sopenharmony_ci cmd_hdr = (struct wmi_cmd_hdr *)skb->data; 64162306a36Sopenharmony_ci id = MS(__le32_to_cpu(cmd_hdr->cmd_id), WMI_CMD_HDR_CMD_ID); 64262306a36Sopenharmony_ci 64362306a36Sopenharmony_ci if (skb_pull(skb, sizeof(struct wmi_cmd_hdr)) == NULL) 64462306a36Sopenharmony_ci goto out; 64562306a36Sopenharmony_ci 64662306a36Sopenharmony_ci trace_ath10k_wmi_event(ar, id, skb->data, skb->len); 64762306a36Sopenharmony_ci 64862306a36Sopenharmony_ci consumed = ath10k_tm_event_wmi(ar, id, skb); 64962306a36Sopenharmony_ci 65062306a36Sopenharmony_ci /* Ready event must be handled normally also in UTF mode so that we 65162306a36Sopenharmony_ci * know the UTF firmware has booted, others we are just bypass WMI 65262306a36Sopenharmony_ci * events to testmode. 65362306a36Sopenharmony_ci */ 65462306a36Sopenharmony_ci if (consumed && id != WMI_TLV_READY_EVENTID) { 65562306a36Sopenharmony_ci ath10k_dbg(ar, ATH10K_DBG_WMI, 65662306a36Sopenharmony_ci "wmi tlv testmode consumed 0x%x\n", id); 65762306a36Sopenharmony_ci goto out; 65862306a36Sopenharmony_ci } 65962306a36Sopenharmony_ci 66062306a36Sopenharmony_ci switch (id) { 66162306a36Sopenharmony_ci case WMI_TLV_MGMT_RX_EVENTID: 66262306a36Sopenharmony_ci ath10k_wmi_event_mgmt_rx(ar, skb); 66362306a36Sopenharmony_ci /* mgmt_rx() owns the skb now! */ 66462306a36Sopenharmony_ci return; 66562306a36Sopenharmony_ci case WMI_TLV_SCAN_EVENTID: 66662306a36Sopenharmony_ci ath10k_wmi_event_scan(ar, skb); 66762306a36Sopenharmony_ci break; 66862306a36Sopenharmony_ci case WMI_TLV_CHAN_INFO_EVENTID: 66962306a36Sopenharmony_ci ath10k_wmi_event_chan_info(ar, skb); 67062306a36Sopenharmony_ci break; 67162306a36Sopenharmony_ci case WMI_TLV_ECHO_EVENTID: 67262306a36Sopenharmony_ci ath10k_wmi_event_echo(ar, skb); 67362306a36Sopenharmony_ci break; 67462306a36Sopenharmony_ci case WMI_TLV_DEBUG_MESG_EVENTID: 67562306a36Sopenharmony_ci ath10k_wmi_event_debug_mesg(ar, skb); 67662306a36Sopenharmony_ci break; 67762306a36Sopenharmony_ci case WMI_TLV_UPDATE_STATS_EVENTID: 67862306a36Sopenharmony_ci ath10k_wmi_event_update_stats(ar, skb); 67962306a36Sopenharmony_ci break; 68062306a36Sopenharmony_ci case WMI_TLV_PEER_STATS_INFO_EVENTID: 68162306a36Sopenharmony_ci ath10k_wmi_tlv_event_peer_stats_info(ar, skb); 68262306a36Sopenharmony_ci break; 68362306a36Sopenharmony_ci case WMI_TLV_VDEV_START_RESP_EVENTID: 68462306a36Sopenharmony_ci ath10k_wmi_event_vdev_start_resp(ar, skb); 68562306a36Sopenharmony_ci break; 68662306a36Sopenharmony_ci case WMI_TLV_VDEV_STOPPED_EVENTID: 68762306a36Sopenharmony_ci ath10k_wmi_event_vdev_stopped(ar, skb); 68862306a36Sopenharmony_ci break; 68962306a36Sopenharmony_ci case WMI_TLV_VDEV_DELETE_RESP_EVENTID: 69062306a36Sopenharmony_ci ath10k_wmi_tlv_event_vdev_delete_resp(ar, skb); 69162306a36Sopenharmony_ci break; 69262306a36Sopenharmony_ci case WMI_TLV_PEER_STA_KICKOUT_EVENTID: 69362306a36Sopenharmony_ci ath10k_wmi_event_peer_sta_kickout(ar, skb); 69462306a36Sopenharmony_ci break; 69562306a36Sopenharmony_ci case WMI_TLV_HOST_SWBA_EVENTID: 69662306a36Sopenharmony_ci ath10k_wmi_event_host_swba(ar, skb); 69762306a36Sopenharmony_ci break; 69862306a36Sopenharmony_ci case WMI_TLV_TBTTOFFSET_UPDATE_EVENTID: 69962306a36Sopenharmony_ci ath10k_wmi_event_tbttoffset_update(ar, skb); 70062306a36Sopenharmony_ci break; 70162306a36Sopenharmony_ci case WMI_TLV_PHYERR_EVENTID: 70262306a36Sopenharmony_ci ath10k_wmi_event_phyerr(ar, skb); 70362306a36Sopenharmony_ci break; 70462306a36Sopenharmony_ci case WMI_TLV_ROAM_EVENTID: 70562306a36Sopenharmony_ci ath10k_wmi_event_roam(ar, skb); 70662306a36Sopenharmony_ci break; 70762306a36Sopenharmony_ci case WMI_TLV_PROFILE_MATCH: 70862306a36Sopenharmony_ci ath10k_wmi_event_profile_match(ar, skb); 70962306a36Sopenharmony_ci break; 71062306a36Sopenharmony_ci case WMI_TLV_DEBUG_PRINT_EVENTID: 71162306a36Sopenharmony_ci ath10k_wmi_event_debug_print(ar, skb); 71262306a36Sopenharmony_ci break; 71362306a36Sopenharmony_ci case WMI_TLV_PDEV_QVIT_EVENTID: 71462306a36Sopenharmony_ci ath10k_wmi_event_pdev_qvit(ar, skb); 71562306a36Sopenharmony_ci break; 71662306a36Sopenharmony_ci case WMI_TLV_WLAN_PROFILE_DATA_EVENTID: 71762306a36Sopenharmony_ci ath10k_wmi_event_wlan_profile_data(ar, skb); 71862306a36Sopenharmony_ci break; 71962306a36Sopenharmony_ci case WMI_TLV_RTT_MEASUREMENT_REPORT_EVENTID: 72062306a36Sopenharmony_ci ath10k_wmi_event_rtt_measurement_report(ar, skb); 72162306a36Sopenharmony_ci break; 72262306a36Sopenharmony_ci case WMI_TLV_TSF_MEASUREMENT_REPORT_EVENTID: 72362306a36Sopenharmony_ci ath10k_wmi_event_tsf_measurement_report(ar, skb); 72462306a36Sopenharmony_ci break; 72562306a36Sopenharmony_ci case WMI_TLV_RTT_ERROR_REPORT_EVENTID: 72662306a36Sopenharmony_ci ath10k_wmi_event_rtt_error_report(ar, skb); 72762306a36Sopenharmony_ci break; 72862306a36Sopenharmony_ci case WMI_TLV_WOW_WAKEUP_HOST_EVENTID: 72962306a36Sopenharmony_ci ath10k_wmi_event_wow_wakeup_host(ar, skb); 73062306a36Sopenharmony_ci break; 73162306a36Sopenharmony_ci case WMI_TLV_DCS_INTERFERENCE_EVENTID: 73262306a36Sopenharmony_ci ath10k_wmi_event_dcs_interference(ar, skb); 73362306a36Sopenharmony_ci break; 73462306a36Sopenharmony_ci case WMI_TLV_PDEV_TPC_CONFIG_EVENTID: 73562306a36Sopenharmony_ci ath10k_wmi_event_pdev_tpc_config(ar, skb); 73662306a36Sopenharmony_ci break; 73762306a36Sopenharmony_ci case WMI_TLV_PDEV_FTM_INTG_EVENTID: 73862306a36Sopenharmony_ci ath10k_wmi_event_pdev_ftm_intg(ar, skb); 73962306a36Sopenharmony_ci break; 74062306a36Sopenharmony_ci case WMI_TLV_GTK_OFFLOAD_STATUS_EVENTID: 74162306a36Sopenharmony_ci ath10k_wmi_event_gtk_offload_status(ar, skb); 74262306a36Sopenharmony_ci break; 74362306a36Sopenharmony_ci case WMI_TLV_GTK_REKEY_FAIL_EVENTID: 74462306a36Sopenharmony_ci ath10k_wmi_event_gtk_rekey_fail(ar, skb); 74562306a36Sopenharmony_ci break; 74662306a36Sopenharmony_ci case WMI_TLV_TX_DELBA_COMPLETE_EVENTID: 74762306a36Sopenharmony_ci ath10k_wmi_event_delba_complete(ar, skb); 74862306a36Sopenharmony_ci break; 74962306a36Sopenharmony_ci case WMI_TLV_TX_ADDBA_COMPLETE_EVENTID: 75062306a36Sopenharmony_ci ath10k_wmi_event_addba_complete(ar, skb); 75162306a36Sopenharmony_ci break; 75262306a36Sopenharmony_ci case WMI_TLV_VDEV_INSTALL_KEY_COMPLETE_EVENTID: 75362306a36Sopenharmony_ci ath10k_wmi_event_vdev_install_key_complete(ar, skb); 75462306a36Sopenharmony_ci break; 75562306a36Sopenharmony_ci case WMI_TLV_SERVICE_READY_EVENTID: 75662306a36Sopenharmony_ci ath10k_wmi_event_service_ready(ar, skb); 75762306a36Sopenharmony_ci return; 75862306a36Sopenharmony_ci case WMI_TLV_READY_EVENTID: 75962306a36Sopenharmony_ci ath10k_wmi_event_ready(ar, skb); 76062306a36Sopenharmony_ci break; 76162306a36Sopenharmony_ci case WMI_TLV_SERVICE_AVAILABLE_EVENTID: 76262306a36Sopenharmony_ci ath10k_wmi_event_service_available(ar, skb); 76362306a36Sopenharmony_ci break; 76462306a36Sopenharmony_ci case WMI_TLV_OFFLOAD_BCN_TX_STATUS_EVENTID: 76562306a36Sopenharmony_ci ath10k_wmi_tlv_event_bcn_tx_status(ar, skb); 76662306a36Sopenharmony_ci break; 76762306a36Sopenharmony_ci case WMI_TLV_DIAG_DATA_CONTAINER_EVENTID: 76862306a36Sopenharmony_ci ath10k_wmi_tlv_event_diag_data(ar, skb); 76962306a36Sopenharmony_ci break; 77062306a36Sopenharmony_ci case WMI_TLV_DIAG_EVENTID: 77162306a36Sopenharmony_ci ath10k_wmi_tlv_event_diag(ar, skb); 77262306a36Sopenharmony_ci break; 77362306a36Sopenharmony_ci case WMI_TLV_P2P_NOA_EVENTID: 77462306a36Sopenharmony_ci ath10k_wmi_tlv_event_p2p_noa(ar, skb); 77562306a36Sopenharmony_ci break; 77662306a36Sopenharmony_ci case WMI_TLV_TX_PAUSE_EVENTID: 77762306a36Sopenharmony_ci ath10k_wmi_tlv_event_tx_pause(ar, skb); 77862306a36Sopenharmony_ci break; 77962306a36Sopenharmony_ci case WMI_TLV_RFKILL_STATE_CHANGE_EVENTID: 78062306a36Sopenharmony_ci ath10k_wmi_tlv_event_rfkill_state_change(ar, skb); 78162306a36Sopenharmony_ci break; 78262306a36Sopenharmony_ci case WMI_TLV_PDEV_TEMPERATURE_EVENTID: 78362306a36Sopenharmony_ci ath10k_wmi_tlv_event_temperature(ar, skb); 78462306a36Sopenharmony_ci break; 78562306a36Sopenharmony_ci case WMI_TLV_TDLS_PEER_EVENTID: 78662306a36Sopenharmony_ci ath10k_wmi_event_tdls_peer(ar, skb); 78762306a36Sopenharmony_ci break; 78862306a36Sopenharmony_ci case WMI_TLV_PEER_DELETE_RESP_EVENTID: 78962306a36Sopenharmony_ci ath10k_wmi_tlv_event_peer_delete_resp(ar, skb); 79062306a36Sopenharmony_ci break; 79162306a36Sopenharmony_ci case WMI_TLV_MGMT_TX_COMPLETION_EVENTID: 79262306a36Sopenharmony_ci ath10k_wmi_event_mgmt_tx_compl(ar, skb); 79362306a36Sopenharmony_ci break; 79462306a36Sopenharmony_ci case WMI_TLV_MGMT_TX_BUNDLE_COMPLETION_EVENTID: 79562306a36Sopenharmony_ci ath10k_wmi_event_mgmt_tx_bundle_compl(ar, skb); 79662306a36Sopenharmony_ci break; 79762306a36Sopenharmony_ci default: 79862306a36Sopenharmony_ci ath10k_dbg(ar, ATH10K_DBG_WMI, "Unknown eventid: %d\n", id); 79962306a36Sopenharmony_ci break; 80062306a36Sopenharmony_ci } 80162306a36Sopenharmony_ci 80262306a36Sopenharmony_ciout: 80362306a36Sopenharmony_ci dev_kfree_skb(skb); 80462306a36Sopenharmony_ci} 80562306a36Sopenharmony_ci 80662306a36Sopenharmony_cistatic int ath10k_wmi_tlv_op_pull_scan_ev(struct ath10k *ar, 80762306a36Sopenharmony_ci struct sk_buff *skb, 80862306a36Sopenharmony_ci struct wmi_scan_ev_arg *arg) 80962306a36Sopenharmony_ci{ 81062306a36Sopenharmony_ci const void **tb; 81162306a36Sopenharmony_ci const struct wmi_scan_event *ev; 81262306a36Sopenharmony_ci int ret; 81362306a36Sopenharmony_ci 81462306a36Sopenharmony_ci tb = ath10k_wmi_tlv_parse_alloc(ar, skb->data, skb->len, GFP_ATOMIC); 81562306a36Sopenharmony_ci if (IS_ERR(tb)) { 81662306a36Sopenharmony_ci ret = PTR_ERR(tb); 81762306a36Sopenharmony_ci ath10k_warn(ar, "failed to parse tlv: %d\n", ret); 81862306a36Sopenharmony_ci return ret; 81962306a36Sopenharmony_ci } 82062306a36Sopenharmony_ci 82162306a36Sopenharmony_ci ev = tb[WMI_TLV_TAG_STRUCT_SCAN_EVENT]; 82262306a36Sopenharmony_ci if (!ev) { 82362306a36Sopenharmony_ci kfree(tb); 82462306a36Sopenharmony_ci return -EPROTO; 82562306a36Sopenharmony_ci } 82662306a36Sopenharmony_ci 82762306a36Sopenharmony_ci arg->event_type = ev->event_type; 82862306a36Sopenharmony_ci arg->reason = ev->reason; 82962306a36Sopenharmony_ci arg->channel_freq = ev->channel_freq; 83062306a36Sopenharmony_ci arg->scan_req_id = ev->scan_req_id; 83162306a36Sopenharmony_ci arg->scan_id = ev->scan_id; 83262306a36Sopenharmony_ci arg->vdev_id = ev->vdev_id; 83362306a36Sopenharmony_ci 83462306a36Sopenharmony_ci kfree(tb); 83562306a36Sopenharmony_ci return 0; 83662306a36Sopenharmony_ci} 83762306a36Sopenharmony_ci 83862306a36Sopenharmony_cistatic int 83962306a36Sopenharmony_ciath10k_wmi_tlv_op_pull_mgmt_tx_compl_ev(struct ath10k *ar, struct sk_buff *skb, 84062306a36Sopenharmony_ci struct wmi_tlv_mgmt_tx_compl_ev_arg *arg) 84162306a36Sopenharmony_ci{ 84262306a36Sopenharmony_ci const void **tb; 84362306a36Sopenharmony_ci const struct wmi_tlv_mgmt_tx_compl_ev *ev; 84462306a36Sopenharmony_ci int ret; 84562306a36Sopenharmony_ci 84662306a36Sopenharmony_ci tb = ath10k_wmi_tlv_parse_alloc(ar, skb->data, skb->len, GFP_ATOMIC); 84762306a36Sopenharmony_ci if (IS_ERR(tb)) { 84862306a36Sopenharmony_ci ret = PTR_ERR(tb); 84962306a36Sopenharmony_ci ath10k_warn(ar, "failed to parse tlv: %d\n", ret); 85062306a36Sopenharmony_ci return ret; 85162306a36Sopenharmony_ci } 85262306a36Sopenharmony_ci 85362306a36Sopenharmony_ci ev = tb[WMI_TLV_TAG_STRUCT_MGMT_TX_COMPL_EVENT]; 85462306a36Sopenharmony_ci if (!ev) { 85562306a36Sopenharmony_ci kfree(tb); 85662306a36Sopenharmony_ci return -EPROTO; 85762306a36Sopenharmony_ci } 85862306a36Sopenharmony_ci 85962306a36Sopenharmony_ci arg->desc_id = ev->desc_id; 86062306a36Sopenharmony_ci arg->status = ev->status; 86162306a36Sopenharmony_ci arg->pdev_id = ev->pdev_id; 86262306a36Sopenharmony_ci arg->ppdu_id = ev->ppdu_id; 86362306a36Sopenharmony_ci 86462306a36Sopenharmony_ci if (test_bit(WMI_SERVICE_TX_DATA_ACK_RSSI, ar->wmi.svc_map)) 86562306a36Sopenharmony_ci arg->ack_rssi = ev->ack_rssi; 86662306a36Sopenharmony_ci 86762306a36Sopenharmony_ci kfree(tb); 86862306a36Sopenharmony_ci return 0; 86962306a36Sopenharmony_ci} 87062306a36Sopenharmony_ci 87162306a36Sopenharmony_cistruct wmi_tlv_tx_bundle_compl_parse { 87262306a36Sopenharmony_ci const __le32 *num_reports; 87362306a36Sopenharmony_ci const __le32 *desc_ids; 87462306a36Sopenharmony_ci const __le32 *status; 87562306a36Sopenharmony_ci const __le32 *ppdu_ids; 87662306a36Sopenharmony_ci const __le32 *ack_rssi; 87762306a36Sopenharmony_ci bool desc_ids_done; 87862306a36Sopenharmony_ci bool status_done; 87962306a36Sopenharmony_ci bool ppdu_ids_done; 88062306a36Sopenharmony_ci bool ack_rssi_done; 88162306a36Sopenharmony_ci}; 88262306a36Sopenharmony_ci 88362306a36Sopenharmony_cistatic int 88462306a36Sopenharmony_ciath10k_wmi_tlv_mgmt_tx_bundle_compl_parse(struct ath10k *ar, u16 tag, u16 len, 88562306a36Sopenharmony_ci const void *ptr, void *data) 88662306a36Sopenharmony_ci{ 88762306a36Sopenharmony_ci struct wmi_tlv_tx_bundle_compl_parse *bundle_tx_compl = data; 88862306a36Sopenharmony_ci 88962306a36Sopenharmony_ci switch (tag) { 89062306a36Sopenharmony_ci case WMI_TLV_TAG_STRUCT_MGMT_TX_COMPL_BUNDLE_EVENT: 89162306a36Sopenharmony_ci bundle_tx_compl->num_reports = ptr; 89262306a36Sopenharmony_ci break; 89362306a36Sopenharmony_ci case WMI_TLV_TAG_ARRAY_UINT32: 89462306a36Sopenharmony_ci if (!bundle_tx_compl->desc_ids_done) { 89562306a36Sopenharmony_ci bundle_tx_compl->desc_ids_done = true; 89662306a36Sopenharmony_ci bundle_tx_compl->desc_ids = ptr; 89762306a36Sopenharmony_ci } else if (!bundle_tx_compl->status_done) { 89862306a36Sopenharmony_ci bundle_tx_compl->status_done = true; 89962306a36Sopenharmony_ci bundle_tx_compl->status = ptr; 90062306a36Sopenharmony_ci } else if (!bundle_tx_compl->ppdu_ids_done) { 90162306a36Sopenharmony_ci bundle_tx_compl->ppdu_ids_done = true; 90262306a36Sopenharmony_ci bundle_tx_compl->ppdu_ids = ptr; 90362306a36Sopenharmony_ci } else if (!bundle_tx_compl->ack_rssi_done) { 90462306a36Sopenharmony_ci bundle_tx_compl->ack_rssi_done = true; 90562306a36Sopenharmony_ci bundle_tx_compl->ack_rssi = ptr; 90662306a36Sopenharmony_ci } 90762306a36Sopenharmony_ci break; 90862306a36Sopenharmony_ci default: 90962306a36Sopenharmony_ci break; 91062306a36Sopenharmony_ci } 91162306a36Sopenharmony_ci return 0; 91262306a36Sopenharmony_ci} 91362306a36Sopenharmony_ci 91462306a36Sopenharmony_cistatic int ath10k_wmi_tlv_op_pull_mgmt_tx_bundle_compl_ev( 91562306a36Sopenharmony_ci struct ath10k *ar, struct sk_buff *skb, 91662306a36Sopenharmony_ci struct wmi_tlv_mgmt_tx_bundle_compl_ev_arg *arg) 91762306a36Sopenharmony_ci{ 91862306a36Sopenharmony_ci struct wmi_tlv_tx_bundle_compl_parse bundle_tx_compl = { }; 91962306a36Sopenharmony_ci int ret; 92062306a36Sopenharmony_ci 92162306a36Sopenharmony_ci ret = ath10k_wmi_tlv_iter(ar, skb->data, skb->len, 92262306a36Sopenharmony_ci ath10k_wmi_tlv_mgmt_tx_bundle_compl_parse, 92362306a36Sopenharmony_ci &bundle_tx_compl); 92462306a36Sopenharmony_ci if (ret) { 92562306a36Sopenharmony_ci ath10k_warn(ar, "failed to parse tlv: %d\n", ret); 92662306a36Sopenharmony_ci return ret; 92762306a36Sopenharmony_ci } 92862306a36Sopenharmony_ci 92962306a36Sopenharmony_ci if (!bundle_tx_compl.num_reports || !bundle_tx_compl.desc_ids || 93062306a36Sopenharmony_ci !bundle_tx_compl.status) 93162306a36Sopenharmony_ci return -EPROTO; 93262306a36Sopenharmony_ci 93362306a36Sopenharmony_ci arg->num_reports = *bundle_tx_compl.num_reports; 93462306a36Sopenharmony_ci arg->desc_ids = bundle_tx_compl.desc_ids; 93562306a36Sopenharmony_ci arg->status = bundle_tx_compl.status; 93662306a36Sopenharmony_ci arg->ppdu_ids = bundle_tx_compl.ppdu_ids; 93762306a36Sopenharmony_ci 93862306a36Sopenharmony_ci if (test_bit(WMI_SERVICE_TX_DATA_ACK_RSSI, ar->wmi.svc_map)) 93962306a36Sopenharmony_ci arg->ack_rssi = bundle_tx_compl.ack_rssi; 94062306a36Sopenharmony_ci 94162306a36Sopenharmony_ci return 0; 94262306a36Sopenharmony_ci} 94362306a36Sopenharmony_ci 94462306a36Sopenharmony_cistatic int ath10k_wmi_tlv_op_pull_mgmt_rx_ev(struct ath10k *ar, 94562306a36Sopenharmony_ci struct sk_buff *skb, 94662306a36Sopenharmony_ci struct wmi_mgmt_rx_ev_arg *arg) 94762306a36Sopenharmony_ci{ 94862306a36Sopenharmony_ci const void **tb; 94962306a36Sopenharmony_ci const struct wmi_tlv_mgmt_rx_ev *ev; 95062306a36Sopenharmony_ci const u8 *frame; 95162306a36Sopenharmony_ci u32 msdu_len; 95262306a36Sopenharmony_ci int ret, i; 95362306a36Sopenharmony_ci 95462306a36Sopenharmony_ci tb = ath10k_wmi_tlv_parse_alloc(ar, skb->data, skb->len, GFP_ATOMIC); 95562306a36Sopenharmony_ci if (IS_ERR(tb)) { 95662306a36Sopenharmony_ci ret = PTR_ERR(tb); 95762306a36Sopenharmony_ci ath10k_warn(ar, "failed to parse tlv: %d\n", ret); 95862306a36Sopenharmony_ci return ret; 95962306a36Sopenharmony_ci } 96062306a36Sopenharmony_ci 96162306a36Sopenharmony_ci ev = tb[WMI_TLV_TAG_STRUCT_MGMT_RX_HDR]; 96262306a36Sopenharmony_ci frame = tb[WMI_TLV_TAG_ARRAY_BYTE]; 96362306a36Sopenharmony_ci 96462306a36Sopenharmony_ci if (!ev || !frame) { 96562306a36Sopenharmony_ci kfree(tb); 96662306a36Sopenharmony_ci return -EPROTO; 96762306a36Sopenharmony_ci } 96862306a36Sopenharmony_ci 96962306a36Sopenharmony_ci arg->channel = ev->channel; 97062306a36Sopenharmony_ci arg->buf_len = ev->buf_len; 97162306a36Sopenharmony_ci arg->status = ev->status; 97262306a36Sopenharmony_ci arg->snr = ev->snr; 97362306a36Sopenharmony_ci arg->phy_mode = ev->phy_mode; 97462306a36Sopenharmony_ci arg->rate = ev->rate; 97562306a36Sopenharmony_ci 97662306a36Sopenharmony_ci for (i = 0; i < ARRAY_SIZE(ev->rssi); i++) 97762306a36Sopenharmony_ci arg->rssi[i] = ev->rssi[i]; 97862306a36Sopenharmony_ci 97962306a36Sopenharmony_ci msdu_len = __le32_to_cpu(arg->buf_len); 98062306a36Sopenharmony_ci 98162306a36Sopenharmony_ci if (skb->len < (frame - skb->data) + msdu_len) { 98262306a36Sopenharmony_ci kfree(tb); 98362306a36Sopenharmony_ci return -EPROTO; 98462306a36Sopenharmony_ci } 98562306a36Sopenharmony_ci 98662306a36Sopenharmony_ci /* shift the sk_buff to point to `frame` */ 98762306a36Sopenharmony_ci skb_trim(skb, 0); 98862306a36Sopenharmony_ci skb_put(skb, frame - skb->data); 98962306a36Sopenharmony_ci skb_pull(skb, frame - skb->data); 99062306a36Sopenharmony_ci skb_put(skb, msdu_len); 99162306a36Sopenharmony_ci 99262306a36Sopenharmony_ci kfree(tb); 99362306a36Sopenharmony_ci return 0; 99462306a36Sopenharmony_ci} 99562306a36Sopenharmony_ci 99662306a36Sopenharmony_cistatic int ath10k_wmi_tlv_op_pull_ch_info_ev(struct ath10k *ar, 99762306a36Sopenharmony_ci struct sk_buff *skb, 99862306a36Sopenharmony_ci struct wmi_ch_info_ev_arg *arg) 99962306a36Sopenharmony_ci{ 100062306a36Sopenharmony_ci const void **tb; 100162306a36Sopenharmony_ci const struct wmi_tlv_chan_info_event *ev; 100262306a36Sopenharmony_ci int ret; 100362306a36Sopenharmony_ci 100462306a36Sopenharmony_ci tb = ath10k_wmi_tlv_parse_alloc(ar, skb->data, skb->len, GFP_ATOMIC); 100562306a36Sopenharmony_ci if (IS_ERR(tb)) { 100662306a36Sopenharmony_ci ret = PTR_ERR(tb); 100762306a36Sopenharmony_ci ath10k_warn(ar, "failed to parse tlv: %d\n", ret); 100862306a36Sopenharmony_ci return ret; 100962306a36Sopenharmony_ci } 101062306a36Sopenharmony_ci 101162306a36Sopenharmony_ci ev = tb[WMI_TLV_TAG_STRUCT_CHAN_INFO_EVENT]; 101262306a36Sopenharmony_ci if (!ev) { 101362306a36Sopenharmony_ci kfree(tb); 101462306a36Sopenharmony_ci return -EPROTO; 101562306a36Sopenharmony_ci } 101662306a36Sopenharmony_ci 101762306a36Sopenharmony_ci arg->err_code = ev->err_code; 101862306a36Sopenharmony_ci arg->freq = ev->freq; 101962306a36Sopenharmony_ci arg->cmd_flags = ev->cmd_flags; 102062306a36Sopenharmony_ci arg->noise_floor = ev->noise_floor; 102162306a36Sopenharmony_ci arg->rx_clear_count = ev->rx_clear_count; 102262306a36Sopenharmony_ci arg->cycle_count = ev->cycle_count; 102362306a36Sopenharmony_ci if (test_bit(ATH10K_FW_FEATURE_SINGLE_CHAN_INFO_PER_CHANNEL, 102462306a36Sopenharmony_ci ar->running_fw->fw_file.fw_features)) 102562306a36Sopenharmony_ci arg->mac_clk_mhz = ev->mac_clk_mhz; 102662306a36Sopenharmony_ci 102762306a36Sopenharmony_ci kfree(tb); 102862306a36Sopenharmony_ci return 0; 102962306a36Sopenharmony_ci} 103062306a36Sopenharmony_ci 103162306a36Sopenharmony_cistatic int 103262306a36Sopenharmony_ciath10k_wmi_tlv_op_pull_vdev_start_ev(struct ath10k *ar, struct sk_buff *skb, 103362306a36Sopenharmony_ci struct wmi_vdev_start_ev_arg *arg) 103462306a36Sopenharmony_ci{ 103562306a36Sopenharmony_ci const void **tb; 103662306a36Sopenharmony_ci const struct wmi_vdev_start_response_event *ev; 103762306a36Sopenharmony_ci int ret; 103862306a36Sopenharmony_ci 103962306a36Sopenharmony_ci tb = ath10k_wmi_tlv_parse_alloc(ar, skb->data, skb->len, GFP_ATOMIC); 104062306a36Sopenharmony_ci if (IS_ERR(tb)) { 104162306a36Sopenharmony_ci ret = PTR_ERR(tb); 104262306a36Sopenharmony_ci ath10k_warn(ar, "failed to parse tlv: %d\n", ret); 104362306a36Sopenharmony_ci return ret; 104462306a36Sopenharmony_ci } 104562306a36Sopenharmony_ci 104662306a36Sopenharmony_ci ev = tb[WMI_TLV_TAG_STRUCT_VDEV_START_RESPONSE_EVENT]; 104762306a36Sopenharmony_ci if (!ev) { 104862306a36Sopenharmony_ci kfree(tb); 104962306a36Sopenharmony_ci return -EPROTO; 105062306a36Sopenharmony_ci } 105162306a36Sopenharmony_ci 105262306a36Sopenharmony_ci skb_pull(skb, sizeof(*ev)); 105362306a36Sopenharmony_ci arg->vdev_id = ev->vdev_id; 105462306a36Sopenharmony_ci arg->req_id = ev->req_id; 105562306a36Sopenharmony_ci arg->resp_type = ev->resp_type; 105662306a36Sopenharmony_ci arg->status = ev->status; 105762306a36Sopenharmony_ci 105862306a36Sopenharmony_ci kfree(tb); 105962306a36Sopenharmony_ci return 0; 106062306a36Sopenharmony_ci} 106162306a36Sopenharmony_ci 106262306a36Sopenharmony_cistatic int ath10k_wmi_tlv_op_pull_peer_kick_ev(struct ath10k *ar, 106362306a36Sopenharmony_ci struct sk_buff *skb, 106462306a36Sopenharmony_ci struct wmi_peer_kick_ev_arg *arg) 106562306a36Sopenharmony_ci{ 106662306a36Sopenharmony_ci const void **tb; 106762306a36Sopenharmony_ci const struct wmi_peer_sta_kickout_event *ev; 106862306a36Sopenharmony_ci int ret; 106962306a36Sopenharmony_ci 107062306a36Sopenharmony_ci tb = ath10k_wmi_tlv_parse_alloc(ar, skb->data, skb->len, GFP_ATOMIC); 107162306a36Sopenharmony_ci if (IS_ERR(tb)) { 107262306a36Sopenharmony_ci ret = PTR_ERR(tb); 107362306a36Sopenharmony_ci ath10k_warn(ar, "failed to parse tlv: %d\n", ret); 107462306a36Sopenharmony_ci return ret; 107562306a36Sopenharmony_ci } 107662306a36Sopenharmony_ci 107762306a36Sopenharmony_ci ev = tb[WMI_TLV_TAG_STRUCT_PEER_STA_KICKOUT_EVENT]; 107862306a36Sopenharmony_ci if (!ev) { 107962306a36Sopenharmony_ci kfree(tb); 108062306a36Sopenharmony_ci return -EPROTO; 108162306a36Sopenharmony_ci } 108262306a36Sopenharmony_ci 108362306a36Sopenharmony_ci arg->mac_addr = ev->peer_macaddr.addr; 108462306a36Sopenharmony_ci 108562306a36Sopenharmony_ci kfree(tb); 108662306a36Sopenharmony_ci return 0; 108762306a36Sopenharmony_ci} 108862306a36Sopenharmony_ci 108962306a36Sopenharmony_cistruct wmi_tlv_swba_parse { 109062306a36Sopenharmony_ci const struct wmi_host_swba_event *ev; 109162306a36Sopenharmony_ci bool tim_done; 109262306a36Sopenharmony_ci bool noa_done; 109362306a36Sopenharmony_ci size_t n_tim; 109462306a36Sopenharmony_ci size_t n_noa; 109562306a36Sopenharmony_ci struct wmi_swba_ev_arg *arg; 109662306a36Sopenharmony_ci}; 109762306a36Sopenharmony_ci 109862306a36Sopenharmony_cistatic int ath10k_wmi_tlv_swba_tim_parse(struct ath10k *ar, u16 tag, u16 len, 109962306a36Sopenharmony_ci const void *ptr, void *data) 110062306a36Sopenharmony_ci{ 110162306a36Sopenharmony_ci struct wmi_tlv_swba_parse *swba = data; 110262306a36Sopenharmony_ci struct wmi_tim_info_arg *tim_info_arg; 110362306a36Sopenharmony_ci const struct wmi_tim_info *tim_info_ev = ptr; 110462306a36Sopenharmony_ci 110562306a36Sopenharmony_ci if (tag != WMI_TLV_TAG_STRUCT_TIM_INFO) 110662306a36Sopenharmony_ci return -EPROTO; 110762306a36Sopenharmony_ci 110862306a36Sopenharmony_ci if (swba->n_tim >= ARRAY_SIZE(swba->arg->tim_info)) 110962306a36Sopenharmony_ci return -ENOBUFS; 111062306a36Sopenharmony_ci 111162306a36Sopenharmony_ci if (__le32_to_cpu(tim_info_ev->tim_len) > 111262306a36Sopenharmony_ci sizeof(tim_info_ev->tim_bitmap)) { 111362306a36Sopenharmony_ci ath10k_warn(ar, "refusing to parse invalid swba structure\n"); 111462306a36Sopenharmony_ci return -EPROTO; 111562306a36Sopenharmony_ci } 111662306a36Sopenharmony_ci 111762306a36Sopenharmony_ci tim_info_arg = &swba->arg->tim_info[swba->n_tim]; 111862306a36Sopenharmony_ci tim_info_arg->tim_len = tim_info_ev->tim_len; 111962306a36Sopenharmony_ci tim_info_arg->tim_mcast = tim_info_ev->tim_mcast; 112062306a36Sopenharmony_ci tim_info_arg->tim_bitmap = tim_info_ev->tim_bitmap; 112162306a36Sopenharmony_ci tim_info_arg->tim_changed = tim_info_ev->tim_changed; 112262306a36Sopenharmony_ci tim_info_arg->tim_num_ps_pending = tim_info_ev->tim_num_ps_pending; 112362306a36Sopenharmony_ci 112462306a36Sopenharmony_ci swba->n_tim++; 112562306a36Sopenharmony_ci 112662306a36Sopenharmony_ci return 0; 112762306a36Sopenharmony_ci} 112862306a36Sopenharmony_ci 112962306a36Sopenharmony_cistatic int ath10k_wmi_tlv_swba_noa_parse(struct ath10k *ar, u16 tag, u16 len, 113062306a36Sopenharmony_ci const void *ptr, void *data) 113162306a36Sopenharmony_ci{ 113262306a36Sopenharmony_ci struct wmi_tlv_swba_parse *swba = data; 113362306a36Sopenharmony_ci 113462306a36Sopenharmony_ci if (tag != WMI_TLV_TAG_STRUCT_P2P_NOA_INFO) 113562306a36Sopenharmony_ci return -EPROTO; 113662306a36Sopenharmony_ci 113762306a36Sopenharmony_ci if (swba->n_noa >= ARRAY_SIZE(swba->arg->noa_info)) 113862306a36Sopenharmony_ci return -ENOBUFS; 113962306a36Sopenharmony_ci 114062306a36Sopenharmony_ci swba->arg->noa_info[swba->n_noa++] = ptr; 114162306a36Sopenharmony_ci return 0; 114262306a36Sopenharmony_ci} 114362306a36Sopenharmony_ci 114462306a36Sopenharmony_cistatic int ath10k_wmi_tlv_swba_parse(struct ath10k *ar, u16 tag, u16 len, 114562306a36Sopenharmony_ci const void *ptr, void *data) 114662306a36Sopenharmony_ci{ 114762306a36Sopenharmony_ci struct wmi_tlv_swba_parse *swba = data; 114862306a36Sopenharmony_ci int ret; 114962306a36Sopenharmony_ci 115062306a36Sopenharmony_ci switch (tag) { 115162306a36Sopenharmony_ci case WMI_TLV_TAG_STRUCT_HOST_SWBA_EVENT: 115262306a36Sopenharmony_ci swba->ev = ptr; 115362306a36Sopenharmony_ci break; 115462306a36Sopenharmony_ci case WMI_TLV_TAG_ARRAY_STRUCT: 115562306a36Sopenharmony_ci if (!swba->tim_done) { 115662306a36Sopenharmony_ci swba->tim_done = true; 115762306a36Sopenharmony_ci ret = ath10k_wmi_tlv_iter(ar, ptr, len, 115862306a36Sopenharmony_ci ath10k_wmi_tlv_swba_tim_parse, 115962306a36Sopenharmony_ci swba); 116062306a36Sopenharmony_ci if (ret) 116162306a36Sopenharmony_ci return ret; 116262306a36Sopenharmony_ci } else if (!swba->noa_done) { 116362306a36Sopenharmony_ci swba->noa_done = true; 116462306a36Sopenharmony_ci ret = ath10k_wmi_tlv_iter(ar, ptr, len, 116562306a36Sopenharmony_ci ath10k_wmi_tlv_swba_noa_parse, 116662306a36Sopenharmony_ci swba); 116762306a36Sopenharmony_ci if (ret) 116862306a36Sopenharmony_ci return ret; 116962306a36Sopenharmony_ci } 117062306a36Sopenharmony_ci break; 117162306a36Sopenharmony_ci default: 117262306a36Sopenharmony_ci break; 117362306a36Sopenharmony_ci } 117462306a36Sopenharmony_ci return 0; 117562306a36Sopenharmony_ci} 117662306a36Sopenharmony_ci 117762306a36Sopenharmony_cistatic int ath10k_wmi_tlv_op_pull_swba_ev(struct ath10k *ar, 117862306a36Sopenharmony_ci struct sk_buff *skb, 117962306a36Sopenharmony_ci struct wmi_swba_ev_arg *arg) 118062306a36Sopenharmony_ci{ 118162306a36Sopenharmony_ci struct wmi_tlv_swba_parse swba = { .arg = arg }; 118262306a36Sopenharmony_ci u32 map; 118362306a36Sopenharmony_ci size_t n_vdevs; 118462306a36Sopenharmony_ci int ret; 118562306a36Sopenharmony_ci 118662306a36Sopenharmony_ci ret = ath10k_wmi_tlv_iter(ar, skb->data, skb->len, 118762306a36Sopenharmony_ci ath10k_wmi_tlv_swba_parse, &swba); 118862306a36Sopenharmony_ci if (ret) { 118962306a36Sopenharmony_ci ath10k_warn(ar, "failed to parse tlv: %d\n", ret); 119062306a36Sopenharmony_ci return ret; 119162306a36Sopenharmony_ci } 119262306a36Sopenharmony_ci 119362306a36Sopenharmony_ci if (!swba.ev) 119462306a36Sopenharmony_ci return -EPROTO; 119562306a36Sopenharmony_ci 119662306a36Sopenharmony_ci arg->vdev_map = swba.ev->vdev_map; 119762306a36Sopenharmony_ci 119862306a36Sopenharmony_ci for (map = __le32_to_cpu(arg->vdev_map), n_vdevs = 0; map; map >>= 1) 119962306a36Sopenharmony_ci if (map & BIT(0)) 120062306a36Sopenharmony_ci n_vdevs++; 120162306a36Sopenharmony_ci 120262306a36Sopenharmony_ci if (n_vdevs != swba.n_tim || 120362306a36Sopenharmony_ci n_vdevs != swba.n_noa) 120462306a36Sopenharmony_ci return -EPROTO; 120562306a36Sopenharmony_ci 120662306a36Sopenharmony_ci return 0; 120762306a36Sopenharmony_ci} 120862306a36Sopenharmony_ci 120962306a36Sopenharmony_cistatic int ath10k_wmi_tlv_op_pull_phyerr_ev_hdr(struct ath10k *ar, 121062306a36Sopenharmony_ci struct sk_buff *skb, 121162306a36Sopenharmony_ci struct wmi_phyerr_hdr_arg *arg) 121262306a36Sopenharmony_ci{ 121362306a36Sopenharmony_ci const void **tb; 121462306a36Sopenharmony_ci const struct wmi_tlv_phyerr_ev *ev; 121562306a36Sopenharmony_ci const void *phyerrs; 121662306a36Sopenharmony_ci int ret; 121762306a36Sopenharmony_ci 121862306a36Sopenharmony_ci tb = ath10k_wmi_tlv_parse_alloc(ar, skb->data, skb->len, GFP_ATOMIC); 121962306a36Sopenharmony_ci if (IS_ERR(tb)) { 122062306a36Sopenharmony_ci ret = PTR_ERR(tb); 122162306a36Sopenharmony_ci ath10k_warn(ar, "failed to parse tlv: %d\n", ret); 122262306a36Sopenharmony_ci return ret; 122362306a36Sopenharmony_ci } 122462306a36Sopenharmony_ci 122562306a36Sopenharmony_ci ev = tb[WMI_TLV_TAG_STRUCT_COMB_PHYERR_RX_HDR]; 122662306a36Sopenharmony_ci phyerrs = tb[WMI_TLV_TAG_ARRAY_BYTE]; 122762306a36Sopenharmony_ci 122862306a36Sopenharmony_ci if (!ev || !phyerrs) { 122962306a36Sopenharmony_ci kfree(tb); 123062306a36Sopenharmony_ci return -EPROTO; 123162306a36Sopenharmony_ci } 123262306a36Sopenharmony_ci 123362306a36Sopenharmony_ci arg->num_phyerrs = __le32_to_cpu(ev->num_phyerrs); 123462306a36Sopenharmony_ci arg->tsf_l32 = __le32_to_cpu(ev->tsf_l32); 123562306a36Sopenharmony_ci arg->tsf_u32 = __le32_to_cpu(ev->tsf_u32); 123662306a36Sopenharmony_ci arg->buf_len = __le32_to_cpu(ev->buf_len); 123762306a36Sopenharmony_ci arg->phyerrs = phyerrs; 123862306a36Sopenharmony_ci 123962306a36Sopenharmony_ci kfree(tb); 124062306a36Sopenharmony_ci return 0; 124162306a36Sopenharmony_ci} 124262306a36Sopenharmony_ci 124362306a36Sopenharmony_ci#define WMI_TLV_ABI_VER_NS0 0x5F414351 124462306a36Sopenharmony_ci#define WMI_TLV_ABI_VER_NS1 0x00004C4D 124562306a36Sopenharmony_ci#define WMI_TLV_ABI_VER_NS2 0x00000000 124662306a36Sopenharmony_ci#define WMI_TLV_ABI_VER_NS3 0x00000000 124762306a36Sopenharmony_ci 124862306a36Sopenharmony_ci#define WMI_TLV_ABI_VER0_MAJOR 1 124962306a36Sopenharmony_ci#define WMI_TLV_ABI_VER0_MINOR 0 125062306a36Sopenharmony_ci#define WMI_TLV_ABI_VER0 ((((WMI_TLV_ABI_VER0_MAJOR) << 24) & 0xFF000000) | \ 125162306a36Sopenharmony_ci (((WMI_TLV_ABI_VER0_MINOR) << 0) & 0x00FFFFFF)) 125262306a36Sopenharmony_ci#define WMI_TLV_ABI_VER1 53 125362306a36Sopenharmony_ci 125462306a36Sopenharmony_cistatic int 125562306a36Sopenharmony_ciath10k_wmi_tlv_parse_mem_reqs(struct ath10k *ar, u16 tag, u16 len, 125662306a36Sopenharmony_ci const void *ptr, void *data) 125762306a36Sopenharmony_ci{ 125862306a36Sopenharmony_ci struct wmi_svc_rdy_ev_arg *arg = data; 125962306a36Sopenharmony_ci int i; 126062306a36Sopenharmony_ci 126162306a36Sopenharmony_ci if (tag != WMI_TLV_TAG_STRUCT_WLAN_HOST_MEM_REQ) 126262306a36Sopenharmony_ci return -EPROTO; 126362306a36Sopenharmony_ci 126462306a36Sopenharmony_ci for (i = 0; i < ARRAY_SIZE(arg->mem_reqs); i++) { 126562306a36Sopenharmony_ci if (!arg->mem_reqs[i]) { 126662306a36Sopenharmony_ci arg->mem_reqs[i] = ptr; 126762306a36Sopenharmony_ci return 0; 126862306a36Sopenharmony_ci } 126962306a36Sopenharmony_ci } 127062306a36Sopenharmony_ci 127162306a36Sopenharmony_ci return -ENOMEM; 127262306a36Sopenharmony_ci} 127362306a36Sopenharmony_ci 127462306a36Sopenharmony_cistruct wmi_tlv_svc_rdy_parse { 127562306a36Sopenharmony_ci const struct hal_reg_capabilities *reg; 127662306a36Sopenharmony_ci const struct wmi_tlv_svc_rdy_ev *ev; 127762306a36Sopenharmony_ci const __le32 *svc_bmap; 127862306a36Sopenharmony_ci const struct wlan_host_mem_req *mem_reqs; 127962306a36Sopenharmony_ci bool svc_bmap_done; 128062306a36Sopenharmony_ci bool dbs_hw_mode_done; 128162306a36Sopenharmony_ci}; 128262306a36Sopenharmony_ci 128362306a36Sopenharmony_cistatic int ath10k_wmi_tlv_svc_rdy_parse(struct ath10k *ar, u16 tag, u16 len, 128462306a36Sopenharmony_ci const void *ptr, void *data) 128562306a36Sopenharmony_ci{ 128662306a36Sopenharmony_ci struct wmi_tlv_svc_rdy_parse *svc_rdy = data; 128762306a36Sopenharmony_ci 128862306a36Sopenharmony_ci switch (tag) { 128962306a36Sopenharmony_ci case WMI_TLV_TAG_STRUCT_SERVICE_READY_EVENT: 129062306a36Sopenharmony_ci svc_rdy->ev = ptr; 129162306a36Sopenharmony_ci break; 129262306a36Sopenharmony_ci case WMI_TLV_TAG_STRUCT_HAL_REG_CAPABILITIES: 129362306a36Sopenharmony_ci svc_rdy->reg = ptr; 129462306a36Sopenharmony_ci break; 129562306a36Sopenharmony_ci case WMI_TLV_TAG_ARRAY_STRUCT: 129662306a36Sopenharmony_ci svc_rdy->mem_reqs = ptr; 129762306a36Sopenharmony_ci break; 129862306a36Sopenharmony_ci case WMI_TLV_TAG_ARRAY_UINT32: 129962306a36Sopenharmony_ci if (!svc_rdy->svc_bmap_done) { 130062306a36Sopenharmony_ci svc_rdy->svc_bmap_done = true; 130162306a36Sopenharmony_ci svc_rdy->svc_bmap = ptr; 130262306a36Sopenharmony_ci } else if (!svc_rdy->dbs_hw_mode_done) { 130362306a36Sopenharmony_ci svc_rdy->dbs_hw_mode_done = true; 130462306a36Sopenharmony_ci } 130562306a36Sopenharmony_ci break; 130662306a36Sopenharmony_ci default: 130762306a36Sopenharmony_ci break; 130862306a36Sopenharmony_ci } 130962306a36Sopenharmony_ci return 0; 131062306a36Sopenharmony_ci} 131162306a36Sopenharmony_ci 131262306a36Sopenharmony_cistatic int ath10k_wmi_tlv_op_pull_svc_rdy_ev(struct ath10k *ar, 131362306a36Sopenharmony_ci struct sk_buff *skb, 131462306a36Sopenharmony_ci struct wmi_svc_rdy_ev_arg *arg) 131562306a36Sopenharmony_ci{ 131662306a36Sopenharmony_ci const struct hal_reg_capabilities *reg; 131762306a36Sopenharmony_ci const struct wmi_tlv_svc_rdy_ev *ev; 131862306a36Sopenharmony_ci const __le32 *svc_bmap; 131962306a36Sopenharmony_ci const struct wlan_host_mem_req *mem_reqs; 132062306a36Sopenharmony_ci struct wmi_tlv_svc_rdy_parse svc_rdy = { }; 132162306a36Sopenharmony_ci int ret; 132262306a36Sopenharmony_ci 132362306a36Sopenharmony_ci ret = ath10k_wmi_tlv_iter(ar, skb->data, skb->len, 132462306a36Sopenharmony_ci ath10k_wmi_tlv_svc_rdy_parse, &svc_rdy); 132562306a36Sopenharmony_ci if (ret) { 132662306a36Sopenharmony_ci ath10k_warn(ar, "failed to parse tlv: %d\n", ret); 132762306a36Sopenharmony_ci return ret; 132862306a36Sopenharmony_ci } 132962306a36Sopenharmony_ci 133062306a36Sopenharmony_ci ev = svc_rdy.ev; 133162306a36Sopenharmony_ci reg = svc_rdy.reg; 133262306a36Sopenharmony_ci svc_bmap = svc_rdy.svc_bmap; 133362306a36Sopenharmony_ci mem_reqs = svc_rdy.mem_reqs; 133462306a36Sopenharmony_ci 133562306a36Sopenharmony_ci if (!ev || !reg || !svc_bmap || !mem_reqs) 133662306a36Sopenharmony_ci return -EPROTO; 133762306a36Sopenharmony_ci 133862306a36Sopenharmony_ci /* This is an internal ABI compatibility check for WMI TLV so check it 133962306a36Sopenharmony_ci * here instead of the generic WMI code. 134062306a36Sopenharmony_ci */ 134162306a36Sopenharmony_ci ath10k_dbg(ar, ATH10K_DBG_WMI, 134262306a36Sopenharmony_ci "wmi tlv abi 0x%08x ?= 0x%08x, 0x%08x ?= 0x%08x, 0x%08x ?= 0x%08x, 0x%08x ?= 0x%08x, 0x%08x ?= 0x%08x\n", 134362306a36Sopenharmony_ci __le32_to_cpu(ev->abi.abi_ver0), WMI_TLV_ABI_VER0, 134462306a36Sopenharmony_ci __le32_to_cpu(ev->abi.abi_ver_ns0), WMI_TLV_ABI_VER_NS0, 134562306a36Sopenharmony_ci __le32_to_cpu(ev->abi.abi_ver_ns1), WMI_TLV_ABI_VER_NS1, 134662306a36Sopenharmony_ci __le32_to_cpu(ev->abi.abi_ver_ns2), WMI_TLV_ABI_VER_NS2, 134762306a36Sopenharmony_ci __le32_to_cpu(ev->abi.abi_ver_ns3), WMI_TLV_ABI_VER_NS3); 134862306a36Sopenharmony_ci 134962306a36Sopenharmony_ci if (__le32_to_cpu(ev->abi.abi_ver0) != WMI_TLV_ABI_VER0 || 135062306a36Sopenharmony_ci __le32_to_cpu(ev->abi.abi_ver_ns0) != WMI_TLV_ABI_VER_NS0 || 135162306a36Sopenharmony_ci __le32_to_cpu(ev->abi.abi_ver_ns1) != WMI_TLV_ABI_VER_NS1 || 135262306a36Sopenharmony_ci __le32_to_cpu(ev->abi.abi_ver_ns2) != WMI_TLV_ABI_VER_NS2 || 135362306a36Sopenharmony_ci __le32_to_cpu(ev->abi.abi_ver_ns3) != WMI_TLV_ABI_VER_NS3) { 135462306a36Sopenharmony_ci return -ENOTSUPP; 135562306a36Sopenharmony_ci } 135662306a36Sopenharmony_ci 135762306a36Sopenharmony_ci arg->min_tx_power = ev->hw_min_tx_power; 135862306a36Sopenharmony_ci arg->max_tx_power = ev->hw_max_tx_power; 135962306a36Sopenharmony_ci arg->ht_cap = ev->ht_cap_info; 136062306a36Sopenharmony_ci arg->vht_cap = ev->vht_cap_info; 136162306a36Sopenharmony_ci arg->vht_supp_mcs = ev->vht_supp_mcs; 136262306a36Sopenharmony_ci arg->sw_ver0 = ev->abi.abi_ver0; 136362306a36Sopenharmony_ci arg->sw_ver1 = ev->abi.abi_ver1; 136462306a36Sopenharmony_ci arg->fw_build = ev->fw_build_vers; 136562306a36Sopenharmony_ci arg->phy_capab = ev->phy_capability; 136662306a36Sopenharmony_ci arg->num_rf_chains = ev->num_rf_chains; 136762306a36Sopenharmony_ci arg->eeprom_rd = reg->eeprom_rd; 136862306a36Sopenharmony_ci arg->low_2ghz_chan = reg->low_2ghz_chan; 136962306a36Sopenharmony_ci arg->high_2ghz_chan = reg->high_2ghz_chan; 137062306a36Sopenharmony_ci arg->low_5ghz_chan = reg->low_5ghz_chan; 137162306a36Sopenharmony_ci arg->high_5ghz_chan = reg->high_5ghz_chan; 137262306a36Sopenharmony_ci arg->num_mem_reqs = ev->num_mem_reqs; 137362306a36Sopenharmony_ci arg->service_map = svc_bmap; 137462306a36Sopenharmony_ci arg->service_map_len = ath10k_wmi_tlv_len(svc_bmap); 137562306a36Sopenharmony_ci arg->sys_cap_info = ev->sys_cap_info; 137662306a36Sopenharmony_ci 137762306a36Sopenharmony_ci ret = ath10k_wmi_tlv_iter(ar, mem_reqs, ath10k_wmi_tlv_len(mem_reqs), 137862306a36Sopenharmony_ci ath10k_wmi_tlv_parse_mem_reqs, arg); 137962306a36Sopenharmony_ci if (ret) { 138062306a36Sopenharmony_ci ath10k_warn(ar, "failed to parse mem_reqs tlv: %d\n", ret); 138162306a36Sopenharmony_ci return ret; 138262306a36Sopenharmony_ci } 138362306a36Sopenharmony_ci 138462306a36Sopenharmony_ci return 0; 138562306a36Sopenharmony_ci} 138662306a36Sopenharmony_ci 138762306a36Sopenharmony_cistatic int ath10k_wmi_tlv_op_pull_rdy_ev(struct ath10k *ar, 138862306a36Sopenharmony_ci struct sk_buff *skb, 138962306a36Sopenharmony_ci struct wmi_rdy_ev_arg *arg) 139062306a36Sopenharmony_ci{ 139162306a36Sopenharmony_ci const void **tb; 139262306a36Sopenharmony_ci const struct wmi_tlv_rdy_ev *ev; 139362306a36Sopenharmony_ci int ret; 139462306a36Sopenharmony_ci 139562306a36Sopenharmony_ci tb = ath10k_wmi_tlv_parse_alloc(ar, skb->data, skb->len, GFP_ATOMIC); 139662306a36Sopenharmony_ci if (IS_ERR(tb)) { 139762306a36Sopenharmony_ci ret = PTR_ERR(tb); 139862306a36Sopenharmony_ci ath10k_warn(ar, "failed to parse tlv: %d\n", ret); 139962306a36Sopenharmony_ci return ret; 140062306a36Sopenharmony_ci } 140162306a36Sopenharmony_ci 140262306a36Sopenharmony_ci ev = tb[WMI_TLV_TAG_STRUCT_READY_EVENT]; 140362306a36Sopenharmony_ci if (!ev) { 140462306a36Sopenharmony_ci kfree(tb); 140562306a36Sopenharmony_ci return -EPROTO; 140662306a36Sopenharmony_ci } 140762306a36Sopenharmony_ci 140862306a36Sopenharmony_ci arg->sw_version = ev->abi.abi_ver0; 140962306a36Sopenharmony_ci arg->abi_version = ev->abi.abi_ver1; 141062306a36Sopenharmony_ci arg->status = ev->status; 141162306a36Sopenharmony_ci arg->mac_addr = ev->mac_addr.addr; 141262306a36Sopenharmony_ci 141362306a36Sopenharmony_ci kfree(tb); 141462306a36Sopenharmony_ci return 0; 141562306a36Sopenharmony_ci} 141662306a36Sopenharmony_ci 141762306a36Sopenharmony_cistatic int ath10k_wmi_tlv_svc_avail_parse(struct ath10k *ar, u16 tag, u16 len, 141862306a36Sopenharmony_ci const void *ptr, void *data) 141962306a36Sopenharmony_ci{ 142062306a36Sopenharmony_ci struct wmi_svc_avail_ev_arg *arg = data; 142162306a36Sopenharmony_ci 142262306a36Sopenharmony_ci switch (tag) { 142362306a36Sopenharmony_ci case WMI_TLV_TAG_STRUCT_SERVICE_AVAILABLE_EVENT: 142462306a36Sopenharmony_ci arg->service_map_ext_valid = true; 142562306a36Sopenharmony_ci arg->service_map_ext_len = *(__le32 *)ptr; 142662306a36Sopenharmony_ci arg->service_map_ext = ptr + sizeof(__le32); 142762306a36Sopenharmony_ci return 0; 142862306a36Sopenharmony_ci default: 142962306a36Sopenharmony_ci break; 143062306a36Sopenharmony_ci } 143162306a36Sopenharmony_ci 143262306a36Sopenharmony_ci return 0; 143362306a36Sopenharmony_ci} 143462306a36Sopenharmony_ci 143562306a36Sopenharmony_cistatic int ath10k_wmi_tlv_op_pull_svc_avail(struct ath10k *ar, 143662306a36Sopenharmony_ci struct sk_buff *skb, 143762306a36Sopenharmony_ci struct wmi_svc_avail_ev_arg *arg) 143862306a36Sopenharmony_ci{ 143962306a36Sopenharmony_ci int ret; 144062306a36Sopenharmony_ci 144162306a36Sopenharmony_ci ret = ath10k_wmi_tlv_iter(ar, skb->data, skb->len, 144262306a36Sopenharmony_ci ath10k_wmi_tlv_svc_avail_parse, arg); 144362306a36Sopenharmony_ci 144462306a36Sopenharmony_ci if (ret) { 144562306a36Sopenharmony_ci ath10k_warn(ar, "failed to parse svc_avail tlv: %d\n", ret); 144662306a36Sopenharmony_ci return ret; 144762306a36Sopenharmony_ci } 144862306a36Sopenharmony_ci 144962306a36Sopenharmony_ci return 0; 145062306a36Sopenharmony_ci} 145162306a36Sopenharmony_ci 145262306a36Sopenharmony_cistatic void ath10k_wmi_tlv_pull_vdev_stats(const struct wmi_tlv_vdev_stats *src, 145362306a36Sopenharmony_ci struct ath10k_fw_stats_vdev *dst) 145462306a36Sopenharmony_ci{ 145562306a36Sopenharmony_ci int i; 145662306a36Sopenharmony_ci 145762306a36Sopenharmony_ci dst->vdev_id = __le32_to_cpu(src->vdev_id); 145862306a36Sopenharmony_ci dst->beacon_snr = __le32_to_cpu(src->beacon_snr); 145962306a36Sopenharmony_ci dst->data_snr = __le32_to_cpu(src->data_snr); 146062306a36Sopenharmony_ci dst->num_rx_frames = __le32_to_cpu(src->num_rx_frames); 146162306a36Sopenharmony_ci dst->num_rts_fail = __le32_to_cpu(src->num_rts_fail); 146262306a36Sopenharmony_ci dst->num_rts_success = __le32_to_cpu(src->num_rts_success); 146362306a36Sopenharmony_ci dst->num_rx_err = __le32_to_cpu(src->num_rx_err); 146462306a36Sopenharmony_ci dst->num_rx_discard = __le32_to_cpu(src->num_rx_discard); 146562306a36Sopenharmony_ci dst->num_tx_not_acked = __le32_to_cpu(src->num_tx_not_acked); 146662306a36Sopenharmony_ci 146762306a36Sopenharmony_ci for (i = 0; i < ARRAY_SIZE(src->num_tx_frames); i++) 146862306a36Sopenharmony_ci dst->num_tx_frames[i] = 146962306a36Sopenharmony_ci __le32_to_cpu(src->num_tx_frames[i]); 147062306a36Sopenharmony_ci 147162306a36Sopenharmony_ci for (i = 0; i < ARRAY_SIZE(src->num_tx_frames_retries); i++) 147262306a36Sopenharmony_ci dst->num_tx_frames_retries[i] = 147362306a36Sopenharmony_ci __le32_to_cpu(src->num_tx_frames_retries[i]); 147462306a36Sopenharmony_ci 147562306a36Sopenharmony_ci for (i = 0; i < ARRAY_SIZE(src->num_tx_frames_failures); i++) 147662306a36Sopenharmony_ci dst->num_tx_frames_failures[i] = 147762306a36Sopenharmony_ci __le32_to_cpu(src->num_tx_frames_failures[i]); 147862306a36Sopenharmony_ci 147962306a36Sopenharmony_ci for (i = 0; i < ARRAY_SIZE(src->tx_rate_history); i++) 148062306a36Sopenharmony_ci dst->tx_rate_history[i] = 148162306a36Sopenharmony_ci __le32_to_cpu(src->tx_rate_history[i]); 148262306a36Sopenharmony_ci 148362306a36Sopenharmony_ci for (i = 0; i < ARRAY_SIZE(src->beacon_rssi_history); i++) 148462306a36Sopenharmony_ci dst->beacon_rssi_history[i] = 148562306a36Sopenharmony_ci __le32_to_cpu(src->beacon_rssi_history[i]); 148662306a36Sopenharmony_ci} 148762306a36Sopenharmony_ci 148862306a36Sopenharmony_cistatic int ath10k_wmi_tlv_op_pull_fw_stats(struct ath10k *ar, 148962306a36Sopenharmony_ci struct sk_buff *skb, 149062306a36Sopenharmony_ci struct ath10k_fw_stats *stats) 149162306a36Sopenharmony_ci{ 149262306a36Sopenharmony_ci const void **tb; 149362306a36Sopenharmony_ci const struct wmi_tlv_stats_ev *ev; 149462306a36Sopenharmony_ci u32 num_peer_stats_extd; 149562306a36Sopenharmony_ci const void *data; 149662306a36Sopenharmony_ci u32 num_pdev_stats; 149762306a36Sopenharmony_ci u32 num_vdev_stats; 149862306a36Sopenharmony_ci u32 num_peer_stats; 149962306a36Sopenharmony_ci u32 num_bcnflt_stats; 150062306a36Sopenharmony_ci u32 num_chan_stats; 150162306a36Sopenharmony_ci size_t data_len; 150262306a36Sopenharmony_ci u32 stats_id; 150362306a36Sopenharmony_ci int ret; 150462306a36Sopenharmony_ci int i; 150562306a36Sopenharmony_ci 150662306a36Sopenharmony_ci tb = ath10k_wmi_tlv_parse_alloc(ar, skb->data, skb->len, GFP_ATOMIC); 150762306a36Sopenharmony_ci if (IS_ERR(tb)) { 150862306a36Sopenharmony_ci ret = PTR_ERR(tb); 150962306a36Sopenharmony_ci ath10k_warn(ar, "failed to parse tlv: %d\n", ret); 151062306a36Sopenharmony_ci return ret; 151162306a36Sopenharmony_ci } 151262306a36Sopenharmony_ci 151362306a36Sopenharmony_ci ev = tb[WMI_TLV_TAG_STRUCT_STATS_EVENT]; 151462306a36Sopenharmony_ci data = tb[WMI_TLV_TAG_ARRAY_BYTE]; 151562306a36Sopenharmony_ci 151662306a36Sopenharmony_ci if (!ev || !data) { 151762306a36Sopenharmony_ci kfree(tb); 151862306a36Sopenharmony_ci return -EPROTO; 151962306a36Sopenharmony_ci } 152062306a36Sopenharmony_ci 152162306a36Sopenharmony_ci data_len = ath10k_wmi_tlv_len(data); 152262306a36Sopenharmony_ci num_pdev_stats = __le32_to_cpu(ev->num_pdev_stats); 152362306a36Sopenharmony_ci num_vdev_stats = __le32_to_cpu(ev->num_vdev_stats); 152462306a36Sopenharmony_ci num_peer_stats = __le32_to_cpu(ev->num_peer_stats); 152562306a36Sopenharmony_ci num_bcnflt_stats = __le32_to_cpu(ev->num_bcnflt_stats); 152662306a36Sopenharmony_ci num_chan_stats = __le32_to_cpu(ev->num_chan_stats); 152762306a36Sopenharmony_ci stats_id = __le32_to_cpu(ev->stats_id); 152862306a36Sopenharmony_ci num_peer_stats_extd = __le32_to_cpu(ev->num_peer_stats_extd); 152962306a36Sopenharmony_ci 153062306a36Sopenharmony_ci ath10k_dbg(ar, ATH10K_DBG_WMI, 153162306a36Sopenharmony_ci "wmi tlv stats update pdev %i vdev %i peer %i bcnflt %i chan %i peer_extd %i\n", 153262306a36Sopenharmony_ci num_pdev_stats, num_vdev_stats, num_peer_stats, 153362306a36Sopenharmony_ci num_bcnflt_stats, num_chan_stats, num_peer_stats_extd); 153462306a36Sopenharmony_ci 153562306a36Sopenharmony_ci for (i = 0; i < num_pdev_stats; i++) { 153662306a36Sopenharmony_ci const struct wmi_pdev_stats *src; 153762306a36Sopenharmony_ci struct ath10k_fw_stats_pdev *dst; 153862306a36Sopenharmony_ci 153962306a36Sopenharmony_ci src = data; 154062306a36Sopenharmony_ci if (data_len < sizeof(*src)) { 154162306a36Sopenharmony_ci kfree(tb); 154262306a36Sopenharmony_ci return -EPROTO; 154362306a36Sopenharmony_ci } 154462306a36Sopenharmony_ci 154562306a36Sopenharmony_ci data += sizeof(*src); 154662306a36Sopenharmony_ci data_len -= sizeof(*src); 154762306a36Sopenharmony_ci 154862306a36Sopenharmony_ci dst = kzalloc(sizeof(*dst), GFP_ATOMIC); 154962306a36Sopenharmony_ci if (!dst) 155062306a36Sopenharmony_ci continue; 155162306a36Sopenharmony_ci 155262306a36Sopenharmony_ci ath10k_wmi_pull_pdev_stats_base(&src->base, dst); 155362306a36Sopenharmony_ci ath10k_wmi_pull_pdev_stats_tx(&src->tx, dst); 155462306a36Sopenharmony_ci ath10k_wmi_pull_pdev_stats_rx(&src->rx, dst); 155562306a36Sopenharmony_ci list_add_tail(&dst->list, &stats->pdevs); 155662306a36Sopenharmony_ci } 155762306a36Sopenharmony_ci 155862306a36Sopenharmony_ci for (i = 0; i < num_vdev_stats; i++) { 155962306a36Sopenharmony_ci const struct wmi_tlv_vdev_stats *src; 156062306a36Sopenharmony_ci struct ath10k_fw_stats_vdev *dst; 156162306a36Sopenharmony_ci 156262306a36Sopenharmony_ci src = data; 156362306a36Sopenharmony_ci if (data_len < sizeof(*src)) { 156462306a36Sopenharmony_ci kfree(tb); 156562306a36Sopenharmony_ci return -EPROTO; 156662306a36Sopenharmony_ci } 156762306a36Sopenharmony_ci 156862306a36Sopenharmony_ci data += sizeof(*src); 156962306a36Sopenharmony_ci data_len -= sizeof(*src); 157062306a36Sopenharmony_ci 157162306a36Sopenharmony_ci dst = kzalloc(sizeof(*dst), GFP_ATOMIC); 157262306a36Sopenharmony_ci if (!dst) 157362306a36Sopenharmony_ci continue; 157462306a36Sopenharmony_ci 157562306a36Sopenharmony_ci ath10k_wmi_tlv_pull_vdev_stats(src, dst); 157662306a36Sopenharmony_ci list_add_tail(&dst->list, &stats->vdevs); 157762306a36Sopenharmony_ci } 157862306a36Sopenharmony_ci 157962306a36Sopenharmony_ci for (i = 0; i < num_peer_stats; i++) { 158062306a36Sopenharmony_ci const struct wmi_10x_peer_stats *src; 158162306a36Sopenharmony_ci struct ath10k_fw_stats_peer *dst; 158262306a36Sopenharmony_ci 158362306a36Sopenharmony_ci src = data; 158462306a36Sopenharmony_ci if (data_len < sizeof(*src)) { 158562306a36Sopenharmony_ci kfree(tb); 158662306a36Sopenharmony_ci return -EPROTO; 158762306a36Sopenharmony_ci } 158862306a36Sopenharmony_ci 158962306a36Sopenharmony_ci data += sizeof(*src); 159062306a36Sopenharmony_ci data_len -= sizeof(*src); 159162306a36Sopenharmony_ci 159262306a36Sopenharmony_ci dst = kzalloc(sizeof(*dst), GFP_ATOMIC); 159362306a36Sopenharmony_ci if (!dst) 159462306a36Sopenharmony_ci continue; 159562306a36Sopenharmony_ci 159662306a36Sopenharmony_ci ath10k_wmi_pull_peer_stats(&src->old, dst); 159762306a36Sopenharmony_ci dst->peer_rx_rate = __le32_to_cpu(src->peer_rx_rate); 159862306a36Sopenharmony_ci 159962306a36Sopenharmony_ci if (stats_id & WMI_TLV_STAT_PEER_EXTD) { 160062306a36Sopenharmony_ci const struct wmi_tlv_peer_stats_extd *extd; 160162306a36Sopenharmony_ci unsigned long rx_duration_high; 160262306a36Sopenharmony_ci 160362306a36Sopenharmony_ci extd = data + sizeof(*src) * (num_peer_stats - i - 1) 160462306a36Sopenharmony_ci + sizeof(*extd) * i; 160562306a36Sopenharmony_ci 160662306a36Sopenharmony_ci dst->rx_duration = __le32_to_cpu(extd->rx_duration); 160762306a36Sopenharmony_ci rx_duration_high = __le32_to_cpu 160862306a36Sopenharmony_ci (extd->rx_duration_high); 160962306a36Sopenharmony_ci 161062306a36Sopenharmony_ci if (test_bit(WMI_TLV_PEER_RX_DURATION_HIGH_VALID_BIT, 161162306a36Sopenharmony_ci &rx_duration_high)) { 161262306a36Sopenharmony_ci rx_duration_high = 161362306a36Sopenharmony_ci FIELD_GET(WMI_TLV_PEER_RX_DURATION_HIGH_MASK, 161462306a36Sopenharmony_ci rx_duration_high); 161562306a36Sopenharmony_ci dst->rx_duration |= (u64)rx_duration_high << 161662306a36Sopenharmony_ci WMI_TLV_PEER_RX_DURATION_SHIFT; 161762306a36Sopenharmony_ci } 161862306a36Sopenharmony_ci } 161962306a36Sopenharmony_ci 162062306a36Sopenharmony_ci list_add_tail(&dst->list, &stats->peers); 162162306a36Sopenharmony_ci } 162262306a36Sopenharmony_ci 162362306a36Sopenharmony_ci kfree(tb); 162462306a36Sopenharmony_ci return 0; 162562306a36Sopenharmony_ci} 162662306a36Sopenharmony_ci 162762306a36Sopenharmony_cistatic int ath10k_wmi_tlv_op_pull_roam_ev(struct ath10k *ar, 162862306a36Sopenharmony_ci struct sk_buff *skb, 162962306a36Sopenharmony_ci struct wmi_roam_ev_arg *arg) 163062306a36Sopenharmony_ci{ 163162306a36Sopenharmony_ci const void **tb; 163262306a36Sopenharmony_ci const struct wmi_tlv_roam_ev *ev; 163362306a36Sopenharmony_ci int ret; 163462306a36Sopenharmony_ci 163562306a36Sopenharmony_ci tb = ath10k_wmi_tlv_parse_alloc(ar, skb->data, skb->len, GFP_ATOMIC); 163662306a36Sopenharmony_ci if (IS_ERR(tb)) { 163762306a36Sopenharmony_ci ret = PTR_ERR(tb); 163862306a36Sopenharmony_ci ath10k_warn(ar, "failed to parse tlv: %d\n", ret); 163962306a36Sopenharmony_ci return ret; 164062306a36Sopenharmony_ci } 164162306a36Sopenharmony_ci 164262306a36Sopenharmony_ci ev = tb[WMI_TLV_TAG_STRUCT_ROAM_EVENT]; 164362306a36Sopenharmony_ci if (!ev) { 164462306a36Sopenharmony_ci kfree(tb); 164562306a36Sopenharmony_ci return -EPROTO; 164662306a36Sopenharmony_ci } 164762306a36Sopenharmony_ci 164862306a36Sopenharmony_ci arg->vdev_id = ev->vdev_id; 164962306a36Sopenharmony_ci arg->reason = ev->reason; 165062306a36Sopenharmony_ci arg->rssi = ev->rssi; 165162306a36Sopenharmony_ci 165262306a36Sopenharmony_ci kfree(tb); 165362306a36Sopenharmony_ci return 0; 165462306a36Sopenharmony_ci} 165562306a36Sopenharmony_ci 165662306a36Sopenharmony_cistatic int 165762306a36Sopenharmony_ciath10k_wmi_tlv_op_pull_wow_ev(struct ath10k *ar, struct sk_buff *skb, 165862306a36Sopenharmony_ci struct wmi_wow_ev_arg *arg) 165962306a36Sopenharmony_ci{ 166062306a36Sopenharmony_ci const void **tb; 166162306a36Sopenharmony_ci const struct wmi_tlv_wow_event_info *ev; 166262306a36Sopenharmony_ci int ret; 166362306a36Sopenharmony_ci 166462306a36Sopenharmony_ci tb = ath10k_wmi_tlv_parse_alloc(ar, skb->data, skb->len, GFP_ATOMIC); 166562306a36Sopenharmony_ci if (IS_ERR(tb)) { 166662306a36Sopenharmony_ci ret = PTR_ERR(tb); 166762306a36Sopenharmony_ci ath10k_warn(ar, "failed to parse tlv: %d\n", ret); 166862306a36Sopenharmony_ci return ret; 166962306a36Sopenharmony_ci } 167062306a36Sopenharmony_ci 167162306a36Sopenharmony_ci ev = tb[WMI_TLV_TAG_STRUCT_WOW_EVENT_INFO]; 167262306a36Sopenharmony_ci if (!ev) { 167362306a36Sopenharmony_ci kfree(tb); 167462306a36Sopenharmony_ci return -EPROTO; 167562306a36Sopenharmony_ci } 167662306a36Sopenharmony_ci 167762306a36Sopenharmony_ci arg->vdev_id = __le32_to_cpu(ev->vdev_id); 167862306a36Sopenharmony_ci arg->flag = __le32_to_cpu(ev->flag); 167962306a36Sopenharmony_ci arg->wake_reason = __le32_to_cpu(ev->wake_reason); 168062306a36Sopenharmony_ci arg->data_len = __le32_to_cpu(ev->data_len); 168162306a36Sopenharmony_ci 168262306a36Sopenharmony_ci kfree(tb); 168362306a36Sopenharmony_ci return 0; 168462306a36Sopenharmony_ci} 168562306a36Sopenharmony_ci 168662306a36Sopenharmony_cistatic int ath10k_wmi_tlv_op_pull_echo_ev(struct ath10k *ar, 168762306a36Sopenharmony_ci struct sk_buff *skb, 168862306a36Sopenharmony_ci struct wmi_echo_ev_arg *arg) 168962306a36Sopenharmony_ci{ 169062306a36Sopenharmony_ci const void **tb; 169162306a36Sopenharmony_ci const struct wmi_echo_event *ev; 169262306a36Sopenharmony_ci int ret; 169362306a36Sopenharmony_ci 169462306a36Sopenharmony_ci tb = ath10k_wmi_tlv_parse_alloc(ar, skb->data, skb->len, GFP_ATOMIC); 169562306a36Sopenharmony_ci if (IS_ERR(tb)) { 169662306a36Sopenharmony_ci ret = PTR_ERR(tb); 169762306a36Sopenharmony_ci ath10k_warn(ar, "failed to parse tlv: %d\n", ret); 169862306a36Sopenharmony_ci return ret; 169962306a36Sopenharmony_ci } 170062306a36Sopenharmony_ci 170162306a36Sopenharmony_ci ev = tb[WMI_TLV_TAG_STRUCT_ECHO_EVENT]; 170262306a36Sopenharmony_ci if (!ev) { 170362306a36Sopenharmony_ci kfree(tb); 170462306a36Sopenharmony_ci return -EPROTO; 170562306a36Sopenharmony_ci } 170662306a36Sopenharmony_ci 170762306a36Sopenharmony_ci arg->value = ev->value; 170862306a36Sopenharmony_ci 170962306a36Sopenharmony_ci kfree(tb); 171062306a36Sopenharmony_ci return 0; 171162306a36Sopenharmony_ci} 171262306a36Sopenharmony_ci 171362306a36Sopenharmony_cistatic struct sk_buff * 171462306a36Sopenharmony_ciath10k_wmi_tlv_op_gen_pdev_suspend(struct ath10k *ar, u32 opt) 171562306a36Sopenharmony_ci{ 171662306a36Sopenharmony_ci struct wmi_tlv_pdev_suspend *cmd; 171762306a36Sopenharmony_ci struct wmi_tlv *tlv; 171862306a36Sopenharmony_ci struct sk_buff *skb; 171962306a36Sopenharmony_ci 172062306a36Sopenharmony_ci skb = ath10k_wmi_alloc_skb(ar, sizeof(*tlv) + sizeof(*cmd)); 172162306a36Sopenharmony_ci if (!skb) 172262306a36Sopenharmony_ci return ERR_PTR(-ENOMEM); 172362306a36Sopenharmony_ci 172462306a36Sopenharmony_ci tlv = (void *)skb->data; 172562306a36Sopenharmony_ci tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_PDEV_SUSPEND_CMD); 172662306a36Sopenharmony_ci tlv->len = __cpu_to_le16(sizeof(*cmd)); 172762306a36Sopenharmony_ci cmd = (void *)tlv->value; 172862306a36Sopenharmony_ci cmd->opt = __cpu_to_le32(opt); 172962306a36Sopenharmony_ci 173062306a36Sopenharmony_ci ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv pdev suspend\n"); 173162306a36Sopenharmony_ci return skb; 173262306a36Sopenharmony_ci} 173362306a36Sopenharmony_ci 173462306a36Sopenharmony_cistatic struct sk_buff * 173562306a36Sopenharmony_ciath10k_wmi_tlv_op_gen_pdev_resume(struct ath10k *ar) 173662306a36Sopenharmony_ci{ 173762306a36Sopenharmony_ci struct wmi_tlv_resume_cmd *cmd; 173862306a36Sopenharmony_ci struct wmi_tlv *tlv; 173962306a36Sopenharmony_ci struct sk_buff *skb; 174062306a36Sopenharmony_ci 174162306a36Sopenharmony_ci skb = ath10k_wmi_alloc_skb(ar, sizeof(*tlv) + sizeof(*cmd)); 174262306a36Sopenharmony_ci if (!skb) 174362306a36Sopenharmony_ci return ERR_PTR(-ENOMEM); 174462306a36Sopenharmony_ci 174562306a36Sopenharmony_ci tlv = (void *)skb->data; 174662306a36Sopenharmony_ci tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_PDEV_RESUME_CMD); 174762306a36Sopenharmony_ci tlv->len = __cpu_to_le16(sizeof(*cmd)); 174862306a36Sopenharmony_ci cmd = (void *)tlv->value; 174962306a36Sopenharmony_ci cmd->reserved = __cpu_to_le32(0); 175062306a36Sopenharmony_ci 175162306a36Sopenharmony_ci ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv pdev resume\n"); 175262306a36Sopenharmony_ci return skb; 175362306a36Sopenharmony_ci} 175462306a36Sopenharmony_ci 175562306a36Sopenharmony_cistatic struct sk_buff * 175662306a36Sopenharmony_ciath10k_wmi_tlv_op_gen_pdev_set_rd(struct ath10k *ar, 175762306a36Sopenharmony_ci u16 rd, u16 rd2g, u16 rd5g, 175862306a36Sopenharmony_ci u16 ctl2g, u16 ctl5g, 175962306a36Sopenharmony_ci enum wmi_dfs_region dfs_reg) 176062306a36Sopenharmony_ci{ 176162306a36Sopenharmony_ci struct wmi_tlv_pdev_set_rd_cmd *cmd; 176262306a36Sopenharmony_ci struct wmi_tlv *tlv; 176362306a36Sopenharmony_ci struct sk_buff *skb; 176462306a36Sopenharmony_ci 176562306a36Sopenharmony_ci skb = ath10k_wmi_alloc_skb(ar, sizeof(*tlv) + sizeof(*cmd)); 176662306a36Sopenharmony_ci if (!skb) 176762306a36Sopenharmony_ci return ERR_PTR(-ENOMEM); 176862306a36Sopenharmony_ci 176962306a36Sopenharmony_ci tlv = (void *)skb->data; 177062306a36Sopenharmony_ci tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_PDEV_SET_REGDOMAIN_CMD); 177162306a36Sopenharmony_ci tlv->len = __cpu_to_le16(sizeof(*cmd)); 177262306a36Sopenharmony_ci cmd = (void *)tlv->value; 177362306a36Sopenharmony_ci cmd->regd = __cpu_to_le32(rd); 177462306a36Sopenharmony_ci cmd->regd_2ghz = __cpu_to_le32(rd2g); 177562306a36Sopenharmony_ci cmd->regd_5ghz = __cpu_to_le32(rd5g); 177662306a36Sopenharmony_ci cmd->conform_limit_2ghz = __cpu_to_le32(ctl2g); 177762306a36Sopenharmony_ci cmd->conform_limit_5ghz = __cpu_to_le32(ctl5g); 177862306a36Sopenharmony_ci 177962306a36Sopenharmony_ci ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv pdev set rd\n"); 178062306a36Sopenharmony_ci return skb; 178162306a36Sopenharmony_ci} 178262306a36Sopenharmony_ci 178362306a36Sopenharmony_cistatic enum wmi_txbf_conf ath10k_wmi_tlv_txbf_conf_scheme(struct ath10k *ar) 178462306a36Sopenharmony_ci{ 178562306a36Sopenharmony_ci return WMI_TXBF_CONF_AFTER_ASSOC; 178662306a36Sopenharmony_ci} 178762306a36Sopenharmony_ci 178862306a36Sopenharmony_cistatic struct sk_buff * 178962306a36Sopenharmony_ciath10k_wmi_tlv_op_gen_pdev_set_param(struct ath10k *ar, u32 param_id, 179062306a36Sopenharmony_ci u32 param_value) 179162306a36Sopenharmony_ci{ 179262306a36Sopenharmony_ci struct wmi_tlv_pdev_set_param_cmd *cmd; 179362306a36Sopenharmony_ci struct wmi_tlv *tlv; 179462306a36Sopenharmony_ci struct sk_buff *skb; 179562306a36Sopenharmony_ci 179662306a36Sopenharmony_ci skb = ath10k_wmi_alloc_skb(ar, sizeof(*tlv) + sizeof(*cmd)); 179762306a36Sopenharmony_ci if (!skb) 179862306a36Sopenharmony_ci return ERR_PTR(-ENOMEM); 179962306a36Sopenharmony_ci 180062306a36Sopenharmony_ci tlv = (void *)skb->data; 180162306a36Sopenharmony_ci tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_PDEV_SET_PARAM_CMD); 180262306a36Sopenharmony_ci tlv->len = __cpu_to_le16(sizeof(*cmd)); 180362306a36Sopenharmony_ci cmd = (void *)tlv->value; 180462306a36Sopenharmony_ci cmd->param_id = __cpu_to_le32(param_id); 180562306a36Sopenharmony_ci cmd->param_value = __cpu_to_le32(param_value); 180662306a36Sopenharmony_ci 180762306a36Sopenharmony_ci ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv pdev set param %d value 0x%x\n", 180862306a36Sopenharmony_ci param_id, param_value); 180962306a36Sopenharmony_ci return skb; 181062306a36Sopenharmony_ci} 181162306a36Sopenharmony_ci 181262306a36Sopenharmony_cistatic void 181362306a36Sopenharmony_ciath10k_wmi_tlv_put_host_mem_chunks(struct ath10k *ar, void *host_mem_chunks) 181462306a36Sopenharmony_ci{ 181562306a36Sopenharmony_ci struct host_memory_chunk_tlv *chunk; 181662306a36Sopenharmony_ci struct wmi_tlv *tlv; 181762306a36Sopenharmony_ci dma_addr_t paddr; 181862306a36Sopenharmony_ci int i; 181962306a36Sopenharmony_ci __le16 tlv_len, tlv_tag; 182062306a36Sopenharmony_ci 182162306a36Sopenharmony_ci tlv_tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_WLAN_HOST_MEMORY_CHUNK); 182262306a36Sopenharmony_ci tlv_len = __cpu_to_le16(sizeof(*chunk)); 182362306a36Sopenharmony_ci for (i = 0; i < ar->wmi.num_mem_chunks; i++) { 182462306a36Sopenharmony_ci tlv = host_mem_chunks; 182562306a36Sopenharmony_ci tlv->tag = tlv_tag; 182662306a36Sopenharmony_ci tlv->len = tlv_len; 182762306a36Sopenharmony_ci chunk = (void *)tlv->value; 182862306a36Sopenharmony_ci 182962306a36Sopenharmony_ci chunk->ptr = __cpu_to_le32(ar->wmi.mem_chunks[i].paddr); 183062306a36Sopenharmony_ci chunk->size = __cpu_to_le32(ar->wmi.mem_chunks[i].len); 183162306a36Sopenharmony_ci chunk->req_id = __cpu_to_le32(ar->wmi.mem_chunks[i].req_id); 183262306a36Sopenharmony_ci 183362306a36Sopenharmony_ci if (test_bit(WMI_SERVICE_SUPPORT_EXTEND_ADDRESS, 183462306a36Sopenharmony_ci ar->wmi.svc_map)) { 183562306a36Sopenharmony_ci paddr = ar->wmi.mem_chunks[i].paddr; 183662306a36Sopenharmony_ci chunk->ptr_high = __cpu_to_le32(upper_32_bits(paddr)); 183762306a36Sopenharmony_ci } 183862306a36Sopenharmony_ci 183962306a36Sopenharmony_ci ath10k_dbg(ar, ATH10K_DBG_WMI, 184062306a36Sopenharmony_ci "wmi-tlv chunk %d len %d, addr 0x%llx, id 0x%x\n", 184162306a36Sopenharmony_ci i, 184262306a36Sopenharmony_ci ar->wmi.mem_chunks[i].len, 184362306a36Sopenharmony_ci (unsigned long long)ar->wmi.mem_chunks[i].paddr, 184462306a36Sopenharmony_ci ar->wmi.mem_chunks[i].req_id); 184562306a36Sopenharmony_ci 184662306a36Sopenharmony_ci host_mem_chunks += sizeof(*tlv); 184762306a36Sopenharmony_ci host_mem_chunks += sizeof(*chunk); 184862306a36Sopenharmony_ci } 184962306a36Sopenharmony_ci} 185062306a36Sopenharmony_ci 185162306a36Sopenharmony_cistatic struct sk_buff *ath10k_wmi_tlv_op_gen_init(struct ath10k *ar) 185262306a36Sopenharmony_ci{ 185362306a36Sopenharmony_ci struct sk_buff *skb; 185462306a36Sopenharmony_ci struct wmi_tlv *tlv; 185562306a36Sopenharmony_ci struct wmi_tlv_init_cmd *cmd; 185662306a36Sopenharmony_ci struct wmi_tlv_resource_config *cfg; 185762306a36Sopenharmony_ci void *chunks; 185862306a36Sopenharmony_ci size_t len, chunks_len; 185962306a36Sopenharmony_ci void *ptr; 186062306a36Sopenharmony_ci 186162306a36Sopenharmony_ci chunks_len = ar->wmi.num_mem_chunks * 186262306a36Sopenharmony_ci (sizeof(struct host_memory_chunk_tlv) + sizeof(*tlv)); 186362306a36Sopenharmony_ci len = (sizeof(*tlv) + sizeof(*cmd)) + 186462306a36Sopenharmony_ci (sizeof(*tlv) + sizeof(*cfg)) + 186562306a36Sopenharmony_ci (sizeof(*tlv) + chunks_len); 186662306a36Sopenharmony_ci 186762306a36Sopenharmony_ci skb = ath10k_wmi_alloc_skb(ar, len); 186862306a36Sopenharmony_ci if (!skb) 186962306a36Sopenharmony_ci return ERR_PTR(-ENOMEM); 187062306a36Sopenharmony_ci 187162306a36Sopenharmony_ci ptr = skb->data; 187262306a36Sopenharmony_ci 187362306a36Sopenharmony_ci tlv = ptr; 187462306a36Sopenharmony_ci tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_INIT_CMD); 187562306a36Sopenharmony_ci tlv->len = __cpu_to_le16(sizeof(*cmd)); 187662306a36Sopenharmony_ci cmd = (void *)tlv->value; 187762306a36Sopenharmony_ci ptr += sizeof(*tlv); 187862306a36Sopenharmony_ci ptr += sizeof(*cmd); 187962306a36Sopenharmony_ci 188062306a36Sopenharmony_ci tlv = ptr; 188162306a36Sopenharmony_ci tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_RESOURCE_CONFIG); 188262306a36Sopenharmony_ci tlv->len = __cpu_to_le16(sizeof(*cfg)); 188362306a36Sopenharmony_ci cfg = (void *)tlv->value; 188462306a36Sopenharmony_ci ptr += sizeof(*tlv); 188562306a36Sopenharmony_ci ptr += sizeof(*cfg); 188662306a36Sopenharmony_ci 188762306a36Sopenharmony_ci tlv = ptr; 188862306a36Sopenharmony_ci tlv->tag = __cpu_to_le16(WMI_TLV_TAG_ARRAY_STRUCT); 188962306a36Sopenharmony_ci tlv->len = __cpu_to_le16(chunks_len); 189062306a36Sopenharmony_ci chunks = (void *)tlv->value; 189162306a36Sopenharmony_ci 189262306a36Sopenharmony_ci ptr += sizeof(*tlv); 189362306a36Sopenharmony_ci ptr += chunks_len; 189462306a36Sopenharmony_ci 189562306a36Sopenharmony_ci cmd->abi.abi_ver0 = __cpu_to_le32(WMI_TLV_ABI_VER0); 189662306a36Sopenharmony_ci cmd->abi.abi_ver1 = __cpu_to_le32(WMI_TLV_ABI_VER1); 189762306a36Sopenharmony_ci cmd->abi.abi_ver_ns0 = __cpu_to_le32(WMI_TLV_ABI_VER_NS0); 189862306a36Sopenharmony_ci cmd->abi.abi_ver_ns1 = __cpu_to_le32(WMI_TLV_ABI_VER_NS1); 189962306a36Sopenharmony_ci cmd->abi.abi_ver_ns2 = __cpu_to_le32(WMI_TLV_ABI_VER_NS2); 190062306a36Sopenharmony_ci cmd->abi.abi_ver_ns3 = __cpu_to_le32(WMI_TLV_ABI_VER_NS3); 190162306a36Sopenharmony_ci cmd->num_host_mem_chunks = __cpu_to_le32(ar->wmi.num_mem_chunks); 190262306a36Sopenharmony_ci 190362306a36Sopenharmony_ci cfg->num_vdevs = __cpu_to_le32(TARGET_TLV_NUM_VDEVS); 190462306a36Sopenharmony_ci 190562306a36Sopenharmony_ci if (ar->hw_params.num_peers) 190662306a36Sopenharmony_ci cfg->num_peers = __cpu_to_le32(ar->hw_params.num_peers); 190762306a36Sopenharmony_ci else 190862306a36Sopenharmony_ci cfg->num_peers = __cpu_to_le32(TARGET_TLV_NUM_PEERS); 190962306a36Sopenharmony_ci cfg->ast_skid_limit = __cpu_to_le32(ar->hw_params.ast_skid_limit); 191062306a36Sopenharmony_ci cfg->num_wds_entries = __cpu_to_le32(ar->hw_params.num_wds_entries); 191162306a36Sopenharmony_ci 191262306a36Sopenharmony_ci if (test_bit(WMI_SERVICE_RX_FULL_REORDER, ar->wmi.svc_map)) { 191362306a36Sopenharmony_ci cfg->num_offload_peers = __cpu_to_le32(TARGET_TLV_NUM_VDEVS); 191462306a36Sopenharmony_ci cfg->num_offload_reorder_bufs = __cpu_to_le32(TARGET_TLV_NUM_VDEVS); 191562306a36Sopenharmony_ci } else { 191662306a36Sopenharmony_ci cfg->num_offload_peers = __cpu_to_le32(0); 191762306a36Sopenharmony_ci cfg->num_offload_reorder_bufs = __cpu_to_le32(0); 191862306a36Sopenharmony_ci } 191962306a36Sopenharmony_ci 192062306a36Sopenharmony_ci cfg->num_peer_keys = __cpu_to_le32(2); 192162306a36Sopenharmony_ci if (ar->hw_params.num_peers) 192262306a36Sopenharmony_ci cfg->num_tids = __cpu_to_le32(ar->hw_params.num_peers * 2); 192362306a36Sopenharmony_ci else 192462306a36Sopenharmony_ci cfg->num_tids = __cpu_to_le32(TARGET_TLV_NUM_TIDS); 192562306a36Sopenharmony_ci cfg->tx_chain_mask = __cpu_to_le32(0x7); 192662306a36Sopenharmony_ci cfg->rx_chain_mask = __cpu_to_le32(0x7); 192762306a36Sopenharmony_ci cfg->rx_timeout_pri[0] = __cpu_to_le32(0x64); 192862306a36Sopenharmony_ci cfg->rx_timeout_pri[1] = __cpu_to_le32(0x64); 192962306a36Sopenharmony_ci cfg->rx_timeout_pri[2] = __cpu_to_le32(0x64); 193062306a36Sopenharmony_ci cfg->rx_timeout_pri[3] = __cpu_to_le32(0x28); 193162306a36Sopenharmony_ci cfg->rx_decap_mode = __cpu_to_le32(ar->wmi.rx_decap_mode); 193262306a36Sopenharmony_ci cfg->scan_max_pending_reqs = __cpu_to_le32(4); 193362306a36Sopenharmony_ci cfg->bmiss_offload_max_vdev = __cpu_to_le32(TARGET_TLV_NUM_VDEVS); 193462306a36Sopenharmony_ci cfg->roam_offload_max_vdev = __cpu_to_le32(TARGET_TLV_NUM_VDEVS); 193562306a36Sopenharmony_ci cfg->roam_offload_max_ap_profiles = __cpu_to_le32(8); 193662306a36Sopenharmony_ci cfg->num_mcast_groups = __cpu_to_le32(0); 193762306a36Sopenharmony_ci cfg->num_mcast_table_elems = __cpu_to_le32(0); 193862306a36Sopenharmony_ci cfg->mcast2ucast_mode = __cpu_to_le32(0); 193962306a36Sopenharmony_ci cfg->tx_dbg_log_size = __cpu_to_le32(0x400); 194062306a36Sopenharmony_ci cfg->dma_burst_size = __cpu_to_le32(0); 194162306a36Sopenharmony_ci cfg->mac_aggr_delim = __cpu_to_le32(0); 194262306a36Sopenharmony_ci cfg->rx_skip_defrag_timeout_dup_detection_check = __cpu_to_le32(0); 194362306a36Sopenharmony_ci cfg->vow_config = __cpu_to_le32(0); 194462306a36Sopenharmony_ci cfg->gtk_offload_max_vdev = __cpu_to_le32(2); 194562306a36Sopenharmony_ci cfg->num_msdu_desc = __cpu_to_le32(ar->htt.max_num_pending_tx); 194662306a36Sopenharmony_ci cfg->max_frag_entries = __cpu_to_le32(2); 194762306a36Sopenharmony_ci cfg->num_tdls_vdevs = __cpu_to_le32(TARGET_TLV_NUM_TDLS_VDEVS); 194862306a36Sopenharmony_ci cfg->num_tdls_conn_table_entries = __cpu_to_le32(0x20); 194962306a36Sopenharmony_ci cfg->beacon_tx_offload_max_vdev = __cpu_to_le32(2); 195062306a36Sopenharmony_ci cfg->num_multicast_filter_entries = __cpu_to_le32(5); 195162306a36Sopenharmony_ci cfg->num_wow_filters = __cpu_to_le32(ar->wow.max_num_patterns); 195262306a36Sopenharmony_ci cfg->num_keep_alive_pattern = __cpu_to_le32(6); 195362306a36Sopenharmony_ci cfg->keep_alive_pattern_size = __cpu_to_le32(0); 195462306a36Sopenharmony_ci cfg->max_tdls_concurrent_sleep_sta = __cpu_to_le32(1); 195562306a36Sopenharmony_ci cfg->max_tdls_concurrent_buffer_sta = __cpu_to_le32(1); 195662306a36Sopenharmony_ci cfg->wmi_send_separate = __cpu_to_le32(0); 195762306a36Sopenharmony_ci cfg->num_ocb_vdevs = __cpu_to_le32(0); 195862306a36Sopenharmony_ci cfg->num_ocb_channels = __cpu_to_le32(0); 195962306a36Sopenharmony_ci cfg->num_ocb_schedules = __cpu_to_le32(0); 196062306a36Sopenharmony_ci cfg->host_capab = __cpu_to_le32(WMI_TLV_FLAG_MGMT_BUNDLE_TX_COMPL); 196162306a36Sopenharmony_ci 196262306a36Sopenharmony_ci if (test_bit(WMI_SERVICE_TX_DATA_ACK_RSSI, ar->wmi.svc_map)) 196362306a36Sopenharmony_ci cfg->host_capab |= __cpu_to_le32(WMI_RSRC_CFG_FLAG_TX_ACK_RSSI); 196462306a36Sopenharmony_ci 196562306a36Sopenharmony_ci ath10k_wmi_tlv_put_host_mem_chunks(ar, chunks); 196662306a36Sopenharmony_ci 196762306a36Sopenharmony_ci ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv init\n"); 196862306a36Sopenharmony_ci return skb; 196962306a36Sopenharmony_ci} 197062306a36Sopenharmony_ci 197162306a36Sopenharmony_cistatic struct sk_buff * 197262306a36Sopenharmony_ciath10k_wmi_tlv_op_gen_start_scan(struct ath10k *ar, 197362306a36Sopenharmony_ci const struct wmi_start_scan_arg *arg) 197462306a36Sopenharmony_ci{ 197562306a36Sopenharmony_ci struct wmi_tlv_start_scan_cmd *cmd; 197662306a36Sopenharmony_ci struct wmi_tlv *tlv; 197762306a36Sopenharmony_ci struct sk_buff *skb; 197862306a36Sopenharmony_ci size_t len, chan_len, ssid_len, bssid_len, ie_len; 197962306a36Sopenharmony_ci __le32 *chans; 198062306a36Sopenharmony_ci struct wmi_ssid *ssids; 198162306a36Sopenharmony_ci struct wmi_mac_addr *addrs; 198262306a36Sopenharmony_ci void *ptr; 198362306a36Sopenharmony_ci int i, ret; 198462306a36Sopenharmony_ci 198562306a36Sopenharmony_ci ret = ath10k_wmi_start_scan_verify(arg); 198662306a36Sopenharmony_ci if (ret) 198762306a36Sopenharmony_ci return ERR_PTR(ret); 198862306a36Sopenharmony_ci 198962306a36Sopenharmony_ci chan_len = arg->n_channels * sizeof(__le32); 199062306a36Sopenharmony_ci ssid_len = arg->n_ssids * sizeof(struct wmi_ssid); 199162306a36Sopenharmony_ci bssid_len = arg->n_bssids * sizeof(struct wmi_mac_addr); 199262306a36Sopenharmony_ci ie_len = roundup(arg->ie_len, 4); 199362306a36Sopenharmony_ci len = (sizeof(*tlv) + sizeof(*cmd)) + 199462306a36Sopenharmony_ci sizeof(*tlv) + chan_len + 199562306a36Sopenharmony_ci sizeof(*tlv) + ssid_len + 199662306a36Sopenharmony_ci sizeof(*tlv) + bssid_len + 199762306a36Sopenharmony_ci sizeof(*tlv) + ie_len; 199862306a36Sopenharmony_ci 199962306a36Sopenharmony_ci skb = ath10k_wmi_alloc_skb(ar, len); 200062306a36Sopenharmony_ci if (!skb) 200162306a36Sopenharmony_ci return ERR_PTR(-ENOMEM); 200262306a36Sopenharmony_ci 200362306a36Sopenharmony_ci ptr = (void *)skb->data; 200462306a36Sopenharmony_ci tlv = ptr; 200562306a36Sopenharmony_ci tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_START_SCAN_CMD); 200662306a36Sopenharmony_ci tlv->len = __cpu_to_le16(sizeof(*cmd)); 200762306a36Sopenharmony_ci cmd = (void *)tlv->value; 200862306a36Sopenharmony_ci 200962306a36Sopenharmony_ci ath10k_wmi_put_start_scan_common(&cmd->common, arg); 201062306a36Sopenharmony_ci cmd->burst_duration_ms = __cpu_to_le32(arg->burst_duration_ms); 201162306a36Sopenharmony_ci cmd->num_channels = __cpu_to_le32(arg->n_channels); 201262306a36Sopenharmony_ci cmd->num_ssids = __cpu_to_le32(arg->n_ssids); 201362306a36Sopenharmony_ci cmd->num_bssids = __cpu_to_le32(arg->n_bssids); 201462306a36Sopenharmony_ci cmd->ie_len = __cpu_to_le32(arg->ie_len); 201562306a36Sopenharmony_ci cmd->num_probes = __cpu_to_le32(3); 201662306a36Sopenharmony_ci ether_addr_copy(cmd->mac_addr.addr, arg->mac_addr.addr); 201762306a36Sopenharmony_ci ether_addr_copy(cmd->mac_mask.addr, arg->mac_mask.addr); 201862306a36Sopenharmony_ci 201962306a36Sopenharmony_ci /* FIXME: There are some scan flag inconsistencies across firmwares, 202062306a36Sopenharmony_ci * e.g. WMI-TLV inverts the logic behind the following flag. 202162306a36Sopenharmony_ci */ 202262306a36Sopenharmony_ci cmd->common.scan_ctrl_flags ^= __cpu_to_le32(WMI_SCAN_FILTER_PROBE_REQ); 202362306a36Sopenharmony_ci 202462306a36Sopenharmony_ci ptr += sizeof(*tlv); 202562306a36Sopenharmony_ci ptr += sizeof(*cmd); 202662306a36Sopenharmony_ci 202762306a36Sopenharmony_ci tlv = ptr; 202862306a36Sopenharmony_ci tlv->tag = __cpu_to_le16(WMI_TLV_TAG_ARRAY_UINT32); 202962306a36Sopenharmony_ci tlv->len = __cpu_to_le16(chan_len); 203062306a36Sopenharmony_ci chans = (void *)tlv->value; 203162306a36Sopenharmony_ci for (i = 0; i < arg->n_channels; i++) 203262306a36Sopenharmony_ci chans[i] = __cpu_to_le32(arg->channels[i]); 203362306a36Sopenharmony_ci 203462306a36Sopenharmony_ci ptr += sizeof(*tlv); 203562306a36Sopenharmony_ci ptr += chan_len; 203662306a36Sopenharmony_ci 203762306a36Sopenharmony_ci tlv = ptr; 203862306a36Sopenharmony_ci tlv->tag = __cpu_to_le16(WMI_TLV_TAG_ARRAY_FIXED_STRUCT); 203962306a36Sopenharmony_ci tlv->len = __cpu_to_le16(ssid_len); 204062306a36Sopenharmony_ci ssids = (void *)tlv->value; 204162306a36Sopenharmony_ci for (i = 0; i < arg->n_ssids; i++) { 204262306a36Sopenharmony_ci ssids[i].ssid_len = __cpu_to_le32(arg->ssids[i].len); 204362306a36Sopenharmony_ci memcpy(ssids[i].ssid, arg->ssids[i].ssid, arg->ssids[i].len); 204462306a36Sopenharmony_ci } 204562306a36Sopenharmony_ci 204662306a36Sopenharmony_ci ptr += sizeof(*tlv); 204762306a36Sopenharmony_ci ptr += ssid_len; 204862306a36Sopenharmony_ci 204962306a36Sopenharmony_ci tlv = ptr; 205062306a36Sopenharmony_ci tlv->tag = __cpu_to_le16(WMI_TLV_TAG_ARRAY_FIXED_STRUCT); 205162306a36Sopenharmony_ci tlv->len = __cpu_to_le16(bssid_len); 205262306a36Sopenharmony_ci addrs = (void *)tlv->value; 205362306a36Sopenharmony_ci for (i = 0; i < arg->n_bssids; i++) 205462306a36Sopenharmony_ci ether_addr_copy(addrs[i].addr, arg->bssids[i].bssid); 205562306a36Sopenharmony_ci 205662306a36Sopenharmony_ci ptr += sizeof(*tlv); 205762306a36Sopenharmony_ci ptr += bssid_len; 205862306a36Sopenharmony_ci 205962306a36Sopenharmony_ci tlv = ptr; 206062306a36Sopenharmony_ci tlv->tag = __cpu_to_le16(WMI_TLV_TAG_ARRAY_BYTE); 206162306a36Sopenharmony_ci tlv->len = __cpu_to_le16(ie_len); 206262306a36Sopenharmony_ci memcpy(tlv->value, arg->ie, arg->ie_len); 206362306a36Sopenharmony_ci 206462306a36Sopenharmony_ci ptr += sizeof(*tlv); 206562306a36Sopenharmony_ci ptr += ie_len; 206662306a36Sopenharmony_ci 206762306a36Sopenharmony_ci ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv start scan\n"); 206862306a36Sopenharmony_ci return skb; 206962306a36Sopenharmony_ci} 207062306a36Sopenharmony_ci 207162306a36Sopenharmony_cistatic struct sk_buff * 207262306a36Sopenharmony_ciath10k_wmi_tlv_op_gen_stop_scan(struct ath10k *ar, 207362306a36Sopenharmony_ci const struct wmi_stop_scan_arg *arg) 207462306a36Sopenharmony_ci{ 207562306a36Sopenharmony_ci struct wmi_stop_scan_cmd *cmd; 207662306a36Sopenharmony_ci struct wmi_tlv *tlv; 207762306a36Sopenharmony_ci struct sk_buff *skb; 207862306a36Sopenharmony_ci u32 scan_id; 207962306a36Sopenharmony_ci u32 req_id; 208062306a36Sopenharmony_ci 208162306a36Sopenharmony_ci if (arg->req_id > 0xFFF) 208262306a36Sopenharmony_ci return ERR_PTR(-EINVAL); 208362306a36Sopenharmony_ci if (arg->req_type == WMI_SCAN_STOP_ONE && arg->u.scan_id > 0xFFF) 208462306a36Sopenharmony_ci return ERR_PTR(-EINVAL); 208562306a36Sopenharmony_ci 208662306a36Sopenharmony_ci skb = ath10k_wmi_alloc_skb(ar, sizeof(*tlv) + sizeof(*cmd)); 208762306a36Sopenharmony_ci if (!skb) 208862306a36Sopenharmony_ci return ERR_PTR(-ENOMEM); 208962306a36Sopenharmony_ci 209062306a36Sopenharmony_ci scan_id = arg->u.scan_id; 209162306a36Sopenharmony_ci scan_id |= WMI_HOST_SCAN_REQ_ID_PREFIX; 209262306a36Sopenharmony_ci 209362306a36Sopenharmony_ci req_id = arg->req_id; 209462306a36Sopenharmony_ci req_id |= WMI_HOST_SCAN_REQUESTOR_ID_PREFIX; 209562306a36Sopenharmony_ci 209662306a36Sopenharmony_ci tlv = (void *)skb->data; 209762306a36Sopenharmony_ci tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_STOP_SCAN_CMD); 209862306a36Sopenharmony_ci tlv->len = __cpu_to_le16(sizeof(*cmd)); 209962306a36Sopenharmony_ci cmd = (void *)tlv->value; 210062306a36Sopenharmony_ci cmd->req_type = __cpu_to_le32(arg->req_type); 210162306a36Sopenharmony_ci cmd->vdev_id = __cpu_to_le32(arg->u.vdev_id); 210262306a36Sopenharmony_ci cmd->scan_id = __cpu_to_le32(scan_id); 210362306a36Sopenharmony_ci cmd->scan_req_id = __cpu_to_le32(req_id); 210462306a36Sopenharmony_ci 210562306a36Sopenharmony_ci ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv stop scan\n"); 210662306a36Sopenharmony_ci return skb; 210762306a36Sopenharmony_ci} 210862306a36Sopenharmony_ci 210962306a36Sopenharmony_cistatic int ath10k_wmi_tlv_op_get_vdev_subtype(struct ath10k *ar, 211062306a36Sopenharmony_ci enum wmi_vdev_subtype subtype) 211162306a36Sopenharmony_ci{ 211262306a36Sopenharmony_ci switch (subtype) { 211362306a36Sopenharmony_ci case WMI_VDEV_SUBTYPE_NONE: 211462306a36Sopenharmony_ci return WMI_TLV_VDEV_SUBTYPE_NONE; 211562306a36Sopenharmony_ci case WMI_VDEV_SUBTYPE_P2P_DEVICE: 211662306a36Sopenharmony_ci return WMI_TLV_VDEV_SUBTYPE_P2P_DEV; 211762306a36Sopenharmony_ci case WMI_VDEV_SUBTYPE_P2P_CLIENT: 211862306a36Sopenharmony_ci return WMI_TLV_VDEV_SUBTYPE_P2P_CLI; 211962306a36Sopenharmony_ci case WMI_VDEV_SUBTYPE_P2P_GO: 212062306a36Sopenharmony_ci return WMI_TLV_VDEV_SUBTYPE_P2P_GO; 212162306a36Sopenharmony_ci case WMI_VDEV_SUBTYPE_PROXY_STA: 212262306a36Sopenharmony_ci return WMI_TLV_VDEV_SUBTYPE_PROXY_STA; 212362306a36Sopenharmony_ci case WMI_VDEV_SUBTYPE_MESH_11S: 212462306a36Sopenharmony_ci return WMI_TLV_VDEV_SUBTYPE_MESH_11S; 212562306a36Sopenharmony_ci case WMI_VDEV_SUBTYPE_MESH_NON_11S: 212662306a36Sopenharmony_ci return -ENOTSUPP; 212762306a36Sopenharmony_ci } 212862306a36Sopenharmony_ci return -ENOTSUPP; 212962306a36Sopenharmony_ci} 213062306a36Sopenharmony_ci 213162306a36Sopenharmony_cistatic struct sk_buff * 213262306a36Sopenharmony_ciath10k_wmi_tlv_op_gen_vdev_create(struct ath10k *ar, 213362306a36Sopenharmony_ci u32 vdev_id, 213462306a36Sopenharmony_ci enum wmi_vdev_type vdev_type, 213562306a36Sopenharmony_ci enum wmi_vdev_subtype vdev_subtype, 213662306a36Sopenharmony_ci const u8 mac_addr[ETH_ALEN]) 213762306a36Sopenharmony_ci{ 213862306a36Sopenharmony_ci struct wmi_vdev_create_cmd *cmd; 213962306a36Sopenharmony_ci struct wmi_tlv *tlv; 214062306a36Sopenharmony_ci struct sk_buff *skb; 214162306a36Sopenharmony_ci 214262306a36Sopenharmony_ci skb = ath10k_wmi_alloc_skb(ar, sizeof(*tlv) + sizeof(*cmd)); 214362306a36Sopenharmony_ci if (!skb) 214462306a36Sopenharmony_ci return ERR_PTR(-ENOMEM); 214562306a36Sopenharmony_ci 214662306a36Sopenharmony_ci tlv = (void *)skb->data; 214762306a36Sopenharmony_ci tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_VDEV_CREATE_CMD); 214862306a36Sopenharmony_ci tlv->len = __cpu_to_le16(sizeof(*cmd)); 214962306a36Sopenharmony_ci cmd = (void *)tlv->value; 215062306a36Sopenharmony_ci cmd->vdev_id = __cpu_to_le32(vdev_id); 215162306a36Sopenharmony_ci cmd->vdev_type = __cpu_to_le32(vdev_type); 215262306a36Sopenharmony_ci cmd->vdev_subtype = __cpu_to_le32(vdev_subtype); 215362306a36Sopenharmony_ci ether_addr_copy(cmd->vdev_macaddr.addr, mac_addr); 215462306a36Sopenharmony_ci 215562306a36Sopenharmony_ci ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv vdev create\n"); 215662306a36Sopenharmony_ci return skb; 215762306a36Sopenharmony_ci} 215862306a36Sopenharmony_ci 215962306a36Sopenharmony_cistatic struct sk_buff * 216062306a36Sopenharmony_ciath10k_wmi_tlv_op_gen_vdev_delete(struct ath10k *ar, u32 vdev_id) 216162306a36Sopenharmony_ci{ 216262306a36Sopenharmony_ci struct wmi_vdev_delete_cmd *cmd; 216362306a36Sopenharmony_ci struct wmi_tlv *tlv; 216462306a36Sopenharmony_ci struct sk_buff *skb; 216562306a36Sopenharmony_ci 216662306a36Sopenharmony_ci skb = ath10k_wmi_alloc_skb(ar, sizeof(*tlv) + sizeof(*cmd)); 216762306a36Sopenharmony_ci if (!skb) 216862306a36Sopenharmony_ci return ERR_PTR(-ENOMEM); 216962306a36Sopenharmony_ci 217062306a36Sopenharmony_ci tlv = (void *)skb->data; 217162306a36Sopenharmony_ci tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_VDEV_DELETE_CMD); 217262306a36Sopenharmony_ci tlv->len = __cpu_to_le16(sizeof(*cmd)); 217362306a36Sopenharmony_ci cmd = (void *)tlv->value; 217462306a36Sopenharmony_ci cmd->vdev_id = __cpu_to_le32(vdev_id); 217562306a36Sopenharmony_ci 217662306a36Sopenharmony_ci ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv vdev delete\n"); 217762306a36Sopenharmony_ci return skb; 217862306a36Sopenharmony_ci} 217962306a36Sopenharmony_ci 218062306a36Sopenharmony_cistatic struct sk_buff * 218162306a36Sopenharmony_ciath10k_wmi_tlv_op_gen_vdev_start(struct ath10k *ar, 218262306a36Sopenharmony_ci const struct wmi_vdev_start_request_arg *arg, 218362306a36Sopenharmony_ci bool restart) 218462306a36Sopenharmony_ci{ 218562306a36Sopenharmony_ci struct wmi_tlv_vdev_start_cmd *cmd; 218662306a36Sopenharmony_ci struct wmi_channel *ch; 218762306a36Sopenharmony_ci struct wmi_tlv *tlv; 218862306a36Sopenharmony_ci struct sk_buff *skb; 218962306a36Sopenharmony_ci size_t len; 219062306a36Sopenharmony_ci void *ptr; 219162306a36Sopenharmony_ci u32 flags = 0; 219262306a36Sopenharmony_ci 219362306a36Sopenharmony_ci if (WARN_ON(arg->hidden_ssid && !arg->ssid)) 219462306a36Sopenharmony_ci return ERR_PTR(-EINVAL); 219562306a36Sopenharmony_ci if (WARN_ON(arg->ssid_len > sizeof(cmd->ssid.ssid))) 219662306a36Sopenharmony_ci return ERR_PTR(-EINVAL); 219762306a36Sopenharmony_ci 219862306a36Sopenharmony_ci len = (sizeof(*tlv) + sizeof(*cmd)) + 219962306a36Sopenharmony_ci (sizeof(*tlv) + sizeof(*ch)) + 220062306a36Sopenharmony_ci (sizeof(*tlv) + 0); 220162306a36Sopenharmony_ci skb = ath10k_wmi_alloc_skb(ar, len); 220262306a36Sopenharmony_ci if (!skb) 220362306a36Sopenharmony_ci return ERR_PTR(-ENOMEM); 220462306a36Sopenharmony_ci 220562306a36Sopenharmony_ci if (arg->hidden_ssid) 220662306a36Sopenharmony_ci flags |= WMI_VDEV_START_HIDDEN_SSID; 220762306a36Sopenharmony_ci if (arg->pmf_enabled) 220862306a36Sopenharmony_ci flags |= WMI_VDEV_START_PMF_ENABLED; 220962306a36Sopenharmony_ci 221062306a36Sopenharmony_ci ptr = (void *)skb->data; 221162306a36Sopenharmony_ci 221262306a36Sopenharmony_ci tlv = ptr; 221362306a36Sopenharmony_ci tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_VDEV_START_REQUEST_CMD); 221462306a36Sopenharmony_ci tlv->len = __cpu_to_le16(sizeof(*cmd)); 221562306a36Sopenharmony_ci cmd = (void *)tlv->value; 221662306a36Sopenharmony_ci cmd->vdev_id = __cpu_to_le32(arg->vdev_id); 221762306a36Sopenharmony_ci cmd->bcn_intval = __cpu_to_le32(arg->bcn_intval); 221862306a36Sopenharmony_ci cmd->dtim_period = __cpu_to_le32(arg->dtim_period); 221962306a36Sopenharmony_ci cmd->flags = __cpu_to_le32(flags); 222062306a36Sopenharmony_ci cmd->bcn_tx_rate = __cpu_to_le32(arg->bcn_tx_rate); 222162306a36Sopenharmony_ci cmd->bcn_tx_power = __cpu_to_le32(arg->bcn_tx_power); 222262306a36Sopenharmony_ci cmd->disable_hw_ack = __cpu_to_le32(arg->disable_hw_ack); 222362306a36Sopenharmony_ci 222462306a36Sopenharmony_ci if (arg->ssid) { 222562306a36Sopenharmony_ci cmd->ssid.ssid_len = __cpu_to_le32(arg->ssid_len); 222662306a36Sopenharmony_ci memcpy(cmd->ssid.ssid, arg->ssid, arg->ssid_len); 222762306a36Sopenharmony_ci } 222862306a36Sopenharmony_ci 222962306a36Sopenharmony_ci ptr += sizeof(*tlv); 223062306a36Sopenharmony_ci ptr += sizeof(*cmd); 223162306a36Sopenharmony_ci 223262306a36Sopenharmony_ci tlv = ptr; 223362306a36Sopenharmony_ci tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_CHANNEL); 223462306a36Sopenharmony_ci tlv->len = __cpu_to_le16(sizeof(*ch)); 223562306a36Sopenharmony_ci ch = (void *)tlv->value; 223662306a36Sopenharmony_ci ath10k_wmi_put_wmi_channel(ar, ch, &arg->channel); 223762306a36Sopenharmony_ci 223862306a36Sopenharmony_ci ptr += sizeof(*tlv); 223962306a36Sopenharmony_ci ptr += sizeof(*ch); 224062306a36Sopenharmony_ci 224162306a36Sopenharmony_ci tlv = ptr; 224262306a36Sopenharmony_ci tlv->tag = __cpu_to_le16(WMI_TLV_TAG_ARRAY_STRUCT); 224362306a36Sopenharmony_ci tlv->len = 0; 224462306a36Sopenharmony_ci 224562306a36Sopenharmony_ci /* Note: This is a nested TLV containing: 224662306a36Sopenharmony_ci * [wmi_tlv][wmi_p2p_noa_descriptor][wmi_tlv].. 224762306a36Sopenharmony_ci */ 224862306a36Sopenharmony_ci 224962306a36Sopenharmony_ci ptr += sizeof(*tlv); 225062306a36Sopenharmony_ci ptr += 0; 225162306a36Sopenharmony_ci 225262306a36Sopenharmony_ci ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv vdev start\n"); 225362306a36Sopenharmony_ci return skb; 225462306a36Sopenharmony_ci} 225562306a36Sopenharmony_ci 225662306a36Sopenharmony_cistatic struct sk_buff * 225762306a36Sopenharmony_ciath10k_wmi_tlv_op_gen_vdev_stop(struct ath10k *ar, u32 vdev_id) 225862306a36Sopenharmony_ci{ 225962306a36Sopenharmony_ci struct wmi_vdev_stop_cmd *cmd; 226062306a36Sopenharmony_ci struct wmi_tlv *tlv; 226162306a36Sopenharmony_ci struct sk_buff *skb; 226262306a36Sopenharmony_ci 226362306a36Sopenharmony_ci skb = ath10k_wmi_alloc_skb(ar, sizeof(*tlv) + sizeof(*cmd)); 226462306a36Sopenharmony_ci if (!skb) 226562306a36Sopenharmony_ci return ERR_PTR(-ENOMEM); 226662306a36Sopenharmony_ci 226762306a36Sopenharmony_ci tlv = (void *)skb->data; 226862306a36Sopenharmony_ci tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_VDEV_STOP_CMD); 226962306a36Sopenharmony_ci tlv->len = __cpu_to_le16(sizeof(*cmd)); 227062306a36Sopenharmony_ci cmd = (void *)tlv->value; 227162306a36Sopenharmony_ci cmd->vdev_id = __cpu_to_le32(vdev_id); 227262306a36Sopenharmony_ci 227362306a36Sopenharmony_ci ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv vdev stop\n"); 227462306a36Sopenharmony_ci return skb; 227562306a36Sopenharmony_ci} 227662306a36Sopenharmony_ci 227762306a36Sopenharmony_cistatic struct sk_buff * 227862306a36Sopenharmony_ciath10k_wmi_tlv_op_gen_vdev_up(struct ath10k *ar, u32 vdev_id, u32 aid, 227962306a36Sopenharmony_ci const u8 *bssid) 228062306a36Sopenharmony_ci 228162306a36Sopenharmony_ci{ 228262306a36Sopenharmony_ci struct wmi_vdev_up_cmd *cmd; 228362306a36Sopenharmony_ci struct wmi_tlv *tlv; 228462306a36Sopenharmony_ci struct sk_buff *skb; 228562306a36Sopenharmony_ci 228662306a36Sopenharmony_ci skb = ath10k_wmi_alloc_skb(ar, sizeof(*tlv) + sizeof(*cmd)); 228762306a36Sopenharmony_ci if (!skb) 228862306a36Sopenharmony_ci return ERR_PTR(-ENOMEM); 228962306a36Sopenharmony_ci 229062306a36Sopenharmony_ci tlv = (void *)skb->data; 229162306a36Sopenharmony_ci tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_VDEV_UP_CMD); 229262306a36Sopenharmony_ci tlv->len = __cpu_to_le16(sizeof(*cmd)); 229362306a36Sopenharmony_ci cmd = (void *)tlv->value; 229462306a36Sopenharmony_ci cmd->vdev_id = __cpu_to_le32(vdev_id); 229562306a36Sopenharmony_ci cmd->vdev_assoc_id = __cpu_to_le32(aid); 229662306a36Sopenharmony_ci ether_addr_copy(cmd->vdev_bssid.addr, bssid); 229762306a36Sopenharmony_ci 229862306a36Sopenharmony_ci ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv vdev up\n"); 229962306a36Sopenharmony_ci return skb; 230062306a36Sopenharmony_ci} 230162306a36Sopenharmony_ci 230262306a36Sopenharmony_cistatic struct sk_buff * 230362306a36Sopenharmony_ciath10k_wmi_tlv_op_gen_vdev_down(struct ath10k *ar, u32 vdev_id) 230462306a36Sopenharmony_ci{ 230562306a36Sopenharmony_ci struct wmi_vdev_down_cmd *cmd; 230662306a36Sopenharmony_ci struct wmi_tlv *tlv; 230762306a36Sopenharmony_ci struct sk_buff *skb; 230862306a36Sopenharmony_ci 230962306a36Sopenharmony_ci skb = ath10k_wmi_alloc_skb(ar, sizeof(*tlv) + sizeof(*cmd)); 231062306a36Sopenharmony_ci if (!skb) 231162306a36Sopenharmony_ci return ERR_PTR(-ENOMEM); 231262306a36Sopenharmony_ci 231362306a36Sopenharmony_ci tlv = (void *)skb->data; 231462306a36Sopenharmony_ci tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_VDEV_DOWN_CMD); 231562306a36Sopenharmony_ci tlv->len = __cpu_to_le16(sizeof(*cmd)); 231662306a36Sopenharmony_ci cmd = (void *)tlv->value; 231762306a36Sopenharmony_ci cmd->vdev_id = __cpu_to_le32(vdev_id); 231862306a36Sopenharmony_ci 231962306a36Sopenharmony_ci ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv vdev down\n"); 232062306a36Sopenharmony_ci return skb; 232162306a36Sopenharmony_ci} 232262306a36Sopenharmony_ci 232362306a36Sopenharmony_cistatic struct sk_buff * 232462306a36Sopenharmony_ciath10k_wmi_tlv_op_gen_vdev_set_param(struct ath10k *ar, u32 vdev_id, 232562306a36Sopenharmony_ci u32 param_id, u32 param_value) 232662306a36Sopenharmony_ci{ 232762306a36Sopenharmony_ci struct wmi_vdev_set_param_cmd *cmd; 232862306a36Sopenharmony_ci struct wmi_tlv *tlv; 232962306a36Sopenharmony_ci struct sk_buff *skb; 233062306a36Sopenharmony_ci 233162306a36Sopenharmony_ci skb = ath10k_wmi_alloc_skb(ar, sizeof(*tlv) + sizeof(*cmd)); 233262306a36Sopenharmony_ci if (!skb) 233362306a36Sopenharmony_ci return ERR_PTR(-ENOMEM); 233462306a36Sopenharmony_ci 233562306a36Sopenharmony_ci tlv = (void *)skb->data; 233662306a36Sopenharmony_ci tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_VDEV_SET_PARAM_CMD); 233762306a36Sopenharmony_ci tlv->len = __cpu_to_le16(sizeof(*cmd)); 233862306a36Sopenharmony_ci cmd = (void *)tlv->value; 233962306a36Sopenharmony_ci cmd->vdev_id = __cpu_to_le32(vdev_id); 234062306a36Sopenharmony_ci cmd->param_id = __cpu_to_le32(param_id); 234162306a36Sopenharmony_ci cmd->param_value = __cpu_to_le32(param_value); 234262306a36Sopenharmony_ci 234362306a36Sopenharmony_ci ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv vdev %d set param %d value 0x%x\n", 234462306a36Sopenharmony_ci vdev_id, param_id, param_value); 234562306a36Sopenharmony_ci return skb; 234662306a36Sopenharmony_ci} 234762306a36Sopenharmony_ci 234862306a36Sopenharmony_cistatic struct sk_buff * 234962306a36Sopenharmony_ciath10k_wmi_tlv_op_gen_vdev_install_key(struct ath10k *ar, 235062306a36Sopenharmony_ci const struct wmi_vdev_install_key_arg *arg) 235162306a36Sopenharmony_ci{ 235262306a36Sopenharmony_ci struct wmi_vdev_install_key_cmd *cmd; 235362306a36Sopenharmony_ci struct wmi_tlv *tlv; 235462306a36Sopenharmony_ci struct sk_buff *skb; 235562306a36Sopenharmony_ci size_t len; 235662306a36Sopenharmony_ci void *ptr; 235762306a36Sopenharmony_ci 235862306a36Sopenharmony_ci if (arg->key_cipher == ar->wmi_key_cipher[WMI_CIPHER_NONE] && 235962306a36Sopenharmony_ci arg->key_data) 236062306a36Sopenharmony_ci return ERR_PTR(-EINVAL); 236162306a36Sopenharmony_ci if (arg->key_cipher != ar->wmi_key_cipher[WMI_CIPHER_NONE] && 236262306a36Sopenharmony_ci !arg->key_data) 236362306a36Sopenharmony_ci return ERR_PTR(-EINVAL); 236462306a36Sopenharmony_ci 236562306a36Sopenharmony_ci len = sizeof(*tlv) + sizeof(*cmd) + 236662306a36Sopenharmony_ci sizeof(*tlv) + roundup(arg->key_len, sizeof(__le32)); 236762306a36Sopenharmony_ci skb = ath10k_wmi_alloc_skb(ar, len); 236862306a36Sopenharmony_ci if (!skb) 236962306a36Sopenharmony_ci return ERR_PTR(-ENOMEM); 237062306a36Sopenharmony_ci 237162306a36Sopenharmony_ci ptr = (void *)skb->data; 237262306a36Sopenharmony_ci tlv = ptr; 237362306a36Sopenharmony_ci tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_VDEV_INSTALL_KEY_CMD); 237462306a36Sopenharmony_ci tlv->len = __cpu_to_le16(sizeof(*cmd)); 237562306a36Sopenharmony_ci cmd = (void *)tlv->value; 237662306a36Sopenharmony_ci cmd->vdev_id = __cpu_to_le32(arg->vdev_id); 237762306a36Sopenharmony_ci cmd->key_idx = __cpu_to_le32(arg->key_idx); 237862306a36Sopenharmony_ci cmd->key_flags = __cpu_to_le32(arg->key_flags); 237962306a36Sopenharmony_ci cmd->key_cipher = __cpu_to_le32(arg->key_cipher); 238062306a36Sopenharmony_ci cmd->key_len = __cpu_to_le32(arg->key_len); 238162306a36Sopenharmony_ci cmd->key_txmic_len = __cpu_to_le32(arg->key_txmic_len); 238262306a36Sopenharmony_ci cmd->key_rxmic_len = __cpu_to_le32(arg->key_rxmic_len); 238362306a36Sopenharmony_ci 238462306a36Sopenharmony_ci if (arg->macaddr) 238562306a36Sopenharmony_ci ether_addr_copy(cmd->peer_macaddr.addr, arg->macaddr); 238662306a36Sopenharmony_ci 238762306a36Sopenharmony_ci ptr += sizeof(*tlv); 238862306a36Sopenharmony_ci ptr += sizeof(*cmd); 238962306a36Sopenharmony_ci 239062306a36Sopenharmony_ci tlv = ptr; 239162306a36Sopenharmony_ci tlv->tag = __cpu_to_le16(WMI_TLV_TAG_ARRAY_BYTE); 239262306a36Sopenharmony_ci tlv->len = __cpu_to_le16(roundup(arg->key_len, sizeof(__le32))); 239362306a36Sopenharmony_ci if (arg->key_data) 239462306a36Sopenharmony_ci memcpy(tlv->value, arg->key_data, arg->key_len); 239562306a36Sopenharmony_ci 239662306a36Sopenharmony_ci ptr += sizeof(*tlv); 239762306a36Sopenharmony_ci ptr += roundup(arg->key_len, sizeof(__le32)); 239862306a36Sopenharmony_ci 239962306a36Sopenharmony_ci ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv vdev install key\n"); 240062306a36Sopenharmony_ci return skb; 240162306a36Sopenharmony_ci} 240262306a36Sopenharmony_ci 240362306a36Sopenharmony_cistatic void *ath10k_wmi_tlv_put_uapsd_ac(struct ath10k *ar, void *ptr, 240462306a36Sopenharmony_ci const struct wmi_sta_uapsd_auto_trig_arg *arg) 240562306a36Sopenharmony_ci{ 240662306a36Sopenharmony_ci struct wmi_sta_uapsd_auto_trig_param *ac; 240762306a36Sopenharmony_ci struct wmi_tlv *tlv; 240862306a36Sopenharmony_ci 240962306a36Sopenharmony_ci tlv = ptr; 241062306a36Sopenharmony_ci tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_STA_UAPSD_AUTO_TRIG_PARAM); 241162306a36Sopenharmony_ci tlv->len = __cpu_to_le16(sizeof(*ac)); 241262306a36Sopenharmony_ci ac = (void *)tlv->value; 241362306a36Sopenharmony_ci 241462306a36Sopenharmony_ci ac->wmm_ac = __cpu_to_le32(arg->wmm_ac); 241562306a36Sopenharmony_ci ac->user_priority = __cpu_to_le32(arg->user_priority); 241662306a36Sopenharmony_ci ac->service_interval = __cpu_to_le32(arg->service_interval); 241762306a36Sopenharmony_ci ac->suspend_interval = __cpu_to_le32(arg->suspend_interval); 241862306a36Sopenharmony_ci ac->delay_interval = __cpu_to_le32(arg->delay_interval); 241962306a36Sopenharmony_ci 242062306a36Sopenharmony_ci ath10k_dbg(ar, ATH10K_DBG_WMI, 242162306a36Sopenharmony_ci "wmi tlv vdev sta uapsd auto trigger ac %d prio %d svc int %d susp int %d delay int %d\n", 242262306a36Sopenharmony_ci ac->wmm_ac, ac->user_priority, ac->service_interval, 242362306a36Sopenharmony_ci ac->suspend_interval, ac->delay_interval); 242462306a36Sopenharmony_ci 242562306a36Sopenharmony_ci return ptr + sizeof(*tlv) + sizeof(*ac); 242662306a36Sopenharmony_ci} 242762306a36Sopenharmony_ci 242862306a36Sopenharmony_cistatic struct sk_buff * 242962306a36Sopenharmony_ciath10k_wmi_tlv_op_gen_vdev_sta_uapsd(struct ath10k *ar, u32 vdev_id, 243062306a36Sopenharmony_ci const u8 peer_addr[ETH_ALEN], 243162306a36Sopenharmony_ci const struct wmi_sta_uapsd_auto_trig_arg *args, 243262306a36Sopenharmony_ci u32 num_ac) 243362306a36Sopenharmony_ci{ 243462306a36Sopenharmony_ci struct wmi_sta_uapsd_auto_trig_cmd_fixed_param *cmd; 243562306a36Sopenharmony_ci struct wmi_sta_uapsd_auto_trig_param *ac; 243662306a36Sopenharmony_ci struct wmi_tlv *tlv; 243762306a36Sopenharmony_ci struct sk_buff *skb; 243862306a36Sopenharmony_ci size_t len; 243962306a36Sopenharmony_ci size_t ac_tlv_len; 244062306a36Sopenharmony_ci void *ptr; 244162306a36Sopenharmony_ci int i; 244262306a36Sopenharmony_ci 244362306a36Sopenharmony_ci ac_tlv_len = num_ac * (sizeof(*tlv) + sizeof(*ac)); 244462306a36Sopenharmony_ci len = sizeof(*tlv) + sizeof(*cmd) + 244562306a36Sopenharmony_ci sizeof(*tlv) + ac_tlv_len; 244662306a36Sopenharmony_ci skb = ath10k_wmi_alloc_skb(ar, len); 244762306a36Sopenharmony_ci if (!skb) 244862306a36Sopenharmony_ci return ERR_PTR(-ENOMEM); 244962306a36Sopenharmony_ci 245062306a36Sopenharmony_ci ptr = (void *)skb->data; 245162306a36Sopenharmony_ci tlv = ptr; 245262306a36Sopenharmony_ci tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_STA_UAPSD_AUTO_TRIG_CMD); 245362306a36Sopenharmony_ci tlv->len = __cpu_to_le16(sizeof(*cmd)); 245462306a36Sopenharmony_ci cmd = (void *)tlv->value; 245562306a36Sopenharmony_ci cmd->vdev_id = __cpu_to_le32(vdev_id); 245662306a36Sopenharmony_ci cmd->num_ac = __cpu_to_le32(num_ac); 245762306a36Sopenharmony_ci ether_addr_copy(cmd->peer_macaddr.addr, peer_addr); 245862306a36Sopenharmony_ci 245962306a36Sopenharmony_ci ptr += sizeof(*tlv); 246062306a36Sopenharmony_ci ptr += sizeof(*cmd); 246162306a36Sopenharmony_ci 246262306a36Sopenharmony_ci tlv = ptr; 246362306a36Sopenharmony_ci tlv->tag = __cpu_to_le16(WMI_TLV_TAG_ARRAY_STRUCT); 246462306a36Sopenharmony_ci tlv->len = __cpu_to_le16(ac_tlv_len); 246562306a36Sopenharmony_ci ac = (void *)tlv->value; 246662306a36Sopenharmony_ci 246762306a36Sopenharmony_ci ptr += sizeof(*tlv); 246862306a36Sopenharmony_ci for (i = 0; i < num_ac; i++) 246962306a36Sopenharmony_ci ptr = ath10k_wmi_tlv_put_uapsd_ac(ar, ptr, &args[i]); 247062306a36Sopenharmony_ci 247162306a36Sopenharmony_ci ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv vdev sta uapsd auto trigger\n"); 247262306a36Sopenharmony_ci return skb; 247362306a36Sopenharmony_ci} 247462306a36Sopenharmony_ci 247562306a36Sopenharmony_cistatic void *ath10k_wmi_tlv_put_wmm(void *ptr, 247662306a36Sopenharmony_ci const struct wmi_wmm_params_arg *arg) 247762306a36Sopenharmony_ci{ 247862306a36Sopenharmony_ci struct wmi_wmm_params *wmm; 247962306a36Sopenharmony_ci struct wmi_tlv *tlv; 248062306a36Sopenharmony_ci 248162306a36Sopenharmony_ci tlv = ptr; 248262306a36Sopenharmony_ci tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_WMM_PARAMS); 248362306a36Sopenharmony_ci tlv->len = __cpu_to_le16(sizeof(*wmm)); 248462306a36Sopenharmony_ci wmm = (void *)tlv->value; 248562306a36Sopenharmony_ci ath10k_wmi_set_wmm_param(wmm, arg); 248662306a36Sopenharmony_ci 248762306a36Sopenharmony_ci return ptr + sizeof(*tlv) + sizeof(*wmm); 248862306a36Sopenharmony_ci} 248962306a36Sopenharmony_ci 249062306a36Sopenharmony_cistatic struct sk_buff * 249162306a36Sopenharmony_ciath10k_wmi_tlv_op_gen_vdev_wmm_conf(struct ath10k *ar, u32 vdev_id, 249262306a36Sopenharmony_ci const struct wmi_wmm_params_all_arg *arg) 249362306a36Sopenharmony_ci{ 249462306a36Sopenharmony_ci struct wmi_tlv_vdev_set_wmm_cmd *cmd; 249562306a36Sopenharmony_ci struct wmi_tlv *tlv; 249662306a36Sopenharmony_ci struct sk_buff *skb; 249762306a36Sopenharmony_ci size_t len; 249862306a36Sopenharmony_ci void *ptr; 249962306a36Sopenharmony_ci 250062306a36Sopenharmony_ci len = sizeof(*tlv) + sizeof(*cmd); 250162306a36Sopenharmony_ci skb = ath10k_wmi_alloc_skb(ar, len); 250262306a36Sopenharmony_ci if (!skb) 250362306a36Sopenharmony_ci return ERR_PTR(-ENOMEM); 250462306a36Sopenharmony_ci 250562306a36Sopenharmony_ci ptr = (void *)skb->data; 250662306a36Sopenharmony_ci tlv = ptr; 250762306a36Sopenharmony_ci tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_VDEV_SET_WMM_PARAMS_CMD); 250862306a36Sopenharmony_ci tlv->len = __cpu_to_le16(sizeof(*cmd)); 250962306a36Sopenharmony_ci cmd = (void *)tlv->value; 251062306a36Sopenharmony_ci cmd->vdev_id = __cpu_to_le32(vdev_id); 251162306a36Sopenharmony_ci 251262306a36Sopenharmony_ci ath10k_wmi_set_wmm_param(&cmd->vdev_wmm_params[0].params, &arg->ac_be); 251362306a36Sopenharmony_ci ath10k_wmi_set_wmm_param(&cmd->vdev_wmm_params[1].params, &arg->ac_bk); 251462306a36Sopenharmony_ci ath10k_wmi_set_wmm_param(&cmd->vdev_wmm_params[2].params, &arg->ac_vi); 251562306a36Sopenharmony_ci ath10k_wmi_set_wmm_param(&cmd->vdev_wmm_params[3].params, &arg->ac_vo); 251662306a36Sopenharmony_ci 251762306a36Sopenharmony_ci ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv vdev wmm conf\n"); 251862306a36Sopenharmony_ci return skb; 251962306a36Sopenharmony_ci} 252062306a36Sopenharmony_ci 252162306a36Sopenharmony_cistatic struct sk_buff * 252262306a36Sopenharmony_ciath10k_wmi_tlv_op_gen_sta_keepalive(struct ath10k *ar, 252362306a36Sopenharmony_ci const struct wmi_sta_keepalive_arg *arg) 252462306a36Sopenharmony_ci{ 252562306a36Sopenharmony_ci struct wmi_tlv_sta_keepalive_cmd *cmd; 252662306a36Sopenharmony_ci struct wmi_sta_keepalive_arp_resp *arp; 252762306a36Sopenharmony_ci struct sk_buff *skb; 252862306a36Sopenharmony_ci struct wmi_tlv *tlv; 252962306a36Sopenharmony_ci void *ptr; 253062306a36Sopenharmony_ci size_t len; 253162306a36Sopenharmony_ci 253262306a36Sopenharmony_ci len = sizeof(*tlv) + sizeof(*cmd) + 253362306a36Sopenharmony_ci sizeof(*tlv) + sizeof(*arp); 253462306a36Sopenharmony_ci skb = ath10k_wmi_alloc_skb(ar, len); 253562306a36Sopenharmony_ci if (!skb) 253662306a36Sopenharmony_ci return ERR_PTR(-ENOMEM); 253762306a36Sopenharmony_ci 253862306a36Sopenharmony_ci ptr = (void *)skb->data; 253962306a36Sopenharmony_ci tlv = ptr; 254062306a36Sopenharmony_ci tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_STA_KEEPALIVE_CMD); 254162306a36Sopenharmony_ci tlv->len = __cpu_to_le16(sizeof(*cmd)); 254262306a36Sopenharmony_ci cmd = (void *)tlv->value; 254362306a36Sopenharmony_ci cmd->vdev_id = __cpu_to_le32(arg->vdev_id); 254462306a36Sopenharmony_ci cmd->enabled = __cpu_to_le32(arg->enabled); 254562306a36Sopenharmony_ci cmd->method = __cpu_to_le32(arg->method); 254662306a36Sopenharmony_ci cmd->interval = __cpu_to_le32(arg->interval); 254762306a36Sopenharmony_ci 254862306a36Sopenharmony_ci ptr += sizeof(*tlv); 254962306a36Sopenharmony_ci ptr += sizeof(*cmd); 255062306a36Sopenharmony_ci 255162306a36Sopenharmony_ci tlv = ptr; 255262306a36Sopenharmony_ci tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_STA_KEEPALVE_ARP_RESPONSE); 255362306a36Sopenharmony_ci tlv->len = __cpu_to_le16(sizeof(*arp)); 255462306a36Sopenharmony_ci arp = (void *)tlv->value; 255562306a36Sopenharmony_ci 255662306a36Sopenharmony_ci arp->src_ip4_addr = arg->src_ip4_addr; 255762306a36Sopenharmony_ci arp->dest_ip4_addr = arg->dest_ip4_addr; 255862306a36Sopenharmony_ci ether_addr_copy(arp->dest_mac_addr.addr, arg->dest_mac_addr); 255962306a36Sopenharmony_ci 256062306a36Sopenharmony_ci ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv sta keepalive vdev %d enabled %d method %d interval %d\n", 256162306a36Sopenharmony_ci arg->vdev_id, arg->enabled, arg->method, arg->interval); 256262306a36Sopenharmony_ci return skb; 256362306a36Sopenharmony_ci} 256462306a36Sopenharmony_ci 256562306a36Sopenharmony_cistatic struct sk_buff * 256662306a36Sopenharmony_ciath10k_wmi_tlv_op_gen_peer_create(struct ath10k *ar, u32 vdev_id, 256762306a36Sopenharmony_ci const u8 peer_addr[ETH_ALEN], 256862306a36Sopenharmony_ci enum wmi_peer_type peer_type) 256962306a36Sopenharmony_ci{ 257062306a36Sopenharmony_ci struct wmi_tlv_peer_create_cmd *cmd; 257162306a36Sopenharmony_ci struct wmi_tlv *tlv; 257262306a36Sopenharmony_ci struct sk_buff *skb; 257362306a36Sopenharmony_ci 257462306a36Sopenharmony_ci skb = ath10k_wmi_alloc_skb(ar, sizeof(*tlv) + sizeof(*cmd)); 257562306a36Sopenharmony_ci if (!skb) 257662306a36Sopenharmony_ci return ERR_PTR(-ENOMEM); 257762306a36Sopenharmony_ci 257862306a36Sopenharmony_ci tlv = (void *)skb->data; 257962306a36Sopenharmony_ci tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_PEER_CREATE_CMD); 258062306a36Sopenharmony_ci tlv->len = __cpu_to_le16(sizeof(*cmd)); 258162306a36Sopenharmony_ci cmd = (void *)tlv->value; 258262306a36Sopenharmony_ci cmd->vdev_id = __cpu_to_le32(vdev_id); 258362306a36Sopenharmony_ci cmd->peer_type = __cpu_to_le32(peer_type); 258462306a36Sopenharmony_ci ether_addr_copy(cmd->peer_addr.addr, peer_addr); 258562306a36Sopenharmony_ci 258662306a36Sopenharmony_ci ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv peer create\n"); 258762306a36Sopenharmony_ci return skb; 258862306a36Sopenharmony_ci} 258962306a36Sopenharmony_ci 259062306a36Sopenharmony_cistatic struct sk_buff * 259162306a36Sopenharmony_ciath10k_wmi_tlv_op_gen_peer_delete(struct ath10k *ar, u32 vdev_id, 259262306a36Sopenharmony_ci const u8 peer_addr[ETH_ALEN]) 259362306a36Sopenharmony_ci{ 259462306a36Sopenharmony_ci struct wmi_peer_delete_cmd *cmd; 259562306a36Sopenharmony_ci struct wmi_tlv *tlv; 259662306a36Sopenharmony_ci struct sk_buff *skb; 259762306a36Sopenharmony_ci 259862306a36Sopenharmony_ci skb = ath10k_wmi_alloc_skb(ar, sizeof(*tlv) + sizeof(*cmd)); 259962306a36Sopenharmony_ci if (!skb) 260062306a36Sopenharmony_ci return ERR_PTR(-ENOMEM); 260162306a36Sopenharmony_ci 260262306a36Sopenharmony_ci tlv = (void *)skb->data; 260362306a36Sopenharmony_ci tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_PEER_DELETE_CMD); 260462306a36Sopenharmony_ci tlv->len = __cpu_to_le16(sizeof(*cmd)); 260562306a36Sopenharmony_ci cmd = (void *)tlv->value; 260662306a36Sopenharmony_ci cmd->vdev_id = __cpu_to_le32(vdev_id); 260762306a36Sopenharmony_ci ether_addr_copy(cmd->peer_macaddr.addr, peer_addr); 260862306a36Sopenharmony_ci 260962306a36Sopenharmony_ci ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv peer delete\n"); 261062306a36Sopenharmony_ci return skb; 261162306a36Sopenharmony_ci} 261262306a36Sopenharmony_ci 261362306a36Sopenharmony_cistatic struct sk_buff * 261462306a36Sopenharmony_ciath10k_wmi_tlv_op_gen_peer_flush(struct ath10k *ar, u32 vdev_id, 261562306a36Sopenharmony_ci const u8 peer_addr[ETH_ALEN], u32 tid_bitmap) 261662306a36Sopenharmony_ci{ 261762306a36Sopenharmony_ci struct wmi_peer_flush_tids_cmd *cmd; 261862306a36Sopenharmony_ci struct wmi_tlv *tlv; 261962306a36Sopenharmony_ci struct sk_buff *skb; 262062306a36Sopenharmony_ci 262162306a36Sopenharmony_ci skb = ath10k_wmi_alloc_skb(ar, sizeof(*tlv) + sizeof(*cmd)); 262262306a36Sopenharmony_ci if (!skb) 262362306a36Sopenharmony_ci return ERR_PTR(-ENOMEM); 262462306a36Sopenharmony_ci 262562306a36Sopenharmony_ci tlv = (void *)skb->data; 262662306a36Sopenharmony_ci tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_PEER_FLUSH_TIDS_CMD); 262762306a36Sopenharmony_ci tlv->len = __cpu_to_le16(sizeof(*cmd)); 262862306a36Sopenharmony_ci cmd = (void *)tlv->value; 262962306a36Sopenharmony_ci cmd->vdev_id = __cpu_to_le32(vdev_id); 263062306a36Sopenharmony_ci cmd->peer_tid_bitmap = __cpu_to_le32(tid_bitmap); 263162306a36Sopenharmony_ci ether_addr_copy(cmd->peer_macaddr.addr, peer_addr); 263262306a36Sopenharmony_ci 263362306a36Sopenharmony_ci ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv peer flush\n"); 263462306a36Sopenharmony_ci return skb; 263562306a36Sopenharmony_ci} 263662306a36Sopenharmony_ci 263762306a36Sopenharmony_cistatic struct sk_buff * 263862306a36Sopenharmony_ciath10k_wmi_tlv_op_gen_peer_set_param(struct ath10k *ar, u32 vdev_id, 263962306a36Sopenharmony_ci const u8 *peer_addr, 264062306a36Sopenharmony_ci enum wmi_peer_param param_id, 264162306a36Sopenharmony_ci u32 param_value) 264262306a36Sopenharmony_ci{ 264362306a36Sopenharmony_ci struct wmi_peer_set_param_cmd *cmd; 264462306a36Sopenharmony_ci struct wmi_tlv *tlv; 264562306a36Sopenharmony_ci struct sk_buff *skb; 264662306a36Sopenharmony_ci 264762306a36Sopenharmony_ci skb = ath10k_wmi_alloc_skb(ar, sizeof(*tlv) + sizeof(*cmd)); 264862306a36Sopenharmony_ci if (!skb) 264962306a36Sopenharmony_ci return ERR_PTR(-ENOMEM); 265062306a36Sopenharmony_ci 265162306a36Sopenharmony_ci tlv = (void *)skb->data; 265262306a36Sopenharmony_ci tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_PEER_SET_PARAM_CMD); 265362306a36Sopenharmony_ci tlv->len = __cpu_to_le16(sizeof(*cmd)); 265462306a36Sopenharmony_ci cmd = (void *)tlv->value; 265562306a36Sopenharmony_ci cmd->vdev_id = __cpu_to_le32(vdev_id); 265662306a36Sopenharmony_ci cmd->param_id = __cpu_to_le32(param_id); 265762306a36Sopenharmony_ci cmd->param_value = __cpu_to_le32(param_value); 265862306a36Sopenharmony_ci ether_addr_copy(cmd->peer_macaddr.addr, peer_addr); 265962306a36Sopenharmony_ci 266062306a36Sopenharmony_ci ath10k_dbg(ar, ATH10K_DBG_WMI, 266162306a36Sopenharmony_ci "wmi tlv vdev %d peer %pM set param %d value 0x%x\n", 266262306a36Sopenharmony_ci vdev_id, peer_addr, param_id, param_value); 266362306a36Sopenharmony_ci return skb; 266462306a36Sopenharmony_ci} 266562306a36Sopenharmony_ci 266662306a36Sopenharmony_cistatic struct sk_buff * 266762306a36Sopenharmony_ciath10k_wmi_tlv_op_gen_peer_assoc(struct ath10k *ar, 266862306a36Sopenharmony_ci const struct wmi_peer_assoc_complete_arg *arg) 266962306a36Sopenharmony_ci{ 267062306a36Sopenharmony_ci struct wmi_tlv_peer_assoc_cmd *cmd; 267162306a36Sopenharmony_ci struct wmi_vht_rate_set *vht_rate; 267262306a36Sopenharmony_ci struct wmi_tlv *tlv; 267362306a36Sopenharmony_ci struct sk_buff *skb; 267462306a36Sopenharmony_ci size_t len, legacy_rate_len, ht_rate_len; 267562306a36Sopenharmony_ci void *ptr; 267662306a36Sopenharmony_ci 267762306a36Sopenharmony_ci if (arg->peer_mpdu_density > 16) 267862306a36Sopenharmony_ci return ERR_PTR(-EINVAL); 267962306a36Sopenharmony_ci if (arg->peer_legacy_rates.num_rates > MAX_SUPPORTED_RATES) 268062306a36Sopenharmony_ci return ERR_PTR(-EINVAL); 268162306a36Sopenharmony_ci if (arg->peer_ht_rates.num_rates > MAX_SUPPORTED_RATES) 268262306a36Sopenharmony_ci return ERR_PTR(-EINVAL); 268362306a36Sopenharmony_ci 268462306a36Sopenharmony_ci legacy_rate_len = roundup(arg->peer_legacy_rates.num_rates, 268562306a36Sopenharmony_ci sizeof(__le32)); 268662306a36Sopenharmony_ci ht_rate_len = roundup(arg->peer_ht_rates.num_rates, sizeof(__le32)); 268762306a36Sopenharmony_ci len = (sizeof(*tlv) + sizeof(*cmd)) + 268862306a36Sopenharmony_ci (sizeof(*tlv) + legacy_rate_len) + 268962306a36Sopenharmony_ci (sizeof(*tlv) + ht_rate_len) + 269062306a36Sopenharmony_ci (sizeof(*tlv) + sizeof(*vht_rate)); 269162306a36Sopenharmony_ci skb = ath10k_wmi_alloc_skb(ar, len); 269262306a36Sopenharmony_ci if (!skb) 269362306a36Sopenharmony_ci return ERR_PTR(-ENOMEM); 269462306a36Sopenharmony_ci 269562306a36Sopenharmony_ci ptr = (void *)skb->data; 269662306a36Sopenharmony_ci tlv = ptr; 269762306a36Sopenharmony_ci tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_PEER_ASSOC_COMPLETE_CMD); 269862306a36Sopenharmony_ci tlv->len = __cpu_to_le16(sizeof(*cmd)); 269962306a36Sopenharmony_ci cmd = (void *)tlv->value; 270062306a36Sopenharmony_ci 270162306a36Sopenharmony_ci cmd->vdev_id = __cpu_to_le32(arg->vdev_id); 270262306a36Sopenharmony_ci cmd->new_assoc = __cpu_to_le32(arg->peer_reassoc ? 0 : 1); 270362306a36Sopenharmony_ci cmd->assoc_id = __cpu_to_le32(arg->peer_aid); 270462306a36Sopenharmony_ci cmd->flags = __cpu_to_le32(arg->peer_flags); 270562306a36Sopenharmony_ci cmd->caps = __cpu_to_le32(arg->peer_caps); 270662306a36Sopenharmony_ci cmd->listen_intval = __cpu_to_le32(arg->peer_listen_intval); 270762306a36Sopenharmony_ci cmd->ht_caps = __cpu_to_le32(arg->peer_ht_caps); 270862306a36Sopenharmony_ci cmd->max_mpdu = __cpu_to_le32(arg->peer_max_mpdu); 270962306a36Sopenharmony_ci cmd->mpdu_density = __cpu_to_le32(arg->peer_mpdu_density); 271062306a36Sopenharmony_ci cmd->rate_caps = __cpu_to_le32(arg->peer_rate_caps); 271162306a36Sopenharmony_ci cmd->nss = __cpu_to_le32(arg->peer_num_spatial_streams); 271262306a36Sopenharmony_ci cmd->vht_caps = __cpu_to_le32(arg->peer_vht_caps); 271362306a36Sopenharmony_ci cmd->phy_mode = __cpu_to_le32(arg->peer_phymode); 271462306a36Sopenharmony_ci cmd->num_legacy_rates = __cpu_to_le32(arg->peer_legacy_rates.num_rates); 271562306a36Sopenharmony_ci cmd->num_ht_rates = __cpu_to_le32(arg->peer_ht_rates.num_rates); 271662306a36Sopenharmony_ci ether_addr_copy(cmd->mac_addr.addr, arg->addr); 271762306a36Sopenharmony_ci 271862306a36Sopenharmony_ci ptr += sizeof(*tlv); 271962306a36Sopenharmony_ci ptr += sizeof(*cmd); 272062306a36Sopenharmony_ci 272162306a36Sopenharmony_ci tlv = ptr; 272262306a36Sopenharmony_ci tlv->tag = __cpu_to_le16(WMI_TLV_TAG_ARRAY_BYTE); 272362306a36Sopenharmony_ci tlv->len = __cpu_to_le16(legacy_rate_len); 272462306a36Sopenharmony_ci memcpy(tlv->value, arg->peer_legacy_rates.rates, 272562306a36Sopenharmony_ci arg->peer_legacy_rates.num_rates); 272662306a36Sopenharmony_ci 272762306a36Sopenharmony_ci ptr += sizeof(*tlv); 272862306a36Sopenharmony_ci ptr += legacy_rate_len; 272962306a36Sopenharmony_ci 273062306a36Sopenharmony_ci tlv = ptr; 273162306a36Sopenharmony_ci tlv->tag = __cpu_to_le16(WMI_TLV_TAG_ARRAY_BYTE); 273262306a36Sopenharmony_ci tlv->len = __cpu_to_le16(ht_rate_len); 273362306a36Sopenharmony_ci memcpy(tlv->value, arg->peer_ht_rates.rates, 273462306a36Sopenharmony_ci arg->peer_ht_rates.num_rates); 273562306a36Sopenharmony_ci 273662306a36Sopenharmony_ci ptr += sizeof(*tlv); 273762306a36Sopenharmony_ci ptr += ht_rate_len; 273862306a36Sopenharmony_ci 273962306a36Sopenharmony_ci tlv = ptr; 274062306a36Sopenharmony_ci tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_VHT_RATE_SET); 274162306a36Sopenharmony_ci tlv->len = __cpu_to_le16(sizeof(*vht_rate)); 274262306a36Sopenharmony_ci vht_rate = (void *)tlv->value; 274362306a36Sopenharmony_ci 274462306a36Sopenharmony_ci vht_rate->rx_max_rate = __cpu_to_le32(arg->peer_vht_rates.rx_max_rate); 274562306a36Sopenharmony_ci vht_rate->rx_mcs_set = __cpu_to_le32(arg->peer_vht_rates.rx_mcs_set); 274662306a36Sopenharmony_ci vht_rate->tx_max_rate = __cpu_to_le32(arg->peer_vht_rates.tx_max_rate); 274762306a36Sopenharmony_ci vht_rate->tx_mcs_set = __cpu_to_le32(arg->peer_vht_rates.tx_mcs_set); 274862306a36Sopenharmony_ci 274962306a36Sopenharmony_ci ptr += sizeof(*tlv); 275062306a36Sopenharmony_ci ptr += sizeof(*vht_rate); 275162306a36Sopenharmony_ci 275262306a36Sopenharmony_ci ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv peer assoc\n"); 275362306a36Sopenharmony_ci return skb; 275462306a36Sopenharmony_ci} 275562306a36Sopenharmony_ci 275662306a36Sopenharmony_cistatic struct sk_buff * 275762306a36Sopenharmony_ciath10k_wmi_tlv_op_gen_set_psmode(struct ath10k *ar, u32 vdev_id, 275862306a36Sopenharmony_ci enum wmi_sta_ps_mode psmode) 275962306a36Sopenharmony_ci{ 276062306a36Sopenharmony_ci struct wmi_sta_powersave_mode_cmd *cmd; 276162306a36Sopenharmony_ci struct wmi_tlv *tlv; 276262306a36Sopenharmony_ci struct sk_buff *skb; 276362306a36Sopenharmony_ci 276462306a36Sopenharmony_ci skb = ath10k_wmi_alloc_skb(ar, sizeof(*tlv) + sizeof(*cmd)); 276562306a36Sopenharmony_ci if (!skb) 276662306a36Sopenharmony_ci return ERR_PTR(-ENOMEM); 276762306a36Sopenharmony_ci 276862306a36Sopenharmony_ci tlv = (void *)skb->data; 276962306a36Sopenharmony_ci tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_STA_POWERSAVE_MODE_CMD); 277062306a36Sopenharmony_ci tlv->len = __cpu_to_le16(sizeof(*cmd)); 277162306a36Sopenharmony_ci cmd = (void *)tlv->value; 277262306a36Sopenharmony_ci cmd->vdev_id = __cpu_to_le32(vdev_id); 277362306a36Sopenharmony_ci cmd->sta_ps_mode = __cpu_to_le32(psmode); 277462306a36Sopenharmony_ci 277562306a36Sopenharmony_ci ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv set psmode\n"); 277662306a36Sopenharmony_ci return skb; 277762306a36Sopenharmony_ci} 277862306a36Sopenharmony_ci 277962306a36Sopenharmony_cistatic struct sk_buff * 278062306a36Sopenharmony_ciath10k_wmi_tlv_op_gen_set_sta_ps(struct ath10k *ar, u32 vdev_id, 278162306a36Sopenharmony_ci enum wmi_sta_powersave_param param_id, 278262306a36Sopenharmony_ci u32 param_value) 278362306a36Sopenharmony_ci{ 278462306a36Sopenharmony_ci struct wmi_sta_powersave_param_cmd *cmd; 278562306a36Sopenharmony_ci struct wmi_tlv *tlv; 278662306a36Sopenharmony_ci struct sk_buff *skb; 278762306a36Sopenharmony_ci 278862306a36Sopenharmony_ci skb = ath10k_wmi_alloc_skb(ar, sizeof(*tlv) + sizeof(*cmd)); 278962306a36Sopenharmony_ci if (!skb) 279062306a36Sopenharmony_ci return ERR_PTR(-ENOMEM); 279162306a36Sopenharmony_ci 279262306a36Sopenharmony_ci tlv = (void *)skb->data; 279362306a36Sopenharmony_ci tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_STA_POWERSAVE_PARAM_CMD); 279462306a36Sopenharmony_ci tlv->len = __cpu_to_le16(sizeof(*cmd)); 279562306a36Sopenharmony_ci cmd = (void *)tlv->value; 279662306a36Sopenharmony_ci cmd->vdev_id = __cpu_to_le32(vdev_id); 279762306a36Sopenharmony_ci cmd->param_id = __cpu_to_le32(param_id); 279862306a36Sopenharmony_ci cmd->param_value = __cpu_to_le32(param_value); 279962306a36Sopenharmony_ci 280062306a36Sopenharmony_ci ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv set sta ps\n"); 280162306a36Sopenharmony_ci return skb; 280262306a36Sopenharmony_ci} 280362306a36Sopenharmony_ci 280462306a36Sopenharmony_cistatic struct sk_buff * 280562306a36Sopenharmony_ciath10k_wmi_tlv_op_gen_set_ap_ps(struct ath10k *ar, u32 vdev_id, const u8 *mac, 280662306a36Sopenharmony_ci enum wmi_ap_ps_peer_param param_id, u32 value) 280762306a36Sopenharmony_ci{ 280862306a36Sopenharmony_ci struct wmi_ap_ps_peer_cmd *cmd; 280962306a36Sopenharmony_ci struct wmi_tlv *tlv; 281062306a36Sopenharmony_ci struct sk_buff *skb; 281162306a36Sopenharmony_ci 281262306a36Sopenharmony_ci if (!mac) 281362306a36Sopenharmony_ci return ERR_PTR(-EINVAL); 281462306a36Sopenharmony_ci 281562306a36Sopenharmony_ci skb = ath10k_wmi_alloc_skb(ar, sizeof(*tlv) + sizeof(*cmd)); 281662306a36Sopenharmony_ci if (!skb) 281762306a36Sopenharmony_ci return ERR_PTR(-ENOMEM); 281862306a36Sopenharmony_ci 281962306a36Sopenharmony_ci tlv = (void *)skb->data; 282062306a36Sopenharmony_ci tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_AP_PS_PEER_CMD); 282162306a36Sopenharmony_ci tlv->len = __cpu_to_le16(sizeof(*cmd)); 282262306a36Sopenharmony_ci cmd = (void *)tlv->value; 282362306a36Sopenharmony_ci cmd->vdev_id = __cpu_to_le32(vdev_id); 282462306a36Sopenharmony_ci cmd->param_id = __cpu_to_le32(param_id); 282562306a36Sopenharmony_ci cmd->param_value = __cpu_to_le32(value); 282662306a36Sopenharmony_ci ether_addr_copy(cmd->peer_macaddr.addr, mac); 282762306a36Sopenharmony_ci 282862306a36Sopenharmony_ci ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv ap ps param\n"); 282962306a36Sopenharmony_ci return skb; 283062306a36Sopenharmony_ci} 283162306a36Sopenharmony_ci 283262306a36Sopenharmony_cistatic struct sk_buff * 283362306a36Sopenharmony_ciath10k_wmi_tlv_op_gen_scan_chan_list(struct ath10k *ar, 283462306a36Sopenharmony_ci const struct wmi_scan_chan_list_arg *arg) 283562306a36Sopenharmony_ci{ 283662306a36Sopenharmony_ci struct wmi_tlv_scan_chan_list_cmd *cmd; 283762306a36Sopenharmony_ci struct wmi_channel *ci; 283862306a36Sopenharmony_ci struct wmi_channel_arg *ch; 283962306a36Sopenharmony_ci struct wmi_tlv *tlv; 284062306a36Sopenharmony_ci struct sk_buff *skb; 284162306a36Sopenharmony_ci size_t chans_len, len; 284262306a36Sopenharmony_ci int i; 284362306a36Sopenharmony_ci void *ptr, *chans; 284462306a36Sopenharmony_ci 284562306a36Sopenharmony_ci chans_len = arg->n_channels * (sizeof(*tlv) + sizeof(*ci)); 284662306a36Sopenharmony_ci len = (sizeof(*tlv) + sizeof(*cmd)) + 284762306a36Sopenharmony_ci (sizeof(*tlv) + chans_len); 284862306a36Sopenharmony_ci 284962306a36Sopenharmony_ci skb = ath10k_wmi_alloc_skb(ar, len); 285062306a36Sopenharmony_ci if (!skb) 285162306a36Sopenharmony_ci return ERR_PTR(-ENOMEM); 285262306a36Sopenharmony_ci 285362306a36Sopenharmony_ci ptr = (void *)skb->data; 285462306a36Sopenharmony_ci tlv = ptr; 285562306a36Sopenharmony_ci tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_SCAN_CHAN_LIST_CMD); 285662306a36Sopenharmony_ci tlv->len = __cpu_to_le16(sizeof(*cmd)); 285762306a36Sopenharmony_ci cmd = (void *)tlv->value; 285862306a36Sopenharmony_ci cmd->num_scan_chans = __cpu_to_le32(arg->n_channels); 285962306a36Sopenharmony_ci 286062306a36Sopenharmony_ci ptr += sizeof(*tlv); 286162306a36Sopenharmony_ci ptr += sizeof(*cmd); 286262306a36Sopenharmony_ci 286362306a36Sopenharmony_ci tlv = ptr; 286462306a36Sopenharmony_ci tlv->tag = __cpu_to_le16(WMI_TLV_TAG_ARRAY_STRUCT); 286562306a36Sopenharmony_ci tlv->len = __cpu_to_le16(chans_len); 286662306a36Sopenharmony_ci chans = (void *)tlv->value; 286762306a36Sopenharmony_ci 286862306a36Sopenharmony_ci for (i = 0; i < arg->n_channels; i++) { 286962306a36Sopenharmony_ci ch = &arg->channels[i]; 287062306a36Sopenharmony_ci 287162306a36Sopenharmony_ci tlv = chans; 287262306a36Sopenharmony_ci tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_CHANNEL); 287362306a36Sopenharmony_ci tlv->len = __cpu_to_le16(sizeof(*ci)); 287462306a36Sopenharmony_ci ci = (void *)tlv->value; 287562306a36Sopenharmony_ci 287662306a36Sopenharmony_ci ath10k_wmi_put_wmi_channel(ar, ci, ch); 287762306a36Sopenharmony_ci 287862306a36Sopenharmony_ci chans += sizeof(*tlv); 287962306a36Sopenharmony_ci chans += sizeof(*ci); 288062306a36Sopenharmony_ci } 288162306a36Sopenharmony_ci 288262306a36Sopenharmony_ci ptr += sizeof(*tlv); 288362306a36Sopenharmony_ci ptr += chans_len; 288462306a36Sopenharmony_ci 288562306a36Sopenharmony_ci ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv scan chan list\n"); 288662306a36Sopenharmony_ci return skb; 288762306a36Sopenharmony_ci} 288862306a36Sopenharmony_ci 288962306a36Sopenharmony_cistatic struct sk_buff * 289062306a36Sopenharmony_ciath10k_wmi_tlv_op_gen_scan_prob_req_oui(struct ath10k *ar, u32 prob_req_oui) 289162306a36Sopenharmony_ci{ 289262306a36Sopenharmony_ci struct wmi_scan_prob_req_oui_cmd *cmd; 289362306a36Sopenharmony_ci struct wmi_tlv *tlv; 289462306a36Sopenharmony_ci struct sk_buff *skb; 289562306a36Sopenharmony_ci 289662306a36Sopenharmony_ci skb = ath10k_wmi_alloc_skb(ar, sizeof(*tlv) + sizeof(*cmd)); 289762306a36Sopenharmony_ci if (!skb) 289862306a36Sopenharmony_ci return ERR_PTR(-ENOMEM); 289962306a36Sopenharmony_ci 290062306a36Sopenharmony_ci tlv = (void *)skb->data; 290162306a36Sopenharmony_ci tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_SCAN_PROB_REQ_OUI_CMD); 290262306a36Sopenharmony_ci tlv->len = __cpu_to_le16(sizeof(*cmd)); 290362306a36Sopenharmony_ci cmd = (void *)tlv->value; 290462306a36Sopenharmony_ci cmd->prob_req_oui = __cpu_to_le32(prob_req_oui); 290562306a36Sopenharmony_ci 290662306a36Sopenharmony_ci ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv scan prob req oui\n"); 290762306a36Sopenharmony_ci return skb; 290862306a36Sopenharmony_ci} 290962306a36Sopenharmony_ci 291062306a36Sopenharmony_cistatic struct sk_buff * 291162306a36Sopenharmony_ciath10k_wmi_tlv_op_gen_beacon_dma(struct ath10k *ar, u32 vdev_id, 291262306a36Sopenharmony_ci const void *bcn, size_t bcn_len, 291362306a36Sopenharmony_ci u32 bcn_paddr, bool dtim_zero, 291462306a36Sopenharmony_ci bool deliver_cab) 291562306a36Sopenharmony_ci 291662306a36Sopenharmony_ci{ 291762306a36Sopenharmony_ci struct wmi_bcn_tx_ref_cmd *cmd; 291862306a36Sopenharmony_ci struct wmi_tlv *tlv; 291962306a36Sopenharmony_ci struct sk_buff *skb; 292062306a36Sopenharmony_ci struct ieee80211_hdr *hdr; 292162306a36Sopenharmony_ci u16 fc; 292262306a36Sopenharmony_ci 292362306a36Sopenharmony_ci skb = ath10k_wmi_alloc_skb(ar, sizeof(*tlv) + sizeof(*cmd)); 292462306a36Sopenharmony_ci if (!skb) 292562306a36Sopenharmony_ci return ERR_PTR(-ENOMEM); 292662306a36Sopenharmony_ci 292762306a36Sopenharmony_ci hdr = (struct ieee80211_hdr *)bcn; 292862306a36Sopenharmony_ci fc = le16_to_cpu(hdr->frame_control); 292962306a36Sopenharmony_ci 293062306a36Sopenharmony_ci tlv = (void *)skb->data; 293162306a36Sopenharmony_ci tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_BCN_SEND_FROM_HOST_CMD); 293262306a36Sopenharmony_ci tlv->len = __cpu_to_le16(sizeof(*cmd)); 293362306a36Sopenharmony_ci cmd = (void *)tlv->value; 293462306a36Sopenharmony_ci cmd->vdev_id = __cpu_to_le32(vdev_id); 293562306a36Sopenharmony_ci cmd->data_len = __cpu_to_le32(bcn_len); 293662306a36Sopenharmony_ci cmd->data_ptr = __cpu_to_le32(bcn_paddr); 293762306a36Sopenharmony_ci cmd->msdu_id = 0; 293862306a36Sopenharmony_ci cmd->frame_control = __cpu_to_le32(fc); 293962306a36Sopenharmony_ci cmd->flags = 0; 294062306a36Sopenharmony_ci 294162306a36Sopenharmony_ci if (dtim_zero) 294262306a36Sopenharmony_ci cmd->flags |= __cpu_to_le32(WMI_BCN_TX_REF_FLAG_DTIM_ZERO); 294362306a36Sopenharmony_ci 294462306a36Sopenharmony_ci if (deliver_cab) 294562306a36Sopenharmony_ci cmd->flags |= __cpu_to_le32(WMI_BCN_TX_REF_FLAG_DELIVER_CAB); 294662306a36Sopenharmony_ci 294762306a36Sopenharmony_ci ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv beacon dma\n"); 294862306a36Sopenharmony_ci return skb; 294962306a36Sopenharmony_ci} 295062306a36Sopenharmony_ci 295162306a36Sopenharmony_cistatic struct sk_buff * 295262306a36Sopenharmony_ciath10k_wmi_tlv_op_gen_pdev_set_wmm(struct ath10k *ar, 295362306a36Sopenharmony_ci const struct wmi_wmm_params_all_arg *arg) 295462306a36Sopenharmony_ci{ 295562306a36Sopenharmony_ci struct wmi_tlv_pdev_set_wmm_cmd *cmd; 295662306a36Sopenharmony_ci struct wmi_wmm_params *wmm; 295762306a36Sopenharmony_ci struct wmi_tlv *tlv; 295862306a36Sopenharmony_ci struct sk_buff *skb; 295962306a36Sopenharmony_ci size_t len; 296062306a36Sopenharmony_ci void *ptr; 296162306a36Sopenharmony_ci 296262306a36Sopenharmony_ci len = (sizeof(*tlv) + sizeof(*cmd)) + 296362306a36Sopenharmony_ci (4 * (sizeof(*tlv) + sizeof(*wmm))); 296462306a36Sopenharmony_ci skb = ath10k_wmi_alloc_skb(ar, len); 296562306a36Sopenharmony_ci if (!skb) 296662306a36Sopenharmony_ci return ERR_PTR(-ENOMEM); 296762306a36Sopenharmony_ci 296862306a36Sopenharmony_ci ptr = (void *)skb->data; 296962306a36Sopenharmony_ci 297062306a36Sopenharmony_ci tlv = ptr; 297162306a36Sopenharmony_ci tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_PDEV_SET_WMM_PARAMS_CMD); 297262306a36Sopenharmony_ci tlv->len = __cpu_to_le16(sizeof(*cmd)); 297362306a36Sopenharmony_ci cmd = (void *)tlv->value; 297462306a36Sopenharmony_ci 297562306a36Sopenharmony_ci /* nothing to set here */ 297662306a36Sopenharmony_ci 297762306a36Sopenharmony_ci ptr += sizeof(*tlv); 297862306a36Sopenharmony_ci ptr += sizeof(*cmd); 297962306a36Sopenharmony_ci 298062306a36Sopenharmony_ci ptr = ath10k_wmi_tlv_put_wmm(ptr, &arg->ac_be); 298162306a36Sopenharmony_ci ptr = ath10k_wmi_tlv_put_wmm(ptr, &arg->ac_bk); 298262306a36Sopenharmony_ci ptr = ath10k_wmi_tlv_put_wmm(ptr, &arg->ac_vi); 298362306a36Sopenharmony_ci ptr = ath10k_wmi_tlv_put_wmm(ptr, &arg->ac_vo); 298462306a36Sopenharmony_ci 298562306a36Sopenharmony_ci ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv pdev set wmm\n"); 298662306a36Sopenharmony_ci return skb; 298762306a36Sopenharmony_ci} 298862306a36Sopenharmony_ci 298962306a36Sopenharmony_cistatic struct sk_buff * 299062306a36Sopenharmony_ciath10k_wmi_tlv_op_gen_request_stats(struct ath10k *ar, u32 stats_mask) 299162306a36Sopenharmony_ci{ 299262306a36Sopenharmony_ci struct wmi_request_stats_cmd *cmd; 299362306a36Sopenharmony_ci struct wmi_tlv *tlv; 299462306a36Sopenharmony_ci struct sk_buff *skb; 299562306a36Sopenharmony_ci 299662306a36Sopenharmony_ci skb = ath10k_wmi_alloc_skb(ar, sizeof(*tlv) + sizeof(*cmd)); 299762306a36Sopenharmony_ci if (!skb) 299862306a36Sopenharmony_ci return ERR_PTR(-ENOMEM); 299962306a36Sopenharmony_ci 300062306a36Sopenharmony_ci tlv = (void *)skb->data; 300162306a36Sopenharmony_ci tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_REQUEST_STATS_CMD); 300262306a36Sopenharmony_ci tlv->len = __cpu_to_le16(sizeof(*cmd)); 300362306a36Sopenharmony_ci cmd = (void *)tlv->value; 300462306a36Sopenharmony_ci cmd->stats_id = __cpu_to_le32(stats_mask); 300562306a36Sopenharmony_ci 300662306a36Sopenharmony_ci ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv request stats\n"); 300762306a36Sopenharmony_ci return skb; 300862306a36Sopenharmony_ci} 300962306a36Sopenharmony_ci 301062306a36Sopenharmony_cistatic struct sk_buff * 301162306a36Sopenharmony_ciath10k_wmi_tlv_op_gen_request_peer_stats_info(struct ath10k *ar, 301262306a36Sopenharmony_ci u32 vdev_id, 301362306a36Sopenharmony_ci enum wmi_peer_stats_info_request_type type, 301462306a36Sopenharmony_ci u8 *addr, 301562306a36Sopenharmony_ci u32 reset) 301662306a36Sopenharmony_ci{ 301762306a36Sopenharmony_ci struct wmi_tlv_request_peer_stats_info *cmd; 301862306a36Sopenharmony_ci struct wmi_tlv *tlv; 301962306a36Sopenharmony_ci struct sk_buff *skb; 302062306a36Sopenharmony_ci 302162306a36Sopenharmony_ci skb = ath10k_wmi_alloc_skb(ar, sizeof(*tlv) + sizeof(*cmd)); 302262306a36Sopenharmony_ci if (!skb) 302362306a36Sopenharmony_ci return ERR_PTR(-ENOMEM); 302462306a36Sopenharmony_ci 302562306a36Sopenharmony_ci tlv = (void *)skb->data; 302662306a36Sopenharmony_ci tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_REQUEST_PEER_STATS_INFO_CMD); 302762306a36Sopenharmony_ci tlv->len = __cpu_to_le16(sizeof(*cmd)); 302862306a36Sopenharmony_ci cmd = (void *)tlv->value; 302962306a36Sopenharmony_ci cmd->vdev_id = __cpu_to_le32(vdev_id); 303062306a36Sopenharmony_ci cmd->request_type = __cpu_to_le32(type); 303162306a36Sopenharmony_ci 303262306a36Sopenharmony_ci if (type == WMI_REQUEST_ONE_PEER_STATS_INFO) 303362306a36Sopenharmony_ci ether_addr_copy(cmd->peer_macaddr.addr, addr); 303462306a36Sopenharmony_ci 303562306a36Sopenharmony_ci cmd->reset_after_request = __cpu_to_le32(reset); 303662306a36Sopenharmony_ci ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv request peer stats info\n"); 303762306a36Sopenharmony_ci return skb; 303862306a36Sopenharmony_ci} 303962306a36Sopenharmony_ci 304062306a36Sopenharmony_cistatic int 304162306a36Sopenharmony_ciath10k_wmi_tlv_op_cleanup_mgmt_tx_send(struct ath10k *ar, 304262306a36Sopenharmony_ci struct sk_buff *msdu) 304362306a36Sopenharmony_ci{ 304462306a36Sopenharmony_ci struct ath10k_skb_cb *cb = ATH10K_SKB_CB(msdu); 304562306a36Sopenharmony_ci struct ath10k_wmi *wmi = &ar->wmi; 304662306a36Sopenharmony_ci 304762306a36Sopenharmony_ci idr_remove(&wmi->mgmt_pending_tx, cb->msdu_id); 304862306a36Sopenharmony_ci 304962306a36Sopenharmony_ci return 0; 305062306a36Sopenharmony_ci} 305162306a36Sopenharmony_ci 305262306a36Sopenharmony_cistatic int 305362306a36Sopenharmony_ciath10k_wmi_mgmt_tx_alloc_msdu_id(struct ath10k *ar, struct sk_buff *skb, 305462306a36Sopenharmony_ci dma_addr_t paddr) 305562306a36Sopenharmony_ci{ 305662306a36Sopenharmony_ci struct ath10k_wmi *wmi = &ar->wmi; 305762306a36Sopenharmony_ci struct ath10k_mgmt_tx_pkt_addr *pkt_addr; 305862306a36Sopenharmony_ci int ret; 305962306a36Sopenharmony_ci 306062306a36Sopenharmony_ci pkt_addr = kmalloc(sizeof(*pkt_addr), GFP_ATOMIC); 306162306a36Sopenharmony_ci if (!pkt_addr) 306262306a36Sopenharmony_ci return -ENOMEM; 306362306a36Sopenharmony_ci 306462306a36Sopenharmony_ci pkt_addr->vaddr = skb; 306562306a36Sopenharmony_ci pkt_addr->paddr = paddr; 306662306a36Sopenharmony_ci 306762306a36Sopenharmony_ci spin_lock_bh(&ar->data_lock); 306862306a36Sopenharmony_ci ret = idr_alloc(&wmi->mgmt_pending_tx, pkt_addr, 0, 306962306a36Sopenharmony_ci wmi->mgmt_max_num_pending_tx, GFP_ATOMIC); 307062306a36Sopenharmony_ci spin_unlock_bh(&ar->data_lock); 307162306a36Sopenharmony_ci 307262306a36Sopenharmony_ci ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi mgmt tx alloc msdu_id ret %d\n", ret); 307362306a36Sopenharmony_ci return ret; 307462306a36Sopenharmony_ci} 307562306a36Sopenharmony_ci 307662306a36Sopenharmony_cistatic struct sk_buff * 307762306a36Sopenharmony_ciath10k_wmi_tlv_op_gen_mgmt_tx_send(struct ath10k *ar, struct sk_buff *msdu, 307862306a36Sopenharmony_ci dma_addr_t paddr) 307962306a36Sopenharmony_ci{ 308062306a36Sopenharmony_ci struct ath10k_skb_cb *cb = ATH10K_SKB_CB(msdu); 308162306a36Sopenharmony_ci struct wmi_tlv_mgmt_tx_cmd *cmd; 308262306a36Sopenharmony_ci struct ieee80211_hdr *hdr; 308362306a36Sopenharmony_ci struct ath10k_vif *arvif; 308462306a36Sopenharmony_ci u32 buf_len = msdu->len; 308562306a36Sopenharmony_ci struct wmi_tlv *tlv; 308662306a36Sopenharmony_ci struct sk_buff *skb; 308762306a36Sopenharmony_ci int len, desc_id; 308862306a36Sopenharmony_ci u32 vdev_id; 308962306a36Sopenharmony_ci void *ptr; 309062306a36Sopenharmony_ci 309162306a36Sopenharmony_ci if (!cb->vif) 309262306a36Sopenharmony_ci return ERR_PTR(-EINVAL); 309362306a36Sopenharmony_ci 309462306a36Sopenharmony_ci hdr = (struct ieee80211_hdr *)msdu->data; 309562306a36Sopenharmony_ci arvif = (void *)cb->vif->drv_priv; 309662306a36Sopenharmony_ci vdev_id = arvif->vdev_id; 309762306a36Sopenharmony_ci 309862306a36Sopenharmony_ci if (WARN_ON_ONCE(!ieee80211_is_mgmt(hdr->frame_control) && 309962306a36Sopenharmony_ci (!(ieee80211_is_nullfunc(hdr->frame_control) || 310062306a36Sopenharmony_ci ieee80211_is_qos_nullfunc(hdr->frame_control))))) 310162306a36Sopenharmony_ci return ERR_PTR(-EINVAL); 310262306a36Sopenharmony_ci 310362306a36Sopenharmony_ci len = sizeof(*cmd) + 2 * sizeof(*tlv); 310462306a36Sopenharmony_ci 310562306a36Sopenharmony_ci if ((ieee80211_is_action(hdr->frame_control) || 310662306a36Sopenharmony_ci ieee80211_is_deauth(hdr->frame_control) || 310762306a36Sopenharmony_ci ieee80211_is_disassoc(hdr->frame_control)) && 310862306a36Sopenharmony_ci ieee80211_has_protected(hdr->frame_control)) { 310962306a36Sopenharmony_ci skb_put(msdu, IEEE80211_CCMP_MIC_LEN); 311062306a36Sopenharmony_ci buf_len += IEEE80211_CCMP_MIC_LEN; 311162306a36Sopenharmony_ci } 311262306a36Sopenharmony_ci 311362306a36Sopenharmony_ci buf_len = min_t(u32, buf_len, WMI_TLV_MGMT_TX_FRAME_MAX_LEN); 311462306a36Sopenharmony_ci buf_len = round_up(buf_len, 4); 311562306a36Sopenharmony_ci 311662306a36Sopenharmony_ci len += buf_len; 311762306a36Sopenharmony_ci len = round_up(len, 4); 311862306a36Sopenharmony_ci skb = ath10k_wmi_alloc_skb(ar, len); 311962306a36Sopenharmony_ci if (!skb) 312062306a36Sopenharmony_ci return ERR_PTR(-ENOMEM); 312162306a36Sopenharmony_ci 312262306a36Sopenharmony_ci desc_id = ath10k_wmi_mgmt_tx_alloc_msdu_id(ar, msdu, paddr); 312362306a36Sopenharmony_ci if (desc_id < 0) 312462306a36Sopenharmony_ci goto err_free_skb; 312562306a36Sopenharmony_ci 312662306a36Sopenharmony_ci cb->msdu_id = desc_id; 312762306a36Sopenharmony_ci 312862306a36Sopenharmony_ci ptr = (void *)skb->data; 312962306a36Sopenharmony_ci tlv = ptr; 313062306a36Sopenharmony_ci tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_MGMT_TX_CMD); 313162306a36Sopenharmony_ci tlv->len = __cpu_to_le16(sizeof(*cmd)); 313262306a36Sopenharmony_ci cmd = (void *)tlv->value; 313362306a36Sopenharmony_ci cmd->vdev_id = __cpu_to_le32(vdev_id); 313462306a36Sopenharmony_ci cmd->desc_id = __cpu_to_le32(desc_id); 313562306a36Sopenharmony_ci cmd->chanfreq = 0; 313662306a36Sopenharmony_ci cmd->buf_len = __cpu_to_le32(buf_len); 313762306a36Sopenharmony_ci cmd->frame_len = __cpu_to_le32(msdu->len); 313862306a36Sopenharmony_ci cmd->paddr = __cpu_to_le64(paddr); 313962306a36Sopenharmony_ci 314062306a36Sopenharmony_ci ptr += sizeof(*tlv); 314162306a36Sopenharmony_ci ptr += sizeof(*cmd); 314262306a36Sopenharmony_ci 314362306a36Sopenharmony_ci tlv = ptr; 314462306a36Sopenharmony_ci tlv->tag = __cpu_to_le16(WMI_TLV_TAG_ARRAY_BYTE); 314562306a36Sopenharmony_ci tlv->len = __cpu_to_le16(buf_len); 314662306a36Sopenharmony_ci 314762306a36Sopenharmony_ci ptr += sizeof(*tlv); 314862306a36Sopenharmony_ci memcpy(ptr, msdu->data, buf_len); 314962306a36Sopenharmony_ci 315062306a36Sopenharmony_ci return skb; 315162306a36Sopenharmony_ci 315262306a36Sopenharmony_cierr_free_skb: 315362306a36Sopenharmony_ci dev_kfree_skb(skb); 315462306a36Sopenharmony_ci return ERR_PTR(desc_id); 315562306a36Sopenharmony_ci} 315662306a36Sopenharmony_ci 315762306a36Sopenharmony_cistatic struct sk_buff * 315862306a36Sopenharmony_ciath10k_wmi_tlv_op_gen_force_fw_hang(struct ath10k *ar, 315962306a36Sopenharmony_ci enum wmi_force_fw_hang_type type, 316062306a36Sopenharmony_ci u32 delay_ms) 316162306a36Sopenharmony_ci{ 316262306a36Sopenharmony_ci struct wmi_force_fw_hang_cmd *cmd; 316362306a36Sopenharmony_ci struct wmi_tlv *tlv; 316462306a36Sopenharmony_ci struct sk_buff *skb; 316562306a36Sopenharmony_ci 316662306a36Sopenharmony_ci skb = ath10k_wmi_alloc_skb(ar, sizeof(*tlv) + sizeof(*cmd)); 316762306a36Sopenharmony_ci if (!skb) 316862306a36Sopenharmony_ci return ERR_PTR(-ENOMEM); 316962306a36Sopenharmony_ci 317062306a36Sopenharmony_ci tlv = (void *)skb->data; 317162306a36Sopenharmony_ci tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_FORCE_FW_HANG_CMD); 317262306a36Sopenharmony_ci tlv->len = __cpu_to_le16(sizeof(*cmd)); 317362306a36Sopenharmony_ci cmd = (void *)tlv->value; 317462306a36Sopenharmony_ci cmd->type = __cpu_to_le32(type); 317562306a36Sopenharmony_ci cmd->delay_ms = __cpu_to_le32(delay_ms); 317662306a36Sopenharmony_ci 317762306a36Sopenharmony_ci ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv force fw hang\n"); 317862306a36Sopenharmony_ci return skb; 317962306a36Sopenharmony_ci} 318062306a36Sopenharmony_ci 318162306a36Sopenharmony_cistatic struct sk_buff * 318262306a36Sopenharmony_ciath10k_wmi_tlv_op_gen_dbglog_cfg(struct ath10k *ar, u64 module_enable, 318362306a36Sopenharmony_ci u32 log_level) 318462306a36Sopenharmony_ci{ 318562306a36Sopenharmony_ci struct wmi_tlv_dbglog_cmd *cmd; 318662306a36Sopenharmony_ci struct wmi_tlv *tlv; 318762306a36Sopenharmony_ci struct sk_buff *skb; 318862306a36Sopenharmony_ci size_t len, bmap_len; 318962306a36Sopenharmony_ci u32 value; 319062306a36Sopenharmony_ci void *ptr; 319162306a36Sopenharmony_ci 319262306a36Sopenharmony_ci if (module_enable) { 319362306a36Sopenharmony_ci value = WMI_TLV_DBGLOG_LOG_LEVEL_VALUE( 319462306a36Sopenharmony_ci module_enable, 319562306a36Sopenharmony_ci WMI_TLV_DBGLOG_LOG_LEVEL_VERBOSE); 319662306a36Sopenharmony_ci } else { 319762306a36Sopenharmony_ci value = WMI_TLV_DBGLOG_LOG_LEVEL_VALUE( 319862306a36Sopenharmony_ci WMI_TLV_DBGLOG_ALL_MODULES, 319962306a36Sopenharmony_ci WMI_TLV_DBGLOG_LOG_LEVEL_WARN); 320062306a36Sopenharmony_ci } 320162306a36Sopenharmony_ci 320262306a36Sopenharmony_ci bmap_len = 0; 320362306a36Sopenharmony_ci len = sizeof(*tlv) + sizeof(*cmd) + sizeof(*tlv) + bmap_len; 320462306a36Sopenharmony_ci skb = ath10k_wmi_alloc_skb(ar, len); 320562306a36Sopenharmony_ci if (!skb) 320662306a36Sopenharmony_ci return ERR_PTR(-ENOMEM); 320762306a36Sopenharmony_ci 320862306a36Sopenharmony_ci ptr = (void *)skb->data; 320962306a36Sopenharmony_ci 321062306a36Sopenharmony_ci tlv = ptr; 321162306a36Sopenharmony_ci tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_DEBUG_LOG_CONFIG_CMD); 321262306a36Sopenharmony_ci tlv->len = __cpu_to_le16(sizeof(*cmd)); 321362306a36Sopenharmony_ci cmd = (void *)tlv->value; 321462306a36Sopenharmony_ci cmd->param = __cpu_to_le32(WMI_TLV_DBGLOG_PARAM_LOG_LEVEL); 321562306a36Sopenharmony_ci cmd->value = __cpu_to_le32(value); 321662306a36Sopenharmony_ci 321762306a36Sopenharmony_ci ptr += sizeof(*tlv); 321862306a36Sopenharmony_ci ptr += sizeof(*cmd); 321962306a36Sopenharmony_ci 322062306a36Sopenharmony_ci tlv = ptr; 322162306a36Sopenharmony_ci tlv->tag = __cpu_to_le16(WMI_TLV_TAG_ARRAY_UINT32); 322262306a36Sopenharmony_ci tlv->len = __cpu_to_le16(bmap_len); 322362306a36Sopenharmony_ci 322462306a36Sopenharmony_ci /* nothing to do here */ 322562306a36Sopenharmony_ci 322662306a36Sopenharmony_ci ptr += sizeof(*tlv); 322762306a36Sopenharmony_ci ptr += sizeof(bmap_len); 322862306a36Sopenharmony_ci 322962306a36Sopenharmony_ci ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv dbglog value 0x%08x\n", value); 323062306a36Sopenharmony_ci return skb; 323162306a36Sopenharmony_ci} 323262306a36Sopenharmony_ci 323362306a36Sopenharmony_cistatic struct sk_buff * 323462306a36Sopenharmony_ciath10k_wmi_tlv_op_gen_pktlog_enable(struct ath10k *ar, u32 filter) 323562306a36Sopenharmony_ci{ 323662306a36Sopenharmony_ci struct wmi_tlv_pktlog_enable *cmd; 323762306a36Sopenharmony_ci struct wmi_tlv *tlv; 323862306a36Sopenharmony_ci struct sk_buff *skb; 323962306a36Sopenharmony_ci void *ptr; 324062306a36Sopenharmony_ci size_t len; 324162306a36Sopenharmony_ci 324262306a36Sopenharmony_ci len = sizeof(*tlv) + sizeof(*cmd); 324362306a36Sopenharmony_ci skb = ath10k_wmi_alloc_skb(ar, len); 324462306a36Sopenharmony_ci if (!skb) 324562306a36Sopenharmony_ci return ERR_PTR(-ENOMEM); 324662306a36Sopenharmony_ci 324762306a36Sopenharmony_ci ptr = (void *)skb->data; 324862306a36Sopenharmony_ci tlv = ptr; 324962306a36Sopenharmony_ci tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_PDEV_PKTLOG_ENABLE_CMD); 325062306a36Sopenharmony_ci tlv->len = __cpu_to_le16(sizeof(*cmd)); 325162306a36Sopenharmony_ci cmd = (void *)tlv->value; 325262306a36Sopenharmony_ci cmd->filter = __cpu_to_le32(filter); 325362306a36Sopenharmony_ci 325462306a36Sopenharmony_ci ptr += sizeof(*tlv); 325562306a36Sopenharmony_ci ptr += sizeof(*cmd); 325662306a36Sopenharmony_ci 325762306a36Sopenharmony_ci ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv pktlog enable filter 0x%08x\n", 325862306a36Sopenharmony_ci filter); 325962306a36Sopenharmony_ci return skb; 326062306a36Sopenharmony_ci} 326162306a36Sopenharmony_ci 326262306a36Sopenharmony_cistatic struct sk_buff * 326362306a36Sopenharmony_ciath10k_wmi_tlv_op_gen_pdev_get_temperature(struct ath10k *ar) 326462306a36Sopenharmony_ci{ 326562306a36Sopenharmony_ci struct wmi_tlv_pdev_get_temp_cmd *cmd; 326662306a36Sopenharmony_ci struct wmi_tlv *tlv; 326762306a36Sopenharmony_ci struct sk_buff *skb; 326862306a36Sopenharmony_ci 326962306a36Sopenharmony_ci skb = ath10k_wmi_alloc_skb(ar, sizeof(*tlv) + sizeof(*cmd)); 327062306a36Sopenharmony_ci if (!skb) 327162306a36Sopenharmony_ci return ERR_PTR(-ENOMEM); 327262306a36Sopenharmony_ci 327362306a36Sopenharmony_ci tlv = (void *)skb->data; 327462306a36Sopenharmony_ci tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_PDEV_GET_TEMPERATURE_CMD); 327562306a36Sopenharmony_ci tlv->len = __cpu_to_le16(sizeof(*cmd)); 327662306a36Sopenharmony_ci cmd = (void *)tlv->value; 327762306a36Sopenharmony_ci ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi pdev get temperature tlv\n"); 327862306a36Sopenharmony_ci return skb; 327962306a36Sopenharmony_ci} 328062306a36Sopenharmony_ci 328162306a36Sopenharmony_cistatic struct sk_buff * 328262306a36Sopenharmony_ciath10k_wmi_tlv_op_gen_pktlog_disable(struct ath10k *ar) 328362306a36Sopenharmony_ci{ 328462306a36Sopenharmony_ci struct wmi_tlv_pktlog_disable *cmd; 328562306a36Sopenharmony_ci struct wmi_tlv *tlv; 328662306a36Sopenharmony_ci struct sk_buff *skb; 328762306a36Sopenharmony_ci void *ptr; 328862306a36Sopenharmony_ci size_t len; 328962306a36Sopenharmony_ci 329062306a36Sopenharmony_ci len = sizeof(*tlv) + sizeof(*cmd); 329162306a36Sopenharmony_ci skb = ath10k_wmi_alloc_skb(ar, len); 329262306a36Sopenharmony_ci if (!skb) 329362306a36Sopenharmony_ci return ERR_PTR(-ENOMEM); 329462306a36Sopenharmony_ci 329562306a36Sopenharmony_ci ptr = (void *)skb->data; 329662306a36Sopenharmony_ci tlv = ptr; 329762306a36Sopenharmony_ci tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_PDEV_PKTLOG_DISABLE_CMD); 329862306a36Sopenharmony_ci tlv->len = __cpu_to_le16(sizeof(*cmd)); 329962306a36Sopenharmony_ci cmd = (void *)tlv->value; 330062306a36Sopenharmony_ci 330162306a36Sopenharmony_ci ptr += sizeof(*tlv); 330262306a36Sopenharmony_ci ptr += sizeof(*cmd); 330362306a36Sopenharmony_ci 330462306a36Sopenharmony_ci ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv pktlog disable\n"); 330562306a36Sopenharmony_ci return skb; 330662306a36Sopenharmony_ci} 330762306a36Sopenharmony_ci 330862306a36Sopenharmony_cistatic struct sk_buff * 330962306a36Sopenharmony_ciath10k_wmi_tlv_op_gen_bcn_tmpl(struct ath10k *ar, u32 vdev_id, 331062306a36Sopenharmony_ci u32 tim_ie_offset, struct sk_buff *bcn, 331162306a36Sopenharmony_ci u32 prb_caps, u32 prb_erp, void *prb_ies, 331262306a36Sopenharmony_ci size_t prb_ies_len) 331362306a36Sopenharmony_ci{ 331462306a36Sopenharmony_ci struct wmi_tlv_bcn_tmpl_cmd *cmd; 331562306a36Sopenharmony_ci struct wmi_tlv_bcn_prb_info *info; 331662306a36Sopenharmony_ci struct wmi_tlv *tlv; 331762306a36Sopenharmony_ci struct sk_buff *skb; 331862306a36Sopenharmony_ci void *ptr; 331962306a36Sopenharmony_ci size_t len; 332062306a36Sopenharmony_ci 332162306a36Sopenharmony_ci if (WARN_ON(prb_ies_len > 0 && !prb_ies)) 332262306a36Sopenharmony_ci return ERR_PTR(-EINVAL); 332362306a36Sopenharmony_ci 332462306a36Sopenharmony_ci len = sizeof(*tlv) + sizeof(*cmd) + 332562306a36Sopenharmony_ci sizeof(*tlv) + sizeof(*info) + prb_ies_len + 332662306a36Sopenharmony_ci sizeof(*tlv) + roundup(bcn->len, 4); 332762306a36Sopenharmony_ci skb = ath10k_wmi_alloc_skb(ar, len); 332862306a36Sopenharmony_ci if (!skb) 332962306a36Sopenharmony_ci return ERR_PTR(-ENOMEM); 333062306a36Sopenharmony_ci 333162306a36Sopenharmony_ci ptr = (void *)skb->data; 333262306a36Sopenharmony_ci tlv = ptr; 333362306a36Sopenharmony_ci tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_BCN_TMPL_CMD); 333462306a36Sopenharmony_ci tlv->len = __cpu_to_le16(sizeof(*cmd)); 333562306a36Sopenharmony_ci cmd = (void *)tlv->value; 333662306a36Sopenharmony_ci cmd->vdev_id = __cpu_to_le32(vdev_id); 333762306a36Sopenharmony_ci cmd->tim_ie_offset = __cpu_to_le32(tim_ie_offset); 333862306a36Sopenharmony_ci cmd->buf_len = __cpu_to_le32(bcn->len); 333962306a36Sopenharmony_ci 334062306a36Sopenharmony_ci ptr += sizeof(*tlv); 334162306a36Sopenharmony_ci ptr += sizeof(*cmd); 334262306a36Sopenharmony_ci 334362306a36Sopenharmony_ci /* FIXME: prb_ies_len should be probably aligned to 4byte boundary but 334462306a36Sopenharmony_ci * then it is then impossible to pass original ie len. 334562306a36Sopenharmony_ci * This chunk is not used yet so if setting probe resp template yields 334662306a36Sopenharmony_ci * problems with beaconing or crashes firmware look here. 334762306a36Sopenharmony_ci */ 334862306a36Sopenharmony_ci tlv = ptr; 334962306a36Sopenharmony_ci tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_BCN_PRB_INFO); 335062306a36Sopenharmony_ci tlv->len = __cpu_to_le16(sizeof(*info) + prb_ies_len); 335162306a36Sopenharmony_ci info = (void *)tlv->value; 335262306a36Sopenharmony_ci info->caps = __cpu_to_le32(prb_caps); 335362306a36Sopenharmony_ci info->erp = __cpu_to_le32(prb_erp); 335462306a36Sopenharmony_ci memcpy(info->ies, prb_ies, prb_ies_len); 335562306a36Sopenharmony_ci 335662306a36Sopenharmony_ci ptr += sizeof(*tlv); 335762306a36Sopenharmony_ci ptr += sizeof(*info); 335862306a36Sopenharmony_ci ptr += prb_ies_len; 335962306a36Sopenharmony_ci 336062306a36Sopenharmony_ci tlv = ptr; 336162306a36Sopenharmony_ci tlv->tag = __cpu_to_le16(WMI_TLV_TAG_ARRAY_BYTE); 336262306a36Sopenharmony_ci tlv->len = __cpu_to_le16(roundup(bcn->len, 4)); 336362306a36Sopenharmony_ci memcpy(tlv->value, bcn->data, bcn->len); 336462306a36Sopenharmony_ci 336562306a36Sopenharmony_ci /* FIXME: Adjust TSF? */ 336662306a36Sopenharmony_ci 336762306a36Sopenharmony_ci ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv bcn tmpl vdev_id %i\n", 336862306a36Sopenharmony_ci vdev_id); 336962306a36Sopenharmony_ci return skb; 337062306a36Sopenharmony_ci} 337162306a36Sopenharmony_ci 337262306a36Sopenharmony_cistatic struct sk_buff * 337362306a36Sopenharmony_ciath10k_wmi_tlv_op_gen_prb_tmpl(struct ath10k *ar, u32 vdev_id, 337462306a36Sopenharmony_ci struct sk_buff *prb) 337562306a36Sopenharmony_ci{ 337662306a36Sopenharmony_ci struct wmi_tlv_prb_tmpl_cmd *cmd; 337762306a36Sopenharmony_ci struct wmi_tlv_bcn_prb_info *info; 337862306a36Sopenharmony_ci struct wmi_tlv *tlv; 337962306a36Sopenharmony_ci struct sk_buff *skb; 338062306a36Sopenharmony_ci void *ptr; 338162306a36Sopenharmony_ci size_t len; 338262306a36Sopenharmony_ci 338362306a36Sopenharmony_ci len = sizeof(*tlv) + sizeof(*cmd) + 338462306a36Sopenharmony_ci sizeof(*tlv) + sizeof(*info) + 338562306a36Sopenharmony_ci sizeof(*tlv) + roundup(prb->len, 4); 338662306a36Sopenharmony_ci skb = ath10k_wmi_alloc_skb(ar, len); 338762306a36Sopenharmony_ci if (!skb) 338862306a36Sopenharmony_ci return ERR_PTR(-ENOMEM); 338962306a36Sopenharmony_ci 339062306a36Sopenharmony_ci ptr = (void *)skb->data; 339162306a36Sopenharmony_ci tlv = ptr; 339262306a36Sopenharmony_ci tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_PRB_TMPL_CMD); 339362306a36Sopenharmony_ci tlv->len = __cpu_to_le16(sizeof(*cmd)); 339462306a36Sopenharmony_ci cmd = (void *)tlv->value; 339562306a36Sopenharmony_ci cmd->vdev_id = __cpu_to_le32(vdev_id); 339662306a36Sopenharmony_ci cmd->buf_len = __cpu_to_le32(prb->len); 339762306a36Sopenharmony_ci 339862306a36Sopenharmony_ci ptr += sizeof(*tlv); 339962306a36Sopenharmony_ci ptr += sizeof(*cmd); 340062306a36Sopenharmony_ci 340162306a36Sopenharmony_ci tlv = ptr; 340262306a36Sopenharmony_ci tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_BCN_PRB_INFO); 340362306a36Sopenharmony_ci tlv->len = __cpu_to_le16(sizeof(*info)); 340462306a36Sopenharmony_ci info = (void *)tlv->value; 340562306a36Sopenharmony_ci info->caps = 0; 340662306a36Sopenharmony_ci info->erp = 0; 340762306a36Sopenharmony_ci 340862306a36Sopenharmony_ci ptr += sizeof(*tlv); 340962306a36Sopenharmony_ci ptr += sizeof(*info); 341062306a36Sopenharmony_ci 341162306a36Sopenharmony_ci tlv = ptr; 341262306a36Sopenharmony_ci tlv->tag = __cpu_to_le16(WMI_TLV_TAG_ARRAY_BYTE); 341362306a36Sopenharmony_ci tlv->len = __cpu_to_le16(roundup(prb->len, 4)); 341462306a36Sopenharmony_ci memcpy(tlv->value, prb->data, prb->len); 341562306a36Sopenharmony_ci 341662306a36Sopenharmony_ci ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv prb tmpl vdev_id %i\n", 341762306a36Sopenharmony_ci vdev_id); 341862306a36Sopenharmony_ci return skb; 341962306a36Sopenharmony_ci} 342062306a36Sopenharmony_ci 342162306a36Sopenharmony_cistatic struct sk_buff * 342262306a36Sopenharmony_ciath10k_wmi_tlv_op_gen_p2p_go_bcn_ie(struct ath10k *ar, u32 vdev_id, 342362306a36Sopenharmony_ci const u8 *p2p_ie) 342462306a36Sopenharmony_ci{ 342562306a36Sopenharmony_ci struct wmi_tlv_p2p_go_bcn_ie *cmd; 342662306a36Sopenharmony_ci struct wmi_tlv *tlv; 342762306a36Sopenharmony_ci struct sk_buff *skb; 342862306a36Sopenharmony_ci void *ptr; 342962306a36Sopenharmony_ci size_t len; 343062306a36Sopenharmony_ci 343162306a36Sopenharmony_ci len = sizeof(*tlv) + sizeof(*cmd) + 343262306a36Sopenharmony_ci sizeof(*tlv) + roundup(p2p_ie[1] + 2, 4); 343362306a36Sopenharmony_ci skb = ath10k_wmi_alloc_skb(ar, len); 343462306a36Sopenharmony_ci if (!skb) 343562306a36Sopenharmony_ci return ERR_PTR(-ENOMEM); 343662306a36Sopenharmony_ci 343762306a36Sopenharmony_ci ptr = (void *)skb->data; 343862306a36Sopenharmony_ci tlv = ptr; 343962306a36Sopenharmony_ci tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_P2P_GO_SET_BEACON_IE); 344062306a36Sopenharmony_ci tlv->len = __cpu_to_le16(sizeof(*cmd)); 344162306a36Sopenharmony_ci cmd = (void *)tlv->value; 344262306a36Sopenharmony_ci cmd->vdev_id = __cpu_to_le32(vdev_id); 344362306a36Sopenharmony_ci cmd->ie_len = __cpu_to_le32(p2p_ie[1] + 2); 344462306a36Sopenharmony_ci 344562306a36Sopenharmony_ci ptr += sizeof(*tlv); 344662306a36Sopenharmony_ci ptr += sizeof(*cmd); 344762306a36Sopenharmony_ci 344862306a36Sopenharmony_ci tlv = ptr; 344962306a36Sopenharmony_ci tlv->tag = __cpu_to_le16(WMI_TLV_TAG_ARRAY_BYTE); 345062306a36Sopenharmony_ci tlv->len = __cpu_to_le16(roundup(p2p_ie[1] + 2, 4)); 345162306a36Sopenharmony_ci memcpy(tlv->value, p2p_ie, p2p_ie[1] + 2); 345262306a36Sopenharmony_ci 345362306a36Sopenharmony_ci ptr += sizeof(*tlv); 345462306a36Sopenharmony_ci ptr += roundup(p2p_ie[1] + 2, 4); 345562306a36Sopenharmony_ci 345662306a36Sopenharmony_ci ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv p2p go bcn ie for vdev %i\n", 345762306a36Sopenharmony_ci vdev_id); 345862306a36Sopenharmony_ci return skb; 345962306a36Sopenharmony_ci} 346062306a36Sopenharmony_ci 346162306a36Sopenharmony_cistatic struct sk_buff * 346262306a36Sopenharmony_ciath10k_wmi_tlv_op_gen_update_fw_tdls_state(struct ath10k *ar, u32 vdev_id, 346362306a36Sopenharmony_ci enum wmi_tdls_state state) 346462306a36Sopenharmony_ci{ 346562306a36Sopenharmony_ci struct wmi_tdls_set_state_cmd *cmd; 346662306a36Sopenharmony_ci struct wmi_tlv *tlv; 346762306a36Sopenharmony_ci struct sk_buff *skb; 346862306a36Sopenharmony_ci void *ptr; 346962306a36Sopenharmony_ci size_t len; 347062306a36Sopenharmony_ci /* Set to options from wmi_tlv_tdls_options, 347162306a36Sopenharmony_ci * for now none of them are enabled. 347262306a36Sopenharmony_ci */ 347362306a36Sopenharmony_ci u32 options = 0; 347462306a36Sopenharmony_ci 347562306a36Sopenharmony_ci if (test_bit(WMI_SERVICE_TDLS_UAPSD_BUFFER_STA, ar->wmi.svc_map)) 347662306a36Sopenharmony_ci options |= WMI_TLV_TDLS_BUFFER_STA_EN; 347762306a36Sopenharmony_ci 347862306a36Sopenharmony_ci /* WMI_TDLS_ENABLE_ACTIVE_EXTERNAL_CONTROL means firm will handle TDLS 347962306a36Sopenharmony_ci * link inactivity detecting logic. 348062306a36Sopenharmony_ci */ 348162306a36Sopenharmony_ci if (state == WMI_TDLS_ENABLE_ACTIVE) 348262306a36Sopenharmony_ci state = WMI_TDLS_ENABLE_ACTIVE_EXTERNAL_CONTROL; 348362306a36Sopenharmony_ci 348462306a36Sopenharmony_ci len = sizeof(*tlv) + sizeof(*cmd); 348562306a36Sopenharmony_ci skb = ath10k_wmi_alloc_skb(ar, len); 348662306a36Sopenharmony_ci if (!skb) 348762306a36Sopenharmony_ci return ERR_PTR(-ENOMEM); 348862306a36Sopenharmony_ci 348962306a36Sopenharmony_ci ptr = (void *)skb->data; 349062306a36Sopenharmony_ci tlv = ptr; 349162306a36Sopenharmony_ci tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_TDLS_SET_STATE_CMD); 349262306a36Sopenharmony_ci tlv->len = __cpu_to_le16(sizeof(*cmd)); 349362306a36Sopenharmony_ci 349462306a36Sopenharmony_ci cmd = (void *)tlv->value; 349562306a36Sopenharmony_ci cmd->vdev_id = __cpu_to_le32(vdev_id); 349662306a36Sopenharmony_ci cmd->state = __cpu_to_le32(state); 349762306a36Sopenharmony_ci cmd->notification_interval_ms = __cpu_to_le32(5000); 349862306a36Sopenharmony_ci cmd->tx_discovery_threshold = __cpu_to_le32(100); 349962306a36Sopenharmony_ci cmd->tx_teardown_threshold = __cpu_to_le32(5); 350062306a36Sopenharmony_ci cmd->rssi_teardown_threshold = __cpu_to_le32(-75); 350162306a36Sopenharmony_ci cmd->rssi_delta = __cpu_to_le32(-20); 350262306a36Sopenharmony_ci cmd->tdls_options = __cpu_to_le32(options); 350362306a36Sopenharmony_ci cmd->tdls_peer_traffic_ind_window = __cpu_to_le32(2); 350462306a36Sopenharmony_ci cmd->tdls_peer_traffic_response_timeout_ms = __cpu_to_le32(5000); 350562306a36Sopenharmony_ci cmd->tdls_puapsd_mask = __cpu_to_le32(0xf); 350662306a36Sopenharmony_ci cmd->tdls_puapsd_inactivity_time_ms = __cpu_to_le32(0); 350762306a36Sopenharmony_ci cmd->tdls_puapsd_rx_frame_threshold = __cpu_to_le32(10); 350862306a36Sopenharmony_ci 350962306a36Sopenharmony_ci ptr += sizeof(*tlv); 351062306a36Sopenharmony_ci ptr += sizeof(*cmd); 351162306a36Sopenharmony_ci 351262306a36Sopenharmony_ci ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv update fw tdls state %d for vdev %i\n", 351362306a36Sopenharmony_ci state, vdev_id); 351462306a36Sopenharmony_ci return skb; 351562306a36Sopenharmony_ci} 351662306a36Sopenharmony_ci 351762306a36Sopenharmony_cistatic u32 ath10k_wmi_tlv_prepare_peer_qos(u8 uapsd_queues, u8 sp) 351862306a36Sopenharmony_ci{ 351962306a36Sopenharmony_ci u32 peer_qos = 0; 352062306a36Sopenharmony_ci 352162306a36Sopenharmony_ci if (uapsd_queues & IEEE80211_WMM_IE_STA_QOSINFO_AC_VO) 352262306a36Sopenharmony_ci peer_qos |= WMI_TLV_TDLS_PEER_QOS_AC_VO; 352362306a36Sopenharmony_ci if (uapsd_queues & IEEE80211_WMM_IE_STA_QOSINFO_AC_VI) 352462306a36Sopenharmony_ci peer_qos |= WMI_TLV_TDLS_PEER_QOS_AC_VI; 352562306a36Sopenharmony_ci if (uapsd_queues & IEEE80211_WMM_IE_STA_QOSINFO_AC_BK) 352662306a36Sopenharmony_ci peer_qos |= WMI_TLV_TDLS_PEER_QOS_AC_BK; 352762306a36Sopenharmony_ci if (uapsd_queues & IEEE80211_WMM_IE_STA_QOSINFO_AC_BE) 352862306a36Sopenharmony_ci peer_qos |= WMI_TLV_TDLS_PEER_QOS_AC_BE; 352962306a36Sopenharmony_ci 353062306a36Sopenharmony_ci peer_qos |= SM(sp, WMI_TLV_TDLS_PEER_SP); 353162306a36Sopenharmony_ci 353262306a36Sopenharmony_ci return peer_qos; 353362306a36Sopenharmony_ci} 353462306a36Sopenharmony_ci 353562306a36Sopenharmony_cistatic struct sk_buff * 353662306a36Sopenharmony_ciath10k_wmi_tlv_op_gen_tdls_peer_update(struct ath10k *ar, 353762306a36Sopenharmony_ci const struct wmi_tdls_peer_update_cmd_arg *arg, 353862306a36Sopenharmony_ci const struct wmi_tdls_peer_capab_arg *cap, 353962306a36Sopenharmony_ci const struct wmi_channel_arg *chan_arg) 354062306a36Sopenharmony_ci{ 354162306a36Sopenharmony_ci struct wmi_tdls_peer_update_cmd *cmd; 354262306a36Sopenharmony_ci struct wmi_tdls_peer_capab *peer_cap; 354362306a36Sopenharmony_ci struct wmi_channel *chan; 354462306a36Sopenharmony_ci struct wmi_tlv *tlv; 354562306a36Sopenharmony_ci struct sk_buff *skb; 354662306a36Sopenharmony_ci u32 peer_qos; 354762306a36Sopenharmony_ci void *ptr; 354862306a36Sopenharmony_ci int len; 354962306a36Sopenharmony_ci int i; 355062306a36Sopenharmony_ci 355162306a36Sopenharmony_ci len = sizeof(*tlv) + sizeof(*cmd) + 355262306a36Sopenharmony_ci sizeof(*tlv) + sizeof(*peer_cap) + 355362306a36Sopenharmony_ci sizeof(*tlv) + cap->peer_chan_len * sizeof(*chan); 355462306a36Sopenharmony_ci 355562306a36Sopenharmony_ci skb = ath10k_wmi_alloc_skb(ar, len); 355662306a36Sopenharmony_ci if (!skb) 355762306a36Sopenharmony_ci return ERR_PTR(-ENOMEM); 355862306a36Sopenharmony_ci 355962306a36Sopenharmony_ci ptr = (void *)skb->data; 356062306a36Sopenharmony_ci tlv = ptr; 356162306a36Sopenharmony_ci tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_TDLS_PEER_UPDATE_CMD); 356262306a36Sopenharmony_ci tlv->len = __cpu_to_le16(sizeof(*cmd)); 356362306a36Sopenharmony_ci 356462306a36Sopenharmony_ci cmd = (void *)tlv->value; 356562306a36Sopenharmony_ci cmd->vdev_id = __cpu_to_le32(arg->vdev_id); 356662306a36Sopenharmony_ci ether_addr_copy(cmd->peer_macaddr.addr, arg->addr); 356762306a36Sopenharmony_ci cmd->peer_state = __cpu_to_le32(arg->peer_state); 356862306a36Sopenharmony_ci 356962306a36Sopenharmony_ci ptr += sizeof(*tlv); 357062306a36Sopenharmony_ci ptr += sizeof(*cmd); 357162306a36Sopenharmony_ci 357262306a36Sopenharmony_ci tlv = ptr; 357362306a36Sopenharmony_ci tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_TDLS_PEER_CAPABILITIES); 357462306a36Sopenharmony_ci tlv->len = __cpu_to_le16(sizeof(*peer_cap)); 357562306a36Sopenharmony_ci peer_cap = (void *)tlv->value; 357662306a36Sopenharmony_ci peer_qos = ath10k_wmi_tlv_prepare_peer_qos(cap->peer_uapsd_queues, 357762306a36Sopenharmony_ci cap->peer_max_sp); 357862306a36Sopenharmony_ci peer_cap->peer_qos = __cpu_to_le32(peer_qos); 357962306a36Sopenharmony_ci peer_cap->buff_sta_support = __cpu_to_le32(cap->buff_sta_support); 358062306a36Sopenharmony_ci peer_cap->off_chan_support = __cpu_to_le32(cap->off_chan_support); 358162306a36Sopenharmony_ci peer_cap->peer_curr_operclass = __cpu_to_le32(cap->peer_curr_operclass); 358262306a36Sopenharmony_ci peer_cap->self_curr_operclass = __cpu_to_le32(cap->self_curr_operclass); 358362306a36Sopenharmony_ci peer_cap->peer_chan_len = __cpu_to_le32(cap->peer_chan_len); 358462306a36Sopenharmony_ci peer_cap->peer_operclass_len = __cpu_to_le32(cap->peer_operclass_len); 358562306a36Sopenharmony_ci 358662306a36Sopenharmony_ci for (i = 0; i < WMI_TDLS_MAX_SUPP_OPER_CLASSES; i++) 358762306a36Sopenharmony_ci peer_cap->peer_operclass[i] = cap->peer_operclass[i]; 358862306a36Sopenharmony_ci 358962306a36Sopenharmony_ci peer_cap->is_peer_responder = __cpu_to_le32(cap->is_peer_responder); 359062306a36Sopenharmony_ci peer_cap->pref_offchan_num = __cpu_to_le32(cap->pref_offchan_num); 359162306a36Sopenharmony_ci peer_cap->pref_offchan_bw = __cpu_to_le32(cap->pref_offchan_bw); 359262306a36Sopenharmony_ci 359362306a36Sopenharmony_ci ptr += sizeof(*tlv); 359462306a36Sopenharmony_ci ptr += sizeof(*peer_cap); 359562306a36Sopenharmony_ci 359662306a36Sopenharmony_ci tlv = ptr; 359762306a36Sopenharmony_ci tlv->tag = __cpu_to_le16(WMI_TLV_TAG_ARRAY_STRUCT); 359862306a36Sopenharmony_ci tlv->len = __cpu_to_le16(cap->peer_chan_len * sizeof(*chan)); 359962306a36Sopenharmony_ci 360062306a36Sopenharmony_ci ptr += sizeof(*tlv); 360162306a36Sopenharmony_ci 360262306a36Sopenharmony_ci for (i = 0; i < cap->peer_chan_len; i++) { 360362306a36Sopenharmony_ci tlv = ptr; 360462306a36Sopenharmony_ci tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_CHANNEL); 360562306a36Sopenharmony_ci tlv->len = __cpu_to_le16(sizeof(*chan)); 360662306a36Sopenharmony_ci chan = (void *)tlv->value; 360762306a36Sopenharmony_ci ath10k_wmi_put_wmi_channel(ar, chan, &chan_arg[i]); 360862306a36Sopenharmony_ci 360962306a36Sopenharmony_ci ptr += sizeof(*tlv); 361062306a36Sopenharmony_ci ptr += sizeof(*chan); 361162306a36Sopenharmony_ci } 361262306a36Sopenharmony_ci 361362306a36Sopenharmony_ci ath10k_dbg(ar, ATH10K_DBG_WMI, 361462306a36Sopenharmony_ci "wmi tlv tdls peer update vdev %i state %d n_chans %u\n", 361562306a36Sopenharmony_ci arg->vdev_id, arg->peer_state, cap->peer_chan_len); 361662306a36Sopenharmony_ci return skb; 361762306a36Sopenharmony_ci} 361862306a36Sopenharmony_ci 361962306a36Sopenharmony_cistatic struct sk_buff * 362062306a36Sopenharmony_ciath10k_wmi_tlv_op_gen_pdev_set_quiet_mode(struct ath10k *ar, u32 period, 362162306a36Sopenharmony_ci u32 duration, u32 next_offset, 362262306a36Sopenharmony_ci u32 enabled) 362362306a36Sopenharmony_ci{ 362462306a36Sopenharmony_ci struct wmi_tlv_set_quiet_cmd *cmd; 362562306a36Sopenharmony_ci struct wmi_tlv *tlv; 362662306a36Sopenharmony_ci struct sk_buff *skb; 362762306a36Sopenharmony_ci 362862306a36Sopenharmony_ci skb = ath10k_wmi_alloc_skb(ar, sizeof(*tlv) + sizeof(*cmd)); 362962306a36Sopenharmony_ci if (!skb) 363062306a36Sopenharmony_ci return ERR_PTR(-ENOMEM); 363162306a36Sopenharmony_ci 363262306a36Sopenharmony_ci tlv = (void *)skb->data; 363362306a36Sopenharmony_ci tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_PDEV_SET_QUIET_CMD); 363462306a36Sopenharmony_ci tlv->len = __cpu_to_le16(sizeof(*cmd)); 363562306a36Sopenharmony_ci cmd = (void *)tlv->value; 363662306a36Sopenharmony_ci 363762306a36Sopenharmony_ci /* vdev_id is not in use, set to 0 */ 363862306a36Sopenharmony_ci cmd->vdev_id = __cpu_to_le32(0); 363962306a36Sopenharmony_ci cmd->period = __cpu_to_le32(period); 364062306a36Sopenharmony_ci cmd->duration = __cpu_to_le32(duration); 364162306a36Sopenharmony_ci cmd->next_start = __cpu_to_le32(next_offset); 364262306a36Sopenharmony_ci cmd->enabled = __cpu_to_le32(enabled); 364362306a36Sopenharmony_ci 364462306a36Sopenharmony_ci ath10k_dbg(ar, ATH10K_DBG_WMI, 364562306a36Sopenharmony_ci "wmi tlv quiet param: period %u duration %u enabled %d\n", 364662306a36Sopenharmony_ci period, duration, enabled); 364762306a36Sopenharmony_ci return skb; 364862306a36Sopenharmony_ci} 364962306a36Sopenharmony_ci 365062306a36Sopenharmony_cistatic struct sk_buff * 365162306a36Sopenharmony_ciath10k_wmi_tlv_op_gen_wow_enable(struct ath10k *ar) 365262306a36Sopenharmony_ci{ 365362306a36Sopenharmony_ci struct wmi_tlv_wow_enable_cmd *cmd; 365462306a36Sopenharmony_ci struct wmi_tlv *tlv; 365562306a36Sopenharmony_ci struct sk_buff *skb; 365662306a36Sopenharmony_ci size_t len; 365762306a36Sopenharmony_ci 365862306a36Sopenharmony_ci len = sizeof(*tlv) + sizeof(*cmd); 365962306a36Sopenharmony_ci skb = ath10k_wmi_alloc_skb(ar, len); 366062306a36Sopenharmony_ci if (!skb) 366162306a36Sopenharmony_ci return ERR_PTR(-ENOMEM); 366262306a36Sopenharmony_ci 366362306a36Sopenharmony_ci tlv = (struct wmi_tlv *)skb->data; 366462306a36Sopenharmony_ci tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_WOW_ENABLE_CMD); 366562306a36Sopenharmony_ci tlv->len = __cpu_to_le16(sizeof(*cmd)); 366662306a36Sopenharmony_ci cmd = (void *)tlv->value; 366762306a36Sopenharmony_ci 366862306a36Sopenharmony_ci cmd->enable = __cpu_to_le32(1); 366962306a36Sopenharmony_ci if (!ar->bus_param.link_can_suspend) 367062306a36Sopenharmony_ci cmd->pause_iface_config = __cpu_to_le32(WOW_IFACE_PAUSE_DISABLED); 367162306a36Sopenharmony_ci 367262306a36Sopenharmony_ci ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv wow enable\n"); 367362306a36Sopenharmony_ci return skb; 367462306a36Sopenharmony_ci} 367562306a36Sopenharmony_ci 367662306a36Sopenharmony_cistatic struct sk_buff * 367762306a36Sopenharmony_ciath10k_wmi_tlv_op_gen_wow_add_wakeup_event(struct ath10k *ar, 367862306a36Sopenharmony_ci u32 vdev_id, 367962306a36Sopenharmony_ci enum wmi_wow_wakeup_event event, 368062306a36Sopenharmony_ci u32 enable) 368162306a36Sopenharmony_ci{ 368262306a36Sopenharmony_ci struct wmi_tlv_wow_add_del_event_cmd *cmd; 368362306a36Sopenharmony_ci struct wmi_tlv *tlv; 368462306a36Sopenharmony_ci struct sk_buff *skb; 368562306a36Sopenharmony_ci size_t len; 368662306a36Sopenharmony_ci 368762306a36Sopenharmony_ci len = sizeof(*tlv) + sizeof(*cmd); 368862306a36Sopenharmony_ci skb = ath10k_wmi_alloc_skb(ar, len); 368962306a36Sopenharmony_ci if (!skb) 369062306a36Sopenharmony_ci return ERR_PTR(-ENOMEM); 369162306a36Sopenharmony_ci 369262306a36Sopenharmony_ci tlv = (struct wmi_tlv *)skb->data; 369362306a36Sopenharmony_ci tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_WOW_ADD_DEL_EVT_CMD); 369462306a36Sopenharmony_ci tlv->len = __cpu_to_le16(sizeof(*cmd)); 369562306a36Sopenharmony_ci cmd = (void *)tlv->value; 369662306a36Sopenharmony_ci 369762306a36Sopenharmony_ci cmd->vdev_id = __cpu_to_le32(vdev_id); 369862306a36Sopenharmony_ci cmd->is_add = __cpu_to_le32(enable); 369962306a36Sopenharmony_ci cmd->event_bitmap = __cpu_to_le32(1 << event); 370062306a36Sopenharmony_ci 370162306a36Sopenharmony_ci ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv wow add wakeup event %s enable %d vdev_id %d\n", 370262306a36Sopenharmony_ci wow_wakeup_event(event), enable, vdev_id); 370362306a36Sopenharmony_ci return skb; 370462306a36Sopenharmony_ci} 370562306a36Sopenharmony_ci 370662306a36Sopenharmony_cistatic struct sk_buff * 370762306a36Sopenharmony_ciath10k_wmi_tlv_gen_wow_host_wakeup_ind(struct ath10k *ar) 370862306a36Sopenharmony_ci{ 370962306a36Sopenharmony_ci struct wmi_tlv_wow_host_wakeup_ind *cmd; 371062306a36Sopenharmony_ci struct wmi_tlv *tlv; 371162306a36Sopenharmony_ci struct sk_buff *skb; 371262306a36Sopenharmony_ci size_t len; 371362306a36Sopenharmony_ci 371462306a36Sopenharmony_ci len = sizeof(*tlv) + sizeof(*cmd); 371562306a36Sopenharmony_ci skb = ath10k_wmi_alloc_skb(ar, len); 371662306a36Sopenharmony_ci if (!skb) 371762306a36Sopenharmony_ci return ERR_PTR(-ENOMEM); 371862306a36Sopenharmony_ci 371962306a36Sopenharmony_ci tlv = (struct wmi_tlv *)skb->data; 372062306a36Sopenharmony_ci tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_WOW_HOSTWAKEUP_FROM_SLEEP_CMD); 372162306a36Sopenharmony_ci tlv->len = __cpu_to_le16(sizeof(*cmd)); 372262306a36Sopenharmony_ci cmd = (void *)tlv->value; 372362306a36Sopenharmony_ci 372462306a36Sopenharmony_ci ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv wow host wakeup ind\n"); 372562306a36Sopenharmony_ci return skb; 372662306a36Sopenharmony_ci} 372762306a36Sopenharmony_ci 372862306a36Sopenharmony_cistatic struct sk_buff * 372962306a36Sopenharmony_ciath10k_wmi_tlv_op_gen_wow_add_pattern(struct ath10k *ar, u32 vdev_id, 373062306a36Sopenharmony_ci u32 pattern_id, const u8 *pattern, 373162306a36Sopenharmony_ci const u8 *bitmask, int pattern_len, 373262306a36Sopenharmony_ci int pattern_offset) 373362306a36Sopenharmony_ci{ 373462306a36Sopenharmony_ci struct wmi_tlv_wow_add_pattern_cmd *cmd; 373562306a36Sopenharmony_ci struct wmi_tlv_wow_bitmap_pattern *bitmap; 373662306a36Sopenharmony_ci struct wmi_tlv *tlv; 373762306a36Sopenharmony_ci struct sk_buff *skb; 373862306a36Sopenharmony_ci void *ptr; 373962306a36Sopenharmony_ci size_t len; 374062306a36Sopenharmony_ci 374162306a36Sopenharmony_ci len = sizeof(*tlv) + sizeof(*cmd) + 374262306a36Sopenharmony_ci sizeof(*tlv) + /* array struct */ 374362306a36Sopenharmony_ci sizeof(*tlv) + sizeof(*bitmap) + /* bitmap */ 374462306a36Sopenharmony_ci sizeof(*tlv) + /* empty ipv4 sync */ 374562306a36Sopenharmony_ci sizeof(*tlv) + /* empty ipv6 sync */ 374662306a36Sopenharmony_ci sizeof(*tlv) + /* empty magic */ 374762306a36Sopenharmony_ci sizeof(*tlv) + /* empty info timeout */ 374862306a36Sopenharmony_ci sizeof(*tlv) + sizeof(u32); /* ratelimit interval */ 374962306a36Sopenharmony_ci 375062306a36Sopenharmony_ci skb = ath10k_wmi_alloc_skb(ar, len); 375162306a36Sopenharmony_ci if (!skb) 375262306a36Sopenharmony_ci return ERR_PTR(-ENOMEM); 375362306a36Sopenharmony_ci 375462306a36Sopenharmony_ci /* cmd */ 375562306a36Sopenharmony_ci ptr = (void *)skb->data; 375662306a36Sopenharmony_ci tlv = ptr; 375762306a36Sopenharmony_ci tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_WOW_ADD_PATTERN_CMD); 375862306a36Sopenharmony_ci tlv->len = __cpu_to_le16(sizeof(*cmd)); 375962306a36Sopenharmony_ci cmd = (void *)tlv->value; 376062306a36Sopenharmony_ci 376162306a36Sopenharmony_ci cmd->vdev_id = __cpu_to_le32(vdev_id); 376262306a36Sopenharmony_ci cmd->pattern_id = __cpu_to_le32(pattern_id); 376362306a36Sopenharmony_ci cmd->pattern_type = __cpu_to_le32(WOW_BITMAP_PATTERN); 376462306a36Sopenharmony_ci 376562306a36Sopenharmony_ci ptr += sizeof(*tlv); 376662306a36Sopenharmony_ci ptr += sizeof(*cmd); 376762306a36Sopenharmony_ci 376862306a36Sopenharmony_ci /* bitmap */ 376962306a36Sopenharmony_ci tlv = ptr; 377062306a36Sopenharmony_ci tlv->tag = __cpu_to_le16(WMI_TLV_TAG_ARRAY_STRUCT); 377162306a36Sopenharmony_ci tlv->len = __cpu_to_le16(sizeof(*tlv) + sizeof(*bitmap)); 377262306a36Sopenharmony_ci 377362306a36Sopenharmony_ci ptr += sizeof(*tlv); 377462306a36Sopenharmony_ci 377562306a36Sopenharmony_ci tlv = ptr; 377662306a36Sopenharmony_ci tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_WOW_BITMAP_PATTERN_T); 377762306a36Sopenharmony_ci tlv->len = __cpu_to_le16(sizeof(*bitmap)); 377862306a36Sopenharmony_ci bitmap = (void *)tlv->value; 377962306a36Sopenharmony_ci 378062306a36Sopenharmony_ci memcpy(bitmap->patternbuf, pattern, pattern_len); 378162306a36Sopenharmony_ci memcpy(bitmap->bitmaskbuf, bitmask, pattern_len); 378262306a36Sopenharmony_ci bitmap->pattern_offset = __cpu_to_le32(pattern_offset); 378362306a36Sopenharmony_ci bitmap->pattern_len = __cpu_to_le32(pattern_len); 378462306a36Sopenharmony_ci bitmap->bitmask_len = __cpu_to_le32(pattern_len); 378562306a36Sopenharmony_ci bitmap->pattern_id = __cpu_to_le32(pattern_id); 378662306a36Sopenharmony_ci 378762306a36Sopenharmony_ci ptr += sizeof(*tlv); 378862306a36Sopenharmony_ci ptr += sizeof(*bitmap); 378962306a36Sopenharmony_ci 379062306a36Sopenharmony_ci /* ipv4 sync */ 379162306a36Sopenharmony_ci tlv = ptr; 379262306a36Sopenharmony_ci tlv->tag = __cpu_to_le16(WMI_TLV_TAG_ARRAY_STRUCT); 379362306a36Sopenharmony_ci tlv->len = __cpu_to_le16(0); 379462306a36Sopenharmony_ci 379562306a36Sopenharmony_ci ptr += sizeof(*tlv); 379662306a36Sopenharmony_ci 379762306a36Sopenharmony_ci /* ipv6 sync */ 379862306a36Sopenharmony_ci tlv = ptr; 379962306a36Sopenharmony_ci tlv->tag = __cpu_to_le16(WMI_TLV_TAG_ARRAY_STRUCT); 380062306a36Sopenharmony_ci tlv->len = __cpu_to_le16(0); 380162306a36Sopenharmony_ci 380262306a36Sopenharmony_ci ptr += sizeof(*tlv); 380362306a36Sopenharmony_ci 380462306a36Sopenharmony_ci /* magic */ 380562306a36Sopenharmony_ci tlv = ptr; 380662306a36Sopenharmony_ci tlv->tag = __cpu_to_le16(WMI_TLV_TAG_ARRAY_STRUCT); 380762306a36Sopenharmony_ci tlv->len = __cpu_to_le16(0); 380862306a36Sopenharmony_ci 380962306a36Sopenharmony_ci ptr += sizeof(*tlv); 381062306a36Sopenharmony_ci 381162306a36Sopenharmony_ci /* pattern info timeout */ 381262306a36Sopenharmony_ci tlv = ptr; 381362306a36Sopenharmony_ci tlv->tag = __cpu_to_le16(WMI_TLV_TAG_ARRAY_UINT32); 381462306a36Sopenharmony_ci tlv->len = __cpu_to_le16(0); 381562306a36Sopenharmony_ci 381662306a36Sopenharmony_ci ptr += sizeof(*tlv); 381762306a36Sopenharmony_ci 381862306a36Sopenharmony_ci /* ratelimit interval */ 381962306a36Sopenharmony_ci tlv = ptr; 382062306a36Sopenharmony_ci tlv->tag = __cpu_to_le16(WMI_TLV_TAG_ARRAY_UINT32); 382162306a36Sopenharmony_ci tlv->len = __cpu_to_le16(sizeof(u32)); 382262306a36Sopenharmony_ci 382362306a36Sopenharmony_ci ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv wow add pattern vdev_id %d pattern_id %d, pattern_offset %d\n", 382462306a36Sopenharmony_ci vdev_id, pattern_id, pattern_offset); 382562306a36Sopenharmony_ci return skb; 382662306a36Sopenharmony_ci} 382762306a36Sopenharmony_ci 382862306a36Sopenharmony_cistatic struct sk_buff * 382962306a36Sopenharmony_ciath10k_wmi_tlv_op_gen_wow_del_pattern(struct ath10k *ar, u32 vdev_id, 383062306a36Sopenharmony_ci u32 pattern_id) 383162306a36Sopenharmony_ci{ 383262306a36Sopenharmony_ci struct wmi_tlv_wow_del_pattern_cmd *cmd; 383362306a36Sopenharmony_ci struct wmi_tlv *tlv; 383462306a36Sopenharmony_ci struct sk_buff *skb; 383562306a36Sopenharmony_ci size_t len; 383662306a36Sopenharmony_ci 383762306a36Sopenharmony_ci len = sizeof(*tlv) + sizeof(*cmd); 383862306a36Sopenharmony_ci skb = ath10k_wmi_alloc_skb(ar, len); 383962306a36Sopenharmony_ci if (!skb) 384062306a36Sopenharmony_ci return ERR_PTR(-ENOMEM); 384162306a36Sopenharmony_ci 384262306a36Sopenharmony_ci tlv = (struct wmi_tlv *)skb->data; 384362306a36Sopenharmony_ci tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_WOW_DEL_PATTERN_CMD); 384462306a36Sopenharmony_ci tlv->len = __cpu_to_le16(sizeof(*cmd)); 384562306a36Sopenharmony_ci cmd = (void *)tlv->value; 384662306a36Sopenharmony_ci 384762306a36Sopenharmony_ci cmd->vdev_id = __cpu_to_le32(vdev_id); 384862306a36Sopenharmony_ci cmd->pattern_id = __cpu_to_le32(pattern_id); 384962306a36Sopenharmony_ci cmd->pattern_type = __cpu_to_le32(WOW_BITMAP_PATTERN); 385062306a36Sopenharmony_ci 385162306a36Sopenharmony_ci ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv wow del pattern vdev_id %d pattern_id %d\n", 385262306a36Sopenharmony_ci vdev_id, pattern_id); 385362306a36Sopenharmony_ci return skb; 385462306a36Sopenharmony_ci} 385562306a36Sopenharmony_ci 385662306a36Sopenharmony_ci/* Request FW to start PNO operation */ 385762306a36Sopenharmony_cistatic struct sk_buff * 385862306a36Sopenharmony_ciath10k_wmi_tlv_op_gen_config_pno_start(struct ath10k *ar, 385962306a36Sopenharmony_ci u32 vdev_id, 386062306a36Sopenharmony_ci struct wmi_pno_scan_req *pno) 386162306a36Sopenharmony_ci{ 386262306a36Sopenharmony_ci struct nlo_configured_parameters *nlo_list; 386362306a36Sopenharmony_ci struct wmi_tlv_wow_nlo_config_cmd *cmd; 386462306a36Sopenharmony_ci struct wmi_tlv *tlv; 386562306a36Sopenharmony_ci struct sk_buff *skb; 386662306a36Sopenharmony_ci __le32 *channel_list; 386762306a36Sopenharmony_ci u16 tlv_len; 386862306a36Sopenharmony_ci size_t len; 386962306a36Sopenharmony_ci void *ptr; 387062306a36Sopenharmony_ci u32 i; 387162306a36Sopenharmony_ci 387262306a36Sopenharmony_ci len = sizeof(*tlv) + sizeof(*cmd) + 387362306a36Sopenharmony_ci sizeof(*tlv) + 387462306a36Sopenharmony_ci /* TLV place holder for array of structures 387562306a36Sopenharmony_ci * nlo_configured_parameters(nlo_list) 387662306a36Sopenharmony_ci */ 387762306a36Sopenharmony_ci sizeof(*tlv); 387862306a36Sopenharmony_ci /* TLV place holder for array of uint32 channel_list */ 387962306a36Sopenharmony_ci 388062306a36Sopenharmony_ci len += sizeof(u32) * min_t(u8, pno->a_networks[0].channel_count, 388162306a36Sopenharmony_ci WMI_NLO_MAX_CHAN); 388262306a36Sopenharmony_ci len += sizeof(struct nlo_configured_parameters) * 388362306a36Sopenharmony_ci min_t(u8, pno->uc_networks_count, WMI_NLO_MAX_SSIDS); 388462306a36Sopenharmony_ci 388562306a36Sopenharmony_ci skb = ath10k_wmi_alloc_skb(ar, len); 388662306a36Sopenharmony_ci if (!skb) 388762306a36Sopenharmony_ci return ERR_PTR(-ENOMEM); 388862306a36Sopenharmony_ci 388962306a36Sopenharmony_ci ptr = (void *)skb->data; 389062306a36Sopenharmony_ci tlv = ptr; 389162306a36Sopenharmony_ci tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_NLO_CONFIG_CMD); 389262306a36Sopenharmony_ci tlv->len = __cpu_to_le16(sizeof(*cmd)); 389362306a36Sopenharmony_ci cmd = (void *)tlv->value; 389462306a36Sopenharmony_ci 389562306a36Sopenharmony_ci /* wmi_tlv_wow_nlo_config_cmd parameters*/ 389662306a36Sopenharmony_ci cmd->vdev_id = __cpu_to_le32(pno->vdev_id); 389762306a36Sopenharmony_ci cmd->flags = __cpu_to_le32(WMI_NLO_CONFIG_START | WMI_NLO_CONFIG_SSID_HIDE_EN); 389862306a36Sopenharmony_ci 389962306a36Sopenharmony_ci /* current FW does not support min-max range for dwell time */ 390062306a36Sopenharmony_ci cmd->active_dwell_time = __cpu_to_le32(pno->active_max_time); 390162306a36Sopenharmony_ci cmd->passive_dwell_time = __cpu_to_le32(pno->passive_max_time); 390262306a36Sopenharmony_ci 390362306a36Sopenharmony_ci if (pno->do_passive_scan) 390462306a36Sopenharmony_ci cmd->flags |= __cpu_to_le32(WMI_NLO_CONFIG_SCAN_PASSIVE); 390562306a36Sopenharmony_ci 390662306a36Sopenharmony_ci /* copy scan interval */ 390762306a36Sopenharmony_ci cmd->fast_scan_period = __cpu_to_le32(pno->fast_scan_period); 390862306a36Sopenharmony_ci cmd->slow_scan_period = __cpu_to_le32(pno->slow_scan_period); 390962306a36Sopenharmony_ci cmd->fast_scan_max_cycles = __cpu_to_le32(pno->fast_scan_max_cycles); 391062306a36Sopenharmony_ci cmd->delay_start_time = __cpu_to_le32(pno->delay_start_time); 391162306a36Sopenharmony_ci 391262306a36Sopenharmony_ci if (pno->enable_pno_scan_randomization) { 391362306a36Sopenharmony_ci cmd->flags |= __cpu_to_le32(WMI_NLO_CONFIG_SPOOFED_MAC_IN_PROBE_REQ | 391462306a36Sopenharmony_ci WMI_NLO_CONFIG_RANDOM_SEQ_NO_IN_PROBE_REQ); 391562306a36Sopenharmony_ci ether_addr_copy(cmd->mac_addr.addr, pno->mac_addr); 391662306a36Sopenharmony_ci ether_addr_copy(cmd->mac_mask.addr, pno->mac_addr_mask); 391762306a36Sopenharmony_ci } 391862306a36Sopenharmony_ci 391962306a36Sopenharmony_ci ptr += sizeof(*tlv); 392062306a36Sopenharmony_ci ptr += sizeof(*cmd); 392162306a36Sopenharmony_ci 392262306a36Sopenharmony_ci /* nlo_configured_parameters(nlo_list) */ 392362306a36Sopenharmony_ci cmd->no_of_ssids = __cpu_to_le32(min_t(u8, pno->uc_networks_count, 392462306a36Sopenharmony_ci WMI_NLO_MAX_SSIDS)); 392562306a36Sopenharmony_ci tlv_len = __le32_to_cpu(cmd->no_of_ssids) * 392662306a36Sopenharmony_ci sizeof(struct nlo_configured_parameters); 392762306a36Sopenharmony_ci 392862306a36Sopenharmony_ci tlv = ptr; 392962306a36Sopenharmony_ci tlv->tag = __cpu_to_le16(WMI_TLV_TAG_ARRAY_STRUCT); 393062306a36Sopenharmony_ci tlv->len = __cpu_to_le16(tlv_len); 393162306a36Sopenharmony_ci 393262306a36Sopenharmony_ci ptr += sizeof(*tlv); 393362306a36Sopenharmony_ci nlo_list = ptr; 393462306a36Sopenharmony_ci for (i = 0; i < __le32_to_cpu(cmd->no_of_ssids); i++) { 393562306a36Sopenharmony_ci tlv = (struct wmi_tlv *)(&nlo_list[i].tlv_header); 393662306a36Sopenharmony_ci tlv->tag = __cpu_to_le16(WMI_TLV_TAG_ARRAY_BYTE); 393762306a36Sopenharmony_ci tlv->len = __cpu_to_le16(sizeof(struct nlo_configured_parameters) - 393862306a36Sopenharmony_ci sizeof(*tlv)); 393962306a36Sopenharmony_ci 394062306a36Sopenharmony_ci /* copy ssid and it's length */ 394162306a36Sopenharmony_ci nlo_list[i].ssid.valid = __cpu_to_le32(true); 394262306a36Sopenharmony_ci nlo_list[i].ssid.ssid.ssid_len = pno->a_networks[i].ssid.ssid_len; 394362306a36Sopenharmony_ci memcpy(nlo_list[i].ssid.ssid.ssid, 394462306a36Sopenharmony_ci pno->a_networks[i].ssid.ssid, 394562306a36Sopenharmony_ci __le32_to_cpu(nlo_list[i].ssid.ssid.ssid_len)); 394662306a36Sopenharmony_ci 394762306a36Sopenharmony_ci /* copy rssi threshold */ 394862306a36Sopenharmony_ci if (pno->a_networks[i].rssi_threshold && 394962306a36Sopenharmony_ci pno->a_networks[i].rssi_threshold > -300) { 395062306a36Sopenharmony_ci nlo_list[i].rssi_cond.valid = __cpu_to_le32(true); 395162306a36Sopenharmony_ci nlo_list[i].rssi_cond.rssi = 395262306a36Sopenharmony_ci __cpu_to_le32(pno->a_networks[i].rssi_threshold); 395362306a36Sopenharmony_ci } 395462306a36Sopenharmony_ci 395562306a36Sopenharmony_ci nlo_list[i].bcast_nw_type.valid = __cpu_to_le32(true); 395662306a36Sopenharmony_ci nlo_list[i].bcast_nw_type.bcast_nw_type = 395762306a36Sopenharmony_ci __cpu_to_le32(pno->a_networks[i].bcast_nw_type); 395862306a36Sopenharmony_ci } 395962306a36Sopenharmony_ci 396062306a36Sopenharmony_ci ptr += __le32_to_cpu(cmd->no_of_ssids) * sizeof(struct nlo_configured_parameters); 396162306a36Sopenharmony_ci 396262306a36Sopenharmony_ci /* copy channel info */ 396362306a36Sopenharmony_ci cmd->num_of_channels = __cpu_to_le32(min_t(u8, 396462306a36Sopenharmony_ci pno->a_networks[0].channel_count, 396562306a36Sopenharmony_ci WMI_NLO_MAX_CHAN)); 396662306a36Sopenharmony_ci 396762306a36Sopenharmony_ci tlv = ptr; 396862306a36Sopenharmony_ci tlv->tag = __cpu_to_le16(WMI_TLV_TAG_ARRAY_UINT32); 396962306a36Sopenharmony_ci tlv->len = __cpu_to_le16(__le32_to_cpu(cmd->num_of_channels) * 397062306a36Sopenharmony_ci sizeof(u_int32_t)); 397162306a36Sopenharmony_ci ptr += sizeof(*tlv); 397262306a36Sopenharmony_ci 397362306a36Sopenharmony_ci channel_list = (__le32 *)ptr; 397462306a36Sopenharmony_ci for (i = 0; i < __le32_to_cpu(cmd->num_of_channels); i++) 397562306a36Sopenharmony_ci channel_list[i] = __cpu_to_le32(pno->a_networks[0].channels[i]); 397662306a36Sopenharmony_ci 397762306a36Sopenharmony_ci ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv start pno config vdev_id %d\n", 397862306a36Sopenharmony_ci vdev_id); 397962306a36Sopenharmony_ci 398062306a36Sopenharmony_ci return skb; 398162306a36Sopenharmony_ci} 398262306a36Sopenharmony_ci 398362306a36Sopenharmony_ci/* Request FW to stop ongoing PNO operation */ 398462306a36Sopenharmony_cistatic struct sk_buff *ath10k_wmi_tlv_op_gen_config_pno_stop(struct ath10k *ar, 398562306a36Sopenharmony_ci u32 vdev_id) 398662306a36Sopenharmony_ci{ 398762306a36Sopenharmony_ci struct wmi_tlv_wow_nlo_config_cmd *cmd; 398862306a36Sopenharmony_ci struct wmi_tlv *tlv; 398962306a36Sopenharmony_ci struct sk_buff *skb; 399062306a36Sopenharmony_ci void *ptr; 399162306a36Sopenharmony_ci size_t len; 399262306a36Sopenharmony_ci 399362306a36Sopenharmony_ci len = sizeof(*tlv) + sizeof(*cmd) + 399462306a36Sopenharmony_ci sizeof(*tlv) + 399562306a36Sopenharmony_ci /* TLV place holder for array of structures 399662306a36Sopenharmony_ci * nlo_configured_parameters(nlo_list) 399762306a36Sopenharmony_ci */ 399862306a36Sopenharmony_ci sizeof(*tlv); 399962306a36Sopenharmony_ci /* TLV place holder for array of uint32 channel_list */ 400062306a36Sopenharmony_ci skb = ath10k_wmi_alloc_skb(ar, len); 400162306a36Sopenharmony_ci if (!skb) 400262306a36Sopenharmony_ci return ERR_PTR(-ENOMEM); 400362306a36Sopenharmony_ci 400462306a36Sopenharmony_ci ptr = (void *)skb->data; 400562306a36Sopenharmony_ci tlv = ptr; 400662306a36Sopenharmony_ci tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_NLO_CONFIG_CMD); 400762306a36Sopenharmony_ci tlv->len = __cpu_to_le16(sizeof(*cmd)); 400862306a36Sopenharmony_ci cmd = (void *)tlv->value; 400962306a36Sopenharmony_ci 401062306a36Sopenharmony_ci cmd->vdev_id = __cpu_to_le32(vdev_id); 401162306a36Sopenharmony_ci cmd->flags = __cpu_to_le32(WMI_NLO_CONFIG_STOP); 401262306a36Sopenharmony_ci 401362306a36Sopenharmony_ci ptr += sizeof(*tlv); 401462306a36Sopenharmony_ci ptr += sizeof(*cmd); 401562306a36Sopenharmony_ci 401662306a36Sopenharmony_ci /* nlo_configured_parameters(nlo_list) */ 401762306a36Sopenharmony_ci tlv = ptr; 401862306a36Sopenharmony_ci tlv->tag = __cpu_to_le16(WMI_TLV_TAG_ARRAY_STRUCT); 401962306a36Sopenharmony_ci tlv->len = __cpu_to_le16(0); 402062306a36Sopenharmony_ci 402162306a36Sopenharmony_ci ptr += sizeof(*tlv); 402262306a36Sopenharmony_ci 402362306a36Sopenharmony_ci /* channel list */ 402462306a36Sopenharmony_ci tlv = ptr; 402562306a36Sopenharmony_ci tlv->tag = __cpu_to_le16(WMI_TLV_TAG_ARRAY_UINT32); 402662306a36Sopenharmony_ci tlv->len = __cpu_to_le16(0); 402762306a36Sopenharmony_ci 402862306a36Sopenharmony_ci ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv stop pno config vdev_id %d\n", vdev_id); 402962306a36Sopenharmony_ci return skb; 403062306a36Sopenharmony_ci} 403162306a36Sopenharmony_ci 403262306a36Sopenharmony_cistatic struct sk_buff * 403362306a36Sopenharmony_ciath10k_wmi_tlv_op_gen_config_pno(struct ath10k *ar, u32 vdev_id, 403462306a36Sopenharmony_ci struct wmi_pno_scan_req *pno_scan) 403562306a36Sopenharmony_ci{ 403662306a36Sopenharmony_ci if (pno_scan->enable) 403762306a36Sopenharmony_ci return ath10k_wmi_tlv_op_gen_config_pno_start(ar, vdev_id, pno_scan); 403862306a36Sopenharmony_ci else 403962306a36Sopenharmony_ci return ath10k_wmi_tlv_op_gen_config_pno_stop(ar, vdev_id); 404062306a36Sopenharmony_ci} 404162306a36Sopenharmony_ci 404262306a36Sopenharmony_cistatic struct sk_buff * 404362306a36Sopenharmony_ciath10k_wmi_tlv_op_gen_adaptive_qcs(struct ath10k *ar, bool enable) 404462306a36Sopenharmony_ci{ 404562306a36Sopenharmony_ci struct wmi_tlv_adaptive_qcs *cmd; 404662306a36Sopenharmony_ci struct wmi_tlv *tlv; 404762306a36Sopenharmony_ci struct sk_buff *skb; 404862306a36Sopenharmony_ci void *ptr; 404962306a36Sopenharmony_ci size_t len; 405062306a36Sopenharmony_ci 405162306a36Sopenharmony_ci len = sizeof(*tlv) + sizeof(*cmd); 405262306a36Sopenharmony_ci skb = ath10k_wmi_alloc_skb(ar, len); 405362306a36Sopenharmony_ci if (!skb) 405462306a36Sopenharmony_ci return ERR_PTR(-ENOMEM); 405562306a36Sopenharmony_ci 405662306a36Sopenharmony_ci ptr = (void *)skb->data; 405762306a36Sopenharmony_ci tlv = ptr; 405862306a36Sopenharmony_ci tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_RESMGR_ADAPTIVE_OCS_CMD); 405962306a36Sopenharmony_ci tlv->len = __cpu_to_le16(sizeof(*cmd)); 406062306a36Sopenharmony_ci cmd = (void *)tlv->value; 406162306a36Sopenharmony_ci cmd->enable = __cpu_to_le32(enable ? 1 : 0); 406262306a36Sopenharmony_ci 406362306a36Sopenharmony_ci ptr += sizeof(*tlv); 406462306a36Sopenharmony_ci ptr += sizeof(*cmd); 406562306a36Sopenharmony_ci 406662306a36Sopenharmony_ci ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv adaptive qcs %d\n", enable); 406762306a36Sopenharmony_ci return skb; 406862306a36Sopenharmony_ci} 406962306a36Sopenharmony_ci 407062306a36Sopenharmony_cistatic struct sk_buff * 407162306a36Sopenharmony_ciath10k_wmi_tlv_op_gen_echo(struct ath10k *ar, u32 value) 407262306a36Sopenharmony_ci{ 407362306a36Sopenharmony_ci struct wmi_echo_cmd *cmd; 407462306a36Sopenharmony_ci struct wmi_tlv *tlv; 407562306a36Sopenharmony_ci struct sk_buff *skb; 407662306a36Sopenharmony_ci void *ptr; 407762306a36Sopenharmony_ci size_t len; 407862306a36Sopenharmony_ci 407962306a36Sopenharmony_ci len = sizeof(*tlv) + sizeof(*cmd); 408062306a36Sopenharmony_ci skb = ath10k_wmi_alloc_skb(ar, len); 408162306a36Sopenharmony_ci if (!skb) 408262306a36Sopenharmony_ci return ERR_PTR(-ENOMEM); 408362306a36Sopenharmony_ci 408462306a36Sopenharmony_ci ptr = (void *)skb->data; 408562306a36Sopenharmony_ci tlv = ptr; 408662306a36Sopenharmony_ci tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_ECHO_CMD); 408762306a36Sopenharmony_ci tlv->len = __cpu_to_le16(sizeof(*cmd)); 408862306a36Sopenharmony_ci cmd = (void *)tlv->value; 408962306a36Sopenharmony_ci cmd->value = cpu_to_le32(value); 409062306a36Sopenharmony_ci 409162306a36Sopenharmony_ci ptr += sizeof(*tlv); 409262306a36Sopenharmony_ci ptr += sizeof(*cmd); 409362306a36Sopenharmony_ci 409462306a36Sopenharmony_ci ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv echo value 0x%08x\n", value); 409562306a36Sopenharmony_ci return skb; 409662306a36Sopenharmony_ci} 409762306a36Sopenharmony_ci 409862306a36Sopenharmony_cistatic struct sk_buff * 409962306a36Sopenharmony_ciath10k_wmi_tlv_op_gen_vdev_spectral_conf(struct ath10k *ar, 410062306a36Sopenharmony_ci const struct wmi_vdev_spectral_conf_arg *arg) 410162306a36Sopenharmony_ci{ 410262306a36Sopenharmony_ci struct wmi_vdev_spectral_conf_cmd *cmd; 410362306a36Sopenharmony_ci struct sk_buff *skb; 410462306a36Sopenharmony_ci struct wmi_tlv *tlv; 410562306a36Sopenharmony_ci void *ptr; 410662306a36Sopenharmony_ci size_t len; 410762306a36Sopenharmony_ci 410862306a36Sopenharmony_ci len = sizeof(*tlv) + sizeof(*cmd); 410962306a36Sopenharmony_ci skb = ath10k_wmi_alloc_skb(ar, len); 411062306a36Sopenharmony_ci if (!skb) 411162306a36Sopenharmony_ci return ERR_PTR(-ENOMEM); 411262306a36Sopenharmony_ci 411362306a36Sopenharmony_ci ptr = (void *)skb->data; 411462306a36Sopenharmony_ci tlv = ptr; 411562306a36Sopenharmony_ci tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_VDEV_SPECTRAL_CONFIGURE_CMD); 411662306a36Sopenharmony_ci tlv->len = __cpu_to_le16(sizeof(*cmd)); 411762306a36Sopenharmony_ci cmd = (void *)tlv->value; 411862306a36Sopenharmony_ci cmd->vdev_id = __cpu_to_le32(arg->vdev_id); 411962306a36Sopenharmony_ci cmd->scan_count = __cpu_to_le32(arg->scan_count); 412062306a36Sopenharmony_ci cmd->scan_period = __cpu_to_le32(arg->scan_period); 412162306a36Sopenharmony_ci cmd->scan_priority = __cpu_to_le32(arg->scan_priority); 412262306a36Sopenharmony_ci cmd->scan_fft_size = __cpu_to_le32(arg->scan_fft_size); 412362306a36Sopenharmony_ci cmd->scan_gc_ena = __cpu_to_le32(arg->scan_gc_ena); 412462306a36Sopenharmony_ci cmd->scan_restart_ena = __cpu_to_le32(arg->scan_restart_ena); 412562306a36Sopenharmony_ci cmd->scan_noise_floor_ref = __cpu_to_le32(arg->scan_noise_floor_ref); 412662306a36Sopenharmony_ci cmd->scan_init_delay = __cpu_to_le32(arg->scan_init_delay); 412762306a36Sopenharmony_ci cmd->scan_nb_tone_thr = __cpu_to_le32(arg->scan_nb_tone_thr); 412862306a36Sopenharmony_ci cmd->scan_str_bin_thr = __cpu_to_le32(arg->scan_str_bin_thr); 412962306a36Sopenharmony_ci cmd->scan_wb_rpt_mode = __cpu_to_le32(arg->scan_wb_rpt_mode); 413062306a36Sopenharmony_ci cmd->scan_rssi_rpt_mode = __cpu_to_le32(arg->scan_rssi_rpt_mode); 413162306a36Sopenharmony_ci cmd->scan_rssi_thr = __cpu_to_le32(arg->scan_rssi_thr); 413262306a36Sopenharmony_ci cmd->scan_pwr_format = __cpu_to_le32(arg->scan_pwr_format); 413362306a36Sopenharmony_ci cmd->scan_rpt_mode = __cpu_to_le32(arg->scan_rpt_mode); 413462306a36Sopenharmony_ci cmd->scan_bin_scale = __cpu_to_le32(arg->scan_bin_scale); 413562306a36Sopenharmony_ci cmd->scan_dbm_adj = __cpu_to_le32(arg->scan_dbm_adj); 413662306a36Sopenharmony_ci cmd->scan_chn_mask = __cpu_to_le32(arg->scan_chn_mask); 413762306a36Sopenharmony_ci 413862306a36Sopenharmony_ci return skb; 413962306a36Sopenharmony_ci} 414062306a36Sopenharmony_ci 414162306a36Sopenharmony_cistatic struct sk_buff * 414262306a36Sopenharmony_ciath10k_wmi_tlv_op_gen_vdev_spectral_enable(struct ath10k *ar, u32 vdev_id, 414362306a36Sopenharmony_ci u32 trigger, u32 enable) 414462306a36Sopenharmony_ci{ 414562306a36Sopenharmony_ci struct wmi_vdev_spectral_enable_cmd *cmd; 414662306a36Sopenharmony_ci struct sk_buff *skb; 414762306a36Sopenharmony_ci struct wmi_tlv *tlv; 414862306a36Sopenharmony_ci void *ptr; 414962306a36Sopenharmony_ci size_t len; 415062306a36Sopenharmony_ci 415162306a36Sopenharmony_ci len = sizeof(*tlv) + sizeof(*cmd); 415262306a36Sopenharmony_ci skb = ath10k_wmi_alloc_skb(ar, len); 415362306a36Sopenharmony_ci if (!skb) 415462306a36Sopenharmony_ci return ERR_PTR(-ENOMEM); 415562306a36Sopenharmony_ci 415662306a36Sopenharmony_ci ptr = (void *)skb->data; 415762306a36Sopenharmony_ci tlv = ptr; 415862306a36Sopenharmony_ci tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_VDEV_SPECTRAL_ENABLE_CMD); 415962306a36Sopenharmony_ci tlv->len = __cpu_to_le16(sizeof(*cmd)); 416062306a36Sopenharmony_ci cmd = (void *)tlv->value; 416162306a36Sopenharmony_ci cmd->vdev_id = __cpu_to_le32(vdev_id); 416262306a36Sopenharmony_ci cmd->trigger_cmd = __cpu_to_le32(trigger); 416362306a36Sopenharmony_ci cmd->enable_cmd = __cpu_to_le32(enable); 416462306a36Sopenharmony_ci 416562306a36Sopenharmony_ci return skb; 416662306a36Sopenharmony_ci} 416762306a36Sopenharmony_ci 416862306a36Sopenharmony_ci/****************/ 416962306a36Sopenharmony_ci/* TLV mappings */ 417062306a36Sopenharmony_ci/****************/ 417162306a36Sopenharmony_ci 417262306a36Sopenharmony_cistatic struct wmi_cmd_map wmi_tlv_cmd_map = { 417362306a36Sopenharmony_ci .init_cmdid = WMI_TLV_INIT_CMDID, 417462306a36Sopenharmony_ci .start_scan_cmdid = WMI_TLV_START_SCAN_CMDID, 417562306a36Sopenharmony_ci .stop_scan_cmdid = WMI_TLV_STOP_SCAN_CMDID, 417662306a36Sopenharmony_ci .scan_chan_list_cmdid = WMI_TLV_SCAN_CHAN_LIST_CMDID, 417762306a36Sopenharmony_ci .scan_sch_prio_tbl_cmdid = WMI_TLV_SCAN_SCH_PRIO_TBL_CMDID, 417862306a36Sopenharmony_ci .scan_prob_req_oui_cmdid = WMI_TLV_SCAN_PROB_REQ_OUI_CMDID, 417962306a36Sopenharmony_ci .pdev_set_regdomain_cmdid = WMI_TLV_PDEV_SET_REGDOMAIN_CMDID, 418062306a36Sopenharmony_ci .pdev_set_channel_cmdid = WMI_TLV_PDEV_SET_CHANNEL_CMDID, 418162306a36Sopenharmony_ci .pdev_set_param_cmdid = WMI_TLV_PDEV_SET_PARAM_CMDID, 418262306a36Sopenharmony_ci .pdev_pktlog_enable_cmdid = WMI_TLV_PDEV_PKTLOG_ENABLE_CMDID, 418362306a36Sopenharmony_ci .pdev_pktlog_disable_cmdid = WMI_TLV_PDEV_PKTLOG_DISABLE_CMDID, 418462306a36Sopenharmony_ci .pdev_set_wmm_params_cmdid = WMI_TLV_PDEV_SET_WMM_PARAMS_CMDID, 418562306a36Sopenharmony_ci .pdev_set_ht_cap_ie_cmdid = WMI_TLV_PDEV_SET_HT_CAP_IE_CMDID, 418662306a36Sopenharmony_ci .pdev_set_vht_cap_ie_cmdid = WMI_TLV_PDEV_SET_VHT_CAP_IE_CMDID, 418762306a36Sopenharmony_ci .pdev_set_dscp_tid_map_cmdid = WMI_TLV_PDEV_SET_DSCP_TID_MAP_CMDID, 418862306a36Sopenharmony_ci .pdev_set_quiet_mode_cmdid = WMI_TLV_PDEV_SET_QUIET_MODE_CMDID, 418962306a36Sopenharmony_ci .pdev_green_ap_ps_enable_cmdid = WMI_TLV_PDEV_GREEN_AP_PS_ENABLE_CMDID, 419062306a36Sopenharmony_ci .pdev_get_tpc_config_cmdid = WMI_TLV_PDEV_GET_TPC_CONFIG_CMDID, 419162306a36Sopenharmony_ci .pdev_set_base_macaddr_cmdid = WMI_TLV_PDEV_SET_BASE_MACADDR_CMDID, 419262306a36Sopenharmony_ci .vdev_create_cmdid = WMI_TLV_VDEV_CREATE_CMDID, 419362306a36Sopenharmony_ci .vdev_delete_cmdid = WMI_TLV_VDEV_DELETE_CMDID, 419462306a36Sopenharmony_ci .vdev_start_request_cmdid = WMI_TLV_VDEV_START_REQUEST_CMDID, 419562306a36Sopenharmony_ci .vdev_restart_request_cmdid = WMI_TLV_VDEV_RESTART_REQUEST_CMDID, 419662306a36Sopenharmony_ci .vdev_up_cmdid = WMI_TLV_VDEV_UP_CMDID, 419762306a36Sopenharmony_ci .vdev_stop_cmdid = WMI_TLV_VDEV_STOP_CMDID, 419862306a36Sopenharmony_ci .vdev_down_cmdid = WMI_TLV_VDEV_DOWN_CMDID, 419962306a36Sopenharmony_ci .vdev_set_param_cmdid = WMI_TLV_VDEV_SET_PARAM_CMDID, 420062306a36Sopenharmony_ci .vdev_install_key_cmdid = WMI_TLV_VDEV_INSTALL_KEY_CMDID, 420162306a36Sopenharmony_ci .peer_create_cmdid = WMI_TLV_PEER_CREATE_CMDID, 420262306a36Sopenharmony_ci .peer_delete_cmdid = WMI_TLV_PEER_DELETE_CMDID, 420362306a36Sopenharmony_ci .peer_flush_tids_cmdid = WMI_TLV_PEER_FLUSH_TIDS_CMDID, 420462306a36Sopenharmony_ci .peer_set_param_cmdid = WMI_TLV_PEER_SET_PARAM_CMDID, 420562306a36Sopenharmony_ci .peer_assoc_cmdid = WMI_TLV_PEER_ASSOC_CMDID, 420662306a36Sopenharmony_ci .peer_add_wds_entry_cmdid = WMI_TLV_PEER_ADD_WDS_ENTRY_CMDID, 420762306a36Sopenharmony_ci .peer_remove_wds_entry_cmdid = WMI_TLV_PEER_REMOVE_WDS_ENTRY_CMDID, 420862306a36Sopenharmony_ci .peer_mcast_group_cmdid = WMI_TLV_PEER_MCAST_GROUP_CMDID, 420962306a36Sopenharmony_ci .bcn_tx_cmdid = WMI_TLV_BCN_TX_CMDID, 421062306a36Sopenharmony_ci .pdev_send_bcn_cmdid = WMI_TLV_PDEV_SEND_BCN_CMDID, 421162306a36Sopenharmony_ci .bcn_tmpl_cmdid = WMI_TLV_BCN_TMPL_CMDID, 421262306a36Sopenharmony_ci .bcn_filter_rx_cmdid = WMI_TLV_BCN_FILTER_RX_CMDID, 421362306a36Sopenharmony_ci .prb_req_filter_rx_cmdid = WMI_TLV_PRB_REQ_FILTER_RX_CMDID, 421462306a36Sopenharmony_ci .mgmt_tx_cmdid = WMI_TLV_MGMT_TX_CMDID, 421562306a36Sopenharmony_ci .mgmt_tx_send_cmdid = WMI_TLV_MGMT_TX_SEND_CMD, 421662306a36Sopenharmony_ci .prb_tmpl_cmdid = WMI_TLV_PRB_TMPL_CMDID, 421762306a36Sopenharmony_ci .addba_clear_resp_cmdid = WMI_TLV_ADDBA_CLEAR_RESP_CMDID, 421862306a36Sopenharmony_ci .addba_send_cmdid = WMI_TLV_ADDBA_SEND_CMDID, 421962306a36Sopenharmony_ci .addba_status_cmdid = WMI_TLV_ADDBA_STATUS_CMDID, 422062306a36Sopenharmony_ci .delba_send_cmdid = WMI_TLV_DELBA_SEND_CMDID, 422162306a36Sopenharmony_ci .addba_set_resp_cmdid = WMI_TLV_ADDBA_SET_RESP_CMDID, 422262306a36Sopenharmony_ci .send_singleamsdu_cmdid = WMI_TLV_SEND_SINGLEAMSDU_CMDID, 422362306a36Sopenharmony_ci .sta_powersave_mode_cmdid = WMI_TLV_STA_POWERSAVE_MODE_CMDID, 422462306a36Sopenharmony_ci .sta_powersave_param_cmdid = WMI_TLV_STA_POWERSAVE_PARAM_CMDID, 422562306a36Sopenharmony_ci .sta_mimo_ps_mode_cmdid = WMI_TLV_STA_MIMO_PS_MODE_CMDID, 422662306a36Sopenharmony_ci .pdev_dfs_enable_cmdid = WMI_TLV_PDEV_DFS_ENABLE_CMDID, 422762306a36Sopenharmony_ci .pdev_dfs_disable_cmdid = WMI_TLV_PDEV_DFS_DISABLE_CMDID, 422862306a36Sopenharmony_ci .roam_scan_mode = WMI_TLV_ROAM_SCAN_MODE, 422962306a36Sopenharmony_ci .roam_scan_rssi_threshold = WMI_TLV_ROAM_SCAN_RSSI_THRESHOLD, 423062306a36Sopenharmony_ci .roam_scan_period = WMI_TLV_ROAM_SCAN_PERIOD, 423162306a36Sopenharmony_ci .roam_scan_rssi_change_threshold = 423262306a36Sopenharmony_ci WMI_TLV_ROAM_SCAN_RSSI_CHANGE_THRESHOLD, 423362306a36Sopenharmony_ci .roam_ap_profile = WMI_TLV_ROAM_AP_PROFILE, 423462306a36Sopenharmony_ci .ofl_scan_add_ap_profile = WMI_TLV_ROAM_AP_PROFILE, 423562306a36Sopenharmony_ci .ofl_scan_remove_ap_profile = WMI_TLV_OFL_SCAN_REMOVE_AP_PROFILE, 423662306a36Sopenharmony_ci .ofl_scan_period = WMI_TLV_OFL_SCAN_PERIOD, 423762306a36Sopenharmony_ci .p2p_dev_set_device_info = WMI_TLV_P2P_DEV_SET_DEVICE_INFO, 423862306a36Sopenharmony_ci .p2p_dev_set_discoverability = WMI_TLV_P2P_DEV_SET_DISCOVERABILITY, 423962306a36Sopenharmony_ci .p2p_go_set_beacon_ie = WMI_TLV_P2P_GO_SET_BEACON_IE, 424062306a36Sopenharmony_ci .p2p_go_set_probe_resp_ie = WMI_TLV_P2P_GO_SET_PROBE_RESP_IE, 424162306a36Sopenharmony_ci .p2p_set_vendor_ie_data_cmdid = WMI_TLV_P2P_SET_VENDOR_IE_DATA_CMDID, 424262306a36Sopenharmony_ci .ap_ps_peer_param_cmdid = WMI_TLV_AP_PS_PEER_PARAM_CMDID, 424362306a36Sopenharmony_ci .ap_ps_peer_uapsd_coex_cmdid = WMI_TLV_AP_PS_PEER_UAPSD_COEX_CMDID, 424462306a36Sopenharmony_ci .peer_rate_retry_sched_cmdid = WMI_TLV_PEER_RATE_RETRY_SCHED_CMDID, 424562306a36Sopenharmony_ci .wlan_profile_trigger_cmdid = WMI_TLV_WLAN_PROFILE_TRIGGER_CMDID, 424662306a36Sopenharmony_ci .wlan_profile_set_hist_intvl_cmdid = 424762306a36Sopenharmony_ci WMI_TLV_WLAN_PROFILE_SET_HIST_INTVL_CMDID, 424862306a36Sopenharmony_ci .wlan_profile_get_profile_data_cmdid = 424962306a36Sopenharmony_ci WMI_TLV_WLAN_PROFILE_GET_PROFILE_DATA_CMDID, 425062306a36Sopenharmony_ci .wlan_profile_enable_profile_id_cmdid = 425162306a36Sopenharmony_ci WMI_TLV_WLAN_PROFILE_ENABLE_PROFILE_ID_CMDID, 425262306a36Sopenharmony_ci .wlan_profile_list_profile_id_cmdid = 425362306a36Sopenharmony_ci WMI_TLV_WLAN_PROFILE_LIST_PROFILE_ID_CMDID, 425462306a36Sopenharmony_ci .pdev_suspend_cmdid = WMI_TLV_PDEV_SUSPEND_CMDID, 425562306a36Sopenharmony_ci .pdev_resume_cmdid = WMI_TLV_PDEV_RESUME_CMDID, 425662306a36Sopenharmony_ci .add_bcn_filter_cmdid = WMI_TLV_ADD_BCN_FILTER_CMDID, 425762306a36Sopenharmony_ci .rmv_bcn_filter_cmdid = WMI_TLV_RMV_BCN_FILTER_CMDID, 425862306a36Sopenharmony_ci .wow_add_wake_pattern_cmdid = WMI_TLV_WOW_ADD_WAKE_PATTERN_CMDID, 425962306a36Sopenharmony_ci .wow_del_wake_pattern_cmdid = WMI_TLV_WOW_DEL_WAKE_PATTERN_CMDID, 426062306a36Sopenharmony_ci .wow_enable_disable_wake_event_cmdid = 426162306a36Sopenharmony_ci WMI_TLV_WOW_ENABLE_DISABLE_WAKE_EVENT_CMDID, 426262306a36Sopenharmony_ci .wow_enable_cmdid = WMI_TLV_WOW_ENABLE_CMDID, 426362306a36Sopenharmony_ci .wow_hostwakeup_from_sleep_cmdid = 426462306a36Sopenharmony_ci WMI_TLV_WOW_HOSTWAKEUP_FROM_SLEEP_CMDID, 426562306a36Sopenharmony_ci .rtt_measreq_cmdid = WMI_TLV_RTT_MEASREQ_CMDID, 426662306a36Sopenharmony_ci .rtt_tsf_cmdid = WMI_TLV_RTT_TSF_CMDID, 426762306a36Sopenharmony_ci .vdev_spectral_scan_configure_cmdid = WMI_TLV_SPECTRAL_SCAN_CONF_CMDID, 426862306a36Sopenharmony_ci .vdev_spectral_scan_enable_cmdid = WMI_TLV_SPECTRAL_SCAN_ENABLE_CMDID, 426962306a36Sopenharmony_ci .request_stats_cmdid = WMI_TLV_REQUEST_STATS_CMDID, 427062306a36Sopenharmony_ci .request_peer_stats_info_cmdid = WMI_TLV_REQUEST_PEER_STATS_INFO_CMDID, 427162306a36Sopenharmony_ci .set_arp_ns_offload_cmdid = WMI_TLV_SET_ARP_NS_OFFLOAD_CMDID, 427262306a36Sopenharmony_ci .network_list_offload_config_cmdid = 427362306a36Sopenharmony_ci WMI_TLV_NETWORK_LIST_OFFLOAD_CONFIG_CMDID, 427462306a36Sopenharmony_ci .gtk_offload_cmdid = WMI_TLV_GTK_OFFLOAD_CMDID, 427562306a36Sopenharmony_ci .csa_offload_enable_cmdid = WMI_TLV_CSA_OFFLOAD_ENABLE_CMDID, 427662306a36Sopenharmony_ci .csa_offload_chanswitch_cmdid = WMI_TLV_CSA_OFFLOAD_CHANSWITCH_CMDID, 427762306a36Sopenharmony_ci .chatter_set_mode_cmdid = WMI_TLV_CHATTER_SET_MODE_CMDID, 427862306a36Sopenharmony_ci .peer_tid_addba_cmdid = WMI_TLV_PEER_TID_ADDBA_CMDID, 427962306a36Sopenharmony_ci .peer_tid_delba_cmdid = WMI_TLV_PEER_TID_DELBA_CMDID, 428062306a36Sopenharmony_ci .sta_dtim_ps_method_cmdid = WMI_TLV_STA_DTIM_PS_METHOD_CMDID, 428162306a36Sopenharmony_ci .sta_uapsd_auto_trig_cmdid = WMI_TLV_STA_UAPSD_AUTO_TRIG_CMDID, 428262306a36Sopenharmony_ci .sta_keepalive_cmd = WMI_TLV_STA_KEEPALIVE_CMDID, 428362306a36Sopenharmony_ci .echo_cmdid = WMI_TLV_ECHO_CMDID, 428462306a36Sopenharmony_ci .pdev_utf_cmdid = WMI_TLV_PDEV_UTF_CMDID, 428562306a36Sopenharmony_ci .dbglog_cfg_cmdid = WMI_TLV_DBGLOG_CFG_CMDID, 428662306a36Sopenharmony_ci .pdev_qvit_cmdid = WMI_TLV_PDEV_QVIT_CMDID, 428762306a36Sopenharmony_ci .pdev_ftm_intg_cmdid = WMI_TLV_PDEV_FTM_INTG_CMDID, 428862306a36Sopenharmony_ci .vdev_set_keepalive_cmdid = WMI_TLV_VDEV_SET_KEEPALIVE_CMDID, 428962306a36Sopenharmony_ci .vdev_get_keepalive_cmdid = WMI_TLV_VDEV_GET_KEEPALIVE_CMDID, 429062306a36Sopenharmony_ci .force_fw_hang_cmdid = WMI_TLV_FORCE_FW_HANG_CMDID, 429162306a36Sopenharmony_ci .gpio_config_cmdid = WMI_TLV_GPIO_CONFIG_CMDID, 429262306a36Sopenharmony_ci .gpio_output_cmdid = WMI_TLV_GPIO_OUTPUT_CMDID, 429362306a36Sopenharmony_ci .pdev_get_temperature_cmdid = WMI_TLV_PDEV_GET_TEMPERATURE_CMDID, 429462306a36Sopenharmony_ci .vdev_set_wmm_params_cmdid = WMI_TLV_VDEV_SET_WMM_PARAMS_CMDID, 429562306a36Sopenharmony_ci .tdls_set_state_cmdid = WMI_TLV_TDLS_SET_STATE_CMDID, 429662306a36Sopenharmony_ci .tdls_peer_update_cmdid = WMI_TLV_TDLS_PEER_UPDATE_CMDID, 429762306a36Sopenharmony_ci .adaptive_qcs_cmdid = WMI_TLV_RESMGR_ADAPTIVE_OCS_CMDID, 429862306a36Sopenharmony_ci .scan_update_request_cmdid = WMI_CMD_UNSUPPORTED, 429962306a36Sopenharmony_ci .vdev_standby_response_cmdid = WMI_CMD_UNSUPPORTED, 430062306a36Sopenharmony_ci .vdev_resume_response_cmdid = WMI_CMD_UNSUPPORTED, 430162306a36Sopenharmony_ci .wlan_peer_caching_add_peer_cmdid = WMI_CMD_UNSUPPORTED, 430262306a36Sopenharmony_ci .wlan_peer_caching_evict_peer_cmdid = WMI_CMD_UNSUPPORTED, 430362306a36Sopenharmony_ci .wlan_peer_caching_restore_peer_cmdid = WMI_CMD_UNSUPPORTED, 430462306a36Sopenharmony_ci .wlan_peer_caching_print_all_peers_info_cmdid = WMI_CMD_UNSUPPORTED, 430562306a36Sopenharmony_ci .peer_update_wds_entry_cmdid = WMI_CMD_UNSUPPORTED, 430662306a36Sopenharmony_ci .peer_add_proxy_sta_entry_cmdid = WMI_CMD_UNSUPPORTED, 430762306a36Sopenharmony_ci .rtt_keepalive_cmdid = WMI_CMD_UNSUPPORTED, 430862306a36Sopenharmony_ci .oem_req_cmdid = WMI_CMD_UNSUPPORTED, 430962306a36Sopenharmony_ci .nan_cmdid = WMI_CMD_UNSUPPORTED, 431062306a36Sopenharmony_ci .vdev_ratemask_cmdid = WMI_CMD_UNSUPPORTED, 431162306a36Sopenharmony_ci .qboost_cfg_cmdid = WMI_CMD_UNSUPPORTED, 431262306a36Sopenharmony_ci .pdev_smart_ant_enable_cmdid = WMI_CMD_UNSUPPORTED, 431362306a36Sopenharmony_ci .pdev_smart_ant_set_rx_antenna_cmdid = WMI_CMD_UNSUPPORTED, 431462306a36Sopenharmony_ci .peer_smart_ant_set_tx_antenna_cmdid = WMI_CMD_UNSUPPORTED, 431562306a36Sopenharmony_ci .peer_smart_ant_set_train_info_cmdid = WMI_CMD_UNSUPPORTED, 431662306a36Sopenharmony_ci .peer_smart_ant_set_node_config_ops_cmdid = WMI_CMD_UNSUPPORTED, 431762306a36Sopenharmony_ci .pdev_set_antenna_switch_table_cmdid = WMI_CMD_UNSUPPORTED, 431862306a36Sopenharmony_ci .pdev_set_ctl_table_cmdid = WMI_CMD_UNSUPPORTED, 431962306a36Sopenharmony_ci .pdev_set_mimogain_table_cmdid = WMI_CMD_UNSUPPORTED, 432062306a36Sopenharmony_ci .pdev_ratepwr_table_cmdid = WMI_CMD_UNSUPPORTED, 432162306a36Sopenharmony_ci .pdev_ratepwr_chainmsk_table_cmdid = WMI_CMD_UNSUPPORTED, 432262306a36Sopenharmony_ci .pdev_fips_cmdid = WMI_CMD_UNSUPPORTED, 432362306a36Sopenharmony_ci .tt_set_conf_cmdid = WMI_CMD_UNSUPPORTED, 432462306a36Sopenharmony_ci .fwtest_cmdid = WMI_CMD_UNSUPPORTED, 432562306a36Sopenharmony_ci .vdev_atf_request_cmdid = WMI_CMD_UNSUPPORTED, 432662306a36Sopenharmony_ci .peer_atf_request_cmdid = WMI_CMD_UNSUPPORTED, 432762306a36Sopenharmony_ci .pdev_get_ani_cck_config_cmdid = WMI_CMD_UNSUPPORTED, 432862306a36Sopenharmony_ci .pdev_get_ani_ofdm_config_cmdid = WMI_CMD_UNSUPPORTED, 432962306a36Sopenharmony_ci .pdev_reserve_ast_entry_cmdid = WMI_CMD_UNSUPPORTED, 433062306a36Sopenharmony_ci}; 433162306a36Sopenharmony_ci 433262306a36Sopenharmony_cistatic struct wmi_pdev_param_map wmi_tlv_pdev_param_map = { 433362306a36Sopenharmony_ci .tx_chain_mask = WMI_TLV_PDEV_PARAM_TX_CHAIN_MASK, 433462306a36Sopenharmony_ci .rx_chain_mask = WMI_TLV_PDEV_PARAM_RX_CHAIN_MASK, 433562306a36Sopenharmony_ci .txpower_limit2g = WMI_TLV_PDEV_PARAM_TXPOWER_LIMIT2G, 433662306a36Sopenharmony_ci .txpower_limit5g = WMI_TLV_PDEV_PARAM_TXPOWER_LIMIT5G, 433762306a36Sopenharmony_ci .txpower_scale = WMI_TLV_PDEV_PARAM_TXPOWER_SCALE, 433862306a36Sopenharmony_ci .beacon_gen_mode = WMI_TLV_PDEV_PARAM_BEACON_GEN_MODE, 433962306a36Sopenharmony_ci .beacon_tx_mode = WMI_TLV_PDEV_PARAM_BEACON_TX_MODE, 434062306a36Sopenharmony_ci .resmgr_offchan_mode = WMI_TLV_PDEV_PARAM_RESMGR_OFFCHAN_MODE, 434162306a36Sopenharmony_ci .protection_mode = WMI_TLV_PDEV_PARAM_PROTECTION_MODE, 434262306a36Sopenharmony_ci .dynamic_bw = WMI_TLV_PDEV_PARAM_DYNAMIC_BW, 434362306a36Sopenharmony_ci .non_agg_sw_retry_th = WMI_TLV_PDEV_PARAM_NON_AGG_SW_RETRY_TH, 434462306a36Sopenharmony_ci .agg_sw_retry_th = WMI_TLV_PDEV_PARAM_AGG_SW_RETRY_TH, 434562306a36Sopenharmony_ci .sta_kickout_th = WMI_TLV_PDEV_PARAM_STA_KICKOUT_TH, 434662306a36Sopenharmony_ci .ac_aggrsize_scaling = WMI_TLV_PDEV_PARAM_AC_AGGRSIZE_SCALING, 434762306a36Sopenharmony_ci .ltr_enable = WMI_TLV_PDEV_PARAM_LTR_ENABLE, 434862306a36Sopenharmony_ci .ltr_ac_latency_be = WMI_TLV_PDEV_PARAM_LTR_AC_LATENCY_BE, 434962306a36Sopenharmony_ci .ltr_ac_latency_bk = WMI_TLV_PDEV_PARAM_LTR_AC_LATENCY_BK, 435062306a36Sopenharmony_ci .ltr_ac_latency_vi = WMI_TLV_PDEV_PARAM_LTR_AC_LATENCY_VI, 435162306a36Sopenharmony_ci .ltr_ac_latency_vo = WMI_TLV_PDEV_PARAM_LTR_AC_LATENCY_VO, 435262306a36Sopenharmony_ci .ltr_ac_latency_timeout = WMI_TLV_PDEV_PARAM_LTR_AC_LATENCY_TIMEOUT, 435362306a36Sopenharmony_ci .ltr_sleep_override = WMI_TLV_PDEV_PARAM_LTR_SLEEP_OVERRIDE, 435462306a36Sopenharmony_ci .ltr_rx_override = WMI_TLV_PDEV_PARAM_LTR_RX_OVERRIDE, 435562306a36Sopenharmony_ci .ltr_tx_activity_timeout = WMI_TLV_PDEV_PARAM_LTR_TX_ACTIVITY_TIMEOUT, 435662306a36Sopenharmony_ci .l1ss_enable = WMI_TLV_PDEV_PARAM_L1SS_ENABLE, 435762306a36Sopenharmony_ci .dsleep_enable = WMI_TLV_PDEV_PARAM_DSLEEP_ENABLE, 435862306a36Sopenharmony_ci .pcielp_txbuf_flush = WMI_TLV_PDEV_PARAM_PCIELP_TXBUF_FLUSH, 435962306a36Sopenharmony_ci .pcielp_txbuf_watermark = WMI_TLV_PDEV_PARAM_PCIELP_TXBUF_TMO_EN, 436062306a36Sopenharmony_ci .pcielp_txbuf_tmo_en = WMI_TLV_PDEV_PARAM_PCIELP_TXBUF_TMO_EN, 436162306a36Sopenharmony_ci .pcielp_txbuf_tmo_value = WMI_TLV_PDEV_PARAM_PCIELP_TXBUF_TMO_VALUE, 436262306a36Sopenharmony_ci .pdev_stats_update_period = WMI_TLV_PDEV_PARAM_PDEV_STATS_UPDATE_PERIOD, 436362306a36Sopenharmony_ci .vdev_stats_update_period = WMI_TLV_PDEV_PARAM_VDEV_STATS_UPDATE_PERIOD, 436462306a36Sopenharmony_ci .peer_stats_update_period = WMI_TLV_PDEV_PARAM_PEER_STATS_UPDATE_PERIOD, 436562306a36Sopenharmony_ci .bcnflt_stats_update_period = 436662306a36Sopenharmony_ci WMI_TLV_PDEV_PARAM_BCNFLT_STATS_UPDATE_PERIOD, 436762306a36Sopenharmony_ci .pmf_qos = WMI_TLV_PDEV_PARAM_PMF_QOS, 436862306a36Sopenharmony_ci .arp_ac_override = WMI_TLV_PDEV_PARAM_ARP_AC_OVERRIDE, 436962306a36Sopenharmony_ci .dcs = WMI_TLV_PDEV_PARAM_DCS, 437062306a36Sopenharmony_ci .ani_enable = WMI_TLV_PDEV_PARAM_ANI_ENABLE, 437162306a36Sopenharmony_ci .ani_poll_period = WMI_TLV_PDEV_PARAM_ANI_POLL_PERIOD, 437262306a36Sopenharmony_ci .ani_listen_period = WMI_TLV_PDEV_PARAM_ANI_LISTEN_PERIOD, 437362306a36Sopenharmony_ci .ani_ofdm_level = WMI_TLV_PDEV_PARAM_ANI_OFDM_LEVEL, 437462306a36Sopenharmony_ci .ani_cck_level = WMI_TLV_PDEV_PARAM_ANI_CCK_LEVEL, 437562306a36Sopenharmony_ci .dyntxchain = WMI_TLV_PDEV_PARAM_DYNTXCHAIN, 437662306a36Sopenharmony_ci .proxy_sta = WMI_TLV_PDEV_PARAM_PROXY_STA, 437762306a36Sopenharmony_ci .idle_ps_config = WMI_TLV_PDEV_PARAM_IDLE_PS_CONFIG, 437862306a36Sopenharmony_ci .power_gating_sleep = WMI_TLV_PDEV_PARAM_POWER_GATING_SLEEP, 437962306a36Sopenharmony_ci .fast_channel_reset = WMI_TLV_PDEV_PARAM_UNSUPPORTED, 438062306a36Sopenharmony_ci .burst_dur = WMI_TLV_PDEV_PARAM_BURST_DUR, 438162306a36Sopenharmony_ci .burst_enable = WMI_TLV_PDEV_PARAM_BURST_ENABLE, 438262306a36Sopenharmony_ci .cal_period = WMI_PDEV_PARAM_UNSUPPORTED, 438362306a36Sopenharmony_ci .aggr_burst = WMI_PDEV_PARAM_UNSUPPORTED, 438462306a36Sopenharmony_ci .rx_decap_mode = WMI_PDEV_PARAM_UNSUPPORTED, 438562306a36Sopenharmony_ci .smart_antenna_default_antenna = WMI_PDEV_PARAM_UNSUPPORTED, 438662306a36Sopenharmony_ci .igmpmld_override = WMI_PDEV_PARAM_UNSUPPORTED, 438762306a36Sopenharmony_ci .igmpmld_tid = WMI_PDEV_PARAM_UNSUPPORTED, 438862306a36Sopenharmony_ci .antenna_gain = WMI_PDEV_PARAM_UNSUPPORTED, 438962306a36Sopenharmony_ci .rx_filter = WMI_PDEV_PARAM_UNSUPPORTED, 439062306a36Sopenharmony_ci .set_mcast_to_ucast_tid = WMI_PDEV_PARAM_UNSUPPORTED, 439162306a36Sopenharmony_ci .proxy_sta_mode = WMI_PDEV_PARAM_UNSUPPORTED, 439262306a36Sopenharmony_ci .set_mcast2ucast_mode = WMI_PDEV_PARAM_UNSUPPORTED, 439362306a36Sopenharmony_ci .set_mcast2ucast_buffer = WMI_PDEV_PARAM_UNSUPPORTED, 439462306a36Sopenharmony_ci .remove_mcast2ucast_buffer = WMI_PDEV_PARAM_UNSUPPORTED, 439562306a36Sopenharmony_ci .peer_sta_ps_statechg_enable = WMI_PDEV_PARAM_UNSUPPORTED, 439662306a36Sopenharmony_ci .igmpmld_ac_override = WMI_PDEV_PARAM_UNSUPPORTED, 439762306a36Sopenharmony_ci .block_interbss = WMI_PDEV_PARAM_UNSUPPORTED, 439862306a36Sopenharmony_ci .set_disable_reset_cmdid = WMI_PDEV_PARAM_UNSUPPORTED, 439962306a36Sopenharmony_ci .set_msdu_ttl_cmdid = WMI_PDEV_PARAM_UNSUPPORTED, 440062306a36Sopenharmony_ci .set_ppdu_duration_cmdid = WMI_PDEV_PARAM_UNSUPPORTED, 440162306a36Sopenharmony_ci .txbf_sound_period_cmdid = WMI_PDEV_PARAM_UNSUPPORTED, 440262306a36Sopenharmony_ci .set_promisc_mode_cmdid = WMI_PDEV_PARAM_UNSUPPORTED, 440362306a36Sopenharmony_ci .set_burst_mode_cmdid = WMI_PDEV_PARAM_UNSUPPORTED, 440462306a36Sopenharmony_ci .en_stats = WMI_PDEV_PARAM_UNSUPPORTED, 440562306a36Sopenharmony_ci .mu_group_policy = WMI_PDEV_PARAM_UNSUPPORTED, 440662306a36Sopenharmony_ci .noise_detection = WMI_PDEV_PARAM_UNSUPPORTED, 440762306a36Sopenharmony_ci .noise_threshold = WMI_PDEV_PARAM_UNSUPPORTED, 440862306a36Sopenharmony_ci .dpd_enable = WMI_PDEV_PARAM_UNSUPPORTED, 440962306a36Sopenharmony_ci .set_mcast_bcast_echo = WMI_PDEV_PARAM_UNSUPPORTED, 441062306a36Sopenharmony_ci .atf_strict_sch = WMI_PDEV_PARAM_UNSUPPORTED, 441162306a36Sopenharmony_ci .atf_sched_duration = WMI_PDEV_PARAM_UNSUPPORTED, 441262306a36Sopenharmony_ci .ant_plzn = WMI_PDEV_PARAM_UNSUPPORTED, 441362306a36Sopenharmony_ci .mgmt_retry_limit = WMI_PDEV_PARAM_UNSUPPORTED, 441462306a36Sopenharmony_ci .sensitivity_level = WMI_PDEV_PARAM_UNSUPPORTED, 441562306a36Sopenharmony_ci .signed_txpower_2g = WMI_PDEV_PARAM_UNSUPPORTED, 441662306a36Sopenharmony_ci .signed_txpower_5g = WMI_PDEV_PARAM_UNSUPPORTED, 441762306a36Sopenharmony_ci .enable_per_tid_amsdu = WMI_PDEV_PARAM_UNSUPPORTED, 441862306a36Sopenharmony_ci .enable_per_tid_ampdu = WMI_PDEV_PARAM_UNSUPPORTED, 441962306a36Sopenharmony_ci .cca_threshold = WMI_PDEV_PARAM_UNSUPPORTED, 442062306a36Sopenharmony_ci .rts_fixed_rate = WMI_PDEV_PARAM_UNSUPPORTED, 442162306a36Sopenharmony_ci .pdev_reset = WMI_PDEV_PARAM_UNSUPPORTED, 442262306a36Sopenharmony_ci .wapi_mbssid_offset = WMI_PDEV_PARAM_UNSUPPORTED, 442362306a36Sopenharmony_ci .arp_srcaddr = WMI_PDEV_PARAM_UNSUPPORTED, 442462306a36Sopenharmony_ci .arp_dstaddr = WMI_PDEV_PARAM_UNSUPPORTED, 442562306a36Sopenharmony_ci .rfkill_config = WMI_TLV_PDEV_PARAM_HW_RFKILL_CONFIG, 442662306a36Sopenharmony_ci .rfkill_enable = WMI_TLV_PDEV_PARAM_RFKILL_ENABLE, 442762306a36Sopenharmony_ci .peer_stats_info_enable = WMI_TLV_PDEV_PARAM_PEER_STATS_INFO_ENABLE, 442862306a36Sopenharmony_ci}; 442962306a36Sopenharmony_ci 443062306a36Sopenharmony_cistatic struct wmi_peer_param_map wmi_tlv_peer_param_map = { 443162306a36Sopenharmony_ci .smps_state = WMI_TLV_PEER_SMPS_STATE, 443262306a36Sopenharmony_ci .ampdu = WMI_TLV_PEER_AMPDU, 443362306a36Sopenharmony_ci .authorize = WMI_TLV_PEER_AUTHORIZE, 443462306a36Sopenharmony_ci .chan_width = WMI_TLV_PEER_CHAN_WIDTH, 443562306a36Sopenharmony_ci .nss = WMI_TLV_PEER_NSS, 443662306a36Sopenharmony_ci .use_4addr = WMI_TLV_PEER_USE_4ADDR, 443762306a36Sopenharmony_ci .membership = WMI_TLV_PEER_MEMBERSHIP, 443862306a36Sopenharmony_ci .user_pos = WMI_TLV_PEER_USERPOS, 443962306a36Sopenharmony_ci .crit_proto_hint_enabled = WMI_TLV_PEER_CRIT_PROTO_HINT_ENABLED, 444062306a36Sopenharmony_ci .tx_fail_cnt_thr = WMI_TLV_PEER_TX_FAIL_CNT_THR, 444162306a36Sopenharmony_ci .set_hw_retry_cts2s = WMI_TLV_PEER_SET_HW_RETRY_CTS2S, 444262306a36Sopenharmony_ci .ibss_atim_win_len = WMI_TLV_PEER_IBSS_ATIM_WINDOW_LENGTH, 444362306a36Sopenharmony_ci .phymode = WMI_TLV_PEER_PHYMODE, 444462306a36Sopenharmony_ci .use_fixed_power = WMI_TLV_PEER_USE_FIXED_PWR, 444562306a36Sopenharmony_ci .dummy_var = WMI_TLV_PEER_DUMMY_VAR, 444662306a36Sopenharmony_ci}; 444762306a36Sopenharmony_ci 444862306a36Sopenharmony_cistatic struct wmi_vdev_param_map wmi_tlv_vdev_param_map = { 444962306a36Sopenharmony_ci .rts_threshold = WMI_TLV_VDEV_PARAM_RTS_THRESHOLD, 445062306a36Sopenharmony_ci .fragmentation_threshold = WMI_TLV_VDEV_PARAM_FRAGMENTATION_THRESHOLD, 445162306a36Sopenharmony_ci .beacon_interval = WMI_TLV_VDEV_PARAM_BEACON_INTERVAL, 445262306a36Sopenharmony_ci .listen_interval = WMI_TLV_VDEV_PARAM_LISTEN_INTERVAL, 445362306a36Sopenharmony_ci .multicast_rate = WMI_TLV_VDEV_PARAM_MULTICAST_RATE, 445462306a36Sopenharmony_ci .mgmt_tx_rate = WMI_TLV_VDEV_PARAM_MGMT_TX_RATE, 445562306a36Sopenharmony_ci .slot_time = WMI_TLV_VDEV_PARAM_SLOT_TIME, 445662306a36Sopenharmony_ci .preamble = WMI_TLV_VDEV_PARAM_PREAMBLE, 445762306a36Sopenharmony_ci .swba_time = WMI_TLV_VDEV_PARAM_SWBA_TIME, 445862306a36Sopenharmony_ci .wmi_vdev_stats_update_period = WMI_TLV_VDEV_STATS_UPDATE_PERIOD, 445962306a36Sopenharmony_ci .wmi_vdev_pwrsave_ageout_time = WMI_TLV_VDEV_PWRSAVE_AGEOUT_TIME, 446062306a36Sopenharmony_ci .wmi_vdev_host_swba_interval = WMI_TLV_VDEV_HOST_SWBA_INTERVAL, 446162306a36Sopenharmony_ci .dtim_period = WMI_TLV_VDEV_PARAM_DTIM_PERIOD, 446262306a36Sopenharmony_ci .wmi_vdev_oc_scheduler_air_time_limit = 446362306a36Sopenharmony_ci WMI_TLV_VDEV_OC_SCHEDULER_AIR_TIME_LIMIT, 446462306a36Sopenharmony_ci .wds = WMI_TLV_VDEV_PARAM_WDS, 446562306a36Sopenharmony_ci .atim_window = WMI_TLV_VDEV_PARAM_ATIM_WINDOW, 446662306a36Sopenharmony_ci .bmiss_count_max = WMI_TLV_VDEV_PARAM_BMISS_COUNT_MAX, 446762306a36Sopenharmony_ci .bmiss_first_bcnt = WMI_TLV_VDEV_PARAM_BMISS_FIRST_BCNT, 446862306a36Sopenharmony_ci .bmiss_final_bcnt = WMI_TLV_VDEV_PARAM_BMISS_FINAL_BCNT, 446962306a36Sopenharmony_ci .feature_wmm = WMI_TLV_VDEV_PARAM_FEATURE_WMM, 447062306a36Sopenharmony_ci .chwidth = WMI_TLV_VDEV_PARAM_CHWIDTH, 447162306a36Sopenharmony_ci .chextoffset = WMI_TLV_VDEV_PARAM_CHEXTOFFSET, 447262306a36Sopenharmony_ci .disable_htprotection = WMI_TLV_VDEV_PARAM_DISABLE_HTPROTECTION, 447362306a36Sopenharmony_ci .sta_quickkickout = WMI_TLV_VDEV_PARAM_STA_QUICKKICKOUT, 447462306a36Sopenharmony_ci .mgmt_rate = WMI_TLV_VDEV_PARAM_MGMT_RATE, 447562306a36Sopenharmony_ci .protection_mode = WMI_TLV_VDEV_PARAM_PROTECTION_MODE, 447662306a36Sopenharmony_ci .fixed_rate = WMI_TLV_VDEV_PARAM_FIXED_RATE, 447762306a36Sopenharmony_ci .sgi = WMI_TLV_VDEV_PARAM_SGI, 447862306a36Sopenharmony_ci .ldpc = WMI_TLV_VDEV_PARAM_LDPC, 447962306a36Sopenharmony_ci .tx_stbc = WMI_TLV_VDEV_PARAM_TX_STBC, 448062306a36Sopenharmony_ci .rx_stbc = WMI_TLV_VDEV_PARAM_RX_STBC, 448162306a36Sopenharmony_ci .intra_bss_fwd = WMI_TLV_VDEV_PARAM_INTRA_BSS_FWD, 448262306a36Sopenharmony_ci .def_keyid = WMI_TLV_VDEV_PARAM_DEF_KEYID, 448362306a36Sopenharmony_ci .nss = WMI_TLV_VDEV_PARAM_NSS, 448462306a36Sopenharmony_ci .bcast_data_rate = WMI_TLV_VDEV_PARAM_BCAST_DATA_RATE, 448562306a36Sopenharmony_ci .mcast_data_rate = WMI_TLV_VDEV_PARAM_MCAST_DATA_RATE, 448662306a36Sopenharmony_ci .mcast_indicate = WMI_TLV_VDEV_PARAM_MCAST_INDICATE, 448762306a36Sopenharmony_ci .dhcp_indicate = WMI_TLV_VDEV_PARAM_DHCP_INDICATE, 448862306a36Sopenharmony_ci .unknown_dest_indicate = WMI_TLV_VDEV_PARAM_UNKNOWN_DEST_INDICATE, 448962306a36Sopenharmony_ci .ap_keepalive_min_idle_inactive_time_secs = 449062306a36Sopenharmony_ci WMI_TLV_VDEV_PARAM_AP_KEEPALIVE_MIN_IDLE_INACTIVE_TIME_SECS, 449162306a36Sopenharmony_ci .ap_keepalive_max_idle_inactive_time_secs = 449262306a36Sopenharmony_ci WMI_TLV_VDEV_PARAM_AP_KEEPALIVE_MAX_IDLE_INACTIVE_TIME_SECS, 449362306a36Sopenharmony_ci .ap_keepalive_max_unresponsive_time_secs = 449462306a36Sopenharmony_ci WMI_TLV_VDEV_PARAM_AP_KEEPALIVE_MAX_UNRESPONSIVE_TIME_SECS, 449562306a36Sopenharmony_ci .ap_enable_nawds = WMI_TLV_VDEV_PARAM_AP_ENABLE_NAWDS, 449662306a36Sopenharmony_ci .mcast2ucast_set = WMI_TLV_VDEV_PARAM_UNSUPPORTED, 449762306a36Sopenharmony_ci .enable_rtscts = WMI_TLV_VDEV_PARAM_ENABLE_RTSCTS, 449862306a36Sopenharmony_ci .txbf = WMI_TLV_VDEV_PARAM_TXBF, 449962306a36Sopenharmony_ci .packet_powersave = WMI_TLV_VDEV_PARAM_PACKET_POWERSAVE, 450062306a36Sopenharmony_ci .drop_unencry = WMI_TLV_VDEV_PARAM_DROP_UNENCRY, 450162306a36Sopenharmony_ci .tx_encap_type = WMI_TLV_VDEV_PARAM_TX_ENCAP_TYPE, 450262306a36Sopenharmony_ci .ap_detect_out_of_sync_sleeping_sta_time_secs = 450362306a36Sopenharmony_ci WMI_TLV_VDEV_PARAM_UNSUPPORTED, 450462306a36Sopenharmony_ci .rc_num_retries = WMI_VDEV_PARAM_UNSUPPORTED, 450562306a36Sopenharmony_ci .cabq_maxdur = WMI_VDEV_PARAM_UNSUPPORTED, 450662306a36Sopenharmony_ci .mfptest_set = WMI_VDEV_PARAM_UNSUPPORTED, 450762306a36Sopenharmony_ci .rts_fixed_rate = WMI_VDEV_PARAM_UNSUPPORTED, 450862306a36Sopenharmony_ci .vht_sgimask = WMI_VDEV_PARAM_UNSUPPORTED, 450962306a36Sopenharmony_ci .vht80_ratemask = WMI_VDEV_PARAM_UNSUPPORTED, 451062306a36Sopenharmony_ci .early_rx_adjust_enable = WMI_VDEV_PARAM_UNSUPPORTED, 451162306a36Sopenharmony_ci .early_rx_tgt_bmiss_num = WMI_VDEV_PARAM_UNSUPPORTED, 451262306a36Sopenharmony_ci .early_rx_bmiss_sample_cycle = WMI_VDEV_PARAM_UNSUPPORTED, 451362306a36Sopenharmony_ci .early_rx_slop_step = WMI_VDEV_PARAM_UNSUPPORTED, 451462306a36Sopenharmony_ci .early_rx_init_slop = WMI_VDEV_PARAM_UNSUPPORTED, 451562306a36Sopenharmony_ci .early_rx_adjust_pause = WMI_VDEV_PARAM_UNSUPPORTED, 451662306a36Sopenharmony_ci .proxy_sta = WMI_VDEV_PARAM_UNSUPPORTED, 451762306a36Sopenharmony_ci .meru_vc = WMI_VDEV_PARAM_UNSUPPORTED, 451862306a36Sopenharmony_ci .rx_decap_type = WMI_VDEV_PARAM_UNSUPPORTED, 451962306a36Sopenharmony_ci .bw_nss_ratemask = WMI_VDEV_PARAM_UNSUPPORTED, 452062306a36Sopenharmony_ci}; 452162306a36Sopenharmony_ci 452262306a36Sopenharmony_cistatic const struct wmi_ops wmi_tlv_ops = { 452362306a36Sopenharmony_ci .rx = ath10k_wmi_tlv_op_rx, 452462306a36Sopenharmony_ci .map_svc = wmi_tlv_svc_map, 452562306a36Sopenharmony_ci .map_svc_ext = wmi_tlv_svc_map_ext, 452662306a36Sopenharmony_ci 452762306a36Sopenharmony_ci .pull_scan = ath10k_wmi_tlv_op_pull_scan_ev, 452862306a36Sopenharmony_ci .pull_mgmt_rx = ath10k_wmi_tlv_op_pull_mgmt_rx_ev, 452962306a36Sopenharmony_ci .pull_mgmt_tx_compl = ath10k_wmi_tlv_op_pull_mgmt_tx_compl_ev, 453062306a36Sopenharmony_ci .pull_mgmt_tx_bundle_compl = ath10k_wmi_tlv_op_pull_mgmt_tx_bundle_compl_ev, 453162306a36Sopenharmony_ci .pull_ch_info = ath10k_wmi_tlv_op_pull_ch_info_ev, 453262306a36Sopenharmony_ci .pull_vdev_start = ath10k_wmi_tlv_op_pull_vdev_start_ev, 453362306a36Sopenharmony_ci .pull_peer_kick = ath10k_wmi_tlv_op_pull_peer_kick_ev, 453462306a36Sopenharmony_ci .pull_swba = ath10k_wmi_tlv_op_pull_swba_ev, 453562306a36Sopenharmony_ci .pull_phyerr_hdr = ath10k_wmi_tlv_op_pull_phyerr_ev_hdr, 453662306a36Sopenharmony_ci .pull_phyerr = ath10k_wmi_op_pull_phyerr_ev, 453762306a36Sopenharmony_ci .pull_svc_rdy = ath10k_wmi_tlv_op_pull_svc_rdy_ev, 453862306a36Sopenharmony_ci .pull_rdy = ath10k_wmi_tlv_op_pull_rdy_ev, 453962306a36Sopenharmony_ci .pull_svc_avail = ath10k_wmi_tlv_op_pull_svc_avail, 454062306a36Sopenharmony_ci .pull_fw_stats = ath10k_wmi_tlv_op_pull_fw_stats, 454162306a36Sopenharmony_ci .pull_roam_ev = ath10k_wmi_tlv_op_pull_roam_ev, 454262306a36Sopenharmony_ci .pull_wow_event = ath10k_wmi_tlv_op_pull_wow_ev, 454362306a36Sopenharmony_ci .pull_echo_ev = ath10k_wmi_tlv_op_pull_echo_ev, 454462306a36Sopenharmony_ci .get_txbf_conf_scheme = ath10k_wmi_tlv_txbf_conf_scheme, 454562306a36Sopenharmony_ci 454662306a36Sopenharmony_ci .gen_pdev_suspend = ath10k_wmi_tlv_op_gen_pdev_suspend, 454762306a36Sopenharmony_ci .gen_pdev_resume = ath10k_wmi_tlv_op_gen_pdev_resume, 454862306a36Sopenharmony_ci .gen_pdev_set_rd = ath10k_wmi_tlv_op_gen_pdev_set_rd, 454962306a36Sopenharmony_ci .gen_pdev_set_param = ath10k_wmi_tlv_op_gen_pdev_set_param, 455062306a36Sopenharmony_ci .gen_init = ath10k_wmi_tlv_op_gen_init, 455162306a36Sopenharmony_ci .gen_start_scan = ath10k_wmi_tlv_op_gen_start_scan, 455262306a36Sopenharmony_ci .gen_stop_scan = ath10k_wmi_tlv_op_gen_stop_scan, 455362306a36Sopenharmony_ci .gen_vdev_create = ath10k_wmi_tlv_op_gen_vdev_create, 455462306a36Sopenharmony_ci .gen_vdev_delete = ath10k_wmi_tlv_op_gen_vdev_delete, 455562306a36Sopenharmony_ci .gen_vdev_start = ath10k_wmi_tlv_op_gen_vdev_start, 455662306a36Sopenharmony_ci .gen_vdev_stop = ath10k_wmi_tlv_op_gen_vdev_stop, 455762306a36Sopenharmony_ci .gen_vdev_up = ath10k_wmi_tlv_op_gen_vdev_up, 455862306a36Sopenharmony_ci .gen_vdev_down = ath10k_wmi_tlv_op_gen_vdev_down, 455962306a36Sopenharmony_ci .gen_vdev_set_param = ath10k_wmi_tlv_op_gen_vdev_set_param, 456062306a36Sopenharmony_ci .gen_vdev_install_key = ath10k_wmi_tlv_op_gen_vdev_install_key, 456162306a36Sopenharmony_ci .gen_vdev_wmm_conf = ath10k_wmi_tlv_op_gen_vdev_wmm_conf, 456262306a36Sopenharmony_ci .gen_peer_create = ath10k_wmi_tlv_op_gen_peer_create, 456362306a36Sopenharmony_ci .gen_peer_delete = ath10k_wmi_tlv_op_gen_peer_delete, 456462306a36Sopenharmony_ci .gen_peer_flush = ath10k_wmi_tlv_op_gen_peer_flush, 456562306a36Sopenharmony_ci .gen_peer_set_param = ath10k_wmi_tlv_op_gen_peer_set_param, 456662306a36Sopenharmony_ci .gen_peer_assoc = ath10k_wmi_tlv_op_gen_peer_assoc, 456762306a36Sopenharmony_ci .gen_set_psmode = ath10k_wmi_tlv_op_gen_set_psmode, 456862306a36Sopenharmony_ci .gen_set_sta_ps = ath10k_wmi_tlv_op_gen_set_sta_ps, 456962306a36Sopenharmony_ci .gen_set_ap_ps = ath10k_wmi_tlv_op_gen_set_ap_ps, 457062306a36Sopenharmony_ci .gen_scan_chan_list = ath10k_wmi_tlv_op_gen_scan_chan_list, 457162306a36Sopenharmony_ci .gen_scan_prob_req_oui = ath10k_wmi_tlv_op_gen_scan_prob_req_oui, 457262306a36Sopenharmony_ci .gen_beacon_dma = ath10k_wmi_tlv_op_gen_beacon_dma, 457362306a36Sopenharmony_ci .gen_pdev_set_wmm = ath10k_wmi_tlv_op_gen_pdev_set_wmm, 457462306a36Sopenharmony_ci .gen_request_stats = ath10k_wmi_tlv_op_gen_request_stats, 457562306a36Sopenharmony_ci .gen_request_peer_stats_info = ath10k_wmi_tlv_op_gen_request_peer_stats_info, 457662306a36Sopenharmony_ci .gen_force_fw_hang = ath10k_wmi_tlv_op_gen_force_fw_hang, 457762306a36Sopenharmony_ci /* .gen_mgmt_tx = not implemented; HTT is used */ 457862306a36Sopenharmony_ci .gen_mgmt_tx_send = ath10k_wmi_tlv_op_gen_mgmt_tx_send, 457962306a36Sopenharmony_ci .cleanup_mgmt_tx_send = ath10k_wmi_tlv_op_cleanup_mgmt_tx_send, 458062306a36Sopenharmony_ci .gen_dbglog_cfg = ath10k_wmi_tlv_op_gen_dbglog_cfg, 458162306a36Sopenharmony_ci .gen_pktlog_enable = ath10k_wmi_tlv_op_gen_pktlog_enable, 458262306a36Sopenharmony_ci .gen_pktlog_disable = ath10k_wmi_tlv_op_gen_pktlog_disable, 458362306a36Sopenharmony_ci .gen_pdev_set_quiet_mode = ath10k_wmi_tlv_op_gen_pdev_set_quiet_mode, 458462306a36Sopenharmony_ci .gen_pdev_get_temperature = ath10k_wmi_tlv_op_gen_pdev_get_temperature, 458562306a36Sopenharmony_ci /* .gen_addba_clear_resp not implemented */ 458662306a36Sopenharmony_ci /* .gen_addba_send not implemented */ 458762306a36Sopenharmony_ci /* .gen_addba_set_resp not implemented */ 458862306a36Sopenharmony_ci /* .gen_delba_send not implemented */ 458962306a36Sopenharmony_ci .gen_bcn_tmpl = ath10k_wmi_tlv_op_gen_bcn_tmpl, 459062306a36Sopenharmony_ci .gen_prb_tmpl = ath10k_wmi_tlv_op_gen_prb_tmpl, 459162306a36Sopenharmony_ci .gen_p2p_go_bcn_ie = ath10k_wmi_tlv_op_gen_p2p_go_bcn_ie, 459262306a36Sopenharmony_ci .gen_vdev_sta_uapsd = ath10k_wmi_tlv_op_gen_vdev_sta_uapsd, 459362306a36Sopenharmony_ci .gen_sta_keepalive = ath10k_wmi_tlv_op_gen_sta_keepalive, 459462306a36Sopenharmony_ci .gen_wow_enable = ath10k_wmi_tlv_op_gen_wow_enable, 459562306a36Sopenharmony_ci .gen_wow_add_wakeup_event = ath10k_wmi_tlv_op_gen_wow_add_wakeup_event, 459662306a36Sopenharmony_ci .gen_wow_host_wakeup_ind = ath10k_wmi_tlv_gen_wow_host_wakeup_ind, 459762306a36Sopenharmony_ci .gen_wow_add_pattern = ath10k_wmi_tlv_op_gen_wow_add_pattern, 459862306a36Sopenharmony_ci .gen_wow_del_pattern = ath10k_wmi_tlv_op_gen_wow_del_pattern, 459962306a36Sopenharmony_ci .gen_wow_config_pno = ath10k_wmi_tlv_op_gen_config_pno, 460062306a36Sopenharmony_ci .gen_update_fw_tdls_state = ath10k_wmi_tlv_op_gen_update_fw_tdls_state, 460162306a36Sopenharmony_ci .gen_tdls_peer_update = ath10k_wmi_tlv_op_gen_tdls_peer_update, 460262306a36Sopenharmony_ci .gen_adaptive_qcs = ath10k_wmi_tlv_op_gen_adaptive_qcs, 460362306a36Sopenharmony_ci .fw_stats_fill = ath10k_wmi_main_op_fw_stats_fill, 460462306a36Sopenharmony_ci .get_vdev_subtype = ath10k_wmi_tlv_op_get_vdev_subtype, 460562306a36Sopenharmony_ci .gen_echo = ath10k_wmi_tlv_op_gen_echo, 460662306a36Sopenharmony_ci .gen_vdev_spectral_conf = ath10k_wmi_tlv_op_gen_vdev_spectral_conf, 460762306a36Sopenharmony_ci .gen_vdev_spectral_enable = ath10k_wmi_tlv_op_gen_vdev_spectral_enable, 460862306a36Sopenharmony_ci}; 460962306a36Sopenharmony_ci 461062306a36Sopenharmony_cistatic const struct wmi_peer_flags_map wmi_tlv_peer_flags_map = { 461162306a36Sopenharmony_ci .auth = WMI_TLV_PEER_AUTH, 461262306a36Sopenharmony_ci .qos = WMI_TLV_PEER_QOS, 461362306a36Sopenharmony_ci .need_ptk_4_way = WMI_TLV_PEER_NEED_PTK_4_WAY, 461462306a36Sopenharmony_ci .need_gtk_2_way = WMI_TLV_PEER_NEED_GTK_2_WAY, 461562306a36Sopenharmony_ci .apsd = WMI_TLV_PEER_APSD, 461662306a36Sopenharmony_ci .ht = WMI_TLV_PEER_HT, 461762306a36Sopenharmony_ci .bw40 = WMI_TLV_PEER_40MHZ, 461862306a36Sopenharmony_ci .stbc = WMI_TLV_PEER_STBC, 461962306a36Sopenharmony_ci .ldbc = WMI_TLV_PEER_LDPC, 462062306a36Sopenharmony_ci .dyn_mimops = WMI_TLV_PEER_DYN_MIMOPS, 462162306a36Sopenharmony_ci .static_mimops = WMI_TLV_PEER_STATIC_MIMOPS, 462262306a36Sopenharmony_ci .spatial_mux = WMI_TLV_PEER_SPATIAL_MUX, 462362306a36Sopenharmony_ci .vht = WMI_TLV_PEER_VHT, 462462306a36Sopenharmony_ci .bw80 = WMI_TLV_PEER_80MHZ, 462562306a36Sopenharmony_ci .pmf = WMI_TLV_PEER_PMF, 462662306a36Sopenharmony_ci .bw160 = WMI_TLV_PEER_160MHZ, 462762306a36Sopenharmony_ci}; 462862306a36Sopenharmony_ci 462962306a36Sopenharmony_ci/************/ 463062306a36Sopenharmony_ci/* TLV init */ 463162306a36Sopenharmony_ci/************/ 463262306a36Sopenharmony_ci 463362306a36Sopenharmony_civoid ath10k_wmi_tlv_attach(struct ath10k *ar) 463462306a36Sopenharmony_ci{ 463562306a36Sopenharmony_ci ar->wmi.cmd = &wmi_tlv_cmd_map; 463662306a36Sopenharmony_ci ar->wmi.vdev_param = &wmi_tlv_vdev_param_map; 463762306a36Sopenharmony_ci ar->wmi.pdev_param = &wmi_tlv_pdev_param_map; 463862306a36Sopenharmony_ci ar->wmi.peer_param = &wmi_tlv_peer_param_map; 463962306a36Sopenharmony_ci ar->wmi.ops = &wmi_tlv_ops; 464062306a36Sopenharmony_ci ar->wmi.peer_flags = &wmi_tlv_peer_flags_map; 464162306a36Sopenharmony_ci} 4642