1 // SPDX-License-Identifier: BSD-3-Clause-Clear 2 /* 3 * Copyright (c) 2018-2019 The Linux Foundation. All rights reserved. 4 */ 5 #include <linux/skbuff.h> 6 #include <linux/ctype.h> 7 #include <net/mac80211.h> 8 #include <net/cfg80211.h> 9 #include <linux/completion.h> 10 #include <linux/if_ether.h> 11 #include <linux/types.h> 12 #include <linux/pci.h> 13 #include <linux/uuid.h> 14 #include <linux/time.h> 15 #include <linux/of.h> 16 #include "core.h" 17 #include "debug.h" 18 #include "mac.h" 19 #include "hw.h" 20 #include "peer.h" 21 22 struct wmi_tlv_policy { 23 size_t min_len; 24 }; 25 26 struct wmi_tlv_svc_ready_parse { 27 bool wmi_svc_bitmap_done; 28 }; 29 30 struct wmi_tlv_dma_ring_caps_parse { 31 struct wmi_dma_ring_capabilities *dma_ring_caps; 32 u32 n_dma_ring_caps; 33 }; 34 35 struct wmi_tlv_svc_rdy_ext_parse { 36 struct ath11k_service_ext_param param; 37 struct wmi_soc_mac_phy_hw_mode_caps *hw_caps; 38 struct wmi_hw_mode_capabilities *hw_mode_caps; 39 u32 n_hw_mode_caps; 40 u32 tot_phy_id; 41 struct wmi_hw_mode_capabilities pref_hw_mode_caps; 42 struct wmi_mac_phy_capabilities *mac_phy_caps; 43 u32 n_mac_phy_caps; 44 struct wmi_soc_hal_reg_capabilities *soc_hal_reg_caps; 45 struct wmi_hal_reg_capabilities_ext *ext_hal_reg_caps; 46 u32 n_ext_hal_reg_caps; 47 struct wmi_tlv_dma_ring_caps_parse dma_caps_parse; 48 bool hw_mode_done; 49 bool mac_phy_done; 50 bool ext_hal_reg_done; 51 bool mac_phy_chainmask_combo_done; 52 bool mac_phy_chainmask_cap_done; 53 bool oem_dma_ring_cap_done; 54 bool dma_ring_cap_done; 55 }; 56 57 struct wmi_tlv_svc_rdy_ext2_parse { 58 struct wmi_tlv_dma_ring_caps_parse dma_caps_parse; 59 bool dma_ring_cap_done; 60 }; 61 62 struct wmi_tlv_rdy_parse { 63 u32 num_extra_mac_addr; 64 }; 65 66 struct wmi_tlv_dma_buf_release_parse { 67 struct ath11k_wmi_dma_buf_release_fixed_param fixed; 68 struct wmi_dma_buf_release_entry *buf_entry; 69 struct wmi_dma_buf_release_meta_data *meta_data; 70 u32 num_buf_entry; 71 u32 num_meta; 72 bool buf_entry_done; 73 bool meta_data_done; 74 }; 75 76 static const struct wmi_tlv_policy wmi_tlv_policies[] = { 77 [WMI_TAG_ARRAY_BYTE] 78 = { .min_len = 0 }, 79 [WMI_TAG_ARRAY_UINT32] 80 = { .min_len = 0 }, 81 [WMI_TAG_SERVICE_READY_EVENT] 82 = { .min_len = sizeof(struct wmi_service_ready_event) }, 83 [WMI_TAG_SERVICE_READY_EXT_EVENT] 84 = { .min_len = sizeof(struct wmi_service_ready_ext_event) }, 85 [WMI_TAG_SOC_MAC_PHY_HW_MODE_CAPS] 86 = { .min_len = sizeof(struct wmi_soc_mac_phy_hw_mode_caps) }, 87 [WMI_TAG_SOC_HAL_REG_CAPABILITIES] 88 = { .min_len = sizeof(struct wmi_soc_hal_reg_capabilities) }, 89 [WMI_TAG_VDEV_START_RESPONSE_EVENT] 90 = { .min_len = sizeof(struct wmi_vdev_start_resp_event) }, 91 [WMI_TAG_PEER_DELETE_RESP_EVENT] 92 = { .min_len = sizeof(struct wmi_peer_delete_resp_event) }, 93 [WMI_TAG_OFFLOAD_BCN_TX_STATUS_EVENT] 94 = { .min_len = sizeof(struct wmi_bcn_tx_status_event) }, 95 [WMI_TAG_VDEV_STOPPED_EVENT] 96 = { .min_len = sizeof(struct wmi_vdev_stopped_event) }, 97 [WMI_TAG_REG_CHAN_LIST_CC_EVENT] 98 = { .min_len = sizeof(struct wmi_reg_chan_list_cc_event) }, 99 [WMI_TAG_MGMT_RX_HDR] 100 = { .min_len = sizeof(struct wmi_mgmt_rx_hdr) }, 101 [WMI_TAG_MGMT_TX_COMPL_EVENT] 102 = { .min_len = sizeof(struct wmi_mgmt_tx_compl_event) }, 103 [WMI_TAG_SCAN_EVENT] 104 = { .min_len = sizeof(struct wmi_scan_event) }, 105 [WMI_TAG_PEER_STA_KICKOUT_EVENT] 106 = { .min_len = sizeof(struct wmi_peer_sta_kickout_event) }, 107 [WMI_TAG_ROAM_EVENT] 108 = { .min_len = sizeof(struct wmi_roam_event) }, 109 [WMI_TAG_CHAN_INFO_EVENT] 110 = { .min_len = sizeof(struct wmi_chan_info_event) }, 111 [WMI_TAG_PDEV_BSS_CHAN_INFO_EVENT] 112 = { .min_len = sizeof(struct wmi_pdev_bss_chan_info_event) }, 113 [WMI_TAG_VDEV_INSTALL_KEY_COMPLETE_EVENT] 114 = { .min_len = sizeof(struct wmi_vdev_install_key_compl_event) }, 115 [WMI_TAG_READY_EVENT] = { 116 .min_len = sizeof(struct wmi_ready_event_min) }, 117 [WMI_TAG_SERVICE_AVAILABLE_EVENT] 118 = {.min_len = sizeof(struct wmi_service_available_event) }, 119 [WMI_TAG_PEER_ASSOC_CONF_EVENT] 120 = { .min_len = sizeof(struct wmi_peer_assoc_conf_event) }, 121 [WMI_TAG_STATS_EVENT] 122 = { .min_len = sizeof(struct wmi_stats_event) }, 123 [WMI_TAG_PDEV_CTL_FAILSAFE_CHECK_EVENT] 124 = { .min_len = sizeof(struct wmi_pdev_ctl_failsafe_chk_event) }, 125 [WMI_TAG_HOST_SWFDA_EVENT] = { 126 .min_len = sizeof(struct wmi_fils_discovery_event) }, 127 [WMI_TAG_OFFLOAD_PRB_RSP_TX_STATUS_EVENT] = { 128 .min_len = sizeof(struct wmi_probe_resp_tx_status_event) }, 129 [WMI_TAG_VDEV_DELETE_RESP_EVENT] = { 130 .min_len = sizeof(struct wmi_vdev_delete_resp_event) }, 131 }; 132 133 #define PRIMAP(_hw_mode_) \ 134 [_hw_mode_] = _hw_mode_##_PRI 135 136 static const int ath11k_hw_mode_pri_map[] = { 137 PRIMAP(WMI_HOST_HW_MODE_SINGLE), 138 PRIMAP(WMI_HOST_HW_MODE_DBS), 139 PRIMAP(WMI_HOST_HW_MODE_SBS_PASSIVE), 140 PRIMAP(WMI_HOST_HW_MODE_SBS), 141 PRIMAP(WMI_HOST_HW_MODE_DBS_SBS), 142 PRIMAP(WMI_HOST_HW_MODE_DBS_OR_SBS), 143 /* keep last */ 144 PRIMAP(WMI_HOST_HW_MODE_MAX), 145 }; 146 147 static int 148 ath11k_wmi_tlv_iter(struct ath11k_base *ab, const void *ptr, size_t len, 149 int (*iter)(struct ath11k_base *ab, u16 tag, u16 len, 150 const void *ptr, void *data), 151 void *data) 152 { 153 const void *begin = ptr; 154 const struct wmi_tlv *tlv; 155 u16 tlv_tag, tlv_len; 156 int ret; 157 158 while (len > 0) { 159 if (len < sizeof(*tlv)) { 160 ath11k_err(ab, "wmi tlv parse failure at byte %zd (%zu bytes left, %zu expected)\n", 161 ptr - begin, len, sizeof(*tlv)); 162 return -EINVAL; 163 } 164 165 tlv = ptr; 166 tlv_tag = FIELD_GET(WMI_TLV_TAG, tlv->header); 167 tlv_len = FIELD_GET(WMI_TLV_LEN, tlv->header); 168 ptr += sizeof(*tlv); 169 len -= sizeof(*tlv); 170 171 if (tlv_len > len) { 172 ath11k_err(ab, "wmi tlv parse failure of tag %u at byte %zd (%zu bytes left, %u expected)\n", 173 tlv_tag, ptr - begin, len, tlv_len); 174 return -EINVAL; 175 } 176 177 if (tlv_tag < ARRAY_SIZE(wmi_tlv_policies) && 178 wmi_tlv_policies[tlv_tag].min_len && 179 wmi_tlv_policies[tlv_tag].min_len > tlv_len) { 180 ath11k_err(ab, "wmi tlv parse failure of tag %u at byte %zd (%u bytes is less than min length %zu)\n", 181 tlv_tag, ptr - begin, tlv_len, 182 wmi_tlv_policies[tlv_tag].min_len); 183 return -EINVAL; 184 } 185 186 ret = iter(ab, tlv_tag, tlv_len, ptr, data); 187 if (ret) 188 return ret; 189 190 ptr += tlv_len; 191 len -= tlv_len; 192 } 193 194 return 0; 195 } 196 197 static int ath11k_wmi_tlv_iter_parse(struct ath11k_base *ab, u16 tag, u16 len, 198 const void *ptr, void *data) 199 { 200 const void **tb = data; 201 202 if (tag < WMI_TAG_MAX) 203 tb[tag] = ptr; 204 205 return 0; 206 } 207 208 static int ath11k_wmi_tlv_parse(struct ath11k_base *ar, const void **tb, 209 const void *ptr, size_t len) 210 { 211 return ath11k_wmi_tlv_iter(ar, ptr, len, ath11k_wmi_tlv_iter_parse, 212 (void *)tb); 213 } 214 215 static const void ** 216 ath11k_wmi_tlv_parse_alloc(struct ath11k_base *ab, const void *ptr, 217 size_t len, gfp_t gfp) 218 { 219 const void **tb; 220 int ret; 221 222 tb = kcalloc(WMI_TAG_MAX, sizeof(*tb), gfp); 223 if (!tb) 224 return ERR_PTR(-ENOMEM); 225 226 ret = ath11k_wmi_tlv_parse(ab, tb, ptr, len); 227 if (ret) { 228 kfree(tb); 229 return ERR_PTR(ret); 230 } 231 232 return tb; 233 } 234 235 static int ath11k_wmi_cmd_send_nowait(struct ath11k_pdev_wmi *wmi, struct sk_buff *skb, 236 u32 cmd_id) 237 { 238 struct ath11k_skb_cb *skb_cb = ATH11K_SKB_CB(skb); 239 struct ath11k_base *ab = wmi->wmi_ab->ab; 240 struct wmi_cmd_hdr *cmd_hdr; 241 int ret; 242 u32 cmd = 0; 243 244 if (skb_push(skb, sizeof(struct wmi_cmd_hdr)) == NULL) 245 return -ENOMEM; 246 247 cmd |= FIELD_PREP(WMI_CMD_HDR_CMD_ID, cmd_id); 248 249 cmd_hdr = (struct wmi_cmd_hdr *)skb->data; 250 cmd_hdr->cmd_id = cmd; 251 252 memset(skb_cb, 0, sizeof(*skb_cb)); 253 ret = ath11k_htc_send(&ab->htc, wmi->eid, skb); 254 255 if (ret) 256 goto err_pull; 257 258 return 0; 259 260 err_pull: 261 skb_pull(skb, sizeof(struct wmi_cmd_hdr)); 262 return ret; 263 } 264 265 int ath11k_wmi_cmd_send(struct ath11k_pdev_wmi *wmi, struct sk_buff *skb, 266 u32 cmd_id) 267 { 268 struct ath11k_wmi_base *wmi_sc = wmi->wmi_ab; 269 int ret = -EOPNOTSUPP; 270 271 might_sleep(); 272 273 wait_event_timeout(wmi_sc->tx_credits_wq, ({ 274 ret = ath11k_wmi_cmd_send_nowait(wmi, skb, cmd_id); 275 276 if (ret && test_bit(ATH11K_FLAG_CRASH_FLUSH, &wmi_sc->ab->dev_flags)) 277 ret = -ESHUTDOWN; 278 279 (ret != -EAGAIN); 280 }), WMI_SEND_TIMEOUT_HZ); 281 282 if (ret == -EAGAIN) 283 ath11k_warn(wmi_sc->ab, "wmi command %d timeout\n", cmd_id); 284 285 return ret; 286 } 287 288 static int ath11k_pull_svc_ready_ext(struct ath11k_pdev_wmi *wmi_handle, 289 const void *ptr, 290 struct ath11k_service_ext_param *param) 291 { 292 const struct wmi_service_ready_ext_event *ev = ptr; 293 294 if (!ev) 295 return -EINVAL; 296 297 /* Move this to host based bitmap */ 298 param->default_conc_scan_config_bits = ev->default_conc_scan_config_bits; 299 param->default_fw_config_bits = ev->default_fw_config_bits; 300 param->he_cap_info = ev->he_cap_info; 301 param->mpdu_density = ev->mpdu_density; 302 param->max_bssid_rx_filters = ev->max_bssid_rx_filters; 303 memcpy(¶m->ppet, &ev->ppet, sizeof(param->ppet)); 304 305 return 0; 306 } 307 308 static int 309 ath11k_pull_mac_phy_cap_svc_ready_ext(struct ath11k_pdev_wmi *wmi_handle, 310 struct wmi_soc_mac_phy_hw_mode_caps *hw_caps, 311 struct wmi_hw_mode_capabilities *wmi_hw_mode_caps, 312 struct wmi_soc_hal_reg_capabilities *hal_reg_caps, 313 struct wmi_mac_phy_capabilities *wmi_mac_phy_caps, 314 u8 hw_mode_id, u8 phy_id, 315 struct ath11k_pdev *pdev) 316 { 317 struct wmi_mac_phy_capabilities *mac_phy_caps; 318 struct ath11k_band_cap *cap_band; 319 struct ath11k_pdev_cap *pdev_cap = &pdev->cap; 320 u32 phy_map; 321 u32 hw_idx, phy_idx = 0; 322 323 if (!hw_caps || !wmi_hw_mode_caps || !hal_reg_caps) 324 return -EINVAL; 325 326 for (hw_idx = 0; hw_idx < hw_caps->num_hw_modes; hw_idx++) { 327 if (hw_mode_id == wmi_hw_mode_caps[hw_idx].hw_mode_id) 328 break; 329 330 phy_map = wmi_hw_mode_caps[hw_idx].phy_id_map; 331 while (phy_map) { 332 phy_map >>= 1; 333 phy_idx++; 334 } 335 } 336 337 if (hw_idx == hw_caps->num_hw_modes) 338 return -EINVAL; 339 340 phy_idx += phy_id; 341 if (phy_id >= hal_reg_caps->num_phy) 342 return -EINVAL; 343 344 mac_phy_caps = wmi_mac_phy_caps + phy_idx; 345 346 pdev->pdev_id = mac_phy_caps->pdev_id; 347 pdev_cap->supported_bands |= mac_phy_caps->supported_bands; 348 pdev_cap->ampdu_density = mac_phy_caps->ampdu_density; 349 350 /* Take non-zero tx/rx chainmask. If tx/rx chainmask differs from 351 * band to band for a single radio, need to see how this should be 352 * handled. 353 */ 354 if (mac_phy_caps->supported_bands & WMI_HOST_WLAN_2G_CAP) { 355 pdev_cap->tx_chain_mask = mac_phy_caps->tx_chain_mask_2g; 356 pdev_cap->rx_chain_mask = mac_phy_caps->rx_chain_mask_2g; 357 } else if (mac_phy_caps->supported_bands & WMI_HOST_WLAN_5G_CAP) { 358 pdev_cap->vht_cap = mac_phy_caps->vht_cap_info_5g; 359 pdev_cap->vht_mcs = mac_phy_caps->vht_supp_mcs_5g; 360 pdev_cap->he_mcs = mac_phy_caps->he_supp_mcs_5g; 361 pdev_cap->tx_chain_mask = mac_phy_caps->tx_chain_mask_5g; 362 pdev_cap->rx_chain_mask = mac_phy_caps->rx_chain_mask_5g; 363 } else { 364 return -EINVAL; 365 } 366 367 /* tx/rx chainmask reported from fw depends on the actual hw chains used, 368 * For example, for 4x4 capable macphys, first 4 chains can be used for first 369 * mac and the remaing 4 chains can be used for the second mac or vice-versa. 370 * In this case, tx/rx chainmask 0xf will be advertised for first mac and 0xf0 371 * will be advertised for second mac or vice-versa. Compute the shift value 372 * for tx/rx chainmask which will be used to advertise supported ht/vht rates to 373 * mac80211. 374 */ 375 pdev_cap->tx_chain_mask_shift = 376 find_first_bit((unsigned long *)&pdev_cap->tx_chain_mask, 32); 377 pdev_cap->rx_chain_mask_shift = 378 find_first_bit((unsigned long *)&pdev_cap->rx_chain_mask, 32); 379 380 if (mac_phy_caps->supported_bands & WMI_HOST_WLAN_2G_CAP) { 381 cap_band = &pdev_cap->band[NL80211_BAND_2GHZ]; 382 cap_band->phy_id = mac_phy_caps->phy_id; 383 cap_band->max_bw_supported = mac_phy_caps->max_bw_supported_2g; 384 cap_band->ht_cap_info = mac_phy_caps->ht_cap_info_2g; 385 cap_band->he_cap_info[0] = mac_phy_caps->he_cap_info_2g; 386 cap_band->he_cap_info[1] = mac_phy_caps->he_cap_info_2g_ext; 387 cap_band->he_mcs = mac_phy_caps->he_supp_mcs_2g; 388 memcpy(cap_band->he_cap_phy_info, &mac_phy_caps->he_cap_phy_info_2g, 389 sizeof(u32) * PSOC_HOST_MAX_PHY_SIZE); 390 memcpy(&cap_band->he_ppet, &mac_phy_caps->he_ppet2g, 391 sizeof(struct ath11k_ppe_threshold)); 392 } 393 394 if (mac_phy_caps->supported_bands & WMI_HOST_WLAN_5G_CAP) { 395 cap_band = &pdev_cap->band[NL80211_BAND_5GHZ]; 396 cap_band->phy_id = mac_phy_caps->phy_id; 397 cap_band->max_bw_supported = mac_phy_caps->max_bw_supported_5g; 398 cap_band->ht_cap_info = mac_phy_caps->ht_cap_info_5g; 399 cap_band->he_cap_info[0] = mac_phy_caps->he_cap_info_5g; 400 cap_band->he_cap_info[1] = mac_phy_caps->he_cap_info_5g_ext; 401 cap_band->he_mcs = mac_phy_caps->he_supp_mcs_5g; 402 memcpy(cap_band->he_cap_phy_info, &mac_phy_caps->he_cap_phy_info_5g, 403 sizeof(u32) * PSOC_HOST_MAX_PHY_SIZE); 404 memcpy(&cap_band->he_ppet, &mac_phy_caps->he_ppet5g, 405 sizeof(struct ath11k_ppe_threshold)); 406 } 407 408 cap_band = &pdev_cap->band[NL80211_BAND_6GHZ]; 409 cap_band->max_bw_supported = mac_phy_caps->max_bw_supported_5g; 410 cap_band->ht_cap_info = mac_phy_caps->ht_cap_info_5g; 411 cap_band->he_cap_info[0] = mac_phy_caps->he_cap_info_5g; 412 cap_band->he_cap_info[1] = mac_phy_caps->he_cap_info_5g_ext; 413 cap_band->he_mcs = mac_phy_caps->he_supp_mcs_5g; 414 memcpy(cap_band->he_cap_phy_info, &mac_phy_caps->he_cap_phy_info_5g, 415 sizeof(u32) * PSOC_HOST_MAX_PHY_SIZE); 416 memcpy(&cap_band->he_ppet, &mac_phy_caps->he_ppet5g, 417 sizeof(struct ath11k_ppe_threshold)); 418 419 return 0; 420 } 421 422 static int 423 ath11k_pull_reg_cap_svc_rdy_ext(struct ath11k_pdev_wmi *wmi_handle, 424 struct wmi_soc_hal_reg_capabilities *reg_caps, 425 struct wmi_hal_reg_capabilities_ext *wmi_ext_reg_cap, 426 u8 phy_idx, 427 struct ath11k_hal_reg_capabilities_ext *param) 428 { 429 struct wmi_hal_reg_capabilities_ext *ext_reg_cap; 430 431 if (!reg_caps || !wmi_ext_reg_cap) 432 return -EINVAL; 433 434 if (phy_idx >= reg_caps->num_phy) 435 return -EINVAL; 436 437 ext_reg_cap = &wmi_ext_reg_cap[phy_idx]; 438 439 param->phy_id = ext_reg_cap->phy_id; 440 param->eeprom_reg_domain = ext_reg_cap->eeprom_reg_domain; 441 param->eeprom_reg_domain_ext = 442 ext_reg_cap->eeprom_reg_domain_ext; 443 param->regcap1 = ext_reg_cap->regcap1; 444 param->regcap2 = ext_reg_cap->regcap2; 445 /* check if param->wireless_mode is needed */ 446 param->low_2ghz_chan = ext_reg_cap->low_2ghz_chan; 447 param->high_2ghz_chan = ext_reg_cap->high_2ghz_chan; 448 param->low_5ghz_chan = ext_reg_cap->low_5ghz_chan; 449 param->high_5ghz_chan = ext_reg_cap->high_5ghz_chan; 450 451 return 0; 452 } 453 454 static int ath11k_pull_service_ready_tlv(struct ath11k_base *ab, 455 const void *evt_buf, 456 struct ath11k_targ_cap *cap) 457 { 458 const struct wmi_service_ready_event *ev = evt_buf; 459 460 if (!ev) { 461 ath11k_err(ab, "%s: failed by NULL param\n", 462 __func__); 463 return -EINVAL; 464 } 465 466 cap->phy_capability = ev->phy_capability; 467 cap->max_frag_entry = ev->max_frag_entry; 468 cap->num_rf_chains = ev->num_rf_chains; 469 cap->ht_cap_info = ev->ht_cap_info; 470 cap->vht_cap_info = ev->vht_cap_info; 471 cap->vht_supp_mcs = ev->vht_supp_mcs; 472 cap->hw_min_tx_power = ev->hw_min_tx_power; 473 cap->hw_max_tx_power = ev->hw_max_tx_power; 474 cap->sys_cap_info = ev->sys_cap_info; 475 cap->min_pkt_size_enable = ev->min_pkt_size_enable; 476 cap->max_bcn_ie_size = ev->max_bcn_ie_size; 477 cap->max_num_scan_channels = ev->max_num_scan_channels; 478 cap->max_supported_macs = ev->max_supported_macs; 479 cap->wmi_fw_sub_feat_caps = ev->wmi_fw_sub_feat_caps; 480 cap->txrx_chainmask = ev->txrx_chainmask; 481 cap->default_dbs_hw_mode_index = ev->default_dbs_hw_mode_index; 482 cap->num_msdu_desc = ev->num_msdu_desc; 483 484 return 0; 485 } 486 487 /* Save the wmi_service_bitmap into a linear bitmap. The wmi_services in 488 * wmi_service ready event are advertised in b0-b3 (LSB 4-bits) of each 489 * 4-byte word. 490 */ 491 static void ath11k_wmi_service_bitmap_copy(struct ath11k_pdev_wmi *wmi, 492 const u32 *wmi_svc_bm) 493 { 494 int i, j; 495 496 for (i = 0, j = 0; i < WMI_SERVICE_BM_SIZE && j < WMI_MAX_SERVICE; i++) { 497 do { 498 if (wmi_svc_bm[i] & BIT(j % WMI_SERVICE_BITS_IN_SIZE32)) 499 set_bit(j, wmi->wmi_ab->svc_map); 500 } while (++j % WMI_SERVICE_BITS_IN_SIZE32); 501 } 502 } 503 504 static int ath11k_wmi_tlv_svc_rdy_parse(struct ath11k_base *ab, u16 tag, u16 len, 505 const void *ptr, void *data) 506 { 507 struct wmi_tlv_svc_ready_parse *svc_ready = data; 508 struct ath11k_pdev_wmi *wmi_handle = &ab->wmi_ab.wmi[0]; 509 u16 expect_len; 510 511 switch (tag) { 512 case WMI_TAG_SERVICE_READY_EVENT: 513 if (ath11k_pull_service_ready_tlv(ab, ptr, &ab->target_caps)) 514 return -EINVAL; 515 break; 516 517 case WMI_TAG_ARRAY_UINT32: 518 if (!svc_ready->wmi_svc_bitmap_done) { 519 expect_len = WMI_SERVICE_BM_SIZE * sizeof(u32); 520 if (len < expect_len) { 521 ath11k_warn(ab, "invalid len %d for the tag 0x%x\n", 522 len, tag); 523 return -EINVAL; 524 } 525 526 ath11k_wmi_service_bitmap_copy(wmi_handle, ptr); 527 528 svc_ready->wmi_svc_bitmap_done = true; 529 } 530 break; 531 default: 532 break; 533 } 534 535 return 0; 536 } 537 538 static int ath11k_service_ready_event(struct ath11k_base *ab, struct sk_buff *skb) 539 { 540 struct wmi_tlv_svc_ready_parse svc_ready = { }; 541 int ret; 542 543 ret = ath11k_wmi_tlv_iter(ab, skb->data, skb->len, 544 ath11k_wmi_tlv_svc_rdy_parse, 545 &svc_ready); 546 if (ret) { 547 ath11k_warn(ab, "failed to parse tlv %d\n", ret); 548 return ret; 549 } 550 551 return 0; 552 } 553 554 struct sk_buff *ath11k_wmi_alloc_skb(struct ath11k_wmi_base *wmi_sc, u32 len) 555 { 556 struct sk_buff *skb; 557 struct ath11k_base *ab = wmi_sc->ab; 558 u32 round_len = roundup(len, 4); 559 560 skb = ath11k_htc_alloc_skb(ab, WMI_SKB_HEADROOM + round_len); 561 if (!skb) 562 return NULL; 563 564 skb_reserve(skb, WMI_SKB_HEADROOM); 565 if (!IS_ALIGNED((unsigned long)skb->data, 4)) 566 ath11k_warn(ab, "unaligned WMI skb data\n"); 567 568 skb_put(skb, round_len); 569 memset(skb->data, 0, round_len); 570 571 return skb; 572 } 573 574 int ath11k_wmi_mgmt_send(struct ath11k *ar, u32 vdev_id, u32 buf_id, 575 struct sk_buff *frame) 576 { 577 struct ath11k_pdev_wmi *wmi = ar->wmi; 578 struct wmi_mgmt_send_cmd *cmd; 579 struct wmi_tlv *frame_tlv; 580 struct sk_buff *skb; 581 u32 buf_len; 582 int ret, len; 583 584 buf_len = frame->len < WMI_MGMT_SEND_DOWNLD_LEN ? 585 frame->len : WMI_MGMT_SEND_DOWNLD_LEN; 586 587 len = sizeof(*cmd) + sizeof(*frame_tlv) + roundup(buf_len, 4); 588 589 skb = ath11k_wmi_alloc_skb(wmi->wmi_ab, len); 590 if (!skb) 591 return -ENOMEM; 592 593 cmd = (struct wmi_mgmt_send_cmd *)skb->data; 594 cmd->tlv_header = FIELD_PREP(WMI_TLV_TAG, WMI_TAG_MGMT_TX_SEND_CMD) | 595 FIELD_PREP(WMI_TLV_LEN, sizeof(*cmd) - TLV_HDR_SIZE); 596 cmd->vdev_id = vdev_id; 597 cmd->desc_id = buf_id; 598 cmd->chanfreq = 0; 599 cmd->paddr_lo = lower_32_bits(ATH11K_SKB_CB(frame)->paddr); 600 cmd->paddr_hi = upper_32_bits(ATH11K_SKB_CB(frame)->paddr); 601 cmd->frame_len = frame->len; 602 cmd->buf_len = buf_len; 603 cmd->tx_params_valid = 0; 604 605 frame_tlv = (struct wmi_tlv *)(skb->data + sizeof(*cmd)); 606 frame_tlv->header = FIELD_PREP(WMI_TLV_TAG, WMI_TAG_ARRAY_BYTE) | 607 FIELD_PREP(WMI_TLV_LEN, buf_len); 608 609 memcpy(frame_tlv->value, frame->data, buf_len); 610 611 ath11k_ce_byte_swap(frame_tlv->value, buf_len); 612 613 ret = ath11k_wmi_cmd_send(wmi, skb, WMI_MGMT_TX_SEND_CMDID); 614 if (ret) { 615 ath11k_warn(ar->ab, 616 "failed to submit WMI_MGMT_TX_SEND_CMDID cmd\n"); 617 dev_kfree_skb(skb); 618 } 619 620 return ret; 621 } 622 623 int ath11k_wmi_vdev_create(struct ath11k *ar, u8 *macaddr, 624 struct vdev_create_params *param) 625 { 626 struct ath11k_pdev_wmi *wmi = ar->wmi; 627 struct wmi_vdev_create_cmd *cmd; 628 struct sk_buff *skb; 629 struct wmi_vdev_txrx_streams *txrx_streams; 630 struct wmi_tlv *tlv; 631 int ret, len; 632 void *ptr; 633 634 /* It can be optimized my sending tx/rx chain configuration 635 * only for supported bands instead of always sending it for 636 * both the bands. 637 */ 638 len = sizeof(*cmd) + TLV_HDR_SIZE + 639 (WMI_NUM_SUPPORTED_BAND_MAX * sizeof(*txrx_streams)); 640 641 skb = ath11k_wmi_alloc_skb(wmi->wmi_ab, len); 642 if (!skb) 643 return -ENOMEM; 644 645 cmd = (struct wmi_vdev_create_cmd *)skb->data; 646 cmd->tlv_header = FIELD_PREP(WMI_TLV_TAG, WMI_TAG_VDEV_CREATE_CMD) | 647 FIELD_PREP(WMI_TLV_LEN, sizeof(*cmd) - TLV_HDR_SIZE); 648 649 cmd->vdev_id = param->if_id; 650 cmd->vdev_type = param->type; 651 cmd->vdev_subtype = param->subtype; 652 cmd->num_cfg_txrx_streams = WMI_NUM_SUPPORTED_BAND_MAX; 653 cmd->pdev_id = param->pdev_id; 654 ether_addr_copy(cmd->vdev_macaddr.addr, macaddr); 655 656 ptr = skb->data + sizeof(*cmd); 657 len = WMI_NUM_SUPPORTED_BAND_MAX * sizeof(*txrx_streams); 658 659 tlv = ptr; 660 tlv->header = FIELD_PREP(WMI_TLV_TAG, WMI_TAG_ARRAY_STRUCT) | 661 FIELD_PREP(WMI_TLV_LEN, len); 662 663 ptr += TLV_HDR_SIZE; 664 txrx_streams = ptr; 665 len = sizeof(*txrx_streams); 666 txrx_streams->tlv_header = 667 FIELD_PREP(WMI_TLV_TAG, WMI_TAG_VDEV_TXRX_STREAMS) | 668 FIELD_PREP(WMI_TLV_LEN, len - TLV_HDR_SIZE); 669 txrx_streams->band = WMI_TPC_CHAINMASK_CONFIG_BAND_2G; 670 txrx_streams->supported_tx_streams = 671 param->chains[NL80211_BAND_2GHZ].tx; 672 txrx_streams->supported_rx_streams = 673 param->chains[NL80211_BAND_2GHZ].rx; 674 675 txrx_streams++; 676 txrx_streams->tlv_header = 677 FIELD_PREP(WMI_TLV_TAG, WMI_TAG_VDEV_TXRX_STREAMS) | 678 FIELD_PREP(WMI_TLV_LEN, len - TLV_HDR_SIZE); 679 txrx_streams->band = WMI_TPC_CHAINMASK_CONFIG_BAND_5G; 680 txrx_streams->supported_tx_streams = 681 param->chains[NL80211_BAND_5GHZ].tx; 682 txrx_streams->supported_rx_streams = 683 param->chains[NL80211_BAND_5GHZ].rx; 684 685 ret = ath11k_wmi_cmd_send(wmi, skb, WMI_VDEV_CREATE_CMDID); 686 if (ret) { 687 ath11k_warn(ar->ab, 688 "failed to submit WMI_VDEV_CREATE_CMDID\n"); 689 dev_kfree_skb(skb); 690 } 691 692 ath11k_dbg(ar->ab, ATH11K_DBG_WMI, 693 "WMI vdev create: id %d type %d subtype %d macaddr %pM pdevid %d\n", 694 param->if_id, param->type, param->subtype, 695 macaddr, param->pdev_id); 696 697 return ret; 698 } 699 700 int ath11k_wmi_vdev_delete(struct ath11k *ar, u8 vdev_id) 701 { 702 struct ath11k_pdev_wmi *wmi = ar->wmi; 703 struct wmi_vdev_delete_cmd *cmd; 704 struct sk_buff *skb; 705 int ret; 706 707 skb = ath11k_wmi_alloc_skb(wmi->wmi_ab, sizeof(*cmd)); 708 if (!skb) 709 return -ENOMEM; 710 711 cmd = (struct wmi_vdev_delete_cmd *)skb->data; 712 cmd->tlv_header = FIELD_PREP(WMI_TLV_TAG, WMI_TAG_VDEV_DELETE_CMD) | 713 FIELD_PREP(WMI_TLV_LEN, sizeof(*cmd) - TLV_HDR_SIZE); 714 cmd->vdev_id = vdev_id; 715 716 ret = ath11k_wmi_cmd_send(wmi, skb, WMI_VDEV_DELETE_CMDID); 717 if (ret) { 718 ath11k_warn(ar->ab, "failed to submit WMI_VDEV_DELETE_CMDID\n"); 719 dev_kfree_skb(skb); 720 } 721 722 ath11k_dbg(ar->ab, ATH11K_DBG_WMI, "WMI vdev delete id %d\n", vdev_id); 723 724 return ret; 725 } 726 727 int ath11k_wmi_vdev_stop(struct ath11k *ar, u8 vdev_id) 728 { 729 struct ath11k_pdev_wmi *wmi = ar->wmi; 730 struct wmi_vdev_stop_cmd *cmd; 731 struct sk_buff *skb; 732 int ret; 733 734 skb = ath11k_wmi_alloc_skb(wmi->wmi_ab, sizeof(*cmd)); 735 if (!skb) 736 return -ENOMEM; 737 738 cmd = (struct wmi_vdev_stop_cmd *)skb->data; 739 740 cmd->tlv_header = FIELD_PREP(WMI_TLV_TAG, WMI_TAG_VDEV_STOP_CMD) | 741 FIELD_PREP(WMI_TLV_LEN, sizeof(*cmd) - TLV_HDR_SIZE); 742 cmd->vdev_id = vdev_id; 743 744 ret = ath11k_wmi_cmd_send(wmi, skb, WMI_VDEV_STOP_CMDID); 745 if (ret) { 746 ath11k_warn(ar->ab, "failed to submit WMI_VDEV_STOP cmd\n"); 747 dev_kfree_skb(skb); 748 } 749 750 ath11k_dbg(ar->ab, ATH11K_DBG_WMI, "WMI vdev stop id 0x%x\n", vdev_id); 751 752 return ret; 753 } 754 755 int ath11k_wmi_vdev_down(struct ath11k *ar, u8 vdev_id) 756 { 757 struct ath11k_pdev_wmi *wmi = ar->wmi; 758 struct wmi_vdev_down_cmd *cmd; 759 struct sk_buff *skb; 760 int ret; 761 762 skb = ath11k_wmi_alloc_skb(wmi->wmi_ab, sizeof(*cmd)); 763 if (!skb) 764 return -ENOMEM; 765 766 cmd = (struct wmi_vdev_down_cmd *)skb->data; 767 768 cmd->tlv_header = FIELD_PREP(WMI_TLV_TAG, WMI_TAG_VDEV_DOWN_CMD) | 769 FIELD_PREP(WMI_TLV_LEN, sizeof(*cmd) - TLV_HDR_SIZE); 770 cmd->vdev_id = vdev_id; 771 772 ret = ath11k_wmi_cmd_send(wmi, skb, WMI_VDEV_DOWN_CMDID); 773 if (ret) { 774 ath11k_warn(ar->ab, "failed to submit WMI_VDEV_DOWN cmd\n"); 775 dev_kfree_skb(skb); 776 } 777 778 ath11k_dbg(ar->ab, ATH11K_DBG_WMI, "WMI vdev down id 0x%x\n", vdev_id); 779 780 return ret; 781 } 782 783 static void ath11k_wmi_put_wmi_channel(struct wmi_channel *chan, 784 struct wmi_vdev_start_req_arg *arg) 785 { 786 memset(chan, 0, sizeof(*chan)); 787 788 chan->mhz = arg->channel.freq; 789 chan->band_center_freq1 = arg->channel.band_center_freq1; 790 if (arg->channel.mode == MODE_11AC_VHT80_80) 791 chan->band_center_freq2 = arg->channel.band_center_freq2; 792 else 793 chan->band_center_freq2 = 0; 794 795 chan->info |= FIELD_PREP(WMI_CHAN_INFO_MODE, arg->channel.mode); 796 if (arg->channel.passive) 797 chan->info |= WMI_CHAN_INFO_PASSIVE; 798 if (arg->channel.allow_ibss) 799 chan->info |= WMI_CHAN_INFO_ADHOC_ALLOWED; 800 if (arg->channel.allow_ht) 801 chan->info |= WMI_CHAN_INFO_ALLOW_HT; 802 if (arg->channel.allow_vht) 803 chan->info |= WMI_CHAN_INFO_ALLOW_VHT; 804 if (arg->channel.allow_he) 805 chan->info |= WMI_CHAN_INFO_ALLOW_HE; 806 if (arg->channel.ht40plus) 807 chan->info |= WMI_CHAN_INFO_HT40_PLUS; 808 if (arg->channel.chan_radar) 809 chan->info |= WMI_CHAN_INFO_DFS; 810 if (arg->channel.freq2_radar) 811 chan->info |= WMI_CHAN_INFO_DFS_FREQ2; 812 813 chan->reg_info_1 = FIELD_PREP(WMI_CHAN_REG_INFO1_MAX_PWR, 814 arg->channel.max_power) | 815 FIELD_PREP(WMI_CHAN_REG_INFO1_MAX_REG_PWR, 816 arg->channel.max_reg_power); 817 818 chan->reg_info_2 = FIELD_PREP(WMI_CHAN_REG_INFO2_ANT_MAX, 819 arg->channel.max_antenna_gain) | 820 FIELD_PREP(WMI_CHAN_REG_INFO2_MAX_TX_PWR, 821 arg->channel.max_power); 822 } 823 824 int ath11k_wmi_vdev_start(struct ath11k *ar, struct wmi_vdev_start_req_arg *arg, 825 bool restart) 826 { 827 struct ath11k_pdev_wmi *wmi = ar->wmi; 828 struct wmi_vdev_start_request_cmd *cmd; 829 struct sk_buff *skb; 830 struct wmi_channel *chan; 831 struct wmi_tlv *tlv; 832 void *ptr; 833 int ret, len; 834 835 if (WARN_ON(arg->ssid_len > sizeof(cmd->ssid.ssid))) 836 return -EINVAL; 837 838 len = sizeof(*cmd) + sizeof(*chan) + TLV_HDR_SIZE; 839 840 skb = ath11k_wmi_alloc_skb(wmi->wmi_ab, len); 841 if (!skb) 842 return -ENOMEM; 843 844 cmd = (struct wmi_vdev_start_request_cmd *)skb->data; 845 cmd->tlv_header = FIELD_PREP(WMI_TLV_TAG, 846 WMI_TAG_VDEV_START_REQUEST_CMD) | 847 FIELD_PREP(WMI_TLV_LEN, sizeof(*cmd) - TLV_HDR_SIZE); 848 cmd->vdev_id = arg->vdev_id; 849 cmd->beacon_interval = arg->bcn_intval; 850 cmd->bcn_tx_rate = arg->bcn_tx_rate; 851 cmd->dtim_period = arg->dtim_period; 852 cmd->num_noa_descriptors = arg->num_noa_descriptors; 853 cmd->preferred_rx_streams = arg->pref_rx_streams; 854 cmd->preferred_tx_streams = arg->pref_tx_streams; 855 cmd->cac_duration_ms = arg->cac_duration_ms; 856 cmd->regdomain = arg->regdomain; 857 cmd->he_ops = arg->he_ops; 858 859 if (!restart) { 860 if (arg->ssid) { 861 cmd->ssid.ssid_len = arg->ssid_len; 862 memcpy(cmd->ssid.ssid, arg->ssid, arg->ssid_len); 863 } 864 if (arg->hidden_ssid) 865 cmd->flags |= WMI_VDEV_START_HIDDEN_SSID; 866 if (arg->pmf_enabled) 867 cmd->flags |= WMI_VDEV_START_PMF_ENABLED; 868 } 869 870 cmd->flags |= WMI_VDEV_START_LDPC_RX_ENABLED; 871 872 ptr = skb->data + sizeof(*cmd); 873 chan = ptr; 874 875 ath11k_wmi_put_wmi_channel(chan, arg); 876 877 chan->tlv_header = FIELD_PREP(WMI_TLV_TAG, WMI_TAG_CHANNEL) | 878 FIELD_PREP(WMI_TLV_LEN, 879 sizeof(*chan) - TLV_HDR_SIZE); 880 ptr += sizeof(*chan); 881 882 tlv = ptr; 883 tlv->header = FIELD_PREP(WMI_TLV_TAG, WMI_TAG_ARRAY_STRUCT) | 884 FIELD_PREP(WMI_TLV_LEN, 0); 885 886 /* Note: This is a nested TLV containing: 887 * [wmi_tlv][wmi_p2p_noa_descriptor][wmi_tlv].. 888 */ 889 890 ptr += sizeof(*tlv); 891 892 if (restart) 893 ret = ath11k_wmi_cmd_send(wmi, skb, 894 WMI_VDEV_RESTART_REQUEST_CMDID); 895 else 896 ret = ath11k_wmi_cmd_send(wmi, skb, 897 WMI_VDEV_START_REQUEST_CMDID); 898 if (ret) { 899 ath11k_warn(ar->ab, "failed to submit vdev_%s cmd\n", 900 restart ? "restart" : "start"); 901 dev_kfree_skb(skb); 902 } 903 904 ath11k_dbg(ar->ab, ATH11K_DBG_WMI, "vdev %s id 0x%x freq 0x%x mode 0x%x\n", 905 restart ? "restart" : "start", arg->vdev_id, 906 arg->channel.freq, arg->channel.mode); 907 908 return ret; 909 } 910 911 int ath11k_wmi_vdev_up(struct ath11k *ar, u32 vdev_id, u32 aid, const u8 *bssid) 912 { 913 struct ath11k_pdev_wmi *wmi = ar->wmi; 914 struct wmi_vdev_up_cmd *cmd; 915 struct sk_buff *skb; 916 int ret; 917 918 skb = ath11k_wmi_alloc_skb(wmi->wmi_ab, sizeof(*cmd)); 919 if (!skb) 920 return -ENOMEM; 921 922 cmd = (struct wmi_vdev_up_cmd *)skb->data; 923 924 cmd->tlv_header = FIELD_PREP(WMI_TLV_TAG, WMI_TAG_VDEV_UP_CMD) | 925 FIELD_PREP(WMI_TLV_LEN, sizeof(*cmd) - TLV_HDR_SIZE); 926 cmd->vdev_id = vdev_id; 927 cmd->vdev_assoc_id = aid; 928 929 ether_addr_copy(cmd->vdev_bssid.addr, bssid); 930 931 ret = ath11k_wmi_cmd_send(wmi, skb, WMI_VDEV_UP_CMDID); 932 if (ret) { 933 ath11k_warn(ar->ab, "failed to submit WMI_VDEV_UP cmd\n"); 934 dev_kfree_skb(skb); 935 } 936 937 ath11k_dbg(ar->ab, ATH11K_DBG_WMI, 938 "WMI mgmt vdev up id 0x%x assoc id %d bssid %pM\n", 939 vdev_id, aid, bssid); 940 941 return ret; 942 } 943 944 int ath11k_wmi_send_peer_create_cmd(struct ath11k *ar, 945 struct peer_create_params *param) 946 { 947 struct ath11k_pdev_wmi *wmi = ar->wmi; 948 struct wmi_peer_create_cmd *cmd; 949 struct sk_buff *skb; 950 int ret; 951 952 skb = ath11k_wmi_alloc_skb(wmi->wmi_ab, sizeof(*cmd)); 953 if (!skb) 954 return -ENOMEM; 955 956 cmd = (struct wmi_peer_create_cmd *)skb->data; 957 cmd->tlv_header = FIELD_PREP(WMI_TLV_TAG, WMI_TAG_PEER_CREATE_CMD) | 958 FIELD_PREP(WMI_TLV_LEN, sizeof(*cmd) - TLV_HDR_SIZE); 959 960 ether_addr_copy(cmd->peer_macaddr.addr, param->peer_addr); 961 cmd->peer_type = param->peer_type; 962 cmd->vdev_id = param->vdev_id; 963 964 ret = ath11k_wmi_cmd_send(wmi, skb, WMI_PEER_CREATE_CMDID); 965 if (ret) { 966 ath11k_warn(ar->ab, "failed to submit WMI_PEER_CREATE cmd\n"); 967 dev_kfree_skb(skb); 968 } 969 970 ath11k_dbg(ar->ab, ATH11K_DBG_WMI, 971 "WMI peer create vdev_id %d peer_addr %pM\n", 972 param->vdev_id, param->peer_addr); 973 974 return ret; 975 } 976 977 int ath11k_wmi_send_peer_delete_cmd(struct ath11k *ar, 978 const u8 *peer_addr, u8 vdev_id) 979 { 980 struct ath11k_pdev_wmi *wmi = ar->wmi; 981 struct wmi_peer_delete_cmd *cmd; 982 struct sk_buff *skb; 983 int ret; 984 985 skb = ath11k_wmi_alloc_skb(wmi->wmi_ab, sizeof(*cmd)); 986 if (!skb) 987 return -ENOMEM; 988 989 cmd = (struct wmi_peer_delete_cmd *)skb->data; 990 cmd->tlv_header = FIELD_PREP(WMI_TLV_TAG, WMI_TAG_PEER_DELETE_CMD) | 991 FIELD_PREP(WMI_TLV_LEN, sizeof(*cmd) - TLV_HDR_SIZE); 992 993 ether_addr_copy(cmd->peer_macaddr.addr, peer_addr); 994 cmd->vdev_id = vdev_id; 995 996 ath11k_dbg(ar->ab, ATH11K_DBG_WMI, 997 "WMI peer delete vdev_id %d peer_addr %pM\n", 998 vdev_id, peer_addr); 999 1000 ret = ath11k_wmi_cmd_send(wmi, skb, WMI_PEER_DELETE_CMDID); 1001 if (ret) { 1002 ath11k_warn(ar->ab, "failed to send WMI_PEER_DELETE cmd\n"); 1003 dev_kfree_skb(skb); 1004 } 1005 1006 return ret; 1007 } 1008 1009 int ath11k_wmi_send_pdev_set_regdomain(struct ath11k *ar, 1010 struct pdev_set_regdomain_params *param) 1011 { 1012 struct ath11k_pdev_wmi *wmi = ar->wmi; 1013 struct wmi_pdev_set_regdomain_cmd *cmd; 1014 struct sk_buff *skb; 1015 int ret; 1016 1017 skb = ath11k_wmi_alloc_skb(wmi->wmi_ab, sizeof(*cmd)); 1018 if (!skb) 1019 return -ENOMEM; 1020 1021 cmd = (struct wmi_pdev_set_regdomain_cmd *)skb->data; 1022 cmd->tlv_header = FIELD_PREP(WMI_TLV_TAG, 1023 WMI_TAG_PDEV_SET_REGDOMAIN_CMD) | 1024 FIELD_PREP(WMI_TLV_LEN, sizeof(*cmd) - TLV_HDR_SIZE); 1025 1026 cmd->reg_domain = param->current_rd_in_use; 1027 cmd->reg_domain_2g = param->current_rd_2g; 1028 cmd->reg_domain_5g = param->current_rd_5g; 1029 cmd->conformance_test_limit_2g = param->ctl_2g; 1030 cmd->conformance_test_limit_5g = param->ctl_5g; 1031 cmd->dfs_domain = param->dfs_domain; 1032 cmd->pdev_id = param->pdev_id; 1033 1034 ath11k_dbg(ar->ab, ATH11K_DBG_WMI, 1035 "WMI pdev regd rd %d rd2g %d rd5g %d domain %d pdev id %d\n", 1036 param->current_rd_in_use, param->current_rd_2g, 1037 param->current_rd_5g, param->dfs_domain, param->pdev_id); 1038 1039 ret = ath11k_wmi_cmd_send(wmi, skb, WMI_PDEV_SET_REGDOMAIN_CMDID); 1040 if (ret) { 1041 ath11k_warn(ar->ab, 1042 "failed to send WMI_PDEV_SET_REGDOMAIN cmd\n"); 1043 dev_kfree_skb(skb); 1044 } 1045 1046 return ret; 1047 } 1048 1049 int ath11k_wmi_set_peer_param(struct ath11k *ar, const u8 *peer_addr, 1050 u32 vdev_id, u32 param_id, u32 param_val) 1051 { 1052 struct ath11k_pdev_wmi *wmi = ar->wmi; 1053 struct wmi_peer_set_param_cmd *cmd; 1054 struct sk_buff *skb; 1055 int ret; 1056 1057 skb = ath11k_wmi_alloc_skb(wmi->wmi_ab, sizeof(*cmd)); 1058 if (!skb) 1059 return -ENOMEM; 1060 1061 cmd = (struct wmi_peer_set_param_cmd *)skb->data; 1062 cmd->tlv_header = FIELD_PREP(WMI_TLV_TAG, WMI_TAG_PEER_SET_PARAM_CMD) | 1063 FIELD_PREP(WMI_TLV_LEN, sizeof(*cmd) - TLV_HDR_SIZE); 1064 ether_addr_copy(cmd->peer_macaddr.addr, peer_addr); 1065 cmd->vdev_id = vdev_id; 1066 cmd->param_id = param_id; 1067 cmd->param_value = param_val; 1068 1069 ret = ath11k_wmi_cmd_send(wmi, skb, WMI_PEER_SET_PARAM_CMDID); 1070 if (ret) { 1071 ath11k_warn(ar->ab, "failed to send WMI_PEER_SET_PARAM cmd\n"); 1072 dev_kfree_skb(skb); 1073 } 1074 1075 ath11k_dbg(ar->ab, ATH11K_DBG_WMI, 1076 "WMI vdev %d peer 0x%pM set param %d value %d\n", 1077 vdev_id, peer_addr, param_id, param_val); 1078 1079 return ret; 1080 } 1081 1082 int ath11k_wmi_send_peer_flush_tids_cmd(struct ath11k *ar, 1083 u8 peer_addr[ETH_ALEN], 1084 struct peer_flush_params *param) 1085 { 1086 struct ath11k_pdev_wmi *wmi = ar->wmi; 1087 struct wmi_peer_flush_tids_cmd *cmd; 1088 struct sk_buff *skb; 1089 int ret; 1090 1091 skb = ath11k_wmi_alloc_skb(wmi->wmi_ab, sizeof(*cmd)); 1092 if (!skb) 1093 return -ENOMEM; 1094 1095 cmd = (struct wmi_peer_flush_tids_cmd *)skb->data; 1096 cmd->tlv_header = FIELD_PREP(WMI_TLV_TAG, WMI_TAG_PEER_FLUSH_TIDS_CMD) | 1097 FIELD_PREP(WMI_TLV_LEN, sizeof(*cmd) - TLV_HDR_SIZE); 1098 1099 ether_addr_copy(cmd->peer_macaddr.addr, peer_addr); 1100 cmd->peer_tid_bitmap = param->peer_tid_bitmap; 1101 cmd->vdev_id = param->vdev_id; 1102 1103 ret = ath11k_wmi_cmd_send(wmi, skb, WMI_PEER_FLUSH_TIDS_CMDID); 1104 if (ret) { 1105 ath11k_warn(ar->ab, 1106 "failed to send WMI_PEER_FLUSH_TIDS cmd\n"); 1107 dev_kfree_skb(skb); 1108 } 1109 1110 ath11k_dbg(ar->ab, ATH11K_DBG_WMI, 1111 "WMI peer flush vdev_id %d peer_addr %pM tids %08x\n", 1112 param->vdev_id, peer_addr, param->peer_tid_bitmap); 1113 1114 return ret; 1115 } 1116 1117 int ath11k_wmi_peer_rx_reorder_queue_setup(struct ath11k *ar, 1118 int vdev_id, const u8 *addr, 1119 dma_addr_t paddr, u8 tid, 1120 u8 ba_window_size_valid, 1121 u32 ba_window_size) 1122 { 1123 struct wmi_peer_reorder_queue_setup_cmd *cmd; 1124 struct sk_buff *skb; 1125 int ret; 1126 1127 skb = ath11k_wmi_alloc_skb(ar->wmi->wmi_ab, sizeof(*cmd)); 1128 if (!skb) 1129 return -ENOMEM; 1130 1131 cmd = (struct wmi_peer_reorder_queue_setup_cmd *)skb->data; 1132 cmd->tlv_header = FIELD_PREP(WMI_TLV_TAG, 1133 WMI_TAG_REORDER_QUEUE_SETUP_CMD) | 1134 FIELD_PREP(WMI_TLV_LEN, sizeof(*cmd) - TLV_HDR_SIZE); 1135 1136 ether_addr_copy(cmd->peer_macaddr.addr, addr); 1137 cmd->vdev_id = vdev_id; 1138 cmd->tid = tid; 1139 cmd->queue_ptr_lo = lower_32_bits(paddr); 1140 cmd->queue_ptr_hi = upper_32_bits(paddr); 1141 cmd->queue_no = tid; 1142 cmd->ba_window_size_valid = ba_window_size_valid; 1143 cmd->ba_window_size = ba_window_size; 1144 1145 ret = ath11k_wmi_cmd_send(ar->wmi, skb, 1146 WMI_PEER_REORDER_QUEUE_SETUP_CMDID); 1147 if (ret) { 1148 ath11k_warn(ar->ab, 1149 "failed to send WMI_PEER_REORDER_QUEUE_SETUP\n"); 1150 dev_kfree_skb(skb); 1151 } 1152 1153 ath11k_dbg(ar->ab, ATH11K_DBG_WMI, 1154 "wmi rx reorder queue setup addr %pM vdev_id %d tid %d\n", 1155 addr, vdev_id, tid); 1156 1157 return ret; 1158 } 1159 1160 int 1161 ath11k_wmi_rx_reord_queue_remove(struct ath11k *ar, 1162 struct rx_reorder_queue_remove_params *param) 1163 { 1164 struct ath11k_pdev_wmi *wmi = ar->wmi; 1165 struct wmi_peer_reorder_queue_remove_cmd *cmd; 1166 struct sk_buff *skb; 1167 int ret; 1168 1169 skb = ath11k_wmi_alloc_skb(wmi->wmi_ab, sizeof(*cmd)); 1170 if (!skb) 1171 return -ENOMEM; 1172 1173 cmd = (struct wmi_peer_reorder_queue_remove_cmd *)skb->data; 1174 cmd->tlv_header = FIELD_PREP(WMI_TLV_TAG, 1175 WMI_TAG_REORDER_QUEUE_REMOVE_CMD) | 1176 FIELD_PREP(WMI_TLV_LEN, sizeof(*cmd) - TLV_HDR_SIZE); 1177 1178 ether_addr_copy(cmd->peer_macaddr.addr, param->peer_macaddr); 1179 cmd->vdev_id = param->vdev_id; 1180 cmd->tid_mask = param->peer_tid_bitmap; 1181 1182 ath11k_dbg(ar->ab, ATH11K_DBG_WMI, 1183 "%s: peer_macaddr %pM vdev_id %d, tid_map %d", __func__, 1184 param->peer_macaddr, param->vdev_id, param->peer_tid_bitmap); 1185 1186 ret = ath11k_wmi_cmd_send(wmi, skb, 1187 WMI_PEER_REORDER_QUEUE_REMOVE_CMDID); 1188 if (ret) { 1189 ath11k_warn(ar->ab, 1190 "failed to send WMI_PEER_REORDER_QUEUE_REMOVE_CMDID"); 1191 dev_kfree_skb(skb); 1192 } 1193 1194 return ret; 1195 } 1196 1197 int ath11k_wmi_pdev_set_param(struct ath11k *ar, u32 param_id, 1198 u32 param_value, u8 pdev_id) 1199 { 1200 struct ath11k_pdev_wmi *wmi = ar->wmi; 1201 struct wmi_pdev_set_param_cmd *cmd; 1202 struct sk_buff *skb; 1203 int ret; 1204 1205 skb = ath11k_wmi_alloc_skb(wmi->wmi_ab, sizeof(*cmd)); 1206 if (!skb) 1207 return -ENOMEM; 1208 1209 cmd = (struct wmi_pdev_set_param_cmd *)skb->data; 1210 cmd->tlv_header = FIELD_PREP(WMI_TLV_TAG, WMI_TAG_PDEV_SET_PARAM_CMD) | 1211 FIELD_PREP(WMI_TLV_LEN, sizeof(*cmd) - TLV_HDR_SIZE); 1212 cmd->pdev_id = pdev_id; 1213 cmd->param_id = param_id; 1214 cmd->param_value = param_value; 1215 1216 ret = ath11k_wmi_cmd_send(wmi, skb, WMI_PDEV_SET_PARAM_CMDID); 1217 if (ret) { 1218 ath11k_warn(ar->ab, "failed to send WMI_PDEV_SET_PARAM cmd\n"); 1219 dev_kfree_skb(skb); 1220 } 1221 1222 ath11k_dbg(ar->ab, ATH11K_DBG_WMI, 1223 "WMI pdev set param %d pdev id %d value %d\n", 1224 param_id, pdev_id, param_value); 1225 1226 return ret; 1227 } 1228 1229 int ath11k_wmi_pdev_set_ps_mode(struct ath11k *ar, int vdev_id, u32 enable) 1230 { 1231 struct ath11k_pdev_wmi *wmi = ar->wmi; 1232 struct wmi_pdev_set_ps_mode_cmd *cmd; 1233 struct sk_buff *skb; 1234 int ret; 1235 1236 skb = ath11k_wmi_alloc_skb(wmi->wmi_ab, sizeof(*cmd)); 1237 if (!skb) 1238 return -ENOMEM; 1239 1240 cmd = (struct wmi_pdev_set_ps_mode_cmd *)skb->data; 1241 cmd->tlv_header = FIELD_PREP(WMI_TLV_TAG, WMI_TAG_STA_POWERSAVE_MODE_CMD) | 1242 FIELD_PREP(WMI_TLV_LEN, sizeof(*cmd) - TLV_HDR_SIZE); 1243 cmd->vdev_id = vdev_id; 1244 cmd->sta_ps_mode = enable; 1245 1246 ret = ath11k_wmi_cmd_send(wmi, skb, WMI_STA_POWERSAVE_MODE_CMDID); 1247 if (ret) { 1248 ath11k_warn(ar->ab, "failed to send WMI_PDEV_SET_PARAM cmd\n"); 1249 dev_kfree_skb(skb); 1250 } 1251 1252 ath11k_dbg(ar->ab, ATH11K_DBG_WMI, 1253 "WMI vdev set psmode %d vdev id %d\n", 1254 enable, vdev_id); 1255 1256 return ret; 1257 } 1258 1259 int ath11k_wmi_pdev_suspend(struct ath11k *ar, u32 suspend_opt, 1260 u32 pdev_id) 1261 { 1262 struct ath11k_pdev_wmi *wmi = ar->wmi; 1263 struct wmi_pdev_suspend_cmd *cmd; 1264 struct sk_buff *skb; 1265 int ret; 1266 1267 skb = ath11k_wmi_alloc_skb(wmi->wmi_ab, sizeof(*cmd)); 1268 if (!skb) 1269 return -ENOMEM; 1270 1271 cmd = (struct wmi_pdev_suspend_cmd *)skb->data; 1272 1273 cmd->tlv_header = FIELD_PREP(WMI_TLV_TAG, WMI_TAG_PDEV_SUSPEND_CMD) | 1274 FIELD_PREP(WMI_TLV_LEN, sizeof(*cmd) - TLV_HDR_SIZE); 1275 1276 cmd->suspend_opt = suspend_opt; 1277 cmd->pdev_id = pdev_id; 1278 1279 ret = ath11k_wmi_cmd_send(wmi, skb, WMI_PDEV_SUSPEND_CMDID); 1280 if (ret) { 1281 ath11k_warn(ar->ab, "failed to send WMI_PDEV_SUSPEND cmd\n"); 1282 dev_kfree_skb(skb); 1283 } 1284 1285 ath11k_dbg(ar->ab, ATH11K_DBG_WMI, 1286 "WMI pdev suspend pdev_id %d\n", pdev_id); 1287 1288 return ret; 1289 } 1290 1291 int ath11k_wmi_pdev_resume(struct ath11k *ar, u32 pdev_id) 1292 { 1293 struct ath11k_pdev_wmi *wmi = ar->wmi; 1294 struct wmi_pdev_resume_cmd *cmd; 1295 struct sk_buff *skb; 1296 int ret; 1297 1298 skb = ath11k_wmi_alloc_skb(wmi->wmi_ab, sizeof(*cmd)); 1299 if (!skb) 1300 return -ENOMEM; 1301 1302 cmd = (struct wmi_pdev_resume_cmd *)skb->data; 1303 1304 cmd->tlv_header = FIELD_PREP(WMI_TLV_TAG, WMI_TAG_PDEV_RESUME_CMD) | 1305 FIELD_PREP(WMI_TLV_LEN, sizeof(*cmd) - TLV_HDR_SIZE); 1306 cmd->pdev_id = pdev_id; 1307 1308 ath11k_dbg(ar->ab, ATH11K_DBG_WMI, 1309 "WMI pdev resume pdev id %d\n", pdev_id); 1310 1311 ret = ath11k_wmi_cmd_send(wmi, skb, WMI_PDEV_RESUME_CMDID); 1312 if (ret) { 1313 ath11k_warn(ar->ab, "failed to send WMI_PDEV_RESUME cmd\n"); 1314 dev_kfree_skb(skb); 1315 } 1316 1317 return ret; 1318 } 1319 1320 /* TODO FW Support for the cmd is not available yet. 1321 * Can be tested once the command and corresponding 1322 * event is implemented in FW 1323 */ 1324 int ath11k_wmi_pdev_bss_chan_info_request(struct ath11k *ar, 1325 enum wmi_bss_chan_info_req_type type) 1326 { 1327 struct ath11k_pdev_wmi *wmi = ar->wmi; 1328 struct wmi_pdev_bss_chan_info_req_cmd *cmd; 1329 struct sk_buff *skb; 1330 int ret; 1331 1332 skb = ath11k_wmi_alloc_skb(wmi->wmi_ab, sizeof(*cmd)); 1333 if (!skb) 1334 return -ENOMEM; 1335 1336 cmd = (struct wmi_pdev_bss_chan_info_req_cmd *)skb->data; 1337 1338 cmd->tlv_header = FIELD_PREP(WMI_TLV_TAG, 1339 WMI_TAG_PDEV_BSS_CHAN_INFO_REQUEST) | 1340 FIELD_PREP(WMI_TLV_LEN, sizeof(*cmd) - TLV_HDR_SIZE); 1341 cmd->req_type = type; 1342 cmd->pdev_id = ar->pdev->pdev_id; 1343 1344 ath11k_dbg(ar->ab, ATH11K_DBG_WMI, 1345 "WMI bss chan info req type %d\n", type); 1346 1347 ret = ath11k_wmi_cmd_send(wmi, skb, 1348 WMI_PDEV_BSS_CHAN_INFO_REQUEST_CMDID); 1349 if (ret) { 1350 ath11k_warn(ar->ab, 1351 "failed to send WMI_PDEV_BSS_CHAN_INFO_REQUEST cmd\n"); 1352 dev_kfree_skb(skb); 1353 } 1354 1355 return ret; 1356 } 1357 1358 int ath11k_wmi_send_set_ap_ps_param_cmd(struct ath11k *ar, u8 *peer_addr, 1359 struct ap_ps_params *param) 1360 { 1361 struct ath11k_pdev_wmi *wmi = ar->wmi; 1362 struct wmi_ap_ps_peer_cmd *cmd; 1363 struct sk_buff *skb; 1364 int ret; 1365 1366 skb = ath11k_wmi_alloc_skb(wmi->wmi_ab, sizeof(*cmd)); 1367 if (!skb) 1368 return -ENOMEM; 1369 1370 cmd = (struct wmi_ap_ps_peer_cmd *)skb->data; 1371 cmd->tlv_header = FIELD_PREP(WMI_TLV_TAG, WMI_TAG_AP_PS_PEER_CMD) | 1372 FIELD_PREP(WMI_TLV_LEN, sizeof(*cmd) - TLV_HDR_SIZE); 1373 1374 cmd->vdev_id = param->vdev_id; 1375 ether_addr_copy(cmd->peer_macaddr.addr, peer_addr); 1376 cmd->param = param->param; 1377 cmd->value = param->value; 1378 1379 ret = ath11k_wmi_cmd_send(wmi, skb, WMI_AP_PS_PEER_PARAM_CMDID); 1380 if (ret) { 1381 ath11k_warn(ar->ab, 1382 "failed to send WMI_AP_PS_PEER_PARAM_CMDID\n"); 1383 dev_kfree_skb(skb); 1384 } 1385 1386 ath11k_dbg(ar->ab, ATH11K_DBG_WMI, 1387 "WMI set ap ps vdev id %d peer %pM param %d value %d\n", 1388 param->vdev_id, peer_addr, param->param, param->value); 1389 1390 return ret; 1391 } 1392 1393 int ath11k_wmi_set_sta_ps_param(struct ath11k *ar, u32 vdev_id, 1394 u32 param, u32 param_value) 1395 { 1396 struct ath11k_pdev_wmi *wmi = ar->wmi; 1397 struct wmi_sta_powersave_param_cmd *cmd; 1398 struct sk_buff *skb; 1399 int ret; 1400 1401 skb = ath11k_wmi_alloc_skb(wmi->wmi_ab, sizeof(*cmd)); 1402 if (!skb) 1403 return -ENOMEM; 1404 1405 cmd = (struct wmi_sta_powersave_param_cmd *)skb->data; 1406 cmd->tlv_header = FIELD_PREP(WMI_TLV_TAG, 1407 WMI_TAG_STA_POWERSAVE_PARAM_CMD) | 1408 FIELD_PREP(WMI_TLV_LEN, sizeof(*cmd) - TLV_HDR_SIZE); 1409 1410 cmd->vdev_id = vdev_id; 1411 cmd->param = param; 1412 cmd->value = param_value; 1413 1414 ath11k_dbg(ar->ab, ATH11K_DBG_WMI, 1415 "WMI set sta ps vdev_id %d param %d value %d\n", 1416 vdev_id, param, param_value); 1417 1418 ret = ath11k_wmi_cmd_send(wmi, skb, WMI_STA_POWERSAVE_PARAM_CMDID); 1419 if (ret) { 1420 ath11k_warn(ar->ab, "failed to send WMI_STA_POWERSAVE_PARAM_CMDID"); 1421 dev_kfree_skb(skb); 1422 } 1423 1424 return ret; 1425 } 1426 1427 int ath11k_wmi_force_fw_hang_cmd(struct ath11k *ar, u32 type, u32 delay_time_ms) 1428 { 1429 struct ath11k_pdev_wmi *wmi = ar->wmi; 1430 struct wmi_force_fw_hang_cmd *cmd; 1431 struct sk_buff *skb; 1432 int ret, len; 1433 1434 len = sizeof(*cmd); 1435 1436 skb = ath11k_wmi_alloc_skb(wmi->wmi_ab, len); 1437 if (!skb) 1438 return -ENOMEM; 1439 1440 cmd = (struct wmi_force_fw_hang_cmd *)skb->data; 1441 cmd->tlv_header = FIELD_PREP(WMI_TLV_TAG, WMI_TAG_FORCE_FW_HANG_CMD) | 1442 FIELD_PREP(WMI_TLV_LEN, len - TLV_HDR_SIZE); 1443 1444 cmd->type = type; 1445 cmd->delay_time_ms = delay_time_ms; 1446 1447 ret = ath11k_wmi_cmd_send(wmi, skb, WMI_FORCE_FW_HANG_CMDID); 1448 1449 if (ret) { 1450 ath11k_warn(ar->ab, "Failed to send WMI_FORCE_FW_HANG_CMDID"); 1451 dev_kfree_skb(skb); 1452 } 1453 return ret; 1454 } 1455 1456 int ath11k_wmi_vdev_set_param_cmd(struct ath11k *ar, u32 vdev_id, 1457 u32 param_id, u32 param_value) 1458 { 1459 struct ath11k_pdev_wmi *wmi = ar->wmi; 1460 struct wmi_vdev_set_param_cmd *cmd; 1461 struct sk_buff *skb; 1462 int ret; 1463 1464 skb = ath11k_wmi_alloc_skb(wmi->wmi_ab, sizeof(*cmd)); 1465 if (!skb) 1466 return -ENOMEM; 1467 1468 cmd = (struct wmi_vdev_set_param_cmd *)skb->data; 1469 cmd->tlv_header = FIELD_PREP(WMI_TLV_TAG, WMI_TAG_VDEV_SET_PARAM_CMD) | 1470 FIELD_PREP(WMI_TLV_LEN, sizeof(*cmd) - TLV_HDR_SIZE); 1471 1472 cmd->vdev_id = vdev_id; 1473 cmd->param_id = param_id; 1474 cmd->param_value = param_value; 1475 1476 ret = ath11k_wmi_cmd_send(wmi, skb, WMI_VDEV_SET_PARAM_CMDID); 1477 if (ret) { 1478 ath11k_warn(ar->ab, 1479 "failed to send WMI_VDEV_SET_PARAM_CMDID\n"); 1480 dev_kfree_skb(skb); 1481 } 1482 1483 ath11k_dbg(ar->ab, ATH11K_DBG_WMI, 1484 "WMI vdev id 0x%x set param %d value %d\n", 1485 vdev_id, param_id, param_value); 1486 1487 return ret; 1488 } 1489 1490 int ath11k_wmi_send_stats_request_cmd(struct ath11k *ar, 1491 struct stats_request_params *param) 1492 { 1493 struct ath11k_pdev_wmi *wmi = ar->wmi; 1494 struct wmi_request_stats_cmd *cmd; 1495 struct sk_buff *skb; 1496 int ret; 1497 1498 skb = ath11k_wmi_alloc_skb(wmi->wmi_ab, sizeof(*cmd)); 1499 if (!skb) 1500 return -ENOMEM; 1501 1502 cmd = (struct wmi_request_stats_cmd *)skb->data; 1503 cmd->tlv_header = FIELD_PREP(WMI_TLV_TAG, WMI_TAG_REQUEST_STATS_CMD) | 1504 FIELD_PREP(WMI_TLV_LEN, sizeof(*cmd) - TLV_HDR_SIZE); 1505 1506 cmd->stats_id = param->stats_id; 1507 cmd->vdev_id = param->vdev_id; 1508 cmd->pdev_id = param->pdev_id; 1509 1510 ret = ath11k_wmi_cmd_send(wmi, skb, WMI_REQUEST_STATS_CMDID); 1511 if (ret) { 1512 ath11k_warn(ar->ab, "failed to send WMI_REQUEST_STATS cmd\n"); 1513 dev_kfree_skb(skb); 1514 } 1515 1516 ath11k_dbg(ar->ab, ATH11K_DBG_WMI, 1517 "WMI request stats 0x%x vdev id %d pdev id %d\n", 1518 param->stats_id, param->vdev_id, param->pdev_id); 1519 1520 return ret; 1521 } 1522 1523 int ath11k_wmi_send_pdev_temperature_cmd(struct ath11k *ar) 1524 { 1525 struct ath11k_pdev_wmi *wmi = ar->wmi; 1526 struct wmi_get_pdev_temperature_cmd *cmd; 1527 struct sk_buff *skb; 1528 int ret; 1529 1530 skb = ath11k_wmi_alloc_skb(wmi->wmi_ab, sizeof(*cmd)); 1531 if (!skb) 1532 return -ENOMEM; 1533 1534 cmd = (struct wmi_get_pdev_temperature_cmd *)skb->data; 1535 cmd->tlv_header = FIELD_PREP(WMI_TLV_TAG, WMI_TAG_PDEV_GET_TEMPERATURE_CMD) | 1536 FIELD_PREP(WMI_TLV_LEN, sizeof(*cmd) - TLV_HDR_SIZE); 1537 cmd->pdev_id = ar->pdev->pdev_id; 1538 1539 ret = ath11k_wmi_cmd_send(wmi, skb, WMI_PDEV_GET_TEMPERATURE_CMDID); 1540 if (ret) { 1541 ath11k_warn(ar->ab, "failed to send WMI_PDEV_GET_TEMPERATURE cmd\n"); 1542 dev_kfree_skb(skb); 1543 } 1544 1545 ath11k_dbg(ar->ab, ATH11K_DBG_WMI, 1546 "WMI pdev get temperature for pdev_id %d\n", ar->pdev->pdev_id); 1547 1548 return ret; 1549 } 1550 1551 int ath11k_wmi_send_bcn_offload_control_cmd(struct ath11k *ar, 1552 u32 vdev_id, u32 bcn_ctrl_op) 1553 { 1554 struct ath11k_pdev_wmi *wmi = ar->wmi; 1555 struct wmi_bcn_offload_ctrl_cmd *cmd; 1556 struct sk_buff *skb; 1557 int ret; 1558 1559 skb = ath11k_wmi_alloc_skb(wmi->wmi_ab, sizeof(*cmd)); 1560 if (!skb) 1561 return -ENOMEM; 1562 1563 cmd = (struct wmi_bcn_offload_ctrl_cmd *)skb->data; 1564 cmd->tlv_header = FIELD_PREP(WMI_TLV_TAG, 1565 WMI_TAG_BCN_OFFLOAD_CTRL_CMD) | 1566 FIELD_PREP(WMI_TLV_LEN, sizeof(*cmd) - TLV_HDR_SIZE); 1567 1568 cmd->vdev_id = vdev_id; 1569 cmd->bcn_ctrl_op = bcn_ctrl_op; 1570 1571 ath11k_dbg(ar->ab, ATH11K_DBG_WMI, 1572 "WMI bcn ctrl offload vdev id %d ctrl_op %d\n", 1573 vdev_id, bcn_ctrl_op); 1574 1575 ret = ath11k_wmi_cmd_send(wmi, skb, WMI_BCN_OFFLOAD_CTRL_CMDID); 1576 if (ret) { 1577 ath11k_warn(ar->ab, 1578 "failed to send WMI_BCN_OFFLOAD_CTRL_CMDID\n"); 1579 dev_kfree_skb(skb); 1580 } 1581 1582 return ret; 1583 } 1584 1585 int ath11k_wmi_bcn_tmpl(struct ath11k *ar, u32 vdev_id, 1586 struct ieee80211_mutable_offsets *offs, 1587 struct sk_buff *bcn) 1588 { 1589 struct ath11k_pdev_wmi *wmi = ar->wmi; 1590 struct wmi_bcn_tmpl_cmd *cmd; 1591 struct wmi_bcn_prb_info *bcn_prb_info; 1592 struct wmi_tlv *tlv; 1593 struct sk_buff *skb; 1594 void *ptr; 1595 int ret, len; 1596 size_t aligned_len = roundup(bcn->len, 4); 1597 1598 len = sizeof(*cmd) + sizeof(*bcn_prb_info) + TLV_HDR_SIZE + aligned_len; 1599 1600 skb = ath11k_wmi_alloc_skb(wmi->wmi_ab, len); 1601 if (!skb) 1602 return -ENOMEM; 1603 1604 cmd = (struct wmi_bcn_tmpl_cmd *)skb->data; 1605 cmd->tlv_header = FIELD_PREP(WMI_TLV_TAG, WMI_TAG_BCN_TMPL_CMD) | 1606 FIELD_PREP(WMI_TLV_LEN, sizeof(*cmd) - TLV_HDR_SIZE); 1607 cmd->vdev_id = vdev_id; 1608 cmd->tim_ie_offset = offs->tim_offset; 1609 cmd->csa_switch_count_offset = offs->cntdwn_counter_offs[0]; 1610 cmd->ext_csa_switch_count_offset = offs->cntdwn_counter_offs[1]; 1611 cmd->buf_len = bcn->len; 1612 1613 ptr = skb->data + sizeof(*cmd); 1614 1615 bcn_prb_info = ptr; 1616 len = sizeof(*bcn_prb_info); 1617 bcn_prb_info->tlv_header = FIELD_PREP(WMI_TLV_TAG, 1618 WMI_TAG_BCN_PRB_INFO) | 1619 FIELD_PREP(WMI_TLV_LEN, len - TLV_HDR_SIZE); 1620 bcn_prb_info->caps = 0; 1621 bcn_prb_info->erp = 0; 1622 1623 ptr += sizeof(*bcn_prb_info); 1624 1625 tlv = ptr; 1626 tlv->header = FIELD_PREP(WMI_TLV_TAG, WMI_TAG_ARRAY_BYTE) | 1627 FIELD_PREP(WMI_TLV_LEN, aligned_len); 1628 memcpy(tlv->value, bcn->data, bcn->len); 1629 1630 ret = ath11k_wmi_cmd_send(wmi, skb, WMI_BCN_TMPL_CMDID); 1631 if (ret) { 1632 ath11k_warn(ar->ab, "failed to send WMI_BCN_TMPL_CMDID\n"); 1633 dev_kfree_skb(skb); 1634 } 1635 1636 return ret; 1637 } 1638 1639 int ath11k_wmi_vdev_install_key(struct ath11k *ar, 1640 struct wmi_vdev_install_key_arg *arg) 1641 { 1642 struct ath11k_pdev_wmi *wmi = ar->wmi; 1643 struct wmi_vdev_install_key_cmd *cmd; 1644 struct wmi_tlv *tlv; 1645 struct sk_buff *skb; 1646 int ret, len; 1647 int key_len_aligned = roundup(arg->key_len, sizeof(uint32_t)); 1648 1649 len = sizeof(*cmd) + TLV_HDR_SIZE + key_len_aligned; 1650 1651 skb = ath11k_wmi_alloc_skb(wmi->wmi_ab, len); 1652 if (!skb) 1653 return -ENOMEM; 1654 1655 cmd = (struct wmi_vdev_install_key_cmd *)skb->data; 1656 cmd->tlv_header = FIELD_PREP(WMI_TLV_TAG, WMI_TAG_VDEV_INSTALL_KEY_CMD) | 1657 FIELD_PREP(WMI_TLV_LEN, sizeof(*cmd) - TLV_HDR_SIZE); 1658 cmd->vdev_id = arg->vdev_id; 1659 ether_addr_copy(cmd->peer_macaddr.addr, arg->macaddr); 1660 cmd->key_idx = arg->key_idx; 1661 cmd->key_flags = arg->key_flags; 1662 cmd->key_cipher = arg->key_cipher; 1663 cmd->key_len = arg->key_len; 1664 cmd->key_txmic_len = arg->key_txmic_len; 1665 cmd->key_rxmic_len = arg->key_rxmic_len; 1666 1667 if (arg->key_rsc_counter) 1668 memcpy(&cmd->key_rsc_counter, &arg->key_rsc_counter, 1669 sizeof(struct wmi_key_seq_counter)); 1670 1671 tlv = (struct wmi_tlv *)(skb->data + sizeof(*cmd)); 1672 tlv->header = FIELD_PREP(WMI_TLV_TAG, WMI_TAG_ARRAY_BYTE) | 1673 FIELD_PREP(WMI_TLV_LEN, key_len_aligned); 1674 memcpy(tlv->value, (u8 *)arg->key_data, key_len_aligned); 1675 1676 ret = ath11k_wmi_cmd_send(wmi, skb, WMI_VDEV_INSTALL_KEY_CMDID); 1677 if (ret) { 1678 ath11k_warn(ar->ab, 1679 "failed to send WMI_VDEV_INSTALL_KEY cmd\n"); 1680 dev_kfree_skb(skb); 1681 } 1682 1683 ath11k_dbg(ar->ab, ATH11K_DBG_WMI, 1684 "WMI vdev install key idx %d cipher %d len %d\n", 1685 arg->key_idx, arg->key_cipher, arg->key_len); 1686 1687 return ret; 1688 } 1689 1690 static inline void 1691 ath11k_wmi_copy_peer_flags(struct wmi_peer_assoc_complete_cmd *cmd, 1692 struct peer_assoc_params *param, 1693 bool hw_crypto_disabled) 1694 { 1695 cmd->peer_flags = 0; 1696 1697 if (param->is_wme_set) { 1698 if (param->qos_flag) 1699 cmd->peer_flags |= WMI_PEER_QOS; 1700 if (param->apsd_flag) 1701 cmd->peer_flags |= WMI_PEER_APSD; 1702 if (param->ht_flag) 1703 cmd->peer_flags |= WMI_PEER_HT; 1704 if (param->bw_40) 1705 cmd->peer_flags |= WMI_PEER_40MHZ; 1706 if (param->bw_80) 1707 cmd->peer_flags |= WMI_PEER_80MHZ; 1708 if (param->bw_160) 1709 cmd->peer_flags |= WMI_PEER_160MHZ; 1710 1711 /* Typically if STBC is enabled for VHT it should be enabled 1712 * for HT as well 1713 **/ 1714 if (param->stbc_flag) 1715 cmd->peer_flags |= WMI_PEER_STBC; 1716 1717 /* Typically if LDPC is enabled for VHT it should be enabled 1718 * for HT as well 1719 **/ 1720 if (param->ldpc_flag) 1721 cmd->peer_flags |= WMI_PEER_LDPC; 1722 1723 if (param->static_mimops_flag) 1724 cmd->peer_flags |= WMI_PEER_STATIC_MIMOPS; 1725 if (param->dynamic_mimops_flag) 1726 cmd->peer_flags |= WMI_PEER_DYN_MIMOPS; 1727 if (param->spatial_mux_flag) 1728 cmd->peer_flags |= WMI_PEER_SPATIAL_MUX; 1729 if (param->vht_flag) 1730 cmd->peer_flags |= WMI_PEER_VHT; 1731 if (param->he_flag) 1732 cmd->peer_flags |= WMI_PEER_HE; 1733 if (param->twt_requester) 1734 cmd->peer_flags |= WMI_PEER_TWT_REQ; 1735 if (param->twt_responder) 1736 cmd->peer_flags |= WMI_PEER_TWT_RESP; 1737 } 1738 1739 /* Suppress authorization for all AUTH modes that need 4-way handshake 1740 * (during re-association). 1741 * Authorization will be done for these modes on key installation. 1742 */ 1743 if (param->auth_flag) 1744 cmd->peer_flags |= WMI_PEER_AUTH; 1745 if (param->need_ptk_4_way) { 1746 cmd->peer_flags |= WMI_PEER_NEED_PTK_4_WAY; 1747 if (!hw_crypto_disabled) 1748 cmd->peer_flags &= ~WMI_PEER_AUTH; 1749 } 1750 if (param->need_gtk_2_way) 1751 cmd->peer_flags |= WMI_PEER_NEED_GTK_2_WAY; 1752 /* safe mode bypass the 4-way handshake */ 1753 if (param->safe_mode_enabled) 1754 cmd->peer_flags &= ~(WMI_PEER_NEED_PTK_4_WAY | 1755 WMI_PEER_NEED_GTK_2_WAY); 1756 1757 if (param->is_pmf_enabled) 1758 cmd->peer_flags |= WMI_PEER_PMF; 1759 1760 /* Disable AMSDU for station transmit, if user configures it */ 1761 /* Disable AMSDU for AP transmit to 11n Stations, if user configures 1762 * it 1763 * if (param->amsdu_disable) Add after FW support 1764 **/ 1765 1766 /* Target asserts if node is marked HT and all MCS is set to 0. 1767 * Mark the node as non-HT if all the mcs rates are disabled through 1768 * iwpriv 1769 **/ 1770 if (param->peer_ht_rates.num_rates == 0) 1771 cmd->peer_flags &= ~WMI_PEER_HT; 1772 } 1773 1774 int ath11k_wmi_send_peer_assoc_cmd(struct ath11k *ar, 1775 struct peer_assoc_params *param) 1776 { 1777 struct ath11k_pdev_wmi *wmi = ar->wmi; 1778 struct wmi_peer_assoc_complete_cmd *cmd; 1779 struct wmi_vht_rate_set *mcs; 1780 struct wmi_he_rate_set *he_mcs; 1781 struct sk_buff *skb; 1782 struct wmi_tlv *tlv; 1783 void *ptr; 1784 u32 peer_legacy_rates_align; 1785 u32 peer_ht_rates_align; 1786 int i, ret, len; 1787 1788 peer_legacy_rates_align = roundup(param->peer_legacy_rates.num_rates, 1789 sizeof(u32)); 1790 peer_ht_rates_align = roundup(param->peer_ht_rates.num_rates, 1791 sizeof(u32)); 1792 1793 len = sizeof(*cmd) + 1794 TLV_HDR_SIZE + (peer_legacy_rates_align * sizeof(u8)) + 1795 TLV_HDR_SIZE + (peer_ht_rates_align * sizeof(u8)) + 1796 sizeof(*mcs) + TLV_HDR_SIZE + 1797 (sizeof(*he_mcs) * param->peer_he_mcs_count); 1798 1799 skb = ath11k_wmi_alloc_skb(wmi->wmi_ab, len); 1800 if (!skb) 1801 return -ENOMEM; 1802 1803 ptr = skb->data; 1804 1805 cmd = ptr; 1806 cmd->tlv_header = FIELD_PREP(WMI_TLV_TAG, 1807 WMI_TAG_PEER_ASSOC_COMPLETE_CMD) | 1808 FIELD_PREP(WMI_TLV_LEN, sizeof(*cmd) - TLV_HDR_SIZE); 1809 1810 cmd->vdev_id = param->vdev_id; 1811 1812 cmd->peer_new_assoc = param->peer_new_assoc; 1813 cmd->peer_associd = param->peer_associd; 1814 1815 ath11k_wmi_copy_peer_flags(cmd, param, 1816 test_bit(ATH11K_FLAG_HW_CRYPTO_DISABLED, 1817 &ar->ab->dev_flags)); 1818 1819 ether_addr_copy(cmd->peer_macaddr.addr, param->peer_mac); 1820 1821 cmd->peer_rate_caps = param->peer_rate_caps; 1822 cmd->peer_caps = param->peer_caps; 1823 cmd->peer_listen_intval = param->peer_listen_intval; 1824 cmd->peer_ht_caps = param->peer_ht_caps; 1825 cmd->peer_max_mpdu = param->peer_max_mpdu; 1826 cmd->peer_mpdu_density = param->peer_mpdu_density; 1827 cmd->peer_vht_caps = param->peer_vht_caps; 1828 cmd->peer_phymode = param->peer_phymode; 1829 1830 /* Update 11ax capabilities */ 1831 cmd->peer_he_cap_info = param->peer_he_cap_macinfo[0]; 1832 cmd->peer_he_cap_info_ext = param->peer_he_cap_macinfo[1]; 1833 cmd->peer_he_cap_info_internal = param->peer_he_cap_macinfo_internal; 1834 cmd->peer_he_caps_6ghz = param->peer_he_caps_6ghz; 1835 cmd->peer_he_ops = param->peer_he_ops; 1836 memcpy(&cmd->peer_he_cap_phy, ¶m->peer_he_cap_phyinfo, 1837 sizeof(param->peer_he_cap_phyinfo)); 1838 memcpy(&cmd->peer_ppet, ¶m->peer_ppet, 1839 sizeof(param->peer_ppet)); 1840 1841 /* Update peer legacy rate information */ 1842 ptr += sizeof(*cmd); 1843 1844 tlv = ptr; 1845 tlv->header = FIELD_PREP(WMI_TLV_TAG, WMI_TAG_ARRAY_BYTE) | 1846 FIELD_PREP(WMI_TLV_LEN, peer_legacy_rates_align); 1847 1848 ptr += TLV_HDR_SIZE; 1849 1850 cmd->num_peer_legacy_rates = param->peer_legacy_rates.num_rates; 1851 memcpy(ptr, param->peer_legacy_rates.rates, 1852 param->peer_legacy_rates.num_rates); 1853 1854 /* Update peer HT rate information */ 1855 ptr += peer_legacy_rates_align; 1856 1857 tlv = ptr; 1858 tlv->header = FIELD_PREP(WMI_TLV_TAG, WMI_TAG_ARRAY_BYTE) | 1859 FIELD_PREP(WMI_TLV_LEN, peer_ht_rates_align); 1860 ptr += TLV_HDR_SIZE; 1861 cmd->num_peer_ht_rates = param->peer_ht_rates.num_rates; 1862 memcpy(ptr, param->peer_ht_rates.rates, 1863 param->peer_ht_rates.num_rates); 1864 1865 /* VHT Rates */ 1866 ptr += peer_ht_rates_align; 1867 1868 mcs = ptr; 1869 1870 mcs->tlv_header = FIELD_PREP(WMI_TLV_TAG, WMI_TAG_VHT_RATE_SET) | 1871 FIELD_PREP(WMI_TLV_LEN, sizeof(*mcs) - TLV_HDR_SIZE); 1872 1873 cmd->peer_nss = param->peer_nss; 1874 1875 /* Update bandwidth-NSS mapping */ 1876 cmd->peer_bw_rxnss_override = 0; 1877 cmd->peer_bw_rxnss_override |= param->peer_bw_rxnss_override; 1878 1879 if (param->vht_capable) { 1880 mcs->rx_max_rate = param->rx_max_rate; 1881 mcs->rx_mcs_set = param->rx_mcs_set; 1882 mcs->tx_max_rate = param->tx_max_rate; 1883 mcs->tx_mcs_set = param->tx_mcs_set; 1884 } 1885 1886 /* HE Rates */ 1887 cmd->peer_he_mcs = param->peer_he_mcs_count; 1888 cmd->min_data_rate = param->min_data_rate; 1889 1890 ptr += sizeof(*mcs); 1891 1892 len = param->peer_he_mcs_count * sizeof(*he_mcs); 1893 1894 tlv = ptr; 1895 tlv->header = FIELD_PREP(WMI_TLV_TAG, WMI_TAG_ARRAY_STRUCT) | 1896 FIELD_PREP(WMI_TLV_LEN, len); 1897 ptr += TLV_HDR_SIZE; 1898 1899 /* Loop through the HE rate set */ 1900 for (i = 0; i < param->peer_he_mcs_count; i++) { 1901 he_mcs = ptr; 1902 he_mcs->tlv_header = FIELD_PREP(WMI_TLV_TAG, 1903 WMI_TAG_HE_RATE_SET) | 1904 FIELD_PREP(WMI_TLV_LEN, 1905 sizeof(*he_mcs) - TLV_HDR_SIZE); 1906 1907 he_mcs->rx_mcs_set = param->peer_he_tx_mcs_set[i]; 1908 he_mcs->tx_mcs_set = param->peer_he_rx_mcs_set[i]; 1909 ptr += sizeof(*he_mcs); 1910 } 1911 1912 ret = ath11k_wmi_cmd_send(wmi, skb, WMI_PEER_ASSOC_CMDID); 1913 if (ret) { 1914 ath11k_warn(ar->ab, 1915 "failed to send WMI_PEER_ASSOC_CMDID\n"); 1916 dev_kfree_skb(skb); 1917 } 1918 1919 ath11k_dbg(ar->ab, ATH11K_DBG_WMI, 1920 "wmi 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", 1921 cmd->vdev_id, cmd->peer_associd, param->peer_mac, 1922 cmd->peer_flags, cmd->peer_rate_caps, cmd->peer_caps, 1923 cmd->peer_listen_intval, cmd->peer_ht_caps, 1924 cmd->peer_max_mpdu, cmd->peer_nss, cmd->peer_phymode, 1925 cmd->peer_mpdu_density, 1926 cmd->peer_vht_caps, cmd->peer_he_cap_info, 1927 cmd->peer_he_ops, cmd->peer_he_cap_info_ext, 1928 cmd->peer_he_cap_phy[0], cmd->peer_he_cap_phy[1], 1929 cmd->peer_he_cap_phy[2], 1930 cmd->peer_bw_rxnss_override); 1931 1932 return ret; 1933 } 1934 1935 void ath11k_wmi_start_scan_init(struct ath11k *ar, 1936 struct scan_req_params *arg) 1937 { 1938 /* setup commonly used values */ 1939 arg->scan_req_id = 1; 1940 arg->scan_priority = WMI_SCAN_PRIORITY_LOW; 1941 arg->dwell_time_active = 50; 1942 arg->dwell_time_active_2g = 0; 1943 arg->dwell_time_passive = 150; 1944 arg->dwell_time_active_6g = 40; 1945 arg->dwell_time_passive_6g = 30; 1946 arg->min_rest_time = 50; 1947 arg->max_rest_time = 500; 1948 arg->repeat_probe_time = 0; 1949 arg->probe_spacing_time = 0; 1950 arg->idle_time = 0; 1951 arg->max_scan_time = 20000; 1952 arg->probe_delay = 5; 1953 arg->notify_scan_events = WMI_SCAN_EVENT_STARTED | 1954 WMI_SCAN_EVENT_COMPLETED | 1955 WMI_SCAN_EVENT_BSS_CHANNEL | 1956 WMI_SCAN_EVENT_FOREIGN_CHAN | 1957 WMI_SCAN_EVENT_DEQUEUED; 1958 arg->scan_flags |= WMI_SCAN_CHAN_STAT_EVENT; 1959 arg->num_bssid = 1; 1960 1961 /* fill bssid_list[0] with 0xff, otherwise bssid and RA will be 1962 * ZEROs in probe request 1963 */ 1964 eth_broadcast_addr(arg->bssid_list[0].addr); 1965 } 1966 1967 static inline void 1968 ath11k_wmi_copy_scan_event_cntrl_flags(struct wmi_start_scan_cmd *cmd, 1969 struct scan_req_params *param) 1970 { 1971 /* Scan events subscription */ 1972 if (param->scan_ev_started) 1973 cmd->notify_scan_events |= WMI_SCAN_EVENT_STARTED; 1974 if (param->scan_ev_completed) 1975 cmd->notify_scan_events |= WMI_SCAN_EVENT_COMPLETED; 1976 if (param->scan_ev_bss_chan) 1977 cmd->notify_scan_events |= WMI_SCAN_EVENT_BSS_CHANNEL; 1978 if (param->scan_ev_foreign_chan) 1979 cmd->notify_scan_events |= WMI_SCAN_EVENT_FOREIGN_CHAN; 1980 if (param->scan_ev_dequeued) 1981 cmd->notify_scan_events |= WMI_SCAN_EVENT_DEQUEUED; 1982 if (param->scan_ev_preempted) 1983 cmd->notify_scan_events |= WMI_SCAN_EVENT_PREEMPTED; 1984 if (param->scan_ev_start_failed) 1985 cmd->notify_scan_events |= WMI_SCAN_EVENT_START_FAILED; 1986 if (param->scan_ev_restarted) 1987 cmd->notify_scan_events |= WMI_SCAN_EVENT_RESTARTED; 1988 if (param->scan_ev_foreign_chn_exit) 1989 cmd->notify_scan_events |= WMI_SCAN_EVENT_FOREIGN_CHAN_EXIT; 1990 if (param->scan_ev_suspended) 1991 cmd->notify_scan_events |= WMI_SCAN_EVENT_SUSPENDED; 1992 if (param->scan_ev_resumed) 1993 cmd->notify_scan_events |= WMI_SCAN_EVENT_RESUMED; 1994 1995 /** Set scan control flags */ 1996 cmd->scan_ctrl_flags = 0; 1997 if (param->scan_f_passive) 1998 cmd->scan_ctrl_flags |= WMI_SCAN_FLAG_PASSIVE; 1999 if (param->scan_f_strict_passive_pch) 2000 cmd->scan_ctrl_flags |= WMI_SCAN_FLAG_STRICT_PASSIVE_ON_PCHN; 2001 if (param->scan_f_promisc_mode) 2002 cmd->scan_ctrl_flags |= WMI_SCAN_FILTER_PROMISCUOS; 2003 if (param->scan_f_capture_phy_err) 2004 cmd->scan_ctrl_flags |= WMI_SCAN_CAPTURE_PHY_ERROR; 2005 if (param->scan_f_half_rate) 2006 cmd->scan_ctrl_flags |= WMI_SCAN_FLAG_HALF_RATE_SUPPORT; 2007 if (param->scan_f_quarter_rate) 2008 cmd->scan_ctrl_flags |= WMI_SCAN_FLAG_QUARTER_RATE_SUPPORT; 2009 if (param->scan_f_cck_rates) 2010 cmd->scan_ctrl_flags |= WMI_SCAN_ADD_CCK_RATES; 2011 if (param->scan_f_ofdm_rates) 2012 cmd->scan_ctrl_flags |= WMI_SCAN_ADD_OFDM_RATES; 2013 if (param->scan_f_chan_stat_evnt) 2014 cmd->scan_ctrl_flags |= WMI_SCAN_CHAN_STAT_EVENT; 2015 if (param->scan_f_filter_prb_req) 2016 cmd->scan_ctrl_flags |= WMI_SCAN_FILTER_PROBE_REQ; 2017 if (param->scan_f_bcast_probe) 2018 cmd->scan_ctrl_flags |= WMI_SCAN_ADD_BCAST_PROBE_REQ; 2019 if (param->scan_f_offchan_mgmt_tx) 2020 cmd->scan_ctrl_flags |= WMI_SCAN_OFFCHAN_MGMT_TX; 2021 if (param->scan_f_offchan_data_tx) 2022 cmd->scan_ctrl_flags |= WMI_SCAN_OFFCHAN_DATA_TX; 2023 if (param->scan_f_force_active_dfs_chn) 2024 cmd->scan_ctrl_flags |= WMI_SCAN_FLAG_FORCE_ACTIVE_ON_DFS; 2025 if (param->scan_f_add_tpc_ie_in_probe) 2026 cmd->scan_ctrl_flags |= WMI_SCAN_ADD_TPC_IE_IN_PROBE_REQ; 2027 if (param->scan_f_add_ds_ie_in_probe) 2028 cmd->scan_ctrl_flags |= WMI_SCAN_ADD_DS_IE_IN_PROBE_REQ; 2029 if (param->scan_f_add_spoofed_mac_in_probe) 2030 cmd->scan_ctrl_flags |= WMI_SCAN_ADD_SPOOF_MAC_IN_PROBE_REQ; 2031 if (param->scan_f_add_rand_seq_in_probe) 2032 cmd->scan_ctrl_flags |= WMI_SCAN_RANDOM_SEQ_NO_IN_PROBE_REQ; 2033 if (param->scan_f_en_ie_whitelist_in_probe) 2034 cmd->scan_ctrl_flags |= 2035 WMI_SCAN_ENABLE_IE_WHTELIST_IN_PROBE_REQ; 2036 2037 /* for adaptive scan mode using 3 bits (21 - 23 bits) */ 2038 WMI_SCAN_SET_DWELL_MODE(cmd->scan_ctrl_flags, 2039 param->adaptive_dwell_time_mode); 2040 } 2041 2042 int ath11k_wmi_send_scan_start_cmd(struct ath11k *ar, 2043 struct scan_req_params *params) 2044 { 2045 struct ath11k_pdev_wmi *wmi = ar->wmi; 2046 struct wmi_start_scan_cmd *cmd; 2047 struct wmi_ssid *ssid = NULL; 2048 struct wmi_mac_addr *bssid; 2049 struct sk_buff *skb; 2050 struct wmi_tlv *tlv; 2051 void *ptr; 2052 int i, ret, len; 2053 u32 *tmp_ptr; 2054 u8 extraie_len_with_pad = 0; 2055 struct hint_short_ssid *s_ssid = NULL; 2056 struct hint_bssid *hint_bssid = NULL; 2057 2058 len = sizeof(*cmd); 2059 2060 len += TLV_HDR_SIZE; 2061 if (params->num_chan) 2062 len += params->num_chan * sizeof(u32); 2063 2064 len += TLV_HDR_SIZE; 2065 if (params->num_ssids) 2066 len += params->num_ssids * sizeof(*ssid); 2067 2068 len += TLV_HDR_SIZE; 2069 if (params->num_bssid) 2070 len += sizeof(*bssid) * params->num_bssid; 2071 2072 len += TLV_HDR_SIZE; 2073 if (params->extraie.len) 2074 extraie_len_with_pad = 2075 roundup(params->extraie.len, sizeof(u32)); 2076 len += extraie_len_with_pad; 2077 2078 if (params->num_hint_bssid) 2079 len += TLV_HDR_SIZE + 2080 params->num_hint_bssid * sizeof(struct hint_bssid); 2081 2082 if (params->num_hint_s_ssid) 2083 len += TLV_HDR_SIZE + 2084 params->num_hint_s_ssid * sizeof(struct hint_short_ssid); 2085 2086 skb = ath11k_wmi_alloc_skb(wmi->wmi_ab, len); 2087 if (!skb) 2088 return -ENOMEM; 2089 2090 ptr = skb->data; 2091 2092 cmd = ptr; 2093 cmd->tlv_header = FIELD_PREP(WMI_TLV_TAG, WMI_TAG_START_SCAN_CMD) | 2094 FIELD_PREP(WMI_TLV_LEN, sizeof(*cmd) - TLV_HDR_SIZE); 2095 2096 cmd->scan_id = params->scan_id; 2097 cmd->scan_req_id = params->scan_req_id; 2098 cmd->vdev_id = params->vdev_id; 2099 cmd->scan_priority = params->scan_priority; 2100 cmd->notify_scan_events = params->notify_scan_events; 2101 2102 ath11k_wmi_copy_scan_event_cntrl_flags(cmd, params); 2103 2104 cmd->dwell_time_active = params->dwell_time_active; 2105 cmd->dwell_time_active_2g = params->dwell_time_active_2g; 2106 cmd->dwell_time_passive = params->dwell_time_passive; 2107 cmd->dwell_time_active_6g = params->dwell_time_active_6g; 2108 cmd->dwell_time_passive_6g = params->dwell_time_passive_6g; 2109 cmd->min_rest_time = params->min_rest_time; 2110 cmd->max_rest_time = params->max_rest_time; 2111 cmd->repeat_probe_time = params->repeat_probe_time; 2112 cmd->probe_spacing_time = params->probe_spacing_time; 2113 cmd->idle_time = params->idle_time; 2114 cmd->max_scan_time = params->max_scan_time; 2115 cmd->probe_delay = params->probe_delay; 2116 cmd->burst_duration = params->burst_duration; 2117 cmd->num_chan = params->num_chan; 2118 cmd->num_bssid = params->num_bssid; 2119 cmd->num_ssids = params->num_ssids; 2120 cmd->ie_len = params->extraie.len; 2121 cmd->n_probes = params->n_probes; 2122 2123 ptr += sizeof(*cmd); 2124 2125 len = params->num_chan * sizeof(u32); 2126 2127 tlv = ptr; 2128 tlv->header = FIELD_PREP(WMI_TLV_TAG, WMI_TAG_ARRAY_UINT32) | 2129 FIELD_PREP(WMI_TLV_LEN, len); 2130 ptr += TLV_HDR_SIZE; 2131 tmp_ptr = (u32 *)ptr; 2132 2133 for (i = 0; i < params->num_chan; ++i) 2134 tmp_ptr[i] = params->chan_list[i]; 2135 2136 ptr += len; 2137 2138 len = params->num_ssids * sizeof(*ssid); 2139 tlv = ptr; 2140 tlv->header = FIELD_PREP(WMI_TLV_TAG, WMI_TAG_ARRAY_FIXED_STRUCT) | 2141 FIELD_PREP(WMI_TLV_LEN, len); 2142 2143 ptr += TLV_HDR_SIZE; 2144 2145 if (params->num_ssids) { 2146 ssid = ptr; 2147 for (i = 0; i < params->num_ssids; ++i) { 2148 ssid->ssid_len = params->ssid[i].length; 2149 memcpy(ssid->ssid, params->ssid[i].ssid, 2150 params->ssid[i].length); 2151 ssid++; 2152 } 2153 } 2154 2155 ptr += (params->num_ssids * sizeof(*ssid)); 2156 len = params->num_bssid * sizeof(*bssid); 2157 tlv = ptr; 2158 tlv->header = FIELD_PREP(WMI_TLV_TAG, WMI_TAG_ARRAY_FIXED_STRUCT) | 2159 FIELD_PREP(WMI_TLV_LEN, len); 2160 2161 ptr += TLV_HDR_SIZE; 2162 bssid = ptr; 2163 2164 if (params->num_bssid) { 2165 for (i = 0; i < params->num_bssid; ++i) { 2166 ether_addr_copy(bssid->addr, 2167 params->bssid_list[i].addr); 2168 bssid++; 2169 } 2170 } 2171 2172 ptr += params->num_bssid * sizeof(*bssid); 2173 2174 len = extraie_len_with_pad; 2175 tlv = ptr; 2176 tlv->header = FIELD_PREP(WMI_TLV_TAG, WMI_TAG_ARRAY_BYTE) | 2177 FIELD_PREP(WMI_TLV_LEN, len); 2178 ptr += TLV_HDR_SIZE; 2179 2180 if (params->extraie.len) 2181 memcpy(ptr, params->extraie.ptr, 2182 params->extraie.len); 2183 2184 ptr += extraie_len_with_pad; 2185 2186 if (params->num_hint_s_ssid) { 2187 len = params->num_hint_s_ssid * sizeof(struct hint_short_ssid); 2188 tlv = ptr; 2189 tlv->header = FIELD_PREP(WMI_TLV_TAG, WMI_TAG_ARRAY_FIXED_STRUCT) | 2190 FIELD_PREP(WMI_TLV_LEN, len); 2191 ptr += TLV_HDR_SIZE; 2192 s_ssid = ptr; 2193 for (i = 0; i < params->num_hint_s_ssid; ++i) { 2194 s_ssid->freq_flags = params->hint_s_ssid[i].freq_flags; 2195 s_ssid->short_ssid = params->hint_s_ssid[i].short_ssid; 2196 s_ssid++; 2197 } 2198 ptr += len; 2199 } 2200 2201 if (params->num_hint_bssid) { 2202 len = params->num_hint_bssid * sizeof(struct hint_bssid); 2203 tlv = ptr; 2204 tlv->header = FIELD_PREP(WMI_TLV_TAG, WMI_TAG_ARRAY_FIXED_STRUCT) | 2205 FIELD_PREP(WMI_TLV_LEN, len); 2206 ptr += TLV_HDR_SIZE; 2207 hint_bssid = ptr; 2208 for (i = 0; i < params->num_hint_bssid; ++i) { 2209 hint_bssid->freq_flags = 2210 params->hint_bssid[i].freq_flags; 2211 ether_addr_copy(¶ms->hint_bssid[i].bssid.addr[0], 2212 &hint_bssid->bssid.addr[0]); 2213 hint_bssid++; 2214 } 2215 } 2216 2217 ret = ath11k_wmi_cmd_send(wmi, skb, 2218 WMI_START_SCAN_CMDID); 2219 if (ret) { 2220 ath11k_warn(ar->ab, "failed to send WMI_START_SCAN_CMDID\n"); 2221 dev_kfree_skb(skb); 2222 } 2223 2224 return ret; 2225 } 2226 2227 int ath11k_wmi_send_scan_stop_cmd(struct ath11k *ar, 2228 struct scan_cancel_param *param) 2229 { 2230 struct ath11k_pdev_wmi *wmi = ar->wmi; 2231 struct wmi_stop_scan_cmd *cmd; 2232 struct sk_buff *skb; 2233 int ret; 2234 2235 skb = ath11k_wmi_alloc_skb(wmi->wmi_ab, sizeof(*cmd)); 2236 if (!skb) 2237 return -ENOMEM; 2238 2239 cmd = (struct wmi_stop_scan_cmd *)skb->data; 2240 2241 cmd->tlv_header = FIELD_PREP(WMI_TLV_TAG, WMI_TAG_STOP_SCAN_CMD) | 2242 FIELD_PREP(WMI_TLV_LEN, sizeof(*cmd) - TLV_HDR_SIZE); 2243 2244 cmd->vdev_id = param->vdev_id; 2245 cmd->requestor = param->requester; 2246 cmd->scan_id = param->scan_id; 2247 cmd->pdev_id = param->pdev_id; 2248 /* stop the scan with the corresponding scan_id */ 2249 if (param->req_type == WLAN_SCAN_CANCEL_PDEV_ALL) { 2250 /* Cancelling all scans */ 2251 cmd->req_type = WMI_SCAN_STOP_ALL; 2252 } else if (param->req_type == WLAN_SCAN_CANCEL_VDEV_ALL) { 2253 /* Cancelling VAP scans */ 2254 cmd->req_type = WMI_SCN_STOP_VAP_ALL; 2255 } else if (param->req_type == WLAN_SCAN_CANCEL_SINGLE) { 2256 /* Cancelling specific scan */ 2257 cmd->req_type = WMI_SCAN_STOP_ONE; 2258 } else { 2259 ath11k_warn(ar->ab, "invalid scan cancel param %d", 2260 param->req_type); 2261 dev_kfree_skb(skb); 2262 return -EINVAL; 2263 } 2264 2265 ret = ath11k_wmi_cmd_send(wmi, skb, 2266 WMI_STOP_SCAN_CMDID); 2267 if (ret) { 2268 ath11k_warn(ar->ab, "failed to send WMI_STOP_SCAN_CMDID\n"); 2269 dev_kfree_skb(skb); 2270 } 2271 2272 return ret; 2273 } 2274 2275 int ath11k_wmi_send_scan_chan_list_cmd(struct ath11k *ar, 2276 struct scan_chan_list_params *chan_list) 2277 { 2278 struct ath11k_pdev_wmi *wmi = ar->wmi; 2279 struct wmi_scan_chan_list_cmd *cmd; 2280 struct sk_buff *skb; 2281 struct wmi_channel *chan_info; 2282 struct channel_param *tchan_info; 2283 struct wmi_tlv *tlv; 2284 void *ptr; 2285 int i, ret, len; 2286 u16 num_send_chans, num_sends = 0, max_chan_limit = 0; 2287 u32 *reg1, *reg2; 2288 2289 tchan_info = &chan_list->ch_param[0]; 2290 while (chan_list->nallchans) { 2291 len = sizeof(*cmd) + TLV_HDR_SIZE; 2292 max_chan_limit = (wmi->wmi_ab->max_msg_len[ar->pdev_idx] - len) / 2293 sizeof(*chan_info); 2294 2295 if (chan_list->nallchans > max_chan_limit) 2296 num_send_chans = max_chan_limit; 2297 else 2298 num_send_chans = chan_list->nallchans; 2299 2300 chan_list->nallchans -= num_send_chans; 2301 len += sizeof(*chan_info) * num_send_chans; 2302 2303 skb = ath11k_wmi_alloc_skb(wmi->wmi_ab, len); 2304 if (!skb) 2305 return -ENOMEM; 2306 2307 cmd = (struct wmi_scan_chan_list_cmd *)skb->data; 2308 cmd->tlv_header = FIELD_PREP(WMI_TLV_TAG, WMI_TAG_SCAN_CHAN_LIST_CMD) | 2309 FIELD_PREP(WMI_TLV_LEN, sizeof(*cmd) - TLV_HDR_SIZE); 2310 cmd->pdev_id = chan_list->pdev_id; 2311 cmd->num_scan_chans = num_send_chans; 2312 if (num_sends) 2313 cmd->flags |= WMI_APPEND_TO_EXISTING_CHAN_LIST_FLAG; 2314 2315 ath11k_dbg(ar->ab, ATH11K_DBG_WMI, 2316 "WMI no.of chan = %d len = %d pdev_id = %d num_sends = %d\n", 2317 num_send_chans, len, cmd->pdev_id, num_sends); 2318 2319 ptr = skb->data + sizeof(*cmd); 2320 2321 len = sizeof(*chan_info) * num_send_chans; 2322 tlv = ptr; 2323 tlv->header = FIELD_PREP(WMI_TLV_TAG, WMI_TAG_ARRAY_STRUCT) | 2324 FIELD_PREP(WMI_TLV_LEN, len - TLV_HDR_SIZE); 2325 ptr += TLV_HDR_SIZE; 2326 2327 for (i = 0; i < num_send_chans; ++i) { 2328 chan_info = ptr; 2329 memset(chan_info, 0, sizeof(*chan_info)); 2330 len = sizeof(*chan_info); 2331 chan_info->tlv_header = FIELD_PREP(WMI_TLV_TAG, 2332 WMI_TAG_CHANNEL) | 2333 FIELD_PREP(WMI_TLV_LEN, 2334 len - TLV_HDR_SIZE); 2335 2336 reg1 = &chan_info->reg_info_1; 2337 reg2 = &chan_info->reg_info_2; 2338 chan_info->mhz = tchan_info->mhz; 2339 chan_info->band_center_freq1 = tchan_info->cfreq1; 2340 chan_info->band_center_freq2 = tchan_info->cfreq2; 2341 2342 if (tchan_info->is_chan_passive) 2343 chan_info->info |= WMI_CHAN_INFO_PASSIVE; 2344 if (tchan_info->allow_he) 2345 chan_info->info |= WMI_CHAN_INFO_ALLOW_HE; 2346 else if (tchan_info->allow_vht) 2347 chan_info->info |= WMI_CHAN_INFO_ALLOW_VHT; 2348 else if (tchan_info->allow_ht) 2349 chan_info->info |= WMI_CHAN_INFO_ALLOW_HT; 2350 if (tchan_info->half_rate) 2351 chan_info->info |= WMI_CHAN_INFO_HALF_RATE; 2352 if (tchan_info->quarter_rate) 2353 chan_info->info |= WMI_CHAN_INFO_QUARTER_RATE; 2354 if (tchan_info->psc_channel) 2355 chan_info->info |= WMI_CHAN_INFO_PSC; 2356 2357 chan_info->info |= FIELD_PREP(WMI_CHAN_INFO_MODE, 2358 tchan_info->phy_mode); 2359 *reg1 |= FIELD_PREP(WMI_CHAN_REG_INFO1_MIN_PWR, 2360 tchan_info->minpower); 2361 *reg1 |= FIELD_PREP(WMI_CHAN_REG_INFO1_MAX_PWR, 2362 tchan_info->maxpower); 2363 *reg1 |= FIELD_PREP(WMI_CHAN_REG_INFO1_MAX_REG_PWR, 2364 tchan_info->maxregpower); 2365 *reg1 |= FIELD_PREP(WMI_CHAN_REG_INFO1_REG_CLS, 2366 tchan_info->reg_class_id); 2367 *reg2 |= FIELD_PREP(WMI_CHAN_REG_INFO2_ANT_MAX, 2368 tchan_info->antennamax); 2369 2370 ath11k_dbg(ar->ab, ATH11K_DBG_WMI, 2371 "WMI chan scan list chan[%d] = %u, chan_info->info %8x\n", 2372 i, chan_info->mhz, chan_info->info); 2373 2374 ptr += sizeof(*chan_info); 2375 2376 tchan_info++; 2377 } 2378 2379 ret = ath11k_wmi_cmd_send(wmi, skb, WMI_SCAN_CHAN_LIST_CMDID); 2380 if (ret) { 2381 ath11k_warn(ar->ab, "failed to send WMI_SCAN_CHAN_LIST cmd\n"); 2382 dev_kfree_skb(skb); 2383 return ret; 2384 } 2385 2386 num_sends++; 2387 } 2388 2389 return 0; 2390 } 2391 2392 int ath11k_wmi_send_wmm_update_cmd_tlv(struct ath11k *ar, u32 vdev_id, 2393 struct wmi_wmm_params_all_arg *param) 2394 { 2395 struct ath11k_pdev_wmi *wmi = ar->wmi; 2396 struct wmi_vdev_set_wmm_params_cmd *cmd; 2397 struct wmi_wmm_params *wmm_param; 2398 struct wmi_wmm_params_arg *wmi_wmm_arg; 2399 struct sk_buff *skb; 2400 int ret, ac; 2401 2402 skb = ath11k_wmi_alloc_skb(wmi->wmi_ab, sizeof(*cmd)); 2403 if (!skb) 2404 return -ENOMEM; 2405 2406 cmd = (struct wmi_vdev_set_wmm_params_cmd *)skb->data; 2407 cmd->tlv_header = FIELD_PREP(WMI_TLV_TAG, 2408 WMI_TAG_VDEV_SET_WMM_PARAMS_CMD) | 2409 FIELD_PREP(WMI_TLV_LEN, sizeof(*cmd) - TLV_HDR_SIZE); 2410 2411 cmd->vdev_id = vdev_id; 2412 cmd->wmm_param_type = 0; 2413 2414 for (ac = 0; ac < WME_NUM_AC; ac++) { 2415 switch (ac) { 2416 case WME_AC_BE: 2417 wmi_wmm_arg = ¶m->ac_be; 2418 break; 2419 case WME_AC_BK: 2420 wmi_wmm_arg = ¶m->ac_bk; 2421 break; 2422 case WME_AC_VI: 2423 wmi_wmm_arg = ¶m->ac_vi; 2424 break; 2425 case WME_AC_VO: 2426 wmi_wmm_arg = ¶m->ac_vo; 2427 break; 2428 } 2429 2430 wmm_param = (struct wmi_wmm_params *)&cmd->wmm_params[ac]; 2431 wmm_param->tlv_header = 2432 FIELD_PREP(WMI_TLV_TAG, 2433 WMI_TAG_VDEV_SET_WMM_PARAMS_CMD) | 2434 FIELD_PREP(WMI_TLV_LEN, 2435 sizeof(*wmm_param) - TLV_HDR_SIZE); 2436 2437 wmm_param->aifs = wmi_wmm_arg->aifs; 2438 wmm_param->cwmin = wmi_wmm_arg->cwmin; 2439 wmm_param->cwmax = wmi_wmm_arg->cwmax; 2440 wmm_param->txoplimit = wmi_wmm_arg->txop; 2441 wmm_param->acm = wmi_wmm_arg->acm; 2442 wmm_param->no_ack = wmi_wmm_arg->no_ack; 2443 2444 ath11k_dbg(ar->ab, ATH11K_DBG_WMI, 2445 "wmi wmm set ac %d aifs %d cwmin %d cwmax %d txop %d acm %d no_ack %d\n", 2446 ac, wmm_param->aifs, wmm_param->cwmin, 2447 wmm_param->cwmax, wmm_param->txoplimit, 2448 wmm_param->acm, wmm_param->no_ack); 2449 } 2450 ret = ath11k_wmi_cmd_send(wmi, skb, 2451 WMI_VDEV_SET_WMM_PARAMS_CMDID); 2452 if (ret) { 2453 ath11k_warn(ar->ab, 2454 "failed to send WMI_VDEV_SET_WMM_PARAMS_CMDID"); 2455 dev_kfree_skb(skb); 2456 } 2457 2458 return ret; 2459 } 2460 2461 int ath11k_wmi_send_dfs_phyerr_offload_enable_cmd(struct ath11k *ar, 2462 u32 pdev_id) 2463 { 2464 struct ath11k_pdev_wmi *wmi = ar->wmi; 2465 struct wmi_dfs_phyerr_offload_cmd *cmd; 2466 struct sk_buff *skb; 2467 int ret; 2468 2469 skb = ath11k_wmi_alloc_skb(wmi->wmi_ab, sizeof(*cmd)); 2470 if (!skb) 2471 return -ENOMEM; 2472 2473 cmd = (struct wmi_dfs_phyerr_offload_cmd *)skb->data; 2474 cmd->tlv_header = 2475 FIELD_PREP(WMI_TLV_TAG, 2476 WMI_TAG_PDEV_DFS_PHYERR_OFFLOAD_ENABLE_CMD) | 2477 FIELD_PREP(WMI_TLV_LEN, sizeof(*cmd) - TLV_HDR_SIZE); 2478 2479 cmd->pdev_id = pdev_id; 2480 2481 ath11k_dbg(ar->ab, ATH11K_DBG_WMI, 2482 "WMI dfs phy err offload enable pdev id %d\n", pdev_id); 2483 2484 ret = ath11k_wmi_cmd_send(wmi, skb, 2485 WMI_PDEV_DFS_PHYERR_OFFLOAD_ENABLE_CMDID); 2486 if (ret) { 2487 ath11k_warn(ar->ab, 2488 "failed to send WMI_PDEV_DFS_PHYERR_OFFLOAD_ENABLE cmd\n"); 2489 dev_kfree_skb(skb); 2490 } 2491 2492 return ret; 2493 } 2494 2495 int ath11k_wmi_delba_send(struct ath11k *ar, u32 vdev_id, const u8 *mac, 2496 u32 tid, u32 initiator, u32 reason) 2497 { 2498 struct ath11k_pdev_wmi *wmi = ar->wmi; 2499 struct wmi_delba_send_cmd *cmd; 2500 struct sk_buff *skb; 2501 int ret; 2502 2503 skb = ath11k_wmi_alloc_skb(wmi->wmi_ab, sizeof(*cmd)); 2504 if (!skb) 2505 return -ENOMEM; 2506 2507 cmd = (struct wmi_delba_send_cmd *)skb->data; 2508 cmd->tlv_header = FIELD_PREP(WMI_TLV_TAG, WMI_TAG_DELBA_SEND_CMD) | 2509 FIELD_PREP(WMI_TLV_LEN, sizeof(*cmd) - TLV_HDR_SIZE); 2510 cmd->vdev_id = vdev_id; 2511 ether_addr_copy(cmd->peer_macaddr.addr, mac); 2512 cmd->tid = tid; 2513 cmd->initiator = initiator; 2514 cmd->reasoncode = reason; 2515 2516 ath11k_dbg(ar->ab, ATH11K_DBG_WMI, 2517 "wmi delba send vdev_id 0x%X mac_addr %pM tid %u initiator %u reason %u\n", 2518 vdev_id, mac, tid, initiator, reason); 2519 2520 ret = ath11k_wmi_cmd_send(wmi, skb, WMI_DELBA_SEND_CMDID); 2521 2522 if (ret) { 2523 ath11k_warn(ar->ab, 2524 "failed to send WMI_DELBA_SEND_CMDID cmd\n"); 2525 dev_kfree_skb(skb); 2526 } 2527 2528 return ret; 2529 } 2530 2531 int ath11k_wmi_addba_set_resp(struct ath11k *ar, u32 vdev_id, const u8 *mac, 2532 u32 tid, u32 status) 2533 { 2534 struct ath11k_pdev_wmi *wmi = ar->wmi; 2535 struct wmi_addba_setresponse_cmd *cmd; 2536 struct sk_buff *skb; 2537 int ret; 2538 2539 skb = ath11k_wmi_alloc_skb(wmi->wmi_ab, sizeof(*cmd)); 2540 if (!skb) 2541 return -ENOMEM; 2542 2543 cmd = (struct wmi_addba_setresponse_cmd *)skb->data; 2544 cmd->tlv_header = 2545 FIELD_PREP(WMI_TLV_TAG, WMI_TAG_ADDBA_SETRESPONSE_CMD) | 2546 FIELD_PREP(WMI_TLV_LEN, sizeof(*cmd) - TLV_HDR_SIZE); 2547 cmd->vdev_id = vdev_id; 2548 ether_addr_copy(cmd->peer_macaddr.addr, mac); 2549 cmd->tid = tid; 2550 cmd->statuscode = status; 2551 2552 ath11k_dbg(ar->ab, ATH11K_DBG_WMI, 2553 "wmi addba set resp vdev_id 0x%X mac_addr %pM tid %u status %u\n", 2554 vdev_id, mac, tid, status); 2555 2556 ret = ath11k_wmi_cmd_send(wmi, skb, WMI_ADDBA_SET_RESP_CMDID); 2557 2558 if (ret) { 2559 ath11k_warn(ar->ab, 2560 "failed to send WMI_ADDBA_SET_RESP_CMDID cmd\n"); 2561 dev_kfree_skb(skb); 2562 } 2563 2564 return ret; 2565 } 2566 2567 int ath11k_wmi_addba_send(struct ath11k *ar, u32 vdev_id, const u8 *mac, 2568 u32 tid, u32 buf_size) 2569 { 2570 struct ath11k_pdev_wmi *wmi = ar->wmi; 2571 struct wmi_addba_send_cmd *cmd; 2572 struct sk_buff *skb; 2573 int ret; 2574 2575 skb = ath11k_wmi_alloc_skb(wmi->wmi_ab, sizeof(*cmd)); 2576 if (!skb) 2577 return -ENOMEM; 2578 2579 cmd = (struct wmi_addba_send_cmd *)skb->data; 2580 cmd->tlv_header = FIELD_PREP(WMI_TLV_TAG, WMI_TAG_ADDBA_SEND_CMD) | 2581 FIELD_PREP(WMI_TLV_LEN, sizeof(*cmd) - TLV_HDR_SIZE); 2582 cmd->vdev_id = vdev_id; 2583 ether_addr_copy(cmd->peer_macaddr.addr, mac); 2584 cmd->tid = tid; 2585 cmd->buffersize = buf_size; 2586 2587 ath11k_dbg(ar->ab, ATH11K_DBG_WMI, 2588 "wmi addba send vdev_id 0x%X mac_addr %pM tid %u bufsize %u\n", 2589 vdev_id, mac, tid, buf_size); 2590 2591 ret = ath11k_wmi_cmd_send(wmi, skb, WMI_ADDBA_SEND_CMDID); 2592 2593 if (ret) { 2594 ath11k_warn(ar->ab, 2595 "failed to send WMI_ADDBA_SEND_CMDID cmd\n"); 2596 dev_kfree_skb(skb); 2597 } 2598 2599 return ret; 2600 } 2601 2602 int ath11k_wmi_addba_clear_resp(struct ath11k *ar, u32 vdev_id, const u8 *mac) 2603 { 2604 struct ath11k_pdev_wmi *wmi = ar->wmi; 2605 struct wmi_addba_clear_resp_cmd *cmd; 2606 struct sk_buff *skb; 2607 int ret; 2608 2609 skb = ath11k_wmi_alloc_skb(wmi->wmi_ab, sizeof(*cmd)); 2610 if (!skb) 2611 return -ENOMEM; 2612 2613 cmd = (struct wmi_addba_clear_resp_cmd *)skb->data; 2614 cmd->tlv_header = 2615 FIELD_PREP(WMI_TLV_TAG, WMI_TAG_ADDBA_CLEAR_RESP_CMD) | 2616 FIELD_PREP(WMI_TLV_LEN, sizeof(*cmd) - TLV_HDR_SIZE); 2617 cmd->vdev_id = vdev_id; 2618 ether_addr_copy(cmd->peer_macaddr.addr, mac); 2619 2620 ath11k_dbg(ar->ab, ATH11K_DBG_WMI, 2621 "wmi addba clear resp vdev_id 0x%X mac_addr %pM\n", 2622 vdev_id, mac); 2623 2624 ret = ath11k_wmi_cmd_send(wmi, skb, WMI_ADDBA_CLEAR_RESP_CMDID); 2625 2626 if (ret) { 2627 ath11k_warn(ar->ab, 2628 "failed to send WMI_ADDBA_CLEAR_RESP_CMDID cmd\n"); 2629 dev_kfree_skb(skb); 2630 } 2631 2632 return ret; 2633 } 2634 2635 int ath11k_wmi_pdev_peer_pktlog_filter(struct ath11k *ar, u8 *addr, u8 enable) 2636 { 2637 struct ath11k_pdev_wmi *wmi = ar->wmi; 2638 struct wmi_pdev_pktlog_filter_cmd *cmd; 2639 struct wmi_pdev_pktlog_filter_info *info; 2640 struct sk_buff *skb; 2641 struct wmi_tlv *tlv; 2642 void *ptr; 2643 int ret, len; 2644 2645 len = sizeof(*cmd) + sizeof(*info) + TLV_HDR_SIZE; 2646 skb = ath11k_wmi_alloc_skb(wmi->wmi_ab, len); 2647 if (!skb) 2648 return -ENOMEM; 2649 2650 cmd = (struct wmi_pdev_pktlog_filter_cmd *)skb->data; 2651 2652 cmd->tlv_header = FIELD_PREP(WMI_TLV_TAG, WMI_TAG_PDEV_PEER_PKTLOG_FILTER_CMD) | 2653 FIELD_PREP(WMI_TLV_LEN, sizeof(*cmd) - TLV_HDR_SIZE); 2654 2655 cmd->pdev_id = DP_HW2SW_MACID(ar->pdev->pdev_id); 2656 cmd->num_mac = 1; 2657 cmd->enable = enable; 2658 2659 ptr = skb->data + sizeof(*cmd); 2660 2661 tlv = ptr; 2662 tlv->header = FIELD_PREP(WMI_TLV_TAG, WMI_TAG_ARRAY_STRUCT) | 2663 FIELD_PREP(WMI_TLV_LEN, sizeof(*info)); 2664 2665 ptr += TLV_HDR_SIZE; 2666 info = ptr; 2667 2668 ether_addr_copy(info->peer_macaddr.addr, addr); 2669 info->tlv_header = FIELD_PREP(WMI_TLV_TAG, WMI_TAG_PDEV_PEER_PKTLOG_FILTER_INFO) | 2670 FIELD_PREP(WMI_TLV_LEN, 2671 sizeof(*info) - TLV_HDR_SIZE); 2672 2673 ret = ath11k_wmi_cmd_send(wmi, skb, 2674 WMI_PDEV_PKTLOG_FILTER_CMDID); 2675 if (ret) { 2676 ath11k_warn(ar->ab, "failed to send WMI_PDEV_PKTLOG_ENABLE_CMDID\n"); 2677 dev_kfree_skb(skb); 2678 } 2679 2680 return ret; 2681 } 2682 2683 int 2684 ath11k_wmi_send_init_country_cmd(struct ath11k *ar, 2685 struct wmi_init_country_params init_cc_params) 2686 { 2687 struct ath11k_pdev_wmi *wmi = ar->wmi; 2688 struct wmi_init_country_cmd *cmd; 2689 struct sk_buff *skb; 2690 int ret; 2691 2692 skb = ath11k_wmi_alloc_skb(wmi->wmi_ab, sizeof(*cmd)); 2693 if (!skb) 2694 return -ENOMEM; 2695 2696 cmd = (struct wmi_init_country_cmd *)skb->data; 2697 cmd->tlv_header = 2698 FIELD_PREP(WMI_TLV_TAG, 2699 WMI_TAG_SET_INIT_COUNTRY_CMD) | 2700 FIELD_PREP(WMI_TLV_LEN, sizeof(*cmd) - TLV_HDR_SIZE); 2701 2702 cmd->pdev_id = ar->pdev->pdev_id; 2703 2704 switch (init_cc_params.flags) { 2705 case ALPHA_IS_SET: 2706 cmd->init_cc_type = WMI_COUNTRY_INFO_TYPE_ALPHA; 2707 memcpy((u8 *)&cmd->cc_info.alpha2, 2708 init_cc_params.cc_info.alpha2, 3); 2709 break; 2710 case CC_IS_SET: 2711 cmd->init_cc_type = WMI_COUNTRY_INFO_TYPE_COUNTRY_CODE; 2712 cmd->cc_info.country_code = init_cc_params.cc_info.country_code; 2713 break; 2714 case REGDMN_IS_SET: 2715 cmd->init_cc_type = WMI_COUNTRY_INFO_TYPE_REGDOMAIN; 2716 cmd->cc_info.regdom_id = init_cc_params.cc_info.regdom_id; 2717 break; 2718 default: 2719 ret = -EINVAL; 2720 goto out; 2721 } 2722 2723 ret = ath11k_wmi_cmd_send(wmi, skb, 2724 WMI_SET_INIT_COUNTRY_CMDID); 2725 2726 out: 2727 if (ret) { 2728 ath11k_warn(ar->ab, 2729 "failed to send WMI_SET_INIT_COUNTRY CMD :%d\n", 2730 ret); 2731 dev_kfree_skb(skb); 2732 } 2733 2734 return ret; 2735 } 2736 2737 int 2738 ath11k_wmi_send_thermal_mitigation_param_cmd(struct ath11k *ar, 2739 struct thermal_mitigation_params *param) 2740 { 2741 struct ath11k_pdev_wmi *wmi = ar->wmi; 2742 struct wmi_therm_throt_config_request_cmd *cmd; 2743 struct wmi_therm_throt_level_config_info *lvl_conf; 2744 struct wmi_tlv *tlv; 2745 struct sk_buff *skb; 2746 int i, ret, len; 2747 2748 len = sizeof(*cmd) + TLV_HDR_SIZE + 2749 THERMAL_LEVELS * sizeof(struct wmi_therm_throt_level_config_info); 2750 2751 skb = ath11k_wmi_alloc_skb(wmi->wmi_ab, len); 2752 if (!skb) 2753 return -ENOMEM; 2754 2755 cmd = (struct wmi_therm_throt_config_request_cmd *)skb->data; 2756 2757 cmd->tlv_header = FIELD_PREP(WMI_TLV_TAG, WMI_TAG_THERM_THROT_CONFIG_REQUEST) | 2758 FIELD_PREP(WMI_TLV_LEN, sizeof(*cmd) - TLV_HDR_SIZE); 2759 2760 cmd->pdev_id = ar->pdev->pdev_id; 2761 cmd->enable = param->enable; 2762 cmd->dc = param->dc; 2763 cmd->dc_per_event = param->dc_per_event; 2764 cmd->therm_throt_levels = THERMAL_LEVELS; 2765 2766 tlv = (struct wmi_tlv *)(skb->data + sizeof(*cmd)); 2767 tlv->header = FIELD_PREP(WMI_TLV_TAG, WMI_TAG_ARRAY_STRUCT) | 2768 FIELD_PREP(WMI_TLV_LEN, 2769 (THERMAL_LEVELS * 2770 sizeof(struct wmi_therm_throt_level_config_info))); 2771 2772 lvl_conf = (struct wmi_therm_throt_level_config_info *)(skb->data + 2773 sizeof(*cmd) + 2774 TLV_HDR_SIZE); 2775 for (i = 0; i < THERMAL_LEVELS; i++) { 2776 lvl_conf->tlv_header = 2777 FIELD_PREP(WMI_TLV_TAG, WMI_TAG_THERM_THROT_LEVEL_CONFIG_INFO) | 2778 FIELD_PREP(WMI_TLV_LEN, sizeof(*lvl_conf) - TLV_HDR_SIZE); 2779 2780 lvl_conf->temp_lwm = param->levelconf[i].tmplwm; 2781 lvl_conf->temp_hwm = param->levelconf[i].tmphwm; 2782 lvl_conf->dc_off_percent = param->levelconf[i].dcoffpercent; 2783 lvl_conf->prio = param->levelconf[i].priority; 2784 lvl_conf++; 2785 } 2786 2787 ret = ath11k_wmi_cmd_send(wmi, skb, WMI_THERM_THROT_SET_CONF_CMDID); 2788 if (ret) { 2789 ath11k_warn(ar->ab, "failed to send THERM_THROT_SET_CONF cmd\n"); 2790 dev_kfree_skb(skb); 2791 } 2792 2793 ath11k_dbg(ar->ab, ATH11K_DBG_WMI, 2794 "WMI vdev set thermal throt pdev_id %d enable %d dc %d dc_per_event %x levels %d\n", 2795 ar->pdev->pdev_id, param->enable, param->dc, 2796 param->dc_per_event, THERMAL_LEVELS); 2797 2798 return ret; 2799 } 2800 2801 int ath11k_wmi_pdev_pktlog_enable(struct ath11k *ar, u32 pktlog_filter) 2802 { 2803 struct ath11k_pdev_wmi *wmi = ar->wmi; 2804 struct wmi_pktlog_enable_cmd *cmd; 2805 struct sk_buff *skb; 2806 int ret; 2807 2808 skb = ath11k_wmi_alloc_skb(wmi->wmi_ab, sizeof(*cmd)); 2809 if (!skb) 2810 return -ENOMEM; 2811 2812 cmd = (struct wmi_pktlog_enable_cmd *)skb->data; 2813 2814 cmd->tlv_header = FIELD_PREP(WMI_TLV_TAG, WMI_TAG_PDEV_PKTLOG_ENABLE_CMD) | 2815 FIELD_PREP(WMI_TLV_LEN, sizeof(*cmd) - TLV_HDR_SIZE); 2816 2817 cmd->pdev_id = DP_HW2SW_MACID(ar->pdev->pdev_id); 2818 cmd->evlist = pktlog_filter; 2819 cmd->enable = ATH11K_WMI_PKTLOG_ENABLE_FORCE; 2820 2821 ret = ath11k_wmi_cmd_send(wmi, skb, 2822 WMI_PDEV_PKTLOG_ENABLE_CMDID); 2823 if (ret) { 2824 ath11k_warn(ar->ab, "failed to send WMI_PDEV_PKTLOG_ENABLE_CMDID\n"); 2825 dev_kfree_skb(skb); 2826 } 2827 2828 return ret; 2829 } 2830 2831 int ath11k_wmi_pdev_pktlog_disable(struct ath11k *ar) 2832 { 2833 struct ath11k_pdev_wmi *wmi = ar->wmi; 2834 struct wmi_pktlog_disable_cmd *cmd; 2835 struct sk_buff *skb; 2836 int ret; 2837 2838 skb = ath11k_wmi_alloc_skb(wmi->wmi_ab, sizeof(*cmd)); 2839 if (!skb) 2840 return -ENOMEM; 2841 2842 cmd = (struct wmi_pktlog_disable_cmd *)skb->data; 2843 2844 cmd->tlv_header = FIELD_PREP(WMI_TLV_TAG, WMI_TAG_PDEV_PKTLOG_DISABLE_CMD) | 2845 FIELD_PREP(WMI_TLV_LEN, sizeof(*cmd) - TLV_HDR_SIZE); 2846 2847 cmd->pdev_id = DP_HW2SW_MACID(ar->pdev->pdev_id); 2848 2849 ret = ath11k_wmi_cmd_send(wmi, skb, 2850 WMI_PDEV_PKTLOG_DISABLE_CMDID); 2851 if (ret) { 2852 ath11k_warn(ar->ab, "failed to send WMI_PDEV_PKTLOG_ENABLE_CMDID\n"); 2853 dev_kfree_skb(skb); 2854 } 2855 2856 return ret; 2857 } 2858 2859 int 2860 ath11k_wmi_send_twt_enable_cmd(struct ath11k *ar, u32 pdev_id) 2861 { 2862 struct ath11k_pdev_wmi *wmi = ar->wmi; 2863 struct ath11k_base *ab = wmi->wmi_ab->ab; 2864 struct wmi_twt_enable_params_cmd *cmd; 2865 struct sk_buff *skb; 2866 int ret, len; 2867 2868 len = sizeof(*cmd); 2869 2870 skb = ath11k_wmi_alloc_skb(wmi->wmi_ab, len); 2871 if (!skb) 2872 return -ENOMEM; 2873 2874 cmd = (struct wmi_twt_enable_params_cmd *)skb->data; 2875 cmd->tlv_header = FIELD_PREP(WMI_TLV_TAG, WMI_TAG_TWT_ENABLE_CMD) | 2876 FIELD_PREP(WMI_TLV_LEN, len - TLV_HDR_SIZE); 2877 cmd->pdev_id = pdev_id; 2878 cmd->sta_cong_timer_ms = ATH11K_TWT_DEF_STA_CONG_TIMER_MS; 2879 cmd->default_slot_size = ATH11K_TWT_DEF_DEFAULT_SLOT_SIZE; 2880 cmd->congestion_thresh_setup = ATH11K_TWT_DEF_CONGESTION_THRESH_SETUP; 2881 cmd->congestion_thresh_teardown = 2882 ATH11K_TWT_DEF_CONGESTION_THRESH_TEARDOWN; 2883 cmd->congestion_thresh_critical = 2884 ATH11K_TWT_DEF_CONGESTION_THRESH_CRITICAL; 2885 cmd->interference_thresh_teardown = 2886 ATH11K_TWT_DEF_INTERFERENCE_THRESH_TEARDOWN; 2887 cmd->interference_thresh_setup = 2888 ATH11K_TWT_DEF_INTERFERENCE_THRESH_SETUP; 2889 cmd->min_no_sta_setup = ATH11K_TWT_DEF_MIN_NO_STA_SETUP; 2890 cmd->min_no_sta_teardown = ATH11K_TWT_DEF_MIN_NO_STA_TEARDOWN; 2891 cmd->no_of_bcast_mcast_slots = ATH11K_TWT_DEF_NO_OF_BCAST_MCAST_SLOTS; 2892 cmd->min_no_twt_slots = ATH11K_TWT_DEF_MIN_NO_TWT_SLOTS; 2893 cmd->max_no_sta_twt = ATH11K_TWT_DEF_MAX_NO_STA_TWT; 2894 cmd->mode_check_interval = ATH11K_TWT_DEF_MODE_CHECK_INTERVAL; 2895 cmd->add_sta_slot_interval = ATH11K_TWT_DEF_ADD_STA_SLOT_INTERVAL; 2896 cmd->remove_sta_slot_interval = 2897 ATH11K_TWT_DEF_REMOVE_STA_SLOT_INTERVAL; 2898 /* TODO add MBSSID support */ 2899 cmd->mbss_support = 0; 2900 2901 ret = ath11k_wmi_cmd_send(wmi, skb, 2902 WMI_TWT_ENABLE_CMDID); 2903 if (ret) { 2904 ath11k_warn(ab, "Failed to send WMI_TWT_ENABLE_CMDID"); 2905 dev_kfree_skb(skb); 2906 } 2907 return ret; 2908 } 2909 2910 int 2911 ath11k_wmi_send_twt_disable_cmd(struct ath11k *ar, u32 pdev_id) 2912 { 2913 struct ath11k_pdev_wmi *wmi = ar->wmi; 2914 struct ath11k_base *ab = wmi->wmi_ab->ab; 2915 struct wmi_twt_disable_params_cmd *cmd; 2916 struct sk_buff *skb; 2917 int ret, len; 2918 2919 len = sizeof(*cmd); 2920 2921 skb = ath11k_wmi_alloc_skb(wmi->wmi_ab, len); 2922 if (!skb) 2923 return -ENOMEM; 2924 2925 cmd = (struct wmi_twt_disable_params_cmd *)skb->data; 2926 cmd->tlv_header = FIELD_PREP(WMI_TLV_TAG, WMI_TAG_TWT_DISABLE_CMD) | 2927 FIELD_PREP(WMI_TLV_LEN, len - TLV_HDR_SIZE); 2928 cmd->pdev_id = pdev_id; 2929 2930 ret = ath11k_wmi_cmd_send(wmi, skb, 2931 WMI_TWT_DISABLE_CMDID); 2932 if (ret) { 2933 ath11k_warn(ab, "Failed to send WMI_TWT_DISABLE_CMDID"); 2934 dev_kfree_skb(skb); 2935 } 2936 return ret; 2937 } 2938 2939 int 2940 ath11k_wmi_send_obss_spr_cmd(struct ath11k *ar, u32 vdev_id, 2941 struct ieee80211_he_obss_pd *he_obss_pd) 2942 { 2943 struct ath11k_pdev_wmi *wmi = ar->wmi; 2944 struct ath11k_base *ab = wmi->wmi_ab->ab; 2945 struct wmi_obss_spatial_reuse_params_cmd *cmd; 2946 struct sk_buff *skb; 2947 int ret, len; 2948 2949 len = sizeof(*cmd); 2950 2951 skb = ath11k_wmi_alloc_skb(wmi->wmi_ab, len); 2952 if (!skb) 2953 return -ENOMEM; 2954 2955 cmd = (struct wmi_obss_spatial_reuse_params_cmd *)skb->data; 2956 cmd->tlv_header = FIELD_PREP(WMI_TLV_TAG, 2957 WMI_TAG_OBSS_SPATIAL_REUSE_SET_CMD) | 2958 FIELD_PREP(WMI_TLV_LEN, len - TLV_HDR_SIZE); 2959 cmd->vdev_id = vdev_id; 2960 cmd->enable = he_obss_pd->enable; 2961 cmd->obss_min = he_obss_pd->min_offset; 2962 cmd->obss_max = he_obss_pd->max_offset; 2963 2964 ret = ath11k_wmi_cmd_send(wmi, skb, 2965 WMI_PDEV_OBSS_PD_SPATIAL_REUSE_CMDID); 2966 if (ret) { 2967 ath11k_warn(ab, 2968 "Failed to send WMI_PDEV_OBSS_PD_SPATIAL_REUSE_CMDID"); 2969 dev_kfree_skb(skb); 2970 } 2971 return ret; 2972 } 2973 2974 int 2975 ath11k_wmi_pdev_set_srg_bss_color_bitmap(struct ath11k *ar, u32 *bitmap) 2976 { 2977 struct ath11k_pdev_wmi *wmi = ar->wmi; 2978 struct ath11k_base *ab = wmi->wmi_ab->ab; 2979 struct wmi_pdev_obss_pd_bitmap_cmd *cmd; 2980 struct sk_buff *skb; 2981 int ret, len; 2982 2983 len = sizeof(*cmd); 2984 2985 skb = ath11k_wmi_alloc_skb(wmi->wmi_ab, len); 2986 if (!skb) 2987 return -ENOMEM; 2988 2989 cmd = (struct wmi_pdev_obss_pd_bitmap_cmd *)skb->data; 2990 cmd->tlv_header = FIELD_PREP(WMI_TLV_TAG, 2991 WMI_TAG_PDEV_SRG_BSS_COLOR_BITMAP_CMD) | 2992 FIELD_PREP(WMI_TLV_LEN, len - TLV_HDR_SIZE); 2993 cmd->pdev_id = ar->pdev->pdev_id; 2994 memcpy(cmd->bitmap, bitmap, sizeof(cmd->bitmap)); 2995 2996 ath11k_dbg(ar->ab, ATH11K_DBG_WMI, 2997 "obss pd pdev_id %d bss color bitmap %08x %08x\n", 2998 cmd->pdev_id, cmd->bitmap[0], cmd->bitmap[1]); 2999 3000 ret = ath11k_wmi_cmd_send(wmi, skb, 3001 WMI_PDEV_SET_SRG_BSS_COLOR_BITMAP_CMDID); 3002 if (ret) { 3003 ath11k_warn(ab, 3004 "failed to send WMI_PDEV_SET_SRG_BSS_COLOR_BITMAP_CMDID"); 3005 dev_kfree_skb(skb); 3006 } 3007 3008 return ret; 3009 } 3010 3011 int 3012 ath11k_wmi_pdev_set_srg_patial_bssid_bitmap(struct ath11k *ar, u32 *bitmap) 3013 { 3014 struct ath11k_pdev_wmi *wmi = ar->wmi; 3015 struct ath11k_base *ab = wmi->wmi_ab->ab; 3016 struct wmi_pdev_obss_pd_bitmap_cmd *cmd; 3017 struct sk_buff *skb; 3018 int ret, len; 3019 3020 len = sizeof(*cmd); 3021 3022 skb = ath11k_wmi_alloc_skb(wmi->wmi_ab, len); 3023 if (!skb) 3024 return -ENOMEM; 3025 3026 cmd = (struct wmi_pdev_obss_pd_bitmap_cmd *)skb->data; 3027 cmd->tlv_header = 3028 FIELD_PREP(WMI_TLV_TAG, 3029 WMI_TAG_PDEV_SRG_PARTIAL_BSSID_BITMAP_CMD) | 3030 FIELD_PREP(WMI_TLV_LEN, len - TLV_HDR_SIZE); 3031 cmd->pdev_id = ar->pdev->pdev_id; 3032 memcpy(cmd->bitmap, bitmap, sizeof(cmd->bitmap)); 3033 3034 ath11k_dbg(ar->ab, ATH11K_DBG_WMI, 3035 "obss pd pdev_id %d partial bssid bitmap %08x %08x\n", 3036 cmd->pdev_id, cmd->bitmap[0], cmd->bitmap[1]); 3037 3038 ret = ath11k_wmi_cmd_send(wmi, skb, 3039 WMI_PDEV_SET_SRG_PARTIAL_BSSID_BITMAP_CMDID); 3040 if (ret) { 3041 ath11k_warn(ab, 3042 "failed to send WMI_PDEV_SET_SRG_PARTIAL_BSSID_BITMAP_CMDID"); 3043 dev_kfree_skb(skb); 3044 } 3045 3046 return ret; 3047 } 3048 3049 int 3050 ath11k_wmi_pdev_srg_obss_color_enable_bitmap(struct ath11k *ar, u32 *bitmap) 3051 { 3052 struct ath11k_pdev_wmi *wmi = ar->wmi; 3053 struct ath11k_base *ab = wmi->wmi_ab->ab; 3054 struct wmi_pdev_obss_pd_bitmap_cmd *cmd; 3055 struct sk_buff *skb; 3056 int ret, len; 3057 3058 len = sizeof(*cmd); 3059 3060 skb = ath11k_wmi_alloc_skb(wmi->wmi_ab, len); 3061 if (!skb) 3062 return -ENOMEM; 3063 3064 cmd = (struct wmi_pdev_obss_pd_bitmap_cmd *)skb->data; 3065 cmd->tlv_header = 3066 FIELD_PREP(WMI_TLV_TAG, 3067 WMI_TAG_PDEV_SRG_OBSS_COLOR_ENABLE_BITMAP_CMD) | 3068 FIELD_PREP(WMI_TLV_LEN, len - TLV_HDR_SIZE); 3069 cmd->pdev_id = ar->pdev->pdev_id; 3070 memcpy(cmd->bitmap, bitmap, sizeof(cmd->bitmap)); 3071 3072 ath11k_dbg(ar->ab, ATH11K_DBG_WMI, 3073 "obss pd srg pdev_id %d bss color enable bitmap %08x %08x\n", 3074 cmd->pdev_id, cmd->bitmap[0], cmd->bitmap[1]); 3075 3076 ret = ath11k_wmi_cmd_send(wmi, skb, 3077 WMI_PDEV_SET_SRG_OBSS_COLOR_ENABLE_BITMAP_CMDID); 3078 if (ret) { 3079 ath11k_warn(ab, 3080 "failed to send WMI_PDEV_SET_SRG_OBSS_COLOR_ENABLE_BITMAP_CMDID"); 3081 dev_kfree_skb(skb); 3082 } 3083 3084 return ret; 3085 } 3086 3087 int 3088 ath11k_wmi_pdev_srg_obss_bssid_enable_bitmap(struct ath11k *ar, u32 *bitmap) 3089 { 3090 struct ath11k_pdev_wmi *wmi = ar->wmi; 3091 struct ath11k_base *ab = wmi->wmi_ab->ab; 3092 struct wmi_pdev_obss_pd_bitmap_cmd *cmd; 3093 struct sk_buff *skb; 3094 int ret, len; 3095 3096 len = sizeof(*cmd); 3097 3098 skb = ath11k_wmi_alloc_skb(wmi->wmi_ab, len); 3099 if (!skb) 3100 return -ENOMEM; 3101 3102 cmd = (struct wmi_pdev_obss_pd_bitmap_cmd *)skb->data; 3103 cmd->tlv_header = 3104 FIELD_PREP(WMI_TLV_TAG, 3105 WMI_TAG_PDEV_SRG_OBSS_BSSID_ENABLE_BITMAP_CMD) | 3106 FIELD_PREP(WMI_TLV_LEN, len - TLV_HDR_SIZE); 3107 cmd->pdev_id = ar->pdev->pdev_id; 3108 memcpy(cmd->bitmap, bitmap, sizeof(cmd->bitmap)); 3109 3110 ath11k_dbg(ar->ab, ATH11K_DBG_WMI, 3111 "obss pd srg pdev_id %d bssid enable bitmap %08x %08x\n", 3112 cmd->pdev_id, cmd->bitmap[0], cmd->bitmap[1]); 3113 3114 ret = ath11k_wmi_cmd_send(wmi, skb, 3115 WMI_PDEV_SET_SRG_OBSS_BSSID_ENABLE_BITMAP_CMDID); 3116 if (ret) { 3117 ath11k_warn(ab, 3118 "failed to send WMI_PDEV_SET_SRG_OBSS_BSSID_ENABLE_BITMAP_CMDID"); 3119 dev_kfree_skb(skb); 3120 } 3121 3122 return ret; 3123 } 3124 3125 int 3126 ath11k_wmi_pdev_non_srg_obss_color_enable_bitmap(struct ath11k *ar, u32 *bitmap) 3127 { 3128 struct ath11k_pdev_wmi *wmi = ar->wmi; 3129 struct ath11k_base *ab = wmi->wmi_ab->ab; 3130 struct wmi_pdev_obss_pd_bitmap_cmd *cmd; 3131 struct sk_buff *skb; 3132 int ret, len; 3133 3134 len = sizeof(*cmd); 3135 3136 skb = ath11k_wmi_alloc_skb(wmi->wmi_ab, len); 3137 if (!skb) 3138 return -ENOMEM; 3139 3140 cmd = (struct wmi_pdev_obss_pd_bitmap_cmd *)skb->data; 3141 cmd->tlv_header = 3142 FIELD_PREP(WMI_TLV_TAG, 3143 WMI_TAG_PDEV_NON_SRG_OBSS_COLOR_ENABLE_BITMAP_CMD) | 3144 FIELD_PREP(WMI_TLV_LEN, len - TLV_HDR_SIZE); 3145 cmd->pdev_id = ar->pdev->pdev_id; 3146 memcpy(cmd->bitmap, bitmap, sizeof(cmd->bitmap)); 3147 3148 ath11k_dbg(ar->ab, ATH11K_DBG_WMI, 3149 "obss pd non_srg pdev_id %d bss color enable bitmap %08x %08x\n", 3150 cmd->pdev_id, cmd->bitmap[0], cmd->bitmap[1]); 3151 3152 ret = ath11k_wmi_cmd_send(wmi, skb, 3153 WMI_PDEV_SET_NON_SRG_OBSS_COLOR_ENABLE_BITMAP_CMDID); 3154 if (ret) { 3155 ath11k_warn(ab, 3156 "failed to send WMI_PDEV_SET_NON_SRG_OBSS_COLOR_ENABLE_BITMAP_CMDID"); 3157 dev_kfree_skb(skb); 3158 } 3159 3160 return ret; 3161 } 3162 3163 int 3164 ath11k_wmi_pdev_non_srg_obss_bssid_enable_bitmap(struct ath11k *ar, u32 *bitmap) 3165 { 3166 struct ath11k_pdev_wmi *wmi = ar->wmi; 3167 struct ath11k_base *ab = wmi->wmi_ab->ab; 3168 struct wmi_pdev_obss_pd_bitmap_cmd *cmd; 3169 struct sk_buff *skb; 3170 int ret, len; 3171 3172 len = sizeof(*cmd); 3173 3174 skb = ath11k_wmi_alloc_skb(wmi->wmi_ab, len); 3175 if (!skb) 3176 return -ENOMEM; 3177 3178 cmd = (struct wmi_pdev_obss_pd_bitmap_cmd *)skb->data; 3179 cmd->tlv_header = 3180 FIELD_PREP(WMI_TLV_TAG, 3181 WMI_TAG_PDEV_NON_SRG_OBSS_BSSID_ENABLE_BITMAP_CMD) | 3182 FIELD_PREP(WMI_TLV_LEN, len - TLV_HDR_SIZE); 3183 cmd->pdev_id = ar->pdev->pdev_id; 3184 memcpy(cmd->bitmap, bitmap, sizeof(cmd->bitmap)); 3185 3186 ath11k_dbg(ar->ab, ATH11K_DBG_WMI, 3187 "obss pd non_srg pdev_id %d bssid enable bitmap %08x %08x\n", 3188 cmd->pdev_id, cmd->bitmap[0], cmd->bitmap[1]); 3189 3190 ret = ath11k_wmi_cmd_send(wmi, skb, 3191 WMI_PDEV_SET_NON_SRG_OBSS_BSSID_ENABLE_BITMAP_CMDID); 3192 if (ret) { 3193 ath11k_warn(ab, 3194 "failed to send WMI_PDEV_SET_NON_SRG_OBSS_BSSID_ENABLE_BITMAP_CMDID"); 3195 dev_kfree_skb(skb); 3196 } 3197 3198 return ret; 3199 } 3200 3201 int 3202 ath11k_wmi_send_obss_color_collision_cfg_cmd(struct ath11k *ar, u32 vdev_id, 3203 u8 bss_color, u32 period, 3204 bool enable) 3205 { 3206 struct ath11k_pdev_wmi *wmi = ar->wmi; 3207 struct ath11k_base *ab = wmi->wmi_ab->ab; 3208 struct wmi_obss_color_collision_cfg_params_cmd *cmd; 3209 struct sk_buff *skb; 3210 int ret, len; 3211 3212 len = sizeof(*cmd); 3213 3214 skb = ath11k_wmi_alloc_skb(wmi->wmi_ab, len); 3215 if (!skb) 3216 return -ENOMEM; 3217 3218 cmd = (struct wmi_obss_color_collision_cfg_params_cmd *)skb->data; 3219 cmd->tlv_header = FIELD_PREP(WMI_TLV_TAG, 3220 WMI_TAG_OBSS_COLOR_COLLISION_DET_CONFIG) | 3221 FIELD_PREP(WMI_TLV_LEN, len - TLV_HDR_SIZE); 3222 cmd->vdev_id = vdev_id; 3223 cmd->evt_type = enable ? ATH11K_OBSS_COLOR_COLLISION_DETECTION : 3224 ATH11K_OBSS_COLOR_COLLISION_DETECTION_DISABLE; 3225 cmd->current_bss_color = bss_color; 3226 cmd->detection_period_ms = period; 3227 cmd->scan_period_ms = ATH11K_BSS_COLOR_COLLISION_SCAN_PERIOD_MS; 3228 cmd->free_slot_expiry_time_ms = 0; 3229 cmd->flags = 0; 3230 3231 ath11k_dbg(ar->ab, ATH11K_DBG_WMI, 3232 "wmi_send_obss_color_collision_cfg id %d type %d bss_color %d detect_period %d scan_period %d\n", 3233 cmd->vdev_id, cmd->evt_type, cmd->current_bss_color, 3234 cmd->detection_period_ms, cmd->scan_period_ms); 3235 3236 ret = ath11k_wmi_cmd_send(wmi, skb, 3237 WMI_OBSS_COLOR_COLLISION_DET_CONFIG_CMDID); 3238 if (ret) { 3239 ath11k_warn(ab, "Failed to send WMI_OBSS_COLOR_COLLISION_DET_CONFIG_CMDID"); 3240 dev_kfree_skb(skb); 3241 } 3242 return ret; 3243 } 3244 3245 int ath11k_wmi_send_bss_color_change_enable_cmd(struct ath11k *ar, u32 vdev_id, 3246 bool enable) 3247 { 3248 struct ath11k_pdev_wmi *wmi = ar->wmi; 3249 struct ath11k_base *ab = wmi->wmi_ab->ab; 3250 struct wmi_bss_color_change_enable_params_cmd *cmd; 3251 struct sk_buff *skb; 3252 int ret, len; 3253 3254 len = sizeof(*cmd); 3255 3256 skb = ath11k_wmi_alloc_skb(wmi->wmi_ab, len); 3257 if (!skb) 3258 return -ENOMEM; 3259 3260 cmd = (struct wmi_bss_color_change_enable_params_cmd *)skb->data; 3261 cmd->tlv_header = FIELD_PREP(WMI_TLV_TAG, WMI_TAG_BSS_COLOR_CHANGE_ENABLE) | 3262 FIELD_PREP(WMI_TLV_LEN, len - TLV_HDR_SIZE); 3263 cmd->vdev_id = vdev_id; 3264 cmd->enable = enable ? 1 : 0; 3265 3266 ath11k_dbg(ar->ab, ATH11K_DBG_WMI, 3267 "wmi_send_bss_color_change_enable id %d enable %d\n", 3268 cmd->vdev_id, cmd->enable); 3269 3270 ret = ath11k_wmi_cmd_send(wmi, skb, 3271 WMI_BSS_COLOR_CHANGE_ENABLE_CMDID); 3272 if (ret) { 3273 ath11k_warn(ab, "Failed to send WMI_BSS_COLOR_CHANGE_ENABLE_CMDID"); 3274 dev_kfree_skb(skb); 3275 } 3276 return ret; 3277 } 3278 3279 int ath11k_wmi_fils_discovery_tmpl(struct ath11k *ar, u32 vdev_id, 3280 struct sk_buff *tmpl) 3281 { 3282 struct wmi_tlv *tlv; 3283 struct sk_buff *skb; 3284 void *ptr; 3285 int ret, len; 3286 size_t aligned_len; 3287 struct wmi_fils_discovery_tmpl_cmd *cmd; 3288 3289 aligned_len = roundup(tmpl->len, 4); 3290 len = sizeof(*cmd) + TLV_HDR_SIZE + aligned_len; 3291 3292 ath11k_dbg(ar->ab, ATH11K_DBG_WMI, 3293 "WMI vdev %i set FILS discovery template\n", vdev_id); 3294 3295 skb = ath11k_wmi_alloc_skb(ar->wmi->wmi_ab, len); 3296 if (!skb) 3297 return -ENOMEM; 3298 3299 cmd = (struct wmi_fils_discovery_tmpl_cmd *)skb->data; 3300 cmd->tlv_header = FIELD_PREP(WMI_TLV_TAG, 3301 WMI_TAG_FILS_DISCOVERY_TMPL_CMD) | 3302 FIELD_PREP(WMI_TLV_LEN, sizeof(*cmd) - TLV_HDR_SIZE); 3303 cmd->vdev_id = vdev_id; 3304 cmd->buf_len = tmpl->len; 3305 ptr = skb->data + sizeof(*cmd); 3306 3307 tlv = ptr; 3308 tlv->header = FIELD_PREP(WMI_TLV_TAG, WMI_TAG_ARRAY_BYTE) | 3309 FIELD_PREP(WMI_TLV_LEN, aligned_len); 3310 memcpy(tlv->value, tmpl->data, tmpl->len); 3311 3312 ret = ath11k_wmi_cmd_send(ar->wmi, skb, WMI_FILS_DISCOVERY_TMPL_CMDID); 3313 if (ret) { 3314 ath11k_warn(ar->ab, 3315 "WMI vdev %i failed to send FILS discovery template command\n", 3316 vdev_id); 3317 dev_kfree_skb(skb); 3318 } 3319 return ret; 3320 } 3321 3322 int ath11k_wmi_probe_resp_tmpl(struct ath11k *ar, u32 vdev_id, 3323 struct sk_buff *tmpl) 3324 { 3325 struct wmi_probe_tmpl_cmd *cmd; 3326 struct wmi_bcn_prb_info *probe_info; 3327 struct wmi_tlv *tlv; 3328 struct sk_buff *skb; 3329 void *ptr; 3330 int ret, len; 3331 size_t aligned_len = roundup(tmpl->len, 4); 3332 3333 ath11k_dbg(ar->ab, ATH11K_DBG_WMI, 3334 "WMI vdev %i set probe response template\n", vdev_id); 3335 3336 len = sizeof(*cmd) + sizeof(*probe_info) + TLV_HDR_SIZE + aligned_len; 3337 3338 skb = ath11k_wmi_alloc_skb(ar->wmi->wmi_ab, len); 3339 if (!skb) 3340 return -ENOMEM; 3341 3342 cmd = (struct wmi_probe_tmpl_cmd *)skb->data; 3343 cmd->tlv_header = FIELD_PREP(WMI_TLV_TAG, WMI_TAG_PRB_TMPL_CMD) | 3344 FIELD_PREP(WMI_TLV_LEN, sizeof(*cmd) - TLV_HDR_SIZE); 3345 cmd->vdev_id = vdev_id; 3346 cmd->buf_len = tmpl->len; 3347 3348 ptr = skb->data + sizeof(*cmd); 3349 3350 probe_info = ptr; 3351 len = sizeof(*probe_info); 3352 probe_info->tlv_header = FIELD_PREP(WMI_TLV_TAG, 3353 WMI_TAG_BCN_PRB_INFO) | 3354 FIELD_PREP(WMI_TLV_LEN, len - TLV_HDR_SIZE); 3355 probe_info->caps = 0; 3356 probe_info->erp = 0; 3357 3358 ptr += sizeof(*probe_info); 3359 3360 tlv = ptr; 3361 tlv->header = FIELD_PREP(WMI_TLV_TAG, WMI_TAG_ARRAY_BYTE) | 3362 FIELD_PREP(WMI_TLV_LEN, aligned_len); 3363 memcpy(tlv->value, tmpl->data, tmpl->len); 3364 3365 ret = ath11k_wmi_cmd_send(ar->wmi, skb, WMI_PRB_TMPL_CMDID); 3366 if (ret) { 3367 ath11k_warn(ar->ab, 3368 "WMI vdev %i failed to send probe response template command\n", 3369 vdev_id); 3370 dev_kfree_skb(skb); 3371 } 3372 return ret; 3373 } 3374 3375 int ath11k_wmi_fils_discovery(struct ath11k *ar, u32 vdev_id, u32 interval, 3376 bool unsol_bcast_probe_resp_enabled) 3377 { 3378 struct sk_buff *skb; 3379 int ret, len; 3380 struct wmi_fils_discovery_cmd *cmd; 3381 3382 ath11k_dbg(ar->ab, ATH11K_DBG_WMI, 3383 "WMI vdev %i set %s interval to %u TU\n", 3384 vdev_id, unsol_bcast_probe_resp_enabled ? 3385 "unsolicited broadcast probe response" : "FILS discovery", 3386 interval); 3387 3388 len = sizeof(*cmd); 3389 skb = ath11k_wmi_alloc_skb(ar->wmi->wmi_ab, len); 3390 if (!skb) 3391 return -ENOMEM; 3392 3393 cmd = (struct wmi_fils_discovery_cmd *)skb->data; 3394 cmd->tlv_header = FIELD_PREP(WMI_TLV_TAG, WMI_TAG_ENABLE_FILS_CMD) | 3395 FIELD_PREP(WMI_TLV_LEN, len - TLV_HDR_SIZE); 3396 cmd->vdev_id = vdev_id; 3397 cmd->interval = interval; 3398 cmd->config = unsol_bcast_probe_resp_enabled; 3399 3400 ret = ath11k_wmi_cmd_send(ar->wmi, skb, WMI_ENABLE_FILS_CMDID); 3401 if (ret) { 3402 ath11k_warn(ar->ab, 3403 "WMI vdev %i failed to send FILS discovery enable/disable command\n", 3404 vdev_id); 3405 dev_kfree_skb(skb); 3406 } 3407 return ret; 3408 } 3409 3410 static void 3411 ath11k_fill_band_to_mac_param(struct ath11k_base *soc, 3412 struct wmi_host_pdev_band_to_mac *band_to_mac) 3413 { 3414 u8 i; 3415 struct ath11k_hal_reg_capabilities_ext *hal_reg_cap; 3416 struct ath11k_pdev *pdev; 3417 3418 for (i = 0; i < soc->num_radios; i++) { 3419 pdev = &soc->pdevs[i]; 3420 hal_reg_cap = &soc->hal_reg_cap[i]; 3421 band_to_mac[i].pdev_id = pdev->pdev_id; 3422 3423 switch (pdev->cap.supported_bands) { 3424 case WMI_HOST_WLAN_2G_5G_CAP: 3425 band_to_mac[i].start_freq = hal_reg_cap->low_2ghz_chan; 3426 band_to_mac[i].end_freq = hal_reg_cap->high_5ghz_chan; 3427 break; 3428 case WMI_HOST_WLAN_2G_CAP: 3429 band_to_mac[i].start_freq = hal_reg_cap->low_2ghz_chan; 3430 band_to_mac[i].end_freq = hal_reg_cap->high_2ghz_chan; 3431 break; 3432 case WMI_HOST_WLAN_5G_CAP: 3433 band_to_mac[i].start_freq = hal_reg_cap->low_5ghz_chan; 3434 band_to_mac[i].end_freq = hal_reg_cap->high_5ghz_chan; 3435 break; 3436 default: 3437 break; 3438 } 3439 } 3440 } 3441 3442 static void 3443 ath11k_wmi_copy_resource_config(struct wmi_resource_config *wmi_cfg, 3444 struct target_resource_config *tg_cfg) 3445 { 3446 wmi_cfg->num_vdevs = tg_cfg->num_vdevs; 3447 wmi_cfg->num_peers = tg_cfg->num_peers; 3448 wmi_cfg->num_offload_peers = tg_cfg->num_offload_peers; 3449 wmi_cfg->num_offload_reorder_buffs = tg_cfg->num_offload_reorder_buffs; 3450 wmi_cfg->num_peer_keys = tg_cfg->num_peer_keys; 3451 wmi_cfg->num_tids = tg_cfg->num_tids; 3452 wmi_cfg->ast_skid_limit = tg_cfg->ast_skid_limit; 3453 wmi_cfg->tx_chain_mask = tg_cfg->tx_chain_mask; 3454 wmi_cfg->rx_chain_mask = tg_cfg->rx_chain_mask; 3455 wmi_cfg->rx_timeout_pri[0] = tg_cfg->rx_timeout_pri[0]; 3456 wmi_cfg->rx_timeout_pri[1] = tg_cfg->rx_timeout_pri[1]; 3457 wmi_cfg->rx_timeout_pri[2] = tg_cfg->rx_timeout_pri[2]; 3458 wmi_cfg->rx_timeout_pri[3] = tg_cfg->rx_timeout_pri[3]; 3459 wmi_cfg->rx_decap_mode = tg_cfg->rx_decap_mode; 3460 wmi_cfg->scan_max_pending_req = tg_cfg->scan_max_pending_req; 3461 wmi_cfg->bmiss_offload_max_vdev = tg_cfg->bmiss_offload_max_vdev; 3462 wmi_cfg->roam_offload_max_vdev = tg_cfg->roam_offload_max_vdev; 3463 wmi_cfg->roam_offload_max_ap_profiles = 3464 tg_cfg->roam_offload_max_ap_profiles; 3465 wmi_cfg->num_mcast_groups = tg_cfg->num_mcast_groups; 3466 wmi_cfg->num_mcast_table_elems = tg_cfg->num_mcast_table_elems; 3467 wmi_cfg->mcast2ucast_mode = tg_cfg->mcast2ucast_mode; 3468 wmi_cfg->tx_dbg_log_size = tg_cfg->tx_dbg_log_size; 3469 wmi_cfg->num_wds_entries = tg_cfg->num_wds_entries; 3470 wmi_cfg->dma_burst_size = tg_cfg->dma_burst_size; 3471 wmi_cfg->mac_aggr_delim = tg_cfg->mac_aggr_delim; 3472 wmi_cfg->rx_skip_defrag_timeout_dup_detection_check = 3473 tg_cfg->rx_skip_defrag_timeout_dup_detection_check; 3474 wmi_cfg->vow_config = tg_cfg->vow_config; 3475 wmi_cfg->gtk_offload_max_vdev = tg_cfg->gtk_offload_max_vdev; 3476 wmi_cfg->num_msdu_desc = tg_cfg->num_msdu_desc; 3477 wmi_cfg->max_frag_entries = tg_cfg->max_frag_entries; 3478 wmi_cfg->num_tdls_vdevs = tg_cfg->num_tdls_vdevs; 3479 wmi_cfg->num_tdls_conn_table_entries = 3480 tg_cfg->num_tdls_conn_table_entries; 3481 wmi_cfg->beacon_tx_offload_max_vdev = 3482 tg_cfg->beacon_tx_offload_max_vdev; 3483 wmi_cfg->num_multicast_filter_entries = 3484 tg_cfg->num_multicast_filter_entries; 3485 wmi_cfg->num_wow_filters = tg_cfg->num_wow_filters; 3486 wmi_cfg->num_keep_alive_pattern = tg_cfg->num_keep_alive_pattern; 3487 wmi_cfg->keep_alive_pattern_size = tg_cfg->keep_alive_pattern_size; 3488 wmi_cfg->max_tdls_concurrent_sleep_sta = 3489 tg_cfg->max_tdls_concurrent_sleep_sta; 3490 wmi_cfg->max_tdls_concurrent_buffer_sta = 3491 tg_cfg->max_tdls_concurrent_buffer_sta; 3492 wmi_cfg->wmi_send_separate = tg_cfg->wmi_send_separate; 3493 wmi_cfg->num_ocb_vdevs = tg_cfg->num_ocb_vdevs; 3494 wmi_cfg->num_ocb_channels = tg_cfg->num_ocb_channels; 3495 wmi_cfg->num_ocb_schedules = tg_cfg->num_ocb_schedules; 3496 wmi_cfg->bpf_instruction_size = tg_cfg->bpf_instruction_size; 3497 wmi_cfg->max_bssid_rx_filters = tg_cfg->max_bssid_rx_filters; 3498 wmi_cfg->use_pdev_id = tg_cfg->use_pdev_id; 3499 wmi_cfg->flag1 = tg_cfg->flag1; 3500 wmi_cfg->peer_map_unmap_v2_support = tg_cfg->peer_map_unmap_v2_support; 3501 wmi_cfg->sched_params = tg_cfg->sched_params; 3502 wmi_cfg->twt_ap_pdev_count = tg_cfg->twt_ap_pdev_count; 3503 wmi_cfg->twt_ap_sta_count = tg_cfg->twt_ap_sta_count; 3504 } 3505 3506 static int ath11k_init_cmd_send(struct ath11k_pdev_wmi *wmi, 3507 struct wmi_init_cmd_param *param) 3508 { 3509 struct ath11k_base *ab = wmi->wmi_ab->ab; 3510 struct sk_buff *skb; 3511 struct wmi_init_cmd *cmd; 3512 struct wmi_resource_config *cfg; 3513 struct wmi_pdev_set_hw_mode_cmd_param *hw_mode; 3514 struct wmi_pdev_band_to_mac *band_to_mac; 3515 struct wlan_host_mem_chunk *host_mem_chunks; 3516 struct wmi_tlv *tlv; 3517 size_t ret, len; 3518 void *ptr; 3519 u32 hw_mode_len = 0; 3520 u16 idx; 3521 3522 if (param->hw_mode_id != WMI_HOST_HW_MODE_MAX) 3523 hw_mode_len = sizeof(*hw_mode) + TLV_HDR_SIZE + 3524 (param->num_band_to_mac * sizeof(*band_to_mac)); 3525 3526 len = sizeof(*cmd) + TLV_HDR_SIZE + sizeof(*cfg) + hw_mode_len + 3527 (param->num_mem_chunks ? (sizeof(*host_mem_chunks) * WMI_MAX_MEM_REQS) : 0); 3528 3529 skb = ath11k_wmi_alloc_skb(wmi->wmi_ab, len); 3530 if (!skb) 3531 return -ENOMEM; 3532 3533 cmd = (struct wmi_init_cmd *)skb->data; 3534 3535 cmd->tlv_header = FIELD_PREP(WMI_TLV_TAG, WMI_TAG_INIT_CMD) | 3536 FIELD_PREP(WMI_TLV_LEN, sizeof(*cmd) - TLV_HDR_SIZE); 3537 3538 ptr = skb->data + sizeof(*cmd); 3539 cfg = ptr; 3540 3541 ath11k_wmi_copy_resource_config(cfg, param->res_cfg); 3542 3543 cfg->tlv_header = FIELD_PREP(WMI_TLV_TAG, WMI_TAG_RESOURCE_CONFIG) | 3544 FIELD_PREP(WMI_TLV_LEN, sizeof(*cfg) - TLV_HDR_SIZE); 3545 3546 ptr += sizeof(*cfg); 3547 host_mem_chunks = ptr + TLV_HDR_SIZE; 3548 len = sizeof(struct wlan_host_mem_chunk); 3549 3550 for (idx = 0; idx < param->num_mem_chunks; ++idx) { 3551 host_mem_chunks[idx].tlv_header = 3552 FIELD_PREP(WMI_TLV_TAG, 3553 WMI_TAG_WLAN_HOST_MEMORY_CHUNK) | 3554 FIELD_PREP(WMI_TLV_LEN, len); 3555 3556 host_mem_chunks[idx].ptr = param->mem_chunks[idx].paddr; 3557 host_mem_chunks[idx].size = param->mem_chunks[idx].len; 3558 host_mem_chunks[idx].req_id = param->mem_chunks[idx].req_id; 3559 3560 ath11k_dbg(ab, ATH11K_DBG_WMI, 3561 "WMI host mem chunk req_id %d paddr 0x%llx len %d\n", 3562 param->mem_chunks[idx].req_id, 3563 (u64)param->mem_chunks[idx].paddr, 3564 param->mem_chunks[idx].len); 3565 } 3566 cmd->num_host_mem_chunks = param->num_mem_chunks; 3567 len = sizeof(struct wlan_host_mem_chunk) * param->num_mem_chunks; 3568 3569 /* num_mem_chunks is zero */ 3570 tlv = ptr; 3571 tlv->header = FIELD_PREP(WMI_TLV_TAG, WMI_TAG_ARRAY_STRUCT) | 3572 FIELD_PREP(WMI_TLV_LEN, len); 3573 ptr += TLV_HDR_SIZE + len; 3574 3575 if (param->hw_mode_id != WMI_HOST_HW_MODE_MAX) { 3576 hw_mode = (struct wmi_pdev_set_hw_mode_cmd_param *)ptr; 3577 hw_mode->tlv_header = FIELD_PREP(WMI_TLV_TAG, 3578 WMI_TAG_PDEV_SET_HW_MODE_CMD) | 3579 FIELD_PREP(WMI_TLV_LEN, 3580 sizeof(*hw_mode) - TLV_HDR_SIZE); 3581 3582 hw_mode->hw_mode_index = param->hw_mode_id; 3583 hw_mode->num_band_to_mac = param->num_band_to_mac; 3584 3585 ptr += sizeof(*hw_mode); 3586 3587 len = param->num_band_to_mac * sizeof(*band_to_mac); 3588 tlv = ptr; 3589 tlv->header = FIELD_PREP(WMI_TLV_TAG, WMI_TAG_ARRAY_STRUCT) | 3590 FIELD_PREP(WMI_TLV_LEN, len); 3591 3592 ptr += TLV_HDR_SIZE; 3593 len = sizeof(*band_to_mac); 3594 3595 for (idx = 0; idx < param->num_band_to_mac; idx++) { 3596 band_to_mac = (void *)ptr; 3597 3598 band_to_mac->tlv_header = FIELD_PREP(WMI_TLV_TAG, 3599 WMI_TAG_PDEV_BAND_TO_MAC) | 3600 FIELD_PREP(WMI_TLV_LEN, 3601 len - TLV_HDR_SIZE); 3602 band_to_mac->pdev_id = param->band_to_mac[idx].pdev_id; 3603 band_to_mac->start_freq = 3604 param->band_to_mac[idx].start_freq; 3605 band_to_mac->end_freq = 3606 param->band_to_mac[idx].end_freq; 3607 ptr += sizeof(*band_to_mac); 3608 } 3609 } 3610 3611 ret = ath11k_wmi_cmd_send(wmi, skb, WMI_INIT_CMDID); 3612 if (ret) { 3613 ath11k_warn(ab, "failed to send WMI_INIT_CMDID\n"); 3614 dev_kfree_skb(skb); 3615 } 3616 3617 return ret; 3618 } 3619 3620 int ath11k_wmi_pdev_lro_cfg(struct ath11k *ar, 3621 int pdev_id) 3622 { 3623 struct ath11k_wmi_pdev_lro_config_cmd *cmd; 3624 struct sk_buff *skb; 3625 int ret; 3626 3627 skb = ath11k_wmi_alloc_skb(ar->wmi->wmi_ab, sizeof(*cmd)); 3628 if (!skb) 3629 return -ENOMEM; 3630 3631 cmd = (struct ath11k_wmi_pdev_lro_config_cmd *)skb->data; 3632 cmd->tlv_header = FIELD_PREP(WMI_TLV_TAG, WMI_TAG_LRO_INFO_CMD) | 3633 FIELD_PREP(WMI_TLV_LEN, sizeof(*cmd) - TLV_HDR_SIZE); 3634 3635 get_random_bytes(cmd->th_4, sizeof(uint32_t) * ATH11K_IPV4_TH_SEED_SIZE); 3636 get_random_bytes(cmd->th_6, sizeof(uint32_t) * ATH11K_IPV6_TH_SEED_SIZE); 3637 3638 cmd->pdev_id = pdev_id; 3639 3640 ret = ath11k_wmi_cmd_send(ar->wmi, skb, WMI_LRO_CONFIG_CMDID); 3641 if (ret) { 3642 ath11k_warn(ar->ab, 3643 "failed to send lro cfg req wmi cmd\n"); 3644 goto err; 3645 } 3646 3647 ath11k_dbg(ar->ab, ATH11K_DBG_WMI, 3648 "WMI lro cfg cmd pdev_id 0x%x\n", pdev_id); 3649 return 0; 3650 err: 3651 dev_kfree_skb(skb); 3652 return ret; 3653 } 3654 3655 int ath11k_wmi_wait_for_service_ready(struct ath11k_base *ab) 3656 { 3657 unsigned long time_left; 3658 3659 time_left = wait_for_completion_timeout(&ab->wmi_ab.service_ready, 3660 WMI_SERVICE_READY_TIMEOUT_HZ); 3661 if (!time_left) 3662 return -ETIMEDOUT; 3663 3664 return 0; 3665 } 3666 3667 int ath11k_wmi_wait_for_unified_ready(struct ath11k_base *ab) 3668 { 3669 unsigned long time_left; 3670 3671 time_left = wait_for_completion_timeout(&ab->wmi_ab.unified_ready, 3672 WMI_SERVICE_READY_TIMEOUT_HZ); 3673 if (!time_left) 3674 return -ETIMEDOUT; 3675 3676 return 0; 3677 } 3678 3679 int ath11k_wmi_set_hw_mode(struct ath11k_base *ab, 3680 enum wmi_host_hw_mode_config_type mode) 3681 { 3682 struct wmi_pdev_set_hw_mode_cmd_param *cmd; 3683 struct sk_buff *skb; 3684 struct ath11k_wmi_base *wmi_ab = &ab->wmi_ab; 3685 int len; 3686 int ret; 3687 3688 len = sizeof(*cmd); 3689 3690 skb = ath11k_wmi_alloc_skb(wmi_ab, len); 3691 if (!skb) 3692 return -ENOMEM; 3693 3694 cmd = (struct wmi_pdev_set_hw_mode_cmd_param *)skb->data; 3695 3696 cmd->tlv_header = FIELD_PREP(WMI_TLV_TAG, WMI_TAG_PDEV_SET_HW_MODE_CMD) | 3697 FIELD_PREP(WMI_TLV_LEN, sizeof(*cmd) - TLV_HDR_SIZE); 3698 3699 cmd->pdev_id = WMI_PDEV_ID_SOC; 3700 cmd->hw_mode_index = mode; 3701 3702 ret = ath11k_wmi_cmd_send(&wmi_ab->wmi[0], skb, WMI_PDEV_SET_HW_MODE_CMDID); 3703 if (ret) { 3704 ath11k_warn(ab, "failed to send WMI_PDEV_SET_HW_MODE_CMDID\n"); 3705 dev_kfree_skb(skb); 3706 } 3707 3708 return ret; 3709 } 3710 3711 int ath11k_wmi_cmd_init(struct ath11k_base *ab) 3712 { 3713 struct ath11k_wmi_base *wmi_sc = &ab->wmi_ab; 3714 struct wmi_init_cmd_param init_param; 3715 struct target_resource_config config; 3716 3717 memset(&init_param, 0, sizeof(init_param)); 3718 memset(&config, 0, sizeof(config)); 3719 3720 ab->hw_params.hw_ops->wmi_init_config(ab, &config); 3721 3722 memcpy(&wmi_sc->wlan_resource_config, &config, sizeof(config)); 3723 3724 init_param.res_cfg = &wmi_sc->wlan_resource_config; 3725 init_param.num_mem_chunks = wmi_sc->num_mem_chunks; 3726 init_param.hw_mode_id = wmi_sc->preferred_hw_mode; 3727 init_param.mem_chunks = wmi_sc->mem_chunks; 3728 3729 if (ab->hw_params.single_pdev_only) 3730 init_param.hw_mode_id = WMI_HOST_HW_MODE_MAX; 3731 3732 init_param.num_band_to_mac = ab->num_radios; 3733 ath11k_fill_band_to_mac_param(ab, init_param.band_to_mac); 3734 3735 return ath11k_init_cmd_send(&wmi_sc->wmi[0], &init_param); 3736 } 3737 3738 int ath11k_wmi_vdev_spectral_conf(struct ath11k *ar, 3739 struct ath11k_wmi_vdev_spectral_conf_param *param) 3740 { 3741 struct ath11k_wmi_vdev_spectral_conf_cmd *cmd; 3742 struct sk_buff *skb; 3743 int ret; 3744 3745 skb = ath11k_wmi_alloc_skb(ar->wmi->wmi_ab, sizeof(*cmd)); 3746 if (!skb) 3747 return -ENOMEM; 3748 3749 cmd = (struct ath11k_wmi_vdev_spectral_conf_cmd *)skb->data; 3750 cmd->tlv_header = FIELD_PREP(WMI_TLV_TAG, 3751 WMI_TAG_VDEV_SPECTRAL_CONFIGURE_CMD) | 3752 FIELD_PREP(WMI_TLV_LEN, sizeof(*cmd) - TLV_HDR_SIZE); 3753 3754 memcpy(&cmd->param, param, sizeof(*param)); 3755 3756 ret = ath11k_wmi_cmd_send(ar->wmi, skb, 3757 WMI_VDEV_SPECTRAL_SCAN_CONFIGURE_CMDID); 3758 if (ret) { 3759 ath11k_warn(ar->ab, 3760 "failed to send spectral scan config wmi cmd\n"); 3761 goto err; 3762 } 3763 3764 ath11k_dbg(ar->ab, ATH11K_DBG_WMI, 3765 "WMI spectral scan config cmd vdev_id 0x%x\n", 3766 param->vdev_id); 3767 3768 return 0; 3769 err: 3770 dev_kfree_skb(skb); 3771 return ret; 3772 } 3773 3774 int ath11k_wmi_vdev_spectral_enable(struct ath11k *ar, u32 vdev_id, 3775 u32 trigger, u32 enable) 3776 { 3777 struct ath11k_wmi_vdev_spectral_enable_cmd *cmd; 3778 struct sk_buff *skb; 3779 int ret; 3780 3781 skb = ath11k_wmi_alloc_skb(ar->wmi->wmi_ab, sizeof(*cmd)); 3782 if (!skb) 3783 return -ENOMEM; 3784 3785 cmd = (struct ath11k_wmi_vdev_spectral_enable_cmd *)skb->data; 3786 cmd->tlv_header = FIELD_PREP(WMI_TLV_TAG, 3787 WMI_TAG_VDEV_SPECTRAL_ENABLE_CMD) | 3788 FIELD_PREP(WMI_TLV_LEN, sizeof(*cmd) - TLV_HDR_SIZE); 3789 3790 cmd->vdev_id = vdev_id; 3791 cmd->trigger_cmd = trigger; 3792 cmd->enable_cmd = enable; 3793 3794 ret = ath11k_wmi_cmd_send(ar->wmi, skb, 3795 WMI_VDEV_SPECTRAL_SCAN_ENABLE_CMDID); 3796 if (ret) { 3797 ath11k_warn(ar->ab, 3798 "failed to send spectral enable wmi cmd\n"); 3799 goto err; 3800 } 3801 3802 ath11k_dbg(ar->ab, ATH11K_DBG_WMI, 3803 "WMI spectral enable cmd vdev id 0x%x\n", 3804 vdev_id); 3805 3806 return 0; 3807 err: 3808 dev_kfree_skb(skb); 3809 return ret; 3810 } 3811 3812 int ath11k_wmi_pdev_dma_ring_cfg(struct ath11k *ar, 3813 struct ath11k_wmi_pdev_dma_ring_cfg_req_cmd *param) 3814 { 3815 struct ath11k_wmi_pdev_dma_ring_cfg_req_cmd *cmd; 3816 struct sk_buff *skb; 3817 int ret; 3818 3819 skb = ath11k_wmi_alloc_skb(ar->wmi->wmi_ab, sizeof(*cmd)); 3820 if (!skb) 3821 return -ENOMEM; 3822 3823 cmd = (struct ath11k_wmi_pdev_dma_ring_cfg_req_cmd *)skb->data; 3824 cmd->tlv_header = FIELD_PREP(WMI_TLV_TAG, WMI_TAG_DMA_RING_CFG_REQ) | 3825 FIELD_PREP(WMI_TLV_LEN, sizeof(*cmd) - TLV_HDR_SIZE); 3826 3827 cmd->pdev_id = param->pdev_id; 3828 cmd->module_id = param->module_id; 3829 cmd->base_paddr_lo = param->base_paddr_lo; 3830 cmd->base_paddr_hi = param->base_paddr_hi; 3831 cmd->head_idx_paddr_lo = param->head_idx_paddr_lo; 3832 cmd->head_idx_paddr_hi = param->head_idx_paddr_hi; 3833 cmd->tail_idx_paddr_lo = param->tail_idx_paddr_lo; 3834 cmd->tail_idx_paddr_hi = param->tail_idx_paddr_hi; 3835 cmd->num_elems = param->num_elems; 3836 cmd->buf_size = param->buf_size; 3837 cmd->num_resp_per_event = param->num_resp_per_event; 3838 cmd->event_timeout_ms = param->event_timeout_ms; 3839 3840 ret = ath11k_wmi_cmd_send(ar->wmi, skb, 3841 WMI_PDEV_DMA_RING_CFG_REQ_CMDID); 3842 if (ret) { 3843 ath11k_warn(ar->ab, 3844 "failed to send dma ring cfg req wmi cmd\n"); 3845 goto err; 3846 } 3847 3848 ath11k_dbg(ar->ab, ATH11K_DBG_WMI, 3849 "WMI DMA ring cfg req cmd pdev_id 0x%x\n", 3850 param->pdev_id); 3851 3852 return 0; 3853 err: 3854 dev_kfree_skb(skb); 3855 return ret; 3856 } 3857 3858 static int ath11k_wmi_tlv_dma_buf_entry_parse(struct ath11k_base *soc, 3859 u16 tag, u16 len, 3860 const void *ptr, void *data) 3861 { 3862 struct wmi_tlv_dma_buf_release_parse *parse = data; 3863 3864 if (tag != WMI_TAG_DMA_BUF_RELEASE_ENTRY) 3865 return -EPROTO; 3866 3867 if (parse->num_buf_entry >= parse->fixed.num_buf_release_entry) 3868 return -ENOBUFS; 3869 3870 parse->num_buf_entry++; 3871 return 0; 3872 } 3873 3874 static int ath11k_wmi_tlv_dma_buf_meta_parse(struct ath11k_base *soc, 3875 u16 tag, u16 len, 3876 const void *ptr, void *data) 3877 { 3878 struct wmi_tlv_dma_buf_release_parse *parse = data; 3879 3880 if (tag != WMI_TAG_DMA_BUF_RELEASE_SPECTRAL_META_DATA) 3881 return -EPROTO; 3882 3883 if (parse->num_meta >= parse->fixed.num_meta_data_entry) 3884 return -ENOBUFS; 3885 3886 parse->num_meta++; 3887 return 0; 3888 } 3889 3890 static int ath11k_wmi_tlv_dma_buf_parse(struct ath11k_base *ab, 3891 u16 tag, u16 len, 3892 const void *ptr, void *data) 3893 { 3894 struct wmi_tlv_dma_buf_release_parse *parse = data; 3895 int ret; 3896 3897 switch (tag) { 3898 case WMI_TAG_DMA_BUF_RELEASE: 3899 memcpy(&parse->fixed, ptr, 3900 sizeof(struct ath11k_wmi_dma_buf_release_fixed_param)); 3901 parse->fixed.pdev_id = DP_HW2SW_MACID(parse->fixed.pdev_id); 3902 break; 3903 case WMI_TAG_ARRAY_STRUCT: 3904 if (!parse->buf_entry_done) { 3905 parse->num_buf_entry = 0; 3906 parse->buf_entry = (struct wmi_dma_buf_release_entry *)ptr; 3907 3908 ret = ath11k_wmi_tlv_iter(ab, ptr, len, 3909 ath11k_wmi_tlv_dma_buf_entry_parse, 3910 parse); 3911 if (ret) { 3912 ath11k_warn(ab, "failed to parse dma buf entry tlv %d\n", 3913 ret); 3914 return ret; 3915 } 3916 3917 parse->buf_entry_done = true; 3918 } else if (!parse->meta_data_done) { 3919 parse->num_meta = 0; 3920 parse->meta_data = (struct wmi_dma_buf_release_meta_data *)ptr; 3921 3922 ret = ath11k_wmi_tlv_iter(ab, ptr, len, 3923 ath11k_wmi_tlv_dma_buf_meta_parse, 3924 parse); 3925 if (ret) { 3926 ath11k_warn(ab, "failed to parse dma buf meta tlv %d\n", 3927 ret); 3928 return ret; 3929 } 3930 3931 parse->meta_data_done = true; 3932 } 3933 break; 3934 default: 3935 break; 3936 } 3937 return 0; 3938 } 3939 3940 static void ath11k_wmi_pdev_dma_ring_buf_release_event(struct ath11k_base *ab, 3941 struct sk_buff *skb) 3942 { 3943 struct wmi_tlv_dma_buf_release_parse parse = { }; 3944 struct ath11k_dbring_buf_release_event param; 3945 int ret; 3946 3947 ret = ath11k_wmi_tlv_iter(ab, skb->data, skb->len, 3948 ath11k_wmi_tlv_dma_buf_parse, 3949 &parse); 3950 if (ret) { 3951 ath11k_warn(ab, "failed to parse dma buf release tlv %d\n", ret); 3952 return; 3953 } 3954 3955 param.fixed = parse.fixed; 3956 param.buf_entry = parse.buf_entry; 3957 param.num_buf_entry = parse.num_buf_entry; 3958 param.meta_data = parse.meta_data; 3959 param.num_meta = parse.num_meta; 3960 3961 ret = ath11k_dbring_buffer_release_event(ab, ¶m); 3962 if (ret) { 3963 ath11k_warn(ab, "failed to handle dma buf release event %d\n", ret); 3964 return; 3965 } 3966 } 3967 3968 static int ath11k_wmi_tlv_hw_mode_caps_parse(struct ath11k_base *soc, 3969 u16 tag, u16 len, 3970 const void *ptr, void *data) 3971 { 3972 struct wmi_tlv_svc_rdy_ext_parse *svc_rdy_ext = data; 3973 struct wmi_hw_mode_capabilities *hw_mode_cap; 3974 u32 phy_map = 0; 3975 3976 if (tag != WMI_TAG_HW_MODE_CAPABILITIES) 3977 return -EPROTO; 3978 3979 if (svc_rdy_ext->n_hw_mode_caps >= svc_rdy_ext->param.num_hw_modes) 3980 return -ENOBUFS; 3981 3982 hw_mode_cap = container_of(ptr, struct wmi_hw_mode_capabilities, 3983 hw_mode_id); 3984 svc_rdy_ext->n_hw_mode_caps++; 3985 3986 phy_map = hw_mode_cap->phy_id_map; 3987 while (phy_map) { 3988 svc_rdy_ext->tot_phy_id++; 3989 phy_map = phy_map >> 1; 3990 } 3991 3992 return 0; 3993 } 3994 3995 static int ath11k_wmi_tlv_hw_mode_caps(struct ath11k_base *soc, 3996 u16 len, const void *ptr, void *data) 3997 { 3998 struct wmi_tlv_svc_rdy_ext_parse *svc_rdy_ext = data; 3999 struct wmi_hw_mode_capabilities *hw_mode_caps; 4000 enum wmi_host_hw_mode_config_type mode, pref; 4001 u32 i; 4002 int ret; 4003 4004 svc_rdy_ext->n_hw_mode_caps = 0; 4005 svc_rdy_ext->hw_mode_caps = (struct wmi_hw_mode_capabilities *)ptr; 4006 4007 ret = ath11k_wmi_tlv_iter(soc, ptr, len, 4008 ath11k_wmi_tlv_hw_mode_caps_parse, 4009 svc_rdy_ext); 4010 if (ret) { 4011 ath11k_warn(soc, "failed to parse tlv %d\n", ret); 4012 return ret; 4013 } 4014 4015 i = 0; 4016 while (i < svc_rdy_ext->n_hw_mode_caps) { 4017 hw_mode_caps = &svc_rdy_ext->hw_mode_caps[i]; 4018 mode = hw_mode_caps->hw_mode_id; 4019 pref = soc->wmi_ab.preferred_hw_mode; 4020 4021 if (ath11k_hw_mode_pri_map[mode] < ath11k_hw_mode_pri_map[pref]) { 4022 svc_rdy_ext->pref_hw_mode_caps = *hw_mode_caps; 4023 soc->wmi_ab.preferred_hw_mode = mode; 4024 } 4025 i++; 4026 } 4027 4028 ath11k_dbg(soc, ATH11K_DBG_WMI, "preferred_hw_mode:%d\n", 4029 soc->wmi_ab.preferred_hw_mode); 4030 if (soc->wmi_ab.preferred_hw_mode == WMI_HOST_HW_MODE_MAX) 4031 return -EINVAL; 4032 4033 return 0; 4034 } 4035 4036 static int ath11k_wmi_tlv_mac_phy_caps_parse(struct ath11k_base *soc, 4037 u16 tag, u16 len, 4038 const void *ptr, void *data) 4039 { 4040 struct wmi_tlv_svc_rdy_ext_parse *svc_rdy_ext = data; 4041 4042 if (tag != WMI_TAG_MAC_PHY_CAPABILITIES) 4043 return -EPROTO; 4044 4045 if (svc_rdy_ext->n_mac_phy_caps >= svc_rdy_ext->tot_phy_id) 4046 return -ENOBUFS; 4047 4048 len = min_t(u16, len, sizeof(struct wmi_mac_phy_capabilities)); 4049 if (!svc_rdy_ext->n_mac_phy_caps) { 4050 svc_rdy_ext->mac_phy_caps = kzalloc((svc_rdy_ext->tot_phy_id) * len, 4051 GFP_ATOMIC); 4052 if (!svc_rdy_ext->mac_phy_caps) 4053 return -ENOMEM; 4054 } 4055 4056 memcpy(svc_rdy_ext->mac_phy_caps + svc_rdy_ext->n_mac_phy_caps, ptr, len); 4057 svc_rdy_ext->n_mac_phy_caps++; 4058 return 0; 4059 } 4060 4061 static int ath11k_wmi_tlv_ext_hal_reg_caps_parse(struct ath11k_base *soc, 4062 u16 tag, u16 len, 4063 const void *ptr, void *data) 4064 { 4065 struct wmi_tlv_svc_rdy_ext_parse *svc_rdy_ext = data; 4066 4067 if (tag != WMI_TAG_HAL_REG_CAPABILITIES_EXT) 4068 return -EPROTO; 4069 4070 if (svc_rdy_ext->n_ext_hal_reg_caps >= svc_rdy_ext->param.num_phy) 4071 return -ENOBUFS; 4072 4073 svc_rdy_ext->n_ext_hal_reg_caps++; 4074 return 0; 4075 } 4076 4077 static int ath11k_wmi_tlv_ext_hal_reg_caps(struct ath11k_base *soc, 4078 u16 len, const void *ptr, void *data) 4079 { 4080 struct ath11k_pdev_wmi *wmi_handle = &soc->wmi_ab.wmi[0]; 4081 struct wmi_tlv_svc_rdy_ext_parse *svc_rdy_ext = data; 4082 struct ath11k_hal_reg_capabilities_ext reg_cap; 4083 int ret; 4084 u32 i; 4085 4086 svc_rdy_ext->n_ext_hal_reg_caps = 0; 4087 svc_rdy_ext->ext_hal_reg_caps = (struct wmi_hal_reg_capabilities_ext *)ptr; 4088 ret = ath11k_wmi_tlv_iter(soc, ptr, len, 4089 ath11k_wmi_tlv_ext_hal_reg_caps_parse, 4090 svc_rdy_ext); 4091 if (ret) { 4092 ath11k_warn(soc, "failed to parse tlv %d\n", ret); 4093 return ret; 4094 } 4095 4096 for (i = 0; i < svc_rdy_ext->param.num_phy; i++) { 4097 ret = ath11k_pull_reg_cap_svc_rdy_ext(wmi_handle, 4098 svc_rdy_ext->soc_hal_reg_caps, 4099 svc_rdy_ext->ext_hal_reg_caps, i, 4100 ®_cap); 4101 if (ret) { 4102 ath11k_warn(soc, "failed to extract reg cap %d\n", i); 4103 return ret; 4104 } 4105 4106 memcpy(&soc->hal_reg_cap[reg_cap.phy_id], 4107 ®_cap, sizeof(reg_cap)); 4108 } 4109 return 0; 4110 } 4111 4112 static int ath11k_wmi_tlv_ext_soc_hal_reg_caps_parse(struct ath11k_base *soc, 4113 u16 len, const void *ptr, 4114 void *data) 4115 { 4116 struct ath11k_pdev_wmi *wmi_handle = &soc->wmi_ab.wmi[0]; 4117 struct wmi_tlv_svc_rdy_ext_parse *svc_rdy_ext = data; 4118 u8 hw_mode_id = svc_rdy_ext->pref_hw_mode_caps.hw_mode_id; 4119 u32 phy_id_map; 4120 int pdev_index = 0; 4121 int ret; 4122 4123 svc_rdy_ext->soc_hal_reg_caps = (struct wmi_soc_hal_reg_capabilities *)ptr; 4124 svc_rdy_ext->param.num_phy = svc_rdy_ext->soc_hal_reg_caps->num_phy; 4125 4126 soc->num_radios = 0; 4127 phy_id_map = svc_rdy_ext->pref_hw_mode_caps.phy_id_map; 4128 4129 while (phy_id_map && soc->num_radios < MAX_RADIOS) { 4130 ret = ath11k_pull_mac_phy_cap_svc_ready_ext(wmi_handle, 4131 svc_rdy_ext->hw_caps, 4132 svc_rdy_ext->hw_mode_caps, 4133 svc_rdy_ext->soc_hal_reg_caps, 4134 svc_rdy_ext->mac_phy_caps, 4135 hw_mode_id, soc->num_radios, 4136 &soc->pdevs[pdev_index]); 4137 if (ret) { 4138 ath11k_warn(soc, "failed to extract mac caps, idx :%d\n", 4139 soc->num_radios); 4140 return ret; 4141 } 4142 4143 soc->num_radios++; 4144 4145 /* For QCA6390, save mac_phy capability in the same pdev */ 4146 if (soc->hw_params.single_pdev_only) 4147 pdev_index = 0; 4148 else 4149 pdev_index = soc->num_radios; 4150 4151 /* TODO: mac_phy_cap prints */ 4152 phy_id_map >>= 1; 4153 } 4154 4155 /* For QCA6390, set num_radios to 1 because host manages 4156 * both 2G and 5G radio in one pdev. 4157 * Set pdev_id = 0 and 0 means soc level. 4158 */ 4159 if (soc->hw_params.single_pdev_only) { 4160 soc->num_radios = 1; 4161 soc->pdevs[0].pdev_id = 0; 4162 } 4163 4164 return 0; 4165 } 4166 4167 static int ath11k_wmi_tlv_dma_ring_caps_parse(struct ath11k_base *soc, 4168 u16 tag, u16 len, 4169 const void *ptr, void *data) 4170 { 4171 struct wmi_tlv_dma_ring_caps_parse *parse = data; 4172 4173 if (tag != WMI_TAG_DMA_RING_CAPABILITIES) 4174 return -EPROTO; 4175 4176 parse->n_dma_ring_caps++; 4177 return 0; 4178 } 4179 4180 static int ath11k_wmi_alloc_dbring_caps(struct ath11k_base *ab, 4181 u32 num_cap) 4182 { 4183 size_t sz; 4184 void *ptr; 4185 4186 sz = num_cap * sizeof(struct ath11k_dbring_cap); 4187 ptr = kzalloc(sz, GFP_ATOMIC); 4188 if (!ptr) 4189 return -ENOMEM; 4190 4191 ab->db_caps = ptr; 4192 ab->num_db_cap = num_cap; 4193 4194 return 0; 4195 } 4196 4197 static void ath11k_wmi_free_dbring_caps(struct ath11k_base *ab) 4198 { 4199 kfree(ab->db_caps); 4200 ab->db_caps = NULL; 4201 } 4202 4203 static int ath11k_wmi_tlv_dma_ring_caps(struct ath11k_base *ab, 4204 u16 len, const void *ptr, void *data) 4205 { 4206 struct wmi_tlv_dma_ring_caps_parse *dma_caps_parse = data; 4207 struct wmi_dma_ring_capabilities *dma_caps; 4208 struct ath11k_dbring_cap *dir_buff_caps; 4209 int ret; 4210 u32 i; 4211 4212 dma_caps_parse->n_dma_ring_caps = 0; 4213 dma_caps = (struct wmi_dma_ring_capabilities *)ptr; 4214 ret = ath11k_wmi_tlv_iter(ab, ptr, len, 4215 ath11k_wmi_tlv_dma_ring_caps_parse, 4216 dma_caps_parse); 4217 if (ret) { 4218 ath11k_warn(ab, "failed to parse dma ring caps tlv %d\n", ret); 4219 return ret; 4220 } 4221 4222 if (!dma_caps_parse->n_dma_ring_caps) 4223 return 0; 4224 4225 if (ab->num_db_cap) { 4226 ath11k_warn(ab, "Already processed, so ignoring dma ring caps\n"); 4227 return 0; 4228 } 4229 4230 ret = ath11k_wmi_alloc_dbring_caps(ab, dma_caps_parse->n_dma_ring_caps); 4231 if (ret) 4232 return ret; 4233 4234 dir_buff_caps = ab->db_caps; 4235 for (i = 0; i < dma_caps_parse->n_dma_ring_caps; i++) { 4236 if (dma_caps[i].module_id >= WMI_DIRECT_BUF_MAX) { 4237 ath11k_warn(ab, "Invalid module id %d\n", dma_caps[i].module_id); 4238 ret = -EINVAL; 4239 goto free_dir_buff; 4240 } 4241 4242 dir_buff_caps[i].id = dma_caps[i].module_id; 4243 dir_buff_caps[i].pdev_id = DP_HW2SW_MACID(dma_caps[i].pdev_id); 4244 dir_buff_caps[i].min_elem = dma_caps[i].min_elem; 4245 dir_buff_caps[i].min_buf_sz = dma_caps[i].min_buf_sz; 4246 dir_buff_caps[i].min_buf_align = dma_caps[i].min_buf_align; 4247 } 4248 4249 return 0; 4250 4251 free_dir_buff: 4252 ath11k_wmi_free_dbring_caps(ab); 4253 return ret; 4254 } 4255 4256 static int ath11k_wmi_tlv_svc_rdy_ext_parse(struct ath11k_base *ab, 4257 u16 tag, u16 len, 4258 const void *ptr, void *data) 4259 { 4260 struct ath11k_pdev_wmi *wmi_handle = &ab->wmi_ab.wmi[0]; 4261 struct wmi_tlv_svc_rdy_ext_parse *svc_rdy_ext = data; 4262 int ret; 4263 4264 switch (tag) { 4265 case WMI_TAG_SERVICE_READY_EXT_EVENT: 4266 ret = ath11k_pull_svc_ready_ext(wmi_handle, ptr, 4267 &svc_rdy_ext->param); 4268 if (ret) { 4269 ath11k_warn(ab, "unable to extract ext params\n"); 4270 return ret; 4271 } 4272 break; 4273 4274 case WMI_TAG_SOC_MAC_PHY_HW_MODE_CAPS: 4275 svc_rdy_ext->hw_caps = (struct wmi_soc_mac_phy_hw_mode_caps *)ptr; 4276 svc_rdy_ext->param.num_hw_modes = svc_rdy_ext->hw_caps->num_hw_modes; 4277 break; 4278 4279 case WMI_TAG_SOC_HAL_REG_CAPABILITIES: 4280 ret = ath11k_wmi_tlv_ext_soc_hal_reg_caps_parse(ab, len, ptr, 4281 svc_rdy_ext); 4282 if (ret) 4283 return ret; 4284 break; 4285 4286 case WMI_TAG_ARRAY_STRUCT: 4287 if (!svc_rdy_ext->hw_mode_done) { 4288 ret = ath11k_wmi_tlv_hw_mode_caps(ab, len, ptr, 4289 svc_rdy_ext); 4290 if (ret) 4291 return ret; 4292 4293 svc_rdy_ext->hw_mode_done = true; 4294 } else if (!svc_rdy_ext->mac_phy_done) { 4295 svc_rdy_ext->n_mac_phy_caps = 0; 4296 ret = ath11k_wmi_tlv_iter(ab, ptr, len, 4297 ath11k_wmi_tlv_mac_phy_caps_parse, 4298 svc_rdy_ext); 4299 if (ret) { 4300 ath11k_warn(ab, "failed to parse tlv %d\n", ret); 4301 return ret; 4302 } 4303 4304 svc_rdy_ext->mac_phy_done = true; 4305 } else if (!svc_rdy_ext->ext_hal_reg_done) { 4306 ret = ath11k_wmi_tlv_ext_hal_reg_caps(ab, len, ptr, 4307 svc_rdy_ext); 4308 if (ret) 4309 return ret; 4310 4311 svc_rdy_ext->ext_hal_reg_done = true; 4312 } else if (!svc_rdy_ext->mac_phy_chainmask_combo_done) { 4313 svc_rdy_ext->mac_phy_chainmask_combo_done = true; 4314 } else if (!svc_rdy_ext->mac_phy_chainmask_cap_done) { 4315 svc_rdy_ext->mac_phy_chainmask_cap_done = true; 4316 } else if (!svc_rdy_ext->oem_dma_ring_cap_done) { 4317 svc_rdy_ext->oem_dma_ring_cap_done = true; 4318 } else if (!svc_rdy_ext->dma_ring_cap_done) { 4319 ret = ath11k_wmi_tlv_dma_ring_caps(ab, len, ptr, 4320 &svc_rdy_ext->dma_caps_parse); 4321 if (ret) 4322 return ret; 4323 4324 svc_rdy_ext->dma_ring_cap_done = true; 4325 } 4326 break; 4327 4328 default: 4329 break; 4330 } 4331 return 0; 4332 } 4333 4334 static int ath11k_service_ready_ext_event(struct ath11k_base *ab, 4335 struct sk_buff *skb) 4336 { 4337 struct wmi_tlv_svc_rdy_ext_parse svc_rdy_ext = { }; 4338 int ret; 4339 4340 ret = ath11k_wmi_tlv_iter(ab, skb->data, skb->len, 4341 ath11k_wmi_tlv_svc_rdy_ext_parse, 4342 &svc_rdy_ext); 4343 if (ret) { 4344 ath11k_warn(ab, "failed to parse tlv %d\n", ret); 4345 goto err; 4346 } 4347 4348 if (!test_bit(WMI_TLV_SERVICE_EXT2_MSG, ab->wmi_ab.svc_map)) 4349 complete(&ab->wmi_ab.service_ready); 4350 4351 kfree(svc_rdy_ext.mac_phy_caps); 4352 return 0; 4353 4354 err: 4355 ath11k_wmi_free_dbring_caps(ab); 4356 return ret; 4357 } 4358 4359 static int ath11k_wmi_tlv_svc_rdy_ext2_parse(struct ath11k_base *ab, 4360 u16 tag, u16 len, 4361 const void *ptr, void *data) 4362 { 4363 struct wmi_tlv_svc_rdy_ext2_parse *parse = data; 4364 int ret; 4365 4366 switch (tag) { 4367 case WMI_TAG_ARRAY_STRUCT: 4368 if (!parse->dma_ring_cap_done) { 4369 ret = ath11k_wmi_tlv_dma_ring_caps(ab, len, ptr, 4370 &parse->dma_caps_parse); 4371 if (ret) 4372 return ret; 4373 4374 parse->dma_ring_cap_done = true; 4375 } 4376 break; 4377 default: 4378 break; 4379 } 4380 4381 return 0; 4382 } 4383 4384 static int ath11k_service_ready_ext2_event(struct ath11k_base *ab, 4385 struct sk_buff *skb) 4386 { 4387 struct wmi_tlv_svc_rdy_ext2_parse svc_rdy_ext2 = { }; 4388 int ret; 4389 4390 ret = ath11k_wmi_tlv_iter(ab, skb->data, skb->len, 4391 ath11k_wmi_tlv_svc_rdy_ext2_parse, 4392 &svc_rdy_ext2); 4393 if (ret) { 4394 ath11k_warn(ab, "failed to parse ext2 event tlv %d\n", ret); 4395 goto err; 4396 } 4397 4398 complete(&ab->wmi_ab.service_ready); 4399 4400 return 0; 4401 4402 err: 4403 ath11k_wmi_free_dbring_caps(ab); 4404 return ret; 4405 } 4406 4407 static int ath11k_pull_vdev_start_resp_tlv(struct ath11k_base *ab, struct sk_buff *skb, 4408 struct wmi_vdev_start_resp_event *vdev_rsp) 4409 { 4410 const void **tb; 4411 const struct wmi_vdev_start_resp_event *ev; 4412 int ret; 4413 4414 tb = ath11k_wmi_tlv_parse_alloc(ab, skb->data, skb->len, GFP_ATOMIC); 4415 if (IS_ERR(tb)) { 4416 ret = PTR_ERR(tb); 4417 ath11k_warn(ab, "failed to parse tlv: %d\n", ret); 4418 return ret; 4419 } 4420 4421 ev = tb[WMI_TAG_VDEV_START_RESPONSE_EVENT]; 4422 if (!ev) { 4423 ath11k_warn(ab, "failed to fetch vdev start resp ev"); 4424 kfree(tb); 4425 return -EPROTO; 4426 } 4427 4428 memset(vdev_rsp, 0, sizeof(*vdev_rsp)); 4429 4430 vdev_rsp->vdev_id = ev->vdev_id; 4431 vdev_rsp->requestor_id = ev->requestor_id; 4432 vdev_rsp->resp_type = ev->resp_type; 4433 vdev_rsp->status = ev->status; 4434 vdev_rsp->chain_mask = ev->chain_mask; 4435 vdev_rsp->smps_mode = ev->smps_mode; 4436 vdev_rsp->mac_id = ev->mac_id; 4437 vdev_rsp->cfgd_tx_streams = ev->cfgd_tx_streams; 4438 vdev_rsp->cfgd_rx_streams = ev->cfgd_rx_streams; 4439 4440 kfree(tb); 4441 return 0; 4442 } 4443 4444 static struct cur_reg_rule 4445 *create_reg_rules_from_wmi(u32 num_reg_rules, 4446 struct wmi_regulatory_rule_struct *wmi_reg_rule) 4447 { 4448 struct cur_reg_rule *reg_rule_ptr; 4449 u32 count; 4450 4451 reg_rule_ptr = kzalloc((num_reg_rules * sizeof(*reg_rule_ptr)), 4452 GFP_ATOMIC); 4453 4454 if (!reg_rule_ptr) 4455 return NULL; 4456 4457 for (count = 0; count < num_reg_rules; count++) { 4458 reg_rule_ptr[count].start_freq = 4459 FIELD_GET(REG_RULE_START_FREQ, 4460 wmi_reg_rule[count].freq_info); 4461 reg_rule_ptr[count].end_freq = 4462 FIELD_GET(REG_RULE_END_FREQ, 4463 wmi_reg_rule[count].freq_info); 4464 reg_rule_ptr[count].max_bw = 4465 FIELD_GET(REG_RULE_MAX_BW, 4466 wmi_reg_rule[count].bw_pwr_info); 4467 reg_rule_ptr[count].reg_power = 4468 FIELD_GET(REG_RULE_REG_PWR, 4469 wmi_reg_rule[count].bw_pwr_info); 4470 reg_rule_ptr[count].ant_gain = 4471 FIELD_GET(REG_RULE_ANT_GAIN, 4472 wmi_reg_rule[count].bw_pwr_info); 4473 reg_rule_ptr[count].flags = 4474 FIELD_GET(REG_RULE_FLAGS, 4475 wmi_reg_rule[count].flag_info); 4476 } 4477 4478 return reg_rule_ptr; 4479 } 4480 4481 static int ath11k_pull_reg_chan_list_update_ev(struct ath11k_base *ab, 4482 struct sk_buff *skb, 4483 struct cur_regulatory_info *reg_info) 4484 { 4485 const void **tb; 4486 const struct wmi_reg_chan_list_cc_event *chan_list_event_hdr; 4487 struct wmi_regulatory_rule_struct *wmi_reg_rule; 4488 u32 num_2g_reg_rules, num_5g_reg_rules; 4489 int ret; 4490 4491 ath11k_dbg(ab, ATH11K_DBG_WMI, "processing regulatory channel list\n"); 4492 4493 tb = ath11k_wmi_tlv_parse_alloc(ab, skb->data, skb->len, GFP_ATOMIC); 4494 if (IS_ERR(tb)) { 4495 ret = PTR_ERR(tb); 4496 ath11k_warn(ab, "failed to parse tlv: %d\n", ret); 4497 return ret; 4498 } 4499 4500 chan_list_event_hdr = tb[WMI_TAG_REG_CHAN_LIST_CC_EVENT]; 4501 if (!chan_list_event_hdr) { 4502 ath11k_warn(ab, "failed to fetch reg chan list update ev\n"); 4503 kfree(tb); 4504 return -EPROTO; 4505 } 4506 4507 reg_info->num_2g_reg_rules = chan_list_event_hdr->num_2g_reg_rules; 4508 reg_info->num_5g_reg_rules = chan_list_event_hdr->num_5g_reg_rules; 4509 4510 if (!(reg_info->num_2g_reg_rules + reg_info->num_5g_reg_rules)) { 4511 ath11k_warn(ab, "No regulatory rules available in the event info\n"); 4512 kfree(tb); 4513 return -EINVAL; 4514 } 4515 4516 memcpy(reg_info->alpha2, &chan_list_event_hdr->alpha2, 4517 REG_ALPHA2_LEN); 4518 reg_info->dfs_region = chan_list_event_hdr->dfs_region; 4519 reg_info->phybitmap = chan_list_event_hdr->phybitmap; 4520 reg_info->num_phy = chan_list_event_hdr->num_phy; 4521 reg_info->phy_id = chan_list_event_hdr->phy_id; 4522 reg_info->ctry_code = chan_list_event_hdr->country_id; 4523 reg_info->reg_dmn_pair = chan_list_event_hdr->domain_code; 4524 if (chan_list_event_hdr->status_code == WMI_REG_SET_CC_STATUS_PASS) 4525 reg_info->status_code = REG_SET_CC_STATUS_PASS; 4526 else if (chan_list_event_hdr->status_code == WMI_REG_CURRENT_ALPHA2_NOT_FOUND) 4527 reg_info->status_code = REG_CURRENT_ALPHA2_NOT_FOUND; 4528 else if (chan_list_event_hdr->status_code == WMI_REG_INIT_ALPHA2_NOT_FOUND) 4529 reg_info->status_code = REG_INIT_ALPHA2_NOT_FOUND; 4530 else if (chan_list_event_hdr->status_code == WMI_REG_SET_CC_CHANGE_NOT_ALLOWED) 4531 reg_info->status_code = REG_SET_CC_CHANGE_NOT_ALLOWED; 4532 else if (chan_list_event_hdr->status_code == WMI_REG_SET_CC_STATUS_NO_MEMORY) 4533 reg_info->status_code = REG_SET_CC_STATUS_NO_MEMORY; 4534 else if (chan_list_event_hdr->status_code == WMI_REG_SET_CC_STATUS_FAIL) 4535 reg_info->status_code = REG_SET_CC_STATUS_FAIL; 4536 4537 reg_info->min_bw_2g = chan_list_event_hdr->min_bw_2g; 4538 reg_info->max_bw_2g = chan_list_event_hdr->max_bw_2g; 4539 reg_info->min_bw_5g = chan_list_event_hdr->min_bw_5g; 4540 reg_info->max_bw_5g = chan_list_event_hdr->max_bw_5g; 4541 4542 num_2g_reg_rules = reg_info->num_2g_reg_rules; 4543 num_5g_reg_rules = reg_info->num_5g_reg_rules; 4544 4545 ath11k_dbg(ab, ATH11K_DBG_WMI, 4546 "%s:cc %s dsf %d BW: min_2g %d max_2g %d min_5g %d max_5g %d", 4547 __func__, reg_info->alpha2, reg_info->dfs_region, 4548 reg_info->min_bw_2g, reg_info->max_bw_2g, 4549 reg_info->min_bw_5g, reg_info->max_bw_5g); 4550 4551 ath11k_dbg(ab, ATH11K_DBG_WMI, 4552 "%s: num_2g_reg_rules %d num_5g_reg_rules %d", __func__, 4553 num_2g_reg_rules, num_5g_reg_rules); 4554 4555 wmi_reg_rule = 4556 (struct wmi_regulatory_rule_struct *)((u8 *)chan_list_event_hdr 4557 + sizeof(*chan_list_event_hdr) 4558 + sizeof(struct wmi_tlv)); 4559 4560 if (num_2g_reg_rules) { 4561 reg_info->reg_rules_2g_ptr = create_reg_rules_from_wmi(num_2g_reg_rules, 4562 wmi_reg_rule); 4563 if (!reg_info->reg_rules_2g_ptr) { 4564 kfree(tb); 4565 ath11k_warn(ab, "Unable to Allocate memory for 2g rules\n"); 4566 return -ENOMEM; 4567 } 4568 } 4569 4570 if (num_5g_reg_rules) { 4571 wmi_reg_rule += num_2g_reg_rules; 4572 reg_info->reg_rules_5g_ptr = create_reg_rules_from_wmi(num_5g_reg_rules, 4573 wmi_reg_rule); 4574 if (!reg_info->reg_rules_5g_ptr) { 4575 kfree(tb); 4576 ath11k_warn(ab, "Unable to Allocate memory for 5g rules\n"); 4577 return -ENOMEM; 4578 } 4579 } 4580 4581 ath11k_dbg(ab, ATH11K_DBG_WMI, "processed regulatory channel list\n"); 4582 4583 kfree(tb); 4584 return 0; 4585 } 4586 4587 static int ath11k_pull_peer_del_resp_ev(struct ath11k_base *ab, struct sk_buff *skb, 4588 struct wmi_peer_delete_resp_event *peer_del_resp) 4589 { 4590 const void **tb; 4591 const struct wmi_peer_delete_resp_event *ev; 4592 int ret; 4593 4594 tb = ath11k_wmi_tlv_parse_alloc(ab, skb->data, skb->len, GFP_ATOMIC); 4595 if (IS_ERR(tb)) { 4596 ret = PTR_ERR(tb); 4597 ath11k_warn(ab, "failed to parse tlv: %d\n", ret); 4598 return ret; 4599 } 4600 4601 ev = tb[WMI_TAG_PEER_DELETE_RESP_EVENT]; 4602 if (!ev) { 4603 ath11k_warn(ab, "failed to fetch peer delete resp ev"); 4604 kfree(tb); 4605 return -EPROTO; 4606 } 4607 4608 memset(peer_del_resp, 0, sizeof(*peer_del_resp)); 4609 4610 peer_del_resp->vdev_id = ev->vdev_id; 4611 ether_addr_copy(peer_del_resp->peer_macaddr.addr, 4612 ev->peer_macaddr.addr); 4613 4614 kfree(tb); 4615 return 0; 4616 } 4617 4618 static int ath11k_pull_vdev_del_resp_ev(struct ath11k_base *ab, 4619 struct sk_buff *skb, 4620 u32 *vdev_id) 4621 { 4622 const void **tb; 4623 const struct wmi_vdev_delete_resp_event *ev; 4624 int ret; 4625 4626 tb = ath11k_wmi_tlv_parse_alloc(ab, skb->data, skb->len, GFP_ATOMIC); 4627 if (IS_ERR(tb)) { 4628 ret = PTR_ERR(tb); 4629 ath11k_warn(ab, "failed to parse tlv: %d\n", ret); 4630 return ret; 4631 } 4632 4633 ev = tb[WMI_TAG_VDEV_DELETE_RESP_EVENT]; 4634 if (!ev) { 4635 ath11k_warn(ab, "failed to fetch vdev delete resp ev"); 4636 kfree(tb); 4637 return -EPROTO; 4638 } 4639 4640 *vdev_id = ev->vdev_id; 4641 4642 kfree(tb); 4643 return 0; 4644 } 4645 4646 static int ath11k_pull_bcn_tx_status_ev(struct ath11k_base *ab, void *evt_buf, 4647 u32 len, u32 *vdev_id, 4648 u32 *tx_status) 4649 { 4650 const void **tb; 4651 const struct wmi_bcn_tx_status_event *ev; 4652 int ret; 4653 4654 tb = ath11k_wmi_tlv_parse_alloc(ab, evt_buf, len, GFP_ATOMIC); 4655 if (IS_ERR(tb)) { 4656 ret = PTR_ERR(tb); 4657 ath11k_warn(ab, "failed to parse tlv: %d\n", ret); 4658 return ret; 4659 } 4660 4661 ev = tb[WMI_TAG_OFFLOAD_BCN_TX_STATUS_EVENT]; 4662 if (!ev) { 4663 ath11k_warn(ab, "failed to fetch bcn tx status ev"); 4664 kfree(tb); 4665 return -EPROTO; 4666 } 4667 4668 *vdev_id = ev->vdev_id; 4669 *tx_status = ev->tx_status; 4670 4671 kfree(tb); 4672 return 0; 4673 } 4674 4675 static int ath11k_pull_vdev_stopped_param_tlv(struct ath11k_base *ab, struct sk_buff *skb, 4676 u32 *vdev_id) 4677 { 4678 const void **tb; 4679 const struct wmi_vdev_stopped_event *ev; 4680 int ret; 4681 4682 tb = ath11k_wmi_tlv_parse_alloc(ab, skb->data, skb->len, GFP_ATOMIC); 4683 if (IS_ERR(tb)) { 4684 ret = PTR_ERR(tb); 4685 ath11k_warn(ab, "failed to parse tlv: %d\n", ret); 4686 return ret; 4687 } 4688 4689 ev = tb[WMI_TAG_VDEV_STOPPED_EVENT]; 4690 if (!ev) { 4691 ath11k_warn(ab, "failed to fetch vdev stop ev"); 4692 kfree(tb); 4693 return -EPROTO; 4694 } 4695 4696 *vdev_id = ev->vdev_id; 4697 4698 kfree(tb); 4699 return 0; 4700 } 4701 4702 static int ath11k_pull_mgmt_rx_params_tlv(struct ath11k_base *ab, 4703 struct sk_buff *skb, 4704 struct mgmt_rx_event_params *hdr) 4705 { 4706 const void **tb; 4707 const struct wmi_mgmt_rx_hdr *ev; 4708 const u8 *frame; 4709 int ret; 4710 4711 tb = ath11k_wmi_tlv_parse_alloc(ab, skb->data, skb->len, GFP_ATOMIC); 4712 if (IS_ERR(tb)) { 4713 ret = PTR_ERR(tb); 4714 ath11k_warn(ab, "failed to parse tlv: %d\n", ret); 4715 return ret; 4716 } 4717 4718 ev = tb[WMI_TAG_MGMT_RX_HDR]; 4719 frame = tb[WMI_TAG_ARRAY_BYTE]; 4720 4721 if (!ev || !frame) { 4722 ath11k_warn(ab, "failed to fetch mgmt rx hdr"); 4723 kfree(tb); 4724 return -EPROTO; 4725 } 4726 4727 hdr->pdev_id = ev->pdev_id; 4728 hdr->chan_freq = ev->chan_freq; 4729 hdr->channel = ev->channel; 4730 hdr->snr = ev->snr; 4731 hdr->rate = ev->rate; 4732 hdr->phy_mode = ev->phy_mode; 4733 hdr->buf_len = ev->buf_len; 4734 hdr->status = ev->status; 4735 hdr->flags = ev->flags; 4736 hdr->rssi = ev->rssi; 4737 hdr->tsf_delta = ev->tsf_delta; 4738 memcpy(hdr->rssi_ctl, ev->rssi_ctl, sizeof(hdr->rssi_ctl)); 4739 4740 if (skb->len < (frame - skb->data) + hdr->buf_len) { 4741 ath11k_warn(ab, "invalid length in mgmt rx hdr ev"); 4742 kfree(tb); 4743 return -EPROTO; 4744 } 4745 4746 /* shift the sk_buff to point to `frame` */ 4747 skb_trim(skb, 0); 4748 skb_put(skb, frame - skb->data); 4749 skb_pull(skb, frame - skb->data); 4750 skb_put(skb, hdr->buf_len); 4751 4752 ath11k_ce_byte_swap(skb->data, hdr->buf_len); 4753 4754 kfree(tb); 4755 return 0; 4756 } 4757 4758 static int wmi_process_mgmt_tx_comp(struct ath11k *ar, u32 desc_id, 4759 u32 status) 4760 { 4761 struct sk_buff *msdu; 4762 struct ieee80211_tx_info *info; 4763 struct ath11k_skb_cb *skb_cb; 4764 4765 spin_lock_bh(&ar->txmgmt_idr_lock); 4766 msdu = idr_find(&ar->txmgmt_idr, desc_id); 4767 4768 if (!msdu) { 4769 ath11k_warn(ar->ab, "received mgmt tx compl for invalid msdu_id: %d\n", 4770 desc_id); 4771 spin_unlock_bh(&ar->txmgmt_idr_lock); 4772 return -ENOENT; 4773 } 4774 4775 idr_remove(&ar->txmgmt_idr, desc_id); 4776 spin_unlock_bh(&ar->txmgmt_idr_lock); 4777 4778 skb_cb = ATH11K_SKB_CB(msdu); 4779 dma_unmap_single(ar->ab->dev, skb_cb->paddr, msdu->len, DMA_TO_DEVICE); 4780 4781 info = IEEE80211_SKB_CB(msdu); 4782 if ((!(info->flags & IEEE80211_TX_CTL_NO_ACK)) && !status) 4783 info->flags |= IEEE80211_TX_STAT_ACK; 4784 4785 ieee80211_tx_status_irqsafe(ar->hw, msdu); 4786 4787 /* WARN when we received this event without doing any mgmt tx */ 4788 if (atomic_dec_if_positive(&ar->num_pending_mgmt_tx) < 0) 4789 WARN_ON_ONCE(1); 4790 4791 return 0; 4792 } 4793 4794 static int ath11k_pull_mgmt_tx_compl_param_tlv(struct ath11k_base *ab, 4795 struct sk_buff *skb, 4796 struct wmi_mgmt_tx_compl_event *param) 4797 { 4798 const void **tb; 4799 const struct wmi_mgmt_tx_compl_event *ev; 4800 int ret; 4801 4802 tb = ath11k_wmi_tlv_parse_alloc(ab, skb->data, skb->len, GFP_ATOMIC); 4803 if (IS_ERR(tb)) { 4804 ret = PTR_ERR(tb); 4805 ath11k_warn(ab, "failed to parse tlv: %d\n", ret); 4806 return ret; 4807 } 4808 4809 ev = tb[WMI_TAG_MGMT_TX_COMPL_EVENT]; 4810 if (!ev) { 4811 ath11k_warn(ab, "failed to fetch mgmt tx compl ev"); 4812 kfree(tb); 4813 return -EPROTO; 4814 } 4815 4816 param->pdev_id = ev->pdev_id; 4817 param->desc_id = ev->desc_id; 4818 param->status = ev->status; 4819 4820 kfree(tb); 4821 return 0; 4822 } 4823 4824 static void ath11k_wmi_event_scan_started(struct ath11k *ar) 4825 { 4826 lockdep_assert_held(&ar->data_lock); 4827 4828 switch (ar->scan.state) { 4829 case ATH11K_SCAN_IDLE: 4830 case ATH11K_SCAN_RUNNING: 4831 case ATH11K_SCAN_ABORTING: 4832 ath11k_warn(ar->ab, "received scan started event in an invalid scan state: %s (%d)\n", 4833 ath11k_scan_state_str(ar->scan.state), 4834 ar->scan.state); 4835 break; 4836 case ATH11K_SCAN_STARTING: 4837 ar->scan.state = ATH11K_SCAN_RUNNING; 4838 complete(&ar->scan.started); 4839 break; 4840 } 4841 } 4842 4843 static void ath11k_wmi_event_scan_start_failed(struct ath11k *ar) 4844 { 4845 lockdep_assert_held(&ar->data_lock); 4846 4847 switch (ar->scan.state) { 4848 case ATH11K_SCAN_IDLE: 4849 case ATH11K_SCAN_RUNNING: 4850 case ATH11K_SCAN_ABORTING: 4851 ath11k_warn(ar->ab, "received scan start failed event in an invalid scan state: %s (%d)\n", 4852 ath11k_scan_state_str(ar->scan.state), 4853 ar->scan.state); 4854 break; 4855 case ATH11K_SCAN_STARTING: 4856 complete(&ar->scan.started); 4857 __ath11k_mac_scan_finish(ar); 4858 break; 4859 } 4860 } 4861 4862 static void ath11k_wmi_event_scan_completed(struct ath11k *ar) 4863 { 4864 lockdep_assert_held(&ar->data_lock); 4865 4866 switch (ar->scan.state) { 4867 case ATH11K_SCAN_IDLE: 4868 case ATH11K_SCAN_STARTING: 4869 /* One suspected reason scan can be completed while starting is 4870 * if firmware fails to deliver all scan events to the host, 4871 * e.g. when transport pipe is full. This has been observed 4872 * with spectral scan phyerr events starving wmi transport 4873 * pipe. In such case the "scan completed" event should be (and 4874 * is) ignored by the host as it may be just firmware's scan 4875 * state machine recovering. 4876 */ 4877 ath11k_warn(ar->ab, "received scan completed event in an invalid scan state: %s (%d)\n", 4878 ath11k_scan_state_str(ar->scan.state), 4879 ar->scan.state); 4880 break; 4881 case ATH11K_SCAN_RUNNING: 4882 case ATH11K_SCAN_ABORTING: 4883 __ath11k_mac_scan_finish(ar); 4884 break; 4885 } 4886 } 4887 4888 static void ath11k_wmi_event_scan_bss_chan(struct ath11k *ar) 4889 { 4890 lockdep_assert_held(&ar->data_lock); 4891 4892 switch (ar->scan.state) { 4893 case ATH11K_SCAN_IDLE: 4894 case ATH11K_SCAN_STARTING: 4895 ath11k_warn(ar->ab, "received scan bss chan event in an invalid scan state: %s (%d)\n", 4896 ath11k_scan_state_str(ar->scan.state), 4897 ar->scan.state); 4898 break; 4899 case ATH11K_SCAN_RUNNING: 4900 case ATH11K_SCAN_ABORTING: 4901 ar->scan_channel = NULL; 4902 break; 4903 } 4904 } 4905 4906 static void ath11k_wmi_event_scan_foreign_chan(struct ath11k *ar, u32 freq) 4907 { 4908 lockdep_assert_held(&ar->data_lock); 4909 4910 switch (ar->scan.state) { 4911 case ATH11K_SCAN_IDLE: 4912 case ATH11K_SCAN_STARTING: 4913 ath11k_warn(ar->ab, "received scan foreign chan event in an invalid scan state: %s (%d)\n", 4914 ath11k_scan_state_str(ar->scan.state), 4915 ar->scan.state); 4916 break; 4917 case ATH11K_SCAN_RUNNING: 4918 case ATH11K_SCAN_ABORTING: 4919 ar->scan_channel = ieee80211_get_channel(ar->hw->wiphy, freq); 4920 break; 4921 } 4922 } 4923 4924 static const char * 4925 ath11k_wmi_event_scan_type_str(enum wmi_scan_event_type type, 4926 enum wmi_scan_completion_reason reason) 4927 { 4928 switch (type) { 4929 case WMI_SCAN_EVENT_STARTED: 4930 return "started"; 4931 case WMI_SCAN_EVENT_COMPLETED: 4932 switch (reason) { 4933 case WMI_SCAN_REASON_COMPLETED: 4934 return "completed"; 4935 case WMI_SCAN_REASON_CANCELLED: 4936 return "completed [cancelled]"; 4937 case WMI_SCAN_REASON_PREEMPTED: 4938 return "completed [preempted]"; 4939 case WMI_SCAN_REASON_TIMEDOUT: 4940 return "completed [timedout]"; 4941 case WMI_SCAN_REASON_INTERNAL_FAILURE: 4942 return "completed [internal err]"; 4943 case WMI_SCAN_REASON_MAX: 4944 break; 4945 } 4946 return "completed [unknown]"; 4947 case WMI_SCAN_EVENT_BSS_CHANNEL: 4948 return "bss channel"; 4949 case WMI_SCAN_EVENT_FOREIGN_CHAN: 4950 return "foreign channel"; 4951 case WMI_SCAN_EVENT_DEQUEUED: 4952 return "dequeued"; 4953 case WMI_SCAN_EVENT_PREEMPTED: 4954 return "preempted"; 4955 case WMI_SCAN_EVENT_START_FAILED: 4956 return "start failed"; 4957 case WMI_SCAN_EVENT_RESTARTED: 4958 return "restarted"; 4959 case WMI_SCAN_EVENT_FOREIGN_CHAN_EXIT: 4960 return "foreign channel exit"; 4961 default: 4962 return "unknown"; 4963 } 4964 } 4965 4966 static int ath11k_pull_scan_ev(struct ath11k_base *ab, struct sk_buff *skb, 4967 struct wmi_scan_event *scan_evt_param) 4968 { 4969 const void **tb; 4970 const struct wmi_scan_event *ev; 4971 int ret; 4972 4973 tb = ath11k_wmi_tlv_parse_alloc(ab, skb->data, skb->len, GFP_ATOMIC); 4974 if (IS_ERR(tb)) { 4975 ret = PTR_ERR(tb); 4976 ath11k_warn(ab, "failed to parse tlv: %d\n", ret); 4977 return ret; 4978 } 4979 4980 ev = tb[WMI_TAG_SCAN_EVENT]; 4981 if (!ev) { 4982 ath11k_warn(ab, "failed to fetch scan ev"); 4983 kfree(tb); 4984 return -EPROTO; 4985 } 4986 4987 scan_evt_param->event_type = ev->event_type; 4988 scan_evt_param->reason = ev->reason; 4989 scan_evt_param->channel_freq = ev->channel_freq; 4990 scan_evt_param->scan_req_id = ev->scan_req_id; 4991 scan_evt_param->scan_id = ev->scan_id; 4992 scan_evt_param->vdev_id = ev->vdev_id; 4993 scan_evt_param->tsf_timestamp = ev->tsf_timestamp; 4994 4995 kfree(tb); 4996 return 0; 4997 } 4998 4999 static int ath11k_pull_peer_sta_kickout_ev(struct ath11k_base *ab, struct sk_buff *skb, 5000 struct wmi_peer_sta_kickout_arg *arg) 5001 { 5002 const void **tb; 5003 const struct wmi_peer_sta_kickout_event *ev; 5004 int ret; 5005 5006 tb = ath11k_wmi_tlv_parse_alloc(ab, skb->data, skb->len, GFP_ATOMIC); 5007 if (IS_ERR(tb)) { 5008 ret = PTR_ERR(tb); 5009 ath11k_warn(ab, "failed to parse tlv: %d\n", ret); 5010 return ret; 5011 } 5012 5013 ev = tb[WMI_TAG_PEER_STA_KICKOUT_EVENT]; 5014 if (!ev) { 5015 ath11k_warn(ab, "failed to fetch peer sta kickout ev"); 5016 kfree(tb); 5017 return -EPROTO; 5018 } 5019 5020 arg->mac_addr = ev->peer_macaddr.addr; 5021 5022 kfree(tb); 5023 return 0; 5024 } 5025 5026 static int ath11k_pull_roam_ev(struct ath11k_base *ab, struct sk_buff *skb, 5027 struct wmi_roam_event *roam_ev) 5028 { 5029 const void **tb; 5030 const struct wmi_roam_event *ev; 5031 int ret; 5032 5033 tb = ath11k_wmi_tlv_parse_alloc(ab, skb->data, skb->len, GFP_ATOMIC); 5034 if (IS_ERR(tb)) { 5035 ret = PTR_ERR(tb); 5036 ath11k_warn(ab, "failed to parse tlv: %d\n", ret); 5037 return ret; 5038 } 5039 5040 ev = tb[WMI_TAG_ROAM_EVENT]; 5041 if (!ev) { 5042 ath11k_warn(ab, "failed to fetch roam ev"); 5043 kfree(tb); 5044 return -EPROTO; 5045 } 5046 5047 roam_ev->vdev_id = ev->vdev_id; 5048 roam_ev->reason = ev->reason; 5049 roam_ev->rssi = ev->rssi; 5050 5051 kfree(tb); 5052 return 0; 5053 } 5054 5055 static int freq_to_idx(struct ath11k *ar, int freq) 5056 { 5057 struct ieee80211_supported_band *sband; 5058 int band, ch, idx = 0; 5059 5060 for (band = NL80211_BAND_2GHZ; band < NUM_NL80211_BANDS; band++) { 5061 sband = ar->hw->wiphy->bands[band]; 5062 if (!sband) 5063 continue; 5064 5065 for (ch = 0; ch < sband->n_channels; ch++, idx++) 5066 if (sband->channels[ch].center_freq == freq) 5067 goto exit; 5068 } 5069 5070 exit: 5071 return idx; 5072 } 5073 5074 static int ath11k_pull_chan_info_ev(struct ath11k_base *ab, u8 *evt_buf, 5075 u32 len, struct wmi_chan_info_event *ch_info_ev) 5076 { 5077 const void **tb; 5078 const struct wmi_chan_info_event *ev; 5079 int ret; 5080 5081 tb = ath11k_wmi_tlv_parse_alloc(ab, evt_buf, len, GFP_ATOMIC); 5082 if (IS_ERR(tb)) { 5083 ret = PTR_ERR(tb); 5084 ath11k_warn(ab, "failed to parse tlv: %d\n", ret); 5085 return ret; 5086 } 5087 5088 ev = tb[WMI_TAG_CHAN_INFO_EVENT]; 5089 if (!ev) { 5090 ath11k_warn(ab, "failed to fetch chan info ev"); 5091 kfree(tb); 5092 return -EPROTO; 5093 } 5094 5095 ch_info_ev->err_code = ev->err_code; 5096 ch_info_ev->freq = ev->freq; 5097 ch_info_ev->cmd_flags = ev->cmd_flags; 5098 ch_info_ev->noise_floor = ev->noise_floor; 5099 ch_info_ev->rx_clear_count = ev->rx_clear_count; 5100 ch_info_ev->cycle_count = ev->cycle_count; 5101 ch_info_ev->chan_tx_pwr_range = ev->chan_tx_pwr_range; 5102 ch_info_ev->chan_tx_pwr_tp = ev->chan_tx_pwr_tp; 5103 ch_info_ev->rx_frame_count = ev->rx_frame_count; 5104 ch_info_ev->tx_frame_cnt = ev->tx_frame_cnt; 5105 ch_info_ev->mac_clk_mhz = ev->mac_clk_mhz; 5106 ch_info_ev->vdev_id = ev->vdev_id; 5107 5108 kfree(tb); 5109 return 0; 5110 } 5111 5112 static int 5113 ath11k_pull_pdev_bss_chan_info_ev(struct ath11k_base *ab, struct sk_buff *skb, 5114 struct wmi_pdev_bss_chan_info_event *bss_ch_info_ev) 5115 { 5116 const void **tb; 5117 const struct wmi_pdev_bss_chan_info_event *ev; 5118 int ret; 5119 5120 tb = ath11k_wmi_tlv_parse_alloc(ab, skb->data, skb->len, GFP_ATOMIC); 5121 if (IS_ERR(tb)) { 5122 ret = PTR_ERR(tb); 5123 ath11k_warn(ab, "failed to parse tlv: %d\n", ret); 5124 return ret; 5125 } 5126 5127 ev = tb[WMI_TAG_PDEV_BSS_CHAN_INFO_EVENT]; 5128 if (!ev) { 5129 ath11k_warn(ab, "failed to fetch pdev bss chan info ev"); 5130 kfree(tb); 5131 return -EPROTO; 5132 } 5133 5134 bss_ch_info_ev->pdev_id = ev->pdev_id; 5135 bss_ch_info_ev->freq = ev->freq; 5136 bss_ch_info_ev->noise_floor = ev->noise_floor; 5137 bss_ch_info_ev->rx_clear_count_low = ev->rx_clear_count_low; 5138 bss_ch_info_ev->rx_clear_count_high = ev->rx_clear_count_high; 5139 bss_ch_info_ev->cycle_count_low = ev->cycle_count_low; 5140 bss_ch_info_ev->cycle_count_high = ev->cycle_count_high; 5141 bss_ch_info_ev->tx_cycle_count_low = ev->tx_cycle_count_low; 5142 bss_ch_info_ev->tx_cycle_count_high = ev->tx_cycle_count_high; 5143 bss_ch_info_ev->rx_cycle_count_low = ev->rx_cycle_count_low; 5144 bss_ch_info_ev->rx_cycle_count_high = ev->rx_cycle_count_high; 5145 bss_ch_info_ev->rx_bss_cycle_count_low = ev->rx_bss_cycle_count_low; 5146 bss_ch_info_ev->rx_bss_cycle_count_high = ev->rx_bss_cycle_count_high; 5147 5148 kfree(tb); 5149 return 0; 5150 } 5151 5152 static int 5153 ath11k_pull_vdev_install_key_compl_ev(struct ath11k_base *ab, struct sk_buff *skb, 5154 struct wmi_vdev_install_key_complete_arg *arg) 5155 { 5156 const void **tb; 5157 const struct wmi_vdev_install_key_compl_event *ev; 5158 int ret; 5159 5160 tb = ath11k_wmi_tlv_parse_alloc(ab, skb->data, skb->len, GFP_ATOMIC); 5161 if (IS_ERR(tb)) { 5162 ret = PTR_ERR(tb); 5163 ath11k_warn(ab, "failed to parse tlv: %d\n", ret); 5164 return ret; 5165 } 5166 5167 ev = tb[WMI_TAG_VDEV_INSTALL_KEY_COMPLETE_EVENT]; 5168 if (!ev) { 5169 ath11k_warn(ab, "failed to fetch vdev install key compl ev"); 5170 kfree(tb); 5171 return -EPROTO; 5172 } 5173 5174 arg->vdev_id = ev->vdev_id; 5175 arg->macaddr = ev->peer_macaddr.addr; 5176 arg->key_idx = ev->key_idx; 5177 arg->key_flags = ev->key_flags; 5178 arg->status = ev->status; 5179 5180 kfree(tb); 5181 return 0; 5182 } 5183 5184 static int ath11k_pull_peer_assoc_conf_ev(struct ath11k_base *ab, struct sk_buff *skb, 5185 struct wmi_peer_assoc_conf_arg *peer_assoc_conf) 5186 { 5187 const void **tb; 5188 const struct wmi_peer_assoc_conf_event *ev; 5189 int ret; 5190 5191 tb = ath11k_wmi_tlv_parse_alloc(ab, skb->data, skb->len, GFP_ATOMIC); 5192 if (IS_ERR(tb)) { 5193 ret = PTR_ERR(tb); 5194 ath11k_warn(ab, "failed to parse tlv: %d\n", ret); 5195 return ret; 5196 } 5197 5198 ev = tb[WMI_TAG_PEER_ASSOC_CONF_EVENT]; 5199 if (!ev) { 5200 ath11k_warn(ab, "failed to fetch peer assoc conf ev"); 5201 kfree(tb); 5202 return -EPROTO; 5203 } 5204 5205 peer_assoc_conf->vdev_id = ev->vdev_id; 5206 peer_assoc_conf->macaddr = ev->peer_macaddr.addr; 5207 5208 kfree(tb); 5209 return 0; 5210 } 5211 5212 static void ath11k_wmi_pull_pdev_stats_base(const struct wmi_pdev_stats_base *src, 5213 struct ath11k_fw_stats_pdev *dst) 5214 { 5215 dst->ch_noise_floor = src->chan_nf; 5216 dst->tx_frame_count = src->tx_frame_count; 5217 dst->rx_frame_count = src->rx_frame_count; 5218 dst->rx_clear_count = src->rx_clear_count; 5219 dst->cycle_count = src->cycle_count; 5220 dst->phy_err_count = src->phy_err_count; 5221 dst->chan_tx_power = src->chan_tx_pwr; 5222 } 5223 5224 static void 5225 ath11k_wmi_pull_pdev_stats_tx(const struct wmi_pdev_stats_tx *src, 5226 struct ath11k_fw_stats_pdev *dst) 5227 { 5228 dst->comp_queued = src->comp_queued; 5229 dst->comp_delivered = src->comp_delivered; 5230 dst->msdu_enqued = src->msdu_enqued; 5231 dst->mpdu_enqued = src->mpdu_enqued; 5232 dst->wmm_drop = src->wmm_drop; 5233 dst->local_enqued = src->local_enqued; 5234 dst->local_freed = src->local_freed; 5235 dst->hw_queued = src->hw_queued; 5236 dst->hw_reaped = src->hw_reaped; 5237 dst->underrun = src->underrun; 5238 dst->tx_abort = src->tx_abort; 5239 dst->mpdus_requeued = src->mpdus_requeued; 5240 dst->tx_ko = src->tx_ko; 5241 dst->data_rc = src->data_rc; 5242 dst->self_triggers = src->self_triggers; 5243 dst->sw_retry_failure = src->sw_retry_failure; 5244 dst->illgl_rate_phy_err = src->illgl_rate_phy_err; 5245 dst->pdev_cont_xretry = src->pdev_cont_xretry; 5246 dst->pdev_tx_timeout = src->pdev_tx_timeout; 5247 dst->pdev_resets = src->pdev_resets; 5248 dst->stateless_tid_alloc_failure = src->stateless_tid_alloc_failure; 5249 dst->phy_underrun = src->phy_underrun; 5250 dst->txop_ovf = src->txop_ovf; 5251 } 5252 5253 static void ath11k_wmi_pull_pdev_stats_rx(const struct wmi_pdev_stats_rx *src, 5254 struct ath11k_fw_stats_pdev *dst) 5255 { 5256 dst->mid_ppdu_route_change = src->mid_ppdu_route_change; 5257 dst->status_rcvd = src->status_rcvd; 5258 dst->r0_frags = src->r0_frags; 5259 dst->r1_frags = src->r1_frags; 5260 dst->r2_frags = src->r2_frags; 5261 dst->r3_frags = src->r3_frags; 5262 dst->htt_msdus = src->htt_msdus; 5263 dst->htt_mpdus = src->htt_mpdus; 5264 dst->loc_msdus = src->loc_msdus; 5265 dst->loc_mpdus = src->loc_mpdus; 5266 dst->oversize_amsdu = src->oversize_amsdu; 5267 dst->phy_errs = src->phy_errs; 5268 dst->phy_err_drop = src->phy_err_drop; 5269 dst->mpdu_errs = src->mpdu_errs; 5270 } 5271 5272 static void 5273 ath11k_wmi_pull_vdev_stats(const struct wmi_vdev_stats *src, 5274 struct ath11k_fw_stats_vdev *dst) 5275 { 5276 int i; 5277 5278 dst->vdev_id = src->vdev_id; 5279 dst->beacon_snr = src->beacon_snr; 5280 dst->data_snr = src->data_snr; 5281 dst->num_rx_frames = src->num_rx_frames; 5282 dst->num_rts_fail = src->num_rts_fail; 5283 dst->num_rts_success = src->num_rts_success; 5284 dst->num_rx_err = src->num_rx_err; 5285 dst->num_rx_discard = src->num_rx_discard; 5286 dst->num_tx_not_acked = src->num_tx_not_acked; 5287 5288 for (i = 0; i < ARRAY_SIZE(src->num_tx_frames); i++) 5289 dst->num_tx_frames[i] = src->num_tx_frames[i]; 5290 5291 for (i = 0; i < ARRAY_SIZE(src->num_tx_frames_retries); i++) 5292 dst->num_tx_frames_retries[i] = src->num_tx_frames_retries[i]; 5293 5294 for (i = 0; i < ARRAY_SIZE(src->num_tx_frames_failures); i++) 5295 dst->num_tx_frames_failures[i] = src->num_tx_frames_failures[i]; 5296 5297 for (i = 0; i < ARRAY_SIZE(src->tx_rate_history); i++) 5298 dst->tx_rate_history[i] = src->tx_rate_history[i]; 5299 5300 for (i = 0; i < ARRAY_SIZE(src->beacon_rssi_history); i++) 5301 dst->beacon_rssi_history[i] = src->beacon_rssi_history[i]; 5302 } 5303 5304 static void 5305 ath11k_wmi_pull_bcn_stats(const struct wmi_bcn_stats *src, 5306 struct ath11k_fw_stats_bcn *dst) 5307 { 5308 dst->vdev_id = src->vdev_id; 5309 dst->tx_bcn_succ_cnt = src->tx_bcn_succ_cnt; 5310 dst->tx_bcn_outage_cnt = src->tx_bcn_outage_cnt; 5311 } 5312 5313 int ath11k_wmi_pull_fw_stats(struct ath11k_base *ab, struct sk_buff *skb, 5314 struct ath11k_fw_stats *stats) 5315 { 5316 const void **tb; 5317 const struct wmi_stats_event *ev; 5318 const void *data; 5319 int i, ret; 5320 u32 len = skb->len; 5321 5322 tb = ath11k_wmi_tlv_parse_alloc(ab, skb->data, len, GFP_ATOMIC); 5323 if (IS_ERR(tb)) { 5324 ret = PTR_ERR(tb); 5325 ath11k_warn(ab, "failed to parse tlv: %d\n", ret); 5326 return ret; 5327 } 5328 5329 ev = tb[WMI_TAG_STATS_EVENT]; 5330 data = tb[WMI_TAG_ARRAY_BYTE]; 5331 if (!ev || !data) { 5332 ath11k_warn(ab, "failed to fetch update stats ev"); 5333 kfree(tb); 5334 return -EPROTO; 5335 } 5336 5337 ath11k_dbg(ab, ATH11K_DBG_WMI, 5338 "wmi stats update ev pdev_id %d pdev %i vdev %i bcn %i\n", 5339 ev->pdev_id, 5340 ev->num_pdev_stats, ev->num_vdev_stats, 5341 ev->num_bcn_stats); 5342 5343 stats->pdev_id = ev->pdev_id; 5344 stats->stats_id = 0; 5345 5346 for (i = 0; i < ev->num_pdev_stats; i++) { 5347 const struct wmi_pdev_stats *src; 5348 struct ath11k_fw_stats_pdev *dst; 5349 5350 src = data; 5351 if (len < sizeof(*src)) { 5352 kfree(tb); 5353 return -EPROTO; 5354 } 5355 5356 stats->stats_id = WMI_REQUEST_PDEV_STAT; 5357 5358 data += sizeof(*src); 5359 len -= sizeof(*src); 5360 5361 dst = kzalloc(sizeof(*dst), GFP_ATOMIC); 5362 if (!dst) 5363 continue; 5364 5365 ath11k_wmi_pull_pdev_stats_base(&src->base, dst); 5366 ath11k_wmi_pull_pdev_stats_tx(&src->tx, dst); 5367 ath11k_wmi_pull_pdev_stats_rx(&src->rx, dst); 5368 list_add_tail(&dst->list, &stats->pdevs); 5369 } 5370 5371 for (i = 0; i < ev->num_vdev_stats; i++) { 5372 const struct wmi_vdev_stats *src; 5373 struct ath11k_fw_stats_vdev *dst; 5374 5375 src = data; 5376 if (len < sizeof(*src)) { 5377 kfree(tb); 5378 return -EPROTO; 5379 } 5380 5381 stats->stats_id = WMI_REQUEST_VDEV_STAT; 5382 5383 data += sizeof(*src); 5384 len -= sizeof(*src); 5385 5386 dst = kzalloc(sizeof(*dst), GFP_ATOMIC); 5387 if (!dst) 5388 continue; 5389 5390 ath11k_wmi_pull_vdev_stats(src, dst); 5391 list_add_tail(&dst->list, &stats->vdevs); 5392 } 5393 5394 for (i = 0; i < ev->num_bcn_stats; i++) { 5395 const struct wmi_bcn_stats *src; 5396 struct ath11k_fw_stats_bcn *dst; 5397 5398 src = data; 5399 if (len < sizeof(*src)) { 5400 kfree(tb); 5401 return -EPROTO; 5402 } 5403 5404 stats->stats_id = WMI_REQUEST_BCN_STAT; 5405 5406 data += sizeof(*src); 5407 len -= sizeof(*src); 5408 5409 dst = kzalloc(sizeof(*dst), GFP_ATOMIC); 5410 if (!dst) 5411 continue; 5412 5413 ath11k_wmi_pull_bcn_stats(src, dst); 5414 list_add_tail(&dst->list, &stats->bcn); 5415 } 5416 5417 kfree(tb); 5418 return 0; 5419 } 5420 5421 size_t ath11k_wmi_fw_stats_num_vdevs(struct list_head *head) 5422 { 5423 struct ath11k_fw_stats_vdev *i; 5424 size_t num = 0; 5425 5426 list_for_each_entry(i, head, list) 5427 ++num; 5428 5429 return num; 5430 } 5431 5432 static size_t ath11k_wmi_fw_stats_num_bcn(struct list_head *head) 5433 { 5434 struct ath11k_fw_stats_bcn *i; 5435 size_t num = 0; 5436 5437 list_for_each_entry(i, head, list) 5438 ++num; 5439 5440 return num; 5441 } 5442 5443 static void 5444 ath11k_wmi_fw_pdev_base_stats_fill(const struct ath11k_fw_stats_pdev *pdev, 5445 char *buf, u32 *length) 5446 { 5447 u32 len = *length; 5448 u32 buf_len = ATH11K_FW_STATS_BUF_SIZE; 5449 5450 len += scnprintf(buf + len, buf_len - len, "\n"); 5451 len += scnprintf(buf + len, buf_len - len, "%30s\n", 5452 "ath11k PDEV stats"); 5453 len += scnprintf(buf + len, buf_len - len, "%30s\n\n", 5454 "================="); 5455 5456 len += scnprintf(buf + len, buf_len - len, "%30s %10d\n", 5457 "Channel noise floor", pdev->ch_noise_floor); 5458 len += scnprintf(buf + len, buf_len - len, "%30s %10u\n", 5459 "Channel TX power", pdev->chan_tx_power); 5460 len += scnprintf(buf + len, buf_len - len, "%30s %10u\n", 5461 "TX frame count", pdev->tx_frame_count); 5462 len += scnprintf(buf + len, buf_len - len, "%30s %10u\n", 5463 "RX frame count", pdev->rx_frame_count); 5464 len += scnprintf(buf + len, buf_len - len, "%30s %10u\n", 5465 "RX clear count", pdev->rx_clear_count); 5466 len += scnprintf(buf + len, buf_len - len, "%30s %10u\n", 5467 "Cycle count", pdev->cycle_count); 5468 len += scnprintf(buf + len, buf_len - len, "%30s %10u\n", 5469 "PHY error count", pdev->phy_err_count); 5470 5471 *length = len; 5472 } 5473 5474 static void 5475 ath11k_wmi_fw_pdev_tx_stats_fill(const struct ath11k_fw_stats_pdev *pdev, 5476 char *buf, u32 *length) 5477 { 5478 u32 len = *length; 5479 u32 buf_len = ATH11K_FW_STATS_BUF_SIZE; 5480 5481 len += scnprintf(buf + len, buf_len - len, "\n%30s\n", 5482 "ath11k PDEV TX stats"); 5483 len += scnprintf(buf + len, buf_len - len, "%30s\n\n", 5484 "===================="); 5485 5486 len += scnprintf(buf + len, buf_len - len, "%30s %10d\n", 5487 "HTT cookies queued", pdev->comp_queued); 5488 len += scnprintf(buf + len, buf_len - len, "%30s %10d\n", 5489 "HTT cookies disp.", pdev->comp_delivered); 5490 len += scnprintf(buf + len, buf_len - len, "%30s %10d\n", 5491 "MSDU queued", pdev->msdu_enqued); 5492 len += scnprintf(buf + len, buf_len - len, "%30s %10d\n", 5493 "MPDU queued", pdev->mpdu_enqued); 5494 len += scnprintf(buf + len, buf_len - len, "%30s %10d\n", 5495 "MSDUs dropped", pdev->wmm_drop); 5496 len += scnprintf(buf + len, buf_len - len, "%30s %10d\n", 5497 "Local enqued", pdev->local_enqued); 5498 len += scnprintf(buf + len, buf_len - len, "%30s %10d\n", 5499 "Local freed", pdev->local_freed); 5500 len += scnprintf(buf + len, buf_len - len, "%30s %10d\n", 5501 "HW queued", pdev->hw_queued); 5502 len += scnprintf(buf + len, buf_len - len, "%30s %10d\n", 5503 "PPDUs reaped", pdev->hw_reaped); 5504 len += scnprintf(buf + len, buf_len - len, "%30s %10d\n", 5505 "Num underruns", pdev->underrun); 5506 len += scnprintf(buf + len, buf_len - len, "%30s %10d\n", 5507 "PPDUs cleaned", pdev->tx_abort); 5508 len += scnprintf(buf + len, buf_len - len, "%30s %10d\n", 5509 "MPDUs requeued", pdev->mpdus_requeued); 5510 len += scnprintf(buf + len, buf_len - len, "%30s %10u\n", 5511 "Excessive retries", pdev->tx_ko); 5512 len += scnprintf(buf + len, buf_len - len, "%30s %10u\n", 5513 "HW rate", pdev->data_rc); 5514 len += scnprintf(buf + len, buf_len - len, "%30s %10u\n", 5515 "Sched self triggers", pdev->self_triggers); 5516 len += scnprintf(buf + len, buf_len - len, "%30s %10u\n", 5517 "Dropped due to SW retries", 5518 pdev->sw_retry_failure); 5519 len += scnprintf(buf + len, buf_len - len, "%30s %10u\n", 5520 "Illegal rate phy errors", 5521 pdev->illgl_rate_phy_err); 5522 len += scnprintf(buf + len, buf_len - len, "%30s %10u\n", 5523 "PDEV continuous xretry", pdev->pdev_cont_xretry); 5524 len += scnprintf(buf + len, buf_len - len, "%30s %10u\n", 5525 "TX timeout", pdev->pdev_tx_timeout); 5526 len += scnprintf(buf + len, buf_len - len, "%30s %10u\n", 5527 "PDEV resets", pdev->pdev_resets); 5528 len += scnprintf(buf + len, buf_len - len, "%30s %10u\n", 5529 "Stateless TIDs alloc failures", 5530 pdev->stateless_tid_alloc_failure); 5531 len += scnprintf(buf + len, buf_len - len, "%30s %10u\n", 5532 "PHY underrun", pdev->phy_underrun); 5533 len += scnprintf(buf + len, buf_len - len, "%30s %10u\n", 5534 "MPDU is more than txop limit", pdev->txop_ovf); 5535 *length = len; 5536 } 5537 5538 static void 5539 ath11k_wmi_fw_pdev_rx_stats_fill(const struct ath11k_fw_stats_pdev *pdev, 5540 char *buf, u32 *length) 5541 { 5542 u32 len = *length; 5543 u32 buf_len = ATH11K_FW_STATS_BUF_SIZE; 5544 5545 len += scnprintf(buf + len, buf_len - len, "\n%30s\n", 5546 "ath11k PDEV RX stats"); 5547 len += scnprintf(buf + len, buf_len - len, "%30s\n\n", 5548 "===================="); 5549 5550 len += scnprintf(buf + len, buf_len - len, "%30s %10d\n", 5551 "Mid PPDU route change", 5552 pdev->mid_ppdu_route_change); 5553 len += scnprintf(buf + len, buf_len - len, "%30s %10d\n", 5554 "Tot. number of statuses", pdev->status_rcvd); 5555 len += scnprintf(buf + len, buf_len - len, "%30s %10d\n", 5556 "Extra frags on rings 0", pdev->r0_frags); 5557 len += scnprintf(buf + len, buf_len - len, "%30s %10d\n", 5558 "Extra frags on rings 1", pdev->r1_frags); 5559 len += scnprintf(buf + len, buf_len - len, "%30s %10d\n", 5560 "Extra frags on rings 2", pdev->r2_frags); 5561 len += scnprintf(buf + len, buf_len - len, "%30s %10d\n", 5562 "Extra frags on rings 3", pdev->r3_frags); 5563 len += scnprintf(buf + len, buf_len - len, "%30s %10d\n", 5564 "MSDUs delivered to HTT", pdev->htt_msdus); 5565 len += scnprintf(buf + len, buf_len - len, "%30s %10d\n", 5566 "MPDUs delivered to HTT", pdev->htt_mpdus); 5567 len += scnprintf(buf + len, buf_len - len, "%30s %10d\n", 5568 "MSDUs delivered to stack", pdev->loc_msdus); 5569 len += scnprintf(buf + len, buf_len - len, "%30s %10d\n", 5570 "MPDUs delivered to stack", pdev->loc_mpdus); 5571 len += scnprintf(buf + len, buf_len - len, "%30s %10d\n", 5572 "Oversized AMSUs", pdev->oversize_amsdu); 5573 len += scnprintf(buf + len, buf_len - len, "%30s %10d\n", 5574 "PHY errors", pdev->phy_errs); 5575 len += scnprintf(buf + len, buf_len - len, "%30s %10d\n", 5576 "PHY errors drops", pdev->phy_err_drop); 5577 len += scnprintf(buf + len, buf_len - len, "%30s %10d\n", 5578 "MPDU errors (FCS, MIC, ENC)", pdev->mpdu_errs); 5579 *length = len; 5580 } 5581 5582 static void 5583 ath11k_wmi_fw_vdev_stats_fill(struct ath11k *ar, 5584 const struct ath11k_fw_stats_vdev *vdev, 5585 char *buf, u32 *length) 5586 { 5587 u32 len = *length; 5588 u32 buf_len = ATH11K_FW_STATS_BUF_SIZE; 5589 struct ath11k_vif *arvif = ath11k_mac_get_arvif(ar, vdev->vdev_id); 5590 u8 *vif_macaddr; 5591 int i; 5592 5593 /* VDEV stats has all the active VDEVs of other PDEVs as well, 5594 * ignoring those not part of requested PDEV 5595 */ 5596 if (!arvif) 5597 return; 5598 5599 vif_macaddr = arvif->vif->addr; 5600 5601 len += scnprintf(buf + len, buf_len - len, "%30s %u\n", 5602 "VDEV ID", vdev->vdev_id); 5603 len += scnprintf(buf + len, buf_len - len, "%30s %pM\n", 5604 "VDEV MAC address", vif_macaddr); 5605 len += scnprintf(buf + len, buf_len - len, "%30s %u\n", 5606 "beacon snr", vdev->beacon_snr); 5607 len += scnprintf(buf + len, buf_len - len, "%30s %u\n", 5608 "data snr", vdev->data_snr); 5609 len += scnprintf(buf + len, buf_len - len, "%30s %u\n", 5610 "num rx frames", vdev->num_rx_frames); 5611 len += scnprintf(buf + len, buf_len - len, "%30s %u\n", 5612 "num rts fail", vdev->num_rts_fail); 5613 len += scnprintf(buf + len, buf_len - len, "%30s %u\n", 5614 "num rts success", vdev->num_rts_success); 5615 len += scnprintf(buf + len, buf_len - len, "%30s %u\n", 5616 "num rx err", vdev->num_rx_err); 5617 len += scnprintf(buf + len, buf_len - len, "%30s %u\n", 5618 "num rx discard", vdev->num_rx_discard); 5619 len += scnprintf(buf + len, buf_len - len, "%30s %u\n", 5620 "num tx not acked", vdev->num_tx_not_acked); 5621 5622 for (i = 0 ; i < ARRAY_SIZE(vdev->num_tx_frames); i++) 5623 len += scnprintf(buf + len, buf_len - len, 5624 "%25s [%02d] %u\n", 5625 "num tx frames", i, 5626 vdev->num_tx_frames[i]); 5627 5628 for (i = 0 ; i < ARRAY_SIZE(vdev->num_tx_frames_retries); i++) 5629 len += scnprintf(buf + len, buf_len - len, 5630 "%25s [%02d] %u\n", 5631 "num tx frames retries", i, 5632 vdev->num_tx_frames_retries[i]); 5633 5634 for (i = 0 ; i < ARRAY_SIZE(vdev->num_tx_frames_failures); i++) 5635 len += scnprintf(buf + len, buf_len - len, 5636 "%25s [%02d] %u\n", 5637 "num tx frames failures", i, 5638 vdev->num_tx_frames_failures[i]); 5639 5640 for (i = 0 ; i < ARRAY_SIZE(vdev->tx_rate_history); i++) 5641 len += scnprintf(buf + len, buf_len - len, 5642 "%25s [%02d] 0x%08x\n", 5643 "tx rate history", i, 5644 vdev->tx_rate_history[i]); 5645 5646 for (i = 0 ; i < ARRAY_SIZE(vdev->beacon_rssi_history); i++) 5647 len += scnprintf(buf + len, buf_len - len, 5648 "%25s [%02d] %u\n", 5649 "beacon rssi history", i, 5650 vdev->beacon_rssi_history[i]); 5651 5652 len += scnprintf(buf + len, buf_len - len, "\n"); 5653 *length = len; 5654 } 5655 5656 static void 5657 ath11k_wmi_fw_bcn_stats_fill(struct ath11k *ar, 5658 const struct ath11k_fw_stats_bcn *bcn, 5659 char *buf, u32 *length) 5660 { 5661 u32 len = *length; 5662 u32 buf_len = ATH11K_FW_STATS_BUF_SIZE; 5663 struct ath11k_vif *arvif = ath11k_mac_get_arvif(ar, bcn->vdev_id); 5664 u8 *vdev_macaddr; 5665 5666 if (!arvif) { 5667 ath11k_warn(ar->ab, "invalid vdev id %d in bcn stats", 5668 bcn->vdev_id); 5669 return; 5670 } 5671 5672 vdev_macaddr = arvif->vif->addr; 5673 5674 len += scnprintf(buf + len, buf_len - len, "%30s %u\n", 5675 "VDEV ID", bcn->vdev_id); 5676 len += scnprintf(buf + len, buf_len - len, "%30s %pM\n", 5677 "VDEV MAC address", vdev_macaddr); 5678 len += scnprintf(buf + len, buf_len - len, "%30s\n\n", 5679 "================"); 5680 len += scnprintf(buf + len, buf_len - len, "%30s %u\n", 5681 "Num of beacon tx success", bcn->tx_bcn_succ_cnt); 5682 len += scnprintf(buf + len, buf_len - len, "%30s %u\n", 5683 "Num of beacon tx failures", bcn->tx_bcn_outage_cnt); 5684 5685 len += scnprintf(buf + len, buf_len - len, "\n"); 5686 *length = len; 5687 } 5688 5689 void ath11k_wmi_fw_stats_fill(struct ath11k *ar, 5690 struct ath11k_fw_stats *fw_stats, 5691 u32 stats_id, char *buf) 5692 { 5693 u32 len = 0; 5694 u32 buf_len = ATH11K_FW_STATS_BUF_SIZE; 5695 const struct ath11k_fw_stats_pdev *pdev; 5696 const struct ath11k_fw_stats_vdev *vdev; 5697 const struct ath11k_fw_stats_bcn *bcn; 5698 size_t num_bcn; 5699 5700 spin_lock_bh(&ar->data_lock); 5701 5702 if (stats_id == WMI_REQUEST_PDEV_STAT) { 5703 pdev = list_first_entry_or_null(&fw_stats->pdevs, 5704 struct ath11k_fw_stats_pdev, list); 5705 if (!pdev) { 5706 ath11k_warn(ar->ab, "failed to get pdev stats\n"); 5707 goto unlock; 5708 } 5709 5710 ath11k_wmi_fw_pdev_base_stats_fill(pdev, buf, &len); 5711 ath11k_wmi_fw_pdev_tx_stats_fill(pdev, buf, &len); 5712 ath11k_wmi_fw_pdev_rx_stats_fill(pdev, buf, &len); 5713 } 5714 5715 if (stats_id == WMI_REQUEST_VDEV_STAT) { 5716 len += scnprintf(buf + len, buf_len - len, "\n"); 5717 len += scnprintf(buf + len, buf_len - len, "%30s\n", 5718 "ath11k VDEV stats"); 5719 len += scnprintf(buf + len, buf_len - len, "%30s\n\n", 5720 "================="); 5721 5722 list_for_each_entry(vdev, &fw_stats->vdevs, list) 5723 ath11k_wmi_fw_vdev_stats_fill(ar, vdev, buf, &len); 5724 } 5725 5726 if (stats_id == WMI_REQUEST_BCN_STAT) { 5727 num_bcn = ath11k_wmi_fw_stats_num_bcn(&fw_stats->bcn); 5728 5729 len += scnprintf(buf + len, buf_len - len, "\n"); 5730 len += scnprintf(buf + len, buf_len - len, "%30s (%zu)\n", 5731 "ath11k Beacon stats", num_bcn); 5732 len += scnprintf(buf + len, buf_len - len, "%30s\n\n", 5733 "==================="); 5734 5735 list_for_each_entry(bcn, &fw_stats->bcn, list) 5736 ath11k_wmi_fw_bcn_stats_fill(ar, bcn, buf, &len); 5737 } 5738 5739 unlock: 5740 spin_unlock_bh(&ar->data_lock); 5741 5742 if (len >= buf_len) 5743 buf[len - 1] = 0; 5744 else 5745 buf[len] = 0; 5746 } 5747 5748 static void ath11k_wmi_op_ep_tx_credits(struct ath11k_base *ab) 5749 { 5750 /* try to send pending beacons first. they take priority */ 5751 wake_up(&ab->wmi_ab.tx_credits_wq); 5752 } 5753 5754 static void ath11k_wmi_htc_tx_complete(struct ath11k_base *ab, 5755 struct sk_buff *skb) 5756 { 5757 dev_kfree_skb(skb); 5758 } 5759 5760 static bool ath11k_reg_is_world_alpha(char *alpha) 5761 { 5762 return alpha[0] == '0' && alpha[1] == '0'; 5763 } 5764 5765 static int ath11k_reg_chan_list_event(struct ath11k_base *ab, struct sk_buff *skb) 5766 { 5767 struct cur_regulatory_info *reg_info = NULL; 5768 struct ieee80211_regdomain *regd = NULL; 5769 bool intersect = false; 5770 int ret = 0, pdev_idx; 5771 struct ath11k *ar; 5772 5773 reg_info = kzalloc(sizeof(*reg_info), GFP_ATOMIC); 5774 if (!reg_info) { 5775 ret = -ENOMEM; 5776 goto fallback; 5777 } 5778 5779 ret = ath11k_pull_reg_chan_list_update_ev(ab, skb, reg_info); 5780 if (ret) { 5781 ath11k_warn(ab, "failed to extract regulatory info from received event\n"); 5782 goto fallback; 5783 } 5784 5785 if (reg_info->status_code != REG_SET_CC_STATUS_PASS) { 5786 /* In case of failure to set the requested ctry, 5787 * fw retains the current regd. We print a failure info 5788 * and return from here. 5789 */ 5790 ath11k_warn(ab, "Failed to set the requested Country regulatory setting\n"); 5791 goto mem_free; 5792 } 5793 5794 pdev_idx = reg_info->phy_id; 5795 5796 if (pdev_idx >= ab->num_radios) { 5797 /* Process the event for phy0 only if single_pdev_only 5798 * is true. If pdev_idx is valid but not 0, discard the 5799 * event. Otherwise, it goes to fallback. 5800 */ 5801 if (ab->hw_params.single_pdev_only && 5802 pdev_idx < ab->hw_params.num_rxmda_per_pdev) 5803 goto mem_free; 5804 else 5805 goto fallback; 5806 } 5807 5808 /* Avoid multiple overwrites to default regd, during core 5809 * stop-start after mac registration. 5810 */ 5811 if (ab->default_regd[pdev_idx] && !ab->new_regd[pdev_idx] && 5812 !memcmp((char *)ab->default_regd[pdev_idx]->alpha2, 5813 (char *)reg_info->alpha2, 2)) 5814 goto mem_free; 5815 5816 /* Intersect new rules with default regd if a new country setting was 5817 * requested, i.e a default regd was already set during initialization 5818 * and the regd coming from this event has a valid country info. 5819 */ 5820 if (ab->default_regd[pdev_idx] && 5821 !ath11k_reg_is_world_alpha((char *) 5822 ab->default_regd[pdev_idx]->alpha2) && 5823 !ath11k_reg_is_world_alpha((char *)reg_info->alpha2)) 5824 intersect = true; 5825 5826 regd = ath11k_reg_build_regd(ab, reg_info, intersect); 5827 if (!regd) { 5828 ath11k_warn(ab, "failed to build regd from reg_info\n"); 5829 goto fallback; 5830 } 5831 5832 spin_lock(&ab->base_lock); 5833 if (test_bit(ATH11K_FLAG_REGISTERED, &ab->dev_flags)) { 5834 /* Once mac is registered, ar is valid and all CC events from 5835 * fw is considered to be received due to user requests 5836 * currently. 5837 * Free previously built regd before assigning the newly 5838 * generated regd to ar. NULL pointer handling will be 5839 * taken care by kfree itself. 5840 */ 5841 ar = ab->pdevs[pdev_idx].ar; 5842 kfree(ab->new_regd[pdev_idx]); 5843 ab->new_regd[pdev_idx] = regd; 5844 ieee80211_queue_work(ar->hw, &ar->regd_update_work); 5845 } else { 5846 /* Multiple events for the same *ar is not expected. But we 5847 * can still clear any previously stored default_regd if we 5848 * are receiving this event for the same radio by mistake. 5849 * NULL pointer handling will be taken care by kfree itself. 5850 */ 5851 kfree(ab->default_regd[pdev_idx]); 5852 /* This regd would be applied during mac registration */ 5853 ab->default_regd[pdev_idx] = regd; 5854 } 5855 ab->dfs_region = reg_info->dfs_region; 5856 spin_unlock(&ab->base_lock); 5857 5858 goto mem_free; 5859 5860 fallback: 5861 /* Fallback to older reg (by sending previous country setting 5862 * again if fw has succeded and we failed to process here. 5863 * The Regdomain should be uniform across driver and fw. Since the 5864 * FW has processed the command and sent a success status, we expect 5865 * this function to succeed as well. If it doesn't, CTRY needs to be 5866 * reverted at the fw and the old SCAN_CHAN_LIST cmd needs to be sent. 5867 */ 5868 /* TODO: This is rare, but still should also be handled */ 5869 WARN_ON(1); 5870 mem_free: 5871 if (reg_info) { 5872 kfree(reg_info->reg_rules_2g_ptr); 5873 kfree(reg_info->reg_rules_5g_ptr); 5874 kfree(reg_info); 5875 } 5876 return ret; 5877 } 5878 5879 static int ath11k_wmi_tlv_rdy_parse(struct ath11k_base *ab, u16 tag, u16 len, 5880 const void *ptr, void *data) 5881 { 5882 struct wmi_tlv_rdy_parse *rdy_parse = data; 5883 struct wmi_ready_event fixed_param; 5884 struct wmi_mac_addr *addr_list; 5885 struct ath11k_pdev *pdev; 5886 u32 num_mac_addr; 5887 int i; 5888 5889 switch (tag) { 5890 case WMI_TAG_READY_EVENT: 5891 memset(&fixed_param, 0, sizeof(fixed_param)); 5892 memcpy(&fixed_param, (struct wmi_ready_event *)ptr, 5893 min_t(u16, sizeof(fixed_param), len)); 5894 ab->wlan_init_status = fixed_param.ready_event_min.status; 5895 rdy_parse->num_extra_mac_addr = 5896 fixed_param.ready_event_min.num_extra_mac_addr; 5897 5898 ether_addr_copy(ab->mac_addr, 5899 fixed_param.ready_event_min.mac_addr.addr); 5900 ab->pktlog_defs_checksum = fixed_param.pktlog_defs_checksum; 5901 ab->wmi_ready = true; 5902 break; 5903 case WMI_TAG_ARRAY_FIXED_STRUCT: 5904 addr_list = (struct wmi_mac_addr *)ptr; 5905 num_mac_addr = rdy_parse->num_extra_mac_addr; 5906 5907 if (!(ab->num_radios > 1 && num_mac_addr >= ab->num_radios)) 5908 break; 5909 5910 for (i = 0; i < ab->num_radios; i++) { 5911 pdev = &ab->pdevs[i]; 5912 ether_addr_copy(pdev->mac_addr, addr_list[i].addr); 5913 } 5914 ab->pdevs_macaddr_valid = true; 5915 break; 5916 default: 5917 break; 5918 } 5919 5920 return 0; 5921 } 5922 5923 static int ath11k_ready_event(struct ath11k_base *ab, struct sk_buff *skb) 5924 { 5925 struct wmi_tlv_rdy_parse rdy_parse = { }; 5926 int ret; 5927 5928 ret = ath11k_wmi_tlv_iter(ab, skb->data, skb->len, 5929 ath11k_wmi_tlv_rdy_parse, &rdy_parse); 5930 if (ret) { 5931 ath11k_warn(ab, "failed to parse tlv %d\n", ret); 5932 return ret; 5933 } 5934 5935 complete(&ab->wmi_ab.unified_ready); 5936 return 0; 5937 } 5938 5939 static void ath11k_peer_delete_resp_event(struct ath11k_base *ab, struct sk_buff *skb) 5940 { 5941 struct wmi_peer_delete_resp_event peer_del_resp; 5942 struct ath11k *ar; 5943 5944 if (ath11k_pull_peer_del_resp_ev(ab, skb, &peer_del_resp) != 0) { 5945 ath11k_warn(ab, "failed to extract peer delete resp"); 5946 return; 5947 } 5948 5949 rcu_read_lock(); 5950 ar = ath11k_mac_get_ar_by_vdev_id(ab, peer_del_resp.vdev_id); 5951 if (!ar) { 5952 ath11k_warn(ab, "invalid vdev id in peer delete resp ev %d", 5953 peer_del_resp.vdev_id); 5954 rcu_read_unlock(); 5955 return; 5956 } 5957 5958 complete(&ar->peer_delete_done); 5959 rcu_read_unlock(); 5960 ath11k_dbg(ab, ATH11K_DBG_WMI, "peer delete resp for vdev id %d addr %pM\n", 5961 peer_del_resp.vdev_id, peer_del_resp.peer_macaddr.addr); 5962 } 5963 5964 static void ath11k_vdev_delete_resp_event(struct ath11k_base *ab, 5965 struct sk_buff *skb) 5966 { 5967 struct ath11k *ar; 5968 u32 vdev_id = 0; 5969 5970 if (ath11k_pull_vdev_del_resp_ev(ab, skb, &vdev_id) != 0) { 5971 ath11k_warn(ab, "failed to extract vdev delete resp"); 5972 return; 5973 } 5974 5975 rcu_read_lock(); 5976 ar = ath11k_mac_get_ar_by_vdev_id(ab, vdev_id); 5977 if (!ar) { 5978 ath11k_warn(ab, "invalid vdev id in vdev delete resp ev %d", 5979 vdev_id); 5980 rcu_read_unlock(); 5981 return; 5982 } 5983 5984 complete(&ar->vdev_delete_done); 5985 5986 rcu_read_unlock(); 5987 5988 ath11k_dbg(ab, ATH11K_DBG_WMI, "vdev delete resp for vdev id %d\n", 5989 vdev_id); 5990 } 5991 5992 static inline const char *ath11k_wmi_vdev_resp_print(u32 vdev_resp_status) 5993 { 5994 switch (vdev_resp_status) { 5995 case WMI_VDEV_START_RESPONSE_INVALID_VDEVID: 5996 return "invalid vdev id"; 5997 case WMI_VDEV_START_RESPONSE_NOT_SUPPORTED: 5998 return "not supported"; 5999 case WMI_VDEV_START_RESPONSE_DFS_VIOLATION: 6000 return "dfs violation"; 6001 case WMI_VDEV_START_RESPONSE_INVALID_REGDOMAIN: 6002 return "invalid regdomain"; 6003 default: 6004 return "unknown"; 6005 } 6006 } 6007 6008 static void ath11k_vdev_start_resp_event(struct ath11k_base *ab, struct sk_buff *skb) 6009 { 6010 struct wmi_vdev_start_resp_event vdev_start_resp; 6011 struct ath11k *ar; 6012 u32 status; 6013 6014 if (ath11k_pull_vdev_start_resp_tlv(ab, skb, &vdev_start_resp) != 0) { 6015 ath11k_warn(ab, "failed to extract vdev start resp"); 6016 return; 6017 } 6018 6019 rcu_read_lock(); 6020 ar = ath11k_mac_get_ar_by_vdev_id(ab, vdev_start_resp.vdev_id); 6021 if (!ar) { 6022 ath11k_warn(ab, "invalid vdev id in vdev start resp ev %d", 6023 vdev_start_resp.vdev_id); 6024 rcu_read_unlock(); 6025 return; 6026 } 6027 6028 ar->last_wmi_vdev_start_status = 0; 6029 6030 status = vdev_start_resp.status; 6031 6032 if (WARN_ON_ONCE(status)) { 6033 ath11k_warn(ab, "vdev start resp error status %d (%s)\n", 6034 status, ath11k_wmi_vdev_resp_print(status)); 6035 ar->last_wmi_vdev_start_status = status; 6036 } 6037 6038 complete(&ar->vdev_setup_done); 6039 6040 rcu_read_unlock(); 6041 6042 ath11k_dbg(ab, ATH11K_DBG_WMI, "vdev start resp for vdev id %d", 6043 vdev_start_resp.vdev_id); 6044 } 6045 6046 static void ath11k_bcn_tx_status_event(struct ath11k_base *ab, struct sk_buff *skb) 6047 { 6048 u32 vdev_id, tx_status; 6049 6050 if (ath11k_pull_bcn_tx_status_ev(ab, skb->data, skb->len, 6051 &vdev_id, &tx_status) != 0) { 6052 ath11k_warn(ab, "failed to extract bcn tx status"); 6053 return; 6054 } 6055 } 6056 6057 static void ath11k_vdev_stopped_event(struct ath11k_base *ab, struct sk_buff *skb) 6058 { 6059 struct ath11k *ar; 6060 u32 vdev_id = 0; 6061 6062 if (ath11k_pull_vdev_stopped_param_tlv(ab, skb, &vdev_id) != 0) { 6063 ath11k_warn(ab, "failed to extract vdev stopped event"); 6064 return; 6065 } 6066 6067 rcu_read_lock(); 6068 ar = ath11k_mac_get_ar_by_vdev_id(ab, vdev_id); 6069 if (!ar) { 6070 ath11k_warn(ab, "invalid vdev id in vdev stopped ev %d", 6071 vdev_id); 6072 rcu_read_unlock(); 6073 return; 6074 } 6075 6076 complete(&ar->vdev_setup_done); 6077 6078 rcu_read_unlock(); 6079 6080 ath11k_dbg(ab, ATH11K_DBG_WMI, "vdev stopped for vdev id %d", vdev_id); 6081 } 6082 6083 static void ath11k_mgmt_rx_event(struct ath11k_base *ab, struct sk_buff *skb) 6084 { 6085 struct mgmt_rx_event_params rx_ev = {0}; 6086 struct ath11k *ar; 6087 struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb); 6088 struct ieee80211_hdr *hdr; 6089 u16 fc; 6090 struct ieee80211_supported_band *sband; 6091 6092 if (ath11k_pull_mgmt_rx_params_tlv(ab, skb, &rx_ev) != 0) { 6093 ath11k_warn(ab, "failed to extract mgmt rx event"); 6094 dev_kfree_skb(skb); 6095 return; 6096 } 6097 6098 memset(status, 0, sizeof(*status)); 6099 6100 ath11k_dbg(ab, ATH11K_DBG_MGMT, "mgmt rx event status %08x\n", 6101 rx_ev.status); 6102 6103 rcu_read_lock(); 6104 ar = ath11k_mac_get_ar_by_pdev_id(ab, rx_ev.pdev_id); 6105 6106 if (!ar) { 6107 ath11k_warn(ab, "invalid pdev_id %d in mgmt_rx_event\n", 6108 rx_ev.pdev_id); 6109 dev_kfree_skb(skb); 6110 goto exit; 6111 } 6112 6113 if ((test_bit(ATH11K_CAC_RUNNING, &ar->dev_flags)) || 6114 (rx_ev.status & (WMI_RX_STATUS_ERR_DECRYPT | 6115 WMI_RX_STATUS_ERR_KEY_CACHE_MISS | WMI_RX_STATUS_ERR_CRC))) { 6116 dev_kfree_skb(skb); 6117 goto exit; 6118 } 6119 6120 if (rx_ev.status & WMI_RX_STATUS_ERR_MIC) 6121 status->flag |= RX_FLAG_MMIC_ERROR; 6122 6123 if (rx_ev.chan_freq >= ATH11K_MIN_6G_FREQ) { 6124 status->band = NL80211_BAND_6GHZ; 6125 } else if (rx_ev.channel >= 1 && rx_ev.channel <= 14) { 6126 status->band = NL80211_BAND_2GHZ; 6127 } else if (rx_ev.channel >= 36 && rx_ev.channel <= ATH11K_MAX_5G_CHAN) { 6128 status->band = NL80211_BAND_5GHZ; 6129 } else { 6130 /* Shouldn't happen unless list of advertised channels to 6131 * mac80211 has been changed. 6132 */ 6133 WARN_ON_ONCE(1); 6134 dev_kfree_skb(skb); 6135 goto exit; 6136 } 6137 6138 if (rx_ev.phy_mode == MODE_11B && 6139 (status->band == NL80211_BAND_5GHZ || status->band == NL80211_BAND_6GHZ)) 6140 ath11k_dbg(ab, ATH11K_DBG_WMI, 6141 "wmi mgmt rx 11b (CCK) on 5/6GHz, band = %d\n", status->band); 6142 6143 sband = &ar->mac.sbands[status->band]; 6144 6145 status->freq = ieee80211_channel_to_frequency(rx_ev.channel, 6146 status->band); 6147 status->signal = rx_ev.snr + ATH11K_DEFAULT_NOISE_FLOOR; 6148 status->rate_idx = ath11k_mac_bitrate_to_idx(sband, rx_ev.rate / 100); 6149 6150 hdr = (struct ieee80211_hdr *)skb->data; 6151 fc = le16_to_cpu(hdr->frame_control); 6152 6153 /* Firmware is guaranteed to report all essential management frames via 6154 * WMI while it can deliver some extra via HTT. Since there can be 6155 * duplicates split the reporting wrt monitor/sniffing. 6156 */ 6157 status->flag |= RX_FLAG_SKIP_MONITOR; 6158 6159 /* In case of PMF, FW delivers decrypted frames with Protected Bit set. 6160 * Don't clear that. Also, FW delivers broadcast management frames 6161 * (ex: group privacy action frames in mesh) as encrypted payload. 6162 */ 6163 if (ieee80211_has_protected(hdr->frame_control) && 6164 !is_multicast_ether_addr(ieee80211_get_DA(hdr))) { 6165 status->flag |= RX_FLAG_DECRYPTED; 6166 6167 if (!ieee80211_is_robust_mgmt_frame(skb)) { 6168 status->flag |= RX_FLAG_IV_STRIPPED | 6169 RX_FLAG_MMIC_STRIPPED; 6170 hdr->frame_control = __cpu_to_le16(fc & 6171 ~IEEE80211_FCTL_PROTECTED); 6172 } 6173 } 6174 6175 if (ieee80211_is_beacon(hdr->frame_control)) 6176 ath11k_mac_handle_beacon(ar, skb); 6177 6178 ath11k_dbg(ab, ATH11K_DBG_MGMT, 6179 "event mgmt rx skb %pK len %d ftype %02x stype %02x\n", 6180 skb, skb->len, 6181 fc & IEEE80211_FCTL_FTYPE, fc & IEEE80211_FCTL_STYPE); 6182 6183 ath11k_dbg(ab, ATH11K_DBG_MGMT, 6184 "event mgmt rx freq %d band %d snr %d, rate_idx %d\n", 6185 status->freq, status->band, status->signal, 6186 status->rate_idx); 6187 6188 ieee80211_rx_ni(ar->hw, skb); 6189 6190 exit: 6191 rcu_read_unlock(); 6192 } 6193 6194 static void ath11k_mgmt_tx_compl_event(struct ath11k_base *ab, struct sk_buff *skb) 6195 { 6196 struct wmi_mgmt_tx_compl_event tx_compl_param = {0}; 6197 struct ath11k *ar; 6198 6199 if (ath11k_pull_mgmt_tx_compl_param_tlv(ab, skb, &tx_compl_param) != 0) { 6200 ath11k_warn(ab, "failed to extract mgmt tx compl event"); 6201 return; 6202 } 6203 6204 rcu_read_lock(); 6205 ar = ath11k_mac_get_ar_by_pdev_id(ab, tx_compl_param.pdev_id); 6206 if (!ar) { 6207 ath11k_warn(ab, "invalid pdev id %d in mgmt_tx_compl_event\n", 6208 tx_compl_param.pdev_id); 6209 goto exit; 6210 } 6211 6212 wmi_process_mgmt_tx_comp(ar, tx_compl_param.desc_id, 6213 tx_compl_param.status); 6214 6215 ath11k_dbg(ab, ATH11K_DBG_MGMT, 6216 "mgmt tx compl ev pdev_id %d, desc_id %d, status %d", 6217 tx_compl_param.pdev_id, tx_compl_param.desc_id, 6218 tx_compl_param.status); 6219 6220 exit: 6221 rcu_read_unlock(); 6222 } 6223 6224 static struct ath11k *ath11k_get_ar_on_scan_abort(struct ath11k_base *ab, 6225 u32 vdev_id) 6226 { 6227 int i; 6228 struct ath11k_pdev *pdev; 6229 struct ath11k *ar; 6230 6231 for (i = 0; i < ab->num_radios; i++) { 6232 pdev = rcu_dereference(ab->pdevs_active[i]); 6233 if (pdev && pdev->ar) { 6234 ar = pdev->ar; 6235 6236 spin_lock_bh(&ar->data_lock); 6237 if (ar->scan.state == ATH11K_SCAN_ABORTING && 6238 ar->scan.vdev_id == vdev_id) { 6239 spin_unlock_bh(&ar->data_lock); 6240 return ar; 6241 } 6242 spin_unlock_bh(&ar->data_lock); 6243 } 6244 } 6245 return NULL; 6246 } 6247 6248 static void ath11k_scan_event(struct ath11k_base *ab, struct sk_buff *skb) 6249 { 6250 struct ath11k *ar; 6251 struct wmi_scan_event scan_ev = {0}; 6252 6253 if (ath11k_pull_scan_ev(ab, skb, &scan_ev) != 0) { 6254 ath11k_warn(ab, "failed to extract scan event"); 6255 return; 6256 } 6257 6258 rcu_read_lock(); 6259 6260 /* In case the scan was cancelled, ex. during interface teardown, 6261 * the interface will not be found in active interfaces. 6262 * Rather, in such scenarios, iterate over the active pdev's to 6263 * search 'ar' if the corresponding 'ar' scan is ABORTING and the 6264 * aborting scan's vdev id matches this event info. 6265 */ 6266 if (scan_ev.event_type == WMI_SCAN_EVENT_COMPLETED && 6267 scan_ev.reason == WMI_SCAN_REASON_CANCELLED) 6268 ar = ath11k_get_ar_on_scan_abort(ab, scan_ev.vdev_id); 6269 else 6270 ar = ath11k_mac_get_ar_by_vdev_id(ab, scan_ev.vdev_id); 6271 6272 if (!ar) { 6273 ath11k_warn(ab, "Received scan event for unknown vdev"); 6274 rcu_read_unlock(); 6275 return; 6276 } 6277 6278 spin_lock_bh(&ar->data_lock); 6279 6280 ath11k_dbg(ab, ATH11K_DBG_WMI, 6281 "scan event %s type %d reason %d freq %d req_id %d scan_id %d vdev_id %d state %s (%d)\n", 6282 ath11k_wmi_event_scan_type_str(scan_ev.event_type, scan_ev.reason), 6283 scan_ev.event_type, scan_ev.reason, scan_ev.channel_freq, 6284 scan_ev.scan_req_id, scan_ev.scan_id, scan_ev.vdev_id, 6285 ath11k_scan_state_str(ar->scan.state), ar->scan.state); 6286 6287 switch (scan_ev.event_type) { 6288 case WMI_SCAN_EVENT_STARTED: 6289 ath11k_wmi_event_scan_started(ar); 6290 break; 6291 case WMI_SCAN_EVENT_COMPLETED: 6292 ath11k_wmi_event_scan_completed(ar); 6293 break; 6294 case WMI_SCAN_EVENT_BSS_CHANNEL: 6295 ath11k_wmi_event_scan_bss_chan(ar); 6296 break; 6297 case WMI_SCAN_EVENT_FOREIGN_CHAN: 6298 ath11k_wmi_event_scan_foreign_chan(ar, scan_ev.channel_freq); 6299 break; 6300 case WMI_SCAN_EVENT_START_FAILED: 6301 ath11k_warn(ab, "received scan start failure event\n"); 6302 ath11k_wmi_event_scan_start_failed(ar); 6303 break; 6304 case WMI_SCAN_EVENT_DEQUEUED: 6305 case WMI_SCAN_EVENT_PREEMPTED: 6306 case WMI_SCAN_EVENT_RESTARTED: 6307 case WMI_SCAN_EVENT_FOREIGN_CHAN_EXIT: 6308 default: 6309 break; 6310 } 6311 6312 spin_unlock_bh(&ar->data_lock); 6313 6314 rcu_read_unlock(); 6315 } 6316 6317 static void ath11k_peer_sta_kickout_event(struct ath11k_base *ab, struct sk_buff *skb) 6318 { 6319 struct wmi_peer_sta_kickout_arg arg = {}; 6320 struct ieee80211_sta *sta; 6321 struct ath11k_peer *peer; 6322 struct ath11k *ar; 6323 6324 if (ath11k_pull_peer_sta_kickout_ev(ab, skb, &arg) != 0) { 6325 ath11k_warn(ab, "failed to extract peer sta kickout event"); 6326 return; 6327 } 6328 6329 rcu_read_lock(); 6330 6331 spin_lock_bh(&ab->base_lock); 6332 6333 peer = ath11k_peer_find_by_addr(ab, arg.mac_addr); 6334 6335 if (!peer) { 6336 ath11k_warn(ab, "peer not found %pM\n", 6337 arg.mac_addr); 6338 goto exit; 6339 } 6340 6341 ar = ath11k_mac_get_ar_by_vdev_id(ab, peer->vdev_id); 6342 if (!ar) { 6343 ath11k_warn(ab, "invalid vdev id in peer sta kickout ev %d", 6344 peer->vdev_id); 6345 goto exit; 6346 } 6347 6348 sta = ieee80211_find_sta_by_ifaddr(ar->hw, 6349 arg.mac_addr, NULL); 6350 if (!sta) { 6351 ath11k_warn(ab, "Spurious quick kickout for STA %pM\n", 6352 arg.mac_addr); 6353 goto exit; 6354 } 6355 6356 ath11k_dbg(ab, ATH11K_DBG_WMI, "peer sta kickout event %pM", 6357 arg.mac_addr); 6358 6359 ieee80211_report_low_ack(sta, 10); 6360 6361 exit: 6362 spin_unlock_bh(&ab->base_lock); 6363 rcu_read_unlock(); 6364 } 6365 6366 static void ath11k_roam_event(struct ath11k_base *ab, struct sk_buff *skb) 6367 { 6368 struct wmi_roam_event roam_ev = {}; 6369 struct ath11k *ar; 6370 6371 if (ath11k_pull_roam_ev(ab, skb, &roam_ev) != 0) { 6372 ath11k_warn(ab, "failed to extract roam event"); 6373 return; 6374 } 6375 6376 ath11k_dbg(ab, ATH11K_DBG_WMI, 6377 "wmi roam event vdev %u reason 0x%08x rssi %d\n", 6378 roam_ev.vdev_id, roam_ev.reason, roam_ev.rssi); 6379 6380 rcu_read_lock(); 6381 ar = ath11k_mac_get_ar_by_vdev_id(ab, roam_ev.vdev_id); 6382 if (!ar) { 6383 ath11k_warn(ab, "invalid vdev id in roam ev %d", 6384 roam_ev.vdev_id); 6385 rcu_read_unlock(); 6386 return; 6387 } 6388 6389 if (roam_ev.reason >= WMI_ROAM_REASON_MAX) 6390 ath11k_warn(ab, "ignoring unknown roam event reason %d on vdev %i\n", 6391 roam_ev.reason, roam_ev.vdev_id); 6392 6393 switch (roam_ev.reason) { 6394 case WMI_ROAM_REASON_BEACON_MISS: 6395 ath11k_mac_handle_beacon_miss(ar, roam_ev.vdev_id); 6396 break; 6397 case WMI_ROAM_REASON_BETTER_AP: 6398 case WMI_ROAM_REASON_LOW_RSSI: 6399 case WMI_ROAM_REASON_SUITABLE_AP_FOUND: 6400 case WMI_ROAM_REASON_HO_FAILED: 6401 ath11k_warn(ab, "ignoring not implemented roam event reason %d on vdev %i\n", 6402 roam_ev.reason, roam_ev.vdev_id); 6403 break; 6404 } 6405 6406 rcu_read_unlock(); 6407 } 6408 6409 static void ath11k_chan_info_event(struct ath11k_base *ab, struct sk_buff *skb) 6410 { 6411 struct wmi_chan_info_event ch_info_ev = {0}; 6412 struct ath11k *ar; 6413 struct survey_info *survey; 6414 int idx; 6415 /* HW channel counters frequency value in hertz */ 6416 u32 cc_freq_hz = ab->cc_freq_hz; 6417 6418 if (ath11k_pull_chan_info_ev(ab, skb->data, skb->len, &ch_info_ev) != 0) { 6419 ath11k_warn(ab, "failed to extract chan info event"); 6420 return; 6421 } 6422 6423 ath11k_dbg(ab, ATH11K_DBG_WMI, 6424 "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", 6425 ch_info_ev.vdev_id, ch_info_ev.err_code, ch_info_ev.freq, 6426 ch_info_ev.cmd_flags, ch_info_ev.noise_floor, 6427 ch_info_ev.rx_clear_count, ch_info_ev.cycle_count, 6428 ch_info_ev.mac_clk_mhz); 6429 6430 if (ch_info_ev.cmd_flags == WMI_CHAN_INFO_END_RESP) { 6431 ath11k_dbg(ab, ATH11K_DBG_WMI, "chan info report completed\n"); 6432 return; 6433 } 6434 6435 rcu_read_lock(); 6436 ar = ath11k_mac_get_ar_by_vdev_id(ab, ch_info_ev.vdev_id); 6437 if (!ar) { 6438 ath11k_warn(ab, "invalid vdev id in chan info ev %d", 6439 ch_info_ev.vdev_id); 6440 rcu_read_unlock(); 6441 return; 6442 } 6443 spin_lock_bh(&ar->data_lock); 6444 6445 switch (ar->scan.state) { 6446 case ATH11K_SCAN_IDLE: 6447 case ATH11K_SCAN_STARTING: 6448 ath11k_warn(ab, "received chan info event without a scan request, ignoring\n"); 6449 goto exit; 6450 case ATH11K_SCAN_RUNNING: 6451 case ATH11K_SCAN_ABORTING: 6452 break; 6453 } 6454 6455 idx = freq_to_idx(ar, ch_info_ev.freq); 6456 if (idx >= ARRAY_SIZE(ar->survey)) { 6457 ath11k_warn(ab, "chan info: invalid frequency %d (idx %d out of bounds)\n", 6458 ch_info_ev.freq, idx); 6459 goto exit; 6460 } 6461 6462 /* If FW provides MAC clock frequency in Mhz, overriding the initialized 6463 * HW channel counters frequency value 6464 */ 6465 if (ch_info_ev.mac_clk_mhz) 6466 cc_freq_hz = (ch_info_ev.mac_clk_mhz * 1000); 6467 6468 if (ch_info_ev.cmd_flags == WMI_CHAN_INFO_START_RESP) { 6469 survey = &ar->survey[idx]; 6470 memset(survey, 0, sizeof(*survey)); 6471 survey->noise = ch_info_ev.noise_floor; 6472 survey->filled = SURVEY_INFO_NOISE_DBM | SURVEY_INFO_TIME | 6473 SURVEY_INFO_TIME_BUSY; 6474 survey->time = div_u64(ch_info_ev.cycle_count, cc_freq_hz); 6475 survey->time_busy = div_u64(ch_info_ev.rx_clear_count, cc_freq_hz); 6476 } 6477 exit: 6478 spin_unlock_bh(&ar->data_lock); 6479 rcu_read_unlock(); 6480 } 6481 6482 static void 6483 ath11k_pdev_bss_chan_info_event(struct ath11k_base *ab, struct sk_buff *skb) 6484 { 6485 struct wmi_pdev_bss_chan_info_event bss_ch_info_ev = {}; 6486 struct survey_info *survey; 6487 struct ath11k *ar; 6488 u32 cc_freq_hz = ab->cc_freq_hz; 6489 u64 busy, total, tx, rx, rx_bss; 6490 int idx; 6491 6492 if (ath11k_pull_pdev_bss_chan_info_ev(ab, skb, &bss_ch_info_ev) != 0) { 6493 ath11k_warn(ab, "failed to extract pdev bss chan info event"); 6494 return; 6495 } 6496 6497 busy = (u64)(bss_ch_info_ev.rx_clear_count_high) << 32 | 6498 bss_ch_info_ev.rx_clear_count_low; 6499 6500 total = (u64)(bss_ch_info_ev.cycle_count_high) << 32 | 6501 bss_ch_info_ev.cycle_count_low; 6502 6503 tx = (u64)(bss_ch_info_ev.tx_cycle_count_high) << 32 | 6504 bss_ch_info_ev.tx_cycle_count_low; 6505 6506 rx = (u64)(bss_ch_info_ev.rx_cycle_count_high) << 32 | 6507 bss_ch_info_ev.rx_cycle_count_low; 6508 6509 rx_bss = (u64)(bss_ch_info_ev.rx_bss_cycle_count_high) << 32 | 6510 bss_ch_info_ev.rx_bss_cycle_count_low; 6511 6512 ath11k_dbg(ab, ATH11K_DBG_WMI, 6513 "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", 6514 bss_ch_info_ev.pdev_id, bss_ch_info_ev.freq, 6515 bss_ch_info_ev.noise_floor, busy, total, 6516 tx, rx, rx_bss); 6517 6518 rcu_read_lock(); 6519 ar = ath11k_mac_get_ar_by_pdev_id(ab, bss_ch_info_ev.pdev_id); 6520 6521 if (!ar) { 6522 ath11k_warn(ab, "invalid pdev id %d in bss_chan_info event\n", 6523 bss_ch_info_ev.pdev_id); 6524 rcu_read_unlock(); 6525 return; 6526 } 6527 6528 spin_lock_bh(&ar->data_lock); 6529 idx = freq_to_idx(ar, bss_ch_info_ev.freq); 6530 if (idx >= ARRAY_SIZE(ar->survey)) { 6531 ath11k_warn(ab, "bss chan info: invalid frequency %d (idx %d out of bounds)\n", 6532 bss_ch_info_ev.freq, idx); 6533 goto exit; 6534 } 6535 6536 survey = &ar->survey[idx]; 6537 6538 survey->noise = bss_ch_info_ev.noise_floor; 6539 survey->time = div_u64(total, cc_freq_hz); 6540 survey->time_busy = div_u64(busy, cc_freq_hz); 6541 survey->time_rx = div_u64(rx_bss, cc_freq_hz); 6542 survey->time_tx = div_u64(tx, cc_freq_hz); 6543 survey->filled |= (SURVEY_INFO_NOISE_DBM | 6544 SURVEY_INFO_TIME | 6545 SURVEY_INFO_TIME_BUSY | 6546 SURVEY_INFO_TIME_RX | 6547 SURVEY_INFO_TIME_TX); 6548 exit: 6549 spin_unlock_bh(&ar->data_lock); 6550 complete(&ar->bss_survey_done); 6551 6552 rcu_read_unlock(); 6553 } 6554 6555 static void ath11k_vdev_install_key_compl_event(struct ath11k_base *ab, 6556 struct sk_buff *skb) 6557 { 6558 struct wmi_vdev_install_key_complete_arg install_key_compl = {0}; 6559 struct ath11k *ar; 6560 6561 if (ath11k_pull_vdev_install_key_compl_ev(ab, skb, &install_key_compl) != 0) { 6562 ath11k_warn(ab, "failed to extract install key compl event"); 6563 return; 6564 } 6565 6566 ath11k_dbg(ab, ATH11K_DBG_WMI, 6567 "vdev install key ev idx %d flags %08x macaddr %pM status %d\n", 6568 install_key_compl.key_idx, install_key_compl.key_flags, 6569 install_key_compl.macaddr, install_key_compl.status); 6570 6571 rcu_read_lock(); 6572 ar = ath11k_mac_get_ar_by_vdev_id(ab, install_key_compl.vdev_id); 6573 if (!ar) { 6574 ath11k_warn(ab, "invalid vdev id in install key compl ev %d", 6575 install_key_compl.vdev_id); 6576 rcu_read_unlock(); 6577 return; 6578 } 6579 6580 ar->install_key_status = 0; 6581 6582 if (install_key_compl.status != WMI_VDEV_INSTALL_KEY_COMPL_STATUS_SUCCESS) { 6583 ath11k_warn(ab, "install key failed for %pM status %d\n", 6584 install_key_compl.macaddr, install_key_compl.status); 6585 ar->install_key_status = install_key_compl.status; 6586 } 6587 6588 complete(&ar->install_key_done); 6589 rcu_read_unlock(); 6590 } 6591 6592 static void ath11k_service_available_event(struct ath11k_base *ab, struct sk_buff *skb) 6593 { 6594 const void **tb; 6595 const struct wmi_service_available_event *ev; 6596 int ret; 6597 int i, j; 6598 6599 tb = ath11k_wmi_tlv_parse_alloc(ab, skb->data, skb->len, GFP_ATOMIC); 6600 if (IS_ERR(tb)) { 6601 ret = PTR_ERR(tb); 6602 ath11k_warn(ab, "failed to parse tlv: %d\n", ret); 6603 return; 6604 } 6605 6606 ev = tb[WMI_TAG_SERVICE_AVAILABLE_EVENT]; 6607 if (!ev) { 6608 ath11k_warn(ab, "failed to fetch svc available ev"); 6609 kfree(tb); 6610 return; 6611 } 6612 6613 /* TODO: Use wmi_service_segment_offset information to get the service 6614 * especially when more services are advertised in multiple sevice 6615 * available events. 6616 */ 6617 for (i = 0, j = WMI_MAX_SERVICE; 6618 i < WMI_SERVICE_SEGMENT_BM_SIZE32 && j < WMI_MAX_EXT_SERVICE; 6619 i++) { 6620 do { 6621 if (ev->wmi_service_segment_bitmap[i] & 6622 BIT(j % WMI_AVAIL_SERVICE_BITS_IN_SIZE32)) 6623 set_bit(j, ab->wmi_ab.svc_map); 6624 } while (++j % WMI_AVAIL_SERVICE_BITS_IN_SIZE32); 6625 } 6626 6627 ath11k_dbg(ab, ATH11K_DBG_WMI, 6628 "wmi_ext_service_bitmap 0:0x%x, 1:0x%x, 2:0x%x, 3:0x%x", 6629 ev->wmi_service_segment_bitmap[0], ev->wmi_service_segment_bitmap[1], 6630 ev->wmi_service_segment_bitmap[2], ev->wmi_service_segment_bitmap[3]); 6631 6632 kfree(tb); 6633 } 6634 6635 static void ath11k_peer_assoc_conf_event(struct ath11k_base *ab, struct sk_buff *skb) 6636 { 6637 struct wmi_peer_assoc_conf_arg peer_assoc_conf = {0}; 6638 struct ath11k *ar; 6639 6640 if (ath11k_pull_peer_assoc_conf_ev(ab, skb, &peer_assoc_conf) != 0) { 6641 ath11k_warn(ab, "failed to extract peer assoc conf event"); 6642 return; 6643 } 6644 6645 ath11k_dbg(ab, ATH11K_DBG_WMI, 6646 "peer assoc conf ev vdev id %d macaddr %pM\n", 6647 peer_assoc_conf.vdev_id, peer_assoc_conf.macaddr); 6648 6649 rcu_read_lock(); 6650 ar = ath11k_mac_get_ar_by_vdev_id(ab, peer_assoc_conf.vdev_id); 6651 6652 if (!ar) { 6653 ath11k_warn(ab, "invalid vdev id in peer assoc conf ev %d", 6654 peer_assoc_conf.vdev_id); 6655 rcu_read_unlock(); 6656 return; 6657 } 6658 6659 complete(&ar->peer_assoc_done); 6660 rcu_read_unlock(); 6661 } 6662 6663 static void ath11k_update_stats_event(struct ath11k_base *ab, struct sk_buff *skb) 6664 { 6665 ath11k_debugfs_fw_stats_process(ab, skb); 6666 } 6667 6668 /* PDEV_CTL_FAILSAFE_CHECK_EVENT is received from FW when the frequency scanned 6669 * is not part of BDF CTL(Conformance test limits) table entries. 6670 */ 6671 static void ath11k_pdev_ctl_failsafe_check_event(struct ath11k_base *ab, 6672 struct sk_buff *skb) 6673 { 6674 const void **tb; 6675 const struct wmi_pdev_ctl_failsafe_chk_event *ev; 6676 int ret; 6677 6678 tb = ath11k_wmi_tlv_parse_alloc(ab, skb->data, skb->len, GFP_ATOMIC); 6679 if (IS_ERR(tb)) { 6680 ret = PTR_ERR(tb); 6681 ath11k_warn(ab, "failed to parse tlv: %d\n", ret); 6682 return; 6683 } 6684 6685 ev = tb[WMI_TAG_PDEV_CTL_FAILSAFE_CHECK_EVENT]; 6686 if (!ev) { 6687 ath11k_warn(ab, "failed to fetch pdev ctl failsafe check ev"); 6688 kfree(tb); 6689 return; 6690 } 6691 6692 ath11k_dbg(ab, ATH11K_DBG_WMI, 6693 "pdev ctl failsafe check ev status %d\n", 6694 ev->ctl_failsafe_status); 6695 6696 /* If ctl_failsafe_status is set to 1 FW will max out the Transmit power 6697 * to 10 dBm else the CTL power entry in the BDF would be picked up. 6698 */ 6699 if (ev->ctl_failsafe_status != 0) 6700 ath11k_warn(ab, "pdev ctl failsafe failure status %d", 6701 ev->ctl_failsafe_status); 6702 6703 kfree(tb); 6704 } 6705 6706 static void 6707 ath11k_wmi_process_csa_switch_count_event(struct ath11k_base *ab, 6708 const struct wmi_pdev_csa_switch_ev *ev, 6709 const u32 *vdev_ids) 6710 { 6711 int i; 6712 struct ath11k_vif *arvif; 6713 6714 /* Finish CSA once the switch count becomes NULL */ 6715 if (ev->current_switch_count) 6716 return; 6717 6718 rcu_read_lock(); 6719 for (i = 0; i < ev->num_vdevs; i++) { 6720 arvif = ath11k_mac_get_arvif_by_vdev_id(ab, vdev_ids[i]); 6721 6722 if (!arvif) { 6723 ath11k_warn(ab, "Recvd csa status for unknown vdev %d", 6724 vdev_ids[i]); 6725 continue; 6726 } 6727 6728 if (arvif->is_up && arvif->vif->csa_active) 6729 ieee80211_csa_finish(arvif->vif); 6730 } 6731 rcu_read_unlock(); 6732 } 6733 6734 static void 6735 ath11k_wmi_pdev_csa_switch_count_status_event(struct ath11k_base *ab, 6736 struct sk_buff *skb) 6737 { 6738 const void **tb; 6739 const struct wmi_pdev_csa_switch_ev *ev; 6740 const u32 *vdev_ids; 6741 int ret; 6742 6743 tb = ath11k_wmi_tlv_parse_alloc(ab, skb->data, skb->len, GFP_ATOMIC); 6744 if (IS_ERR(tb)) { 6745 ret = PTR_ERR(tb); 6746 ath11k_warn(ab, "failed to parse tlv: %d\n", ret); 6747 return; 6748 } 6749 6750 ev = tb[WMI_TAG_PDEV_CSA_SWITCH_COUNT_STATUS_EVENT]; 6751 vdev_ids = tb[WMI_TAG_ARRAY_UINT32]; 6752 6753 if (!ev || !vdev_ids) { 6754 ath11k_warn(ab, "failed to fetch pdev csa switch count ev"); 6755 kfree(tb); 6756 return; 6757 } 6758 6759 ath11k_dbg(ab, ATH11K_DBG_WMI, 6760 "pdev csa switch count %d for pdev %d, num_vdevs %d", 6761 ev->current_switch_count, ev->pdev_id, 6762 ev->num_vdevs); 6763 6764 ath11k_wmi_process_csa_switch_count_event(ab, ev, vdev_ids); 6765 6766 kfree(tb); 6767 } 6768 6769 static void 6770 ath11k_wmi_pdev_dfs_radar_detected_event(struct ath11k_base *ab, struct sk_buff *skb) 6771 { 6772 const void **tb; 6773 const struct wmi_pdev_radar_ev *ev; 6774 struct ath11k *ar; 6775 int ret; 6776 6777 tb = ath11k_wmi_tlv_parse_alloc(ab, skb->data, skb->len, GFP_ATOMIC); 6778 if (IS_ERR(tb)) { 6779 ret = PTR_ERR(tb); 6780 ath11k_warn(ab, "failed to parse tlv: %d\n", ret); 6781 return; 6782 } 6783 6784 ev = tb[WMI_TAG_PDEV_DFS_RADAR_DETECTION_EVENT]; 6785 6786 if (!ev) { 6787 ath11k_warn(ab, "failed to fetch pdev dfs radar detected ev"); 6788 kfree(tb); 6789 return; 6790 } 6791 6792 ath11k_dbg(ab, ATH11K_DBG_WMI, 6793 "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", 6794 ev->pdev_id, ev->detection_mode, ev->chan_freq, ev->chan_width, 6795 ev->detector_id, ev->segment_id, ev->timestamp, ev->is_chirp, 6796 ev->freq_offset, ev->sidx); 6797 6798 ar = ath11k_mac_get_ar_by_pdev_id(ab, ev->pdev_id); 6799 6800 if (!ar) { 6801 ath11k_warn(ab, "radar detected in invalid pdev %d\n", 6802 ev->pdev_id); 6803 goto exit; 6804 } 6805 6806 ath11k_dbg(ar->ab, ATH11K_DBG_REG, "DFS Radar Detected in pdev %d\n", 6807 ev->pdev_id); 6808 6809 if (ar->dfs_block_radar_events) 6810 ath11k_info(ab, "DFS Radar detected, but ignored as requested\n"); 6811 else 6812 ieee80211_radar_detected(ar->hw); 6813 6814 exit: 6815 kfree(tb); 6816 } 6817 6818 static void 6819 ath11k_wmi_pdev_temperature_event(struct ath11k_base *ab, 6820 struct sk_buff *skb) 6821 { 6822 struct ath11k *ar; 6823 const void **tb; 6824 const struct wmi_pdev_temperature_event *ev; 6825 int ret; 6826 6827 tb = ath11k_wmi_tlv_parse_alloc(ab, skb->data, skb->len, GFP_ATOMIC); 6828 if (IS_ERR(tb)) { 6829 ret = PTR_ERR(tb); 6830 ath11k_warn(ab, "failed to parse tlv: %d\n", ret); 6831 return; 6832 } 6833 6834 ev = tb[WMI_TAG_PDEV_TEMPERATURE_EVENT]; 6835 if (!ev) { 6836 ath11k_warn(ab, "failed to fetch pdev temp ev"); 6837 kfree(tb); 6838 return; 6839 } 6840 6841 ath11k_dbg(ab, ATH11K_DBG_WMI, 6842 "pdev temperature ev temp %d pdev_id %d\n", ev->temp, ev->pdev_id); 6843 6844 ar = ath11k_mac_get_ar_by_pdev_id(ab, ev->pdev_id); 6845 if (!ar) { 6846 ath11k_warn(ab, "invalid pdev id in pdev temperature ev %d", ev->pdev_id); 6847 kfree(tb); 6848 return; 6849 } 6850 6851 ath11k_thermal_event_temperature(ar, ev->temp); 6852 6853 kfree(tb); 6854 } 6855 6856 static void ath11k_fils_discovery_event(struct ath11k_base *ab, 6857 struct sk_buff *skb) 6858 { 6859 const void **tb; 6860 const struct wmi_fils_discovery_event *ev; 6861 int ret; 6862 6863 tb = ath11k_wmi_tlv_parse_alloc(ab, skb->data, skb->len, GFP_ATOMIC); 6864 if (IS_ERR(tb)) { 6865 ret = PTR_ERR(tb); 6866 ath11k_warn(ab, 6867 "failed to parse FILS discovery event tlv %d\n", 6868 ret); 6869 return; 6870 } 6871 6872 ev = tb[WMI_TAG_HOST_SWFDA_EVENT]; 6873 if (!ev) { 6874 ath11k_warn(ab, "failed to fetch FILS discovery event\n"); 6875 kfree(tb); 6876 return; 6877 } 6878 6879 ath11k_warn(ab, 6880 "FILS discovery frame expected from host for vdev_id: %u, transmission scheduled at %u, next TBTT: %u\n", 6881 ev->vdev_id, ev->fils_tt, ev->tbtt); 6882 6883 kfree(tb); 6884 } 6885 6886 static void ath11k_probe_resp_tx_status_event(struct ath11k_base *ab, 6887 struct sk_buff *skb) 6888 { 6889 const void **tb; 6890 const struct wmi_probe_resp_tx_status_event *ev; 6891 int ret; 6892 6893 tb = ath11k_wmi_tlv_parse_alloc(ab, skb->data, skb->len, GFP_ATOMIC); 6894 if (IS_ERR(tb)) { 6895 ret = PTR_ERR(tb); 6896 ath11k_warn(ab, 6897 "failed to parse probe response transmission status event tlv: %d\n", 6898 ret); 6899 return; 6900 } 6901 6902 ev = tb[WMI_TAG_OFFLOAD_PRB_RSP_TX_STATUS_EVENT]; 6903 if (!ev) { 6904 ath11k_warn(ab, 6905 "failed to fetch probe response transmission status event"); 6906 kfree(tb); 6907 return; 6908 } 6909 6910 if (ev->tx_status) 6911 ath11k_warn(ab, 6912 "Probe response transmission failed for vdev_id %u, status %u\n", 6913 ev->vdev_id, ev->tx_status); 6914 6915 kfree(tb); 6916 } 6917 6918 static int ath11k_wmi_tlv_wow_wakeup_host_parse(struct ath11k_base *ab, 6919 u16 tag, u16 len, 6920 const void *ptr, void *data) 6921 { 6922 struct wmi_wow_ev_arg *ev = data; 6923 const char *wow_pg_fault; 6924 int wow_pg_len; 6925 6926 switch (tag) { 6927 case WMI_TAG_WOW_EVENT_INFO: 6928 memcpy(ev, ptr, sizeof(*ev)); 6929 ath11k_dbg(ab, ATH11K_DBG_WMI, "wow wakeup host reason %d %s\n", 6930 ev->wake_reason, wow_reason(ev->wake_reason)); 6931 break; 6932 6933 case WMI_TAG_ARRAY_BYTE: 6934 if (ev && ev->wake_reason == WOW_REASON_PAGE_FAULT) { 6935 wow_pg_fault = ptr; 6936 /* the first 4 bytes are length */ 6937 wow_pg_len = *(int *)wow_pg_fault; 6938 wow_pg_fault += sizeof(int); 6939 ath11k_dbg(ab, ATH11K_DBG_WMI, "wow data_len = %d\n", 6940 wow_pg_len); 6941 ath11k_dbg_dump(ab, ATH11K_DBG_WMI, 6942 "wow_event_info_type packet present", 6943 "wow_pg_fault ", 6944 wow_pg_fault, 6945 wow_pg_len); 6946 } 6947 break; 6948 default: 6949 break; 6950 } 6951 6952 return 0; 6953 } 6954 6955 static void ath11k_wmi_event_wow_wakeup_host(struct ath11k_base *ab, struct sk_buff *skb) 6956 { 6957 struct wmi_wow_ev_arg ev = { }; 6958 int ret; 6959 6960 ret = ath11k_wmi_tlv_iter(ab, skb->data, skb->len, 6961 ath11k_wmi_tlv_wow_wakeup_host_parse, 6962 &ev); 6963 if (ret) { 6964 ath11k_warn(ab, "failed to parse wmi wow tlv: %d\n", ret); 6965 return; 6966 } 6967 6968 complete(&ab->wow.wakeup_completed); 6969 } 6970 6971 static void ath11k_wmi_tlv_op_rx(struct ath11k_base *ab, struct sk_buff *skb) 6972 { 6973 struct wmi_cmd_hdr *cmd_hdr; 6974 enum wmi_tlv_event_id id; 6975 6976 cmd_hdr = (struct wmi_cmd_hdr *)skb->data; 6977 id = FIELD_GET(WMI_CMD_HDR_CMD_ID, (cmd_hdr->cmd_id)); 6978 6979 if (skb_pull(skb, sizeof(struct wmi_cmd_hdr)) == NULL) 6980 goto out; 6981 6982 switch (id) { 6983 /* Process all the WMI events here */ 6984 case WMI_SERVICE_READY_EVENTID: 6985 ath11k_service_ready_event(ab, skb); 6986 break; 6987 case WMI_SERVICE_READY_EXT_EVENTID: 6988 ath11k_service_ready_ext_event(ab, skb); 6989 break; 6990 case WMI_SERVICE_READY_EXT2_EVENTID: 6991 ath11k_service_ready_ext2_event(ab, skb); 6992 break; 6993 case WMI_REG_CHAN_LIST_CC_EVENTID: 6994 ath11k_reg_chan_list_event(ab, skb); 6995 break; 6996 case WMI_READY_EVENTID: 6997 ath11k_ready_event(ab, skb); 6998 break; 6999 case WMI_PEER_DELETE_RESP_EVENTID: 7000 ath11k_peer_delete_resp_event(ab, skb); 7001 break; 7002 case WMI_VDEV_START_RESP_EVENTID: 7003 ath11k_vdev_start_resp_event(ab, skb); 7004 break; 7005 case WMI_OFFLOAD_BCN_TX_STATUS_EVENTID: 7006 ath11k_bcn_tx_status_event(ab, skb); 7007 break; 7008 case WMI_VDEV_STOPPED_EVENTID: 7009 ath11k_vdev_stopped_event(ab, skb); 7010 break; 7011 case WMI_MGMT_RX_EVENTID: 7012 ath11k_mgmt_rx_event(ab, skb); 7013 /* mgmt_rx_event() owns the skb now! */ 7014 return; 7015 case WMI_MGMT_TX_COMPLETION_EVENTID: 7016 ath11k_mgmt_tx_compl_event(ab, skb); 7017 break; 7018 case WMI_SCAN_EVENTID: 7019 ath11k_scan_event(ab, skb); 7020 break; 7021 case WMI_PEER_STA_KICKOUT_EVENTID: 7022 ath11k_peer_sta_kickout_event(ab, skb); 7023 break; 7024 case WMI_ROAM_EVENTID: 7025 ath11k_roam_event(ab, skb); 7026 break; 7027 case WMI_CHAN_INFO_EVENTID: 7028 ath11k_chan_info_event(ab, skb); 7029 break; 7030 case WMI_PDEV_BSS_CHAN_INFO_EVENTID: 7031 ath11k_pdev_bss_chan_info_event(ab, skb); 7032 break; 7033 case WMI_VDEV_INSTALL_KEY_COMPLETE_EVENTID: 7034 ath11k_vdev_install_key_compl_event(ab, skb); 7035 break; 7036 case WMI_SERVICE_AVAILABLE_EVENTID: 7037 ath11k_service_available_event(ab, skb); 7038 break; 7039 case WMI_PEER_ASSOC_CONF_EVENTID: 7040 ath11k_peer_assoc_conf_event(ab, skb); 7041 break; 7042 case WMI_UPDATE_STATS_EVENTID: 7043 ath11k_update_stats_event(ab, skb); 7044 break; 7045 case WMI_PDEV_CTL_FAILSAFE_CHECK_EVENTID: 7046 ath11k_pdev_ctl_failsafe_check_event(ab, skb); 7047 break; 7048 case WMI_PDEV_CSA_SWITCH_COUNT_STATUS_EVENTID: 7049 ath11k_wmi_pdev_csa_switch_count_status_event(ab, skb); 7050 break; 7051 case WMI_PDEV_TEMPERATURE_EVENTID: 7052 ath11k_wmi_pdev_temperature_event(ab, skb); 7053 break; 7054 case WMI_PDEV_DMA_RING_BUF_RELEASE_EVENTID: 7055 ath11k_wmi_pdev_dma_ring_buf_release_event(ab, skb); 7056 break; 7057 case WMI_HOST_FILS_DISCOVERY_EVENTID: 7058 ath11k_fils_discovery_event(ab, skb); 7059 break; 7060 case WMI_OFFLOAD_PROB_RESP_TX_STATUS_EVENTID: 7061 ath11k_probe_resp_tx_status_event(ab, skb); 7062 break; 7063 /* add Unsupported events here */ 7064 case WMI_TBTTOFFSET_EXT_UPDATE_EVENTID: 7065 case WMI_PEER_OPER_MODE_CHANGE_EVENTID: 7066 case WMI_TWT_ENABLE_EVENTID: 7067 case WMI_TWT_DISABLE_EVENTID: 7068 case WMI_PDEV_DMA_RING_CFG_RSP_EVENTID: 7069 ath11k_dbg(ab, ATH11K_DBG_WMI, 7070 "ignoring unsupported event 0x%x\n", id); 7071 break; 7072 case WMI_PDEV_DFS_RADAR_DETECTION_EVENTID: 7073 ath11k_wmi_pdev_dfs_radar_detected_event(ab, skb); 7074 break; 7075 case WMI_VDEV_DELETE_RESP_EVENTID: 7076 ath11k_vdev_delete_resp_event(ab, skb); 7077 break; 7078 case WMI_WOW_WAKEUP_HOST_EVENTID: 7079 ath11k_wmi_event_wow_wakeup_host(ab, skb); 7080 break; 7081 /* TODO: Add remaining events */ 7082 default: 7083 ath11k_dbg(ab, ATH11K_DBG_WMI, "Unknown eventid: 0x%x\n", id); 7084 break; 7085 } 7086 7087 out: 7088 dev_kfree_skb(skb); 7089 } 7090 7091 static int ath11k_connect_pdev_htc_service(struct ath11k_base *ab, 7092 u32 pdev_idx) 7093 { 7094 int status; 7095 u32 svc_id[] = { ATH11K_HTC_SVC_ID_WMI_CONTROL, 7096 ATH11K_HTC_SVC_ID_WMI_CONTROL_MAC1, 7097 ATH11K_HTC_SVC_ID_WMI_CONTROL_MAC2 }; 7098 7099 struct ath11k_htc_svc_conn_req conn_req; 7100 struct ath11k_htc_svc_conn_resp conn_resp; 7101 7102 memset(&conn_req, 0, sizeof(conn_req)); 7103 memset(&conn_resp, 0, sizeof(conn_resp)); 7104 7105 /* these fields are the same for all service endpoints */ 7106 conn_req.ep_ops.ep_tx_complete = ath11k_wmi_htc_tx_complete; 7107 conn_req.ep_ops.ep_rx_complete = ath11k_wmi_tlv_op_rx; 7108 conn_req.ep_ops.ep_tx_credits = ath11k_wmi_op_ep_tx_credits; 7109 7110 /* connect to control service */ 7111 conn_req.service_id = svc_id[pdev_idx]; 7112 7113 status = ath11k_htc_connect_service(&ab->htc, &conn_req, &conn_resp); 7114 if (status) { 7115 ath11k_warn(ab, "failed to connect to WMI CONTROL service status: %d\n", 7116 status); 7117 return status; 7118 } 7119 7120 ab->wmi_ab.wmi_endpoint_id[pdev_idx] = conn_resp.eid; 7121 ab->wmi_ab.wmi[pdev_idx].eid = conn_resp.eid; 7122 ab->wmi_ab.max_msg_len[pdev_idx] = conn_resp.max_msg_len; 7123 7124 return 0; 7125 } 7126 7127 static int 7128 ath11k_wmi_send_unit_test_cmd(struct ath11k *ar, 7129 struct wmi_unit_test_cmd ut_cmd, 7130 u32 *test_args) 7131 { 7132 struct ath11k_pdev_wmi *wmi = ar->wmi; 7133 struct wmi_unit_test_cmd *cmd; 7134 struct sk_buff *skb; 7135 struct wmi_tlv *tlv; 7136 void *ptr; 7137 u32 *ut_cmd_args; 7138 int buf_len, arg_len; 7139 int ret; 7140 int i; 7141 7142 arg_len = sizeof(u32) * ut_cmd.num_args; 7143 buf_len = sizeof(ut_cmd) + arg_len + TLV_HDR_SIZE; 7144 7145 skb = ath11k_wmi_alloc_skb(wmi->wmi_ab, buf_len); 7146 if (!skb) 7147 return -ENOMEM; 7148 7149 cmd = (struct wmi_unit_test_cmd *)skb->data; 7150 cmd->tlv_header = FIELD_PREP(WMI_TLV_TAG, WMI_TAG_UNIT_TEST_CMD) | 7151 FIELD_PREP(WMI_TLV_LEN, sizeof(ut_cmd) - TLV_HDR_SIZE); 7152 7153 cmd->vdev_id = ut_cmd.vdev_id; 7154 cmd->module_id = ut_cmd.module_id; 7155 cmd->num_args = ut_cmd.num_args; 7156 cmd->diag_token = ut_cmd.diag_token; 7157 7158 ptr = skb->data + sizeof(ut_cmd); 7159 7160 tlv = ptr; 7161 tlv->header = FIELD_PREP(WMI_TLV_TAG, WMI_TAG_ARRAY_UINT32) | 7162 FIELD_PREP(WMI_TLV_LEN, arg_len); 7163 7164 ptr += TLV_HDR_SIZE; 7165 7166 ut_cmd_args = ptr; 7167 for (i = 0; i < ut_cmd.num_args; i++) 7168 ut_cmd_args[i] = test_args[i]; 7169 7170 ret = ath11k_wmi_cmd_send(wmi, skb, WMI_UNIT_TEST_CMDID); 7171 7172 if (ret) { 7173 ath11k_warn(ar->ab, "failed to send WMI_UNIT_TEST CMD :%d\n", 7174 ret); 7175 dev_kfree_skb(skb); 7176 } 7177 7178 ath11k_dbg(ar->ab, ATH11K_DBG_WMI, 7179 "WMI unit test : module %d vdev %d n_args %d token %d\n", 7180 cmd->module_id, cmd->vdev_id, cmd->num_args, 7181 cmd->diag_token); 7182 7183 return ret; 7184 } 7185 7186 int ath11k_wmi_simulate_radar(struct ath11k *ar) 7187 { 7188 struct ath11k_vif *arvif; 7189 u32 dfs_args[DFS_MAX_TEST_ARGS]; 7190 struct wmi_unit_test_cmd wmi_ut; 7191 bool arvif_found = false; 7192 7193 list_for_each_entry(arvif, &ar->arvifs, list) { 7194 if (arvif->is_started && arvif->vdev_type == WMI_VDEV_TYPE_AP) { 7195 arvif_found = true; 7196 break; 7197 } 7198 } 7199 7200 if (!arvif_found) 7201 return -EINVAL; 7202 7203 dfs_args[DFS_TEST_CMDID] = 0; 7204 dfs_args[DFS_TEST_PDEV_ID] = ar->pdev->pdev_id; 7205 /* Currently we could pass segment_id(b0 - b1), chirp(b2) 7206 * freq offset (b3 - b10) to unit test. For simulation 7207 * purpose this can be set to 0 which is valid. 7208 */ 7209 dfs_args[DFS_TEST_RADAR_PARAM] = 0; 7210 7211 wmi_ut.vdev_id = arvif->vdev_id; 7212 wmi_ut.module_id = DFS_UNIT_TEST_MODULE; 7213 wmi_ut.num_args = DFS_MAX_TEST_ARGS; 7214 wmi_ut.diag_token = DFS_UNIT_TEST_TOKEN; 7215 7216 ath11k_dbg(ar->ab, ATH11K_DBG_REG, "Triggering Radar Simulation\n"); 7217 7218 return ath11k_wmi_send_unit_test_cmd(ar, wmi_ut, dfs_args); 7219 } 7220 7221 int ath11k_wmi_connect(struct ath11k_base *ab) 7222 { 7223 u32 i; 7224 u8 wmi_ep_count; 7225 7226 wmi_ep_count = ab->htc.wmi_ep_count; 7227 if (wmi_ep_count > ab->hw_params.max_radios) 7228 return -1; 7229 7230 for (i = 0; i < wmi_ep_count; i++) 7231 ath11k_connect_pdev_htc_service(ab, i); 7232 7233 return 0; 7234 } 7235 7236 static void ath11k_wmi_pdev_detach(struct ath11k_base *ab, u8 pdev_id) 7237 { 7238 if (WARN_ON(pdev_id >= MAX_RADIOS)) 7239 return; 7240 7241 /* TODO: Deinit any pdev specific wmi resource */ 7242 } 7243 7244 int ath11k_wmi_pdev_attach(struct ath11k_base *ab, 7245 u8 pdev_id) 7246 { 7247 struct ath11k_pdev_wmi *wmi_handle; 7248 7249 if (pdev_id >= ab->hw_params.max_radios) 7250 return -EINVAL; 7251 7252 wmi_handle = &ab->wmi_ab.wmi[pdev_id]; 7253 7254 wmi_handle->wmi_ab = &ab->wmi_ab; 7255 7256 ab->wmi_ab.ab = ab; 7257 /* TODO: Init remaining resource specific to pdev */ 7258 7259 return 0; 7260 } 7261 7262 int ath11k_wmi_attach(struct ath11k_base *ab) 7263 { 7264 int ret; 7265 7266 ret = ath11k_wmi_pdev_attach(ab, 0); 7267 if (ret) 7268 return ret; 7269 7270 ab->wmi_ab.ab = ab; 7271 ab->wmi_ab.preferred_hw_mode = WMI_HOST_HW_MODE_MAX; 7272 7273 /* It's overwritten when service_ext_ready is handled */ 7274 if (ab->hw_params.single_pdev_only) 7275 ab->wmi_ab.preferred_hw_mode = WMI_HOST_HW_MODE_SINGLE; 7276 7277 /* TODO: Init remaining wmi soc resources required */ 7278 init_completion(&ab->wmi_ab.service_ready); 7279 init_completion(&ab->wmi_ab.unified_ready); 7280 7281 return 0; 7282 } 7283 7284 void ath11k_wmi_detach(struct ath11k_base *ab) 7285 { 7286 int i; 7287 7288 /* TODO: Deinit wmi resource specific to SOC as required */ 7289 7290 for (i = 0; i < ab->htc.wmi_ep_count; i++) 7291 ath11k_wmi_pdev_detach(ab, i); 7292 7293 ath11k_wmi_free_dbring_caps(ab); 7294 } 7295 7296 int ath11k_wmi_wow_host_wakeup_ind(struct ath11k *ar) 7297 { 7298 struct wmi_wow_host_wakeup_ind *cmd; 7299 struct sk_buff *skb; 7300 size_t len; 7301 7302 len = sizeof(*cmd); 7303 skb = ath11k_wmi_alloc_skb(ar->wmi->wmi_ab, len); 7304 if (!skb) 7305 return -ENOMEM; 7306 7307 cmd = (struct wmi_wow_host_wakeup_ind *)skb->data; 7308 cmd->tlv_header = FIELD_PREP(WMI_TLV_TAG, 7309 WMI_TAG_WOW_HOSTWAKEUP_FROM_SLEEP_CMD) | 7310 FIELD_PREP(WMI_TLV_LEN, sizeof(*cmd) - TLV_HDR_SIZE); 7311 7312 ath11k_dbg(ar->ab, ATH11K_DBG_WMI, "wmi tlv wow host wakeup ind\n"); 7313 7314 return ath11k_wmi_cmd_send(ar->wmi, skb, WMI_WOW_HOSTWAKEUP_FROM_SLEEP_CMDID); 7315 } 7316 7317 int ath11k_wmi_wow_enable(struct ath11k *ar) 7318 { 7319 struct wmi_wow_enable_cmd *cmd; 7320 struct sk_buff *skb; 7321 int len; 7322 7323 len = sizeof(*cmd); 7324 skb = ath11k_wmi_alloc_skb(ar->wmi->wmi_ab, len); 7325 if (!skb) 7326 return -ENOMEM; 7327 7328 cmd = (struct wmi_wow_enable_cmd *)skb->data; 7329 cmd->tlv_header = FIELD_PREP(WMI_TLV_TAG, WMI_TAG_WOW_ENABLE_CMD) | 7330 FIELD_PREP(WMI_TLV_LEN, sizeof(*cmd) - TLV_HDR_SIZE); 7331 7332 cmd->enable = 1; 7333 cmd->pause_iface_config = WOW_IFACE_PAUSE_ENABLED; 7334 ath11k_dbg(ar->ab, ATH11K_DBG_WMI, "wmi tlv wow enable\n"); 7335 7336 return ath11k_wmi_cmd_send(ar->wmi, skb, WMI_WOW_ENABLE_CMDID); 7337 } 7338