Linux Audio

Check our new training course

Loading...
Note: File does not exist in v3.5.6.
   1// SPDX-License-Identifier: BSD-3-Clause-Clear
   2/*
   3 * Copyright (c) 2018-2019 The Linux Foundation. All rights reserved.
   4 * Copyright (c) 2021-2024 Qualcomm Innovation Center, Inc. All rights reserved.
   5 */
   6#include <linux/skbuff.h>
   7#include <linux/ctype.h>
   8#include <net/mac80211.h>
   9#include <net/cfg80211.h>
  10#include <linux/completion.h>
  11#include <linux/if_ether.h>
  12#include <linux/types.h>
  13#include <linux/pci.h>
  14#include <linux/uuid.h>
  15#include <linux/time.h>
  16#include <linux/of.h>
  17#include "core.h"
  18#include "debug.h"
  19#include "mac.h"
  20#include "hw.h"
  21#include "peer.h"
  22#include "testmode.h"
  23#include "p2p.h"
  24
  25struct wmi_tlv_policy {
  26	size_t min_len;
  27};
  28
  29struct wmi_tlv_svc_ready_parse {
  30	bool wmi_svc_bitmap_done;
  31};
  32
  33struct wmi_tlv_dma_ring_caps_parse {
  34	struct wmi_dma_ring_capabilities *dma_ring_caps;
  35	u32 n_dma_ring_caps;
  36};
  37
  38struct wmi_tlv_svc_rdy_ext_parse {
  39	struct ath11k_service_ext_param param;
  40	struct wmi_soc_mac_phy_hw_mode_caps *hw_caps;
  41	struct wmi_hw_mode_capabilities *hw_mode_caps;
  42	u32 n_hw_mode_caps;
  43	u32 tot_phy_id;
  44	struct wmi_hw_mode_capabilities pref_hw_mode_caps;
  45	struct wmi_mac_phy_capabilities *mac_phy_caps;
  46	u32 n_mac_phy_caps;
  47	struct wmi_soc_hal_reg_capabilities *soc_hal_reg_caps;
  48	struct wmi_hal_reg_capabilities_ext *ext_hal_reg_caps;
  49	u32 n_ext_hal_reg_caps;
  50	struct wmi_tlv_dma_ring_caps_parse dma_caps_parse;
  51	bool hw_mode_done;
  52	bool mac_phy_done;
  53	bool ext_hal_reg_done;
  54	bool mac_phy_chainmask_combo_done;
  55	bool mac_phy_chainmask_cap_done;
  56	bool oem_dma_ring_cap_done;
  57	bool dma_ring_cap_done;
  58};
  59
  60struct wmi_tlv_svc_rdy_ext2_parse {
  61	struct wmi_tlv_dma_ring_caps_parse dma_caps_parse;
  62	bool dma_ring_cap_done;
  63};
  64
  65struct wmi_tlv_rdy_parse {
  66	u32 num_extra_mac_addr;
  67};
  68
  69struct wmi_tlv_dma_buf_release_parse {
  70	struct ath11k_wmi_dma_buf_release_fixed_param fixed;
  71	struct wmi_dma_buf_release_entry *buf_entry;
  72	struct wmi_dma_buf_release_meta_data *meta_data;
  73	u32 num_buf_entry;
  74	u32 num_meta;
  75	bool buf_entry_done;
  76	bool meta_data_done;
  77};
  78
  79struct wmi_tlv_fw_stats_parse {
  80	const struct wmi_stats_event *ev;
  81	const struct wmi_per_chain_rssi_stats *rssi;
  82	struct ath11k_fw_stats *stats;
  83	int rssi_num;
  84	bool chain_rssi_done;
  85};
  86
  87struct wmi_tlv_mgmt_rx_parse {
  88	const struct wmi_mgmt_rx_hdr *fixed;
  89	const u8 *frame_buf;
  90	bool frame_buf_done;
  91};
  92
  93static const struct wmi_tlv_policy wmi_tlv_policies[] = {
  94	[WMI_TAG_ARRAY_BYTE]
  95		= { .min_len = 0 },
  96	[WMI_TAG_ARRAY_UINT32]
  97		= { .min_len = 0 },
  98	[WMI_TAG_SERVICE_READY_EVENT]
  99		= { .min_len = sizeof(struct wmi_service_ready_event) },
 100	[WMI_TAG_SERVICE_READY_EXT_EVENT]
 101		= { .min_len =  sizeof(struct wmi_service_ready_ext_event) },
 102	[WMI_TAG_SOC_MAC_PHY_HW_MODE_CAPS]
 103		= { .min_len = sizeof(struct wmi_soc_mac_phy_hw_mode_caps) },
 104	[WMI_TAG_SOC_HAL_REG_CAPABILITIES]
 105		= { .min_len = sizeof(struct wmi_soc_hal_reg_capabilities) },
 106	[WMI_TAG_VDEV_START_RESPONSE_EVENT]
 107		= { .min_len = sizeof(struct wmi_vdev_start_resp_event) },
 108	[WMI_TAG_PEER_DELETE_RESP_EVENT]
 109		= { .min_len = sizeof(struct wmi_peer_delete_resp_event) },
 110	[WMI_TAG_OFFLOAD_BCN_TX_STATUS_EVENT]
 111		= { .min_len = sizeof(struct wmi_bcn_tx_status_event) },
 112	[WMI_TAG_VDEV_STOPPED_EVENT]
 113		= { .min_len = sizeof(struct wmi_vdev_stopped_event) },
 114	[WMI_TAG_REG_CHAN_LIST_CC_EVENT]
 115		= { .min_len = sizeof(struct wmi_reg_chan_list_cc_event) },
 116	[WMI_TAG_REG_CHAN_LIST_CC_EXT_EVENT]
 117		= { .min_len = sizeof(struct wmi_reg_chan_list_cc_ext_event) },
 118	[WMI_TAG_MGMT_RX_HDR]
 119		= { .min_len = sizeof(struct wmi_mgmt_rx_hdr) },
 120	[WMI_TAG_MGMT_TX_COMPL_EVENT]
 121		= { .min_len = sizeof(struct wmi_mgmt_tx_compl_event) },
 122	[WMI_TAG_SCAN_EVENT]
 123		= { .min_len = sizeof(struct wmi_scan_event) },
 124	[WMI_TAG_PEER_STA_KICKOUT_EVENT]
 125		= { .min_len = sizeof(struct wmi_peer_sta_kickout_event) },
 126	[WMI_TAG_ROAM_EVENT]
 127		= { .min_len = sizeof(struct wmi_roam_event) },
 128	[WMI_TAG_CHAN_INFO_EVENT]
 129		= { .min_len = sizeof(struct wmi_chan_info_event) },
 130	[WMI_TAG_PDEV_BSS_CHAN_INFO_EVENT]
 131		= { .min_len = sizeof(struct wmi_pdev_bss_chan_info_event) },
 132	[WMI_TAG_VDEV_INSTALL_KEY_COMPLETE_EVENT]
 133		= { .min_len = sizeof(struct wmi_vdev_install_key_compl_event) },
 134	[WMI_TAG_READY_EVENT] = {
 135		.min_len = sizeof(struct wmi_ready_event_min) },
 136	[WMI_TAG_SERVICE_AVAILABLE_EVENT]
 137		= {.min_len = sizeof(struct wmi_service_available_event) },
 138	[WMI_TAG_PEER_ASSOC_CONF_EVENT]
 139		= { .min_len = sizeof(struct wmi_peer_assoc_conf_event) },
 140	[WMI_TAG_STATS_EVENT]
 141		= { .min_len = sizeof(struct wmi_stats_event) },
 142	[WMI_TAG_PDEV_CTL_FAILSAFE_CHECK_EVENT]
 143		= { .min_len = sizeof(struct wmi_pdev_ctl_failsafe_chk_event) },
 144	[WMI_TAG_HOST_SWFDA_EVENT] = {
 145		.min_len = sizeof(struct wmi_fils_discovery_event) },
 146	[WMI_TAG_OFFLOAD_PRB_RSP_TX_STATUS_EVENT] = {
 147		.min_len = sizeof(struct wmi_probe_resp_tx_status_event) },
 148	[WMI_TAG_VDEV_DELETE_RESP_EVENT] = {
 149		.min_len = sizeof(struct wmi_vdev_delete_resp_event) },
 150	[WMI_TAG_OBSS_COLOR_COLLISION_EVT] = {
 151		.min_len = sizeof(struct wmi_obss_color_collision_event) },
 152	[WMI_TAG_11D_NEW_COUNTRY_EVENT] = {
 153		.min_len = sizeof(struct wmi_11d_new_cc_ev) },
 154	[WMI_TAG_PER_CHAIN_RSSI_STATS] = {
 155		.min_len = sizeof(struct wmi_per_chain_rssi_stats) },
 156	[WMI_TAG_TWT_ADD_DIALOG_COMPLETE_EVENT] = {
 157		.min_len = sizeof(struct wmi_twt_add_dialog_event) },
 158	[WMI_TAG_P2P_NOA_INFO] = {
 159		.min_len = sizeof(struct ath11k_wmi_p2p_noa_info) },
 160	[WMI_TAG_P2P_NOA_EVENT] = {
 161		.min_len = sizeof(struct wmi_p2p_noa_event) },
 162};
 163
 164#define PRIMAP(_hw_mode_) \
 165	[_hw_mode_] = _hw_mode_##_PRI
 166
 167static const int ath11k_hw_mode_pri_map[] = {
 168	PRIMAP(WMI_HOST_HW_MODE_SINGLE),
 169	PRIMAP(WMI_HOST_HW_MODE_DBS),
 170	PRIMAP(WMI_HOST_HW_MODE_SBS_PASSIVE),
 171	PRIMAP(WMI_HOST_HW_MODE_SBS),
 172	PRIMAP(WMI_HOST_HW_MODE_DBS_SBS),
 173	PRIMAP(WMI_HOST_HW_MODE_DBS_OR_SBS),
 174	/* keep last */
 175	PRIMAP(WMI_HOST_HW_MODE_MAX),
 176};
 177
 178static int
 179ath11k_wmi_tlv_iter(struct ath11k_base *ab, const void *ptr, size_t len,
 180		    int (*iter)(struct ath11k_base *ab, u16 tag, u16 len,
 181				const void *ptr, void *data),
 182		    void *data)
 183{
 184	const void *begin = ptr;
 185	const struct wmi_tlv *tlv;
 186	u16 tlv_tag, tlv_len;
 187	int ret;
 188
 189	while (len > 0) {
 190		if (len < sizeof(*tlv)) {
 191			ath11k_err(ab, "wmi tlv parse failure at byte %zd (%zu bytes left, %zu expected)\n",
 192				   ptr - begin, len, sizeof(*tlv));
 193			return -EINVAL;
 194		}
 195
 196		tlv = ptr;
 197		tlv_tag = FIELD_GET(WMI_TLV_TAG, tlv->header);
 198		tlv_len = FIELD_GET(WMI_TLV_LEN, tlv->header);
 199		ptr += sizeof(*tlv);
 200		len -= sizeof(*tlv);
 201
 202		if (tlv_len > len) {
 203			ath11k_err(ab, "wmi tlv parse failure of tag %u at byte %zd (%zu bytes left, %u expected)\n",
 204				   tlv_tag, ptr - begin, len, tlv_len);
 205			return -EINVAL;
 206		}
 207
 208		if (tlv_tag < ARRAY_SIZE(wmi_tlv_policies) &&
 209		    wmi_tlv_policies[tlv_tag].min_len &&
 210		    wmi_tlv_policies[tlv_tag].min_len > tlv_len) {
 211			ath11k_err(ab, "wmi tlv parse failure of tag %u at byte %zd (%u bytes is less than min length %zu)\n",
 212				   tlv_tag, ptr - begin, tlv_len,
 213				   wmi_tlv_policies[tlv_tag].min_len);
 214			return -EINVAL;
 215		}
 216
 217		ret = iter(ab, tlv_tag, tlv_len, ptr, data);
 218		if (ret)
 219			return ret;
 220
 221		ptr += tlv_len;
 222		len -= tlv_len;
 223	}
 224
 225	return 0;
 226}
 227
 228static int ath11k_wmi_tlv_iter_parse(struct ath11k_base *ab, u16 tag, u16 len,
 229				     const void *ptr, void *data)
 230{
 231	const void **tb = data;
 232
 233	if (tag < WMI_TAG_MAX)
 234		tb[tag] = ptr;
 235
 236	return 0;
 237}
 238
 239static int ath11k_wmi_tlv_parse(struct ath11k_base *ar, const void **tb,
 240				const void *ptr, size_t len)
 241{
 242	return ath11k_wmi_tlv_iter(ar, ptr, len, ath11k_wmi_tlv_iter_parse,
 243				   (void *)tb);
 244}
 245
 246const void **ath11k_wmi_tlv_parse_alloc(struct ath11k_base *ab,
 247					struct sk_buff *skb, gfp_t gfp)
 248{
 249	const void **tb;
 250	int ret;
 251
 252	tb = kcalloc(WMI_TAG_MAX, sizeof(*tb), gfp);
 253	if (!tb)
 254		return ERR_PTR(-ENOMEM);
 255
 256	ret = ath11k_wmi_tlv_parse(ab, tb, skb->data, skb->len);
 257	if (ret) {
 258		kfree(tb);
 259		return ERR_PTR(ret);
 260	}
 261
 262	return tb;
 263}
 264
 265static int ath11k_wmi_cmd_send_nowait(struct ath11k_pdev_wmi *wmi, struct sk_buff *skb,
 266				      u32 cmd_id)
 267{
 268	struct ath11k_skb_cb *skb_cb = ATH11K_SKB_CB(skb);
 269	struct ath11k_base *ab = wmi->wmi_ab->ab;
 270	struct wmi_cmd_hdr *cmd_hdr;
 271	int ret;
 272	u32 cmd = 0;
 273
 274	if (skb_push(skb, sizeof(struct wmi_cmd_hdr)) == NULL)
 275		return -ENOMEM;
 276
 277	cmd |= FIELD_PREP(WMI_CMD_HDR_CMD_ID, cmd_id);
 278
 279	cmd_hdr = (struct wmi_cmd_hdr *)skb->data;
 280	cmd_hdr->cmd_id = cmd;
 281
 282	trace_ath11k_wmi_cmd(ab, cmd_id, skb->data, skb->len);
 283
 284	memset(skb_cb, 0, sizeof(*skb_cb));
 285	ret = ath11k_htc_send(&ab->htc, wmi->eid, skb);
 286
 287	if (ret)
 288		goto err_pull;
 289
 290	return 0;
 291
 292err_pull:
 293	skb_pull(skb, sizeof(struct wmi_cmd_hdr));
 294	return ret;
 295}
 296
 297int ath11k_wmi_cmd_send(struct ath11k_pdev_wmi *wmi, struct sk_buff *skb,
 298			u32 cmd_id)
 299{
 300	struct ath11k_wmi_base *wmi_ab = wmi->wmi_ab;
 301	int ret = -EOPNOTSUPP;
 302	struct ath11k_base *ab = wmi_ab->ab;
 303
 304	might_sleep();
 305
 306	if (ab->hw_params.credit_flow) {
 307		wait_event_timeout(wmi_ab->tx_credits_wq, ({
 308			ret = ath11k_wmi_cmd_send_nowait(wmi, skb, cmd_id);
 309
 310			if (ret && test_bit(ATH11K_FLAG_CRASH_FLUSH,
 311					    &wmi_ab->ab->dev_flags))
 312				ret = -ESHUTDOWN;
 313
 314			(ret != -EAGAIN);
 315			}), WMI_SEND_TIMEOUT_HZ);
 316	} else {
 317		wait_event_timeout(wmi->tx_ce_desc_wq, ({
 318			ret = ath11k_wmi_cmd_send_nowait(wmi, skb, cmd_id);
 319
 320			if (ret && test_bit(ATH11K_FLAG_CRASH_FLUSH,
 321					    &wmi_ab->ab->dev_flags))
 322				ret = -ESHUTDOWN;
 323
 324			(ret != -ENOBUFS);
 325			}), WMI_SEND_TIMEOUT_HZ);
 326	}
 327
 328	if (ret == -EAGAIN)
 329		ath11k_warn(wmi_ab->ab, "wmi command %d timeout\n", cmd_id);
 330
 331	if (ret == -ENOBUFS)
 332		ath11k_warn(wmi_ab->ab, "ce desc not available for wmi command %d\n",
 333			    cmd_id);
 334
 335	return ret;
 336}
 337
 338static int ath11k_pull_svc_ready_ext(struct ath11k_pdev_wmi *wmi_handle,
 339				     const void *ptr,
 340				     struct ath11k_service_ext_param *param)
 341{
 342	const struct wmi_service_ready_ext_event *ev = ptr;
 343
 344	if (!ev)
 345		return -EINVAL;
 346
 347	/* Move this to host based bitmap */
 348	param->default_conc_scan_config_bits = ev->default_conc_scan_config_bits;
 349	param->default_fw_config_bits =	ev->default_fw_config_bits;
 350	param->he_cap_info = ev->he_cap_info;
 351	param->mpdu_density = ev->mpdu_density;
 352	param->max_bssid_rx_filters = ev->max_bssid_rx_filters;
 353	memcpy(&param->ppet, &ev->ppet, sizeof(param->ppet));
 354
 355	return 0;
 356}
 357
 358static int
 359ath11k_pull_mac_phy_cap_svc_ready_ext(struct ath11k_pdev_wmi *wmi_handle,
 360				      struct wmi_soc_mac_phy_hw_mode_caps *hw_caps,
 361				      struct wmi_hw_mode_capabilities *wmi_hw_mode_caps,
 362				      struct wmi_soc_hal_reg_capabilities *hal_reg_caps,
 363				      struct wmi_mac_phy_capabilities *wmi_mac_phy_caps,
 364				      u8 hw_mode_id, u8 phy_id,
 365				      struct ath11k_pdev *pdev)
 366{
 367	struct wmi_mac_phy_capabilities *mac_phy_caps;
 368	struct ath11k_base *ab = wmi_handle->wmi_ab->ab;
 369	struct ath11k_band_cap *cap_band;
 370	struct ath11k_pdev_cap *pdev_cap = &pdev->cap;
 371	u32 phy_map;
 372	u32 hw_idx, phy_idx = 0;
 373
 374	if (!hw_caps || !wmi_hw_mode_caps || !hal_reg_caps)
 375		return -EINVAL;
 376
 377	for (hw_idx = 0; hw_idx < hw_caps->num_hw_modes; hw_idx++) {
 378		if (hw_mode_id == wmi_hw_mode_caps[hw_idx].hw_mode_id)
 379			break;
 380
 381		phy_map = wmi_hw_mode_caps[hw_idx].phy_id_map;
 382		while (phy_map) {
 383			phy_map >>= 1;
 384			phy_idx++;
 385		}
 386	}
 387
 388	if (hw_idx == hw_caps->num_hw_modes)
 389		return -EINVAL;
 390
 391	phy_idx += phy_id;
 392	if (phy_id >= hal_reg_caps->num_phy)
 393		return -EINVAL;
 394
 395	mac_phy_caps = wmi_mac_phy_caps + phy_idx;
 396
 397	pdev->pdev_id = mac_phy_caps->pdev_id;
 398	pdev_cap->supported_bands |= mac_phy_caps->supported_bands;
 399	pdev_cap->ampdu_density = mac_phy_caps->ampdu_density;
 400	ab->target_pdev_ids[ab->target_pdev_count].supported_bands =
 401		mac_phy_caps->supported_bands;
 402	ab->target_pdev_ids[ab->target_pdev_count].pdev_id = mac_phy_caps->pdev_id;
 403	ab->target_pdev_count++;
 404
 405	if (!(mac_phy_caps->supported_bands & WMI_HOST_WLAN_2G_CAP) &&
 406	    !(mac_phy_caps->supported_bands & WMI_HOST_WLAN_5G_CAP))
 407		return -EINVAL;
 408
 409	/* Take non-zero tx/rx chainmask. If tx/rx chainmask differs from
 410	 * band to band for a single radio, need to see how this should be
 411	 * handled.
 412	 */
 413	if (mac_phy_caps->supported_bands & WMI_HOST_WLAN_2G_CAP) {
 414		pdev_cap->tx_chain_mask = mac_phy_caps->tx_chain_mask_2g;
 415		pdev_cap->rx_chain_mask = mac_phy_caps->rx_chain_mask_2g;
 416	}
 417
 418	if (mac_phy_caps->supported_bands & WMI_HOST_WLAN_5G_CAP) {
 419		pdev_cap->vht_cap = mac_phy_caps->vht_cap_info_5g;
 420		pdev_cap->vht_mcs = mac_phy_caps->vht_supp_mcs_5g;
 421		pdev_cap->he_mcs = mac_phy_caps->he_supp_mcs_5g;
 422		pdev_cap->tx_chain_mask = mac_phy_caps->tx_chain_mask_5g;
 423		pdev_cap->rx_chain_mask = mac_phy_caps->rx_chain_mask_5g;
 424		pdev_cap->nss_ratio_enabled =
 425			WMI_NSS_RATIO_ENABLE_DISABLE_GET(mac_phy_caps->nss_ratio);
 426		pdev_cap->nss_ratio_info =
 427			WMI_NSS_RATIO_INFO_GET(mac_phy_caps->nss_ratio);
 428	}
 429
 430	/* tx/rx chainmask reported from fw depends on the actual hw chains used,
 431	 * For example, for 4x4 capable macphys, first 4 chains can be used for first
 432	 * mac and the remaining 4 chains can be used for the second mac or vice-versa.
 433	 * In this case, tx/rx chainmask 0xf will be advertised for first mac and 0xf0
 434	 * will be advertised for second mac or vice-versa. Compute the shift value
 435	 * for tx/rx chainmask which will be used to advertise supported ht/vht rates to
 436	 * mac80211.
 437	 */
 438	pdev_cap->tx_chain_mask_shift =
 439			find_first_bit((unsigned long *)&pdev_cap->tx_chain_mask, 32);
 440	pdev_cap->rx_chain_mask_shift =
 441			find_first_bit((unsigned long *)&pdev_cap->rx_chain_mask, 32);
 442
 443	if (mac_phy_caps->supported_bands & WMI_HOST_WLAN_2G_CAP) {
 444		cap_band = &pdev_cap->band[NL80211_BAND_2GHZ];
 445		cap_band->phy_id = mac_phy_caps->phy_id;
 446		cap_band->max_bw_supported = mac_phy_caps->max_bw_supported_2g;
 447		cap_band->ht_cap_info = mac_phy_caps->ht_cap_info_2g;
 448		cap_band->he_cap_info[0] = mac_phy_caps->he_cap_info_2g;
 449		cap_band->he_cap_info[1] = mac_phy_caps->he_cap_info_2g_ext;
 450		cap_band->he_mcs = mac_phy_caps->he_supp_mcs_2g;
 451		memcpy(cap_band->he_cap_phy_info, &mac_phy_caps->he_cap_phy_info_2g,
 452		       sizeof(u32) * PSOC_HOST_MAX_PHY_SIZE);
 453		memcpy(&cap_band->he_ppet, &mac_phy_caps->he_ppet2g,
 454		       sizeof(struct ath11k_ppe_threshold));
 455	}
 456
 457	if (mac_phy_caps->supported_bands & WMI_HOST_WLAN_5G_CAP) {
 458		cap_band = &pdev_cap->band[NL80211_BAND_5GHZ];
 459		cap_band->phy_id = mac_phy_caps->phy_id;
 460		cap_band->max_bw_supported = mac_phy_caps->max_bw_supported_5g;
 461		cap_band->ht_cap_info = mac_phy_caps->ht_cap_info_5g;
 462		cap_band->he_cap_info[0] = mac_phy_caps->he_cap_info_5g;
 463		cap_band->he_cap_info[1] = mac_phy_caps->he_cap_info_5g_ext;
 464		cap_band->he_mcs = mac_phy_caps->he_supp_mcs_5g;
 465		memcpy(cap_band->he_cap_phy_info, &mac_phy_caps->he_cap_phy_info_5g,
 466		       sizeof(u32) * PSOC_HOST_MAX_PHY_SIZE);
 467		memcpy(&cap_band->he_ppet, &mac_phy_caps->he_ppet5g,
 468		       sizeof(struct ath11k_ppe_threshold));
 469
 470		cap_band = &pdev_cap->band[NL80211_BAND_6GHZ];
 471		cap_band->max_bw_supported = mac_phy_caps->max_bw_supported_5g;
 472		cap_band->ht_cap_info = mac_phy_caps->ht_cap_info_5g;
 473		cap_band->he_cap_info[0] = mac_phy_caps->he_cap_info_5g;
 474		cap_band->he_cap_info[1] = mac_phy_caps->he_cap_info_5g_ext;
 475		cap_band->he_mcs = mac_phy_caps->he_supp_mcs_5g;
 476		memcpy(cap_band->he_cap_phy_info, &mac_phy_caps->he_cap_phy_info_5g,
 477		       sizeof(u32) * PSOC_HOST_MAX_PHY_SIZE);
 478		memcpy(&cap_band->he_ppet, &mac_phy_caps->he_ppet5g,
 479		       sizeof(struct ath11k_ppe_threshold));
 480	}
 481
 482	return 0;
 483}
 484
 485static int
 486ath11k_pull_reg_cap_svc_rdy_ext(struct ath11k_pdev_wmi *wmi_handle,
 487				struct wmi_soc_hal_reg_capabilities *reg_caps,
 488				struct wmi_hal_reg_capabilities_ext *wmi_ext_reg_cap,
 489				u8 phy_idx,
 490				struct ath11k_hal_reg_capabilities_ext *param)
 491{
 492	struct wmi_hal_reg_capabilities_ext *ext_reg_cap;
 493
 494	if (!reg_caps || !wmi_ext_reg_cap)
 495		return -EINVAL;
 496
 497	if (phy_idx >= reg_caps->num_phy)
 498		return -EINVAL;
 499
 500	ext_reg_cap = &wmi_ext_reg_cap[phy_idx];
 501
 502	param->phy_id = ext_reg_cap->phy_id;
 503	param->eeprom_reg_domain = ext_reg_cap->eeprom_reg_domain;
 504	param->eeprom_reg_domain_ext =
 505			      ext_reg_cap->eeprom_reg_domain_ext;
 506	param->regcap1 = ext_reg_cap->regcap1;
 507	param->regcap2 = ext_reg_cap->regcap2;
 508	/* check if param->wireless_mode is needed */
 509	param->low_2ghz_chan = ext_reg_cap->low_2ghz_chan;
 510	param->high_2ghz_chan = ext_reg_cap->high_2ghz_chan;
 511	param->low_5ghz_chan = ext_reg_cap->low_5ghz_chan;
 512	param->high_5ghz_chan = ext_reg_cap->high_5ghz_chan;
 513
 514	return 0;
 515}
 516
 517static int ath11k_pull_service_ready_tlv(struct ath11k_base *ab,
 518					 const void *evt_buf,
 519					 struct ath11k_targ_cap *cap)
 520{
 521	const struct wmi_service_ready_event *ev = evt_buf;
 522
 523	if (!ev) {
 524		ath11k_err(ab, "%s: failed by NULL param\n",
 525			   __func__);
 526		return -EINVAL;
 527	}
 528
 529	cap->phy_capability = ev->phy_capability;
 530	cap->max_frag_entry = ev->max_frag_entry;
 531	cap->num_rf_chains = ev->num_rf_chains;
 532	cap->ht_cap_info = ev->ht_cap_info;
 533	cap->vht_cap_info = ev->vht_cap_info;
 534	cap->vht_supp_mcs = ev->vht_supp_mcs;
 535	cap->hw_min_tx_power = ev->hw_min_tx_power;
 536	cap->hw_max_tx_power = ev->hw_max_tx_power;
 537	cap->sys_cap_info = ev->sys_cap_info;
 538	cap->min_pkt_size_enable = ev->min_pkt_size_enable;
 539	cap->max_bcn_ie_size = ev->max_bcn_ie_size;
 540	cap->max_num_scan_channels = ev->max_num_scan_channels;
 541	cap->max_supported_macs = ev->max_supported_macs;
 542	cap->wmi_fw_sub_feat_caps = ev->wmi_fw_sub_feat_caps;
 543	cap->txrx_chainmask = ev->txrx_chainmask;
 544	cap->default_dbs_hw_mode_index = ev->default_dbs_hw_mode_index;
 545	cap->num_msdu_desc = ev->num_msdu_desc;
 546
 547	return 0;
 548}
 549
 550/* Save the wmi_service_bitmap into a linear bitmap. The wmi_services in
 551 * wmi_service ready event are advertised in b0-b3 (LSB 4-bits) of each
 552 * 4-byte word.
 553 */
 554static void ath11k_wmi_service_bitmap_copy(struct ath11k_pdev_wmi *wmi,
 555					   const u32 *wmi_svc_bm)
 556{
 557	int i, j;
 558
 559	for (i = 0, j = 0; i < WMI_SERVICE_BM_SIZE && j < WMI_MAX_SERVICE; i++) {
 560		do {
 561			if (wmi_svc_bm[i] & BIT(j % WMI_SERVICE_BITS_IN_SIZE32))
 562				set_bit(j, wmi->wmi_ab->svc_map);
 563		} while (++j % WMI_SERVICE_BITS_IN_SIZE32);
 564	}
 565}
 566
 567static int ath11k_wmi_tlv_svc_rdy_parse(struct ath11k_base *ab, u16 tag, u16 len,
 568					const void *ptr, void *data)
 569{
 570	struct wmi_tlv_svc_ready_parse *svc_ready = data;
 571	struct ath11k_pdev_wmi *wmi_handle = &ab->wmi_ab.wmi[0];
 572	u16 expect_len;
 573
 574	switch (tag) {
 575	case WMI_TAG_SERVICE_READY_EVENT:
 576		if (ath11k_pull_service_ready_tlv(ab, ptr, &ab->target_caps))
 577			return -EINVAL;
 578		break;
 579
 580	case WMI_TAG_ARRAY_UINT32:
 581		if (!svc_ready->wmi_svc_bitmap_done) {
 582			expect_len = WMI_SERVICE_BM_SIZE * sizeof(u32);
 583			if (len < expect_len) {
 584				ath11k_warn(ab, "invalid len %d for the tag 0x%x\n",
 585					    len, tag);
 586				return -EINVAL;
 587			}
 588
 589			ath11k_wmi_service_bitmap_copy(wmi_handle, ptr);
 590
 591			svc_ready->wmi_svc_bitmap_done = true;
 592		}
 593		break;
 594	default:
 595		break;
 596	}
 597
 598	return 0;
 599}
 600
 601static int ath11k_service_ready_event(struct ath11k_base *ab, struct sk_buff *skb)
 602{
 603	struct wmi_tlv_svc_ready_parse svc_ready = { };
 604	int ret;
 605
 606	ret = ath11k_wmi_tlv_iter(ab, skb->data, skb->len,
 607				  ath11k_wmi_tlv_svc_rdy_parse,
 608				  &svc_ready);
 609	if (ret) {
 610		ath11k_warn(ab, "failed to parse tlv %d\n", ret);
 611		return ret;
 612	}
 613
 614	ath11k_dbg(ab, ATH11K_DBG_WMI, "event service ready");
 615
 616	return 0;
 617}
 618
 619struct sk_buff *ath11k_wmi_alloc_skb(struct ath11k_wmi_base *wmi_ab, u32 len)
 620{
 621	struct sk_buff *skb;
 622	struct ath11k_base *ab = wmi_ab->ab;
 623	u32 round_len = roundup(len, 4);
 624
 625	skb = ath11k_htc_alloc_skb(ab, WMI_SKB_HEADROOM + round_len);
 626	if (!skb)
 627		return NULL;
 628
 629	skb_reserve(skb, WMI_SKB_HEADROOM);
 630	if (!IS_ALIGNED((unsigned long)skb->data, 4))
 631		ath11k_warn(ab, "unaligned WMI skb data\n");
 632
 633	skb_put(skb, round_len);
 634	memset(skb->data, 0, round_len);
 635
 636	return skb;
 637}
 638
 639static u32 ath11k_wmi_mgmt_get_freq(struct ath11k *ar,
 640				    struct ieee80211_tx_info *info)
 641{
 642	struct ath11k_base *ab = ar->ab;
 643	u32 freq = 0;
 644
 645	if (ab->hw_params.support_off_channel_tx &&
 646	    ar->scan.is_roc &&
 647	    (info->flags & IEEE80211_TX_CTL_TX_OFFCHAN))
 648		freq = ar->scan.roc_freq;
 649
 650	return freq;
 651}
 652
 653int ath11k_wmi_mgmt_send(struct ath11k *ar, u32 vdev_id, u32 buf_id,
 654			 struct sk_buff *frame)
 655{
 656	struct ath11k_pdev_wmi *wmi = ar->wmi;
 657	struct ieee80211_tx_info *info = IEEE80211_SKB_CB(frame);
 658	struct wmi_mgmt_send_cmd *cmd;
 659	struct wmi_tlv *frame_tlv;
 660	struct sk_buff *skb;
 661	u32 buf_len;
 662	int ret, len;
 663
 664	buf_len = frame->len < WMI_MGMT_SEND_DOWNLD_LEN ?
 665		  frame->len : WMI_MGMT_SEND_DOWNLD_LEN;
 666
 667	len = sizeof(*cmd) + sizeof(*frame_tlv) + roundup(buf_len, 4);
 668
 669	skb = ath11k_wmi_alloc_skb(wmi->wmi_ab, len);
 670	if (!skb)
 671		return -ENOMEM;
 672
 673	cmd = (struct wmi_mgmt_send_cmd *)skb->data;
 674	cmd->tlv_header = FIELD_PREP(WMI_TLV_TAG, WMI_TAG_MGMT_TX_SEND_CMD) |
 675			  FIELD_PREP(WMI_TLV_LEN, sizeof(*cmd) - TLV_HDR_SIZE);
 676	cmd->vdev_id = vdev_id;
 677	cmd->desc_id = buf_id;
 678	cmd->chanfreq = ath11k_wmi_mgmt_get_freq(ar, info);
 679	cmd->paddr_lo = lower_32_bits(ATH11K_SKB_CB(frame)->paddr);
 680	cmd->paddr_hi = upper_32_bits(ATH11K_SKB_CB(frame)->paddr);
 681	cmd->frame_len = frame->len;
 682	cmd->buf_len = buf_len;
 683	cmd->tx_params_valid = 0;
 684
 685	frame_tlv = (struct wmi_tlv *)(skb->data + sizeof(*cmd));
 686	frame_tlv->header = FIELD_PREP(WMI_TLV_TAG, WMI_TAG_ARRAY_BYTE) |
 687			    FIELD_PREP(WMI_TLV_LEN, buf_len);
 688
 689	memcpy(frame_tlv->value, frame->data, buf_len);
 690
 691	ath11k_ce_byte_swap(frame_tlv->value, buf_len);
 692
 693	ret = ath11k_wmi_cmd_send(wmi, skb, WMI_MGMT_TX_SEND_CMDID);
 694	if (ret) {
 695		ath11k_warn(ar->ab,
 696			    "failed to submit WMI_MGMT_TX_SEND_CMDID cmd\n");
 697		dev_kfree_skb(skb);
 698	}
 699
 700	ath11k_dbg(ar->ab, ATH11K_DBG_WMI, "cmd mgmt tx send");
 701
 702	return ret;
 703}
 704
 705int ath11k_wmi_vdev_create(struct ath11k *ar, u8 *macaddr,
 706			   struct vdev_create_params *param)
 707{
 708	struct ath11k_pdev_wmi *wmi = ar->wmi;
 709	struct wmi_vdev_create_cmd *cmd;
 710	struct sk_buff *skb;
 711	struct wmi_vdev_txrx_streams *txrx_streams;
 712	struct wmi_tlv *tlv;
 713	int ret, len;
 714	void *ptr;
 715
 716	/* It can be optimized my sending tx/rx chain configuration
 717	 * only for supported bands instead of always sending it for
 718	 * both the bands.
 719	 */
 720	len = sizeof(*cmd) + TLV_HDR_SIZE +
 721		(WMI_NUM_SUPPORTED_BAND_MAX * sizeof(*txrx_streams));
 722
 723	skb = ath11k_wmi_alloc_skb(wmi->wmi_ab, len);
 724	if (!skb)
 725		return -ENOMEM;
 726
 727	cmd = (struct wmi_vdev_create_cmd *)skb->data;
 728	cmd->tlv_header = FIELD_PREP(WMI_TLV_TAG, WMI_TAG_VDEV_CREATE_CMD) |
 729			  FIELD_PREP(WMI_TLV_LEN, sizeof(*cmd) - TLV_HDR_SIZE);
 730
 731	cmd->vdev_id = param->if_id;
 732	cmd->vdev_type = param->type;
 733	cmd->vdev_subtype = param->subtype;
 734	cmd->num_cfg_txrx_streams = WMI_NUM_SUPPORTED_BAND_MAX;
 735	cmd->pdev_id = param->pdev_id;
 736	cmd->mbssid_flags = param->mbssid_flags;
 737	cmd->mbssid_tx_vdev_id = param->mbssid_tx_vdev_id;
 738
 739	ether_addr_copy(cmd->vdev_macaddr.addr, macaddr);
 740
 741	ptr = skb->data + sizeof(*cmd);
 742	len = WMI_NUM_SUPPORTED_BAND_MAX * sizeof(*txrx_streams);
 743
 744	tlv = ptr;
 745	tlv->header = FIELD_PREP(WMI_TLV_TAG, WMI_TAG_ARRAY_STRUCT) |
 746		      FIELD_PREP(WMI_TLV_LEN, len);
 747
 748	ptr += TLV_HDR_SIZE;
 749	txrx_streams = ptr;
 750	len = sizeof(*txrx_streams);
 751	txrx_streams->tlv_header =
 752		FIELD_PREP(WMI_TLV_TAG, WMI_TAG_VDEV_TXRX_STREAMS) |
 753		FIELD_PREP(WMI_TLV_LEN, len - TLV_HDR_SIZE);
 754	txrx_streams->band = WMI_TPC_CHAINMASK_CONFIG_BAND_2G;
 755	txrx_streams->supported_tx_streams =
 756				 param->chains[NL80211_BAND_2GHZ].tx;
 757	txrx_streams->supported_rx_streams =
 758				 param->chains[NL80211_BAND_2GHZ].rx;
 759
 760	txrx_streams++;
 761	txrx_streams->tlv_header =
 762		FIELD_PREP(WMI_TLV_TAG, WMI_TAG_VDEV_TXRX_STREAMS) |
 763		FIELD_PREP(WMI_TLV_LEN, len - TLV_HDR_SIZE);
 764	txrx_streams->band = WMI_TPC_CHAINMASK_CONFIG_BAND_5G;
 765	txrx_streams->supported_tx_streams =
 766				 param->chains[NL80211_BAND_5GHZ].tx;
 767	txrx_streams->supported_rx_streams =
 768				 param->chains[NL80211_BAND_5GHZ].rx;
 769
 770	ret = ath11k_wmi_cmd_send(wmi, skb, WMI_VDEV_CREATE_CMDID);
 771	if (ret) {
 772		ath11k_warn(ar->ab,
 773			    "failed to submit WMI_VDEV_CREATE_CMDID\n");
 774		dev_kfree_skb(skb);
 775	}
 776
 777	ath11k_dbg(ar->ab, ATH11K_DBG_WMI,
 778		   "cmd vdev create id %d type %d subtype %d macaddr %pM pdevid %d\n",
 779		   param->if_id, param->type, param->subtype,
 780		   macaddr, param->pdev_id);
 781
 782	return ret;
 783}
 784
 785int ath11k_wmi_vdev_delete(struct ath11k *ar, u8 vdev_id)
 786{
 787	struct ath11k_pdev_wmi *wmi = ar->wmi;
 788	struct wmi_vdev_delete_cmd *cmd;
 789	struct sk_buff *skb;
 790	int ret;
 791
 792	skb = ath11k_wmi_alloc_skb(wmi->wmi_ab, sizeof(*cmd));
 793	if (!skb)
 794		return -ENOMEM;
 795
 796	cmd = (struct wmi_vdev_delete_cmd *)skb->data;
 797	cmd->tlv_header = FIELD_PREP(WMI_TLV_TAG, WMI_TAG_VDEV_DELETE_CMD) |
 798			  FIELD_PREP(WMI_TLV_LEN, sizeof(*cmd) - TLV_HDR_SIZE);
 799	cmd->vdev_id = vdev_id;
 800
 801	ret = ath11k_wmi_cmd_send(wmi, skb, WMI_VDEV_DELETE_CMDID);
 802	if (ret) {
 803		ath11k_warn(ar->ab, "failed to submit WMI_VDEV_DELETE_CMDID\n");
 804		dev_kfree_skb(skb);
 805	}
 806
 807	ath11k_dbg(ar->ab, ATH11K_DBG_WMI, "cmd vdev delete id %d\n", vdev_id);
 808
 809	return ret;
 810}
 811
 812int ath11k_wmi_vdev_stop(struct ath11k *ar, u8 vdev_id)
 813{
 814	struct ath11k_pdev_wmi *wmi = ar->wmi;
 815	struct wmi_vdev_stop_cmd *cmd;
 816	struct sk_buff *skb;
 817	int ret;
 818
 819	skb = ath11k_wmi_alloc_skb(wmi->wmi_ab, sizeof(*cmd));
 820	if (!skb)
 821		return -ENOMEM;
 822
 823	cmd = (struct wmi_vdev_stop_cmd *)skb->data;
 824
 825	cmd->tlv_header = FIELD_PREP(WMI_TLV_TAG, WMI_TAG_VDEV_STOP_CMD) |
 826			  FIELD_PREP(WMI_TLV_LEN, sizeof(*cmd) - TLV_HDR_SIZE);
 827	cmd->vdev_id = vdev_id;
 828
 829	ret = ath11k_wmi_cmd_send(wmi, skb, WMI_VDEV_STOP_CMDID);
 830	if (ret) {
 831		ath11k_warn(ar->ab, "failed to submit WMI_VDEV_STOP cmd\n");
 832		dev_kfree_skb(skb);
 833	}
 834
 835	ath11k_dbg(ar->ab, ATH11K_DBG_WMI, "cmd vdev stop id 0x%x\n", vdev_id);
 836
 837	return ret;
 838}
 839
 840int ath11k_wmi_vdev_down(struct ath11k *ar, u8 vdev_id)
 841{
 842	struct ath11k_pdev_wmi *wmi = ar->wmi;
 843	struct wmi_vdev_down_cmd *cmd;
 844	struct sk_buff *skb;
 845	int ret;
 846
 847	skb = ath11k_wmi_alloc_skb(wmi->wmi_ab, sizeof(*cmd));
 848	if (!skb)
 849		return -ENOMEM;
 850
 851	cmd = (struct wmi_vdev_down_cmd *)skb->data;
 852
 853	cmd->tlv_header = FIELD_PREP(WMI_TLV_TAG, WMI_TAG_VDEV_DOWN_CMD) |
 854			  FIELD_PREP(WMI_TLV_LEN, sizeof(*cmd) - TLV_HDR_SIZE);
 855	cmd->vdev_id = vdev_id;
 856
 857	ret = ath11k_wmi_cmd_send(wmi, skb, WMI_VDEV_DOWN_CMDID);
 858	if (ret) {
 859		ath11k_warn(ar->ab, "failed to submit WMI_VDEV_DOWN cmd\n");
 860		dev_kfree_skb(skb);
 861	}
 862
 863	ath11k_dbg(ar->ab, ATH11K_DBG_WMI, "cmd vdev down id 0x%x\n", vdev_id);
 864
 865	return ret;
 866}
 867
 868static void ath11k_wmi_put_wmi_channel(struct wmi_channel *chan,
 869				       struct wmi_vdev_start_req_arg *arg)
 870{
 871	u32 center_freq1 = arg->channel.band_center_freq1;
 872
 873	memset(chan, 0, sizeof(*chan));
 874
 875	chan->mhz = arg->channel.freq;
 876	chan->band_center_freq1 = arg->channel.band_center_freq1;
 877
 878	if (arg->channel.mode == MODE_11AX_HE160) {
 879		if (arg->channel.freq > arg->channel.band_center_freq1)
 880			chan->band_center_freq1 = center_freq1 + 40;
 881		else
 882			chan->band_center_freq1 = center_freq1 - 40;
 883
 884		chan->band_center_freq2 = arg->channel.band_center_freq1;
 885
 886	} else if ((arg->channel.mode == MODE_11AC_VHT80_80) ||
 887		   (arg->channel.mode == MODE_11AX_HE80_80)) {
 888		chan->band_center_freq2 = arg->channel.band_center_freq2;
 889	} else {
 890		chan->band_center_freq2 = 0;
 891	}
 892
 893	chan->info |= FIELD_PREP(WMI_CHAN_INFO_MODE, arg->channel.mode);
 894	if (arg->channel.passive)
 895		chan->info |= WMI_CHAN_INFO_PASSIVE;
 896	if (arg->channel.allow_ibss)
 897		chan->info |= WMI_CHAN_INFO_ADHOC_ALLOWED;
 898	if (arg->channel.allow_ht)
 899		chan->info |= WMI_CHAN_INFO_ALLOW_HT;
 900	if (arg->channel.allow_vht)
 901		chan->info |= WMI_CHAN_INFO_ALLOW_VHT;
 902	if (arg->channel.allow_he)
 903		chan->info |= WMI_CHAN_INFO_ALLOW_HE;
 904	if (arg->channel.ht40plus)
 905		chan->info |= WMI_CHAN_INFO_HT40_PLUS;
 906	if (arg->channel.chan_radar)
 907		chan->info |= WMI_CHAN_INFO_DFS;
 908	if (arg->channel.freq2_radar)
 909		chan->info |= WMI_CHAN_INFO_DFS_FREQ2;
 910
 911	chan->reg_info_1 = FIELD_PREP(WMI_CHAN_REG_INFO1_MAX_PWR,
 912				      arg->channel.max_power) |
 913		FIELD_PREP(WMI_CHAN_REG_INFO1_MAX_REG_PWR,
 914			   arg->channel.max_reg_power);
 915
 916	chan->reg_info_2 = FIELD_PREP(WMI_CHAN_REG_INFO2_ANT_MAX,
 917				      arg->channel.max_antenna_gain) |
 918		FIELD_PREP(WMI_CHAN_REG_INFO2_MAX_TX_PWR,
 919			   arg->channel.max_power);
 920}
 921
 922int ath11k_wmi_vdev_start(struct ath11k *ar, struct wmi_vdev_start_req_arg *arg,
 923			  bool restart)
 924{
 925	struct ath11k_pdev_wmi *wmi = ar->wmi;
 926	struct wmi_vdev_start_request_cmd *cmd;
 927	struct sk_buff *skb;
 928	struct wmi_channel *chan;
 929	struct wmi_tlv *tlv;
 930	void *ptr;
 931	int ret, len;
 932
 933	if (WARN_ON(arg->ssid_len > sizeof(cmd->ssid.ssid)))
 934		return -EINVAL;
 935
 936	len = sizeof(*cmd) + sizeof(*chan) + TLV_HDR_SIZE;
 937
 938	skb = ath11k_wmi_alloc_skb(wmi->wmi_ab, len);
 939	if (!skb)
 940		return -ENOMEM;
 941
 942	cmd = (struct wmi_vdev_start_request_cmd *)skb->data;
 943	cmd->tlv_header = FIELD_PREP(WMI_TLV_TAG,
 944				     WMI_TAG_VDEV_START_REQUEST_CMD) |
 945			  FIELD_PREP(WMI_TLV_LEN, sizeof(*cmd) - TLV_HDR_SIZE);
 946	cmd->vdev_id = arg->vdev_id;
 947	cmd->beacon_interval = arg->bcn_intval;
 948	cmd->bcn_tx_rate = arg->bcn_tx_rate;
 949	cmd->dtim_period = arg->dtim_period;
 950	cmd->num_noa_descriptors = arg->num_noa_descriptors;
 951	cmd->preferred_rx_streams = arg->pref_rx_streams;
 952	cmd->preferred_tx_streams = arg->pref_tx_streams;
 953	cmd->cac_duration_ms = arg->cac_duration_ms;
 954	cmd->regdomain = arg->regdomain;
 955	cmd->he_ops = arg->he_ops;
 956	cmd->mbssid_flags = arg->mbssid_flags;
 957	cmd->mbssid_tx_vdev_id = arg->mbssid_tx_vdev_id;
 958
 959	if (!restart) {
 960		if (arg->ssid) {
 961			cmd->ssid.ssid_len = arg->ssid_len;
 962			memcpy(cmd->ssid.ssid, arg->ssid, arg->ssid_len);
 963		}
 964		if (arg->hidden_ssid)
 965			cmd->flags |= WMI_VDEV_START_HIDDEN_SSID;
 966		if (arg->pmf_enabled)
 967			cmd->flags |= WMI_VDEV_START_PMF_ENABLED;
 968	}
 969
 970	cmd->flags |= WMI_VDEV_START_LDPC_RX_ENABLED;
 971	if (test_bit(ATH11K_FLAG_HW_CRYPTO_DISABLED, &ar->ab->dev_flags))
 972		cmd->flags |= WMI_VDEV_START_HW_ENCRYPTION_DISABLED;
 973
 974	ptr = skb->data + sizeof(*cmd);
 975	chan = ptr;
 976
 977	ath11k_wmi_put_wmi_channel(chan, arg);
 978
 979	chan->tlv_header = FIELD_PREP(WMI_TLV_TAG, WMI_TAG_CHANNEL) |
 980			   FIELD_PREP(WMI_TLV_LEN,
 981				      sizeof(*chan) - TLV_HDR_SIZE);
 982	ptr += sizeof(*chan);
 983
 984	tlv = ptr;
 985	tlv->header = FIELD_PREP(WMI_TLV_TAG, WMI_TAG_ARRAY_STRUCT) |
 986		      FIELD_PREP(WMI_TLV_LEN, 0);
 987
 988	/* Note: This is a nested TLV containing:
 989	 * [wmi_tlv][ath11k_wmi_p2p_noa_descriptor][wmi_tlv]..
 990	 */
 991
 992	ptr += sizeof(*tlv);
 993
 994	if (restart)
 995		ret = ath11k_wmi_cmd_send(wmi, skb,
 996					  WMI_VDEV_RESTART_REQUEST_CMDID);
 997	else
 998		ret = ath11k_wmi_cmd_send(wmi, skb,
 999					  WMI_VDEV_START_REQUEST_CMDID);
1000	if (ret) {
1001		ath11k_warn(ar->ab, "failed to submit vdev_%s cmd\n",
1002			    restart ? "restart" : "start");
1003		dev_kfree_skb(skb);
1004	}
1005
1006	ath11k_dbg(ar->ab, ATH11K_DBG_WMI, "cmd vdev %s id 0x%x freq 0x%x mode 0x%x\n",
1007		   restart ? "restart" : "start", arg->vdev_id,
1008		   arg->channel.freq, arg->channel.mode);
1009
1010	return ret;
1011}
1012
1013int ath11k_wmi_vdev_up(struct ath11k *ar, u32 vdev_id, u32 aid, const u8 *bssid,
1014		       u8 *tx_bssid, u32 nontx_profile_idx, u32 nontx_profile_cnt)
1015{
1016	struct ath11k_pdev_wmi *wmi = ar->wmi;
1017	struct wmi_vdev_up_cmd *cmd;
1018	struct ieee80211_bss_conf *bss_conf;
1019	struct ath11k_vif *arvif;
1020	struct sk_buff *skb;
1021	int ret;
1022
1023	arvif = ath11k_mac_get_arvif(ar, vdev_id);
1024
1025	skb = ath11k_wmi_alloc_skb(wmi->wmi_ab, sizeof(*cmd));
1026	if (!skb)
1027		return -ENOMEM;
1028
1029	cmd = (struct wmi_vdev_up_cmd *)skb->data;
1030
1031	cmd->tlv_header = FIELD_PREP(WMI_TLV_TAG, WMI_TAG_VDEV_UP_CMD) |
1032			  FIELD_PREP(WMI_TLV_LEN, sizeof(*cmd) - TLV_HDR_SIZE);
1033	cmd->vdev_id = vdev_id;
1034	cmd->vdev_assoc_id = aid;
1035
1036	ether_addr_copy(cmd->vdev_bssid.addr, bssid);
1037
1038	cmd->nontx_profile_idx = nontx_profile_idx;
1039	cmd->nontx_profile_cnt = nontx_profile_cnt;
1040	if (tx_bssid)
1041		ether_addr_copy(cmd->tx_vdev_bssid.addr, tx_bssid);
1042
1043	if (arvif && arvif->vif->type == NL80211_IFTYPE_STATION) {
1044		bss_conf = &arvif->vif->bss_conf;
1045
1046		if (bss_conf->nontransmitted) {
1047			ether_addr_copy(cmd->tx_vdev_bssid.addr,
1048					bss_conf->transmitter_bssid);
1049			cmd->nontx_profile_idx = bss_conf->bssid_index;
1050			cmd->nontx_profile_cnt = bss_conf->bssid_indicator;
1051		}
1052	}
1053
1054	ret = ath11k_wmi_cmd_send(wmi, skb, WMI_VDEV_UP_CMDID);
1055	if (ret) {
1056		ath11k_warn(ar->ab, "failed to submit WMI_VDEV_UP cmd\n");
1057		dev_kfree_skb(skb);
1058	}
1059
1060	ath11k_dbg(ar->ab, ATH11K_DBG_WMI,
1061		   "cmd vdev up id 0x%x assoc id %d bssid %pM\n",
1062		   vdev_id, aid, bssid);
1063
1064	return ret;
1065}
1066
1067int ath11k_wmi_send_peer_create_cmd(struct ath11k *ar,
1068				    struct peer_create_params *param)
1069{
1070	struct ath11k_pdev_wmi *wmi = ar->wmi;
1071	struct wmi_peer_create_cmd *cmd;
1072	struct sk_buff *skb;
1073	int ret;
1074
1075	skb = ath11k_wmi_alloc_skb(wmi->wmi_ab, sizeof(*cmd));
1076	if (!skb)
1077		return -ENOMEM;
1078
1079	cmd = (struct wmi_peer_create_cmd *)skb->data;
1080	cmd->tlv_header = FIELD_PREP(WMI_TLV_TAG, WMI_TAG_PEER_CREATE_CMD) |
1081			  FIELD_PREP(WMI_TLV_LEN, sizeof(*cmd) - TLV_HDR_SIZE);
1082
1083	ether_addr_copy(cmd->peer_macaddr.addr, param->peer_addr);
1084	cmd->peer_type = param->peer_type;
1085	cmd->vdev_id = param->vdev_id;
1086
1087	ret = ath11k_wmi_cmd_send(wmi, skb, WMI_PEER_CREATE_CMDID);
1088	if (ret) {
1089		ath11k_warn(ar->ab, "failed to submit WMI_PEER_CREATE cmd\n");
1090		dev_kfree_skb(skb);
1091	}
1092
1093	ath11k_dbg(ar->ab, ATH11K_DBG_WMI,
1094		   "cmd peer create vdev_id %d peer_addr %pM\n",
1095		   param->vdev_id, param->peer_addr);
1096
1097	return ret;
1098}
1099
1100int ath11k_wmi_send_peer_delete_cmd(struct ath11k *ar,
1101				    const u8 *peer_addr, u8 vdev_id)
1102{
1103	struct ath11k_pdev_wmi *wmi = ar->wmi;
1104	struct wmi_peer_delete_cmd *cmd;
1105	struct sk_buff *skb;
1106	int ret;
1107
1108	skb = ath11k_wmi_alloc_skb(wmi->wmi_ab, sizeof(*cmd));
1109	if (!skb)
1110		return -ENOMEM;
1111
1112	cmd = (struct wmi_peer_delete_cmd *)skb->data;
1113	cmd->tlv_header = FIELD_PREP(WMI_TLV_TAG, WMI_TAG_PEER_DELETE_CMD) |
1114			  FIELD_PREP(WMI_TLV_LEN, sizeof(*cmd) - TLV_HDR_SIZE);
1115
1116	ether_addr_copy(cmd->peer_macaddr.addr, peer_addr);
1117	cmd->vdev_id = vdev_id;
1118
1119	ret = ath11k_wmi_cmd_send(wmi, skb, WMI_PEER_DELETE_CMDID);
1120	if (ret) {
1121		ath11k_warn(ar->ab, "failed to send WMI_PEER_DELETE cmd\n");
1122		dev_kfree_skb(skb);
1123	}
1124
1125	ath11k_dbg(ar->ab, ATH11K_DBG_WMI,
1126		   "cmd peer delete vdev_id %d peer_addr %pM\n",
1127		   vdev_id,  peer_addr);
1128
1129	return ret;
1130}
1131
1132int ath11k_wmi_send_pdev_set_regdomain(struct ath11k *ar,
1133				       struct pdev_set_regdomain_params *param)
1134{
1135	struct ath11k_pdev_wmi *wmi = ar->wmi;
1136	struct wmi_pdev_set_regdomain_cmd *cmd;
1137	struct sk_buff *skb;
1138	int ret;
1139
1140	skb = ath11k_wmi_alloc_skb(wmi->wmi_ab, sizeof(*cmd));
1141	if (!skb)
1142		return -ENOMEM;
1143
1144	cmd = (struct wmi_pdev_set_regdomain_cmd *)skb->data;
1145	cmd->tlv_header = FIELD_PREP(WMI_TLV_TAG,
1146				     WMI_TAG_PDEV_SET_REGDOMAIN_CMD) |
1147			  FIELD_PREP(WMI_TLV_LEN, sizeof(*cmd) - TLV_HDR_SIZE);
1148
1149	cmd->reg_domain = param->current_rd_in_use;
1150	cmd->reg_domain_2g = param->current_rd_2g;
1151	cmd->reg_domain_5g = param->current_rd_5g;
1152	cmd->conformance_test_limit_2g = param->ctl_2g;
1153	cmd->conformance_test_limit_5g = param->ctl_5g;
1154	cmd->dfs_domain = param->dfs_domain;
1155	cmd->pdev_id = param->pdev_id;
1156
1157	ret = ath11k_wmi_cmd_send(wmi, skb, WMI_PDEV_SET_REGDOMAIN_CMDID);
1158	if (ret) {
1159		ath11k_warn(ar->ab,
1160			    "failed to send WMI_PDEV_SET_REGDOMAIN cmd\n");
1161		dev_kfree_skb(skb);
1162	}
1163
1164	ath11k_dbg(ar->ab, ATH11K_DBG_WMI,
1165		   "cmd pdev regd rd %d rd2g %d rd5g %d domain %d pdev id %d\n",
1166		   param->current_rd_in_use, param->current_rd_2g,
1167		   param->current_rd_5g, param->dfs_domain, param->pdev_id);
1168
1169	return ret;
1170}
1171
1172int ath11k_wmi_set_peer_param(struct ath11k *ar, const u8 *peer_addr,
1173			      u32 vdev_id, u32 param_id, u32 param_val)
1174{
1175	struct ath11k_pdev_wmi *wmi = ar->wmi;
1176	struct wmi_peer_set_param_cmd *cmd;
1177	struct sk_buff *skb;
1178	int ret;
1179
1180	skb = ath11k_wmi_alloc_skb(wmi->wmi_ab, sizeof(*cmd));
1181	if (!skb)
1182		return -ENOMEM;
1183
1184	cmd = (struct wmi_peer_set_param_cmd *)skb->data;
1185	cmd->tlv_header = FIELD_PREP(WMI_TLV_TAG, WMI_TAG_PEER_SET_PARAM_CMD) |
1186			  FIELD_PREP(WMI_TLV_LEN, sizeof(*cmd) - TLV_HDR_SIZE);
1187	ether_addr_copy(cmd->peer_macaddr.addr, peer_addr);
1188	cmd->vdev_id = vdev_id;
1189	cmd->param_id = param_id;
1190	cmd->param_value = param_val;
1191
1192	ret = ath11k_wmi_cmd_send(wmi, skb, WMI_PEER_SET_PARAM_CMDID);
1193	if (ret) {
1194		ath11k_warn(ar->ab, "failed to send WMI_PEER_SET_PARAM cmd\n");
1195		dev_kfree_skb(skb);
1196	}
1197
1198	ath11k_dbg(ar->ab, ATH11K_DBG_WMI,
1199		   "cmd peer set param vdev %d peer 0x%pM set param %d value %d\n",
1200		   vdev_id, peer_addr, param_id, param_val);
1201
1202	return ret;
1203}
1204
1205int ath11k_wmi_send_peer_flush_tids_cmd(struct ath11k *ar,
1206					u8 peer_addr[ETH_ALEN],
1207					struct peer_flush_params *param)
1208{
1209	struct ath11k_pdev_wmi *wmi = ar->wmi;
1210	struct wmi_peer_flush_tids_cmd *cmd;
1211	struct sk_buff *skb;
1212	int ret;
1213
1214	skb = ath11k_wmi_alloc_skb(wmi->wmi_ab, sizeof(*cmd));
1215	if (!skb)
1216		return -ENOMEM;
1217
1218	cmd = (struct wmi_peer_flush_tids_cmd *)skb->data;
1219	cmd->tlv_header = FIELD_PREP(WMI_TLV_TAG, WMI_TAG_PEER_FLUSH_TIDS_CMD) |
1220			  FIELD_PREP(WMI_TLV_LEN, sizeof(*cmd) - TLV_HDR_SIZE);
1221
1222	ether_addr_copy(cmd->peer_macaddr.addr, peer_addr);
1223	cmd->peer_tid_bitmap = param->peer_tid_bitmap;
1224	cmd->vdev_id = param->vdev_id;
1225
1226	ret = ath11k_wmi_cmd_send(wmi, skb, WMI_PEER_FLUSH_TIDS_CMDID);
1227	if (ret) {
1228		ath11k_warn(ar->ab,
1229			    "failed to send WMI_PEER_FLUSH_TIDS cmd\n");
1230		dev_kfree_skb(skb);
1231	}
1232
1233	ath11k_dbg(ar->ab, ATH11K_DBG_WMI,
1234		   "cmd peer flush tids vdev_id %d peer_addr %pM tids %08x\n",
1235		   param->vdev_id, peer_addr, param->peer_tid_bitmap);
1236
1237	return ret;
1238}
1239
1240int ath11k_wmi_peer_rx_reorder_queue_setup(struct ath11k *ar,
1241					   int vdev_id, const u8 *addr,
1242					   dma_addr_t paddr, u8 tid,
1243					   u8 ba_window_size_valid,
1244					   u32 ba_window_size)
1245{
1246	struct wmi_peer_reorder_queue_setup_cmd *cmd;
1247	struct sk_buff *skb;
1248	int ret;
1249
1250	skb = ath11k_wmi_alloc_skb(ar->wmi->wmi_ab, sizeof(*cmd));
1251	if (!skb)
1252		return -ENOMEM;
1253
1254	cmd = (struct wmi_peer_reorder_queue_setup_cmd *)skb->data;
1255	cmd->tlv_header = FIELD_PREP(WMI_TLV_TAG,
1256				     WMI_TAG_REORDER_QUEUE_SETUP_CMD) |
1257			  FIELD_PREP(WMI_TLV_LEN, sizeof(*cmd) - TLV_HDR_SIZE);
1258
1259	ether_addr_copy(cmd->peer_macaddr.addr, addr);
1260	cmd->vdev_id = vdev_id;
1261	cmd->tid = tid;
1262	cmd->queue_ptr_lo = lower_32_bits(paddr);
1263	cmd->queue_ptr_hi = upper_32_bits(paddr);
1264	cmd->queue_no = tid;
1265	cmd->ba_window_size_valid = ba_window_size_valid;
1266	cmd->ba_window_size = ba_window_size;
1267
1268	ret = ath11k_wmi_cmd_send(ar->wmi, skb,
1269				  WMI_PEER_REORDER_QUEUE_SETUP_CMDID);
1270	if (ret) {
1271		ath11k_warn(ar->ab,
1272			    "failed to send WMI_PEER_REORDER_QUEUE_SETUP\n");
1273		dev_kfree_skb(skb);
1274	}
1275
1276	ath11k_dbg(ar->ab, ATH11K_DBG_WMI,
1277		   "cmd peer reorder queue setup addr %pM vdev_id %d tid %d\n",
1278		   addr, vdev_id, tid);
1279
1280	return ret;
1281}
1282
1283int
1284ath11k_wmi_rx_reord_queue_remove(struct ath11k *ar,
1285				 struct rx_reorder_queue_remove_params *param)
1286{
1287	struct ath11k_pdev_wmi *wmi = ar->wmi;
1288	struct wmi_peer_reorder_queue_remove_cmd *cmd;
1289	struct sk_buff *skb;
1290	int ret;
1291
1292	skb = ath11k_wmi_alloc_skb(wmi->wmi_ab, sizeof(*cmd));
1293	if (!skb)
1294		return -ENOMEM;
1295
1296	cmd = (struct wmi_peer_reorder_queue_remove_cmd *)skb->data;
1297	cmd->tlv_header = FIELD_PREP(WMI_TLV_TAG,
1298				     WMI_TAG_REORDER_QUEUE_REMOVE_CMD) |
1299			  FIELD_PREP(WMI_TLV_LEN, sizeof(*cmd) - TLV_HDR_SIZE);
1300
1301	ether_addr_copy(cmd->peer_macaddr.addr, param->peer_macaddr);
1302	cmd->vdev_id = param->vdev_id;
1303	cmd->tid_mask = param->peer_tid_bitmap;
1304
1305	ret = ath11k_wmi_cmd_send(wmi, skb,
1306				  WMI_PEER_REORDER_QUEUE_REMOVE_CMDID);
1307	if (ret) {
1308		ath11k_warn(ar->ab,
1309			    "failed to send WMI_PEER_REORDER_QUEUE_REMOVE_CMDID");
1310		dev_kfree_skb(skb);
1311	}
1312
1313	ath11k_dbg(ar->ab, ATH11K_DBG_WMI,
1314		   "cmd peer reorder queue remove peer_macaddr %pM vdev_id %d tid_map %d",
1315		   param->peer_macaddr, param->vdev_id, param->peer_tid_bitmap);
1316
1317	return ret;
1318}
1319
1320int ath11k_wmi_pdev_set_param(struct ath11k *ar, u32 param_id,
1321			      u32 param_value, u8 pdev_id)
1322{
1323	struct ath11k_pdev_wmi *wmi = ar->wmi;
1324	struct wmi_pdev_set_param_cmd *cmd;
1325	struct sk_buff *skb;
1326	int ret;
1327
1328	skb = ath11k_wmi_alloc_skb(wmi->wmi_ab, sizeof(*cmd));
1329	if (!skb)
1330		return -ENOMEM;
1331
1332	cmd = (struct wmi_pdev_set_param_cmd *)skb->data;
1333	cmd->tlv_header = FIELD_PREP(WMI_TLV_TAG, WMI_TAG_PDEV_SET_PARAM_CMD) |
1334			  FIELD_PREP(WMI_TLV_LEN, sizeof(*cmd) - TLV_HDR_SIZE);
1335	cmd->pdev_id = pdev_id;
1336	cmd->param_id = param_id;
1337	cmd->param_value = param_value;
1338
1339	ret = ath11k_wmi_cmd_send(wmi, skb, WMI_PDEV_SET_PARAM_CMDID);
1340	if (ret) {
1341		ath11k_warn(ar->ab, "failed to send WMI_PDEV_SET_PARAM cmd\n");
1342		dev_kfree_skb(skb);
1343	}
1344
1345	ath11k_dbg(ar->ab, ATH11K_DBG_WMI,
1346		   "cmd pdev set param %d pdev id %d value %d\n",
1347		   param_id, pdev_id, param_value);
1348
1349	return ret;
1350}
1351
1352int ath11k_wmi_pdev_set_ps_mode(struct ath11k *ar, int vdev_id,
1353				enum wmi_sta_ps_mode psmode)
1354{
1355	struct ath11k_pdev_wmi *wmi = ar->wmi;
1356	struct wmi_pdev_set_ps_mode_cmd *cmd;
1357	struct sk_buff *skb;
1358	int ret;
1359
1360	skb = ath11k_wmi_alloc_skb(wmi->wmi_ab, sizeof(*cmd));
1361	if (!skb)
1362		return -ENOMEM;
1363
1364	cmd = (struct wmi_pdev_set_ps_mode_cmd *)skb->data;
1365	cmd->tlv_header = FIELD_PREP(WMI_TLV_TAG, WMI_TAG_STA_POWERSAVE_MODE_CMD) |
1366			  FIELD_PREP(WMI_TLV_LEN, sizeof(*cmd) - TLV_HDR_SIZE);
1367	cmd->vdev_id = vdev_id;
1368	cmd->sta_ps_mode = psmode;
1369
1370	ret = ath11k_wmi_cmd_send(wmi, skb, WMI_STA_POWERSAVE_MODE_CMDID);
1371	if (ret) {
1372		ath11k_warn(ar->ab, "failed to send WMI_PDEV_SET_PARAM cmd\n");
1373		dev_kfree_skb(skb);
1374	}
1375
1376	ath11k_dbg(ar->ab, ATH11K_DBG_WMI,
1377		   "cmd sta powersave mode psmode %d vdev id %d\n",
1378		   psmode, vdev_id);
1379
1380	return ret;
1381}
1382
1383int ath11k_wmi_pdev_suspend(struct ath11k *ar, u32 suspend_opt,
1384			    u32 pdev_id)
1385{
1386	struct ath11k_pdev_wmi *wmi = ar->wmi;
1387	struct wmi_pdev_suspend_cmd *cmd;
1388	struct sk_buff *skb;
1389	int ret;
1390
1391	skb = ath11k_wmi_alloc_skb(wmi->wmi_ab, sizeof(*cmd));
1392	if (!skb)
1393		return -ENOMEM;
1394
1395	cmd = (struct wmi_pdev_suspend_cmd *)skb->data;
1396
1397	cmd->tlv_header = FIELD_PREP(WMI_TLV_TAG, WMI_TAG_PDEV_SUSPEND_CMD) |
1398			  FIELD_PREP(WMI_TLV_LEN, sizeof(*cmd) - TLV_HDR_SIZE);
1399
1400	cmd->suspend_opt = suspend_opt;
1401	cmd->pdev_id = pdev_id;
1402
1403	ret = ath11k_wmi_cmd_send(wmi, skb, WMI_PDEV_SUSPEND_CMDID);
1404	if (ret) {
1405		ath11k_warn(ar->ab, "failed to send WMI_PDEV_SUSPEND cmd\n");
1406		dev_kfree_skb(skb);
1407	}
1408
1409	ath11k_dbg(ar->ab, ATH11K_DBG_WMI,
1410		   "cmd pdev suspend pdev_id %d\n", pdev_id);
1411
1412	return ret;
1413}
1414
1415int ath11k_wmi_pdev_resume(struct ath11k *ar, u32 pdev_id)
1416{
1417	struct ath11k_pdev_wmi *wmi = ar->wmi;
1418	struct wmi_pdev_resume_cmd *cmd;
1419	struct sk_buff *skb;
1420	int ret;
1421
1422	skb = ath11k_wmi_alloc_skb(wmi->wmi_ab, sizeof(*cmd));
1423	if (!skb)
1424		return -ENOMEM;
1425
1426	cmd = (struct wmi_pdev_resume_cmd *)skb->data;
1427
1428	cmd->tlv_header = FIELD_PREP(WMI_TLV_TAG, WMI_TAG_PDEV_RESUME_CMD) |
1429			  FIELD_PREP(WMI_TLV_LEN, sizeof(*cmd) - TLV_HDR_SIZE);
1430	cmd->pdev_id = pdev_id;
1431
1432	ret = ath11k_wmi_cmd_send(wmi, skb, WMI_PDEV_RESUME_CMDID);
1433	if (ret) {
1434		ath11k_warn(ar->ab, "failed to send WMI_PDEV_RESUME cmd\n");
1435		dev_kfree_skb(skb);
1436	}
1437
1438	ath11k_dbg(ar->ab, ATH11K_DBG_WMI,
1439		   "cmd pdev resume pdev id %d\n", pdev_id);
1440
1441	return ret;
1442}
1443
1444/* TODO FW Support for the cmd is not available yet.
1445 * Can be tested once the command and corresponding
1446 * event is implemented in FW
1447 */
1448int ath11k_wmi_pdev_bss_chan_info_request(struct ath11k *ar,
1449					  enum wmi_bss_chan_info_req_type type)
1450{
1451	struct ath11k_pdev_wmi *wmi = ar->wmi;
1452	struct wmi_pdev_bss_chan_info_req_cmd *cmd;
1453	struct sk_buff *skb;
1454	int ret;
1455
1456	skb = ath11k_wmi_alloc_skb(wmi->wmi_ab, sizeof(*cmd));
1457	if (!skb)
1458		return -ENOMEM;
1459
1460	cmd = (struct wmi_pdev_bss_chan_info_req_cmd *)skb->data;
1461
1462	cmd->tlv_header = FIELD_PREP(WMI_TLV_TAG,
1463				     WMI_TAG_PDEV_BSS_CHAN_INFO_REQUEST) |
1464			  FIELD_PREP(WMI_TLV_LEN, sizeof(*cmd) - TLV_HDR_SIZE);
1465	cmd->req_type = type;
1466	cmd->pdev_id = ar->pdev->pdev_id;
1467
1468	ret = ath11k_wmi_cmd_send(wmi, skb,
1469				  WMI_PDEV_BSS_CHAN_INFO_REQUEST_CMDID);
1470	if (ret) {
1471		ath11k_warn(ar->ab,
1472			    "failed to send WMI_PDEV_BSS_CHAN_INFO_REQUEST cmd\n");
1473		dev_kfree_skb(skb);
1474	}
1475
1476	ath11k_dbg(ar->ab, ATH11K_DBG_WMI,
1477		   "cmd pdev bss chan info request type %d\n", type);
1478
1479	return ret;
1480}
1481
1482int ath11k_wmi_send_set_ap_ps_param_cmd(struct ath11k *ar, u8 *peer_addr,
1483					struct ap_ps_params *param)
1484{
1485	struct ath11k_pdev_wmi *wmi = ar->wmi;
1486	struct wmi_ap_ps_peer_cmd *cmd;
1487	struct sk_buff *skb;
1488	int ret;
1489
1490	skb = ath11k_wmi_alloc_skb(wmi->wmi_ab, sizeof(*cmd));
1491	if (!skb)
1492		return -ENOMEM;
1493
1494	cmd = (struct wmi_ap_ps_peer_cmd *)skb->data;
1495	cmd->tlv_header = FIELD_PREP(WMI_TLV_TAG, WMI_TAG_AP_PS_PEER_CMD) |
1496			  FIELD_PREP(WMI_TLV_LEN, sizeof(*cmd) - TLV_HDR_SIZE);
1497
1498	cmd->vdev_id = param->vdev_id;
1499	ether_addr_copy(cmd->peer_macaddr.addr, peer_addr);
1500	cmd->param = param->param;
1501	cmd->value = param->value;
1502
1503	ret = ath11k_wmi_cmd_send(wmi, skb, WMI_AP_PS_PEER_PARAM_CMDID);
1504	if (ret) {
1505		ath11k_warn(ar->ab,
1506			    "failed to send WMI_AP_PS_PEER_PARAM_CMDID\n");
1507		dev_kfree_skb(skb);
1508	}
1509
1510	ath11k_dbg(ar->ab, ATH11K_DBG_WMI,
1511		   "cmd ap ps peer param vdev id %d peer %pM param %d value %d\n",
1512		   param->vdev_id, peer_addr, param->param, param->value);
1513
1514	return ret;
1515}
1516
1517int ath11k_wmi_set_sta_ps_param(struct ath11k *ar, u32 vdev_id,
1518				u32 param, u32 param_value)
1519{
1520	struct ath11k_pdev_wmi *wmi = ar->wmi;
1521	struct wmi_sta_powersave_param_cmd *cmd;
1522	struct sk_buff *skb;
1523	int ret;
1524
1525	skb = ath11k_wmi_alloc_skb(wmi->wmi_ab, sizeof(*cmd));
1526	if (!skb)
1527		return -ENOMEM;
1528
1529	cmd = (struct wmi_sta_powersave_param_cmd *)skb->data;
1530	cmd->tlv_header = FIELD_PREP(WMI_TLV_TAG,
1531				     WMI_TAG_STA_POWERSAVE_PARAM_CMD) |
1532			  FIELD_PREP(WMI_TLV_LEN, sizeof(*cmd) - TLV_HDR_SIZE);
1533
1534	cmd->vdev_id = vdev_id;
1535	cmd->param = param;
1536	cmd->value = param_value;
1537
1538	ret = ath11k_wmi_cmd_send(wmi, skb, WMI_STA_POWERSAVE_PARAM_CMDID);
1539	if (ret) {
1540		ath11k_warn(ar->ab, "failed to send WMI_STA_POWERSAVE_PARAM_CMDID");
1541		dev_kfree_skb(skb);
1542	}
1543
1544	ath11k_dbg(ar->ab, ATH11K_DBG_WMI,
1545		   "cmd set powersave param vdev_id %d param %d value %d\n",
1546		   vdev_id, param, param_value);
1547
1548	return ret;
1549}
1550
1551int ath11k_wmi_force_fw_hang_cmd(struct ath11k *ar, u32 type, u32 delay_time_ms)
1552{
1553	struct ath11k_pdev_wmi *wmi = ar->wmi;
1554	struct wmi_force_fw_hang_cmd *cmd;
1555	struct sk_buff *skb;
1556	int ret, len;
1557
1558	len = sizeof(*cmd);
1559
1560	skb = ath11k_wmi_alloc_skb(wmi->wmi_ab, len);
1561	if (!skb)
1562		return -ENOMEM;
1563
1564	cmd = (struct wmi_force_fw_hang_cmd *)skb->data;
1565	cmd->tlv_header = FIELD_PREP(WMI_TLV_TAG, WMI_TAG_FORCE_FW_HANG_CMD) |
1566			  FIELD_PREP(WMI_TLV_LEN, len - TLV_HDR_SIZE);
1567
1568	cmd->type = type;
1569	cmd->delay_time_ms = delay_time_ms;
1570
1571	ret = ath11k_wmi_cmd_send(wmi, skb, WMI_FORCE_FW_HANG_CMDID);
1572
1573	if (ret) {
1574		ath11k_warn(ar->ab, "Failed to send WMI_FORCE_FW_HANG_CMDID");
1575		dev_kfree_skb(skb);
1576	}
1577
1578	ath11k_dbg(ar->ab, ATH11K_DBG_WMI, "cmd force fw hang");
1579
1580	return ret;
1581}
1582
1583int ath11k_wmi_vdev_set_param_cmd(struct ath11k *ar, u32 vdev_id,
1584				  u32 param_id, u32 param_value)
1585{
1586	struct ath11k_pdev_wmi *wmi = ar->wmi;
1587	struct wmi_vdev_set_param_cmd *cmd;
1588	struct sk_buff *skb;
1589	int ret;
1590
1591	skb = ath11k_wmi_alloc_skb(wmi->wmi_ab, sizeof(*cmd));
1592	if (!skb)
1593		return -ENOMEM;
1594
1595	cmd = (struct wmi_vdev_set_param_cmd *)skb->data;
1596	cmd->tlv_header = FIELD_PREP(WMI_TLV_TAG, WMI_TAG_VDEV_SET_PARAM_CMD) |
1597			  FIELD_PREP(WMI_TLV_LEN, sizeof(*cmd) - TLV_HDR_SIZE);
1598
1599	cmd->vdev_id = vdev_id;
1600	cmd->param_id = param_id;
1601	cmd->param_value = param_value;
1602
1603	ret = ath11k_wmi_cmd_send(wmi, skb, WMI_VDEV_SET_PARAM_CMDID);
1604	if (ret) {
1605		ath11k_warn(ar->ab,
1606			    "failed to send WMI_VDEV_SET_PARAM_CMDID\n");
1607		dev_kfree_skb(skb);
1608	}
1609
1610	ath11k_dbg(ar->ab, ATH11K_DBG_WMI,
1611		   "cmd vdev set param vdev 0x%x param %d value %d\n",
1612		   vdev_id, param_id, param_value);
1613
1614	return ret;
1615}
1616
1617int ath11k_wmi_send_stats_request_cmd(struct ath11k *ar,
1618				      struct stats_request_params *param)
1619{
1620	struct ath11k_pdev_wmi *wmi = ar->wmi;
1621	struct wmi_request_stats_cmd *cmd;
1622	struct sk_buff *skb;
1623	int ret;
1624
1625	skb = ath11k_wmi_alloc_skb(wmi->wmi_ab, sizeof(*cmd));
1626	if (!skb)
1627		return -ENOMEM;
1628
1629	cmd = (struct wmi_request_stats_cmd *)skb->data;
1630	cmd->tlv_header = FIELD_PREP(WMI_TLV_TAG, WMI_TAG_REQUEST_STATS_CMD) |
1631			  FIELD_PREP(WMI_TLV_LEN, sizeof(*cmd) - TLV_HDR_SIZE);
1632
1633	cmd->stats_id = param->stats_id;
1634	cmd->vdev_id = param->vdev_id;
1635	cmd->pdev_id = param->pdev_id;
1636
1637	ret = ath11k_wmi_cmd_send(wmi, skb, WMI_REQUEST_STATS_CMDID);
1638	if (ret) {
1639		ath11k_warn(ar->ab, "failed to send WMI_REQUEST_STATS cmd\n");
1640		dev_kfree_skb(skb);
1641	}
1642
1643	ath11k_dbg(ar->ab, ATH11K_DBG_WMI,
1644		   "cmd request stats 0x%x vdev id %d pdev id %d\n",
1645		   param->stats_id, param->vdev_id, param->pdev_id);
1646
1647	return ret;
1648}
1649
1650int ath11k_wmi_send_pdev_temperature_cmd(struct ath11k *ar)
1651{
1652	struct ath11k_pdev_wmi *wmi = ar->wmi;
1653	struct wmi_get_pdev_temperature_cmd *cmd;
1654	struct sk_buff *skb;
1655	int ret;
1656
1657	skb = ath11k_wmi_alloc_skb(wmi->wmi_ab, sizeof(*cmd));
1658	if (!skb)
1659		return -ENOMEM;
1660
1661	cmd = (struct wmi_get_pdev_temperature_cmd *)skb->data;
1662	cmd->tlv_header = FIELD_PREP(WMI_TLV_TAG, WMI_TAG_PDEV_GET_TEMPERATURE_CMD) |
1663			  FIELD_PREP(WMI_TLV_LEN, sizeof(*cmd) - TLV_HDR_SIZE);
1664	cmd->pdev_id = ar->pdev->pdev_id;
1665
1666	ret = ath11k_wmi_cmd_send(wmi, skb, WMI_PDEV_GET_TEMPERATURE_CMDID);
1667	if (ret) {
1668		ath11k_warn(ar->ab, "failed to send WMI_PDEV_GET_TEMPERATURE cmd\n");
1669		dev_kfree_skb(skb);
1670	}
1671
1672	ath11k_dbg(ar->ab, ATH11K_DBG_WMI,
1673		   "cmd pdev get temperature for pdev_id %d\n", ar->pdev->pdev_id);
1674
1675	return ret;
1676}
1677
1678int ath11k_wmi_send_bcn_offload_control_cmd(struct ath11k *ar,
1679					    u32 vdev_id, u32 bcn_ctrl_op)
1680{
1681	struct ath11k_pdev_wmi *wmi = ar->wmi;
1682	struct wmi_bcn_offload_ctrl_cmd *cmd;
1683	struct sk_buff *skb;
1684	int ret;
1685
1686	skb = ath11k_wmi_alloc_skb(wmi->wmi_ab, sizeof(*cmd));
1687	if (!skb)
1688		return -ENOMEM;
1689
1690	cmd = (struct wmi_bcn_offload_ctrl_cmd *)skb->data;
1691	cmd->tlv_header = FIELD_PREP(WMI_TLV_TAG,
1692				     WMI_TAG_BCN_OFFLOAD_CTRL_CMD) |
1693			  FIELD_PREP(WMI_TLV_LEN, sizeof(*cmd) - TLV_HDR_SIZE);
1694
1695	cmd->vdev_id = vdev_id;
1696	cmd->bcn_ctrl_op = bcn_ctrl_op;
1697
1698	ret = ath11k_wmi_cmd_send(wmi, skb, WMI_BCN_OFFLOAD_CTRL_CMDID);
1699	if (ret) {
1700		ath11k_warn(ar->ab,
1701			    "failed to send WMI_BCN_OFFLOAD_CTRL_CMDID\n");
1702		dev_kfree_skb(skb);
1703	}
1704
1705	ath11k_dbg(ar->ab, ATH11K_DBG_WMI,
1706		   "cmd bcn offload ctrl vdev id %d ctrl_op %d\n",
1707		   vdev_id, bcn_ctrl_op);
1708
1709	return ret;
1710}
1711
1712int ath11k_wmi_p2p_go_bcn_ie(struct ath11k *ar, u32 vdev_id,
1713			     const u8 *p2p_ie)
1714{
1715	struct ath11k_pdev_wmi *wmi = ar->wmi;
1716	struct wmi_p2p_go_set_beacon_ie_cmd *cmd;
1717	size_t p2p_ie_len, aligned_len;
1718	struct wmi_tlv *tlv;
1719	struct sk_buff *skb;
1720	int ret, len;
1721
1722	p2p_ie_len = p2p_ie[1] + 2;
1723	aligned_len = roundup(p2p_ie_len, 4);
1724
1725	len = sizeof(*cmd) + TLV_HDR_SIZE + aligned_len;
1726
1727	skb = ath11k_wmi_alloc_skb(wmi->wmi_ab, len);
1728	if (!skb)
1729		return -ENOMEM;
1730
1731	cmd = (struct wmi_p2p_go_set_beacon_ie_cmd *)skb->data;
1732	cmd->tlv_header = FIELD_PREP(WMI_TLV_TAG, WMI_TAG_P2P_GO_SET_BEACON_IE) |
1733			  FIELD_PREP(WMI_TLV_LEN, sizeof(*cmd) - TLV_HDR_SIZE);
1734	cmd->vdev_id = vdev_id;
1735	cmd->ie_buf_len = p2p_ie_len;
1736
1737	tlv = (struct wmi_tlv *)cmd->tlv;
1738	tlv->header = FIELD_PREP(WMI_TLV_TAG, WMI_TAG_ARRAY_BYTE) |
1739		      FIELD_PREP(WMI_TLV_LEN, aligned_len);
1740	memcpy(tlv->value, p2p_ie, p2p_ie_len);
1741
1742	ret = ath11k_wmi_cmd_send(wmi, skb, WMI_P2P_GO_SET_BEACON_IE);
1743	if (ret) {
1744		ath11k_warn(ar->ab, "failed to send WMI_P2P_GO_SET_BEACON_IE\n");
1745		dev_kfree_skb(skb);
1746	}
1747
1748	return ret;
1749}
1750
1751int ath11k_wmi_bcn_tmpl(struct ath11k *ar, u32 vdev_id,
1752			struct ieee80211_mutable_offsets *offs,
1753			struct sk_buff *bcn, u32 ema_params)
1754{
1755	struct ath11k_pdev_wmi *wmi = ar->wmi;
1756	struct wmi_bcn_tmpl_cmd *cmd;
1757	struct wmi_bcn_prb_info *bcn_prb_info;
1758	struct wmi_tlv *tlv;
1759	struct sk_buff *skb;
1760	void *ptr;
1761	int ret, len;
1762	size_t aligned_len = roundup(bcn->len, 4);
1763	struct ieee80211_vif *vif;
1764	struct ath11k_vif *arvif = ath11k_mac_get_arvif(ar, vdev_id);
1765
1766	if (!arvif) {
1767		ath11k_warn(ar->ab, "failed to find arvif with vdev id %d\n", vdev_id);
1768		return -EINVAL;
1769	}
1770
1771	vif = arvif->vif;
1772
1773	len = sizeof(*cmd) + sizeof(*bcn_prb_info) + TLV_HDR_SIZE + aligned_len;
1774
1775	skb = ath11k_wmi_alloc_skb(wmi->wmi_ab, len);
1776	if (!skb)
1777		return -ENOMEM;
1778
1779	cmd = (struct wmi_bcn_tmpl_cmd *)skb->data;
1780	cmd->tlv_header = FIELD_PREP(WMI_TLV_TAG, WMI_TAG_BCN_TMPL_CMD) |
1781			  FIELD_PREP(WMI_TLV_LEN, sizeof(*cmd) - TLV_HDR_SIZE);
1782	cmd->vdev_id = vdev_id;
1783	cmd->tim_ie_offset = offs->tim_offset;
1784
1785	if (vif->bss_conf.csa_active) {
1786		cmd->csa_switch_count_offset = offs->cntdwn_counter_offs[0];
1787		cmd->ext_csa_switch_count_offset = offs->cntdwn_counter_offs[1];
1788	}
1789
1790	cmd->buf_len = bcn->len;
1791	cmd->mbssid_ie_offset = offs->mbssid_off;
1792	cmd->ema_params = ema_params;
1793
1794	ptr = skb->data + sizeof(*cmd);
1795
1796	bcn_prb_info = ptr;
1797	len = sizeof(*bcn_prb_info);
1798	bcn_prb_info->tlv_header = FIELD_PREP(WMI_TLV_TAG,
1799					      WMI_TAG_BCN_PRB_INFO) |
1800				   FIELD_PREP(WMI_TLV_LEN, len - TLV_HDR_SIZE);
1801	bcn_prb_info->caps = 0;
1802	bcn_prb_info->erp = 0;
1803
1804	ptr += sizeof(*bcn_prb_info);
1805
1806	tlv = ptr;
1807	tlv->header = FIELD_PREP(WMI_TLV_TAG, WMI_TAG_ARRAY_BYTE) |
1808		      FIELD_PREP(WMI_TLV_LEN, aligned_len);
1809	memcpy(tlv->value, bcn->data, bcn->len);
1810
1811	ret = ath11k_wmi_cmd_send(wmi, skb, WMI_BCN_TMPL_CMDID);
1812	if (ret) {
1813		ath11k_warn(ar->ab, "failed to send WMI_BCN_TMPL_CMDID\n");
1814		dev_kfree_skb(skb);
1815	}
1816
1817	ath11k_dbg(ar->ab, ATH11K_DBG_WMI, "cmd bcn tmpl");
1818
1819	return ret;
1820}
1821
1822int ath11k_wmi_vdev_install_key(struct ath11k *ar,
1823				struct wmi_vdev_install_key_arg *arg)
1824{
1825	struct ath11k_pdev_wmi *wmi = ar->wmi;
1826	struct wmi_vdev_install_key_cmd *cmd;
1827	struct wmi_tlv *tlv;
1828	struct sk_buff *skb;
1829	int ret, len;
1830	int key_len_aligned = roundup(arg->key_len, sizeof(uint32_t));
1831
1832	len = sizeof(*cmd) + TLV_HDR_SIZE + key_len_aligned;
1833
1834	skb = ath11k_wmi_alloc_skb(wmi->wmi_ab, len);
1835	if (!skb)
1836		return -ENOMEM;
1837
1838	cmd = (struct wmi_vdev_install_key_cmd *)skb->data;
1839	cmd->tlv_header = FIELD_PREP(WMI_TLV_TAG, WMI_TAG_VDEV_INSTALL_KEY_CMD) |
1840			  FIELD_PREP(WMI_TLV_LEN, sizeof(*cmd) - TLV_HDR_SIZE);
1841	cmd->vdev_id = arg->vdev_id;
1842	ether_addr_copy(cmd->peer_macaddr.addr, arg->macaddr);
1843	cmd->key_idx = arg->key_idx;
1844	cmd->key_flags = arg->key_flags;
1845	cmd->key_cipher = arg->key_cipher;
1846	cmd->key_len = arg->key_len;
1847	cmd->key_txmic_len = arg->key_txmic_len;
1848	cmd->key_rxmic_len = arg->key_rxmic_len;
1849
1850	if (arg->key_rsc_counter)
1851		memcpy(&cmd->key_rsc_counter, &arg->key_rsc_counter,
1852		       sizeof(struct wmi_key_seq_counter));
1853
1854	tlv = (struct wmi_tlv *)(skb->data + sizeof(*cmd));
1855	tlv->header = FIELD_PREP(WMI_TLV_TAG, WMI_TAG_ARRAY_BYTE) |
1856		      FIELD_PREP(WMI_TLV_LEN, key_len_aligned);
1857	if (arg->key_data)
1858		memcpy(tlv->value, (u8 *)arg->key_data, key_len_aligned);
1859
1860	ret = ath11k_wmi_cmd_send(wmi, skb, WMI_VDEV_INSTALL_KEY_CMDID);
1861	if (ret) {
1862		ath11k_warn(ar->ab,
1863			    "failed to send WMI_VDEV_INSTALL_KEY cmd\n");
1864		dev_kfree_skb(skb);
1865	}
1866
1867	ath11k_dbg(ar->ab, ATH11K_DBG_WMI,
1868		   "cmd vdev install key idx %d cipher %d len %d\n",
1869		   arg->key_idx, arg->key_cipher, arg->key_len);
1870
1871	return ret;
1872}
1873
1874static inline void
1875ath11k_wmi_copy_peer_flags(struct wmi_peer_assoc_complete_cmd *cmd,
1876			   struct peer_assoc_params *param,
1877			   bool hw_crypto_disabled)
1878{
1879	cmd->peer_flags = 0;
1880
1881	if (param->is_wme_set) {
1882		if (param->qos_flag)
1883			cmd->peer_flags |= WMI_PEER_QOS;
1884		if (param->apsd_flag)
1885			cmd->peer_flags |= WMI_PEER_APSD;
1886		if (param->ht_flag)
1887			cmd->peer_flags |= WMI_PEER_HT;
1888		if (param->bw_40)
1889			cmd->peer_flags |= WMI_PEER_40MHZ;
1890		if (param->bw_80)
1891			cmd->peer_flags |= WMI_PEER_80MHZ;
1892		if (param->bw_160)
1893			cmd->peer_flags |= WMI_PEER_160MHZ;
1894
1895		/* Typically if STBC is enabled for VHT it should be enabled
1896		 * for HT as well
1897		 **/
1898		if (param->stbc_flag)
1899			cmd->peer_flags |= WMI_PEER_STBC;
1900
1901		/* Typically if LDPC is enabled for VHT it should be enabled
1902		 * for HT as well
1903		 **/
1904		if (param->ldpc_flag)
1905			cmd->peer_flags |= WMI_PEER_LDPC;
1906
1907		if (param->static_mimops_flag)
1908			cmd->peer_flags |= WMI_PEER_STATIC_MIMOPS;
1909		if (param->dynamic_mimops_flag)
1910			cmd->peer_flags |= WMI_PEER_DYN_MIMOPS;
1911		if (param->spatial_mux_flag)
1912			cmd->peer_flags |= WMI_PEER_SPATIAL_MUX;
1913		if (param->vht_flag)
1914			cmd->peer_flags |= WMI_PEER_VHT;
1915		if (param->he_flag)
1916			cmd->peer_flags |= WMI_PEER_HE;
1917		if (param->twt_requester)
1918			cmd->peer_flags |= WMI_PEER_TWT_REQ;
1919		if (param->twt_responder)
1920			cmd->peer_flags |= WMI_PEER_TWT_RESP;
1921	}
1922
1923	/* Suppress authorization for all AUTH modes that need 4-way handshake
1924	 * (during re-association).
1925	 * Authorization will be done for these modes on key installation.
1926	 */
1927	if (param->auth_flag)
1928		cmd->peer_flags |= WMI_PEER_AUTH;
1929	if (param->need_ptk_4_way) {
1930		cmd->peer_flags |= WMI_PEER_NEED_PTK_4_WAY;
1931		if (!hw_crypto_disabled && param->is_assoc)
1932			cmd->peer_flags &= ~WMI_PEER_AUTH;
1933	}
1934	if (param->need_gtk_2_way)
1935		cmd->peer_flags |= WMI_PEER_NEED_GTK_2_WAY;
1936	/* safe mode bypass the 4-way handshake */
1937	if (param->safe_mode_enabled)
1938		cmd->peer_flags &= ~(WMI_PEER_NEED_PTK_4_WAY |
1939				     WMI_PEER_NEED_GTK_2_WAY);
1940
1941	if (param->is_pmf_enabled)
1942		cmd->peer_flags |= WMI_PEER_PMF;
1943
1944	/* Disable AMSDU for station transmit, if user configures it */
1945	/* Disable AMSDU for AP transmit to 11n Stations, if user configures
1946	 * it
1947	 * if (param->amsdu_disable) Add after FW support
1948	 **/
1949
1950	/* Target asserts if node is marked HT and all MCS is set to 0.
1951	 * Mark the node as non-HT if all the mcs rates are disabled through
1952	 * iwpriv
1953	 **/
1954	if (param->peer_ht_rates.num_rates == 0)
1955		cmd->peer_flags &= ~WMI_PEER_HT;
1956}
1957
1958int ath11k_wmi_send_peer_assoc_cmd(struct ath11k *ar,
1959				   struct peer_assoc_params *param)
1960{
1961	struct ath11k_pdev_wmi *wmi = ar->wmi;
1962	struct wmi_peer_assoc_complete_cmd *cmd;
1963	struct wmi_vht_rate_set *mcs;
1964	struct wmi_he_rate_set *he_mcs;
1965	struct sk_buff *skb;
1966	struct wmi_tlv *tlv;
1967	void *ptr;
1968	u32 peer_legacy_rates_align;
1969	u32 peer_ht_rates_align;
1970	int i, ret, len;
1971
1972	peer_legacy_rates_align = roundup(param->peer_legacy_rates.num_rates,
1973					  sizeof(u32));
1974	peer_ht_rates_align = roundup(param->peer_ht_rates.num_rates,
1975				      sizeof(u32));
1976
1977	len = sizeof(*cmd) +
1978	      TLV_HDR_SIZE + (peer_legacy_rates_align * sizeof(u8)) +
1979	      TLV_HDR_SIZE + (peer_ht_rates_align * sizeof(u8)) +
1980	      sizeof(*mcs) + TLV_HDR_SIZE +
1981	      (sizeof(*he_mcs) * param->peer_he_mcs_count);
1982
1983	skb = ath11k_wmi_alloc_skb(wmi->wmi_ab, len);
1984	if (!skb)
1985		return -ENOMEM;
1986
1987	ptr = skb->data;
1988
1989	cmd = ptr;
1990	cmd->tlv_header = FIELD_PREP(WMI_TLV_TAG,
1991				     WMI_TAG_PEER_ASSOC_COMPLETE_CMD) |
1992			  FIELD_PREP(WMI_TLV_LEN, sizeof(*cmd) - TLV_HDR_SIZE);
1993
1994	cmd->vdev_id = param->vdev_id;
1995
1996	cmd->peer_new_assoc = param->peer_new_assoc;
1997	cmd->peer_associd = param->peer_associd;
1998
1999	ath11k_wmi_copy_peer_flags(cmd, param,
2000				   test_bit(ATH11K_FLAG_HW_CRYPTO_DISABLED,
2001					    &ar->ab->dev_flags));
2002
2003	ether_addr_copy(cmd->peer_macaddr.addr, param->peer_mac);
2004
2005	cmd->peer_rate_caps = param->peer_rate_caps;
2006	cmd->peer_caps = param->peer_caps;
2007	cmd->peer_listen_intval = param->peer_listen_intval;
2008	cmd->peer_ht_caps = param->peer_ht_caps;
2009	cmd->peer_max_mpdu = param->peer_max_mpdu;
2010	cmd->peer_mpdu_density = param->peer_mpdu_density;
2011	cmd->peer_vht_caps = param->peer_vht_caps;
2012	cmd->peer_phymode = param->peer_phymode;
2013
2014	/* Update 11ax capabilities */
2015	cmd->peer_he_cap_info = param->peer_he_cap_macinfo[0];
2016	cmd->peer_he_cap_info_ext = param->peer_he_cap_macinfo[1];
2017	cmd->peer_he_cap_info_internal = param->peer_he_cap_macinfo_internal;
2018	cmd->peer_he_caps_6ghz = param->peer_he_caps_6ghz;
2019	cmd->peer_he_ops = param->peer_he_ops;
2020	memcpy(&cmd->peer_he_cap_phy, &param->peer_he_cap_phyinfo,
2021	       sizeof(param->peer_he_cap_phyinfo));
2022	memcpy(&cmd->peer_ppet, &param->peer_ppet,
2023	       sizeof(param->peer_ppet));
2024
2025	/* Update peer legacy rate information */
2026	ptr += sizeof(*cmd);
2027
2028	tlv = ptr;
2029	tlv->header = FIELD_PREP(WMI_TLV_TAG, WMI_TAG_ARRAY_BYTE) |
2030		      FIELD_PREP(WMI_TLV_LEN, peer_legacy_rates_align);
2031
2032	ptr += TLV_HDR_SIZE;
2033
2034	cmd->num_peer_legacy_rates = param->peer_legacy_rates.num_rates;
2035	memcpy(ptr, param->peer_legacy_rates.rates,
2036	       param->peer_legacy_rates.num_rates);
2037
2038	/* Update peer HT rate information */
2039	ptr += peer_legacy_rates_align;
2040
2041	tlv = ptr;
2042	tlv->header = FIELD_PREP(WMI_TLV_TAG, WMI_TAG_ARRAY_BYTE) |
2043		      FIELD_PREP(WMI_TLV_LEN, peer_ht_rates_align);
2044	ptr += TLV_HDR_SIZE;
2045	cmd->num_peer_ht_rates = param->peer_ht_rates.num_rates;
2046	memcpy(ptr, param->peer_ht_rates.rates,
2047	       param->peer_ht_rates.num_rates);
2048
2049	/* VHT Rates */
2050	ptr += peer_ht_rates_align;
2051
2052	mcs = ptr;
2053
2054	mcs->tlv_header = FIELD_PREP(WMI_TLV_TAG, WMI_TAG_VHT_RATE_SET) |
2055			  FIELD_PREP(WMI_TLV_LEN, sizeof(*mcs) - TLV_HDR_SIZE);
2056
2057	cmd->peer_nss = param->peer_nss;
2058
2059	/* Update bandwidth-NSS mapping */
2060	cmd->peer_bw_rxnss_override = 0;
2061	cmd->peer_bw_rxnss_override |= param->peer_bw_rxnss_override;
2062
2063	if (param->vht_capable) {
2064		mcs->rx_max_rate = param->rx_max_rate;
2065		mcs->rx_mcs_set = param->rx_mcs_set;
2066		mcs->tx_max_rate = param->tx_max_rate;
2067		mcs->tx_mcs_set = param->tx_mcs_set;
2068	}
2069
2070	/* HE Rates */
2071	cmd->peer_he_mcs = param->peer_he_mcs_count;
2072	cmd->min_data_rate = param->min_data_rate;
2073
2074	ptr += sizeof(*mcs);
2075
2076	len = param->peer_he_mcs_count * sizeof(*he_mcs);
2077
2078	tlv = ptr;
2079	tlv->header = FIELD_PREP(WMI_TLV_TAG, WMI_TAG_ARRAY_STRUCT) |
2080		      FIELD_PREP(WMI_TLV_LEN, len);
2081	ptr += TLV_HDR_SIZE;
2082
2083	/* Loop through the HE rate set */
2084	for (i = 0; i < param->peer_he_mcs_count; i++) {
2085		he_mcs = ptr;
2086		he_mcs->tlv_header = FIELD_PREP(WMI_TLV_TAG,
2087						WMI_TAG_HE_RATE_SET) |
2088				     FIELD_PREP(WMI_TLV_LEN,
2089						sizeof(*he_mcs) - TLV_HDR_SIZE);
2090
2091		he_mcs->rx_mcs_set = param->peer_he_tx_mcs_set[i];
2092		he_mcs->tx_mcs_set = param->peer_he_rx_mcs_set[i];
2093		ptr += sizeof(*he_mcs);
2094	}
2095
2096	ret = ath11k_wmi_cmd_send(wmi, skb, WMI_PEER_ASSOC_CMDID);
2097	if (ret) {
2098		ath11k_warn(ar->ab,
2099			    "failed to send WMI_PEER_ASSOC_CMDID\n");
2100		dev_kfree_skb(skb);
2101	}
2102
2103	ath11k_dbg(ar->ab, ATH11K_DBG_WMI,
2104		   "cmd peer assoc vdev id %d assoc id %d peer mac %pM peer_flags %x rate_caps %x peer_caps %x listen_intval %d ht_caps %x max_mpdu %d nss %d phymode %d peer_mpdu_density %d vht_caps %x he cap_info %x he ops %x he cap_info_ext %x he phy %x %x %x peer_bw_rxnss_override %x\n",
2105		   cmd->vdev_id, cmd->peer_associd, param->peer_mac,
2106		   cmd->peer_flags, cmd->peer_rate_caps, cmd->peer_caps,
2107		   cmd->peer_listen_intval, cmd->peer_ht_caps,
2108		   cmd->peer_max_mpdu, cmd->peer_nss, cmd->peer_phymode,
2109		   cmd->peer_mpdu_density,
2110		   cmd->peer_vht_caps, cmd->peer_he_cap_info,
2111		   cmd->peer_he_ops, cmd->peer_he_cap_info_ext,
2112		   cmd->peer_he_cap_phy[0], cmd->peer_he_cap_phy[1],
2113		   cmd->peer_he_cap_phy[2],
2114		   cmd->peer_bw_rxnss_override);
2115
2116	return ret;
2117}
2118
2119void ath11k_wmi_start_scan_init(struct ath11k *ar,
2120				struct scan_req_params *arg)
2121{
2122	/* setup commonly used values */
2123	arg->scan_req_id = 1;
2124	if (ar->state_11d == ATH11K_11D_PREPARING)
2125		arg->scan_priority = WMI_SCAN_PRIORITY_MEDIUM;
2126	else
2127		arg->scan_priority = WMI_SCAN_PRIORITY_LOW;
2128	arg->dwell_time_active = 50;
2129	arg->dwell_time_active_2g = 0;
2130	arg->dwell_time_passive = 150;
2131	arg->dwell_time_active_6g = 40;
2132	arg->dwell_time_passive_6g = 30;
2133	arg->min_rest_time = 50;
2134	arg->max_rest_time = 500;
2135	arg->repeat_probe_time = 0;
2136	arg->probe_spacing_time = 0;
2137	arg->idle_time = 0;
2138	arg->max_scan_time = 20000;
2139	arg->probe_delay = 5;
2140	arg->notify_scan_events = WMI_SCAN_EVENT_STARTED |
2141				  WMI_SCAN_EVENT_COMPLETED |
2142				  WMI_SCAN_EVENT_BSS_CHANNEL |
2143				  WMI_SCAN_EVENT_FOREIGN_CHAN |
2144				  WMI_SCAN_EVENT_DEQUEUED;
2145	arg->scan_f_chan_stat_evnt = 1;
2146
2147	if (test_bit(WMI_TLV_SERVICE_PASSIVE_SCAN_START_TIME_ENHANCE,
2148		     ar->ab->wmi_ab.svc_map))
2149		arg->scan_ctrl_flags_ext |=
2150			WMI_SCAN_FLAG_EXT_PASSIVE_SCAN_START_TIME_ENHANCE;
2151
2152	arg->num_bssid = 1;
2153
2154	/* fill bssid_list[0] with 0xff, otherwise bssid and RA will be
2155	 * ZEROs in probe request
2156	 */
2157	eth_broadcast_addr(arg->bssid_list[0].addr);
2158}
2159
2160static inline void
2161ath11k_wmi_copy_scan_event_cntrl_flags(struct wmi_start_scan_cmd *cmd,
2162				       struct scan_req_params *param)
2163{
2164	/* Scan events subscription */
2165	if (param->scan_ev_started)
2166		cmd->notify_scan_events |=  WMI_SCAN_EVENT_STARTED;
2167	if (param->scan_ev_completed)
2168		cmd->notify_scan_events |=  WMI_SCAN_EVENT_COMPLETED;
2169	if (param->scan_ev_bss_chan)
2170		cmd->notify_scan_events |=  WMI_SCAN_EVENT_BSS_CHANNEL;
2171	if (param->scan_ev_foreign_chan)
2172		cmd->notify_scan_events |=  WMI_SCAN_EVENT_FOREIGN_CHAN;
2173	if (param->scan_ev_dequeued)
2174		cmd->notify_scan_events |=  WMI_SCAN_EVENT_DEQUEUED;
2175	if (param->scan_ev_preempted)
2176		cmd->notify_scan_events |=  WMI_SCAN_EVENT_PREEMPTED;
2177	if (param->scan_ev_start_failed)
2178		cmd->notify_scan_events |=  WMI_SCAN_EVENT_START_FAILED;
2179	if (param->scan_ev_restarted)
2180		cmd->notify_scan_events |=  WMI_SCAN_EVENT_RESTARTED;
2181	if (param->scan_ev_foreign_chn_exit)
2182		cmd->notify_scan_events |=  WMI_SCAN_EVENT_FOREIGN_CHAN_EXIT;
2183	if (param->scan_ev_suspended)
2184		cmd->notify_scan_events |=  WMI_SCAN_EVENT_SUSPENDED;
2185	if (param->scan_ev_resumed)
2186		cmd->notify_scan_events |=  WMI_SCAN_EVENT_RESUMED;
2187
2188	/** Set scan control flags */
2189	cmd->scan_ctrl_flags = 0;
2190	if (param->scan_f_passive)
2191		cmd->scan_ctrl_flags |=  WMI_SCAN_FLAG_PASSIVE;
2192	if (param->scan_f_strict_passive_pch)
2193		cmd->scan_ctrl_flags |=  WMI_SCAN_FLAG_STRICT_PASSIVE_ON_PCHN;
2194	if (param->scan_f_promisc_mode)
2195		cmd->scan_ctrl_flags |=  WMI_SCAN_FILTER_PROMISCUOS;
2196	if (param->scan_f_capture_phy_err)
2197		cmd->scan_ctrl_flags |=  WMI_SCAN_CAPTURE_PHY_ERROR;
2198	if (param->scan_f_half_rate)
2199		cmd->scan_ctrl_flags |=  WMI_SCAN_FLAG_HALF_RATE_SUPPORT;
2200	if (param->scan_f_quarter_rate)
2201		cmd->scan_ctrl_flags |=  WMI_SCAN_FLAG_QUARTER_RATE_SUPPORT;
2202	if (param->scan_f_cck_rates)
2203		cmd->scan_ctrl_flags |=  WMI_SCAN_ADD_CCK_RATES;
2204	if (param->scan_f_ofdm_rates)
2205		cmd->scan_ctrl_flags |=  WMI_SCAN_ADD_OFDM_RATES;
2206	if (param->scan_f_chan_stat_evnt)
2207		cmd->scan_ctrl_flags |=  WMI_SCAN_CHAN_STAT_EVENT;
2208	if (param->scan_f_filter_prb_req)
2209		cmd->scan_ctrl_flags |=  WMI_SCAN_FILTER_PROBE_REQ;
2210	if (param->scan_f_bcast_probe)
2211		cmd->scan_ctrl_flags |=  WMI_SCAN_ADD_BCAST_PROBE_REQ;
2212	if (param->scan_f_offchan_mgmt_tx)
2213		cmd->scan_ctrl_flags |=  WMI_SCAN_OFFCHAN_MGMT_TX;
2214	if (param->scan_f_offchan_data_tx)
2215		cmd->scan_ctrl_flags |=  WMI_SCAN_OFFCHAN_DATA_TX;
2216	if (param->scan_f_force_active_dfs_chn)
2217		cmd->scan_ctrl_flags |=  WMI_SCAN_FLAG_FORCE_ACTIVE_ON_DFS;
2218	if (param->scan_f_add_tpc_ie_in_probe)
2219		cmd->scan_ctrl_flags |=  WMI_SCAN_ADD_TPC_IE_IN_PROBE_REQ;
2220	if (param->scan_f_add_ds_ie_in_probe)
2221		cmd->scan_ctrl_flags |=  WMI_SCAN_ADD_DS_IE_IN_PROBE_REQ;
2222	if (param->scan_f_add_spoofed_mac_in_probe)
2223		cmd->scan_ctrl_flags |=  WMI_SCAN_ADD_SPOOF_MAC_IN_PROBE_REQ;
2224	if (param->scan_f_add_rand_seq_in_probe)
2225		cmd->scan_ctrl_flags |=  WMI_SCAN_RANDOM_SEQ_NO_IN_PROBE_REQ;
2226	if (param->scan_f_en_ie_whitelist_in_probe)
2227		cmd->scan_ctrl_flags |=
2228			 WMI_SCAN_ENABLE_IE_WHTELIST_IN_PROBE_REQ;
2229
2230	/* for adaptive scan mode using 3 bits (21 - 23 bits) */
2231	WMI_SCAN_SET_DWELL_MODE(cmd->scan_ctrl_flags,
2232				param->adaptive_dwell_time_mode);
2233
2234	cmd->scan_ctrl_flags_ext = param->scan_ctrl_flags_ext;
2235}
2236
2237int ath11k_wmi_send_scan_start_cmd(struct ath11k *ar,
2238				   struct scan_req_params *params)
2239{
2240	struct ath11k_pdev_wmi *wmi = ar->wmi;
2241	struct wmi_start_scan_cmd *cmd;
2242	struct wmi_ssid *ssid = NULL;
2243	struct wmi_mac_addr *bssid;
2244	struct sk_buff *skb;
2245	struct wmi_tlv *tlv;
2246	void *ptr;
2247	int i, ret, len;
2248	u32 *tmp_ptr;
2249	u16 extraie_len_with_pad = 0;
2250	struct hint_short_ssid *s_ssid = NULL;
2251	struct hint_bssid *hint_bssid = NULL;
2252
2253	len = sizeof(*cmd);
2254
2255	len += TLV_HDR_SIZE;
2256	if (params->num_chan)
2257		len += params->num_chan * sizeof(u32);
2258
2259	len += TLV_HDR_SIZE;
2260	if (params->num_ssids)
2261		len += params->num_ssids * sizeof(*ssid);
2262
2263	len += TLV_HDR_SIZE;
2264	if (params->num_bssid)
2265		len += sizeof(*bssid) * params->num_bssid;
2266
2267	len += TLV_HDR_SIZE;
2268	if (params->extraie.len && params->extraie.len <= 0xFFFF)
2269		extraie_len_with_pad =
2270			roundup(params->extraie.len, sizeof(u32));
2271	len += extraie_len_with_pad;
2272
2273	if (params->num_hint_bssid)
2274		len += TLV_HDR_SIZE +
2275		       params->num_hint_bssid * sizeof(struct hint_bssid);
2276
2277	if (params->num_hint_s_ssid)
2278		len += TLV_HDR_SIZE +
2279		       params->num_hint_s_ssid * sizeof(struct hint_short_ssid);
2280
2281	skb = ath11k_wmi_alloc_skb(wmi->wmi_ab, len);
2282	if (!skb)
2283		return -ENOMEM;
2284
2285	ptr = skb->data;
2286
2287	cmd = ptr;
2288	cmd->tlv_header = FIELD_PREP(WMI_TLV_TAG, WMI_TAG_START_SCAN_CMD) |
2289			  FIELD_PREP(WMI_TLV_LEN, sizeof(*cmd) - TLV_HDR_SIZE);
2290
2291	cmd->scan_id = params->scan_id;
2292	cmd->scan_req_id = params->scan_req_id;
2293	cmd->vdev_id = params->vdev_id;
2294	cmd->scan_priority = params->scan_priority;
2295	cmd->notify_scan_events = params->notify_scan_events;
2296
2297	ath11k_wmi_copy_scan_event_cntrl_flags(cmd, params);
2298
2299	cmd->dwell_time_active = params->dwell_time_active;
2300	cmd->dwell_time_active_2g = params->dwell_time_active_2g;
2301	cmd->dwell_time_passive = params->dwell_time_passive;
2302	cmd->dwell_time_active_6g = params->dwell_time_active_6g;
2303	cmd->dwell_time_passive_6g = params->dwell_time_passive_6g;
2304	cmd->min_rest_time = params->min_rest_time;
2305	cmd->max_rest_time = params->max_rest_time;
2306	cmd->repeat_probe_time = params->repeat_probe_time;
2307	cmd->probe_spacing_time = params->probe_spacing_time;
2308	cmd->idle_time = params->idle_time;
2309	cmd->max_scan_time = params->max_scan_time;
2310	cmd->probe_delay = params->probe_delay;
2311	cmd->burst_duration = params->burst_duration;
2312	cmd->num_chan = params->num_chan;
2313	cmd->num_bssid = params->num_bssid;
2314	cmd->num_ssids = params->num_ssids;
2315	cmd->ie_len = params->extraie.len;
2316	cmd->n_probes = params->n_probes;
2317	ether_addr_copy(cmd->mac_addr.addr, params->mac_addr.addr);
2318	ether_addr_copy(cmd->mac_mask.addr, params->mac_mask.addr);
2319
2320	ptr += sizeof(*cmd);
2321
2322	len = params->num_chan * sizeof(u32);
2323
2324	tlv = ptr;
2325	tlv->header = FIELD_PREP(WMI_TLV_TAG, WMI_TAG_ARRAY_UINT32) |
2326		      FIELD_PREP(WMI_TLV_LEN, len);
2327	ptr += TLV_HDR_SIZE;
2328	tmp_ptr = ptr;
2329
2330	for (i = 0; i < params->num_chan; ++i)
2331		tmp_ptr[i] = params->chan_list[i];
2332
2333	ptr += len;
2334
2335	len = params->num_ssids * sizeof(*ssid);
2336	tlv = ptr;
2337	tlv->header = FIELD_PREP(WMI_TLV_TAG, WMI_TAG_ARRAY_FIXED_STRUCT) |
2338		      FIELD_PREP(WMI_TLV_LEN, len);
2339
2340	ptr += TLV_HDR_SIZE;
2341
2342	if (params->num_ssids) {
2343		ssid = ptr;
2344		for (i = 0; i < params->num_ssids; ++i) {
2345			ssid->ssid_len = params->ssid[i].length;
2346			memcpy(ssid->ssid, params->ssid[i].ssid,
2347			       params->ssid[i].length);
2348			ssid++;
2349		}
2350	}
2351
2352	ptr += (params->num_ssids * sizeof(*ssid));
2353	len = params->num_bssid * sizeof(*bssid);
2354	tlv = ptr;
2355	tlv->header = FIELD_PREP(WMI_TLV_TAG, WMI_TAG_ARRAY_FIXED_STRUCT) |
2356		      FIELD_PREP(WMI_TLV_LEN, len);
2357
2358	ptr += TLV_HDR_SIZE;
2359	bssid = ptr;
2360
2361	if (params->num_bssid) {
2362		for (i = 0; i < params->num_bssid; ++i) {
2363			ether_addr_copy(bssid->addr,
2364					params->bssid_list[i].addr);
2365			bssid++;
2366		}
2367	}
2368
2369	ptr += params->num_bssid * sizeof(*bssid);
2370
2371	len = extraie_len_with_pad;
2372	tlv = ptr;
2373	tlv->header = FIELD_PREP(WMI_TLV_TAG, WMI_TAG_ARRAY_BYTE) |
2374		      FIELD_PREP(WMI_TLV_LEN, len);
2375	ptr += TLV_HDR_SIZE;
2376
2377	if (extraie_len_with_pad)
2378		memcpy(ptr, params->extraie.ptr,
2379		       params->extraie.len);
2380
2381	ptr += extraie_len_with_pad;
2382
2383	if (params->num_hint_s_ssid) {
2384		len = params->num_hint_s_ssid * sizeof(struct hint_short_ssid);
2385		tlv = ptr;
2386		tlv->header = FIELD_PREP(WMI_TLV_TAG, WMI_TAG_ARRAY_FIXED_STRUCT) |
2387			      FIELD_PREP(WMI_TLV_LEN, len);
2388		ptr += TLV_HDR_SIZE;
2389		s_ssid = ptr;
2390		for (i = 0; i < params->num_hint_s_ssid; ++i) {
2391			s_ssid->freq_flags = params->hint_s_ssid[i].freq_flags;
2392			s_ssid->short_ssid = params->hint_s_ssid[i].short_ssid;
2393			s_ssid++;
2394		}
2395		ptr += len;
2396	}
2397
2398	if (params->num_hint_bssid) {
2399		len = params->num_hint_bssid * sizeof(struct hint_bssid);
2400		tlv = ptr;
2401		tlv->header = FIELD_PREP(WMI_TLV_TAG, WMI_TAG_ARRAY_FIXED_STRUCT) |
2402			      FIELD_PREP(WMI_TLV_LEN, len);
2403		ptr += TLV_HDR_SIZE;
2404		hint_bssid = ptr;
2405		for (i = 0; i < params->num_hint_bssid; ++i) {
2406			hint_bssid->freq_flags =
2407				params->hint_bssid[i].freq_flags;
2408			ether_addr_copy(&params->hint_bssid[i].bssid.addr[0],
2409					&hint_bssid->bssid.addr[0]);
2410			hint_bssid++;
2411		}
2412	}
2413
2414	ret = ath11k_wmi_cmd_send(wmi, skb,
2415				  WMI_START_SCAN_CMDID);
2416	if (ret) {
2417		ath11k_warn(ar->ab, "failed to send WMI_START_SCAN_CMDID\n");
2418		dev_kfree_skb(skb);
2419	}
2420
2421	ath11k_dbg(ar->ab, ATH11K_DBG_WMI, "cmd start scan");
2422
2423	return ret;
2424}
2425
2426int ath11k_wmi_send_vdev_set_tpc_power(struct ath11k *ar,
2427				       u32 vdev_id,
2428				       struct ath11k_reg_tpc_power_info *param)
2429{
2430	struct ath11k_pdev_wmi *wmi = ar->wmi;
2431	struct wmi_vdev_set_tpc_power_cmd *cmd;
2432	struct wmi_vdev_ch_power_info *ch;
2433	struct sk_buff *skb;
2434	struct wmi_tlv *tlv;
2435	u8 *ptr;
2436	int i, ret, len, array_len;
2437
2438	array_len = sizeof(*ch) * param->num_pwr_levels;
2439	len = sizeof(*cmd) + TLV_HDR_SIZE + array_len;
2440
2441	skb = ath11k_wmi_alloc_skb(wmi->wmi_ab, len);
2442	if (!skb)
2443		return -ENOMEM;
2444
2445	ptr = skb->data;
2446
2447	cmd = (struct wmi_vdev_set_tpc_power_cmd *)ptr;
2448	cmd->tlv_header = FIELD_PREP(WMI_TLV_TAG, WMI_TAG_VDEV_SET_TPC_POWER_CMD) |
2449			  FIELD_PREP(WMI_TLV_LEN, sizeof(*cmd) - TLV_HDR_SIZE);
2450	cmd->vdev_id = vdev_id;
2451	cmd->psd_power = param->is_psd_power;
2452	cmd->eirp_power = param->eirp_power;
2453	cmd->power_type_6ghz = param->ap_power_type;
2454
2455	ath11k_dbg(ar->ab, ATH11K_DBG_WMI,
2456		   "tpc vdev id %d is psd power %d eirp power %d 6 ghz power type %d\n",
2457		   vdev_id, param->is_psd_power, param->eirp_power, param->ap_power_type);
2458
2459	ptr += sizeof(*cmd);
2460	tlv = (struct wmi_tlv *)ptr;
2461	tlv->header = FIELD_PREP(WMI_TLV_TAG, WMI_TAG_ARRAY_STRUCT) |
2462		      FIELD_PREP(WMI_TLV_LEN, array_len);
2463
2464	ptr += TLV_HDR_SIZE;
2465	ch = (struct wmi_vdev_ch_power_info *)ptr;
2466
2467	for (i = 0; i < param->num_pwr_levels; i++, ch++) {
2468		ch->tlv_header = FIELD_PREP(WMI_TLV_TAG,
2469					    WMI_TAG_VDEV_CH_POWER_INFO) |
2470				FIELD_PREP(WMI_TLV_LEN,
2471					   sizeof(*ch) - TLV_HDR_SIZE);
2472
2473		ch->chan_cfreq = param->chan_power_info[i].chan_cfreq;
2474		ch->tx_power = param->chan_power_info[i].tx_power;
2475
2476		ath11k_dbg(ar->ab, ATH11K_DBG_WMI, "tpc chan freq %d TX power %d\n",
2477			   ch->chan_cfreq, ch->tx_power);
2478	}
2479
2480	ret = ath11k_wmi_cmd_send(wmi, skb, WMI_VDEV_SET_TPC_POWER_CMDID);
2481	if (ret) {
2482		ath11k_warn(ar->ab, "failed to send WMI_VDEV_SET_TPC_POWER_CMDID\n");
2483		dev_kfree_skb(skb);
2484		return ret;
2485	}
2486
2487	return 0;
2488}
2489
2490int ath11k_wmi_send_scan_stop_cmd(struct ath11k *ar,
2491				  struct scan_cancel_param *param)
2492{
2493	struct ath11k_pdev_wmi *wmi = ar->wmi;
2494	struct wmi_stop_scan_cmd *cmd;
2495	struct sk_buff *skb;
2496	int ret;
2497
2498	skb = ath11k_wmi_alloc_skb(wmi->wmi_ab, sizeof(*cmd));
2499	if (!skb)
2500		return -ENOMEM;
2501
2502	cmd = (struct wmi_stop_scan_cmd *)skb->data;
2503
2504	cmd->tlv_header = FIELD_PREP(WMI_TLV_TAG, WMI_TAG_STOP_SCAN_CMD) |
2505			  FIELD_PREP(WMI_TLV_LEN, sizeof(*cmd) - TLV_HDR_SIZE);
2506
2507	cmd->vdev_id = param->vdev_id;
2508	cmd->requestor = param->requester;
2509	cmd->scan_id = param->scan_id;
2510	cmd->pdev_id = param->pdev_id;
2511	/* stop the scan with the corresponding scan_id */
2512	if (param->req_type == WLAN_SCAN_CANCEL_PDEV_ALL) {
2513		/* Cancelling all scans */
2514		cmd->req_type =  WMI_SCAN_STOP_ALL;
2515	} else if (param->req_type == WLAN_SCAN_CANCEL_VDEV_ALL) {
2516		/* Cancelling VAP scans */
2517		cmd->req_type =  WMI_SCN_STOP_VAP_ALL;
2518	} else if (param->req_type == WLAN_SCAN_CANCEL_SINGLE) {
2519		/* Cancelling specific scan */
2520		cmd->req_type =  WMI_SCAN_STOP_ONE;
2521	} else {
2522		ath11k_warn(ar->ab, "invalid scan cancel param %d",
2523			    param->req_type);
2524		dev_kfree_skb(skb);
2525		return -EINVAL;
2526	}
2527
2528	ret = ath11k_wmi_cmd_send(wmi, skb,
2529				  WMI_STOP_SCAN_CMDID);
2530	if (ret) {
2531		ath11k_warn(ar->ab, "failed to send WMI_STOP_SCAN_CMDID\n");
2532		dev_kfree_skb(skb);
2533	}
2534
2535	ath11k_dbg(ar->ab, ATH11K_DBG_WMI, "cmd stop scan");
2536
2537	return ret;
2538}
2539
2540int ath11k_wmi_send_scan_chan_list_cmd(struct ath11k *ar,
2541				       struct scan_chan_list_params *chan_list)
2542{
2543	struct ath11k_pdev_wmi *wmi = ar->wmi;
2544	struct wmi_scan_chan_list_cmd *cmd;
2545	struct sk_buff *skb;
2546	struct wmi_channel *chan_info;
2547	struct channel_param *tchan_info;
2548	struct wmi_tlv *tlv;
2549	void *ptr;
2550	int i, ret, len;
2551	u16 num_send_chans, num_sends = 0, max_chan_limit = 0;
2552	u32 *reg1, *reg2;
2553
2554	tchan_info = chan_list->ch_param;
2555	while (chan_list->nallchans) {
2556		len = sizeof(*cmd) + TLV_HDR_SIZE;
2557		max_chan_limit = (wmi->wmi_ab->max_msg_len[ar->pdev_idx] - len) /
2558			sizeof(*chan_info);
2559
2560		if (chan_list->nallchans > max_chan_limit)
2561			num_send_chans = max_chan_limit;
2562		else
2563			num_send_chans = chan_list->nallchans;
2564
2565		chan_list->nallchans -= num_send_chans;
2566		len += sizeof(*chan_info) * num_send_chans;
2567
2568		skb = ath11k_wmi_alloc_skb(wmi->wmi_ab, len);
2569		if (!skb)
2570			return -ENOMEM;
2571
2572		cmd = (struct wmi_scan_chan_list_cmd *)skb->data;
2573		cmd->tlv_header = FIELD_PREP(WMI_TLV_TAG, WMI_TAG_SCAN_CHAN_LIST_CMD) |
2574			FIELD_PREP(WMI_TLV_LEN, sizeof(*cmd) - TLV_HDR_SIZE);
2575		cmd->pdev_id = chan_list->pdev_id;
2576		cmd->num_scan_chans = num_send_chans;
2577		if (num_sends)
2578			cmd->flags |= WMI_APPEND_TO_EXISTING_CHAN_LIST_FLAG;
2579
2580		ath11k_dbg(ar->ab, ATH11K_DBG_WMI,
2581			   "no.of chan = %d len = %d pdev_id = %d num_sends = %d\n",
2582			   num_send_chans, len, cmd->pdev_id, num_sends);
2583
2584		ptr = skb->data + sizeof(*cmd);
2585
2586		len = sizeof(*chan_info) * num_send_chans;
2587		tlv = ptr;
2588		tlv->header = FIELD_PREP(WMI_TLV_TAG, WMI_TAG_ARRAY_STRUCT) |
2589			      FIELD_PREP(WMI_TLV_LEN, len - TLV_HDR_SIZE);
2590		ptr += TLV_HDR_SIZE;
2591
2592		for (i = 0; i < num_send_chans; ++i) {
2593			chan_info = ptr;
2594			memset(chan_info, 0, sizeof(*chan_info));
2595			len = sizeof(*chan_info);
2596			chan_info->tlv_header = FIELD_PREP(WMI_TLV_TAG,
2597							   WMI_TAG_CHANNEL) |
2598						FIELD_PREP(WMI_TLV_LEN,
2599							   len - TLV_HDR_SIZE);
2600
2601			reg1 = &chan_info->reg_info_1;
2602			reg2 = &chan_info->reg_info_2;
2603			chan_info->mhz = tchan_info->mhz;
2604			chan_info->band_center_freq1 = tchan_info->cfreq1;
2605			chan_info->band_center_freq2 = tchan_info->cfreq2;
2606
2607			if (tchan_info->is_chan_passive)
2608				chan_info->info |= WMI_CHAN_INFO_PASSIVE;
2609			if (tchan_info->allow_he)
2610				chan_info->info |= WMI_CHAN_INFO_ALLOW_HE;
2611			else if (tchan_info->allow_vht)
2612				chan_info->info |= WMI_CHAN_INFO_ALLOW_VHT;
2613			else if (tchan_info->allow_ht)
2614				chan_info->info |= WMI_CHAN_INFO_ALLOW_HT;
2615			if (tchan_info->half_rate)
2616				chan_info->info |= WMI_CHAN_INFO_HALF_RATE;
2617			if (tchan_info->quarter_rate)
2618				chan_info->info |= WMI_CHAN_INFO_QUARTER_RATE;
2619			if (tchan_info->psc_channel)
2620				chan_info->info |= WMI_CHAN_INFO_PSC;
2621			if (tchan_info->dfs_set)
2622				chan_info->info |= WMI_CHAN_INFO_DFS;
2623
2624			chan_info->info |= FIELD_PREP(WMI_CHAN_INFO_MODE,
2625						      tchan_info->phy_mode);
2626			*reg1 |= FIELD_PREP(WMI_CHAN_REG_INFO1_MIN_PWR,
2627					    tchan_info->minpower);
2628			*reg1 |= FIELD_PREP(WMI_CHAN_REG_INFO1_MAX_PWR,
2629					    tchan_info->maxpower);
2630			*reg1 |= FIELD_PREP(WMI_CHAN_REG_INFO1_MAX_REG_PWR,
2631					    tchan_info->maxregpower);
2632			*reg1 |= FIELD_PREP(WMI_CHAN_REG_INFO1_REG_CLS,
2633					    tchan_info->reg_class_id);
2634			*reg2 |= FIELD_PREP(WMI_CHAN_REG_INFO2_ANT_MAX,
2635					    tchan_info->antennamax);
2636			*reg2 |= FIELD_PREP(WMI_CHAN_REG_INFO2_MAX_TX_PWR,
2637					    tchan_info->maxregpower);
2638
2639			ath11k_dbg(ar->ab, ATH11K_DBG_WMI,
2640				   "chan scan list chan[%d] = %u, chan_info->info %8x\n",
2641				   i, chan_info->mhz, chan_info->info);
2642
2643			ptr += sizeof(*chan_info);
2644
2645			tchan_info++;
2646		}
2647
2648		ret = ath11k_wmi_cmd_send(wmi, skb, WMI_SCAN_CHAN_LIST_CMDID);
2649		if (ret) {
2650			ath11k_warn(ar->ab, "failed to send WMI_SCAN_CHAN_LIST cmd\n");
2651			dev_kfree_skb(skb);
2652			return ret;
2653		}
2654
2655		ath11k_dbg(ar->ab, ATH11K_DBG_WMI, "cmd scan chan list channels %d",
2656			   num_send_chans);
2657
2658		num_sends++;
2659	}
2660
2661	return 0;
2662}
2663
2664int ath11k_wmi_send_wmm_update_cmd_tlv(struct ath11k *ar, u32 vdev_id,
2665				       struct wmi_wmm_params_all_arg *param)
2666{
2667	struct ath11k_pdev_wmi *wmi = ar->wmi;
2668	struct wmi_vdev_set_wmm_params_cmd *cmd;
2669	struct wmi_wmm_params *wmm_param;
2670	struct wmi_wmm_params_arg *wmi_wmm_arg;
2671	struct sk_buff *skb;
2672	int ret, ac;
2673
2674	skb = ath11k_wmi_alloc_skb(wmi->wmi_ab, sizeof(*cmd));
2675	if (!skb)
2676		return -ENOMEM;
2677
2678	cmd = (struct wmi_vdev_set_wmm_params_cmd *)skb->data;
2679	cmd->tlv_header = FIELD_PREP(WMI_TLV_TAG,
2680				     WMI_TAG_VDEV_SET_WMM_PARAMS_CMD) |
2681			  FIELD_PREP(WMI_TLV_LEN, sizeof(*cmd) - TLV_HDR_SIZE);
2682
2683	cmd->vdev_id = vdev_id;
2684	cmd->wmm_param_type = 0;
2685
2686	for (ac = 0; ac < WME_NUM_AC; ac++) {
2687		switch (ac) {
2688		case WME_AC_BE:
2689			wmi_wmm_arg = &param->ac_be;
2690			break;
2691		case WME_AC_BK:
2692			wmi_wmm_arg = &param->ac_bk;
2693			break;
2694		case WME_AC_VI:
2695			wmi_wmm_arg = &param->ac_vi;
2696			break;
2697		case WME_AC_VO:
2698			wmi_wmm_arg = &param->ac_vo;
2699			break;
2700		}
2701
2702		wmm_param = (struct wmi_wmm_params *)&cmd->wmm_params[ac];
2703		wmm_param->tlv_header =
2704				FIELD_PREP(WMI_TLV_TAG,
2705					   WMI_TAG_VDEV_SET_WMM_PARAMS_CMD) |
2706				FIELD_PREP(WMI_TLV_LEN,
2707					   sizeof(*wmm_param) - TLV_HDR_SIZE);
2708
2709		wmm_param->aifs = wmi_wmm_arg->aifs;
2710		wmm_param->cwmin = wmi_wmm_arg->cwmin;
2711		wmm_param->cwmax = wmi_wmm_arg->cwmax;
2712		wmm_param->txoplimit = wmi_wmm_arg->txop;
2713		wmm_param->acm = wmi_wmm_arg->acm;
2714		wmm_param->no_ack = wmi_wmm_arg->no_ack;
2715
2716		ath11k_dbg(ar->ab, ATH11K_DBG_WMI,
2717			   "wmm set ac %d aifs %d cwmin %d cwmax %d txop %d acm %d no_ack %d\n",
2718			   ac, wmm_param->aifs, wmm_param->cwmin,
2719			   wmm_param->cwmax, wmm_param->txoplimit,
2720			   wmm_param->acm, wmm_param->no_ack);
2721	}
2722	ret = ath11k_wmi_cmd_send(wmi, skb,
2723				  WMI_VDEV_SET_WMM_PARAMS_CMDID);
2724	if (ret) {
2725		ath11k_warn(ar->ab,
2726			    "failed to send WMI_VDEV_SET_WMM_PARAMS_CMDID");
2727		dev_kfree_skb(skb);
2728	}
2729
2730	ath11k_dbg(ar->ab, ATH11K_DBG_WMI, "cmd vdev set wmm params");
2731
2732	return ret;
2733}
2734
2735int ath11k_wmi_send_dfs_phyerr_offload_enable_cmd(struct ath11k *ar,
2736						  u32 pdev_id)
2737{
2738	struct ath11k_pdev_wmi *wmi = ar->wmi;
2739	struct wmi_dfs_phyerr_offload_cmd *cmd;
2740	struct sk_buff *skb;
2741	int ret;
2742
2743	skb = ath11k_wmi_alloc_skb(wmi->wmi_ab, sizeof(*cmd));
2744	if (!skb)
2745		return -ENOMEM;
2746
2747	cmd = (struct wmi_dfs_phyerr_offload_cmd *)skb->data;
2748	cmd->tlv_header =
2749		FIELD_PREP(WMI_TLV_TAG,
2750			   WMI_TAG_PDEV_DFS_PHYERR_OFFLOAD_ENABLE_CMD) |
2751		FIELD_PREP(WMI_TLV_LEN, sizeof(*cmd) - TLV_HDR_SIZE);
2752
2753	cmd->pdev_id = pdev_id;
2754
2755	ret = ath11k_wmi_cmd_send(wmi, skb,
2756				  WMI_PDEV_DFS_PHYERR_OFFLOAD_ENABLE_CMDID);
2757	if (ret) {
2758		ath11k_warn(ar->ab,
2759			    "failed to send WMI_PDEV_DFS_PHYERR_OFFLOAD_ENABLE cmd\n");
2760		dev_kfree_skb(skb);
2761	}
2762
2763	ath11k_dbg(ar->ab, ATH11K_DBG_WMI,
2764		   "cmd pdev dfs phyerr offload enable pdev id %d\n", pdev_id);
2765
2766	return ret;
2767}
2768
2769int ath11k_wmi_delba_send(struct ath11k *ar, u32 vdev_id, const u8 *mac,
2770			  u32 tid, u32 initiator, u32 reason)
2771{
2772	struct ath11k_pdev_wmi *wmi = ar->wmi;
2773	struct wmi_delba_send_cmd *cmd;
2774	struct sk_buff *skb;
2775	int ret;
2776
2777	skb = ath11k_wmi_alloc_skb(wmi->wmi_ab, sizeof(*cmd));
2778	if (!skb)
2779		return -ENOMEM;
2780
2781	cmd = (struct wmi_delba_send_cmd *)skb->data;
2782	cmd->tlv_header = FIELD_PREP(WMI_TLV_TAG, WMI_TAG_DELBA_SEND_CMD) |
2783			FIELD_PREP(WMI_TLV_LEN, sizeof(*cmd) - TLV_HDR_SIZE);
2784	cmd->vdev_id = vdev_id;
2785	ether_addr_copy(cmd->peer_macaddr.addr, mac);
2786	cmd->tid = tid;
2787	cmd->initiator = initiator;
2788	cmd->reasoncode = reason;
2789
2790	ret = ath11k_wmi_cmd_send(wmi, skb, WMI_DELBA_SEND_CMDID);
2791
2792	if (ret) {
2793		ath11k_warn(ar->ab,
2794			    "failed to send WMI_DELBA_SEND_CMDID cmd\n");
2795		dev_kfree_skb(skb);
2796	}
2797
2798	ath11k_dbg(ar->ab, ATH11K_DBG_WMI,
2799		   "cmd delba send vdev_id 0x%X mac_addr %pM tid %u initiator %u reason %u\n",
2800		   vdev_id, mac, tid, initiator, reason);
2801
2802	return ret;
2803}
2804
2805int ath11k_wmi_addba_set_resp(struct ath11k *ar, u32 vdev_id, const u8 *mac,
2806			      u32 tid, u32 status)
2807{
2808	struct ath11k_pdev_wmi *wmi = ar->wmi;
2809	struct wmi_addba_setresponse_cmd *cmd;
2810	struct sk_buff *skb;
2811	int ret;
2812
2813	skb = ath11k_wmi_alloc_skb(wmi->wmi_ab, sizeof(*cmd));
2814	if (!skb)
2815		return -ENOMEM;
2816
2817	cmd = (struct wmi_addba_setresponse_cmd *)skb->data;
2818	cmd->tlv_header =
2819		FIELD_PREP(WMI_TLV_TAG, WMI_TAG_ADDBA_SETRESPONSE_CMD) |
2820		FIELD_PREP(WMI_TLV_LEN, sizeof(*cmd) - TLV_HDR_SIZE);
2821	cmd->vdev_id = vdev_id;
2822	ether_addr_copy(cmd->peer_macaddr.addr, mac);
2823	cmd->tid = tid;
2824	cmd->statuscode = status;
2825
2826	ret = ath11k_wmi_cmd_send(wmi, skb, WMI_ADDBA_SET_RESP_CMDID);
2827
2828	if (ret) {
2829		ath11k_warn(ar->ab,
2830			    "failed to send WMI_ADDBA_SET_RESP_CMDID cmd\n");
2831		dev_kfree_skb(skb);
2832	}
2833
2834	ath11k_dbg(ar->ab, ATH11K_DBG_WMI,
2835		   "cmd addba set resp vdev_id 0x%X mac_addr %pM tid %u status %u\n",
2836		   vdev_id, mac, tid, status);
2837
2838	return ret;
2839}
2840
2841int ath11k_wmi_addba_send(struct ath11k *ar, u32 vdev_id, const u8 *mac,
2842			  u32 tid, u32 buf_size)
2843{
2844	struct ath11k_pdev_wmi *wmi = ar->wmi;
2845	struct wmi_addba_send_cmd *cmd;
2846	struct sk_buff *skb;
2847	int ret;
2848
2849	skb = ath11k_wmi_alloc_skb(wmi->wmi_ab, sizeof(*cmd));
2850	if (!skb)
2851		return -ENOMEM;
2852
2853	cmd = (struct wmi_addba_send_cmd *)skb->data;
2854	cmd->tlv_header = FIELD_PREP(WMI_TLV_TAG, WMI_TAG_ADDBA_SEND_CMD) |
2855		FIELD_PREP(WMI_TLV_LEN, sizeof(*cmd) - TLV_HDR_SIZE);
2856	cmd->vdev_id = vdev_id;
2857	ether_addr_copy(cmd->peer_macaddr.addr, mac);
2858	cmd->tid = tid;
2859	cmd->buffersize = buf_size;
2860
2861	ret = ath11k_wmi_cmd_send(wmi, skb, WMI_ADDBA_SEND_CMDID);
2862
2863	if (ret) {
2864		ath11k_warn(ar->ab,
2865			    "failed to send WMI_ADDBA_SEND_CMDID cmd\n");
2866		dev_kfree_skb(skb);
2867	}
2868
2869	ath11k_dbg(ar->ab, ATH11K_DBG_WMI,
2870		   "cmd addba send vdev_id 0x%X mac_addr %pM tid %u bufsize %u\n",
2871		   vdev_id, mac, tid, buf_size);
2872
2873	return ret;
2874}
2875
2876int ath11k_wmi_addba_clear_resp(struct ath11k *ar, u32 vdev_id, const u8 *mac)
2877{
2878	struct ath11k_pdev_wmi *wmi = ar->wmi;
2879	struct wmi_addba_clear_resp_cmd *cmd;
2880	struct sk_buff *skb;
2881	int ret;
2882
2883	skb = ath11k_wmi_alloc_skb(wmi->wmi_ab, sizeof(*cmd));
2884	if (!skb)
2885		return -ENOMEM;
2886
2887	cmd = (struct wmi_addba_clear_resp_cmd *)skb->data;
2888	cmd->tlv_header =
2889		FIELD_PREP(WMI_TLV_TAG, WMI_TAG_ADDBA_CLEAR_RESP_CMD) |
2890		FIELD_PREP(WMI_TLV_LEN, sizeof(*cmd) - TLV_HDR_SIZE);
2891	cmd->vdev_id = vdev_id;
2892	ether_addr_copy(cmd->peer_macaddr.addr, mac);
2893
2894	ret = ath11k_wmi_cmd_send(wmi, skb, WMI_ADDBA_CLEAR_RESP_CMDID);
2895
2896	if (ret) {
2897		ath11k_warn(ar->ab,
2898			    "failed to send WMI_ADDBA_CLEAR_RESP_CMDID cmd\n");
2899		dev_kfree_skb(skb);
2900	}
2901
2902	ath11k_dbg(ar->ab, ATH11K_DBG_WMI,
2903		   "cmd addba clear resp vdev_id 0x%X mac_addr %pM\n",
2904		   vdev_id, mac);
2905
2906	return ret;
2907}
2908
2909int ath11k_wmi_pdev_peer_pktlog_filter(struct ath11k *ar, u8 *addr, u8 enable)
2910{
2911	struct ath11k_pdev_wmi *wmi = ar->wmi;
2912	struct wmi_pdev_pktlog_filter_cmd *cmd;
2913	struct wmi_pdev_pktlog_filter_info *info;
2914	struct sk_buff *skb;
2915	struct wmi_tlv *tlv;
2916	void *ptr;
2917	int ret, len;
2918
2919	len = sizeof(*cmd) + sizeof(*info) + TLV_HDR_SIZE;
2920	skb = ath11k_wmi_alloc_skb(wmi->wmi_ab, len);
2921	if (!skb)
2922		return -ENOMEM;
2923
2924	cmd = (struct wmi_pdev_pktlog_filter_cmd *)skb->data;
2925
2926	cmd->tlv_header = FIELD_PREP(WMI_TLV_TAG, WMI_TAG_PDEV_PEER_PKTLOG_FILTER_CMD) |
2927			  FIELD_PREP(WMI_TLV_LEN, sizeof(*cmd) - TLV_HDR_SIZE);
2928
2929	cmd->pdev_id = DP_HW2SW_MACID(ar->pdev->pdev_id);
2930	cmd->num_mac = 1;
2931	cmd->enable = enable;
2932
2933	ptr = skb->data + sizeof(*cmd);
2934
2935	tlv = ptr;
2936	tlv->header = FIELD_PREP(WMI_TLV_TAG, WMI_TAG_ARRAY_STRUCT) |
2937		      FIELD_PREP(WMI_TLV_LEN, sizeof(*info));
2938
2939	ptr += TLV_HDR_SIZE;
2940	info = ptr;
2941
2942	ether_addr_copy(info->peer_macaddr.addr, addr);
2943	info->tlv_header = FIELD_PREP(WMI_TLV_TAG, WMI_TAG_PDEV_PEER_PKTLOG_FILTER_INFO) |
2944			   FIELD_PREP(WMI_TLV_LEN,
2945				      sizeof(*info) - TLV_HDR_SIZE);
2946
2947	ret = ath11k_wmi_cmd_send(wmi, skb,
2948				  WMI_PDEV_PKTLOG_FILTER_CMDID);
2949	if (ret) {
2950		ath11k_warn(ar->ab, "failed to send WMI_PDEV_PKTLOG_ENABLE_CMDID\n");
2951		dev_kfree_skb(skb);
2952	}
2953
2954	ath11k_dbg(ar->ab, ATH11K_DBG_WMI, "cmd pdev pktlog filter");
2955
2956	return ret;
2957}
2958
2959int
2960ath11k_wmi_send_init_country_cmd(struct ath11k *ar,
2961				 struct wmi_init_country_params init_cc_params)
2962{
2963	struct ath11k_pdev_wmi *wmi = ar->wmi;
2964	struct wmi_init_country_cmd *cmd;
2965	struct sk_buff *skb;
2966	int ret;
2967
2968	skb = ath11k_wmi_alloc_skb(wmi->wmi_ab, sizeof(*cmd));
2969	if (!skb)
2970		return -ENOMEM;
2971
2972	cmd = (struct wmi_init_country_cmd *)skb->data;
2973	cmd->tlv_header =
2974		FIELD_PREP(WMI_TLV_TAG,
2975			   WMI_TAG_SET_INIT_COUNTRY_CMD) |
2976		FIELD_PREP(WMI_TLV_LEN, sizeof(*cmd) - TLV_HDR_SIZE);
2977
2978	cmd->pdev_id = ar->pdev->pdev_id;
2979
2980	switch (init_cc_params.flags) {
2981	case ALPHA_IS_SET:
2982		cmd->init_cc_type = WMI_COUNTRY_INFO_TYPE_ALPHA;
2983		memcpy((u8 *)&cmd->cc_info.alpha2,
2984		       init_cc_params.cc_info.alpha2, 3);
2985		break;
2986	case CC_IS_SET:
2987		cmd->init_cc_type = WMI_COUNTRY_INFO_TYPE_COUNTRY_CODE;
2988		cmd->cc_info.country_code = init_cc_params.cc_info.country_code;
2989		break;
2990	case REGDMN_IS_SET:
2991		cmd->init_cc_type = WMI_COUNTRY_INFO_TYPE_REGDOMAIN;
2992		cmd->cc_info.regdom_id = init_cc_params.cc_info.regdom_id;
2993		break;
2994	default:
2995		ath11k_warn(ar->ab, "unknown cc params flags: 0x%x",
2996			    init_cc_params.flags);
2997		ret = -EINVAL;
2998		goto err;
2999	}
3000
3001	ret = ath11k_wmi_cmd_send(wmi, skb,
3002				  WMI_SET_INIT_COUNTRY_CMDID);
3003	if (ret) {
3004		ath11k_warn(ar->ab,
3005			    "failed to send WMI_SET_INIT_COUNTRY CMD :%d\n",
3006			    ret);
3007		goto err;
3008	}
3009
3010	ath11k_dbg(ar->ab, ATH11K_DBG_WMI, "cmd set init country");
3011
3012	return 0;
3013
3014err:
3015	dev_kfree_skb(skb);
3016	return ret;
3017}
3018
3019int ath11k_wmi_send_set_current_country_cmd(struct ath11k *ar,
3020					    struct wmi_set_current_country_params *param)
3021{
3022	struct ath11k_pdev_wmi *wmi = ar->wmi;
3023	struct wmi_set_current_country_cmd *cmd;
3024	struct sk_buff *skb;
3025	int ret;
3026
3027	skb = ath11k_wmi_alloc_skb(wmi->wmi_ab, sizeof(*cmd));
3028	if (!skb)
3029		return -ENOMEM;
3030
3031	cmd = (struct wmi_set_current_country_cmd *)skb->data;
3032	cmd->tlv_header =
3033		FIELD_PREP(WMI_TLV_TAG, WMI_TAG_SET_CURRENT_COUNTRY_CMD) |
3034		FIELD_PREP(WMI_TLV_LEN, sizeof(*cmd) - TLV_HDR_SIZE);
3035
3036	cmd->pdev_id = ar->pdev->pdev_id;
3037	memcpy(&cmd->new_alpha2, &param->alpha2, 3);
3038
3039	ret = ath11k_wmi_cmd_send(wmi, skb, WMI_SET_CURRENT_COUNTRY_CMDID);
3040	if (ret) {
3041		ath11k_warn(ar->ab,
3042			    "failed to send WMI_SET_CURRENT_COUNTRY_CMDID: %d\n", ret);
3043		dev_kfree_skb(skb);
3044	}
3045
3046	ath11k_dbg(ar->ab, ATH11K_DBG_WMI,
3047		   "cmd set current country pdev id %d alpha2 %c%c\n",
3048		   ar->pdev->pdev_id,
3049		   param->alpha2[0],
3050		   param->alpha2[1]);
3051
3052	return ret;
3053}
3054
3055int
3056ath11k_wmi_send_thermal_mitigation_param_cmd(struct ath11k *ar,
3057					     struct thermal_mitigation_params *param)
3058{
3059	struct ath11k_pdev_wmi *wmi = ar->wmi;
3060	struct wmi_therm_throt_config_request_cmd *cmd;
3061	struct wmi_therm_throt_level_config_info *lvl_conf;
3062	struct wmi_tlv *tlv;
3063	struct sk_buff *skb;
3064	int i, ret, len;
3065
3066	len = sizeof(*cmd) + TLV_HDR_SIZE +
3067	      THERMAL_LEVELS * sizeof(struct wmi_therm_throt_level_config_info);
3068
3069	skb = ath11k_wmi_alloc_skb(wmi->wmi_ab, len);
3070	if (!skb)
3071		return -ENOMEM;
3072
3073	cmd = (struct wmi_therm_throt_config_request_cmd *)skb->data;
3074
3075	cmd->tlv_header = FIELD_PREP(WMI_TLV_TAG, WMI_TAG_THERM_THROT_CONFIG_REQUEST) |
3076			  FIELD_PREP(WMI_TLV_LEN, sizeof(*cmd) - TLV_HDR_SIZE);
3077
3078	cmd->pdev_id = ar->pdev->pdev_id;
3079	cmd->enable = param->enable;
3080	cmd->dc = param->dc;
3081	cmd->dc_per_event = param->dc_per_event;
3082	cmd->therm_throt_levels = THERMAL_LEVELS;
3083
3084	tlv = (struct wmi_tlv *)(skb->data + sizeof(*cmd));
3085	tlv->header = FIELD_PREP(WMI_TLV_TAG, WMI_TAG_ARRAY_STRUCT) |
3086		      FIELD_PREP(WMI_TLV_LEN,
3087				 (THERMAL_LEVELS *
3088				  sizeof(struct wmi_therm_throt_level_config_info)));
3089
3090	lvl_conf = (struct wmi_therm_throt_level_config_info *)(skb->data +
3091								sizeof(*cmd) +
3092								TLV_HDR_SIZE);
3093	for (i = 0; i < THERMAL_LEVELS; i++) {
3094		lvl_conf->tlv_header =
3095			FIELD_PREP(WMI_TLV_TAG, WMI_TAG_THERM_THROT_LEVEL_CONFIG_INFO) |
3096			FIELD_PREP(WMI_TLV_LEN, sizeof(*lvl_conf) - TLV_HDR_SIZE);
3097
3098		lvl_conf->temp_lwm = param->levelconf[i].tmplwm;
3099		lvl_conf->temp_hwm = param->levelconf[i].tmphwm;
3100		lvl_conf->dc_off_percent = param->levelconf[i].dcoffpercent;
3101		lvl_conf->prio = param->levelconf[i].priority;
3102		lvl_conf++;
3103	}
3104
3105	ret = ath11k_wmi_cmd_send(wmi, skb, WMI_THERM_THROT_SET_CONF_CMDID);
3106	if (ret) {
3107		ath11k_warn(ar->ab, "failed to send THERM_THROT_SET_CONF cmd\n");
3108		dev_kfree_skb(skb);
3109	}
3110
3111	ath11k_dbg(ar->ab, ATH11K_DBG_WMI,
3112		   "cmd therm throt set conf pdev_id %d enable %d dc %d dc_per_event %x levels %d\n",
3113		   ar->pdev->pdev_id, param->enable, param->dc,
3114		   param->dc_per_event, THERMAL_LEVELS);
3115
3116	return ret;
3117}
3118
3119int ath11k_wmi_send_11d_scan_start_cmd(struct ath11k *ar,
3120				       struct wmi_11d_scan_start_params *param)
3121{
3122	struct ath11k_pdev_wmi *wmi = ar->wmi;
3123	struct wmi_11d_scan_start_cmd *cmd;
3124	struct sk_buff *skb;
3125	int ret;
3126
3127	skb = ath11k_wmi_alloc_skb(wmi->wmi_ab, sizeof(*cmd));
3128	if (!skb)
3129		return -ENOMEM;
3130
3131	cmd = (struct wmi_11d_scan_start_cmd *)skb->data;
3132	cmd->tlv_header =
3133		FIELD_PREP(WMI_TLV_TAG, WMI_TAG_11D_SCAN_START_CMD) |
3134		FIELD_PREP(WMI_TLV_LEN, sizeof(*cmd) - TLV_HDR_SIZE);
3135
3136	cmd->vdev_id = param->vdev_id;
3137	cmd->scan_period_msec = param->scan_period_msec;
3138	cmd->start_interval_msec = param->start_interval_msec;
3139
3140	ret = ath11k_wmi_cmd_send(wmi, skb, WMI_11D_SCAN_START_CMDID);
3141	if (ret) {
3142		ath11k_warn(ar->ab,
3143			    "failed to send WMI_11D_SCAN_START_CMDID: %d\n", ret);
3144		dev_kfree_skb(skb);
3145	}
3146
3147	ath11k_dbg(ar->ab, ATH11K_DBG_WMI,
3148		   "cmd 11d scan start vdev id %d period %d ms internal %d ms\n",
3149		   cmd->vdev_id,
3150		   cmd->scan_period_msec,
3151		   cmd->start_interval_msec);
3152
3153	return ret;
3154}
3155
3156int ath11k_wmi_send_11d_scan_stop_cmd(struct ath11k *ar, u32 vdev_id)
3157{
3158	struct ath11k_pdev_wmi *wmi = ar->wmi;
3159	struct wmi_11d_scan_stop_cmd *cmd;
3160	struct sk_buff *skb;
3161	int ret;
3162
3163	skb = ath11k_wmi_alloc_skb(wmi->wmi_ab, sizeof(*cmd));
3164	if (!skb)
3165		return -ENOMEM;
3166
3167	cmd = (struct wmi_11d_scan_stop_cmd *)skb->data;
3168	cmd->tlv_header =
3169		FIELD_PREP(WMI_TLV_TAG, WMI_TAG_11D_SCAN_STOP_CMD) |
3170		FIELD_PREP(WMI_TLV_LEN, sizeof(*cmd) - TLV_HDR_SIZE);
3171
3172	cmd->vdev_id = vdev_id;
3173
3174	ret = ath11k_wmi_cmd_send(wmi, skb, WMI_11D_SCAN_STOP_CMDID);
3175	if (ret) {
3176		ath11k_warn(ar->ab,
3177			    "failed to send WMI_11D_SCAN_STOP_CMDID: %d\n", ret);
3178		dev_kfree_skb(skb);
3179	}
3180
3181	ath11k_dbg(ar->ab, ATH11K_DBG_WMI,
3182		   "cmd 11d scan stop vdev id %d\n",
3183		   cmd->vdev_id);
3184
3185	return ret;
3186}
3187
3188int ath11k_wmi_pdev_pktlog_enable(struct ath11k *ar, u32 pktlog_filter)
3189{
3190	struct ath11k_pdev_wmi *wmi = ar->wmi;
3191	struct wmi_pktlog_enable_cmd *cmd;
3192	struct sk_buff *skb;
3193	int ret;
3194
3195	skb = ath11k_wmi_alloc_skb(wmi->wmi_ab, sizeof(*cmd));
3196	if (!skb)
3197		return -ENOMEM;
3198
3199	cmd = (struct wmi_pktlog_enable_cmd *)skb->data;
3200
3201	cmd->tlv_header = FIELD_PREP(WMI_TLV_TAG, WMI_TAG_PDEV_PKTLOG_ENABLE_CMD) |
3202			  FIELD_PREP(WMI_TLV_LEN, sizeof(*cmd) - TLV_HDR_SIZE);
3203
3204	cmd->pdev_id = DP_HW2SW_MACID(ar->pdev->pdev_id);
3205	cmd->evlist = pktlog_filter;
3206	cmd->enable = ATH11K_WMI_PKTLOG_ENABLE_FORCE;
3207
3208	ret = ath11k_wmi_cmd_send(wmi, skb,
3209				  WMI_PDEV_PKTLOG_ENABLE_CMDID);
3210	if (ret) {
3211		ath11k_warn(ar->ab, "failed to send WMI_PDEV_PKTLOG_ENABLE_CMDID\n");
3212		dev_kfree_skb(skb);
3213	}
3214
3215	ath11k_dbg(ar->ab, ATH11K_DBG_WMI, "cmd pdev pktlog enable");
3216
3217	return ret;
3218}
3219
3220int ath11k_wmi_pdev_pktlog_disable(struct ath11k *ar)
3221{
3222	struct ath11k_pdev_wmi *wmi = ar->wmi;
3223	struct wmi_pktlog_disable_cmd *cmd;
3224	struct sk_buff *skb;
3225	int ret;
3226
3227	skb = ath11k_wmi_alloc_skb(wmi->wmi_ab, sizeof(*cmd));
3228	if (!skb)
3229		return -ENOMEM;
3230
3231	cmd = (struct wmi_pktlog_disable_cmd *)skb->data;
3232
3233	cmd->tlv_header = FIELD_PREP(WMI_TLV_TAG, WMI_TAG_PDEV_PKTLOG_DISABLE_CMD) |
3234			  FIELD_PREP(WMI_TLV_LEN, sizeof(*cmd) - TLV_HDR_SIZE);
3235
3236	cmd->pdev_id = DP_HW2SW_MACID(ar->pdev->pdev_id);
3237
3238	ret = ath11k_wmi_cmd_send(wmi, skb,
3239				  WMI_PDEV_PKTLOG_DISABLE_CMDID);
3240	if (ret) {
3241		ath11k_warn(ar->ab, "failed to send WMI_PDEV_PKTLOG_ENABLE_CMDID\n");
3242		dev_kfree_skb(skb);
3243	}
3244
3245	ath11k_dbg(ar->ab, ATH11K_DBG_WMI, "cmd pdev pktlog disable");
3246
3247	return ret;
3248}
3249
3250void ath11k_wmi_fill_default_twt_params(struct wmi_twt_enable_params *twt_params)
3251{
3252	twt_params->sta_cong_timer_ms = ATH11K_TWT_DEF_STA_CONG_TIMER_MS;
3253	twt_params->default_slot_size = ATH11K_TWT_DEF_DEFAULT_SLOT_SIZE;
3254	twt_params->congestion_thresh_setup = ATH11K_TWT_DEF_CONGESTION_THRESH_SETUP;
3255	twt_params->congestion_thresh_teardown =
3256		ATH11K_TWT_DEF_CONGESTION_THRESH_TEARDOWN;
3257	twt_params->congestion_thresh_critical =
3258		ATH11K_TWT_DEF_CONGESTION_THRESH_CRITICAL;
3259	twt_params->interference_thresh_teardown =
3260		ATH11K_TWT_DEF_INTERFERENCE_THRESH_TEARDOWN;
3261	twt_params->interference_thresh_setup =
3262		ATH11K_TWT_DEF_INTERFERENCE_THRESH_SETUP;
3263	twt_params->min_no_sta_setup = ATH11K_TWT_DEF_MIN_NO_STA_SETUP;
3264	twt_params->min_no_sta_teardown = ATH11K_TWT_DEF_MIN_NO_STA_TEARDOWN;
3265	twt_params->no_of_bcast_mcast_slots = ATH11K_TWT_DEF_NO_OF_BCAST_MCAST_SLOTS;
3266	twt_params->min_no_twt_slots = ATH11K_TWT_DEF_MIN_NO_TWT_SLOTS;
3267	twt_params->max_no_sta_twt = ATH11K_TWT_DEF_MAX_NO_STA_TWT;
3268	twt_params->mode_check_interval = ATH11K_TWT_DEF_MODE_CHECK_INTERVAL;
3269	twt_params->add_sta_slot_interval = ATH11K_TWT_DEF_ADD_STA_SLOT_INTERVAL;
3270	twt_params->remove_sta_slot_interval =
3271		ATH11K_TWT_DEF_REMOVE_STA_SLOT_INTERVAL;
3272	/* TODO add MBSSID support */
3273	twt_params->mbss_support = 0;
3274}
3275
3276int ath11k_wmi_send_twt_enable_cmd(struct ath11k *ar, u32 pdev_id,
3277				   struct wmi_twt_enable_params *params)
3278{
3279	struct ath11k_pdev_wmi *wmi = ar->wmi;
3280	struct ath11k_base *ab = wmi->wmi_ab->ab;
3281	struct wmi_twt_enable_params_cmd *cmd;
3282	struct sk_buff *skb;
3283	int ret, len;
3284
3285	len = sizeof(*cmd);
3286
3287	skb = ath11k_wmi_alloc_skb(wmi->wmi_ab, len);
3288	if (!skb)
3289		return -ENOMEM;
3290
3291	cmd = (struct wmi_twt_enable_params_cmd *)skb->data;
3292	cmd->tlv_header = FIELD_PREP(WMI_TLV_TAG, WMI_TAG_TWT_ENABLE_CMD) |
3293			  FIELD_PREP(WMI_TLV_LEN, len - TLV_HDR_SIZE);
3294	cmd->pdev_id = pdev_id;
3295	cmd->sta_cong_timer_ms = params->sta_cong_timer_ms;
3296	cmd->default_slot_size = params->default_slot_size;
3297	cmd->congestion_thresh_setup = params->congestion_thresh_setup;
3298	cmd->congestion_thresh_teardown = params->congestion_thresh_teardown;
3299	cmd->congestion_thresh_critical = params->congestion_thresh_critical;
3300	cmd->interference_thresh_teardown = params->interference_thresh_teardown;
3301	cmd->interference_thresh_setup = params->interference_thresh_setup;
3302	cmd->min_no_sta_setup = params->min_no_sta_setup;
3303	cmd->min_no_sta_teardown = params->min_no_sta_teardown;
3304	cmd->no_of_bcast_mcast_slots = params->no_of_bcast_mcast_slots;
3305	cmd->min_no_twt_slots = params->min_no_twt_slots;
3306	cmd->max_no_sta_twt = params->max_no_sta_twt;
3307	cmd->mode_check_interval = params->mode_check_interval;
3308	cmd->add_sta_slot_interval = params->add_sta_slot_interval;
3309	cmd->remove_sta_slot_interval = params->remove_sta_slot_interval;
3310	cmd->mbss_support = params->mbss_support;
3311
3312	ret = ath11k_wmi_cmd_send(wmi, skb, WMI_TWT_ENABLE_CMDID);
3313	if (ret) {
3314		ath11k_warn(ab, "Failed to send WMI_TWT_ENABLE_CMDID");
3315		dev_kfree_skb(skb);
3316		return ret;
3317	}
3318
3319	ar->twt_enabled = 1;
3320
3321	ath11k_dbg(ab, ATH11K_DBG_WMI, "cmd twt enable");
3322
3323	return 0;
3324}
3325
3326int
3327ath11k_wmi_send_twt_disable_cmd(struct ath11k *ar, u32 pdev_id)
3328{
3329	struct ath11k_pdev_wmi *wmi = ar->wmi;
3330	struct ath11k_base *ab = wmi->wmi_ab->ab;
3331	struct wmi_twt_disable_params_cmd *cmd;
3332	struct sk_buff *skb;
3333	int ret, len;
3334
3335	len = sizeof(*cmd);
3336
3337	skb = ath11k_wmi_alloc_skb(wmi->wmi_ab, len);
3338	if (!skb)
3339		return -ENOMEM;
3340
3341	cmd = (struct wmi_twt_disable_params_cmd *)skb->data;
3342	cmd->tlv_header = FIELD_PREP(WMI_TLV_TAG, WMI_TAG_TWT_DISABLE_CMD) |
3343			  FIELD_PREP(WMI_TLV_LEN, len - TLV_HDR_SIZE);
3344	cmd->pdev_id = pdev_id;
3345
3346	ret = ath11k_wmi_cmd_send(wmi, skb, WMI_TWT_DISABLE_CMDID);
3347	if (ret) {
3348		ath11k_warn(ab, "Failed to send WMI_TWT_DISABLE_CMDID");
3349		dev_kfree_skb(skb);
3350		return ret;
3351	}
3352
3353	ath11k_dbg(ab, ATH11K_DBG_WMI, "cmd twt disable");
3354
3355	ar->twt_enabled = 0;
3356
3357	return 0;
3358}
3359
3360int ath11k_wmi_send_twt_add_dialog_cmd(struct ath11k *ar,
3361				       struct wmi_twt_add_dialog_params *params)
3362{
3363	struct ath11k_pdev_wmi *wmi = ar->wmi;
3364	struct ath11k_base *ab = wmi->wmi_ab->ab;
3365	struct wmi_twt_add_dialog_params_cmd *cmd;
3366	struct sk_buff *skb;
3367	int ret, len;
3368
3369	len = sizeof(*cmd);
3370
3371	skb = ath11k_wmi_alloc_skb(wmi->wmi_ab, len);
3372	if (!skb)
3373		return -ENOMEM;
3374
3375	cmd = (struct wmi_twt_add_dialog_params_cmd *)skb->data;
3376	cmd->tlv_header = FIELD_PREP(WMI_TLV_TAG, WMI_TAG_TWT_ADD_DIALOG_CMD) |
3377			  FIELD_PREP(WMI_TLV_LEN, len - TLV_HDR_SIZE);
3378
3379	cmd->vdev_id = params->vdev_id;
3380	ether_addr_copy(cmd->peer_macaddr.addr, params->peer_macaddr);
3381	cmd->dialog_id = params->dialog_id;
3382	cmd->wake_intvl_us = params->wake_intvl_us;
3383	cmd->wake_intvl_mantis = params->wake_intvl_mantis;
3384	cmd->wake_dura_us = params->wake_dura_us;
3385	cmd->sp_offset_us = params->sp_offset_us;
3386	cmd->flags = params->twt_cmd;
3387	if (params->flag_bcast)
3388		cmd->flags |= WMI_TWT_ADD_DIALOG_FLAG_BCAST;
3389	if (params->flag_trigger)
3390		cmd->flags |= WMI_TWT_ADD_DIALOG_FLAG_TRIGGER;
3391	if (params->flag_flow_type)
3392		cmd->flags |= WMI_TWT_ADD_DIALOG_FLAG_FLOW_TYPE;
3393	if (params->flag_protection)
3394		cmd->flags |= WMI_TWT_ADD_DIALOG_FLAG_PROTECTION;
3395
3396	ret = ath11k_wmi_cmd_send(wmi, skb, WMI_TWT_ADD_DIALOG_CMDID);
3397	if (ret) {
3398		ath11k_warn(ab,
3399			    "failed to send wmi command to add twt dialog: %d",
3400			    ret);
3401		dev_kfree_skb(skb);
3402		return ret;
3403	}
3404
3405	ath11k_dbg(ar->ab, ATH11K_DBG_WMI,
3406		   "cmd twt add dialog vdev %u dialog id %u wake interval %u mantissa %u wake duration %u service period offset %u flags 0x%x\n",
3407		   cmd->vdev_id, cmd->dialog_id, cmd->wake_intvl_us,
3408		   cmd->wake_intvl_mantis, cmd->wake_dura_us, cmd->sp_offset_us,
3409		   cmd->flags);
3410
3411	return 0;
3412}
3413
3414int ath11k_wmi_send_twt_del_dialog_cmd(struct ath11k *ar,
3415				       struct wmi_twt_del_dialog_params *params)
3416{
3417	struct ath11k_pdev_wmi *wmi = ar->wmi;
3418	struct ath11k_base *ab = wmi->wmi_ab->ab;
3419	struct wmi_twt_del_dialog_params_cmd *cmd;
3420	struct sk_buff *skb;
3421	int ret, len;
3422
3423	len = sizeof(*cmd);
3424
3425	skb = ath11k_wmi_alloc_skb(wmi->wmi_ab, len);
3426	if (!skb)
3427		return -ENOMEM;
3428
3429	cmd = (struct wmi_twt_del_dialog_params_cmd *)skb->data;
3430	cmd->tlv_header = FIELD_PREP(WMI_TLV_TAG, WMI_TAG_TWT_DEL_DIALOG_CMD) |
3431			  FIELD_PREP(WMI_TLV_LEN, len - TLV_HDR_SIZE);
3432
3433	cmd->vdev_id = params->vdev_id;
3434	ether_addr_copy(cmd->peer_macaddr.addr, params->peer_macaddr);
3435	cmd->dialog_id = params->dialog_id;
3436
3437	ret = ath11k_wmi_cmd_send(wmi, skb, WMI_TWT_DEL_DIALOG_CMDID);
3438	if (ret) {
3439		ath11k_warn(ab,
3440			    "failed to send wmi command to delete twt dialog: %d",
3441			    ret);
3442		dev_kfree_skb(skb);
3443		return ret;
3444	}
3445
3446	ath11k_dbg(ar->ab, ATH11K_DBG_WMI,
3447		   "cmd twt del dialog vdev %u dialog id %u\n",
3448		   cmd->vdev_id, cmd->dialog_id);
3449
3450	return 0;
3451}
3452
3453int ath11k_wmi_send_twt_pause_dialog_cmd(struct ath11k *ar,
3454					 struct wmi_twt_pause_dialog_params *params)
3455{
3456	struct ath11k_pdev_wmi *wmi = ar->wmi;
3457	struct ath11k_base *ab = wmi->wmi_ab->ab;
3458	struct wmi_twt_pause_dialog_params_cmd *cmd;
3459	struct sk_buff *skb;
3460	int ret, len;
3461
3462	len = sizeof(*cmd);
3463
3464	skb = ath11k_wmi_alloc_skb(wmi->wmi_ab, len);
3465	if (!skb)
3466		return -ENOMEM;
3467
3468	cmd = (struct wmi_twt_pause_dialog_params_cmd *)skb->data;
3469	cmd->tlv_header = FIELD_PREP(WMI_TLV_TAG,
3470				     WMI_TAG_TWT_PAUSE_DIALOG_CMD) |
3471			  FIELD_PREP(WMI_TLV_LEN, len - TLV_HDR_SIZE);
3472
3473	cmd->vdev_id = params->vdev_id;
3474	ether_addr_copy(cmd->peer_macaddr.addr, params->peer_macaddr);
3475	cmd->dialog_id = params->dialog_id;
3476
3477	ret = ath11k_wmi_cmd_send(wmi, skb, WMI_TWT_PAUSE_DIALOG_CMDID);
3478	if (ret) {
3479		ath11k_warn(ab,
3480			    "failed to send wmi command to pause twt dialog: %d",
3481			    ret);
3482		dev_kfree_skb(skb);
3483		return ret;
3484	}
3485
3486	ath11k_dbg(ar->ab, ATH11K_DBG_WMI,
3487		   "cmd twt pause dialog vdev %u dialog id %u\n",
3488		   cmd->vdev_id, cmd->dialog_id);
3489
3490	return 0;
3491}
3492
3493int ath11k_wmi_send_twt_resume_dialog_cmd(struct ath11k *ar,
3494					  struct wmi_twt_resume_dialog_params *params)
3495{
3496	struct ath11k_pdev_wmi *wmi = ar->wmi;
3497	struct ath11k_base *ab = wmi->wmi_ab->ab;
3498	struct wmi_twt_resume_dialog_params_cmd *cmd;
3499	struct sk_buff *skb;
3500	int ret, len;
3501
3502	len = sizeof(*cmd);
3503
3504	skb = ath11k_wmi_alloc_skb(wmi->wmi_ab, len);
3505	if (!skb)
3506		return -ENOMEM;
3507
3508	cmd = (struct wmi_twt_resume_dialog_params_cmd *)skb->data;
3509	cmd->tlv_header = FIELD_PREP(WMI_TLV_TAG,
3510				     WMI_TAG_TWT_RESUME_DIALOG_CMD) |
3511			  FIELD_PREP(WMI_TLV_LEN, len - TLV_HDR_SIZE);
3512
3513	cmd->vdev_id = params->vdev_id;
3514	ether_addr_copy(cmd->peer_macaddr.addr, params->peer_macaddr);
3515	cmd->dialog_id = params->dialog_id;
3516	cmd->sp_offset_us = params->sp_offset_us;
3517	cmd->next_twt_size = params->next_twt_size;
3518
3519	ret = ath11k_wmi_cmd_send(wmi, skb, WMI_TWT_RESUME_DIALOG_CMDID);
3520	if (ret) {
3521		ath11k_warn(ab,
3522			    "failed to send wmi command to resume twt dialog: %d",
3523			    ret);
3524		dev_kfree_skb(skb);
3525		return ret;
3526	}
3527
3528	ath11k_dbg(ar->ab, ATH11K_DBG_WMI,
3529		   "cmd twt resume dialog vdev %u dialog id %u service period offset %u next twt subfield size %u\n",
3530		   cmd->vdev_id, cmd->dialog_id, cmd->sp_offset_us,
3531		   cmd->next_twt_size);
3532
3533	return 0;
3534}
3535
3536int
3537ath11k_wmi_send_obss_spr_cmd(struct ath11k *ar, u32 vdev_id,
3538			     struct ieee80211_he_obss_pd *he_obss_pd)
3539{
3540	struct ath11k_pdev_wmi *wmi = ar->wmi;
3541	struct ath11k_base *ab = wmi->wmi_ab->ab;
3542	struct wmi_obss_spatial_reuse_params_cmd *cmd;
3543	struct sk_buff *skb;
3544	int ret, len;
3545
3546	len = sizeof(*cmd);
3547
3548	skb = ath11k_wmi_alloc_skb(wmi->wmi_ab, len);
3549	if (!skb)
3550		return -ENOMEM;
3551
3552	cmd = (struct wmi_obss_spatial_reuse_params_cmd *)skb->data;
3553	cmd->tlv_header = FIELD_PREP(WMI_TLV_TAG,
3554				     WMI_TAG_OBSS_SPATIAL_REUSE_SET_CMD) |
3555			  FIELD_PREP(WMI_TLV_LEN, len - TLV_HDR_SIZE);
3556	cmd->vdev_id = vdev_id;
3557	cmd->enable = he_obss_pd->enable;
3558	cmd->obss_min = he_obss_pd->min_offset;
3559	cmd->obss_max = he_obss_pd->max_offset;
3560
3561	ret = ath11k_wmi_cmd_send(wmi, skb,
3562				  WMI_PDEV_OBSS_PD_SPATIAL_REUSE_CMDID);
3563	if (ret) {
3564		ath11k_warn(ab,
3565			    "Failed to send WMI_PDEV_OBSS_PD_SPATIAL_REUSE_CMDID");
3566		dev_kfree_skb(skb);
3567		return ret;
3568	}
3569
3570	ath11k_dbg(ab, ATH11K_DBG_WMI, "cmd pdev obss pd spatial reuse");
3571
3572	return 0;
3573}
3574
3575int
3576ath11k_wmi_pdev_set_srg_bss_color_bitmap(struct ath11k *ar, u32 *bitmap)
3577{
3578	struct ath11k_pdev_wmi *wmi = ar->wmi;
3579	struct ath11k_base *ab = wmi->wmi_ab->ab;
3580	struct wmi_pdev_obss_pd_bitmap_cmd *cmd;
3581	struct sk_buff *skb;
3582	int ret, len;
3583
3584	len = sizeof(*cmd);
3585
3586	skb = ath11k_wmi_alloc_skb(wmi->wmi_ab, len);
3587	if (!skb)
3588		return -ENOMEM;
3589
3590	cmd = (struct wmi_pdev_obss_pd_bitmap_cmd *)skb->data;
3591	cmd->tlv_header = FIELD_PREP(WMI_TLV_TAG,
3592				     WMI_TAG_PDEV_SRG_BSS_COLOR_BITMAP_CMD) |
3593			  FIELD_PREP(WMI_TLV_LEN, len - TLV_HDR_SIZE);
3594	cmd->pdev_id = ar->pdev->pdev_id;
3595	memcpy(cmd->bitmap, bitmap, sizeof(cmd->bitmap));
3596
3597	ret = ath11k_wmi_cmd_send(wmi, skb,
3598				  WMI_PDEV_SET_SRG_BSS_COLOR_BITMAP_CMDID);
3599	if (ret) {
3600		ath11k_warn(ab,
3601			    "failed to send WMI_PDEV_SET_SRG_BSS_COLOR_BITMAP_CMDID");
3602		dev_kfree_skb(skb);
3603		return ret;
3604	}
3605
3606	ath11k_dbg(ar->ab, ATH11K_DBG_WMI,
3607		   "cmd pdev set srg bss color bitmap pdev_id %d bss color bitmap %08x %08x\n",
3608		   cmd->pdev_id, cmd->bitmap[0], cmd->bitmap[1]);
3609
3610	return 0;
3611}
3612
3613int
3614ath11k_wmi_pdev_set_srg_patial_bssid_bitmap(struct ath11k *ar, u32 *bitmap)
3615{
3616	struct ath11k_pdev_wmi *wmi = ar->wmi;
3617	struct ath11k_base *ab = wmi->wmi_ab->ab;
3618	struct wmi_pdev_obss_pd_bitmap_cmd *cmd;
3619	struct sk_buff *skb;
3620	int ret, len;
3621
3622	len = sizeof(*cmd);
3623
3624	skb = ath11k_wmi_alloc_skb(wmi->wmi_ab, len);
3625	if (!skb)
3626		return -ENOMEM;
3627
3628	cmd = (struct wmi_pdev_obss_pd_bitmap_cmd *)skb->data;
3629	cmd->tlv_header =
3630		FIELD_PREP(WMI_TLV_TAG,
3631			   WMI_TAG_PDEV_SRG_PARTIAL_BSSID_BITMAP_CMD) |
3632		FIELD_PREP(WMI_TLV_LEN, len - TLV_HDR_SIZE);
3633	cmd->pdev_id = ar->pdev->pdev_id;
3634	memcpy(cmd->bitmap, bitmap, sizeof(cmd->bitmap));
3635
3636	ret = ath11k_wmi_cmd_send(wmi, skb,
3637				  WMI_PDEV_SET_SRG_PARTIAL_BSSID_BITMAP_CMDID);
3638	if (ret) {
3639		ath11k_warn(ab,
3640			    "failed to send WMI_PDEV_SET_SRG_PARTIAL_BSSID_BITMAP_CMDID");
3641		dev_kfree_skb(skb);
3642		return ret;
3643	}
3644
3645	ath11k_dbg(ar->ab, ATH11K_DBG_WMI,
3646		   "cmd pdev set srg partial bssid bitmap pdev_id %d partial bssid bitmap %08x %08x\n",
3647		   cmd->pdev_id, cmd->bitmap[0], cmd->bitmap[1]);
3648
3649	return 0;
3650}
3651
3652int
3653ath11k_wmi_pdev_srg_obss_color_enable_bitmap(struct ath11k *ar, u32 *bitmap)
3654{
3655	struct ath11k_pdev_wmi *wmi = ar->wmi;
3656	struct ath11k_base *ab = wmi->wmi_ab->ab;
3657	struct wmi_pdev_obss_pd_bitmap_cmd *cmd;
3658	struct sk_buff *skb;
3659	int ret, len;
3660
3661	len = sizeof(*cmd);
3662
3663	skb = ath11k_wmi_alloc_skb(wmi->wmi_ab, len);
3664	if (!skb)
3665		return -ENOMEM;
3666
3667	cmd = (struct wmi_pdev_obss_pd_bitmap_cmd *)skb->data;
3668	cmd->tlv_header =
3669		FIELD_PREP(WMI_TLV_TAG,
3670			   WMI_TAG_PDEV_SRG_OBSS_COLOR_ENABLE_BITMAP_CMD) |
3671		FIELD_PREP(WMI_TLV_LEN, len - TLV_HDR_SIZE);
3672	cmd->pdev_id = ar->pdev->pdev_id;
3673	memcpy(cmd->bitmap, bitmap, sizeof(cmd->bitmap));
3674
3675	ret = ath11k_wmi_cmd_send(wmi, skb,
3676				  WMI_PDEV_SET_SRG_OBSS_COLOR_ENABLE_BITMAP_CMDID);
3677	if (ret) {
3678		ath11k_warn(ab,
3679			    "failed to send WMI_PDEV_SET_SRG_OBSS_COLOR_ENABLE_BITMAP_CMDID");
3680		dev_kfree_skb(skb);
3681		return ret;
3682	}
3683
3684	ath11k_dbg(ar->ab, ATH11K_DBG_WMI,
3685		   "cmd pdev set srg obsscolor enable pdev_id %d bss color enable bitmap %08x %08x\n",
3686		   cmd->pdev_id, cmd->bitmap[0], cmd->bitmap[1]);
3687
3688	return 0;
3689}
3690
3691int
3692ath11k_wmi_pdev_srg_obss_bssid_enable_bitmap(struct ath11k *ar, u32 *bitmap)
3693{
3694	struct ath11k_pdev_wmi *wmi = ar->wmi;
3695	struct ath11k_base *ab = wmi->wmi_ab->ab;
3696	struct wmi_pdev_obss_pd_bitmap_cmd *cmd;
3697	struct sk_buff *skb;
3698	int ret, len;
3699
3700	len = sizeof(*cmd);
3701
3702	skb = ath11k_wmi_alloc_skb(wmi->wmi_ab, len);
3703	if (!skb)
3704		return -ENOMEM;
3705
3706	cmd = (struct wmi_pdev_obss_pd_bitmap_cmd *)skb->data;
3707	cmd->tlv_header =
3708		FIELD_PREP(WMI_TLV_TAG,
3709			   WMI_TAG_PDEV_SRG_OBSS_BSSID_ENABLE_BITMAP_CMD) |
3710		FIELD_PREP(WMI_TLV_LEN, len - TLV_HDR_SIZE);
3711	cmd->pdev_id = ar->pdev->pdev_id;
3712	memcpy(cmd->bitmap, bitmap, sizeof(cmd->bitmap));
3713
3714	ret = ath11k_wmi_cmd_send(wmi, skb,
3715				  WMI_PDEV_SET_SRG_OBSS_BSSID_ENABLE_BITMAP_CMDID);
3716	if (ret) {
3717		ath11k_warn(ab,
3718			    "failed to send WMI_PDEV_SET_SRG_OBSS_BSSID_ENABLE_BITMAP_CMDID");
3719		dev_kfree_skb(skb);
3720		return ret;
3721	}
3722
3723	ath11k_dbg(ar->ab, ATH11K_DBG_WMI,
3724		   "cmd pdev set srg obss bssid enable bitmap pdev_id %d bssid enable bitmap %08x %08x\n",
3725		   cmd->pdev_id, cmd->bitmap[0], cmd->bitmap[1]);
3726
3727	return 0;
3728}
3729
3730int
3731ath11k_wmi_pdev_non_srg_obss_color_enable_bitmap(struct ath11k *ar, u32 *bitmap)
3732{
3733	struct ath11k_pdev_wmi *wmi = ar->wmi;
3734	struct ath11k_base *ab = wmi->wmi_ab->ab;
3735	struct wmi_pdev_obss_pd_bitmap_cmd *cmd;
3736	struct sk_buff *skb;
3737	int ret, len;
3738
3739	len = sizeof(*cmd);
3740
3741	skb = ath11k_wmi_alloc_skb(wmi->wmi_ab, len);
3742	if (!skb)
3743		return -ENOMEM;
3744
3745	cmd = (struct wmi_pdev_obss_pd_bitmap_cmd *)skb->data;
3746	cmd->tlv_header =
3747		FIELD_PREP(WMI_TLV_TAG,
3748			   WMI_TAG_PDEV_NON_SRG_OBSS_COLOR_ENABLE_BITMAP_CMD) |
3749		FIELD_PREP(WMI_TLV_LEN, len - TLV_HDR_SIZE);
3750	cmd->pdev_id = ar->pdev->pdev_id;
3751	memcpy(cmd->bitmap, bitmap, sizeof(cmd->bitmap));
3752
3753	ret = ath11k_wmi_cmd_send(wmi, skb,
3754				  WMI_PDEV_SET_NON_SRG_OBSS_COLOR_ENABLE_BITMAP_CMDID);
3755	if (ret) {
3756		ath11k_warn(ab,
3757			    "failed to send WMI_PDEV_SET_NON_SRG_OBSS_COLOR_ENABLE_BITMAP_CMDID");
3758		dev_kfree_skb(skb);
3759		return ret;
3760	}
3761
3762	ath11k_dbg(ar->ab, ATH11K_DBG_WMI,
3763		   "cmd pdev set non srg obss color enable bitmap pdev_id %d bss color enable bitmap %08x %08x\n",
3764		   cmd->pdev_id, cmd->bitmap[0], cmd->bitmap[1]);
3765
3766	return 0;
3767}
3768
3769int
3770ath11k_wmi_pdev_non_srg_obss_bssid_enable_bitmap(struct ath11k *ar, u32 *bitmap)
3771{
3772	struct ath11k_pdev_wmi *wmi = ar->wmi;
3773	struct ath11k_base *ab = wmi->wmi_ab->ab;
3774	struct wmi_pdev_obss_pd_bitmap_cmd *cmd;
3775	struct sk_buff *skb;
3776	int ret, len;
3777
3778	len = sizeof(*cmd);
3779
3780	skb = ath11k_wmi_alloc_skb(wmi->wmi_ab, len);
3781	if (!skb)
3782		return -ENOMEM;
3783
3784	cmd = (struct wmi_pdev_obss_pd_bitmap_cmd *)skb->data;
3785	cmd->tlv_header =
3786		FIELD_PREP(WMI_TLV_TAG,
3787			   WMI_TAG_PDEV_NON_SRG_OBSS_BSSID_ENABLE_BITMAP_CMD) |
3788		FIELD_PREP(WMI_TLV_LEN, len - TLV_HDR_SIZE);
3789	cmd->pdev_id = ar->pdev->pdev_id;
3790	memcpy(cmd->bitmap, bitmap, sizeof(cmd->bitmap));
3791
3792	ret = ath11k_wmi_cmd_send(wmi, skb,
3793				  WMI_PDEV_SET_NON_SRG_OBSS_BSSID_ENABLE_BITMAP_CMDID);
3794	if (ret) {
3795		ath11k_warn(ab,
3796			    "failed to send WMI_PDEV_SET_NON_SRG_OBSS_BSSID_ENABLE_BITMAP_CMDID");
3797		dev_kfree_skb(skb);
3798		return ret;
3799	}
3800
3801	ath11k_dbg(ar->ab, ATH11K_DBG_WMI,
3802		   "cmd pdev set non srg obss bssid enable bitmap pdev_id %d bssid enable bitmap %08x %08x\n",
3803		   cmd->pdev_id, cmd->bitmap[0], cmd->bitmap[1]);
3804
3805	return 0;
3806}
3807
3808int
3809ath11k_wmi_send_obss_color_collision_cfg_cmd(struct ath11k *ar, u32 vdev_id,
3810					     u8 bss_color, u32 period,
3811					     bool enable)
3812{
3813	struct ath11k_pdev_wmi *wmi = ar->wmi;
3814	struct ath11k_base *ab = wmi->wmi_ab->ab;
3815	struct wmi_obss_color_collision_cfg_params_cmd *cmd;
3816	struct sk_buff *skb;
3817	int ret, len;
3818
3819	len = sizeof(*cmd);
3820
3821	skb = ath11k_wmi_alloc_skb(wmi->wmi_ab, len);
3822	if (!skb)
3823		return -ENOMEM;
3824
3825	cmd = (struct wmi_obss_color_collision_cfg_params_cmd *)skb->data;
3826	cmd->tlv_header = FIELD_PREP(WMI_TLV_TAG,
3827				     WMI_TAG_OBSS_COLOR_COLLISION_DET_CONFIG) |
3828			  FIELD_PREP(WMI_TLV_LEN, len - TLV_HDR_SIZE);
3829	cmd->vdev_id = vdev_id;
3830	cmd->evt_type = enable ? ATH11K_OBSS_COLOR_COLLISION_DETECTION :
3831				 ATH11K_OBSS_COLOR_COLLISION_DETECTION_DISABLE;
3832	cmd->current_bss_color = bss_color;
3833	cmd->detection_period_ms = period;
3834	cmd->scan_period_ms = ATH11K_BSS_COLOR_COLLISION_SCAN_PERIOD_MS;
3835	cmd->free_slot_expiry_time_ms = 0;
3836	cmd->flags = 0;
3837
3838	ret = ath11k_wmi_cmd_send(wmi, skb,
3839				  WMI_OBSS_COLOR_COLLISION_DET_CONFIG_CMDID);
3840	if (ret) {
3841		ath11k_warn(ab, "Failed to send WMI_OBSS_COLOR_COLLISION_DET_CONFIG_CMDID");
3842		dev_kfree_skb(skb);
3843		return ret;
3844	}
3845
3846	ath11k_dbg(ar->ab, ATH11K_DBG_WMI,
3847		   "cmd obss color collision det config id %d type %d bss_color %d detect_period %d scan_period %d\n",
3848		   cmd->vdev_id, cmd->evt_type, cmd->current_bss_color,
3849		   cmd->detection_period_ms, cmd->scan_period_ms);
3850
3851	return 0;
3852}
3853
3854int ath11k_wmi_send_bss_color_change_enable_cmd(struct ath11k *ar, u32 vdev_id,
3855						bool enable)
3856{
3857	struct ath11k_pdev_wmi *wmi = ar->wmi;
3858	struct ath11k_base *ab = wmi->wmi_ab->ab;
3859	struct wmi_bss_color_change_enable_params_cmd *cmd;
3860	struct sk_buff *skb;
3861	int ret, len;
3862
3863	len = sizeof(*cmd);
3864
3865	skb = ath11k_wmi_alloc_skb(wmi->wmi_ab, len);
3866	if (!skb)
3867		return -ENOMEM;
3868
3869	cmd = (struct wmi_bss_color_change_enable_params_cmd *)skb->data;
3870	cmd->tlv_header = FIELD_PREP(WMI_TLV_TAG, WMI_TAG_BSS_COLOR_CHANGE_ENABLE) |
3871			  FIELD_PREP(WMI_TLV_LEN, len - TLV_HDR_SIZE);
3872	cmd->vdev_id = vdev_id;
3873	cmd->enable = enable ? 1 : 0;
3874
3875	ret = ath11k_wmi_cmd_send(wmi, skb,
3876				  WMI_BSS_COLOR_CHANGE_ENABLE_CMDID);
3877	if (ret) {
3878		ath11k_warn(ab, "Failed to send WMI_BSS_COLOR_CHANGE_ENABLE_CMDID");
3879		dev_kfree_skb(skb);
3880		return ret;
3881	}
3882
3883	ath11k_dbg(ar->ab, ATH11K_DBG_WMI,
3884		   "cmd bss color change enable id %d enable %d\n",
3885		   cmd->vdev_id, cmd->enable);
3886
3887	return 0;
3888}
3889
3890int ath11k_wmi_fils_discovery_tmpl(struct ath11k *ar, u32 vdev_id,
3891				   struct sk_buff *tmpl)
3892{
3893	struct wmi_tlv *tlv;
3894	struct sk_buff *skb;
3895	void *ptr;
3896	int ret, len;
3897	size_t aligned_len;
3898	struct wmi_fils_discovery_tmpl_cmd *cmd;
3899
3900	aligned_len = roundup(tmpl->len, 4);
3901	len = sizeof(*cmd) + TLV_HDR_SIZE + aligned_len;
3902
3903	ath11k_dbg(ar->ab, ATH11K_DBG_WMI,
3904		   "vdev %i set FILS discovery template\n", vdev_id);
3905
3906	skb = ath11k_wmi_alloc_skb(ar->wmi->wmi_ab, len);
3907	if (!skb)
3908		return -ENOMEM;
3909
3910	cmd = (struct wmi_fils_discovery_tmpl_cmd *)skb->data;
3911	cmd->tlv_header = FIELD_PREP(WMI_TLV_TAG,
3912				     WMI_TAG_FILS_DISCOVERY_TMPL_CMD) |
3913			  FIELD_PREP(WMI_TLV_LEN, sizeof(*cmd) - TLV_HDR_SIZE);
3914	cmd->vdev_id = vdev_id;
3915	cmd->buf_len = tmpl->len;
3916	ptr = skb->data + sizeof(*cmd);
3917
3918	tlv = ptr;
3919	tlv->header = FIELD_PREP(WMI_TLV_TAG, WMI_TAG_ARRAY_BYTE) |
3920		      FIELD_PREP(WMI_TLV_LEN, aligned_len);
3921	memcpy(tlv->value, tmpl->data, tmpl->len);
3922
3923	ret = ath11k_wmi_cmd_send(ar->wmi, skb, WMI_FILS_DISCOVERY_TMPL_CMDID);
3924	if (ret) {
3925		ath11k_warn(ar->ab,
3926			    "WMI vdev %i failed to send FILS discovery template command\n",
3927			    vdev_id);
3928		dev_kfree_skb(skb);
3929		return ret;
3930	}
3931
3932	ath11k_dbg(ar->ab, ATH11K_DBG_WMI, "cmd fils discovery tmpl");
3933
3934	return 0;
3935}
3936
3937int ath11k_wmi_probe_resp_tmpl(struct ath11k *ar, u32 vdev_id,
3938			       struct sk_buff *tmpl)
3939{
3940	struct wmi_probe_tmpl_cmd *cmd;
3941	struct wmi_bcn_prb_info *probe_info;
3942	struct wmi_tlv *tlv;
3943	struct sk_buff *skb;
3944	void *ptr;
3945	int ret, len;
3946	size_t aligned_len = roundup(tmpl->len, 4);
3947
3948	ath11k_dbg(ar->ab, ATH11K_DBG_WMI,
3949		   "vdev %i set probe response template\n", vdev_id);
3950
3951	len = sizeof(*cmd) + sizeof(*probe_info) + TLV_HDR_SIZE + aligned_len;
3952
3953	skb = ath11k_wmi_alloc_skb(ar->wmi->wmi_ab, len);
3954	if (!skb)
3955		return -ENOMEM;
3956
3957	cmd = (struct wmi_probe_tmpl_cmd *)skb->data;
3958	cmd->tlv_header = FIELD_PREP(WMI_TLV_TAG, WMI_TAG_PRB_TMPL_CMD) |
3959			  FIELD_PREP(WMI_TLV_LEN, sizeof(*cmd) - TLV_HDR_SIZE);
3960	cmd->vdev_id = vdev_id;
3961	cmd->buf_len = tmpl->len;
3962
3963	ptr = skb->data + sizeof(*cmd);
3964
3965	probe_info = ptr;
3966	len = sizeof(*probe_info);
3967	probe_info->tlv_header = FIELD_PREP(WMI_TLV_TAG,
3968					    WMI_TAG_BCN_PRB_INFO) |
3969				 FIELD_PREP(WMI_TLV_LEN, len - TLV_HDR_SIZE);
3970	probe_info->caps = 0;
3971	probe_info->erp = 0;
3972
3973	ptr += sizeof(*probe_info);
3974
3975	tlv = ptr;
3976	tlv->header = FIELD_PREP(WMI_TLV_TAG, WMI_TAG_ARRAY_BYTE) |
3977		      FIELD_PREP(WMI_TLV_LEN, aligned_len);
3978	memcpy(tlv->value, tmpl->data, tmpl->len);
3979
3980	ret = ath11k_wmi_cmd_send(ar->wmi, skb, WMI_PRB_TMPL_CMDID);
3981	if (ret) {
3982		ath11k_warn(ar->ab,
3983			    "WMI vdev %i failed to send probe response template command\n",
3984			    vdev_id);
3985		dev_kfree_skb(skb);
3986		return ret;
3987	}
3988
3989	ath11k_dbg(ar->ab, ATH11K_DBG_WMI, "cmd ");
3990
3991	return 0;
3992}
3993
3994int ath11k_wmi_fils_discovery(struct ath11k *ar, u32 vdev_id, u32 interval,
3995			      bool unsol_bcast_probe_resp_enabled)
3996{
3997	struct sk_buff *skb;
3998	int ret, len;
3999	struct wmi_fils_discovery_cmd *cmd;
4000
4001	ath11k_dbg(ar->ab, ATH11K_DBG_WMI,
4002		   "vdev %i set %s interval to %u TU\n",
4003		   vdev_id, unsol_bcast_probe_resp_enabled ?
4004		   "unsolicited broadcast probe response" : "FILS discovery",
4005		   interval);
4006
4007	len = sizeof(*cmd);
4008	skb = ath11k_wmi_alloc_skb(ar->wmi->wmi_ab, len);
4009	if (!skb)
4010		return -ENOMEM;
4011
4012	cmd = (struct wmi_fils_discovery_cmd *)skb->data;
4013	cmd->tlv_header = FIELD_PREP(WMI_TLV_TAG, WMI_TAG_ENABLE_FILS_CMD) |
4014			  FIELD_PREP(WMI_TLV_LEN, len - TLV_HDR_SIZE);
4015	cmd->vdev_id = vdev_id;
4016	cmd->interval = interval;
4017	cmd->config = unsol_bcast_probe_resp_enabled;
4018
4019	ret = ath11k_wmi_cmd_send(ar->wmi, skb, WMI_ENABLE_FILS_CMDID);
4020	if (ret) {
4021		ath11k_warn(ar->ab,
4022			    "WMI vdev %i failed to send FILS discovery enable/disable command\n",
4023			    vdev_id);
4024		dev_kfree_skb(skb);
4025		return ret;
4026	}
4027
4028	ath11k_dbg(ar->ab, ATH11K_DBG_WMI, "cmd enable fils");
4029
4030	return 0;
4031}
4032
4033static void
4034ath11k_wmi_obss_color_collision_event(struct ath11k_base *ab, struct sk_buff *skb)
4035{
4036	const void **tb;
4037	const struct wmi_obss_color_collision_event *ev;
4038	struct ath11k_vif *arvif;
4039	int ret;
4040
4041	tb = ath11k_wmi_tlv_parse_alloc(ab, skb, GFP_ATOMIC);
4042	if (IS_ERR(tb)) {
4043		ret = PTR_ERR(tb);
4044		ath11k_warn(ab, "failed to parse tlv: %d\n", ret);
4045		return;
4046	}
4047
4048	ath11k_dbg(ab, ATH11K_DBG_WMI, "event obss color collision");
4049
4050	rcu_read_lock();
4051
4052	ev = tb[WMI_TAG_OBSS_COLOR_COLLISION_EVT];
4053	if (!ev) {
4054		ath11k_warn(ab, "failed to fetch obss color collision ev");
4055		goto exit;
4056	}
4057
4058	arvif = ath11k_mac_get_arvif_by_vdev_id(ab, ev->vdev_id);
4059	if (!arvif) {
4060		ath11k_warn(ab, "failed to find arvif with vedv id %d in obss_color_collision_event\n",
4061			    ev->vdev_id);
4062		goto exit;
4063	}
4064
4065	switch (ev->evt_type) {
4066	case WMI_BSS_COLOR_COLLISION_DETECTION:
4067		ieee80211_obss_color_collision_notify(arvif->vif, ev->obss_color_bitmap,
4068						      0);
4069		ath11k_dbg(ab, ATH11K_DBG_WMI,
4070			   "OBSS color collision detected vdev:%d, event:%d, bitmap:%08llx\n",
4071			   ev->vdev_id, ev->evt_type, ev->obss_color_bitmap);
4072		break;
4073	case WMI_BSS_COLOR_COLLISION_DISABLE:
4074	case WMI_BSS_COLOR_FREE_SLOT_TIMER_EXPIRY:
4075	case WMI_BSS_COLOR_FREE_SLOT_AVAILABLE:
4076		break;
4077	default:
4078		ath11k_warn(ab, "received unknown obss color collision detection event\n");
4079	}
4080
4081exit:
4082	kfree(tb);
4083	rcu_read_unlock();
4084}
4085
4086static void
4087ath11k_fill_band_to_mac_param(struct ath11k_base  *soc,
4088			      struct wmi_host_pdev_band_to_mac *band_to_mac)
4089{
4090	u8 i;
4091	struct ath11k_hal_reg_capabilities_ext *hal_reg_cap;
4092	struct ath11k_pdev *pdev;
4093
4094	for (i = 0; i < soc->num_radios; i++) {
4095		pdev = &soc->pdevs[i];
4096		hal_reg_cap = &soc->hal_reg_cap[i];
4097		band_to_mac[i].pdev_id = pdev->pdev_id;
4098
4099		switch (pdev->cap.supported_bands) {
4100		case WMI_HOST_WLAN_2G_5G_CAP:
4101			band_to_mac[i].start_freq = hal_reg_cap->low_2ghz_chan;
4102			band_to_mac[i].end_freq = hal_reg_cap->high_5ghz_chan;
4103			break;
4104		case WMI_HOST_WLAN_2G_CAP:
4105			band_to_mac[i].start_freq = hal_reg_cap->low_2ghz_chan;
4106			band_to_mac[i].end_freq = hal_reg_cap->high_2ghz_chan;
4107			break;
4108		case WMI_HOST_WLAN_5G_CAP:
4109			band_to_mac[i].start_freq = hal_reg_cap->low_5ghz_chan;
4110			band_to_mac[i].end_freq = hal_reg_cap->high_5ghz_chan;
4111			break;
4112		default:
4113			break;
4114		}
4115	}
4116}
4117
4118static void
4119ath11k_wmi_copy_resource_config(struct wmi_resource_config *wmi_cfg,
4120				struct target_resource_config *tg_cfg)
4121{
4122	wmi_cfg->num_vdevs = tg_cfg->num_vdevs;
4123	wmi_cfg->num_peers = tg_cfg->num_peers;
4124	wmi_cfg->num_offload_peers = tg_cfg->num_offload_peers;
4125	wmi_cfg->num_offload_reorder_buffs = tg_cfg->num_offload_reorder_buffs;
4126	wmi_cfg->num_peer_keys = tg_cfg->num_peer_keys;
4127	wmi_cfg->num_tids = tg_cfg->num_tids;
4128	wmi_cfg->ast_skid_limit = tg_cfg->ast_skid_limit;
4129	wmi_cfg->tx_chain_mask = tg_cfg->tx_chain_mask;
4130	wmi_cfg->rx_chain_mask = tg_cfg->rx_chain_mask;
4131	wmi_cfg->rx_timeout_pri[0] = tg_cfg->rx_timeout_pri[0];
4132	wmi_cfg->rx_timeout_pri[1] = tg_cfg->rx_timeout_pri[1];
4133	wmi_cfg->rx_timeout_pri[2] = tg_cfg->rx_timeout_pri[2];
4134	wmi_cfg->rx_timeout_pri[3] = tg_cfg->rx_timeout_pri[3];
4135	wmi_cfg->rx_decap_mode = tg_cfg->rx_decap_mode;
4136	wmi_cfg->scan_max_pending_req = tg_cfg->scan_max_pending_req;
4137	wmi_cfg->bmiss_offload_max_vdev = tg_cfg->bmiss_offload_max_vdev;
4138	wmi_cfg->roam_offload_max_vdev = tg_cfg->roam_offload_max_vdev;
4139	wmi_cfg->roam_offload_max_ap_profiles =
4140		tg_cfg->roam_offload_max_ap_profiles;
4141	wmi_cfg->num_mcast_groups = tg_cfg->num_mcast_groups;
4142	wmi_cfg->num_mcast_table_elems = tg_cfg->num_mcast_table_elems;
4143	wmi_cfg->mcast2ucast_mode = tg_cfg->mcast2ucast_mode;
4144	wmi_cfg->tx_dbg_log_size = tg_cfg->tx_dbg_log_size;
4145	wmi_cfg->num_wds_entries = tg_cfg->num_wds_entries;
4146	wmi_cfg->dma_burst_size = tg_cfg->dma_burst_size;
4147	wmi_cfg->mac_aggr_delim = tg_cfg->mac_aggr_delim;
4148	wmi_cfg->rx_skip_defrag_timeout_dup_detection_check =
4149		tg_cfg->rx_skip_defrag_timeout_dup_detection_check;
4150	wmi_cfg->vow_config = tg_cfg->vow_config;
4151	wmi_cfg->gtk_offload_max_vdev = tg_cfg->gtk_offload_max_vdev;
4152	wmi_cfg->num_msdu_desc = tg_cfg->num_msdu_desc;
4153	wmi_cfg->max_frag_entries = tg_cfg->max_frag_entries;
4154	wmi_cfg->num_tdls_vdevs = tg_cfg->num_tdls_vdevs;
4155	wmi_cfg->num_tdls_conn_table_entries =
4156		tg_cfg->num_tdls_conn_table_entries;
4157	wmi_cfg->beacon_tx_offload_max_vdev =
4158		tg_cfg->beacon_tx_offload_max_vdev;
4159	wmi_cfg->num_multicast_filter_entries =
4160		tg_cfg->num_multicast_filter_entries;
4161	wmi_cfg->num_wow_filters = tg_cfg->num_wow_filters;
4162	wmi_cfg->num_keep_alive_pattern = tg_cfg->num_keep_alive_pattern;
4163	wmi_cfg->keep_alive_pattern_size = tg_cfg->keep_alive_pattern_size;
4164	wmi_cfg->max_tdls_concurrent_sleep_sta =
4165		tg_cfg->max_tdls_concurrent_sleep_sta;
4166	wmi_cfg->max_tdls_concurrent_buffer_sta =
4167		tg_cfg->max_tdls_concurrent_buffer_sta;
4168	wmi_cfg->wmi_send_separate = tg_cfg->wmi_send_separate;
4169	wmi_cfg->num_ocb_vdevs = tg_cfg->num_ocb_vdevs;
4170	wmi_cfg->num_ocb_channels = tg_cfg->num_ocb_channels;
4171	wmi_cfg->num_ocb_schedules = tg_cfg->num_ocb_schedules;
4172	wmi_cfg->bpf_instruction_size = tg_cfg->bpf_instruction_size;
4173	wmi_cfg->max_bssid_rx_filters = tg_cfg->max_bssid_rx_filters;
4174	wmi_cfg->use_pdev_id = tg_cfg->use_pdev_id;
4175	wmi_cfg->flag1 = tg_cfg->flag1;
4176	wmi_cfg->peer_map_unmap_v2_support = tg_cfg->peer_map_unmap_v2_support;
4177	wmi_cfg->sched_params = tg_cfg->sched_params;
4178	wmi_cfg->twt_ap_pdev_count = tg_cfg->twt_ap_pdev_count;
4179	wmi_cfg->twt_ap_sta_count = tg_cfg->twt_ap_sta_count;
4180	wmi_cfg->host_service_flags &=
4181		~(1 << WMI_CFG_HOST_SERVICE_FLAG_REG_CC_EXT);
4182	wmi_cfg->host_service_flags |= (tg_cfg->is_reg_cc_ext_event_supported <<
4183					WMI_CFG_HOST_SERVICE_FLAG_REG_CC_EXT);
4184	wmi_cfg->flags2 = WMI_RSRC_CFG_FLAG2_CALC_NEXT_DTIM_COUNT_SET;
4185	wmi_cfg->ema_max_vap_cnt = tg_cfg->ema_max_vap_cnt;
4186	wmi_cfg->ema_max_profile_period = tg_cfg->ema_max_profile_period;
4187}
4188
4189static int ath11k_init_cmd_send(struct ath11k_pdev_wmi *wmi,
4190				struct wmi_init_cmd_param *param)
4191{
4192	struct ath11k_base *ab = wmi->wmi_ab->ab;
4193	struct sk_buff *skb;
4194	struct wmi_init_cmd *cmd;
4195	struct wmi_resource_config *cfg;
4196	struct wmi_pdev_set_hw_mode_cmd_param *hw_mode;
4197	struct wmi_pdev_band_to_mac *band_to_mac;
4198	struct wlan_host_mem_chunk *host_mem_chunks;
4199	struct wmi_tlv *tlv;
4200	size_t ret, len;
4201	void *ptr;
4202	u32 hw_mode_len = 0;
4203	u16 idx;
4204
4205	if (param->hw_mode_id != WMI_HOST_HW_MODE_MAX)
4206		hw_mode_len = sizeof(*hw_mode) + TLV_HDR_SIZE +
4207			      (param->num_band_to_mac * sizeof(*band_to_mac));
4208
4209	len = sizeof(*cmd) + TLV_HDR_SIZE + sizeof(*cfg) + hw_mode_len +
4210	      (param->num_mem_chunks ? (sizeof(*host_mem_chunks) * WMI_MAX_MEM_REQS) : 0);
4211
4212	skb = ath11k_wmi_alloc_skb(wmi->wmi_ab, len);
4213	if (!skb)
4214		return -ENOMEM;
4215
4216	cmd = (struct wmi_init_cmd *)skb->data;
4217
4218	cmd->tlv_header = FIELD_PREP(WMI_TLV_TAG, WMI_TAG_INIT_CMD) |
4219			  FIELD_PREP(WMI_TLV_LEN, sizeof(*cmd) - TLV_HDR_SIZE);
4220
4221	ptr = skb->data + sizeof(*cmd);
4222	cfg = ptr;
4223
4224	ath11k_wmi_copy_resource_config(cfg, param->res_cfg);
4225
4226	cfg->tlv_header = FIELD_PREP(WMI_TLV_TAG, WMI_TAG_RESOURCE_CONFIG) |
4227			  FIELD_PREP(WMI_TLV_LEN, sizeof(*cfg) - TLV_HDR_SIZE);
4228
4229	ptr += sizeof(*cfg);
4230	host_mem_chunks = ptr + TLV_HDR_SIZE;
4231	len = sizeof(struct wlan_host_mem_chunk);
4232
4233	for (idx = 0; idx < param->num_mem_chunks; ++idx) {
4234		host_mem_chunks[idx].tlv_header =
4235				FIELD_PREP(WMI_TLV_TAG,
4236					   WMI_TAG_WLAN_HOST_MEMORY_CHUNK) |
4237				FIELD_PREP(WMI_TLV_LEN, len);
4238
4239		host_mem_chunks[idx].ptr = param->mem_chunks[idx].paddr;
4240		host_mem_chunks[idx].size = param->mem_chunks[idx].len;
4241		host_mem_chunks[idx].req_id = param->mem_chunks[idx].req_id;
4242
4243		ath11k_dbg(ab, ATH11K_DBG_WMI,
4244			   "host mem chunk req_id %d paddr 0x%llx len %d\n",
4245			   param->mem_chunks[idx].req_id,
4246			   (u64)param->mem_chunks[idx].paddr,
4247			   param->mem_chunks[idx].len);
4248	}
4249	cmd->num_host_mem_chunks = param->num_mem_chunks;
4250	len = sizeof(struct wlan_host_mem_chunk) * param->num_mem_chunks;
4251
4252	/* num_mem_chunks is zero */
4253	tlv = ptr;
4254	tlv->header = FIELD_PREP(WMI_TLV_TAG, WMI_TAG_ARRAY_STRUCT) |
4255		      FIELD_PREP(WMI_TLV_LEN, len);
4256	ptr += TLV_HDR_SIZE + len;
4257
4258	if (param->hw_mode_id != WMI_HOST_HW_MODE_MAX) {
4259		hw_mode = ptr;
4260		hw_mode->tlv_header = FIELD_PREP(WMI_TLV_TAG,
4261						 WMI_TAG_PDEV_SET_HW_MODE_CMD) |
4262				      FIELD_PREP(WMI_TLV_LEN,
4263						 sizeof(*hw_mode) - TLV_HDR_SIZE);
4264
4265		hw_mode->hw_mode_index = param->hw_mode_id;
4266		hw_mode->num_band_to_mac = param->num_band_to_mac;
4267
4268		ptr += sizeof(*hw_mode);
4269
4270		len = param->num_band_to_mac * sizeof(*band_to_mac);
4271		tlv = ptr;
4272		tlv->header = FIELD_PREP(WMI_TLV_TAG, WMI_TAG_ARRAY_STRUCT) |
4273			      FIELD_PREP(WMI_TLV_LEN, len);
4274
4275		ptr += TLV_HDR_SIZE;
4276		len = sizeof(*band_to_mac);
4277
4278		for (idx = 0; idx < param->num_band_to_mac; idx++) {
4279			band_to_mac = ptr;
4280
4281			band_to_mac->tlv_header = FIELD_PREP(WMI_TLV_TAG,
4282							     WMI_TAG_PDEV_BAND_TO_MAC) |
4283						  FIELD_PREP(WMI_TLV_LEN,
4284							     len - TLV_HDR_SIZE);
4285			band_to_mac->pdev_id = param->band_to_mac[idx].pdev_id;
4286			band_to_mac->start_freq =
4287				param->band_to_mac[idx].start_freq;
4288			band_to_mac->end_freq =
4289				param->band_to_mac[idx].end_freq;
4290			ptr += sizeof(*band_to_mac);
4291		}
4292	}
4293
4294	ret = ath11k_wmi_cmd_send(wmi, skb, WMI_INIT_CMDID);
4295	if (ret) {
4296		ath11k_warn(ab, "failed to send WMI_INIT_CMDID\n");
4297		dev_kfree_skb(skb);
4298		return ret;
4299	}
4300
4301	ath11k_dbg(ab, ATH11K_DBG_WMI, "cmd wmi init");
4302
4303	return 0;
4304}
4305
4306int ath11k_wmi_pdev_lro_cfg(struct ath11k *ar,
4307			    int pdev_id)
4308{
4309	struct ath11k_wmi_pdev_lro_config_cmd *cmd;
4310	struct sk_buff *skb;
4311	int ret;
4312
4313	skb = ath11k_wmi_alloc_skb(ar->wmi->wmi_ab, sizeof(*cmd));
4314	if (!skb)
4315		return -ENOMEM;
4316
4317	cmd = (struct ath11k_wmi_pdev_lro_config_cmd *)skb->data;
4318	cmd->tlv_header = FIELD_PREP(WMI_TLV_TAG, WMI_TAG_LRO_INFO_CMD) |
4319			  FIELD_PREP(WMI_TLV_LEN, sizeof(*cmd) - TLV_HDR_SIZE);
4320
4321	get_random_bytes(cmd->th_4, sizeof(uint32_t) * ATH11K_IPV4_TH_SEED_SIZE);
4322	get_random_bytes(cmd->th_6, sizeof(uint32_t) * ATH11K_IPV6_TH_SEED_SIZE);
4323
4324	cmd->pdev_id = pdev_id;
4325
4326	ret = ath11k_wmi_cmd_send(ar->wmi, skb, WMI_LRO_CONFIG_CMDID);
4327	if (ret) {
4328		ath11k_warn(ar->ab,
4329			    "failed to send lro cfg req wmi cmd\n");
4330		goto err;
4331	}
4332
4333	ath11k_dbg(ar->ab, ATH11K_DBG_WMI,
4334		   "cmd lro config pdev_id 0x%x\n", pdev_id);
4335	return 0;
4336err:
4337	dev_kfree_skb(skb);
4338	return ret;
4339}
4340
4341int ath11k_wmi_wait_for_service_ready(struct ath11k_base *ab)
4342{
4343	unsigned long time_left;
4344
4345	time_left = wait_for_completion_timeout(&ab->wmi_ab.service_ready,
4346						WMI_SERVICE_READY_TIMEOUT_HZ);
4347	if (!time_left)
4348		return -ETIMEDOUT;
4349
4350	return 0;
4351}
4352
4353int ath11k_wmi_wait_for_unified_ready(struct ath11k_base *ab)
4354{
4355	unsigned long time_left;
4356
4357	time_left = wait_for_completion_timeout(&ab->wmi_ab.unified_ready,
4358						WMI_SERVICE_READY_TIMEOUT_HZ);
4359	if (!time_left)
4360		return -ETIMEDOUT;
4361
4362	return 0;
4363}
4364
4365int ath11k_wmi_set_hw_mode(struct ath11k_base *ab,
4366			   enum wmi_host_hw_mode_config_type mode)
4367{
4368	struct wmi_pdev_set_hw_mode_cmd_param *cmd;
4369	struct sk_buff *skb;
4370	struct ath11k_wmi_base *wmi_ab = &ab->wmi_ab;
4371	int len;
4372	int ret;
4373
4374	len = sizeof(*cmd);
4375
4376	skb = ath11k_wmi_alloc_skb(wmi_ab, len);
4377	if (!skb)
4378		return -ENOMEM;
4379
4380	cmd = (struct wmi_pdev_set_hw_mode_cmd_param *)skb->data;
4381
4382	cmd->tlv_header = FIELD_PREP(WMI_TLV_TAG, WMI_TAG_PDEV_SET_HW_MODE_CMD) |
4383			  FIELD_PREP(WMI_TLV_LEN, sizeof(*cmd) - TLV_HDR_SIZE);
4384
4385	cmd->pdev_id = WMI_PDEV_ID_SOC;
4386	cmd->hw_mode_index = mode;
4387
4388	ret = ath11k_wmi_cmd_send(&wmi_ab->wmi[0], skb, WMI_PDEV_SET_HW_MODE_CMDID);
4389	if (ret) {
4390		ath11k_warn(ab, "failed to send WMI_PDEV_SET_HW_MODE_CMDID\n");
4391		dev_kfree_skb(skb);
4392		return ret;
4393	}
4394
4395	ath11k_dbg(ab, ATH11K_DBG_WMI, "cmd pdev set hw mode %d", cmd->hw_mode_index);
4396
4397	return 0;
4398}
4399
4400int ath11k_wmi_cmd_init(struct ath11k_base *ab)
4401{
4402	struct ath11k_wmi_base *wmi_ab = &ab->wmi_ab;
4403	struct wmi_init_cmd_param init_param;
4404	struct target_resource_config  config;
4405
4406	memset(&init_param, 0, sizeof(init_param));
4407	memset(&config, 0, sizeof(config));
4408
4409	ab->hw_params.hw_ops->wmi_init_config(ab, &config);
4410
4411	if (test_bit(WMI_TLV_SERVICE_REG_CC_EXT_EVENT_SUPPORT,
4412		     ab->wmi_ab.svc_map))
4413		config.is_reg_cc_ext_event_supported = 1;
4414
4415	memcpy(&wmi_ab->wlan_resource_config, &config, sizeof(config));
4416
4417	init_param.res_cfg = &wmi_ab->wlan_resource_config;
4418	init_param.num_mem_chunks = wmi_ab->num_mem_chunks;
4419	init_param.hw_mode_id = wmi_ab->preferred_hw_mode;
4420	init_param.mem_chunks = wmi_ab->mem_chunks;
4421
4422	if (ab->hw_params.single_pdev_only)
4423		init_param.hw_mode_id = WMI_HOST_HW_MODE_MAX;
4424
4425	init_param.num_band_to_mac = ab->num_radios;
4426	ath11k_fill_band_to_mac_param(ab, init_param.band_to_mac);
4427
4428	return ath11k_init_cmd_send(&wmi_ab->wmi[0], &init_param);
4429}
4430
4431int ath11k_wmi_vdev_spectral_conf(struct ath11k *ar,
4432				  struct ath11k_wmi_vdev_spectral_conf_param *param)
4433{
4434	struct ath11k_wmi_vdev_spectral_conf_cmd *cmd;
4435	struct sk_buff *skb;
4436	int ret;
4437
4438	skb = ath11k_wmi_alloc_skb(ar->wmi->wmi_ab, sizeof(*cmd));
4439	if (!skb)
4440		return -ENOMEM;
4441
4442	cmd = (struct ath11k_wmi_vdev_spectral_conf_cmd *)skb->data;
4443	cmd->tlv_header = FIELD_PREP(WMI_TLV_TAG,
4444				     WMI_TAG_VDEV_SPECTRAL_CONFIGURE_CMD) |
4445			  FIELD_PREP(WMI_TLV_LEN, sizeof(*cmd) - TLV_HDR_SIZE);
4446
4447	memcpy(&cmd->param, param, sizeof(*param));
4448
4449	ret = ath11k_wmi_cmd_send(ar->wmi, skb,
4450				  WMI_VDEV_SPECTRAL_SCAN_CONFIGURE_CMDID);
4451	if (ret) {
4452		ath11k_warn(ar->ab,
4453			    "failed to send spectral scan config wmi cmd\n");
4454		goto err;
4455	}
4456
4457	ath11k_dbg(ar->ab, ATH11K_DBG_WMI,
4458		   "cmd vdev spectral scan configure vdev_id 0x%x\n",
4459		   param->vdev_id);
4460
4461	return 0;
4462err:
4463	dev_kfree_skb(skb);
4464	return ret;
4465}
4466
4467int ath11k_wmi_vdev_spectral_enable(struct ath11k *ar, u32 vdev_id,
4468				    u32 trigger, u32 enable)
4469{
4470	struct ath11k_wmi_vdev_spectral_enable_cmd *cmd;
4471	struct sk_buff *skb;
4472	int ret;
4473
4474	skb = ath11k_wmi_alloc_skb(ar->wmi->wmi_ab, sizeof(*cmd));
4475	if (!skb)
4476		return -ENOMEM;
4477
4478	cmd = (struct ath11k_wmi_vdev_spectral_enable_cmd *)skb->data;
4479	cmd->tlv_header = FIELD_PREP(WMI_TLV_TAG,
4480				     WMI_TAG_VDEV_SPECTRAL_ENABLE_CMD) |
4481			  FIELD_PREP(WMI_TLV_LEN, sizeof(*cmd) - TLV_HDR_SIZE);
4482
4483	cmd->vdev_id = vdev_id;
4484	cmd->trigger_cmd = trigger;
4485	cmd->enable_cmd = enable;
4486
4487	ret = ath11k_wmi_cmd_send(ar->wmi, skb,
4488				  WMI_VDEV_SPECTRAL_SCAN_ENABLE_CMDID);
4489	if (ret) {
4490		ath11k_warn(ar->ab,
4491			    "failed to send spectral enable wmi cmd\n");
4492		goto err;
4493	}
4494
4495	ath11k_dbg(ar->ab, ATH11K_DBG_WMI,
4496		   "cmd vdev spectral scan enable vdev id 0x%x\n",
4497		   vdev_id);
4498
4499	return 0;
4500err:
4501	dev_kfree_skb(skb);
4502	return ret;
4503}
4504
4505int ath11k_wmi_pdev_dma_ring_cfg(struct ath11k *ar,
4506				 struct ath11k_wmi_pdev_dma_ring_cfg_req_cmd *param)
4507{
4508	struct ath11k_wmi_pdev_dma_ring_cfg_req_cmd *cmd;
4509	struct sk_buff *skb;
4510	int ret;
4511
4512	skb = ath11k_wmi_alloc_skb(ar->wmi->wmi_ab, sizeof(*cmd));
4513	if (!skb)
4514		return -ENOMEM;
4515
4516	cmd = (struct ath11k_wmi_pdev_dma_ring_cfg_req_cmd *)skb->data;
4517	cmd->tlv_header = FIELD_PREP(WMI_TLV_TAG, WMI_TAG_DMA_RING_CFG_REQ) |
4518			  FIELD_PREP(WMI_TLV_LEN, sizeof(*cmd) - TLV_HDR_SIZE);
4519
4520	cmd->pdev_id		= param->pdev_id;
4521	cmd->module_id		= param->module_id;
4522	cmd->base_paddr_lo	= param->base_paddr_lo;
4523	cmd->base_paddr_hi	= param->base_paddr_hi;
4524	cmd->head_idx_paddr_lo	= param->head_idx_paddr_lo;
4525	cmd->head_idx_paddr_hi	= param->head_idx_paddr_hi;
4526	cmd->tail_idx_paddr_lo	= param->tail_idx_paddr_lo;
4527	cmd->tail_idx_paddr_hi	= param->tail_idx_paddr_hi;
4528	cmd->num_elems		= param->num_elems;
4529	cmd->buf_size		= param->buf_size;
4530	cmd->num_resp_per_event	= param->num_resp_per_event;
4531	cmd->event_timeout_ms	= param->event_timeout_ms;
4532
4533	ret = ath11k_wmi_cmd_send(ar->wmi, skb,
4534				  WMI_PDEV_DMA_RING_CFG_REQ_CMDID);
4535	if (ret) {
4536		ath11k_warn(ar->ab,
4537			    "failed to send dma ring cfg req wmi cmd\n");
4538		goto err;
4539	}
4540
4541	ath11k_dbg(ar->ab, ATH11K_DBG_WMI,
4542		   "cmd pdev dma ring cfg req pdev_id 0x%x\n",
4543		   param->pdev_id);
4544
4545	return 0;
4546err:
4547	dev_kfree_skb(skb);
4548	return ret;
4549}
4550
4551static int ath11k_wmi_tlv_dma_buf_entry_parse(struct ath11k_base *soc,
4552					      u16 tag, u16 len,
4553					      const void *ptr, void *data)
4554{
4555	struct wmi_tlv_dma_buf_release_parse *parse = data;
4556
4557	if (tag != WMI_TAG_DMA_BUF_RELEASE_ENTRY)
4558		return -EPROTO;
4559
4560	if (parse->num_buf_entry >= parse->fixed.num_buf_release_entry)
4561		return -ENOBUFS;
4562
4563	parse->num_buf_entry++;
4564	return 0;
4565}
4566
4567static int ath11k_wmi_tlv_dma_buf_meta_parse(struct ath11k_base *soc,
4568					     u16 tag, u16 len,
4569					     const void *ptr, void *data)
4570{
4571	struct wmi_tlv_dma_buf_release_parse *parse = data;
4572
4573	if (tag != WMI_TAG_DMA_BUF_RELEASE_SPECTRAL_META_DATA)
4574		return -EPROTO;
4575
4576	if (parse->num_meta >= parse->fixed.num_meta_data_entry)
4577		return -ENOBUFS;
4578
4579	parse->num_meta++;
4580	return 0;
4581}
4582
4583static int ath11k_wmi_tlv_dma_buf_parse(struct ath11k_base *ab,
4584					u16 tag, u16 len,
4585					const void *ptr, void *data)
4586{
4587	struct wmi_tlv_dma_buf_release_parse *parse = data;
4588	int ret;
4589
4590	switch (tag) {
4591	case WMI_TAG_DMA_BUF_RELEASE:
4592		memcpy(&parse->fixed, ptr,
4593		       sizeof(struct ath11k_wmi_dma_buf_release_fixed_param));
4594		parse->fixed.pdev_id = DP_HW2SW_MACID(parse->fixed.pdev_id);
4595		break;
4596	case WMI_TAG_ARRAY_STRUCT:
4597		if (!parse->buf_entry_done) {
4598			parse->num_buf_entry = 0;
4599			parse->buf_entry = (struct wmi_dma_buf_release_entry *)ptr;
4600
4601			ret = ath11k_wmi_tlv_iter(ab, ptr, len,
4602						  ath11k_wmi_tlv_dma_buf_entry_parse,
4603						  parse);
4604			if (ret) {
4605				ath11k_warn(ab, "failed to parse dma buf entry tlv %d\n",
4606					    ret);
4607				return ret;
4608			}
4609
4610			parse->buf_entry_done = true;
4611		} else if (!parse->meta_data_done) {
4612			parse->num_meta = 0;
4613			parse->meta_data = (struct wmi_dma_buf_release_meta_data *)ptr;
4614
4615			ret = ath11k_wmi_tlv_iter(ab, ptr, len,
4616						  ath11k_wmi_tlv_dma_buf_meta_parse,
4617						  parse);
4618			if (ret) {
4619				ath11k_warn(ab, "failed to parse dma buf meta tlv %d\n",
4620					    ret);
4621				return ret;
4622			}
4623
4624			parse->meta_data_done = true;
4625		}
4626		break;
4627	default:
4628		break;
4629	}
4630	return 0;
4631}
4632
4633static void ath11k_wmi_pdev_dma_ring_buf_release_event(struct ath11k_base *ab,
4634						       struct sk_buff *skb)
4635{
4636	struct wmi_tlv_dma_buf_release_parse parse = { };
4637	struct ath11k_dbring_buf_release_event param;
4638	int ret;
4639
4640	ret = ath11k_wmi_tlv_iter(ab, skb->data, skb->len,
4641				  ath11k_wmi_tlv_dma_buf_parse,
4642				  &parse);
4643	if (ret) {
4644		ath11k_warn(ab, "failed to parse dma buf release tlv %d\n", ret);
4645		return;
4646	}
4647
4648	ath11k_dbg(ab, ATH11K_DBG_WMI, "event pdev dma ring buf release");
4649
4650	param.fixed		= parse.fixed;
4651	param.buf_entry		= parse.buf_entry;
4652	param.num_buf_entry	= parse.num_buf_entry;
4653	param.meta_data		= parse.meta_data;
4654	param.num_meta		= parse.num_meta;
4655
4656	ret = ath11k_dbring_buffer_release_event(ab, &param);
4657	if (ret) {
4658		ath11k_warn(ab, "failed to handle dma buf release event %d\n", ret);
4659		return;
4660	}
4661}
4662
4663static int ath11k_wmi_tlv_hw_mode_caps_parse(struct ath11k_base *soc,
4664					     u16 tag, u16 len,
4665					     const void *ptr, void *data)
4666{
4667	struct wmi_tlv_svc_rdy_ext_parse *svc_rdy_ext = data;
4668	struct wmi_hw_mode_capabilities *hw_mode_cap;
4669	u32 phy_map = 0;
4670
4671	if (tag != WMI_TAG_HW_MODE_CAPABILITIES)
4672		return -EPROTO;
4673
4674	if (svc_rdy_ext->n_hw_mode_caps >= svc_rdy_ext->param.num_hw_modes)
4675		return -ENOBUFS;
4676
4677	hw_mode_cap = container_of(ptr, struct wmi_hw_mode_capabilities,
4678				   hw_mode_id);
4679	svc_rdy_ext->n_hw_mode_caps++;
4680
4681	phy_map = hw_mode_cap->phy_id_map;
4682	while (phy_map) {
4683		svc_rdy_ext->tot_phy_id++;
4684		phy_map = phy_map >> 1;
4685	}
4686
4687	return 0;
4688}
4689
4690static int ath11k_wmi_tlv_hw_mode_caps(struct ath11k_base *soc,
4691				       u16 len, const void *ptr, void *data)
4692{
4693	struct wmi_tlv_svc_rdy_ext_parse *svc_rdy_ext = data;
4694	struct wmi_hw_mode_capabilities *hw_mode_caps;
4695	enum wmi_host_hw_mode_config_type mode, pref;
4696	u32 i;
4697	int ret;
4698
4699	svc_rdy_ext->n_hw_mode_caps = 0;
4700	svc_rdy_ext->hw_mode_caps = (struct wmi_hw_mode_capabilities *)ptr;
4701
4702	ret = ath11k_wmi_tlv_iter(soc, ptr, len,
4703				  ath11k_wmi_tlv_hw_mode_caps_parse,
4704				  svc_rdy_ext);
4705	if (ret) {
4706		ath11k_warn(soc, "failed to parse tlv %d\n", ret);
4707		return ret;
4708	}
4709
4710	i = 0;
4711	while (i < svc_rdy_ext->n_hw_mode_caps) {
4712		hw_mode_caps = &svc_rdy_ext->hw_mode_caps[i];
4713		mode = hw_mode_caps->hw_mode_id;
4714		pref = soc->wmi_ab.preferred_hw_mode;
4715
4716		if (ath11k_hw_mode_pri_map[mode] < ath11k_hw_mode_pri_map[pref]) {
4717			svc_rdy_ext->pref_hw_mode_caps = *hw_mode_caps;
4718			soc->wmi_ab.preferred_hw_mode = mode;
4719		}
4720		i++;
4721	}
4722
4723	ath11k_dbg(soc, ATH11K_DBG_WMI, "preferred_hw_mode:%d\n",
4724		   soc->wmi_ab.preferred_hw_mode);
4725	if (soc->wmi_ab.preferred_hw_mode == WMI_HOST_HW_MODE_MAX)
4726		return -EINVAL;
4727
4728	return 0;
4729}
4730
4731static int ath11k_wmi_tlv_mac_phy_caps_parse(struct ath11k_base *soc,
4732					     u16 tag, u16 len,
4733					     const void *ptr, void *data)
4734{
4735	struct wmi_tlv_svc_rdy_ext_parse *svc_rdy_ext = data;
4736
4737	if (tag != WMI_TAG_MAC_PHY_CAPABILITIES)
4738		return -EPROTO;
4739
4740	if (svc_rdy_ext->n_mac_phy_caps >= svc_rdy_ext->tot_phy_id)
4741		return -ENOBUFS;
4742
4743	len = min_t(u16, len, sizeof(struct wmi_mac_phy_capabilities));
4744	if (!svc_rdy_ext->n_mac_phy_caps) {
4745		svc_rdy_ext->mac_phy_caps = kcalloc(svc_rdy_ext->tot_phy_id,
4746						    len, GFP_ATOMIC);
4747		if (!svc_rdy_ext->mac_phy_caps)
4748			return -ENOMEM;
4749	}
4750
4751	memcpy(svc_rdy_ext->mac_phy_caps + svc_rdy_ext->n_mac_phy_caps, ptr, len);
4752	svc_rdy_ext->n_mac_phy_caps++;
4753	return 0;
4754}
4755
4756static int ath11k_wmi_tlv_ext_hal_reg_caps_parse(struct ath11k_base *soc,
4757						 u16 tag, u16 len,
4758						 const void *ptr, void *data)
4759{
4760	struct wmi_tlv_svc_rdy_ext_parse *svc_rdy_ext = data;
4761
4762	if (tag != WMI_TAG_HAL_REG_CAPABILITIES_EXT)
4763		return -EPROTO;
4764
4765	if (svc_rdy_ext->n_ext_hal_reg_caps >= svc_rdy_ext->param.num_phy)
4766		return -ENOBUFS;
4767
4768	svc_rdy_ext->n_ext_hal_reg_caps++;
4769	return 0;
4770}
4771
4772static int ath11k_wmi_tlv_ext_hal_reg_caps(struct ath11k_base *soc,
4773					   u16 len, const void *ptr, void *data)
4774{
4775	struct ath11k_pdev_wmi *wmi_handle = &soc->wmi_ab.wmi[0];
4776	struct wmi_tlv_svc_rdy_ext_parse *svc_rdy_ext = data;
4777	struct ath11k_hal_reg_capabilities_ext reg_cap;
4778	int ret;
4779	u32 i;
4780
4781	svc_rdy_ext->n_ext_hal_reg_caps = 0;
4782	svc_rdy_ext->ext_hal_reg_caps = (struct wmi_hal_reg_capabilities_ext *)ptr;
4783	ret = ath11k_wmi_tlv_iter(soc, ptr, len,
4784				  ath11k_wmi_tlv_ext_hal_reg_caps_parse,
4785				  svc_rdy_ext);
4786	if (ret) {
4787		ath11k_warn(soc, "failed to parse tlv %d\n", ret);
4788		return ret;
4789	}
4790
4791	for (i = 0; i < svc_rdy_ext->param.num_phy; i++) {
4792		ret = ath11k_pull_reg_cap_svc_rdy_ext(wmi_handle,
4793						      svc_rdy_ext->soc_hal_reg_caps,
4794						      svc_rdy_ext->ext_hal_reg_caps, i,
4795						      &reg_cap);
4796		if (ret) {
4797			ath11k_warn(soc, "failed to extract reg cap %d\n", i);
4798			return ret;
4799		}
4800
4801		memcpy(&soc->hal_reg_cap[reg_cap.phy_id],
4802		       &reg_cap, sizeof(reg_cap));
4803	}
4804	return 0;
4805}
4806
4807static int ath11k_wmi_tlv_ext_soc_hal_reg_caps_parse(struct ath11k_base *soc,
4808						     u16 len, const void *ptr,
4809						     void *data)
4810{
4811	struct ath11k_pdev_wmi *wmi_handle = &soc->wmi_ab.wmi[0];
4812	struct wmi_tlv_svc_rdy_ext_parse *svc_rdy_ext = data;
4813	u8 hw_mode_id = svc_rdy_ext->pref_hw_mode_caps.hw_mode_id;
4814	u32 phy_id_map;
4815	int pdev_index = 0;
4816	int ret;
4817
4818	svc_rdy_ext->soc_hal_reg_caps = (struct wmi_soc_hal_reg_capabilities *)ptr;
4819	svc_rdy_ext->param.num_phy = svc_rdy_ext->soc_hal_reg_caps->num_phy;
4820
4821	soc->num_radios = 0;
4822	soc->target_pdev_count = 0;
4823	phy_id_map = svc_rdy_ext->pref_hw_mode_caps.phy_id_map;
4824
4825	while (phy_id_map && soc->num_radios < MAX_RADIOS) {
4826		ret = ath11k_pull_mac_phy_cap_svc_ready_ext(wmi_handle,
4827							    svc_rdy_ext->hw_caps,
4828							    svc_rdy_ext->hw_mode_caps,
4829							    svc_rdy_ext->soc_hal_reg_caps,
4830							    svc_rdy_ext->mac_phy_caps,
4831							    hw_mode_id, soc->num_radios,
4832							    &soc->pdevs[pdev_index]);
4833		if (ret) {
4834			ath11k_warn(soc, "failed to extract mac caps, idx :%d\n",
4835				    soc->num_radios);
4836			return ret;
4837		}
4838
4839		soc->num_radios++;
4840
4841		/* For QCA6390, save mac_phy capability in the same pdev */
4842		if (soc->hw_params.single_pdev_only)
4843			pdev_index = 0;
4844		else
4845			pdev_index = soc->num_radios;
4846
4847		/* TODO: mac_phy_cap prints */
4848		phy_id_map >>= 1;
4849	}
4850
4851	/* For QCA6390, set num_radios to 1 because host manages
4852	 * both 2G and 5G radio in one pdev.
4853	 * Set pdev_id = 0 and 0 means soc level.
4854	 */
4855	if (soc->hw_params.single_pdev_only) {
4856		soc->num_radios = 1;
4857		soc->pdevs[0].pdev_id = 0;
4858	}
4859
4860	if (!soc->reg_info_store) {
4861		soc->reg_info_store = kcalloc(soc->num_radios,
4862					      sizeof(*soc->reg_info_store),
4863					      GFP_ATOMIC);
4864		if (!soc->reg_info_store)
4865			return -ENOMEM;
4866	}
4867
4868	return 0;
4869}
4870
4871static int ath11k_wmi_tlv_dma_ring_caps_parse(struct ath11k_base *soc,
4872					      u16 tag, u16 len,
4873					      const void *ptr, void *data)
4874{
4875	struct wmi_tlv_dma_ring_caps_parse *parse = data;
4876
4877	if (tag != WMI_TAG_DMA_RING_CAPABILITIES)
4878		return -EPROTO;
4879
4880	parse->n_dma_ring_caps++;
4881	return 0;
4882}
4883
4884static int ath11k_wmi_alloc_dbring_caps(struct ath11k_base *ab,
4885					u32 num_cap)
4886{
4887	size_t sz;
4888	void *ptr;
4889
4890	sz = num_cap * sizeof(struct ath11k_dbring_cap);
4891	ptr = kzalloc(sz, GFP_ATOMIC);
4892	if (!ptr)
4893		return -ENOMEM;
4894
4895	ab->db_caps = ptr;
4896	ab->num_db_cap = num_cap;
4897
4898	return 0;
4899}
4900
4901static void ath11k_wmi_free_dbring_caps(struct ath11k_base *ab)
4902{
4903	kfree(ab->db_caps);
4904	ab->db_caps = NULL;
4905	ab->num_db_cap = 0;
4906}
4907
4908static int ath11k_wmi_tlv_dma_ring_caps(struct ath11k_base *ab,
4909					u16 len, const void *ptr, void *data)
4910{
4911	struct wmi_tlv_dma_ring_caps_parse *dma_caps_parse = data;
4912	struct wmi_dma_ring_capabilities *dma_caps;
4913	struct ath11k_dbring_cap *dir_buff_caps;
4914	int ret;
4915	u32 i;
4916
4917	dma_caps_parse->n_dma_ring_caps = 0;
4918	dma_caps = (struct wmi_dma_ring_capabilities *)ptr;
4919	ret = ath11k_wmi_tlv_iter(ab, ptr, len,
4920				  ath11k_wmi_tlv_dma_ring_caps_parse,
4921				  dma_caps_parse);
4922	if (ret) {
4923		ath11k_warn(ab, "failed to parse dma ring caps tlv %d\n", ret);
4924		return ret;
4925	}
4926
4927	if (!dma_caps_parse->n_dma_ring_caps)
4928		return 0;
4929
4930	if (ab->num_db_cap) {
4931		ath11k_warn(ab, "Already processed, so ignoring dma ring caps\n");
4932		return 0;
4933	}
4934
4935	ret = ath11k_wmi_alloc_dbring_caps(ab, dma_caps_parse->n_dma_ring_caps);
4936	if (ret)
4937		return ret;
4938
4939	dir_buff_caps = ab->db_caps;
4940	for (i = 0; i < dma_caps_parse->n_dma_ring_caps; i++) {
4941		if (dma_caps[i].module_id >= WMI_DIRECT_BUF_MAX) {
4942			ath11k_warn(ab, "Invalid module id %d\n", dma_caps[i].module_id);
4943			ret = -EINVAL;
4944			goto free_dir_buff;
4945		}
4946
4947		dir_buff_caps[i].id = dma_caps[i].module_id;
4948		dir_buff_caps[i].pdev_id = DP_HW2SW_MACID(dma_caps[i].pdev_id);
4949		dir_buff_caps[i].min_elem = dma_caps[i].min_elem;
4950		dir_buff_caps[i].min_buf_sz = dma_caps[i].min_buf_sz;
4951		dir_buff_caps[i].min_buf_align = dma_caps[i].min_buf_align;
4952	}
4953
4954	return 0;
4955
4956free_dir_buff:
4957	ath11k_wmi_free_dbring_caps(ab);
4958	return ret;
4959}
4960
4961static int ath11k_wmi_tlv_svc_rdy_ext_parse(struct ath11k_base *ab,
4962					    u16 tag, u16 len,
4963					    const void *ptr, void *data)
4964{
4965	struct ath11k_pdev_wmi *wmi_handle = &ab->wmi_ab.wmi[0];
4966	struct wmi_tlv_svc_rdy_ext_parse *svc_rdy_ext = data;
4967	int ret;
4968
4969	switch (tag) {
4970	case WMI_TAG_SERVICE_READY_EXT_EVENT:
4971		ret = ath11k_pull_svc_ready_ext(wmi_handle, ptr,
4972						&svc_rdy_ext->param);
4973		if (ret) {
4974			ath11k_warn(ab, "unable to extract ext params\n");
4975			return ret;
4976		}
4977		break;
4978
4979	case WMI_TAG_SOC_MAC_PHY_HW_MODE_CAPS:
4980		svc_rdy_ext->hw_caps = (struct wmi_soc_mac_phy_hw_mode_caps *)ptr;
4981		svc_rdy_ext->param.num_hw_modes = svc_rdy_ext->hw_caps->num_hw_modes;
4982		break;
4983
4984	case WMI_TAG_SOC_HAL_REG_CAPABILITIES:
4985		ret = ath11k_wmi_tlv_ext_soc_hal_reg_caps_parse(ab, len, ptr,
4986								svc_rdy_ext);
4987		if (ret)
4988			return ret;
4989		break;
4990
4991	case WMI_TAG_ARRAY_STRUCT:
4992		if (!svc_rdy_ext->hw_mode_done) {
4993			ret = ath11k_wmi_tlv_hw_mode_caps(ab, len, ptr,
4994							  svc_rdy_ext);
4995			if (ret)
4996				return ret;
4997
4998			svc_rdy_ext->hw_mode_done = true;
4999		} else if (!svc_rdy_ext->mac_phy_done) {
5000			svc_rdy_ext->n_mac_phy_caps = 0;
5001			ret = ath11k_wmi_tlv_iter(ab, ptr, len,
5002						  ath11k_wmi_tlv_mac_phy_caps_parse,
5003						  svc_rdy_ext);
5004			if (ret) {
5005				ath11k_warn(ab, "failed to parse tlv %d\n", ret);
5006				return ret;
5007			}
5008
5009			svc_rdy_ext->mac_phy_done = true;
5010		} else if (!svc_rdy_ext->ext_hal_reg_done) {
5011			ret = ath11k_wmi_tlv_ext_hal_reg_caps(ab, len, ptr,
5012							      svc_rdy_ext);
5013			if (ret)
5014				return ret;
5015
5016			svc_rdy_ext->ext_hal_reg_done = true;
5017		} else if (!svc_rdy_ext->mac_phy_chainmask_combo_done) {
5018			svc_rdy_ext->mac_phy_chainmask_combo_done = true;
5019		} else if (!svc_rdy_ext->mac_phy_chainmask_cap_done) {
5020			svc_rdy_ext->mac_phy_chainmask_cap_done = true;
5021		} else if (!svc_rdy_ext->oem_dma_ring_cap_done) {
5022			svc_rdy_ext->oem_dma_ring_cap_done = true;
5023		} else if (!svc_rdy_ext->dma_ring_cap_done) {
5024			ret = ath11k_wmi_tlv_dma_ring_caps(ab, len, ptr,
5025							   &svc_rdy_ext->dma_caps_parse);
5026			if (ret)
5027				return ret;
5028
5029			svc_rdy_ext->dma_ring_cap_done = true;
5030		}
5031		break;
5032
5033	default:
5034		break;
5035	}
5036	return 0;
5037}
5038
5039static int ath11k_service_ready_ext_event(struct ath11k_base *ab,
5040					  struct sk_buff *skb)
5041{
5042	struct wmi_tlv_svc_rdy_ext_parse svc_rdy_ext = { };
5043	int ret;
5044
5045	ret = ath11k_wmi_tlv_iter(ab, skb->data, skb->len,
5046				  ath11k_wmi_tlv_svc_rdy_ext_parse,
5047				  &svc_rdy_ext);
5048	if (ret) {
5049		ath11k_warn(ab, "failed to parse tlv %d\n", ret);
5050		goto err;
5051	}
5052
5053	ath11k_dbg(ab, ATH11K_DBG_WMI, "event service ready ext");
5054
5055	if (!test_bit(WMI_TLV_SERVICE_EXT2_MSG, ab->wmi_ab.svc_map))
5056		complete(&ab->wmi_ab.service_ready);
5057
5058	kfree(svc_rdy_ext.mac_phy_caps);
5059	return 0;
5060
5061err:
5062	ath11k_wmi_free_dbring_caps(ab);
5063	return ret;
5064}
5065
5066static int ath11k_wmi_tlv_svc_rdy_ext2_parse(struct ath11k_base *ab,
5067					     u16 tag, u16 len,
5068					     const void *ptr, void *data)
5069{
5070	struct wmi_tlv_svc_rdy_ext2_parse *parse = data;
5071	int ret;
5072
5073	switch (tag) {
5074	case WMI_TAG_ARRAY_STRUCT:
5075		if (!parse->dma_ring_cap_done) {
5076			ret = ath11k_wmi_tlv_dma_ring_caps(ab, len, ptr,
5077							   &parse->dma_caps_parse);
5078			if (ret)
5079				return ret;
5080
5081			parse->dma_ring_cap_done = true;
5082		}
5083		break;
5084	default:
5085		break;
5086	}
5087
5088	return 0;
5089}
5090
5091static int ath11k_service_ready_ext2_event(struct ath11k_base *ab,
5092					   struct sk_buff *skb)
5093{
5094	struct wmi_tlv_svc_rdy_ext2_parse svc_rdy_ext2 = { };
5095	int ret;
5096
5097	ret = ath11k_wmi_tlv_iter(ab, skb->data, skb->len,
5098				  ath11k_wmi_tlv_svc_rdy_ext2_parse,
5099				  &svc_rdy_ext2);
5100	if (ret) {
5101		ath11k_warn(ab, "failed to parse ext2 event tlv %d\n", ret);
5102		goto err;
5103	}
5104
5105	ath11k_dbg(ab, ATH11K_DBG_WMI, "event service ready ext2");
5106
5107	complete(&ab->wmi_ab.service_ready);
5108
5109	return 0;
5110
5111err:
5112	ath11k_wmi_free_dbring_caps(ab);
5113	return ret;
5114}
5115
5116static int ath11k_pull_vdev_start_resp_tlv(struct ath11k_base *ab, struct sk_buff *skb,
5117					   struct wmi_vdev_start_resp_event *vdev_rsp)
5118{
5119	const void **tb;
5120	const struct wmi_vdev_start_resp_event *ev;
5121	int ret;
5122
5123	tb = ath11k_wmi_tlv_parse_alloc(ab, skb, GFP_ATOMIC);
5124	if (IS_ERR(tb)) {
5125		ret = PTR_ERR(tb);
5126		ath11k_warn(ab, "failed to parse tlv: %d\n", ret);
5127		return ret;
5128	}
5129
5130	ev = tb[WMI_TAG_VDEV_START_RESPONSE_EVENT];
5131	if (!ev) {
5132		ath11k_warn(ab, "failed to fetch vdev start resp ev");
5133		kfree(tb);
5134		return -EPROTO;
5135	}
5136
5137	memset(vdev_rsp, 0, sizeof(*vdev_rsp));
5138
5139	vdev_rsp->vdev_id = ev->vdev_id;
5140	vdev_rsp->requestor_id = ev->requestor_id;
5141	vdev_rsp->resp_type = ev->resp_type;
5142	vdev_rsp->status = ev->status;
5143	vdev_rsp->chain_mask = ev->chain_mask;
5144	vdev_rsp->smps_mode = ev->smps_mode;
5145	vdev_rsp->mac_id = ev->mac_id;
5146	vdev_rsp->cfgd_tx_streams = ev->cfgd_tx_streams;
5147	vdev_rsp->cfgd_rx_streams = ev->cfgd_rx_streams;
5148	vdev_rsp->max_allowed_tx_power = ev->max_allowed_tx_power;
5149
5150	kfree(tb);
5151	return 0;
5152}
5153
5154static void ath11k_print_reg_rule(struct ath11k_base *ab, const char *band,
5155				  u32 num_reg_rules,
5156				  struct cur_reg_rule *reg_rule_ptr)
5157{
5158	struct cur_reg_rule *reg_rule = reg_rule_ptr;
5159	u32 count;
5160
5161	ath11k_dbg(ab, ATH11K_DBG_WMI, "number of reg rules in %s band: %d\n",
5162		   band, num_reg_rules);
5163
5164	for (count = 0; count < num_reg_rules; count++) {
5165		ath11k_dbg(ab, ATH11K_DBG_WMI,
5166			   "reg rule %d: (%d - %d @ %d) (%d, %d) (FLAGS %d)\n",
5167			   count + 1, reg_rule->start_freq, reg_rule->end_freq,
5168			   reg_rule->max_bw, reg_rule->ant_gain,
5169			   reg_rule->reg_power, reg_rule->flags);
5170		reg_rule++;
5171	}
5172}
5173
5174static struct cur_reg_rule
5175*create_reg_rules_from_wmi(u32 num_reg_rules,
5176			   struct wmi_regulatory_rule_struct *wmi_reg_rule)
5177{
5178	struct cur_reg_rule *reg_rule_ptr;
5179	u32 count;
5180
5181	reg_rule_ptr = kcalloc(num_reg_rules, sizeof(*reg_rule_ptr),
5182			       GFP_ATOMIC);
5183
5184	if (!reg_rule_ptr)
5185		return NULL;
5186
5187	for (count = 0; count < num_reg_rules; count++) {
5188		reg_rule_ptr[count].start_freq =
5189			FIELD_GET(REG_RULE_START_FREQ,
5190				  wmi_reg_rule[count].freq_info);
5191		reg_rule_ptr[count].end_freq =
5192			FIELD_GET(REG_RULE_END_FREQ,
5193				  wmi_reg_rule[count].freq_info);
5194		reg_rule_ptr[count].max_bw =
5195			FIELD_GET(REG_RULE_MAX_BW,
5196				  wmi_reg_rule[count].bw_pwr_info);
5197		reg_rule_ptr[count].reg_power =
5198			FIELD_GET(REG_RULE_REG_PWR,
5199				  wmi_reg_rule[count].bw_pwr_info);
5200		reg_rule_ptr[count].ant_gain =
5201			FIELD_GET(REG_RULE_ANT_GAIN,
5202				  wmi_reg_rule[count].bw_pwr_info);
5203		reg_rule_ptr[count].flags =
5204			FIELD_GET(REG_RULE_FLAGS,
5205				  wmi_reg_rule[count].flag_info);
5206	}
5207
5208	return reg_rule_ptr;
5209}
5210
5211static int ath11k_pull_reg_chan_list_update_ev(struct ath11k_base *ab,
5212					       struct sk_buff *skb,
5213					       struct cur_regulatory_info *reg_info)
5214{
5215	const void **tb;
5216	const struct wmi_reg_chan_list_cc_event *chan_list_event_hdr;
5217	struct wmi_regulatory_rule_struct *wmi_reg_rule;
5218	u32 num_2ghz_reg_rules, num_5ghz_reg_rules;
5219	int ret;
5220
5221	ath11k_dbg(ab, ATH11K_DBG_WMI, "processing regulatory channel list\n");
5222
5223	tb = ath11k_wmi_tlv_parse_alloc(ab, skb, GFP_ATOMIC);
5224	if (IS_ERR(tb)) {
5225		ret = PTR_ERR(tb);
5226		ath11k_warn(ab, "failed to parse tlv: %d\n", ret);
5227		return ret;
5228	}
5229
5230	chan_list_event_hdr = tb[WMI_TAG_REG_CHAN_LIST_CC_EVENT];
5231	if (!chan_list_event_hdr) {
5232		ath11k_warn(ab, "failed to fetch reg chan list update ev\n");
5233		kfree(tb);
5234		return -EPROTO;
5235	}
5236
5237	reg_info->num_2ghz_reg_rules = chan_list_event_hdr->num_2ghz_reg_rules;
5238	reg_info->num_5ghz_reg_rules = chan_list_event_hdr->num_5ghz_reg_rules;
5239
5240	if (!(reg_info->num_2ghz_reg_rules + reg_info->num_5ghz_reg_rules)) {
5241		ath11k_warn(ab, "No regulatory rules available in the event info\n");
5242		kfree(tb);
5243		return -EINVAL;
5244	}
5245
5246	memcpy(reg_info->alpha2, &chan_list_event_hdr->alpha2,
5247	       REG_ALPHA2_LEN);
5248	reg_info->dfs_region = chan_list_event_hdr->dfs_region;
5249	reg_info->phybitmap = chan_list_event_hdr->phybitmap;
5250	reg_info->num_phy = chan_list_event_hdr->num_phy;
5251	reg_info->phy_id = chan_list_event_hdr->phy_id;
5252	reg_info->ctry_code = chan_list_event_hdr->country_id;
5253	reg_info->reg_dmn_pair = chan_list_event_hdr->domain_code;
5254
5255	ath11k_dbg(ab, ATH11K_DBG_WMI,
5256		   "status_code %s",
5257		   ath11k_cc_status_to_str(reg_info->status_code));
5258
5259	reg_info->status_code =
5260		ath11k_wmi_cc_setting_code_to_reg(chan_list_event_hdr->status_code);
5261
5262	reg_info->is_ext_reg_event = false;
5263
5264	reg_info->min_bw_2ghz = chan_list_event_hdr->min_bw_2ghz;
5265	reg_info->max_bw_2ghz = chan_list_event_hdr->max_bw_2ghz;
5266	reg_info->min_bw_5ghz = chan_list_event_hdr->min_bw_5ghz;
5267	reg_info->max_bw_5ghz = chan_list_event_hdr->max_bw_5ghz;
5268
5269	num_2ghz_reg_rules = reg_info->num_2ghz_reg_rules;
5270	num_5ghz_reg_rules = reg_info->num_5ghz_reg_rules;
5271
5272	ath11k_dbg(ab, ATH11K_DBG_WMI,
5273		   "cc %s dsf %d BW: min_2ghz %d max_2ghz %d min_5ghz %d max_5ghz %d",
5274		   reg_info->alpha2, reg_info->dfs_region,
5275		   reg_info->min_bw_2ghz, reg_info->max_bw_2ghz,
5276		   reg_info->min_bw_5ghz, reg_info->max_bw_5ghz);
5277
5278	ath11k_dbg(ab, ATH11K_DBG_WMI,
5279		   "num_2ghz_reg_rules %d num_5ghz_reg_rules %d",
5280		   num_2ghz_reg_rules, num_5ghz_reg_rules);
5281
5282	wmi_reg_rule =
5283		(struct wmi_regulatory_rule_struct *)((u8 *)chan_list_event_hdr
5284						+ sizeof(*chan_list_event_hdr)
5285						+ sizeof(struct wmi_tlv));
5286
5287	if (num_2ghz_reg_rules) {
5288		reg_info->reg_rules_2ghz_ptr =
5289				create_reg_rules_from_wmi(num_2ghz_reg_rules,
5290							  wmi_reg_rule);
5291		if (!reg_info->reg_rules_2ghz_ptr) {
5292			kfree(tb);
5293			ath11k_warn(ab, "Unable to Allocate memory for 2 GHz rules\n");
5294			return -ENOMEM;
5295		}
5296
5297		ath11k_print_reg_rule(ab, "2 GHz",
5298				      num_2ghz_reg_rules,
5299				      reg_info->reg_rules_2ghz_ptr);
5300	}
5301
5302	if (num_5ghz_reg_rules) {
5303		wmi_reg_rule += num_2ghz_reg_rules;
5304		reg_info->reg_rules_5ghz_ptr =
5305				create_reg_rules_from_wmi(num_5ghz_reg_rules,
5306							  wmi_reg_rule);
5307		if (!reg_info->reg_rules_5ghz_ptr) {
5308			kfree(tb);
5309			ath11k_warn(ab, "Unable to Allocate memory for 5 GHz rules\n");
5310			return -ENOMEM;
5311		}
5312
5313		ath11k_print_reg_rule(ab, "5 GHz",
5314				      num_5ghz_reg_rules,
5315				      reg_info->reg_rules_5ghz_ptr);
5316	}
5317
5318	ath11k_dbg(ab, ATH11K_DBG_WMI, "processed regulatory channel list\n");
5319
5320	kfree(tb);
5321	return 0;
5322}
5323
5324static struct cur_reg_rule
5325*create_ext_reg_rules_from_wmi(u32 num_reg_rules,
5326			       struct wmi_regulatory_ext_rule *wmi_reg_rule)
5327{
5328	struct cur_reg_rule *reg_rule_ptr;
5329	u32 count;
5330
5331	reg_rule_ptr =  kcalloc(num_reg_rules, sizeof(*reg_rule_ptr), GFP_ATOMIC);
5332
5333	if (!reg_rule_ptr)
5334		return NULL;
5335
5336	for (count = 0; count < num_reg_rules; count++) {
5337		reg_rule_ptr[count].start_freq =
5338			u32_get_bits(wmi_reg_rule[count].freq_info,
5339				     REG_RULE_START_FREQ);
5340		reg_rule_ptr[count].end_freq =
5341			u32_get_bits(wmi_reg_rule[count].freq_info,
5342				     REG_RULE_END_FREQ);
5343		reg_rule_ptr[count].max_bw =
5344			u32_get_bits(wmi_reg_rule[count].bw_pwr_info,
5345				     REG_RULE_MAX_BW);
5346		reg_rule_ptr[count].reg_power =
5347			u32_get_bits(wmi_reg_rule[count].bw_pwr_info,
5348				     REG_RULE_REG_PWR);
5349		reg_rule_ptr[count].ant_gain =
5350			u32_get_bits(wmi_reg_rule[count].bw_pwr_info,
5351				     REG_RULE_ANT_GAIN);
5352		reg_rule_ptr[count].flags =
5353			u32_get_bits(wmi_reg_rule[count].flag_info,
5354				     REG_RULE_FLAGS);
5355		reg_rule_ptr[count].psd_flag =
5356			u32_get_bits(wmi_reg_rule[count].psd_power_info,
5357				     REG_RULE_PSD_INFO);
5358		reg_rule_ptr[count].psd_eirp =
5359			u32_get_bits(wmi_reg_rule[count].psd_power_info,
5360				     REG_RULE_PSD_EIRP);
5361	}
5362
5363	return reg_rule_ptr;
5364}
5365
5366static u8
5367ath11k_invalid_5ghz_reg_ext_rules_from_wmi(u32 num_reg_rules,
5368					   const struct wmi_regulatory_ext_rule *rule)
5369{
5370	u8 num_invalid_5ghz_rules = 0;
5371	u32 count, start_freq;
5372
5373	for (count = 0; count < num_reg_rules; count++) {
5374		start_freq = u32_get_bits(rule[count].freq_info,
5375					  REG_RULE_START_FREQ);
5376
5377		if (start_freq >= ATH11K_MIN_6G_FREQ)
5378			num_invalid_5ghz_rules++;
5379	}
5380
5381	return num_invalid_5ghz_rules;
5382}
5383
5384static int ath11k_pull_reg_chan_list_ext_update_ev(struct ath11k_base *ab,
5385						   struct sk_buff *skb,
5386						   struct cur_regulatory_info *reg_info)
5387{
5388	const void **tb;
5389	const struct wmi_reg_chan_list_cc_ext_event *ev;
5390	struct wmi_regulatory_ext_rule *ext_wmi_reg_rule;
5391	u32 num_2ghz_reg_rules, num_5ghz_reg_rules;
5392	u32 num_6ghz_reg_rules_ap[WMI_REG_CURRENT_MAX_AP_TYPE];
5393	u32 num_6ghz_client[WMI_REG_CURRENT_MAX_AP_TYPE][WMI_REG_MAX_CLIENT_TYPE];
5394	u32 total_reg_rules = 0;
5395	int ret, i, j, num_invalid_5ghz_ext_rules = 0;
5396
5397	ath11k_dbg(ab, ATH11K_DBG_WMI, "processing regulatory ext channel list\n");
5398
5399	tb = ath11k_wmi_tlv_parse_alloc(ab, skb, GFP_ATOMIC);
5400	if (IS_ERR(tb)) {
5401		ret = PTR_ERR(tb);
5402		ath11k_warn(ab, "failed to parse tlv: %d\n", ret);
5403		return ret;
5404	}
5405
5406	ev = tb[WMI_TAG_REG_CHAN_LIST_CC_EXT_EVENT];
5407	if (!ev) {
5408		ath11k_warn(ab, "failed to fetch reg chan list ext update ev\n");
5409		kfree(tb);
5410		return -EPROTO;
5411	}
5412
5413	reg_info->num_2ghz_reg_rules = ev->num_2ghz_reg_rules;
5414	reg_info->num_5ghz_reg_rules = ev->num_5ghz_reg_rules;
5415	reg_info->num_6ghz_rules_ap[WMI_REG_INDOOR_AP] =
5416			ev->num_6ghz_reg_rules_ap_lpi;
5417	reg_info->num_6ghz_rules_ap[WMI_REG_STANDARD_POWER_AP] =
5418			ev->num_6ghz_reg_rules_ap_sp;
5419	reg_info->num_6ghz_rules_ap[WMI_REG_VERY_LOW_POWER_AP] =
5420			ev->num_6ghz_reg_rules_ap_vlp;
5421
5422	for (i = 0; i < WMI_REG_MAX_CLIENT_TYPE; i++) {
5423		reg_info->num_6ghz_rules_client[WMI_REG_INDOOR_AP][i] =
5424			ev->num_6ghz_reg_rules_client_lpi[i];
5425		reg_info->num_6ghz_rules_client[WMI_REG_STANDARD_POWER_AP][i] =
5426			ev->num_6ghz_reg_rules_client_sp[i];
5427		reg_info->num_6ghz_rules_client[WMI_REG_VERY_LOW_POWER_AP][i] =
5428			ev->num_6ghz_reg_rules_client_vlp[i];
5429	}
5430
5431	num_2ghz_reg_rules = reg_info->num_2ghz_reg_rules;
5432	num_5ghz_reg_rules = reg_info->num_5ghz_reg_rules;
5433
5434	total_reg_rules += num_2ghz_reg_rules;
5435	total_reg_rules += num_5ghz_reg_rules;
5436
5437	if ((num_2ghz_reg_rules > MAX_REG_RULES) ||
5438	    (num_5ghz_reg_rules > MAX_REG_RULES)) {
5439		ath11k_warn(ab, "Num reg rules for 2.4 GHz/5 GHz exceeds max limit (num_2ghz_reg_rules: %d num_5ghz_reg_rules: %d max_rules: %d)\n",
5440			    num_2ghz_reg_rules, num_5ghz_reg_rules, MAX_REG_RULES);
5441		kfree(tb);
5442		return -EINVAL;
5443	}
5444
5445	for (i = 0; i < WMI_REG_CURRENT_MAX_AP_TYPE; i++) {
5446		num_6ghz_reg_rules_ap[i] = reg_info->num_6ghz_rules_ap[i];
5447
5448		if (num_6ghz_reg_rules_ap[i] > MAX_6GHZ_REG_RULES) {
5449			ath11k_warn(ab, "Num 6 GHz reg rules for AP mode(%d) exceeds max limit (num_6ghz_reg_rules_ap: %d, max_rules: %d)\n",
5450				    i, num_6ghz_reg_rules_ap[i], MAX_6GHZ_REG_RULES);
5451			kfree(tb);
5452			return -EINVAL;
5453		}
5454
5455		total_reg_rules += num_6ghz_reg_rules_ap[i];
5456	}
5457
5458	for (i = 0; i < WMI_REG_MAX_CLIENT_TYPE; i++) {
5459		num_6ghz_client[WMI_REG_INDOOR_AP][i] =
5460			reg_info->num_6ghz_rules_client[WMI_REG_INDOOR_AP][i];
5461		total_reg_rules += num_6ghz_client[WMI_REG_INDOOR_AP][i];
5462
5463		num_6ghz_client[WMI_REG_STANDARD_POWER_AP][i] =
5464			reg_info->num_6ghz_rules_client[WMI_REG_STANDARD_POWER_AP][i];
5465		total_reg_rules += num_6ghz_client[WMI_REG_STANDARD_POWER_AP][i];
5466
5467		num_6ghz_client[WMI_REG_VERY_LOW_POWER_AP][i] =
5468			reg_info->num_6ghz_rules_client[WMI_REG_VERY_LOW_POWER_AP][i];
5469		total_reg_rules += num_6ghz_client[WMI_REG_VERY_LOW_POWER_AP][i];
5470
5471		if ((num_6ghz_client[WMI_REG_INDOOR_AP][i] > MAX_6GHZ_REG_RULES) ||
5472		    (num_6ghz_client[WMI_REG_STANDARD_POWER_AP][i] >
5473							     MAX_6GHZ_REG_RULES) ||
5474		    (num_6ghz_client[WMI_REG_VERY_LOW_POWER_AP][i] >
5475							     MAX_6GHZ_REG_RULES)) {
5476			ath11k_warn(ab,
5477				    "Num 6 GHz client reg rules exceeds max limit, for client(type: %d)\n",
5478				    i);
5479			kfree(tb);
5480			return -EINVAL;
5481		}
5482	}
5483
5484	if (!total_reg_rules) {
5485		ath11k_warn(ab, "No reg rules available\n");
5486		kfree(tb);
5487		return -EINVAL;
5488	}
5489
5490	memcpy(reg_info->alpha2, &ev->alpha2, REG_ALPHA2_LEN);
5491
5492	reg_info->dfs_region = ev->dfs_region;
5493	reg_info->phybitmap = ev->phybitmap;
5494	reg_info->num_phy = ev->num_phy;
5495	reg_info->phy_id = ev->phy_id;
5496	reg_info->ctry_code = ev->country_id;
5497	reg_info->reg_dmn_pair = ev->domain_code;
5498
5499	ath11k_dbg(ab, ATH11K_DBG_WMI,
5500		   "status_code %s",
5501		   ath11k_cc_status_to_str(reg_info->status_code));
5502
5503	reg_info->status_code =
5504		ath11k_wmi_cc_setting_code_to_reg(ev->status_code);
5505
5506	reg_info->is_ext_reg_event = true;
5507
5508	reg_info->min_bw_2ghz = ev->min_bw_2ghz;
5509	reg_info->max_bw_2ghz = ev->max_bw_2ghz;
5510	reg_info->min_bw_5ghz = ev->min_bw_5ghz;
5511	reg_info->max_bw_5ghz = ev->max_bw_5ghz;
5512
5513	reg_info->min_bw_6ghz_ap[WMI_REG_INDOOR_AP] =
5514			ev->min_bw_6ghz_ap_lpi;
5515	reg_info->max_bw_6ghz_ap[WMI_REG_INDOOR_AP] =
5516			ev->max_bw_6ghz_ap_lpi;
5517	reg_info->min_bw_6ghz_ap[WMI_REG_STANDARD_POWER_AP] =
5518			ev->min_bw_6ghz_ap_sp;
5519	reg_info->max_bw_6ghz_ap[WMI_REG_STANDARD_POWER_AP] =
5520			ev->max_bw_6ghz_ap_sp;
5521	reg_info->min_bw_6ghz_ap[WMI_REG_VERY_LOW_POWER_AP] =
5522			ev->min_bw_6ghz_ap_vlp;
5523	reg_info->max_bw_6ghz_ap[WMI_REG_VERY_LOW_POWER_AP] =
5524			ev->max_bw_6ghz_ap_vlp;
5525
5526	ath11k_dbg(ab, ATH11K_DBG_WMI,
5527		   "6 GHz AP BW: LPI (%d - %d), SP (%d - %d), VLP (%d - %d)\n",
5528		   reg_info->min_bw_6ghz_ap[WMI_REG_INDOOR_AP],
5529		   reg_info->max_bw_6ghz_ap[WMI_REG_INDOOR_AP],
5530		   reg_info->min_bw_6ghz_ap[WMI_REG_STANDARD_POWER_AP],
5531		   reg_info->max_bw_6ghz_ap[WMI_REG_STANDARD_POWER_AP],
5532		   reg_info->min_bw_6ghz_ap[WMI_REG_VERY_LOW_POWER_AP],
5533		   reg_info->max_bw_6ghz_ap[WMI_REG_VERY_LOW_POWER_AP]);
5534
5535	for (i = 0; i < WMI_REG_MAX_CLIENT_TYPE; i++) {
5536		reg_info->min_bw_6ghz_client[WMI_REG_INDOOR_AP][i] =
5537				ev->min_bw_6ghz_client_lpi[i];
5538		reg_info->max_bw_6ghz_client[WMI_REG_INDOOR_AP][i] =
5539				ev->max_bw_6ghz_client_lpi[i];
5540		reg_info->min_bw_6ghz_client[WMI_REG_STANDARD_POWER_AP][i] =
5541				ev->min_bw_6ghz_client_sp[i];
5542		reg_info->max_bw_6ghz_client[WMI_REG_STANDARD_POWER_AP][i] =
5543				ev->max_bw_6ghz_client_sp[i];
5544		reg_info->min_bw_6ghz_client[WMI_REG_VERY_LOW_POWER_AP][i] =
5545				ev->min_bw_6ghz_client_vlp[i];
5546		reg_info->max_bw_6ghz_client[WMI_REG_VERY_LOW_POWER_AP][i] =
5547				ev->max_bw_6ghz_client_vlp[i];
5548
5549		ath11k_dbg(ab, ATH11K_DBG_WMI,
5550			   "6 GHz %s BW: LPI (%d - %d), SP (%d - %d), VLP (%d - %d)\n",
5551			   ath11k_6ghz_client_type_to_str(i),
5552			   reg_info->min_bw_6ghz_client[WMI_REG_INDOOR_AP][i],
5553			   reg_info->max_bw_6ghz_client[WMI_REG_INDOOR_AP][i],
5554			   reg_info->min_bw_6ghz_client[WMI_REG_STANDARD_POWER_AP][i],
5555			   reg_info->max_bw_6ghz_client[WMI_REG_STANDARD_POWER_AP][i],
5556			   reg_info->min_bw_6ghz_client[WMI_REG_VERY_LOW_POWER_AP][i],
5557			   reg_info->max_bw_6ghz_client[WMI_REG_VERY_LOW_POWER_AP][i]);
5558	}
5559
5560	ath11k_dbg(ab, ATH11K_DBG_WMI,
5561		   "cc_ext %s dfs %d BW: min_2ghz %d max_2ghz %d min_5ghz %d max_5ghz %d phy_bitmap 0x%x",
5562		   reg_info->alpha2, reg_info->dfs_region,
5563		   reg_info->min_bw_2ghz, reg_info->max_bw_2ghz,
5564		   reg_info->min_bw_5ghz, reg_info->max_bw_5ghz,
5565		   reg_info->phybitmap);
5566
5567	ath11k_dbg(ab, ATH11K_DBG_WMI,
5568		   "num_2ghz_reg_rules %d num_5ghz_reg_rules %d",
5569		   num_2ghz_reg_rules, num_5ghz_reg_rules);
5570
5571	ath11k_dbg(ab, ATH11K_DBG_WMI,
5572		   "num_6ghz_reg_rules_ap_lpi: %d num_6ghz_reg_rules_ap_sp: %d num_6ghz_reg_rules_ap_vlp: %d",
5573		   num_6ghz_reg_rules_ap[WMI_REG_INDOOR_AP],
5574		   num_6ghz_reg_rules_ap[WMI_REG_STANDARD_POWER_AP],
5575		   num_6ghz_reg_rules_ap[WMI_REG_VERY_LOW_POWER_AP]);
5576
5577	j = WMI_REG_DEFAULT_CLIENT;
5578	ath11k_dbg(ab, ATH11K_DBG_WMI,
5579		   "6 GHz Regular client: num_6ghz_reg_rules_lpi: %d num_6ghz_reg_rules_sp: %d num_6ghz_reg_rules_vlp: %d",
5580		   num_6ghz_client[WMI_REG_INDOOR_AP][j],
5581		   num_6ghz_client[WMI_REG_STANDARD_POWER_AP][j],
5582		   num_6ghz_client[WMI_REG_VERY_LOW_POWER_AP][j]);
5583
5584	j = WMI_REG_SUBORDINATE_CLIENT;
5585	ath11k_dbg(ab, ATH11K_DBG_WMI,
5586		   "6 GHz Subordinate client: num_6ghz_reg_rules_lpi: %d num_6ghz_reg_rules_sp: %d num_6ghz_reg_rules_vlp: %d",
5587		   num_6ghz_client[WMI_REG_INDOOR_AP][j],
5588		   num_6ghz_client[WMI_REG_STANDARD_POWER_AP][j],
5589		   num_6ghz_client[WMI_REG_VERY_LOW_POWER_AP][j]);
5590
5591	ext_wmi_reg_rule =
5592		(struct wmi_regulatory_ext_rule *)((u8 *)ev + sizeof(*ev) +
5593						   sizeof(struct wmi_tlv));
5594	if (num_2ghz_reg_rules) {
5595		reg_info->reg_rules_2ghz_ptr =
5596			create_ext_reg_rules_from_wmi(num_2ghz_reg_rules,
5597						      ext_wmi_reg_rule);
5598
5599		if (!reg_info->reg_rules_2ghz_ptr) {
5600			kfree(tb);
5601			ath11k_warn(ab, "Unable to Allocate memory for 2 GHz rules\n");
5602			return -ENOMEM;
5603		}
5604
5605		ath11k_print_reg_rule(ab, "2 GHz",
5606				      num_2ghz_reg_rules,
5607				      reg_info->reg_rules_2ghz_ptr);
5608	}
5609
5610	ext_wmi_reg_rule += num_2ghz_reg_rules;
5611
5612	/* Firmware might include 6 GHz reg rule in 5 GHz rule list
5613	 * for few countries along with separate 6 GHz rule.
5614	 * Having same 6 GHz reg rule in 5 GHz and 6 GHz rules list
5615	 * causes intersect check to be true, and same rules will be
5616	 * shown multiple times in iw cmd.
5617	 * Hence, avoid parsing 6 GHz rule from 5 GHz reg rule list
5618	 */
5619	num_invalid_5ghz_ext_rules =
5620		ath11k_invalid_5ghz_reg_ext_rules_from_wmi(num_5ghz_reg_rules,
5621							   ext_wmi_reg_rule);
5622
5623	if (num_invalid_5ghz_ext_rules) {
5624		ath11k_dbg(ab, ATH11K_DBG_WMI,
5625			   "CC: %s 5 GHz reg rules number %d from fw, %d number of invalid 5 GHz rules",
5626			   reg_info->alpha2, reg_info->num_5ghz_reg_rules,
5627			   num_invalid_5ghz_ext_rules);
5628
5629		num_5ghz_reg_rules = num_5ghz_reg_rules - num_invalid_5ghz_ext_rules;
5630		reg_info->num_5ghz_reg_rules = num_5ghz_reg_rules;
5631	}
5632
5633	if (num_5ghz_reg_rules) {
5634		reg_info->reg_rules_5ghz_ptr =
5635			create_ext_reg_rules_from_wmi(num_5ghz_reg_rules,
5636						      ext_wmi_reg_rule);
5637
5638		if (!reg_info->reg_rules_5ghz_ptr) {
5639			kfree(tb);
5640			ath11k_warn(ab, "Unable to Allocate memory for 5 GHz rules\n");
5641			return -ENOMEM;
5642		}
5643
5644		ath11k_print_reg_rule(ab, "5 GHz",
5645				      num_5ghz_reg_rules,
5646				      reg_info->reg_rules_5ghz_ptr);
5647	}
5648
5649	/* We have adjusted the number of 5 GHz reg rules above. But still those
5650	 * many rules needs to be adjusted in ext_wmi_reg_rule.
5651	 *
5652	 * NOTE: num_invalid_5ghz_ext_rules will be 0 for rest other cases.
5653	 */
5654	ext_wmi_reg_rule += (num_5ghz_reg_rules + num_invalid_5ghz_ext_rules);
5655
5656	for (i = 0; i < WMI_REG_CURRENT_MAX_AP_TYPE; i++) {
5657		reg_info->reg_rules_6ghz_ap_ptr[i] =
5658			create_ext_reg_rules_from_wmi(num_6ghz_reg_rules_ap[i],
5659						      ext_wmi_reg_rule);
5660
5661		if (!reg_info->reg_rules_6ghz_ap_ptr[i]) {
5662			kfree(tb);
5663			ath11k_warn(ab, "Unable to Allocate memory for 6 GHz AP rules\n");
5664			return -ENOMEM;
5665		}
5666
5667		ath11k_print_reg_rule(ab, ath11k_6ghz_ap_type_to_str(i),
5668				      num_6ghz_reg_rules_ap[i],
5669				      reg_info->reg_rules_6ghz_ap_ptr[i]);
5670
5671		ext_wmi_reg_rule += num_6ghz_reg_rules_ap[i];
5672	}
5673
5674	for (j = 0; j < WMI_REG_CURRENT_MAX_AP_TYPE; j++) {
5675		ath11k_dbg(ab, ATH11K_DBG_WMI,
5676			   "6 GHz AP type %s", ath11k_6ghz_ap_type_to_str(j));
5677
5678		for (i = 0; i < WMI_REG_MAX_CLIENT_TYPE; i++) {
5679			reg_info->reg_rules_6ghz_client_ptr[j][i] =
5680				create_ext_reg_rules_from_wmi(num_6ghz_client[j][i],
5681							      ext_wmi_reg_rule);
5682
5683			if (!reg_info->reg_rules_6ghz_client_ptr[j][i]) {
5684				kfree(tb);
5685				ath11k_warn(ab, "Unable to Allocate memory for 6 GHz client rules\n");
5686				return -ENOMEM;
5687			}
5688
5689			ath11k_print_reg_rule(ab,
5690					      ath11k_6ghz_client_type_to_str(i),
5691					      num_6ghz_client[j][i],
5692					      reg_info->reg_rules_6ghz_client_ptr[j][i]);
5693
5694			ext_wmi_reg_rule += num_6ghz_client[j][i];
5695		}
5696	}
5697
5698	reg_info->client_type = ev->client_type;
5699	reg_info->rnr_tpe_usable = ev->rnr_tpe_usable;
5700	reg_info->unspecified_ap_usable =
5701			ev->unspecified_ap_usable;
5702	reg_info->domain_code_6ghz_ap[WMI_REG_INDOOR_AP] =
5703			ev->domain_code_6ghz_ap_lpi;
5704	reg_info->domain_code_6ghz_ap[WMI_REG_STANDARD_POWER_AP] =
5705			ev->domain_code_6ghz_ap_sp;
5706	reg_info->domain_code_6ghz_ap[WMI_REG_VERY_LOW_POWER_AP] =
5707			ev->domain_code_6ghz_ap_vlp;
5708
5709	ath11k_dbg(ab, ATH11K_DBG_WMI,
5710		   "6 GHz reg info client type %s rnr_tpe_usable %d unspecified_ap_usable %d AP sub domain: lpi %s, sp %s, vlp %s\n",
5711		   ath11k_6ghz_client_type_to_str(reg_info->client_type),
5712		   reg_info->rnr_tpe_usable,
5713		   reg_info->unspecified_ap_usable,
5714		   ath11k_sub_reg_6ghz_to_str(ev->domain_code_6ghz_ap_lpi),
5715		   ath11k_sub_reg_6ghz_to_str(ev->domain_code_6ghz_ap_sp),
5716		   ath11k_sub_reg_6ghz_to_str(ev->domain_code_6ghz_ap_vlp));
5717
5718	for (i = 0; i < WMI_REG_MAX_CLIENT_TYPE; i++) {
5719		reg_info->domain_code_6ghz_client[WMI_REG_INDOOR_AP][i] =
5720				ev->domain_code_6ghz_client_lpi[i];
5721		reg_info->domain_code_6ghz_client[WMI_REG_STANDARD_POWER_AP][i] =
5722				ev->domain_code_6ghz_client_sp[i];
5723		reg_info->domain_code_6ghz_client[WMI_REG_VERY_LOW_POWER_AP][i] =
5724				ev->domain_code_6ghz_client_vlp[i];
5725
5726		ath11k_dbg(ab, ATH11K_DBG_WMI,
5727			   "6 GHz client type %s client sub domain: lpi %s, sp %s, vlp %s\n",
5728			   ath11k_6ghz_client_type_to_str(i),
5729			   ath11k_sub_reg_6ghz_to_str(ev->domain_code_6ghz_client_lpi[i]),
5730			   ath11k_sub_reg_6ghz_to_str(ev->domain_code_6ghz_client_sp[i]),
5731			   ath11k_sub_reg_6ghz_to_str(ev->domain_code_6ghz_client_vlp[i])
5732			  );
5733	}
5734
5735	reg_info->domain_code_6ghz_super_id = ev->domain_code_6ghz_super_id;
5736
5737	ath11k_dbg(ab, ATH11K_DBG_WMI,
5738		   "6 GHz client_type %s 6 GHz super domain %s",
5739		   ath11k_6ghz_client_type_to_str(reg_info->client_type),
5740		   ath11k_super_reg_6ghz_to_str(reg_info->domain_code_6ghz_super_id));
5741
5742	ath11k_dbg(ab, ATH11K_DBG_WMI, "processed regulatory ext channel list\n");
5743
5744	kfree(tb);
5745	return 0;
5746}
5747
5748static int ath11k_pull_peer_del_resp_ev(struct ath11k_base *ab, struct sk_buff *skb,
5749					struct wmi_peer_delete_resp_event *peer_del_resp)
5750{
5751	const void **tb;
5752	const struct wmi_peer_delete_resp_event *ev;
5753	int ret;
5754
5755	tb = ath11k_wmi_tlv_parse_alloc(ab, skb, GFP_ATOMIC);
5756	if (IS_ERR(tb)) {
5757		ret = PTR_ERR(tb);
5758		ath11k_warn(ab, "failed to parse tlv: %d\n", ret);
5759		return ret;
5760	}
5761
5762	ev = tb[WMI_TAG_PEER_DELETE_RESP_EVENT];
5763	if (!ev) {
5764		ath11k_warn(ab, "failed to fetch peer delete resp ev");
5765		kfree(tb);
5766		return -EPROTO;
5767	}
5768
5769	memset(peer_del_resp, 0, sizeof(*peer_del_resp));
5770
5771	peer_del_resp->vdev_id = ev->vdev_id;
5772	ether_addr_copy(peer_del_resp->peer_macaddr.addr,
5773			ev->peer_macaddr.addr);
5774
5775	kfree(tb);
5776	return 0;
5777}
5778
5779static int ath11k_pull_vdev_del_resp_ev(struct ath11k_base *ab,
5780					struct sk_buff *skb,
5781					u32 *vdev_id)
5782{
5783	const void **tb;
5784	const struct wmi_vdev_delete_resp_event *ev;
5785	int ret;
5786
5787	tb = ath11k_wmi_tlv_parse_alloc(ab, skb, GFP_ATOMIC);
5788	if (IS_ERR(tb)) {
5789		ret = PTR_ERR(tb);
5790		ath11k_warn(ab, "failed to parse tlv: %d\n", ret);
5791		return ret;
5792	}
5793
5794	ev = tb[WMI_TAG_VDEV_DELETE_RESP_EVENT];
5795	if (!ev) {
5796		ath11k_warn(ab, "failed to fetch vdev delete resp ev");
5797		kfree(tb);
5798		return -EPROTO;
5799	}
5800
5801	*vdev_id = ev->vdev_id;
5802
5803	kfree(tb);
5804	return 0;
5805}
5806
5807static int ath11k_pull_bcn_tx_status_ev(struct ath11k_base *ab,
5808					struct sk_buff *skb,
5809					u32 *vdev_id, u32 *tx_status)
5810{
5811	const void **tb;
5812	const struct wmi_bcn_tx_status_event *ev;
5813	int ret;
5814
5815	tb = ath11k_wmi_tlv_parse_alloc(ab, skb, GFP_ATOMIC);
5816	if (IS_ERR(tb)) {
5817		ret = PTR_ERR(tb);
5818		ath11k_warn(ab, "failed to parse tlv: %d\n", ret);
5819		return ret;
5820	}
5821
5822	ev = tb[WMI_TAG_OFFLOAD_BCN_TX_STATUS_EVENT];
5823	if (!ev) {
5824		ath11k_warn(ab, "failed to fetch bcn tx status ev");
5825		kfree(tb);
5826		return -EPROTO;
5827	}
5828
5829	*vdev_id   = ev->vdev_id;
5830	*tx_status = ev->tx_status;
5831
5832	kfree(tb);
5833	return 0;
5834}
5835
5836static int ath11k_pull_vdev_stopped_param_tlv(struct ath11k_base *ab, struct sk_buff *skb,
5837					      u32 *vdev_id)
5838{
5839	const void **tb;
5840	const struct wmi_vdev_stopped_event *ev;
5841	int ret;
5842
5843	tb = ath11k_wmi_tlv_parse_alloc(ab, skb, GFP_ATOMIC);
5844	if (IS_ERR(tb)) {
5845		ret = PTR_ERR(tb);
5846		ath11k_warn(ab, "failed to parse tlv: %d\n", ret);
5847		return ret;
5848	}
5849
5850	ev = tb[WMI_TAG_VDEV_STOPPED_EVENT];
5851	if (!ev) {
5852		ath11k_warn(ab, "failed to fetch vdev stop ev");
5853		kfree(tb);
5854		return -EPROTO;
5855	}
5856
5857	*vdev_id =  ev->vdev_id;
5858
5859	kfree(tb);
5860	return 0;
5861}
5862
5863static int ath11k_wmi_tlv_mgmt_rx_parse(struct ath11k_base *ab,
5864					u16 tag, u16 len,
5865					const void *ptr, void *data)
5866{
5867	struct wmi_tlv_mgmt_rx_parse *parse = data;
5868
5869	switch (tag) {
5870	case WMI_TAG_MGMT_RX_HDR:
5871		parse->fixed = ptr;
5872		break;
5873	case WMI_TAG_ARRAY_BYTE:
5874		if (!parse->frame_buf_done) {
5875			parse->frame_buf = ptr;
5876			parse->frame_buf_done = true;
5877		}
5878		break;
5879	}
5880	return 0;
5881}
5882
5883static int ath11k_pull_mgmt_rx_params_tlv(struct ath11k_base *ab,
5884					  struct sk_buff *skb,
5885					  struct mgmt_rx_event_params *hdr)
5886{
5887	struct wmi_tlv_mgmt_rx_parse parse = { };
5888	const struct wmi_mgmt_rx_hdr *ev;
5889	const u8 *frame;
5890	int ret;
5891
5892	ret = ath11k_wmi_tlv_iter(ab, skb->data, skb->len,
5893				  ath11k_wmi_tlv_mgmt_rx_parse,
5894				  &parse);
5895	if (ret) {
5896		ath11k_warn(ab, "failed to parse mgmt rx tlv %d\n",
5897			    ret);
5898		return ret;
5899	}
5900
5901	ev = parse.fixed;
5902	frame = parse.frame_buf;
5903
5904	if (!ev || !frame) {
5905		ath11k_warn(ab, "failed to fetch mgmt rx hdr");
5906		return -EPROTO;
5907	}
5908
5909	hdr->pdev_id =  ev->pdev_id;
5910	hdr->chan_freq = ev->chan_freq;
5911	hdr->channel =  ev->channel;
5912	hdr->snr =  ev->snr;
5913	hdr->rate =  ev->rate;
5914	hdr->phy_mode =  ev->phy_mode;
5915	hdr->buf_len =  ev->buf_len;
5916	hdr->status =  ev->status;
5917	hdr->flags =  ev->flags;
5918	hdr->rssi =  ev->rssi;
5919	hdr->tsf_delta =  ev->tsf_delta;
5920	memcpy(hdr->rssi_ctl, ev->rssi_ctl, sizeof(hdr->rssi_ctl));
5921
5922	if (skb->len < (frame - skb->data) + hdr->buf_len) {
5923		ath11k_warn(ab, "invalid length in mgmt rx hdr ev");
5924		return -EPROTO;
5925	}
5926
5927	/* shift the sk_buff to point to `frame` */
5928	skb_trim(skb, 0);
5929	skb_put(skb, frame - skb->data);
5930	skb_pull(skb, frame - skb->data);
5931	skb_put(skb, hdr->buf_len);
5932
5933	ath11k_ce_byte_swap(skb->data, hdr->buf_len);
5934
5935	return 0;
5936}
5937
5938static int wmi_process_mgmt_tx_comp(struct ath11k *ar,
5939				    struct wmi_mgmt_tx_compl_event *tx_compl_param)
5940{
5941	struct sk_buff *msdu;
5942	struct ieee80211_tx_info *info;
5943	struct ath11k_skb_cb *skb_cb;
5944	int num_mgmt;
5945
5946	spin_lock_bh(&ar->txmgmt_idr_lock);
5947	msdu = idr_find(&ar->txmgmt_idr, tx_compl_param->desc_id);
5948
5949	if (!msdu) {
5950		ath11k_warn(ar->ab, "received mgmt tx compl for invalid msdu_id: %d\n",
5951			    tx_compl_param->desc_id);
5952		spin_unlock_bh(&ar->txmgmt_idr_lock);
5953		return -ENOENT;
5954	}
5955
5956	idr_remove(&ar->txmgmt_idr, tx_compl_param->desc_id);
5957	spin_unlock_bh(&ar->txmgmt_idr_lock);
5958
5959	skb_cb = ATH11K_SKB_CB(msdu);
5960	dma_unmap_single(ar->ab->dev, skb_cb->paddr, msdu->len, DMA_TO_DEVICE);
5961
5962	info = IEEE80211_SKB_CB(msdu);
5963	if ((!(info->flags & IEEE80211_TX_CTL_NO_ACK)) &&
5964	    !tx_compl_param->status) {
5965		info->flags |= IEEE80211_TX_STAT_ACK;
5966		if (test_bit(WMI_TLV_SERVICE_TX_DATA_MGMT_ACK_RSSI,
5967			     ar->ab->wmi_ab.svc_map))
5968			info->status.ack_signal = tx_compl_param->ack_rssi;
5969	}
5970
5971	ieee80211_tx_status_irqsafe(ar->hw, msdu);
5972
5973	num_mgmt = atomic_dec_if_positive(&ar->num_pending_mgmt_tx);
5974
5975	/* WARN when we received this event without doing any mgmt tx */
5976	if (num_mgmt < 0)
5977		WARN_ON_ONCE(1);
5978
5979	ath11k_dbg(ar->ab, ATH11K_DBG_WMI,
5980		   "mgmt tx comp pending %d desc id %d\n",
5981		   num_mgmt, tx_compl_param->desc_id);
5982
5983	if (!num_mgmt)
5984		wake_up(&ar->txmgmt_empty_waitq);
5985
5986	return 0;
5987}
5988
5989static int ath11k_pull_mgmt_tx_compl_param_tlv(struct ath11k_base *ab,
5990					       struct sk_buff *skb,
5991					       struct wmi_mgmt_tx_compl_event *param)
5992{
5993	const void **tb;
5994	const struct wmi_mgmt_tx_compl_event *ev;
5995	int ret;
5996
5997	tb = ath11k_wmi_tlv_parse_alloc(ab, skb, GFP_ATOMIC);
5998	if (IS_ERR(tb)) {
5999		ret = PTR_ERR(tb);
6000		ath11k_warn(ab, "failed to parse tlv: %d\n", ret);
6001		return ret;
6002	}
6003
6004	ev = tb[WMI_TAG_MGMT_TX_COMPL_EVENT];
6005	if (!ev) {
6006		ath11k_warn(ab, "failed to fetch mgmt tx compl ev");
6007		kfree(tb);
6008		return -EPROTO;
6009	}
6010
6011	param->pdev_id = ev->pdev_id;
6012	param->desc_id = ev->desc_id;
6013	param->status = ev->status;
6014	param->ack_rssi = ev->ack_rssi;
6015
6016	kfree(tb);
6017	return 0;
6018}
6019
6020static void ath11k_wmi_event_scan_started(struct ath11k *ar)
6021{
6022	lockdep_assert_held(&ar->data_lock);
6023
6024	switch (ar->scan.state) {
6025	case ATH11K_SCAN_IDLE:
6026	case ATH11K_SCAN_RUNNING:
6027	case ATH11K_SCAN_ABORTING:
6028		ath11k_warn(ar->ab, "received scan started event in an invalid scan state: %s (%d)\n",
6029			    ath11k_scan_state_str(ar->scan.state),
6030			    ar->scan.state);
6031		break;
6032	case ATH11K_SCAN_STARTING:
6033		ar->scan.state = ATH11K_SCAN_RUNNING;
6034		if (ar->scan.is_roc)
6035			ieee80211_ready_on_channel(ar->hw);
6036		complete(&ar->scan.started);
6037		break;
6038	}
6039}
6040
6041static void ath11k_wmi_event_scan_start_failed(struct ath11k *ar)
6042{
6043	lockdep_assert_held(&ar->data_lock);
6044
6045	switch (ar->scan.state) {
6046	case ATH11K_SCAN_IDLE:
6047	case ATH11K_SCAN_RUNNING:
6048	case ATH11K_SCAN_ABORTING:
6049		ath11k_warn(ar->ab, "received scan start failed event in an invalid scan state: %s (%d)\n",
6050			    ath11k_scan_state_str(ar->scan.state),
6051			    ar->scan.state);
6052		break;
6053	case ATH11K_SCAN_STARTING:
6054		complete(&ar->scan.started);
6055		__ath11k_mac_scan_finish(ar);
6056		break;
6057	}
6058}
6059
6060static void ath11k_wmi_event_scan_completed(struct ath11k *ar)
6061{
6062	lockdep_assert_held(&ar->data_lock);
6063
6064	switch (ar->scan.state) {
6065	case ATH11K_SCAN_IDLE:
6066	case ATH11K_SCAN_STARTING:
6067		/* One suspected reason scan can be completed while starting is
6068		 * if firmware fails to deliver all scan events to the host,
6069		 * e.g. when transport pipe is full. This has been observed
6070		 * with spectral scan phyerr events starving wmi transport
6071		 * pipe. In such case the "scan completed" event should be (and
6072		 * is) ignored by the host as it may be just firmware's scan
6073		 * state machine recovering.
6074		 */
6075		ath11k_warn(ar->ab, "received scan completed event in an invalid scan state: %s (%d)\n",
6076			    ath11k_scan_state_str(ar->scan.state),
6077			    ar->scan.state);
6078		break;
6079	case ATH11K_SCAN_RUNNING:
6080	case ATH11K_SCAN_ABORTING:
6081		__ath11k_mac_scan_finish(ar);
6082		break;
6083	}
6084}
6085
6086static void ath11k_wmi_event_scan_bss_chan(struct ath11k *ar)
6087{
6088	lockdep_assert_held(&ar->data_lock);
6089
6090	switch (ar->scan.state) {
6091	case ATH11K_SCAN_IDLE:
6092	case ATH11K_SCAN_STARTING:
6093		ath11k_warn(ar->ab, "received scan bss chan event in an invalid scan state: %s (%d)\n",
6094			    ath11k_scan_state_str(ar->scan.state),
6095			    ar->scan.state);
6096		break;
6097	case ATH11K_SCAN_RUNNING:
6098	case ATH11K_SCAN_ABORTING:
6099		ar->scan_channel = NULL;
6100		break;
6101	}
6102}
6103
6104static void ath11k_wmi_event_scan_foreign_chan(struct ath11k *ar, u32 freq)
6105{
6106	lockdep_assert_held(&ar->data_lock);
6107
6108	switch (ar->scan.state) {
6109	case ATH11K_SCAN_IDLE:
6110	case ATH11K_SCAN_STARTING:
6111		ath11k_warn(ar->ab, "received scan foreign chan event in an invalid scan state: %s (%d)\n",
6112			    ath11k_scan_state_str(ar->scan.state),
6113			    ar->scan.state);
6114		break;
6115	case ATH11K_SCAN_RUNNING:
6116	case ATH11K_SCAN_ABORTING:
6117		ar->scan_channel = ieee80211_get_channel(ar->hw->wiphy, freq);
6118		if (ar->scan.is_roc && ar->scan.roc_freq == freq)
6119			complete(&ar->scan.on_channel);
6120		break;
6121	}
6122}
6123
6124static const char *
6125ath11k_wmi_event_scan_type_str(enum wmi_scan_event_type type,
6126			       enum wmi_scan_completion_reason reason)
6127{
6128	switch (type) {
6129	case WMI_SCAN_EVENT_STARTED:
6130		return "started";
6131	case WMI_SCAN_EVENT_COMPLETED:
6132		switch (reason) {
6133		case WMI_SCAN_REASON_COMPLETED:
6134			return "completed";
6135		case WMI_SCAN_REASON_CANCELLED:
6136			return "completed [cancelled]";
6137		case WMI_SCAN_REASON_PREEMPTED:
6138			return "completed [preempted]";
6139		case WMI_SCAN_REASON_TIMEDOUT:
6140			return "completed [timedout]";
6141		case WMI_SCAN_REASON_INTERNAL_FAILURE:
6142			return "completed [internal err]";
6143		case WMI_SCAN_REASON_MAX:
6144			break;
6145		}
6146		return "completed [unknown]";
6147	case WMI_SCAN_EVENT_BSS_CHANNEL:
6148		return "bss channel";
6149	case WMI_SCAN_EVENT_FOREIGN_CHAN:
6150		return "foreign channel";
6151	case WMI_SCAN_EVENT_DEQUEUED:
6152		return "dequeued";
6153	case WMI_SCAN_EVENT_PREEMPTED:
6154		return "preempted";
6155	case WMI_SCAN_EVENT_START_FAILED:
6156		return "start failed";
6157	case WMI_SCAN_EVENT_RESTARTED:
6158		return "restarted";
6159	case WMI_SCAN_EVENT_FOREIGN_CHAN_EXIT:
6160		return "foreign channel exit";
6161	default:
6162		return "unknown";
6163	}
6164}
6165
6166static int ath11k_pull_scan_ev(struct ath11k_base *ab, struct sk_buff *skb,
6167			       struct wmi_scan_event *scan_evt_param)
6168{
6169	const void **tb;
6170	const struct wmi_scan_event *ev;
6171	int ret;
6172
6173	tb = ath11k_wmi_tlv_parse_alloc(ab, skb, GFP_ATOMIC);
6174	if (IS_ERR(tb)) {
6175		ret = PTR_ERR(tb);
6176		ath11k_warn(ab, "failed to parse tlv: %d\n", ret);
6177		return ret;
6178	}
6179
6180	ev = tb[WMI_TAG_SCAN_EVENT];
6181	if (!ev) {
6182		ath11k_warn(ab, "failed to fetch scan ev");
6183		kfree(tb);
6184		return -EPROTO;
6185	}
6186
6187	scan_evt_param->event_type = ev->event_type;
6188	scan_evt_param->reason = ev->reason;
6189	scan_evt_param->channel_freq = ev->channel_freq;
6190	scan_evt_param->scan_req_id = ev->scan_req_id;
6191	scan_evt_param->scan_id = ev->scan_id;
6192	scan_evt_param->vdev_id = ev->vdev_id;
6193	scan_evt_param->tsf_timestamp = ev->tsf_timestamp;
6194
6195	kfree(tb);
6196	return 0;
6197}
6198
6199static int ath11k_pull_peer_sta_kickout_ev(struct ath11k_base *ab, struct sk_buff *skb,
6200					   struct wmi_peer_sta_kickout_arg *arg)
6201{
6202	const void **tb;
6203	const struct wmi_peer_sta_kickout_event *ev;
6204	int ret;
6205
6206	tb = ath11k_wmi_tlv_parse_alloc(ab, skb, GFP_ATOMIC);
6207	if (IS_ERR(tb)) {
6208		ret = PTR_ERR(tb);
6209		ath11k_warn(ab, "failed to parse tlv: %d\n", ret);
6210		return ret;
6211	}
6212
6213	ev = tb[WMI_TAG_PEER_STA_KICKOUT_EVENT];
6214	if (!ev) {
6215		ath11k_warn(ab, "failed to fetch peer sta kickout ev");
6216		kfree(tb);
6217		return -EPROTO;
6218	}
6219
6220	arg->mac_addr = ev->peer_macaddr.addr;
6221
6222	kfree(tb);
6223	return 0;
6224}
6225
6226static int ath11k_pull_roam_ev(struct ath11k_base *ab, struct sk_buff *skb,
6227			       struct wmi_roam_event *roam_ev)
6228{
6229	const void **tb;
6230	const struct wmi_roam_event *ev;
6231	int ret;
6232
6233	tb = ath11k_wmi_tlv_parse_alloc(ab, skb, GFP_ATOMIC);
6234	if (IS_ERR(tb)) {
6235		ret = PTR_ERR(tb);
6236		ath11k_warn(ab, "failed to parse tlv: %d\n", ret);
6237		return ret;
6238	}
6239
6240	ev = tb[WMI_TAG_ROAM_EVENT];
6241	if (!ev) {
6242		ath11k_warn(ab, "failed to fetch roam ev");
6243		kfree(tb);
6244		return -EPROTO;
6245	}
6246
6247	roam_ev->vdev_id = ev->vdev_id;
6248	roam_ev->reason = ev->reason;
6249	roam_ev->rssi = ev->rssi;
6250
6251	kfree(tb);
6252	return 0;
6253}
6254
6255static int freq_to_idx(struct ath11k *ar, int freq)
6256{
6257	struct ieee80211_supported_band *sband;
6258	int band, ch, idx = 0;
6259
6260	for (band = NL80211_BAND_2GHZ; band < NUM_NL80211_BANDS; band++) {
6261		sband = ar->hw->wiphy->bands[band];
6262		if (!sband)
6263			continue;
6264
6265		for (ch = 0; ch < sband->n_channels; ch++, idx++)
6266			if (sband->channels[ch].center_freq == freq)
6267				goto exit;
6268	}
6269
6270exit:
6271	return idx;
6272}
6273
6274static int ath11k_pull_chan_info_ev(struct ath11k_base *ab, struct sk_buff *skb,
6275				    struct wmi_chan_info_event *ch_info_ev)
6276{
6277	const void **tb;
6278	const struct wmi_chan_info_event *ev;
6279	int ret;
6280
6281	tb = ath11k_wmi_tlv_parse_alloc(ab, skb, GFP_ATOMIC);
6282	if (IS_ERR(tb)) {
6283		ret = PTR_ERR(tb);
6284		ath11k_warn(ab, "failed to parse tlv: %d\n", ret);
6285		return ret;
6286	}
6287
6288	ev = tb[WMI_TAG_CHAN_INFO_EVENT];
6289	if (!ev) {
6290		ath11k_warn(ab, "failed to fetch chan info ev");
6291		kfree(tb);
6292		return -EPROTO;
6293	}
6294
6295	ch_info_ev->err_code = ev->err_code;
6296	ch_info_ev->freq = ev->freq;
6297	ch_info_ev->cmd_flags = ev->cmd_flags;
6298	ch_info_ev->noise_floor = ev->noise_floor;
6299	ch_info_ev->rx_clear_count = ev->rx_clear_count;
6300	ch_info_ev->cycle_count = ev->cycle_count;
6301	ch_info_ev->chan_tx_pwr_range = ev->chan_tx_pwr_range;
6302	ch_info_ev->chan_tx_pwr_tp = ev->chan_tx_pwr_tp;
6303	ch_info_ev->rx_frame_count = ev->rx_frame_count;
6304	ch_info_ev->tx_frame_cnt = ev->tx_frame_cnt;
6305	ch_info_ev->mac_clk_mhz = ev->mac_clk_mhz;
6306	ch_info_ev->vdev_id = ev->vdev_id;
6307
6308	kfree(tb);
6309	return 0;
6310}
6311
6312static int
6313ath11k_pull_pdev_bss_chan_info_ev(struct ath11k_base *ab, struct sk_buff *skb,
6314				  struct wmi_pdev_bss_chan_info_event *bss_ch_info_ev)
6315{
6316	const void **tb;
6317	const struct wmi_pdev_bss_chan_info_event *ev;
6318	int ret;
6319
6320	tb = ath11k_wmi_tlv_parse_alloc(ab, skb, GFP_ATOMIC);
6321	if (IS_ERR(tb)) {
6322		ret = PTR_ERR(tb);
6323		ath11k_warn(ab, "failed to parse tlv: %d\n", ret);
6324		return ret;
6325	}
6326
6327	ev = tb[WMI_TAG_PDEV_BSS_CHAN_INFO_EVENT];
6328	if (!ev) {
6329		ath11k_warn(ab, "failed to fetch pdev bss chan info ev");
6330		kfree(tb);
6331		return -EPROTO;
6332	}
6333
6334	bss_ch_info_ev->pdev_id = ev->pdev_id;
6335	bss_ch_info_ev->freq = ev->freq;
6336	bss_ch_info_ev->noise_floor = ev->noise_floor;
6337	bss_ch_info_ev->rx_clear_count_low = ev->rx_clear_count_low;
6338	bss_ch_info_ev->rx_clear_count_high = ev->rx_clear_count_high;
6339	bss_ch_info_ev->cycle_count_low = ev->cycle_count_low;
6340	bss_ch_info_ev->cycle_count_high = ev->cycle_count_high;
6341	bss_ch_info_ev->tx_cycle_count_low = ev->tx_cycle_count_low;
6342	bss_ch_info_ev->tx_cycle_count_high = ev->tx_cycle_count_high;
6343	bss_ch_info_ev->rx_cycle_count_low = ev->rx_cycle_count_low;
6344	bss_ch_info_ev->rx_cycle_count_high = ev->rx_cycle_count_high;
6345	bss_ch_info_ev->rx_bss_cycle_count_low = ev->rx_bss_cycle_count_low;
6346	bss_ch_info_ev->rx_bss_cycle_count_high = ev->rx_bss_cycle_count_high;
6347
6348	kfree(tb);
6349	return 0;
6350}
6351
6352static int
6353ath11k_pull_vdev_install_key_compl_ev(struct ath11k_base *ab, struct sk_buff *skb,
6354				      struct wmi_vdev_install_key_complete_arg *arg)
6355{
6356	const void **tb;
6357	const struct wmi_vdev_install_key_compl_event *ev;
6358	int ret;
6359
6360	tb = ath11k_wmi_tlv_parse_alloc(ab, skb, GFP_ATOMIC);
6361	if (IS_ERR(tb)) {
6362		ret = PTR_ERR(tb);
6363		ath11k_warn(ab, "failed to parse tlv: %d\n", ret);
6364		return ret;
6365	}
6366
6367	ev = tb[WMI_TAG_VDEV_INSTALL_KEY_COMPLETE_EVENT];
6368	if (!ev) {
6369		ath11k_warn(ab, "failed to fetch vdev install key compl ev");
6370		kfree(tb);
6371		return -EPROTO;
6372	}
6373
6374	arg->vdev_id = ev->vdev_id;
6375	arg->macaddr = ev->peer_macaddr.addr;
6376	arg->key_idx = ev->key_idx;
6377	arg->key_flags = ev->key_flags;
6378	arg->status = ev->status;
6379
6380	kfree(tb);
6381	return 0;
6382}
6383
6384static int ath11k_pull_peer_assoc_conf_ev(struct ath11k_base *ab, struct sk_buff *skb,
6385					  struct wmi_peer_assoc_conf_arg *peer_assoc_conf)
6386{
6387	const void **tb;
6388	const struct wmi_peer_assoc_conf_event *ev;
6389	int ret;
6390
6391	tb = ath11k_wmi_tlv_parse_alloc(ab, skb, GFP_ATOMIC);
6392	if (IS_ERR(tb)) {
6393		ret = PTR_ERR(tb);
6394		ath11k_warn(ab, "failed to parse tlv: %d\n", ret);
6395		return ret;
6396	}
6397
6398	ev = tb[WMI_TAG_PEER_ASSOC_CONF_EVENT];
6399	if (!ev) {
6400		ath11k_warn(ab, "failed to fetch peer assoc conf ev");
6401		kfree(tb);
6402		return -EPROTO;
6403	}
6404
6405	peer_assoc_conf->vdev_id = ev->vdev_id;
6406	peer_assoc_conf->macaddr = ev->peer_macaddr.addr;
6407
6408	kfree(tb);
6409	return 0;
6410}
6411
6412static void ath11k_wmi_pull_pdev_stats_base(const struct wmi_pdev_stats_base *src,
6413					    struct ath11k_fw_stats_pdev *dst)
6414{
6415	dst->ch_noise_floor = src->chan_nf;
6416	dst->tx_frame_count = src->tx_frame_count;
6417	dst->rx_frame_count = src->rx_frame_count;
6418	dst->rx_clear_count = src->rx_clear_count;
6419	dst->cycle_count = src->cycle_count;
6420	dst->phy_err_count = src->phy_err_count;
6421	dst->chan_tx_power = src->chan_tx_pwr;
6422}
6423
6424static void
6425ath11k_wmi_pull_pdev_stats_tx(const struct wmi_pdev_stats_tx *src,
6426			      struct ath11k_fw_stats_pdev *dst)
6427{
6428	dst->comp_queued = src->comp_queued;
6429	dst->comp_delivered = src->comp_delivered;
6430	dst->msdu_enqued = src->msdu_enqued;
6431	dst->mpdu_enqued = src->mpdu_enqued;
6432	dst->wmm_drop = src->wmm_drop;
6433	dst->local_enqued = src->local_enqued;
6434	dst->local_freed = src->local_freed;
6435	dst->hw_queued = src->hw_queued;
6436	dst->hw_reaped = src->hw_reaped;
6437	dst->underrun = src->underrun;
6438	dst->hw_paused = src->hw_paused;
6439	dst->tx_abort = src->tx_abort;
6440	dst->mpdus_requeued = src->mpdus_requeued;
6441	dst->tx_ko = src->tx_ko;
6442	dst->tx_xretry = src->tx_xretry;
6443	dst->data_rc = src->data_rc;
6444	dst->self_triggers = src->self_triggers;
6445	dst->sw_retry_failure = src->sw_retry_failure;
6446	dst->illgl_rate_phy_err = src->illgl_rate_phy_err;
6447	dst->pdev_cont_xretry = src->pdev_cont_xretry;
6448	dst->pdev_tx_timeout = src->pdev_tx_timeout;
6449	dst->pdev_resets = src->pdev_resets;
6450	dst->stateless_tid_alloc_failure = src->stateless_tid_alloc_failure;
6451	dst->phy_underrun = src->phy_underrun;
6452	dst->txop_ovf = src->txop_ovf;
6453	dst->seq_posted = src->seq_posted;
6454	dst->seq_failed_queueing = src->seq_failed_queueing;
6455	dst->seq_completed = src->seq_completed;
6456	dst->seq_restarted = src->seq_restarted;
6457	dst->mu_seq_posted = src->mu_seq_posted;
6458	dst->mpdus_sw_flush = src->mpdus_sw_flush;
6459	dst->mpdus_hw_filter = src->mpdus_hw_filter;
6460	dst->mpdus_truncated = src->mpdus_truncated;
6461	dst->mpdus_ack_failed = src->mpdus_ack_failed;
6462	dst->mpdus_expired = src->mpdus_expired;
6463}
6464
6465static void ath11k_wmi_pull_pdev_stats_rx(const struct wmi_pdev_stats_rx *src,
6466					  struct ath11k_fw_stats_pdev *dst)
6467{
6468	dst->mid_ppdu_route_change = src->mid_ppdu_route_change;
6469	dst->status_rcvd = src->status_rcvd;
6470	dst->r0_frags = src->r0_frags;
6471	dst->r1_frags = src->r1_frags;
6472	dst->r2_frags = src->r2_frags;
6473	dst->r3_frags = src->r3_frags;
6474	dst->htt_msdus = src->htt_msdus;
6475	dst->htt_mpdus = src->htt_mpdus;
6476	dst->loc_msdus = src->loc_msdus;
6477	dst->loc_mpdus = src->loc_mpdus;
6478	dst->oversize_amsdu = src->oversize_amsdu;
6479	dst->phy_errs = src->phy_errs;
6480	dst->phy_err_drop = src->phy_err_drop;
6481	dst->mpdu_errs = src->mpdu_errs;
6482	dst->rx_ovfl_errs = src->rx_ovfl_errs;
6483}
6484
6485static void
6486ath11k_wmi_pull_vdev_stats(const struct wmi_vdev_stats *src,
6487			   struct ath11k_fw_stats_vdev *dst)
6488{
6489	int i;
6490
6491	dst->vdev_id = src->vdev_id;
6492	dst->beacon_snr = src->beacon_snr;
6493	dst->data_snr = src->data_snr;
6494	dst->num_rx_frames = src->num_rx_frames;
6495	dst->num_rts_fail = src->num_rts_fail;
6496	dst->num_rts_success = src->num_rts_success;
6497	dst->num_rx_err = src->num_rx_err;
6498	dst->num_rx_discard = src->num_rx_discard;
6499	dst->num_tx_not_acked = src->num_tx_not_acked;
6500
6501	for (i = 0; i < ARRAY_SIZE(src->num_tx_frames); i++)
6502		dst->num_tx_frames[i] = src->num_tx_frames[i];
6503
6504	for (i = 0; i < ARRAY_SIZE(src->num_tx_frames_retries); i++)
6505		dst->num_tx_frames_retries[i] = src->num_tx_frames_retries[i];
6506
6507	for (i = 0; i < ARRAY_SIZE(src->num_tx_frames_failures); i++)
6508		dst->num_tx_frames_failures[i] = src->num_tx_frames_failures[i];
6509
6510	for (i = 0; i < ARRAY_SIZE(src->tx_rate_history); i++)
6511		dst->tx_rate_history[i] = src->tx_rate_history[i];
6512
6513	for (i = 0; i < ARRAY_SIZE(src->beacon_rssi_history); i++)
6514		dst->beacon_rssi_history[i] = src->beacon_rssi_history[i];
6515}
6516
6517static void
6518ath11k_wmi_pull_bcn_stats(const struct wmi_bcn_stats *src,
6519			  struct ath11k_fw_stats_bcn *dst)
6520{
6521	dst->vdev_id = src->vdev_id;
6522	dst->tx_bcn_succ_cnt = src->tx_bcn_succ_cnt;
6523	dst->tx_bcn_outage_cnt = src->tx_bcn_outage_cnt;
6524}
6525
6526static int ath11k_wmi_tlv_rssi_chain_parse(struct ath11k_base *ab,
6527					   u16 tag, u16 len,
6528					   const void *ptr, void *data)
6529{
6530	struct wmi_tlv_fw_stats_parse *parse = data;
6531	const struct wmi_stats_event *ev = parse->ev;
6532	struct ath11k_fw_stats *stats = parse->stats;
6533	struct ath11k *ar;
6534	struct ath11k_vif *arvif;
6535	struct ieee80211_sta *sta;
6536	struct ath11k_sta *arsta;
6537	const struct wmi_rssi_stats *stats_rssi = (const struct wmi_rssi_stats *)ptr;
6538	int j, ret = 0;
6539
6540	if (tag != WMI_TAG_RSSI_STATS)
6541		return -EPROTO;
6542
6543	rcu_read_lock();
6544
6545	ar = ath11k_mac_get_ar_by_pdev_id(ab, ev->pdev_id);
6546	stats->stats_id = WMI_REQUEST_RSSI_PER_CHAIN_STAT;
6547
6548	ath11k_dbg(ab, ATH11K_DBG_WMI,
6549		   "stats vdev id %d mac %pM\n",
6550		   stats_rssi->vdev_id, stats_rssi->peer_macaddr.addr);
6551
6552	arvif = ath11k_mac_get_arvif(ar, stats_rssi->vdev_id);
6553	if (!arvif) {
6554		ath11k_warn(ab, "not found vif for vdev id %d\n",
6555			    stats_rssi->vdev_id);
6556		ret = -EPROTO;
6557		goto exit;
6558	}
6559
6560	ath11k_dbg(ab, ATH11K_DBG_WMI,
6561		   "stats bssid %pM vif %p\n",
6562		   arvif->bssid, arvif->vif);
6563
6564	sta = ieee80211_find_sta_by_ifaddr(ar->hw,
6565					   arvif->bssid,
6566					   NULL);
6567	if (!sta) {
6568		ath11k_dbg(ab, ATH11K_DBG_WMI,
6569			   "not found station of bssid %pM for rssi chain\n",
6570			   arvif->bssid);
6571		goto exit;
6572	}
6573
6574	arsta = ath11k_sta_to_arsta(sta);
6575
6576	BUILD_BUG_ON(ARRAY_SIZE(arsta->chain_signal) >
6577		     ARRAY_SIZE(stats_rssi->rssi_avg_beacon));
6578
6579	for (j = 0; j < ARRAY_SIZE(arsta->chain_signal); j++) {
6580		arsta->chain_signal[j] = stats_rssi->rssi_avg_beacon[j];
6581		ath11k_dbg(ab, ATH11K_DBG_WMI,
6582			   "stats beacon rssi[%d] %d data rssi[%d] %d\n",
6583			   j,
6584			   stats_rssi->rssi_avg_beacon[j],
6585			   j,
6586			   stats_rssi->rssi_avg_data[j]);
6587	}
6588
6589exit:
6590	rcu_read_unlock();
6591	return ret;
6592}
6593
6594static int ath11k_wmi_tlv_fw_stats_data_parse(struct ath11k_base *ab,
6595					      struct wmi_tlv_fw_stats_parse *parse,
6596					      const void *ptr,
6597					      u16 len)
6598{
6599	struct ath11k_fw_stats *stats = parse->stats;
6600	const struct wmi_stats_event *ev = parse->ev;
6601	struct ath11k *ar;
6602	struct ath11k_vif *arvif;
6603	struct ieee80211_sta *sta;
6604	struct ath11k_sta *arsta;
6605	int i, ret = 0;
6606	const void *data = ptr;
6607
6608	if (!ev) {
6609		ath11k_warn(ab, "failed to fetch update stats ev");
6610		return -EPROTO;
6611	}
6612
6613	stats->stats_id = 0;
6614
6615	rcu_read_lock();
6616
6617	ar = ath11k_mac_get_ar_by_pdev_id(ab, ev->pdev_id);
6618
6619	for (i = 0; i < ev->num_pdev_stats; i++) {
6620		const struct wmi_pdev_stats *src;
6621		struct ath11k_fw_stats_pdev *dst;
6622
6623		src = data;
6624		if (len < sizeof(*src)) {
6625			ret = -EPROTO;
6626			goto exit;
6627		}
6628
6629		stats->stats_id = WMI_REQUEST_PDEV_STAT;
6630
6631		data += sizeof(*src);
6632		len -= sizeof(*src);
6633
6634		dst = kzalloc(sizeof(*dst), GFP_ATOMIC);
6635		if (!dst)
6636			continue;
6637
6638		ath11k_wmi_pull_pdev_stats_base(&src->base, dst);
6639		ath11k_wmi_pull_pdev_stats_tx(&src->tx, dst);
6640		ath11k_wmi_pull_pdev_stats_rx(&src->rx, dst);
6641		list_add_tail(&dst->list, &stats->pdevs);
6642	}
6643
6644	for (i = 0; i < ev->num_vdev_stats; i++) {
6645		const struct wmi_vdev_stats *src;
6646		struct ath11k_fw_stats_vdev *dst;
6647
6648		src = data;
6649		if (len < sizeof(*src)) {
6650			ret = -EPROTO;
6651			goto exit;
6652		}
6653
6654		stats->stats_id = WMI_REQUEST_VDEV_STAT;
6655
6656		arvif = ath11k_mac_get_arvif(ar, src->vdev_id);
6657		if (arvif) {
6658			sta = ieee80211_find_sta_by_ifaddr(ar->hw,
6659							   arvif->bssid,
6660							   NULL);
6661			if (sta) {
6662				arsta = ath11k_sta_to_arsta(sta);
6663				arsta->rssi_beacon = src->beacon_snr;
6664				ath11k_dbg(ab, ATH11K_DBG_WMI,
6665					   "stats vdev id %d snr %d\n",
6666					   src->vdev_id, src->beacon_snr);
6667			} else {
6668				ath11k_dbg(ab, ATH11K_DBG_WMI,
6669					   "not found station of bssid %pM for vdev stat\n",
6670					   arvif->bssid);
6671			}
6672		}
6673
6674		data += sizeof(*src);
6675		len -= sizeof(*src);
6676
6677		dst = kzalloc(sizeof(*dst), GFP_ATOMIC);
6678		if (!dst)
6679			continue;
6680
6681		ath11k_wmi_pull_vdev_stats(src, dst);
6682		list_add_tail(&dst->list, &stats->vdevs);
6683	}
6684
6685	for (i = 0; i < ev->num_bcn_stats; i++) {
6686		const struct wmi_bcn_stats *src;
6687		struct ath11k_fw_stats_bcn *dst;
6688
6689		src = data;
6690		if (len < sizeof(*src)) {
6691			ret = -EPROTO;
6692			goto exit;
6693		}
6694
6695		stats->stats_id = WMI_REQUEST_BCN_STAT;
6696
6697		data += sizeof(*src);
6698		len -= sizeof(*src);
6699
6700		dst = kzalloc(sizeof(*dst), GFP_ATOMIC);
6701		if (!dst)
6702			continue;
6703
6704		ath11k_wmi_pull_bcn_stats(src, dst);
6705		list_add_tail(&dst->list, &stats->bcn);
6706	}
6707
6708exit:
6709	rcu_read_unlock();
6710	return ret;
6711}
6712
6713static int ath11k_wmi_tlv_fw_stats_parse(struct ath11k_base *ab,
6714					 u16 tag, u16 len,
6715					 const void *ptr, void *data)
6716{
6717	struct wmi_tlv_fw_stats_parse *parse = data;
6718	int ret = 0;
6719
6720	switch (tag) {
6721	case WMI_TAG_STATS_EVENT:
6722		parse->ev = (struct wmi_stats_event *)ptr;
6723		parse->stats->pdev_id = parse->ev->pdev_id;
6724		break;
6725	case WMI_TAG_ARRAY_BYTE:
6726		ret = ath11k_wmi_tlv_fw_stats_data_parse(ab, parse, ptr, len);
6727		break;
6728	case WMI_TAG_PER_CHAIN_RSSI_STATS:
6729		parse->rssi = (struct wmi_per_chain_rssi_stats *)ptr;
6730
6731		if (parse->ev->stats_id & WMI_REQUEST_RSSI_PER_CHAIN_STAT)
6732			parse->rssi_num = parse->rssi->num_per_chain_rssi_stats;
6733
6734		ath11k_dbg(ab, ATH11K_DBG_WMI,
6735			   "stats id 0x%x num chain %d\n",
6736			   parse->ev->stats_id,
6737			   parse->rssi_num);
6738		break;
6739	case WMI_TAG_ARRAY_STRUCT:
6740		if (parse->rssi_num && !parse->chain_rssi_done) {
6741			ret = ath11k_wmi_tlv_iter(ab, ptr, len,
6742						  ath11k_wmi_tlv_rssi_chain_parse,
6743						  parse);
6744			if (ret) {
6745				ath11k_warn(ab, "failed to parse rssi chain %d\n",
6746					    ret);
6747				return ret;
6748			}
6749			parse->chain_rssi_done = true;
6750		}
6751		break;
6752	default:
6753		break;
6754	}
6755	return ret;
6756}
6757
6758int ath11k_wmi_pull_fw_stats(struct ath11k_base *ab, struct sk_buff *skb,
6759			     struct ath11k_fw_stats *stats)
6760{
6761	struct wmi_tlv_fw_stats_parse parse = { };
6762
6763	stats->stats_id = 0;
6764	parse.stats = stats;
6765
6766	return ath11k_wmi_tlv_iter(ab, skb->data, skb->len,
6767				   ath11k_wmi_tlv_fw_stats_parse,
6768				   &parse);
6769}
6770
6771static void
6772ath11k_wmi_fw_pdev_base_stats_fill(const struct ath11k_fw_stats_pdev *pdev,
6773				   char *buf, u32 *length)
6774{
6775	u32 len = *length;
6776	u32 buf_len = ATH11K_FW_STATS_BUF_SIZE;
6777
6778	len += scnprintf(buf + len, buf_len - len, "\n");
6779	len += scnprintf(buf + len, buf_len - len, "%30s\n",
6780			"ath11k PDEV stats");
6781	len += scnprintf(buf + len, buf_len - len, "%30s\n\n",
6782			"=================");
6783
6784	len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
6785			"Channel noise floor", pdev->ch_noise_floor);
6786	len += scnprintf(buf + len, buf_len - len, "%30s %10u\n",
6787			"Channel TX power", pdev->chan_tx_power);
6788	len += scnprintf(buf + len, buf_len - len, "%30s %10u\n",
6789			"TX frame count", pdev->tx_frame_count);
6790	len += scnprintf(buf + len, buf_len - len, "%30s %10u\n",
6791			"RX frame count", pdev->rx_frame_count);
6792	len += scnprintf(buf + len, buf_len - len, "%30s %10u\n",
6793			"RX clear count", pdev->rx_clear_count);
6794	len += scnprintf(buf + len, buf_len - len, "%30s %10u\n",
6795			"Cycle count", pdev->cycle_count);
6796	len += scnprintf(buf + len, buf_len - len, "%30s %10u\n",
6797			"PHY error count", pdev->phy_err_count);
6798
6799	*length = len;
6800}
6801
6802static void
6803ath11k_wmi_fw_pdev_tx_stats_fill(const struct ath11k_fw_stats_pdev *pdev,
6804				 char *buf, u32 *length)
6805{
6806	u32 len = *length;
6807	u32 buf_len = ATH11K_FW_STATS_BUF_SIZE;
6808
6809	len += scnprintf(buf + len, buf_len - len, "\n%30s\n",
6810			 "ath11k PDEV TX stats");
6811	len += scnprintf(buf + len, buf_len - len, "%30s\n\n",
6812			 "====================");
6813
6814	len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
6815			 "HTT cookies queued", pdev->comp_queued);
6816	len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
6817			 "HTT cookies disp.", pdev->comp_delivered);
6818	len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
6819			 "MSDU queued", pdev->msdu_enqued);
6820	len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
6821			 "MPDU queued", pdev->mpdu_enqued);
6822	len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
6823			 "MSDUs dropped", pdev->wmm_drop);
6824	len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
6825			 "Local enqued", pdev->local_enqued);
6826	len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
6827			 "Local freed", pdev->local_freed);
6828	len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
6829			 "HW queued", pdev->hw_queued);
6830	len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
6831			 "PPDUs reaped", pdev->hw_reaped);
6832	len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
6833			 "Num underruns", pdev->underrun);
6834	len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
6835			 "Num HW Paused", pdev->hw_paused);
6836	len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
6837			 "PPDUs cleaned", pdev->tx_abort);
6838	len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
6839			 "MPDUs requeued", pdev->mpdus_requeued);
6840	len += scnprintf(buf + len, buf_len - len, "%30s %10u\n",
6841			 "PPDU OK", pdev->tx_ko);
6842	len += scnprintf(buf + len, buf_len - len, "%30s %10u\n",
6843			 "Excessive retries", pdev->tx_xretry);
6844	len += scnprintf(buf + len, buf_len - len, "%30s %10u\n",
6845			 "HW rate", pdev->data_rc);
6846	len += scnprintf(buf + len, buf_len - len, "%30s %10u\n",
6847			 "Sched self triggers", pdev->self_triggers);
6848	len += scnprintf(buf + len, buf_len - len, "%30s %10u\n",
6849			 "Dropped due to SW retries",
6850			 pdev->sw_retry_failure);
6851	len += scnprintf(buf + len, buf_len - len, "%30s %10u\n",
6852			 "Illegal rate phy errors",
6853			 pdev->illgl_rate_phy_err);
6854	len += scnprintf(buf + len, buf_len - len, "%30s %10u\n",
6855			 "PDEV continuous xretry", pdev->pdev_cont_xretry);
6856	len += scnprintf(buf + len, buf_len - len, "%30s %10u\n",
6857			 "TX timeout", pdev->pdev_tx_timeout);
6858	len += scnprintf(buf + len, buf_len - len, "%30s %10u\n",
6859			 "PDEV resets", pdev->pdev_resets);
6860	len += scnprintf(buf + len, buf_len - len, "%30s %10u\n",
6861			 "Stateless TIDs alloc failures",
6862			 pdev->stateless_tid_alloc_failure);
6863	len += scnprintf(buf + len, buf_len - len, "%30s %10u\n",
6864			 "PHY underrun", pdev->phy_underrun);
6865	len += scnprintf(buf + len, buf_len - len, "%30s %10u\n",
6866			 "MPDU is more than txop limit", pdev->txop_ovf);
6867	len += scnprintf(buf + len, buf_len - len, "%30s %10u\n",
6868			 "Num sequences posted", pdev->seq_posted);
6869	len += scnprintf(buf + len, buf_len - len, "%30s %10u\n",
6870			 "Num seq failed queueing ", pdev->seq_failed_queueing);
6871	len += scnprintf(buf + len, buf_len - len, "%30s %10u\n",
6872			 "Num sequences completed ", pdev->seq_completed);
6873	len += scnprintf(buf + len, buf_len - len, "%30s %10u\n",
6874			 "Num sequences restarted ", pdev->seq_restarted);
6875	len += scnprintf(buf + len, buf_len - len, "%30s %10u\n",
6876			 "Num of MU sequences posted ", pdev->mu_seq_posted);
6877	len += scnprintf(buf + len, buf_len - len, "%30s %10u\n",
6878			 "Num of MPDUS SW flushed ", pdev->mpdus_sw_flush);
6879	len += scnprintf(buf + len, buf_len - len, "%30s %10u\n",
6880			 "Num of MPDUS HW filtered ", pdev->mpdus_hw_filter);
6881	len += scnprintf(buf + len, buf_len - len, "%30s %10u\n",
6882			 "Num of MPDUS truncated ", pdev->mpdus_truncated);
6883	len += scnprintf(buf + len, buf_len - len, "%30s %10u\n",
6884			 "Num of MPDUS ACK failed ", pdev->mpdus_ack_failed);
6885	len += scnprintf(buf + len, buf_len - len, "%30s %10u\n",
6886			 "Num of MPDUS expired ", pdev->mpdus_expired);
6887	*length = len;
6888}
6889
6890static void
6891ath11k_wmi_fw_pdev_rx_stats_fill(const struct ath11k_fw_stats_pdev *pdev,
6892				 char *buf, u32 *length)
6893{
6894	u32 len = *length;
6895	u32 buf_len = ATH11K_FW_STATS_BUF_SIZE;
6896
6897	len += scnprintf(buf + len, buf_len - len, "\n%30s\n",
6898			 "ath11k PDEV RX stats");
6899	len += scnprintf(buf + len, buf_len - len, "%30s\n\n",
6900			 "====================");
6901
6902	len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
6903			 "Mid PPDU route change",
6904			 pdev->mid_ppdu_route_change);
6905	len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
6906			 "Tot. number of statuses", pdev->status_rcvd);
6907	len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
6908			 "Extra frags on rings 0", pdev->r0_frags);
6909	len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
6910			 "Extra frags on rings 1", pdev->r1_frags);
6911	len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
6912			 "Extra frags on rings 2", pdev->r2_frags);
6913	len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
6914			 "Extra frags on rings 3", pdev->r3_frags);
6915	len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
6916			 "MSDUs delivered to HTT", pdev->htt_msdus);
6917	len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
6918			 "MPDUs delivered to HTT", pdev->htt_mpdus);
6919	len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
6920			 "MSDUs delivered to stack", pdev->loc_msdus);
6921	len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
6922			 "MPDUs delivered to stack", pdev->loc_mpdus);
6923	len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
6924			 "Oversized AMSUs", pdev->oversize_amsdu);
6925	len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
6926			 "PHY errors", pdev->phy_errs);
6927	len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
6928			 "PHY errors drops", pdev->phy_err_drop);
6929	len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
6930			 "MPDU errors (FCS, MIC, ENC)", pdev->mpdu_errs);
6931	len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
6932			 "Overflow errors", pdev->rx_ovfl_errs);
6933	*length = len;
6934}
6935
6936static void
6937ath11k_wmi_fw_vdev_stats_fill(struct ath11k *ar,
6938			      const struct ath11k_fw_stats_vdev *vdev,
6939			      char *buf, u32 *length)
6940{
6941	u32 len = *length;
6942	u32 buf_len = ATH11K_FW_STATS_BUF_SIZE;
6943	struct ath11k_vif *arvif = ath11k_mac_get_arvif(ar, vdev->vdev_id);
6944	u8 *vif_macaddr;
6945	int i;
6946
6947	/* VDEV stats has all the active VDEVs of other PDEVs as well,
6948	 * ignoring those not part of requested PDEV
6949	 */
6950	if (!arvif)
6951		return;
6952
6953	vif_macaddr = arvif->vif->addr;
6954
6955	len += scnprintf(buf + len, buf_len - len, "%30s %u\n",
6956			 "VDEV ID", vdev->vdev_id);
6957	len += scnprintf(buf + len, buf_len - len, "%30s %pM\n",
6958			 "VDEV MAC address", vif_macaddr);
6959	len += scnprintf(buf + len, buf_len - len, "%30s %u\n",
6960			 "beacon snr", vdev->beacon_snr);
6961	len += scnprintf(buf + len, buf_len - len, "%30s %u\n",
6962			 "data snr", vdev->data_snr);
6963	len += scnprintf(buf + len, buf_len - len, "%30s %u\n",
6964			 "num rx frames", vdev->num_rx_frames);
6965	len += scnprintf(buf + len, buf_len - len, "%30s %u\n",
6966			 "num rts fail", vdev->num_rts_fail);
6967	len += scnprintf(buf + len, buf_len - len, "%30s %u\n",
6968			 "num rts success", vdev->num_rts_success);
6969	len += scnprintf(buf + len, buf_len - len, "%30s %u\n",
6970			 "num rx err", vdev->num_rx_err);
6971	len += scnprintf(buf + len, buf_len - len, "%30s %u\n",
6972			 "num rx discard", vdev->num_rx_discard);
6973	len += scnprintf(buf + len, buf_len - len, "%30s %u\n",
6974			 "num tx not acked", vdev->num_tx_not_acked);
6975
6976	for (i = 0 ; i < ARRAY_SIZE(vdev->num_tx_frames); i++)
6977		len += scnprintf(buf + len, buf_len - len,
6978				"%25s [%02d] %u\n",
6979				"num tx frames", i,
6980				vdev->num_tx_frames[i]);
6981
6982	for (i = 0 ; i < ARRAY_SIZE(vdev->num_tx_frames_retries); i++)
6983		len += scnprintf(buf + len, buf_len - len,
6984				"%25s [%02d] %u\n",
6985				"num tx frames retries", i,
6986				vdev->num_tx_frames_retries[i]);
6987
6988	for (i = 0 ; i < ARRAY_SIZE(vdev->num_tx_frames_failures); i++)
6989		len += scnprintf(buf + len, buf_len - len,
6990				"%25s [%02d] %u\n",
6991				"num tx frames failures", i,
6992				vdev->num_tx_frames_failures[i]);
6993
6994	for (i = 0 ; i < ARRAY_SIZE(vdev->tx_rate_history); i++)
6995		len += scnprintf(buf + len, buf_len - len,
6996				"%25s [%02d] 0x%08x\n",
6997				"tx rate history", i,
6998				vdev->tx_rate_history[i]);
6999
7000	for (i = 0 ; i < ARRAY_SIZE(vdev->beacon_rssi_history); i++)
7001		len += scnprintf(buf + len, buf_len - len,
7002				"%25s [%02d] %u\n",
7003				"beacon rssi history", i,
7004				vdev->beacon_rssi_history[i]);
7005
7006	len += scnprintf(buf + len, buf_len - len, "\n");
7007	*length = len;
7008}
7009
7010static void
7011ath11k_wmi_fw_bcn_stats_fill(struct ath11k *ar,
7012			     const struct ath11k_fw_stats_bcn *bcn,
7013			     char *buf, u32 *length)
7014{
7015	u32 len = *length;
7016	u32 buf_len = ATH11K_FW_STATS_BUF_SIZE;
7017	struct ath11k_vif *arvif = ath11k_mac_get_arvif(ar, bcn->vdev_id);
7018	u8 *vdev_macaddr;
7019
7020	if (!arvif) {
7021		ath11k_warn(ar->ab, "invalid vdev id %d in bcn stats",
7022			    bcn->vdev_id);
7023		return;
7024	}
7025
7026	vdev_macaddr = arvif->vif->addr;
7027
7028	len += scnprintf(buf + len, buf_len - len, "%30s %u\n",
7029			 "VDEV ID", bcn->vdev_id);
7030	len += scnprintf(buf + len, buf_len - len, "%30s %pM\n",
7031			 "VDEV MAC address", vdev_macaddr);
7032	len += scnprintf(buf + len, buf_len - len, "%30s\n\n",
7033			 "================");
7034	len += scnprintf(buf + len, buf_len - len, "%30s %u\n",
7035			 "Num of beacon tx success", bcn->tx_bcn_succ_cnt);
7036	len += scnprintf(buf + len, buf_len - len, "%30s %u\n",
7037			 "Num of beacon tx failures", bcn->tx_bcn_outage_cnt);
7038
7039	len += scnprintf(buf + len, buf_len - len, "\n");
7040	*length = len;
7041}
7042
7043void ath11k_wmi_fw_stats_fill(struct ath11k *ar,
7044			      struct ath11k_fw_stats *fw_stats,
7045			      u32 stats_id, char *buf)
7046{
7047	u32 len = 0;
7048	u32 buf_len = ATH11K_FW_STATS_BUF_SIZE;
7049	const struct ath11k_fw_stats_pdev *pdev;
7050	const struct ath11k_fw_stats_vdev *vdev;
7051	const struct ath11k_fw_stats_bcn *bcn;
7052	size_t num_bcn;
7053
7054	spin_lock_bh(&ar->data_lock);
7055
7056	if (stats_id == WMI_REQUEST_PDEV_STAT) {
7057		pdev = list_first_entry_or_null(&fw_stats->pdevs,
7058						struct ath11k_fw_stats_pdev, list);
7059		if (!pdev) {
7060			ath11k_warn(ar->ab, "failed to get pdev stats\n");
7061			goto unlock;
7062		}
7063
7064		ath11k_wmi_fw_pdev_base_stats_fill(pdev, buf, &len);
7065		ath11k_wmi_fw_pdev_tx_stats_fill(pdev, buf, &len);
7066		ath11k_wmi_fw_pdev_rx_stats_fill(pdev, buf, &len);
7067	}
7068
7069	if (stats_id == WMI_REQUEST_VDEV_STAT) {
7070		len += scnprintf(buf + len, buf_len - len, "\n");
7071		len += scnprintf(buf + len, buf_len - len, "%30s\n",
7072				 "ath11k VDEV stats");
7073		len += scnprintf(buf + len, buf_len - len, "%30s\n\n",
7074				 "=================");
7075
7076		list_for_each_entry(vdev, &fw_stats->vdevs, list)
7077			ath11k_wmi_fw_vdev_stats_fill(ar, vdev, buf, &len);
7078	}
7079
7080	if (stats_id == WMI_REQUEST_BCN_STAT) {
7081		num_bcn = list_count_nodes(&fw_stats->bcn);
7082
7083		len += scnprintf(buf + len, buf_len - len, "\n");
7084		len += scnprintf(buf + len, buf_len - len, "%30s (%zu)\n",
7085				 "ath11k Beacon stats", num_bcn);
7086		len += scnprintf(buf + len, buf_len - len, "%30s\n\n",
7087				 "===================");
7088
7089		list_for_each_entry(bcn, &fw_stats->bcn, list)
7090			ath11k_wmi_fw_bcn_stats_fill(ar, bcn, buf, &len);
7091	}
7092
7093unlock:
7094	spin_unlock_bh(&ar->data_lock);
7095
7096	if (len >= buf_len)
7097		buf[len - 1] = 0;
7098	else
7099		buf[len] = 0;
7100}
7101
7102static void ath11k_wmi_op_ep_tx_credits(struct ath11k_base *ab)
7103{
7104	/* try to send pending beacons first. they take priority */
7105	wake_up(&ab->wmi_ab.tx_credits_wq);
7106}
7107
7108static int ath11k_reg_11d_new_cc_event(struct ath11k_base *ab, struct sk_buff *skb)
7109{
7110	const struct wmi_11d_new_cc_ev *ev;
7111	struct ath11k *ar;
7112	struct ath11k_pdev *pdev;
7113	const void **tb;
7114	int ret, i;
7115
7116	tb = ath11k_wmi_tlv_parse_alloc(ab, skb, GFP_ATOMIC);
7117	if (IS_ERR(tb)) {
7118		ret = PTR_ERR(tb);
7119		ath11k_warn(ab, "failed to parse tlv: %d\n", ret);
7120		return ret;
7121	}
7122
7123	ev = tb[WMI_TAG_11D_NEW_COUNTRY_EVENT];
7124	if (!ev) {
7125		kfree(tb);
7126		ath11k_warn(ab, "failed to fetch 11d new cc ev");
7127		return -EPROTO;
7128	}
7129
7130	spin_lock_bh(&ab->base_lock);
7131	memcpy(&ab->new_alpha2, &ev->new_alpha2, 2);
7132	spin_unlock_bh(&ab->base_lock);
7133
7134	ath11k_dbg(ab, ATH11K_DBG_WMI, "event 11d new cc %c%c\n",
7135		   ab->new_alpha2[0],
7136		   ab->new_alpha2[1]);
7137
7138	kfree(tb);
7139
7140	for (i = 0; i < ab->num_radios; i++) {
7141		pdev = &ab->pdevs[i];
7142		ar = pdev->ar;
7143		ar->state_11d = ATH11K_11D_IDLE;
7144		complete(&ar->completed_11d_scan);
7145	}
7146
7147	queue_work(ab->workqueue, &ab->update_11d_work);
7148
7149	return 0;
7150}
7151
7152static void ath11k_wmi_htc_tx_complete(struct ath11k_base *ab,
7153				       struct sk_buff *skb)
7154{
7155	struct ath11k_pdev_wmi *wmi = NULL;
7156	u32 i;
7157	u8 wmi_ep_count;
7158	u8 eid;
7159
7160	eid = ATH11K_SKB_CB(skb)->eid;
7161	dev_kfree_skb(skb);
7162
7163	if (eid >= ATH11K_HTC_EP_COUNT)
7164		return;
7165
7166	wmi_ep_count = ab->htc.wmi_ep_count;
7167	if (wmi_ep_count > ab->hw_params.max_radios)
7168		return;
7169
7170	for (i = 0; i < ab->htc.wmi_ep_count; i++) {
7171		if (ab->wmi_ab.wmi[i].eid == eid) {
7172			wmi = &ab->wmi_ab.wmi[i];
7173			break;
7174		}
7175	}
7176
7177	if (wmi)
7178		wake_up(&wmi->tx_ce_desc_wq);
7179}
7180
7181static int ath11k_reg_chan_list_event(struct ath11k_base *ab, struct sk_buff *skb,
7182				      enum wmi_reg_chan_list_cmd_type id)
7183{
7184	struct cur_regulatory_info *reg_info;
7185	int ret;
7186
7187	reg_info = kzalloc(sizeof(*reg_info), GFP_ATOMIC);
7188	if (!reg_info)
7189		return -ENOMEM;
7190
7191	if (id == WMI_REG_CHAN_LIST_CC_ID)
7192		ret = ath11k_pull_reg_chan_list_update_ev(ab, skb, reg_info);
7193	else
7194		ret = ath11k_pull_reg_chan_list_ext_update_ev(ab, skb, reg_info);
7195
7196	if (ret) {
7197		ath11k_warn(ab, "failed to extract regulatory info\n");
7198		goto mem_free;
7199	}
7200
7201	ret = ath11k_reg_handle_chan_list(ab, reg_info, IEEE80211_REG_UNSET_AP);
7202	if (ret) {
7203		ath11k_warn(ab, "failed to process regulatory info %d\n", ret);
7204		goto mem_free;
7205	}
7206
7207	kfree(reg_info);
7208	return 0;
7209
7210mem_free:
7211	ath11k_reg_reset_info(reg_info);
7212	kfree(reg_info);
7213	return ret;
7214}
7215
7216static int ath11k_wmi_tlv_rdy_parse(struct ath11k_base *ab, u16 tag, u16 len,
7217				    const void *ptr, void *data)
7218{
7219	struct wmi_tlv_rdy_parse *rdy_parse = data;
7220	struct wmi_ready_event fixed_param;
7221	struct wmi_mac_addr *addr_list;
7222	struct ath11k_pdev *pdev;
7223	u32 num_mac_addr;
7224	int i;
7225
7226	switch (tag) {
7227	case WMI_TAG_READY_EVENT:
7228		memset(&fixed_param, 0, sizeof(fixed_param));
7229		memcpy(&fixed_param, (struct wmi_ready_event *)ptr,
7230		       min_t(u16, sizeof(fixed_param), len));
7231		rdy_parse->num_extra_mac_addr =
7232			fixed_param.ready_event_min.num_extra_mac_addr;
7233
7234		ether_addr_copy(ab->mac_addr,
7235				fixed_param.ready_event_min.mac_addr.addr);
7236		ab->pktlog_defs_checksum = fixed_param.pktlog_defs_checksum;
7237		break;
7238	case WMI_TAG_ARRAY_FIXED_STRUCT:
7239		addr_list = (struct wmi_mac_addr *)ptr;
7240		num_mac_addr = rdy_parse->num_extra_mac_addr;
7241
7242		if (!(ab->num_radios > 1 && num_mac_addr >= ab->num_radios))
7243			break;
7244
7245		for (i = 0; i < ab->num_radios; i++) {
7246			pdev = &ab->pdevs[i];
7247			ether_addr_copy(pdev->mac_addr, addr_list[i].addr);
7248		}
7249		ab->pdevs_macaddr_valid = true;
7250		break;
7251	default:
7252		break;
7253	}
7254
7255	return 0;
7256}
7257
7258static int ath11k_ready_event(struct ath11k_base *ab, struct sk_buff *skb)
7259{
7260	struct wmi_tlv_rdy_parse rdy_parse = { };
7261	int ret;
7262
7263	ret = ath11k_wmi_tlv_iter(ab, skb->data, skb->len,
7264				  ath11k_wmi_tlv_rdy_parse, &rdy_parse);
7265	if (ret) {
7266		ath11k_warn(ab, "failed to parse tlv %d\n", ret);
7267		return ret;
7268	}
7269
7270	ath11k_dbg(ab, ATH11K_DBG_WMI, "event ready");
7271
7272	complete(&ab->wmi_ab.unified_ready);
7273	return 0;
7274}
7275
7276static void ath11k_peer_delete_resp_event(struct ath11k_base *ab, struct sk_buff *skb)
7277{
7278	struct wmi_peer_delete_resp_event peer_del_resp;
7279	struct ath11k *ar;
7280
7281	if (ath11k_pull_peer_del_resp_ev(ab, skb, &peer_del_resp) != 0) {
7282		ath11k_warn(ab, "failed to extract peer delete resp");
7283		return;
7284	}
7285
7286	ath11k_dbg(ab, ATH11K_DBG_WMI, "event peer delete resp");
7287
7288	rcu_read_lock();
7289	ar = ath11k_mac_get_ar_by_vdev_id(ab, peer_del_resp.vdev_id);
7290	if (!ar) {
7291		ath11k_warn(ab, "invalid vdev id in peer delete resp ev %d",
7292			    peer_del_resp.vdev_id);
7293		rcu_read_unlock();
7294		return;
7295	}
7296
7297	complete(&ar->peer_delete_done);
7298	rcu_read_unlock();
7299	ath11k_dbg(ab, ATH11K_DBG_WMI, "peer delete resp for vdev id %d addr %pM\n",
7300		   peer_del_resp.vdev_id, peer_del_resp.peer_macaddr.addr);
7301}
7302
7303static void ath11k_vdev_delete_resp_event(struct ath11k_base *ab,
7304					  struct sk_buff *skb)
7305{
7306	struct ath11k *ar;
7307	u32 vdev_id = 0;
7308
7309	if (ath11k_pull_vdev_del_resp_ev(ab, skb, &vdev_id) != 0) {
7310		ath11k_warn(ab, "failed to extract vdev delete resp");
7311		return;
7312	}
7313
7314	rcu_read_lock();
7315	ar = ath11k_mac_get_ar_by_vdev_id(ab, vdev_id);
7316	if (!ar) {
7317		ath11k_warn(ab, "invalid vdev id in vdev delete resp ev %d",
7318			    vdev_id);
7319		rcu_read_unlock();
7320		return;
7321	}
7322
7323	complete(&ar->vdev_delete_done);
7324
7325	rcu_read_unlock();
7326
7327	ath11k_dbg(ab, ATH11K_DBG_WMI, "event vdev delete resp for vdev id %d\n",
7328		   vdev_id);
7329}
7330
7331static inline const char *ath11k_wmi_vdev_resp_print(u32 vdev_resp_status)
7332{
7333	switch (vdev_resp_status) {
7334	case WMI_VDEV_START_RESPONSE_INVALID_VDEVID:
7335		return "invalid vdev id";
7336	case WMI_VDEV_START_RESPONSE_NOT_SUPPORTED:
7337		return "not supported";
7338	case WMI_VDEV_START_RESPONSE_DFS_VIOLATION:
7339		return "dfs violation";
7340	case WMI_VDEV_START_RESPONSE_INVALID_REGDOMAIN:
7341		return "invalid regdomain";
7342	default:
7343		return "unknown";
7344	}
7345}
7346
7347static void ath11k_vdev_start_resp_event(struct ath11k_base *ab, struct sk_buff *skb)
7348{
7349	struct wmi_vdev_start_resp_event vdev_start_resp;
7350	struct ath11k *ar;
7351	u32 status;
7352
7353	if (ath11k_pull_vdev_start_resp_tlv(ab, skb, &vdev_start_resp) != 0) {
7354		ath11k_warn(ab, "failed to extract vdev start resp");
7355		return;
7356	}
7357
7358	ath11k_dbg(ab, ATH11K_DBG_WMI, "event start resp event");
7359
7360	rcu_read_lock();
7361	ar = ath11k_mac_get_ar_by_vdev_id(ab, vdev_start_resp.vdev_id);
7362	if (!ar) {
7363		ath11k_warn(ab, "invalid vdev id in vdev start resp ev %d",
7364			    vdev_start_resp.vdev_id);
7365		rcu_read_unlock();
7366		return;
7367	}
7368
7369	ar->last_wmi_vdev_start_status = 0;
7370	ar->max_allowed_tx_power = vdev_start_resp.max_allowed_tx_power;
7371	status = vdev_start_resp.status;
7372
7373	if (WARN_ON_ONCE(status)) {
7374		ath11k_warn(ab, "vdev start resp error status %d (%s)\n",
7375			    status, ath11k_wmi_vdev_resp_print(status));
7376		ar->last_wmi_vdev_start_status = status;
7377	}
7378
7379	complete(&ar->vdev_setup_done);
7380
7381	rcu_read_unlock();
7382
7383	ath11k_dbg(ab, ATH11K_DBG_WMI, "vdev start resp for vdev id %d",
7384		   vdev_start_resp.vdev_id);
7385}
7386
7387static void ath11k_bcn_tx_status_event(struct ath11k_base *ab, struct sk_buff *skb)
7388{
7389	struct ath11k_vif *arvif;
7390	u32 vdev_id, tx_status;
7391
7392	if (ath11k_pull_bcn_tx_status_ev(ab, skb, &vdev_id, &tx_status) != 0) {
7393		ath11k_warn(ab, "failed to extract bcn tx status");
7394		return;
7395	}
7396
7397	ath11k_dbg(ab, ATH11K_DBG_WMI, "event offload bcn tx status");
7398
7399	rcu_read_lock();
7400	arvif = ath11k_mac_get_arvif_by_vdev_id(ab, vdev_id);
7401	if (!arvif) {
7402		ath11k_warn(ab, "invalid vdev id %d in bcn_tx_status",
7403			    vdev_id);
7404		rcu_read_unlock();
7405		return;
7406	}
7407
7408	queue_work(ab->workqueue, &arvif->bcn_tx_work);
7409
7410	rcu_read_unlock();
7411}
7412
7413static void ath11k_wmi_event_peer_sta_ps_state_chg(struct ath11k_base *ab,
7414						   struct sk_buff *skb)
7415{
7416	const struct wmi_peer_sta_ps_state_chg_event *ev;
7417	struct ieee80211_sta *sta;
7418	struct ath11k_peer *peer;
7419	struct ath11k *ar;
7420	struct ath11k_sta *arsta;
7421	const void **tb;
7422	enum ath11k_wmi_peer_ps_state peer_previous_ps_state;
7423	int ret;
7424
7425	tb = ath11k_wmi_tlv_parse_alloc(ab, skb, GFP_ATOMIC);
7426	if (IS_ERR(tb)) {
7427		ret = PTR_ERR(tb);
7428		ath11k_warn(ab, "failed to parse tlv: %d\n", ret);
7429		return;
7430	}
7431
7432	ev = tb[WMI_TAG_PEER_STA_PS_STATECHANGE_EVENT];
7433	if (!ev) {
7434		ath11k_warn(ab, "failed to fetch sta ps change ev");
7435		kfree(tb);
7436		return;
7437	}
7438
7439	ath11k_dbg(ab, ATH11K_DBG_WMI,
7440		   "event peer sta ps change ev addr %pM state %u sup_bitmap %x ps_valid %u ts %u\n",
7441		   ev->peer_macaddr.addr, ev->peer_ps_state,
7442		   ev->ps_supported_bitmap, ev->peer_ps_valid,
7443		   ev->peer_ps_timestamp);
7444
7445	rcu_read_lock();
7446
7447	spin_lock_bh(&ab->base_lock);
7448
7449	peer = ath11k_peer_find_by_addr(ab, ev->peer_macaddr.addr);
7450
7451	if (!peer) {
7452		spin_unlock_bh(&ab->base_lock);
7453		ath11k_warn(ab, "peer not found %pM\n", ev->peer_macaddr.addr);
7454		goto exit;
7455	}
7456
7457	ar = ath11k_mac_get_ar_by_vdev_id(ab, peer->vdev_id);
7458
7459	if (!ar) {
7460		spin_unlock_bh(&ab->base_lock);
7461		ath11k_warn(ab, "invalid vdev id in peer sta ps state change ev %d",
7462			    peer->vdev_id);
7463
7464		goto exit;
7465	}
7466
7467	sta = peer->sta;
7468
7469	spin_unlock_bh(&ab->base_lock);
7470
7471	if (!sta) {
7472		ath11k_warn(ab, "failed to find station entry %pM\n",
7473			    ev->peer_macaddr.addr);
7474		goto exit;
7475	}
7476
7477	arsta = ath11k_sta_to_arsta(sta);
7478
7479	spin_lock_bh(&ar->data_lock);
7480
7481	peer_previous_ps_state = arsta->peer_ps_state;
7482	arsta->peer_ps_state = ev->peer_ps_state;
7483	arsta->peer_current_ps_valid = !!ev->peer_ps_valid;
7484
7485	if (test_bit(WMI_TLV_SERVICE_PEER_POWER_SAVE_DURATION_SUPPORT,
7486		     ar->ab->wmi_ab.svc_map)) {
7487		if (!(ev->ps_supported_bitmap & WMI_PEER_PS_VALID) ||
7488		    !(ev->ps_supported_bitmap & WMI_PEER_PS_STATE_TIMESTAMP) ||
7489		    !ev->peer_ps_valid)
7490			goto out;
7491
7492		if (arsta->peer_ps_state == WMI_PEER_PS_STATE_ON) {
7493			arsta->ps_start_time = ev->peer_ps_timestamp;
7494			arsta->ps_start_jiffies = jiffies;
7495		} else if (arsta->peer_ps_state == WMI_PEER_PS_STATE_OFF &&
7496			   peer_previous_ps_state == WMI_PEER_PS_STATE_ON) {
7497			arsta->ps_total_duration = arsta->ps_total_duration +
7498					(ev->peer_ps_timestamp - arsta->ps_start_time);
7499		}
7500
7501		if (ar->ps_timekeeper_enable)
7502			trace_ath11k_ps_timekeeper(ar, ev->peer_macaddr.addr,
7503						   ev->peer_ps_timestamp,
7504						   arsta->peer_ps_state);
7505	}
7506
7507out:
7508	spin_unlock_bh(&ar->data_lock);
7509exit:
7510	rcu_read_unlock();
7511	kfree(tb);
7512}
7513
7514static void ath11k_vdev_stopped_event(struct ath11k_base *ab, struct sk_buff *skb)
7515{
7516	struct ath11k *ar;
7517	u32 vdev_id = 0;
7518
7519	if (ath11k_pull_vdev_stopped_param_tlv(ab, skb, &vdev_id) != 0) {
7520		ath11k_warn(ab, "failed to extract vdev stopped event");
7521		return;
7522	}
7523
7524	ath11k_dbg(ab, ATH11K_DBG_WMI, "event vdev stopped");
7525
7526	rcu_read_lock();
7527	ar = ath11k_mac_get_ar_by_vdev_id(ab, vdev_id);
7528	if (!ar) {
7529		ath11k_warn(ab, "invalid vdev id in vdev stopped ev %d",
7530			    vdev_id);
7531		rcu_read_unlock();
7532		return;
7533	}
7534
7535	complete(&ar->vdev_setup_done);
7536
7537	rcu_read_unlock();
7538
7539	ath11k_dbg(ab, ATH11K_DBG_WMI, "vdev stopped for vdev id %d", vdev_id);
7540}
7541
7542static void ath11k_mgmt_rx_event(struct ath11k_base *ab, struct sk_buff *skb)
7543{
7544	struct mgmt_rx_event_params rx_ev = {0};
7545	struct ath11k *ar;
7546	struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb);
7547	struct ieee80211_hdr *hdr;
7548	u16 fc;
7549	struct ieee80211_supported_band *sband;
7550
7551	if (ath11k_pull_mgmt_rx_params_tlv(ab, skb, &rx_ev) != 0) {
7552		ath11k_warn(ab, "failed to extract mgmt rx event");
7553		dev_kfree_skb(skb);
7554		return;
7555	}
7556
7557	memset(status, 0, sizeof(*status));
7558
7559	ath11k_dbg(ab, ATH11K_DBG_MGMT, "event mgmt rx status %08x\n",
7560		   rx_ev.status);
7561
7562	rcu_read_lock();
7563	ar = ath11k_mac_get_ar_by_pdev_id(ab, rx_ev.pdev_id);
7564
7565	if (!ar) {
7566		ath11k_warn(ab, "invalid pdev_id %d in mgmt_rx_event\n",
7567			    rx_ev.pdev_id);
7568		dev_kfree_skb(skb);
7569		goto exit;
7570	}
7571
7572	if ((test_bit(ATH11K_CAC_RUNNING, &ar->dev_flags)) ||
7573	    (rx_ev.status & (WMI_RX_STATUS_ERR_DECRYPT |
7574	    WMI_RX_STATUS_ERR_KEY_CACHE_MISS | WMI_RX_STATUS_ERR_CRC))) {
7575		dev_kfree_skb(skb);
7576		goto exit;
7577	}
7578
7579	if (rx_ev.status & WMI_RX_STATUS_ERR_MIC)
7580		status->flag |= RX_FLAG_MMIC_ERROR;
7581
7582	if (rx_ev.chan_freq >= ATH11K_MIN_6G_FREQ &&
7583	    rx_ev.chan_freq <= ATH11K_MAX_6G_FREQ) {
7584		status->band = NL80211_BAND_6GHZ;
7585		status->freq = rx_ev.chan_freq;
7586	} else if (rx_ev.channel >= 1 && rx_ev.channel <= 14) {
7587		status->band = NL80211_BAND_2GHZ;
7588	} else if (rx_ev.channel >= 36 && rx_ev.channel <= ATH11K_MAX_5G_CHAN) {
7589		status->band = NL80211_BAND_5GHZ;
7590	} else {
7591		/* Shouldn't happen unless list of advertised channels to
7592		 * mac80211 has been changed.
7593		 */
7594		WARN_ON_ONCE(1);
7595		dev_kfree_skb(skb);
7596		goto exit;
7597	}
7598
7599	if (rx_ev.phy_mode == MODE_11B &&
7600	    (status->band == NL80211_BAND_5GHZ || status->band == NL80211_BAND_6GHZ))
7601		ath11k_dbg(ab, ATH11K_DBG_WMI,
7602			   "mgmt rx 11b (CCK) on 5/6GHz, band = %d\n", status->band);
7603
7604	sband = &ar->mac.sbands[status->band];
7605
7606	if (status->band != NL80211_BAND_6GHZ)
7607		status->freq = ieee80211_channel_to_frequency(rx_ev.channel,
7608							      status->band);
7609
7610	status->signal = rx_ev.snr + ATH11K_DEFAULT_NOISE_FLOOR;
7611	status->rate_idx = ath11k_mac_bitrate_to_idx(sband, rx_ev.rate / 100);
7612
7613	hdr = (struct ieee80211_hdr *)skb->data;
7614	fc = le16_to_cpu(hdr->frame_control);
7615
7616	/* Firmware is guaranteed to report all essential management frames via
7617	 * WMI while it can deliver some extra via HTT. Since there can be
7618	 * duplicates split the reporting wrt monitor/sniffing.
7619	 */
7620	status->flag |= RX_FLAG_SKIP_MONITOR;
7621
7622	/* In case of PMF, FW delivers decrypted frames with Protected Bit set.
7623	 * Don't clear that. Also, FW delivers broadcast management frames
7624	 * (ex: group privacy action frames in mesh) as encrypted payload.
7625	 */
7626	if (ieee80211_has_protected(hdr->frame_control) &&
7627	    !is_multicast_ether_addr(ieee80211_get_DA(hdr))) {
7628		status->flag |= RX_FLAG_DECRYPTED;
7629
7630		if (!ieee80211_is_robust_mgmt_frame(skb)) {
7631			status->flag |= RX_FLAG_IV_STRIPPED |
7632					RX_FLAG_MMIC_STRIPPED;
7633			hdr->frame_control = __cpu_to_le16(fc &
7634					     ~IEEE80211_FCTL_PROTECTED);
7635		}
7636	}
7637
7638	if (ieee80211_is_beacon(hdr->frame_control))
7639		ath11k_mac_handle_beacon(ar, skb);
7640
7641	ath11k_dbg(ab, ATH11K_DBG_MGMT,
7642		   "event mgmt rx skb %p len %d ftype %02x stype %02x\n",
7643		   skb, skb->len,
7644		   fc & IEEE80211_FCTL_FTYPE, fc & IEEE80211_FCTL_STYPE);
7645
7646	ath11k_dbg(ab, ATH11K_DBG_MGMT,
7647		   "event mgmt rx freq %d band %d snr %d, rate_idx %d\n",
7648		   status->freq, status->band, status->signal,
7649		   status->rate_idx);
7650
7651	ieee80211_rx_ni(ar->hw, skb);
7652
7653exit:
7654	rcu_read_unlock();
7655}
7656
7657static void ath11k_mgmt_tx_compl_event(struct ath11k_base *ab, struct sk_buff *skb)
7658{
7659	struct wmi_mgmt_tx_compl_event tx_compl_param = {0};
7660	struct ath11k *ar;
7661
7662	if (ath11k_pull_mgmt_tx_compl_param_tlv(ab, skb, &tx_compl_param) != 0) {
7663		ath11k_warn(ab, "failed to extract mgmt tx compl event");
7664		return;
7665	}
7666
7667	rcu_read_lock();
7668	ar = ath11k_mac_get_ar_by_pdev_id(ab, tx_compl_param.pdev_id);
7669	if (!ar) {
7670		ath11k_warn(ab, "invalid pdev id %d in mgmt_tx_compl_event\n",
7671			    tx_compl_param.pdev_id);
7672		goto exit;
7673	}
7674
7675	wmi_process_mgmt_tx_comp(ar, &tx_compl_param);
7676
7677	ath11k_dbg(ab, ATH11K_DBG_MGMT,
7678		   "event mgmt tx compl ev pdev_id %d, desc_id %d, status %d ack_rssi %d",
7679		   tx_compl_param.pdev_id, tx_compl_param.desc_id,
7680		   tx_compl_param.status, tx_compl_param.ack_rssi);
7681
7682exit:
7683	rcu_read_unlock();
7684}
7685
7686static struct ath11k *ath11k_get_ar_on_scan_state(struct ath11k_base *ab,
7687						  u32 vdev_id,
7688						  enum ath11k_scan_state state)
7689{
7690	int i;
7691	struct ath11k_pdev *pdev;
7692	struct ath11k *ar;
7693
7694	for (i = 0; i < ab->num_radios; i++) {
7695		pdev = rcu_dereference(ab->pdevs_active[i]);
7696		if (pdev && pdev->ar) {
7697			ar = pdev->ar;
7698
7699			spin_lock_bh(&ar->data_lock);
7700			if (ar->scan.state == state &&
7701			    ar->scan.vdev_id == vdev_id) {
7702				spin_unlock_bh(&ar->data_lock);
7703				return ar;
7704			}
7705			spin_unlock_bh(&ar->data_lock);
7706		}
7707	}
7708	return NULL;
7709}
7710
7711static void ath11k_scan_event(struct ath11k_base *ab, struct sk_buff *skb)
7712{
7713	struct ath11k *ar;
7714	struct wmi_scan_event scan_ev = {0};
7715
7716	if (ath11k_pull_scan_ev(ab, skb, &scan_ev) != 0) {
7717		ath11k_warn(ab, "failed to extract scan event");
7718		return;
7719	}
7720
7721	rcu_read_lock();
7722
7723	/* In case the scan was cancelled, ex. during interface teardown,
7724	 * the interface will not be found in active interfaces.
7725	 * Rather, in such scenarios, iterate over the active pdev's to
7726	 * search 'ar' if the corresponding 'ar' scan is ABORTING and the
7727	 * aborting scan's vdev id matches this event info.
7728	 */
7729	if (scan_ev.event_type == WMI_SCAN_EVENT_COMPLETED &&
7730	    scan_ev.reason == WMI_SCAN_REASON_CANCELLED) {
7731		ar = ath11k_get_ar_on_scan_state(ab, scan_ev.vdev_id,
7732						 ATH11K_SCAN_ABORTING);
7733		if (!ar)
7734			ar = ath11k_get_ar_on_scan_state(ab, scan_ev.vdev_id,
7735							 ATH11K_SCAN_RUNNING);
7736	} else {
7737		ar = ath11k_mac_get_ar_by_vdev_id(ab, scan_ev.vdev_id);
7738	}
7739
7740	if (!ar) {
7741		ath11k_warn(ab, "Received scan event for unknown vdev");
7742		rcu_read_unlock();
7743		return;
7744	}
7745
7746	spin_lock_bh(&ar->data_lock);
7747
7748	ath11k_dbg(ab, ATH11K_DBG_WMI,
7749		   "event scan %s type %d reason %d freq %d req_id %d scan_id %d vdev_id %d state %s (%d)\n",
7750		   ath11k_wmi_event_scan_type_str(scan_ev.event_type, scan_ev.reason),
7751		   scan_ev.event_type, scan_ev.reason, scan_ev.channel_freq,
7752		   scan_ev.scan_req_id, scan_ev.scan_id, scan_ev.vdev_id,
7753		   ath11k_scan_state_str(ar->scan.state), ar->scan.state);
7754
7755	switch (scan_ev.event_type) {
7756	case WMI_SCAN_EVENT_STARTED:
7757		ath11k_wmi_event_scan_started(ar);
7758		break;
7759	case WMI_SCAN_EVENT_COMPLETED:
7760		ath11k_wmi_event_scan_completed(ar);
7761		break;
7762	case WMI_SCAN_EVENT_BSS_CHANNEL:
7763		ath11k_wmi_event_scan_bss_chan(ar);
7764		break;
7765	case WMI_SCAN_EVENT_FOREIGN_CHAN:
7766		ath11k_wmi_event_scan_foreign_chan(ar, scan_ev.channel_freq);
7767		break;
7768	case WMI_SCAN_EVENT_START_FAILED:
7769		ath11k_warn(ab, "received scan start failure event\n");
7770		ath11k_wmi_event_scan_start_failed(ar);
7771		break;
7772	case WMI_SCAN_EVENT_DEQUEUED:
7773		__ath11k_mac_scan_finish(ar);
7774		break;
7775	case WMI_SCAN_EVENT_PREEMPTED:
7776	case WMI_SCAN_EVENT_RESTARTED:
7777	case WMI_SCAN_EVENT_FOREIGN_CHAN_EXIT:
7778	default:
7779		break;
7780	}
7781
7782	spin_unlock_bh(&ar->data_lock);
7783
7784	rcu_read_unlock();
7785}
7786
7787static void ath11k_peer_sta_kickout_event(struct ath11k_base *ab, struct sk_buff *skb)
7788{
7789	struct wmi_peer_sta_kickout_arg arg = {};
7790	struct ieee80211_sta *sta;
7791	struct ath11k_peer *peer;
7792	struct ath11k *ar;
7793	u32 vdev_id;
7794
7795	if (ath11k_pull_peer_sta_kickout_ev(ab, skb, &arg) != 0) {
7796		ath11k_warn(ab, "failed to extract peer sta kickout event");
7797		return;
7798	}
7799
7800	rcu_read_lock();
7801
7802	spin_lock_bh(&ab->base_lock);
7803
7804	peer = ath11k_peer_find_by_addr(ab, arg.mac_addr);
7805
7806	if (!peer) {
7807		ath11k_warn(ab, "peer not found %pM\n",
7808			    arg.mac_addr);
7809		spin_unlock_bh(&ab->base_lock);
7810		goto exit;
7811	}
7812
7813	vdev_id = peer->vdev_id;
7814
7815	spin_unlock_bh(&ab->base_lock);
7816
7817	ar = ath11k_mac_get_ar_by_vdev_id(ab, vdev_id);
7818	if (!ar) {
7819		ath11k_warn(ab, "invalid vdev id in peer sta kickout ev %d",
7820			    peer->vdev_id);
7821		goto exit;
7822	}
7823
7824	sta = ieee80211_find_sta_by_ifaddr(ar->hw,
7825					   arg.mac_addr, NULL);
7826	if (!sta) {
7827		ath11k_warn(ab, "Spurious quick kickout for STA %pM\n",
7828			    arg.mac_addr);
7829		goto exit;
7830	}
7831
7832	ath11k_dbg(ab, ATH11K_DBG_WMI, "event peer sta kickout %pM",
7833		   arg.mac_addr);
7834
7835	ieee80211_report_low_ack(sta, 10);
7836
7837exit:
7838	rcu_read_unlock();
7839}
7840
7841static void ath11k_roam_event(struct ath11k_base *ab, struct sk_buff *skb)
7842{
7843	struct wmi_roam_event roam_ev = {};
7844	struct ath11k *ar;
7845
7846	if (ath11k_pull_roam_ev(ab, skb, &roam_ev) != 0) {
7847		ath11k_warn(ab, "failed to extract roam event");
7848		return;
7849	}
7850
7851	ath11k_dbg(ab, ATH11K_DBG_WMI,
7852		   "event roam vdev %u reason 0x%08x rssi %d\n",
7853		   roam_ev.vdev_id, roam_ev.reason, roam_ev.rssi);
7854
7855	rcu_read_lock();
7856	ar = ath11k_mac_get_ar_by_vdev_id(ab, roam_ev.vdev_id);
7857	if (!ar) {
7858		ath11k_warn(ab, "invalid vdev id in roam ev %d",
7859			    roam_ev.vdev_id);
7860		rcu_read_unlock();
7861		return;
7862	}
7863
7864	if (roam_ev.reason >= WMI_ROAM_REASON_MAX)
7865		ath11k_warn(ab, "ignoring unknown roam event reason %d on vdev %i\n",
7866			    roam_ev.reason, roam_ev.vdev_id);
7867
7868	switch (roam_ev.reason) {
7869	case WMI_ROAM_REASON_BEACON_MISS:
7870		ath11k_mac_handle_beacon_miss(ar, roam_ev.vdev_id);
7871		break;
7872	case WMI_ROAM_REASON_BETTER_AP:
7873	case WMI_ROAM_REASON_LOW_RSSI:
7874	case WMI_ROAM_REASON_SUITABLE_AP_FOUND:
7875	case WMI_ROAM_REASON_HO_FAILED:
7876		ath11k_warn(ab, "ignoring not implemented roam event reason %d on vdev %i\n",
7877			    roam_ev.reason, roam_ev.vdev_id);
7878		break;
7879	}
7880
7881	rcu_read_unlock();
7882}
7883
7884static void ath11k_chan_info_event(struct ath11k_base *ab, struct sk_buff *skb)
7885{
7886	struct wmi_chan_info_event ch_info_ev = {0};
7887	struct ath11k *ar;
7888	struct survey_info *survey;
7889	int idx;
7890	/* HW channel counters frequency value in hertz */
7891	u32 cc_freq_hz = ab->cc_freq_hz;
7892
7893	if (ath11k_pull_chan_info_ev(ab, skb, &ch_info_ev) != 0) {
7894		ath11k_warn(ab, "failed to extract chan info event");
7895		return;
7896	}
7897
7898	ath11k_dbg(ab, ATH11K_DBG_WMI,
7899		   "event chan info vdev_id %d err_code %d freq %d cmd_flags %d noise_floor %d rx_clear_count %d cycle_count %d mac_clk_mhz %d\n",
7900		   ch_info_ev.vdev_id, ch_info_ev.err_code, ch_info_ev.freq,
7901		   ch_info_ev.cmd_flags, ch_info_ev.noise_floor,
7902		   ch_info_ev.rx_clear_count, ch_info_ev.cycle_count,
7903		   ch_info_ev.mac_clk_mhz);
7904
7905	if (ch_info_ev.cmd_flags == WMI_CHAN_INFO_END_RESP) {
7906		ath11k_dbg(ab, ATH11K_DBG_WMI, "chan info report completed\n");
7907		return;
7908	}
7909
7910	rcu_read_lock();
7911	ar = ath11k_mac_get_ar_by_vdev_id(ab, ch_info_ev.vdev_id);
7912	if (!ar) {
7913		ath11k_warn(ab, "invalid vdev id in chan info ev %d",
7914			    ch_info_ev.vdev_id);
7915		rcu_read_unlock();
7916		return;
7917	}
7918	spin_lock_bh(&ar->data_lock);
7919
7920	switch (ar->scan.state) {
7921	case ATH11K_SCAN_IDLE:
7922	case ATH11K_SCAN_STARTING:
7923		ath11k_warn(ab, "received chan info event without a scan request, ignoring\n");
7924		goto exit;
7925	case ATH11K_SCAN_RUNNING:
7926	case ATH11K_SCAN_ABORTING:
7927		break;
7928	}
7929
7930	idx = freq_to_idx(ar, ch_info_ev.freq);
7931	if (idx >= ARRAY_SIZE(ar->survey)) {
7932		ath11k_warn(ab, "chan info: invalid frequency %d (idx %d out of bounds)\n",
7933			    ch_info_ev.freq, idx);
7934		goto exit;
7935	}
7936
7937	/* If FW provides MAC clock frequency in Mhz, overriding the initialized
7938	 * HW channel counters frequency value
7939	 */
7940	if (ch_info_ev.mac_clk_mhz)
7941		cc_freq_hz = (ch_info_ev.mac_clk_mhz * 1000);
7942
7943	if (ch_info_ev.cmd_flags == WMI_CHAN_INFO_START_RESP) {
7944		survey = &ar->survey[idx];
7945		memset(survey, 0, sizeof(*survey));
7946		survey->noise = ch_info_ev.noise_floor;
7947		survey->filled = SURVEY_INFO_NOISE_DBM | SURVEY_INFO_TIME |
7948				 SURVEY_INFO_TIME_BUSY;
7949		survey->time = div_u64(ch_info_ev.cycle_count, cc_freq_hz);
7950		survey->time_busy = div_u64(ch_info_ev.rx_clear_count, cc_freq_hz);
7951	}
7952exit:
7953	spin_unlock_bh(&ar->data_lock);
7954	rcu_read_unlock();
7955}
7956
7957static void
7958ath11k_pdev_bss_chan_info_event(struct ath11k_base *ab, struct sk_buff *skb)
7959{
7960	struct wmi_pdev_bss_chan_info_event bss_ch_info_ev = {};
7961	struct survey_info *survey;
7962	struct ath11k *ar;
7963	u32 cc_freq_hz = ab->cc_freq_hz;
7964	u64 busy, total, tx, rx, rx_bss;
7965	int idx;
7966
7967	if (ath11k_pull_pdev_bss_chan_info_ev(ab, skb, &bss_ch_info_ev) != 0) {
7968		ath11k_warn(ab, "failed to extract pdev bss chan info event");
7969		return;
7970	}
7971
7972	busy = (u64)(bss_ch_info_ev.rx_clear_count_high) << 32 |
7973			bss_ch_info_ev.rx_clear_count_low;
7974
7975	total = (u64)(bss_ch_info_ev.cycle_count_high) << 32 |
7976			bss_ch_info_ev.cycle_count_low;
7977
7978	tx = (u64)(bss_ch_info_ev.tx_cycle_count_high) << 32 |
7979			bss_ch_info_ev.tx_cycle_count_low;
7980
7981	rx = (u64)(bss_ch_info_ev.rx_cycle_count_high) << 32 |
7982			bss_ch_info_ev.rx_cycle_count_low;
7983
7984	rx_bss = (u64)(bss_ch_info_ev.rx_bss_cycle_count_high) << 32 |
7985			bss_ch_info_ev.rx_bss_cycle_count_low;
7986
7987	ath11k_dbg(ab, ATH11K_DBG_WMI,
7988		   "event pdev bss chan info:\n pdev_id: %d freq: %d noise: %d cycle: busy %llu total %llu tx %llu rx %llu rx_bss %llu\n",
7989		   bss_ch_info_ev.pdev_id, bss_ch_info_ev.freq,
7990		   bss_ch_info_ev.noise_floor, busy, total,
7991		   tx, rx, rx_bss);
7992
7993	rcu_read_lock();
7994	ar = ath11k_mac_get_ar_by_pdev_id(ab, bss_ch_info_ev.pdev_id);
7995
7996	if (!ar) {
7997		ath11k_warn(ab, "invalid pdev id %d in bss_chan_info event\n",
7998			    bss_ch_info_ev.pdev_id);
7999		rcu_read_unlock();
8000		return;
8001	}
8002
8003	spin_lock_bh(&ar->data_lock);
8004	idx = freq_to_idx(ar, bss_ch_info_ev.freq);
8005	if (idx >= ARRAY_SIZE(ar->survey)) {
8006		ath11k_warn(ab, "bss chan info: invalid frequency %d (idx %d out of bounds)\n",
8007			    bss_ch_info_ev.freq, idx);
8008		goto exit;
8009	}
8010
8011	survey = &ar->survey[idx];
8012
8013	survey->noise     = bss_ch_info_ev.noise_floor;
8014	survey->time      = div_u64(total, cc_freq_hz);
8015	survey->time_busy = div_u64(busy, cc_freq_hz);
8016	survey->time_rx   = div_u64(rx_bss, cc_freq_hz);
8017	survey->time_tx   = div_u64(tx, cc_freq_hz);
8018	survey->filled   |= (SURVEY_INFO_NOISE_DBM |
8019			     SURVEY_INFO_TIME |
8020			     SURVEY_INFO_TIME_BUSY |
8021			     SURVEY_INFO_TIME_RX |
8022			     SURVEY_INFO_TIME_TX);
8023exit:
8024	spin_unlock_bh(&ar->data_lock);
8025	complete(&ar->bss_survey_done);
8026
8027	rcu_read_unlock();
8028}
8029
8030static void ath11k_vdev_install_key_compl_event(struct ath11k_base *ab,
8031						struct sk_buff *skb)
8032{
8033	struct wmi_vdev_install_key_complete_arg install_key_compl = {0};
8034	struct ath11k *ar;
8035
8036	if (ath11k_pull_vdev_install_key_compl_ev(ab, skb, &install_key_compl) != 0) {
8037		ath11k_warn(ab, "failed to extract install key compl event");
8038		return;
8039	}
8040
8041	ath11k_dbg(ab, ATH11K_DBG_WMI,
8042		   "event vdev install key ev idx %d flags %08x macaddr %pM status %d\n",
8043		   install_key_compl.key_idx, install_key_compl.key_flags,
8044		   install_key_compl.macaddr, install_key_compl.status);
8045
8046	rcu_read_lock();
8047	ar = ath11k_mac_get_ar_by_vdev_id(ab, install_key_compl.vdev_id);
8048	if (!ar) {
8049		ath11k_warn(ab, "invalid vdev id in install key compl ev %d",
8050			    install_key_compl.vdev_id);
8051		rcu_read_unlock();
8052		return;
8053	}
8054
8055	ar->install_key_status = 0;
8056
8057	if (install_key_compl.status != WMI_VDEV_INSTALL_KEY_COMPL_STATUS_SUCCESS) {
8058		ath11k_warn(ab, "install key failed for %pM status %d\n",
8059			    install_key_compl.macaddr, install_key_compl.status);
8060		ar->install_key_status = install_key_compl.status;
8061	}
8062
8063	complete(&ar->install_key_done);
8064	rcu_read_unlock();
8065}
8066
8067static int  ath11k_wmi_tlv_services_parser(struct ath11k_base *ab,
8068					   u16 tag, u16 len,
8069					   const void *ptr, void *data)
8070{
8071	const struct wmi_service_available_event *ev;
8072	u32 *wmi_ext2_service_bitmap;
8073	int i, j;
8074
8075	switch (tag) {
8076	case WMI_TAG_SERVICE_AVAILABLE_EVENT:
8077		ev = (struct wmi_service_available_event *)ptr;
8078		for (i = 0, j = WMI_MAX_SERVICE;
8079			i < WMI_SERVICE_SEGMENT_BM_SIZE32 && j < WMI_MAX_EXT_SERVICE;
8080			i++) {
8081			do {
8082				if (ev->wmi_service_segment_bitmap[i] &
8083				    BIT(j % WMI_AVAIL_SERVICE_BITS_IN_SIZE32))
8084					set_bit(j, ab->wmi_ab.svc_map);
8085			} while (++j % WMI_AVAIL_SERVICE_BITS_IN_SIZE32);
8086		}
8087
8088		ath11k_dbg(ab, ATH11K_DBG_WMI,
8089			   "wmi_ext_service_bitmap 0:0x%04x, 1:0x%04x, 2:0x%04x, 3:0x%04x",
8090			   ev->wmi_service_segment_bitmap[0],
8091			   ev->wmi_service_segment_bitmap[1],
8092			   ev->wmi_service_segment_bitmap[2],
8093			   ev->wmi_service_segment_bitmap[3]);
8094		break;
8095	case WMI_TAG_ARRAY_UINT32:
8096		wmi_ext2_service_bitmap = (u32 *)ptr;
8097		for (i = 0, j = WMI_MAX_EXT_SERVICE;
8098			i < WMI_SERVICE_SEGMENT_BM_SIZE32 && j < WMI_MAX_EXT2_SERVICE;
8099			i++) {
8100			do {
8101				if (wmi_ext2_service_bitmap[i] &
8102				    BIT(j % WMI_AVAIL_SERVICE_BITS_IN_SIZE32))
8103					set_bit(j, ab->wmi_ab.svc_map);
8104			} while (++j % WMI_AVAIL_SERVICE_BITS_IN_SIZE32);
8105		}
8106
8107		ath11k_dbg(ab, ATH11K_DBG_WMI,
8108			   "wmi_ext2_service__bitmap  0:0x%04x, 1:0x%04x, 2:0x%04x, 3:0x%04x",
8109			   wmi_ext2_service_bitmap[0], wmi_ext2_service_bitmap[1],
8110			   wmi_ext2_service_bitmap[2], wmi_ext2_service_bitmap[3]);
8111		break;
8112	}
8113	return 0;
8114}
8115
8116static void ath11k_service_available_event(struct ath11k_base *ab, struct sk_buff *skb)
8117{
8118	int ret;
8119
8120	ret = ath11k_wmi_tlv_iter(ab, skb->data, skb->len,
8121				  ath11k_wmi_tlv_services_parser,
8122				  NULL);
8123	if (ret)
8124		ath11k_warn(ab, "failed to parse services available tlv %d\n", ret);
8125
8126	ath11k_dbg(ab, ATH11K_DBG_WMI, "event service available");
8127}
8128
8129static void ath11k_peer_assoc_conf_event(struct ath11k_base *ab, struct sk_buff *skb)
8130{
8131	struct wmi_peer_assoc_conf_arg peer_assoc_conf = {0};
8132	struct ath11k *ar;
8133
8134	if (ath11k_pull_peer_assoc_conf_ev(ab, skb, &peer_assoc_conf) != 0) {
8135		ath11k_warn(ab, "failed to extract peer assoc conf event");
8136		return;
8137	}
8138
8139	ath11k_dbg(ab, ATH11K_DBG_WMI,
8140		   "event peer assoc conf ev vdev id %d macaddr %pM\n",
8141		   peer_assoc_conf.vdev_id, peer_assoc_conf.macaddr);
8142
8143	rcu_read_lock();
8144	ar = ath11k_mac_get_ar_by_vdev_id(ab, peer_assoc_conf.vdev_id);
8145
8146	if (!ar) {
8147		ath11k_warn(ab, "invalid vdev id in peer assoc conf ev %d",
8148			    peer_assoc_conf.vdev_id);
8149		rcu_read_unlock();
8150		return;
8151	}
8152
8153	complete(&ar->peer_assoc_done);
8154	rcu_read_unlock();
8155}
8156
8157static void ath11k_update_stats_event(struct ath11k_base *ab, struct sk_buff *skb)
8158{
8159	struct ath11k_fw_stats stats = {};
8160	struct ath11k *ar;
8161	int ret;
8162
8163	INIT_LIST_HEAD(&stats.pdevs);
8164	INIT_LIST_HEAD(&stats.vdevs);
8165	INIT_LIST_HEAD(&stats.bcn);
8166
8167	ret = ath11k_wmi_pull_fw_stats(ab, skb, &stats);
8168	if (ret) {
8169		ath11k_warn(ab, "failed to pull fw stats: %d\n", ret);
8170		goto free;
8171	}
8172
8173	ath11k_dbg(ab, ATH11K_DBG_WMI, "event update stats");
8174
8175	rcu_read_lock();
8176	ar = ath11k_mac_get_ar_by_pdev_id(ab, stats.pdev_id);
8177	if (!ar) {
8178		rcu_read_unlock();
8179		ath11k_warn(ab, "failed to get ar for pdev_id %d: %d\n",
8180			    stats.pdev_id, ret);
8181		goto free;
8182	}
8183
8184	spin_lock_bh(&ar->data_lock);
8185
8186	/* WMI_REQUEST_PDEV_STAT can be requested via .get_txpower mac ops or via
8187	 * debugfs fw stats. Therefore, processing it separately.
8188	 */
8189	if (stats.stats_id == WMI_REQUEST_PDEV_STAT) {
8190		list_splice_tail_init(&stats.pdevs, &ar->fw_stats.pdevs);
8191		ar->fw_stats_done = true;
8192		goto complete;
8193	}
8194
8195	/* WMI_REQUEST_VDEV_STAT, WMI_REQUEST_BCN_STAT and WMI_REQUEST_RSSI_PER_CHAIN_STAT
8196	 * are currently requested only via debugfs fw stats. Hence, processing these
8197	 * in debugfs context
8198	 */
8199	ath11k_debugfs_fw_stats_process(ar, &stats);
8200
8201complete:
8202	complete(&ar->fw_stats_complete);
8203	rcu_read_unlock();
8204	spin_unlock_bh(&ar->data_lock);
8205
8206	/* Since the stats's pdev, vdev and beacon list are spliced and reinitialised
8207	 * at this point, no need to free the individual list.
8208	 */
8209	return;
8210
8211free:
8212	ath11k_fw_stats_free(&stats);
8213}
8214
8215/* PDEV_CTL_FAILSAFE_CHECK_EVENT is received from FW when the frequency scanned
8216 * is not part of BDF CTL(Conformance test limits) table entries.
8217 */
8218static void ath11k_pdev_ctl_failsafe_check_event(struct ath11k_base *ab,
8219						 struct sk_buff *skb)
8220{
8221	const void **tb;
8222	const struct wmi_pdev_ctl_failsafe_chk_event *ev;
8223	int ret;
8224
8225	tb = ath11k_wmi_tlv_parse_alloc(ab, skb, GFP_ATOMIC);
8226	if (IS_ERR(tb)) {
8227		ret = PTR_ERR(tb);
8228		ath11k_warn(ab, "failed to parse tlv: %d\n", ret);
8229		return;
8230	}
8231
8232	ev = tb[WMI_TAG_PDEV_CTL_FAILSAFE_CHECK_EVENT];
8233	if (!ev) {
8234		ath11k_warn(ab, "failed to fetch pdev ctl failsafe check ev");
8235		kfree(tb);
8236		return;
8237	}
8238
8239	ath11k_dbg(ab, ATH11K_DBG_WMI,
8240		   "event pdev ctl failsafe check status %d\n",
8241		   ev->ctl_failsafe_status);
8242
8243	/* If ctl_failsafe_status is set to 1 FW will max out the Transmit power
8244	 * to 10 dBm else the CTL power entry in the BDF would be picked up.
8245	 */
8246	if (ev->ctl_failsafe_status != 0)
8247		ath11k_warn(ab, "pdev ctl failsafe failure status %d",
8248			    ev->ctl_failsafe_status);
8249
8250	kfree(tb);
8251}
8252
8253static void
8254ath11k_wmi_process_csa_switch_count_event(struct ath11k_base *ab,
8255					  const struct wmi_pdev_csa_switch_ev *ev,
8256					  const u32 *vdev_ids)
8257{
8258	int i;
8259	struct ath11k_vif *arvif;
8260
8261	/* Finish CSA once the switch count becomes NULL */
8262	if (ev->current_switch_count)
8263		return;
8264
8265	rcu_read_lock();
8266	for (i = 0; i < ev->num_vdevs; i++) {
8267		arvif = ath11k_mac_get_arvif_by_vdev_id(ab, vdev_ids[i]);
8268
8269		if (!arvif) {
8270			ath11k_warn(ab, "Recvd csa status for unknown vdev %d",
8271				    vdev_ids[i]);
8272			continue;
8273		}
8274
8275		if (arvif->is_up && arvif->vif->bss_conf.csa_active)
8276			ieee80211_csa_finish(arvif->vif, 0);
8277	}
8278	rcu_read_unlock();
8279}
8280
8281static void
8282ath11k_wmi_pdev_csa_switch_count_status_event(struct ath11k_base *ab,
8283					      struct sk_buff *skb)
8284{
8285	const void **tb;
8286	const struct wmi_pdev_csa_switch_ev *ev;
8287	const u32 *vdev_ids;
8288	int ret;
8289
8290	tb = ath11k_wmi_tlv_parse_alloc(ab, skb, GFP_ATOMIC);
8291	if (IS_ERR(tb)) {
8292		ret = PTR_ERR(tb);
8293		ath11k_warn(ab, "failed to parse tlv: %d\n", ret);
8294		return;
8295	}
8296
8297	ev = tb[WMI_TAG_PDEV_CSA_SWITCH_COUNT_STATUS_EVENT];
8298	vdev_ids = tb[WMI_TAG_ARRAY_UINT32];
8299
8300	if (!ev || !vdev_ids) {
8301		ath11k_warn(ab, "failed to fetch pdev csa switch count ev");
8302		kfree(tb);
8303		return;
8304	}
8305
8306	ath11k_dbg(ab, ATH11K_DBG_WMI,
8307		   "event pdev csa switch count %d for pdev %d, num_vdevs %d",
8308		   ev->current_switch_count, ev->pdev_id,
8309		   ev->num_vdevs);
8310
8311	ath11k_wmi_process_csa_switch_count_event(ab, ev, vdev_ids);
8312
8313	kfree(tb);
8314}
8315
8316static void
8317ath11k_wmi_pdev_dfs_radar_detected_event(struct ath11k_base *ab, struct sk_buff *skb)
8318{
8319	const void **tb;
8320	const struct wmi_pdev_radar_ev *ev;
8321	struct ath11k *ar;
8322	int ret;
8323
8324	tb = ath11k_wmi_tlv_parse_alloc(ab, skb, GFP_ATOMIC);
8325	if (IS_ERR(tb)) {
8326		ret = PTR_ERR(tb);
8327		ath11k_warn(ab, "failed to parse tlv: %d\n", ret);
8328		return;
8329	}
8330
8331	ev = tb[WMI_TAG_PDEV_DFS_RADAR_DETECTION_EVENT];
8332
8333	if (!ev) {
8334		ath11k_warn(ab, "failed to fetch pdev dfs radar detected ev");
8335		kfree(tb);
8336		return;
8337	}
8338
8339	ath11k_dbg(ab, ATH11K_DBG_WMI,
8340		   "event pdev dfs radar detected on pdev %d, detection mode %d, chan freq %d, chan_width %d, detector id %d, seg id %d, timestamp %d, chirp %d, freq offset %d, sidx %d",
8341		   ev->pdev_id, ev->detection_mode, ev->chan_freq, ev->chan_width,
8342		   ev->detector_id, ev->segment_id, ev->timestamp, ev->is_chirp,
8343		   ev->freq_offset, ev->sidx);
8344
8345	rcu_read_lock();
8346
8347	ar = ath11k_mac_get_ar_by_pdev_id(ab, ev->pdev_id);
8348
8349	if (!ar) {
8350		ath11k_warn(ab, "radar detected in invalid pdev %d\n",
8351			    ev->pdev_id);
8352		goto exit;
8353	}
8354
8355	ath11k_dbg(ar->ab, ATH11K_DBG_REG, "DFS Radar Detected in pdev %d\n",
8356		   ev->pdev_id);
8357
8358	if (ar->dfs_block_radar_events)
8359		ath11k_info(ab, "DFS Radar detected, but ignored as requested\n");
8360	else
8361		ieee80211_radar_detected(ar->hw, NULL);
8362
8363exit:
8364	rcu_read_unlock();
8365
8366	kfree(tb);
8367}
8368
8369static void
8370ath11k_wmi_pdev_temperature_event(struct ath11k_base *ab,
8371				  struct sk_buff *skb)
8372{
8373	struct ath11k *ar;
8374	const void **tb;
8375	const struct wmi_pdev_temperature_event *ev;
8376	int ret;
8377
8378	tb = ath11k_wmi_tlv_parse_alloc(ab, skb, GFP_ATOMIC);
8379	if (IS_ERR(tb)) {
8380		ret = PTR_ERR(tb);
8381		ath11k_warn(ab, "failed to parse tlv: %d\n", ret);
8382		return;
8383	}
8384
8385	ev = tb[WMI_TAG_PDEV_TEMPERATURE_EVENT];
8386	if (!ev) {
8387		ath11k_warn(ab, "failed to fetch pdev temp ev");
8388		kfree(tb);
8389		return;
8390	}
8391
8392	ath11k_dbg(ab, ATH11K_DBG_WMI, "event pdev temperature ev temp %d pdev_id %d\n",
8393		   ev->temp, ev->pdev_id);
8394
8395	rcu_read_lock();
8396
8397	ar = ath11k_mac_get_ar_by_pdev_id(ab, ev->pdev_id);
8398	if (!ar) {
8399		ath11k_warn(ab, "invalid pdev id in pdev temperature ev %d", ev->pdev_id);
8400		goto exit;
8401	}
8402
8403	ath11k_thermal_event_temperature(ar, ev->temp);
8404
8405exit:
8406	rcu_read_unlock();
8407
8408	kfree(tb);
8409}
8410
8411static void ath11k_fils_discovery_event(struct ath11k_base *ab,
8412					struct sk_buff *skb)
8413{
8414	const void **tb;
8415	const struct wmi_fils_discovery_event *ev;
8416	int ret;
8417
8418	tb = ath11k_wmi_tlv_parse_alloc(ab, skb, GFP_ATOMIC);
8419	if (IS_ERR(tb)) {
8420		ret = PTR_ERR(tb);
8421		ath11k_warn(ab,
8422			    "failed to parse FILS discovery event tlv %d\n",
8423			    ret);
8424		return;
8425	}
8426
8427	ath11k_dbg(ab, ATH11K_DBG_WMI, "event fils discovery");
8428
8429	ev = tb[WMI_TAG_HOST_SWFDA_EVENT];
8430	if (!ev) {
8431		ath11k_warn(ab, "failed to fetch FILS discovery event\n");
8432		kfree(tb);
8433		return;
8434	}
8435
8436	ath11k_warn(ab,
8437		    "FILS discovery frame expected from host for vdev_id: %u, transmission scheduled at %u, next TBTT: %u\n",
8438		    ev->vdev_id, ev->fils_tt, ev->tbtt);
8439
8440	kfree(tb);
8441}
8442
8443static void ath11k_probe_resp_tx_status_event(struct ath11k_base *ab,
8444					      struct sk_buff *skb)
8445{
8446	const void **tb;
8447	const struct wmi_probe_resp_tx_status_event *ev;
8448	int ret;
8449
8450	tb = ath11k_wmi_tlv_parse_alloc(ab, skb, GFP_ATOMIC);
8451	if (IS_ERR(tb)) {
8452		ret = PTR_ERR(tb);
8453		ath11k_warn(ab,
8454			    "failed to parse probe response transmission status event tlv: %d\n",
8455			    ret);
8456		return;
8457	}
8458
8459	ath11k_dbg(ab, ATH11K_DBG_WMI, "event probe resp tx status");
8460
8461	ev = tb[WMI_TAG_OFFLOAD_PRB_RSP_TX_STATUS_EVENT];
8462	if (!ev) {
8463		ath11k_warn(ab,
8464			    "failed to fetch probe response transmission status event");
8465		kfree(tb);
8466		return;
8467	}
8468
8469	if (ev->tx_status)
8470		ath11k_warn(ab,
8471			    "Probe response transmission failed for vdev_id %u, status %u\n",
8472			    ev->vdev_id, ev->tx_status);
8473
8474	kfree(tb);
8475}
8476
8477static int ath11k_wmi_tlv_wow_wakeup_host_parse(struct ath11k_base *ab,
8478						u16 tag, u16 len,
8479						const void *ptr, void *data)
8480{
8481	struct wmi_wow_ev_arg *ev = data;
8482	const char *wow_pg_fault;
8483	int wow_pg_len;
8484
8485	switch (tag) {
8486	case WMI_TAG_WOW_EVENT_INFO:
8487		memcpy(ev, ptr, sizeof(*ev));
8488		ath11k_dbg(ab, ATH11K_DBG_WMI, "wow wakeup host reason %d %s\n",
8489			   ev->wake_reason, wow_reason(ev->wake_reason));
8490		break;
8491
8492	case WMI_TAG_ARRAY_BYTE:
8493		if (ev && ev->wake_reason == WOW_REASON_PAGE_FAULT) {
8494			wow_pg_fault = ptr;
8495			/* the first 4 bytes are length */
8496			wow_pg_len = *(int *)wow_pg_fault;
8497			wow_pg_fault += sizeof(int);
8498			ath11k_dbg(ab, ATH11K_DBG_WMI, "wow data_len = %d\n",
8499				   wow_pg_len);
8500			ath11k_dbg_dump(ab, ATH11K_DBG_WMI,
8501					"wow_event_info_type packet present",
8502					"wow_pg_fault ",
8503					wow_pg_fault,
8504					wow_pg_len);
8505		}
8506		break;
8507	default:
8508		break;
8509	}
8510
8511	return 0;
8512}
8513
8514static void ath11k_wmi_event_wow_wakeup_host(struct ath11k_base *ab, struct sk_buff *skb)
8515{
8516	struct wmi_wow_ev_arg ev = { };
8517	int ret;
8518
8519	ret = ath11k_wmi_tlv_iter(ab, skb->data, skb->len,
8520				  ath11k_wmi_tlv_wow_wakeup_host_parse,
8521				  &ev);
8522	if (ret) {
8523		ath11k_warn(ab, "failed to parse wmi wow tlv: %d\n", ret);
8524		return;
8525	}
8526
8527	ath11k_dbg(ab, ATH11K_DBG_WMI, "event wow wakeup host");
8528
8529	complete(&ab->wow.wakeup_completed);
8530}
8531
8532static void
8533ath11k_wmi_diag_event(struct ath11k_base *ab,
8534		      struct sk_buff *skb)
8535{
8536	ath11k_dbg(ab, ATH11K_DBG_WMI, "event diag");
8537
8538	trace_ath11k_wmi_diag(ab, skb->data, skb->len);
8539}
8540
8541static const char *ath11k_wmi_twt_add_dialog_event_status(u32 status)
8542{
8543	switch (status) {
8544	case WMI_ADD_TWT_STATUS_OK:
8545		return "ok";
8546	case WMI_ADD_TWT_STATUS_TWT_NOT_ENABLED:
8547		return "twt disabled";
8548	case WMI_ADD_TWT_STATUS_USED_DIALOG_ID:
8549		return "dialog id in use";
8550	case WMI_ADD_TWT_STATUS_INVALID_PARAM:
8551		return "invalid parameters";
8552	case WMI_ADD_TWT_STATUS_NOT_READY:
8553		return "not ready";
8554	case WMI_ADD_TWT_STATUS_NO_RESOURCE:
8555		return "resource unavailable";
8556	case WMI_ADD_TWT_STATUS_NO_ACK:
8557		return "no ack";
8558	case WMI_ADD_TWT_STATUS_NO_RESPONSE:
8559		return "no response";
8560	case WMI_ADD_TWT_STATUS_DENIED:
8561		return "denied";
8562	case WMI_ADD_TWT_STATUS_UNKNOWN_ERROR:
8563		fallthrough;
8564	default:
8565		return "unknown error";
8566	}
8567}
8568
8569static void ath11k_wmi_twt_add_dialog_event(struct ath11k_base *ab,
8570					    struct sk_buff *skb)
8571{
8572	const void **tb;
8573	const struct wmi_twt_add_dialog_event *ev;
8574	int ret;
8575
8576	tb = ath11k_wmi_tlv_parse_alloc(ab, skb, GFP_ATOMIC);
8577	if (IS_ERR(tb)) {
8578		ret = PTR_ERR(tb);
8579		ath11k_warn(ab,
8580			    "failed to parse wmi twt add dialog status event tlv: %d\n",
8581			    ret);
8582		return;
8583	}
8584
8585	ath11k_dbg(ab, ATH11K_DBG_WMI, "event twt add dialog");
8586
8587	ev = tb[WMI_TAG_TWT_ADD_DIALOG_COMPLETE_EVENT];
8588	if (!ev) {
8589		ath11k_warn(ab, "failed to fetch twt add dialog wmi event\n");
8590		goto exit;
8591	}
8592
8593	if (ev->status)
8594		ath11k_warn(ab,
8595			    "wmi add twt dialog event vdev %d dialog id %d status %s\n",
8596			    ev->vdev_id, ev->dialog_id,
8597			    ath11k_wmi_twt_add_dialog_event_status(ev->status));
8598
8599exit:
8600	kfree(tb);
8601}
8602
8603static void ath11k_wmi_gtk_offload_status_event(struct ath11k_base *ab,
8604						struct sk_buff *skb)
8605{
8606	const void **tb;
8607	const struct wmi_gtk_offload_status_event *ev;
8608	struct ath11k_vif *arvif;
8609	__be64 replay_ctr_be;
8610	u64    replay_ctr;
8611	int ret;
8612
8613	tb = ath11k_wmi_tlv_parse_alloc(ab, skb, GFP_ATOMIC);
8614	if (IS_ERR(tb)) {
8615		ret = PTR_ERR(tb);
8616		ath11k_warn(ab, "failed to parse tlv: %d\n", ret);
8617		return;
8618	}
8619
8620	ev = tb[WMI_TAG_GTK_OFFLOAD_STATUS_EVENT];
8621	if (!ev) {
8622		ath11k_warn(ab, "failed to fetch gtk offload status ev");
8623		kfree(tb);
8624		return;
8625	}
8626
8627	rcu_read_lock();
8628
8629	arvif = ath11k_mac_get_arvif_by_vdev_id(ab, ev->vdev_id);
8630	if (!arvif) {
8631		ath11k_warn(ab, "failed to get arvif for vdev_id:%d\n",
8632			    ev->vdev_id);
8633		goto exit;
8634	}
8635
8636	ath11k_dbg(ab, ATH11K_DBG_WMI, "event gtk offload refresh_cnt %d\n",
8637		   ev->refresh_cnt);
8638	ath11k_dbg_dump(ab, ATH11K_DBG_WMI, "replay_cnt",
8639			NULL, ev->replay_ctr.counter, GTK_REPLAY_COUNTER_BYTES);
8640
8641	replay_ctr =  ev->replay_ctr.word1;
8642	replay_ctr = (replay_ctr << 32) | ev->replay_ctr.word0;
8643	arvif->rekey_data.replay_ctr = replay_ctr;
8644
8645	/* supplicant expects big-endian replay counter */
8646	replay_ctr_be = cpu_to_be64(replay_ctr);
8647
8648	ieee80211_gtk_rekey_notify(arvif->vif, arvif->bssid,
8649				   (void *)&replay_ctr_be, GFP_ATOMIC);
8650exit:
8651	rcu_read_unlock();
8652
8653	kfree(tb);
8654}
8655
8656static void ath11k_wmi_p2p_noa_event(struct ath11k_base *ab,
8657				     struct sk_buff *skb)
8658{
8659	const void **tb;
8660	const struct wmi_p2p_noa_event *ev;
8661	const struct ath11k_wmi_p2p_noa_info *noa;
8662	struct ath11k *ar;
8663	int vdev_id;
8664	u8 noa_descriptors;
8665
8666	tb = ath11k_wmi_tlv_parse_alloc(ab, skb, GFP_ATOMIC);
8667	if (IS_ERR(tb)) {
8668		ath11k_warn(ab, "failed to parse tlv: %ld\n", PTR_ERR(tb));
8669		return;
8670	}
8671
8672	ev = tb[WMI_TAG_P2P_NOA_EVENT];
8673	noa = tb[WMI_TAG_P2P_NOA_INFO];
8674
8675	if (!ev || !noa)
8676		goto out;
8677
8678	vdev_id = ev->vdev_id;
8679	noa_descriptors = u32_get_bits(noa->noa_attr,
8680				       WMI_P2P_NOA_INFO_DESC_NUM);
8681
8682	if (noa_descriptors > WMI_P2P_MAX_NOA_DESCRIPTORS) {
8683		ath11k_warn(ab, "invalid descriptor num %d in P2P NoA event\n",
8684			    noa_descriptors);
8685		goto out;
8686	}
8687
8688	ath11k_dbg(ab, ATH11K_DBG_WMI,
8689		   "wmi tlv p2p noa vdev_id %i descriptors %u\n",
8690		   vdev_id, noa_descriptors);
8691
8692	rcu_read_lock();
8693	ar = ath11k_mac_get_ar_by_vdev_id(ab, vdev_id);
8694	if (!ar) {
8695		ath11k_warn(ab, "invalid vdev id %d in P2P NoA event\n",
8696			    vdev_id);
8697		goto unlock;
8698	}
8699
8700	ath11k_p2p_noa_update_by_vdev_id(ar, vdev_id, noa);
8701
8702unlock:
8703	rcu_read_unlock();
8704out:
8705	kfree(tb);
8706}
8707
8708static void ath11k_wmi_tlv_op_rx(struct ath11k_base *ab, struct sk_buff *skb)
8709{
8710	struct wmi_cmd_hdr *cmd_hdr;
8711	enum wmi_tlv_event_id id;
8712
8713	cmd_hdr = (struct wmi_cmd_hdr *)skb->data;
8714	id = FIELD_GET(WMI_CMD_HDR_CMD_ID, (cmd_hdr->cmd_id));
8715
8716	trace_ath11k_wmi_event(ab, id, skb->data, skb->len);
8717
8718	if (skb_pull(skb, sizeof(struct wmi_cmd_hdr)) == NULL)
8719		goto out;
8720
8721	switch (id) {
8722		/* Process all the WMI events here */
8723	case WMI_SERVICE_READY_EVENTID:
8724		ath11k_service_ready_event(ab, skb);
8725		break;
8726	case WMI_SERVICE_READY_EXT_EVENTID:
8727		ath11k_service_ready_ext_event(ab, skb);
8728		break;
8729	case WMI_SERVICE_READY_EXT2_EVENTID:
8730		ath11k_service_ready_ext2_event(ab, skb);
8731		break;
8732	case WMI_REG_CHAN_LIST_CC_EVENTID:
8733		ath11k_reg_chan_list_event(ab, skb, WMI_REG_CHAN_LIST_CC_ID);
8734		break;
8735	case WMI_REG_CHAN_LIST_CC_EXT_EVENTID:
8736		ath11k_reg_chan_list_event(ab, skb, WMI_REG_CHAN_LIST_CC_EXT_ID);
8737		break;
8738	case WMI_READY_EVENTID:
8739		ath11k_ready_event(ab, skb);
8740		break;
8741	case WMI_PEER_DELETE_RESP_EVENTID:
8742		ath11k_peer_delete_resp_event(ab, skb);
8743		break;
8744	case WMI_VDEV_START_RESP_EVENTID:
8745		ath11k_vdev_start_resp_event(ab, skb);
8746		break;
8747	case WMI_OFFLOAD_BCN_TX_STATUS_EVENTID:
8748		ath11k_bcn_tx_status_event(ab, skb);
8749		break;
8750	case WMI_VDEV_STOPPED_EVENTID:
8751		ath11k_vdev_stopped_event(ab, skb);
8752		break;
8753	case WMI_MGMT_RX_EVENTID:
8754		ath11k_mgmt_rx_event(ab, skb);
8755		/* mgmt_rx_event() owns the skb now! */
8756		return;
8757	case WMI_MGMT_TX_COMPLETION_EVENTID:
8758		ath11k_mgmt_tx_compl_event(ab, skb);
8759		break;
8760	case WMI_SCAN_EVENTID:
8761		ath11k_scan_event(ab, skb);
8762		break;
8763	case WMI_PEER_STA_KICKOUT_EVENTID:
8764		ath11k_peer_sta_kickout_event(ab, skb);
8765		break;
8766	case WMI_ROAM_EVENTID:
8767		ath11k_roam_event(ab, skb);
8768		break;
8769	case WMI_CHAN_INFO_EVENTID:
8770		ath11k_chan_info_event(ab, skb);
8771		break;
8772	case WMI_PDEV_BSS_CHAN_INFO_EVENTID:
8773		ath11k_pdev_bss_chan_info_event(ab, skb);
8774		break;
8775	case WMI_VDEV_INSTALL_KEY_COMPLETE_EVENTID:
8776		ath11k_vdev_install_key_compl_event(ab, skb);
8777		break;
8778	case WMI_SERVICE_AVAILABLE_EVENTID:
8779		ath11k_service_available_event(ab, skb);
8780		break;
8781	case WMI_PEER_ASSOC_CONF_EVENTID:
8782		ath11k_peer_assoc_conf_event(ab, skb);
8783		break;
8784	case WMI_UPDATE_STATS_EVENTID:
8785		ath11k_update_stats_event(ab, skb);
8786		break;
8787	case WMI_PDEV_CTL_FAILSAFE_CHECK_EVENTID:
8788		ath11k_pdev_ctl_failsafe_check_event(ab, skb);
8789		break;
8790	case WMI_PDEV_CSA_SWITCH_COUNT_STATUS_EVENTID:
8791		ath11k_wmi_pdev_csa_switch_count_status_event(ab, skb);
8792		break;
8793	case WMI_PDEV_UTF_EVENTID:
8794		ath11k_tm_wmi_event(ab, id, skb);
8795		break;
8796	case WMI_PDEV_TEMPERATURE_EVENTID:
8797		ath11k_wmi_pdev_temperature_event(ab, skb);
8798		break;
8799	case WMI_PDEV_DMA_RING_BUF_RELEASE_EVENTID:
8800		ath11k_wmi_pdev_dma_ring_buf_release_event(ab, skb);
8801		break;
8802	case WMI_HOST_FILS_DISCOVERY_EVENTID:
8803		ath11k_fils_discovery_event(ab, skb);
8804		break;
8805	case WMI_OFFLOAD_PROB_RESP_TX_STATUS_EVENTID:
8806		ath11k_probe_resp_tx_status_event(ab, skb);
8807		break;
8808	case WMI_OBSS_COLOR_COLLISION_DETECTION_EVENTID:
8809		ath11k_wmi_obss_color_collision_event(ab, skb);
8810		break;
8811	case WMI_TWT_ADD_DIALOG_EVENTID:
8812		ath11k_wmi_twt_add_dialog_event(ab, skb);
8813		break;
8814	case WMI_PDEV_DFS_RADAR_DETECTION_EVENTID:
8815		ath11k_wmi_pdev_dfs_radar_detected_event(ab, skb);
8816		break;
8817	case WMI_VDEV_DELETE_RESP_EVENTID:
8818		ath11k_vdev_delete_resp_event(ab, skb);
8819		break;
8820	case WMI_WOW_WAKEUP_HOST_EVENTID:
8821		ath11k_wmi_event_wow_wakeup_host(ab, skb);
8822		break;
8823	case WMI_11D_NEW_COUNTRY_EVENTID:
8824		ath11k_reg_11d_new_cc_event(ab, skb);
8825		break;
8826	case WMI_DIAG_EVENTID:
8827		ath11k_wmi_diag_event(ab, skb);
8828		break;
8829	case WMI_PEER_STA_PS_STATECHG_EVENTID:
8830		ath11k_wmi_event_peer_sta_ps_state_chg(ab, skb);
8831		break;
8832	case WMI_GTK_OFFLOAD_STATUS_EVENTID:
8833		ath11k_wmi_gtk_offload_status_event(ab, skb);
8834		break;
8835	case WMI_P2P_NOA_EVENTID:
8836		ath11k_wmi_p2p_noa_event(ab, skb);
8837		break;
8838	default:
8839		ath11k_dbg(ab, ATH11K_DBG_WMI, "unsupported event id 0x%x\n", id);
8840		break;
8841	}
8842
8843out:
8844	dev_kfree_skb(skb);
8845}
8846
8847static int ath11k_connect_pdev_htc_service(struct ath11k_base *ab,
8848					   u32 pdev_idx)
8849{
8850	int status;
8851	u32 svc_id[] = { ATH11K_HTC_SVC_ID_WMI_CONTROL,
8852			 ATH11K_HTC_SVC_ID_WMI_CONTROL_MAC1,
8853			 ATH11K_HTC_SVC_ID_WMI_CONTROL_MAC2 };
8854
8855	struct ath11k_htc_svc_conn_req conn_req;
8856	struct ath11k_htc_svc_conn_resp conn_resp;
8857
8858	memset(&conn_req, 0, sizeof(conn_req));
8859	memset(&conn_resp, 0, sizeof(conn_resp));
8860
8861	/* these fields are the same for all service endpoints */
8862	conn_req.ep_ops.ep_tx_complete = ath11k_wmi_htc_tx_complete;
8863	conn_req.ep_ops.ep_rx_complete = ath11k_wmi_tlv_op_rx;
8864	conn_req.ep_ops.ep_tx_credits = ath11k_wmi_op_ep_tx_credits;
8865
8866	/* connect to control service */
8867	conn_req.service_id = svc_id[pdev_idx];
8868
8869	status = ath11k_htc_connect_service(&ab->htc, &conn_req, &conn_resp);
8870	if (status) {
8871		ath11k_warn(ab, "failed to connect to WMI CONTROL service status: %d\n",
8872			    status);
8873		return status;
8874	}
8875
8876	ab->wmi_ab.wmi_endpoint_id[pdev_idx] = conn_resp.eid;
8877	ab->wmi_ab.wmi[pdev_idx].eid = conn_resp.eid;
8878	ab->wmi_ab.max_msg_len[pdev_idx] = conn_resp.max_msg_len;
8879	init_waitqueue_head(&ab->wmi_ab.wmi[pdev_idx].tx_ce_desc_wq);
8880
8881	return 0;
8882}
8883
8884static int
8885ath11k_wmi_send_unit_test_cmd(struct ath11k *ar,
8886			      struct wmi_unit_test_cmd ut_cmd,
8887			      u32 *test_args)
8888{
8889	struct ath11k_pdev_wmi *wmi = ar->wmi;
8890	struct wmi_unit_test_cmd *cmd;
8891	struct sk_buff *skb;
8892	struct wmi_tlv *tlv;
8893	void *ptr;
8894	u32 *ut_cmd_args;
8895	int buf_len, arg_len;
8896	int ret;
8897	int i;
8898
8899	arg_len = sizeof(u32) * ut_cmd.num_args;
8900	buf_len = sizeof(ut_cmd) + arg_len + TLV_HDR_SIZE;
8901
8902	skb = ath11k_wmi_alloc_skb(wmi->wmi_ab, buf_len);
8903	if (!skb)
8904		return -ENOMEM;
8905
8906	cmd = (struct wmi_unit_test_cmd *)skb->data;
8907	cmd->tlv_header = FIELD_PREP(WMI_TLV_TAG, WMI_TAG_UNIT_TEST_CMD) |
8908			  FIELD_PREP(WMI_TLV_LEN, sizeof(ut_cmd) - TLV_HDR_SIZE);
8909
8910	cmd->vdev_id = ut_cmd.vdev_id;
8911	cmd->module_id = ut_cmd.module_id;
8912	cmd->num_args = ut_cmd.num_args;
8913	cmd->diag_token = ut_cmd.diag_token;
8914
8915	ptr = skb->data + sizeof(ut_cmd);
8916
8917	tlv = ptr;
8918	tlv->header = FIELD_PREP(WMI_TLV_TAG, WMI_TAG_ARRAY_UINT32) |
8919		      FIELD_PREP(WMI_TLV_LEN, arg_len);
8920
8921	ptr += TLV_HDR_SIZE;
8922
8923	ut_cmd_args = ptr;
8924	for (i = 0; i < ut_cmd.num_args; i++)
8925		ut_cmd_args[i] = test_args[i];
8926
8927	ret = ath11k_wmi_cmd_send(wmi, skb, WMI_UNIT_TEST_CMDID);
8928
8929	if (ret) {
8930		ath11k_warn(ar->ab, "failed to send WMI_UNIT_TEST CMD :%d\n",
8931			    ret);
8932		dev_kfree_skb(skb);
8933	}
8934
8935	ath11k_dbg(ar->ab, ATH11K_DBG_WMI,
8936		   "cmd unit test module %d vdev %d n_args %d token %d\n",
8937		   cmd->module_id, cmd->vdev_id, cmd->num_args,
8938		   cmd->diag_token);
8939
8940	return ret;
8941}
8942
8943int ath11k_wmi_simulate_radar(struct ath11k *ar)
8944{
8945	struct ath11k_vif *arvif;
8946	u32 dfs_args[DFS_MAX_TEST_ARGS];
8947	struct wmi_unit_test_cmd wmi_ut;
8948	bool arvif_found = false;
8949
8950	list_for_each_entry(arvif, &ar->arvifs, list) {
8951		if (arvif->is_started && arvif->vdev_type == WMI_VDEV_TYPE_AP) {
8952			arvif_found = true;
8953			break;
8954		}
8955	}
8956
8957	if (!arvif_found)
8958		return -EINVAL;
8959
8960	dfs_args[DFS_TEST_CMDID] = 0;
8961	dfs_args[DFS_TEST_PDEV_ID] = ar->pdev->pdev_id;
8962	/* Currently we could pass segment_id(b0 - b1), chirp(b2)
8963	 * freq offset (b3 - b10) to unit test. For simulation
8964	 * purpose this can be set to 0 which is valid.
8965	 */
8966	dfs_args[DFS_TEST_RADAR_PARAM] = 0;
8967
8968	wmi_ut.vdev_id = arvif->vdev_id;
8969	wmi_ut.module_id = DFS_UNIT_TEST_MODULE;
8970	wmi_ut.num_args = DFS_MAX_TEST_ARGS;
8971	wmi_ut.diag_token = DFS_UNIT_TEST_TOKEN;
8972
8973	ath11k_dbg(ar->ab, ATH11K_DBG_REG, "Triggering Radar Simulation\n");
8974
8975	return ath11k_wmi_send_unit_test_cmd(ar, wmi_ut, dfs_args);
8976}
8977
8978int ath11k_wmi_fw_dbglog_cfg(struct ath11k *ar, u32 *module_id_bitmap,
8979			     struct ath11k_fw_dbglog *dbglog)
8980{
8981	struct ath11k_pdev_wmi *wmi = ar->wmi;
8982	struct wmi_debug_log_config_cmd_fixed_param *cmd;
8983	struct sk_buff *skb;
8984	struct wmi_tlv *tlv;
8985	int ret, len;
8986
8987	len = sizeof(*cmd) + TLV_HDR_SIZE + (MAX_MODULE_ID_BITMAP_WORDS * sizeof(u32));
8988	skb = ath11k_wmi_alloc_skb(wmi->wmi_ab, len);
8989	if (!skb)
8990		return -ENOMEM;
8991
8992	cmd = (struct wmi_debug_log_config_cmd_fixed_param *)skb->data;
8993	cmd->tlv_header = FIELD_PREP(WMI_TLV_TAG, WMI_TAG_DEBUG_LOG_CONFIG_CMD) |
8994			  FIELD_PREP(WMI_TLV_LEN, sizeof(*cmd) - TLV_HDR_SIZE);
8995	cmd->dbg_log_param = dbglog->param;
8996
8997	tlv = (struct wmi_tlv *)((u8 *)cmd + sizeof(*cmd));
8998	tlv->header = FIELD_PREP(WMI_TLV_TAG, WMI_TAG_ARRAY_UINT32) |
8999		      FIELD_PREP(WMI_TLV_LEN, MAX_MODULE_ID_BITMAP_WORDS * sizeof(u32));
9000
9001	switch (dbglog->param) {
9002	case WMI_DEBUG_LOG_PARAM_LOG_LEVEL:
9003	case WMI_DEBUG_LOG_PARAM_VDEV_ENABLE:
9004	case WMI_DEBUG_LOG_PARAM_VDEV_DISABLE:
9005	case WMI_DEBUG_LOG_PARAM_VDEV_ENABLE_BITMAP:
9006		cmd->value = dbglog->value;
9007		break;
9008	case WMI_DEBUG_LOG_PARAM_MOD_ENABLE_BITMAP:
9009	case WMI_DEBUG_LOG_PARAM_WOW_MOD_ENABLE_BITMAP:
9010		cmd->value = dbglog->value;
9011		memcpy(tlv->value, module_id_bitmap,
9012		       MAX_MODULE_ID_BITMAP_WORDS * sizeof(u32));
9013		/* clear current config to be used for next user config */
9014		memset(module_id_bitmap, 0,
9015		       MAX_MODULE_ID_BITMAP_WORDS * sizeof(u32));
9016		break;
9017	default:
9018		dev_kfree_skb(skb);
9019		return -EINVAL;
9020	}
9021
9022	ret = ath11k_wmi_cmd_send(wmi, skb, WMI_DBGLOG_CFG_CMDID);
9023	if (ret) {
9024		ath11k_warn(ar->ab,
9025			    "failed to send WMI_DBGLOG_CFG_CMDID\n");
9026		dev_kfree_skb(skb);
9027	}
9028
9029	ath11k_dbg(ar->ab, ATH11K_DBG_WMI, "cmd dbglog cfg");
9030
9031	return ret;
9032}
9033
9034int ath11k_wmi_connect(struct ath11k_base *ab)
9035{
9036	u32 i;
9037	u8 wmi_ep_count;
9038
9039	wmi_ep_count = ab->htc.wmi_ep_count;
9040	if (wmi_ep_count > ab->hw_params.max_radios)
9041		return -1;
9042
9043	for (i = 0; i < wmi_ep_count; i++)
9044		ath11k_connect_pdev_htc_service(ab, i);
9045
9046	return 0;
9047}
9048
9049static void ath11k_wmi_pdev_detach(struct ath11k_base *ab, u8 pdev_id)
9050{
9051	if (WARN_ON(pdev_id >= MAX_RADIOS))
9052		return;
9053
9054	/* TODO: Deinit any pdev specific wmi resource */
9055}
9056
9057int ath11k_wmi_pdev_attach(struct ath11k_base *ab,
9058			   u8 pdev_id)
9059{
9060	struct ath11k_pdev_wmi *wmi_handle;
9061
9062	if (pdev_id >= ab->hw_params.max_radios)
9063		return -EINVAL;
9064
9065	wmi_handle = &ab->wmi_ab.wmi[pdev_id];
9066
9067	wmi_handle->wmi_ab = &ab->wmi_ab;
9068
9069	ab->wmi_ab.ab = ab;
9070	/* TODO: Init remaining resource specific to pdev */
9071
9072	return 0;
9073}
9074
9075int ath11k_wmi_attach(struct ath11k_base *ab)
9076{
9077	int ret;
9078
9079	ret = ath11k_wmi_pdev_attach(ab, 0);
9080	if (ret)
9081		return ret;
9082
9083	ab->wmi_ab.ab = ab;
9084	ab->wmi_ab.preferred_hw_mode = WMI_HOST_HW_MODE_MAX;
9085
9086	/* It's overwritten when service_ext_ready is handled */
9087	if (ab->hw_params.single_pdev_only && ab->hw_params.num_rxdma_per_pdev > 1)
9088		ab->wmi_ab.preferred_hw_mode = WMI_HOST_HW_MODE_SINGLE;
9089
9090	/* TODO: Init remaining wmi soc resources required */
9091	init_completion(&ab->wmi_ab.service_ready);
9092	init_completion(&ab->wmi_ab.unified_ready);
9093
9094	return 0;
9095}
9096
9097void ath11k_wmi_detach(struct ath11k_base *ab)
9098{
9099	int i;
9100
9101	/* TODO: Deinit wmi resource specific to SOC as required */
9102
9103	for (i = 0; i < ab->htc.wmi_ep_count; i++)
9104		ath11k_wmi_pdev_detach(ab, i);
9105
9106	ath11k_wmi_free_dbring_caps(ab);
9107}
9108
9109int ath11k_wmi_hw_data_filter_cmd(struct ath11k *ar, u32 vdev_id,
9110				  u32 filter_bitmap, bool enable)
9111{
9112	struct wmi_hw_data_filter_cmd *cmd;
9113	struct sk_buff *skb;
9114	int len;
9115
9116	len = sizeof(*cmd);
9117	skb = ath11k_wmi_alloc_skb(ar->wmi->wmi_ab, len);
9118
9119	if (!skb)
9120		return -ENOMEM;
9121
9122	cmd = (struct wmi_hw_data_filter_cmd *)skb->data;
9123	cmd->tlv_header = FIELD_PREP(WMI_TLV_TAG, WMI_TAG_HW_DATA_FILTER_CMD) |
9124			  FIELD_PREP(WMI_TLV_LEN, sizeof(*cmd) - TLV_HDR_SIZE);
9125
9126	cmd->vdev_id = vdev_id;
9127	cmd->enable = enable;
9128
9129	/* Set all modes in case of disable */
9130	if (cmd->enable)
9131		cmd->hw_filter_bitmap = filter_bitmap;
9132	else
9133		cmd->hw_filter_bitmap = ((u32)~0U);
9134
9135	ath11k_dbg(ar->ab, ATH11K_DBG_WMI,
9136		   "hw data filter enable %d filter_bitmap 0x%x\n",
9137		   enable, filter_bitmap);
9138
9139	return ath11k_wmi_cmd_send(ar->wmi, skb, WMI_HW_DATA_FILTER_CMDID);
9140}
9141
9142int ath11k_wmi_wow_host_wakeup_ind(struct ath11k *ar)
9143{
9144	struct wmi_wow_host_wakeup_ind *cmd;
9145	struct sk_buff *skb;
9146	size_t len;
9147
9148	len = sizeof(*cmd);
9149	skb = ath11k_wmi_alloc_skb(ar->wmi->wmi_ab, len);
9150	if (!skb)
9151		return -ENOMEM;
9152
9153	cmd = (struct wmi_wow_host_wakeup_ind *)skb->data;
9154	cmd->tlv_header = FIELD_PREP(WMI_TLV_TAG,
9155				     WMI_TAG_WOW_HOSTWAKEUP_FROM_SLEEP_CMD) |
9156			  FIELD_PREP(WMI_TLV_LEN, sizeof(*cmd) - TLV_HDR_SIZE);
9157
9158	ath11k_dbg(ar->ab, ATH11K_DBG_WMI, "tlv wow host wakeup ind\n");
9159
9160	return ath11k_wmi_cmd_send(ar->wmi, skb, WMI_WOW_HOSTWAKEUP_FROM_SLEEP_CMDID);
9161}
9162
9163int ath11k_wmi_wow_enable(struct ath11k *ar)
9164{
9165	struct wmi_wow_enable_cmd *cmd;
9166	struct sk_buff *skb;
9167	int len;
9168
9169	len = sizeof(*cmd);
9170	skb = ath11k_wmi_alloc_skb(ar->wmi->wmi_ab, len);
9171	if (!skb)
9172		return -ENOMEM;
9173
9174	cmd = (struct wmi_wow_enable_cmd *)skb->data;
9175	cmd->tlv_header = FIELD_PREP(WMI_TLV_TAG, WMI_TAG_WOW_ENABLE_CMD) |
9176			  FIELD_PREP(WMI_TLV_LEN, sizeof(*cmd) - TLV_HDR_SIZE);
9177
9178	cmd->enable = 1;
9179	cmd->pause_iface_config = WOW_IFACE_PAUSE_ENABLED;
9180	ath11k_dbg(ar->ab, ATH11K_DBG_WMI, "tlv wow enable\n");
9181
9182	return ath11k_wmi_cmd_send(ar->wmi, skb, WMI_WOW_ENABLE_CMDID);
9183}
9184
9185int ath11k_wmi_scan_prob_req_oui(struct ath11k *ar,
9186				 const u8 mac_addr[ETH_ALEN])
9187{
9188	struct sk_buff *skb;
9189	struct wmi_scan_prob_req_oui_cmd *cmd;
9190	u32 prob_req_oui;
9191	int len;
9192
9193	prob_req_oui = (((u32)mac_addr[0]) << 16) |
9194		       (((u32)mac_addr[1]) << 8) | mac_addr[2];
9195
9196	len = sizeof(*cmd);
9197	skb = ath11k_wmi_alloc_skb(ar->wmi->wmi_ab, len);
9198	if (!skb)
9199		return -ENOMEM;
9200
9201	cmd = (struct wmi_scan_prob_req_oui_cmd *)skb->data;
9202	cmd->tlv_header = FIELD_PREP(WMI_TLV_TAG,
9203				     WMI_TAG_SCAN_PROB_REQ_OUI_CMD) |
9204			  FIELD_PREP(WMI_TLV_LEN, sizeof(*cmd) - TLV_HDR_SIZE);
9205	cmd->prob_req_oui = prob_req_oui;
9206
9207	ath11k_dbg(ar->ab, ATH11K_DBG_WMI, "scan prob req oui %d\n",
9208		   prob_req_oui);
9209
9210	return ath11k_wmi_cmd_send(ar->wmi, skb, WMI_SCAN_PROB_REQ_OUI_CMDID);
9211}
9212
9213int ath11k_wmi_wow_add_wakeup_event(struct ath11k *ar, u32 vdev_id,
9214				    enum wmi_wow_wakeup_event event,
9215				u32 enable)
9216{
9217	struct wmi_wow_add_del_event_cmd *cmd;
9218	struct sk_buff *skb;
9219	size_t len;
9220
9221	len = sizeof(*cmd);
9222	skb = ath11k_wmi_alloc_skb(ar->wmi->wmi_ab, len);
9223	if (!skb)
9224		return -ENOMEM;
9225
9226	cmd = (struct wmi_wow_add_del_event_cmd *)skb->data;
9227	cmd->tlv_header = FIELD_PREP(WMI_TLV_TAG, WMI_TAG_WOW_ADD_DEL_EVT_CMD) |
9228			  FIELD_PREP(WMI_TLV_LEN, sizeof(*cmd) - TLV_HDR_SIZE);
9229
9230	cmd->vdev_id = vdev_id;
9231	cmd->is_add = enable;
9232	cmd->event_bitmap = (1 << event);
9233
9234	ath11k_dbg(ar->ab, ATH11K_DBG_WMI, "tlv wow add wakeup event %s enable %d vdev_id %d\n",
9235		   wow_wakeup_event(event), enable, vdev_id);
9236
9237	return ath11k_wmi_cmd_send(ar->wmi, skb, WMI_WOW_ENABLE_DISABLE_WAKE_EVENT_CMDID);
9238}
9239
9240int ath11k_wmi_wow_add_pattern(struct ath11k *ar, u32 vdev_id, u32 pattern_id,
9241			       const u8 *pattern, const u8 *mask,
9242			   int pattern_len, int pattern_offset)
9243{
9244	struct wmi_wow_add_pattern_cmd *cmd;
9245	struct wmi_wow_bitmap_pattern *bitmap;
9246	struct wmi_tlv *tlv;
9247	struct sk_buff *skb;
9248	u8 *ptr;
9249	size_t len;
9250
9251	len = sizeof(*cmd) +
9252	      sizeof(*tlv) +			/* array struct */
9253	      sizeof(*bitmap) +			/* bitmap */
9254	      sizeof(*tlv) +			/* empty ipv4 sync */
9255	      sizeof(*tlv) +			/* empty ipv6 sync */
9256	      sizeof(*tlv) +			/* empty magic */
9257	      sizeof(*tlv) +			/* empty info timeout */
9258	      sizeof(*tlv) + sizeof(u32);	/* ratelimit interval */
9259
9260	skb = ath11k_wmi_alloc_skb(ar->wmi->wmi_ab, len);
9261	if (!skb)
9262		return -ENOMEM;
9263
9264	/* cmd */
9265	ptr = (u8 *)skb->data;
9266	cmd = (struct wmi_wow_add_pattern_cmd *)ptr;
9267	cmd->tlv_header = FIELD_PREP(WMI_TLV_TAG,
9268				     WMI_TAG_WOW_ADD_PATTERN_CMD) |
9269			  FIELD_PREP(WMI_TLV_LEN, sizeof(*cmd) - TLV_HDR_SIZE);
9270
9271	cmd->vdev_id = vdev_id;
9272	cmd->pattern_id = pattern_id;
9273	cmd->pattern_type = WOW_BITMAP_PATTERN;
9274
9275	ptr += sizeof(*cmd);
9276
9277	/* bitmap */
9278	tlv = (struct wmi_tlv *)ptr;
9279	tlv->header = FIELD_PREP(WMI_TLV_TAG,
9280				 WMI_TAG_ARRAY_STRUCT) |
9281		      FIELD_PREP(WMI_TLV_LEN, sizeof(*bitmap));
9282
9283	ptr += sizeof(*tlv);
9284
9285	bitmap = (struct wmi_wow_bitmap_pattern *)ptr;
9286	bitmap->tlv_header = FIELD_PREP(WMI_TLV_TAG,
9287					WMI_TAG_WOW_BITMAP_PATTERN_T) |
9288			     FIELD_PREP(WMI_TLV_LEN, sizeof(*bitmap) - TLV_HDR_SIZE);
9289
9290	memcpy(bitmap->patternbuf, pattern, pattern_len);
9291	ath11k_ce_byte_swap(bitmap->patternbuf, roundup(pattern_len, 4));
9292	memcpy(bitmap->bitmaskbuf, mask, pattern_len);
9293	ath11k_ce_byte_swap(bitmap->bitmaskbuf, roundup(pattern_len, 4));
9294	bitmap->pattern_offset = pattern_offset;
9295	bitmap->pattern_len = pattern_len;
9296	bitmap->bitmask_len = pattern_len;
9297	bitmap->pattern_id = pattern_id;
9298
9299	ptr += sizeof(*bitmap);
9300
9301	/* ipv4 sync */
9302	tlv = (struct wmi_tlv *)ptr;
9303	tlv->header = FIELD_PREP(WMI_TLV_TAG,
9304				 WMI_TAG_ARRAY_STRUCT) |
9305		      FIELD_PREP(WMI_TLV_LEN, 0);
9306
9307	ptr += sizeof(*tlv);
9308
9309	/* ipv6 sync */
9310	tlv = (struct wmi_tlv *)ptr;
9311	tlv->header = FIELD_PREP(WMI_TLV_TAG,
9312				 WMI_TAG_ARRAY_STRUCT) |
9313		      FIELD_PREP(WMI_TLV_LEN, 0);
9314
9315	ptr += sizeof(*tlv);
9316
9317	/* magic */
9318	tlv = (struct wmi_tlv *)ptr;
9319	tlv->header = FIELD_PREP(WMI_TLV_TAG,
9320				 WMI_TAG_ARRAY_STRUCT) |
9321		      FIELD_PREP(WMI_TLV_LEN, 0);
9322
9323	ptr += sizeof(*tlv);
9324
9325	/* pattern info timeout */
9326	tlv = (struct wmi_tlv *)ptr;
9327	tlv->header = FIELD_PREP(WMI_TLV_TAG,
9328				 WMI_TAG_ARRAY_UINT32) |
9329		      FIELD_PREP(WMI_TLV_LEN, 0);
9330
9331	ptr += sizeof(*tlv);
9332
9333	/* ratelimit interval */
9334	tlv = (struct wmi_tlv *)ptr;
9335	tlv->header = FIELD_PREP(WMI_TLV_TAG,
9336				 WMI_TAG_ARRAY_UINT32) |
9337		      FIELD_PREP(WMI_TLV_LEN, sizeof(u32));
9338
9339	ath11k_dbg(ar->ab, ATH11K_DBG_WMI, "tlv wow add pattern vdev_id %d pattern_id %d pattern_offset %d\n",
9340		   vdev_id, pattern_id, pattern_offset);
9341
9342	return ath11k_wmi_cmd_send(ar->wmi, skb, WMI_WOW_ADD_WAKE_PATTERN_CMDID);
9343}
9344
9345int ath11k_wmi_wow_del_pattern(struct ath11k *ar, u32 vdev_id, u32 pattern_id)
9346{
9347	struct wmi_wow_del_pattern_cmd *cmd;
9348	struct sk_buff *skb;
9349	size_t len;
9350
9351	len = sizeof(*cmd);
9352	skb = ath11k_wmi_alloc_skb(ar->wmi->wmi_ab, len);
9353	if (!skb)
9354		return -ENOMEM;
9355
9356	cmd = (struct wmi_wow_del_pattern_cmd *)skb->data;
9357	cmd->tlv_header = FIELD_PREP(WMI_TLV_TAG,
9358				     WMI_TAG_WOW_DEL_PATTERN_CMD) |
9359			  FIELD_PREP(WMI_TLV_LEN, sizeof(*cmd) - TLV_HDR_SIZE);
9360
9361	cmd->vdev_id = vdev_id;
9362	cmd->pattern_id = pattern_id;
9363	cmd->pattern_type = WOW_BITMAP_PATTERN;
9364
9365	ath11k_dbg(ar->ab, ATH11K_DBG_WMI, "tlv wow del pattern vdev_id %d pattern_id %d\n",
9366		   vdev_id, pattern_id);
9367
9368	return ath11k_wmi_cmd_send(ar->wmi, skb, WMI_WOW_DEL_WAKE_PATTERN_CMDID);
9369}
9370
9371static struct sk_buff *
9372ath11k_wmi_op_gen_config_pno_start(struct ath11k *ar,
9373				   u32 vdev_id,
9374				       struct wmi_pno_scan_req *pno)
9375{
9376	struct nlo_configured_parameters *nlo_list;
9377	struct wmi_wow_nlo_config_cmd *cmd;
9378	struct wmi_tlv *tlv;
9379	struct sk_buff *skb;
9380	u32 *channel_list;
9381	size_t len, nlo_list_len, channel_list_len;
9382	u8 *ptr;
9383	u32 i;
9384
9385	len = sizeof(*cmd) +
9386	      sizeof(*tlv) +
9387	      /* TLV place holder for array of structures
9388	       * nlo_configured_parameters(nlo_list)
9389	       */
9390	      sizeof(*tlv);
9391	      /* TLV place holder for array of uint32 channel_list */
9392
9393	channel_list_len = sizeof(u32) * pno->a_networks[0].channel_count;
9394	len += channel_list_len;
9395
9396	nlo_list_len = sizeof(*nlo_list) * pno->uc_networks_count;
9397	len += nlo_list_len;
9398
9399	skb = ath11k_wmi_alloc_skb(ar->wmi->wmi_ab, len);
9400	if (!skb)
9401		return ERR_PTR(-ENOMEM);
9402
9403	ptr = (u8 *)skb->data;
9404	cmd = (struct wmi_wow_nlo_config_cmd *)ptr;
9405	cmd->tlv_header = FIELD_PREP(WMI_TLV_TAG, WMI_TAG_NLO_CONFIG_CMD) |
9406			  FIELD_PREP(WMI_TLV_LEN, sizeof(*cmd) - TLV_HDR_SIZE);
9407
9408	cmd->vdev_id = pno->vdev_id;
9409	cmd->flags = WMI_NLO_CONFIG_START | WMI_NLO_CONFIG_SSID_HIDE_EN;
9410
9411	/* current FW does not support min-max range for dwell time */
9412	cmd->active_dwell_time = pno->active_max_time;
9413	cmd->passive_dwell_time = pno->passive_max_time;
9414
9415	if (pno->do_passive_scan)
9416		cmd->flags |= WMI_NLO_CONFIG_SCAN_PASSIVE;
9417
9418	cmd->fast_scan_period = pno->fast_scan_period;
9419	cmd->slow_scan_period = pno->slow_scan_period;
9420	cmd->fast_scan_max_cycles = pno->fast_scan_max_cycles;
9421	cmd->delay_start_time = pno->delay_start_time;
9422
9423	if (pno->enable_pno_scan_randomization) {
9424		cmd->flags |= WMI_NLO_CONFIG_SPOOFED_MAC_IN_PROBE_REQ |
9425				WMI_NLO_CONFIG_RANDOM_SEQ_NO_IN_PROBE_REQ;
9426		ether_addr_copy(cmd->mac_addr.addr, pno->mac_addr);
9427		ether_addr_copy(cmd->mac_mask.addr, pno->mac_addr_mask);
9428		ath11k_ce_byte_swap(cmd->mac_addr.addr, 8);
9429		ath11k_ce_byte_swap(cmd->mac_mask.addr, 8);
9430	}
9431
9432	ptr += sizeof(*cmd);
9433
9434	/* nlo_configured_parameters(nlo_list) */
9435	cmd->no_of_ssids = pno->uc_networks_count;
9436	tlv = (struct wmi_tlv *)ptr;
9437	tlv->header = FIELD_PREP(WMI_TLV_TAG,
9438				 WMI_TAG_ARRAY_STRUCT) |
9439		      FIELD_PREP(WMI_TLV_LEN, nlo_list_len);
9440
9441	ptr += sizeof(*tlv);
9442	nlo_list = (struct nlo_configured_parameters *)ptr;
9443	for (i = 0; i < cmd->no_of_ssids; i++) {
9444		tlv = (struct wmi_tlv *)(&nlo_list[i].tlv_header);
9445		tlv->header = FIELD_PREP(WMI_TLV_TAG, WMI_TAG_ARRAY_BYTE) |
9446			      FIELD_PREP(WMI_TLV_LEN, sizeof(*nlo_list) - sizeof(*tlv));
9447
9448		nlo_list[i].ssid.valid = true;
9449		nlo_list[i].ssid.ssid.ssid_len = pno->a_networks[i].ssid.ssid_len;
9450		memcpy(nlo_list[i].ssid.ssid.ssid,
9451		       pno->a_networks[i].ssid.ssid,
9452		       nlo_list[i].ssid.ssid.ssid_len);
9453		ath11k_ce_byte_swap(nlo_list[i].ssid.ssid.ssid,
9454				    roundup(nlo_list[i].ssid.ssid.ssid_len, 4));
9455
9456		if (pno->a_networks[i].rssi_threshold &&
9457		    pno->a_networks[i].rssi_threshold > -300) {
9458			nlo_list[i].rssi_cond.valid = true;
9459			nlo_list[i].rssi_cond.rssi =
9460				pno->a_networks[i].rssi_threshold;
9461		}
9462
9463		nlo_list[i].bcast_nw_type.valid = true;
9464		nlo_list[i].bcast_nw_type.bcast_nw_type =
9465			pno->a_networks[i].bcast_nw_type;
9466	}
9467
9468	ptr += nlo_list_len;
9469	cmd->num_of_channels = pno->a_networks[0].channel_count;
9470	tlv = (struct wmi_tlv *)ptr;
9471	tlv->header =  FIELD_PREP(WMI_TLV_TAG, WMI_TAG_ARRAY_UINT32) |
9472		       FIELD_PREP(WMI_TLV_LEN, channel_list_len);
9473	ptr += sizeof(*tlv);
9474	channel_list = (u32 *)ptr;
9475	for (i = 0; i < cmd->num_of_channels; i++)
9476		channel_list[i] = pno->a_networks[0].channels[i];
9477
9478	ath11k_dbg(ar->ab, ATH11K_DBG_WMI, "tlv start pno config vdev_id %d\n",
9479		   vdev_id);
9480
9481	return skb;
9482}
9483
9484static struct sk_buff *ath11k_wmi_op_gen_config_pno_stop(struct ath11k *ar,
9485							 u32 vdev_id)
9486{
9487	struct wmi_wow_nlo_config_cmd *cmd;
9488	struct sk_buff *skb;
9489	size_t len;
9490
9491	len = sizeof(*cmd);
9492	skb = ath11k_wmi_alloc_skb(ar->wmi->wmi_ab, len);
9493	if (!skb)
9494		return ERR_PTR(-ENOMEM);
9495
9496	cmd = (struct wmi_wow_nlo_config_cmd *)skb->data;
9497	cmd->tlv_header = FIELD_PREP(WMI_TLV_TAG, WMI_TAG_NLO_CONFIG_CMD) |
9498			  FIELD_PREP(WMI_TLV_LEN, len - TLV_HDR_SIZE);
9499
9500	cmd->vdev_id = vdev_id;
9501	cmd->flags = WMI_NLO_CONFIG_STOP;
9502
9503	ath11k_dbg(ar->ab, ATH11K_DBG_WMI,
9504		   "tlv stop pno config vdev_id %d\n", vdev_id);
9505	return skb;
9506}
9507
9508int ath11k_wmi_wow_config_pno(struct ath11k *ar, u32 vdev_id,
9509			      struct wmi_pno_scan_req  *pno_scan)
9510{
9511	struct sk_buff *skb;
9512
9513	if (pno_scan->enable)
9514		skb = ath11k_wmi_op_gen_config_pno_start(ar, vdev_id, pno_scan);
9515	else
9516		skb = ath11k_wmi_op_gen_config_pno_stop(ar, vdev_id);
9517
9518	if (IS_ERR_OR_NULL(skb))
9519		return -ENOMEM;
9520
9521	return ath11k_wmi_cmd_send(ar->wmi, skb, WMI_NETWORK_LIST_OFFLOAD_CONFIG_CMDID);
9522}
9523
9524static void ath11k_wmi_fill_ns_offload(struct ath11k *ar,
9525				       struct ath11k_arp_ns_offload *offload,
9526				       u8 **ptr,
9527				       bool enable,
9528				       bool ext)
9529{
9530	struct wmi_ns_offload_tuple *ns;
9531	struct wmi_tlv *tlv;
9532	u8 *buf_ptr = *ptr;
9533	u32 ns_cnt, ns_ext_tuples;
9534	int i, max_offloads;
9535
9536	ns_cnt = offload->ipv6_count;
9537
9538	tlv  = (struct wmi_tlv *)buf_ptr;
9539
9540	if (ext) {
9541		ns_ext_tuples = offload->ipv6_count - WMI_MAX_NS_OFFLOADS;
9542		tlv->header = FIELD_PREP(WMI_TLV_TAG, WMI_TAG_ARRAY_STRUCT) |
9543			      FIELD_PREP(WMI_TLV_LEN, ns_ext_tuples * sizeof(*ns));
9544		i = WMI_MAX_NS_OFFLOADS;
9545		max_offloads = offload->ipv6_count;
9546	} else {
9547		tlv->header = FIELD_PREP(WMI_TLV_TAG, WMI_TAG_ARRAY_STRUCT) |
9548			      FIELD_PREP(WMI_TLV_LEN, WMI_MAX_NS_OFFLOADS * sizeof(*ns));
9549		i = 0;
9550		max_offloads = WMI_MAX_NS_OFFLOADS;
9551	}
9552
9553	buf_ptr += sizeof(*tlv);
9554
9555	for (; i < max_offloads; i++) {
9556		ns = (struct wmi_ns_offload_tuple *)buf_ptr;
9557		ns->tlv_header = FIELD_PREP(WMI_TLV_TAG, WMI_TAG_NS_OFFLOAD_TUPLE) |
9558				 FIELD_PREP(WMI_TLV_LEN, sizeof(*ns) - TLV_HDR_SIZE);
9559
9560		if (enable) {
9561			if (i < ns_cnt)
9562				ns->flags |= WMI_NSOL_FLAGS_VALID;
9563
9564			memcpy(ns->target_ipaddr[0], offload->ipv6_addr[i], 16);
9565			memcpy(ns->solicitation_ipaddr, offload->self_ipv6_addr[i], 16);
9566			ath11k_ce_byte_swap(ns->target_ipaddr[0], 16);
9567			ath11k_ce_byte_swap(ns->solicitation_ipaddr, 16);
9568
9569			if (offload->ipv6_type[i])
9570				ns->flags |= WMI_NSOL_FLAGS_IS_IPV6_ANYCAST;
9571
9572			memcpy(ns->target_mac.addr, offload->mac_addr, ETH_ALEN);
9573			ath11k_ce_byte_swap(ns->target_mac.addr, 8);
9574
9575			if (ns->target_mac.word0 != 0 ||
9576			    ns->target_mac.word1 != 0) {
9577				ns->flags |= WMI_NSOL_FLAGS_MAC_VALID;
9578			}
9579
9580			ath11k_dbg(ar->ab, ATH11K_DBG_WMI,
9581				   "index %d ns_solicited %pI6 target %pI6",
9582				   i, ns->solicitation_ipaddr,
9583				   ns->target_ipaddr[0]);
9584		}
9585
9586		buf_ptr += sizeof(*ns);
9587	}
9588
9589	*ptr = buf_ptr;
9590}
9591
9592static void ath11k_wmi_fill_arp_offload(struct ath11k *ar,
9593					struct ath11k_arp_ns_offload *offload,
9594					u8 **ptr,
9595					bool enable)
9596{
9597	struct wmi_arp_offload_tuple *arp;
9598	struct wmi_tlv *tlv;
9599	u8 *buf_ptr = *ptr;
9600	int i;
9601
9602	/* fill arp tuple */
9603	tlv = (struct wmi_tlv *)buf_ptr;
9604	tlv->header = FIELD_PREP(WMI_TLV_TAG, WMI_TAG_ARRAY_STRUCT) |
9605		      FIELD_PREP(WMI_TLV_LEN, WMI_MAX_ARP_OFFLOADS * sizeof(*arp));
9606	buf_ptr += sizeof(*tlv);
9607
9608	for (i = 0; i < WMI_MAX_ARP_OFFLOADS; i++) {
9609		arp = (struct wmi_arp_offload_tuple *)buf_ptr;
9610		arp->tlv_header = FIELD_PREP(WMI_TLV_TAG, WMI_TAG_ARP_OFFLOAD_TUPLE) |
9611				  FIELD_PREP(WMI_TLV_LEN, sizeof(*arp) - TLV_HDR_SIZE);
9612
9613		if (enable && i < offload->ipv4_count) {
9614			/* Copy the target ip addr and flags */
9615			arp->flags = WMI_ARPOL_FLAGS_VALID;
9616			memcpy(arp->target_ipaddr, offload->ipv4_addr[i], 4);
9617			ath11k_ce_byte_swap(arp->target_ipaddr, 4);
9618
9619			ath11k_dbg(ar->ab, ATH11K_DBG_WMI, "arp offload address %pI4",
9620				   arp->target_ipaddr);
9621		}
9622
9623		buf_ptr += sizeof(*arp);
9624	}
9625
9626	*ptr = buf_ptr;
9627}
9628
9629int ath11k_wmi_arp_ns_offload(struct ath11k *ar,
9630			      struct ath11k_vif *arvif, bool enable)
9631{
9632	struct ath11k_arp_ns_offload *offload;
9633	struct wmi_set_arp_ns_offload_cmd *cmd;
9634	struct wmi_tlv *tlv;
9635	struct sk_buff *skb;
9636	u8 *buf_ptr;
9637	size_t len;
9638	u8 ns_cnt, ns_ext_tuples = 0;
9639
9640	offload = &arvif->arp_ns_offload;
9641	ns_cnt = offload->ipv6_count;
9642
9643	len = sizeof(*cmd) +
9644	      sizeof(*tlv) +
9645	      WMI_MAX_NS_OFFLOADS * sizeof(struct wmi_ns_offload_tuple) +
9646	      sizeof(*tlv) +
9647	      WMI_MAX_ARP_OFFLOADS * sizeof(struct wmi_arp_offload_tuple);
9648
9649	if (ns_cnt > WMI_MAX_NS_OFFLOADS) {
9650		ns_ext_tuples = ns_cnt - WMI_MAX_NS_OFFLOADS;
9651		len += sizeof(*tlv) +
9652		       ns_ext_tuples * sizeof(struct wmi_ns_offload_tuple);
9653	}
9654
9655	skb = ath11k_wmi_alloc_skb(ar->wmi->wmi_ab, len);
9656	if (!skb)
9657		return -ENOMEM;
9658
9659	buf_ptr = skb->data;
9660	cmd = (struct wmi_set_arp_ns_offload_cmd *)buf_ptr;
9661	cmd->tlv_header = FIELD_PREP(WMI_TLV_TAG,
9662				     WMI_TAG_SET_ARP_NS_OFFLOAD_CMD) |
9663			  FIELD_PREP(WMI_TLV_LEN, sizeof(*cmd) - TLV_HDR_SIZE);
9664
9665	cmd->flags = 0;
9666	cmd->vdev_id = arvif->vdev_id;
9667	cmd->num_ns_ext_tuples = ns_ext_tuples;
9668
9669	buf_ptr += sizeof(*cmd);
9670
9671	ath11k_wmi_fill_ns_offload(ar, offload, &buf_ptr, enable, 0);
9672	ath11k_wmi_fill_arp_offload(ar, offload, &buf_ptr, enable);
9673
9674	if (ns_ext_tuples)
9675		ath11k_wmi_fill_ns_offload(ar, offload, &buf_ptr, enable, 1);
9676
9677	return ath11k_wmi_cmd_send(ar->wmi, skb, WMI_SET_ARP_NS_OFFLOAD_CMDID);
9678}
9679
9680int ath11k_wmi_gtk_rekey_offload(struct ath11k *ar,
9681				 struct ath11k_vif *arvif, bool enable)
9682{
9683	struct wmi_gtk_rekey_offload_cmd *cmd;
9684	struct ath11k_rekey_data *rekey_data = &arvif->rekey_data;
9685	int len;
9686	struct sk_buff *skb;
9687	__le64 replay_ctr;
9688
9689	len = sizeof(*cmd);
9690	skb =  ath11k_wmi_alloc_skb(ar->wmi->wmi_ab, len);
9691	if (!skb)
9692		return -ENOMEM;
9693
9694	cmd = (struct wmi_gtk_rekey_offload_cmd *)skb->data;
9695	cmd->tlv_header = FIELD_PREP(WMI_TLV_TAG, WMI_TAG_GTK_OFFLOAD_CMD) |
9696			  FIELD_PREP(WMI_TLV_LEN, sizeof(*cmd) - TLV_HDR_SIZE);
9697
9698	cmd->vdev_id = arvif->vdev_id;
9699
9700	if (enable) {
9701		cmd->flags = GTK_OFFLOAD_ENABLE_OPCODE;
9702
9703		/* the length in rekey_data and cmd is equal */
9704		memcpy(cmd->kck, rekey_data->kck, sizeof(cmd->kck));
9705		ath11k_ce_byte_swap(cmd->kck, GTK_OFFLOAD_KEK_BYTES);
9706		memcpy(cmd->kek, rekey_data->kek, sizeof(cmd->kek));
9707		ath11k_ce_byte_swap(cmd->kek, GTK_OFFLOAD_KEK_BYTES);
9708
9709		replay_ctr = cpu_to_le64(rekey_data->replay_ctr);
9710		memcpy(cmd->replay_ctr, &replay_ctr,
9711		       sizeof(replay_ctr));
9712		ath11k_ce_byte_swap(cmd->replay_ctr, GTK_REPLAY_COUNTER_BYTES);
9713	} else {
9714		cmd->flags = GTK_OFFLOAD_DISABLE_OPCODE;
9715	}
9716
9717	ath11k_dbg(ar->ab, ATH11K_DBG_WMI, "offload gtk rekey vdev: %d %d\n",
9718		   arvif->vdev_id, enable);
9719	return ath11k_wmi_cmd_send(ar->wmi, skb, WMI_GTK_OFFLOAD_CMDID);
9720}
9721
9722int ath11k_wmi_gtk_rekey_getinfo(struct ath11k *ar,
9723				 struct ath11k_vif *arvif)
9724{
9725	struct wmi_gtk_rekey_offload_cmd *cmd;
9726	int len;
9727	struct sk_buff *skb;
9728
9729	len = sizeof(*cmd);
9730	skb =  ath11k_wmi_alloc_skb(ar->wmi->wmi_ab, len);
9731	if (!skb)
9732		return -ENOMEM;
9733
9734	cmd = (struct wmi_gtk_rekey_offload_cmd *)skb->data;
9735	cmd->tlv_header = FIELD_PREP(WMI_TLV_TAG, WMI_TAG_GTK_OFFLOAD_CMD) |
9736			  FIELD_PREP(WMI_TLV_LEN, sizeof(*cmd) - TLV_HDR_SIZE);
9737
9738	cmd->vdev_id = arvif->vdev_id;
9739	cmd->flags = GTK_OFFLOAD_REQUEST_STATUS_OPCODE;
9740
9741	ath11k_dbg(ar->ab, ATH11K_DBG_WMI, "get gtk rekey vdev_id: %d\n",
9742		   arvif->vdev_id);
9743	return ath11k_wmi_cmd_send(ar->wmi, skb, WMI_GTK_OFFLOAD_CMDID);
9744}
9745
9746int ath11k_wmi_pdev_set_bios_sar_table_param(struct ath11k *ar, const u8 *sar_val)
9747{	struct ath11k_pdev_wmi *wmi = ar->wmi;
9748	struct wmi_pdev_set_sar_table_cmd *cmd;
9749	struct wmi_tlv *tlv;
9750	struct sk_buff *skb;
9751	u8 *buf_ptr;
9752	u32 len, sar_len_aligned, rsvd_len_aligned;
9753
9754	sar_len_aligned = roundup(BIOS_SAR_TABLE_LEN, sizeof(u32));
9755	rsvd_len_aligned = roundup(BIOS_SAR_RSVD1_LEN, sizeof(u32));
9756	len = sizeof(*cmd) +
9757	      TLV_HDR_SIZE + sar_len_aligned +
9758	      TLV_HDR_SIZE + rsvd_len_aligned;
9759
9760	skb = ath11k_wmi_alloc_skb(wmi->wmi_ab, len);
9761	if (!skb)
9762		return -ENOMEM;
9763
9764	cmd = (struct wmi_pdev_set_sar_table_cmd *)skb->data;
9765	cmd->tlv_header = FIELD_PREP(WMI_TLV_TAG, WMI_TAG_PDEV_SET_BIOS_SAR_TABLE_CMD) |
9766			  FIELD_PREP(WMI_TLV_LEN, sizeof(*cmd) - TLV_HDR_SIZE);
9767	cmd->pdev_id = ar->pdev->pdev_id;
9768	cmd->sar_len = BIOS_SAR_TABLE_LEN;
9769	cmd->rsvd_len = BIOS_SAR_RSVD1_LEN;
9770
9771	buf_ptr = skb->data + sizeof(*cmd);
9772	tlv = (struct wmi_tlv *)buf_ptr;
9773	tlv->header = FIELD_PREP(WMI_TLV_TAG, WMI_TAG_ARRAY_BYTE) |
9774		      FIELD_PREP(WMI_TLV_LEN, sar_len_aligned);
9775	buf_ptr += TLV_HDR_SIZE;
9776	memcpy(buf_ptr, sar_val, BIOS_SAR_TABLE_LEN);
9777
9778	buf_ptr += sar_len_aligned;
9779	tlv = (struct wmi_tlv *)buf_ptr;
9780	tlv->header = FIELD_PREP(WMI_TLV_TAG, WMI_TAG_ARRAY_BYTE) |
9781		      FIELD_PREP(WMI_TLV_LEN, rsvd_len_aligned);
9782
9783	return ath11k_wmi_cmd_send(wmi, skb, WMI_PDEV_SET_BIOS_SAR_TABLE_CMDID);
9784}
9785
9786int ath11k_wmi_pdev_set_bios_geo_table_param(struct ath11k *ar)
9787{
9788	struct ath11k_pdev_wmi *wmi = ar->wmi;
9789	struct wmi_pdev_set_geo_table_cmd *cmd;
9790	struct wmi_tlv *tlv;
9791	struct sk_buff *skb;
9792	u8 *buf_ptr;
9793	u32 len, rsvd_len_aligned;
9794
9795	rsvd_len_aligned = roundup(BIOS_SAR_RSVD2_LEN, sizeof(u32));
9796	len = sizeof(*cmd) + TLV_HDR_SIZE + rsvd_len_aligned;
9797
9798	skb = ath11k_wmi_alloc_skb(wmi->wmi_ab, len);
9799	if (!skb)
9800		return -ENOMEM;
9801
9802	cmd = (struct wmi_pdev_set_geo_table_cmd *)skb->data;
9803	cmd->tlv_header = FIELD_PREP(WMI_TLV_TAG, WMI_TAG_PDEV_SET_BIOS_GEO_TABLE_CMD) |
9804			  FIELD_PREP(WMI_TLV_LEN, sizeof(*cmd) - TLV_HDR_SIZE);
9805	cmd->pdev_id = ar->pdev->pdev_id;
9806	cmd->rsvd_len = BIOS_SAR_RSVD2_LEN;
9807
9808	buf_ptr = skb->data + sizeof(*cmd);
9809	tlv = (struct wmi_tlv *)buf_ptr;
9810	tlv->header = FIELD_PREP(WMI_TLV_TAG, WMI_TAG_ARRAY_BYTE) |
9811		      FIELD_PREP(WMI_TLV_LEN, rsvd_len_aligned);
9812
9813	return ath11k_wmi_cmd_send(wmi, skb, WMI_PDEV_SET_BIOS_GEO_TABLE_CMDID);
9814}
9815
9816int ath11k_wmi_sta_keepalive(struct ath11k *ar,
9817			     const struct wmi_sta_keepalive_arg *arg)
9818{
9819	struct ath11k_pdev_wmi *wmi = ar->wmi;
9820	struct wmi_sta_keepalive_cmd *cmd;
9821	struct wmi_sta_keepalive_arp_resp *arp;
9822	struct sk_buff *skb;
9823	size_t len;
9824
9825	len = sizeof(*cmd) + sizeof(*arp);
9826	skb = ath11k_wmi_alloc_skb(wmi->wmi_ab, len);
9827	if (!skb)
9828		return -ENOMEM;
9829
9830	cmd = (struct wmi_sta_keepalive_cmd *)skb->data;
9831	cmd->tlv_header = FIELD_PREP(WMI_TLV_TAG,
9832				     WMI_TAG_STA_KEEPALIVE_CMD) |
9833				     FIELD_PREP(WMI_TLV_LEN, sizeof(*cmd) - TLV_HDR_SIZE);
9834	cmd->vdev_id = arg->vdev_id;
9835	cmd->enabled = arg->enabled;
9836	cmd->interval = arg->interval;
9837	cmd->method = arg->method;
9838
9839	arp = (struct wmi_sta_keepalive_arp_resp *)(cmd + 1);
9840	arp->tlv_header = FIELD_PREP(WMI_TLV_TAG,
9841				     WMI_TAG_STA_KEEPALIVE_ARP_RESPONSE) |
9842			 FIELD_PREP(WMI_TLV_LEN, sizeof(*arp) - TLV_HDR_SIZE);
9843
9844	if (arg->method == WMI_STA_KEEPALIVE_METHOD_UNSOLICITED_ARP_RESPONSE ||
9845	    arg->method == WMI_STA_KEEPALIVE_METHOD_GRATUITOUS_ARP_REQUEST) {
9846		arp->src_ip4_addr = arg->src_ip4_addr;
9847		arp->dest_ip4_addr = arg->dest_ip4_addr;
9848		ether_addr_copy(arp->dest_mac_addr.addr, arg->dest_mac_addr);
9849	}
9850
9851	ath11k_dbg(ar->ab, ATH11K_DBG_WMI,
9852		   "sta keepalive vdev %d enabled %d method %d interval %d\n",
9853		   arg->vdev_id, arg->enabled, arg->method, arg->interval);
9854
9855	return ath11k_wmi_cmd_send(wmi, skb, WMI_STA_KEEPALIVE_CMDID);
9856}
9857
9858bool ath11k_wmi_supports_6ghz_cc_ext(struct ath11k *ar)
9859{
9860	return test_bit(WMI_TLV_SERVICE_REG_CC_EXT_EVENT_SUPPORT,
9861			ar->ab->wmi_ab.svc_map) && ar->supports_6ghz;
9862}