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