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