18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: ISC
28c2ecf20Sopenharmony_ci/*
38c2ecf20Sopenharmony_ci * Copyright (c) 2005-2011 Atheros Communications Inc.
48c2ecf20Sopenharmony_ci * Copyright (c) 2011-2017 Qualcomm Atheros, Inc.
58c2ecf20Sopenharmony_ci * Copyright (c) 2018-2019, The Linux Foundation. All rights reserved.
68c2ecf20Sopenharmony_ci */
78c2ecf20Sopenharmony_ci#include "core.h"
88c2ecf20Sopenharmony_ci#include "debug.h"
98c2ecf20Sopenharmony_ci#include "mac.h"
108c2ecf20Sopenharmony_ci#include "hw.h"
118c2ecf20Sopenharmony_ci#include "wmi.h"
128c2ecf20Sopenharmony_ci#include "wmi-ops.h"
138c2ecf20Sopenharmony_ci#include "wmi-tlv.h"
148c2ecf20Sopenharmony_ci#include "p2p.h"
158c2ecf20Sopenharmony_ci#include "testmode.h"
168c2ecf20Sopenharmony_ci#include <linux/bitfield.h>
178c2ecf20Sopenharmony_ci
188c2ecf20Sopenharmony_ci/***************/
198c2ecf20Sopenharmony_ci/* TLV helpers */
208c2ecf20Sopenharmony_ci/**************/
218c2ecf20Sopenharmony_ci
228c2ecf20Sopenharmony_cistruct wmi_tlv_policy {
238c2ecf20Sopenharmony_ci	size_t min_len;
248c2ecf20Sopenharmony_ci};
258c2ecf20Sopenharmony_ci
268c2ecf20Sopenharmony_cistatic const struct wmi_tlv_policy wmi_tlv_policies[] = {
278c2ecf20Sopenharmony_ci	[WMI_TLV_TAG_ARRAY_BYTE]
288c2ecf20Sopenharmony_ci		= { .min_len = 0 },
298c2ecf20Sopenharmony_ci	[WMI_TLV_TAG_ARRAY_UINT32]
308c2ecf20Sopenharmony_ci		= { .min_len = 0 },
318c2ecf20Sopenharmony_ci	[WMI_TLV_TAG_STRUCT_SCAN_EVENT]
328c2ecf20Sopenharmony_ci		= { .min_len = sizeof(struct wmi_scan_event) },
338c2ecf20Sopenharmony_ci	[WMI_TLV_TAG_STRUCT_MGMT_RX_HDR]
348c2ecf20Sopenharmony_ci		= { .min_len = sizeof(struct wmi_tlv_mgmt_rx_ev) },
358c2ecf20Sopenharmony_ci	[WMI_TLV_TAG_STRUCT_CHAN_INFO_EVENT]
368c2ecf20Sopenharmony_ci		= { .min_len = sizeof(struct wmi_chan_info_event) },
378c2ecf20Sopenharmony_ci	[WMI_TLV_TAG_STRUCT_VDEV_START_RESPONSE_EVENT]
388c2ecf20Sopenharmony_ci		= { .min_len = sizeof(struct wmi_vdev_start_response_event) },
398c2ecf20Sopenharmony_ci	[WMI_TLV_TAG_STRUCT_PEER_STA_KICKOUT_EVENT]
408c2ecf20Sopenharmony_ci		= { .min_len = sizeof(struct wmi_peer_sta_kickout_event) },
418c2ecf20Sopenharmony_ci	[WMI_TLV_TAG_STRUCT_HOST_SWBA_EVENT]
428c2ecf20Sopenharmony_ci		= { .min_len = sizeof(struct wmi_host_swba_event) },
438c2ecf20Sopenharmony_ci	[WMI_TLV_TAG_STRUCT_TIM_INFO]
448c2ecf20Sopenharmony_ci		= { .min_len = sizeof(struct wmi_tim_info) },
458c2ecf20Sopenharmony_ci	[WMI_TLV_TAG_STRUCT_P2P_NOA_INFO]
468c2ecf20Sopenharmony_ci		= { .min_len = sizeof(struct wmi_p2p_noa_info) },
478c2ecf20Sopenharmony_ci	[WMI_TLV_TAG_STRUCT_SERVICE_READY_EVENT]
488c2ecf20Sopenharmony_ci		= { .min_len = sizeof(struct wmi_tlv_svc_rdy_ev) },
498c2ecf20Sopenharmony_ci	[WMI_TLV_TAG_STRUCT_HAL_REG_CAPABILITIES]
508c2ecf20Sopenharmony_ci		= { .min_len = sizeof(struct hal_reg_capabilities) },
518c2ecf20Sopenharmony_ci	[WMI_TLV_TAG_STRUCT_WLAN_HOST_MEM_REQ]
528c2ecf20Sopenharmony_ci		= { .min_len = sizeof(struct wlan_host_mem_req) },
538c2ecf20Sopenharmony_ci	[WMI_TLV_TAG_STRUCT_READY_EVENT]
548c2ecf20Sopenharmony_ci		= { .min_len = sizeof(struct wmi_tlv_rdy_ev) },
558c2ecf20Sopenharmony_ci	[WMI_TLV_TAG_STRUCT_OFFLOAD_BCN_TX_STATUS_EVENT]
568c2ecf20Sopenharmony_ci		= { .min_len = sizeof(struct wmi_tlv_bcn_tx_status_ev) },
578c2ecf20Sopenharmony_ci	[WMI_TLV_TAG_STRUCT_DIAG_DATA_CONTAINER_EVENT]
588c2ecf20Sopenharmony_ci		= { .min_len = sizeof(struct wmi_tlv_diag_data_ev) },
598c2ecf20Sopenharmony_ci	[WMI_TLV_TAG_STRUCT_P2P_NOA_EVENT]
608c2ecf20Sopenharmony_ci		= { .min_len = sizeof(struct wmi_tlv_p2p_noa_ev) },
618c2ecf20Sopenharmony_ci	[WMI_TLV_TAG_STRUCT_ROAM_EVENT]
628c2ecf20Sopenharmony_ci		= { .min_len = sizeof(struct wmi_tlv_roam_ev) },
638c2ecf20Sopenharmony_ci	[WMI_TLV_TAG_STRUCT_WOW_EVENT_INFO]
648c2ecf20Sopenharmony_ci		= { .min_len = sizeof(struct wmi_tlv_wow_event_info) },
658c2ecf20Sopenharmony_ci	[WMI_TLV_TAG_STRUCT_TX_PAUSE_EVENT]
668c2ecf20Sopenharmony_ci		= { .min_len = sizeof(struct wmi_tlv_tx_pause_ev) },
678c2ecf20Sopenharmony_ci};
688c2ecf20Sopenharmony_ci
698c2ecf20Sopenharmony_cistatic int
708c2ecf20Sopenharmony_ciath10k_wmi_tlv_iter(struct ath10k *ar, const void *ptr, size_t len,
718c2ecf20Sopenharmony_ci		    int (*iter)(struct ath10k *ar, u16 tag, u16 len,
728c2ecf20Sopenharmony_ci				const void *ptr, void *data),
738c2ecf20Sopenharmony_ci		    void *data)
748c2ecf20Sopenharmony_ci{
758c2ecf20Sopenharmony_ci	const void *begin = ptr;
768c2ecf20Sopenharmony_ci	const struct wmi_tlv *tlv;
778c2ecf20Sopenharmony_ci	u16 tlv_tag, tlv_len;
788c2ecf20Sopenharmony_ci	int ret;
798c2ecf20Sopenharmony_ci
808c2ecf20Sopenharmony_ci	while (len > 0) {
818c2ecf20Sopenharmony_ci		if (len < sizeof(*tlv)) {
828c2ecf20Sopenharmony_ci			ath10k_dbg(ar, ATH10K_DBG_WMI,
838c2ecf20Sopenharmony_ci				   "wmi tlv parse failure at byte %zd (%zu bytes left, %zu expected)\n",
848c2ecf20Sopenharmony_ci				   ptr - begin, len, sizeof(*tlv));
858c2ecf20Sopenharmony_ci			return -EINVAL;
868c2ecf20Sopenharmony_ci		}
878c2ecf20Sopenharmony_ci
888c2ecf20Sopenharmony_ci		tlv = ptr;
898c2ecf20Sopenharmony_ci		tlv_tag = __le16_to_cpu(tlv->tag);
908c2ecf20Sopenharmony_ci		tlv_len = __le16_to_cpu(tlv->len);
918c2ecf20Sopenharmony_ci		ptr += sizeof(*tlv);
928c2ecf20Sopenharmony_ci		len -= sizeof(*tlv);
938c2ecf20Sopenharmony_ci
948c2ecf20Sopenharmony_ci		if (tlv_len > len) {
958c2ecf20Sopenharmony_ci			ath10k_dbg(ar, ATH10K_DBG_WMI,
968c2ecf20Sopenharmony_ci				   "wmi tlv parse failure of tag %hhu at byte %zd (%zu bytes left, %hhu expected)\n",
978c2ecf20Sopenharmony_ci				   tlv_tag, ptr - begin, len, tlv_len);
988c2ecf20Sopenharmony_ci			return -EINVAL;
998c2ecf20Sopenharmony_ci		}
1008c2ecf20Sopenharmony_ci
1018c2ecf20Sopenharmony_ci		if (tlv_tag < ARRAY_SIZE(wmi_tlv_policies) &&
1028c2ecf20Sopenharmony_ci		    wmi_tlv_policies[tlv_tag].min_len &&
1038c2ecf20Sopenharmony_ci		    wmi_tlv_policies[tlv_tag].min_len > tlv_len) {
1048c2ecf20Sopenharmony_ci			ath10k_dbg(ar, ATH10K_DBG_WMI,
1058c2ecf20Sopenharmony_ci				   "wmi tlv parse failure of tag %hhu at byte %zd (%hhu bytes is less than min length %zu)\n",
1068c2ecf20Sopenharmony_ci				   tlv_tag, ptr - begin, tlv_len,
1078c2ecf20Sopenharmony_ci				   wmi_tlv_policies[tlv_tag].min_len);
1088c2ecf20Sopenharmony_ci			return -EINVAL;
1098c2ecf20Sopenharmony_ci		}
1108c2ecf20Sopenharmony_ci
1118c2ecf20Sopenharmony_ci		ret = iter(ar, tlv_tag, tlv_len, ptr, data);
1128c2ecf20Sopenharmony_ci		if (ret)
1138c2ecf20Sopenharmony_ci			return ret;
1148c2ecf20Sopenharmony_ci
1158c2ecf20Sopenharmony_ci		ptr += tlv_len;
1168c2ecf20Sopenharmony_ci		len -= tlv_len;
1178c2ecf20Sopenharmony_ci	}
1188c2ecf20Sopenharmony_ci
1198c2ecf20Sopenharmony_ci	return 0;
1208c2ecf20Sopenharmony_ci}
1218c2ecf20Sopenharmony_ci
1228c2ecf20Sopenharmony_cistatic int ath10k_wmi_tlv_iter_parse(struct ath10k *ar, u16 tag, u16 len,
1238c2ecf20Sopenharmony_ci				     const void *ptr, void *data)
1248c2ecf20Sopenharmony_ci{
1258c2ecf20Sopenharmony_ci	const void **tb = data;
1268c2ecf20Sopenharmony_ci
1278c2ecf20Sopenharmony_ci	if (tag < WMI_TLV_TAG_MAX)
1288c2ecf20Sopenharmony_ci		tb[tag] = ptr;
1298c2ecf20Sopenharmony_ci
1308c2ecf20Sopenharmony_ci	return 0;
1318c2ecf20Sopenharmony_ci}
1328c2ecf20Sopenharmony_ci
1338c2ecf20Sopenharmony_cistatic int ath10k_wmi_tlv_parse(struct ath10k *ar, const void **tb,
1348c2ecf20Sopenharmony_ci				const void *ptr, size_t len)
1358c2ecf20Sopenharmony_ci{
1368c2ecf20Sopenharmony_ci	return ath10k_wmi_tlv_iter(ar, ptr, len, ath10k_wmi_tlv_iter_parse,
1378c2ecf20Sopenharmony_ci				   (void *)tb);
1388c2ecf20Sopenharmony_ci}
1398c2ecf20Sopenharmony_ci
1408c2ecf20Sopenharmony_cistatic const void **
1418c2ecf20Sopenharmony_ciath10k_wmi_tlv_parse_alloc(struct ath10k *ar, const void *ptr,
1428c2ecf20Sopenharmony_ci			   size_t len, gfp_t gfp)
1438c2ecf20Sopenharmony_ci{
1448c2ecf20Sopenharmony_ci	const void **tb;
1458c2ecf20Sopenharmony_ci	int ret;
1468c2ecf20Sopenharmony_ci
1478c2ecf20Sopenharmony_ci	tb = kcalloc(WMI_TLV_TAG_MAX, sizeof(*tb), gfp);
1488c2ecf20Sopenharmony_ci	if (!tb)
1498c2ecf20Sopenharmony_ci		return ERR_PTR(-ENOMEM);
1508c2ecf20Sopenharmony_ci
1518c2ecf20Sopenharmony_ci	ret = ath10k_wmi_tlv_parse(ar, tb, ptr, len);
1528c2ecf20Sopenharmony_ci	if (ret) {
1538c2ecf20Sopenharmony_ci		kfree(tb);
1548c2ecf20Sopenharmony_ci		return ERR_PTR(ret);
1558c2ecf20Sopenharmony_ci	}
1568c2ecf20Sopenharmony_ci
1578c2ecf20Sopenharmony_ci	return tb;
1588c2ecf20Sopenharmony_ci}
1598c2ecf20Sopenharmony_ci
1608c2ecf20Sopenharmony_cistatic u16 ath10k_wmi_tlv_len(const void *ptr)
1618c2ecf20Sopenharmony_ci{
1628c2ecf20Sopenharmony_ci	return __le16_to_cpu((((const struct wmi_tlv *)ptr) - 1)->len);
1638c2ecf20Sopenharmony_ci}
1648c2ecf20Sopenharmony_ci
1658c2ecf20Sopenharmony_ci/**************/
1668c2ecf20Sopenharmony_ci/* TLV events */
1678c2ecf20Sopenharmony_ci/**************/
1688c2ecf20Sopenharmony_cistatic int ath10k_wmi_tlv_event_bcn_tx_status(struct ath10k *ar,
1698c2ecf20Sopenharmony_ci					      struct sk_buff *skb)
1708c2ecf20Sopenharmony_ci{
1718c2ecf20Sopenharmony_ci	const void **tb;
1728c2ecf20Sopenharmony_ci	const struct wmi_tlv_bcn_tx_status_ev *ev;
1738c2ecf20Sopenharmony_ci	struct ath10k_vif *arvif;
1748c2ecf20Sopenharmony_ci	u32 vdev_id, tx_status;
1758c2ecf20Sopenharmony_ci	int ret;
1768c2ecf20Sopenharmony_ci
1778c2ecf20Sopenharmony_ci	tb = ath10k_wmi_tlv_parse_alloc(ar, skb->data, skb->len, GFP_ATOMIC);
1788c2ecf20Sopenharmony_ci	if (IS_ERR(tb)) {
1798c2ecf20Sopenharmony_ci		ret = PTR_ERR(tb);
1808c2ecf20Sopenharmony_ci		ath10k_warn(ar, "failed to parse tlv: %d\n", ret);
1818c2ecf20Sopenharmony_ci		return ret;
1828c2ecf20Sopenharmony_ci	}
1838c2ecf20Sopenharmony_ci
1848c2ecf20Sopenharmony_ci	ev = tb[WMI_TLV_TAG_STRUCT_OFFLOAD_BCN_TX_STATUS_EVENT];
1858c2ecf20Sopenharmony_ci	if (!ev) {
1868c2ecf20Sopenharmony_ci		kfree(tb);
1878c2ecf20Sopenharmony_ci		return -EPROTO;
1888c2ecf20Sopenharmony_ci	}
1898c2ecf20Sopenharmony_ci
1908c2ecf20Sopenharmony_ci	tx_status = __le32_to_cpu(ev->tx_status);
1918c2ecf20Sopenharmony_ci	vdev_id = __le32_to_cpu(ev->vdev_id);
1928c2ecf20Sopenharmony_ci
1938c2ecf20Sopenharmony_ci	switch (tx_status) {
1948c2ecf20Sopenharmony_ci	case WMI_TLV_BCN_TX_STATUS_OK:
1958c2ecf20Sopenharmony_ci		break;
1968c2ecf20Sopenharmony_ci	case WMI_TLV_BCN_TX_STATUS_XRETRY:
1978c2ecf20Sopenharmony_ci	case WMI_TLV_BCN_TX_STATUS_DROP:
1988c2ecf20Sopenharmony_ci	case WMI_TLV_BCN_TX_STATUS_FILTERED:
1998c2ecf20Sopenharmony_ci		/* FIXME: It's probably worth telling mac80211 to stop the
2008c2ecf20Sopenharmony_ci		 * interface as it is crippled.
2018c2ecf20Sopenharmony_ci		 */
2028c2ecf20Sopenharmony_ci		ath10k_warn(ar, "received bcn tmpl tx status on vdev %i: %d",
2038c2ecf20Sopenharmony_ci			    vdev_id, tx_status);
2048c2ecf20Sopenharmony_ci		break;
2058c2ecf20Sopenharmony_ci	}
2068c2ecf20Sopenharmony_ci
2078c2ecf20Sopenharmony_ci	arvif = ath10k_get_arvif(ar, vdev_id);
2088c2ecf20Sopenharmony_ci	if (arvif && arvif->is_up && arvif->vif->csa_active)
2098c2ecf20Sopenharmony_ci		ieee80211_queue_work(ar->hw, &arvif->ap_csa_work);
2108c2ecf20Sopenharmony_ci
2118c2ecf20Sopenharmony_ci	kfree(tb);
2128c2ecf20Sopenharmony_ci	return 0;
2138c2ecf20Sopenharmony_ci}
2148c2ecf20Sopenharmony_ci
2158c2ecf20Sopenharmony_cistatic void ath10k_wmi_tlv_event_vdev_delete_resp(struct ath10k *ar,
2168c2ecf20Sopenharmony_ci						  struct sk_buff *skb)
2178c2ecf20Sopenharmony_ci{
2188c2ecf20Sopenharmony_ci	ath10k_dbg(ar, ATH10K_DBG_WMI, "WMI_VDEV_DELETE_RESP_EVENTID\n");
2198c2ecf20Sopenharmony_ci	complete(&ar->vdev_delete_done);
2208c2ecf20Sopenharmony_ci}
2218c2ecf20Sopenharmony_ci
2228c2ecf20Sopenharmony_cistatic int ath10k_wmi_tlv_parse_peer_stats_info(struct ath10k *ar, u16 tag, u16 len,
2238c2ecf20Sopenharmony_ci						const void *ptr, void *data)
2248c2ecf20Sopenharmony_ci{
2258c2ecf20Sopenharmony_ci	const struct wmi_tlv_peer_stats_info *stat = ptr;
2268c2ecf20Sopenharmony_ci	struct ieee80211_sta *sta;
2278c2ecf20Sopenharmony_ci	struct ath10k_sta *arsta;
2288c2ecf20Sopenharmony_ci
2298c2ecf20Sopenharmony_ci	if (tag != WMI_TLV_TAG_STRUCT_PEER_STATS_INFO)
2308c2ecf20Sopenharmony_ci		return -EPROTO;
2318c2ecf20Sopenharmony_ci
2328c2ecf20Sopenharmony_ci	ath10k_dbg(ar, ATH10K_DBG_WMI,
2338c2ecf20Sopenharmony_ci		   "wmi tlv stats peer addr %pMF rx rate code 0x%x bit rate %d kbps\n",
2348c2ecf20Sopenharmony_ci		   stat->peer_macaddr.addr,
2358c2ecf20Sopenharmony_ci		   __le32_to_cpu(stat->last_rx_rate_code),
2368c2ecf20Sopenharmony_ci		   __le32_to_cpu(stat->last_rx_bitrate_kbps));
2378c2ecf20Sopenharmony_ci
2388c2ecf20Sopenharmony_ci	ath10k_dbg(ar, ATH10K_DBG_WMI,
2398c2ecf20Sopenharmony_ci		   "wmi tlv stats tx rate code 0x%x bit rate %d kbps\n",
2408c2ecf20Sopenharmony_ci		   __le32_to_cpu(stat->last_tx_rate_code),
2418c2ecf20Sopenharmony_ci		   __le32_to_cpu(stat->last_tx_bitrate_kbps));
2428c2ecf20Sopenharmony_ci
2438c2ecf20Sopenharmony_ci	rcu_read_lock();
2448c2ecf20Sopenharmony_ci	sta = ieee80211_find_sta_by_ifaddr(ar->hw, stat->peer_macaddr.addr, NULL);
2458c2ecf20Sopenharmony_ci	if (!sta) {
2468c2ecf20Sopenharmony_ci		rcu_read_unlock();
2478c2ecf20Sopenharmony_ci		ath10k_warn(ar, "not found station for peer stats\n");
2488c2ecf20Sopenharmony_ci		return -EINVAL;
2498c2ecf20Sopenharmony_ci	}
2508c2ecf20Sopenharmony_ci
2518c2ecf20Sopenharmony_ci	arsta = (struct ath10k_sta *)sta->drv_priv;
2528c2ecf20Sopenharmony_ci	arsta->rx_rate_code = __le32_to_cpu(stat->last_rx_rate_code);
2538c2ecf20Sopenharmony_ci	arsta->rx_bitrate_kbps = __le32_to_cpu(stat->last_rx_bitrate_kbps);
2548c2ecf20Sopenharmony_ci	arsta->tx_rate_code = __le32_to_cpu(stat->last_tx_rate_code);
2558c2ecf20Sopenharmony_ci	arsta->tx_bitrate_kbps = __le32_to_cpu(stat->last_tx_bitrate_kbps);
2568c2ecf20Sopenharmony_ci	rcu_read_unlock();
2578c2ecf20Sopenharmony_ci
2588c2ecf20Sopenharmony_ci	return 0;
2598c2ecf20Sopenharmony_ci}
2608c2ecf20Sopenharmony_ci
2618c2ecf20Sopenharmony_cistatic int ath10k_wmi_tlv_op_pull_peer_stats_info(struct ath10k *ar,
2628c2ecf20Sopenharmony_ci						  struct sk_buff *skb)
2638c2ecf20Sopenharmony_ci{
2648c2ecf20Sopenharmony_ci	const void **tb;
2658c2ecf20Sopenharmony_ci	const struct wmi_tlv_peer_stats_info_ev *ev;
2668c2ecf20Sopenharmony_ci	const void *data;
2678c2ecf20Sopenharmony_ci	u32 num_peer_stats;
2688c2ecf20Sopenharmony_ci	int ret;
2698c2ecf20Sopenharmony_ci
2708c2ecf20Sopenharmony_ci	tb = ath10k_wmi_tlv_parse_alloc(ar, skb->data, skb->len, GFP_ATOMIC);
2718c2ecf20Sopenharmony_ci	if (IS_ERR(tb)) {
2728c2ecf20Sopenharmony_ci		ret = PTR_ERR(tb);
2738c2ecf20Sopenharmony_ci		ath10k_warn(ar, "failed to parse tlv: %d\n", ret);
2748c2ecf20Sopenharmony_ci		return ret;
2758c2ecf20Sopenharmony_ci	}
2768c2ecf20Sopenharmony_ci
2778c2ecf20Sopenharmony_ci	ev = tb[WMI_TLV_TAG_STRUCT_PEER_STATS_INFO_EVENT];
2788c2ecf20Sopenharmony_ci	data = tb[WMI_TLV_TAG_ARRAY_STRUCT];
2798c2ecf20Sopenharmony_ci
2808c2ecf20Sopenharmony_ci	if (!ev || !data) {
2818c2ecf20Sopenharmony_ci		kfree(tb);
2828c2ecf20Sopenharmony_ci		return -EPROTO;
2838c2ecf20Sopenharmony_ci	}
2848c2ecf20Sopenharmony_ci
2858c2ecf20Sopenharmony_ci	num_peer_stats = __le32_to_cpu(ev->num_peers);
2868c2ecf20Sopenharmony_ci
2878c2ecf20Sopenharmony_ci	ath10k_dbg(ar, ATH10K_DBG_WMI,
2888c2ecf20Sopenharmony_ci		   "wmi tlv peer stats info update peer vdev id %d peers %i more data %d\n",
2898c2ecf20Sopenharmony_ci		   __le32_to_cpu(ev->vdev_id),
2908c2ecf20Sopenharmony_ci		   num_peer_stats,
2918c2ecf20Sopenharmony_ci		   __le32_to_cpu(ev->more_data));
2928c2ecf20Sopenharmony_ci
2938c2ecf20Sopenharmony_ci	ret = ath10k_wmi_tlv_iter(ar, data, ath10k_wmi_tlv_len(data),
2948c2ecf20Sopenharmony_ci				  ath10k_wmi_tlv_parse_peer_stats_info, NULL);
2958c2ecf20Sopenharmony_ci	if (ret)
2968c2ecf20Sopenharmony_ci		ath10k_warn(ar, "failed to parse stats info tlv: %d\n", ret);
2978c2ecf20Sopenharmony_ci
2988c2ecf20Sopenharmony_ci	kfree(tb);
2998c2ecf20Sopenharmony_ci	return 0;
3008c2ecf20Sopenharmony_ci}
3018c2ecf20Sopenharmony_ci
3028c2ecf20Sopenharmony_cistatic void ath10k_wmi_tlv_event_peer_stats_info(struct ath10k *ar,
3038c2ecf20Sopenharmony_ci						 struct sk_buff *skb)
3048c2ecf20Sopenharmony_ci{
3058c2ecf20Sopenharmony_ci	ath10k_dbg(ar, ATH10K_DBG_WMI, "WMI_PEER_STATS_INFO_EVENTID\n");
3068c2ecf20Sopenharmony_ci	ath10k_wmi_tlv_op_pull_peer_stats_info(ar, skb);
3078c2ecf20Sopenharmony_ci	complete(&ar->peer_stats_info_complete);
3088c2ecf20Sopenharmony_ci}
3098c2ecf20Sopenharmony_ci
3108c2ecf20Sopenharmony_cistatic int ath10k_wmi_tlv_event_diag_data(struct ath10k *ar,
3118c2ecf20Sopenharmony_ci					  struct sk_buff *skb)
3128c2ecf20Sopenharmony_ci{
3138c2ecf20Sopenharmony_ci	const void **tb;
3148c2ecf20Sopenharmony_ci	const struct wmi_tlv_diag_data_ev *ev;
3158c2ecf20Sopenharmony_ci	const struct wmi_tlv_diag_item *item;
3168c2ecf20Sopenharmony_ci	const void *data;
3178c2ecf20Sopenharmony_ci	int ret, num_items, len;
3188c2ecf20Sopenharmony_ci
3198c2ecf20Sopenharmony_ci	tb = ath10k_wmi_tlv_parse_alloc(ar, skb->data, skb->len, GFP_ATOMIC);
3208c2ecf20Sopenharmony_ci	if (IS_ERR(tb)) {
3218c2ecf20Sopenharmony_ci		ret = PTR_ERR(tb);
3228c2ecf20Sopenharmony_ci		ath10k_warn(ar, "failed to parse tlv: %d\n", ret);
3238c2ecf20Sopenharmony_ci		return ret;
3248c2ecf20Sopenharmony_ci	}
3258c2ecf20Sopenharmony_ci
3268c2ecf20Sopenharmony_ci	ev = tb[WMI_TLV_TAG_STRUCT_DIAG_DATA_CONTAINER_EVENT];
3278c2ecf20Sopenharmony_ci	data = tb[WMI_TLV_TAG_ARRAY_BYTE];
3288c2ecf20Sopenharmony_ci	if (!ev || !data) {
3298c2ecf20Sopenharmony_ci		kfree(tb);
3308c2ecf20Sopenharmony_ci		return -EPROTO;
3318c2ecf20Sopenharmony_ci	}
3328c2ecf20Sopenharmony_ci
3338c2ecf20Sopenharmony_ci	num_items = __le32_to_cpu(ev->num_items);
3348c2ecf20Sopenharmony_ci	len = ath10k_wmi_tlv_len(data);
3358c2ecf20Sopenharmony_ci
3368c2ecf20Sopenharmony_ci	while (num_items--) {
3378c2ecf20Sopenharmony_ci		if (len == 0)
3388c2ecf20Sopenharmony_ci			break;
3398c2ecf20Sopenharmony_ci		if (len < sizeof(*item)) {
3408c2ecf20Sopenharmony_ci			ath10k_warn(ar, "failed to parse diag data: can't fit item header\n");
3418c2ecf20Sopenharmony_ci			break;
3428c2ecf20Sopenharmony_ci		}
3438c2ecf20Sopenharmony_ci
3448c2ecf20Sopenharmony_ci		item = data;
3458c2ecf20Sopenharmony_ci
3468c2ecf20Sopenharmony_ci		if (len < sizeof(*item) + __le16_to_cpu(item->len)) {
3478c2ecf20Sopenharmony_ci			ath10k_warn(ar, "failed to parse diag data: item is too long\n");
3488c2ecf20Sopenharmony_ci			break;
3498c2ecf20Sopenharmony_ci		}
3508c2ecf20Sopenharmony_ci
3518c2ecf20Sopenharmony_ci		trace_ath10k_wmi_diag_container(ar,
3528c2ecf20Sopenharmony_ci						item->type,
3538c2ecf20Sopenharmony_ci						__le32_to_cpu(item->timestamp),
3548c2ecf20Sopenharmony_ci						__le32_to_cpu(item->code),
3558c2ecf20Sopenharmony_ci						__le16_to_cpu(item->len),
3568c2ecf20Sopenharmony_ci						item->payload);
3578c2ecf20Sopenharmony_ci
3588c2ecf20Sopenharmony_ci		len -= sizeof(*item);
3598c2ecf20Sopenharmony_ci		len -= roundup(__le16_to_cpu(item->len), 4);
3608c2ecf20Sopenharmony_ci
3618c2ecf20Sopenharmony_ci		data += sizeof(*item);
3628c2ecf20Sopenharmony_ci		data += roundup(__le16_to_cpu(item->len), 4);
3638c2ecf20Sopenharmony_ci	}
3648c2ecf20Sopenharmony_ci
3658c2ecf20Sopenharmony_ci	if (num_items != -1 || len != 0)
3668c2ecf20Sopenharmony_ci		ath10k_warn(ar, "failed to parse diag data event: num_items %d len %d\n",
3678c2ecf20Sopenharmony_ci			    num_items, len);
3688c2ecf20Sopenharmony_ci
3698c2ecf20Sopenharmony_ci	kfree(tb);
3708c2ecf20Sopenharmony_ci	return 0;
3718c2ecf20Sopenharmony_ci}
3728c2ecf20Sopenharmony_ci
3738c2ecf20Sopenharmony_cistatic int ath10k_wmi_tlv_event_diag(struct ath10k *ar,
3748c2ecf20Sopenharmony_ci				     struct sk_buff *skb)
3758c2ecf20Sopenharmony_ci{
3768c2ecf20Sopenharmony_ci	const void **tb;
3778c2ecf20Sopenharmony_ci	const void *data;
3788c2ecf20Sopenharmony_ci	int ret, len;
3798c2ecf20Sopenharmony_ci
3808c2ecf20Sopenharmony_ci	tb = ath10k_wmi_tlv_parse_alloc(ar, skb->data, skb->len, GFP_ATOMIC);
3818c2ecf20Sopenharmony_ci	if (IS_ERR(tb)) {
3828c2ecf20Sopenharmony_ci		ret = PTR_ERR(tb);
3838c2ecf20Sopenharmony_ci		ath10k_warn(ar, "failed to parse tlv: %d\n", ret);
3848c2ecf20Sopenharmony_ci		return ret;
3858c2ecf20Sopenharmony_ci	}
3868c2ecf20Sopenharmony_ci
3878c2ecf20Sopenharmony_ci	data = tb[WMI_TLV_TAG_ARRAY_BYTE];
3888c2ecf20Sopenharmony_ci	if (!data) {
3898c2ecf20Sopenharmony_ci		kfree(tb);
3908c2ecf20Sopenharmony_ci		return -EPROTO;
3918c2ecf20Sopenharmony_ci	}
3928c2ecf20Sopenharmony_ci	len = ath10k_wmi_tlv_len(data);
3938c2ecf20Sopenharmony_ci
3948c2ecf20Sopenharmony_ci	ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv diag event len %d\n", len);
3958c2ecf20Sopenharmony_ci	trace_ath10k_wmi_diag(ar, data, len);
3968c2ecf20Sopenharmony_ci
3978c2ecf20Sopenharmony_ci	kfree(tb);
3988c2ecf20Sopenharmony_ci	return 0;
3998c2ecf20Sopenharmony_ci}
4008c2ecf20Sopenharmony_ci
4018c2ecf20Sopenharmony_cistatic int ath10k_wmi_tlv_event_p2p_noa(struct ath10k *ar,
4028c2ecf20Sopenharmony_ci					struct sk_buff *skb)
4038c2ecf20Sopenharmony_ci{
4048c2ecf20Sopenharmony_ci	const void **tb;
4058c2ecf20Sopenharmony_ci	const struct wmi_tlv_p2p_noa_ev *ev;
4068c2ecf20Sopenharmony_ci	const struct wmi_p2p_noa_info *noa;
4078c2ecf20Sopenharmony_ci	int ret, vdev_id;
4088c2ecf20Sopenharmony_ci
4098c2ecf20Sopenharmony_ci	tb = ath10k_wmi_tlv_parse_alloc(ar, skb->data, skb->len, GFP_ATOMIC);
4108c2ecf20Sopenharmony_ci	if (IS_ERR(tb)) {
4118c2ecf20Sopenharmony_ci		ret = PTR_ERR(tb);
4128c2ecf20Sopenharmony_ci		ath10k_warn(ar, "failed to parse tlv: %d\n", ret);
4138c2ecf20Sopenharmony_ci		return ret;
4148c2ecf20Sopenharmony_ci	}
4158c2ecf20Sopenharmony_ci
4168c2ecf20Sopenharmony_ci	ev = tb[WMI_TLV_TAG_STRUCT_P2P_NOA_EVENT];
4178c2ecf20Sopenharmony_ci	noa = tb[WMI_TLV_TAG_STRUCT_P2P_NOA_INFO];
4188c2ecf20Sopenharmony_ci
4198c2ecf20Sopenharmony_ci	if (!ev || !noa) {
4208c2ecf20Sopenharmony_ci		kfree(tb);
4218c2ecf20Sopenharmony_ci		return -EPROTO;
4228c2ecf20Sopenharmony_ci	}
4238c2ecf20Sopenharmony_ci
4248c2ecf20Sopenharmony_ci	vdev_id = __le32_to_cpu(ev->vdev_id);
4258c2ecf20Sopenharmony_ci
4268c2ecf20Sopenharmony_ci	ath10k_dbg(ar, ATH10K_DBG_WMI,
4278c2ecf20Sopenharmony_ci		   "wmi tlv p2p noa vdev_id %i descriptors %hhu\n",
4288c2ecf20Sopenharmony_ci		   vdev_id, noa->num_descriptors);
4298c2ecf20Sopenharmony_ci
4308c2ecf20Sopenharmony_ci	ath10k_p2p_noa_update_by_vdev_id(ar, vdev_id, noa);
4318c2ecf20Sopenharmony_ci	kfree(tb);
4328c2ecf20Sopenharmony_ci	return 0;
4338c2ecf20Sopenharmony_ci}
4348c2ecf20Sopenharmony_ci
4358c2ecf20Sopenharmony_cistatic int ath10k_wmi_tlv_event_tx_pause(struct ath10k *ar,
4368c2ecf20Sopenharmony_ci					 struct sk_buff *skb)
4378c2ecf20Sopenharmony_ci{
4388c2ecf20Sopenharmony_ci	const void **tb;
4398c2ecf20Sopenharmony_ci	const struct wmi_tlv_tx_pause_ev *ev;
4408c2ecf20Sopenharmony_ci	int ret, vdev_id;
4418c2ecf20Sopenharmony_ci	u32 pause_id, action, vdev_map, peer_id, tid_map;
4428c2ecf20Sopenharmony_ci
4438c2ecf20Sopenharmony_ci	tb = ath10k_wmi_tlv_parse_alloc(ar, skb->data, skb->len, GFP_ATOMIC);
4448c2ecf20Sopenharmony_ci	if (IS_ERR(tb)) {
4458c2ecf20Sopenharmony_ci		ret = PTR_ERR(tb);
4468c2ecf20Sopenharmony_ci		ath10k_warn(ar, "failed to parse tlv: %d\n", ret);
4478c2ecf20Sopenharmony_ci		return ret;
4488c2ecf20Sopenharmony_ci	}
4498c2ecf20Sopenharmony_ci
4508c2ecf20Sopenharmony_ci	ev = tb[WMI_TLV_TAG_STRUCT_TX_PAUSE_EVENT];
4518c2ecf20Sopenharmony_ci	if (!ev) {
4528c2ecf20Sopenharmony_ci		kfree(tb);
4538c2ecf20Sopenharmony_ci		return -EPROTO;
4548c2ecf20Sopenharmony_ci	}
4558c2ecf20Sopenharmony_ci
4568c2ecf20Sopenharmony_ci	pause_id = __le32_to_cpu(ev->pause_id);
4578c2ecf20Sopenharmony_ci	action = __le32_to_cpu(ev->action);
4588c2ecf20Sopenharmony_ci	vdev_map = __le32_to_cpu(ev->vdev_map);
4598c2ecf20Sopenharmony_ci	peer_id = __le32_to_cpu(ev->peer_id);
4608c2ecf20Sopenharmony_ci	tid_map = __le32_to_cpu(ev->tid_map);
4618c2ecf20Sopenharmony_ci
4628c2ecf20Sopenharmony_ci	ath10k_dbg(ar, ATH10K_DBG_WMI,
4638c2ecf20Sopenharmony_ci		   "wmi tlv tx pause pause_id %u action %u vdev_map 0x%08x peer_id %u tid_map 0x%08x\n",
4648c2ecf20Sopenharmony_ci		   pause_id, action, vdev_map, peer_id, tid_map);
4658c2ecf20Sopenharmony_ci
4668c2ecf20Sopenharmony_ci	switch (pause_id) {
4678c2ecf20Sopenharmony_ci	case WMI_TLV_TX_PAUSE_ID_MCC:
4688c2ecf20Sopenharmony_ci	case WMI_TLV_TX_PAUSE_ID_P2P_CLI_NOA:
4698c2ecf20Sopenharmony_ci	case WMI_TLV_TX_PAUSE_ID_P2P_GO_PS:
4708c2ecf20Sopenharmony_ci	case WMI_TLV_TX_PAUSE_ID_AP_PS:
4718c2ecf20Sopenharmony_ci	case WMI_TLV_TX_PAUSE_ID_IBSS_PS:
4728c2ecf20Sopenharmony_ci		for (vdev_id = 0; vdev_map; vdev_id++) {
4738c2ecf20Sopenharmony_ci			if (!(vdev_map & BIT(vdev_id)))
4748c2ecf20Sopenharmony_ci				continue;
4758c2ecf20Sopenharmony_ci
4768c2ecf20Sopenharmony_ci			vdev_map &= ~BIT(vdev_id);
4778c2ecf20Sopenharmony_ci			ath10k_mac_handle_tx_pause_vdev(ar, vdev_id, pause_id,
4788c2ecf20Sopenharmony_ci							action);
4798c2ecf20Sopenharmony_ci		}
4808c2ecf20Sopenharmony_ci		break;
4818c2ecf20Sopenharmony_ci	case WMI_TLV_TX_PAUSE_ID_AP_PEER_PS:
4828c2ecf20Sopenharmony_ci	case WMI_TLV_TX_PAUSE_ID_AP_PEER_UAPSD:
4838c2ecf20Sopenharmony_ci	case WMI_TLV_TX_PAUSE_ID_STA_ADD_BA:
4848c2ecf20Sopenharmony_ci	case WMI_TLV_TX_PAUSE_ID_HOST:
4858c2ecf20Sopenharmony_ci		ath10k_dbg(ar, ATH10K_DBG_MAC,
4868c2ecf20Sopenharmony_ci			   "mac ignoring unsupported tx pause id %d\n",
4878c2ecf20Sopenharmony_ci			   pause_id);
4888c2ecf20Sopenharmony_ci		break;
4898c2ecf20Sopenharmony_ci	default:
4908c2ecf20Sopenharmony_ci		ath10k_dbg(ar, ATH10K_DBG_MAC,
4918c2ecf20Sopenharmony_ci			   "mac ignoring unknown tx pause vdev %d\n",
4928c2ecf20Sopenharmony_ci			   pause_id);
4938c2ecf20Sopenharmony_ci		break;
4948c2ecf20Sopenharmony_ci	}
4958c2ecf20Sopenharmony_ci
4968c2ecf20Sopenharmony_ci	kfree(tb);
4978c2ecf20Sopenharmony_ci	return 0;
4988c2ecf20Sopenharmony_ci}
4998c2ecf20Sopenharmony_ci
5008c2ecf20Sopenharmony_cistatic void ath10k_wmi_tlv_event_rfkill_state_change(struct ath10k *ar,
5018c2ecf20Sopenharmony_ci						     struct sk_buff *skb)
5028c2ecf20Sopenharmony_ci{
5038c2ecf20Sopenharmony_ci	const struct wmi_tlv_rfkill_state_change_ev *ev;
5048c2ecf20Sopenharmony_ci	const void **tb;
5058c2ecf20Sopenharmony_ci	bool radio;
5068c2ecf20Sopenharmony_ci	int ret;
5078c2ecf20Sopenharmony_ci
5088c2ecf20Sopenharmony_ci	tb = ath10k_wmi_tlv_parse_alloc(ar, skb->data, skb->len, GFP_ATOMIC);
5098c2ecf20Sopenharmony_ci	if (IS_ERR(tb)) {
5108c2ecf20Sopenharmony_ci		ret = PTR_ERR(tb);
5118c2ecf20Sopenharmony_ci		ath10k_warn(ar,
5128c2ecf20Sopenharmony_ci			    "failed to parse rfkill state change event: %d\n",
5138c2ecf20Sopenharmony_ci			    ret);
5148c2ecf20Sopenharmony_ci		return;
5158c2ecf20Sopenharmony_ci	}
5168c2ecf20Sopenharmony_ci
5178c2ecf20Sopenharmony_ci	ev = tb[WMI_TLV_TAG_STRUCT_RFKILL_EVENT];
5188c2ecf20Sopenharmony_ci	if (!ev) {
5198c2ecf20Sopenharmony_ci		kfree(tb);
5208c2ecf20Sopenharmony_ci		return;
5218c2ecf20Sopenharmony_ci	}
5228c2ecf20Sopenharmony_ci
5238c2ecf20Sopenharmony_ci	ath10k_dbg(ar, ATH10K_DBG_MAC,
5248c2ecf20Sopenharmony_ci		   "wmi tlv rfkill state change gpio %d type %d radio_state %d\n",
5258c2ecf20Sopenharmony_ci		   __le32_to_cpu(ev->gpio_pin_num),
5268c2ecf20Sopenharmony_ci		   __le32_to_cpu(ev->int_type),
5278c2ecf20Sopenharmony_ci		   __le32_to_cpu(ev->radio_state));
5288c2ecf20Sopenharmony_ci
5298c2ecf20Sopenharmony_ci	radio = (__le32_to_cpu(ev->radio_state) == WMI_TLV_RFKILL_RADIO_STATE_ON);
5308c2ecf20Sopenharmony_ci
5318c2ecf20Sopenharmony_ci	spin_lock_bh(&ar->data_lock);
5328c2ecf20Sopenharmony_ci
5338c2ecf20Sopenharmony_ci	if (!radio)
5348c2ecf20Sopenharmony_ci		ar->hw_rfkill_on = true;
5358c2ecf20Sopenharmony_ci
5368c2ecf20Sopenharmony_ci	spin_unlock_bh(&ar->data_lock);
5378c2ecf20Sopenharmony_ci
5388c2ecf20Sopenharmony_ci	/* notify cfg80211 radio state change */
5398c2ecf20Sopenharmony_ci	ath10k_mac_rfkill_enable_radio(ar, radio);
5408c2ecf20Sopenharmony_ci	wiphy_rfkill_set_hw_state(ar->hw->wiphy, !radio);
5418c2ecf20Sopenharmony_ci}
5428c2ecf20Sopenharmony_ci
5438c2ecf20Sopenharmony_cistatic int ath10k_wmi_tlv_event_temperature(struct ath10k *ar,
5448c2ecf20Sopenharmony_ci					    struct sk_buff *skb)
5458c2ecf20Sopenharmony_ci{
5468c2ecf20Sopenharmony_ci	const struct wmi_tlv_pdev_temperature_event *ev;
5478c2ecf20Sopenharmony_ci
5488c2ecf20Sopenharmony_ci	ev = (struct wmi_tlv_pdev_temperature_event *)skb->data;
5498c2ecf20Sopenharmony_ci	if (WARN_ON(skb->len < sizeof(*ev)))
5508c2ecf20Sopenharmony_ci		return -EPROTO;
5518c2ecf20Sopenharmony_ci
5528c2ecf20Sopenharmony_ci	ath10k_thermal_event_temperature(ar, __le32_to_cpu(ev->temperature));
5538c2ecf20Sopenharmony_ci	return 0;
5548c2ecf20Sopenharmony_ci}
5558c2ecf20Sopenharmony_ci
5568c2ecf20Sopenharmony_cistatic void ath10k_wmi_event_tdls_peer(struct ath10k *ar, struct sk_buff *skb)
5578c2ecf20Sopenharmony_ci{
5588c2ecf20Sopenharmony_ci	struct ieee80211_sta *station;
5598c2ecf20Sopenharmony_ci	const struct wmi_tlv_tdls_peer_event *ev;
5608c2ecf20Sopenharmony_ci	const void **tb;
5618c2ecf20Sopenharmony_ci	struct ath10k_vif *arvif;
5628c2ecf20Sopenharmony_ci
5638c2ecf20Sopenharmony_ci	tb = ath10k_wmi_tlv_parse_alloc(ar, skb->data, skb->len, GFP_ATOMIC);
5648c2ecf20Sopenharmony_ci	if (IS_ERR(tb)) {
5658c2ecf20Sopenharmony_ci		ath10k_warn(ar, "tdls peer failed to parse tlv");
5668c2ecf20Sopenharmony_ci		return;
5678c2ecf20Sopenharmony_ci	}
5688c2ecf20Sopenharmony_ci	ev = tb[WMI_TLV_TAG_STRUCT_TDLS_PEER_EVENT];
5698c2ecf20Sopenharmony_ci	if (!ev) {
5708c2ecf20Sopenharmony_ci		kfree(tb);
5718c2ecf20Sopenharmony_ci		ath10k_warn(ar, "tdls peer NULL event");
5728c2ecf20Sopenharmony_ci		return;
5738c2ecf20Sopenharmony_ci	}
5748c2ecf20Sopenharmony_ci
5758c2ecf20Sopenharmony_ci	switch (__le32_to_cpu(ev->peer_reason)) {
5768c2ecf20Sopenharmony_ci	case WMI_TDLS_TEARDOWN_REASON_TX:
5778c2ecf20Sopenharmony_ci	case WMI_TDLS_TEARDOWN_REASON_RSSI:
5788c2ecf20Sopenharmony_ci	case WMI_TDLS_TEARDOWN_REASON_PTR_TIMEOUT:
5798c2ecf20Sopenharmony_ci		rcu_read_lock();
5808c2ecf20Sopenharmony_ci		station = ieee80211_find_sta_by_ifaddr(ar->hw,
5818c2ecf20Sopenharmony_ci						       ev->peer_macaddr.addr,
5828c2ecf20Sopenharmony_ci						       NULL);
5838c2ecf20Sopenharmony_ci		if (!station) {
5848c2ecf20Sopenharmony_ci			ath10k_warn(ar, "did not find station from tdls peer event");
5858c2ecf20Sopenharmony_ci			goto exit;
5868c2ecf20Sopenharmony_ci		}
5878c2ecf20Sopenharmony_ci		arvif = ath10k_get_arvif(ar, __le32_to_cpu(ev->vdev_id));
5888c2ecf20Sopenharmony_ci		ieee80211_tdls_oper_request(
5898c2ecf20Sopenharmony_ci					arvif->vif, station->addr,
5908c2ecf20Sopenharmony_ci					NL80211_TDLS_TEARDOWN,
5918c2ecf20Sopenharmony_ci					WLAN_REASON_TDLS_TEARDOWN_UNREACHABLE,
5928c2ecf20Sopenharmony_ci					GFP_ATOMIC
5938c2ecf20Sopenharmony_ci					);
5948c2ecf20Sopenharmony_ci		break;
5958c2ecf20Sopenharmony_ci	default:
5968c2ecf20Sopenharmony_ci		kfree(tb);
5978c2ecf20Sopenharmony_ci		return;
5988c2ecf20Sopenharmony_ci	}
5998c2ecf20Sopenharmony_ci
6008c2ecf20Sopenharmony_ciexit:
6018c2ecf20Sopenharmony_ci	rcu_read_unlock();
6028c2ecf20Sopenharmony_ci	kfree(tb);
6038c2ecf20Sopenharmony_ci}
6048c2ecf20Sopenharmony_ci
6058c2ecf20Sopenharmony_cistatic int ath10k_wmi_tlv_event_peer_delete_resp(struct ath10k *ar,
6068c2ecf20Sopenharmony_ci						 struct sk_buff *skb)
6078c2ecf20Sopenharmony_ci{
6088c2ecf20Sopenharmony_ci	struct wmi_peer_delete_resp_ev_arg *arg;
6098c2ecf20Sopenharmony_ci	struct wmi_tlv *tlv_hdr;
6108c2ecf20Sopenharmony_ci
6118c2ecf20Sopenharmony_ci	tlv_hdr = (struct wmi_tlv *)skb->data;
6128c2ecf20Sopenharmony_ci	arg = (struct wmi_peer_delete_resp_ev_arg *)tlv_hdr->value;
6138c2ecf20Sopenharmony_ci
6148c2ecf20Sopenharmony_ci	ath10k_dbg(ar, ATH10K_DBG_WMI, "vdev id %d", arg->vdev_id);
6158c2ecf20Sopenharmony_ci	ath10k_dbg(ar, ATH10K_DBG_WMI, "peer mac addr %pM", &arg->peer_addr);
6168c2ecf20Sopenharmony_ci	ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv peer delete response\n");
6178c2ecf20Sopenharmony_ci
6188c2ecf20Sopenharmony_ci	complete(&ar->peer_delete_done);
6198c2ecf20Sopenharmony_ci
6208c2ecf20Sopenharmony_ci	return 0;
6218c2ecf20Sopenharmony_ci}
6228c2ecf20Sopenharmony_ci
6238c2ecf20Sopenharmony_ci/***********/
6248c2ecf20Sopenharmony_ci/* TLV ops */
6258c2ecf20Sopenharmony_ci/***********/
6268c2ecf20Sopenharmony_ci
6278c2ecf20Sopenharmony_cistatic void ath10k_wmi_tlv_op_rx(struct ath10k *ar, struct sk_buff *skb)
6288c2ecf20Sopenharmony_ci{
6298c2ecf20Sopenharmony_ci	struct wmi_cmd_hdr *cmd_hdr;
6308c2ecf20Sopenharmony_ci	enum wmi_tlv_event_id id;
6318c2ecf20Sopenharmony_ci	bool consumed;
6328c2ecf20Sopenharmony_ci
6338c2ecf20Sopenharmony_ci	cmd_hdr = (struct wmi_cmd_hdr *)skb->data;
6348c2ecf20Sopenharmony_ci	id = MS(__le32_to_cpu(cmd_hdr->cmd_id), WMI_CMD_HDR_CMD_ID);
6358c2ecf20Sopenharmony_ci
6368c2ecf20Sopenharmony_ci	if (skb_pull(skb, sizeof(struct wmi_cmd_hdr)) == NULL)
6378c2ecf20Sopenharmony_ci		goto out;
6388c2ecf20Sopenharmony_ci
6398c2ecf20Sopenharmony_ci	trace_ath10k_wmi_event(ar, id, skb->data, skb->len);
6408c2ecf20Sopenharmony_ci
6418c2ecf20Sopenharmony_ci	consumed = ath10k_tm_event_wmi(ar, id, skb);
6428c2ecf20Sopenharmony_ci
6438c2ecf20Sopenharmony_ci	/* Ready event must be handled normally also in UTF mode so that we
6448c2ecf20Sopenharmony_ci	 * know the UTF firmware has booted, others we are just bypass WMI
6458c2ecf20Sopenharmony_ci	 * events to testmode.
6468c2ecf20Sopenharmony_ci	 */
6478c2ecf20Sopenharmony_ci	if (consumed && id != WMI_TLV_READY_EVENTID) {
6488c2ecf20Sopenharmony_ci		ath10k_dbg(ar, ATH10K_DBG_WMI,
6498c2ecf20Sopenharmony_ci			   "wmi tlv testmode consumed 0x%x\n", id);
6508c2ecf20Sopenharmony_ci		goto out;
6518c2ecf20Sopenharmony_ci	}
6528c2ecf20Sopenharmony_ci
6538c2ecf20Sopenharmony_ci	switch (id) {
6548c2ecf20Sopenharmony_ci	case WMI_TLV_MGMT_RX_EVENTID:
6558c2ecf20Sopenharmony_ci		ath10k_wmi_event_mgmt_rx(ar, skb);
6568c2ecf20Sopenharmony_ci		/* mgmt_rx() owns the skb now! */
6578c2ecf20Sopenharmony_ci		return;
6588c2ecf20Sopenharmony_ci	case WMI_TLV_SCAN_EVENTID:
6598c2ecf20Sopenharmony_ci		ath10k_wmi_event_scan(ar, skb);
6608c2ecf20Sopenharmony_ci		break;
6618c2ecf20Sopenharmony_ci	case WMI_TLV_CHAN_INFO_EVENTID:
6628c2ecf20Sopenharmony_ci		ath10k_wmi_event_chan_info(ar, skb);
6638c2ecf20Sopenharmony_ci		break;
6648c2ecf20Sopenharmony_ci	case WMI_TLV_ECHO_EVENTID:
6658c2ecf20Sopenharmony_ci		ath10k_wmi_event_echo(ar, skb);
6668c2ecf20Sopenharmony_ci		break;
6678c2ecf20Sopenharmony_ci	case WMI_TLV_DEBUG_MESG_EVENTID:
6688c2ecf20Sopenharmony_ci		ath10k_wmi_event_debug_mesg(ar, skb);
6698c2ecf20Sopenharmony_ci		break;
6708c2ecf20Sopenharmony_ci	case WMI_TLV_UPDATE_STATS_EVENTID:
6718c2ecf20Sopenharmony_ci		ath10k_wmi_event_update_stats(ar, skb);
6728c2ecf20Sopenharmony_ci		break;
6738c2ecf20Sopenharmony_ci	case WMI_TLV_PEER_STATS_INFO_EVENTID:
6748c2ecf20Sopenharmony_ci		ath10k_wmi_tlv_event_peer_stats_info(ar, skb);
6758c2ecf20Sopenharmony_ci		break;
6768c2ecf20Sopenharmony_ci	case WMI_TLV_VDEV_START_RESP_EVENTID:
6778c2ecf20Sopenharmony_ci		ath10k_wmi_event_vdev_start_resp(ar, skb);
6788c2ecf20Sopenharmony_ci		break;
6798c2ecf20Sopenharmony_ci	case WMI_TLV_VDEV_STOPPED_EVENTID:
6808c2ecf20Sopenharmony_ci		ath10k_wmi_event_vdev_stopped(ar, skb);
6818c2ecf20Sopenharmony_ci		break;
6828c2ecf20Sopenharmony_ci	case WMI_TLV_VDEV_DELETE_RESP_EVENTID:
6838c2ecf20Sopenharmony_ci		ath10k_wmi_tlv_event_vdev_delete_resp(ar, skb);
6848c2ecf20Sopenharmony_ci		break;
6858c2ecf20Sopenharmony_ci	case WMI_TLV_PEER_STA_KICKOUT_EVENTID:
6868c2ecf20Sopenharmony_ci		ath10k_wmi_event_peer_sta_kickout(ar, skb);
6878c2ecf20Sopenharmony_ci		break;
6888c2ecf20Sopenharmony_ci	case WMI_TLV_HOST_SWBA_EVENTID:
6898c2ecf20Sopenharmony_ci		ath10k_wmi_event_host_swba(ar, skb);
6908c2ecf20Sopenharmony_ci		break;
6918c2ecf20Sopenharmony_ci	case WMI_TLV_TBTTOFFSET_UPDATE_EVENTID:
6928c2ecf20Sopenharmony_ci		ath10k_wmi_event_tbttoffset_update(ar, skb);
6938c2ecf20Sopenharmony_ci		break;
6948c2ecf20Sopenharmony_ci	case WMI_TLV_PHYERR_EVENTID:
6958c2ecf20Sopenharmony_ci		ath10k_wmi_event_phyerr(ar, skb);
6968c2ecf20Sopenharmony_ci		break;
6978c2ecf20Sopenharmony_ci	case WMI_TLV_ROAM_EVENTID:
6988c2ecf20Sopenharmony_ci		ath10k_wmi_event_roam(ar, skb);
6998c2ecf20Sopenharmony_ci		break;
7008c2ecf20Sopenharmony_ci	case WMI_TLV_PROFILE_MATCH:
7018c2ecf20Sopenharmony_ci		ath10k_wmi_event_profile_match(ar, skb);
7028c2ecf20Sopenharmony_ci		break;
7038c2ecf20Sopenharmony_ci	case WMI_TLV_DEBUG_PRINT_EVENTID:
7048c2ecf20Sopenharmony_ci		ath10k_wmi_event_debug_print(ar, skb);
7058c2ecf20Sopenharmony_ci		break;
7068c2ecf20Sopenharmony_ci	case WMI_TLV_PDEV_QVIT_EVENTID:
7078c2ecf20Sopenharmony_ci		ath10k_wmi_event_pdev_qvit(ar, skb);
7088c2ecf20Sopenharmony_ci		break;
7098c2ecf20Sopenharmony_ci	case WMI_TLV_WLAN_PROFILE_DATA_EVENTID:
7108c2ecf20Sopenharmony_ci		ath10k_wmi_event_wlan_profile_data(ar, skb);
7118c2ecf20Sopenharmony_ci		break;
7128c2ecf20Sopenharmony_ci	case WMI_TLV_RTT_MEASUREMENT_REPORT_EVENTID:
7138c2ecf20Sopenharmony_ci		ath10k_wmi_event_rtt_measurement_report(ar, skb);
7148c2ecf20Sopenharmony_ci		break;
7158c2ecf20Sopenharmony_ci	case WMI_TLV_TSF_MEASUREMENT_REPORT_EVENTID:
7168c2ecf20Sopenharmony_ci		ath10k_wmi_event_tsf_measurement_report(ar, skb);
7178c2ecf20Sopenharmony_ci		break;
7188c2ecf20Sopenharmony_ci	case WMI_TLV_RTT_ERROR_REPORT_EVENTID:
7198c2ecf20Sopenharmony_ci		ath10k_wmi_event_rtt_error_report(ar, skb);
7208c2ecf20Sopenharmony_ci		break;
7218c2ecf20Sopenharmony_ci	case WMI_TLV_WOW_WAKEUP_HOST_EVENTID:
7228c2ecf20Sopenharmony_ci		ath10k_wmi_event_wow_wakeup_host(ar, skb);
7238c2ecf20Sopenharmony_ci		break;
7248c2ecf20Sopenharmony_ci	case WMI_TLV_DCS_INTERFERENCE_EVENTID:
7258c2ecf20Sopenharmony_ci		ath10k_wmi_event_dcs_interference(ar, skb);
7268c2ecf20Sopenharmony_ci		break;
7278c2ecf20Sopenharmony_ci	case WMI_TLV_PDEV_TPC_CONFIG_EVENTID:
7288c2ecf20Sopenharmony_ci		ath10k_wmi_event_pdev_tpc_config(ar, skb);
7298c2ecf20Sopenharmony_ci		break;
7308c2ecf20Sopenharmony_ci	case WMI_TLV_PDEV_FTM_INTG_EVENTID:
7318c2ecf20Sopenharmony_ci		ath10k_wmi_event_pdev_ftm_intg(ar, skb);
7328c2ecf20Sopenharmony_ci		break;
7338c2ecf20Sopenharmony_ci	case WMI_TLV_GTK_OFFLOAD_STATUS_EVENTID:
7348c2ecf20Sopenharmony_ci		ath10k_wmi_event_gtk_offload_status(ar, skb);
7358c2ecf20Sopenharmony_ci		break;
7368c2ecf20Sopenharmony_ci	case WMI_TLV_GTK_REKEY_FAIL_EVENTID:
7378c2ecf20Sopenharmony_ci		ath10k_wmi_event_gtk_rekey_fail(ar, skb);
7388c2ecf20Sopenharmony_ci		break;
7398c2ecf20Sopenharmony_ci	case WMI_TLV_TX_DELBA_COMPLETE_EVENTID:
7408c2ecf20Sopenharmony_ci		ath10k_wmi_event_delba_complete(ar, skb);
7418c2ecf20Sopenharmony_ci		break;
7428c2ecf20Sopenharmony_ci	case WMI_TLV_TX_ADDBA_COMPLETE_EVENTID:
7438c2ecf20Sopenharmony_ci		ath10k_wmi_event_addba_complete(ar, skb);
7448c2ecf20Sopenharmony_ci		break;
7458c2ecf20Sopenharmony_ci	case WMI_TLV_VDEV_INSTALL_KEY_COMPLETE_EVENTID:
7468c2ecf20Sopenharmony_ci		ath10k_wmi_event_vdev_install_key_complete(ar, skb);
7478c2ecf20Sopenharmony_ci		break;
7488c2ecf20Sopenharmony_ci	case WMI_TLV_SERVICE_READY_EVENTID:
7498c2ecf20Sopenharmony_ci		ath10k_wmi_event_service_ready(ar, skb);
7508c2ecf20Sopenharmony_ci		return;
7518c2ecf20Sopenharmony_ci	case WMI_TLV_READY_EVENTID:
7528c2ecf20Sopenharmony_ci		ath10k_wmi_event_ready(ar, skb);
7538c2ecf20Sopenharmony_ci		break;
7548c2ecf20Sopenharmony_ci	case WMI_TLV_SERVICE_AVAILABLE_EVENTID:
7558c2ecf20Sopenharmony_ci		ath10k_wmi_event_service_available(ar, skb);
7568c2ecf20Sopenharmony_ci		break;
7578c2ecf20Sopenharmony_ci	case WMI_TLV_OFFLOAD_BCN_TX_STATUS_EVENTID:
7588c2ecf20Sopenharmony_ci		ath10k_wmi_tlv_event_bcn_tx_status(ar, skb);
7598c2ecf20Sopenharmony_ci		break;
7608c2ecf20Sopenharmony_ci	case WMI_TLV_DIAG_DATA_CONTAINER_EVENTID:
7618c2ecf20Sopenharmony_ci		ath10k_wmi_tlv_event_diag_data(ar, skb);
7628c2ecf20Sopenharmony_ci		break;
7638c2ecf20Sopenharmony_ci	case WMI_TLV_DIAG_EVENTID:
7648c2ecf20Sopenharmony_ci		ath10k_wmi_tlv_event_diag(ar, skb);
7658c2ecf20Sopenharmony_ci		break;
7668c2ecf20Sopenharmony_ci	case WMI_TLV_P2P_NOA_EVENTID:
7678c2ecf20Sopenharmony_ci		ath10k_wmi_tlv_event_p2p_noa(ar, skb);
7688c2ecf20Sopenharmony_ci		break;
7698c2ecf20Sopenharmony_ci	case WMI_TLV_TX_PAUSE_EVENTID:
7708c2ecf20Sopenharmony_ci		ath10k_wmi_tlv_event_tx_pause(ar, skb);
7718c2ecf20Sopenharmony_ci		break;
7728c2ecf20Sopenharmony_ci	case WMI_TLV_RFKILL_STATE_CHANGE_EVENTID:
7738c2ecf20Sopenharmony_ci		ath10k_wmi_tlv_event_rfkill_state_change(ar, skb);
7748c2ecf20Sopenharmony_ci		break;
7758c2ecf20Sopenharmony_ci	case WMI_TLV_PDEV_TEMPERATURE_EVENTID:
7768c2ecf20Sopenharmony_ci		ath10k_wmi_tlv_event_temperature(ar, skb);
7778c2ecf20Sopenharmony_ci		break;
7788c2ecf20Sopenharmony_ci	case WMI_TLV_TDLS_PEER_EVENTID:
7798c2ecf20Sopenharmony_ci		ath10k_wmi_event_tdls_peer(ar, skb);
7808c2ecf20Sopenharmony_ci		break;
7818c2ecf20Sopenharmony_ci	case WMI_TLV_PEER_DELETE_RESP_EVENTID:
7828c2ecf20Sopenharmony_ci		ath10k_wmi_tlv_event_peer_delete_resp(ar, skb);
7838c2ecf20Sopenharmony_ci		break;
7848c2ecf20Sopenharmony_ci	case WMI_TLV_MGMT_TX_COMPLETION_EVENTID:
7858c2ecf20Sopenharmony_ci		ath10k_wmi_event_mgmt_tx_compl(ar, skb);
7868c2ecf20Sopenharmony_ci		break;
7878c2ecf20Sopenharmony_ci	case WMI_TLV_MGMT_TX_BUNDLE_COMPLETION_EVENTID:
7888c2ecf20Sopenharmony_ci		ath10k_wmi_event_mgmt_tx_bundle_compl(ar, skb);
7898c2ecf20Sopenharmony_ci		break;
7908c2ecf20Sopenharmony_ci	default:
7918c2ecf20Sopenharmony_ci		ath10k_dbg(ar, ATH10K_DBG_WMI, "Unknown eventid: %d\n", id);
7928c2ecf20Sopenharmony_ci		break;
7938c2ecf20Sopenharmony_ci	}
7948c2ecf20Sopenharmony_ci
7958c2ecf20Sopenharmony_ciout:
7968c2ecf20Sopenharmony_ci	dev_kfree_skb(skb);
7978c2ecf20Sopenharmony_ci}
7988c2ecf20Sopenharmony_ci
7998c2ecf20Sopenharmony_cistatic int ath10k_wmi_tlv_op_pull_scan_ev(struct ath10k *ar,
8008c2ecf20Sopenharmony_ci					  struct sk_buff *skb,
8018c2ecf20Sopenharmony_ci					  struct wmi_scan_ev_arg *arg)
8028c2ecf20Sopenharmony_ci{
8038c2ecf20Sopenharmony_ci	const void **tb;
8048c2ecf20Sopenharmony_ci	const struct wmi_scan_event *ev;
8058c2ecf20Sopenharmony_ci	int ret;
8068c2ecf20Sopenharmony_ci
8078c2ecf20Sopenharmony_ci	tb = ath10k_wmi_tlv_parse_alloc(ar, skb->data, skb->len, GFP_ATOMIC);
8088c2ecf20Sopenharmony_ci	if (IS_ERR(tb)) {
8098c2ecf20Sopenharmony_ci		ret = PTR_ERR(tb);
8108c2ecf20Sopenharmony_ci		ath10k_warn(ar, "failed to parse tlv: %d\n", ret);
8118c2ecf20Sopenharmony_ci		return ret;
8128c2ecf20Sopenharmony_ci	}
8138c2ecf20Sopenharmony_ci
8148c2ecf20Sopenharmony_ci	ev = tb[WMI_TLV_TAG_STRUCT_SCAN_EVENT];
8158c2ecf20Sopenharmony_ci	if (!ev) {
8168c2ecf20Sopenharmony_ci		kfree(tb);
8178c2ecf20Sopenharmony_ci		return -EPROTO;
8188c2ecf20Sopenharmony_ci	}
8198c2ecf20Sopenharmony_ci
8208c2ecf20Sopenharmony_ci	arg->event_type = ev->event_type;
8218c2ecf20Sopenharmony_ci	arg->reason = ev->reason;
8228c2ecf20Sopenharmony_ci	arg->channel_freq = ev->channel_freq;
8238c2ecf20Sopenharmony_ci	arg->scan_req_id = ev->scan_req_id;
8248c2ecf20Sopenharmony_ci	arg->scan_id = ev->scan_id;
8258c2ecf20Sopenharmony_ci	arg->vdev_id = ev->vdev_id;
8268c2ecf20Sopenharmony_ci
8278c2ecf20Sopenharmony_ci	kfree(tb);
8288c2ecf20Sopenharmony_ci	return 0;
8298c2ecf20Sopenharmony_ci}
8308c2ecf20Sopenharmony_ci
8318c2ecf20Sopenharmony_cistatic int
8328c2ecf20Sopenharmony_ciath10k_wmi_tlv_op_pull_mgmt_tx_compl_ev(struct ath10k *ar, struct sk_buff *skb,
8338c2ecf20Sopenharmony_ci					struct wmi_tlv_mgmt_tx_compl_ev_arg *arg)
8348c2ecf20Sopenharmony_ci{
8358c2ecf20Sopenharmony_ci	const void **tb;
8368c2ecf20Sopenharmony_ci	const struct wmi_tlv_mgmt_tx_compl_ev *ev;
8378c2ecf20Sopenharmony_ci	int ret;
8388c2ecf20Sopenharmony_ci
8398c2ecf20Sopenharmony_ci	tb = ath10k_wmi_tlv_parse_alloc(ar, skb->data, skb->len, GFP_ATOMIC);
8408c2ecf20Sopenharmony_ci	if (IS_ERR(tb)) {
8418c2ecf20Sopenharmony_ci		ret = PTR_ERR(tb);
8428c2ecf20Sopenharmony_ci		ath10k_warn(ar, "failed to parse tlv: %d\n", ret);
8438c2ecf20Sopenharmony_ci		return ret;
8448c2ecf20Sopenharmony_ci	}
8458c2ecf20Sopenharmony_ci
8468c2ecf20Sopenharmony_ci	ev = tb[WMI_TLV_TAG_STRUCT_MGMT_TX_COMPL_EVENT];
8478c2ecf20Sopenharmony_ci
8488c2ecf20Sopenharmony_ci	arg->desc_id = ev->desc_id;
8498c2ecf20Sopenharmony_ci	arg->status = ev->status;
8508c2ecf20Sopenharmony_ci	arg->pdev_id = ev->pdev_id;
8518c2ecf20Sopenharmony_ci	arg->ppdu_id = ev->ppdu_id;
8528c2ecf20Sopenharmony_ci
8538c2ecf20Sopenharmony_ci	if (test_bit(WMI_SERVICE_TX_DATA_ACK_RSSI, ar->wmi.svc_map))
8548c2ecf20Sopenharmony_ci		arg->ack_rssi = ev->ack_rssi;
8558c2ecf20Sopenharmony_ci
8568c2ecf20Sopenharmony_ci	kfree(tb);
8578c2ecf20Sopenharmony_ci	return 0;
8588c2ecf20Sopenharmony_ci}
8598c2ecf20Sopenharmony_ci
8608c2ecf20Sopenharmony_cistruct wmi_tlv_tx_bundle_compl_parse {
8618c2ecf20Sopenharmony_ci	const __le32 *num_reports;
8628c2ecf20Sopenharmony_ci	const __le32 *desc_ids;
8638c2ecf20Sopenharmony_ci	const __le32 *status;
8648c2ecf20Sopenharmony_ci	const __le32 *ppdu_ids;
8658c2ecf20Sopenharmony_ci	const __le32 *ack_rssi;
8668c2ecf20Sopenharmony_ci	bool desc_ids_done;
8678c2ecf20Sopenharmony_ci	bool status_done;
8688c2ecf20Sopenharmony_ci	bool ppdu_ids_done;
8698c2ecf20Sopenharmony_ci	bool ack_rssi_done;
8708c2ecf20Sopenharmony_ci};
8718c2ecf20Sopenharmony_ci
8728c2ecf20Sopenharmony_cistatic int
8738c2ecf20Sopenharmony_ciath10k_wmi_tlv_mgmt_tx_bundle_compl_parse(struct ath10k *ar, u16 tag, u16 len,
8748c2ecf20Sopenharmony_ci					  const void *ptr, void *data)
8758c2ecf20Sopenharmony_ci{
8768c2ecf20Sopenharmony_ci	struct wmi_tlv_tx_bundle_compl_parse *bundle_tx_compl = data;
8778c2ecf20Sopenharmony_ci
8788c2ecf20Sopenharmony_ci	switch (tag) {
8798c2ecf20Sopenharmony_ci	case WMI_TLV_TAG_STRUCT_MGMT_TX_COMPL_BUNDLE_EVENT:
8808c2ecf20Sopenharmony_ci		bundle_tx_compl->num_reports = ptr;
8818c2ecf20Sopenharmony_ci		break;
8828c2ecf20Sopenharmony_ci	case WMI_TLV_TAG_ARRAY_UINT32:
8838c2ecf20Sopenharmony_ci		if (!bundle_tx_compl->desc_ids_done) {
8848c2ecf20Sopenharmony_ci			bundle_tx_compl->desc_ids_done = true;
8858c2ecf20Sopenharmony_ci			bundle_tx_compl->desc_ids = ptr;
8868c2ecf20Sopenharmony_ci		} else if (!bundle_tx_compl->status_done) {
8878c2ecf20Sopenharmony_ci			bundle_tx_compl->status_done = true;
8888c2ecf20Sopenharmony_ci			bundle_tx_compl->status = ptr;
8898c2ecf20Sopenharmony_ci		} else if (!bundle_tx_compl->ppdu_ids_done) {
8908c2ecf20Sopenharmony_ci			bundle_tx_compl->ppdu_ids_done = true;
8918c2ecf20Sopenharmony_ci			bundle_tx_compl->ppdu_ids = ptr;
8928c2ecf20Sopenharmony_ci		} else if (!bundle_tx_compl->ack_rssi_done) {
8938c2ecf20Sopenharmony_ci			bundle_tx_compl->ack_rssi_done = true;
8948c2ecf20Sopenharmony_ci			bundle_tx_compl->ack_rssi = ptr;
8958c2ecf20Sopenharmony_ci		}
8968c2ecf20Sopenharmony_ci		break;
8978c2ecf20Sopenharmony_ci	default:
8988c2ecf20Sopenharmony_ci		break;
8998c2ecf20Sopenharmony_ci	}
9008c2ecf20Sopenharmony_ci	return 0;
9018c2ecf20Sopenharmony_ci}
9028c2ecf20Sopenharmony_ci
9038c2ecf20Sopenharmony_cistatic int ath10k_wmi_tlv_op_pull_mgmt_tx_bundle_compl_ev(
9048c2ecf20Sopenharmony_ci				struct ath10k *ar, struct sk_buff *skb,
9058c2ecf20Sopenharmony_ci				struct wmi_tlv_mgmt_tx_bundle_compl_ev_arg *arg)
9068c2ecf20Sopenharmony_ci{
9078c2ecf20Sopenharmony_ci	struct wmi_tlv_tx_bundle_compl_parse bundle_tx_compl = { };
9088c2ecf20Sopenharmony_ci	int ret;
9098c2ecf20Sopenharmony_ci
9108c2ecf20Sopenharmony_ci	ret = ath10k_wmi_tlv_iter(ar, skb->data, skb->len,
9118c2ecf20Sopenharmony_ci				  ath10k_wmi_tlv_mgmt_tx_bundle_compl_parse,
9128c2ecf20Sopenharmony_ci				  &bundle_tx_compl);
9138c2ecf20Sopenharmony_ci	if (ret) {
9148c2ecf20Sopenharmony_ci		ath10k_warn(ar, "failed to parse tlv: %d\n", ret);
9158c2ecf20Sopenharmony_ci		return ret;
9168c2ecf20Sopenharmony_ci	}
9178c2ecf20Sopenharmony_ci
9188c2ecf20Sopenharmony_ci	if (!bundle_tx_compl.num_reports || !bundle_tx_compl.desc_ids ||
9198c2ecf20Sopenharmony_ci	    !bundle_tx_compl.status)
9208c2ecf20Sopenharmony_ci		return -EPROTO;
9218c2ecf20Sopenharmony_ci
9228c2ecf20Sopenharmony_ci	arg->num_reports = *bundle_tx_compl.num_reports;
9238c2ecf20Sopenharmony_ci	arg->desc_ids = bundle_tx_compl.desc_ids;
9248c2ecf20Sopenharmony_ci	arg->status = bundle_tx_compl.status;
9258c2ecf20Sopenharmony_ci	arg->ppdu_ids = bundle_tx_compl.ppdu_ids;
9268c2ecf20Sopenharmony_ci
9278c2ecf20Sopenharmony_ci	if (test_bit(WMI_SERVICE_TX_DATA_ACK_RSSI, ar->wmi.svc_map))
9288c2ecf20Sopenharmony_ci		arg->ack_rssi = bundle_tx_compl.ack_rssi;
9298c2ecf20Sopenharmony_ci
9308c2ecf20Sopenharmony_ci	return 0;
9318c2ecf20Sopenharmony_ci}
9328c2ecf20Sopenharmony_ci
9338c2ecf20Sopenharmony_cistatic int ath10k_wmi_tlv_op_pull_mgmt_rx_ev(struct ath10k *ar,
9348c2ecf20Sopenharmony_ci					     struct sk_buff *skb,
9358c2ecf20Sopenharmony_ci					     struct wmi_mgmt_rx_ev_arg *arg)
9368c2ecf20Sopenharmony_ci{
9378c2ecf20Sopenharmony_ci	const void **tb;
9388c2ecf20Sopenharmony_ci	const struct wmi_tlv_mgmt_rx_ev *ev;
9398c2ecf20Sopenharmony_ci	const u8 *frame;
9408c2ecf20Sopenharmony_ci	u32 msdu_len;
9418c2ecf20Sopenharmony_ci	int ret, i;
9428c2ecf20Sopenharmony_ci
9438c2ecf20Sopenharmony_ci	tb = ath10k_wmi_tlv_parse_alloc(ar, skb->data, skb->len, GFP_ATOMIC);
9448c2ecf20Sopenharmony_ci	if (IS_ERR(tb)) {
9458c2ecf20Sopenharmony_ci		ret = PTR_ERR(tb);
9468c2ecf20Sopenharmony_ci		ath10k_warn(ar, "failed to parse tlv: %d\n", ret);
9478c2ecf20Sopenharmony_ci		return ret;
9488c2ecf20Sopenharmony_ci	}
9498c2ecf20Sopenharmony_ci
9508c2ecf20Sopenharmony_ci	ev = tb[WMI_TLV_TAG_STRUCT_MGMT_RX_HDR];
9518c2ecf20Sopenharmony_ci	frame = tb[WMI_TLV_TAG_ARRAY_BYTE];
9528c2ecf20Sopenharmony_ci
9538c2ecf20Sopenharmony_ci	if (!ev || !frame) {
9548c2ecf20Sopenharmony_ci		kfree(tb);
9558c2ecf20Sopenharmony_ci		return -EPROTO;
9568c2ecf20Sopenharmony_ci	}
9578c2ecf20Sopenharmony_ci
9588c2ecf20Sopenharmony_ci	arg->channel = ev->channel;
9598c2ecf20Sopenharmony_ci	arg->buf_len = ev->buf_len;
9608c2ecf20Sopenharmony_ci	arg->status = ev->status;
9618c2ecf20Sopenharmony_ci	arg->snr = ev->snr;
9628c2ecf20Sopenharmony_ci	arg->phy_mode = ev->phy_mode;
9638c2ecf20Sopenharmony_ci	arg->rate = ev->rate;
9648c2ecf20Sopenharmony_ci
9658c2ecf20Sopenharmony_ci	for (i = 0; i < ARRAY_SIZE(ev->rssi); i++)
9668c2ecf20Sopenharmony_ci		arg->rssi[i] = ev->rssi[i];
9678c2ecf20Sopenharmony_ci
9688c2ecf20Sopenharmony_ci	msdu_len = __le32_to_cpu(arg->buf_len);
9698c2ecf20Sopenharmony_ci
9708c2ecf20Sopenharmony_ci	if (skb->len < (frame - skb->data) + msdu_len) {
9718c2ecf20Sopenharmony_ci		kfree(tb);
9728c2ecf20Sopenharmony_ci		return -EPROTO;
9738c2ecf20Sopenharmony_ci	}
9748c2ecf20Sopenharmony_ci
9758c2ecf20Sopenharmony_ci	/* shift the sk_buff to point to `frame` */
9768c2ecf20Sopenharmony_ci	skb_trim(skb, 0);
9778c2ecf20Sopenharmony_ci	skb_put(skb, frame - skb->data);
9788c2ecf20Sopenharmony_ci	skb_pull(skb, frame - skb->data);
9798c2ecf20Sopenharmony_ci	skb_put(skb, msdu_len);
9808c2ecf20Sopenharmony_ci
9818c2ecf20Sopenharmony_ci	kfree(tb);
9828c2ecf20Sopenharmony_ci	return 0;
9838c2ecf20Sopenharmony_ci}
9848c2ecf20Sopenharmony_ci
9858c2ecf20Sopenharmony_cistatic int ath10k_wmi_tlv_op_pull_ch_info_ev(struct ath10k *ar,
9868c2ecf20Sopenharmony_ci					     struct sk_buff *skb,
9878c2ecf20Sopenharmony_ci					     struct wmi_ch_info_ev_arg *arg)
9888c2ecf20Sopenharmony_ci{
9898c2ecf20Sopenharmony_ci	const void **tb;
9908c2ecf20Sopenharmony_ci	const struct wmi_tlv_chan_info_event *ev;
9918c2ecf20Sopenharmony_ci	int ret;
9928c2ecf20Sopenharmony_ci
9938c2ecf20Sopenharmony_ci	tb = ath10k_wmi_tlv_parse_alloc(ar, skb->data, skb->len, GFP_ATOMIC);
9948c2ecf20Sopenharmony_ci	if (IS_ERR(tb)) {
9958c2ecf20Sopenharmony_ci		ret = PTR_ERR(tb);
9968c2ecf20Sopenharmony_ci		ath10k_warn(ar, "failed to parse tlv: %d\n", ret);
9978c2ecf20Sopenharmony_ci		return ret;
9988c2ecf20Sopenharmony_ci	}
9998c2ecf20Sopenharmony_ci
10008c2ecf20Sopenharmony_ci	ev = tb[WMI_TLV_TAG_STRUCT_CHAN_INFO_EVENT];
10018c2ecf20Sopenharmony_ci	if (!ev) {
10028c2ecf20Sopenharmony_ci		kfree(tb);
10038c2ecf20Sopenharmony_ci		return -EPROTO;
10048c2ecf20Sopenharmony_ci	}
10058c2ecf20Sopenharmony_ci
10068c2ecf20Sopenharmony_ci	arg->err_code = ev->err_code;
10078c2ecf20Sopenharmony_ci	arg->freq = ev->freq;
10088c2ecf20Sopenharmony_ci	arg->cmd_flags = ev->cmd_flags;
10098c2ecf20Sopenharmony_ci	arg->noise_floor = ev->noise_floor;
10108c2ecf20Sopenharmony_ci	arg->rx_clear_count = ev->rx_clear_count;
10118c2ecf20Sopenharmony_ci	arg->cycle_count = ev->cycle_count;
10128c2ecf20Sopenharmony_ci	if (test_bit(ATH10K_FW_FEATURE_SINGLE_CHAN_INFO_PER_CHANNEL,
10138c2ecf20Sopenharmony_ci		     ar->running_fw->fw_file.fw_features))
10148c2ecf20Sopenharmony_ci		arg->mac_clk_mhz = ev->mac_clk_mhz;
10158c2ecf20Sopenharmony_ci
10168c2ecf20Sopenharmony_ci	kfree(tb);
10178c2ecf20Sopenharmony_ci	return 0;
10188c2ecf20Sopenharmony_ci}
10198c2ecf20Sopenharmony_ci
10208c2ecf20Sopenharmony_cistatic int
10218c2ecf20Sopenharmony_ciath10k_wmi_tlv_op_pull_vdev_start_ev(struct ath10k *ar, struct sk_buff *skb,
10228c2ecf20Sopenharmony_ci				     struct wmi_vdev_start_ev_arg *arg)
10238c2ecf20Sopenharmony_ci{
10248c2ecf20Sopenharmony_ci	const void **tb;
10258c2ecf20Sopenharmony_ci	const struct wmi_vdev_start_response_event *ev;
10268c2ecf20Sopenharmony_ci	int ret;
10278c2ecf20Sopenharmony_ci
10288c2ecf20Sopenharmony_ci	tb = ath10k_wmi_tlv_parse_alloc(ar, skb->data, skb->len, GFP_ATOMIC);
10298c2ecf20Sopenharmony_ci	if (IS_ERR(tb)) {
10308c2ecf20Sopenharmony_ci		ret = PTR_ERR(tb);
10318c2ecf20Sopenharmony_ci		ath10k_warn(ar, "failed to parse tlv: %d\n", ret);
10328c2ecf20Sopenharmony_ci		return ret;
10338c2ecf20Sopenharmony_ci	}
10348c2ecf20Sopenharmony_ci
10358c2ecf20Sopenharmony_ci	ev = tb[WMI_TLV_TAG_STRUCT_VDEV_START_RESPONSE_EVENT];
10368c2ecf20Sopenharmony_ci	if (!ev) {
10378c2ecf20Sopenharmony_ci		kfree(tb);
10388c2ecf20Sopenharmony_ci		return -EPROTO;
10398c2ecf20Sopenharmony_ci	}
10408c2ecf20Sopenharmony_ci
10418c2ecf20Sopenharmony_ci	skb_pull(skb, sizeof(*ev));
10428c2ecf20Sopenharmony_ci	arg->vdev_id = ev->vdev_id;
10438c2ecf20Sopenharmony_ci	arg->req_id = ev->req_id;
10448c2ecf20Sopenharmony_ci	arg->resp_type = ev->resp_type;
10458c2ecf20Sopenharmony_ci	arg->status = ev->status;
10468c2ecf20Sopenharmony_ci
10478c2ecf20Sopenharmony_ci	kfree(tb);
10488c2ecf20Sopenharmony_ci	return 0;
10498c2ecf20Sopenharmony_ci}
10508c2ecf20Sopenharmony_ci
10518c2ecf20Sopenharmony_cistatic int ath10k_wmi_tlv_op_pull_peer_kick_ev(struct ath10k *ar,
10528c2ecf20Sopenharmony_ci					       struct sk_buff *skb,
10538c2ecf20Sopenharmony_ci					       struct wmi_peer_kick_ev_arg *arg)
10548c2ecf20Sopenharmony_ci{
10558c2ecf20Sopenharmony_ci	const void **tb;
10568c2ecf20Sopenharmony_ci	const struct wmi_peer_sta_kickout_event *ev;
10578c2ecf20Sopenharmony_ci	int ret;
10588c2ecf20Sopenharmony_ci
10598c2ecf20Sopenharmony_ci	tb = ath10k_wmi_tlv_parse_alloc(ar, skb->data, skb->len, GFP_ATOMIC);
10608c2ecf20Sopenharmony_ci	if (IS_ERR(tb)) {
10618c2ecf20Sopenharmony_ci		ret = PTR_ERR(tb);
10628c2ecf20Sopenharmony_ci		ath10k_warn(ar, "failed to parse tlv: %d\n", ret);
10638c2ecf20Sopenharmony_ci		return ret;
10648c2ecf20Sopenharmony_ci	}
10658c2ecf20Sopenharmony_ci
10668c2ecf20Sopenharmony_ci	ev = tb[WMI_TLV_TAG_STRUCT_PEER_STA_KICKOUT_EVENT];
10678c2ecf20Sopenharmony_ci	if (!ev) {
10688c2ecf20Sopenharmony_ci		kfree(tb);
10698c2ecf20Sopenharmony_ci		return -EPROTO;
10708c2ecf20Sopenharmony_ci	}
10718c2ecf20Sopenharmony_ci
10728c2ecf20Sopenharmony_ci	arg->mac_addr = ev->peer_macaddr.addr;
10738c2ecf20Sopenharmony_ci
10748c2ecf20Sopenharmony_ci	kfree(tb);
10758c2ecf20Sopenharmony_ci	return 0;
10768c2ecf20Sopenharmony_ci}
10778c2ecf20Sopenharmony_ci
10788c2ecf20Sopenharmony_cistruct wmi_tlv_swba_parse {
10798c2ecf20Sopenharmony_ci	const struct wmi_host_swba_event *ev;
10808c2ecf20Sopenharmony_ci	bool tim_done;
10818c2ecf20Sopenharmony_ci	bool noa_done;
10828c2ecf20Sopenharmony_ci	size_t n_tim;
10838c2ecf20Sopenharmony_ci	size_t n_noa;
10848c2ecf20Sopenharmony_ci	struct wmi_swba_ev_arg *arg;
10858c2ecf20Sopenharmony_ci};
10868c2ecf20Sopenharmony_ci
10878c2ecf20Sopenharmony_cistatic int ath10k_wmi_tlv_swba_tim_parse(struct ath10k *ar, u16 tag, u16 len,
10888c2ecf20Sopenharmony_ci					 const void *ptr, void *data)
10898c2ecf20Sopenharmony_ci{
10908c2ecf20Sopenharmony_ci	struct wmi_tlv_swba_parse *swba = data;
10918c2ecf20Sopenharmony_ci	struct wmi_tim_info_arg *tim_info_arg;
10928c2ecf20Sopenharmony_ci	const struct wmi_tim_info *tim_info_ev = ptr;
10938c2ecf20Sopenharmony_ci
10948c2ecf20Sopenharmony_ci	if (tag != WMI_TLV_TAG_STRUCT_TIM_INFO)
10958c2ecf20Sopenharmony_ci		return -EPROTO;
10968c2ecf20Sopenharmony_ci
10978c2ecf20Sopenharmony_ci	if (swba->n_tim >= ARRAY_SIZE(swba->arg->tim_info))
10988c2ecf20Sopenharmony_ci		return -ENOBUFS;
10998c2ecf20Sopenharmony_ci
11008c2ecf20Sopenharmony_ci	if (__le32_to_cpu(tim_info_ev->tim_len) >
11018c2ecf20Sopenharmony_ci	     sizeof(tim_info_ev->tim_bitmap)) {
11028c2ecf20Sopenharmony_ci		ath10k_warn(ar, "refusing to parse invalid swba structure\n");
11038c2ecf20Sopenharmony_ci		return -EPROTO;
11048c2ecf20Sopenharmony_ci	}
11058c2ecf20Sopenharmony_ci
11068c2ecf20Sopenharmony_ci	tim_info_arg = &swba->arg->tim_info[swba->n_tim];
11078c2ecf20Sopenharmony_ci	tim_info_arg->tim_len = tim_info_ev->tim_len;
11088c2ecf20Sopenharmony_ci	tim_info_arg->tim_mcast = tim_info_ev->tim_mcast;
11098c2ecf20Sopenharmony_ci	tim_info_arg->tim_bitmap = tim_info_ev->tim_bitmap;
11108c2ecf20Sopenharmony_ci	tim_info_arg->tim_changed = tim_info_ev->tim_changed;
11118c2ecf20Sopenharmony_ci	tim_info_arg->tim_num_ps_pending = tim_info_ev->tim_num_ps_pending;
11128c2ecf20Sopenharmony_ci
11138c2ecf20Sopenharmony_ci	swba->n_tim++;
11148c2ecf20Sopenharmony_ci
11158c2ecf20Sopenharmony_ci	return 0;
11168c2ecf20Sopenharmony_ci}
11178c2ecf20Sopenharmony_ci
11188c2ecf20Sopenharmony_cistatic int ath10k_wmi_tlv_swba_noa_parse(struct ath10k *ar, u16 tag, u16 len,
11198c2ecf20Sopenharmony_ci					 const void *ptr, void *data)
11208c2ecf20Sopenharmony_ci{
11218c2ecf20Sopenharmony_ci	struct wmi_tlv_swba_parse *swba = data;
11228c2ecf20Sopenharmony_ci
11238c2ecf20Sopenharmony_ci	if (tag != WMI_TLV_TAG_STRUCT_P2P_NOA_INFO)
11248c2ecf20Sopenharmony_ci		return -EPROTO;
11258c2ecf20Sopenharmony_ci
11268c2ecf20Sopenharmony_ci	if (swba->n_noa >= ARRAY_SIZE(swba->arg->noa_info))
11278c2ecf20Sopenharmony_ci		return -ENOBUFS;
11288c2ecf20Sopenharmony_ci
11298c2ecf20Sopenharmony_ci	swba->arg->noa_info[swba->n_noa++] = ptr;
11308c2ecf20Sopenharmony_ci	return 0;
11318c2ecf20Sopenharmony_ci}
11328c2ecf20Sopenharmony_ci
11338c2ecf20Sopenharmony_cistatic int ath10k_wmi_tlv_swba_parse(struct ath10k *ar, u16 tag, u16 len,
11348c2ecf20Sopenharmony_ci				     const void *ptr, void *data)
11358c2ecf20Sopenharmony_ci{
11368c2ecf20Sopenharmony_ci	struct wmi_tlv_swba_parse *swba = data;
11378c2ecf20Sopenharmony_ci	int ret;
11388c2ecf20Sopenharmony_ci
11398c2ecf20Sopenharmony_ci	switch (tag) {
11408c2ecf20Sopenharmony_ci	case WMI_TLV_TAG_STRUCT_HOST_SWBA_EVENT:
11418c2ecf20Sopenharmony_ci		swba->ev = ptr;
11428c2ecf20Sopenharmony_ci		break;
11438c2ecf20Sopenharmony_ci	case WMI_TLV_TAG_ARRAY_STRUCT:
11448c2ecf20Sopenharmony_ci		if (!swba->tim_done) {
11458c2ecf20Sopenharmony_ci			swba->tim_done = true;
11468c2ecf20Sopenharmony_ci			ret = ath10k_wmi_tlv_iter(ar, ptr, len,
11478c2ecf20Sopenharmony_ci						  ath10k_wmi_tlv_swba_tim_parse,
11488c2ecf20Sopenharmony_ci						  swba);
11498c2ecf20Sopenharmony_ci			if (ret)
11508c2ecf20Sopenharmony_ci				return ret;
11518c2ecf20Sopenharmony_ci		} else if (!swba->noa_done) {
11528c2ecf20Sopenharmony_ci			swba->noa_done = true;
11538c2ecf20Sopenharmony_ci			ret = ath10k_wmi_tlv_iter(ar, ptr, len,
11548c2ecf20Sopenharmony_ci						  ath10k_wmi_tlv_swba_noa_parse,
11558c2ecf20Sopenharmony_ci						  swba);
11568c2ecf20Sopenharmony_ci			if (ret)
11578c2ecf20Sopenharmony_ci				return ret;
11588c2ecf20Sopenharmony_ci		}
11598c2ecf20Sopenharmony_ci		break;
11608c2ecf20Sopenharmony_ci	default:
11618c2ecf20Sopenharmony_ci		break;
11628c2ecf20Sopenharmony_ci	}
11638c2ecf20Sopenharmony_ci	return 0;
11648c2ecf20Sopenharmony_ci}
11658c2ecf20Sopenharmony_ci
11668c2ecf20Sopenharmony_cistatic int ath10k_wmi_tlv_op_pull_swba_ev(struct ath10k *ar,
11678c2ecf20Sopenharmony_ci					  struct sk_buff *skb,
11688c2ecf20Sopenharmony_ci					  struct wmi_swba_ev_arg *arg)
11698c2ecf20Sopenharmony_ci{
11708c2ecf20Sopenharmony_ci	struct wmi_tlv_swba_parse swba = { .arg = arg };
11718c2ecf20Sopenharmony_ci	u32 map;
11728c2ecf20Sopenharmony_ci	size_t n_vdevs;
11738c2ecf20Sopenharmony_ci	int ret;
11748c2ecf20Sopenharmony_ci
11758c2ecf20Sopenharmony_ci	ret = ath10k_wmi_tlv_iter(ar, skb->data, skb->len,
11768c2ecf20Sopenharmony_ci				  ath10k_wmi_tlv_swba_parse, &swba);
11778c2ecf20Sopenharmony_ci	if (ret) {
11788c2ecf20Sopenharmony_ci		ath10k_warn(ar, "failed to parse tlv: %d\n", ret);
11798c2ecf20Sopenharmony_ci		return ret;
11808c2ecf20Sopenharmony_ci	}
11818c2ecf20Sopenharmony_ci
11828c2ecf20Sopenharmony_ci	if (!swba.ev)
11838c2ecf20Sopenharmony_ci		return -EPROTO;
11848c2ecf20Sopenharmony_ci
11858c2ecf20Sopenharmony_ci	arg->vdev_map = swba.ev->vdev_map;
11868c2ecf20Sopenharmony_ci
11878c2ecf20Sopenharmony_ci	for (map = __le32_to_cpu(arg->vdev_map), n_vdevs = 0; map; map >>= 1)
11888c2ecf20Sopenharmony_ci		if (map & BIT(0))
11898c2ecf20Sopenharmony_ci			n_vdevs++;
11908c2ecf20Sopenharmony_ci
11918c2ecf20Sopenharmony_ci	if (n_vdevs != swba.n_tim ||
11928c2ecf20Sopenharmony_ci	    n_vdevs != swba.n_noa)
11938c2ecf20Sopenharmony_ci		return -EPROTO;
11948c2ecf20Sopenharmony_ci
11958c2ecf20Sopenharmony_ci	return 0;
11968c2ecf20Sopenharmony_ci}
11978c2ecf20Sopenharmony_ci
11988c2ecf20Sopenharmony_cistatic int ath10k_wmi_tlv_op_pull_phyerr_ev_hdr(struct ath10k *ar,
11998c2ecf20Sopenharmony_ci						struct sk_buff *skb,
12008c2ecf20Sopenharmony_ci						struct wmi_phyerr_hdr_arg *arg)
12018c2ecf20Sopenharmony_ci{
12028c2ecf20Sopenharmony_ci	const void **tb;
12038c2ecf20Sopenharmony_ci	const struct wmi_tlv_phyerr_ev *ev;
12048c2ecf20Sopenharmony_ci	const void *phyerrs;
12058c2ecf20Sopenharmony_ci	int ret;
12068c2ecf20Sopenharmony_ci
12078c2ecf20Sopenharmony_ci	tb = ath10k_wmi_tlv_parse_alloc(ar, skb->data, skb->len, GFP_ATOMIC);
12088c2ecf20Sopenharmony_ci	if (IS_ERR(tb)) {
12098c2ecf20Sopenharmony_ci		ret = PTR_ERR(tb);
12108c2ecf20Sopenharmony_ci		ath10k_warn(ar, "failed to parse tlv: %d\n", ret);
12118c2ecf20Sopenharmony_ci		return ret;
12128c2ecf20Sopenharmony_ci	}
12138c2ecf20Sopenharmony_ci
12148c2ecf20Sopenharmony_ci	ev = tb[WMI_TLV_TAG_STRUCT_COMB_PHYERR_RX_HDR];
12158c2ecf20Sopenharmony_ci	phyerrs = tb[WMI_TLV_TAG_ARRAY_BYTE];
12168c2ecf20Sopenharmony_ci
12178c2ecf20Sopenharmony_ci	if (!ev || !phyerrs) {
12188c2ecf20Sopenharmony_ci		kfree(tb);
12198c2ecf20Sopenharmony_ci		return -EPROTO;
12208c2ecf20Sopenharmony_ci	}
12218c2ecf20Sopenharmony_ci
12228c2ecf20Sopenharmony_ci	arg->num_phyerrs  = __le32_to_cpu(ev->num_phyerrs);
12238c2ecf20Sopenharmony_ci	arg->tsf_l32 = __le32_to_cpu(ev->tsf_l32);
12248c2ecf20Sopenharmony_ci	arg->tsf_u32 = __le32_to_cpu(ev->tsf_u32);
12258c2ecf20Sopenharmony_ci	arg->buf_len = __le32_to_cpu(ev->buf_len);
12268c2ecf20Sopenharmony_ci	arg->phyerrs = phyerrs;
12278c2ecf20Sopenharmony_ci
12288c2ecf20Sopenharmony_ci	kfree(tb);
12298c2ecf20Sopenharmony_ci	return 0;
12308c2ecf20Sopenharmony_ci}
12318c2ecf20Sopenharmony_ci
12328c2ecf20Sopenharmony_ci#define WMI_TLV_ABI_VER_NS0 0x5F414351
12338c2ecf20Sopenharmony_ci#define WMI_TLV_ABI_VER_NS1 0x00004C4D
12348c2ecf20Sopenharmony_ci#define WMI_TLV_ABI_VER_NS2 0x00000000
12358c2ecf20Sopenharmony_ci#define WMI_TLV_ABI_VER_NS3 0x00000000
12368c2ecf20Sopenharmony_ci
12378c2ecf20Sopenharmony_ci#define WMI_TLV_ABI_VER0_MAJOR 1
12388c2ecf20Sopenharmony_ci#define WMI_TLV_ABI_VER0_MINOR 0
12398c2ecf20Sopenharmony_ci#define WMI_TLV_ABI_VER0 ((((WMI_TLV_ABI_VER0_MAJOR) << 24) & 0xFF000000) | \
12408c2ecf20Sopenharmony_ci			  (((WMI_TLV_ABI_VER0_MINOR) <<  0) & 0x00FFFFFF))
12418c2ecf20Sopenharmony_ci#define WMI_TLV_ABI_VER1 53
12428c2ecf20Sopenharmony_ci
12438c2ecf20Sopenharmony_cistatic int
12448c2ecf20Sopenharmony_ciath10k_wmi_tlv_parse_mem_reqs(struct ath10k *ar, u16 tag, u16 len,
12458c2ecf20Sopenharmony_ci			      const void *ptr, void *data)
12468c2ecf20Sopenharmony_ci{
12478c2ecf20Sopenharmony_ci	struct wmi_svc_rdy_ev_arg *arg = data;
12488c2ecf20Sopenharmony_ci	int i;
12498c2ecf20Sopenharmony_ci
12508c2ecf20Sopenharmony_ci	if (tag != WMI_TLV_TAG_STRUCT_WLAN_HOST_MEM_REQ)
12518c2ecf20Sopenharmony_ci		return -EPROTO;
12528c2ecf20Sopenharmony_ci
12538c2ecf20Sopenharmony_ci	for (i = 0; i < ARRAY_SIZE(arg->mem_reqs); i++) {
12548c2ecf20Sopenharmony_ci		if (!arg->mem_reqs[i]) {
12558c2ecf20Sopenharmony_ci			arg->mem_reqs[i] = ptr;
12568c2ecf20Sopenharmony_ci			return 0;
12578c2ecf20Sopenharmony_ci		}
12588c2ecf20Sopenharmony_ci	}
12598c2ecf20Sopenharmony_ci
12608c2ecf20Sopenharmony_ci	return -ENOMEM;
12618c2ecf20Sopenharmony_ci}
12628c2ecf20Sopenharmony_ci
12638c2ecf20Sopenharmony_cistruct wmi_tlv_svc_rdy_parse {
12648c2ecf20Sopenharmony_ci	const struct hal_reg_capabilities *reg;
12658c2ecf20Sopenharmony_ci	const struct wmi_tlv_svc_rdy_ev *ev;
12668c2ecf20Sopenharmony_ci	const __le32 *svc_bmap;
12678c2ecf20Sopenharmony_ci	const struct wlan_host_mem_req *mem_reqs;
12688c2ecf20Sopenharmony_ci	bool svc_bmap_done;
12698c2ecf20Sopenharmony_ci	bool dbs_hw_mode_done;
12708c2ecf20Sopenharmony_ci};
12718c2ecf20Sopenharmony_ci
12728c2ecf20Sopenharmony_cistatic int ath10k_wmi_tlv_svc_rdy_parse(struct ath10k *ar, u16 tag, u16 len,
12738c2ecf20Sopenharmony_ci					const void *ptr, void *data)
12748c2ecf20Sopenharmony_ci{
12758c2ecf20Sopenharmony_ci	struct wmi_tlv_svc_rdy_parse *svc_rdy = data;
12768c2ecf20Sopenharmony_ci
12778c2ecf20Sopenharmony_ci	switch (tag) {
12788c2ecf20Sopenharmony_ci	case WMI_TLV_TAG_STRUCT_SERVICE_READY_EVENT:
12798c2ecf20Sopenharmony_ci		svc_rdy->ev = ptr;
12808c2ecf20Sopenharmony_ci		break;
12818c2ecf20Sopenharmony_ci	case WMI_TLV_TAG_STRUCT_HAL_REG_CAPABILITIES:
12828c2ecf20Sopenharmony_ci		svc_rdy->reg = ptr;
12838c2ecf20Sopenharmony_ci		break;
12848c2ecf20Sopenharmony_ci	case WMI_TLV_TAG_ARRAY_STRUCT:
12858c2ecf20Sopenharmony_ci		svc_rdy->mem_reqs = ptr;
12868c2ecf20Sopenharmony_ci		break;
12878c2ecf20Sopenharmony_ci	case WMI_TLV_TAG_ARRAY_UINT32:
12888c2ecf20Sopenharmony_ci		if (!svc_rdy->svc_bmap_done) {
12898c2ecf20Sopenharmony_ci			svc_rdy->svc_bmap_done = true;
12908c2ecf20Sopenharmony_ci			svc_rdy->svc_bmap = ptr;
12918c2ecf20Sopenharmony_ci		} else if (!svc_rdy->dbs_hw_mode_done) {
12928c2ecf20Sopenharmony_ci			svc_rdy->dbs_hw_mode_done = true;
12938c2ecf20Sopenharmony_ci		}
12948c2ecf20Sopenharmony_ci		break;
12958c2ecf20Sopenharmony_ci	default:
12968c2ecf20Sopenharmony_ci		break;
12978c2ecf20Sopenharmony_ci	}
12988c2ecf20Sopenharmony_ci	return 0;
12998c2ecf20Sopenharmony_ci}
13008c2ecf20Sopenharmony_ci
13018c2ecf20Sopenharmony_cistatic int ath10k_wmi_tlv_op_pull_svc_rdy_ev(struct ath10k *ar,
13028c2ecf20Sopenharmony_ci					     struct sk_buff *skb,
13038c2ecf20Sopenharmony_ci					     struct wmi_svc_rdy_ev_arg *arg)
13048c2ecf20Sopenharmony_ci{
13058c2ecf20Sopenharmony_ci	const struct hal_reg_capabilities *reg;
13068c2ecf20Sopenharmony_ci	const struct wmi_tlv_svc_rdy_ev *ev;
13078c2ecf20Sopenharmony_ci	const __le32 *svc_bmap;
13088c2ecf20Sopenharmony_ci	const struct wlan_host_mem_req *mem_reqs;
13098c2ecf20Sopenharmony_ci	struct wmi_tlv_svc_rdy_parse svc_rdy = { };
13108c2ecf20Sopenharmony_ci	int ret;
13118c2ecf20Sopenharmony_ci
13128c2ecf20Sopenharmony_ci	ret = ath10k_wmi_tlv_iter(ar, skb->data, skb->len,
13138c2ecf20Sopenharmony_ci				  ath10k_wmi_tlv_svc_rdy_parse, &svc_rdy);
13148c2ecf20Sopenharmony_ci	if (ret) {
13158c2ecf20Sopenharmony_ci		ath10k_warn(ar, "failed to parse tlv: %d\n", ret);
13168c2ecf20Sopenharmony_ci		return ret;
13178c2ecf20Sopenharmony_ci	}
13188c2ecf20Sopenharmony_ci
13198c2ecf20Sopenharmony_ci	ev = svc_rdy.ev;
13208c2ecf20Sopenharmony_ci	reg = svc_rdy.reg;
13218c2ecf20Sopenharmony_ci	svc_bmap = svc_rdy.svc_bmap;
13228c2ecf20Sopenharmony_ci	mem_reqs = svc_rdy.mem_reqs;
13238c2ecf20Sopenharmony_ci
13248c2ecf20Sopenharmony_ci	if (!ev || !reg || !svc_bmap || !mem_reqs)
13258c2ecf20Sopenharmony_ci		return -EPROTO;
13268c2ecf20Sopenharmony_ci
13278c2ecf20Sopenharmony_ci	/* This is an internal ABI compatibility check for WMI TLV so check it
13288c2ecf20Sopenharmony_ci	 * here instead of the generic WMI code.
13298c2ecf20Sopenharmony_ci	 */
13308c2ecf20Sopenharmony_ci	ath10k_dbg(ar, ATH10K_DBG_WMI,
13318c2ecf20Sopenharmony_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",
13328c2ecf20Sopenharmony_ci		   __le32_to_cpu(ev->abi.abi_ver0), WMI_TLV_ABI_VER0,
13338c2ecf20Sopenharmony_ci		   __le32_to_cpu(ev->abi.abi_ver_ns0), WMI_TLV_ABI_VER_NS0,
13348c2ecf20Sopenharmony_ci		   __le32_to_cpu(ev->abi.abi_ver_ns1), WMI_TLV_ABI_VER_NS1,
13358c2ecf20Sopenharmony_ci		   __le32_to_cpu(ev->abi.abi_ver_ns2), WMI_TLV_ABI_VER_NS2,
13368c2ecf20Sopenharmony_ci		   __le32_to_cpu(ev->abi.abi_ver_ns3), WMI_TLV_ABI_VER_NS3);
13378c2ecf20Sopenharmony_ci
13388c2ecf20Sopenharmony_ci	if (__le32_to_cpu(ev->abi.abi_ver0) != WMI_TLV_ABI_VER0 ||
13398c2ecf20Sopenharmony_ci	    __le32_to_cpu(ev->abi.abi_ver_ns0) != WMI_TLV_ABI_VER_NS0 ||
13408c2ecf20Sopenharmony_ci	    __le32_to_cpu(ev->abi.abi_ver_ns1) != WMI_TLV_ABI_VER_NS1 ||
13418c2ecf20Sopenharmony_ci	    __le32_to_cpu(ev->abi.abi_ver_ns2) != WMI_TLV_ABI_VER_NS2 ||
13428c2ecf20Sopenharmony_ci	    __le32_to_cpu(ev->abi.abi_ver_ns3) != WMI_TLV_ABI_VER_NS3) {
13438c2ecf20Sopenharmony_ci		return -ENOTSUPP;
13448c2ecf20Sopenharmony_ci	}
13458c2ecf20Sopenharmony_ci
13468c2ecf20Sopenharmony_ci	arg->min_tx_power = ev->hw_min_tx_power;
13478c2ecf20Sopenharmony_ci	arg->max_tx_power = ev->hw_max_tx_power;
13488c2ecf20Sopenharmony_ci	arg->ht_cap = ev->ht_cap_info;
13498c2ecf20Sopenharmony_ci	arg->vht_cap = ev->vht_cap_info;
13508c2ecf20Sopenharmony_ci	arg->vht_supp_mcs = ev->vht_supp_mcs;
13518c2ecf20Sopenharmony_ci	arg->sw_ver0 = ev->abi.abi_ver0;
13528c2ecf20Sopenharmony_ci	arg->sw_ver1 = ev->abi.abi_ver1;
13538c2ecf20Sopenharmony_ci	arg->fw_build = ev->fw_build_vers;
13548c2ecf20Sopenharmony_ci	arg->phy_capab = ev->phy_capability;
13558c2ecf20Sopenharmony_ci	arg->num_rf_chains = ev->num_rf_chains;
13568c2ecf20Sopenharmony_ci	arg->eeprom_rd = reg->eeprom_rd;
13578c2ecf20Sopenharmony_ci	arg->low_2ghz_chan = reg->low_2ghz_chan;
13588c2ecf20Sopenharmony_ci	arg->high_2ghz_chan = reg->high_2ghz_chan;
13598c2ecf20Sopenharmony_ci	arg->low_5ghz_chan = reg->low_5ghz_chan;
13608c2ecf20Sopenharmony_ci	arg->high_5ghz_chan = reg->high_5ghz_chan;
13618c2ecf20Sopenharmony_ci	arg->num_mem_reqs = ev->num_mem_reqs;
13628c2ecf20Sopenharmony_ci	arg->service_map = svc_bmap;
13638c2ecf20Sopenharmony_ci	arg->service_map_len = ath10k_wmi_tlv_len(svc_bmap);
13648c2ecf20Sopenharmony_ci	arg->sys_cap_info = ev->sys_cap_info;
13658c2ecf20Sopenharmony_ci
13668c2ecf20Sopenharmony_ci	ret = ath10k_wmi_tlv_iter(ar, mem_reqs, ath10k_wmi_tlv_len(mem_reqs),
13678c2ecf20Sopenharmony_ci				  ath10k_wmi_tlv_parse_mem_reqs, arg);
13688c2ecf20Sopenharmony_ci	if (ret) {
13698c2ecf20Sopenharmony_ci		ath10k_warn(ar, "failed to parse mem_reqs tlv: %d\n", ret);
13708c2ecf20Sopenharmony_ci		return ret;
13718c2ecf20Sopenharmony_ci	}
13728c2ecf20Sopenharmony_ci
13738c2ecf20Sopenharmony_ci	return 0;
13748c2ecf20Sopenharmony_ci}
13758c2ecf20Sopenharmony_ci
13768c2ecf20Sopenharmony_cistatic int ath10k_wmi_tlv_op_pull_rdy_ev(struct ath10k *ar,
13778c2ecf20Sopenharmony_ci					 struct sk_buff *skb,
13788c2ecf20Sopenharmony_ci					 struct wmi_rdy_ev_arg *arg)
13798c2ecf20Sopenharmony_ci{
13808c2ecf20Sopenharmony_ci	const void **tb;
13818c2ecf20Sopenharmony_ci	const struct wmi_tlv_rdy_ev *ev;
13828c2ecf20Sopenharmony_ci	int ret;
13838c2ecf20Sopenharmony_ci
13848c2ecf20Sopenharmony_ci	tb = ath10k_wmi_tlv_parse_alloc(ar, skb->data, skb->len, GFP_ATOMIC);
13858c2ecf20Sopenharmony_ci	if (IS_ERR(tb)) {
13868c2ecf20Sopenharmony_ci		ret = PTR_ERR(tb);
13878c2ecf20Sopenharmony_ci		ath10k_warn(ar, "failed to parse tlv: %d\n", ret);
13888c2ecf20Sopenharmony_ci		return ret;
13898c2ecf20Sopenharmony_ci	}
13908c2ecf20Sopenharmony_ci
13918c2ecf20Sopenharmony_ci	ev = tb[WMI_TLV_TAG_STRUCT_READY_EVENT];
13928c2ecf20Sopenharmony_ci	if (!ev) {
13938c2ecf20Sopenharmony_ci		kfree(tb);
13948c2ecf20Sopenharmony_ci		return -EPROTO;
13958c2ecf20Sopenharmony_ci	}
13968c2ecf20Sopenharmony_ci
13978c2ecf20Sopenharmony_ci	arg->sw_version = ev->abi.abi_ver0;
13988c2ecf20Sopenharmony_ci	arg->abi_version = ev->abi.abi_ver1;
13998c2ecf20Sopenharmony_ci	arg->status = ev->status;
14008c2ecf20Sopenharmony_ci	arg->mac_addr = ev->mac_addr.addr;
14018c2ecf20Sopenharmony_ci
14028c2ecf20Sopenharmony_ci	kfree(tb);
14038c2ecf20Sopenharmony_ci	return 0;
14048c2ecf20Sopenharmony_ci}
14058c2ecf20Sopenharmony_ci
14068c2ecf20Sopenharmony_cistatic int ath10k_wmi_tlv_svc_avail_parse(struct ath10k *ar, u16 tag, u16 len,
14078c2ecf20Sopenharmony_ci					  const void *ptr, void *data)
14088c2ecf20Sopenharmony_ci{
14098c2ecf20Sopenharmony_ci	struct wmi_svc_avail_ev_arg *arg = data;
14108c2ecf20Sopenharmony_ci
14118c2ecf20Sopenharmony_ci	switch (tag) {
14128c2ecf20Sopenharmony_ci	case WMI_TLV_TAG_STRUCT_SERVICE_AVAILABLE_EVENT:
14138c2ecf20Sopenharmony_ci		arg->service_map_ext_valid = true;
14148c2ecf20Sopenharmony_ci		arg->service_map_ext_len = *(__le32 *)ptr;
14158c2ecf20Sopenharmony_ci		arg->service_map_ext = ptr + sizeof(__le32);
14168c2ecf20Sopenharmony_ci		return 0;
14178c2ecf20Sopenharmony_ci	default:
14188c2ecf20Sopenharmony_ci		break;
14198c2ecf20Sopenharmony_ci	}
14208c2ecf20Sopenharmony_ci
14218c2ecf20Sopenharmony_ci	return 0;
14228c2ecf20Sopenharmony_ci}
14238c2ecf20Sopenharmony_ci
14248c2ecf20Sopenharmony_cistatic int ath10k_wmi_tlv_op_pull_svc_avail(struct ath10k *ar,
14258c2ecf20Sopenharmony_ci					    struct sk_buff *skb,
14268c2ecf20Sopenharmony_ci					    struct wmi_svc_avail_ev_arg *arg)
14278c2ecf20Sopenharmony_ci{
14288c2ecf20Sopenharmony_ci	int ret;
14298c2ecf20Sopenharmony_ci
14308c2ecf20Sopenharmony_ci	ret = ath10k_wmi_tlv_iter(ar, skb->data, skb->len,
14318c2ecf20Sopenharmony_ci				  ath10k_wmi_tlv_svc_avail_parse, arg);
14328c2ecf20Sopenharmony_ci
14338c2ecf20Sopenharmony_ci	if (ret) {
14348c2ecf20Sopenharmony_ci		ath10k_warn(ar, "failed to parse svc_avail tlv: %d\n", ret);
14358c2ecf20Sopenharmony_ci		return ret;
14368c2ecf20Sopenharmony_ci	}
14378c2ecf20Sopenharmony_ci
14388c2ecf20Sopenharmony_ci	return 0;
14398c2ecf20Sopenharmony_ci}
14408c2ecf20Sopenharmony_ci
14418c2ecf20Sopenharmony_cistatic void ath10k_wmi_tlv_pull_vdev_stats(const struct wmi_tlv_vdev_stats *src,
14428c2ecf20Sopenharmony_ci					   struct ath10k_fw_stats_vdev *dst)
14438c2ecf20Sopenharmony_ci{
14448c2ecf20Sopenharmony_ci	int i;
14458c2ecf20Sopenharmony_ci
14468c2ecf20Sopenharmony_ci	dst->vdev_id = __le32_to_cpu(src->vdev_id);
14478c2ecf20Sopenharmony_ci	dst->beacon_snr = __le32_to_cpu(src->beacon_snr);
14488c2ecf20Sopenharmony_ci	dst->data_snr = __le32_to_cpu(src->data_snr);
14498c2ecf20Sopenharmony_ci	dst->num_rx_frames = __le32_to_cpu(src->num_rx_frames);
14508c2ecf20Sopenharmony_ci	dst->num_rts_fail = __le32_to_cpu(src->num_rts_fail);
14518c2ecf20Sopenharmony_ci	dst->num_rts_success = __le32_to_cpu(src->num_rts_success);
14528c2ecf20Sopenharmony_ci	dst->num_rx_err = __le32_to_cpu(src->num_rx_err);
14538c2ecf20Sopenharmony_ci	dst->num_rx_discard = __le32_to_cpu(src->num_rx_discard);
14548c2ecf20Sopenharmony_ci	dst->num_tx_not_acked = __le32_to_cpu(src->num_tx_not_acked);
14558c2ecf20Sopenharmony_ci
14568c2ecf20Sopenharmony_ci	for (i = 0; i < ARRAY_SIZE(src->num_tx_frames); i++)
14578c2ecf20Sopenharmony_ci		dst->num_tx_frames[i] =
14588c2ecf20Sopenharmony_ci			__le32_to_cpu(src->num_tx_frames[i]);
14598c2ecf20Sopenharmony_ci
14608c2ecf20Sopenharmony_ci	for (i = 0; i < ARRAY_SIZE(src->num_tx_frames_retries); i++)
14618c2ecf20Sopenharmony_ci		dst->num_tx_frames_retries[i] =
14628c2ecf20Sopenharmony_ci			__le32_to_cpu(src->num_tx_frames_retries[i]);
14638c2ecf20Sopenharmony_ci
14648c2ecf20Sopenharmony_ci	for (i = 0; i < ARRAY_SIZE(src->num_tx_frames_failures); i++)
14658c2ecf20Sopenharmony_ci		dst->num_tx_frames_failures[i] =
14668c2ecf20Sopenharmony_ci			__le32_to_cpu(src->num_tx_frames_failures[i]);
14678c2ecf20Sopenharmony_ci
14688c2ecf20Sopenharmony_ci	for (i = 0; i < ARRAY_SIZE(src->tx_rate_history); i++)
14698c2ecf20Sopenharmony_ci		dst->tx_rate_history[i] =
14708c2ecf20Sopenharmony_ci			__le32_to_cpu(src->tx_rate_history[i]);
14718c2ecf20Sopenharmony_ci
14728c2ecf20Sopenharmony_ci	for (i = 0; i < ARRAY_SIZE(src->beacon_rssi_history); i++)
14738c2ecf20Sopenharmony_ci		dst->beacon_rssi_history[i] =
14748c2ecf20Sopenharmony_ci			__le32_to_cpu(src->beacon_rssi_history[i]);
14758c2ecf20Sopenharmony_ci}
14768c2ecf20Sopenharmony_ci
14778c2ecf20Sopenharmony_cistatic int ath10k_wmi_tlv_op_pull_fw_stats(struct ath10k *ar,
14788c2ecf20Sopenharmony_ci					   struct sk_buff *skb,
14798c2ecf20Sopenharmony_ci					   struct ath10k_fw_stats *stats)
14808c2ecf20Sopenharmony_ci{
14818c2ecf20Sopenharmony_ci	const void **tb;
14828c2ecf20Sopenharmony_ci	const struct wmi_tlv_stats_ev *ev;
14838c2ecf20Sopenharmony_ci	u32 num_peer_stats_extd;
14848c2ecf20Sopenharmony_ci	const void *data;
14858c2ecf20Sopenharmony_ci	u32 num_pdev_stats;
14868c2ecf20Sopenharmony_ci	u32 num_vdev_stats;
14878c2ecf20Sopenharmony_ci	u32 num_peer_stats;
14888c2ecf20Sopenharmony_ci	u32 num_bcnflt_stats;
14898c2ecf20Sopenharmony_ci	u32 num_chan_stats;
14908c2ecf20Sopenharmony_ci	size_t data_len;
14918c2ecf20Sopenharmony_ci	u32 stats_id;
14928c2ecf20Sopenharmony_ci	int ret;
14938c2ecf20Sopenharmony_ci	int i;
14948c2ecf20Sopenharmony_ci
14958c2ecf20Sopenharmony_ci	tb = ath10k_wmi_tlv_parse_alloc(ar, skb->data, skb->len, GFP_ATOMIC);
14968c2ecf20Sopenharmony_ci	if (IS_ERR(tb)) {
14978c2ecf20Sopenharmony_ci		ret = PTR_ERR(tb);
14988c2ecf20Sopenharmony_ci		ath10k_warn(ar, "failed to parse tlv: %d\n", ret);
14998c2ecf20Sopenharmony_ci		return ret;
15008c2ecf20Sopenharmony_ci	}
15018c2ecf20Sopenharmony_ci
15028c2ecf20Sopenharmony_ci	ev = tb[WMI_TLV_TAG_STRUCT_STATS_EVENT];
15038c2ecf20Sopenharmony_ci	data = tb[WMI_TLV_TAG_ARRAY_BYTE];
15048c2ecf20Sopenharmony_ci
15058c2ecf20Sopenharmony_ci	if (!ev || !data) {
15068c2ecf20Sopenharmony_ci		kfree(tb);
15078c2ecf20Sopenharmony_ci		return -EPROTO;
15088c2ecf20Sopenharmony_ci	}
15098c2ecf20Sopenharmony_ci
15108c2ecf20Sopenharmony_ci	data_len = ath10k_wmi_tlv_len(data);
15118c2ecf20Sopenharmony_ci	num_pdev_stats = __le32_to_cpu(ev->num_pdev_stats);
15128c2ecf20Sopenharmony_ci	num_vdev_stats = __le32_to_cpu(ev->num_vdev_stats);
15138c2ecf20Sopenharmony_ci	num_peer_stats = __le32_to_cpu(ev->num_peer_stats);
15148c2ecf20Sopenharmony_ci	num_bcnflt_stats = __le32_to_cpu(ev->num_bcnflt_stats);
15158c2ecf20Sopenharmony_ci	num_chan_stats = __le32_to_cpu(ev->num_chan_stats);
15168c2ecf20Sopenharmony_ci	stats_id = __le32_to_cpu(ev->stats_id);
15178c2ecf20Sopenharmony_ci	num_peer_stats_extd = __le32_to_cpu(ev->num_peer_stats_extd);
15188c2ecf20Sopenharmony_ci
15198c2ecf20Sopenharmony_ci	ath10k_dbg(ar, ATH10K_DBG_WMI,
15208c2ecf20Sopenharmony_ci		   "wmi tlv stats update pdev %i vdev %i peer %i bcnflt %i chan %i peer_extd %i\n",
15218c2ecf20Sopenharmony_ci		   num_pdev_stats, num_vdev_stats, num_peer_stats,
15228c2ecf20Sopenharmony_ci		   num_bcnflt_stats, num_chan_stats, num_peer_stats_extd);
15238c2ecf20Sopenharmony_ci
15248c2ecf20Sopenharmony_ci	for (i = 0; i < num_pdev_stats; i++) {
15258c2ecf20Sopenharmony_ci		const struct wmi_pdev_stats *src;
15268c2ecf20Sopenharmony_ci		struct ath10k_fw_stats_pdev *dst;
15278c2ecf20Sopenharmony_ci
15288c2ecf20Sopenharmony_ci		src = data;
15298c2ecf20Sopenharmony_ci		if (data_len < sizeof(*src)) {
15308c2ecf20Sopenharmony_ci			kfree(tb);
15318c2ecf20Sopenharmony_ci			return -EPROTO;
15328c2ecf20Sopenharmony_ci		}
15338c2ecf20Sopenharmony_ci
15348c2ecf20Sopenharmony_ci		data += sizeof(*src);
15358c2ecf20Sopenharmony_ci		data_len -= sizeof(*src);
15368c2ecf20Sopenharmony_ci
15378c2ecf20Sopenharmony_ci		dst = kzalloc(sizeof(*dst), GFP_ATOMIC);
15388c2ecf20Sopenharmony_ci		if (!dst)
15398c2ecf20Sopenharmony_ci			continue;
15408c2ecf20Sopenharmony_ci
15418c2ecf20Sopenharmony_ci		ath10k_wmi_pull_pdev_stats_base(&src->base, dst);
15428c2ecf20Sopenharmony_ci		ath10k_wmi_pull_pdev_stats_tx(&src->tx, dst);
15438c2ecf20Sopenharmony_ci		ath10k_wmi_pull_pdev_stats_rx(&src->rx, dst);
15448c2ecf20Sopenharmony_ci		list_add_tail(&dst->list, &stats->pdevs);
15458c2ecf20Sopenharmony_ci	}
15468c2ecf20Sopenharmony_ci
15478c2ecf20Sopenharmony_ci	for (i = 0; i < num_vdev_stats; i++) {
15488c2ecf20Sopenharmony_ci		const struct wmi_tlv_vdev_stats *src;
15498c2ecf20Sopenharmony_ci		struct ath10k_fw_stats_vdev *dst;
15508c2ecf20Sopenharmony_ci
15518c2ecf20Sopenharmony_ci		src = data;
15528c2ecf20Sopenharmony_ci		if (data_len < sizeof(*src)) {
15538c2ecf20Sopenharmony_ci			kfree(tb);
15548c2ecf20Sopenharmony_ci			return -EPROTO;
15558c2ecf20Sopenharmony_ci		}
15568c2ecf20Sopenharmony_ci
15578c2ecf20Sopenharmony_ci		data += sizeof(*src);
15588c2ecf20Sopenharmony_ci		data_len -= sizeof(*src);
15598c2ecf20Sopenharmony_ci
15608c2ecf20Sopenharmony_ci		dst = kzalloc(sizeof(*dst), GFP_ATOMIC);
15618c2ecf20Sopenharmony_ci		if (!dst)
15628c2ecf20Sopenharmony_ci			continue;
15638c2ecf20Sopenharmony_ci
15648c2ecf20Sopenharmony_ci		ath10k_wmi_tlv_pull_vdev_stats(src, dst);
15658c2ecf20Sopenharmony_ci		list_add_tail(&dst->list, &stats->vdevs);
15668c2ecf20Sopenharmony_ci	}
15678c2ecf20Sopenharmony_ci
15688c2ecf20Sopenharmony_ci	for (i = 0; i < num_peer_stats; i++) {
15698c2ecf20Sopenharmony_ci		const struct wmi_10x_peer_stats *src;
15708c2ecf20Sopenharmony_ci		struct ath10k_fw_stats_peer *dst;
15718c2ecf20Sopenharmony_ci
15728c2ecf20Sopenharmony_ci		src = data;
15738c2ecf20Sopenharmony_ci		if (data_len < sizeof(*src)) {
15748c2ecf20Sopenharmony_ci			kfree(tb);
15758c2ecf20Sopenharmony_ci			return -EPROTO;
15768c2ecf20Sopenharmony_ci		}
15778c2ecf20Sopenharmony_ci
15788c2ecf20Sopenharmony_ci		data += sizeof(*src);
15798c2ecf20Sopenharmony_ci		data_len -= sizeof(*src);
15808c2ecf20Sopenharmony_ci
15818c2ecf20Sopenharmony_ci		dst = kzalloc(sizeof(*dst), GFP_ATOMIC);
15828c2ecf20Sopenharmony_ci		if (!dst)
15838c2ecf20Sopenharmony_ci			continue;
15848c2ecf20Sopenharmony_ci
15858c2ecf20Sopenharmony_ci		ath10k_wmi_pull_peer_stats(&src->old, dst);
15868c2ecf20Sopenharmony_ci		dst->peer_rx_rate = __le32_to_cpu(src->peer_rx_rate);
15878c2ecf20Sopenharmony_ci
15888c2ecf20Sopenharmony_ci		if (stats_id & WMI_TLV_STAT_PEER_EXTD) {
15898c2ecf20Sopenharmony_ci			const struct wmi_tlv_peer_stats_extd *extd;
15908c2ecf20Sopenharmony_ci			unsigned long rx_duration_high;
15918c2ecf20Sopenharmony_ci
15928c2ecf20Sopenharmony_ci			extd = data + sizeof(*src) * (num_peer_stats - i - 1)
15938c2ecf20Sopenharmony_ci			       + sizeof(*extd) * i;
15948c2ecf20Sopenharmony_ci
15958c2ecf20Sopenharmony_ci			dst->rx_duration = __le32_to_cpu(extd->rx_duration);
15968c2ecf20Sopenharmony_ci			rx_duration_high = __le32_to_cpu
15978c2ecf20Sopenharmony_ci						(extd->rx_duration_high);
15988c2ecf20Sopenharmony_ci
15998c2ecf20Sopenharmony_ci			if (test_bit(WMI_TLV_PEER_RX_DURATION_HIGH_VALID_BIT,
16008c2ecf20Sopenharmony_ci				     &rx_duration_high)) {
16018c2ecf20Sopenharmony_ci				rx_duration_high =
16028c2ecf20Sopenharmony_ci					FIELD_GET(WMI_TLV_PEER_RX_DURATION_HIGH_MASK,
16038c2ecf20Sopenharmony_ci						  rx_duration_high);
16048c2ecf20Sopenharmony_ci				dst->rx_duration |= (u64)rx_duration_high <<
16058c2ecf20Sopenharmony_ci						    WMI_TLV_PEER_RX_DURATION_SHIFT;
16068c2ecf20Sopenharmony_ci			}
16078c2ecf20Sopenharmony_ci		}
16088c2ecf20Sopenharmony_ci
16098c2ecf20Sopenharmony_ci		list_add_tail(&dst->list, &stats->peers);
16108c2ecf20Sopenharmony_ci	}
16118c2ecf20Sopenharmony_ci
16128c2ecf20Sopenharmony_ci	kfree(tb);
16138c2ecf20Sopenharmony_ci	return 0;
16148c2ecf20Sopenharmony_ci}
16158c2ecf20Sopenharmony_ci
16168c2ecf20Sopenharmony_cistatic int ath10k_wmi_tlv_op_pull_roam_ev(struct ath10k *ar,
16178c2ecf20Sopenharmony_ci					  struct sk_buff *skb,
16188c2ecf20Sopenharmony_ci					  struct wmi_roam_ev_arg *arg)
16198c2ecf20Sopenharmony_ci{
16208c2ecf20Sopenharmony_ci	const void **tb;
16218c2ecf20Sopenharmony_ci	const struct wmi_tlv_roam_ev *ev;
16228c2ecf20Sopenharmony_ci	int ret;
16238c2ecf20Sopenharmony_ci
16248c2ecf20Sopenharmony_ci	tb = ath10k_wmi_tlv_parse_alloc(ar, skb->data, skb->len, GFP_ATOMIC);
16258c2ecf20Sopenharmony_ci	if (IS_ERR(tb)) {
16268c2ecf20Sopenharmony_ci		ret = PTR_ERR(tb);
16278c2ecf20Sopenharmony_ci		ath10k_warn(ar, "failed to parse tlv: %d\n", ret);
16288c2ecf20Sopenharmony_ci		return ret;
16298c2ecf20Sopenharmony_ci	}
16308c2ecf20Sopenharmony_ci
16318c2ecf20Sopenharmony_ci	ev = tb[WMI_TLV_TAG_STRUCT_ROAM_EVENT];
16328c2ecf20Sopenharmony_ci	if (!ev) {
16338c2ecf20Sopenharmony_ci		kfree(tb);
16348c2ecf20Sopenharmony_ci		return -EPROTO;
16358c2ecf20Sopenharmony_ci	}
16368c2ecf20Sopenharmony_ci
16378c2ecf20Sopenharmony_ci	arg->vdev_id = ev->vdev_id;
16388c2ecf20Sopenharmony_ci	arg->reason = ev->reason;
16398c2ecf20Sopenharmony_ci	arg->rssi = ev->rssi;
16408c2ecf20Sopenharmony_ci
16418c2ecf20Sopenharmony_ci	kfree(tb);
16428c2ecf20Sopenharmony_ci	return 0;
16438c2ecf20Sopenharmony_ci}
16448c2ecf20Sopenharmony_ci
16458c2ecf20Sopenharmony_cistatic int
16468c2ecf20Sopenharmony_ciath10k_wmi_tlv_op_pull_wow_ev(struct ath10k *ar, struct sk_buff *skb,
16478c2ecf20Sopenharmony_ci			      struct wmi_wow_ev_arg *arg)
16488c2ecf20Sopenharmony_ci{
16498c2ecf20Sopenharmony_ci	const void **tb;
16508c2ecf20Sopenharmony_ci	const struct wmi_tlv_wow_event_info *ev;
16518c2ecf20Sopenharmony_ci	int ret;
16528c2ecf20Sopenharmony_ci
16538c2ecf20Sopenharmony_ci	tb = ath10k_wmi_tlv_parse_alloc(ar, skb->data, skb->len, GFP_ATOMIC);
16548c2ecf20Sopenharmony_ci	if (IS_ERR(tb)) {
16558c2ecf20Sopenharmony_ci		ret = PTR_ERR(tb);
16568c2ecf20Sopenharmony_ci		ath10k_warn(ar, "failed to parse tlv: %d\n", ret);
16578c2ecf20Sopenharmony_ci		return ret;
16588c2ecf20Sopenharmony_ci	}
16598c2ecf20Sopenharmony_ci
16608c2ecf20Sopenharmony_ci	ev = tb[WMI_TLV_TAG_STRUCT_WOW_EVENT_INFO];
16618c2ecf20Sopenharmony_ci	if (!ev) {
16628c2ecf20Sopenharmony_ci		kfree(tb);
16638c2ecf20Sopenharmony_ci		return -EPROTO;
16648c2ecf20Sopenharmony_ci	}
16658c2ecf20Sopenharmony_ci
16668c2ecf20Sopenharmony_ci	arg->vdev_id = __le32_to_cpu(ev->vdev_id);
16678c2ecf20Sopenharmony_ci	arg->flag = __le32_to_cpu(ev->flag);
16688c2ecf20Sopenharmony_ci	arg->wake_reason = __le32_to_cpu(ev->wake_reason);
16698c2ecf20Sopenharmony_ci	arg->data_len = __le32_to_cpu(ev->data_len);
16708c2ecf20Sopenharmony_ci
16718c2ecf20Sopenharmony_ci	kfree(tb);
16728c2ecf20Sopenharmony_ci	return 0;
16738c2ecf20Sopenharmony_ci}
16748c2ecf20Sopenharmony_ci
16758c2ecf20Sopenharmony_cistatic int ath10k_wmi_tlv_op_pull_echo_ev(struct ath10k *ar,
16768c2ecf20Sopenharmony_ci					  struct sk_buff *skb,
16778c2ecf20Sopenharmony_ci					  struct wmi_echo_ev_arg *arg)
16788c2ecf20Sopenharmony_ci{
16798c2ecf20Sopenharmony_ci	const void **tb;
16808c2ecf20Sopenharmony_ci	const struct wmi_echo_event *ev;
16818c2ecf20Sopenharmony_ci	int ret;
16828c2ecf20Sopenharmony_ci
16838c2ecf20Sopenharmony_ci	tb = ath10k_wmi_tlv_parse_alloc(ar, skb->data, skb->len, GFP_ATOMIC);
16848c2ecf20Sopenharmony_ci	if (IS_ERR(tb)) {
16858c2ecf20Sopenharmony_ci		ret = PTR_ERR(tb);
16868c2ecf20Sopenharmony_ci		ath10k_warn(ar, "failed to parse tlv: %d\n", ret);
16878c2ecf20Sopenharmony_ci		return ret;
16888c2ecf20Sopenharmony_ci	}
16898c2ecf20Sopenharmony_ci
16908c2ecf20Sopenharmony_ci	ev = tb[WMI_TLV_TAG_STRUCT_ECHO_EVENT];
16918c2ecf20Sopenharmony_ci	if (!ev) {
16928c2ecf20Sopenharmony_ci		kfree(tb);
16938c2ecf20Sopenharmony_ci		return -EPROTO;
16948c2ecf20Sopenharmony_ci	}
16958c2ecf20Sopenharmony_ci
16968c2ecf20Sopenharmony_ci	arg->value = ev->value;
16978c2ecf20Sopenharmony_ci
16988c2ecf20Sopenharmony_ci	kfree(tb);
16998c2ecf20Sopenharmony_ci	return 0;
17008c2ecf20Sopenharmony_ci}
17018c2ecf20Sopenharmony_ci
17028c2ecf20Sopenharmony_cistatic struct sk_buff *
17038c2ecf20Sopenharmony_ciath10k_wmi_tlv_op_gen_pdev_suspend(struct ath10k *ar, u32 opt)
17048c2ecf20Sopenharmony_ci{
17058c2ecf20Sopenharmony_ci	struct wmi_tlv_pdev_suspend *cmd;
17068c2ecf20Sopenharmony_ci	struct wmi_tlv *tlv;
17078c2ecf20Sopenharmony_ci	struct sk_buff *skb;
17088c2ecf20Sopenharmony_ci
17098c2ecf20Sopenharmony_ci	skb = ath10k_wmi_alloc_skb(ar, sizeof(*tlv) + sizeof(*cmd));
17108c2ecf20Sopenharmony_ci	if (!skb)
17118c2ecf20Sopenharmony_ci		return ERR_PTR(-ENOMEM);
17128c2ecf20Sopenharmony_ci
17138c2ecf20Sopenharmony_ci	tlv = (void *)skb->data;
17148c2ecf20Sopenharmony_ci	tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_PDEV_SUSPEND_CMD);
17158c2ecf20Sopenharmony_ci	tlv->len = __cpu_to_le16(sizeof(*cmd));
17168c2ecf20Sopenharmony_ci	cmd = (void *)tlv->value;
17178c2ecf20Sopenharmony_ci	cmd->opt = __cpu_to_le32(opt);
17188c2ecf20Sopenharmony_ci
17198c2ecf20Sopenharmony_ci	ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv pdev suspend\n");
17208c2ecf20Sopenharmony_ci	return skb;
17218c2ecf20Sopenharmony_ci}
17228c2ecf20Sopenharmony_ci
17238c2ecf20Sopenharmony_cistatic struct sk_buff *
17248c2ecf20Sopenharmony_ciath10k_wmi_tlv_op_gen_pdev_resume(struct ath10k *ar)
17258c2ecf20Sopenharmony_ci{
17268c2ecf20Sopenharmony_ci	struct wmi_tlv_resume_cmd *cmd;
17278c2ecf20Sopenharmony_ci	struct wmi_tlv *tlv;
17288c2ecf20Sopenharmony_ci	struct sk_buff *skb;
17298c2ecf20Sopenharmony_ci
17308c2ecf20Sopenharmony_ci	skb = ath10k_wmi_alloc_skb(ar, sizeof(*tlv) + sizeof(*cmd));
17318c2ecf20Sopenharmony_ci	if (!skb)
17328c2ecf20Sopenharmony_ci		return ERR_PTR(-ENOMEM);
17338c2ecf20Sopenharmony_ci
17348c2ecf20Sopenharmony_ci	tlv = (void *)skb->data;
17358c2ecf20Sopenharmony_ci	tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_PDEV_RESUME_CMD);
17368c2ecf20Sopenharmony_ci	tlv->len = __cpu_to_le16(sizeof(*cmd));
17378c2ecf20Sopenharmony_ci	cmd = (void *)tlv->value;
17388c2ecf20Sopenharmony_ci	cmd->reserved = __cpu_to_le32(0);
17398c2ecf20Sopenharmony_ci
17408c2ecf20Sopenharmony_ci	ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv pdev resume\n");
17418c2ecf20Sopenharmony_ci	return skb;
17428c2ecf20Sopenharmony_ci}
17438c2ecf20Sopenharmony_ci
17448c2ecf20Sopenharmony_cistatic struct sk_buff *
17458c2ecf20Sopenharmony_ciath10k_wmi_tlv_op_gen_pdev_set_rd(struct ath10k *ar,
17468c2ecf20Sopenharmony_ci				  u16 rd, u16 rd2g, u16 rd5g,
17478c2ecf20Sopenharmony_ci				  u16 ctl2g, u16 ctl5g,
17488c2ecf20Sopenharmony_ci				  enum wmi_dfs_region dfs_reg)
17498c2ecf20Sopenharmony_ci{
17508c2ecf20Sopenharmony_ci	struct wmi_tlv_pdev_set_rd_cmd *cmd;
17518c2ecf20Sopenharmony_ci	struct wmi_tlv *tlv;
17528c2ecf20Sopenharmony_ci	struct sk_buff *skb;
17538c2ecf20Sopenharmony_ci
17548c2ecf20Sopenharmony_ci	skb = ath10k_wmi_alloc_skb(ar, sizeof(*tlv) + sizeof(*cmd));
17558c2ecf20Sopenharmony_ci	if (!skb)
17568c2ecf20Sopenharmony_ci		return ERR_PTR(-ENOMEM);
17578c2ecf20Sopenharmony_ci
17588c2ecf20Sopenharmony_ci	tlv = (void *)skb->data;
17598c2ecf20Sopenharmony_ci	tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_PDEV_SET_REGDOMAIN_CMD);
17608c2ecf20Sopenharmony_ci	tlv->len = __cpu_to_le16(sizeof(*cmd));
17618c2ecf20Sopenharmony_ci	cmd = (void *)tlv->value;
17628c2ecf20Sopenharmony_ci	cmd->regd = __cpu_to_le32(rd);
17638c2ecf20Sopenharmony_ci	cmd->regd_2ghz = __cpu_to_le32(rd2g);
17648c2ecf20Sopenharmony_ci	cmd->regd_5ghz = __cpu_to_le32(rd5g);
17658c2ecf20Sopenharmony_ci	cmd->conform_limit_2ghz = __cpu_to_le32(ctl2g);
17668c2ecf20Sopenharmony_ci	cmd->conform_limit_5ghz = __cpu_to_le32(ctl5g);
17678c2ecf20Sopenharmony_ci
17688c2ecf20Sopenharmony_ci	ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv pdev set rd\n");
17698c2ecf20Sopenharmony_ci	return skb;
17708c2ecf20Sopenharmony_ci}
17718c2ecf20Sopenharmony_ci
17728c2ecf20Sopenharmony_cistatic enum wmi_txbf_conf ath10k_wmi_tlv_txbf_conf_scheme(struct ath10k *ar)
17738c2ecf20Sopenharmony_ci{
17748c2ecf20Sopenharmony_ci	return WMI_TXBF_CONF_AFTER_ASSOC;
17758c2ecf20Sopenharmony_ci}
17768c2ecf20Sopenharmony_ci
17778c2ecf20Sopenharmony_cistatic struct sk_buff *
17788c2ecf20Sopenharmony_ciath10k_wmi_tlv_op_gen_pdev_set_param(struct ath10k *ar, u32 param_id,
17798c2ecf20Sopenharmony_ci				     u32 param_value)
17808c2ecf20Sopenharmony_ci{
17818c2ecf20Sopenharmony_ci	struct wmi_tlv_pdev_set_param_cmd *cmd;
17828c2ecf20Sopenharmony_ci	struct wmi_tlv *tlv;
17838c2ecf20Sopenharmony_ci	struct sk_buff *skb;
17848c2ecf20Sopenharmony_ci
17858c2ecf20Sopenharmony_ci	skb = ath10k_wmi_alloc_skb(ar, sizeof(*tlv) + sizeof(*cmd));
17868c2ecf20Sopenharmony_ci	if (!skb)
17878c2ecf20Sopenharmony_ci		return ERR_PTR(-ENOMEM);
17888c2ecf20Sopenharmony_ci
17898c2ecf20Sopenharmony_ci	tlv = (void *)skb->data;
17908c2ecf20Sopenharmony_ci	tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_PDEV_SET_PARAM_CMD);
17918c2ecf20Sopenharmony_ci	tlv->len = __cpu_to_le16(sizeof(*cmd));
17928c2ecf20Sopenharmony_ci	cmd = (void *)tlv->value;
17938c2ecf20Sopenharmony_ci	cmd->param_id = __cpu_to_le32(param_id);
17948c2ecf20Sopenharmony_ci	cmd->param_value = __cpu_to_le32(param_value);
17958c2ecf20Sopenharmony_ci
17968c2ecf20Sopenharmony_ci	ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv pdev set param %d value 0x%x\n",
17978c2ecf20Sopenharmony_ci		   param_id, param_value);
17988c2ecf20Sopenharmony_ci	return skb;
17998c2ecf20Sopenharmony_ci}
18008c2ecf20Sopenharmony_ci
18018c2ecf20Sopenharmony_cistatic void
18028c2ecf20Sopenharmony_ciath10k_wmi_tlv_put_host_mem_chunks(struct ath10k *ar, void *host_mem_chunks)
18038c2ecf20Sopenharmony_ci{
18048c2ecf20Sopenharmony_ci	struct host_memory_chunk_tlv *chunk;
18058c2ecf20Sopenharmony_ci	struct wmi_tlv *tlv;
18068c2ecf20Sopenharmony_ci	dma_addr_t paddr;
18078c2ecf20Sopenharmony_ci	int i;
18088c2ecf20Sopenharmony_ci	__le16 tlv_len, tlv_tag;
18098c2ecf20Sopenharmony_ci
18108c2ecf20Sopenharmony_ci	tlv_tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_WLAN_HOST_MEMORY_CHUNK);
18118c2ecf20Sopenharmony_ci	tlv_len = __cpu_to_le16(sizeof(*chunk));
18128c2ecf20Sopenharmony_ci	for (i = 0; i < ar->wmi.num_mem_chunks; i++) {
18138c2ecf20Sopenharmony_ci		tlv = host_mem_chunks;
18148c2ecf20Sopenharmony_ci		tlv->tag = tlv_tag;
18158c2ecf20Sopenharmony_ci		tlv->len = tlv_len;
18168c2ecf20Sopenharmony_ci		chunk = (void *)tlv->value;
18178c2ecf20Sopenharmony_ci
18188c2ecf20Sopenharmony_ci		chunk->ptr = __cpu_to_le32(ar->wmi.mem_chunks[i].paddr);
18198c2ecf20Sopenharmony_ci		chunk->size = __cpu_to_le32(ar->wmi.mem_chunks[i].len);
18208c2ecf20Sopenharmony_ci		chunk->req_id = __cpu_to_le32(ar->wmi.mem_chunks[i].req_id);
18218c2ecf20Sopenharmony_ci
18228c2ecf20Sopenharmony_ci		if (test_bit(WMI_SERVICE_SUPPORT_EXTEND_ADDRESS,
18238c2ecf20Sopenharmony_ci			     ar->wmi.svc_map)) {
18248c2ecf20Sopenharmony_ci			paddr = ar->wmi.mem_chunks[i].paddr;
18258c2ecf20Sopenharmony_ci			chunk->ptr_high = __cpu_to_le32(upper_32_bits(paddr));
18268c2ecf20Sopenharmony_ci		}
18278c2ecf20Sopenharmony_ci
18288c2ecf20Sopenharmony_ci		ath10k_dbg(ar, ATH10K_DBG_WMI,
18298c2ecf20Sopenharmony_ci			   "wmi-tlv chunk %d len %d, addr 0x%llx, id 0x%x\n",
18308c2ecf20Sopenharmony_ci			   i,
18318c2ecf20Sopenharmony_ci			   ar->wmi.mem_chunks[i].len,
18328c2ecf20Sopenharmony_ci			   (unsigned long long)ar->wmi.mem_chunks[i].paddr,
18338c2ecf20Sopenharmony_ci			   ar->wmi.mem_chunks[i].req_id);
18348c2ecf20Sopenharmony_ci
18358c2ecf20Sopenharmony_ci		host_mem_chunks += sizeof(*tlv);
18368c2ecf20Sopenharmony_ci		host_mem_chunks += sizeof(*chunk);
18378c2ecf20Sopenharmony_ci	}
18388c2ecf20Sopenharmony_ci}
18398c2ecf20Sopenharmony_ci
18408c2ecf20Sopenharmony_cistatic struct sk_buff *ath10k_wmi_tlv_op_gen_init(struct ath10k *ar)
18418c2ecf20Sopenharmony_ci{
18428c2ecf20Sopenharmony_ci	struct sk_buff *skb;
18438c2ecf20Sopenharmony_ci	struct wmi_tlv *tlv;
18448c2ecf20Sopenharmony_ci	struct wmi_tlv_init_cmd *cmd;
18458c2ecf20Sopenharmony_ci	struct wmi_tlv_resource_config *cfg;
18468c2ecf20Sopenharmony_ci	void *chunks;
18478c2ecf20Sopenharmony_ci	size_t len, chunks_len;
18488c2ecf20Sopenharmony_ci	void *ptr;
18498c2ecf20Sopenharmony_ci
18508c2ecf20Sopenharmony_ci	chunks_len = ar->wmi.num_mem_chunks *
18518c2ecf20Sopenharmony_ci		     (sizeof(struct host_memory_chunk_tlv) + sizeof(*tlv));
18528c2ecf20Sopenharmony_ci	len = (sizeof(*tlv) + sizeof(*cmd)) +
18538c2ecf20Sopenharmony_ci	      (sizeof(*tlv) + sizeof(*cfg)) +
18548c2ecf20Sopenharmony_ci	      (sizeof(*tlv) + chunks_len);
18558c2ecf20Sopenharmony_ci
18568c2ecf20Sopenharmony_ci	skb = ath10k_wmi_alloc_skb(ar, len);
18578c2ecf20Sopenharmony_ci	if (!skb)
18588c2ecf20Sopenharmony_ci		return ERR_PTR(-ENOMEM);
18598c2ecf20Sopenharmony_ci
18608c2ecf20Sopenharmony_ci	ptr = skb->data;
18618c2ecf20Sopenharmony_ci
18628c2ecf20Sopenharmony_ci	tlv = ptr;
18638c2ecf20Sopenharmony_ci	tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_INIT_CMD);
18648c2ecf20Sopenharmony_ci	tlv->len = __cpu_to_le16(sizeof(*cmd));
18658c2ecf20Sopenharmony_ci	cmd = (void *)tlv->value;
18668c2ecf20Sopenharmony_ci	ptr += sizeof(*tlv);
18678c2ecf20Sopenharmony_ci	ptr += sizeof(*cmd);
18688c2ecf20Sopenharmony_ci
18698c2ecf20Sopenharmony_ci	tlv = ptr;
18708c2ecf20Sopenharmony_ci	tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_RESOURCE_CONFIG);
18718c2ecf20Sopenharmony_ci	tlv->len = __cpu_to_le16(sizeof(*cfg));
18728c2ecf20Sopenharmony_ci	cfg = (void *)tlv->value;
18738c2ecf20Sopenharmony_ci	ptr += sizeof(*tlv);
18748c2ecf20Sopenharmony_ci	ptr += sizeof(*cfg);
18758c2ecf20Sopenharmony_ci
18768c2ecf20Sopenharmony_ci	tlv = ptr;
18778c2ecf20Sopenharmony_ci	tlv->tag = __cpu_to_le16(WMI_TLV_TAG_ARRAY_STRUCT);
18788c2ecf20Sopenharmony_ci	tlv->len = __cpu_to_le16(chunks_len);
18798c2ecf20Sopenharmony_ci	chunks = (void *)tlv->value;
18808c2ecf20Sopenharmony_ci
18818c2ecf20Sopenharmony_ci	ptr += sizeof(*tlv);
18828c2ecf20Sopenharmony_ci	ptr += chunks_len;
18838c2ecf20Sopenharmony_ci
18848c2ecf20Sopenharmony_ci	cmd->abi.abi_ver0 = __cpu_to_le32(WMI_TLV_ABI_VER0);
18858c2ecf20Sopenharmony_ci	cmd->abi.abi_ver1 = __cpu_to_le32(WMI_TLV_ABI_VER1);
18868c2ecf20Sopenharmony_ci	cmd->abi.abi_ver_ns0 = __cpu_to_le32(WMI_TLV_ABI_VER_NS0);
18878c2ecf20Sopenharmony_ci	cmd->abi.abi_ver_ns1 = __cpu_to_le32(WMI_TLV_ABI_VER_NS1);
18888c2ecf20Sopenharmony_ci	cmd->abi.abi_ver_ns2 = __cpu_to_le32(WMI_TLV_ABI_VER_NS2);
18898c2ecf20Sopenharmony_ci	cmd->abi.abi_ver_ns3 = __cpu_to_le32(WMI_TLV_ABI_VER_NS3);
18908c2ecf20Sopenharmony_ci	cmd->num_host_mem_chunks = __cpu_to_le32(ar->wmi.num_mem_chunks);
18918c2ecf20Sopenharmony_ci
18928c2ecf20Sopenharmony_ci	cfg->num_vdevs = __cpu_to_le32(TARGET_TLV_NUM_VDEVS);
18938c2ecf20Sopenharmony_ci
18948c2ecf20Sopenharmony_ci	if (ar->hw_params.num_peers)
18958c2ecf20Sopenharmony_ci		cfg->num_peers = __cpu_to_le32(ar->hw_params.num_peers);
18968c2ecf20Sopenharmony_ci	else
18978c2ecf20Sopenharmony_ci		cfg->num_peers = __cpu_to_le32(TARGET_TLV_NUM_PEERS);
18988c2ecf20Sopenharmony_ci	cfg->ast_skid_limit = __cpu_to_le32(ar->hw_params.ast_skid_limit);
18998c2ecf20Sopenharmony_ci	cfg->num_wds_entries = __cpu_to_le32(ar->hw_params.num_wds_entries);
19008c2ecf20Sopenharmony_ci
19018c2ecf20Sopenharmony_ci	if (test_bit(WMI_SERVICE_RX_FULL_REORDER, ar->wmi.svc_map)) {
19028c2ecf20Sopenharmony_ci		cfg->num_offload_peers = __cpu_to_le32(TARGET_TLV_NUM_VDEVS);
19038c2ecf20Sopenharmony_ci		cfg->num_offload_reorder_bufs = __cpu_to_le32(TARGET_TLV_NUM_VDEVS);
19048c2ecf20Sopenharmony_ci	} else {
19058c2ecf20Sopenharmony_ci		cfg->num_offload_peers = __cpu_to_le32(0);
19068c2ecf20Sopenharmony_ci		cfg->num_offload_reorder_bufs = __cpu_to_le32(0);
19078c2ecf20Sopenharmony_ci	}
19088c2ecf20Sopenharmony_ci
19098c2ecf20Sopenharmony_ci	cfg->num_peer_keys = __cpu_to_le32(2);
19108c2ecf20Sopenharmony_ci	if (ar->hw_params.num_peers)
19118c2ecf20Sopenharmony_ci		cfg->num_tids = __cpu_to_le32(ar->hw_params.num_peers * 2);
19128c2ecf20Sopenharmony_ci	else
19138c2ecf20Sopenharmony_ci		cfg->num_tids = __cpu_to_le32(TARGET_TLV_NUM_TIDS);
19148c2ecf20Sopenharmony_ci	cfg->tx_chain_mask = __cpu_to_le32(0x7);
19158c2ecf20Sopenharmony_ci	cfg->rx_chain_mask = __cpu_to_le32(0x7);
19168c2ecf20Sopenharmony_ci	cfg->rx_timeout_pri[0] = __cpu_to_le32(0x64);
19178c2ecf20Sopenharmony_ci	cfg->rx_timeout_pri[1] = __cpu_to_le32(0x64);
19188c2ecf20Sopenharmony_ci	cfg->rx_timeout_pri[2] = __cpu_to_le32(0x64);
19198c2ecf20Sopenharmony_ci	cfg->rx_timeout_pri[3] = __cpu_to_le32(0x28);
19208c2ecf20Sopenharmony_ci	cfg->rx_decap_mode = __cpu_to_le32(ar->wmi.rx_decap_mode);
19218c2ecf20Sopenharmony_ci	cfg->scan_max_pending_reqs = __cpu_to_le32(4);
19228c2ecf20Sopenharmony_ci	cfg->bmiss_offload_max_vdev = __cpu_to_le32(TARGET_TLV_NUM_VDEVS);
19238c2ecf20Sopenharmony_ci	cfg->roam_offload_max_vdev = __cpu_to_le32(TARGET_TLV_NUM_VDEVS);
19248c2ecf20Sopenharmony_ci	cfg->roam_offload_max_ap_profiles = __cpu_to_le32(8);
19258c2ecf20Sopenharmony_ci	cfg->num_mcast_groups = __cpu_to_le32(0);
19268c2ecf20Sopenharmony_ci	cfg->num_mcast_table_elems = __cpu_to_le32(0);
19278c2ecf20Sopenharmony_ci	cfg->mcast2ucast_mode = __cpu_to_le32(0);
19288c2ecf20Sopenharmony_ci	cfg->tx_dbg_log_size = __cpu_to_le32(0x400);
19298c2ecf20Sopenharmony_ci	cfg->dma_burst_size = __cpu_to_le32(0);
19308c2ecf20Sopenharmony_ci	cfg->mac_aggr_delim = __cpu_to_le32(0);
19318c2ecf20Sopenharmony_ci	cfg->rx_skip_defrag_timeout_dup_detection_check = __cpu_to_le32(0);
19328c2ecf20Sopenharmony_ci	cfg->vow_config = __cpu_to_le32(0);
19338c2ecf20Sopenharmony_ci	cfg->gtk_offload_max_vdev = __cpu_to_le32(2);
19348c2ecf20Sopenharmony_ci	cfg->num_msdu_desc = __cpu_to_le32(ar->htt.max_num_pending_tx);
19358c2ecf20Sopenharmony_ci	cfg->max_frag_entries = __cpu_to_le32(2);
19368c2ecf20Sopenharmony_ci	cfg->num_tdls_vdevs = __cpu_to_le32(TARGET_TLV_NUM_TDLS_VDEVS);
19378c2ecf20Sopenharmony_ci	cfg->num_tdls_conn_table_entries = __cpu_to_le32(0x20);
19388c2ecf20Sopenharmony_ci	cfg->beacon_tx_offload_max_vdev = __cpu_to_le32(2);
19398c2ecf20Sopenharmony_ci	cfg->num_multicast_filter_entries = __cpu_to_le32(5);
19408c2ecf20Sopenharmony_ci	cfg->num_wow_filters = __cpu_to_le32(ar->wow.max_num_patterns);
19418c2ecf20Sopenharmony_ci	cfg->num_keep_alive_pattern = __cpu_to_le32(6);
19428c2ecf20Sopenharmony_ci	cfg->keep_alive_pattern_size = __cpu_to_le32(0);
19438c2ecf20Sopenharmony_ci	cfg->max_tdls_concurrent_sleep_sta = __cpu_to_le32(1);
19448c2ecf20Sopenharmony_ci	cfg->max_tdls_concurrent_buffer_sta = __cpu_to_le32(1);
19458c2ecf20Sopenharmony_ci	cfg->wmi_send_separate = __cpu_to_le32(0);
19468c2ecf20Sopenharmony_ci	cfg->num_ocb_vdevs = __cpu_to_le32(0);
19478c2ecf20Sopenharmony_ci	cfg->num_ocb_channels = __cpu_to_le32(0);
19488c2ecf20Sopenharmony_ci	cfg->num_ocb_schedules = __cpu_to_le32(0);
19498c2ecf20Sopenharmony_ci	cfg->host_capab = __cpu_to_le32(WMI_TLV_FLAG_MGMT_BUNDLE_TX_COMPL);
19508c2ecf20Sopenharmony_ci
19518c2ecf20Sopenharmony_ci	if (test_bit(WMI_SERVICE_TX_DATA_ACK_RSSI, ar->wmi.svc_map))
19528c2ecf20Sopenharmony_ci		cfg->host_capab |= __cpu_to_le32(WMI_RSRC_CFG_FLAG_TX_ACK_RSSI);
19538c2ecf20Sopenharmony_ci
19548c2ecf20Sopenharmony_ci	ath10k_wmi_tlv_put_host_mem_chunks(ar, chunks);
19558c2ecf20Sopenharmony_ci
19568c2ecf20Sopenharmony_ci	ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv init\n");
19578c2ecf20Sopenharmony_ci	return skb;
19588c2ecf20Sopenharmony_ci}
19598c2ecf20Sopenharmony_ci
19608c2ecf20Sopenharmony_cistatic struct sk_buff *
19618c2ecf20Sopenharmony_ciath10k_wmi_tlv_op_gen_start_scan(struct ath10k *ar,
19628c2ecf20Sopenharmony_ci				 const struct wmi_start_scan_arg *arg)
19638c2ecf20Sopenharmony_ci{
19648c2ecf20Sopenharmony_ci	struct wmi_tlv_start_scan_cmd *cmd;
19658c2ecf20Sopenharmony_ci	struct wmi_tlv *tlv;
19668c2ecf20Sopenharmony_ci	struct sk_buff *skb;
19678c2ecf20Sopenharmony_ci	size_t len, chan_len, ssid_len, bssid_len, ie_len;
19688c2ecf20Sopenharmony_ci	__le32 *chans;
19698c2ecf20Sopenharmony_ci	struct wmi_ssid *ssids;
19708c2ecf20Sopenharmony_ci	struct wmi_mac_addr *addrs;
19718c2ecf20Sopenharmony_ci	void *ptr;
19728c2ecf20Sopenharmony_ci	int i, ret;
19738c2ecf20Sopenharmony_ci
19748c2ecf20Sopenharmony_ci	ret = ath10k_wmi_start_scan_verify(arg);
19758c2ecf20Sopenharmony_ci	if (ret)
19768c2ecf20Sopenharmony_ci		return ERR_PTR(ret);
19778c2ecf20Sopenharmony_ci
19788c2ecf20Sopenharmony_ci	chan_len = arg->n_channels * sizeof(__le32);
19798c2ecf20Sopenharmony_ci	ssid_len = arg->n_ssids * sizeof(struct wmi_ssid);
19808c2ecf20Sopenharmony_ci	bssid_len = arg->n_bssids * sizeof(struct wmi_mac_addr);
19818c2ecf20Sopenharmony_ci	ie_len = roundup(arg->ie_len, 4);
19828c2ecf20Sopenharmony_ci	len = (sizeof(*tlv) + sizeof(*cmd)) +
19838c2ecf20Sopenharmony_ci	      sizeof(*tlv) + chan_len +
19848c2ecf20Sopenharmony_ci	      sizeof(*tlv) + ssid_len +
19858c2ecf20Sopenharmony_ci	      sizeof(*tlv) + bssid_len +
19868c2ecf20Sopenharmony_ci	      sizeof(*tlv) + ie_len;
19878c2ecf20Sopenharmony_ci
19888c2ecf20Sopenharmony_ci	skb = ath10k_wmi_alloc_skb(ar, len);
19898c2ecf20Sopenharmony_ci	if (!skb)
19908c2ecf20Sopenharmony_ci		return ERR_PTR(-ENOMEM);
19918c2ecf20Sopenharmony_ci
19928c2ecf20Sopenharmony_ci	ptr = (void *)skb->data;
19938c2ecf20Sopenharmony_ci	tlv = ptr;
19948c2ecf20Sopenharmony_ci	tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_START_SCAN_CMD);
19958c2ecf20Sopenharmony_ci	tlv->len = __cpu_to_le16(sizeof(*cmd));
19968c2ecf20Sopenharmony_ci	cmd = (void *)tlv->value;
19978c2ecf20Sopenharmony_ci
19988c2ecf20Sopenharmony_ci	ath10k_wmi_put_start_scan_common(&cmd->common, arg);
19998c2ecf20Sopenharmony_ci	cmd->burst_duration_ms = __cpu_to_le32(arg->burst_duration_ms);
20008c2ecf20Sopenharmony_ci	cmd->num_channels = __cpu_to_le32(arg->n_channels);
20018c2ecf20Sopenharmony_ci	cmd->num_ssids = __cpu_to_le32(arg->n_ssids);
20028c2ecf20Sopenharmony_ci	cmd->num_bssids = __cpu_to_le32(arg->n_bssids);
20038c2ecf20Sopenharmony_ci	cmd->ie_len = __cpu_to_le32(arg->ie_len);
20048c2ecf20Sopenharmony_ci	cmd->num_probes = __cpu_to_le32(3);
20058c2ecf20Sopenharmony_ci	ether_addr_copy(cmd->mac_addr.addr, arg->mac_addr.addr);
20068c2ecf20Sopenharmony_ci	ether_addr_copy(cmd->mac_mask.addr, arg->mac_mask.addr);
20078c2ecf20Sopenharmony_ci
20088c2ecf20Sopenharmony_ci	/* FIXME: There are some scan flag inconsistencies across firmwares,
20098c2ecf20Sopenharmony_ci	 * e.g. WMI-TLV inverts the logic behind the following flag.
20108c2ecf20Sopenharmony_ci	 */
20118c2ecf20Sopenharmony_ci	cmd->common.scan_ctrl_flags ^= __cpu_to_le32(WMI_SCAN_FILTER_PROBE_REQ);
20128c2ecf20Sopenharmony_ci
20138c2ecf20Sopenharmony_ci	ptr += sizeof(*tlv);
20148c2ecf20Sopenharmony_ci	ptr += sizeof(*cmd);
20158c2ecf20Sopenharmony_ci
20168c2ecf20Sopenharmony_ci	tlv = ptr;
20178c2ecf20Sopenharmony_ci	tlv->tag = __cpu_to_le16(WMI_TLV_TAG_ARRAY_UINT32);
20188c2ecf20Sopenharmony_ci	tlv->len = __cpu_to_le16(chan_len);
20198c2ecf20Sopenharmony_ci	chans = (void *)tlv->value;
20208c2ecf20Sopenharmony_ci	for (i = 0; i < arg->n_channels; i++)
20218c2ecf20Sopenharmony_ci		chans[i] = __cpu_to_le32(arg->channels[i]);
20228c2ecf20Sopenharmony_ci
20238c2ecf20Sopenharmony_ci	ptr += sizeof(*tlv);
20248c2ecf20Sopenharmony_ci	ptr += chan_len;
20258c2ecf20Sopenharmony_ci
20268c2ecf20Sopenharmony_ci	tlv = ptr;
20278c2ecf20Sopenharmony_ci	tlv->tag = __cpu_to_le16(WMI_TLV_TAG_ARRAY_FIXED_STRUCT);
20288c2ecf20Sopenharmony_ci	tlv->len = __cpu_to_le16(ssid_len);
20298c2ecf20Sopenharmony_ci	ssids = (void *)tlv->value;
20308c2ecf20Sopenharmony_ci	for (i = 0; i < arg->n_ssids; i++) {
20318c2ecf20Sopenharmony_ci		ssids[i].ssid_len = __cpu_to_le32(arg->ssids[i].len);
20328c2ecf20Sopenharmony_ci		memcpy(ssids[i].ssid, arg->ssids[i].ssid, arg->ssids[i].len);
20338c2ecf20Sopenharmony_ci	}
20348c2ecf20Sopenharmony_ci
20358c2ecf20Sopenharmony_ci	ptr += sizeof(*tlv);
20368c2ecf20Sopenharmony_ci	ptr += ssid_len;
20378c2ecf20Sopenharmony_ci
20388c2ecf20Sopenharmony_ci	tlv = ptr;
20398c2ecf20Sopenharmony_ci	tlv->tag = __cpu_to_le16(WMI_TLV_TAG_ARRAY_FIXED_STRUCT);
20408c2ecf20Sopenharmony_ci	tlv->len = __cpu_to_le16(bssid_len);
20418c2ecf20Sopenharmony_ci	addrs = (void *)tlv->value;
20428c2ecf20Sopenharmony_ci	for (i = 0; i < arg->n_bssids; i++)
20438c2ecf20Sopenharmony_ci		ether_addr_copy(addrs[i].addr, arg->bssids[i].bssid);
20448c2ecf20Sopenharmony_ci
20458c2ecf20Sopenharmony_ci	ptr += sizeof(*tlv);
20468c2ecf20Sopenharmony_ci	ptr += bssid_len;
20478c2ecf20Sopenharmony_ci
20488c2ecf20Sopenharmony_ci	tlv = ptr;
20498c2ecf20Sopenharmony_ci	tlv->tag = __cpu_to_le16(WMI_TLV_TAG_ARRAY_BYTE);
20508c2ecf20Sopenharmony_ci	tlv->len = __cpu_to_le16(ie_len);
20518c2ecf20Sopenharmony_ci	memcpy(tlv->value, arg->ie, arg->ie_len);
20528c2ecf20Sopenharmony_ci
20538c2ecf20Sopenharmony_ci	ptr += sizeof(*tlv);
20548c2ecf20Sopenharmony_ci	ptr += ie_len;
20558c2ecf20Sopenharmony_ci
20568c2ecf20Sopenharmony_ci	ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv start scan\n");
20578c2ecf20Sopenharmony_ci	return skb;
20588c2ecf20Sopenharmony_ci}
20598c2ecf20Sopenharmony_ci
20608c2ecf20Sopenharmony_cistatic struct sk_buff *
20618c2ecf20Sopenharmony_ciath10k_wmi_tlv_op_gen_stop_scan(struct ath10k *ar,
20628c2ecf20Sopenharmony_ci				const struct wmi_stop_scan_arg *arg)
20638c2ecf20Sopenharmony_ci{
20648c2ecf20Sopenharmony_ci	struct wmi_stop_scan_cmd *cmd;
20658c2ecf20Sopenharmony_ci	struct wmi_tlv *tlv;
20668c2ecf20Sopenharmony_ci	struct sk_buff *skb;
20678c2ecf20Sopenharmony_ci	u32 scan_id;
20688c2ecf20Sopenharmony_ci	u32 req_id;
20698c2ecf20Sopenharmony_ci
20708c2ecf20Sopenharmony_ci	if (arg->req_id > 0xFFF)
20718c2ecf20Sopenharmony_ci		return ERR_PTR(-EINVAL);
20728c2ecf20Sopenharmony_ci	if (arg->req_type == WMI_SCAN_STOP_ONE && arg->u.scan_id > 0xFFF)
20738c2ecf20Sopenharmony_ci		return ERR_PTR(-EINVAL);
20748c2ecf20Sopenharmony_ci
20758c2ecf20Sopenharmony_ci	skb = ath10k_wmi_alloc_skb(ar, sizeof(*tlv) + sizeof(*cmd));
20768c2ecf20Sopenharmony_ci	if (!skb)
20778c2ecf20Sopenharmony_ci		return ERR_PTR(-ENOMEM);
20788c2ecf20Sopenharmony_ci
20798c2ecf20Sopenharmony_ci	scan_id = arg->u.scan_id;
20808c2ecf20Sopenharmony_ci	scan_id |= WMI_HOST_SCAN_REQ_ID_PREFIX;
20818c2ecf20Sopenharmony_ci
20828c2ecf20Sopenharmony_ci	req_id = arg->req_id;
20838c2ecf20Sopenharmony_ci	req_id |= WMI_HOST_SCAN_REQUESTOR_ID_PREFIX;
20848c2ecf20Sopenharmony_ci
20858c2ecf20Sopenharmony_ci	tlv = (void *)skb->data;
20868c2ecf20Sopenharmony_ci	tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_STOP_SCAN_CMD);
20878c2ecf20Sopenharmony_ci	tlv->len = __cpu_to_le16(sizeof(*cmd));
20888c2ecf20Sopenharmony_ci	cmd = (void *)tlv->value;
20898c2ecf20Sopenharmony_ci	cmd->req_type = __cpu_to_le32(arg->req_type);
20908c2ecf20Sopenharmony_ci	cmd->vdev_id = __cpu_to_le32(arg->u.vdev_id);
20918c2ecf20Sopenharmony_ci	cmd->scan_id = __cpu_to_le32(scan_id);
20928c2ecf20Sopenharmony_ci	cmd->scan_req_id = __cpu_to_le32(req_id);
20938c2ecf20Sopenharmony_ci
20948c2ecf20Sopenharmony_ci	ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv stop scan\n");
20958c2ecf20Sopenharmony_ci	return skb;
20968c2ecf20Sopenharmony_ci}
20978c2ecf20Sopenharmony_ci
20988c2ecf20Sopenharmony_cistatic int ath10k_wmi_tlv_op_get_vdev_subtype(struct ath10k *ar,
20998c2ecf20Sopenharmony_ci					      enum wmi_vdev_subtype subtype)
21008c2ecf20Sopenharmony_ci{
21018c2ecf20Sopenharmony_ci	switch (subtype) {
21028c2ecf20Sopenharmony_ci	case WMI_VDEV_SUBTYPE_NONE:
21038c2ecf20Sopenharmony_ci		return WMI_TLV_VDEV_SUBTYPE_NONE;
21048c2ecf20Sopenharmony_ci	case WMI_VDEV_SUBTYPE_P2P_DEVICE:
21058c2ecf20Sopenharmony_ci		return WMI_TLV_VDEV_SUBTYPE_P2P_DEV;
21068c2ecf20Sopenharmony_ci	case WMI_VDEV_SUBTYPE_P2P_CLIENT:
21078c2ecf20Sopenharmony_ci		return WMI_TLV_VDEV_SUBTYPE_P2P_CLI;
21088c2ecf20Sopenharmony_ci	case WMI_VDEV_SUBTYPE_P2P_GO:
21098c2ecf20Sopenharmony_ci		return WMI_TLV_VDEV_SUBTYPE_P2P_GO;
21108c2ecf20Sopenharmony_ci	case WMI_VDEV_SUBTYPE_PROXY_STA:
21118c2ecf20Sopenharmony_ci		return WMI_TLV_VDEV_SUBTYPE_PROXY_STA;
21128c2ecf20Sopenharmony_ci	case WMI_VDEV_SUBTYPE_MESH_11S:
21138c2ecf20Sopenharmony_ci		return WMI_TLV_VDEV_SUBTYPE_MESH_11S;
21148c2ecf20Sopenharmony_ci	case WMI_VDEV_SUBTYPE_MESH_NON_11S:
21158c2ecf20Sopenharmony_ci		return -ENOTSUPP;
21168c2ecf20Sopenharmony_ci	}
21178c2ecf20Sopenharmony_ci	return -ENOTSUPP;
21188c2ecf20Sopenharmony_ci}
21198c2ecf20Sopenharmony_ci
21208c2ecf20Sopenharmony_cistatic struct sk_buff *
21218c2ecf20Sopenharmony_ciath10k_wmi_tlv_op_gen_vdev_create(struct ath10k *ar,
21228c2ecf20Sopenharmony_ci				  u32 vdev_id,
21238c2ecf20Sopenharmony_ci				  enum wmi_vdev_type vdev_type,
21248c2ecf20Sopenharmony_ci				  enum wmi_vdev_subtype vdev_subtype,
21258c2ecf20Sopenharmony_ci				  const u8 mac_addr[ETH_ALEN])
21268c2ecf20Sopenharmony_ci{
21278c2ecf20Sopenharmony_ci	struct wmi_vdev_create_cmd *cmd;
21288c2ecf20Sopenharmony_ci	struct wmi_tlv *tlv;
21298c2ecf20Sopenharmony_ci	struct sk_buff *skb;
21308c2ecf20Sopenharmony_ci
21318c2ecf20Sopenharmony_ci	skb = ath10k_wmi_alloc_skb(ar, sizeof(*tlv) + sizeof(*cmd));
21328c2ecf20Sopenharmony_ci	if (!skb)
21338c2ecf20Sopenharmony_ci		return ERR_PTR(-ENOMEM);
21348c2ecf20Sopenharmony_ci
21358c2ecf20Sopenharmony_ci	tlv = (void *)skb->data;
21368c2ecf20Sopenharmony_ci	tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_VDEV_CREATE_CMD);
21378c2ecf20Sopenharmony_ci	tlv->len = __cpu_to_le16(sizeof(*cmd));
21388c2ecf20Sopenharmony_ci	cmd = (void *)tlv->value;
21398c2ecf20Sopenharmony_ci	cmd->vdev_id = __cpu_to_le32(vdev_id);
21408c2ecf20Sopenharmony_ci	cmd->vdev_type = __cpu_to_le32(vdev_type);
21418c2ecf20Sopenharmony_ci	cmd->vdev_subtype = __cpu_to_le32(vdev_subtype);
21428c2ecf20Sopenharmony_ci	ether_addr_copy(cmd->vdev_macaddr.addr, mac_addr);
21438c2ecf20Sopenharmony_ci
21448c2ecf20Sopenharmony_ci	ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv vdev create\n");
21458c2ecf20Sopenharmony_ci	return skb;
21468c2ecf20Sopenharmony_ci}
21478c2ecf20Sopenharmony_ci
21488c2ecf20Sopenharmony_cistatic struct sk_buff *
21498c2ecf20Sopenharmony_ciath10k_wmi_tlv_op_gen_vdev_delete(struct ath10k *ar, u32 vdev_id)
21508c2ecf20Sopenharmony_ci{
21518c2ecf20Sopenharmony_ci	struct wmi_vdev_delete_cmd *cmd;
21528c2ecf20Sopenharmony_ci	struct wmi_tlv *tlv;
21538c2ecf20Sopenharmony_ci	struct sk_buff *skb;
21548c2ecf20Sopenharmony_ci
21558c2ecf20Sopenharmony_ci	skb = ath10k_wmi_alloc_skb(ar, sizeof(*tlv) + sizeof(*cmd));
21568c2ecf20Sopenharmony_ci	if (!skb)
21578c2ecf20Sopenharmony_ci		return ERR_PTR(-ENOMEM);
21588c2ecf20Sopenharmony_ci
21598c2ecf20Sopenharmony_ci	tlv = (void *)skb->data;
21608c2ecf20Sopenharmony_ci	tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_VDEV_DELETE_CMD);
21618c2ecf20Sopenharmony_ci	tlv->len = __cpu_to_le16(sizeof(*cmd));
21628c2ecf20Sopenharmony_ci	cmd = (void *)tlv->value;
21638c2ecf20Sopenharmony_ci	cmd->vdev_id = __cpu_to_le32(vdev_id);
21648c2ecf20Sopenharmony_ci
21658c2ecf20Sopenharmony_ci	ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv vdev delete\n");
21668c2ecf20Sopenharmony_ci	return skb;
21678c2ecf20Sopenharmony_ci}
21688c2ecf20Sopenharmony_ci
21698c2ecf20Sopenharmony_cistatic struct sk_buff *
21708c2ecf20Sopenharmony_ciath10k_wmi_tlv_op_gen_vdev_start(struct ath10k *ar,
21718c2ecf20Sopenharmony_ci				 const struct wmi_vdev_start_request_arg *arg,
21728c2ecf20Sopenharmony_ci				 bool restart)
21738c2ecf20Sopenharmony_ci{
21748c2ecf20Sopenharmony_ci	struct wmi_tlv_vdev_start_cmd *cmd;
21758c2ecf20Sopenharmony_ci	struct wmi_channel *ch;
21768c2ecf20Sopenharmony_ci	struct wmi_tlv *tlv;
21778c2ecf20Sopenharmony_ci	struct sk_buff *skb;
21788c2ecf20Sopenharmony_ci	size_t len;
21798c2ecf20Sopenharmony_ci	void *ptr;
21808c2ecf20Sopenharmony_ci	u32 flags = 0;
21818c2ecf20Sopenharmony_ci
21828c2ecf20Sopenharmony_ci	if (WARN_ON(arg->hidden_ssid && !arg->ssid))
21838c2ecf20Sopenharmony_ci		return ERR_PTR(-EINVAL);
21848c2ecf20Sopenharmony_ci	if (WARN_ON(arg->ssid_len > sizeof(cmd->ssid.ssid)))
21858c2ecf20Sopenharmony_ci		return ERR_PTR(-EINVAL);
21868c2ecf20Sopenharmony_ci
21878c2ecf20Sopenharmony_ci	len = (sizeof(*tlv) + sizeof(*cmd)) +
21888c2ecf20Sopenharmony_ci	      (sizeof(*tlv) + sizeof(*ch)) +
21898c2ecf20Sopenharmony_ci	      (sizeof(*tlv) + 0);
21908c2ecf20Sopenharmony_ci	skb = ath10k_wmi_alloc_skb(ar, len);
21918c2ecf20Sopenharmony_ci	if (!skb)
21928c2ecf20Sopenharmony_ci		return ERR_PTR(-ENOMEM);
21938c2ecf20Sopenharmony_ci
21948c2ecf20Sopenharmony_ci	if (arg->hidden_ssid)
21958c2ecf20Sopenharmony_ci		flags |= WMI_VDEV_START_HIDDEN_SSID;
21968c2ecf20Sopenharmony_ci	if (arg->pmf_enabled)
21978c2ecf20Sopenharmony_ci		flags |= WMI_VDEV_START_PMF_ENABLED;
21988c2ecf20Sopenharmony_ci
21998c2ecf20Sopenharmony_ci	ptr = (void *)skb->data;
22008c2ecf20Sopenharmony_ci
22018c2ecf20Sopenharmony_ci	tlv = ptr;
22028c2ecf20Sopenharmony_ci	tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_VDEV_START_REQUEST_CMD);
22038c2ecf20Sopenharmony_ci	tlv->len = __cpu_to_le16(sizeof(*cmd));
22048c2ecf20Sopenharmony_ci	cmd = (void *)tlv->value;
22058c2ecf20Sopenharmony_ci	cmd->vdev_id = __cpu_to_le32(arg->vdev_id);
22068c2ecf20Sopenharmony_ci	cmd->bcn_intval = __cpu_to_le32(arg->bcn_intval);
22078c2ecf20Sopenharmony_ci	cmd->dtim_period = __cpu_to_le32(arg->dtim_period);
22088c2ecf20Sopenharmony_ci	cmd->flags = __cpu_to_le32(flags);
22098c2ecf20Sopenharmony_ci	cmd->bcn_tx_rate = __cpu_to_le32(arg->bcn_tx_rate);
22108c2ecf20Sopenharmony_ci	cmd->bcn_tx_power = __cpu_to_le32(arg->bcn_tx_power);
22118c2ecf20Sopenharmony_ci	cmd->disable_hw_ack = __cpu_to_le32(arg->disable_hw_ack);
22128c2ecf20Sopenharmony_ci
22138c2ecf20Sopenharmony_ci	if (arg->ssid) {
22148c2ecf20Sopenharmony_ci		cmd->ssid.ssid_len = __cpu_to_le32(arg->ssid_len);
22158c2ecf20Sopenharmony_ci		memcpy(cmd->ssid.ssid, arg->ssid, arg->ssid_len);
22168c2ecf20Sopenharmony_ci	}
22178c2ecf20Sopenharmony_ci
22188c2ecf20Sopenharmony_ci	ptr += sizeof(*tlv);
22198c2ecf20Sopenharmony_ci	ptr += sizeof(*cmd);
22208c2ecf20Sopenharmony_ci
22218c2ecf20Sopenharmony_ci	tlv = ptr;
22228c2ecf20Sopenharmony_ci	tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_CHANNEL);
22238c2ecf20Sopenharmony_ci	tlv->len = __cpu_to_le16(sizeof(*ch));
22248c2ecf20Sopenharmony_ci	ch = (void *)tlv->value;
22258c2ecf20Sopenharmony_ci	ath10k_wmi_put_wmi_channel(ar, ch, &arg->channel);
22268c2ecf20Sopenharmony_ci
22278c2ecf20Sopenharmony_ci	ptr += sizeof(*tlv);
22288c2ecf20Sopenharmony_ci	ptr += sizeof(*ch);
22298c2ecf20Sopenharmony_ci
22308c2ecf20Sopenharmony_ci	tlv = ptr;
22318c2ecf20Sopenharmony_ci	tlv->tag = __cpu_to_le16(WMI_TLV_TAG_ARRAY_STRUCT);
22328c2ecf20Sopenharmony_ci	tlv->len = 0;
22338c2ecf20Sopenharmony_ci
22348c2ecf20Sopenharmony_ci	/* Note: This is a nested TLV containing:
22358c2ecf20Sopenharmony_ci	 * [wmi_tlv][wmi_p2p_noa_descriptor][wmi_tlv]..
22368c2ecf20Sopenharmony_ci	 */
22378c2ecf20Sopenharmony_ci
22388c2ecf20Sopenharmony_ci	ptr += sizeof(*tlv);
22398c2ecf20Sopenharmony_ci	ptr += 0;
22408c2ecf20Sopenharmony_ci
22418c2ecf20Sopenharmony_ci	ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv vdev start\n");
22428c2ecf20Sopenharmony_ci	return skb;
22438c2ecf20Sopenharmony_ci}
22448c2ecf20Sopenharmony_ci
22458c2ecf20Sopenharmony_cistatic struct sk_buff *
22468c2ecf20Sopenharmony_ciath10k_wmi_tlv_op_gen_vdev_stop(struct ath10k *ar, u32 vdev_id)
22478c2ecf20Sopenharmony_ci{
22488c2ecf20Sopenharmony_ci	struct wmi_vdev_stop_cmd *cmd;
22498c2ecf20Sopenharmony_ci	struct wmi_tlv *tlv;
22508c2ecf20Sopenharmony_ci	struct sk_buff *skb;
22518c2ecf20Sopenharmony_ci
22528c2ecf20Sopenharmony_ci	skb = ath10k_wmi_alloc_skb(ar, sizeof(*tlv) + sizeof(*cmd));
22538c2ecf20Sopenharmony_ci	if (!skb)
22548c2ecf20Sopenharmony_ci		return ERR_PTR(-ENOMEM);
22558c2ecf20Sopenharmony_ci
22568c2ecf20Sopenharmony_ci	tlv = (void *)skb->data;
22578c2ecf20Sopenharmony_ci	tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_VDEV_STOP_CMD);
22588c2ecf20Sopenharmony_ci	tlv->len = __cpu_to_le16(sizeof(*cmd));
22598c2ecf20Sopenharmony_ci	cmd = (void *)tlv->value;
22608c2ecf20Sopenharmony_ci	cmd->vdev_id = __cpu_to_le32(vdev_id);
22618c2ecf20Sopenharmony_ci
22628c2ecf20Sopenharmony_ci	ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv vdev stop\n");
22638c2ecf20Sopenharmony_ci	return skb;
22648c2ecf20Sopenharmony_ci}
22658c2ecf20Sopenharmony_ci
22668c2ecf20Sopenharmony_cistatic struct sk_buff *
22678c2ecf20Sopenharmony_ciath10k_wmi_tlv_op_gen_vdev_up(struct ath10k *ar, u32 vdev_id, u32 aid,
22688c2ecf20Sopenharmony_ci			      const u8 *bssid)
22698c2ecf20Sopenharmony_ci
22708c2ecf20Sopenharmony_ci{
22718c2ecf20Sopenharmony_ci	struct wmi_vdev_up_cmd *cmd;
22728c2ecf20Sopenharmony_ci	struct wmi_tlv *tlv;
22738c2ecf20Sopenharmony_ci	struct sk_buff *skb;
22748c2ecf20Sopenharmony_ci
22758c2ecf20Sopenharmony_ci	skb = ath10k_wmi_alloc_skb(ar, sizeof(*tlv) + sizeof(*cmd));
22768c2ecf20Sopenharmony_ci	if (!skb)
22778c2ecf20Sopenharmony_ci		return ERR_PTR(-ENOMEM);
22788c2ecf20Sopenharmony_ci
22798c2ecf20Sopenharmony_ci	tlv = (void *)skb->data;
22808c2ecf20Sopenharmony_ci	tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_VDEV_UP_CMD);
22818c2ecf20Sopenharmony_ci	tlv->len = __cpu_to_le16(sizeof(*cmd));
22828c2ecf20Sopenharmony_ci	cmd = (void *)tlv->value;
22838c2ecf20Sopenharmony_ci	cmd->vdev_id = __cpu_to_le32(vdev_id);
22848c2ecf20Sopenharmony_ci	cmd->vdev_assoc_id = __cpu_to_le32(aid);
22858c2ecf20Sopenharmony_ci	ether_addr_copy(cmd->vdev_bssid.addr, bssid);
22868c2ecf20Sopenharmony_ci
22878c2ecf20Sopenharmony_ci	ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv vdev up\n");
22888c2ecf20Sopenharmony_ci	return skb;
22898c2ecf20Sopenharmony_ci}
22908c2ecf20Sopenharmony_ci
22918c2ecf20Sopenharmony_cistatic struct sk_buff *
22928c2ecf20Sopenharmony_ciath10k_wmi_tlv_op_gen_vdev_down(struct ath10k *ar, u32 vdev_id)
22938c2ecf20Sopenharmony_ci{
22948c2ecf20Sopenharmony_ci	struct wmi_vdev_down_cmd *cmd;
22958c2ecf20Sopenharmony_ci	struct wmi_tlv *tlv;
22968c2ecf20Sopenharmony_ci	struct sk_buff *skb;
22978c2ecf20Sopenharmony_ci
22988c2ecf20Sopenharmony_ci	skb = ath10k_wmi_alloc_skb(ar, sizeof(*tlv) + sizeof(*cmd));
22998c2ecf20Sopenharmony_ci	if (!skb)
23008c2ecf20Sopenharmony_ci		return ERR_PTR(-ENOMEM);
23018c2ecf20Sopenharmony_ci
23028c2ecf20Sopenharmony_ci	tlv = (void *)skb->data;
23038c2ecf20Sopenharmony_ci	tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_VDEV_DOWN_CMD);
23048c2ecf20Sopenharmony_ci	tlv->len = __cpu_to_le16(sizeof(*cmd));
23058c2ecf20Sopenharmony_ci	cmd = (void *)tlv->value;
23068c2ecf20Sopenharmony_ci	cmd->vdev_id = __cpu_to_le32(vdev_id);
23078c2ecf20Sopenharmony_ci
23088c2ecf20Sopenharmony_ci	ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv vdev down\n");
23098c2ecf20Sopenharmony_ci	return skb;
23108c2ecf20Sopenharmony_ci}
23118c2ecf20Sopenharmony_ci
23128c2ecf20Sopenharmony_cistatic struct sk_buff *
23138c2ecf20Sopenharmony_ciath10k_wmi_tlv_op_gen_vdev_set_param(struct ath10k *ar, u32 vdev_id,
23148c2ecf20Sopenharmony_ci				     u32 param_id, u32 param_value)
23158c2ecf20Sopenharmony_ci{
23168c2ecf20Sopenharmony_ci	struct wmi_vdev_set_param_cmd *cmd;
23178c2ecf20Sopenharmony_ci	struct wmi_tlv *tlv;
23188c2ecf20Sopenharmony_ci	struct sk_buff *skb;
23198c2ecf20Sopenharmony_ci
23208c2ecf20Sopenharmony_ci	skb = ath10k_wmi_alloc_skb(ar, sizeof(*tlv) + sizeof(*cmd));
23218c2ecf20Sopenharmony_ci	if (!skb)
23228c2ecf20Sopenharmony_ci		return ERR_PTR(-ENOMEM);
23238c2ecf20Sopenharmony_ci
23248c2ecf20Sopenharmony_ci	tlv = (void *)skb->data;
23258c2ecf20Sopenharmony_ci	tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_VDEV_SET_PARAM_CMD);
23268c2ecf20Sopenharmony_ci	tlv->len = __cpu_to_le16(sizeof(*cmd));
23278c2ecf20Sopenharmony_ci	cmd = (void *)tlv->value;
23288c2ecf20Sopenharmony_ci	cmd->vdev_id = __cpu_to_le32(vdev_id);
23298c2ecf20Sopenharmony_ci	cmd->param_id = __cpu_to_le32(param_id);
23308c2ecf20Sopenharmony_ci	cmd->param_value = __cpu_to_le32(param_value);
23318c2ecf20Sopenharmony_ci
23328c2ecf20Sopenharmony_ci	ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv vdev %d set param %d value 0x%x\n",
23338c2ecf20Sopenharmony_ci		   vdev_id, param_id, param_value);
23348c2ecf20Sopenharmony_ci	return skb;
23358c2ecf20Sopenharmony_ci}
23368c2ecf20Sopenharmony_ci
23378c2ecf20Sopenharmony_cistatic struct sk_buff *
23388c2ecf20Sopenharmony_ciath10k_wmi_tlv_op_gen_vdev_install_key(struct ath10k *ar,
23398c2ecf20Sopenharmony_ci				       const struct wmi_vdev_install_key_arg *arg)
23408c2ecf20Sopenharmony_ci{
23418c2ecf20Sopenharmony_ci	struct wmi_vdev_install_key_cmd *cmd;
23428c2ecf20Sopenharmony_ci	struct wmi_tlv *tlv;
23438c2ecf20Sopenharmony_ci	struct sk_buff *skb;
23448c2ecf20Sopenharmony_ci	size_t len;
23458c2ecf20Sopenharmony_ci	void *ptr;
23468c2ecf20Sopenharmony_ci
23478c2ecf20Sopenharmony_ci	if (arg->key_cipher == ar->wmi_key_cipher[WMI_CIPHER_NONE] &&
23488c2ecf20Sopenharmony_ci	    arg->key_data)
23498c2ecf20Sopenharmony_ci		return ERR_PTR(-EINVAL);
23508c2ecf20Sopenharmony_ci	if (arg->key_cipher != ar->wmi_key_cipher[WMI_CIPHER_NONE] &&
23518c2ecf20Sopenharmony_ci	    !arg->key_data)
23528c2ecf20Sopenharmony_ci		return ERR_PTR(-EINVAL);
23538c2ecf20Sopenharmony_ci
23548c2ecf20Sopenharmony_ci	len = sizeof(*tlv) + sizeof(*cmd) +
23558c2ecf20Sopenharmony_ci	      sizeof(*tlv) + roundup(arg->key_len, sizeof(__le32));
23568c2ecf20Sopenharmony_ci	skb = ath10k_wmi_alloc_skb(ar, len);
23578c2ecf20Sopenharmony_ci	if (!skb)
23588c2ecf20Sopenharmony_ci		return ERR_PTR(-ENOMEM);
23598c2ecf20Sopenharmony_ci
23608c2ecf20Sopenharmony_ci	ptr = (void *)skb->data;
23618c2ecf20Sopenharmony_ci	tlv = ptr;
23628c2ecf20Sopenharmony_ci	tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_VDEV_INSTALL_KEY_CMD);
23638c2ecf20Sopenharmony_ci	tlv->len = __cpu_to_le16(sizeof(*cmd));
23648c2ecf20Sopenharmony_ci	cmd = (void *)tlv->value;
23658c2ecf20Sopenharmony_ci	cmd->vdev_id = __cpu_to_le32(arg->vdev_id);
23668c2ecf20Sopenharmony_ci	cmd->key_idx = __cpu_to_le32(arg->key_idx);
23678c2ecf20Sopenharmony_ci	cmd->key_flags = __cpu_to_le32(arg->key_flags);
23688c2ecf20Sopenharmony_ci	cmd->key_cipher = __cpu_to_le32(arg->key_cipher);
23698c2ecf20Sopenharmony_ci	cmd->key_len = __cpu_to_le32(arg->key_len);
23708c2ecf20Sopenharmony_ci	cmd->key_txmic_len = __cpu_to_le32(arg->key_txmic_len);
23718c2ecf20Sopenharmony_ci	cmd->key_rxmic_len = __cpu_to_le32(arg->key_rxmic_len);
23728c2ecf20Sopenharmony_ci
23738c2ecf20Sopenharmony_ci	if (arg->macaddr)
23748c2ecf20Sopenharmony_ci		ether_addr_copy(cmd->peer_macaddr.addr, arg->macaddr);
23758c2ecf20Sopenharmony_ci
23768c2ecf20Sopenharmony_ci	ptr += sizeof(*tlv);
23778c2ecf20Sopenharmony_ci	ptr += sizeof(*cmd);
23788c2ecf20Sopenharmony_ci
23798c2ecf20Sopenharmony_ci	tlv = ptr;
23808c2ecf20Sopenharmony_ci	tlv->tag = __cpu_to_le16(WMI_TLV_TAG_ARRAY_BYTE);
23818c2ecf20Sopenharmony_ci	tlv->len = __cpu_to_le16(roundup(arg->key_len, sizeof(__le32)));
23828c2ecf20Sopenharmony_ci	if (arg->key_data)
23838c2ecf20Sopenharmony_ci		memcpy(tlv->value, arg->key_data, arg->key_len);
23848c2ecf20Sopenharmony_ci
23858c2ecf20Sopenharmony_ci	ptr += sizeof(*tlv);
23868c2ecf20Sopenharmony_ci	ptr += roundup(arg->key_len, sizeof(__le32));
23878c2ecf20Sopenharmony_ci
23888c2ecf20Sopenharmony_ci	ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv vdev install key\n");
23898c2ecf20Sopenharmony_ci	return skb;
23908c2ecf20Sopenharmony_ci}
23918c2ecf20Sopenharmony_ci
23928c2ecf20Sopenharmony_cistatic void *ath10k_wmi_tlv_put_uapsd_ac(struct ath10k *ar, void *ptr,
23938c2ecf20Sopenharmony_ci					 const struct wmi_sta_uapsd_auto_trig_arg *arg)
23948c2ecf20Sopenharmony_ci{
23958c2ecf20Sopenharmony_ci	struct wmi_sta_uapsd_auto_trig_param *ac;
23968c2ecf20Sopenharmony_ci	struct wmi_tlv *tlv;
23978c2ecf20Sopenharmony_ci
23988c2ecf20Sopenharmony_ci	tlv = ptr;
23998c2ecf20Sopenharmony_ci	tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_STA_UAPSD_AUTO_TRIG_PARAM);
24008c2ecf20Sopenharmony_ci	tlv->len = __cpu_to_le16(sizeof(*ac));
24018c2ecf20Sopenharmony_ci	ac = (void *)tlv->value;
24028c2ecf20Sopenharmony_ci
24038c2ecf20Sopenharmony_ci	ac->wmm_ac = __cpu_to_le32(arg->wmm_ac);
24048c2ecf20Sopenharmony_ci	ac->user_priority = __cpu_to_le32(arg->user_priority);
24058c2ecf20Sopenharmony_ci	ac->service_interval = __cpu_to_le32(arg->service_interval);
24068c2ecf20Sopenharmony_ci	ac->suspend_interval = __cpu_to_le32(arg->suspend_interval);
24078c2ecf20Sopenharmony_ci	ac->delay_interval = __cpu_to_le32(arg->delay_interval);
24088c2ecf20Sopenharmony_ci
24098c2ecf20Sopenharmony_ci	ath10k_dbg(ar, ATH10K_DBG_WMI,
24108c2ecf20Sopenharmony_ci		   "wmi tlv vdev sta uapsd auto trigger ac %d prio %d svc int %d susp int %d delay int %d\n",
24118c2ecf20Sopenharmony_ci		   ac->wmm_ac, ac->user_priority, ac->service_interval,
24128c2ecf20Sopenharmony_ci		   ac->suspend_interval, ac->delay_interval);
24138c2ecf20Sopenharmony_ci
24148c2ecf20Sopenharmony_ci	return ptr + sizeof(*tlv) + sizeof(*ac);
24158c2ecf20Sopenharmony_ci}
24168c2ecf20Sopenharmony_ci
24178c2ecf20Sopenharmony_cistatic struct sk_buff *
24188c2ecf20Sopenharmony_ciath10k_wmi_tlv_op_gen_vdev_sta_uapsd(struct ath10k *ar, u32 vdev_id,
24198c2ecf20Sopenharmony_ci				     const u8 peer_addr[ETH_ALEN],
24208c2ecf20Sopenharmony_ci				     const struct wmi_sta_uapsd_auto_trig_arg *args,
24218c2ecf20Sopenharmony_ci				     u32 num_ac)
24228c2ecf20Sopenharmony_ci{
24238c2ecf20Sopenharmony_ci	struct wmi_sta_uapsd_auto_trig_cmd_fixed_param *cmd;
24248c2ecf20Sopenharmony_ci	struct wmi_sta_uapsd_auto_trig_param *ac;
24258c2ecf20Sopenharmony_ci	struct wmi_tlv *tlv;
24268c2ecf20Sopenharmony_ci	struct sk_buff *skb;
24278c2ecf20Sopenharmony_ci	size_t len;
24288c2ecf20Sopenharmony_ci	size_t ac_tlv_len;
24298c2ecf20Sopenharmony_ci	void *ptr;
24308c2ecf20Sopenharmony_ci	int i;
24318c2ecf20Sopenharmony_ci
24328c2ecf20Sopenharmony_ci	ac_tlv_len = num_ac * (sizeof(*tlv) + sizeof(*ac));
24338c2ecf20Sopenharmony_ci	len = sizeof(*tlv) + sizeof(*cmd) +
24348c2ecf20Sopenharmony_ci	      sizeof(*tlv) + ac_tlv_len;
24358c2ecf20Sopenharmony_ci	skb = ath10k_wmi_alloc_skb(ar, len);
24368c2ecf20Sopenharmony_ci	if (!skb)
24378c2ecf20Sopenharmony_ci		return ERR_PTR(-ENOMEM);
24388c2ecf20Sopenharmony_ci
24398c2ecf20Sopenharmony_ci	ptr = (void *)skb->data;
24408c2ecf20Sopenharmony_ci	tlv = ptr;
24418c2ecf20Sopenharmony_ci	tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_STA_UAPSD_AUTO_TRIG_CMD);
24428c2ecf20Sopenharmony_ci	tlv->len = __cpu_to_le16(sizeof(*cmd));
24438c2ecf20Sopenharmony_ci	cmd = (void *)tlv->value;
24448c2ecf20Sopenharmony_ci	cmd->vdev_id = __cpu_to_le32(vdev_id);
24458c2ecf20Sopenharmony_ci	cmd->num_ac = __cpu_to_le32(num_ac);
24468c2ecf20Sopenharmony_ci	ether_addr_copy(cmd->peer_macaddr.addr, peer_addr);
24478c2ecf20Sopenharmony_ci
24488c2ecf20Sopenharmony_ci	ptr += sizeof(*tlv);
24498c2ecf20Sopenharmony_ci	ptr += sizeof(*cmd);
24508c2ecf20Sopenharmony_ci
24518c2ecf20Sopenharmony_ci	tlv = ptr;
24528c2ecf20Sopenharmony_ci	tlv->tag = __cpu_to_le16(WMI_TLV_TAG_ARRAY_STRUCT);
24538c2ecf20Sopenharmony_ci	tlv->len = __cpu_to_le16(ac_tlv_len);
24548c2ecf20Sopenharmony_ci	ac = (void *)tlv->value;
24558c2ecf20Sopenharmony_ci
24568c2ecf20Sopenharmony_ci	ptr += sizeof(*tlv);
24578c2ecf20Sopenharmony_ci	for (i = 0; i < num_ac; i++)
24588c2ecf20Sopenharmony_ci		ptr = ath10k_wmi_tlv_put_uapsd_ac(ar, ptr, &args[i]);
24598c2ecf20Sopenharmony_ci
24608c2ecf20Sopenharmony_ci	ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv vdev sta uapsd auto trigger\n");
24618c2ecf20Sopenharmony_ci	return skb;
24628c2ecf20Sopenharmony_ci}
24638c2ecf20Sopenharmony_ci
24648c2ecf20Sopenharmony_cistatic void *ath10k_wmi_tlv_put_wmm(void *ptr,
24658c2ecf20Sopenharmony_ci				    const struct wmi_wmm_params_arg *arg)
24668c2ecf20Sopenharmony_ci{
24678c2ecf20Sopenharmony_ci	struct wmi_wmm_params *wmm;
24688c2ecf20Sopenharmony_ci	struct wmi_tlv *tlv;
24698c2ecf20Sopenharmony_ci
24708c2ecf20Sopenharmony_ci	tlv = ptr;
24718c2ecf20Sopenharmony_ci	tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_WMM_PARAMS);
24728c2ecf20Sopenharmony_ci	tlv->len = __cpu_to_le16(sizeof(*wmm));
24738c2ecf20Sopenharmony_ci	wmm = (void *)tlv->value;
24748c2ecf20Sopenharmony_ci	ath10k_wmi_set_wmm_param(wmm, arg);
24758c2ecf20Sopenharmony_ci
24768c2ecf20Sopenharmony_ci	return ptr + sizeof(*tlv) + sizeof(*wmm);
24778c2ecf20Sopenharmony_ci}
24788c2ecf20Sopenharmony_ci
24798c2ecf20Sopenharmony_cistatic struct sk_buff *
24808c2ecf20Sopenharmony_ciath10k_wmi_tlv_op_gen_vdev_wmm_conf(struct ath10k *ar, u32 vdev_id,
24818c2ecf20Sopenharmony_ci				    const struct wmi_wmm_params_all_arg *arg)
24828c2ecf20Sopenharmony_ci{
24838c2ecf20Sopenharmony_ci	struct wmi_tlv_vdev_set_wmm_cmd *cmd;
24848c2ecf20Sopenharmony_ci	struct wmi_tlv *tlv;
24858c2ecf20Sopenharmony_ci	struct sk_buff *skb;
24868c2ecf20Sopenharmony_ci	size_t len;
24878c2ecf20Sopenharmony_ci	void *ptr;
24888c2ecf20Sopenharmony_ci
24898c2ecf20Sopenharmony_ci	len = sizeof(*tlv) + sizeof(*cmd);
24908c2ecf20Sopenharmony_ci	skb = ath10k_wmi_alloc_skb(ar, len);
24918c2ecf20Sopenharmony_ci	if (!skb)
24928c2ecf20Sopenharmony_ci		return ERR_PTR(-ENOMEM);
24938c2ecf20Sopenharmony_ci
24948c2ecf20Sopenharmony_ci	ptr = (void *)skb->data;
24958c2ecf20Sopenharmony_ci	tlv = ptr;
24968c2ecf20Sopenharmony_ci	tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_VDEV_SET_WMM_PARAMS_CMD);
24978c2ecf20Sopenharmony_ci	tlv->len = __cpu_to_le16(sizeof(*cmd));
24988c2ecf20Sopenharmony_ci	cmd = (void *)tlv->value;
24998c2ecf20Sopenharmony_ci	cmd->vdev_id = __cpu_to_le32(vdev_id);
25008c2ecf20Sopenharmony_ci
25018c2ecf20Sopenharmony_ci	ath10k_wmi_set_wmm_param(&cmd->vdev_wmm_params[0].params, &arg->ac_be);
25028c2ecf20Sopenharmony_ci	ath10k_wmi_set_wmm_param(&cmd->vdev_wmm_params[1].params, &arg->ac_bk);
25038c2ecf20Sopenharmony_ci	ath10k_wmi_set_wmm_param(&cmd->vdev_wmm_params[2].params, &arg->ac_vi);
25048c2ecf20Sopenharmony_ci	ath10k_wmi_set_wmm_param(&cmd->vdev_wmm_params[3].params, &arg->ac_vo);
25058c2ecf20Sopenharmony_ci
25068c2ecf20Sopenharmony_ci	ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv vdev wmm conf\n");
25078c2ecf20Sopenharmony_ci	return skb;
25088c2ecf20Sopenharmony_ci}
25098c2ecf20Sopenharmony_ci
25108c2ecf20Sopenharmony_cistatic struct sk_buff *
25118c2ecf20Sopenharmony_ciath10k_wmi_tlv_op_gen_sta_keepalive(struct ath10k *ar,
25128c2ecf20Sopenharmony_ci				    const struct wmi_sta_keepalive_arg *arg)
25138c2ecf20Sopenharmony_ci{
25148c2ecf20Sopenharmony_ci	struct wmi_tlv_sta_keepalive_cmd *cmd;
25158c2ecf20Sopenharmony_ci	struct wmi_sta_keepalive_arp_resp *arp;
25168c2ecf20Sopenharmony_ci	struct sk_buff *skb;
25178c2ecf20Sopenharmony_ci	struct wmi_tlv *tlv;
25188c2ecf20Sopenharmony_ci	void *ptr;
25198c2ecf20Sopenharmony_ci	size_t len;
25208c2ecf20Sopenharmony_ci
25218c2ecf20Sopenharmony_ci	len = sizeof(*tlv) + sizeof(*cmd) +
25228c2ecf20Sopenharmony_ci	      sizeof(*tlv) + sizeof(*arp);
25238c2ecf20Sopenharmony_ci	skb = ath10k_wmi_alloc_skb(ar, len);
25248c2ecf20Sopenharmony_ci	if (!skb)
25258c2ecf20Sopenharmony_ci		return ERR_PTR(-ENOMEM);
25268c2ecf20Sopenharmony_ci
25278c2ecf20Sopenharmony_ci	ptr = (void *)skb->data;
25288c2ecf20Sopenharmony_ci	tlv = ptr;
25298c2ecf20Sopenharmony_ci	tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_STA_KEEPALIVE_CMD);
25308c2ecf20Sopenharmony_ci	tlv->len = __cpu_to_le16(sizeof(*cmd));
25318c2ecf20Sopenharmony_ci	cmd = (void *)tlv->value;
25328c2ecf20Sopenharmony_ci	cmd->vdev_id = __cpu_to_le32(arg->vdev_id);
25338c2ecf20Sopenharmony_ci	cmd->enabled = __cpu_to_le32(arg->enabled);
25348c2ecf20Sopenharmony_ci	cmd->method = __cpu_to_le32(arg->method);
25358c2ecf20Sopenharmony_ci	cmd->interval = __cpu_to_le32(arg->interval);
25368c2ecf20Sopenharmony_ci
25378c2ecf20Sopenharmony_ci	ptr += sizeof(*tlv);
25388c2ecf20Sopenharmony_ci	ptr += sizeof(*cmd);
25398c2ecf20Sopenharmony_ci
25408c2ecf20Sopenharmony_ci	tlv = ptr;
25418c2ecf20Sopenharmony_ci	tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_STA_KEEPALVE_ARP_RESPONSE);
25428c2ecf20Sopenharmony_ci	tlv->len = __cpu_to_le16(sizeof(*arp));
25438c2ecf20Sopenharmony_ci	arp = (void *)tlv->value;
25448c2ecf20Sopenharmony_ci
25458c2ecf20Sopenharmony_ci	arp->src_ip4_addr = arg->src_ip4_addr;
25468c2ecf20Sopenharmony_ci	arp->dest_ip4_addr = arg->dest_ip4_addr;
25478c2ecf20Sopenharmony_ci	ether_addr_copy(arp->dest_mac_addr.addr, arg->dest_mac_addr);
25488c2ecf20Sopenharmony_ci
25498c2ecf20Sopenharmony_ci	ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv sta keepalive vdev %d enabled %d method %d interval %d\n",
25508c2ecf20Sopenharmony_ci		   arg->vdev_id, arg->enabled, arg->method, arg->interval);
25518c2ecf20Sopenharmony_ci	return skb;
25528c2ecf20Sopenharmony_ci}
25538c2ecf20Sopenharmony_ci
25548c2ecf20Sopenharmony_cistatic struct sk_buff *
25558c2ecf20Sopenharmony_ciath10k_wmi_tlv_op_gen_peer_create(struct ath10k *ar, u32 vdev_id,
25568c2ecf20Sopenharmony_ci				  const u8 peer_addr[ETH_ALEN],
25578c2ecf20Sopenharmony_ci				  enum wmi_peer_type peer_type)
25588c2ecf20Sopenharmony_ci{
25598c2ecf20Sopenharmony_ci	struct wmi_tlv_peer_create_cmd *cmd;
25608c2ecf20Sopenharmony_ci	struct wmi_tlv *tlv;
25618c2ecf20Sopenharmony_ci	struct sk_buff *skb;
25628c2ecf20Sopenharmony_ci
25638c2ecf20Sopenharmony_ci	skb = ath10k_wmi_alloc_skb(ar, sizeof(*tlv) + sizeof(*cmd));
25648c2ecf20Sopenharmony_ci	if (!skb)
25658c2ecf20Sopenharmony_ci		return ERR_PTR(-ENOMEM);
25668c2ecf20Sopenharmony_ci
25678c2ecf20Sopenharmony_ci	tlv = (void *)skb->data;
25688c2ecf20Sopenharmony_ci	tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_PEER_CREATE_CMD);
25698c2ecf20Sopenharmony_ci	tlv->len = __cpu_to_le16(sizeof(*cmd));
25708c2ecf20Sopenharmony_ci	cmd = (void *)tlv->value;
25718c2ecf20Sopenharmony_ci	cmd->vdev_id = __cpu_to_le32(vdev_id);
25728c2ecf20Sopenharmony_ci	cmd->peer_type = __cpu_to_le32(peer_type);
25738c2ecf20Sopenharmony_ci	ether_addr_copy(cmd->peer_addr.addr, peer_addr);
25748c2ecf20Sopenharmony_ci
25758c2ecf20Sopenharmony_ci	ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv peer create\n");
25768c2ecf20Sopenharmony_ci	return skb;
25778c2ecf20Sopenharmony_ci}
25788c2ecf20Sopenharmony_ci
25798c2ecf20Sopenharmony_cistatic struct sk_buff *
25808c2ecf20Sopenharmony_ciath10k_wmi_tlv_op_gen_peer_delete(struct ath10k *ar, u32 vdev_id,
25818c2ecf20Sopenharmony_ci				  const u8 peer_addr[ETH_ALEN])
25828c2ecf20Sopenharmony_ci{
25838c2ecf20Sopenharmony_ci	struct wmi_peer_delete_cmd *cmd;
25848c2ecf20Sopenharmony_ci	struct wmi_tlv *tlv;
25858c2ecf20Sopenharmony_ci	struct sk_buff *skb;
25868c2ecf20Sopenharmony_ci
25878c2ecf20Sopenharmony_ci	skb = ath10k_wmi_alloc_skb(ar, sizeof(*tlv) + sizeof(*cmd));
25888c2ecf20Sopenharmony_ci	if (!skb)
25898c2ecf20Sopenharmony_ci		return ERR_PTR(-ENOMEM);
25908c2ecf20Sopenharmony_ci
25918c2ecf20Sopenharmony_ci	tlv = (void *)skb->data;
25928c2ecf20Sopenharmony_ci	tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_PEER_DELETE_CMD);
25938c2ecf20Sopenharmony_ci	tlv->len = __cpu_to_le16(sizeof(*cmd));
25948c2ecf20Sopenharmony_ci	cmd = (void *)tlv->value;
25958c2ecf20Sopenharmony_ci	cmd->vdev_id = __cpu_to_le32(vdev_id);
25968c2ecf20Sopenharmony_ci	ether_addr_copy(cmd->peer_macaddr.addr, peer_addr);
25978c2ecf20Sopenharmony_ci
25988c2ecf20Sopenharmony_ci	ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv peer delete\n");
25998c2ecf20Sopenharmony_ci	return skb;
26008c2ecf20Sopenharmony_ci}
26018c2ecf20Sopenharmony_ci
26028c2ecf20Sopenharmony_cistatic struct sk_buff *
26038c2ecf20Sopenharmony_ciath10k_wmi_tlv_op_gen_peer_flush(struct ath10k *ar, u32 vdev_id,
26048c2ecf20Sopenharmony_ci				 const u8 peer_addr[ETH_ALEN], u32 tid_bitmap)
26058c2ecf20Sopenharmony_ci{
26068c2ecf20Sopenharmony_ci	struct wmi_peer_flush_tids_cmd *cmd;
26078c2ecf20Sopenharmony_ci	struct wmi_tlv *tlv;
26088c2ecf20Sopenharmony_ci	struct sk_buff *skb;
26098c2ecf20Sopenharmony_ci
26108c2ecf20Sopenharmony_ci	skb = ath10k_wmi_alloc_skb(ar, sizeof(*tlv) + sizeof(*cmd));
26118c2ecf20Sopenharmony_ci	if (!skb)
26128c2ecf20Sopenharmony_ci		return ERR_PTR(-ENOMEM);
26138c2ecf20Sopenharmony_ci
26148c2ecf20Sopenharmony_ci	tlv = (void *)skb->data;
26158c2ecf20Sopenharmony_ci	tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_PEER_FLUSH_TIDS_CMD);
26168c2ecf20Sopenharmony_ci	tlv->len = __cpu_to_le16(sizeof(*cmd));
26178c2ecf20Sopenharmony_ci	cmd = (void *)tlv->value;
26188c2ecf20Sopenharmony_ci	cmd->vdev_id = __cpu_to_le32(vdev_id);
26198c2ecf20Sopenharmony_ci	cmd->peer_tid_bitmap = __cpu_to_le32(tid_bitmap);
26208c2ecf20Sopenharmony_ci	ether_addr_copy(cmd->peer_macaddr.addr, peer_addr);
26218c2ecf20Sopenharmony_ci
26228c2ecf20Sopenharmony_ci	ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv peer flush\n");
26238c2ecf20Sopenharmony_ci	return skb;
26248c2ecf20Sopenharmony_ci}
26258c2ecf20Sopenharmony_ci
26268c2ecf20Sopenharmony_cistatic struct sk_buff *
26278c2ecf20Sopenharmony_ciath10k_wmi_tlv_op_gen_peer_set_param(struct ath10k *ar, u32 vdev_id,
26288c2ecf20Sopenharmony_ci				     const u8 *peer_addr,
26298c2ecf20Sopenharmony_ci				     enum wmi_peer_param param_id,
26308c2ecf20Sopenharmony_ci				     u32 param_value)
26318c2ecf20Sopenharmony_ci{
26328c2ecf20Sopenharmony_ci	struct wmi_peer_set_param_cmd *cmd;
26338c2ecf20Sopenharmony_ci	struct wmi_tlv *tlv;
26348c2ecf20Sopenharmony_ci	struct sk_buff *skb;
26358c2ecf20Sopenharmony_ci
26368c2ecf20Sopenharmony_ci	skb = ath10k_wmi_alloc_skb(ar, sizeof(*tlv) + sizeof(*cmd));
26378c2ecf20Sopenharmony_ci	if (!skb)
26388c2ecf20Sopenharmony_ci		return ERR_PTR(-ENOMEM);
26398c2ecf20Sopenharmony_ci
26408c2ecf20Sopenharmony_ci	tlv = (void *)skb->data;
26418c2ecf20Sopenharmony_ci	tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_PEER_SET_PARAM_CMD);
26428c2ecf20Sopenharmony_ci	tlv->len = __cpu_to_le16(sizeof(*cmd));
26438c2ecf20Sopenharmony_ci	cmd = (void *)tlv->value;
26448c2ecf20Sopenharmony_ci	cmd->vdev_id = __cpu_to_le32(vdev_id);
26458c2ecf20Sopenharmony_ci	cmd->param_id = __cpu_to_le32(param_id);
26468c2ecf20Sopenharmony_ci	cmd->param_value = __cpu_to_le32(param_value);
26478c2ecf20Sopenharmony_ci	ether_addr_copy(cmd->peer_macaddr.addr, peer_addr);
26488c2ecf20Sopenharmony_ci
26498c2ecf20Sopenharmony_ci	ath10k_dbg(ar, ATH10K_DBG_WMI,
26508c2ecf20Sopenharmony_ci		   "wmi tlv vdev %d peer %pM set param %d value 0x%x\n",
26518c2ecf20Sopenharmony_ci		   vdev_id, peer_addr, param_id, param_value);
26528c2ecf20Sopenharmony_ci	return skb;
26538c2ecf20Sopenharmony_ci}
26548c2ecf20Sopenharmony_ci
26558c2ecf20Sopenharmony_cistatic struct sk_buff *
26568c2ecf20Sopenharmony_ciath10k_wmi_tlv_op_gen_peer_assoc(struct ath10k *ar,
26578c2ecf20Sopenharmony_ci				 const struct wmi_peer_assoc_complete_arg *arg)
26588c2ecf20Sopenharmony_ci{
26598c2ecf20Sopenharmony_ci	struct wmi_tlv_peer_assoc_cmd *cmd;
26608c2ecf20Sopenharmony_ci	struct wmi_vht_rate_set *vht_rate;
26618c2ecf20Sopenharmony_ci	struct wmi_tlv *tlv;
26628c2ecf20Sopenharmony_ci	struct sk_buff *skb;
26638c2ecf20Sopenharmony_ci	size_t len, legacy_rate_len, ht_rate_len;
26648c2ecf20Sopenharmony_ci	void *ptr;
26658c2ecf20Sopenharmony_ci
26668c2ecf20Sopenharmony_ci	if (arg->peer_mpdu_density > 16)
26678c2ecf20Sopenharmony_ci		return ERR_PTR(-EINVAL);
26688c2ecf20Sopenharmony_ci	if (arg->peer_legacy_rates.num_rates > MAX_SUPPORTED_RATES)
26698c2ecf20Sopenharmony_ci		return ERR_PTR(-EINVAL);
26708c2ecf20Sopenharmony_ci	if (arg->peer_ht_rates.num_rates > MAX_SUPPORTED_RATES)
26718c2ecf20Sopenharmony_ci		return ERR_PTR(-EINVAL);
26728c2ecf20Sopenharmony_ci
26738c2ecf20Sopenharmony_ci	legacy_rate_len = roundup(arg->peer_legacy_rates.num_rates,
26748c2ecf20Sopenharmony_ci				  sizeof(__le32));
26758c2ecf20Sopenharmony_ci	ht_rate_len = roundup(arg->peer_ht_rates.num_rates, sizeof(__le32));
26768c2ecf20Sopenharmony_ci	len = (sizeof(*tlv) + sizeof(*cmd)) +
26778c2ecf20Sopenharmony_ci	      (sizeof(*tlv) + legacy_rate_len) +
26788c2ecf20Sopenharmony_ci	      (sizeof(*tlv) + ht_rate_len) +
26798c2ecf20Sopenharmony_ci	      (sizeof(*tlv) + sizeof(*vht_rate));
26808c2ecf20Sopenharmony_ci	skb = ath10k_wmi_alloc_skb(ar, len);
26818c2ecf20Sopenharmony_ci	if (!skb)
26828c2ecf20Sopenharmony_ci		return ERR_PTR(-ENOMEM);
26838c2ecf20Sopenharmony_ci
26848c2ecf20Sopenharmony_ci	ptr = (void *)skb->data;
26858c2ecf20Sopenharmony_ci	tlv = ptr;
26868c2ecf20Sopenharmony_ci	tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_PEER_ASSOC_COMPLETE_CMD);
26878c2ecf20Sopenharmony_ci	tlv->len = __cpu_to_le16(sizeof(*cmd));
26888c2ecf20Sopenharmony_ci	cmd = (void *)tlv->value;
26898c2ecf20Sopenharmony_ci
26908c2ecf20Sopenharmony_ci	cmd->vdev_id = __cpu_to_le32(arg->vdev_id);
26918c2ecf20Sopenharmony_ci	cmd->new_assoc = __cpu_to_le32(arg->peer_reassoc ? 0 : 1);
26928c2ecf20Sopenharmony_ci	cmd->assoc_id = __cpu_to_le32(arg->peer_aid);
26938c2ecf20Sopenharmony_ci	cmd->flags = __cpu_to_le32(arg->peer_flags);
26948c2ecf20Sopenharmony_ci	cmd->caps = __cpu_to_le32(arg->peer_caps);
26958c2ecf20Sopenharmony_ci	cmd->listen_intval = __cpu_to_le32(arg->peer_listen_intval);
26968c2ecf20Sopenharmony_ci	cmd->ht_caps = __cpu_to_le32(arg->peer_ht_caps);
26978c2ecf20Sopenharmony_ci	cmd->max_mpdu = __cpu_to_le32(arg->peer_max_mpdu);
26988c2ecf20Sopenharmony_ci	cmd->mpdu_density = __cpu_to_le32(arg->peer_mpdu_density);
26998c2ecf20Sopenharmony_ci	cmd->rate_caps = __cpu_to_le32(arg->peer_rate_caps);
27008c2ecf20Sopenharmony_ci	cmd->nss = __cpu_to_le32(arg->peer_num_spatial_streams);
27018c2ecf20Sopenharmony_ci	cmd->vht_caps = __cpu_to_le32(arg->peer_vht_caps);
27028c2ecf20Sopenharmony_ci	cmd->phy_mode = __cpu_to_le32(arg->peer_phymode);
27038c2ecf20Sopenharmony_ci	cmd->num_legacy_rates = __cpu_to_le32(arg->peer_legacy_rates.num_rates);
27048c2ecf20Sopenharmony_ci	cmd->num_ht_rates = __cpu_to_le32(arg->peer_ht_rates.num_rates);
27058c2ecf20Sopenharmony_ci	ether_addr_copy(cmd->mac_addr.addr, arg->addr);
27068c2ecf20Sopenharmony_ci
27078c2ecf20Sopenharmony_ci	ptr += sizeof(*tlv);
27088c2ecf20Sopenharmony_ci	ptr += sizeof(*cmd);
27098c2ecf20Sopenharmony_ci
27108c2ecf20Sopenharmony_ci	tlv = ptr;
27118c2ecf20Sopenharmony_ci	tlv->tag = __cpu_to_le16(WMI_TLV_TAG_ARRAY_BYTE);
27128c2ecf20Sopenharmony_ci	tlv->len = __cpu_to_le16(legacy_rate_len);
27138c2ecf20Sopenharmony_ci	memcpy(tlv->value, arg->peer_legacy_rates.rates,
27148c2ecf20Sopenharmony_ci	       arg->peer_legacy_rates.num_rates);
27158c2ecf20Sopenharmony_ci
27168c2ecf20Sopenharmony_ci	ptr += sizeof(*tlv);
27178c2ecf20Sopenharmony_ci	ptr += legacy_rate_len;
27188c2ecf20Sopenharmony_ci
27198c2ecf20Sopenharmony_ci	tlv = ptr;
27208c2ecf20Sopenharmony_ci	tlv->tag = __cpu_to_le16(WMI_TLV_TAG_ARRAY_BYTE);
27218c2ecf20Sopenharmony_ci	tlv->len = __cpu_to_le16(ht_rate_len);
27228c2ecf20Sopenharmony_ci	memcpy(tlv->value, arg->peer_ht_rates.rates,
27238c2ecf20Sopenharmony_ci	       arg->peer_ht_rates.num_rates);
27248c2ecf20Sopenharmony_ci
27258c2ecf20Sopenharmony_ci	ptr += sizeof(*tlv);
27268c2ecf20Sopenharmony_ci	ptr += ht_rate_len;
27278c2ecf20Sopenharmony_ci
27288c2ecf20Sopenharmony_ci	tlv = ptr;
27298c2ecf20Sopenharmony_ci	tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_VHT_RATE_SET);
27308c2ecf20Sopenharmony_ci	tlv->len = __cpu_to_le16(sizeof(*vht_rate));
27318c2ecf20Sopenharmony_ci	vht_rate = (void *)tlv->value;
27328c2ecf20Sopenharmony_ci
27338c2ecf20Sopenharmony_ci	vht_rate->rx_max_rate = __cpu_to_le32(arg->peer_vht_rates.rx_max_rate);
27348c2ecf20Sopenharmony_ci	vht_rate->rx_mcs_set = __cpu_to_le32(arg->peer_vht_rates.rx_mcs_set);
27358c2ecf20Sopenharmony_ci	vht_rate->tx_max_rate = __cpu_to_le32(arg->peer_vht_rates.tx_max_rate);
27368c2ecf20Sopenharmony_ci	vht_rate->tx_mcs_set = __cpu_to_le32(arg->peer_vht_rates.tx_mcs_set);
27378c2ecf20Sopenharmony_ci
27388c2ecf20Sopenharmony_ci	ptr += sizeof(*tlv);
27398c2ecf20Sopenharmony_ci	ptr += sizeof(*vht_rate);
27408c2ecf20Sopenharmony_ci
27418c2ecf20Sopenharmony_ci	ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv peer assoc\n");
27428c2ecf20Sopenharmony_ci	return skb;
27438c2ecf20Sopenharmony_ci}
27448c2ecf20Sopenharmony_ci
27458c2ecf20Sopenharmony_cistatic struct sk_buff *
27468c2ecf20Sopenharmony_ciath10k_wmi_tlv_op_gen_set_psmode(struct ath10k *ar, u32 vdev_id,
27478c2ecf20Sopenharmony_ci				 enum wmi_sta_ps_mode psmode)
27488c2ecf20Sopenharmony_ci{
27498c2ecf20Sopenharmony_ci	struct wmi_sta_powersave_mode_cmd *cmd;
27508c2ecf20Sopenharmony_ci	struct wmi_tlv *tlv;
27518c2ecf20Sopenharmony_ci	struct sk_buff *skb;
27528c2ecf20Sopenharmony_ci
27538c2ecf20Sopenharmony_ci	skb = ath10k_wmi_alloc_skb(ar, sizeof(*tlv) + sizeof(*cmd));
27548c2ecf20Sopenharmony_ci	if (!skb)
27558c2ecf20Sopenharmony_ci		return ERR_PTR(-ENOMEM);
27568c2ecf20Sopenharmony_ci
27578c2ecf20Sopenharmony_ci	tlv = (void *)skb->data;
27588c2ecf20Sopenharmony_ci	tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_STA_POWERSAVE_MODE_CMD);
27598c2ecf20Sopenharmony_ci	tlv->len = __cpu_to_le16(sizeof(*cmd));
27608c2ecf20Sopenharmony_ci	cmd = (void *)tlv->value;
27618c2ecf20Sopenharmony_ci	cmd->vdev_id = __cpu_to_le32(vdev_id);
27628c2ecf20Sopenharmony_ci	cmd->sta_ps_mode = __cpu_to_le32(psmode);
27638c2ecf20Sopenharmony_ci
27648c2ecf20Sopenharmony_ci	ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv set psmode\n");
27658c2ecf20Sopenharmony_ci	return skb;
27668c2ecf20Sopenharmony_ci}
27678c2ecf20Sopenharmony_ci
27688c2ecf20Sopenharmony_cistatic struct sk_buff *
27698c2ecf20Sopenharmony_ciath10k_wmi_tlv_op_gen_set_sta_ps(struct ath10k *ar, u32 vdev_id,
27708c2ecf20Sopenharmony_ci				 enum wmi_sta_powersave_param param_id,
27718c2ecf20Sopenharmony_ci				 u32 param_value)
27728c2ecf20Sopenharmony_ci{
27738c2ecf20Sopenharmony_ci	struct wmi_sta_powersave_param_cmd *cmd;
27748c2ecf20Sopenharmony_ci	struct wmi_tlv *tlv;
27758c2ecf20Sopenharmony_ci	struct sk_buff *skb;
27768c2ecf20Sopenharmony_ci
27778c2ecf20Sopenharmony_ci	skb = ath10k_wmi_alloc_skb(ar, sizeof(*tlv) + sizeof(*cmd));
27788c2ecf20Sopenharmony_ci	if (!skb)
27798c2ecf20Sopenharmony_ci		return ERR_PTR(-ENOMEM);
27808c2ecf20Sopenharmony_ci
27818c2ecf20Sopenharmony_ci	tlv = (void *)skb->data;
27828c2ecf20Sopenharmony_ci	tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_STA_POWERSAVE_PARAM_CMD);
27838c2ecf20Sopenharmony_ci	tlv->len = __cpu_to_le16(sizeof(*cmd));
27848c2ecf20Sopenharmony_ci	cmd = (void *)tlv->value;
27858c2ecf20Sopenharmony_ci	cmd->vdev_id = __cpu_to_le32(vdev_id);
27868c2ecf20Sopenharmony_ci	cmd->param_id = __cpu_to_le32(param_id);
27878c2ecf20Sopenharmony_ci	cmd->param_value = __cpu_to_le32(param_value);
27888c2ecf20Sopenharmony_ci
27898c2ecf20Sopenharmony_ci	ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv set sta ps\n");
27908c2ecf20Sopenharmony_ci	return skb;
27918c2ecf20Sopenharmony_ci}
27928c2ecf20Sopenharmony_ci
27938c2ecf20Sopenharmony_cistatic struct sk_buff *
27948c2ecf20Sopenharmony_ciath10k_wmi_tlv_op_gen_set_ap_ps(struct ath10k *ar, u32 vdev_id, const u8 *mac,
27958c2ecf20Sopenharmony_ci				enum wmi_ap_ps_peer_param param_id, u32 value)
27968c2ecf20Sopenharmony_ci{
27978c2ecf20Sopenharmony_ci	struct wmi_ap_ps_peer_cmd *cmd;
27988c2ecf20Sopenharmony_ci	struct wmi_tlv *tlv;
27998c2ecf20Sopenharmony_ci	struct sk_buff *skb;
28008c2ecf20Sopenharmony_ci
28018c2ecf20Sopenharmony_ci	if (!mac)
28028c2ecf20Sopenharmony_ci		return ERR_PTR(-EINVAL);
28038c2ecf20Sopenharmony_ci
28048c2ecf20Sopenharmony_ci	skb = ath10k_wmi_alloc_skb(ar, sizeof(*tlv) + sizeof(*cmd));
28058c2ecf20Sopenharmony_ci	if (!skb)
28068c2ecf20Sopenharmony_ci		return ERR_PTR(-ENOMEM);
28078c2ecf20Sopenharmony_ci
28088c2ecf20Sopenharmony_ci	tlv = (void *)skb->data;
28098c2ecf20Sopenharmony_ci	tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_AP_PS_PEER_CMD);
28108c2ecf20Sopenharmony_ci	tlv->len = __cpu_to_le16(sizeof(*cmd));
28118c2ecf20Sopenharmony_ci	cmd = (void *)tlv->value;
28128c2ecf20Sopenharmony_ci	cmd->vdev_id = __cpu_to_le32(vdev_id);
28138c2ecf20Sopenharmony_ci	cmd->param_id = __cpu_to_le32(param_id);
28148c2ecf20Sopenharmony_ci	cmd->param_value = __cpu_to_le32(value);
28158c2ecf20Sopenharmony_ci	ether_addr_copy(cmd->peer_macaddr.addr, mac);
28168c2ecf20Sopenharmony_ci
28178c2ecf20Sopenharmony_ci	ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv ap ps param\n");
28188c2ecf20Sopenharmony_ci	return skb;
28198c2ecf20Sopenharmony_ci}
28208c2ecf20Sopenharmony_ci
28218c2ecf20Sopenharmony_cistatic struct sk_buff *
28228c2ecf20Sopenharmony_ciath10k_wmi_tlv_op_gen_scan_chan_list(struct ath10k *ar,
28238c2ecf20Sopenharmony_ci				     const struct wmi_scan_chan_list_arg *arg)
28248c2ecf20Sopenharmony_ci{
28258c2ecf20Sopenharmony_ci	struct wmi_tlv_scan_chan_list_cmd *cmd;
28268c2ecf20Sopenharmony_ci	struct wmi_channel *ci;
28278c2ecf20Sopenharmony_ci	struct wmi_channel_arg *ch;
28288c2ecf20Sopenharmony_ci	struct wmi_tlv *tlv;
28298c2ecf20Sopenharmony_ci	struct sk_buff *skb;
28308c2ecf20Sopenharmony_ci	size_t chans_len, len;
28318c2ecf20Sopenharmony_ci	int i;
28328c2ecf20Sopenharmony_ci	void *ptr, *chans;
28338c2ecf20Sopenharmony_ci
28348c2ecf20Sopenharmony_ci	chans_len = arg->n_channels * (sizeof(*tlv) + sizeof(*ci));
28358c2ecf20Sopenharmony_ci	len = (sizeof(*tlv) + sizeof(*cmd)) +
28368c2ecf20Sopenharmony_ci	      (sizeof(*tlv) + chans_len);
28378c2ecf20Sopenharmony_ci
28388c2ecf20Sopenharmony_ci	skb = ath10k_wmi_alloc_skb(ar, len);
28398c2ecf20Sopenharmony_ci	if (!skb)
28408c2ecf20Sopenharmony_ci		return ERR_PTR(-ENOMEM);
28418c2ecf20Sopenharmony_ci
28428c2ecf20Sopenharmony_ci	ptr = (void *)skb->data;
28438c2ecf20Sopenharmony_ci	tlv = ptr;
28448c2ecf20Sopenharmony_ci	tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_SCAN_CHAN_LIST_CMD);
28458c2ecf20Sopenharmony_ci	tlv->len = __cpu_to_le16(sizeof(*cmd));
28468c2ecf20Sopenharmony_ci	cmd = (void *)tlv->value;
28478c2ecf20Sopenharmony_ci	cmd->num_scan_chans = __cpu_to_le32(arg->n_channels);
28488c2ecf20Sopenharmony_ci
28498c2ecf20Sopenharmony_ci	ptr += sizeof(*tlv);
28508c2ecf20Sopenharmony_ci	ptr += sizeof(*cmd);
28518c2ecf20Sopenharmony_ci
28528c2ecf20Sopenharmony_ci	tlv = ptr;
28538c2ecf20Sopenharmony_ci	tlv->tag = __cpu_to_le16(WMI_TLV_TAG_ARRAY_STRUCT);
28548c2ecf20Sopenharmony_ci	tlv->len = __cpu_to_le16(chans_len);
28558c2ecf20Sopenharmony_ci	chans = (void *)tlv->value;
28568c2ecf20Sopenharmony_ci
28578c2ecf20Sopenharmony_ci	for (i = 0; i < arg->n_channels; i++) {
28588c2ecf20Sopenharmony_ci		ch = &arg->channels[i];
28598c2ecf20Sopenharmony_ci
28608c2ecf20Sopenharmony_ci		tlv = chans;
28618c2ecf20Sopenharmony_ci		tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_CHANNEL);
28628c2ecf20Sopenharmony_ci		tlv->len = __cpu_to_le16(sizeof(*ci));
28638c2ecf20Sopenharmony_ci		ci = (void *)tlv->value;
28648c2ecf20Sopenharmony_ci
28658c2ecf20Sopenharmony_ci		ath10k_wmi_put_wmi_channel(ar, ci, ch);
28668c2ecf20Sopenharmony_ci
28678c2ecf20Sopenharmony_ci		chans += sizeof(*tlv);
28688c2ecf20Sopenharmony_ci		chans += sizeof(*ci);
28698c2ecf20Sopenharmony_ci	}
28708c2ecf20Sopenharmony_ci
28718c2ecf20Sopenharmony_ci	ptr += sizeof(*tlv);
28728c2ecf20Sopenharmony_ci	ptr += chans_len;
28738c2ecf20Sopenharmony_ci
28748c2ecf20Sopenharmony_ci	ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv scan chan list\n");
28758c2ecf20Sopenharmony_ci	return skb;
28768c2ecf20Sopenharmony_ci}
28778c2ecf20Sopenharmony_ci
28788c2ecf20Sopenharmony_cistatic struct sk_buff *
28798c2ecf20Sopenharmony_ciath10k_wmi_tlv_op_gen_scan_prob_req_oui(struct ath10k *ar, u32 prob_req_oui)
28808c2ecf20Sopenharmony_ci{
28818c2ecf20Sopenharmony_ci	struct wmi_scan_prob_req_oui_cmd *cmd;
28828c2ecf20Sopenharmony_ci	struct wmi_tlv *tlv;
28838c2ecf20Sopenharmony_ci	struct sk_buff *skb;
28848c2ecf20Sopenharmony_ci
28858c2ecf20Sopenharmony_ci	skb = ath10k_wmi_alloc_skb(ar, sizeof(*tlv) + sizeof(*cmd));
28868c2ecf20Sopenharmony_ci	if (!skb)
28878c2ecf20Sopenharmony_ci		return ERR_PTR(-ENOMEM);
28888c2ecf20Sopenharmony_ci
28898c2ecf20Sopenharmony_ci	tlv = (void *)skb->data;
28908c2ecf20Sopenharmony_ci	tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_SCAN_PROB_REQ_OUI_CMD);
28918c2ecf20Sopenharmony_ci	tlv->len = __cpu_to_le16(sizeof(*cmd));
28928c2ecf20Sopenharmony_ci	cmd = (void *)tlv->value;
28938c2ecf20Sopenharmony_ci	cmd->prob_req_oui = __cpu_to_le32(prob_req_oui);
28948c2ecf20Sopenharmony_ci
28958c2ecf20Sopenharmony_ci	ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv scan prob req oui\n");
28968c2ecf20Sopenharmony_ci	return skb;
28978c2ecf20Sopenharmony_ci}
28988c2ecf20Sopenharmony_ci
28998c2ecf20Sopenharmony_cistatic struct sk_buff *
29008c2ecf20Sopenharmony_ciath10k_wmi_tlv_op_gen_beacon_dma(struct ath10k *ar, u32 vdev_id,
29018c2ecf20Sopenharmony_ci				 const void *bcn, size_t bcn_len,
29028c2ecf20Sopenharmony_ci				 u32 bcn_paddr, bool dtim_zero,
29038c2ecf20Sopenharmony_ci				 bool deliver_cab)
29048c2ecf20Sopenharmony_ci
29058c2ecf20Sopenharmony_ci{
29068c2ecf20Sopenharmony_ci	struct wmi_bcn_tx_ref_cmd *cmd;
29078c2ecf20Sopenharmony_ci	struct wmi_tlv *tlv;
29088c2ecf20Sopenharmony_ci	struct sk_buff *skb;
29098c2ecf20Sopenharmony_ci	struct ieee80211_hdr *hdr;
29108c2ecf20Sopenharmony_ci	u16 fc;
29118c2ecf20Sopenharmony_ci
29128c2ecf20Sopenharmony_ci	skb = ath10k_wmi_alloc_skb(ar, sizeof(*tlv) + sizeof(*cmd));
29138c2ecf20Sopenharmony_ci	if (!skb)
29148c2ecf20Sopenharmony_ci		return ERR_PTR(-ENOMEM);
29158c2ecf20Sopenharmony_ci
29168c2ecf20Sopenharmony_ci	hdr = (struct ieee80211_hdr *)bcn;
29178c2ecf20Sopenharmony_ci	fc = le16_to_cpu(hdr->frame_control);
29188c2ecf20Sopenharmony_ci
29198c2ecf20Sopenharmony_ci	tlv = (void *)skb->data;
29208c2ecf20Sopenharmony_ci	tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_BCN_SEND_FROM_HOST_CMD);
29218c2ecf20Sopenharmony_ci	tlv->len = __cpu_to_le16(sizeof(*cmd));
29228c2ecf20Sopenharmony_ci	cmd = (void *)tlv->value;
29238c2ecf20Sopenharmony_ci	cmd->vdev_id = __cpu_to_le32(vdev_id);
29248c2ecf20Sopenharmony_ci	cmd->data_len = __cpu_to_le32(bcn_len);
29258c2ecf20Sopenharmony_ci	cmd->data_ptr = __cpu_to_le32(bcn_paddr);
29268c2ecf20Sopenharmony_ci	cmd->msdu_id = 0;
29278c2ecf20Sopenharmony_ci	cmd->frame_control = __cpu_to_le32(fc);
29288c2ecf20Sopenharmony_ci	cmd->flags = 0;
29298c2ecf20Sopenharmony_ci
29308c2ecf20Sopenharmony_ci	if (dtim_zero)
29318c2ecf20Sopenharmony_ci		cmd->flags |= __cpu_to_le32(WMI_BCN_TX_REF_FLAG_DTIM_ZERO);
29328c2ecf20Sopenharmony_ci
29338c2ecf20Sopenharmony_ci	if (deliver_cab)
29348c2ecf20Sopenharmony_ci		cmd->flags |= __cpu_to_le32(WMI_BCN_TX_REF_FLAG_DELIVER_CAB);
29358c2ecf20Sopenharmony_ci
29368c2ecf20Sopenharmony_ci	ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv beacon dma\n");
29378c2ecf20Sopenharmony_ci	return skb;
29388c2ecf20Sopenharmony_ci}
29398c2ecf20Sopenharmony_ci
29408c2ecf20Sopenharmony_cistatic struct sk_buff *
29418c2ecf20Sopenharmony_ciath10k_wmi_tlv_op_gen_pdev_set_wmm(struct ath10k *ar,
29428c2ecf20Sopenharmony_ci				   const struct wmi_wmm_params_all_arg *arg)
29438c2ecf20Sopenharmony_ci{
29448c2ecf20Sopenharmony_ci	struct wmi_tlv_pdev_set_wmm_cmd *cmd;
29458c2ecf20Sopenharmony_ci	struct wmi_wmm_params *wmm;
29468c2ecf20Sopenharmony_ci	struct wmi_tlv *tlv;
29478c2ecf20Sopenharmony_ci	struct sk_buff *skb;
29488c2ecf20Sopenharmony_ci	size_t len;
29498c2ecf20Sopenharmony_ci	void *ptr;
29508c2ecf20Sopenharmony_ci
29518c2ecf20Sopenharmony_ci	len = (sizeof(*tlv) + sizeof(*cmd)) +
29528c2ecf20Sopenharmony_ci	      (4 * (sizeof(*tlv) + sizeof(*wmm)));
29538c2ecf20Sopenharmony_ci	skb = ath10k_wmi_alloc_skb(ar, len);
29548c2ecf20Sopenharmony_ci	if (!skb)
29558c2ecf20Sopenharmony_ci		return ERR_PTR(-ENOMEM);
29568c2ecf20Sopenharmony_ci
29578c2ecf20Sopenharmony_ci	ptr = (void *)skb->data;
29588c2ecf20Sopenharmony_ci
29598c2ecf20Sopenharmony_ci	tlv = ptr;
29608c2ecf20Sopenharmony_ci	tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_PDEV_SET_WMM_PARAMS_CMD);
29618c2ecf20Sopenharmony_ci	tlv->len = __cpu_to_le16(sizeof(*cmd));
29628c2ecf20Sopenharmony_ci	cmd = (void *)tlv->value;
29638c2ecf20Sopenharmony_ci
29648c2ecf20Sopenharmony_ci	/* nothing to set here */
29658c2ecf20Sopenharmony_ci
29668c2ecf20Sopenharmony_ci	ptr += sizeof(*tlv);
29678c2ecf20Sopenharmony_ci	ptr += sizeof(*cmd);
29688c2ecf20Sopenharmony_ci
29698c2ecf20Sopenharmony_ci	ptr = ath10k_wmi_tlv_put_wmm(ptr, &arg->ac_be);
29708c2ecf20Sopenharmony_ci	ptr = ath10k_wmi_tlv_put_wmm(ptr, &arg->ac_bk);
29718c2ecf20Sopenharmony_ci	ptr = ath10k_wmi_tlv_put_wmm(ptr, &arg->ac_vi);
29728c2ecf20Sopenharmony_ci	ptr = ath10k_wmi_tlv_put_wmm(ptr, &arg->ac_vo);
29738c2ecf20Sopenharmony_ci
29748c2ecf20Sopenharmony_ci	ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv pdev set wmm\n");
29758c2ecf20Sopenharmony_ci	return skb;
29768c2ecf20Sopenharmony_ci}
29778c2ecf20Sopenharmony_ci
29788c2ecf20Sopenharmony_cistatic struct sk_buff *
29798c2ecf20Sopenharmony_ciath10k_wmi_tlv_op_gen_request_stats(struct ath10k *ar, u32 stats_mask)
29808c2ecf20Sopenharmony_ci{
29818c2ecf20Sopenharmony_ci	struct wmi_request_stats_cmd *cmd;
29828c2ecf20Sopenharmony_ci	struct wmi_tlv *tlv;
29838c2ecf20Sopenharmony_ci	struct sk_buff *skb;
29848c2ecf20Sopenharmony_ci
29858c2ecf20Sopenharmony_ci	skb = ath10k_wmi_alloc_skb(ar, sizeof(*tlv) + sizeof(*cmd));
29868c2ecf20Sopenharmony_ci	if (!skb)
29878c2ecf20Sopenharmony_ci		return ERR_PTR(-ENOMEM);
29888c2ecf20Sopenharmony_ci
29898c2ecf20Sopenharmony_ci	tlv = (void *)skb->data;
29908c2ecf20Sopenharmony_ci	tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_REQUEST_STATS_CMD);
29918c2ecf20Sopenharmony_ci	tlv->len = __cpu_to_le16(sizeof(*cmd));
29928c2ecf20Sopenharmony_ci	cmd = (void *)tlv->value;
29938c2ecf20Sopenharmony_ci	cmd->stats_id = __cpu_to_le32(stats_mask);
29948c2ecf20Sopenharmony_ci
29958c2ecf20Sopenharmony_ci	ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv request stats\n");
29968c2ecf20Sopenharmony_ci	return skb;
29978c2ecf20Sopenharmony_ci}
29988c2ecf20Sopenharmony_ci
29998c2ecf20Sopenharmony_cistatic struct sk_buff *
30008c2ecf20Sopenharmony_ciath10k_wmi_tlv_op_gen_request_peer_stats_info(struct ath10k *ar,
30018c2ecf20Sopenharmony_ci					      u32 vdev_id,
30028c2ecf20Sopenharmony_ci					      enum wmi_peer_stats_info_request_type type,
30038c2ecf20Sopenharmony_ci					      u8 *addr,
30048c2ecf20Sopenharmony_ci					      u32 reset)
30058c2ecf20Sopenharmony_ci{
30068c2ecf20Sopenharmony_ci	struct wmi_tlv_request_peer_stats_info *cmd;
30078c2ecf20Sopenharmony_ci	struct wmi_tlv *tlv;
30088c2ecf20Sopenharmony_ci	struct sk_buff *skb;
30098c2ecf20Sopenharmony_ci
30108c2ecf20Sopenharmony_ci	skb = ath10k_wmi_alloc_skb(ar, sizeof(*tlv) + sizeof(*cmd));
30118c2ecf20Sopenharmony_ci	if (!skb)
30128c2ecf20Sopenharmony_ci		return ERR_PTR(-ENOMEM);
30138c2ecf20Sopenharmony_ci
30148c2ecf20Sopenharmony_ci	tlv = (void *)skb->data;
30158c2ecf20Sopenharmony_ci	tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_REQUEST_PEER_STATS_INFO_CMD);
30168c2ecf20Sopenharmony_ci	tlv->len = __cpu_to_le16(sizeof(*cmd));
30178c2ecf20Sopenharmony_ci	cmd = (void *)tlv->value;
30188c2ecf20Sopenharmony_ci	cmd->vdev_id = __cpu_to_le32(vdev_id);
30198c2ecf20Sopenharmony_ci	cmd->request_type = __cpu_to_le32(type);
30208c2ecf20Sopenharmony_ci
30218c2ecf20Sopenharmony_ci	if (type == WMI_REQUEST_ONE_PEER_STATS_INFO)
30228c2ecf20Sopenharmony_ci		ether_addr_copy(cmd->peer_macaddr.addr, addr);
30238c2ecf20Sopenharmony_ci
30248c2ecf20Sopenharmony_ci	cmd->reset_after_request = __cpu_to_le32(reset);
30258c2ecf20Sopenharmony_ci	ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv request peer stats info\n");
30268c2ecf20Sopenharmony_ci	return skb;
30278c2ecf20Sopenharmony_ci}
30288c2ecf20Sopenharmony_ci
30298c2ecf20Sopenharmony_cistatic int
30308c2ecf20Sopenharmony_ciath10k_wmi_tlv_op_cleanup_mgmt_tx_send(struct ath10k *ar,
30318c2ecf20Sopenharmony_ci				       struct sk_buff *msdu)
30328c2ecf20Sopenharmony_ci{
30338c2ecf20Sopenharmony_ci	struct ath10k_skb_cb *cb = ATH10K_SKB_CB(msdu);
30348c2ecf20Sopenharmony_ci	struct ath10k_wmi *wmi = &ar->wmi;
30358c2ecf20Sopenharmony_ci
30368c2ecf20Sopenharmony_ci	idr_remove(&wmi->mgmt_pending_tx, cb->msdu_id);
30378c2ecf20Sopenharmony_ci
30388c2ecf20Sopenharmony_ci	return 0;
30398c2ecf20Sopenharmony_ci}
30408c2ecf20Sopenharmony_ci
30418c2ecf20Sopenharmony_cistatic int
30428c2ecf20Sopenharmony_ciath10k_wmi_mgmt_tx_alloc_msdu_id(struct ath10k *ar, struct sk_buff *skb,
30438c2ecf20Sopenharmony_ci				 dma_addr_t paddr)
30448c2ecf20Sopenharmony_ci{
30458c2ecf20Sopenharmony_ci	struct ath10k_wmi *wmi = &ar->wmi;
30468c2ecf20Sopenharmony_ci	struct ath10k_mgmt_tx_pkt_addr *pkt_addr;
30478c2ecf20Sopenharmony_ci	int ret;
30488c2ecf20Sopenharmony_ci
30498c2ecf20Sopenharmony_ci	pkt_addr = kmalloc(sizeof(*pkt_addr), GFP_ATOMIC);
30508c2ecf20Sopenharmony_ci	if (!pkt_addr)
30518c2ecf20Sopenharmony_ci		return -ENOMEM;
30528c2ecf20Sopenharmony_ci
30538c2ecf20Sopenharmony_ci	pkt_addr->vaddr = skb;
30548c2ecf20Sopenharmony_ci	pkt_addr->paddr = paddr;
30558c2ecf20Sopenharmony_ci
30568c2ecf20Sopenharmony_ci	spin_lock_bh(&ar->data_lock);
30578c2ecf20Sopenharmony_ci	ret = idr_alloc(&wmi->mgmt_pending_tx, pkt_addr, 0,
30588c2ecf20Sopenharmony_ci			wmi->mgmt_max_num_pending_tx, GFP_ATOMIC);
30598c2ecf20Sopenharmony_ci	spin_unlock_bh(&ar->data_lock);
30608c2ecf20Sopenharmony_ci
30618c2ecf20Sopenharmony_ci	ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi mgmt tx alloc msdu_id ret %d\n", ret);
30628c2ecf20Sopenharmony_ci	return ret;
30638c2ecf20Sopenharmony_ci}
30648c2ecf20Sopenharmony_ci
30658c2ecf20Sopenharmony_cistatic struct sk_buff *
30668c2ecf20Sopenharmony_ciath10k_wmi_tlv_op_gen_mgmt_tx_send(struct ath10k *ar, struct sk_buff *msdu,
30678c2ecf20Sopenharmony_ci				   dma_addr_t paddr)
30688c2ecf20Sopenharmony_ci{
30698c2ecf20Sopenharmony_ci	struct ath10k_skb_cb *cb = ATH10K_SKB_CB(msdu);
30708c2ecf20Sopenharmony_ci	struct wmi_tlv_mgmt_tx_cmd *cmd;
30718c2ecf20Sopenharmony_ci	struct ieee80211_hdr *hdr;
30728c2ecf20Sopenharmony_ci	struct ath10k_vif *arvif;
30738c2ecf20Sopenharmony_ci	u32 buf_len = msdu->len;
30748c2ecf20Sopenharmony_ci	struct wmi_tlv *tlv;
30758c2ecf20Sopenharmony_ci	struct sk_buff *skb;
30768c2ecf20Sopenharmony_ci	int len, desc_id;
30778c2ecf20Sopenharmony_ci	u32 vdev_id;
30788c2ecf20Sopenharmony_ci	void *ptr;
30798c2ecf20Sopenharmony_ci
30808c2ecf20Sopenharmony_ci	if (!cb->vif)
30818c2ecf20Sopenharmony_ci		return ERR_PTR(-EINVAL);
30828c2ecf20Sopenharmony_ci
30838c2ecf20Sopenharmony_ci	hdr = (struct ieee80211_hdr *)msdu->data;
30848c2ecf20Sopenharmony_ci	arvif = (void *)cb->vif->drv_priv;
30858c2ecf20Sopenharmony_ci	vdev_id = arvif->vdev_id;
30868c2ecf20Sopenharmony_ci
30878c2ecf20Sopenharmony_ci	if (WARN_ON_ONCE(!ieee80211_is_mgmt(hdr->frame_control) &&
30888c2ecf20Sopenharmony_ci			 (!(ieee80211_is_nullfunc(hdr->frame_control) ||
30898c2ecf20Sopenharmony_ci			 ieee80211_is_qos_nullfunc(hdr->frame_control)))))
30908c2ecf20Sopenharmony_ci		return ERR_PTR(-EINVAL);
30918c2ecf20Sopenharmony_ci
30928c2ecf20Sopenharmony_ci	len = sizeof(*cmd) + 2 * sizeof(*tlv);
30938c2ecf20Sopenharmony_ci
30948c2ecf20Sopenharmony_ci	if ((ieee80211_is_action(hdr->frame_control) ||
30958c2ecf20Sopenharmony_ci	     ieee80211_is_deauth(hdr->frame_control) ||
30968c2ecf20Sopenharmony_ci	     ieee80211_is_disassoc(hdr->frame_control)) &&
30978c2ecf20Sopenharmony_ci	     ieee80211_has_protected(hdr->frame_control)) {
30988c2ecf20Sopenharmony_ci		skb_put(msdu, IEEE80211_CCMP_MIC_LEN);
30998c2ecf20Sopenharmony_ci		buf_len += IEEE80211_CCMP_MIC_LEN;
31008c2ecf20Sopenharmony_ci	}
31018c2ecf20Sopenharmony_ci
31028c2ecf20Sopenharmony_ci	buf_len = min_t(u32, buf_len, WMI_TLV_MGMT_TX_FRAME_MAX_LEN);
31038c2ecf20Sopenharmony_ci	buf_len = round_up(buf_len, 4);
31048c2ecf20Sopenharmony_ci
31058c2ecf20Sopenharmony_ci	len += buf_len;
31068c2ecf20Sopenharmony_ci	len = round_up(len, 4);
31078c2ecf20Sopenharmony_ci	skb = ath10k_wmi_alloc_skb(ar, len);
31088c2ecf20Sopenharmony_ci	if (!skb)
31098c2ecf20Sopenharmony_ci		return ERR_PTR(-ENOMEM);
31108c2ecf20Sopenharmony_ci
31118c2ecf20Sopenharmony_ci	desc_id = ath10k_wmi_mgmt_tx_alloc_msdu_id(ar, msdu, paddr);
31128c2ecf20Sopenharmony_ci	if (desc_id < 0)
31138c2ecf20Sopenharmony_ci		goto err_free_skb;
31148c2ecf20Sopenharmony_ci
31158c2ecf20Sopenharmony_ci	cb->msdu_id = desc_id;
31168c2ecf20Sopenharmony_ci
31178c2ecf20Sopenharmony_ci	ptr = (void *)skb->data;
31188c2ecf20Sopenharmony_ci	tlv = ptr;
31198c2ecf20Sopenharmony_ci	tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_MGMT_TX_CMD);
31208c2ecf20Sopenharmony_ci	tlv->len = __cpu_to_le16(sizeof(*cmd));
31218c2ecf20Sopenharmony_ci	cmd = (void *)tlv->value;
31228c2ecf20Sopenharmony_ci	cmd->vdev_id = __cpu_to_le32(vdev_id);
31238c2ecf20Sopenharmony_ci	cmd->desc_id = __cpu_to_le32(desc_id);
31248c2ecf20Sopenharmony_ci	cmd->chanfreq = 0;
31258c2ecf20Sopenharmony_ci	cmd->buf_len = __cpu_to_le32(buf_len);
31268c2ecf20Sopenharmony_ci	cmd->frame_len = __cpu_to_le32(msdu->len);
31278c2ecf20Sopenharmony_ci	cmd->paddr = __cpu_to_le64(paddr);
31288c2ecf20Sopenharmony_ci
31298c2ecf20Sopenharmony_ci	ptr += sizeof(*tlv);
31308c2ecf20Sopenharmony_ci	ptr += sizeof(*cmd);
31318c2ecf20Sopenharmony_ci
31328c2ecf20Sopenharmony_ci	tlv = ptr;
31338c2ecf20Sopenharmony_ci	tlv->tag = __cpu_to_le16(WMI_TLV_TAG_ARRAY_BYTE);
31348c2ecf20Sopenharmony_ci	tlv->len = __cpu_to_le16(buf_len);
31358c2ecf20Sopenharmony_ci
31368c2ecf20Sopenharmony_ci	ptr += sizeof(*tlv);
31378c2ecf20Sopenharmony_ci	memcpy(ptr, msdu->data, buf_len);
31388c2ecf20Sopenharmony_ci
31398c2ecf20Sopenharmony_ci	return skb;
31408c2ecf20Sopenharmony_ci
31418c2ecf20Sopenharmony_cierr_free_skb:
31428c2ecf20Sopenharmony_ci	dev_kfree_skb(skb);
31438c2ecf20Sopenharmony_ci	return ERR_PTR(desc_id);
31448c2ecf20Sopenharmony_ci}
31458c2ecf20Sopenharmony_ci
31468c2ecf20Sopenharmony_cistatic struct sk_buff *
31478c2ecf20Sopenharmony_ciath10k_wmi_tlv_op_gen_force_fw_hang(struct ath10k *ar,
31488c2ecf20Sopenharmony_ci				    enum wmi_force_fw_hang_type type,
31498c2ecf20Sopenharmony_ci				    u32 delay_ms)
31508c2ecf20Sopenharmony_ci{
31518c2ecf20Sopenharmony_ci	struct wmi_force_fw_hang_cmd *cmd;
31528c2ecf20Sopenharmony_ci	struct wmi_tlv *tlv;
31538c2ecf20Sopenharmony_ci	struct sk_buff *skb;
31548c2ecf20Sopenharmony_ci
31558c2ecf20Sopenharmony_ci	skb = ath10k_wmi_alloc_skb(ar, sizeof(*tlv) + sizeof(*cmd));
31568c2ecf20Sopenharmony_ci	if (!skb)
31578c2ecf20Sopenharmony_ci		return ERR_PTR(-ENOMEM);
31588c2ecf20Sopenharmony_ci
31598c2ecf20Sopenharmony_ci	tlv = (void *)skb->data;
31608c2ecf20Sopenharmony_ci	tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_FORCE_FW_HANG_CMD);
31618c2ecf20Sopenharmony_ci	tlv->len = __cpu_to_le16(sizeof(*cmd));
31628c2ecf20Sopenharmony_ci	cmd = (void *)tlv->value;
31638c2ecf20Sopenharmony_ci	cmd->type = __cpu_to_le32(type);
31648c2ecf20Sopenharmony_ci	cmd->delay_ms = __cpu_to_le32(delay_ms);
31658c2ecf20Sopenharmony_ci
31668c2ecf20Sopenharmony_ci	ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv force fw hang\n");
31678c2ecf20Sopenharmony_ci	return skb;
31688c2ecf20Sopenharmony_ci}
31698c2ecf20Sopenharmony_ci
31708c2ecf20Sopenharmony_cistatic struct sk_buff *
31718c2ecf20Sopenharmony_ciath10k_wmi_tlv_op_gen_dbglog_cfg(struct ath10k *ar, u64 module_enable,
31728c2ecf20Sopenharmony_ci				 u32 log_level)
31738c2ecf20Sopenharmony_ci{
31748c2ecf20Sopenharmony_ci	struct wmi_tlv_dbglog_cmd *cmd;
31758c2ecf20Sopenharmony_ci	struct wmi_tlv *tlv;
31768c2ecf20Sopenharmony_ci	struct sk_buff *skb;
31778c2ecf20Sopenharmony_ci	size_t len, bmap_len;
31788c2ecf20Sopenharmony_ci	u32 value;
31798c2ecf20Sopenharmony_ci	void *ptr;
31808c2ecf20Sopenharmony_ci
31818c2ecf20Sopenharmony_ci	if (module_enable) {
31828c2ecf20Sopenharmony_ci		value = WMI_TLV_DBGLOG_LOG_LEVEL_VALUE(
31838c2ecf20Sopenharmony_ci				module_enable,
31848c2ecf20Sopenharmony_ci				WMI_TLV_DBGLOG_LOG_LEVEL_VERBOSE);
31858c2ecf20Sopenharmony_ci	} else {
31868c2ecf20Sopenharmony_ci		value = WMI_TLV_DBGLOG_LOG_LEVEL_VALUE(
31878c2ecf20Sopenharmony_ci				WMI_TLV_DBGLOG_ALL_MODULES,
31888c2ecf20Sopenharmony_ci				WMI_TLV_DBGLOG_LOG_LEVEL_WARN);
31898c2ecf20Sopenharmony_ci	}
31908c2ecf20Sopenharmony_ci
31918c2ecf20Sopenharmony_ci	bmap_len = 0;
31928c2ecf20Sopenharmony_ci	len = sizeof(*tlv) + sizeof(*cmd) + sizeof(*tlv) + bmap_len;
31938c2ecf20Sopenharmony_ci	skb = ath10k_wmi_alloc_skb(ar, len);
31948c2ecf20Sopenharmony_ci	if (!skb)
31958c2ecf20Sopenharmony_ci		return ERR_PTR(-ENOMEM);
31968c2ecf20Sopenharmony_ci
31978c2ecf20Sopenharmony_ci	ptr = (void *)skb->data;
31988c2ecf20Sopenharmony_ci
31998c2ecf20Sopenharmony_ci	tlv = ptr;
32008c2ecf20Sopenharmony_ci	tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_DEBUG_LOG_CONFIG_CMD);
32018c2ecf20Sopenharmony_ci	tlv->len = __cpu_to_le16(sizeof(*cmd));
32028c2ecf20Sopenharmony_ci	cmd = (void *)tlv->value;
32038c2ecf20Sopenharmony_ci	cmd->param = __cpu_to_le32(WMI_TLV_DBGLOG_PARAM_LOG_LEVEL);
32048c2ecf20Sopenharmony_ci	cmd->value = __cpu_to_le32(value);
32058c2ecf20Sopenharmony_ci
32068c2ecf20Sopenharmony_ci	ptr += sizeof(*tlv);
32078c2ecf20Sopenharmony_ci	ptr += sizeof(*cmd);
32088c2ecf20Sopenharmony_ci
32098c2ecf20Sopenharmony_ci	tlv = ptr;
32108c2ecf20Sopenharmony_ci	tlv->tag = __cpu_to_le16(WMI_TLV_TAG_ARRAY_UINT32);
32118c2ecf20Sopenharmony_ci	tlv->len = __cpu_to_le16(bmap_len);
32128c2ecf20Sopenharmony_ci
32138c2ecf20Sopenharmony_ci	/* nothing to do here */
32148c2ecf20Sopenharmony_ci
32158c2ecf20Sopenharmony_ci	ptr += sizeof(*tlv);
32168c2ecf20Sopenharmony_ci	ptr += sizeof(bmap_len);
32178c2ecf20Sopenharmony_ci
32188c2ecf20Sopenharmony_ci	ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv dbglog value 0x%08x\n", value);
32198c2ecf20Sopenharmony_ci	return skb;
32208c2ecf20Sopenharmony_ci}
32218c2ecf20Sopenharmony_ci
32228c2ecf20Sopenharmony_cistatic struct sk_buff *
32238c2ecf20Sopenharmony_ciath10k_wmi_tlv_op_gen_pktlog_enable(struct ath10k *ar, u32 filter)
32248c2ecf20Sopenharmony_ci{
32258c2ecf20Sopenharmony_ci	struct wmi_tlv_pktlog_enable *cmd;
32268c2ecf20Sopenharmony_ci	struct wmi_tlv *tlv;
32278c2ecf20Sopenharmony_ci	struct sk_buff *skb;
32288c2ecf20Sopenharmony_ci	void *ptr;
32298c2ecf20Sopenharmony_ci	size_t len;
32308c2ecf20Sopenharmony_ci
32318c2ecf20Sopenharmony_ci	len = sizeof(*tlv) + sizeof(*cmd);
32328c2ecf20Sopenharmony_ci	skb = ath10k_wmi_alloc_skb(ar, len);
32338c2ecf20Sopenharmony_ci	if (!skb)
32348c2ecf20Sopenharmony_ci		return ERR_PTR(-ENOMEM);
32358c2ecf20Sopenharmony_ci
32368c2ecf20Sopenharmony_ci	ptr = (void *)skb->data;
32378c2ecf20Sopenharmony_ci	tlv = ptr;
32388c2ecf20Sopenharmony_ci	tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_PDEV_PKTLOG_ENABLE_CMD);
32398c2ecf20Sopenharmony_ci	tlv->len = __cpu_to_le16(sizeof(*cmd));
32408c2ecf20Sopenharmony_ci	cmd = (void *)tlv->value;
32418c2ecf20Sopenharmony_ci	cmd->filter = __cpu_to_le32(filter);
32428c2ecf20Sopenharmony_ci
32438c2ecf20Sopenharmony_ci	ptr += sizeof(*tlv);
32448c2ecf20Sopenharmony_ci	ptr += sizeof(*cmd);
32458c2ecf20Sopenharmony_ci
32468c2ecf20Sopenharmony_ci	ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv pktlog enable filter 0x%08x\n",
32478c2ecf20Sopenharmony_ci		   filter);
32488c2ecf20Sopenharmony_ci	return skb;
32498c2ecf20Sopenharmony_ci}
32508c2ecf20Sopenharmony_ci
32518c2ecf20Sopenharmony_cistatic struct sk_buff *
32528c2ecf20Sopenharmony_ciath10k_wmi_tlv_op_gen_pdev_get_temperature(struct ath10k *ar)
32538c2ecf20Sopenharmony_ci{
32548c2ecf20Sopenharmony_ci	struct wmi_tlv_pdev_get_temp_cmd *cmd;
32558c2ecf20Sopenharmony_ci	struct wmi_tlv *tlv;
32568c2ecf20Sopenharmony_ci	struct sk_buff *skb;
32578c2ecf20Sopenharmony_ci
32588c2ecf20Sopenharmony_ci	skb = ath10k_wmi_alloc_skb(ar, sizeof(*tlv) + sizeof(*cmd));
32598c2ecf20Sopenharmony_ci	if (!skb)
32608c2ecf20Sopenharmony_ci		return ERR_PTR(-ENOMEM);
32618c2ecf20Sopenharmony_ci
32628c2ecf20Sopenharmony_ci	tlv = (void *)skb->data;
32638c2ecf20Sopenharmony_ci	tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_PDEV_GET_TEMPERATURE_CMD);
32648c2ecf20Sopenharmony_ci	tlv->len = __cpu_to_le16(sizeof(*cmd));
32658c2ecf20Sopenharmony_ci	cmd = (void *)tlv->value;
32668c2ecf20Sopenharmony_ci	ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi pdev get temperature tlv\n");
32678c2ecf20Sopenharmony_ci	return skb;
32688c2ecf20Sopenharmony_ci}
32698c2ecf20Sopenharmony_ci
32708c2ecf20Sopenharmony_cistatic struct sk_buff *
32718c2ecf20Sopenharmony_ciath10k_wmi_tlv_op_gen_pktlog_disable(struct ath10k *ar)
32728c2ecf20Sopenharmony_ci{
32738c2ecf20Sopenharmony_ci	struct wmi_tlv_pktlog_disable *cmd;
32748c2ecf20Sopenharmony_ci	struct wmi_tlv *tlv;
32758c2ecf20Sopenharmony_ci	struct sk_buff *skb;
32768c2ecf20Sopenharmony_ci	void *ptr;
32778c2ecf20Sopenharmony_ci	size_t len;
32788c2ecf20Sopenharmony_ci
32798c2ecf20Sopenharmony_ci	len = sizeof(*tlv) + sizeof(*cmd);
32808c2ecf20Sopenharmony_ci	skb = ath10k_wmi_alloc_skb(ar, len);
32818c2ecf20Sopenharmony_ci	if (!skb)
32828c2ecf20Sopenharmony_ci		return ERR_PTR(-ENOMEM);
32838c2ecf20Sopenharmony_ci
32848c2ecf20Sopenharmony_ci	ptr = (void *)skb->data;
32858c2ecf20Sopenharmony_ci	tlv = ptr;
32868c2ecf20Sopenharmony_ci	tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_PDEV_PKTLOG_DISABLE_CMD);
32878c2ecf20Sopenharmony_ci	tlv->len = __cpu_to_le16(sizeof(*cmd));
32888c2ecf20Sopenharmony_ci	cmd = (void *)tlv->value;
32898c2ecf20Sopenharmony_ci
32908c2ecf20Sopenharmony_ci	ptr += sizeof(*tlv);
32918c2ecf20Sopenharmony_ci	ptr += sizeof(*cmd);
32928c2ecf20Sopenharmony_ci
32938c2ecf20Sopenharmony_ci	ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv pktlog disable\n");
32948c2ecf20Sopenharmony_ci	return skb;
32958c2ecf20Sopenharmony_ci}
32968c2ecf20Sopenharmony_ci
32978c2ecf20Sopenharmony_cistatic struct sk_buff *
32988c2ecf20Sopenharmony_ciath10k_wmi_tlv_op_gen_bcn_tmpl(struct ath10k *ar, u32 vdev_id,
32998c2ecf20Sopenharmony_ci			       u32 tim_ie_offset, struct sk_buff *bcn,
33008c2ecf20Sopenharmony_ci			       u32 prb_caps, u32 prb_erp, void *prb_ies,
33018c2ecf20Sopenharmony_ci			       size_t prb_ies_len)
33028c2ecf20Sopenharmony_ci{
33038c2ecf20Sopenharmony_ci	struct wmi_tlv_bcn_tmpl_cmd *cmd;
33048c2ecf20Sopenharmony_ci	struct wmi_tlv_bcn_prb_info *info;
33058c2ecf20Sopenharmony_ci	struct wmi_tlv *tlv;
33068c2ecf20Sopenharmony_ci	struct sk_buff *skb;
33078c2ecf20Sopenharmony_ci	void *ptr;
33088c2ecf20Sopenharmony_ci	size_t len;
33098c2ecf20Sopenharmony_ci
33108c2ecf20Sopenharmony_ci	if (WARN_ON(prb_ies_len > 0 && !prb_ies))
33118c2ecf20Sopenharmony_ci		return ERR_PTR(-EINVAL);
33128c2ecf20Sopenharmony_ci
33138c2ecf20Sopenharmony_ci	len = sizeof(*tlv) + sizeof(*cmd) +
33148c2ecf20Sopenharmony_ci	      sizeof(*tlv) + sizeof(*info) + prb_ies_len +
33158c2ecf20Sopenharmony_ci	      sizeof(*tlv) + roundup(bcn->len, 4);
33168c2ecf20Sopenharmony_ci	skb = ath10k_wmi_alloc_skb(ar, len);
33178c2ecf20Sopenharmony_ci	if (!skb)
33188c2ecf20Sopenharmony_ci		return ERR_PTR(-ENOMEM);
33198c2ecf20Sopenharmony_ci
33208c2ecf20Sopenharmony_ci	ptr = (void *)skb->data;
33218c2ecf20Sopenharmony_ci	tlv = ptr;
33228c2ecf20Sopenharmony_ci	tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_BCN_TMPL_CMD);
33238c2ecf20Sopenharmony_ci	tlv->len = __cpu_to_le16(sizeof(*cmd));
33248c2ecf20Sopenharmony_ci	cmd = (void *)tlv->value;
33258c2ecf20Sopenharmony_ci	cmd->vdev_id = __cpu_to_le32(vdev_id);
33268c2ecf20Sopenharmony_ci	cmd->tim_ie_offset = __cpu_to_le32(tim_ie_offset);
33278c2ecf20Sopenharmony_ci	cmd->buf_len = __cpu_to_le32(bcn->len);
33288c2ecf20Sopenharmony_ci
33298c2ecf20Sopenharmony_ci	ptr += sizeof(*tlv);
33308c2ecf20Sopenharmony_ci	ptr += sizeof(*cmd);
33318c2ecf20Sopenharmony_ci
33328c2ecf20Sopenharmony_ci	/* FIXME: prb_ies_len should be probably aligned to 4byte boundary but
33338c2ecf20Sopenharmony_ci	 * then it is then impossible to pass original ie len.
33348c2ecf20Sopenharmony_ci	 * This chunk is not used yet so if setting probe resp template yields
33358c2ecf20Sopenharmony_ci	 * problems with beaconing or crashes firmware look here.
33368c2ecf20Sopenharmony_ci	 */
33378c2ecf20Sopenharmony_ci	tlv = ptr;
33388c2ecf20Sopenharmony_ci	tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_BCN_PRB_INFO);
33398c2ecf20Sopenharmony_ci	tlv->len = __cpu_to_le16(sizeof(*info) + prb_ies_len);
33408c2ecf20Sopenharmony_ci	info = (void *)tlv->value;
33418c2ecf20Sopenharmony_ci	info->caps = __cpu_to_le32(prb_caps);
33428c2ecf20Sopenharmony_ci	info->erp = __cpu_to_le32(prb_erp);
33438c2ecf20Sopenharmony_ci	memcpy(info->ies, prb_ies, prb_ies_len);
33448c2ecf20Sopenharmony_ci
33458c2ecf20Sopenharmony_ci	ptr += sizeof(*tlv);
33468c2ecf20Sopenharmony_ci	ptr += sizeof(*info);
33478c2ecf20Sopenharmony_ci	ptr += prb_ies_len;
33488c2ecf20Sopenharmony_ci
33498c2ecf20Sopenharmony_ci	tlv = ptr;
33508c2ecf20Sopenharmony_ci	tlv->tag = __cpu_to_le16(WMI_TLV_TAG_ARRAY_BYTE);
33518c2ecf20Sopenharmony_ci	tlv->len = __cpu_to_le16(roundup(bcn->len, 4));
33528c2ecf20Sopenharmony_ci	memcpy(tlv->value, bcn->data, bcn->len);
33538c2ecf20Sopenharmony_ci
33548c2ecf20Sopenharmony_ci	/* FIXME: Adjust TSF? */
33558c2ecf20Sopenharmony_ci
33568c2ecf20Sopenharmony_ci	ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv bcn tmpl vdev_id %i\n",
33578c2ecf20Sopenharmony_ci		   vdev_id);
33588c2ecf20Sopenharmony_ci	return skb;
33598c2ecf20Sopenharmony_ci}
33608c2ecf20Sopenharmony_ci
33618c2ecf20Sopenharmony_cistatic struct sk_buff *
33628c2ecf20Sopenharmony_ciath10k_wmi_tlv_op_gen_prb_tmpl(struct ath10k *ar, u32 vdev_id,
33638c2ecf20Sopenharmony_ci			       struct sk_buff *prb)
33648c2ecf20Sopenharmony_ci{
33658c2ecf20Sopenharmony_ci	struct wmi_tlv_prb_tmpl_cmd *cmd;
33668c2ecf20Sopenharmony_ci	struct wmi_tlv_bcn_prb_info *info;
33678c2ecf20Sopenharmony_ci	struct wmi_tlv *tlv;
33688c2ecf20Sopenharmony_ci	struct sk_buff *skb;
33698c2ecf20Sopenharmony_ci	void *ptr;
33708c2ecf20Sopenharmony_ci	size_t len;
33718c2ecf20Sopenharmony_ci
33728c2ecf20Sopenharmony_ci	len = sizeof(*tlv) + sizeof(*cmd) +
33738c2ecf20Sopenharmony_ci	      sizeof(*tlv) + sizeof(*info) +
33748c2ecf20Sopenharmony_ci	      sizeof(*tlv) + roundup(prb->len, 4);
33758c2ecf20Sopenharmony_ci	skb = ath10k_wmi_alloc_skb(ar, len);
33768c2ecf20Sopenharmony_ci	if (!skb)
33778c2ecf20Sopenharmony_ci		return ERR_PTR(-ENOMEM);
33788c2ecf20Sopenharmony_ci
33798c2ecf20Sopenharmony_ci	ptr = (void *)skb->data;
33808c2ecf20Sopenharmony_ci	tlv = ptr;
33818c2ecf20Sopenharmony_ci	tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_PRB_TMPL_CMD);
33828c2ecf20Sopenharmony_ci	tlv->len = __cpu_to_le16(sizeof(*cmd));
33838c2ecf20Sopenharmony_ci	cmd = (void *)tlv->value;
33848c2ecf20Sopenharmony_ci	cmd->vdev_id = __cpu_to_le32(vdev_id);
33858c2ecf20Sopenharmony_ci	cmd->buf_len = __cpu_to_le32(prb->len);
33868c2ecf20Sopenharmony_ci
33878c2ecf20Sopenharmony_ci	ptr += sizeof(*tlv);
33888c2ecf20Sopenharmony_ci	ptr += sizeof(*cmd);
33898c2ecf20Sopenharmony_ci
33908c2ecf20Sopenharmony_ci	tlv = ptr;
33918c2ecf20Sopenharmony_ci	tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_BCN_PRB_INFO);
33928c2ecf20Sopenharmony_ci	tlv->len = __cpu_to_le16(sizeof(*info));
33938c2ecf20Sopenharmony_ci	info = (void *)tlv->value;
33948c2ecf20Sopenharmony_ci	info->caps = 0;
33958c2ecf20Sopenharmony_ci	info->erp = 0;
33968c2ecf20Sopenharmony_ci
33978c2ecf20Sopenharmony_ci	ptr += sizeof(*tlv);
33988c2ecf20Sopenharmony_ci	ptr += sizeof(*info);
33998c2ecf20Sopenharmony_ci
34008c2ecf20Sopenharmony_ci	tlv = ptr;
34018c2ecf20Sopenharmony_ci	tlv->tag = __cpu_to_le16(WMI_TLV_TAG_ARRAY_BYTE);
34028c2ecf20Sopenharmony_ci	tlv->len = __cpu_to_le16(roundup(prb->len, 4));
34038c2ecf20Sopenharmony_ci	memcpy(tlv->value, prb->data, prb->len);
34048c2ecf20Sopenharmony_ci
34058c2ecf20Sopenharmony_ci	ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv prb tmpl vdev_id %i\n",
34068c2ecf20Sopenharmony_ci		   vdev_id);
34078c2ecf20Sopenharmony_ci	return skb;
34088c2ecf20Sopenharmony_ci}
34098c2ecf20Sopenharmony_ci
34108c2ecf20Sopenharmony_cistatic struct sk_buff *
34118c2ecf20Sopenharmony_ciath10k_wmi_tlv_op_gen_p2p_go_bcn_ie(struct ath10k *ar, u32 vdev_id,
34128c2ecf20Sopenharmony_ci				    const u8 *p2p_ie)
34138c2ecf20Sopenharmony_ci{
34148c2ecf20Sopenharmony_ci	struct wmi_tlv_p2p_go_bcn_ie *cmd;
34158c2ecf20Sopenharmony_ci	struct wmi_tlv *tlv;
34168c2ecf20Sopenharmony_ci	struct sk_buff *skb;
34178c2ecf20Sopenharmony_ci	void *ptr;
34188c2ecf20Sopenharmony_ci	size_t len;
34198c2ecf20Sopenharmony_ci
34208c2ecf20Sopenharmony_ci	len = sizeof(*tlv) + sizeof(*cmd) +
34218c2ecf20Sopenharmony_ci	      sizeof(*tlv) + roundup(p2p_ie[1] + 2, 4);
34228c2ecf20Sopenharmony_ci	skb = ath10k_wmi_alloc_skb(ar, len);
34238c2ecf20Sopenharmony_ci	if (!skb)
34248c2ecf20Sopenharmony_ci		return ERR_PTR(-ENOMEM);
34258c2ecf20Sopenharmony_ci
34268c2ecf20Sopenharmony_ci	ptr = (void *)skb->data;
34278c2ecf20Sopenharmony_ci	tlv = ptr;
34288c2ecf20Sopenharmony_ci	tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_P2P_GO_SET_BEACON_IE);
34298c2ecf20Sopenharmony_ci	tlv->len = __cpu_to_le16(sizeof(*cmd));
34308c2ecf20Sopenharmony_ci	cmd = (void *)tlv->value;
34318c2ecf20Sopenharmony_ci	cmd->vdev_id = __cpu_to_le32(vdev_id);
34328c2ecf20Sopenharmony_ci	cmd->ie_len = __cpu_to_le32(p2p_ie[1] + 2);
34338c2ecf20Sopenharmony_ci
34348c2ecf20Sopenharmony_ci	ptr += sizeof(*tlv);
34358c2ecf20Sopenharmony_ci	ptr += sizeof(*cmd);
34368c2ecf20Sopenharmony_ci
34378c2ecf20Sopenharmony_ci	tlv = ptr;
34388c2ecf20Sopenharmony_ci	tlv->tag = __cpu_to_le16(WMI_TLV_TAG_ARRAY_BYTE);
34398c2ecf20Sopenharmony_ci	tlv->len = __cpu_to_le16(roundup(p2p_ie[1] + 2, 4));
34408c2ecf20Sopenharmony_ci	memcpy(tlv->value, p2p_ie, p2p_ie[1] + 2);
34418c2ecf20Sopenharmony_ci
34428c2ecf20Sopenharmony_ci	ptr += sizeof(*tlv);
34438c2ecf20Sopenharmony_ci	ptr += roundup(p2p_ie[1] + 2, 4);
34448c2ecf20Sopenharmony_ci
34458c2ecf20Sopenharmony_ci	ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv p2p go bcn ie for vdev %i\n",
34468c2ecf20Sopenharmony_ci		   vdev_id);
34478c2ecf20Sopenharmony_ci	return skb;
34488c2ecf20Sopenharmony_ci}
34498c2ecf20Sopenharmony_ci
34508c2ecf20Sopenharmony_cistatic struct sk_buff *
34518c2ecf20Sopenharmony_ciath10k_wmi_tlv_op_gen_update_fw_tdls_state(struct ath10k *ar, u32 vdev_id,
34528c2ecf20Sopenharmony_ci					   enum wmi_tdls_state state)
34538c2ecf20Sopenharmony_ci{
34548c2ecf20Sopenharmony_ci	struct wmi_tdls_set_state_cmd *cmd;
34558c2ecf20Sopenharmony_ci	struct wmi_tlv *tlv;
34568c2ecf20Sopenharmony_ci	struct sk_buff *skb;
34578c2ecf20Sopenharmony_ci	void *ptr;
34588c2ecf20Sopenharmony_ci	size_t len;
34598c2ecf20Sopenharmony_ci	/* Set to options from wmi_tlv_tdls_options,
34608c2ecf20Sopenharmony_ci	 * for now none of them are enabled.
34618c2ecf20Sopenharmony_ci	 */
34628c2ecf20Sopenharmony_ci	u32 options = 0;
34638c2ecf20Sopenharmony_ci
34648c2ecf20Sopenharmony_ci	if (test_bit(WMI_SERVICE_TDLS_UAPSD_BUFFER_STA, ar->wmi.svc_map))
34658c2ecf20Sopenharmony_ci		options |=  WMI_TLV_TDLS_BUFFER_STA_EN;
34668c2ecf20Sopenharmony_ci
34678c2ecf20Sopenharmony_ci	/* WMI_TDLS_ENABLE_ACTIVE_EXTERNAL_CONTROL means firm will handle TDLS
34688c2ecf20Sopenharmony_ci	 * link inactivity detecting logic.
34698c2ecf20Sopenharmony_ci	 */
34708c2ecf20Sopenharmony_ci	if (state == WMI_TDLS_ENABLE_ACTIVE)
34718c2ecf20Sopenharmony_ci		state = WMI_TDLS_ENABLE_ACTIVE_EXTERNAL_CONTROL;
34728c2ecf20Sopenharmony_ci
34738c2ecf20Sopenharmony_ci	len = sizeof(*tlv) + sizeof(*cmd);
34748c2ecf20Sopenharmony_ci	skb = ath10k_wmi_alloc_skb(ar, len);
34758c2ecf20Sopenharmony_ci	if (!skb)
34768c2ecf20Sopenharmony_ci		return ERR_PTR(-ENOMEM);
34778c2ecf20Sopenharmony_ci
34788c2ecf20Sopenharmony_ci	ptr = (void *)skb->data;
34798c2ecf20Sopenharmony_ci	tlv = ptr;
34808c2ecf20Sopenharmony_ci	tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_TDLS_SET_STATE_CMD);
34818c2ecf20Sopenharmony_ci	tlv->len = __cpu_to_le16(sizeof(*cmd));
34828c2ecf20Sopenharmony_ci
34838c2ecf20Sopenharmony_ci	cmd = (void *)tlv->value;
34848c2ecf20Sopenharmony_ci	cmd->vdev_id = __cpu_to_le32(vdev_id);
34858c2ecf20Sopenharmony_ci	cmd->state = __cpu_to_le32(state);
34868c2ecf20Sopenharmony_ci	cmd->notification_interval_ms = __cpu_to_le32(5000);
34878c2ecf20Sopenharmony_ci	cmd->tx_discovery_threshold = __cpu_to_le32(100);
34888c2ecf20Sopenharmony_ci	cmd->tx_teardown_threshold = __cpu_to_le32(5);
34898c2ecf20Sopenharmony_ci	cmd->rssi_teardown_threshold = __cpu_to_le32(-75);
34908c2ecf20Sopenharmony_ci	cmd->rssi_delta = __cpu_to_le32(-20);
34918c2ecf20Sopenharmony_ci	cmd->tdls_options = __cpu_to_le32(options);
34928c2ecf20Sopenharmony_ci	cmd->tdls_peer_traffic_ind_window = __cpu_to_le32(2);
34938c2ecf20Sopenharmony_ci	cmd->tdls_peer_traffic_response_timeout_ms = __cpu_to_le32(5000);
34948c2ecf20Sopenharmony_ci	cmd->tdls_puapsd_mask = __cpu_to_le32(0xf);
34958c2ecf20Sopenharmony_ci	cmd->tdls_puapsd_inactivity_time_ms = __cpu_to_le32(0);
34968c2ecf20Sopenharmony_ci	cmd->tdls_puapsd_rx_frame_threshold = __cpu_to_le32(10);
34978c2ecf20Sopenharmony_ci
34988c2ecf20Sopenharmony_ci	ptr += sizeof(*tlv);
34998c2ecf20Sopenharmony_ci	ptr += sizeof(*cmd);
35008c2ecf20Sopenharmony_ci
35018c2ecf20Sopenharmony_ci	ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv update fw tdls state %d for vdev %i\n",
35028c2ecf20Sopenharmony_ci		   state, vdev_id);
35038c2ecf20Sopenharmony_ci	return skb;
35048c2ecf20Sopenharmony_ci}
35058c2ecf20Sopenharmony_ci
35068c2ecf20Sopenharmony_cistatic u32 ath10k_wmi_tlv_prepare_peer_qos(u8 uapsd_queues, u8 sp)
35078c2ecf20Sopenharmony_ci{
35088c2ecf20Sopenharmony_ci	u32 peer_qos = 0;
35098c2ecf20Sopenharmony_ci
35108c2ecf20Sopenharmony_ci	if (uapsd_queues & IEEE80211_WMM_IE_STA_QOSINFO_AC_VO)
35118c2ecf20Sopenharmony_ci		peer_qos |= WMI_TLV_TDLS_PEER_QOS_AC_VO;
35128c2ecf20Sopenharmony_ci	if (uapsd_queues & IEEE80211_WMM_IE_STA_QOSINFO_AC_VI)
35138c2ecf20Sopenharmony_ci		peer_qos |= WMI_TLV_TDLS_PEER_QOS_AC_VI;
35148c2ecf20Sopenharmony_ci	if (uapsd_queues & IEEE80211_WMM_IE_STA_QOSINFO_AC_BK)
35158c2ecf20Sopenharmony_ci		peer_qos |= WMI_TLV_TDLS_PEER_QOS_AC_BK;
35168c2ecf20Sopenharmony_ci	if (uapsd_queues & IEEE80211_WMM_IE_STA_QOSINFO_AC_BE)
35178c2ecf20Sopenharmony_ci		peer_qos |= WMI_TLV_TDLS_PEER_QOS_AC_BE;
35188c2ecf20Sopenharmony_ci
35198c2ecf20Sopenharmony_ci	peer_qos |= SM(sp, WMI_TLV_TDLS_PEER_SP);
35208c2ecf20Sopenharmony_ci
35218c2ecf20Sopenharmony_ci	return peer_qos;
35228c2ecf20Sopenharmony_ci}
35238c2ecf20Sopenharmony_ci
35248c2ecf20Sopenharmony_cistatic struct sk_buff *
35258c2ecf20Sopenharmony_ciath10k_wmi_tlv_op_gen_tdls_peer_update(struct ath10k *ar,
35268c2ecf20Sopenharmony_ci				       const struct wmi_tdls_peer_update_cmd_arg *arg,
35278c2ecf20Sopenharmony_ci				       const struct wmi_tdls_peer_capab_arg *cap,
35288c2ecf20Sopenharmony_ci				       const struct wmi_channel_arg *chan_arg)
35298c2ecf20Sopenharmony_ci{
35308c2ecf20Sopenharmony_ci	struct wmi_tdls_peer_update_cmd *cmd;
35318c2ecf20Sopenharmony_ci	struct wmi_tdls_peer_capab *peer_cap;
35328c2ecf20Sopenharmony_ci	struct wmi_channel *chan;
35338c2ecf20Sopenharmony_ci	struct wmi_tlv *tlv;
35348c2ecf20Sopenharmony_ci	struct sk_buff *skb;
35358c2ecf20Sopenharmony_ci	u32 peer_qos;
35368c2ecf20Sopenharmony_ci	void *ptr;
35378c2ecf20Sopenharmony_ci	int len;
35388c2ecf20Sopenharmony_ci	int i;
35398c2ecf20Sopenharmony_ci
35408c2ecf20Sopenharmony_ci	len = sizeof(*tlv) + sizeof(*cmd) +
35418c2ecf20Sopenharmony_ci	      sizeof(*tlv) + sizeof(*peer_cap) +
35428c2ecf20Sopenharmony_ci	      sizeof(*tlv) + cap->peer_chan_len * sizeof(*chan);
35438c2ecf20Sopenharmony_ci
35448c2ecf20Sopenharmony_ci	skb = ath10k_wmi_alloc_skb(ar, len);
35458c2ecf20Sopenharmony_ci	if (!skb)
35468c2ecf20Sopenharmony_ci		return ERR_PTR(-ENOMEM);
35478c2ecf20Sopenharmony_ci
35488c2ecf20Sopenharmony_ci	ptr = (void *)skb->data;
35498c2ecf20Sopenharmony_ci	tlv = ptr;
35508c2ecf20Sopenharmony_ci	tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_TDLS_PEER_UPDATE_CMD);
35518c2ecf20Sopenharmony_ci	tlv->len = __cpu_to_le16(sizeof(*cmd));
35528c2ecf20Sopenharmony_ci
35538c2ecf20Sopenharmony_ci	cmd = (void *)tlv->value;
35548c2ecf20Sopenharmony_ci	cmd->vdev_id = __cpu_to_le32(arg->vdev_id);
35558c2ecf20Sopenharmony_ci	ether_addr_copy(cmd->peer_macaddr.addr, arg->addr);
35568c2ecf20Sopenharmony_ci	cmd->peer_state = __cpu_to_le32(arg->peer_state);
35578c2ecf20Sopenharmony_ci
35588c2ecf20Sopenharmony_ci	ptr += sizeof(*tlv);
35598c2ecf20Sopenharmony_ci	ptr += sizeof(*cmd);
35608c2ecf20Sopenharmony_ci
35618c2ecf20Sopenharmony_ci	tlv = ptr;
35628c2ecf20Sopenharmony_ci	tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_TDLS_PEER_CAPABILITIES);
35638c2ecf20Sopenharmony_ci	tlv->len = __cpu_to_le16(sizeof(*peer_cap));
35648c2ecf20Sopenharmony_ci	peer_cap = (void *)tlv->value;
35658c2ecf20Sopenharmony_ci	peer_qos = ath10k_wmi_tlv_prepare_peer_qos(cap->peer_uapsd_queues,
35668c2ecf20Sopenharmony_ci						   cap->peer_max_sp);
35678c2ecf20Sopenharmony_ci	peer_cap->peer_qos = __cpu_to_le32(peer_qos);
35688c2ecf20Sopenharmony_ci	peer_cap->buff_sta_support = __cpu_to_le32(cap->buff_sta_support);
35698c2ecf20Sopenharmony_ci	peer_cap->off_chan_support = __cpu_to_le32(cap->off_chan_support);
35708c2ecf20Sopenharmony_ci	peer_cap->peer_curr_operclass = __cpu_to_le32(cap->peer_curr_operclass);
35718c2ecf20Sopenharmony_ci	peer_cap->self_curr_operclass = __cpu_to_le32(cap->self_curr_operclass);
35728c2ecf20Sopenharmony_ci	peer_cap->peer_chan_len = __cpu_to_le32(cap->peer_chan_len);
35738c2ecf20Sopenharmony_ci	peer_cap->peer_operclass_len = __cpu_to_le32(cap->peer_operclass_len);
35748c2ecf20Sopenharmony_ci
35758c2ecf20Sopenharmony_ci	for (i = 0; i < WMI_TDLS_MAX_SUPP_OPER_CLASSES; i++)
35768c2ecf20Sopenharmony_ci		peer_cap->peer_operclass[i] = cap->peer_operclass[i];
35778c2ecf20Sopenharmony_ci
35788c2ecf20Sopenharmony_ci	peer_cap->is_peer_responder = __cpu_to_le32(cap->is_peer_responder);
35798c2ecf20Sopenharmony_ci	peer_cap->pref_offchan_num = __cpu_to_le32(cap->pref_offchan_num);
35808c2ecf20Sopenharmony_ci	peer_cap->pref_offchan_bw = __cpu_to_le32(cap->pref_offchan_bw);
35818c2ecf20Sopenharmony_ci
35828c2ecf20Sopenharmony_ci	ptr += sizeof(*tlv);
35838c2ecf20Sopenharmony_ci	ptr += sizeof(*peer_cap);
35848c2ecf20Sopenharmony_ci
35858c2ecf20Sopenharmony_ci	tlv = ptr;
35868c2ecf20Sopenharmony_ci	tlv->tag = __cpu_to_le16(WMI_TLV_TAG_ARRAY_STRUCT);
35878c2ecf20Sopenharmony_ci	tlv->len = __cpu_to_le16(cap->peer_chan_len * sizeof(*chan));
35888c2ecf20Sopenharmony_ci
35898c2ecf20Sopenharmony_ci	ptr += sizeof(*tlv);
35908c2ecf20Sopenharmony_ci
35918c2ecf20Sopenharmony_ci	for (i = 0; i < cap->peer_chan_len; i++) {
35928c2ecf20Sopenharmony_ci		tlv = ptr;
35938c2ecf20Sopenharmony_ci		tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_CHANNEL);
35948c2ecf20Sopenharmony_ci		tlv->len = __cpu_to_le16(sizeof(*chan));
35958c2ecf20Sopenharmony_ci		chan = (void *)tlv->value;
35968c2ecf20Sopenharmony_ci		ath10k_wmi_put_wmi_channel(ar, chan, &chan_arg[i]);
35978c2ecf20Sopenharmony_ci
35988c2ecf20Sopenharmony_ci		ptr += sizeof(*tlv);
35998c2ecf20Sopenharmony_ci		ptr += sizeof(*chan);
36008c2ecf20Sopenharmony_ci	}
36018c2ecf20Sopenharmony_ci
36028c2ecf20Sopenharmony_ci	ath10k_dbg(ar, ATH10K_DBG_WMI,
36038c2ecf20Sopenharmony_ci		   "wmi tlv tdls peer update vdev %i state %d n_chans %u\n",
36048c2ecf20Sopenharmony_ci		   arg->vdev_id, arg->peer_state, cap->peer_chan_len);
36058c2ecf20Sopenharmony_ci	return skb;
36068c2ecf20Sopenharmony_ci}
36078c2ecf20Sopenharmony_ci
36088c2ecf20Sopenharmony_cistatic struct sk_buff *
36098c2ecf20Sopenharmony_ciath10k_wmi_tlv_op_gen_pdev_set_quiet_mode(struct ath10k *ar, u32 period,
36108c2ecf20Sopenharmony_ci					  u32 duration, u32 next_offset,
36118c2ecf20Sopenharmony_ci					  u32 enabled)
36128c2ecf20Sopenharmony_ci{
36138c2ecf20Sopenharmony_ci	struct wmi_tlv_set_quiet_cmd *cmd;
36148c2ecf20Sopenharmony_ci	struct wmi_tlv *tlv;
36158c2ecf20Sopenharmony_ci	struct sk_buff *skb;
36168c2ecf20Sopenharmony_ci
36178c2ecf20Sopenharmony_ci	skb = ath10k_wmi_alloc_skb(ar, sizeof(*tlv) + sizeof(*cmd));
36188c2ecf20Sopenharmony_ci	if (!skb)
36198c2ecf20Sopenharmony_ci		return ERR_PTR(-ENOMEM);
36208c2ecf20Sopenharmony_ci
36218c2ecf20Sopenharmony_ci	tlv = (void *)skb->data;
36228c2ecf20Sopenharmony_ci	tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_PDEV_SET_QUIET_CMD);
36238c2ecf20Sopenharmony_ci	tlv->len = __cpu_to_le16(sizeof(*cmd));
36248c2ecf20Sopenharmony_ci	cmd = (void *)tlv->value;
36258c2ecf20Sopenharmony_ci
36268c2ecf20Sopenharmony_ci	/* vdev_id is not in use, set to 0 */
36278c2ecf20Sopenharmony_ci	cmd->vdev_id = __cpu_to_le32(0);
36288c2ecf20Sopenharmony_ci	cmd->period = __cpu_to_le32(period);
36298c2ecf20Sopenharmony_ci	cmd->duration = __cpu_to_le32(duration);
36308c2ecf20Sopenharmony_ci	cmd->next_start = __cpu_to_le32(next_offset);
36318c2ecf20Sopenharmony_ci	cmd->enabled = __cpu_to_le32(enabled);
36328c2ecf20Sopenharmony_ci
36338c2ecf20Sopenharmony_ci	ath10k_dbg(ar, ATH10K_DBG_WMI,
36348c2ecf20Sopenharmony_ci		   "wmi tlv quiet param: period %u duration %u enabled %d\n",
36358c2ecf20Sopenharmony_ci		   period, duration, enabled);
36368c2ecf20Sopenharmony_ci	return skb;
36378c2ecf20Sopenharmony_ci}
36388c2ecf20Sopenharmony_ci
36398c2ecf20Sopenharmony_cistatic struct sk_buff *
36408c2ecf20Sopenharmony_ciath10k_wmi_tlv_op_gen_wow_enable(struct ath10k *ar)
36418c2ecf20Sopenharmony_ci{
36428c2ecf20Sopenharmony_ci	struct wmi_tlv_wow_enable_cmd *cmd;
36438c2ecf20Sopenharmony_ci	struct wmi_tlv *tlv;
36448c2ecf20Sopenharmony_ci	struct sk_buff *skb;
36458c2ecf20Sopenharmony_ci	size_t len;
36468c2ecf20Sopenharmony_ci
36478c2ecf20Sopenharmony_ci	len = sizeof(*tlv) + sizeof(*cmd);
36488c2ecf20Sopenharmony_ci	skb = ath10k_wmi_alloc_skb(ar, len);
36498c2ecf20Sopenharmony_ci	if (!skb)
36508c2ecf20Sopenharmony_ci		return ERR_PTR(-ENOMEM);
36518c2ecf20Sopenharmony_ci
36528c2ecf20Sopenharmony_ci	tlv = (struct wmi_tlv *)skb->data;
36538c2ecf20Sopenharmony_ci	tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_WOW_ENABLE_CMD);
36548c2ecf20Sopenharmony_ci	tlv->len = __cpu_to_le16(sizeof(*cmd));
36558c2ecf20Sopenharmony_ci	cmd = (void *)tlv->value;
36568c2ecf20Sopenharmony_ci
36578c2ecf20Sopenharmony_ci	cmd->enable = __cpu_to_le32(1);
36588c2ecf20Sopenharmony_ci	if (!ar->bus_param.link_can_suspend)
36598c2ecf20Sopenharmony_ci		cmd->pause_iface_config = __cpu_to_le32(WOW_IFACE_PAUSE_DISABLED);
36608c2ecf20Sopenharmony_ci
36618c2ecf20Sopenharmony_ci	ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv wow enable\n");
36628c2ecf20Sopenharmony_ci	return skb;
36638c2ecf20Sopenharmony_ci}
36648c2ecf20Sopenharmony_ci
36658c2ecf20Sopenharmony_cistatic struct sk_buff *
36668c2ecf20Sopenharmony_ciath10k_wmi_tlv_op_gen_wow_add_wakeup_event(struct ath10k *ar,
36678c2ecf20Sopenharmony_ci					   u32 vdev_id,
36688c2ecf20Sopenharmony_ci					   enum wmi_wow_wakeup_event event,
36698c2ecf20Sopenharmony_ci					   u32 enable)
36708c2ecf20Sopenharmony_ci{
36718c2ecf20Sopenharmony_ci	struct wmi_tlv_wow_add_del_event_cmd *cmd;
36728c2ecf20Sopenharmony_ci	struct wmi_tlv *tlv;
36738c2ecf20Sopenharmony_ci	struct sk_buff *skb;
36748c2ecf20Sopenharmony_ci	size_t len;
36758c2ecf20Sopenharmony_ci
36768c2ecf20Sopenharmony_ci	len = sizeof(*tlv) + sizeof(*cmd);
36778c2ecf20Sopenharmony_ci	skb = ath10k_wmi_alloc_skb(ar, len);
36788c2ecf20Sopenharmony_ci	if (!skb)
36798c2ecf20Sopenharmony_ci		return ERR_PTR(-ENOMEM);
36808c2ecf20Sopenharmony_ci
36818c2ecf20Sopenharmony_ci	tlv = (struct wmi_tlv *)skb->data;
36828c2ecf20Sopenharmony_ci	tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_WOW_ADD_DEL_EVT_CMD);
36838c2ecf20Sopenharmony_ci	tlv->len = __cpu_to_le16(sizeof(*cmd));
36848c2ecf20Sopenharmony_ci	cmd = (void *)tlv->value;
36858c2ecf20Sopenharmony_ci
36868c2ecf20Sopenharmony_ci	cmd->vdev_id = __cpu_to_le32(vdev_id);
36878c2ecf20Sopenharmony_ci	cmd->is_add = __cpu_to_le32(enable);
36888c2ecf20Sopenharmony_ci	cmd->event_bitmap = __cpu_to_le32(1 << event);
36898c2ecf20Sopenharmony_ci
36908c2ecf20Sopenharmony_ci	ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv wow add wakeup event %s enable %d vdev_id %d\n",
36918c2ecf20Sopenharmony_ci		   wow_wakeup_event(event), enable, vdev_id);
36928c2ecf20Sopenharmony_ci	return skb;
36938c2ecf20Sopenharmony_ci}
36948c2ecf20Sopenharmony_ci
36958c2ecf20Sopenharmony_cistatic struct sk_buff *
36968c2ecf20Sopenharmony_ciath10k_wmi_tlv_gen_wow_host_wakeup_ind(struct ath10k *ar)
36978c2ecf20Sopenharmony_ci{
36988c2ecf20Sopenharmony_ci	struct wmi_tlv_wow_host_wakeup_ind *cmd;
36998c2ecf20Sopenharmony_ci	struct wmi_tlv *tlv;
37008c2ecf20Sopenharmony_ci	struct sk_buff *skb;
37018c2ecf20Sopenharmony_ci	size_t len;
37028c2ecf20Sopenharmony_ci
37038c2ecf20Sopenharmony_ci	len = sizeof(*tlv) + sizeof(*cmd);
37048c2ecf20Sopenharmony_ci	skb = ath10k_wmi_alloc_skb(ar, len);
37058c2ecf20Sopenharmony_ci	if (!skb)
37068c2ecf20Sopenharmony_ci		return ERR_PTR(-ENOMEM);
37078c2ecf20Sopenharmony_ci
37088c2ecf20Sopenharmony_ci	tlv = (struct wmi_tlv *)skb->data;
37098c2ecf20Sopenharmony_ci	tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_WOW_HOSTWAKEUP_FROM_SLEEP_CMD);
37108c2ecf20Sopenharmony_ci	tlv->len = __cpu_to_le16(sizeof(*cmd));
37118c2ecf20Sopenharmony_ci	cmd = (void *)tlv->value;
37128c2ecf20Sopenharmony_ci
37138c2ecf20Sopenharmony_ci	ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv wow host wakeup ind\n");
37148c2ecf20Sopenharmony_ci	return skb;
37158c2ecf20Sopenharmony_ci}
37168c2ecf20Sopenharmony_ci
37178c2ecf20Sopenharmony_cistatic struct sk_buff *
37188c2ecf20Sopenharmony_ciath10k_wmi_tlv_op_gen_wow_add_pattern(struct ath10k *ar, u32 vdev_id,
37198c2ecf20Sopenharmony_ci				      u32 pattern_id, const u8 *pattern,
37208c2ecf20Sopenharmony_ci				      const u8 *bitmask, int pattern_len,
37218c2ecf20Sopenharmony_ci				      int pattern_offset)
37228c2ecf20Sopenharmony_ci{
37238c2ecf20Sopenharmony_ci	struct wmi_tlv_wow_add_pattern_cmd *cmd;
37248c2ecf20Sopenharmony_ci	struct wmi_tlv_wow_bitmap_pattern *bitmap;
37258c2ecf20Sopenharmony_ci	struct wmi_tlv *tlv;
37268c2ecf20Sopenharmony_ci	struct sk_buff *skb;
37278c2ecf20Sopenharmony_ci	void *ptr;
37288c2ecf20Sopenharmony_ci	size_t len;
37298c2ecf20Sopenharmony_ci
37308c2ecf20Sopenharmony_ci	len = sizeof(*tlv) + sizeof(*cmd) +
37318c2ecf20Sopenharmony_ci	      sizeof(*tlv) +			/* array struct */
37328c2ecf20Sopenharmony_ci	      sizeof(*tlv) + sizeof(*bitmap) +  /* bitmap */
37338c2ecf20Sopenharmony_ci	      sizeof(*tlv) +			/* empty ipv4 sync */
37348c2ecf20Sopenharmony_ci	      sizeof(*tlv) +			/* empty ipv6 sync */
37358c2ecf20Sopenharmony_ci	      sizeof(*tlv) +			/* empty magic */
37368c2ecf20Sopenharmony_ci	      sizeof(*tlv) +			/* empty info timeout */
37378c2ecf20Sopenharmony_ci	      sizeof(*tlv) + sizeof(u32);	/* ratelimit interval */
37388c2ecf20Sopenharmony_ci
37398c2ecf20Sopenharmony_ci	skb = ath10k_wmi_alloc_skb(ar, len);
37408c2ecf20Sopenharmony_ci	if (!skb)
37418c2ecf20Sopenharmony_ci		return ERR_PTR(-ENOMEM);
37428c2ecf20Sopenharmony_ci
37438c2ecf20Sopenharmony_ci	/* cmd */
37448c2ecf20Sopenharmony_ci	ptr = (void *)skb->data;
37458c2ecf20Sopenharmony_ci	tlv = ptr;
37468c2ecf20Sopenharmony_ci	tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_WOW_ADD_PATTERN_CMD);
37478c2ecf20Sopenharmony_ci	tlv->len = __cpu_to_le16(sizeof(*cmd));
37488c2ecf20Sopenharmony_ci	cmd = (void *)tlv->value;
37498c2ecf20Sopenharmony_ci
37508c2ecf20Sopenharmony_ci	cmd->vdev_id = __cpu_to_le32(vdev_id);
37518c2ecf20Sopenharmony_ci	cmd->pattern_id = __cpu_to_le32(pattern_id);
37528c2ecf20Sopenharmony_ci	cmd->pattern_type = __cpu_to_le32(WOW_BITMAP_PATTERN);
37538c2ecf20Sopenharmony_ci
37548c2ecf20Sopenharmony_ci	ptr += sizeof(*tlv);
37558c2ecf20Sopenharmony_ci	ptr += sizeof(*cmd);
37568c2ecf20Sopenharmony_ci
37578c2ecf20Sopenharmony_ci	/* bitmap */
37588c2ecf20Sopenharmony_ci	tlv = ptr;
37598c2ecf20Sopenharmony_ci	tlv->tag = __cpu_to_le16(WMI_TLV_TAG_ARRAY_STRUCT);
37608c2ecf20Sopenharmony_ci	tlv->len = __cpu_to_le16(sizeof(*tlv) + sizeof(*bitmap));
37618c2ecf20Sopenharmony_ci
37628c2ecf20Sopenharmony_ci	ptr += sizeof(*tlv);
37638c2ecf20Sopenharmony_ci
37648c2ecf20Sopenharmony_ci	tlv = ptr;
37658c2ecf20Sopenharmony_ci	tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_WOW_BITMAP_PATTERN_T);
37668c2ecf20Sopenharmony_ci	tlv->len = __cpu_to_le16(sizeof(*bitmap));
37678c2ecf20Sopenharmony_ci	bitmap = (void *)tlv->value;
37688c2ecf20Sopenharmony_ci
37698c2ecf20Sopenharmony_ci	memcpy(bitmap->patternbuf, pattern, pattern_len);
37708c2ecf20Sopenharmony_ci	memcpy(bitmap->bitmaskbuf, bitmask, pattern_len);
37718c2ecf20Sopenharmony_ci	bitmap->pattern_offset = __cpu_to_le32(pattern_offset);
37728c2ecf20Sopenharmony_ci	bitmap->pattern_len = __cpu_to_le32(pattern_len);
37738c2ecf20Sopenharmony_ci	bitmap->bitmask_len = __cpu_to_le32(pattern_len);
37748c2ecf20Sopenharmony_ci	bitmap->pattern_id = __cpu_to_le32(pattern_id);
37758c2ecf20Sopenharmony_ci
37768c2ecf20Sopenharmony_ci	ptr += sizeof(*tlv);
37778c2ecf20Sopenharmony_ci	ptr += sizeof(*bitmap);
37788c2ecf20Sopenharmony_ci
37798c2ecf20Sopenharmony_ci	/* ipv4 sync */
37808c2ecf20Sopenharmony_ci	tlv = ptr;
37818c2ecf20Sopenharmony_ci	tlv->tag = __cpu_to_le16(WMI_TLV_TAG_ARRAY_STRUCT);
37828c2ecf20Sopenharmony_ci	tlv->len = __cpu_to_le16(0);
37838c2ecf20Sopenharmony_ci
37848c2ecf20Sopenharmony_ci	ptr += sizeof(*tlv);
37858c2ecf20Sopenharmony_ci
37868c2ecf20Sopenharmony_ci	/* ipv6 sync */
37878c2ecf20Sopenharmony_ci	tlv = ptr;
37888c2ecf20Sopenharmony_ci	tlv->tag = __cpu_to_le16(WMI_TLV_TAG_ARRAY_STRUCT);
37898c2ecf20Sopenharmony_ci	tlv->len = __cpu_to_le16(0);
37908c2ecf20Sopenharmony_ci
37918c2ecf20Sopenharmony_ci	ptr += sizeof(*tlv);
37928c2ecf20Sopenharmony_ci
37938c2ecf20Sopenharmony_ci	/* magic */
37948c2ecf20Sopenharmony_ci	tlv = ptr;
37958c2ecf20Sopenharmony_ci	tlv->tag = __cpu_to_le16(WMI_TLV_TAG_ARRAY_STRUCT);
37968c2ecf20Sopenharmony_ci	tlv->len = __cpu_to_le16(0);
37978c2ecf20Sopenharmony_ci
37988c2ecf20Sopenharmony_ci	ptr += sizeof(*tlv);
37998c2ecf20Sopenharmony_ci
38008c2ecf20Sopenharmony_ci	/* pattern info timeout */
38018c2ecf20Sopenharmony_ci	tlv = ptr;
38028c2ecf20Sopenharmony_ci	tlv->tag = __cpu_to_le16(WMI_TLV_TAG_ARRAY_UINT32);
38038c2ecf20Sopenharmony_ci	tlv->len = __cpu_to_le16(0);
38048c2ecf20Sopenharmony_ci
38058c2ecf20Sopenharmony_ci	ptr += sizeof(*tlv);
38068c2ecf20Sopenharmony_ci
38078c2ecf20Sopenharmony_ci	/* ratelimit interval */
38088c2ecf20Sopenharmony_ci	tlv = ptr;
38098c2ecf20Sopenharmony_ci	tlv->tag = __cpu_to_le16(WMI_TLV_TAG_ARRAY_UINT32);
38108c2ecf20Sopenharmony_ci	tlv->len = __cpu_to_le16(sizeof(u32));
38118c2ecf20Sopenharmony_ci
38128c2ecf20Sopenharmony_ci	ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv wow add pattern vdev_id %d pattern_id %d, pattern_offset %d\n",
38138c2ecf20Sopenharmony_ci		   vdev_id, pattern_id, pattern_offset);
38148c2ecf20Sopenharmony_ci	return skb;
38158c2ecf20Sopenharmony_ci}
38168c2ecf20Sopenharmony_ci
38178c2ecf20Sopenharmony_cistatic struct sk_buff *
38188c2ecf20Sopenharmony_ciath10k_wmi_tlv_op_gen_wow_del_pattern(struct ath10k *ar, u32 vdev_id,
38198c2ecf20Sopenharmony_ci				      u32 pattern_id)
38208c2ecf20Sopenharmony_ci{
38218c2ecf20Sopenharmony_ci	struct wmi_tlv_wow_del_pattern_cmd *cmd;
38228c2ecf20Sopenharmony_ci	struct wmi_tlv *tlv;
38238c2ecf20Sopenharmony_ci	struct sk_buff *skb;
38248c2ecf20Sopenharmony_ci	size_t len;
38258c2ecf20Sopenharmony_ci
38268c2ecf20Sopenharmony_ci	len = sizeof(*tlv) + sizeof(*cmd);
38278c2ecf20Sopenharmony_ci	skb = ath10k_wmi_alloc_skb(ar, len);
38288c2ecf20Sopenharmony_ci	if (!skb)
38298c2ecf20Sopenharmony_ci		return ERR_PTR(-ENOMEM);
38308c2ecf20Sopenharmony_ci
38318c2ecf20Sopenharmony_ci	tlv = (struct wmi_tlv *)skb->data;
38328c2ecf20Sopenharmony_ci	tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_WOW_DEL_PATTERN_CMD);
38338c2ecf20Sopenharmony_ci	tlv->len = __cpu_to_le16(sizeof(*cmd));
38348c2ecf20Sopenharmony_ci	cmd = (void *)tlv->value;
38358c2ecf20Sopenharmony_ci
38368c2ecf20Sopenharmony_ci	cmd->vdev_id = __cpu_to_le32(vdev_id);
38378c2ecf20Sopenharmony_ci	cmd->pattern_id = __cpu_to_le32(pattern_id);
38388c2ecf20Sopenharmony_ci	cmd->pattern_type = __cpu_to_le32(WOW_BITMAP_PATTERN);
38398c2ecf20Sopenharmony_ci
38408c2ecf20Sopenharmony_ci	ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv wow del pattern vdev_id %d pattern_id %d\n",
38418c2ecf20Sopenharmony_ci		   vdev_id, pattern_id);
38428c2ecf20Sopenharmony_ci	return skb;
38438c2ecf20Sopenharmony_ci}
38448c2ecf20Sopenharmony_ci
38458c2ecf20Sopenharmony_ci/* Request FW to start PNO operation */
38468c2ecf20Sopenharmony_cistatic struct sk_buff *
38478c2ecf20Sopenharmony_ciath10k_wmi_tlv_op_gen_config_pno_start(struct ath10k *ar,
38488c2ecf20Sopenharmony_ci				       u32 vdev_id,
38498c2ecf20Sopenharmony_ci				       struct wmi_pno_scan_req *pno)
38508c2ecf20Sopenharmony_ci{
38518c2ecf20Sopenharmony_ci	struct nlo_configured_parameters *nlo_list;
38528c2ecf20Sopenharmony_ci	struct wmi_tlv_wow_nlo_config_cmd *cmd;
38538c2ecf20Sopenharmony_ci	struct wmi_tlv *tlv;
38548c2ecf20Sopenharmony_ci	struct sk_buff *skb;
38558c2ecf20Sopenharmony_ci	__le32 *channel_list;
38568c2ecf20Sopenharmony_ci	u16 tlv_len;
38578c2ecf20Sopenharmony_ci	size_t len;
38588c2ecf20Sopenharmony_ci	void *ptr;
38598c2ecf20Sopenharmony_ci	u32 i;
38608c2ecf20Sopenharmony_ci
38618c2ecf20Sopenharmony_ci	len = sizeof(*tlv) + sizeof(*cmd) +
38628c2ecf20Sopenharmony_ci	      sizeof(*tlv) +
38638c2ecf20Sopenharmony_ci	      /* TLV place holder for array of structures
38648c2ecf20Sopenharmony_ci	       * nlo_configured_parameters(nlo_list)
38658c2ecf20Sopenharmony_ci	       */
38668c2ecf20Sopenharmony_ci	      sizeof(*tlv);
38678c2ecf20Sopenharmony_ci	      /* TLV place holder for array of uint32 channel_list */
38688c2ecf20Sopenharmony_ci
38698c2ecf20Sopenharmony_ci	len += sizeof(u32) * min_t(u8, pno->a_networks[0].channel_count,
38708c2ecf20Sopenharmony_ci				   WMI_NLO_MAX_CHAN);
38718c2ecf20Sopenharmony_ci	len += sizeof(struct nlo_configured_parameters) *
38728c2ecf20Sopenharmony_ci				min_t(u8, pno->uc_networks_count, WMI_NLO_MAX_SSIDS);
38738c2ecf20Sopenharmony_ci
38748c2ecf20Sopenharmony_ci	skb = ath10k_wmi_alloc_skb(ar, len);
38758c2ecf20Sopenharmony_ci	if (!skb)
38768c2ecf20Sopenharmony_ci		return ERR_PTR(-ENOMEM);
38778c2ecf20Sopenharmony_ci
38788c2ecf20Sopenharmony_ci	ptr = (void *)skb->data;
38798c2ecf20Sopenharmony_ci	tlv = ptr;
38808c2ecf20Sopenharmony_ci	tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_NLO_CONFIG_CMD);
38818c2ecf20Sopenharmony_ci	tlv->len = __cpu_to_le16(sizeof(*cmd));
38828c2ecf20Sopenharmony_ci	cmd = (void *)tlv->value;
38838c2ecf20Sopenharmony_ci
38848c2ecf20Sopenharmony_ci	/* wmi_tlv_wow_nlo_config_cmd parameters*/
38858c2ecf20Sopenharmony_ci	cmd->vdev_id = __cpu_to_le32(pno->vdev_id);
38868c2ecf20Sopenharmony_ci	cmd->flags = __cpu_to_le32(WMI_NLO_CONFIG_START | WMI_NLO_CONFIG_SSID_HIDE_EN);
38878c2ecf20Sopenharmony_ci
38888c2ecf20Sopenharmony_ci	/* current FW does not support min-max range for dwell time */
38898c2ecf20Sopenharmony_ci	cmd->active_dwell_time = __cpu_to_le32(pno->active_max_time);
38908c2ecf20Sopenharmony_ci	cmd->passive_dwell_time = __cpu_to_le32(pno->passive_max_time);
38918c2ecf20Sopenharmony_ci
38928c2ecf20Sopenharmony_ci	if (pno->do_passive_scan)
38938c2ecf20Sopenharmony_ci		cmd->flags |= __cpu_to_le32(WMI_NLO_CONFIG_SCAN_PASSIVE);
38948c2ecf20Sopenharmony_ci
38958c2ecf20Sopenharmony_ci	/* copy scan interval */
38968c2ecf20Sopenharmony_ci	cmd->fast_scan_period = __cpu_to_le32(pno->fast_scan_period);
38978c2ecf20Sopenharmony_ci	cmd->slow_scan_period = __cpu_to_le32(pno->slow_scan_period);
38988c2ecf20Sopenharmony_ci	cmd->fast_scan_max_cycles = __cpu_to_le32(pno->fast_scan_max_cycles);
38998c2ecf20Sopenharmony_ci	cmd->delay_start_time = __cpu_to_le32(pno->delay_start_time);
39008c2ecf20Sopenharmony_ci
39018c2ecf20Sopenharmony_ci	if (pno->enable_pno_scan_randomization) {
39028c2ecf20Sopenharmony_ci		cmd->flags |= __cpu_to_le32(WMI_NLO_CONFIG_SPOOFED_MAC_IN_PROBE_REQ |
39038c2ecf20Sopenharmony_ci				WMI_NLO_CONFIG_RANDOM_SEQ_NO_IN_PROBE_REQ);
39048c2ecf20Sopenharmony_ci		ether_addr_copy(cmd->mac_addr.addr, pno->mac_addr);
39058c2ecf20Sopenharmony_ci		ether_addr_copy(cmd->mac_mask.addr, pno->mac_addr_mask);
39068c2ecf20Sopenharmony_ci	}
39078c2ecf20Sopenharmony_ci
39088c2ecf20Sopenharmony_ci	ptr += sizeof(*tlv);
39098c2ecf20Sopenharmony_ci	ptr += sizeof(*cmd);
39108c2ecf20Sopenharmony_ci
39118c2ecf20Sopenharmony_ci	/* nlo_configured_parameters(nlo_list) */
39128c2ecf20Sopenharmony_ci	cmd->no_of_ssids = __cpu_to_le32(min_t(u8, pno->uc_networks_count,
39138c2ecf20Sopenharmony_ci					       WMI_NLO_MAX_SSIDS));
39148c2ecf20Sopenharmony_ci	tlv_len = __le32_to_cpu(cmd->no_of_ssids) *
39158c2ecf20Sopenharmony_ci		sizeof(struct nlo_configured_parameters);
39168c2ecf20Sopenharmony_ci
39178c2ecf20Sopenharmony_ci	tlv = ptr;
39188c2ecf20Sopenharmony_ci	tlv->tag = __cpu_to_le16(WMI_TLV_TAG_ARRAY_STRUCT);
39198c2ecf20Sopenharmony_ci	tlv->len = __cpu_to_le16(tlv_len);
39208c2ecf20Sopenharmony_ci
39218c2ecf20Sopenharmony_ci	ptr += sizeof(*tlv);
39228c2ecf20Sopenharmony_ci	nlo_list = ptr;
39238c2ecf20Sopenharmony_ci	for (i = 0; i < __le32_to_cpu(cmd->no_of_ssids); i++) {
39248c2ecf20Sopenharmony_ci		tlv = (struct wmi_tlv *)(&nlo_list[i].tlv_header);
39258c2ecf20Sopenharmony_ci		tlv->tag = __cpu_to_le16(WMI_TLV_TAG_ARRAY_BYTE);
39268c2ecf20Sopenharmony_ci		tlv->len = __cpu_to_le16(sizeof(struct nlo_configured_parameters) -
39278c2ecf20Sopenharmony_ci					 sizeof(*tlv));
39288c2ecf20Sopenharmony_ci
39298c2ecf20Sopenharmony_ci		/* copy ssid and it's length */
39308c2ecf20Sopenharmony_ci		nlo_list[i].ssid.valid = __cpu_to_le32(true);
39318c2ecf20Sopenharmony_ci		nlo_list[i].ssid.ssid.ssid_len = pno->a_networks[i].ssid.ssid_len;
39328c2ecf20Sopenharmony_ci		memcpy(nlo_list[i].ssid.ssid.ssid,
39338c2ecf20Sopenharmony_ci		       pno->a_networks[i].ssid.ssid,
39348c2ecf20Sopenharmony_ci		       __le32_to_cpu(nlo_list[i].ssid.ssid.ssid_len));
39358c2ecf20Sopenharmony_ci
39368c2ecf20Sopenharmony_ci		/* copy rssi threshold */
39378c2ecf20Sopenharmony_ci		if (pno->a_networks[i].rssi_threshold &&
39388c2ecf20Sopenharmony_ci		    pno->a_networks[i].rssi_threshold > -300) {
39398c2ecf20Sopenharmony_ci			nlo_list[i].rssi_cond.valid = __cpu_to_le32(true);
39408c2ecf20Sopenharmony_ci			nlo_list[i].rssi_cond.rssi =
39418c2ecf20Sopenharmony_ci				__cpu_to_le32(pno->a_networks[i].rssi_threshold);
39428c2ecf20Sopenharmony_ci		}
39438c2ecf20Sopenharmony_ci
39448c2ecf20Sopenharmony_ci		nlo_list[i].bcast_nw_type.valid = __cpu_to_le32(true);
39458c2ecf20Sopenharmony_ci		nlo_list[i].bcast_nw_type.bcast_nw_type =
39468c2ecf20Sopenharmony_ci			__cpu_to_le32(pno->a_networks[i].bcast_nw_type);
39478c2ecf20Sopenharmony_ci	}
39488c2ecf20Sopenharmony_ci
39498c2ecf20Sopenharmony_ci	ptr += __le32_to_cpu(cmd->no_of_ssids) * sizeof(struct nlo_configured_parameters);
39508c2ecf20Sopenharmony_ci
39518c2ecf20Sopenharmony_ci	/* copy channel info */
39528c2ecf20Sopenharmony_ci	cmd->num_of_channels = __cpu_to_le32(min_t(u8,
39538c2ecf20Sopenharmony_ci						   pno->a_networks[0].channel_count,
39548c2ecf20Sopenharmony_ci						   WMI_NLO_MAX_CHAN));
39558c2ecf20Sopenharmony_ci
39568c2ecf20Sopenharmony_ci	tlv = ptr;
39578c2ecf20Sopenharmony_ci	tlv->tag = __cpu_to_le16(WMI_TLV_TAG_ARRAY_UINT32);
39588c2ecf20Sopenharmony_ci	tlv->len = __cpu_to_le16(__le32_to_cpu(cmd->num_of_channels) *
39598c2ecf20Sopenharmony_ci				 sizeof(u_int32_t));
39608c2ecf20Sopenharmony_ci	ptr += sizeof(*tlv);
39618c2ecf20Sopenharmony_ci
39628c2ecf20Sopenharmony_ci	channel_list = (__le32 *)ptr;
39638c2ecf20Sopenharmony_ci	for (i = 0; i < __le32_to_cpu(cmd->num_of_channels); i++)
39648c2ecf20Sopenharmony_ci		channel_list[i] = __cpu_to_le32(pno->a_networks[0].channels[i]);
39658c2ecf20Sopenharmony_ci
39668c2ecf20Sopenharmony_ci	ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv start pno config vdev_id %d\n",
39678c2ecf20Sopenharmony_ci		   vdev_id);
39688c2ecf20Sopenharmony_ci
39698c2ecf20Sopenharmony_ci	return skb;
39708c2ecf20Sopenharmony_ci}
39718c2ecf20Sopenharmony_ci
39728c2ecf20Sopenharmony_ci/* Request FW to stop ongoing PNO operation */
39738c2ecf20Sopenharmony_cistatic struct sk_buff *ath10k_wmi_tlv_op_gen_config_pno_stop(struct ath10k *ar,
39748c2ecf20Sopenharmony_ci							     u32 vdev_id)
39758c2ecf20Sopenharmony_ci{
39768c2ecf20Sopenharmony_ci	struct wmi_tlv_wow_nlo_config_cmd *cmd;
39778c2ecf20Sopenharmony_ci	struct wmi_tlv *tlv;
39788c2ecf20Sopenharmony_ci	struct sk_buff *skb;
39798c2ecf20Sopenharmony_ci	void *ptr;
39808c2ecf20Sopenharmony_ci	size_t len;
39818c2ecf20Sopenharmony_ci
39828c2ecf20Sopenharmony_ci	len = sizeof(*tlv) + sizeof(*cmd) +
39838c2ecf20Sopenharmony_ci	      sizeof(*tlv) +
39848c2ecf20Sopenharmony_ci	      /* TLV place holder for array of structures
39858c2ecf20Sopenharmony_ci	       * nlo_configured_parameters(nlo_list)
39868c2ecf20Sopenharmony_ci	       */
39878c2ecf20Sopenharmony_ci	      sizeof(*tlv);
39888c2ecf20Sopenharmony_ci	      /* TLV place holder for array of uint32 channel_list */
39898c2ecf20Sopenharmony_ci	skb = ath10k_wmi_alloc_skb(ar, len);
39908c2ecf20Sopenharmony_ci	if (!skb)
39918c2ecf20Sopenharmony_ci		return ERR_PTR(-ENOMEM);
39928c2ecf20Sopenharmony_ci
39938c2ecf20Sopenharmony_ci	ptr = (void *)skb->data;
39948c2ecf20Sopenharmony_ci	tlv = ptr;
39958c2ecf20Sopenharmony_ci	tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_NLO_CONFIG_CMD);
39968c2ecf20Sopenharmony_ci	tlv->len = __cpu_to_le16(sizeof(*cmd));
39978c2ecf20Sopenharmony_ci	cmd = (void *)tlv->value;
39988c2ecf20Sopenharmony_ci
39998c2ecf20Sopenharmony_ci	cmd->vdev_id = __cpu_to_le32(vdev_id);
40008c2ecf20Sopenharmony_ci	cmd->flags = __cpu_to_le32(WMI_NLO_CONFIG_STOP);
40018c2ecf20Sopenharmony_ci
40028c2ecf20Sopenharmony_ci	ptr += sizeof(*tlv);
40038c2ecf20Sopenharmony_ci	ptr += sizeof(*cmd);
40048c2ecf20Sopenharmony_ci
40058c2ecf20Sopenharmony_ci	/* nlo_configured_parameters(nlo_list) */
40068c2ecf20Sopenharmony_ci	tlv = ptr;
40078c2ecf20Sopenharmony_ci	tlv->tag = __cpu_to_le16(WMI_TLV_TAG_ARRAY_STRUCT);
40088c2ecf20Sopenharmony_ci	tlv->len = __cpu_to_le16(0);
40098c2ecf20Sopenharmony_ci
40108c2ecf20Sopenharmony_ci	ptr += sizeof(*tlv);
40118c2ecf20Sopenharmony_ci
40128c2ecf20Sopenharmony_ci	/* channel list */
40138c2ecf20Sopenharmony_ci	tlv = ptr;
40148c2ecf20Sopenharmony_ci	tlv->tag = __cpu_to_le16(WMI_TLV_TAG_ARRAY_UINT32);
40158c2ecf20Sopenharmony_ci	tlv->len = __cpu_to_le16(0);
40168c2ecf20Sopenharmony_ci
40178c2ecf20Sopenharmony_ci	ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv stop pno config vdev_id %d\n", vdev_id);
40188c2ecf20Sopenharmony_ci	return skb;
40198c2ecf20Sopenharmony_ci}
40208c2ecf20Sopenharmony_ci
40218c2ecf20Sopenharmony_cistatic struct sk_buff *
40228c2ecf20Sopenharmony_ciath10k_wmi_tlv_op_gen_config_pno(struct ath10k *ar, u32 vdev_id,
40238c2ecf20Sopenharmony_ci				 struct wmi_pno_scan_req *pno_scan)
40248c2ecf20Sopenharmony_ci{
40258c2ecf20Sopenharmony_ci	if (pno_scan->enable)
40268c2ecf20Sopenharmony_ci		return ath10k_wmi_tlv_op_gen_config_pno_start(ar, vdev_id, pno_scan);
40278c2ecf20Sopenharmony_ci	else
40288c2ecf20Sopenharmony_ci		return ath10k_wmi_tlv_op_gen_config_pno_stop(ar, vdev_id);
40298c2ecf20Sopenharmony_ci}
40308c2ecf20Sopenharmony_ci
40318c2ecf20Sopenharmony_cistatic struct sk_buff *
40328c2ecf20Sopenharmony_ciath10k_wmi_tlv_op_gen_adaptive_qcs(struct ath10k *ar, bool enable)
40338c2ecf20Sopenharmony_ci{
40348c2ecf20Sopenharmony_ci	struct wmi_tlv_adaptive_qcs *cmd;
40358c2ecf20Sopenharmony_ci	struct wmi_tlv *tlv;
40368c2ecf20Sopenharmony_ci	struct sk_buff *skb;
40378c2ecf20Sopenharmony_ci	void *ptr;
40388c2ecf20Sopenharmony_ci	size_t len;
40398c2ecf20Sopenharmony_ci
40408c2ecf20Sopenharmony_ci	len = sizeof(*tlv) + sizeof(*cmd);
40418c2ecf20Sopenharmony_ci	skb = ath10k_wmi_alloc_skb(ar, len);
40428c2ecf20Sopenharmony_ci	if (!skb)
40438c2ecf20Sopenharmony_ci		return ERR_PTR(-ENOMEM);
40448c2ecf20Sopenharmony_ci
40458c2ecf20Sopenharmony_ci	ptr = (void *)skb->data;
40468c2ecf20Sopenharmony_ci	tlv = ptr;
40478c2ecf20Sopenharmony_ci	tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_RESMGR_ADAPTIVE_OCS_CMD);
40488c2ecf20Sopenharmony_ci	tlv->len = __cpu_to_le16(sizeof(*cmd));
40498c2ecf20Sopenharmony_ci	cmd = (void *)tlv->value;
40508c2ecf20Sopenharmony_ci	cmd->enable = __cpu_to_le32(enable ? 1 : 0);
40518c2ecf20Sopenharmony_ci
40528c2ecf20Sopenharmony_ci	ptr += sizeof(*tlv);
40538c2ecf20Sopenharmony_ci	ptr += sizeof(*cmd);
40548c2ecf20Sopenharmony_ci
40558c2ecf20Sopenharmony_ci	ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv adaptive qcs %d\n", enable);
40568c2ecf20Sopenharmony_ci	return skb;
40578c2ecf20Sopenharmony_ci}
40588c2ecf20Sopenharmony_ci
40598c2ecf20Sopenharmony_cistatic struct sk_buff *
40608c2ecf20Sopenharmony_ciath10k_wmi_tlv_op_gen_echo(struct ath10k *ar, u32 value)
40618c2ecf20Sopenharmony_ci{
40628c2ecf20Sopenharmony_ci	struct wmi_echo_cmd *cmd;
40638c2ecf20Sopenharmony_ci	struct wmi_tlv *tlv;
40648c2ecf20Sopenharmony_ci	struct sk_buff *skb;
40658c2ecf20Sopenharmony_ci	void *ptr;
40668c2ecf20Sopenharmony_ci	size_t len;
40678c2ecf20Sopenharmony_ci
40688c2ecf20Sopenharmony_ci	len = sizeof(*tlv) + sizeof(*cmd);
40698c2ecf20Sopenharmony_ci	skb = ath10k_wmi_alloc_skb(ar, len);
40708c2ecf20Sopenharmony_ci	if (!skb)
40718c2ecf20Sopenharmony_ci		return ERR_PTR(-ENOMEM);
40728c2ecf20Sopenharmony_ci
40738c2ecf20Sopenharmony_ci	ptr = (void *)skb->data;
40748c2ecf20Sopenharmony_ci	tlv = ptr;
40758c2ecf20Sopenharmony_ci	tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_ECHO_CMD);
40768c2ecf20Sopenharmony_ci	tlv->len = __cpu_to_le16(sizeof(*cmd));
40778c2ecf20Sopenharmony_ci	cmd = (void *)tlv->value;
40788c2ecf20Sopenharmony_ci	cmd->value = cpu_to_le32(value);
40798c2ecf20Sopenharmony_ci
40808c2ecf20Sopenharmony_ci	ptr += sizeof(*tlv);
40818c2ecf20Sopenharmony_ci	ptr += sizeof(*cmd);
40828c2ecf20Sopenharmony_ci
40838c2ecf20Sopenharmony_ci	ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv echo value 0x%08x\n", value);
40848c2ecf20Sopenharmony_ci	return skb;
40858c2ecf20Sopenharmony_ci}
40868c2ecf20Sopenharmony_ci
40878c2ecf20Sopenharmony_cistatic struct sk_buff *
40888c2ecf20Sopenharmony_ciath10k_wmi_tlv_op_gen_vdev_spectral_conf(struct ath10k *ar,
40898c2ecf20Sopenharmony_ci					 const struct wmi_vdev_spectral_conf_arg *arg)
40908c2ecf20Sopenharmony_ci{
40918c2ecf20Sopenharmony_ci	struct wmi_vdev_spectral_conf_cmd *cmd;
40928c2ecf20Sopenharmony_ci	struct sk_buff *skb;
40938c2ecf20Sopenharmony_ci	struct wmi_tlv *tlv;
40948c2ecf20Sopenharmony_ci	void *ptr;
40958c2ecf20Sopenharmony_ci	size_t len;
40968c2ecf20Sopenharmony_ci
40978c2ecf20Sopenharmony_ci	len = sizeof(*tlv) + sizeof(*cmd);
40988c2ecf20Sopenharmony_ci	skb = ath10k_wmi_alloc_skb(ar, len);
40998c2ecf20Sopenharmony_ci	if (!skb)
41008c2ecf20Sopenharmony_ci		return ERR_PTR(-ENOMEM);
41018c2ecf20Sopenharmony_ci
41028c2ecf20Sopenharmony_ci	ptr = (void *)skb->data;
41038c2ecf20Sopenharmony_ci	tlv = ptr;
41048c2ecf20Sopenharmony_ci	tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_VDEV_SPECTRAL_CONFIGURE_CMD);
41058c2ecf20Sopenharmony_ci	tlv->len = __cpu_to_le16(sizeof(*cmd));
41068c2ecf20Sopenharmony_ci	cmd = (void *)tlv->value;
41078c2ecf20Sopenharmony_ci	cmd->vdev_id = __cpu_to_le32(arg->vdev_id);
41088c2ecf20Sopenharmony_ci	cmd->scan_count = __cpu_to_le32(arg->scan_count);
41098c2ecf20Sopenharmony_ci	cmd->scan_period = __cpu_to_le32(arg->scan_period);
41108c2ecf20Sopenharmony_ci	cmd->scan_priority = __cpu_to_le32(arg->scan_priority);
41118c2ecf20Sopenharmony_ci	cmd->scan_fft_size = __cpu_to_le32(arg->scan_fft_size);
41128c2ecf20Sopenharmony_ci	cmd->scan_gc_ena = __cpu_to_le32(arg->scan_gc_ena);
41138c2ecf20Sopenharmony_ci	cmd->scan_restart_ena = __cpu_to_le32(arg->scan_restart_ena);
41148c2ecf20Sopenharmony_ci	cmd->scan_noise_floor_ref = __cpu_to_le32(arg->scan_noise_floor_ref);
41158c2ecf20Sopenharmony_ci	cmd->scan_init_delay = __cpu_to_le32(arg->scan_init_delay);
41168c2ecf20Sopenharmony_ci	cmd->scan_nb_tone_thr = __cpu_to_le32(arg->scan_nb_tone_thr);
41178c2ecf20Sopenharmony_ci	cmd->scan_str_bin_thr = __cpu_to_le32(arg->scan_str_bin_thr);
41188c2ecf20Sopenharmony_ci	cmd->scan_wb_rpt_mode = __cpu_to_le32(arg->scan_wb_rpt_mode);
41198c2ecf20Sopenharmony_ci	cmd->scan_rssi_rpt_mode = __cpu_to_le32(arg->scan_rssi_rpt_mode);
41208c2ecf20Sopenharmony_ci	cmd->scan_rssi_thr = __cpu_to_le32(arg->scan_rssi_thr);
41218c2ecf20Sopenharmony_ci	cmd->scan_pwr_format = __cpu_to_le32(arg->scan_pwr_format);
41228c2ecf20Sopenharmony_ci	cmd->scan_rpt_mode = __cpu_to_le32(arg->scan_rpt_mode);
41238c2ecf20Sopenharmony_ci	cmd->scan_bin_scale = __cpu_to_le32(arg->scan_bin_scale);
41248c2ecf20Sopenharmony_ci	cmd->scan_dbm_adj = __cpu_to_le32(arg->scan_dbm_adj);
41258c2ecf20Sopenharmony_ci	cmd->scan_chn_mask = __cpu_to_le32(arg->scan_chn_mask);
41268c2ecf20Sopenharmony_ci
41278c2ecf20Sopenharmony_ci	return skb;
41288c2ecf20Sopenharmony_ci}
41298c2ecf20Sopenharmony_ci
41308c2ecf20Sopenharmony_cistatic struct sk_buff *
41318c2ecf20Sopenharmony_ciath10k_wmi_tlv_op_gen_vdev_spectral_enable(struct ath10k *ar, u32 vdev_id,
41328c2ecf20Sopenharmony_ci					   u32 trigger, u32 enable)
41338c2ecf20Sopenharmony_ci{
41348c2ecf20Sopenharmony_ci	struct wmi_vdev_spectral_enable_cmd *cmd;
41358c2ecf20Sopenharmony_ci	struct sk_buff *skb;
41368c2ecf20Sopenharmony_ci	struct wmi_tlv *tlv;
41378c2ecf20Sopenharmony_ci	void *ptr;
41388c2ecf20Sopenharmony_ci	size_t len;
41398c2ecf20Sopenharmony_ci
41408c2ecf20Sopenharmony_ci	len = sizeof(*tlv) + sizeof(*cmd);
41418c2ecf20Sopenharmony_ci	skb = ath10k_wmi_alloc_skb(ar, len);
41428c2ecf20Sopenharmony_ci	if (!skb)
41438c2ecf20Sopenharmony_ci		return ERR_PTR(-ENOMEM);
41448c2ecf20Sopenharmony_ci
41458c2ecf20Sopenharmony_ci	ptr = (void *)skb->data;
41468c2ecf20Sopenharmony_ci	tlv = ptr;
41478c2ecf20Sopenharmony_ci	tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_VDEV_SPECTRAL_ENABLE_CMD);
41488c2ecf20Sopenharmony_ci	tlv->len = __cpu_to_le16(sizeof(*cmd));
41498c2ecf20Sopenharmony_ci	cmd = (void *)tlv->value;
41508c2ecf20Sopenharmony_ci	cmd->vdev_id = __cpu_to_le32(vdev_id);
41518c2ecf20Sopenharmony_ci	cmd->trigger_cmd = __cpu_to_le32(trigger);
41528c2ecf20Sopenharmony_ci	cmd->enable_cmd = __cpu_to_le32(enable);
41538c2ecf20Sopenharmony_ci
41548c2ecf20Sopenharmony_ci	return skb;
41558c2ecf20Sopenharmony_ci}
41568c2ecf20Sopenharmony_ci
41578c2ecf20Sopenharmony_ci/****************/
41588c2ecf20Sopenharmony_ci/* TLV mappings */
41598c2ecf20Sopenharmony_ci/****************/
41608c2ecf20Sopenharmony_ci
41618c2ecf20Sopenharmony_cistatic struct wmi_cmd_map wmi_tlv_cmd_map = {
41628c2ecf20Sopenharmony_ci	.init_cmdid = WMI_TLV_INIT_CMDID,
41638c2ecf20Sopenharmony_ci	.start_scan_cmdid = WMI_TLV_START_SCAN_CMDID,
41648c2ecf20Sopenharmony_ci	.stop_scan_cmdid = WMI_TLV_STOP_SCAN_CMDID,
41658c2ecf20Sopenharmony_ci	.scan_chan_list_cmdid = WMI_TLV_SCAN_CHAN_LIST_CMDID,
41668c2ecf20Sopenharmony_ci	.scan_sch_prio_tbl_cmdid = WMI_TLV_SCAN_SCH_PRIO_TBL_CMDID,
41678c2ecf20Sopenharmony_ci	.scan_prob_req_oui_cmdid = WMI_TLV_SCAN_PROB_REQ_OUI_CMDID,
41688c2ecf20Sopenharmony_ci	.pdev_set_regdomain_cmdid = WMI_TLV_PDEV_SET_REGDOMAIN_CMDID,
41698c2ecf20Sopenharmony_ci	.pdev_set_channel_cmdid = WMI_TLV_PDEV_SET_CHANNEL_CMDID,
41708c2ecf20Sopenharmony_ci	.pdev_set_param_cmdid = WMI_TLV_PDEV_SET_PARAM_CMDID,
41718c2ecf20Sopenharmony_ci	.pdev_pktlog_enable_cmdid = WMI_TLV_PDEV_PKTLOG_ENABLE_CMDID,
41728c2ecf20Sopenharmony_ci	.pdev_pktlog_disable_cmdid = WMI_TLV_PDEV_PKTLOG_DISABLE_CMDID,
41738c2ecf20Sopenharmony_ci	.pdev_set_wmm_params_cmdid = WMI_TLV_PDEV_SET_WMM_PARAMS_CMDID,
41748c2ecf20Sopenharmony_ci	.pdev_set_ht_cap_ie_cmdid = WMI_TLV_PDEV_SET_HT_CAP_IE_CMDID,
41758c2ecf20Sopenharmony_ci	.pdev_set_vht_cap_ie_cmdid = WMI_TLV_PDEV_SET_VHT_CAP_IE_CMDID,
41768c2ecf20Sopenharmony_ci	.pdev_set_dscp_tid_map_cmdid = WMI_TLV_PDEV_SET_DSCP_TID_MAP_CMDID,
41778c2ecf20Sopenharmony_ci	.pdev_set_quiet_mode_cmdid = WMI_TLV_PDEV_SET_QUIET_MODE_CMDID,
41788c2ecf20Sopenharmony_ci	.pdev_green_ap_ps_enable_cmdid = WMI_TLV_PDEV_GREEN_AP_PS_ENABLE_CMDID,
41798c2ecf20Sopenharmony_ci	.pdev_get_tpc_config_cmdid = WMI_TLV_PDEV_GET_TPC_CONFIG_CMDID,
41808c2ecf20Sopenharmony_ci	.pdev_set_base_macaddr_cmdid = WMI_TLV_PDEV_SET_BASE_MACADDR_CMDID,
41818c2ecf20Sopenharmony_ci	.vdev_create_cmdid = WMI_TLV_VDEV_CREATE_CMDID,
41828c2ecf20Sopenharmony_ci	.vdev_delete_cmdid = WMI_TLV_VDEV_DELETE_CMDID,
41838c2ecf20Sopenharmony_ci	.vdev_start_request_cmdid = WMI_TLV_VDEV_START_REQUEST_CMDID,
41848c2ecf20Sopenharmony_ci	.vdev_restart_request_cmdid = WMI_TLV_VDEV_RESTART_REQUEST_CMDID,
41858c2ecf20Sopenharmony_ci	.vdev_up_cmdid = WMI_TLV_VDEV_UP_CMDID,
41868c2ecf20Sopenharmony_ci	.vdev_stop_cmdid = WMI_TLV_VDEV_STOP_CMDID,
41878c2ecf20Sopenharmony_ci	.vdev_down_cmdid = WMI_TLV_VDEV_DOWN_CMDID,
41888c2ecf20Sopenharmony_ci	.vdev_set_param_cmdid = WMI_TLV_VDEV_SET_PARAM_CMDID,
41898c2ecf20Sopenharmony_ci	.vdev_install_key_cmdid = WMI_TLV_VDEV_INSTALL_KEY_CMDID,
41908c2ecf20Sopenharmony_ci	.peer_create_cmdid = WMI_TLV_PEER_CREATE_CMDID,
41918c2ecf20Sopenharmony_ci	.peer_delete_cmdid = WMI_TLV_PEER_DELETE_CMDID,
41928c2ecf20Sopenharmony_ci	.peer_flush_tids_cmdid = WMI_TLV_PEER_FLUSH_TIDS_CMDID,
41938c2ecf20Sopenharmony_ci	.peer_set_param_cmdid = WMI_TLV_PEER_SET_PARAM_CMDID,
41948c2ecf20Sopenharmony_ci	.peer_assoc_cmdid = WMI_TLV_PEER_ASSOC_CMDID,
41958c2ecf20Sopenharmony_ci	.peer_add_wds_entry_cmdid = WMI_TLV_PEER_ADD_WDS_ENTRY_CMDID,
41968c2ecf20Sopenharmony_ci	.peer_remove_wds_entry_cmdid = WMI_TLV_PEER_REMOVE_WDS_ENTRY_CMDID,
41978c2ecf20Sopenharmony_ci	.peer_mcast_group_cmdid = WMI_TLV_PEER_MCAST_GROUP_CMDID,
41988c2ecf20Sopenharmony_ci	.bcn_tx_cmdid = WMI_TLV_BCN_TX_CMDID,
41998c2ecf20Sopenharmony_ci	.pdev_send_bcn_cmdid = WMI_TLV_PDEV_SEND_BCN_CMDID,
42008c2ecf20Sopenharmony_ci	.bcn_tmpl_cmdid = WMI_TLV_BCN_TMPL_CMDID,
42018c2ecf20Sopenharmony_ci	.bcn_filter_rx_cmdid = WMI_TLV_BCN_FILTER_RX_CMDID,
42028c2ecf20Sopenharmony_ci	.prb_req_filter_rx_cmdid = WMI_TLV_PRB_REQ_FILTER_RX_CMDID,
42038c2ecf20Sopenharmony_ci	.mgmt_tx_cmdid = WMI_TLV_MGMT_TX_CMDID,
42048c2ecf20Sopenharmony_ci	.mgmt_tx_send_cmdid = WMI_TLV_MGMT_TX_SEND_CMD,
42058c2ecf20Sopenharmony_ci	.prb_tmpl_cmdid = WMI_TLV_PRB_TMPL_CMDID,
42068c2ecf20Sopenharmony_ci	.addba_clear_resp_cmdid = WMI_TLV_ADDBA_CLEAR_RESP_CMDID,
42078c2ecf20Sopenharmony_ci	.addba_send_cmdid = WMI_TLV_ADDBA_SEND_CMDID,
42088c2ecf20Sopenharmony_ci	.addba_status_cmdid = WMI_TLV_ADDBA_STATUS_CMDID,
42098c2ecf20Sopenharmony_ci	.delba_send_cmdid = WMI_TLV_DELBA_SEND_CMDID,
42108c2ecf20Sopenharmony_ci	.addba_set_resp_cmdid = WMI_TLV_ADDBA_SET_RESP_CMDID,
42118c2ecf20Sopenharmony_ci	.send_singleamsdu_cmdid = WMI_TLV_SEND_SINGLEAMSDU_CMDID,
42128c2ecf20Sopenharmony_ci	.sta_powersave_mode_cmdid = WMI_TLV_STA_POWERSAVE_MODE_CMDID,
42138c2ecf20Sopenharmony_ci	.sta_powersave_param_cmdid = WMI_TLV_STA_POWERSAVE_PARAM_CMDID,
42148c2ecf20Sopenharmony_ci	.sta_mimo_ps_mode_cmdid = WMI_TLV_STA_MIMO_PS_MODE_CMDID,
42158c2ecf20Sopenharmony_ci	.pdev_dfs_enable_cmdid = WMI_TLV_PDEV_DFS_ENABLE_CMDID,
42168c2ecf20Sopenharmony_ci	.pdev_dfs_disable_cmdid = WMI_TLV_PDEV_DFS_DISABLE_CMDID,
42178c2ecf20Sopenharmony_ci	.roam_scan_mode = WMI_TLV_ROAM_SCAN_MODE,
42188c2ecf20Sopenharmony_ci	.roam_scan_rssi_threshold = WMI_TLV_ROAM_SCAN_RSSI_THRESHOLD,
42198c2ecf20Sopenharmony_ci	.roam_scan_period = WMI_TLV_ROAM_SCAN_PERIOD,
42208c2ecf20Sopenharmony_ci	.roam_scan_rssi_change_threshold =
42218c2ecf20Sopenharmony_ci				WMI_TLV_ROAM_SCAN_RSSI_CHANGE_THRESHOLD,
42228c2ecf20Sopenharmony_ci	.roam_ap_profile = WMI_TLV_ROAM_AP_PROFILE,
42238c2ecf20Sopenharmony_ci	.ofl_scan_add_ap_profile = WMI_TLV_ROAM_AP_PROFILE,
42248c2ecf20Sopenharmony_ci	.ofl_scan_remove_ap_profile = WMI_TLV_OFL_SCAN_REMOVE_AP_PROFILE,
42258c2ecf20Sopenharmony_ci	.ofl_scan_period = WMI_TLV_OFL_SCAN_PERIOD,
42268c2ecf20Sopenharmony_ci	.p2p_dev_set_device_info = WMI_TLV_P2P_DEV_SET_DEVICE_INFO,
42278c2ecf20Sopenharmony_ci	.p2p_dev_set_discoverability = WMI_TLV_P2P_DEV_SET_DISCOVERABILITY,
42288c2ecf20Sopenharmony_ci	.p2p_go_set_beacon_ie = WMI_TLV_P2P_GO_SET_BEACON_IE,
42298c2ecf20Sopenharmony_ci	.p2p_go_set_probe_resp_ie = WMI_TLV_P2P_GO_SET_PROBE_RESP_IE,
42308c2ecf20Sopenharmony_ci	.p2p_set_vendor_ie_data_cmdid = WMI_TLV_P2P_SET_VENDOR_IE_DATA_CMDID,
42318c2ecf20Sopenharmony_ci	.ap_ps_peer_param_cmdid = WMI_TLV_AP_PS_PEER_PARAM_CMDID,
42328c2ecf20Sopenharmony_ci	.ap_ps_peer_uapsd_coex_cmdid = WMI_TLV_AP_PS_PEER_UAPSD_COEX_CMDID,
42338c2ecf20Sopenharmony_ci	.peer_rate_retry_sched_cmdid = WMI_TLV_PEER_RATE_RETRY_SCHED_CMDID,
42348c2ecf20Sopenharmony_ci	.wlan_profile_trigger_cmdid = WMI_TLV_WLAN_PROFILE_TRIGGER_CMDID,
42358c2ecf20Sopenharmony_ci	.wlan_profile_set_hist_intvl_cmdid =
42368c2ecf20Sopenharmony_ci				WMI_TLV_WLAN_PROFILE_SET_HIST_INTVL_CMDID,
42378c2ecf20Sopenharmony_ci	.wlan_profile_get_profile_data_cmdid =
42388c2ecf20Sopenharmony_ci				WMI_TLV_WLAN_PROFILE_GET_PROFILE_DATA_CMDID,
42398c2ecf20Sopenharmony_ci	.wlan_profile_enable_profile_id_cmdid =
42408c2ecf20Sopenharmony_ci				WMI_TLV_WLAN_PROFILE_ENABLE_PROFILE_ID_CMDID,
42418c2ecf20Sopenharmony_ci	.wlan_profile_list_profile_id_cmdid =
42428c2ecf20Sopenharmony_ci				WMI_TLV_WLAN_PROFILE_LIST_PROFILE_ID_CMDID,
42438c2ecf20Sopenharmony_ci	.pdev_suspend_cmdid = WMI_TLV_PDEV_SUSPEND_CMDID,
42448c2ecf20Sopenharmony_ci	.pdev_resume_cmdid = WMI_TLV_PDEV_RESUME_CMDID,
42458c2ecf20Sopenharmony_ci	.add_bcn_filter_cmdid = WMI_TLV_ADD_BCN_FILTER_CMDID,
42468c2ecf20Sopenharmony_ci	.rmv_bcn_filter_cmdid = WMI_TLV_RMV_BCN_FILTER_CMDID,
42478c2ecf20Sopenharmony_ci	.wow_add_wake_pattern_cmdid = WMI_TLV_WOW_ADD_WAKE_PATTERN_CMDID,
42488c2ecf20Sopenharmony_ci	.wow_del_wake_pattern_cmdid = WMI_TLV_WOW_DEL_WAKE_PATTERN_CMDID,
42498c2ecf20Sopenharmony_ci	.wow_enable_disable_wake_event_cmdid =
42508c2ecf20Sopenharmony_ci				WMI_TLV_WOW_ENABLE_DISABLE_WAKE_EVENT_CMDID,
42518c2ecf20Sopenharmony_ci	.wow_enable_cmdid = WMI_TLV_WOW_ENABLE_CMDID,
42528c2ecf20Sopenharmony_ci	.wow_hostwakeup_from_sleep_cmdid =
42538c2ecf20Sopenharmony_ci				WMI_TLV_WOW_HOSTWAKEUP_FROM_SLEEP_CMDID,
42548c2ecf20Sopenharmony_ci	.rtt_measreq_cmdid = WMI_TLV_RTT_MEASREQ_CMDID,
42558c2ecf20Sopenharmony_ci	.rtt_tsf_cmdid = WMI_TLV_RTT_TSF_CMDID,
42568c2ecf20Sopenharmony_ci	.vdev_spectral_scan_configure_cmdid = WMI_TLV_SPECTRAL_SCAN_CONF_CMDID,
42578c2ecf20Sopenharmony_ci	.vdev_spectral_scan_enable_cmdid = WMI_TLV_SPECTRAL_SCAN_ENABLE_CMDID,
42588c2ecf20Sopenharmony_ci	.request_stats_cmdid = WMI_TLV_REQUEST_STATS_CMDID,
42598c2ecf20Sopenharmony_ci	.request_peer_stats_info_cmdid = WMI_TLV_REQUEST_PEER_STATS_INFO_CMDID,
42608c2ecf20Sopenharmony_ci	.set_arp_ns_offload_cmdid = WMI_TLV_SET_ARP_NS_OFFLOAD_CMDID,
42618c2ecf20Sopenharmony_ci	.network_list_offload_config_cmdid =
42628c2ecf20Sopenharmony_ci				WMI_TLV_NETWORK_LIST_OFFLOAD_CONFIG_CMDID,
42638c2ecf20Sopenharmony_ci	.gtk_offload_cmdid = WMI_TLV_GTK_OFFLOAD_CMDID,
42648c2ecf20Sopenharmony_ci	.csa_offload_enable_cmdid = WMI_TLV_CSA_OFFLOAD_ENABLE_CMDID,
42658c2ecf20Sopenharmony_ci	.csa_offload_chanswitch_cmdid = WMI_TLV_CSA_OFFLOAD_CHANSWITCH_CMDID,
42668c2ecf20Sopenharmony_ci	.chatter_set_mode_cmdid = WMI_TLV_CHATTER_SET_MODE_CMDID,
42678c2ecf20Sopenharmony_ci	.peer_tid_addba_cmdid = WMI_TLV_PEER_TID_ADDBA_CMDID,
42688c2ecf20Sopenharmony_ci	.peer_tid_delba_cmdid = WMI_TLV_PEER_TID_DELBA_CMDID,
42698c2ecf20Sopenharmony_ci	.sta_dtim_ps_method_cmdid = WMI_TLV_STA_DTIM_PS_METHOD_CMDID,
42708c2ecf20Sopenharmony_ci	.sta_uapsd_auto_trig_cmdid = WMI_TLV_STA_UAPSD_AUTO_TRIG_CMDID,
42718c2ecf20Sopenharmony_ci	.sta_keepalive_cmd = WMI_TLV_STA_KEEPALIVE_CMDID,
42728c2ecf20Sopenharmony_ci	.echo_cmdid = WMI_TLV_ECHO_CMDID,
42738c2ecf20Sopenharmony_ci	.pdev_utf_cmdid = WMI_TLV_PDEV_UTF_CMDID,
42748c2ecf20Sopenharmony_ci	.dbglog_cfg_cmdid = WMI_TLV_DBGLOG_CFG_CMDID,
42758c2ecf20Sopenharmony_ci	.pdev_qvit_cmdid = WMI_TLV_PDEV_QVIT_CMDID,
42768c2ecf20Sopenharmony_ci	.pdev_ftm_intg_cmdid = WMI_TLV_PDEV_FTM_INTG_CMDID,
42778c2ecf20Sopenharmony_ci	.vdev_set_keepalive_cmdid = WMI_TLV_VDEV_SET_KEEPALIVE_CMDID,
42788c2ecf20Sopenharmony_ci	.vdev_get_keepalive_cmdid = WMI_TLV_VDEV_GET_KEEPALIVE_CMDID,
42798c2ecf20Sopenharmony_ci	.force_fw_hang_cmdid = WMI_TLV_FORCE_FW_HANG_CMDID,
42808c2ecf20Sopenharmony_ci	.gpio_config_cmdid = WMI_TLV_GPIO_CONFIG_CMDID,
42818c2ecf20Sopenharmony_ci	.gpio_output_cmdid = WMI_TLV_GPIO_OUTPUT_CMDID,
42828c2ecf20Sopenharmony_ci	.pdev_get_temperature_cmdid = WMI_TLV_PDEV_GET_TEMPERATURE_CMDID,
42838c2ecf20Sopenharmony_ci	.vdev_set_wmm_params_cmdid = WMI_TLV_VDEV_SET_WMM_PARAMS_CMDID,
42848c2ecf20Sopenharmony_ci	.tdls_set_state_cmdid = WMI_TLV_TDLS_SET_STATE_CMDID,
42858c2ecf20Sopenharmony_ci	.tdls_peer_update_cmdid = WMI_TLV_TDLS_PEER_UPDATE_CMDID,
42868c2ecf20Sopenharmony_ci	.adaptive_qcs_cmdid = WMI_TLV_RESMGR_ADAPTIVE_OCS_CMDID,
42878c2ecf20Sopenharmony_ci	.scan_update_request_cmdid = WMI_CMD_UNSUPPORTED,
42888c2ecf20Sopenharmony_ci	.vdev_standby_response_cmdid = WMI_CMD_UNSUPPORTED,
42898c2ecf20Sopenharmony_ci	.vdev_resume_response_cmdid = WMI_CMD_UNSUPPORTED,
42908c2ecf20Sopenharmony_ci	.wlan_peer_caching_add_peer_cmdid = WMI_CMD_UNSUPPORTED,
42918c2ecf20Sopenharmony_ci	.wlan_peer_caching_evict_peer_cmdid = WMI_CMD_UNSUPPORTED,
42928c2ecf20Sopenharmony_ci	.wlan_peer_caching_restore_peer_cmdid = WMI_CMD_UNSUPPORTED,
42938c2ecf20Sopenharmony_ci	.wlan_peer_caching_print_all_peers_info_cmdid = WMI_CMD_UNSUPPORTED,
42948c2ecf20Sopenharmony_ci	.peer_update_wds_entry_cmdid = WMI_CMD_UNSUPPORTED,
42958c2ecf20Sopenharmony_ci	.peer_add_proxy_sta_entry_cmdid = WMI_CMD_UNSUPPORTED,
42968c2ecf20Sopenharmony_ci	.rtt_keepalive_cmdid = WMI_CMD_UNSUPPORTED,
42978c2ecf20Sopenharmony_ci	.oem_req_cmdid = WMI_CMD_UNSUPPORTED,
42988c2ecf20Sopenharmony_ci	.nan_cmdid = WMI_CMD_UNSUPPORTED,
42998c2ecf20Sopenharmony_ci	.vdev_ratemask_cmdid = WMI_CMD_UNSUPPORTED,
43008c2ecf20Sopenharmony_ci	.qboost_cfg_cmdid = WMI_CMD_UNSUPPORTED,
43018c2ecf20Sopenharmony_ci	.pdev_smart_ant_enable_cmdid = WMI_CMD_UNSUPPORTED,
43028c2ecf20Sopenharmony_ci	.pdev_smart_ant_set_rx_antenna_cmdid = WMI_CMD_UNSUPPORTED,
43038c2ecf20Sopenharmony_ci	.peer_smart_ant_set_tx_antenna_cmdid = WMI_CMD_UNSUPPORTED,
43048c2ecf20Sopenharmony_ci	.peer_smart_ant_set_train_info_cmdid = WMI_CMD_UNSUPPORTED,
43058c2ecf20Sopenharmony_ci	.peer_smart_ant_set_node_config_ops_cmdid = WMI_CMD_UNSUPPORTED,
43068c2ecf20Sopenharmony_ci	.pdev_set_antenna_switch_table_cmdid = WMI_CMD_UNSUPPORTED,
43078c2ecf20Sopenharmony_ci	.pdev_set_ctl_table_cmdid = WMI_CMD_UNSUPPORTED,
43088c2ecf20Sopenharmony_ci	.pdev_set_mimogain_table_cmdid = WMI_CMD_UNSUPPORTED,
43098c2ecf20Sopenharmony_ci	.pdev_ratepwr_table_cmdid = WMI_CMD_UNSUPPORTED,
43108c2ecf20Sopenharmony_ci	.pdev_ratepwr_chainmsk_table_cmdid = WMI_CMD_UNSUPPORTED,
43118c2ecf20Sopenharmony_ci	.pdev_fips_cmdid = WMI_CMD_UNSUPPORTED,
43128c2ecf20Sopenharmony_ci	.tt_set_conf_cmdid = WMI_CMD_UNSUPPORTED,
43138c2ecf20Sopenharmony_ci	.fwtest_cmdid = WMI_CMD_UNSUPPORTED,
43148c2ecf20Sopenharmony_ci	.vdev_atf_request_cmdid = WMI_CMD_UNSUPPORTED,
43158c2ecf20Sopenharmony_ci	.peer_atf_request_cmdid = WMI_CMD_UNSUPPORTED,
43168c2ecf20Sopenharmony_ci	.pdev_get_ani_cck_config_cmdid = WMI_CMD_UNSUPPORTED,
43178c2ecf20Sopenharmony_ci	.pdev_get_ani_ofdm_config_cmdid = WMI_CMD_UNSUPPORTED,
43188c2ecf20Sopenharmony_ci	.pdev_reserve_ast_entry_cmdid = WMI_CMD_UNSUPPORTED,
43198c2ecf20Sopenharmony_ci};
43208c2ecf20Sopenharmony_ci
43218c2ecf20Sopenharmony_cistatic struct wmi_pdev_param_map wmi_tlv_pdev_param_map = {
43228c2ecf20Sopenharmony_ci	.tx_chain_mask = WMI_TLV_PDEV_PARAM_TX_CHAIN_MASK,
43238c2ecf20Sopenharmony_ci	.rx_chain_mask = WMI_TLV_PDEV_PARAM_RX_CHAIN_MASK,
43248c2ecf20Sopenharmony_ci	.txpower_limit2g = WMI_TLV_PDEV_PARAM_TXPOWER_LIMIT2G,
43258c2ecf20Sopenharmony_ci	.txpower_limit5g = WMI_TLV_PDEV_PARAM_TXPOWER_LIMIT5G,
43268c2ecf20Sopenharmony_ci	.txpower_scale = WMI_TLV_PDEV_PARAM_TXPOWER_SCALE,
43278c2ecf20Sopenharmony_ci	.beacon_gen_mode = WMI_TLV_PDEV_PARAM_BEACON_GEN_MODE,
43288c2ecf20Sopenharmony_ci	.beacon_tx_mode = WMI_TLV_PDEV_PARAM_BEACON_TX_MODE,
43298c2ecf20Sopenharmony_ci	.resmgr_offchan_mode = WMI_TLV_PDEV_PARAM_RESMGR_OFFCHAN_MODE,
43308c2ecf20Sopenharmony_ci	.protection_mode = WMI_TLV_PDEV_PARAM_PROTECTION_MODE,
43318c2ecf20Sopenharmony_ci	.dynamic_bw = WMI_TLV_PDEV_PARAM_DYNAMIC_BW,
43328c2ecf20Sopenharmony_ci	.non_agg_sw_retry_th = WMI_TLV_PDEV_PARAM_NON_AGG_SW_RETRY_TH,
43338c2ecf20Sopenharmony_ci	.agg_sw_retry_th = WMI_TLV_PDEV_PARAM_AGG_SW_RETRY_TH,
43348c2ecf20Sopenharmony_ci	.sta_kickout_th = WMI_TLV_PDEV_PARAM_STA_KICKOUT_TH,
43358c2ecf20Sopenharmony_ci	.ac_aggrsize_scaling = WMI_TLV_PDEV_PARAM_AC_AGGRSIZE_SCALING,
43368c2ecf20Sopenharmony_ci	.ltr_enable = WMI_TLV_PDEV_PARAM_LTR_ENABLE,
43378c2ecf20Sopenharmony_ci	.ltr_ac_latency_be = WMI_TLV_PDEV_PARAM_LTR_AC_LATENCY_BE,
43388c2ecf20Sopenharmony_ci	.ltr_ac_latency_bk = WMI_TLV_PDEV_PARAM_LTR_AC_LATENCY_BK,
43398c2ecf20Sopenharmony_ci	.ltr_ac_latency_vi = WMI_TLV_PDEV_PARAM_LTR_AC_LATENCY_VI,
43408c2ecf20Sopenharmony_ci	.ltr_ac_latency_vo = WMI_TLV_PDEV_PARAM_LTR_AC_LATENCY_VO,
43418c2ecf20Sopenharmony_ci	.ltr_ac_latency_timeout = WMI_TLV_PDEV_PARAM_LTR_AC_LATENCY_TIMEOUT,
43428c2ecf20Sopenharmony_ci	.ltr_sleep_override = WMI_TLV_PDEV_PARAM_LTR_SLEEP_OVERRIDE,
43438c2ecf20Sopenharmony_ci	.ltr_rx_override = WMI_TLV_PDEV_PARAM_LTR_RX_OVERRIDE,
43448c2ecf20Sopenharmony_ci	.ltr_tx_activity_timeout = WMI_TLV_PDEV_PARAM_LTR_TX_ACTIVITY_TIMEOUT,
43458c2ecf20Sopenharmony_ci	.l1ss_enable = WMI_TLV_PDEV_PARAM_L1SS_ENABLE,
43468c2ecf20Sopenharmony_ci	.dsleep_enable = WMI_TLV_PDEV_PARAM_DSLEEP_ENABLE,
43478c2ecf20Sopenharmony_ci	.pcielp_txbuf_flush = WMI_TLV_PDEV_PARAM_PCIELP_TXBUF_FLUSH,
43488c2ecf20Sopenharmony_ci	.pcielp_txbuf_watermark = WMI_TLV_PDEV_PARAM_PCIELP_TXBUF_TMO_EN,
43498c2ecf20Sopenharmony_ci	.pcielp_txbuf_tmo_en = WMI_TLV_PDEV_PARAM_PCIELP_TXBUF_TMO_EN,
43508c2ecf20Sopenharmony_ci	.pcielp_txbuf_tmo_value = WMI_TLV_PDEV_PARAM_PCIELP_TXBUF_TMO_VALUE,
43518c2ecf20Sopenharmony_ci	.pdev_stats_update_period = WMI_TLV_PDEV_PARAM_PDEV_STATS_UPDATE_PERIOD,
43528c2ecf20Sopenharmony_ci	.vdev_stats_update_period = WMI_TLV_PDEV_PARAM_VDEV_STATS_UPDATE_PERIOD,
43538c2ecf20Sopenharmony_ci	.peer_stats_update_period = WMI_TLV_PDEV_PARAM_PEER_STATS_UPDATE_PERIOD,
43548c2ecf20Sopenharmony_ci	.bcnflt_stats_update_period =
43558c2ecf20Sopenharmony_ci				WMI_TLV_PDEV_PARAM_BCNFLT_STATS_UPDATE_PERIOD,
43568c2ecf20Sopenharmony_ci	.pmf_qos = WMI_TLV_PDEV_PARAM_PMF_QOS,
43578c2ecf20Sopenharmony_ci	.arp_ac_override = WMI_TLV_PDEV_PARAM_ARP_AC_OVERRIDE,
43588c2ecf20Sopenharmony_ci	.dcs = WMI_TLV_PDEV_PARAM_DCS,
43598c2ecf20Sopenharmony_ci	.ani_enable = WMI_TLV_PDEV_PARAM_ANI_ENABLE,
43608c2ecf20Sopenharmony_ci	.ani_poll_period = WMI_TLV_PDEV_PARAM_ANI_POLL_PERIOD,
43618c2ecf20Sopenharmony_ci	.ani_listen_period = WMI_TLV_PDEV_PARAM_ANI_LISTEN_PERIOD,
43628c2ecf20Sopenharmony_ci	.ani_ofdm_level = WMI_TLV_PDEV_PARAM_ANI_OFDM_LEVEL,
43638c2ecf20Sopenharmony_ci	.ani_cck_level = WMI_TLV_PDEV_PARAM_ANI_CCK_LEVEL,
43648c2ecf20Sopenharmony_ci	.dyntxchain = WMI_TLV_PDEV_PARAM_DYNTXCHAIN,
43658c2ecf20Sopenharmony_ci	.proxy_sta = WMI_TLV_PDEV_PARAM_PROXY_STA,
43668c2ecf20Sopenharmony_ci	.idle_ps_config = WMI_TLV_PDEV_PARAM_IDLE_PS_CONFIG,
43678c2ecf20Sopenharmony_ci	.power_gating_sleep = WMI_TLV_PDEV_PARAM_POWER_GATING_SLEEP,
43688c2ecf20Sopenharmony_ci	.fast_channel_reset = WMI_TLV_PDEV_PARAM_UNSUPPORTED,
43698c2ecf20Sopenharmony_ci	.burst_dur = WMI_TLV_PDEV_PARAM_BURST_DUR,
43708c2ecf20Sopenharmony_ci	.burst_enable = WMI_TLV_PDEV_PARAM_BURST_ENABLE,
43718c2ecf20Sopenharmony_ci	.cal_period = WMI_PDEV_PARAM_UNSUPPORTED,
43728c2ecf20Sopenharmony_ci	.aggr_burst = WMI_PDEV_PARAM_UNSUPPORTED,
43738c2ecf20Sopenharmony_ci	.rx_decap_mode = WMI_PDEV_PARAM_UNSUPPORTED,
43748c2ecf20Sopenharmony_ci	.smart_antenna_default_antenna = WMI_PDEV_PARAM_UNSUPPORTED,
43758c2ecf20Sopenharmony_ci	.igmpmld_override = WMI_PDEV_PARAM_UNSUPPORTED,
43768c2ecf20Sopenharmony_ci	.igmpmld_tid = WMI_PDEV_PARAM_UNSUPPORTED,
43778c2ecf20Sopenharmony_ci	.antenna_gain = WMI_PDEV_PARAM_UNSUPPORTED,
43788c2ecf20Sopenharmony_ci	.rx_filter = WMI_PDEV_PARAM_UNSUPPORTED,
43798c2ecf20Sopenharmony_ci	.set_mcast_to_ucast_tid = WMI_PDEV_PARAM_UNSUPPORTED,
43808c2ecf20Sopenharmony_ci	.proxy_sta_mode = WMI_PDEV_PARAM_UNSUPPORTED,
43818c2ecf20Sopenharmony_ci	.set_mcast2ucast_mode = WMI_PDEV_PARAM_UNSUPPORTED,
43828c2ecf20Sopenharmony_ci	.set_mcast2ucast_buffer = WMI_PDEV_PARAM_UNSUPPORTED,
43838c2ecf20Sopenharmony_ci	.remove_mcast2ucast_buffer = WMI_PDEV_PARAM_UNSUPPORTED,
43848c2ecf20Sopenharmony_ci	.peer_sta_ps_statechg_enable = WMI_PDEV_PARAM_UNSUPPORTED,
43858c2ecf20Sopenharmony_ci	.igmpmld_ac_override = WMI_PDEV_PARAM_UNSUPPORTED,
43868c2ecf20Sopenharmony_ci	.block_interbss = WMI_PDEV_PARAM_UNSUPPORTED,
43878c2ecf20Sopenharmony_ci	.set_disable_reset_cmdid = WMI_PDEV_PARAM_UNSUPPORTED,
43888c2ecf20Sopenharmony_ci	.set_msdu_ttl_cmdid = WMI_PDEV_PARAM_UNSUPPORTED,
43898c2ecf20Sopenharmony_ci	.set_ppdu_duration_cmdid = WMI_PDEV_PARAM_UNSUPPORTED,
43908c2ecf20Sopenharmony_ci	.txbf_sound_period_cmdid = WMI_PDEV_PARAM_UNSUPPORTED,
43918c2ecf20Sopenharmony_ci	.set_promisc_mode_cmdid = WMI_PDEV_PARAM_UNSUPPORTED,
43928c2ecf20Sopenharmony_ci	.set_burst_mode_cmdid = WMI_PDEV_PARAM_UNSUPPORTED,
43938c2ecf20Sopenharmony_ci	.en_stats = WMI_PDEV_PARAM_UNSUPPORTED,
43948c2ecf20Sopenharmony_ci	.mu_group_policy = WMI_PDEV_PARAM_UNSUPPORTED,
43958c2ecf20Sopenharmony_ci	.noise_detection = WMI_PDEV_PARAM_UNSUPPORTED,
43968c2ecf20Sopenharmony_ci	.noise_threshold = WMI_PDEV_PARAM_UNSUPPORTED,
43978c2ecf20Sopenharmony_ci	.dpd_enable = WMI_PDEV_PARAM_UNSUPPORTED,
43988c2ecf20Sopenharmony_ci	.set_mcast_bcast_echo = WMI_PDEV_PARAM_UNSUPPORTED,
43998c2ecf20Sopenharmony_ci	.atf_strict_sch = WMI_PDEV_PARAM_UNSUPPORTED,
44008c2ecf20Sopenharmony_ci	.atf_sched_duration = WMI_PDEV_PARAM_UNSUPPORTED,
44018c2ecf20Sopenharmony_ci	.ant_plzn = WMI_PDEV_PARAM_UNSUPPORTED,
44028c2ecf20Sopenharmony_ci	.mgmt_retry_limit = WMI_PDEV_PARAM_UNSUPPORTED,
44038c2ecf20Sopenharmony_ci	.sensitivity_level = WMI_PDEV_PARAM_UNSUPPORTED,
44048c2ecf20Sopenharmony_ci	.signed_txpower_2g = WMI_PDEV_PARAM_UNSUPPORTED,
44058c2ecf20Sopenharmony_ci	.signed_txpower_5g = WMI_PDEV_PARAM_UNSUPPORTED,
44068c2ecf20Sopenharmony_ci	.enable_per_tid_amsdu = WMI_PDEV_PARAM_UNSUPPORTED,
44078c2ecf20Sopenharmony_ci	.enable_per_tid_ampdu = WMI_PDEV_PARAM_UNSUPPORTED,
44088c2ecf20Sopenharmony_ci	.cca_threshold = WMI_PDEV_PARAM_UNSUPPORTED,
44098c2ecf20Sopenharmony_ci	.rts_fixed_rate = WMI_PDEV_PARAM_UNSUPPORTED,
44108c2ecf20Sopenharmony_ci	.pdev_reset = WMI_PDEV_PARAM_UNSUPPORTED,
44118c2ecf20Sopenharmony_ci	.wapi_mbssid_offset = WMI_PDEV_PARAM_UNSUPPORTED,
44128c2ecf20Sopenharmony_ci	.arp_srcaddr = WMI_PDEV_PARAM_UNSUPPORTED,
44138c2ecf20Sopenharmony_ci	.arp_dstaddr = WMI_PDEV_PARAM_UNSUPPORTED,
44148c2ecf20Sopenharmony_ci	.rfkill_config = WMI_TLV_PDEV_PARAM_HW_RFKILL_CONFIG,
44158c2ecf20Sopenharmony_ci	.rfkill_enable = WMI_TLV_PDEV_PARAM_RFKILL_ENABLE,
44168c2ecf20Sopenharmony_ci	.peer_stats_info_enable = WMI_TLV_PDEV_PARAM_PEER_STATS_INFO_ENABLE,
44178c2ecf20Sopenharmony_ci};
44188c2ecf20Sopenharmony_ci
44198c2ecf20Sopenharmony_cistatic struct wmi_peer_param_map wmi_tlv_peer_param_map = {
44208c2ecf20Sopenharmony_ci	.smps_state = WMI_TLV_PEER_SMPS_STATE,
44218c2ecf20Sopenharmony_ci	.ampdu = WMI_TLV_PEER_AMPDU,
44228c2ecf20Sopenharmony_ci	.authorize = WMI_TLV_PEER_AUTHORIZE,
44238c2ecf20Sopenharmony_ci	.chan_width = WMI_TLV_PEER_CHAN_WIDTH,
44248c2ecf20Sopenharmony_ci	.nss = WMI_TLV_PEER_NSS,
44258c2ecf20Sopenharmony_ci	.use_4addr = WMI_TLV_PEER_USE_4ADDR,
44268c2ecf20Sopenharmony_ci	.membership = WMI_TLV_PEER_MEMBERSHIP,
44278c2ecf20Sopenharmony_ci	.user_pos = WMI_TLV_PEER_USERPOS,
44288c2ecf20Sopenharmony_ci	.crit_proto_hint_enabled = WMI_TLV_PEER_CRIT_PROTO_HINT_ENABLED,
44298c2ecf20Sopenharmony_ci	.tx_fail_cnt_thr = WMI_TLV_PEER_TX_FAIL_CNT_THR,
44308c2ecf20Sopenharmony_ci	.set_hw_retry_cts2s = WMI_TLV_PEER_SET_HW_RETRY_CTS2S,
44318c2ecf20Sopenharmony_ci	.ibss_atim_win_len = WMI_TLV_PEER_IBSS_ATIM_WINDOW_LENGTH,
44328c2ecf20Sopenharmony_ci	.phymode = WMI_TLV_PEER_PHYMODE,
44338c2ecf20Sopenharmony_ci	.use_fixed_power = WMI_TLV_PEER_USE_FIXED_PWR,
44348c2ecf20Sopenharmony_ci	.dummy_var = WMI_TLV_PEER_DUMMY_VAR,
44358c2ecf20Sopenharmony_ci};
44368c2ecf20Sopenharmony_ci
44378c2ecf20Sopenharmony_cistatic struct wmi_vdev_param_map wmi_tlv_vdev_param_map = {
44388c2ecf20Sopenharmony_ci	.rts_threshold = WMI_TLV_VDEV_PARAM_RTS_THRESHOLD,
44398c2ecf20Sopenharmony_ci	.fragmentation_threshold = WMI_TLV_VDEV_PARAM_FRAGMENTATION_THRESHOLD,
44408c2ecf20Sopenharmony_ci	.beacon_interval = WMI_TLV_VDEV_PARAM_BEACON_INTERVAL,
44418c2ecf20Sopenharmony_ci	.listen_interval = WMI_TLV_VDEV_PARAM_LISTEN_INTERVAL,
44428c2ecf20Sopenharmony_ci	.multicast_rate = WMI_TLV_VDEV_PARAM_MULTICAST_RATE,
44438c2ecf20Sopenharmony_ci	.mgmt_tx_rate = WMI_TLV_VDEV_PARAM_MGMT_TX_RATE,
44448c2ecf20Sopenharmony_ci	.slot_time = WMI_TLV_VDEV_PARAM_SLOT_TIME,
44458c2ecf20Sopenharmony_ci	.preamble = WMI_TLV_VDEV_PARAM_PREAMBLE,
44468c2ecf20Sopenharmony_ci	.swba_time = WMI_TLV_VDEV_PARAM_SWBA_TIME,
44478c2ecf20Sopenharmony_ci	.wmi_vdev_stats_update_period = WMI_TLV_VDEV_STATS_UPDATE_PERIOD,
44488c2ecf20Sopenharmony_ci	.wmi_vdev_pwrsave_ageout_time = WMI_TLV_VDEV_PWRSAVE_AGEOUT_TIME,
44498c2ecf20Sopenharmony_ci	.wmi_vdev_host_swba_interval = WMI_TLV_VDEV_HOST_SWBA_INTERVAL,
44508c2ecf20Sopenharmony_ci	.dtim_period = WMI_TLV_VDEV_PARAM_DTIM_PERIOD,
44518c2ecf20Sopenharmony_ci	.wmi_vdev_oc_scheduler_air_time_limit =
44528c2ecf20Sopenharmony_ci				WMI_TLV_VDEV_OC_SCHEDULER_AIR_TIME_LIMIT,
44538c2ecf20Sopenharmony_ci	.wds = WMI_TLV_VDEV_PARAM_WDS,
44548c2ecf20Sopenharmony_ci	.atim_window = WMI_TLV_VDEV_PARAM_ATIM_WINDOW,
44558c2ecf20Sopenharmony_ci	.bmiss_count_max = WMI_TLV_VDEV_PARAM_BMISS_COUNT_MAX,
44568c2ecf20Sopenharmony_ci	.bmiss_first_bcnt = WMI_TLV_VDEV_PARAM_BMISS_FIRST_BCNT,
44578c2ecf20Sopenharmony_ci	.bmiss_final_bcnt = WMI_TLV_VDEV_PARAM_BMISS_FINAL_BCNT,
44588c2ecf20Sopenharmony_ci	.feature_wmm = WMI_TLV_VDEV_PARAM_FEATURE_WMM,
44598c2ecf20Sopenharmony_ci	.chwidth = WMI_TLV_VDEV_PARAM_CHWIDTH,
44608c2ecf20Sopenharmony_ci	.chextoffset = WMI_TLV_VDEV_PARAM_CHEXTOFFSET,
44618c2ecf20Sopenharmony_ci	.disable_htprotection =	WMI_TLV_VDEV_PARAM_DISABLE_HTPROTECTION,
44628c2ecf20Sopenharmony_ci	.sta_quickkickout = WMI_TLV_VDEV_PARAM_STA_QUICKKICKOUT,
44638c2ecf20Sopenharmony_ci	.mgmt_rate = WMI_TLV_VDEV_PARAM_MGMT_RATE,
44648c2ecf20Sopenharmony_ci	.protection_mode = WMI_TLV_VDEV_PARAM_PROTECTION_MODE,
44658c2ecf20Sopenharmony_ci	.fixed_rate = WMI_TLV_VDEV_PARAM_FIXED_RATE,
44668c2ecf20Sopenharmony_ci	.sgi = WMI_TLV_VDEV_PARAM_SGI,
44678c2ecf20Sopenharmony_ci	.ldpc = WMI_TLV_VDEV_PARAM_LDPC,
44688c2ecf20Sopenharmony_ci	.tx_stbc = WMI_TLV_VDEV_PARAM_TX_STBC,
44698c2ecf20Sopenharmony_ci	.rx_stbc = WMI_TLV_VDEV_PARAM_RX_STBC,
44708c2ecf20Sopenharmony_ci	.intra_bss_fwd = WMI_TLV_VDEV_PARAM_INTRA_BSS_FWD,
44718c2ecf20Sopenharmony_ci	.def_keyid = WMI_TLV_VDEV_PARAM_DEF_KEYID,
44728c2ecf20Sopenharmony_ci	.nss = WMI_TLV_VDEV_PARAM_NSS,
44738c2ecf20Sopenharmony_ci	.bcast_data_rate = WMI_TLV_VDEV_PARAM_BCAST_DATA_RATE,
44748c2ecf20Sopenharmony_ci	.mcast_data_rate = WMI_TLV_VDEV_PARAM_MCAST_DATA_RATE,
44758c2ecf20Sopenharmony_ci	.mcast_indicate = WMI_TLV_VDEV_PARAM_MCAST_INDICATE,
44768c2ecf20Sopenharmony_ci	.dhcp_indicate = WMI_TLV_VDEV_PARAM_DHCP_INDICATE,
44778c2ecf20Sopenharmony_ci	.unknown_dest_indicate = WMI_TLV_VDEV_PARAM_UNKNOWN_DEST_INDICATE,
44788c2ecf20Sopenharmony_ci	.ap_keepalive_min_idle_inactive_time_secs =
44798c2ecf20Sopenharmony_ci		WMI_TLV_VDEV_PARAM_AP_KEEPALIVE_MIN_IDLE_INACTIVE_TIME_SECS,
44808c2ecf20Sopenharmony_ci	.ap_keepalive_max_idle_inactive_time_secs =
44818c2ecf20Sopenharmony_ci		WMI_TLV_VDEV_PARAM_AP_KEEPALIVE_MAX_IDLE_INACTIVE_TIME_SECS,
44828c2ecf20Sopenharmony_ci	.ap_keepalive_max_unresponsive_time_secs =
44838c2ecf20Sopenharmony_ci		WMI_TLV_VDEV_PARAM_AP_KEEPALIVE_MAX_UNRESPONSIVE_TIME_SECS,
44848c2ecf20Sopenharmony_ci	.ap_enable_nawds = WMI_TLV_VDEV_PARAM_AP_ENABLE_NAWDS,
44858c2ecf20Sopenharmony_ci	.mcast2ucast_set = WMI_TLV_VDEV_PARAM_UNSUPPORTED,
44868c2ecf20Sopenharmony_ci	.enable_rtscts = WMI_TLV_VDEV_PARAM_ENABLE_RTSCTS,
44878c2ecf20Sopenharmony_ci	.txbf = WMI_TLV_VDEV_PARAM_TXBF,
44888c2ecf20Sopenharmony_ci	.packet_powersave = WMI_TLV_VDEV_PARAM_PACKET_POWERSAVE,
44898c2ecf20Sopenharmony_ci	.drop_unencry = WMI_TLV_VDEV_PARAM_DROP_UNENCRY,
44908c2ecf20Sopenharmony_ci	.tx_encap_type = WMI_TLV_VDEV_PARAM_TX_ENCAP_TYPE,
44918c2ecf20Sopenharmony_ci	.ap_detect_out_of_sync_sleeping_sta_time_secs =
44928c2ecf20Sopenharmony_ci					WMI_TLV_VDEV_PARAM_UNSUPPORTED,
44938c2ecf20Sopenharmony_ci	.rc_num_retries = WMI_VDEV_PARAM_UNSUPPORTED,
44948c2ecf20Sopenharmony_ci	.cabq_maxdur = WMI_VDEV_PARAM_UNSUPPORTED,
44958c2ecf20Sopenharmony_ci	.mfptest_set = WMI_VDEV_PARAM_UNSUPPORTED,
44968c2ecf20Sopenharmony_ci	.rts_fixed_rate = WMI_VDEV_PARAM_UNSUPPORTED,
44978c2ecf20Sopenharmony_ci	.vht_sgimask = WMI_VDEV_PARAM_UNSUPPORTED,
44988c2ecf20Sopenharmony_ci	.vht80_ratemask = WMI_VDEV_PARAM_UNSUPPORTED,
44998c2ecf20Sopenharmony_ci	.early_rx_adjust_enable = WMI_VDEV_PARAM_UNSUPPORTED,
45008c2ecf20Sopenharmony_ci	.early_rx_tgt_bmiss_num = WMI_VDEV_PARAM_UNSUPPORTED,
45018c2ecf20Sopenharmony_ci	.early_rx_bmiss_sample_cycle = WMI_VDEV_PARAM_UNSUPPORTED,
45028c2ecf20Sopenharmony_ci	.early_rx_slop_step = WMI_VDEV_PARAM_UNSUPPORTED,
45038c2ecf20Sopenharmony_ci	.early_rx_init_slop = WMI_VDEV_PARAM_UNSUPPORTED,
45048c2ecf20Sopenharmony_ci	.early_rx_adjust_pause = WMI_VDEV_PARAM_UNSUPPORTED,
45058c2ecf20Sopenharmony_ci	.proxy_sta = WMI_VDEV_PARAM_UNSUPPORTED,
45068c2ecf20Sopenharmony_ci	.meru_vc = WMI_VDEV_PARAM_UNSUPPORTED,
45078c2ecf20Sopenharmony_ci	.rx_decap_type = WMI_VDEV_PARAM_UNSUPPORTED,
45088c2ecf20Sopenharmony_ci	.bw_nss_ratemask = WMI_VDEV_PARAM_UNSUPPORTED,
45098c2ecf20Sopenharmony_ci};
45108c2ecf20Sopenharmony_ci
45118c2ecf20Sopenharmony_cistatic const struct wmi_ops wmi_tlv_ops = {
45128c2ecf20Sopenharmony_ci	.rx = ath10k_wmi_tlv_op_rx,
45138c2ecf20Sopenharmony_ci	.map_svc = wmi_tlv_svc_map,
45148c2ecf20Sopenharmony_ci	.map_svc_ext = wmi_tlv_svc_map_ext,
45158c2ecf20Sopenharmony_ci
45168c2ecf20Sopenharmony_ci	.pull_scan = ath10k_wmi_tlv_op_pull_scan_ev,
45178c2ecf20Sopenharmony_ci	.pull_mgmt_rx = ath10k_wmi_tlv_op_pull_mgmt_rx_ev,
45188c2ecf20Sopenharmony_ci	.pull_mgmt_tx_compl = ath10k_wmi_tlv_op_pull_mgmt_tx_compl_ev,
45198c2ecf20Sopenharmony_ci	.pull_mgmt_tx_bundle_compl = ath10k_wmi_tlv_op_pull_mgmt_tx_bundle_compl_ev,
45208c2ecf20Sopenharmony_ci	.pull_ch_info = ath10k_wmi_tlv_op_pull_ch_info_ev,
45218c2ecf20Sopenharmony_ci	.pull_vdev_start = ath10k_wmi_tlv_op_pull_vdev_start_ev,
45228c2ecf20Sopenharmony_ci	.pull_peer_kick = ath10k_wmi_tlv_op_pull_peer_kick_ev,
45238c2ecf20Sopenharmony_ci	.pull_swba = ath10k_wmi_tlv_op_pull_swba_ev,
45248c2ecf20Sopenharmony_ci	.pull_phyerr_hdr = ath10k_wmi_tlv_op_pull_phyerr_ev_hdr,
45258c2ecf20Sopenharmony_ci	.pull_phyerr = ath10k_wmi_op_pull_phyerr_ev,
45268c2ecf20Sopenharmony_ci	.pull_svc_rdy = ath10k_wmi_tlv_op_pull_svc_rdy_ev,
45278c2ecf20Sopenharmony_ci	.pull_rdy = ath10k_wmi_tlv_op_pull_rdy_ev,
45288c2ecf20Sopenharmony_ci	.pull_svc_avail = ath10k_wmi_tlv_op_pull_svc_avail,
45298c2ecf20Sopenharmony_ci	.pull_fw_stats = ath10k_wmi_tlv_op_pull_fw_stats,
45308c2ecf20Sopenharmony_ci	.pull_roam_ev = ath10k_wmi_tlv_op_pull_roam_ev,
45318c2ecf20Sopenharmony_ci	.pull_wow_event = ath10k_wmi_tlv_op_pull_wow_ev,
45328c2ecf20Sopenharmony_ci	.pull_echo_ev = ath10k_wmi_tlv_op_pull_echo_ev,
45338c2ecf20Sopenharmony_ci	.get_txbf_conf_scheme = ath10k_wmi_tlv_txbf_conf_scheme,
45348c2ecf20Sopenharmony_ci
45358c2ecf20Sopenharmony_ci	.gen_pdev_suspend = ath10k_wmi_tlv_op_gen_pdev_suspend,
45368c2ecf20Sopenharmony_ci	.gen_pdev_resume = ath10k_wmi_tlv_op_gen_pdev_resume,
45378c2ecf20Sopenharmony_ci	.gen_pdev_set_rd = ath10k_wmi_tlv_op_gen_pdev_set_rd,
45388c2ecf20Sopenharmony_ci	.gen_pdev_set_param = ath10k_wmi_tlv_op_gen_pdev_set_param,
45398c2ecf20Sopenharmony_ci	.gen_init = ath10k_wmi_tlv_op_gen_init,
45408c2ecf20Sopenharmony_ci	.gen_start_scan = ath10k_wmi_tlv_op_gen_start_scan,
45418c2ecf20Sopenharmony_ci	.gen_stop_scan = ath10k_wmi_tlv_op_gen_stop_scan,
45428c2ecf20Sopenharmony_ci	.gen_vdev_create = ath10k_wmi_tlv_op_gen_vdev_create,
45438c2ecf20Sopenharmony_ci	.gen_vdev_delete = ath10k_wmi_tlv_op_gen_vdev_delete,
45448c2ecf20Sopenharmony_ci	.gen_vdev_start = ath10k_wmi_tlv_op_gen_vdev_start,
45458c2ecf20Sopenharmony_ci	.gen_vdev_stop = ath10k_wmi_tlv_op_gen_vdev_stop,
45468c2ecf20Sopenharmony_ci	.gen_vdev_up = ath10k_wmi_tlv_op_gen_vdev_up,
45478c2ecf20Sopenharmony_ci	.gen_vdev_down = ath10k_wmi_tlv_op_gen_vdev_down,
45488c2ecf20Sopenharmony_ci	.gen_vdev_set_param = ath10k_wmi_tlv_op_gen_vdev_set_param,
45498c2ecf20Sopenharmony_ci	.gen_vdev_install_key = ath10k_wmi_tlv_op_gen_vdev_install_key,
45508c2ecf20Sopenharmony_ci	.gen_vdev_wmm_conf = ath10k_wmi_tlv_op_gen_vdev_wmm_conf,
45518c2ecf20Sopenharmony_ci	.gen_peer_create = ath10k_wmi_tlv_op_gen_peer_create,
45528c2ecf20Sopenharmony_ci	.gen_peer_delete = ath10k_wmi_tlv_op_gen_peer_delete,
45538c2ecf20Sopenharmony_ci	.gen_peer_flush = ath10k_wmi_tlv_op_gen_peer_flush,
45548c2ecf20Sopenharmony_ci	.gen_peer_set_param = ath10k_wmi_tlv_op_gen_peer_set_param,
45558c2ecf20Sopenharmony_ci	.gen_peer_assoc = ath10k_wmi_tlv_op_gen_peer_assoc,
45568c2ecf20Sopenharmony_ci	.gen_set_psmode = ath10k_wmi_tlv_op_gen_set_psmode,
45578c2ecf20Sopenharmony_ci	.gen_set_sta_ps = ath10k_wmi_tlv_op_gen_set_sta_ps,
45588c2ecf20Sopenharmony_ci	.gen_set_ap_ps = ath10k_wmi_tlv_op_gen_set_ap_ps,
45598c2ecf20Sopenharmony_ci	.gen_scan_chan_list = ath10k_wmi_tlv_op_gen_scan_chan_list,
45608c2ecf20Sopenharmony_ci	.gen_scan_prob_req_oui = ath10k_wmi_tlv_op_gen_scan_prob_req_oui,
45618c2ecf20Sopenharmony_ci	.gen_beacon_dma = ath10k_wmi_tlv_op_gen_beacon_dma,
45628c2ecf20Sopenharmony_ci	.gen_pdev_set_wmm = ath10k_wmi_tlv_op_gen_pdev_set_wmm,
45638c2ecf20Sopenharmony_ci	.gen_request_stats = ath10k_wmi_tlv_op_gen_request_stats,
45648c2ecf20Sopenharmony_ci	.gen_request_peer_stats_info = ath10k_wmi_tlv_op_gen_request_peer_stats_info,
45658c2ecf20Sopenharmony_ci	.gen_force_fw_hang = ath10k_wmi_tlv_op_gen_force_fw_hang,
45668c2ecf20Sopenharmony_ci	/* .gen_mgmt_tx = not implemented; HTT is used */
45678c2ecf20Sopenharmony_ci	.gen_mgmt_tx_send = ath10k_wmi_tlv_op_gen_mgmt_tx_send,
45688c2ecf20Sopenharmony_ci	.cleanup_mgmt_tx_send = ath10k_wmi_tlv_op_cleanup_mgmt_tx_send,
45698c2ecf20Sopenharmony_ci	.gen_dbglog_cfg = ath10k_wmi_tlv_op_gen_dbglog_cfg,
45708c2ecf20Sopenharmony_ci	.gen_pktlog_enable = ath10k_wmi_tlv_op_gen_pktlog_enable,
45718c2ecf20Sopenharmony_ci	.gen_pktlog_disable = ath10k_wmi_tlv_op_gen_pktlog_disable,
45728c2ecf20Sopenharmony_ci	.gen_pdev_set_quiet_mode = ath10k_wmi_tlv_op_gen_pdev_set_quiet_mode,
45738c2ecf20Sopenharmony_ci	.gen_pdev_get_temperature = ath10k_wmi_tlv_op_gen_pdev_get_temperature,
45748c2ecf20Sopenharmony_ci	/* .gen_addba_clear_resp not implemented */
45758c2ecf20Sopenharmony_ci	/* .gen_addba_send not implemented */
45768c2ecf20Sopenharmony_ci	/* .gen_addba_set_resp not implemented */
45778c2ecf20Sopenharmony_ci	/* .gen_delba_send not implemented */
45788c2ecf20Sopenharmony_ci	.gen_bcn_tmpl = ath10k_wmi_tlv_op_gen_bcn_tmpl,
45798c2ecf20Sopenharmony_ci	.gen_prb_tmpl = ath10k_wmi_tlv_op_gen_prb_tmpl,
45808c2ecf20Sopenharmony_ci	.gen_p2p_go_bcn_ie = ath10k_wmi_tlv_op_gen_p2p_go_bcn_ie,
45818c2ecf20Sopenharmony_ci	.gen_vdev_sta_uapsd = ath10k_wmi_tlv_op_gen_vdev_sta_uapsd,
45828c2ecf20Sopenharmony_ci	.gen_sta_keepalive = ath10k_wmi_tlv_op_gen_sta_keepalive,
45838c2ecf20Sopenharmony_ci	.gen_wow_enable = ath10k_wmi_tlv_op_gen_wow_enable,
45848c2ecf20Sopenharmony_ci	.gen_wow_add_wakeup_event = ath10k_wmi_tlv_op_gen_wow_add_wakeup_event,
45858c2ecf20Sopenharmony_ci	.gen_wow_host_wakeup_ind = ath10k_wmi_tlv_gen_wow_host_wakeup_ind,
45868c2ecf20Sopenharmony_ci	.gen_wow_add_pattern = ath10k_wmi_tlv_op_gen_wow_add_pattern,
45878c2ecf20Sopenharmony_ci	.gen_wow_del_pattern = ath10k_wmi_tlv_op_gen_wow_del_pattern,
45888c2ecf20Sopenharmony_ci	.gen_wow_config_pno = ath10k_wmi_tlv_op_gen_config_pno,
45898c2ecf20Sopenharmony_ci	.gen_update_fw_tdls_state = ath10k_wmi_tlv_op_gen_update_fw_tdls_state,
45908c2ecf20Sopenharmony_ci	.gen_tdls_peer_update = ath10k_wmi_tlv_op_gen_tdls_peer_update,
45918c2ecf20Sopenharmony_ci	.gen_adaptive_qcs = ath10k_wmi_tlv_op_gen_adaptive_qcs,
45928c2ecf20Sopenharmony_ci	.fw_stats_fill = ath10k_wmi_main_op_fw_stats_fill,
45938c2ecf20Sopenharmony_ci	.get_vdev_subtype = ath10k_wmi_tlv_op_get_vdev_subtype,
45948c2ecf20Sopenharmony_ci	.gen_echo = ath10k_wmi_tlv_op_gen_echo,
45958c2ecf20Sopenharmony_ci	.gen_vdev_spectral_conf = ath10k_wmi_tlv_op_gen_vdev_spectral_conf,
45968c2ecf20Sopenharmony_ci	.gen_vdev_spectral_enable = ath10k_wmi_tlv_op_gen_vdev_spectral_enable,
45978c2ecf20Sopenharmony_ci};
45988c2ecf20Sopenharmony_ci
45998c2ecf20Sopenharmony_cistatic const struct wmi_peer_flags_map wmi_tlv_peer_flags_map = {
46008c2ecf20Sopenharmony_ci	.auth = WMI_TLV_PEER_AUTH,
46018c2ecf20Sopenharmony_ci	.qos = WMI_TLV_PEER_QOS,
46028c2ecf20Sopenharmony_ci	.need_ptk_4_way = WMI_TLV_PEER_NEED_PTK_4_WAY,
46038c2ecf20Sopenharmony_ci	.need_gtk_2_way = WMI_TLV_PEER_NEED_GTK_2_WAY,
46048c2ecf20Sopenharmony_ci	.apsd = WMI_TLV_PEER_APSD,
46058c2ecf20Sopenharmony_ci	.ht = WMI_TLV_PEER_HT,
46068c2ecf20Sopenharmony_ci	.bw40 = WMI_TLV_PEER_40MHZ,
46078c2ecf20Sopenharmony_ci	.stbc = WMI_TLV_PEER_STBC,
46088c2ecf20Sopenharmony_ci	.ldbc = WMI_TLV_PEER_LDPC,
46098c2ecf20Sopenharmony_ci	.dyn_mimops = WMI_TLV_PEER_DYN_MIMOPS,
46108c2ecf20Sopenharmony_ci	.static_mimops = WMI_TLV_PEER_STATIC_MIMOPS,
46118c2ecf20Sopenharmony_ci	.spatial_mux = WMI_TLV_PEER_SPATIAL_MUX,
46128c2ecf20Sopenharmony_ci	.vht = WMI_TLV_PEER_VHT,
46138c2ecf20Sopenharmony_ci	.bw80 = WMI_TLV_PEER_80MHZ,
46148c2ecf20Sopenharmony_ci	.pmf = WMI_TLV_PEER_PMF,
46158c2ecf20Sopenharmony_ci	.bw160 = WMI_TLV_PEER_160MHZ,
46168c2ecf20Sopenharmony_ci};
46178c2ecf20Sopenharmony_ci
46188c2ecf20Sopenharmony_ci/************/
46198c2ecf20Sopenharmony_ci/* TLV init */
46208c2ecf20Sopenharmony_ci/************/
46218c2ecf20Sopenharmony_ci
46228c2ecf20Sopenharmony_civoid ath10k_wmi_tlv_attach(struct ath10k *ar)
46238c2ecf20Sopenharmony_ci{
46248c2ecf20Sopenharmony_ci	ar->wmi.cmd = &wmi_tlv_cmd_map;
46258c2ecf20Sopenharmony_ci	ar->wmi.vdev_param = &wmi_tlv_vdev_param_map;
46268c2ecf20Sopenharmony_ci	ar->wmi.pdev_param = &wmi_tlv_pdev_param_map;
46278c2ecf20Sopenharmony_ci	ar->wmi.peer_param = &wmi_tlv_peer_param_map;
46288c2ecf20Sopenharmony_ci	ar->wmi.ops = &wmi_tlv_ops;
46298c2ecf20Sopenharmony_ci	ar->wmi.peer_flags = &wmi_tlv_peer_flags_map;
46308c2ecf20Sopenharmony_ci}
4631