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