Linux Audio

Check our new training course

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