Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge tag 'wireless-next-2026-02-04' of https://git.kernel.org/pub/scm/linux/kernel/git/wireless/wireless-next

Johannes Berg says:

====================
Some more changes, including pulls from drivers:
- ath drivers: small features/cleanups
- rtw drivers: mostly refactoring for rtw89 RTL8922DE support
- mac80211: use hrtimers for CAC to avoid too long delays
- cfg80211/mac80211: some initial UHR (Wi-Fi 8) support

* tag 'wireless-next-2026-02-04' of https://git.kernel.org/pub/scm/linux/kernel/git/wireless/wireless-next: (59 commits)
wifi: brcmsmac: phy: Remove unreachable error handling code
wifi: mac80211: Add eMLSR/eMLMR action frame parsing support
wifi: mac80211: add initial UHR support
wifi: cfg80211: add initial UHR support
wifi: ieee80211: add some initial UHR definitions
wifi: mac80211: use wiphy_hrtimer_work for CAC timeout
wifi: mac80211: correct ieee80211-{s1g/eht}.h include guard comments
wifi: ath12k: clear stale link mapping of ahvif->links_map
wifi: ath12k: Add support TX hardware queue stats
wifi: ath12k: Add support RX PDEV stats
wifi: ath12k: Fix index decrement when array_len is zero
wifi: ath12k: support OBSS PD configuration for AP mode
wifi: ath12k: add WMI support for spatial reuse parameter configuration
dt-bindings: net: wireless: ath11k-pci: deprecate 'firmware-name' property
wifi: ath11k: add usecase firmware handling based on device compatible
wifi: ath10k: sdio: add missing lock protection in ath10k_sdio_fw_crashed_dump()
wifi: ath10k: fix lock protection in ath10k_wmi_event_peer_sta_ps_state_chg()
wifi: ath10k: snoc: support powering on the device via pwrseq
wifi: rtw89: pci: warn if SPS OCP happens for RTL8922DE
wifi: rtw89: pci: restore LDO setting after device resume
...
====================

Link: https://patch.msgid.link/20260204121143.181112-3-johannes@sipsolutions.net
Signed-off-by: Jakub Kicinski <kuba@kernel.org>

+3973 -247
+1
Documentation/devicetree/bindings/net/wireless/qcom,ath11k-pci.yaml
··· 37 37 38 38 firmware-name: 39 39 maxItems: 1 40 + deprecated: true 40 41 description: 41 42 If present, a board or platform specific string used to lookup 42 43 usecase-specific firmware files for the device.
+6
drivers/net/wireless/ath/ath10k/sdio.c
··· 2487 2487 if (fast_dump) 2488 2488 ath10k_bmi_start(ar); 2489 2489 2490 + mutex_lock(&ar->dump_mutex); 2491 + 2492 + spin_lock_bh(&ar->data_lock); 2490 2493 ar->stats.fw_crash_counter++; 2494 + spin_unlock_bh(&ar->data_lock); 2491 2495 2492 2496 ath10k_sdio_disable_intrs(ar); 2493 2497 ··· 2508 2504 ath10k_sdio_dump_memory(ar, crash_data, fast_dump); 2509 2505 2510 2506 ath10k_sdio_enable_intrs(ar); 2507 + 2508 + mutex_unlock(&ar->dump_mutex); 2511 2509 2512 2510 ath10k_core_start_recovery(ar); 2513 2511 }
+50 -3
drivers/net/wireless/ath/ath10k/snoc.c
··· 1 1 // SPDX-License-Identifier: ISC 2 2 /* 3 3 * Copyright (c) 2018 The Linux Foundation. All rights reserved. 4 + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. 4 5 */ 5 6 6 7 #include <linux/bits.h> ··· 12 11 #include <linux/of_device.h> 13 12 #include <linux/platform_device.h> 14 13 #include <linux/property.h> 14 + #include <linux/pwrseq/consumer.h> 15 15 #include <linux/regulator/consumer.h> 16 16 #include <linux/remoteproc/qcom_rproc.h> 17 17 #include <linux/of_reserved_mem.h> ··· 1025 1023 1026 1024 ath10k_dbg(ar, ATH10K_DBG_SNOC, "soc power on\n"); 1027 1025 1028 - ret = regulator_bulk_enable(ar_snoc->num_vregs, ar_snoc->vregs); 1026 + ret = pwrseq_power_on(ar_snoc->pwrseq); 1029 1027 if (ret) 1030 1028 return ret; 1029 + 1030 + ret = regulator_bulk_enable(ar_snoc->num_vregs, ar_snoc->vregs); 1031 + if (ret) 1032 + goto pwrseq_off; 1031 1033 1032 1034 ret = clk_bulk_prepare_enable(ar_snoc->num_clks, ar_snoc->clks); 1033 1035 if (ret) ··· 1041 1035 1042 1036 vreg_off: 1043 1037 regulator_bulk_disable(ar_snoc->num_vregs, ar_snoc->vregs); 1038 + pwrseq_off: 1039 + pwrseq_power_off(ar_snoc->pwrseq); 1040 + 1044 1041 return ret; 1045 1042 } 1046 1043 1047 1044 static int ath10k_hw_power_off(struct ath10k *ar) 1048 1045 { 1049 1046 struct ath10k_snoc *ar_snoc = ath10k_snoc_priv(ar); 1047 + int ret_seq = 0; 1048 + int ret_vreg; 1050 1049 1051 1050 ath10k_dbg(ar, ATH10K_DBG_SNOC, "soc power off\n"); 1052 1051 1053 1052 clk_bulk_disable_unprepare(ar_snoc->num_clks, ar_snoc->clks); 1054 1053 1055 - return regulator_bulk_disable(ar_snoc->num_vregs, ar_snoc->vregs); 1054 + ret_vreg = regulator_bulk_disable(ar_snoc->num_vregs, ar_snoc->vregs); 1055 + 1056 + if (ar_snoc->pwrseq) 1057 + ret_seq = pwrseq_power_off(ar_snoc->pwrseq); 1058 + 1059 + return ret_vreg ? : ret_seq; 1056 1060 } 1057 1061 1058 1062 static void ath10k_snoc_wlan_disable(struct ath10k *ar) ··· 1778 1762 goto err_release_resource; 1779 1763 } 1780 1764 1781 - ar_snoc->num_vregs = ARRAY_SIZE(ath10k_regulators); 1765 + /* 1766 + * devm_pwrseq_get() can return -EPROBE_DEFER in two cases: 1767 + * - it is not supposed to be used 1768 + * - it is supposed to be used, but the driver hasn't probed yet. 1769 + * 1770 + * There is no simple way to distinguish between these two cases, but: 1771 + * - if it is not supposed to be used, then regulator_bulk_get() will 1772 + * return all regulators as expected, continuing the probe 1773 + * - if it is supposed to be used, but wasn't probed yet, we will get 1774 + * -EPROBE_DEFER from regulator_bulk_get() too. 1775 + * 1776 + * For backwards compatibility with DTs specifying regulators directly 1777 + * rather than using the PMU device, ignore the defer error from 1778 + * pwrseq. 1779 + */ 1780 + ar_snoc->pwrseq = devm_pwrseq_get(&pdev->dev, "wlan"); 1781 + if (IS_ERR(ar_snoc->pwrseq)) { 1782 + ret = PTR_ERR(ar_snoc->pwrseq); 1783 + ar_snoc->pwrseq = NULL; 1784 + if (ret != -EPROBE_DEFER) 1785 + goto err_free_irq; 1786 + 1787 + ar_snoc->num_vregs = ARRAY_SIZE(ath10k_regulators); 1788 + } else { 1789 + /* 1790 + * The first regulator (vdd-0.8-cx-mx) is used to power on part 1791 + * of the SoC rather than the PMU on WCN399x, the rest are 1792 + * handled via pwrseq. 1793 + */ 1794 + ar_snoc->num_vregs = 1; 1795 + } 1796 + 1782 1797 ar_snoc->vregs = devm_kcalloc(&pdev->dev, ar_snoc->num_vregs, 1783 1798 sizeof(*ar_snoc->vregs), GFP_KERNEL); 1784 1799 if (!ar_snoc->vregs) {
+3
drivers/net/wireless/ath/ath10k/snoc.h
··· 1 1 /* SPDX-License-Identifier: ISC */ 2 2 /* 3 3 * Copyright (c) 2018 The Linux Foundation. All rights reserved. 4 + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. 4 5 */ 5 6 6 7 #ifndef _SNOC_H_ ··· 54 53 }; 55 54 56 55 struct clk_bulk_data; 56 + struct pwrseq_desc; 57 57 struct regulator_bulk_data; 58 58 59 59 struct ath10k_snoc { ··· 75 73 struct ath10k_snoc_ce_irq ce_irqs[CE_COUNT_MAX]; 76 74 struct ath10k_ce ce; 77 75 struct timer_list rx_post_retry; 76 + struct pwrseq_desc *pwrseq; 78 77 struct regulator_bulk_data *vregs; 79 78 size_t num_vregs; 80 79 struct clk_bulk_data *clks;
+2 -2
drivers/net/wireless/ath/ath10k/wmi.c
··· 5289 5289 struct ath10k_sta *arsta; 5290 5290 u8 peer_addr[ETH_ALEN]; 5291 5291 5292 - lockdep_assert_held(&ar->data_lock); 5293 - 5294 5292 ev = (struct wmi_peer_sta_ps_state_chg_event *)skb->data; 5295 5293 ether_addr_copy(peer_addr, ev->peer_macaddr.addr); 5296 5294 ··· 5303 5305 } 5304 5306 5305 5307 arsta = (struct ath10k_sta *)sta->drv_priv; 5308 + spin_lock_bh(&ar->data_lock); 5306 5309 arsta->peer_ps_state = __le32_to_cpu(ev->peer_ps_state); 5310 + spin_unlock_bh(&ar->data_lock); 5307 5311 5308 5312 exit: 5309 5313 rcu_read_unlock();
+27
drivers/net/wireless/ath/ath11k/core.c
··· 1044 1044 {} 1045 1045 }; 1046 1046 1047 + static const struct __ath11k_core_usecase_firmware_table { 1048 + u32 hw_rev; 1049 + const char *compatible; 1050 + const char *firmware_name; 1051 + } ath11k_core_usecase_firmware_table[] = { 1052 + { ATH11K_HW_WCN6855_HW21, "qcom,lemans-evk", "nfa765"}, 1053 + { ATH11K_HW_WCN6855_HW21, "qcom,monaco-evk", "nfa765"}, 1054 + { ATH11K_HW_WCN6855_HW21, "qcom,hamoa-iot-evk", "nfa765"}, 1055 + { /* Sentinel */ } 1056 + }; 1057 + 1058 + const char *ath11k_core_get_usecase_firmware(struct ath11k_base *ab) 1059 + { 1060 + const struct __ath11k_core_usecase_firmware_table *entry = NULL; 1061 + 1062 + entry = ath11k_core_usecase_firmware_table; 1063 + while (entry->compatible) { 1064 + if (ab->hw_rev == entry->hw_rev && 1065 + of_machine_is_compatible(entry->compatible)) 1066 + return entry->firmware_name; 1067 + entry++; 1068 + } 1069 + 1070 + return NULL; 1071 + } 1072 + EXPORT_SYMBOL(ath11k_core_get_usecase_firmware); 1073 + 1047 1074 void ath11k_fw_stats_pdevs_free(struct list_head *head) 1048 1075 { 1049 1076 struct ath11k_fw_stats_pdev *i, *tmp;
+4
drivers/net/wireless/ath/ath11k/core.h
··· 1292 1292 1293 1293 const struct firmware *ath11k_core_firmware_request(struct ath11k_base *ab, 1294 1294 const char *filename); 1295 + const char *ath11k_core_get_usecase_firmware(struct ath11k_base *ab); 1295 1296 1296 1297 static inline const char *ath11k_scan_state_str(enum ath11k_scan_state state) 1297 1298 { ··· 1346 1345 const char *fw_name = NULL; 1347 1346 1348 1347 of_property_read_string(ab->dev->of_node, "firmware-name", &fw_name); 1348 + 1349 + if (!fw_name) 1350 + fw_name = ath11k_core_get_usecase_firmware(ab); 1349 1351 1350 1352 if (fw_name && strncmp(filename, "board", 5)) 1351 1353 snprintf(buf, buf_len, "%s/%s/%s/%s", ATH11K_FW_DIR,
+194 -3
drivers/net/wireless/ath/ath12k/debugfs_htt_stats.c
··· 1 1 // SPDX-License-Identifier: BSD-3-Clause-Clear 2 2 /* 3 3 * Copyright (c) 2018-2021 The Linux Foundation. All rights reserved. 4 - * Copyright (c) 2021-2025 Qualcomm Innovation Center, Inc. All rights reserved. 4 + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. 5 5 */ 6 6 7 7 #include <linux/vmalloc.h> ··· 29 29 " %u:%u,", stats_index++, le32_to_cpu(array[i])); 30 30 } 31 31 /* To overwrite the last trailing comma */ 32 - index--; 33 - *(buf + offset + index) = '\0'; 32 + if (array_len > 0) { 33 + index--; 34 + *(buf + offset + index) = '\0'; 35 + } 34 36 35 37 if (footer) { 36 38 index += scnprintf(buf + offset + index, ··· 5539 5537 stats_req->buf_len = len; 5540 5538 } 5541 5539 5540 + static void 5541 + ath12k_htt_print_rx_pdev_fw_stats_tlv(const void *tag_buf, u16 tag_len, 5542 + struct debug_htt_stats_req *stats_req) 5543 + { 5544 + const struct htt_rx_pdev_fw_stats_tlv *htt_stats_buf = tag_buf; 5545 + u32 buf_len = ATH12K_HTT_STATS_BUF_SIZE; 5546 + u32 len = stats_req->buf_len; 5547 + u8 *buf = stats_req->buf; 5548 + 5549 + if (tag_len < sizeof(*htt_stats_buf)) 5550 + return; 5551 + 5552 + len += scnprintf(buf + len, buf_len - len, "HTT_RX_PDEV_FW_STATS_TLV:\n"); 5553 + len += scnprintf(buf + len, buf_len - len, "mac_id = %u\n", 5554 + le32_to_cpu(htt_stats_buf->mac_id__word) & 0xFF); 5555 + len += scnprintf(buf + len, buf_len - len, "ppdu_recvd = %u\n", 5556 + le32_to_cpu(htt_stats_buf->ppdu_recvd)); 5557 + len += scnprintf(buf + len, buf_len - len, "mpdu_cnt_fcs_ok = %u\n", 5558 + le32_to_cpu(htt_stats_buf->mpdu_cnt_fcs_ok)); 5559 + len += scnprintf(buf + len, buf_len - len, "mpdu_cnt_fcs_err = %u\n", 5560 + le32_to_cpu(htt_stats_buf->mpdu_cnt_fcs_err)); 5561 + len += scnprintf(buf + len, buf_len - len, "tcp_msdu_cnt = %u\n", 5562 + le32_to_cpu(htt_stats_buf->tcp_msdu_cnt)); 5563 + len += scnprintf(buf + len, buf_len - len, "tcp_ack_msdu_cnt = %u\n", 5564 + le32_to_cpu(htt_stats_buf->tcp_ack_msdu_cnt)); 5565 + len += scnprintf(buf + len, buf_len - len, "udp_msdu_cnt = %u\n", 5566 + le32_to_cpu(htt_stats_buf->udp_msdu_cnt)); 5567 + len += scnprintf(buf + len, buf_len - len, "other_msdu_cnt = %u\n", 5568 + le32_to_cpu(htt_stats_buf->other_msdu_cnt)); 5569 + len += scnprintf(buf + len, buf_len - len, "fw_ring_mpdu_ind = %u\n", 5570 + le32_to_cpu(htt_stats_buf->fw_ring_mpdu_ind)); 5571 + len += print_array_to_buf(buf, len, "fw_ring_mgmt_subtype", 5572 + htt_stats_buf->fw_ring_mgmt_subtype, 5573 + ATH12K_HTT_STATS_SUBTYPE_MAX, "\n"); 5574 + len += print_array_to_buf(buf, len, "fw_ring_ctrl_subtype", 5575 + htt_stats_buf->fw_ring_ctrl_subtype, 5576 + ATH12K_HTT_STATS_SUBTYPE_MAX, "\n"); 5577 + len += scnprintf(buf + len, buf_len - len, "fw_ring_mcast_data_msdu = %u\n", 5578 + le32_to_cpu(htt_stats_buf->fw_ring_mcast_data_msdu)); 5579 + len += scnprintf(buf + len, buf_len - len, "fw_ring_bcast_data_msdu = %u\n", 5580 + le32_to_cpu(htt_stats_buf->fw_ring_bcast_data_msdu)); 5581 + len += scnprintf(buf + len, buf_len - len, "fw_ring_ucast_data_msdu = %u\n", 5582 + le32_to_cpu(htt_stats_buf->fw_ring_ucast_data_msdu)); 5583 + len += scnprintf(buf + len, buf_len - len, "fw_ring_null_data_msdu = %u\n", 5584 + le32_to_cpu(htt_stats_buf->fw_ring_null_data_msdu)); 5585 + len += scnprintf(buf + len, buf_len - len, "fw_ring_mpdu_drop = %u\n", 5586 + le32_to_cpu(htt_stats_buf->fw_ring_mpdu_drop)); 5587 + len += scnprintf(buf + len, buf_len - len, "ofld_local_data_ind_cnt = %u\n", 5588 + le32_to_cpu(htt_stats_buf->ofld_local_data_ind_cnt)); 5589 + len += scnprintf(buf + len, buf_len - len, 5590 + "ofld_local_data_buf_recycle_cnt = %u\n", 5591 + le32_to_cpu(htt_stats_buf->ofld_local_data_buf_recycle_cnt)); 5592 + len += scnprintf(buf + len, buf_len - len, "drx_local_data_ind_cnt = %u\n", 5593 + le32_to_cpu(htt_stats_buf->drx_local_data_ind_cnt)); 5594 + len += scnprintf(buf + len, buf_len - len, 5595 + "drx_local_data_buf_recycle_cnt = %u\n", 5596 + le32_to_cpu(htt_stats_buf->drx_local_data_buf_recycle_cnt)); 5597 + len += scnprintf(buf + len, buf_len - len, "local_nondata_ind_cnt = %u\n", 5598 + le32_to_cpu(htt_stats_buf->local_nondata_ind_cnt)); 5599 + len += scnprintf(buf + len, buf_len - len, "local_nondata_buf_recycle_cnt = %u\n", 5600 + le32_to_cpu(htt_stats_buf->local_nondata_buf_recycle_cnt)); 5601 + len += scnprintf(buf + len, buf_len - len, "fw_status_buf_ring_refill_cnt = %u\n", 5602 + le32_to_cpu(htt_stats_buf->fw_status_buf_ring_refill_cnt)); 5603 + len += scnprintf(buf + len, buf_len - len, "fw_status_buf_ring_empty_cnt = %u\n", 5604 + le32_to_cpu(htt_stats_buf->fw_status_buf_ring_empty_cnt)); 5605 + len += scnprintf(buf + len, buf_len - len, "fw_pkt_buf_ring_refill_cnt = %u\n", 5606 + le32_to_cpu(htt_stats_buf->fw_pkt_buf_ring_refill_cnt)); 5607 + len += scnprintf(buf + len, buf_len - len, "fw_pkt_buf_ring_empty_cnt = %u\n", 5608 + le32_to_cpu(htt_stats_buf->fw_pkt_buf_ring_empty_cnt)); 5609 + len += scnprintf(buf + len, buf_len - len, "fw_link_buf_ring_refill_cnt = %u\n", 5610 + le32_to_cpu(htt_stats_buf->fw_link_buf_ring_refill_cnt)); 5611 + len += scnprintf(buf + len, buf_len - len, "fw_link_buf_ring_empty_cnt = %u\n", 5612 + le32_to_cpu(htt_stats_buf->fw_link_buf_ring_empty_cnt)); 5613 + len += scnprintf(buf + len, buf_len - len, "host_pkt_buf_ring_refill_cnt = %u\n", 5614 + le32_to_cpu(htt_stats_buf->host_pkt_buf_ring_refill_cnt)); 5615 + len += scnprintf(buf + len, buf_len - len, "host_pkt_buf_ring_empty_cnt = %u\n", 5616 + le32_to_cpu(htt_stats_buf->host_pkt_buf_ring_empty_cnt)); 5617 + len += scnprintf(buf + len, buf_len - len, "mon_pkt_buf_ring_refill_cnt = %u\n", 5618 + le32_to_cpu(htt_stats_buf->mon_pkt_buf_ring_refill_cnt)); 5619 + len += scnprintf(buf + len, buf_len - len, "mon_pkt_buf_ring_empty_cnt = %u\n", 5620 + le32_to_cpu(htt_stats_buf->mon_pkt_buf_ring_empty_cnt)); 5621 + len += scnprintf(buf + len, buf_len - len, 5622 + "mon_status_buf_ring_refill_cnt = %u\n", 5623 + le32_to_cpu(htt_stats_buf->mon_status_buf_ring_refill_cnt)); 5624 + len += scnprintf(buf + len, buf_len - len, "mon_status_buf_ring_empty_cnt = %u\n", 5625 + le32_to_cpu(htt_stats_buf->mon_status_buf_ring_empty_cnt)); 5626 + len += scnprintf(buf + len, buf_len - len, "mon_desc_buf_ring_refill_cnt = %u\n", 5627 + le32_to_cpu(htt_stats_buf->mon_desc_buf_ring_refill_cnt)); 5628 + len += scnprintf(buf + len, buf_len - len, "mon_desc_buf_ring_empty_cnt = %u\n", 5629 + le32_to_cpu(htt_stats_buf->mon_desc_buf_ring_empty_cnt)); 5630 + len += scnprintf(buf + len, buf_len - len, "mon_dest_ring_update_cnt = %u\n", 5631 + le32_to_cpu(htt_stats_buf->mon_dest_ring_update_cnt)); 5632 + len += scnprintf(buf + len, buf_len - len, "mon_dest_ring_full_cnt = %u\n", 5633 + le32_to_cpu(htt_stats_buf->mon_dest_ring_full_cnt)); 5634 + len += scnprintf(buf + len, buf_len - len, "rx_suspend_cnt = %u\n", 5635 + le32_to_cpu(htt_stats_buf->rx_suspend_cnt)); 5636 + len += scnprintf(buf + len, buf_len - len, "rx_suspend_fail_cnt = %u\n", 5637 + le32_to_cpu(htt_stats_buf->rx_suspend_fail_cnt)); 5638 + len += scnprintf(buf + len, buf_len - len, "rx_resume_cnt = %u\n", 5639 + le32_to_cpu(htt_stats_buf->rx_resume_cnt)); 5640 + len += scnprintf(buf + len, buf_len - len, "rx_resume_fail_cnt = %u\n", 5641 + le32_to_cpu(htt_stats_buf->rx_resume_fail_cnt)); 5642 + len += scnprintf(buf + len, buf_len - len, "rx_ring_switch_cnt = %u\n", 5643 + le32_to_cpu(htt_stats_buf->rx_ring_switch_cnt)); 5644 + len += scnprintf(buf + len, buf_len - len, "rx_ring_restore_cnt = %u\n", 5645 + le32_to_cpu(htt_stats_buf->rx_ring_restore_cnt)); 5646 + len += scnprintf(buf + len, buf_len - len, "rx_flush_cnt = %u\n", 5647 + le32_to_cpu(htt_stats_buf->rx_flush_cnt)); 5648 + len += scnprintf(buf + len, buf_len - len, "rx_recovery_reset_cnt = %u\n", 5649 + le32_to_cpu(htt_stats_buf->rx_recovery_reset_cnt)); 5650 + len += scnprintf(buf + len, buf_len - len, "rx_lwm_prom_filter_dis = %u\n", 5651 + le32_to_cpu(htt_stats_buf->rx_lwm_prom_filter_dis)); 5652 + len += scnprintf(buf + len, buf_len - len, "rx_hwm_prom_filter_en = %u\n", 5653 + le32_to_cpu(htt_stats_buf->rx_hwm_prom_filter_en)); 5654 + len += scnprintf(buf + len, buf_len - len, "bytes_received_low_32 = %u\n", 5655 + le32_to_cpu(htt_stats_buf->bytes_received_low_32)); 5656 + len += scnprintf(buf + len, buf_len - len, "bytes_received_high_32 = %u\n", 5657 + le32_to_cpu(htt_stats_buf->bytes_received_high_32)); 5658 + 5659 + stats_req->buf_len = len; 5660 + } 5661 + 5662 + static void 5663 + ath12k_htt_print_tx_hwq_stats_cmn_tlv(const void *tag_buf, u16 tag_len, 5664 + struct debug_htt_stats_req *stats_req) 5665 + { 5666 + const struct htt_tx_hwq_stats_cmn_tlv *htt_stats_buf = tag_buf; 5667 + u32 buf_len = ATH12K_HTT_STATS_BUF_SIZE; 5668 + u32 len = stats_req->buf_len; 5669 + u8 *buf = stats_req->buf; 5670 + 5671 + if (tag_len < sizeof(*htt_stats_buf)) 5672 + return; 5673 + 5674 + len += scnprintf(buf + len, buf_len - len, "HTT_TX_HWQ_STATS_CMN_TLV:\n"); 5675 + len += scnprintf(buf + len, buf_len - len, "mac_id = %u\n", 5676 + le32_to_cpu(htt_stats_buf->mac_id__hwq_id__word) & 0xFF); 5677 + len += scnprintf(buf + len, buf_len - len, "hwq_id = %u\n", 5678 + (le32_to_cpu(htt_stats_buf->mac_id__hwq_id__word) & 0xFF00) >> 8); 5679 + len += scnprintf(buf + len, buf_len - len, "xretry = %u\n", 5680 + le32_to_cpu(htt_stats_buf->xretry)); 5681 + len += scnprintf(buf + len, buf_len - len, "underrun_cnt = %u\n", 5682 + le32_to_cpu(htt_stats_buf->underrun_cnt)); 5683 + len += scnprintf(buf + len, buf_len - len, "flush_cnt = %u\n", 5684 + le32_to_cpu(htt_stats_buf->flush_cnt)); 5685 + len += scnprintf(buf + len, buf_len - len, "filt_cnt = %u\n", 5686 + le32_to_cpu(htt_stats_buf->filt_cnt)); 5687 + len += scnprintf(buf + len, buf_len - len, "null_mpdu_bmap = %u\n", 5688 + le32_to_cpu(htt_stats_buf->null_mpdu_bmap)); 5689 + len += scnprintf(buf + len, buf_len - len, "user_ack_failure = %u\n", 5690 + le32_to_cpu(htt_stats_buf->user_ack_failure)); 5691 + len += scnprintf(buf + len, buf_len - len, "ack_tlv_proc = %u\n", 5692 + le32_to_cpu(htt_stats_buf->ack_tlv_proc)); 5693 + len += scnprintf(buf + len, buf_len - len, "sched_id_proc = %u\n", 5694 + le32_to_cpu(htt_stats_buf->sched_id_proc)); 5695 + len += scnprintf(buf + len, buf_len - len, "null_mpdu_tx_count = %u\n", 5696 + le32_to_cpu(htt_stats_buf->null_mpdu_tx_count)); 5697 + len += scnprintf(buf + len, buf_len - len, "mpdu_bmap_not_recvd = %u\n", 5698 + le32_to_cpu(htt_stats_buf->mpdu_bmap_not_recvd)); 5699 + len += scnprintf(buf + len, buf_len - len, "num_bar = %u\n", 5700 + le32_to_cpu(htt_stats_buf->num_bar)); 5701 + len += scnprintf(buf + len, buf_len - len, "rts = %u\n", 5702 + le32_to_cpu(htt_stats_buf->rts)); 5703 + len += scnprintf(buf + len, buf_len - len, "cts2self = %u\n", 5704 + le32_to_cpu(htt_stats_buf->cts2self)); 5705 + len += scnprintf(buf + len, buf_len - len, "qos_null = %u\n", 5706 + le32_to_cpu(htt_stats_buf->qos_null)); 5707 + len += scnprintf(buf + len, buf_len - len, "mpdu_tried_cnt = %u\n", 5708 + le32_to_cpu(htt_stats_buf->mpdu_tried_cnt)); 5709 + len += scnprintf(buf + len, buf_len - len, "mpdu_queued_cnt = %u\n", 5710 + le32_to_cpu(htt_stats_buf->mpdu_queued_cnt)); 5711 + len += scnprintf(buf + len, buf_len - len, "mpdu_ack_fail_cnt = %u\n", 5712 + le32_to_cpu(htt_stats_buf->mpdu_ack_fail_cnt)); 5713 + len += scnprintf(buf + len, buf_len - len, "mpdu_filt_cnt = %u\n", 5714 + le32_to_cpu(htt_stats_buf->mpdu_filt_cnt)); 5715 + len += scnprintf(buf + len, buf_len - len, "false_mpdu_ack_count = %u\n", 5716 + le32_to_cpu(htt_stats_buf->false_mpdu_ack_count)); 5717 + len += scnprintf(buf + len, buf_len - len, "txq_timeout = %u\n", 5718 + le32_to_cpu(htt_stats_buf->txq_timeout)); 5719 + 5720 + stats_req->buf_len = len; 5721 + } 5722 + 5542 5723 static int ath12k_dbg_htt_ext_stats_parse(struct ath12k_base *ab, 5543 5724 u16 tag, u16 len, const void *tag_buf, 5544 5725 void *user_data) ··· 5875 5690 case HTT_STATS_SFM_CLIENT_USER_TAG: 5876 5691 ath12k_htt_print_sfm_client_user_tlv(tag_buf, len, stats_req); 5877 5692 break; 5693 + case HTT_STATS_RX_PDEV_FW_STATS_TAG: 5694 + ath12k_htt_print_rx_pdev_fw_stats_tlv(tag_buf, len, stats_req); 5695 + break; 5878 5696 case HTT_STATS_TX_PDEV_MU_MIMO_STATS_TAG: 5879 5697 ath12k_htt_print_tx_pdev_mu_mimo_sch_stats_tlv(tag_buf, len, stats_req); 5880 5698 break; ··· 6020 5832 break; 6021 5833 case HTT_STATS_PDEV_RTT_TBR_CMD_RESULT_STATS_TAG: 6022 5834 ath12k_htt_print_pdev_rtt_tbr_cmd_res_stats_tlv(tag_buf, len, stats_req); 5835 + break; 5836 + case HTT_STATS_TX_HWQ_CMN_TAG: 5837 + ath12k_htt_print_tx_hwq_stats_cmn_tlv(tag_buf, len, stats_req); 6023 5838 break; 6024 5839 default: 6025 5840 break;
+81
drivers/net/wireless/ath/ath12k/debugfs_htt_stats.h
··· 127 127 enum ath12k_dbg_htt_ext_stats_type { 128 128 ATH12K_DBG_HTT_EXT_STATS_RESET = 0, 129 129 ATH12K_DBG_HTT_EXT_STATS_PDEV_TX = 1, 130 + ATH12K_DBG_HTT_EXT_STATS_PDEV_RX = 2, 131 + ATH12K_DBG_HTT_EXT_STATS_PDEV_TX_HWQ = 3, 130 132 ATH12K_DBG_HTT_EXT_STATS_PDEV_TX_SCHED = 4, 131 133 ATH12K_DBG_HTT_EXT_STATS_PDEV_ERROR = 5, 132 134 ATH12K_DBG_HTT_EXT_STATS_PDEV_TQM = 6, ··· 175 173 HTT_STATS_TX_PDEV_SIFS_TAG = 2, 176 174 HTT_STATS_TX_PDEV_FLUSH_TAG = 3, 177 175 HTT_STATS_STRING_TAG = 5, 176 + HTT_STATS_TX_HWQ_CMN_TAG = 6, 178 177 HTT_STATS_TX_TQM_GEN_MPDU_TAG = 11, 179 178 HTT_STATS_TX_TQM_LIST_MPDU_TAG = 12, 180 179 HTT_STATS_TX_TQM_LIST_MPDU_CNT_TAG = 13, ··· 191 188 HTT_STATS_TX_PDEV_MU_MIMO_STATS_TAG = 25, 192 189 HTT_STATS_SFM_CMN_TAG = 26, 193 190 HTT_STATS_SRING_STATS_TAG = 27, 191 + HTT_STATS_RX_PDEV_FW_STATS_TAG = 28, 194 192 HTT_STATS_TX_PDEV_RATE_STATS_TAG = 34, 195 193 HTT_STATS_RX_PDEV_RATE_STATS_TAG = 35, 196 194 HTT_STATS_TX_PDEV_SCHEDULER_TXQ_STATS_TAG = 36, ··· 2077 2073 __le32 tbr_num_sch_cmd_result_buckets; 2078 2074 __le32 su_res[ATH12K_HTT_FTYPE_MAX][ATH12K_HTT_MAX_SCH_CMD_RESULT]; 2079 2075 __le32 mu_res[ATH12K_HTT_FTYPE_MAX][ATH12K_HTT_MAX_SCH_CMD_RESULT]; 2076 + } __packed; 2077 + 2078 + struct htt_rx_pdev_fw_stats_tlv { 2079 + __le32 mac_id__word; 2080 + __le32 ppdu_recvd; 2081 + __le32 mpdu_cnt_fcs_ok; 2082 + __le32 mpdu_cnt_fcs_err; 2083 + __le32 tcp_msdu_cnt; 2084 + __le32 tcp_ack_msdu_cnt; 2085 + __le32 udp_msdu_cnt; 2086 + __le32 other_msdu_cnt; 2087 + __le32 fw_ring_mpdu_ind; 2088 + __le32 fw_ring_mgmt_subtype[ATH12K_HTT_STATS_SUBTYPE_MAX]; 2089 + __le32 fw_ring_ctrl_subtype[ATH12K_HTT_STATS_SUBTYPE_MAX]; 2090 + __le32 fw_ring_mcast_data_msdu; 2091 + __le32 fw_ring_bcast_data_msdu; 2092 + __le32 fw_ring_ucast_data_msdu; 2093 + __le32 fw_ring_null_data_msdu; 2094 + __le32 fw_ring_mpdu_drop; 2095 + __le32 ofld_local_data_ind_cnt; 2096 + __le32 ofld_local_data_buf_recycle_cnt; 2097 + __le32 drx_local_data_ind_cnt; 2098 + __le32 drx_local_data_buf_recycle_cnt; 2099 + __le32 local_nondata_ind_cnt; 2100 + __le32 local_nondata_buf_recycle_cnt; 2101 + __le32 fw_status_buf_ring_refill_cnt; 2102 + __le32 fw_status_buf_ring_empty_cnt; 2103 + __le32 fw_pkt_buf_ring_refill_cnt; 2104 + __le32 fw_pkt_buf_ring_empty_cnt; 2105 + __le32 fw_link_buf_ring_refill_cnt; 2106 + __le32 fw_link_buf_ring_empty_cnt; 2107 + __le32 host_pkt_buf_ring_refill_cnt; 2108 + __le32 host_pkt_buf_ring_empty_cnt; 2109 + __le32 mon_pkt_buf_ring_refill_cnt; 2110 + __le32 mon_pkt_buf_ring_empty_cnt; 2111 + __le32 mon_status_buf_ring_refill_cnt; 2112 + __le32 mon_status_buf_ring_empty_cnt; 2113 + __le32 mon_desc_buf_ring_refill_cnt; 2114 + __le32 mon_desc_buf_ring_empty_cnt; 2115 + __le32 mon_dest_ring_update_cnt; 2116 + __le32 mon_dest_ring_full_cnt; 2117 + __le32 rx_suspend_cnt; 2118 + __le32 rx_suspend_fail_cnt; 2119 + __le32 rx_resume_cnt; 2120 + __le32 rx_resume_fail_cnt; 2121 + __le32 rx_ring_switch_cnt; 2122 + __le32 rx_ring_restore_cnt; 2123 + __le32 rx_flush_cnt; 2124 + __le32 rx_recovery_reset_cnt; 2125 + __le32 rx_lwm_prom_filter_dis; 2126 + __le32 rx_hwm_prom_filter_en; 2127 + __le32 bytes_received_low_32; 2128 + __le32 bytes_received_high_32; 2129 + } __packed; 2130 + 2131 + struct htt_tx_hwq_stats_cmn_tlv { 2132 + __le32 mac_id__hwq_id__word; 2133 + __le32 xretry; 2134 + __le32 underrun_cnt; 2135 + __le32 flush_cnt; 2136 + __le32 filt_cnt; 2137 + __le32 null_mpdu_bmap; 2138 + __le32 user_ack_failure; 2139 + __le32 ack_tlv_proc; 2140 + __le32 sched_id_proc; 2141 + __le32 null_mpdu_tx_count; 2142 + __le32 mpdu_bmap_not_recvd; 2143 + __le32 num_bar; 2144 + __le32 rts; 2145 + __le32 cts2self; 2146 + __le32 qos_null; 2147 + __le32 mpdu_tried_cnt; 2148 + __le32 mpdu_queued_cnt; 2149 + __le32 mpdu_ack_fail_cnt; 2150 + __le32 mpdu_filt_cnt; 2151 + __le32 false_mpdu_ack_count; 2152 + __le32 txq_timeout; 2080 2153 } __packed; 2081 2154 2082 2155 #endif
+170 -4
drivers/net/wireless/ath/ath12k/mac.c
··· 4281 4281 if (WARN_ON(!arvif)) 4282 4282 return -EINVAL; 4283 4283 4284 - if (!arvif->is_created) 4284 + if (!arvif->is_created) { 4285 + ath12k_mac_unassign_link_vif(arvif); 4285 4286 continue; 4287 + } 4286 4288 4287 4289 if (WARN_ON(!arvif->ar)) 4288 4290 return -EINVAL; ··· 4505 4503 if (ret) 4506 4504 ath12k_warn(ar->ab, "failed to bring vdev up %d: %d\n", 4507 4505 arvif->vdev_id, ret); 4506 + } 4507 + 4508 + static int ath12k_mac_config_obss_pd(struct ath12k_link_vif *arvif, 4509 + const struct ieee80211_he_obss_pd *he_obss_pd) 4510 + { 4511 + struct ath12k_wmi_obss_pd_arg obss_pd_arg = {}; 4512 + u32 srg_bitmap[2], non_srg_bitmap[2]; 4513 + struct ath12k *ar = arvif->ar; 4514 + u32 param_id, pdev_id; 4515 + u32 param_val; 4516 + int ret; 4517 + 4518 + if (ar->ab->hw_params->single_pdev_only) 4519 + pdev_id = ath12k_mac_get_target_pdev_id_from_vif(arvif); 4520 + else 4521 + pdev_id = ar->pdev->pdev_id; 4522 + 4523 + /* Set and enable SRG/non-SRG OBSS PD threshold */ 4524 + param_id = WMI_PDEV_PARAM_SET_CMD_OBSS_PD_THRESHOLD; 4525 + if (ar->monitor_started || !he_obss_pd->enable) { 4526 + ret = ath12k_wmi_pdev_set_param(ar, param_id, 0, pdev_id); 4527 + if (ret) 4528 + ath12k_warn(ar->ab, 4529 + "failed to set OBSS PD threshold for pdev %u: %d\n", 4530 + pdev_id, ret); 4531 + return ret; 4532 + } 4533 + 4534 + /* 4535 + * This service flag indicates firmware support for SRG/SRP-based 4536 + * spatial reuse. It also specifies whether OBSS PD threshold values 4537 + * should be interpreted as dB (offset) or dBm (absolute) units. 4538 + */ 4539 + obss_pd_arg.srp_support = test_bit(WMI_TLV_SERVICE_SRG_SRP_SPATIAL_REUSE_SUPPORT, 4540 + ar->ab->wmi_ab.svc_map); 4541 + 4542 + if (!(he_obss_pd->sr_ctrl & 4543 + IEEE80211_HE_SPR_NON_SRG_OBSS_PD_SR_DISALLOWED)) { 4544 + if (he_obss_pd->sr_ctrl & IEEE80211_HE_SPR_NON_SRG_OFFSET_PRESENT) 4545 + obss_pd_arg.non_srg_th = ATH12K_OBSS_PD_MAX_THRESHOLD + 4546 + he_obss_pd->non_srg_max_offset; 4547 + else 4548 + obss_pd_arg.non_srg_th = ATH12K_OBSS_PD_NON_SRG_MAX_THRESHOLD; 4549 + 4550 + if (!obss_pd_arg.srp_support) 4551 + obss_pd_arg.non_srg_th -= ATH12K_DEFAULT_NOISE_FLOOR; 4552 + 4553 + obss_pd_arg.non_srg_enabled = true; 4554 + } 4555 + 4556 + if (he_obss_pd->sr_ctrl & IEEE80211_HE_SPR_SRG_INFORMATION_PRESENT) { 4557 + obss_pd_arg.srg_th = ATH12K_OBSS_PD_MAX_THRESHOLD + 4558 + he_obss_pd->max_offset; 4559 + obss_pd_arg.srg_enabled = true; 4560 + } 4561 + 4562 + ath12k_dbg(ar->ab, ATH12K_DBG_MAC, 4563 + "pdev %u OBSS PD sr_ctrl 0x%x srg_th %d dBm non_srg_th %d dBm\n", 4564 + pdev_id, he_obss_pd->sr_ctrl, 4565 + obss_pd_arg.srg_th, obss_pd_arg.non_srg_th); 4566 + 4567 + param_val = ath12k_wmi_build_obss_pd(&obss_pd_arg); 4568 + ret = ath12k_wmi_pdev_set_param(ar, param_id, param_val, pdev_id); 4569 + if (ret) { 4570 + ath12k_warn(ar->ab, 4571 + "failed to set OBSS PD threshold for pdev %u: %d\n", 4572 + pdev_id, ret); 4573 + return ret; 4574 + } 4575 + 4576 + /* Enable OBSS PD for all access category */ 4577 + param_id = WMI_PDEV_PARAM_SET_CMD_OBSS_PD_PER_AC; 4578 + param_val = 0xf; 4579 + ret = ath12k_wmi_pdev_set_param(ar, param_id, param_val, pdev_id); 4580 + if (ret) { 4581 + ath12k_warn(ar->ab, 4582 + "failed to set OBSS PD per ac for pdev %u: %d\n", 4583 + pdev_id, ret); 4584 + return ret; 4585 + } 4586 + 4587 + /* Set SR prohibit */ 4588 + param_id = WMI_PDEV_PARAM_ENABLE_SR_PROHIBIT; 4589 + param_val = !!(he_obss_pd->sr_ctrl & 4590 + IEEE80211_HE_SPR_HESIGA_SR_VAL15_ALLOWED); 4591 + ret = ath12k_wmi_pdev_set_param(ar, param_id, param_val, pdev_id); 4592 + if (ret) { 4593 + ath12k_warn(ar->ab, "failed to set SR prohibit for pdev %u: %d\n", 4594 + pdev_id, ret); 4595 + return ret; 4596 + } 4597 + 4598 + if (!obss_pd_arg.srp_support) 4599 + return 0; 4600 + 4601 + memcpy(srg_bitmap, he_obss_pd->bss_color_bitmap, sizeof(srg_bitmap)); 4602 + /* Set SRG BSS color bitmap */ 4603 + ret = ath12k_wmi_pdev_set_srg_bss_color_bitmap(ar, pdev_id, srg_bitmap); 4604 + if (ret) { 4605 + ath12k_warn(ar->ab, 4606 + "failed to set SRG bss color bitmap for pdev %u: %d\n", 4607 + pdev_id, ret); 4608 + return ret; 4609 + } 4610 + 4611 + /* Enable BSS colors for SRG */ 4612 + ret = ath12k_wmi_pdev_srg_obss_color_enable_bitmap(ar, pdev_id, srg_bitmap); 4613 + if (ret) { 4614 + ath12k_warn(ar->ab, 4615 + "failed to enable SRG bss color bitmap pdev %u: %d\n", 4616 + pdev_id, ret); 4617 + return ret; 4618 + } 4619 + 4620 + memcpy(srg_bitmap, he_obss_pd->partial_bssid_bitmap, sizeof(srg_bitmap)); 4621 + /* Set SRG partial bssid bitmap */ 4622 + ret = ath12k_wmi_pdev_set_srg_partial_bssid_bitmap(ar, pdev_id, srg_bitmap); 4623 + if (ret) { 4624 + ath12k_warn(ar->ab, 4625 + "failed to set SRG partial bssid bitmap for pdev %u: %d\n", 4626 + pdev_id, ret); 4627 + return ret; 4628 + } 4629 + 4630 + /* Enable partial bssid mask for SRG */ 4631 + ret = ath12k_wmi_pdev_srg_obss_bssid_enable_bitmap(ar, pdev_id, srg_bitmap); 4632 + if (ret) { 4633 + ath12k_warn(ar->ab, 4634 + "failed to enable SRG bssid bitmap pdev %u: %d\n", 4635 + pdev_id, ret); 4636 + return ret; 4637 + } 4638 + 4639 + /* 4640 + * No explicit non-SRG bitmap from mac80211; enable all colors/bssids 4641 + * as non-SRG candidates. Actual SRG members are filtered by SRG bitmaps. 4642 + */ 4643 + memset(non_srg_bitmap, 0xff, sizeof(non_srg_bitmap)); 4644 + 4645 + /* Enable BSS colors for non-SRG */ 4646 + ret = ath12k_wmi_pdev_non_srg_obss_color_enable_bitmap(ar, pdev_id, 4647 + non_srg_bitmap); 4648 + if (ret) { 4649 + ath12k_warn(ar->ab, 4650 + "failed to enable non SRG color bitmap pdev %u: %d\n", 4651 + pdev_id, ret); 4652 + return ret; 4653 + } 4654 + 4655 + /* Enable partial bssid mask for non-SRG */ 4656 + ret = ath12k_wmi_pdev_non_srg_obss_bssid_enable_bitmap(ar, pdev_id, 4657 + non_srg_bitmap); 4658 + if (ret) { 4659 + ath12k_warn(ar->ab, 4660 + "failed to enable non SRG bssid bitmap pdev %u: %d\n", 4661 + pdev_id, ret); 4662 + return ret; 4663 + } 4664 + 4665 + return 0; 4508 4666 } 4509 4667 4510 4668 static void ath12k_mac_bss_info_changed(struct ath12k *ar, ··· 4958 4796 ath12k_wmi_send_twt_disable_cmd(ar, ar->pdev->pdev_id); 4959 4797 } 4960 4798 4961 - if (changed & BSS_CHANGED_HE_OBSS_PD) 4962 - ath12k_wmi_send_obss_spr_cmd(ar, arvif->vdev_id, 4963 - &info->he_obss_pd); 4799 + if (changed & BSS_CHANGED_HE_OBSS_PD) { 4800 + if (vif->type == NL80211_IFTYPE_AP) 4801 + ath12k_mac_config_obss_pd(arvif, &info->he_obss_pd); 4802 + else 4803 + ath12k_wmi_send_obss_spr_cmd(ar, arvif->vdev_id, 4804 + &info->he_obss_pd); 4805 + } 4964 4806 4965 4807 if (changed & BSS_CHANGED_HE_BSS_COLOR) { 4966 4808 if (vif->type == NL80211_IFTYPE_AP) {
+3
drivers/net/wireless/ath/ath12k/mac.h
··· 138 138 struct ath12k_chan_power_info chan_power_info[ATH12K_NUM_PWR_LEVELS]; 139 139 }; 140 140 141 + #define ATH12K_OBSS_PD_MAX_THRESHOLD -82 142 + #define ATH12K_OBSS_PD_NON_SRG_MAX_THRESHOLD -62 143 + 141 144 extern const struct htt_rx_ring_tlv_filter ath12k_mac_mon_status_filter_default; 142 145 143 146 #define ATH12K_SCAN_11D_INTERVAL 600000
+142
drivers/net/wireless/ath/ath12k/wmi.c
··· 126 126 bool frame_buf_done; 127 127 }; 128 128 129 + struct wmi_pdev_set_obss_bitmap_arg { 130 + u32 tlv_tag; 131 + u32 pdev_id; 132 + u32 cmd_id; 133 + const u32 *bitmap; 134 + const char *label; 135 + }; 136 + 129 137 static const struct ath12k_wmi_tlv_policy ath12k_wmi_tlv_policies[] = { 130 138 [WMI_TAG_ARRAY_BYTE] = { .min_len = 0 }, 131 139 [WMI_TAG_ARRAY_UINT32] = { .min_len = 0 }, ··· 3566 3558 dev_kfree_skb(skb); 3567 3559 } 3568 3560 return ret; 3561 + } 3562 + 3563 + u32 ath12k_wmi_build_obss_pd(const struct ath12k_wmi_obss_pd_arg *arg) 3564 + { 3565 + u32 param_val = 0; 3566 + 3567 + param_val |= u32_encode_bits((u8)arg->srg_th, GENMASK(15, 8)); 3568 + param_val |= u32_encode_bits((u8)arg->non_srg_th, GENMASK(7, 0)); 3569 + 3570 + if (arg->srp_support) 3571 + param_val |= ATH12K_OBSS_PD_THRESHOLD_IN_DBM; 3572 + 3573 + if (arg->srg_enabled && arg->srp_support) 3574 + param_val |= ATH12K_OBSS_PD_SRG_EN; 3575 + 3576 + if (arg->non_srg_enabled) 3577 + param_val |= ATH12K_OBSS_PD_NON_SRG_EN; 3578 + 3579 + return param_val; 3580 + } 3581 + 3582 + static int ath12k_wmi_pdev_set_obss_bitmap(struct ath12k *ar, 3583 + const struct wmi_pdev_set_obss_bitmap_arg *arg) 3584 + { 3585 + struct wmi_pdev_obss_pd_bitmap_cmd *cmd; 3586 + struct ath12k_wmi_pdev *wmi = ar->wmi; 3587 + const int len = sizeof(*cmd); 3588 + struct sk_buff *skb; 3589 + int ret; 3590 + 3591 + skb = ath12k_wmi_alloc_skb(wmi->wmi_ab, len); 3592 + if (!skb) 3593 + return -ENOMEM; 3594 + 3595 + cmd = (struct wmi_pdev_obss_pd_bitmap_cmd *)skb->data; 3596 + cmd->tlv_header = ath12k_wmi_tlv_cmd_hdr(arg->tlv_tag, len); 3597 + cmd->pdev_id = cpu_to_le32(arg->pdev_id); 3598 + memcpy(cmd->bitmap, arg->bitmap, sizeof(cmd->bitmap)); 3599 + 3600 + ath12k_dbg(ar->ab, ATH12K_DBG_WMI, 3601 + "wmi set pdev %u %s %08x %08x\n", 3602 + arg->pdev_id, arg->label, arg->bitmap[0], arg->bitmap[1]); 3603 + 3604 + ret = ath12k_wmi_cmd_send(wmi, skb, arg->cmd_id); 3605 + if (ret) { 3606 + ath12k_warn(ar->ab, "failed to send %s: %d\n", arg->label, ret); 3607 + dev_kfree_skb(skb); 3608 + } 3609 + 3610 + return ret; 3611 + } 3612 + 3613 + int ath12k_wmi_pdev_set_srg_bss_color_bitmap(struct ath12k *ar, 3614 + u32 pdev_id, const u32 *bitmap) 3615 + { 3616 + struct wmi_pdev_set_obss_bitmap_arg arg = { 3617 + .tlv_tag = WMI_TAG_PDEV_SRG_BSS_COLOR_BITMAP_CMD, 3618 + .pdev_id = pdev_id, 3619 + .cmd_id = WMI_PDEV_SET_SRG_BSS_COLOR_BITMAP_CMDID, 3620 + .bitmap = bitmap, 3621 + .label = "SRG bss color bitmap", 3622 + }; 3623 + 3624 + return ath12k_wmi_pdev_set_obss_bitmap(ar, &arg); 3625 + } 3626 + 3627 + int ath12k_wmi_pdev_set_srg_partial_bssid_bitmap(struct ath12k *ar, 3628 + u32 pdev_id, const u32 *bitmap) 3629 + { 3630 + struct wmi_pdev_set_obss_bitmap_arg arg = { 3631 + .tlv_tag = WMI_TAG_PDEV_SRG_PARTIAL_BSSID_BITMAP_CMD, 3632 + .pdev_id = pdev_id, 3633 + .cmd_id = WMI_PDEV_SET_SRG_PARTIAL_BSSID_BITMAP_CMDID, 3634 + .bitmap = bitmap, 3635 + .label = "SRG partial bssid bitmap", 3636 + }; 3637 + 3638 + return ath12k_wmi_pdev_set_obss_bitmap(ar, &arg); 3639 + } 3640 + 3641 + int ath12k_wmi_pdev_srg_obss_color_enable_bitmap(struct ath12k *ar, 3642 + u32 pdev_id, const u32 *bitmap) 3643 + { 3644 + struct wmi_pdev_set_obss_bitmap_arg arg = { 3645 + .tlv_tag = WMI_TAG_PDEV_SRG_OBSS_COLOR_ENABLE_BITMAP_CMD, 3646 + .pdev_id = pdev_id, 3647 + .cmd_id = WMI_PDEV_SET_SRG_OBSS_COLOR_ENABLE_BITMAP_CMDID, 3648 + .bitmap = bitmap, 3649 + .label = "SRG obss color enable bitmap", 3650 + }; 3651 + 3652 + return ath12k_wmi_pdev_set_obss_bitmap(ar, &arg); 3653 + } 3654 + 3655 + int ath12k_wmi_pdev_srg_obss_bssid_enable_bitmap(struct ath12k *ar, 3656 + u32 pdev_id, const u32 *bitmap) 3657 + { 3658 + struct wmi_pdev_set_obss_bitmap_arg arg = { 3659 + .tlv_tag = WMI_TAG_PDEV_SRG_OBSS_BSSID_ENABLE_BITMAP_CMD, 3660 + .pdev_id = pdev_id, 3661 + .cmd_id = WMI_PDEV_SET_SRG_OBSS_BSSID_ENABLE_BITMAP_CMDID, 3662 + .bitmap = bitmap, 3663 + .label = "SRG obss bssid enable bitmap", 3664 + }; 3665 + 3666 + return ath12k_wmi_pdev_set_obss_bitmap(ar, &arg); 3667 + } 3668 + 3669 + int ath12k_wmi_pdev_non_srg_obss_color_enable_bitmap(struct ath12k *ar, 3670 + u32 pdev_id, const u32 *bitmap) 3671 + { 3672 + struct wmi_pdev_set_obss_bitmap_arg arg = { 3673 + .tlv_tag = WMI_TAG_PDEV_NON_SRG_OBSS_COLOR_ENABLE_BITMAP_CMD, 3674 + .pdev_id = pdev_id, 3675 + .cmd_id = WMI_PDEV_SET_NON_SRG_OBSS_COLOR_ENABLE_BITMAP_CMDID, 3676 + .bitmap = bitmap, 3677 + .label = "non SRG obss color enable bitmap", 3678 + }; 3679 + 3680 + return ath12k_wmi_pdev_set_obss_bitmap(ar, &arg); 3681 + } 3682 + 3683 + int ath12k_wmi_pdev_non_srg_obss_bssid_enable_bitmap(struct ath12k *ar, 3684 + u32 pdev_id, const u32 *bitmap) 3685 + { 3686 + struct wmi_pdev_set_obss_bitmap_arg arg = { 3687 + .tlv_tag = WMI_TAG_PDEV_NON_SRG_OBSS_BSSID_ENABLE_BITMAP_CMD, 3688 + .pdev_id = pdev_id, 3689 + .cmd_id = WMI_PDEV_SET_NON_SRG_OBSS_BSSID_ENABLE_BITMAP_CMDID, 3690 + .bitmap = bitmap, 3691 + .label = "non SRG obss bssid enable bitmap", 3692 + }; 3693 + 3694 + return ath12k_wmi_pdev_set_obss_bitmap(ar, &arg); 3569 3695 } 3570 3696 3571 3697 int ath12k_wmi_obss_color_cfg_cmd(struct ath12k *ar, u32 vdev_id,
+47
drivers/net/wireless/ath/ath12k/wmi.h
··· 374 374 WMI_PDEV_DMA_RING_CFG_REQ_CMDID, 375 375 WMI_PDEV_HE_TB_ACTION_FRM_CMDID, 376 376 WMI_PDEV_PKTLOG_FILTER_CMDID, 377 + WMI_PDEV_SET_SRG_BSS_COLOR_BITMAP_CMDID = 0x403b, 378 + WMI_PDEV_SET_SRG_PARTIAL_BSSID_BITMAP_CMDID, 379 + WMI_PDEV_SET_SRG_OBSS_COLOR_ENABLE_BITMAP_CMDID, 380 + WMI_PDEV_SET_SRG_OBSS_BSSID_ENABLE_BITMAP_CMDID, 381 + WMI_PDEV_SET_NON_SRG_OBSS_COLOR_ENABLE_BITMAP_CMDID, 382 + WMI_PDEV_SET_NON_SRG_OBSS_BSSID_ENABLE_BITMAP_CMDID, 377 383 WMI_PDEV_SET_BIOS_SAR_TABLE_CMDID = 0x4044, 378 384 WMI_PDEV_SET_BIOS_GEO_TABLE_CMDID = 0x4045, 379 385 WMI_PDEV_SET_BIOS_INTERFACE_CMDID = 0x404A, ··· 1082 1076 WMI_PDEV_PARAM_RADIO_CHAN_STATS_ENABLE, 1083 1077 WMI_PDEV_PARAM_RADIO_DIAGNOSIS_ENABLE, 1084 1078 WMI_PDEV_PARAM_MESH_MCAST_ENABLE, 1079 + WMI_PDEV_PARAM_SET_CMD_OBSS_PD_THRESHOLD = 0xbc, 1080 + WMI_PDEV_PARAM_SET_CMD_OBSS_PD_PER_AC = 0xbe, 1081 + WMI_PDEV_PARAM_ENABLE_SR_PROHIBIT = 0xc6, 1085 1082 }; 1086 1083 1087 1084 enum wmi_tlv_vdev_param { ··· 1996 1987 WMI_TAG_SERVICE_READY_EXT2_EVENT = 0x334, 1997 1988 WMI_TAG_FILS_DISCOVERY_TMPL_CMD = 0x344, 1998 1989 WMI_TAG_MAC_PHY_CAPABILITIES_EXT = 0x36F, 1990 + WMI_TAG_PDEV_SRG_BSS_COLOR_BITMAP_CMD = 0x37b, 1991 + WMI_TAG_PDEV_SRG_PARTIAL_BSSID_BITMAP_CMD, 1992 + WMI_TAG_PDEV_SRG_OBSS_COLOR_ENABLE_BITMAP_CMD = 0x381, 1993 + WMI_TAG_PDEV_SRG_OBSS_BSSID_ENABLE_BITMAP_CMD, 1994 + WMI_TAG_PDEV_NON_SRG_OBSS_COLOR_ENABLE_BITMAP_CMD, 1995 + WMI_TAG_PDEV_NON_SRG_OBSS_BSSID_ENABLE_BITMAP_CMD, 1999 1996 WMI_TAG_REGULATORY_RULE_EXT_STRUCT = 0x3A9, 2000 1997 WMI_TAG_REG_CHAN_LIST_CC_EXT_EVENT, 2001 1998 WMI_TAG_TPC_STATS_GET_CMD = 0x38B, ··· 2259 2244 WMI_TLV_SERVICE_FREQINFO_IN_METADATA = 219, 2260 2245 WMI_TLV_SERVICE_EXT2_MSG = 220, 2261 2246 WMI_TLV_SERVICE_BEACON_PROTECTION_SUPPORT = 244, 2247 + WMI_TLV_SERVICE_SRG_SRP_SPATIAL_REUSE_SUPPORT = 249, 2262 2248 WMI_TLV_SERVICE_MBSS_PARAM_IN_VDEV_START_SUPPORT = 253, 2263 2249 2264 2250 WMI_MAX_EXT_SERVICE = 256, ··· 4941 4925 __le32 vdev_id; 4942 4926 } __packed; 4943 4927 4928 + struct wmi_pdev_obss_pd_bitmap_cmd { 4929 + __le32 tlv_header; 4930 + __le32 pdev_id; 4931 + __le32 bitmap[2]; 4932 + } __packed; 4933 + 4944 4934 #define ATH12K_BSS_COLOR_COLLISION_SCAN_PERIOD_MS 200 4945 4935 #define ATH12K_OBSS_COLOR_COLLISION_DETECTION_DISABLE 0 4946 4936 #define ATH12K_OBSS_COLOR_COLLISION_DETECTION 1 ··· 6351 6329 /* each WMI cmd can hold 58 channel entries at most */ 6352 6330 #define ATH12K_WMI_MAX_NUM_CHAN_PER_CMD 58 6353 6331 6332 + #define ATH12K_OBSS_PD_THRESHOLD_IN_DBM BIT(29) 6333 + #define ATH12K_OBSS_PD_SRG_EN BIT(30) 6334 + #define ATH12K_OBSS_PD_NON_SRG_EN BIT(31) 6335 + 6336 + struct ath12k_wmi_obss_pd_arg { 6337 + bool srp_support; 6338 + bool srg_enabled; 6339 + bool non_srg_enabled; 6340 + s8 srg_th; 6341 + s8 non_srg_th; 6342 + }; 6343 + 6354 6344 int ath12k_wmi_cmd_send(struct ath12k_wmi_pdev *wmi, struct sk_buff *skb, 6355 6345 u32 cmd_id); 6356 6346 struct sk_buff *ath12k_wmi_alloc_skb(struct ath12k_wmi_base *wmi_sc, u32 len); ··· 6466 6432 int ath12k_wmi_send_twt_disable_cmd(struct ath12k *ar, u32 pdev_id); 6467 6433 int ath12k_wmi_send_obss_spr_cmd(struct ath12k *ar, u32 vdev_id, 6468 6434 struct ieee80211_he_obss_pd *he_obss_pd); 6435 + u32 ath12k_wmi_build_obss_pd(const struct ath12k_wmi_obss_pd_arg *arg); 6436 + int ath12k_wmi_pdev_set_srg_bss_color_bitmap(struct ath12k *ar, u32 pdev_id, 6437 + const u32 *bitmap); 6438 + int ath12k_wmi_pdev_set_srg_partial_bssid_bitmap(struct ath12k *ar, u32 pdev_id, 6439 + const u32 *bitmap); 6440 + int ath12k_wmi_pdev_srg_obss_color_enable_bitmap(struct ath12k *ar, u32 pdev_id, 6441 + const u32 *bitmap); 6442 + int ath12k_wmi_pdev_srg_obss_bssid_enable_bitmap(struct ath12k *ar, u32 pdev_id, 6443 + const u32 *bitmap); 6444 + int ath12k_wmi_pdev_non_srg_obss_color_enable_bitmap(struct ath12k *ar, u32 pdev_id, 6445 + const u32 *bitmap); 6446 + int ath12k_wmi_pdev_non_srg_obss_bssid_enable_bitmap(struct ath12k *ar, u32 pdev_id, 6447 + const u32 *bitmap); 6469 6448 int ath12k_wmi_obss_color_cfg_cmd(struct ath12k *ar, u32 vdev_id, 6470 6449 u8 bss_color, u32 period, 6471 6450 bool enable);
+2 -7
drivers/net/wireless/broadcom/brcm80211/brcmsmac/phy/phy_lcn.c
··· 4790 4790 wlc_lcnphy_calib_modes(pi, PHY_PERICAL_PHYINIT); 4791 4791 } 4792 4792 4793 - static bool wlc_phy_txpwr_srom_read_lcnphy(struct brcms_phy *pi) 4793 + static void wlc_phy_txpwr_srom_read_lcnphy(struct brcms_phy *pi) 4794 4794 { 4795 4795 s8 txpwr = 0; 4796 4796 int i; ··· 4879 4879 sprom->ant_available_bg); 4880 4880 } 4881 4881 pi_lcn->lcnphy_cck_dig_filt_type = -1; 4882 - 4883 - return true; 4884 4882 } 4885 4883 4886 4884 void wlc_2064_vco_cal(struct brcms_phy *pi) ··· 4990 4992 pi->pi_fptr.radioloftget = wlc_lcnphy_get_radio_loft; 4991 4993 pi->pi_fptr.detach = wlc_phy_detach_lcnphy; 4992 4994 4993 - if (!wlc_phy_txpwr_srom_read_lcnphy(pi)) { 4994 - kfree(pi->u.pi_lcnphy); 4995 - return false; 4996 - } 4995 + wlc_phy_txpwr_srom_read_lcnphy(pi); 4997 4996 4998 4997 if (LCNREV_IS(pi->pubpi.phy_rev, 1)) { 4999 4998 if (pi_lcn->lcnphy_tempsense_option == 3) {
+2 -1
drivers/net/wireless/realtek/rtw88/usb.c
··· 965 965 struct sk_buff *rx_skb; 966 966 int i; 967 967 968 - rtwusb->rxwq = alloc_workqueue("rtw88_usb: rx wq", WQ_BH, 0); 968 + rtwusb->rxwq = alloc_workqueue("rtw88_usb: rx wq", WQ_BH | WQ_PERCPU, 969 + 0); 969 970 if (!rtwusb->rxwq) { 970 971 rtw_err(rtwdev, "failed to create RX work queue\n"); 971 972 return -ENOMEM;
+27 -4
drivers/net/wireless/realtek/rtw89/chan.c
··· 60 60 } 61 61 } 62 62 63 + static enum rtw89_tx_comp_band rtw89_get_tx_comp_band(enum rtw89_band band, 64 + u8 center_chan) 65 + { 66 + switch (band) { 67 + default: 68 + case RTW89_BAND_2G: 69 + return RTW89_TX_COMP_BAND_2GHZ; 70 + case RTW89_BAND_5G: 71 + if (center_chan < 149) 72 + return RTW89_TX_COMP_BAND_5GHZ_L; 73 + else 74 + return RTW89_TX_COMP_BAND_5GHZ_H; 75 + case RTW89_BAND_6G: 76 + if (center_chan < 65) 77 + return RTW89_TX_COMP_BAND_5GHZ_H; 78 + else if (center_chan < 193) 79 + return RTW89_TX_COMP_BAND_6GHZ_M; 80 + else 81 + return RTW89_TX_COMP_BAND_6GHZ_UH; 82 + } 83 + } 84 + 63 85 static enum rtw89_sc_offset rtw89_get_primary_chan_idx(enum rtw89_bandwidth bw, 64 86 u32 center_freq, 65 87 u32 primary_freq) ··· 145 123 146 124 chan->freq = center_freq; 147 125 chan->subband_type = rtw89_get_subband_type(band, center_chan); 126 + chan->tx_comp_band = rtw89_get_tx_comp_band(band, center_chan); 148 127 chan->pri_ch_idx = rtw89_get_primary_chan_idx(bandwidth, center_freq, 149 128 primary_freq); 150 129 chan->pri_sb_idx = rtw89_get_primary_sb_idx(center_chan, primary_chan, ··· 372 349 if (unlikely(!rtwvif_link->chanctx_assigned)) 373 350 return; 374 351 375 - cur = rtw89_vif_get_link_inst(rtwvif, 0); 376 - if (!cur || !cur->chanctx_assigned) 352 + cur = rtw89_get_designated_link(rtwvif); 353 + if (unlikely(!cur) || !cur->chanctx_assigned) 377 354 return; 378 355 379 356 if (cur == rtwvif_link) ··· 522 499 } 523 500 524 501 /* To be consistent with legacy behavior, expect the first active role 525 - * which uses RTW89_CHANCTX_0 to put at position 0, and make its first 526 - * link instance take RTW89_CHANCTX_0. (normalizing) 502 + * which uses RTW89_CHANCTX_0 to put at position 0 and its designated 503 + * link take RTW89_CHANCTX_0. (normalizing) 527 504 */ 528 505 list_for_each_entry(role, &mgnt->active_list, mgnt_entry) { 529 506 for (i = 0; i < role->links_inst_valid_num; i++) {
+39 -1
drivers/net/wireless/realtek/rtw89/core.h
··· 23 23 struct rtw89_h2c_rf_tssi; 24 24 struct rtw89_fw_txpwr_track_cfg; 25 25 struct rtw89_phy_rfk_log_fmt; 26 + struct rtw89_phy_calc_efuse_gain; 26 27 struct rtw89_debugfs; 27 28 struct rtw89_regd_data; 28 29 struct rtw89_wow_cam_info; ··· 113 112 114 113 RTW89_SUBBAND_NR, 115 114 RTW89_SUBBAND_2GHZ_5GHZ_NR = RTW89_CH_5G_BAND_4 + 1, 115 + }; 116 + 117 + enum rtw89_tx_comp_band { 118 + RTW89_TX_COMP_BAND_2GHZ, 119 + RTW89_TX_COMP_BAND_5GHZ_L, 120 + RTW89_TX_COMP_BAND_5GHZ_H, 121 + RTW89_TX_COMP_BAND_6GHZ_M, 122 + RTW89_TX_COMP_BAND_6GHZ_UH, 123 + 124 + RTW89_TX_COMP_BAND_NR, 116 125 }; 117 126 118 127 enum rtw89_gain_offset { ··· 1001 990 */ 1002 991 u32 freq; 1003 992 enum rtw89_subband subband_type; 993 + enum rtw89_tx_comp_band tx_comp_band; 1004 994 enum rtw89_sc_offset pri_ch_idx; 1005 995 u8 pri_sb_idx; 1006 996 }; ··· 3834 3822 s8 pw_ofst, enum rtw89_mac_idx mac_idx); 3835 3823 void (*digital_pwr_comp)(struct rtw89_dev *rtwdev, 3836 3824 enum rtw89_phy_idx phy_idx); 3825 + void (*calc_rx_gain_normal)(struct rtw89_dev *rtwdev, 3826 + const struct rtw89_chan *chan, 3827 + enum rtw89_rf_path path, 3828 + enum rtw89_phy_idx phy_idx, 3829 + struct rtw89_phy_calc_efuse_gain *calc); 3837 3830 int (*pwr_on_func)(struct rtw89_dev *rtwdev); 3838 3831 int (*pwr_off_func)(struct rtw89_dev *rtwdev); 3839 3832 void (*query_rxdesc)(struct rtw89_dev *rtwdev, ··· 4778 4761 RTW89_FW_FEATURE_ADDR_CAM_V0, 4779 4762 RTW89_FW_FEATURE_SER_L1_BY_EVENT, 4780 4763 RTW89_FW_FEATURE_SIM_SER_L0L1_BY_HALT_H2C, 4764 + RTW89_FW_FEATURE_LPS_ML_INFO_V1, 4781 4765 4782 4766 NUM_OF_RTW89_FW_FEATURES, 4783 4767 }; ··· 4842 4824 const struct rtw89_regd_data *regd; 4843 4825 const struct rtw89_fw_element_hdr *afe; 4844 4826 const struct rtw89_fw_element_hdr *diag_mac; 4827 + const struct rtw89_fw_element_hdr *tx_comp; 4845 4828 }; 4846 4829 4847 4830 enum rtw89_fw_mss_dev_type { ··· 5705 5686 u16 ifs_clm_cckfa; 5706 5687 u16 ifs_clm_cckcca_excl_fa; 5707 5688 u16 ifs_clm_total_ifs; 5708 - u8 ifs_clm_his[RTW89_IFS_CLM_NUM]; 5689 + u16 ifs_clm_his[RTW89_IFS_CLM_NUM]; 5709 5690 u16 ifs_clm_avg[RTW89_IFS_CLM_NUM]; 5710 5691 u16 ifs_clm_cca[RTW89_IFS_CLM_NUM]; 5711 5692 u8 ifs_clm_tx_ratio; ··· 5904 5885 s8 offset_base[RTW89_PHY_NUM]; /* S(8, 4) */ 5905 5886 s8 rssi_base[RTW89_PHY_NUM]; /* S(8, 4) */ 5906 5887 s8 comp[RF_PATH_MAX][RTW89_SUBBAND_NR]; /* S(8, 0) */ 5888 + }; 5889 + 5890 + struct rtw89_phy_calc_efuse_gain { 5891 + s8 cck_mean_gain_bias; 5892 + s8 cck_rpl_ofst; 5893 + s8 rssi_ofst; 5907 5894 }; 5908 5895 5909 5896 #define RTW89_MAX_PATTERN_NUM 18 ··· 7364 7339 7365 7340 if (chip->ops->digital_pwr_comp) 7366 7341 chip->ops->digital_pwr_comp(rtwdev, phy_idx); 7342 + } 7343 + 7344 + static inline 7345 + void rtw89_chip_calc_rx_gain_normal(struct rtw89_dev *rtwdev, 7346 + const struct rtw89_chan *chan, 7347 + enum rtw89_rf_path path, 7348 + enum rtw89_phy_idx phy_idx, 7349 + struct rtw89_phy_calc_efuse_gain *calc) 7350 + { 7351 + const struct rtw89_chip_info *chip = rtwdev->chip; 7352 + 7353 + if (chip->ops->calc_rx_gain_normal) 7354 + chip->ops->calc_rx_gain_normal(rtwdev, chan, path, phy_idx, calc); 7367 7355 } 7368 7356 7369 7357 static inline void rtw89_load_txpwr_table(struct rtw89_dev *rtwdev,
+73 -26
drivers/net/wireless/realtek/rtw89/debug.c
··· 826 826 s8 *bufp, tmp; 827 827 int ret; 828 828 829 - bufp = vzalloc(map->addr_to - map->addr_from + 4); 830 - if (!bufp) 831 - return -ENOMEM; 832 - 833 829 if (path_num == 1) 834 830 max_valid_addr = map->addr_to_1ss; 835 831 else ··· 833 837 834 838 if (max_valid_addr == 0) 835 839 return -EOPNOTSUPP; 840 + 841 + bufp = vzalloc(map->addr_to - map->addr_from + 4); 842 + if (!bufp) 843 + return -ENOMEM; 836 844 837 845 for (addr = map->addr_from; addr <= max_valid_addr; addr += 4) { 838 846 ret = rtw89_mac_txpwr_read32(rtwdev, RTW89_PHY_0, addr, &val); ··· 3538 3538 return count; 3539 3539 } 3540 3540 3541 - static int rtw89_dbg_trigger_ctrl_error_by_halt_h2c(struct rtw89_dev *rtwdev) 3541 + static int rtw89_dbg_trigger_l1_error_by_halt_h2c_ax(struct rtw89_dev *rtwdev) 3542 3542 { 3543 3543 if (!test_bit(RTW89_FLAG_FW_RDY, rtwdev->flags)) 3544 3544 return -EBUSY; ··· 3546 3546 return rtw89_mac_set_err_status(rtwdev, MAC_AX_ERR_L1_RESET_FORCE); 3547 3547 } 3548 3548 3549 - static int rtw89_dbg_trigger_ctrl_error(struct rtw89_dev *rtwdev) 3549 + static int rtw89_dbg_trigger_l1_error_by_halt_h2c_be(struct rtw89_dev *rtwdev) 3550 + { 3551 + if (!test_bit(RTW89_FLAG_FW_RDY, rtwdev->flags)) 3552 + return -EBUSY; 3553 + 3554 + rtw89_write32_set(rtwdev, R_BE_FW_TRIGGER_IDCT_ISR, 3555 + B_BE_DMAC_FW_TRIG_IDCT | B_BE_DMAC_FW_ERR_IDCT_IMR); 3556 + 3557 + return 0; 3558 + } 3559 + 3560 + static int rtw89_dbg_trigger_l1_error_by_halt_h2c(struct rtw89_dev *rtwdev) 3561 + { 3562 + const struct rtw89_chip_info *chip = rtwdev->chip; 3563 + 3564 + switch (chip->chip_gen) { 3565 + case RTW89_CHIP_AX: 3566 + return rtw89_dbg_trigger_l1_error_by_halt_h2c_ax(rtwdev); 3567 + case RTW89_CHIP_BE: 3568 + return rtw89_dbg_trigger_l1_error_by_halt_h2c_be(rtwdev); 3569 + default: 3570 + return -EOPNOTSUPP; 3571 + } 3572 + } 3573 + 3574 + static int rtw89_dbg_trigger_l1_error(struct rtw89_dev *rtwdev) 3550 3575 { 3551 3576 const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def; 3552 3577 struct rtw89_cpuio_ctrl ctrl_para = {0}; ··· 3579 3554 int ret; 3580 3555 3581 3556 if (RTW89_CHK_FW_FEATURE(SIM_SER_L0L1_BY_HALT_H2C, &rtwdev->fw)) 3582 - return rtw89_dbg_trigger_ctrl_error_by_halt_h2c(rtwdev); 3557 + return rtw89_dbg_trigger_l1_error_by_halt_h2c(rtwdev); 3583 3558 3584 3559 rtw89_leave_ps_mode(rtwdev); 3585 3560 ··· 3601 3576 return 0; 3602 3577 } 3603 3578 3604 - static int rtw89_dbg_trigger_mac_error_ax(struct rtw89_dev *rtwdev) 3579 + static int rtw89_dbg_trigger_l0_error_ax(struct rtw89_dev *rtwdev) 3605 3580 { 3606 3581 u16 val16; 3607 3582 u8 val8; ··· 3623 3598 return 0; 3624 3599 } 3625 3600 3626 - static int rtw89_dbg_trigger_mac_error_be(struct rtw89_dev *rtwdev) 3601 + static int rtw89_dbg_trigger_l0_error_be(struct rtw89_dev *rtwdev) 3627 3602 { 3603 + u8 val8; 3628 3604 int ret; 3629 3605 3630 3606 ret = rtw89_mac_check_mac_en(rtwdev, RTW89_MAC_0, RTW89_CMAC_SEL); 3631 3607 if (ret) 3632 3608 return ret; 3633 3609 3634 - rtw89_write32_set(rtwdev, R_BE_CMAC_FW_TRIGGER_IDCT_ISR, 3635 - B_BE_CMAC_FW_TRIG_IDCT | B_BE_CMAC_FW_ERR_IDCT_IMR); 3610 + val8 = rtw89_read8(rtwdev, R_BE_CMAC_FUNC_EN); 3611 + rtw89_write8(rtwdev, R_BE_CMAC_FUNC_EN, val8 & ~B_BE_TMAC_EN); 3612 + mdelay(1); 3613 + rtw89_write8(rtwdev, R_BE_CMAC_FUNC_EN, val8); 3636 3614 3637 3615 return 0; 3638 3616 } 3639 3617 3640 - static int rtw89_dbg_trigger_mac_error_by_halt_h2c(struct rtw89_dev *rtwdev) 3618 + static int rtw89_dbg_trigger_l0_error_by_halt_h2c_ax(struct rtw89_dev *rtwdev) 3641 3619 { 3642 3620 if (!test_bit(RTW89_FLAG_FW_RDY, rtwdev->flags)) 3643 3621 return -EBUSY; ··· 3648 3620 return rtw89_mac_set_err_status(rtwdev, MAC_AX_ERR_L0_RESET_FORCE); 3649 3621 } 3650 3622 3651 - static int rtw89_dbg_trigger_mac_error(struct rtw89_dev *rtwdev) 3623 + static int rtw89_dbg_trigger_l0_error_by_halt_h2c_be(struct rtw89_dev *rtwdev) 3624 + { 3625 + if (!test_bit(RTW89_FLAG_FW_RDY, rtwdev->flags)) 3626 + return -EBUSY; 3627 + 3628 + rtw89_write32_set(rtwdev, R_BE_CMAC_FW_TRIGGER_IDCT_ISR, 3629 + B_BE_CMAC_FW_TRIG_IDCT | B_BE_CMAC_FW_ERR_IDCT_IMR); 3630 + 3631 + return 0; 3632 + } 3633 + 3634 + static int rtw89_dbg_trigger_l0_error(struct rtw89_dev *rtwdev) 3652 3635 { 3653 3636 const struct rtw89_chip_info *chip = rtwdev->chip; 3654 - 3655 - if (RTW89_CHK_FW_FEATURE(SIM_SER_L0L1_BY_HALT_H2C, &rtwdev->fw)) 3656 - return rtw89_dbg_trigger_mac_error_by_halt_h2c(rtwdev); 3657 - 3658 - rtw89_leave_ps_mode(rtwdev); 3637 + int (*sim_l0_by_halt_h2c)(struct rtw89_dev *rtwdev); 3638 + int (*sim_l0)(struct rtw89_dev *rtwdev); 3659 3639 3660 3640 switch (chip->chip_gen) { 3661 3641 case RTW89_CHIP_AX: 3662 - return rtw89_dbg_trigger_mac_error_ax(rtwdev); 3642 + sim_l0_by_halt_h2c = rtw89_dbg_trigger_l0_error_by_halt_h2c_ax; 3643 + sim_l0 = rtw89_dbg_trigger_l0_error_ax; 3644 + break; 3663 3645 case RTW89_CHIP_BE: 3664 - return rtw89_dbg_trigger_mac_error_be(rtwdev); 3646 + sim_l0_by_halt_h2c = rtw89_dbg_trigger_l0_error_by_halt_h2c_be; 3647 + sim_l0 = rtw89_dbg_trigger_l0_error_be; 3648 + break; 3665 3649 default: 3666 3650 return -EOPNOTSUPP; 3667 3651 } 3652 + 3653 + if (RTW89_CHK_FW_FEATURE(SIM_SER_L0L1_BY_HALT_H2C, &rtwdev->fw)) 3654 + return sim_l0_by_halt_h2c(rtwdev); 3655 + 3656 + rtw89_leave_ps_mode(rtwdev); 3657 + 3658 + return sim_l0(rtwdev); 3668 3659 } 3669 3660 3670 3661 static ssize_t ··· 3700 3653 3701 3654 enum rtw89_dbg_crash_simulation_type { 3702 3655 RTW89_DBG_SIM_CPU_EXCEPTION = 1, 3703 - RTW89_DBG_SIM_CTRL_ERROR = 2, 3704 - RTW89_DBG_SIM_MAC_ERROR = 3, 3656 + RTW89_DBG_SIM_L1_ERROR = 2, 3657 + RTW89_DBG_SIM_L0_ERROR = 3, 3705 3658 }; 3706 3659 3707 3660 static ssize_t ··· 3726 3679 return -EOPNOTSUPP; 3727 3680 sim = rtw89_fw_h2c_trigger_cpu_exception; 3728 3681 break; 3729 - case RTW89_DBG_SIM_CTRL_ERROR: 3730 - sim = rtw89_dbg_trigger_ctrl_error; 3682 + case RTW89_DBG_SIM_L1_ERROR: 3683 + sim = rtw89_dbg_trigger_l1_error; 3731 3684 break; 3732 - case RTW89_DBG_SIM_MAC_ERROR: 3733 - sim = rtw89_dbg_trigger_mac_error; 3685 + case RTW89_DBG_SIM_L0_ERROR: 3686 + sim = rtw89_dbg_trigger_l0_error; 3734 3687 3735 3688 /* Driver SER flow won't get involved; only FW will. */ 3736 3689 announce = false;
+1
drivers/net/wireless/realtek/rtw89/debug.h
··· 31 31 RTW89_DBG_CHAN = BIT(20), 32 32 RTW89_DBG_ACPI = BIT(21), 33 33 RTW89_DBG_EDCCA = BIT(22), 34 + RTW89_DBG_PS = BIT(23), 34 35 35 36 RTW89_DBG_UNEXP = BIT(31), 36 37 };
+288 -9
drivers/net/wireless/realtek/rtw89/fw.c
··· 922 922 __DIS_FW_FEAT(RTL8922A, ge, 0, 35, 84, 0, WITH_RFK_PRE_NOTIFY, G), 923 923 __CFG_FW_FEAT(RTL8922A, ge, 0, 35, 84, 0, RFK_PRE_NOTIFY_MCC_V1), 924 924 __CFG_FW_FEAT(RTL8922A, lt, 0, 35, 84, 0, ADDR_CAM_V0), 925 + __CFG_FW_FEAT(RTL8922A, ge, 0, 35, 97, 0, SIM_SER_L0L1_BY_HALT_H2C), 925 926 }; 926 927 927 928 static void rtw89_fw_iterate_feature_cfg(struct rtw89_fw_info *fw, ··· 1383 1382 return 0; 1384 1383 } 1385 1384 1385 + static 1386 + int rtw89_build_tx_comp_from_elm(struct rtw89_dev *rtwdev, 1387 + const struct rtw89_fw_element_hdr *elm, 1388 + const union rtw89_fw_element_arg arg) 1389 + { 1390 + struct rtw89_fw_elm_info *elm_info = &rtwdev->fw.elm_info; 1391 + struct rtw89_hal *hal = &rtwdev->hal; 1392 + u16 aid; 1393 + 1394 + aid = le16_to_cpu(elm->aid); 1395 + if (aid && aid != hal->aid) 1396 + return 1; /* ignore if aid not matched */ 1397 + else if (elm_info->tx_comp) 1398 + return 1; /* ignore if an element is existing */ 1399 + 1400 + elm_info->tx_comp = elm; 1401 + 1402 + return 0; 1403 + } 1404 + 1386 1405 static const struct rtw89_fw_element_handler __fw_element_handlers[] = { 1387 1406 [RTW89_FW_ELEMENT_ID_BBMCU0] = {__rtw89_fw_recognize_from_elm, 1388 1407 { .fw_type = RTW89_FW_BBMCU0 }, NULL}, ··· 1493 1472 }, 1494 1473 [RTW89_FW_ELEMENT_ID_DIAG_MAC] = { 1495 1474 rtw89_recognize_diag_mac_from_elm, {}, NULL, 1475 + }, 1476 + [RTW89_FW_ELEMENT_ID_TX_COMP] = { 1477 + rtw89_build_tx_comp_from_elm, {}, NULL, 1496 1478 }, 1497 1479 }; 1498 1480 ··· 3278 3254 3279 3255 ret = read_poll_timeout(rtw89_phy_read32_mask, done, done, 50, 5000, 3280 3256 true, rtwdev, R_CHK_LPS_STAT, B_CHK_LPS_STAT); 3257 + if (ret) 3258 + rtw89_warn(rtwdev, "h2c_lps_ml_cmn_info done polling timeout\n"); 3259 + 3260 + return 0; 3261 + fail: 3262 + dev_kfree_skb_any(skb); 3263 + 3264 + return ret; 3265 + } 3266 + 3267 + void rtw89_bb_lps_cmn_info_rx_gain_fill(struct rtw89_dev *rtwdev, 3268 + struct rtw89_bb_link_info_rx_gain *h2c_gain, 3269 + const struct rtw89_chan *chan, u8 phy_idx) 3270 + { 3271 + const struct rtw89_phy_bb_gain_info_be *gain = &rtwdev->bb_gain.be; 3272 + enum rtw89_bb_link_rx_gain_table_type tab_idx; 3273 + struct rtw89_chan chan_bcn; 3274 + u8 bw = chan->band_width; 3275 + u8 gain_band; 3276 + u8 bw_idx; 3277 + u8 path; 3278 + int i; 3279 + 3280 + rtw89_chan_create(&chan_bcn, chan->primary_channel, chan->primary_channel, 3281 + chan->band_type, RTW89_CHANNEL_WIDTH_20); 3282 + 3283 + for (tab_idx = RTW89_BB_PS_LINK_RX_GAIN_TAB_BCN_PATH_A; 3284 + tab_idx < RTW89_BB_PS_LINK_RX_GAIN_TAB_MAX; tab_idx++) { 3285 + struct rtw89_phy_calc_efuse_gain calc = {}; 3286 + 3287 + path = (tab_idx & BIT(0)) ? (RF_PATH_B) : (RF_PATH_A); 3288 + if (tab_idx & BIT(1)) { 3289 + rtw89_chip_calc_rx_gain_normal(rtwdev, chan, path, phy_idx, 3290 + &calc); 3291 + gain_band = rtw89_subband_to_gain_band_be(chan->subband_type); 3292 + if (bw > RTW89_CHANNEL_WIDTH_40) 3293 + bw_idx = RTW89_BB_BW_80_160_320; 3294 + else 3295 + bw_idx = RTW89_BB_BW_20_40; 3296 + } else { 3297 + rtw89_chip_calc_rx_gain_normal(rtwdev, &chan_bcn, path, phy_idx, 3298 + &calc); 3299 + gain_band = rtw89_subband_to_gain_band_be(chan_bcn.subband_type); 3300 + bw_idx = RTW89_BB_BW_20_40; 3301 + } 3302 + 3303 + /* efuse ofst and comp */ 3304 + h2c_gain->gain_ofst[tab_idx] = calc.rssi_ofst; 3305 + h2c_gain->cck_gain_ofst[tab_idx] = calc.cck_rpl_ofst; 3306 + h2c_gain->cck_rpl_bias_comp[tab_idx][0] = calc.cck_mean_gain_bias; 3307 + h2c_gain->cck_rpl_bias_comp[tab_idx][1] = calc.cck_mean_gain_bias; 3308 + 3309 + for (i = 0; i < TIA_GAIN_NUM; i++) { 3310 + h2c_gain->gain_err_tia[tab_idx][i] = 3311 + cpu_to_le16(gain->tia_gain[gain_band][bw_idx][path][i]); 3312 + } 3313 + memcpy(h2c_gain->gain_err_lna[tab_idx], 3314 + gain->lna_gain[gain_band][bw_idx][path], 3315 + LNA_GAIN_NUM); 3316 + memcpy(h2c_gain->op1db_lna[tab_idx], 3317 + gain->lna_op1db[gain_band][bw_idx][path], 3318 + LNA_GAIN_NUM); 3319 + memcpy(h2c_gain->op1db_tia[tab_idx], 3320 + gain->tia_lna_op1db[gain_band][bw_idx][path], 3321 + LNA_GAIN_NUM + 1); 3322 + 3323 + memcpy(h2c_gain->rpl_bias_comp_bw[tab_idx]._20M, 3324 + gain->rpl_ofst_20[gain_band][path], 3325 + RTW89_BW20_SC_20M); 3326 + memcpy(h2c_gain->rpl_bias_comp_bw[tab_idx]._40M, 3327 + gain->rpl_ofst_40[gain_band][path], 3328 + RTW89_BW20_SC_40M); 3329 + memcpy(h2c_gain->rpl_bias_comp_bw[tab_idx]._80M, 3330 + gain->rpl_ofst_80[gain_band][path], 3331 + RTW89_BW20_SC_80M); 3332 + memcpy(h2c_gain->rpl_bias_comp_bw[tab_idx]._160M, 3333 + gain->rpl_ofst_160[gain_band][path], 3334 + RTW89_BW20_SC_160M); 3335 + } 3336 + } 3337 + 3338 + int rtw89_fw_h2c_lps_ml_cmn_info_v1(struct rtw89_dev *rtwdev, 3339 + struct rtw89_vif *rtwvif) 3340 + { 3341 + static const u8 bcn_bw_ofst[] = {0, 0, 0, 3, 6, 9, 0, 12}; 3342 + const struct rtw89_chip_info *chip = rtwdev->chip; 3343 + struct rtw89_efuse *efuse = &rtwdev->efuse; 3344 + struct rtw89_h2c_lps_ml_cmn_info_v1 *h2c; 3345 + struct rtw89_vif_link *rtwvif_link; 3346 + const struct rtw89_chan *chan; 3347 + struct rtw89_bb_ctx *bb; 3348 + u32 len = sizeof(*h2c); 3349 + unsigned int link_id; 3350 + struct sk_buff *skb; 3351 + u8 beacon_bw_ofst; 3352 + u32 done; 3353 + int ret; 3354 + 3355 + if (chip->chip_gen != RTW89_CHIP_BE) 3356 + return 0; 3357 + 3358 + skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len); 3359 + if (!skb) { 3360 + rtw89_err(rtwdev, "failed to alloc skb for h2c lps_ml_cmn_info_v1\n"); 3361 + return -ENOMEM; 3362 + } 3363 + skb_put(skb, len); 3364 + h2c = (struct rtw89_h2c_lps_ml_cmn_info_v1 *)skb->data; 3365 + 3366 + h2c->fmt_id = 0x20; 3367 + 3368 + h2c->mlo_dbcc_mode = cpu_to_le32(rtwdev->mlo_dbcc_mode); 3369 + h2c->rfe_type = efuse->rfe_type; 3370 + h2c->rssi_main = U8_MAX; 3371 + 3372 + memset(h2c->link_id, 0xfe, RTW89_BB_PS_LINK_BUF_MAX); 3373 + 3374 + rtw89_vif_for_each_link(rtwvif, rtwvif_link, link_id) { 3375 + u8 phy_idx = rtwvif_link->phy_idx; 3376 + 3377 + bb = rtw89_get_bb_ctx(rtwdev, phy_idx); 3378 + chan = rtw89_chan_get(rtwdev, rtwvif_link->chanctx_idx); 3379 + 3380 + h2c->link_id[phy_idx] = phy_idx; 3381 + h2c->central_ch[phy_idx] = chan->channel; 3382 + h2c->pri_ch[phy_idx] = chan->primary_channel; 3383 + h2c->band[phy_idx] = chan->band_type; 3384 + h2c->bw[phy_idx] = chan->band_width; 3385 + 3386 + if (rtwvif_link->bcn_bw_idx < ARRAY_SIZE(bcn_bw_ofst)) { 3387 + beacon_bw_ofst = bcn_bw_ofst[rtwvif_link->bcn_bw_idx]; 3388 + h2c->dup_bcn_ofst[phy_idx] = beacon_bw_ofst; 3389 + } 3390 + 3391 + if (h2c->rssi_main > bb->ch_info.rssi_min) 3392 + h2c->rssi_main = bb->ch_info.rssi_min; 3393 + 3394 + rtw89_bb_lps_cmn_info_rx_gain_fill(rtwdev, 3395 + &h2c->rx_gain[phy_idx], 3396 + chan, phy_idx); 3397 + } 3398 + 3399 + rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 3400 + H2C_CAT_OUTSRC, H2C_CL_OUTSRC_DM, 3401 + H2C_FUNC_FW_LPS_ML_CMN_INFO, 0, 0, len); 3402 + 3403 + rtw89_phy_write32_mask(rtwdev, R_CHK_LPS_STAT_BE4, B_CHK_LPS_STAT, 0); 3404 + ret = rtw89_h2c_tx(rtwdev, skb, false); 3405 + if (ret) { 3406 + rtw89_err(rtwdev, "failed to send h2c\n"); 3407 + goto fail; 3408 + } 3409 + 3410 + ret = read_poll_timeout(rtw89_phy_read32_mask, done, done, 50, 5000, 3411 + true, rtwdev, R_CHK_LPS_STAT_BE4, B_CHK_LPS_STAT); 3281 3412 if (ret) 3282 3413 rtw89_warn(rtwdev, "h2c_lps_ml_cmn_info done polling timeout\n"); 3283 3414 ··· 7292 7113 int rtw89_fw_h2c_rf_tssi(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx, 7293 7114 const struct rtw89_chan *chan, enum rtw89_tssi_mode tssi_mode) 7294 7115 { 7116 + const struct rtw89_chip_info *chip = rtwdev->chip; 7295 7117 struct rtw89_efuse *efuse = &rtwdev->efuse; 7296 7118 struct rtw89_hal *hal = &rtwdev->hal; 7297 7119 struct rtw89_h2c_rf_tssi *h2c; ··· 7313 7133 h2c->ch = chan->channel; 7314 7134 h2c->bw = chan->band_width; 7315 7135 h2c->band = chan->band_type; 7316 - h2c->hwtx_en = true; 7317 7136 h2c->cv = hal->cv; 7318 7137 h2c->tssi_mode = tssi_mode; 7319 7138 h2c->rfe_type = efuse->rfe_type; 7139 + 7140 + if (chip->chip_id == RTL8922A) 7141 + h2c->hwtx_en = true; 7142 + else 7143 + h2c->hwtx_en = false; 7320 7144 7321 7145 rtw89_phy_rfk_tssi_fill_fwcmd_efuse_to_de(rtwdev, phy_idx, chan, h2c); 7322 7146 rtw89_phy_rfk_tssi_fill_fwcmd_tmeter_tbl(rtwdev, phy_idx, chan, h2c); ··· 7504 7320 skb_put(skb, len); 7505 7321 h2c = (struct rtw89_h2c_rf_dack *)skb->data; 7506 7322 7507 - h2c->len = cpu_to_le32(len); 7508 - h2c->phy = cpu_to_le32(phy_idx); 7509 - h2c->type = cpu_to_le32(0); 7323 + h2c->len = len; 7324 + h2c->phy = phy_idx; 7325 + h2c->type = 0; 7510 7326 7511 7327 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 7512 7328 H2C_CAT_OUTSRC, H2C_CL_OUTSRC_RF_FW_RFK, ··· 7615 7431 return ret; 7616 7432 } 7617 7433 7434 + int rtw89_fw_h2c_rf_txiqk(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx, 7435 + const struct rtw89_chan *chan) 7436 + { 7437 + struct rtw89_h2c_rf_txiqk *h2c; 7438 + u32 len = sizeof(*h2c); 7439 + struct sk_buff *skb; 7440 + int ret; 7441 + 7442 + skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len); 7443 + if (!skb) { 7444 + rtw89_err(rtwdev, "failed to alloc skb for h2c RF TXIQK\n"); 7445 + return -ENOMEM; 7446 + } 7447 + skb_put(skb, len); 7448 + h2c = (struct rtw89_h2c_rf_txiqk *)skb->data; 7449 + 7450 + h2c->len = len; 7451 + h2c->phy = phy_idx; 7452 + h2c->txiqk_enable = true; 7453 + h2c->is_wb_txiqk = true; 7454 + h2c->kpath = RF_AB; 7455 + h2c->cur_band = chan->band_type; 7456 + h2c->cur_bw = chan->band_width; 7457 + h2c->cur_ch = chan->channel; 7458 + h2c->txiqk_dbg_en = rtw89_debug_is_enabled(rtwdev, RTW89_DBG_RFK); 7459 + 7460 + rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 7461 + H2C_CAT_OUTSRC, H2C_CL_OUTSRC_RF_FW_RFK, 7462 + H2C_FUNC_RFK_TXIQK_OFFOAD, 0, 0, len); 7463 + 7464 + ret = rtw89_h2c_tx(rtwdev, skb, false); 7465 + if (ret) { 7466 + rtw89_err(rtwdev, "failed to send h2c\n"); 7467 + goto fail; 7468 + } 7469 + 7470 + return 0; 7471 + fail: 7472 + dev_kfree_skb_any(skb); 7473 + 7474 + return ret; 7475 + } 7476 + 7477 + int rtw89_fw_h2c_rf_cim3k(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx, 7478 + const struct rtw89_chan *chan) 7479 + { 7480 + struct rtw89_h2c_rf_cim3k *h2c; 7481 + u32 len = sizeof(*h2c); 7482 + struct sk_buff *skb; 7483 + int ret; 7484 + 7485 + skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len); 7486 + if (!skb) { 7487 + rtw89_err(rtwdev, "failed to alloc skb for h2c RF CIM3K\n"); 7488 + return -ENOMEM; 7489 + } 7490 + skb_put(skb, len); 7491 + h2c = (struct rtw89_h2c_rf_cim3k *)skb->data; 7492 + 7493 + h2c->len = len; 7494 + h2c->phy = phy_idx; 7495 + h2c->kpath = RF_AB; 7496 + h2c->cur_band = chan->band_type; 7497 + h2c->cur_bw = chan->band_width; 7498 + h2c->cur_ch = chan->channel; 7499 + h2c->cim3k_dbg_en = rtw89_debug_is_enabled(rtwdev, RTW89_DBG_RFK); 7500 + 7501 + rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 7502 + H2C_CAT_OUTSRC, H2C_CL_OUTSRC_RF_FW_RFK, 7503 + H2C_FUNC_RFK_CIM3K_OFFOAD, 0, 0, len); 7504 + 7505 + ret = rtw89_h2c_tx(rtwdev, skb, false); 7506 + if (ret) { 7507 + rtw89_err(rtwdev, "failed to send h2c\n"); 7508 + goto fail; 7509 + } 7510 + 7511 + return 0; 7512 + fail: 7513 + dev_kfree_skb_any(skb); 7514 + 7515 + return ret; 7516 + } 7517 + 7618 7518 int rtw89_fw_h2c_raw_with_hdr(struct rtw89_dev *rtwdev, 7619 7519 u8 h2c_class, u8 h2c_func, u8 *buf, u16 len, 7620 7520 bool rack, bool dack) ··· 7782 7514 lockdep_assert_wiphy(rtwdev->hw->wiphy); 7783 7515 7784 7516 __rtw89_fw_free_all_early_h2c(rtwdev); 7517 + } 7518 + 7519 + void rtw89_fw_c2h_dummy_handler(struct rtw89_dev *rtwdev, struct sk_buff *c2h, u32 len) 7520 + { 7521 + struct rtw89_fw_c2h_attr *attr = RTW89_SKB_C2H_CB(c2h); 7522 + u8 category = attr->category; 7523 + u8 class = attr->class; 7524 + u8 func = attr->func; 7525 + 7526 + rtw89_debug(rtwdev, RTW89_DBG_FW, 7527 + "C2H cate=%u cls=%u func=%u is dummy\n", category, class, func); 7785 7528 } 7786 7529 7787 7530 static void rtw89_fw_c2h_parse_attr(struct sk_buff *c2h) ··· 9027 8748 if (tmp == scan_rtwvif) 9028 8749 continue; 9029 8750 9030 - tmp_link = rtw89_vif_get_link_inst(tmp, 0); 9031 - if (unlikely(!tmp_link)) { 9032 - rtw89_debug(rtwdev, RTW89_DBG_HW_SCAN, 9033 - "hw scan: no HW-0 link for extra op\n"); 8751 + tmp_link = rtw89_get_designated_link(tmp); 8752 + if (unlikely(!tmp_link)) 9034 8753 continue; 9035 - } 9036 8754 9037 8755 tmp_chan = rtw89_chan_get(rtwdev, tmp_link->chanctx_idx); 9038 8756 *ext = (struct rtw89_hw_scan_extra_op){ ··· 9055 8779 struct cfg80211_scan_request *req = &scan_req->req; 9056 8780 const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, 9057 8781 rtwvif_link->chanctx_idx); 8782 + struct ieee80211_vif *vif = rtwvif_link_to_vif(rtwvif_link); 9058 8783 struct rtw89_vif *rtwvif = rtwvif_link->rtwvif; 9059 8784 struct rtw89_chanctx_pause_parm pause_parm = { 9060 8785 .rsn = RTW89_CHANCTX_PAUSE_REASON_HW_SCAN, ··· 9084 8807 if (req->flags & NL80211_SCAN_FLAG_RANDOM_ADDR) 9085 8808 get_random_mask_addr(mac_addr, req->mac_addr, 9086 8809 req->mac_addr_mask); 8810 + else if (ieee80211_vif_is_mld(vif)) 8811 + ether_addr_copy(mac_addr, vif->addr); 9087 8812 else 9088 8813 ether_addr_copy(mac_addr, rtwvif_link->mac_addr); 9089 8814
+180 -8
drivers/net/wireless/realtek/rtw89/fw.h
··· 2017 2017 u8 dup_bcn_ofst[RTW89_PHY_NUM]; 2018 2018 } __packed; 2019 2019 2020 + #define BB_RX_GAIN_TB_RSSI_COMP_NUM 3 2021 + #define BB_RX_GAIN_CCK_RPL_BIAS_COMP_NUM 2 2022 + #define BB_GT2_GS_IDX_NUM 11 2023 + #define BB_GT2_WB_GIDX_ELNA_NUM 16 2024 + #define BB_GT2_G_ELNA_NUM 2 2025 + 2026 + enum rtw89_bb_link_rx_gain_table_type { 2027 + RTW89_BB_PS_LINK_RX_GAIN_TAB_BCN_PATH_A = 0x00, 2028 + RTW89_BB_PS_LINK_RX_GAIN_TAB_BCN_PATH_B = 0x01, 2029 + RTW89_BB_PS_LINK_RX_GAIN_TAB_NOR_PATH_A = 0x02, 2030 + RTW89_BB_PS_LINK_RX_GAIN_TAB_NOR_PATH_B = 0x03, 2031 + RTW89_BB_PS_LINK_RX_GAIN_TAB_MAX, 2032 + }; 2033 + 2034 + enum rtw89_bb_ps_link_buf_id { 2035 + RTW89_BB_PS_LINK_BUF_0 = 0x00, 2036 + RTW89_BB_PS_LINK_BUF_1 = 0x01, 2037 + RTW89_BB_PS_LINK_BUF_2 = 0x02, 2038 + RTW89_BB_PS_LINK_BUF_MAX, 2039 + }; 2040 + 2041 + struct rtw89_bb_link_info_rx_gain { 2042 + u8 gain_ofst[RTW89_BB_PS_LINK_RX_GAIN_TAB_MAX]; 2043 + __le16 rpl_bias_comp[RTW89_BB_PS_LINK_RX_GAIN_TAB_MAX]; 2044 + u8 tb_rssi_m_bias_comp[RTW89_BB_PS_LINK_RX_GAIN_TAB_MAX] 2045 + [BB_RX_GAIN_TB_RSSI_COMP_NUM]; 2046 + u8 cck_gain_ofst[RTW89_BB_PS_LINK_RX_GAIN_TAB_MAX]; 2047 + u8 cck_rpl_bias_comp[RTW89_BB_PS_LINK_RX_GAIN_TAB_MAX] 2048 + [BB_RX_GAIN_CCK_RPL_BIAS_COMP_NUM]; 2049 + u8 gain_err_lna[RTW89_BB_PS_LINK_RX_GAIN_TAB_MAX][LNA_GAIN_NUM]; 2050 + __le16 gain_err_tia[RTW89_BB_PS_LINK_RX_GAIN_TAB_MAX][TIA_GAIN_NUM]; 2051 + u8 op1db_lna[RTW89_BB_PS_LINK_RX_GAIN_TAB_MAX][LNA_GAIN_NUM]; 2052 + u8 op1db_tia[RTW89_BB_PS_LINK_RX_GAIN_TAB_MAX][TIA_LNA_OP1DB_NUM]; 2053 + struct { 2054 + u8 _20M[RTW89_BW20_SC_20M]; 2055 + u8 _40M[RTW89_BW20_SC_40M]; 2056 + u8 _80M[RTW89_BW20_SC_80M]; 2057 + u8 _160M[RTW89_BW20_SC_160M]; 2058 + } rpl_bias_comp_bw[RTW89_BB_PS_LINK_RX_GAIN_TAB_MAX]; 2059 + u8 wb_gs[RTW89_BB_PS_LINK_RX_GAIN_TAB_MAX][BB_GT2_GS_IDX_NUM]; 2060 + u8 bypass_lna[RTW89_BB_PS_LINK_RX_GAIN_TAB_MAX][LNA_GAIN_NUM]; 2061 + u8 wb_lna_tia[RTW89_BB_PS_LINK_RX_GAIN_TAB_MAX][BB_GT2_WB_GIDX_ELNA_NUM]; 2062 + u8 wb_g_elna[RTW89_BB_PS_LINK_RX_GAIN_TAB_MAX][BB_GT2_G_ELNA_NUM]; 2063 + } __packed; 2064 + 2065 + struct rtw89_h2c_lps_ml_cmn_info_v1 { 2066 + u8 fmt_id; 2067 + u8 rfe_type; 2068 + u8 rssi_main; 2069 + u8 rsvd0; 2070 + __le32 mlo_dbcc_mode; 2071 + u8 link_id[RTW89_BB_PS_LINK_BUF_MAX]; 2072 + u8 central_ch[RTW89_BB_PS_LINK_BUF_MAX]; 2073 + u8 pri_ch[RTW89_BB_PS_LINK_BUF_MAX]; 2074 + u8 bw[RTW89_BB_PS_LINK_BUF_MAX]; 2075 + u8 band[RTW89_BB_PS_LINK_BUF_MAX]; 2076 + u8 dup_bcn_ofst[RTW89_BB_PS_LINK_BUF_MAX]; 2077 + struct rtw89_bb_link_info_rx_gain rx_gain[RTW89_BB_PS_LINK_BUF_MAX]; 2078 + } __packed; 2079 + 2020 2080 struct rtw89_h2c_trig_cpu_except { 2021 2081 __le32 w0; 2022 2082 } __packed; ··· 3889 3829 #define RTW89_C2H_RA_RPT_W3_MD_SEL_B2 BIT(15) 3890 3830 #define RTW89_C2H_RA_RPT_W3_BW_B2 BIT(16) 3891 3831 3832 + struct rtw89_c2h_lps_rpt { 3833 + struct rtw89_c2h_hdr hdr; 3834 + u8 type; 3835 + u8 cnt_bbcr; 3836 + u8 cnt_bbmcucr; 3837 + u8 cnt_rfcr; 3838 + u8 data[]; 3839 + /* 3840 + * The layout of data: 3841 + * u8 info[][4], size = total_len - size of below fields 3842 + * __le16 bbcr_addr[], size = cnt_bbcr 3843 + * __le32 bbcr_data[], size = cnt_bbcr 3844 + * __le16 bbmcucr_addr[], size = cnt_bbmcucr 3845 + * __le32 bbmcucr_data[], size = cnt_bbmcucr 3846 + * __le16 rfcr_addr[], size = cnt_rfcr 3847 + * __le32 rfcr_data_a[], size = cnt_rfcr 3848 + * __le32 rfcr_data_b[], size = cnt_rfcr 3849 + */ 3850 + } __packed; 3851 + 3892 3852 struct rtw89_c2h_fw_scan_rpt { 3893 3853 struct rtw89_c2h_hdr hdr; 3894 3854 u8 phy_idx; ··· 4262 4182 RTW89_FW_ELEMENT_ID_TXPWR_DA_LMT_RU_6GHZ = 26, 4263 4183 RTW89_FW_ELEMENT_ID_AFE_PWR_SEQ = 27, 4264 4184 RTW89_FW_ELEMENT_ID_DIAG_MAC = 28, 4185 + RTW89_FW_ELEMENT_ID_TX_COMP = 29, 4265 4186 4266 4187 RTW89_FW_ELEMENT_ID_NUM, 4267 4188 }; ··· 4718 4637 H2C_FUNC_RFK_RXDCK_OFFLOAD = 0x6, 4719 4638 H2C_FUNC_RFK_PRE_NOTIFY = 0x8, 4720 4639 H2C_FUNC_RFK_TAS_OFFLOAD = 0x9, 4640 + H2C_FUNC_RFK_TXIQK_OFFOAD = 0xc, 4641 + H2C_FUNC_RFK_CIM3K_OFFOAD = 0xe, 4721 4642 }; 4722 4643 4723 4644 struct rtw89_fw_h2c_rf_get_mccch { ··· 4912 4829 } __packed; 4913 4830 4914 4831 struct rtw89_h2c_rf_dack { 4915 - __le32 len; 4916 - __le32 phy; 4917 - __le32 type; 4832 + u8 len; 4833 + u8 phy; 4834 + u8 type; 4918 4835 } __packed; 4919 4836 4920 4837 struct rtw89_h2c_rf_rxdck_v0 { ··· 4935 4852 struct rtw89_h2c_rf_rxdck { 4936 4853 struct rtw89_h2c_rf_rxdck_v0 v0; 4937 4854 u8 is_chl_k; 4855 + } __packed; 4856 + 4857 + struct rtw89_h2c_rf_txiqk { 4858 + u8 len; 4859 + u8 phy; 4860 + u8 txiqk_enable; 4861 + u8 is_wb_txiqk; 4862 + u8 kpath; 4863 + u8 cur_band; 4864 + u8 cur_bw; 4865 + u8 cur_ch; 4866 + u8 txiqk_dbg_en; 4867 + } __packed; 4868 + 4869 + struct rtw89_h2c_rf_cim3k { 4870 + u8 len; 4871 + u8 phy; 4872 + u8 su_cim3k_enable[2]; 4873 + u8 ru_cim3k_enable[2]; 4874 + u8 kpath; 4875 + u8 cur_band; 4876 + u8 cur_bw; 4877 + u8 cur_ch; 4878 + u8 cim3k_dbg_en; 4938 4879 } __packed; 4939 4880 4940 4881 enum rtw89_rf_log_type { ··· 5005 4898 u8 rsvd; 5006 4899 __le32 reload_cnt; 5007 4900 __le32 iqk_fail_cnt; 4901 + __le32 rf_0x18[2]; 5008 4902 __le32 lok_idac[2]; 5009 4903 __le32 lok_vbuf[2]; 5010 - __le32 rftxgain[2][4]; 5011 - __le32 rfrxgain[2][4]; 5012 - __le32 tx_xym[2][4]; 5013 - __le32 rx_xym[2][4]; 4904 + __le32 rftxgain[2][6]; 4905 + __le32 rfrxgain[2][6]; 4906 + __le32 tx_xym[2][6]; 4907 + __le32 rx_xym[2][6]; 4908 + __le32 rx_wb_xym[2][32]; 4909 + bool is_radar; 4910 + u8 rsvd1[3]; 5014 4911 } __packed; 5015 4912 5016 4913 struct rtw89_c2h_rf_dpk_rpt_log { ··· 5057 4946 u8 dack_fail; 5058 4947 u8 wbdck_d[2]; 5059 4948 u8 rck_d; 4949 + u8 adgaink_ex_d; 5060 4950 } __packed; 5061 4951 5062 4952 struct rtw89_c2h_rf_rxdck_rpt_log { ··· 5084 4972 u8 is_txgapk_ok; 5085 4973 u8 chk_id; 5086 4974 u8 ver; 5087 - u8 rsv1; 4975 + u8 d_bnd_ok; 4976 + __le32 stage[2]; 4977 + __le16 failcode[2]; 4978 + u8 rsvd[4]; 4979 + } __packed; 4980 + 4981 + struct rtw89_c2h_rf_txiqk_rpt_log { 4982 + u8 fw_txiqk_ver; 4983 + u8 iqk_band[2]; 4984 + u8 iqk_ch[2]; 4985 + u8 iqk_bw[2]; 4986 + bool tx_iqk_fail[2]; 4987 + bool is_iqk_init; 4988 + bool txiqk_en; 4989 + bool lok_en; 4990 + bool lok_fail[2]; 4991 + u8 rsvd[2]; 4992 + __le32 iqk_times; 4993 + bool txiqk_nctldone[2]; 4994 + u8 rsvd2[2]; 4995 + __le32 txgain[2][6]; 4996 + __le32 tx_iqc[2][6]; 4997 + __le32 tx_xym[2][6][14]; 4998 + __le32 kidx[2]; 4999 + } __packed; 5000 + 5001 + struct rtw89_c2h_rf_cim3k_rpt_log { 5002 + u8 cim3k_band[2]; 5003 + u8 cim3k_ch[2]; 5004 + u8 cim3k_bw[2]; 5005 + u8 su_path_ok[2]; 5006 + u8 ru_path_ok[2]; 5007 + u8 txagc_cim3k[2]; 5008 + u8 ther_cim3k[2]; 5009 + u8 cim3k_gs[2]; 5010 + __le16 cim3k_pwsf[2]; 5011 + bool cim3k_nctldone[2]; 5012 + u8 rsvd[2]; 5013 + __le32 cim3k_rxiqc[2]; 5014 + __le32 cim3k_su_coef[2][3]; 5015 + __le16 dc_i[2]; 5016 + __le16 dc_q[2]; 5017 + u8 corr_val[2]; 5018 + u8 corr_idx[2]; 5019 + u8 rxbb_ov[2]; 5020 + u8 cim3k_txiqc[2]; 5021 + u8 kidx[2]; 5022 + u8 fw_cim3k_ver; 5023 + bool su_cim3k_en[2]; 5024 + bool ru_cim3k_en[2]; 5025 + u8 rsvd1; 5088 5026 } __packed; 5089 5027 5090 5028 struct rtw89_c2h_rfk_report { ··· 5249 5087 void rtw89_fw_c2h_irqsafe(struct rtw89_dev *rtwdev, struct sk_buff *c2h); 5250 5088 void rtw89_fw_c2h_work(struct wiphy *wiphy, struct wiphy_work *work); 5251 5089 void rtw89_fw_c2h_purge_obsoleted_scan_events(struct rtw89_dev *rtwdev); 5090 + void rtw89_fw_c2h_dummy_handler(struct rtw89_dev *rtwdev, struct sk_buff *c2h, u32 len); 5252 5091 int rtw89_fw_h2c_role_maintain(struct rtw89_dev *rtwdev, 5253 5092 struct rtw89_vif_link *rtwvif_link, 5254 5093 struct rtw89_sta_link *rtwsta_link, ··· 5317 5154 int rtw89_fw_h2c_rf_rxdck(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx, 5318 5155 const struct rtw89_chan *chan, bool is_chl_k); 5319 5156 int rtw89_fw_h2c_rf_tas_trigger(struct rtw89_dev *rtwdev, bool enable); 5157 + int rtw89_fw_h2c_rf_txiqk(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx, 5158 + const struct rtw89_chan *chan); 5159 + int rtw89_fw_h2c_rf_cim3k(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx, 5160 + const struct rtw89_chan *chan); 5320 5161 int rtw89_fw_h2c_raw_with_hdr(struct rtw89_dev *rtwdev, 5321 5162 u8 h2c_class, u8 h2c_func, u8 *buf, u16 len, 5322 5163 bool rack, bool dack); ··· 5351 5184 int rtw89_fw_h2c_lps_ch_info(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif); 5352 5185 int rtw89_fw_h2c_lps_ml_cmn_info(struct rtw89_dev *rtwdev, 5353 5186 struct rtw89_vif *rtwvif); 5187 + void rtw89_bb_lps_cmn_info_rx_gain_fill(struct rtw89_dev *rtwdev, 5188 + struct rtw89_bb_link_info_rx_gain *h2c_gain, 5189 + const struct rtw89_chan *chan, u8 phy_idx); 5190 + int rtw89_fw_h2c_lps_ml_cmn_info_v1(struct rtw89_dev *rtwdev, 5191 + struct rtw89_vif *rtwvif); 5354 5192 int rtw89_fw_h2c_fwips(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link, 5355 5193 bool enable); 5356 5194 struct sk_buff *rtw89_fw_h2c_alloc_skb_with_hdr(struct rtw89_dev *rtwdev, u32 len);
+17 -6
drivers/net/wireless/realtek/rtw89/mac.c
··· 1554 1554 set_bit(RTW89_FLAG_CMAC0_FUNC, rtwdev->flags); 1555 1555 1556 1556 rtw89_mac_update_scoreboard(rtwdev, MAC_AX_NOTIFY_TP_MAJOR); 1557 + rtw89_mac_clr_aon_intr(rtwdev); 1557 1558 } else { 1558 1559 clear_bit(RTW89_FLAG_POWERON, rtwdev->flags); 1559 1560 clear_bit(RTW89_FLAG_DMAC_FUNC, rtwdev->flags); ··· 4374 4373 R_AX_PORT_HGQ_WINDOW_CFG + 3}, 4375 4374 }; 4376 4375 4376 + static const struct rtw89_mac_mu_gid_addr rtw89_mac_mu_gid_addr_ax = { 4377 + .position_en = {R_AX_GID_POSITION_EN0, R_AX_GID_POSITION_EN1}, 4378 + .position = {R_AX_GID_POSITION0, R_AX_GID_POSITION1, 4379 + R_AX_GID_POSITION2, R_AX_GID_POSITION3}, 4380 + }; 4381 + 4377 4382 static void rtw89_mac_check_packet_ctrl(struct rtw89_dev *rtwdev, 4378 4383 struct rtw89_vif_link *rtwvif_link, u8 type) 4379 4384 { ··· 6776 6769 void rtw89_mac_bf_set_gid_table(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif, 6777 6770 struct ieee80211_bss_conf *conf) 6778 6771 { 6772 + const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def; 6773 + const struct rtw89_mac_mu_gid_addr *addr = mac->mu_gid; 6779 6774 struct rtw89_vif *rtwvif = vif_to_rtwvif(vif); 6780 6775 struct rtw89_vif_link *rtwvif_link; 6781 6776 u8 mac_idx; ··· 6797 6788 6798 6789 p = (__le32 *)conf->mu_group.membership; 6799 6790 rtw89_write32(rtwdev, 6800 - rtw89_mac_reg_by_idx(rtwdev, R_AX_GID_POSITION_EN0, mac_idx), 6791 + rtw89_mac_reg_by_idx(rtwdev, addr->position_en[0], mac_idx), 6801 6792 le32_to_cpu(p[0])); 6802 6793 rtw89_write32(rtwdev, 6803 - rtw89_mac_reg_by_idx(rtwdev, R_AX_GID_POSITION_EN1, mac_idx), 6794 + rtw89_mac_reg_by_idx(rtwdev, addr->position_en[1], mac_idx), 6804 6795 le32_to_cpu(p[1])); 6805 6796 6806 6797 p = (__le32 *)conf->mu_group.position; 6807 - rtw89_write32(rtwdev, rtw89_mac_reg_by_idx(rtwdev, R_AX_GID_POSITION0, mac_idx), 6798 + rtw89_write32(rtwdev, rtw89_mac_reg_by_idx(rtwdev, addr->position[0], mac_idx), 6808 6799 le32_to_cpu(p[0])); 6809 - rtw89_write32(rtwdev, rtw89_mac_reg_by_idx(rtwdev, R_AX_GID_POSITION1, mac_idx), 6800 + rtw89_write32(rtwdev, rtw89_mac_reg_by_idx(rtwdev, addr->position[1], mac_idx), 6810 6801 le32_to_cpu(p[1])); 6811 - rtw89_write32(rtwdev, rtw89_mac_reg_by_idx(rtwdev, R_AX_GID_POSITION2, mac_idx), 6802 + rtw89_write32(rtwdev, rtw89_mac_reg_by_idx(rtwdev, addr->position[2], mac_idx), 6812 6803 le32_to_cpu(p[2])); 6813 - rtw89_write32(rtwdev, rtw89_mac_reg_by_idx(rtwdev, R_AX_GID_POSITION3, mac_idx), 6804 + rtw89_write32(rtwdev, rtw89_mac_reg_by_idx(rtwdev, addr->position[3], mac_idx), 6814 6805 le32_to_cpu(p[3])); 6815 6806 } 6816 6807 ··· 7290 7281 .port_base = &rtw89_port_base_ax, 7291 7282 .agg_len_ht = R_AX_AGG_LEN_HT_0, 7292 7283 .ps_status = R_AX_PPWRBIT_SETTING, 7284 + .mu_gid = &rtw89_mac_mu_gid_addr_ax, 7293 7285 7294 7286 .muedca_ctrl = { 7295 7287 .addr = R_AX_MUEDCA_EN, ··· 7313 7303 .sys_init = sys_init_ax, 7314 7304 .trx_init = trx_init_ax, 7315 7305 .preload_init = preload_init_set_ax, 7306 + .clr_aon_intr = NULL, 7316 7307 .err_imr_ctrl = err_imr_ctrl_ax, 7317 7308 .mac_func_en = NULL, 7318 7309 .hci_func_en = rtw89_mac_hci_func_en_ax,
+23
drivers/net/wireless/realtek/rtw89/mac.h
··· 1015 1015 1016 1016 extern const struct rtw89_mac_size_set rtw89_mac_size; 1017 1017 1018 + struct rtw89_mac_mu_gid_addr { 1019 + u32 position_en[2]; 1020 + u32 position[4]; 1021 + }; 1022 + 1018 1023 struct rtw89_mac_gen_def { 1019 1024 u32 band1_offset; 1020 1025 u32 filter_model_addr; ··· 1030 1025 const struct rtw89_port_reg *port_base; 1031 1026 u32 agg_len_ht; 1032 1027 u32 ps_status; 1028 + const struct rtw89_mac_mu_gid_addr *mu_gid; 1033 1029 1034 1030 struct rtw89_reg_def muedca_ctrl; 1035 1031 struct rtw89_reg_def bfee_ctrl; ··· 1045 1039 int (*trx_init)(struct rtw89_dev *rtwdev); 1046 1040 int (*preload_init)(struct rtw89_dev *rtwdev, u8 mac_idx, 1047 1041 enum rtw89_qta_mode mode); 1042 + void (*clr_aon_intr)(struct rtw89_dev *rtwdev); 1048 1043 void (*err_imr_ctrl)(struct rtw89_dev *rtwdev, bool en); 1049 1044 int (*mac_func_en)(struct rtw89_dev *rtwdev); 1050 1045 void (*hci_func_en)(struct rtw89_dev *rtwdev); ··· 1143 1136 addr = rtw89_mac_reg_by_idx(rtwdev, addr, band); 1144 1137 1145 1138 rtw89_write16(rtwdev, addr, data); 1139 + } 1140 + 1141 + static inline void 1142 + rtw89_write32_idx(struct rtw89_dev *rtwdev, u32 addr, u32 mask, u32 data, u8 band) 1143 + { 1144 + addr = rtw89_mac_reg_by_idx(rtwdev, addr, band); 1145 + 1146 + rtw89_write32_mask(rtwdev, addr, mask, data); 1146 1147 } 1147 1148 1148 1149 static inline ··· 1264 1249 const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def; 1265 1250 1266 1251 return mac->check_mac_en(rtwdev, band, sel); 1252 + } 1253 + 1254 + static inline void rtw89_mac_clr_aon_intr(struct rtw89_dev *rtwdev) 1255 + { 1256 + const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def; 1257 + 1258 + if (mac->clr_aon_intr) 1259 + mac->clr_aon_intr(rtwdev); 1267 1260 } 1268 1261 1269 1262 int rtw89_mac_write_lte(struct rtw89_dev *rtwdev, const u32 offset, u32 val);
+2 -2
drivers/net/wireless/realtek/rtw89/mac80211.c
··· 1438 1438 1439 1439 BUILD_BUG_ON(RTW89_MLD_NON_STA_LINK_NUM != 1); 1440 1440 1441 - rtwvif_link = rtw89_vif_get_link_inst(rtwvif, 0); 1441 + rtwvif_link = rtw89_get_designated_link(rtwvif); 1442 1442 if (unlikely(!rtwvif_link)) { 1443 - rtw89_err(rtwdev, "chsw bcn: find no link on HW-0\n"); 1443 + rtw89_err(rtwdev, "chsw bcn: find no designated link\n"); 1444 1444 return; 1445 1445 } 1446 1446
+22 -1
drivers/net/wireless/realtek/rtw89/mac_be.c
··· 62 62 R_BE_PORT_HGQ_WINDOW_CFG + 3}, 63 63 }; 64 64 65 + static const struct rtw89_mac_mu_gid_addr rtw89_mac_mu_gid_addr_be = { 66 + .position_en = {R_BE_GID_POSITION_EN0, R_BE_GID_POSITION_EN1}, 67 + .position = {R_BE_GID_POSITION0, R_BE_GID_POSITION1, 68 + R_BE_GID_POSITION2, R_BE_GID_POSITION3}, 69 + }; 70 + 65 71 static int rtw89_mac_check_mac_en_be(struct rtw89_dev *rtwdev, u8 mac_idx, 66 72 enum rtw89_mac_hwmod_sel sel) 67 73 { ··· 1334 1328 reg = rtw89_mac_reg_by_idx(rtwdev, R_BE_SPECIAL_TX_SETTING, mac_idx); 1335 1329 rtw89_write32_clr(rtwdev, reg, B_BE_BMC_NAV_PROTECT); 1336 1330 1331 + reg = rtw89_mac_reg_by_idx(rtwdev, R_BE_TRXPTCL_RESP_0, mac_idx); 1332 + rtw89_write32_set(rtwdev, reg, B_BE_WMAC_MBA_DUR_FORCE); 1333 + 1337 1334 return 0; 1338 1335 } 1339 1336 ··· 1361 1352 static int tmac_init_be(struct rtw89_dev *rtwdev, u8 mac_idx) 1362 1353 { 1363 1354 const struct rtw89_chip_info *chip = rtwdev->chip; 1355 + struct rtw89_hal *hal = &rtwdev->hal; 1364 1356 u32 reg; 1365 1357 1366 1358 reg = rtw89_mac_reg_by_idx(rtwdev, R_BE_TB_PPDU_CTRL, mac_idx); ··· 1373 1363 rtw89_write32_mask(rtwdev, reg, B_BE_EHT_HE_PPDU_2XLTF_ZLD_USTIMER_MASK, 0xe); 1374 1364 } 1375 1365 1376 - if (chip->chip_id == RTL8922D) { 1366 + if (chip->chip_id == RTL8922D && hal->cid != RTL8922D_CID7090) { 1377 1367 reg = rtw89_mac_reg_by_idx(rtwdev, R_BE_COMMON_PHYINTF_CTRL_0, mac_idx); 1378 1368 rtw89_write32_clr(rtwdev, reg, CLEAR_DTOP_DIS); 1379 1369 } ··· 1998 1988 rtw89_write32(rtwdev, reg, val32); 1999 1989 2000 1990 return 0; 1991 + } 1992 + 1993 + static void clr_aon_intr_be(struct rtw89_dev *rtwdev) 1994 + { 1995 + if (rtwdev->hci.type != RTW89_HCI_TYPE_PCIE) 1996 + return; 1997 + 1998 + rtw89_write32_clr(rtwdev, R_BE_FWS0IMR, B_BE_FS_GPIOA_INT_EN); 1999 + rtw89_write32_set(rtwdev, R_BE_FWS0ISR, B_BE_FS_GPIOA_INT); 2001 2000 } 2002 2001 2003 2002 static int dbcc_bb_ctrl_be(struct rtw89_dev *rtwdev, bool bb1_en) ··· 3176 3157 .port_base = &rtw89_port_base_be, 3177 3158 .agg_len_ht = R_BE_AGG_LEN_HT_0, 3178 3159 .ps_status = R_BE_WMTX_POWER_BE_BIT_CTL, 3160 + .mu_gid = &rtw89_mac_mu_gid_addr_be, 3179 3161 3180 3162 .muedca_ctrl = { 3181 3163 .addr = R_BE_MUEDCA_EN, ··· 3199 3179 .sys_init = sys_init_be, 3200 3180 .trx_init = trx_init_be, 3201 3181 .preload_init = preload_init_be, 3182 + .clr_aon_intr = clr_aon_intr_be, 3202 3183 .err_imr_ctrl = err_imr_ctrl_be, 3203 3184 .mac_func_en = mac_func_en_be, 3204 3185 .hci_func_en = rtw89_mac_hci_func_en_be,
+13 -4
drivers/net/wireless/realtek/rtw89/pci.c
··· 604 604 605 605 info->parse_rpp(rtwdev, rpp, &rpp_info); 606 606 607 - if (unlikely(rpp_info.txch == RTW89_TXCH_CH12)) { 608 - rtw89_warn(rtwdev, "should no fwcmd release report\n"); 607 + if (unlikely(rpp_info.txch >= RTW89_TXCH_NUM || 608 + info->tx_dma_ch_mask & BIT(rpp_info.txch))) { 609 + rtw89_warn(rtwdev, "should no release report on txch %d\n", 610 + rpp_info.txch); 609 611 return; 610 612 } 611 613 ··· 969 967 970 968 if (unlikely(isrs.halt_c2h_isrs & isr_def->isr_wdt_timeout)) 971 969 rtw89_ser_notify(rtwdev, MAC_AX_ERR_L2_ERR_WDT_TIMEOUT_INT); 970 + 971 + if (unlikely(isrs.halt_c2h_isrs & isr_def->isr_sps_ocp)) 972 + rtw89_warn(rtwdev, "SPS OCP alarm 0x%x\n", isrs.halt_c2h_isrs); 972 973 973 974 if (unlikely(rtwpci->under_recovery)) 974 975 goto enable_intr; ··· 4008 4003 struct rtw89_pci *rtwpci = (struct rtw89_pci *)rtwdev->priv; 4009 4004 4010 4005 rtwpci->ind_intrs = B_BE_HS0_IND_INT_EN0; 4011 - rtwpci->halt_c2h_intrs = B_BE_HALT_C2H_INT_EN | B_BE_WDT_TIMEOUT_INT_EN; 4006 + rtwpci->halt_c2h_intrs = B_BE_HALT_C2H_INT_EN | B_BE_WDT_TIMEOUT_INT_EN | 4007 + B_BE_SPSANA_OCP_INT_EN | B_BE_SPS_OCP_INT_EN; 4012 4008 rtwpci->intrs[0] = 0; 4013 4009 rtwpci->intrs[1] = 0; 4014 4010 } ··· 4019 4013 struct rtw89_pci *rtwpci = (struct rtw89_pci *)rtwdev->priv; 4020 4014 4021 4015 rtwpci->ind_intrs = B_BE_HS0_IND_INT_EN0; 4022 - rtwpci->halt_c2h_intrs = B_BE_HALT_C2H_INT_EN | B_BE_WDT_TIMEOUT_INT_EN; 4016 + rtwpci->halt_c2h_intrs = B_BE_HALT_C2H_INT_EN | B_BE_WDT_TIMEOUT_INT_EN | 4017 + B_BE_SPSANA_OCP_INT_EN | B_BE_SPS_OCP_INT_EN; 4023 4018 rtwpci->intrs[0] = 0; 4024 4019 rtwpci->intrs[1] = B_BE_PCIE_RDU_CH1_IMR | 4025 4020 B_BE_PCIE_RDU_CH0_IMR | ··· 4610 4603 rtw89_write32_clr(rtwdev, R_AX_PCIE_PS_CTRL_V1, 4611 4604 B_AX_SEL_REQ_ENTR_L1); 4612 4605 } 4606 + rtw89_pci_hci_ldo(rtwdev); 4613 4607 rtw89_pci_l2_hci_ldo(rtwdev); 4614 4608 4615 4609 rtw89_pci_basic_cfg(rtwdev, true); ··· 4662 4654 .isr_rdu = B_AX_RDU_INT, 4663 4655 .isr_halt_c2h = B_AX_HALT_C2H_INT_EN, 4664 4656 .isr_wdt_timeout = B_AX_WDT_TIMEOUT_INT_EN, 4657 + .isr_sps_ocp = 0, 4665 4658 .isr_clear_rpq = {R_AX_PCIE_HISR00, B_AX_RPQDMA_INT | B_AX_RPQBD_FULL_INT}, 4666 4659 .isr_clear_rxq = {R_AX_PCIE_HISR00, B_AX_RXP1DMA_INT | B_AX_RXDMA_INT | 4667 4660 B_AX_RDU_INT},
+1
drivers/net/wireless/realtek/rtw89/pci.h
··· 1331 1331 u32 isr_rdu; 1332 1332 u32 isr_halt_c2h; 1333 1333 u32 isr_wdt_timeout; 1334 + u32 isr_sps_ocp; 1334 1335 struct rtw89_reg2_def isr_clear_rpq; 1335 1336 struct rtw89_reg2_def isr_clear_rxq; 1336 1337 };
+2
drivers/net/wireless/realtek/rtw89/pci_be.c
··· 763 763 .isr_rdu = B_BE_RDU_CH1_INT_V1 | B_BE_RDU_CH0_INT_V1, 764 764 .isr_halt_c2h = B_BE_HALT_C2H_INT, 765 765 .isr_wdt_timeout = B_BE_WDT_TIMEOUT_INT, 766 + .isr_sps_ocp = 0, 766 767 .isr_clear_rpq = {R_BE_PCIE_DMA_ISR, B_BE_PCIE_RX_RPQ0_ISR_V1}, 767 768 .isr_clear_rxq = {R_BE_PCIE_DMA_ISR, B_BE_PCIE_RX_RX0P2_ISR_V1}, 768 769 }; ··· 773 772 .isr_rdu = B_BE_PCIE_RDU_CH1_INT | B_BE_PCIE_RDU_CH0_INT, 774 773 .isr_halt_c2h = B_BE_HALT_C2H_INT, 775 774 .isr_wdt_timeout = B_BE_WDT_TIMEOUT_INT, 775 + .isr_sps_ocp = B_BE_SPS_OCP_INT | B_BE_SPSANA_OCP_INT, 776 776 .isr_clear_rpq = {R_BE_PCIE_DMA_ISR, B_BE_PCIE_RX_RPQ0_ISR_V1}, 777 777 .isr_clear_rxq = {R_BE_PCIE_DMA_ISR, B_BE_PCIE_RX_RX0P2_ISR_V1}, 778 778 };
+346 -35
drivers/net/wireless/realtek/rtw89/phy.c
··· 1036 1036 } 1037 1037 EXPORT_SYMBOL(rtw89_phy_read_rf_v2); 1038 1038 1039 + static u32 rtw89_phy_read_full_rf_v3_a(struct rtw89_dev *rtwdev, 1040 + enum rtw89_rf_path rf_path, u32 addr) 1041 + { 1042 + bool done; 1043 + u32 busy; 1044 + int ret; 1045 + u32 val; 1046 + 1047 + ret = read_poll_timeout_atomic(rtw89_phy_read32_mask, busy, !busy, 1048 + 1, 30, false, 1049 + rtwdev, R_SW_SI_DATA_BE4, 1050 + B_SW_SI_W_BUSY_BE4 | B_SW_SI_R_BUSY_BE4); 1051 + if (ret) { 1052 + rtw89_warn(rtwdev, "poll HWSI is busy\n"); 1053 + return INV_RF_DATA; 1054 + } 1055 + 1056 + val = u32_encode_bits(rf_path, GENMASK(10, 8)) | 1057 + u32_encode_bits(addr, GENMASK(7, 0)); 1058 + 1059 + rtw89_phy_write32_mask(rtwdev, R_SW_SI_READ_ADDR_BE4, B_SW_SI_READ_ADDR_BE4, val); 1060 + 1061 + ret = read_poll_timeout_atomic(rtw89_phy_read32_mask, done, done, 1062 + 1, 30, false, 1063 + rtwdev, R_SW_SI_DATA_BE4, B_SW_SI_READ_DATA_DONE_BE4); 1064 + if (ret) { 1065 + rtw89_warn(rtwdev, "read HWSI is busy\n"); 1066 + return INV_RF_DATA; 1067 + } 1068 + 1069 + val = rtw89_phy_read32_mask(rtwdev, R_SW_SI_DATA_BE4, B_SW_SI_READ_DATA_BE4); 1070 + 1071 + return val; 1072 + } 1073 + 1074 + static u32 rtw89_phy_read_rf_v3_a(struct rtw89_dev *rtwdev, 1075 + enum rtw89_rf_path rf_path, u32 addr, u32 mask) 1076 + { 1077 + u32 val; 1078 + 1079 + val = rtw89_phy_read_full_rf_v3_a(rtwdev, rf_path, addr); 1080 + 1081 + return (val & mask) >> __ffs(mask); 1082 + } 1083 + 1084 + u32 rtw89_phy_read_rf_v3(struct rtw89_dev *rtwdev, enum rtw89_rf_path rf_path, 1085 + u32 addr, u32 mask) 1086 + { 1087 + bool ad_sel = u32_get_bits(addr, RTW89_RF_ADDR_ADSEL_MASK); 1088 + 1089 + if (rf_path >= rtwdev->chip->rf_path_num) { 1090 + rtw89_err(rtwdev, "unsupported rf path (%d)\n", rf_path); 1091 + return INV_RF_DATA; 1092 + } 1093 + 1094 + if (ad_sel) 1095 + return rtw89_phy_read_rf(rtwdev, rf_path, addr, mask); 1096 + else 1097 + return rtw89_phy_read_rf_v3_a(rtwdev, rf_path, addr, mask); 1098 + } 1099 + EXPORT_SYMBOL(rtw89_phy_read_rf_v3); 1100 + 1039 1101 bool rtw89_phy_write_rf(struct rtw89_dev *rtwdev, enum rtw89_rf_path rf_path, 1040 1102 u32 addr, u32 mask, u32 data) 1041 1103 { ··· 1236 1174 return rtw89_phy_write_rf_a_v2(rtwdev, rf_path, addr, mask, data); 1237 1175 } 1238 1176 EXPORT_SYMBOL(rtw89_phy_write_rf_v2); 1177 + 1178 + static 1179 + bool rtw89_phy_write_full_rf_v3_a(struct rtw89_dev *rtwdev, enum rtw89_rf_path rf_path, 1180 + u32 addr, u32 data) 1181 + { 1182 + u32 busy; 1183 + u32 val; 1184 + int ret; 1185 + 1186 + ret = read_poll_timeout_atomic(rtw89_phy_read32_mask, busy, !busy, 1187 + 1, 30, false, 1188 + rtwdev, R_SW_SI_DATA_BE4, 1189 + B_SW_SI_W_BUSY_BE4 | B_SW_SI_R_BUSY_BE4); 1190 + if (ret) { 1191 + rtw89_warn(rtwdev, "[%s] HWSI is busy\n", __func__); 1192 + return false; 1193 + } 1194 + 1195 + val = u32_encode_bits(rf_path, B_SW_SI_DATA_PATH_BE4) | 1196 + u32_encode_bits(addr, B_SW_SI_DATA_ADR_BE4) | 1197 + u32_encode_bits(data, B_SW_SI_DATA_DAT_BE4); 1198 + 1199 + rtw89_phy_write32(rtwdev, R_SW_SI_WDATA_BE4, val); 1200 + 1201 + return true; 1202 + } 1203 + 1204 + static 1205 + bool rtw89_phy_write_rf_a_v3(struct rtw89_dev *rtwdev, enum rtw89_rf_path rf_path, 1206 + u32 addr, u32 mask, u32 data) 1207 + { 1208 + u32 val; 1209 + 1210 + if (mask == RFREG_MASK) { 1211 + val = data; 1212 + } else { 1213 + val = rtw89_phy_read_full_rf_v3_a(rtwdev, rf_path, addr); 1214 + val &= ~mask; 1215 + val |= (data << __ffs(mask)) & mask; 1216 + } 1217 + 1218 + return rtw89_phy_write_full_rf_v3_a(rtwdev, rf_path, addr, val); 1219 + } 1220 + 1221 + bool rtw89_phy_write_rf_v3(struct rtw89_dev *rtwdev, enum rtw89_rf_path rf_path, 1222 + u32 addr, u32 mask, u32 data) 1223 + { 1224 + bool ad_sel = u32_get_bits(addr, RTW89_RF_ADDR_ADSEL_MASK); 1225 + 1226 + if (rf_path >= rtwdev->chip->rf_path_num) { 1227 + rtw89_err(rtwdev, "unsupported rf path (%d)\n", rf_path); 1228 + return INV_RF_DATA; 1229 + } 1230 + 1231 + if (ad_sel) 1232 + return rtw89_phy_write_rf(rtwdev, rf_path, addr, mask, data); 1233 + else 1234 + return rtw89_phy_write_rf_a_v3(rtwdev, rf_path, addr, mask, data); 1235 + } 1236 + EXPORT_SYMBOL(rtw89_phy_write_rf_v3); 1239 1237 1240 1238 static bool rtw89_chip_rf_v1(struct rtw89_dev *rtwdev) 1241 1239 { ··· 3332 3210 [RTW89_PHY_C2H_FUNC_STS_RPT] = rtw89_phy_c2h_ra_rpt, 3333 3211 [RTW89_PHY_C2H_FUNC_MU_GPTBL_RPT] = NULL, 3334 3212 [RTW89_PHY_C2H_FUNC_TXSTS] = NULL, 3213 + [RTW89_PHY_C2H_FUNC_ACCELERATE_EN] = rtw89_fw_c2h_dummy_handler, 3335 3214 }; 3336 3215 3337 3216 static void 3338 3217 rtw89_phy_c2h_lowrt_rty(struct rtw89_dev *rtwdev, struct sk_buff *c2h, u32 len) 3339 3218 { 3219 + } 3220 + 3221 + static void 3222 + rtw89_phy_c2h_lps_rpt(struct rtw89_dev *rtwdev, struct sk_buff *c2h, u32 len) 3223 + { 3224 + const struct rtw89_c2h_lps_rpt *c2h_rpt = (const void *)c2h->data; 3225 + const __le32 *data_a, *data_b; 3226 + u16 len_info, cr_len, idx; 3227 + const __le16 *addr; 3228 + const u8 *info; 3229 + 3230 + /* elements size of BBCR/BBMCUCR/RFCR are 6/6/10 bytes respectively */ 3231 + cr_len = c2h_rpt->cnt_bbcr * 6 + 3232 + c2h_rpt->cnt_bbmcucr * 6 + 3233 + c2h_rpt->cnt_rfcr * 10; 3234 + len_info = len - (sizeof(*c2h_rpt) + cr_len); 3235 + 3236 + if (len < sizeof(*c2h_rpt) + cr_len || len_info % 4 != 0) { 3237 + rtw89_debug(rtwdev, RTW89_DBG_PS, 3238 + "Invalid LPS RPT len(%d) TYPE(%d) CRCNT: BB(%d) MCU(%d) RF(%d)\n", 3239 + len, c2h_rpt->type, c2h_rpt->cnt_bbcr, 3240 + c2h_rpt->cnt_bbmcucr, c2h_rpt->cnt_rfcr); 3241 + return; 3242 + } 3243 + 3244 + rtw89_debug(rtwdev, RTW89_DBG_PS, 3245 + "LPS RPT TYPE(%d), CRCNT: BB(%d) MCU(%d) RF(%d)\n", 3246 + c2h_rpt->type, c2h_rpt->cnt_bbcr, 3247 + c2h_rpt->cnt_bbmcucr, c2h_rpt->cnt_rfcr); 3248 + 3249 + info = &c2h_rpt->data[0]; 3250 + for (idx = 0; idx < len_info; idx += 4, info += 4) 3251 + rtw89_debug(rtwdev, RTW89_DBG_PS, 3252 + "BB LPS INFO (%02d) - 0x%02x,0x%02x,0x%02x,0x%02x\n", 3253 + idx, info[3], info[2], info[1], info[0]); 3254 + 3255 + addr = (const void *)(info); 3256 + data_a = (const void *)(addr + c2h_rpt->cnt_bbcr); 3257 + for (idx = 0; idx < c2h_rpt->cnt_bbcr; idx++, addr++, data_a++) 3258 + rtw89_debug(rtwdev, RTW89_DBG_PS, 3259 + "LPS BB CR - 0x%04x=0x%08x\n", 3260 + le16_to_cpu(*addr), le32_to_cpu(*data_a)); 3261 + 3262 + addr = (const void *)data_a; 3263 + data_a = (const void *)(addr + c2h_rpt->cnt_bbmcucr); 3264 + for (idx = 0; idx < c2h_rpt->cnt_bbmcucr; idx++, addr++, data_a++) 3265 + rtw89_debug(rtwdev, RTW89_DBG_PS, 3266 + "LPS BBMCU - 0x%04x=0x%08x\n", 3267 + le16_to_cpu(*addr), le32_to_cpu(*data_a)); 3268 + 3269 + addr = (const void *)data_a; 3270 + data_a = (const void *)(addr + c2h_rpt->cnt_rfcr); 3271 + data_b = (const void *)(data_a + c2h_rpt->cnt_rfcr); 3272 + for (idx = 0; idx < c2h_rpt->cnt_rfcr; idx++, addr++, data_a++, data_b++) 3273 + rtw89_debug(rtwdev, RTW89_DBG_PS, 3274 + "LPS RFCR - 0x%04x=0x%05x,0x%05x\n", 3275 + le16_to_cpu(*addr), le32_to_cpu(*data_a), 3276 + le32_to_cpu(*data_b)); 3340 3277 } 3341 3278 3342 3279 static void ··· 3419 3238 [RTW89_PHY_C2H_DM_FUNC_SIGB] = NULL, 3420 3239 [RTW89_PHY_C2H_DM_FUNC_LOWRT_RTY] = rtw89_phy_c2h_lowrt_rty, 3421 3240 [RTW89_PHY_C2H_DM_FUNC_MCC_DIG] = NULL, 3241 + [RTW89_PHY_C2H_DM_FUNC_LPS] = rtw89_phy_c2h_lps_rpt, 3242 + [RTW89_PHY_C2H_DM_FUNC_ENV_MNTR] = rtw89_fw_c2h_dummy_handler, 3422 3243 [RTW89_PHY_C2H_DM_FUNC_FW_SCAN] = rtw89_phy_c2h_fw_scan_rpt, 3423 3244 }; 3424 3245 ··· 3458 3275 { 3459 3276 struct rtw89_c2h_rf_txgapk_rpt_log *txgapk; 3460 3277 struct rtw89_c2h_rf_rxdck_rpt_log *rxdck; 3278 + struct rtw89_c2h_rf_txiqk_rpt_log *txiqk; 3279 + struct rtw89_c2h_rf_cim3k_rpt_log *cim3k; 3461 3280 struct rtw89_c2h_rf_dack_rpt_log *dack; 3462 3281 struct rtw89_c2h_rf_tssi_rpt_log *tssi; 3463 3282 struct rtw89_c2h_rf_dpk_rpt_log *dpk; ··· 3514 3329 i, iqk->iqk_ch[i]); 3515 3330 rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK] iqk->iqk_bw[%d] = %x\n", 3516 3331 i, iqk->iqk_bw[i]); 3332 + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK] iqk->rf_0x18[%d] = %x\n", 3333 + i, le32_to_cpu(iqk->rf_0x18[i])); 3517 3334 rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK] iqk->lok_idac[%d] = %x\n", 3518 3335 i, le32_to_cpu(iqk->lok_idac[i])); 3519 3336 rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK] iqk->lok_vbuf[%d] = %x\n", ··· 3524 3337 i, iqk->iqk_tx_fail[i]); 3525 3338 rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK] iqk->iqk_rx_fail[%d] = %x\n", 3526 3339 i, iqk->iqk_rx_fail[i]); 3527 - for (j = 0; j < 4; j++) 3340 + for (j = 0; j < 6; j++) 3528 3341 rtw89_debug(rtwdev, RTW89_DBG_RFK, 3529 3342 "[IQK] iqk->rftxgain[%d][%d] = %x\n", 3530 3343 i, j, le32_to_cpu(iqk->rftxgain[i][j])); 3531 - for (j = 0; j < 4; j++) 3344 + for (j = 0; j < 6; j++) 3532 3345 rtw89_debug(rtwdev, RTW89_DBG_RFK, 3533 3346 "[IQK] iqk->tx_xym[%d][%d] = %x\n", 3534 3347 i, j, le32_to_cpu(iqk->tx_xym[i][j])); 3535 - for (j = 0; j < 4; j++) 3348 + for (j = 0; j < 6; j++) 3536 3349 rtw89_debug(rtwdev, RTW89_DBG_RFK, 3537 3350 "[IQK] iqk->rfrxgain[%d][%d] = %x\n", 3538 3351 i, j, le32_to_cpu(iqk->rfrxgain[i][j])); 3539 - for (j = 0; j < 4; j++) 3352 + for (j = 0; j < 6; j++) 3540 3353 rtw89_debug(rtwdev, RTW89_DBG_RFK, 3541 3354 "[IQK] iqk->rx_xym[%d][%d] = %x\n", 3542 3355 i, j, le32_to_cpu(iqk->rx_xym[i][j])); 3356 + 3357 + if (!iqk->iqk_xym_en) 3358 + continue; 3359 + 3360 + for (j = 0; j < 32; j++) 3361 + rtw89_debug(rtwdev, RTW89_DBG_RFK, 3362 + "[IQK] iqk->rx_wb_xym[%d][%d] = %x\n", 3363 + i, j, iqk->rx_wb_xym[i][j]); 3543 3364 } 3544 3365 return; 3545 3366 case RTW89_PHY_C2H_RFK_LOG_FUNC_DPK: ··· 3703 3508 le32_to_cpu(txgapk->chk_cnt)); 3704 3509 rtw89_debug(rtwdev, RTW89_DBG_RFK, "[TXGAPK]rpt ver = 0x%x\n", 3705 3510 txgapk->ver); 3706 - rtw89_debug(rtwdev, RTW89_DBG_RFK, "[TXGAPK]rpt rsv1 = %d\n", 3707 - txgapk->rsv1); 3511 + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[TXGAPK]rpt d_bnd_ok = %d\n", 3512 + txgapk->d_bnd_ok); 3513 + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[TXGAPK]rpt stage[0] = 0x%x\n", 3514 + le32_to_cpu(txgapk->stage[0])); 3515 + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[TXGAPK]rpt stage[1] = 0x%x\n", 3516 + le32_to_cpu(txgapk->stage[1])); 3517 + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[TXGAPK]failcode[0] = 0x%x\n", 3518 + le16_to_cpu(txgapk->failcode[0])); 3519 + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[TXGAPK]failcode[1] = 0x%x\n", 3520 + le16_to_cpu(txgapk->failcode[1])); 3708 3521 3709 3522 rtw89_debug(rtwdev, RTW89_DBG_RFK, "[TXGAPK]rpt track_d[0] = %*ph\n", 3710 3523 (int)sizeof(txgapk->track_d[0]), txgapk->track_d[0]); ··· 3728 3525 goto out; 3729 3526 3730 3527 rtw89_phy_c2h_rfk_tas_pwr(rtwdev, content); 3731 - 3528 + return; 3529 + case RTW89_PHY_C2H_RFK_LOG_FUNC_TXIQK: 3530 + if (len != sizeof(*txiqk)) 3531 + goto out; 3532 + return; 3533 + case RTW89_PHY_C2H_RFK_LOG_FUNC_CIM3K: 3534 + if (len != sizeof(*cim3k)) 3535 + goto out; 3732 3536 return; 3733 3537 default: 3734 3538 break; ··· 3872 3662 RTW89_PHY_C2H_RFK_LOG_FUNC_TAS_PWR, "TAS"); 3873 3663 } 3874 3664 3665 + static void 3666 + rtw89_phy_c2h_rfk_log_txiqk(struct rtw89_dev *rtwdev, struct sk_buff *c2h, u32 len) 3667 + { 3668 + rtw89_phy_c2h_rfk_log(rtwdev, c2h, len, 3669 + RTW89_PHY_C2H_RFK_LOG_FUNC_TXIQK, "TXIQK"); 3670 + } 3671 + 3672 + static void 3673 + rtw89_phy_c2h_rfk_log_cim3k(struct rtw89_dev *rtwdev, struct sk_buff *c2h, u32 len) 3674 + { 3675 + rtw89_phy_c2h_rfk_log(rtwdev, c2h, len, 3676 + RTW89_PHY_C2H_RFK_LOG_FUNC_CIM3K, "CIM3K"); 3677 + } 3678 + 3875 3679 static 3876 3680 void (* const rtw89_phy_c2h_rfk_log_handler[])(struct rtw89_dev *rtwdev, 3877 3681 struct sk_buff *c2h, u32 len) = { ··· 3896 3672 [RTW89_PHY_C2H_RFK_LOG_FUNC_TSSI] = rtw89_phy_c2h_rfk_log_tssi, 3897 3673 [RTW89_PHY_C2H_RFK_LOG_FUNC_TXGAPK] = rtw89_phy_c2h_rfk_log_txgapk, 3898 3674 [RTW89_PHY_C2H_RFK_LOG_FUNC_TAS_PWR] = rtw89_phy_c2h_rfk_log_tas_pwr, 3675 + [RTW89_PHY_C2H_RFK_LOG_FUNC_TXIQK] = rtw89_phy_c2h_rfk_log_txiqk, 3676 + [RTW89_PHY_C2H_RFK_LOG_FUNC_CIM3K] = rtw89_phy_c2h_rfk_log_cim3k, 3899 3677 }; 3900 3678 3901 3679 static ··· 3986 3760 case RTW89_PHY_C2H_RFK_LOG_FUNC_RXDCK: 3987 3761 case RTW89_PHY_C2H_RFK_LOG_FUNC_TSSI: 3988 3762 case RTW89_PHY_C2H_RFK_LOG_FUNC_TXGAPK: 3763 + case RTW89_PHY_C2H_RFK_LOG_FUNC_TXIQK: 3989 3764 return true; 3990 3765 default: 3991 3766 return false; ··· 4011 3784 4012 3785 switch (class) { 4013 3786 case RTW89_PHY_C2H_CLASS_RA: 4014 - if (func < RTW89_PHY_C2H_FUNC_RA_MAX) 3787 + if (func < ARRAY_SIZE(rtw89_phy_c2h_ra_handler)) 4015 3788 handler = rtw89_phy_c2h_ra_handler[func]; 4016 3789 break; 4017 3790 case RTW89_PHY_C2H_RFK_LOG: ··· 4164 3937 return rtw89_phy_rfk_report_wait(rtwdev, "RX_DCK", ms); 4165 3938 } 4166 3939 EXPORT_SYMBOL(rtw89_phy_rfk_rxdck_and_wait); 3940 + 3941 + int rtw89_phy_rfk_txiqk_and_wait(struct rtw89_dev *rtwdev, 3942 + enum rtw89_phy_idx phy_idx, 3943 + const struct rtw89_chan *chan, 3944 + unsigned int ms) 3945 + { 3946 + int ret; 3947 + 3948 + rtw89_phy_rfk_report_prep(rtwdev); 3949 + 3950 + ret = rtw89_fw_h2c_rf_txiqk(rtwdev, phy_idx, chan); 3951 + if (ret) 3952 + return ret; 3953 + 3954 + return rtw89_phy_rfk_report_wait(rtwdev, "TX_IQK", ms); 3955 + } 3956 + EXPORT_SYMBOL(rtw89_phy_rfk_txiqk_and_wait); 3957 + 3958 + int rtw89_phy_rfk_cim3k_and_wait(struct rtw89_dev *rtwdev, 3959 + enum rtw89_phy_idx phy_idx, 3960 + const struct rtw89_chan *chan, 3961 + unsigned int ms) 3962 + { 3963 + int ret; 3964 + 3965 + rtw89_phy_rfk_report_prep(rtwdev); 3966 + 3967 + ret = rtw89_fw_h2c_rf_cim3k(rtwdev, phy_idx, chan); 3968 + if (ret) 3969 + return ret; 3970 + 3971 + return rtw89_phy_rfk_report_wait(rtwdev, "CIM3k", ms); 3972 + } 3973 + EXPORT_SYMBOL(rtw89_phy_rfk_cim3k_and_wait); 4167 3974 4168 3975 static u32 phy_tssi_get_cck_group(u8 ch) 4169 3976 { ··· 4646 4385 const struct rtw89_chan *chan, 4647 4386 struct rtw89_h2c_rf_tssi *h2c) 4648 4387 { 4388 + const struct rtw89_chip_info *chip = rtwdev->chip; 4649 4389 struct rtw89_tssi_info *tssi_info = &rtwdev->tssi; 4650 4390 u8 ch = chan->channel; 4651 4391 s8 trim_de; ··· 4670 4408 cck_de = tssi_info->tssi_cck[i][gidx]; 4671 4409 val = u32_get_bits(cck_de + trim_de, 0xff); 4672 4410 4673 - h2c->curr_tssi_cck_de[i] = 0x0; 4674 - h2c->curr_tssi_cck_de_20m[i] = val; 4675 - h2c->curr_tssi_cck_de_40m[i] = val; 4411 + if (chip->chip_id == RTL8922A) { 4412 + h2c->curr_tssi_cck_de[i] = 0x0; 4413 + h2c->curr_tssi_cck_de_20m[i] = val; 4414 + h2c->curr_tssi_cck_de_40m[i] = val; 4415 + } else { 4416 + h2c->curr_tssi_cck_de[i] = val; 4417 + } 4418 + 4676 4419 h2c->curr_tssi_efuse_cck_de[i] = cck_de; 4677 4420 4678 4421 rtw89_debug(rtwdev, RTW89_DBG_TSSI, ··· 4686 4419 ofdm_de = phy_tssi_get_ofdm_de(rtwdev, phy, chan, i); 4687 4420 val = u32_get_bits(ofdm_de + trim_de, 0xff); 4688 4421 4689 - h2c->curr_tssi_ofdm_de[i] = 0x0; 4690 - h2c->curr_tssi_ofdm_de_20m[i] = val; 4691 - h2c->curr_tssi_ofdm_de_40m[i] = val; 4692 - h2c->curr_tssi_ofdm_de_80m[i] = val; 4693 - h2c->curr_tssi_ofdm_de_160m[i] = val; 4694 - h2c->curr_tssi_ofdm_de_320m[i] = val; 4422 + if (chip->chip_id == RTL8922A) { 4423 + h2c->curr_tssi_ofdm_de[i] = 0x0; 4424 + h2c->curr_tssi_ofdm_de_20m[i] = val; 4425 + h2c->curr_tssi_ofdm_de_40m[i] = val; 4426 + h2c->curr_tssi_ofdm_de_80m[i] = val; 4427 + h2c->curr_tssi_ofdm_de_160m[i] = val; 4428 + h2c->curr_tssi_ofdm_de_320m[i] = val; 4429 + } else { 4430 + h2c->curr_tssi_ofdm_de[i] = val; 4431 + } 4432 + 4695 4433 h2c->curr_tssi_efuse_ofdm_de[i] = ofdm_de; 4696 4434 4697 4435 rtw89_debug(rtwdev, RTW89_DBG_TSSI, ··· 4711 4439 { 4712 4440 struct rtw89_fw_txpwr_track_cfg *trk = rtwdev->fw.elm_info.txpwr_trk; 4713 4441 struct rtw89_tssi_info *tssi_info = &rtwdev->tssi; 4442 + const struct rtw89_chip_info *chip = rtwdev->chip; 4714 4443 const s8 *thm_up[RF_PATH_B + 1] = {}; 4715 4444 const s8 *thm_down[RF_PATH_B + 1] = {}; 4716 4445 u8 subband = chan->subband_type; 4717 - s8 thm_ofst[128] = {0}; 4446 + s8 thm_ofst[128] = {}; 4447 + int multiplier; 4718 4448 u8 thermal; 4719 4449 u8 path; 4720 4450 u8 i, j; ··· 4780 4506 rtw89_debug(rtwdev, RTW89_DBG_TSSI, 4781 4507 "[TSSI] tmeter tbl on subband: %u\n", subband); 4782 4508 4509 + if (chip->chip_id == RTL8922A) 4510 + multiplier = 1; 4511 + else 4512 + multiplier = -1; 4513 + 4783 4514 for (path = RF_PATH_A; path <= RF_PATH_B; path++) { 4784 4515 thermal = tssi_info->thermal[path]; 4785 4516 rtw89_debug(rtwdev, RTW89_DBG_TSSI, ··· 4799 4520 h2c->pg_thermal[path] = thermal; 4800 4521 4801 4522 i = 0; 4802 - for (j = 0; j < 64; j++) 4523 + for (j = 0; j < 64; j++) { 4803 4524 thm_ofst[j] = i < DELTA_SWINGIDX_SIZE ? 4804 4525 thm_up[path][i++] : 4805 4526 thm_up[path][DELTA_SWINGIDX_SIZE - 1]; 4527 + thm_ofst[j] *= multiplier; 4528 + } 4806 4529 4807 4530 i = 1; 4808 - for (j = 127; j >= 64; j--) 4531 + for (j = 127; j >= 64; j--) { 4809 4532 thm_ofst[j] = i < DELTA_SWINGIDX_SIZE ? 4810 4533 -thm_down[path][i++] : 4811 4534 -thm_down[path][DELTA_SWINGIDX_SIZE - 1]; 4535 + thm_ofst[j] *= multiplier; 4536 + } 4812 4537 4813 4538 for (i = 0; i < 128; i += 4) { 4814 4539 h2c->ftable[path][i + 0] = thm_ofst[i + 3]; ··· 6301 6018 env->ifs_clm_his[1] = 6302 6019 rtw89_phy_read32_idx(rtwdev, ccx->ifs_his_addr, 6303 6020 ccx->ifs_t2_his_mask, bb->phy_idx); 6021 + 6304 6022 env->ifs_clm_his[2] = 6305 - rtw89_phy_read32_idx(rtwdev, ccx->ifs_his_addr, 6023 + rtw89_phy_read32_idx(rtwdev, ccx->ifs_his_addr2, 6306 6024 ccx->ifs_t3_his_mask, bb->phy_idx); 6307 6025 env->ifs_clm_his[3] = 6308 - rtw89_phy_read32_idx(rtwdev, ccx->ifs_his_addr, 6026 + rtw89_phy_read32_idx(rtwdev, ccx->ifs_his_addr2, 6309 6027 ccx->ifs_t4_his_mask, bb->phy_idx); 6310 6028 6311 6029 env->ifs_clm_avg[0] = ··· 6569 6285 return true; 6570 6286 } 6571 6287 6572 - static u32 rtw89_phy_get_ie_bitmap_addr(enum rtw89_phy_status_bitmap ie_page) 6288 + static u32 rtw89_phy_get_ie_bitmap_addr(struct rtw89_dev *rtwdev, 6289 + enum rtw89_phy_status_bitmap ie_page) 6573 6290 { 6291 + const struct rtw89_phy_gen_def *phy = rtwdev->chip->phy_def; 6574 6292 static const u8 ie_page_shift = 2; 6575 6293 6576 6294 if (ie_page == RTW89_EHT_PKT) 6577 - return R_PHY_STS_BITMAP_EHT; 6295 + return phy->physt_bmp_eht; 6578 6296 6579 - return R_PHY_STS_BITMAP_ADDR_START + (ie_page << ie_page_shift); 6297 + return phy->physt_bmp_start + (ie_page << ie_page_shift); 6580 6298 } 6581 6299 6582 6300 static u32 rtw89_physts_get_ie_bitmap(struct rtw89_dev *rtwdev, ··· 6590 6304 if (!rtw89_physts_ie_page_valid(rtwdev, &ie_page)) 6591 6305 return 0; 6592 6306 6593 - addr = rtw89_phy_get_ie_bitmap_addr(ie_page); 6307 + addr = rtw89_phy_get_ie_bitmap_addr(rtwdev, ie_page); 6594 6308 6595 6309 return rtw89_phy_read32_idx(rtwdev, addr, MASKDWORD, phy_idx); 6596 6310 } ··· 6608 6322 if (chip->chip_id == RTL8852A) 6609 6323 val &= B_PHY_STS_BITMAP_MSK_52A; 6610 6324 6611 - addr = rtw89_phy_get_ie_bitmap_addr(ie_page); 6325 + addr = rtw89_phy_get_ie_bitmap_addr(rtwdev, ie_page); 6612 6326 rtw89_phy_write32_idx(rtwdev, addr, MASKDWORD, val, phy_idx); 6613 6327 } 6614 6328 ··· 6632 6346 } 6633 6347 } 6634 6348 6349 + static void rtw89_physts_enable_hdr_2(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx) 6350 + { 6351 + const struct rtw89_chip_info *chip = rtwdev->chip; 6352 + 6353 + if (chip->chip_gen == RTW89_CHIP_AX || chip->chip_id == RTL8922A) 6354 + return; 6355 + 6356 + rtw89_phy_write32_idx_set(rtwdev, R_STS_HDR2_PARSING_BE4, 6357 + B_STS_HDR2_PARSING_BE4, phy_idx); 6358 + } 6359 + 6635 6360 static void __rtw89_physts_parsing_init(struct rtw89_dev *rtwdev, 6636 6361 enum rtw89_phy_idx phy_idx) 6637 6362 { ··· 6651 6354 u8 i; 6652 6355 6653 6356 rtw89_physts_enable_fail_report(rtwdev, false, phy_idx); 6357 + 6358 + /* enable hdr_2 for 8922D (PHYSTS_BE_GEN2 above) */ 6359 + rtw89_physts_enable_hdr_2(rtwdev, phy_idx); 6654 6360 6655 6361 for (i = 0; i < RTW89_PHYSTS_BITMAP_NUM; i++) { 6656 6362 if (i == RTW89_RSVD_9 || ··· 7019 6719 bool enable) 7020 6720 { 7021 6721 const struct rtw89_dig_regs *dig_regs = rtwdev->chip->dig_regs; 6722 + 6723 + if (rtwdev->chip->chip_gen != RTW89_CHIP_AX) 6724 + return; 7022 6725 7023 6726 rtw89_phy_write32_idx(rtwdev, dig_regs->p0_p20_pagcugc_en.addr, 7024 6727 dig_regs->p0_p20_pagcugc_en.mask, enable, bb->phy_idx); ··· 8082 7779 bool flag_fb, flag_p20, flag_s20, flag_s40, flag_s80; 8083 7780 s8 pwdb_fb, pwdb_p20, pwdb_s20, pwdb_s40, pwdb_s80; 8084 7781 u8 path, per20_bitmap = 0; 7782 + u8 pwdb_sel = 5; 8085 7783 u8 pwdb[8]; 8086 7784 u32 tmp; 8087 7785 ··· 8094 7790 else 8095 7791 edcca_p_regs = &edcca_regs->p[RTW89_PHY_0]; 8096 7792 8097 - if (rtwdev->chip->chip_id == RTL8922A) 8098 - rtw89_phy_write32_mask(rtwdev, edcca_regs->rpt_sel_be, 8099 - edcca_regs->rpt_sel_be_mask, 0); 8100 - 8101 7793 rtw89_phy_write32_mask(rtwdev, edcca_p_regs->rpt_sel, 8102 7794 edcca_p_regs->rpt_sel_mask, 0); 7795 + if (rtwdev->chip->chip_id == RTL8922A || rtwdev->chip->chip_id == RTL8922D) { 7796 + rtw89_phy_write32_mask(rtwdev, edcca_regs->rpt_sel_be, 7797 + edcca_regs->rpt_sel_be_mask, 0); 7798 + per20_bitmap = rtw89_phy_read32_mask(rtwdev, edcca_p_regs->rpt_a, 7799 + MASKBYTE0); 7800 + } 8103 7801 tmp = rtw89_phy_read32(rtwdev, edcca_p_regs->rpt_b); 8104 7802 path = u32_get_bits(tmp, B_EDCCA_RPT_B_PATH_MASK); 8105 7803 flag_s80 = u32_get_bits(tmp, B_EDCCA_RPT_B_S80); ··· 8113 7807 pwdb_p20 = u32_get_bits(tmp, MASKBYTE2); 8114 7808 pwdb_fb = u32_get_bits(tmp, MASKBYTE3); 8115 7809 7810 + if (rtwdev->chip->chip_id == RTL8922D) 7811 + pwdb_sel = 2; 7812 + 8116 7813 rtw89_phy_write32_mask(rtwdev, edcca_p_regs->rpt_sel, 8117 - edcca_p_regs->rpt_sel_mask, 5); 7814 + edcca_p_regs->rpt_sel_mask, pwdb_sel); 8118 7815 tmp = rtw89_phy_read32(rtwdev, edcca_p_regs->rpt_b); 8119 7816 pwdb_s80 = u32_get_bits(tmp, MASKBYTE1); 8120 7817 pwdb_s40 = u32_get_bits(tmp, MASKBYTE2); 8121 7818 8122 - if (rtwdev->chip->chip_id == RTL8922A) { 7819 + if (rtwdev->chip->chip_id == RTL8922A || rtwdev->chip->chip_id == RTL8922D) { 8123 7820 rtw89_phy_write32_mask(rtwdev, edcca_regs->rpt_sel_be, 8124 7821 edcca_regs->rpt_sel_be_mask, 4); 8125 7822 tmp = rtw89_phy_read32(rtwdev, edcca_p_regs->rpt_b); ··· 8130 7821 pwdb[1] = u32_get_bits(tmp, MASKBYTE2); 8131 7822 pwdb[2] = u32_get_bits(tmp, MASKBYTE1); 8132 7823 pwdb[3] = u32_get_bits(tmp, MASKBYTE0); 8133 - per20_bitmap = rtw89_phy_read32_mask(rtwdev, edcca_p_regs->rpt_a, 8134 - MASKBYTE0); 8135 7824 8136 7825 rtw89_phy_write32_mask(rtwdev, edcca_regs->rpt_sel_be, 8137 7826 edcca_regs->rpt_sel_be_mask, 5); ··· 8351 8044 .ifs_clm_ofdm_fa_mask = B_IFS_CLM_OFDM_FA_MSK, 8352 8045 .ifs_clm_cck_fa_mask = B_IFS_CLM_CCK_FA_MSK, 8353 8046 .ifs_his_addr = R_IFS_HIS, 8047 + .ifs_his_addr2 = R_IFS_HIS, 8354 8048 .ifs_t4_his_mask = B_IFS_T4_HIS_MSK, 8355 8049 .ifs_t3_his_mask = B_IFS_T3_HIS_MSK, 8356 8050 .ifs_t2_his_mask = B_IFS_T2_HIS_MSK, ··· 8397 8089 8398 8090 const struct rtw89_phy_gen_def rtw89_phy_gen_ax = { 8399 8091 .cr_base = 0x10000, 8092 + .physt_bmp_start = R_PHY_STS_BITMAP_ADDR_START, 8093 + .physt_bmp_eht = 0xfc, 8400 8094 .ccx = &rtw89_ccx_regs_ax, 8401 8095 .physts = &rtw89_physts_regs_ax, 8402 8096 .cfo = &rtw89_cfo_regs_ax, 8097 + .bb_wrap = NULL, 8403 8098 .phy0_phy1_offset = rtw89_phy0_phy1_offset_ax, 8404 8099 .config_bb_gain = rtw89_phy_config_bb_gain_ax, 8405 8100 .preinit_rf_nctl = rtw89_phy_preinit_rf_nctl_ax,
+35 -1
drivers/net/wireless/realtek/rtw89/phy.h
··· 139 139 RTW89_PHY_C2H_FUNC_STS_RPT, 140 140 RTW89_PHY_C2H_FUNC_MU_GPTBL_RPT, 141 141 RTW89_PHY_C2H_FUNC_TXSTS, 142 - RTW89_PHY_C2H_FUNC_RA_MAX, 142 + RTW89_PHY_C2H_FUNC_ACCELERATE_EN = 0x7, 143 + 144 + RTW89_PHY_C2H_FUNC_RA_NUM, 143 145 }; 144 146 145 147 enum rtw89_phy_c2h_rfk_log_func { ··· 152 150 RTW89_PHY_C2H_RFK_LOG_FUNC_TSSI = 4, 153 151 RTW89_PHY_C2H_RFK_LOG_FUNC_TXGAPK = 5, 154 152 RTW89_PHY_C2H_RFK_LOG_FUNC_TAS_PWR = 9, 153 + RTW89_PHY_C2H_RFK_LOG_FUNC_TXIQK = 0xc, 154 + RTW89_PHY_C2H_RFK_LOG_FUNC_CIM3K = 0xe, 155 155 156 156 RTW89_PHY_C2H_RFK_LOG_FUNC_NUM, 157 157 }; ··· 169 165 RTW89_PHY_C2H_DM_FUNC_SIGB, 170 166 RTW89_PHY_C2H_DM_FUNC_LOWRT_RTY, 171 167 RTW89_PHY_C2H_DM_FUNC_MCC_DIG, 168 + RTW89_PHY_C2H_DM_FUNC_LPS = 0x9, 169 + RTW89_PHY_C2H_DM_FUNC_ENV_MNTR = 0xa, 172 170 RTW89_PHY_C2H_DM_FUNC_FW_SCAN = 0xc, 173 171 RTW89_PHY_C2H_DM_FUNC_NUM, 174 172 }; ··· 422 416 u32 ifs_clm_ofdm_fa_mask; 423 417 u32 ifs_clm_cck_fa_mask; 424 418 u32 ifs_his_addr; 419 + u32 ifs_his_addr2; 425 420 u32 ifs_t4_his_mask; 426 421 u32 ifs_t3_his_mask; 427 422 u32 ifs_t2_his_mask; ··· 464 457 u32 weighting_mask; 465 458 u32 comp_seg0; 466 459 u32 valid_0_mask; 460 + }; 461 + 462 + struct rtw89_bb_wrap_regs { 463 + u32 pwr_macid_lmt; 464 + u32 pwr_macid_path; 467 465 }; 468 466 469 467 enum rtw89_bandwidth_section_num_ax { ··· 543 531 544 532 struct rtw89_phy_gen_def { 545 533 u32 cr_base; 534 + u32 physt_bmp_start; 535 + u32 physt_bmp_eht; 546 536 const struct rtw89_ccx_regs *ccx; 547 537 const struct rtw89_physts_regs *physts; 548 538 const struct rtw89_cfo_regs *cfo; 539 + const struct rtw89_bb_wrap_regs *bb_wrap; 549 540 u32 (*phy0_phy1_offset)(struct rtw89_dev *rtwdev, u32 addr); 550 541 void (*config_bb_gain)(struct rtw89_dev *rtwdev, 551 542 const struct rtw89_reg2_def *reg, ··· 574 559 575 560 extern const struct rtw89_phy_gen_def rtw89_phy_gen_ax; 576 561 extern const struct rtw89_phy_gen_def rtw89_phy_gen_be; 562 + extern const struct rtw89_phy_gen_def rtw89_phy_gen_be_v1; 577 563 578 564 static inline void rtw89_phy_write8(struct rtw89_dev *rtwdev, 579 565 u32 addr, u8 data) ··· 839 823 u32 addr, u32 mask); 840 824 u32 rtw89_phy_read_rf_v2(struct rtw89_dev *rtwdev, enum rtw89_rf_path rf_path, 841 825 u32 addr, u32 mask); 826 + u32 rtw89_phy_read_rf_v3(struct rtw89_dev *rtwdev, enum rtw89_rf_path rf_path, 827 + u32 addr, u32 mask); 842 828 bool rtw89_phy_write_rf(struct rtw89_dev *rtwdev, enum rtw89_rf_path rf_path, 843 829 u32 addr, u32 mask, u32 data); 844 830 bool rtw89_phy_write_rf_v1(struct rtw89_dev *rtwdev, enum rtw89_rf_path rf_path, 845 831 u32 addr, u32 mask, u32 data); 846 832 bool rtw89_phy_write_rf_v2(struct rtw89_dev *rtwdev, enum rtw89_rf_path rf_path, 833 + u32 addr, u32 mask, u32 data); 834 + bool rtw89_phy_write_rf_v3(struct rtw89_dev *rtwdev, enum rtw89_rf_path rf_path, 847 835 u32 addr, u32 mask, u32 data); 848 836 void rtw89_phy_init_bb_reg(struct rtw89_dev *rtwdev); 849 837 void rtw89_phy_init_bb_afe(struct rtw89_dev *rtwdev); ··· 898 878 if (phy->bb_wrap_init) 899 879 phy->bb_wrap_init(rtwdev); 900 880 } 881 + 882 + void rtw89_phy_bb_wrap_set_rfsi_ct_opt(struct rtw89_dev *rtwdev, 883 + enum rtw89_phy_idx phy_idx); 884 + void rtw89_phy_bb_wrap_set_rfsi_bandedge_ch(struct rtw89_dev *rtwdev, 885 + const struct rtw89_chan *chan, 886 + enum rtw89_phy_idx phy_idx); 901 887 902 888 static inline void rtw89_phy_ch_info_init(struct rtw89_dev *rtwdev) 903 889 { ··· 1036 1010 enum rtw89_phy_idx phy_idx, 1037 1011 const struct rtw89_chan *chan, 1038 1012 bool is_chl_k, unsigned int ms); 1013 + int rtw89_phy_rfk_txiqk_and_wait(struct rtw89_dev *rtwdev, 1014 + enum rtw89_phy_idx phy_idx, 1015 + const struct rtw89_chan *chan, 1016 + unsigned int ms); 1017 + int rtw89_phy_rfk_cim3k_and_wait(struct rtw89_dev *rtwdev, 1018 + enum rtw89_phy_idx phy_idx, 1019 + const struct rtw89_chan *chan, 1020 + unsigned int ms); 1039 1021 void rtw89_phy_rfk_tssi_fill_fwcmd_efuse_to_de(struct rtw89_dev *rtwdev, 1040 1022 enum rtw89_phy_idx phy, 1041 1023 const struct rtw89_chan *chan,
+543 -20
drivers/net/wireless/realtek/rtw89/phy_be.c
··· 2 2 /* Copyright(c) 2023 Realtek Corporation 3 3 */ 4 4 5 + #include "chan.h" 5 6 #include "debug.h" 6 7 #include "mac.h" 7 8 #include "phy.h" ··· 45 44 .ifs_clm_ofdm_fa_mask = B_IFS_CLM_OFDM_FA_MSK, 46 45 .ifs_clm_cck_fa_mask = B_IFS_CLM_CCK_FA_MSK, 47 46 .ifs_his_addr = R_IFS_HIS_V1, 47 + .ifs_his_addr2 = R_IFS_HIS_V1, 48 48 .ifs_t4_his_mask = B_IFS_T4_HIS_MSK, 49 49 .ifs_t3_his_mask = B_IFS_T3_HIS_MSK, 50 50 .ifs_t2_his_mask = B_IFS_T2_HIS_MSK, ··· 76 74 .nhm_pwr_method_msk = B_NHM_PWDB_METHOD_MSK, 77 75 }; 78 76 77 + static const struct rtw89_ccx_regs rtw89_ccx_regs_be_v1 = { 78 + .setting_addr = R_CCX_BE4, 79 + .edcca_opt_mask = B_CCX_EDCCA_OPT_MSK_V1, 80 + .measurement_trig_mask = B_MEASUREMENT_TRIG_MSK, 81 + .trig_opt_mask = B_CCX_TRIG_OPT_MSK, 82 + .en_mask = B_CCX_EN_MSK, 83 + .ifs_cnt_addr = R_IFS_COUNTER_BE4, 84 + .ifs_clm_period_mask = B_IFS_CLM_PERIOD_MSK, 85 + .ifs_clm_cnt_unit_mask = B_IFS_CLM_COUNTER_UNIT_MSK, 86 + .ifs_clm_cnt_clear_mask = B_IFS_COUNTER_CLR_MSK, 87 + .ifs_collect_en_mask = B_IFS_COLLECT_EN, 88 + .ifs_t1_addr = R_IFS_T1_BE4, 89 + .ifs_t1_th_h_mask = B_IFS_T1_TH_HIGH_MSK, 90 + .ifs_t1_en_mask = B_IFS_T1_EN_MSK, 91 + .ifs_t1_th_l_mask = B_IFS_T1_TH_LOW_MSK, 92 + .ifs_t2_addr = R_IFS_T2_BE4, 93 + .ifs_t2_th_h_mask = B_IFS_T2_TH_HIGH_MSK, 94 + .ifs_t2_en_mask = B_IFS_T2_EN_MSK, 95 + .ifs_t2_th_l_mask = B_IFS_T2_TH_LOW_MSK, 96 + .ifs_t3_addr = R_IFS_T3_BE4, 97 + .ifs_t3_th_h_mask = B_IFS_T3_TH_HIGH_MSK, 98 + .ifs_t3_en_mask = B_IFS_T3_EN_MSK, 99 + .ifs_t3_th_l_mask = B_IFS_T3_TH_LOW_MSK, 100 + .ifs_t4_addr = R_IFS_T4_BE4, 101 + .ifs_t4_th_h_mask = B_IFS_T4_TH_HIGH_MSK, 102 + .ifs_t4_en_mask = B_IFS_T4_EN_MSK, 103 + .ifs_t4_th_l_mask = B_IFS_T4_TH_LOW_MSK, 104 + .ifs_clm_tx_cnt_addr = R_IFS_CLM_TX_CNT_BE4, 105 + .ifs_clm_edcca_excl_cca_fa_mask = B_IFS_CLM_EDCCA_EXCLUDE_CCA_FA_MSK, 106 + .ifs_clm_tx_cnt_msk = B_IFS_CLM_TX_CNT_MSK, 107 + .ifs_clm_cca_addr = R_IFS_CLM_CCA_BE4, 108 + .ifs_clm_ofdmcca_excl_fa_mask = B_IFS_CLM_OFDMCCA_EXCLUDE_FA_MSK, 109 + .ifs_clm_cckcca_excl_fa_mask = B_IFS_CLM_CCKCCA_EXCLUDE_FA_MSK, 110 + .ifs_clm_fa_addr = R_IFS_CLM_FA_BE4, 111 + .ifs_clm_ofdm_fa_mask = B_IFS_CLM_OFDM_FA_MSK, 112 + .ifs_clm_cck_fa_mask = B_IFS_CLM_CCK_FA_MSK, 113 + .ifs_his_addr = R_IFS_T1_HIS_BE4, 114 + .ifs_his_addr2 = R_IFS_T3_HIS_BE4, /* for 3/4 */ 115 + .ifs_t4_his_mask = B_IFS_T4_HIS_BE4, 116 + .ifs_t3_his_mask = B_IFS_T3_HIS_BE4, 117 + .ifs_t2_his_mask = B_IFS_T2_HIS_BE4, 118 + .ifs_t1_his_mask = B_IFS_T1_HIS_BE4, 119 + .ifs_avg_l_addr = R_IFS_T1_AVG_BE4, 120 + .ifs_t2_avg_mask = B_IFS_T2_AVG_BE4, 121 + .ifs_t1_avg_mask = B_IFS_T1_AVG_BE4, 122 + .ifs_avg_h_addr = R_IFS_T3_AVG_BE4, 123 + .ifs_t4_avg_mask = B_IFS_T4_AVG_BE4, 124 + .ifs_t3_avg_mask = B_IFS_T3_AVG_BE4, 125 + .ifs_cca_l_addr = R_IFS_T1_CLM_BE4, 126 + .ifs_t2_cca_mask = B_IFS_T2_CLM_BE4, 127 + .ifs_t1_cca_mask = B_IFS_T1_CLM_BE4, 128 + .ifs_cca_h_addr = R_IFS_T3_CLM_BE4, 129 + .ifs_t4_cca_mask = B_IFS_T4_CLM_BE4, 130 + .ifs_t3_cca_mask = B_IFS_T3_CLM_BE4, 131 + .ifs_total_addr = R_IFS_TOTAL_BE4, 132 + .ifs_cnt_done_mask = B_IFS_CNT_DONE_BE4, 133 + .ifs_total_mask = B_IFS_TOTAL_BE4, 134 + }; 135 + 79 136 static const struct rtw89_physts_regs rtw89_physts_regs_be = { 80 137 .setting_addr = R_PLCP_HISTOGRAM, 81 138 .dis_trigger_fail_mask = B_STS_DIS_TRIG_BY_FAIL, 82 139 .dis_trigger_brk_mask = B_STS_DIS_TRIG_BY_BRK, 83 140 }; 84 141 142 + static const struct rtw89_physts_regs rtw89_physts_regs_be_v1 = { 143 + .setting_addr = R_PLCP_HISTOGRAM_BE_V1, 144 + .dis_trigger_fail_mask = B_STS_DIS_TRIG_BY_FAIL, 145 + .dis_trigger_brk_mask = B_STS_DIS_TRIG_BY_BRK, 146 + }; 147 + 85 148 static const struct rtw89_cfo_regs rtw89_cfo_regs_be = { 86 - .comp = R_DCFO_WEIGHT_V1, 87 - .weighting_mask = B_DCFO_WEIGHT_MSK_V1, 88 - .comp_seg0 = R_DCFO_OPT_V1, 89 - .valid_0_mask = B_DCFO_OPT_EN_V1, 149 + .comp = R_DCFO_WEIGHT_BE, 150 + .weighting_mask = B_DCFO_WEIGHT_MSK_BE, 151 + .comp_seg0 = R_DCFO_OPT_BE, 152 + .valid_0_mask = B_DCFO_OPT_EN_BE, 153 + }; 154 + 155 + static const struct rtw89_cfo_regs rtw89_cfo_regs_be_v1 = { 156 + .comp = R_DCFO_WEIGHT_BE_V1, 157 + .weighting_mask = B_DCFO_WEIGHT_MSK_BE, 158 + .comp_seg0 = R_DCFO_OPT_BE_V1, 159 + .valid_0_mask = B_DCFO_OPT_EN_BE, 160 + }; 161 + 162 + static const struct rtw89_bb_wrap_regs rtw89_bb_wrap_regs_be = { 163 + .pwr_macid_lmt = R_BE_PWR_MACID_LMT_BASE, 164 + .pwr_macid_path = R_BE_PWR_MACID_PATH_BASE, 165 + }; 166 + 167 + static const struct rtw89_bb_wrap_regs rtw89_bb_wrap_regs_be_v1 = { 168 + .pwr_macid_lmt = R_BE_PWR_MACID_LMT_BASE_V1, 169 + .pwr_macid_path = R_BE_PWR_MACID_PATH_BASE_V1, 90 170 }; 91 171 92 172 static u32 rtw89_phy0_phy1_offset_be(struct rtw89_dev *rtwdev, u32 addr) ··· 182 98 (phy_page >= 0x60 && phy_page <= 0x6f) || 183 99 (phy_page >= 0xE4 && phy_page <= 0xE5) || 184 100 (phy_page >= 0xE8 && phy_page <= 0xED)) 101 + ofst = 0x1000; 102 + else 103 + ofst = 0x0; 104 + 105 + return ofst; 106 + } 107 + 108 + static u32 rtw89_phy0_phy1_offset_be_v1(struct rtw89_dev *rtwdev, u32 addr) 109 + { 110 + u32 phy_page = addr >> 8; 111 + u32 ofst = 0; 112 + 113 + if ((phy_page >= 0x204 && phy_page <= 0x20F) || 114 + (phy_page >= 0x220 && phy_page <= 0x22F) || 115 + (phy_page >= 0x240 && phy_page <= 0x24f) || 116 + (phy_page >= 0x260 && phy_page <= 0x26f) || 117 + (phy_page >= 0x2C0 && phy_page <= 0x2C9) || 118 + (phy_page >= 0x2E4 && phy_page <= 0x2E8) || 119 + phy_page == 0x2EE) 185 120 ofst = 0x1000; 186 121 else 187 122 ofst = 0x0; ··· 404 301 } 405 302 } 406 303 304 + static void rtw89_phy_preinit_rf_nctl_be_v1(struct rtw89_dev *rtwdev) 305 + { 306 + rtw89_phy_write32_mask(rtwdev, R_GOTX_IQKDPK_C0_BE4, B_GOTX_IQKDPK, 0x3); 307 + rtw89_phy_write32_mask(rtwdev, R_GOTX_IQKDPK_C1_BE4, B_GOTX_IQKDPK, 0x3); 308 + rtw89_phy_write32_mask(rtwdev, R_IOQ_IQK_DPK_BE4, B_IOQ_IQK_DPK_RST, 0x1); 309 + rtw89_phy_write32_mask(rtwdev, R_IQK_DPK_RST_BE4, B_IQK_DPK_RST, 0x1); 310 + rtw89_phy_write32_mask(rtwdev, R_IQK_DPK_PRST_BE4, B_IQK_DPK_PRST, 0x1); 311 + rtw89_phy_write32_mask(rtwdev, R_IQK_DPK_PRST_C1_BE4, B_IQK_DPK_PRST, 0x1); 312 + } 313 + 314 + static u32 rtw89_phy_bb_wrap_flush_addr(struct rtw89_dev *rtwdev, u32 addr) 315 + { 316 + struct rtw89_hal *hal = &rtwdev->hal; 317 + 318 + if (!test_bit(RTW89_FLAG_RUNNING, rtwdev->flags)) 319 + return 0; 320 + 321 + if (rtwdev->chip->chip_id == RTL8922D && hal->cid == RTL8922D_CID7025) { 322 + if (addr >= R_BE_PWR_MACID_PATH_BASE_V1 && 323 + addr <= R_BE_PWR_MACID_PATH_BASE_V1 + 0xFF) 324 + return addr + 0x800; 325 + 326 + if (addr >= R_BE_PWR_MACID_LMT_BASE_V1 && 327 + addr <= R_BE_PWR_MACID_LMT_BASE_V1 + 0xFF) 328 + return addr - 0x800; 329 + } 330 + 331 + return 0; 332 + } 333 + 334 + static 335 + void rtw89_write_bb_wrap_flush(struct rtw89_dev *rtwdev, u32 addr, u32 data) 336 + { 337 + /* To write registers of pwr_macid_lmt and pwr_macid_path with flush */ 338 + u32 flush_addr; 339 + u32 val32; 340 + 341 + flush_addr = rtw89_phy_bb_wrap_flush_addr(rtwdev, addr); 342 + if (flush_addr) { 343 + val32 = rtw89_read32(rtwdev, flush_addr); 344 + rtw89_write32(rtwdev, flush_addr, val32); 345 + } 346 + 347 + rtw89_write32(rtwdev, addr, data); 348 + } 349 + 407 350 static 408 351 void rtw89_phy_bb_wrap_pwr_by_macid_init(struct rtw89_dev *rtwdev) 409 352 { 410 - u32 macid_idx, cr, base_macid_lmt, max_macid = 32; 353 + const struct rtw89_phy_gen_def *phy = rtwdev->chip->phy_def; 354 + const struct rtw89_bb_wrap_regs *bb_wrap = phy->bb_wrap; 355 + u32 max_macid = rtwdev->chip->support_macid_num; 356 + u32 macid_idx, cr, base_macid_lmt; 411 357 412 - base_macid_lmt = R_BE_PWR_MACID_LMT_BASE; 358 + base_macid_lmt = bb_wrap->pwr_macid_lmt; 413 359 414 360 for (macid_idx = 0; macid_idx < 4 * max_macid; macid_idx += 4) { 415 361 cr = base_macid_lmt + macid_idx; 416 - rtw89_write32(rtwdev, cr, 0x03007F7F); 362 + rtw89_write_bb_wrap_flush(rtwdev, cr, 0); 417 363 } 418 364 } 419 365 420 366 static 421 367 void rtw89_phy_bb_wrap_tx_path_by_macid_init(struct rtw89_dev *rtwdev) 422 368 { 423 - int i, max_macid = 32; 424 - u32 cr = R_BE_PWR_MACID_PATH_BASE; 369 + const struct rtw89_phy_gen_def *phy = rtwdev->chip->phy_def; 370 + const struct rtw89_bb_wrap_regs *bb_wrap = phy->bb_wrap; 371 + u32 max_macid = rtwdev->chip->support_macid_num; 372 + u32 cr = bb_wrap->pwr_macid_path; 373 + int i; 425 374 426 375 for (i = 0; i < max_macid; i++, cr += 4) 427 - rtw89_write32(rtwdev, cr, 0x03C86000); 376 + rtw89_write_bb_wrap_flush(rtwdev, cr, 0); 428 377 } 429 378 430 379 static void rtw89_phy_bb_wrap_tpu_set_all(struct rtw89_dev *rtwdev, 431 380 enum rtw89_mac_idx mac_idx) 432 381 { 433 - u32 addr; 382 + u32 addr, t; 434 383 435 - for (addr = R_BE_PWR_BY_RATE; addr <= R_BE_PWR_BY_RATE_END; addr += 4) 436 - rtw89_write32(rtwdev, addr, 0); 437 - for (addr = R_BE_PWR_RULMT_START; addr <= R_BE_PWR_RULMT_END; addr += 4) 438 - rtw89_write32(rtwdev, addr, 0); 439 - for (addr = R_BE_PWR_RATE_OFST_CTRL; addr <= R_BE_PWR_RATE_OFST_END; addr += 4) 440 - rtw89_write32(rtwdev, addr, 0); 384 + addr = rtw89_mac_reg_by_idx(rtwdev, R_BE_PWR_FTM_SS, mac_idx); 385 + rtw89_write32_mask(rtwdev, addr, B_BE_PWR_BY_RATE_DBW_ON, 0x3); 386 + 387 + for (addr = R_BE_PWR_BY_RATE; addr <= R_BE_PWR_BY_RATE_END; addr += 4) { 388 + t = rtw89_mac_reg_by_idx(rtwdev, addr, mac_idx); 389 + rtw89_write32(rtwdev, t, 0); 390 + } 391 + for (addr = R_BE_PWR_RULMT_START; addr <= R_BE_PWR_RULMT_END; addr += 4) { 392 + t = rtw89_mac_reg_by_idx(rtwdev, addr, mac_idx); 393 + rtw89_write32(rtwdev, t, 0); 394 + } 395 + for (addr = R_BE_PWR_RATE_OFST_CTRL; addr <= R_BE_PWR_RATE_OFST_END; addr += 4) { 396 + t = rtw89_mac_reg_by_idx(rtwdev, addr, mac_idx); 397 + rtw89_write32(rtwdev, t, 0); 398 + } 441 399 442 400 addr = rtw89_mac_reg_by_idx(rtwdev, R_BE_PWR_REF_CTRL, mac_idx); 443 401 rtw89_write32_mask(rtwdev, addr, B_BE_PWR_OFST_LMT_DB, 0); ··· 558 394 rtw89_write32_mask(rtwdev, addr, 0x7, 0); 559 395 } 560 396 397 + static u32 rtw89_phy_bb_wrap_be_bandedge_decision(struct rtw89_dev *rtwdev, 398 + const struct rtw89_chan *chan) 399 + { 400 + u8 pri_ch = chan->primary_channel; 401 + u32 val = 0; 402 + 403 + switch (chan->band_type) { 404 + default: 405 + case RTW89_BAND_2G: 406 + if (pri_ch == 1 || pri_ch == 13) 407 + val = BIT(1) | BIT(0); 408 + else if (pri_ch == 3 || pri_ch == 11) 409 + val = BIT(1); 410 + break; 411 + case RTW89_BAND_5G: 412 + if (pri_ch == 36 || pri_ch == 64 || pri_ch == 100) 413 + val = BIT(3) | BIT(2) | BIT(1) | BIT(0); 414 + else if (pri_ch == 40 || pri_ch == 60 || pri_ch == 104) 415 + val = BIT(3) | BIT(2) | BIT(1); 416 + else if ((pri_ch > 40 && pri_ch < 60) || pri_ch == 108 || pri_ch == 112) 417 + val = BIT(3) | BIT(2); 418 + else if (pri_ch > 112 && pri_ch < 132) 419 + val = BIT(3); 420 + break; 421 + case RTW89_BAND_6G: 422 + if (pri_ch == 233) 423 + val = BIT(0); 424 + break; 425 + } 426 + 427 + return val; 428 + } 429 + 430 + void rtw89_phy_bb_wrap_set_rfsi_ct_opt(struct rtw89_dev *rtwdev, 431 + enum rtw89_phy_idx phy_idx) 432 + { 433 + u32 reg; 434 + 435 + reg = rtw89_mac_reg_by_idx(rtwdev, R_RFSI_CT_OPT_0_BE4, phy_idx); 436 + rtw89_write32(rtwdev, reg, 0x00010001); 437 + 438 + reg = rtw89_mac_reg_by_idx(rtwdev, R_RFSI_CT_OPT_8_BE4, phy_idx); 439 + rtw89_write32(rtwdev, reg, 0x00010001); 440 + } 441 + EXPORT_SYMBOL(rtw89_phy_bb_wrap_set_rfsi_ct_opt); 442 + 443 + void rtw89_phy_bb_wrap_set_rfsi_bandedge_ch(struct rtw89_dev *rtwdev, 444 + const struct rtw89_chan *chan, 445 + enum rtw89_phy_idx phy_idx) 446 + { 447 + u32 reg; 448 + u32 val; 449 + 450 + val = rtw89_phy_bb_wrap_be_bandedge_decision(rtwdev, chan); 451 + 452 + rtw89_phy_write32_idx(rtwdev, R_TX_CFR_MANUAL_EN_BE4, B_TX_CFR_MANUAL_EN_BE4_M, 453 + chan->primary_channel == 13, phy_idx); 454 + 455 + reg = rtw89_mac_reg_by_idx(rtwdev, R_BANDEDGE_DBWX_BE4, phy_idx); 456 + rtw89_write32_mask(rtwdev, reg, B_BANDEDGE_DBW20_BE4, val & BIT(0)); 457 + reg = rtw89_mac_reg_by_idx(rtwdev, R_BANDEDGE_DBWX_BE4, phy_idx); 458 + rtw89_write32_mask(rtwdev, reg, B_BANDEDGE_DBW40_BE4, (val & BIT(1)) >> 1); 459 + reg = rtw89_mac_reg_by_idx(rtwdev, R_BANDEDGE_DBWX_BE4, phy_idx); 460 + rtw89_write32_mask(rtwdev, reg, B_BANDEDGE_DBW80_BE4, (val & BIT(2)) >> 2); 461 + reg = rtw89_mac_reg_by_idx(rtwdev, R_BANDEDGE_DBWY_BE4, phy_idx); 462 + rtw89_write32_mask(rtwdev, reg, B_BANDEDGE_DBW160_BE4, (val & BIT(3)) >> 3); 463 + } 464 + EXPORT_SYMBOL(rtw89_phy_bb_wrap_set_rfsi_bandedge_ch); 465 + 466 + static void rtw89_phy_bb_wrap_tx_rfsi_qam_comp_th_init(struct rtw89_dev *rtwdev, 467 + enum rtw89_mac_idx mac_idx) 468 + { 469 + /* TH0 */ 470 + rtw89_write32_idx(rtwdev, R_QAM_TH0_BE4, B_QAM_TH0_0_BE4, 0x1, mac_idx); 471 + rtw89_write32_idx(rtwdev, R_QAM_TH0_BE4, B_QAM_TH0_3_BE4, 0x1, mac_idx); 472 + rtw89_write32_idx(rtwdev, R_QAM_TH1_BE4, B_QAM_TH1_1_BE4, 0x1, mac_idx); 473 + rtw89_write32_idx(rtwdev, R_QAM_TH1_BE4, B_QAM_TH1_4_BE4, 0x1, mac_idx); 474 + rtw89_write32_idx(rtwdev, R_QAM_TH1_BE4, B_QAM_TH1_7_BE4, 0x1, mac_idx); 475 + rtw89_write32_idx(rtwdev, R_QAM_TH2_BE4, B_QAM_TH2_0_BE4, 0x1, mac_idx); 476 + rtw89_write32_idx(rtwdev, R_QAM_TH2_BE4, B_QAM_TH2_3_BE4, 0x1, mac_idx); 477 + rtw89_write32_idx(rtwdev, R_QAM_TH2_BE4, B_QAM_TH2_6_BE4, 0x1, mac_idx); 478 + /* TH1 */ 479 + rtw89_write32_idx(rtwdev, R_QAM_TH0_BE4, B_QAM_TH0_1_BE4, 0x2, mac_idx); 480 + rtw89_write32_idx(rtwdev, R_QAM_TH0_BE4, B_QAM_TH0_4_BE4, 0x2, mac_idx); 481 + rtw89_write32_idx(rtwdev, R_QAM_TH1_BE4, B_QAM_TH1_2_BE4, 0x2, mac_idx); 482 + rtw89_write32_idx(rtwdev, R_QAM_TH1_BE4, B_QAM_TH1_5_BE4, 0x2, mac_idx); 483 + rtw89_write32_idx(rtwdev, R_QAM_TH1_BE4, B_QAM_TH1_8_BE4, 0x2, mac_idx); 484 + rtw89_write32_idx(rtwdev, R_QAM_TH2_BE4, B_QAM_TH2_1_BE4, 0x2, mac_idx); 485 + rtw89_write32_idx(rtwdev, R_QAM_TH2_BE4, B_QAM_TH2_4_BE4, 0x2, mac_idx); 486 + rtw89_write32_idx(rtwdev, R_QAM_TH2_BE4, B_QAM_TH2_7_BE4, 0x2, mac_idx); 487 + /* TH2 */ 488 + rtw89_write32_idx(rtwdev, R_QAM_TH0_BE4, B_QAM_TH0_2_BE4, 0x4, mac_idx); 489 + rtw89_write32_idx(rtwdev, R_QAM_TH1_BE4, B_QAM_TH1_0_BE4, 0x4, mac_idx); 490 + rtw89_write32_idx(rtwdev, R_QAM_TH1_BE4, B_QAM_TH1_3_BE4, 0x4, mac_idx); 491 + rtw89_write32_idx(rtwdev, R_QAM_TH1_BE4, B_QAM_TH1_6_BE4, 0x4, mac_idx); 492 + rtw89_write32_idx(rtwdev, R_QAM_TH1_BE4, B_QAM_TH1_9_BE4, 0x4, mac_idx); 493 + rtw89_write32_idx(rtwdev, R_QAM_TH2_BE4, B_QAM_TH2_2_BE4, 0x4, mac_idx); 494 + rtw89_write32_idx(rtwdev, R_QAM_TH2_BE4, B_QAM_TH2_5_BE4, 0x4, mac_idx); 495 + rtw89_write32_idx(rtwdev, R_QAM_TH2_BE4, B_QAM_TH2_8_BE4, 0x4, mac_idx); 496 + /* DPD 160M */ 497 + rtw89_write32_idx(rtwdev, R_DPD_DBW160_TH0_BE4, B_DPD_DBW160_TH0_0_BE4, 0x1, mac_idx); 498 + rtw89_write32_idx(rtwdev, R_DPD_DBW160_TH0_BE4, B_DPD_DBW160_TH0_1_BE4, 0x1, mac_idx); 499 + rtw89_write32_idx(rtwdev, R_DPD_DBW160_TH0_BE4, B_DPD_DBW160_TH0_2_BE4, 0x1, mac_idx); 500 + rtw89_write32_idx(rtwdev, R_DPD_DBW160_TH0_BE4, B_DPD_DBW160_TH0_3_BE4, 0x1, mac_idx); 501 + rtw89_write32_idx(rtwdev, R_DPD_DBW160_TH0_BE4, B_DPD_DBW160_TH0_4_BE4, 0x1, mac_idx); 502 + rtw89_write32_idx(rtwdev, R_DPD_DBW160_TH1_BE4, B_DPD_DBW160_TH1_5_BE4, 0x1, mac_idx); 503 + rtw89_write32_idx(rtwdev, R_DPD_DBW160_TH1_BE4, B_DPD_DBW160_TH1_6_BE4, 0x1, mac_idx); 504 + rtw89_write32_idx(rtwdev, R_DPD_DBW160_TH1_BE4, B_DPD_DBW160_TH1_7_BE4, 0x1, mac_idx); 505 + /* DPD 20M */ 506 + rtw89_write32_idx(rtwdev, R_DPD_CBW_TH0_BE4, B_DPD_CBW20_TH0_0_BE4, 0x2, mac_idx); 507 + rtw89_write32_idx(rtwdev, R_DPD_CBW_TH0_BE4, B_DPD_CBW20_TH0_1_BE4, 0x2, mac_idx); 508 + rtw89_write32_idx(rtwdev, R_DPD_CBW_TH0_BE4, B_DPD_CBW20_TH0_2_BE4, 0x2, mac_idx); 509 + rtw89_write32_idx(rtwdev, R_DPD_CBW_TH0_BE4, B_DPD_CBW20_TH0_3_BE4, 0x2, mac_idx); 510 + rtw89_write32_idx(rtwdev, R_DPD_CBW_TH0_BE4, B_DPD_CBW20_TH0_4_BE4, 0x2, mac_idx); 511 + rtw89_write32_idx(rtwdev, R_DPD_CBW_TH0_BE4, B_DPD_CBW20_TH0_5_BE4, 0x2, mac_idx); 512 + rtw89_write32_idx(rtwdev, R_DPD_CBW_TH0_BE4, B_DPD_CBW20_TH0_6_BE4, 0x2, mac_idx); 513 + rtw89_write32_idx(rtwdev, R_DPD_CBW_TH1_BE4, B_DPD_CBW20_TH1_7_BE4, 0x2, mac_idx); 514 + /* DPD 40M */ 515 + rtw89_write32_idx(rtwdev, R_DPD_CBW_TH1_BE4, B_DPD_CBW40_TH1_0_BE4, 0x2, mac_idx); 516 + rtw89_write32_idx(rtwdev, R_DPD_CBW_TH1_BE4, B_DPD_CBW40_TH1_1_BE4, 0x2, mac_idx); 517 + rtw89_write32_idx(rtwdev, R_DPD_CBW_TH1_BE4, B_DPD_CBW40_TH1_2_BE4, 0x2, mac_idx); 518 + rtw89_write32_idx(rtwdev, R_DPD_CBW_TH1_BE4, B_DPD_CBW40_TH1_3_BE4, 0x2, mac_idx); 519 + rtw89_write32_idx(rtwdev, R_DPD_CBW_TH1_BE4, B_DPD_CBW40_TH1_4_BE4, 0x2, mac_idx); 520 + rtw89_write32_idx(rtwdev, R_DPD_CBW_TH1_BE4, B_DPD_CBW20_TH0_3_BE4, 0x2, mac_idx); 521 + rtw89_write32_idx(rtwdev, R_DPD_CBW_TH1_BE4, B_DPD_CBW20_TH0_4_BE4, 0x2, mac_idx); 522 + rtw89_write32_idx(rtwdev, R_DPD_CBW_TH1_BE4, B_DPD_CBW20_TH0_5_BE4, 0x2, mac_idx); 523 + /* DPD 80M */ 524 + rtw89_write32_idx(rtwdev, R_DPD_CBW_TH1_BE4, B_DPD_CBW80_TH1_0_BE4, 0x2, mac_idx); 525 + rtw89_write32_idx(rtwdev, R_DPD_CBW_TH2_BE4, B_DPD_CBW80_TH2_1_BE4, 0x2, mac_idx); 526 + rtw89_write32_idx(rtwdev, R_DPD_CBW_TH2_BE4, B_DPD_CBW80_TH2_2_BE4, 0x2, mac_idx); 527 + rtw89_write32_idx(rtwdev, R_DPD_CBW_TH2_BE4, B_DPD_CBW80_TH2_3_BE4, 0x2, mac_idx); 528 + rtw89_write32_idx(rtwdev, R_DPD_CBW_TH2_BE4, B_DPD_CBW80_TH2_4_BE4, 0x2, mac_idx); 529 + rtw89_write32_idx(rtwdev, R_DPD_CBW_TH2_BE4, B_DPD_CBW80_TH2_5_BE4, 0x2, mac_idx); 530 + rtw89_write32_idx(rtwdev, R_DPD_CBW_TH2_BE4, B_DPD_CBW80_TH2_6_BE4, 0x2, mac_idx); 531 + rtw89_write32_idx(rtwdev, R_DPD_CBW_TH2_BE4, B_DPD_CBW80_TH2_7_BE4, 0x2, mac_idx); 532 + /* CIM3K */ 533 + rtw89_write32_idx(rtwdev, R_COMP_CIM3K_BE4, B_COMP_CIM3K_TH2_BE4, 0x2, mac_idx); 534 + } 535 + 536 + static void rtw89_phy_bb_wrap_tx_rfsi_scenario_def(struct rtw89_dev *rtwdev, 537 + enum rtw89_mac_idx mac_idx) 538 + { 539 + rtw89_write32_idx(rtwdev, R_RFSI_CT_DEF_BE4, B_RFSI_CT_ER_BE4, 0x0, mac_idx); 540 + rtw89_write32_idx(rtwdev, R_RFSI_CT_DEF_BE4, B_RFSI_CT_SUBF_BE4, 0x0, mac_idx); 541 + rtw89_write32_idx(rtwdev, R_RFSI_CT_DEF_BE4, B_RFSI_CT_FTM_BE4, 0x0, mac_idx); 542 + rtw89_write32_idx(rtwdev, R_RFSI_CT_DEF_BE4, B_RFSI_CT_SENS_BE4, 0x0, mac_idx); 543 + 544 + rtw89_write32_idx(rtwdev, R_FBTB_CT_DEF_BE4, B_FBTB_CT_DEF_BE, 0x0, mac_idx); 545 + rtw89_write32_idx(rtwdev, R_FBTB_CT_DEF_BE4, B_FBTB_CT_PB_BE4, 0x0, mac_idx); 546 + rtw89_write32_idx(rtwdev, R_FBTB_CT_DEF_BE4, B_FBTB_CT_DL_WO_BE4, 0x0, mac_idx); 547 + rtw89_write32_idx(rtwdev, R_FBTB_CT_DEF_BE4, B_FBTB_CT_DL_BF_BE4, 0x0, mac_idx); 548 + rtw89_write32_idx(rtwdev, R_FBTB_CT_DEF_BE4, B_FBTB_CT_MUMIMO_BE4, 0x0, mac_idx); 549 + rtw89_write32_idx(rtwdev, R_FBTB_CT_DEF_BE4, B_FBTB_CT_FTM_BE4, 0x0, mac_idx); 550 + rtw89_write32_idx(rtwdev, R_FBTB_CT_DEF_BE4, B_FBTB_CT_SENS_BE4, 0x0, mac_idx); 551 + } 552 + 553 + static void rtw89_phy_bb_wrap_tx_rfsi_qam_comp_val(struct rtw89_dev *rtwdev, 554 + enum rtw89_mac_idx mac_idx) 555 + { 556 + rtw89_write32_idx(rtwdev, R_QAM_COMP_TH0_BE4, MASKLWORD, 0x4010, mac_idx); 557 + rtw89_write32_idx(rtwdev, R_QAM_COMP_TH0_BE4, MASKHWORD, 0x4410, mac_idx); 558 + rtw89_write32_idx(rtwdev, R_QAM_COMP_TH1_BE4, MASKLWORD, 0x0, mac_idx); 559 + rtw89_write32_idx(rtwdev, R_QAM_COMP_TH1_BE4, MASKHWORD, 0x0, mac_idx); 560 + rtw89_write32_idx(rtwdev, R_QAM_COMP_TH2_BE4, MASKLWORD, 0x0, mac_idx); 561 + rtw89_write32_idx(rtwdev, R_QAM_COMP_TH2_BE4, MASKHWORD, 0x0, mac_idx); 562 + rtw89_write32_idx(rtwdev, R_QAM_COMP_TH3_BE4, MASKLWORD, 0x0, mac_idx); 563 + rtw89_write32_idx(rtwdev, R_QAM_COMP_TH3_BE4, MASKHWORD, 0x0, mac_idx); 564 + 565 + rtw89_write32_idx(rtwdev, R_QAM_COMP_TH4_BE4, B_QAM_COMP_TH4_L, 0x8, mac_idx); 566 + rtw89_write32_idx(rtwdev, R_QAM_COMP_TH4_BE4, B_QAM_COMP_TH4_M, 0x8, mac_idx); 567 + rtw89_write32_idx(rtwdev, R_QAM_COMP_TH4_BE4, B_QAM_COMP_TH4_H, 0x0, mac_idx); 568 + rtw89_write32_idx(rtwdev, R_QAM_COMP_TH5_BE4, B_QAM_COMP_TH5_L, 0x0, mac_idx); 569 + rtw89_write32_idx(rtwdev, R_QAM_COMP_TH5_BE4, B_QAM_COMP_TH5_M, 0x0, mac_idx); 570 + rtw89_write32_idx(rtwdev, R_QAM_COMP_TH5_BE4, B_QAM_COMP_TH5_H, 0x0, mac_idx); 571 + rtw89_write32_idx(rtwdev, R_QAM_COMP_TH6_BE4, B_QAM_COMP_TH6_L, 0x0, mac_idx); 572 + rtw89_write32_idx(rtwdev, R_QAM_COMP_TH6_BE4, B_QAM_COMP_TH6_M, 0x0, mac_idx); 573 + rtw89_write32_idx(rtwdev, R_QAM_COMP_TH4_BE4, B_QAM_COMP_TH4_2L, 0x8, mac_idx); 574 + rtw89_write32_idx(rtwdev, R_QAM_COMP_TH4_BE4, B_QAM_COMP_TH4_2M, 0x8, mac_idx); 575 + rtw89_write32_idx(rtwdev, R_QAM_COMP_TH4_BE4, B_QAM_COMP_TH4_2H, 0x0, mac_idx); 576 + rtw89_write32_idx(rtwdev, R_QAM_COMP_TH5_BE4, B_QAM_COMP_TH5_2L, 0x0, mac_idx); 577 + rtw89_write32_idx(rtwdev, R_QAM_COMP_TH5_BE4, B_QAM_COMP_TH5_2M, 0x0, mac_idx); 578 + rtw89_write32_idx(rtwdev, R_QAM_COMP_TH5_BE4, B_QAM_COMP_TH5_2H, 0x0, mac_idx); 579 + rtw89_write32_idx(rtwdev, R_QAM_COMP_TH6_BE4, B_QAM_COMP_TH6_2L, 0x0, mac_idx); 580 + rtw89_write32_idx(rtwdev, R_QAM_COMP_TH6_BE4, B_QAM_COMP_TH6_2M, 0x0, mac_idx); 581 + 582 + rtw89_write32_idx(rtwdev, R_OW_VAL_0_BE4, MASKLWORD, 0x4010, mac_idx); 583 + rtw89_write32_idx(rtwdev, R_OW_VAL_0_BE4, MASKHWORD, 0x4010, mac_idx); 584 + rtw89_write32_idx(rtwdev, R_OW_VAL_1_BE4, MASKLWORD, 0x0, mac_idx); 585 + rtw89_write32_idx(rtwdev, R_OW_VAL_1_BE4, MASKHWORD, 0x0, mac_idx); 586 + rtw89_write32_idx(rtwdev, R_OW_VAL_2_BE4, MASKLWORD, 0x0, mac_idx); 587 + rtw89_write32_idx(rtwdev, R_OW_VAL_2_BE4, MASKHWORD, 0x0, mac_idx); 588 + rtw89_write32_idx(rtwdev, R_OW_VAL_3_BE4, MASKLWORD, 0x0, mac_idx); 589 + rtw89_write32_idx(rtwdev, R_OW_VAL_3_BE4, MASKHWORD, 0x0, mac_idx); 590 + } 591 + 592 + static void rtw89_phy_bb_set_oob_dpd_qam_comp_val(struct rtw89_dev *rtwdev, 593 + enum rtw89_mac_idx mac_idx) 594 + { 595 + rtw89_write32_idx(rtwdev, R_OOB_CBW20_BE4, B_OOB_CBW20_CCK0_BE4, 0x0, mac_idx); 596 + rtw89_write32_idx(rtwdev, R_OOB_CBW20_BE4, B_OOB_CBW20_CCK1_BE4, 0x0, mac_idx); 597 + rtw89_write32_idx(rtwdev, R_OOB_CBW20_BE4, B_OOB_CBW20_CCK2_BE4, 0x0, mac_idx); 598 + rtw89_write32_idx(rtwdev, R_OOB_CBW20_BE4, B_OOB_CBW20_CCK3_BE4, 0x0, mac_idx); 599 + rtw89_write32_idx(rtwdev, R_OOB_CBW20_BE4, B_OOB_CBW20_CCK4_BE4, 0x0, mac_idx); 600 + rtw89_write32_idx(rtwdev, R_OOB_CBW20_BE4, B_OOB_CBW20_CCK5_BE4, 0x0, mac_idx); 601 + rtw89_write32_idx(rtwdev, R_OOB_CBW20_BE4, B_OOB_CBW20_CCK6_BE4, 0x0, mac_idx); 602 + rtw89_write32_idx(rtwdev, R_OOB_CBW20_BE4, B_OOB_CBW20_CCK7_BE4, 0x0, mac_idx); 603 + 604 + rtw89_write32_idx(rtwdev, R_OOB_CBW40_BE4, B_OOB_CBW40_CCK0_BE4, 0x0, mac_idx); 605 + rtw89_write32_idx(rtwdev, R_OOB_CBW40_BE4, B_OOB_CBW40_CCK1_BE4, 0x0, mac_idx); 606 + rtw89_write32_idx(rtwdev, R_OOB_CBW40_BE4, B_OOB_CBW40_CCK2_BE4, 0x0, mac_idx); 607 + rtw89_write32_idx(rtwdev, R_OOB_CBW40_BE4, B_OOB_CBW40_CCK3_BE4, 0x0, mac_idx); 608 + rtw89_write32_idx(rtwdev, R_OOB_CBW40_BE4, B_OOB_CBW40_CCK4_BE4, 0x0, mac_idx); 609 + rtw89_write32_idx(rtwdev, R_OOB_CBW40_BE4, B_OOB_CBW40_CCK5_BE4, 0x0, mac_idx); 610 + rtw89_write32_idx(rtwdev, R_OOB_CBW40_BE4, B_OOB_CBW40_CCK6_BE4, 0x0, mac_idx); 611 + rtw89_write32_idx(rtwdev, R_OOB_CBW40_BE4, B_OOB_CBW40_CCK7_BE4, 0x0, mac_idx); 612 + 613 + rtw89_write32_idx(rtwdev, R_OOB_CBW20_BE4, B_OOB_CBW20_TH0_BE4, 0x0, mac_idx); 614 + rtw89_write32_idx(rtwdev, R_OOB_CBW20_BE4, B_OOB_CBW20_TH1_BE4, 0x0, mac_idx); 615 + rtw89_write32_idx(rtwdev, R_OOB_CBW20_BE4, B_OOB_CBW20_TH2_BE4, 0x0, mac_idx); 616 + rtw89_write32_idx(rtwdev, R_OOB_CBW20_BE4, B_OOB_CBW20_TH3_BE4, 0x0, mac_idx); 617 + rtw89_write32_idx(rtwdev, R_OOB_CBW20_BE4, B_OOB_CBW20_TH4_BE4, 0x0, mac_idx); 618 + rtw89_write32_idx(rtwdev, R_OOB_CBW20_BE4, B_OOB_CBW20_TH5_BE4, 0x0, mac_idx); 619 + rtw89_write32_idx(rtwdev, R_OOB_CBW20_BE4, B_OOB_CBW20_TH6_BE4, 0x0, mac_idx); 620 + rtw89_write32_idx(rtwdev, R_OOB_CBW20_BE4, B_OOB_CBW20_TH7_BE4, 0x0, mac_idx); 621 + 622 + rtw89_write32_idx(rtwdev, R_OOB_CBW40_BE4, B_OOB_CBW40_TH0_BE4, 0x0, mac_idx); 623 + rtw89_write32_idx(rtwdev, R_OOB_CBW40_BE4, B_OOB_CBW40_TH1_BE4, 0x0, mac_idx); 624 + rtw89_write32_idx(rtwdev, R_OOB_CBW40_BE4, B_OOB_CBW40_TH2_BE4, 0x0, mac_idx); 625 + rtw89_write32_idx(rtwdev, R_OOB_CBW40_BE4, B_OOB_CBW40_TH3_BE4, 0x0, mac_idx); 626 + rtw89_write32_idx(rtwdev, R_OOB_CBW40_BE4, B_OOB_CBW40_TH4_BE4, 0x0, mac_idx); 627 + rtw89_write32_idx(rtwdev, R_OOB_CBW40_BE4, B_OOB_CBW40_TH5_BE4, 0x0, mac_idx); 628 + rtw89_write32_idx(rtwdev, R_OOB_CBW40_BE4, B_OOB_CBW40_TH6_BE4, 0x0, mac_idx); 629 + rtw89_write32_idx(rtwdev, R_OOB_CBW40_BE4, B_OOB_CBW40_TH7_BE4, 0x0, mac_idx); 630 + 631 + rtw89_write32_idx(rtwdev, R_OOB_CBW80_BE4, B_OOB_CBW80_TH0_BE4, 0x0, mac_idx); 632 + rtw89_write32_idx(rtwdev, R_OOB_CBW80_BE4, B_OOB_CBW80_TH1_BE4, 0x0, mac_idx); 633 + rtw89_write32_idx(rtwdev, R_OOB_CBW80_BE4, B_OOB_CBW80_TH2_BE4, 0x0, mac_idx); 634 + rtw89_write32_idx(rtwdev, R_OOB_CBW80_BE4, B_OOB_CBW80_TH3_BE4, 0x0, mac_idx); 635 + rtw89_write32_idx(rtwdev, R_OOB_CBW80_BE4, B_OOB_CBW80_TH4_BE4, 0x0, mac_idx); 636 + rtw89_write32_idx(rtwdev, R_OOB_CBW80_BE4, B_OOB_CBW80_TH5_BE4, 0x0, mac_idx); 637 + rtw89_write32_idx(rtwdev, R_OOB_CBW80_BE4, B_OOB_CBW80_TH6_BE4, 0x0, mac_idx); 638 + rtw89_write32_idx(rtwdev, R_OOB_CBW80_BE4, B_OOB_CBW80_TH7_BE4, 0x0, mac_idx); 639 + 640 + rtw89_write32_idx(rtwdev, R_OOB_CBW40_BE4, B_OOB_CBW20_OW0_BE4, 0x0, mac_idx); 641 + rtw89_write32_idx(rtwdev, R_OOB_CBW40_BE4, B_OOB_CBW20_OW1_BE4, 0x0, mac_idx); 642 + rtw89_write32_idx(rtwdev, R_OOB_CBW40_BE4, B_OOB_CBW20_OW2_BE4, 0x0, mac_idx); 643 + rtw89_write32_idx(rtwdev, R_OOB_CBW40_BE4, B_OOB_CBW20_OW3_BE4, 0x0, mac_idx); 644 + rtw89_write32_idx(rtwdev, R_OOB_CBW40_BE4, B_OOB_CBW20_OW4_BE4, 0x0, mac_idx); 645 + rtw89_write32_idx(rtwdev, R_OOB_CBW40_BE4, B_OOB_CBW20_OW5_BE4, 0x0, mac_idx); 646 + rtw89_write32_idx(rtwdev, R_OOB_CBW40_BE4, B_OOB_CBW20_OW6_BE4, 0x0, mac_idx); 647 + rtw89_write32_idx(rtwdev, R_OOB_CBW40_BE4, B_OOB_CBW20_OW7_BE4, 0x0, mac_idx); 648 + 649 + rtw89_write32_idx(rtwdev, R_OOB_CBW40_BE4, B_OOB_CBW40_OW0_BE4, 0x0, mac_idx); 650 + rtw89_write32_idx(rtwdev, R_OOB_CBW40_BE4, B_OOB_CBW40_OW1_BE4, 0x0, mac_idx); 651 + rtw89_write32_idx(rtwdev, R_OOB_CBW40_BE4, B_OOB_CBW40_OW2_BE4, 0x0, mac_idx); 652 + rtw89_write32_idx(rtwdev, R_OOB_CBW40_BE4, B_OOB_CBW40_OW3_BE4, 0x0, mac_idx); 653 + rtw89_write32_idx(rtwdev, R_OOB_CBW40_BE4, B_OOB_CBW40_OW4_BE4, 0x0, mac_idx); 654 + rtw89_write32_idx(rtwdev, R_OOB_CBW40_BE4, B_OOB_CBW40_OW5_BE4, 0x0, mac_idx); 655 + rtw89_write32_idx(rtwdev, R_OOB_CBW40_BE4, B_OOB_CBW40_OW6_BE4, 0x0, mac_idx); 656 + rtw89_write32_idx(rtwdev, R_OOB_CBW40_BE4, B_OOB_CBW40_OW7_BE4, 0x0, mac_idx); 657 + 658 + rtw89_write32_idx(rtwdev, R_OOB_CBW80_BE4, B_OOB_CBW80_OW0_BE4, 0x0, mac_idx); 659 + rtw89_write32_idx(rtwdev, R_OOB_CBW80_BE4, B_OOB_CBW80_OW1_BE4, 0x0, mac_idx); 660 + rtw89_write32_idx(rtwdev, R_OOB_CBW80_BE4, B_OOB_CBW80_OW2_BE4, 0x0, mac_idx); 661 + rtw89_write32_idx(rtwdev, R_OOB_CBW80_BE4, B_OOB_CBW80_OW3_BE4, 0x0, mac_idx); 662 + rtw89_write32_idx(rtwdev, R_OOB_CBW80_BE4, B_OOB_CBW80_OW4_BE4, 0x0, mac_idx); 663 + rtw89_write32_idx(rtwdev, R_OOB_CBW80_BE4, B_OOB_CBW80_OW5_BE4, 0x0, mac_idx); 664 + rtw89_write32_idx(rtwdev, R_OOB_CBW80_BE4, B_OOB_CBW80_OW6_BE4, 0x0, mac_idx); 665 + rtw89_write32_idx(rtwdev, R_OOB_CBW80_BE4, B_OOB_CBW80_OW7_BE4, 0x0, mac_idx); 666 + } 667 + 668 + static void rtw89_phy_bb_set_mdpd_qam_comp_val(struct rtw89_dev *rtwdev, 669 + enum rtw89_mac_idx mac_idx) 670 + { 671 + rtw89_write32_idx(rtwdev, R_DPD_CBW160_BE4, B_DPD_CBW160_TH0_BE4, 0x0, mac_idx); 672 + rtw89_write32_idx(rtwdev, R_DPD_CBW160_BE4, B_DPD_CBW160_TH1_BE4, 0x0, mac_idx); 673 + rtw89_write32_idx(rtwdev, R_DPD_CBW160_BE4, B_DPD_CBW160_TH2_BE4, 0x0, mac_idx); 674 + rtw89_write32_idx(rtwdev, R_DPD_CBW160_BE4, B_DPD_CBW160_TH3_BE4, 0x0, mac_idx); 675 + rtw89_write32_idx(rtwdev, R_DPD_CBW160_BE4, B_DPD_CBW160_TH4_BE4, 0x0, mac_idx); 676 + rtw89_write32_idx(rtwdev, R_DPD_CBW160_BE4, B_DPD_CBW160_TH5_BE4, 0x0, mac_idx); 677 + rtw89_write32_idx(rtwdev, R_DPD_CBW160_BE4, B_DPD_CBW160_TH6_BE4, 0x0, mac_idx); 678 + rtw89_write32_idx(rtwdev, R_DPD_CBW160_BE4, B_DPD_CBW160_TH7_BE4, 0x0, mac_idx); 679 + 680 + rtw89_write32_idx(rtwdev, R_DPD_CBW160_BE4, B_DPD_CBW160_OW0_BE4, 0x0, mac_idx); 681 + rtw89_write32_idx(rtwdev, R_DPD_CBW160_BE4, B_DPD_CBW160_OW1_BE4, 0x0, mac_idx); 682 + rtw89_write32_idx(rtwdev, R_DPD_CBW160_BE4, B_DPD_CBW160_OW2_BE4, 0x0, mac_idx); 683 + rtw89_write32_idx(rtwdev, R_DPD_CBW160_BE4, B_DPD_CBW160_OW3_BE4, 0x0, mac_idx); 684 + rtw89_write32_idx(rtwdev, R_DPD_CBW160_BE4, B_DPD_CBW160_OW4_BE4, 0x0, mac_idx); 685 + rtw89_write32_idx(rtwdev, R_DPD_CBW160_BE4, B_DPD_CBW160_OW5_BE4, 0x0, mac_idx); 686 + rtw89_write32_idx(rtwdev, R_DPD_CBW160_BE4, B_DPD_CBW160_OW6_BE4, 0x0, mac_idx); 687 + rtw89_write32_idx(rtwdev, R_DPD_CBW160_BE4, B_DPD_CBW160_OW7_BE4, 0x0, mac_idx); 688 + } 689 + 690 + static void rtw89_phy_bb_set_cim3k_val(struct rtw89_dev *rtwdev, 691 + enum rtw89_mac_idx mac_idx) 692 + { 693 + rtw89_write32_idx(rtwdev, R_COMP_CIM3K_BE4, B_COMP_CIM3K_TH_BE4, 0x0, mac_idx); 694 + rtw89_write32_idx(rtwdev, R_COMP_CIM3K_BE4, B_COMP_CIM3K_OW_BE4, 0x0, mac_idx); 695 + rtw89_write32_idx(rtwdev, R_COMP_CIM3K_BE4, B_COMP_CIM3K_NONBE_BE4, 0x1, mac_idx); 696 + rtw89_write32_idx(rtwdev, R_COMP_CIM3K_BE4, B_COMP_CIM3K_BANDEDGE_BE4, 0x1, mac_idx); 697 + } 698 + 699 + static void rtw89_phy_bb_wrap_tx_rfsi_ctrl_init(struct rtw89_dev *rtwdev, 700 + enum rtw89_mac_idx mac_idx) 701 + { 702 + enum rtw89_phy_idx phy_idx = mac_idx != RTW89_MAC_0 ? RTW89_PHY_1 : RTW89_PHY_0; 703 + enum rtw89_core_chip_id chip_id = rtwdev->chip->chip_id; 704 + const struct rtw89_chan *chan; 705 + 706 + if (chip_id != RTL8922D) 707 + return; 708 + 709 + rtw89_phy_bb_wrap_tx_rfsi_qam_comp_th_init(rtwdev, mac_idx); 710 + rtw89_phy_bb_wrap_tx_rfsi_scenario_def(rtwdev, mac_idx); 711 + rtw89_phy_bb_wrap_tx_rfsi_qam_comp_val(rtwdev, mac_idx); 712 + rtw89_phy_bb_set_oob_dpd_qam_comp_val(rtwdev, mac_idx); 713 + rtw89_phy_bb_set_mdpd_qam_comp_val(rtwdev, mac_idx); 714 + rtw89_phy_bb_set_cim3k_val(rtwdev, mac_idx); 715 + 716 + rtw89_phy_bb_wrap_set_rfsi_ct_opt(rtwdev, phy_idx); 717 + 718 + chan = rtw89_mgnt_chan_get(rtwdev, phy_idx); 719 + if (chan) 720 + rtw89_phy_bb_wrap_set_rfsi_bandedge_ch(rtwdev, chan, phy_idx); 721 + } 722 + 561 723 static void rtw89_phy_bb_wrap_ul_pwr(struct rtw89_dev *rtwdev) 562 724 { 563 725 enum rtw89_core_chip_id chip_id = rtwdev->chip->chip_id; ··· 904 414 static void __rtw89_phy_bb_wrap_init_be(struct rtw89_dev *rtwdev, 905 415 enum rtw89_mac_idx mac_idx) 906 416 { 907 - rtw89_phy_bb_wrap_pwr_by_macid_init(rtwdev); 908 417 rtw89_phy_bb_wrap_tx_path_by_macid_init(rtwdev); 909 - rtw89_phy_bb_wrap_listen_path_en_init(rtwdev); 418 + rtw89_phy_bb_wrap_pwr_by_macid_init(rtwdev); 419 + rtw89_phy_bb_wrap_tpu_set_all(rtwdev, mac_idx); 420 + rtw89_phy_bb_wrap_tx_rfsi_ctrl_init(rtwdev, mac_idx); 910 421 rtw89_phy_bb_wrap_force_cr_init(rtwdev, mac_idx); 911 422 rtw89_phy_bb_wrap_ftm_init(rtwdev, mac_idx); 912 - rtw89_phy_bb_wrap_tpu_set_all(rtwdev, mac_idx); 423 + rtw89_phy_bb_wrap_listen_path_en_init(rtwdev); 913 424 rtw89_phy_bb_wrap_ul_pwr(rtwdev); 914 425 } 915 426 ··· 930 439 rtw89_phy_set_phy_regs(rtwdev, R_CHINFO_ELM_SRC, B_CHINFO_SRC, 0x0); 931 440 rtw89_phy_set_phy_regs(rtwdev, R_CHINFO_TYPE_SCAL, B_CHINFO_TYPE, 0x3); 932 441 rtw89_phy_set_phy_regs(rtwdev, R_CHINFO_TYPE_SCAL, B_CHINFO_SCAL, 0x0); 442 + } 443 + 444 + static void rtw89_phy_ch_info_init_be_v1(struct rtw89_dev *rtwdev) 445 + { 446 + rtw89_phy_write32_mask(rtwdev, R_CHINFO_SEG_BE4, B_CHINFO_SEG_LEN_BE4, 0); 447 + rtw89_phy_set_phy_regs(rtwdev, R_CHINFO_OPT_BE4, B_CHINFO_OPT_BE4, 0x3); 448 + rtw89_phy_set_phy_regs(rtwdev, R_CHINFO_NX_BE4, B_CHINFO_NX_BE4, 0x669); 449 + rtw89_phy_set_phy_regs(rtwdev, R_CHINFO_ALG_BE4, B_CHINFO_ALG_BE4, 0); 933 450 } 934 451 935 452 struct rtw89_byr_spec_ent_be { ··· 1503 1004 1504 1005 const struct rtw89_phy_gen_def rtw89_phy_gen_be = { 1505 1006 .cr_base = 0x20000, 1007 + .physt_bmp_start = R_PHY_STS_BITMAP_ADDR_START, 1008 + .physt_bmp_eht = R_PHY_STS_BITMAP_EHT, 1506 1009 .ccx = &rtw89_ccx_regs_be, 1507 1010 .physts = &rtw89_physts_regs_be, 1508 1011 .cfo = &rtw89_cfo_regs_be, 1012 + .bb_wrap = &rtw89_bb_wrap_regs_be, 1509 1013 .phy0_phy1_offset = rtw89_phy0_phy1_offset_be, 1510 1014 .config_bb_gain = rtw89_phy_config_bb_gain_be, 1511 1015 .preinit_rf_nctl = rtw89_phy_preinit_rf_nctl_be, ··· 1521 1019 .set_txpwr_limit_ru = rtw89_phy_set_txpwr_limit_ru_be, 1522 1020 }; 1523 1021 EXPORT_SYMBOL(rtw89_phy_gen_be); 1022 + 1023 + const struct rtw89_phy_gen_def rtw89_phy_gen_be_v1 = { 1024 + .cr_base = 0x0, 1025 + .physt_bmp_start = R_PHY_STS_BITMAP_ADDR_START_BE4, 1026 + .physt_bmp_eht = R_PHY_STS_BITMAP_EHT_BE4, 1027 + .ccx = &rtw89_ccx_regs_be_v1, 1028 + .physts = &rtw89_physts_regs_be_v1, 1029 + .cfo = &rtw89_cfo_regs_be_v1, 1030 + .bb_wrap = &rtw89_bb_wrap_regs_be_v1, 1031 + .phy0_phy1_offset = rtw89_phy0_phy1_offset_be_v1, 1032 + .config_bb_gain = rtw89_phy_config_bb_gain_be, 1033 + .preinit_rf_nctl = rtw89_phy_preinit_rf_nctl_be_v1, 1034 + .bb_wrap_init = rtw89_phy_bb_wrap_init_be, 1035 + .ch_info_init = rtw89_phy_ch_info_init_be_v1, 1036 + 1037 + .set_txpwr_byrate = rtw89_phy_set_txpwr_byrate_be, 1038 + .set_txpwr_offset = rtw89_phy_set_txpwr_offset_be, 1039 + .set_txpwr_limit = rtw89_phy_set_txpwr_limit_be, 1040 + .set_txpwr_limit_ru = rtw89_phy_set_txpwr_limit_ru_be, 1041 + }; 1042 + EXPORT_SYMBOL(rtw89_phy_gen_be_v1);
+2
drivers/net/wireless/realtek/rtw89/ps.c
··· 189 189 190 190 if (RTW89_CHK_FW_FEATURE(LPS_CH_INFO, &rtwdev->fw)) 191 191 rtw89_fw_h2c_lps_ch_info(rtwdev, rtwvif); 192 + else if (RTW89_CHK_FW_FEATURE(LPS_ML_INFO_V1, &rtwdev->fw)) 193 + rtw89_fw_h2c_lps_ml_cmn_info_v1(rtwdev, rtwvif); 192 194 else 193 195 rtw89_fw_h2c_lps_ml_cmn_info(rtwdev, rtwvif); 194 196
+364 -4
drivers/net/wireless/realtek/rtw89/reg.h
··· 4315 4315 4316 4316 #define R_BE_SECURE_BOOT_MALLOC_INFO 0x0184 4317 4317 4318 + #define R_BE_FWS0IMR 0x0190 4319 + #define B_BE_FS_HALT_H2C_INT_EN BIT(31) 4320 + #define B_BE_FS_FSM_HIOE_TO_EVENT_INT_EN BIT(30) 4321 + #define B_BE_FS_HCI_SUS_INT_EN BIT(29) 4322 + #define B_BE_FS_HCI_RES_INT_EN BIT(28) 4323 + #define B_BE_FS_HCI_RESET_INT_EN BIT(27) 4324 + #define B_BE_FS_BT_SB1_INT_EN BIT(26) 4325 + #define B_BE_FS_ACT2RECOVERY_INT_EN BIT(25) 4326 + #define B_BE_FS_GEN1GEN2_SWITCH_INT_EN BIT(24) 4327 + #define B_BE_FS_USB_LPMRSM_INT_EN BIT(22) 4328 + #define B_BE_FS_USB_LPMINT_INT_EN BIT(21) 4329 + #define B_BE_FS_PWMERR_INT_EN BIT(20) 4330 + #define B_BE_FS_PDNINT_EN BIT(19) 4331 + #define B_BE_FS_SPSA_OCP_INT_EN BIT(18) 4332 + #define B_BE_FS_SPSD_OCP_INT_EN BIT(17) 4333 + #define B_BE_FS_BT_SB0_INT_EN BIT(16) 4334 + #define B_BE_FS_GPIOF_INT_EN BIT(15) 4335 + #define B_BE_FS_GPIOE_INT_EN BIT(14) 4336 + #define B_BE_FS_GPIOD_INT_EN BIT(13) 4337 + #define B_BE_FS_GPIOC_INT_EN BIT(12) 4338 + #define B_BE_FS_GPIOB_INT_EN BIT(11) 4339 + #define B_BE_FS_GPIOA_INT_EN BIT(10) 4340 + #define B_BE_FS_GPIO9_INT_EN BIT(9) 4341 + #define B_BE_FS_GPIO8_INT_EN BIT(8) 4342 + #define B_BE_FS_GPIO7_INT_EN BIT(7) 4343 + #define B_BE_FS_GPIO6_INT_EN BIT(6) 4344 + #define B_BE_FS_GPIO5_INT_EN BIT(5) 4345 + #define B_BE_FS_GPIO4_INT_EN BIT(4) 4346 + #define B_BE_FS_GPIO3_INT_EN BIT(3) 4347 + #define B_BE_FS_GPIO2_INT_EN BIT(2) 4348 + #define B_BE_FS_GPIO1_INT_EN BIT(1) 4349 + #define B_BE_FS_GPIO0_INT_EN BIT(0) 4350 + 4351 + #define R_BE_FWS0ISR 0x0194 4352 + #define B_BE_FS_HALT_H2C_INT BIT(31) 4353 + #define B_BE_FS_FSM_HIOE_TO_EVENT_INT BIT(30) 4354 + #define B_BE_FS_HCI_SUS_INT BIT(29) 4355 + #define B_BE_FS_HCI_RES_INT BIT(28) 4356 + #define B_BE_FS_HCI_RESET_INT BIT(27) 4357 + #define B_BE_FS_BT_SB1_INT BIT(26) 4358 + #define B_BE_FS_ACT2RECOVERY_INT BIT(25) 4359 + #define B_BE_FS_GEN1GEN2_SWITCH_INT BIT(24) 4360 + #define B_BE_FS_USB_LPMRSM_INT BIT(22) 4361 + #define B_BE_FS_USB_LPMINT_INT BIT(21) 4362 + #define B_BE_FS_PWMERR_INT BIT(20) 4363 + #define B_BE_FS_PDNINT BIT(19) 4364 + #define B_BE_FS_SPSA_OCP_INT BIT(18) 4365 + #define B_BE_FS_SPSD_OCP_INT BIT(17) 4366 + #define B_BE_FS_BT_SB0_INT BIT(16) 4367 + #define B_BE_FS_GPIOF_INT BIT(15) 4368 + #define B_BE_FS_GPIOE_INT BIT(14) 4369 + #define B_BE_FS_GPIOD_INT BIT(13) 4370 + #define B_BE_FS_GPIOC_INT BIT(12) 4371 + #define B_BE_FS_GPIOB_INT BIT(11) 4372 + #define B_BE_FS_GPIOA_INT BIT(10) 4373 + #define B_BE_FS_GPIO9_INT BIT(9) 4374 + #define B_BE_FS_GPIO8_INT BIT(8) 4375 + #define B_BE_FS_GPIO7_INT BIT(7) 4376 + #define B_BE_FS_GPIO6_INT BIT(6) 4377 + #define B_BE_FS_GPIO5_INT BIT(5) 4378 + #define B_BE_FS_GPIO4_INT BIT(4) 4379 + #define B_BE_FS_GPIO3_INT BIT(3) 4380 + #define B_BE_FS_GPIO2_INT BIT(2) 4381 + #define B_BE_FS_GPIO1_INT BIT(1) 4382 + #define B_BE_FS_GPIO0_INT BIT(0) 4383 + 4318 4384 #define R_BE_FWS1IMR 0x0198 4319 4385 #define B_BE_FS_RPWM_INT_EN_V1 BIT(24) 4320 4386 #define B_BE_PCIE_HOTRST_EN BIT(22) ··· 4959 4893 4960 4894 #define R_BE_SER_L1_DBG_CNT_7 0x845C 4961 4895 #define B_BE_SER_L1_DBG_2_MASK GENMASK(31, 0) 4896 + 4897 + #define R_BE_FW_TRIGGER_IDCT_ISR 0x8508 4898 + #define B_BE_DMAC_FW_ERR_IDCT_IMR BIT(31) 4899 + #define B_BE_DMAC_FW_TRIG_IDCT BIT(0) 4962 4900 4963 4901 #define R_BE_DMAC_ERR_IMR 0x8520 4964 4902 #define B_BE_DMAC_NOTX_ERR_INT_EN BIT(21) ··· 6436 6366 #define B_BE_PTA_GNT_BT1_BB_SWCTRL BIT(0) 6437 6367 6438 6368 #define R_BE_PWR_MACID_PATH_BASE 0x0E500 6369 + #define R_BE_PWR_MACID_PATH_BASE_V1 0x1C000 6439 6370 #define R_BE_PWR_MACID_LMT_BASE 0x0ED00 6371 + #define R_BE_PWR_MACID_LMT_BASE_V1 0x1C800 6440 6372 6441 6373 #define R_BE_CMAC_FUNC_EN 0x10000 6442 6374 #define R_BE_CMAC_FUNC_EN_C1 0x14000 ··· 6500 6428 #define BE_WMAC_RFMOD_80M 2 6501 6429 #define BE_WMAC_RFMOD_160M 3 6502 6430 #define BE_WMAC_RFMOD_320M 4 6431 + 6432 + #define R_BE_GID_POSITION0 0x10070 6433 + #define R_BE_GID_POSITION0_C1 0x14070 6434 + #define R_BE_GID_POSITION1 0x10074 6435 + #define R_BE_GID_POSITION1_C1 0x14074 6436 + #define R_BE_GID_POSITION2 0x10078 6437 + #define R_BE_GID_POSITION2_C1 0x14078 6438 + #define R_BE_GID_POSITION3 0x1007C 6439 + #define R_BE_GID_POSITION3_C1 0x1407C 6440 + #define R_BE_GID_POSITION_EN0 0x10080 6441 + #define R_BE_GID_POSITION_EN0_C1 0x14080 6442 + #define R_BE_GID_POSITION_EN1 0x10084 6443 + #define R_BE_GID_POSITION_EN1_C1 0x14084 6503 6444 6504 6445 #define R_BE_TX_SUB_BAND_VALUE 0x10088 6505 6446 #define R_BE_TX_SUB_BAND_VALUE_C1 0x14088 ··· 8328 8243 8329 8244 #define R_BE_PWR_FTM 0x11B00 8330 8245 #define R_BE_PWR_FTM_SS 0x11B04 8246 + #define B_BE_PWR_BY_RATE_DBW_ON GENMASK(27, 26) 8331 8247 8332 8248 #define R_BE_PWR_BY_RATE 0x11E00 8333 8249 #define R_BE_PWR_BY_RATE_MAX 0x11FA8 ··· 8637 8551 #define B_UPD_P0_EN BIT(31) 8638 8552 #define R_EMLSR 0x0044 8639 8553 #define B_EMLSR_PARM GENMASK(27, 12) 8554 + #define R_CHK_LPS_STAT_BE4 0x3007C 8640 8555 #define R_CHK_LPS_STAT 0x0058 8641 8556 #define B_CHK_LPS_STAT BIT(0) 8642 8557 #define R_SPOOF_CG 0x00B4 ··· 8711 8624 #define R_MAC_PIN_SEL 0x0734 8712 8625 #define B_CH_IDX_SEG0 GENMASK(23, 16) 8713 8626 #define R_PLCP_HISTOGRAM 0x0738 8627 + #define R_PLCP_HISTOGRAM_BE_V1 0x20738 8714 8628 #define B_STS_PARSING_TIME GENMASK(19, 16) 8715 8629 #define B_STS_DIS_TRIG_BY_FAIL BIT(3) 8716 8630 #define B_STS_DIS_TRIG_BY_BRK BIT(2) 8717 8631 #define R_PHY_STS_BITMAP_ADDR_START R_PHY_STS_BITMAP_SEARCH_FAIL 8632 + #define R_PHY_STS_BITMAP_ADDR_START_BE4 0x2073C 8718 8633 #define B_PHY_STS_BITMAP_ADDR_MASK GENMASK(6, 2) 8719 8634 #define R_PHY_STS_BITMAP_SEARCH_FAIL 0x073C 8720 8635 #define B_PHY_STS_BITMAP_MSK_52A 0x337cff3f ··· 8735 8646 #define R_PHY_STS_BITMAP_VHT 0x0770 8736 8647 #define R_PHY_STS_BITMAP_HE 0x0774 8737 8648 #define R_PHY_STS_BITMAP_EHT 0x0788 8649 + #define R_PHY_STS_BITMAP_EHT_BE4 0x20788 8738 8650 #define R_EDCCA_RPTREG_SEL_BE 0x078C 8739 8651 #define B_EDCCA_RPTREG_SEL_BE_MSK GENMASK(22, 20) 8740 8652 #define R_PMAC_GNT 0x0980 ··· 8766 8676 #define R_DBCC_80P80_SEL_EVM_RPT 0x0A10 8767 8677 #define B_DBCC_80P80_SEL_EVM_RPT_EN BIT(0) 8768 8678 #define R_CCX 0x0C00 8679 + #define R_CCX_BE4 0x20C00 8769 8680 #define B_CCX_EDCCA_OPT_MSK GENMASK(6, 4) 8770 8681 #define B_CCX_EDCCA_OPT_MSK_V1 GENMASK(7, 4) 8771 8682 #define B_MEASUREMENT_TRIG_MSK BIT(2) ··· 8795 8704 #define R_FAHM 0x0C1C 8796 8705 #define B_RXTD_CKEN BIT(2) 8797 8706 #define R_IFS_COUNTER 0x0C28 8707 + #define R_IFS_COUNTER_BE4 0x20C28 8798 8708 #define B_IFS_CLM_PERIOD_MSK GENMASK(31, 16) 8799 8709 #define B_IFS_CLM_COUNTER_UNIT_MSK GENMASK(15, 14) 8800 8710 #define B_IFS_COUNTER_CLR_MSK BIT(13) 8801 8711 #define B_IFS_COLLECT_EN BIT(12) 8802 8712 #define R_IFS_T1 0x0C2C 8713 + #define R_IFS_T1_BE4 0x20C2C 8803 8714 #define B_IFS_T1_TH_HIGH_MSK GENMASK(31, 16) 8804 8715 #define B_IFS_T1_EN_MSK BIT(15) 8805 8716 #define B_IFS_T1_TH_LOW_MSK GENMASK(14, 0) 8806 8717 #define R_IFS_T2 0x0C30 8718 + #define R_IFS_T2_BE4 0x20C30 8807 8719 #define B_IFS_T2_TH_HIGH_MSK GENMASK(31, 16) 8808 8720 #define B_IFS_T2_EN_MSK BIT(15) 8809 8721 #define B_IFS_T2_TH_LOW_MSK GENMASK(14, 0) 8810 8722 #define R_IFS_T3 0x0C34 8723 + #define R_IFS_T3_BE4 0x20C34 8811 8724 #define B_IFS_T3_TH_HIGH_MSK GENMASK(31, 16) 8812 8725 #define B_IFS_T3_EN_MSK BIT(15) 8813 8726 #define B_IFS_T3_TH_LOW_MSK GENMASK(14, 0) 8814 8727 #define R_IFS_T4 0x0C38 8728 + #define R_IFS_T4_BE4 0x20C38 8815 8729 #define B_IFS_T4_TH_HIGH_MSK GENMASK(31, 16) 8816 8730 #define B_IFS_T4_EN_MSK BIT(15) 8817 8731 #define B_IFS_T4_TH_LOW_MSK GENMASK(14, 0) 8818 8732 #define R_PD_CTRL 0x0C3C 8819 8733 #define B_PD_HIT_DIS BIT(9) 8820 8734 #define R_IOQ_IQK_DPK 0x0C60 8735 + #define R_IOQ_IQK_DPK_BE4 0x20C60 8821 8736 #define B_IOQ_IQK_DPK_CLKEN GENMASK(1, 0) 8822 8737 #define B_IOQ_IQK_DPK_EN BIT(1) 8738 + #define B_IOQ_IQK_DPK_RST BIT(0) 8823 8739 #define R_GNT_BT_WGT_EN 0x0C6C 8824 8740 #define B_GNT_BT_WGT_EN BIT(21) 8825 8741 #define R_IQK_DPK_RST 0x0C6C 8742 + #define R_IQK_DPK_RST_BE4 0x20C6C 8826 8743 #define R_IQK_DPK_RST_C1 0x1C6C 8827 8744 #define B_IQK_DPK_RST BIT(0) 8828 8745 #define R_TX_COLLISION_T2R_ST 0x0C70 ··· 8948 8849 #define B_NHM_READY_MSK BIT(16) 8949 8850 #define R_IFS_CLM_TX_CNT 0x1ACC 8950 8851 #define R_IFS_CLM_TX_CNT_V1 0x0ECC 8852 + #define R_IFS_CLM_TX_CNT_BE4 0x20ECC 8951 8853 #define B_IFS_CLM_EDCCA_EXCLUDE_CCA_FA_MSK GENMASK(31, 16) 8952 8854 #define B_IFS_CLM_TX_CNT_MSK GENMASK(15, 0) 8953 8855 #define R_IFS_CLM_CCA 0x1AD0 8954 8856 #define R_IFS_CLM_CCA_V1 0x0ED0 8857 + #define R_IFS_CLM_CCA_BE4 0x20ED0 8955 8858 #define B_IFS_CLM_OFDMCCA_EXCLUDE_FA_MSK GENMASK(31, 16) 8956 8859 #define B_IFS_CLM_CCKCCA_EXCLUDE_FA_MSK GENMASK(15, 0) 8957 8860 #define R_IFS_CLM_FA 0x1AD4 8958 8861 #define R_IFS_CLM_FA_V1 0x0ED4 8862 + #define R_IFS_CLM_FA_BE4 0x20ED4 8959 8863 #define B_IFS_CLM_OFDM_FA_MSK GENMASK(31, 16) 8960 8864 #define B_IFS_CLM_CCK_FA_MSK GENMASK(15, 0) 8961 8865 #define R_IFS_HIS 0x1AD8 ··· 9615 9513 #define B_S0_DACKQ7_K GENMASK(15, 8) 9616 9514 #define R_S0_DACKQ8 0x5E98 9617 9515 #define B_S0_DACKQ8_K GENMASK(15, 8) 9618 - #define R_DCFO_WEIGHT_V1 0x6244 9619 - #define B_DCFO_WEIGHT_MSK_V1 GENMASK(31, 28) 9516 + #define R_DCFO_WEIGHT_BE 0x6244 9517 + #define R_DCFO_WEIGHT_BE_V1 0x24808 9518 + #define B_DCFO_WEIGHT_MSK_BE GENMASK(31, 28) 9620 9519 #define R_DAC_CLK 0x625C 9621 9520 #define B_DAC_CLK GENMASK(31, 30) 9622 - #define R_DCFO_OPT_V1 0x6260 9623 - #define B_DCFO_OPT_EN_V1 BIT(17) 9521 + #define R_DCFO_OPT_BE 0x6260 9522 + #define R_DCFO_OPT_BE_V1 0x24824 9523 + #define B_DCFO_OPT_EN_BE BIT(17) 9624 9524 #define R_TXFCTR 0x627C 9625 9525 #define B_TXFCTR_THD GENMASK(19, 10) 9626 9526 #define R_TXSCALE 0x6284 ··· 10132 10028 #define R_GAIN_MAP1 0xE54C 10133 10029 #define B_GAIN_MAP1_EN BIT(0) 10134 10030 #define R_GOTX_IQKDPK_C0 0xE464 10031 + #define R_GOTX_IQKDPK_C0_BE4 0x2E464 10135 10032 #define R_GOTX_IQKDPK_C1 0xE564 10033 + #define R_GOTX_IQKDPK_C1_BE4 0x2E564 10136 10034 #define B_GOTX_IQKDPK GENMASK(28, 27) 10137 10035 #define R_IQK_DPK_PRST 0xE4AC 10036 + #define R_IQK_DPK_PRST_BE4 0x2E4AC 10138 10037 #define R_IQK_DPK_PRST_C1 0xE5AC 10038 + #define R_IQK_DPK_PRST_C1_BE4 0x2E5AC 10139 10039 #define B_IQK_DPK_PRST BIT(27) 10140 10040 #define R_TXPWR_RSTA 0xE60C 10141 10041 #define B_TXPWR_RSTA BIT(16) ··· 10165 10057 #define B_TXAGC_CCK_REF_DBM_P1 GENMASK(17, 9) 10166 10058 #define R_TSSI_K_P1 0xE7A0 10167 10059 #define B_TSSI_K_OFDM_P1 GENMASK(29, 20) 10060 + 10061 + #define R_COMP_CIM3K_BE4 0x11998 10062 + #define B_COMP_CIM3K_OW_BE4 BIT(1) 10063 + #define B_COMP_CIM3K_TH_BE4 BIT(2) 10064 + #define B_COMP_CIM3K_TH2_BE4 GENMASK(5, 3) 10065 + #define B_COMP_CIM3K_TXPWR_EN_BE4 BIT(6) 10066 + #define B_COMP_CIM3K_NONBE_BE4 BIT(7) 10067 + #define B_COMP_CIM3K_BANDEDGE_BE4 BIT(8) 10068 + #define R_DPD_CBW160_BE4 0x119B4 10069 + #define B_DPD_CBW160_TH0_BE4 BIT(0) 10070 + #define B_DPD_CBW160_TH1_BE4 BIT(1) 10071 + #define B_DPD_CBW160_TH2_BE4 BIT(2) 10072 + #define B_DPD_CBW160_TH3_BE4 BIT(3) 10073 + #define B_DPD_CBW160_TH4_BE4 BIT(4) 10074 + #define B_DPD_CBW160_TH5_BE4 BIT(5) 10075 + #define B_DPD_CBW160_TH6_BE4 BIT(6) 10076 + #define B_DPD_CBW160_TH7_BE4 BIT(7) 10077 + #define B_DPD_CBW160_OW0_BE4 BIT(8) 10078 + #define B_DPD_CBW160_OW1_BE4 BIT(9) 10079 + #define B_DPD_CBW160_OW2_BE4 BIT(10) 10080 + #define B_DPD_CBW160_OW3_BE4 BIT(11) 10081 + #define B_DPD_CBW160_OW4_BE4 BIT(12) 10082 + #define B_DPD_CBW160_OW5_BE4 BIT(13) 10083 + #define B_DPD_CBW160_OW6_BE4 BIT(14) 10084 + #define B_DPD_CBW160_OW7_BE4 BIT(15) 10085 + #define R_OOB_CBW20_BE4 0x119B4 10086 + #define B_OOB_CBW20_CCK0_BE4 BIT(16) 10087 + #define B_OOB_CBW20_CCK1_BE4 BIT(17) 10088 + #define B_OOB_CBW20_CCK2_BE4 BIT(18) 10089 + #define B_OOB_CBW20_CCK3_BE4 BIT(19) 10090 + #define B_OOB_CBW20_CCK4_BE4 BIT(20) 10091 + #define B_OOB_CBW20_CCK5_BE4 BIT(21) 10092 + #define B_OOB_CBW20_CCK6_BE4 BIT(22) 10093 + #define B_OOB_CBW20_CCK7_BE4 BIT(23) 10094 + #define B_OOB_CBW20_TH0_BE4 BIT(24) 10095 + #define B_OOB_CBW20_TH1_BE4 BIT(25) 10096 + #define B_OOB_CBW20_TH2_BE4 BIT(26) 10097 + #define B_OOB_CBW20_TH3_BE4 BIT(27) 10098 + #define B_OOB_CBW20_TH4_BE4 BIT(28) 10099 + #define B_OOB_CBW20_TH5_BE4 BIT(29) 10100 + #define B_OOB_CBW20_TH6_BE4 BIT(30) 10101 + #define B_OOB_CBW20_TH7_BE4 BIT(31) 10102 + #define R_OOB_CBW40_BE4 0x119B8 10103 + #define B_OOB_CBW20_OW0_BE4 BIT(0) 10104 + #define B_OOB_CBW20_OW1_BE4 BIT(1) 10105 + #define B_OOB_CBW20_OW2_BE4 BIT(2) 10106 + #define B_OOB_CBW20_OW3_BE4 BIT(3) 10107 + #define B_OOB_CBW20_OW4_BE4 BIT(4) 10108 + #define B_OOB_CBW20_OW5_BE4 BIT(5) 10109 + #define B_OOB_CBW20_OW6_BE4 BIT(6) 10110 + #define B_OOB_CBW20_OW7_BE4 BIT(7) 10111 + #define B_OOB_CBW40_CCK0_BE4 BIT(8) 10112 + #define B_OOB_CBW40_CCK1_BE4 BIT(9) 10113 + #define B_OOB_CBW40_CCK2_BE4 BIT(10) 10114 + #define B_OOB_CBW40_CCK3_BE4 BIT(11) 10115 + #define B_OOB_CBW40_CCK4_BE4 BIT(12) 10116 + #define B_OOB_CBW40_CCK5_BE4 BIT(13) 10117 + #define B_OOB_CBW40_CCK6_BE4 BIT(14) 10118 + #define B_OOB_CBW40_CCK7_BE4 BIT(15) 10119 + #define B_OOB_CBW40_TH0_BE4 BIT(16) 10120 + #define B_OOB_CBW40_TH1_BE4 BIT(17) 10121 + #define B_OOB_CBW40_TH2_BE4 BIT(18) 10122 + #define B_OOB_CBW40_TH3_BE4 BIT(19) 10123 + #define B_OOB_CBW40_TH4_BE4 BIT(20) 10124 + #define B_OOB_CBW40_TH5_BE4 BIT(21) 10125 + #define B_OOB_CBW40_TH6_BE4 BIT(22) 10126 + #define B_OOB_CBW40_TH7_BE4 BIT(23) 10127 + #define B_OOB_CBW40_OW0_BE4 BIT(24) 10128 + #define B_OOB_CBW40_OW1_BE4 BIT(25) 10129 + #define B_OOB_CBW40_OW2_BE4 BIT(26) 10130 + #define B_OOB_CBW40_OW3_BE4 BIT(27) 10131 + #define B_OOB_CBW40_OW4_BE4 BIT(28) 10132 + #define B_OOB_CBW40_OW5_BE4 BIT(29) 10133 + #define B_OOB_CBW40_OW6_BE4 BIT(30) 10134 + #define B_OOB_CBW40_OW7_BE4 BIT(31) 10135 + #define R_OOB_CBW80_BE4 0x119BC 10136 + #define B_OOB_CBW80_TH0_BE4 BIT(0) 10137 + #define B_OOB_CBW80_TH1_BE4 BIT(1) 10138 + #define B_OOB_CBW80_TH2_BE4 BIT(2) 10139 + #define B_OOB_CBW80_TH3_BE4 BIT(3) 10140 + #define B_OOB_CBW80_TH4_BE4 BIT(4) 10141 + #define B_OOB_CBW80_TH5_BE4 BIT(5) 10142 + #define B_OOB_CBW80_TH6_BE4 BIT(6) 10143 + #define B_OOB_CBW80_TH7_BE4 BIT(7) 10144 + #define B_OOB_CBW80_OW0_BE4 BIT(8) 10145 + #define B_OOB_CBW80_OW1_BE4 BIT(9) 10146 + #define B_OOB_CBW80_OW2_BE4 BIT(10) 10147 + #define B_OOB_CBW80_OW3_BE4 BIT(11) 10148 + #define B_OOB_CBW80_OW4_BE4 BIT(12) 10149 + #define B_OOB_CBW80_OW5_BE4 BIT(13) 10150 + #define B_OOB_CBW80_OW6_BE4 BIT(14) 10151 + #define B_OOB_CBW80_OW7_BE4 BIT(15) 10152 + #define R_DPD_DBW160_TH0_BE4 0x119BC 10153 + #define B_DPD_DBW160_TH0_0_BE4 GENMASK(18, 16) 10154 + #define B_DPD_DBW160_TH0_1_BE4 GENMASK(21, 19) 10155 + #define B_DPD_DBW160_TH0_2_BE4 GENMASK(24, 22) 10156 + #define B_DPD_DBW160_TH0_3_BE4 GENMASK(27, 25) 10157 + #define B_DPD_DBW160_TH0_4_BE4 GENMASK(30, 28) 10158 + #define R_DPD_DBW160_TH1_BE4 0x119C0 10159 + #define B_DPD_DBW160_TH1_5_BE4 GENMASK(2, 0) 10160 + #define B_DPD_DBW160_TH1_6_BE4 GENMASK(5, 3) 10161 + #define B_DPD_DBW160_TH1_7_BE4 GENMASK(8, 6) 10162 + #define R_DPD_CBW_TH0_BE4 0x119C0 10163 + #define B_DPD_CBW20_TH0_0_BE4 GENMASK(11, 9) 10164 + #define B_DPD_CBW20_TH0_1_BE4 GENMASK(14, 12) 10165 + #define B_DPD_CBW20_TH0_2_BE4 GENMASK(17, 15) 10166 + #define B_DPD_CBW20_TH0_3_BE4 GENMASK(20, 18) 10167 + #define B_DPD_CBW20_TH0_4_BE4 GENMASK(23, 21) 10168 + #define B_DPD_CBW20_TH0_5_BE4 GENMASK(26, 24) 10169 + #define B_DPD_CBW20_TH0_6_BE4 GENMASK(29, 27) 10170 + #define R_DPD_CBW_TH1_BE4 0x119C4 10171 + #define B_DPD_CBW20_TH1_7_BE4 GENMASK(2, 0) 10172 + #define B_DPD_CBW40_TH1_0_BE4 GENMASK(5, 3) 10173 + #define B_DPD_CBW40_TH1_1_BE4 GENMASK(8, 6) 10174 + #define B_DPD_CBW40_TH1_2_BE4 GENMASK(11, 9) 10175 + #define B_DPD_CBW40_TH1_3_BE4 GENMASK(14, 12) 10176 + #define B_DPD_CBW40_TH1_4_BE4 GENMASK(17, 15) 10177 + #define B_DPD_CBW40_TH1_5_BE4 GENMASK(20, 18) 10178 + #define B_DPD_CBW40_TH1_6_BE4 GENMASK(23, 21) 10179 + #define B_DPD_CBW40_TH1_7_BE4 GENMASK(26, 24) 10180 + #define B_DPD_CBW80_TH1_0_BE4 GENMASK(29, 27) 10181 + #define R_DPD_CBW_TH2_BE4 0x119C8 10182 + #define B_DPD_CBW80_TH2_1_BE4 GENMASK(2, 0) 10183 + #define B_DPD_CBW80_TH2_2_BE4 GENMASK(5, 3) 10184 + #define B_DPD_CBW80_TH2_3_BE4 GENMASK(8, 6) 10185 + #define B_DPD_CBW80_TH2_4_BE4 GENMASK(11, 9) 10186 + #define B_DPD_CBW80_TH2_5_BE4 GENMASK(14, 12) 10187 + #define B_DPD_CBW80_TH2_6_BE4 GENMASK(17, 15) 10188 + #define B_DPD_CBW80_TH2_7_BE4 GENMASK(20, 18) 10189 + #define R_QAM_TH0_BE4 0x119E4 10190 + #define B_QAM_TH0_0_BE4 GENMASK(18, 16) 10191 + #define B_QAM_TH0_1_BE4 GENMASK(21, 19) 10192 + #define B_QAM_TH0_2_BE4 GENMASK(24, 22) 10193 + #define B_QAM_TH0_3_BE4 GENMASK(27, 25) 10194 + #define B_QAM_TH0_4_BE4 GENMASK(30, 28) 10195 + #define R_QAM_TH1_BE4 0x119E8 10196 + #define B_QAM_TH1_0_BE4 GENMASK(2, 0) 10197 + #define B_QAM_TH1_1_BE4 GENMASK(5, 3) 10198 + #define B_QAM_TH1_2_BE4 GENMASK(8, 6) 10199 + #define B_QAM_TH1_3_BE4 GENMASK(11, 9) 10200 + #define B_QAM_TH1_4_BE4 GENMASK(14, 12) 10201 + #define B_QAM_TH1_5_BE4 GENMASK(17, 15) 10202 + #define B_QAM_TH1_6_BE4 GENMASK(20, 18) 10203 + #define B_QAM_TH1_7_BE4 GENMASK(23, 21) 10204 + #define B_QAM_TH1_8_BE4 GENMASK(26, 24) 10205 + #define B_QAM_TH1_9_BE4 GENMASK(29, 27) 10206 + #define R_QAM_TH2_BE4 0x119EC 10207 + #define B_QAM_TH2_0_BE4 GENMASK(2, 0) 10208 + #define B_QAM_TH2_1_BE4 GENMASK(5, 3) 10209 + #define B_QAM_TH2_2_BE4 GENMASK(8, 6) 10210 + #define B_QAM_TH2_3_BE4 GENMASK(11, 9) 10211 + #define B_QAM_TH2_4_BE4 GENMASK(14, 12) 10212 + #define B_QAM_TH2_5_BE4 GENMASK(17, 15) 10213 + #define B_QAM_TH2_6_BE4 GENMASK(20, 18) 10214 + #define B_QAM_TH2_7_BE4 GENMASK(23, 21) 10215 + #define B_QAM_TH2_8_BE4 GENMASK(26, 24) 10216 + #define R_RFSI_CT_DEF_BE4 0x119F0 10217 + #define B_RFSI_CT_ER_BE4 GENMASK(18, 15) 10218 + #define B_RFSI_CT_SUBF_BE4 GENMASK(22, 19) 10219 + #define B_RFSI_CT_FTM_BE4 GENMASK(26, 23) 10220 + #define B_RFSI_CT_SENS_BE4 GENMASK(30, 27) 10221 + #define R_FBTB_CT_DEF_BE4 0x119F4 10222 + #define B_FBTB_CT_DEF_BE GENMASK(3, 0) 10223 + #define B_FBTB_CT_PB_BE4 GENMASK(7, 4) 10224 + #define B_FBTB_CT_DL_WO_BE4 GENMASK(11, 8) 10225 + #define B_FBTB_CT_DL_BF_BE4 GENMASK(15, 12) 10226 + #define B_FBTB_CT_MUMIMO_BE4 GENMASK(19, 16) 10227 + #define B_FBTB_CT_FTM_BE4 GENMASK(23, 20) 10228 + #define B_FBTB_CT_SENS_BE4 GENMASK(27, 24) 10229 + #define R_RFSI_CT_OPT_0_BE4 0x11A94 10230 + #define R_RFSI_CT_OPT_8_BE4 0x11A98 10231 + #define R_QAM_COMP_TH0_BE4 0x11A9C 10232 + #define R_QAM_COMP_TH1_BE4 0x11AA0 10233 + #define R_QAM_COMP_TH2_BE4 0x11AA4 10234 + #define R_QAM_COMP_TH3_BE4 0x11AA8 10235 + #define R_QAM_COMP_TH4_BE4 0x11ABC 10236 + #define B_QAM_COMP_TH4_L GENMASK(4, 0) 10237 + #define B_QAM_COMP_TH4_M GENMASK(14, 10) 10238 + #define B_QAM_COMP_TH4_H GENMASK(24, 20) 10239 + #define B_QAM_COMP_TH4_2L GENMASK(9, 5) 10240 + #define B_QAM_COMP_TH4_2M GENMASK(19, 15) 10241 + #define B_QAM_COMP_TH4_2H GENMASK(29, 25) 10242 + #define R_QAM_COMP_TH5_BE4 0x11AC0 10243 + #define B_QAM_COMP_TH5_L GENMASK(4, 0) 10244 + #define B_QAM_COMP_TH5_M GENMASK(14, 10) 10245 + #define B_QAM_COMP_TH5_H GENMASK(24, 20) 10246 + #define B_QAM_COMP_TH5_2L GENMASK(9, 5) 10247 + #define B_QAM_COMP_TH5_2M GENMASK(19, 15) 10248 + #define B_QAM_COMP_TH5_2H GENMASK(29, 25) 10249 + #define R_QAM_COMP_TH6_BE4 0x11AC4 10250 + #define B_QAM_COMP_TH6_L GENMASK(4, 0) 10251 + #define B_QAM_COMP_TH6_M GENMASK(14, 10) 10252 + #define B_QAM_COMP_TH6_2L GENMASK(9, 5) 10253 + #define B_QAM_COMP_TH6_2M GENMASK(19, 15) 10254 + #define R_OW_VAL_0_BE4 0x11AAC 10255 + #define R_OW_VAL_1_BE4 0x11AB0 10256 + #define R_OW_VAL_2_BE4 0x11AB4 10257 + #define R_OW_VAL_3_BE4 0x11AB8 10258 + #define R_BANDEDGE_DBWX_BE4 0x11ACC 10259 + #define B_BANDEDGE_DBW20_BE4 BIT(29) 10260 + #define B_BANDEDGE_DBW40_BE4 BIT(30) 10261 + #define B_BANDEDGE_DBW80_BE4 BIT(31) 10262 + #define R_BANDEDGE_DBWY_BE4 0x11AD0 10263 + #define B_BANDEDGE_DBW160_BE4 BIT(0) 10264 + 10265 + #define R_CHINFO_SEG_BE4 0x200B4 10266 + #define B_CHINFO_SEG_LEN_BE4 GENMASK(12, 10) 10267 + #define R_STS_HDR2_PARSING_BE4 0x2070C 10268 + #define B_STS_HDR2_PARSING_BE4 BIT(10) 10269 + #define R_SW_SI_WDATA_BE4 0x20370 10270 + #define B_SW_SI_DATA_PATH_BE4 GENMASK(31, 28) 10271 + #define B_SW_SI_DATA_ADR_BE4 GENMASK(27, 20) 10272 + #define B_SW_SI_DATA_DAT_BE4 GENMASK(19, 0) 10273 + #define R_SW_SI_READ_ADDR_BE4 0x20378 10274 + #define B_SW_SI_READ_ADDR_BE4 GENMASK(10, 0) 10275 + #define R_IFS_T1_AVG_BE4 0x20EDC 10276 + #define B_IFS_T1_AVG_BE4 GENMASK(15, 0) 10277 + #define B_IFS_T2_AVG_BE4 GENMASK(31, 16) 10278 + #define R_IFS_T3_AVG_BE4 0x20EE0 10279 + #define B_IFS_T3_AVG_BE4 GENMASK(15, 0) 10280 + #define B_IFS_T4_AVG_BE4 GENMASK(31, 16) 10281 + #define R_IFS_T1_CLM_BE4 0x20EE4 10282 + #define B_IFS_T1_CLM_BE4 GENMASK(15, 0) 10283 + #define B_IFS_T2_CLM_BE4 GENMASK(31, 16) 10284 + #define R_IFS_T3_CLM_BE4 0x20EE8 10285 + #define B_IFS_T3_CLM_BE4 GENMASK(15, 0) 10286 + #define B_IFS_T4_CLM_BE4 GENMASK(31, 16) 10287 + #define R_IFS_TOTAL_BE4 0x20EEC 10288 + #define B_IFS_TOTAL_BE4 GENMASK(15, 0) 10289 + #define B_IFS_CNT_DONE_BE4 BIT(16) 10290 + #define R_IFS_T1_HIS_BE4 0x20F50 10291 + #define B_IFS_T1_HIS_BE4 GENMASK(15, 0) 10292 + #define B_IFS_T2_HIS_BE4 GENMASK(31, 16) 10293 + #define R_IFS_T3_HIS_BE4 0x20F54 10294 + #define B_IFS_T3_HIS_BE4 GENMASK(15, 0) 10295 + #define B_IFS_T4_HIS_BE4 GENMASK(31, 16) 10296 + 10297 + #define R_TX_CFR_MANUAL_EN_BE4 0x2483C 10298 + #define B_TX_CFR_MANUAL_EN_BE4_M BIT(30) 10299 + 10300 + #define R_CHINFO_OPT_BE4 0x267C8 10301 + #define B_CHINFO_OPT_BE4 GENMASK(14, 13) 10302 + #define R_CHINFO_NX_BE4 0x267D0 10303 + #define B_CHINFO_NX_BE4 GENMASK(16, 6) 10304 + #define R_CHINFO_ALG_BE4 0x267C8 10305 + #define B_CHINFO_ALG_BE4 GENMASK(31, 30) 10306 + 10307 + #define R_SW_SI_DATA_BE4 0x2CF4C 10308 + #define B_SW_SI_READ_DATA_BE4 GENMASK(19, 0) 10309 + #define B_SW_SI_W_BUSY_BE4 BIT(24) 10310 + #define B_SW_SI_R_BUSY_BE4 BIT(25) 10311 + #define B_SW_SI_READ_DATA_DONE_BE4 BIT(26) 10168 10312 10169 10313 /* WiFi CPU local domain */ 10170 10314 #define R_AX_WDT_CTRL 0x0040
+10 -10
drivers/net/wireless/realtek/rtw89/regd.c
··· 38 38 COUNTRY_REGD("MX", RTW89_MEXICO, RTW89_MEXICO, RTW89_FCC, 0x0), 39 39 COUNTRY_REGD("NI", RTW89_FCC, RTW89_FCC, RTW89_NA, 0x0), 40 40 COUNTRY_REGD("PA", RTW89_FCC, RTW89_FCC, RTW89_NA, 0x0), 41 - COUNTRY_REGD("PY", RTW89_FCC, RTW89_FCC, RTW89_NA, 0x0), 41 + COUNTRY_REGD("PY", RTW89_FCC, RTW89_FCC, RTW89_FCC, 0x0), 42 42 COUNTRY_REGD("PE", RTW89_FCC, RTW89_FCC, RTW89_FCC, 0x0), 43 43 COUNTRY_REGD("US", RTW89_FCC, RTW89_FCC, RTW89_FCC, 0x1), 44 44 COUNTRY_REGD("UY", RTW89_FCC, RTW89_FCC, RTW89_NA, 0x0), ··· 95 95 COUNTRY_REGD("MK", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0), 96 96 COUNTRY_REGD("MA", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x0), 97 97 COUNTRY_REGD("MZ", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x0), 98 - COUNTRY_REGD("NA", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0), 98 + COUNTRY_REGD("NA", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x0), 99 99 COUNTRY_REGD("NG", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x0), 100 100 COUNTRY_REGD("OM", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x0), 101 101 COUNTRY_REGD("QA", RTW89_QATAR, RTW89_QATAR, RTW89_QATAR, 0x0), ··· 111 111 COUNTRY_REGD("AE", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x0), 112 112 COUNTRY_REGD("YE", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0), 113 113 COUNTRY_REGD("ZW", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x0), 114 - COUNTRY_REGD("BD", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0), 114 + COUNTRY_REGD("BD", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x0), 115 115 COUNTRY_REGD("KH", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0), 116 116 COUNTRY_REGD("CN", RTW89_CN, RTW89_CN, RTW89_CN, 0x0), 117 117 COUNTRY_REGD("HK", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x0), 118 118 COUNTRY_REGD("IN", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0), 119 - COUNTRY_REGD("ID", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0), 119 + COUNTRY_REGD("ID", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x0), 120 120 COUNTRY_REGD("KR", RTW89_KCC, RTW89_KCC, RTW89_KCC, 0x1), 121 121 COUNTRY_REGD("MY", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x0), 122 122 COUNTRY_REGD("PK", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x0), ··· 125 125 COUNTRY_REGD("LK", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0), 126 126 COUNTRY_REGD("TW", RTW89_FCC, RTW89_FCC, RTW89_ETSI, 0x0), 127 127 COUNTRY_REGD("TH", RTW89_THAILAND, RTW89_THAILAND, RTW89_THAILAND, 0x0), 128 - COUNTRY_REGD("VN", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0), 128 + COUNTRY_REGD("VN", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x0), 129 129 COUNTRY_REGD("AU", RTW89_ACMA, RTW89_ACMA, RTW89_ACMA, 0x0), 130 130 COUNTRY_REGD("NZ", RTW89_ACMA, RTW89_ACMA, RTW89_ACMA, 0x0), 131 131 COUNTRY_REGD("PG", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x0), ··· 134 134 COUNTRY_REGD("JM", RTW89_FCC, RTW89_FCC, RTW89_FCC, 0x0), 135 135 COUNTRY_REGD("AN", RTW89_FCC, RTW89_FCC, RTW89_FCC, 0x0), 136 136 COUNTRY_REGD("TT", RTW89_FCC, RTW89_FCC, RTW89_NA, 0x0), 137 - COUNTRY_REGD("TN", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0), 137 + COUNTRY_REGD("TN", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x0), 138 138 COUNTRY_REGD("AF", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0), 139 139 COUNTRY_REGD("DZ", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x0), 140 140 COUNTRY_REGD("AS", RTW89_FCC, RTW89_FCC, RTW89_NA, 0x0), ··· 187 187 COUNTRY_REGD("GM", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x0), 188 188 COUNTRY_REGD("GE", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x0), 189 189 COUNTRY_REGD("GI", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x0), 190 - COUNTRY_REGD("GL", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0), 190 + COUNTRY_REGD("GL", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x0), 191 191 COUNTRY_REGD("GD", RTW89_FCC, RTW89_FCC, RTW89_FCC, 0x0), 192 - COUNTRY_REGD("GP", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0), 192 + COUNTRY_REGD("GP", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x0), 193 193 COUNTRY_REGD("GU", RTW89_FCC, RTW89_FCC, RTW89_FCC, 0x0), 194 194 COUNTRY_REGD("GG", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0), 195 195 COUNTRY_REGD("GN", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x0), ··· 214 214 COUNTRY_REGD("MQ", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0), 215 215 COUNTRY_REGD("MR", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0), 216 216 COUNTRY_REGD("MU", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x0), 217 - COUNTRY_REGD("YT", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0), 217 + COUNTRY_REGD("YT", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x0), 218 218 COUNTRY_REGD("FM", RTW89_FCC, RTW89_FCC, RTW89_FCC, 0x0), 219 219 COUNTRY_REGD("MD", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x0), 220 220 COUNTRY_REGD("MN", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x0), ··· 260 260 COUNTRY_REGD("UZ", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x0), 261 261 COUNTRY_REGD("VU", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0), 262 262 COUNTRY_REGD("WF", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0), 263 - COUNTRY_REGD("EH", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0), 263 + COUNTRY_REGD("EH", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x0), 264 264 COUNTRY_REGD("ZM", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0), 265 265 COUNTRY_REGD("CU", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0), 266 266 COUNTRY_REGD("IR", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0),
+1
drivers/net/wireless/realtek/rtw89/rtw8851b.c
··· 2530 2530 .cfg_txrx_path = rtw8851b_bb_cfg_txrx_path, 2531 2531 .set_txpwr_ul_tb_offset = rtw8851b_set_txpwr_ul_tb_offset, 2532 2532 .digital_pwr_comp = NULL, 2533 + .calc_rx_gain_normal = NULL, 2533 2534 .pwr_on_func = rtw8851b_pwr_on_func, 2534 2535 .pwr_off_func = rtw8851b_pwr_off_func, 2535 2536 .query_rxdesc = rtw89_core_query_rxdesc,
+1
drivers/net/wireless/realtek/rtw89/rtw8852a.c
··· 2224 2224 .cfg_txrx_path = NULL, 2225 2225 .set_txpwr_ul_tb_offset = rtw8852a_set_txpwr_ul_tb_offset, 2226 2226 .digital_pwr_comp = NULL, 2227 + .calc_rx_gain_normal = NULL, 2227 2228 .pwr_on_func = NULL, 2228 2229 .pwr_off_func = NULL, 2229 2230 .query_rxdesc = rtw89_core_query_rxdesc,
+1
drivers/net/wireless/realtek/rtw89/rtw8852b.c
··· 857 857 .cfg_txrx_path = rtw8852bx_bb_cfg_txrx_path, 858 858 .set_txpwr_ul_tb_offset = rtw8852bx_set_txpwr_ul_tb_offset, 859 859 .digital_pwr_comp = NULL, 860 + .calc_rx_gain_normal = NULL, 860 861 .pwr_on_func = rtw8852b_pwr_on_func, 861 862 .pwr_off_func = rtw8852b_pwr_off_func, 862 863 .query_rxdesc = rtw89_core_query_rxdesc,
+1
drivers/net/wireless/realtek/rtw89/rtw8852bt.c
··· 703 703 .cfg_txrx_path = rtw8852bx_bb_cfg_txrx_path, 704 704 .set_txpwr_ul_tb_offset = rtw8852bx_set_txpwr_ul_tb_offset, 705 705 .digital_pwr_comp = NULL, 706 + .calc_rx_gain_normal = NULL, 706 707 .pwr_on_func = rtw8852bt_pwr_on_func, 707 708 .pwr_off_func = rtw8852bt_pwr_off_func, 708 709 .query_rxdesc = rtw89_core_query_rxdesc,
+1
drivers/net/wireless/realtek/rtw89/rtw8852c.c
··· 3065 3065 .cfg_txrx_path = rtw8852c_bb_cfg_txrx_path, 3066 3066 .set_txpwr_ul_tb_offset = rtw8852c_set_txpwr_ul_tb_offset, 3067 3067 .digital_pwr_comp = NULL, 3068 + .calc_rx_gain_normal = NULL, 3068 3069 .pwr_on_func = rtw8852c_pwr_on_func, 3069 3070 .pwr_off_func = rtw8852c_pwr_off_func, 3070 3071 .query_rxdesc = rtw89_core_query_rxdesc,
+2
drivers/net/wireless/realtek/rtw89/rtw8852cu.c
··· 46 46 .driver_info = (kernel_ulong_t)&rtw89_8852cu_info }, 47 47 { USB_DEVICE_AND_INTERFACE_INFO(0x0db0, 0x991d, 0xff, 0xff, 0xff), 48 48 .driver_info = (kernel_ulong_t)&rtw89_8852cu_info }, 49 + { USB_DEVICE_AND_INTERFACE_INFO(0x28de, 0x2432, 0xff, 0xff, 0xff), 50 + .driver_info = (kernel_ulong_t)&rtw89_8852cu_info }, 49 51 { USB_DEVICE_AND_INTERFACE_INFO(0x35b2, 0x0502, 0xff, 0xff, 0xff), 50 52 .driver_info = (kernel_ulong_t)&rtw89_8852cu_info }, 51 53 { USB_DEVICE_AND_INTERFACE_INFO(0x35bc, 0x0101, 0xff, 0xff, 0xff),
+48 -10
drivers/net/wireless/realtek/rtw89/rtw8922a.c
··· 1768 1768 } 1769 1769 1770 1770 #define DIGITAL_PWR_COMP_REG_NUM 22 1771 + static const u32 rtw8922a_digital_pwr_comp_2g_s0_val[][DIGITAL_PWR_COMP_REG_NUM] = { 1772 + {0x012C0064, 0x04B00258, 0x00432710, 0x019000A7, 0x06400320, 1773 + 0x0D05091D, 0x14D50FA0, 0x00000000, 0x01010000, 0x00000101, 1774 + 0x01010101, 0x02020201, 0x02010000, 0x03030202, 0x00000303, 1775 + 0x03020101, 0x06060504, 0x01010000, 0x06050403, 0x01000606, 1776 + 0x05040202, 0x07070706}, 1777 + {0x012C0064, 0x04B00258, 0x00432710, 0x019000A7, 0x06400320, 1778 + 0x0D05091D, 0x14D50FA0, 0x00000000, 0x01010100, 0x00000101, 1779 + 0x01000000, 0x01010101, 0x01010000, 0x02020202, 0x00000404, 1780 + 0x03020101, 0x04040303, 0x02010000, 0x03030303, 0x00000505, 1781 + 0x03030201, 0x05050303}, 1782 + }; 1783 + 1784 + static const u32 rtw8922a_digital_pwr_comp_2g_s1_val[][DIGITAL_PWR_COMP_REG_NUM] = { 1785 + {0x012C0064, 0x04B00258, 0x00432710, 0x019000A7, 0x06400320, 1786 + 0x0D05091D, 0x14D50FA0, 0x01010000, 0x01010101, 0x00000101, 1787 + 0x01010100, 0x01010101, 0x01010000, 0x02020202, 0x01000202, 1788 + 0x02020101, 0x03030202, 0x02010000, 0x05040403, 0x01000606, 1789 + 0x05040302, 0x07070605}, 1790 + {0x012C0064, 0x04B00258, 0x00432710, 0x019000A7, 0x06400320, 1791 + 0x0D05091D, 0x14D50FA0, 0x00000000, 0x01010100, 0x00000101, 1792 + 0x01010000, 0x02020201, 0x02010100, 0x03030202, 0x01000404, 1793 + 0x04030201, 0x05050404, 0x01010100, 0x04030303, 0x01000505, 1794 + 0x03030101, 0x05050404}, 1795 + }; 1796 + 1771 1797 static const u32 rtw8922a_digital_pwr_comp_val[][DIGITAL_PWR_COMP_REG_NUM] = { 1772 1798 {0x012C0096, 0x044C02BC, 0x00322710, 0x015E0096, 0x03C8028A, 1773 1799 0x0BB80708, 0x17701194, 0x02020100, 0x03030303, 0x01000303, ··· 1808 1782 }; 1809 1783 1810 1784 static void rtw8922a_set_digital_pwr_comp(struct rtw89_dev *rtwdev, 1811 - bool enable, u8 nss, 1785 + u8 band, u8 nss, 1812 1786 enum rtw89_rf_path path) 1813 1787 { 1814 1788 static const u32 ltpc_t0[2] = {R_BE_LTPC_T0_PATH0, R_BE_LTPC_T0_PATH1}; ··· 1816 1790 u32 addr, val; 1817 1791 u32 i; 1818 1792 1819 - if (nss == 1) 1820 - digital_pwr_comp = rtw8922a_digital_pwr_comp_val[0]; 1821 - else 1822 - digital_pwr_comp = rtw8922a_digital_pwr_comp_val[1]; 1793 + if (nss == 1) { 1794 + if (band == RTW89_BAND_2G) 1795 + digital_pwr_comp = path == RF_PATH_A ? 1796 + rtw8922a_digital_pwr_comp_2g_s0_val[0] : 1797 + rtw8922a_digital_pwr_comp_2g_s1_val[0]; 1798 + else 1799 + digital_pwr_comp = rtw8922a_digital_pwr_comp_val[0]; 1800 + } else { 1801 + if (band == RTW89_BAND_2G) 1802 + digital_pwr_comp = path == RF_PATH_A ? 1803 + rtw8922a_digital_pwr_comp_2g_s0_val[1] : 1804 + rtw8922a_digital_pwr_comp_2g_s1_val[1]; 1805 + else 1806 + digital_pwr_comp = rtw8922a_digital_pwr_comp_val[1]; 1807 + } 1823 1808 1824 1809 addr = ltpc_t0[path]; 1825 1810 for (i = 0; i < DIGITAL_PWR_COMP_REG_NUM; i++, addr += 4) { 1826 - val = enable ? digital_pwr_comp[i] : 0; 1811 + val = digital_pwr_comp[i]; 1827 1812 rtw89_phy_write32(rtwdev, addr, val); 1828 1813 } 1829 1814 } ··· 1843 1806 enum rtw89_phy_idx phy_idx) 1844 1807 { 1845 1808 const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_CHANCTX_0); 1846 - bool enable = chan->band_type != RTW89_BAND_2G; 1809 + u8 band = chan->band_type; 1847 1810 u8 path; 1848 1811 1849 1812 if (rtwdev->mlo_dbcc_mode == MLO_1_PLUS_1_1RF) { ··· 1851 1814 path = RF_PATH_A; 1852 1815 else 1853 1816 path = RF_PATH_B; 1854 - rtw8922a_set_digital_pwr_comp(rtwdev, enable, 1, path); 1817 + rtw8922a_set_digital_pwr_comp(rtwdev, band, 1, path); 1855 1818 } else { 1856 - rtw8922a_set_digital_pwr_comp(rtwdev, enable, 2, RF_PATH_A); 1857 - rtw8922a_set_digital_pwr_comp(rtwdev, enable, 2, RF_PATH_B); 1819 + rtw8922a_set_digital_pwr_comp(rtwdev, band, 2, RF_PATH_A); 1820 + rtw8922a_set_digital_pwr_comp(rtwdev, band, 2, RF_PATH_B); 1858 1821 } 1859 1822 } 1860 1823 ··· 2875 2838 .cfg_txrx_path = rtw8922a_bb_cfg_txrx_path, 2876 2839 .set_txpwr_ul_tb_offset = NULL, 2877 2840 .digital_pwr_comp = rtw8922a_digital_pwr_comp, 2841 + .calc_rx_gain_normal = NULL, 2878 2842 .pwr_on_func = rtw8922a_pwr_on_func, 2879 2843 .pwr_off_func = rtw8922a_pwr_off_func, 2880 2844 .query_rxdesc = rtw89_core_query_rxdesc_v2,
+3 -3
drivers/net/wireless/realtek/rtw89/wow.c
··· 1267 1267 enum rtw89_core_chip_id chip_id = rtwdev->chip->chip_id; 1268 1268 const struct rtw89_chip_info *chip = rtwdev->chip; 1269 1269 bool include_bb = !!chip->bbmcu_nr; 1270 - bool disable_intr_for_dlfw = false; 1270 + bool disable_intr_for_dlfw = true; 1271 1271 struct ieee80211_sta *wow_sta; 1272 1272 struct rtw89_sta_link *rtwsta_link = NULL; 1273 1273 struct rtw89_sta *rtwsta; 1274 1274 bool is_conn = true; 1275 1275 int ret; 1276 1276 1277 - if (chip_id == RTL8852C || chip_id == RTL8922A) 1278 - disable_intr_for_dlfw = true; 1277 + if (chip->chip_gen == RTW89_CHIP_AX && chip_id != RTL8852C) 1278 + disable_intr_for_dlfw = false; 1279 1279 1280 1280 wow_sta = ieee80211_find_sta(wow_vif, wow_vif->cfg.ap_addr); 1281 1281 if (wow_sta) {
+12 -1
include/linux/ieee80211-eht.h
··· 558 558 559 559 #define IEEE80211_MLC_PRIO_ACCESS_PRES_AP_MLD_MAC_ADDR 0x0010 560 560 561 + #define IEEE80211_EML_CTRL_EMLSR_MODE BIT(0) 562 + #define IEEE80211_EML_CTRL_EMLMR_MODE BIT(1) 563 + #define IEEE80211_EML_CTRL_EMLSR_PARAM_UPDATE BIT(2) 564 + #define IEEE80211_EML_CTRL_INDEV_COEX_ACT BIT(3) 565 + 566 + #define IEEE80211_EML_EMLSR_PAD_DELAY 0x07 567 + #define IEEE80211_EML_EMLSR_TRANS_DELAY 0x38 568 + 569 + #define IEEE80211_EML_EMLMR_RX_MCS_MAP 0xf0 570 + #define IEEE80211_EML_EMLMR_TX_MCS_MAP 0x0f 571 + 561 572 /* no fixed fields in PRIO_ACCESS */ 562 573 563 574 /** ··· 1190 1179 _data + ieee80211_mle_common_size(_data),\ 1191 1180 _len - ieee80211_mle_common_size(_data)) 1192 1181 1193 - #endif /* LINUX_IEEE80211_H */ 1182 + #endif /* LINUX_IEEE80211_EHT_H */
+1 -1
include/linux/ieee80211-s1g.h
··· 572 572 } 573 573 } 574 574 575 - #endif /* LINUX_IEEE80211_H */ 575 + #endif /* LINUX_IEEE80211_S1G_H */
+220
include/linux/ieee80211-uhr.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0-only */ 2 + /* 3 + * IEEE 802.11 UHR definitions 4 + * 5 + * Copyright (c) 2025-2026 Intel Corporation 6 + */ 7 + #ifndef LINUX_IEEE80211_UHR_H 8 + #define LINUX_IEEE80211_UHR_H 9 + 10 + #include <linux/types.h> 11 + #include <linux/if_ether.h> 12 + 13 + #define IEEE80211_UHR_OPER_PARAMS_DPS_ENA 0x0001 14 + #define IEEE80211_UHR_OPER_PARAMS_NPCA_ENA 0x0002 15 + #define IEEE80211_UHR_OPER_PARAMS_DBE_ENA 0x0004 16 + #define IEEE80211_UHR_OPER_PARAMS_PEDCA_ENA 0x0008 17 + 18 + struct ieee80211_uhr_operation { 19 + __le16 params; 20 + u8 basic_mcs_nss_set[4]; 21 + u8 variable[]; 22 + } __packed; 23 + 24 + #define IEEE80211_UHR_NPCA_PARAMS_PRIMARY_CHAN_OFFS 0x0000000F 25 + #define IEEE80211_UHR_NPCA_PARAMS_MIN_DUR_THRESH 0x000000F0 26 + #define IEEE80211_UHR_NPCA_PARAMS_SWITCH_DELAY 0x00003F00 27 + #define IEEE80211_UHR_NPCA_PARAMS_SWITCH_BACK_DELAY 0x000FC000 28 + #define IEEE80211_UHR_NPCA_PARAMS_INIT_QSRC 0x00300000 29 + #define IEEE80211_UHR_NPCA_PARAMS_MOPLEN 0x00400000 30 + #define IEEE80211_UHR_NPCA_PARAMS_DIS_SUBCH_BMAP_PRES 0x00800000 31 + 32 + struct ieee80211_uhr_npca_info { 33 + __le32 params; 34 + __le16 dis_subch_bmap[]; 35 + } __packed; 36 + 37 + static inline bool ieee80211_uhr_oper_size_ok(const u8 *data, u8 len, 38 + bool beacon) 39 + { 40 + const struct ieee80211_uhr_operation *oper = (const void *)data; 41 + u8 needed = sizeof(*oper); 42 + 43 + if (len < needed) 44 + return false; 45 + 46 + /* nothing else present in beacons */ 47 + if (beacon) 48 + return true; 49 + 50 + /* FIXME: DPS, DBE, P-EDCA (consider order, also relative to NPCA) */ 51 + 52 + if (oper->params & cpu_to_le16(IEEE80211_UHR_OPER_PARAMS_NPCA_ENA)) { 53 + const struct ieee80211_uhr_npca_info *npca = 54 + (const void *)oper->variable; 55 + 56 + needed += sizeof(*npca); 57 + 58 + if (len < needed) 59 + return false; 60 + 61 + if (npca->params & cpu_to_le32(IEEE80211_UHR_NPCA_PARAMS_DIS_SUBCH_BMAP_PRES)) 62 + needed += sizeof(npca->dis_subch_bmap[0]); 63 + } 64 + 65 + return len >= needed; 66 + } 67 + 68 + /* 69 + * Note: cannot call this on the element coming from a beacon, 70 + * must ensure ieee80211_uhr_oper_size_ok(..., false) first 71 + */ 72 + static inline const struct ieee80211_uhr_npca_info * 73 + ieee80211_uhr_npca_info(const struct ieee80211_uhr_operation *oper) 74 + { 75 + if (!(oper->params & cpu_to_le16(IEEE80211_UHR_OPER_PARAMS_NPCA_ENA))) 76 + return NULL; 77 + 78 + /* FIXME: DPS */ 79 + 80 + return (const void *)oper->variable; 81 + } 82 + 83 + static inline const __le16 * 84 + ieee80211_uhr_npca_dis_subch_bitmap(const struct ieee80211_uhr_operation *oper) 85 + { 86 + const struct ieee80211_uhr_npca_info *npca; 87 + 88 + npca = ieee80211_uhr_npca_info(oper); 89 + if (!npca) 90 + return NULL; 91 + if (!(npca->params & cpu_to_le32(IEEE80211_UHR_NPCA_PARAMS_DIS_SUBCH_BMAP_PRES))) 92 + return NULL; 93 + return npca->dis_subch_bmap; 94 + } 95 + 96 + #define IEEE80211_UHR_MAC_CAP0_DPS_SUPP 0x01 97 + #define IEEE80211_UHR_MAC_CAP0_DPS_ASSIST_SUPP 0x02 98 + #define IEEE80211_UHR_MAC_CAP0_DPS_AP_STATIC_HCM_SUPP 0x04 99 + #define IEEE80211_UHR_MAC_CAP0_NPCA_SUPP 0x10 100 + #define IEEE80211_UHR_MAC_CAP0_ENH_BSR_SUPP 0x20 101 + #define IEEE80211_UHR_MAC_CAP0_ADD_MAP_TID_SUPP 0x40 102 + #define IEEE80211_UHR_MAC_CAP0_EOTSP_SUPP 0x80 103 + 104 + #define IEEE80211_UHR_MAC_CAP1_DSO_SUPP 0x01 105 + #define IEEE80211_UHR_MAC_CAP1_PEDCA_SUPP 0x02 106 + #define IEEE80211_UHR_MAC_CAP1_DBE_SUPP 0x04 107 + #define IEEE80211_UHR_MAC_CAP1_UL_LLI_SUPP 0x08 108 + #define IEEE80211_UHR_MAC_CAP1_P2P_LLI_SUPP 0x10 109 + #define IEEE80211_UHR_MAC_CAP1_PUO_SUPP 0x20 110 + #define IEEE80211_UHR_MAC_CAP1_AP_PUO_SUPP 0x40 111 + #define IEEE80211_UHR_MAC_CAP1_DUO_SUPP 0x80 112 + 113 + #define IEEE80211_UHR_MAC_CAP2_OMC_UL_MU_DIS_RX_SUPP 0x01 114 + #define IEEE80211_UHR_MAC_CAP2_AOM_SUPP 0x02 115 + #define IEEE80211_UHR_MAC_CAP2_IFCS_LOC_SUPP 0x04 116 + #define IEEE80211_UHR_MAC_CAP2_UHR_TRS_SUPP 0x08 117 + #define IEEE80211_UHR_MAC_CAP2_TXSPG_SUPP 0x10 118 + #define IEEE80211_UHR_MAC_CAP2_TXOP_RET_IN_TXSPG 0x20 119 + #define IEEE80211_UHR_MAC_CAP2_UHR_OM_PU_TO_LOW 0xC0 120 + 121 + #define IEEE80211_UHR_MAC_CAP3_UHR_OM_PU_TO_HIGH 0x03 122 + #define IEEE80211_UHR_MAC_CAP3_PARAM_UPD_ADV_NOTIF_INTV 0x1C 123 + #define IEEE80211_UHR_MAC_CAP3_UPD_IND_TIM_INTV_LOW 0xE0 124 + 125 + #define IEEE80211_UHR_MAC_CAP4_UPD_IND_TIM_INTV_HIGH 0x03 126 + #define IEEE80211_UHR_MAC_CAP4_BOUNDED_ESS 0x04 127 + #define IEEE80211_UHR_MAC_CAP4_BTM_ASSURANCE 0x08 128 + #define IEEE80211_UHR_MAC_CAP4_CO_BF_SUPP 0x10 129 + 130 + #define IEEE80211_UHR_MAC_CAP_DBE_MAX_BW 0x07 131 + #define IEEE80211_UHR_MAC_CAP_DBE_EHT_MCS_MAP_160_PRES 0x08 132 + #define IEEE80211_UHR_MAC_CAP_DBE_EHT_MCS_MAP_320_PRES 0x10 133 + 134 + struct ieee80211_uhr_cap_mac { 135 + u8 mac_cap[5]; 136 + } __packed; 137 + 138 + struct ieee80211_uhr_cap { 139 + struct ieee80211_uhr_cap_mac mac; 140 + /* DBE, PHY capabilities */ 141 + u8 variable[]; 142 + } __packed; 143 + 144 + #define IEEE80211_UHR_PHY_CAP_MAX_NSS_RX_SND_NDP_LE80 0x01 145 + #define IEEE80211_UHR_PHY_CAP_MAX_NSS_RX_DL_MU_LE80 0x02 146 + #define IEEE80211_UHR_PHY_CAP_MAX_NSS_RX_SND_NDP_160 0x04 147 + #define IEEE80211_UHR_PHY_CAP_MAX_NSS_RX_DL_MU_160 0x08 148 + #define IEEE80211_UHR_PHY_CAP_MAX_NSS_RX_SND_NDP_320 0x10 149 + #define IEEE80211_UHR_PHY_CAP_MAX_NSS_RX_DL_MU_320 0x20 150 + #define IEEE80211_UHR_PHY_CAP_ELR_RX 0x40 151 + #define IEEE80211_UHR_PHY_CAP_ELR_TX 0x80 152 + 153 + struct ieee80211_uhr_cap_phy { 154 + u8 cap; 155 + } __packed; 156 + 157 + static inline bool ieee80211_uhr_capa_size_ok(const u8 *data, u8 len, 158 + bool from_ap) 159 + { 160 + const struct ieee80211_uhr_cap *cap = (const void *)data; 161 + size_t needed = sizeof(*cap) + sizeof(struct ieee80211_uhr_cap_phy); 162 + 163 + if (len < needed) 164 + return false; 165 + 166 + /* 167 + * A non-AP STA does not include the DBE Capability Parameters field 168 + * in the UHR MAC Capabilities Information field. 169 + */ 170 + if (from_ap && cap->mac.mac_cap[1] & IEEE80211_UHR_MAC_CAP1_DBE_SUPP) { 171 + u8 dbe; 172 + 173 + needed += 1; 174 + if (len < needed) 175 + return false; 176 + 177 + dbe = cap->variable[0]; 178 + 179 + if (dbe & IEEE80211_UHR_MAC_CAP_DBE_EHT_MCS_MAP_160_PRES) 180 + needed += 3; 181 + 182 + if (dbe & IEEE80211_UHR_MAC_CAP_DBE_EHT_MCS_MAP_320_PRES) 183 + needed += 3; 184 + } 185 + 186 + return len >= needed; 187 + } 188 + 189 + static inline const struct ieee80211_uhr_cap_phy * 190 + ieee80211_uhr_phy_cap(const struct ieee80211_uhr_cap *cap, bool from_ap) 191 + { 192 + u8 offs = 0; 193 + 194 + if (from_ap && cap->mac.mac_cap[1] & IEEE80211_UHR_MAC_CAP1_DBE_SUPP) { 195 + u8 dbe = cap->variable[0]; 196 + 197 + offs += 1; 198 + 199 + if (dbe & IEEE80211_UHR_MAC_CAP_DBE_EHT_MCS_MAP_160_PRES) 200 + offs += 3; 201 + 202 + if (dbe & IEEE80211_UHR_MAC_CAP_DBE_EHT_MCS_MAP_320_PRES) 203 + offs += 3; 204 + } 205 + 206 + return (const void *)&cap->variable[offs]; 207 + } 208 + 209 + #define IEEE80211_SMD_INFO_CAPA_DL_DATA_FWD 0x01 210 + #define IEEE80211_SMD_INFO_CAPA_MAX_NUM_PREP 0x0E 211 + #define IEEE80211_SMD_INFO_CAPA_TYPE 0x10 212 + #define IEEE80211_SMD_INFO_CAPA_PTK_PER_AP_MLD 0x20 213 + 214 + struct ieee80211_smd_info { 215 + u8 id[ETH_ALEN]; 216 + u8 capa; 217 + __le16 timeout; 218 + } __packed; 219 + 220 + #endif /* LINUX_IEEE80211_UHR_H */
+37 -2
include/linux/ieee80211.h
··· 9 9 * Copyright (c) 2006, Michael Wu <flamingice@sourmilk.net> 10 10 * Copyright (c) 2013 - 2014 Intel Mobile Communications GmbH 11 11 * Copyright (c) 2016 - 2017 Intel Deutschland GmbH 12 - * Copyright (c) 2018 - 2025 Intel Corporation 12 + * Copyright (c) 2018 - 2026 Intel Corporation 13 13 */ 14 14 15 15 #ifndef LINUX_IEEE80211_H ··· 1186 1186 u8 action_code; 1187 1187 u8 variable[]; 1188 1188 } __packed epcs; 1189 + struct { 1190 + u8 action_code; 1191 + u8 dialog_token; 1192 + u8 control; 1193 + u8 variable[]; 1194 + } __packed eml_omn; 1189 1195 } u; 1190 1196 } __packed action; 1191 1197 DECLARE_FLEX_ARRAY(u8, body); /* Generic frame body */ ··· 1206 1200 #define BSS_MEMBERSHIP_SELECTOR_SAE_H2E 123 1207 1201 #define BSS_MEMBERSHIP_SELECTOR_HE_PHY 122 1208 1202 #define BSS_MEMBERSHIP_SELECTOR_EHT_PHY 121 1203 + #define BSS_MEMBERSHIP_SELECTOR_UHR_PHY 120 1209 1204 1210 - #define BSS_MEMBERSHIP_SELECTOR_MIN BSS_MEMBERSHIP_SELECTOR_EHT_PHY 1205 + #define BSS_MEMBERSHIP_SELECTOR_MIN BSS_MEMBERSHIP_SELECTOR_UHR_PHY 1211 1206 1212 1207 /* mgmt header + 1 byte category code */ 1213 1208 #define IEEE80211_MIN_ACTION_SIZE offsetof(struct ieee80211_mgmt, u.action.u) ··· 1809 1802 WLAN_EID_EXT_BANDWIDTH_INDICATION = 135, 1810 1803 WLAN_EID_EXT_KNOWN_STA_IDENTIFCATION = 136, 1811 1804 WLAN_EID_EXT_NON_AP_STA_REG_CON = 137, 1805 + WLAN_EID_EXT_UHR_OPER = 151, 1806 + WLAN_EID_EXT_UHR_CAPA = 152, 1807 + WLAN_EID_EXT_MACP = 153, 1808 + WLAN_EID_EXT_SMD = 154, 1809 + WLAN_EID_EXT_BSS_SMD_TRANS_PARAMS = 155, 1810 + WLAN_EID_EXT_CHAN_USAGE = 156, 1811 + WLAN_EID_EXT_UHR_MODE_CHG = 157, 1812 + WLAN_EID_EXT_UHR_PARAM_UPD = 158, 1813 + WLAN_EID_EXT_TXPI = 159, 1812 1814 }; 1813 1815 1814 1816 /* Action category code */ ··· 2761 2745 #define WLAN_RSNX_CAPA_PROTECTED_TWT BIT(4) 2762 2746 #define WLAN_RSNX_CAPA_SAE_H2E BIT(5) 2763 2747 2748 + /* EBPCC = Enhanced BSS Parameter Change Count */ 2749 + #define IEEE80211_ENH_CRIT_UPD_EBPCC 0x0F 2750 + #define IEEE80211_ENH_CRIT_UPD_TYPE 0x70 2751 + #define IEEE80211_ENH_CRIT_UPD_TYPE_NO_UHR 0 2752 + #define IEEE80211_ENH_CRIT_UPD_TYPE_UHR 1 2753 + #define IEEE80211_ENH_CRIT_UPD_ALL 0x80 2754 + 2755 + /** 2756 + * struct ieee80211_enh_crit_upd - enhanced critical update (UHR) 2757 + * @v: value of the enhanced critical update data, 2758 + * see %IEEE80211_ENH_CRIT_UPD_* to parse the bits 2759 + */ 2760 + struct ieee80211_enh_crit_upd { 2761 + u8 v; 2762 + } __packed; 2763 + 2764 2764 /* 2765 2765 * reduced neighbor report, based on Draft P802.11ax_D6.1, 2766 2766 * section 9.4.2.170 and accepted contributions. ··· 2795 2763 #define IEEE80211_RNR_TBTT_PARAMS_COLOC_ESS 0x10 2796 2764 #define IEEE80211_RNR_TBTT_PARAMS_PROBE_ACTIVE 0x20 2797 2765 #define IEEE80211_RNR_TBTT_PARAMS_COLOC_AP 0x40 2766 + #define IEEE80211_RNR_TBTT_PARAMS_SAME_SMD 0x80 2798 2767 2799 2768 #define IEEE80211_RNR_TBTT_PARAMS_PSD_NO_LIMIT 127 2800 2769 #define IEEE80211_RNR_TBTT_PARAMS_PSD_RESERVED -128 ··· 2848 2815 u8 bss_params; 2849 2816 s8 psd_20; 2850 2817 struct ieee80211_rnr_mld_params mld_params; 2818 + struct ieee80211_enh_crit_upd enh_crit_upd; 2851 2819 } __packed; 2852 2820 2853 2821 #include "ieee80211-ht.h" 2854 2822 #include "ieee80211-vht.h" 2855 2823 #include "ieee80211-he.h" 2856 2824 #include "ieee80211-eht.h" 2825 + #include "ieee80211-uhr.h" 2857 2826 #include "ieee80211-mesh.h" 2858 2827 #include "ieee80211-s1g.h" 2859 2828 #include "ieee80211-p2p.h"
+55 -3
include/net/cfg80211.h
··· 7 7 * Copyright 2006-2010 Johannes Berg <johannes@sipsolutions.net> 8 8 * Copyright 2013-2014 Intel Mobile Communications GmbH 9 9 * Copyright 2015-2017 Intel Deutschland GmbH 10 - * Copyright (C) 2018-2025 Intel Corporation 10 + * Copyright (C) 2018-2026 Intel Corporation 11 11 */ 12 12 13 13 #include <linux/ethtool.h> ··· 126 126 * @IEEE80211_CHAN_NO_4MHZ: 4 MHz bandwidth is not permitted on this channel. 127 127 * @IEEE80211_CHAN_NO_8MHZ: 8 MHz bandwidth is not permitted on this channel. 128 128 * @IEEE80211_CHAN_NO_16MHZ: 16 MHz bandwidth is not permitted on this channel. 129 + * @IEEE80211_CHAN_NO_UHR: UHR operation is not permitted on this channel. 129 130 */ 130 131 enum ieee80211_channel_flags { 131 132 IEEE80211_CHAN_DISABLED = BIT(0), ··· 144 143 IEEE80211_CHAN_NO_10MHZ = BIT(12), 145 144 IEEE80211_CHAN_NO_HE = BIT(13), 146 145 /* can use free bits here */ 146 + IEEE80211_CHAN_NO_UHR = BIT(18), 147 147 IEEE80211_CHAN_NO_320MHZ = BIT(19), 148 148 IEEE80211_CHAN_NO_EHT = BIT(20), 149 149 IEEE80211_CHAN_DFS_CONCURRENT = BIT(21), ··· 431 429 u8 eht_ppe_thres[IEEE80211_EHT_PPE_THRES_MAX_LEN]; 432 430 }; 433 431 432 + /** 433 + * struct ieee80211_sta_uhr_cap - STA's UHR capabilities 434 + * @has_uhr: true iff UHR is supported and data is valid 435 + * @mac: fixed MAC capabilities 436 + * @phy: fixed PHY capabilities 437 + */ 438 + struct ieee80211_sta_uhr_cap { 439 + bool has_uhr; 440 + struct ieee80211_uhr_cap_mac mac; 441 + struct ieee80211_uhr_cap_phy phy; 442 + }; 443 + 434 444 /* sparse defines __CHECKER__; see Documentation/dev-tools/sparse.rst */ 435 445 #ifdef __CHECKER__ 436 446 /* ··· 468 454 * @he_6ghz_capa: HE 6 GHz capabilities, must be filled in for a 469 455 * 6 GHz band channel (and 0 may be valid value). 470 456 * @eht_cap: STA's EHT capabilities 457 + * @uhr_cap: STA's UHR capabilities 471 458 * @vendor_elems: vendor element(s) to advertise 472 459 * @vendor_elems.data: vendor element(s) data 473 460 * @vendor_elems.len: vendor element(s) length ··· 478 463 struct ieee80211_sta_he_cap he_cap; 479 464 struct ieee80211_he_6ghz_capa he_6ghz_capa; 480 465 struct ieee80211_sta_eht_cap eht_cap; 466 + struct ieee80211_sta_uhr_cap uhr_cap; 481 467 struct { 482 468 const u8 *data; 483 469 unsigned int len; ··· 716 700 717 701 if (data && data->eht_cap.has_eht) 718 702 return &data->eht_cap; 703 + 704 + return NULL; 705 + } 706 + 707 + /** 708 + * ieee80211_get_uhr_iftype_cap - return UHR capabilities for an sband's iftype 709 + * @sband: the sband to search for the iftype on 710 + * @iftype: enum nl80211_iftype 711 + * 712 + * Return: pointer to the struct ieee80211_sta_uhr_cap, or NULL is none found 713 + */ 714 + static inline const struct ieee80211_sta_uhr_cap * 715 + ieee80211_get_uhr_iftype_cap(const struct ieee80211_supported_band *sband, 716 + enum nl80211_iftype iftype) 717 + { 718 + const struct ieee80211_sband_iftype_data *data = 719 + ieee80211_get_sband_iftype_data(sband, iftype); 720 + 721 + if (data && data->uhr_cap.has_uhr) 722 + return &data->uhr_cap; 719 723 720 724 return NULL; 721 725 } ··· 1522 1486 * @he_cap: HE capabilities (or %NULL if HE isn't enabled) 1523 1487 * @eht_cap: EHT capabilities (or %NULL if EHT isn't enabled) 1524 1488 * @eht_oper: EHT operation IE (or %NULL if EHT isn't enabled) 1489 + * @uhr_oper: UHR operation (or %NULL if UHR isn't enabled) 1525 1490 * @ht_required: stations must support HT 1526 1491 * @vht_required: stations must support VHT 1527 1492 * @twt_responder: Enable Target Wait Time ··· 1562 1525 const struct ieee80211_he_operation *he_oper; 1563 1526 const struct ieee80211_eht_cap_elem *eht_cap; 1564 1527 const struct ieee80211_eht_operation *eht_oper; 1528 + const struct ieee80211_uhr_operation *uhr_oper; 1565 1529 bool ht_required, vht_required, he_required, sae_h2e_required; 1566 1530 bool twt_responder; 1567 1531 u32 flags; ··· 1736 1698 * @eht_capa: EHT capabilities of station 1737 1699 * @eht_capa_len: the length of the EHT capabilities 1738 1700 * @s1g_capa: S1G capabilities of station 1701 + * @uhr_capa: UHR capabilities of the station 1702 + * @uhr_capa_len: the length of the UHR capabilities 1739 1703 */ 1740 1704 struct link_station_parameters { 1741 1705 const u8 *mld_mac; ··· 1757 1717 const struct ieee80211_eht_cap_elem *eht_capa; 1758 1718 u8 eht_capa_len; 1759 1719 const struct ieee80211_s1g_cap *s1g_capa; 1720 + const struct ieee80211_uhr_cap *uhr_capa; 1721 + u8 uhr_capa_len; 1760 1722 }; 1761 1723 1762 1724 /** ··· 1940 1898 * @RATE_INFO_FLAGS_EXTENDED_SC_DMG: 60GHz extended SC MCS 1941 1899 * @RATE_INFO_FLAGS_EHT_MCS: EHT MCS information 1942 1900 * @RATE_INFO_FLAGS_S1G_MCS: MCS field filled with S1G MCS 1901 + * @RATE_INFO_FLAGS_UHR_MCS: UHR MCS information 1902 + * @RATE_INFO_FLAGS_UHR_ELR_MCS: UHR ELR MCS was used 1903 + * (set together with @RATE_INFO_FLAGS_UHR_MCS) 1904 + * @RATE_INFO_FLAGS_UHR_IM: UHR Interference Mitigation 1905 + * was used 1943 1906 */ 1944 1907 enum rate_info_flags { 1945 1908 RATE_INFO_FLAGS_MCS = BIT(0), ··· 1956 1909 RATE_INFO_FLAGS_EXTENDED_SC_DMG = BIT(6), 1957 1910 RATE_INFO_FLAGS_EHT_MCS = BIT(7), 1958 1911 RATE_INFO_FLAGS_S1G_MCS = BIT(8), 1912 + RATE_INFO_FLAGS_UHR_MCS = BIT(9), 1913 + RATE_INFO_FLAGS_UHR_ELR_MCS = BIT(10), 1914 + RATE_INFO_FLAGS_UHR_IM = BIT(11), 1959 1915 }; 1960 1916 1961 1917 /** ··· 1974 1924 * @RATE_INFO_BW_160: 160 MHz bandwidth 1975 1925 * @RATE_INFO_BW_HE_RU: bandwidth determined by HE RU allocation 1976 1926 * @RATE_INFO_BW_320: 320 MHz bandwidth 1977 - * @RATE_INFO_BW_EHT_RU: bandwidth determined by EHT RU allocation 1927 + * @RATE_INFO_BW_EHT_RU: bandwidth determined by EHT/UHR RU allocation 1978 1928 * @RATE_INFO_BW_1: 1 MHz bandwidth 1979 1929 * @RATE_INFO_BW_2: 2 MHz bandwidth 1980 1930 * @RATE_INFO_BW_4: 4 MHz bandwidth ··· 2005 1955 * 2006 1956 * @flags: bitflag of flags from &enum rate_info_flags 2007 1957 * @legacy: bitrate in 100kbit/s for 802.11abg 2008 - * @mcs: mcs index if struct describes an HT/VHT/HE/EHT/S1G rate 1958 + * @mcs: mcs index if struct describes an HT/VHT/HE/EHT/S1G/UHR rate 2009 1959 * @nss: number of streams (VHT & HE only) 2010 1960 * @bw: bandwidth (from &enum rate_info_bw) 2011 1961 * @he_gi: HE guard interval (from &enum nl80211_he_gi) ··· 3312 3262 * Drivers shall disable MLO features for the current association if this 3313 3263 * flag is not set. 3314 3264 * @ASSOC_REQ_SPP_AMSDU: SPP A-MSDUs will be used on this connection (if any) 3265 + * @ASSOC_REQ_DISABLE_UHR: Disable UHR 3315 3266 */ 3316 3267 enum cfg80211_assoc_req_flags { 3317 3268 ASSOC_REQ_DISABLE_HT = BIT(0), ··· 3323 3272 ASSOC_REQ_DISABLE_EHT = BIT(5), 3324 3273 CONNECT_REQ_MLO_SUPPORT = BIT(6), 3325 3274 ASSOC_REQ_SPP_AMSDU = BIT(7), 3275 + ASSOC_REQ_DISABLE_UHR = BIT(8), 3326 3276 }; 3327 3277 3328 3278 /**
+65 -2
include/net/mac80211.h
··· 7 7 * Copyright 2007-2010 Johannes Berg <johannes@sipsolutions.net> 8 8 * Copyright 2013-2014 Intel Mobile Communications GmbH 9 9 * Copyright (C) 2015 - 2017 Intel Deutschland GmbH 10 - * Copyright (C) 2018 - 2025 Intel Corporation 10 + * Copyright (C) 2018 - 2026 Intel Corporation 11 11 */ 12 12 13 13 #ifndef MAC80211_H ··· 706 706 * @pwr_reduction: power constraint of BSS. 707 707 * @eht_support: does this BSS support EHT 708 708 * @epcs_support: does this BSS support EPCS 709 + * @uhr_support: does this BSS support UHR 709 710 * @csa_active: marks whether a channel switch is going on. 710 711 * @mu_mimo_owner: indicates interface owns MU-MIMO capability 711 712 * @chanctx_conf: The channel context this interface is assigned to, or %NULL ··· 833 832 u8 pwr_reduction; 834 833 bool eht_support; 835 834 bool epcs_support; 835 + bool uhr_support; 836 + 836 837 bool csa_active; 837 838 838 839 bool mu_mimo_owner; ··· 1601 1598 RX_ENC_VHT, 1602 1599 RX_ENC_HE, 1603 1600 RX_ENC_EHT, 1601 + RX_ENC_UHR, 1604 1602 }; 1605 1603 1606 1604 /** ··· 1635 1631 * @antenna: antenna used 1636 1632 * @rate_idx: index of data rate into band's supported rates or MCS index if 1637 1633 * HT or VHT is used (%RX_FLAG_HT/%RX_FLAG_VHT) 1638 - * @nss: number of streams (VHT, HE and EHT only) 1634 + * @nss: number of streams (VHT, HE, EHT and UHR only) 1639 1635 * @flag: %RX_FLAG_\* 1640 1636 * @encoding: &enum mac80211_rx_encoding 1641 1637 * @bw: &enum rate_info_bw ··· 1646 1642 * @eht: EHT specific rate information 1647 1643 * @eht.ru: EHT RU, from &enum nl80211_eht_ru_alloc 1648 1644 * @eht.gi: EHT GI, from &enum nl80211_eht_gi 1645 + * @uhr: UHR specific rate information 1646 + * @uhr.ru: UHR RU, from &enum nl80211_eht_ru_alloc 1647 + * @uhr.gi: UHR GI, from &enum nl80211_eht_gi 1648 + * @uhr.elr: UHR ELR MCS was used 1649 + * @uhr.im: UHR interference mitigation was used 1649 1650 * @rx_flags: internal RX flags for mac80211 1650 1651 * @ampdu_reference: A-MPDU reference number, must be a different value for 1651 1652 * each A-MPDU but the same for each subframe within one A-MPDU ··· 1682 1673 u8 ru:4; 1683 1674 u8 gi:2; 1684 1675 } eht; 1676 + struct { 1677 + u8 ru:4; 1678 + u8 gi:2; 1679 + u8 elr:1; 1680 + u8 im:1; 1681 + } uhr; 1685 1682 }; 1686 1683 u8 rate_idx; 1687 1684 u8 nss; ··· 1915 1900 IEEE80211_OFFLOAD_ENCAP_ENABLED = BIT(0), 1916 1901 IEEE80211_OFFLOAD_ENCAP_4ADDR = BIT(1), 1917 1902 IEEE80211_OFFLOAD_DECAP_ENABLED = BIT(2), 1903 + }; 1904 + 1905 + /** 1906 + * struct ieee80211_eml_params - EHT Operating mode notification parameters 1907 + * 1908 + * EML Operating mode notification parameters received in the Operating mode 1909 + * notification frame. This struct is used as a container to pass the info to 1910 + * the underlay driver. 1911 + * 1912 + * @link_id: the link ID where the Operating mode notification frame has been 1913 + * received. 1914 + * @control: EML control field defined in P802.11be section 9.4.1.76. 1915 + * @link_bitmap: eMLSR/eMLMR enabled links defined in P802.11be 1916 + * section 9.4.1.76. 1917 + * @emlmr_mcs_map_count: eMLMR number of valid mcs_map_bw fields according to 1918 + * P802.11be section 9.4.1.76 (valid if eMLMR mode control bit is set). 1919 + * @emlmr_mcs_map_bw: eMLMR supported MCS and NSS set subfileds defined in 1920 + * P802.11be section 9.4.1.76 (valid if eMLMR mode control bit is set). 1921 + */ 1922 + struct ieee80211_eml_params { 1923 + u8 link_id; 1924 + u8 control; 1925 + u16 link_bitmap; 1926 + u8 emlmr_mcs_map_count; 1927 + u8 emlmr_mcs_map_bw[9]; 1918 1928 }; 1919 1929 1920 1930 /** ··· 2474 2434 * @he_cap: HE capabilities of this STA 2475 2435 * @he_6ghz_capa: on 6 GHz, holds the HE 6 GHz band capabilities 2476 2436 * @eht_cap: EHT capabilities of this STA 2437 + * @uhr_cap: UHR capabilities of this STA 2477 2438 * @s1g_cap: S1G capabilities of this STA 2478 2439 * @agg: per-link data for multi-link aggregation 2479 2440 * @bandwidth: current bandwidth the station can receive with ··· 2498 2457 struct ieee80211_sta_he_cap he_cap; 2499 2458 struct ieee80211_he_6ghz_capa he_6ghz_capa; 2500 2459 struct ieee80211_sta_eht_cap eht_cap; 2460 + struct ieee80211_sta_uhr_cap uhr_cap; 2501 2461 struct ieee80211_sta_s1g_cap s1g_cap; 2502 2462 2503 2463 struct ieee80211_sta_aggregates agg; ··· 4555 4513 * interface with the specified type would be added, and thus drivers that 4556 4514 * implement this callback need to handle such cases. The type is the full 4557 4515 * &enum nl80211_iftype. 4516 + * @set_eml_op_mode: Configure eMLSR/eMLMR operation mode in the underlay 4517 + * driver according to the parameter received in the EML Operating mode 4518 + * notification frame. 4558 4519 */ 4559 4520 struct ieee80211_ops { 4560 4521 void (*tx)(struct ieee80211_hw *hw, ··· 4953 4908 struct ieee80211_neg_ttlm *ttlm); 4954 4909 void (*prep_add_interface)(struct ieee80211_hw *hw, 4955 4910 enum nl80211_iftype type); 4911 + int (*set_eml_op_mode)(struct ieee80211_hw *hw, 4912 + struct ieee80211_vif *vif, 4913 + struct ieee80211_sta *sta, 4914 + struct ieee80211_eml_params *eml_params); 4956 4915 }; 4957 4916 4958 4917 /** ··· 7336 7287 struct ieee80211_vif *vif) 7337 7288 { 7338 7289 return ieee80211_get_eht_iftype_cap(sband, ieee80211_vif_type_p2p(vif)); 7290 + } 7291 + 7292 + /** 7293 + * ieee80211_get_uhr_iftype_cap_vif - return UHR capabilities for sband/vif 7294 + * @sband: the sband to search for the iftype on 7295 + * @vif: the vif to get the iftype from 7296 + * 7297 + * Return: pointer to the struct ieee80211_sta_uhr_cap, or %NULL is none found 7298 + */ 7299 + static inline const struct ieee80211_sta_uhr_cap * 7300 + ieee80211_get_uhr_iftype_cap_vif(const struct ieee80211_supported_band *sband, 7301 + struct ieee80211_vif *vif) 7302 + { 7303 + return ieee80211_get_uhr_iftype_cap(sband, ieee80211_vif_type_p2p(vif)); 7339 7304 } 7340 7305 7341 7306 /**
+30
include/uapi/linux/nl80211.h
··· 2977 2977 * @NL80211_ATTR_EPP_PEER: A flag attribute to indicate if the peer is an EPP 2978 2978 * STA. Used with %NL80211_CMD_NEW_STA and %NL80211_CMD_ADD_LINK_STA 2979 2979 * 2980 + * @NL80211_ATTR_UHR_CAPABILITY: UHR Capability information element (from 2981 + * association request when used with NL80211_CMD_NEW_STATION). Can be set 2982 + * only if HE/EHT are also available. 2983 + * @NL80211_ATTR_DISABLE_UHR: Force UHR capable interfaces to disable 2984 + * this feature during association. This is a flag attribute. 2985 + * Currently only supported in mac80211 drivers. 2986 + * 2980 2987 * @NUM_NL80211_ATTR: total number of nl80211_attrs available 2981 2988 * @NL80211_ATTR_MAX: highest attribute number currently defined 2982 2989 * @__NL80211_ATTR_AFTER_LAST: internal use ··· 3554 3547 3555 3548 NL80211_ATTR_EPP_PEER, 3556 3549 3550 + NL80211_ATTR_UHR_CAPABILITY, 3551 + NL80211_ATTR_DISABLE_UHR, 3552 + 3557 3553 /* add attributes here, update the policy in nl80211.c */ 3558 3554 3559 3555 __NL80211_ATTR_AFTER_LAST, ··· 3909 3899 * @NL80211_RATE_INFO_4_MHZ_WIDTH: 4 MHz S1G rate 3910 3900 * @NL80211_RATE_INFO_8_MHZ_WIDTH: 8 MHz S1G rate 3911 3901 * @NL80211_RATE_INFO_16_MHZ_WIDTH: 16 MHz S1G rate 3902 + * @NL80211_RATE_INFO_UHR_MCS: UHR MCS index (u8, 0-15, 17, 19, 20, 23) 3903 + * Note that the other EHT attributes (such as @NL80211_RATE_INFO_EHT_NSS) 3904 + * are used in conjunction with this where applicable 3905 + * @NL80211_RATE_INFO_UHR_ELR: UHR ELR flag, which restricts NSS to 1, 3906 + * MCS to 0 or 1, and GI to %NL80211_RATE_INFO_EHT_GI_1_6. 3907 + * @NL80211_RATE_INFO_UHR_IM: UHR Interference Mitigation flag 3912 3908 * @__NL80211_RATE_INFO_AFTER_LAST: internal use 3913 3909 */ 3914 3910 enum nl80211_rate_info { ··· 3948 3932 NL80211_RATE_INFO_4_MHZ_WIDTH, 3949 3933 NL80211_RATE_INFO_8_MHZ_WIDTH, 3950 3934 NL80211_RATE_INFO_16_MHZ_WIDTH, 3935 + NL80211_RATE_INFO_UHR_MCS, 3936 + NL80211_RATE_INFO_UHR_ELR, 3937 + NL80211_RATE_INFO_UHR_IM, 3951 3938 3952 3939 /* keep last */ 3953 3940 __NL80211_RATE_INFO_AFTER_LAST, ··· 4273 4254 * capabilities element 4274 4255 * @NL80211_BAND_IFTYPE_ATTR_EHT_CAP_PPE: EHT PPE thresholds information as 4275 4256 * defined in EHT capabilities element 4257 + * @NL80211_BAND_IFTYPE_ATTR_UHR_CAP_MAC: UHR MAC capabilities as in UHR 4258 + * capabilities element 4259 + * @NL80211_BAND_IFTYPE_ATTR_UHR_CAP_PHY: UHR PHY capabilities as in UHR 4260 + * capabilities element 4276 4261 * @__NL80211_BAND_IFTYPE_ATTR_AFTER_LAST: internal use 4277 4262 * @NL80211_BAND_IFTYPE_ATTR_MAX: highest band attribute currently defined 4278 4263 */ ··· 4294 4271 NL80211_BAND_IFTYPE_ATTR_EHT_CAP_PHY, 4295 4272 NL80211_BAND_IFTYPE_ATTR_EHT_CAP_MCS_SET, 4296 4273 NL80211_BAND_IFTYPE_ATTR_EHT_CAP_PPE, 4274 + NL80211_BAND_IFTYPE_ATTR_UHR_CAP_MAC, 4275 + NL80211_BAND_IFTYPE_ATTR_UHR_CAP_PHY, 4297 4276 4298 4277 /* keep last */ 4299 4278 __NL80211_BAND_IFTYPE_ATTR_AFTER_LAST, ··· 4478 4453 * @NL80211_FREQUENCY_ATTR_S1G_NO_PRIMARY: Channel is not permitted for use 4479 4454 * as a primary channel. Does not prevent the channel from existing 4480 4455 * as a non-primary subchannel. Only applicable to S1G channels. 4456 + * @NL80211_FREQUENCY_ATTR_NO_UHR: UHR operation is not allowed on this channel 4457 + * in current regulatory domain. 4481 4458 * @NL80211_FREQUENCY_ATTR_MAX: highest frequency attribute number 4482 4459 * currently defined 4483 4460 * @__NL80211_FREQUENCY_ATTR_AFTER_LAST: internal use ··· 4529 4502 NL80211_FREQUENCY_ATTR_NO_8MHZ, 4530 4503 NL80211_FREQUENCY_ATTR_NO_16MHZ, 4531 4504 NL80211_FREQUENCY_ATTR_S1G_NO_PRIMARY, 4505 + NL80211_FREQUENCY_ATTR_NO_UHR, 4532 4506 4533 4507 /* keep last */ 4534 4508 __NL80211_FREQUENCY_ATTR_AFTER_LAST, ··· 4743 4715 * despite NO_IR configuration. 4744 4716 * @NL80211_RRF_ALLOW_20MHZ_ACTIVITY: Allow activity in 20 MHz bandwidth, 4745 4717 * despite NO_IR configuration. 4718 + * @NL80211_RRF_NO_UHR: UHR operation not allowed 4746 4719 */ 4747 4720 enum nl80211_reg_rule_flags { 4748 4721 NL80211_RRF_NO_OFDM = 1 << 0, ··· 4770 4741 NL80211_RRF_NO_6GHZ_AFC_CLIENT = 1 << 23, 4771 4742 NL80211_RRF_ALLOW_6GHZ_VLP_AP = 1 << 24, 4772 4743 NL80211_RRF_ALLOW_20MHZ_ACTIVITY = 1 << 25, 4744 + NL80211_RRF_NO_UHR = 1 << 26, 4773 4745 }; 4774 4746 4775 4747 #define NL80211_RRF_PASSIVE_SCAN NL80211_RRF_NO_IR
+1 -1
net/mac80211/Makefile
··· 36 36 tdls.o \ 37 37 ocb.o \ 38 38 airtime.o \ 39 - eht.o 39 + eht.o uhr.o 40 40 41 41 mac80211-$(CONFIG_MAC80211_LEDS) += led.o 42 42 mac80211-$(CONFIG_MAC80211_DEBUGFS) += \
+19 -5
net/mac80211/cfg.c
··· 5 5 * Copyright 2006-2010 Johannes Berg <johannes@sipsolutions.net> 6 6 * Copyright 2013-2015 Intel Mobile Communications GmbH 7 7 * Copyright (C) 2015-2017 Intel Deutschland GmbH 8 - * Copyright (C) 2018-2025 Intel Corporation 8 + * Copyright (C) 2018-2026 Intel Corporation 9 9 */ 10 10 11 11 #include <linux/ieee80211.h> ··· 1608 1608 link_conf->eht_mu_beamformer = false; 1609 1609 } 1610 1610 1611 + if (params->uhr_oper) { 1612 + if (!link_conf->eht_support) 1613 + return -EOPNOTSUPP; 1614 + 1615 + link_conf->uhr_support = true; 1616 + } 1617 + 1611 1618 if (sdata->vif.type == NL80211_IFTYPE_AP && 1612 1619 params->mbssid_config.tx_wdev) { 1613 1620 err = ieee80211_set_ap_mbssid_options(sdata, ··· 1923 1916 1924 1917 if (sdata->wdev.links[link_id].cac_started) { 1925 1918 chandef = link_conf->chanreq.oper; 1926 - wiphy_delayed_work_cancel(wiphy, &link->dfs_cac_timer_work); 1919 + wiphy_hrtimer_work_cancel(wiphy, &link->dfs_cac_timer_work); 1927 1920 cfg80211_cac_event(sdata->dev, &chandef, 1928 1921 NL80211_RADAR_CAC_ABORTED, 1929 1922 GFP_KERNEL, link_id); ··· 2092 2085 params->vht_capa || 2093 2086 params->he_capa || 2094 2087 params->eht_capa || 2088 + params->uhr_capa || 2095 2089 params->s1g_capa || 2096 2090 params->opmode_notif_used; 2097 2091 ··· 2169 2161 params->he_capa_len, 2170 2162 params->eht_capa, 2171 2163 params->eht_capa_len, 2164 + link_sta); 2165 + 2166 + if (params->uhr_capa) 2167 + ieee80211_uhr_cap_ie_to_sta_uhr_cap(sdata, sband, 2168 + params->uhr_capa, 2169 + params->uhr_capa_len, 2172 2170 link_sta); 2173 2171 2174 2172 if (params->s1g_capa) ··· 3888 3874 if (err) 3889 3875 return err; 3890 3876 3891 - wiphy_delayed_work_queue(wiphy, &link_data->dfs_cac_timer_work, 3892 - msecs_to_jiffies(cac_time_ms)); 3877 + wiphy_hrtimer_work_queue(wiphy, &link_data->dfs_cac_timer_work, 3878 + ms_to_ktime(cac_time_ms)); 3893 3879 3894 3880 return 0; 3895 3881 } ··· 3908 3894 if (!link_data) 3909 3895 continue; 3910 3896 3911 - wiphy_delayed_work_cancel(wiphy, 3897 + wiphy_hrtimer_work_cancel(wiphy, 3912 3898 &link_data->dfs_cac_timer_work); 3913 3899 3914 3900 if (sdata->wdev.links[link_id].cac_started) {
+21
net/mac80211/driver-ops.h
··· 1772 1772 trace_drv_return_void(local); 1773 1773 } 1774 1774 1775 + static inline int drv_set_eml_op_mode(struct ieee80211_sub_if_data *sdata, 1776 + struct ieee80211_sta *sta, 1777 + struct ieee80211_eml_params *eml_params) 1778 + { 1779 + struct ieee80211_local *local = sdata->local; 1780 + int ret = -EOPNOTSUPP; 1781 + 1782 + might_sleep(); 1783 + lockdep_assert_wiphy(local->hw.wiphy); 1784 + 1785 + trace_drv_set_eml_op_mode(local, sdata, sta, eml_params->link_id, 1786 + eml_params->control, 1787 + eml_params->link_bitmap); 1788 + if (local->ops->set_eml_op_mode) 1789 + ret = local->ops->set_eml_op_mode(&local->hw, &sdata->vif, 1790 + sta, eml_params); 1791 + trace_drv_return_int(local, ret); 1792 + 1793 + return ret; 1794 + } 1795 + 1775 1796 #endif /* __MAC80211_DRIVER_OPS */
+175
net/mac80211/eht.c
··· 5 5 * Copyright(c) 2021-2025 Intel Corporation 6 6 */ 7 7 8 + #include "driver-ops.h" 8 9 #include "ieee80211_i.h" 9 10 10 11 void ··· 102 101 } 103 102 104 103 ieee80211_sta_recalc_aggregates(&link_sta->sta->sta); 104 + } 105 + 106 + static void 107 + ieee80211_send_eml_op_mode_notif(struct ieee80211_sub_if_data *sdata, 108 + struct ieee80211_mgmt *req, int opt_len) 109 + { 110 + int len = offsetofend(struct ieee80211_mgmt, u.action.u.eml_omn); 111 + struct ieee80211_local *local = sdata->local; 112 + struct ieee80211_mgmt *mgmt; 113 + struct sk_buff *skb; 114 + 115 + len += opt_len; /* optional len */ 116 + skb = dev_alloc_skb(local->tx_headroom + len); 117 + if (!skb) 118 + return; 119 + 120 + skb_reserve(skb, local->tx_headroom); 121 + mgmt = skb_put_zero(skb, len); 122 + mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT | 123 + IEEE80211_STYPE_ACTION); 124 + memcpy(mgmt->da, req->sa, ETH_ALEN); 125 + memcpy(mgmt->sa, sdata->vif.addr, ETH_ALEN); 126 + memcpy(mgmt->bssid, sdata->vif.addr, ETH_ALEN); 127 + 128 + mgmt->u.action.category = WLAN_CATEGORY_PROTECTED_EHT; 129 + mgmt->u.action.u.eml_omn.action_code = 130 + WLAN_PROTECTED_EHT_ACTION_EML_OP_MODE_NOTIF; 131 + mgmt->u.action.u.eml_omn.dialog_token = 132 + req->u.action.u.eml_omn.dialog_token; 133 + mgmt->u.action.u.eml_omn.control = req->u.action.u.eml_omn.control & 134 + ~(IEEE80211_EML_CTRL_EMLSR_PARAM_UPDATE | 135 + IEEE80211_EML_CTRL_INDEV_COEX_ACT); 136 + /* Copy optional fields from the received notification frame */ 137 + memcpy(mgmt->u.action.u.eml_omn.variable, 138 + req->u.action.u.eml_omn.variable, opt_len); 139 + 140 + ieee80211_tx_skb(sdata, skb); 141 + } 142 + 143 + void ieee80211_rx_eml_op_mode_notif(struct ieee80211_sub_if_data *sdata, 144 + struct sk_buff *skb) 145 + { 146 + int len = offsetofend(struct ieee80211_mgmt, u.action.u.eml_omn); 147 + enum nl80211_iftype type = ieee80211_vif_type_p2p(&sdata->vif); 148 + struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb); 149 + const struct wiphy_iftype_ext_capab *ift_ext_capa; 150 + struct ieee80211_mgmt *mgmt = (void *)skb->data; 151 + struct ieee80211_local *local = sdata->local; 152 + u8 control = mgmt->u.action.u.eml_omn.control; 153 + u8 *ptr = mgmt->u.action.u.eml_omn.variable; 154 + struct ieee80211_eml_params eml_params = { 155 + .link_id = status->link_id, 156 + }; 157 + struct sta_info *sta; 158 + int opt_len = 0; 159 + 160 + if (!ieee80211_vif_is_mld(&sdata->vif)) 161 + return; 162 + 163 + /* eMLSR and eMLMR can't be enabled at the same time */ 164 + if ((control & IEEE80211_EML_CTRL_EMLSR_MODE) && 165 + (control & IEEE80211_EML_CTRL_EMLMR_MODE)) 166 + return; 167 + 168 + if ((control & IEEE80211_EML_CTRL_EMLMR_MODE) && 169 + (control & IEEE80211_EML_CTRL_EMLSR_PARAM_UPDATE)) 170 + return; 171 + 172 + ift_ext_capa = cfg80211_get_iftype_ext_capa(local->hw.wiphy, type); 173 + if (!ift_ext_capa) 174 + return; 175 + 176 + if (!status->link_valid) 177 + return; 178 + 179 + sta = sta_info_get_bss(sdata, mgmt->sa); 180 + if (!sta) 181 + return; 182 + 183 + if (control & IEEE80211_EML_CTRL_EMLSR_MODE) { 184 + u8 emlsr_param_update_len; 185 + 186 + if (!(ift_ext_capa->eml_capabilities & 187 + IEEE80211_EML_CAP_EMLSR_SUPP)) 188 + return; 189 + 190 + opt_len += sizeof(__le16); /* eMLSR link_bitmap */ 191 + /* eMLSR param update field is not part of Notfication frame 192 + * sent by the AP to client so account it separately. 193 + */ 194 + emlsr_param_update_len = 195 + !!(control & IEEE80211_EML_CTRL_EMLSR_PARAM_UPDATE); 196 + 197 + if (skb->len < len + opt_len + emlsr_param_update_len) 198 + return; 199 + 200 + if (control & IEEE80211_EML_CTRL_EMLSR_PARAM_UPDATE) { 201 + u8 pad_delay, trans_delay; 202 + 203 + pad_delay = u8_get_bits(ptr[2], 204 + IEEE80211_EML_EMLSR_PAD_DELAY); 205 + if (pad_delay > 206 + IEEE80211_EML_CAP_EMLSR_PADDING_DELAY_256US) 207 + return; 208 + 209 + trans_delay = u8_get_bits(ptr[2], 210 + IEEE80211_EML_EMLSR_TRANS_DELAY); 211 + if (trans_delay > 212 + IEEE80211_EML_CAP_EMLSR_TRANSITION_DELAY_256US) 213 + return; 214 + 215 + /* Update sta padding and transition delay */ 216 + sta->sta.eml_cap = 217 + u8_replace_bits(sta->sta.eml_cap, 218 + pad_delay, 219 + IEEE80211_EML_CAP_EMLSR_PADDING_DELAY); 220 + sta->sta.eml_cap = 221 + u8_replace_bits(sta->sta.eml_cap, 222 + trans_delay, 223 + IEEE80211_EML_CAP_EMLSR_TRANSITION_DELAY); 224 + } 225 + } 226 + 227 + if (control & IEEE80211_EML_CTRL_EMLMR_MODE) { 228 + u8 mcs_map_size; 229 + int i; 230 + 231 + if (!(ift_ext_capa->eml_capabilities & 232 + IEEE80211_EML_CAP_EMLMR_SUPPORT)) 233 + return; 234 + 235 + opt_len += sizeof(__le16); /* eMLMR link_bitmap */ 236 + opt_len++; /* eMLMR mcs_map_count */ 237 + if (skb->len < len + opt_len) 238 + return; 239 + 240 + eml_params.emlmr_mcs_map_count = ptr[2]; 241 + if (eml_params.emlmr_mcs_map_count > 2) 242 + return; 243 + 244 + mcs_map_size = 3 * (1 + eml_params.emlmr_mcs_map_count); 245 + opt_len += mcs_map_size; 246 + if (skb->len < len + opt_len) 247 + return; 248 + 249 + for (i = 0; i < mcs_map_size; i++) { 250 + u8 rx_mcs, tx_mcs; 251 + 252 + rx_mcs = u8_get_bits(ptr[3 + i], 253 + IEEE80211_EML_EMLMR_RX_MCS_MAP); 254 + if (rx_mcs > 8) 255 + return; 256 + 257 + tx_mcs = u8_get_bits(ptr[3 + i], 258 + IEEE80211_EML_EMLMR_TX_MCS_MAP); 259 + if (tx_mcs > 8) 260 + return; 261 + } 262 + 263 + memcpy(eml_params.emlmr_mcs_map_bw, &ptr[3], mcs_map_size); 264 + } 265 + 266 + if ((control & IEEE80211_EML_CTRL_EMLSR_MODE) || 267 + (control & IEEE80211_EML_CTRL_EMLMR_MODE)) { 268 + eml_params.link_bitmap = get_unaligned_le16(ptr); 269 + if ((eml_params.link_bitmap & sdata->vif.active_links) != 270 + eml_params.link_bitmap) 271 + return; 272 + } 273 + 274 + if (drv_set_eml_op_mode(sdata, &sta->sta, &eml_params)) 275 + return; 276 + 277 + ieee80211_send_eml_op_mode_notif(sdata, mgmt, opt_len); 105 278 }
+20 -3
net/mac80211/ieee80211_i.h
··· 5 5 * Copyright 2006-2007 Jiri Benc <jbenc@suse.cz> 6 6 * Copyright 2007-2010 Johannes Berg <johannes@sipsolutions.net> 7 7 * Copyright 2013-2015 Intel Mobile Communications GmbH 8 - * Copyright (C) 2018-2025 Intel Corporation 8 + * Copyright (C) 2018-2026 Intel Corporation 9 9 */ 10 10 11 11 #ifndef IEEE80211_I_H ··· 394 394 IEEE80211_CONN_MODE_VHT, 395 395 IEEE80211_CONN_MODE_HE, 396 396 IEEE80211_CONN_MODE_EHT, 397 + IEEE80211_CONN_MODE_UHR, 397 398 }; 398 399 399 - #define IEEE80211_CONN_MODE_HIGHEST IEEE80211_CONN_MODE_EHT 400 + #define IEEE80211_CONN_MODE_HIGHEST IEEE80211_CONN_MODE_UHR 400 401 401 402 enum ieee80211_conn_bw_limit { 402 403 IEEE80211_CONN_BW_LIMIT_20, ··· 1100 1099 int ap_power_level; /* in dBm */ 1101 1100 1102 1101 bool radar_required; 1103 - struct wiphy_delayed_work dfs_cac_timer_work; 1102 + struct wiphy_hrtimer_work dfs_cac_timer_work; 1104 1103 1105 1104 union { 1106 1105 struct ieee80211_link_data_managed mgd; ··· 1825 1824 const struct ieee80211_multi_link_elem *ml_epcs; 1826 1825 const struct ieee80211_bandwidth_indication *bandwidth_indication; 1827 1826 const struct ieee80211_ttlm_elem *ttlm[IEEE80211_TTLM_MAX_CNT]; 1827 + const struct ieee80211_uhr_cap *uhr_cap; 1828 + const struct ieee80211_uhr_operation *uhr_operation; 1828 1829 1829 1830 /* not the order in the psd values is per element, not per chandef */ 1830 1831 struct ieee80211_parsed_tpe tpe; ··· 1851 1848 u8 country_elem_len; 1852 1849 u8 bssid_index_len; 1853 1850 u8 eht_cap_len; 1851 + u8 uhr_cap_len; 1852 + u8 uhr_operation_len; 1854 1853 1855 1854 /* mult-link element can be de-fragmented and thus u8 is not sufficient */ 1856 1855 size_t ml_basic_len; ··· 2696 2691 struct ieee80211_sub_if_data *sdata, 2697 2692 const struct ieee80211_supported_band *sband, 2698 2693 const struct ieee80211_conn_settings *conn); 2694 + int ieee80211_put_uhr_cap(struct sk_buff *skb, 2695 + struct ieee80211_sub_if_data *sdata, 2696 + const struct ieee80211_supported_band *sband); 2699 2697 int ieee80211_put_reg_conn(struct sk_buff *skb, 2700 2698 enum ieee80211_channel_flags flags); 2701 2699 ··· 2843 2835 2844 2836 u8 ieee80211_ie_len_eht_cap(struct ieee80211_sub_if_data *sdata); 2845 2837 2838 + void ieee80211_rx_eml_op_mode_notif(struct ieee80211_sub_if_data *sdata, 2839 + struct sk_buff *skb); 2846 2840 void 2847 2841 ieee80211_eht_cap_ie_to_sta_eht_cap(struct ieee80211_sub_if_data *sdata, 2848 2842 struct ieee80211_supported_band *sband, ··· 2875 2865 void ieee80211_process_ml_reconf_resp(struct ieee80211_sub_if_data *sdata, 2876 2866 struct ieee80211_mgmt *mgmt, size_t len); 2877 2867 void ieee80211_stop_mbssid(struct ieee80211_sub_if_data *sdata); 2868 + 2869 + void 2870 + ieee80211_uhr_cap_ie_to_sta_uhr_cap(struct ieee80211_sub_if_data *sdata, 2871 + struct ieee80211_supported_band *sband, 2872 + const struct ieee80211_uhr_cap *uhr_cap, 2873 + u8 uhr_cap_len, 2874 + struct link_sta_info *link_sta); 2878 2875 2879 2876 #if IS_ENABLED(CONFIG_MAC80211_KUNIT_TEST) 2880 2877 #define EXPORT_SYMBOL_IF_MAC80211_KUNIT(sym) EXPORT_SYMBOL_IF_KUNIT(sym)
+10 -2
net/mac80211/iface.c
··· 565 565 wiphy_work_cancel(local->hw.wiphy, &sdata->deflink.csa.finalize_work); 566 566 wiphy_work_cancel(local->hw.wiphy, 567 567 &sdata->deflink.color_change_finalize_work); 568 - wiphy_delayed_work_cancel(local->hw.wiphy, 568 + wiphy_hrtimer_work_cancel(local->hw.wiphy, 569 569 &sdata->deflink.dfs_cac_timer_work); 570 570 571 571 if (sdata->wdev.links[0].cac_started) { ··· 1668 1668 } 1669 1669 } else if (ieee80211_is_action(mgmt->frame_control) && 1670 1670 mgmt->u.action.category == WLAN_CATEGORY_PROTECTED_EHT) { 1671 - if (sdata->vif.type == NL80211_IFTYPE_STATION) { 1671 + if (sdata->vif.type == NL80211_IFTYPE_AP) { 1672 + switch (mgmt->u.action.u.eml_omn.action_code) { 1673 + case WLAN_PROTECTED_EHT_ACTION_EML_OP_MODE_NOTIF: 1674 + ieee80211_rx_eml_op_mode_notif(sdata, skb); 1675 + break; 1676 + default: 1677 + break; 1678 + } 1679 + } else if (sdata->vif.type == NL80211_IFTYPE_STATION) { 1672 1680 switch (mgmt->u.action.u.ttlm_req.action_code) { 1673 1681 case WLAN_PROTECTED_EHT_ACTION_TTLM_REQ: 1674 1682 ieee80211_process_neg_ttlm_req(sdata, mgmt,
+2 -2
net/mac80211/link.c
··· 116 116 ieee80211_color_change_finalize_work); 117 117 wiphy_delayed_work_init(&link->color_collision_detect_work, 118 118 ieee80211_color_collision_detection_work); 119 - wiphy_delayed_work_init(&link->dfs_cac_timer_work, 119 + wiphy_hrtimer_work_init(&link->dfs_cac_timer_work, 120 120 ieee80211_dfs_cac_timer_work); 121 121 122 122 if (!deflink) { ··· 155 155 &link->csa.finalize_work); 156 156 157 157 if (link->sdata->wdev.links[link->link_id].cac_started) { 158 - wiphy_delayed_work_cancel(link->sdata->local->hw.wiphy, 158 + wiphy_hrtimer_work_cancel(link->sdata->local->hw.wiphy, 159 159 &link->dfs_cac_timer_work); 160 160 cfg80211_cac_event(link->sdata->dev, 161 161 &link->conf->chanreq.oper,
+13 -2
net/mac80211/main.c
··· 5 5 * Copyright 2006-2007 Jiri Benc <jbenc@suse.cz> 6 6 * Copyright 2013-2014 Intel Mobile Communications GmbH 7 7 * Copyright (C) 2017 Intel Deutschland GmbH 8 - * Copyright (C) 2018-2025 Intel Corporation 8 + * Copyright (C) 2018-2026 Intel Corporation 9 9 */ 10 10 11 11 #include <net/mac80211.h> ··· 1123 1123 int result, i; 1124 1124 enum nl80211_band band; 1125 1125 int channels, max_bitrates; 1126 - bool supp_ht, supp_vht, supp_he, supp_eht, supp_s1g; 1126 + bool supp_ht, supp_vht, supp_he, supp_eht, supp_s1g, supp_uhr; 1127 1127 struct cfg80211_chan_def dflt_chandef = {}; 1128 1128 1129 1129 if (ieee80211_hw_check(hw, QUEUE_CONTROL) && ··· 1237 1237 supp_he = false; 1238 1238 supp_eht = false; 1239 1239 supp_s1g = false; 1240 + supp_uhr = false; 1240 1241 for (band = 0; band < NUM_NL80211_BANDS; band++) { 1241 1242 const struct ieee80211_sband_iftype_data *iftd; 1242 1243 struct ieee80211_supported_band *sband; ··· 1294 1293 1295 1294 supp_he = supp_he || iftd->he_cap.has_he; 1296 1295 supp_eht = supp_eht || iftd->eht_cap.has_eht; 1296 + supp_uhr = supp_uhr || iftd->uhr_cap.has_uhr; 1297 1297 1298 1298 if (band == NL80211_BAND_2GHZ) 1299 1299 he_40_mhz_cap = ··· 1325 1323 1326 1324 /* EHT requires HE support */ 1327 1325 if (WARN_ON(supp_eht && !supp_he)) 1326 + return -EINVAL; 1327 + 1328 + /* UHR requires EHT support */ 1329 + if (WARN_ON(supp_uhr && !supp_eht)) 1328 1330 return -EINVAL; 1329 1331 1330 1332 if (!sband->ht_cap.ht_supported) ··· 1442 1436 sizeof(struct ieee80211_eht_mcs_nss_supp) + 1443 1437 IEEE80211_EHT_PPE_THRES_MAX_LEN; 1444 1438 } 1439 + 1440 + if (supp_uhr) 1441 + local->scan_ies_len += 1442 + 3 + sizeof(struct ieee80211_uhr_cap) + 1443 + sizeof(struct ieee80211_uhr_cap_phy); 1445 1444 1446 1445 if (!local->ops->hw_scan) { 1447 1446 /* For hw_scan, driver needs to set these up. */
+107 -8
net/mac80211/mlme.c
··· 162 162 const struct ieee80211_vht_operation *vht_oper = elems->vht_operation; 163 163 const struct ieee80211_he_operation *he_oper = elems->he_operation; 164 164 const struct ieee80211_eht_operation *eht_oper = elems->eht_operation; 165 + const struct ieee80211_uhr_operation *uhr_oper = elems->uhr_operation; 165 166 struct ieee80211_supported_band *sband = 166 167 sdata->local->hw.wiphy->bands[channel->band]; 167 168 struct cfg80211_chan_def vht_chandef; ··· 193 192 194 193 /* get special 6 GHz case out of the way */ 195 194 if (sband->band == NL80211_BAND_6GHZ) { 196 - enum ieee80211_conn_mode mode = IEEE80211_CONN_MODE_EHT; 195 + enum ieee80211_conn_mode mode = IEEE80211_CONN_MODE_HIGHEST; 197 196 198 197 /* this is an error */ 199 198 if (conn->mode < IEEE80211_CONN_MODE_HE) ··· 216 215 return IEEE80211_CONN_MODE_LEGACY; 217 216 } 218 217 219 - return mode; 218 + if (mode <= IEEE80211_CONN_MODE_EHT) 219 + return mode; 220 + goto check_uhr; 220 221 } 221 222 222 223 /* now we have the progression HT, VHT, ... */ ··· 343 340 *chandef = eht_chandef; 344 341 } 345 342 346 - return IEEE80211_CONN_MODE_EHT; 343 + check_uhr: 344 + if (conn->mode < IEEE80211_CONN_MODE_UHR || !uhr_oper) 345 + return IEEE80211_CONN_MODE_EHT; 346 + 347 + /* 348 + * In beacons we don't have all the data - but we know the size was OK, 349 + * so if the size is valid as a non-beacon case, we have more data and 350 + * can validate the NPCA parameters. 351 + */ 352 + if (ieee80211_uhr_oper_size_ok((const void *)uhr_oper, 353 + elems->uhr_operation_len, 354 + false)) { 355 + struct cfg80211_chan_def npca_chandef = *chandef; 356 + const struct ieee80211_uhr_npca_info *npca; 357 + const __le16 *dis_subch_bmap; 358 + u16 punct = chandef->punctured, npca_punct; 359 + 360 + npca = ieee80211_uhr_npca_info(uhr_oper); 361 + if (npca) { 362 + int width = cfg80211_chandef_get_width(chandef); 363 + u8 offs = le32_get_bits(npca->params, 364 + IEEE80211_UHR_NPCA_PARAMS_PRIMARY_CHAN_OFFS); 365 + u32 cf1 = chandef->center_freq1; 366 + bool pri_upper, npca_upper; 367 + 368 + pri_upper = chandef->chan->center_freq > cf1; 369 + npca_upper = 20 * offs >= width / 2; 370 + 371 + if (20 * offs >= cfg80211_chandef_get_width(chandef) || 372 + pri_upper == npca_upper) { 373 + sdata_info(sdata, 374 + "AP UHR NPCA primary channel invalid, disabling UHR\n"); 375 + return IEEE80211_CONN_MODE_EHT; 376 + } 377 + } 378 + 379 + dis_subch_bmap = ieee80211_uhr_npca_dis_subch_bitmap(uhr_oper); 380 + 381 + if (dis_subch_bmap) { 382 + npca_punct = get_unaligned_le16(dis_subch_bmap); 383 + npca_chandef.punctured = npca_punct; 384 + } 385 + 386 + /* 387 + * must be a valid puncturing pattern for this channel as 388 + * well as puncturing all subchannels that are already in 389 + * the disabled subchannel bitmap on the primary channel 390 + */ 391 + if (!cfg80211_chandef_valid(&npca_chandef) || 392 + ((punct & npca_punct) != punct)) { 393 + sdata_info(sdata, 394 + "AP UHR NPCA disabled subchannel bitmap invalid, disabling UHR\n"); 395 + return IEEE80211_CONN_MODE_EHT; 396 + } 397 + } 398 + 399 + return IEEE80211_CONN_MODE_UHR; 347 400 } 348 401 349 402 static bool ··· 1150 1091 IEEE80211_CONN_BW_LIMIT_160); 1151 1092 break; 1152 1093 case IEEE80211_CONN_MODE_EHT: 1094 + case IEEE80211_CONN_MODE_UHR: 1153 1095 conn->bw_limit = min_t(enum ieee80211_conn_bw_limit, 1154 1096 conn->bw_limit, 1155 1097 IEEE80211_CONN_BW_LIMIT_320); ··· 1168 1108 set_bit(BSS_MEMBERSHIP_SELECTOR_HE_PHY, sta_selectors); 1169 1109 if (conn->mode >= IEEE80211_CONN_MODE_EHT) 1170 1110 set_bit(BSS_MEMBERSHIP_SELECTOR_EHT_PHY, sta_selectors); 1111 + if (conn->mode >= IEEE80211_CONN_MODE_UHR) 1112 + set_bit(BSS_MEMBERSHIP_SELECTOR_UHR_PHY, sta_selectors); 1171 1113 1172 1114 /* 1173 1115 * We do not support EPD or GLK so never add them. ··· 1216 1154 conn->bw_limit, 1217 1155 IEEE80211_CONN_BW_LIMIT_160); 1218 1156 } 1157 + 1158 + if (conn->mode >= IEEE80211_CONN_MODE_UHR && 1159 + !cfg80211_chandef_usable(sdata->wdev.wiphy, &chanreq->oper, 1160 + IEEE80211_CHAN_NO_UHR)) 1161 + conn->mode = IEEE80211_CONN_MODE_EHT; 1219 1162 1220 1163 if (chanreq->oper.width != ap_chandef->width || ap_mode != conn->mode) 1221 1164 link_id_info(sdata, link_id, ··· 1951 1884 1952 1885 /* 1953 1886 * careful - need to know about all the present elems before 1954 - * calling ieee80211_assoc_add_ml_elem(), so add this one if 1955 - * we're going to put it after the ML element 1887 + * calling ieee80211_assoc_add_ml_elem(), so add these if 1888 + * we're going to put them after the ML element 1956 1889 */ 1957 1890 if (assoc_data->link[link_id].conn.mode >= IEEE80211_CONN_MODE_EHT) 1958 1891 ADD_PRESENT_EXT_ELEM(WLAN_EID_EXT_EHT_CAPABILITY); 1892 + if (assoc_data->link[link_id].conn.mode >= IEEE80211_CONN_MODE_UHR) 1893 + ADD_PRESENT_EXT_ELEM(WLAN_EID_EXT_UHR_CAPA); 1959 1894 1960 1895 if (link_id == assoc_data->assoc_link_id) 1961 1896 ieee80211_assoc_add_ml_elem(sdata, skb, orig_capab, ext_capa, ··· 1969 1900 if (assoc_data->link[link_id].conn.mode >= IEEE80211_CONN_MODE_EHT) 1970 1901 ieee80211_put_eht_cap(skb, sdata, sband, 1971 1902 &assoc_data->link[link_id].conn); 1903 + 1904 + if (assoc_data->link[link_id].conn.mode >= IEEE80211_CONN_MODE_UHR) 1905 + ieee80211_put_uhr_cap(skb, sdata, sband); 1972 1906 1973 1907 if (sband->band == NL80211_BAND_S1GHZ) { 1974 1908 ieee80211_add_aid_request_ie(sdata, skb); ··· 2206 2134 size += 2 + 1 + sizeof(struct ieee80211_eht_cap_elem) + 2207 2135 sizeof(struct ieee80211_eht_mcs_nss_supp) + 2208 2136 IEEE80211_EHT_PPE_THRES_MAX_LEN; 2137 + 2138 + size += 2 + 1 + sizeof(struct ieee80211_uhr_cap) + 2139 + sizeof(struct ieee80211_uhr_cap_phy); 2209 2140 2210 2141 return size; 2211 2142 } ··· 5606 5531 bss_conf->epcs_support = false; 5607 5532 } 5608 5533 5534 + if (elems->uhr_operation && elems->uhr_cap && 5535 + link->u.mgd.conn.mode >= IEEE80211_CONN_MODE_UHR) { 5536 + ieee80211_uhr_cap_ie_to_sta_uhr_cap(sdata, sband, 5537 + elems->uhr_cap, 5538 + elems->uhr_cap_len, 5539 + link_sta); 5540 + 5541 + bss_conf->uhr_support = link_sta->pub->uhr_cap.has_uhr; 5542 + } else { 5543 + bss_conf->uhr_support = false; 5544 + } 5545 + 5609 5546 if (elems->s1g_oper && 5610 5547 link->u.mgd.conn.mode == IEEE80211_CONN_MODE_S1G && 5611 5548 elems->s1g_capab) ··· 5908 5821 bool is_6ghz = sband->band == NL80211_BAND_6GHZ; 5909 5822 const struct ieee80211_sta_he_cap *he_cap; 5910 5823 const struct ieee80211_sta_eht_cap *eht_cap; 5824 + const struct ieee80211_sta_uhr_cap *uhr_cap; 5911 5825 struct ieee80211_sta_vht_cap vht_cap; 5912 5826 5913 5827 if (sband->band == NL80211_BAND_S1GHZ) { ··· 6084 5996 "no EHT support, limiting to HE\n"); 6085 5997 goto out; 6086 5998 } 6087 - 6088 - /* we have EHT */ 6089 - 6090 5999 conn->mode = IEEE80211_CONN_MODE_EHT; 6091 6000 6092 6001 /* check bandwidth */ ··· 6093 6008 else if (is_6ghz) 6094 6009 mlme_link_id_dbg(sdata, link_id, 6095 6010 "no EHT 320 MHz cap in 6 GHz, limiting to 160 MHz\n"); 6011 + 6012 + if (req && req->flags & ASSOC_REQ_DISABLE_UHR) { 6013 + mlme_link_id_dbg(sdata, link_id, 6014 + "UHR disabled by flag, limiting to EHT\n"); 6015 + goto out; 6016 + } 6017 + 6018 + uhr_cap = ieee80211_get_uhr_iftype_cap_vif(sband, &sdata->vif); 6019 + if (!uhr_cap) { 6020 + mlme_link_id_dbg(sdata, link_id, 6021 + "no UHR support, limiting to EHT\n"); 6022 + goto out; 6023 + } 6024 + conn->mode = IEEE80211_CONN_MODE_UHR; 6096 6025 6097 6026 out: 6098 6027 mlme_link_id_dbg(sdata, link_id,
+21 -1
net/mac80211/parse.c
··· 6 6 * Copyright 2007 Johannes Berg <johannes@sipsolutions.net> 7 7 * Copyright 2013-2014 Intel Mobile Communications GmbH 8 8 * Copyright (C) 2015-2017 Intel Deutschland GmbH 9 - * Copyright (C) 2018-2025 Intel Corporation 9 + * Copyright (C) 2018-2026 Intel Corporation 10 10 * 11 11 * element parsing for mac80211 12 12 */ ··· 187 187 elems->ttlm_num < ARRAY_SIZE(elems->ttlm)) { 188 188 elems->ttlm[elems->ttlm_num] = (void *)data; 189 189 elems->ttlm_num++; 190 + } 191 + break; 192 + case WLAN_EID_EXT_UHR_OPER: 193 + if (params->mode < IEEE80211_CONN_MODE_UHR) 194 + break; 195 + calc_crc = true; 196 + if (ieee80211_uhr_oper_size_ok(data, len, 197 + params->type == (IEEE80211_FTYPE_MGMT | 198 + IEEE80211_STYPE_BEACON))) { 199 + elems->uhr_operation = data; 200 + elems->uhr_operation_len = len; 201 + } 202 + break; 203 + case WLAN_EID_EXT_UHR_CAPA: 204 + if (params->mode < IEEE80211_CONN_MODE_UHR) 205 + break; 206 + calc_crc = true; 207 + if (ieee80211_uhr_capa_size_ok(data, len, true)) { 208 + elems->uhr_cap = data; 209 + elems->uhr_cap_len = len; 190 210 } 191 211 break; 192 212 }
+34
net/mac80211/rx.c
··· 3928 3928 u.action.u.epcs)) 3929 3929 goto invalid; 3930 3930 goto queue; 3931 + case WLAN_PROTECTED_EHT_ACTION_EML_OP_MODE_NOTIF: 3932 + if (sdata->vif.type != NL80211_IFTYPE_AP) 3933 + break; 3934 + 3935 + if (len < offsetofend(typeof(*mgmt), 3936 + u.action.u.eml_omn)) 3937 + goto invalid; 3938 + goto queue; 3931 3939 default: 3932 3940 break; 3933 3941 } ··· 5524 5516 status->eht.gi > NL80211_RATE_INFO_EHT_GI_3_2, 5525 5517 "Rate marked as an EHT rate but data is invalid: MCS:%d, NSS:%d, GI:%d\n", 5526 5518 status->rate_idx, status->nss, status->eht.gi)) 5519 + goto drop; 5520 + break; 5521 + case RX_ENC_UHR: 5522 + if (WARN_ONCE(!(status->rate_idx <= 15 || 5523 + status->rate_idx == 17 || 5524 + status->rate_idx == 19 || 5525 + status->rate_idx == 20 || 5526 + status->rate_idx == 23) || 5527 + !status->nss || 5528 + status->nss > 8 || 5529 + status->uhr.gi > NL80211_RATE_INFO_EHT_GI_3_2, 5530 + "Rate marked as a UHR rate but data is invalid: MCS:%d, NSS:%d, GI:%d\n", 5531 + status->rate_idx, status->nss, status->uhr.gi)) 5532 + goto drop; 5533 + if (WARN_ONCE(status->uhr.elr && 5534 + (status->nss != 1 || status->rate_idx > 1 || 5535 + status->uhr.gi != NL80211_RATE_INFO_EHT_GI_1_6 || 5536 + status->bw != RATE_INFO_BW_20 || status->uhr.im), 5537 + "bad UHR ELR MCS MCS:%d, NSS:%d, GI:%d, BW:%d, IM:%d\n", 5538 + status->rate_idx, status->nss, status->uhr.gi, 5539 + status->bw, status->uhr.im)) 5540 + goto drop; 5541 + if (WARN_ONCE(status->uhr.im && 5542 + (status->nss != 1 || status->rate_idx == 15), 5543 + "bad UHR IM MCS MCS:%d, NSS:%d\n", 5544 + status->rate_idx, status->nss)) 5527 5545 goto drop; 5528 5546 break; 5529 5547 default:
+12 -1
net/mac80211/sta_info.c
··· 4 4 * Copyright 2006-2007 Jiri Benc <jbenc@suse.cz> 5 5 * Copyright 2013-2014 Intel Mobile Communications GmbH 6 6 * Copyright (C) 2015 - 2017 Intel Deutschland GmbH 7 - * Copyright (C) 2018-2025 Intel Corporation 7 + * Copyright (C) 2018-2026 Intel Corporation 8 8 */ 9 9 10 10 #include <linux/module.h> ··· 2566 2566 rinfo->nss = STA_STATS_GET(EHT_NSS, rate); 2567 2567 rinfo->eht_gi = STA_STATS_GET(EHT_GI, rate); 2568 2568 rinfo->eht_ru_alloc = STA_STATS_GET(EHT_RU, rate); 2569 + break; 2570 + case STA_STATS_RATE_TYPE_UHR: 2571 + rinfo->flags = RATE_INFO_FLAGS_UHR_MCS; 2572 + rinfo->mcs = STA_STATS_GET(UHR_MCS, rate); 2573 + rinfo->nss = STA_STATS_GET(UHR_NSS, rate); 2574 + rinfo->eht_gi = STA_STATS_GET(UHR_GI, rate); 2575 + rinfo->eht_ru_alloc = STA_STATS_GET(UHR_RU, rate); 2576 + if (STA_STATS_GET(UHR_ELR, rate)) 2577 + rinfo->flags |= RATE_INFO_FLAGS_UHR_ELR_MCS; 2578 + if (STA_STATS_GET(UHR_IM, rate)) 2579 + rinfo->flags |= RATE_INFO_FLAGS_UHR_IM; 2569 2580 break; 2570 2581 } 2571 2582 }
+60 -20
net/mac80211/sta_info.h
··· 3 3 * Copyright 2002-2005, Devicescape Software, Inc. 4 4 * Copyright 2013-2014 Intel Mobile Communications GmbH 5 5 * Copyright(c) 2015-2017 Intel Deutschland GmbH 6 - * Copyright(c) 2020-2024 Intel Corporation 6 + * Copyright(c) 2020-2026 Intel Corporation 7 7 */ 8 8 9 9 #ifndef STA_INFO_H ··· 1009 1009 STA_STATS_RATE_TYPE_HE, 1010 1010 STA_STATS_RATE_TYPE_S1G, 1011 1011 STA_STATS_RATE_TYPE_EHT, 1012 + STA_STATS_RATE_TYPE_UHR, 1012 1013 }; 1013 1014 1014 - #define STA_STATS_FIELD_HT_MCS GENMASK( 7, 0) 1015 - #define STA_STATS_FIELD_LEGACY_IDX GENMASK( 3, 0) 1016 - #define STA_STATS_FIELD_LEGACY_BAND GENMASK( 7, 4) 1017 - #define STA_STATS_FIELD_VHT_MCS GENMASK( 3, 0) 1018 - #define STA_STATS_FIELD_VHT_NSS GENMASK( 7, 4) 1019 - #define STA_STATS_FIELD_HE_MCS GENMASK( 3, 0) 1020 - #define STA_STATS_FIELD_HE_NSS GENMASK( 7, 4) 1021 - #define STA_STATS_FIELD_EHT_MCS GENMASK( 3, 0) 1022 - #define STA_STATS_FIELD_EHT_NSS GENMASK( 7, 4) 1023 - #define STA_STATS_FIELD_BW GENMASK(12, 8) 1024 - #define STA_STATS_FIELD_SGI GENMASK(13, 13) 1025 - #define STA_STATS_FIELD_TYPE GENMASK(16, 14) 1026 - #define STA_STATS_FIELD_HE_RU GENMASK(19, 17) 1027 - #define STA_STATS_FIELD_HE_GI GENMASK(21, 20) 1028 - #define STA_STATS_FIELD_HE_DCM GENMASK(22, 22) 1029 - #define STA_STATS_FIELD_EHT_RU GENMASK(20, 17) 1030 - #define STA_STATS_FIELD_EHT_GI GENMASK(22, 21) 1015 + /* common */ 1016 + #define STA_STATS_FIELD_TYPE 0x0000000F 1017 + #define STA_STATS_FIELD_BW 0x000001F0 1018 + #define STA_STATS_FIELD_RESERVED 0x00000E00 1019 + 1020 + /* STA_STATS_RATE_TYPE_LEGACY */ 1021 + #define STA_STATS_FIELD_LEGACY_IDX 0x0000F000 1022 + #define STA_STATS_FIELD_LEGACY_BAND 0x000F0000 1023 + 1024 + /* STA_STATS_RATE_TYPE_HT */ 1025 + #define STA_STATS_FIELD_HT_MCS 0x000FF000 1026 + 1027 + /* STA_STATS_RATE_TYPE_VHT */ 1028 + #define STA_STATS_FIELD_VHT_MCS 0x0000F000 1029 + #define STA_STATS_FIELD_VHT_NSS 0x000F0000 1030 + 1031 + /* HT & VHT */ 1032 + #define STA_STATS_FIELD_SGI 0x00100000 1033 + 1034 + /* STA_STATS_RATE_TYPE_HE */ 1035 + #define STA_STATS_FIELD_HE_MCS 0x0000F000 1036 + #define STA_STATS_FIELD_HE_NSS 0x000F0000 1037 + #define STA_STATS_FIELD_HE_RU 0x00700000 1038 + #define STA_STATS_FIELD_HE_GI 0x01800000 1039 + #define STA_STATS_FIELD_HE_DCM 0x02000000 1040 + 1041 + /* STA_STATS_RATE_TYPE_EHT */ 1042 + #define STA_STATS_FIELD_EHT_MCS 0x0000F000 1043 + #define STA_STATS_FIELD_EHT_NSS 0x000F0000 1044 + #define STA_STATS_FIELD_EHT_RU 0x00F00000 1045 + #define STA_STATS_FIELD_EHT_GI 0x03000000 1046 + 1047 + /* STA_STATS_RATE_TYPE_UHR */ 1048 + #define STA_STATS_FIELD_UHR_MCS 0x0001F000 1049 + #define STA_STATS_FIELD_UHR_NSS 0x001E0000 1050 + #define STA_STATS_FIELD_UHR_RU 0x01E00000 1051 + #define STA_STATS_FIELD_UHR_GI 0x06000000 1052 + #define STA_STATS_FIELD_UHR_ELR 0x08000000 1053 + #define STA_STATS_FIELD_UHR_IM 0x10000000 1054 + 1031 1055 1032 1056 #define STA_STATS_FIELD(_n, _v) FIELD_PREP(STA_STATS_FIELD_ ## _n, _v) 1033 1057 #define STA_STATS_GET(_n, _v) FIELD_GET(STA_STATS_FIELD_ ## _n, _v) ··· 1064 1040 1065 1041 r = STA_STATS_FIELD(BW, s->bw); 1066 1042 1067 - if (s->enc_flags & RX_ENC_FLAG_SHORT_GI) 1068 - r |= STA_STATS_FIELD(SGI, 1); 1043 + switch (s->encoding) { 1044 + case RX_ENC_HT: 1045 + case RX_ENC_VHT: 1046 + if (s->enc_flags & RX_ENC_FLAG_SHORT_GI) 1047 + r |= STA_STATS_FIELD(SGI, 1); 1048 + break; 1049 + default: 1050 + break; 1051 + } 1069 1052 1070 1053 switch (s->encoding) { 1071 1054 case RX_ENC_VHT: ··· 1103 1072 r |= STA_STATS_FIELD(EHT_MCS, s->rate_idx); 1104 1073 r |= STA_STATS_FIELD(EHT_GI, s->eht.gi); 1105 1074 r |= STA_STATS_FIELD(EHT_RU, s->eht.ru); 1075 + break; 1076 + case RX_ENC_UHR: 1077 + r |= STA_STATS_FIELD(TYPE, STA_STATS_RATE_TYPE_UHR); 1078 + r |= STA_STATS_FIELD(UHR_NSS, s->nss); 1079 + r |= STA_STATS_FIELD(UHR_MCS, s->rate_idx); 1080 + r |= STA_STATS_FIELD(UHR_GI, s->uhr.gi); 1081 + r |= STA_STATS_FIELD(UHR_RU, s->uhr.ru); 1082 + r |= STA_STATS_FIELD(UHR_ELR, s->uhr.elr); 1083 + r |= STA_STATS_FIELD(UHR_IM, s->uhr.im); 1106 1084 break; 1107 1085 default: 1108 1086 WARN_ON(1);
+32
net/mac80211/trace.h
··· 3353 3353 ) 3354 3354 ); 3355 3355 3356 + TRACE_EVENT(drv_set_eml_op_mode, 3357 + TP_PROTO(struct ieee80211_local *local, 3358 + struct ieee80211_sub_if_data *sdata, 3359 + struct ieee80211_sta *sta, 3360 + unsigned int link_id, 3361 + u8 control, u16 link_bitmap), 3362 + 3363 + TP_ARGS(local, sdata, sta, link_id, control, link_bitmap), 3364 + 3365 + TP_STRUCT__entry(LOCAL_ENTRY 3366 + VIF_ENTRY 3367 + STA_ENTRY 3368 + __field(u32, link_id) 3369 + __field(u8, control) 3370 + __field(u16, link_bitmap)), 3371 + 3372 + TP_fast_assign(LOCAL_ASSIGN; 3373 + VIF_ASSIGN; 3374 + STA_NAMED_ASSIGN(sta); 3375 + __entry->link_id = link_id; 3376 + __entry->control = control; 3377 + __entry->link_bitmap = link_bitmap; 3378 + ), 3379 + 3380 + TP_printk( 3381 + LOCAL_PR_FMT VIF_PR_FMT STA_PR_FMT 3382 + " (link:%d control:%02x link_bitmap:%04x)", 3383 + LOCAL_PR_ARG, VIF_PR_ARG, STA_PR_ARG, __entry->link_id, 3384 + __entry->control, __entry->link_bitmap 3385 + ) 3386 + ); 3387 + 3356 3388 #endif /* !__MAC80211_DRIVER_TRACE || TRACE_HEADER_MULTI_READ */ 3357 3389 3358 3390 #undef TRACE_INCLUDE_PATH
+30
net/mac80211/uhr.c
··· 1 + // SPDX-License-Identifier: GPL-2.0-only 2 + /* 3 + * UHR handling 4 + * 5 + * Copyright(c) 2025-2026 Intel Corporation 6 + */ 7 + 8 + #include "ieee80211_i.h" 9 + 10 + void 11 + ieee80211_uhr_cap_ie_to_sta_uhr_cap(struct ieee80211_sub_if_data *sdata, 12 + struct ieee80211_supported_band *sband, 13 + const struct ieee80211_uhr_cap *uhr_cap, 14 + u8 uhr_cap_len, 15 + struct link_sta_info *link_sta) 16 + { 17 + struct ieee80211_sta_uhr_cap *sta_uhr_cap = &link_sta->pub->uhr_cap; 18 + bool from_ap; 19 + 20 + memset(sta_uhr_cap, 0, sizeof(*sta_uhr_cap)); 21 + 22 + if (!ieee80211_get_uhr_iftype_cap_vif(sband, &sdata->vif)) 23 + return; 24 + 25 + sta_uhr_cap->has_uhr = true; 26 + 27 + sta_uhr_cap->mac = uhr_cap->mac; 28 + from_ap = sdata->vif.type == NL80211_IFTYPE_STATION; 29 + sta_uhr_cap->phy = *ieee80211_uhr_phy_cap(uhr_cap, from_ap); 30 + }
+36 -2
net/mac80211/util.c
··· 6 6 * Copyright 2007 Johannes Berg <johannes@sipsolutions.net> 7 7 * Copyright 2013-2014 Intel Mobile Communications GmbH 8 8 * Copyright (C) 2015-2017 Intel Deutschland GmbH 9 - * Copyright (C) 2018-2025 Intel Corporation 9 + * Copyright (C) 2018-2026 Intel Corporation 10 10 * 11 11 * utilities for mac80211 12 12 */ ··· 1420 1420 err = ieee80211_put_he_6ghz_cap(skb, sdata, IEEE80211_SMPS_OFF); 1421 1421 if (err) 1422 1422 return err; 1423 + 1424 + if (cfg80211_any_usable_channels(local->hw.wiphy, BIT(sband->band), 1425 + IEEE80211_CHAN_NO_UHR)) { 1426 + err = ieee80211_put_uhr_cap(skb, sdata, sband); 1427 + if (err) 1428 + return err; 1429 + } 1423 1430 1424 1431 /* 1425 1432 * If adding more here, adjust code in main.c ··· 3604 3597 if (ctx && &ctx->conf != chanctx_conf) 3605 3598 continue; 3606 3599 3607 - wiphy_delayed_work_cancel(local->hw.wiphy, 3600 + wiphy_hrtimer_work_cancel(local->hw.wiphy, 3608 3601 &link->dfs_cac_timer_work); 3609 3602 3610 3603 if (!sdata->wdev.links[link_id].cac_started) ··· 4534 4527 return 0; 4535 4528 } 4536 4529 4530 + int ieee80211_put_uhr_cap(struct sk_buff *skb, 4531 + struct ieee80211_sub_if_data *sdata, 4532 + const struct ieee80211_supported_band *sband) 4533 + { 4534 + const struct ieee80211_sta_uhr_cap *uhr_cap = 4535 + ieee80211_get_uhr_iftype_cap_vif(sband, &sdata->vif); 4536 + int len; 4537 + 4538 + if (!uhr_cap) 4539 + return 0; 4540 + 4541 + len = 2 + 1 + sizeof(struct ieee80211_uhr_cap) + 4542 + sizeof(struct ieee80211_uhr_cap_phy); 4543 + 4544 + if (skb_tailroom(skb) < len) 4545 + return -ENOBUFS; 4546 + 4547 + skb_put_u8(skb, WLAN_EID_EXTENSION); 4548 + skb_put_u8(skb, len - 2); 4549 + skb_put_u8(skb, WLAN_EID_EXT_UHR_CAPA); 4550 + skb_put_data(skb, &uhr_cap->mac, sizeof(uhr_cap->mac)); 4551 + skb_put_data(skb, &uhr_cap->phy, sizeof(uhr_cap->phy)); 4552 + 4553 + return 0; 4554 + } 4555 + 4537 4556 const char *ieee80211_conn_mode_str(enum ieee80211_conn_mode mode) 4538 4557 { 4539 4558 static const char * const modes[] = { ··· 4569 4536 [IEEE80211_CONN_MODE_VHT] = "VHT", 4570 4537 [IEEE80211_CONN_MODE_HE] = "HE", 4571 4538 [IEEE80211_CONN_MODE_EHT] = "EHT", 4539 + [IEEE80211_CONN_MODE_UHR] = "UHR", 4572 4540 }; 4573 4541 4574 4542 if (WARN_ON(mode >= ARRAY_SIZE(modes)))
+98 -4
net/wireless/nl80211.c
··· 332 332 return 0; 333 333 } 334 334 335 + static int validate_uhr_capa(const struct nlattr *attr, 336 + struct netlink_ext_ack *extack) 337 + { 338 + const u8 *data = nla_data(attr); 339 + unsigned int len = nla_len(attr); 340 + 341 + return ieee80211_uhr_capa_size_ok(data, len, false); 342 + } 343 + 335 344 /* policy for the attributes */ 336 345 static const struct nla_policy nl80211_policy[NUM_NL80211_ATTR]; 337 346 ··· 943 934 [NL80211_ATTR_BSS_PARAM] = { .type = NLA_FLAG }, 944 935 [NL80211_ATTR_S1G_PRIMARY_2MHZ] = { .type = NLA_FLAG }, 945 936 [NL80211_ATTR_EPP_PEER] = { .type = NLA_FLAG }, 937 + [NL80211_ATTR_UHR_CAPABILITY] = 938 + NLA_POLICY_VALIDATE_FN(NLA_BINARY, validate_uhr_capa, 255), 939 + [NL80211_ATTR_DISABLE_UHR] = { .type = NLA_FLAG }, 946 940 }; 947 941 948 942 /* policy for the key attributes */ ··· 1330 1318 goto nla_put_failure; 1331 1319 if ((chan->flags & IEEE80211_CHAN_S1G_NO_PRIMARY) && 1332 1320 nla_put_flag(msg, NL80211_FREQUENCY_ATTR_S1G_NO_PRIMARY)) 1321 + goto nla_put_failure; 1322 + if ((chan->flags & IEEE80211_CHAN_NO_UHR) && 1323 + nla_put_flag(msg, NL80211_FREQUENCY_ATTR_NO_UHR)) 1333 1324 goto nla_put_failure; 1334 1325 } 1335 1326 ··· 1969 1954 { 1970 1955 const struct ieee80211_sta_he_cap *he_cap = &iftdata->he_cap; 1971 1956 const struct ieee80211_sta_eht_cap *eht_cap = &iftdata->eht_cap; 1957 + const struct ieee80211_sta_uhr_cap *uhr_cap = &iftdata->uhr_cap; 1972 1958 1973 1959 if (nl80211_put_iftypes(msg, NL80211_BAND_IFTYPE_ATTR_IFTYPES, 1974 1960 iftdata->types_mask)) ··· 2018 2002 mcs_nss_size, &eht_cap->eht_mcs_nss_supp) || 2019 2003 nla_put(msg, NL80211_BAND_IFTYPE_ATTR_EHT_CAP_PPE, 2020 2004 ppe_thresh_size, eht_cap->eht_ppe_thres)) 2005 + return -ENOBUFS; 2006 + } 2007 + 2008 + if (uhr_cap->has_uhr) { 2009 + if (nla_put(msg, NL80211_BAND_IFTYPE_ATTR_UHR_CAP_MAC, 2010 + sizeof(uhr_cap->mac), &uhr_cap->mac) || 2011 + nla_put(msg, NL80211_BAND_IFTYPE_ATTR_UHR_CAP_PHY, 2012 + sizeof(uhr_cap->phy), &uhr_cap->phy)) 2021 2013 return -ENOBUFS; 2022 2014 } 2023 2015 ··· 6486 6462 cap->datalen - 1)) 6487 6463 return -EINVAL; 6488 6464 } 6465 + 6466 + cap = cfg80211_find_ext_elem(WLAN_EID_EXT_UHR_OPER, ies, ies_len); 6467 + if (cap) { 6468 + if (!cap->datalen) 6469 + return -EINVAL; 6470 + params->uhr_oper = (void *)(cap->data + 1); 6471 + if (!ieee80211_uhr_oper_size_ok((const u8 *)params->uhr_oper, 6472 + cap->datalen - 1, true)) 6473 + return -EINVAL; 6474 + } 6475 + 6489 6476 return 0; 6490 6477 } 6491 6478 ··· 6626 6591 6627 6592 if ((params->eht_cap || params->eht_oper) && 6628 6593 (channel->flags & IEEE80211_CHAN_NO_EHT)) 6594 + return -EOPNOTSUPP; 6595 + 6596 + if (params->uhr_oper && (channel->flags & IEEE80211_CHAN_NO_UHR)) 6629 6597 return -EOPNOTSUPP; 6630 6598 6631 6599 return 0; ··· 7213 7175 break; 7214 7176 case RATE_INFO_BW_EHT_RU: 7215 7177 rate_flg = 0; 7216 - WARN_ON(!(info->flags & RATE_INFO_FLAGS_EHT_MCS)); 7178 + WARN_ON(!(info->flags & RATE_INFO_FLAGS_EHT_MCS) && 7179 + !(info->flags & RATE_INFO_FLAGS_UHR_MCS)); 7217 7180 break; 7218 7181 } 7219 7182 ··· 7266 7227 if (info->bw == RATE_INFO_BW_EHT_RU && 7267 7228 nla_put_u8(msg, NL80211_RATE_INFO_EHT_RU_ALLOC, 7268 7229 info->eht_ru_alloc)) 7230 + return false; 7231 + } else if (info->flags & RATE_INFO_FLAGS_UHR_MCS) { 7232 + if (nla_put_u8(msg, NL80211_RATE_INFO_UHR_MCS, info->mcs)) 7233 + return false; 7234 + if (nla_put_u8(msg, NL80211_RATE_INFO_EHT_NSS, info->nss)) 7235 + return false; 7236 + if (nla_put_u8(msg, NL80211_RATE_INFO_EHT_GI, info->eht_gi)) 7237 + return false; 7238 + if (info->bw == RATE_INFO_BW_EHT_RU && 7239 + nla_put_u8(msg, NL80211_RATE_INFO_EHT_RU_ALLOC, 7240 + info->eht_ru_alloc)) 7241 + return false; 7242 + if (info->flags & RATE_INFO_FLAGS_UHR_ELR_MCS && 7243 + nla_put_flag(msg, NL80211_RATE_INFO_UHR_ELR)) 7244 + return false; 7245 + if (info->flags & RATE_INFO_FLAGS_UHR_IM && 7246 + nla_put_flag(msg, NL80211_RATE_INFO_UHR_IM)) 7269 7247 return false; 7270 7248 } 7271 7249 ··· 8157 8101 if (params->ext_capab || params->link_sta_params.ht_capa || 8158 8102 params->link_sta_params.vht_capa || 8159 8103 params->link_sta_params.he_capa || 8160 - params->link_sta_params.eht_capa) 8104 + params->link_sta_params.eht_capa || 8105 + params->link_sta_params.uhr_capa) 8161 8106 return -EINVAL; 8162 8107 if (params->sta_flags_mask & BIT(NL80211_STA_FLAG_SPP_AMSDU)) 8163 8108 return -EINVAL; ··· 8376 8319 false)) 8377 8320 return -EINVAL; 8378 8321 } 8322 + } 8323 + 8324 + if (info->attrs[NL80211_ATTR_UHR_CAPABILITY]) { 8325 + if (!params->link_sta_params.eht_capa) 8326 + return -EINVAL; 8327 + 8328 + params->link_sta_params.uhr_capa = 8329 + nla_data(info->attrs[NL80211_ATTR_UHR_CAPABILITY]); 8330 + params->link_sta_params.uhr_capa_len = 8331 + nla_len(info->attrs[NL80211_ATTR_UHR_CAPABILITY]); 8379 8332 } 8380 8333 8381 8334 if (info->attrs[NL80211_ATTR_S1G_CAPABILITY]) ··· 8708 8641 } 8709 8642 } 8710 8643 8644 + if (info->attrs[NL80211_ATTR_UHR_CAPABILITY]) { 8645 + if (!params.link_sta_params.eht_capa) 8646 + return -EINVAL; 8647 + 8648 + params.link_sta_params.uhr_capa = 8649 + nla_data(info->attrs[NL80211_ATTR_UHR_CAPABILITY]); 8650 + params.link_sta_params.uhr_capa_len = 8651 + nla_len(info->attrs[NL80211_ATTR_UHR_CAPABILITY]); 8652 + } 8653 + 8711 8654 if (info->attrs[NL80211_ATTR_EML_CAPABILITY]) { 8712 8655 params.eml_cap_present = true; 8713 8656 params.eml_cap = ··· 8777 8700 params.link_sta_params.ht_capa = NULL; 8778 8701 params.link_sta_params.vht_capa = NULL; 8779 8702 8780 - /* HE and EHT require WME */ 8703 + /* HE, EHT and UHR require WME */ 8781 8704 if (params.link_sta_params.he_capa_len || 8782 8705 params.link_sta_params.he_6ghz_capa || 8783 - params.link_sta_params.eht_capa_len) 8706 + params.link_sta_params.eht_capa_len || 8707 + params.link_sta_params.uhr_capa_len) 8784 8708 return -EINVAL; 8785 8709 } 8786 8710 ··· 12454 12376 if (nla_get_flag(info->attrs[NL80211_ATTR_DISABLE_EHT])) 12455 12377 req.flags |= ASSOC_REQ_DISABLE_EHT; 12456 12378 12379 + if (nla_get_flag(info->attrs[NL80211_ATTR_DISABLE_UHR])) 12380 + req.flags |= ASSOC_REQ_DISABLE_UHR; 12381 + 12457 12382 if (info->attrs[NL80211_ATTR_VHT_CAPABILITY_MASK]) 12458 12383 memcpy(&req.vht_capa_mask, 12459 12384 nla_data(info->attrs[NL80211_ATTR_VHT_CAPABILITY_MASK]), ··· 13328 13247 13329 13248 if (nla_get_flag(info->attrs[NL80211_ATTR_DISABLE_EHT])) 13330 13249 connect.flags |= ASSOC_REQ_DISABLE_EHT; 13250 + 13251 + if (nla_get_flag(info->attrs[NL80211_ATTR_DISABLE_UHR])) 13252 + connect.flags |= ASSOC_REQ_DISABLE_UHR; 13331 13253 13332 13254 if (info->attrs[NL80211_ATTR_VHT_CAPABILITY_MASK]) 13333 13255 memcpy(&connect.vht_capa_mask, ··· 17762 17678 false)) 17763 17679 return -EINVAL; 17764 17680 } 17681 + } 17682 + 17683 + if (info->attrs[NL80211_ATTR_UHR_CAPABILITY]) { 17684 + if (!params.eht_capa) 17685 + return -EINVAL; 17686 + 17687 + params.uhr_capa = 17688 + nla_data(info->attrs[NL80211_ATTR_UHR_CAPABILITY]); 17689 + params.uhr_capa_len = 17690 + nla_len(info->attrs[NL80211_ATTR_UHR_CAPABILITY]); 17765 17691 } 17766 17692 17767 17693 if (info->attrs[NL80211_ATTR_HE_6GHZ_CAPABILITY])
+3 -1
net/wireless/reg.c
··· 5 5 * Copyright 2008-2011 Luis R. Rodriguez <mcgrof@qca.qualcomm.com> 6 6 * Copyright 2013-2014 Intel Mobile Communications GmbH 7 7 * Copyright 2017 Intel Deutschland GmbH 8 - * Copyright (C) 2018 - 2025 Intel Corporation 8 + * Copyright (C) 2018 - 2026 Intel Corporation 9 9 * 10 10 * Permission to use, copy, modify, and/or distribute this software for any 11 11 * purpose with or without fee is hereby granted, provided that the above ··· 1605 1605 channel_flags |= IEEE80211_CHAN_ALLOW_6GHZ_VLP_AP; 1606 1606 if (rd_flags & NL80211_RRF_ALLOW_20MHZ_ACTIVITY) 1607 1607 channel_flags |= IEEE80211_CHAN_ALLOW_20MHZ_ACTIVITY; 1608 + if (rd_flags & NL80211_RRF_NO_UHR) 1609 + channel_flags |= IEEE80211_CHAN_NO_UHR; 1608 1610 return channel_flags; 1609 1611 } 1610 1612
+79 -22
net/wireless/util.c
··· 5 5 * Copyright 2007-2009 Johannes Berg <johannes@sipsolutions.net> 6 6 * Copyright 2013-2014 Intel Mobile Communications GmbH 7 7 * Copyright 2017 Intel Deutschland GmbH 8 - * Copyright (C) 2018-2023, 2025 Intel Corporation 8 + * Copyright (C) 2018-2023, 2025-2026 Intel Corporation 9 9 */ 10 10 #include <linux/export.h> 11 11 #include <linux/bitops.h> ··· 1574 1574 return result / 10000; 1575 1575 } 1576 1576 1577 - static u32 cfg80211_calculate_bitrate_eht(struct rate_info *rate) 1577 + static u32 _cfg80211_calculate_bitrate_eht_uhr(struct rate_info *rate) 1578 1578 { 1579 1579 #define SCALE 6144 1580 - static const u32 mcs_divisors[16] = { 1581 - 102399, /* 16.666666... */ 1582 - 51201, /* 8.333333... */ 1583 - 34134, /* 5.555555... */ 1584 - 25599, /* 4.166666... */ 1585 - 17067, /* 2.777777... */ 1586 - 12801, /* 2.083333... */ 1587 - 11377, /* 1.851725... */ 1588 - 10239, /* 1.666666... */ 1589 - 8532, /* 1.388888... */ 1590 - 7680, /* 1.250000... */ 1591 - 6828, /* 1.111111... */ 1592 - 6144, /* 1.000000... */ 1593 - 5690, /* 0.926106... */ 1594 - 5120, /* 0.833333... */ 1595 - 409600, /* 66.666666... */ 1596 - 204800, /* 33.333333... */ 1580 + static const u32 mcs_divisors[] = { 1581 + [ 0] = 102399, /* 16.666666... */ 1582 + [ 1] = 51201, /* 8.333333... */ 1583 + [ 2] = 34134, /* 5.555555... */ 1584 + [ 3] = 25599, /* 4.166666... */ 1585 + [ 4] = 17067, /* 2.777777... */ 1586 + [ 5] = 12801, /* 2.083333... */ 1587 + [ 6] = 11377, /* 1.851725... */ 1588 + [ 7] = 10239, /* 1.666666... */ 1589 + [ 8] = 8532, /* 1.388888... */ 1590 + [ 9] = 7680, /* 1.250000... */ 1591 + [10] = 6828, /* 1.111111... */ 1592 + [11] = 6144, /* 1.000000... */ 1593 + [12] = 5690, /* 0.926106... */ 1594 + [13] = 5120, /* 0.833333... */ 1595 + [14] = 409600, /* 66.666666... */ 1596 + [15] = 204800, /* 33.333333... */ 1597 + [17] = 38400, /* 6.250180... */ 1598 + [19] = 19200, /* 3.125090... */ 1599 + [20] = 15360, /* 2.500000... */ 1600 + [23] = 9600, /* 1.562545... */ 1597 1601 }; 1598 1602 static const u32 rates_996[3] = { 480388888, 453700000, 408333333 }; 1599 1603 static const u32 rates_484[3] = { 229411111, 216666666, 195000000 }; ··· 1608 1604 u64 tmp; 1609 1605 u32 result; 1610 1606 1611 - if (WARN_ON_ONCE(rate->mcs > 15)) 1612 - return 0; 1613 1607 if (WARN_ON_ONCE(rate->eht_gi > NL80211_RATE_INFO_EHT_GI_3_2)) 1614 1608 return 0; 1615 1609 if (WARN_ON_ONCE(rate->eht_ru_alloc > ··· 1688 1686 rate->eht_ru_alloc == NL80211_RATE_INFO_EHT_RU_ALLOC_26) 1689 1687 result = rates_26[rate->eht_gi]; 1690 1688 else { 1691 - WARN(1, "invalid EHT MCS: bw:%d, ru:%d\n", 1689 + WARN(1, "invalid EHT or UHR MCS: bw:%d, ru:%d\n", 1692 1690 rate->bw, rate->eht_ru_alloc); 1693 1691 return 0; 1694 1692 } ··· 1702 1700 tmp *= rate->nss; 1703 1701 do_div(tmp, 8); 1704 1702 1703 + /* and handle interference mitigation - 0.9x */ 1704 + if (rate->flags & RATE_INFO_FLAGS_UHR_IM) { 1705 + if (WARN(rate->nss != 1 || rate->mcs == 15, 1706 + "invalid NSS or MCS for UHR IM\n")) 1707 + return 0; 1708 + tmp *= 9000; 1709 + do_div(tmp, 10000); 1710 + } 1711 + 1705 1712 result = tmp; 1706 1713 1707 1714 return result / 10000; 1715 + } 1716 + 1717 + static u32 cfg80211_calculate_bitrate_eht(struct rate_info *rate) 1718 + { 1719 + if (WARN_ONCE(rate->mcs > 15, "bad EHT MCS %d\n", rate->mcs)) 1720 + return 0; 1721 + 1722 + if (WARN_ONCE(rate->flags & (RATE_INFO_FLAGS_UHR_ELR_MCS | 1723 + RATE_INFO_FLAGS_UHR_IM), 1724 + "bad EHT MCS flags 0x%x\n", rate->flags)) 1725 + return 0; 1726 + 1727 + return _cfg80211_calculate_bitrate_eht_uhr(rate); 1728 + } 1729 + 1730 + static u32 cfg80211_calculate_bitrate_uhr(struct rate_info *rate) 1731 + { 1732 + if (rate->flags & RATE_INFO_FLAGS_UHR_ELR_MCS) { 1733 + WARN_ONCE(rate->eht_gi != NL80211_RATE_INFO_EHT_GI_1_6, 1734 + "bad UHR ELR guard interval %d\n", 1735 + rate->eht_gi); 1736 + WARN_ONCE(rate->mcs > 1, "bad UHR ELR MCS %d\n", rate->mcs); 1737 + WARN_ONCE(rate->nss != 1, "bad UHR ELR NSS %d\n", rate->nss); 1738 + WARN_ONCE(rate->bw != RATE_INFO_BW_20, 1739 + "bad UHR ELR bandwidth %d\n", 1740 + rate->bw); 1741 + WARN_ONCE(rate->flags & RATE_INFO_FLAGS_UHR_IM, 1742 + "bad UHR MCS flags 0x%x\n", rate->flags); 1743 + if (rate->mcs == 0) 1744 + return 17; 1745 + return 33; 1746 + } 1747 + 1748 + switch (rate->mcs) { 1749 + case 0 ... 15: 1750 + case 17: 1751 + case 19: 1752 + case 20: 1753 + case 23: 1754 + return _cfg80211_calculate_bitrate_eht_uhr(rate); 1755 + } 1756 + 1757 + WARN_ONCE(1, "bad UHR MCS %d\n", rate->mcs); 1758 + return 0; 1708 1759 } 1709 1760 1710 1761 static u32 cfg80211_calculate_bitrate_s1g(struct rate_info *rate) ··· 1884 1829 return cfg80211_calculate_bitrate_he(rate); 1885 1830 if (rate->flags & RATE_INFO_FLAGS_EHT_MCS) 1886 1831 return cfg80211_calculate_bitrate_eht(rate); 1832 + if (rate->flags & RATE_INFO_FLAGS_UHR_MCS) 1833 + return cfg80211_calculate_bitrate_uhr(rate); 1887 1834 if (rate->flags & RATE_INFO_FLAGS_S1G_MCS) 1888 1835 return cfg80211_calculate_bitrate_s1g(rate); 1889 1836