cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

wmi-tlv.c (137040B)


      1// SPDX-License-Identifier: ISC
      2/*
      3 * Copyright (c) 2005-2011 Atheros Communications Inc.
      4 * Copyright (c) 2011-2017 Qualcomm Atheros, Inc.
      5 * Copyright (c) 2018-2019, The Linux Foundation. All rights reserved.
      6 */
      7#include "core.h"
      8#include "debug.h"
      9#include "mac.h"
     10#include "hw.h"
     11#include "wmi.h"
     12#include "wmi-ops.h"
     13#include "wmi-tlv.h"
     14#include "p2p.h"
     15#include "testmode.h"
     16#include <linux/bitfield.h>
     17
     18/***************/
     19/* TLV helpers */
     20/**************/
     21
     22struct wmi_tlv_policy {
     23	size_t min_len;
     24};
     25
     26static const struct wmi_tlv_policy wmi_tlv_policies[] = {
     27	[WMI_TLV_TAG_ARRAY_BYTE]
     28		= { .min_len = 0 },
     29	[WMI_TLV_TAG_ARRAY_UINT32]
     30		= { .min_len = 0 },
     31	[WMI_TLV_TAG_STRUCT_SCAN_EVENT]
     32		= { .min_len = sizeof(struct wmi_scan_event) },
     33	[WMI_TLV_TAG_STRUCT_MGMT_RX_HDR]
     34		= { .min_len = sizeof(struct wmi_tlv_mgmt_rx_ev) },
     35	[WMI_TLV_TAG_STRUCT_CHAN_INFO_EVENT]
     36		= { .min_len = sizeof(struct wmi_chan_info_event) },
     37	[WMI_TLV_TAG_STRUCT_VDEV_START_RESPONSE_EVENT]
     38		= { .min_len = sizeof(struct wmi_vdev_start_response_event) },
     39	[WMI_TLV_TAG_STRUCT_PEER_STA_KICKOUT_EVENT]
     40		= { .min_len = sizeof(struct wmi_peer_sta_kickout_event) },
     41	[WMI_TLV_TAG_STRUCT_HOST_SWBA_EVENT]
     42		= { .min_len = sizeof(struct wmi_host_swba_event) },
     43	[WMI_TLV_TAG_STRUCT_TIM_INFO]
     44		= { .min_len = sizeof(struct wmi_tim_info) },
     45	[WMI_TLV_TAG_STRUCT_P2P_NOA_INFO]
     46		= { .min_len = sizeof(struct wmi_p2p_noa_info) },
     47	[WMI_TLV_TAG_STRUCT_SERVICE_READY_EVENT]
     48		= { .min_len = sizeof(struct wmi_tlv_svc_rdy_ev) },
     49	[WMI_TLV_TAG_STRUCT_HAL_REG_CAPABILITIES]
     50		= { .min_len = sizeof(struct hal_reg_capabilities) },
     51	[WMI_TLV_TAG_STRUCT_WLAN_HOST_MEM_REQ]
     52		= { .min_len = sizeof(struct wlan_host_mem_req) },
     53	[WMI_TLV_TAG_STRUCT_READY_EVENT]
     54		= { .min_len = sizeof(struct wmi_tlv_rdy_ev) },
     55	[WMI_TLV_TAG_STRUCT_OFFLOAD_BCN_TX_STATUS_EVENT]
     56		= { .min_len = sizeof(struct wmi_tlv_bcn_tx_status_ev) },
     57	[WMI_TLV_TAG_STRUCT_DIAG_DATA_CONTAINER_EVENT]
     58		= { .min_len = sizeof(struct wmi_tlv_diag_data_ev) },
     59	[WMI_TLV_TAG_STRUCT_P2P_NOA_EVENT]
     60		= { .min_len = sizeof(struct wmi_tlv_p2p_noa_ev) },
     61	[WMI_TLV_TAG_STRUCT_ROAM_EVENT]
     62		= { .min_len = sizeof(struct wmi_tlv_roam_ev) },
     63	[WMI_TLV_TAG_STRUCT_WOW_EVENT_INFO]
     64		= { .min_len = sizeof(struct wmi_tlv_wow_event_info) },
     65	[WMI_TLV_TAG_STRUCT_TX_PAUSE_EVENT]
     66		= { .min_len = sizeof(struct wmi_tlv_tx_pause_ev) },
     67};
     68
     69static int
     70ath10k_wmi_tlv_iter(struct ath10k *ar, const void *ptr, size_t len,
     71		    int (*iter)(struct ath10k *ar, u16 tag, u16 len,
     72				const void *ptr, void *data),
     73		    void *data)
     74{
     75	const void *begin = ptr;
     76	const struct wmi_tlv *tlv;
     77	u16 tlv_tag, tlv_len;
     78	int ret;
     79
     80	while (len > 0) {
     81		if (len < sizeof(*tlv)) {
     82			ath10k_dbg(ar, ATH10K_DBG_WMI,
     83				   "wmi tlv parse failure at byte %zd (%zu bytes left, %zu expected)\n",
     84				   ptr - begin, len, sizeof(*tlv));
     85			return -EINVAL;
     86		}
     87
     88		tlv = ptr;
     89		tlv_tag = __le16_to_cpu(tlv->tag);
     90		tlv_len = __le16_to_cpu(tlv->len);
     91		ptr += sizeof(*tlv);
     92		len -= sizeof(*tlv);
     93
     94		if (tlv_len > len) {
     95			ath10k_dbg(ar, ATH10K_DBG_WMI,
     96				   "wmi tlv parse failure of tag %u at byte %zd (%zu bytes left, %u expected)\n",
     97				   tlv_tag, ptr - begin, len, tlv_len);
     98			return -EINVAL;
     99		}
    100
    101		if (tlv_tag < ARRAY_SIZE(wmi_tlv_policies) &&
    102		    wmi_tlv_policies[tlv_tag].min_len &&
    103		    wmi_tlv_policies[tlv_tag].min_len > tlv_len) {
    104			ath10k_dbg(ar, ATH10K_DBG_WMI,
    105				   "wmi tlv parse failure of tag %u at byte %zd (%u bytes is less than min length %zu)\n",
    106				   tlv_tag, ptr - begin, tlv_len,
    107				   wmi_tlv_policies[tlv_tag].min_len);
    108			return -EINVAL;
    109		}
    110
    111		ret = iter(ar, tlv_tag, tlv_len, ptr, data);
    112		if (ret)
    113			return ret;
    114
    115		ptr += tlv_len;
    116		len -= tlv_len;
    117	}
    118
    119	return 0;
    120}
    121
    122static int ath10k_wmi_tlv_iter_parse(struct ath10k *ar, u16 tag, u16 len,
    123				     const void *ptr, void *data)
    124{
    125	const void **tb = data;
    126
    127	if (tag < WMI_TLV_TAG_MAX)
    128		tb[tag] = ptr;
    129
    130	return 0;
    131}
    132
    133static int ath10k_wmi_tlv_parse(struct ath10k *ar, const void **tb,
    134				const void *ptr, size_t len)
    135{
    136	return ath10k_wmi_tlv_iter(ar, ptr, len, ath10k_wmi_tlv_iter_parse,
    137				   (void *)tb);
    138}
    139
    140static const void **
    141ath10k_wmi_tlv_parse_alloc(struct ath10k *ar, const void *ptr,
    142			   size_t len, gfp_t gfp)
    143{
    144	const void **tb;
    145	int ret;
    146
    147	tb = kcalloc(WMI_TLV_TAG_MAX, sizeof(*tb), gfp);
    148	if (!tb)
    149		return ERR_PTR(-ENOMEM);
    150
    151	ret = ath10k_wmi_tlv_parse(ar, tb, ptr, len);
    152	if (ret) {
    153		kfree(tb);
    154		return ERR_PTR(ret);
    155	}
    156
    157	return tb;
    158}
    159
    160static u16 ath10k_wmi_tlv_len(const void *ptr)
    161{
    162	return __le16_to_cpu((((const struct wmi_tlv *)ptr) - 1)->len);
    163}
    164
    165/**************/
    166/* TLV events */
    167/**************/
    168static int ath10k_wmi_tlv_event_bcn_tx_status(struct ath10k *ar,
    169					      struct sk_buff *skb)
    170{
    171	const void **tb;
    172	const struct wmi_tlv_bcn_tx_status_ev *ev;
    173	struct ath10k_vif *arvif;
    174	u32 vdev_id, tx_status;
    175	int ret;
    176
    177	tb = ath10k_wmi_tlv_parse_alloc(ar, skb->data, skb->len, GFP_ATOMIC);
    178	if (IS_ERR(tb)) {
    179		ret = PTR_ERR(tb);
    180		ath10k_warn(ar, "failed to parse tlv: %d\n", ret);
    181		return ret;
    182	}
    183
    184	ev = tb[WMI_TLV_TAG_STRUCT_OFFLOAD_BCN_TX_STATUS_EVENT];
    185	if (!ev) {
    186		kfree(tb);
    187		return -EPROTO;
    188	}
    189
    190	tx_status = __le32_to_cpu(ev->tx_status);
    191	vdev_id = __le32_to_cpu(ev->vdev_id);
    192
    193	switch (tx_status) {
    194	case WMI_TLV_BCN_TX_STATUS_OK:
    195		break;
    196	case WMI_TLV_BCN_TX_STATUS_XRETRY:
    197	case WMI_TLV_BCN_TX_STATUS_DROP:
    198	case WMI_TLV_BCN_TX_STATUS_FILTERED:
    199		/* FIXME: It's probably worth telling mac80211 to stop the
    200		 * interface as it is crippled.
    201		 */
    202		ath10k_warn(ar, "received bcn tmpl tx status on vdev %i: %d",
    203			    vdev_id, tx_status);
    204		break;
    205	}
    206
    207	arvif = ath10k_get_arvif(ar, vdev_id);
    208	if (arvif && arvif->is_up && arvif->vif->csa_active)
    209		ieee80211_queue_work(ar->hw, &arvif->ap_csa_work);
    210
    211	kfree(tb);
    212	return 0;
    213}
    214
    215static void ath10k_wmi_tlv_event_vdev_delete_resp(struct ath10k *ar,
    216						  struct sk_buff *skb)
    217{
    218	ath10k_dbg(ar, ATH10K_DBG_WMI, "WMI_VDEV_DELETE_RESP_EVENTID\n");
    219	complete(&ar->vdev_delete_done);
    220}
    221
    222static int ath10k_wmi_tlv_parse_peer_stats_info(struct ath10k *ar, u16 tag, u16 len,
    223						const void *ptr, void *data)
    224{
    225	const struct wmi_tlv_peer_stats_info *stat = ptr;
    226	struct ieee80211_sta *sta;
    227	struct ath10k_sta *arsta;
    228
    229	if (tag != WMI_TLV_TAG_STRUCT_PEER_STATS_INFO)
    230		return -EPROTO;
    231
    232	ath10k_dbg(ar, ATH10K_DBG_WMI,
    233		   "wmi tlv stats peer addr %pMF rx rate code 0x%x bit rate %d kbps\n",
    234		   stat->peer_macaddr.addr,
    235		   __le32_to_cpu(stat->last_rx_rate_code),
    236		   __le32_to_cpu(stat->last_rx_bitrate_kbps));
    237
    238	ath10k_dbg(ar, ATH10K_DBG_WMI,
    239		   "wmi tlv stats tx rate code 0x%x bit rate %d kbps\n",
    240		   __le32_to_cpu(stat->last_tx_rate_code),
    241		   __le32_to_cpu(stat->last_tx_bitrate_kbps));
    242
    243	rcu_read_lock();
    244	sta = ieee80211_find_sta_by_ifaddr(ar->hw, stat->peer_macaddr.addr, NULL);
    245	if (!sta) {
    246		rcu_read_unlock();
    247		ath10k_warn(ar, "not found station for peer stats\n");
    248		return -EINVAL;
    249	}
    250
    251	arsta = (struct ath10k_sta *)sta->drv_priv;
    252	arsta->rx_rate_code = __le32_to_cpu(stat->last_rx_rate_code);
    253	arsta->rx_bitrate_kbps = __le32_to_cpu(stat->last_rx_bitrate_kbps);
    254	arsta->tx_rate_code = __le32_to_cpu(stat->last_tx_rate_code);
    255	arsta->tx_bitrate_kbps = __le32_to_cpu(stat->last_tx_bitrate_kbps);
    256	rcu_read_unlock();
    257
    258	return 0;
    259}
    260
    261static int ath10k_wmi_tlv_op_pull_peer_stats_info(struct ath10k *ar,
    262						  struct sk_buff *skb)
    263{
    264	const void **tb;
    265	const struct wmi_tlv_peer_stats_info_ev *ev;
    266	const void *data;
    267	u32 num_peer_stats;
    268	int ret;
    269
    270	tb = ath10k_wmi_tlv_parse_alloc(ar, skb->data, skb->len, GFP_ATOMIC);
    271	if (IS_ERR(tb)) {
    272		ret = PTR_ERR(tb);
    273		ath10k_warn(ar, "failed to parse tlv: %d\n", ret);
    274		return ret;
    275	}
    276
    277	ev = tb[WMI_TLV_TAG_STRUCT_PEER_STATS_INFO_EVENT];
    278	data = tb[WMI_TLV_TAG_ARRAY_STRUCT];
    279
    280	if (!ev || !data) {
    281		kfree(tb);
    282		return -EPROTO;
    283	}
    284
    285	num_peer_stats = __le32_to_cpu(ev->num_peers);
    286
    287	ath10k_dbg(ar, ATH10K_DBG_WMI,
    288		   "wmi tlv peer stats info update peer vdev id %d peers %i more data %d\n",
    289		   __le32_to_cpu(ev->vdev_id),
    290		   num_peer_stats,
    291		   __le32_to_cpu(ev->more_data));
    292
    293	ret = ath10k_wmi_tlv_iter(ar, data, ath10k_wmi_tlv_len(data),
    294				  ath10k_wmi_tlv_parse_peer_stats_info, NULL);
    295	if (ret)
    296		ath10k_warn(ar, "failed to parse stats info tlv: %d\n", ret);
    297
    298	kfree(tb);
    299	return 0;
    300}
    301
    302static void ath10k_wmi_tlv_event_peer_stats_info(struct ath10k *ar,
    303						 struct sk_buff *skb)
    304{
    305	ath10k_dbg(ar, ATH10K_DBG_WMI, "WMI_PEER_STATS_INFO_EVENTID\n");
    306	ath10k_wmi_tlv_op_pull_peer_stats_info(ar, skb);
    307	complete(&ar->peer_stats_info_complete);
    308}
    309
    310static int ath10k_wmi_tlv_event_diag_data(struct ath10k *ar,
    311					  struct sk_buff *skb)
    312{
    313	const void **tb;
    314	const struct wmi_tlv_diag_data_ev *ev;
    315	const struct wmi_tlv_diag_item *item;
    316	const void *data;
    317	int ret, num_items, len;
    318
    319	tb = ath10k_wmi_tlv_parse_alloc(ar, skb->data, skb->len, GFP_ATOMIC);
    320	if (IS_ERR(tb)) {
    321		ret = PTR_ERR(tb);
    322		ath10k_warn(ar, "failed to parse tlv: %d\n", ret);
    323		return ret;
    324	}
    325
    326	ev = tb[WMI_TLV_TAG_STRUCT_DIAG_DATA_CONTAINER_EVENT];
    327	data = tb[WMI_TLV_TAG_ARRAY_BYTE];
    328	if (!ev || !data) {
    329		kfree(tb);
    330		return -EPROTO;
    331	}
    332
    333	num_items = __le32_to_cpu(ev->num_items);
    334	len = ath10k_wmi_tlv_len(data);
    335
    336	while (num_items--) {
    337		if (len == 0)
    338			break;
    339		if (len < sizeof(*item)) {
    340			ath10k_warn(ar, "failed to parse diag data: can't fit item header\n");
    341			break;
    342		}
    343
    344		item = data;
    345
    346		if (len < sizeof(*item) + __le16_to_cpu(item->len)) {
    347			ath10k_warn(ar, "failed to parse diag data: item is too long\n");
    348			break;
    349		}
    350
    351		trace_ath10k_wmi_diag_container(ar,
    352						item->type,
    353						__le32_to_cpu(item->timestamp),
    354						__le32_to_cpu(item->code),
    355						__le16_to_cpu(item->len),
    356						item->payload);
    357
    358		len -= sizeof(*item);
    359		len -= roundup(__le16_to_cpu(item->len), 4);
    360
    361		data += sizeof(*item);
    362		data += roundup(__le16_to_cpu(item->len), 4);
    363	}
    364
    365	if (num_items != -1 || len != 0)
    366		ath10k_warn(ar, "failed to parse diag data event: num_items %d len %d\n",
    367			    num_items, len);
    368
    369	kfree(tb);
    370	return 0;
    371}
    372
    373static int ath10k_wmi_tlv_event_diag(struct ath10k *ar,
    374				     struct sk_buff *skb)
    375{
    376	const void **tb;
    377	const void *data;
    378	int ret, len;
    379
    380	tb = ath10k_wmi_tlv_parse_alloc(ar, skb->data, skb->len, GFP_ATOMIC);
    381	if (IS_ERR(tb)) {
    382		ret = PTR_ERR(tb);
    383		ath10k_warn(ar, "failed to parse tlv: %d\n", ret);
    384		return ret;
    385	}
    386
    387	data = tb[WMI_TLV_TAG_ARRAY_BYTE];
    388	if (!data) {
    389		kfree(tb);
    390		return -EPROTO;
    391	}
    392	len = ath10k_wmi_tlv_len(data);
    393
    394	ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv diag event len %d\n", len);
    395	trace_ath10k_wmi_diag(ar, data, len);
    396
    397	kfree(tb);
    398	return 0;
    399}
    400
    401static int ath10k_wmi_tlv_event_p2p_noa(struct ath10k *ar,
    402					struct sk_buff *skb)
    403{
    404	const void **tb;
    405	const struct wmi_tlv_p2p_noa_ev *ev;
    406	const struct wmi_p2p_noa_info *noa;
    407	int ret, vdev_id;
    408
    409	tb = ath10k_wmi_tlv_parse_alloc(ar, skb->data, skb->len, GFP_ATOMIC);
    410	if (IS_ERR(tb)) {
    411		ret = PTR_ERR(tb);
    412		ath10k_warn(ar, "failed to parse tlv: %d\n", ret);
    413		return ret;
    414	}
    415
    416	ev = tb[WMI_TLV_TAG_STRUCT_P2P_NOA_EVENT];
    417	noa = tb[WMI_TLV_TAG_STRUCT_P2P_NOA_INFO];
    418
    419	if (!ev || !noa) {
    420		kfree(tb);
    421		return -EPROTO;
    422	}
    423
    424	vdev_id = __le32_to_cpu(ev->vdev_id);
    425
    426	ath10k_dbg(ar, ATH10K_DBG_WMI,
    427		   "wmi tlv p2p noa vdev_id %i descriptors %u\n",
    428		   vdev_id, noa->num_descriptors);
    429
    430	ath10k_p2p_noa_update_by_vdev_id(ar, vdev_id, noa);
    431	kfree(tb);
    432	return 0;
    433}
    434
    435static int ath10k_wmi_tlv_event_tx_pause(struct ath10k *ar,
    436					 struct sk_buff *skb)
    437{
    438	const void **tb;
    439	const struct wmi_tlv_tx_pause_ev *ev;
    440	int ret, vdev_id;
    441	u32 pause_id, action, vdev_map, peer_id, tid_map;
    442
    443	tb = ath10k_wmi_tlv_parse_alloc(ar, skb->data, skb->len, GFP_ATOMIC);
    444	if (IS_ERR(tb)) {
    445		ret = PTR_ERR(tb);
    446		ath10k_warn(ar, "failed to parse tlv: %d\n", ret);
    447		return ret;
    448	}
    449
    450	ev = tb[WMI_TLV_TAG_STRUCT_TX_PAUSE_EVENT];
    451	if (!ev) {
    452		kfree(tb);
    453		return -EPROTO;
    454	}
    455
    456	pause_id = __le32_to_cpu(ev->pause_id);
    457	action = __le32_to_cpu(ev->action);
    458	vdev_map = __le32_to_cpu(ev->vdev_map);
    459	peer_id = __le32_to_cpu(ev->peer_id);
    460	tid_map = __le32_to_cpu(ev->tid_map);
    461
    462	ath10k_dbg(ar, ATH10K_DBG_WMI,
    463		   "wmi tlv tx pause pause_id %u action %u vdev_map 0x%08x peer_id %u tid_map 0x%08x\n",
    464		   pause_id, action, vdev_map, peer_id, tid_map);
    465
    466	switch (pause_id) {
    467	case WMI_TLV_TX_PAUSE_ID_MCC:
    468	case WMI_TLV_TX_PAUSE_ID_P2P_CLI_NOA:
    469	case WMI_TLV_TX_PAUSE_ID_P2P_GO_PS:
    470	case WMI_TLV_TX_PAUSE_ID_AP_PS:
    471	case WMI_TLV_TX_PAUSE_ID_IBSS_PS:
    472		for (vdev_id = 0; vdev_map; vdev_id++) {
    473			if (!(vdev_map & BIT(vdev_id)))
    474				continue;
    475
    476			vdev_map &= ~BIT(vdev_id);
    477			ath10k_mac_handle_tx_pause_vdev(ar, vdev_id, pause_id,
    478							action);
    479		}
    480		break;
    481	case WMI_TLV_TX_PAUSE_ID_AP_PEER_PS:
    482	case WMI_TLV_TX_PAUSE_ID_AP_PEER_UAPSD:
    483	case WMI_TLV_TX_PAUSE_ID_STA_ADD_BA:
    484	case WMI_TLV_TX_PAUSE_ID_HOST:
    485		ath10k_dbg(ar, ATH10K_DBG_MAC,
    486			   "mac ignoring unsupported tx pause id %d\n",
    487			   pause_id);
    488		break;
    489	default:
    490		ath10k_dbg(ar, ATH10K_DBG_MAC,
    491			   "mac ignoring unknown tx pause vdev %d\n",
    492			   pause_id);
    493		break;
    494	}
    495
    496	kfree(tb);
    497	return 0;
    498}
    499
    500static void ath10k_wmi_tlv_event_rfkill_state_change(struct ath10k *ar,
    501						     struct sk_buff *skb)
    502{
    503	const struct wmi_tlv_rfkill_state_change_ev *ev;
    504	const void **tb;
    505	bool radio;
    506	int ret;
    507
    508	tb = ath10k_wmi_tlv_parse_alloc(ar, skb->data, skb->len, GFP_ATOMIC);
    509	if (IS_ERR(tb)) {
    510		ret = PTR_ERR(tb);
    511		ath10k_warn(ar,
    512			    "failed to parse rfkill state change event: %d\n",
    513			    ret);
    514		return;
    515	}
    516
    517	ev = tb[WMI_TLV_TAG_STRUCT_RFKILL_EVENT];
    518	if (!ev) {
    519		kfree(tb);
    520		return;
    521	}
    522
    523	ath10k_dbg(ar, ATH10K_DBG_MAC,
    524		   "wmi tlv rfkill state change gpio %d type %d radio_state %d\n",
    525		   __le32_to_cpu(ev->gpio_pin_num),
    526		   __le32_to_cpu(ev->int_type),
    527		   __le32_to_cpu(ev->radio_state));
    528
    529	radio = (__le32_to_cpu(ev->radio_state) == WMI_TLV_RFKILL_RADIO_STATE_ON);
    530
    531	spin_lock_bh(&ar->data_lock);
    532
    533	if (!radio)
    534		ar->hw_rfkill_on = true;
    535
    536	spin_unlock_bh(&ar->data_lock);
    537
    538	/* notify cfg80211 radio state change */
    539	ath10k_mac_rfkill_enable_radio(ar, radio);
    540	wiphy_rfkill_set_hw_state(ar->hw->wiphy, !radio);
    541}
    542
    543static int ath10k_wmi_tlv_event_temperature(struct ath10k *ar,
    544					    struct sk_buff *skb)
    545{
    546	const struct wmi_tlv_pdev_temperature_event *ev;
    547
    548	ev = (struct wmi_tlv_pdev_temperature_event *)skb->data;
    549	if (WARN_ON(skb->len < sizeof(*ev)))
    550		return -EPROTO;
    551
    552	ath10k_thermal_event_temperature(ar, __le32_to_cpu(ev->temperature));
    553	return 0;
    554}
    555
    556static void ath10k_wmi_event_tdls_peer(struct ath10k *ar, struct sk_buff *skb)
    557{
    558	struct ieee80211_sta *station;
    559	const struct wmi_tlv_tdls_peer_event *ev;
    560	const void **tb;
    561	struct ath10k_vif *arvif;
    562
    563	tb = ath10k_wmi_tlv_parse_alloc(ar, skb->data, skb->len, GFP_ATOMIC);
    564	if (IS_ERR(tb)) {
    565		ath10k_warn(ar, "tdls peer failed to parse tlv");
    566		return;
    567	}
    568	ev = tb[WMI_TLV_TAG_STRUCT_TDLS_PEER_EVENT];
    569	if (!ev) {
    570		kfree(tb);
    571		ath10k_warn(ar, "tdls peer NULL event");
    572		return;
    573	}
    574
    575	switch (__le32_to_cpu(ev->peer_reason)) {
    576	case WMI_TDLS_TEARDOWN_REASON_TX:
    577	case WMI_TDLS_TEARDOWN_REASON_RSSI:
    578	case WMI_TDLS_TEARDOWN_REASON_PTR_TIMEOUT:
    579		rcu_read_lock();
    580		station = ieee80211_find_sta_by_ifaddr(ar->hw,
    581						       ev->peer_macaddr.addr,
    582						       NULL);
    583		if (!station) {
    584			ath10k_warn(ar, "did not find station from tdls peer event");
    585			goto exit;
    586		}
    587		arvif = ath10k_get_arvif(ar, __le32_to_cpu(ev->vdev_id));
    588		ieee80211_tdls_oper_request(
    589					arvif->vif, station->addr,
    590					NL80211_TDLS_TEARDOWN,
    591					WLAN_REASON_TDLS_TEARDOWN_UNREACHABLE,
    592					GFP_ATOMIC
    593					);
    594		break;
    595	default:
    596		kfree(tb);
    597		return;
    598	}
    599
    600exit:
    601	rcu_read_unlock();
    602	kfree(tb);
    603}
    604
    605static int ath10k_wmi_tlv_event_peer_delete_resp(struct ath10k *ar,
    606						 struct sk_buff *skb)
    607{
    608	struct wmi_peer_delete_resp_ev_arg *arg;
    609	struct wmi_tlv *tlv_hdr;
    610
    611	tlv_hdr = (struct wmi_tlv *)skb->data;
    612	arg = (struct wmi_peer_delete_resp_ev_arg *)tlv_hdr->value;
    613
    614	ath10k_dbg(ar, ATH10K_DBG_WMI, "vdev id %d", arg->vdev_id);
    615	ath10k_dbg(ar, ATH10K_DBG_WMI, "peer mac addr %pM", &arg->peer_addr);
    616	ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv peer delete response\n");
    617
    618	complete(&ar->peer_delete_done);
    619
    620	return 0;
    621}
    622
    623/***********/
    624/* TLV ops */
    625/***********/
    626
    627static void ath10k_wmi_tlv_op_rx(struct ath10k *ar, struct sk_buff *skb)
    628{
    629	struct wmi_cmd_hdr *cmd_hdr;
    630	enum wmi_tlv_event_id id;
    631	bool consumed;
    632
    633	cmd_hdr = (struct wmi_cmd_hdr *)skb->data;
    634	id = MS(__le32_to_cpu(cmd_hdr->cmd_id), WMI_CMD_HDR_CMD_ID);
    635
    636	if (skb_pull(skb, sizeof(struct wmi_cmd_hdr)) == NULL)
    637		goto out;
    638
    639	trace_ath10k_wmi_event(ar, id, skb->data, skb->len);
    640
    641	consumed = ath10k_tm_event_wmi(ar, id, skb);
    642
    643	/* Ready event must be handled normally also in UTF mode so that we
    644	 * know the UTF firmware has booted, others we are just bypass WMI
    645	 * events to testmode.
    646	 */
    647	if (consumed && id != WMI_TLV_READY_EVENTID) {
    648		ath10k_dbg(ar, ATH10K_DBG_WMI,
    649			   "wmi tlv testmode consumed 0x%x\n", id);
    650		goto out;
    651	}
    652
    653	switch (id) {
    654	case WMI_TLV_MGMT_RX_EVENTID:
    655		ath10k_wmi_event_mgmt_rx(ar, skb);
    656		/* mgmt_rx() owns the skb now! */
    657		return;
    658	case WMI_TLV_SCAN_EVENTID:
    659		ath10k_wmi_event_scan(ar, skb);
    660		break;
    661	case WMI_TLV_CHAN_INFO_EVENTID:
    662		ath10k_wmi_event_chan_info(ar, skb);
    663		break;
    664	case WMI_TLV_ECHO_EVENTID:
    665		ath10k_wmi_event_echo(ar, skb);
    666		break;
    667	case WMI_TLV_DEBUG_MESG_EVENTID:
    668		ath10k_wmi_event_debug_mesg(ar, skb);
    669		break;
    670	case WMI_TLV_UPDATE_STATS_EVENTID:
    671		ath10k_wmi_event_update_stats(ar, skb);
    672		break;
    673	case WMI_TLV_PEER_STATS_INFO_EVENTID:
    674		ath10k_wmi_tlv_event_peer_stats_info(ar, skb);
    675		break;
    676	case WMI_TLV_VDEV_START_RESP_EVENTID:
    677		ath10k_wmi_event_vdev_start_resp(ar, skb);
    678		break;
    679	case WMI_TLV_VDEV_STOPPED_EVENTID:
    680		ath10k_wmi_event_vdev_stopped(ar, skb);
    681		break;
    682	case WMI_TLV_VDEV_DELETE_RESP_EVENTID:
    683		ath10k_wmi_tlv_event_vdev_delete_resp(ar, skb);
    684		break;
    685	case WMI_TLV_PEER_STA_KICKOUT_EVENTID:
    686		ath10k_wmi_event_peer_sta_kickout(ar, skb);
    687		break;
    688	case WMI_TLV_HOST_SWBA_EVENTID:
    689		ath10k_wmi_event_host_swba(ar, skb);
    690		break;
    691	case WMI_TLV_TBTTOFFSET_UPDATE_EVENTID:
    692		ath10k_wmi_event_tbttoffset_update(ar, skb);
    693		break;
    694	case WMI_TLV_PHYERR_EVENTID:
    695		ath10k_wmi_event_phyerr(ar, skb);
    696		break;
    697	case WMI_TLV_ROAM_EVENTID:
    698		ath10k_wmi_event_roam(ar, skb);
    699		break;
    700	case WMI_TLV_PROFILE_MATCH:
    701		ath10k_wmi_event_profile_match(ar, skb);
    702		break;
    703	case WMI_TLV_DEBUG_PRINT_EVENTID:
    704		ath10k_wmi_event_debug_print(ar, skb);
    705		break;
    706	case WMI_TLV_PDEV_QVIT_EVENTID:
    707		ath10k_wmi_event_pdev_qvit(ar, skb);
    708		break;
    709	case WMI_TLV_WLAN_PROFILE_DATA_EVENTID:
    710		ath10k_wmi_event_wlan_profile_data(ar, skb);
    711		break;
    712	case WMI_TLV_RTT_MEASUREMENT_REPORT_EVENTID:
    713		ath10k_wmi_event_rtt_measurement_report(ar, skb);
    714		break;
    715	case WMI_TLV_TSF_MEASUREMENT_REPORT_EVENTID:
    716		ath10k_wmi_event_tsf_measurement_report(ar, skb);
    717		break;
    718	case WMI_TLV_RTT_ERROR_REPORT_EVENTID:
    719		ath10k_wmi_event_rtt_error_report(ar, skb);
    720		break;
    721	case WMI_TLV_WOW_WAKEUP_HOST_EVENTID:
    722		ath10k_wmi_event_wow_wakeup_host(ar, skb);
    723		break;
    724	case WMI_TLV_DCS_INTERFERENCE_EVENTID:
    725		ath10k_wmi_event_dcs_interference(ar, skb);
    726		break;
    727	case WMI_TLV_PDEV_TPC_CONFIG_EVENTID:
    728		ath10k_wmi_event_pdev_tpc_config(ar, skb);
    729		break;
    730	case WMI_TLV_PDEV_FTM_INTG_EVENTID:
    731		ath10k_wmi_event_pdev_ftm_intg(ar, skb);
    732		break;
    733	case WMI_TLV_GTK_OFFLOAD_STATUS_EVENTID:
    734		ath10k_wmi_event_gtk_offload_status(ar, skb);
    735		break;
    736	case WMI_TLV_GTK_REKEY_FAIL_EVENTID:
    737		ath10k_wmi_event_gtk_rekey_fail(ar, skb);
    738		break;
    739	case WMI_TLV_TX_DELBA_COMPLETE_EVENTID:
    740		ath10k_wmi_event_delba_complete(ar, skb);
    741		break;
    742	case WMI_TLV_TX_ADDBA_COMPLETE_EVENTID:
    743		ath10k_wmi_event_addba_complete(ar, skb);
    744		break;
    745	case WMI_TLV_VDEV_INSTALL_KEY_COMPLETE_EVENTID:
    746		ath10k_wmi_event_vdev_install_key_complete(ar, skb);
    747		break;
    748	case WMI_TLV_SERVICE_READY_EVENTID:
    749		ath10k_wmi_event_service_ready(ar, skb);
    750		return;
    751	case WMI_TLV_READY_EVENTID:
    752		ath10k_wmi_event_ready(ar, skb);
    753		break;
    754	case WMI_TLV_SERVICE_AVAILABLE_EVENTID:
    755		ath10k_wmi_event_service_available(ar, skb);
    756		break;
    757	case WMI_TLV_OFFLOAD_BCN_TX_STATUS_EVENTID:
    758		ath10k_wmi_tlv_event_bcn_tx_status(ar, skb);
    759		break;
    760	case WMI_TLV_DIAG_DATA_CONTAINER_EVENTID:
    761		ath10k_wmi_tlv_event_diag_data(ar, skb);
    762		break;
    763	case WMI_TLV_DIAG_EVENTID:
    764		ath10k_wmi_tlv_event_diag(ar, skb);
    765		break;
    766	case WMI_TLV_P2P_NOA_EVENTID:
    767		ath10k_wmi_tlv_event_p2p_noa(ar, skb);
    768		break;
    769	case WMI_TLV_TX_PAUSE_EVENTID:
    770		ath10k_wmi_tlv_event_tx_pause(ar, skb);
    771		break;
    772	case WMI_TLV_RFKILL_STATE_CHANGE_EVENTID:
    773		ath10k_wmi_tlv_event_rfkill_state_change(ar, skb);
    774		break;
    775	case WMI_TLV_PDEV_TEMPERATURE_EVENTID:
    776		ath10k_wmi_tlv_event_temperature(ar, skb);
    777		break;
    778	case WMI_TLV_TDLS_PEER_EVENTID:
    779		ath10k_wmi_event_tdls_peer(ar, skb);
    780		break;
    781	case WMI_TLV_PEER_DELETE_RESP_EVENTID:
    782		ath10k_wmi_tlv_event_peer_delete_resp(ar, skb);
    783		break;
    784	case WMI_TLV_MGMT_TX_COMPLETION_EVENTID:
    785		ath10k_wmi_event_mgmt_tx_compl(ar, skb);
    786		break;
    787	case WMI_TLV_MGMT_TX_BUNDLE_COMPLETION_EVENTID:
    788		ath10k_wmi_event_mgmt_tx_bundle_compl(ar, skb);
    789		break;
    790	default:
    791		ath10k_dbg(ar, ATH10K_DBG_WMI, "Unknown eventid: %d\n", id);
    792		break;
    793	}
    794
    795out:
    796	dev_kfree_skb(skb);
    797}
    798
    799static int ath10k_wmi_tlv_op_pull_scan_ev(struct ath10k *ar,
    800					  struct sk_buff *skb,
    801					  struct wmi_scan_ev_arg *arg)
    802{
    803	const void **tb;
    804	const struct wmi_scan_event *ev;
    805	int ret;
    806
    807	tb = ath10k_wmi_tlv_parse_alloc(ar, skb->data, skb->len, GFP_ATOMIC);
    808	if (IS_ERR(tb)) {
    809		ret = PTR_ERR(tb);
    810		ath10k_warn(ar, "failed to parse tlv: %d\n", ret);
    811		return ret;
    812	}
    813
    814	ev = tb[WMI_TLV_TAG_STRUCT_SCAN_EVENT];
    815	if (!ev) {
    816		kfree(tb);
    817		return -EPROTO;
    818	}
    819
    820	arg->event_type = ev->event_type;
    821	arg->reason = ev->reason;
    822	arg->channel_freq = ev->channel_freq;
    823	arg->scan_req_id = ev->scan_req_id;
    824	arg->scan_id = ev->scan_id;
    825	arg->vdev_id = ev->vdev_id;
    826
    827	kfree(tb);
    828	return 0;
    829}
    830
    831static int
    832ath10k_wmi_tlv_op_pull_mgmt_tx_compl_ev(struct ath10k *ar, struct sk_buff *skb,
    833					struct wmi_tlv_mgmt_tx_compl_ev_arg *arg)
    834{
    835	const void **tb;
    836	const struct wmi_tlv_mgmt_tx_compl_ev *ev;
    837	int ret;
    838
    839	tb = ath10k_wmi_tlv_parse_alloc(ar, skb->data, skb->len, GFP_ATOMIC);
    840	if (IS_ERR(tb)) {
    841		ret = PTR_ERR(tb);
    842		ath10k_warn(ar, "failed to parse tlv: %d\n", ret);
    843		return ret;
    844	}
    845
    846	ev = tb[WMI_TLV_TAG_STRUCT_MGMT_TX_COMPL_EVENT];
    847
    848	arg->desc_id = ev->desc_id;
    849	arg->status = ev->status;
    850	arg->pdev_id = ev->pdev_id;
    851	arg->ppdu_id = ev->ppdu_id;
    852
    853	if (test_bit(WMI_SERVICE_TX_DATA_ACK_RSSI, ar->wmi.svc_map))
    854		arg->ack_rssi = ev->ack_rssi;
    855
    856	kfree(tb);
    857	return 0;
    858}
    859
    860struct wmi_tlv_tx_bundle_compl_parse {
    861	const __le32 *num_reports;
    862	const __le32 *desc_ids;
    863	const __le32 *status;
    864	const __le32 *ppdu_ids;
    865	const __le32 *ack_rssi;
    866	bool desc_ids_done;
    867	bool status_done;
    868	bool ppdu_ids_done;
    869	bool ack_rssi_done;
    870};
    871
    872static int
    873ath10k_wmi_tlv_mgmt_tx_bundle_compl_parse(struct ath10k *ar, u16 tag, u16 len,
    874					  const void *ptr, void *data)
    875{
    876	struct wmi_tlv_tx_bundle_compl_parse *bundle_tx_compl = data;
    877
    878	switch (tag) {
    879	case WMI_TLV_TAG_STRUCT_MGMT_TX_COMPL_BUNDLE_EVENT:
    880		bundle_tx_compl->num_reports = ptr;
    881		break;
    882	case WMI_TLV_TAG_ARRAY_UINT32:
    883		if (!bundle_tx_compl->desc_ids_done) {
    884			bundle_tx_compl->desc_ids_done = true;
    885			bundle_tx_compl->desc_ids = ptr;
    886		} else if (!bundle_tx_compl->status_done) {
    887			bundle_tx_compl->status_done = true;
    888			bundle_tx_compl->status = ptr;
    889		} else if (!bundle_tx_compl->ppdu_ids_done) {
    890			bundle_tx_compl->ppdu_ids_done = true;
    891			bundle_tx_compl->ppdu_ids = ptr;
    892		} else if (!bundle_tx_compl->ack_rssi_done) {
    893			bundle_tx_compl->ack_rssi_done = true;
    894			bundle_tx_compl->ack_rssi = ptr;
    895		}
    896		break;
    897	default:
    898		break;
    899	}
    900	return 0;
    901}
    902
    903static int ath10k_wmi_tlv_op_pull_mgmt_tx_bundle_compl_ev(
    904				struct ath10k *ar, struct sk_buff *skb,
    905				struct wmi_tlv_mgmt_tx_bundle_compl_ev_arg *arg)
    906{
    907	struct wmi_tlv_tx_bundle_compl_parse bundle_tx_compl = { };
    908	int ret;
    909
    910	ret = ath10k_wmi_tlv_iter(ar, skb->data, skb->len,
    911				  ath10k_wmi_tlv_mgmt_tx_bundle_compl_parse,
    912				  &bundle_tx_compl);
    913	if (ret) {
    914		ath10k_warn(ar, "failed to parse tlv: %d\n", ret);
    915		return ret;
    916	}
    917
    918	if (!bundle_tx_compl.num_reports || !bundle_tx_compl.desc_ids ||
    919	    !bundle_tx_compl.status)
    920		return -EPROTO;
    921
    922	arg->num_reports = *bundle_tx_compl.num_reports;
    923	arg->desc_ids = bundle_tx_compl.desc_ids;
    924	arg->status = bundle_tx_compl.status;
    925	arg->ppdu_ids = bundle_tx_compl.ppdu_ids;
    926
    927	if (test_bit(WMI_SERVICE_TX_DATA_ACK_RSSI, ar->wmi.svc_map))
    928		arg->ack_rssi = bundle_tx_compl.ack_rssi;
    929
    930	return 0;
    931}
    932
    933static int ath10k_wmi_tlv_op_pull_mgmt_rx_ev(struct ath10k *ar,
    934					     struct sk_buff *skb,
    935					     struct wmi_mgmt_rx_ev_arg *arg)
    936{
    937	const void **tb;
    938	const struct wmi_tlv_mgmt_rx_ev *ev;
    939	const u8 *frame;
    940	u32 msdu_len;
    941	int ret, i;
    942
    943	tb = ath10k_wmi_tlv_parse_alloc(ar, skb->data, skb->len, GFP_ATOMIC);
    944	if (IS_ERR(tb)) {
    945		ret = PTR_ERR(tb);
    946		ath10k_warn(ar, "failed to parse tlv: %d\n", ret);
    947		return ret;
    948	}
    949
    950	ev = tb[WMI_TLV_TAG_STRUCT_MGMT_RX_HDR];
    951	frame = tb[WMI_TLV_TAG_ARRAY_BYTE];
    952
    953	if (!ev || !frame) {
    954		kfree(tb);
    955		return -EPROTO;
    956	}
    957
    958	arg->channel = ev->channel;
    959	arg->buf_len = ev->buf_len;
    960	arg->status = ev->status;
    961	arg->snr = ev->snr;
    962	arg->phy_mode = ev->phy_mode;
    963	arg->rate = ev->rate;
    964
    965	for (i = 0; i < ARRAY_SIZE(ev->rssi); i++)
    966		arg->rssi[i] = ev->rssi[i];
    967
    968	msdu_len = __le32_to_cpu(arg->buf_len);
    969
    970	if (skb->len < (frame - skb->data) + msdu_len) {
    971		kfree(tb);
    972		return -EPROTO;
    973	}
    974
    975	/* shift the sk_buff to point to `frame` */
    976	skb_trim(skb, 0);
    977	skb_put(skb, frame - skb->data);
    978	skb_pull(skb, frame - skb->data);
    979	skb_put(skb, msdu_len);
    980
    981	kfree(tb);
    982	return 0;
    983}
    984
    985static int ath10k_wmi_tlv_op_pull_ch_info_ev(struct ath10k *ar,
    986					     struct sk_buff *skb,
    987					     struct wmi_ch_info_ev_arg *arg)
    988{
    989	const void **tb;
    990	const struct wmi_tlv_chan_info_event *ev;
    991	int ret;
    992
    993	tb = ath10k_wmi_tlv_parse_alloc(ar, skb->data, skb->len, GFP_ATOMIC);
    994	if (IS_ERR(tb)) {
    995		ret = PTR_ERR(tb);
    996		ath10k_warn(ar, "failed to parse tlv: %d\n", ret);
    997		return ret;
    998	}
    999
   1000	ev = tb[WMI_TLV_TAG_STRUCT_CHAN_INFO_EVENT];
   1001	if (!ev) {
   1002		kfree(tb);
   1003		return -EPROTO;
   1004	}
   1005
   1006	arg->err_code = ev->err_code;
   1007	arg->freq = ev->freq;
   1008	arg->cmd_flags = ev->cmd_flags;
   1009	arg->noise_floor = ev->noise_floor;
   1010	arg->rx_clear_count = ev->rx_clear_count;
   1011	arg->cycle_count = ev->cycle_count;
   1012	if (test_bit(ATH10K_FW_FEATURE_SINGLE_CHAN_INFO_PER_CHANNEL,
   1013		     ar->running_fw->fw_file.fw_features))
   1014		arg->mac_clk_mhz = ev->mac_clk_mhz;
   1015
   1016	kfree(tb);
   1017	return 0;
   1018}
   1019
   1020static int
   1021ath10k_wmi_tlv_op_pull_vdev_start_ev(struct ath10k *ar, struct sk_buff *skb,
   1022				     struct wmi_vdev_start_ev_arg *arg)
   1023{
   1024	const void **tb;
   1025	const struct wmi_vdev_start_response_event *ev;
   1026	int ret;
   1027
   1028	tb = ath10k_wmi_tlv_parse_alloc(ar, skb->data, skb->len, GFP_ATOMIC);
   1029	if (IS_ERR(tb)) {
   1030		ret = PTR_ERR(tb);
   1031		ath10k_warn(ar, "failed to parse tlv: %d\n", ret);
   1032		return ret;
   1033	}
   1034
   1035	ev = tb[WMI_TLV_TAG_STRUCT_VDEV_START_RESPONSE_EVENT];
   1036	if (!ev) {
   1037		kfree(tb);
   1038		return -EPROTO;
   1039	}
   1040
   1041	skb_pull(skb, sizeof(*ev));
   1042	arg->vdev_id = ev->vdev_id;
   1043	arg->req_id = ev->req_id;
   1044	arg->resp_type = ev->resp_type;
   1045	arg->status = ev->status;
   1046
   1047	kfree(tb);
   1048	return 0;
   1049}
   1050
   1051static int ath10k_wmi_tlv_op_pull_peer_kick_ev(struct ath10k *ar,
   1052					       struct sk_buff *skb,
   1053					       struct wmi_peer_kick_ev_arg *arg)
   1054{
   1055	const void **tb;
   1056	const struct wmi_peer_sta_kickout_event *ev;
   1057	int ret;
   1058
   1059	tb = ath10k_wmi_tlv_parse_alloc(ar, skb->data, skb->len, GFP_ATOMIC);
   1060	if (IS_ERR(tb)) {
   1061		ret = PTR_ERR(tb);
   1062		ath10k_warn(ar, "failed to parse tlv: %d\n", ret);
   1063		return ret;
   1064	}
   1065
   1066	ev = tb[WMI_TLV_TAG_STRUCT_PEER_STA_KICKOUT_EVENT];
   1067	if (!ev) {
   1068		kfree(tb);
   1069		return -EPROTO;
   1070	}
   1071
   1072	arg->mac_addr = ev->peer_macaddr.addr;
   1073
   1074	kfree(tb);
   1075	return 0;
   1076}
   1077
   1078struct wmi_tlv_swba_parse {
   1079	const struct wmi_host_swba_event *ev;
   1080	bool tim_done;
   1081	bool noa_done;
   1082	size_t n_tim;
   1083	size_t n_noa;
   1084	struct wmi_swba_ev_arg *arg;
   1085};
   1086
   1087static int ath10k_wmi_tlv_swba_tim_parse(struct ath10k *ar, u16 tag, u16 len,
   1088					 const void *ptr, void *data)
   1089{
   1090	struct wmi_tlv_swba_parse *swba = data;
   1091	struct wmi_tim_info_arg *tim_info_arg;
   1092	const struct wmi_tim_info *tim_info_ev = ptr;
   1093
   1094	if (tag != WMI_TLV_TAG_STRUCT_TIM_INFO)
   1095		return -EPROTO;
   1096
   1097	if (swba->n_tim >= ARRAY_SIZE(swba->arg->tim_info))
   1098		return -ENOBUFS;
   1099
   1100	if (__le32_to_cpu(tim_info_ev->tim_len) >
   1101	     sizeof(tim_info_ev->tim_bitmap)) {
   1102		ath10k_warn(ar, "refusing to parse invalid swba structure\n");
   1103		return -EPROTO;
   1104	}
   1105
   1106	tim_info_arg = &swba->arg->tim_info[swba->n_tim];
   1107	tim_info_arg->tim_len = tim_info_ev->tim_len;
   1108	tim_info_arg->tim_mcast = tim_info_ev->tim_mcast;
   1109	tim_info_arg->tim_bitmap = tim_info_ev->tim_bitmap;
   1110	tim_info_arg->tim_changed = tim_info_ev->tim_changed;
   1111	tim_info_arg->tim_num_ps_pending = tim_info_ev->tim_num_ps_pending;
   1112
   1113	swba->n_tim++;
   1114
   1115	return 0;
   1116}
   1117
   1118static int ath10k_wmi_tlv_swba_noa_parse(struct ath10k *ar, u16 tag, u16 len,
   1119					 const void *ptr, void *data)
   1120{
   1121	struct wmi_tlv_swba_parse *swba = data;
   1122
   1123	if (tag != WMI_TLV_TAG_STRUCT_P2P_NOA_INFO)
   1124		return -EPROTO;
   1125
   1126	if (swba->n_noa >= ARRAY_SIZE(swba->arg->noa_info))
   1127		return -ENOBUFS;
   1128
   1129	swba->arg->noa_info[swba->n_noa++] = ptr;
   1130	return 0;
   1131}
   1132
   1133static int ath10k_wmi_tlv_swba_parse(struct ath10k *ar, u16 tag, u16 len,
   1134				     const void *ptr, void *data)
   1135{
   1136	struct wmi_tlv_swba_parse *swba = data;
   1137	int ret;
   1138
   1139	switch (tag) {
   1140	case WMI_TLV_TAG_STRUCT_HOST_SWBA_EVENT:
   1141		swba->ev = ptr;
   1142		break;
   1143	case WMI_TLV_TAG_ARRAY_STRUCT:
   1144		if (!swba->tim_done) {
   1145			swba->tim_done = true;
   1146			ret = ath10k_wmi_tlv_iter(ar, ptr, len,
   1147						  ath10k_wmi_tlv_swba_tim_parse,
   1148						  swba);
   1149			if (ret)
   1150				return ret;
   1151		} else if (!swba->noa_done) {
   1152			swba->noa_done = true;
   1153			ret = ath10k_wmi_tlv_iter(ar, ptr, len,
   1154						  ath10k_wmi_tlv_swba_noa_parse,
   1155						  swba);
   1156			if (ret)
   1157				return ret;
   1158		}
   1159		break;
   1160	default:
   1161		break;
   1162	}
   1163	return 0;
   1164}
   1165
   1166static int ath10k_wmi_tlv_op_pull_swba_ev(struct ath10k *ar,
   1167					  struct sk_buff *skb,
   1168					  struct wmi_swba_ev_arg *arg)
   1169{
   1170	struct wmi_tlv_swba_parse swba = { .arg = arg };
   1171	u32 map;
   1172	size_t n_vdevs;
   1173	int ret;
   1174
   1175	ret = ath10k_wmi_tlv_iter(ar, skb->data, skb->len,
   1176				  ath10k_wmi_tlv_swba_parse, &swba);
   1177	if (ret) {
   1178		ath10k_warn(ar, "failed to parse tlv: %d\n", ret);
   1179		return ret;
   1180	}
   1181
   1182	if (!swba.ev)
   1183		return -EPROTO;
   1184
   1185	arg->vdev_map = swba.ev->vdev_map;
   1186
   1187	for (map = __le32_to_cpu(arg->vdev_map), n_vdevs = 0; map; map >>= 1)
   1188		if (map & BIT(0))
   1189			n_vdevs++;
   1190
   1191	if (n_vdevs != swba.n_tim ||
   1192	    n_vdevs != swba.n_noa)
   1193		return -EPROTO;
   1194
   1195	return 0;
   1196}
   1197
   1198static int ath10k_wmi_tlv_op_pull_phyerr_ev_hdr(struct ath10k *ar,
   1199						struct sk_buff *skb,
   1200						struct wmi_phyerr_hdr_arg *arg)
   1201{
   1202	const void **tb;
   1203	const struct wmi_tlv_phyerr_ev *ev;
   1204	const void *phyerrs;
   1205	int ret;
   1206
   1207	tb = ath10k_wmi_tlv_parse_alloc(ar, skb->data, skb->len, GFP_ATOMIC);
   1208	if (IS_ERR(tb)) {
   1209		ret = PTR_ERR(tb);
   1210		ath10k_warn(ar, "failed to parse tlv: %d\n", ret);
   1211		return ret;
   1212	}
   1213
   1214	ev = tb[WMI_TLV_TAG_STRUCT_COMB_PHYERR_RX_HDR];
   1215	phyerrs = tb[WMI_TLV_TAG_ARRAY_BYTE];
   1216
   1217	if (!ev || !phyerrs) {
   1218		kfree(tb);
   1219		return -EPROTO;
   1220	}
   1221
   1222	arg->num_phyerrs  = __le32_to_cpu(ev->num_phyerrs);
   1223	arg->tsf_l32 = __le32_to_cpu(ev->tsf_l32);
   1224	arg->tsf_u32 = __le32_to_cpu(ev->tsf_u32);
   1225	arg->buf_len = __le32_to_cpu(ev->buf_len);
   1226	arg->phyerrs = phyerrs;
   1227
   1228	kfree(tb);
   1229	return 0;
   1230}
   1231
   1232#define WMI_TLV_ABI_VER_NS0 0x5F414351
   1233#define WMI_TLV_ABI_VER_NS1 0x00004C4D
   1234#define WMI_TLV_ABI_VER_NS2 0x00000000
   1235#define WMI_TLV_ABI_VER_NS3 0x00000000
   1236
   1237#define WMI_TLV_ABI_VER0_MAJOR 1
   1238#define WMI_TLV_ABI_VER0_MINOR 0
   1239#define WMI_TLV_ABI_VER0 ((((WMI_TLV_ABI_VER0_MAJOR) << 24) & 0xFF000000) | \
   1240			  (((WMI_TLV_ABI_VER0_MINOR) <<  0) & 0x00FFFFFF))
   1241#define WMI_TLV_ABI_VER1 53
   1242
   1243static int
   1244ath10k_wmi_tlv_parse_mem_reqs(struct ath10k *ar, u16 tag, u16 len,
   1245			      const void *ptr, void *data)
   1246{
   1247	struct wmi_svc_rdy_ev_arg *arg = data;
   1248	int i;
   1249
   1250	if (tag != WMI_TLV_TAG_STRUCT_WLAN_HOST_MEM_REQ)
   1251		return -EPROTO;
   1252
   1253	for (i = 0; i < ARRAY_SIZE(arg->mem_reqs); i++) {
   1254		if (!arg->mem_reqs[i]) {
   1255			arg->mem_reqs[i] = ptr;
   1256			return 0;
   1257		}
   1258	}
   1259
   1260	return -ENOMEM;
   1261}
   1262
   1263struct wmi_tlv_svc_rdy_parse {
   1264	const struct hal_reg_capabilities *reg;
   1265	const struct wmi_tlv_svc_rdy_ev *ev;
   1266	const __le32 *svc_bmap;
   1267	const struct wlan_host_mem_req *mem_reqs;
   1268	bool svc_bmap_done;
   1269	bool dbs_hw_mode_done;
   1270};
   1271
   1272static int ath10k_wmi_tlv_svc_rdy_parse(struct ath10k *ar, u16 tag, u16 len,
   1273					const void *ptr, void *data)
   1274{
   1275	struct wmi_tlv_svc_rdy_parse *svc_rdy = data;
   1276
   1277	switch (tag) {
   1278	case WMI_TLV_TAG_STRUCT_SERVICE_READY_EVENT:
   1279		svc_rdy->ev = ptr;
   1280		break;
   1281	case WMI_TLV_TAG_STRUCT_HAL_REG_CAPABILITIES:
   1282		svc_rdy->reg = ptr;
   1283		break;
   1284	case WMI_TLV_TAG_ARRAY_STRUCT:
   1285		svc_rdy->mem_reqs = ptr;
   1286		break;
   1287	case WMI_TLV_TAG_ARRAY_UINT32:
   1288		if (!svc_rdy->svc_bmap_done) {
   1289			svc_rdy->svc_bmap_done = true;
   1290			svc_rdy->svc_bmap = ptr;
   1291		} else if (!svc_rdy->dbs_hw_mode_done) {
   1292			svc_rdy->dbs_hw_mode_done = true;
   1293		}
   1294		break;
   1295	default:
   1296		break;
   1297	}
   1298	return 0;
   1299}
   1300
   1301static int ath10k_wmi_tlv_op_pull_svc_rdy_ev(struct ath10k *ar,
   1302					     struct sk_buff *skb,
   1303					     struct wmi_svc_rdy_ev_arg *arg)
   1304{
   1305	const struct hal_reg_capabilities *reg;
   1306	const struct wmi_tlv_svc_rdy_ev *ev;
   1307	const __le32 *svc_bmap;
   1308	const struct wlan_host_mem_req *mem_reqs;
   1309	struct wmi_tlv_svc_rdy_parse svc_rdy = { };
   1310	int ret;
   1311
   1312	ret = ath10k_wmi_tlv_iter(ar, skb->data, skb->len,
   1313				  ath10k_wmi_tlv_svc_rdy_parse, &svc_rdy);
   1314	if (ret) {
   1315		ath10k_warn(ar, "failed to parse tlv: %d\n", ret);
   1316		return ret;
   1317	}
   1318
   1319	ev = svc_rdy.ev;
   1320	reg = svc_rdy.reg;
   1321	svc_bmap = svc_rdy.svc_bmap;
   1322	mem_reqs = svc_rdy.mem_reqs;
   1323
   1324	if (!ev || !reg || !svc_bmap || !mem_reqs)
   1325		return -EPROTO;
   1326
   1327	/* This is an internal ABI compatibility check for WMI TLV so check it
   1328	 * here instead of the generic WMI code.
   1329	 */
   1330	ath10k_dbg(ar, ATH10K_DBG_WMI,
   1331		   "wmi tlv abi 0x%08x ?= 0x%08x, 0x%08x ?= 0x%08x, 0x%08x ?= 0x%08x, 0x%08x ?= 0x%08x, 0x%08x ?= 0x%08x\n",
   1332		   __le32_to_cpu(ev->abi.abi_ver0), WMI_TLV_ABI_VER0,
   1333		   __le32_to_cpu(ev->abi.abi_ver_ns0), WMI_TLV_ABI_VER_NS0,
   1334		   __le32_to_cpu(ev->abi.abi_ver_ns1), WMI_TLV_ABI_VER_NS1,
   1335		   __le32_to_cpu(ev->abi.abi_ver_ns2), WMI_TLV_ABI_VER_NS2,
   1336		   __le32_to_cpu(ev->abi.abi_ver_ns3), WMI_TLV_ABI_VER_NS3);
   1337
   1338	if (__le32_to_cpu(ev->abi.abi_ver0) != WMI_TLV_ABI_VER0 ||
   1339	    __le32_to_cpu(ev->abi.abi_ver_ns0) != WMI_TLV_ABI_VER_NS0 ||
   1340	    __le32_to_cpu(ev->abi.abi_ver_ns1) != WMI_TLV_ABI_VER_NS1 ||
   1341	    __le32_to_cpu(ev->abi.abi_ver_ns2) != WMI_TLV_ABI_VER_NS2 ||
   1342	    __le32_to_cpu(ev->abi.abi_ver_ns3) != WMI_TLV_ABI_VER_NS3) {
   1343		return -ENOTSUPP;
   1344	}
   1345
   1346	arg->min_tx_power = ev->hw_min_tx_power;
   1347	arg->max_tx_power = ev->hw_max_tx_power;
   1348	arg->ht_cap = ev->ht_cap_info;
   1349	arg->vht_cap = ev->vht_cap_info;
   1350	arg->vht_supp_mcs = ev->vht_supp_mcs;
   1351	arg->sw_ver0 = ev->abi.abi_ver0;
   1352	arg->sw_ver1 = ev->abi.abi_ver1;
   1353	arg->fw_build = ev->fw_build_vers;
   1354	arg->phy_capab = ev->phy_capability;
   1355	arg->num_rf_chains = ev->num_rf_chains;
   1356	arg->eeprom_rd = reg->eeprom_rd;
   1357	arg->low_2ghz_chan = reg->low_2ghz_chan;
   1358	arg->high_2ghz_chan = reg->high_2ghz_chan;
   1359	arg->low_5ghz_chan = reg->low_5ghz_chan;
   1360	arg->high_5ghz_chan = reg->high_5ghz_chan;
   1361	arg->num_mem_reqs = ev->num_mem_reqs;
   1362	arg->service_map = svc_bmap;
   1363	arg->service_map_len = ath10k_wmi_tlv_len(svc_bmap);
   1364	arg->sys_cap_info = ev->sys_cap_info;
   1365
   1366	ret = ath10k_wmi_tlv_iter(ar, mem_reqs, ath10k_wmi_tlv_len(mem_reqs),
   1367				  ath10k_wmi_tlv_parse_mem_reqs, arg);
   1368	if (ret) {
   1369		ath10k_warn(ar, "failed to parse mem_reqs tlv: %d\n", ret);
   1370		return ret;
   1371	}
   1372
   1373	return 0;
   1374}
   1375
   1376static int ath10k_wmi_tlv_op_pull_rdy_ev(struct ath10k *ar,
   1377					 struct sk_buff *skb,
   1378					 struct wmi_rdy_ev_arg *arg)
   1379{
   1380	const void **tb;
   1381	const struct wmi_tlv_rdy_ev *ev;
   1382	int ret;
   1383
   1384	tb = ath10k_wmi_tlv_parse_alloc(ar, skb->data, skb->len, GFP_ATOMIC);
   1385	if (IS_ERR(tb)) {
   1386		ret = PTR_ERR(tb);
   1387		ath10k_warn(ar, "failed to parse tlv: %d\n", ret);
   1388		return ret;
   1389	}
   1390
   1391	ev = tb[WMI_TLV_TAG_STRUCT_READY_EVENT];
   1392	if (!ev) {
   1393		kfree(tb);
   1394		return -EPROTO;
   1395	}
   1396
   1397	arg->sw_version = ev->abi.abi_ver0;
   1398	arg->abi_version = ev->abi.abi_ver1;
   1399	arg->status = ev->status;
   1400	arg->mac_addr = ev->mac_addr.addr;
   1401
   1402	kfree(tb);
   1403	return 0;
   1404}
   1405
   1406static int ath10k_wmi_tlv_svc_avail_parse(struct ath10k *ar, u16 tag, u16 len,
   1407					  const void *ptr, void *data)
   1408{
   1409	struct wmi_svc_avail_ev_arg *arg = data;
   1410
   1411	switch (tag) {
   1412	case WMI_TLV_TAG_STRUCT_SERVICE_AVAILABLE_EVENT:
   1413		arg->service_map_ext_valid = true;
   1414		arg->service_map_ext_len = *(__le32 *)ptr;
   1415		arg->service_map_ext = ptr + sizeof(__le32);
   1416		return 0;
   1417	default:
   1418		break;
   1419	}
   1420
   1421	return 0;
   1422}
   1423
   1424static int ath10k_wmi_tlv_op_pull_svc_avail(struct ath10k *ar,
   1425					    struct sk_buff *skb,
   1426					    struct wmi_svc_avail_ev_arg *arg)
   1427{
   1428	int ret;
   1429
   1430	ret = ath10k_wmi_tlv_iter(ar, skb->data, skb->len,
   1431				  ath10k_wmi_tlv_svc_avail_parse, arg);
   1432
   1433	if (ret) {
   1434		ath10k_warn(ar, "failed to parse svc_avail tlv: %d\n", ret);
   1435		return ret;
   1436	}
   1437
   1438	return 0;
   1439}
   1440
   1441static void ath10k_wmi_tlv_pull_vdev_stats(const struct wmi_tlv_vdev_stats *src,
   1442					   struct ath10k_fw_stats_vdev *dst)
   1443{
   1444	int i;
   1445
   1446	dst->vdev_id = __le32_to_cpu(src->vdev_id);
   1447	dst->beacon_snr = __le32_to_cpu(src->beacon_snr);
   1448	dst->data_snr = __le32_to_cpu(src->data_snr);
   1449	dst->num_rx_frames = __le32_to_cpu(src->num_rx_frames);
   1450	dst->num_rts_fail = __le32_to_cpu(src->num_rts_fail);
   1451	dst->num_rts_success = __le32_to_cpu(src->num_rts_success);
   1452	dst->num_rx_err = __le32_to_cpu(src->num_rx_err);
   1453	dst->num_rx_discard = __le32_to_cpu(src->num_rx_discard);
   1454	dst->num_tx_not_acked = __le32_to_cpu(src->num_tx_not_acked);
   1455
   1456	for (i = 0; i < ARRAY_SIZE(src->num_tx_frames); i++)
   1457		dst->num_tx_frames[i] =
   1458			__le32_to_cpu(src->num_tx_frames[i]);
   1459
   1460	for (i = 0; i < ARRAY_SIZE(src->num_tx_frames_retries); i++)
   1461		dst->num_tx_frames_retries[i] =
   1462			__le32_to_cpu(src->num_tx_frames_retries[i]);
   1463
   1464	for (i = 0; i < ARRAY_SIZE(src->num_tx_frames_failures); i++)
   1465		dst->num_tx_frames_failures[i] =
   1466			__le32_to_cpu(src->num_tx_frames_failures[i]);
   1467
   1468	for (i = 0; i < ARRAY_SIZE(src->tx_rate_history); i++)
   1469		dst->tx_rate_history[i] =
   1470			__le32_to_cpu(src->tx_rate_history[i]);
   1471
   1472	for (i = 0; i < ARRAY_SIZE(src->beacon_rssi_history); i++)
   1473		dst->beacon_rssi_history[i] =
   1474			__le32_to_cpu(src->beacon_rssi_history[i]);
   1475}
   1476
   1477static int ath10k_wmi_tlv_op_pull_fw_stats(struct ath10k *ar,
   1478					   struct sk_buff *skb,
   1479					   struct ath10k_fw_stats *stats)
   1480{
   1481	const void **tb;
   1482	const struct wmi_tlv_stats_ev *ev;
   1483	u32 num_peer_stats_extd;
   1484	const void *data;
   1485	u32 num_pdev_stats;
   1486	u32 num_vdev_stats;
   1487	u32 num_peer_stats;
   1488	u32 num_bcnflt_stats;
   1489	u32 num_chan_stats;
   1490	size_t data_len;
   1491	u32 stats_id;
   1492	int ret;
   1493	int i;
   1494
   1495	tb = ath10k_wmi_tlv_parse_alloc(ar, skb->data, skb->len, GFP_ATOMIC);
   1496	if (IS_ERR(tb)) {
   1497		ret = PTR_ERR(tb);
   1498		ath10k_warn(ar, "failed to parse tlv: %d\n", ret);
   1499		return ret;
   1500	}
   1501
   1502	ev = tb[WMI_TLV_TAG_STRUCT_STATS_EVENT];
   1503	data = tb[WMI_TLV_TAG_ARRAY_BYTE];
   1504
   1505	if (!ev || !data) {
   1506		kfree(tb);
   1507		return -EPROTO;
   1508	}
   1509
   1510	data_len = ath10k_wmi_tlv_len(data);
   1511	num_pdev_stats = __le32_to_cpu(ev->num_pdev_stats);
   1512	num_vdev_stats = __le32_to_cpu(ev->num_vdev_stats);
   1513	num_peer_stats = __le32_to_cpu(ev->num_peer_stats);
   1514	num_bcnflt_stats = __le32_to_cpu(ev->num_bcnflt_stats);
   1515	num_chan_stats = __le32_to_cpu(ev->num_chan_stats);
   1516	stats_id = __le32_to_cpu(ev->stats_id);
   1517	num_peer_stats_extd = __le32_to_cpu(ev->num_peer_stats_extd);
   1518
   1519	ath10k_dbg(ar, ATH10K_DBG_WMI,
   1520		   "wmi tlv stats update pdev %i vdev %i peer %i bcnflt %i chan %i peer_extd %i\n",
   1521		   num_pdev_stats, num_vdev_stats, num_peer_stats,
   1522		   num_bcnflt_stats, num_chan_stats, num_peer_stats_extd);
   1523
   1524	for (i = 0; i < num_pdev_stats; i++) {
   1525		const struct wmi_pdev_stats *src;
   1526		struct ath10k_fw_stats_pdev *dst;
   1527
   1528		src = data;
   1529		if (data_len < sizeof(*src)) {
   1530			kfree(tb);
   1531			return -EPROTO;
   1532		}
   1533
   1534		data += sizeof(*src);
   1535		data_len -= sizeof(*src);
   1536
   1537		dst = kzalloc(sizeof(*dst), GFP_ATOMIC);
   1538		if (!dst)
   1539			continue;
   1540
   1541		ath10k_wmi_pull_pdev_stats_base(&src->base, dst);
   1542		ath10k_wmi_pull_pdev_stats_tx(&src->tx, dst);
   1543		ath10k_wmi_pull_pdev_stats_rx(&src->rx, dst);
   1544		list_add_tail(&dst->list, &stats->pdevs);
   1545	}
   1546
   1547	for (i = 0; i < num_vdev_stats; i++) {
   1548		const struct wmi_tlv_vdev_stats *src;
   1549		struct ath10k_fw_stats_vdev *dst;
   1550
   1551		src = data;
   1552		if (data_len < sizeof(*src)) {
   1553			kfree(tb);
   1554			return -EPROTO;
   1555		}
   1556
   1557		data += sizeof(*src);
   1558		data_len -= sizeof(*src);
   1559
   1560		dst = kzalloc(sizeof(*dst), GFP_ATOMIC);
   1561		if (!dst)
   1562			continue;
   1563
   1564		ath10k_wmi_tlv_pull_vdev_stats(src, dst);
   1565		list_add_tail(&dst->list, &stats->vdevs);
   1566	}
   1567
   1568	for (i = 0; i < num_peer_stats; i++) {
   1569		const struct wmi_10x_peer_stats *src;
   1570		struct ath10k_fw_stats_peer *dst;
   1571
   1572		src = data;
   1573		if (data_len < sizeof(*src)) {
   1574			kfree(tb);
   1575			return -EPROTO;
   1576		}
   1577
   1578		data += sizeof(*src);
   1579		data_len -= sizeof(*src);
   1580
   1581		dst = kzalloc(sizeof(*dst), GFP_ATOMIC);
   1582		if (!dst)
   1583			continue;
   1584
   1585		ath10k_wmi_pull_peer_stats(&src->old, dst);
   1586		dst->peer_rx_rate = __le32_to_cpu(src->peer_rx_rate);
   1587
   1588		if (stats_id & WMI_TLV_STAT_PEER_EXTD) {
   1589			const struct wmi_tlv_peer_stats_extd *extd;
   1590			unsigned long rx_duration_high;
   1591
   1592			extd = data + sizeof(*src) * (num_peer_stats - i - 1)
   1593			       + sizeof(*extd) * i;
   1594
   1595			dst->rx_duration = __le32_to_cpu(extd->rx_duration);
   1596			rx_duration_high = __le32_to_cpu
   1597						(extd->rx_duration_high);
   1598
   1599			if (test_bit(WMI_TLV_PEER_RX_DURATION_HIGH_VALID_BIT,
   1600				     &rx_duration_high)) {
   1601				rx_duration_high =
   1602					FIELD_GET(WMI_TLV_PEER_RX_DURATION_HIGH_MASK,
   1603						  rx_duration_high);
   1604				dst->rx_duration |= (u64)rx_duration_high <<
   1605						    WMI_TLV_PEER_RX_DURATION_SHIFT;
   1606			}
   1607		}
   1608
   1609		list_add_tail(&dst->list, &stats->peers);
   1610	}
   1611
   1612	kfree(tb);
   1613	return 0;
   1614}
   1615
   1616static int ath10k_wmi_tlv_op_pull_roam_ev(struct ath10k *ar,
   1617					  struct sk_buff *skb,
   1618					  struct wmi_roam_ev_arg *arg)
   1619{
   1620	const void **tb;
   1621	const struct wmi_tlv_roam_ev *ev;
   1622	int ret;
   1623
   1624	tb = ath10k_wmi_tlv_parse_alloc(ar, skb->data, skb->len, GFP_ATOMIC);
   1625	if (IS_ERR(tb)) {
   1626		ret = PTR_ERR(tb);
   1627		ath10k_warn(ar, "failed to parse tlv: %d\n", ret);
   1628		return ret;
   1629	}
   1630
   1631	ev = tb[WMI_TLV_TAG_STRUCT_ROAM_EVENT];
   1632	if (!ev) {
   1633		kfree(tb);
   1634		return -EPROTO;
   1635	}
   1636
   1637	arg->vdev_id = ev->vdev_id;
   1638	arg->reason = ev->reason;
   1639	arg->rssi = ev->rssi;
   1640
   1641	kfree(tb);
   1642	return 0;
   1643}
   1644
   1645static int
   1646ath10k_wmi_tlv_op_pull_wow_ev(struct ath10k *ar, struct sk_buff *skb,
   1647			      struct wmi_wow_ev_arg *arg)
   1648{
   1649	const void **tb;
   1650	const struct wmi_tlv_wow_event_info *ev;
   1651	int ret;
   1652
   1653	tb = ath10k_wmi_tlv_parse_alloc(ar, skb->data, skb->len, GFP_ATOMIC);
   1654	if (IS_ERR(tb)) {
   1655		ret = PTR_ERR(tb);
   1656		ath10k_warn(ar, "failed to parse tlv: %d\n", ret);
   1657		return ret;
   1658	}
   1659
   1660	ev = tb[WMI_TLV_TAG_STRUCT_WOW_EVENT_INFO];
   1661	if (!ev) {
   1662		kfree(tb);
   1663		return -EPROTO;
   1664	}
   1665
   1666	arg->vdev_id = __le32_to_cpu(ev->vdev_id);
   1667	arg->flag = __le32_to_cpu(ev->flag);
   1668	arg->wake_reason = __le32_to_cpu(ev->wake_reason);
   1669	arg->data_len = __le32_to_cpu(ev->data_len);
   1670
   1671	kfree(tb);
   1672	return 0;
   1673}
   1674
   1675static int ath10k_wmi_tlv_op_pull_echo_ev(struct ath10k *ar,
   1676					  struct sk_buff *skb,
   1677					  struct wmi_echo_ev_arg *arg)
   1678{
   1679	const void **tb;
   1680	const struct wmi_echo_event *ev;
   1681	int ret;
   1682
   1683	tb = ath10k_wmi_tlv_parse_alloc(ar, skb->data, skb->len, GFP_ATOMIC);
   1684	if (IS_ERR(tb)) {
   1685		ret = PTR_ERR(tb);
   1686		ath10k_warn(ar, "failed to parse tlv: %d\n", ret);
   1687		return ret;
   1688	}
   1689
   1690	ev = tb[WMI_TLV_TAG_STRUCT_ECHO_EVENT];
   1691	if (!ev) {
   1692		kfree(tb);
   1693		return -EPROTO;
   1694	}
   1695
   1696	arg->value = ev->value;
   1697
   1698	kfree(tb);
   1699	return 0;
   1700}
   1701
   1702static struct sk_buff *
   1703ath10k_wmi_tlv_op_gen_pdev_suspend(struct ath10k *ar, u32 opt)
   1704{
   1705	struct wmi_tlv_pdev_suspend *cmd;
   1706	struct wmi_tlv *tlv;
   1707	struct sk_buff *skb;
   1708
   1709	skb = ath10k_wmi_alloc_skb(ar, sizeof(*tlv) + sizeof(*cmd));
   1710	if (!skb)
   1711		return ERR_PTR(-ENOMEM);
   1712
   1713	tlv = (void *)skb->data;
   1714	tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_PDEV_SUSPEND_CMD);
   1715	tlv->len = __cpu_to_le16(sizeof(*cmd));
   1716	cmd = (void *)tlv->value;
   1717	cmd->opt = __cpu_to_le32(opt);
   1718
   1719	ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv pdev suspend\n");
   1720	return skb;
   1721}
   1722
   1723static struct sk_buff *
   1724ath10k_wmi_tlv_op_gen_pdev_resume(struct ath10k *ar)
   1725{
   1726	struct wmi_tlv_resume_cmd *cmd;
   1727	struct wmi_tlv *tlv;
   1728	struct sk_buff *skb;
   1729
   1730	skb = ath10k_wmi_alloc_skb(ar, sizeof(*tlv) + sizeof(*cmd));
   1731	if (!skb)
   1732		return ERR_PTR(-ENOMEM);
   1733
   1734	tlv = (void *)skb->data;
   1735	tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_PDEV_RESUME_CMD);
   1736	tlv->len = __cpu_to_le16(sizeof(*cmd));
   1737	cmd = (void *)tlv->value;
   1738	cmd->reserved = __cpu_to_le32(0);
   1739
   1740	ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv pdev resume\n");
   1741	return skb;
   1742}
   1743
   1744static struct sk_buff *
   1745ath10k_wmi_tlv_op_gen_pdev_set_rd(struct ath10k *ar,
   1746				  u16 rd, u16 rd2g, u16 rd5g,
   1747				  u16 ctl2g, u16 ctl5g,
   1748				  enum wmi_dfs_region dfs_reg)
   1749{
   1750	struct wmi_tlv_pdev_set_rd_cmd *cmd;
   1751	struct wmi_tlv *tlv;
   1752	struct sk_buff *skb;
   1753
   1754	skb = ath10k_wmi_alloc_skb(ar, sizeof(*tlv) + sizeof(*cmd));
   1755	if (!skb)
   1756		return ERR_PTR(-ENOMEM);
   1757
   1758	tlv = (void *)skb->data;
   1759	tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_PDEV_SET_REGDOMAIN_CMD);
   1760	tlv->len = __cpu_to_le16(sizeof(*cmd));
   1761	cmd = (void *)tlv->value;
   1762	cmd->regd = __cpu_to_le32(rd);
   1763	cmd->regd_2ghz = __cpu_to_le32(rd2g);
   1764	cmd->regd_5ghz = __cpu_to_le32(rd5g);
   1765	cmd->conform_limit_2ghz = __cpu_to_le32(ctl2g);
   1766	cmd->conform_limit_5ghz = __cpu_to_le32(ctl5g);
   1767
   1768	ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv pdev set rd\n");
   1769	return skb;
   1770}
   1771
   1772static enum wmi_txbf_conf ath10k_wmi_tlv_txbf_conf_scheme(struct ath10k *ar)
   1773{
   1774	return WMI_TXBF_CONF_AFTER_ASSOC;
   1775}
   1776
   1777static struct sk_buff *
   1778ath10k_wmi_tlv_op_gen_pdev_set_param(struct ath10k *ar, u32 param_id,
   1779				     u32 param_value)
   1780{
   1781	struct wmi_tlv_pdev_set_param_cmd *cmd;
   1782	struct wmi_tlv *tlv;
   1783	struct sk_buff *skb;
   1784
   1785	skb = ath10k_wmi_alloc_skb(ar, sizeof(*tlv) + sizeof(*cmd));
   1786	if (!skb)
   1787		return ERR_PTR(-ENOMEM);
   1788
   1789	tlv = (void *)skb->data;
   1790	tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_PDEV_SET_PARAM_CMD);
   1791	tlv->len = __cpu_to_le16(sizeof(*cmd));
   1792	cmd = (void *)tlv->value;
   1793	cmd->param_id = __cpu_to_le32(param_id);
   1794	cmd->param_value = __cpu_to_le32(param_value);
   1795
   1796	ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv pdev set param %d value 0x%x\n",
   1797		   param_id, param_value);
   1798	return skb;
   1799}
   1800
   1801static void
   1802ath10k_wmi_tlv_put_host_mem_chunks(struct ath10k *ar, void *host_mem_chunks)
   1803{
   1804	struct host_memory_chunk_tlv *chunk;
   1805	struct wmi_tlv *tlv;
   1806	dma_addr_t paddr;
   1807	int i;
   1808	__le16 tlv_len, tlv_tag;
   1809
   1810	tlv_tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_WLAN_HOST_MEMORY_CHUNK);
   1811	tlv_len = __cpu_to_le16(sizeof(*chunk));
   1812	for (i = 0; i < ar->wmi.num_mem_chunks; i++) {
   1813		tlv = host_mem_chunks;
   1814		tlv->tag = tlv_tag;
   1815		tlv->len = tlv_len;
   1816		chunk = (void *)tlv->value;
   1817
   1818		chunk->ptr = __cpu_to_le32(ar->wmi.mem_chunks[i].paddr);
   1819		chunk->size = __cpu_to_le32(ar->wmi.mem_chunks[i].len);
   1820		chunk->req_id = __cpu_to_le32(ar->wmi.mem_chunks[i].req_id);
   1821
   1822		if (test_bit(WMI_SERVICE_SUPPORT_EXTEND_ADDRESS,
   1823			     ar->wmi.svc_map)) {
   1824			paddr = ar->wmi.mem_chunks[i].paddr;
   1825			chunk->ptr_high = __cpu_to_le32(upper_32_bits(paddr));
   1826		}
   1827
   1828		ath10k_dbg(ar, ATH10K_DBG_WMI,
   1829			   "wmi-tlv chunk %d len %d, addr 0x%llx, id 0x%x\n",
   1830			   i,
   1831			   ar->wmi.mem_chunks[i].len,
   1832			   (unsigned long long)ar->wmi.mem_chunks[i].paddr,
   1833			   ar->wmi.mem_chunks[i].req_id);
   1834
   1835		host_mem_chunks += sizeof(*tlv);
   1836		host_mem_chunks += sizeof(*chunk);
   1837	}
   1838}
   1839
   1840static struct sk_buff *ath10k_wmi_tlv_op_gen_init(struct ath10k *ar)
   1841{
   1842	struct sk_buff *skb;
   1843	struct wmi_tlv *tlv;
   1844	struct wmi_tlv_init_cmd *cmd;
   1845	struct wmi_tlv_resource_config *cfg;
   1846	void *chunks;
   1847	size_t len, chunks_len;
   1848	void *ptr;
   1849
   1850	chunks_len = ar->wmi.num_mem_chunks *
   1851		     (sizeof(struct host_memory_chunk_tlv) + sizeof(*tlv));
   1852	len = (sizeof(*tlv) + sizeof(*cmd)) +
   1853	      (sizeof(*tlv) + sizeof(*cfg)) +
   1854	      (sizeof(*tlv) + chunks_len);
   1855
   1856	skb = ath10k_wmi_alloc_skb(ar, len);
   1857	if (!skb)
   1858		return ERR_PTR(-ENOMEM);
   1859
   1860	ptr = skb->data;
   1861
   1862	tlv = ptr;
   1863	tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_INIT_CMD);
   1864	tlv->len = __cpu_to_le16(sizeof(*cmd));
   1865	cmd = (void *)tlv->value;
   1866	ptr += sizeof(*tlv);
   1867	ptr += sizeof(*cmd);
   1868
   1869	tlv = ptr;
   1870	tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_RESOURCE_CONFIG);
   1871	tlv->len = __cpu_to_le16(sizeof(*cfg));
   1872	cfg = (void *)tlv->value;
   1873	ptr += sizeof(*tlv);
   1874	ptr += sizeof(*cfg);
   1875
   1876	tlv = ptr;
   1877	tlv->tag = __cpu_to_le16(WMI_TLV_TAG_ARRAY_STRUCT);
   1878	tlv->len = __cpu_to_le16(chunks_len);
   1879	chunks = (void *)tlv->value;
   1880
   1881	ptr += sizeof(*tlv);
   1882	ptr += chunks_len;
   1883
   1884	cmd->abi.abi_ver0 = __cpu_to_le32(WMI_TLV_ABI_VER0);
   1885	cmd->abi.abi_ver1 = __cpu_to_le32(WMI_TLV_ABI_VER1);
   1886	cmd->abi.abi_ver_ns0 = __cpu_to_le32(WMI_TLV_ABI_VER_NS0);
   1887	cmd->abi.abi_ver_ns1 = __cpu_to_le32(WMI_TLV_ABI_VER_NS1);
   1888	cmd->abi.abi_ver_ns2 = __cpu_to_le32(WMI_TLV_ABI_VER_NS2);
   1889	cmd->abi.abi_ver_ns3 = __cpu_to_le32(WMI_TLV_ABI_VER_NS3);
   1890	cmd->num_host_mem_chunks = __cpu_to_le32(ar->wmi.num_mem_chunks);
   1891
   1892	cfg->num_vdevs = __cpu_to_le32(TARGET_TLV_NUM_VDEVS);
   1893
   1894	if (ar->hw_params.num_peers)
   1895		cfg->num_peers = __cpu_to_le32(ar->hw_params.num_peers);
   1896	else
   1897		cfg->num_peers = __cpu_to_le32(TARGET_TLV_NUM_PEERS);
   1898	cfg->ast_skid_limit = __cpu_to_le32(ar->hw_params.ast_skid_limit);
   1899	cfg->num_wds_entries = __cpu_to_le32(ar->hw_params.num_wds_entries);
   1900
   1901	if (test_bit(WMI_SERVICE_RX_FULL_REORDER, ar->wmi.svc_map)) {
   1902		cfg->num_offload_peers = __cpu_to_le32(TARGET_TLV_NUM_VDEVS);
   1903		cfg->num_offload_reorder_bufs = __cpu_to_le32(TARGET_TLV_NUM_VDEVS);
   1904	} else {
   1905		cfg->num_offload_peers = __cpu_to_le32(0);
   1906		cfg->num_offload_reorder_bufs = __cpu_to_le32(0);
   1907	}
   1908
   1909	cfg->num_peer_keys = __cpu_to_le32(2);
   1910	if (ar->hw_params.num_peers)
   1911		cfg->num_tids = __cpu_to_le32(ar->hw_params.num_peers * 2);
   1912	else
   1913		cfg->num_tids = __cpu_to_le32(TARGET_TLV_NUM_TIDS);
   1914	cfg->tx_chain_mask = __cpu_to_le32(0x7);
   1915	cfg->rx_chain_mask = __cpu_to_le32(0x7);
   1916	cfg->rx_timeout_pri[0] = __cpu_to_le32(0x64);
   1917	cfg->rx_timeout_pri[1] = __cpu_to_le32(0x64);
   1918	cfg->rx_timeout_pri[2] = __cpu_to_le32(0x64);
   1919	cfg->rx_timeout_pri[3] = __cpu_to_le32(0x28);
   1920	cfg->rx_decap_mode = __cpu_to_le32(ar->wmi.rx_decap_mode);
   1921	cfg->scan_max_pending_reqs = __cpu_to_le32(4);
   1922	cfg->bmiss_offload_max_vdev = __cpu_to_le32(TARGET_TLV_NUM_VDEVS);
   1923	cfg->roam_offload_max_vdev = __cpu_to_le32(TARGET_TLV_NUM_VDEVS);
   1924	cfg->roam_offload_max_ap_profiles = __cpu_to_le32(8);
   1925	cfg->num_mcast_groups = __cpu_to_le32(0);
   1926	cfg->num_mcast_table_elems = __cpu_to_le32(0);
   1927	cfg->mcast2ucast_mode = __cpu_to_le32(0);
   1928	cfg->tx_dbg_log_size = __cpu_to_le32(0x400);
   1929	cfg->dma_burst_size = __cpu_to_le32(0);
   1930	cfg->mac_aggr_delim = __cpu_to_le32(0);
   1931	cfg->rx_skip_defrag_timeout_dup_detection_check = __cpu_to_le32(0);
   1932	cfg->vow_config = __cpu_to_le32(0);
   1933	cfg->gtk_offload_max_vdev = __cpu_to_le32(2);
   1934	cfg->num_msdu_desc = __cpu_to_le32(ar->htt.max_num_pending_tx);
   1935	cfg->max_frag_entries = __cpu_to_le32(2);
   1936	cfg->num_tdls_vdevs = __cpu_to_le32(TARGET_TLV_NUM_TDLS_VDEVS);
   1937	cfg->num_tdls_conn_table_entries = __cpu_to_le32(0x20);
   1938	cfg->beacon_tx_offload_max_vdev = __cpu_to_le32(2);
   1939	cfg->num_multicast_filter_entries = __cpu_to_le32(5);
   1940	cfg->num_wow_filters = __cpu_to_le32(ar->wow.max_num_patterns);
   1941	cfg->num_keep_alive_pattern = __cpu_to_le32(6);
   1942	cfg->keep_alive_pattern_size = __cpu_to_le32(0);
   1943	cfg->max_tdls_concurrent_sleep_sta = __cpu_to_le32(1);
   1944	cfg->max_tdls_concurrent_buffer_sta = __cpu_to_le32(1);
   1945	cfg->wmi_send_separate = __cpu_to_le32(0);
   1946	cfg->num_ocb_vdevs = __cpu_to_le32(0);
   1947	cfg->num_ocb_channels = __cpu_to_le32(0);
   1948	cfg->num_ocb_schedules = __cpu_to_le32(0);
   1949	cfg->host_capab = __cpu_to_le32(WMI_TLV_FLAG_MGMT_BUNDLE_TX_COMPL);
   1950
   1951	if (test_bit(WMI_SERVICE_TX_DATA_ACK_RSSI, ar->wmi.svc_map))
   1952		cfg->host_capab |= __cpu_to_le32(WMI_RSRC_CFG_FLAG_TX_ACK_RSSI);
   1953
   1954	ath10k_wmi_tlv_put_host_mem_chunks(ar, chunks);
   1955
   1956	ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv init\n");
   1957	return skb;
   1958}
   1959
   1960static struct sk_buff *
   1961ath10k_wmi_tlv_op_gen_start_scan(struct ath10k *ar,
   1962				 const struct wmi_start_scan_arg *arg)
   1963{
   1964	struct wmi_tlv_start_scan_cmd *cmd;
   1965	struct wmi_tlv *tlv;
   1966	struct sk_buff *skb;
   1967	size_t len, chan_len, ssid_len, bssid_len, ie_len;
   1968	__le32 *chans;
   1969	struct wmi_ssid *ssids;
   1970	struct wmi_mac_addr *addrs;
   1971	void *ptr;
   1972	int i, ret;
   1973
   1974	ret = ath10k_wmi_start_scan_verify(arg);
   1975	if (ret)
   1976		return ERR_PTR(ret);
   1977
   1978	chan_len = arg->n_channels * sizeof(__le32);
   1979	ssid_len = arg->n_ssids * sizeof(struct wmi_ssid);
   1980	bssid_len = arg->n_bssids * sizeof(struct wmi_mac_addr);
   1981	ie_len = roundup(arg->ie_len, 4);
   1982	len = (sizeof(*tlv) + sizeof(*cmd)) +
   1983	      sizeof(*tlv) + chan_len +
   1984	      sizeof(*tlv) + ssid_len +
   1985	      sizeof(*tlv) + bssid_len +
   1986	      sizeof(*tlv) + ie_len;
   1987
   1988	skb = ath10k_wmi_alloc_skb(ar, len);
   1989	if (!skb)
   1990		return ERR_PTR(-ENOMEM);
   1991
   1992	ptr = (void *)skb->data;
   1993	tlv = ptr;
   1994	tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_START_SCAN_CMD);
   1995	tlv->len = __cpu_to_le16(sizeof(*cmd));
   1996	cmd = (void *)tlv->value;
   1997
   1998	ath10k_wmi_put_start_scan_common(&cmd->common, arg);
   1999	cmd->burst_duration_ms = __cpu_to_le32(arg->burst_duration_ms);
   2000	cmd->num_channels = __cpu_to_le32(arg->n_channels);
   2001	cmd->num_ssids = __cpu_to_le32(arg->n_ssids);
   2002	cmd->num_bssids = __cpu_to_le32(arg->n_bssids);
   2003	cmd->ie_len = __cpu_to_le32(arg->ie_len);
   2004	cmd->num_probes = __cpu_to_le32(3);
   2005	ether_addr_copy(cmd->mac_addr.addr, arg->mac_addr.addr);
   2006	ether_addr_copy(cmd->mac_mask.addr, arg->mac_mask.addr);
   2007
   2008	/* FIXME: There are some scan flag inconsistencies across firmwares,
   2009	 * e.g. WMI-TLV inverts the logic behind the following flag.
   2010	 */
   2011	cmd->common.scan_ctrl_flags ^= __cpu_to_le32(WMI_SCAN_FILTER_PROBE_REQ);
   2012
   2013	ptr += sizeof(*tlv);
   2014	ptr += sizeof(*cmd);
   2015
   2016	tlv = ptr;
   2017	tlv->tag = __cpu_to_le16(WMI_TLV_TAG_ARRAY_UINT32);
   2018	tlv->len = __cpu_to_le16(chan_len);
   2019	chans = (void *)tlv->value;
   2020	for (i = 0; i < arg->n_channels; i++)
   2021		chans[i] = __cpu_to_le32(arg->channels[i]);
   2022
   2023	ptr += sizeof(*tlv);
   2024	ptr += chan_len;
   2025
   2026	tlv = ptr;
   2027	tlv->tag = __cpu_to_le16(WMI_TLV_TAG_ARRAY_FIXED_STRUCT);
   2028	tlv->len = __cpu_to_le16(ssid_len);
   2029	ssids = (void *)tlv->value;
   2030	for (i = 0; i < arg->n_ssids; i++) {
   2031		ssids[i].ssid_len = __cpu_to_le32(arg->ssids[i].len);
   2032		memcpy(ssids[i].ssid, arg->ssids[i].ssid, arg->ssids[i].len);
   2033	}
   2034
   2035	ptr += sizeof(*tlv);
   2036	ptr += ssid_len;
   2037
   2038	tlv = ptr;
   2039	tlv->tag = __cpu_to_le16(WMI_TLV_TAG_ARRAY_FIXED_STRUCT);
   2040	tlv->len = __cpu_to_le16(bssid_len);
   2041	addrs = (void *)tlv->value;
   2042	for (i = 0; i < arg->n_bssids; i++)
   2043		ether_addr_copy(addrs[i].addr, arg->bssids[i].bssid);
   2044
   2045	ptr += sizeof(*tlv);
   2046	ptr += bssid_len;
   2047
   2048	tlv = ptr;
   2049	tlv->tag = __cpu_to_le16(WMI_TLV_TAG_ARRAY_BYTE);
   2050	tlv->len = __cpu_to_le16(ie_len);
   2051	memcpy(tlv->value, arg->ie, arg->ie_len);
   2052
   2053	ptr += sizeof(*tlv);
   2054	ptr += ie_len;
   2055
   2056	ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv start scan\n");
   2057	return skb;
   2058}
   2059
   2060static struct sk_buff *
   2061ath10k_wmi_tlv_op_gen_stop_scan(struct ath10k *ar,
   2062				const struct wmi_stop_scan_arg *arg)
   2063{
   2064	struct wmi_stop_scan_cmd *cmd;
   2065	struct wmi_tlv *tlv;
   2066	struct sk_buff *skb;
   2067	u32 scan_id;
   2068	u32 req_id;
   2069
   2070	if (arg->req_id > 0xFFF)
   2071		return ERR_PTR(-EINVAL);
   2072	if (arg->req_type == WMI_SCAN_STOP_ONE && arg->u.scan_id > 0xFFF)
   2073		return ERR_PTR(-EINVAL);
   2074
   2075	skb = ath10k_wmi_alloc_skb(ar, sizeof(*tlv) + sizeof(*cmd));
   2076	if (!skb)
   2077		return ERR_PTR(-ENOMEM);
   2078
   2079	scan_id = arg->u.scan_id;
   2080	scan_id |= WMI_HOST_SCAN_REQ_ID_PREFIX;
   2081
   2082	req_id = arg->req_id;
   2083	req_id |= WMI_HOST_SCAN_REQUESTOR_ID_PREFIX;
   2084
   2085	tlv = (void *)skb->data;
   2086	tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_STOP_SCAN_CMD);
   2087	tlv->len = __cpu_to_le16(sizeof(*cmd));
   2088	cmd = (void *)tlv->value;
   2089	cmd->req_type = __cpu_to_le32(arg->req_type);
   2090	cmd->vdev_id = __cpu_to_le32(arg->u.vdev_id);
   2091	cmd->scan_id = __cpu_to_le32(scan_id);
   2092	cmd->scan_req_id = __cpu_to_le32(req_id);
   2093
   2094	ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv stop scan\n");
   2095	return skb;
   2096}
   2097
   2098static int ath10k_wmi_tlv_op_get_vdev_subtype(struct ath10k *ar,
   2099					      enum wmi_vdev_subtype subtype)
   2100{
   2101	switch (subtype) {
   2102	case WMI_VDEV_SUBTYPE_NONE:
   2103		return WMI_TLV_VDEV_SUBTYPE_NONE;
   2104	case WMI_VDEV_SUBTYPE_P2P_DEVICE:
   2105		return WMI_TLV_VDEV_SUBTYPE_P2P_DEV;
   2106	case WMI_VDEV_SUBTYPE_P2P_CLIENT:
   2107		return WMI_TLV_VDEV_SUBTYPE_P2P_CLI;
   2108	case WMI_VDEV_SUBTYPE_P2P_GO:
   2109		return WMI_TLV_VDEV_SUBTYPE_P2P_GO;
   2110	case WMI_VDEV_SUBTYPE_PROXY_STA:
   2111		return WMI_TLV_VDEV_SUBTYPE_PROXY_STA;
   2112	case WMI_VDEV_SUBTYPE_MESH_11S:
   2113		return WMI_TLV_VDEV_SUBTYPE_MESH_11S;
   2114	case WMI_VDEV_SUBTYPE_MESH_NON_11S:
   2115		return -ENOTSUPP;
   2116	}
   2117	return -ENOTSUPP;
   2118}
   2119
   2120static struct sk_buff *
   2121ath10k_wmi_tlv_op_gen_vdev_create(struct ath10k *ar,
   2122				  u32 vdev_id,
   2123				  enum wmi_vdev_type vdev_type,
   2124				  enum wmi_vdev_subtype vdev_subtype,
   2125				  const u8 mac_addr[ETH_ALEN])
   2126{
   2127	struct wmi_vdev_create_cmd *cmd;
   2128	struct wmi_tlv *tlv;
   2129	struct sk_buff *skb;
   2130
   2131	skb = ath10k_wmi_alloc_skb(ar, sizeof(*tlv) + sizeof(*cmd));
   2132	if (!skb)
   2133		return ERR_PTR(-ENOMEM);
   2134
   2135	tlv = (void *)skb->data;
   2136	tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_VDEV_CREATE_CMD);
   2137	tlv->len = __cpu_to_le16(sizeof(*cmd));
   2138	cmd = (void *)tlv->value;
   2139	cmd->vdev_id = __cpu_to_le32(vdev_id);
   2140	cmd->vdev_type = __cpu_to_le32(vdev_type);
   2141	cmd->vdev_subtype = __cpu_to_le32(vdev_subtype);
   2142	ether_addr_copy(cmd->vdev_macaddr.addr, mac_addr);
   2143
   2144	ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv vdev create\n");
   2145	return skb;
   2146}
   2147
   2148static struct sk_buff *
   2149ath10k_wmi_tlv_op_gen_vdev_delete(struct ath10k *ar, u32 vdev_id)
   2150{
   2151	struct wmi_vdev_delete_cmd *cmd;
   2152	struct wmi_tlv *tlv;
   2153	struct sk_buff *skb;
   2154
   2155	skb = ath10k_wmi_alloc_skb(ar, sizeof(*tlv) + sizeof(*cmd));
   2156	if (!skb)
   2157		return ERR_PTR(-ENOMEM);
   2158
   2159	tlv = (void *)skb->data;
   2160	tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_VDEV_DELETE_CMD);
   2161	tlv->len = __cpu_to_le16(sizeof(*cmd));
   2162	cmd = (void *)tlv->value;
   2163	cmd->vdev_id = __cpu_to_le32(vdev_id);
   2164
   2165	ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv vdev delete\n");
   2166	return skb;
   2167}
   2168
   2169static struct sk_buff *
   2170ath10k_wmi_tlv_op_gen_vdev_start(struct ath10k *ar,
   2171				 const struct wmi_vdev_start_request_arg *arg,
   2172				 bool restart)
   2173{
   2174	struct wmi_tlv_vdev_start_cmd *cmd;
   2175	struct wmi_channel *ch;
   2176	struct wmi_tlv *tlv;
   2177	struct sk_buff *skb;
   2178	size_t len;
   2179	void *ptr;
   2180	u32 flags = 0;
   2181
   2182	if (WARN_ON(arg->hidden_ssid && !arg->ssid))
   2183		return ERR_PTR(-EINVAL);
   2184	if (WARN_ON(arg->ssid_len > sizeof(cmd->ssid.ssid)))
   2185		return ERR_PTR(-EINVAL);
   2186
   2187	len = (sizeof(*tlv) + sizeof(*cmd)) +
   2188	      (sizeof(*tlv) + sizeof(*ch)) +
   2189	      (sizeof(*tlv) + 0);
   2190	skb = ath10k_wmi_alloc_skb(ar, len);
   2191	if (!skb)
   2192		return ERR_PTR(-ENOMEM);
   2193
   2194	if (arg->hidden_ssid)
   2195		flags |= WMI_VDEV_START_HIDDEN_SSID;
   2196	if (arg->pmf_enabled)
   2197		flags |= WMI_VDEV_START_PMF_ENABLED;
   2198
   2199	ptr = (void *)skb->data;
   2200
   2201	tlv = ptr;
   2202	tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_VDEV_START_REQUEST_CMD);
   2203	tlv->len = __cpu_to_le16(sizeof(*cmd));
   2204	cmd = (void *)tlv->value;
   2205	cmd->vdev_id = __cpu_to_le32(arg->vdev_id);
   2206	cmd->bcn_intval = __cpu_to_le32(arg->bcn_intval);
   2207	cmd->dtim_period = __cpu_to_le32(arg->dtim_period);
   2208	cmd->flags = __cpu_to_le32(flags);
   2209	cmd->bcn_tx_rate = __cpu_to_le32(arg->bcn_tx_rate);
   2210	cmd->bcn_tx_power = __cpu_to_le32(arg->bcn_tx_power);
   2211	cmd->disable_hw_ack = __cpu_to_le32(arg->disable_hw_ack);
   2212
   2213	if (arg->ssid) {
   2214		cmd->ssid.ssid_len = __cpu_to_le32(arg->ssid_len);
   2215		memcpy(cmd->ssid.ssid, arg->ssid, arg->ssid_len);
   2216	}
   2217
   2218	ptr += sizeof(*tlv);
   2219	ptr += sizeof(*cmd);
   2220
   2221	tlv = ptr;
   2222	tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_CHANNEL);
   2223	tlv->len = __cpu_to_le16(sizeof(*ch));
   2224	ch = (void *)tlv->value;
   2225	ath10k_wmi_put_wmi_channel(ar, ch, &arg->channel);
   2226
   2227	ptr += sizeof(*tlv);
   2228	ptr += sizeof(*ch);
   2229
   2230	tlv = ptr;
   2231	tlv->tag = __cpu_to_le16(WMI_TLV_TAG_ARRAY_STRUCT);
   2232	tlv->len = 0;
   2233
   2234	/* Note: This is a nested TLV containing:
   2235	 * [wmi_tlv][wmi_p2p_noa_descriptor][wmi_tlv]..
   2236	 */
   2237
   2238	ptr += sizeof(*tlv);
   2239	ptr += 0;
   2240
   2241	ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv vdev start\n");
   2242	return skb;
   2243}
   2244
   2245static struct sk_buff *
   2246ath10k_wmi_tlv_op_gen_vdev_stop(struct ath10k *ar, u32 vdev_id)
   2247{
   2248	struct wmi_vdev_stop_cmd *cmd;
   2249	struct wmi_tlv *tlv;
   2250	struct sk_buff *skb;
   2251
   2252	skb = ath10k_wmi_alloc_skb(ar, sizeof(*tlv) + sizeof(*cmd));
   2253	if (!skb)
   2254		return ERR_PTR(-ENOMEM);
   2255
   2256	tlv = (void *)skb->data;
   2257	tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_VDEV_STOP_CMD);
   2258	tlv->len = __cpu_to_le16(sizeof(*cmd));
   2259	cmd = (void *)tlv->value;
   2260	cmd->vdev_id = __cpu_to_le32(vdev_id);
   2261
   2262	ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv vdev stop\n");
   2263	return skb;
   2264}
   2265
   2266static struct sk_buff *
   2267ath10k_wmi_tlv_op_gen_vdev_up(struct ath10k *ar, u32 vdev_id, u32 aid,
   2268			      const u8 *bssid)
   2269
   2270{
   2271	struct wmi_vdev_up_cmd *cmd;
   2272	struct wmi_tlv *tlv;
   2273	struct sk_buff *skb;
   2274
   2275	skb = ath10k_wmi_alloc_skb(ar, sizeof(*tlv) + sizeof(*cmd));
   2276	if (!skb)
   2277		return ERR_PTR(-ENOMEM);
   2278
   2279	tlv = (void *)skb->data;
   2280	tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_VDEV_UP_CMD);
   2281	tlv->len = __cpu_to_le16(sizeof(*cmd));
   2282	cmd = (void *)tlv->value;
   2283	cmd->vdev_id = __cpu_to_le32(vdev_id);
   2284	cmd->vdev_assoc_id = __cpu_to_le32(aid);
   2285	ether_addr_copy(cmd->vdev_bssid.addr, bssid);
   2286
   2287	ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv vdev up\n");
   2288	return skb;
   2289}
   2290
   2291static struct sk_buff *
   2292ath10k_wmi_tlv_op_gen_vdev_down(struct ath10k *ar, u32 vdev_id)
   2293{
   2294	struct wmi_vdev_down_cmd *cmd;
   2295	struct wmi_tlv *tlv;
   2296	struct sk_buff *skb;
   2297
   2298	skb = ath10k_wmi_alloc_skb(ar, sizeof(*tlv) + sizeof(*cmd));
   2299	if (!skb)
   2300		return ERR_PTR(-ENOMEM);
   2301
   2302	tlv = (void *)skb->data;
   2303	tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_VDEV_DOWN_CMD);
   2304	tlv->len = __cpu_to_le16(sizeof(*cmd));
   2305	cmd = (void *)tlv->value;
   2306	cmd->vdev_id = __cpu_to_le32(vdev_id);
   2307
   2308	ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv vdev down\n");
   2309	return skb;
   2310}
   2311
   2312static struct sk_buff *
   2313ath10k_wmi_tlv_op_gen_vdev_set_param(struct ath10k *ar, u32 vdev_id,
   2314				     u32 param_id, u32 param_value)
   2315{
   2316	struct wmi_vdev_set_param_cmd *cmd;
   2317	struct wmi_tlv *tlv;
   2318	struct sk_buff *skb;
   2319
   2320	skb = ath10k_wmi_alloc_skb(ar, sizeof(*tlv) + sizeof(*cmd));
   2321	if (!skb)
   2322		return ERR_PTR(-ENOMEM);
   2323
   2324	tlv = (void *)skb->data;
   2325	tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_VDEV_SET_PARAM_CMD);
   2326	tlv->len = __cpu_to_le16(sizeof(*cmd));
   2327	cmd = (void *)tlv->value;
   2328	cmd->vdev_id = __cpu_to_le32(vdev_id);
   2329	cmd->param_id = __cpu_to_le32(param_id);
   2330	cmd->param_value = __cpu_to_le32(param_value);
   2331
   2332	ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv vdev %d set param %d value 0x%x\n",
   2333		   vdev_id, param_id, param_value);
   2334	return skb;
   2335}
   2336
   2337static struct sk_buff *
   2338ath10k_wmi_tlv_op_gen_vdev_install_key(struct ath10k *ar,
   2339				       const struct wmi_vdev_install_key_arg *arg)
   2340{
   2341	struct wmi_vdev_install_key_cmd *cmd;
   2342	struct wmi_tlv *tlv;
   2343	struct sk_buff *skb;
   2344	size_t len;
   2345	void *ptr;
   2346
   2347	if (arg->key_cipher == ar->wmi_key_cipher[WMI_CIPHER_NONE] &&
   2348	    arg->key_data)
   2349		return ERR_PTR(-EINVAL);
   2350	if (arg->key_cipher != ar->wmi_key_cipher[WMI_CIPHER_NONE] &&
   2351	    !arg->key_data)
   2352		return ERR_PTR(-EINVAL);
   2353
   2354	len = sizeof(*tlv) + sizeof(*cmd) +
   2355	      sizeof(*tlv) + roundup(arg->key_len, sizeof(__le32));
   2356	skb = ath10k_wmi_alloc_skb(ar, len);
   2357	if (!skb)
   2358		return ERR_PTR(-ENOMEM);
   2359
   2360	ptr = (void *)skb->data;
   2361	tlv = ptr;
   2362	tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_VDEV_INSTALL_KEY_CMD);
   2363	tlv->len = __cpu_to_le16(sizeof(*cmd));
   2364	cmd = (void *)tlv->value;
   2365	cmd->vdev_id = __cpu_to_le32(arg->vdev_id);
   2366	cmd->key_idx = __cpu_to_le32(arg->key_idx);
   2367	cmd->key_flags = __cpu_to_le32(arg->key_flags);
   2368	cmd->key_cipher = __cpu_to_le32(arg->key_cipher);
   2369	cmd->key_len = __cpu_to_le32(arg->key_len);
   2370	cmd->key_txmic_len = __cpu_to_le32(arg->key_txmic_len);
   2371	cmd->key_rxmic_len = __cpu_to_le32(arg->key_rxmic_len);
   2372
   2373	if (arg->macaddr)
   2374		ether_addr_copy(cmd->peer_macaddr.addr, arg->macaddr);
   2375
   2376	ptr += sizeof(*tlv);
   2377	ptr += sizeof(*cmd);
   2378
   2379	tlv = ptr;
   2380	tlv->tag = __cpu_to_le16(WMI_TLV_TAG_ARRAY_BYTE);
   2381	tlv->len = __cpu_to_le16(roundup(arg->key_len, sizeof(__le32)));
   2382	if (arg->key_data)
   2383		memcpy(tlv->value, arg->key_data, arg->key_len);
   2384
   2385	ptr += sizeof(*tlv);
   2386	ptr += roundup(arg->key_len, sizeof(__le32));
   2387
   2388	ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv vdev install key\n");
   2389	return skb;
   2390}
   2391
   2392static void *ath10k_wmi_tlv_put_uapsd_ac(struct ath10k *ar, void *ptr,
   2393					 const struct wmi_sta_uapsd_auto_trig_arg *arg)
   2394{
   2395	struct wmi_sta_uapsd_auto_trig_param *ac;
   2396	struct wmi_tlv *tlv;
   2397
   2398	tlv = ptr;
   2399	tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_STA_UAPSD_AUTO_TRIG_PARAM);
   2400	tlv->len = __cpu_to_le16(sizeof(*ac));
   2401	ac = (void *)tlv->value;
   2402
   2403	ac->wmm_ac = __cpu_to_le32(arg->wmm_ac);
   2404	ac->user_priority = __cpu_to_le32(arg->user_priority);
   2405	ac->service_interval = __cpu_to_le32(arg->service_interval);
   2406	ac->suspend_interval = __cpu_to_le32(arg->suspend_interval);
   2407	ac->delay_interval = __cpu_to_le32(arg->delay_interval);
   2408
   2409	ath10k_dbg(ar, ATH10K_DBG_WMI,
   2410		   "wmi tlv vdev sta uapsd auto trigger ac %d prio %d svc int %d susp int %d delay int %d\n",
   2411		   ac->wmm_ac, ac->user_priority, ac->service_interval,
   2412		   ac->suspend_interval, ac->delay_interval);
   2413
   2414	return ptr + sizeof(*tlv) + sizeof(*ac);
   2415}
   2416
   2417static struct sk_buff *
   2418ath10k_wmi_tlv_op_gen_vdev_sta_uapsd(struct ath10k *ar, u32 vdev_id,
   2419				     const u8 peer_addr[ETH_ALEN],
   2420				     const struct wmi_sta_uapsd_auto_trig_arg *args,
   2421				     u32 num_ac)
   2422{
   2423	struct wmi_sta_uapsd_auto_trig_cmd_fixed_param *cmd;
   2424	struct wmi_sta_uapsd_auto_trig_param *ac;
   2425	struct wmi_tlv *tlv;
   2426	struct sk_buff *skb;
   2427	size_t len;
   2428	size_t ac_tlv_len;
   2429	void *ptr;
   2430	int i;
   2431
   2432	ac_tlv_len = num_ac * (sizeof(*tlv) + sizeof(*ac));
   2433	len = sizeof(*tlv) + sizeof(*cmd) +
   2434	      sizeof(*tlv) + ac_tlv_len;
   2435	skb = ath10k_wmi_alloc_skb(ar, len);
   2436	if (!skb)
   2437		return ERR_PTR(-ENOMEM);
   2438
   2439	ptr = (void *)skb->data;
   2440	tlv = ptr;
   2441	tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_STA_UAPSD_AUTO_TRIG_CMD);
   2442	tlv->len = __cpu_to_le16(sizeof(*cmd));
   2443	cmd = (void *)tlv->value;
   2444	cmd->vdev_id = __cpu_to_le32(vdev_id);
   2445	cmd->num_ac = __cpu_to_le32(num_ac);
   2446	ether_addr_copy(cmd->peer_macaddr.addr, peer_addr);
   2447
   2448	ptr += sizeof(*tlv);
   2449	ptr += sizeof(*cmd);
   2450
   2451	tlv = ptr;
   2452	tlv->tag = __cpu_to_le16(WMI_TLV_TAG_ARRAY_STRUCT);
   2453	tlv->len = __cpu_to_le16(ac_tlv_len);
   2454	ac = (void *)tlv->value;
   2455
   2456	ptr += sizeof(*tlv);
   2457	for (i = 0; i < num_ac; i++)
   2458		ptr = ath10k_wmi_tlv_put_uapsd_ac(ar, ptr, &args[i]);
   2459
   2460	ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv vdev sta uapsd auto trigger\n");
   2461	return skb;
   2462}
   2463
   2464static void *ath10k_wmi_tlv_put_wmm(void *ptr,
   2465				    const struct wmi_wmm_params_arg *arg)
   2466{
   2467	struct wmi_wmm_params *wmm;
   2468	struct wmi_tlv *tlv;
   2469
   2470	tlv = ptr;
   2471	tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_WMM_PARAMS);
   2472	tlv->len = __cpu_to_le16(sizeof(*wmm));
   2473	wmm = (void *)tlv->value;
   2474	ath10k_wmi_set_wmm_param(wmm, arg);
   2475
   2476	return ptr + sizeof(*tlv) + sizeof(*wmm);
   2477}
   2478
   2479static struct sk_buff *
   2480ath10k_wmi_tlv_op_gen_vdev_wmm_conf(struct ath10k *ar, u32 vdev_id,
   2481				    const struct wmi_wmm_params_all_arg *arg)
   2482{
   2483	struct wmi_tlv_vdev_set_wmm_cmd *cmd;
   2484	struct wmi_tlv *tlv;
   2485	struct sk_buff *skb;
   2486	size_t len;
   2487	void *ptr;
   2488
   2489	len = sizeof(*tlv) + sizeof(*cmd);
   2490	skb = ath10k_wmi_alloc_skb(ar, len);
   2491	if (!skb)
   2492		return ERR_PTR(-ENOMEM);
   2493
   2494	ptr = (void *)skb->data;
   2495	tlv = ptr;
   2496	tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_VDEV_SET_WMM_PARAMS_CMD);
   2497	tlv->len = __cpu_to_le16(sizeof(*cmd));
   2498	cmd = (void *)tlv->value;
   2499	cmd->vdev_id = __cpu_to_le32(vdev_id);
   2500
   2501	ath10k_wmi_set_wmm_param(&cmd->vdev_wmm_params[0].params, &arg->ac_be);
   2502	ath10k_wmi_set_wmm_param(&cmd->vdev_wmm_params[1].params, &arg->ac_bk);
   2503	ath10k_wmi_set_wmm_param(&cmd->vdev_wmm_params[2].params, &arg->ac_vi);
   2504	ath10k_wmi_set_wmm_param(&cmd->vdev_wmm_params[3].params, &arg->ac_vo);
   2505
   2506	ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv vdev wmm conf\n");
   2507	return skb;
   2508}
   2509
   2510static struct sk_buff *
   2511ath10k_wmi_tlv_op_gen_sta_keepalive(struct ath10k *ar,
   2512				    const struct wmi_sta_keepalive_arg *arg)
   2513{
   2514	struct wmi_tlv_sta_keepalive_cmd *cmd;
   2515	struct wmi_sta_keepalive_arp_resp *arp;
   2516	struct sk_buff *skb;
   2517	struct wmi_tlv *tlv;
   2518	void *ptr;
   2519	size_t len;
   2520
   2521	len = sizeof(*tlv) + sizeof(*cmd) +
   2522	      sizeof(*tlv) + sizeof(*arp);
   2523	skb = ath10k_wmi_alloc_skb(ar, len);
   2524	if (!skb)
   2525		return ERR_PTR(-ENOMEM);
   2526
   2527	ptr = (void *)skb->data;
   2528	tlv = ptr;
   2529	tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_STA_KEEPALIVE_CMD);
   2530	tlv->len = __cpu_to_le16(sizeof(*cmd));
   2531	cmd = (void *)tlv->value;
   2532	cmd->vdev_id = __cpu_to_le32(arg->vdev_id);
   2533	cmd->enabled = __cpu_to_le32(arg->enabled);
   2534	cmd->method = __cpu_to_le32(arg->method);
   2535	cmd->interval = __cpu_to_le32(arg->interval);
   2536
   2537	ptr += sizeof(*tlv);
   2538	ptr += sizeof(*cmd);
   2539
   2540	tlv = ptr;
   2541	tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_STA_KEEPALVE_ARP_RESPONSE);
   2542	tlv->len = __cpu_to_le16(sizeof(*arp));
   2543	arp = (void *)tlv->value;
   2544
   2545	arp->src_ip4_addr = arg->src_ip4_addr;
   2546	arp->dest_ip4_addr = arg->dest_ip4_addr;
   2547	ether_addr_copy(arp->dest_mac_addr.addr, arg->dest_mac_addr);
   2548
   2549	ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv sta keepalive vdev %d enabled %d method %d interval %d\n",
   2550		   arg->vdev_id, arg->enabled, arg->method, arg->interval);
   2551	return skb;
   2552}
   2553
   2554static struct sk_buff *
   2555ath10k_wmi_tlv_op_gen_peer_create(struct ath10k *ar, u32 vdev_id,
   2556				  const u8 peer_addr[ETH_ALEN],
   2557				  enum wmi_peer_type peer_type)
   2558{
   2559	struct wmi_tlv_peer_create_cmd *cmd;
   2560	struct wmi_tlv *tlv;
   2561	struct sk_buff *skb;
   2562
   2563	skb = ath10k_wmi_alloc_skb(ar, sizeof(*tlv) + sizeof(*cmd));
   2564	if (!skb)
   2565		return ERR_PTR(-ENOMEM);
   2566
   2567	tlv = (void *)skb->data;
   2568	tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_PEER_CREATE_CMD);
   2569	tlv->len = __cpu_to_le16(sizeof(*cmd));
   2570	cmd = (void *)tlv->value;
   2571	cmd->vdev_id = __cpu_to_le32(vdev_id);
   2572	cmd->peer_type = __cpu_to_le32(peer_type);
   2573	ether_addr_copy(cmd->peer_addr.addr, peer_addr);
   2574
   2575	ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv peer create\n");
   2576	return skb;
   2577}
   2578
   2579static struct sk_buff *
   2580ath10k_wmi_tlv_op_gen_peer_delete(struct ath10k *ar, u32 vdev_id,
   2581				  const u8 peer_addr[ETH_ALEN])
   2582{
   2583	struct wmi_peer_delete_cmd *cmd;
   2584	struct wmi_tlv *tlv;
   2585	struct sk_buff *skb;
   2586
   2587	skb = ath10k_wmi_alloc_skb(ar, sizeof(*tlv) + sizeof(*cmd));
   2588	if (!skb)
   2589		return ERR_PTR(-ENOMEM);
   2590
   2591	tlv = (void *)skb->data;
   2592	tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_PEER_DELETE_CMD);
   2593	tlv->len = __cpu_to_le16(sizeof(*cmd));
   2594	cmd = (void *)tlv->value;
   2595	cmd->vdev_id = __cpu_to_le32(vdev_id);
   2596	ether_addr_copy(cmd->peer_macaddr.addr, peer_addr);
   2597
   2598	ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv peer delete\n");
   2599	return skb;
   2600}
   2601
   2602static struct sk_buff *
   2603ath10k_wmi_tlv_op_gen_peer_flush(struct ath10k *ar, u32 vdev_id,
   2604				 const u8 peer_addr[ETH_ALEN], u32 tid_bitmap)
   2605{
   2606	struct wmi_peer_flush_tids_cmd *cmd;
   2607	struct wmi_tlv *tlv;
   2608	struct sk_buff *skb;
   2609
   2610	skb = ath10k_wmi_alloc_skb(ar, sizeof(*tlv) + sizeof(*cmd));
   2611	if (!skb)
   2612		return ERR_PTR(-ENOMEM);
   2613
   2614	tlv = (void *)skb->data;
   2615	tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_PEER_FLUSH_TIDS_CMD);
   2616	tlv->len = __cpu_to_le16(sizeof(*cmd));
   2617	cmd = (void *)tlv->value;
   2618	cmd->vdev_id = __cpu_to_le32(vdev_id);
   2619	cmd->peer_tid_bitmap = __cpu_to_le32(tid_bitmap);
   2620	ether_addr_copy(cmd->peer_macaddr.addr, peer_addr);
   2621
   2622	ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv peer flush\n");
   2623	return skb;
   2624}
   2625
   2626static struct sk_buff *
   2627ath10k_wmi_tlv_op_gen_peer_set_param(struct ath10k *ar, u32 vdev_id,
   2628				     const u8 *peer_addr,
   2629				     enum wmi_peer_param param_id,
   2630				     u32 param_value)
   2631{
   2632	struct wmi_peer_set_param_cmd *cmd;
   2633	struct wmi_tlv *tlv;
   2634	struct sk_buff *skb;
   2635
   2636	skb = ath10k_wmi_alloc_skb(ar, sizeof(*tlv) + sizeof(*cmd));
   2637	if (!skb)
   2638		return ERR_PTR(-ENOMEM);
   2639
   2640	tlv = (void *)skb->data;
   2641	tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_PEER_SET_PARAM_CMD);
   2642	tlv->len = __cpu_to_le16(sizeof(*cmd));
   2643	cmd = (void *)tlv->value;
   2644	cmd->vdev_id = __cpu_to_le32(vdev_id);
   2645	cmd->param_id = __cpu_to_le32(param_id);
   2646	cmd->param_value = __cpu_to_le32(param_value);
   2647	ether_addr_copy(cmd->peer_macaddr.addr, peer_addr);
   2648
   2649	ath10k_dbg(ar, ATH10K_DBG_WMI,
   2650		   "wmi tlv vdev %d peer %pM set param %d value 0x%x\n",
   2651		   vdev_id, peer_addr, param_id, param_value);
   2652	return skb;
   2653}
   2654
   2655static struct sk_buff *
   2656ath10k_wmi_tlv_op_gen_peer_assoc(struct ath10k *ar,
   2657				 const struct wmi_peer_assoc_complete_arg *arg)
   2658{
   2659	struct wmi_tlv_peer_assoc_cmd *cmd;
   2660	struct wmi_vht_rate_set *vht_rate;
   2661	struct wmi_tlv *tlv;
   2662	struct sk_buff *skb;
   2663	size_t len, legacy_rate_len, ht_rate_len;
   2664	void *ptr;
   2665
   2666	if (arg->peer_mpdu_density > 16)
   2667		return ERR_PTR(-EINVAL);
   2668	if (arg->peer_legacy_rates.num_rates > MAX_SUPPORTED_RATES)
   2669		return ERR_PTR(-EINVAL);
   2670	if (arg->peer_ht_rates.num_rates > MAX_SUPPORTED_RATES)
   2671		return ERR_PTR(-EINVAL);
   2672
   2673	legacy_rate_len = roundup(arg->peer_legacy_rates.num_rates,
   2674				  sizeof(__le32));
   2675	ht_rate_len = roundup(arg->peer_ht_rates.num_rates, sizeof(__le32));
   2676	len = (sizeof(*tlv) + sizeof(*cmd)) +
   2677	      (sizeof(*tlv) + legacy_rate_len) +
   2678	      (sizeof(*tlv) + ht_rate_len) +
   2679	      (sizeof(*tlv) + sizeof(*vht_rate));
   2680	skb = ath10k_wmi_alloc_skb(ar, len);
   2681	if (!skb)
   2682		return ERR_PTR(-ENOMEM);
   2683
   2684	ptr = (void *)skb->data;
   2685	tlv = ptr;
   2686	tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_PEER_ASSOC_COMPLETE_CMD);
   2687	tlv->len = __cpu_to_le16(sizeof(*cmd));
   2688	cmd = (void *)tlv->value;
   2689
   2690	cmd->vdev_id = __cpu_to_le32(arg->vdev_id);
   2691	cmd->new_assoc = __cpu_to_le32(arg->peer_reassoc ? 0 : 1);
   2692	cmd->assoc_id = __cpu_to_le32(arg->peer_aid);
   2693	cmd->flags = __cpu_to_le32(arg->peer_flags);
   2694	cmd->caps = __cpu_to_le32(arg->peer_caps);
   2695	cmd->listen_intval = __cpu_to_le32(arg->peer_listen_intval);
   2696	cmd->ht_caps = __cpu_to_le32(arg->peer_ht_caps);
   2697	cmd->max_mpdu = __cpu_to_le32(arg->peer_max_mpdu);
   2698	cmd->mpdu_density = __cpu_to_le32(arg->peer_mpdu_density);
   2699	cmd->rate_caps = __cpu_to_le32(arg->peer_rate_caps);
   2700	cmd->nss = __cpu_to_le32(arg->peer_num_spatial_streams);
   2701	cmd->vht_caps = __cpu_to_le32(arg->peer_vht_caps);
   2702	cmd->phy_mode = __cpu_to_le32(arg->peer_phymode);
   2703	cmd->num_legacy_rates = __cpu_to_le32(arg->peer_legacy_rates.num_rates);
   2704	cmd->num_ht_rates = __cpu_to_le32(arg->peer_ht_rates.num_rates);
   2705	ether_addr_copy(cmd->mac_addr.addr, arg->addr);
   2706
   2707	ptr += sizeof(*tlv);
   2708	ptr += sizeof(*cmd);
   2709
   2710	tlv = ptr;
   2711	tlv->tag = __cpu_to_le16(WMI_TLV_TAG_ARRAY_BYTE);
   2712	tlv->len = __cpu_to_le16(legacy_rate_len);
   2713	memcpy(tlv->value, arg->peer_legacy_rates.rates,
   2714	       arg->peer_legacy_rates.num_rates);
   2715
   2716	ptr += sizeof(*tlv);
   2717	ptr += legacy_rate_len;
   2718
   2719	tlv = ptr;
   2720	tlv->tag = __cpu_to_le16(WMI_TLV_TAG_ARRAY_BYTE);
   2721	tlv->len = __cpu_to_le16(ht_rate_len);
   2722	memcpy(tlv->value, arg->peer_ht_rates.rates,
   2723	       arg->peer_ht_rates.num_rates);
   2724
   2725	ptr += sizeof(*tlv);
   2726	ptr += ht_rate_len;
   2727
   2728	tlv = ptr;
   2729	tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_VHT_RATE_SET);
   2730	tlv->len = __cpu_to_le16(sizeof(*vht_rate));
   2731	vht_rate = (void *)tlv->value;
   2732
   2733	vht_rate->rx_max_rate = __cpu_to_le32(arg->peer_vht_rates.rx_max_rate);
   2734	vht_rate->rx_mcs_set = __cpu_to_le32(arg->peer_vht_rates.rx_mcs_set);
   2735	vht_rate->tx_max_rate = __cpu_to_le32(arg->peer_vht_rates.tx_max_rate);
   2736	vht_rate->tx_mcs_set = __cpu_to_le32(arg->peer_vht_rates.tx_mcs_set);
   2737
   2738	ptr += sizeof(*tlv);
   2739	ptr += sizeof(*vht_rate);
   2740
   2741	ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv peer assoc\n");
   2742	return skb;
   2743}
   2744
   2745static struct sk_buff *
   2746ath10k_wmi_tlv_op_gen_set_psmode(struct ath10k *ar, u32 vdev_id,
   2747				 enum wmi_sta_ps_mode psmode)
   2748{
   2749	struct wmi_sta_powersave_mode_cmd *cmd;
   2750	struct wmi_tlv *tlv;
   2751	struct sk_buff *skb;
   2752
   2753	skb = ath10k_wmi_alloc_skb(ar, sizeof(*tlv) + sizeof(*cmd));
   2754	if (!skb)
   2755		return ERR_PTR(-ENOMEM);
   2756
   2757	tlv = (void *)skb->data;
   2758	tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_STA_POWERSAVE_MODE_CMD);
   2759	tlv->len = __cpu_to_le16(sizeof(*cmd));
   2760	cmd = (void *)tlv->value;
   2761	cmd->vdev_id = __cpu_to_le32(vdev_id);
   2762	cmd->sta_ps_mode = __cpu_to_le32(psmode);
   2763
   2764	ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv set psmode\n");
   2765	return skb;
   2766}
   2767
   2768static struct sk_buff *
   2769ath10k_wmi_tlv_op_gen_set_sta_ps(struct ath10k *ar, u32 vdev_id,
   2770				 enum wmi_sta_powersave_param param_id,
   2771				 u32 param_value)
   2772{
   2773	struct wmi_sta_powersave_param_cmd *cmd;
   2774	struct wmi_tlv *tlv;
   2775	struct sk_buff *skb;
   2776
   2777	skb = ath10k_wmi_alloc_skb(ar, sizeof(*tlv) + sizeof(*cmd));
   2778	if (!skb)
   2779		return ERR_PTR(-ENOMEM);
   2780
   2781	tlv = (void *)skb->data;
   2782	tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_STA_POWERSAVE_PARAM_CMD);
   2783	tlv->len = __cpu_to_le16(sizeof(*cmd));
   2784	cmd = (void *)tlv->value;
   2785	cmd->vdev_id = __cpu_to_le32(vdev_id);
   2786	cmd->param_id = __cpu_to_le32(param_id);
   2787	cmd->param_value = __cpu_to_le32(param_value);
   2788
   2789	ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv set sta ps\n");
   2790	return skb;
   2791}
   2792
   2793static struct sk_buff *
   2794ath10k_wmi_tlv_op_gen_set_ap_ps(struct ath10k *ar, u32 vdev_id, const u8 *mac,
   2795				enum wmi_ap_ps_peer_param param_id, u32 value)
   2796{
   2797	struct wmi_ap_ps_peer_cmd *cmd;
   2798	struct wmi_tlv *tlv;
   2799	struct sk_buff *skb;
   2800
   2801	if (!mac)
   2802		return ERR_PTR(-EINVAL);
   2803
   2804	skb = ath10k_wmi_alloc_skb(ar, sizeof(*tlv) + sizeof(*cmd));
   2805	if (!skb)
   2806		return ERR_PTR(-ENOMEM);
   2807
   2808	tlv = (void *)skb->data;
   2809	tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_AP_PS_PEER_CMD);
   2810	tlv->len = __cpu_to_le16(sizeof(*cmd));
   2811	cmd = (void *)tlv->value;
   2812	cmd->vdev_id = __cpu_to_le32(vdev_id);
   2813	cmd->param_id = __cpu_to_le32(param_id);
   2814	cmd->param_value = __cpu_to_le32(value);
   2815	ether_addr_copy(cmd->peer_macaddr.addr, mac);
   2816
   2817	ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv ap ps param\n");
   2818	return skb;
   2819}
   2820
   2821static struct sk_buff *
   2822ath10k_wmi_tlv_op_gen_scan_chan_list(struct ath10k *ar,
   2823				     const struct wmi_scan_chan_list_arg *arg)
   2824{
   2825	struct wmi_tlv_scan_chan_list_cmd *cmd;
   2826	struct wmi_channel *ci;
   2827	struct wmi_channel_arg *ch;
   2828	struct wmi_tlv *tlv;
   2829	struct sk_buff *skb;
   2830	size_t chans_len, len;
   2831	int i;
   2832	void *ptr, *chans;
   2833
   2834	chans_len = arg->n_channels * (sizeof(*tlv) + sizeof(*ci));
   2835	len = (sizeof(*tlv) + sizeof(*cmd)) +
   2836	      (sizeof(*tlv) + chans_len);
   2837
   2838	skb = ath10k_wmi_alloc_skb(ar, len);
   2839	if (!skb)
   2840		return ERR_PTR(-ENOMEM);
   2841
   2842	ptr = (void *)skb->data;
   2843	tlv = ptr;
   2844	tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_SCAN_CHAN_LIST_CMD);
   2845	tlv->len = __cpu_to_le16(sizeof(*cmd));
   2846	cmd = (void *)tlv->value;
   2847	cmd->num_scan_chans = __cpu_to_le32(arg->n_channels);
   2848
   2849	ptr += sizeof(*tlv);
   2850	ptr += sizeof(*cmd);
   2851
   2852	tlv = ptr;
   2853	tlv->tag = __cpu_to_le16(WMI_TLV_TAG_ARRAY_STRUCT);
   2854	tlv->len = __cpu_to_le16(chans_len);
   2855	chans = (void *)tlv->value;
   2856
   2857	for (i = 0; i < arg->n_channels; i++) {
   2858		ch = &arg->channels[i];
   2859
   2860		tlv = chans;
   2861		tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_CHANNEL);
   2862		tlv->len = __cpu_to_le16(sizeof(*ci));
   2863		ci = (void *)tlv->value;
   2864
   2865		ath10k_wmi_put_wmi_channel(ar, ci, ch);
   2866
   2867		chans += sizeof(*tlv);
   2868		chans += sizeof(*ci);
   2869	}
   2870
   2871	ptr += sizeof(*tlv);
   2872	ptr += chans_len;
   2873
   2874	ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv scan chan list\n");
   2875	return skb;
   2876}
   2877
   2878static struct sk_buff *
   2879ath10k_wmi_tlv_op_gen_scan_prob_req_oui(struct ath10k *ar, u32 prob_req_oui)
   2880{
   2881	struct wmi_scan_prob_req_oui_cmd *cmd;
   2882	struct wmi_tlv *tlv;
   2883	struct sk_buff *skb;
   2884
   2885	skb = ath10k_wmi_alloc_skb(ar, sizeof(*tlv) + sizeof(*cmd));
   2886	if (!skb)
   2887		return ERR_PTR(-ENOMEM);
   2888
   2889	tlv = (void *)skb->data;
   2890	tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_SCAN_PROB_REQ_OUI_CMD);
   2891	tlv->len = __cpu_to_le16(sizeof(*cmd));
   2892	cmd = (void *)tlv->value;
   2893	cmd->prob_req_oui = __cpu_to_le32(prob_req_oui);
   2894
   2895	ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv scan prob req oui\n");
   2896	return skb;
   2897}
   2898
   2899static struct sk_buff *
   2900ath10k_wmi_tlv_op_gen_beacon_dma(struct ath10k *ar, u32 vdev_id,
   2901				 const void *bcn, size_t bcn_len,
   2902				 u32 bcn_paddr, bool dtim_zero,
   2903				 bool deliver_cab)
   2904
   2905{
   2906	struct wmi_bcn_tx_ref_cmd *cmd;
   2907	struct wmi_tlv *tlv;
   2908	struct sk_buff *skb;
   2909	struct ieee80211_hdr *hdr;
   2910	u16 fc;
   2911
   2912	skb = ath10k_wmi_alloc_skb(ar, sizeof(*tlv) + sizeof(*cmd));
   2913	if (!skb)
   2914		return ERR_PTR(-ENOMEM);
   2915
   2916	hdr = (struct ieee80211_hdr *)bcn;
   2917	fc = le16_to_cpu(hdr->frame_control);
   2918
   2919	tlv = (void *)skb->data;
   2920	tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_BCN_SEND_FROM_HOST_CMD);
   2921	tlv->len = __cpu_to_le16(sizeof(*cmd));
   2922	cmd = (void *)tlv->value;
   2923	cmd->vdev_id = __cpu_to_le32(vdev_id);
   2924	cmd->data_len = __cpu_to_le32(bcn_len);
   2925	cmd->data_ptr = __cpu_to_le32(bcn_paddr);
   2926	cmd->msdu_id = 0;
   2927	cmd->frame_control = __cpu_to_le32(fc);
   2928	cmd->flags = 0;
   2929
   2930	if (dtim_zero)
   2931		cmd->flags |= __cpu_to_le32(WMI_BCN_TX_REF_FLAG_DTIM_ZERO);
   2932
   2933	if (deliver_cab)
   2934		cmd->flags |= __cpu_to_le32(WMI_BCN_TX_REF_FLAG_DELIVER_CAB);
   2935
   2936	ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv beacon dma\n");
   2937	return skb;
   2938}
   2939
   2940static struct sk_buff *
   2941ath10k_wmi_tlv_op_gen_pdev_set_wmm(struct ath10k *ar,
   2942				   const struct wmi_wmm_params_all_arg *arg)
   2943{
   2944	struct wmi_tlv_pdev_set_wmm_cmd *cmd;
   2945	struct wmi_wmm_params *wmm;
   2946	struct wmi_tlv *tlv;
   2947	struct sk_buff *skb;
   2948	size_t len;
   2949	void *ptr;
   2950
   2951	len = (sizeof(*tlv) + sizeof(*cmd)) +
   2952	      (4 * (sizeof(*tlv) + sizeof(*wmm)));
   2953	skb = ath10k_wmi_alloc_skb(ar, len);
   2954	if (!skb)
   2955		return ERR_PTR(-ENOMEM);
   2956
   2957	ptr = (void *)skb->data;
   2958
   2959	tlv = ptr;
   2960	tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_PDEV_SET_WMM_PARAMS_CMD);
   2961	tlv->len = __cpu_to_le16(sizeof(*cmd));
   2962	cmd = (void *)tlv->value;
   2963
   2964	/* nothing to set here */
   2965
   2966	ptr += sizeof(*tlv);
   2967	ptr += sizeof(*cmd);
   2968
   2969	ptr = ath10k_wmi_tlv_put_wmm(ptr, &arg->ac_be);
   2970	ptr = ath10k_wmi_tlv_put_wmm(ptr, &arg->ac_bk);
   2971	ptr = ath10k_wmi_tlv_put_wmm(ptr, &arg->ac_vi);
   2972	ptr = ath10k_wmi_tlv_put_wmm(ptr, &arg->ac_vo);
   2973
   2974	ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv pdev set wmm\n");
   2975	return skb;
   2976}
   2977
   2978static struct sk_buff *
   2979ath10k_wmi_tlv_op_gen_request_stats(struct ath10k *ar, u32 stats_mask)
   2980{
   2981	struct wmi_request_stats_cmd *cmd;
   2982	struct wmi_tlv *tlv;
   2983	struct sk_buff *skb;
   2984
   2985	skb = ath10k_wmi_alloc_skb(ar, sizeof(*tlv) + sizeof(*cmd));
   2986	if (!skb)
   2987		return ERR_PTR(-ENOMEM);
   2988
   2989	tlv = (void *)skb->data;
   2990	tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_REQUEST_STATS_CMD);
   2991	tlv->len = __cpu_to_le16(sizeof(*cmd));
   2992	cmd = (void *)tlv->value;
   2993	cmd->stats_id = __cpu_to_le32(stats_mask);
   2994
   2995	ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv request stats\n");
   2996	return skb;
   2997}
   2998
   2999static struct sk_buff *
   3000ath10k_wmi_tlv_op_gen_request_peer_stats_info(struct ath10k *ar,
   3001					      u32 vdev_id,
   3002					      enum wmi_peer_stats_info_request_type type,
   3003					      u8 *addr,
   3004					      u32 reset)
   3005{
   3006	struct wmi_tlv_request_peer_stats_info *cmd;
   3007	struct wmi_tlv *tlv;
   3008	struct sk_buff *skb;
   3009
   3010	skb = ath10k_wmi_alloc_skb(ar, sizeof(*tlv) + sizeof(*cmd));
   3011	if (!skb)
   3012		return ERR_PTR(-ENOMEM);
   3013
   3014	tlv = (void *)skb->data;
   3015	tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_REQUEST_PEER_STATS_INFO_CMD);
   3016	tlv->len = __cpu_to_le16(sizeof(*cmd));
   3017	cmd = (void *)tlv->value;
   3018	cmd->vdev_id = __cpu_to_le32(vdev_id);
   3019	cmd->request_type = __cpu_to_le32(type);
   3020
   3021	if (type == WMI_REQUEST_ONE_PEER_STATS_INFO)
   3022		ether_addr_copy(cmd->peer_macaddr.addr, addr);
   3023
   3024	cmd->reset_after_request = __cpu_to_le32(reset);
   3025	ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv request peer stats info\n");
   3026	return skb;
   3027}
   3028
   3029static int
   3030ath10k_wmi_tlv_op_cleanup_mgmt_tx_send(struct ath10k *ar,
   3031				       struct sk_buff *msdu)
   3032{
   3033	struct ath10k_skb_cb *cb = ATH10K_SKB_CB(msdu);
   3034	struct ath10k_wmi *wmi = &ar->wmi;
   3035
   3036	idr_remove(&wmi->mgmt_pending_tx, cb->msdu_id);
   3037
   3038	return 0;
   3039}
   3040
   3041static int
   3042ath10k_wmi_mgmt_tx_alloc_msdu_id(struct ath10k *ar, struct sk_buff *skb,
   3043				 dma_addr_t paddr)
   3044{
   3045	struct ath10k_wmi *wmi = &ar->wmi;
   3046	struct ath10k_mgmt_tx_pkt_addr *pkt_addr;
   3047	int ret;
   3048
   3049	pkt_addr = kmalloc(sizeof(*pkt_addr), GFP_ATOMIC);
   3050	if (!pkt_addr)
   3051		return -ENOMEM;
   3052
   3053	pkt_addr->vaddr = skb;
   3054	pkt_addr->paddr = paddr;
   3055
   3056	spin_lock_bh(&ar->data_lock);
   3057	ret = idr_alloc(&wmi->mgmt_pending_tx, pkt_addr, 0,
   3058			wmi->mgmt_max_num_pending_tx, GFP_ATOMIC);
   3059	spin_unlock_bh(&ar->data_lock);
   3060
   3061	ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi mgmt tx alloc msdu_id ret %d\n", ret);
   3062	return ret;
   3063}
   3064
   3065static struct sk_buff *
   3066ath10k_wmi_tlv_op_gen_mgmt_tx_send(struct ath10k *ar, struct sk_buff *msdu,
   3067				   dma_addr_t paddr)
   3068{
   3069	struct ath10k_skb_cb *cb = ATH10K_SKB_CB(msdu);
   3070	struct wmi_tlv_mgmt_tx_cmd *cmd;
   3071	struct ieee80211_hdr *hdr;
   3072	struct ath10k_vif *arvif;
   3073	u32 buf_len = msdu->len;
   3074	struct wmi_tlv *tlv;
   3075	struct sk_buff *skb;
   3076	int len, desc_id;
   3077	u32 vdev_id;
   3078	void *ptr;
   3079
   3080	if (!cb->vif)
   3081		return ERR_PTR(-EINVAL);
   3082
   3083	hdr = (struct ieee80211_hdr *)msdu->data;
   3084	arvif = (void *)cb->vif->drv_priv;
   3085	vdev_id = arvif->vdev_id;
   3086
   3087	if (WARN_ON_ONCE(!ieee80211_is_mgmt(hdr->frame_control) &&
   3088			 (!(ieee80211_is_nullfunc(hdr->frame_control) ||
   3089			 ieee80211_is_qos_nullfunc(hdr->frame_control)))))
   3090		return ERR_PTR(-EINVAL);
   3091
   3092	len = sizeof(*cmd) + 2 * sizeof(*tlv);
   3093
   3094	if ((ieee80211_is_action(hdr->frame_control) ||
   3095	     ieee80211_is_deauth(hdr->frame_control) ||
   3096	     ieee80211_is_disassoc(hdr->frame_control)) &&
   3097	     ieee80211_has_protected(hdr->frame_control)) {
   3098		skb_put(msdu, IEEE80211_CCMP_MIC_LEN);
   3099		buf_len += IEEE80211_CCMP_MIC_LEN;
   3100	}
   3101
   3102	buf_len = min_t(u32, buf_len, WMI_TLV_MGMT_TX_FRAME_MAX_LEN);
   3103	buf_len = round_up(buf_len, 4);
   3104
   3105	len += buf_len;
   3106	len = round_up(len, 4);
   3107	skb = ath10k_wmi_alloc_skb(ar, len);
   3108	if (!skb)
   3109		return ERR_PTR(-ENOMEM);
   3110
   3111	desc_id = ath10k_wmi_mgmt_tx_alloc_msdu_id(ar, msdu, paddr);
   3112	if (desc_id < 0)
   3113		goto err_free_skb;
   3114
   3115	cb->msdu_id = desc_id;
   3116
   3117	ptr = (void *)skb->data;
   3118	tlv = ptr;
   3119	tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_MGMT_TX_CMD);
   3120	tlv->len = __cpu_to_le16(sizeof(*cmd));
   3121	cmd = (void *)tlv->value;
   3122	cmd->vdev_id = __cpu_to_le32(vdev_id);
   3123	cmd->desc_id = __cpu_to_le32(desc_id);
   3124	cmd->chanfreq = 0;
   3125	cmd->buf_len = __cpu_to_le32(buf_len);
   3126	cmd->frame_len = __cpu_to_le32(msdu->len);
   3127	cmd->paddr = __cpu_to_le64(paddr);
   3128
   3129	ptr += sizeof(*tlv);
   3130	ptr += sizeof(*cmd);
   3131
   3132	tlv = ptr;
   3133	tlv->tag = __cpu_to_le16(WMI_TLV_TAG_ARRAY_BYTE);
   3134	tlv->len = __cpu_to_le16(buf_len);
   3135
   3136	ptr += sizeof(*tlv);
   3137	memcpy(ptr, msdu->data, buf_len);
   3138
   3139	return skb;
   3140
   3141err_free_skb:
   3142	dev_kfree_skb(skb);
   3143	return ERR_PTR(desc_id);
   3144}
   3145
   3146static struct sk_buff *
   3147ath10k_wmi_tlv_op_gen_force_fw_hang(struct ath10k *ar,
   3148				    enum wmi_force_fw_hang_type type,
   3149				    u32 delay_ms)
   3150{
   3151	struct wmi_force_fw_hang_cmd *cmd;
   3152	struct wmi_tlv *tlv;
   3153	struct sk_buff *skb;
   3154
   3155	skb = ath10k_wmi_alloc_skb(ar, sizeof(*tlv) + sizeof(*cmd));
   3156	if (!skb)
   3157		return ERR_PTR(-ENOMEM);
   3158
   3159	tlv = (void *)skb->data;
   3160	tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_FORCE_FW_HANG_CMD);
   3161	tlv->len = __cpu_to_le16(sizeof(*cmd));
   3162	cmd = (void *)tlv->value;
   3163	cmd->type = __cpu_to_le32(type);
   3164	cmd->delay_ms = __cpu_to_le32(delay_ms);
   3165
   3166	ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv force fw hang\n");
   3167	return skb;
   3168}
   3169
   3170static struct sk_buff *
   3171ath10k_wmi_tlv_op_gen_dbglog_cfg(struct ath10k *ar, u64 module_enable,
   3172				 u32 log_level)
   3173{
   3174	struct wmi_tlv_dbglog_cmd *cmd;
   3175	struct wmi_tlv *tlv;
   3176	struct sk_buff *skb;
   3177	size_t len, bmap_len;
   3178	u32 value;
   3179	void *ptr;
   3180
   3181	if (module_enable) {
   3182		value = WMI_TLV_DBGLOG_LOG_LEVEL_VALUE(
   3183				module_enable,
   3184				WMI_TLV_DBGLOG_LOG_LEVEL_VERBOSE);
   3185	} else {
   3186		value = WMI_TLV_DBGLOG_LOG_LEVEL_VALUE(
   3187				WMI_TLV_DBGLOG_ALL_MODULES,
   3188				WMI_TLV_DBGLOG_LOG_LEVEL_WARN);
   3189	}
   3190
   3191	bmap_len = 0;
   3192	len = sizeof(*tlv) + sizeof(*cmd) + sizeof(*tlv) + bmap_len;
   3193	skb = ath10k_wmi_alloc_skb(ar, len);
   3194	if (!skb)
   3195		return ERR_PTR(-ENOMEM);
   3196
   3197	ptr = (void *)skb->data;
   3198
   3199	tlv = ptr;
   3200	tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_DEBUG_LOG_CONFIG_CMD);
   3201	tlv->len = __cpu_to_le16(sizeof(*cmd));
   3202	cmd = (void *)tlv->value;
   3203	cmd->param = __cpu_to_le32(WMI_TLV_DBGLOG_PARAM_LOG_LEVEL);
   3204	cmd->value = __cpu_to_le32(value);
   3205
   3206	ptr += sizeof(*tlv);
   3207	ptr += sizeof(*cmd);
   3208
   3209	tlv = ptr;
   3210	tlv->tag = __cpu_to_le16(WMI_TLV_TAG_ARRAY_UINT32);
   3211	tlv->len = __cpu_to_le16(bmap_len);
   3212
   3213	/* nothing to do here */
   3214
   3215	ptr += sizeof(*tlv);
   3216	ptr += sizeof(bmap_len);
   3217
   3218	ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv dbglog value 0x%08x\n", value);
   3219	return skb;
   3220}
   3221
   3222static struct sk_buff *
   3223ath10k_wmi_tlv_op_gen_pktlog_enable(struct ath10k *ar, u32 filter)
   3224{
   3225	struct wmi_tlv_pktlog_enable *cmd;
   3226	struct wmi_tlv *tlv;
   3227	struct sk_buff *skb;
   3228	void *ptr;
   3229	size_t len;
   3230
   3231	len = sizeof(*tlv) + sizeof(*cmd);
   3232	skb = ath10k_wmi_alloc_skb(ar, len);
   3233	if (!skb)
   3234		return ERR_PTR(-ENOMEM);
   3235
   3236	ptr = (void *)skb->data;
   3237	tlv = ptr;
   3238	tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_PDEV_PKTLOG_ENABLE_CMD);
   3239	tlv->len = __cpu_to_le16(sizeof(*cmd));
   3240	cmd = (void *)tlv->value;
   3241	cmd->filter = __cpu_to_le32(filter);
   3242
   3243	ptr += sizeof(*tlv);
   3244	ptr += sizeof(*cmd);
   3245
   3246	ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv pktlog enable filter 0x%08x\n",
   3247		   filter);
   3248	return skb;
   3249}
   3250
   3251static struct sk_buff *
   3252ath10k_wmi_tlv_op_gen_pdev_get_temperature(struct ath10k *ar)
   3253{
   3254	struct wmi_tlv_pdev_get_temp_cmd *cmd;
   3255	struct wmi_tlv *tlv;
   3256	struct sk_buff *skb;
   3257
   3258	skb = ath10k_wmi_alloc_skb(ar, sizeof(*tlv) + sizeof(*cmd));
   3259	if (!skb)
   3260		return ERR_PTR(-ENOMEM);
   3261
   3262	tlv = (void *)skb->data;
   3263	tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_PDEV_GET_TEMPERATURE_CMD);
   3264	tlv->len = __cpu_to_le16(sizeof(*cmd));
   3265	cmd = (void *)tlv->value;
   3266	ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi pdev get temperature tlv\n");
   3267	return skb;
   3268}
   3269
   3270static struct sk_buff *
   3271ath10k_wmi_tlv_op_gen_pktlog_disable(struct ath10k *ar)
   3272{
   3273	struct wmi_tlv_pktlog_disable *cmd;
   3274	struct wmi_tlv *tlv;
   3275	struct sk_buff *skb;
   3276	void *ptr;
   3277	size_t len;
   3278
   3279	len = sizeof(*tlv) + sizeof(*cmd);
   3280	skb = ath10k_wmi_alloc_skb(ar, len);
   3281	if (!skb)
   3282		return ERR_PTR(-ENOMEM);
   3283
   3284	ptr = (void *)skb->data;
   3285	tlv = ptr;
   3286	tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_PDEV_PKTLOG_DISABLE_CMD);
   3287	tlv->len = __cpu_to_le16(sizeof(*cmd));
   3288	cmd = (void *)tlv->value;
   3289
   3290	ptr += sizeof(*tlv);
   3291	ptr += sizeof(*cmd);
   3292
   3293	ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv pktlog disable\n");
   3294	return skb;
   3295}
   3296
   3297static struct sk_buff *
   3298ath10k_wmi_tlv_op_gen_bcn_tmpl(struct ath10k *ar, u32 vdev_id,
   3299			       u32 tim_ie_offset, struct sk_buff *bcn,
   3300			       u32 prb_caps, u32 prb_erp, void *prb_ies,
   3301			       size_t prb_ies_len)
   3302{
   3303	struct wmi_tlv_bcn_tmpl_cmd *cmd;
   3304	struct wmi_tlv_bcn_prb_info *info;
   3305	struct wmi_tlv *tlv;
   3306	struct sk_buff *skb;
   3307	void *ptr;
   3308	size_t len;
   3309
   3310	if (WARN_ON(prb_ies_len > 0 && !prb_ies))
   3311		return ERR_PTR(-EINVAL);
   3312
   3313	len = sizeof(*tlv) + sizeof(*cmd) +
   3314	      sizeof(*tlv) + sizeof(*info) + prb_ies_len +
   3315	      sizeof(*tlv) + roundup(bcn->len, 4);
   3316	skb = ath10k_wmi_alloc_skb(ar, len);
   3317	if (!skb)
   3318		return ERR_PTR(-ENOMEM);
   3319
   3320	ptr = (void *)skb->data;
   3321	tlv = ptr;
   3322	tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_BCN_TMPL_CMD);
   3323	tlv->len = __cpu_to_le16(sizeof(*cmd));
   3324	cmd = (void *)tlv->value;
   3325	cmd->vdev_id = __cpu_to_le32(vdev_id);
   3326	cmd->tim_ie_offset = __cpu_to_le32(tim_ie_offset);
   3327	cmd->buf_len = __cpu_to_le32(bcn->len);
   3328
   3329	ptr += sizeof(*tlv);
   3330	ptr += sizeof(*cmd);
   3331
   3332	/* FIXME: prb_ies_len should be probably aligned to 4byte boundary but
   3333	 * then it is then impossible to pass original ie len.
   3334	 * This chunk is not used yet so if setting probe resp template yields
   3335	 * problems with beaconing or crashes firmware look here.
   3336	 */
   3337	tlv = ptr;
   3338	tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_BCN_PRB_INFO);
   3339	tlv->len = __cpu_to_le16(sizeof(*info) + prb_ies_len);
   3340	info = (void *)tlv->value;
   3341	info->caps = __cpu_to_le32(prb_caps);
   3342	info->erp = __cpu_to_le32(prb_erp);
   3343	memcpy(info->ies, prb_ies, prb_ies_len);
   3344
   3345	ptr += sizeof(*tlv);
   3346	ptr += sizeof(*info);
   3347	ptr += prb_ies_len;
   3348
   3349	tlv = ptr;
   3350	tlv->tag = __cpu_to_le16(WMI_TLV_TAG_ARRAY_BYTE);
   3351	tlv->len = __cpu_to_le16(roundup(bcn->len, 4));
   3352	memcpy(tlv->value, bcn->data, bcn->len);
   3353
   3354	/* FIXME: Adjust TSF? */
   3355
   3356	ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv bcn tmpl vdev_id %i\n",
   3357		   vdev_id);
   3358	return skb;
   3359}
   3360
   3361static struct sk_buff *
   3362ath10k_wmi_tlv_op_gen_prb_tmpl(struct ath10k *ar, u32 vdev_id,
   3363			       struct sk_buff *prb)
   3364{
   3365	struct wmi_tlv_prb_tmpl_cmd *cmd;
   3366	struct wmi_tlv_bcn_prb_info *info;
   3367	struct wmi_tlv *tlv;
   3368	struct sk_buff *skb;
   3369	void *ptr;
   3370	size_t len;
   3371
   3372	len = sizeof(*tlv) + sizeof(*cmd) +
   3373	      sizeof(*tlv) + sizeof(*info) +
   3374	      sizeof(*tlv) + roundup(prb->len, 4);
   3375	skb = ath10k_wmi_alloc_skb(ar, len);
   3376	if (!skb)
   3377		return ERR_PTR(-ENOMEM);
   3378
   3379	ptr = (void *)skb->data;
   3380	tlv = ptr;
   3381	tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_PRB_TMPL_CMD);
   3382	tlv->len = __cpu_to_le16(sizeof(*cmd));
   3383	cmd = (void *)tlv->value;
   3384	cmd->vdev_id = __cpu_to_le32(vdev_id);
   3385	cmd->buf_len = __cpu_to_le32(prb->len);
   3386
   3387	ptr += sizeof(*tlv);
   3388	ptr += sizeof(*cmd);
   3389
   3390	tlv = ptr;
   3391	tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_BCN_PRB_INFO);
   3392	tlv->len = __cpu_to_le16(sizeof(*info));
   3393	info = (void *)tlv->value;
   3394	info->caps = 0;
   3395	info->erp = 0;
   3396
   3397	ptr += sizeof(*tlv);
   3398	ptr += sizeof(*info);
   3399
   3400	tlv = ptr;
   3401	tlv->tag = __cpu_to_le16(WMI_TLV_TAG_ARRAY_BYTE);
   3402	tlv->len = __cpu_to_le16(roundup(prb->len, 4));
   3403	memcpy(tlv->value, prb->data, prb->len);
   3404
   3405	ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv prb tmpl vdev_id %i\n",
   3406		   vdev_id);
   3407	return skb;
   3408}
   3409
   3410static struct sk_buff *
   3411ath10k_wmi_tlv_op_gen_p2p_go_bcn_ie(struct ath10k *ar, u32 vdev_id,
   3412				    const u8 *p2p_ie)
   3413{
   3414	struct wmi_tlv_p2p_go_bcn_ie *cmd;
   3415	struct wmi_tlv *tlv;
   3416	struct sk_buff *skb;
   3417	void *ptr;
   3418	size_t len;
   3419
   3420	len = sizeof(*tlv) + sizeof(*cmd) +
   3421	      sizeof(*tlv) + roundup(p2p_ie[1] + 2, 4);
   3422	skb = ath10k_wmi_alloc_skb(ar, len);
   3423	if (!skb)
   3424		return ERR_PTR(-ENOMEM);
   3425
   3426	ptr = (void *)skb->data;
   3427	tlv = ptr;
   3428	tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_P2P_GO_SET_BEACON_IE);
   3429	tlv->len = __cpu_to_le16(sizeof(*cmd));
   3430	cmd = (void *)tlv->value;
   3431	cmd->vdev_id = __cpu_to_le32(vdev_id);
   3432	cmd->ie_len = __cpu_to_le32(p2p_ie[1] + 2);
   3433
   3434	ptr += sizeof(*tlv);
   3435	ptr += sizeof(*cmd);
   3436
   3437	tlv = ptr;
   3438	tlv->tag = __cpu_to_le16(WMI_TLV_TAG_ARRAY_BYTE);
   3439	tlv->len = __cpu_to_le16(roundup(p2p_ie[1] + 2, 4));
   3440	memcpy(tlv->value, p2p_ie, p2p_ie[1] + 2);
   3441
   3442	ptr += sizeof(*tlv);
   3443	ptr += roundup(p2p_ie[1] + 2, 4);
   3444
   3445	ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv p2p go bcn ie for vdev %i\n",
   3446		   vdev_id);
   3447	return skb;
   3448}
   3449
   3450static struct sk_buff *
   3451ath10k_wmi_tlv_op_gen_update_fw_tdls_state(struct ath10k *ar, u32 vdev_id,
   3452					   enum wmi_tdls_state state)
   3453{
   3454	struct wmi_tdls_set_state_cmd *cmd;
   3455	struct wmi_tlv *tlv;
   3456	struct sk_buff *skb;
   3457	void *ptr;
   3458	size_t len;
   3459	/* Set to options from wmi_tlv_tdls_options,
   3460	 * for now none of them are enabled.
   3461	 */
   3462	u32 options = 0;
   3463
   3464	if (test_bit(WMI_SERVICE_TDLS_UAPSD_BUFFER_STA, ar->wmi.svc_map))
   3465		options |=  WMI_TLV_TDLS_BUFFER_STA_EN;
   3466
   3467	/* WMI_TDLS_ENABLE_ACTIVE_EXTERNAL_CONTROL means firm will handle TDLS
   3468	 * link inactivity detecting logic.
   3469	 */
   3470	if (state == WMI_TDLS_ENABLE_ACTIVE)
   3471		state = WMI_TDLS_ENABLE_ACTIVE_EXTERNAL_CONTROL;
   3472
   3473	len = sizeof(*tlv) + sizeof(*cmd);
   3474	skb = ath10k_wmi_alloc_skb(ar, len);
   3475	if (!skb)
   3476		return ERR_PTR(-ENOMEM);
   3477
   3478	ptr = (void *)skb->data;
   3479	tlv = ptr;
   3480	tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_TDLS_SET_STATE_CMD);
   3481	tlv->len = __cpu_to_le16(sizeof(*cmd));
   3482
   3483	cmd = (void *)tlv->value;
   3484	cmd->vdev_id = __cpu_to_le32(vdev_id);
   3485	cmd->state = __cpu_to_le32(state);
   3486	cmd->notification_interval_ms = __cpu_to_le32(5000);
   3487	cmd->tx_discovery_threshold = __cpu_to_le32(100);
   3488	cmd->tx_teardown_threshold = __cpu_to_le32(5);
   3489	cmd->rssi_teardown_threshold = __cpu_to_le32(-75);
   3490	cmd->rssi_delta = __cpu_to_le32(-20);
   3491	cmd->tdls_options = __cpu_to_le32(options);
   3492	cmd->tdls_peer_traffic_ind_window = __cpu_to_le32(2);
   3493	cmd->tdls_peer_traffic_response_timeout_ms = __cpu_to_le32(5000);
   3494	cmd->tdls_puapsd_mask = __cpu_to_le32(0xf);
   3495	cmd->tdls_puapsd_inactivity_time_ms = __cpu_to_le32(0);
   3496	cmd->tdls_puapsd_rx_frame_threshold = __cpu_to_le32(10);
   3497
   3498	ptr += sizeof(*tlv);
   3499	ptr += sizeof(*cmd);
   3500
   3501	ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv update fw tdls state %d for vdev %i\n",
   3502		   state, vdev_id);
   3503	return skb;
   3504}
   3505
   3506static u32 ath10k_wmi_tlv_prepare_peer_qos(u8 uapsd_queues, u8 sp)
   3507{
   3508	u32 peer_qos = 0;
   3509
   3510	if (uapsd_queues & IEEE80211_WMM_IE_STA_QOSINFO_AC_VO)
   3511		peer_qos |= WMI_TLV_TDLS_PEER_QOS_AC_VO;
   3512	if (uapsd_queues & IEEE80211_WMM_IE_STA_QOSINFO_AC_VI)
   3513		peer_qos |= WMI_TLV_TDLS_PEER_QOS_AC_VI;
   3514	if (uapsd_queues & IEEE80211_WMM_IE_STA_QOSINFO_AC_BK)
   3515		peer_qos |= WMI_TLV_TDLS_PEER_QOS_AC_BK;
   3516	if (uapsd_queues & IEEE80211_WMM_IE_STA_QOSINFO_AC_BE)
   3517		peer_qos |= WMI_TLV_TDLS_PEER_QOS_AC_BE;
   3518
   3519	peer_qos |= SM(sp, WMI_TLV_TDLS_PEER_SP);
   3520
   3521	return peer_qos;
   3522}
   3523
   3524static struct sk_buff *
   3525ath10k_wmi_tlv_op_gen_tdls_peer_update(struct ath10k *ar,
   3526				       const struct wmi_tdls_peer_update_cmd_arg *arg,
   3527				       const struct wmi_tdls_peer_capab_arg *cap,
   3528				       const struct wmi_channel_arg *chan_arg)
   3529{
   3530	struct wmi_tdls_peer_update_cmd *cmd;
   3531	struct wmi_tdls_peer_capab *peer_cap;
   3532	struct wmi_channel *chan;
   3533	struct wmi_tlv *tlv;
   3534	struct sk_buff *skb;
   3535	u32 peer_qos;
   3536	void *ptr;
   3537	int len;
   3538	int i;
   3539
   3540	len = sizeof(*tlv) + sizeof(*cmd) +
   3541	      sizeof(*tlv) + sizeof(*peer_cap) +
   3542	      sizeof(*tlv) + cap->peer_chan_len * sizeof(*chan);
   3543
   3544	skb = ath10k_wmi_alloc_skb(ar, len);
   3545	if (!skb)
   3546		return ERR_PTR(-ENOMEM);
   3547
   3548	ptr = (void *)skb->data;
   3549	tlv = ptr;
   3550	tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_TDLS_PEER_UPDATE_CMD);
   3551	tlv->len = __cpu_to_le16(sizeof(*cmd));
   3552
   3553	cmd = (void *)tlv->value;
   3554	cmd->vdev_id = __cpu_to_le32(arg->vdev_id);
   3555	ether_addr_copy(cmd->peer_macaddr.addr, arg->addr);
   3556	cmd->peer_state = __cpu_to_le32(arg->peer_state);
   3557
   3558	ptr += sizeof(*tlv);
   3559	ptr += sizeof(*cmd);
   3560
   3561	tlv = ptr;
   3562	tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_TDLS_PEER_CAPABILITIES);
   3563	tlv->len = __cpu_to_le16(sizeof(*peer_cap));
   3564	peer_cap = (void *)tlv->value;
   3565	peer_qos = ath10k_wmi_tlv_prepare_peer_qos(cap->peer_uapsd_queues,
   3566						   cap->peer_max_sp);
   3567	peer_cap->peer_qos = __cpu_to_le32(peer_qos);
   3568	peer_cap->buff_sta_support = __cpu_to_le32(cap->buff_sta_support);
   3569	peer_cap->off_chan_support = __cpu_to_le32(cap->off_chan_support);
   3570	peer_cap->peer_curr_operclass = __cpu_to_le32(cap->peer_curr_operclass);
   3571	peer_cap->self_curr_operclass = __cpu_to_le32(cap->self_curr_operclass);
   3572	peer_cap->peer_chan_len = __cpu_to_le32(cap->peer_chan_len);
   3573	peer_cap->peer_operclass_len = __cpu_to_le32(cap->peer_operclass_len);
   3574
   3575	for (i = 0; i < WMI_TDLS_MAX_SUPP_OPER_CLASSES; i++)
   3576		peer_cap->peer_operclass[i] = cap->peer_operclass[i];
   3577
   3578	peer_cap->is_peer_responder = __cpu_to_le32(cap->is_peer_responder);
   3579	peer_cap->pref_offchan_num = __cpu_to_le32(cap->pref_offchan_num);
   3580	peer_cap->pref_offchan_bw = __cpu_to_le32(cap->pref_offchan_bw);
   3581
   3582	ptr += sizeof(*tlv);
   3583	ptr += sizeof(*peer_cap);
   3584
   3585	tlv = ptr;
   3586	tlv->tag = __cpu_to_le16(WMI_TLV_TAG_ARRAY_STRUCT);
   3587	tlv->len = __cpu_to_le16(cap->peer_chan_len * sizeof(*chan));
   3588
   3589	ptr += sizeof(*tlv);
   3590
   3591	for (i = 0; i < cap->peer_chan_len; i++) {
   3592		tlv = ptr;
   3593		tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_CHANNEL);
   3594		tlv->len = __cpu_to_le16(sizeof(*chan));
   3595		chan = (void *)tlv->value;
   3596		ath10k_wmi_put_wmi_channel(ar, chan, &chan_arg[i]);
   3597
   3598		ptr += sizeof(*tlv);
   3599		ptr += sizeof(*chan);
   3600	}
   3601
   3602	ath10k_dbg(ar, ATH10K_DBG_WMI,
   3603		   "wmi tlv tdls peer update vdev %i state %d n_chans %u\n",
   3604		   arg->vdev_id, arg->peer_state, cap->peer_chan_len);
   3605	return skb;
   3606}
   3607
   3608static struct sk_buff *
   3609ath10k_wmi_tlv_op_gen_pdev_set_quiet_mode(struct ath10k *ar, u32 period,
   3610					  u32 duration, u32 next_offset,
   3611					  u32 enabled)
   3612{
   3613	struct wmi_tlv_set_quiet_cmd *cmd;
   3614	struct wmi_tlv *tlv;
   3615	struct sk_buff *skb;
   3616
   3617	skb = ath10k_wmi_alloc_skb(ar, sizeof(*tlv) + sizeof(*cmd));
   3618	if (!skb)
   3619		return ERR_PTR(-ENOMEM);
   3620
   3621	tlv = (void *)skb->data;
   3622	tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_PDEV_SET_QUIET_CMD);
   3623	tlv->len = __cpu_to_le16(sizeof(*cmd));
   3624	cmd = (void *)tlv->value;
   3625
   3626	/* vdev_id is not in use, set to 0 */
   3627	cmd->vdev_id = __cpu_to_le32(0);
   3628	cmd->period = __cpu_to_le32(period);
   3629	cmd->duration = __cpu_to_le32(duration);
   3630	cmd->next_start = __cpu_to_le32(next_offset);
   3631	cmd->enabled = __cpu_to_le32(enabled);
   3632
   3633	ath10k_dbg(ar, ATH10K_DBG_WMI,
   3634		   "wmi tlv quiet param: period %u duration %u enabled %d\n",
   3635		   period, duration, enabled);
   3636	return skb;
   3637}
   3638
   3639static struct sk_buff *
   3640ath10k_wmi_tlv_op_gen_wow_enable(struct ath10k *ar)
   3641{
   3642	struct wmi_tlv_wow_enable_cmd *cmd;
   3643	struct wmi_tlv *tlv;
   3644	struct sk_buff *skb;
   3645	size_t len;
   3646
   3647	len = sizeof(*tlv) + sizeof(*cmd);
   3648	skb = ath10k_wmi_alloc_skb(ar, len);
   3649	if (!skb)
   3650		return ERR_PTR(-ENOMEM);
   3651
   3652	tlv = (struct wmi_tlv *)skb->data;
   3653	tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_WOW_ENABLE_CMD);
   3654	tlv->len = __cpu_to_le16(sizeof(*cmd));
   3655	cmd = (void *)tlv->value;
   3656
   3657	cmd->enable = __cpu_to_le32(1);
   3658	if (!ar->bus_param.link_can_suspend)
   3659		cmd->pause_iface_config = __cpu_to_le32(WOW_IFACE_PAUSE_DISABLED);
   3660
   3661	ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv wow enable\n");
   3662	return skb;
   3663}
   3664
   3665static struct sk_buff *
   3666ath10k_wmi_tlv_op_gen_wow_add_wakeup_event(struct ath10k *ar,
   3667					   u32 vdev_id,
   3668					   enum wmi_wow_wakeup_event event,
   3669					   u32 enable)
   3670{
   3671	struct wmi_tlv_wow_add_del_event_cmd *cmd;
   3672	struct wmi_tlv *tlv;
   3673	struct sk_buff *skb;
   3674	size_t len;
   3675
   3676	len = sizeof(*tlv) + sizeof(*cmd);
   3677	skb = ath10k_wmi_alloc_skb(ar, len);
   3678	if (!skb)
   3679		return ERR_PTR(-ENOMEM);
   3680
   3681	tlv = (struct wmi_tlv *)skb->data;
   3682	tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_WOW_ADD_DEL_EVT_CMD);
   3683	tlv->len = __cpu_to_le16(sizeof(*cmd));
   3684	cmd = (void *)tlv->value;
   3685
   3686	cmd->vdev_id = __cpu_to_le32(vdev_id);
   3687	cmd->is_add = __cpu_to_le32(enable);
   3688	cmd->event_bitmap = __cpu_to_le32(1 << event);
   3689
   3690	ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv wow add wakeup event %s enable %d vdev_id %d\n",
   3691		   wow_wakeup_event(event), enable, vdev_id);
   3692	return skb;
   3693}
   3694
   3695static struct sk_buff *
   3696ath10k_wmi_tlv_gen_wow_host_wakeup_ind(struct ath10k *ar)
   3697{
   3698	struct wmi_tlv_wow_host_wakeup_ind *cmd;
   3699	struct wmi_tlv *tlv;
   3700	struct sk_buff *skb;
   3701	size_t len;
   3702
   3703	len = sizeof(*tlv) + sizeof(*cmd);
   3704	skb = ath10k_wmi_alloc_skb(ar, len);
   3705	if (!skb)
   3706		return ERR_PTR(-ENOMEM);
   3707
   3708	tlv = (struct wmi_tlv *)skb->data;
   3709	tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_WOW_HOSTWAKEUP_FROM_SLEEP_CMD);
   3710	tlv->len = __cpu_to_le16(sizeof(*cmd));
   3711	cmd = (void *)tlv->value;
   3712
   3713	ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv wow host wakeup ind\n");
   3714	return skb;
   3715}
   3716
   3717static struct sk_buff *
   3718ath10k_wmi_tlv_op_gen_wow_add_pattern(struct ath10k *ar, u32 vdev_id,
   3719				      u32 pattern_id, const u8 *pattern,
   3720				      const u8 *bitmask, int pattern_len,
   3721				      int pattern_offset)
   3722{
   3723	struct wmi_tlv_wow_add_pattern_cmd *cmd;
   3724	struct wmi_tlv_wow_bitmap_pattern *bitmap;
   3725	struct wmi_tlv *tlv;
   3726	struct sk_buff *skb;
   3727	void *ptr;
   3728	size_t len;
   3729
   3730	len = sizeof(*tlv) + sizeof(*cmd) +
   3731	      sizeof(*tlv) +			/* array struct */
   3732	      sizeof(*tlv) + sizeof(*bitmap) +  /* bitmap */
   3733	      sizeof(*tlv) +			/* empty ipv4 sync */
   3734	      sizeof(*tlv) +			/* empty ipv6 sync */
   3735	      sizeof(*tlv) +			/* empty magic */
   3736	      sizeof(*tlv) +			/* empty info timeout */
   3737	      sizeof(*tlv) + sizeof(u32);	/* ratelimit interval */
   3738
   3739	skb = ath10k_wmi_alloc_skb(ar, len);
   3740	if (!skb)
   3741		return ERR_PTR(-ENOMEM);
   3742
   3743	/* cmd */
   3744	ptr = (void *)skb->data;
   3745	tlv = ptr;
   3746	tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_WOW_ADD_PATTERN_CMD);
   3747	tlv->len = __cpu_to_le16(sizeof(*cmd));
   3748	cmd = (void *)tlv->value;
   3749
   3750	cmd->vdev_id = __cpu_to_le32(vdev_id);
   3751	cmd->pattern_id = __cpu_to_le32(pattern_id);
   3752	cmd->pattern_type = __cpu_to_le32(WOW_BITMAP_PATTERN);
   3753
   3754	ptr += sizeof(*tlv);
   3755	ptr += sizeof(*cmd);
   3756
   3757	/* bitmap */
   3758	tlv = ptr;
   3759	tlv->tag = __cpu_to_le16(WMI_TLV_TAG_ARRAY_STRUCT);
   3760	tlv->len = __cpu_to_le16(sizeof(*tlv) + sizeof(*bitmap));
   3761
   3762	ptr += sizeof(*tlv);
   3763
   3764	tlv = ptr;
   3765	tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_WOW_BITMAP_PATTERN_T);
   3766	tlv->len = __cpu_to_le16(sizeof(*bitmap));
   3767	bitmap = (void *)tlv->value;
   3768
   3769	memcpy(bitmap->patternbuf, pattern, pattern_len);
   3770	memcpy(bitmap->bitmaskbuf, bitmask, pattern_len);
   3771	bitmap->pattern_offset = __cpu_to_le32(pattern_offset);
   3772	bitmap->pattern_len = __cpu_to_le32(pattern_len);
   3773	bitmap->bitmask_len = __cpu_to_le32(pattern_len);
   3774	bitmap->pattern_id = __cpu_to_le32(pattern_id);
   3775
   3776	ptr += sizeof(*tlv);
   3777	ptr += sizeof(*bitmap);
   3778
   3779	/* ipv4 sync */
   3780	tlv = ptr;
   3781	tlv->tag = __cpu_to_le16(WMI_TLV_TAG_ARRAY_STRUCT);
   3782	tlv->len = __cpu_to_le16(0);
   3783
   3784	ptr += sizeof(*tlv);
   3785
   3786	/* ipv6 sync */
   3787	tlv = ptr;
   3788	tlv->tag = __cpu_to_le16(WMI_TLV_TAG_ARRAY_STRUCT);
   3789	tlv->len = __cpu_to_le16(0);
   3790
   3791	ptr += sizeof(*tlv);
   3792
   3793	/* magic */
   3794	tlv = ptr;
   3795	tlv->tag = __cpu_to_le16(WMI_TLV_TAG_ARRAY_STRUCT);
   3796	tlv->len = __cpu_to_le16(0);
   3797
   3798	ptr += sizeof(*tlv);
   3799
   3800	/* pattern info timeout */
   3801	tlv = ptr;
   3802	tlv->tag = __cpu_to_le16(WMI_TLV_TAG_ARRAY_UINT32);
   3803	tlv->len = __cpu_to_le16(0);
   3804
   3805	ptr += sizeof(*tlv);
   3806
   3807	/* ratelimit interval */
   3808	tlv = ptr;
   3809	tlv->tag = __cpu_to_le16(WMI_TLV_TAG_ARRAY_UINT32);
   3810	tlv->len = __cpu_to_le16(sizeof(u32));
   3811
   3812	ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv wow add pattern vdev_id %d pattern_id %d, pattern_offset %d\n",
   3813		   vdev_id, pattern_id, pattern_offset);
   3814	return skb;
   3815}
   3816
   3817static struct sk_buff *
   3818ath10k_wmi_tlv_op_gen_wow_del_pattern(struct ath10k *ar, u32 vdev_id,
   3819				      u32 pattern_id)
   3820{
   3821	struct wmi_tlv_wow_del_pattern_cmd *cmd;
   3822	struct wmi_tlv *tlv;
   3823	struct sk_buff *skb;
   3824	size_t len;
   3825
   3826	len = sizeof(*tlv) + sizeof(*cmd);
   3827	skb = ath10k_wmi_alloc_skb(ar, len);
   3828	if (!skb)
   3829		return ERR_PTR(-ENOMEM);
   3830
   3831	tlv = (struct wmi_tlv *)skb->data;
   3832	tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_WOW_DEL_PATTERN_CMD);
   3833	tlv->len = __cpu_to_le16(sizeof(*cmd));
   3834	cmd = (void *)tlv->value;
   3835
   3836	cmd->vdev_id = __cpu_to_le32(vdev_id);
   3837	cmd->pattern_id = __cpu_to_le32(pattern_id);
   3838	cmd->pattern_type = __cpu_to_le32(WOW_BITMAP_PATTERN);
   3839
   3840	ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv wow del pattern vdev_id %d pattern_id %d\n",
   3841		   vdev_id, pattern_id);
   3842	return skb;
   3843}
   3844
   3845/* Request FW to start PNO operation */
   3846static struct sk_buff *
   3847ath10k_wmi_tlv_op_gen_config_pno_start(struct ath10k *ar,
   3848				       u32 vdev_id,
   3849				       struct wmi_pno_scan_req *pno)
   3850{
   3851	struct nlo_configured_parameters *nlo_list;
   3852	struct wmi_tlv_wow_nlo_config_cmd *cmd;
   3853	struct wmi_tlv *tlv;
   3854	struct sk_buff *skb;
   3855	__le32 *channel_list;
   3856	u16 tlv_len;
   3857	size_t len;
   3858	void *ptr;
   3859	u32 i;
   3860
   3861	len = sizeof(*tlv) + sizeof(*cmd) +
   3862	      sizeof(*tlv) +
   3863	      /* TLV place holder for array of structures
   3864	       * nlo_configured_parameters(nlo_list)
   3865	       */
   3866	      sizeof(*tlv);
   3867	      /* TLV place holder for array of uint32 channel_list */
   3868
   3869	len += sizeof(u32) * min_t(u8, pno->a_networks[0].channel_count,
   3870				   WMI_NLO_MAX_CHAN);
   3871	len += sizeof(struct nlo_configured_parameters) *
   3872				min_t(u8, pno->uc_networks_count, WMI_NLO_MAX_SSIDS);
   3873
   3874	skb = ath10k_wmi_alloc_skb(ar, len);
   3875	if (!skb)
   3876		return ERR_PTR(-ENOMEM);
   3877
   3878	ptr = (void *)skb->data;
   3879	tlv = ptr;
   3880	tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_NLO_CONFIG_CMD);
   3881	tlv->len = __cpu_to_le16(sizeof(*cmd));
   3882	cmd = (void *)tlv->value;
   3883
   3884	/* wmi_tlv_wow_nlo_config_cmd parameters*/
   3885	cmd->vdev_id = __cpu_to_le32(pno->vdev_id);
   3886	cmd->flags = __cpu_to_le32(WMI_NLO_CONFIG_START | WMI_NLO_CONFIG_SSID_HIDE_EN);
   3887
   3888	/* current FW does not support min-max range for dwell time */
   3889	cmd->active_dwell_time = __cpu_to_le32(pno->active_max_time);
   3890	cmd->passive_dwell_time = __cpu_to_le32(pno->passive_max_time);
   3891
   3892	if (pno->do_passive_scan)
   3893		cmd->flags |= __cpu_to_le32(WMI_NLO_CONFIG_SCAN_PASSIVE);
   3894
   3895	/* copy scan interval */
   3896	cmd->fast_scan_period = __cpu_to_le32(pno->fast_scan_period);
   3897	cmd->slow_scan_period = __cpu_to_le32(pno->slow_scan_period);
   3898	cmd->fast_scan_max_cycles = __cpu_to_le32(pno->fast_scan_max_cycles);
   3899	cmd->delay_start_time = __cpu_to_le32(pno->delay_start_time);
   3900
   3901	if (pno->enable_pno_scan_randomization) {
   3902		cmd->flags |= __cpu_to_le32(WMI_NLO_CONFIG_SPOOFED_MAC_IN_PROBE_REQ |
   3903				WMI_NLO_CONFIG_RANDOM_SEQ_NO_IN_PROBE_REQ);
   3904		ether_addr_copy(cmd->mac_addr.addr, pno->mac_addr);
   3905		ether_addr_copy(cmd->mac_mask.addr, pno->mac_addr_mask);
   3906	}
   3907
   3908	ptr += sizeof(*tlv);
   3909	ptr += sizeof(*cmd);
   3910
   3911	/* nlo_configured_parameters(nlo_list) */
   3912	cmd->no_of_ssids = __cpu_to_le32(min_t(u8, pno->uc_networks_count,
   3913					       WMI_NLO_MAX_SSIDS));
   3914	tlv_len = __le32_to_cpu(cmd->no_of_ssids) *
   3915		sizeof(struct nlo_configured_parameters);
   3916
   3917	tlv = ptr;
   3918	tlv->tag = __cpu_to_le16(WMI_TLV_TAG_ARRAY_STRUCT);
   3919	tlv->len = __cpu_to_le16(tlv_len);
   3920
   3921	ptr += sizeof(*tlv);
   3922	nlo_list = ptr;
   3923	for (i = 0; i < __le32_to_cpu(cmd->no_of_ssids); i++) {
   3924		tlv = (struct wmi_tlv *)(&nlo_list[i].tlv_header);
   3925		tlv->tag = __cpu_to_le16(WMI_TLV_TAG_ARRAY_BYTE);
   3926		tlv->len = __cpu_to_le16(sizeof(struct nlo_configured_parameters) -
   3927					 sizeof(*tlv));
   3928
   3929		/* copy ssid and it's length */
   3930		nlo_list[i].ssid.valid = __cpu_to_le32(true);
   3931		nlo_list[i].ssid.ssid.ssid_len = pno->a_networks[i].ssid.ssid_len;
   3932		memcpy(nlo_list[i].ssid.ssid.ssid,
   3933		       pno->a_networks[i].ssid.ssid,
   3934		       __le32_to_cpu(nlo_list[i].ssid.ssid.ssid_len));
   3935
   3936		/* copy rssi threshold */
   3937		if (pno->a_networks[i].rssi_threshold &&
   3938		    pno->a_networks[i].rssi_threshold > -300) {
   3939			nlo_list[i].rssi_cond.valid = __cpu_to_le32(true);
   3940			nlo_list[i].rssi_cond.rssi =
   3941				__cpu_to_le32(pno->a_networks[i].rssi_threshold);
   3942		}
   3943
   3944		nlo_list[i].bcast_nw_type.valid = __cpu_to_le32(true);
   3945		nlo_list[i].bcast_nw_type.bcast_nw_type =
   3946			__cpu_to_le32(pno->a_networks[i].bcast_nw_type);
   3947	}
   3948
   3949	ptr += __le32_to_cpu(cmd->no_of_ssids) * sizeof(struct nlo_configured_parameters);
   3950
   3951	/* copy channel info */
   3952	cmd->num_of_channels = __cpu_to_le32(min_t(u8,
   3953						   pno->a_networks[0].channel_count,
   3954						   WMI_NLO_MAX_CHAN));
   3955
   3956	tlv = ptr;
   3957	tlv->tag = __cpu_to_le16(WMI_TLV_TAG_ARRAY_UINT32);
   3958	tlv->len = __cpu_to_le16(__le32_to_cpu(cmd->num_of_channels) *
   3959				 sizeof(u_int32_t));
   3960	ptr += sizeof(*tlv);
   3961
   3962	channel_list = (__le32 *)ptr;
   3963	for (i = 0; i < __le32_to_cpu(cmd->num_of_channels); i++)
   3964		channel_list[i] = __cpu_to_le32(pno->a_networks[0].channels[i]);
   3965
   3966	ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv start pno config vdev_id %d\n",
   3967		   vdev_id);
   3968
   3969	return skb;
   3970}
   3971
   3972/* Request FW to stop ongoing PNO operation */
   3973static struct sk_buff *ath10k_wmi_tlv_op_gen_config_pno_stop(struct ath10k *ar,
   3974							     u32 vdev_id)
   3975{
   3976	struct wmi_tlv_wow_nlo_config_cmd *cmd;
   3977	struct wmi_tlv *tlv;
   3978	struct sk_buff *skb;
   3979	void *ptr;
   3980	size_t len;
   3981
   3982	len = sizeof(*tlv) + sizeof(*cmd) +
   3983	      sizeof(*tlv) +
   3984	      /* TLV place holder for array of structures
   3985	       * nlo_configured_parameters(nlo_list)
   3986	       */
   3987	      sizeof(*tlv);
   3988	      /* TLV place holder for array of uint32 channel_list */
   3989	skb = ath10k_wmi_alloc_skb(ar, len);
   3990	if (!skb)
   3991		return ERR_PTR(-ENOMEM);
   3992
   3993	ptr = (void *)skb->data;
   3994	tlv = ptr;
   3995	tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_NLO_CONFIG_CMD);
   3996	tlv->len = __cpu_to_le16(sizeof(*cmd));
   3997	cmd = (void *)tlv->value;
   3998
   3999	cmd->vdev_id = __cpu_to_le32(vdev_id);
   4000	cmd->flags = __cpu_to_le32(WMI_NLO_CONFIG_STOP);
   4001
   4002	ptr += sizeof(*tlv);
   4003	ptr += sizeof(*cmd);
   4004
   4005	/* nlo_configured_parameters(nlo_list) */
   4006	tlv = ptr;
   4007	tlv->tag = __cpu_to_le16(WMI_TLV_TAG_ARRAY_STRUCT);
   4008	tlv->len = __cpu_to_le16(0);
   4009
   4010	ptr += sizeof(*tlv);
   4011
   4012	/* channel list */
   4013	tlv = ptr;
   4014	tlv->tag = __cpu_to_le16(WMI_TLV_TAG_ARRAY_UINT32);
   4015	tlv->len = __cpu_to_le16(0);
   4016
   4017	ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv stop pno config vdev_id %d\n", vdev_id);
   4018	return skb;
   4019}
   4020
   4021static struct sk_buff *
   4022ath10k_wmi_tlv_op_gen_config_pno(struct ath10k *ar, u32 vdev_id,
   4023				 struct wmi_pno_scan_req *pno_scan)
   4024{
   4025	if (pno_scan->enable)
   4026		return ath10k_wmi_tlv_op_gen_config_pno_start(ar, vdev_id, pno_scan);
   4027	else
   4028		return ath10k_wmi_tlv_op_gen_config_pno_stop(ar, vdev_id);
   4029}
   4030
   4031static struct sk_buff *
   4032ath10k_wmi_tlv_op_gen_adaptive_qcs(struct ath10k *ar, bool enable)
   4033{
   4034	struct wmi_tlv_adaptive_qcs *cmd;
   4035	struct wmi_tlv *tlv;
   4036	struct sk_buff *skb;
   4037	void *ptr;
   4038	size_t len;
   4039
   4040	len = sizeof(*tlv) + sizeof(*cmd);
   4041	skb = ath10k_wmi_alloc_skb(ar, len);
   4042	if (!skb)
   4043		return ERR_PTR(-ENOMEM);
   4044
   4045	ptr = (void *)skb->data;
   4046	tlv = ptr;
   4047	tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_RESMGR_ADAPTIVE_OCS_CMD);
   4048	tlv->len = __cpu_to_le16(sizeof(*cmd));
   4049	cmd = (void *)tlv->value;
   4050	cmd->enable = __cpu_to_le32(enable ? 1 : 0);
   4051
   4052	ptr += sizeof(*tlv);
   4053	ptr += sizeof(*cmd);
   4054
   4055	ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv adaptive qcs %d\n", enable);
   4056	return skb;
   4057}
   4058
   4059static struct sk_buff *
   4060ath10k_wmi_tlv_op_gen_echo(struct ath10k *ar, u32 value)
   4061{
   4062	struct wmi_echo_cmd *cmd;
   4063	struct wmi_tlv *tlv;
   4064	struct sk_buff *skb;
   4065	void *ptr;
   4066	size_t len;
   4067
   4068	len = sizeof(*tlv) + sizeof(*cmd);
   4069	skb = ath10k_wmi_alloc_skb(ar, len);
   4070	if (!skb)
   4071		return ERR_PTR(-ENOMEM);
   4072
   4073	ptr = (void *)skb->data;
   4074	tlv = ptr;
   4075	tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_ECHO_CMD);
   4076	tlv->len = __cpu_to_le16(sizeof(*cmd));
   4077	cmd = (void *)tlv->value;
   4078	cmd->value = cpu_to_le32(value);
   4079
   4080	ptr += sizeof(*tlv);
   4081	ptr += sizeof(*cmd);
   4082
   4083	ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv echo value 0x%08x\n", value);
   4084	return skb;
   4085}
   4086
   4087static struct sk_buff *
   4088ath10k_wmi_tlv_op_gen_vdev_spectral_conf(struct ath10k *ar,
   4089					 const struct wmi_vdev_spectral_conf_arg *arg)
   4090{
   4091	struct wmi_vdev_spectral_conf_cmd *cmd;
   4092	struct sk_buff *skb;
   4093	struct wmi_tlv *tlv;
   4094	void *ptr;
   4095	size_t len;
   4096
   4097	len = sizeof(*tlv) + sizeof(*cmd);
   4098	skb = ath10k_wmi_alloc_skb(ar, len);
   4099	if (!skb)
   4100		return ERR_PTR(-ENOMEM);
   4101
   4102	ptr = (void *)skb->data;
   4103	tlv = ptr;
   4104	tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_VDEV_SPECTRAL_CONFIGURE_CMD);
   4105	tlv->len = __cpu_to_le16(sizeof(*cmd));
   4106	cmd = (void *)tlv->value;
   4107	cmd->vdev_id = __cpu_to_le32(arg->vdev_id);
   4108	cmd->scan_count = __cpu_to_le32(arg->scan_count);
   4109	cmd->scan_period = __cpu_to_le32(arg->scan_period);
   4110	cmd->scan_priority = __cpu_to_le32(arg->scan_priority);
   4111	cmd->scan_fft_size = __cpu_to_le32(arg->scan_fft_size);
   4112	cmd->scan_gc_ena = __cpu_to_le32(arg->scan_gc_ena);
   4113	cmd->scan_restart_ena = __cpu_to_le32(arg->scan_restart_ena);
   4114	cmd->scan_noise_floor_ref = __cpu_to_le32(arg->scan_noise_floor_ref);
   4115	cmd->scan_init_delay = __cpu_to_le32(arg->scan_init_delay);
   4116	cmd->scan_nb_tone_thr = __cpu_to_le32(arg->scan_nb_tone_thr);
   4117	cmd->scan_str_bin_thr = __cpu_to_le32(arg->scan_str_bin_thr);
   4118	cmd->scan_wb_rpt_mode = __cpu_to_le32(arg->scan_wb_rpt_mode);
   4119	cmd->scan_rssi_rpt_mode = __cpu_to_le32(arg->scan_rssi_rpt_mode);
   4120	cmd->scan_rssi_thr = __cpu_to_le32(arg->scan_rssi_thr);
   4121	cmd->scan_pwr_format = __cpu_to_le32(arg->scan_pwr_format);
   4122	cmd->scan_rpt_mode = __cpu_to_le32(arg->scan_rpt_mode);
   4123	cmd->scan_bin_scale = __cpu_to_le32(arg->scan_bin_scale);
   4124	cmd->scan_dbm_adj = __cpu_to_le32(arg->scan_dbm_adj);
   4125	cmd->scan_chn_mask = __cpu_to_le32(arg->scan_chn_mask);
   4126
   4127	return skb;
   4128}
   4129
   4130static struct sk_buff *
   4131ath10k_wmi_tlv_op_gen_vdev_spectral_enable(struct ath10k *ar, u32 vdev_id,
   4132					   u32 trigger, u32 enable)
   4133{
   4134	struct wmi_vdev_spectral_enable_cmd *cmd;
   4135	struct sk_buff *skb;
   4136	struct wmi_tlv *tlv;
   4137	void *ptr;
   4138	size_t len;
   4139
   4140	len = sizeof(*tlv) + sizeof(*cmd);
   4141	skb = ath10k_wmi_alloc_skb(ar, len);
   4142	if (!skb)
   4143		return ERR_PTR(-ENOMEM);
   4144
   4145	ptr = (void *)skb->data;
   4146	tlv = ptr;
   4147	tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_VDEV_SPECTRAL_ENABLE_CMD);
   4148	tlv->len = __cpu_to_le16(sizeof(*cmd));
   4149	cmd = (void *)tlv->value;
   4150	cmd->vdev_id = __cpu_to_le32(vdev_id);
   4151	cmd->trigger_cmd = __cpu_to_le32(trigger);
   4152	cmd->enable_cmd = __cpu_to_le32(enable);
   4153
   4154	return skb;
   4155}
   4156
   4157/****************/
   4158/* TLV mappings */
   4159/****************/
   4160
   4161static struct wmi_cmd_map wmi_tlv_cmd_map = {
   4162	.init_cmdid = WMI_TLV_INIT_CMDID,
   4163	.start_scan_cmdid = WMI_TLV_START_SCAN_CMDID,
   4164	.stop_scan_cmdid = WMI_TLV_STOP_SCAN_CMDID,
   4165	.scan_chan_list_cmdid = WMI_TLV_SCAN_CHAN_LIST_CMDID,
   4166	.scan_sch_prio_tbl_cmdid = WMI_TLV_SCAN_SCH_PRIO_TBL_CMDID,
   4167	.scan_prob_req_oui_cmdid = WMI_TLV_SCAN_PROB_REQ_OUI_CMDID,
   4168	.pdev_set_regdomain_cmdid = WMI_TLV_PDEV_SET_REGDOMAIN_CMDID,
   4169	.pdev_set_channel_cmdid = WMI_TLV_PDEV_SET_CHANNEL_CMDID,
   4170	.pdev_set_param_cmdid = WMI_TLV_PDEV_SET_PARAM_CMDID,
   4171	.pdev_pktlog_enable_cmdid = WMI_TLV_PDEV_PKTLOG_ENABLE_CMDID,
   4172	.pdev_pktlog_disable_cmdid = WMI_TLV_PDEV_PKTLOG_DISABLE_CMDID,
   4173	.pdev_set_wmm_params_cmdid = WMI_TLV_PDEV_SET_WMM_PARAMS_CMDID,
   4174	.pdev_set_ht_cap_ie_cmdid = WMI_TLV_PDEV_SET_HT_CAP_IE_CMDID,
   4175	.pdev_set_vht_cap_ie_cmdid = WMI_TLV_PDEV_SET_VHT_CAP_IE_CMDID,
   4176	.pdev_set_dscp_tid_map_cmdid = WMI_TLV_PDEV_SET_DSCP_TID_MAP_CMDID,
   4177	.pdev_set_quiet_mode_cmdid = WMI_TLV_PDEV_SET_QUIET_MODE_CMDID,
   4178	.pdev_green_ap_ps_enable_cmdid = WMI_TLV_PDEV_GREEN_AP_PS_ENABLE_CMDID,
   4179	.pdev_get_tpc_config_cmdid = WMI_TLV_PDEV_GET_TPC_CONFIG_CMDID,
   4180	.pdev_set_base_macaddr_cmdid = WMI_TLV_PDEV_SET_BASE_MACADDR_CMDID,
   4181	.vdev_create_cmdid = WMI_TLV_VDEV_CREATE_CMDID,
   4182	.vdev_delete_cmdid = WMI_TLV_VDEV_DELETE_CMDID,
   4183	.vdev_start_request_cmdid = WMI_TLV_VDEV_START_REQUEST_CMDID,
   4184	.vdev_restart_request_cmdid = WMI_TLV_VDEV_RESTART_REQUEST_CMDID,
   4185	.vdev_up_cmdid = WMI_TLV_VDEV_UP_CMDID,
   4186	.vdev_stop_cmdid = WMI_TLV_VDEV_STOP_CMDID,
   4187	.vdev_down_cmdid = WMI_TLV_VDEV_DOWN_CMDID,
   4188	.vdev_set_param_cmdid = WMI_TLV_VDEV_SET_PARAM_CMDID,
   4189	.vdev_install_key_cmdid = WMI_TLV_VDEV_INSTALL_KEY_CMDID,
   4190	.peer_create_cmdid = WMI_TLV_PEER_CREATE_CMDID,
   4191	.peer_delete_cmdid = WMI_TLV_PEER_DELETE_CMDID,
   4192	.peer_flush_tids_cmdid = WMI_TLV_PEER_FLUSH_TIDS_CMDID,
   4193	.peer_set_param_cmdid = WMI_TLV_PEER_SET_PARAM_CMDID,
   4194	.peer_assoc_cmdid = WMI_TLV_PEER_ASSOC_CMDID,
   4195	.peer_add_wds_entry_cmdid = WMI_TLV_PEER_ADD_WDS_ENTRY_CMDID,
   4196	.peer_remove_wds_entry_cmdid = WMI_TLV_PEER_REMOVE_WDS_ENTRY_CMDID,
   4197	.peer_mcast_group_cmdid = WMI_TLV_PEER_MCAST_GROUP_CMDID,
   4198	.bcn_tx_cmdid = WMI_TLV_BCN_TX_CMDID,
   4199	.pdev_send_bcn_cmdid = WMI_TLV_PDEV_SEND_BCN_CMDID,
   4200	.bcn_tmpl_cmdid = WMI_TLV_BCN_TMPL_CMDID,
   4201	.bcn_filter_rx_cmdid = WMI_TLV_BCN_FILTER_RX_CMDID,
   4202	.prb_req_filter_rx_cmdid = WMI_TLV_PRB_REQ_FILTER_RX_CMDID,
   4203	.mgmt_tx_cmdid = WMI_TLV_MGMT_TX_CMDID,
   4204	.mgmt_tx_send_cmdid = WMI_TLV_MGMT_TX_SEND_CMD,
   4205	.prb_tmpl_cmdid = WMI_TLV_PRB_TMPL_CMDID,
   4206	.addba_clear_resp_cmdid = WMI_TLV_ADDBA_CLEAR_RESP_CMDID,
   4207	.addba_send_cmdid = WMI_TLV_ADDBA_SEND_CMDID,
   4208	.addba_status_cmdid = WMI_TLV_ADDBA_STATUS_CMDID,
   4209	.delba_send_cmdid = WMI_TLV_DELBA_SEND_CMDID,
   4210	.addba_set_resp_cmdid = WMI_TLV_ADDBA_SET_RESP_CMDID,
   4211	.send_singleamsdu_cmdid = WMI_TLV_SEND_SINGLEAMSDU_CMDID,
   4212	.sta_powersave_mode_cmdid = WMI_TLV_STA_POWERSAVE_MODE_CMDID,
   4213	.sta_powersave_param_cmdid = WMI_TLV_STA_POWERSAVE_PARAM_CMDID,
   4214	.sta_mimo_ps_mode_cmdid = WMI_TLV_STA_MIMO_PS_MODE_CMDID,
   4215	.pdev_dfs_enable_cmdid = WMI_TLV_PDEV_DFS_ENABLE_CMDID,
   4216	.pdev_dfs_disable_cmdid = WMI_TLV_PDEV_DFS_DISABLE_CMDID,
   4217	.roam_scan_mode = WMI_TLV_ROAM_SCAN_MODE,
   4218	.roam_scan_rssi_threshold = WMI_TLV_ROAM_SCAN_RSSI_THRESHOLD,
   4219	.roam_scan_period = WMI_TLV_ROAM_SCAN_PERIOD,
   4220	.roam_scan_rssi_change_threshold =
   4221				WMI_TLV_ROAM_SCAN_RSSI_CHANGE_THRESHOLD,
   4222	.roam_ap_profile = WMI_TLV_ROAM_AP_PROFILE,
   4223	.ofl_scan_add_ap_profile = WMI_TLV_ROAM_AP_PROFILE,
   4224	.ofl_scan_remove_ap_profile = WMI_TLV_OFL_SCAN_REMOVE_AP_PROFILE,
   4225	.ofl_scan_period = WMI_TLV_OFL_SCAN_PERIOD,
   4226	.p2p_dev_set_device_info = WMI_TLV_P2P_DEV_SET_DEVICE_INFO,
   4227	.p2p_dev_set_discoverability = WMI_TLV_P2P_DEV_SET_DISCOVERABILITY,
   4228	.p2p_go_set_beacon_ie = WMI_TLV_P2P_GO_SET_BEACON_IE,
   4229	.p2p_go_set_probe_resp_ie = WMI_TLV_P2P_GO_SET_PROBE_RESP_IE,
   4230	.p2p_set_vendor_ie_data_cmdid = WMI_TLV_P2P_SET_VENDOR_IE_DATA_CMDID,
   4231	.ap_ps_peer_param_cmdid = WMI_TLV_AP_PS_PEER_PARAM_CMDID,
   4232	.ap_ps_peer_uapsd_coex_cmdid = WMI_TLV_AP_PS_PEER_UAPSD_COEX_CMDID,
   4233	.peer_rate_retry_sched_cmdid = WMI_TLV_PEER_RATE_RETRY_SCHED_CMDID,
   4234	.wlan_profile_trigger_cmdid = WMI_TLV_WLAN_PROFILE_TRIGGER_CMDID,
   4235	.wlan_profile_set_hist_intvl_cmdid =
   4236				WMI_TLV_WLAN_PROFILE_SET_HIST_INTVL_CMDID,
   4237	.wlan_profile_get_profile_data_cmdid =
   4238				WMI_TLV_WLAN_PROFILE_GET_PROFILE_DATA_CMDID,
   4239	.wlan_profile_enable_profile_id_cmdid =
   4240				WMI_TLV_WLAN_PROFILE_ENABLE_PROFILE_ID_CMDID,
   4241	.wlan_profile_list_profile_id_cmdid =
   4242				WMI_TLV_WLAN_PROFILE_LIST_PROFILE_ID_CMDID,
   4243	.pdev_suspend_cmdid = WMI_TLV_PDEV_SUSPEND_CMDID,
   4244	.pdev_resume_cmdid = WMI_TLV_PDEV_RESUME_CMDID,
   4245	.add_bcn_filter_cmdid = WMI_TLV_ADD_BCN_FILTER_CMDID,
   4246	.rmv_bcn_filter_cmdid = WMI_TLV_RMV_BCN_FILTER_CMDID,
   4247	.wow_add_wake_pattern_cmdid = WMI_TLV_WOW_ADD_WAKE_PATTERN_CMDID,
   4248	.wow_del_wake_pattern_cmdid = WMI_TLV_WOW_DEL_WAKE_PATTERN_CMDID,
   4249	.wow_enable_disable_wake_event_cmdid =
   4250				WMI_TLV_WOW_ENABLE_DISABLE_WAKE_EVENT_CMDID,
   4251	.wow_enable_cmdid = WMI_TLV_WOW_ENABLE_CMDID,
   4252	.wow_hostwakeup_from_sleep_cmdid =
   4253				WMI_TLV_WOW_HOSTWAKEUP_FROM_SLEEP_CMDID,
   4254	.rtt_measreq_cmdid = WMI_TLV_RTT_MEASREQ_CMDID,
   4255	.rtt_tsf_cmdid = WMI_TLV_RTT_TSF_CMDID,
   4256	.vdev_spectral_scan_configure_cmdid = WMI_TLV_SPECTRAL_SCAN_CONF_CMDID,
   4257	.vdev_spectral_scan_enable_cmdid = WMI_TLV_SPECTRAL_SCAN_ENABLE_CMDID,
   4258	.request_stats_cmdid = WMI_TLV_REQUEST_STATS_CMDID,
   4259	.request_peer_stats_info_cmdid = WMI_TLV_REQUEST_PEER_STATS_INFO_CMDID,
   4260	.set_arp_ns_offload_cmdid = WMI_TLV_SET_ARP_NS_OFFLOAD_CMDID,
   4261	.network_list_offload_config_cmdid =
   4262				WMI_TLV_NETWORK_LIST_OFFLOAD_CONFIG_CMDID,
   4263	.gtk_offload_cmdid = WMI_TLV_GTK_OFFLOAD_CMDID,
   4264	.csa_offload_enable_cmdid = WMI_TLV_CSA_OFFLOAD_ENABLE_CMDID,
   4265	.csa_offload_chanswitch_cmdid = WMI_TLV_CSA_OFFLOAD_CHANSWITCH_CMDID,
   4266	.chatter_set_mode_cmdid = WMI_TLV_CHATTER_SET_MODE_CMDID,
   4267	.peer_tid_addba_cmdid = WMI_TLV_PEER_TID_ADDBA_CMDID,
   4268	.peer_tid_delba_cmdid = WMI_TLV_PEER_TID_DELBA_CMDID,
   4269	.sta_dtim_ps_method_cmdid = WMI_TLV_STA_DTIM_PS_METHOD_CMDID,
   4270	.sta_uapsd_auto_trig_cmdid = WMI_TLV_STA_UAPSD_AUTO_TRIG_CMDID,
   4271	.sta_keepalive_cmd = WMI_TLV_STA_KEEPALIVE_CMDID,
   4272	.echo_cmdid = WMI_TLV_ECHO_CMDID,
   4273	.pdev_utf_cmdid = WMI_TLV_PDEV_UTF_CMDID,
   4274	.dbglog_cfg_cmdid = WMI_TLV_DBGLOG_CFG_CMDID,
   4275	.pdev_qvit_cmdid = WMI_TLV_PDEV_QVIT_CMDID,
   4276	.pdev_ftm_intg_cmdid = WMI_TLV_PDEV_FTM_INTG_CMDID,
   4277	.vdev_set_keepalive_cmdid = WMI_TLV_VDEV_SET_KEEPALIVE_CMDID,
   4278	.vdev_get_keepalive_cmdid = WMI_TLV_VDEV_GET_KEEPALIVE_CMDID,
   4279	.force_fw_hang_cmdid = WMI_TLV_FORCE_FW_HANG_CMDID,
   4280	.gpio_config_cmdid = WMI_TLV_GPIO_CONFIG_CMDID,
   4281	.gpio_output_cmdid = WMI_TLV_GPIO_OUTPUT_CMDID,
   4282	.pdev_get_temperature_cmdid = WMI_TLV_PDEV_GET_TEMPERATURE_CMDID,
   4283	.vdev_set_wmm_params_cmdid = WMI_TLV_VDEV_SET_WMM_PARAMS_CMDID,
   4284	.tdls_set_state_cmdid = WMI_TLV_TDLS_SET_STATE_CMDID,
   4285	.tdls_peer_update_cmdid = WMI_TLV_TDLS_PEER_UPDATE_CMDID,
   4286	.adaptive_qcs_cmdid = WMI_TLV_RESMGR_ADAPTIVE_OCS_CMDID,
   4287	.scan_update_request_cmdid = WMI_CMD_UNSUPPORTED,
   4288	.vdev_standby_response_cmdid = WMI_CMD_UNSUPPORTED,
   4289	.vdev_resume_response_cmdid = WMI_CMD_UNSUPPORTED,
   4290	.wlan_peer_caching_add_peer_cmdid = WMI_CMD_UNSUPPORTED,
   4291	.wlan_peer_caching_evict_peer_cmdid = WMI_CMD_UNSUPPORTED,
   4292	.wlan_peer_caching_restore_peer_cmdid = WMI_CMD_UNSUPPORTED,
   4293	.wlan_peer_caching_print_all_peers_info_cmdid = WMI_CMD_UNSUPPORTED,
   4294	.peer_update_wds_entry_cmdid = WMI_CMD_UNSUPPORTED,
   4295	.peer_add_proxy_sta_entry_cmdid = WMI_CMD_UNSUPPORTED,
   4296	.rtt_keepalive_cmdid = WMI_CMD_UNSUPPORTED,
   4297	.oem_req_cmdid = WMI_CMD_UNSUPPORTED,
   4298	.nan_cmdid = WMI_CMD_UNSUPPORTED,
   4299	.vdev_ratemask_cmdid = WMI_CMD_UNSUPPORTED,
   4300	.qboost_cfg_cmdid = WMI_CMD_UNSUPPORTED,
   4301	.pdev_smart_ant_enable_cmdid = WMI_CMD_UNSUPPORTED,
   4302	.pdev_smart_ant_set_rx_antenna_cmdid = WMI_CMD_UNSUPPORTED,
   4303	.peer_smart_ant_set_tx_antenna_cmdid = WMI_CMD_UNSUPPORTED,
   4304	.peer_smart_ant_set_train_info_cmdid = WMI_CMD_UNSUPPORTED,
   4305	.peer_smart_ant_set_node_config_ops_cmdid = WMI_CMD_UNSUPPORTED,
   4306	.pdev_set_antenna_switch_table_cmdid = WMI_CMD_UNSUPPORTED,
   4307	.pdev_set_ctl_table_cmdid = WMI_CMD_UNSUPPORTED,
   4308	.pdev_set_mimogain_table_cmdid = WMI_CMD_UNSUPPORTED,
   4309	.pdev_ratepwr_table_cmdid = WMI_CMD_UNSUPPORTED,
   4310	.pdev_ratepwr_chainmsk_table_cmdid = WMI_CMD_UNSUPPORTED,
   4311	.pdev_fips_cmdid = WMI_CMD_UNSUPPORTED,
   4312	.tt_set_conf_cmdid = WMI_CMD_UNSUPPORTED,
   4313	.fwtest_cmdid = WMI_CMD_UNSUPPORTED,
   4314	.vdev_atf_request_cmdid = WMI_CMD_UNSUPPORTED,
   4315	.peer_atf_request_cmdid = WMI_CMD_UNSUPPORTED,
   4316	.pdev_get_ani_cck_config_cmdid = WMI_CMD_UNSUPPORTED,
   4317	.pdev_get_ani_ofdm_config_cmdid = WMI_CMD_UNSUPPORTED,
   4318	.pdev_reserve_ast_entry_cmdid = WMI_CMD_UNSUPPORTED,
   4319};
   4320
   4321static struct wmi_pdev_param_map wmi_tlv_pdev_param_map = {
   4322	.tx_chain_mask = WMI_TLV_PDEV_PARAM_TX_CHAIN_MASK,
   4323	.rx_chain_mask = WMI_TLV_PDEV_PARAM_RX_CHAIN_MASK,
   4324	.txpower_limit2g = WMI_TLV_PDEV_PARAM_TXPOWER_LIMIT2G,
   4325	.txpower_limit5g = WMI_TLV_PDEV_PARAM_TXPOWER_LIMIT5G,
   4326	.txpower_scale = WMI_TLV_PDEV_PARAM_TXPOWER_SCALE,
   4327	.beacon_gen_mode = WMI_TLV_PDEV_PARAM_BEACON_GEN_MODE,
   4328	.beacon_tx_mode = WMI_TLV_PDEV_PARAM_BEACON_TX_MODE,
   4329	.resmgr_offchan_mode = WMI_TLV_PDEV_PARAM_RESMGR_OFFCHAN_MODE,
   4330	.protection_mode = WMI_TLV_PDEV_PARAM_PROTECTION_MODE,
   4331	.dynamic_bw = WMI_TLV_PDEV_PARAM_DYNAMIC_BW,
   4332	.non_agg_sw_retry_th = WMI_TLV_PDEV_PARAM_NON_AGG_SW_RETRY_TH,
   4333	.agg_sw_retry_th = WMI_TLV_PDEV_PARAM_AGG_SW_RETRY_TH,
   4334	.sta_kickout_th = WMI_TLV_PDEV_PARAM_STA_KICKOUT_TH,
   4335	.ac_aggrsize_scaling = WMI_TLV_PDEV_PARAM_AC_AGGRSIZE_SCALING,
   4336	.ltr_enable = WMI_TLV_PDEV_PARAM_LTR_ENABLE,
   4337	.ltr_ac_latency_be = WMI_TLV_PDEV_PARAM_LTR_AC_LATENCY_BE,
   4338	.ltr_ac_latency_bk = WMI_TLV_PDEV_PARAM_LTR_AC_LATENCY_BK,
   4339	.ltr_ac_latency_vi = WMI_TLV_PDEV_PARAM_LTR_AC_LATENCY_VI,
   4340	.ltr_ac_latency_vo = WMI_TLV_PDEV_PARAM_LTR_AC_LATENCY_VO,
   4341	.ltr_ac_latency_timeout = WMI_TLV_PDEV_PARAM_LTR_AC_LATENCY_TIMEOUT,
   4342	.ltr_sleep_override = WMI_TLV_PDEV_PARAM_LTR_SLEEP_OVERRIDE,
   4343	.ltr_rx_override = WMI_TLV_PDEV_PARAM_LTR_RX_OVERRIDE,
   4344	.ltr_tx_activity_timeout = WMI_TLV_PDEV_PARAM_LTR_TX_ACTIVITY_TIMEOUT,
   4345	.l1ss_enable = WMI_TLV_PDEV_PARAM_L1SS_ENABLE,
   4346	.dsleep_enable = WMI_TLV_PDEV_PARAM_DSLEEP_ENABLE,
   4347	.pcielp_txbuf_flush = WMI_TLV_PDEV_PARAM_PCIELP_TXBUF_FLUSH,
   4348	.pcielp_txbuf_watermark = WMI_TLV_PDEV_PARAM_PCIELP_TXBUF_TMO_EN,
   4349	.pcielp_txbuf_tmo_en = WMI_TLV_PDEV_PARAM_PCIELP_TXBUF_TMO_EN,
   4350	.pcielp_txbuf_tmo_value = WMI_TLV_PDEV_PARAM_PCIELP_TXBUF_TMO_VALUE,
   4351	.pdev_stats_update_period = WMI_TLV_PDEV_PARAM_PDEV_STATS_UPDATE_PERIOD,
   4352	.vdev_stats_update_period = WMI_TLV_PDEV_PARAM_VDEV_STATS_UPDATE_PERIOD,
   4353	.peer_stats_update_period = WMI_TLV_PDEV_PARAM_PEER_STATS_UPDATE_PERIOD,
   4354	.bcnflt_stats_update_period =
   4355				WMI_TLV_PDEV_PARAM_BCNFLT_STATS_UPDATE_PERIOD,
   4356	.pmf_qos = WMI_TLV_PDEV_PARAM_PMF_QOS,
   4357	.arp_ac_override = WMI_TLV_PDEV_PARAM_ARP_AC_OVERRIDE,
   4358	.dcs = WMI_TLV_PDEV_PARAM_DCS,
   4359	.ani_enable = WMI_TLV_PDEV_PARAM_ANI_ENABLE,
   4360	.ani_poll_period = WMI_TLV_PDEV_PARAM_ANI_POLL_PERIOD,
   4361	.ani_listen_period = WMI_TLV_PDEV_PARAM_ANI_LISTEN_PERIOD,
   4362	.ani_ofdm_level = WMI_TLV_PDEV_PARAM_ANI_OFDM_LEVEL,
   4363	.ani_cck_level = WMI_TLV_PDEV_PARAM_ANI_CCK_LEVEL,
   4364	.dyntxchain = WMI_TLV_PDEV_PARAM_DYNTXCHAIN,
   4365	.proxy_sta = WMI_TLV_PDEV_PARAM_PROXY_STA,
   4366	.idle_ps_config = WMI_TLV_PDEV_PARAM_IDLE_PS_CONFIG,
   4367	.power_gating_sleep = WMI_TLV_PDEV_PARAM_POWER_GATING_SLEEP,
   4368	.fast_channel_reset = WMI_TLV_PDEV_PARAM_UNSUPPORTED,
   4369	.burst_dur = WMI_TLV_PDEV_PARAM_BURST_DUR,
   4370	.burst_enable = WMI_TLV_PDEV_PARAM_BURST_ENABLE,
   4371	.cal_period = WMI_PDEV_PARAM_UNSUPPORTED,
   4372	.aggr_burst = WMI_PDEV_PARAM_UNSUPPORTED,
   4373	.rx_decap_mode = WMI_PDEV_PARAM_UNSUPPORTED,
   4374	.smart_antenna_default_antenna = WMI_PDEV_PARAM_UNSUPPORTED,
   4375	.igmpmld_override = WMI_PDEV_PARAM_UNSUPPORTED,
   4376	.igmpmld_tid = WMI_PDEV_PARAM_UNSUPPORTED,
   4377	.antenna_gain = WMI_PDEV_PARAM_UNSUPPORTED,
   4378	.rx_filter = WMI_PDEV_PARAM_UNSUPPORTED,
   4379	.set_mcast_to_ucast_tid = WMI_PDEV_PARAM_UNSUPPORTED,
   4380	.proxy_sta_mode = WMI_PDEV_PARAM_UNSUPPORTED,
   4381	.set_mcast2ucast_mode = WMI_PDEV_PARAM_UNSUPPORTED,
   4382	.set_mcast2ucast_buffer = WMI_PDEV_PARAM_UNSUPPORTED,
   4383	.remove_mcast2ucast_buffer = WMI_PDEV_PARAM_UNSUPPORTED,
   4384	.peer_sta_ps_statechg_enable = WMI_PDEV_PARAM_UNSUPPORTED,
   4385	.igmpmld_ac_override = WMI_PDEV_PARAM_UNSUPPORTED,
   4386	.block_interbss = WMI_PDEV_PARAM_UNSUPPORTED,
   4387	.set_disable_reset_cmdid = WMI_PDEV_PARAM_UNSUPPORTED,
   4388	.set_msdu_ttl_cmdid = WMI_PDEV_PARAM_UNSUPPORTED,
   4389	.set_ppdu_duration_cmdid = WMI_PDEV_PARAM_UNSUPPORTED,
   4390	.txbf_sound_period_cmdid = WMI_PDEV_PARAM_UNSUPPORTED,
   4391	.set_promisc_mode_cmdid = WMI_PDEV_PARAM_UNSUPPORTED,
   4392	.set_burst_mode_cmdid = WMI_PDEV_PARAM_UNSUPPORTED,
   4393	.en_stats = WMI_PDEV_PARAM_UNSUPPORTED,
   4394	.mu_group_policy = WMI_PDEV_PARAM_UNSUPPORTED,
   4395	.noise_detection = WMI_PDEV_PARAM_UNSUPPORTED,
   4396	.noise_threshold = WMI_PDEV_PARAM_UNSUPPORTED,
   4397	.dpd_enable = WMI_PDEV_PARAM_UNSUPPORTED,
   4398	.set_mcast_bcast_echo = WMI_PDEV_PARAM_UNSUPPORTED,
   4399	.atf_strict_sch = WMI_PDEV_PARAM_UNSUPPORTED,
   4400	.atf_sched_duration = WMI_PDEV_PARAM_UNSUPPORTED,
   4401	.ant_plzn = WMI_PDEV_PARAM_UNSUPPORTED,
   4402	.mgmt_retry_limit = WMI_PDEV_PARAM_UNSUPPORTED,
   4403	.sensitivity_level = WMI_PDEV_PARAM_UNSUPPORTED,
   4404	.signed_txpower_2g = WMI_PDEV_PARAM_UNSUPPORTED,
   4405	.signed_txpower_5g = WMI_PDEV_PARAM_UNSUPPORTED,
   4406	.enable_per_tid_amsdu = WMI_PDEV_PARAM_UNSUPPORTED,
   4407	.enable_per_tid_ampdu = WMI_PDEV_PARAM_UNSUPPORTED,
   4408	.cca_threshold = WMI_PDEV_PARAM_UNSUPPORTED,
   4409	.rts_fixed_rate = WMI_PDEV_PARAM_UNSUPPORTED,
   4410	.pdev_reset = WMI_PDEV_PARAM_UNSUPPORTED,
   4411	.wapi_mbssid_offset = WMI_PDEV_PARAM_UNSUPPORTED,
   4412	.arp_srcaddr = WMI_PDEV_PARAM_UNSUPPORTED,
   4413	.arp_dstaddr = WMI_PDEV_PARAM_UNSUPPORTED,
   4414	.rfkill_config = WMI_TLV_PDEV_PARAM_HW_RFKILL_CONFIG,
   4415	.rfkill_enable = WMI_TLV_PDEV_PARAM_RFKILL_ENABLE,
   4416	.peer_stats_info_enable = WMI_TLV_PDEV_PARAM_PEER_STATS_INFO_ENABLE,
   4417};
   4418
   4419static struct wmi_peer_param_map wmi_tlv_peer_param_map = {
   4420	.smps_state = WMI_TLV_PEER_SMPS_STATE,
   4421	.ampdu = WMI_TLV_PEER_AMPDU,
   4422	.authorize = WMI_TLV_PEER_AUTHORIZE,
   4423	.chan_width = WMI_TLV_PEER_CHAN_WIDTH,
   4424	.nss = WMI_TLV_PEER_NSS,
   4425	.use_4addr = WMI_TLV_PEER_USE_4ADDR,
   4426	.membership = WMI_TLV_PEER_MEMBERSHIP,
   4427	.user_pos = WMI_TLV_PEER_USERPOS,
   4428	.crit_proto_hint_enabled = WMI_TLV_PEER_CRIT_PROTO_HINT_ENABLED,
   4429	.tx_fail_cnt_thr = WMI_TLV_PEER_TX_FAIL_CNT_THR,
   4430	.set_hw_retry_cts2s = WMI_TLV_PEER_SET_HW_RETRY_CTS2S,
   4431	.ibss_atim_win_len = WMI_TLV_PEER_IBSS_ATIM_WINDOW_LENGTH,
   4432	.phymode = WMI_TLV_PEER_PHYMODE,
   4433	.use_fixed_power = WMI_TLV_PEER_USE_FIXED_PWR,
   4434	.dummy_var = WMI_TLV_PEER_DUMMY_VAR,
   4435};
   4436
   4437static struct wmi_vdev_param_map wmi_tlv_vdev_param_map = {
   4438	.rts_threshold = WMI_TLV_VDEV_PARAM_RTS_THRESHOLD,
   4439	.fragmentation_threshold = WMI_TLV_VDEV_PARAM_FRAGMENTATION_THRESHOLD,
   4440	.beacon_interval = WMI_TLV_VDEV_PARAM_BEACON_INTERVAL,
   4441	.listen_interval = WMI_TLV_VDEV_PARAM_LISTEN_INTERVAL,
   4442	.multicast_rate = WMI_TLV_VDEV_PARAM_MULTICAST_RATE,
   4443	.mgmt_tx_rate = WMI_TLV_VDEV_PARAM_MGMT_TX_RATE,
   4444	.slot_time = WMI_TLV_VDEV_PARAM_SLOT_TIME,
   4445	.preamble = WMI_TLV_VDEV_PARAM_PREAMBLE,
   4446	.swba_time = WMI_TLV_VDEV_PARAM_SWBA_TIME,
   4447	.wmi_vdev_stats_update_period = WMI_TLV_VDEV_STATS_UPDATE_PERIOD,
   4448	.wmi_vdev_pwrsave_ageout_time = WMI_TLV_VDEV_PWRSAVE_AGEOUT_TIME,
   4449	.wmi_vdev_host_swba_interval = WMI_TLV_VDEV_HOST_SWBA_INTERVAL,
   4450	.dtim_period = WMI_TLV_VDEV_PARAM_DTIM_PERIOD,
   4451	.wmi_vdev_oc_scheduler_air_time_limit =
   4452				WMI_TLV_VDEV_OC_SCHEDULER_AIR_TIME_LIMIT,
   4453	.wds = WMI_TLV_VDEV_PARAM_WDS,
   4454	.atim_window = WMI_TLV_VDEV_PARAM_ATIM_WINDOW,
   4455	.bmiss_count_max = WMI_TLV_VDEV_PARAM_BMISS_COUNT_MAX,
   4456	.bmiss_first_bcnt = WMI_TLV_VDEV_PARAM_BMISS_FIRST_BCNT,
   4457	.bmiss_final_bcnt = WMI_TLV_VDEV_PARAM_BMISS_FINAL_BCNT,
   4458	.feature_wmm = WMI_TLV_VDEV_PARAM_FEATURE_WMM,
   4459	.chwidth = WMI_TLV_VDEV_PARAM_CHWIDTH,
   4460	.chextoffset = WMI_TLV_VDEV_PARAM_CHEXTOFFSET,
   4461	.disable_htprotection =	WMI_TLV_VDEV_PARAM_DISABLE_HTPROTECTION,
   4462	.sta_quickkickout = WMI_TLV_VDEV_PARAM_STA_QUICKKICKOUT,
   4463	.mgmt_rate = WMI_TLV_VDEV_PARAM_MGMT_RATE,
   4464	.protection_mode = WMI_TLV_VDEV_PARAM_PROTECTION_MODE,
   4465	.fixed_rate = WMI_TLV_VDEV_PARAM_FIXED_RATE,
   4466	.sgi = WMI_TLV_VDEV_PARAM_SGI,
   4467	.ldpc = WMI_TLV_VDEV_PARAM_LDPC,
   4468	.tx_stbc = WMI_TLV_VDEV_PARAM_TX_STBC,
   4469	.rx_stbc = WMI_TLV_VDEV_PARAM_RX_STBC,
   4470	.intra_bss_fwd = WMI_TLV_VDEV_PARAM_INTRA_BSS_FWD,
   4471	.def_keyid = WMI_TLV_VDEV_PARAM_DEF_KEYID,
   4472	.nss = WMI_TLV_VDEV_PARAM_NSS,
   4473	.bcast_data_rate = WMI_TLV_VDEV_PARAM_BCAST_DATA_RATE,
   4474	.mcast_data_rate = WMI_TLV_VDEV_PARAM_MCAST_DATA_RATE,
   4475	.mcast_indicate = WMI_TLV_VDEV_PARAM_MCAST_INDICATE,
   4476	.dhcp_indicate = WMI_TLV_VDEV_PARAM_DHCP_INDICATE,
   4477	.unknown_dest_indicate = WMI_TLV_VDEV_PARAM_UNKNOWN_DEST_INDICATE,
   4478	.ap_keepalive_min_idle_inactive_time_secs =
   4479		WMI_TLV_VDEV_PARAM_AP_KEEPALIVE_MIN_IDLE_INACTIVE_TIME_SECS,
   4480	.ap_keepalive_max_idle_inactive_time_secs =
   4481		WMI_TLV_VDEV_PARAM_AP_KEEPALIVE_MAX_IDLE_INACTIVE_TIME_SECS,
   4482	.ap_keepalive_max_unresponsive_time_secs =
   4483		WMI_TLV_VDEV_PARAM_AP_KEEPALIVE_MAX_UNRESPONSIVE_TIME_SECS,
   4484	.ap_enable_nawds = WMI_TLV_VDEV_PARAM_AP_ENABLE_NAWDS,
   4485	.mcast2ucast_set = WMI_TLV_VDEV_PARAM_UNSUPPORTED,
   4486	.enable_rtscts = WMI_TLV_VDEV_PARAM_ENABLE_RTSCTS,
   4487	.txbf = WMI_TLV_VDEV_PARAM_TXBF,
   4488	.packet_powersave = WMI_TLV_VDEV_PARAM_PACKET_POWERSAVE,
   4489	.drop_unencry = WMI_TLV_VDEV_PARAM_DROP_UNENCRY,
   4490	.tx_encap_type = WMI_TLV_VDEV_PARAM_TX_ENCAP_TYPE,
   4491	.ap_detect_out_of_sync_sleeping_sta_time_secs =
   4492					WMI_TLV_VDEV_PARAM_UNSUPPORTED,
   4493	.rc_num_retries = WMI_VDEV_PARAM_UNSUPPORTED,
   4494	.cabq_maxdur = WMI_VDEV_PARAM_UNSUPPORTED,
   4495	.mfptest_set = WMI_VDEV_PARAM_UNSUPPORTED,
   4496	.rts_fixed_rate = WMI_VDEV_PARAM_UNSUPPORTED,
   4497	.vht_sgimask = WMI_VDEV_PARAM_UNSUPPORTED,
   4498	.vht80_ratemask = WMI_VDEV_PARAM_UNSUPPORTED,
   4499	.early_rx_adjust_enable = WMI_VDEV_PARAM_UNSUPPORTED,
   4500	.early_rx_tgt_bmiss_num = WMI_VDEV_PARAM_UNSUPPORTED,
   4501	.early_rx_bmiss_sample_cycle = WMI_VDEV_PARAM_UNSUPPORTED,
   4502	.early_rx_slop_step = WMI_VDEV_PARAM_UNSUPPORTED,
   4503	.early_rx_init_slop = WMI_VDEV_PARAM_UNSUPPORTED,
   4504	.early_rx_adjust_pause = WMI_VDEV_PARAM_UNSUPPORTED,
   4505	.proxy_sta = WMI_VDEV_PARAM_UNSUPPORTED,
   4506	.meru_vc = WMI_VDEV_PARAM_UNSUPPORTED,
   4507	.rx_decap_type = WMI_VDEV_PARAM_UNSUPPORTED,
   4508	.bw_nss_ratemask = WMI_VDEV_PARAM_UNSUPPORTED,
   4509};
   4510
   4511static const struct wmi_ops wmi_tlv_ops = {
   4512	.rx = ath10k_wmi_tlv_op_rx,
   4513	.map_svc = wmi_tlv_svc_map,
   4514	.map_svc_ext = wmi_tlv_svc_map_ext,
   4515
   4516	.pull_scan = ath10k_wmi_tlv_op_pull_scan_ev,
   4517	.pull_mgmt_rx = ath10k_wmi_tlv_op_pull_mgmt_rx_ev,
   4518	.pull_mgmt_tx_compl = ath10k_wmi_tlv_op_pull_mgmt_tx_compl_ev,
   4519	.pull_mgmt_tx_bundle_compl = ath10k_wmi_tlv_op_pull_mgmt_tx_bundle_compl_ev,
   4520	.pull_ch_info = ath10k_wmi_tlv_op_pull_ch_info_ev,
   4521	.pull_vdev_start = ath10k_wmi_tlv_op_pull_vdev_start_ev,
   4522	.pull_peer_kick = ath10k_wmi_tlv_op_pull_peer_kick_ev,
   4523	.pull_swba = ath10k_wmi_tlv_op_pull_swba_ev,
   4524	.pull_phyerr_hdr = ath10k_wmi_tlv_op_pull_phyerr_ev_hdr,
   4525	.pull_phyerr = ath10k_wmi_op_pull_phyerr_ev,
   4526	.pull_svc_rdy = ath10k_wmi_tlv_op_pull_svc_rdy_ev,
   4527	.pull_rdy = ath10k_wmi_tlv_op_pull_rdy_ev,
   4528	.pull_svc_avail = ath10k_wmi_tlv_op_pull_svc_avail,
   4529	.pull_fw_stats = ath10k_wmi_tlv_op_pull_fw_stats,
   4530	.pull_roam_ev = ath10k_wmi_tlv_op_pull_roam_ev,
   4531	.pull_wow_event = ath10k_wmi_tlv_op_pull_wow_ev,
   4532	.pull_echo_ev = ath10k_wmi_tlv_op_pull_echo_ev,
   4533	.get_txbf_conf_scheme = ath10k_wmi_tlv_txbf_conf_scheme,
   4534
   4535	.gen_pdev_suspend = ath10k_wmi_tlv_op_gen_pdev_suspend,
   4536	.gen_pdev_resume = ath10k_wmi_tlv_op_gen_pdev_resume,
   4537	.gen_pdev_set_rd = ath10k_wmi_tlv_op_gen_pdev_set_rd,
   4538	.gen_pdev_set_param = ath10k_wmi_tlv_op_gen_pdev_set_param,
   4539	.gen_init = ath10k_wmi_tlv_op_gen_init,
   4540	.gen_start_scan = ath10k_wmi_tlv_op_gen_start_scan,
   4541	.gen_stop_scan = ath10k_wmi_tlv_op_gen_stop_scan,
   4542	.gen_vdev_create = ath10k_wmi_tlv_op_gen_vdev_create,
   4543	.gen_vdev_delete = ath10k_wmi_tlv_op_gen_vdev_delete,
   4544	.gen_vdev_start = ath10k_wmi_tlv_op_gen_vdev_start,
   4545	.gen_vdev_stop = ath10k_wmi_tlv_op_gen_vdev_stop,
   4546	.gen_vdev_up = ath10k_wmi_tlv_op_gen_vdev_up,
   4547	.gen_vdev_down = ath10k_wmi_tlv_op_gen_vdev_down,
   4548	.gen_vdev_set_param = ath10k_wmi_tlv_op_gen_vdev_set_param,
   4549	.gen_vdev_install_key = ath10k_wmi_tlv_op_gen_vdev_install_key,
   4550	.gen_vdev_wmm_conf = ath10k_wmi_tlv_op_gen_vdev_wmm_conf,
   4551	.gen_peer_create = ath10k_wmi_tlv_op_gen_peer_create,
   4552	.gen_peer_delete = ath10k_wmi_tlv_op_gen_peer_delete,
   4553	.gen_peer_flush = ath10k_wmi_tlv_op_gen_peer_flush,
   4554	.gen_peer_set_param = ath10k_wmi_tlv_op_gen_peer_set_param,
   4555	.gen_peer_assoc = ath10k_wmi_tlv_op_gen_peer_assoc,
   4556	.gen_set_psmode = ath10k_wmi_tlv_op_gen_set_psmode,
   4557	.gen_set_sta_ps = ath10k_wmi_tlv_op_gen_set_sta_ps,
   4558	.gen_set_ap_ps = ath10k_wmi_tlv_op_gen_set_ap_ps,
   4559	.gen_scan_chan_list = ath10k_wmi_tlv_op_gen_scan_chan_list,
   4560	.gen_scan_prob_req_oui = ath10k_wmi_tlv_op_gen_scan_prob_req_oui,
   4561	.gen_beacon_dma = ath10k_wmi_tlv_op_gen_beacon_dma,
   4562	.gen_pdev_set_wmm = ath10k_wmi_tlv_op_gen_pdev_set_wmm,
   4563	.gen_request_stats = ath10k_wmi_tlv_op_gen_request_stats,
   4564	.gen_request_peer_stats_info = ath10k_wmi_tlv_op_gen_request_peer_stats_info,
   4565	.gen_force_fw_hang = ath10k_wmi_tlv_op_gen_force_fw_hang,
   4566	/* .gen_mgmt_tx = not implemented; HTT is used */
   4567	.gen_mgmt_tx_send = ath10k_wmi_tlv_op_gen_mgmt_tx_send,
   4568	.cleanup_mgmt_tx_send = ath10k_wmi_tlv_op_cleanup_mgmt_tx_send,
   4569	.gen_dbglog_cfg = ath10k_wmi_tlv_op_gen_dbglog_cfg,
   4570	.gen_pktlog_enable = ath10k_wmi_tlv_op_gen_pktlog_enable,
   4571	.gen_pktlog_disable = ath10k_wmi_tlv_op_gen_pktlog_disable,
   4572	.gen_pdev_set_quiet_mode = ath10k_wmi_tlv_op_gen_pdev_set_quiet_mode,
   4573	.gen_pdev_get_temperature = ath10k_wmi_tlv_op_gen_pdev_get_temperature,
   4574	/* .gen_addba_clear_resp not implemented */
   4575	/* .gen_addba_send not implemented */
   4576	/* .gen_addba_set_resp not implemented */
   4577	/* .gen_delba_send not implemented */
   4578	.gen_bcn_tmpl = ath10k_wmi_tlv_op_gen_bcn_tmpl,
   4579	.gen_prb_tmpl = ath10k_wmi_tlv_op_gen_prb_tmpl,
   4580	.gen_p2p_go_bcn_ie = ath10k_wmi_tlv_op_gen_p2p_go_bcn_ie,
   4581	.gen_vdev_sta_uapsd = ath10k_wmi_tlv_op_gen_vdev_sta_uapsd,
   4582	.gen_sta_keepalive = ath10k_wmi_tlv_op_gen_sta_keepalive,
   4583	.gen_wow_enable = ath10k_wmi_tlv_op_gen_wow_enable,
   4584	.gen_wow_add_wakeup_event = ath10k_wmi_tlv_op_gen_wow_add_wakeup_event,
   4585	.gen_wow_host_wakeup_ind = ath10k_wmi_tlv_gen_wow_host_wakeup_ind,
   4586	.gen_wow_add_pattern = ath10k_wmi_tlv_op_gen_wow_add_pattern,
   4587	.gen_wow_del_pattern = ath10k_wmi_tlv_op_gen_wow_del_pattern,
   4588	.gen_wow_config_pno = ath10k_wmi_tlv_op_gen_config_pno,
   4589	.gen_update_fw_tdls_state = ath10k_wmi_tlv_op_gen_update_fw_tdls_state,
   4590	.gen_tdls_peer_update = ath10k_wmi_tlv_op_gen_tdls_peer_update,
   4591	.gen_adaptive_qcs = ath10k_wmi_tlv_op_gen_adaptive_qcs,
   4592	.fw_stats_fill = ath10k_wmi_main_op_fw_stats_fill,
   4593	.get_vdev_subtype = ath10k_wmi_tlv_op_get_vdev_subtype,
   4594	.gen_echo = ath10k_wmi_tlv_op_gen_echo,
   4595	.gen_vdev_spectral_conf = ath10k_wmi_tlv_op_gen_vdev_spectral_conf,
   4596	.gen_vdev_spectral_enable = ath10k_wmi_tlv_op_gen_vdev_spectral_enable,
   4597};
   4598
   4599static const struct wmi_peer_flags_map wmi_tlv_peer_flags_map = {
   4600	.auth = WMI_TLV_PEER_AUTH,
   4601	.qos = WMI_TLV_PEER_QOS,
   4602	.need_ptk_4_way = WMI_TLV_PEER_NEED_PTK_4_WAY,
   4603	.need_gtk_2_way = WMI_TLV_PEER_NEED_GTK_2_WAY,
   4604	.apsd = WMI_TLV_PEER_APSD,
   4605	.ht = WMI_TLV_PEER_HT,
   4606	.bw40 = WMI_TLV_PEER_40MHZ,
   4607	.stbc = WMI_TLV_PEER_STBC,
   4608	.ldbc = WMI_TLV_PEER_LDPC,
   4609	.dyn_mimops = WMI_TLV_PEER_DYN_MIMOPS,
   4610	.static_mimops = WMI_TLV_PEER_STATIC_MIMOPS,
   4611	.spatial_mux = WMI_TLV_PEER_SPATIAL_MUX,
   4612	.vht = WMI_TLV_PEER_VHT,
   4613	.bw80 = WMI_TLV_PEER_80MHZ,
   4614	.pmf = WMI_TLV_PEER_PMF,
   4615	.bw160 = WMI_TLV_PEER_160MHZ,
   4616};
   4617
   4618/************/
   4619/* TLV init */
   4620/************/
   4621
   4622void ath10k_wmi_tlv_attach(struct ath10k *ar)
   4623{
   4624	ar->wmi.cmd = &wmi_tlv_cmd_map;
   4625	ar->wmi.vdev_param = &wmi_tlv_vdev_param_map;
   4626	ar->wmi.pdev_param = &wmi_tlv_pdev_param_map;
   4627	ar->wmi.peer_param = &wmi_tlv_peer_param_map;
   4628	ar->wmi.ops = &wmi_tlv_ops;
   4629	ar->wmi.peer_flags = &wmi_tlv_peer_flags_map;
   4630}