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-2025-06-25' of https://git.kernel.org/pub/scm/linux/kernel/git/wireless/wireless-next

Johannes Berg says:

====================
The usual features/cleanups/etc., notably:

- rtw88: IBSS mode for SDIO devices
- rtw89:
- BT coex for MLO/WiFi7
- work on station + P2P concurrency
- ath: fix W=2 export.h warnings
- ath12k: fix scan on multi-radio devices
- cfg80211/mac80211: MLO statistics
- mac80211: S1G aggregation
- cfg80211/mac80211: per-radio RTS threshold

* tag 'wireless-next-2025-06-25' of https://git.kernel.org/pub/scm/linux/kernel/git/wireless/wireless-next: (171 commits)
wifi: iwlwifi: dvm: fix potential overflow in rs_fill_link_cmd()
iwlwifi: Add missing check for alloc_ordered_workqueue
wifi: iwlwifi: Fix memory leak in iwl_mvm_init()
iwlwifi: api: delete repeated words
iwlwifi: remove unused no_sleep_autoadjust declaration
iwlwifi: Fix comment typo
iwlwifi: use DECLARE_BITMAP macro
iwlwifi: fw: simplify the iwl_fw_dbg_collect_trig()
wifi: iwlwifi: mld: ftm: fix switch end indentation
MAINTAINERS: update iwlwifi git link
wifi: iwlwifi: pcie: fix non-MSIX handshake register
wifi: iwlwifi: mld: don't exit EMLSR when we shouldn't
wifi: iwlwifi: move _iwl_trans_set_bits_mask utilities
wifi: iwlwifi: mld: make iwl_mld_add_all_rekeys void
wifi: iwlwifi: move iwl_trans_pcie_write_mem to iwl-trans.c
wifi: iwlwifi: pcie: move iwl_trans_pcie_dump_regs() to utils.c
wifi: iwlwifi: mld: advertise support for TTLM changes
wifi: iwlwifi: mld: Block EMLSR when scanning on P2P Device
wifi: iwlwifi: mld: use the correct struct size for tracing
wifi: iwlwifi: support RZL platform device ID
...
====================

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

+5840 -1906
+1 -1
MAINTAINERS
··· 12521 12521 L: linux-wireless@vger.kernel.org 12522 12522 S: Supported 12523 12523 W: https://wireless.wiki.kernel.org/en/users/drivers/iwlwifi 12524 - T: git git://git.kernel.org/pub/scm/linux/kernel/git/iwlwifi/iwlwifi.git 12524 + T: git https://git.kernel.org/pub/scm/linux/kernel/git/iwlwifi/iwlwifi-next.git/ 12525 12525 F: drivers/net/wireless/intel/iwlwifi/ 12526 12526 12527 12527 INTEL WMI SLIM BOOTLOADER (SBL) FIRMWARE UPDATE DRIVER
+1 -1
drivers/net/wireless/admtek/adm8211.c
··· 1293 1293 ADM8211_CSR_WRITE(ABDA1, reg); 1294 1294 } 1295 1295 1296 - static int adm8211_config(struct ieee80211_hw *dev, u32 changed) 1296 + static int adm8211_config(struct ieee80211_hw *dev, int radio_idx, u32 changed) 1297 1297 { 1298 1298 struct adm8211_priv *priv = dev->priv; 1299 1299 struct ieee80211_conf *conf = &dev->conf;
+3 -2
drivers/net/wireless/ath/ar5523/ar5523.c
··· 1083 1083 mutex_unlock(&ar->mutex); 1084 1084 } 1085 1085 1086 - static int ar5523_set_rts_threshold(struct ieee80211_hw *hw, u32 value) 1086 + static int ar5523_set_rts_threshold(struct ieee80211_hw *hw, int radio_idx, 1087 + u32 value) 1087 1088 { 1088 1089 struct ar5523 *ar = hw->priv; 1089 1090 int ret; ··· 1138 1137 ar->vif = NULL; 1139 1138 } 1140 1139 1141 - static int ar5523_hwconfig(struct ieee80211_hw *hw, u32 changed) 1140 + static int ar5523_hwconfig(struct ieee80211_hw *hw, int radio_idx, u32 changed) 1142 1141 { 1143 1142 struct ar5523 *ar = hw->priv; 1144 1143
+2
drivers/net/wireless/ath/ath10k/bmi.c
··· 3 3 * Copyright (c) 2005-2011 Atheros Communications Inc. 4 4 * Copyright (c) 2011-2014,2016-2017 Qualcomm Atheros, Inc. 5 5 * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. 6 + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. 6 7 */ 7 8 9 + #include <linux/export.h> 8 10 #include "bmi.h" 9 11 #include "hif.h" 10 12 #include "debug.h"
+2
drivers/net/wireless/ath/ath10k/ce.c
··· 4 4 * Copyright (c) 2011-2017 Qualcomm Atheros, Inc. 5 5 * Copyright (c) 2018 The Linux Foundation. All rights reserved. 6 6 * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. 7 + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. 7 8 */ 8 9 10 + #include <linux/export.h> 9 11 #include "hif.h" 10 12 #include "ce.h" 11 13 #include "debug.h"
+3 -1
drivers/net/wireless/ath/ath10k/core.c
··· 4 4 * Copyright (c) 2011-2017 Qualcomm Atheros, Inc. 5 5 * Copyright (c) 2018-2019, The Linux Foundation. All rights reserved. 6 6 * Copyright (c) 2021-2024 Qualcomm Innovation Center, Inc. All rights reserved. 7 + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. 7 8 */ 8 9 10 + #include <linux/export.h> 9 11 #include <linux/module.h> 10 12 #include <linux/firmware.h> 11 13 #include <linux/of.h> ··· 2608 2606 set_coverage_class_work); 2609 2607 2610 2608 if (ar->hw_params.hw_ops->set_coverage_class) 2611 - ar->hw_params.hw_ops->set_coverage_class(ar, -1); 2609 + ar->hw_params.hw_ops->set_coverage_class(ar, -1, -1); 2612 2610 } 2613 2611 2614 2612 static int ath10k_core_init_firmware_features(struct ath10k *ar)
+2
drivers/net/wireless/ath/ath10k/coredump.c
··· 3 3 * Copyright (c) 2011-2017 Qualcomm Atheros, Inc. 4 4 * Copyright (c) 2018, The Linux Foundation. All rights reserved. 5 5 * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. 6 + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. 6 7 */ 7 8 8 9 #include "coredump.h" 9 10 10 11 #include <linux/devcoredump.h> 12 + #include <linux/export.h> 11 13 #include <linux/kernel.h> 12 14 #include <linux/types.h> 13 15 #include <linux/utsname.h>
+2
drivers/net/wireless/ath/ath10k/debug.c
··· 4 4 * Copyright (c) 2011-2017 Qualcomm Atheros, Inc. 5 5 * Copyright (c) 2018, The Linux Foundation. All rights reserved. 6 6 * Copyright (c) 2022, 2024 Qualcomm Innovation Center, Inc. All rights reserved. 7 + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. 7 8 */ 8 9 9 10 #include <linux/module.h> 10 11 #include <linux/debugfs.h> 12 + #include <linux/export.h> 11 13 #include <linux/vmalloc.h> 12 14 #include <linux/crc32.h> 13 15 #include <linux/firmware.h>
+3
drivers/net/wireless/ath/ath10k/htc.c
··· 3 3 * Copyright (c) 2005-2011 Atheros Communications Inc. 4 4 * Copyright (c) 2011-2017 Qualcomm Atheros, Inc. 5 5 * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. 6 + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. 6 7 */ 8 + 9 + #include <linux/export.h> 7 10 8 11 #include "core.h" 9 12 #include "hif.h"
+3
drivers/net/wireless/ath/ath10k/htt_rx.c
··· 4 4 * Copyright (c) 2011-2017 Qualcomm Atheros, Inc. 5 5 * Copyright (c) 2018, The Linux Foundation. All rights reserved. 6 6 * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. 7 + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. 7 8 */ 9 + 10 + #include <linux/export.h> 8 11 9 12 #include "core.h" 10 13 #include "htc.h"
+2
drivers/net/wireless/ath/ath10k/htt_tx.c
··· 3 3 * Copyright (c) 2005-2011 Atheros Communications Inc. 4 4 * Copyright (c) 2011-2017 Qualcomm Atheros, Inc. 5 5 * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. 6 + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. 6 7 */ 7 8 9 + #include <linux/export.h> 8 10 #include <linux/etherdevice.h> 9 11 #include "htt.h" 10 12 #include "mac.h"
+1
drivers/net/wireless/ath/ath10k/hw.c
··· 590 590 * function monitors and modifies the corresponding MAC registers. 591 591 */ 592 592 static void ath10k_hw_qca988x_set_coverage_class(struct ath10k *ar, 593 + int radio_idx, 593 594 s16 value) 594 595 { 595 596 u32 slottime_reg;
+1 -1
drivers/net/wireless/ath/ath10k/hw.h
··· 646 646 647 647 /* Defines needed for Rx descriptor abstraction */ 648 648 struct ath10k_hw_ops { 649 - void (*set_coverage_class)(struct ath10k *ar, s16 value); 649 + void (*set_coverage_class)(struct ath10k *ar, int radio_idx, s16 value); 650 650 int (*enable_pll_clk)(struct ath10k *ar); 651 651 int (*tx_data_rssi_pad_bytes)(struct htt_resp *htt); 652 652 int (*is_rssi_enable)(struct htt_resp *resp);
+13 -7
drivers/net/wireless/ath/ath10k/mac.c
··· 9 9 10 10 #include "mac.h" 11 11 12 + #include <linux/export.h> 12 13 #include <net/cfg80211.h> 13 14 #include <net/mac80211.h> 14 15 #include <linux/etherdevice.h> ··· 4821 4820 spin_unlock_bh(&ar->data_lock); 4822 4821 } 4823 4822 4824 - static int ath10k_get_antenna(struct ieee80211_hw *hw, u32 *tx_ant, u32 *rx_ant) 4823 + static int ath10k_get_antenna(struct ieee80211_hw *hw, int radio_idx, 4824 + u32 *tx_ant, u32 *rx_ant) 4825 4825 { 4826 4826 struct ath10k *ar = hw->priv; 4827 4827 ··· 5069 5067 return 0; 5070 5068 } 5071 5069 5072 - static int ath10k_set_antenna(struct ieee80211_hw *hw, u32 tx_ant, u32 rx_ant) 5070 + static int ath10k_set_antenna(struct ieee80211_hw *hw, int radio_idx, 5071 + u32 tx_ant, u32 rx_ant) 5073 5072 { 5074 5073 struct ath10k *ar = hw->priv; 5075 5074 int ret; ··· 5440 5437 return ret; 5441 5438 } 5442 5439 5443 - static int ath10k_config(struct ieee80211_hw *hw, u32 changed) 5440 + static int ath10k_config(struct ieee80211_hw *hw, int radio_idx, u32 changed) 5444 5441 { 5445 5442 struct ath10k *ar = hw->priv; 5446 5443 struct ieee80211_conf *conf = &hw->conf; ··· 6339 6336 mutex_unlock(&ar->conf_mutex); 6340 6337 } 6341 6338 6342 - static void ath10k_mac_op_set_coverage_class(struct ieee80211_hw *hw, s16 value) 6339 + static void ath10k_mac_op_set_coverage_class(struct ieee80211_hw *hw, int radio_idx, 6340 + s16 value) 6343 6341 { 6344 6342 struct ath10k *ar = hw->priv; 6345 6343 ··· 6351 6347 WARN_ON_ONCE(1); 6352 6348 return; 6353 6349 } 6354 - ar->hw_params.hw_ops->set_coverage_class(ar, value); 6350 + ar->hw_params.hw_ops->set_coverage_class(ar, -1, value); 6355 6351 } 6356 6352 6357 6353 struct ath10k_mac_tdls_iter_data { ··· 8039 8035 * in ath10k, but device-specific in mac80211. 8040 8036 */ 8041 8037 8042 - static int ath10k_set_rts_threshold(struct ieee80211_hw *hw, u32 value) 8038 + static int ath10k_set_rts_threshold(struct ieee80211_hw *hw, int radio_idx, 8039 + u32 value) 8043 8040 { 8044 8041 struct ath10k *ar = hw->priv; 8045 8042 struct ath10k_vif *arvif; ··· 8063 8058 return ret; 8064 8059 } 8065 8060 8066 - static int ath10k_mac_op_set_frag_threshold(struct ieee80211_hw *hw, u32 value) 8061 + static int ath10k_mac_op_set_frag_threshold(struct ieee80211_hw *hw, 8062 + int radio_idx, u32 value) 8067 8063 { 8068 8064 /* Even though there's a WMI enum for fragmentation threshold no known 8069 8065 * firmware actually implements it. Moreover it is not possible to rely
+2
drivers/net/wireless/ath/ath10k/trace.c
··· 1 1 // SPDX-License-Identifier: ISC 2 2 /* 3 3 * Copyright (c) 2012 Qualcomm Atheros, Inc. 4 + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. 4 5 */ 5 6 7 + #include <linux/export.h> 6 8 #include <linux/module.h> 7 9 8 10 #define CREATE_TRACE_POINTS
+2
drivers/net/wireless/ath/ath11k/ce.c
··· 2 2 /* 3 3 * Copyright (c) 2018-2019 The Linux Foundation. All rights reserved. 4 4 * Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved. 5 + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. 5 6 */ 6 7 8 + #include <linux/export.h> 7 9 #include "dp_rx.h" 8 10 #include "debug.h" 9 11 #include "hif.h"
+2
drivers/net/wireless/ath/ath11k/core.c
··· 2 2 /* 3 3 * Copyright (c) 2018-2019 The Linux Foundation. All rights reserved. 4 4 * Copyright (c) 2021-2025 Qualcomm Innovation Center, Inc. All rights reserved. 5 + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. 5 6 */ 6 7 8 + #include <linux/export.h> 7 9 #include <linux/module.h> 8 10 #include <linux/slab.h> 9 11 #include <linux/remoteproc.h>
+2
drivers/net/wireless/ath/ath11k/coredump.c
··· 2 2 /* 3 3 * Copyright (c) 2020 The Linux Foundation. All rights reserved. 4 4 * Copyright (c) 2024 Qualcomm Innovation Center, Inc. All rights reserved. 5 + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. 5 6 */ 6 7 #include <linux/devcoredump.h> 8 + #include <linux/export.h> 7 9 #include "hif.h" 8 10 #include "coredump.h" 9 11 #include "debug.h"
+2
drivers/net/wireless/ath/ath11k/debug.c
··· 2 2 /* 3 3 * Copyright (c) 2018-2019 The Linux Foundation. All rights reserved. 4 4 * Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved. 5 + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. 5 6 */ 6 7 8 + #include <linux/export.h> 7 9 #include <linux/vmalloc.h> 8 10 #include "core.h" 9 11 #include "debug.h"
+2
drivers/net/wireless/ath/ath11k/debugfs.c
··· 2 2 /* 3 3 * Copyright (c) 2018-2020 The Linux Foundation. All rights reserved. 4 4 * Copyright (c) 2021-2025 Qualcomm Innovation Center, Inc. All rights reserved. 5 + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. 5 6 */ 6 7 8 + #include <linux/export.h> 7 9 #include <linux/vmalloc.h> 8 10 9 11 #include "debugfs.h"
+2
drivers/net/wireless/ath/ath11k/dp.c
··· 2 2 /* 3 3 * Copyright (c) 2018-2019 The Linux Foundation. All rights reserved. 4 4 * Copyright (c) 2021-2025 Qualcomm Innovation Center, Inc. All rights reserved. 5 + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. 5 6 */ 6 7 7 8 #include <crypto/hash.h> 9 + #include <linux/export.h> 8 10 #include "core.h" 9 11 #include "dp_tx.h" 10 12 #include "hal_tx.h"
+2
drivers/net/wireless/ath/ath11k/fw.c
··· 1 1 // SPDX-License-Identifier: BSD-3-Clause-Clear 2 2 /* 3 3 * Copyright (c) 2022-2025 Qualcomm Innovation Center, Inc. All rights reserved. 4 + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. 4 5 */ 5 6 7 + #include <linux/export.h> 6 8 #include "core.h" 7 9 8 10 #include "debug.h"
+2
drivers/net/wireless/ath/ath11k/hal.c
··· 2 2 /* 3 3 * Copyright (c) 2018-2019 The Linux Foundation. All rights reserved. 4 4 * Copyright (c) 2021-2024 Qualcomm Innovation Center, Inc. All rights reserved. 5 + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. 5 6 */ 6 7 #include <linux/dma-mapping.h> 8 + #include <linux/export.h> 7 9 #include "hal_tx.h" 8 10 #include "debug.h" 9 11 #include "hal_desc.h"
+9 -5
drivers/net/wireless/ath/ath11k/mac.c
··· 1283 1283 return ret; 1284 1284 } 1285 1285 1286 - static int ath11k_mac_op_config(struct ieee80211_hw *hw, u32 changed) 1286 + static int ath11k_mac_op_config(struct ieee80211_hw *hw, int radio_idx, u32 changed) 1287 1287 { 1288 1288 struct ath11k *ar = hw->priv; 1289 1289 struct ieee80211_conf *conf = &hw->conf; ··· 7044 7044 mutex_unlock(&ar->conf_mutex); 7045 7045 } 7046 7046 7047 - static int ath11k_mac_op_get_antenna(struct ieee80211_hw *hw, u32 *tx_ant, u32 *rx_ant) 7047 + static int ath11k_mac_op_get_antenna(struct ieee80211_hw *hw, int radio_idx, 7048 + u32 *tx_ant, u32 *rx_ant) 7048 7049 { 7049 7050 struct ath11k *ar = hw->priv; 7050 7051 ··· 7059 7058 return 0; 7060 7059 } 7061 7060 7062 - static int ath11k_mac_op_set_antenna(struct ieee80211_hw *hw, u32 tx_ant, u32 rx_ant) 7061 + static int ath11k_mac_op_set_antenna(struct ieee80211_hw *hw, int radio_idx, 7062 + u32 tx_ant, u32 rx_ant) 7063 7063 { 7064 7064 struct ath11k *ar = hw->priv; 7065 7065 int ret; ··· 8184 8182 /* mac80211 stores device specific RTS/Fragmentation threshold value, 8185 8183 * this is set interface specific to firmware from ath11k driver 8186 8184 */ 8187 - static int ath11k_mac_op_set_rts_threshold(struct ieee80211_hw *hw, u32 value) 8185 + static int ath11k_mac_op_set_rts_threshold(struct ieee80211_hw *hw, 8186 + int radio_idx, u32 value) 8188 8187 { 8189 8188 struct ath11k *ar = hw->priv; 8190 8189 int param_id = WMI_VDEV_PARAM_RTS_THRESHOLD; ··· 8193 8190 return ath11k_set_vdev_param_to_all_vifs(ar, param_id, value); 8194 8191 } 8195 8192 8196 - static int ath11k_mac_op_set_frag_threshold(struct ieee80211_hw *hw, u32 value) 8193 + static int ath11k_mac_op_set_frag_threshold(struct ieee80211_hw *hw, 8194 + int radio_idx, u32 value) 8197 8195 { 8198 8196 /* Even though there's a WMI vdev param for fragmentation threshold no 8199 8197 * known firmware actually implements it. Moreover it is not possible to
+2
drivers/net/wireless/ath/ath11k/pcic.c
··· 2 2 /* 3 3 * Copyright (c) 2019-2021 The Linux Foundation. All rights reserved. 4 4 * Copyright (c) 2021-2024 Qualcomm Innovation Center, Inc. All rights reserved. 5 + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. 5 6 */ 6 7 8 + #include <linux/export.h> 7 9 #include "core.h" 8 10 #include "pcic.h" 9 11 #include "debug.h"
+2
drivers/net/wireless/ath/ath11k/qmi.c
··· 2 2 /* 3 3 * Copyright (c) 2018-2019 The Linux Foundation. All rights reserved. 4 4 * Copyright (c) 2021-2025 Qualcomm Innovation Center, Inc. All rights reserved. 5 + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. 5 6 */ 6 7 7 8 #include <linux/elf.h> 9 + #include <linux/export.h> 8 10 9 11 #include "qmi.h" 10 12 #include "core.h"
+2
drivers/net/wireless/ath/ath11k/trace.c
··· 1 1 // SPDX-License-Identifier: BSD-3-Clause-Clear 2 2 /* 3 3 * Copyright (c) 2019 The Linux Foundation. All rights reserved. 4 + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. 4 5 */ 5 6 7 + #include <linux/export.h> 6 8 #include <linux/module.h> 7 9 8 10 #define CREATE_TRACE_POINTS
+7
drivers/net/wireless/ath/ath12k/core.c
··· 2 2 /* 3 3 * Copyright (c) 2018-2021 The Linux Foundation. All rights reserved. 4 4 * Copyright (c) 2021-2025 Qualcomm Innovation Center, Inc. All rights reserved. 5 + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. 5 6 */ 6 7 8 + #include <linux/export.h> 7 9 #include <linux/module.h> 8 10 #include <linux/slab.h> 9 11 #include <linux/remoteproc.h> ··· 1411 1409 ath12k_mac_peer_cleanup_all(ar); 1412 1410 cancel_delayed_work_sync(&ar->scan.timeout); 1413 1411 cancel_work_sync(&ar->regd_update_work); 1412 + cancel_work_sync(&ar->regd_channel_update_work); 1414 1413 cancel_work_sync(&ab->rfkill_work); 1415 1414 cancel_work_sync(&ab->update_11d_work); 1416 1415 ··· 1475 1472 complete(&ar->vdev_setup_done); 1476 1473 complete(&ar->vdev_delete_done); 1477 1474 complete(&ar->bss_survey_done); 1475 + complete(&ar->regd_update_completed); 1478 1476 1479 1477 wake_up(&ar->dp.tx_empty_waitq); 1480 1478 idr_for_each(&ar->txmgmt_idr, ··· 1515 1511 ar = pdev->ar; 1516 1512 1517 1513 memcpy(&ar->alpha2, &arg.alpha2, 2); 1514 + 1515 + reinit_completion(&ar->regd_update_completed); 1516 + 1518 1517 ret = ath12k_wmi_send_set_current_country_cmd(ar, &arg); 1519 1518 if (ret) 1520 1519 ath12k_warn(ar->ab,
+9 -4
drivers/net/wireless/ath/ath12k/core.h
··· 345 345 bool is_sta_assoc_link; 346 346 347 347 struct ath12k_reg_tpc_power_info reg_tpc_info; 348 + 349 + bool group_key_valid; 350 + struct wmi_vdev_install_key_arg group_key; 351 + bool pairwise_key_done; 348 352 }; 349 353 350 354 struct ath12k_vif { ··· 384 380 struct ath12k_link_vif __rcu *link[ATH12K_NUM_MAX_LINKS]; 385 381 struct ath12k_vif_cache *cache[IEEE80211_MLD_MAX_NUM_LINKS]; 386 382 /* indicates bitmap of link vif created in FW */ 387 - u16 links_map; 388 - u8 last_scan_link; 389 - 383 + u32 links_map; 390 384 /* Must be last - ends in a flexible-array member. 391 385 * 392 386 * FIXME: Driver should not copy struct ieee80211_chanctx_conf, ··· 721 719 722 720 /* protects the radio specific data like debug stats, ppdu_stats_info stats, 723 721 * vdev_stop_status info, scan data, ath12k_sta info, ath12k_link_vif info, 724 - * channel context data, survey info, test mode data. 722 + * channel context data, survey info, test mode data, regd_channel_update_queue. 725 723 */ 726 724 spinlock_t data_lock; 727 725 ··· 780 778 struct completion bss_survey_done; 781 779 782 780 struct work_struct regd_update_work; 781 + struct work_struct regd_channel_update_work; 782 + struct list_head regd_channel_update_queue; 783 783 784 784 struct wiphy_work wmi_mgmt_tx_work; 785 785 struct sk_buff_head wmi_mgmt_tx_queue; ··· 815 811 enum ath12k_11d_state state_11d; 816 812 u8 alpha2[REG_ALPHA2_LEN]; 817 813 bool regdom_set_by_user; 814 + struct completion regd_update_completed; 818 815 819 816 struct completion fw_stats_complete; 820 817 struct completion fw_stats_done;
+1
drivers/net/wireless/ath/ath12k/dp.c
··· 84 84 ret = ath12k_dp_rx_peer_frag_setup(ar, addr, vdev_id); 85 85 if (ret) { 86 86 ath12k_warn(ab, "failed to setup rx defrag context\n"); 87 + tid--; 87 88 goto peer_clean; 88 89 } 89 90
-1
drivers/net/wireless/ath/ath12k/dp_mon.c
··· 3761 3761 ath12k_hal_srng_access_begin(ab, srng); 3762 3762 3763 3763 while (likely(*budget)) { 3764 - *budget -= 1; 3765 3764 mon_dst_desc = ath12k_hal_srng_dst_peek(ab, srng); 3766 3765 if (unlikely(!mon_dst_desc)) 3767 3766 break;
+1 -17
drivers/net/wireless/ath/ath12k/dp_rx.c
··· 2533 2533 struct ath12k_dp_rx_info *rx_info) 2534 2534 { 2535 2535 struct ath12k_base *ab = ar->ab; 2536 - static const struct ieee80211_radiotap_he known = { 2537 - .data1 = cpu_to_le16(IEEE80211_RADIOTAP_HE_DATA1_DATA_MCS_KNOWN | 2538 - IEEE80211_RADIOTAP_HE_DATA1_BW_RU_ALLOC_KNOWN), 2539 - .data2 = cpu_to_le16(IEEE80211_RADIOTAP_HE_DATA2_GI_KNOWN), 2540 - }; 2541 - struct ieee80211_radiotap_he *he; 2542 2536 struct ieee80211_rx_status *rx_status; 2543 2537 struct ieee80211_sta *pubsta; 2544 2538 struct ath12k_peer *peer; 2545 2539 struct ath12k_skb_rxcb *rxcb = ATH12K_SKB_RXCB(msdu); 2546 2540 struct ieee80211_rx_status *status = rx_info->rx_status; 2547 - u8 decap = DP_RX_DECAP_TYPE_RAW; 2541 + u8 decap = rx_info->decap_type; 2548 2542 bool is_mcbc = rxcb->is_mcbc; 2549 2543 bool is_eapol = rxcb->is_eapol; 2550 - 2551 - if (status->encoding == RX_ENC_HE && !(status->flag & RX_FLAG_RADIOTAP_HE) && 2552 - !(status->flag & RX_FLAG_SKIP_MONITOR)) { 2553 - he = skb_push(msdu, sizeof(known)); 2554 - memcpy(he, &known, sizeof(known)); 2555 - status->flag |= RX_FLAG_RADIOTAP_HE; 2556 - } 2557 - 2558 - if (!(status->flag & RX_FLAG_ONLY_MONITOR)) 2559 - decap = rx_info->decap_type; 2560 2544 2561 2545 spin_lock_bh(&ab->base_lock); 2562 2546 peer = ath12k_dp_rx_h_find_peer(ab, msdu, rx_info);
+2 -3
drivers/net/wireless/ath/ath12k/dp_tx.c
··· 13 13 #include "mac.h" 14 14 15 15 static enum hal_tcl_encap_type 16 - ath12k_dp_tx_get_encap_type(struct ath12k_link_vif *arvif, struct sk_buff *skb) 16 + ath12k_dp_tx_get_encap_type(struct ath12k_base *ab, struct sk_buff *skb) 17 17 { 18 18 struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); 19 - struct ath12k_base *ab = arvif->ar->ab; 20 19 21 20 if (test_bit(ATH12K_FLAG_RAW_MODE, &ab->dev_flags)) 22 21 return HAL_TCL_ENCAP_TYPE_RAW; ··· 304 305 u32_encode_bits(mcbc_gsn, HTT_TCL_META_DATA_GLOBAL_SEQ_NUM); 305 306 } 306 307 307 - ti.encap_type = ath12k_dp_tx_get_encap_type(arvif, skb); 308 + ti.encap_type = ath12k_dp_tx_get_encap_type(ab, skb); 308 309 ti.addr_search_flags = arvif->hal_addr_search_flags; 309 310 ti.search_type = arvif->search_type; 310 311 ti.type = HAL_TCL_DESC_TYPE_BUFFER;
+1 -1
drivers/net/wireless/ath/ath12k/hw.c
··· 1478 1478 .download_calib = true, 1479 1479 .supports_suspend = false, 1480 1480 .tcl_ring_retry = true, 1481 - .reoq_lut_support = false, 1481 + .reoq_lut_support = true, 1482 1482 .supports_shadow_regs = false, 1483 1483 1484 1484 .num_tcl_banks = 48,
+371 -70
drivers/net/wireless/ath/ath12k/mac.c
··· 693 693 if (WARN_ON(!arvif)) 694 694 continue; 695 695 696 + if (!arvif->is_created) 697 + continue; 698 + 696 699 if (arvif->vdev_id == arvif_iter->vdev_id && 697 700 arvif->ar == arvif_iter->ar) { 698 701 arvif_iter->arvif = arvif; ··· 1395 1392 return ret; 1396 1393 } 1397 1394 1398 - static int ath12k_mac_op_config(struct ieee80211_hw *hw, u32 changed) 1395 + static int ath12k_mac_op_config(struct ieee80211_hw *hw, int radio_idx, u32 changed) 1399 1396 { 1400 1397 return 0; 1401 1398 } ··· 1758 1755 struct ath12k_vif *ahvif = ath12k_vif_to_ahvif(vif); 1759 1756 struct ath12k_link_vif *arvif = &ahvif->deflink; 1760 1757 1761 - if (vif->type != NL80211_IFTYPE_STATION) 1758 + if (vif->type != NL80211_IFTYPE_STATION || !arvif->is_created) 1762 1759 return; 1763 1760 1764 1761 if (!ether_addr_equal(mgmt->bssid, vif->bss_conf.bssid)) ··· 1781 1778 u32 *vdev_id = data; 1782 1779 struct ath12k_vif *ahvif = ath12k_vif_to_ahvif(vif); 1783 1780 struct ath12k_link_vif *arvif = &ahvif->deflink; 1784 - struct ath12k *ar = arvif->ar; 1785 - struct ieee80211_hw *hw = ath12k_ar_to_hw(ar); 1781 + struct ieee80211_hw *hw; 1786 1782 1787 - if (arvif->vdev_id != *vdev_id) 1783 + if (!arvif->is_created || arvif->vdev_id != *vdev_id) 1788 1784 return; 1789 1785 1790 1786 if (!arvif->is_up) 1791 1787 return; 1792 1788 1793 1789 ieee80211_beacon_loss(vif); 1790 + hw = ath12k_ar_to_hw(arvif->ar); 1794 1791 1795 1792 /* Firmware doesn't report beacon loss events repeatedly. If AP probe 1796 1793 * (done by mac80211) succeeds but beacons do not resume then it ··· 3499 3496 /* If this is the first link arvif being created for an ML VIF 3500 3497 * use the preallocated deflink memory except for scan arvifs 3501 3498 */ 3502 - if (!ahvif->links_map && link_id != ATH12K_DEFAULT_SCAN_LINK) { 3499 + if (!ahvif->links_map && link_id < ATH12K_FIRST_SCAN_LINK) { 3503 3500 arvif = &ahvif->deflink; 3504 3501 3505 3502 if (vif->type == NL80211_IFTYPE_STATION) ··· 4152 4149 band = NL80211_BAND_6GHZ; 4153 4150 4154 4151 for_each_ar(ah, ar, i) { 4155 - /* TODO 5 GHz low high split changes */ 4156 - if (ar->mac.sbands[band].channels) 4152 + if (ar->mac.sbands[band].channels && 4153 + center_freq >= KHZ_TO_MHZ(ar->freq_range.start_freq) && 4154 + center_freq <= KHZ_TO_MHZ(ar->freq_range.end_freq)) 4157 4155 return ar; 4158 4156 } 4159 4157 ··· 4278 4274 wiphy_unlock(ath12k_ar_to_hw(ar)->wiphy); 4279 4275 } 4280 4276 4277 + static void ath12k_mac_scan_send_complete(struct ath12k *ar, 4278 + struct cfg80211_scan_info *info) 4279 + { 4280 + struct ath12k_hw *ah = ar->ah; 4281 + struct ath12k *partner_ar; 4282 + int i; 4283 + 4284 + lockdep_assert_wiphy(ah->hw->wiphy); 4285 + 4286 + for_each_ar(ah, partner_ar, i) 4287 + if (partner_ar != ar && 4288 + partner_ar->scan.state == ATH12K_SCAN_RUNNING) 4289 + return; 4290 + 4291 + ieee80211_scan_completed(ah->hw, info); 4292 + } 4293 + 4281 4294 static void ath12k_scan_vdev_clean_work(struct wiphy *wiphy, struct wiphy_work *work) 4282 4295 { 4283 4296 struct ath12k *ar = container_of(work, struct ath12k, ··· 4333 4312 ATH12K_SCAN_STARTING)), 4334 4313 }; 4335 4314 4336 - ieee80211_scan_completed(ar->ah->hw, &info); 4315 + ath12k_mac_scan_send_complete(ar, &info); 4337 4316 } 4338 4317 4339 4318 ar->scan.state = ATH12K_SCAN_IDLE; ··· 4509 4488 struct ath12k_link_vif *arvif; 4510 4489 struct ath12k_hw *ah = ahvif->ah; 4511 4490 unsigned long links = ahvif->links_map; 4491 + unsigned long scan_links_map; 4512 4492 u8 link_id; 4513 4493 4514 4494 lockdep_assert_wiphy(ah->hw->wiphy); 4515 4495 4516 - for_each_set_bit(link_id, &links, IEEE80211_MLD_MAX_NUM_LINKS) { 4496 + for_each_set_bit(link_id, &links, ATH12K_NUM_MAX_LINKS) { 4517 4497 arvif = wiphy_dereference(ah->hw->wiphy, ahvif->link[link_id]); 4518 4498 4519 4499 if (!arvif || !arvif->is_created) ··· 4524 4502 return link_id; 4525 4503 } 4526 4504 4527 - /* input ar is not assigned to any of the links of ML VIF, use scan 4528 - * link (15) for scan vdev creation. 4505 + /* input ar is not assigned to any of the links of ML VIF, use next 4506 + * available scan link for scan vdev creation. There are cases where 4507 + * single scan req needs to be split in driver and initiate separate 4508 + * scan requests to firmware based on device. 4529 4509 */ 4530 - return ATH12K_DEFAULT_SCAN_LINK; 4510 + 4511 + /* Unset all non-scan links (0-14) of scan_links_map so that ffs() will 4512 + * choose an available link among scan links (i.e link id >= 15) 4513 + */ 4514 + scan_links_map = ~ahvif->links_map & ATH12K_SCAN_LINKS_MASK; 4515 + if (scan_links_map) 4516 + return __ffs(scan_links_map); 4517 + 4518 + return ATH12K_FIRST_SCAN_LINK; 4531 4519 } 4532 4520 4533 - static int ath12k_mac_op_hw_scan(struct ieee80211_hw *hw, 4534 - struct ieee80211_vif *vif, 4535 - struct ieee80211_scan_request *hw_req) 4521 + static int ath12k_mac_initiate_hw_scan(struct ieee80211_hw *hw, 4522 + struct ieee80211_vif *vif, 4523 + struct ieee80211_scan_request *hw_req, 4524 + int n_channels, 4525 + struct ieee80211_channel **chan_list, 4526 + struct ath12k *ar) 4536 4527 { 4537 4528 struct ath12k_hw *ah = ath12k_hw_to_ah(hw); 4538 - struct ath12k *ar; 4539 4529 struct ath12k_vif *ahvif = ath12k_vif_to_ahvif(vif); 4540 4530 struct ath12k_link_vif *arvif; 4541 4531 struct cfg80211_scan_request *req = &hw_req->req; ··· 4561 4527 4562 4528 arvif = &ahvif->deflink; 4563 4529 4564 - /* Since the targeted scan device could depend on the frequency 4565 - * requested in the hw_req, select the corresponding radio 4566 - */ 4567 - ar = ath12k_mac_select_scan_device(hw, vif, hw_req->req.channels[0]->center_freq); 4568 - if (!ar) 4569 - return -EINVAL; 4570 - 4571 4530 /* check if any of the links of ML VIF is already started on 4572 4531 * radio(ar) corresponding to given scan frequency and use it, 4573 - * if not use scan link (link 15) for scan purpose. 4532 + * if not use scan link (link id >= 15) for scan purpose. 4574 4533 */ 4575 4534 link_id = ath12k_mac_find_link_id_by_ar(ahvif, ar); 4535 + /* All scan links are occupied. ideally this shouldn't happen as 4536 + * mac80211 won't schedule scan for same band until ongoing scan is 4537 + * completed, don't try to exceed max links just in case if it happens. 4538 + */ 4539 + if (link_id >= ATH12K_NUM_MAX_LINKS) 4540 + return -EBUSY; 4541 + 4576 4542 arvif = ath12k_mac_assign_link_vif(ah, vif, link_id); 4577 4543 4578 4544 ath12k_dbg(ar->ab, ATH12K_DBG_MAC, "mac link ID %d selected for scan", ··· 4663 4629 arg->scan_f_passive = 1; 4664 4630 } 4665 4631 4666 - if (req->n_channels) { 4667 - arg->num_chan = req->n_channels; 4632 + if (n_channels) { 4633 + arg->num_chan = n_channels; 4668 4634 arg->chan_list = kcalloc(arg->num_chan, sizeof(*arg->chan_list), 4669 4635 GFP_KERNEL); 4670 4636 if (!arg->chan_list) { ··· 4673 4639 } 4674 4640 4675 4641 for (i = 0; i < arg->num_chan; i++) 4676 - arg->chan_list[i] = req->channels[i]->center_freq; 4642 + arg->chan_list[i] = chan_list[i]->center_freq; 4677 4643 } 4678 4644 4679 4645 ret = ath12k_start_scan(ar, arg); ··· 4691 4657 } 4692 4658 4693 4659 ath12k_dbg(ar->ab, ATH12K_DBG_MAC, "mac scan started"); 4694 - 4695 - /* As per cfg80211/mac80211 scan design, it allows only one 4696 - * scan at a time. Hence last_scan link id is used for 4697 - * tracking the link id on which the scan is been done on 4698 - * this vif. 4699 - */ 4700 - ahvif->last_scan_link = arvif->link_id; 4701 4660 4702 4661 /* Add a margin to account for event/command processing */ 4703 4662 ieee80211_queue_delayed_work(ath12k_ar_to_hw(ar), &ar->scan.timeout, ··· 4712 4685 return ret; 4713 4686 } 4714 4687 4688 + static int ath12k_mac_op_hw_scan(struct ieee80211_hw *hw, 4689 + struct ieee80211_vif *vif, 4690 + struct ieee80211_scan_request *hw_req) 4691 + { 4692 + struct ath12k_vif *ahvif = ath12k_vif_to_ahvif(vif); 4693 + struct ieee80211_channel **chan_list, *chan; 4694 + struct ath12k_hw *ah = ath12k_hw_to_ah(hw); 4695 + unsigned long links_map, link_id; 4696 + struct ath12k_link_vif *arvif; 4697 + struct ath12k *ar, *scan_ar; 4698 + int i, j, ret = 0; 4699 + 4700 + lockdep_assert_wiphy(hw->wiphy); 4701 + 4702 + chan_list = kcalloc(hw_req->req.n_channels, sizeof(*chan_list), GFP_KERNEL); 4703 + if (!chan_list) 4704 + return -ENOMEM; 4705 + 4706 + /* There could be channels that belong to multiple underlying radio 4707 + * in same scan request as mac80211 sees it as single band. In that 4708 + * case split the hw_req based on frequency range and schedule scans to 4709 + * corresponding radio. 4710 + */ 4711 + for_each_ar(ah, ar, i) { 4712 + int n_chans = 0; 4713 + 4714 + for (j = 0; j < hw_req->req.n_channels; j++) { 4715 + chan = hw_req->req.channels[j]; 4716 + scan_ar = ath12k_mac_select_scan_device(hw, vif, 4717 + chan->center_freq); 4718 + if (!scan_ar) { 4719 + ath12k_hw_warn(ah, "unable to select scan device for freq %d\n", 4720 + chan->center_freq); 4721 + ret = -EINVAL; 4722 + goto abort; 4723 + } 4724 + if (ar != scan_ar) 4725 + continue; 4726 + 4727 + chan_list[n_chans++] = chan; 4728 + } 4729 + if (n_chans) { 4730 + ret = ath12k_mac_initiate_hw_scan(hw, vif, hw_req, n_chans, 4731 + chan_list, ar); 4732 + if (ret) 4733 + goto abort; 4734 + } 4735 + } 4736 + abort: 4737 + /* If any of the parallel scans initiated fails, abort all and 4738 + * remove the scan interfaces created. Return complete scan 4739 + * failure as mac80211 assumes this as single scan request. 4740 + */ 4741 + if (ret) { 4742 + ath12k_hw_warn(ah, "Scan failed %d , cleanup all scan vdevs\n", ret); 4743 + links_map = ahvif->links_map; 4744 + for_each_set_bit(link_id, &links_map, ATH12K_NUM_MAX_LINKS) { 4745 + arvif = wiphy_dereference(hw->wiphy, ahvif->link[link_id]); 4746 + if (!arvif) 4747 + continue; 4748 + 4749 + ar = arvif->ar; 4750 + if (ar->scan.arvif == arvif) { 4751 + wiphy_work_cancel(hw->wiphy, &ar->scan.vdev_clean_wk); 4752 + spin_lock_bh(&ar->data_lock); 4753 + ar->scan.arvif = NULL; 4754 + ar->scan.state = ATH12K_SCAN_IDLE; 4755 + ar->scan_channel = NULL; 4756 + ar->scan.roc_freq = 0; 4757 + spin_unlock_bh(&ar->data_lock); 4758 + } 4759 + if (link_id >= ATH12K_FIRST_SCAN_LINK) { 4760 + ath12k_mac_remove_link_interface(hw, arvif); 4761 + ath12k_mac_unassign_link_vif(arvif); 4762 + } 4763 + } 4764 + } 4765 + kfree(chan_list); 4766 + return ret; 4767 + } 4768 + 4715 4769 static void ath12k_mac_op_cancel_hw_scan(struct ieee80211_hw *hw, 4716 4770 struct ieee80211_vif *vif) 4717 4771 { 4718 4772 struct ath12k_vif *ahvif = ath12k_vif_to_ahvif(vif); 4719 - u16 link_id = ahvif->last_scan_link; 4773 + unsigned long link_id, links_map = ahvif->links_map; 4720 4774 struct ath12k_link_vif *arvif; 4721 4775 struct ath12k *ar; 4722 4776 4723 4777 lockdep_assert_wiphy(hw->wiphy); 4724 4778 4725 - arvif = wiphy_dereference(hw->wiphy, ahvif->link[link_id]); 4726 - if (!arvif || arvif->is_started) 4727 - return; 4779 + for_each_set_bit(link_id, &links_map, ATH12K_NUM_MAX_LINKS) { 4780 + arvif = wiphy_dereference(hw->wiphy, ahvif->link[link_id]); 4781 + if (!arvif || arvif->is_started) 4782 + continue; 4728 4783 4729 - ar = arvif->ar; 4784 + ar = arvif->ar; 4730 4785 4731 - ath12k_scan_abort(ar); 4786 + ath12k_scan_abort(ar); 4732 4787 4733 - cancel_delayed_work_sync(&ar->scan.timeout); 4788 + cancel_delayed_work_sync(&ar->scan.timeout); 4789 + } 4734 4790 } 4735 4791 4736 4792 static int ath12k_install_key(struct ath12k_link_vif *arvif, ··· 4829 4719 .key_len = key->keylen, 4830 4720 .key_data = key->key, 4831 4721 .key_flags = flags, 4722 + .ieee80211_key_cipher = key->cipher, 4832 4723 .macaddr = macaddr, 4833 4724 }; 4834 4725 struct ath12k_vif *ahvif = arvif->ahvif; 4835 4726 4836 4727 lockdep_assert_wiphy(ath12k_ar_to_hw(ar)->wiphy); 4837 - 4838 - reinit_completion(&ar->install_key_done); 4839 4728 4840 4729 if (test_bit(ATH12K_FLAG_HW_CRYPTO_DISABLED, &ar->ab->dev_flags)) 4841 4730 return 0; ··· 4844 4735 /* arg.key_cipher = WMI_CIPHER_NONE; */ 4845 4736 arg.key_len = 0; 4846 4737 arg.key_data = NULL; 4847 - goto install; 4738 + goto check_order; 4848 4739 } 4849 4740 4850 4741 switch (key->cipher) { ··· 4872 4763 key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV | 4873 4764 IEEE80211_KEY_FLAG_RESERVE_TAILROOM; 4874 4765 4875 - install: 4876 - ret = ath12k_wmi_vdev_install_key(arvif->ar, &arg); 4766 + check_order: 4767 + if (ahvif->vdev_type == WMI_VDEV_TYPE_STA && 4768 + arg.key_flags == WMI_KEY_GROUP) { 4769 + if (cmd == SET_KEY) { 4770 + if (arvif->pairwise_key_done) { 4771 + ath12k_dbg(ar->ab, ATH12K_DBG_MAC, 4772 + "vdev %u pairwise key done, go install group key\n", 4773 + arg.vdev_id); 4774 + goto install; 4775 + } else { 4776 + /* WCN7850 firmware requires pairwise key to be installed 4777 + * before group key. In case group key comes first, cache 4778 + * it and return. Will revisit it once pairwise key gets 4779 + * installed. 4780 + */ 4781 + arvif->group_key = arg; 4782 + arvif->group_key_valid = true; 4783 + ath12k_dbg(ar->ab, ATH12K_DBG_MAC, 4784 + "vdev %u group key before pairwise key, cache and skip\n", 4785 + arg.vdev_id); 4877 4786 4787 + ret = 0; 4788 + goto out; 4789 + } 4790 + } else { 4791 + arvif->group_key_valid = false; 4792 + } 4793 + } 4794 + 4795 + install: 4796 + reinit_completion(&ar->install_key_done); 4797 + 4798 + ret = ath12k_wmi_vdev_install_key(arvif->ar, &arg); 4878 4799 if (ret) 4879 4800 return ret; 4880 4801 4881 4802 if (!wait_for_completion_timeout(&ar->install_key_done, 1 * HZ)) 4882 4803 return -ETIMEDOUT; 4883 4804 4884 - if (ether_addr_equal(macaddr, arvif->bssid)) 4885 - ahvif->key_cipher = key->cipher; 4805 + if (ether_addr_equal(arg.macaddr, arvif->bssid)) 4806 + ahvif->key_cipher = arg.ieee80211_key_cipher; 4886 4807 4887 - return ar->install_key_status ? -EINVAL : 0; 4808 + if (ar->install_key_status) { 4809 + ret = -EINVAL; 4810 + goto out; 4811 + } 4812 + 4813 + if (ahvif->vdev_type == WMI_VDEV_TYPE_STA && 4814 + arg.key_flags == WMI_KEY_PAIRWISE) { 4815 + if (cmd == SET_KEY) { 4816 + arvif->pairwise_key_done = true; 4817 + if (arvif->group_key_valid) { 4818 + /* Install cached GTK */ 4819 + arvif->group_key_valid = false; 4820 + arg = arvif->group_key; 4821 + ath12k_dbg(ar->ab, ATH12K_DBG_MAC, 4822 + "vdev %u pairwise key done, group key ready, go install\n", 4823 + arg.vdev_id); 4824 + goto install; 4825 + } 4826 + } else { 4827 + arvif->pairwise_key_done = false; 4828 + } 4829 + } 4830 + 4831 + out: 4832 + if (ret) { 4833 + /* In case of failure userspace may not do DISABLE_KEY 4834 + * but triggers re-connection directly, so manually reset 4835 + * status here. 4836 + */ 4837 + arvif->group_key_valid = false; 4838 + arvif->pairwise_key_done = false; 4839 + } 4840 + 4841 + return ret; 4888 4842 } 4889 4843 4890 4844 static int ath12k_clear_peer_keys(struct ath12k_link_vif *arvif, ··· 5041 4869 } 5042 4870 5043 4871 if (key->flags & IEEE80211_KEY_FLAG_PAIRWISE) 5044 - flags |= WMI_KEY_PAIRWISE; 4872 + flags = WMI_KEY_PAIRWISE; 5045 4873 else 5046 - flags |= WMI_KEY_GROUP; 4874 + flags = WMI_KEY_GROUP; 5047 4875 5048 4876 ret = ath12k_install_key(arvif, key, cmd, peer_addr, flags); 5049 4877 if (ret) { ··· 8286 8114 8287 8115 /* TODO: Do we need to enable ANI? */ 8288 8116 8289 - ath12k_reg_update_chan_list(ar, false); 8117 + ret = ath12k_reg_update_chan_list(ar, false); 8118 + 8119 + /* The ar state alone can be turned off for non supported country 8120 + * without returning the error value. As we need to update the channel 8121 + * for the next ar. 8122 + */ 8123 + if (ret) { 8124 + if (ret == -EINVAL) 8125 + ret = 0; 8126 + goto err; 8127 + } 8290 8128 8291 8129 ar->num_started_vdevs = 0; 8292 8130 ar->num_created_vdevs = 0; ··· 8468 8286 { 8469 8287 struct ath12k_hw *ah = ar->ah; 8470 8288 struct htt_ppdu_stats_info *ppdu_stats, *tmp; 8289 + struct ath12k_wmi_scan_chan_list_arg *arg; 8471 8290 int ret; 8472 8291 8473 8292 lockdep_assert_held(&ah->hw_mutex); ··· 8483 8300 8484 8301 cancel_delayed_work_sync(&ar->scan.timeout); 8485 8302 wiphy_work_cancel(ath12k_ar_to_hw(ar)->wiphy, &ar->scan.vdev_clean_wk); 8303 + cancel_work_sync(&ar->regd_channel_update_work); 8486 8304 cancel_work_sync(&ar->regd_update_work); 8487 8305 cancel_work_sync(&ar->ab->rfkill_work); 8488 8306 cancel_work_sync(&ar->ab->update_11d_work); ··· 8491 8307 complete(&ar->completed_11d_scan); 8492 8308 8493 8309 spin_lock_bh(&ar->data_lock); 8310 + 8494 8311 list_for_each_entry_safe(ppdu_stats, tmp, &ar->ppdu_stats_info, list) { 8495 8312 list_del(&ppdu_stats->list); 8496 8313 kfree(ppdu_stats); 8314 + } 8315 + 8316 + while ((arg = list_first_entry_or_null(&ar->regd_channel_update_queue, 8317 + struct ath12k_wmi_scan_chan_list_arg, 8318 + list))) { 8319 + list_del(&arg->list); 8320 + kfree(arg); 8497 8321 } 8498 8322 spin_unlock_bh(&ar->data_lock); 8499 8323 ··· 9247 9055 struct ath12k_hw *ah = hw->priv; 9248 9056 struct ath12k *ar; 9249 9057 struct ath12k_base *ab; 9250 - u8 link_id = arvif->link_id; 9058 + u8 link_id = arvif->link_id, scan_link_id; 9059 + unsigned long scan_link_map; 9251 9060 int ret; 9252 9061 9253 9062 lockdep_assert_wiphy(hw->wiphy); ··· 9267 9074 * and now we want to create for actual usage. 9268 9075 */ 9269 9076 if (ieee80211_vif_is_mld(vif)) { 9270 - scan_arvif = wiphy_dereference(hw->wiphy, 9271 - ahvif->link[ATH12K_DEFAULT_SCAN_LINK]); 9272 - if (scan_arvif && scan_arvif->ar == ar) { 9273 - ar->scan.arvif = NULL; 9274 - ath12k_mac_remove_link_interface(hw, scan_arvif); 9275 - ath12k_mac_unassign_link_vif(scan_arvif); 9077 + scan_link_map = ahvif->links_map & ATH12K_SCAN_LINKS_MASK; 9078 + for_each_set_bit(scan_link_id, &scan_link_map, ATH12K_NUM_MAX_LINKS) { 9079 + scan_arvif = wiphy_dereference(hw->wiphy, 9080 + ahvif->link[scan_link_id]); 9081 + if (scan_arvif && scan_arvif->ar == ar) { 9082 + ar->scan.arvif = NULL; 9083 + ath12k_mac_remove_link_interface(hw, scan_arvif); 9084 + ath12k_mac_unassign_link_vif(scan_arvif); 9085 + break; 9086 + } 9276 9087 } 9277 9088 } 9278 9089 ··· 9511 9314 .aborted = true, 9512 9315 }; 9513 9316 9514 - ieee80211_scan_completed(ar->ah->hw, &info); 9317 + ath12k_mac_scan_send_complete(ar, &info); 9515 9318 } 9516 9319 9517 9320 ar->scan.state = ATH12K_SCAN_IDLE; ··· 9551 9354 ar->filter_flags = *total_flags; 9552 9355 } 9553 9356 9554 - static int ath12k_mac_op_get_antenna(struct ieee80211_hw *hw, u32 *tx_ant, u32 *rx_ant) 9357 + static int ath12k_mac_op_get_antenna(struct ieee80211_hw *hw, int radio_idx, 9358 + u32 *tx_ant, u32 *rx_ant) 9555 9359 { 9556 9360 struct ath12k_hw *ah = ath12k_hw_to_ah(hw); 9557 9361 int antennas_rx = 0, antennas_tx = 0; ··· 9572 9374 return 0; 9573 9375 } 9574 9376 9575 - static int ath12k_mac_op_set_antenna(struct ieee80211_hw *hw, u32 tx_ant, u32 rx_ant) 9377 + static int ath12k_mac_op_set_antenna(struct ieee80211_hw *hw, int radio_idx, 9378 + u32 tx_ant, u32 rx_ant) 9576 9379 { 9577 9380 struct ath12k_hw *ah = ath12k_hw_to_ah(hw); 9578 9381 struct ath12k *ar; ··· 10017 9818 if (WARN_ON(!arvif)) 10018 9819 continue; 10019 9820 10020 - if (arvif->ar != arg->ar) 9821 + if (!arvif->is_created || arvif->ar != arg->ar) 10021 9822 continue; 10022 9823 10023 9824 link_conf = wiphy_dereference(ahvif->ah->hw->wiphy, ··· 10052 9853 if (WARN_ON(!arvif)) 10053 9854 continue; 10054 9855 10055 - if (arvif->ar != arg->ar) 9856 + if (!arvif->is_created || arvif->ar != arg->ar) 10056 9857 continue; 10057 9858 10058 9859 link_conf = wiphy_dereference(ahvif->ah->hw->wiphy, ··· 10934 10735 /* mac80211 stores device specific RTS/Fragmentation threshold value, 10935 10736 * this is set interface specific to firmware from ath12k driver 10936 10737 */ 10937 - static int ath12k_mac_op_set_rts_threshold(struct ieee80211_hw *hw, u32 value) 10738 + static int ath12k_mac_op_set_rts_threshold(struct ieee80211_hw *hw, 10739 + int radio_idx, u32 value) 10938 10740 { 10939 10741 struct ath12k_hw *ah = ath12k_hw_to_ah(hw); 10940 10742 struct ath12k *ar; ··· 10960 10760 return ret; 10961 10761 } 10962 10762 10963 - static int ath12k_mac_op_set_frag_threshold(struct ieee80211_hw *hw, u32 value) 10763 + static int ath12k_mac_op_set_frag_threshold(struct ieee80211_hw *hw, 10764 + int radio_idx, u32 value) 10964 10765 { 10965 10766 /* Even though there's a WMI vdev param for fragmentation threshold no 10966 10767 * known firmware actually implements it. Moreover it is not possible to ··· 11447 11246 struct wmi_set_current_country_arg arg = {}; 11448 11247 11449 11248 memcpy(&arg.alpha2, ar->alpha2, 2); 11249 + reinit_completion(&ar->regd_update_completed); 11450 11250 ath12k_wmi_send_set_current_country_cmd(ar, &arg); 11451 11251 } 11452 11252 ··· 11959 11757 return 0; 11960 11758 } 11961 11759 11760 + static int ath12k_mac_update_band(struct ath12k *ar, 11761 + struct ieee80211_supported_band *orig_band, 11762 + struct ieee80211_supported_band *new_band) 11763 + { 11764 + int i; 11765 + 11766 + if (!orig_band || !new_band) 11767 + return -EINVAL; 11768 + 11769 + if (orig_band->band != new_band->band) 11770 + return -EINVAL; 11771 + 11772 + for (i = 0; i < new_band->n_channels; i++) { 11773 + if (new_band->channels[i].flags & IEEE80211_CHAN_DISABLED) 11774 + continue; 11775 + /* An enabled channel in new_band should not be already enabled 11776 + * in the orig_band 11777 + */ 11778 + if (WARN_ON(!(orig_band->channels[i].flags & 11779 + IEEE80211_CHAN_DISABLED))) 11780 + return -EINVAL; 11781 + orig_band->channels[i].flags &= ~IEEE80211_CHAN_DISABLED; 11782 + } 11783 + return 0; 11784 + } 11785 + 11962 11786 static int ath12k_mac_setup_channels_rates(struct ath12k *ar, 11963 11787 u32 supported_bands, 11964 11788 struct ieee80211_supported_band *bands[]) ··· 11995 11767 u32 phy_id, freq_low, freq_high; 11996 11768 struct ath12k_hw *ah = ar->ah; 11997 11769 void *channels; 11770 + int ret; 11998 11771 11999 11772 BUILD_BUG_ON((ARRAY_SIZE(ath12k_2ghz_channels) + 12000 11773 ARRAY_SIZE(ath12k_5ghz_channels) + ··· 12017 11788 band->channels = channels; 12018 11789 band->n_bitrates = ath12k_g_rates_size; 12019 11790 band->bitrates = ath12k_g_rates; 12020 - bands[NL80211_BAND_2GHZ] = band; 12021 11791 12022 11792 if (ab->hw_params->single_pdev_only) { 12023 11793 phy_id = ath12k_get_phy_id(ar, WMI_HOST_WLAN_2GHZ_CAP); ··· 12033 11805 reg_cap->high_2ghz_chan); 12034 11806 12035 11807 ath12k_mac_update_freq_range(ar, freq_low, freq_high); 11808 + 11809 + if (!bands[NL80211_BAND_2GHZ]) { 11810 + bands[NL80211_BAND_2GHZ] = band; 11811 + } else { 11812 + /* Split mac in same band under same wiphy */ 11813 + ret = ath12k_mac_update_band(ar, bands[NL80211_BAND_2GHZ], band); 11814 + if (ret) { 11815 + kfree(channels); 11816 + band->channels = NULL; 11817 + return ret; 11818 + } 11819 + ath12k_dbg(ar->ab, ATH12K_DBG_MAC, "mac pdev %u identified as 2 GHz split mac with start freq %d end freq %d", 11820 + ar->pdev->pdev_id, 11821 + KHZ_TO_MHZ(ar->freq_range.start_freq), 11822 + KHZ_TO_MHZ(ar->freq_range.end_freq)); 11823 + } 12036 11824 } 12037 11825 12038 11826 if (supported_bands & WMI_HOST_WLAN_5GHZ_CAP) { ··· 12067 11823 band->channels = channels; 12068 11824 band->n_bitrates = ath12k_a_rates_size; 12069 11825 band->bitrates = ath12k_a_rates; 12070 - bands[NL80211_BAND_6GHZ] = band; 12071 11826 12072 11827 freq_low = max(reg_cap->low_5ghz_chan, 12073 11828 ab->reg_freq_6ghz.start_freq); ··· 12079 11836 12080 11837 ath12k_mac_update_freq_range(ar, freq_low, freq_high); 12081 11838 ah->use_6ghz_regd = true; 11839 + 11840 + if (!bands[NL80211_BAND_6GHZ]) { 11841 + bands[NL80211_BAND_6GHZ] = band; 11842 + } else { 11843 + /* Split mac in same band under same wiphy */ 11844 + ret = ath12k_mac_update_band(ar, 11845 + bands[NL80211_BAND_6GHZ], 11846 + band); 11847 + if (ret) { 11848 + kfree(ar->mac.sbands[NL80211_BAND_2GHZ].channels); 11849 + ar->mac.sbands[NL80211_BAND_2GHZ].channels = NULL; 11850 + kfree(channels); 11851 + band->channels = NULL; 11852 + return ret; 11853 + } 11854 + ath12k_dbg(ar->ab, ATH12K_DBG_MAC, "mac pdev %u identified as 6 GHz split mac with start freq %d end freq %d", 11855 + ar->pdev->pdev_id, 11856 + KHZ_TO_MHZ(ar->freq_range.start_freq), 11857 + KHZ_TO_MHZ(ar->freq_range.end_freq)); 11858 + } 12082 11859 } 12083 11860 12084 11861 if (reg_cap->low_5ghz_chan < ATH12K_MIN_6GHZ_FREQ) { ··· 12117 11854 band->channels = channels; 12118 11855 band->n_bitrates = ath12k_a_rates_size; 12119 11856 band->bitrates = ath12k_a_rates; 12120 - bands[NL80211_BAND_5GHZ] = band; 12121 11857 12122 11858 if (ab->hw_params->single_pdev_only) { 12123 11859 phy_id = ath12k_get_phy_id(ar, WMI_HOST_WLAN_5GHZ_CAP); ··· 12133 11871 reg_cap->high_5ghz_chan); 12134 11872 12135 11873 ath12k_mac_update_freq_range(ar, freq_low, freq_high); 11874 + 11875 + if (!bands[NL80211_BAND_5GHZ]) { 11876 + bands[NL80211_BAND_5GHZ] = band; 11877 + } else { 11878 + /* Split mac in same band under same wiphy */ 11879 + ret = ath12k_mac_update_band(ar, 11880 + bands[NL80211_BAND_5GHZ], 11881 + band); 11882 + if (ret) { 11883 + kfree(ar->mac.sbands[NL80211_BAND_2GHZ].channels); 11884 + ar->mac.sbands[NL80211_BAND_2GHZ].channels = NULL; 11885 + kfree(ar->mac.sbands[NL80211_BAND_6GHZ].channels); 11886 + ar->mac.sbands[NL80211_BAND_2GHZ].channels = NULL; 11887 + kfree(channels); 11888 + band->channels = NULL; 11889 + return ret; 11890 + } 11891 + ath12k_dbg(ar->ab, ATH12K_DBG_MAC, "mac pdev %u identified as 5 GHz split mac with start freq %d end freq %d", 11892 + ar->pdev->pdev_id, 11893 + KHZ_TO_MHZ(ar->freq_range.start_freq), 11894 + KHZ_TO_MHZ(ar->freq_range.end_freq)); 11895 + } 12136 11896 } 12137 11897 } 12138 11898 ··· 12488 12204 int i; 12489 12205 12490 12206 for_each_ar(ah, ar, i) { 12207 + cancel_work_sync(&ar->regd_channel_update_work); 12491 12208 cancel_work_sync(&ar->regd_update_work); 12492 12209 ath12k_debugfs_unregister(ar); 12493 12210 ath12k_fw_stats_reset(ar); ··· 12747 12462 goto err_cleanup_if_combs; 12748 12463 } 12749 12464 12465 + /* Boot-time regulatory updates have already been processed. 12466 + * Mark them as complete now, because after registration, 12467 + * cfg80211 will notify us again if there are any pending hints. 12468 + * We need to wait for those hints to be processed, so it's 12469 + * important to mark the boot-time updates as complete before 12470 + * proceeding with registration. 12471 + */ 12472 + for_each_ar(ah, ar, i) 12473 + complete(&ar->regd_update_completed); 12474 + 12750 12475 ret = ieee80211_register_hw(hw); 12751 12476 if (ret) { 12752 12477 ath12k_err(ab, "ieee80211 registration failed: %d\n", ret); ··· 12784 12489 12785 12490 memcpy(&current_cc.alpha2, ab->new_alpha2, 2); 12786 12491 memcpy(&ar->alpha2, ab->new_alpha2, 2); 12492 + 12493 + reinit_completion(&ar->regd_update_completed); 12494 + 12787 12495 ret = ath12k_wmi_send_set_current_country_cmd(ar, &current_cc); 12788 12496 if (ret) 12789 12497 ath12k_warn(ar->ab, ··· 12859 12561 init_completion(&ar->scan.on_channel); 12860 12562 init_completion(&ar->mlo_setup_done); 12861 12563 init_completion(&ar->completed_11d_scan); 12564 + init_completion(&ar->regd_update_completed); 12862 12565 12863 12566 INIT_DELAYED_WORK(&ar->scan.timeout, ath12k_scan_timeout_work); 12864 12567 wiphy_work_init(&ar->scan.vdev_clean_wk, ath12k_scan_vdev_clean_work); 12568 + INIT_WORK(&ar->regd_channel_update_work, ath12k_regd_update_chan_list_work); 12569 + INIT_LIST_HEAD(&ar->regd_channel_update_queue); 12865 12570 INIT_WORK(&ar->regd_update_work, ath12k_regd_update_work); 12866 12571 12867 12572 wiphy_work_init(&ar->wmi_mgmt_tx_work, ath12k_mgmt_over_wmi_tx_work);
+5 -2
drivers/net/wireless/ath/ath12k/mac.h
··· 51 51 /* Default link after the IEEE802.11 defined Max link id limit 52 52 * for driver usage purpose. 53 53 */ 54 - #define ATH12K_DEFAULT_SCAN_LINK IEEE80211_MLD_MAX_NUM_LINKS 55 - #define ATH12K_NUM_MAX_LINKS (IEEE80211_MLD_MAX_NUM_LINKS + 1) 54 + #define ATH12K_FIRST_SCAN_LINK IEEE80211_MLD_MAX_NUM_LINKS 55 + #define ATH12K_SCAN_MAX_LINKS ATH12K_GROUP_MAX_RADIO 56 + /* Define 1 scan link for each radio for parallel scan purposes */ 57 + #define ATH12K_NUM_MAX_LINKS (IEEE80211_MLD_MAX_NUM_LINKS + ATH12K_SCAN_MAX_LINKS) 58 + #define ATH12K_SCAN_LINKS_MASK GENMASK(ATH12K_NUM_MAX_LINKS, IEEE80211_MLD_MAX_NUM_LINKS) 56 59 57 60 #define ATH12K_NUM_MAX_ACTIVE_LINKS_PER_DEVICE 2 58 61
+2 -1
drivers/net/wireless/ath/ath12k/p2p.c
··· 1 1 // SPDX-License-Identifier: BSD-3-Clause-Clear 2 2 /* 3 3 * Copyright (c) 2024 Qualcomm Innovation Center, Inc. All rights reserved. 4 + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. 4 5 */ 5 6 6 7 #include <net/mac80211.h> ··· 125 124 126 125 WARN_ON(!rcu_read_lock_any_held()); 127 126 arvif = &ahvif->deflink; 128 - if (arvif->ar != arg->ar || arvif->vdev_id != arg->vdev_id) 127 + if (!arvif->is_created || arvif->ar != arg->ar || arvif->vdev_id != arg->vdev_id) 129 128 return; 130 129 131 130 ath12k_p2p_noa_update(arvif, arg->noa);
+89 -28
drivers/net/wireless/ath/ath12k/reg.c
··· 65 65 66 66 for_each_ar(ah, ar, i) { 67 67 ret = ath12k_reg_update_chan_list(ar, true); 68 - if (ret) { 68 + if (ret && ret != -EINVAL) { 69 69 ath12k_warn(ar->ab, 70 70 "failed to update chan list for pdev %u, ret %d\n", 71 71 i, ret); ··· 102 102 103 103 /* Send the reg change request to all the radios */ 104 104 for_each_ar(ah, ar, i) { 105 + reinit_completion(&ar->regd_update_completed); 106 + 105 107 if (ar->ab->hw_params->current_cc_support) { 106 108 memcpy(&current_arg.alpha2, request->alpha2, 2); 107 109 memcpy(&ar->alpha2, &current_arg.alpha2, 2); ··· 139 137 struct ath12k_wmi_channel_arg *ch; 140 138 enum nl80211_band band; 141 139 int num_channels = 0; 142 - int i, ret, left; 143 - 144 - if (wait && ar->state_11d == ATH12K_11D_RUNNING) { 145 - left = wait_for_completion_timeout(&ar->completed_11d_scan, 146 - ATH12K_SCAN_TIMEOUT_HZ); 147 - if (!left) { 148 - ath12k_dbg(ar->ab, ATH12K_DBG_REG, 149 - "failed to receive 11d scan complete: timed out\n"); 150 - ar->state_11d = ATH12K_11D_IDLE; 151 - } 152 - ath12k_dbg(ar->ab, ATH12K_DBG_REG, 153 - "reg 11d scan wait left time %d\n", left); 154 - } 155 - 156 - if (wait && 157 - (ar->scan.state == ATH12K_SCAN_STARTING || 158 - ar->scan.state == ATH12K_SCAN_RUNNING)) { 159 - left = wait_for_completion_timeout(&ar->scan.completed, 160 - ATH12K_SCAN_TIMEOUT_HZ); 161 - if (!left) 162 - ath12k_dbg(ar->ab, ATH12K_DBG_REG, 163 - "failed to receive hw scan complete: timed out\n"); 164 - 165 - ath12k_dbg(ar->ab, ATH12K_DBG_REG, 166 - "reg hw scan wait left time %d\n", left); 167 - } 140 + int i, ret = 0; 168 141 169 142 if (ar->ah->state == ATH12K_HW_STATE_RESTARTING) 170 143 return 0; ··· 153 176 if (bands[band]->channels[i].flags & 154 177 IEEE80211_CHAN_DISABLED) 155 178 continue; 179 + /* Skip Channels that are not in current radio's range */ 180 + if (bands[band]->channels[i].center_freq < 181 + KHZ_TO_MHZ(ar->freq_range.start_freq) || 182 + bands[band]->channels[i].center_freq > 183 + KHZ_TO_MHZ(ar->freq_range.end_freq)) 184 + continue; 156 185 157 186 num_channels++; 158 187 } 159 188 } 160 189 161 - if (WARN_ON(!num_channels)) 190 + if (!num_channels) { 191 + ath12k_dbg(ar->ab, ATH12K_DBG_REG, 192 + "pdev is not supported for this country\n"); 162 193 return -EINVAL; 194 + } 163 195 164 196 arg = kzalloc(struct_size(arg, channel, num_channels), GFP_KERNEL); 165 197 ··· 188 202 channel = &bands[band]->channels[i]; 189 203 190 204 if (channel->flags & IEEE80211_CHAN_DISABLED) 205 + continue; 206 + 207 + /* Skip Channels that are not in current radio's range */ 208 + if (bands[band]->channels[i].center_freq < 209 + KHZ_TO_MHZ(ar->freq_range.start_freq) || 210 + bands[band]->channels[i].center_freq > 211 + KHZ_TO_MHZ(ar->freq_range.end_freq)) 191 212 continue; 192 213 193 214 /* TODO: Set to true/false based on some condition? */ ··· 237 244 } 238 245 } 239 246 247 + if (wait) { 248 + spin_lock_bh(&ar->data_lock); 249 + list_add_tail(&arg->list, &ar->regd_channel_update_queue); 250 + spin_unlock_bh(&ar->data_lock); 251 + 252 + queue_work(ar->ab->workqueue, &ar->regd_channel_update_work); 253 + 254 + return 0; 255 + } 256 + 240 257 ret = ath12k_wmi_send_scan_chan_list_cmd(ar, arg); 241 258 kfree(arg); 242 259 ··· 275 272 struct ieee80211_regdomain *regd, *regd_copy = NULL; 276 273 int ret, regd_len, pdev_id; 277 274 struct ath12k_base *ab; 275 + long time_left; 278 276 279 277 ab = ar->ab; 278 + 279 + time_left = wait_for_completion_timeout(&ar->regd_update_completed, 280 + ATH12K_REG_UPDATE_TIMEOUT_HZ); 281 + if (time_left == 0) { 282 + ath12k_warn(ab, "Timeout while waiting for regulatory update"); 283 + /* Even though timeout has occurred, still continue since at least boot 284 + * time data would be there to process 285 + */ 286 + } 280 287 281 288 supported_bands = ar->pdev->cap.supported_bands; 282 289 reg_cap = &ab->hal_reg_cap[ar->pdev_idx]; ··· 775 762 new_regd->n_reg_rules = i; 776 763 ret: 777 764 return new_regd; 765 + } 766 + 767 + void ath12k_regd_update_chan_list_work(struct work_struct *work) 768 + { 769 + struct ath12k *ar = container_of(work, struct ath12k, 770 + regd_channel_update_work); 771 + struct ath12k_wmi_scan_chan_list_arg *arg; 772 + struct list_head local_update_list; 773 + int left; 774 + 775 + INIT_LIST_HEAD(&local_update_list); 776 + 777 + spin_lock_bh(&ar->data_lock); 778 + list_splice_tail_init(&ar->regd_channel_update_queue, &local_update_list); 779 + spin_unlock_bh(&ar->data_lock); 780 + 781 + while ((arg = list_first_entry_or_null(&local_update_list, 782 + struct ath12k_wmi_scan_chan_list_arg, 783 + list))) { 784 + if (ar->state_11d != ATH12K_11D_IDLE) { 785 + left = wait_for_completion_timeout(&ar->completed_11d_scan, 786 + ATH12K_SCAN_TIMEOUT_HZ); 787 + if (!left) { 788 + ath12k_dbg(ar->ab, ATH12K_DBG_REG, 789 + "failed to receive 11d scan complete: timed out\n"); 790 + ar->state_11d = ATH12K_11D_IDLE; 791 + } 792 + 793 + ath12k_dbg(ar->ab, ATH12K_DBG_REG, 794 + "reg 11d scan wait left time %d\n", left); 795 + } 796 + 797 + if ((ar->scan.state == ATH12K_SCAN_STARTING || 798 + ar->scan.state == ATH12K_SCAN_RUNNING)) { 799 + left = wait_for_completion_timeout(&ar->scan.completed, 800 + ATH12K_SCAN_TIMEOUT_HZ); 801 + if (!left) 802 + ath12k_dbg(ar->ab, ATH12K_DBG_REG, 803 + "failed to receive hw scan complete: timed out\n"); 804 + 805 + ath12k_dbg(ar->ab, ATH12K_DBG_REG, 806 + "reg hw scan wait left time %d\n", left); 807 + } 808 + 809 + ath12k_wmi_send_scan_chan_list_cmd(ar, arg); 810 + list_del(&arg->list); 811 + kfree(arg); 812 + } 778 813 } 779 814 780 815 void ath12k_regd_update_work(struct work_struct *work)
+3
drivers/net/wireless/ath/ath12k/reg.h
··· 13 13 struct ath12k_base; 14 14 struct ath12k; 15 15 16 + #define ATH12K_REG_UPDATE_TIMEOUT_HZ (3 * HZ) 17 + 16 18 #define ATH12K_2GHZ_MAX_FREQUENCY 2495 17 19 #define ATH12K_5GHZ_MAX_FREQUENCY 5920 18 20 ··· 115 113 struct ath12k_reg_info *reg_info, 116 114 enum wmi_vdev_type vdev_type, 117 115 enum ieee80211_ap_reg_power power_type); 116 + void ath12k_regd_update_chan_list_work(struct work_struct *work); 118 117 enum wmi_reg_6g_ap_type 119 118 ath12k_reg_ap_pwr_convert(enum ieee80211_ap_reg_power power_type); 120 119 enum ath12k_reg_status ath12k_reg_validate_reg_info(struct ath12k_base *ab,
+23 -3
drivers/net/wireless/ath/ath12k/wmi.c
··· 6445 6445 if (!sband) 6446 6446 continue; 6447 6447 6448 - for (ch = 0; ch < sband->n_channels; ch++, idx++) 6448 + for (ch = 0; ch < sband->n_channels; ch++, idx++) { 6449 + if (sband->channels[ch].center_freq < 6450 + KHZ_TO_MHZ(ar->freq_range.start_freq) || 6451 + sband->channels[ch].center_freq > 6452 + KHZ_TO_MHZ(ar->freq_range.end_freq)) 6453 + continue; 6454 + 6449 6455 if (sband->channels[ch].center_freq == freq) 6450 6456 goto exit; 6457 + } 6451 6458 } 6452 6459 6453 6460 exit: ··· 6684 6677 static int ath12k_reg_chan_list_event(struct ath12k_base *ab, struct sk_buff *skb) 6685 6678 { 6686 6679 struct ath12k_reg_info *reg_info; 6687 - u8 pdev_idx; 6680 + struct ath12k *ar = NULL; 6681 + u8 pdev_idx = 255; 6688 6682 int ret; 6689 6683 6690 6684 reg_info = kzalloc(sizeof(*reg_info), GFP_ATOMIC); ··· 6740 6732 kfree(reg_info); 6741 6733 6742 6734 if (ret == ATH12K_REG_STATUS_VALID) 6743 - return ret; 6735 + goto out; 6744 6736 6745 6737 fallback: 6746 6738 /* Fallback to older reg (by sending previous country setting ··· 6754 6746 WARN_ON(1); 6755 6747 6756 6748 out: 6749 + /* In some error cases, even a valid pdev_idx might not be available */ 6750 + if (pdev_idx != 255) 6751 + ar = ab->pdevs[pdev_idx].ar; 6752 + 6753 + /* During the boot-time update, 'ar' might not be allocated, 6754 + * so the completion cannot be marked at that point. 6755 + * This boot-time update is handled in ath12k_mac_hw_register() 6756 + * before registering the hardware. 6757 + */ 6758 + if (ar) 6759 + complete(&ar->regd_update_completed); 6760 + 6757 6761 return ret; 6758 6762 } 6759 6763
+2
drivers/net/wireless/ath/ath12k/wmi.h
··· 3760 3760 u32 key_idx; 3761 3761 u32 key_flags; 3762 3762 u32 key_cipher; 3763 + u32 ieee80211_key_cipher; 3763 3764 u32 key_len; 3764 3765 u32 key_txmic_len; 3765 3766 u32 key_rxmic_len; ··· 3949 3948 } __packed; 3950 3949 3951 3950 struct ath12k_wmi_scan_chan_list_arg { 3951 + struct list_head list; 3952 3952 u32 pdev_id; 3953 3953 u16 nallchans; 3954 3954 struct ath12k_wmi_channel_arg channel[];
+8 -4
drivers/net/wireless/ath/ath5k/mac80211-ops.c
··· 192 192 * TODO: Phy disable/diversity etc 193 193 */ 194 194 static int 195 - ath5k_config(struct ieee80211_hw *hw, u32 changed) 195 + ath5k_config(struct ieee80211_hw *hw, int radio_idx, u32 changed) 196 196 { 197 197 struct ath5k_hw *ah = hw->priv; 198 198 struct ieee80211_conf *conf = &hw->conf; ··· 686 686 * ath5k_set_coverage_class - Set IEEE 802.11 coverage class 687 687 * 688 688 * @hw: struct ieee80211_hw pointer 689 + * @radio_idx: Radio index 689 690 * @coverage_class: IEEE 802.11 coverage class number 690 691 * 691 692 * Mac80211 callback. Sets slot time, ACK timeout and CTS timeout for given ··· 694 693 * reset. 695 694 */ 696 695 static void 697 - ath5k_set_coverage_class(struct ieee80211_hw *hw, s16 coverage_class) 696 + ath5k_set_coverage_class(struct ieee80211_hw *hw, int radio_idx, 697 + s16 coverage_class) 698 698 { 699 699 struct ath5k_hw *ah = hw->priv; 700 700 ··· 706 704 707 705 708 706 static int 709 - ath5k_set_antenna(struct ieee80211_hw *hw, u32 tx_ant, u32 rx_ant) 707 + ath5k_set_antenna(struct ieee80211_hw *hw, int radio_idx, u32 tx_ant, 708 + u32 rx_ant) 710 709 { 711 710 struct ath5k_hw *ah = hw->priv; 712 711 ··· 724 721 725 722 726 723 static int 727 - ath5k_get_antenna(struct ieee80211_hw *hw, u32 *tx_ant, u32 *rx_ant) 724 + ath5k_get_antenna(struct ieee80211_hw *hw, int radio_idx, 725 + u32 *tx_ant, u32 *rx_ant) 728 726 { 729 727 struct ath5k_hw *ah = hw->priv; 730 728
+5 -2
drivers/net/wireless/ath/ath6kl/cfg80211.c
··· 1376 1376 GFP_KERNEL); 1377 1377 } 1378 1378 1379 - static int ath6kl_cfg80211_set_wiphy_params(struct wiphy *wiphy, u32 changed) 1379 + static int ath6kl_cfg80211_set_wiphy_params(struct wiphy *wiphy, int radio_idx, 1380 + u32 changed) 1380 1381 { 1381 1382 struct ath6kl *ar = (struct ath6kl *)wiphy_priv(wiphy); 1382 1383 struct ath6kl_vif *vif; ··· 1406 1405 1407 1406 static int ath6kl_cfg80211_set_txpower(struct wiphy *wiphy, 1408 1407 struct wireless_dev *wdev, 1408 + int radio_idx, 1409 1409 enum nl80211_tx_power_setting type, 1410 1410 int mbm) 1411 1411 { ··· 1443 1441 1444 1442 static int ath6kl_cfg80211_get_txpower(struct wiphy *wiphy, 1445 1443 struct wireless_dev *wdev, 1444 + int radio_idx, 1446 1445 unsigned int link_id, 1447 1446 int *dbm) 1448 1447 { ··· 3245 3242 wait, buf, len, no_cck); 3246 3243 } 3247 3244 3248 - static int ath6kl_get_antenna(struct wiphy *wiphy, 3245 + static int ath6kl_get_antenna(struct wiphy *wiphy, int radio_idx, 3249 3246 u32 *tx_ant, u32 *rx_ant) 3250 3247 { 3251 3248 struct ath6kl *ar = wiphy_priv(wiphy);
+1
drivers/net/wireless/ath/ath9k/common-beacon.c
··· 14 14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15 15 */ 16 16 17 + #include <linux/export.h> 17 18 #include "common.h" 18 19 19 20 #define FUDGE 2
+1
drivers/net/wireless/ath/ath9k/common-debug.c
··· 14 14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15 15 */ 16 16 17 + #include <linux/export.h> 17 18 #include "common.h" 18 19 19 20 static ssize_t read_file_modal_eeprom(struct file *file, char __user *user_buf,
+1
drivers/net/wireless/ath/ath9k/common-init.c
··· 16 16 17 17 /* We use the hw_value as an index into our private channel structure */ 18 18 19 + #include <linux/export.h> 19 20 #include "common.h" 20 21 21 22 #define CHAN2G(_freq, _idx) { \
+1
drivers/net/wireless/ath/ath9k/common-spectral.c
··· 14 14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15 15 */ 16 16 17 + #include <linux/export.h> 17 18 #include <linux/relay.h> 18 19 #include <linux/random.h> 19 20 #include "ath9k.h"
+1
drivers/net/wireless/ath/ath9k/common.c
··· 18 18 * Module for common driver code between ath9k and ath9k_htc 19 19 */ 20 20 21 + #include <linux/export.h> 21 22 #include <linux/kernel.h> 22 23 #include <linux/module.h> 23 24
+1
drivers/net/wireless/ath/ath9k/dynack.c
··· 14 14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15 15 */ 16 16 17 + #include <linux/export.h> 17 18 #include "ath9k.h" 18 19 #include "hw.h" 19 20 #include "dynack.h"
+6 -4
drivers/net/wireless/ath/ath9k/htc_drv_main.c
··· 1172 1172 mutex_unlock(&priv->mutex); 1173 1173 } 1174 1174 1175 - static int ath9k_htc_config(struct ieee80211_hw *hw, u32 changed) 1175 + static int ath9k_htc_config(struct ieee80211_hw *hw, int radio_idx, u32 changed) 1176 1176 { 1177 1177 struct ath9k_htc_priv *priv = hw->priv; 1178 1178 struct ath_common *common = ath9k_hw_common(priv->ah); ··· 1737 1737 mutex_unlock(&priv->mutex); 1738 1738 } 1739 1739 1740 - static int ath9k_htc_set_rts_threshold(struct ieee80211_hw *hw, u32 value) 1740 + static int ath9k_htc_set_rts_threshold(struct ieee80211_hw *hw, 1741 + int radio_idx, u32 value) 1741 1742 { 1742 1743 return 0; 1743 1744 } 1744 1745 1745 1746 static void ath9k_htc_set_coverage_class(struct ieee80211_hw *hw, 1747 + int radio_idx, 1746 1748 s16 coverage_class) 1747 1749 { 1748 1750 struct ath9k_htc_priv *priv = hw->priv; ··· 1843 1841 } 1844 1842 1845 1843 1846 - static int ath9k_htc_get_antenna(struct ieee80211_hw *hw, u32 *tx_ant, 1847 - u32 *rx_ant) 1844 + static int ath9k_htc_get_antenna(struct ieee80211_hw *hw, int radio_idx, 1845 + u32 *tx_ant, u32 *rx_ant) 1848 1846 { 1849 1847 struct ath9k_htc_priv *priv = hw->priv; 1850 1848 struct base_eep_header *pBase = ath9k_htc_get_eeprom_base(priv);
+1
drivers/net/wireless/ath/ath9k/hw.c
··· 14 14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15 15 */ 16 16 17 + #include <linux/export.h> 17 18 #include <linux/io.h> 18 19 #include <linux/slab.h> 19 20 #include <linux/module.h>
+6 -3
drivers/net/wireless/ath/ath9k/main.c
··· 1484 1484 ath_dbg(common, PS, "PowerSave disabled\n"); 1485 1485 } 1486 1486 1487 - static int ath9k_config(struct ieee80211_hw *hw, u32 changed) 1487 + static int ath9k_config(struct ieee80211_hw *hw, int radio_idx, u32 changed) 1488 1488 { 1489 1489 struct ath_softc *sc = hw->priv; 1490 1490 struct ath_hw *ah = sc->sc_ah; ··· 2114 2114 } 2115 2115 2116 2116 static void ath9k_set_coverage_class(struct ieee80211_hw *hw, 2117 + int radio_idx, 2117 2118 s16 coverage_class) 2118 2119 { 2119 2120 struct ath_softc *sc = hw->priv; ··· 2339 2338 } 2340 2339 } 2341 2340 2342 - static int ath9k_set_antenna(struct ieee80211_hw *hw, u32 tx_ant, u32 rx_ant) 2341 + static int ath9k_set_antenna(struct ieee80211_hw *hw, int radio_idx, 2342 + u32 tx_ant, u32 rx_ant) 2343 2343 { 2344 2344 struct ath_softc *sc = hw->priv; 2345 2345 struct ath_hw *ah = sc->sc_ah; ··· 2369 2367 return 0; 2370 2368 } 2371 2369 2372 - static int ath9k_get_antenna(struct ieee80211_hw *hw, u32 *tx_ant, u32 *rx_ant) 2370 + static int ath9k_get_antenna(struct ieee80211_hw *hw, int radio_idx, 2371 + u32 *tx_ant, u32 *rx_ant) 2373 2372 { 2374 2373 struct ath_softc *sc = hw->priv; 2375 2374
+1 -1
drivers/net/wireless/ath/carl9170/main.c
··· 890 890 round_jiffies(msecs_to_jiffies(CARL9170_STAT_WORK))); 891 891 } 892 892 893 - static int carl9170_op_config(struct ieee80211_hw *hw, u32 changed) 893 + static int carl9170_op_config(struct ieee80211_hw *hw, int radio_idx, u32 changed) 894 894 { 895 895 struct ar9170 *ar = hw->priv; 896 896 int err = 0;
+1
drivers/net/wireless/ath/main.c
··· 16 16 17 17 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 18 18 19 + #include <linux/export.h> 19 20 #include <linux/kernel.h> 20 21 #include <linux/module.h> 21 22
+3 -2
drivers/net/wireless/ath/wcn36xx/main.c
··· 361 361 return; 362 362 } 363 363 364 - static int wcn36xx_config(struct ieee80211_hw *hw, u32 changed) 364 + static int wcn36xx_config(struct ieee80211_hw *hw, int radio_idx, u32 changed) 365 365 { 366 366 struct wcn36xx *wcn = hw->priv; 367 367 int ret; ··· 965 965 } 966 966 967 967 /* this is required when using IEEE80211_HW_HAS_RATE_CONTROL */ 968 - static int wcn36xx_set_rts_threshold(struct ieee80211_hw *hw, u32 value) 968 + static int wcn36xx_set_rts_threshold(struct ieee80211_hw *hw, int radio_idx, 969 + u32 value) 969 970 { 970 971 struct wcn36xx *wcn = hw->priv; 971 972 wcn36xx_dbg(WCN36XX_DBG_MAC, "mac set RTS threshold %d\n", value);
+2 -1
drivers/net/wireless/ath/wil6210/cfg80211.c
··· 1408 1408 return rc; 1409 1409 } 1410 1410 1411 - static int wil_cfg80211_set_wiphy_params(struct wiphy *wiphy, u32 changed) 1411 + static int wil_cfg80211_set_wiphy_params(struct wiphy *wiphy, int radio_idx, 1412 + u32 changed) 1412 1413 { 1413 1414 struct wil6210_priv *wil = wiphy_to_wil(wiphy); 1414 1415 int rc;
+1 -1
drivers/net/wireless/atmel/at76c50x-usb.c
··· 2002 2002 return 0; 2003 2003 } 2004 2004 2005 - static int at76_config(struct ieee80211_hw *hw, u32 changed) 2005 + static int at76_config(struct ieee80211_hw *hw, int radio_idx, u32 changed) 2006 2006 { 2007 2007 struct at76_priv *priv = hw->priv; 2008 2008
+3 -3
drivers/net/wireless/broadcom/b43/main.c
··· 3975 3975 long_retry); 3976 3976 } 3977 3977 3978 - static int b43_op_config(struct ieee80211_hw *hw, u32 changed) 3978 + static int b43_op_config(struct ieee80211_hw *hw, int radio_idx, u32 changed) 3979 3979 { 3980 3980 struct b43_wl *wl = hw_to_b43_wl(hw); 3981 3981 struct b43_wldev *dev = wl->current_dev; ··· 5073 5073 * may hang the system. 5074 5074 */ 5075 5075 if (!err) 5076 - b43_op_config(hw, ~0); 5076 + b43_op_config(hw, -1, ~0); 5077 5077 5078 5078 return err; 5079 5079 } ··· 5248 5248 } 5249 5249 5250 5250 /* reload configuration */ 5251 - b43_op_config(wl->hw, ~0); 5251 + b43_op_config(wl->hw, -1, ~0); 5252 5252 if (wl->vif) 5253 5253 b43_op_bss_info_changed(wl->hw, wl->vif, &wl->vif->bss_conf, ~0); 5254 5254
+1 -1
drivers/net/wireless/broadcom/b43legacy/main.c
··· 2662 2662 b43legacy_shm_write16(dev, B43legacy_SHM_WIRELESS, 0x0007, long_retry); 2663 2663 } 2664 2664 2665 - static int b43legacy_op_dev_config(struct ieee80211_hw *hw, 2665 + static int b43legacy_op_dev_config(struct ieee80211_hw *hw, int radio_idx, 2666 2666 u32 changed) 2667 2667 { 2668 2668 struct b43legacy_wl *wl = hw_to_b43legacy_wl(hw);
+21 -4
drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
··· 1043 1043 } 1044 1044 } 1045 1045 1046 + bool brcmf_is_apmode_operating(struct wiphy *wiphy) 1047 + { 1048 + struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy); 1049 + struct brcmf_cfg80211_vif *vif; 1050 + bool ret = false; 1051 + 1052 + list_for_each_entry(vif, &cfg->vif_list, list) { 1053 + if (brcmf_is_apmode(vif) && 1054 + test_bit(BRCMF_VIF_STATUS_AP_CREATED, &vif->sme_state)) 1055 + ret = true; 1056 + } 1057 + 1058 + return ret; 1059 + } 1060 + 1046 1061 static void brcmf_scan_params_v2_to_v1(struct brcmf_scan_params_v2_le *params_v2_le, 1047 1062 struct brcmf_scan_params_le *params_le) 1048 1063 { ··· 1637 1622 return err; 1638 1623 } 1639 1624 1640 - static s32 brcmf_cfg80211_set_wiphy_params(struct wiphy *wiphy, u32 changed) 1625 + static s32 brcmf_cfg80211_set_wiphy_params(struct wiphy *wiphy, int radio_idx, 1626 + u32 changed) 1641 1627 { 1642 1628 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy); 1643 1629 struct net_device *ndev = cfg_to_ndev(cfg); ··· 2646 2630 2647 2631 static s32 2648 2632 brcmf_cfg80211_set_tx_power(struct wiphy *wiphy, struct wireless_dev *wdev, 2649 - enum nl80211_tx_power_setting type, s32 mbm) 2633 + int radio_idx, enum nl80211_tx_power_setting type, 2634 + s32 mbm) 2650 2635 { 2651 2636 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy); 2652 2637 struct net_device *ndev = cfg_to_ndev(cfg); ··· 2698 2681 2699 2682 static s32 2700 2683 brcmf_cfg80211_get_tx_power(struct wiphy *wiphy, struct wireless_dev *wdev, 2701 - unsigned int link_id, s32 *dbm) 2684 + int radio_idx, unsigned int link_id, s32 *dbm) 2702 2685 { 2703 2686 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy); 2704 2687 struct brcmf_cfg80211_vif *vif = wdev_to_vif(wdev); ··· 5433 5416 bphy_err(drvr, "bss_enable config failed %d\n", err); 5434 5417 } 5435 5418 brcmf_set_mpc(ifp, 1); 5436 - brcmf_configure_arp_nd_offload(ifp, true); 5437 5419 clear_bit(BRCMF_VIF_STATUS_AP_CREATED, &ifp->vif->sme_state); 5420 + brcmf_configure_arp_nd_offload(ifp, true); 5438 5421 brcmf_net_setcarrier(ifp, false); 5439 5422 5440 5423 return err;
+1
drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.h
··· 487 487 struct brcmf_if *ifp, bool aborted, 488 488 bool fw_abort); 489 489 void brcmf_set_mpc(struct brcmf_if *ndev, int mpc); 490 + bool brcmf_is_apmode_operating(struct wiphy *wiphy); 490 491 void brcmf_abort_scanning(struct brcmf_cfg80211_info *cfg); 491 492 void brcmf_cfg80211_free_netdev(struct net_device *ndev); 492 493
+5
drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c
··· 98 98 s32 err; 99 99 u32 mode; 100 100 101 + if (enable && brcmf_is_apmode_operating(ifp->drvr->wiphy)) { 102 + brcmf_dbg(TRACE, "Skip ARP/ND offload enable when soft AP is running\n"); 103 + return; 104 + } 105 + 101 106 if (enable) 102 107 mode = BRCMF_ARP_OL_AGENT | BRCMF_ARP_OL_PEER_AUTO_REPLY; 103 108 else
+13 -11
drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c
··· 654 654 static void brcmf_pcie_reset_device(struct brcmf_pciedev_info *devinfo) 655 655 { 656 656 struct brcmf_core *core; 657 - u16 cfg_offset[] = { BRCMF_PCIE_CFGREG_STATUS_CMD, 658 - BRCMF_PCIE_CFGREG_PM_CSR, 659 - BRCMF_PCIE_CFGREG_MSI_CAP, 660 - BRCMF_PCIE_CFGREG_MSI_ADDR_L, 661 - BRCMF_PCIE_CFGREG_MSI_ADDR_H, 662 - BRCMF_PCIE_CFGREG_MSI_DATA, 663 - BRCMF_PCIE_CFGREG_LINK_STATUS_CTRL2, 664 - BRCMF_PCIE_CFGREG_RBAR_CTRL, 665 - BRCMF_PCIE_CFGREG_PML1_SUB_CTRL1, 666 - BRCMF_PCIE_CFGREG_REG_BAR2_CONFIG, 667 - BRCMF_PCIE_CFGREG_REG_BAR3_CONFIG }; 657 + static const u16 cfg_offset[] = { 658 + BRCMF_PCIE_CFGREG_STATUS_CMD, 659 + BRCMF_PCIE_CFGREG_PM_CSR, 660 + BRCMF_PCIE_CFGREG_MSI_CAP, 661 + BRCMF_PCIE_CFGREG_MSI_ADDR_L, 662 + BRCMF_PCIE_CFGREG_MSI_ADDR_H, 663 + BRCMF_PCIE_CFGREG_MSI_DATA, 664 + BRCMF_PCIE_CFGREG_LINK_STATUS_CTRL2, 665 + BRCMF_PCIE_CFGREG_RBAR_CTRL, 666 + BRCMF_PCIE_CFGREG_PML1_SUB_CTRL1, 667 + BRCMF_PCIE_CFGREG_REG_BAR2_CONFIG, 668 + BRCMF_PCIE_CFGREG_REG_BAR3_CONFIG 669 + }; 668 670 u32 i; 669 671 u32 val; 670 672 u32 lsc;
+2 -1
drivers/net/wireless/broadcom/brcm80211/brcmsmac/mac80211_if.c
··· 525 525 spin_unlock_bh(&wl->lock); 526 526 } 527 527 528 - static int brcms_ops_config(struct ieee80211_hw *hw, u32 changed) 528 + static int brcms_ops_config(struct ieee80211_hw *hw, int radio_idx, 529 + u32 changed) 529 530 { 530 531 struct ieee80211_conf *conf = &hw->conf; 531 532 struct brcms_info *wl = hw->priv;
+1 -1
drivers/net/wireless/intel/ipw2x00/libipw_module.c
··· 83 83 { 84 84 struct libipw_network *network = NULL; 85 85 unsigned long flags; 86 - unsigned long age_jiffies = msecs_to_jiffies(age_secs * MSEC_PER_SEC); 86 + unsigned long age_jiffies = secs_to_jiffies(age_secs); 87 87 88 88 spin_lock_irqsave(&ieee->lock, flags); 89 89 list_for_each_entry(network, &ieee->network_list, list) {
+5 -2
drivers/net/wireless/intel/iwlegacy/4965-mac.c
··· 1382 1382 * we get a thermal update even if the uCode doesn't give us one 1383 1383 */ 1384 1384 mod_timer(&il->stats_periodic, 1385 - jiffies + msecs_to_jiffies(recalib_seconds * 1000)); 1385 + jiffies + secs_to_jiffies(recalib_seconds)); 1386 1386 1387 1387 if (unlikely(!test_bit(S_SCANNING, &il->status)) && 1388 1388 (pkt->hdr.cmd == N_STATS)) { ··· 1575 1575 || rate_idx > RATE_COUNT_LEGACY) 1576 1576 rate_idx = rate_lowest_index(&il->bands[info->band], sta); 1577 1577 /* For 5 GHZ band, remap mac80211 rate indices into driver indices */ 1578 - if (info->band == NL80211_BAND_5GHZ) 1578 + if (info->band == NL80211_BAND_5GHZ) { 1579 1579 rate_idx += IL_FIRST_OFDM_RATE; 1580 + if (rate_idx > IL_LAST_OFDM_RATE) 1581 + rate_idx = IL_LAST_OFDM_RATE; 1582 + } 1580 1583 /* Get PLCP rate for tx_cmd->rate_n_flags */ 1581 1584 rate_plcp = il_rates[rate_idx].plcp; 1582 1585 /* Zero out flags for this packet */
+1 -1
drivers/net/wireless/intel/iwlegacy/common.c
··· 4990 4990 * il_mac_config - mac80211 config callback 4991 4991 */ 4992 4992 int 4993 - il_mac_config(struct ieee80211_hw *hw, u32 changed) 4993 + il_mac_config(struct ieee80211_hw *hw, int radio_idx, u32 changed) 4994 4994 { 4995 4995 struct il_priv *il = hw->priv; 4996 4996 const struct il_channel_info *ch_info;
+1 -1
drivers/net/wireless/intel/iwlegacy/common.h
··· 1956 1956 } 1957 1957 1958 1958 /* mac80211 handlers */ 1959 - int il_mac_config(struct ieee80211_hw *hw, u32 changed); 1959 + int il_mac_config(struct ieee80211_hw *hw, int radio_idx, u32 changed); 1960 1960 void il_mac_reset_tsf(struct ieee80211_hw *hw, struct ieee80211_vif *vif); 1961 1961 void il_mac_bss_info_changed(struct ieee80211_hw *hw, struct ieee80211_vif *vif, 1962 1962 struct ieee80211_bss_conf *bss_conf, u64 changes);
+1
drivers/net/wireless/intel/iwlwifi/Kconfig
··· 97 97 default y if IWLDVM=m 98 98 default y if IWLMVM=m 99 99 default y if IWLMLD=m 100 + default y if IWLWIFI_KUNIT_TESTS=m 100 101 101 102 comment "WARNING: iwlwifi is useless without IWLDVM or IWLMVM or IWLMLD" 102 103 depends on IWLDVM=n && IWLMVM=n && IWLMLD=n
+5 -3
drivers/net/wireless/intel/iwlwifi/Makefile
··· 7 7 iwlwifi-objs += iwl-nvm-utils.o 8 8 iwlwifi-objs += iwl-utils.o 9 9 iwlwifi-objs += iwl-phy-db.o iwl-nvm-parse.o 10 - iwlwifi-objs += pcie/drv.o pcie/rx.o pcie/tx.o pcie/trans.o 11 - iwlwifi-objs += pcie/ctxt-info.o pcie/ctxt-info-v2.o 12 - iwlwifi-objs += pcie/trans-gen2.o pcie/tx-gen2.o 10 + 11 + # Bus 12 + iwlwifi-objs += pcie/ctxt-info.o pcie/ctxt-info-v2.o pcie/drv.o pcie/utils.o 13 + iwlwifi-objs += pcie/gen1_2/rx.o pcie/gen1_2/tx.o pcie/gen1_2/trans.o 14 + iwlwifi-objs += pcie/gen1_2/trans-gen2.o pcie/gen1_2/tx-gen2.o 13 15 14 16 CFLAGS_pcie/drv.o += -Wno-override-init 15 17
+1 -1
drivers/net/wireless/intel/iwlwifi/cfg/bz.c
··· 13 13 #define IWL_BZ_UCODE_API_MAX 99 14 14 15 15 /* Lowest firmware API version supported */ 16 - #define IWL_BZ_UCODE_API_MIN 93 16 + #define IWL_BZ_UCODE_API_MIN 94 17 17 18 18 /* Memory offsets and lengths */ 19 19 #define IWL_BZ_SMEM_OFFSET 0x400000
+1 -1
drivers/net/wireless/intel/iwlwifi/cfg/dr.c
··· 12 12 #define IWL_DR_UCODE_API_MAX 99 13 13 14 14 /* Lowest firmware API version supported */ 15 - #define IWL_DR_UCODE_API_MIN 97 15 + #define IWL_DR_UCODE_API_MIN 98 16 16 17 17 /* Memory offsets and lengths */ 18 18 #define IWL_DR_SMEM_OFFSET 0x400000
+1 -1
drivers/net/wireless/intel/iwlwifi/cfg/sc.c
··· 13 13 #define IWL_SC_UCODE_API_MAX 99 14 14 15 15 /* Lowest firmware API version supported */ 16 - #define IWL_SC_UCODE_API_MIN 97 16 + #define IWL_SC_UCODE_API_MIN 98 17 17 18 18 /* NVM versions */ 19 19 #define IWL_SC_NVM_VERSION 0x0a1d
+3 -1
drivers/net/wireless/intel/iwlwifi/dvm/agn.h
··· 88 88 int iwlagn_set_pan_params(struct iwl_priv *priv); 89 89 int iwlagn_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *ctx); 90 90 void iwlagn_set_rxon_chain(struct iwl_priv *priv, struct iwl_rxon_context *ctx); 91 - int iwlagn_mac_config(struct ieee80211_hw *hw, u32 changed); 91 + int iwlagn_mac_config(struct ieee80211_hw *hw, int radio_idx, u32 changed); 92 92 void iwlagn_bss_info_changed(struct ieee80211_hw *hw, 93 93 struct ieee80211_vif *vif, 94 94 struct ieee80211_bss_conf *bss_conf, ··· 397 397 * returns a (newly allocated) struct containing all the 398 398 * relevant values for driver use. The struct must be freed 399 399 * later with iwl_free_nvm_data(). 400 + * 401 + * Return: the parsed NVM data 400 402 */ 401 403 struct iwl_nvm_data * 402 404 iwl_parse_eeprom_data(struct iwl_trans *trans, const struct iwl_rf_cfg *cfg,
+8 -8
drivers/net/wireless/intel/iwlwifi/dvm/commands.h
··· 1 1 /* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ 2 2 /* 3 - * Copyright (C) 2005-2014, 2023-2024 Intel Corporation 3 + * Copyright (C) 2005-2014, 2023-2025 Intel Corporation 4 4 */ 5 5 /* 6 6 * Please use this file (commands.h) only for uCode API definitions. ··· 614 614 * REPLY_CHANNEL_SWITCH = 0x72 (command, has simple generic response) 615 615 */ 616 616 /** 617 - * struct iwl5000_channel_switch_cmd 617 + * struct iwl5000_channel_switch_cmd - channel switch command (5000 series) 618 618 * @band: 0- 5.2GHz, 1- 2.4GHz 619 619 * @expect_beacon: 0- resume transmits after channel switch 620 620 * 1- wait for beacon to resume transmits ··· 635 635 } __packed; 636 636 637 637 /** 638 - * struct iwl6000_channel_switch_cmd 638 + * struct iwl6000_channel_switch_cmd - channel switch command (6000 series) 639 639 * @band: 0- 5.2GHz, 1- 2.4GHz 640 640 * @expect_beacon: 0- resume transmits after channel switch 641 641 * 1- wait for beacon to resume transmits ··· 791 791 } __packed; 792 792 793 793 /** 794 - * struct sta_id_modify 794 + * struct sta_id_modify - station modify command 795 795 * @addr: station's MAC address 796 796 * @reserved1: reserved for alignment 797 797 * @sta_id: index of station in uCode's station table ··· 2026 2026 u8 channel; 2027 2027 u8 type; /* see enum iwl_measurement_type */ 2028 2028 u8 reserved1; 2029 - /* NOTE: cca_ofdm, cca_cck, basic_type, and histogram are only only 2029 + /* NOTE: cca_ofdm, cca_cck, basic_type, and histogram are only 2030 2030 * valid if applicable for measurement type requested. */ 2031 2031 __le32 cca_ofdm; /* cca fraction time in 40Mhz clock periods */ 2032 2032 __le32 cca_cck; /* cca fraction time in 44Mhz clock periods */ ··· 2992 2992 #define SENSITIVITY_CMD_CONTROL_WORK_TABLE cpu_to_le16(1) 2993 2993 2994 2994 /** 2995 - * struct iwl_sensitivity_cmd 2995 + * struct iwl_sensitivity_cmd - sensitivity configuration command 2996 2996 * @control: (1) updates working table, (0) updates default table 2997 2997 * @table: energy threshold values, use HD_* as index into table 2998 2998 * ··· 3848 3848 #define IWL_MIN_SLOT_TIME 20 3849 3849 3850 3850 /** 3851 - * struct iwl_wipan_slot 3851 + * struct iwl_wipan_slot - WiPAN slot configuration 3852 3852 * @width: Time in TU 3853 3853 * @type: 3854 3854 * 0 - BSS ··· 3868 3868 #define IWL_WIPAN_PARAMS_FLG_FULL_SLOTTED_MODE BIT(5) 3869 3869 3870 3870 /** 3871 - * struct iwl_wipan_params_cmd 3871 + * struct iwl_wipan_params_cmd - WiPAN parameters 3872 3872 * @flags: 3873 3873 * bit0: reserved 3874 3874 * bit1: CP leave channel with CTS
+2 -2
drivers/net/wireless/intel/iwlwifi/dvm/dev.h
··· 104 104 }; 105 105 106 106 /** 107 - * enum iwl_agg_state 107 + * enum iwl_agg_state - aggregation state 108 108 * 109 109 * The state machine of the BA agreement establishment / tear down. 110 110 * These states relate to a specific RA / TID. ··· 519 519 }; 520 520 521 521 /** 522 - * struct iwl_hw_params 522 + * struct iwl_hw_params - HW parameters 523 523 * 524 524 * Holds the module parameters 525 525 *
+2
drivers/net/wireless/intel/iwlwifi/dvm/devices.c
··· 55 55 * iwl_beacon_time_mask_low - mask of lower 32 bit of beacon time 56 56 * @priv: pointer to iwl_priv data structure 57 57 * @tsf_bits: number of bits need to shift for masking) 58 + * Return: low 32 bits of beacon time mask 58 59 */ 59 60 static inline u32 iwl_beacon_time_mask_low(struct iwl_priv *priv, 60 61 u16 tsf_bits) ··· 67 66 * iwl_beacon_time_mask_high - mask of higher 32 bit of beacon time 68 67 * @priv: pointer to iwl_priv data structure 69 68 * @tsf_bits: number of bits need to shift for masking) 69 + * Return: high 32 bits of beacon time mask 70 70 */ 71 71 static inline u32 iwl_beacon_time_mask_high(struct iwl_priv *priv, 72 72 u16 tsf_bits)
+1 -1
drivers/net/wireless/intel/iwlwifi/dvm/lib.c
··· 586 586 return false; 587 587 } 588 588 589 - ave_rssi = ieee80211_ave_rssi(ctx->vif); 589 + ave_rssi = ieee80211_ave_rssi(ctx->vif, -1); 590 590 if (!ave_rssi) { 591 591 /* no rssi data, no changes to reduce tx power */ 592 592 IWL_DEBUG_COEX(priv, "no rssi data available\n");
+9 -2
drivers/net/wireless/intel/iwlwifi/dvm/main.c
··· 1049 1049 * 1050 1050 *****************************************************************************/ 1051 1051 1052 - static void iwl_setup_deferred_work(struct iwl_priv *priv) 1052 + static int iwl_setup_deferred_work(struct iwl_priv *priv) 1053 1053 { 1054 1054 priv->workqueue = alloc_ordered_workqueue(DRV_NAME, 0); 1055 + if (!priv->workqueue) 1056 + return -ENOMEM; 1055 1057 1056 1058 INIT_WORK(&priv->restart, iwl_bg_restart); 1057 1059 INIT_WORK(&priv->beacon_update, iwl_bg_beacon_update); ··· 1070 1068 timer_setup(&priv->statistics_periodic, iwl_bg_statistics_periodic, 0); 1071 1069 1072 1070 timer_setup(&priv->ucode_trace, iwl_bg_ucode_trace, 0); 1071 + 1072 + return 0; 1073 1073 } 1074 1074 1075 1075 void iwl_cancel_deferred_work(struct iwl_priv *priv) ··· 1467 1463 /******************** 1468 1464 * 6. Setup services 1469 1465 ********************/ 1470 - iwl_setup_deferred_work(priv); 1466 + if (iwl_setup_deferred_work(priv)) 1467 + goto out_uninit_drv; 1468 + 1471 1469 iwl_setup_rx_handlers(priv); 1472 1470 1473 1471 iwl_power_initialize(priv); ··· 1508 1502 iwl_cancel_deferred_work(priv); 1509 1503 destroy_workqueue(priv->workqueue); 1510 1504 priv->workqueue = NULL; 1505 + out_uninit_drv: 1511 1506 iwl_uninit_drv(priv); 1512 1507 out_free_eeprom_blob: 1513 1508 kfree(priv->eeprom_blob);
-2
drivers/net/wireless/intel/iwlwifi/dvm/power.h
··· 23 23 int iwl_power_update_mode(struct iwl_priv *priv, bool force); 24 24 void iwl_power_initialize(struct iwl_priv *priv); 25 25 26 - extern bool no_sleep_autoadjust; 27 - 28 26 #endif /* __iwl_power_setting_h__ */
+1 -1
drivers/net/wireless/intel/iwlwifi/dvm/rs.c
··· 2899 2899 /* Repeat initial/next rate. 2900 2900 * For legacy IWL_NUMBER_TRY == 1, this loop will not execute. 2901 2901 * For HT IWL_HT_NUMBER_TRY == 3, this executes twice. */ 2902 - while (repeat_rate > 0 && (index < LINK_QUAL_MAX_RETRY_NUM)) { 2902 + while (repeat_rate > 0 && index < (LINK_QUAL_MAX_RETRY_NUM - 1)) { 2903 2903 if (is_legacy(tbl_type.lq_type)) { 2904 2904 if (ant_toggle_cnt < NUM_TRY_BEFORE_ANT_TOGGLE) 2905 2905 ant_toggle_cnt++;
+1 -1
drivers/net/wireless/intel/iwlwifi/dvm/rx.c
··· 429 429 * thermal update even if the uCode doesn't give 430 430 * us one */ 431 431 mod_timer(&priv->statistics_periodic, jiffies + 432 - msecs_to_jiffies(reg_recalib_period * 1000)); 432 + secs_to_jiffies(reg_recalib_period)); 433 433 434 434 if (unlikely(!test_bit(STATUS_SCANNING, &priv->status)) && 435 435 (pkt->hdr.cmd == STATISTICS_NOTIFICATION)) {
+1 -1
drivers/net/wireless/intel/iwlwifi/dvm/rxon.c
··· 1149 1149 } 1150 1150 } 1151 1151 1152 - int iwlagn_mac_config(struct ieee80211_hw *hw, u32 changed) 1152 + int iwlagn_mac_config(struct ieee80211_hw *hw, int radio_idx, u32 changed) 1153 1153 { 1154 1154 struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw); 1155 1155 struct iwl_rxon_context *ctx;
+2
drivers/net/wireless/intel/iwlwifi/dvm/tx.c
··· 232 232 * that may be %NULL, for example during TX or key setup. In 233 233 * that case, we need to use the broadcast station, so this 234 234 * inline wraps that pattern. 235 + * 236 + * Return: station ID for mac80211 station (or broadcast if %NULL) 235 237 */ 236 238 static int iwl_sta_id_or_broadcast(struct iwl_rxon_context *context, 237 239 struct ieee80211_sta *sta)
+4 -2
drivers/net/wireless/intel/iwlwifi/fw/api/d3.h
··· 1 1 /* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ 2 2 /* 3 - * Copyright (C) 2012-2014, 2018-2024 Intel Corporation 3 + * Copyright (C) 2012-2014, 2018-2025 Intel Corporation 4 4 * Copyright (C) 2013-2014 Intel Mobile Communications GmbH 5 5 * Copyright (C) 2015-2017 Intel Deutschland GmbH 6 6 */ ··· 19 19 /** 20 20 * enum iwl_d3_wakeup_flags - D3 manager wakeup flags 21 21 * @IWL_WAKEUP_D3_CONFIG_FW_ERROR: wake up on firmware sysassert 22 + * @IWL_WAKEUP_D3_HOST_TIMER: wake up on host timer expiry 22 23 */ 23 24 enum iwl_d3_wakeup_flags { 24 - IWL_WAKEUP_D3_CONFIG_FW_ERROR = BIT(0), 25 + IWL_WAKEUP_D3_CONFIG_FW_ERROR = BIT(0), 26 + IWL_WAKEUP_D3_HOST_TIMER = BIT(1), 25 27 }; /* D3_MANAGER_WAKEUP_CONFIG_API_E_VER_3 */ 26 28 27 29 /**
+1 -1
drivers/net/wireless/intel/iwlwifi/fw/api/tx.h
··· 864 864 865 865 /** 866 866 * enum iwl_dump_control - dump (flush) control flags 867 - * @DUMP_TX_FIFO_FLUSH: Dump MSDUs until the the FIFO is empty 867 + * @DUMP_TX_FIFO_FLUSH: Dump MSDUs until the FIFO is empty 868 868 * and the TFD queues are empty. 869 869 */ 870 870 enum iwl_dump_control {
+25 -9
drivers/net/wireless/intel/iwlwifi/fw/dbg.c
··· 1106 1106 u32 prph_val; 1107 1107 u32 dphy_state; 1108 1108 u32 dphy_addr; 1109 + u32 prph_stts; 1109 1110 int i; 1110 1111 1111 1112 range->internal_base_addr = cpu_to_le32(addr); ··· 1134 1133 1135 1134 iwl_write_prph_no_grab(fwrt->trans, indirect_wr_addr, 1136 1135 WMAL_INDRCT_CMD(addr + i)); 1136 + 1137 + if (fwrt->trans->info.hw_rf_id != IWL_CFG_RF_TYPE_JF1 && 1138 + fwrt->trans->info.hw_rf_id != IWL_CFG_RF_TYPE_JF2 && 1139 + fwrt->trans->info.hw_rf_id != IWL_CFG_RF_TYPE_HR1 && 1140 + fwrt->trans->info.hw_rf_id != IWL_CFG_RF_TYPE_HR2) { 1141 + udelay(2); 1142 + prph_stts = iwl_read_prph_no_grab(fwrt->trans, 1143 + WMAL_MRSPF_STTS); 1144 + 1145 + /* Abort dump if status is 0xA5A5A5A2 or FIFO1 empty */ 1146 + if (prph_stts == WMAL_TIMEOUT_VAL || 1147 + !WMAL_MRSPF_STTS_IS_FIFO1_NOT_EMPTY(prph_stts)) 1148 + break; 1149 + } 1150 + 1137 1151 prph_val = iwl_read_prph_no_grab(fwrt->trans, 1138 1152 indirect_rd_addr); 1139 1153 *val++ = cpu_to_le32(prph_val); ··· 3024 3008 struct iwl_fw_dump_desc *desc; 3025 3009 unsigned int delay = 0; 3026 3010 bool monitor_only = false; 3011 + int ret; 3027 3012 3028 3013 if (trigger) { 3029 3014 u16 occurrences = le16_to_cpu(trigger->occurrences) - 1; ··· 3055 3038 desc->trig_desc.type = cpu_to_le32(trig); 3056 3039 memcpy(desc->trig_desc.data, str, len); 3057 3040 3058 - return iwl_fw_dbg_collect_desc(fwrt, desc, monitor_only, delay); 3041 + ret = iwl_fw_dbg_collect_desc(fwrt, desc, monitor_only, delay); 3042 + if (ret) 3043 + kfree(desc); 3044 + 3045 + return ret; 3059 3046 } 3060 3047 IWL_EXPORT_SYMBOL(iwl_fw_dbg_collect); 3061 3048 ··· 3067 3046 struct iwl_fw_dbg_trigger_tlv *trigger, 3068 3047 const char *fmt, ...) 3069 3048 { 3070 - int ret, len = 0; 3049 + int len = 0; 3071 3050 char buf[64]; 3072 3051 3073 3052 if (iwl_trans_dbg_ini_valid(fwrt->trans)) ··· 3089 3068 len = strlen(buf) + 1; 3090 3069 } 3091 3070 3092 - ret = iwl_fw_dbg_collect(fwrt, le32_to_cpu(trigger->id), buf, len, 3093 - trigger); 3094 - 3095 - if (ret) 3096 - return ret; 3097 - 3098 - return 0; 3071 + return iwl_fw_dbg_collect(fwrt, le32_to_cpu(trigger->id), buf, len, 3072 + trigger); 3099 3073 } 3100 3074 IWL_EXPORT_SYMBOL(iwl_fw_dbg_collect_trig); 3101 3075
+1 -1
drivers/net/wireless/intel/iwlwifi/fw/debugfs.c
··· 198 198 199 199 iwl_fw_cancel_timestamp(fwrt); 200 200 201 - fwrt->timestamp.delay = msecs_to_jiffies(delay * 1000); 201 + fwrt->timestamp.delay = secs_to_jiffies(delay); 202 202 203 203 schedule_delayed_work(&fwrt->timestamp.wk, 204 204 round_jiffies_relative(fwrt->timestamp.delay));
+2 -2
drivers/net/wireless/intel/iwlwifi/fw/img.h
··· 53 53 u32 num_stations; 54 54 u32 num_links; 55 55 u32 num_beacons; 56 - unsigned long _api[BITS_TO_LONGS(NUM_IWL_UCODE_TLV_API)]; 57 - unsigned long _capa[BITS_TO_LONGS(NUM_IWL_UCODE_TLV_CAPA)]; 56 + DECLARE_BITMAP(_api, NUM_IWL_UCODE_TLV_API); 57 + DECLARE_BITMAP(_capa, NUM_IWL_UCODE_TLV_CAPA); 58 58 59 59 const struct iwl_fw_cmd_version *cmd_versions; 60 60 u32 n_cmd_versions;
+1 -1
drivers/net/wireless/intel/iwlwifi/fw/pnvm.c
··· 332 332 ret = iwl_trans_load_pnvm(trans, pnvm_data, capa); 333 333 if (ret) 334 334 goto free; 335 - IWL_INFO(trans, "loaded PNVM version %08x\n", pnvm_data->version); 335 + IWL_DEBUG_INFO(trans, "loaded PNVM version %08x\n", pnvm_data->version); 336 336 337 337 set: 338 338 iwl_trans_set_pnvm(trans, capa);
+3 -3
drivers/net/wireless/intel/iwlwifi/iwl-context-info-v2.h drivers/net/wireless/intel/iwlwifi/pcie/iwl-context-info-v2.h
··· 130 130 } __packed; /* PERIPH_SCRATCH_PNVM_CFG_S */ 131 131 132 132 /** 133 - * struct iwl_prph_scrath_mem_desc_addr_array 133 + * struct iwl_prph_scratch_mem_desc_addr_array - DRAM 134 134 * @mem_descs: array of dram addresses. 135 - * Each address is the beggining of a pnvm payload. 135 + * Each address is the beginning of a PNVM payload. 136 136 */ 137 - struct iwl_prph_scrath_mem_desc_addr_array { 137 + struct iwl_prph_scratch_mem_desc_addr_array { 138 138 __le64 mem_descs[IPC_DRAM_MAP_ENTRY_NUM_MAX]; 139 139 } __packed; /* PERIPH_SCRATCH_MEM_DESC_ADDR_ARRAY_S_VER_1 */ 140 140
drivers/net/wireless/intel/iwlwifi/iwl-context-info.h drivers/net/wireless/intel/iwlwifi/pcie/iwl-context-info.h
+1
drivers/net/wireless/intel/iwlwifi/iwl-csr.h
··· 113 113 #define CSR_IPC_STATE_RESET_SW_READY 1 114 114 #define CSR_IPC_STATE_RESET_TOP_READY 2 115 115 #define CSR_IPC_STATE_RESET_TOP_FOLLOWER 3 116 + #define CSR_IPC_STATE_TOP_RESET_REQ BIT(6) 116 117 117 118 #define CSR_IPC_SLEEP_CONTROL (CSR_BASE + 0x114) 118 119 #define CSR_IPC_SLEEP_CONTROL_SUSPEND 0x3
+2 -2
drivers/net/wireless/intel/iwlwifi/iwl-drv.c
··· 1276 1276 1277 1277 if (tlv_len != sizeof(*fseq_ver)) 1278 1278 goto invalid_tlv_len; 1279 - IWL_INFO(drv, "TLV_FW_FSEQ_VERSION: %.32s\n", 1280 - fseq_ver->version); 1279 + IWL_DEBUG_INFO(drv, "TLV_FW_FSEQ_VERSION: %.32s\n", 1280 + fseq_ver->version); 1281 1281 } 1282 1282 break; 1283 1283 case IWL_UCODE_TLV_FW_NUM_STATIONS:
+27 -22
drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c
··· 160 160 * @NVM_CHANNEL_DC_HIGH: DC HIGH required/allowed (?) 161 161 * @NVM_CHANNEL_VLP: client support connection to UHB VLP AP 162 162 * @NVM_CHANNEL_AFC: client support connection to UHB AFC AP 163 + * @NVM_CHANNEL_VLP_AP_NOT_ALLOWED: UHB VLP AP not allowed, 164 + * Valid only when %NVM_CHANNEL_VLP is enabled. 163 165 */ 164 166 enum iwl_nvm_channel_flags { 165 - NVM_CHANNEL_VALID = BIT(0), 166 - NVM_CHANNEL_IBSS = BIT(1), 167 - NVM_CHANNEL_ALLOW_20MHZ_ACTIVITY = BIT(2), 168 - NVM_CHANNEL_ACTIVE = BIT(3), 169 - NVM_CHANNEL_RADAR = BIT(4), 170 - NVM_CHANNEL_INDOOR_ONLY = BIT(5), 171 - NVM_CHANNEL_GO_CONCURRENT = BIT(6), 172 - NVM_CHANNEL_UNIFORM = BIT(7), 173 - NVM_CHANNEL_20MHZ = BIT(8), 174 - NVM_CHANNEL_40MHZ = BIT(9), 175 - NVM_CHANNEL_80MHZ = BIT(10), 176 - NVM_CHANNEL_160MHZ = BIT(11), 177 - NVM_CHANNEL_DC_HIGH = BIT(12), 178 - NVM_CHANNEL_VLP = BIT(13), 179 - NVM_CHANNEL_AFC = BIT(14), 167 + NVM_CHANNEL_VALID = BIT(0), 168 + NVM_CHANNEL_IBSS = BIT(1), 169 + NVM_CHANNEL_ALLOW_20MHZ_ACTIVITY = BIT(2), 170 + NVM_CHANNEL_ACTIVE = BIT(3), 171 + NVM_CHANNEL_RADAR = BIT(4), 172 + NVM_CHANNEL_INDOOR_ONLY = BIT(5), 173 + NVM_CHANNEL_GO_CONCURRENT = BIT(6), 174 + NVM_CHANNEL_UNIFORM = BIT(7), 175 + NVM_CHANNEL_20MHZ = BIT(8), 176 + NVM_CHANNEL_40MHZ = BIT(9), 177 + NVM_CHANNEL_80MHZ = BIT(10), 178 + NVM_CHANNEL_160MHZ = BIT(11), 179 + NVM_CHANNEL_DC_HIGH = BIT(12), 180 + NVM_CHANNEL_VLP = BIT(13), 181 + NVM_CHANNEL_AFC = BIT(14), 182 + NVM_CHANNEL_VLP_AP_NOT_ALLOWED = BIT(15), 180 183 }; 181 184 182 185 /** ··· 1047 1044 case IWL_CFG_RF_TYPE_GF: 1048 1045 case IWL_CFG_RF_TYPE_FM: 1049 1046 case IWL_CFG_RF_TYPE_WH: 1047 + case IWL_CFG_RF_TYPE_PE: 1050 1048 iftype_data->he_cap.he_cap_elem.phy_cap_info[9] |= 1051 1049 IEEE80211_HE_PHY_CAP9_TX_1024_QAM_LESS_THAN_242_TONE_RU; 1052 1050 if (!is_ap) ··· 1633 1629 1634 1630 static u32 iwl_nvm_get_regdom_bw_flags(const u16 *nvm_chan, 1635 1631 int ch_idx, u16 nvm_flags, 1636 - struct iwl_reg_capa reg_capa, 1637 - const struct iwl_rf_cfg *cfg) 1632 + struct iwl_reg_capa reg_capa) 1638 1633 { 1639 1634 u32 flags = NL80211_RRF_NO_HT40; 1640 1635 ··· 1688 1685 } 1689 1686 1690 1687 /* Set the AP type for the UHB case. */ 1691 - if (nvm_flags & NVM_CHANNEL_VLP) 1692 - flags |= NL80211_RRF_ALLOW_6GHZ_VLP_AP; 1693 - else 1688 + if (nvm_flags & NVM_CHANNEL_VLP) { 1689 + if (!(nvm_flags & NVM_CHANNEL_VLP_AP_NOT_ALLOWED)) 1690 + flags |= NL80211_RRF_ALLOW_6GHZ_VLP_AP; 1691 + } else { 1694 1692 flags |= NL80211_RRF_NO_6GHZ_VLP_CLIENT; 1693 + } 1695 1694 1696 1695 if (!(nvm_flags & NVM_CHANNEL_AFC)) 1697 1696 flags |= NL80211_RRF_NO_6GHZ_AFC_CLIENT; ··· 1820 1815 } 1821 1816 1822 1817 reg_rule_flags = iwl_nvm_get_regdom_bw_flags(nvm_chan, ch_idx, 1823 - ch_flags, reg_capa, 1824 - cfg); 1818 + ch_flags, 1819 + reg_capa); 1825 1820 1826 1821 /* we can't continue the same rule */ 1827 1822 if (ch_idx == 0 || prev_reg_rule_flags != reg_rule_flags ||
+10
drivers/net/wireless/intel/iwlwifi/iwl-op-mode.h
··· 147 147 * Op_mode needs to reset its internal state because the device did not 148 148 * survive the system state transition. The firmware is no longer running, 149 149 * etc... 150 + * @dump: Op_mode needs to collect the firmware dump upon this handler 151 + * being called. 150 152 */ 151 153 struct iwl_op_mode_ops { 152 154 struct iwl_op_mode *(*start)(struct iwl_trans *trans, ··· 176 174 enum iwl_fw_ini_time_point tp_id, 177 175 union iwl_dbg_tlv_tp_data *tp_data); 178 176 void (*device_powered_off)(struct iwl_op_mode *op_mode); 177 + void (*dump)(struct iwl_op_mode *op_mode); 179 178 }; 180 179 181 180 int iwl_opmode_register(const char *name, const struct iwl_op_mode_ops *ops); ··· 287 284 if (!op_mode || !op_mode->ops || !op_mode->ops->device_powered_off) 288 285 return; 289 286 op_mode->ops->device_powered_off(op_mode); 287 + } 288 + 289 + static inline void iwl_op_mode_dump(struct iwl_op_mode *op_mode) 290 + { 291 + if (!op_mode || !op_mode->ops || !op_mode->ops->dump) 292 + return; 293 + op_mode->ops->dump(op_mode); 290 294 } 291 295 292 296 #endif /* __iwl_op_mode_h__ */
+9 -1
drivers/net/wireless/intel/iwlwifi/iwl-prph.h
··· 1 1 /* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ 2 2 /* 3 - * Copyright (C) 2005-2014, 2018-2024 Intel Corporation 3 + * Copyright (C) 2005-2014, 2018-2025 Intel Corporation 4 4 * Copyright (C) 2013-2015 Intel Mobile Communications GmbH 5 5 * Copyright (C) 2016 Intel Deutschland GmbH 6 6 */ ··· 514 514 #define WMAL_INDRCT_CMD(addr) \ 515 515 ((WMAL_CMD_READ_BURST_ACCESS << WMAL_INDRCT_RD_CMD1_OPMOD_POS) | \ 516 516 ((addr) & WMAL_INDRCT_RD_CMD1_BYTE_ADDRESS_MSK)) 517 + #define WMAL_MRSPF_STTS 0xADFC24 518 + #define WMAL_MRSPF_STTS_FIFO1_NOT_EMPTY_POS 15 519 + #define WMAL_MRSPF_STTS_FIFO1_NOT_EMPTY_MSK 0x8000 520 + #define WMAL_TIMEOUT_VAL 0xA5A5A5A2 521 + #define WMAL_MRSPF_STTS_IS_FIFO1_NOT_EMPTY(val) \ 522 + (((val) >> (WMAL_MRSPF_STTS_FIFO1_NOT_EMPTY_POS)) & \ 523 + ((WMAL_MRSPF_STTS_FIFO1_NOT_EMPTY_MSK) >> \ 524 + (WMAL_MRSPF_STTS_FIFO1_NOT_EMPTY_POS))) 517 525 518 526 #define WFPM_LMAC1_PS_CTL_RW 0xA03380 519 527 #define WFPM_LMAC2_PS_CTL_RW 0xA033C0
+15 -3
drivers/net/wireless/intel/iwlwifi/iwl-trans.c
··· 14 14 #include "iwl-fh.h" 15 15 #include <linux/dmapool.h> 16 16 #include "fw/api/commands.h" 17 - #include "pcie/internal.h" 18 - #include "iwl-context-info-v2.h" 17 + #include "pcie/gen1_2/internal.h" 18 + #include "pcie/iwl-context-info-v2.h" 19 19 20 20 struct iwl_trans_dev_restart_data { 21 21 struct list_head list; ··· 497 497 int iwl_trans_write_mem(struct iwl_trans *trans, u32 addr, 498 498 const void *buf, int dwords) 499 499 { 500 - return iwl_trans_pcie_write_mem(trans, addr, buf, dwords); 500 + int offs, ret = 0; 501 + const u32 *vals = buf; 502 + 503 + if (iwl_trans_grab_nic_access(trans)) { 504 + iwl_write32(trans, HBUS_TARG_MEM_WADDR, addr); 505 + for (offs = 0; offs < dwords; offs++) 506 + iwl_write32(trans, HBUS_TARG_MEM_WDAT, 507 + vals ? vals[offs] : 0); 508 + iwl_trans_release_nic_access(trans); 509 + } else { 510 + ret = -EBUSY; 511 + } 512 + return ret; 501 513 } 502 514 IWL_EXPORT_SYMBOL(iwl_trans_write_mem); 503 515
+112 -1
drivers/net/wireless/intel/iwlwifi/iwl-utils.c
··· 1 1 /* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ 2 2 /* 3 - * Copyright (C) 2024 Intel Corporation 3 + * Copyright (C) 2024-2025 Intel Corporation 4 4 */ 5 5 #include <net/gso.h> 6 6 #include <linux/ieee80211.h> ··· 82 82 } 83 83 IWL_EXPORT_SYMBOL(iwl_tx_tso_segment); 84 84 #endif /* CONFIG_INET */ 85 + 86 + static u32 iwl_div_by_db(u32 value, u8 db) 87 + { 88 + /* 89 + * 2^32 * 10**(i / 10) for i = [1, 10], skipping 0 and simply stopping 90 + * at 10 dB and looping instead of using a much larger table. 91 + * 92 + * Using 64 bit math is overkill, but means the helper does not require 93 + * a limit on the input range. 94 + */ 95 + static const u32 db_to_val[] = { 96 + 0xcb59185e, 0xa1866ba8, 0x804dce7a, 0x65ea59fe, 0x50f44d89, 97 + 0x404de61f, 0x331426af, 0x2892c18b, 0x203a7e5b, 0x1999999a, 98 + }; 99 + 100 + while (value && db > 0) { 101 + u8 change = min_t(u8, db, ARRAY_SIZE(db_to_val)); 102 + 103 + value = (((u64)value) * db_to_val[change - 1]) >> 32; 104 + 105 + db -= change; 106 + } 107 + 108 + return value; 109 + } 110 + 111 + s8 iwl_average_neg_dbm(const u8 *neg_dbm_values, u8 len) 112 + { 113 + int average_magnitude; 114 + u32 average_factor; 115 + int sum_magnitude = -128; 116 + u32 sum_factor = 0; 117 + int i, count = 0; 118 + 119 + /* 120 + * To properly average the decibel values (signal values given in dBm) 121 + * we need to do the math in linear space. Doing a linear average of 122 + * dB (dBm) values is a bit annoying though due to the large range of 123 + * at least -10 to -110 dBm that will not fit into a 32 bit integer. 124 + * 125 + * A 64 bit integer should be sufficient, but then we still have the 126 + * problem that there are no directly usable utility functions 127 + * available. 128 + * 129 + * So, lets not deal with that and instead do much of the calculation 130 + * with a 16.16 fixed point integer along with a base in dBm. 16.16 bit 131 + * gives us plenty of head-room for adding up a few values and even 132 + * doing some math on it. And the tail should be accurate enough too 133 + * (1/2^16 is somewhere around -48 dB, so effectively zero). 134 + * 135 + * i.e. the real value of sum is: 136 + * sum = sum_factor / 2^16 * 10^(sum_magnitude / 10) mW 137 + * 138 + * However, that does mean we need to be able to bring two values to 139 + * a common base, so we need a helper for that. 140 + * 141 + * Note that this function takes an input with unsigned negative dBm 142 + * values but returns a signed dBm (i.e. a negative value). 143 + */ 144 + 145 + for (i = 0; i < len; i++) { 146 + int val_magnitude; 147 + u32 val_factor; 148 + 149 + /* Assume invalid */ 150 + if (neg_dbm_values[i] == 0xff) 151 + continue; 152 + 153 + val_factor = 0x10000; 154 + val_magnitude = -neg_dbm_values[i]; 155 + 156 + if (val_magnitude <= sum_magnitude) { 157 + u8 div_db = sum_magnitude - val_magnitude; 158 + 159 + val_factor = iwl_div_by_db(val_factor, div_db); 160 + val_magnitude = sum_magnitude; 161 + } else { 162 + u8 div_db = val_magnitude - sum_magnitude; 163 + 164 + sum_factor = iwl_div_by_db(sum_factor, div_db); 165 + sum_magnitude = val_magnitude; 166 + } 167 + 168 + sum_factor += val_factor; 169 + count++; 170 + } 171 + 172 + /* No valid noise measurement, return a very high noise level */ 173 + if (count == 0) 174 + return 0; 175 + 176 + average_magnitude = sum_magnitude; 177 + average_factor = sum_factor / count; 178 + 179 + /* 180 + * average_factor will be a number smaller than 1.0 (0x10000) at this 181 + * point. What we need to do now is to adjust average_magnitude so that 182 + * average_factor is between -0.5 dB and 0.5 dB. 183 + * 184 + * Just do -1 dB steps and find the point where 185 + * -0.5 dB * -i dB = 0x10000 * 10^(-0.5/10) / i dB 186 + * = div_by_db(0xe429, i) 187 + * is smaller than average_factor. 188 + */ 189 + for (i = 0; average_factor < iwl_div_by_db(0xe429, i); i++) { 190 + /* nothing */ 191 + } 192 + 193 + return clamp(average_magnitude - i, -128, 0); 194 + } 195 + IWL_EXPORT_SYMBOL(iwl_average_neg_dbm);
+3 -1
drivers/net/wireless/intel/iwlwifi/iwl-utils.h
··· 1 1 /* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ 2 2 /* 3 - * Copyright (C) 2024 Intel Corporation 3 + * Copyright (C) 2024-2025 Intel Corporation 4 4 */ 5 5 #ifndef __iwl_utils_h__ 6 6 #define __iwl_utils_h__ ··· 52 52 53 53 return ie - beacon; 54 54 } 55 + 56 + s8 iwl_average_neg_dbm(const u8 *neg_dbm_values, u8 len); 55 57 56 58 #endif /* __iwl_utils_h__ */
+15 -15
drivers/net/wireless/intel/iwlwifi/mei/sap.h
··· 1 1 /* SPDX-License-Identifier: GPL-2.0-only */ 2 2 /* 3 - * Copyright (C) 2021 - 2022 Intel Corporation 3 + * Copyright (C) 2021 - 2022, 2025 Intel Corporation 4 4 */ 5 5 6 6 #ifndef __sap_h__ ··· 340 340 }; 341 341 342 342 /** 343 - * enum iwl_sap_wifi_cipher_alg 344 - * @SAP_WIFI_CIPHER_ALG_NONE: TBD 345 - * @SAP_WIFI_CIPHER_ALG_TKIP: TBD 346 - * @SAP_WIFI_CIPHER_ALG_CCMP: TBD 347 - * @SAP_WIFI_CIPHER_ALG_GCMP: TBD 348 - * @SAP_WIFI_CIPHER_ALG_GCMP_256: TBD 343 + * enum iwl_sap_wifi_cipher_alg - MEI WiFi cipher algorithm IDs 344 + * @SAP_WIFI_CIPHER_ALG_NONE: No encryption 345 + * @SAP_WIFI_CIPHER_ALG_TKIP: TKIPO 346 + * @SAP_WIFI_CIPHER_ALG_CCMP: CCMP 347 + * @SAP_WIFI_CIPHER_ALG_GCMP: GCMP-128 348 + * @SAP_WIFI_CIPHER_ALG_GCMP_256: GCMP-256 349 349 */ 350 350 enum iwl_sap_wifi_cipher_alg { 351 351 SAP_WIFI_CIPHER_ALG_NONE = IWL_MEI_CIPHER_NONE, ··· 601 601 }; 602 602 603 603 /** 604 - * struct iwl_sap_flex_filter - 604 + * struct iwl_sap_flex_filter - filter configuration 605 605 * @src_port: Source port in network format. 606 606 * @dst_port: Destination port in network format. 607 607 * @flags: Flags and protocol, see &enum iwl_sap_flex_filter_flags. ··· 633 633 }; 634 634 635 635 /** 636 - * struct iwl_sap_ipv4_filter- 636 + * struct iwl_sap_ipv4_filter - IPv4 filter configuration 637 637 * @ipv4_addr: The IP address to filer. 638 638 * @flags: See &enum iwl_sap_ipv4_filter_flags. 639 639 */ ··· 643 643 } __packed; 644 644 645 645 /** 646 - * enum iwl_sap_ipv6_filter_flags - 646 + * enum iwl_sap_ipv6_filter_flags - IPv6 filter flags 647 647 * @SAP_IPV6_ADDR_FILTER_COPY: Pass packets to the host. 648 648 * @SAP_IPV6_ADDR_FILTER_ENABLED: If false, the filter should be ignored. 649 649 */ ··· 653 653 }; 654 654 655 655 /** 656 - * struct iwl_sap_ipv6_filter - 656 + * struct iwl_sap_ipv6_filter - IPv6 filter configuration 657 657 * @addr_lo24: Lowest 24 bits of the IPv6 address. 658 658 * @flags: See &enum iwl_sap_ipv6_filter_flags. 659 659 */ ··· 663 663 } __packed; 664 664 665 665 /** 666 - * enum iwl_sap_icmpv6_filter_flags - 666 + * enum iwl_sap_icmpv6_filter_flags - ICMPv6 filter flags 667 667 * @SAP_ICMPV6_FILTER_ENABLED: If false, the filter should be ignored. 668 668 * @SAP_ICMPV6_FILTER_COPY: Pass packets to the host. 669 669 */ ··· 673 673 }; 674 674 675 675 /** 676 - * enum iwl_sap_vlan_filter_flags - 677 - * @SAP_VLAN_FILTER_VLAN_ID_MSK: TBD 676 + * enum iwl_sap_vlan_filter_flags - VLAN filter flags 677 + * @SAP_VLAN_FILTER_VLAN_ID_MSK: VLAN ID 678 678 * @SAP_VLAN_FILTER_ENABLED: If false, the filter should be ignored. 679 679 */ 680 680 enum iwl_sap_vlan_filter_flags { ··· 751 751 } __packed; 752 752 753 753 /** 754 - * enum iwl_sap_pldr_status - 754 + * enum iwl_sap_pldr_status - product reset status 755 755 * @SAP_PLDR_STATUS_SUCCESS: PLDR started/ended successfully 756 756 * @SAP_PLDR_STATUS_FAILURE: PLDR failed to start/end 757 757 */
-4
drivers/net/wireless/intel/iwlwifi/mld/Makefile
··· 9 9 iwlmld-$(CONFIG_IWLWIFI_LEDS) += led.o 10 10 iwlmld-$(CONFIG_PM_SLEEP) += d3.o 11 11 12 - # non-upstream things 13 - iwlmld-$(CONFIG_IWL_VENDOR_CMDS) += vendor-cmd.o 14 - iwlmld-$(CONFIG_IWLMVM_AX_SOFTAP_TESTMODE) += ax-softap-testmode.o 15 - 16 12 subdir-ccflags-y += -I$(src)/../
+13 -76
drivers/net/wireless/intel/iwlwifi/mld/d3.c
··· 204 204 } 205 205 #endif 206 206 207 - enum rt_status { 208 - FW_ALIVE, 209 - FW_NEEDS_RESET, 210 - FW_ERROR, 211 - }; 212 - 213 - static enum rt_status iwl_mld_check_err_tables(struct iwl_mld *mld, 214 - struct ieee80211_vif *vif) 215 - { 216 - u32 err_id; 217 - 218 - /* check for lmac1 error */ 219 - if (iwl_fwrt_read_err_table(mld->trans, 220 - mld->trans->dbg.lmac_error_event_table[0], 221 - &err_id)) { 222 - if (err_id == RF_KILL_INDICATOR_FOR_WOWLAN && vif) { 223 - struct cfg80211_wowlan_wakeup wakeup = { 224 - .rfkill_release = true, 225 - }; 226 - ieee80211_report_wowlan_wakeup(vif, &wakeup, 227 - GFP_KERNEL); 228 - 229 - return FW_NEEDS_RESET; 230 - } 231 - return FW_ERROR; 232 - } 233 - 234 - /* check if we have lmac2 set and check for error */ 235 - if (iwl_fwrt_read_err_table(mld->trans, 236 - mld->trans->dbg.lmac_error_event_table[1], 237 - NULL)) 238 - return FW_ERROR; 239 - 240 - /* check for umac error */ 241 - if (iwl_fwrt_read_err_table(mld->trans, 242 - mld->trans->dbg.umac_error_event_table, 243 - NULL)) 244 - return FW_ERROR; 245 - 246 - return FW_ALIVE; 247 - } 248 - 249 - static bool iwl_mld_fw_needs_restart(struct iwl_mld *mld, 250 - struct ieee80211_vif *vif) 251 - { 252 - enum rt_status rt_status = iwl_mld_check_err_tables(mld, vif); 253 - 254 - if (rt_status == FW_ALIVE) 255 - return false; 256 - 257 - if (rt_status == FW_ERROR) { 258 - IWL_ERR(mld, "FW Error occurred during suspend\n"); 259 - iwl_fwrt_dump_error_logs(&mld->fwrt); 260 - iwl_dbg_tlv_time_point(&mld->fwrt, 261 - IWL_FW_INI_TIME_POINT_FW_ASSERT, NULL); 262 - } 263 - 264 - return true; 265 - } 266 - 267 207 static int 268 208 iwl_mld_netdetect_config(struct iwl_mld *mld, 269 209 struct ieee80211_vif *vif, ··· 868 928 return true; 869 929 } 870 930 871 - static bool 931 + static void 872 932 iwl_mld_add_all_rekeys(struct ieee80211_vif *vif, 873 933 struct iwl_mld_wowlan_status *wowlan_status, 874 934 struct iwl_mld_resume_key_iter_data *key_iter_data, ··· 881 941 &wowlan_status->gtk[i], 882 942 link_conf, 883 943 key_iter_data->gtk_cipher)) 884 - return false; 944 + return; 885 945 886 946 if (!iwl_mld_add_mcast_rekey(vif, key_iter_data->mld, 887 947 &wowlan_status->igtk, 888 948 link_conf, key_iter_data->igtk_cipher)) 889 - return false; 949 + return; 890 950 891 951 for (i = 0; i < ARRAY_SIZE(wowlan_status->bigtk); i++) 892 952 if (!iwl_mld_add_mcast_rekey(vif, key_iter_data->mld, 893 953 &wowlan_status->bigtk[i], 894 954 link_conf, 895 955 key_iter_data->bigtk_cipher)) 896 - return false; 897 - 898 - return true; 956 + return; 899 957 } 900 958 901 959 static bool ··· 1255 1317 struct iwl_d3_manager_config d3_cfg_cmd_data = {}; 1256 1318 int ret; 1257 1319 1320 + if (mld->debug_max_sleep) { 1321 + d3_cfg_cmd_data.wakeup_host_timer = 1322 + cpu_to_le32(mld->debug_max_sleep); 1323 + d3_cfg_cmd_data.wakeup_flags = 1324 + cpu_to_le32(IWL_WAKEUP_D3_HOST_TIMER); 1325 + } 1326 + 1258 1327 lockdep_assert_wiphy(mld->wiphy); 1259 1328 1260 1329 IWL_DEBUG_WOWLAN(mld, "Starting the no wowlan suspend flow\n"); ··· 1321 1376 mld->fw_status.in_d3 = false; 1322 1377 iwl_fw_dbg_read_d3_debug_data(&mld->fwrt); 1323 1378 1324 - if (iwl_mld_fw_needs_restart(mld, NULL)) 1325 - ret = -ENODEV; 1326 - else 1327 - ret = iwl_mld_wait_d3_notif(mld, &resume_data, false); 1379 + ret = iwl_mld_wait_d3_notif(mld, &resume_data, false); 1328 1380 1329 1381 if (!ret && (resume_data.d3_end_flags & IWL_D0I3_RESET_REQUIRE)) 1330 1382 return -ENODEV; ··· 1870 1928 1871 1929 iwl_fw_dbg_read_d3_debug_data(&mld->fwrt); 1872 1930 1873 - if (iwl_mld_fw_needs_restart(mld, bss_vif)) { 1874 - fw_err = true; 1875 - goto err; 1876 - } 1877 - 1878 1931 resume_data.wowlan_status = kzalloc(sizeof(*resume_data.wowlan_status), 1879 1932 GFP_KERNEL); 1880 1933 if (!resume_data.wowlan_status) 1881 - return -1; 1934 + return -ENOMEM; 1882 1935 1883 1936 if (mld->netdetect) 1884 1937 resume_data.notifs_expected |= IWL_D3_ND_MATCH_INFO;
+5
drivers/net/wireless/intel/iwlwifi/mld/debugfs.c
··· 546 546 #endif 547 547 MLD_DEBUGFS_ADD_FILE(inject_packet, debugfs_dir, 0200); 548 548 549 + #ifdef CONFIG_PM_SLEEP 550 + debugfs_create_u32("max_sleep", 0600, debugfs_dir, 551 + &mld->debug_max_sleep); 552 + #endif 553 + 549 554 debugfs_create_bool("rx_ts_ptp", 0600, debugfs_dir, 550 555 &mld->monitor.ptp_time); 551 556
+1 -1
drivers/net/wireless/intel/iwlwifi/mld/ftm-initiator.c
··· 94 94 IWL_ERR(mld, "Unsupported BW in FTM request (%d)\n", 95 95 peer->chandef.width); 96 96 return -EINVAL; 97 - } 97 + } 98 98 99 99 /* non EDCA based measurement must use HE preamble */ 100 100 if (peer->ftm.trigger_based || peer->ftm.non_trigger_based)
+15
drivers/net/wireless/intel/iwlwifi/mld/iface.c
··· 55 55 56 56 ieee80211_iter_keys(mld->hw, vif, iwl_mld_cleanup_keys_iter, NULL); 57 57 58 + wiphy_delayed_work_cancel(mld->wiphy, &mld_vif->mlo_scan_start_wk); 59 + 58 60 CLEANUP_STRUCT(mld_vif); 59 61 } 60 62 ··· 387 385 return iwl_mld_send_mac_cmd(mld, &cmd); 388 386 } 389 387 388 + static void iwl_mld_mlo_scan_start_wk(struct wiphy *wiphy, 389 + struct wiphy_work *wk) 390 + { 391 + struct iwl_mld_vif *mld_vif = container_of(wk, struct iwl_mld_vif, 392 + mlo_scan_start_wk.work); 393 + struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy); 394 + struct iwl_mld *mld = IWL_MAC80211_GET_MLD(hw); 395 + 396 + iwl_mld_int_mlo_scan(mld, iwl_mld_vif_to_mac80211(mld_vif)); 397 + } 398 + 390 399 IWL_MLD_ALLOC_FN(vif, vif) 391 400 392 401 /* Constructor function for struct iwl_mld_vif */ ··· 425 412 iwl_mld_emlsr_prevent_done_wk); 426 413 wiphy_delayed_work_init(&mld_vif->emlsr.tmp_non_bss_done_wk, 427 414 iwl_mld_emlsr_tmp_non_bss_done_wk); 415 + wiphy_delayed_work_init(&mld_vif->mlo_scan_start_wk, 416 + iwl_mld_mlo_scan_start_wk); 428 417 } 429 418 iwl_mld_init_internal_sta(&mld_vif->aux_sta); 430 419
+15
drivers/net/wireless/intel/iwlwifi/mld/iface.h
··· 87 87 * @last_exit_reason: Reason for the last EMLSR exit 88 88 * @last_exit_ts: Time of the last EMLSR exit (if @last_exit_reason is non-zero) 89 89 * @exit_repeat_count: Number of times EMLSR was exited for the same reason 90 + * @last_entry_ts: the time of the last EMLSR entry (if iwl_mld_emlsr_active() 91 + * is true) 90 92 * @unblock_tpt_wk: Unblock EMLSR because the throughput limit was reached 91 93 * @check_tpt_wk: a worker to check if IWL_MLD_EMLSR_BLOCKED_TPT should be 92 94 * added, for example if there is no longer enough traffic. ··· 107 105 enum iwl_mld_emlsr_exit last_exit_reason; 108 106 unsigned long last_exit_ts; 109 107 u8 exit_repeat_count; 108 + unsigned long last_entry_ts; 110 109 ); 111 110 112 111 struct wiphy_work unblock_tpt_wk; ··· 136 133 * @low_latency_causes: bit flags, indicating the causes for low-latency, 137 134 * see @iwl_mld_low_latency_cause. 138 135 * @ps_disabled: indicates that PS is disabled for this interface 136 + * @last_link_activation_time: last time a link was activated, for 137 + * deferring MLO scans (to make them more reliable) 139 138 * @mld: pointer to the mld structure. 140 139 * @deflink: default link data, for use in non-MLO, 141 140 * @link: reference to link data for each valid link, for use in MLO. ··· 149 144 * @roc_activity: the id of the roc_activity running. Relevant for STA and 150 145 * p2p device only. Set to %ROC_NUM_ACTIVITIES when not in use. 151 146 * @aux_sta: station used for remain on channel. Used in P2P device. 147 + * @mlo_scan_start_wk: worker to start a deferred MLO scan 152 148 */ 153 149 struct iwl_mld_vif { 154 150 /* Add here fields that need clean up on restart */ ··· 167 161 #endif 168 162 u8 low_latency_causes; 169 163 bool ps_disabled; 164 + time64_t last_link_activation_time; 170 165 ); 171 166 /* And here fields that survive a fw restart */ 172 167 struct iwl_mld *mld; ··· 186 179 #endif 187 180 enum iwl_roc_activity roc_activity; 188 181 struct iwl_mld_int_sta aux_sta; 182 + 183 + struct wiphy_delayed_work mlo_scan_start_wk; 189 184 }; 190 185 191 186 static inline struct iwl_mld_vif * 192 187 iwl_mld_vif_from_mac80211(struct ieee80211_vif *vif) 193 188 { 194 189 return (void *)vif->drv_priv; 190 + } 191 + 192 + static inline struct ieee80211_vif * 193 + iwl_mld_vif_to_mac80211(struct iwl_mld_vif *mld_vif) 194 + { 195 + return container_of((void *)mld_vif, struct ieee80211_vif, drv_priv); 195 196 } 196 197 197 198 #define iwl_mld_link_dereference_check(mld_vif, link_id) \
+4
drivers/net/wireless/intel/iwlwifi/mld/link.c
··· 404 404 struct ieee80211_bss_conf *link) 405 405 { 406 406 struct iwl_mld_link *mld_link = iwl_mld_link_from_mac80211(link); 407 + struct iwl_mld_vif *mld_vif = iwl_mld_vif_from_mac80211(mld_link->vif); 407 408 int ret; 408 409 409 410 lockdep_assert_wiphy(mld->wiphy); ··· 419 418 LINK_CONTEXT_MODIFY_ACTIVE); 420 419 if (ret) 421 420 mld_link->active = false; 421 + else 422 + mld_vif->last_link_activation_time = 423 + ktime_get_boottime_seconds(); 422 424 423 425 return ret; 424 426 }
+33 -30
drivers/net/wireless/intel/iwlwifi/mld/mac80211.c
··· 508 508 if (in_d3) { 509 509 /* mac80211 already cleaned up the state, no need for cleanup */ 510 510 ret = iwl_mld_no_wowlan_resume(mld); 511 - if (ret) 511 + if (ret) { 512 512 iwl_mld_stop_fw(mld); 513 + /* We're not really restarting in the sense of 514 + * in_hw_restart even if we got an error during 515 + * this. We'll just start again below and have 516 + * nothing to recover, mac80211 will do anyway. 517 + */ 518 + mld->fw_status.in_hw_restart = false; 519 + } 513 520 } 514 521 #endif /* CONFIG_PM_SLEEP */ 515 522 ··· 581 574 } 582 575 583 576 static 584 - int iwl_mld_mac80211_config(struct ieee80211_hw *hw, u32 changed) 577 + int iwl_mld_mac80211_config(struct ieee80211_hw *hw, int radio_idx, 578 + u32 changed) 585 579 { 586 580 return 0; 587 581 } ··· 1010 1002 1011 1003 /* Indicate to mac80211 that EML is enabled */ 1012 1004 vif->driver_flags |= IEEE80211_VIF_EML_ACTIVE; 1005 + mld_vif->emlsr.last_entry_ts = jiffies; 1013 1006 1014 1007 if (vif->active_links & BIT(mld_vif->emlsr.selected_links)) 1015 1008 mld_vif->emlsr.primary = mld_vif->emlsr.selected_primary; ··· 1111 1102 } 1112 1103 1113 1104 static 1114 - int iwl_mld_mac80211_set_rts_threshold(struct ieee80211_hw *hw, u32 value) 1105 + int iwl_mld_mac80211_set_rts_threshold(struct ieee80211_hw *hw, int radio_idx, 1106 + u32 value) 1115 1107 { 1116 1108 return 0; 1117 1109 } ··· 1478 1468 struct iwl_mld *mld = IWL_MAC80211_GET_MLD(hw); 1479 1469 u32 duration = IWL_MLD_SESSION_PROTECTION_ASSOC_TIME_MS; 1480 1470 1481 - /* After a successful association the connection is etalibeshed 1471 + /* After a successful association the connection is established 1482 1472 * and we can rely on the quota to send the disassociation frame. 1483 1473 */ 1484 1474 if (info->was_assoc) ··· 2583 2573 return mld->ibss_manager; 2584 2574 } 2585 2575 2586 - #define IWL_MLD_EMLSR_BLOCKED_TMP_NON_BSS_TIMEOUT (5 * HZ) 2587 - 2588 - static void iwl_mld_vif_iter_emlsr_block_tmp_non_bss(void *_data, u8 *mac, 2589 - struct ieee80211_vif *vif) 2590 - { 2591 - struct iwl_mld_vif *mld_vif = iwl_mld_vif_from_mac80211(vif); 2592 - int ret; 2593 - 2594 - if (!iwl_mld_vif_has_emlsr_cap(vif)) 2595 - return; 2596 - 2597 - ret = iwl_mld_block_emlsr_sync(mld_vif->mld, vif, 2598 - IWL_MLD_EMLSR_BLOCKED_TMP_NON_BSS, 2599 - iwl_mld_get_primary_link(vif)); 2600 - if (ret) 2601 - return; 2602 - 2603 - wiphy_delayed_work_queue(mld_vif->mld->wiphy, 2604 - &mld_vif->emlsr.tmp_non_bss_done_wk, 2605 - IWL_MLD_EMLSR_BLOCKED_TMP_NON_BSS_TIMEOUT); 2606 - } 2607 - 2608 2576 static void iwl_mld_prep_add_interface(struct ieee80211_hw *hw, 2609 2577 enum nl80211_iftype type) 2610 2578 { ··· 2595 2607 type == NL80211_IFTYPE_P2P_CLIENT)) 2596 2608 return; 2597 2609 2598 - ieee80211_iterate_active_interfaces_mtx(mld->hw, 2599 - IEEE80211_IFACE_ITER_NORMAL, 2600 - iwl_mld_vif_iter_emlsr_block_tmp_non_bss, 2601 - NULL); 2610 + iwl_mld_emlsr_block_tmp_non_bss(mld); 2602 2611 } 2603 2612 2604 2613 static int iwl_mld_set_hw_timestamp(struct ieee80211_hw *hw, ··· 2623 2638 struct iwl_mld *mld = IWL_MAC80211_GET_MLD(hw); 2624 2639 2625 2640 return iwl_mld_ftm_start(mld, vif, request); 2641 + } 2642 + 2643 + static enum ieee80211_neg_ttlm_res 2644 + iwl_mld_can_neg_ttlm(struct ieee80211_hw *hw, struct ieee80211_vif *vif, 2645 + struct ieee80211_neg_ttlm *neg_ttlm) 2646 + { 2647 + u16 map; 2648 + 2649 + /* Verify all TIDs are mapped to the same links set */ 2650 + map = neg_ttlm->downlink[0]; 2651 + for (int i = 0; i < IEEE80211_TTLM_NUM_TIDS; i++) { 2652 + if (neg_ttlm->downlink[i] != neg_ttlm->uplink[i] || 2653 + neg_ttlm->uplink[i] != map) 2654 + return NEG_TTLM_RES_REJECT; 2655 + } 2656 + 2657 + return NEG_TTLM_RES_ACCEPT; 2626 2658 } 2627 2659 2628 2660 const struct ieee80211_ops iwl_mld_hw_ops = { ··· 2711 2709 .prep_add_interface = iwl_mld_prep_add_interface, 2712 2710 .set_hw_timestamp = iwl_mld_set_hw_timestamp, 2713 2711 .start_pmsr = iwl_mld_start_pmsr, 2712 + .can_neg_ttlm = iwl_mld_can_neg_ttlm, 2714 2713 };
+13 -1
drivers/net/wireless/intel/iwlwifi/mld/mld.c
··· 357 357 trans->conf.n_no_reclaim_cmds = ARRAY_SIZE(no_reclaim_cmds); 358 358 359 359 trans->conf.rx_mpdu_cmd = REPLY_RX_MPDU_CMD; 360 - trans->conf.rx_mpdu_cmd_hdr_size = sizeof(struct iwl_rx_mpdu_res_start); 360 + trans->conf.rx_mpdu_cmd_hdr_size = sizeof(struct iwl_rx_mpdu_desc); 361 361 trans->conf.wide_cmd_header = true; 362 362 363 363 iwl_trans_op_mode_enter(trans, op_mode); ··· 725 725 {} 726 726 #endif 727 727 728 + static void iwl_mld_dump(struct iwl_op_mode *op_mode) 729 + { 730 + struct iwl_mld *mld = IWL_OP_MODE_GET_MLD(op_mode); 731 + struct iwl_fw_runtime *fwrt = &mld->fwrt; 732 + 733 + if (!iwl_trans_fw_running(fwrt->trans)) 734 + return; 735 + 736 + iwl_dbg_tlv_time_point(fwrt, IWL_FW_INI_TIME_POINT_USER_TRIGGER, NULL); 737 + } 738 + 728 739 static const struct iwl_op_mode_ops iwl_mld_ops = { 729 740 .start = iwl_op_mode_mld_start, 730 741 .stop = iwl_op_mode_mld_stop, ··· 750 739 .sw_reset = iwl_mld_sw_reset, 751 740 .time_point = iwl_mld_time_point, 752 741 .device_powered_off = pm_sleep_ptr(iwl_mld_device_powered_off), 742 + .dump = iwl_mld_dump, 753 743 }; 754 744 755 745 struct iwl_mld_mod_params iwlmld_mod_params = {
+2
drivers/net/wireless/intel/iwlwifi/mld/mld.h
··· 159 159 * @addresses: device MAC addresses. 160 160 * @scan: instance of the scan object 161 161 * @wowlan: WoWLAN support data. 162 + * @debug_max_sleep: maximum sleep time in D3 (for debug purposes) 162 163 * @led: the led device 163 164 * @mcc_src: the source id of the MCC, comes from the firmware 164 165 * @bios_enable_puncturing: is puncturing enabled by bios ··· 253 252 struct iwl_mld_scan scan; 254 253 #ifdef CONFIG_PM_SLEEP 255 254 struct wiphy_wowlan_support wowlan; 255 + u32 debug_max_sleep; 256 256 #endif /* CONFIG_PM_SLEEP */ 257 257 #ifdef CONFIG_IWLWIFI_LEDS 258 258 struct led_classdev led;
+37 -5
drivers/net/wireless/intel/iwlwifi/mld/mlo.c
··· 287 287 return _iwl_mld_emlsr_block(mld, vif, reason, link_to_keep, true); 288 288 } 289 289 290 + #define IWL_MLD_EMLSR_BLOCKED_TMP_NON_BSS_TIMEOUT (10 * HZ) 291 + 292 + static void iwl_mld_vif_iter_emlsr_block_tmp_non_bss(void *_data, u8 *mac, 293 + struct ieee80211_vif *vif) 294 + { 295 + struct iwl_mld_vif *mld_vif = iwl_mld_vif_from_mac80211(vif); 296 + int ret; 297 + 298 + if (!iwl_mld_vif_has_emlsr_cap(vif)) 299 + return; 300 + 301 + ret = iwl_mld_block_emlsr_sync(mld_vif->mld, vif, 302 + IWL_MLD_EMLSR_BLOCKED_TMP_NON_BSS, 303 + iwl_mld_get_primary_link(vif)); 304 + if (ret) 305 + return; 306 + 307 + wiphy_delayed_work_queue(mld_vif->mld->wiphy, 308 + &mld_vif->emlsr.tmp_non_bss_done_wk, 309 + IWL_MLD_EMLSR_BLOCKED_TMP_NON_BSS_TIMEOUT); 310 + } 311 + 312 + void iwl_mld_emlsr_block_tmp_non_bss(struct iwl_mld *mld) 313 + { 314 + ieee80211_iterate_active_interfaces_mtx(mld->hw, 315 + IEEE80211_IFACE_ITER_NORMAL, 316 + iwl_mld_vif_iter_emlsr_block_tmp_non_bss, 317 + NULL); 318 + } 319 + 290 320 static void _iwl_mld_select_links(struct iwl_mld *mld, 291 321 struct ieee80211_vif *vif); 292 322 ··· 560 530 /* 561 531 * TPT is unblocked, need to check if the TPT criteria is still met. 562 532 * 563 - * If EMLSR is active, then we also need to check the secondar link 564 - * requirements. 533 + * If EMLSR is active for at least 5 seconds, then we also 534 + * need to check the secondary link requirements. 565 535 */ 566 - if (iwl_mld_emlsr_active(vif)) { 536 + if (iwl_mld_emlsr_active(vif) && 537 + time_is_before_jiffies(mld_vif->emlsr.last_entry_ts + 538 + IWL_MLD_TPT_COUNT_WINDOW)) { 567 539 sec_link_id = iwl_mld_get_other_link(vif, iwl_mld_get_primary_link(vif)); 568 540 sec_link = iwl_mld_link_dereference_check(mld_vif, sec_link_id); 569 541 if (WARN_ON_ONCE(!sec_link)) ··· 1199 1167 { 1200 1168 struct iwl_mld_vif *mld_vif = iwl_mld_vif_from_mac80211(vif); 1201 1169 1202 - if (!iwl_mld_vif_has_emlsr_cap(vif) || iwl_mld_emlsr_active(vif) || 1203 - mld_vif->emlsr.blocked_reasons) 1170 + if (!IWL_MLD_AUTO_EML_ENABLE || !iwl_mld_vif_has_emlsr_cap(vif) || 1171 + iwl_mld_emlsr_active(vif) || mld_vif->emlsr.blocked_reasons) 1204 1172 return; 1205 1173 1206 1174 iwl_mld_int_mlo_scan(mld, vif);
+2
drivers/net/wireless/intel/iwlwifi/mld/mlo.h
··· 157 157 u16 grade; 158 158 }; 159 159 160 + void iwl_mld_emlsr_block_tmp_non_bss(struct iwl_mld *mld); 161 + 160 162 #if IS_ENABLED(CONFIG_IWLWIFI_KUNIT_TESTS) 161 163 u32 iwl_mld_emlsr_pair_state(struct ieee80211_vif *vif, 162 164 struct iwl_mld_link_sel_data *a,
+1 -1
drivers/net/wireless/intel/iwlwifi/mld/phy.c
··· 181 181 .phy_specific_cfg = mld->fwrt.phy_filters, 182 182 }; 183 183 184 - IWL_INFO(mld, "Sending Phy CFG command: 0x%x\n", cmd.phy_cfg); 184 + IWL_DEBUG_INFO(mld, "Sending Phy CFG command: 0x%x\n", cmd.phy_cfg); 185 185 186 186 return iwl_mld_send_cmd_pdu(mld, PHY_CONFIGURATION_CMD, &cmd); 187 187 }
+18 -2
drivers/net/wireless/intel/iwlwifi/mld/scan.c
··· 1752 1752 struct cfg80211_scan_request *req, 1753 1753 struct ieee80211_scan_ies *ies) 1754 1754 { 1755 + 1756 + if (vif->type == NL80211_IFTYPE_P2P_DEVICE) 1757 + iwl_mld_emlsr_block_tmp_non_bss(mld); 1758 + 1755 1759 return _iwl_mld_single_scan_start(mld, vif, req, ies, 1756 1760 IWL_MLD_SCAN_REGULAR); 1757 1761 } ··· 1804 1800 IWL_DEBUG_SCAN(mld, "Internal MLO scan: ret=%d\n", ret); 1805 1801 } 1806 1802 1803 + #define IWL_MLD_MLO_SCAN_BLOCKOUT_TIME 5 /* seconds */ 1804 + 1807 1805 void iwl_mld_int_mlo_scan(struct iwl_mld *mld, struct ieee80211_vif *vif) 1808 1806 { 1809 1807 struct ieee80211_channel *channels[IEEE80211_MLD_MAX_NUM_LINKS]; 1808 + struct iwl_mld_vif *mld_vif = iwl_mld_vif_from_mac80211(vif); 1810 1809 unsigned long usable_links = ieee80211_vif_usable_links(vif); 1811 1810 size_t n_channels = 0; 1812 1811 u8 link_id; 1813 1812 1814 1813 lockdep_assert_wiphy(mld->wiphy); 1815 1814 1816 - if (!vif->cfg.assoc || !ieee80211_vif_is_mld(vif) || 1817 - hweight16(vif->valid_links) == 1) 1815 + if (!IWL_MLD_AUTO_EML_ENABLE || !vif->cfg.assoc || 1816 + !ieee80211_vif_is_mld(vif) || hweight16(vif->valid_links) == 1) 1818 1817 return; 1819 1818 1820 1819 if (mld->scan.status & IWL_MLD_SCAN_INT_MLO) { 1821 1820 IWL_DEBUG_SCAN(mld, "Internal MLO scan is already running\n"); 1821 + return; 1822 + } 1823 + 1824 + if (mld_vif->last_link_activation_time > ktime_get_boottime_seconds() - 1825 + IWL_MLD_MLO_SCAN_BLOCKOUT_TIME) { 1826 + /* timing doesn't matter much, so use the blockout time */ 1827 + wiphy_delayed_work_queue(mld->wiphy, 1828 + &mld_vif->mlo_scan_start_wk, 1829 + IWL_MLD_MLO_SCAN_BLOCKOUT_TIME); 1822 1830 return; 1823 1831 } 1824 1832
+1 -1
drivers/net/wireless/intel/iwlwifi/mld/scan.h
··· 130 130 void *cmd; 131 131 unsigned long last_6ghz_passive_jiffies; 132 132 unsigned long last_start_time_jiffies; 133 - unsigned long last_mlo_scan_time; 133 + u64 last_mlo_scan_time; 134 134 }; 135 135 136 136 #endif /* __iwl_mld_scan_h__ */
+61 -68
drivers/net/wireless/intel/iwlwifi/mvm/d3.c
··· 120 120 switch (key->cipher) { 121 121 case WLAN_CIPHER_SUITE_WEP40: 122 122 case WLAN_CIPHER_SUITE_WEP104: { /* hack it for now */ 123 - struct { 124 - struct iwl_mvm_wep_key_cmd wep_key_cmd; 125 - struct iwl_mvm_wep_key wep_key; 126 - } __packed wkc = { 127 - .wep_key_cmd.mac_id_n_color = 128 - cpu_to_le32(FW_CMD_ID_AND_COLOR(mvmvif->id, 129 - mvmvif->color)), 130 - .wep_key_cmd.num_keys = 1, 131 - /* firmware sets STA_KEY_FLG_WEP_13BYTES */ 132 - .wep_key_cmd.decryption_type = STA_KEY_FLG_WEP, 133 - .wep_key.key_index = key->keyidx, 134 - .wep_key.key_size = key->keylen, 135 - }; 123 + DEFINE_RAW_FLEX(struct iwl_mvm_wep_key_cmd, wkc, wep_key, 1); 124 + struct iwl_mvm_wep_key *wep_key = wkc->wep_key; 125 + 126 + wkc->mac_id_n_color = 127 + cpu_to_le32(FW_CMD_ID_AND_COLOR(mvmvif->id, 128 + mvmvif->color)); 129 + wkc->num_keys = 1; 130 + /* firmware sets STA_KEY_FLG_WEP_13BYTES */ 131 + wkc->decryption_type = STA_KEY_FLG_WEP; 132 + wep_key->key_index = key->keyidx; 133 + wep_key->key_size = key->keylen; 136 134 137 135 /* 138 136 * This will fail -- the key functions don't set support ··· 140 142 if (key->flags & IEEE80211_KEY_FLAG_PAIRWISE) 141 143 break; 142 144 143 - memcpy(&wkc.wep_key.key[3], key->key, key->keylen); 145 + memcpy(&wep_key->key[3], key->key, key->keylen); 144 146 if (key->keyidx == mvmvif->tx_key_idx) { 145 147 /* TX key must be at offset 0 */ 146 - wkc.wep_key.key_offset = 0; 148 + wep_key->key_offset = 0; 147 149 } else { 148 150 /* others start at 1 */ 149 151 data->wep_key_idx++; 150 - wkc.wep_key.key_offset = data->wep_key_idx; 152 + wep_key->key_offset = data->wep_key_idx; 151 153 } 152 154 153 155 mutex_lock(&mvm->mutex); 154 - ret = iwl_mvm_send_cmd_pdu(mvm, WEP_KEY, 0, sizeof(wkc), &wkc); 156 + ret = iwl_mvm_send_cmd_pdu(mvm, WEP_KEY, 0, 157 + __struct_size(wkc), wkc); 155 158 data->error = ret != 0; 156 159 157 160 mvm->ptk_ivlen = key->iv_len; ··· 2060 2061 struct iwl_wowlan_mlo_gtk *mlo_key = &status->mlo_keys[i]; 2061 2062 struct ieee80211_key_conf *key, *old_key; 2062 2063 struct ieee80211_key_seq seq; 2063 - struct { 2064 - struct ieee80211_key_conf conf; 2065 - u8 key[32]; 2066 - } conf = {}; 2064 + DEFINE_RAW_FLEX(struct ieee80211_key_conf, conf, key, 2065 + WOWLAN_KEY_MAX_SIZE); 2067 2066 u16 flags = le16_to_cpu(mlo_key->flags); 2068 2067 int j, link_id, key_id, key_type; 2069 2068 ··· 2078 2081 key_type >= WOWLAN_MLO_GTK_KEY_NUM_TYPES)) 2079 2082 continue; 2080 2083 2081 - conf.conf.cipher = old_keys->cipher[link_id][key_type]; 2084 + conf->cipher = old_keys->cipher[link_id][key_type]; 2082 2085 /* WARN_ON? */ 2083 - if (!conf.conf.cipher) 2086 + if (!conf->cipher) 2084 2087 continue; 2085 2088 2086 - conf.conf.keylen = 0; 2087 - switch (conf.conf.cipher) { 2089 + conf->keylen = 0; 2090 + switch (conf->cipher) { 2088 2091 case WLAN_CIPHER_SUITE_CCMP: 2089 2092 case WLAN_CIPHER_SUITE_GCMP: 2090 - conf.conf.keylen = WLAN_KEY_LEN_CCMP; 2093 + conf->keylen = WLAN_KEY_LEN_CCMP; 2091 2094 break; 2092 2095 case WLAN_CIPHER_SUITE_GCMP_256: 2093 - conf.conf.keylen = WLAN_KEY_LEN_GCMP_256; 2096 + conf->keylen = WLAN_KEY_LEN_GCMP_256; 2094 2097 break; 2095 2098 case WLAN_CIPHER_SUITE_BIP_GMAC_128: 2096 - conf.conf.keylen = WLAN_KEY_LEN_BIP_GMAC_128; 2099 + conf->keylen = WLAN_KEY_LEN_BIP_GMAC_128; 2097 2100 break; 2098 2101 case WLAN_CIPHER_SUITE_BIP_GMAC_256: 2099 - conf.conf.keylen = WLAN_KEY_LEN_BIP_GMAC_256; 2102 + conf->keylen = WLAN_KEY_LEN_BIP_GMAC_256; 2100 2103 break; 2101 2104 case WLAN_CIPHER_SUITE_AES_CMAC: 2102 - conf.conf.keylen = WLAN_KEY_LEN_AES_CMAC; 2105 + conf->keylen = WLAN_KEY_LEN_AES_CMAC; 2103 2106 break; 2104 2107 case WLAN_CIPHER_SUITE_BIP_CMAC_256: 2105 - conf.conf.keylen = WLAN_KEY_LEN_BIP_CMAC_256; 2108 + conf->keylen = WLAN_KEY_LEN_BIP_CMAC_256; 2106 2109 break; 2107 2110 } 2108 2111 2109 - if (WARN_ON(!conf.conf.keylen || 2110 - conf.conf.keylen > sizeof(conf.key))) 2112 + if (WARN_ON(!conf->keylen || 2113 + conf->keylen > WOWLAN_KEY_MAX_SIZE)) 2111 2114 continue; 2112 2115 2113 - memcpy(conf.conf.key, mlo_key->key, conf.conf.keylen); 2114 - conf.conf.keyidx = key_id; 2116 + memcpy(conf->key, mlo_key->key, conf->keylen); 2117 + conf->keyidx = key_id; 2115 2118 2116 2119 old_key = old_keys->key[link_id][key_id]; 2117 2120 if (old_key) { ··· 2123 2126 2124 2127 IWL_DEBUG_WOWLAN(mvm, "Add MLO key id %d, link id %d\n", 2125 2128 key_id, link_id); 2126 - key = ieee80211_gtk_rekey_add(vif, &conf.conf, link_id); 2129 + key = ieee80211_gtk_rekey_add(vif, conf, link_id); 2127 2130 if (WARN_ON(IS_ERR(key))) { 2128 2131 ret = false; 2129 2132 goto out; ··· 2153 2156 { 2154 2157 int i, j; 2155 2158 struct ieee80211_key_conf *key; 2156 - struct { 2157 - struct ieee80211_key_conf conf; 2158 - u8 key[32]; 2159 - } conf = { 2160 - .conf.cipher = gtk_cipher, 2161 - }; 2159 + DEFINE_RAW_FLEX(struct ieee80211_key_conf, conf, key, 2160 + WOWLAN_KEY_MAX_SIZE); 2162 2161 int link_id = vif->active_links ? __ffs(vif->active_links) : -1; 2163 2162 2163 + conf->cipher = gtk_cipher; 2164 + 2164 2165 BUILD_BUG_ON(WLAN_KEY_LEN_CCMP != WLAN_KEY_LEN_GCMP); 2165 - BUILD_BUG_ON(sizeof(conf.key) < WLAN_KEY_LEN_CCMP); 2166 - BUILD_BUG_ON(sizeof(conf.key) < WLAN_KEY_LEN_GCMP_256); 2167 - BUILD_BUG_ON(sizeof(conf.key) < WLAN_KEY_LEN_TKIP); 2168 - BUILD_BUG_ON(sizeof(conf.key) < sizeof(status->gtk[0].key)); 2166 + BUILD_BUG_ON(WOWLAN_KEY_MAX_SIZE < WLAN_KEY_LEN_CCMP); 2167 + BUILD_BUG_ON(WOWLAN_KEY_MAX_SIZE < WLAN_KEY_LEN_GCMP_256); 2168 + BUILD_BUG_ON(WOWLAN_KEY_MAX_SIZE < WLAN_KEY_LEN_TKIP); 2169 + BUILD_BUG_ON(WOWLAN_KEY_MAX_SIZE < sizeof(status->gtk[0].key)); 2169 2170 2170 2171 switch (gtk_cipher) { 2171 2172 case WLAN_CIPHER_SUITE_CCMP: 2172 2173 case WLAN_CIPHER_SUITE_GCMP: 2173 - conf.conf.keylen = WLAN_KEY_LEN_CCMP; 2174 + conf->keylen = WLAN_KEY_LEN_CCMP; 2174 2175 break; 2175 2176 case WLAN_CIPHER_SUITE_GCMP_256: 2176 - conf.conf.keylen = WLAN_KEY_LEN_GCMP_256; 2177 + conf->keylen = WLAN_KEY_LEN_GCMP_256; 2177 2178 break; 2178 2179 case WLAN_CIPHER_SUITE_TKIP: 2179 - conf.conf.keylen = WLAN_KEY_LEN_TKIP; 2180 + conf->keylen = WLAN_KEY_LEN_TKIP; 2180 2181 break; 2181 2182 default: 2182 2183 WARN_ON(1); ··· 2184 2189 if (!status->gtk[i].len) 2185 2190 continue; 2186 2191 2187 - conf.conf.keyidx = status->gtk[i].id; 2192 + conf->keyidx = status->gtk[i].id; 2188 2193 IWL_DEBUG_WOWLAN(mvm, 2189 2194 "Received from FW GTK cipher %d, key index %d\n", 2190 - conf.conf.cipher, conf.conf.keyidx); 2191 - memcpy(conf.conf.key, status->gtk[i].key, 2195 + conf->cipher, conf->keyidx); 2196 + memcpy(conf->key, status->gtk[i].key, 2192 2197 sizeof(status->gtk[i].key)); 2193 2198 2194 - key = ieee80211_gtk_rekey_add(vif, &conf.conf, link_id); 2199 + key = ieee80211_gtk_rekey_add(vif, conf, link_id); 2195 2200 if (IS_ERR(key)) 2196 2201 return false; 2197 2202 ··· 2213 2218 struct ieee80211_vif *vif, u32 cipher, 2214 2219 struct iwl_multicast_key_data *key_data) 2215 2220 { 2221 + DEFINE_RAW_FLEX(struct ieee80211_key_conf, conf, key, 2222 + WOWLAN_KEY_MAX_SIZE); 2216 2223 struct ieee80211_key_conf *key_config; 2217 - struct { 2218 - struct ieee80211_key_conf conf; 2219 - u8 key[WOWLAN_KEY_MAX_SIZE]; 2220 - } conf = { 2221 - .conf.cipher = cipher, 2222 - .conf.keyidx = key_data->id, 2223 - }; 2224 2224 struct ieee80211_key_seq seq; 2225 2225 int link_id = vif->active_links ? __ffs(vif->active_links) : -1; 2226 + 2227 + conf->cipher = cipher; 2228 + conf->keyidx = key_data->id; 2226 2229 2227 2230 if (!key_data->len) 2228 2231 return true; 2229 2232 2230 - iwl_mvm_d3_set_igtk_bigtk_ipn(key_data, &seq, conf.conf.cipher); 2233 + iwl_mvm_d3_set_igtk_bigtk_ipn(key_data, &seq, conf->cipher); 2231 2234 2232 2235 switch (cipher) { 2233 2236 case WLAN_CIPHER_SUITE_BIP_GMAC_128: 2234 - conf.conf.keylen = WLAN_KEY_LEN_BIP_GMAC_128; 2237 + conf->keylen = WLAN_KEY_LEN_BIP_GMAC_128; 2235 2238 break; 2236 2239 case WLAN_CIPHER_SUITE_BIP_GMAC_256: 2237 - conf.conf.keylen = WLAN_KEY_LEN_BIP_GMAC_256; 2240 + conf->keylen = WLAN_KEY_LEN_BIP_GMAC_256; 2238 2241 break; 2239 2242 case WLAN_CIPHER_SUITE_AES_CMAC: 2240 - conf.conf.keylen = WLAN_KEY_LEN_AES_CMAC; 2243 + conf->keylen = WLAN_KEY_LEN_AES_CMAC; 2241 2244 break; 2242 2245 case WLAN_CIPHER_SUITE_BIP_CMAC_256: 2243 - conf.conf.keylen = WLAN_KEY_LEN_BIP_CMAC_256; 2246 + conf->keylen = WLAN_KEY_LEN_BIP_CMAC_256; 2244 2247 break; 2245 2248 default: 2246 2249 WARN_ON(1); 2247 2250 } 2248 - BUILD_BUG_ON(sizeof(conf.key) < sizeof(key_data->key)); 2249 - memcpy(conf.conf.key, key_data->key, conf.conf.keylen); 2251 + BUILD_BUG_ON(WOWLAN_KEY_MAX_SIZE < sizeof(key_data->key)); 2252 + memcpy(conf->key, key_data->key, conf->keylen); 2250 2253 2251 - key_config = ieee80211_gtk_rekey_add(vif, &conf.conf, link_id); 2254 + key_config = ieee80211_gtk_rekey_add(vif, conf, link_id); 2252 2255 if (IS_ERR(key_config)) 2253 2256 return false; 2254 2257 ieee80211_set_key_rx_seq(key_config, 0, &seq);
+8 -4
drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c
··· 298 298 }, 299 299 }; 300 300 301 - int iwl_mvm_op_get_antenna(struct ieee80211_hw *hw, u32 *tx_ant, u32 *rx_ant) 301 + int iwl_mvm_op_get_antenna(struct ieee80211_hw *hw, int radio_idx, 302 + u32 *tx_ant, u32 *rx_ant) 302 303 { 303 304 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw); 304 305 *tx_ant = iwl_mvm_get_valid_tx_ant(mvm); ··· 307 306 return 0; 308 307 } 309 308 310 - int iwl_mvm_op_set_antenna(struct ieee80211_hw *hw, u32 tx_ant, u32 rx_ant) 309 + int iwl_mvm_op_set_antenna(struct ieee80211_hw *hw, int radio_idx, u32 tx_ant, 310 + u32 rx_ant) 311 311 { 312 312 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw); 313 313 314 314 /* This has been tested on those devices only */ 315 315 if (mvm->trans->mac_cfg->device_family != IWL_DEVICE_FAMILY_9000 && 316 - mvm->trans->mac_cfg->device_family != IWL_DEVICE_FAMILY_22000) 316 + mvm->trans->mac_cfg->device_family != IWL_DEVICE_FAMILY_22000 && 317 + mvm->trans->mac_cfg->device_family != IWL_DEVICE_FAMILY_AX210) 317 318 return -EOPNOTSUPP; 318 319 319 320 if (!mvm->nvm_data) ··· 4252 4249 return ret; 4253 4250 } 4254 4251 4255 - int iwl_mvm_mac_set_rts_threshold(struct ieee80211_hw *hw, u32 value) 4252 + int iwl_mvm_mac_set_rts_threshold(struct ieee80211_hw *hw, int radio_idx, 4253 + u32 value) 4256 4254 { 4257 4255 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw); 4258 4256
+8 -5
drivers/net/wireless/intel/iwlwifi/mvm/mvm.h
··· 2133 2133 2134 2134 s8 iwl_mvm_average_dbm_values(const struct iwl_umac_scan_channel_survey_notif *notif); 2135 2135 2136 - 2137 2136 extern const struct iwl_hcmd_arr iwl_mvm_groups[]; 2138 2137 extern const unsigned int iwl_mvm_groups_size; 2139 2138 #endif ··· 2865 2866 int iwl_mvm_mac_ampdu_action(struct ieee80211_hw *hw, 2866 2867 struct ieee80211_vif *vif, 2867 2868 struct ieee80211_ampdu_params *params); 2868 - int iwl_mvm_op_get_antenna(struct ieee80211_hw *hw, u32 *tx_ant, u32 *rx_ant); 2869 - int iwl_mvm_op_set_antenna(struct ieee80211_hw *hw, u32 tx_ant, u32 rx_ant); 2869 + int iwl_mvm_op_get_antenna(struct ieee80211_hw *hw, int radio_idx, u32 *tx_ant, 2870 + u32 *rx_ant); 2871 + int iwl_mvm_op_set_antenna(struct ieee80211_hw *hw, int radio_idx, u32 tx_ant, 2872 + u32 rx_ant); 2870 2873 int iwl_mvm_mac_start(struct ieee80211_hw *hw); 2871 2874 void iwl_mvm_mac_reconfig_complete(struct ieee80211_hw *hw, 2872 2875 enum ieee80211_reconfig_type reconfig_type); 2873 2876 void iwl_mvm_mac_stop(struct ieee80211_hw *hw, bool suspend); 2874 - static inline int iwl_mvm_mac_config(struct ieee80211_hw *hw, u32 changed) 2877 + static inline int iwl_mvm_mac_config(struct ieee80211_hw *hw, int radio_idx, 2878 + u32 changed) 2875 2879 { 2876 2880 return 0; 2877 2881 } ··· 2907 2905 int num_frames, 2908 2906 enum ieee80211_frame_release_type reason, 2909 2907 bool more_data); 2910 - int iwl_mvm_mac_set_rts_threshold(struct ieee80211_hw *hw, u32 value); 2908 + int iwl_mvm_mac_set_rts_threshold(struct ieee80211_hw *hw, int radio_idx, 2909 + u32 value); 2911 2910 void iwl_mvm_sta_rc_update(struct ieee80211_hw *hw, struct ieee80211_vif *vif, 2912 2911 struct ieee80211_link_sta *link_sta, u32 changed); 2913 2912 void iwl_mvm_mac_mgd_prepare_tx(struct ieee80211_hw *hw,
+3 -1
drivers/net/wireless/intel/iwlwifi/mvm/ops.c
··· 61 61 } 62 62 63 63 ret = iwl_opmode_register("iwlmvm", &iwl_mvm_ops); 64 - if (ret) 64 + if (ret) { 65 65 pr_err("Unable to register MVM op_mode: %d\n", ret); 66 + iwl_mvm_rate_control_unregister(); 67 + } 66 68 67 69 return ret; 68 70 }
+1
drivers/net/wireless/intel/iwlwifi/mvm/rs.h
··· 411 411 * with the mac80211 subsystem. This should be performed prior to calling 412 412 * ieee80211_register_hw 413 413 * 414 + * Return: negative error code, or 0 on success 414 415 */ 415 416 int iwl_mvm_rate_control_register(void); 416 417
+4 -113
drivers/net/wireless/intel/iwlwifi/mvm/scan.c
··· 1 1 // SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause 2 2 /* 3 - * Copyright (C) 2012-2014, 2018-2024 Intel Corporation 3 + * Copyright (C) 2012-2014, 2018-2025 Intel Corporation 4 4 * Copyright (C) 2013-2015 Intel Mobile Communications GmbH 5 5 * Copyright (C) 2016-2017 Intel Deutschland GmbH 6 6 */ ··· 11 11 #include "mvm.h" 12 12 #include "fw/api/scan.h" 13 13 #include "iwl-io.h" 14 + #include "iwl-utils.h" 14 15 15 16 #define IWL_DENSE_EBS_SCAN_RATIO 5 16 17 #define IWL_SPARSE_EBS_SCAN_RATIO 1 ··· 3686 3685 return -EINVAL; 3687 3686 } 3688 3687 3689 - static u32 iwl_mvm_div_by_db(u32 value, u8 db) 3690 - { 3691 - /* 3692 - * 2^32 * 10**(i / 10) for i = [1, 10], skipping 0 and simply stopping 3693 - * at 10 dB and looping instead of using a much larger table. 3694 - * 3695 - * Using 64 bit math is overkill, but means the helper does not require 3696 - * a limit on the input range. 3697 - */ 3698 - static const u32 db_to_val[] = { 3699 - 0xcb59185e, 0xa1866ba8, 0x804dce7a, 0x65ea59fe, 0x50f44d89, 3700 - 0x404de61f, 0x331426af, 0x2892c18b, 0x203a7e5b, 0x1999999a, 3701 - }; 3702 - 3703 - while (value && db > 0) { 3704 - u8 change = min_t(u8, db, ARRAY_SIZE(db_to_val)); 3705 - 3706 - value = (((u64)value) * db_to_val[change - 1]) >> 32; 3707 - 3708 - db -= change; 3709 - } 3710 - 3711 - return value; 3712 - } 3713 - 3714 - VISIBLE_IF_IWLWIFI_KUNIT s8 3715 - iwl_mvm_average_dbm_values(const struct iwl_umac_scan_channel_survey_notif *notif) 3716 - { 3717 - s8 average_magnitude; 3718 - u32 average_factor; 3719 - s8 sum_magnitude = -128; 3720 - u32 sum_factor = 0; 3721 - int i, count = 0; 3722 - 3723 - /* 3724 - * To properly average the decibel values (signal values given in dBm) 3725 - * we need to do the math in linear space. Doing a linear average of 3726 - * dB (dBm) values is a bit annoying though due to the large range of 3727 - * at least -10 to -110 dBm that will not fit into a 32 bit integer. 3728 - * 3729 - * A 64 bit integer should be sufficient, but then we still have the 3730 - * problem that there are no directly usable utility functions 3731 - * available. 3732 - * 3733 - * So, lets not deal with that and instead do much of the calculation 3734 - * with a 16.16 fixed point integer along with a base in dBm. 16.16 bit 3735 - * gives us plenty of head-room for adding up a few values and even 3736 - * doing some math on it. And the tail should be accurate enough too 3737 - * (1/2^16 is somewhere around -48 dB, so effectively zero). 3738 - * 3739 - * i.e. the real value of sum is: 3740 - * sum = sum_factor / 2^16 * 10^(sum_magnitude / 10) mW 3741 - * 3742 - * However, that does mean we need to be able to bring two values to 3743 - * a common base, so we need a helper for that. 3744 - * 3745 - * Note that this function takes an input with unsigned negative dBm 3746 - * values but returns a signed dBm (i.e. a negative value). 3747 - */ 3748 - 3749 - for (i = 0; i < ARRAY_SIZE(notif->noise); i++) { 3750 - s8 val_magnitude; 3751 - u32 val_factor; 3752 - 3753 - if (notif->noise[i] == 0xff) 3754 - continue; 3755 - 3756 - val_factor = 0x10000; 3757 - val_magnitude = -notif->noise[i]; 3758 - 3759 - if (val_magnitude <= sum_magnitude) { 3760 - u8 div_db = sum_magnitude - val_magnitude; 3761 - 3762 - val_factor = iwl_mvm_div_by_db(val_factor, div_db); 3763 - val_magnitude = sum_magnitude; 3764 - } else { 3765 - u8 div_db = val_magnitude - sum_magnitude; 3766 - 3767 - sum_factor = iwl_mvm_div_by_db(sum_factor, div_db); 3768 - sum_magnitude = val_magnitude; 3769 - } 3770 - 3771 - sum_factor += val_factor; 3772 - count++; 3773 - } 3774 - 3775 - /* No valid noise measurement, return a very high noise level */ 3776 - if (count == 0) 3777 - return 0; 3778 - 3779 - average_magnitude = sum_magnitude; 3780 - average_factor = sum_factor / count; 3781 - 3782 - /* 3783 - * average_factor will be a number smaller than 1.0 (0x10000) at this 3784 - * point. What we need to do now is to adjust average_magnitude so that 3785 - * average_factor is between -0.5 dB and 0.5 dB. 3786 - * 3787 - * Just do -1 dB steps and find the point where 3788 - * -0.5 dB * -i dB = 0x10000 * 10^(-0.5/10) / i dB 3789 - * = div_by_db(0xe429, i) 3790 - * is smaller than average_factor. 3791 - */ 3792 - for (i = 0; average_factor < iwl_mvm_div_by_db(0xe429, i); i++) { 3793 - /* nothing */ 3794 - } 3795 - 3796 - return average_magnitude - i; 3797 - } 3798 - EXPORT_SYMBOL_IF_IWLWIFI_KUNIT(iwl_mvm_average_dbm_values); 3799 - 3800 3688 void iwl_mvm_rx_channel_survey_notif(struct iwl_mvm *mvm, 3801 3689 struct iwl_rx_cmd_buffer *rxb) 3802 3690 { ··· 3743 3853 info->time_busy = le32_to_cpu(notif->busy_time); 3744 3854 info->time_rx = le32_to_cpu(notif->rx_time); 3745 3855 info->time_tx = le32_to_cpu(notif->tx_time); 3746 - info->noise = iwl_mvm_average_dbm_values(notif); 3856 + info->noise = 3857 + iwl_average_neg_dbm(notif->noise, ARRAY_SIZE(notif->noise)); 3747 3858 }
+2 -1
drivers/net/wireless/intel/iwlwifi/mvm/sta.h
··· 214 214 */ 215 215 216 216 /** 217 - * enum iwl_mvm_agg_state 217 + * enum iwl_mvm_agg_state - aggregation session state 218 218 * 219 219 * The state machine of the BA agreement establishment / tear down. 220 220 * These states relate to a specific RA / TID. ··· 483 483 * about. Otherwise (if this is a new STA), this should be false. 484 484 * @flags: if update==true, this marks what is being changed via ORs of values 485 485 * from enum iwl_sta_modify_flag. Otherwise, this is ignored. 486 + * Return: negative error code or 0 on success 486 487 */ 487 488 int iwl_mvm_sta_send_to_fw(struct iwl_mvm *mvm, struct ieee80211_sta *sta, 488 489 bool update, unsigned int flags);
+1 -1
drivers/net/wireless/intel/iwlwifi/mvm/tests/Makefile
··· 1 - iwlmvm-tests-y += module.o links.o scan.o hcmd.o 1 + iwlmvm-tests-y += module.o links.o hcmd.o 2 2 3 3 obj-$(CONFIG_IWLWIFI_KUNIT_TESTS) += iwlmvm-tests.o
+21 -22
drivers/net/wireless/intel/iwlwifi/mvm/tests/scan.c drivers/net/wireless/intel/iwlwifi/tests/utils.c
··· 1 1 // SPDX-License-Identifier: GPL-2.0-only 2 2 /* 3 - * KUnit tests for channel helper functions 3 + * KUnit tests for utilities 4 4 * 5 - * Copyright (C) 2024 Intel Corporation 5 + * Copyright (C) 2024-2025 Intel Corporation 6 6 */ 7 - #include <net/mac80211.h> 8 - #include "../mvm.h" 7 + #include "../iwl-utils.h" 9 8 #include <kunit/test.h> 10 9 11 - MODULE_IMPORT_NS("EXPORTED_FOR_KUNIT_TESTING"); 10 + MODULE_IMPORT_NS("IWLWIFI"); 12 11 13 - static const struct acs_average_db_case { 12 + static const struct average_neg_db_case { 14 13 const char *desc; 15 14 u8 neg_dbm[22]; 16 15 s8 result; 17 - } acs_average_db_cases[] = { 16 + } average_neg_db_cases[] = { 18 17 { 19 18 .desc = "Smallest possible value, all filled", 20 19 .neg_dbm = { ··· 72 73 }, 73 74 }; 74 75 75 - KUNIT_ARRAY_PARAM_DESC(acs_average_db, acs_average_db_cases, desc) 76 + KUNIT_ARRAY_PARAM_DESC(average_neg_db, average_neg_db_cases, desc) 76 77 77 - static void test_acs_average_db(struct kunit *test) 78 + static void test_average_neg_db(struct kunit *test) 78 79 { 79 - const struct acs_average_db_case *params = test->param_value; 80 - struct iwl_umac_scan_channel_survey_notif notif; 80 + const struct average_neg_db_case *params = test->param_value; 81 + u8 reversed[ARRAY_SIZE(params->neg_dbm)]; 81 82 int i; 82 83 83 84 /* Test the values in the given order */ 84 - for (i = 0; i < ARRAY_SIZE(params->neg_dbm); i++) 85 - notif.noise[i] = params->neg_dbm[i]; 86 85 KUNIT_ASSERT_EQ(test, 87 - iwl_mvm_average_dbm_values(&notif), 86 + iwl_average_neg_dbm(params->neg_dbm, 87 + ARRAY_SIZE(params->neg_dbm)), 88 88 params->result); 89 89 90 90 /* Test in reverse order */ 91 91 for (i = 0; i < ARRAY_SIZE(params->neg_dbm); i++) 92 - notif.noise[ARRAY_SIZE(params->neg_dbm) - i - 1] = 92 + reversed[ARRAY_SIZE(params->neg_dbm) - i - 1] = 93 93 params->neg_dbm[i]; 94 94 KUNIT_ASSERT_EQ(test, 95 - iwl_mvm_average_dbm_values(&notif), 95 + iwl_average_neg_dbm(reversed, 96 + ARRAY_SIZE(params->neg_dbm)), 96 97 params->result); 97 98 } 98 99 99 - static struct kunit_case acs_average_db_case[] = { 100 - KUNIT_CASE_PARAM(test_acs_average_db, acs_average_db_gen_params), 100 + static struct kunit_case average_db_case[] = { 101 + KUNIT_CASE_PARAM(test_average_neg_db, average_neg_db_gen_params), 101 102 {} 102 103 }; 103 104 104 - static struct kunit_suite acs_average_db = { 105 - .name = "iwlmvm-acs-average-db", 106 - .test_cases = acs_average_db_case, 105 + static struct kunit_suite average_db = { 106 + .name = "iwl-average-db", 107 + .test_cases = average_db_case, 107 108 }; 108 109 109 - kunit_test_suite(acs_average_db); 110 + kunit_test_suite(average_db);
+6 -2
drivers/net/wireless/intel/iwlwifi/mvm/time-event.h
··· 1 1 /* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ 2 2 /* 3 - * Copyright (C) 2012-2014, 2019-2020, 2023 Intel Corporation 3 + * Copyright (C) 2012-2014, 2019-2020, 2023, 2025 Intel Corporation 4 4 * Copyright (C) 2013-2014 Intel Mobile Communications GmbH 5 5 */ 6 6 #ifndef __time_event_h__ ··· 124 124 * ROC request, it will issue a notification to the driver that it is on the 125 125 * requested channel. Once the FW completes the ROC request it will issue 126 126 * another notification to the driver. 127 + * 128 + * Return: negative error code or 0 on success 127 129 */ 128 130 int iwl_mvm_start_p2p_roc(struct iwl_mvm *mvm, struct ieee80211_vif *vif, 129 131 int duration, enum ieee80211_roc_type type); ··· 181 179 * 182 180 * This function is used to schedule NoA time event and is used to perform 183 181 * the channel switch flow. 182 + * 183 + * Return: negative error code or 0 on success 184 184 */ 185 185 int iwl_mvm_schedule_csa_period(struct iwl_mvm *mvm, 186 186 struct ieee80211_vif *vif, ··· 192 188 * iwl_mvm_te_scheduled - check if the fw received the TE cmd 193 189 * @te_data: the time event data that corresponds to that time event 194 190 * 195 - * This function returns true iff this TE is added to the fw. 191 + * Return: %true if this TE is added to the fw, %false otherwise 196 192 */ 197 193 static inline bool 198 194 iwl_mvm_te_scheduled(struct iwl_mvm_time_event_data *te_data)
+3 -3
drivers/net/wireless/intel/iwlwifi/pcie/ctxt-info-v2.c
··· 6 6 #include "iwl-trans.h" 7 7 #include "iwl-fh.h" 8 8 #include "iwl-context-info-v2.h" 9 - #include "internal.h" 9 + #include "gen1_2/internal.h" 10 10 #include "iwl-prph.h" 11 11 12 12 static const struct dmi_system_id dmi_force_scu_active_approved_list[] = { ··· 391 391 { 392 392 struct iwl_dram_data *cur_payload_dram = &dram_regions->drams[0]; 393 393 struct iwl_dram_data *desc_dram = &dram_regions->prph_scratch_mem_desc; 394 - struct iwl_prph_scrath_mem_desc_addr_array *addresses; 394 + struct iwl_prph_scratch_mem_desc_addr_array *addresses; 395 395 const void *data; 396 396 u32 len; 397 397 int i; 398 398 399 399 /* allocate and init DRAM descriptors array */ 400 - len = sizeof(struct iwl_prph_scrath_mem_desc_addr_array); 400 + len = sizeof(struct iwl_prph_scratch_mem_desc_addr_array); 401 401 desc_dram->block = iwl_pcie_ctxt_info_dma_alloc_coherent 402 402 (trans, 403 403 len,
+1 -1
drivers/net/wireless/intel/iwlwifi/pcie/ctxt-info.c
··· 6 6 #include "iwl-trans.h" 7 7 #include "iwl-fh.h" 8 8 #include "iwl-context-info.h" 9 - #include "internal.h" 9 + #include "gen1_2/internal.h" 10 10 #include "iwl-prph.h" 11 11 12 12 static void *_iwl_pcie_ctxt_info_dma_alloc_coherent(struct iwl_trans *trans,
+11 -1
drivers/net/wireless/intel/iwlwifi/pcie/drv.c
··· 15 15 #include "iwl-trans.h" 16 16 #include "iwl-drv.h" 17 17 #include "iwl-prph.h" 18 - #include "internal.h" 18 + #include "gen1_2/internal.h" 19 19 20 20 #define _IS_A(cfg, _struct) __builtin_types_compatible_p(typeof(cfg), \ 21 21 struct _struct) ··· 545 545 {IWL_PCI_DEVICE(0xE340, PCI_ANY_ID, iwl_sc_mac_cfg)}, 546 546 {IWL_PCI_DEVICE(0xD340, PCI_ANY_ID, iwl_sc_mac_cfg)}, 547 547 {IWL_PCI_DEVICE(0x6E70, PCI_ANY_ID, iwl_sc_mac_cfg)}, 548 + {IWL_PCI_DEVICE(0xD240, PCI_ANY_ID, iwl_sc_mac_cfg)}, 548 549 #endif /* CONFIG_IWLMLD */ 549 550 550 551 {0} ··· 1581 1580 1582 1581 #endif /* CONFIG_PM_SLEEP */ 1583 1582 1583 + static void iwl_pci_dump(struct device *device) 1584 + { 1585 + struct pci_dev *pdev = to_pci_dev(device); 1586 + struct iwl_trans *trans = pci_get_drvdata(pdev); 1587 + 1588 + iwl_op_mode_dump(trans->op_mode); 1589 + } 1590 + 1584 1591 static struct pci_driver iwl_pci_driver = { 1585 1592 .name = DRV_NAME, 1586 1593 .id_table = iwl_hw_card_ids, 1587 1594 .probe = iwl_pci_probe, 1588 1595 .remove = iwl_pci_remove, 1589 1596 .driver.pm = IWL_PM_OPS, 1597 + .driver.coredump = iwl_pci_dump, 1590 1598 }; 1591 1599 1592 1600 int __must_check iwl_pci_register_driver(void)
+13 -36
drivers/net/wireless/intel/iwlwifi/pcie/internal.h drivers/net/wireless/intel/iwlwifi/pcie/gen1_2/internal.h
··· 22 22 #include "iwl-io.h" 23 23 #include "iwl-op-mode.h" 24 24 #include "iwl-drv.h" 25 - #include "iwl-context-info.h" 25 + #include "pcie/iwl-context-info.h" 26 26 27 27 /* 28 28 * RX related structures and functions ··· 39 39 * trans_pcie layer */ 40 40 41 41 /** 42 - * struct iwl_rx_mem_buffer 42 + * struct iwl_rx_mem_buffer - driver-side RX buffer descriptor 43 43 * @page_dma: bus address of rxb page 44 44 * @page: driver's pointer to the rxb page 45 45 * @list: list entry for the membuffer ··· 190 190 * iwl_get_closed_rb_stts - get closed rb stts from different structs 191 191 * @trans: transport pointer (for configuration) 192 192 * @rxq: the rxq to get the rb stts from 193 + * Return: last closed RB index 193 194 */ 194 195 static inline u16 iwl_get_closed_rb_stts(struct iwl_trans *trans, 195 196 struct iwl_rxq *rxq) ··· 383 382 * @irq_lock: lock to synchronize IRQ handling 384 383 * @txq_memory: TXQ allocation array 385 384 * @sx_waitq: waitqueue for Sx transitions 386 - * @sx_complete: completion for Sx transitions 387 - * @pcie_dbg_dumped_once: indicates PCIe regs were dumped already 385 + * @sx_state: state tracking Sx transitions 388 386 * @opmode_down: indicates opmode went away 389 387 * @num_rx_bufs: number of RX buffers to allocate/use 390 388 * @affinity_mask: IRQ affinity mask for each RX queue ··· 448 448 u8 __iomem *hw_base; 449 449 450 450 bool ucode_write_complete; 451 - bool sx_complete; 451 + enum { 452 + IWL_SX_INVALID = 0, 453 + IWL_SX_WAITING, 454 + IWL_SX_ERROR, 455 + IWL_SX_COMPLETE, 456 + } sx_state; 452 457 wait_queue_head_t ucode_write_waitq; 453 458 wait_queue_head_t sx_waitq; 454 459 455 460 u16 num_rx_bufs; 456 461 457 - bool pcie_dbg_dumped_once; 458 462 u32 rx_page_order; 459 463 u32 rx_buf_bytes; 460 464 u32 supported_dma_mask; ··· 702 698 * iwl_txq_inc_wrap - increment queue index, wrap back to beginning 703 699 * @trans: the transport (for configuration data) 704 700 * @index: current index 701 + * Return: the queue index incremented, subject to wrapping 705 702 */ 706 703 static inline int iwl_txq_inc_wrap(struct iwl_trans *trans, int index) 707 704 { ··· 714 709 * iwl_txq_dec_wrap - decrement queue index, wrap back to end 715 710 * @trans: the transport (for configuration data) 716 711 * @index: current index 712 + * Return: the queue index decremented, subject to wrapping 717 713 */ 718 714 static inline int iwl_txq_dec_wrap(struct iwl_trans *trans, int index) 719 715 { ··· 1034 1028 CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW); 1035 1029 } 1036 1030 1037 - static inline void __iwl_trans_pcie_set_bits_mask(struct iwl_trans *trans, 1038 - u32 reg, u32 mask, u32 value) 1039 - { 1040 - u32 v; 1041 - 1042 - #ifdef CONFIG_IWLWIFI_DEBUG 1043 - WARN_ON_ONCE(value & ~mask); 1044 - #endif 1045 - 1046 - v = iwl_read32(trans, reg); 1047 - v &= ~mask; 1048 - v |= value; 1049 - iwl_write32(trans, reg, v); 1050 - } 1051 - 1052 - static inline void __iwl_trans_pcie_clear_bit(struct iwl_trans *trans, 1053 - u32 reg, u32 mask) 1054 - { 1055 - __iwl_trans_pcie_set_bits_mask(trans, reg, mask, 0); 1056 - } 1057 - 1058 - static inline void __iwl_trans_pcie_set_bit(struct iwl_trans *trans, 1059 - u32 reg, u32 mask) 1060 - { 1061 - __iwl_trans_pcie_set_bits_mask(trans, reg, mask, mask); 1062 - } 1063 - 1064 1031 static inline bool iwl_pcie_dbg_on(struct iwl_trans *trans) 1065 1032 { 1066 1033 return (trans->dbg.dest_tlv || iwl_trans_dbg_ini_valid(trans)); 1067 1034 } 1068 1035 1069 1036 void iwl_trans_pcie_rf_kill(struct iwl_trans *trans, bool state, bool from_irq); 1070 - void iwl_trans_pcie_dump_regs(struct iwl_trans *trans); 1071 1037 1072 1038 #ifdef CONFIG_IWLWIFI_DEBUGFS 1073 1039 void iwl_trans_pcie_dbgfs_register(struct iwl_trans *trans); ··· 1052 1074 1053 1075 /* common trans ops for all generations transports */ 1054 1076 void iwl_trans_pcie_op_mode_enter(struct iwl_trans *trans); 1077 + int _iwl_trans_pcie_start_hw(struct iwl_trans *trans); 1055 1078 int iwl_trans_pcie_start_hw(struct iwl_trans *trans); 1056 1079 void iwl_trans_pcie_op_mode_leave(struct iwl_trans *trans); 1057 1080 void iwl_trans_pcie_write8(struct iwl_trans *trans, u32 ofs, u8 val); ··· 1062 1083 void iwl_trans_pcie_write_prph(struct iwl_trans *trans, u32 addr, u32 val); 1063 1084 int iwl_trans_pcie_read_mem(struct iwl_trans *trans, u32 addr, 1064 1085 void *buf, int dwords); 1065 - int iwl_trans_pcie_write_mem(struct iwl_trans *trans, u32 addr, 1066 - const void *buf, int dwords); 1067 1086 int iwl_trans_pcie_sw_reset(struct iwl_trans *trans, bool retake_ownership); 1068 1087 struct iwl_trans_dump_data * 1069 1088 iwl_trans_pcie_dump_data(struct iwl_trans *trans, u32 dump_mask,
+30 -4
drivers/net/wireless/intel/iwlwifi/pcie/rx.c drivers/net/wireless/intel/iwlwifi/pcie/gen1_2/rx.c
··· 12 12 #include "iwl-io.h" 13 13 #include "internal.h" 14 14 #include "iwl-op-mode.h" 15 - #include "iwl-context-info-v2.h" 15 + #include "pcie/iwl-context-info-v2.h" 16 16 #include "fw/dbg.h" 17 17 18 18 /****************************************************************************** ··· 1700 1700 timer_delete(&trans_pcie->txqs.txq[i]->stuck_timer); 1701 1701 } 1702 1702 1703 + if (trans->mac_cfg->device_family >= IWL_DEVICE_FAMILY_SC) { 1704 + u32 val = iwl_read32(trans, CSR_IPC_STATE); 1705 + 1706 + if (val & CSR_IPC_STATE_TOP_RESET_REQ) { 1707 + IWL_ERR(trans, "FW requested TOP reset for FSEQ\n"); 1708 + trans->do_top_reset = 1; 1709 + } 1710 + } 1711 + 1703 1712 /* The STATUS_FW_ERROR bit is set in this function. This must happen 1704 1713 * before we wake up the command caller, to ensure a proper cleanup. */ 1705 1714 iwl_trans_fw_error(trans, IWL_ERR_TYPE_IRQ); ··· 1861 1852 } 1862 1853 fallthrough; 1863 1854 case CSR_IPC_STATE_RESET_TOP_READY: 1864 - /* FIXME: handle this case when requesting TOP reset */ 1855 + if (trans_pcie->fw_reset_state == FW_RESET_TOP_REQUESTED) { 1856 + IWL_DEBUG_ISR(trans, "TOP Reset continues\n"); 1857 + trans_pcie->fw_reset_state = FW_RESET_OK; 1858 + wake_up(&trans_pcie->fw_reset_waitq); 1859 + break; 1860 + } 1865 1861 fallthrough; 1866 1862 case CSR_IPC_STATE_RESET_NONE: 1867 1863 IWL_FW_CHECK_FAILED(trans, ··· 2394 2380 } else { 2395 2381 iwl_pcie_irq_handle_error(trans); 2396 2382 } 2383 + 2384 + if (trans_pcie->sx_state == IWL_SX_WAITING) { 2385 + trans_pcie->sx_state = IWL_SX_ERROR; 2386 + wake_up(&trans_pcie->sx_waitq); 2387 + } 2397 2388 } 2398 2389 2399 2390 /* After checking FH register check HW register */ ··· 2433 2414 if (inta_hw & MSIX_HW_INT_CAUSES_REG_WAKEUP && trans_pcie->prph_info) { 2434 2415 u32 sleep_notif = 2435 2416 le32_to_cpu(trans_pcie->prph_info->sleep_notif); 2417 + 2436 2418 if (sleep_notif == IWL_D3_SLEEP_STATUS_SUSPEND || 2437 2419 sleep_notif == IWL_D3_SLEEP_STATUS_RESUME) { 2438 2420 IWL_DEBUG_ISR(trans, 2439 2421 "Sx interrupt: sleep notification = 0x%x\n", 2440 2422 sleep_notif); 2441 - trans_pcie->sx_complete = true; 2442 - wake_up(&trans_pcie->sx_waitq); 2423 + if (trans_pcie->sx_state == IWL_SX_WAITING) { 2424 + trans_pcie->sx_state = IWL_SX_COMPLETE; 2425 + wake_up(&trans_pcie->sx_waitq); 2426 + } else { 2427 + IWL_ERR(trans, 2428 + "unexpected Sx interrupt (0x%x)\n", 2429 + sleep_notif); 2430 + } 2443 2431 } else { 2444 2432 /* uCode wakes up after power-down sleep */ 2445 2433 IWL_DEBUG_ISR(trans, "Wakeup interrupt\n");
+7 -2
drivers/net/wireless/intel/iwlwifi/pcie/trans-gen2.c drivers/net/wireless/intel/iwlwifi/pcie/gen1_2/trans-gen2.c
··· 5 5 */ 6 6 #include "iwl-trans.h" 7 7 #include "iwl-prph.h" 8 - #include "iwl-context-info.h" 9 - #include "iwl-context-info-v2.h" 8 + #include "pcie/iwl-context-info.h" 9 + #include "pcie/iwl-context-info-v2.h" 10 10 #include "internal.h" 11 11 #include "fw/dbg.h" 12 12 ··· 610 610 msleep(10); 611 611 IWL_INFO(trans, "TOP reset successful, reinit now\n"); 612 612 /* now load the firmware again properly */ 613 + ret = _iwl_trans_pcie_start_hw(trans); 614 + if (ret) { 615 + IWL_ERR(trans, "failed to start HW after TOP reset\n"); 616 + goto out; 617 + } 613 618 trans_pcie->prph_scratch->ctrl_cfg.control.control_flags &= 614 619 ~cpu_to_le32(IWL_PRPH_SCRATCH_TOP_RESET); 615 620 top_reset_done = true;
+41 -141
drivers/net/wireless/intel/iwlwifi/pcie/trans.c drivers/net/wireless/intel/iwlwifi/pcie/gen1_2/trans.c
··· 28 28 #include "mei/iwl-mei.h" 29 29 #include "internal.h" 30 30 #include "iwl-fh.h" 31 - #include "iwl-context-info-v2.h" 31 + #include "pcie/iwl-context-info-v2.h" 32 + #include "pcie/utils.h" 32 33 33 34 /* extended range in FW SRAM */ 34 35 #define IWL_FW_MEM_EXTENDED_START 0x40000 35 36 #define IWL_FW_MEM_EXTENDED_END 0x57FFF 36 - 37 - void iwl_trans_pcie_dump_regs(struct iwl_trans *trans) 38 - { 39 - #define PCI_DUMP_SIZE 352 40 - #define PCI_MEM_DUMP_SIZE 64 41 - #define PCI_PARENT_DUMP_SIZE 524 42 - #define PREFIX_LEN 32 43 - struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); 44 - struct pci_dev *pdev = trans_pcie->pci_dev; 45 - u32 i, pos, alloc_size, *ptr, *buf; 46 - char *prefix; 47 - 48 - if (trans_pcie->pcie_dbg_dumped_once) 49 - return; 50 - 51 - /* Should be a multiple of 4 */ 52 - BUILD_BUG_ON(PCI_DUMP_SIZE > 4096 || PCI_DUMP_SIZE & 0x3); 53 - BUILD_BUG_ON(PCI_MEM_DUMP_SIZE > 4096 || PCI_MEM_DUMP_SIZE & 0x3); 54 - BUILD_BUG_ON(PCI_PARENT_DUMP_SIZE > 4096 || PCI_PARENT_DUMP_SIZE & 0x3); 55 - 56 - /* Alloc a max size buffer */ 57 - alloc_size = PCI_ERR_ROOT_ERR_SRC + 4 + PREFIX_LEN; 58 - alloc_size = max_t(u32, alloc_size, PCI_DUMP_SIZE + PREFIX_LEN); 59 - alloc_size = max_t(u32, alloc_size, PCI_MEM_DUMP_SIZE + PREFIX_LEN); 60 - alloc_size = max_t(u32, alloc_size, PCI_PARENT_DUMP_SIZE + PREFIX_LEN); 61 - 62 - buf = kmalloc(alloc_size, GFP_ATOMIC); 63 - if (!buf) 64 - return; 65 - prefix = (char *)buf + alloc_size - PREFIX_LEN; 66 - 67 - IWL_ERR(trans, "iwlwifi transaction failed, dumping registers\n"); 68 - 69 - /* Print wifi device registers */ 70 - sprintf(prefix, "iwlwifi %s: ", pci_name(pdev)); 71 - IWL_ERR(trans, "iwlwifi device config registers:\n"); 72 - for (i = 0, ptr = buf; i < PCI_DUMP_SIZE; i += 4, ptr++) 73 - if (pci_read_config_dword(pdev, i, ptr)) 74 - goto err_read; 75 - print_hex_dump(KERN_ERR, prefix, DUMP_PREFIX_OFFSET, 32, 4, buf, i, 0); 76 - 77 - IWL_ERR(trans, "iwlwifi device memory mapped registers:\n"); 78 - for (i = 0, ptr = buf; i < PCI_MEM_DUMP_SIZE; i += 4, ptr++) 79 - *ptr = iwl_read32(trans, i); 80 - print_hex_dump(KERN_ERR, prefix, DUMP_PREFIX_OFFSET, 32, 4, buf, i, 0); 81 - 82 - pos = pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_ERR); 83 - if (pos) { 84 - IWL_ERR(trans, "iwlwifi device AER capability structure:\n"); 85 - for (i = 0, ptr = buf; i < PCI_ERR_ROOT_COMMAND; i += 4, ptr++) 86 - if (pci_read_config_dword(pdev, pos + i, ptr)) 87 - goto err_read; 88 - print_hex_dump(KERN_ERR, prefix, DUMP_PREFIX_OFFSET, 89 - 32, 4, buf, i, 0); 90 - } 91 - 92 - /* Print parent device registers next */ 93 - if (!pdev->bus->self) 94 - goto out; 95 - 96 - pdev = pdev->bus->self; 97 - sprintf(prefix, "iwlwifi %s: ", pci_name(pdev)); 98 - 99 - IWL_ERR(trans, "iwlwifi parent port (%s) config registers:\n", 100 - pci_name(pdev)); 101 - for (i = 0, ptr = buf; i < PCI_PARENT_DUMP_SIZE; i += 4, ptr++) 102 - if (pci_read_config_dword(pdev, i, ptr)) 103 - goto err_read; 104 - print_hex_dump(KERN_ERR, prefix, DUMP_PREFIX_OFFSET, 32, 4, buf, i, 0); 105 - 106 - /* Print root port AER registers */ 107 - pos = 0; 108 - pdev = pcie_find_root_port(pdev); 109 - if (pdev) 110 - pos = pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_ERR); 111 - if (pos) { 112 - IWL_ERR(trans, "iwlwifi root port (%s) AER cap structure:\n", 113 - pci_name(pdev)); 114 - sprintf(prefix, "iwlwifi %s: ", pci_name(pdev)); 115 - for (i = 0, ptr = buf; i <= PCI_ERR_ROOT_ERR_SRC; i += 4, ptr++) 116 - if (pci_read_config_dword(pdev, pos + i, ptr)) 117 - goto err_read; 118 - print_hex_dump(KERN_ERR, prefix, DUMP_PREFIX_OFFSET, 32, 119 - 4, buf, i, 0); 120 - } 121 - goto out; 122 - 123 - err_read: 124 - print_hex_dump(KERN_ERR, prefix, DUMP_PREFIX_OFFSET, 32, 4, buf, i, 0); 125 - IWL_ERR(trans, "Read failed at 0x%X\n", i); 126 - out: 127 - trans_pcie->pcie_dbg_dumped_once = 1; 128 - kfree(buf); 129 - } 130 37 131 38 int iwl_trans_pcie_sw_reset(struct iwl_trans *trans, bool retake_ownership) 132 39 { ··· 294 387 u32 dl_cfg_reg; 295 388 296 389 /* Force XTAL ON */ 297 - __iwl_trans_pcie_set_bit(trans, CSR_GP_CNTRL, 298 - CSR_GP_CNTRL_REG_FLAG_XTAL_ON); 390 + iwl_trans_set_bit(trans, CSR_GP_CNTRL, 391 + CSR_GP_CNTRL_REG_FLAG_XTAL_ON); 299 392 300 393 ret = iwl_trans_pcie_sw_reset(trans, true); 301 394 ··· 304 397 305 398 if (WARN_ON(ret)) { 306 399 /* Release XTAL ON request */ 307 - __iwl_trans_pcie_clear_bit(trans, CSR_GP_CNTRL, 308 - CSR_GP_CNTRL_REG_FLAG_XTAL_ON); 400 + iwl_trans_clear_bit(trans, CSR_GP_CNTRL, 401 + CSR_GP_CNTRL_REG_FLAG_XTAL_ON); 309 402 return; 310 403 } 311 404 ··· 356 449 iwl_clear_bit(trans, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_INIT_DONE); 357 450 358 451 /* Activates XTAL resources monitor */ 359 - __iwl_trans_pcie_set_bit(trans, CSR_MONITOR_CFG_REG, 360 - CSR_MONITOR_XTAL_RESOURCES); 452 + iwl_trans_set_bit(trans, CSR_MONITOR_CFG_REG, 453 + CSR_MONITOR_XTAL_RESOURCES); 361 454 362 455 /* Release XTAL ON request */ 363 - __iwl_trans_pcie_clear_bit(trans, CSR_GP_CNTRL, 364 - CSR_GP_CNTRL_REG_FLAG_XTAL_ON); 456 + iwl_trans_clear_bit(trans, CSR_GP_CNTRL, 457 + CSR_GP_CNTRL_REG_FLAG_XTAL_ON); 365 458 udelay(10); 366 459 367 460 /* Release APMG XTAL */ ··· 611 704 trans_pcie->ucode_write_complete, 5 * HZ); 612 705 if (!ret) { 613 706 IWL_ERR(trans, "Failed to load firmware chunk!\n"); 614 - iwl_trans_pcie_dump_regs(trans); 707 + iwl_trans_pcie_dump_regs(trans, trans_pcie->pci_dev); 615 708 return -ETIMEDOUT; 616 709 } 617 710 ··· 1443 1536 struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); 1444 1537 int ret; 1445 1538 1539 + if (trans->mac_cfg->device_family < IWL_DEVICE_FAMILY_AX210) 1540 + return 0; 1541 + 1542 + trans_pcie->sx_state = IWL_SX_WAITING; 1543 + 1446 1544 if (trans->mac_cfg->device_family == IWL_DEVICE_FAMILY_AX210) 1447 1545 iwl_write_umac_prph(trans, UREG_DOORBELL_TO_ISR6, 1448 1546 suspend ? UREG_DOORBELL_TO_ISR6_SUSPEND : 1449 1547 UREG_DOORBELL_TO_ISR6_RESUME); 1450 - else if (trans->mac_cfg->device_family >= IWL_DEVICE_FAMILY_BZ) 1548 + else 1451 1549 iwl_write32(trans, CSR_IPC_SLEEP_CONTROL, 1452 1550 suspend ? CSR_IPC_SLEEP_CONTROL_SUSPEND : 1453 1551 CSR_IPC_SLEEP_CONTROL_RESUME); 1454 - else 1455 - return 0; 1456 1552 1457 1553 ret = wait_event_timeout(trans_pcie->sx_waitq, 1458 - trans_pcie->sx_complete, 2 * HZ); 1459 - 1460 - /* Invalidate it toward next suspend or resume */ 1461 - trans_pcie->sx_complete = false; 1462 - 1554 + trans_pcie->sx_state != IWL_SX_WAITING, 1555 + 2 * HZ); 1463 1556 if (!ret) { 1464 1557 IWL_ERR(trans, "Timeout %s D3\n", 1465 1558 suspend ? "entering" : "exiting"); 1466 - return -ETIMEDOUT; 1559 + ret = -ETIMEDOUT; 1560 + } else { 1561 + ret = 0; 1467 1562 } 1468 1563 1469 - return 0; 1564 + if (trans_pcie->sx_state == IWL_SX_ERROR) { 1565 + IWL_ERR(trans, "FW error while %s D3\n", 1566 + suspend ? "entering" : "exiting"); 1567 + ret = -EIO; 1568 + } 1569 + 1570 + /* Invalidate it toward next suspend or resume */ 1571 + trans_pcie->sx_state = IWL_SX_INVALID; 1572 + 1573 + return ret; 1470 1574 } 1471 1575 1472 1576 int iwl_trans_pcie_d3_suspend(struct iwl_trans *trans, bool test, bool reset) ··· 1763 1845 return iwl_trans_pcie_sw_reset(trans, true); 1764 1846 } 1765 1847 1766 - static int _iwl_trans_pcie_start_hw(struct iwl_trans *trans) 1848 + int _iwl_trans_pcie_start_hw(struct iwl_trans *trans) 1767 1849 { 1768 1850 struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); 1769 1851 int err; ··· 2330 2412 } 2331 2413 2332 2414 /* this bit wakes up the NIC */ 2333 - __iwl_trans_pcie_set_bit(trans, CSR_GP_CNTRL, write); 2415 + iwl_trans_set_bit(trans, CSR_GP_CNTRL, write); 2334 2416 if (trans->mac_cfg->device_family >= IWL_DEVICE_FAMILY_8000) 2335 2417 udelay(2); 2336 2418 ··· 2367 2449 "Timeout waiting for hardware access (CSR_GP_CNTRL 0x%08x)\n", 2368 2450 cntrl); 2369 2451 2370 - iwl_trans_pcie_dump_regs(trans); 2452 + iwl_trans_pcie_dump_regs(trans, trans_pcie->pci_dev); 2371 2453 2372 2454 if (iwlwifi_mod_params.remove_when_gone && cntrl == ~0U) 2373 2455 iwl_trans_pcie_reset(trans, ··· 2419 2501 if (trans_pcie->cmd_hold_nic_awake) 2420 2502 goto out; 2421 2503 if (trans->mac_cfg->device_family >= IWL_DEVICE_FAMILY_BZ) 2422 - __iwl_trans_pcie_clear_bit(trans, CSR_GP_CNTRL, 2423 - CSR_GP_CNTRL_REG_FLAG_BZ_MAC_ACCESS_REQ); 2504 + iwl_trans_clear_bit(trans, CSR_GP_CNTRL, 2505 + CSR_GP_CNTRL_REG_FLAG_BZ_MAC_ACCESS_REQ); 2424 2506 else 2425 - __iwl_trans_pcie_clear_bit(trans, CSR_GP_CNTRL, 2426 - CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ); 2507 + iwl_trans_clear_bit(trans, CSR_GP_CNTRL, 2508 + CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ); 2427 2509 /* 2428 2510 * Above we read the CSR_GP_CNTRL register, which will flush 2429 2511 * any previous writes, but we need the write that clears the ··· 2483 2565 } 2484 2566 2485 2567 return 0; 2486 - } 2487 - 2488 - int iwl_trans_pcie_write_mem(struct iwl_trans *trans, u32 addr, 2489 - const void *buf, int dwords) 2490 - { 2491 - int offs, ret = 0; 2492 - const u32 *vals = buf; 2493 - 2494 - if (iwl_trans_grab_nic_access(trans)) { 2495 - iwl_write32(trans, HBUS_TARG_MEM_WADDR, addr); 2496 - for (offs = 0; offs < dwords; offs++) 2497 - iwl_write32(trans, HBUS_TARG_MEM_WDAT, 2498 - vals ? vals[offs] : 0); 2499 - iwl_trans_release_nic_access(trans); 2500 - } else { 2501 - ret = -EBUSY; 2502 - } 2503 - return ret; 2504 2568 } 2505 2569 2506 2570 int iwl_trans_pcie_read_config32(struct iwl_trans *trans, u32 ofs, ··· 2604 2704 struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); 2605 2705 2606 2706 spin_lock_bh(&trans_pcie->reg_lock); 2607 - __iwl_trans_pcie_set_bits_mask(trans, reg, mask, value); 2707 + _iwl_trans_set_bits_mask(trans, reg, mask, value); 2608 2708 spin_unlock_bh(&trans_pcie->reg_lock); 2609 2709 } 2610 2710 ··· 3946 4046 IMR_D2S_REQUESTED, 5 * HZ); 3947 4047 if (!ret || trans_pcie->imr_status == IMR_D2S_ERROR) { 3948 4048 IWL_ERR(trans, "Failed to copy IMR Memory chunk!\n"); 3949 - iwl_trans_pcie_dump_regs(trans); 4049 + iwl_trans_pcie_dump_regs(trans, trans_pcie->pci_dev); 3950 4050 return -ETIMEDOUT; 3951 4051 } 3952 4052 trans_pcie->imr_status = IMR_D2S_IDLE;
drivers/net/wireless/intel/iwlwifi/pcie/tx-gen2.c drivers/net/wireless/intel/iwlwifi/pcie/gen1_2/tx-gen2.c
+8 -8
drivers/net/wireless/intel/iwlwifi/pcie/tx.c drivers/net/wireless/intel/iwlwifi/pcie/gen1_2/tx.c
··· 25 25 #include "iwl-op-mode.h" 26 26 #include "internal.h" 27 27 #include "fw/api/tx.h" 28 + #include "pcie/utils.h" 28 29 29 30 /*************** DMA-QUEUE-GENERAL-FUNCTIONS ***** 30 31 * DMA services ··· 204 203 } 205 204 206 205 trans_pcie->cmd_hold_nic_awake = false; 207 - __iwl_trans_pcie_clear_bit(trans, CSR_GP_CNTRL, 208 - CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ); 206 + iwl_trans_clear_bit(trans, CSR_GP_CNTRL, 207 + CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ); 209 208 spin_unlock(&trans_pcie->reg_lock); 210 209 } 211 210 ··· 495 494 iwl_read_prph(trans, SCD_SRAM_BASE_ADDR); 496 495 497 496 /* reset context data, TX status and translation data */ 498 - iwl_trans_pcie_write_mem(trans, trans_pcie->scd_base_addr + 499 - SCD_CONTEXT_MEM_LOWER_BOUND, 500 - NULL, clear_dwords); 497 + iwl_trans_write_mem(trans, trans_pcie->scd_base_addr + 498 + SCD_CONTEXT_MEM_LOWER_BOUND, 499 + NULL, clear_dwords); 501 500 502 501 iwl_write_prph(trans, SCD_DRAM_BASE_ADDR, 503 502 trans_pcie->txqs.scd_bc_tbls.dma >> 10); ··· 1293 1292 if (configure_scd) { 1294 1293 iwl_scd_txq_set_inactive(trans, txq_id); 1295 1294 1296 - iwl_trans_pcie_write_mem(trans, stts_addr, 1297 - (const void *)zero_val, 1298 - ARRAY_SIZE(zero_val)); 1295 + iwl_trans_write_mem(trans, stts_addr, (const void *)zero_val, 1296 + ARRAY_SIZE(zero_val)); 1299 1297 } 1300 1298 1301 1299 iwl_pcie_txq_unmap(trans, txq_id);
+104
drivers/net/wireless/intel/iwlwifi/pcie/utils.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause 2 + /* 3 + * Copyright (C) 2025 Intel Corporation 4 + */ 5 + 6 + #include <linux/pci.h> 7 + #include <linux/gfp.h> 8 + 9 + #include "iwl-io.h" 10 + #include "pcie/utils.h" 11 + 12 + void iwl_trans_pcie_dump_regs(struct iwl_trans *trans, struct pci_dev *pdev) 13 + { 14 + #define PCI_DUMP_SIZE 352 15 + #define PCI_MEM_DUMP_SIZE 64 16 + #define PCI_PARENT_DUMP_SIZE 524 17 + #define PREFIX_LEN 32 18 + 19 + static bool pcie_dbg_dumped_once = 0; 20 + u32 i, pos, alloc_size, *ptr, *buf; 21 + char *prefix; 22 + 23 + if (pcie_dbg_dumped_once) 24 + return; 25 + 26 + /* Should be a multiple of 4 */ 27 + BUILD_BUG_ON(PCI_DUMP_SIZE > 4096 || PCI_DUMP_SIZE & 0x3); 28 + BUILD_BUG_ON(PCI_MEM_DUMP_SIZE > 4096 || PCI_MEM_DUMP_SIZE & 0x3); 29 + BUILD_BUG_ON(PCI_PARENT_DUMP_SIZE > 4096 || PCI_PARENT_DUMP_SIZE & 0x3); 30 + 31 + /* Alloc a max size buffer */ 32 + alloc_size = PCI_ERR_ROOT_ERR_SRC + 4 + PREFIX_LEN; 33 + alloc_size = max_t(u32, alloc_size, PCI_DUMP_SIZE + PREFIX_LEN); 34 + alloc_size = max_t(u32, alloc_size, PCI_MEM_DUMP_SIZE + PREFIX_LEN); 35 + alloc_size = max_t(u32, alloc_size, PCI_PARENT_DUMP_SIZE + PREFIX_LEN); 36 + 37 + buf = kmalloc(alloc_size, GFP_ATOMIC); 38 + if (!buf) 39 + return; 40 + prefix = (char *)buf + alloc_size - PREFIX_LEN; 41 + 42 + IWL_ERR(trans, "iwlwifi transaction failed, dumping registers\n"); 43 + 44 + /* Print wifi device registers */ 45 + sprintf(prefix, "iwlwifi %s: ", pci_name(pdev)); 46 + IWL_ERR(trans, "iwlwifi device config registers:\n"); 47 + for (i = 0, ptr = buf; i < PCI_DUMP_SIZE; i += 4, ptr++) 48 + if (pci_read_config_dword(pdev, i, ptr)) 49 + goto err_read; 50 + print_hex_dump(KERN_ERR, prefix, DUMP_PREFIX_OFFSET, 32, 4, buf, i, 0); 51 + 52 + IWL_ERR(trans, "iwlwifi device memory mapped registers:\n"); 53 + for (i = 0, ptr = buf; i < PCI_MEM_DUMP_SIZE; i += 4, ptr++) 54 + *ptr = iwl_read32(trans, i); 55 + print_hex_dump(KERN_ERR, prefix, DUMP_PREFIX_OFFSET, 32, 4, buf, i, 0); 56 + 57 + pos = pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_ERR); 58 + if (pos) { 59 + IWL_ERR(trans, "iwlwifi device AER capability structure:\n"); 60 + for (i = 0, ptr = buf; i < PCI_ERR_ROOT_COMMAND; i += 4, ptr++) 61 + if (pci_read_config_dword(pdev, pos + i, ptr)) 62 + goto err_read; 63 + print_hex_dump(KERN_ERR, prefix, DUMP_PREFIX_OFFSET, 64 + 32, 4, buf, i, 0); 65 + } 66 + 67 + /* Print parent device registers next */ 68 + if (!pdev->bus->self) 69 + goto out; 70 + 71 + pdev = pdev->bus->self; 72 + sprintf(prefix, "iwlwifi %s: ", pci_name(pdev)); 73 + 74 + IWL_ERR(trans, "iwlwifi parent port (%s) config registers:\n", 75 + pci_name(pdev)); 76 + for (i = 0, ptr = buf; i < PCI_PARENT_DUMP_SIZE; i += 4, ptr++) 77 + if (pci_read_config_dword(pdev, i, ptr)) 78 + goto err_read; 79 + print_hex_dump(KERN_ERR, prefix, DUMP_PREFIX_OFFSET, 32, 4, buf, i, 0); 80 + 81 + /* Print root port AER registers */ 82 + pos = 0; 83 + pdev = pcie_find_root_port(pdev); 84 + if (pdev) 85 + pos = pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_ERR); 86 + if (pos) { 87 + IWL_ERR(trans, "iwlwifi root port (%s) AER cap structure:\n", 88 + pci_name(pdev)); 89 + sprintf(prefix, "iwlwifi %s: ", pci_name(pdev)); 90 + for (i = 0, ptr = buf; i <= PCI_ERR_ROOT_ERR_SRC; i += 4, ptr++) 91 + if (pci_read_config_dword(pdev, pos + i, ptr)) 92 + goto err_read; 93 + print_hex_dump(KERN_ERR, prefix, DUMP_PREFIX_OFFSET, 32, 94 + 4, buf, i, 0); 95 + } 96 + goto out; 97 + 98 + err_read: 99 + print_hex_dump(KERN_ERR, prefix, DUMP_PREFIX_OFFSET, 32, 4, buf, i, 0); 100 + IWL_ERR(trans, "Read failed at 0x%X\n", i); 101 + out: 102 + pcie_dbg_dumped_once = 1; 103 + kfree(buf); 104 + }
+38
drivers/net/wireless/intel/iwlwifi/pcie/utils.h
··· 1 + // SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause 2 + /* 3 + * Copyright (C) 2025 Intel Corporation 4 + */ 5 + 6 + #ifndef __iwl_pcie_utils_h__ 7 + #define __iwl_pcie_utils_h__ 8 + 9 + void iwl_trans_pcie_dump_regs(struct iwl_trans *trans, struct pci_dev *pdev); 10 + 11 + static inline void _iwl_trans_set_bits_mask(struct iwl_trans *trans, 12 + u32 reg, u32 mask, u32 value) 13 + { 14 + u32 v; 15 + 16 + #ifdef CONFIG_IWLWIFI_DEBUG 17 + WARN_ON_ONCE(value & ~mask); 18 + #endif 19 + 20 + v = iwl_read32(trans, reg); 21 + v &= ~mask; 22 + v |= value; 23 + iwl_write32(trans, reg, v); 24 + } 25 + 26 + static inline void iwl_trans_clear_bit(struct iwl_trans *trans, 27 + u32 reg, u32 mask) 28 + { 29 + _iwl_trans_set_bits_mask(trans, reg, mask, 0); 30 + } 31 + 32 + static inline void iwl_trans_set_bit(struct iwl_trans *trans, 33 + u32 reg, u32 mask) 34 + { 35 + _iwl_trans_set_bits_mask(trans, reg, mask, mask); 36 + } 37 + 38 + #endif /* __iwl_pcie_utils_h__ */
+1 -1
drivers/net/wireless/intel/iwlwifi/tests/Makefile
··· 1 1 # SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause 2 2 3 - iwlwifi-tests-y += module.o devinfo.o 3 + iwlwifi-tests-y += module.o devinfo.o utils.o 4 4 5 5 ccflags-y += -I$(src)/../ 6 6
+2 -1
drivers/net/wireless/intersil/p54/main.c
··· 313 313 priv->survey_raw.tx = 0; 314 314 } 315 315 316 - static int p54_config(struct ieee80211_hw *dev, u32 changed) 316 + static int p54_config(struct ieee80211_hw *dev, int radio_idx, u32 changed) 317 317 { 318 318 int ret = 0; 319 319 struct p54_common *priv = dev->priv; ··· 692 692 } 693 693 694 694 static void p54_set_coverage_class(struct ieee80211_hw *dev, 695 + int radio_idx, 695 696 s16 coverage_class) 696 697 { 697 698 struct p54_common *priv = dev->priv;
+1 -1
drivers/net/wireless/marvell/libertas_tf/main.c
··· 337 337 lbtf_deb_leave(LBTF_DEB_MACOPS); 338 338 } 339 339 340 - static int lbtf_op_config(struct ieee80211_hw *hw, u32 changed) 340 + static int lbtf_op_config(struct ieee80211_hw *hw, int radio_idx, u32 changed) 341 341 { 342 342 struct lbtf_private *priv = hw->priv; 343 343 struct ieee80211_conf *conf = &hw->conf;
+8 -3
drivers/net/wireless/marvell/mwifiex/cfg80211.c
··· 375 375 static int 376 376 mwifiex_cfg80211_set_tx_power(struct wiphy *wiphy, 377 377 struct wireless_dev *wdev, 378 + int radio_idx, 378 379 enum nl80211_tx_power_setting type, 379 380 int mbm) 380 381 { ··· 411 410 static int 412 411 mwifiex_cfg80211_get_tx_power(struct wiphy *wiphy, 413 412 struct wireless_dev *wdev, 413 + int radio_idx, 414 414 unsigned int link_id, int *dbm) 415 415 { 416 416 struct mwifiex_adapter *adapter = mwifiex_cfg80211_get_adapter(wiphy); ··· 739 737 * Fragmentation threshold of the driver. 740 738 */ 741 739 static int 742 - mwifiex_cfg80211_set_wiphy_params(struct wiphy *wiphy, u32 changed) 740 + mwifiex_cfg80211_set_wiphy_params(struct wiphy *wiphy, int radio_idx, 741 + u32 changed) 743 742 { 744 743 struct mwifiex_adapter *adapter = mwifiex_cfg80211_get_adapter(wiphy); 745 744 struct mwifiex_private *priv; ··· 1942 1939 } 1943 1940 1944 1941 static int 1945 - mwifiex_cfg80211_set_antenna(struct wiphy *wiphy, u32 tx_ant, u32 rx_ant) 1942 + mwifiex_cfg80211_set_antenna(struct wiphy *wiphy, int radio_idx, u32 tx_ant, 1943 + u32 rx_ant) 1946 1944 { 1947 1945 struct mwifiex_adapter *adapter = mwifiex_cfg80211_get_adapter(wiphy); 1948 1946 struct mwifiex_private *priv = mwifiex_get_priv(adapter, ··· 2006 2002 } 2007 2003 2008 2004 static int 2009 - mwifiex_cfg80211_get_antenna(struct wiphy *wiphy, u32 *tx_ant, u32 *rx_ant) 2005 + mwifiex_cfg80211_get_antenna(struct wiphy *wiphy, int radio_idx, u32 *tx_ant, 2006 + u32 *rx_ant) 2010 2007 { 2011 2008 struct mwifiex_adapter *adapter = mwifiex_cfg80211_get_adapter(wiphy); 2012 2009 struct mwifiex_private *priv = mwifiex_get_priv(adapter,
+1 -1
drivers/net/wireless/marvell/mwifiex/sdio.c
··· 438 438 .can_auto_tdls = false, 439 439 .can_ext_scan = true, 440 440 .fw_ready_extra_delay = false, 441 - .host_mlme = false, 441 + .host_mlme = true, 442 442 }; 443 443 444 444 static const struct mwifiex_sdio_device mwifiex_sdio_sd8887 = {
+7 -5
drivers/net/wireless/marvell/mwl8k.c
··· 3369 3369 } __packed; 3370 3370 3371 3371 static int 3372 - mwl8k_cmd_set_rts_threshold(struct ieee80211_hw *hw, int rts_thresh) 3372 + mwl8k_cmd_set_rts_threshold(struct ieee80211_hw *hw, int radio_idx, 3373 + int rts_thresh) 3373 3374 { 3374 3375 struct mwl8k_cmd_set_rts_threshold *cmd; 3375 3376 int rc; ··· 4956 4955 wiphy_err(hw->wiphy, "Firmware restart failed\n"); 4957 4956 } 4958 4957 4959 - static int mwl8k_config(struct ieee80211_hw *hw, u32 changed) 4958 + static int mwl8k_config(struct ieee80211_hw *hw, int radio_idx, u32 changed) 4960 4959 { 4961 4960 struct ieee80211_conf *conf = &hw->conf; 4962 4961 struct mwl8k_priv *priv = hw->priv; ··· 5322 5321 mwl8k_fw_unlock(hw); 5323 5322 } 5324 5323 5325 - static int mwl8k_set_rts_threshold(struct ieee80211_hw *hw, u32 value) 5324 + static int mwl8k_set_rts_threshold(struct ieee80211_hw *hw, int radio_idx, 5325 + u32 value) 5326 5326 { 5327 - return mwl8k_cmd_set_rts_threshold(hw, value); 5327 + return mwl8k_cmd_set_rts_threshold(hw, radio_idx, value); 5328 5328 } 5329 5329 5330 5330 static int mwl8k_sta_remove(struct ieee80211_hw *hw, ··· 6058 6056 if (rc) 6059 6057 goto fail; 6060 6058 6061 - rc = mwl8k_config(hw, ~0); 6059 + rc = mwl8k_config(hw, -1, ~0); 6062 6060 if (rc) 6063 6061 goto fail; 6064 6062
+2 -1
drivers/net/wireless/mediatek/mt76/mac80211.c
··· 1892 1892 } 1893 1893 EXPORT_SYMBOL_GPL(mt76_sw_scan_complete); 1894 1894 1895 - int mt76_get_antenna(struct ieee80211_hw *hw, u32 *tx_ant, u32 *rx_ant) 1895 + int mt76_get_antenna(struct ieee80211_hw *hw, int radio_idx, u32 *tx_ant, 1896 + u32 *rx_ant) 1896 1897 { 1897 1898 struct mt76_phy *phy = hw->priv; 1898 1899 struct mt76_dev *dev = phy->dev;
+2 -1
drivers/net/wireless/mediatek/mt76/mt76.h
··· 1513 1513 void mt76_csa_check(struct mt76_dev *dev); 1514 1514 void mt76_csa_finish(struct mt76_dev *dev); 1515 1515 1516 - int mt76_get_antenna(struct ieee80211_hw *hw, u32 *tx_ant, u32 *rx_ant); 1516 + int mt76_get_antenna(struct ieee80211_hw *hw, int radio_idx, u32 *tx_ant, 1517 + u32 *rx_ant); 1517 1518 int mt76_set_tim(struct ieee80211_hw *hw, struct ieee80211_sta *sta, bool set); 1518 1519 void mt76_insert_ccmp_hdr(struct sk_buff *skb, u8 key_id); 1519 1520 int mt76_get_rate(struct mt76_dev *dev,
+3 -2
drivers/net/wireless/mediatek/mt76/mt7603/main.c
··· 216 216 } 217 217 218 218 static int 219 - mt7603_config(struct ieee80211_hw *hw, u32 changed) 219 + mt7603_config(struct ieee80211_hw *hw, int radio_idx, u32 changed) 220 220 { 221 221 struct mt7603_dev *dev = hw->priv; 222 222 int ret = 0; ··· 657 657 } 658 658 659 659 static void 660 - mt7603_set_coverage_class(struct ieee80211_hw *hw, s16 coverage_class) 660 + mt7603_set_coverage_class(struct ieee80211_hw *hw, int radio_idx, 661 + s16 coverage_class) 661 662 { 662 663 struct mt7603_dev *dev = hw->priv; 663 664
+7 -4
drivers/net/wireless/mediatek/mt76/mt7615/main.c
··· 420 420 return mt76_update_channel(phy->mt76); 421 421 } 422 422 423 - static int mt7615_config(struct ieee80211_hw *hw, u32 changed) 423 + static int mt7615_config(struct ieee80211_hw *hw, int radio_idx, u32 changed) 424 424 { 425 425 struct mt7615_dev *dev = mt7615_hw_dev(hw); 426 426 struct mt7615_phy *phy = mt7615_hw_phy(hw); ··· 784 784 mt76_connac_pm_queue_skb(hw, &dev->pm, wcid, skb); 785 785 } 786 786 787 - static int mt7615_set_rts_threshold(struct ieee80211_hw *hw, u32 val) 787 + static int mt7615_set_rts_threshold(struct ieee80211_hw *hw, int radio_idx, 788 + u32 val) 788 789 { 789 790 struct mt7615_dev *dev = mt7615_hw_dev(hw); 790 791 struct mt7615_phy *phy = mt7615_hw_phy(hw); ··· 973 972 } 974 973 975 974 static void 976 - mt7615_set_coverage_class(struct ieee80211_hw *hw, s16 coverage_class) 975 + mt7615_set_coverage_class(struct ieee80211_hw *hw, int radio_idx, 976 + s16 coverage_class) 977 977 { 978 978 struct mt7615_phy *phy = mt7615_hw_phy(hw); 979 979 struct mt7615_dev *dev = phy->dev; ··· 986 984 } 987 985 988 986 static int 989 - mt7615_set_antenna(struct ieee80211_hw *hw, u32 tx_ant, u32 rx_ant) 987 + mt7615_set_antenna(struct ieee80211_hw *hw, int radio_idx, 988 + u32 tx_ant, u32 rx_ant) 990 989 { 991 990 struct mt7615_dev *dev = mt7615_hw_dev(hw); 992 991 struct mt7615_phy *phy = mt7615_hw_phy(hw);
+1 -1
drivers/net/wireless/mediatek/mt76/mt76x0/main.c
··· 57 57 } 58 58 EXPORT_SYMBOL_GPL(mt76x0_set_sar_specs); 59 59 60 - int mt76x0_config(struct ieee80211_hw *hw, u32 changed) 60 + int mt76x0_config(struct ieee80211_hw *hw, int radio_idx, u32 changed) 61 61 { 62 62 struct mt76x02_dev *dev = hw->priv; 63 63
+1 -1
drivers/net/wireless/mediatek/mt76/mt76x0/mt76x0.h
··· 48 48 49 49 void mt76x0_mac_stop(struct mt76x02_dev *dev); 50 50 51 - int mt76x0_config(struct ieee80211_hw *hw, u32 changed); 51 + int mt76x0_config(struct ieee80211_hw *hw, int radio_idx, u32 changed); 52 52 int mt76x0_set_channel(struct mt76_phy *mphy); 53 53 int mt76x0_set_sar_specs(struct ieee80211_hw *hw, 54 54 const struct cfg80211_sar_specs *sar);
+2 -2
drivers/net/wireless/mediatek/mt76/mt76x02.h
··· 183 183 void mt76x02_tx_set_txpwr_auto(struct mt76x02_dev *dev, s8 txpwr); 184 184 void mt76x02_set_tx_ackto(struct mt76x02_dev *dev); 185 185 void mt76x02_set_coverage_class(struct ieee80211_hw *hw, 186 - s16 coverage_class); 187 - int mt76x02_set_rts_threshold(struct ieee80211_hw *hw, u32 val); 186 + int radio_idx, s16 coverage_class); 187 + int mt76x02_set_rts_threshold(struct ieee80211_hw *hw, int radio_idx, u32 val); 188 188 void mt76x02_remove_hdr_pad(struct sk_buff *skb, int len); 189 189 bool mt76x02_tx_status_data(struct mt76_dev *mdev, u8 *update); 190 190 void mt76x02_queue_rx_skb(struct mt76_dev *mdev, enum mt76_rxq_id q,
+2 -2
drivers/net/wireless/mediatek/mt76/mt76x02_util.c
··· 548 548 EXPORT_SYMBOL_GPL(mt76x02_set_tx_ackto); 549 549 550 550 void mt76x02_set_coverage_class(struct ieee80211_hw *hw, 551 - s16 coverage_class) 551 + int radio_idx, s16 coverage_class) 552 552 { 553 553 struct mt76x02_dev *dev = hw->priv; 554 554 ··· 559 559 } 560 560 EXPORT_SYMBOL_GPL(mt76x02_set_coverage_class); 561 561 562 - int mt76x02_set_rts_threshold(struct ieee80211_hw *hw, u32 val) 562 + int mt76x02_set_rts_threshold(struct ieee80211_hw *hw, int radio_idx, u32 val) 563 563 { 564 564 struct mt76x02_dev *dev = hw->priv; 565 565
+3 -3
drivers/net/wireless/mediatek/mt76/mt76x2/pci_main.c
··· 54 54 } 55 55 56 56 static int 57 - mt76x2_config(struct ieee80211_hw *hw, u32 changed) 57 + mt76x2_config(struct ieee80211_hw *hw, int radio_idx, u32 changed) 58 58 { 59 59 struct mt76x02_dev *dev = hw->priv; 60 60 ··· 99 99 { 100 100 } 101 101 102 - static int mt76x2_set_antenna(struct ieee80211_hw *hw, u32 tx_ant, 103 - u32 rx_ant) 102 + static int mt76x2_set_antenna(struct ieee80211_hw *hw, int radio_idx, 103 + u32 tx_ant, u32 rx_ant) 104 104 { 105 105 struct mt76x02_dev *dev = hw->priv; 106 106
+1 -1
drivers/net/wireless/mediatek/mt76/mt76x2/usb_main.c
··· 50 50 } 51 51 52 52 static int 53 - mt76x2u_config(struct ieee80211_hw *hw, u32 changed) 53 + mt76x2u_config(struct ieee80211_hw *hw, int radio_idx, u32 changed) 54 54 { 55 55 struct mt76x02_dev *dev = hw->priv; 56 56 int err = 0;
+8 -5
drivers/net/wireless/mediatek/mt76/mt7915/main.c
··· 449 449 return err; 450 450 } 451 451 452 - static int mt7915_config(struct ieee80211_hw *hw, u32 changed) 452 + static int mt7915_config(struct ieee80211_hw *hw, int radio_idx, 453 + u32 changed) 453 454 { 454 455 struct mt7915_dev *dev = mt7915_hw_dev(hw); 455 456 struct mt7915_phy *phy = mt7915_hw_phy(hw); ··· 907 906 mt76_tx(mphy, control->sta, wcid, skb); 908 907 } 909 908 910 - static int mt7915_set_rts_threshold(struct ieee80211_hw *hw, u32 val) 909 + static int mt7915_set_rts_threshold(struct ieee80211_hw *hw, int radio_idx, 910 + u32 val) 911 911 { 912 912 struct mt7915_dev *dev = mt7915_hw_dev(hw); 913 913 struct mt7915_phy *phy = mt7915_hw_phy(hw); ··· 1104 1102 } 1105 1103 1106 1104 static void 1107 - mt7915_set_coverage_class(struct ieee80211_hw *hw, s16 coverage_class) 1105 + mt7915_set_coverage_class(struct ieee80211_hw *hw, int radio_idx, 1106 + s16 coverage_class) 1108 1107 { 1109 1108 struct mt7915_phy *phy = mt7915_hw_phy(hw); 1110 1109 struct mt7915_dev *dev = phy->dev; ··· 1117 1114 } 1118 1115 1119 1116 static int 1120 - mt7915_set_antenna(struct ieee80211_hw *hw, u32 tx_ant, u32 rx_ant) 1117 + mt7915_set_antenna(struct ieee80211_hw *hw, int radio_idx, u32 tx_ant, u32 rx_ant) 1121 1118 { 1122 1119 struct mt7915_dev *dev = mt7915_hw_dev(hw); 1123 1120 struct mt7915_phy *phy = mt7915_hw_phy(hw); ··· 1658 1655 } 1659 1656 1660 1657 static int 1661 - mt7915_set_frag_threshold(struct ieee80211_hw *hw, u32 val) 1658 + mt7915_set_frag_threshold(struct ieee80211_hw *hw, int radio_idx, u32 val) 1662 1659 { 1663 1660 return 0; 1664 1661 }
+5 -3
drivers/net/wireless/mediatek/mt76/mt7921/main.c
··· 624 624 mt76_connac_mcu_set_deep_sleep(&dev->mt76, pm->ds_enable); 625 625 } 626 626 627 - static int mt7921_config(struct ieee80211_hw *hw, u32 changed) 627 + static int mt7921_config(struct ieee80211_hw *hw, int radio_idx, u32 changed) 628 628 { 629 629 struct mt792x_dev *dev = mt792x_hw_dev(hw); 630 630 struct mt792x_phy *phy = mt792x_hw_phy(hw); ··· 907 907 } 908 908 EXPORT_SYMBOL_GPL(mt7921_mac_sta_remove); 909 909 910 - static int mt7921_set_rts_threshold(struct ieee80211_hw *hw, u32 val) 910 + static int mt7921_set_rts_threshold(struct ieee80211_hw *hw, int radio_idx, 911 + u32 val) 911 912 { 912 913 struct mt792x_dev *dev = mt792x_hw_dev(hw); 913 914 ··· 1089 1088 } 1090 1089 1091 1090 static int 1092 - mt7921_set_antenna(struct ieee80211_hw *hw, u32 tx_ant, u32 rx_ant) 1091 + mt7921_set_antenna(struct ieee80211_hw *hw, int radio_idx, 1092 + u32 tx_ant, u32 rx_ant) 1093 1093 { 1094 1094 struct mt792x_dev *dev = mt792x_hw_dev(hw); 1095 1095 struct mt792x_phy *phy = mt792x_hw_phy(hw);
+5 -3
drivers/net/wireless/mediatek/mt76/mt7925/main.c
··· 757 757 mt7925_mcu_set_deep_sleep(dev, pm->ds_enable); 758 758 } 759 759 760 - static int mt7925_config(struct ieee80211_hw *hw, u32 changed) 760 + static int mt7925_config(struct ieee80211_hw *hw, int radio_idx, u32 changed) 761 761 { 762 762 struct mt792x_dev *dev = mt792x_hw_dev(hw); 763 763 int ret = 0; ··· 1265 1265 } 1266 1266 EXPORT_SYMBOL_GPL(mt7925_mac_sta_remove); 1267 1267 1268 - static int mt7925_set_rts_threshold(struct ieee80211_hw *hw, u32 val) 1268 + static int mt7925_set_rts_threshold(struct ieee80211_hw *hw, int radio_idx, 1269 + u32 val) 1269 1270 { 1270 1271 struct mt792x_dev *dev = mt792x_hw_dev(hw); 1271 1272 ··· 1508 1507 } 1509 1508 1510 1509 static int 1511 - mt7925_set_antenna(struct ieee80211_hw *hw, u32 tx_ant, u32 rx_ant) 1510 + mt7925_set_antenna(struct ieee80211_hw *hw, int radio_idx, 1511 + u32 tx_ant, u32 rx_ant) 1512 1512 { 1513 1513 struct mt792x_dev *dev = mt792x_hw_dev(hw); 1514 1514 struct mt792x_phy *phy = mt792x_hw_phy(hw);
+2 -1
drivers/net/wireless/mediatek/mt76/mt792x.h
··· 412 412 struct ieee80211_vif *vif, 413 413 struct ieee80211_sta *sta, 414 414 struct station_info *sinfo); 415 - void mt792x_set_coverage_class(struct ieee80211_hw *hw, s16 coverage_class); 415 + void mt792x_set_coverage_class(struct ieee80211_hw *hw, int radio_idx, 416 + s16 coverage_class); 416 417 void mt792x_dma_cleanup(struct mt792x_dev *dev); 417 418 int mt792x_dma_enable(struct mt792x_dev *dev); 418 419 int mt792x_wpdma_reset(struct mt792x_dev *dev, bool force);
+2 -1
drivers/net/wireless/mediatek/mt76/mt792x_core.c
··· 579 579 } 580 580 EXPORT_SYMBOL_GPL(mt792x_sta_statistics); 581 581 582 - void mt792x_set_coverage_class(struct ieee80211_hw *hw, s16 coverage_class) 582 + void mt792x_set_coverage_class(struct ieee80211_hw *hw, int radio_idx, 583 + s16 coverage_class) 583 584 { 584 585 struct mt792x_phy *phy = mt792x_hw_phy(hw); 585 586 struct mt792x_dev *dev = phy->dev;
+7 -4
drivers/net/wireless/mediatek/mt76/mt7996/main.c
··· 591 591 return err; 592 592 } 593 593 594 - static int mt7996_config(struct ieee80211_hw *hw, u32 changed) 594 + static int mt7996_config(struct ieee80211_hw *hw, int radio_idx, u32 changed) 595 595 { 596 596 return 0; 597 597 } ··· 1251 1251 rcu_read_unlock(); 1252 1252 } 1253 1253 1254 - static int mt7996_set_rts_threshold(struct ieee80211_hw *hw, u32 val) 1254 + static int mt7996_set_rts_threshold(struct ieee80211_hw *hw, int radio_idx, 1255 + u32 val) 1255 1256 { 1256 1257 struct mt7996_dev *dev = mt7996_hw_dev(hw); 1257 1258 int i, ret = 0; ··· 1492 1491 } 1493 1492 1494 1493 static void 1495 - mt7996_set_coverage_class(struct ieee80211_hw *hw, s16 coverage_class) 1494 + mt7996_set_coverage_class(struct ieee80211_hw *hw, int radio_idx, 1495 + s16 coverage_class) 1496 1496 { 1497 1497 struct mt7996_dev *dev = mt7996_hw_dev(hw); 1498 1498 struct mt7996_phy *phy; ··· 1507 1505 } 1508 1506 1509 1507 static int 1510 - mt7996_set_antenna(struct ieee80211_hw *hw, u32 tx_ant, u32 rx_ant) 1508 + mt7996_set_antenna(struct ieee80211_hw *hw, int radio_idx, 1509 + u32 tx_ant, u32 rx_ant) 1511 1510 { 1512 1511 struct mt7996_dev *dev = mt7996_hw_dev(hw); 1513 1512 int i;
+3 -2
drivers/net/wireless/mediatek/mt7601u/main.c
··· 78 78 dev->wcid_mask[wcid / BITS_PER_LONG] &= ~BIT(wcid % BITS_PER_LONG); 79 79 } 80 80 81 - static int mt7601u_config(struct ieee80211_hw *hw, u32 changed) 81 + static int mt7601u_config(struct ieee80211_hw *hw, int radio_idx, u32 changed) 82 82 { 83 83 struct mt7601u_dev *dev = hw->priv; 84 84 int ret = 0; ··· 334 334 return mt76_mac_wcid_set_key(dev, msta->wcid.idx, key); 335 335 } 336 336 337 - static int mt7601u_set_rts_threshold(struct ieee80211_hw *hw, u32 value) 337 + static int mt7601u_set_rts_threshold(struct ieee80211_hw *hw, int radio_idx, 338 + u32 value) 338 339 { 339 340 struct mt7601u_dev *dev = hw->priv; 340 341
+4 -3
drivers/net/wireless/microchip/wilc1000/cfg80211.c
··· 800 800 return 0; 801 801 } 802 802 803 - static int set_wiphy_params(struct wiphy *wiphy, u32 changed) 803 + static int set_wiphy_params(struct wiphy *wiphy, int radio_idx, u32 changed) 804 804 { 805 805 int ret = -EINVAL; 806 806 struct cfg_param_attr cfg_param_val; ··· 1637 1637 } 1638 1638 1639 1639 static int set_tx_power(struct wiphy *wiphy, struct wireless_dev *wdev, 1640 - enum nl80211_tx_power_setting type, int mbm) 1640 + int radio_idx, enum nl80211_tx_power_setting type, 1641 + int mbm) 1641 1642 { 1642 1643 int ret; 1643 1644 int srcu_idx; ··· 1670 1669 } 1671 1670 1672 1671 static int get_tx_power(struct wiphy *wiphy, struct wireless_dev *wdev, 1673 - unsigned int link_id, int *dbm) 1672 + int radio_idx, unsigned int link_id, int *dbm) 1674 1673 { 1675 1674 int ret; 1676 1675 struct wilc_vif *vif = netdev_priv(wdev->netdev);
+3 -2
drivers/net/wireless/purelifi/plfxlc/mac.c
··· 531 531 mac->vif = NULL; 532 532 } 533 533 534 - static int plfxlc_op_config(struct ieee80211_hw *hw, u32 changed) 534 + static int plfxlc_op_config(struct ieee80211_hw *hw, int radio_idx, u32 changed) 535 535 { 536 536 return 0; 537 537 } ··· 677 677 data[1] = mac->crc_errors; 678 678 } 679 679 680 - static int plfxlc_set_rts_threshold(struct ieee80211_hw *hw, u32 value) 680 + static int plfxlc_set_rts_threshold(struct ieee80211_hw *hw, int radio_idx, 681 + u32 value) 681 682 { 682 683 return 0; 683 684 }
+5 -3
drivers/net/wireless/quantenna/qtnfmac/cfg80211.c
··· 370 370 return ret; 371 371 } 372 372 373 - static int qtnf_set_wiphy_params(struct wiphy *wiphy, u32 changed) 373 + static int qtnf_set_wiphy_params(struct wiphy *wiphy, int radio_idx, 374 + u32 changed) 374 375 { 375 376 struct qtnf_wmac *mac = wiphy_priv(wiphy); 376 377 struct qtnf_vif *vif; ··· 882 881 } 883 882 884 883 static int qtnf_get_tx_power(struct wiphy *wiphy, struct wireless_dev *wdev, 885 - unsigned int link_id, int *dbm) 884 + int radio_idx, unsigned int link_id, int *dbm) 886 885 { 887 886 struct qtnf_vif *vif = qtnf_netdev_get_priv(wdev->netdev); 888 887 int ret; ··· 895 894 } 896 895 897 896 static int qtnf_set_tx_power(struct wiphy *wiphy, struct wireless_dev *wdev, 898 - enum nl80211_tx_power_setting type, int mbm) 897 + int radio_idx, enum nl80211_tx_power_setting type, 898 + int mbm) 899 899 { 900 900 struct qtnf_vif *vif; 901 901 int ret;
+1 -1
drivers/net/wireless/ralink/rt2x00/rt2800lib.c
··· 12100 12100 } 12101 12101 EXPORT_SYMBOL_GPL(rt2800_get_key_seq); 12102 12102 12103 - int rt2800_set_rts_threshold(struct ieee80211_hw *hw, u32 value) 12103 + int rt2800_set_rts_threshold(struct ieee80211_hw *hw, int radio_idx, u32 value) 12104 12104 { 12105 12105 struct rt2x00_dev *rt2x00dev = hw->priv; 12106 12106 u32 reg;
+2 -1
drivers/net/wireless/ralink/rt2x00/rt2800lib.h
··· 253 253 void rt2800_get_key_seq(struct ieee80211_hw *hw, 254 254 struct ieee80211_key_conf *key, 255 255 struct ieee80211_key_seq *seq); 256 - int rt2800_set_rts_threshold(struct ieee80211_hw *hw, u32 value); 256 + int rt2800_set_rts_threshold(struct ieee80211_hw *hw, int radio_idx, 257 + u32 value); 257 258 int rt2800_conf_tx(struct ieee80211_hw *hw, 258 259 struct ieee80211_vif *vif, 259 260 unsigned int link_id, u16 queue_idx,
+5 -3
drivers/net/wireless/ralink/rt2x00/rt2x00.h
··· 1457 1457 struct ieee80211_vif *vif); 1458 1458 void rt2x00mac_remove_interface(struct ieee80211_hw *hw, 1459 1459 struct ieee80211_vif *vif); 1460 - int rt2x00mac_config(struct ieee80211_hw *hw, u32 changed); 1460 + int rt2x00mac_config(struct ieee80211_hw *hw, int radio_idx, u32 changed); 1461 1461 void rt2x00mac_configure_filter(struct ieee80211_hw *hw, 1462 1462 unsigned int changed_flags, 1463 1463 unsigned int *total_flags, ··· 1489 1489 void rt2x00mac_rfkill_poll(struct ieee80211_hw *hw); 1490 1490 void rt2x00mac_flush(struct ieee80211_hw *hw, struct ieee80211_vif *vif, 1491 1491 u32 queues, bool drop); 1492 - int rt2x00mac_set_antenna(struct ieee80211_hw *hw, u32 tx_ant, u32 rx_ant); 1493 - int rt2x00mac_get_antenna(struct ieee80211_hw *hw, u32 *tx_ant, u32 *rx_ant); 1492 + int rt2x00mac_set_antenna(struct ieee80211_hw *hw, int radio_idx, 1493 + u32 tx_ant, u32 rx_ant); 1494 + int rt2x00mac_get_antenna(struct ieee80211_hw *hw, int radio_idx, 1495 + u32 *tx_ant, u32 *rx_ant); 1494 1496 void rt2x00mac_get_ringparam(struct ieee80211_hw *hw, 1495 1497 u32 *tx, u32 *tx_max, u32 *rx, u32 *rx_max); 1496 1498 bool rt2x00mac_tx_frames_pending(struct ieee80211_hw *hw);
+5 -3
drivers/net/wireless/ralink/rt2x00/rt2x00mac.c
··· 304 304 } 305 305 EXPORT_SYMBOL_GPL(rt2x00mac_remove_interface); 306 306 307 - int rt2x00mac_config(struct ieee80211_hw *hw, u32 changed) 307 + int rt2x00mac_config(struct ieee80211_hw *hw, int radio_idx, u32 changed) 308 308 { 309 309 struct rt2x00_dev *rt2x00dev = hw->priv; 310 310 struct ieee80211_conf *conf = &hw->conf; ··· 740 740 } 741 741 EXPORT_SYMBOL_GPL(rt2x00mac_flush); 742 742 743 - int rt2x00mac_set_antenna(struct ieee80211_hw *hw, u32 tx_ant, u32 rx_ant) 743 + int rt2x00mac_set_antenna(struct ieee80211_hw *hw, int radio_idx, 744 + u32 tx_ant, u32 rx_ant) 744 745 { 745 746 struct rt2x00_dev *rt2x00dev = hw->priv; 746 747 struct link_ant *ant = &rt2x00dev->link.ant; ··· 786 785 } 787 786 EXPORT_SYMBOL_GPL(rt2x00mac_set_antenna); 788 787 789 - int rt2x00mac_get_antenna(struct ieee80211_hw *hw, u32 *tx_ant, u32 *rx_ant) 788 + int rt2x00mac_get_antenna(struct ieee80211_hw *hw, int radio_idx, 789 + u32 *tx_ant, u32 *rx_ant) 790 790 { 791 791 struct rt2x00_dev *rt2x00dev = hw->priv; 792 792 struct link_ant *ant = &rt2x00dev->link.ant;
+1 -1
drivers/net/wireless/realtek/rtl818x/rtl8180/dev.c
··· 1370 1370 priv->vif = NULL; 1371 1371 } 1372 1372 1373 - static int rtl8180_config(struct ieee80211_hw *dev, u32 changed) 1373 + static int rtl8180_config(struct ieee80211_hw *dev, int radio_idx, u32 changed) 1374 1374 { 1375 1375 struct rtl8180_priv *priv = dev->priv; 1376 1376 struct ieee80211_conf *conf = &dev->conf;
+3 -2
drivers/net/wireless/realtek/rtl818x/rtl8187/dev.c
··· 1041 1041 rtl818x_iowrite8(priv, &priv->map->CONFIG4, reg | RTL818X_CONFIG4_VCOOFF); 1042 1042 rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_NORMAL); 1043 1043 1044 + usb_kill_anchored_urbs(&priv->anchored); 1045 + 1044 1046 while ((skb = skb_dequeue(&priv->b_tx_status.queue))) 1045 1047 dev_kfree_skb_any(skb); 1046 1048 1047 - usb_kill_anchored_urbs(&priv->anchored); 1048 1049 mutex_unlock(&priv->conf_mutex); 1049 1050 1050 1051 if (!priv->is_rtl8187b) ··· 1152 1151 mutex_unlock(&priv->conf_mutex); 1153 1152 } 1154 1153 1155 - static int rtl8187_config(struct ieee80211_hw *dev, u32 changed) 1154 + static int rtl8187_config(struct ieee80211_hw *dev, int radio_idx, u32 changed) 1156 1155 { 1157 1156 struct rtl8187_priv *priv = dev->priv; 1158 1157 struct ieee80211_conf *conf = &dev->conf;
+5 -3
drivers/net/wireless/realtek/rtl8xxxu/core.c
··· 4552 4552 } 4553 4553 4554 4554 static 4555 - int rtl8xxxu_get_antenna(struct ieee80211_hw *hw, u32 *tx_ant, u32 *rx_ant) 4555 + int rtl8xxxu_get_antenna(struct ieee80211_hw *hw, int radio_idx, u32 *tx_ant, 4556 + u32 *rx_ant) 4556 4557 { 4557 4558 struct rtl8xxxu_priv *priv = hw->priv; 4558 4559 ··· 6840 6839 priv->vifs[rtlvif->port_num] = NULL; 6841 6840 } 6842 6841 6843 - static int rtl8xxxu_config(struct ieee80211_hw *hw, u32 changed) 6842 + static int rtl8xxxu_config(struct ieee80211_hw *hw, int radio_idx, u32 changed) 6844 6843 { 6845 6844 struct rtl8xxxu_priv *priv = hw->priv; 6846 6845 struct device *dev = &priv->udev->dev; ··· 6989 6988 FIF_PROBE_REQ); 6990 6989 } 6991 6990 6992 - static int rtl8xxxu_set_rts_threshold(struct ieee80211_hw *hw, u32 rts) 6991 + static int rtl8xxxu_set_rts_threshold(struct ieee80211_hw *hw, int radio_idx, 6992 + u32 rts) 6993 6993 { 6994 6994 if (rts > 2347 && rts != (u32)-1) 6995 6995 return -EINVAL;
+1 -1
drivers/net/wireless/realtek/rtlwifi/core.c
··· 566 566 } 567 567 #endif 568 568 569 - static int rtl_op_config(struct ieee80211_hw *hw, u32 changed) 569 + static int rtl_op_config(struct ieee80211_hw *hw, int radio_idx, u32 changed) 570 570 { 571 571 struct rtl_priv *rtlpriv = rtl_priv(hw); 572 572 struct rtl_phy *rtlphy = &(rtlpriv->phy);
+16 -7
drivers/net/wireless/realtek/rtlwifi/pci.c
··· 572 572 dma_map_single(&rtlpci->pdev->dev, skb_tail_pointer(skb), 573 573 rtlpci->rxbuffersize, DMA_FROM_DEVICE); 574 574 bufferaddress = *((dma_addr_t *)skb->cb); 575 - if (dma_mapping_error(&rtlpci->pdev->dev, bufferaddress)) 575 + if (dma_mapping_error(&rtlpci->pdev->dev, bufferaddress)) { 576 + if (!new_skb) 577 + kfree_skb(skb); 576 578 return 0; 579 + } 577 580 rtlpci->rx_ring[rxring_idx].rx_buf[desc_idx] = skb; 578 581 if (rtlpriv->use_new_trx_flow) { 579 582 /* skb->cb may be 64 bit address */ ··· 805 802 skb = new_skb; 806 803 no_new: 807 804 if (rtlpriv->use_new_trx_flow) { 808 - _rtl_pci_init_one_rxdesc(hw, skb, (u8 *)buffer_desc, 809 - rxring_idx, 810 - rtlpci->rx_ring[rxring_idx].idx); 805 + if (!_rtl_pci_init_one_rxdesc(hw, skb, (u8 *)buffer_desc, 806 + rxring_idx, 807 + rtlpci->rx_ring[rxring_idx].idx)) { 808 + if (new_skb) 809 + dev_kfree_skb_any(skb); 810 + } 811 811 } else { 812 - _rtl_pci_init_one_rxdesc(hw, skb, (u8 *)pdesc, 813 - rxring_idx, 814 - rtlpci->rx_ring[rxring_idx].idx); 812 + if (!_rtl_pci_init_one_rxdesc(hw, skb, (u8 *)pdesc, 813 + rxring_idx, 814 + rtlpci->rx_ring[rxring_idx].idx)) { 815 + if (new_skb) 816 + dev_kfree_skb_any(skb); 817 + } 815 818 if (rtlpci->rx_ring[rxring_idx].idx == 816 819 rtlpci->rxringcount - 1) 817 820 rtlpriv->cfg->ops->set_desc(hw, (u8 *)pdesc,
+3 -3
drivers/net/wireless/realtek/rtlwifi/rtl8188ee/hw.c
··· 1738 1738 } 1739 1739 } 1740 1740 1741 - static void _rtl88ee_read_txpower_info_from_hwpg(struct ieee80211_hw *hw, 1742 - bool autoload_fail, 1743 - u8 *hwinfo) 1741 + static noinline_for_stack void 1742 + _rtl88ee_read_txpower_info_from_hwpg(struct ieee80211_hw *hw, 1743 + bool autoload_fail, u8 *hwinfo) 1744 1744 { 1745 1745 struct rtl_priv *rtlpriv = rtl_priv(hw); 1746 1746 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
+1 -1
drivers/net/wireless/realtek/rtlwifi/rtl8188ee/sw.c
··· 190 190 return false; 191 191 } 192 192 193 - static struct rtl_hal_ops rtl8188ee_hal_ops = { 193 + static const struct rtl_hal_ops rtl8188ee_hal_ops = { 194 194 .init_sw_vars = rtl88e_init_sw_vars, 195 195 .deinit_sw_vars = rtl88e_deinit_sw_vars, 196 196 .read_eeprom_info = rtl88ee_read_eeprom_info,
+3 -3
drivers/net/wireless/realtek/rtlwifi/rtl8192ce/hw.c
··· 1412 1412 rtl92ce_enable_interrupt(hw); 1413 1413 } 1414 1414 1415 - static void _rtl92ce_read_txpower_info_from_hwpg(struct ieee80211_hw *hw, 1416 - bool autoload_fail, 1417 - u8 *hwinfo) 1415 + static noinline_for_stack void 1416 + _rtl92ce_read_txpower_info_from_hwpg(struct ieee80211_hw *hw, 1417 + bool autoload_fail, u8 *hwinfo) 1418 1418 { 1419 1419 struct rtl_priv *rtlpriv = rtl_priv(hw); 1420 1420 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
+1 -1
drivers/net/wireless/realtek/rtlwifi/rtl8192ce/sw.c
··· 167 167 } 168 168 } 169 169 170 - static struct rtl_hal_ops rtl8192ce_hal_ops = { 170 + static const struct rtl_hal_ops rtl8192ce_hal_ops = { 171 171 .init_sw_vars = rtl92c_init_sw_vars, 172 172 .deinit_sw_vars = rtl92c_deinit_sw_vars, 173 173 .read_eeprom_info = rtl92ce_read_eeprom_info,
+3 -3
drivers/net/wireless/realtek/rtlwifi/rtl8192cu/hw.c
··· 95 95 } 96 96 } 97 97 98 - static void _rtl92cu_read_txpower_info_from_hwpg(struct ieee80211_hw *hw, 99 - bool autoload_fail, 100 - u8 *hwinfo) 98 + static noinline_for_stack void 99 + _rtl92cu_read_txpower_info_from_hwpg(struct ieee80211_hw *hw, 100 + bool autoload_fail, u8 *hwinfo) 101 101 { 102 102 struct rtl_priv *rtlpriv = rtl_priv(hw); 103 103 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
+2 -2
drivers/net/wireless/realtek/rtlwifi/rtl8192cu/sw.c
··· 81 81 return false; 82 82 } 83 83 84 - static struct rtl_hal_ops rtl8192cu_hal_ops = { 84 + static const struct rtl_hal_ops rtl8192cu_hal_ops = { 85 85 .init_sw_vars = rtl92cu_init_sw_vars, 86 86 .deinit_sw_vars = rtl92cu_deinit_sw_vars, 87 87 .read_chip_version = rtl92c_read_chip_version, ··· 156 156 .usb_mq_to_hwq = rtl8192cu_mq_to_hwq, 157 157 }; 158 158 159 - static struct rtl_hal_cfg rtl92cu_hal_cfg = { 159 + static const struct rtl_hal_cfg rtl92cu_hal_cfg = { 160 160 .name = "rtl92c_usb", 161 161 .alt_fw_name = "rtlwifi/rtl8192cufw.bin", 162 162 .ops = &rtl8192cu_hal_ops,
+1 -1
drivers/net/wireless/realtek/rtlwifi/rtl8192de/sw.c
··· 184 184 skb_queue_purge(&rtlpriv->mac80211.skb_waitq[tid]); 185 185 } 186 186 187 - static struct rtl_hal_ops rtl8192de_hal_ops = { 187 + static const struct rtl_hal_ops rtl8192de_hal_ops = { 188 188 .init_sw_vars = rtl92d_init_sw_vars, 189 189 .deinit_sw_vars = rtl92d_deinit_sw_vars, 190 190 .read_eeprom_info = rtl92d_read_eeprom_info,
+4 -3
drivers/net/wireless/realtek/rtlwifi/rtl8192ee/hw.c
··· 1731 1731 rtl92ee_enable_interrupt(hw); 1732 1732 } 1733 1733 1734 - static u8 _rtl92ee_get_chnl_group(u8 chnl) 1734 + static __always_inline u8 _rtl92ee_get_chnl_group(u8 chnl) 1735 1735 { 1736 1736 u8 group = 0; 1737 1737 ··· 2009 2009 } 2010 2010 } 2011 2011 2012 - static void _rtl92ee_read_txpower_info_from_hwpg(struct ieee80211_hw *hw, 2013 - bool autoload_fail, u8 *hwinfo) 2012 + static noinline_for_stack void 2013 + _rtl92ee_read_txpower_info_from_hwpg(struct ieee80211_hw *hw, 2014 + bool autoload_fail, u8 *hwinfo) 2014 2015 { 2015 2016 struct rtl_priv *rtlpriv = rtl_priv(hw); 2016 2017 struct rtl_efuse *efu = rtl_efuse(rtl_priv(hw));
+1 -1
drivers/net/wireless/realtek/rtlwifi/rtl8192ee/sw.c
··· 176 176 return true; 177 177 } 178 178 179 - static struct rtl_hal_ops rtl8192ee_hal_ops = { 179 + static const struct rtl_hal_ops rtl8192ee_hal_ops = { 180 180 .init_sw_vars = rtl92ee_init_sw_vars, 181 181 .deinit_sw_vars = rtl92ee_deinit_sw_vars, 182 182 .read_eeprom_info = rtl92ee_read_eeprom_info,
+1 -1
drivers/net/wireless/realtek/rtlwifi/rtl8192se/sw.c
··· 221 221 return true; 222 222 } 223 223 224 - static struct rtl_hal_ops rtl8192se_hal_ops = { 224 + static const struct rtl_hal_ops rtl8192se_hal_ops = { 225 225 .init_sw_vars = rtl92s_init_sw_vars, 226 226 .deinit_sw_vars = rtl92s_deinit_sw_vars, 227 227 .read_eeprom_info = rtl92se_read_eeprom_info,
+3 -3
drivers/net/wireless/realtek/rtlwifi/rtl8723ae/hw.c
··· 1381 1381 return group; 1382 1382 } 1383 1383 1384 - static void _rtl8723e_read_txpower_info_from_hwpg(struct ieee80211_hw *hw, 1385 - bool autoload_fail, 1386 - u8 *hwinfo) 1384 + static noinline_for_stack void 1385 + _rtl8723e_read_txpower_info_from_hwpg(struct ieee80211_hw *hw, 1386 + bool autoload_fail, u8 *hwinfo) 1387 1387 { 1388 1388 struct rtl_priv *rtlpriv = rtl_priv(hw); 1389 1389 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
+1 -1
drivers/net/wireless/realtek/rtlwifi/rtl8723ae/sw.c
··· 183 183 return (le16_to_cpu(hdr->signature) & 0xfff0) == 0x2300; 184 184 } 185 185 186 - static struct rtl_hal_ops rtl8723e_hal_ops = { 186 + static const struct rtl_hal_ops rtl8723e_hal_ops = { 187 187 .init_sw_vars = rtl8723e_init_sw_vars, 188 188 .deinit_sw_vars = rtl8723e_deinit_sw_vars, 189 189 .read_eeprom_info = rtl8723e_read_eeprom_info,
+3 -3
drivers/net/wireless/realtek/rtlwifi/rtl8723be/hw.c
··· 1935 1935 } 1936 1936 } 1937 1937 1938 - static void _rtl8723be_read_txpower_info_from_hwpg(struct ieee80211_hw *hw, 1939 - bool autoload_fail, 1940 - u8 *hwinfo) 1938 + static noinline_for_stack void 1939 + _rtl8723be_read_txpower_info_from_hwpg(struct ieee80211_hw *hw, 1940 + bool autoload_fail, u8 *hwinfo) 1941 1941 { 1942 1942 struct rtl_priv *rtlpriv = rtl_priv(hw); 1943 1943 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
+1 -1
drivers/net/wireless/realtek/rtlwifi/rtl8723be/sw.c
··· 187 187 return (le16_to_cpu(hdr->signature) & 0xfff0) == 0x5300; 188 188 } 189 189 190 - static struct rtl_hal_ops rtl8723be_hal_ops = { 190 + static const struct rtl_hal_ops rtl8723be_hal_ops = { 191 191 .init_sw_vars = rtl8723be_init_sw_vars, 192 192 .deinit_sw_vars = rtl8723be_deinit_sw_vars, 193 193 .read_eeprom_info = rtl8723be_read_eeprom_info,
+9 -7
drivers/net/wireless/realtek/rtlwifi/rtl8821ae/hw.c
··· 2782 2782 "eeprom_regulatory = 0x%x\n", rtlefuse->eeprom_regulatory); 2783 2783 } 2784 2784 #endif 2785 - static void _rtl8821ae_read_txpower_info_from_hwpg(struct ieee80211_hw *hw, 2786 - bool autoload_fail, 2787 - u8 *hwinfo) 2785 + static noinline_for_stack void 2786 + _rtl8821ae_read_txpower_info_from_hwpg(struct ieee80211_hw *hw, 2787 + bool autoload_fail, u8 *hwinfo) 2788 2788 { 2789 2789 struct rtl_priv *rtlpriv = rtl_priv(hw); 2790 2790 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); ··· 3064 3064 struct rtl_priv *rtlpriv = rtl_priv(hw); 3065 3065 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); 3066 3066 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); 3067 - int params[] = {RTL_EEPROM_ID, EEPROM_VID, EEPROM_DID, 3068 - EEPROM_SVID, EEPROM_SMID, EEPROM_MAC_ADDR, 3069 - EEPROM_CHANNELPLAN, EEPROM_VERSION, EEPROM_CUSTOMER_ID, 3070 - COUNTRY_CODE_WORLD_WIDE_13}; 3067 + static const int params[] = { 3068 + RTL_EEPROM_ID, EEPROM_VID, EEPROM_DID, 3069 + EEPROM_SVID, EEPROM_SMID, EEPROM_MAC_ADDR, 3070 + EEPROM_CHANNELPLAN, EEPROM_VERSION, EEPROM_CUSTOMER_ID, 3071 + COUNTRY_CODE_WORLD_WIDE_13 3072 + }; 3071 3073 u8 *hwinfo; 3072 3074 3073 3075 if (b_pseudo_test) {
+1 -1
drivers/net/wireless/realtek/rtlwifi/rtl8821ae/sw.c
··· 229 229 return true; 230 230 } 231 231 232 - static struct rtl_hal_ops rtl8821ae_hal_ops = { 232 + static const struct rtl_hal_ops rtl8821ae_hal_ops = { 233 233 .init_sw_vars = rtl8821ae_init_sw_vars, 234 234 .deinit_sw_vars = rtl8821ae_deinit_sw_vars, 235 235 .read_eeprom_info = rtl8821ae_read_eeprom_info,
+4 -4
drivers/net/wireless/realtek/rtw88/fw.c
··· 521 521 u8 h2c_pkt[H2C_PKT_SIZE] = {0}; 522 522 u16 total_size = H2C_PKT_HDR_SIZE + 4; 523 523 524 - if (rtw_chip_wcpu_11n(rtwdev)) 524 + if (rtw_chip_wcpu_8051(rtwdev)) 525 525 return; 526 526 527 527 rtw_h2c_pkt_set_header(h2c_pkt, H2C_PKT_GENERAL_INFO); ··· 544 544 u16 total_size = H2C_PKT_HDR_SIZE + 8; 545 545 u8 fw_rf_type = 0; 546 546 547 - if (rtw_chip_wcpu_11n(rtwdev)) 547 + if (rtw_chip_wcpu_8051(rtwdev)) 548 548 return; 549 549 550 550 if (hal->rf_type == RF_1T1R) ··· 1480 1480 1481 1481 bckp[2] = rtw_read8(rtwdev, REG_BCN_CTRL); 1482 1482 1483 - if (rtw_chip_wcpu_11n(rtwdev)) { 1483 + if (rtw_chip_wcpu_8051(rtwdev)) { 1484 1484 rtw_write32_set(rtwdev, REG_DWBCN0_CTRL, BIT_BCN_VALID); 1485 1485 } else { 1486 1486 pg_addr &= BIT_MASK_BCN_HEAD_1_V1; ··· 1509 1509 goto restore; 1510 1510 } 1511 1511 1512 - if (rtw_chip_wcpu_11n(rtwdev)) { 1512 + if (rtw_chip_wcpu_8051(rtwdev)) { 1513 1513 bcn_valid_addr = REG_DWBCN0_CTRL; 1514 1514 bcn_valid_mask = BIT_BCN_VALID; 1515 1515 } else {
+11 -11
drivers/net/wireless/realtek/rtw88/mac.c
··· 41 41 } 42 42 rtw_write32(rtwdev, REG_WMAC_TRXPTCL_CTL, value32); 43 43 44 - if (rtw_chip_wcpu_11n(rtwdev)) 44 + if (rtw_chip_wcpu_8051(rtwdev)) 45 45 return; 46 46 47 47 value32 = rtw_read32(rtwdev, REG_AFE_CTRL1) & ~(BIT_MAC_CLK_SEL); ··· 67 67 68 68 rtw_write8(rtwdev, REG_RSV_CTRL, 0); 69 69 70 - if (rtw_chip_wcpu_11n(rtwdev)) { 70 + if (rtw_chip_wcpu_8051(rtwdev)) { 71 71 if (rtw_read32(rtwdev, REG_SYS_CFG1) & BIT_LDO) 72 72 rtw_write8(rtwdev, REG_LDO_SWR_CTRL, LDO_SEL); 73 73 else ··· 278 278 bool cur_pwr; 279 279 int ret; 280 280 281 - if (rtw_chip_wcpu_11ac(rtwdev)) { 281 + if (rtw_chip_wcpu_3081(rtwdev)) { 282 282 rpwm = rtw_read8(rtwdev, rtwdev->hci.rpwm_addr); 283 283 284 284 /* Check FW still exist or not */ ··· 369 369 370 370 static int rtw_mac_init_system_cfg(struct rtw_dev *rtwdev) 371 371 { 372 - if (rtw_chip_wcpu_11n(rtwdev)) 372 + if (rtw_chip_wcpu_8051(rtwdev)) 373 373 return __rtw_mac_init_system_cfg_legacy(rtwdev); 374 374 375 375 return __rtw_mac_init_system_cfg(rtwdev); ··· 981 981 static 982 982 int _rtw_download_firmware(struct rtw_dev *rtwdev, struct rtw_fw_state *fw) 983 983 { 984 - if (rtw_chip_wcpu_11n(rtwdev)) 984 + if (rtw_chip_wcpu_8051(rtwdev)) 985 985 return __rtw_download_firmware_legacy(rtwdev, fw); 986 986 987 987 return __rtw_download_firmware(rtwdev, fw); ··· 1122 1122 1123 1123 rtw_write8(rtwdev, REG_CR, 0); 1124 1124 rtw_write8(rtwdev, REG_CR, MAC_TRX_ENABLE); 1125 - if (rtw_chip_wcpu_11ac(rtwdev)) 1125 + if (rtw_chip_wcpu_3081(rtwdev)) 1126 1126 rtw_write32(rtwdev, REG_H2CQ_CSR, BIT_H2CQ_FULL); 1127 1127 1128 1128 if (rtw_hci_type(rtwdev) == RTW_HCI_TYPE_SDIO) { ··· 1145 1145 /* config rsvd page num */ 1146 1146 fifo->rsvd_drv_pg_num = chip->rsvd_drv_pg_num; 1147 1147 fifo->txff_pg_num = chip->txff_size / chip->page_size; 1148 - if (rtw_chip_wcpu_11n(rtwdev)) 1148 + if (rtw_chip_wcpu_8051(rtwdev)) 1149 1149 fifo->rsvd_pg_num = fifo->rsvd_drv_pg_num; 1150 1150 else 1151 1151 fifo->rsvd_pg_num = fifo->rsvd_drv_pg_num + ··· 1163 1163 fifo->rsvd_boundary = fifo->txff_pg_num - fifo->rsvd_pg_num; 1164 1164 1165 1165 cur_pg_addr = fifo->txff_pg_num; 1166 - if (rtw_chip_wcpu_11ac(rtwdev)) { 1166 + if (rtw_chip_wcpu_3081(rtwdev)) { 1167 1167 cur_pg_addr -= csi_buf_pg_num; 1168 1168 fifo->rsvd_csibuf_addr = cur_pg_addr; 1169 1169 cur_pg_addr -= RSVD_PG_FW_TXBUF_NUM; ··· 1292 1292 1293 1293 pubq_num = fifo->acq_pg_num - pg_tbl->hq_num - pg_tbl->lq_num - 1294 1294 pg_tbl->nq_num - pg_tbl->exq_num - pg_tbl->gapq_num; 1295 - if (rtw_chip_wcpu_11n(rtwdev)) 1295 + if (rtw_chip_wcpu_8051(rtwdev)) 1296 1296 return __priority_queue_cfg_legacy(rtwdev, pg_tbl, pubq_num); 1297 1297 else 1298 1298 return __priority_queue_cfg(rtwdev, pg_tbl, pubq_num); ··· 1308 1308 u32 h2cq_free; 1309 1309 u32 wp, rp; 1310 1310 1311 - if (rtw_chip_wcpu_11n(rtwdev)) 1311 + if (rtw_chip_wcpu_8051(rtwdev)) 1312 1312 return 0; 1313 1313 1314 1314 h2cq_addr = fifo->rsvd_h2cq_addr << TX_PAGE_SIZE_SHIFT; ··· 1375 1375 u8 value8; 1376 1376 1377 1377 rtw_write8(rtwdev, REG_RX_DRVINFO_SZ, PHY_STATUS_SIZE); 1378 - if (rtw_chip_wcpu_11ac(rtwdev)) { 1378 + if (rtw_chip_wcpu_3081(rtwdev)) { 1379 1379 value8 = rtw_read8(rtwdev, REG_TRXFF_BNDY + 1); 1380 1380 value8 &= 0xF0; 1381 1381 /* For rxdesc len = 0 issue */
+6 -3
drivers/net/wireless/realtek/rtw88/mac80211.c
··· 71 71 mutex_unlock(&rtwdev->mutex); 72 72 } 73 73 74 - static int rtw_ops_config(struct ieee80211_hw *hw, u32 changed) 74 + static int rtw_ops_config(struct ieee80211_hw *hw, int radio_idx, u32 changed) 75 75 { 76 76 struct rtw_dev *rtwdev = hw->priv; 77 77 int ret = 0; ··· 708 708 mutex_unlock(&rtwdev->mutex); 709 709 } 710 710 711 - static int rtw_ops_set_rts_threshold(struct ieee80211_hw *hw, u32 value) 711 + static int rtw_ops_set_rts_threshold(struct ieee80211_hw *hw, int radio_idx, 712 + u32 value) 712 713 { 713 714 struct rtw_dev *rtwdev = hw->priv; 714 715 ··· 798 797 } 799 798 800 799 static int rtw_ops_set_antenna(struct ieee80211_hw *hw, 800 + int radio_idx, 801 801 u32 tx_antenna, 802 802 u32 rx_antenna) 803 803 { ··· 810 808 return -EOPNOTSUPP; 811 809 812 810 mutex_lock(&rtwdev->mutex); 813 - ret = chip->ops->set_antenna(rtwdev, tx_antenna, rx_antenna); 811 + ret = chip->ops->set_antenna(rtwdev, -1, tx_antenna, rx_antenna); 814 812 mutex_unlock(&rtwdev->mutex); 815 813 816 814 return ret; 817 815 } 818 816 819 817 static int rtw_ops_get_antenna(struct ieee80211_hw *hw, 818 + int radio_idx, 820 819 u32 *tx_antenna, 821 820 u32 *rx_antenna) 822 821 {
+6 -9
drivers/net/wireless/realtek/rtw88/main.c
··· 636 636 if (!test_bit(RTW_FLAG_RESTARTING, rtwdev->flags)) 637 637 ieee80211_queue_work(rtwdev->hw, &rtwdev->fw_recovery_work); 638 638 } 639 + EXPORT_SYMBOL(rtw_fw_recovery); 639 640 640 641 static void __fw_recovery_work(struct rtw_dev *rtwdev) 641 642 { ··· 1766 1765 static void update_firmware_info(struct rtw_dev *rtwdev, 1767 1766 struct rtw_fw_state *fw) 1768 1767 { 1769 - if (rtw_chip_wcpu_11n(rtwdev)) 1768 + if (rtw_chip_wcpu_8051(rtwdev)) 1770 1769 __update_firmware_info_legacy(rtwdev, fw); 1771 1770 else 1772 1771 __update_firmware_info(rtwdev, fw); ··· 2219 2218 2220 2219 int rtw_register_hw(struct rtw_dev *rtwdev, struct ieee80211_hw *hw) 2221 2220 { 2222 - bool sta_mode_only = rtwdev->hci.type == RTW_HCI_TYPE_SDIO; 2223 2221 struct rtw_hal *hal = &rtwdev->hal; 2224 2222 int max_tx_headroom = 0; 2225 2223 int ret; ··· 2248 2248 ieee80211_hw_set(hw, TX_AMSDU); 2249 2249 ieee80211_hw_set(hw, SINGLE_SCAN_ON_ALL_BANDS); 2250 2250 2251 - if (sta_mode_only) 2252 - hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION); 2253 - else 2254 - hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) | 2255 - BIT(NL80211_IFTYPE_AP) | 2256 - BIT(NL80211_IFTYPE_ADHOC); 2251 + hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) | 2252 + BIT(NL80211_IFTYPE_AP) | 2253 + BIT(NL80211_IFTYPE_ADHOC); 2257 2254 hw->wiphy->available_antennas_tx = hal->antenna_tx; 2258 2255 hw->wiphy->available_antennas_rx = hal->antenna_rx; 2259 2256 ··· 2261 2264 hw->wiphy->max_scan_ssids = RTW_SCAN_MAX_SSIDS; 2262 2265 hw->wiphy->max_scan_ie_len = rtw_get_max_scan_ie_len(rtwdev); 2263 2266 2264 - if (!sta_mode_only && rtwdev->chip->id == RTW_CHIP_TYPE_8822C) { 2267 + if (rtwdev->chip->id == RTW_CHIP_TYPE_8822C) { 2265 2268 hw->wiphy->iface_combinations = rtw_iface_combs; 2266 2269 hw->wiphy->n_iface_combinations = ARRAY_SIZE(rtw_iface_combs); 2267 2270 }
+7 -7
drivers/net/wireless/realtek/rtw88/main.h
··· 873 873 void (*set_tx_power_index)(struct rtw_dev *rtwdev); 874 874 int (*rsvd_page_dump)(struct rtw_dev *rtwdev, u8 *buf, u32 offset, 875 875 u32 size); 876 - int (*set_antenna)(struct rtw_dev *rtwdev, 876 + int (*set_antenna)(struct rtw_dev *rtwdev, int radio_idx, 877 877 u32 antenna_tx, 878 878 u32 antenna_rx); 879 879 void (*cfg_ldo25)(struct rtw_dev *rtwdev, bool enable); ··· 1173 1173 }; 1174 1174 1175 1175 enum rtw_wlan_cpu { 1176 - RTW_WCPU_11AC, 1177 - RTW_WCPU_11N, 1176 + RTW_WCPU_3081, 1177 + RTW_WCPU_8051, 1178 1178 }; 1179 1179 1180 1180 enum rtw_fw_fifo_sel { ··· 2166 2166 rtwdev->chip->ops->efuse_grant(rtwdev, false); 2167 2167 } 2168 2168 2169 - static inline bool rtw_chip_wcpu_11n(struct rtw_dev *rtwdev) 2169 + static inline bool rtw_chip_wcpu_8051(struct rtw_dev *rtwdev) 2170 2170 { 2171 - return rtwdev->chip->wlan_cpu == RTW_WCPU_11N; 2171 + return rtwdev->chip->wlan_cpu == RTW_WCPU_8051; 2172 2172 } 2173 2173 2174 - static inline bool rtw_chip_wcpu_11ac(struct rtw_dev *rtwdev) 2174 + static inline bool rtw_chip_wcpu_3081(struct rtw_dev *rtwdev) 2175 2175 { 2176 - return rtwdev->chip->wlan_cpu == RTW_WCPU_11AC; 2176 + return rtwdev->chip->wlan_cpu == RTW_WCPU_3081; 2177 2177 } 2178 2178 2179 2179 static inline bool rtw_chip_has_rx_ldpc(struct rtw_dev *rtwdev)
+43 -6
drivers/net/wireless/realtek/rtw88/pci.c
··· 405 405 dma = rtwpci->tx_rings[RTW_TX_QUEUE_BCN].r.dma; 406 406 rtw_write32(rtwdev, RTK_PCI_TXBD_DESA_BCNQ, dma); 407 407 408 - if (!rtw_chip_wcpu_11n(rtwdev)) { 408 + if (!rtw_chip_wcpu_8051(rtwdev)) { 409 409 len = rtwpci->tx_rings[RTW_TX_QUEUE_H2C].r.len; 410 410 dma = rtwpci->tx_rings[RTW_TX_QUEUE_H2C].r.dma; 411 411 rtwpci->tx_rings[RTW_TX_QUEUE_H2C].r.rp = 0; ··· 467 467 rtw_write32(rtwdev, RTK_PCI_TXBD_RWPTR_CLR, 0xffffffff); 468 468 469 469 /* reset H2C Queue index in a single write */ 470 - if (rtw_chip_wcpu_11ac(rtwdev)) 470 + if (rtw_chip_wcpu_3081(rtwdev)) 471 471 rtw_write32_set(rtwdev, RTK_PCI_TXBD_H2CQ_CSR, 472 472 BIT_CLR_H2CQ_HOST_IDX | BIT_CLR_H2CQ_HW_IDX); 473 473 } ··· 487 487 488 488 rtw_write32(rtwdev, RTK_PCI_HIMR0, rtwpci->irq_mask[0] & ~imr0_unmask); 489 489 rtw_write32(rtwdev, RTK_PCI_HIMR1, rtwpci->irq_mask[1]); 490 - if (rtw_chip_wcpu_11ac(rtwdev)) 490 + if (rtw_chip_wcpu_3081(rtwdev)) 491 491 rtw_write32(rtwdev, RTK_PCI_HIMR3, rtwpci->irq_mask[3]); 492 492 493 493 rtwpci->irq_enabled = true; ··· 507 507 508 508 rtw_write32(rtwdev, RTK_PCI_HIMR0, 0); 509 509 rtw_write32(rtwdev, RTK_PCI_HIMR1, 0); 510 - if (rtw_chip_wcpu_11ac(rtwdev)) 510 + if (rtw_chip_wcpu_3081(rtwdev)) 511 511 rtw_write32(rtwdev, RTK_PCI_HIMR3, 0); 512 512 513 513 rtwpci->irq_enabled = false; ··· 1125 1125 1126 1126 irq_status[0] = rtw_read32(rtwdev, RTK_PCI_HISR0); 1127 1127 irq_status[1] = rtw_read32(rtwdev, RTK_PCI_HISR1); 1128 - if (rtw_chip_wcpu_11ac(rtwdev)) 1128 + if (rtw_chip_wcpu_3081(rtwdev)) 1129 1129 irq_status[3] = rtw_read32(rtwdev, RTK_PCI_HISR3); 1130 1130 else 1131 1131 irq_status[3] = 0; ··· 1134 1134 irq_status[3] &= rtwpci->irq_mask[3]; 1135 1135 rtw_write32(rtwdev, RTK_PCI_HISR0, irq_status[0]); 1136 1136 rtw_write32(rtwdev, RTK_PCI_HISR1, irq_status[1]); 1137 - if (rtw_chip_wcpu_11ac(rtwdev)) 1137 + if (rtw_chip_wcpu_3081(rtwdev)) 1138 1138 rtw_write32(rtwdev, RTK_PCI_HISR3, irq_status[3]); 1139 1139 1140 1140 spin_unlock_irqrestore(&rtwpci->hwirq_lock, flags); ··· 1706 1706 netif_napi_del(&rtwpci->napi); 1707 1707 free_netdev(rtwpci->netdev); 1708 1708 } 1709 + 1710 + static pci_ers_result_t rtw_pci_io_err_detected(struct pci_dev *pdev, 1711 + pci_channel_state_t state) 1712 + { 1713 + struct net_device *netdev = pci_get_drvdata(pdev); 1714 + 1715 + netif_device_detach(netdev); 1716 + 1717 + return PCI_ERS_RESULT_NEED_RESET; 1718 + } 1719 + 1720 + static pci_ers_result_t rtw_pci_io_slot_reset(struct pci_dev *pdev) 1721 + { 1722 + struct ieee80211_hw *hw = pci_get_drvdata(pdev); 1723 + struct rtw_dev *rtwdev = hw->priv; 1724 + 1725 + rtw_fw_recovery(rtwdev); 1726 + 1727 + return PCI_ERS_RESULT_RECOVERED; 1728 + } 1729 + 1730 + static void rtw_pci_io_resume(struct pci_dev *pdev) 1731 + { 1732 + struct net_device *netdev = pci_get_drvdata(pdev); 1733 + 1734 + /* ack any pending wake events, disable PME */ 1735 + pci_enable_wake(pdev, PCI_D0, 0); 1736 + 1737 + netif_device_attach(netdev); 1738 + } 1739 + 1740 + const struct pci_error_handlers rtw_pci_err_handler = { 1741 + .error_detected = rtw_pci_io_err_detected, 1742 + .slot_reset = rtw_pci_io_slot_reset, 1743 + .resume = rtw_pci_io_resume, 1744 + }; 1745 + EXPORT_SYMBOL(rtw_pci_err_handler); 1709 1746 1710 1747 int rtw_pci_probe(struct pci_dev *pdev, 1711 1748 const struct pci_device_id *id)
+1
drivers/net/wireless/realtek/rtw88/pci.h
··· 231 231 }; 232 232 233 233 extern const struct dev_pm_ops rtw_pm_ops; 234 + extern const struct pci_error_handlers rtw_pci_err_handler; 234 235 235 236 int rtw_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id); 236 237 void rtw_pci_remove(struct pci_dev *pdev);
+1 -1
drivers/net/wireless/realtek/rtw88/rtw8703b.c
··· 1882 1882 .id = RTW_CHIP_TYPE_8703B, 1883 1883 1884 1884 .fw_name = "rtw88/rtw8703b_fw.bin", 1885 - .wlan_cpu = RTW_WCPU_11N, 1885 + .wlan_cpu = RTW_WCPU_8051, 1886 1886 .tx_pkt_desc_sz = 40, 1887 1887 .tx_buf_desc_sz = 16, 1888 1888 .rx_pkt_desc_sz = 24,
+1 -1
drivers/net/wireless/realtek/rtw88/rtw8723d.c
··· 2116 2116 .ops = &rtw8723d_ops, 2117 2117 .id = RTW_CHIP_TYPE_8723D, 2118 2118 .fw_name = "rtw88/rtw8723d_fw.bin", 2119 - .wlan_cpu = RTW_WCPU_11N, 2119 + .wlan_cpu = RTW_WCPU_8051, 2120 2120 .tx_pkt_desc_sz = 40, 2121 2121 .tx_buf_desc_sz = 16, 2122 2122 .rx_pkt_desc_sz = 24,
+1
drivers/net/wireless/realtek/rtw88/rtw8723de.c
··· 23 23 .remove = rtw_pci_remove, 24 24 .driver.pm = &rtw_pm_ops, 25 25 .shutdown = rtw_pci_shutdown, 26 + .err_handler = &rtw_pci_err_handler, 26 27 }; 27 28 module_pci_driver(rtw_8723de_driver); 28 29
+1 -1
drivers/net/wireless/realtek/rtw88/rtw8812a.c
··· 1038 1038 .ops = &rtw8812a_ops, 1039 1039 .id = RTW_CHIP_TYPE_8812A, 1040 1040 .fw_name = "rtw88/rtw8812a_fw.bin", 1041 - .wlan_cpu = RTW_WCPU_11N, 1041 + .wlan_cpu = RTW_WCPU_8051, 1042 1042 .tx_pkt_desc_sz = 40, 1043 1043 .tx_buf_desc_sz = 16, 1044 1044 .rx_pkt_desc_sz = 24,
+1 -1
drivers/net/wireless/realtek/rtw88/rtw8814a.c
··· 2180 2180 .ops = &rtw8814a_ops, 2181 2181 .id = RTW_CHIP_TYPE_8814A, 2182 2182 .fw_name = "rtw88/rtw8814a_fw.bin", 2183 - .wlan_cpu = RTW_WCPU_11AC, 2183 + .wlan_cpu = RTW_WCPU_3081, 2184 2184 .tx_pkt_desc_sz = 40, 2185 2185 .tx_buf_desc_sz = 16, 2186 2186 .rx_pkt_desc_sz = 24,
+1 -1
drivers/net/wireless/realtek/rtw88/rtw8821a.c
··· 1138 1138 .ops = &rtw8821a_ops, 1139 1139 .id = RTW_CHIP_TYPE_8821A, 1140 1140 .fw_name = "rtw88/rtw8821a_fw.bin", 1141 - .wlan_cpu = RTW_WCPU_11N, 1141 + .wlan_cpu = RTW_WCPU_8051, 1142 1142 .tx_pkt_desc_sz = 40, 1143 1143 .tx_buf_desc_sz = 16, 1144 1144 .rx_pkt_desc_sz = 24,
+1 -1
drivers/net/wireless/realtek/rtw88/rtw8821c.c
··· 1973 1973 .ops = &rtw8821c_ops, 1974 1974 .id = RTW_CHIP_TYPE_8821C, 1975 1975 .fw_name = "rtw88/rtw8821c_fw.bin", 1976 - .wlan_cpu = RTW_WCPU_11AC, 1976 + .wlan_cpu = RTW_WCPU_3081, 1977 1977 .tx_pkt_desc_sz = 48, 1978 1978 .tx_buf_desc_sz = 16, 1979 1979 .rx_pkt_desc_sz = 24,
+1
drivers/net/wireless/realtek/rtw88/rtw8821ce.c
··· 27 27 .remove = rtw_pci_remove, 28 28 .driver.pm = &rtw_pm_ops, 29 29 .shutdown = rtw_pci_shutdown, 30 + .err_handler = &rtw_pci_err_handler, 30 31 }; 31 32 module_pci_driver(rtw_8821ce_driver); 32 33
+2 -1
drivers/net/wireless/realtek/rtw88/rtw8822b.c
··· 983 983 } 984 984 985 985 static int rtw8822b_set_antenna(struct rtw_dev *rtwdev, 986 + int radio_idx, 986 987 u32 antenna_tx, 987 988 u32 antenna_rx) 988 989 { ··· 2514 2513 .ops = &rtw8822b_ops, 2515 2514 .id = RTW_CHIP_TYPE_8822B, 2516 2515 .fw_name = "rtw88/rtw8822b_fw.bin", 2517 - .wlan_cpu = RTW_WCPU_11AC, 2516 + .wlan_cpu = RTW_WCPU_3081, 2518 2517 .tx_pkt_desc_sz = 48, 2519 2518 .tx_buf_desc_sz = 16, 2520 2519 .rx_pkt_desc_sz = 24,
+1
drivers/net/wireless/realtek/rtw88/rtw8822be.c
··· 23 23 .remove = rtw_pci_remove, 24 24 .driver.pm = &rtw_pm_ops, 25 25 .shutdown = rtw_pci_shutdown, 26 + .err_handler = &rtw_pci_err_handler, 26 27 }; 27 28 module_pci_driver(rtw_8822be_driver); 28 29
+2 -1
drivers/net/wireless/realtek/rtw88/rtw8822c.c
··· 2767 2767 } 2768 2768 2769 2769 static int rtw8822c_set_antenna(struct rtw_dev *rtwdev, 2770 + int radio_idx, 2770 2771 u32 antenna_tx, 2771 2772 u32 antenna_rx) 2772 2773 { ··· 5333 5332 .ops = &rtw8822c_ops, 5334 5333 .id = RTW_CHIP_TYPE_8822C, 5335 5334 .fw_name = "rtw88/rtw8822c_fw.bin", 5336 - .wlan_cpu = RTW_WCPU_11AC, 5335 + .wlan_cpu = RTW_WCPU_3081, 5337 5336 .tx_pkt_desc_sz = 48, 5338 5337 .tx_buf_desc_sz = 16, 5339 5338 .rx_pkt_desc_sz = 24,
+1
drivers/net/wireless/realtek/rtw88/rtw8822ce.c
··· 27 27 .remove = rtw_pci_remove, 28 28 .driver.pm = &rtw_pm_ops, 29 29 .shutdown = rtw_pci_shutdown, 30 + .err_handler = &rtw_pci_err_handler, 30 31 }; 31 32 module_pci_driver(rtw_8822ce_driver); 32 33
+4 -4
drivers/net/wireless/realtek/rtw88/sdio.c
··· 547 547 { 548 548 unsigned int pages_free, pages_needed; 549 549 550 - if (rtw_chip_wcpu_11n(rtwdev)) { 550 + if (rtw_chip_wcpu_8051(rtwdev)) { 551 551 u32 free_txpg; 552 552 553 553 free_txpg = rtw_sdio_read32(rtwdev, REG_SDIO_FREE_TXPG); ··· 1030 1030 u32 rx_len, hisr, total_rx_bytes = 0; 1031 1031 1032 1032 do { 1033 - if (rtw_chip_wcpu_11n(rtwdev)) 1033 + if (rtw_chip_wcpu_8051(rtwdev)) 1034 1034 rx_len = rtw_read16(rtwdev, REG_SDIO_RX0_REQ_LEN); 1035 1035 else 1036 1036 rx_len = rtw_read32(rtwdev, REG_SDIO_RX0_REQ_LEN); ··· 1042 1042 1043 1043 total_rx_bytes += rx_len; 1044 1044 1045 - if (rtw_chip_wcpu_11n(rtwdev)) { 1045 + if (rtw_chip_wcpu_8051(rtwdev)) { 1046 1046 /* Stop if no more RX requests are pending, even if 1047 1047 * rx_len could be greater than zero in the next 1048 1048 * iteration. This is needed because the RX buffer may ··· 1054 1054 */ 1055 1055 hisr = rtw_read32(rtwdev, REG_SDIO_HISR); 1056 1056 } else { 1057 - /* RTW_WCPU_11AC chips have improved hardware or 1057 + /* RTW_WCPU_3081 chips have improved hardware or 1058 1058 * firmware and can use rx_len unconditionally. 1059 1059 */ 1060 1060 hisr = REG_SDIO_HISR_RX_REQUEST;
+337 -10
drivers/net/wireless/realtek/rtw89/chan.c
··· 170 170 171 171 static void __rtw89_config_entity_chandef(struct rtw89_dev *rtwdev, 172 172 enum rtw89_chanctx_idx idx, 173 - const struct cfg80211_chan_def *chandef, 174 - bool from_stack) 173 + const struct cfg80211_chan_def *chandef) 175 174 { 176 175 struct rtw89_hal *hal = &rtwdev->hal; 177 176 178 177 hal->chanctx[idx].chandef = *chandef; 179 - 180 - if (from_stack) 181 - set_bit(idx, hal->entity_map); 182 178 } 183 179 184 180 void rtw89_config_entity_chandef(struct rtw89_dev *rtwdev, 185 181 enum rtw89_chanctx_idx idx, 186 182 const struct cfg80211_chan_def *chandef) 187 183 { 188 - __rtw89_config_entity_chandef(rtwdev, idx, chandef, true); 184 + struct rtw89_hal *hal = &rtwdev->hal; 185 + 186 + if (!chandef) { 187 + clear_bit(idx, hal->entity_map); 188 + return; 189 + } 190 + 191 + __rtw89_config_entity_chandef(rtwdev, idx, chandef); 192 + set_bit(idx, hal->entity_map); 189 193 } 190 194 191 195 void rtw89_config_roc_chandef(struct rtw89_dev *rtwdev, ··· 231 227 struct cfg80211_chan_def chandef = {0}; 232 228 233 229 rtw89_get_default_chandef(&chandef); 234 - __rtw89_config_entity_chandef(rtwdev, RTW89_CHANCTX_0, &chandef, false); 230 + __rtw89_config_entity_chandef(rtwdev, RTW89_CHANCTX_0, &chandef); 235 231 } 236 232 237 233 void rtw89_entity_init(struct rtw89_dev *rtwdev) ··· 268 264 const struct rtw89_chanctx_cfg *cfg; 269 265 struct rtw89_vif *rtwvif; 270 266 int idx; 267 + 268 + w->registered_chanctxs = bitmap_weight(hal->entity_map, NUM_OF_RTW89_CHANCTX); 271 269 272 270 for_each_set_bit(idx, hal->entity_map, NUM_OF_RTW89_CHANCTX) { 273 271 cfg = hal->chanctx[idx].cfg; ··· 479 473 bitmap_zero(recalc_map, NUM_OF_RTW89_CHANCTX); 480 474 fallthrough; 481 475 case 0: 482 - rtw89_config_default_chandef(rtwdev); 476 + if (!w.registered_chanctxs) 477 + rtw89_config_default_chandef(rtwdev); 483 478 set_bit(RTW89_CHANCTX_0, recalc_map); 484 479 fallthrough; 485 480 case 1: ··· 960 953 } 961 954 962 955 sel.bind_vif[i] = rtwvif_link; 956 + rtw89_p2p_disable_all_noa(rtwdev, rtwvif_link, NULL); 963 957 } 964 958 965 959 ret = rtw89_iterate_mcc_roles(rtwdev, rtw89_mcc_fill_role_iterator, &sel); ··· 1272 1264 bool small_bcn_ofst; 1273 1265 1274 1266 if (bcn_ofst < RTW89_MCC_MIN_RX_BCN_TIME) 1267 + small_bcn_ofst = true; 1268 + else if (bcn_ofst < aux->duration - aux->limit.max_toa) 1275 1269 small_bcn_ofst = true; 1276 1270 else if (mcc_intvl - bcn_ofst < RTW89_MCC_MIN_RX_BCN_TIME) 1277 1271 small_bcn_ofst = false; ··· 1605 1595 return false; 1606 1596 } 1607 1597 1598 + void rtw89_mcc_prepare_done_work(struct wiphy *wiphy, struct wiphy_work *work) 1599 + { 1600 + struct rtw89_dev *rtwdev = container_of(work, struct rtw89_dev, 1601 + mcc_prepare_done_work.work); 1602 + 1603 + lockdep_assert_wiphy(wiphy); 1604 + 1605 + ieee80211_wake_queues(rtwdev->hw); 1606 + } 1607 + 1608 + static void rtw89_mcc_prepare(struct rtw89_dev *rtwdev, bool start) 1609 + { 1610 + struct rtw89_mcc_info *mcc = &rtwdev->mcc; 1611 + struct rtw89_mcc_config *config = &mcc->config; 1612 + 1613 + if (start) { 1614 + ieee80211_stop_queues(rtwdev->hw); 1615 + 1616 + wiphy_delayed_work_queue(rtwdev->hw->wiphy, 1617 + &rtwdev->mcc_prepare_done_work, 1618 + usecs_to_jiffies(config->prepare_delay)); 1619 + } else { 1620 + wiphy_delayed_work_queue(rtwdev->hw->wiphy, 1621 + &rtwdev->mcc_prepare_done_work, 0); 1622 + wiphy_delayed_work_flush(rtwdev->hw->wiphy, 1623 + &rtwdev->mcc_prepare_done_work); 1624 + } 1625 + } 1626 + 1608 1627 static int rtw89_mcc_fill_start_tsf(struct rtw89_dev *rtwdev) 1609 1628 { 1610 1629 struct rtw89_mcc_info *mcc = &rtwdev->mcc; ··· 1669 1630 1670 1631 config->start_tsf = start_tsf; 1671 1632 config->start_tsf_in_aux_domain = tsf_aux + start_tsf - tsf; 1633 + config->prepare_delay = start_tsf - tsf; 1634 + 1672 1635 return 0; 1673 1636 } 1674 1637 ··· 2218 2177 rtw89_mcc_handle_beacon_noa(rtwdev, false); 2219 2178 } 2220 2179 2180 + static bool rtw89_mcc_ignore_bcn(struct rtw89_dev *rtwdev, struct rtw89_mcc_role *role) 2181 + { 2182 + enum rtw89_chip_gen chip_gen = rtwdev->chip->chip_gen; 2183 + 2184 + if (role->is_go) 2185 + return true; 2186 + else if (chip_gen == RTW89_CHIP_BE && role->is_gc) 2187 + return true; 2188 + else 2189 + return false; 2190 + } 2191 + 2221 2192 static int rtw89_mcc_start(struct rtw89_dev *rtwdev) 2222 2193 { 2223 2194 struct rtw89_mcc_info *mcc = &rtwdev->mcc; ··· 2253 2200 else 2254 2201 mcc->mode = RTW89_MCC_MODE_GC_STA; 2255 2202 2203 + if (rtw89_mcc_ignore_bcn(rtwdev, ref)) { 2204 + rtw89_fw_h2c_set_bcn_fltr_cfg(rtwdev, aux->rtwvif_link, false); 2205 + } else if (rtw89_mcc_ignore_bcn(rtwdev, aux)) { 2206 + rtw89_fw_h2c_set_bcn_fltr_cfg(rtwdev, ref->rtwvif_link, false); 2207 + } else { 2208 + rtw89_fw_h2c_set_bcn_fltr_cfg(rtwdev, ref->rtwvif_link, true); 2209 + rtw89_fw_h2c_set_bcn_fltr_cfg(rtwdev, aux->rtwvif_link, true); 2210 + } 2211 + 2256 2212 rtw89_debug(rtwdev, RTW89_DBG_CHAN, "MCC sel mode: %d\n", mcc->mode); 2257 2213 2258 2214 mcc->group = RTW89_MCC_DFLT_GROUP; ··· 2281 2219 rtw89_chanctx_notify(rtwdev, RTW89_CHANCTX_STATE_MCC_START); 2282 2220 2283 2221 rtw89_mcc_start_beacon_noa(rtwdev); 2222 + 2223 + rtw89_mcc_prepare(rtwdev, true); 2284 2224 return 0; 2285 2225 } 2286 2226 ··· 2371 2307 rtw89_chanctx_notify(rtwdev, RTW89_CHANCTX_STATE_MCC_STOP); 2372 2308 2373 2309 rtw89_mcc_stop_beacon_noa(rtwdev); 2310 + 2311 + rtw89_mcc_prepare(rtwdev, false); 2374 2312 } 2375 2313 2376 2314 static int rtw89_mcc_update(struct rtw89_dev *rtwdev) ··· 2428 2362 return 0; 2429 2363 } 2430 2364 2365 + static void rtw89_mcc_detect_connection(struct rtw89_dev *rtwdev, 2366 + struct rtw89_mcc_role *role) 2367 + { 2368 + struct ieee80211_vif *vif; 2369 + int ret; 2370 + 2371 + ret = rtw89_core_send_nullfunc(rtwdev, role->rtwvif_link, true, false, 2372 + RTW89_MCC_PROBE_TIMEOUT); 2373 + if (ret) 2374 + role->probe_count++; 2375 + else 2376 + role->probe_count = 0; 2377 + 2378 + if (role->probe_count < RTW89_MCC_PROBE_MAX_TRIES) 2379 + return; 2380 + 2381 + rtw89_debug(rtwdev, RTW89_DBG_CHAN, 2382 + "MCC <macid %d> can not detect AP\n", role->rtwvif_link->mac_id); 2383 + vif = rtwvif_link_to_vif(role->rtwvif_link); 2384 + ieee80211_connection_loss(vif); 2385 + } 2386 + 2431 2387 static void rtw89_mcc_track(struct rtw89_dev *rtwdev) 2432 2388 { 2433 2389 struct rtw89_mcc_info *mcc = &rtwdev->mcc; 2434 2390 struct rtw89_mcc_config *config = &mcc->config; 2435 2391 struct rtw89_mcc_pattern *pattern = &config->pattern; 2392 + struct rtw89_mcc_role *ref = &mcc->role_ref; 2393 + struct rtw89_mcc_role *aux = &mcc->role_aux; 2436 2394 u16 tolerance; 2437 2395 u16 bcn_ofst; 2438 2396 u16 diff; 2397 + 2398 + if (rtw89_mcc_ignore_bcn(rtwdev, ref)) 2399 + rtw89_mcc_detect_connection(rtwdev, aux); 2400 + else if (rtw89_mcc_ignore_bcn(rtwdev, aux)) 2401 + rtw89_mcc_detect_connection(rtwdev, ref); 2439 2402 2440 2403 if (mcc->mode != RTW89_MCC_MODE_GC_STA) 2441 2404 return; ··· 2714 2619 rtw89_queue_chanctx_change(rtwdev, RTW89_CHANCTX_CHANGE_DFLT); 2715 2620 } 2716 2621 2622 + static enum rtw89_mr_wtype __rtw89_query_mr_wtype(struct rtw89_dev *rtwdev) 2623 + { 2624 + struct rtw89_entity_mgnt *mgnt = &rtwdev->hal.entity_mgnt; 2625 + enum rtw89_chanctx_idx chanctx_idx; 2626 + struct ieee80211_vif *vif; 2627 + struct rtw89_vif *rtwvif; 2628 + unsigned int num_mld = 0; 2629 + unsigned int num_ml = 0; 2630 + unsigned int cnt = 0; 2631 + u8 role_idx; 2632 + u8 idx; 2633 + 2634 + for (role_idx = 0; role_idx < RTW89_MAX_INTERFACE_NUM; role_idx++) { 2635 + rtwvif = mgnt->active_roles[role_idx]; 2636 + if (!rtwvif) 2637 + continue; 2638 + 2639 + cnt++; 2640 + 2641 + vif = rtwvif_to_vif(rtwvif); 2642 + if (!ieee80211_vif_is_mld(vif)) 2643 + continue; 2644 + 2645 + num_mld++; 2646 + 2647 + for (idx = 0; idx < __RTW89_MLD_MAX_LINK_NUM; idx++) { 2648 + chanctx_idx = mgnt->chanctx_tbl[role_idx][idx]; 2649 + if (chanctx_idx != RTW89_CHANCTX_IDLE) 2650 + num_ml++; 2651 + } 2652 + } 2653 + 2654 + if (num_mld > 1) 2655 + goto err; 2656 + 2657 + switch (cnt) { 2658 + case 0: 2659 + return RTW89_MR_WTYPE_NONE; 2660 + case 1: 2661 + if (!num_mld) 2662 + return RTW89_MR_WTYPE_NONMLD; 2663 + switch (num_ml) { 2664 + case 1: 2665 + return RTW89_MR_WTYPE_MLD1L1R; 2666 + case 2: 2667 + return RTW89_MR_WTYPE_MLD2L1R; 2668 + default: 2669 + break; 2670 + } 2671 + break; 2672 + case 2: 2673 + if (!num_mld) 2674 + return RTW89_MR_WTYPE_NONMLD_NONMLD; 2675 + switch (num_ml) { 2676 + case 1: 2677 + return RTW89_MR_WTYPE_MLD1L1R_NONMLD; 2678 + case 2: 2679 + return RTW89_MR_WTYPE_MLD2L1R_NONMLD; 2680 + default: 2681 + break; 2682 + } 2683 + break; 2684 + default: 2685 + break; 2686 + } 2687 + 2688 + err: 2689 + rtw89_warn(rtwdev, "%s: unhandled cnt %u mld %u ml %u\n", __func__, 2690 + cnt, num_mld, num_ml); 2691 + return RTW89_MR_WTYPE_UNKNOWN; 2692 + } 2693 + 2694 + static enum rtw89_mr_wmode __rtw89_query_mr_wmode(struct rtw89_dev *rtwdev, 2695 + u8 inst_idx) 2696 + { 2697 + struct rtw89_entity_mgnt *mgnt = &rtwdev->hal.entity_mgnt; 2698 + unsigned int num[NUM_NL80211_IFTYPES] = {}; 2699 + enum rtw89_chanctx_idx chanctx_idx; 2700 + struct ieee80211_vif *vif; 2701 + struct rtw89_vif *rtwvif; 2702 + unsigned int cnt = 0; 2703 + u8 role_idx; 2704 + 2705 + if (unlikely(inst_idx >= __RTW89_MLD_MAX_LINK_NUM)) 2706 + return RTW89_MR_WMODE_UNKNOWN; 2707 + 2708 + for (role_idx = 0; role_idx < RTW89_MAX_INTERFACE_NUM; role_idx++) { 2709 + chanctx_idx = mgnt->chanctx_tbl[role_idx][inst_idx]; 2710 + if (chanctx_idx == RTW89_CHANCTX_IDLE) 2711 + continue; 2712 + 2713 + rtwvif = mgnt->active_roles[role_idx]; 2714 + if (unlikely(!rtwvif)) 2715 + continue; 2716 + 2717 + vif = rtwvif_to_vif(rtwvif); 2718 + num[vif->type]++; 2719 + cnt++; 2720 + } 2721 + 2722 + switch (cnt) { 2723 + case 0: 2724 + return RTW89_MR_WMODE_NONE; 2725 + case 1: 2726 + if (num[NL80211_IFTYPE_STATION]) 2727 + return RTW89_MR_WMODE_1CLIENT; 2728 + if (num[NL80211_IFTYPE_AP]) 2729 + return RTW89_MR_WMODE_1AP; 2730 + break; 2731 + case 2: 2732 + if (num[NL80211_IFTYPE_STATION] == 2) 2733 + return RTW89_MR_WMODE_2CLIENTS; 2734 + if (num[NL80211_IFTYPE_AP] == 2) 2735 + return RTW89_MR_WMODE_2APS; 2736 + if (num[NL80211_IFTYPE_STATION] && num[NL80211_IFTYPE_AP]) 2737 + return RTW89_MR_WMODE_1AP_1CLIENT; 2738 + break; 2739 + default: 2740 + break; 2741 + } 2742 + 2743 + rtw89_warn(rtwdev, "%s: unhandled cnt %u\n", __func__, cnt); 2744 + return RTW89_MR_WMODE_UNKNOWN; 2745 + } 2746 + 2747 + static enum rtw89_mr_ctxtype __rtw89_query_mr_ctxtype(struct rtw89_dev *rtwdev, 2748 + u8 inst_idx) 2749 + { 2750 + struct rtw89_entity_mgnt *mgnt = &rtwdev->hal.entity_mgnt; 2751 + DECLARE_BITMAP(map, NUM_OF_RTW89_CHANCTX) = {}; 2752 + unsigned int num[RTW89_BAND_NUM] = {}; 2753 + enum rtw89_chanctx_idx chanctx_idx; 2754 + const struct rtw89_chan *chan; 2755 + unsigned int cnt = 0; 2756 + u8 role_idx; 2757 + 2758 + if (unlikely(inst_idx >= __RTW89_MLD_MAX_LINK_NUM)) 2759 + return RTW89_MR_CTX_UNKNOWN; 2760 + 2761 + for (role_idx = 0; role_idx < RTW89_MAX_INTERFACE_NUM; role_idx++) { 2762 + chanctx_idx = mgnt->chanctx_tbl[role_idx][inst_idx]; 2763 + if (chanctx_idx == RTW89_CHANCTX_IDLE) 2764 + continue; 2765 + 2766 + if (__test_and_set_bit(chanctx_idx, map)) 2767 + continue; 2768 + 2769 + chan = rtw89_chan_get(rtwdev, chanctx_idx); 2770 + num[chan->band_type]++; 2771 + cnt++; 2772 + } 2773 + 2774 + switch (cnt) { 2775 + case 0: 2776 + return RTW89_MR_CTX_NONE; 2777 + case 1: 2778 + if (num[RTW89_BAND_2G]) 2779 + return RTW89_MR_CTX1_2GHZ; 2780 + if (num[RTW89_BAND_5G]) 2781 + return RTW89_MR_CTX1_5GHZ; 2782 + if (num[RTW89_BAND_6G]) 2783 + return RTW89_MR_CTX1_6GHZ; 2784 + break; 2785 + case 2: 2786 + if (num[RTW89_BAND_2G] == 2) 2787 + return RTW89_MR_CTX2_2GHZ; 2788 + if (num[RTW89_BAND_5G] == 2) 2789 + return RTW89_MR_CTX2_5GHZ; 2790 + if (num[RTW89_BAND_6G] == 2) 2791 + return RTW89_MR_CTX2_6GHZ; 2792 + if (num[RTW89_BAND_2G] && num[RTW89_BAND_5G]) 2793 + return RTW89_MR_CTX2_2GHZ_5GHZ; 2794 + if (num[RTW89_BAND_2G] && num[RTW89_BAND_6G]) 2795 + return RTW89_MR_CTX2_2GHZ_6GHZ; 2796 + if (num[RTW89_BAND_5G] && num[RTW89_BAND_6G]) 2797 + return RTW89_MR_CTX2_5GHZ_6GHZ; 2798 + break; 2799 + default: 2800 + break; 2801 + } 2802 + 2803 + rtw89_warn(rtwdev, "%s: unhandled cnt %u\n", __func__, cnt); 2804 + return RTW89_MR_CTX_UNKNOWN; 2805 + } 2806 + 2807 + void rtw89_query_mr_chanctx_info(struct rtw89_dev *rtwdev, u8 inst_idx, 2808 + struct rtw89_mr_chanctx_info *info) 2809 + { 2810 + lockdep_assert_wiphy(rtwdev->hw->wiphy); 2811 + 2812 + info->wtype = __rtw89_query_mr_wtype(rtwdev); 2813 + info->wmode = __rtw89_query_mr_wmode(rtwdev, inst_idx); 2814 + info->ctxtype = __rtw89_query_mr_ctxtype(rtwdev, inst_idx); 2815 + } 2816 + 2717 2817 void rtw89_chanctx_track(struct rtw89_dev *rtwdev) 2718 2818 { 2719 2819 struct rtw89_hal *hal = &rtwdev->hal; ··· 3072 2782 void rtw89_chanctx_ops_remove(struct rtw89_dev *rtwdev, 3073 2783 struct ieee80211_chanctx_conf *ctx) 3074 2784 { 3075 - struct rtw89_hal *hal = &rtwdev->hal; 3076 2785 struct rtw89_chanctx_cfg *cfg = (struct rtw89_chanctx_cfg *)ctx->drv_priv; 3077 2786 3078 - clear_bit(cfg->idx, hal->entity_map); 2787 + rtw89_config_entity_chandef(rtwdev, cfg->idx, NULL); 3079 2788 } 3080 2789 3081 2790 void rtw89_chanctx_ops_change(struct rtw89_dev *rtwdev, ··· 3104 2815 rtwvif_link->chanctx_idx = cfg->idx; 3105 2816 rtwvif_link->chanctx_assigned = true; 3106 2817 cfg->ref_count++; 2818 + 2819 + if (rtwdev->scanning) 2820 + rtw89_hw_scan_abort(rtwdev, rtwdev->scan_info.scanning_vif); 3107 2821 3108 2822 if (list_empty(&rtwvif->mgnt_entry)) 3109 2823 list_add_tail(&rtwvif->mgnt_entry, &mgnt->active_list); ··· 3146 2854 rtwvif_link->chanctx_idx = RTW89_CHANCTX_0; 3147 2855 rtwvif_link->chanctx_assigned = false; 3148 2856 cfg->ref_count--; 2857 + 2858 + if (rtwdev->scanning) 2859 + rtw89_hw_scan_abort(rtwdev, rtwdev->scan_info.scanning_vif); 3149 2860 3150 2861 if (!rtw89_vif_is_active_role(rtwvif)) 3151 2862 list_del_init(&rtwvif->mgnt_entry); ··· 3200 2905 default: 3201 2906 break; 3202 2907 } 2908 + } 2909 + 2910 + int rtw89_chanctx_ops_reassign_vif(struct rtw89_dev *rtwdev, 2911 + struct rtw89_vif_link *rtwvif_link, 2912 + struct ieee80211_chanctx_conf *old_ctx, 2913 + struct ieee80211_chanctx_conf *new_ctx, 2914 + bool replace) 2915 + { 2916 + int ret; 2917 + 2918 + rtw89_chanctx_ops_unassign_vif(rtwdev, rtwvif_link, old_ctx); 2919 + 2920 + if (!replace) 2921 + goto assign; 2922 + 2923 + rtw89_chanctx_ops_remove(rtwdev, old_ctx); 2924 + ret = rtw89_chanctx_ops_add(rtwdev, new_ctx); 2925 + if (ret) { 2926 + rtw89_err(rtwdev, "%s: failed to add chanctx: %d\n", 2927 + __func__, ret); 2928 + return ret; 2929 + } 2930 + 2931 + assign: 2932 + ret = rtw89_chanctx_ops_assign_vif(rtwdev, rtwvif_link, new_ctx); 2933 + if (ret) { 2934 + rtw89_err(rtwdev, "%s: failed to assign chanctx: %d\n", 2935 + __func__, ret); 2936 + return ret; 2937 + } 2938 + 2939 + return 0; 3203 2940 }
+57 -1
drivers/net/wireless/realtek/rtw89/chan.h
··· 19 19 #define RTW89_MCC_MIN_RX_BCN_TIME 10 20 20 #define RTW89_MCC_DFLT_BCN_OFST_TIME 40 21 21 22 + #define RTW89_MCC_PROBE_TIMEOUT 100 23 + #define RTW89_MCC_PROBE_MAX_TRIES 3 24 + 22 25 #define RTW89_MCC_MIN_GO_DURATION \ 23 26 (RTW89_MCC_EARLY_TX_BCN_TIME + RTW89_MCC_MIN_RX_BCN_TIME) 24 27 ··· 31 28 #define RTW89_MCC_DFLT_GROUP 0 32 29 #define RTW89_MCC_NEXT_GROUP(cur) (((cur) + 1) % 4) 33 30 34 - #define RTW89_MCC_DFLT_TX_NULL_EARLY 3 31 + #define RTW89_MCC_DFLT_TX_NULL_EARLY 7 35 32 #define RTW89_MCC_DFLT_COURTESY_SLOT 3 36 33 37 34 #define RTW89_MCC_REQ_COURTESY_TIME 5 ··· 43 40 }) 44 41 45 42 #define NUM_OF_RTW89_MCC_ROLES 2 43 + 44 + enum rtw89_mr_wtype { 45 + RTW89_MR_WTYPE_NONE, 46 + RTW89_MR_WTYPE_NONMLD, 47 + RTW89_MR_WTYPE_MLD1L1R, 48 + RTW89_MR_WTYPE_MLD2L1R, 49 + RTW89_MR_WTYPE_MLD2L2R, 50 + RTW89_MR_WTYPE_NONMLD_NONMLD, 51 + RTW89_MR_WTYPE_MLD1L1R_NONMLD, 52 + RTW89_MR_WTYPE_MLD2L1R_NONMLD, 53 + RTW89_MR_WTYPE_MLD2L2R_NONMLD, 54 + RTW89_MR_WTYPE_UNKNOWN, 55 + }; 56 + 57 + enum rtw89_mr_wmode { 58 + RTW89_MR_WMODE_NONE, 59 + RTW89_MR_WMODE_1CLIENT, 60 + RTW89_MR_WMODE_1AP, 61 + RTW89_MR_WMODE_1AP_1CLIENT, 62 + RTW89_MR_WMODE_2CLIENTS, 63 + RTW89_MR_WMODE_2APS, 64 + RTW89_MR_WMODE_UNKNOWN, 65 + }; 66 + 67 + enum rtw89_mr_ctxtype { 68 + RTW89_MR_CTX_NONE, 69 + RTW89_MR_CTX1_2GHZ, 70 + RTW89_MR_CTX1_5GHZ, 71 + RTW89_MR_CTX1_6GHZ, 72 + RTW89_MR_CTX2_2GHZ, 73 + RTW89_MR_CTX2_5GHZ, 74 + RTW89_MR_CTX2_6GHZ, 75 + RTW89_MR_CTX2_2GHZ_5GHZ, 76 + RTW89_MR_CTX2_2GHZ_6GHZ, 77 + RTW89_MR_CTX2_5GHZ_6GHZ, 78 + RTW89_MR_CTX_UNKNOWN, 79 + }; 80 + 81 + struct rtw89_mr_chanctx_info { 82 + enum rtw89_mr_wtype wtype; 83 + enum rtw89_mr_wmode wmode; 84 + enum rtw89_mr_ctxtype ctxtype; 85 + }; 46 86 47 87 enum rtw89_chanctx_pause_reasons { 48 88 RTW89_CHANCTX_PAUSE_REASON_HW_SCAN, ··· 104 58 }; 105 59 106 60 struct rtw89_entity_weight { 61 + unsigned int registered_chanctxs; 107 62 unsigned int active_chanctxs; 108 63 unsigned int active_roles; 109 64 }; ··· 163 116 void rtw89_queue_chanctx_work(struct rtw89_dev *rtwdev); 164 117 void rtw89_queue_chanctx_change(struct rtw89_dev *rtwdev, 165 118 enum rtw89_chanctx_changes change); 119 + void rtw89_query_mr_chanctx_info(struct rtw89_dev *rtwdev, u8 inst_idx, 120 + struct rtw89_mr_chanctx_info *info); 166 121 void rtw89_chanctx_track(struct rtw89_dev *rtwdev); 167 122 void rtw89_chanctx_pause(struct rtw89_dev *rtwdev, 168 123 const struct rtw89_chanctx_pause_parm *parm); ··· 177 128 178 129 #define rtw89_mgnt_chan_get(rtwdev, link_index) \ 179 130 __rtw89_mgnt_chan_get(rtwdev, __func__, link_index) 131 + 132 + void rtw89_mcc_prepare_done_work(struct wiphy *wiphy, struct wiphy_work *work); 180 133 181 134 int rtw89_chanctx_ops_add(struct rtw89_dev *rtwdev, 182 135 struct ieee80211_chanctx_conf *ctx); ··· 193 142 void rtw89_chanctx_ops_unassign_vif(struct rtw89_dev *rtwdev, 194 143 struct rtw89_vif_link *rtwvif_link, 195 144 struct ieee80211_chanctx_conf *ctx); 145 + int rtw89_chanctx_ops_reassign_vif(struct rtw89_dev *rtwdev, 146 + struct rtw89_vif_link *rtwvif_link, 147 + struct ieee80211_chanctx_conf *old_ctx, 148 + struct ieee80211_chanctx_conf *new_ctx, 149 + bool replace); 196 150 197 151 #endif
+982 -327
drivers/net/wireless/realtek/rtw89/coex.c
··· 2 2 /* Copyright(c) 2019-2020 Realtek Corporation 3 3 */ 4 4 5 + #include "chan.h" 5 6 #include "coex.h" 6 7 #include "debug.h" 7 8 #include "fw.h" ··· 11 10 #include "ps.h" 12 11 #include "reg.h" 13 12 14 - #define RTW89_COEX_VERSION 0x07000413 13 + #define RTW89_COEX_VERSION 0x09000013 15 14 #define FCXDEF_STEP 50 /* MUST <= FCXMAX_STEP and match with wl fw*/ 16 15 #define BTC_E2G_LIMIT_DEF 80 17 16 ··· 139 138 .fcxbtver = 7, .fcxbtscan = 7, .fcxbtafh = 7, .fcxbtdevinfo = 7, 140 139 .fwlrole = 7, .frptmap = 3, .fcxctrl = 7, .fcxinit = 7, 141 140 .fwevntrptl = 1, .fwc2hfunc = 2, .drvinfo_type = 1, .info_buf = 1800, 142 - .max_role_num = 6, 141 + .max_role_num = 6, .fcxosi = 0, .fcxmlo = 0, .bt_desired = 8, 143 142 }, 144 143 {RTL8852BT, RTW89_FW_VER_CODE(0, 29, 90, 0), 145 144 .fcxbtcrpt = 7, .fcxtdma = 7, .fcxslots = 7, .fcxcysta = 7, ··· 147 146 .fcxbtver = 7, .fcxbtscan = 7, .fcxbtafh = 7, .fcxbtdevinfo = 7, 148 147 .fwlrole = 7, .frptmap = 3, .fcxctrl = 7, .fcxinit = 7, 149 148 .fwevntrptl = 1, .fwc2hfunc = 2, .drvinfo_type = 1, .info_buf = 1800, 150 - .max_role_num = 6, 149 + .max_role_num = 6, .fcxosi = 0, .fcxmlo = 0, .bt_desired = 8, 150 + }, 151 + {RTL8922A, RTW89_FW_VER_CODE(0, 35, 71, 0), 152 + .fcxbtcrpt = 8, .fcxtdma = 7, .fcxslots = 7, .fcxcysta = 7, 153 + .fcxstep = 7, .fcxnullsta = 7, .fcxmreg = 7, .fcxgpiodbg = 7, 154 + .fcxbtver = 7, .fcxbtscan = 7, .fcxbtafh = 7, .fcxbtdevinfo = 7, 155 + .fwlrole = 8, .frptmap = 4, .fcxctrl = 7, .fcxinit = 7, 156 + .fwevntrptl = 1, .fwc2hfunc = 3, .drvinfo_type = 2, .info_buf = 1800, 157 + .max_role_num = 6, .fcxosi = 1, .fcxmlo = 1, .bt_desired = 9, 158 + }, 159 + {RTL8922A, RTW89_FW_VER_CODE(0, 35, 63, 0), 160 + .fcxbtcrpt = 8, .fcxtdma = 7, .fcxslots = 7, .fcxcysta = 7, 161 + .fcxstep = 7, .fcxnullsta = 7, .fcxmreg = 7, .fcxgpiodbg = 7, 162 + .fcxbtver = 7, .fcxbtscan = 7, .fcxbtafh = 7, .fcxbtdevinfo = 7, 163 + .fwlrole = 8, .frptmap = 4, .fcxctrl = 7, .fcxinit = 7, 164 + .fwevntrptl = 1, .fwc2hfunc = 3, .drvinfo_type = 2, .info_buf = 1800, 165 + .max_role_num = 6, .fcxosi = 1, .fcxmlo = 1, .bt_desired = 9, 151 166 }, 152 167 {RTL8922A, RTW89_FW_VER_CODE(0, 35, 8, 0), 153 168 .fcxbtcrpt = 8, .fcxtdma = 7, .fcxslots = 7, .fcxcysta = 7, ··· 171 154 .fcxbtver = 7, .fcxbtscan = 7, .fcxbtafh = 7, .fcxbtdevinfo = 7, 172 155 .fwlrole = 8, .frptmap = 3, .fcxctrl = 7, .fcxinit = 7, 173 156 .fwevntrptl = 1, .fwc2hfunc = 1, .drvinfo_type = 1, .info_buf = 1800, 174 - .max_role_num = 6, 157 + .max_role_num = 6, .fcxosi = 0, .fcxmlo = 0, .bt_desired = 7, 175 158 }, 176 159 {RTL8851B, RTW89_FW_VER_CODE(0, 29, 29, 0), 177 160 .fcxbtcrpt = 105, .fcxtdma = 3, .fcxslots = 1, .fcxcysta = 5, ··· 179 162 .fcxbtver = 1, .fcxbtscan = 2, .fcxbtafh = 2, .fcxbtdevinfo = 1, 180 163 .fwlrole = 2, .frptmap = 3, .fcxctrl = 1, .fcxinit = 0, 181 164 .fwevntrptl = 0, .fwc2hfunc = 1, .drvinfo_type = 0, .info_buf = 1800, 182 - .max_role_num = 6, 165 + .max_role_num = 6, .fcxosi = 0, .fcxmlo = 0, .bt_desired = 7, 183 166 }, 184 167 {RTL8852C, RTW89_FW_VER_CODE(0, 27, 57, 0), 185 168 .fcxbtcrpt = 4, .fcxtdma = 3, .fcxslots = 1, .fcxcysta = 3, ··· 187 170 .fcxbtver = 1, .fcxbtscan = 1, .fcxbtafh = 2, .fcxbtdevinfo = 1, 188 171 .fwlrole = 1, .frptmap = 3, .fcxctrl = 1, .fcxinit = 0, 189 172 .fwevntrptl = 0, .fwc2hfunc = 1, .drvinfo_type = 0, .info_buf = 1280, 190 - .max_role_num = 5, 173 + .max_role_num = 5, .fcxosi = 0, .fcxmlo = 0, .bt_desired = 7, 191 174 }, 192 175 {RTL8852C, RTW89_FW_VER_CODE(0, 27, 42, 0), 193 176 .fcxbtcrpt = 4, .fcxtdma = 3, .fcxslots = 1, .fcxcysta = 3, ··· 195 178 .fcxbtver = 1, .fcxbtscan = 1, .fcxbtafh = 2, .fcxbtdevinfo = 1, 196 179 .fwlrole = 1, .frptmap = 2, .fcxctrl = 1, .fcxinit = 0, 197 180 .fwevntrptl = 0, .fwc2hfunc = 1, .drvinfo_type = 0, .info_buf = 1280, 198 - .max_role_num = 5, 181 + .max_role_num = 5, .fcxosi = 0, .fcxmlo = 0, .bt_desired = 7, 199 182 }, 200 183 {RTL8852C, RTW89_FW_VER_CODE(0, 27, 0, 0), 201 184 .fcxbtcrpt = 4, .fcxtdma = 3, .fcxslots = 1, .fcxcysta = 3, ··· 203 186 .fcxbtver = 1, .fcxbtscan = 1, .fcxbtafh = 1, .fcxbtdevinfo = 1, 204 187 .fwlrole = 1, .frptmap = 2, .fcxctrl = 1, .fcxinit = 0, 205 188 .fwevntrptl = 0, .fwc2hfunc = 1, .drvinfo_type = 0, .info_buf = 1280, 206 - .max_role_num = 5, 189 + .max_role_num = 5, .fcxosi = 0, .fcxmlo = 0, .bt_desired = 7, 190 + }, 191 + {RTL8852B, RTW89_FW_VER_CODE(0, 29, 122, 0), 192 + .fcxbtcrpt = 8, .fcxtdma = 7, .fcxslots = 7, .fcxcysta = 7, 193 + .fcxstep = 7, .fcxnullsta = 7, .fcxmreg = 7, .fcxgpiodbg = 7, 194 + .fcxbtver = 7, .fcxbtscan = 7, .fcxbtafh = 7, .fcxbtdevinfo = 7, 195 + .fwlrole = 7, .frptmap = 3, .fcxctrl = 7, .fcxinit = 7, 196 + .fwevntrptl = 1, .fwc2hfunc = 2, .drvinfo_type = 1, .info_buf = 1800, 197 + .max_role_num = 6, .fcxosi = 0, .fcxmlo = 0, .bt_desired = 8, 207 198 }, 208 199 {RTL8852B, RTW89_FW_VER_CODE(0, 29, 29, 0), 209 200 .fcxbtcrpt = 105, .fcxtdma = 3, .fcxslots = 1, .fcxcysta = 5, ··· 219 194 .fcxbtver = 1, .fcxbtscan = 2, .fcxbtafh = 2, .fcxbtdevinfo = 1, 220 195 .fwlrole = 2, .frptmap = 3, .fcxctrl = 1, .fcxinit = 0, 221 196 .fwevntrptl = 0, .fwc2hfunc = 1, .drvinfo_type = 0, .info_buf = 1800, 222 - .max_role_num = 6, 197 + .max_role_num = 6, .fcxosi = 0, .fcxmlo = 0, .bt_desired = 7, 223 198 }, 224 199 {RTL8852B, RTW89_FW_VER_CODE(0, 29, 14, 0), 225 200 .fcxbtcrpt = 5, .fcxtdma = 3, .fcxslots = 1, .fcxcysta = 4, ··· 227 202 .fcxbtver = 1, .fcxbtscan = 1, .fcxbtafh = 2, .fcxbtdevinfo = 1, 228 203 .fwlrole = 1, .frptmap = 3, .fcxctrl = 1, .fcxinit = 0, 229 204 .fwevntrptl = 0, .fwc2hfunc = 1, .drvinfo_type = 0, .info_buf = 1800, 230 - .max_role_num = 6, 205 + .max_role_num = 6, .fcxosi = 0, .fcxmlo = 0, .bt_desired = 7, 231 206 }, 232 207 {RTL8852B, RTW89_FW_VER_CODE(0, 27, 0, 0), 233 208 .fcxbtcrpt = 4, .fcxtdma = 3, .fcxslots = 1, .fcxcysta = 3, ··· 235 210 .fcxbtver = 1, .fcxbtscan = 1, .fcxbtafh = 1, .fcxbtdevinfo = 1, 236 211 .fwlrole = 1, .frptmap = 1, .fcxctrl = 1, .fcxinit = 0, 237 212 .fwevntrptl = 0, .fwc2hfunc = 1, .drvinfo_type = 0, .info_buf = 1280, 238 - .max_role_num = 5, 213 + .max_role_num = 5, .fcxosi = 0, .fcxmlo = 0, .bt_desired = 7, 239 214 }, 240 215 {RTL8852A, RTW89_FW_VER_CODE(0, 13, 37, 0), 241 216 .fcxbtcrpt = 4, .fcxtdma = 3, .fcxslots = 1, .fcxcysta = 3, ··· 243 218 .fcxbtver = 1, .fcxbtscan = 1, .fcxbtafh = 2, .fcxbtdevinfo = 1, 244 219 .fwlrole = 1, .frptmap = 3, .fcxctrl = 1, .fcxinit = 0, 245 220 .fwevntrptl = 0, .fwc2hfunc = 0, .drvinfo_type = 0, .info_buf = 1280, 246 - .max_role_num = 5, 221 + .max_role_num = 5, .fcxosi = 0, .fcxmlo = 0, .bt_desired = 7, 247 222 }, 248 223 {RTL8852A, RTW89_FW_VER_CODE(0, 13, 0, 0), 249 224 .fcxbtcrpt = 1, .fcxtdma = 1, .fcxslots = 1, .fcxcysta = 2, ··· 251 226 .fcxbtver = 1, .fcxbtscan = 1, .fcxbtafh = 1, .fcxbtdevinfo = 1, 252 227 .fwlrole = 0, .frptmap = 0, .fcxctrl = 0, .fcxinit = 0, 253 228 .fwevntrptl = 0, .fwc2hfunc = 0, .drvinfo_type = 0, .info_buf = 1024, 254 - .max_role_num = 5, 229 + .max_role_num = 5, .fcxosi = 0, .fcxmlo = 0, .bt_desired = 7, 255 230 }, 256 231 257 232 /* keep it to be the last as default entry */ ··· 261 236 .fcxbtver = 1, .fcxbtscan = 1, .fcxbtafh = 1, .fcxbtdevinfo = 1, 262 237 .fwlrole = 0, .frptmap = 0, .fcxctrl = 0, .fcxinit = 0, 263 238 .fwevntrptl = 0, .fwc2hfunc = 1, .drvinfo_type = 0, .info_buf = 1024, 264 - .max_role_num = 5, 239 + .max_role_num = 5, .fcxosi = 0, .fcxmlo = 0, .bt_desired = 7, 265 240 }, 266 241 }; 267 242 ··· 294 269 } 295 270 } 296 271 272 + #define CASE_BTC_MLME_STATE(e) case MLME_##e: return #e 273 + 274 + static const char *id_to_mlme_state(u32 id) 275 + { 276 + switch (id) { 277 + CASE_BTC_MLME_STATE(NO_LINK); 278 + CASE_BTC_MLME_STATE(LINKING); 279 + CASE_BTC_MLME_STATE(LINKED); 280 + default: 281 + return "unknown"; 282 + } 283 + } 284 + 285 + static char *chip_id_str(u32 id) 286 + { 287 + switch (id) { 288 + case RTL8852A: 289 + return "RTL8852A"; 290 + case RTL8852B: 291 + return "RTL8852B"; 292 + case RTL8852C: 293 + return "RTL8852C"; 294 + case RTL8852BT: 295 + return "RTL8852BT"; 296 + case RTL8851B: 297 + return "RTL8851B"; 298 + case RTL8922A: 299 + return "RTL8922A"; 300 + default: 301 + return "UNKNOWN"; 302 + } 303 + } 304 + 297 305 struct rtw89_btc_btf_tlv { 298 306 u8 type; 299 307 u8 len; ··· 349 291 RPT_EN_BT_DEVICE_INFO, 350 292 RPT_EN_BT_AFH_MAP, 351 293 RPT_EN_BT_AFH_MAP_LE, 294 + RPT_EN_BT_TX_PWR_LVL, 352 295 RPT_EN_FW_STEP_INFO, 353 296 RPT_EN_TEST, 354 297 RPT_EN_WL_ALL, ··· 727 668 BTC_WLINK_MAX 728 669 }; 729 670 671 + #define CASE_BTC_WL_LINK_MODE(e) case BTC_WLINK_## e: return #e 672 + 673 + static const char *id_to_linkmode(u8 id) 674 + { 675 + switch (id) { 676 + CASE_BTC_WL_LINK_MODE(NOLINK); 677 + CASE_BTC_WL_LINK_MODE(2G_STA); 678 + CASE_BTC_WL_LINK_MODE(2G_AP); 679 + CASE_BTC_WL_LINK_MODE(2G_GO); 680 + CASE_BTC_WL_LINK_MODE(2G_GC); 681 + CASE_BTC_WL_LINK_MODE(2G_SCC); 682 + CASE_BTC_WL_LINK_MODE(2G_MCC); 683 + CASE_BTC_WL_LINK_MODE(25G_MCC); 684 + CASE_BTC_WL_LINK_MODE(25G_DBCC); 685 + CASE_BTC_WL_LINK_MODE(5G); 686 + CASE_BTC_WL_LINK_MODE(OTHER); 687 + default: 688 + return "unknown"; 689 + } 690 + } 691 + 730 692 enum btc_wl_mrole_type { 731 693 BTC_WLMROLE_NONE = 0x0, 732 694 BTC_WLMROLE_STA_GC, ··· 913 833 return ret; 914 834 } 915 835 836 + #define BTC_BT_DEF_BR_TX_PWR 4 837 + #define BTC_BT_DEF_LE_TX_PWR 4 838 + 916 839 static void _reset_btc_var(struct rtw89_dev *rtwdev, u8 type) 917 840 { 918 841 struct rtw89_btc *btc = &rtwdev->btc; ··· 984 901 985 902 if (type & BTC_RESET_MDINFO) 986 903 memset(&btc->mdinfo, 0, sizeof(btc->mdinfo)); 904 + 905 + bt->link_info.bt_txpwr_desc.br_dbm = BTC_BT_DEF_BR_TX_PWR; 906 + bt->link_info.bt_txpwr_desc.le_dbm = BTC_BT_DEF_LE_TX_PWR; 987 907 } 988 908 989 909 static u8 _search_reg_index(struct rtw89_dev *rtwdev, u8 mreg_num, u16 reg_type, u32 target) ··· 1410 1324 u8 *prptbuf, u32 index) 1411 1325 { 1412 1326 struct rtw89_btc *btc = &rtwdev->btc; 1327 + struct rtw89_btc_ver *fwsubver = &btc->fwinfo.fw_subver; 1413 1328 const struct rtw89_btc_ver *ver = btc->ver; 1414 1329 struct rtw89_btc_dm *dm = &btc->dm; 1415 1330 struct rtw89_btc_rpt_cmn_info *pcinfo = NULL; ··· 1453 1366 if (ver->fcxbtcrpt == 1) { 1454 1367 pfinfo = &pfwinfo->rpt_ctrl.finfo.v1; 1455 1368 pcinfo->req_len = sizeof(pfwinfo->rpt_ctrl.finfo.v1); 1369 + fwsubver->fcxbtcrpt = pfwinfo->rpt_ctrl.finfo.v1.fver; 1456 1370 } else if (ver->fcxbtcrpt == 4) { 1457 1371 pfinfo = &pfwinfo->rpt_ctrl.finfo.v4; 1458 1372 pcinfo->req_len = sizeof(pfwinfo->rpt_ctrl.finfo.v4); 1373 + fwsubver->fcxbtcrpt = pfwinfo->rpt_ctrl.finfo.v4.fver; 1459 1374 } else if (ver->fcxbtcrpt == 5) { 1460 1375 pfinfo = &pfwinfo->rpt_ctrl.finfo.v5; 1461 1376 pcinfo->req_len = sizeof(pfwinfo->rpt_ctrl.finfo.v5); 1377 + fwsubver->fcxbtcrpt = pfwinfo->rpt_ctrl.finfo.v5.fver; 1462 1378 } else if (ver->fcxbtcrpt == 105) { 1463 1379 pfinfo = &pfwinfo->rpt_ctrl.finfo.v105; 1464 1380 pcinfo->req_len = sizeof(pfwinfo->rpt_ctrl.finfo.v105); 1381 + fwsubver->fcxbtcrpt = pfwinfo->rpt_ctrl.finfo.v105.fver; 1465 1382 pcinfo->req_fver = 5; 1466 1383 break; 1467 1384 } else if (ver->fcxbtcrpt == 8) { 1468 1385 pfinfo = &pfwinfo->rpt_ctrl.finfo.v8; 1469 1386 pcinfo->req_len = sizeof(pfwinfo->rpt_ctrl.finfo.v8); 1387 + fwsubver->fcxbtcrpt = pfwinfo->rpt_ctrl.finfo.v8.fver; 1470 1388 } else if (ver->fcxbtcrpt == 7) { 1471 1389 pfinfo = &pfwinfo->rpt_ctrl.finfo.v7; 1472 1390 pcinfo->req_len = sizeof(pfwinfo->rpt_ctrl.finfo.v7); 1391 + fwsubver->fcxbtcrpt = pfwinfo->rpt_ctrl.finfo.v7.fver; 1473 1392 } else { 1474 1393 goto err; 1475 1394 } ··· 1486 1393 if (ver->fcxtdma == 1) { 1487 1394 pfinfo = &pfwinfo->rpt_fbtc_tdma.finfo.v1; 1488 1395 pcinfo->req_len = sizeof(pfwinfo->rpt_fbtc_tdma.finfo.v1); 1396 + fwsubver->fcxtdma = 0; 1489 1397 } else if (ver->fcxtdma == 3 || ver->fcxtdma == 7) { 1490 1398 pfinfo = &pfwinfo->rpt_fbtc_tdma.finfo.v3; 1491 1399 pcinfo->req_len = sizeof(pfwinfo->rpt_fbtc_tdma.finfo.v3); 1400 + fwsubver->fcxtdma = pfwinfo->rpt_fbtc_tdma.finfo.v3.fver; 1492 1401 } else { 1493 1402 goto err; 1494 1403 } ··· 1501 1406 if (ver->fcxslots == 1) { 1502 1407 pfinfo = &pfwinfo->rpt_fbtc_slots.finfo.v1; 1503 1408 pcinfo->req_len = sizeof(pfwinfo->rpt_fbtc_slots.finfo.v1); 1409 + fwsubver->fcxslots = pfwinfo->rpt_fbtc_slots.finfo.v1.fver; 1504 1410 } else if (ver->fcxslots == 7) { 1505 1411 pfinfo = &pfwinfo->rpt_fbtc_slots.finfo.v7; 1506 1412 pcinfo->req_len = sizeof(pfwinfo->rpt_fbtc_slots.finfo.v7); 1413 + fwsubver->fcxslots = pfwinfo->rpt_fbtc_slots.finfo.v7.fver; 1507 1414 } else { 1508 1415 goto err; 1509 1416 } ··· 1518 1421 pfinfo = &pfwinfo->rpt_fbtc_cysta.finfo.v2; 1519 1422 pcysta->v2 = pfwinfo->rpt_fbtc_cysta.finfo.v2; 1520 1423 pcinfo->req_len = sizeof(pfwinfo->rpt_fbtc_cysta.finfo.v2); 1424 + fwsubver->fcxcysta = pfwinfo->rpt_fbtc_cysta.finfo.v2.fver; 1521 1425 } else if (ver->fcxcysta == 3) { 1522 1426 pfinfo = &pfwinfo->rpt_fbtc_cysta.finfo.v3; 1523 1427 pcysta->v3 = pfwinfo->rpt_fbtc_cysta.finfo.v3; 1524 1428 pcinfo->req_len = sizeof(pfwinfo->rpt_fbtc_cysta.finfo.v3); 1429 + fwsubver->fcxcysta = pfwinfo->rpt_fbtc_cysta.finfo.v3.fver; 1525 1430 } else if (ver->fcxcysta == 4) { 1526 1431 pfinfo = &pfwinfo->rpt_fbtc_cysta.finfo.v4; 1527 1432 pcysta->v4 = pfwinfo->rpt_fbtc_cysta.finfo.v4; 1528 1433 pcinfo->req_len = sizeof(pfwinfo->rpt_fbtc_cysta.finfo.v4); 1434 + fwsubver->fcxcysta = pfwinfo->rpt_fbtc_cysta.finfo.v4.fver; 1529 1435 } else if (ver->fcxcysta == 5) { 1530 1436 pfinfo = &pfwinfo->rpt_fbtc_cysta.finfo.v5; 1531 1437 pcysta->v5 = pfwinfo->rpt_fbtc_cysta.finfo.v5; 1532 1438 pcinfo->req_len = sizeof(pfwinfo->rpt_fbtc_cysta.finfo.v5); 1439 + fwsubver->fcxcysta = pfwinfo->rpt_fbtc_cysta.finfo.v5.fver; 1533 1440 } else if (ver->fcxcysta == 7) { 1534 1441 pfinfo = &pfwinfo->rpt_fbtc_cysta.finfo.v7; 1535 1442 pcysta->v7 = pfwinfo->rpt_fbtc_cysta.finfo.v7; 1536 1443 pcinfo->req_len = sizeof(pfwinfo->rpt_fbtc_cysta.finfo.v7); 1444 + fwsubver->fcxcysta = pfwinfo->rpt_fbtc_cysta.finfo.v7.fver; 1537 1445 } else { 1538 1446 goto err; 1539 1447 } ··· 1554 1452 pcinfo->req_len = sizeof(pfwinfo->rpt_fbtc_step.finfo.v2.step[0]) * 1555 1453 trace_step + 1556 1454 offsetof(struct rtw89_btc_fbtc_steps_v2, step); 1455 + fwsubver->fcxstep = pfwinfo->rpt_fbtc_step.finfo.v2.fver; 1557 1456 } else if (ver->fcxstep == 3) { 1558 1457 pfinfo = &pfwinfo->rpt_fbtc_step.finfo.v3; 1559 1458 pcinfo->req_len = sizeof(pfwinfo->rpt_fbtc_step.finfo.v3.step[0]) * 1560 1459 trace_step + 1561 1460 offsetof(struct rtw89_btc_fbtc_steps_v3, step); 1461 + fwsubver->fcxstep = pfwinfo->rpt_fbtc_step.finfo.v3.fver; 1562 1462 } else { 1563 1463 goto err; 1564 1464 } ··· 1571 1467 if (ver->fcxnullsta == 1) { 1572 1468 pfinfo = &pfwinfo->rpt_fbtc_nullsta.finfo.v1; 1573 1469 pcinfo->req_len = sizeof(pfwinfo->rpt_fbtc_nullsta.finfo.v1); 1470 + fwsubver->fcxnullsta = pfwinfo->rpt_fbtc_nullsta.finfo.v1.fver; 1574 1471 } else if (ver->fcxnullsta == 2) { 1575 1472 pfinfo = &pfwinfo->rpt_fbtc_nullsta.finfo.v2; 1576 1473 pcinfo->req_len = sizeof(pfwinfo->rpt_fbtc_nullsta.finfo.v2); 1474 + fwsubver->fcxnullsta = pfwinfo->rpt_fbtc_nullsta.finfo.v2.fver; 1577 1475 } else if (ver->fcxnullsta == 7) { 1578 1476 pfinfo = &pfwinfo->rpt_fbtc_nullsta.finfo.v7; 1579 1477 pcinfo->req_len = sizeof(pfwinfo->rpt_fbtc_nullsta.finfo.v7); 1478 + fwsubver->fcxnullsta = pfwinfo->rpt_fbtc_nullsta.finfo.v7.fver; 1580 1479 } else { 1581 1480 goto err; 1582 1481 } ··· 1590 1483 if (ver->fcxmreg == 1) { 1591 1484 pfinfo = &pfwinfo->rpt_fbtc_mregval.finfo.v1; 1592 1485 pcinfo->req_len = sizeof(pfwinfo->rpt_fbtc_mregval.finfo.v1); 1486 + fwsubver->fcxmreg = pfwinfo->rpt_fbtc_mregval.finfo.v1.fver; 1593 1487 } else if (ver->fcxmreg == 2) { 1594 1488 pfinfo = &pfwinfo->rpt_fbtc_mregval.finfo.v2; 1595 1489 pcinfo->req_len = sizeof(pfwinfo->rpt_fbtc_mregval.finfo.v2); 1490 + fwsubver->fcxmreg = pfwinfo->rpt_fbtc_mregval.finfo.v2.fver; 1596 1491 } else if (ver->fcxmreg == 7) { 1597 1492 pfinfo = &pfwinfo->rpt_fbtc_mregval.finfo.v7; 1598 1493 pcinfo->req_len = sizeof(pfwinfo->rpt_fbtc_mregval.finfo.v7); 1494 + fwsubver->fcxmreg = pfwinfo->rpt_fbtc_mregval.finfo.v7.fver; 1599 1495 } else { 1600 1496 goto err; 1601 1497 } ··· 1609 1499 if (ver->fcxgpiodbg == 7) { 1610 1500 pfinfo = &pfwinfo->rpt_fbtc_gpio_dbg.finfo.v7; 1611 1501 pcinfo->req_len = sizeof(pfwinfo->rpt_fbtc_gpio_dbg.finfo.v7); 1502 + fwsubver->fcxgpiodbg = pfwinfo->rpt_fbtc_gpio_dbg.finfo.v7.fver; 1612 1503 } else { 1613 1504 pfinfo = &pfwinfo->rpt_fbtc_gpio_dbg.finfo.v1; 1614 1505 pcinfo->req_len = sizeof(pfwinfo->rpt_fbtc_gpio_dbg.finfo.v1); 1506 + fwsubver->fcxgpiodbg = pfwinfo->rpt_fbtc_gpio_dbg.finfo.v1.fver; 1615 1507 } 1616 1508 pcinfo->req_fver = ver->fcxgpiodbg; 1617 1509 break; ··· 1622 1510 if (ver->fcxbtver == 1) { 1623 1511 pfinfo = &pfwinfo->rpt_fbtc_btver.finfo.v1; 1624 1512 pcinfo->req_len = sizeof(pfwinfo->rpt_fbtc_btver.finfo.v1); 1513 + fwsubver->fcxbtver = pfwinfo->rpt_fbtc_btver.finfo.v1.fver; 1625 1514 } else if (ver->fcxbtver == 7) { 1626 1515 pfinfo = &pfwinfo->rpt_fbtc_btver.finfo.v7; 1627 1516 pcinfo->req_len = sizeof(pfwinfo->rpt_fbtc_btver.finfo.v7); 1517 + fwsubver->fcxbtver = pfwinfo->rpt_fbtc_btver.finfo.v7.fver; 1628 1518 } 1629 1519 pcinfo->req_fver = ver->fcxbtver; 1630 1520 break; ··· 1635 1521 if (ver->fcxbtscan == 1) { 1636 1522 pfinfo = &pfwinfo->rpt_fbtc_btscan.finfo.v1; 1637 1523 pcinfo->req_len = sizeof(pfwinfo->rpt_fbtc_btscan.finfo.v1); 1524 + fwsubver->fcxbtscan = pfwinfo->rpt_fbtc_btscan.finfo.v1.fver; 1638 1525 } else if (ver->fcxbtscan == 2) { 1639 1526 pfinfo = &pfwinfo->rpt_fbtc_btscan.finfo.v2; 1640 1527 pcinfo->req_len = sizeof(pfwinfo->rpt_fbtc_btscan.finfo.v2); 1528 + fwsubver->fcxbtscan = pfwinfo->rpt_fbtc_btscan.finfo.v2.fver; 1641 1529 } else if (ver->fcxbtscan == 7) { 1642 1530 pfinfo = &pfwinfo->rpt_fbtc_btscan.finfo.v7; 1643 1531 pcinfo->req_len = sizeof(pfwinfo->rpt_fbtc_btscan.finfo.v7); 1532 + fwsubver->fcxbtscan = pfwinfo->rpt_fbtc_btscan.finfo.v7.fver; 1644 1533 } else { 1645 1534 goto err; 1646 1535 } ··· 1654 1537 if (ver->fcxbtafh == 1) { 1655 1538 pfinfo = &pfwinfo->rpt_fbtc_btafh.finfo.v1; 1656 1539 pcinfo->req_len = sizeof(pfwinfo->rpt_fbtc_btafh.finfo.v1); 1540 + fwsubver->fcxbtafh = pfwinfo->rpt_fbtc_btafh.finfo.v1.fver; 1657 1541 } else if (ver->fcxbtafh == 2) { 1658 1542 pfinfo = &pfwinfo->rpt_fbtc_btafh.finfo.v2; 1659 1543 pcinfo->req_len = sizeof(pfwinfo->rpt_fbtc_btafh.finfo.v2); 1544 + fwsubver->fcxbtafh = pfwinfo->rpt_fbtc_btafh.finfo.v2.fver; 1660 1545 } else if (ver->fcxbtafh == 7) { 1661 1546 pfinfo = &pfwinfo->rpt_fbtc_btafh.finfo.v7; 1662 1547 pcinfo->req_len = sizeof(pfwinfo->rpt_fbtc_btafh.finfo.v7); 1548 + fwsubver->fcxbtafh = pfwinfo->rpt_fbtc_btafh.finfo.v7.fver; 1663 1549 } else { 1664 1550 goto err; 1665 1551 } ··· 1672 1552 pcinfo = &pfwinfo->rpt_fbtc_btdev.cinfo; 1673 1553 pfinfo = &pfwinfo->rpt_fbtc_btdev.finfo; 1674 1554 pcinfo->req_len = sizeof(pfwinfo->rpt_fbtc_btdev.finfo); 1555 + fwsubver->fcxbtdevinfo = pfwinfo->rpt_fbtc_btdev.finfo.fver; 1675 1556 pcinfo->req_fver = ver->fcxbtdevinfo; 1676 1557 break; 1677 1558 default: ··· 2404 2283 bit_map = BIT(6); 2405 2284 break; 2406 2285 case 3: 2286 + case 4: 2407 2287 bit_map = BIT(5); 2408 2288 break; 2409 2289 default: ··· 2419 2297 bit_map = BIT(5); 2420 2298 break; 2421 2299 case 3: 2300 + case 4: 2422 2301 bit_map = BIT(6); 2423 2302 break; 2424 2303 default: ··· 2432 2309 bit_map = BIT(8); 2433 2310 break; 2434 2311 case 3: 2312 + case 4: 2435 2313 bit_map = BIT(7); 2314 + break; 2315 + default: 2316 + break; 2317 + } 2318 + break; 2319 + case RPT_EN_BT_TX_PWR_LVL: 2320 + switch (ver->frptmap) { 2321 + case 0: 2322 + case 1: 2323 + case 2: 2324 + case 3: 2325 + break; 2326 + case 4: 2327 + bit_map = BIT(8); 2436 2328 break; 2437 2329 default: 2438 2330 break; ··· 2461 2323 break; 2462 2324 case 3: 2463 2325 bit_map = BIT(8); 2326 + break; 2327 + case 4: 2328 + bit_map = BIT(9); 2464 2329 break; 2465 2330 default: 2466 2331 break; ··· 2482 2341 case 3: 2483 2342 bit_map = GENMASK(2, 0) | BIT(8); 2484 2343 break; 2344 + case 4: 2345 + bit_map = GENMASK(2, 0) | BIT(9); 2346 + break; 2485 2347 default: 2486 2348 break; 2487 2349 } ··· 2500 2356 break; 2501 2357 case 3: 2502 2358 bit_map = GENMASK(7, 3); 2359 + break; 2360 + case 4: 2361 + bit_map = GENMASK(8, 3); 2503 2362 break; 2504 2363 default: 2505 2364 break; ··· 2520 2373 case 3: 2521 2374 bit_map = GENMASK(8, 0); 2522 2375 break; 2376 + case 4: 2377 + bit_map = GENMASK(9, 0); 2378 + break; 2523 2379 default: 2524 2380 break; 2525 2381 } ··· 2538 2388 break; 2539 2389 case 3: 2540 2390 bit_map = GENMASK(8, 2); 2391 + break; 2392 + case 4: 2393 + bit_map = GENMASK(9, 2); 2541 2394 break; 2542 2395 default: 2543 2396 break; ··· 2831 2678 case CXDRVINFO_FDDT: 2832 2679 case CXDRVINFO_MLO: 2833 2680 case CXDRVINFO_OSI: 2681 + if (!ver->fcxosi) 2682 + return; 2683 + 2684 + if (ver->drvinfo_type == 2) 2685 + type = 7; 2686 + else 2687 + return; 2688 + 2689 + rtw89_fw_h2c_cxdrv_osi_info(rtwdev, type); 2690 + break; 2834 2691 default: 2835 2692 break; 2836 2693 } ··· 2921 2758 { 2922 2759 struct rtw89_btc *btc = &rtwdev->btc; 2923 2760 struct rtw89_btc_dm *dm = &btc->dm; 2761 + struct rtw89_btc_fbtc_outsrc_set_info *osi = &dm->ost_info; 2762 + struct rtw89_mac_ax_wl_act *b = dm->gnt.bt; 2924 2763 struct rtw89_mac_ax_gnt *g = dm->gnt.band; 2925 2764 u8 i, bt_idx = dm->bt_select + 1; 2926 2765 ··· 2971 2806 2972 2807 switch (wlact_state) { 2973 2808 case BTC_WLACT_HW: 2974 - dm->gnt.bt[i].wlan_act_en = 0; 2975 - dm->gnt.bt[i].wlan_act = 0; 2809 + b[i].wlan_act_en = 0; 2810 + b[i].wlan_act = 0; 2976 2811 break; 2977 2812 case BTC_WLACT_SW_LO: 2978 - dm->gnt.bt[i].wlan_act_en = 1; 2979 - dm->gnt.bt[i].wlan_act = 0; 2813 + b[i].wlan_act_en = 1; 2814 + b[i].wlan_act = 0; 2980 2815 break; 2981 2816 case BTC_WLACT_SW_HI: 2982 - dm->gnt.bt[i].wlan_act_en = 1; 2983 - dm->gnt.bt[i].wlan_act = 1; 2817 + b[i].wlan_act_en = 1; 2818 + b[i].wlan_act = 1; 2984 2819 break; 2985 2820 } 2986 2821 } 2987 2822 } 2988 - rtw89_mac_cfg_gnt_v2(rtwdev, &dm->gnt); 2823 + 2824 + if (!btc->ver->fcxosi) { 2825 + rtw89_mac_cfg_gnt_v2(rtwdev, &dm->gnt); 2826 + return; 2827 + } 2828 + 2829 + memcpy(osi->gnt_set, dm->gnt.band, sizeof(osi->gnt_set)); 2830 + memcpy(osi->wlact_set, dm->gnt.bt, sizeof(osi->wlact_set)); 2831 + 2832 + /* GBT source should be GBT_S1 in 1+1 (HWB0:5G + HWB1:2G) case */ 2833 + if (osi->rf_band[BTC_RF_S0] == 1 && 2834 + osi->rf_band[BTC_RF_S1] == 0) 2835 + osi->rf_gbt_source = BTC_RF_S1; 2836 + else 2837 + osi->rf_gbt_source = BTC_RF_S0; 2989 2838 } 2990 2839 2991 2840 #define BTC_TDMA_WLROLE_MAX 3 ··· 3241 3062 } 3242 3063 } 3243 3064 3244 - static void _set_bt_afh_info(struct rtw89_dev *rtwdev) 3065 + static void _set_bt_afh_info_v0(struct rtw89_dev *rtwdev) 3245 3066 { 3246 3067 const struct rtw89_chip_info *chip = rtwdev->chip; 3247 3068 struct rtw89_btc *btc = &rtwdev->btc; ··· 3408 3229 "[BTC], %s(): en=%d, ch=%d, bw=%d\n", 3409 3230 __func__, en, ch, bw); 3410 3231 btc->cx.cnt_wl[BTC_WCNT_CH_UPDATE]++; 3232 + } 3233 + 3234 + static void _set_bt_afh_info_v1(struct rtw89_dev *rtwdev) 3235 + { 3236 + const struct rtw89_chip_info *chip = rtwdev->chip; 3237 + struct rtw89_btc *btc = &rtwdev->btc; 3238 + struct rtw89_btc_wl_info *wl = &btc->cx.wl; 3239 + struct rtw89_btc_wl_role_info_v8 *wl_rinfo = &wl->role_info_v8; 3240 + struct rtw89_btc_wl_afh_info *wl_afh = &wl->afh_info; 3241 + struct rtw89_btc_bt_info *bt = &btc->cx.bt; 3242 + struct rtw89_btc_wl_rlink *rlink; 3243 + u8 en = 0, ch = 0, bw = 0, buf[3] = {}; 3244 + u8 i, j, link_mode; 3245 + 3246 + if (btc->manual_ctrl || wl->status.map.scan) 3247 + return; 3248 + 3249 + link_mode = wl_rinfo->link_mode; 3250 + 3251 + for (i = 0; i < btc->ver->max_role_num; i++) { 3252 + for (j = RTW89_MAC_0; j < RTW89_MAC_NUM; j++) { 3253 + if (wl->status.map.rf_off || bt->whql_test || 3254 + link_mode == BTC_WLINK_NOLINK || 3255 + link_mode == BTC_WLINK_5G) 3256 + break; 3257 + 3258 + rlink = &wl_rinfo->rlink[i][j]; 3259 + 3260 + /* Don't care no-connected/non-2G-band role */ 3261 + if (!rlink->connected || !rlink->active || 3262 + rlink->rf_band != RTW89_BAND_2G) 3263 + continue; 3264 + 3265 + en = 1; 3266 + ch = rlink->ch; 3267 + bw = rlink->bw; 3268 + 3269 + if (link_mode == BTC_WLINK_2G_MCC && 3270 + (rlink->role == RTW89_WIFI_ROLE_AP || 3271 + rlink->role == RTW89_WIFI_ROLE_P2P_GO || 3272 + rlink->role == RTW89_WIFI_ROLE_P2P_CLIENT)) { 3273 + /* for 2.4G MCC, take role = ap/go/gc */ 3274 + break; 3275 + } else if (link_mode != BTC_WLINK_2G_SCC || 3276 + rlink->bw == RTW89_CHANNEL_WIDTH_40) { 3277 + /* for 2.4G scc, take bw = 40M */ 3278 + break; 3279 + } 3280 + } 3281 + } 3282 + 3283 + /* default AFH channel sapn = center-ch +- 6MHz */ 3284 + switch (bw) { 3285 + case RTW89_CHANNEL_WIDTH_20: 3286 + if (btc->dm.freerun || btc->dm.fddt_train) 3287 + bw = 48; 3288 + else 3289 + bw = 20 + chip->afh_guard_ch * 2; 3290 + break; 3291 + case RTW89_CHANNEL_WIDTH_40: 3292 + if (btc->dm.freerun) 3293 + bw = 40 + chip->afh_guard_ch * 2; 3294 + else 3295 + bw = 40; 3296 + break; 3297 + case RTW89_CHANNEL_WIDTH_5: 3298 + bw = 5 + chip->afh_guard_ch * 2; 3299 + break; 3300 + case RTW89_CHANNEL_WIDTH_10: 3301 + bw = 10 + chip->afh_guard_ch * 2; 3302 + break; 3303 + default: 3304 + en = false; /* turn off AFH info if invalid BW */ 3305 + bw = 0; 3306 + ch = 0; 3307 + break; 3308 + } 3309 + 3310 + if (!en || ch > 14 || ch == 0) { 3311 + en = false; 3312 + bw = 0; 3313 + ch = 0; 3314 + } 3315 + 3316 + if (wl_afh->en == en && 3317 + wl_afh->ch == ch && 3318 + wl_afh->bw == bw && 3319 + (!bt->enable.now || bt->enable.last)) 3320 + return; 3321 + 3322 + wl_afh->en = buf[0]; 3323 + wl_afh->ch = buf[1]; 3324 + wl_afh->bw = buf[2]; 3325 + 3326 + if (_send_fw_cmd(rtwdev, BTFC_SET, SET_BT_WL_CH_INFO, &wl->afh_info, 3)) { 3327 + rtw89_debug(rtwdev, RTW89_DBG_BTC, 3328 + "[BTC], %s(): en=%d, ch=%d, bw=%d\n", 3329 + __func__, en, ch, bw); 3330 + 3331 + btc->cx.cnt_wl[BTC_WCNT_CH_UPDATE]++; 3332 + } 3333 + } 3334 + 3335 + static void _set_bt_afh_info(struct rtw89_dev *rtwdev) 3336 + { 3337 + if (rtwdev->chip->chip_id == RTL8922A) 3338 + _set_bt_afh_info_v1(rtwdev); 3339 + else 3340 + _set_bt_afh_info_v0(rtwdev); 3411 3341 } 3412 3342 3413 3343 static bool _check_freerun(struct rtw89_dev *rtwdev) ··· 4004 3716 u32 tbl_w1, tbl_b1, tbl_b4; 4005 3717 u16 dur_2; 4006 3718 3719 + if (wl->status.map.lps) { 3720 + _slot_set_le(btc, CXST_E2G, s_def[CXST_E2G].dur, 3721 + s_def[CXST_E2G].cxtbl, s_def[CXST_E2G].cxtype); 3722 + _slot_set_le(btc, CXST_E5G, s_def[CXST_E5G].dur, 3723 + s_def[CXST_E5G].cxtbl, s_def[CXST_E5G].cxtype); 3724 + _slot_set_le(btc, CXST_EBT, s_def[CXST_EBT].dur, 3725 + s_def[CXST_EBT].cxtbl, s_def[CXST_EBT].cxtype); 3726 + } 3727 + 4007 3728 type = FIELD_GET(BTC_CXP_MASK, policy_type); 4008 3729 4009 3730 if (btc->ant_type == BTC_ANT_SHARED) { ··· 4133 3836 4134 3837 switch (policy_type) { 4135 3838 case BTC_CXP_OFFE_2GBWISOB: /* for normal-case */ 4136 - _slot_set(btc, CXST_E2G, 0, tbl_w1, SLOT_ISO); 3839 + _slot_set(btc, CXST_E2G, 5, tbl_w1, SLOT_ISO); 4137 3840 _slot_set_le(btc, CXST_EBT, s_def[CXST_EBT].dur, 4138 3841 s_def[CXST_EBT].cxtbl, s_def[CXST_EBT].cxtype); 4139 3842 _slot_set_dur(btc, CXST_EBT, dur_2); 4140 3843 break; 4141 3844 case BTC_CXP_OFFE_2GISOB: /* for bt no-link */ 4142 - _slot_set(btc, CXST_E2G, 0, cxtbl[1], SLOT_ISO); 3845 + _slot_set(btc, CXST_E2G, 5, cxtbl[1], SLOT_ISO); 4143 3846 _slot_set_le(btc, CXST_EBT, s_def[CXST_EBT].dur, 4144 3847 s_def[CXST_EBT].cxtbl, s_def[CXST_EBT].cxtype); 4145 3848 _slot_set_dur(btc, CXST_EBT, dur_2); ··· 4165 3868 break; 4166 3869 case BTC_CXP_OFFE_2GBWMIXB: 4167 3870 if (a2dp->exist) 4168 - _slot_set(btc, CXST_E2G, 0, cxtbl[2], SLOT_MIX); 3871 + _slot_set(btc, CXST_E2G, 5, cxtbl[2], SLOT_MIX); 4169 3872 else 4170 - _slot_set(btc, CXST_E2G, 0, tbl_w1, SLOT_MIX); 4171 - _slot_set_le(btc, CXST_EBT, s_def[CXST_EBT].dur, 3873 + _slot_set(btc, CXST_E2G, 5, tbl_w1, SLOT_MIX); 3874 + _slot_set_le(btc, CXST_EBT, cpu_to_le16(40), 4172 3875 s_def[CXST_EBT].cxtbl, s_def[CXST_EBT].cxtype); 4173 3876 break; 4174 3877 case BTC_CXP_OFFE_WL: /* for 4-way */ 4175 - _slot_set(btc, CXST_E2G, 0, cxtbl[1], SLOT_MIX); 4176 - _slot_set(btc, CXST_EBT, 0, cxtbl[1], SLOT_MIX); 3878 + _slot_set(btc, CXST_E2G, 5, cxtbl[1], SLOT_MIX); 3879 + _slot_set(btc, CXST_EBT, 5, cxtbl[1], SLOT_MIX); 4177 3880 break; 4178 3881 default: 4179 3882 break; ··· 5161 4864 struct rtw89_btc_wl_role_info_v2 *wl_rinfo_v2 = &wl->role_info_v2; 5162 4865 struct rtw89_btc_wl_role_info_v7 *wl_rinfo_v7 = &wl->role_info_v7; 5163 4866 struct rtw89_btc_wl_role_info_v8 *wl_rinfo_v8 = &wl->role_info_v8; 4867 + struct rtw89_btc_fbtc_outsrc_set_info *o_info = &btc->dm.ost_info; 5164 4868 struct rtw89_btc_wl_role_info *wl_rinfo_v0 = &wl->role_info; 5165 - struct rtw89_btc_wl_dbcc_info *wl_dinfo = &wl->dbcc_info; 5166 4869 const struct rtw89_chip_info *chip = rtwdev->chip; 5167 4870 const struct rtw89_btc_ver *ver = btc->ver; 5168 4871 struct rtw89_btc_bt_info *bt = &btc->cx.bt; 5169 4872 struct rtw89_btc_dm *dm = &btc->dm; 5170 4873 struct _wl_rinfo_now wl_rinfo; 5171 - u32 run_reason = btc->dm.run_reason; 5172 - u32 is_btg; 5173 - u8 i, val; 4874 + u32 is_btg = BTC_BTGCTRL_DISABLE; 5174 4875 5175 4876 if (btc->manual_ctrl) 5176 4877 return; ··· 5186 4891 else 5187 4892 return; 5188 4893 5189 - if (rtwdev->dbcc_en) { 5190 - if (ver->fwlrole == 0) { 5191 - wl_rinfo.dbcc_2g_phy = RTW89_PHY_NUM; 4894 + /* notify halbb ignore GNT_BT or not for WL BB Rx-AGC control */ 4895 + if (btc->ant_type == BTC_ANT_SHARED) { 4896 + if (!(bt->run_patch_code && bt->enable.now)) 4897 + is_btg = BTC_BTGCTRL_DISABLE; 4898 + else if (wl_rinfo.link_mode != BTC_WLINK_5G) 4899 + is_btg = BTC_BTGCTRL_ENABLE; 4900 + else 4901 + is_btg = BTC_BTGCTRL_DISABLE; 5192 4902 5193 - for (i = 0; i < RTW89_PHY_NUM; i++) { 5194 - if (wl_dinfo->real_band[i] == RTW89_BAND_2G) 5195 - wl_rinfo.dbcc_2g_phy = i; 5196 - } 5197 - } else if (ver->fwlrole == 1) { 5198 - wl_rinfo.dbcc_2g_phy = wl_rinfo_v1->dbcc_2g_phy; 5199 - } else if (ver->fwlrole == 2) { 5200 - wl_rinfo.dbcc_2g_phy = wl_rinfo_v2->dbcc_2g_phy; 5201 - } else if (ver->fwlrole == 7) { 5202 - wl_rinfo.dbcc_2g_phy = wl_rinfo_v7->dbcc_2g_phy; 5203 - } else if (ver->fwlrole == 8) { 5204 - wl_rinfo.dbcc_2g_phy = wl_rinfo_v8->dbcc_2g_phy; 5205 - } else { 5206 - return; 5207 - } 4903 + /* bb call ctrl_btg() in WL FW by slot */ 4904 + if (!ver->fcxosi && 4905 + wl_rinfo.link_mode == BTC_WLINK_25G_MCC) 4906 + is_btg = BTC_BTGCTRL_BB_GNT_FWCTRL; 5208 4907 } 5209 4908 5210 - if (wl_rinfo.link_mode == BTC_WLINK_25G_MCC) 5211 - is_btg = BTC_BTGCTRL_BB_GNT_FWCTRL; 5212 - else if (!(bt->run_patch_code && bt->enable.now)) 5213 - is_btg = BTC_BTGCTRL_DISABLE; 5214 - else if (wl_rinfo.link_mode == BTC_WLINK_5G) 5215 - is_btg = BTC_BTGCTRL_DISABLE; 5216 - else if (dm->freerun) 5217 - is_btg = BTC_BTGCTRL_DISABLE; 5218 - else if (rtwdev->dbcc_en && wl_rinfo.dbcc_2g_phy != RTW89_PHY_1) 5219 - is_btg = BTC_BTGCTRL_DISABLE; 4909 + if (is_btg == dm->wl_btg_rx) 4910 + return; 5220 4911 else 5221 - is_btg = BTC_BTGCTRL_ENABLE; 5222 - 5223 - if (dm->wl_btg_rx_rb != dm->wl_btg_rx && 5224 - dm->wl_btg_rx_rb != BTC_BTGCTRL_BB_GNT_NOTFOUND) { 5225 - _get_reg_status(rtwdev, BTC_CSTATUS_BB_GNT_MUX, &val); 5226 - dm->wl_btg_rx_rb = val; 5227 - } 5228 - 5229 - if (run_reason == BTC_RSN_NTFY_INIT || 5230 - run_reason == BTC_RSN_NTFY_SWBAND || 5231 - dm->wl_btg_rx_rb != dm->wl_btg_rx || 5232 - is_btg != dm->wl_btg_rx) { 5233 - 5234 4912 dm->wl_btg_rx = is_btg; 5235 4913 5236 - if (is_btg > BTC_BTGCTRL_ENABLE) 5237 - return; 4914 + /* skip setup if btg_ctrl set by wl fw */ 4915 + if (!ver->fcxosi && is_btg > BTC_BTGCTRL_ENABLE) 4916 + return; 5238 4917 5239 - chip->ops->ctrl_btg_bt_rx(rtwdev, is_btg, RTW89_PHY_0); 4918 + /* Below flow is for BTC_FEAT_NEW_BBAPI_FLOW = 1 */ 4919 + if (o_info->rf_band[BTC_RF_S0] != o_info->rf_band[BTC_RF_S1]) {/* 1+1 */ 4920 + if (o_info->rf_band[BTC_RF_S0]) /* Non-2G */ 4921 + o_info->btg_rx[BTC_RF_S0] = BTC_BTGCTRL_DISABLE; 4922 + else 4923 + o_info->btg_rx[BTC_RF_S0] = is_btg; 4924 + 4925 + if (o_info->rf_band[BTC_RF_S1]) /* Non-2G */ 4926 + o_info->btg_rx[BTC_RF_S1] = BTC_BTGCTRL_DISABLE; 4927 + else 4928 + o_info->btg_rx[BTC_RF_S1] = is_btg; 4929 + } else { /* 2+0 or 0+2 */ 4930 + o_info->btg_rx[BTC_RF_S0] = is_btg; 4931 + o_info->btg_rx[BTC_RF_S1] = is_btg; 5240 4932 } 4933 + 4934 + if (ver->fcxosi) 4935 + return; 4936 + 4937 + chip->ops->ctrl_btg_bt_rx(rtwdev, o_info->btg_rx[BTC_RF_S0], 4938 + RTW89_PHY_0); 4939 + if (chip->chip_id != RTL8922A) 4940 + return; 4941 + 4942 + chip->ops->ctrl_btg_bt_rx(rtwdev, o_info->btg_rx[BTC_RF_S1], 4943 + RTW89_PHY_1); 5241 4944 } 5242 4945 5243 4946 static void _set_wl_preagc_ctrl(struct rtw89_dev *rtwdev) 5244 4947 { 5245 4948 struct rtw89_btc *btc = &rtwdev->btc; 4949 + struct rtw89_btc_fbtc_outsrc_set_info *o_info = &btc->dm.ost_info; 5246 4950 struct rtw89_btc_bt_link_info *bt_linfo = &btc->cx.bt.link_info; 5247 4951 struct rtw89_btc_wl_info *wl = &btc->cx.wl; 5248 4952 struct rtw89_btc_wl_role_info_v2 *rinfo_v2 = &wl->role_info_v2; ··· 5273 4979 return; 5274 4980 } 5275 4981 5276 - if (link_mode == BTC_WLINK_25G_MCC) { 5277 - is_preagc = BTC_PREAGC_BB_FWCTRL; 5278 - } else if (!(bt->run_patch_code && bt->enable.now)) { 4982 + if (!(bt->run_patch_code && bt->enable.now)) { 5279 4983 is_preagc = BTC_PREAGC_DISABLE; 5280 4984 } else if (link_mode == BTC_WLINK_5G) { 5281 4985 is_preagc = BTC_PREAGC_DISABLE; ··· 5293 5001 is_preagc = BTC_PREAGC_ENABLE; 5294 5002 } 5295 5003 5004 + if (!btc->ver->fcxosi && link_mode == BTC_WLINK_25G_MCC) 5005 + is_preagc = BTC_PREAGC_BB_FWCTRL; 5006 + 5296 5007 if (dm->wl_pre_agc_rb != dm->wl_pre_agc && 5297 5008 dm->wl_pre_agc_rb != BTC_PREAGC_NOTFOUND) { 5298 5009 _get_reg_status(rtwdev, BTC_CSTATUS_BB_PRE_AGC, &val); ··· 5309 5014 is_preagc != dm->wl_pre_agc) { 5310 5015 dm->wl_pre_agc = is_preagc; 5311 5016 5312 - if (is_preagc > BTC_PREAGC_ENABLE) 5017 + if (!btc->ver->fcxosi && is_preagc > BTC_PREAGC_ENABLE) 5313 5018 return; 5314 - chip->ops->ctrl_nbtg_bt_tx(rtwdev, dm->wl_pre_agc, RTW89_PHY_0); 5019 + 5020 + if (o_info->rf_band[BTC_RF_S0] != o_info->rf_band[BTC_RF_S1]) {/* 1+1 */ 5021 + if (o_info->rf_band[BTC_RF_S0]) /* Non-2G */ 5022 + o_info->nbtg_tx[BTC_RF_S0] = BTC_PREAGC_DISABLE; 5023 + else 5024 + o_info->nbtg_tx[BTC_RF_S0] = is_preagc; 5025 + 5026 + if (o_info->rf_band[BTC_RF_S1]) /* Non-2G */ 5027 + o_info->nbtg_tx[BTC_RF_S1] = BTC_PREAGC_DISABLE; 5028 + else 5029 + o_info->nbtg_tx[BTC_RF_S1] = is_preagc; 5030 + 5031 + } else { /* 2+0 or 0+2 */ 5032 + o_info->nbtg_tx[BTC_RF_S0] = is_preagc; 5033 + o_info->nbtg_tx[BTC_RF_S1] = is_preagc; 5034 + } 5035 + 5036 + if (btc->ver->fcxosi) 5037 + return; 5038 + 5039 + chip->ops->ctrl_nbtg_bt_tx(rtwdev, o_info->nbtg_tx[BTC_RF_S0], 5040 + RTW89_PHY_0); 5041 + if (chip->chip_id != RTL8922A) 5042 + return; 5043 + chip->ops->ctrl_nbtg_bt_tx(rtwdev, o_info->nbtg_tx[BTC_RF_S1], 5044 + RTW89_PHY_1); 5315 5045 } 5316 5046 } 5317 5047 ··· 5549 5229 _write_scbd(rtwdev, BTC_WSCB_RXSCAN_PRI, (bool)(!!bt->scan_rx_low_pri)); 5550 5230 } 5551 5231 5232 + static void _wl_req_mac(struct rtw89_dev *rtwdev, u8 mac) 5233 + { 5234 + struct rtw89_btc *btc = &rtwdev->btc; 5235 + struct rtw89_btc_wl_info *wl = &btc->cx.wl; 5236 + struct rtw89_btc_dm *dm = &btc->dm; 5237 + u32 add; 5238 + 5239 + if (mac == wl->pta_req_mac) 5240 + return; 5241 + 5242 + dm->ost_info.pta_req_hw_band = mac; 5243 + wl->pta_req_mac = mac; 5244 + wl->pta_reg_mac_chg = true; 5245 + 5246 + if (btc->ver->fcxosi) 5247 + return; 5248 + 5249 + if (rtwdev->chip->chip_gen == RTW89_CHIP_BE) 5250 + add = R_BE_BTC_CFG; 5251 + else 5252 + add = R_AX_BTC_CFG; 5253 + 5254 + if (mac == RTW89_MAC_0) 5255 + rtw89_write32_clr(rtwdev, add, B_AX_WL_SRC); 5256 + else 5257 + rtw89_write32_set(rtwdev, add, B_AX_WL_SRC); 5258 + } 5259 + 5552 5260 static void _action_common(struct rtw89_dev *rtwdev) 5553 5261 { 5554 5262 struct rtw89_btc *btc = &rtwdev->btc; 5555 5263 struct rtw89_btc_wl_info *wl = &btc->cx.wl; 5264 + struct rtw89_btc_wl_role_info_v8 *rinfo_v8 = &wl->role_info_v8; 5556 5265 struct rtw89_btc_wl_smap *wl_smap = &wl->status.map; 5557 5266 struct rtw89_btc_bt_info *bt = &btc->cx.bt; 5558 5267 struct rtw89_btc_dm *dm = &btc->dm; 5559 5268 u32 bt_rom_code_id, bt_fw_ver; 5269 + 5270 + if (btc->ver->fwlrole == 8) 5271 + _wl_req_mac(rtwdev, rinfo_v8->pta_req_band); 5560 5272 5561 5273 _set_btg_ctrl(rtwdev); 5562 5274 _set_wl_preagc_ctrl(rtwdev); ··· 5625 5273 wl->scbd_change = false; 5626 5274 btc->cx.cnt_wl[BTC_WCNT_SCBDUPDATE]++; 5627 5275 } 5276 + 5277 + if (btc->ver->fcxosi) { 5278 + if (memcmp(&dm->ost_info_last, &dm->ost_info, 5279 + sizeof(dm->ost_info_last)) || 5280 + dm->run_reason == BTC_RSN_NTFY_INIT || 5281 + dm->run_reason == BTC_RSN_NTFY_RADIO_STATE) { 5282 + dm->ost_info_last = dm->ost_info; 5283 + _fw_set_drv_info(rtwdev, CXDRVINFO_OSI); 5284 + } 5285 + } 5628 5286 btc->dm.tdma_instant_excute = 0; 5287 + wl->pta_reg_mac_chg = false; 5629 5288 } 5630 5289 5631 5290 static void _action_by_bt(struct rtw89_dev *rtwdev) ··· 6097 5734 } 6098 5735 6099 5736 return next_state; 6100 - } 6101 - 6102 - static void _wl_req_mac(struct rtw89_dev *rtwdev, u8 mac) 6103 - { 6104 - if (mac == RTW89_MAC_0) 6105 - rtw89_write32_clr(rtwdev, R_AX_BTC_CFG, B_AX_WL_SRC); 6106 - else 6107 - rtw89_write32_set(rtwdev, R_AX_BTC_CFG, B_AX_WL_SRC); 6108 5737 } 6109 5738 6110 5739 static ··· 6594 6239 } 6595 6240 6596 6241 static u8 _chk_dbcc(struct rtw89_dev *rtwdev, struct rtw89_btc_chdef *ch, 6597 - u8 *phy, u8 *role, u8 *dbcc_2g_phy) 6242 + u8 *phy, u8 *role, u8 link_cnt) 6598 6243 { 6599 6244 struct rtw89_btc_wl_info *wl = &rtwdev->btc.cx.wl; 6600 6245 struct rtw89_btc_wl_role_info_v7 *rinfo_v7 = &wl->role_info_v7; 6601 6246 struct rtw89_btc_wl_role_info_v8 *rinfo_v8 = &wl->role_info_v8; 6602 6247 bool is_2g_ch_exist = false, is_multi_role_in_2g_phy = false; 6603 - u8 j, k, dbcc_2g_cid, dbcc_2g_cid2, connect_cnt; 6604 - 6605 - if (rtwdev->btc.ver->fwlrole == 7) 6606 - connect_cnt = rinfo_v7->connect_cnt; 6607 - else if (rtwdev->btc.ver->fwlrole == 8) 6608 - connect_cnt = rinfo_v8->connect_cnt; 6609 - else 6610 - return BTC_WLINK_NOLINK; 6248 + u8 j, k, dbcc_2g_cid, dbcc_2g_cid2, dbcc_2g_phy, pta_req_band; 6611 6249 6612 6250 /* find out the 2G-PHY by connect-id ->ch */ 6613 - for (j = 0; j < connect_cnt; j++) { 6251 + for (j = 0; j < link_cnt; j++) { 6614 6252 if (ch[j].center_ch <= 14) { 6615 6253 is_2g_ch_exist = true; 6616 6254 break; ··· 6612 6264 6613 6265 /* If no any 2G-port exist, it's impossible because 5G-exclude */ 6614 6266 if (!is_2g_ch_exist) 6615 - return BTC_WLINK_OTHER; 6267 + return BTC_WLINK_5G; 6616 6268 6617 6269 dbcc_2g_cid = j; 6618 - *dbcc_2g_phy = phy[dbcc_2g_cid]; 6270 + dbcc_2g_phy = phy[dbcc_2g_cid]; 6271 + 6272 + if (dbcc_2g_phy == RTW89_PHY_1) 6273 + pta_req_band = RTW89_PHY_1; 6274 + else 6275 + pta_req_band = RTW89_PHY_0; 6276 + 6277 + if (rtwdev->btc.ver->fwlrole == 7) { 6278 + rinfo_v7->dbcc_2g_phy = dbcc_2g_phy; 6279 + } else if (rtwdev->btc.ver->fwlrole == 8) { 6280 + rinfo_v8->dbcc_2g_phy = dbcc_2g_phy; 6281 + rinfo_v8->pta_req_band = pta_req_band; 6282 + } 6619 6283 6620 6284 /* connect_cnt <= 2 */ 6621 - if (connect_cnt < BTC_TDMA_WLROLE_MAX) 6285 + if (link_cnt < BTC_TDMA_WLROLE_MAX) 6622 6286 return (_get_role_link_mode((role[dbcc_2g_cid]))); 6623 6287 6624 6288 /* find the other-port in the 2G-PHY, ex: PHY-0:6G, PHY1: mcc/scc */ 6625 - for (k = 0; k < connect_cnt; k++) { 6289 + for (k = 0; k < link_cnt; k++) { 6626 6290 if (k == dbcc_2g_cid) 6627 6291 continue; 6628 6292 6629 - if (phy[k] == *dbcc_2g_phy) { 6293 + if (phy[k] == dbcc_2g_phy) { 6630 6294 is_multi_role_in_2g_phy = true; 6631 6295 dbcc_2g_cid2 = k; 6632 6296 break; ··· 6840 6480 } else if (cnt > BTC_TDMA_WLROLE_MAX) { 6841 6481 mode = BTC_WLINK_OTHER; 6842 6482 } else if (rtwdev->dbcc_en) { 6843 - mode = _chk_dbcc(rtwdev, cid_ch, cid_phy, cid_role, &dbcc_2g_phy); 6483 + mode = _chk_dbcc(rtwdev, cid_ch, cid_phy, cid_role, cnt); 6844 6484 6845 6485 /* correct 2G-located PHY band for gnt ctrl */ 6846 6486 if (dbcc_2g_phy < RTW89_PHY_NUM) ··· 6885 6525 _fw_set_drv_info(rtwdev, CXDRVINFO_ROLE); 6886 6526 } 6887 6527 6528 + static u8 _update_wl_link_mode(struct rtw89_dev *rtwdev, u8 hw_band, u8 type) 6529 + { 6530 + struct rtw89_btc_wl_info *wl = &rtwdev->btc.cx.wl; 6531 + struct rtw89_btc_wl_mlo_info *mlo_info = &wl->mlo_info; 6532 + u8 mode = BTC_WLINK_NOLINK; 6533 + 6534 + switch (type) { 6535 + case RTW89_MR_WTYPE_NONE: /* no-link */ 6536 + mode = BTC_WLINK_NOLINK; 6537 + break; 6538 + case RTW89_MR_WTYPE_NONMLD: /* Non_MLO 1-role 2+0/0+2 */ 6539 + case RTW89_MR_WTYPE_MLD1L1R: /* MLO only-1 link 2+0/0+2 */ 6540 + if (mlo_info->hwb_rf_band[hw_band] != RTW89_BAND_2G) { 6541 + mode = BTC_WLINK_5G; 6542 + } else if (mlo_info->wmode[hw_band] == RTW89_MR_WMODE_1AP) { 6543 + mode = BTC_WLINK_2G_GO; 6544 + } else if (mlo_info->wmode[hw_band] == RTW89_MR_WMODE_1CLIENT) { 6545 + if (wl->role_info_v8.p2p_2g) 6546 + mode = BTC_WLINK_2G_GC; 6547 + else 6548 + mode = BTC_WLINK_2G_STA; 6549 + } 6550 + break; 6551 + case RTW89_MR_WTYPE_NONMLD_NONMLD: /* Non_MLO 2-role 2+0/0+2 */ 6552 + case RTW89_MR_WTYPE_MLD1L1R_NONMLD: /* MLO only-1 link + P2P 2+0/0+2 */ 6553 + if (mlo_info->hwb_rf_band[hw_band] != RTW89_BAND_2G) { 6554 + mode = BTC_WLINK_5G; 6555 + } else if (mlo_info->ch_type[hw_band] == RTW89_MR_CTX2_2GHZ_5GHZ || 6556 + mlo_info->ch_type[hw_band] == RTW89_MR_CTX2_2GHZ_6GHZ) { 6557 + mode = BTC_WLINK_25G_MCC; 6558 + } else if (mlo_info->ch_type[hw_band] == RTW89_MR_CTX2_2GHZ) { 6559 + mode = BTC_WLINK_2G_MCC; 6560 + } else if (mlo_info->ch_type[hw_band] == RTW89_MR_CTX1_2GHZ) { 6561 + mode = BTC_WLINK_2G_SCC; 6562 + } 6563 + break; 6564 + case RTW89_MR_WTYPE_MLD2L1R: /* MLO_MLSR 2+0/0+2 */ 6565 + if (mlo_info->hwb_rf_band[hw_band] != RTW89_BAND_2G) 6566 + mode = BTC_WLINK_5G; 6567 + else if (wl->role_info_v8.p2p_2g) 6568 + mode = BTC_WLINK_2G_GC; 6569 + else 6570 + mode = BTC_WLINK_2G_STA; 6571 + break; 6572 + case RTW89_MR_WTYPE_MLD2L1R_NONMLD: /* MLO_MLSR + P2P 2+0/0+2 */ 6573 + case RTW89_MR_WTYPE_MLD2L2R_NONMLD: /* MLO_MLMR + P2P 1+1/2+2 */ 6574 + /* driver may doze 1-link to 6575 + * 2G+5G -> TDMA slot switch by E2G/E5G 6576 + * 5G only -> TDMA slot switch by E5G 6577 + */ 6578 + mode = BTC_WLINK_25G_MCC; 6579 + break; 6580 + case RTW89_MR_WTYPE_MLD2L2R: /* MLO_MLMR 1+1/2+2 */ 6581 + if (mlo_info->hwb_rf_band[hw_band] != RTW89_BAND_2G) { 6582 + mode = BTC_WLINK_5G; 6583 + } else if (mlo_info->wmode[hw_band] == RTW89_MR_WMODE_1AP) { 6584 + mode = BTC_WLINK_2G_GO; 6585 + } else if (mlo_info->wmode[hw_band] == RTW89_MR_WMODE_1CLIENT) { 6586 + if (wl->role_info_v8.p2p_2g) 6587 + mode = BTC_WLINK_2G_GC; 6588 + else 6589 + mode = BTC_WLINK_2G_STA; 6590 + } 6591 + break; 6592 + } 6593 + return mode; 6594 + } 6595 + 6596 + static void _update_wl_mlo_info(struct rtw89_dev *rtwdev) 6597 + { 6598 + struct rtw89_btc_wl_info *wl = &rtwdev->btc.cx.wl; 6599 + struct rtw89_btc_wl_role_info_v8 *wl_rinfo = &wl->role_info_v8; 6600 + struct rtw89_btc_wl_mlo_info *mlo_info = &wl->mlo_info; 6601 + struct rtw89_mr_chanctx_info qinfo; 6602 + u8 track_band = RTW89_PHY_0; 6603 + u8 rf_band = RTW89_BAND_2G; 6604 + u8 i, type; 6605 + 6606 + /* parse MLO info form PHL API for each HW-band */ 6607 + for (i = RTW89_MAC_0; i <= RTW89_MAC_1; i++) { 6608 + memset(&qinfo, 0, sizeof(qinfo)); 6609 + 6610 + rtw89_query_mr_chanctx_info(rtwdev, i, &qinfo); 6611 + mlo_info->wmode[i] = qinfo.wmode; 6612 + mlo_info->ch_type[i] = qinfo.ctxtype; 6613 + mlo_info->wtype = qinfo.wtype; 6614 + 6615 + if (mlo_info->ch_type[i] == RTW89_MR_CTX1_5GHZ || 6616 + mlo_info->ch_type[i] == RTW89_MR_CTX2_5GHZ || 6617 + mlo_info->ch_type[i] == RTW89_MR_CTX2_5GHZ_6GHZ) 6618 + mlo_info->hwb_rf_band[i] = RTW89_BAND_5G; 6619 + else if (mlo_info->ch_type[i] == RTW89_MR_CTX1_6GHZ || 6620 + mlo_info->ch_type[i] == RTW89_MR_CTX2_6GHZ) 6621 + mlo_info->hwb_rf_band[i] = RTW89_BAND_6G; 6622 + else /* check if "2G-included" or unknown in each HW-band */ 6623 + mlo_info->hwb_rf_band[i] = RTW89_BAND_2G; 6624 + } 6625 + 6626 + mlo_info->link_status = rtwdev->mlo_dbcc_mode; 6627 + type = mlo_info->wtype; 6628 + 6629 + if (mlo_info->wtype == RTW89_MR_WTYPE_MLD1L1R || 6630 + mlo_info->wtype == RTW89_MR_WTYPE_MLD2L1R || 6631 + mlo_info->wtype == RTW89_MR_WTYPE_MLD2L2R || 6632 + mlo_info->wtype == RTW89_MR_WTYPE_MLD1L1R_NONMLD || 6633 + mlo_info->wtype == RTW89_MR_WTYPE_MLD2L1R_NONMLD || 6634 + mlo_info->wtype == RTW89_MR_WTYPE_MLD2L2R_NONMLD) 6635 + mlo_info->mlo_en = 1; 6636 + else 6637 + mlo_info->mlo_en = 0; 6638 + 6639 + if (mlo_info->ch_type[RTW89_MAC_0] != RTW89_MR_CTX_NONE && 6640 + mlo_info->ch_type[RTW89_MAC_0] != RTW89_MR_CTX_UNKNOWN && 6641 + mlo_info->ch_type[RTW89_MAC_1] != RTW89_MR_CTX_NONE && 6642 + mlo_info->ch_type[RTW89_MAC_1] != RTW89_MR_CTX_UNKNOWN) 6643 + mlo_info->dual_hw_band_en = 1; /* two HW-hand link exist */ 6644 + else 6645 + mlo_info->dual_hw_band_en = 0; 6646 + 6647 + if (mlo_info->link_status == MLO_2_PLUS_0_2RF || 6648 + mlo_info->link_status == MLO_0_PLUS_2_2RF || 6649 + mlo_info->link_status == MLO_2_PLUS_2_2RF) 6650 + mlo_info->mlo_adie = 2; 6651 + else 6652 + mlo_info->mlo_adie = 1; 6653 + 6654 + switch (mlo_info->link_status) { 6655 + default: 6656 + case MLO_2_PLUS_0_1RF: /* 2+0 */ 6657 + case MLO_2_PLUS_0_2RF: 6658 + mlo_info->rf_combination = BTC_MLO_RF_2_PLUS_0; 6659 + track_band = RTW89_MAC_0; 6660 + rf_band = mlo_info->hwb_rf_band[RTW89_MAC_0]; 6661 + mlo_info->path_rf_band[BTC_RF_S0] = rf_band; 6662 + mlo_info->path_rf_band[BTC_RF_S1] = rf_band; 6663 + 6664 + wl_rinfo->pta_req_band = RTW89_MAC_0; 6665 + wl_rinfo->dbcc_2g_phy = RTW89_PHY_0; 6666 + wl_rinfo->dbcc_en = 0; 6667 + break; 6668 + case MLO_0_PLUS_2_1RF: /* 0+2 */ 6669 + case MLO_0_PLUS_2_2RF: 6670 + mlo_info->rf_combination = BTC_MLO_RF_0_PLUS_2; 6671 + track_band = RTW89_MAC_1; 6672 + rf_band = mlo_info->hwb_rf_band[RTW89_MAC_1]; 6673 + mlo_info->path_rf_band[BTC_RF_S0] = rf_band; 6674 + mlo_info->path_rf_band[BTC_RF_S1] = rf_band; 6675 + 6676 + wl_rinfo->pta_req_band = RTW89_MAC_1; 6677 + wl_rinfo->dbcc_2g_phy = RTW89_PHY_1; 6678 + wl_rinfo->dbcc_en = 0; 6679 + break; 6680 + case MLO_1_PLUS_1_1RF: /* 1+1 */ 6681 + case MLO_1_PLUS_1_2RF: /* 1+1 */ 6682 + case MLO_2_PLUS_2_2RF: /* 2+2 */ 6683 + case DBCC_LEGACY: /* DBCC 1+1 */ 6684 + if (mlo_info->link_status == MLO_2_PLUS_2_2RF) 6685 + mlo_info->rf_combination = BTC_MLO_RF_2_PLUS_2; 6686 + else 6687 + mlo_info->rf_combination = BTC_MLO_RF_1_PLUS_1; 6688 + 6689 + if (mlo_info->hwb_rf_band[RTW89_MAC_0] == RTW89_BAND_2G) 6690 + track_band = RTW89_MAC_0; 6691 + else 6692 + track_band = RTW89_MAC_1; 6693 + 6694 + mlo_info->path_rf_band[BTC_RF_S0] = 6695 + mlo_info->hwb_rf_band[RTW89_MAC_0]; 6696 + mlo_info->path_rf_band[BTC_RF_S1] = 6697 + mlo_info->hwb_rf_band[RTW89_MAC_1]; 6698 + 6699 + /* Check ch count from ch_type @ 2.4G HW-band, and modify type */ 6700 + if (mlo_info->ch_type[track_band] == RTW89_MR_CTX1_2GHZ) 6701 + type = RTW89_MR_WTYPE_NONMLD; /* only 1-role at 2G */ 6702 + else 6703 + type = RTW89_MR_WTYPE_NONMLD_NONMLD; 6704 + 6705 + if (mlo_info->hwb_rf_band[RTW89_MAC_0] == RTW89_BAND_2G) { 6706 + wl_rinfo->pta_req_band = RTW89_MAC_0; 6707 + wl_rinfo->dbcc_2g_phy = RTW89_PHY_0; 6708 + } else { 6709 + wl_rinfo->pta_req_band = RTW89_MAC_1; 6710 + wl_rinfo->dbcc_2g_phy = RTW89_PHY_1; 6711 + } 6712 + 6713 + if (mlo_info->wmode[RTW89_MAC_0] == RTW89_MR_WMODE_NONE && 6714 + mlo_info->wmode[RTW89_MAC_1] == RTW89_MR_WMODE_NONE) 6715 + wl_rinfo->dbcc_en = 0; 6716 + else 6717 + wl_rinfo->dbcc_en = 1; 6718 + break; 6719 + } 6720 + 6721 + wl_rinfo->link_mode = _update_wl_link_mode(rtwdev, track_band, type); 6722 + 6723 + rtw89_debug(rtwdev, RTW89_DBG_BTC, "[BTC], %s(), mode=%s, pta_band=%d", 6724 + __func__, id_to_linkmode(wl_rinfo->link_mode), 6725 + wl_rinfo->pta_req_band); 6726 + } 6727 + 6728 + static void _update_wl_non_mlo_info(struct rtw89_dev *rtwdev) 6729 + { 6730 + struct rtw89_btc_wl_info *wl = &rtwdev->btc.cx.wl; 6731 + struct rtw89_btc_wl_rlink *rlink = NULL; 6732 + struct rtw89_btc_wl_role_info_v8 *wl_rinfo = &wl->role_info_v8; 6733 + struct rtw89_btc_chdef cid_ch[RTW89_BE_BTC_WL_MAX_ROLE_NUMBER] = {}; 6734 + u8 cid_role[RTW89_BE_BTC_WL_MAX_ROLE_NUMBER] = {}; 6735 + u8 cid_phy[RTW89_BE_BTC_WL_MAX_ROLE_NUMBER] = {}; 6736 + bool b2g = false, b5g = false, outloop = false; 6737 + u8 mode = BTC_WLINK_NOLINK; 6738 + u8 cnt_2g = 0, cnt_5g = 0; 6739 + u8 i, j, cnt = 0; 6740 + 6741 + for (j = RTW89_PHY_0; j < RTW89_PHY_NUM; j++) { 6742 + for (i = 0; i < RTW89_BE_BTC_WL_MAX_ROLE_NUMBER; i++) { 6743 + rlink = &wl_rinfo->rlink[i][j]; 6744 + 6745 + if (!rlink->active || !rlink->connected) 6746 + continue; 6747 + 6748 + if (cnt >= RTW89_BE_BTC_WL_MAX_ROLE_NUMBER) { 6749 + outloop = true; 6750 + break; 6751 + } 6752 + 6753 + cid_ch[cnt] = wl->rlink_info[i][j].chdef; 6754 + cid_phy[cnt] = rlink->phy; 6755 + cid_role[cnt] = rlink->role; 6756 + cnt++; 6757 + 6758 + if (rlink->rf_band != RTW89_BAND_2G) { 6759 + cnt_5g++; 6760 + b5g = true; 6761 + } else { 6762 + cnt_2g++; 6763 + b2g = true; 6764 + } 6765 + } 6766 + if (outloop) 6767 + break; 6768 + } 6769 + 6770 + rtw89_debug(rtwdev, RTW89_DBG_BTC, 6771 + "[BTC], %s(): cnt_2g=%d, cnt_5g=%d\n", __func__, cnt_2g, cnt_5g); 6772 + 6773 + wl_rinfo->dbcc_en = rtwdev->dbcc_en; 6774 + /* Be careful to change the following sequence!! */ 6775 + if (cnt == 0) { 6776 + mode = BTC_WLINK_NOLINK; 6777 + } else if (!b2g && b5g) { 6778 + mode = BTC_WLINK_5G; 6779 + } else if (wl_rinfo->dbcc_en) { 6780 + mode = _chk_dbcc(rtwdev, cid_ch, cid_phy, cid_role, cnt); 6781 + } else if (b2g && b5g) { 6782 + mode = BTC_WLINK_25G_MCC; 6783 + } else if (!b5g && cnt >= 2) { 6784 + if (_chk_role_ch_group(&cid_ch[0], &cid_ch[1])) 6785 + mode = BTC_WLINK_2G_SCC; 6786 + else 6787 + mode = BTC_WLINK_2G_MCC; 6788 + } else if (!b5g) { /* cnt_connect = 1 */ 6789 + mode = _get_role_link_mode(cid_role[0]); 6790 + } 6791 + 6792 + wl_rinfo->link_mode = mode; 6793 + } 6794 + 6795 + static void _modify_role_link_mode(struct rtw89_dev *rtwdev) 6796 + { 6797 + struct rtw89_btc_wl_info *wl = &rtwdev->btc.cx.wl; 6798 + struct rtw89_btc_wl_role_info_v8 *wl_rinfo = &wl->role_info_v8; 6799 + u8 go_cleint_exist = wl->go_client_exist; 6800 + u8 link_mode = wl_rinfo->link_mode; 6801 + u32 role_map = wl_rinfo->role_map; 6802 + u8 noa_exist = wl->noa_exist; 6803 + u32 mrole = BTC_WLMROLE_NONE; 6804 + 6805 + /* if no client_joined, don't care P2P-GO/AP role */ 6806 + if (((role_map & BIT(RTW89_WIFI_ROLE_P2P_GO)) || 6807 + (role_map & BIT(RTW89_WIFI_ROLE_AP))) && !go_cleint_exist) { 6808 + if (link_mode == BTC_WLINK_2G_SCC) { 6809 + wl_rinfo->link_mode = BTC_WLINK_2G_STA; 6810 + } else if (link_mode == BTC_WLINK_2G_GO || 6811 + link_mode == BTC_WLINK_2G_AP) { 6812 + wl_rinfo->link_mode = BTC_WLINK_NOLINK; 6813 + } 6814 + } 6815 + 6816 + /* Identify 2-Role type */ 6817 + if (link_mode == BTC_WLINK_2G_SCC || 6818 + link_mode == BTC_WLINK_2G_MCC || 6819 + link_mode == BTC_WLINK_25G_MCC || 6820 + link_mode == BTC_WLINK_5G) { 6821 + if ((role_map & BIT(RTW89_WIFI_ROLE_P2P_GO)) || 6822 + (role_map & BIT(RTW89_WIFI_ROLE_AP))) { 6823 + if (noa_exist) 6824 + mrole = BTC_WLMROLE_STA_GO_NOA; 6825 + else 6826 + mrole = BTC_WLMROLE_STA_GO; 6827 + } else if (role_map & BIT(RTW89_WIFI_ROLE_P2P_CLIENT)) { 6828 + if (noa_exist) 6829 + mrole = BTC_WLMROLE_STA_GC_NOA; 6830 + else 6831 + mrole = BTC_WLMROLE_STA_GC; 6832 + } else { 6833 + mrole = BTC_WLMROLE_STA_STA; 6834 + } 6835 + } 6836 + 6837 + wl_rinfo->mrole_type = mrole; 6838 + 6839 + rtw89_debug(rtwdev, RTW89_DBG_BTC, 6840 + "[BTC], %s(): link_mode=%s, mrole_type=%d\n", __func__, 6841 + id_to_linkmode(wl_rinfo->link_mode), wl_rinfo->mrole_type); 6842 + } 6843 + 6888 6844 static void _update_wl_info_v8(struct rtw89_dev *rtwdev, u8 role_id, u8 rlink_id, 6889 6845 enum btc_role_state state) 6890 6846 { 6847 + struct rtw89_btc_wl_rlink *rlink = NULL; 6848 + struct rtw89_btc_wl_link_info *wl_linfo; 6891 6849 struct rtw89_btc *btc = &rtwdev->btc; 6892 6850 struct rtw89_btc_wl_info *wl = &btc->cx.wl; 6893 - struct rtw89_btc_chdef cid_ch[RTW89_BE_BTC_WL_MAX_ROLE_NUMBER]; 6894 6851 struct rtw89_btc_wl_role_info_v8 *wl_rinfo = &wl->role_info_v8; 6895 - struct rtw89_btc_wl_dbcc_info *wl_dinfo = &wl->dbcc_info; 6896 - bool client_joined = false, b2g = false, b5g = false; 6897 - u8 cid_role[RTW89_BE_BTC_WL_MAX_ROLE_NUMBER] = {}; 6898 - u8 cid_phy[RTW89_BE_BTC_WL_MAX_ROLE_NUMBER] = {}; 6899 - u8 dbcc_en = 0, pta_req_band = RTW89_MAC_0; 6900 - u8 i, j, cnt = 0, cnt_2g = 0, cnt_5g = 0; 6901 - struct rtw89_btc_wl_link_info *wl_linfo; 6902 - struct rtw89_btc_wl_rlink *rlink = NULL; 6903 - u8 dbcc_2g_phy = RTW89_PHY_0; 6904 - u8 mode = BTC_WLINK_NOLINK; 6905 - u32 noa_dur = 0; 6852 + bool client_joined = false, noa_exist = false, p2p_exist = false; 6853 + bool is_5g_hi_channel = false, bg_mode = false, dbcc_en_ori; 6854 + u8 i, j, link_mode_ori; 6855 + u32 role_map = 0; 6906 6856 6907 - if (role_id >= RTW89_BE_BTC_WL_MAX_ROLE_NUMBER || rlink_id > RTW89_MAC_1) 6857 + if (role_id >= RTW89_BE_BTC_WL_MAX_ROLE_NUMBER || rlink_id >= RTW89_MAC_NUM) 6908 6858 return; 6909 6859 6910 6860 /* Extract wl->link_info[role_id][rlink_id] to wl->role_info ··· 7224 6554 */ 7225 6555 7226 6556 wl_linfo = &wl->rlink_info[role_id][rlink_id]; 7227 - if (wl_linfo->connected == MLME_LINKING) 7228 - return; 7229 - 7230 6557 rlink = &wl_rinfo->rlink[role_id][rlink_id]; 6558 + 7231 6559 rlink->role = wl_linfo->role; 7232 6560 rlink->active = wl_linfo->active; /* Doze or not */ 7233 6561 rlink->pid = wl_linfo->pid; ··· 7241 6573 switch (wl_linfo->connected) { 7242 6574 case MLME_NO_LINK: 7243 6575 rlink->connected = 0; 7244 - if (rlink->role == RTW89_WIFI_ROLE_STATION) 7245 - btc->dm.leak_ap = 0; 7246 6576 break; 7247 6577 case MLME_LINKED: 7248 6578 rlink->connected = 1; ··· 7249 6583 return; 7250 6584 } 7251 6585 7252 - wl->is_5g_hi_channel = false; 7253 - wl->bg_mode = false; 7254 - wl_rinfo->role_map = 0; 7255 - wl_rinfo->p2p_2g = 0; 7256 - memset(cid_ch, 0, sizeof(cid_ch)); 7257 - 7258 - for (i = 0; i < RTW89_BE_BTC_WL_MAX_ROLE_NUMBER; i++) { 7259 - for (j = RTW89_MAC_0; j <= RTW89_MAC_1; j++) { 6586 + for (j = RTW89_MAC_0; j <= RTW89_MAC_1; j++) { 6587 + for (i = 0; i < RTW89_BE_BTC_WL_MAX_ROLE_NUMBER; i++) { 7260 6588 rlink = &wl_rinfo->rlink[i][j]; 7261 6589 7262 6590 if (!rlink->active || !rlink->connected) 7263 6591 continue; 7264 6592 7265 - cnt++; 7266 - wl_rinfo->role_map |= BIT(rlink->role); 6593 + role_map |= BIT(rlink->role); 6594 + 6595 + /* only one noa-role exist */ 6596 + if (rlink->noa && rlink->noa_dur > 0) 6597 + noa_exist = true; 6598 + 6599 + /* for WL 5G-Rx interfered with BT issue */ 6600 + if (rlink->rf_band == RTW89_BAND_5G) { 6601 + if (rlink->ch >= 100) 6602 + is_5g_hi_channel = true; 6603 + 6604 + continue; 6605 + } 7267 6606 7268 6607 /* only if client connect for p2p-Go/AP */ 7269 6608 if ((rlink->role == RTW89_WIFI_ROLE_P2P_GO || 7270 6609 rlink->role == RTW89_WIFI_ROLE_AP) && 7271 - rlink->client_cnt > 1) 6610 + rlink->client_cnt > 1) { 6611 + p2p_exist = true; 7272 6612 client_joined = true; 6613 + } 7273 6614 7274 - /* Identufy if P2P-Go (GO/GC/AP) exist at 2G band*/ 7275 - if (rlink->rf_band == RTW89_BAND_2G && 7276 - (client_joined || rlink->role == RTW89_WIFI_ROLE_P2P_CLIENT)) 7277 - wl_rinfo->p2p_2g = 1; 7278 - 7279 - /* only one noa-role exist */ 7280 - if (rlink->noa && rlink->noa_dur > 0) 7281 - noa_dur = rlink->noa_dur; 7282 - 7283 - /* for WL 5G-Rx interfered with BT issue */ 7284 - if (rlink->rf_band == RTW89_BAND_5G && rlink->ch >= 100) 7285 - wl->is_5g_hi_channel = 1; 6615 + /* Identify if P2P-Go (GO/GC/AP) exist at 2G band */ 6616 + if (rlink->role == RTW89_WIFI_ROLE_P2P_CLIENT) 6617 + p2p_exist = true; 7286 6618 7287 6619 if ((rlink->mode & BIT(BTC_WL_MODE_11B)) || 7288 6620 (rlink->mode & BIT(BTC_WL_MODE_11G))) 7289 - wl->bg_mode = 1; 7290 - 7291 - if (rtwdev->chip->para_ver & BTC_FEAT_MLO_SUPPORT) 7292 - continue; 7293 - 7294 - cid_ch[cnt - 1] = wl_linfo->chdef; 7295 - cid_phy[cnt - 1] = rlink->phy; 7296 - cid_role[cnt - 1] = rlink->role; 7297 - 7298 - if (rlink->rf_band != RTW89_BAND_2G) { 7299 - cnt_5g++; 7300 - b5g = true; 7301 - } else { 7302 - cnt_2g++; 7303 - b2g = true; 7304 - } 6621 + bg_mode = true; 7305 6622 } 7306 6623 } 6624 + 6625 + link_mode_ori = wl_rinfo->link_mode; 6626 + wl->is_5g_hi_channel = is_5g_hi_channel; 6627 + wl->bg_mode = bg_mode; 6628 + wl->go_client_exist = client_joined; 6629 + wl->noa_exist = noa_exist; 6630 + wl_rinfo->p2p_2g = p2p_exist; 6631 + wl_rinfo->role_map = role_map; 6632 + 6633 + dbcc_en_ori = wl_rinfo->dbcc_en; 7307 6634 7308 6635 if (rtwdev->chip->para_ver & BTC_FEAT_MLO_SUPPORT) { 7309 - rtw89_debug(rtwdev, RTW89_DBG_BTC, 7310 - "[BTC] rlink cnt_2g=%d cnt_5g=%d\n", cnt_2g, cnt_5g); 7311 - rtw89_warn(rtwdev, "not support MLO feature yet"); 6636 + /* for MLO-supported, link-mode from driver directly */ 6637 + _update_wl_mlo_info(rtwdev); 7312 6638 } else { 7313 - dbcc_en = rtwdev->dbcc_en; 7314 - 7315 - /* Be careful to change the following sequence!! */ 7316 - if (cnt == 0) { 7317 - mode = BTC_WLINK_NOLINK; 7318 - } else if (!b2g && b5g) { 7319 - mode = BTC_WLINK_5G; 7320 - } else if (wl_rinfo->role_map & BIT(RTW89_WIFI_ROLE_NAN)) { 7321 - mode = BTC_WLINK_2G_NAN; 7322 - } else if (cnt > BTC_TDMA_WLROLE_MAX) { 7323 - mode = BTC_WLINK_OTHER; 7324 - } else if (dbcc_en) { 7325 - mode = _chk_dbcc(rtwdev, cid_ch, cid_phy, cid_role, 7326 - &dbcc_2g_phy); 7327 - } else if (b2g && b5g && cnt == 2) { 7328 - mode = BTC_WLINK_25G_MCC; 7329 - } else if (!b5g && cnt == 2) { /* cnt_connect = 2 */ 7330 - if (_chk_role_ch_group(&cid_ch[0], &cid_ch[cnt - 1])) 7331 - mode = BTC_WLINK_2G_SCC; 7332 - else 7333 - mode = BTC_WLINK_2G_MCC; 7334 - } else if (!b5g && cnt == 1) { /* cnt_connect = 1 */ 7335 - mode = _get_role_link_mode(cid_role[0]); 7336 - } 6639 + /* for non-MLO-supported, link-mode by BTC */ 6640 + _update_wl_non_mlo_info(rtwdev); 7337 6641 } 7338 6642 7339 - wl_rinfo->link_mode = mode; 7340 - wl_rinfo->connect_cnt = cnt; 7341 - if (wl_rinfo->connect_cnt == 0) 7342 - wl_rinfo->role_map = BIT(RTW89_WIFI_ROLE_NONE); 7343 - _update_role_link_mode(rtwdev, client_joined, noa_dur); 6643 + _modify_role_link_mode(rtwdev); 7344 6644 7345 - wl_rinfo->dbcc_2g_phy = dbcc_2g_phy; 7346 - if (wl_rinfo->dbcc_en != dbcc_en) { 7347 - wl_rinfo->dbcc_en = dbcc_en; 7348 - wl_rinfo->dbcc_chg = 1; 6645 + if (link_mode_ori != wl_rinfo->link_mode) 6646 + wl->link_mode_chg = true; 6647 + 6648 + if (wl_rinfo->dbcc_en != dbcc_en_ori) { 6649 + wl->dbcc_chg = true; 7349 6650 btc->cx.cnt_wl[BTC_WCNT_DBCC_CHG]++; 7350 - } else { 7351 - wl_rinfo->dbcc_chg = 0; 7352 6651 } 7353 - 7354 - if (wl_rinfo->dbcc_en) { 7355 - memset(wl_dinfo, 0, sizeof(struct rtw89_btc_wl_dbcc_info)); 7356 - 7357 - if (mode == BTC_WLINK_5G) { 7358 - pta_req_band = RTW89_PHY_0; 7359 - wl_dinfo->op_band[RTW89_PHY_0] = RTW89_BAND_5G; 7360 - wl_dinfo->op_band[RTW89_PHY_1] = RTW89_BAND_2G; 7361 - } else if (wl_rinfo->dbcc_2g_phy == RTW89_PHY_1) { 7362 - pta_req_band = RTW89_PHY_1; 7363 - wl_dinfo->op_band[RTW89_PHY_0] = RTW89_BAND_5G; 7364 - wl_dinfo->op_band[RTW89_PHY_1] = RTW89_BAND_2G; 7365 - } else { 7366 - pta_req_band = RTW89_PHY_0; 7367 - wl_dinfo->op_band[RTW89_PHY_0] = RTW89_BAND_2G; 7368 - wl_dinfo->op_band[RTW89_PHY_1] = RTW89_BAND_5G; 7369 - } 7370 - _update_dbcc_band(rtwdev, RTW89_PHY_0); 7371 - _update_dbcc_band(rtwdev, RTW89_PHY_1); 7372 - } 7373 - 7374 - wl_rinfo->pta_req_band = pta_req_band; 7375 - _fw_set_drv_info(rtwdev, CXDRVINFO_ROLE); 7376 6652 } 7377 6653 7378 6654 void rtw89_coex_act1_work(struct wiphy *wiphy, struct wiphy_work *work) ··· 7437 6829 bt->rfk_info.map.req = !!(val & BTC_BSCB_RFK_REQ); 7438 6830 bt->hi_lna_rx = !!(val & BTC_BSCB_BT_HILNA); 7439 6831 bt->link_info.status.map.connect = !!(val & BTC_BSCB_BT_CONNECT); 6832 + if (bt->run_patch_code != !!(val & BTC_BSCB_PATCH_CODE)) 6833 + status_change = true; 7440 6834 bt->run_patch_code = !!(val & BTC_BSCB_PATCH_CODE); 7441 6835 7442 6836 if (!only_update && status_change) 7443 6837 _run_coex(rtwdev, BTC_RSN_UPDATE_BT_SCBD); 6838 + } 6839 + 6840 + #define BTC_BTINFO_PWR_LEN 5 6841 + static void _update_bt_txpwr_info(struct rtw89_dev *rtwdev, u8 *buf, u32 len) 6842 + { 6843 + struct rtw89_btc_bt_info *bt = &rtwdev->btc.cx.bt; 6844 + struct rtw89_btc_bt_link_info *b = &bt->link_info; 6845 + 6846 + if (len != BTC_BTINFO_PWR_LEN) 6847 + return; 6848 + 6849 + if (!memcmp(bt->txpwr_info, buf, sizeof(bt->txpwr_info))) { 6850 + rtw89_debug(rtwdev, RTW89_DBG_BTC, 6851 + "[BTC], %s return by info duplicate!\n", __func__); 6852 + return; 6853 + } 6854 + 6855 + memcpy(bt->txpwr_info, buf, BTC_BTINFO_MAX); 6856 + memcpy(&b->bt_txpwr_desc, &buf[2], sizeof(b->bt_txpwr_desc)); 7444 6857 } 7445 6858 7446 6859 static bool _chk_wl_rfk_request(struct rtw89_dev *rtwdev) ··· 8247 7618 8248 7619 wlinfo = &wl->link_info[r.pid]; 8249 7620 8250 - rlink_id = 0; /* to do */ 8251 7621 if (ver->fwlrole == 0) { 8252 7622 *wlinfo = r; 8253 7623 _update_wl_info(rtwdev); ··· 8260 7632 *wlinfo = r; 8261 7633 _update_wl_info_v7(rtwdev, r.pid); 8262 7634 } else if (ver->fwlrole == 8) { 7635 + rlink_id = rtwvif_link->mac_idx; 8263 7636 wlinfo = &wl->rlink_info[r.pid][rlink_id]; 8264 7637 *wlinfo = r; 8265 7638 link_mode_ori = wl->role_info_v8.link_mode; ··· 8505 7876 rssi = ewma_rssi_read(&rtwsta_link->avg_rssi) >> RSSI_FACTOR; 8506 7877 rtw89_debug(rtwdev, RTW89_DBG_BTC, "[BTC], rssi=%d\n", rssi); 8507 7878 8508 - link_info = &wl->link_info[port]; 7879 + if (btc->ver->fwlrole != 8) 7880 + link_info = &wl->link_info[port]; 7881 + else 7882 + link_info = &wl->rlink_info[port][rtwvif_link->mac_idx]; 7883 + 8509 7884 link_info->stat.traffic = *stats; 8510 7885 link_info_t = &link_info->stat.traffic; 8511 7886 ··· 8590 7957 r1->active_role_v1[port].rx_lvl = stats->rx_tfc_lv; 8591 7958 r1->active_role_v1[port].tx_rate = rtwsta_link->ra_report.hw_rate; 8592 7959 r1->active_role_v1[port].rx_rate = rtwsta_link->rx_hw_rate; 8593 - } else if (ver->fwlrole == 2) { 8594 - dm->trx_info.tx_lvl = stats->tx_tfc_lv; 8595 - dm->trx_info.rx_lvl = stats->rx_tfc_lv; 8596 - dm->trx_info.tx_rate = rtwsta_link->ra_report.hw_rate; 8597 - dm->trx_info.rx_rate = rtwsta_link->rx_hw_rate; 8598 7960 } 8599 7961 7962 + dm->trx_info.tx_lvl = stats->tx_tfc_lv; 7963 + dm->trx_info.rx_lvl = stats->rx_tfc_lv; 7964 + dm->trx_info.tx_rate = rtwsta_link->ra_report.hw_rate; 7965 + dm->trx_info.rx_rate = rtwsta_link->rx_hw_rate; 8600 7966 dm->trx_info.tx_tp = link_info_t->tx_throughput; 8601 7967 dm->trx_info.rx_tp = link_info_t->rx_throughput; 8602 7968 ··· 8702 8070 return BTF_EVNT_BUF_OVERFLOW; 8703 8071 else if (ver->fwc2hfunc == 2) 8704 8072 return func; 8073 + else if (ver->fwc2hfunc == 3) 8074 + return BTF_EVNT_BUF_OVERFLOW; 8705 8075 else 8706 8076 return BTF_EVNT_MAX; 8707 8077 case BTF_EVNT_BUF_OVERFLOW: ··· 8713 8079 return BTF_EVNT_C2H_LOOPBACK; 8714 8080 else if (ver->fwc2hfunc == 2) 8715 8081 return func; 8082 + else if (ver->fwc2hfunc == 3) 8083 + return BTF_EVNT_C2H_LOOPBACK; 8716 8084 else 8717 8085 return BTF_EVNT_MAX; 8718 8086 case BTF_EVNT_C2H_LOOPBACK: 8719 8087 if (ver->fwc2hfunc == 2) 8088 + return func; 8089 + else if (ver->fwc2hfunc == 3) 8090 + return BTF_EVNT_BT_LEAUDIO_INFO; 8091 + else 8092 + return BTF_EVNT_MAX; 8093 + case BTF_EVNT_BT_QUERY_TXPWR: 8094 + if (ver->fwc2hfunc == 3) 8720 8095 return func; 8721 8096 else 8722 8097 return BTF_EVNT_MAX; ··· 8789 8146 case BTF_EVNT_CX_RUNINFO: 8790 8147 btc->dm.cnt_dm[BTC_DCNT_CX_RUNINFO]++; 8791 8148 break; 8149 + case BTF_EVNT_BT_QUERY_TXPWR: 8150 + btc->cx.cnt_bt[BTC_BCNT_BTTXPWR_UPDATE]++; 8151 + _update_bt_txpwr_info(rtwdev, buf, len); 8792 8152 } 8793 8153 } 8794 8154 ··· 8814 8168 if (!(dm->coex_info_map & BTC_COEX_INFO_CX)) 8815 8169 return 0; 8816 8170 8817 - dm->cnt_notify[BTC_NCNT_SHOW_COEX_INFO]++; 8818 - 8819 8171 p += scnprintf(p, end - p, 8820 - "========== [BTC COEX INFO (%d)] ==========\n", 8821 - chip->chip_id); 8172 + "\n========== [BTC COEX INFO (%s)] ==========\n", 8173 + chip_id_str(chip->chip_id)); 8822 8174 8823 8175 ver_main = FIELD_GET(GENMASK(31, 24), RTW89_COEX_VERSION); 8824 8176 ver_sub = FIELD_GET(GENMASK(23, 16), RTW89_COEX_VERSION); ··· 8842 8198 8843 8199 p += scnprintf(p, end - p, "BT_FW_coex:%d(%s, desired:%d)\n", 8844 8200 bt->ver_info.fw_coex, 8845 - (bt->ver_info.fw_coex >= chip->btcx_desired ? 8846 - "Match" : "Mismatch"), chip->btcx_desired); 8201 + (bt->ver_info.fw_coex >= ver->bt_desired ? 8202 + "Match" : "Mismatch"), ver->bt_desired); 8847 8203 8848 8204 if (bt->enable.now && bt->ver_info.fw == 0) 8849 8205 rtw89_btc_fw_en_rpt(rtwdev, RPT_EN_BT_VER_INFO, true); ··· 8892 8248 { 8893 8249 struct rtw89_btc *btc = &rtwdev->btc; 8894 8250 struct rtw89_btc_wl_link_info *plink = NULL; 8895 - struct rtw89_btc_wl_info *wl = &btc->cx.wl; 8896 - struct rtw89_btc_wl_dbcc_info *wl_dinfo = &wl->dbcc_info; 8897 8251 struct rtw89_traffic_stats *t; 8898 8252 char *p = buf, *end = buf + bufsz; 8899 - u8 i; 8253 + u8 i, j; 8900 8254 8901 - if (rtwdev->dbcc_en) { 8902 - p += scnprintf(p, end - p, 8903 - " %-15s : PHY0_band(op:%d/scan:%d/real:%d), ", 8904 - "[dbcc_info]", wl_dinfo->op_band[RTW89_PHY_0], 8905 - wl_dinfo->scan_band[RTW89_PHY_0], 8906 - wl_dinfo->real_band[RTW89_PHY_0]); 8907 - p += scnprintf(p, end - p, 8908 - "PHY1_band(op:%d/scan:%d/real:%d)\n", 8909 - wl_dinfo->op_band[RTW89_PHY_1], 8910 - wl_dinfo->scan_band[RTW89_PHY_1], 8911 - wl_dinfo->real_band[RTW89_PHY_1]); 8255 + for (i = 0; i < btc->ver->max_role_num; i++) { 8256 + for (j = 0; j < RTW89_MAC_NUM; j++) { 8257 + if (btc->ver->fwlrole == 8) 8258 + plink = &btc->cx.wl.rlink_info[i][j]; 8259 + else 8260 + plink = &btc->cx.wl.link_info[i]; 8261 + 8262 + if (!plink->active) 8263 + continue; 8264 + 8265 + p += scnprintf(p, end - p, 8266 + " [port_%d] : role=%d(phy-%d), connect=%s(client_cnt=%d), mode=%d, center_ch=%d, bw=%d", 8267 + plink->pid, plink->role, plink->phy, 8268 + id_to_mlme_state(plink->connected), 8269 + plink->client_cnt - 1, plink->mode, 8270 + plink->ch, plink->bw); 8271 + 8272 + if (plink->connected == MLME_NO_LINK) 8273 + continue; 8274 + 8275 + p += scnprintf(p, end - p, 8276 + ", mac_id=%d, max_tx_time=%dus, max_tx_retry=%d\n", 8277 + plink->mac_id, plink->tx_time, plink->tx_retry); 8278 + 8279 + p += scnprintf(p, end - p, 8280 + " [port_%d] : rssi=-%ddBm(%d), busy=%d, dir=%s, ", 8281 + plink->pid, 110 - plink->stat.rssi, 8282 + plink->stat.rssi, plink->busy, 8283 + plink->dir == RTW89_TFC_UL ? "UL" : "DL"); 8284 + 8285 + t = &plink->stat.traffic; 8286 + 8287 + p += scnprintf(p, end - p, 8288 + "tx[rate:%d/busy_level:%d], ", 8289 + t->tx_rate, t->tx_tfc_lv); 8290 + 8291 + p += scnprintf(p, end - p, 8292 + "rx[rate:%d/busy_level:%d/drop:%d]\n", 8293 + t->rx_rate, 8294 + t->rx_tfc_lv, plink->rx_rate_drop_cnt); 8295 + } 8912 8296 } 8913 - 8914 - for (i = 0; i < RTW89_PORT_NUM; i++) { 8915 - if (btc->ver->fwlrole == 8) 8916 - plink = &btc->cx.wl.rlink_info[i][0]; 8917 - else 8918 - plink = &btc->cx.wl.link_info[i]; 8919 - 8920 - if (!plink->active) 8921 - continue; 8922 - 8923 - p += scnprintf(p, end - p, 8924 - " [port_%d] : role=%d(phy-%d), connect=%d(client_cnt=%d), mode=%d, center_ch=%d, bw=%d", 8925 - plink->pid, (u32)plink->role, plink->phy, 8926 - (u32)plink->connected, plink->client_cnt - 1, 8927 - (u32)plink->mode, plink->ch, (u32)plink->bw); 8928 - 8929 - if (plink->connected == MLME_NO_LINK) 8930 - continue; 8931 - 8932 - p += scnprintf(p, end - p, 8933 - ", mac_id=%d, max_tx_time=%dus, max_tx_retry=%d\n", 8934 - plink->mac_id, plink->tx_time, plink->tx_retry); 8935 - 8936 - p += scnprintf(p, end - p, 8937 - " [port_%d] : rssi=-%ddBm(%d), busy=%d, dir=%s, ", 8938 - plink->pid, 110 - plink->stat.rssi, 8939 - plink->stat.rssi, plink->busy, 8940 - plink->dir == RTW89_TFC_UL ? "UL" : "DL"); 8941 - 8942 - t = &plink->stat.traffic; 8943 - 8944 - p += scnprintf(p, end - p, 8945 - "tx[rate:%d/busy_level:%d], ", 8946 - (u32)t->tx_rate, t->tx_tfc_lv); 8947 - 8948 - p += scnprintf(p, end - p, 8949 - "rx[rate:%d/busy_level:%d/drop:%d]\n", 8950 - (u32)t->rx_rate, 8951 - t->rx_tfc_lv, plink->rx_rate_drop_cnt); 8952 - } 8953 - 8954 8297 return p - buf; 8955 8298 } 8956 8299 ··· 8973 8342 else 8974 8343 goto out; 8975 8344 8976 - p += scnprintf(p, end - p, " %-15s : link_mode:%d, ", "[status]", 8977 - mode); 8345 + p += scnprintf(p, end - p, " %-15s : link_mode:%s, ", "[status]", 8346 + id_to_linkmode(mode)); 8978 8347 8979 8348 p += scnprintf(p, end - p, 8980 8349 "rf_off:%d, power_save:%d, scan:%s(band:%d/phy_map:0x%x), ", ··· 9064 8433 struct rtw89_btc_cx *cx = &btc->cx; 9065 8434 struct rtw89_btc_bt_info *bt = &cx->bt; 9066 8435 struct rtw89_btc_wl_info *wl = &cx->wl; 8436 + u32 ver_main = FIELD_GET(GENMASK(31, 24), wl->ver_info.fw_coex); 9067 8437 struct rtw89_btc_bt_link_info *bt_linfo = &bt->link_info; 9068 8438 union rtw89_btc_module_info *md = &btc->mdinfo; 8439 + s8 br_dbm = bt->link_info.bt_txpwr_desc.br_dbm; 8440 + s8 le_dbm = bt->link_info.bt_txpwr_desc.le_dbm; 9069 8441 char *p = buf, *end = buf + bufsz; 9070 8442 u8 *afh = bt_linfo->afh_map; 9071 8443 u8 *afh_le = bt_linfo->afh_map_le; ··· 9200 8566 } 9201 8567 p += scnprintf(p, end - p, "\n"); 9202 8568 } 8569 + 8570 + if (ver_main >= 9 && bt_linfo->profile_cnt.now) 8571 + rtw89_btc_fw_en_rpt(rtwdev, RPT_EN_BT_TX_PWR_LVL, true); 8572 + else 8573 + rtw89_btc_fw_en_rpt(rtwdev, RPT_EN_BT_TX_PWR_LVL, false); 8574 + 8575 + if (cx->cnt_bt[BTC_BCNT_BTTXPWR_UPDATE]) { 8576 + p += scnprintf(p, end - p, 8577 + " %-15s : br_index:0x%x, le_index:0x%x", 8578 + "[bt_txpwr_lvl]", 8579 + bt->link_info.bt_txpwr_desc.br_gain_index, 8580 + bt->link_info.bt_txpwr_desc.le_gain_index); 8581 + p += scnprintf(p, end - p, ", br_dbm:%d dBm", br_dbm); 8582 + p += scnprintf(p, end - p, ", le_dbm:%d dBm", le_dbm); 8583 + } else { 8584 + p += scnprintf(p, end - p, 8585 + " %-15s : br_index:NA, le_index:NA, br_dbm:%d dBm[def], le_dbm:%d dBm[def]", 8586 + "[bt_txpwr_lvl]", 8587 + bt->link_info.bt_txpwr_desc.br_dbm, 8588 + bt->link_info.bt_txpwr_desc.le_dbm); 8589 + } 8590 + p += scnprintf(p, end - p, "\n"); 9203 8591 9204 8592 if (bt_linfo->profile_cnt.now || bt_linfo->status.map.ble_connect) 9205 8593 rtw89_btc_fw_en_rpt(rtwdev, RPT_EN_BT_AFH_MAP, true); ··· 9798 9142 if (i % 5 == 4) 9799 9143 p += scnprintf(p, end - p, "\n"); 9800 9144 } 9801 - p += scnprintf(p, end - p, "\n"); 9802 9145 9803 9146 return p - buf; 9804 9147 } ··· 10369 9714 return 0; 10370 9715 10371 9716 pcysta = &pfwinfo->rpt_fbtc_cysta.finfo.v7; 10372 - p += scnprintf(p, end - p, "\n\r %-15s : cycle:%d", "[slot_stat]", 9717 + p += scnprintf(p, end - p, "\n %-15s : cycle:%d", "[slot_stat]", 10373 9718 le16_to_cpu(pcysta->cycles)); 10374 9719 10375 9720 for (i = 0; i < CXST_MAX; i++) { ··· 10517 9862 ns = &pfwinfo->rpt_fbtc_nullsta.finfo; 10518 9863 if (ver->fcxnullsta == 1) { 10519 9864 for (i = 0; i < 2; i++) { 10520 - p += scnprintf(p, end - p, " %-15s : ", "[NULL-STA]"); 9865 + p += scnprintf(p, end - p, " %-15s : ", "\n[NULL-STA]"); 10521 9866 p += scnprintf(p, end - p, "null-%d", i); 10522 9867 p += scnprintf(p, end - p, "[ok:%d/", 10523 9868 le32_to_cpu(ns->v1.result[i][1])); ··· 10530 9875 p += scnprintf(p, end - p, "avg_t:%d.%03d/", 10531 9876 le32_to_cpu(ns->v1.avg_t[i]) / 1000, 10532 9877 le32_to_cpu(ns->v1.avg_t[i]) % 1000); 10533 - p += scnprintf(p, end - p, "max_t:%d.%03d]\n", 9878 + p += scnprintf(p, end - p, "max_t:%d.%03d]", 10534 9879 le32_to_cpu(ns->v1.max_t[i]) / 1000, 10535 9880 le32_to_cpu(ns->v1.max_t[i]) % 1000); 10536 9881 } 10537 9882 } else if (ver->fcxnullsta == 7) { 10538 9883 for (i = 0; i < 2; i++) { 10539 - p += scnprintf(p, end - p, " %-15s : ", "[NULL-STA]"); 9884 + p += scnprintf(p, end - p, " %-15s : ", "\n[NULL-STA]"); 10540 9885 p += scnprintf(p, end - p, "null-%d", i); 10541 9886 p += scnprintf(p, end - p, "[Tx:%d/", 10542 9887 le32_to_cpu(ns->v7.result[i][4])); ··· 10551 9896 p += scnprintf(p, end - p, "avg_t:%d.%03d/", 10552 9897 le32_to_cpu(ns->v7.tavg[i]) / 1000, 10553 9898 le32_to_cpu(ns->v7.tavg[i]) % 1000); 10554 - p += scnprintf(p, end - p, "max_t:%d.%03d]\n", 9899 + p += scnprintf(p, end - p, "max_t:%d.%03d]", 10555 9900 le32_to_cpu(ns->v7.tmax[i]) / 1000, 10556 9901 le32_to_cpu(ns->v7.tmax[i]) % 1000); 10557 9902 } 10558 9903 } else { 10559 9904 for (i = 0; i < 2; i++) { 10560 - p += scnprintf(p, end - p, " %-15s : ", "[NULL-STA]"); 9905 + p += scnprintf(p, end - p, " %-15s : ", "\n[NULL-STA]"); 10561 9906 p += scnprintf(p, end - p, "null-%d", i); 10562 9907 p += scnprintf(p, end - p, "[Tx:%d/", 10563 9908 le32_to_cpu(ns->v2.result[i][4])); ··· 10572 9917 p += scnprintf(p, end - p, "avg_t:%d.%03d/", 10573 9918 le32_to_cpu(ns->v2.avg_t[i]) / 1000, 10574 9919 le32_to_cpu(ns->v2.avg_t[i]) % 1000); 10575 - p += scnprintf(p, end - p, "max_t:%d.%03d]\n", 9920 + p += scnprintf(p, end - p, "max_t:%d.%03d]", 10576 9921 le32_to_cpu(ns->v2.max_t[i]) / 1000, 10577 9922 le32_to_cpu(ns->v2.max_t[i]) % 1000); 10578 9923 } ··· 10814 10159 rtw89_debug(rtwdev, RTW89_DBG_BTC, 10815 10160 "[BTC], %s(): stop due rpt_fbtc_gpio_dbg.cinfo\n", 10816 10161 __func__); 10817 - p += scnprintf(p, end - p, "\n"); 10818 10162 goto out; 10819 10163 } 10820 10164 ··· 11086 10432 id_to_regtype(type), offset, val); 11087 10433 cnt++; 11088 10434 } 11089 - p += scnprintf(p, end - p, "\n"); 11090 10435 11091 10436 out: 11092 10437 return p - buf; ··· 11785 11132 11786 11133 ssize_t rtw89_btc_dump_info(struct rtw89_dev *rtwdev, char *buf, size_t bufsz) 11787 11134 { 11788 - struct rtw89_fw_suit *fw_suit = &rtwdev->fw.normal; 11789 11135 struct rtw89_btc *btc = &rtwdev->btc; 11136 + struct rtw89_btc_ver *fwsubver = &btc->fwinfo.fw_subver; 11790 11137 const struct rtw89_btc_ver *ver = btc->ver; 11791 - struct rtw89_btc_cx *cx = &btc->cx; 11792 - struct rtw89_btc_bt_info *bt = &cx->bt; 11138 + struct rtw89_btc_dm *dm = &btc->dm; 11793 11139 char *p = buf, *end = buf + bufsz; 11794 11140 11795 - p += scnprintf(p, end - p, 11796 - "=========================================\n"); 11797 - p += scnprintf(p, end - p, 11798 - "WL FW / BT FW %d.%d.%d.%d / NA\n", 11799 - fw_suit->major_ver, fw_suit->minor_ver, 11800 - fw_suit->sub_ver, fw_suit->sub_idex); 11801 - p += scnprintf(p, end - p, "manual %d\n", 11802 - btc->manual_ctrl); 11141 + dm->cnt_notify[BTC_NCNT_SHOW_COEX_INFO]++; 11803 11142 11804 11143 p += scnprintf(p, end - p, 11805 - "=========================================\n"); 11806 - 11144 + "\n\n\n** Page:%3d/RunCNT:%3d **", 11145 + dm->cnt_notify[BTC_NCNT_SHOW_COEX_INFO], 11146 + dm->cnt_dm[BTC_DCNT_RUN]); 11807 11147 p += scnprintf(p, end - p, 11808 - "\n\r %-15s : raw_data[%02x %02x %02x %02x %02x %02x] (type:%s/cnt:%d/same:%d)", 11809 - "[bt_info]", 11810 - bt->raw_info[2], bt->raw_info[3], 11811 - bt->raw_info[4], bt->raw_info[5], 11812 - bt->raw_info[6], bt->raw_info[7], 11813 - bt->raw_info[0] == BTC_BTINFO_AUTO ? "auto" : "reply", 11814 - cx->cnt_bt[BTC_BCNT_INFOUPDATE], 11815 - cx->cnt_bt[BTC_BCNT_INFOSAME]); 11816 - 11148 + "\n========== [BTC FEATURE SUB VER] =========="); 11817 11149 p += scnprintf(p, end - p, 11818 - "\n=========================================\n"); 11150 + "\n %-15s : fcxbtcrpt[%d/%d], fcxtdma[%d/%d], fcxslots[%d/%d], fcxcysta[%d/%d]", 11151 + "[FW/DRV]", fwsubver->fcxbtcrpt, ver->fcxbtcrpt, 11152 + fwsubver->fcxtdma, ver->fcxtdma, fwsubver->fcxslots, 11153 + ver->fcxslots, fwsubver->fcxcysta, ver->fcxcysta); 11154 + p += scnprintf(p, end - p, 11155 + "\n %-15s : fcxstep[%d/%d], fcxnullsta[%d/%d], fcxmreg[%d/%d], fcxgpiodbg[%d/%d]", 11156 + "[FW/DRV]", fwsubver->fcxstep, ver->fcxstep, 11157 + fwsubver->fcxnullsta, ver->fcxnullsta, fwsubver->fcxmreg, 11158 + ver->fcxmreg, fwsubver->fcxgpiodbg, ver->fcxgpiodbg); 11159 + p += scnprintf(p, end - p, 11160 + "\n %-15s : fcxbtver[%d/%d], fcxbtscan[%d/%d], fcxbtafh[%d/%d], fcxbtdevinfo[%d/%d]", 11161 + "[FW/DRV]", fwsubver->fcxbtver, ver->fcxbtver, 11162 + fwsubver->fcxbtscan, ver->fcxbtscan, fwsubver->fcxbtafh, 11163 + ver->fcxbtafh, fwsubver->fcxbtdevinfo, ver->fcxbtdevinfo); 11164 + p += scnprintf(p, end - p, 11165 + "\n %-15s : fcxosi[%d/%d], fcxmlo[%d/%d],", 11166 + "[FW/DRV]", fwsubver->fcxosi, ver->fcxosi, 11167 + fwsubver->fcxmlo, ver->fcxmlo); 11819 11168 11820 11169 p += _show_cx_info(rtwdev, p, end - p); 11821 11170 p += _show_wl_info(rtwdev, p, end - p);
+7
drivers/net/wireless/realtek/rtw89/coex.h
··· 224 224 BTC_WL_MODE_NUM, 225 225 }; 226 226 227 + enum btc_mlo_rf_combin { 228 + BTC_MLO_RF_2_PLUS_0 = 0, 229 + BTC_MLO_RF_0_PLUS_2 = 1, 230 + BTC_MLO_RF_1_PLUS_1 = 2, 231 + BTC_MLO_RF_2_PLUS_2 = 3, 232 + }; 233 + 227 234 enum btc_wl_gpio_debug { 228 235 BTC_DBG_GNT_BT = 0, 229 236 BTC_DBG_GNT_WL = 1,
+126 -9
drivers/net/wireless/realtek/rtw89/core.c
··· 204 204 }; 205 205 206 206 static const u8 rtw89_ext_capa_sta[] = { 207 + [0] = WLAN_EXT_CAPA1_EXT_CHANNEL_SWITCHING, 207 208 [2] = WLAN_EXT_CAPA3_MULTI_BSSID_SUPPORT, 208 209 [7] = WLAN_EXT_CAPA8_OPMODE_NOTIF, 209 210 }; ··· 1723 1722 }, 1724 1723 [RTW89_CHIP_BE] = { 1725 1724 32, 40, 24, 24, 8, 8, 8, 8, VAR_LEN, 8, VAR_LEN, 176, VAR_LEN, 1726 - VAR_LEN, VAR_LEN, VAR_LEN, VAR_LEN, VAR_LEN, 16, 24, VAR_LEN, 1725 + VAR_LEN, VAR_LEN, VAR_LEN, VAR_LEN, VAR_LEN, 88, 56, VAR_LEN, 1727 1726 VAR_LEN, VAR_LEN, 0, 24, 24, 24, 24, 32, 32, 32, 32 1728 1727 }, 1729 1728 }; ··· 1918 1917 return -EINVAL; 1919 1918 1920 1919 pos = phy_ppdu->buf + PHY_STS_HDR_LEN; 1920 + if (phy_ppdu->hdr_2_en) 1921 + pos += PHY_STS_HDR_LEN; 1921 1922 end = phy_ppdu->buf + phy_ppdu->len; 1922 1923 while (pos < end) { 1923 1924 const struct rtw89_phy_sts_iehdr *iehdr = pos; ··· 2160 2157 2161 2158 if (rx_status->band != NL80211_BAND_6GHZ) 2162 2159 return; 2160 + 2161 + if (unlikely(!(rtwdev->chip->support_bands & BIT(NL80211_BAND_6GHZ)))) { 2162 + rtw89_debug(rtwdev, RTW89_DBG_UNEXP, "invalid rx on unsupported 6 GHz\n"); 2163 + return; 2164 + } 2163 2165 2164 2166 ssid_ie = cfg80211_find_ie(WLAN_EID_SSID, ies, skb->len); 2165 2167 ··· 2485 2477 rx_status->freq = ieee80211_channel_to_frequency(chan, rx_status->band); 2486 2478 } 2487 2479 2480 + static void rtw89_core_correct_mcc_chan(struct rtw89_dev *rtwdev, 2481 + struct rtw89_rx_desc_info *desc_info, 2482 + struct ieee80211_rx_status *rx_status, 2483 + struct rtw89_rx_phy_ppdu *phy_ppdu) 2484 + { 2485 + enum rtw89_chip_gen chip_gen = rtwdev->chip->chip_gen; 2486 + struct rtw89_vif_link *rtwvif_link; 2487 + struct rtw89_sta_link *rtwsta_link; 2488 + const struct rtw89_chan *chan; 2489 + u8 mac_id = desc_info->mac_id; 2490 + enum rtw89_entity_mode mode; 2491 + enum nl80211_band band; 2492 + 2493 + mode = rtw89_get_entity_mode(rtwdev); 2494 + if (likely(mode != RTW89_ENTITY_MODE_MCC)) 2495 + return; 2496 + 2497 + if (chip_gen == RTW89_CHIP_BE && phy_ppdu) 2498 + mac_id = phy_ppdu->mac_id; 2499 + 2500 + rcu_read_lock(); 2501 + 2502 + rtwsta_link = rtw89_assoc_link_rcu_dereference(rtwdev, mac_id); 2503 + if (!rtwsta_link) 2504 + goto out; 2505 + 2506 + rtwvif_link = rtwsta_link->rtwvif_link; 2507 + chan = rtw89_chan_get(rtwdev, rtwvif_link->chanctx_idx); 2508 + band = rtw89_hw_to_nl80211_band(chan->band_type); 2509 + rx_status->freq = ieee80211_channel_to_frequency(chan->primary_channel, band); 2510 + 2511 + out: 2512 + rcu_read_unlock(); 2513 + } 2514 + 2488 2515 static void rtw89_core_rx_to_mac80211(struct rtw89_dev *rtwdev, 2489 2516 struct rtw89_rx_phy_ppdu *phy_ppdu, 2490 2517 struct rtw89_rx_desc_info *desc_info, ··· 2538 2495 rtw89_core_update_radiotap(rtwdev, skb_ppdu, rx_status); 2539 2496 rtw89_core_validate_rx_signal(rx_status); 2540 2497 rtw89_core_update_rx_freq_from_ie(rtwdev, skb_ppdu, rx_status); 2498 + rtw89_core_correct_mcc_chan(rtwdev, desc_info, rx_status, phy_ppdu); 2541 2499 2542 2500 /* In low power mode, it does RX in thread context. */ 2543 2501 local_bh_disable(); ··· 2796 2752 } 2797 2753 2798 2754 static void rtw89_core_update_rx_status(struct rtw89_dev *rtwdev, 2755 + struct sk_buff *skb, 2799 2756 struct rtw89_rx_desc_info *desc_info, 2800 2757 struct ieee80211_rx_status *rx_status) 2801 2758 { 2759 + struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; 2802 2760 const struct cfg80211_chan_def *chandef = 2803 2761 rtw89_chandef_get(rtwdev, RTW89_CHANCTX_0); 2804 2762 u16 data_rate; ··· 2811 2765 /* currently using single PHY */ 2812 2766 rx_status->freq = chandef->chan->center_freq; 2813 2767 rx_status->band = chandef->chan->band; 2768 + 2769 + if (ieee80211_is_beacon(hdr->frame_control) || 2770 + ieee80211_is_probe_resp(hdr->frame_control)) 2771 + rx_status->boottime_ns = ktime_get_boottime_ns(); 2814 2772 2815 2773 if (rtwdev->scanning && 2816 2774 RTW89_CHK_FW_FEATURE(SCAN_OFFLOAD, &rtwdev->fw)) { ··· 2972 2922 2973 2923 rx_status = IEEE80211_SKB_RXCB(skb); 2974 2924 memset(rx_status, 0, sizeof(*rx_status)); 2975 - rtw89_core_update_rx_status(rtwdev, desc_info, rx_status); 2925 + rtw89_core_update_rx_status(rtwdev, skb, desc_info, rx_status); 2976 2926 rtw89_core_rx_pkt_hdl(rtwdev, skb, desc_info); 2977 2927 if (desc_info->long_rxdesc && 2978 2928 BIT(desc_info->frame_type) & PPDU_FILTER_BITMAP) ··· 3380 3330 rtwvif_link); 3381 3331 } 3382 3332 3383 - static int rtw89_core_send_nullfunc(struct rtw89_dev *rtwdev, 3384 - struct rtw89_vif_link *rtwvif_link, bool qos, bool ps) 3333 + int rtw89_core_send_nullfunc(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link, 3334 + bool qos, bool ps, int timeout) 3385 3335 { 3386 3336 struct ieee80211_vif *vif = rtwvif_link_to_vif(rtwvif_link); 3387 3337 int link_id = ieee80211_vif_is_mld(vif) ? rtwvif_link->link_id : -1; ··· 3429 3379 rcu_read_unlock(); 3430 3380 3431 3381 return rtw89_core_tx_kick_off_and_wait(rtwdev, skb, qsel, 3432 - RTW89_ROC_TX_TIMEOUT); 3382 + timeout); 3433 3383 out: 3434 3384 rcu_read_unlock(); 3435 3385 ··· 3466 3416 pause_parm.trigger = rtwvif_link; 3467 3417 rtw89_chanctx_pause(rtwdev, &pause_parm); 3468 3418 3469 - ret = rtw89_core_send_nullfunc(rtwdev, rtwvif_link, true, true); 3419 + ret = rtw89_core_send_nullfunc(rtwdev, rtwvif_link, true, true, 3420 + RTW89_ROC_TX_TIMEOUT); 3470 3421 if (ret) 3471 3422 rtw89_debug(rtwdev, RTW89_DBG_TXRX, 3472 3423 "roc send null-1 failed: %d\n", ret); ··· 3527 3476 roc->state = RTW89_ROC_IDLE; 3528 3477 rtw89_config_roc_chandef(rtwdev, rtwvif_link, NULL); 3529 3478 rtw89_chanctx_proceed(rtwdev, NULL); 3530 - ret = rtw89_core_send_nullfunc(rtwdev, rtwvif_link, true, false); 3479 + ret = rtw89_core_send_nullfunc(rtwdev, rtwvif_link, true, false, 3480 + RTW89_ROC_TX_TIMEOUT); 3531 3481 if (ret) 3532 3482 rtw89_debug(rtwdev, RTW89_DBG_TXRX, 3533 3483 "roc send null-0 failed: %d\n", ret); ··· 3794 3742 3795 3743 lockdep_assert_wiphy(wiphy); 3796 3744 3797 - if (test_bit(RTW89_FLAG_FORBIDDEN_TRACK_WROK, rtwdev->flags)) 3745 + if (test_bit(RTW89_FLAG_FORBIDDEN_TRACK_WORK, rtwdev->flags)) 3798 3746 return; 3799 3747 3800 3748 if (!test_bit(RTW89_FLAG_RUNNING, rtwdev->flags)) ··· 4019 3967 rtw89_btc_ntfy_role_info(rtwdev, rtwvif_link, rtwsta_link, 4020 3968 BTC_ROLE_MSTS_STA_CONN_START); 4021 3969 rtw89_chip_rfk_channel(rtwdev, rtwvif_link); 3970 + 3971 + if (vif->p2p) { 3972 + rtw89_mac_get_tx_retry_limit(rtwdev, rtwsta_link, 3973 + &rtwsta_link->tx_retry); 3974 + rtw89_mac_set_tx_retry_limit(rtwdev, rtwsta_link, false, 60); 3975 + } 4022 3976 } else if (vif->type == NL80211_IFTYPE_AP || sta->tdls) { 4023 3977 ret = rtw89_mac_set_macid_pause(rtwdev, rtwsta_link->mac_id, false); 4024 3978 if (ret) { ··· 4209 4151 } 4210 4152 4211 4153 rtw89_fw_h2c_set_bcn_fltr_cfg(rtwdev, rtwvif_link, true); 4154 + 4155 + if (vif->p2p) 4156 + rtw89_mac_set_tx_retry_limit(rtwdev, rtwsta_link, false, 4157 + rtwsta_link->tx_retry); 4212 4158 } 4213 4159 4214 4160 rtw89_assoc_link_set(rtwsta_link); ··· 4231 4169 rtw89_reg_6ghz_recalc(rtwdev, rtwvif_link, false); 4232 4170 rtw89_btc_ntfy_role_info(rtwdev, rtwvif_link, rtwsta_link, 4233 4171 BTC_ROLE_MSTS_STA_DIS_CONN); 4172 + 4173 + if (vif->p2p) 4174 + rtw89_mac_set_tx_retry_limit(rtwdev, rtwsta_link, false, 4175 + rtwsta_link->tx_retry); 4234 4176 } else if (vif->type == NL80211_IFTYPE_AP || sta->tdls) { 4235 4177 ret = rtw89_fw_h2c_role_maintain(rtwdev, rtwvif_link, rtwsta_link, 4236 4178 RTW89_ROLE_REMOVE); ··· 4721 4655 rtw89_chip_h2c_update_beacon(rtwdev, rtwvif_link); 4722 4656 } 4723 4657 4658 + void rtw89_core_csa_beacon_work(struct wiphy *wiphy, struct wiphy_work *work) 4659 + { 4660 + struct rtw89_vif_link *rtwvif_link = 4661 + container_of(work, struct rtw89_vif_link, csa_beacon_work.work); 4662 + struct rtw89_vif *rtwvif = rtwvif_link->rtwvif; 4663 + struct ieee80211_vif *vif = rtwvif_to_vif(rtwvif); 4664 + struct rtw89_dev *rtwdev = rtwvif->rtwdev; 4665 + struct ieee80211_bss_conf *bss_conf; 4666 + unsigned int delay; 4667 + 4668 + lockdep_assert_wiphy(wiphy); 4669 + 4670 + if (rtwvif_link->net_type != RTW89_NET_TYPE_AP_MODE) 4671 + return; 4672 + 4673 + rcu_read_lock(); 4674 + 4675 + bss_conf = rtw89_vif_rcu_dereference_link(rtwvif_link, true); 4676 + if (!bss_conf->csa_active) { 4677 + rcu_read_unlock(); 4678 + return; 4679 + } 4680 + 4681 + delay = ieee80211_tu_to_usec(bss_conf->beacon_int); 4682 + 4683 + rcu_read_unlock(); 4684 + 4685 + if (!ieee80211_beacon_cntdwn_is_complete(vif, rtwvif_link->link_id)) { 4686 + rtw89_chip_h2c_update_beacon(rtwdev, rtwvif_link); 4687 + 4688 + wiphy_delayed_work_queue(wiphy, &rtwvif_link->csa_beacon_work, 4689 + usecs_to_jiffies(delay)); 4690 + } else { 4691 + ieee80211_csa_finish(vif, rtwvif_link->link_id); 4692 + } 4693 + } 4694 + 4724 4695 int rtw89_wait_for_cond(struct rtw89_wait_info *wait, unsigned int cond) 4725 4696 { 4726 4697 struct completion *cmpl = &wait->completion; ··· 4911 4808 wiphy_delayed_work_cancel(wiphy, &rtwdev->coex_bt_devinfo_work); 4912 4809 wiphy_delayed_work_cancel(wiphy, &rtwdev->coex_rfk_chk_work); 4913 4810 wiphy_delayed_work_cancel(wiphy, &rtwdev->cfo_track_work); 4811 + wiphy_delayed_work_cancel(wiphy, &rtwdev->mcc_prepare_done_work); 4914 4812 cancel_delayed_work_sync(&rtwdev->forbid_ba_work); 4915 4813 wiphy_delayed_work_cancel(wiphy, &rtwdev->antdiv_work); 4916 4814 ··· 5138 5034 wiphy_delayed_work_init(&rtwdev->coex_bt_devinfo_work, rtw89_coex_bt_devinfo_work); 5139 5035 wiphy_delayed_work_init(&rtwdev->coex_rfk_chk_work, rtw89_coex_rfk_chk_work); 5140 5036 wiphy_delayed_work_init(&rtwdev->cfo_track_work, rtw89_phy_cfo_track_work); 5037 + wiphy_delayed_work_init(&rtwdev->mcc_prepare_done_work, rtw89_mcc_prepare_done_work); 5141 5038 INIT_DELAYED_WORK(&rtwdev->forbid_ba_work, rtw89_forbid_ba_work); 5142 5039 wiphy_delayed_work_init(&rtwdev->antdiv_work, rtw89_phy_antdiv_work); 5143 5040 rtwdev->txq_wq = alloc_workqueue("rtw89_tx_wq", WQ_UNBOUND | WQ_HIGHPRI, 0); ··· 5232 5127 { 5233 5128 struct ieee80211_bss_conf *bss_conf; 5234 5129 struct rtw89_bb_ctx *bb; 5130 + int ret; 5235 5131 5236 5132 if (!rtwvif_link) 5237 5133 return; ··· 5251 5145 bb = rtw89_get_bb_ctx(rtwdev, rtwvif_link->phy_idx); 5252 5146 rtw89_phy_config_edcca(rtwdev, bb, false); 5253 5147 rtw89_tas_scan(rtwdev, false); 5148 + 5149 + if (hw_scan) { 5150 + ret = rtw89_core_send_nullfunc(rtwdev, rtwvif_link, false, false, 5151 + RTW89_SCAN_NULL_TIMEOUT); 5152 + if (ret) 5153 + rtw89_debug(rtwdev, RTW89_DBG_TXRX, 5154 + "scan send null-0 failed: %d\n", ret); 5155 + } 5254 5156 5255 5157 rtwdev->scanning = false; 5256 5158 rtw89_for_each_active_bb(rtwdev, bb) ··· 5353 5239 if (unlikely(!ieee80211_vif_is_mld(vif))) 5354 5240 return -EOPNOTSUPP; 5355 5241 5356 - if (unlikely(!(usable_links & BIT(link_id)))) { 5242 + if (unlikely(link_id >= IEEE80211_MLD_MAX_NUM_LINKS || 5243 + !(usable_links & BIT(link_id)))) { 5357 5244 rtw89_warn(rtwdev, "%s: link id %u is not usable\n", __func__, 5358 5245 link_id); 5359 5246 return -ENOLINK; ··· 5619 5504 ieee80211_hw_set(hw, SINGLE_SCAN_ON_ALL_BANDS); 5620 5505 ieee80211_hw_set(hw, SUPPORTS_MULTI_BSSID); 5621 5506 ieee80211_hw_set(hw, WANT_MONITOR_VIF); 5507 + ieee80211_hw_set(hw, CHANCTX_STA_CSA); 5622 5508 5623 5509 if (chip->support_bandwidths & BIT(NL80211_CHAN_WIDTH_160)) 5624 5510 ieee80211_hw_set(hw, SUPPORTS_VHT_EXT_NSS_BW); ··· 5646 5530 hw->wiphy->flags |= WIPHY_FLAG_SUPPORTS_TDLS | 5647 5531 WIPHY_FLAG_TDLS_EXTERNAL_SETUP | 5648 5532 WIPHY_FLAG_AP_UAPSD | 5533 + WIPHY_FLAG_HAS_CHANNEL_SWITCH | 5649 5534 WIPHY_FLAG_SUPPORTS_EXT_KEK_KCK; 5650 5535 5651 5536 if (!chip->support_rnr)
+119 -28
drivers/net/wireless/realtek/rtw89/core.h
··· 1205 1205 struct rtw89_mac_ax_wl_act { 1206 1206 u8 wlan_act_en; 1207 1207 u8 wlan_act; 1208 - }; 1208 + } __packed; 1209 1209 1210 1210 #define RTW89_MAC_AX_COEX_GNT_NR 2 1211 1211 struct rtw89_mac_ax_coex_gnt { ··· 1322 1322 BTC_BCNT_POLUT_NOW, 1323 1323 BTC_BCNT_POLUT_DIFF, 1324 1324 BTC_BCNT_RATECHG, 1325 + BTC_BCNT_BTTXPWR_UPDATE, 1325 1326 BTC_BCNT_NUM, 1326 1327 }; 1327 1328 ··· 1556 1555 u8 scan_band[RTW89_PHY_NUM]; /* scan band in each phy */ 1557 1556 u8 real_band[RTW89_PHY_NUM]; 1558 1557 u8 role[RTW89_PHY_NUM]; /* role in each phy */ 1558 + }; 1559 + 1560 + struct rtw89_btc_wl_mlo_info { 1561 + u8 wmode[RTW89_PHY_NUM]; /* enum phl_mr_wmode */ 1562 + u8 ch_type[RTW89_PHY_NUM]; /* enum phl_mr_ch_type */ 1563 + u8 hwb_rf_band[RTW89_PHY_NUM]; /* enum band_type, RF-band for HW-band */ 1564 + u8 path_rf_band[RTW89_PHY_NUM]; /* enum band_type, RF-band for PHY0/1 */ 1565 + 1566 + u8 wtype; /* enum phl_mr_wtype */ 1567 + u8 mrcx_mode; 1568 + u8 mrcx_act_hwb_map; 1569 + u8 mrcx_bt_slot_rsp; 1570 + 1571 + u8 rf_combination; /* enum btc_mlo_rf_combin 0:2+0, 1:0+2, 2:1+1,3:2+2 */ 1572 + u8 mlo_en; /* MLO enable */ 1573 + u8 mlo_adie; /* a-die count */ 1574 + u8 dual_hw_band_en; /* both 2 HW-band link exist */ 1575 + 1576 + u32 link_status; /* enum mlo_dbcc_mode_type */ 1559 1577 }; 1560 1578 1561 1579 struct rtw89_btc_wl_active_role { ··· 1811 1791 #define BTC_BT_AFH_GROUP 12 1812 1792 #define BTC_BT_AFH_LE_GROUP 5 1813 1793 1794 + struct rtw89_btc_bt_txpwr_desc { 1795 + s8 br_dbm; 1796 + s8 le_dbm; 1797 + u8 br_gain_index; 1798 + u8 le_gain_index; 1799 + }; 1800 + 1814 1801 struct rtw89_btc_bt_link_info { 1815 1802 struct rtw89_btc_u8_sta_chg profile_cnt; 1816 1803 struct rtw89_btc_bool_sta_chg multi_link; ··· 1827 1800 struct rtw89_btc_bt_a2dp_desc a2dp_desc; 1828 1801 struct rtw89_btc_bt_pan_desc pan_desc; 1829 1802 union rtw89_btc_bt_state_map status; 1803 + struct rtw89_btc_bt_txpwr_desc bt_txpwr_desc; 1830 1804 1831 1805 u8 sut_pwr_level[BTC_PROFILE_MAX]; 1832 1806 u8 golden_rx_shift[BTC_PROFILE_MAX]; ··· 1923 1895 struct rtw89_btc_wl_role_info_v8 role_info_v8; 1924 1896 struct rtw89_btc_wl_scan_info scan_info; 1925 1897 struct rtw89_btc_wl_dbcc_info dbcc_info; 1898 + struct rtw89_btc_wl_mlo_info mlo_info; 1926 1899 struct rtw89_btc_rf_para rf_para; 1927 1900 struct rtw89_btc_wl_nhm nhm; 1928 1901 union rtw89_btc_wl_state_map status; ··· 1936 1907 u8 bt_polut_type[RTW89_PHY_NUM]; /* BT polluted WL-Tx type for phy0/1 */ 1937 1908 1938 1909 bool is_5g_hi_channel; 1910 + bool go_client_exist; 1911 + bool noa_exist; 1939 1912 bool pta_reg_mac_chg; 1940 1913 bool bg_mode; 1941 1914 bool he_mode; 1942 1915 bool scbd_change; 1943 1916 bool fw_ver_mismatch; 1944 1917 bool client_cnt_inc_2g; 1918 + bool link_mode_chg; 1919 + bool dbcc_chg; 1945 1920 u32 scbd; 1946 1921 }; 1947 1922 ··· 2098 2065 union rtw89_btc_bt_rfk_info_map rfk_info; 2099 2066 2100 2067 u8 raw_info[BTC_BTINFO_MAX]; /* raw bt info from mailbox */ 2068 + u8 txpwr_info[BTC_BTINFO_MAX]; 2101 2069 u8 rssi_level; 2102 2070 2103 2071 u32 scbd; ··· 2937 2903 u32 rx_err_ratio; 2938 2904 }; 2939 2905 2906 + enum btc_rf_path { 2907 + BTC_RF_S0 = 0, 2908 + BTC_RF_S1 = 1, 2909 + BTC_RF_NUM, 2910 + }; 2911 + 2912 + struct rtw89_btc_fbtc_outsrc_set_info { 2913 + u8 rf_band[BTC_RF_NUM]; /* 0:2G, 1:non-2G */ 2914 + u8 btg_rx[BTC_RF_NUM]; 2915 + u8 nbtg_tx[BTC_RF_NUM]; 2916 + 2917 + struct rtw89_mac_ax_gnt gnt_set[BTC_RF_NUM]; /* refer to btc_gnt_ctrl */ 2918 + struct rtw89_mac_ax_wl_act wlact_set[BTC_RF_NUM]; /* BT0/BT1 */ 2919 + 2920 + u8 pta_req_hw_band; 2921 + u8 rf_gbt_source; 2922 + } __packed; 2923 + 2940 2924 union rtw89_btc_fbtc_slot_u { 2941 2925 struct rtw89_btc_fbtc_slot v1[CXST_MAX]; 2942 2926 struct rtw89_btc_fbtc_slot_v7 v7[CXST_MAX]; 2943 2927 }; 2944 2928 2945 2929 struct rtw89_btc_dm { 2930 + struct rtw89_btc_fbtc_outsrc_set_info ost_info_last; /* outsrc API setup info */ 2931 + struct rtw89_btc_fbtc_outsrc_set_info ost_info; /* outsrc API setup info */ 2946 2932 union rtw89_btc_fbtc_slot_u slot; 2947 2933 union rtw89_btc_fbtc_slot_u slot_now; 2948 2934 struct rtw89_btc_fbtc_tdma tdma; ··· 3052 2998 BTF_EVNT_BT_LEAUDIO_INFO = 7, /* fwc2hfunc > 1 */ 3053 2999 BTF_EVNT_BUF_OVERFLOW, 3054 3000 BTF_EVNT_C2H_LOOPBACK, 3001 + BTF_EVNT_BT_QUERY_TXPWR, /* fwc2hfunc > 3 */ 3055 3002 BTF_EVNT_MAX, 3056 3003 }; 3057 3004 ··· 3171 3116 BTFRE_MAX, 3172 3117 }; 3173 3118 3174 - struct rtw89_btc_btf_fwinfo { 3175 - u32 cnt_c2h; 3176 - u32 cnt_h2c; 3177 - u32 cnt_h2c_fail; 3178 - u32 event[BTF_EVNT_MAX]; 3179 - 3180 - u32 err[BTFRE_MAX]; 3181 - u32 len_mismch; 3182 - u32 fver_mismch; 3183 - u32 rpt_en_map; 3184 - 3185 - struct rtw89_btc_report_ctrl_state rpt_ctrl; 3186 - struct rtw89_btc_rpt_fbtc_tdma rpt_fbtc_tdma; 3187 - struct rtw89_btc_rpt_fbtc_slots rpt_fbtc_slots; 3188 - struct rtw89_btc_rpt_fbtc_cysta rpt_fbtc_cysta; 3189 - struct rtw89_btc_rpt_fbtc_step rpt_fbtc_step; 3190 - struct rtw89_btc_rpt_fbtc_nullsta rpt_fbtc_nullsta; 3191 - struct rtw89_btc_rpt_fbtc_mreg rpt_fbtc_mregval; 3192 - struct rtw89_btc_rpt_fbtc_gpio_dbg rpt_fbtc_gpio_dbg; 3193 - struct rtw89_btc_rpt_fbtc_btver rpt_fbtc_btver; 3194 - struct rtw89_btc_rpt_fbtc_btscan rpt_fbtc_btscan; 3195 - struct rtw89_btc_rpt_fbtc_btafh rpt_fbtc_btafh; 3196 - struct rtw89_btc_rpt_fbtc_btdev rpt_fbtc_btdev; 3197 - }; 3198 - 3199 3119 struct rtw89_btc_ver { 3200 3120 enum rtw89_core_chip_id chip_id; 3201 3121 u32 fw_ver_code; ··· 3197 3167 u8 drvinfo_type; 3198 3168 u16 info_buf; 3199 3169 u8 max_role_num; 3170 + u8 fcxosi; 3171 + u8 fcxmlo; 3172 + u8 bt_desired; 3173 + }; 3174 + 3175 + struct rtw89_btc_btf_fwinfo { 3176 + u32 cnt_c2h; 3177 + u32 cnt_h2c; 3178 + u32 cnt_h2c_fail; 3179 + u32 event[BTF_EVNT_MAX]; 3180 + 3181 + u32 err[BTFRE_MAX]; 3182 + u32 len_mismch; 3183 + u32 fver_mismch; 3184 + u32 rpt_en_map; 3185 + 3186 + struct rtw89_btc_ver fw_subver; 3187 + struct rtw89_btc_report_ctrl_state rpt_ctrl; 3188 + struct rtw89_btc_rpt_fbtc_tdma rpt_fbtc_tdma; 3189 + struct rtw89_btc_rpt_fbtc_slots rpt_fbtc_slots; 3190 + struct rtw89_btc_rpt_fbtc_cysta rpt_fbtc_cysta; 3191 + struct rtw89_btc_rpt_fbtc_step rpt_fbtc_step; 3192 + struct rtw89_btc_rpt_fbtc_nullsta rpt_fbtc_nullsta; 3193 + struct rtw89_btc_rpt_fbtc_mreg rpt_fbtc_mregval; 3194 + struct rtw89_btc_rpt_fbtc_gpio_dbg rpt_fbtc_gpio_dbg; 3195 + struct rtw89_btc_rpt_fbtc_btver rpt_fbtc_btver; 3196 + struct rtw89_btc_rpt_fbtc_btscan rpt_fbtc_btscan; 3197 + struct rtw89_btc_rpt_fbtc_btafh rpt_fbtc_btafh; 3198 + struct rtw89_btc_rpt_fbtc_btdev rpt_fbtc_btdev; 3200 3199 }; 3201 3200 3202 3201 #define RTW89_BTC_POLICY_MAXLEN 512 ··· 3444 3385 unsigned int link_id; 3445 3386 3446 3387 u8 mac_id; 3388 + u8 tx_retry; 3447 3389 bool er_cap; 3448 3390 struct rtw89_vif_link *rtwvif_link; 3449 3391 struct rtw89_ra_info ra; ··· 3499 3439 struct rtw89_tx_wait_info __rcu *wait; 3500 3440 u8 hci_priv[]; 3501 3441 }; 3442 + 3443 + #define RTW89_SCAN_NULL_TIMEOUT 30 3502 3444 3503 3445 #define RTW89_ROC_IDLE_TIMEOUT 500 3504 3446 #define RTW89_ROC_TX_TIMEOUT 30 ··· 3595 3533 bool pwr_diff_en; 3596 3534 u8 def_tri_idx; 3597 3535 struct wiphy_work update_beacon_work; 3536 + struct wiphy_delayed_work csa_beacon_work; 3598 3537 struct rtw89_addr_cam_entry addr_cam; 3599 3538 struct rtw89_bssid_cam_entry bssid_cam; 3600 3539 struct ieee80211_tx_queue_params tx_params[IEEE80211_NUM_ACS]; ··· 3708 3645 enum rtw89_phy_idx phy_idx); 3709 3646 int (*init_txpwr_unit)(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx); 3710 3647 u8 (*get_thermal)(struct rtw89_dev *rtwdev, enum rtw89_rf_path rf_path); 3648 + u32 (*chan_to_rf18_val)(struct rtw89_dev *rtwdev, 3649 + const struct rtw89_chan *chan); 3711 3650 void (*ctrl_btg_bt_rx)(struct rtw89_dev *rtwdev, bool en, 3712 3651 enum rtw89_phy_idx phy_idx); 3713 3652 void (*query_ppdu)(struct rtw89_dev *rtwdev, ··· 4423 4358 4424 4359 u32 para_ver; 4425 4360 u32 wlcx_desired; 4426 - u8 btcx_desired; 4427 4361 u8 scbd; 4428 4362 u8 mailbox; 4429 4363 ··· 4577 4513 RTW89_FW_FEATURE_RFK_PRE_NOTIFY_V0, 4578 4514 RTW89_FW_FEATURE_RFK_PRE_NOTIFY_V1, 4579 4515 RTW89_FW_FEATURE_RFK_RXDCK_V0, 4516 + RTW89_FW_FEATURE_RFK_IQK_V0, 4580 4517 RTW89_FW_FEATURE_NO_WOW_CPU_IO_RX, 4581 4518 RTW89_FW_FEATURE_NOTIFY_AP_INFO, 4582 4519 RTW89_FW_FEATURE_CH_INFO_BE_V0, ··· 4585 4520 RTW89_FW_FEATURE_NO_PHYCAP_P1, 4586 4521 RTW89_FW_FEATURE_NO_POWER_DIFFERENCE, 4587 4522 RTW89_FW_FEATURE_BEACON_LOSS_COUNT_V1, 4523 + RTW89_FW_FEATURE_SCAN_OFFLOAD_EXTRA_OP, 4524 + RTW89_FW_FEATURE_RFK_NTFY_MCC_V0, 4588 4525 }; 4589 4526 4590 4527 struct rtw89_fw_suit { ··· 4979 4912 RTW89_FLAG_CRASH_SIMULATING, 4980 4913 RTW89_FLAG_SER_HANDLING, 4981 4914 RTW89_FLAG_WOWLAN, 4982 - RTW89_FLAG_FORBIDDEN_TRACK_WROK, 4915 + RTW89_FLAG_FORBIDDEN_TRACK_WORK, 4983 4916 RTW89_FLAG_CHANGING_INTERFACE, 4984 4917 RTW89_FLAG_HW_RFKILL_STATE, 4985 4918 ··· 5514 5447 u16 h2c_len; 5515 5448 }; 5516 5449 5450 + struct rtw89_hw_scan_extra_op { 5451 + bool set; 5452 + u8 macid; 5453 + struct rtw89_chan chan; 5454 + }; 5455 + 5517 5456 struct rtw89_hw_scan_info { 5518 5457 struct rtw89_vif_link *scanning_vif; 5519 5458 struct list_head pkt_list[NUM_NL80211_BANDS]; 5520 5459 struct list_head chan_list; 5521 5460 struct rtw89_chan op_chan; 5461 + struct rtw89_hw_scan_extra_op extra_op; 5522 5462 bool connected; 5523 5463 bool abort; 5524 5464 }; ··· 5746 5672 5747 5673 /* byte-array in LE order for FW */ 5748 5674 u8 macid_bitmap[BITS_TO_BYTES(RTW89_MAX_MAC_ID_NUM)]; 5675 + u8 probe_count; 5749 5676 5750 5677 u16 duration; /* TU */ 5751 5678 u16 beacon_interval; /* TU */ ··· 5803 5728 struct rtw89_mcc_sync sync; 5804 5729 u64 start_tsf; 5805 5730 u64 start_tsf_in_aux_domain; 5731 + u64 prepare_delay; 5806 5732 u16 mcc_interval; /* TU */ 5807 5733 u16 beacon_offset; /* TU */ 5808 5734 }; ··· 5934 5858 struct wiphy_delayed_work coex_bt_devinfo_work; 5935 5859 struct wiphy_delayed_work coex_rfk_chk_work; 5936 5860 struct wiphy_delayed_work cfo_track_work; 5861 + struct wiphy_delayed_work mcc_prepare_done_work; 5937 5862 struct delayed_work forbid_ba_work; 5938 5863 struct wiphy_delayed_work antdiv_work; 5939 5864 struct rtw89_ppdu_sts_info ppdu_sts; ··· 6957 6880 return chip->ops->get_thermal(rtwdev, rf_path); 6958 6881 } 6959 6882 6883 + static inline u32 rtw89_chip_chan_to_rf18_val(struct rtw89_dev *rtwdev, 6884 + const struct rtw89_chan *chan) 6885 + { 6886 + const struct rtw89_chip_info *chip = rtwdev->chip; 6887 + 6888 + if (!chip->ops->chan_to_rf18_val) 6889 + return 0; 6890 + 6891 + return chip->ops->chan_to_rf18_val(rtwdev, chan); 6892 + } 6893 + 6960 6894 static inline void rtw89_chip_query_ppdu(struct rtw89_dev *rtwdev, 6961 6895 struct rtw89_rx_phy_ppdu *phy_ppdu, 6962 6896 struct ieee80211_rx_status *status) ··· 7405 7317 int rtw89_core_start(struct rtw89_dev *rtwdev); 7406 7318 void rtw89_core_stop(struct rtw89_dev *rtwdev); 7407 7319 void rtw89_core_update_beacon_work(struct wiphy *wiphy, struct wiphy_work *work); 7320 + void rtw89_core_csa_beacon_work(struct wiphy *wiphy, struct wiphy_work *work); 7321 + int rtw89_core_send_nullfunc(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link, 7322 + bool qos, bool ps, int timeout); 7408 7323 void rtw89_roc_work(struct wiphy *wiphy, struct wiphy_work *work); 7409 7324 void rtw89_roc_start(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif); 7410 7325 void rtw89_roc_end(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif);
+7 -6
drivers/net/wireless/realtek/rtw89/debug.c
··· 1114 1114 const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def; 1115 1115 u32 filter_model_addr = mac->filter_model_addr; 1116 1116 u32 indir_access_addr = mac->indir_access_addr; 1117 + u32 mem_page_size = mac->mem_page_size; 1117 1118 u32 base_addr, start_page, residue; 1118 1119 char *p = buf, *end = buf + bufsz; 1119 1120 u32 i, j, pp, pages; ··· 1122 1121 u32 val; 1123 1122 1124 1123 remain = len; 1125 - pages = len / MAC_MEM_DUMP_PAGE_SIZE + 1; 1126 - start_page = start_addr / MAC_MEM_DUMP_PAGE_SIZE; 1127 - residue = start_addr % MAC_MEM_DUMP_PAGE_SIZE; 1124 + pages = len / mem_page_size + 1; 1125 + start_page = start_addr / mem_page_size; 1126 + residue = start_addr % mem_page_size; 1128 1127 base_addr = mac->mem_base_addrs[sel]; 1129 - base_addr += start_page * MAC_MEM_DUMP_PAGE_SIZE; 1128 + base_addr += start_page * mem_page_size; 1130 1129 1131 1130 for (pp = 0; pp < pages; pp++) { 1132 - dump_len = min_t(u32, remain, MAC_MEM_DUMP_PAGE_SIZE); 1131 + dump_len = min_t(u32, remain, mem_page_size); 1133 1132 rtw89_write32(rtwdev, filter_model_addr, base_addr); 1134 1133 for (i = indir_access_addr + residue; 1135 1134 i < indir_access_addr + dump_len;) { ··· 1143 1142 } 1144 1143 p += scnprintf(p, end - p, "\n"); 1145 1144 } 1146 - base_addr += MAC_MEM_DUMP_PAGE_SIZE; 1145 + base_addr += mem_page_size; 1147 1146 } 1148 1147 1149 1148 return p - buf;
+285 -29
drivers/net/wireless/realtek/rtw89/fw.c
··· 833 833 __CFG_FW_FEAT(RTL8852BT, ge, 0, 29, 91, 0, SCAN_OFFLOAD), 834 834 __CFG_FW_FEAT(RTL8852BT, ge, 0, 29, 110, 0, BEACON_FILTER), 835 835 __CFG_FW_FEAT(RTL8852C, le, 0, 27, 33, 0, NO_DEEP_PS), 836 + __CFG_FW_FEAT(RTL8852C, ge, 0, 0, 0, 0, RFK_NTFY_MCC_V0), 836 837 __CFG_FW_FEAT(RTL8852C, ge, 0, 27, 34, 0, TX_WAKE), 837 838 __CFG_FW_FEAT(RTL8852C, ge, 0, 27, 36, 0, SCAN_OFFLOAD), 838 839 __CFG_FW_FEAT(RTL8852C, ge, 0, 27, 40, 0, CRASH_TRIGGER), 839 840 __CFG_FW_FEAT(RTL8852C, ge, 0, 27, 56, 10, BEACON_FILTER), 840 841 __CFG_FW_FEAT(RTL8852C, ge, 0, 27, 80, 0, WOW_REASON_V1), 842 + __CFG_FW_FEAT(RTL8852C, ge, 0, 27, 128, 0, BEACON_LOSS_COUNT_V1), 841 843 __CFG_FW_FEAT(RTL8922A, ge, 0, 34, 30, 0, CRASH_TRIGGER), 842 844 __CFG_FW_FEAT(RTL8922A, ge, 0, 34, 11, 0, MACID_PAUSE_SLEEP), 843 845 __CFG_FW_FEAT(RTL8922A, ge, 0, 34, 35, 0, SCAN_OFFLOAD), 844 846 __CFG_FW_FEAT(RTL8922A, lt, 0, 35, 21, 0, SCAN_OFFLOAD_BE_V0), 845 847 __CFG_FW_FEAT(RTL8922A, ge, 0, 35, 12, 0, BEACON_FILTER), 846 848 __CFG_FW_FEAT(RTL8922A, ge, 0, 35, 22, 0, WOW_REASON_V1), 849 + __CFG_FW_FEAT(RTL8922A, lt, 0, 35, 28, 0, RFK_IQK_V0), 847 850 __CFG_FW_FEAT(RTL8922A, lt, 0, 35, 31, 0, RFK_PRE_NOTIFY_V0), 848 851 __CFG_FW_FEAT(RTL8922A, lt, 0, 35, 31, 0, LPS_CH_INFO), 849 852 __CFG_FW_FEAT(RTL8922A, lt, 0, 35, 42, 0, RFK_RXDCK_V0), ··· 3033 3030 #define H2C_P2P_ACT_LEN 20 3034 3031 int rtw89_fw_h2c_p2p_act(struct rtw89_dev *rtwdev, 3035 3032 struct rtw89_vif_link *rtwvif_link, 3036 - struct ieee80211_bss_conf *bss_conf, 3037 3033 struct ieee80211_p2p_noa_desc *desc, 3038 - u8 act, u8 noa_id) 3034 + u8 act, u8 noa_id, u8 ctwindow_oppps) 3039 3035 { 3040 3036 bool p2p_type_gc = rtwvif_link->wifi_role == RTW89_WIFI_ROLE_P2P_CLIENT; 3041 - u8 ctwindow_oppps = bss_conf->p2p_noa_attr.oppps_ctwindow; 3042 3037 struct sk_buff *skb; 3043 3038 u8 *cmd; 3044 3039 int ret; ··· 5084 5083 return ret; 5085 5084 } 5086 5085 5086 + int rtw89_fw_h2c_cxdrv_osi_info(struct rtw89_dev *rtwdev, u8 type) 5087 + { 5088 + struct rtw89_btc *btc = &rtwdev->btc; 5089 + struct rtw89_btc_fbtc_outsrc_set_info *osi = &btc->dm.ost_info; 5090 + struct rtw89_h2c_cxosi *h2c; 5091 + u32 len = sizeof(*h2c); 5092 + struct sk_buff *skb; 5093 + int ret; 5094 + 5095 + skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len); 5096 + if (!skb) { 5097 + rtw89_err(rtwdev, "failed to alloc skb for h2c cxdrv_osi\n"); 5098 + return -ENOMEM; 5099 + } 5100 + skb_put(skb, len); 5101 + h2c = (struct rtw89_h2c_cxosi *)skb->data; 5102 + 5103 + h2c->hdr.type = type; 5104 + h2c->hdr.ver = btc->ver->fcxosi; 5105 + h2c->hdr.len = len - H2C_LEN_CXDRVHDR_V7; 5106 + h2c->osi = *osi; 5107 + 5108 + rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 5109 + H2C_CAT_OUTSRC, BTFC_SET, 5110 + SET_DRV_INFO, 0, 0, 5111 + len); 5112 + 5113 + ret = rtw89_h2c_tx(rtwdev, skb, false); 5114 + if (ret) { 5115 + rtw89_err(rtwdev, "failed to send h2c\n"); 5116 + goto fail; 5117 + } 5118 + 5119 + return 0; 5120 + fail: 5121 + dev_kfree_skb_any(skb); 5122 + 5123 + return ret; 5124 + } 5125 + 5087 5126 #define H2C_LEN_CXDRVINFO_CTRL (4 + H2C_LEN_CXDRVHDR) 5088 5127 int rtw89_fw_h2c_cxdrv_ctrl(struct rtw89_dev *rtwdev, u8 type) 5089 5128 { ··· 5402 5361 int rtw89_fw_h2c_scan_list_offload_ax(struct rtw89_dev *rtwdev, int ch_num, 5403 5362 struct list_head *chan_list) 5404 5363 { 5364 + struct rtw89_hw_scan_info *scan_info = &rtwdev->scan_info; 5405 5365 struct rtw89_wait_info *wait = &rtwdev->mac.fw_ofld_wait; 5406 5366 struct rtw89_h2c_chinfo_elem *elem; 5407 5367 struct rtw89_mac_chinfo_ax *ch_info; ··· 5444 5402 le32_encode_bits(ch_info->dfs_ch, RTW89_H2C_CHINFO_W1_DFS) | 5445 5403 le32_encode_bits(ch_info->tx_null, RTW89_H2C_CHINFO_W1_TX_NULL) | 5446 5404 le32_encode_bits(ch_info->rand_seq_num, RTW89_H2C_CHINFO_W1_RANDOM); 5405 + 5406 + if (scan_info->extra_op.set) 5407 + elem->w1 |= le32_encode_bits(ch_info->macid_tx, 5408 + RTW89_H2C_CHINFO_W1_MACID_TX); 5447 5409 5448 5410 elem->w2 = le32_encode_bits(ch_info->pkt_id[0], RTW89_H2C_CHINFO_W2_PKT0) | 5449 5411 le32_encode_bits(ch_info->pkt_id[1], RTW89_H2C_CHINFO_W2_PKT1) | ··· 5589 5543 struct rtw89_vif_link *rtwvif_link, 5590 5544 bool wowlan) 5591 5545 { 5546 + struct rtw89_hw_scan_info *scan_info = &rtwdev->scan_info; 5592 5547 struct rtw89_wait_info *wait = &rtwdev->mac.fw_ofld_wait; 5593 5548 struct rtw89_chan *op = &rtwdev->scan_info.op_chan; 5594 5549 enum rtw89_scan_mode scan_mode = RTW89_SCAN_IMMEDIATE; ··· 5648 5601 RTW89_H2C_SCANOFLD_W3_TSF_HIGH); 5649 5602 h2c->tsf_low = le32_encode_bits(lower_32_bits(tsf), 5650 5603 RTW89_H2C_SCANOFLD_W4_TSF_LOW); 5604 + 5605 + if (scan_info->extra_op.set) 5606 + h2c->w6 = le32_encode_bits(scan_info->extra_op.macid, 5607 + RTW89_H2C_SCANOFLD_W6_SECOND_MACID); 5651 5608 5652 5609 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 5653 5610 H2C_CAT_MAC, H2C_CL_MAC_FW_OFLD, ··· 5928 5877 int rtw89_fw_h2c_rf_ntfy_mcc(struct rtw89_dev *rtwdev) 5929 5878 { 5930 5879 struct rtw89_rfk_mcc_info_data *rfk_mcc = rtwdev->rfk_mcc.data; 5880 + struct rtw89_fw_h2c_rf_get_mccch_v0 *mccch_v0; 5931 5881 struct rtw89_fw_h2c_rf_get_mccch *mccch; 5882 + u32 len = sizeof(*mccch); 5932 5883 struct sk_buff *skb; 5884 + u8 ver = U8_MAX; 5933 5885 int ret; 5934 5886 u8 idx; 5935 5887 5936 - skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, sizeof(*mccch)); 5888 + if (RTW89_CHK_FW_FEATURE(RFK_NTFY_MCC_V0, &rtwdev->fw)) { 5889 + len = sizeof(*mccch_v0); 5890 + ver = 0; 5891 + } 5892 + 5893 + skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len); 5937 5894 if (!skb) { 5938 5895 rtw89_err(rtwdev, "failed to alloc skb for h2c cxdrv_ctrl\n"); 5939 5896 return -ENOMEM; 5940 5897 } 5941 - skb_put(skb, sizeof(*mccch)); 5942 - mccch = (struct rtw89_fw_h2c_rf_get_mccch *)skb->data; 5898 + skb_put(skb, len); 5943 5899 5944 5900 idx = rfk_mcc->table_idx; 5945 - mccch->ch_0 = cpu_to_le32(rfk_mcc->ch[0]); 5946 - mccch->ch_1 = cpu_to_le32(rfk_mcc->ch[1]); 5947 - mccch->band_0 = cpu_to_le32(rfk_mcc->band[0]); 5948 - mccch->band_1 = cpu_to_le32(rfk_mcc->band[1]); 5949 - mccch->current_channel = cpu_to_le32(rfk_mcc->ch[idx]); 5950 - mccch->current_band_type = cpu_to_le32(rfk_mcc->band[idx]); 5901 + if (ver == 0) { 5902 + mccch_v0 = (struct rtw89_fw_h2c_rf_get_mccch_v0 *)skb->data; 5903 + mccch_v0->ch_0 = cpu_to_le32(rfk_mcc->ch[0]); 5904 + mccch_v0->ch_1 = cpu_to_le32(rfk_mcc->ch[1]); 5905 + mccch_v0->band_0 = cpu_to_le32(rfk_mcc->band[0]); 5906 + mccch_v0->band_1 = cpu_to_le32(rfk_mcc->band[1]); 5907 + mccch_v0->current_band_type = cpu_to_le32(rfk_mcc->band[idx]); 5908 + mccch_v0->current_channel = cpu_to_le32(rfk_mcc->ch[idx]); 5909 + } else { 5910 + mccch = (struct rtw89_fw_h2c_rf_get_mccch *)skb->data; 5911 + mccch->ch_0_0 = cpu_to_le32(rfk_mcc->ch[0]); 5912 + mccch->ch_0_1 = cpu_to_le32(rfk_mcc->ch[0]); 5913 + mccch->ch_1_0 = cpu_to_le32(rfk_mcc->ch[1]); 5914 + mccch->ch_1_1 = cpu_to_le32(rfk_mcc->ch[1]); 5915 + mccch->current_channel = cpu_to_le32(rfk_mcc->ch[idx]); 5916 + } 5951 5917 5952 5918 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 5953 5919 H2C_CAT_OUTSRC, H2C_CL_OUTSRC_RF_FW_NOTIFY, 5954 5920 H2C_FUNC_OUTSRC_RF_GET_MCCCH, 0, 0, 5955 - sizeof(*mccch)); 5921 + len); 5956 5922 5957 5923 ret = rtw89_h2c_tx(rtwdev, skb, false); 5958 5924 if (ret) { ··· 5984 5916 return ret; 5985 5917 } 5986 5918 EXPORT_SYMBOL(rtw89_fw_h2c_rf_ntfy_mcc); 5919 + 5920 + int rtw89_fw_h2c_rf_ps_info(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif) 5921 + { 5922 + const struct rtw89_chip_info *chip = rtwdev->chip; 5923 + struct rtw89_vif_link *rtwvif_link; 5924 + struct rtw89_h2c_rf_ps_info *h2c; 5925 + const struct rtw89_chan *chan; 5926 + u32 len = sizeof(*h2c); 5927 + unsigned int link_id; 5928 + struct sk_buff *skb; 5929 + int ret; 5930 + u8 path; 5931 + u32 val; 5932 + 5933 + if (chip->chip_gen != RTW89_CHIP_BE) 5934 + return 0; 5935 + 5936 + skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len); 5937 + if (!skb) { 5938 + rtw89_err(rtwdev, "failed to alloc skb for h2c rf ps info\n"); 5939 + return -ENOMEM; 5940 + } 5941 + skb_put(skb, len); 5942 + h2c = (struct rtw89_h2c_rf_ps_info *)skb->data; 5943 + h2c->mlo_mode = cpu_to_le32(rtwdev->mlo_dbcc_mode); 5944 + 5945 + rtw89_vif_for_each_link(rtwvif, rtwvif_link, link_id) { 5946 + chan = rtw89_chan_get(rtwdev, rtwvif_link->chanctx_idx); 5947 + path = rtw89_phy_get_syn_sel(rtwdev, rtwvif_link->phy_idx); 5948 + val = rtw89_chip_chan_to_rf18_val(rtwdev, chan); 5949 + 5950 + if (path >= chip->rf_path_num) { 5951 + rtw89_err(rtwdev, "unsupported rf path (%d)\n", path); 5952 + ret = -ENOENT; 5953 + goto fail; 5954 + } 5955 + 5956 + h2c->rf18[path] = cpu_to_le32(val); 5957 + h2c->pri_ch[path] = chan->primary_channel; 5958 + } 5959 + 5960 + rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 5961 + H2C_CAT_OUTSRC, H2C_CL_OUTSRC_RF_FW_NOTIFY, 5962 + H2C_FUNC_OUTSRC_RF_PS_INFO, 0, 0, 5963 + sizeof(*h2c)); 5964 + 5965 + ret = rtw89_h2c_tx(rtwdev, skb, false); 5966 + if (ret) { 5967 + rtw89_err(rtwdev, "failed to send h2c\n"); 5968 + goto fail; 5969 + } 5970 + 5971 + return 0; 5972 + fail: 5973 + dev_kfree_skb_any(skb); 5974 + 5975 + return ret; 5976 + } 5977 + EXPORT_SYMBOL(rtw89_fw_h2c_rf_ps_info); 5987 5978 5988 5979 int rtw89_fw_h2c_rf_pre_ntfy(struct rtw89_dev *rtwdev, 5989 5980 enum rtw89_phy_idx phy_idx) ··· 6158 6031 int rtw89_fw_h2c_rf_tssi(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx, 6159 6032 const struct rtw89_chan *chan, enum rtw89_tssi_mode tssi_mode) 6160 6033 { 6034 + struct rtw89_efuse *efuse = &rtwdev->efuse; 6161 6035 struct rtw89_hal *hal = &rtwdev->hal; 6162 6036 struct rtw89_h2c_rf_tssi *h2c; 6163 6037 u32 len = sizeof(*h2c); ··· 6181 6053 h2c->hwtx_en = true; 6182 6054 h2c->cv = hal->cv; 6183 6055 h2c->tssi_mode = tssi_mode; 6056 + h2c->rfe_type = efuse->rfe_type; 6184 6057 6185 6058 rtw89_phy_rfk_tssi_fill_fwcmd_efuse_to_de(rtwdev, phy_idx, chan, h2c); 6186 6059 rtw89_phy_rfk_tssi_fill_fwcmd_tmeter_tbl(rtwdev, phy_idx, chan, h2c); ··· 6206 6077 int rtw89_fw_h2c_rf_iqk(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx, 6207 6078 const struct rtw89_chan *chan) 6208 6079 { 6080 + struct rtw89_hal *hal = &rtwdev->hal; 6081 + struct rtw89_h2c_rf_iqk_v0 *h2c_v0; 6209 6082 struct rtw89_h2c_rf_iqk *h2c; 6210 6083 u32 len = sizeof(*h2c); 6211 6084 struct sk_buff *skb; 6085 + u8 ver = U8_MAX; 6212 6086 int ret; 6087 + 6088 + if (RTW89_CHK_FW_FEATURE(RFK_IQK_V0, &rtwdev->fw)) { 6089 + len = sizeof(*h2c_v0); 6090 + ver = 0; 6091 + } 6213 6092 6214 6093 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len); 6215 6094 if (!skb) { ··· 6225 6088 return -ENOMEM; 6226 6089 } 6227 6090 skb_put(skb, len); 6091 + 6092 + if (ver == 0) { 6093 + h2c_v0 = (struct rtw89_h2c_rf_iqk_v0 *)skb->data; 6094 + 6095 + h2c_v0->phy_idx = cpu_to_le32(phy_idx); 6096 + h2c_v0->dbcc = cpu_to_le32(rtwdev->dbcc_en); 6097 + 6098 + goto done; 6099 + } 6100 + 6228 6101 h2c = (struct rtw89_h2c_rf_iqk *)skb->data; 6229 6102 6230 - h2c->phy_idx = cpu_to_le32(phy_idx); 6231 - h2c->dbcc = cpu_to_le32(rtwdev->dbcc_en); 6103 + h2c->len = sizeof(*h2c); 6104 + h2c->ktype = 0; 6105 + h2c->phy = phy_idx; 6106 + h2c->kpath = rtw89_phy_get_kpath(rtwdev, phy_idx); 6107 + h2c->band = chan->band_type; 6108 + h2c->bw = chan->band_width; 6109 + h2c->ch = chan->channel; 6110 + h2c->cv = hal->cv; 6232 6111 6112 + done: 6233 6113 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 6234 6114 H2C_CAT_OUTSRC, H2C_CL_OUTSRC_RF_FW_RFK, 6235 6115 H2C_FUNC_RFK_IQK_OFFLOAD, 0, 0, len); ··· 6999 6845 { 7000 6846 struct rtw89_hw_scan_info *scan_info = &rtwdev->scan_info; 7001 6847 struct rtw89_vif_link *rtwvif_link = rtwdev->scan_info.scanning_vif; 6848 + const struct rtw89_hw_scan_extra_op *ext = &scan_info->extra_op; 7002 6849 struct rtw89_vif *rtwvif = rtwvif_link->rtwvif; 7003 6850 struct ieee80211_scan_ies *ies = rtwvif->scan_ies; 7004 6851 struct cfg80211_scan_request *req = rtwvif->scan_req; ··· 7069 6914 break; 7070 6915 case RTW89_CHAN_ACTIVE: 7071 6916 ch_info->pause_data = true; 6917 + break; 6918 + case RTW89_CHAN_EXTRA_OP: 6919 + ch_info->central_ch = ext->chan.channel; 6920 + ch_info->pri_ch = ext->chan.primary_channel; 6921 + ch_info->ch_band = ext->chan.band_type; 6922 + ch_info->bw = ext->chan.band_width; 6923 + ch_info->tx_null = true; 6924 + ch_info->num_pkt = 0; 6925 + ch_info->macid_tx = true; 7072 6926 break; 7073 6927 default: 7074 6928 rtw89_err(rtwdev, "Channel type out of bound\n"); ··· 7237 7073 return ret; 7238 7074 } 7239 7075 7076 + static int rtw89_hw_scan_add_op_types_ax(struct rtw89_dev *rtwdev, 7077 + enum rtw89_chan_type type, 7078 + struct list_head *chan_list, 7079 + struct cfg80211_scan_request *req, 7080 + int *off_chan_time) 7081 + { 7082 + struct rtw89_mac_chinfo_ax *tmp; 7083 + 7084 + tmp = kzalloc(sizeof(*tmp), GFP_KERNEL); 7085 + if (!tmp) 7086 + return -ENOMEM; 7087 + 7088 + switch (type) { 7089 + case RTW89_CHAN_OPERATE: 7090 + tmp->period = req->duration_mandatory ? 7091 + req->duration : RTW89_CHANNEL_TIME; 7092 + *off_chan_time = 0; 7093 + break; 7094 + case RTW89_CHAN_EXTRA_OP: 7095 + tmp->period = RTW89_CHANNEL_TIME_EXTRA_OP; 7096 + /* still calc @off_chan_time for scan op */ 7097 + *off_chan_time += tmp->period; 7098 + break; 7099 + default: 7100 + kfree(tmp); 7101 + return -EINVAL; 7102 + } 7103 + 7104 + rtw89_hw_scan_add_chan_ax(rtwdev, type, 0, tmp); 7105 + list_add_tail(&tmp->list, chan_list); 7106 + 7107 + return 0; 7108 + } 7109 + 7240 7110 int rtw89_hw_scan_prep_chan_list_ax(struct rtw89_dev *rtwdev, 7241 7111 struct rtw89_vif_link *rtwvif_link) 7242 7112 { 7243 7113 struct rtw89_hw_scan_info *scan_info = &rtwdev->scan_info; 7114 + const struct rtw89_hw_scan_extra_op *ext = &scan_info->extra_op; 7244 7115 struct rtw89_vif *rtwvif = rtwvif_link->rtwvif; 7245 7116 struct cfg80211_scan_request *req = rtwvif->scan_req; 7246 7117 struct rtw89_mac_chinfo_ax *ch_info, *tmp; ··· 7302 7103 else if (channel->band == NL80211_BAND_6GHZ) 7303 7104 ch_info->period = RTW89_CHANNEL_TIME_6G + 7304 7105 RTW89_DWELL_TIME_6G; 7106 + else if (rtwvif_link->wifi_role == RTW89_WIFI_ROLE_P2P_CLIENT) 7107 + ch_info->period = RTW89_P2P_CHAN_TIME; 7305 7108 else 7306 7109 ch_info->period = RTW89_CHANNEL_TIME; 7307 7110 ··· 7320 7119 type = RTW89_CHAN_ACTIVE; 7321 7120 rtw89_hw_scan_add_chan_ax(rtwdev, type, req->n_ssids, ch_info); 7322 7121 7323 - if (scan_info->connected && 7324 - off_chan_time + ch_info->period > RTW89_OFF_CHAN_TIME) { 7325 - tmp = kzalloc(sizeof(*tmp), GFP_KERNEL); 7326 - if (!tmp) { 7327 - ret = -ENOMEM; 7328 - kfree(ch_info); 7329 - goto out; 7330 - } 7122 + if (!(scan_info->connected && 7123 + off_chan_time + ch_info->period > RTW89_OFF_CHAN_TIME)) 7124 + goto next; 7331 7125 7332 - type = RTW89_CHAN_OPERATE; 7333 - tmp->period = req->duration_mandatory ? 7334 - req->duration : RTW89_CHANNEL_TIME; 7335 - rtw89_hw_scan_add_chan_ax(rtwdev, type, 0, tmp); 7336 - list_add_tail(&tmp->list, &chan_list); 7337 - off_chan_time = 0; 7126 + ret = rtw89_hw_scan_add_op_types_ax(rtwdev, RTW89_CHAN_OPERATE, 7127 + &chan_list, req, &off_chan_time); 7128 + if (ret) { 7129 + kfree(ch_info); 7130 + goto out; 7338 7131 } 7132 + 7133 + if (!ext->set) 7134 + goto next; 7135 + 7136 + ret = rtw89_hw_scan_add_op_types_ax(rtwdev, RTW89_CHAN_EXTRA_OP, 7137 + &chan_list, req, &off_chan_time); 7138 + if (ret) { 7139 + kfree(ch_info); 7140 + goto out; 7141 + } 7142 + 7143 + next: 7339 7144 list_add_tail(&ch_info->list, &chan_list); 7340 7145 off_chan_time += ch_info->period; 7341 7146 } ··· 7480 7273 ch_info->period = req->duration; 7481 7274 else if (channel->band == NL80211_BAND_6GHZ) 7482 7275 ch_info->period = RTW89_CHANNEL_TIME_6G + RTW89_DWELL_TIME_6G; 7276 + else if (rtwvif_link->wifi_role == RTW89_WIFI_ROLE_P2P_CLIENT) 7277 + ch_info->period = RTW89_P2P_CHAN_TIME; 7483 7278 else 7484 7279 ch_info->period = RTW89_CHANNEL_TIME; 7485 7280 ··· 7645 7436 } 7646 7437 } 7647 7438 7439 + static void rtw89_hw_scan_set_extra_op_info(struct rtw89_dev *rtwdev, 7440 + struct rtw89_vif *scan_rtwvif, 7441 + const struct rtw89_chan *scan_op) 7442 + { 7443 + struct rtw89_entity_mgnt *mgnt = &rtwdev->hal.entity_mgnt; 7444 + struct rtw89_hw_scan_info *scan_info = &rtwdev->scan_info; 7445 + struct rtw89_hw_scan_extra_op *ext = &scan_info->extra_op; 7446 + struct rtw89_vif *tmp; 7447 + 7448 + ext->set = false; 7449 + if (!RTW89_CHK_FW_FEATURE(SCAN_OFFLOAD_EXTRA_OP, &rtwdev->fw)) 7450 + return; 7451 + 7452 + list_for_each_entry(tmp, &mgnt->active_list, mgnt_entry) { 7453 + const struct rtw89_chan *tmp_chan; 7454 + struct rtw89_vif_link *tmp_link; 7455 + 7456 + if (tmp == scan_rtwvif) 7457 + continue; 7458 + 7459 + tmp_link = rtw89_vif_get_link_inst(tmp, 0); 7460 + if (unlikely(!tmp_link)) { 7461 + rtw89_debug(rtwdev, RTW89_DBG_HW_SCAN, 7462 + "hw scan: no HW-0 link for extra op\n"); 7463 + continue; 7464 + } 7465 + 7466 + tmp_chan = rtw89_chan_get(rtwdev, tmp_link->chanctx_idx); 7467 + *ext = (struct rtw89_hw_scan_extra_op){ 7468 + .set = true, 7469 + .macid = tmp_link->mac_id, 7470 + .chan = *tmp_chan, 7471 + }; 7472 + 7473 + rtw89_debug(rtwdev, RTW89_DBG_HW_SCAN, 7474 + "hw scan: extra op: center %d primary %d\n", 7475 + ext->chan.channel, ext->chan.primary_channel); 7476 + break; 7477 + } 7478 + } 7479 + 7648 7480 int rtw89_hw_scan_start(struct rtw89_dev *rtwdev, 7649 7481 struct rtw89_vif_link *rtwvif_link, 7650 7482 struct ieee80211_scan_request *scan_req) ··· 7707 7457 7708 7458 /* clone op and keep it during scan */ 7709 7459 rtwdev->scan_info.op_chan = *chan; 7460 + 7461 + rtw89_debug(rtwdev, RTW89_DBG_HW_SCAN, 7462 + "hw scan: op: center %d primary %d\n", 7463 + chan->channel, chan->primary_channel); 7464 + 7465 + rtw89_hw_scan_set_extra_op_info(rtwdev, rtwvif, chan); 7710 7466 7711 7467 rtwdev->scan_info.connected = rtw89_is_any_vif_connected_or_connecting(rtwdev); 7712 7468 rtwdev->scan_info.scanning_vif = rtwvif_link;
+44 -5
drivers/net/wireless/realtek/rtw89/fw.h
··· 237 237 RTW89_CHAN_OPERATE = 0, 238 238 RTW89_CHAN_ACTIVE, 239 239 RTW89_CHAN_DFS, 240 + RTW89_CHAN_EXTRA_OP, 240 241 }; 241 242 242 243 enum rtw89_p2pps_action { ··· 317 316 #define RTW89_H2C_MAX_SIZE 2048 318 317 #define RTW89_CHANNEL_TIME 45 319 318 #define RTW89_CHANNEL_TIME_6G 20 319 + #define RTW89_CHANNEL_TIME_EXTRA_OP 30 320 320 #define RTW89_DFS_CHAN_TIME 105 321 321 #define RTW89_OFF_CHAN_TIME 100 322 + #define RTW89_P2P_CHAN_TIME 105 322 323 #define RTW89_DWELL_TIME 20 323 324 #define RTW89_DWELL_TIME_6G 10 324 325 #define RTW89_SCAN_WIDTH 0 ··· 355 352 u8 tx_null:1; 356 353 u8 rand_seq_num:1; 357 354 u8 cfg_tx_pwr:1; 358 - u8 rsvd0: 4; 355 + u8 macid_tx: 1; 356 + u8 rsvd0: 3; 359 357 u8 pkt_id[RTW89_SCANOFLD_MAX_SSID]; 360 358 u16 tx_pwr_idx; 361 359 u8 rsvd1; ··· 2251 2247 struct rtw89_btc_wl_role_info_v8_u32 _u32; 2252 2248 } __packed; 2253 2249 2250 + struct rtw89_h2c_cxosi { 2251 + struct rtw89_h2c_cxhdr_v7 hdr; 2252 + struct rtw89_btc_fbtc_outsrc_set_info osi; 2253 + } __packed; 2254 + 2254 2255 struct rtw89_h2c_cxinit { 2255 2256 struct rtw89_h2c_cxhdr hdr; 2256 2257 u8 ant_type; ··· 2683 2674 #define RTW89_H2C_CHINFO_W1_TX_NULL BIT(25) 2684 2675 #define RTW89_H2C_CHINFO_W1_RANDOM BIT(26) 2685 2676 #define RTW89_H2C_CHINFO_W1_CFG_TX BIT(27) 2677 + #define RTW89_H2C_CHINFO_W1_MACID_TX BIT(29) 2686 2678 #define RTW89_H2C_CHINFO_W2_PKT0 GENMASK(7, 0) 2687 2679 #define RTW89_H2C_CHINFO_W2_PKT1 GENMASK(15, 8) 2688 2680 #define RTW89_H2C_CHINFO_W2_PKT2 GENMASK(23, 16) ··· 2783 2773 #define RTW89_H2C_SCANOFLD_W2_SLOW_PD GENMASK(23, 16) 2784 2774 #define RTW89_H2C_SCANOFLD_W3_TSF_HIGH GENMASK(31, 0) 2785 2775 #define RTW89_H2C_SCANOFLD_W4_TSF_LOW GENMASK(31, 0) 2776 + #define RTW89_H2C_SCANOFLD_W6_SECOND_MACID GENMASK(31, 24) 2786 2777 2787 2778 struct rtw89_h2c_scanofld_be_macc_role { 2788 2779 __le32 w0; ··· 4348 4337 #define H2C_CL_OUTSRC_RF_REG_B 0x9 4349 4338 #define H2C_CL_OUTSRC_RF_FW_NOTIFY 0xa 4350 4339 #define H2C_FUNC_OUTSRC_RF_GET_MCCCH 0x2 4340 + #define H2C_FUNC_OUTSRC_RF_PS_INFO 0x10 4351 4341 #define H2C_CL_OUTSRC_RF_FW_RFK 0xb 4352 4342 4353 4343 enum rtw89_rfk_offload_h2c_func { ··· 4362 4350 }; 4363 4351 4364 4352 struct rtw89_fw_h2c_rf_get_mccch { 4353 + __le32 ch_0_0; 4354 + __le32 ch_0_1; 4355 + __le32 ch_1_0; 4356 + __le32 ch_1_1; 4357 + __le32 current_channel; 4358 + } __packed; 4359 + 4360 + struct rtw89_fw_h2c_rf_get_mccch_v0 { 4365 4361 __le32 ch_0; 4366 4362 __le32 ch_1; 4367 4363 __le32 band_0; ··· 4380 4360 4381 4361 #define NUM_OF_RTW89_FW_RFK_PATH 2 4382 4362 #define NUM_OF_RTW89_FW_RFK_TBL 3 4363 + 4364 + struct rtw89_h2c_rf_ps_info { 4365 + __le32 rf18[NUM_OF_RTW89_FW_RFK_PATH]; 4366 + __le32 mlo_mode; 4367 + u8 pri_ch[NUM_OF_RTW89_FW_RFK_PATH]; 4368 + } __packed; 4383 4369 4384 4370 struct rtw89_fw_h2c_rfk_pre_info_common { 4385 4371 struct { ··· 4461 4435 u8 pg_thermal[2]; 4462 4436 u8 ftable[2][128]; 4463 4437 u8 tssi_mode; 4438 + u8 rfe_type; 4439 + } __packed; 4440 + 4441 + struct rtw89_h2c_rf_iqk_v0 { 4442 + __le32 phy_idx; 4443 + __le32 dbcc; 4464 4444 } __packed; 4465 4445 4466 4446 struct rtw89_h2c_rf_iqk { 4467 - __le32 phy_idx; 4468 - __le32 dbcc; 4447 + u8 len; 4448 + u8 ktype; 4449 + u8 phy; 4450 + u8 kpath; 4451 + u8 band; 4452 + u8 bw; 4453 + u8 ch; 4454 + u8 cv; 4469 4455 } __packed; 4470 4456 4471 4457 struct rtw89_h2c_rf_dpk { ··· 4751 4713 int rtw89_fw_h2c_cxdrv_role_v2(struct rtw89_dev *rtwdev, u8 type); 4752 4714 int rtw89_fw_h2c_cxdrv_role_v7(struct rtw89_dev *rtwdev, u8 type); 4753 4715 int rtw89_fw_h2c_cxdrv_role_v8(struct rtw89_dev *rtwdev, u8 type); 4716 + int rtw89_fw_h2c_cxdrv_osi_info(struct rtw89_dev *rtwdev, u8 type); 4754 4717 int rtw89_fw_h2c_cxdrv_ctrl(struct rtw89_dev *rtwdev, u8 type); 4755 4718 int rtw89_fw_h2c_cxdrv_ctrl_v7(struct rtw89_dev *rtwdev, u8 type); 4756 4719 int rtw89_fw_h2c_cxdrv_trx(struct rtw89_dev *rtwdev, u8 type); ··· 4771 4732 struct rtw89_fw_h2c_rf_reg_info *info, 4772 4733 u16 len, u8 page); 4773 4734 int rtw89_fw_h2c_rf_ntfy_mcc(struct rtw89_dev *rtwdev); 4735 + int rtw89_fw_h2c_rf_ps_info(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif); 4774 4736 int rtw89_fw_h2c_rf_pre_ntfy(struct rtw89_dev *rtwdev, 4775 4737 enum rtw89_phy_idx phy_idx); 4776 4738 int rtw89_fw_h2c_rf_tssi(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx, ··· 4855 4815 const struct rtw89_pkt_drop_params *params); 4856 4816 int rtw89_fw_h2c_p2p_act(struct rtw89_dev *rtwdev, 4857 4817 struct rtw89_vif_link *rtwvif_link, 4858 - struct ieee80211_bss_conf *bss_conf, 4859 4818 struct ieee80211_p2p_noa_desc *desc, 4860 - u8 act, u8 noa_id); 4819 + u8 act, u8 noa_id, u8 ctwindow_oppps); 4861 4820 int rtw89_fw_h2c_tsf32_toggle(struct rtw89_dev *rtwdev, 4862 4821 struct rtw89_vif_link *rtwvif_link, 4863 4822 bool en);
+57 -11
drivers/net/wireless/realtek/rtw89/mac.c
··· 4388 4388 rtw89_mac_port_cfg_tx_sw(rtwdev, rtwvif_link, en); 4389 4389 } 4390 4390 4391 - void rtw89_mac_enable_beacon_for_ap_vifs(struct rtw89_dev *rtwdev, bool en) 4391 + static void rtw89_mac_enable_ap_bcn_by_chan(struct rtw89_dev *rtwdev, 4392 + struct rtw89_vif_link *rtwvif_link, 4393 + const struct rtw89_chan *to_match, 4394 + bool en) 4395 + { 4396 + const struct rtw89_chan *chan; 4397 + 4398 + if (rtwvif_link->net_type != RTW89_NET_TYPE_AP_MODE) 4399 + return; 4400 + 4401 + if (!to_match) 4402 + goto doit; 4403 + 4404 + /* @to_match may not be in the same domain as return of calling 4405 + * rtw89_chan_get(). So, cannot compare their addresses directly. 4406 + */ 4407 + chan = rtw89_chan_get(rtwdev, rtwvif_link->chanctx_idx); 4408 + if (chan->channel != to_match->channel) 4409 + return; 4410 + 4411 + doit: 4412 + rtw89_mac_port_cfg_tx_sw(rtwdev, rtwvif_link, en); 4413 + } 4414 + 4415 + static void rtw89_mac_enable_aps_bcn_by_chan(struct rtw89_dev *rtwdev, 4416 + const struct rtw89_chan *to_match, 4417 + bool en) 4392 4418 { 4393 4419 struct rtw89_vif_link *rtwvif_link; 4394 4420 struct rtw89_vif *rtwvif; ··· 4422 4396 4423 4397 rtw89_for_each_rtwvif(rtwdev, rtwvif) 4424 4398 rtw89_vif_for_each_link(rtwvif, rtwvif_link, link_id) 4425 - if (rtwvif_link->net_type == RTW89_NET_TYPE_AP_MODE) 4426 - rtw89_mac_port_cfg_tx_sw(rtwdev, rtwvif_link, en); 4399 + rtw89_mac_enable_ap_bcn_by_chan(rtwdev, rtwvif_link, 4400 + to_match, en); 4401 + } 4402 + 4403 + void rtw89_mac_enable_beacon_for_ap_vifs(struct rtw89_dev *rtwdev, bool en) 4404 + { 4405 + rtw89_mac_enable_aps_bcn_by_chan(rtwdev, NULL, en); 4427 4406 } 4428 4407 4429 4408 static void rtw89_mac_port_cfg_bcn_intv(struct rtw89_dev *rtwdev, ··· 4922 4891 { 4923 4892 } 4924 4893 4925 - static bool rtw89_is_op_chan(struct rtw89_dev *rtwdev, u8 band, u8 channel) 4894 + static const struct rtw89_chan * 4895 + rtw89_hw_scan_search_op_chan(struct rtw89_dev *rtwdev, u8 band, u8 channel) 4926 4896 { 4897 + struct rtw89_hw_scan_info *scan_info = &rtwdev->scan_info; 4927 4898 const struct rtw89_chan *op = &rtwdev->scan_info.op_chan; 4928 4899 4929 - return band == op->band_type && channel == op->primary_channel; 4900 + if (band == op->band_type && channel == op->primary_channel) 4901 + return op; 4902 + 4903 + if (scan_info->extra_op.set) { 4904 + op = &scan_info->extra_op.chan; 4905 + if (band == op->band_type && channel == op->primary_channel) 4906 + return op; 4907 + } 4908 + 4909 + return NULL; 4930 4910 } 4931 4911 4932 4912 static void ··· 4947 4905 const struct rtw89_c2h_scanofld *c2h = 4948 4906 (const struct rtw89_c2h_scanofld *)skb->data; 4949 4907 struct rtw89_vif_link *rtwvif_link = rtwdev->scan_info.scanning_vif; 4908 + const struct rtw89_chan *op_chan; 4950 4909 struct rtw89_vif *rtwvif; 4951 4910 struct rtw89_chan new; 4952 4911 u16 actual_period, expect_period; ··· 5003 4960 switch (reason) { 5004 4961 case RTW89_SCAN_LEAVE_OP_NOTIFY: 5005 4962 case RTW89_SCAN_LEAVE_CH_NOTIFY: 5006 - if (rtw89_is_op_chan(rtwdev, band, chan)) { 5007 - rtw89_mac_enable_beacon_for_ap_vifs(rtwdev, false); 4963 + op_chan = rtw89_hw_scan_search_op_chan(rtwdev, band, chan); 4964 + if (op_chan) { 4965 + rtw89_mac_enable_aps_bcn_by_chan(rtwdev, op_chan, false); 5008 4966 ieee80211_stop_queues(rtwdev->hw); 5009 4967 } 5010 4968 return; ··· 5026 4982 break; 5027 4983 case RTW89_SCAN_ENTER_OP_NOTIFY: 5028 4984 case RTW89_SCAN_ENTER_CH_NOTIFY: 5029 - if (rtw89_is_op_chan(rtwdev, band, chan)) { 5030 - rtw89_assign_entity_chan(rtwdev, rtwvif_link->chanctx_idx, 5031 - &rtwdev->scan_info.op_chan); 5032 - rtw89_mac_enable_beacon_for_ap_vifs(rtwdev, true); 4985 + op_chan = rtw89_hw_scan_search_op_chan(rtwdev, band, chan); 4986 + if (op_chan) { 4987 + rtw89_assign_entity_chan(rtwdev, rtwvif_link->chanctx_idx, op_chan); 4988 + rtw89_mac_enable_aps_bcn_by_chan(rtwdev, op_chan, true); 5033 4989 ieee80211_wake_queues(rtwdev->hw); 5034 4990 } else { 5035 4991 rtw89_chan_create(&new, chan, chan, band, ··· 5761 5717 handler = rtw89_mac_c2h_ap_handler[func]; 5762 5718 break; 5763 5719 case RTW89_MAC_C2H_CLASS_FWDBG: 5720 + case RTW89_MAC_C2H_CLASS_ROLE: 5764 5721 return; 5765 5722 default: 5766 5723 rtw89_info(rtwdev, "MAC c2h class %d not support\n", class); ··· 6914 6869 .filter_model_addr = R_AX_FILTER_MODEL_ADDR, 6915 6870 .indir_access_addr = R_AX_INDIR_ACCESS_ENTRY, 6916 6871 .mem_base_addrs = rtw89_mac_mem_base_addrs_ax, 6872 + .mem_page_size = MAC_MEM_DUMP_PAGE_SIZE_AX, 6917 6873 .rx_fltr = R_AX_RX_FLTR_OPT, 6918 6874 .port_base = &rtw89_port_base_ax, 6919 6875 .agg_len_ht = R_AX_AGG_LEN_HT_0,
+5 -1
drivers/net/wireless/realtek/rtw89/mac.h
··· 8 8 #include "core.h" 9 9 #include "reg.h" 10 10 11 - #define MAC_MEM_DUMP_PAGE_SIZE 0x40000 11 + #define MAC_MEM_DUMP_PAGE_SIZE_AX 0x40000 12 + #define MAC_MEM_DUMP_PAGE_SIZE_BE 0x80000 13 + 12 14 #define ADDR_CAM_ENT_SIZE 0x40 13 15 #define ADDR_CAM_ENT_SHORT_SIZE 0x20 14 16 #define BSSID_CAM_ENT_SIZE 0x08 ··· 471 469 RTW89_MAC_C2H_CLASS_MLO = 0xc, 472 470 RTW89_MAC_C2H_CLASS_MRC = 0xe, 473 471 RTW89_MAC_C2H_CLASS_AP = 0x18, 472 + RTW89_MAC_C2H_CLASS_ROLE = 0x1b, 474 473 RTW89_MAC_C2H_CLASS_MAX, 475 474 }; 476 475 ··· 972 969 u32 filter_model_addr; 973 970 u32 indir_access_addr; 974 971 const u32 *mem_base_addrs; 972 + u32 mem_page_size; 975 973 u32 rx_fltr; 976 974 const struct rtw89_port_reg *port_base; 977 975 u32 agg_len_ht;
+81 -7
drivers/net/wireless/realtek/rtw89/mac80211.c
··· 72 72 rtw89_core_stop(rtwdev); 73 73 } 74 74 75 - static int rtw89_ops_config(struct ieee80211_hw *hw, u32 changed) 75 + static int rtw89_ops_config(struct ieee80211_hw *hw, int radio_idx, u32 changed) 76 76 { 77 77 struct rtw89_dev *rtwdev = hw->priv; 78 78 ··· 112 112 rtw89_vif_type_mapping(rtwvif_link, false); 113 113 114 114 wiphy_work_init(&rtwvif_link->update_beacon_work, rtw89_core_update_beacon_work); 115 + wiphy_delayed_work_init(&rtwvif_link->csa_beacon_work, rtw89_core_csa_beacon_work); 116 + 115 117 INIT_LIST_HEAD(&rtwvif_link->general_pkt_list); 116 118 117 119 rtw89_p2p_noa_once_init(rtwvif_link); ··· 146 144 lockdep_assert_wiphy(rtwdev->hw->wiphy); 147 145 148 146 wiphy_work_cancel(rtwdev->hw->wiphy, &rtwvif_link->update_beacon_work); 147 + wiphy_delayed_work_cancel(rtwdev->hw->wiphy, &rtwvif_link->csa_beacon_work); 149 148 150 149 rtw89_p2p_noa_once_deinit(rtwvif_link); 151 150 ··· 1010 1007 return 0; 1011 1008 } 1012 1009 1013 - static int rtw89_ops_set_rts_threshold(struct ieee80211_hw *hw, u32 value) 1010 + static int rtw89_ops_set_rts_threshold(struct ieee80211_hw *hw, int radio_idx, 1011 + u32 value) 1014 1012 { 1015 1013 struct rtw89_dev *rtwdev = hw->priv; 1016 1014 ··· 1123 1119 } 1124 1120 1125 1121 static 1126 - int rtw89_ops_set_antenna(struct ieee80211_hw *hw, u32 tx_ant, u32 rx_ant) 1122 + int rtw89_ops_set_antenna(struct ieee80211_hw *hw, int radio_idx, u32 tx_ant, u32 rx_ant) 1127 1123 { 1128 1124 struct rtw89_dev *rtwdev = hw->priv; 1129 1125 struct rtw89_hal *hal = &rtwdev->hal; ··· 1146 1142 } 1147 1143 1148 1144 static 1149 - int rtw89_ops_get_antenna(struct ieee80211_hw *hw, u32 *tx_ant, u32 *rx_ant) 1145 + int rtw89_ops_get_antenna(struct ieee80211_hw *hw, int radio_idx, u32 *tx_ant, 1146 + u32 *rx_ant) 1150 1147 { 1151 1148 struct rtw89_dev *rtwdev = hw->priv; 1152 1149 struct rtw89_hal *hal = &rtwdev->hal; ··· 1357 1352 } 1358 1353 1359 1354 rtw89_chanctx_ops_unassign_vif(rtwdev, rtwvif_link, ctx); 1355 + } 1356 + 1357 + static 1358 + int rtw89_ops_switch_vif_chanctx(struct ieee80211_hw *hw, 1359 + struct ieee80211_vif_chanctx_switch *vifs, 1360 + int n_vifs, 1361 + enum ieee80211_chanctx_switch_mode mode) 1362 + { 1363 + struct rtw89_dev *rtwdev = hw->priv; 1364 + bool replace; 1365 + int ret; 1366 + int i; 1367 + 1368 + lockdep_assert_wiphy(hw->wiphy); 1369 + 1370 + switch (mode) { 1371 + case CHANCTX_SWMODE_REASSIGN_VIF: 1372 + replace = false; 1373 + break; 1374 + case CHANCTX_SWMODE_SWAP_CONTEXTS: 1375 + replace = true; 1376 + break; 1377 + default: 1378 + return -EOPNOTSUPP; 1379 + } 1380 + 1381 + for (i = 0; i < n_vifs; i++) { 1382 + struct ieee80211_vif_chanctx_switch *p = &vifs[i]; 1383 + struct ieee80211_bss_conf *link_conf = p->link_conf; 1384 + struct rtw89_vif *rtwvif = vif_to_rtwvif(p->vif); 1385 + struct rtw89_vif_link *rtwvif_link; 1386 + 1387 + rtwvif_link = rtwvif->links[link_conf->link_id]; 1388 + if (unlikely(!rtwvif_link)) { 1389 + rtw89_err(rtwdev, 1390 + "%s: rtwvif link (link_id %u) is not active\n", 1391 + __func__, link_conf->link_id); 1392 + return -ENOLINK; 1393 + } 1394 + 1395 + ret = rtw89_chanctx_ops_reassign_vif(rtwdev, rtwvif_link, 1396 + p->old_ctx, p->new_ctx, 1397 + replace); 1398 + if (ret) 1399 + return ret; 1400 + } 1401 + 1402 + return 0; 1403 + } 1404 + 1405 + static void rtw89_ops_channel_switch_beacon(struct ieee80211_hw *hw, 1406 + struct ieee80211_vif *vif, 1407 + struct cfg80211_chan_def *chandef) 1408 + { 1409 + struct rtw89_vif *rtwvif = vif_to_rtwvif(vif); 1410 + struct rtw89_dev *rtwdev = hw->priv; 1411 + struct rtw89_vif_link *rtwvif_link; 1412 + 1413 + BUILD_BUG_ON(RTW89_MLD_NON_STA_LINK_NUM != 1); 1414 + 1415 + rtwvif_link = rtw89_vif_get_link_inst(rtwvif, 0); 1416 + if (unlikely(!rtwvif_link)) { 1417 + rtw89_err(rtwdev, "chsw bcn: find no link on HW-0\n"); 1418 + return; 1419 + } 1420 + 1421 + wiphy_delayed_work_queue(hw->wiphy, &rtwvif_link->csa_beacon_work, 0); 1360 1422 } 1361 1423 1362 1424 static int rtw89_ops_remain_on_channel(struct ieee80211_hw *hw, ··· 1770 1698 1771 1699 lockdep_assert_wiphy(hw->wiphy); 1772 1700 1773 - set_bit(RTW89_FLAG_FORBIDDEN_TRACK_WROK, rtwdev->flags); 1701 + set_bit(RTW89_FLAG_FORBIDDEN_TRACK_WORK, rtwdev->flags); 1774 1702 wiphy_delayed_work_cancel(hw->wiphy, &rtwdev->track_work); 1775 1703 1776 1704 ret = rtw89_wow_suspend(rtwdev, wowlan); 1777 1705 if (ret) { 1778 1706 rtw89_warn(rtwdev, "failed to suspend for wow %d\n", ret); 1779 - clear_bit(RTW89_FLAG_FORBIDDEN_TRACK_WROK, rtwdev->flags); 1707 + clear_bit(RTW89_FLAG_FORBIDDEN_TRACK_WORK, rtwdev->flags); 1780 1708 return 1; 1781 1709 } 1782 1710 ··· 1794 1722 if (ret) 1795 1723 rtw89_warn(rtwdev, "failed to resume for wow %d\n", ret); 1796 1724 1797 - clear_bit(RTW89_FLAG_FORBIDDEN_TRACK_WROK, rtwdev->flags); 1725 + clear_bit(RTW89_FLAG_FORBIDDEN_TRACK_WORK, rtwdev->flags); 1798 1726 wiphy_delayed_work_queue(hw->wiphy, &rtwdev->track_work, 1799 1727 RTW89_TRACK_WORK_PERIOD); 1800 1728 ··· 1877 1805 .change_chanctx = rtw89_ops_change_chanctx, 1878 1806 .assign_vif_chanctx = rtw89_ops_assign_vif_chanctx, 1879 1807 .unassign_vif_chanctx = rtw89_ops_unassign_vif_chanctx, 1808 + .switch_vif_chanctx = rtw89_ops_switch_vif_chanctx, 1809 + .channel_switch_beacon = rtw89_ops_channel_switch_beacon, 1880 1810 .remain_on_channel = rtw89_ops_remain_on_channel, 1881 1811 .cancel_remain_on_channel = rtw89_ops_cancel_remain_on_channel, 1882 1812 .set_sar_specs = rtw89_ops_set_sar_specs,
+1
drivers/net/wireless/realtek/rtw89/mac_be.c
··· 2567 2567 .filter_model_addr = R_BE_FILTER_MODEL_ADDR, 2568 2568 .indir_access_addr = R_BE_INDIR_ACCESS_ENTRY, 2569 2569 .mem_base_addrs = rtw89_mac_mem_base_addrs_be, 2570 + .mem_page_size = MAC_MEM_DUMP_PAGE_SIZE_BE, 2570 2571 .rx_fltr = R_BE_RX_FLTR_OPT, 2571 2572 .port_base = &rtw89_port_base_be, 2572 2573 .agg_len_ht = R_BE_AGG_LEN_HT_0,
+37
drivers/net/wireless/realtek/rtw89/pci.c
··· 4353 4353 SIMPLE_DEV_PM_OPS(rtw89_pm_ops, rtw89_pci_suspend, rtw89_pci_resume); 4354 4354 EXPORT_SYMBOL(rtw89_pm_ops); 4355 4355 4356 + static pci_ers_result_t rtw89_pci_io_error_detected(struct pci_dev *pdev, 4357 + pci_channel_state_t state) 4358 + { 4359 + struct net_device *netdev = pci_get_drvdata(pdev); 4360 + 4361 + netif_device_detach(netdev); 4362 + 4363 + return PCI_ERS_RESULT_NEED_RESET; 4364 + } 4365 + 4366 + static pci_ers_result_t rtw89_pci_io_slot_reset(struct pci_dev *pdev) 4367 + { 4368 + struct ieee80211_hw *hw = pci_get_drvdata(pdev); 4369 + struct rtw89_dev *rtwdev = hw->priv; 4370 + 4371 + rtw89_ser_notify(rtwdev, MAC_AX_ERR_ASSERTION); 4372 + 4373 + return PCI_ERS_RESULT_RECOVERED; 4374 + } 4375 + 4376 + static void rtw89_pci_io_resume(struct pci_dev *pdev) 4377 + { 4378 + struct net_device *netdev = pci_get_drvdata(pdev); 4379 + 4380 + /* ack any pending wake events, disable PME */ 4381 + pci_enable_wake(pdev, PCI_D0, 0); 4382 + 4383 + netif_device_attach(netdev); 4384 + } 4385 + 4386 + const struct pci_error_handlers rtw89_pci_err_handler = { 4387 + .error_detected = rtw89_pci_io_error_detected, 4388 + .slot_reset = rtw89_pci_io_slot_reset, 4389 + .resume = rtw89_pci_io_resume, 4390 + }; 4391 + EXPORT_SYMBOL(rtw89_pci_err_handler); 4392 + 4356 4393 const struct rtw89_pci_gen_def rtw89_pci_gen_ax = { 4357 4394 .isr_rdu = B_AX_RDU_INT, 4358 4395 .isr_halt_c2h = B_AX_HALT_C2H_INT_EN,
+1
drivers/net/wireless/realtek/rtw89/pci.h
··· 1622 1622 1623 1623 extern const struct dev_pm_ops rtw89_pm_ops; 1624 1624 extern const struct dev_pm_ops rtw89_pm_ops_be; 1625 + extern const struct pci_error_handlers rtw89_pci_err_handler; 1625 1626 extern const struct rtw89_pci_ch_dma_addr_set rtw89_pci_ch_dma_addr_set; 1626 1627 extern const struct rtw89_pci_ch_dma_addr_set rtw89_pci_ch_dma_addr_set_v1; 1627 1628 extern const struct rtw89_pci_ch_dma_addr_set rtw89_pci_ch_dma_addr_set_be;
+49 -47
drivers/net/wireless/realtek/rtw89/phy.c
··· 119 119 return mask; 120 120 } 121 121 122 - static u64 get_eht_ra_mask(struct ieee80211_link_sta *link_sta) 122 + static u64 get_eht_ra_mask(struct rtw89_vif_link *rtwvif_link, 123 + struct ieee80211_link_sta *link_sta) 123 124 { 124 - struct ieee80211_sta_eht_cap *eht_cap = &link_sta->eht_cap; 125 + struct ieee80211_vif *vif = rtwvif_link_to_vif(rtwvif_link); 125 126 struct ieee80211_eht_mcs_nss_supp_20mhz_only *mcs_nss_20mhz; 127 + struct ieee80211_sta_eht_cap *eht_cap = &link_sta->eht_cap; 126 128 struct ieee80211_eht_mcs_nss_supp_bw *mcs_nss; 127 129 u8 *he_phy_cap = link_sta->he_cap.he_cap_elem.phy_cap_info; 128 130 ··· 138 136 /* MCS 9, 11, 13 */ 139 137 return get_eht_mcs_ra_mask(mcs_nss->rx_tx_max_nss, 9, 3); 140 138 case IEEE80211_STA_RX_BW_20: 141 - if (!(he_phy_cap[0] & 142 - IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_MASK_ALL)) { 139 + if (vif->type == NL80211_IFTYPE_AP && 140 + !(he_phy_cap[0] & IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_MASK_ALL)) { 143 141 mcs_nss_20mhz = &eht_cap->eht_mcs_nss_supp.only_20mhz; 144 142 /* MCS 7, 9, 11, 13 */ 145 143 return get_eht_mcs_ra_mask(mcs_nss_20mhz->rx_tx_max_nss, 7, 4); ··· 334 332 /* Set the ra mask from sta's capability */ 335 333 if (link_sta->eht_cap.has_eht) { 336 334 mode |= RTW89_RA_MODE_EHT; 337 - ra_mask |= get_eht_ra_mask(link_sta); 335 + ra_mask |= get_eht_ra_mask(rtwvif_link, link_sta); 338 336 339 337 if (rtwdev->hal.no_mcs_12_13) 340 338 high_rate_masks = rtw89_ra_mask_eht_mcs0_11; ··· 5830 5828 __rtw89_phy_env_monitor_track(rtwdev, bb); 5831 5829 } 5832 5830 5833 - static bool rtw89_physts_ie_page_valid(enum rtw89_phy_status_bitmap *ie_page) 5831 + static bool rtw89_physts_ie_page_valid(struct rtw89_dev *rtwdev, 5832 + enum rtw89_phy_status_bitmap *ie_page) 5834 5833 { 5834 + const struct rtw89_chip_info *chip = rtwdev->chip; 5835 + 5835 5836 if (*ie_page >= RTW89_PHYSTS_BITMAP_NUM || 5836 5837 *ie_page == RTW89_RSVD_9) 5837 5838 return false; 5838 - else if (*ie_page > RTW89_RSVD_9) 5839 + else if (*ie_page > RTW89_RSVD_9 && *ie_page < RTW89_EHT_PKT) 5839 5840 *ie_page -= 1; 5841 + 5842 + if (*ie_page == RTW89_EHT_PKT && chip->chip_gen == RTW89_CHIP_AX) 5843 + return false; 5840 5844 5841 5845 return true; 5842 5846 } ··· 5850 5842 static u32 rtw89_phy_get_ie_bitmap_addr(enum rtw89_phy_status_bitmap ie_page) 5851 5843 { 5852 5844 static const u8 ie_page_shift = 2; 5845 + 5846 + if (ie_page == RTW89_EHT_PKT) 5847 + return R_PHY_STS_BITMAP_EHT; 5853 5848 5854 5849 return R_PHY_STS_BITMAP_ADDR_START + (ie_page << ie_page_shift); 5855 5850 } ··· 5863 5852 { 5864 5853 u32 addr; 5865 5854 5866 - if (!rtw89_physts_ie_page_valid(&ie_page)) 5855 + if (!rtw89_physts_ie_page_valid(rtwdev, &ie_page)) 5867 5856 return 0; 5868 5857 5869 5858 addr = rtw89_phy_get_ie_bitmap_addr(ie_page); ··· 5878 5867 const struct rtw89_chip_info *chip = rtwdev->chip; 5879 5868 u32 addr; 5880 5869 5881 - if (!rtw89_physts_ie_page_valid(&ie_page)) 5870 + if (!rtw89_physts_ie_page_valid(rtwdev, &ie_page)) 5882 5871 return; 5883 5872 5884 5873 if (chip->chip_id == RTL8852A) ··· 5886 5875 5887 5876 addr = rtw89_phy_get_ie_bitmap_addr(ie_page); 5888 5877 rtw89_phy_write32_idx(rtwdev, addr, MASKDWORD, val, phy_idx); 5889 - } 5890 - 5891 - static void rtw89_physts_enable_ie_bitmap(struct rtw89_dev *rtwdev, 5892 - enum rtw89_phy_status_bitmap bitmap, 5893 - enum rtw89_phy_status_ie_type ie, 5894 - bool enable, enum rtw89_phy_idx phy_idx) 5895 - { 5896 - u32 val = rtw89_physts_get_ie_bitmap(rtwdev, bitmap, phy_idx); 5897 - 5898 - if (enable) 5899 - val |= BIT(ie); 5900 - else 5901 - val &= ~BIT(ie); 5902 - 5903 - rtw89_physts_set_ie_bitmap(rtwdev, bitmap, val, phy_idx); 5904 5878 } 5905 5879 5906 5880 static void rtw89_physts_enable_fail_report(struct rtw89_dev *rtwdev, ··· 5911 5915 static void __rtw89_physts_parsing_init(struct rtw89_dev *rtwdev, 5912 5916 enum rtw89_phy_idx phy_idx) 5913 5917 { 5918 + const struct rtw89_chip_info *chip = rtwdev->chip; 5919 + u32 val; 5914 5920 u8 i; 5915 5921 5916 5922 rtw89_physts_enable_fail_report(rtwdev, false, phy_idx); 5917 5923 5918 5924 for (i = 0; i < RTW89_PHYSTS_BITMAP_NUM; i++) { 5919 - if (i >= RTW89_CCK_PKT) 5920 - rtw89_physts_enable_ie_bitmap(rtwdev, i, 5921 - RTW89_PHYSTS_IE09_FTR_0, 5922 - true, phy_idx); 5923 - if ((i >= RTW89_CCK_BRK && i <= RTW89_VHT_MU) || 5924 - (i >= RTW89_RSVD_9 && i <= RTW89_CCK_PKT)) 5925 + if (i == RTW89_RSVD_9 || 5926 + (i == RTW89_EHT_PKT && chip->chip_gen == RTW89_CHIP_AX)) 5925 5927 continue; 5926 - rtw89_physts_enable_ie_bitmap(rtwdev, i, 5927 - RTW89_PHYSTS_IE24_OFDM_TD_PATH_A, 5928 - true, phy_idx); 5929 - } 5930 - rtw89_physts_enable_ie_bitmap(rtwdev, RTW89_VHT_PKT, 5931 - RTW89_PHYSTS_IE13_DL_MU_DEF, true, phy_idx); 5932 - rtw89_physts_enable_ie_bitmap(rtwdev, RTW89_HE_PKT, 5933 - RTW89_PHYSTS_IE13_DL_MU_DEF, true, phy_idx); 5934 5928 5935 - /* force IE01 for channel index, only channel field is valid */ 5936 - rtw89_physts_enable_ie_bitmap(rtwdev, RTW89_CCK_PKT, 5937 - RTW89_PHYSTS_IE01_CMN_OFDM, true, phy_idx); 5929 + val = rtw89_physts_get_ie_bitmap(rtwdev, i, phy_idx); 5930 + if (i == RTW89_HE_MU || i == RTW89_VHT_MU) { 5931 + val |= BIT(RTW89_PHYSTS_IE13_DL_MU_DEF); 5932 + } else if (i == RTW89_TRIG_BASE_PPDU) { 5933 + val |= BIT(RTW89_PHYSTS_IE13_DL_MU_DEF) | 5934 + BIT(RTW89_PHYSTS_IE01_CMN_OFDM); 5935 + } else if (i >= RTW89_CCK_PKT) { 5936 + val |= BIT(RTW89_PHYSTS_IE09_FTR_0); 5937 + 5938 + val &= ~(GENMASK(RTW89_PHYSTS_IE07_CMN_EXT_PATH_D, 5939 + RTW89_PHYSTS_IE04_CMN_EXT_PATH_A)); 5940 + 5941 + if (i == RTW89_CCK_PKT) 5942 + val |= BIT(RTW89_PHYSTS_IE01_CMN_OFDM); 5943 + else if (i >= RTW89_HT_PKT) 5944 + val |= BIT(RTW89_PHYSTS_IE20_DBG_OFDM_FD_USER_SEG_0); 5945 + } 5946 + 5947 + rtw89_physts_set_ie_bitmap(rtwdev, i, val, phy_idx); 5948 + } 5938 5949 } 5939 5950 5940 5951 static void rtw89_physts_parsing_init(struct rtw89_dev *rtwdev) ··· 7128 7125 const struct rtw89_edcca_p_regs *edcca_p_regs; 7129 7126 bool flag_fb, flag_p20, flag_s20, flag_s40, flag_s80; 7130 7127 s8 pwdb_fb, pwdb_p20, pwdb_s20, pwdb_s40, pwdb_s80; 7131 - u8 path, per20_bitmap; 7128 + u8 path, per20_bitmap = 0; 7132 7129 u8 pwdb[8]; 7133 7130 u32 tmp; 7134 7131 ··· 7158 7155 pwdb_fb = u32_get_bits(tmp, MASKBYTE3); 7159 7156 7160 7157 rtw89_phy_write32_mask(rtwdev, edcca_p_regs->rpt_sel, 7161 - edcca_p_regs->rpt_sel_mask, 4); 7158 + edcca_p_regs->rpt_sel_mask, 5); 7162 7159 tmp = rtw89_phy_read32(rtwdev, edcca_p_regs->rpt_b); 7163 7160 pwdb_s80 = u32_get_bits(tmp, MASKBYTE1); 7164 7161 pwdb_s40 = u32_get_bits(tmp, MASKBYTE2); 7165 - 7166 - per20_bitmap = rtw89_phy_read32_mask(rtwdev, edcca_p_regs->rpt_a, 7167 - MASKBYTE0); 7168 7162 7169 7163 if (rtwdev->chip->chip_id == RTL8922A) { 7170 7164 rtw89_phy_write32_mask(rtwdev, edcca_regs->rpt_sel_be, ··· 7171 7171 pwdb[1] = u32_get_bits(tmp, MASKBYTE2); 7172 7172 pwdb[2] = u32_get_bits(tmp, MASKBYTE1); 7173 7173 pwdb[3] = u32_get_bits(tmp, MASKBYTE0); 7174 + per20_bitmap = rtw89_phy_read32_mask(rtwdev, edcca_p_regs->rpt_a, 7175 + MASKBYTE0); 7174 7176 7175 7177 rtw89_phy_write32_mask(rtwdev, edcca_regs->rpt_sel_be, 7176 7178 edcca_regs->rpt_sel_be_mask, 5); ··· 7189 7187 pwdb[1] = u32_get_bits(tmp, MASKBYTE2); 7190 7188 7191 7189 rtw89_phy_write32_mask(rtwdev, edcca_p_regs->rpt_sel, 7192 - edcca_p_regs->rpt_sel_mask, 1); 7190 + edcca_p_regs->rpt_sel_mask, 5); 7193 7191 tmp = rtw89_phy_read32(rtwdev, edcca_p_regs->rpt_a); 7194 7192 pwdb[2] = u32_get_bits(tmp, MASKBYTE3); 7195 7193 pwdb[3] = u32_get_bits(tmp, MASKBYTE2);
+1
drivers/net/wireless/realtek/rtw89/phy.h
··· 252 252 RTW89_HT_PKT = 13, 253 253 RTW89_VHT_PKT = 14, 254 254 RTW89_HE_PKT = 15, 255 + RTW89_EHT_PKT = 16, 255 256 256 257 RTW89_PHYSTS_BITMAP_NUM 257 258 };
+19 -7
drivers/net/wireless/realtek/rtw89/ps.c
··· 137 137 can_ps_mode = false; 138 138 } 139 139 140 + rtw89_fw_h2c_rf_ps_info(rtwdev, rtwvif); 141 + 140 142 if (RTW89_CHK_FW_FEATURE(LPS_CH_INFO, &rtwdev->fw)) 141 143 rtw89_fw_h2c_lps_ch_info(rtwdev, rtwvif); 142 144 else ··· 238 236 rtw89_fw_h2c_tsf32_toggle(rtwdev, rtwvif_link, false); 239 237 } 240 238 241 - static void rtw89_p2p_disable_all_noa(struct rtw89_dev *rtwdev, 242 - struct rtw89_vif_link *rtwvif_link, 243 - struct ieee80211_bss_conf *bss_conf) 239 + void rtw89_p2p_disable_all_noa(struct rtw89_dev *rtwdev, 240 + struct rtw89_vif_link *rtwvif_link, 241 + struct ieee80211_bss_conf *bss_conf) 244 242 { 245 243 enum rtw89_p2pps_action act; 244 + u8 oppps_ctwindow; 246 245 u8 noa_id; 246 + 247 + rcu_read_lock(); 248 + 249 + if (!bss_conf) 250 + bss_conf = rtw89_vif_rcu_dereference_link(rtwvif_link, true); 251 + 252 + oppps_ctwindow = bss_conf->p2p_noa_attr.oppps_ctwindow; 253 + 254 + rcu_read_unlock(); 247 255 248 256 if (rtwvif_link->last_noa_nr == 0) 249 257 return; ··· 264 252 else 265 253 act = RTW89_P2P_ACT_REMOVE; 266 254 rtw89_tsf32_toggle(rtwdev, rtwvif_link, act); 267 - rtw89_fw_h2c_p2p_act(rtwdev, rtwvif_link, bss_conf, 268 - NULL, act, noa_id); 255 + rtw89_fw_h2c_p2p_act(rtwdev, rtwvif_link, NULL, 256 + act, noa_id, oppps_ctwindow); 269 257 } 270 258 } 271 259 ··· 287 275 else 288 276 act = RTW89_P2P_ACT_UPDATE; 289 277 rtw89_tsf32_toggle(rtwdev, rtwvif_link, act); 290 - rtw89_fw_h2c_p2p_act(rtwdev, rtwvif_link, bss_conf, 291 - desc, act, noa_id); 278 + rtw89_fw_h2c_p2p_act(rtwdev, rtwvif_link, desc, act, noa_id, 279 + bss_conf->p2p_noa_attr.oppps_ctwindow); 292 280 } 293 281 rtwvif_link->last_noa_nr = noa_id; 294 282 }
+3
drivers/net/wireless/realtek/rtw89/ps.h
··· 25 25 void rtw89_p2p_noa_once_init(struct rtw89_vif_link *rtwvif_link); 26 26 void rtw89_p2p_noa_once_deinit(struct rtw89_vif_link *rtwvif_link); 27 27 void rtw89_p2p_noa_once_recalc(struct rtw89_vif_link *rtwvif_link); 28 + void rtw89_p2p_disable_all_noa(struct rtw89_dev *rtwdev, 29 + struct rtw89_vif_link *rtwvif_link, 30 + struct ieee80211_bss_conf *bss_conf); 28 31 29 32 static inline void rtw89_leave_ips_by_hwflags(struct rtw89_dev *rtwdev) 30 33 {
+2
drivers/net/wireless/realtek/rtw89/reg.h
··· 6070 6070 #define B_BE_MACID_ACQ_GRP0_CLR_P BIT(2) 6071 6071 #define B_BE_R_MACID_ACQ_CHK_EN BIT(0) 6072 6072 6073 + #define R_BE_BTC_CFG 0x0E300 6073 6074 #define R_BE_BT_BREAK_TABLE 0x0E344 6074 6075 6075 6076 #define R_BE_GNT_SW_CTRL 0x0E348 ··· 8025 8024 #define R_PHY_STS_BITMAP_HT 0x076C 8026 8025 #define R_PHY_STS_BITMAP_VHT 0x0770 8027 8026 #define R_PHY_STS_BITMAP_HE 0x0774 8027 + #define R_PHY_STS_BITMAP_EHT 0x0788 8028 8028 #define R_EDCCA_RPTREG_SEL_BE 0x078C 8029 8029 #define B_EDCCA_RPTREG_SEL_BE_MSK GENMASK(22, 20) 8030 8030 #define R_PMAC_GNT 0x0980
+1 -1
drivers/net/wireless/realtek/rtw89/rtw8851b.c
··· 2402 2402 .set_txpwr_ctrl = rtw8851b_set_txpwr_ctrl, 2403 2403 .init_txpwr_unit = rtw8851b_init_txpwr_unit, 2404 2404 .get_thermal = rtw8851b_get_thermal, 2405 + .chan_to_rf18_val = NULL, 2405 2406 .ctrl_btg_bt_rx = rtw8851b_ctrl_btg_bt_rx, 2406 2407 .query_ppdu = rtw8851b_query_ppdu, 2407 2408 .convert_rpl_to_rssi = NULL, ··· 2529 2528 .phycap_size = 128, 2530 2529 .para_ver = 0, 2531 2530 .wlcx_desired = 0x06000000, 2532 - .btcx_desired = 0x7, 2533 2531 .scbd = 0x1, 2534 2532 .mailbox = 0x1, 2535 2533
+1
drivers/net/wireless/realtek/rtw89/rtw8851be.c
··· 89 89 .probe = rtw89_pci_probe, 90 90 .remove = rtw89_pci_remove, 91 91 .driver.pm = &rtw89_pm_ops, 92 + .err_handler = &rtw89_pci_err_handler, 92 93 }; 93 94 module_pci_driver(rtw89_8851be_driver); 94 95
+1 -1
drivers/net/wireless/realtek/rtw89/rtw8852a.c
··· 2128 2128 .set_txpwr_ctrl = rtw8852a_set_txpwr_ctrl, 2129 2129 .init_txpwr_unit = rtw8852a_init_txpwr_unit, 2130 2130 .get_thermal = rtw8852a_get_thermal, 2131 + .chan_to_rf18_val = NULL, 2131 2132 .ctrl_btg_bt_rx = rtw8852a_ctrl_btg_bt_rx, 2132 2133 .query_ppdu = rtw8852a_query_ppdu, 2133 2134 .convert_rpl_to_rssi = NULL, ··· 2247 2246 .phycap_size = 128, 2248 2247 .para_ver = 0x0, 2249 2248 .wlcx_desired = 0x06000000, 2250 - .btcx_desired = 0x7, 2251 2249 .scbd = 0x1, 2252 2250 .mailbox = 0x1, 2253 2251
+1
drivers/net/wireless/realtek/rtw89/rtw8852ae.c
··· 91 91 .probe = rtw89_pci_probe, 92 92 .remove = rtw89_pci_remove, 93 93 .driver.pm = &rtw89_pm_ops, 94 + .err_handler = &rtw89_pci_err_handler, 94 95 }; 95 96 module_pci_driver(rtw89_8852ae_driver); 96 97
+1 -1
drivers/net/wireless/realtek/rtw89/rtw8852b.c
··· 755 755 .set_txpwr_ctrl = rtw8852bx_set_txpwr_ctrl, 756 756 .init_txpwr_unit = rtw8852bx_init_txpwr_unit, 757 757 .get_thermal = rtw8852bx_get_thermal, 758 + .chan_to_rf18_val = NULL, 758 759 .ctrl_btg_bt_rx = rtw8852bx_ctrl_btg_bt_rx, 759 760 .query_ppdu = rtw8852bx_query_ppdu, 760 761 .convert_rpl_to_rssi = rtw8852bx_convert_rpl_to_rssi, ··· 883 882 .phycap_size = 128, 884 883 .para_ver = 0, 885 884 .wlcx_desired = 0x05050000, 886 - .btcx_desired = 0x5, 887 885 .scbd = 0x1, 888 886 .mailbox = 0x1, 889 887
+1
drivers/net/wireless/realtek/rtw89/rtw8852be.c
··· 93 93 .probe = rtw89_pci_probe, 94 94 .remove = rtw89_pci_remove, 95 95 .driver.pm = &rtw89_pm_ops, 96 + .err_handler = &rtw89_pci_err_handler, 96 97 }; 97 98 module_pci_driver(rtw89_8852be_driver); 98 99
+1 -1
drivers/net/wireless/realtek/rtw89/rtw8852bt.c
··· 689 689 .set_txpwr_ctrl = rtw8852bx_set_txpwr_ctrl, 690 690 .init_txpwr_unit = rtw8852bx_init_txpwr_unit, 691 691 .get_thermal = rtw8852bx_get_thermal, 692 + .chan_to_rf18_val = NULL, 692 693 .ctrl_btg_bt_rx = rtw8852bx_ctrl_btg_bt_rx, 693 694 .query_ppdu = rtw8852bx_query_ppdu, 694 695 .convert_rpl_to_rssi = rtw8852bx_convert_rpl_to_rssi, ··· 816 815 .phycap_size = 128, 817 816 .para_ver = 0, 818 817 .wlcx_desired = 0x070e0000, 819 - .btcx_desired = 0x7, 820 818 .scbd = 0x1, 821 819 .mailbox = 0x1, 822 820
+1
drivers/net/wireless/realtek/rtw89/rtw8852bte.c
··· 95 95 .probe = rtw89_pci_probe, 96 96 .remove = rtw89_pci_remove, 97 97 .driver.pm = &rtw89_pm_ops, 98 + .err_handler = &rtw89_pci_err_handler, 98 99 }; 99 100 module_pci_driver(rtw89_8852bte_driver); 100 101
+1 -1
drivers/net/wireless/realtek/rtw89/rtw8852c.c
··· 2948 2948 .set_txpwr_ctrl = rtw8852c_set_txpwr_ctrl, 2949 2949 .init_txpwr_unit = rtw8852c_init_txpwr_unit, 2950 2950 .get_thermal = rtw8852c_get_thermal, 2951 + .chan_to_rf18_val = NULL, 2951 2952 .ctrl_btg_bt_rx = rtw8852c_ctrl_btg_bt_rx, 2952 2953 .query_ppdu = rtw8852c_query_ppdu, 2953 2954 .convert_rpl_to_rssi = NULL, ··· 3070 3069 .phycap_size = 0x60, 3071 3070 .para_ver = 0x1, 3072 3071 .wlcx_desired = 0x06000000, 3073 - .btcx_desired = 0x7, 3074 3072 .scbd = 0x1, 3075 3073 .mailbox = 0x1, 3076 3074
+1
drivers/net/wireless/realtek/rtw89/rtw8852ce.c
··· 118 118 .probe = rtw89_pci_probe, 119 119 .remove = rtw89_pci_remove, 120 120 .driver.pm = &rtw89_pm_ops, 121 + .err_handler = &rtw89_pci_err_handler, 121 122 }; 122 123 module_pci_driver(rtw89_8852ce_driver); 123 124
+44 -2
drivers/net/wireless/realtek/rtw89/rtw8922a.c
··· 15 15 #include "sar.h" 16 16 #include "util.h" 17 17 18 - #define RTW8922A_FW_FORMAT_MAX 3 18 + #define RTW8922A_FW_FORMAT_MAX 4 19 19 #define RTW8922A_FW_BASENAME "rtw89/rtw8922a_fw" 20 20 #define RTW8922A_MODULE_FIRMWARE \ 21 21 RTW8922A_FW_BASENAME "-" __stringify(RTW8922A_FW_FORMAT_MAX) ".bin" ··· 2390 2390 return clamp_t(int, th, 0, U8_MAX); 2391 2391 } 2392 2392 2393 + static u32 rtw8922a_chan_to_rf18_val(struct rtw89_dev *rtwdev, 2394 + const struct rtw89_chan *chan) 2395 + { 2396 + u32 val = u32_encode_bits(chan->channel, RR_CFGCH_CH); 2397 + 2398 + switch (chan->band_type) { 2399 + case RTW89_BAND_2G: 2400 + default: 2401 + break; 2402 + case RTW89_BAND_5G: 2403 + val |= u32_encode_bits(CFGCH_BAND1_5G, RR_CFGCH_BAND1) | 2404 + u32_encode_bits(CFGCH_BAND0_5G, RR_CFGCH_BAND0); 2405 + break; 2406 + case RTW89_BAND_6G: 2407 + val |= u32_encode_bits(CFGCH_BAND1_6G, RR_CFGCH_BAND1) | 2408 + u32_encode_bits(CFGCH_BAND0_6G, RR_CFGCH_BAND0); 2409 + break; 2410 + } 2411 + 2412 + switch (chan->band_width) { 2413 + case RTW89_CHANNEL_WIDTH_5: 2414 + case RTW89_CHANNEL_WIDTH_10: 2415 + case RTW89_CHANNEL_WIDTH_20: 2416 + default: 2417 + break; 2418 + case RTW89_CHANNEL_WIDTH_40: 2419 + val |= u32_encode_bits(CFGCH_BW_V2_40M, RR_CFGCH_BW_V2); 2420 + break; 2421 + case RTW89_CHANNEL_WIDTH_80: 2422 + val |= u32_encode_bits(CFGCH_BW_V2_80M, RR_CFGCH_BW_V2); 2423 + break; 2424 + case RTW89_CHANNEL_WIDTH_160: 2425 + val |= u32_encode_bits(CFGCH_BW_V2_160M, RR_CFGCH_BW_V2); 2426 + break; 2427 + case RTW89_CHANNEL_WIDTH_320: 2428 + val |= u32_encode_bits(CFGCH_BW_V2_320M, RR_CFGCH_BW_V2); 2429 + break; 2430 + } 2431 + 2432 + return val; 2433 + } 2434 + 2393 2435 static void rtw8922a_btc_set_rfe(struct rtw89_dev *rtwdev) 2394 2436 { 2395 2437 union rtw89_btc_module_info *md = &rtwdev->btc.mdinfo; ··· 2803 2761 .set_txpwr_ctrl = rtw8922a_set_txpwr_ctrl, 2804 2762 .init_txpwr_unit = NULL, 2805 2763 .get_thermal = rtw8922a_get_thermal, 2764 + .chan_to_rf18_val = rtw8922a_chan_to_rf18_val, 2806 2765 .ctrl_btg_bt_rx = rtw8922a_ctrl_btg_bt_rx, 2807 2766 .query_ppdu = rtw8922a_query_ppdu, 2808 2767 .convert_rpl_to_rssi = rtw8922a_convert_rpl_to_rssi, ··· 2923 2880 .phycap_size = 0x38, 2924 2881 .para_ver = 0xf, 2925 2882 .wlcx_desired = 0x07110000, 2926 - .btcx_desired = 0x7, 2927 2883 .scbd = 0x1, 2928 2884 .mailbox = 0x1, 2929 2885
+5 -47
drivers/net/wireless/realtek/rtw89/rtw8922a_rfk.c
··· 36 36 37 37 static 38 38 void rtw8922a_ctl_band_ch_bw(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, 39 - u8 central_ch, enum rtw89_band band, 40 - enum rtw89_bandwidth bw) 39 + const struct rtw89_chan *chan) 41 40 { 42 41 const u32 rf_addr[2] = {RR_CFGCH, RR_CFGCH_V1}; 43 42 struct rtw89_hal *hal = &rtwdev->hal; ··· 72 73 return; 73 74 } 74 75 75 - rf_reg[path][i] &= ~(RR_CFGCH_BAND1 | RR_CFGCH_BW | 76 + rf_reg[path][i] &= ~(RR_CFGCH_BAND1 | RR_CFGCH_BW_V2 | 76 77 RR_CFGCH_BAND0 | RR_CFGCH_CH); 77 - rf_reg[path][i] |= u32_encode_bits(central_ch, RR_CFGCH_CH); 78 - 79 - switch (band) { 80 - case RTW89_BAND_2G: 81 - default: 82 - break; 83 - case RTW89_BAND_5G: 84 - rf_reg[path][i] |= 85 - u32_encode_bits(CFGCH_BAND1_5G, RR_CFGCH_BAND1) | 86 - u32_encode_bits(CFGCH_BAND0_5G, RR_CFGCH_BAND0); 87 - break; 88 - case RTW89_BAND_6G: 89 - rf_reg[path][i] |= 90 - u32_encode_bits(CFGCH_BAND1_6G, RR_CFGCH_BAND1) | 91 - u32_encode_bits(CFGCH_BAND0_6G, RR_CFGCH_BAND0); 92 - break; 93 - } 94 - 95 - switch (bw) { 96 - case RTW89_CHANNEL_WIDTH_5: 97 - case RTW89_CHANNEL_WIDTH_10: 98 - case RTW89_CHANNEL_WIDTH_20: 99 - default: 100 - break; 101 - case RTW89_CHANNEL_WIDTH_40: 102 - rf_reg[path][i] |= 103 - u32_encode_bits(CFGCH_BW_V2_40M, RR_CFGCH_BW_V2); 104 - break; 105 - case RTW89_CHANNEL_WIDTH_80: 106 - rf_reg[path][i] |= 107 - u32_encode_bits(CFGCH_BW_V2_80M, RR_CFGCH_BW_V2); 108 - break; 109 - case RTW89_CHANNEL_WIDTH_160: 110 - rf_reg[path][i] |= 111 - u32_encode_bits(CFGCH_BW_V2_160M, RR_CFGCH_BW_V2); 112 - break; 113 - case RTW89_CHANNEL_WIDTH_320: 114 - rf_reg[path][i] |= 115 - u32_encode_bits(CFGCH_BW_V2_320M, RR_CFGCH_BW_V2); 116 - break; 117 - } 78 + rf_reg[path][i] |= rtw89_chip_chan_to_rf18_val(rtwdev, chan); 118 79 119 80 rtw89_write_rf(rtwdev, path, rf_addr[i], 120 81 RFREG_MASK, rf_reg[path][i]); ··· 85 126 if (hal->cv != CHIP_CAV) 86 127 return; 87 128 88 - if (band == RTW89_BAND_2G) { 129 + if (chan->band_type == RTW89_BAND_2G) { 89 130 rtw89_write_rf(rtwdev, RF_PATH_A, RR_LUTWE, RFREG_MASK, 0x80000); 90 131 rtw89_write_rf(rtwdev, RF_PATH_A, RR_LUTWA, RFREG_MASK, 0x00003); 91 132 rtw89_write_rf(rtwdev, RF_PATH_A, RR_LUTWD1, RFREG_MASK, 0x0c990); ··· 104 145 const struct rtw89_chan *chan, 105 146 enum rtw89_phy_idx phy_idx) 106 147 { 107 - rtw8922a_ctl_band_ch_bw(rtwdev, phy_idx, chan->channel, chan->band_type, 108 - chan->band_width); 148 + rtw8922a_ctl_band_ch_bw(rtwdev, phy_idx, chan); 109 149 } 110 150 111 151 enum _rf_syn_pow {
+1
drivers/net/wireless/realtek/rtw89/rtw8922ae.c
··· 106 106 .probe = rtw89_pci_probe, 107 107 .remove = rtw89_pci_remove, 108 108 .driver.pm = &rtw89_pm_ops_be, 109 + .err_handler = &rtw89_pci_err_handler, 109 110 }; 110 111 module_pci_driver(rtw89_8922ae_driver); 111 112
+2 -3
drivers/net/wireless/realtek/rtw89/sar.c
··· 199 199 typeof(_dev) _d = (_dev); \ 200 200 BUILD_BUG_ON(!rtw89_sar_handlers[_s].descr_sar_source); \ 201 201 BUILD_BUG_ON(!rtw89_sar_handlers[_s].query_sar_config); \ 202 - lockdep_assert_wiphy(_d->hw->wiphy); \ 202 + if (test_bit(RTW89_FLAG_PROBE_DONE, _d->flags)) \ 203 + lockdep_assert_wiphy(_d->hw->wiphy); \ 203 204 _d->sar._cfg_name = *(_cfg_data); \ 204 205 _d->sar.src = _s; \ 205 206 } while (0) ··· 499 498 { 500 499 struct rtw89_sar_cfg_acpi *cfg; 501 500 int ret; 502 - 503 - lockdep_assert_wiphy(rtwdev->hw->wiphy); 504 501 505 502 cfg = kzalloc(sizeof(*cfg), GFP_KERNEL); 506 503 if (!cfg)
+6 -5
drivers/net/wireless/realtek/rtw89/ser.c
··· 566 566 const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def; 567 567 u32 filter_model_addr = mac->filter_model_addr; 568 568 u32 indir_access_addr = mac->indir_access_addr; 569 + u32 mem_page_size = mac->mem_page_size; 569 570 u32 *ptr = (u32 *)buf; 570 571 u32 base_addr, start_page, residue; 571 572 u32 cnt = 0; 572 573 u32 i; 573 574 574 - start_page = start_addr / MAC_MEM_DUMP_PAGE_SIZE; 575 - residue = start_addr % MAC_MEM_DUMP_PAGE_SIZE; 575 + start_page = start_addr / mem_page_size; 576 + residue = start_addr % mem_page_size; 576 577 base_addr = mac->mem_base_addrs[sel]; 577 - base_addr += start_page * MAC_MEM_DUMP_PAGE_SIZE; 578 + base_addr += start_page * mem_page_size; 578 579 579 580 while (cnt < len) { 580 581 rtw89_write32(rtwdev, filter_model_addr, base_addr); 581 582 582 583 for (i = indir_access_addr + residue; 583 - i < indir_access_addr + MAC_MEM_DUMP_PAGE_SIZE; 584 + i < indir_access_addr + mem_page_size; 584 585 i += 4, ptr++) { 585 586 *ptr = rtw89_read32(rtwdev, i); 586 587 cnt += 4; ··· 590 589 } 591 590 592 591 residue = 0; 593 - base_addr += MAC_MEM_DUMP_PAGE_SIZE; 592 + base_addr += mem_page_size; 594 593 } 595 594 } 596 595
+8 -1
drivers/net/wireless/rsi/rsi_91x_mac80211.c
··· 656 656 * requests. The stack calls this function to 657 657 * change hardware configuration, e.g., channel. 658 658 * @hw: Pointer to the ieee80211_hw structure. 659 + * @radio_idx: Radio index. 659 660 * @changed: Changed flags set. 660 661 * 661 662 * Return: 0 on success, negative error code on failure. 662 663 */ 663 664 static int rsi_mac80211_config(struct ieee80211_hw *hw, 665 + int radio_idx, 664 666 u32 changed) 665 667 { 666 668 struct rsi_hw *adapter = hw->priv; ··· 1203 1201 /** 1204 1202 * rsi_mac80211_set_rts_threshold() - This function sets rts threshold value. 1205 1203 * @hw: Pointer to the ieee80211_hw structure. 1204 + * @radio_idx: Radio index. 1206 1205 * @value: Rts threshold value. 1207 1206 * 1208 1207 * Return: 0 on success. 1209 1208 */ 1210 1209 static int rsi_mac80211_set_rts_threshold(struct ieee80211_hw *hw, 1211 - u32 value) 1210 + int radio_idx, u32 value) 1212 1211 { 1213 1212 struct rsi_hw *adapter = hw->priv; 1214 1213 struct rsi_common *common = adapter->priv; ··· 1586 1583 * rsi_mac80211_set_antenna() - This function is used to configure 1587 1584 * tx and rx antennas. 1588 1585 * @hw: Pointer to the ieee80211_hw structure. 1586 + * @radio_idx: Radio index 1589 1587 * @tx_ant: Bitmap for tx antenna 1590 1588 * @rx_ant: Bitmap for rx antenna 1591 1589 * 1592 1590 * Return: 0 on success, Negative error code on failure. 1593 1591 */ 1594 1592 static int rsi_mac80211_set_antenna(struct ieee80211_hw *hw, 1593 + int radio_idx, 1595 1594 u32 tx_ant, u32 rx_ant) 1596 1595 { 1597 1596 struct rsi_hw *adapter = hw->priv; ··· 1639 1634 * tx and rx antennas. 1640 1635 * 1641 1636 * @hw: Pointer to the ieee80211_hw structure. 1637 + * @radio_idx: Radio index 1642 1638 * @tx_ant: Bitmap for tx antenna 1643 1639 * @rx_ant: Bitmap for rx antenna 1644 1640 * 1645 1641 * Return: 0 on success, negative error codes on failure. 1646 1642 */ 1647 1643 static int rsi_mac80211_get_antenna(struct ieee80211_hw *hw, 1644 + int radio_idx, 1648 1645 u32 *tx_ant, u32 *rx_ant) 1649 1646 { 1650 1647 struct rsi_hw *adapter = hw->priv;
+2 -2
drivers/net/wireless/silabs/wfx/sta.c
··· 220 220 return 0; 221 221 } 222 222 223 - int wfx_set_rts_threshold(struct ieee80211_hw *hw, u32 value) 223 + int wfx_set_rts_threshold(struct ieee80211_hw *hw, int radio_idx, u32 value) 224 224 { 225 225 struct wfx_dev *wdev = hw->priv; 226 226 struct wfx_vif *wvif = NULL; ··· 706 706 wvif->channel = NULL; 707 707 } 708 708 709 - int wfx_config(struct ieee80211_hw *hw, u32 changed) 709 + int wfx_config(struct ieee80211_hw *hw, int radio_idx, u32 changed) 710 710 { 711 711 return 0; 712 712 }
+2 -2
drivers/net/wireless/silabs/wfx/sta.h
··· 21 21 /* mac80211 interface */ 22 22 int wfx_start(struct ieee80211_hw *hw); 23 23 void wfx_stop(struct ieee80211_hw *hw, bool suspend); 24 - int wfx_config(struct ieee80211_hw *hw, u32 changed); 25 - int wfx_set_rts_threshold(struct ieee80211_hw *hw, u32 value); 24 + int wfx_config(struct ieee80211_hw *hw, int radio_idx, u32 changed); 25 + int wfx_set_rts_threshold(struct ieee80211_hw *hw, int radio_idx, u32 value); 26 26 void wfx_set_default_unicast_key(struct ieee80211_hw *hw, struct ieee80211_vif *vif, int idx); 27 27 void wfx_configure_filter(struct ieee80211_hw *hw, unsigned int changed_flags, 28 28 unsigned int *total_flags, u64 unused);
+3 -2
drivers/net/wireless/st/cw1200/sta.c
··· 321 321 return ret; 322 322 } 323 323 324 - int cw1200_config(struct ieee80211_hw *dev, u32 changed) 324 + int cw1200_config(struct ieee80211_hw *dev, int radio_idx, u32 changed) 325 325 { 326 326 int ret = 0; 327 327 struct cw1200_common *priv = dev->priv; ··· 857 857 wsm_unlock_tx(priv); 858 858 } 859 859 860 - int cw1200_set_rts_threshold(struct ieee80211_hw *hw, u32 value) 860 + int cw1200_set_rts_threshold(struct ieee80211_hw *hw, int radio_idx, 861 + u32 value) 861 862 { 862 863 int ret = 0; 863 864 __le32 val32;
+3 -2
drivers/net/wireless/st/cw1200/sta.h
··· 22 22 struct ieee80211_vif *vif, 23 23 enum nl80211_iftype new_type, 24 24 bool p2p); 25 - int cw1200_config(struct ieee80211_hw *dev, u32 changed); 25 + int cw1200_config(struct ieee80211_hw *dev, int radio_idx, u32 changed); 26 26 void cw1200_configure_filter(struct ieee80211_hw *dev, 27 27 unsigned int changed_flags, 28 28 unsigned int *total_flags, ··· 36 36 struct ieee80211_vif *vif, struct ieee80211_sta *sta, 37 37 struct ieee80211_key_conf *key); 38 38 39 - int cw1200_set_rts_threshold(struct ieee80211_hw *hw, u32 value); 39 + int cw1200_set_rts_threshold(struct ieee80211_hw *hw, int radio_idx, 40 + u32 value); 40 41 41 42 void cw1200_flush(struct ieee80211_hw *hw, struct ieee80211_vif *vif, 42 43 u32 queues, bool drop);
-35
drivers/net/wireless/ti/wl1251/acx.c
··· 832 832 return 0; 833 833 } 834 834 835 - int wl1251_acx_rate_policies(struct wl1251 *wl) 836 - { 837 - struct acx_rate_policy *acx; 838 - int ret = 0; 839 - 840 - wl1251_debug(DEBUG_ACX, "acx rate policies"); 841 - 842 - acx = kzalloc(sizeof(*acx), GFP_KERNEL); 843 - if (!acx) 844 - return -ENOMEM; 845 - 846 - /* configure one default (one-size-fits-all) rate class */ 847 - acx->rate_class_cnt = 2; 848 - acx->rate_class[0].enabled_rates = ACX_RATE_MASK_UNSPECIFIED; 849 - acx->rate_class[0].short_retry_limit = ACX_RATE_RETRY_LIMIT; 850 - acx->rate_class[0].long_retry_limit = ACX_RATE_RETRY_LIMIT; 851 - acx->rate_class[0].aflags = 0; 852 - 853 - /* no-retry rate class */ 854 - acx->rate_class[1].enabled_rates = ACX_RATE_MASK_UNSPECIFIED; 855 - acx->rate_class[1].short_retry_limit = 0; 856 - acx->rate_class[1].long_retry_limit = 0; 857 - acx->rate_class[1].aflags = 0; 858 - 859 - ret = wl1251_cmd_configure(wl, ACX_RATE_POLICY, acx, sizeof(*acx)); 860 - if (ret < 0) { 861 - wl1251_warning("Setting of rate policies failed: %d", ret); 862 - goto out; 863 - } 864 - 865 - out: 866 - kfree(acx); 867 - return ret; 868 - } 869 - 870 835 int wl1251_acx_mem_cfg(struct wl1251 *wl) 871 836 { 872 837 struct wl1251_acx_config_memory *mem_conf;
-1
drivers/net/wireless/ti/wl1251/acx.h
··· 1469 1469 enum acx_ctsprotect_type ctsprotect); 1470 1470 int wl1251_acx_statistics(struct wl1251 *wl, struct acx_statistics *stats); 1471 1471 int wl1251_acx_tsf_info(struct wl1251 *wl, u64 *mactime); 1472 - int wl1251_acx_rate_policies(struct wl1251 *wl); 1473 1472 int wl1251_acx_mem_cfg(struct wl1251 *wl); 1474 1473 int wl1251_acx_wr_tbtt_and_dtim(struct wl1251 *wl, u16 tbtt, u8 dtim); 1475 1474 int wl1251_acx_bet_enable(struct wl1251 *wl, enum wl1251_acx_bet_mode mode,
-79
drivers/net/wireless/ti/wl1251/cmd.c
··· 59 59 } 60 60 61 61 /** 62 - * wl1251_cmd_test - Send test command to firmware 63 - * 64 - * @wl: wl struct 65 - * @buf: buffer containing the command, with all headers, must work with dma 66 - * @buf_len: length of the buffer 67 - * @answer: is answer needed 68 - */ 69 - int wl1251_cmd_test(struct wl1251 *wl, void *buf, size_t buf_len, u8 answer) 70 - { 71 - int ret; 72 - 73 - wl1251_debug(DEBUG_CMD, "cmd test"); 74 - 75 - ret = wl1251_cmd_send(wl, CMD_TEST, buf, buf_len); 76 - 77 - if (ret < 0) { 78 - wl1251_warning("TEST command failed"); 79 - return ret; 80 - } 81 - 82 - if (answer) { 83 - struct wl1251_command *cmd_answer; 84 - 85 - /* 86 - * The test command got in, we can read the answer. 87 - * The answer would be a wl1251_command, where the 88 - * parameter array contains the actual answer. 89 - */ 90 - wl1251_mem_read(wl, wl->cmd_box_addr, buf, buf_len); 91 - 92 - cmd_answer = buf; 93 - 94 - if (cmd_answer->header.status != CMD_STATUS_SUCCESS) 95 - wl1251_error("TEST command answer error: %d", 96 - cmd_answer->header.status); 97 - } 98 - 99 - return 0; 100 - } 101 - 102 - /** 103 62 * wl1251_cmd_interrogate - Read acx from firmware 104 63 * 105 64 * @wl: wl struct ··· 295 336 296 337 out: 297 338 kfree(ps_params); 298 - return ret; 299 - } 300 - 301 - int wl1251_cmd_read_memory(struct wl1251 *wl, u32 addr, void *answer, 302 - size_t len) 303 - { 304 - struct cmd_read_write_memory *cmd; 305 - int ret = 0; 306 - 307 - wl1251_debug(DEBUG_CMD, "cmd read memory"); 308 - 309 - cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); 310 - if (!cmd) 311 - return -ENOMEM; 312 - 313 - WARN_ON(len > MAX_READ_SIZE); 314 - len = min_t(size_t, len, MAX_READ_SIZE); 315 - 316 - cmd->addr = addr; 317 - cmd->size = len; 318 - 319 - ret = wl1251_cmd_send(wl, CMD_READ_MEMORY, cmd, sizeof(*cmd)); 320 - if (ret < 0) { 321 - wl1251_error("read memory command failed: %d", ret); 322 - goto out; 323 - } 324 - 325 - /* the read command got in, we can now read the answer */ 326 - wl1251_mem_read(wl, wl->cmd_box_addr, cmd, sizeof(*cmd)); 327 - 328 - if (cmd->header.status != CMD_STATUS_SUCCESS) 329 - wl1251_error("error in read command result: %d", 330 - cmd->header.status); 331 - 332 - memcpy(answer, cmd->value, len); 333 - 334 - out: 335 - kfree(cmd); 336 339 return ret; 337 340 } 338 341
-3
drivers/net/wireless/ti/wl1251/cmd.h
··· 16 16 struct acx_header; 17 17 18 18 int wl1251_cmd_send(struct wl1251 *wl, u16 type, void *buf, size_t buf_len); 19 - int wl1251_cmd_test(struct wl1251 *wl, void *buf, size_t buf_len, u8 answer); 20 19 int wl1251_cmd_interrogate(struct wl1251 *wl, u16 id, void *buf, size_t len); 21 20 int wl1251_cmd_configure(struct wl1251 *wl, u16 id, void *buf, size_t len); 22 21 int wl1251_cmd_vbm(struct wl1251 *wl, u8 identity, ··· 25 26 int wl1251_cmd_join(struct wl1251 *wl, u8 bss_type, u8 channel, 26 27 u16 beacon_interval, u8 dtim_interval); 27 28 int wl1251_cmd_ps_mode(struct wl1251 *wl, u8 ps_mode); 28 - int wl1251_cmd_read_memory(struct wl1251 *wl, u32 addr, void *answer, 29 - size_t len); 30 29 int wl1251_cmd_template_set(struct wl1251 *wl, u16 cmd_id, 31 30 void *buf, size_t buf_len); 32 31 int wl1251_cmd_scan(struct wl1251 *wl, u8 *ssid, size_t ssid_len,
+3 -2
drivers/net/wireless/ti/wl1251/main.c
··· 589 589 return (conf->flags & IEEE80211_CONF_PS) && !wl->monitor_present; 590 590 } 591 591 592 - static int wl1251_op_config(struct ieee80211_hw *hw, u32 changed) 592 + static int wl1251_op_config(struct ieee80211_hw *hw, int radio_idx, u32 changed) 593 593 { 594 594 struct wl1251 *wl = hw->priv; 595 595 struct ieee80211_conf *conf = &hw->conf; ··· 1051 1051 return ret; 1052 1052 } 1053 1053 1054 - static int wl1251_op_set_rts_threshold(struct ieee80211_hw *hw, u32 value) 1054 + static int wl1251_op_set_rts_threshold(struct ieee80211_hw *hw, int radio_idx, 1055 + u32 value) 1055 1056 { 1056 1057 struct wl1251 *wl = hw->priv; 1057 1058 int ret;
-26
drivers/net/wireless/ti/wlcore/cmd.c
··· 1804 1804 return ret; 1805 1805 } 1806 1806 1807 - int wl12xx_cmd_start_fwlog(struct wl1271 *wl) 1808 - { 1809 - struct wl12xx_cmd_start_fwlog *cmd; 1810 - int ret = 0; 1811 - 1812 - wl1271_debug(DEBUG_CMD, "cmd start firmware logger"); 1813 - 1814 - cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); 1815 - if (!cmd) { 1816 - ret = -ENOMEM; 1817 - goto out; 1818 - } 1819 - 1820 - ret = wl1271_cmd_send(wl, CMD_START_FWLOGGER, cmd, sizeof(*cmd), 0); 1821 - if (ret < 0) { 1822 - wl1271_error("failed to send start firmware logger command"); 1823 - goto out_free; 1824 - } 1825 - 1826 - out_free: 1827 - kfree(cmd); 1828 - 1829 - out: 1830 - return ret; 1831 - } 1832 - 1833 1807 int wl12xx_cmd_stop_fwlog(struct wl1271 *wl) 1834 1808 { 1835 1809 struct wl12xx_cmd_stop_fwlog *cmd;
-1
drivers/net/wireless/ti/wlcore/cmd.h
··· 81 81 int wlcore_cmd_generic_cfg(struct wl1271 *wl, struct wl12xx_vif *wlvif, 82 82 u8 feature, u8 enable, u8 value); 83 83 int wl12xx_cmd_config_fwlog(struct wl1271 *wl); 84 - int wl12xx_cmd_start_fwlog(struct wl1271 *wl); 85 84 int wl12xx_cmd_stop_fwlog(struct wl1271 *wl); 86 85 int wl12xx_cmd_channel_switch(struct wl1271 *wl, 87 86 struct wl12xx_vif *wlvif,
+5 -3
drivers/net/wireless/ti/wlcore/main.c
··· 3166 3166 return 0; 3167 3167 } 3168 3168 3169 - static int wl1271_op_config(struct ieee80211_hw *hw, u32 changed) 3169 + static int wl1271_op_config(struct ieee80211_hw *hw, int radio_idx, u32 changed) 3170 3170 { 3171 3171 struct wl1271 *wl = hw->priv; 3172 3172 struct wl12xx_vif *wlvif; ··· 3895 3895 return 0; 3896 3896 } 3897 3897 3898 - static int wl1271_op_set_frag_threshold(struct ieee80211_hw *hw, u32 value) 3898 + static int wl1271_op_set_frag_threshold(struct ieee80211_hw *hw, 3899 + int radio_idx, u32 value) 3899 3900 { 3900 3901 struct wl1271 *wl = hw->priv; 3901 3902 int ret = 0; ··· 3925 3924 return ret; 3926 3925 } 3927 3926 3928 - static int wl1271_op_set_rts_threshold(struct ieee80211_hw *hw, u32 value) 3927 + static int wl1271_op_set_rts_threshold(struct ieee80211_hw *hw, int radio_idx, 3928 + u32 value) 3929 3929 { 3930 3930 struct wl1271 *wl = hw->priv; 3931 3931 struct wl12xx_vif *wlvif;
+4 -2
drivers/net/wireless/virtual/mac80211_hwsim.c
··· 2381 2381 [NL80211_CHAN_WIDTH_320] = "eht320", 2382 2382 }; 2383 2383 2384 - static int mac80211_hwsim_config(struct ieee80211_hw *hw, u32 changed) 2384 + static int mac80211_hwsim_config(struct ieee80211_hw *hw, int radio_idx, 2385 + u32 changed) 2385 2386 { 2386 2387 struct mac80211_hwsim_data *data = hw->priv; 2387 2388 struct ieee80211_conf *conf = &hw->conf; ··· 3339 3338 return 1; 3340 3339 } 3341 3340 3342 - static int mac80211_hwsim_set_rts_threshold(struct ieee80211_hw *hw, u32 value) 3341 + static int mac80211_hwsim_set_rts_threshold(struct ieee80211_hw *hw, 3342 + int radio_idx, u32 value) 3343 3343 { 3344 3344 return -EOPNOTSUPP; 3345 3345 }
+1 -1
drivers/net/wireless/zydas/zd1211rw/zd_mac.c
··· 1133 1133 zd_mac_free_cur_beacon(mac); 1134 1134 } 1135 1135 1136 - static int zd_op_config(struct ieee80211_hw *hw, u32 changed) 1136 + static int zd_op_config(struct ieee80211_hw *hw, int radio_idx, u32 changed) 1137 1137 { 1138 1138 struct zd_mac *mac = zd_hw_mac(hw); 1139 1139 struct ieee80211_conf *conf = &hw->conf;
+5 -3
drivers/ssb/driver_gpio.c
··· 45 45 return !!ssb_chipco_gpio_in(&bus->chipco, 1 << gpio); 46 46 } 47 47 48 - static void ssb_gpio_chipco_set_value(struct gpio_chip *chip, unsigned int gpio, 49 - int value) 48 + static int ssb_gpio_chipco_set_value(struct gpio_chip *chip, unsigned int gpio, 49 + int value) 50 50 { 51 51 struct ssb_bus *bus = gpiochip_get_data(chip); 52 52 53 53 ssb_chipco_gpio_out(&bus->chipco, 1 << gpio, value ? 1 << gpio : 0); 54 + 55 + return 0; 54 56 } 55 57 56 58 static int ssb_gpio_chipco_direction_input(struct gpio_chip *chip, ··· 225 223 chip->request = ssb_gpio_chipco_request; 226 224 chip->free = ssb_gpio_chipco_free; 227 225 chip->get = ssb_gpio_chipco_get_value; 228 - chip->set = ssb_gpio_chipco_set_value; 226 + chip->set_rv = ssb_gpio_chipco_set_value; 229 227 chip->direction_input = ssb_gpio_chipco_direction_input; 230 228 chip->direction_output = ssb_gpio_chipco_direction_output; 231 229 #if IS_ENABLED(CONFIG_SSB_EMBEDDED)
+4 -2
drivers/staging/rtl8723bs/os_dep/ioctl_cfg80211.c
··· 1298 1298 return ret; 1299 1299 } 1300 1300 1301 - static int cfg80211_rtw_set_wiphy_params(struct wiphy *wiphy, u32 changed) 1301 + static int cfg80211_rtw_set_wiphy_params(struct wiphy *wiphy, int radio_idx, 1302 + u32 changed) 1302 1303 { 1303 1304 return 0; 1304 1305 } ··· 1796 1795 } 1797 1796 1798 1797 static int cfg80211_rtw_set_txpower(struct wiphy *wiphy, 1799 - struct wireless_dev *wdev, 1798 + struct wireless_dev *wdev, int radio_idx, 1800 1799 enum nl80211_tx_power_setting type, int mbm) 1801 1800 { 1802 1801 return 0; ··· 1804 1803 1805 1804 static int cfg80211_rtw_get_txpower(struct wiphy *wiphy, 1806 1805 struct wireless_dev *wdev, 1806 + int radio_idx, 1807 1807 unsigned int link_id, int *dbm) 1808 1808 { 1809 1809 *dbm = (12);
+10
include/linux/ieee80211.h
··· 4007 4007 WLAN_S1G_TWT_INFORMATION = 11, 4008 4008 }; 4009 4009 4010 + /* Radio measurement action codes as defined in IEEE 802.11-2024 - Table 9-470 */ 4011 + enum ieee80211_radio_measurement_actioncode { 4012 + WLAN_RM_ACTION_RADIO_MEASUREMENT_REQUEST = 0, 4013 + WLAN_RM_ACTION_RADIO_MEASUREMENT_REPORT = 1, 4014 + WLAN_RM_ACTION_LINK_MEASUREMENT_REQUEST = 2, 4015 + WLAN_RM_ACTION_LINK_MEASUREMENT_REPORT = 3, 4016 + WLAN_RM_ACTION_NEIGHBOR_REPORT_REQUEST = 4, 4017 + WLAN_RM_ACTION_NEIGHBOR_REPORT_RESPONSE = 5, 4018 + }; 4019 + 4010 4020 #define IEEE80211_WEP_IV_LEN 4 4011 4021 #define IEEE80211_WEP_ICV_LEN 4 4012 4022 #define IEEE80211_CCMP_HDR_LEN 8
+165 -5
include/net/cfg80211.h
··· 560 560 * @vht_cap: VHT capabilities in this band 561 561 * @s1g_cap: S1G capabilities in this band 562 562 * @edmg_cap: EDMG capabilities in this band 563 - * @s1g_cap: S1G capabilities in this band (S1B band only, of course) 563 + * @s1g_cap: S1G capabilities in this band (S1G band only, of course) 564 564 * @n_iftype_data: number of iftype data entries 565 565 * @iftype_data: interface type data entries. Note that the bits in 566 566 * @types_mask inside this structure cannot overlap (i.e. only ··· 1653 1653 * @he_6ghz_capa: HE 6 GHz Band capabilities of station 1654 1654 * @eht_capa: EHT capabilities of station 1655 1655 * @eht_capa_len: the length of the EHT capabilities 1656 + * @s1g_capa: S1G capabilities of station 1656 1657 */ 1657 1658 struct link_station_parameters { 1658 1659 const u8 *mld_mac; ··· 1672 1671 const struct ieee80211_he_6ghz_capa *he_6ghz_capa; 1673 1672 const struct ieee80211_eht_cap_elem *eht_capa; 1674 1673 u8 eht_capa_len; 1674 + const struct ieee80211_s1g_cap *s1g_capa; 1675 1675 }; 1676 1676 1677 1677 /** ··· 2020 2018 #define IEEE80211_MAX_CHAINS 4 2021 2019 2022 2020 /** 2021 + * struct link_station_info - link station information 2022 + * 2023 + * Link station information filled by driver for get_station() and 2024 + * dump_station(). 2025 + * @filled: bit flag of flags using the bits of &enum nl80211_sta_info to 2026 + * indicate the relevant values in this struct for them 2027 + * @connected_time: time(in secs) since a link of station is last connected 2028 + * @inactive_time: time since last activity for link station(tx/rx) 2029 + * in milliseconds 2030 + * @assoc_at: bootime (ns) of the last association of link of station 2031 + * @rx_bytes: bytes (size of MPDUs) received from this link of station 2032 + * @tx_bytes: bytes (size of MPDUs) transmitted to this link of station 2033 + * @signal: The signal strength, type depends on the wiphy's signal_type. 2034 + * For CFG80211_SIGNAL_TYPE_MBM, value is expressed in _dBm_. 2035 + * @signal_avg: Average signal strength, type depends on the wiphy's 2036 + * signal_type. For CFG80211_SIGNAL_TYPE_MBM, value is expressed in _dBm_ 2037 + * @chains: bitmask for filled values in @chain_signal, @chain_signal_avg 2038 + * @chain_signal: per-chain signal strength of last received packet in dBm 2039 + * @chain_signal_avg: per-chain signal strength average in dBm 2040 + * @txrate: current unicast bitrate from this link of station 2041 + * @rxrate: current unicast bitrate to this link of station 2042 + * @rx_packets: packets (MSDUs & MMPDUs) received from this link of station 2043 + * @tx_packets: packets (MSDUs & MMPDUs) transmitted to this link of station 2044 + * @tx_retries: cumulative retry counts (MPDUs) for this link of station 2045 + * @tx_failed: number of failed transmissions (MPDUs) (retries exceeded, no ACK) 2046 + * @rx_dropped_misc: Dropped for un-specified reason. 2047 + * @bss_param: current BSS parameters 2048 + * @beacon_loss_count: Number of times beacon loss event has triggered. 2049 + * @expected_throughput: expected throughput in kbps (including 802.11 headers) 2050 + * towards this station. 2051 + * @rx_beacon: number of beacons received from this peer 2052 + * @rx_beacon_signal_avg: signal strength average (in dBm) for beacons received 2053 + * from this peer 2054 + * @rx_duration: aggregate PPDU duration(usecs) for all the frames from a peer 2055 + * @tx_duration: aggregate PPDU duration(usecs) for all the frames to a peer 2056 + * @airtime_weight: current airtime scheduling weight 2057 + * @pertid: per-TID statistics, see &struct cfg80211_tid_stats, using the last 2058 + * (IEEE80211_NUM_TIDS) index for MSDUs not encapsulated in QoS-MPDUs. 2059 + * Note that this doesn't use the @filled bit, but is used if non-NULL. 2060 + * @ack_signal: signal strength (in dBm) of the last ACK frame. 2061 + * @avg_ack_signal: average rssi value of ack packet for the no of msdu's has 2062 + * been sent. 2063 + * @rx_mpdu_count: number of MPDUs received from this station 2064 + * @fcs_err_count: number of packets (MPDUs) received from this station with 2065 + * an FCS error. This counter should be incremented only when TA of the 2066 + * received packet with an FCS error matches the peer MAC address. 2067 + * @addr: For MLO STA connection, filled with address of the link of station. 2068 + */ 2069 + struct link_station_info { 2070 + u64 filled; 2071 + u32 connected_time; 2072 + u32 inactive_time; 2073 + u64 assoc_at; 2074 + u64 rx_bytes; 2075 + u64 tx_bytes; 2076 + s8 signal; 2077 + s8 signal_avg; 2078 + 2079 + u8 chains; 2080 + s8 chain_signal[IEEE80211_MAX_CHAINS]; 2081 + s8 chain_signal_avg[IEEE80211_MAX_CHAINS]; 2082 + 2083 + struct rate_info txrate; 2084 + struct rate_info rxrate; 2085 + u32 rx_packets; 2086 + u32 tx_packets; 2087 + u32 tx_retries; 2088 + u32 tx_failed; 2089 + u32 rx_dropped_misc; 2090 + struct sta_bss_parameters bss_param; 2091 + 2092 + u32 beacon_loss_count; 2093 + 2094 + u32 expected_throughput; 2095 + 2096 + u64 tx_duration; 2097 + u64 rx_duration; 2098 + u64 rx_beacon; 2099 + u8 rx_beacon_signal_avg; 2100 + 2101 + u16 airtime_weight; 2102 + 2103 + s8 ack_signal; 2104 + s8 avg_ack_signal; 2105 + struct cfg80211_tid_stats *pertid; 2106 + 2107 + u32 rx_mpdu_count; 2108 + u32 fcs_err_count; 2109 + 2110 + u8 addr[ETH_ALEN] __aligned(2); 2111 + }; 2112 + 2113 + /** 2023 2114 * struct station_info - station information 2024 2115 * 2025 2116 * Station information filled by driver for get_station() and dump_station. ··· 2196 2101 * dump_station() callbacks. User space needs this information to determine 2197 2102 * the accepted and rejected affiliated links of the connected station. 2198 2103 * @assoc_resp_ies_len: Length of @assoc_resp_ies buffer in octets. 2104 + * @valid_links: bitmap of valid links, or 0 for non-MLO. Drivers fill this 2105 + * information in cfg80211_new_sta(), cfg80211_del_sta_sinfo(), 2106 + * get_station() and dump_station() callbacks. 2107 + * @links: reference to Link sta entries for MLO STA, all link specific 2108 + * information is accessed through links[link_id]. 2199 2109 */ 2200 2110 struct station_info { 2201 2111 u64 filled; ··· 2265 2165 u8 mld_addr[ETH_ALEN] __aligned(2); 2266 2166 const u8 *assoc_resp_ies; 2267 2167 size_t assoc_resp_ies_len; 2168 + 2169 + u16 valid_links; 2170 + struct link_station_info *links[IEEE80211_MLD_MAX_NUM_LINKS]; 2268 2171 }; 2269 2172 2270 2173 /** ··· 4855 4752 int (*set_mcast_rate)(struct wiphy *wiphy, struct net_device *dev, 4856 4753 int rate[NUM_NL80211_BANDS]); 4857 4754 4858 - int (*set_wiphy_params)(struct wiphy *wiphy, u32 changed); 4755 + int (*set_wiphy_params)(struct wiphy *wiphy, int radio_idx, 4756 + u32 changed); 4859 4757 4860 4758 int (*set_tx_power)(struct wiphy *wiphy, struct wireless_dev *wdev, 4759 + int radio_idx, 4861 4760 enum nl80211_tx_power_setting type, int mbm); 4862 4761 int (*get_tx_power)(struct wiphy *wiphy, struct wireless_dev *wdev, 4863 - unsigned int link_id, int *dbm); 4762 + int radio_idx, unsigned int link_id, int *dbm); 4864 4763 4865 4764 void (*rfkill_poll)(struct wiphy *wiphy); 4866 4765 ··· 4924 4819 struct wireless_dev *wdev, 4925 4820 struct mgmt_frame_regs *upd); 4926 4821 4927 - int (*set_antenna)(struct wiphy *wiphy, u32 tx_ant, u32 rx_ant); 4928 - int (*get_antenna)(struct wiphy *wiphy, u32 *tx_ant, u32 *rx_ant); 4822 + int (*set_antenna)(struct wiphy *wiphy, int radio_idx, 4823 + u32 tx_ant, u32 rx_ant); 4824 + int (*get_antenna)(struct wiphy *wiphy, int radio_idx, 4825 + u32 *tx_ant, u32 *rx_ant); 4929 4826 4930 4827 int (*sched_scan_start)(struct wiphy *wiphy, 4931 4828 struct net_device *dev, ··· 5550 5443 }; 5551 5444 5552 5445 /** 5446 + * struct wiphy_radio_cfg - physical radio config of a wiphy 5447 + * This structure describes the configurations of a physical radio in a 5448 + * wiphy. It is used to denote per-radio attributes belonging to a wiphy. 5449 + * 5450 + * @rts_threshold: RTS threshold (dot11RTSThreshold); 5451 + * -1 (default) = RTS/CTS disabled 5452 + */ 5453 + struct wiphy_radio_cfg { 5454 + u32 rts_threshold; 5455 + }; 5456 + 5457 + /** 5553 5458 * struct wiphy_radio_freq_range - wiphy frequency range 5554 5459 * @start_freq: start range edge frequency (kHz) 5555 5460 * @end_freq: end range edge frequency (kHz) ··· 5816 5697 * supports enabling HW timestamping for all peers (i.e. no need to 5817 5698 * specify a mac address). 5818 5699 * 5700 + * @radio_cfg: configuration of radios belonging to a muli-radio wiphy. This 5701 + * struct contains a list of all radio specific attributes and should be 5702 + * used only for multi-radio wiphy. 5703 + * 5819 5704 * @radio: radios belonging to this wiphy 5820 5705 * @n_radio: number of radios 5821 5706 */ ··· 5908 5785 5909 5786 void (*reg_notifier)(struct wiphy *wiphy, 5910 5787 struct regulatory_request *request); 5788 + 5789 + struct wiphy_radio_cfg *radio_cfg; 5911 5790 5912 5791 /* fields below are read-only, assigned by cfg80211 */ 5913 5792 ··· 8591 8466 int cfg80211_sinfo_alloc_tid_stats(struct station_info *sinfo, gfp_t gfp); 8592 8467 8593 8468 /** 8469 + * cfg80211_link_sinfo_alloc_tid_stats - allocate per-tid statistics. 8470 + * 8471 + * @link_sinfo: the link station information 8472 + * @gfp: allocation flags 8473 + * 8474 + * Return: 0 on success. Non-zero on error. 8475 + */ 8476 + int cfg80211_link_sinfo_alloc_tid_stats(struct link_station_info *link_sinfo, 8477 + gfp_t gfp); 8478 + 8479 + /** 8594 8480 * cfg80211_sinfo_release_content - release contents of station info 8595 8481 * @sinfo: the station information 8596 8482 * ··· 8612 8476 static inline void cfg80211_sinfo_release_content(struct station_info *sinfo) 8613 8477 { 8614 8478 kfree(sinfo->pertid); 8479 + 8480 + for (int link_id = 0; link_id < ARRAY_SIZE(sinfo->links); link_id++) { 8481 + if (sinfo->links[link_id]) { 8482 + kfree(sinfo->links[link_id]->pertid); 8483 + kfree(sinfo->links[link_id]); 8484 + } 8485 + } 8615 8486 } 8616 8487 8617 8488 /** ··· 9515 9372 void (*iter)(const struct ieee80211_iface_combination *c, 9516 9373 void *data), 9517 9374 void *data); 9375 + /** 9376 + * cfg80211_get_radio_idx_by_chan - get the radio index by the channel 9377 + * 9378 + * @wiphy: the wiphy 9379 + * @chan: channel for which the supported radio index is required 9380 + * 9381 + * Return: radio index on success or a negative error code 9382 + */ 9383 + int cfg80211_get_radio_idx_by_chan(struct wiphy *wiphy, 9384 + const struct ieee80211_channel *chan); 9385 + 9518 9386 9519 9387 /** 9520 9388 * cfg80211_stop_iface - trigger interface disconnection ··· 9890 9736 * struct cfg80211_mlo_reconf_done_data - MLO reconfiguration data 9891 9737 * @buf: MLO Reconfiguration Response frame (header + body) 9892 9738 * @len: length of the frame data 9739 + * @driver_initiated: Indicates whether the add links request is initiated by 9740 + * driver. This is set to true when the link reconfiguration request 9741 + * initiated by driver due to AP link recommendation requests 9742 + * (Ex: BTM (BSS Transition Management) request) handling offloaded to 9743 + * driver. 9893 9744 * @added_links: BIT mask of links successfully added to the association 9894 9745 * @links: per-link information indexed by link ID 9895 9746 * @links.bss: the BSS that MLO reconfiguration was requested for, ownership of ··· 9907 9748 struct cfg80211_mlo_reconf_done_data { 9908 9749 const u8 *buf; 9909 9750 size_t len; 9751 + bool driver_initiated; 9910 9752 u16 added_links; 9911 9753 struct { 9912 9754 struct cfg80211_bss *bss;
+28 -7
include/net/mac80211.h
··· 2428 2428 * @he_cap: HE capabilities of this STA 2429 2429 * @he_6ghz_capa: on 6 GHz, holds the HE 6 GHz band capabilities 2430 2430 * @eht_cap: EHT capabilities of this STA 2431 + * @s1g_cap: S1G capabilities of this STA 2431 2432 * @agg: per-link data for multi-link aggregation 2432 2433 * @bandwidth: current bandwidth the station can receive with 2433 2434 * @rx_nss: in HT/VHT, the maximum number of spatial streams the ··· 2451 2450 struct ieee80211_sta_he_cap he_cap; 2452 2451 struct ieee80211_he_6ghz_capa he_6ghz_capa; 2453 2452 struct ieee80211_sta_eht_cap eht_cap; 2453 + struct ieee80211_sta_s1g_cap s1g_cap; 2454 2454 2455 2455 struct ieee80211_sta_aggregates agg; 2456 2456 ··· 4135 4133 * Statistics that the driver doesn't fill will be filled by mac80211. 4136 4134 * The callback can sleep. 4137 4135 * 4136 + * @link_sta_statistics: Get link statistics for this station. For example with 4137 + * beacon filtering, the statistics kept by mac80211 might not be 4138 + * accurate, so let the driver pre-fill the statistics. The driver can 4139 + * fill most of the values (indicating which by setting the filled 4140 + * bitmap), but not all of them make sense - see the source for which 4141 + * ones are possible. 4142 + * Statistics that the driver doesn't fill will be filled by mac80211. 4143 + * The callback can sleep. 4144 + * 4138 4145 * @conf_tx: Configure TX queue parameters (EDCF (aifs, cw_min, cw_max), 4139 4146 * bursting) for a hardware TX queue. 4140 4147 * Returns a negative error code on failure. ··· 4519 4508 enum nl80211_iftype new_type, bool p2p); 4520 4509 void (*remove_interface)(struct ieee80211_hw *hw, 4521 4510 struct ieee80211_vif *vif); 4522 - int (*config)(struct ieee80211_hw *hw, u32 changed); 4511 + int (*config)(struct ieee80211_hw *hw, int radio_idx, u32 changed); 4523 4512 void (*bss_info_changed)(struct ieee80211_hw *hw, 4524 4513 struct ieee80211_vif *vif, 4525 4514 struct ieee80211_bss_conf *info, ··· 4582 4571 void (*get_key_seq)(struct ieee80211_hw *hw, 4583 4572 struct ieee80211_key_conf *key, 4584 4573 struct ieee80211_key_seq *seq); 4585 - int (*set_frag_threshold)(struct ieee80211_hw *hw, u32 value); 4586 - int (*set_rts_threshold)(struct ieee80211_hw *hw, u32 value); 4574 + int (*set_frag_threshold)(struct ieee80211_hw *hw, int radio_idx, 4575 + u32 value); 4576 + int (*set_rts_threshold)(struct ieee80211_hw *hw, int radio_idx, 4577 + u32 value); 4587 4578 int (*sta_add)(struct ieee80211_hw *hw, struct ieee80211_vif *vif, 4588 4579 struct ieee80211_sta *sta); 4589 4580 int (*sta_remove)(struct ieee80211_hw *hw, struct ieee80211_vif *vif, ··· 4640 4627 s64 offset); 4641 4628 void (*reset_tsf)(struct ieee80211_hw *hw, struct ieee80211_vif *vif); 4642 4629 int (*tx_last_beacon)(struct ieee80211_hw *hw); 4630 + void (*link_sta_statistics)(struct ieee80211_hw *hw, 4631 + struct ieee80211_vif *vif, 4632 + struct ieee80211_link_sta *link_sta, 4633 + struct link_station_info *link_sinfo); 4643 4634 4644 4635 /** 4645 4636 * @ampdu_action: ··· 4682 4665 int (*get_survey)(struct ieee80211_hw *hw, int idx, 4683 4666 struct survey_info *survey); 4684 4667 void (*rfkill_poll)(struct ieee80211_hw *hw); 4685 - void (*set_coverage_class)(struct ieee80211_hw *hw, s16 coverage_class); 4668 + void (*set_coverage_class)(struct ieee80211_hw *hw, int radio_idx, 4669 + s16 coverage_class); 4686 4670 #ifdef CONFIG_NL80211_TESTMODE 4687 4671 int (*testmode_cmd)(struct ieee80211_hw *hw, struct ieee80211_vif *vif, 4688 4672 void *data, int len); ··· 4698 4680 void (*channel_switch)(struct ieee80211_hw *hw, 4699 4681 struct ieee80211_vif *vif, 4700 4682 struct ieee80211_channel_switch *ch_switch); 4701 - int (*set_antenna)(struct ieee80211_hw *hw, u32 tx_ant, u32 rx_ant); 4702 - int (*get_antenna)(struct ieee80211_hw *hw, u32 *tx_ant, u32 *rx_ant); 4683 + int (*set_antenna)(struct ieee80211_hw *hw, int radio_idx, 4684 + u32 tx_ant, u32 rx_ant); 4685 + int (*get_antenna)(struct ieee80211_hw *hw, int radio_idx, 4686 + u32 *tx_ant, u32 *rx_ant); 4703 4687 4704 4688 int (*remain_on_channel)(struct ieee80211_hw *hw, 4705 4689 struct ieee80211_vif *vif, ··· 7262 7242 * ieee80211_ave_rssi - report the average RSSI for the specified interface 7263 7243 * 7264 7244 * @vif: the specified virtual interface 7245 + * @link_id: the link ID for MLO, or -1 for non-MLO 7265 7246 * 7266 7247 * Note: This function assumes that the given vif is valid. 7267 7248 * 7268 7249 * Return: The average RSSI value for the requested interface, or 0 if not 7269 7250 * applicable. 7270 7251 */ 7271 - int ieee80211_ave_rssi(struct ieee80211_vif *vif); 7252 + int ieee80211_ave_rssi(struct ieee80211_vif *vif, int link_id); 7272 7253 7273 7254 /** 7274 7255 * ieee80211_report_wowlan_wakeup - report WoWLAN wakeup
+21 -1
include/uapi/linux/nl80211.h
··· 1330 1330 * TID to Link mapping for downlink/uplink traffic. 1331 1331 * 1332 1332 * @NL80211_CMD_ASSOC_MLO_RECONF: For a non-AP MLD station, request to 1333 - * add/remove links to/from the association. 1333 + * add/remove links to/from the association. To indicate link 1334 + * reconfiguration request results from the driver, this command is also 1335 + * used as an event to notify userspace about the added links information. 1336 + * For notifying the removed links information, the existing 1337 + * %NL80211_CMD_LINKS_REMOVED command is used. This command is also used to 1338 + * notify userspace about newly added links for the current connection in 1339 + * case of AP-initiated link recommendation requests, received via 1340 + * a BTM (BSS Transition Management) request or a link reconfig notify 1341 + * frame, where the driver handles the link recommendation offload. 1334 1342 * 1335 1343 * @NL80211_CMD_EPCS_CFG: EPCS configuration for a station. Used by userland to 1336 1344 * control EPCS configuration. Used to notify userland on the current state ··· 2907 2899 * APs Support". Drivers may set additional flags that they support 2908 2900 * in the kernel or device. 2909 2901 * 2902 + * @NL80211_ATTR_WIPHY_RADIO_INDEX: (int) Integer attribute denoting the index 2903 + * of the radio in interest. Internally a value of -1 is used to 2904 + * indicate that the radio id is not given in user-space. This means 2905 + * that all the attributes are applicable to all the radios. If there is 2906 + * a radio index provided in user-space, the attributes will be 2907 + * applicable to that specific radio only. If the radio id is greater 2908 + * thank the number of radios, error denoting invalid value is returned. 2909 + * 2910 2910 * @NUM_NL80211_ATTR: total number of nl80211_attrs available 2911 2911 * @NL80211_ATTR_MAX: highest attribute number currently defined 2912 2912 * @__NL80211_ATTR_AFTER_LAST: internal use ··· 3471 3455 NL80211_ATTR_EPCS, 3472 3456 3473 3457 NL80211_ATTR_ASSOC_MLD_EXT_CAPA_OPS, 3458 + 3459 + NL80211_ATTR_WIPHY_RADIO_INDEX, 3474 3460 3475 3461 /* add attributes here, update the policy in nl80211.c */ 3476 3462 ··· 8106 8088 * and contains attributes defined in &enum nl80211_if_combination_attrs. 8107 8089 * @NL80211_WIPHY_RADIO_ATTR_ANTENNA_MASK: bitmask (u32) of antennas 8108 8090 * connected to this radio. 8091 + * @NL80211_WIPHY_RADIO_ATTR_RTS_THRESHOLD: RTS threshold (u32) of this radio. 8109 8092 * 8110 8093 * @__NL80211_WIPHY_RADIO_ATTR_LAST: Internal 8111 8094 * @NL80211_WIPHY_RADIO_ATTR_MAX: Highest attribute ··· 8118 8099 NL80211_WIPHY_RADIO_ATTR_FREQ_RANGE, 8119 8100 NL80211_WIPHY_RADIO_ATTR_INTERFACE_COMBINATION, 8120 8101 NL80211_WIPHY_RADIO_ATTR_ANTENNA_MASK, 8102 + NL80211_WIPHY_RADIO_ATTR_RTS_THRESHOLD, 8121 8103 8122 8104 /* keep last */ 8123 8105 __NL80211_WIPHY_RADIO_ATTR_LAST,
+4 -2
net/mac80211/agg-rx.c
··· 299 299 300 300 if (!sta->sta.valid_links && 301 301 !sta->sta.deflink.ht_cap.ht_supported && 302 - !sta->sta.deflink.he_cap.has_he) { 302 + !sta->sta.deflink.he_cap.has_he && 303 + !sta->sta.deflink.s1g_cap.s1g) { 303 304 ht_dbg(sta->sdata, 304 305 "STA %pM erroneously requests BA session on tid %d w/o HT\n", 305 306 sta->sta.addr, tid); ··· 328 327 /* XXX: check own ht delayed BA capability?? */ 329 328 if (((ba_policy != 1) && 330 329 (sta->sta.valid_links || 331 - !(sta->sta.deflink.ht_cap.cap & IEEE80211_HT_CAP_DELAY_BA))) || 330 + !(sta->sta.deflink.ht_cap.cap & IEEE80211_HT_CAP_DELAY_BA) || 331 + !(sta->sta.deflink.s1g_cap.cap[3] & S1G_CAP3_HT_DELAYED_BA))) || 332 332 (buf_size > max_buf_size)) { 333 333 status = WLAN_STATUS_INVALID_QOS_PARAM; 334 334 ht_dbg_ratelimited(sta->sdata,
+2 -1
net/mac80211/agg-tx.c
··· 616 616 !pubsta->deflink.ht_cap.ht_supported && 617 617 !pubsta->deflink.vht_cap.vht_supported && 618 618 !pubsta->deflink.he_cap.has_he && 619 - !pubsta->deflink.eht_cap.has_eht) 619 + !pubsta->deflink.eht_cap.has_eht && 620 + !pubsta->deflink.s1g_cap.s1g) 620 621 return -EINVAL; 621 622 622 623 if (WARN_ON_ONCE(!local->ops->ampdu_action))
+102 -15
net/mac80211/cfg.c
··· 178 178 179 179 link_conf->nontransmitted = true; 180 180 link_conf->bssid_index = params->index; 181 + link_conf->bssid_indicator = tx_bss_conf->bssid_indicator; 181 182 } 182 183 if (params->ema) 183 184 link_conf->ema_ap = true; ··· 886 885 ret = 0; 887 886 memcpy(mac, sta->sta.addr, ETH_ALEN); 888 887 sta_set_sinfo(sta, sinfo, true); 888 + 889 + /* Add accumulated removed link data to sinfo data for 890 + * consistency for MLO 891 + */ 892 + if (sinfo->valid_links) 893 + sta_set_accumulated_removed_links_sinfo(sta, sinfo); 894 + 889 895 } 890 896 891 897 return ret; ··· 920 912 if (sta) { 921 913 ret = 0; 922 914 sta_set_sinfo(sta, sinfo, true); 915 + 916 + /* Add accumulated removed link data to sinfo data for 917 + * consistency for MLO 918 + */ 919 + if (sinfo->valid_links) 920 + sta_set_accumulated_removed_links_sinfo(sta, sinfo); 923 921 } 924 922 925 923 return ret; ··· 1232 1218 ieee80211_copy_rnr_beacon(pos, new->rnr_ies, rnr); 1233 1219 } 1234 1220 /* update bssid_indicator */ 1235 - link_conf->bssid_indicator = 1236 - ilog2(__roundup_pow_of_two(mbssid->cnt + 1)); 1221 + if (new->mbssid_ies->cnt && new->mbssid_ies->elem[0].len > 2) 1222 + link_conf->bssid_indicator = 1223 + *(new->mbssid_ies->elem[0].data + 2); 1224 + else 1225 + link_conf->bssid_indicator = 0; 1237 1226 } 1238 1227 1239 1228 if (csa) { ··· 1895 1878 params->vht_capa || 1896 1879 params->he_capa || 1897 1880 params->eht_capa || 1881 + params->s1g_capa || 1898 1882 params->opmode_notif_used; 1899 1883 1900 1884 switch (mode) { ··· 1973 1955 params->eht_capa, 1974 1956 params->eht_capa_len, 1975 1957 link_sta); 1958 + 1959 + if (params->s1g_capa) 1960 + ieee80211_s1g_cap_to_sta_s1g_cap(sdata, params->s1g_capa, 1961 + link_sta); 1976 1962 1977 1963 ieee80211_sta_init_nss(link_sta); 1978 1964 ··· 3050 3028 return 0; 3051 3029 } 3052 3030 3053 - static int ieee80211_set_wiphy_params(struct wiphy *wiphy, u32 changed) 3031 + static int ieee80211_set_wiphy_params(struct wiphy *wiphy, int radio_idx, 3032 + u32 changed) 3054 3033 { 3055 3034 struct ieee80211_local *local = wiphy_priv(wiphy); 3056 3035 int err; ··· 3059 3036 if (changed & WIPHY_PARAM_FRAG_THRESHOLD) { 3060 3037 ieee80211_check_fast_xmit_all(local); 3061 3038 3062 - err = drv_set_frag_threshold(local, wiphy->frag_threshold); 3039 + err = drv_set_frag_threshold(local, radio_idx, 3040 + wiphy->frag_threshold); 3063 3041 3064 3042 if (err) { 3065 3043 ieee80211_check_fast_xmit_all(local); ··· 3074 3050 3075 3051 coverage_class = changed & WIPHY_PARAM_COVERAGE_CLASS ? 3076 3052 wiphy->coverage_class : -1; 3077 - err = drv_set_coverage_class(local, coverage_class); 3053 + err = drv_set_coverage_class(local, radio_idx, 3054 + coverage_class); 3078 3055 3079 3056 if (err) 3080 3057 return err; 3081 3058 } 3082 3059 3083 3060 if (changed & WIPHY_PARAM_RTS_THRESHOLD) { 3084 - err = drv_set_rts_threshold(local, wiphy->rts_threshold); 3061 + u32 rts_threshold; 3062 + 3063 + if ((radio_idx == -1) || (radio_idx >= wiphy->n_radio)) 3064 + rts_threshold = wiphy->rts_threshold; 3065 + else 3066 + rts_threshold = 3067 + wiphy->radio_cfg[radio_idx].rts_threshold; 3068 + 3069 + err = drv_set_rts_threshold(local, radio_idx, rts_threshold); 3085 3070 3086 3071 if (err) 3087 3072 return err; ··· 3108 3075 } 3109 3076 if (changed & 3110 3077 (WIPHY_PARAM_RETRY_SHORT | WIPHY_PARAM_RETRY_LONG)) 3111 - ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_RETRY_LIMITS); 3078 + ieee80211_hw_config(local, radio_idx, 3079 + IEEE80211_CONF_CHANGE_RETRY_LIMITS); 3112 3080 3113 3081 if (changed & (WIPHY_PARAM_TXQ_LIMIT | 3114 3082 WIPHY_PARAM_TXQ_MEMORY_LIMIT | 3115 3083 WIPHY_PARAM_TXQ_QUANTUM)) 3116 - ieee80211_txq_set_params(local); 3084 + ieee80211_txq_set_params(local, radio_idx); 3117 3085 3118 3086 return 0; 3119 3087 } 3120 3088 3121 3089 static int ieee80211_set_tx_power(struct wiphy *wiphy, 3122 - struct wireless_dev *wdev, 3090 + struct wireless_dev *wdev, int radio_idx, 3123 3091 enum nl80211_tx_power_setting type, int mbm) 3124 3092 { 3125 3093 struct ieee80211_local *local = wiphy_priv(wiphy); ··· 3248 3214 3249 3215 static int ieee80211_get_tx_power(struct wiphy *wiphy, 3250 3216 struct wireless_dev *wdev, 3217 + int radio_idx, 3251 3218 unsigned int link_id, 3252 3219 int *dbm) 3253 3220 { ··· 3427 3392 } 3428 3393 3429 3394 if (ieee80211_hw_check(&local->hw, SUPPORTS_DYNAMIC_PS)) 3430 - ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_PS); 3395 + ieee80211_hw_config(local, -1, IEEE80211_CONF_CHANGE_PS); 3431 3396 3432 3397 ieee80211_recalc_ps(local); 3433 3398 ieee80211_recalc_ps_vif(sdata); ··· 3584 3549 return 0; 3585 3550 } 3586 3551 3552 + static bool ieee80211_is_scan_ongoing(struct wiphy *wiphy, 3553 + struct ieee80211_local *local, 3554 + struct cfg80211_chan_def *chandef) 3555 + { 3556 + struct cfg80211_scan_request *scan_req; 3557 + int chan_radio_idx, req_radio_idx; 3558 + struct ieee80211_roc_work *roc; 3559 + 3560 + if (list_empty(&local->roc_list) && !local->scanning) 3561 + return false; 3562 + 3563 + if (wiphy->n_radio < 2) 3564 + return true; 3565 + 3566 + req_radio_idx = cfg80211_get_radio_idx_by_chan(wiphy, chandef->chan); 3567 + if (req_radio_idx < 0) 3568 + return true; 3569 + 3570 + if (local->scanning) { 3571 + scan_req = wiphy_dereference(wiphy, local->scan_req); 3572 + /* 3573 + * Scan is going on but info is not there. Should not happen 3574 + * but if it does, let's not take risk and assume we can't use 3575 + * the hw hence return true 3576 + */ 3577 + if (WARN_ON_ONCE(!scan_req)) 3578 + return true; 3579 + 3580 + return ieee80211_is_radio_idx_in_scan_req(wiphy, scan_req, 3581 + req_radio_idx); 3582 + } 3583 + 3584 + list_for_each_entry(roc, &local->roc_list, list) { 3585 + chan_radio_idx = cfg80211_get_radio_idx_by_chan(wiphy, 3586 + roc->chan); 3587 + /* 3588 + * The roc work is added but chan_radio_idx is invalid. 3589 + * Should not happen but if it does, let's not take 3590 + * risk and return true. 3591 + */ 3592 + if (chan_radio_idx < 0) 3593 + return true; 3594 + 3595 + if (chan_radio_idx == req_radio_idx) 3596 + return true; 3597 + } 3598 + 3599 + return false; 3600 + } 3601 + 3587 3602 static int ieee80211_start_radar_detection(struct wiphy *wiphy, 3588 3603 struct net_device *dev, 3589 3604 struct cfg80211_chan_def *chandef, ··· 3647 3562 3648 3563 lockdep_assert_wiphy(local->hw.wiphy); 3649 3564 3650 - if (!list_empty(&local->roc_list) || local->scanning) 3565 + if (ieee80211_is_scan_ongoing(wiphy, local, chandef)) 3651 3566 return -EBUSY; 3652 3567 3653 3568 link_data = sdata_dereference(sdata->link[link_id], sdata); ··· 4139 4054 4140 4055 lockdep_assert_wiphy(local->hw.wiphy); 4141 4056 4142 - if (!list_empty(&local->roc_list) || local->scanning) 4057 + if (ieee80211_is_scan_ongoing(wiphy, local, &params->chandef)) 4143 4058 return -EBUSY; 4144 4059 4145 4060 if (sdata->wdev.links[link_id].cac_started) ··· 4323 4238 ieee80211_configure_filter(local); 4324 4239 } 4325 4240 4326 - static int ieee80211_set_antenna(struct wiphy *wiphy, u32 tx_ant, u32 rx_ant) 4241 + static int ieee80211_set_antenna(struct wiphy *wiphy, int radio_idx, 4242 + u32 tx_ant, u32 rx_ant) 4327 4243 { 4328 4244 struct ieee80211_local *local = wiphy_priv(wiphy); 4329 4245 int ret; ··· 4340 4254 return 0; 4341 4255 } 4342 4256 4343 - static int ieee80211_get_antenna(struct wiphy *wiphy, u32 *tx_ant, u32 *rx_ant) 4257 + static int ieee80211_get_antenna(struct wiphy *wiphy, int radio_idx, 4258 + u32 *tx_ant, u32 *rx_ant) 4344 4259 { 4345 4260 struct ieee80211_local *local = wiphy_priv(wiphy); 4346 4261 4347 - return drv_get_antenna(local, tx_ant, rx_ant); 4262 + return drv_get_antenna(local, radio_idx, tx_ant, rx_ant); 4348 4263 } 4349 4264 4350 4265 static int ieee80211_set_rekey_data(struct wiphy *wiphy,
+29 -4
net/mac80211/chan.c
··· 644 644 return NULL; 645 645 } 646 646 647 - bool ieee80211_is_radar_required(struct ieee80211_local *local) 647 + bool ieee80211_is_radar_required(struct ieee80211_local *local, 648 + struct cfg80211_scan_request *req) 648 649 { 650 + struct wiphy *wiphy = local->hw.wiphy; 649 651 struct ieee80211_link_data *link; 652 + struct ieee80211_channel *chan; 653 + int radio_idx; 650 654 651 655 lockdep_assert_wiphy(local->hw.wiphy); 652 656 657 + if (!req) 658 + return false; 659 + 653 660 for_each_sdata_link(local, link) { 654 - if (link->radar_required) 655 - return true; 661 + if (link->radar_required) { 662 + if (wiphy->n_radio < 2) 663 + return true; 664 + 665 + chan = link->conf->chanreq.oper.chan; 666 + radio_idx = cfg80211_get_radio_idx_by_chan(wiphy, chan); 667 + /* 668 + * The radio index (radio_idx) is expected to be valid, 669 + * as it's derived from a channel tied to a link. If 670 + * it's invalid (i.e., negative), return true to avoid 671 + * potential issues with radar-sensitive operations. 672 + */ 673 + if (radio_idx < 0) 674 + return true; 675 + 676 + if (ieee80211_is_radio_idx_in_scan_req(wiphy, req, 677 + radio_idx)) 678 + return true; 679 + } 656 680 } 657 681 658 682 return false; ··· 744 720 /* turn idle off *before* setting channel -- some drivers need that */ 745 721 changed = ieee80211_idle_off(local); 746 722 if (changed) 747 - ieee80211_hw_config(local, changed); 723 + ieee80211_hw_config(local, -1, changed); 748 724 749 725 err = drv_add_chanctx(local, ctx); 750 726 if (err) { ··· 1405 1381 goto out; 1406 1382 } 1407 1383 1384 + link->radar_required = link->reserved_radar_required; 1408 1385 list_move(&link->assigned_chanctx_list, &new_ctx->assigned_links); 1409 1386 rcu_assign_pointer(link_conf->chanctx_conf, &new_ctx->conf); 1410 1387
+39 -16
net/mac80211/driver-ops.h
··· 143 143 void drv_remove_interface(struct ieee80211_local *local, 144 144 struct ieee80211_sub_if_data *sdata); 145 145 146 - static inline int drv_config(struct ieee80211_local *local, u32 changed) 146 + static inline int drv_config(struct ieee80211_local *local, int radio_idx, 147 + u32 changed) 147 148 { 148 149 int ret; 149 150 150 151 might_sleep(); 151 152 lockdep_assert_wiphy(local->hw.wiphy); 152 153 153 - trace_drv_config(local, changed); 154 - ret = local->ops->config(&local->hw, changed); 154 + trace_drv_config(local, radio_idx, changed); 155 + ret = local->ops->config(&local->hw, radio_idx, changed); 155 156 trace_drv_return_int(local, ret); 156 157 return ret; 157 158 } ··· 388 387 } 389 388 390 389 static inline int drv_set_frag_threshold(struct ieee80211_local *local, 391 - u32 value) 390 + int radio_idx, u32 value) 392 391 { 393 392 int ret = 0; 394 393 395 394 might_sleep(); 396 395 lockdep_assert_wiphy(local->hw.wiphy); 397 396 398 - trace_drv_set_frag_threshold(local, value); 397 + trace_drv_set_frag_threshold(local, radio_idx, value); 399 398 if (local->ops->set_frag_threshold) 400 - ret = local->ops->set_frag_threshold(&local->hw, value); 399 + ret = local->ops->set_frag_threshold(&local->hw, radio_idx, 400 + value); 401 401 trace_drv_return_int(local, ret); 402 402 return ret; 403 403 } 404 404 405 405 static inline int drv_set_rts_threshold(struct ieee80211_local *local, 406 - u32 value) 406 + int radio_idx, u32 value) 407 407 { 408 408 int ret = 0; 409 409 410 410 might_sleep(); 411 411 lockdep_assert_wiphy(local->hw.wiphy); 412 412 413 - trace_drv_set_rts_threshold(local, value); 413 + trace_drv_set_rts_threshold(local, radio_idx, value); 414 414 if (local->ops->set_rts_threshold) 415 - ret = local->ops->set_rts_threshold(&local->hw, value); 415 + ret = local->ops->set_rts_threshold(&local->hw, radio_idx, 416 + value); 416 417 trace_drv_return_int(local, ret); 417 418 return ret; 418 419 } 419 420 420 421 static inline int drv_set_coverage_class(struct ieee80211_local *local, 421 - s16 value) 422 + int radio_idx, s16 value) 422 423 { 423 424 int ret = 0; 424 425 might_sleep(); 425 426 lockdep_assert_wiphy(local->hw.wiphy); 426 427 427 - trace_drv_set_coverage_class(local, value); 428 + trace_drv_set_coverage_class(local, radio_idx, value); 428 429 if (local->ops->set_coverage_class) 429 - local->ops->set_coverage_class(&local->hw, value); 430 + local->ops->set_coverage_class(&local->hw, radio_idx, value); 430 431 else 431 432 ret = -EOPNOTSUPP; 432 433 ··· 634 631 trace_drv_return_void(local); 635 632 } 636 633 634 + static inline void drv_link_sta_statistics(struct ieee80211_local *local, 635 + struct ieee80211_sub_if_data *sdata, 636 + struct ieee80211_link_sta *link_sta, 637 + struct link_station_info *link_sinfo) 638 + { 639 + might_sleep(); 640 + lockdep_assert_wiphy(local->hw.wiphy); 641 + 642 + sdata = get_bss_sdata(sdata); 643 + if (!check_sdata_in_driver(sdata)) 644 + return; 645 + 646 + trace_drv_link_sta_statistics(local, sdata, link_sta); 647 + if (local->ops->link_sta_statistics) 648 + local->ops->link_sta_statistics(&local->hw, &sdata->vif, 649 + link_sta, link_sinfo); 650 + trace_drv_return_void(local); 651 + } 652 + 637 653 int drv_conf_tx(struct ieee80211_local *local, 638 654 struct ieee80211_link_data *link, u16 ac, 639 655 const struct ieee80211_tx_queue_params *params); ··· 775 753 might_sleep(); 776 754 lockdep_assert_wiphy(local->hw.wiphy); 777 755 if (local->ops->set_antenna) 778 - ret = local->ops->set_antenna(&local->hw, tx_ant, rx_ant); 756 + ret = local->ops->set_antenna(&local->hw, -1, tx_ant, rx_ant); 779 757 trace_drv_set_antenna(local, tx_ant, rx_ant, ret); 780 758 return ret; 781 759 } 782 760 783 - static inline int drv_get_antenna(struct ieee80211_local *local, 761 + static inline int drv_get_antenna(struct ieee80211_local *local, int radio_idx, 784 762 u32 *tx_ant, u32 *rx_ant) 785 763 { 786 764 int ret = -EOPNOTSUPP; 787 765 might_sleep(); 788 766 lockdep_assert_wiphy(local->hw.wiphy); 789 767 if (local->ops->get_antenna) 790 - ret = local->ops->get_antenna(&local->hw, tx_ant, rx_ant); 791 - trace_drv_get_antenna(local, *tx_ant, *rx_ant, ret); 768 + ret = local->ops->get_antenna(&local->hw, radio_idx, 769 + tx_ant, rx_ant); 770 + trace_drv_get_antenna(local, radio_idx, *tx_ant, *rx_ant, ret); 792 771 return ret; 793 772 } 794 773
+2 -2
net/mac80211/ibss.c
··· 635 635 rcu_read_lock(); 636 636 637 637 list_for_each_entry_rcu(sta, &local->sta_list, list) { 638 - unsigned long last_active = ieee80211_sta_last_active(sta); 638 + unsigned long last_active = ieee80211_sta_last_active(sta, -1); 639 639 640 640 if (sta->sdata == sdata && 641 641 time_is_after_jiffies(last_active + ··· 1228 1228 lockdep_assert_wiphy(local->hw.wiphy); 1229 1229 1230 1230 list_for_each_entry_safe(sta, tmp, &local->sta_list, list) { 1231 - unsigned long last_active = ieee80211_sta_last_active(sta); 1231 + unsigned long last_active = ieee80211_sta_last_active(sta, -1); 1232 1232 1233 1233 if (sdata != sta->sdata) 1234 1234 continue;
+11 -3
net/mac80211/ieee80211_i.h
··· 1872 1872 struct ieee80211_rx_status *status, 1873 1873 unsigned int mpdu_len, 1874 1874 unsigned int mpdu_offset); 1875 - int ieee80211_hw_config(struct ieee80211_local *local, u32 changed); 1875 + int ieee80211_hw_config(struct ieee80211_local *local, int radio_idx, 1876 + u32 changed); 1876 1877 int ieee80211_hw_conf_chan(struct ieee80211_local *local); 1877 1878 void ieee80211_hw_conf_init(struct ieee80211_local *local); 1878 1879 void ieee80211_tx_set_protected(struct ieee80211_tx_data *tx); ··· 2270 2269 struct sk_buff *skb); 2271 2270 void ieee80211_s1g_status_twt_action(struct ieee80211_sub_if_data *sdata, 2272 2271 struct sk_buff *skb); 2272 + void ieee80211_s1g_cap_to_sta_s1g_cap(struct ieee80211_sub_if_data *sdata, 2273 + const struct ieee80211_s1g_cap *s1g_cap_ie, 2274 + struct link_sta_info *link_sta); 2273 2275 2274 2276 /* Spectrum management */ 2275 2277 void ieee80211_process_measurement_req(struct ieee80211_sub_if_data *sdata, ··· 2546 2542 } 2547 2543 2548 2544 int ieee80211_txq_setup_flows(struct ieee80211_local *local); 2549 - void ieee80211_txq_set_params(struct ieee80211_local *local); 2545 + void ieee80211_txq_set_params(struct ieee80211_local *local, int radio_idx); 2550 2546 void ieee80211_txq_teardown_flows(struct ieee80211_local *local); 2551 2547 void ieee80211_txq_init(struct ieee80211_sub_if_data *sdata, 2552 2548 struct sta_info *sta, ··· 2716 2712 struct ieee80211_chanctx *ctx, 2717 2713 struct ieee80211_link_data *rsvd_for, 2718 2714 bool check_reserved); 2719 - bool ieee80211_is_radar_required(struct ieee80211_local *local); 2715 + bool ieee80211_is_radar_required(struct ieee80211_local *local, 2716 + struct cfg80211_scan_request *req); 2717 + bool ieee80211_is_radio_idx_in_scan_req(struct wiphy *wiphy, 2718 + struct cfg80211_scan_request *scan_req, 2719 + int radio_idx); 2720 2720 2721 2721 void ieee80211_dfs_cac_timer_work(struct wiphy *wiphy, struct wiphy_work *work); 2722 2722 void ieee80211_dfs_cac_cancel(struct ieee80211_local *local,
+3 -3
net/mac80211/iface.c
··· 146 146 { 147 147 u32 change = __ieee80211_recalc_idle(local, false); 148 148 if (change) 149 - ieee80211_hw_config(local, change); 149 + ieee80211_hw_config(local, -1, change); 150 150 } 151 151 152 152 static int ieee80211_verify_mac(struct ieee80211_sub_if_data *sdata, u8 *addr, ··· 726 726 727 727 /* do after stop to avoid reconfiguring when we stop anyway */ 728 728 ieee80211_configure_filter(local); 729 - ieee80211_hw_config(local, hw_reconf_flags); 729 + ieee80211_hw_config(local, -1, hw_reconf_flags); 730 730 731 731 if (local->virt_monitors == local->open_count) 732 732 ieee80211_add_virtual_monitor(local); ··· 1491 1491 if (local->open_count == 1) 1492 1492 ieee80211_hw_conf_init(local); 1493 1493 else if (hw_reconf_flags) 1494 - ieee80211_hw_config(local, hw_reconf_flags); 1494 + ieee80211_hw_config(local, -1, hw_reconf_flags); 1495 1495 1496 1496 ieee80211_recalc_ps(local); 1497 1497
+5 -4
net/mac80211/main.c
··· 190 190 return changed; 191 191 } 192 192 193 - int ieee80211_hw_config(struct ieee80211_local *local, u32 changed) 193 + int ieee80211_hw_config(struct ieee80211_local *local, int radio_idx, 194 + u32 changed) 194 195 { 195 196 int ret = 0; 196 197 ··· 202 201 IEEE80211_CONF_CHANGE_SMPS)); 203 202 204 203 if (changed && local->open_count) { 205 - ret = drv_config(local, changed); 204 + ret = drv_config(local, radio_idx, changed); 206 205 /* 207 206 * Goal: 208 207 * HW reconfiguration should never fail, the driver has told ··· 236 235 if (!changed) 237 236 return 0; 238 237 239 - return drv_config(local, changed); 238 + return drv_config(local, -1, changed); 240 239 } 241 240 242 241 int ieee80211_hw_conf_chan(struct ieee80211_local *local) ··· 270 269 ctx ? &ctx->conf : NULL); 271 270 } 272 271 273 - WARN_ON(drv_config(local, changed)); 272 + WARN_ON(drv_config(local, -1, changed)); 274 273 } 275 274 276 275 int ieee80211_emulate_add_chanctx(struct ieee80211_hw *hw,
+12 -6
net/mac80211/mlme.c
··· 3181 3181 return; 3182 3182 3183 3183 conf->flags |= IEEE80211_CONF_PS; 3184 - ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_PS); 3184 + ieee80211_hw_config(local, -1, IEEE80211_CONF_CHANGE_PS); 3185 3185 } 3186 3186 } 3187 3187 ··· 3193 3193 ieee80211_enable_ps(local, local->ps_sdata); 3194 3194 } else if (conf->flags & IEEE80211_CONF_PS) { 3195 3195 conf->flags &= ~IEEE80211_CONF_PS; 3196 - ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_PS); 3196 + ieee80211_hw_config(local, -1, IEEE80211_CONF_CHANGE_PS); 3197 3197 timer_delete_sync(&local->dynamic_ps_timer); 3198 3198 wiphy_work_cancel(local->hw.wiphy, 3199 3199 &local->dynamic_ps_enable_work); ··· 3302 3302 3303 3303 if (local->hw.conf.flags & IEEE80211_CONF_PS) { 3304 3304 local->hw.conf.flags &= ~IEEE80211_CONF_PS; 3305 - ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_PS); 3305 + ieee80211_hw_config(local, -1, IEEE80211_CONF_CHANGE_PS); 3306 3306 } 3307 3307 3308 3308 ieee80211_wake_queues_by_reason(&local->hw, ··· 3377 3377 (ifmgd->flags & IEEE80211_STA_NULLFUNC_ACKED)) { 3378 3378 ifmgd->flags &= ~IEEE80211_STA_NULLFUNC_ACKED; 3379 3379 local->hw.conf.flags |= IEEE80211_CONF_PS; 3380 - ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_PS); 3380 + ieee80211_hw_config(local, -1, IEEE80211_CONF_CHANGE_PS); 3381 3381 } 3382 3382 } 3383 3383 ··· 3986 3986 */ 3987 3987 if (local->hw.conf.flags & IEEE80211_CONF_PS) { 3988 3988 local->hw.conf.flags &= ~IEEE80211_CONF_PS; 3989 - ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_PS); 3989 + ieee80211_hw_config(local, -1, IEEE80211_CONF_CHANGE_PS); 3990 3990 } 3991 3991 local->ps_sdata = NULL; 3992 3992 ··· 5398 5398 bss_conf->eht_support = false; 5399 5399 bss_conf->epcs_support = false; 5400 5400 } 5401 + 5402 + if (elems->s1g_oper && 5403 + link->u.mgd.conn.mode == IEEE80211_CONN_MODE_S1G && 5404 + elems->s1g_capab) 5405 + ieee80211_s1g_cap_to_sta_s1g_cap(sdata, elems->s1g_capab, 5406 + link_sta); 5401 5407 5402 5408 bss_conf->twt_broadcast = 5403 5409 ieee80211_twt_bcast_support(sdata, bss_conf, sband, link_sta); ··· 7346 7340 if (local->hw.conf.dynamic_ps_timeout > 0) { 7347 7341 if (local->hw.conf.flags & IEEE80211_CONF_PS) { 7348 7342 local->hw.conf.flags &= ~IEEE80211_CONF_PS; 7349 - ieee80211_hw_config(local, 7343 + ieee80211_hw_config(local, -1, 7350 7344 IEEE80211_CONF_CHANGE_PS); 7351 7345 } 7352 7346 ieee80211_send_nullfunc(local, sdata, false);
+5 -2
net/mac80211/offchannel.c
··· 39 39 if (local->hw.conf.flags & IEEE80211_CONF_PS) { 40 40 offchannel_ps_enabled = true; 41 41 local->hw.conf.flags &= ~IEEE80211_CONF_PS; 42 - ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_PS); 42 + ieee80211_hw_config(local, -1, IEEE80211_CONF_CHANGE_PS); 43 43 } 44 44 45 45 if (!offchannel_ps_enabled || ··· 567 567 { 568 568 struct ieee80211_roc_work *roc, *tmp; 569 569 bool queued = false, combine_started = true; 570 + struct cfg80211_scan_request *req; 570 571 int ret; 571 572 572 573 lockdep_assert_wiphy(local->hw.wiphy); ··· 613 612 roc->mgmt_tx_cookie = *cookie; 614 613 } 615 614 615 + req = wiphy_dereference(local->hw.wiphy, local->scan_req); 616 + 616 617 /* if there's no need to queue, handle it immediately */ 617 618 if (list_empty(&local->roc_list) && 618 - !local->scanning && !ieee80211_is_radar_required(local)) { 619 + !local->scanning && !ieee80211_is_radar_required(local, req)) { 619 620 /* if not HW assist, just queue & schedule work */ 620 621 if (!local->ops->remain_on_channel) { 621 622 list_add_tail(&roc->list, &local->roc_list);
+1 -1
net/mac80211/pm.c
··· 108 108 sdata->u.mgd.powersave && 109 109 !(local->hw.conf.flags & IEEE80211_CONF_PS)) { 110 110 local->hw.conf.flags |= IEEE80211_CONF_PS; 111 - ieee80211_hw_config(local, 111 + ieee80211_hw_config(local, -1, 112 112 IEEE80211_CONF_CHANGE_PS); 113 113 } 114 114 }
+13 -2
net/mac80211/rx.c
··· 231 231 232 232 skb_queue_tail(&sdata->skb_queue, skb); 233 233 wiphy_work_queue(sdata->local->hw.wiphy, &sdata->work); 234 - if (sta) 235 - sta->deflink.rx_stats.packets++; 234 + if (sta) { 235 + struct link_sta_info *link_sta_info; 236 + 237 + if (link_id >= 0) { 238 + link_sta_info = rcu_dereference(sta->link[link_id]); 239 + if (!link_sta_info) 240 + return; 241 + } else { 242 + link_sta_info = &sta->deflink; 243 + } 244 + 245 + link_sta_info->rx_stats.packets++; 246 + } 236 247 } 237 248 238 249 static void ieee80211_queue_skb_to_iface(struct ieee80211_sub_if_data *sdata,
+26
net/mac80211/s1g.c
··· 194 194 break; 195 195 } 196 196 } 197 + 198 + void ieee80211_s1g_cap_to_sta_s1g_cap(struct ieee80211_sub_if_data *sdata, 199 + const struct ieee80211_s1g_cap *s1g_cap_ie, 200 + struct link_sta_info *link_sta) 201 + { 202 + struct ieee80211_sta_s1g_cap *s1g_cap = &link_sta->pub->s1g_cap; 203 + 204 + memset(s1g_cap, 0, sizeof(*s1g_cap)); 205 + 206 + memcpy(s1g_cap->cap, s1g_cap_ie->capab_info, sizeof(s1g_cap->cap)); 207 + memcpy(s1g_cap->nss_mcs, s1g_cap_ie->supp_mcs_nss, 208 + sizeof(s1g_cap->nss_mcs)); 209 + 210 + s1g_cap->s1g = true; 211 + 212 + /* Maximum MPDU length is 1 bit for S1G */ 213 + if (s1g_cap->cap[3] & S1G_CAP3_MAX_MPDU_LEN) { 214 + link_sta->pub->agg.max_amsdu_len = 215 + IEEE80211_MAX_MPDU_LEN_VHT_7991; 216 + } else { 217 + link_sta->pub->agg.max_amsdu_len = 218 + IEEE80211_MAX_MPDU_LEN_VHT_3895; 219 + } 220 + 221 + ieee80211_sta_recalc_aggregates(&link_sta->sta->sta); 222 + }
+13 -7
net/mac80211/scan.c
··· 586 586 return 0; 587 587 } 588 588 589 - static bool __ieee80211_can_leave_ch(struct ieee80211_sub_if_data *sdata) 589 + static bool __ieee80211_can_leave_ch(struct ieee80211_sub_if_data *sdata, 590 + struct cfg80211_scan_request *req) 590 591 { 591 592 struct ieee80211_local *local = sdata->local; 592 593 struct ieee80211_sub_if_data *sdata_iter; ··· 595 594 596 595 lockdep_assert_wiphy(local->hw.wiphy); 597 596 598 - if (!ieee80211_is_radar_required(local)) 597 + if (!ieee80211_is_radar_required(local, req)) 599 598 return true; 600 599 601 600 if (!regulatory_pre_cac_allowed(local->hw.wiphy)) ··· 611 610 } 612 611 613 612 static bool ieee80211_can_scan(struct ieee80211_local *local, 614 - struct ieee80211_sub_if_data *sdata) 613 + struct ieee80211_sub_if_data *sdata, 614 + struct cfg80211_scan_request *req) 615 615 { 616 - if (!__ieee80211_can_leave_ch(sdata)) 616 + if (!__ieee80211_can_leave_ch(sdata, req)) 617 617 return false; 618 618 619 619 if (!list_empty(&local->roc_list)) ··· 629 627 630 628 void ieee80211_run_deferred_scan(struct ieee80211_local *local) 631 629 { 630 + struct cfg80211_scan_request *req; 631 + 632 632 lockdep_assert_wiphy(local->hw.wiphy); 633 633 634 634 if (!local->scan_req || local->scanning) 635 635 return; 636 636 637 + req = wiphy_dereference(local->hw.wiphy, local->scan_req); 637 638 if (!ieee80211_can_scan(local, 638 639 rcu_dereference_protected( 639 640 local->scan_sdata, 640 - lockdep_is_held(&local->hw.wiphy->mtx)))) 641 + lockdep_is_held(&local->hw.wiphy->mtx)), 642 + req)) 641 643 return; 642 644 643 645 wiphy_delayed_work_queue(local->hw.wiphy, &local->scan_work, ··· 738 732 !(sdata->vif.active_links & BIT(req->tsf_report_link_id))) 739 733 return -EINVAL; 740 734 741 - if (!__ieee80211_can_leave_ch(sdata)) 735 + if (!__ieee80211_can_leave_ch(sdata, req)) 742 736 return -EBUSY; 743 737 744 - if (!ieee80211_can_scan(local, sdata)) { 738 + if (!ieee80211_can_scan(local, sdata, req)) { 745 739 /* wait for the work to finish/time out */ 746 740 rcu_assign_pointer(local->scan_req, req); 747 741 rcu_assign_pointer(local->scan_sdata, sdata);
+389 -28
net/mac80211/sta_info.c
··· 355 355 free_percpu(link_sta->pcpu_rx_stats); 356 356 } 357 357 358 + static void sta_accumulate_removed_link_stats(struct sta_info *sta, int link_id) 359 + { 360 + struct link_sta_info *link_sta = wiphy_dereference(sta->local->hw.wiphy, 361 + sta->link[link_id]); 362 + struct ieee80211_link_data *link; 363 + int ac, tid; 364 + u32 thr; 365 + 366 + for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) { 367 + sta->rem_link_stats.tx_packets += 368 + link_sta->tx_stats.packets[ac]; 369 + sta->rem_link_stats.tx_bytes += link_sta->tx_stats.bytes[ac]; 370 + } 371 + 372 + sta->rem_link_stats.rx_packets += link_sta->rx_stats.packets; 373 + sta->rem_link_stats.rx_bytes += link_sta->rx_stats.bytes; 374 + sta->rem_link_stats.tx_retries += link_sta->status_stats.retry_count; 375 + sta->rem_link_stats.tx_failed += link_sta->status_stats.retry_failed; 376 + sta->rem_link_stats.rx_dropped_misc += link_sta->rx_stats.dropped; 377 + 378 + thr = sta_get_expected_throughput(sta); 379 + if (thr != 0) 380 + sta->rem_link_stats.expected_throughput += thr; 381 + 382 + for (tid = 0; tid < IEEE80211_NUM_TIDS; tid++) { 383 + sta->rem_link_stats.pertid_stats.rx_msdu += 384 + link_sta->rx_stats.msdu[tid]; 385 + sta->rem_link_stats.pertid_stats.tx_msdu += 386 + link_sta->tx_stats.msdu[tid]; 387 + sta->rem_link_stats.pertid_stats.tx_msdu_retries += 388 + link_sta->status_stats.msdu_retries[tid]; 389 + sta->rem_link_stats.pertid_stats.tx_msdu_failed += 390 + link_sta->status_stats.msdu_failed[tid]; 391 + } 392 + 393 + if (sta->sdata->vif.type == NL80211_IFTYPE_STATION) { 394 + link = wiphy_dereference(sta->sdata->local->hw.wiphy, 395 + sta->sdata->link[link_id]); 396 + if (link) 397 + sta->rem_link_stats.beacon_loss_count += 398 + link->u.mgd.beacon_loss_count; 399 + } 400 + } 401 + 358 402 static void sta_remove_link(struct sta_info *sta, unsigned int link_id, 359 403 bool unhash) 360 404 { ··· 421 377 alloc = container_of(link_sta, typeof(*alloc), info); 422 378 423 379 sta->sta.valid_links &= ~BIT(link_id); 380 + 381 + /* store removed link info for accumulated stats consistency */ 382 + sta_accumulate_removed_link_stats(sta, link_id); 383 + 424 384 RCU_INIT_POINTER(sta->link[link_id], NULL); 425 385 RCU_INIT_POINTER(sta->sta.link[link_id], NULL); 426 386 if (alloc) { ··· 1699 1651 lockdep_assert_wiphy(local->hw.wiphy); 1700 1652 1701 1653 list_for_each_entry_safe(sta, tmp, &local->sta_list, list) { 1702 - unsigned long last_active = ieee80211_sta_last_active(sta); 1654 + unsigned long last_active = ieee80211_sta_last_active(sta, -1); 1703 1655 1704 1656 if (sdata != sta->sdata) 1705 1657 continue; ··· 2468 2420 } 2469 2421 2470 2422 static struct ieee80211_sta_rx_stats * 2471 - sta_get_last_rx_stats(struct sta_info *sta) 2423 + sta_get_last_rx_stats(struct sta_info *sta, int link_id) 2472 2424 { 2473 - struct ieee80211_sta_rx_stats *stats = &sta->deflink.rx_stats; 2425 + struct ieee80211_sta_rx_stats *stats; 2426 + struct link_sta_info *link_sta_info; 2474 2427 int cpu; 2475 2428 2476 - if (!sta->deflink.pcpu_rx_stats) 2429 + if (link_id < 0) 2430 + link_sta_info = &sta->deflink; 2431 + else 2432 + link_sta_info = wiphy_dereference(sta->local->hw.wiphy, 2433 + sta->link[link_id]); 2434 + 2435 + stats = &link_sta_info->rx_stats; 2436 + 2437 + if (!link_sta_info->pcpu_rx_stats) 2477 2438 return stats; 2478 2439 2479 2440 for_each_possible_cpu(cpu) { 2480 2441 struct ieee80211_sta_rx_stats *cpustats; 2481 2442 2482 - cpustats = per_cpu_ptr(sta->deflink.pcpu_rx_stats, cpu); 2443 + cpustats = per_cpu_ptr(link_sta_info->pcpu_rx_stats, cpu); 2483 2444 2484 2445 if (time_after(cpustats->last_rx, stats->last_rx)) 2485 2446 stats = cpustats; ··· 2556 2499 } 2557 2500 } 2558 2501 2559 - static int sta_set_rate_info_rx(struct sta_info *sta, struct rate_info *rinfo) 2502 + static int sta_set_rate_info_rx(struct sta_info *sta, struct rate_info *rinfo, 2503 + int link_id) 2560 2504 { 2561 - u32 rate = READ_ONCE(sta_get_last_rx_stats(sta)->last_rate); 2505 + u32 rate = READ_ONCE(sta_get_last_rx_stats(sta, link_id)->last_rate); 2562 2506 2563 2507 if (rate == STA_STATS_RATE_INVALID) 2564 2508 return -EINVAL; ··· 2584 2526 2585 2527 static void sta_set_tidstats(struct sta_info *sta, 2586 2528 struct cfg80211_tid_stats *tidstats, 2587 - int tid) 2529 + int tid, int link_id) 2588 2530 { 2589 2531 struct ieee80211_local *local = sta->local; 2532 + struct link_sta_info *link_sta_info; 2590 2533 int cpu; 2591 2534 2592 - if (!(tidstats->filled & BIT(NL80211_TID_STATS_RX_MSDU))) { 2593 - tidstats->rx_msdu += sta_get_tidstats_msdu(&sta->deflink.rx_stats, 2594 - tid); 2535 + if (link_id < 0) 2536 + link_sta_info = &sta->deflink; 2537 + else 2538 + link_sta_info = wiphy_dereference(sta->local->hw.wiphy, 2539 + sta->link[link_id]); 2595 2540 2596 - if (sta->deflink.pcpu_rx_stats) { 2541 + if (!(tidstats->filled & BIT(NL80211_TID_STATS_RX_MSDU))) { 2542 + tidstats->rx_msdu += 2543 + sta_get_tidstats_msdu(&link_sta_info->rx_stats, 2544 + tid); 2545 + 2546 + if (link_sta_info->pcpu_rx_stats) { 2597 2547 for_each_possible_cpu(cpu) { 2598 2548 struct ieee80211_sta_rx_stats *cpurxs; 2599 2549 2600 - cpurxs = per_cpu_ptr(sta->deflink.pcpu_rx_stats, 2550 + cpurxs = per_cpu_ptr(link_sta_info->pcpu_rx_stats, 2601 2551 cpu); 2602 2552 tidstats->rx_msdu += 2603 2553 sta_get_tidstats_msdu(cpurxs, tid); ··· 2617 2551 2618 2552 if (!(tidstats->filled & BIT(NL80211_TID_STATS_TX_MSDU))) { 2619 2553 tidstats->filled |= BIT(NL80211_TID_STATS_TX_MSDU); 2620 - tidstats->tx_msdu = sta->deflink.tx_stats.msdu[tid]; 2554 + tidstats->tx_msdu = link_sta_info->tx_stats.msdu[tid]; 2621 2555 } 2622 2556 2623 2557 if (!(tidstats->filled & BIT(NL80211_TID_STATS_TX_MSDU_RETRIES)) && 2624 2558 ieee80211_hw_check(&local->hw, REPORTS_TX_ACK_STATUS)) { 2625 2559 tidstats->filled |= BIT(NL80211_TID_STATS_TX_MSDU_RETRIES); 2626 - tidstats->tx_msdu_retries = sta->deflink.status_stats.msdu_retries[tid]; 2560 + tidstats->tx_msdu_retries = 2561 + link_sta_info->status_stats.msdu_retries[tid]; 2627 2562 } 2628 2563 2629 2564 if (!(tidstats->filled & BIT(NL80211_TID_STATS_TX_MSDU_FAILED)) && 2630 2565 ieee80211_hw_check(&local->hw, REPORTS_TX_ACK_STATUS)) { 2631 2566 tidstats->filled |= BIT(NL80211_TID_STATS_TX_MSDU_FAILED); 2632 - tidstats->tx_msdu_failed = sta->deflink.status_stats.msdu_failed[tid]; 2567 + tidstats->tx_msdu_failed = 2568 + link_sta_info->status_stats.msdu_failed[tid]; 2633 2569 } 2634 2570 2635 - if (tid < IEEE80211_NUM_TIDS) { 2571 + if (link_id < 0 && tid < IEEE80211_NUM_TIDS) { 2636 2572 spin_lock_bh(&local->fq.lock); 2637 2573 rcu_read_lock(); 2638 2574 ··· 2693 2625 } 2694 2626 #endif 2695 2627 2628 + void sta_set_accumulated_removed_links_sinfo(struct sta_info *sta, 2629 + struct station_info *sinfo) 2630 + { 2631 + /* Accumulating the removed link statistics. */ 2632 + sinfo->tx_packets = sta->rem_link_stats.tx_packets; 2633 + sinfo->rx_packets = sta->rem_link_stats.rx_packets; 2634 + sinfo->tx_bytes = sta->rem_link_stats.tx_bytes; 2635 + sinfo->rx_bytes = sta->rem_link_stats.rx_bytes; 2636 + sinfo->tx_retries = sta->rem_link_stats.tx_retries; 2637 + sinfo->tx_failed = sta->rem_link_stats.tx_failed; 2638 + sinfo->rx_dropped_misc = sta->rem_link_stats.rx_dropped_misc; 2639 + sinfo->beacon_loss_count = sta->rem_link_stats.beacon_loss_count; 2640 + sinfo->expected_throughput = sta->rem_link_stats.expected_throughput; 2641 + 2642 + if (sinfo->pertid) { 2643 + sinfo->pertid->rx_msdu = 2644 + sta->rem_link_stats.pertid_stats.rx_msdu; 2645 + sinfo->pertid->tx_msdu = 2646 + sta->rem_link_stats.pertid_stats.tx_msdu; 2647 + sinfo->pertid->tx_msdu_retries = 2648 + sta->rem_link_stats.pertid_stats.tx_msdu_retries; 2649 + sinfo->pertid->tx_msdu_failed = 2650 + sta->rem_link_stats.pertid_stats.tx_msdu_failed; 2651 + } 2652 + } 2653 + 2654 + static void sta_set_link_sinfo(struct sta_info *sta, 2655 + struct link_station_info *link_sinfo, 2656 + struct ieee80211_link_data *link, 2657 + bool tidstats) 2658 + { 2659 + struct ieee80211_sub_if_data *sdata = sta->sdata; 2660 + struct ieee80211_sta_rx_stats *last_rxstats; 2661 + int i, ac, cpu, link_id = link->link_id; 2662 + struct link_sta_info *link_sta_info; 2663 + u32 thr = 0; 2664 + 2665 + last_rxstats = sta_get_last_rx_stats(sta, link_id); 2666 + 2667 + link_sta_info = wiphy_dereference(sta->local->hw.wiphy, 2668 + sta->link[link_id]); 2669 + 2670 + /* do before driver, so beacon filtering drivers have a 2671 + * chance to e.g. just add the number of filtered beacons 2672 + * (or just modify the value entirely, of course) 2673 + */ 2674 + if (sdata->vif.type == NL80211_IFTYPE_STATION) 2675 + link_sinfo->rx_beacon = link->u.mgd.count_beacon_signal; 2676 + 2677 + ether_addr_copy(link_sinfo->addr, link_sta_info->addr); 2678 + 2679 + drv_link_sta_statistics(sta->local, sdata, 2680 + link_sta_info->pub, 2681 + link_sinfo); 2682 + 2683 + link_sinfo->filled |= BIT_ULL(NL80211_STA_INFO_INACTIVE_TIME) | 2684 + BIT_ULL(NL80211_STA_INFO_BSS_PARAM) | 2685 + BIT_ULL(NL80211_STA_INFO_RX_DROP_MISC); 2686 + 2687 + if (sdata->vif.type == NL80211_IFTYPE_STATION) { 2688 + link_sinfo->beacon_loss_count = 2689 + link->u.mgd.beacon_loss_count; 2690 + link_sinfo->filled |= BIT_ULL(NL80211_STA_INFO_BEACON_LOSS); 2691 + } 2692 + 2693 + link_sinfo->inactive_time = 2694 + jiffies_to_msecs(jiffies - ieee80211_sta_last_active(sta, link_id)); 2695 + 2696 + if (!(link_sinfo->filled & (BIT_ULL(NL80211_STA_INFO_TX_BYTES64) | 2697 + BIT_ULL(NL80211_STA_INFO_TX_BYTES)))) { 2698 + link_sinfo->tx_bytes = 0; 2699 + for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) 2700 + link_sinfo->tx_bytes += 2701 + link_sta_info->tx_stats.bytes[ac]; 2702 + link_sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_BYTES64); 2703 + } 2704 + 2705 + if (!(link_sinfo->filled & BIT_ULL(NL80211_STA_INFO_TX_PACKETS))) { 2706 + link_sinfo->tx_packets = 0; 2707 + for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) 2708 + link_sinfo->tx_packets += 2709 + link_sta_info->tx_stats.packets[ac]; 2710 + link_sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_PACKETS); 2711 + } 2712 + 2713 + if (!(link_sinfo->filled & (BIT_ULL(NL80211_STA_INFO_RX_BYTES64) | 2714 + BIT_ULL(NL80211_STA_INFO_RX_BYTES)))) { 2715 + link_sinfo->rx_bytes += 2716 + sta_get_stats_bytes(&link_sta_info->rx_stats); 2717 + 2718 + if (link_sta_info->pcpu_rx_stats) { 2719 + for_each_possible_cpu(cpu) { 2720 + struct ieee80211_sta_rx_stats *cpurxs; 2721 + 2722 + cpurxs = per_cpu_ptr(link_sta_info->pcpu_rx_stats, 2723 + cpu); 2724 + link_sinfo->rx_bytes += 2725 + sta_get_stats_bytes(cpurxs); 2726 + } 2727 + } 2728 + 2729 + link_sinfo->filled |= BIT_ULL(NL80211_STA_INFO_RX_BYTES64); 2730 + } 2731 + 2732 + if (!(link_sinfo->filled & BIT_ULL(NL80211_STA_INFO_RX_PACKETS))) { 2733 + link_sinfo->rx_packets = link_sta_info->rx_stats.packets; 2734 + if (link_sta_info->pcpu_rx_stats) { 2735 + for_each_possible_cpu(cpu) { 2736 + struct ieee80211_sta_rx_stats *cpurxs; 2737 + 2738 + cpurxs = per_cpu_ptr(link_sta_info->pcpu_rx_stats, 2739 + cpu); 2740 + link_sinfo->rx_packets += cpurxs->packets; 2741 + } 2742 + } 2743 + link_sinfo->filled |= BIT_ULL(NL80211_STA_INFO_RX_PACKETS); 2744 + } 2745 + 2746 + if (!(link_sinfo->filled & BIT_ULL(NL80211_STA_INFO_TX_RETRIES))) { 2747 + link_sinfo->tx_retries = 2748 + link_sta_info->status_stats.retry_count; 2749 + link_sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_RETRIES); 2750 + } 2751 + 2752 + if (!(link_sinfo->filled & BIT_ULL(NL80211_STA_INFO_TX_FAILED))) { 2753 + link_sinfo->tx_failed = 2754 + link_sta_info->status_stats.retry_failed; 2755 + link_sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_FAILED); 2756 + } 2757 + 2758 + if (!(link_sinfo->filled & BIT_ULL(NL80211_STA_INFO_RX_DURATION))) { 2759 + for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) 2760 + link_sinfo->rx_duration += sta->airtime[ac].rx_airtime; 2761 + link_sinfo->filled |= BIT_ULL(NL80211_STA_INFO_RX_DURATION); 2762 + } 2763 + 2764 + if (!(link_sinfo->filled & BIT_ULL(NL80211_STA_INFO_TX_DURATION))) { 2765 + for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) 2766 + link_sinfo->tx_duration += sta->airtime[ac].tx_airtime; 2767 + link_sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_DURATION); 2768 + } 2769 + 2770 + if (!(link_sinfo->filled & BIT_ULL(NL80211_STA_INFO_AIRTIME_WEIGHT))) { 2771 + link_sinfo->airtime_weight = sta->airtime_weight; 2772 + link_sinfo->filled |= BIT_ULL(NL80211_STA_INFO_AIRTIME_WEIGHT); 2773 + } 2774 + 2775 + link_sinfo->rx_dropped_misc = link_sta_info->rx_stats.dropped; 2776 + if (link_sta_info->pcpu_rx_stats) { 2777 + for_each_possible_cpu(cpu) { 2778 + struct ieee80211_sta_rx_stats *cpurxs; 2779 + 2780 + cpurxs = per_cpu_ptr(link_sta_info->pcpu_rx_stats, 2781 + cpu); 2782 + link_sinfo->rx_dropped_misc += cpurxs->dropped; 2783 + } 2784 + } 2785 + 2786 + if (sdata->vif.type == NL80211_IFTYPE_STATION && 2787 + !(sdata->vif.driver_flags & IEEE80211_VIF_BEACON_FILTER)) { 2788 + link_sinfo->filled |= BIT_ULL(NL80211_STA_INFO_BEACON_RX) | 2789 + BIT_ULL(NL80211_STA_INFO_BEACON_SIGNAL_AVG); 2790 + link_sinfo->rx_beacon_signal_avg = 2791 + ieee80211_ave_rssi(&sdata->vif, -1); 2792 + } 2793 + 2794 + if (ieee80211_hw_check(&sta->local->hw, SIGNAL_DBM) || 2795 + ieee80211_hw_check(&sta->local->hw, SIGNAL_UNSPEC)) { 2796 + if (!(link_sinfo->filled & BIT_ULL(NL80211_STA_INFO_SIGNAL))) { 2797 + link_sinfo->signal = (s8)last_rxstats->last_signal; 2798 + link_sinfo->filled |= BIT_ULL(NL80211_STA_INFO_SIGNAL); 2799 + } 2800 + 2801 + if (!link_sta_info->pcpu_rx_stats && 2802 + !(link_sinfo->filled & 2803 + BIT_ULL(NL80211_STA_INFO_SIGNAL_AVG))) { 2804 + link_sinfo->signal_avg = 2805 + -ewma_signal_read(&link_sta_info->rx_stats_avg.signal); 2806 + link_sinfo->filled |= 2807 + BIT_ULL(NL80211_STA_INFO_SIGNAL_AVG); 2808 + } 2809 + } 2810 + 2811 + /* for the average - if pcpu_rx_stats isn't set - rxstats must point to 2812 + * the sta->rx_stats struct, so the check here is fine with and without 2813 + * pcpu statistics 2814 + */ 2815 + if (last_rxstats->chains && 2816 + !(link_sinfo->filled & (BIT_ULL(NL80211_STA_INFO_CHAIN_SIGNAL) | 2817 + BIT_ULL(NL80211_STA_INFO_CHAIN_SIGNAL_AVG)))) { 2818 + link_sinfo->filled |= BIT_ULL(NL80211_STA_INFO_CHAIN_SIGNAL); 2819 + if (!link_sta_info->pcpu_rx_stats) 2820 + link_sinfo->filled |= 2821 + BIT_ULL(NL80211_STA_INFO_CHAIN_SIGNAL_AVG); 2822 + 2823 + link_sinfo->chains = last_rxstats->chains; 2824 + 2825 + for (i = 0; i < ARRAY_SIZE(link_sinfo->chain_signal); i++) { 2826 + link_sinfo->chain_signal[i] = 2827 + last_rxstats->chain_signal_last[i]; 2828 + link_sinfo->chain_signal_avg[i] = 2829 + -ewma_signal_read( 2830 + &link_sta_info->rx_stats_avg.chain_signal[i]); 2831 + } 2832 + } 2833 + 2834 + if (!(link_sinfo->filled & BIT_ULL(NL80211_STA_INFO_TX_BITRATE)) && 2835 + ieee80211_rate_valid(&link_sta_info->tx_stats.last_rate)) { 2836 + sta_set_rate_info_tx(sta, &link_sta_info->tx_stats.last_rate, 2837 + &link_sinfo->txrate); 2838 + link_sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_BITRATE); 2839 + } 2840 + 2841 + if (!(link_sinfo->filled & BIT_ULL(NL80211_STA_INFO_RX_BITRATE))) { 2842 + if (sta_set_rate_info_rx(sta, &link_sinfo->rxrate, 2843 + link_id) == 0) 2844 + link_sinfo->filled |= 2845 + BIT_ULL(NL80211_STA_INFO_RX_BITRATE); 2846 + } 2847 + 2848 + if (tidstats && !cfg80211_link_sinfo_alloc_tid_stats(link_sinfo, 2849 + GFP_KERNEL)) { 2850 + for (i = 0; i < IEEE80211_NUM_TIDS + 1; i++) 2851 + sta_set_tidstats(sta, &link_sinfo->pertid[i], i, 2852 + link_id); 2853 + } 2854 + 2855 + link_sinfo->bss_param.flags = 0; 2856 + if (sdata->vif.bss_conf.use_cts_prot) 2857 + link_sinfo->bss_param.flags |= BSS_PARAM_FLAGS_CTS_PROT; 2858 + if (sdata->vif.bss_conf.use_short_preamble) 2859 + link_sinfo->bss_param.flags |= BSS_PARAM_FLAGS_SHORT_PREAMBLE; 2860 + if (sdata->vif.bss_conf.use_short_slot) 2861 + link_sinfo->bss_param.flags |= BSS_PARAM_FLAGS_SHORT_SLOT_TIME; 2862 + link_sinfo->bss_param.dtim_period = link->conf->dtim_period; 2863 + link_sinfo->bss_param.beacon_interval = link->conf->beacon_int; 2864 + 2865 + thr = sta_get_expected_throughput(sta); 2866 + 2867 + if (thr != 0) { 2868 + link_sinfo->filled |= 2869 + BIT_ULL(NL80211_STA_INFO_EXPECTED_THROUGHPUT); 2870 + link_sinfo->expected_throughput = thr; 2871 + } 2872 + 2873 + if (!(link_sinfo->filled & BIT_ULL(NL80211_STA_INFO_ACK_SIGNAL)) && 2874 + link_sta_info->status_stats.ack_signal_filled) { 2875 + link_sinfo->ack_signal = 2876 + link_sta_info->status_stats.last_ack_signal; 2877 + link_sinfo->filled |= BIT_ULL(NL80211_STA_INFO_ACK_SIGNAL); 2878 + } 2879 + 2880 + if (!(link_sinfo->filled & BIT_ULL(NL80211_STA_INFO_ACK_SIGNAL_AVG)) && 2881 + link_sta_info->status_stats.ack_signal_filled) { 2882 + link_sinfo->avg_ack_signal = 2883 + -(s8)ewma_avg_signal_read( 2884 + &link_sta_info->status_stats.avg_ack_signal); 2885 + link_sinfo->filled |= 2886 + BIT_ULL(NL80211_STA_INFO_ACK_SIGNAL_AVG); 2887 + } 2888 + } 2889 + 2696 2890 void sta_set_sinfo(struct sta_info *sta, struct station_info *sinfo, 2697 2891 bool tidstats) 2698 2892 { 2699 2893 struct ieee80211_sub_if_data *sdata = sta->sdata; 2700 2894 struct ieee80211_local *local = sdata->local; 2701 2895 u32 thr = 0; 2702 - int i, ac, cpu; 2896 + int i, ac, cpu, link_id; 2703 2897 struct ieee80211_sta_rx_stats *last_rxstats; 2704 2898 2705 - last_rxstats = sta_get_last_rx_stats(sta); 2899 + last_rxstats = sta_get_last_rx_stats(sta, -1); 2706 2900 2707 2901 sinfo->generation = sdata->local->sta_generation; 2708 2902 ··· 2992 2662 sinfo->connected_time = ktime_get_seconds() - sta->last_connected; 2993 2663 sinfo->assoc_at = sta->assoc_at; 2994 2664 sinfo->inactive_time = 2995 - jiffies_to_msecs(jiffies - ieee80211_sta_last_active(sta)); 2665 + jiffies_to_msecs(jiffies - ieee80211_sta_last_active(sta, -1)); 2996 2666 2997 2667 if (!(sinfo->filled & (BIT_ULL(NL80211_STA_INFO_TX_BYTES64) | 2998 2668 BIT_ULL(NL80211_STA_INFO_TX_BYTES)))) { ··· 3081 2751 !(sdata->vif.driver_flags & IEEE80211_VIF_BEACON_FILTER)) { 3082 2752 sinfo->filled |= BIT_ULL(NL80211_STA_INFO_BEACON_RX) | 3083 2753 BIT_ULL(NL80211_STA_INFO_BEACON_SIGNAL_AVG); 3084 - sinfo->rx_beacon_signal_avg = ieee80211_ave_rssi(&sdata->vif); 2754 + sinfo->rx_beacon_signal_avg = 2755 + ieee80211_ave_rssi(&sdata->vif, -1); 3085 2756 } 3086 2757 3087 2758 if (ieee80211_hw_check(&sta->local->hw, SIGNAL_DBM) || ··· 3131 2800 3132 2801 if (!(sinfo->filled & BIT_ULL(NL80211_STA_INFO_RX_BITRATE)) && 3133 2802 !sta->sta.valid_links) { 3134 - if (sta_set_rate_info_rx(sta, &sinfo->rxrate) == 0) 2803 + if (sta_set_rate_info_rx(sta, &sinfo->rxrate, -1) == 0) 3135 2804 sinfo->filled |= BIT_ULL(NL80211_STA_INFO_RX_BITRATE); 3136 2805 } 3137 2806 3138 2807 if (tidstats && !cfg80211_sinfo_alloc_tid_stats(sinfo, GFP_KERNEL)) { 3139 2808 for (i = 0; i < IEEE80211_NUM_TIDS + 1; i++) 3140 - sta_set_tidstats(sta, &sinfo->pertid[i], i); 2809 + sta_set_tidstats(sta, &sinfo->pertid[i], i, -1); 3141 2810 } 3142 2811 3143 2812 #ifdef CONFIG_MAC80211_MESH ··· 3199 2868 sinfo->filled |= 3200 2869 BIT_ULL(NL80211_STA_INFO_ACK_SIGNAL_AVG); 3201 2870 } 2871 + 2872 + if (sta->sta.valid_links) { 2873 + struct ieee80211_link_data *link; 2874 + struct link_sta_info *link_sta; 2875 + 2876 + ether_addr_copy(sinfo->mld_addr, sta->addr); 2877 + for_each_valid_link(sinfo, link_id) { 2878 + link_sta = wiphy_dereference(sta->local->hw.wiphy, 2879 + sta->link[link_id]); 2880 + link = wiphy_dereference(sdata->local->hw.wiphy, 2881 + sdata->link[link_id]); 2882 + 2883 + if (!link_sta || !sinfo->links[link_id] || !link) 2884 + continue; 2885 + 2886 + sinfo->valid_links = sta->sta.valid_links; 2887 + sta_set_link_sinfo(sta, sinfo->links[link_id], 2888 + link, tidstats); 2889 + } 2890 + } 3202 2891 } 3203 2892 3204 2893 u32 sta_get_expected_throughput(struct sta_info *sta) ··· 3240 2889 return thr; 3241 2890 } 3242 2891 3243 - unsigned long ieee80211_sta_last_active(struct sta_info *sta) 2892 + unsigned long ieee80211_sta_last_active(struct sta_info *sta, int link_id) 3244 2893 { 3245 - struct ieee80211_sta_rx_stats *stats = sta_get_last_rx_stats(sta); 2894 + struct ieee80211_sta_rx_stats *stats; 2895 + struct link_sta_info *link_sta_info; 3246 2896 3247 - if (!sta->deflink.status_stats.last_ack || 3248 - time_after(stats->last_rx, sta->deflink.status_stats.last_ack)) 2897 + stats = sta_get_last_rx_stats(sta, link_id); 2898 + 2899 + if (link_id < 0) 2900 + link_sta_info = &sta->deflink; 2901 + else 2902 + link_sta_info = wiphy_dereference(sta->local->hw.wiphy, 2903 + sta->link[link_id]); 2904 + 2905 + if (!link_sta_info->status_stats.last_ack || 2906 + time_after(stats->last_rx, link_sta_info->status_stats.last_ack)) 3249 2907 return stats->last_rx; 3250 - return sta->deflink.status_stats.last_ack; 2908 + 2909 + return link_sta_info->status_stats.last_ack; 3251 2910 } 3252 2911 3253 2912 int ieee80211_sta_allocate_link(struct sta_info *sta, unsigned int link_id)
+58 -1
net/mac80211/sta_info.h
··· 569 569 }; 570 570 571 571 /** 572 + * struct ieee80211_sta_removed_link_stats - Removed link sta data 573 + * 574 + * keep required accumulated removed link data for stats 575 + * 576 + * @rx_packets: accumulated packets (MSDUs & MMPDUs) received from 577 + * this station for removed links 578 + * @tx_packets: accumulated packets (MSDUs & MMPDUs) transmitted to 579 + * this station for removed links 580 + * @rx_bytes: accumulated bytes (size of MPDUs) received from this 581 + * station for removed links 582 + * @tx_bytes: accumulated bytes (size of MPDUs) transmitted to this 583 + * station for removed links 584 + * @tx_retries: cumulative retry counts (MPDUs) for removed links 585 + * @tx_failed: accumulated number of failed transmissions (MPDUs) 586 + * (retries exceeded, no ACK) for removed links 587 + * @rx_dropped_misc: accumulated dropped packets for un-specified reason 588 + * from this station for removed links 589 + * @beacon_loss_count: Number of times beacon loss event has triggered 590 + * from this station for removed links. 591 + * @expected_throughput: expected throughput in kbps (including 802.11 592 + * headers) towards this station for removed links 593 + * @pertid_stats: accumulated per-TID statistics for removed link of 594 + * station 595 + * @pertid_stats.rx_msdu : accumulated number of received MSDUs towards 596 + * this station for removed links. 597 + * @pertid_stats.tx_msdu: accumulated number of (attempted) transmitted 598 + * MSDUs towards this station for removed links 599 + * @pertid_stats.tx_msdu_retries: accumulated number of retries (not 600 + * counting the first) for transmitted MSDUs towards this station 601 + * for removed links 602 + * @pertid_stats.tx_msdu_failed: accumulated number of failed transmitted 603 + * MSDUs towards this station for removed links 604 + */ 605 + struct ieee80211_sta_removed_link_stats { 606 + u32 rx_packets; 607 + u32 tx_packets; 608 + u64 rx_bytes; 609 + u64 tx_bytes; 610 + u32 tx_retries; 611 + u32 tx_failed; 612 + u32 rx_dropped_misc; 613 + u32 beacon_loss_count; 614 + u32 expected_throughput; 615 + struct { 616 + u64 rx_msdu; 617 + u64 tx_msdu; 618 + u64 tx_msdu_retries; 619 + u64 tx_msdu_failed; 620 + } pertid_stats; 621 + }; 622 + 623 + /** 572 624 * struct sta_info - STA information 573 625 * 574 626 * This structure collects information about a station that ··· 696 644 * @deflink address and remaining would be allocated and the address 697 645 * would be assigned to link[link_id] where link_id is the id assigned 698 646 * by the AP. 647 + * @rem_link_stats: accumulated removed link stats 699 648 */ 700 649 struct sta_info { 701 650 /* General information, mostly static */ ··· 771 718 struct ieee80211_sta_aggregates cur; 772 719 struct link_sta_info deflink; 773 720 struct link_sta_info __rcu *link[IEEE80211_MLD_MAX_NUM_LINKS]; 721 + struct ieee80211_sta_removed_link_stats rem_link_stats; 774 722 775 723 /* keep last! */ 776 724 struct ieee80211_sta sta; ··· 976 922 void sta_set_sinfo(struct sta_info *sta, struct station_info *sinfo, 977 923 bool tidstats); 978 924 925 + void sta_set_accumulated_removed_links_sinfo(struct sta_info *sta, 926 + struct station_info *sinfo); 927 + 979 928 u32 sta_get_expected_throughput(struct sta_info *sta); 980 929 981 930 void ieee80211_sta_expire(struct ieee80211_sub_if_data *sdata, ··· 993 936 void ieee80211_sta_ps_deliver_poll_response(struct sta_info *sta); 994 937 void ieee80211_sta_ps_deliver_uapsd(struct sta_info *sta); 995 938 996 - unsigned long ieee80211_sta_last_active(struct sta_info *sta); 939 + unsigned long ieee80211_sta_last_active(struct sta_info *sta, int link_id); 997 940 998 941 void ieee80211_sta_set_max_amsdu_subframes(struct sta_info *sta, 999 942 const u8 *ext_capab,
+93 -22
net/mac80211/trace.h
··· 384 384 385 385 TRACE_EVENT(drv_config, 386 386 TP_PROTO(struct ieee80211_local *local, 387 + int radio_idx, 387 388 u32 changed), 388 389 389 - TP_ARGS(local, changed), 390 + TP_ARGS(local, radio_idx, changed), 390 391 391 392 TP_STRUCT__entry( 392 393 LOCAL_ENTRY 394 + __field(int, radio_idx) 393 395 __field(u32, changed) 394 396 __field(u32, flags) 395 397 __field(int, power_level) ··· 405 403 406 404 TP_fast_assign( 407 405 LOCAL_ASSIGN; 406 + __entry->radio_idx = radio_idx; 408 407 __entry->changed = changed; 409 408 __entry->flags = local->hw.conf.flags; 410 409 __entry->power_level = local->hw.conf.power_level; ··· 420 417 ), 421 418 422 419 TP_printk( 423 - LOCAL_PR_FMT " ch:%#x" CHANDEF_PR_FMT, 424 - LOCAL_PR_ARG, __entry->changed, CHANDEF_PR_ARG 420 + LOCAL_PR_FMT " radio_idx:%d ch:%#x" CHANDEF_PR_FMT, 421 + LOCAL_PR_ARG, __entry->radio_idx, __entry->changed, CHANDEF_PR_ARG 425 422 ) 426 423 ); 427 424 ··· 821 818 ) 822 819 ); 823 820 824 - DEFINE_EVENT(local_u32_evt, drv_set_frag_threshold, 825 - TP_PROTO(struct ieee80211_local *local, u32 value), 826 - TP_ARGS(local, value) 827 - ); 821 + TRACE_EVENT(drv_set_frag_threshold, 822 + TP_PROTO(struct ieee80211_local *local, int radio_idx, u32 value), 828 823 829 - DEFINE_EVENT(local_u32_evt, drv_set_rts_threshold, 830 - TP_PROTO(struct ieee80211_local *local, u32 value), 831 - TP_ARGS(local, value) 832 - ); 833 - 834 - TRACE_EVENT(drv_set_coverage_class, 835 - TP_PROTO(struct ieee80211_local *local, s16 value), 836 - 837 - TP_ARGS(local, value), 824 + TP_ARGS(local, radio_idx, value), 838 825 839 826 TP_STRUCT__entry( 840 827 LOCAL_ENTRY 828 + __field(int, radio_idx) 829 + __field(u32, value) 830 + ), 831 + 832 + TP_fast_assign( 833 + LOCAL_ASSIGN; 834 + __entry->radio_idx = radio_idx; 835 + __entry->value = value; 836 + ), 837 + 838 + TP_printk( 839 + LOCAL_PR_FMT " radio_id:%d value:%u", 840 + LOCAL_PR_ARG, __entry->radio_idx, __entry->value 841 + ) 842 + ); 843 + 844 + TRACE_EVENT(drv_set_rts_threshold, 845 + TP_PROTO(struct ieee80211_local *local, int radio_idx, u32 value), 846 + 847 + TP_ARGS(local, radio_idx, value), 848 + 849 + TP_STRUCT__entry( 850 + LOCAL_ENTRY 851 + __field(int, radio_idx) 852 + __field(u32, value) 853 + ), 854 + TP_fast_assign( 855 + LOCAL_ASSIGN; 856 + __entry->radio_idx = radio_idx; 857 + __entry->value = value; 858 + ), 859 + 860 + TP_printk( 861 + LOCAL_PR_FMT " radio_id:%d value:%u", 862 + LOCAL_PR_ARG, __entry->radio_idx, __entry->value 863 + ) 864 + ); 865 + 866 + TRACE_EVENT(drv_set_coverage_class, 867 + TP_PROTO(struct ieee80211_local *local, int radio_idx, s16 value), 868 + 869 + TP_ARGS(local, radio_idx, value), 870 + 871 + TP_STRUCT__entry( 872 + LOCAL_ENTRY 873 + __field(int, radio_idx) 841 874 __field(s16, value) 842 875 ), 843 876 844 877 TP_fast_assign( 845 878 LOCAL_ASSIGN; 879 + __entry->radio_idx = radio_idx; 846 880 __entry->value = value; 847 881 ), 848 882 849 883 TP_printk( 850 - LOCAL_PR_FMT " value:%d", 851 - LOCAL_PR_ARG, __entry->value 884 + LOCAL_PR_FMT " radio_id:%d value:%d", 885 + LOCAL_PR_ARG, __entry->radio_idx, __entry->value 852 886 ) 853 887 ); 854 888 ··· 1040 1000 struct ieee80211_sub_if_data *sdata, 1041 1001 struct ieee80211_sta *sta), 1042 1002 TP_ARGS(local, sdata, sta) 1003 + ); 1004 + 1005 + TRACE_EVENT(drv_link_sta_statistics, 1006 + TP_PROTO(struct ieee80211_local *local, 1007 + struct ieee80211_sub_if_data *sdata, 1008 + struct ieee80211_link_sta *link_sta), 1009 + 1010 + TP_ARGS(local, sdata, link_sta), 1011 + 1012 + TP_STRUCT__entry( 1013 + LOCAL_ENTRY 1014 + VIF_ENTRY 1015 + STA_ENTRY 1016 + __field(u32, link_id) 1017 + ), 1018 + 1019 + TP_fast_assign( 1020 + LOCAL_ASSIGN; 1021 + VIF_ASSIGN; 1022 + STA_NAMED_ASSIGN(link_sta->sta); 1023 + __entry->link_id = link_sta->link_id; 1024 + ), 1025 + 1026 + TP_printk( 1027 + LOCAL_PR_FMT VIF_PR_FMT STA_PR_FMT " (link %d)", 1028 + LOCAL_PR_ARG, VIF_PR_ARG, STA_PR_ARG, __entry->link_id 1029 + ) 1043 1030 ); 1044 1031 1045 1032 DEFINE_EVENT(sta_event, drv_sta_add, ··· 1358 1291 ); 1359 1292 1360 1293 TRACE_EVENT(drv_get_antenna, 1361 - TP_PROTO(struct ieee80211_local *local, u32 tx_ant, u32 rx_ant, int ret), 1294 + TP_PROTO(struct ieee80211_local *local, int radio_idx, u32 tx_ant, 1295 + u32 rx_ant, int ret), 1362 1296 1363 - TP_ARGS(local, tx_ant, rx_ant, ret), 1297 + TP_ARGS(local, radio_idx, tx_ant, rx_ant, ret), 1364 1298 1365 1299 TP_STRUCT__entry( 1366 1300 LOCAL_ENTRY 1301 + __field(int, radio_idx) 1367 1302 __field(u32, tx_ant) 1368 1303 __field(u32, rx_ant) 1369 1304 __field(int, ret) ··· 1373 1304 1374 1305 TP_fast_assign( 1375 1306 LOCAL_ASSIGN; 1307 + __entry->radio_idx = radio_idx; 1376 1308 __entry->tx_ant = tx_ant; 1377 1309 __entry->rx_ant = rx_ant; 1378 1310 __entry->ret = ret; 1379 1311 ), 1380 1312 1381 1313 TP_printk( 1382 - LOCAL_PR_FMT " tx_ant:%d rx_ant:%d ret:%d", 1383 - LOCAL_PR_ARG, __entry->tx_ant, __entry->rx_ant, __entry->ret 1314 + LOCAL_PR_FMT " radio_idx:%d tx_ant:%d rx_ant:%d ret:%d", 1315 + LOCAL_PR_ARG, __entry->radio_idx, __entry->tx_ant, 1316 + __entry->rx_ant, __entry->ret 1384 1317 ) 1385 1318 ); 1386 1319
+4 -3
net/mac80211/tx.c
··· 1173 1173 return; 1174 1174 1175 1175 if (!sta || 1176 - (!sta->sta.valid_links && !sta->sta.deflink.ht_cap.ht_supported) || 1176 + (!sta->sta.valid_links && !sta->sta.deflink.ht_cap.ht_supported && 1177 + !sta->sta.deflink.s1g_cap.s1g) || 1177 1178 !sta->sta.wme || skb_get_queue_mapping(skb) == IEEE80211_AC_VO || 1178 1179 skb->protocol == sdata->control_port_protocol) 1179 1180 return; ··· 1542 1541 spin_unlock_bh(&local->active_txq_lock[txqi->txq.ac]); 1543 1542 } 1544 1543 1545 - void ieee80211_txq_set_params(struct ieee80211_local *local) 1544 + void ieee80211_txq_set_params(struct ieee80211_local *local, int radio_idx) 1546 1545 { 1547 1546 if (local->hw.wiphy->txq_limit) 1548 1547 local->fq.limit = local->hw.wiphy->txq_limit; ··· 1606 1605 for (i = 0; i < fq->flows_cnt; i++) 1607 1606 codel_vars_init(&local->cvars[i]); 1608 1607 1609 - ieee80211_txq_set_params(local); 1608 + ieee80211_txq_set_params(local, -1); 1610 1609 1611 1610 return 0; 1612 1611 }
+55 -10
net/mac80211/util.c
··· 1756 1756 bool sched_scan_stopped = false; 1757 1757 bool suspended = local->suspended; 1758 1758 bool in_reconfig = false; 1759 + u32 rts_threshold; 1759 1760 1760 1761 lockdep_assert_wiphy(local->hw.wiphy); 1761 1762 ··· 1827 1826 } 1828 1827 1829 1828 /* setup fragmentation threshold */ 1830 - drv_set_frag_threshold(local, hw->wiphy->frag_threshold); 1829 + drv_set_frag_threshold(local, -1, hw->wiphy->frag_threshold); 1831 1830 1832 1831 /* setup RTS threshold */ 1833 - drv_set_rts_threshold(local, hw->wiphy->rts_threshold); 1832 + if (hw->wiphy->n_radio > 0) { 1833 + for (i = 0; i < hw->wiphy->n_radio; i++) { 1834 + rts_threshold = hw->wiphy->radio_cfg[i].rts_threshold; 1835 + drv_set_rts_threshold(local, i, rts_threshold); 1836 + } 1837 + } else { 1838 + drv_set_rts_threshold(local, -1, hw->wiphy->rts_threshold); 1839 + } 1834 1840 1835 1841 /* reset coverage class */ 1836 - drv_set_coverage_class(local, hw->wiphy->coverage_class); 1842 + drv_set_coverage_class(local, -1, hw->wiphy->coverage_class); 1837 1843 1838 1844 ieee80211_led_radio(local, true); 1839 1845 ieee80211_mod_tpt_led_trig(local, ··· 1898 1890 ieee80211_assign_chanctx(local, sdata, &sdata->deflink); 1899 1891 1900 1892 /* reconfigure hardware */ 1901 - ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_LISTEN_INTERVAL | 1902 - IEEE80211_CONF_CHANGE_MONITOR | 1903 - IEEE80211_CONF_CHANGE_PS | 1904 - IEEE80211_CONF_CHANGE_RETRY_LIMITS | 1905 - IEEE80211_CONF_CHANGE_IDLE); 1893 + ieee80211_hw_config(local, -1, IEEE80211_CONF_CHANGE_LISTEN_INTERVAL | 1894 + IEEE80211_CONF_CHANGE_MONITOR | 1895 + IEEE80211_CONF_CHANGE_PS | 1896 + IEEE80211_CONF_CHANGE_RETRY_LIMITS | 1897 + IEEE80211_CONF_CHANGE_IDLE); 1906 1898 1907 1899 ieee80211_configure_filter(local); 1908 1900 ··· 3273 3265 return 0; 3274 3266 } 3275 3267 3276 - int ieee80211_ave_rssi(struct ieee80211_vif *vif) 3268 + int ieee80211_ave_rssi(struct ieee80211_vif *vif, int link_id) 3277 3269 { 3278 3270 struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif); 3271 + struct ieee80211_link_data *link_data; 3279 3272 3280 3273 if (WARN_ON_ONCE(sdata->vif.type != NL80211_IFTYPE_STATION)) 3281 3274 return 0; 3282 3275 3283 - return -ewma_beacon_signal_read(&sdata->deflink.u.mgd.ave_beacon_signal); 3276 + if (link_id < 0) 3277 + link_data = &sdata->deflink; 3278 + else 3279 + link_data = wiphy_dereference(sdata->local->hw.wiphy, 3280 + sdata->link[link_id]); 3281 + 3282 + if (WARN_ON_ONCE(!link_data)) 3283 + return -99; 3284 + 3285 + return -ewma_beacon_signal_read(&link_data->u.mgd.ave_beacon_signal); 3284 3286 } 3285 3287 EXPORT_SYMBOL_GPL(ieee80211_ave_rssi); 3286 3288 ··· 3969 3951 } 3970 3952 3971 3953 return radar_detect; 3954 + } 3955 + 3956 + bool ieee80211_is_radio_idx_in_scan_req(struct wiphy *wiphy, 3957 + struct cfg80211_scan_request *scan_req, 3958 + int radio_idx) 3959 + { 3960 + struct ieee80211_channel *chan; 3961 + int i, chan_radio_idx; 3962 + 3963 + for (i = 0; i < scan_req->n_channels; i++) { 3964 + chan = scan_req->channels[i]; 3965 + chan_radio_idx = cfg80211_get_radio_idx_by_chan(wiphy, chan); 3966 + /* 3967 + * The chan_radio_idx should be valid since it's taken from a 3968 + * valid scan request. 3969 + * However, if chan_radio_idx is unexpectedly invalid (negative), 3970 + * we take a conservative approach and assume the scan request 3971 + * might use the specified radio_idx. Hence, return true. 3972 + */ 3973 + if (WARN_ON(chan_radio_idx < 0)) 3974 + return true; 3975 + 3976 + if (chan_radio_idx == radio_idx) 3977 + return true; 3978 + } 3979 + 3980 + return false; 3972 3981 } 3973 3982 3974 3983 static u32
+19
net/wireless/core.c
··· 995 995 wiphy->max_num_akm_suites > CFG80211_MAX_NUM_AKM_SUITES) 996 996 return -EINVAL; 997 997 998 + /* Allocate radio configuration space for multi-radio wiphy */ 999 + if (wiphy->n_radio > 0) { 1000 + int idx; 1001 + 1002 + wiphy->radio_cfg = kcalloc(wiphy->n_radio, 1003 + sizeof(*wiphy->radio_cfg), 1004 + GFP_KERNEL); 1005 + if (!wiphy->radio_cfg) 1006 + return -ENOMEM; 1007 + /* 1008 + * Initialize wiphy radio parameters to IEEE 802.11 1009 + * MIB default values. RTS threshold is disabled by 1010 + * default with the special -1 value. 1011 + */ 1012 + for (idx = 0; idx < wiphy->n_radio; idx++) 1013 + wiphy->radio_cfg[idx].rts_threshold = (u32)-1; 1014 + } 1015 + 998 1016 /* check and set up bitrates */ 999 1017 ieee80211_set_bitrate_flags(wiphy); 1000 1018 ··· 1240 1222 1241 1223 void wiphy_free(struct wiphy *wiphy) 1242 1224 { 1225 + kfree(wiphy->radio_cfg); 1243 1226 put_device(&wiphy->dev); 1244 1227 } 1245 1228 EXPORT_SYMBOL(wiphy_free);
+8 -2
net/wireless/mlme.c
··· 1331 1331 lockdep_assert_wiphy(wiphy); 1332 1332 1333 1333 trace_cfg80211_mlo_reconf_add_done(dev, data->added_links, 1334 - data->buf, data->len); 1334 + data->buf, data->len, 1335 + data->driver_initiated); 1335 1336 1336 1337 if (WARN_ON(!wdev->valid_links)) 1337 1338 return; ··· 1362 1361 wdev->links[link_id].client.current_bss = 1363 1362 bss_from_pub(bss); 1364 1363 1364 + if (data->driver_initiated) 1365 + cfg80211_hold_bss(bss_from_pub(bss)); 1366 + 1365 1367 memcpy(wdev->links[link_id].addr, 1366 1368 data->links[link_id].addr, 1367 1369 ETH_ALEN); 1368 1370 } else { 1369 - cfg80211_unhold_bss(bss_from_pub(bss)); 1371 + if (!data->driver_initiated) 1372 + cfg80211_unhold_bss(bss_from_pub(bss)); 1373 + 1370 1374 cfg80211_put_bss(wiphy, bss); 1371 1375 } 1372 1376 }
+527 -12
net/wireless/nl80211.c
··· 854 854 [NL80211_ATTR_MLO_RECONF_REM_LINKS] = { .type = NLA_U16 }, 855 855 [NL80211_ATTR_EPCS] = { .type = NLA_FLAG }, 856 856 [NL80211_ATTR_ASSOC_MLD_EXT_CAPA_OPS] = { .type = NLA_U16 }, 857 + [NL80211_ATTR_WIPHY_RADIO_INDEX] = { .type = NLA_U8 }, 857 858 }; 858 859 859 860 /* policy for the key attributes */ ··· 2447 2446 static int nl80211_put_radio(struct wiphy *wiphy, struct sk_buff *msg, int idx) 2448 2447 { 2449 2448 const struct wiphy_radio *r = &wiphy->radio[idx]; 2449 + const struct wiphy_radio_cfg *rcfg = &wiphy->radio_cfg[idx]; 2450 2450 struct nlattr *radio, *freq; 2451 2451 int i; 2452 2452 ··· 2456 2454 return -ENOBUFS; 2457 2455 2458 2456 if (nla_put_u32(msg, NL80211_WIPHY_RADIO_ATTR_INDEX, idx)) 2457 + goto nla_put_failure; 2458 + 2459 + if (rcfg->rts_threshold && 2460 + nla_put_u32(msg, NL80211_WIPHY_RADIO_ATTR_RTS_THRESHOLD, 2461 + rcfg->rts_threshold)) 2459 2462 goto nla_put_failure; 2460 2463 2461 2464 if (r->antenna_mask && ··· 2646 2639 u32 tx_ant = 0, rx_ant = 0; 2647 2640 int res; 2648 2641 2649 - res = rdev_get_antenna(rdev, &tx_ant, &rx_ant); 2642 + res = rdev_get_antenna(rdev, -1, &tx_ant, &rx_ant); 2650 2643 if (!res) { 2651 2644 if (nla_put_u32(msg, 2652 2645 NL80211_ATTR_WIPHY_ANTENNA_TX, ··· 3615 3608 return __nl80211_set_channel(rdev, netdev, info, link_id); 3616 3609 } 3617 3610 3611 + static int nl80211_set_wiphy_radio(struct genl_info *info, 3612 + struct cfg80211_registered_device *rdev, 3613 + int radio_idx) 3614 + { 3615 + u32 rts_threshold = 0, old_rts, changed = 0; 3616 + int result; 3617 + 3618 + if (!rdev->ops->set_wiphy_params) 3619 + return -EOPNOTSUPP; 3620 + 3621 + if (info->attrs[NL80211_ATTR_WIPHY_RTS_THRESHOLD]) { 3622 + rts_threshold = nla_get_u32( 3623 + info->attrs[NL80211_ATTR_WIPHY_RTS_THRESHOLD]); 3624 + changed |= WIPHY_PARAM_RTS_THRESHOLD; 3625 + } 3626 + 3627 + old_rts = rdev->wiphy.radio_cfg[radio_idx].rts_threshold; 3628 + 3629 + rdev->wiphy.radio_cfg[radio_idx].rts_threshold = rts_threshold; 3630 + 3631 + result = rdev_set_wiphy_params(rdev, radio_idx, changed); 3632 + if (result) 3633 + rdev->wiphy.radio_cfg[radio_idx].rts_threshold = old_rts; 3634 + 3635 + return 0; 3636 + } 3637 + 3618 3638 static int nl80211_set_wiphy(struct sk_buff *skb, struct genl_info *info) 3619 3639 { 3620 3640 struct cfg80211_registered_device *rdev = NULL; ··· 3654 3620 u32 frag_threshold = 0, rts_threshold = 0; 3655 3621 u8 coverage_class = 0; 3656 3622 u32 txq_limit = 0, txq_memory_limit = 0, txq_quantum = 0; 3623 + int radio_idx = -1; 3657 3624 3658 3625 rtnl_lock(); 3659 3626 /* ··· 3704 3669 3705 3670 if (result) 3706 3671 return result; 3672 + 3673 + if (info->attrs[NL80211_ATTR_WIPHY_RADIO_INDEX]) { 3674 + /* Radio idx is not expected for non-multi radio wiphy */ 3675 + if (rdev->wiphy.n_radio <= 0) 3676 + return -EINVAL; 3677 + 3678 + radio_idx = nla_get_u8( 3679 + info->attrs[NL80211_ATTR_WIPHY_RADIO_INDEX]); 3680 + if (radio_idx >= rdev->wiphy.n_radio) 3681 + return -EINVAL; 3682 + 3683 + return nl80211_set_wiphy_radio(info, rdev, radio_idx); 3684 + } 3707 3685 3708 3686 if (info->attrs[NL80211_ATTR_WIPHY_TXQ_PARAMS]) { 3709 3687 struct ieee80211_txq_params txq_params; ··· 3807 3759 mbm = nla_get_u32(info->attrs[idx]); 3808 3760 } 3809 3761 3810 - result = rdev_set_tx_power(rdev, txp_wdev, type, mbm); 3762 + result = rdev_set_tx_power(rdev, txp_wdev, radio_idx, type, 3763 + mbm); 3811 3764 if (result) 3812 3765 return result; 3813 3766 } ··· 3834 3785 tx_ant = tx_ant & rdev->wiphy.available_antennas_tx; 3835 3786 rx_ant = rx_ant & rdev->wiphy.available_antennas_rx; 3836 3787 3837 - result = rdev_set_antenna(rdev, tx_ant, rx_ant); 3788 + result = rdev_set_antenna(rdev, radio_idx, tx_ant, rx_ant); 3838 3789 if (result) 3839 3790 return result; 3840 3791 } ··· 3928 3879 if (changed) { 3929 3880 u8 old_retry_short, old_retry_long; 3930 3881 u32 old_frag_threshold, old_rts_threshold; 3931 - u8 old_coverage_class; 3882 + u8 old_coverage_class, i; 3932 3883 u32 old_txq_limit, old_txq_memory_limit, old_txq_quantum; 3884 + u32 *old_radio_rts_threshold = NULL; 3933 3885 3934 3886 if (!rdev->ops->set_wiphy_params) 3935 3887 return -EOPNOTSUPP; 3888 + 3889 + if (rdev->wiphy.n_radio) { 3890 + old_radio_rts_threshold = kcalloc(rdev->wiphy.n_radio, 3891 + sizeof(u32), 3892 + GFP_KERNEL); 3893 + if (!old_radio_rts_threshold) 3894 + return -ENOMEM; 3895 + } 3936 3896 3937 3897 old_retry_short = rdev->wiphy.retry_short; 3938 3898 old_retry_long = rdev->wiphy.retry_long; 3939 3899 old_frag_threshold = rdev->wiphy.frag_threshold; 3940 3900 old_rts_threshold = rdev->wiphy.rts_threshold; 3901 + if (old_radio_rts_threshold) { 3902 + for (i = 0 ; i < rdev->wiphy.n_radio; i++) 3903 + old_radio_rts_threshold[i] = 3904 + rdev->wiphy.radio_cfg[i].rts_threshold; 3905 + } 3941 3906 old_coverage_class = rdev->wiphy.coverage_class; 3942 3907 old_txq_limit = rdev->wiphy.txq_limit; 3943 3908 old_txq_memory_limit = rdev->wiphy.txq_memory_limit; ··· 3963 3900 rdev->wiphy.retry_long = retry_long; 3964 3901 if (changed & WIPHY_PARAM_FRAG_THRESHOLD) 3965 3902 rdev->wiphy.frag_threshold = frag_threshold; 3966 - if (changed & WIPHY_PARAM_RTS_THRESHOLD) 3903 + if ((changed & WIPHY_PARAM_RTS_THRESHOLD) && 3904 + old_radio_rts_threshold) { 3967 3905 rdev->wiphy.rts_threshold = rts_threshold; 3906 + for (i = 0 ; i < rdev->wiphy.n_radio; i++) 3907 + rdev->wiphy.radio_cfg[i].rts_threshold = 3908 + rdev->wiphy.rts_threshold; 3909 + } 3968 3910 if (changed & WIPHY_PARAM_COVERAGE_CLASS) 3969 3911 rdev->wiphy.coverage_class = coverage_class; 3970 3912 if (changed & WIPHY_PARAM_TXQ_LIMIT) ··· 3979 3911 if (changed & WIPHY_PARAM_TXQ_QUANTUM) 3980 3912 rdev->wiphy.txq_quantum = txq_quantum; 3981 3913 3982 - result = rdev_set_wiphy_params(rdev, changed); 3914 + result = rdev_set_wiphy_params(rdev, radio_idx, changed); 3983 3915 if (result) { 3984 3916 rdev->wiphy.retry_short = old_retry_short; 3985 3917 rdev->wiphy.retry_long = old_retry_long; 3986 3918 rdev->wiphy.frag_threshold = old_frag_threshold; 3987 3919 rdev->wiphy.rts_threshold = old_rts_threshold; 3920 + if (old_radio_rts_threshold) { 3921 + for (i = 0 ; i < rdev->wiphy.n_radio; i++) 3922 + rdev->wiphy.radio_cfg[i].rts_threshold = 3923 + old_radio_rts_threshold[i]; 3924 + } 3988 3925 rdev->wiphy.coverage_class = old_coverage_class; 3989 3926 rdev->wiphy.txq_limit = old_txq_limit; 3990 3927 rdev->wiphy.txq_memory_limit = old_txq_memory_limit; 3991 3928 rdev->wiphy.txq_quantum = old_txq_quantum; 3992 - return result; 3993 3929 } 3930 + 3931 + if (old_rts_threshold) 3932 + kfree(old_radio_rts_threshold); 3933 + return result; 3994 3934 } 3995 3935 3996 3936 return 0; ··· 4088 4012 if (rdev->ops->get_tx_power && !wdev->valid_links) { 4089 4013 int dbm, ret; 4090 4014 4091 - ret = rdev_get_tx_power(rdev, wdev, 0, &dbm); 4015 + ret = rdev_get_tx_power(rdev, wdev, -1, 0, &dbm); 4092 4016 if (ret == 0 && 4093 4017 nla_put_u32(msg, NL80211_ATTR_WIPHY_TX_POWER_LEVEL, 4094 4018 DBM_TO_MBM(dbm))) ··· 4160 4084 if (rdev->ops->get_tx_power) { 4161 4085 int dbm, ret; 4162 4086 4163 - ret = rdev_get_tx_power(rdev, wdev, link_id, &dbm); 4087 + ret = rdev_get_tx_power(rdev, wdev, -1, link_id, &dbm); 4164 4088 if (ret == 0 && 4165 4089 nla_put_u32(msg, NL80211_ATTR_WIPHY_TX_POWER_LEVEL, 4166 4090 DBM_TO_MBM(dbm))) ··· 6804 6728 return true; 6805 6729 } 6806 6730 6731 + static int nl80211_fill_link_station(struct sk_buff *msg, 6732 + struct cfg80211_registered_device *rdev, 6733 + struct link_station_info *link_sinfo) 6734 + { 6735 + struct nlattr *bss_param, *link_sinfoattr; 6736 + 6737 + #define PUT_LINK_SINFO(attr, memb, type) do { \ 6738 + BUILD_BUG_ON(sizeof(type) == sizeof(u64)); \ 6739 + if (link_sinfo->filled & BIT_ULL(NL80211_STA_INFO_ ## attr) && \ 6740 + nla_put_ ## type(msg, NL80211_STA_INFO_ ## attr, \ 6741 + link_sinfo->memb)) \ 6742 + goto nla_put_failure; \ 6743 + } while (0) 6744 + #define PUT_LINK_SINFO_U64(attr, memb) do { \ 6745 + if (link_sinfo->filled & BIT_ULL(NL80211_STA_INFO_ ## attr) && \ 6746 + nla_put_u64_64bit(msg, NL80211_STA_INFO_ ## attr, \ 6747 + link_sinfo->memb, NL80211_STA_INFO_PAD)) \ 6748 + goto nla_put_failure; \ 6749 + } while (0) 6750 + 6751 + link_sinfoattr = nla_nest_start_noflag(msg, NL80211_ATTR_STA_INFO); 6752 + if (!link_sinfoattr) 6753 + goto nla_put_failure; 6754 + 6755 + PUT_LINK_SINFO(INACTIVE_TIME, inactive_time, u32); 6756 + 6757 + if (link_sinfo->filled & (BIT_ULL(NL80211_STA_INFO_RX_BYTES) | 6758 + BIT_ULL(NL80211_STA_INFO_RX_BYTES64)) && 6759 + nla_put_u32(msg, NL80211_STA_INFO_RX_BYTES, 6760 + (u32)link_sinfo->rx_bytes)) 6761 + goto nla_put_failure; 6762 + 6763 + if (link_sinfo->filled & (BIT_ULL(NL80211_STA_INFO_TX_BYTES) | 6764 + BIT_ULL(NL80211_STA_INFO_TX_BYTES64)) && 6765 + nla_put_u32(msg, NL80211_STA_INFO_TX_BYTES, 6766 + (u32)link_sinfo->tx_bytes)) 6767 + goto nla_put_failure; 6768 + 6769 + PUT_LINK_SINFO_U64(RX_BYTES64, rx_bytes); 6770 + PUT_LINK_SINFO_U64(TX_BYTES64, tx_bytes); 6771 + PUT_LINK_SINFO_U64(RX_DURATION, rx_duration); 6772 + PUT_LINK_SINFO_U64(TX_DURATION, tx_duration); 6773 + 6774 + if (wiphy_ext_feature_isset(&rdev->wiphy, 6775 + NL80211_EXT_FEATURE_AIRTIME_FAIRNESS)) 6776 + PUT_LINK_SINFO(AIRTIME_WEIGHT, airtime_weight, u16); 6777 + 6778 + switch (rdev->wiphy.signal_type) { 6779 + case CFG80211_SIGNAL_TYPE_MBM: 6780 + PUT_LINK_SINFO(SIGNAL, signal, u8); 6781 + PUT_LINK_SINFO(SIGNAL_AVG, signal_avg, u8); 6782 + break; 6783 + default: 6784 + break; 6785 + } 6786 + if (link_sinfo->filled & BIT_ULL(NL80211_STA_INFO_CHAIN_SIGNAL)) { 6787 + if (!nl80211_put_signal(msg, link_sinfo->chains, 6788 + link_sinfo->chain_signal, 6789 + NL80211_STA_INFO_CHAIN_SIGNAL)) 6790 + goto nla_put_failure; 6791 + } 6792 + if (link_sinfo->filled & BIT_ULL(NL80211_STA_INFO_CHAIN_SIGNAL_AVG)) { 6793 + if (!nl80211_put_signal(msg, link_sinfo->chains, 6794 + link_sinfo->chain_signal_avg, 6795 + NL80211_STA_INFO_CHAIN_SIGNAL_AVG)) 6796 + goto nla_put_failure; 6797 + } 6798 + if (link_sinfo->filled & BIT_ULL(NL80211_STA_INFO_TX_BITRATE)) { 6799 + if (!nl80211_put_sta_rate(msg, &link_sinfo->txrate, 6800 + NL80211_STA_INFO_TX_BITRATE)) 6801 + goto nla_put_failure; 6802 + } 6803 + if (link_sinfo->filled & BIT_ULL(NL80211_STA_INFO_RX_BITRATE)) { 6804 + if (!nl80211_put_sta_rate(msg, &link_sinfo->rxrate, 6805 + NL80211_STA_INFO_RX_BITRATE)) 6806 + goto nla_put_failure; 6807 + } 6808 + 6809 + PUT_LINK_SINFO(RX_PACKETS, rx_packets, u32); 6810 + PUT_LINK_SINFO(TX_PACKETS, tx_packets, u32); 6811 + PUT_LINK_SINFO(TX_RETRIES, tx_retries, u32); 6812 + PUT_LINK_SINFO(TX_FAILED, tx_failed, u32); 6813 + PUT_LINK_SINFO(EXPECTED_THROUGHPUT, expected_throughput, u32); 6814 + PUT_LINK_SINFO(BEACON_LOSS, beacon_loss_count, u32); 6815 + 6816 + if (link_sinfo->filled & BIT_ULL(NL80211_STA_INFO_BSS_PARAM)) { 6817 + bss_param = nla_nest_start_noflag(msg, 6818 + NL80211_STA_INFO_BSS_PARAM); 6819 + if (!bss_param) 6820 + goto nla_put_failure; 6821 + 6822 + if (((link_sinfo->bss_param.flags & 6823 + BSS_PARAM_FLAGS_CTS_PROT) && 6824 + nla_put_flag(msg, NL80211_STA_BSS_PARAM_CTS_PROT)) || 6825 + ((link_sinfo->bss_param.flags & 6826 + BSS_PARAM_FLAGS_SHORT_PREAMBLE) && 6827 + nla_put_flag(msg, 6828 + NL80211_STA_BSS_PARAM_SHORT_PREAMBLE)) || 6829 + ((link_sinfo->bss_param.flags & 6830 + BSS_PARAM_FLAGS_SHORT_SLOT_TIME) && 6831 + nla_put_flag(msg, 6832 + NL80211_STA_BSS_PARAM_SHORT_SLOT_TIME)) || 6833 + nla_put_u8(msg, NL80211_STA_BSS_PARAM_DTIM_PERIOD, 6834 + link_sinfo->bss_param.dtim_period) || 6835 + nla_put_u16(msg, NL80211_STA_BSS_PARAM_BEACON_INTERVAL, 6836 + link_sinfo->bss_param.beacon_interval)) 6837 + goto nla_put_failure; 6838 + 6839 + nla_nest_end(msg, bss_param); 6840 + } 6841 + 6842 + PUT_LINK_SINFO_U64(RX_DROP_MISC, rx_dropped_misc); 6843 + PUT_LINK_SINFO_U64(BEACON_RX, rx_beacon); 6844 + PUT_LINK_SINFO(BEACON_SIGNAL_AVG, rx_beacon_signal_avg, u8); 6845 + PUT_LINK_SINFO(RX_MPDUS, rx_mpdu_count, u32); 6846 + PUT_LINK_SINFO(FCS_ERROR_COUNT, fcs_err_count, u32); 6847 + if (wiphy_ext_feature_isset(&rdev->wiphy, 6848 + NL80211_EXT_FEATURE_ACK_SIGNAL_SUPPORT)) { 6849 + PUT_LINK_SINFO(ACK_SIGNAL, ack_signal, u8); 6850 + PUT_LINK_SINFO(ACK_SIGNAL_AVG, avg_ack_signal, s8); 6851 + } 6852 + 6853 + #undef PUT_LINK_SINFO 6854 + #undef PUT_LINK_SINFO_U64 6855 + 6856 + if (link_sinfo->pertid) { 6857 + struct nlattr *tidsattr; 6858 + int tid; 6859 + 6860 + tidsattr = nla_nest_start_noflag(msg, 6861 + NL80211_STA_INFO_TID_STATS); 6862 + if (!tidsattr) 6863 + goto nla_put_failure; 6864 + 6865 + for (tid = 0; tid < IEEE80211_NUM_TIDS + 1; tid++) { 6866 + struct cfg80211_tid_stats *tidstats; 6867 + struct nlattr *tidattr; 6868 + 6869 + tidstats = &link_sinfo->pertid[tid]; 6870 + 6871 + if (!tidstats->filled) 6872 + continue; 6873 + 6874 + tidattr = nla_nest_start_noflag(msg, tid + 1); 6875 + if (!tidattr) 6876 + goto nla_put_failure; 6877 + 6878 + #define PUT_TIDVAL_U64(attr, memb) do { \ 6879 + if (tidstats->filled & BIT(NL80211_TID_STATS_ ## attr) && \ 6880 + nla_put_u64_64bit(msg, NL80211_TID_STATS_ ## attr, \ 6881 + tidstats->memb, NL80211_TID_STATS_PAD)) \ 6882 + goto nla_put_failure; \ 6883 + } while (0) 6884 + 6885 + PUT_TIDVAL_U64(RX_MSDU, rx_msdu); 6886 + PUT_TIDVAL_U64(TX_MSDU, tx_msdu); 6887 + PUT_TIDVAL_U64(TX_MSDU_RETRIES, tx_msdu_retries); 6888 + PUT_TIDVAL_U64(TX_MSDU_FAILED, tx_msdu_failed); 6889 + 6890 + #undef PUT_TIDVAL_U64 6891 + if ((tidstats->filled & 6892 + BIT(NL80211_TID_STATS_TXQ_STATS)) && 6893 + !nl80211_put_txq_stats(msg, &tidstats->txq_stats, 6894 + NL80211_TID_STATS_TXQ_STATS)) 6895 + goto nla_put_failure; 6896 + 6897 + nla_nest_end(msg, tidattr); 6898 + } 6899 + 6900 + nla_nest_end(msg, tidsattr); 6901 + } 6902 + 6903 + nla_nest_end(msg, link_sinfoattr); 6904 + return 0; 6905 + 6906 + nla_put_failure: 6907 + return -EMSGSIZE; 6908 + } 6909 + 6807 6910 static int nl80211_send_station(struct sk_buff *msg, u32 cmd, u32 portid, 6808 6911 u32 seq, int flags, 6809 6912 struct cfg80211_registered_device *rdev, ··· 6991 6736 { 6992 6737 void *hdr; 6993 6738 struct nlattr *sinfoattr, *bss_param; 6739 + struct link_station_info *link_sinfo; 6740 + struct nlattr *links, *link; 6741 + int link_id; 6994 6742 6995 6743 hdr = nl80211hdr_put(msg, portid, seq, flags, cmd); 6996 6744 if (!hdr) { ··· 7208 6950 goto nla_put_failure; 7209 6951 } 7210 6952 6953 + if (sinfo->valid_links) { 6954 + links = nla_nest_start(msg, NL80211_ATTR_MLO_LINKS); 6955 + if (!links) 6956 + goto nla_put_failure; 6957 + 6958 + for_each_valid_link(sinfo, link_id) { 6959 + link_sinfo = sinfo->links[link_id]; 6960 + 6961 + if (WARN_ON_ONCE(!link_sinfo)) 6962 + continue; 6963 + 6964 + if (!is_valid_ether_addr(link_sinfo->addr)) 6965 + continue; 6966 + 6967 + link = nla_nest_start(msg, link_id + 1); 6968 + if (!link) 6969 + goto nla_put_failure; 6970 + 6971 + if (nla_put_u8(msg, NL80211_ATTR_MLO_LINK_ID, 6972 + link_id)) 6973 + goto nla_put_failure; 6974 + 6975 + if (nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, 6976 + link_sinfo->addr)) 6977 + goto nla_put_failure; 6978 + 6979 + if (nl80211_fill_link_station(msg, rdev, link_sinfo)) 6980 + goto nla_put_failure; 6981 + 6982 + nla_nest_end(msg, link); 6983 + } 6984 + nla_nest_end(msg, links); 6985 + } 6986 + 7211 6987 cfg80211_sinfo_release_content(sinfo); 7212 6988 genlmsg_end(msg, hdr); 7213 6989 return 0; ··· 7252 6960 return -EMSGSIZE; 7253 6961 } 7254 6962 6963 + static void cfg80211_sta_set_mld_sinfo(struct station_info *sinfo) 6964 + { 6965 + struct link_station_info *link_sinfo; 6966 + int link_id, init = 0; 6967 + u32 link_inactive_time; 6968 + 6969 + sinfo->signal = -99; 6970 + 6971 + for_each_valid_link(sinfo, link_id) { 6972 + link_sinfo = sinfo->links[link_id]; 6973 + if (!link_sinfo) 6974 + continue; 6975 + 6976 + if ((link_sinfo->filled & 6977 + BIT_ULL(NL80211_STA_INFO_TX_PACKETS))) { 6978 + sinfo->tx_packets += link_sinfo->tx_packets; 6979 + sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_PACKETS); 6980 + } 6981 + 6982 + if ((link_sinfo->filled & 6983 + BIT_ULL(NL80211_STA_INFO_RX_PACKETS))) { 6984 + sinfo->rx_packets += link_sinfo->rx_packets; 6985 + sinfo->filled |= BIT_ULL(NL80211_STA_INFO_RX_PACKETS); 6986 + } 6987 + 6988 + if (link_sinfo->filled & 6989 + (BIT_ULL(NL80211_STA_INFO_TX_BYTES) | 6990 + BIT_ULL(NL80211_STA_INFO_TX_BYTES64))) { 6991 + sinfo->tx_bytes += link_sinfo->tx_bytes; 6992 + sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_BYTES); 6993 + } 6994 + 6995 + if (link_sinfo->filled & 6996 + (BIT_ULL(NL80211_STA_INFO_RX_BYTES) | 6997 + BIT_ULL(NL80211_STA_INFO_TX_BYTES64))) { 6998 + sinfo->rx_bytes += link_sinfo->rx_bytes; 6999 + sinfo->filled |= BIT_ULL(NL80211_STA_INFO_RX_BYTES); 7000 + } 7001 + 7002 + if (link_sinfo->filled & 7003 + BIT_ULL(NL80211_STA_INFO_TX_RETRIES)) { 7004 + sinfo->tx_retries += link_sinfo->tx_retries; 7005 + sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_RETRIES); 7006 + } 7007 + 7008 + if (link_sinfo->filled & BIT_ULL(NL80211_STA_INFO_TX_FAILED)) { 7009 + sinfo->tx_failed += link_sinfo->tx_failed; 7010 + sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_FAILED); 7011 + } 7012 + 7013 + if (link_sinfo->filled & 7014 + BIT_ULL(NL80211_STA_INFO_RX_DROP_MISC)) { 7015 + sinfo->rx_dropped_misc += link_sinfo->rx_dropped_misc; 7016 + sinfo->filled |= 7017 + BIT_ULL(NL80211_STA_INFO_RX_DROP_MISC); 7018 + } 7019 + 7020 + if (link_sinfo->filled & 7021 + BIT_ULL(NL80211_STA_INFO_BEACON_LOSS)) { 7022 + sinfo->beacon_loss_count += 7023 + link_sinfo->beacon_loss_count; 7024 + sinfo->filled |= BIT_ULL(NL80211_STA_INFO_BEACON_LOSS); 7025 + } 7026 + 7027 + if (link_sinfo->filled & 7028 + BIT_ULL(NL80211_STA_INFO_EXPECTED_THROUGHPUT)) { 7029 + sinfo->expected_throughput += 7030 + link_sinfo->expected_throughput; 7031 + sinfo->filled |= 7032 + BIT_ULL(NL80211_STA_INFO_EXPECTED_THROUGHPUT); 7033 + } 7034 + 7035 + if (link_sinfo->filled & BIT_ULL(NL80211_STA_INFO_RX_MPDUS)) { 7036 + sinfo->rx_mpdu_count += link_sinfo->rx_mpdu_count; 7037 + sinfo->filled |= BIT_ULL(NL80211_STA_INFO_RX_MPDUS); 7038 + } 7039 + 7040 + if (link_sinfo->filled & 7041 + BIT_ULL(NL80211_STA_INFO_FCS_ERROR_COUNT)) { 7042 + sinfo->fcs_err_count += link_sinfo->fcs_err_count; 7043 + sinfo->filled |= 7044 + BIT_ULL(NL80211_STA_INFO_FCS_ERROR_COUNT); 7045 + } 7046 + 7047 + if (link_sinfo->filled & 7048 + BIT_ULL(NL80211_STA_INFO_BEACON_RX)) { 7049 + sinfo->rx_beacon += link_sinfo->rx_beacon; 7050 + sinfo->filled |= BIT_ULL(NL80211_STA_INFO_BEACON_RX); 7051 + } 7052 + 7053 + /* Update MLO signal, signal_avg as best among links */ 7054 + if ((link_sinfo->filled & BIT_ULL(NL80211_STA_INFO_SIGNAL)) && 7055 + link_sinfo->signal > sinfo->signal) { 7056 + sinfo->signal = link_sinfo->signal; 7057 + sinfo->filled |= BIT_ULL(NL80211_STA_INFO_SIGNAL); 7058 + } 7059 + 7060 + if ((link_sinfo->filled & 7061 + BIT_ULL(NL80211_STA_INFO_SIGNAL_AVG)) && 7062 + link_sinfo->signal_avg > sinfo->signal_avg) { 7063 + sinfo->signal_avg = link_sinfo->signal_avg; 7064 + sinfo->filled |= BIT_ULL(NL80211_STA_INFO_SIGNAL_AVG); 7065 + } 7066 + 7067 + /* Update MLO inactive_time, bss_param based on least 7068 + * value for corresponding field of link. 7069 + */ 7070 + if ((link_sinfo->filled & 7071 + BIT_ULL(NL80211_STA_INFO_INACTIVE_TIME)) && 7072 + (!init || 7073 + link_inactive_time > link_sinfo->inactive_time)) { 7074 + link_inactive_time = link_sinfo->inactive_time; 7075 + sinfo->inactive_time = link_sinfo->inactive_time; 7076 + sinfo->filled |= NL80211_STA_INFO_INACTIVE_TIME; 7077 + } 7078 + 7079 + if (link_sinfo->filled & BIT_ULL(NL80211_STA_INFO_BSS_PARAM) && 7080 + (!init || 7081 + sinfo->bss_param.dtim_period > 7082 + link_sinfo->bss_param.dtim_period)) { 7083 + sinfo->bss_param.dtim_period = 7084 + link_sinfo->bss_param.dtim_period; 7085 + sinfo->filled |= NL80211_STA_BSS_PARAM_DTIM_PERIOD; 7086 + sinfo->bss_param.beacon_interval = 7087 + link_sinfo->bss_param.beacon_interval; 7088 + sinfo->filled |= NL80211_STA_BSS_PARAM_BEACON_INTERVAL; 7089 + } 7090 + 7091 + /* Update MLO rates as per last updated link rate */ 7092 + if ((link_sinfo->filled & 7093 + BIT_ULL(NL80211_STA_INFO_TX_BITRATE)) && 7094 + (!init || 7095 + link_inactive_time > link_sinfo->inactive_time)) { 7096 + sinfo->txrate = link_sinfo->txrate; 7097 + sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_BITRATE); 7098 + } 7099 + if ((link_sinfo->filled & 7100 + BIT_ULL(NL80211_STA_INFO_RX_BITRATE)) && 7101 + (!init || 7102 + link_inactive_time > link_sinfo->inactive_time)) { 7103 + sinfo->rxrate = link_sinfo->rxrate; 7104 + sinfo->filled |= BIT_ULL(NL80211_STA_INFO_RX_BITRATE); 7105 + } 7106 + 7107 + if (link_sinfo->filled & 7108 + BIT_ULL(NL80211_STA_INFO_TX_DURATION) && 7109 + (!init || 7110 + link_inactive_time > link_sinfo->inactive_time)) { 7111 + sinfo->tx_duration += link_sinfo->tx_duration; 7112 + sinfo->filled |= 7113 + BIT_ULL(NL80211_STA_INFO_TX_DURATION); 7114 + } 7115 + if (link_sinfo->filled & 7116 + BIT_ULL(NL80211_STA_INFO_RX_DURATION) && 7117 + (!init || 7118 + link_inactive_time > link_sinfo->inactive_time)) { 7119 + sinfo->rx_duration += link_sinfo->rx_duration; 7120 + sinfo->filled |= 7121 + BIT_ULL(NL80211_STA_INFO_RX_DURATION); 7122 + } 7123 + init++; 7124 + 7125 + /* pertid stats accumulate for rx/tx fields */ 7126 + if (sinfo->pertid) { 7127 + sinfo->pertid->rx_msdu += 7128 + link_sinfo->pertid->rx_msdu; 7129 + sinfo->pertid->tx_msdu += 7130 + link_sinfo->pertid->tx_msdu; 7131 + sinfo->pertid->tx_msdu_retries += 7132 + link_sinfo->pertid->tx_msdu_retries; 7133 + sinfo->pertid->tx_msdu_failed += 7134 + link_sinfo->pertid->tx_msdu_failed; 7135 + 7136 + sinfo->pertid->filled |= 7137 + BIT(NL80211_TID_STATS_RX_MSDU) | 7138 + BIT(NL80211_TID_STATS_TX_MSDU) | 7139 + BIT(NL80211_TID_STATS_TX_MSDU_RETRIES) | 7140 + BIT(NL80211_TID_STATS_TX_MSDU_FAILED); 7141 + } 7142 + } 7143 + 7144 + /* Reset sinfo->filled bits to exclude fields which don't make 7145 + * much sense at the MLO level. 7146 + */ 7147 + sinfo->filled &= ~BIT_ULL(NL80211_STA_INFO_CHAIN_SIGNAL); 7148 + sinfo->filled &= ~BIT_ULL(NL80211_STA_INFO_CHAIN_SIGNAL_AVG); 7149 + } 7150 + 7255 7151 static int nl80211_dump_station(struct sk_buff *skb, 7256 7152 struct netlink_callback *cb) 7257 7153 { ··· 7448 6968 struct wireless_dev *wdev; 7449 6969 u8 mac_addr[ETH_ALEN]; 7450 6970 int sta_idx = cb->args[2]; 7451 - int err; 6971 + int err, i; 7452 6972 7453 6973 err = nl80211_prepare_wdev_dump(cb, &rdev, &wdev, NULL); 7454 6974 if (err) ··· 7468 6988 7469 6989 while (1) { 7470 6990 memset(&sinfo, 0, sizeof(sinfo)); 6991 + 6992 + for (i = 0; i < IEEE80211_MLD_MAX_NUM_LINKS; i++) { 6993 + sinfo.links[i] = 6994 + kzalloc(sizeof(*sinfo.links[0]), GFP_KERNEL); 6995 + if (!sinfo.links[i]) { 6996 + err = -ENOMEM; 6997 + goto out_err; 6998 + } 6999 + } 7000 + 7471 7001 err = rdev_dump_station(rdev, wdev->netdev, sta_idx, 7472 7002 mac_addr, &sinfo); 7473 7003 if (err == -ENOENT) 7474 7004 break; 7475 7005 if (err) 7476 7006 goto out_err; 7007 + 7008 + if (sinfo.valid_links) 7009 + cfg80211_sta_set_mld_sinfo(&sinfo); 7477 7010 7478 7011 if (nl80211_send_station(skb, NL80211_CMD_NEW_STATION, 7479 7012 NETLINK_CB(cb->skb).portid, ··· 7502 7009 cb->args[2] = sta_idx; 7503 7010 err = skb->len; 7504 7011 out_err: 7012 + cfg80211_sinfo_release_content(&sinfo); 7505 7013 wiphy_unlock(&rdev->wiphy); 7506 7014 7507 7015 return err; ··· 7515 7021 struct station_info sinfo; 7516 7022 struct sk_buff *msg; 7517 7023 u8 *mac_addr = NULL; 7518 - int err; 7024 + int err, i; 7519 7025 7520 7026 memset(&sinfo, 0, sizeof(sinfo)); 7521 7027 ··· 7527 7033 if (!rdev->ops->get_station) 7528 7034 return -EOPNOTSUPP; 7529 7035 7036 + for (i = 0; i < IEEE80211_MLD_MAX_NUM_LINKS; i++) { 7037 + sinfo.links[i] = kzalloc(sizeof(*sinfo.links[0]), GFP_KERNEL); 7038 + if (!sinfo.links[i]) { 7039 + cfg80211_sinfo_release_content(&sinfo); 7040 + return -ENOMEM; 7041 + } 7042 + } 7043 + 7530 7044 err = rdev_get_station(rdev, dev, mac_addr, &sinfo); 7531 - if (err) 7045 + if (err) { 7046 + cfg80211_sinfo_release_content(&sinfo); 7532 7047 return err; 7048 + } 7533 7049 7534 7050 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); 7535 7051 if (!msg) { 7536 7052 cfg80211_sinfo_release_content(&sinfo); 7537 7053 return -ENOMEM; 7538 7054 } 7055 + 7056 + if (sinfo.valid_links) 7057 + cfg80211_sta_set_mld_sinfo(&sinfo); 7539 7058 7540 7059 if (nl80211_send_station(msg, NL80211_CMD_NEW_STATION, 7541 7060 info->snd_portid, info->snd_seq, 0, ··· 7855 7348 return -EINVAL; 7856 7349 } 7857 7350 } 7351 + 7352 + if (info->attrs[NL80211_ATTR_S1G_CAPABILITY]) 7353 + params->link_sta_params.s1g_capa = 7354 + nla_data(info->attrs[NL80211_ATTR_S1G_CAPABILITY]); 7858 7355 7859 7356 err = nl80211_parse_sta_channel_info(info, params); 7860 7357 if (err) ··· 8185 7674 if (info->attrs[NL80211_ATTR_HE_6GHZ_CAPABILITY]) 8186 7675 params.link_sta_params.he_6ghz_capa = 8187 7676 nla_data(info->attrs[NL80211_ATTR_HE_6GHZ_CAPABILITY]); 7677 + 7678 + if (info->attrs[NL80211_ATTR_S1G_CAPABILITY]) 7679 + params.link_sta_params.s1g_capa = 7680 + nla_data(info->attrs[NL80211_ATTR_S1G_CAPABILITY]); 8188 7681 8189 7682 if (info->attrs[NL80211_ATTR_OPMODE_NOTIF]) { 8190 7683 params.link_sta_params.opmode_notif_used = true;
+22 -17
net/wireless/rdev-ops.h
··· 577 577 } 578 578 579 579 static inline int 580 - rdev_set_wiphy_params(struct cfg80211_registered_device *rdev, u32 changed) 580 + rdev_set_wiphy_params(struct cfg80211_registered_device *rdev, int radio_idx, 581 + u32 changed) 581 582 { 582 583 int ret = -EOPNOTSUPP; 583 584 584 - trace_rdev_set_wiphy_params(&rdev->wiphy, changed); 585 + trace_rdev_set_wiphy_params(&rdev->wiphy, radio_idx, changed); 585 586 if (rdev->ops->set_wiphy_params) 586 - ret = rdev->ops->set_wiphy_params(&rdev->wiphy, changed); 587 + ret = rdev->ops->set_wiphy_params(&rdev->wiphy, radio_idx, 588 + changed); 587 589 trace_rdev_return_int(&rdev->wiphy, ret); 588 590 return ret; 589 591 } 590 592 591 593 static inline int rdev_set_tx_power(struct cfg80211_registered_device *rdev, 592 - struct wireless_dev *wdev, 593 - enum nl80211_tx_power_setting type, int mbm) 594 + struct wireless_dev *wdev, int radio_idx, 595 + enum nl80211_tx_power_setting type, 596 + int mbm) 594 597 { 595 598 int ret; 596 - trace_rdev_set_tx_power(&rdev->wiphy, wdev, type, mbm); 597 - ret = rdev->ops->set_tx_power(&rdev->wiphy, wdev, type, mbm); 599 + trace_rdev_set_tx_power(&rdev->wiphy, wdev, radio_idx, type, mbm); 600 + ret = rdev->ops->set_tx_power(&rdev->wiphy, wdev, radio_idx, type, 601 + mbm); 598 602 trace_rdev_return_int(&rdev->wiphy, ret); 599 603 return ret; 600 604 } 601 605 602 606 static inline int rdev_get_tx_power(struct cfg80211_registered_device *rdev, 603 - struct wireless_dev *wdev, unsigned int link_id, 604 - int *dbm) 607 + struct wireless_dev *wdev, int radio_idx, 608 + unsigned int link_id, int *dbm) 605 609 { 606 610 int ret; 607 - trace_rdev_get_tx_power(&rdev->wiphy, wdev, link_id); 608 - ret = rdev->ops->get_tx_power(&rdev->wiphy, wdev, link_id, dbm); 611 + trace_rdev_get_tx_power(&rdev->wiphy, wdev, radio_idx, link_id); 612 + ret = rdev->ops->get_tx_power(&rdev->wiphy, wdev, radio_idx, link_id, 613 + dbm); 609 614 trace_rdev_return_int_int(&rdev->wiphy, ret, *dbm); 610 615 return ret; 611 616 } ··· 862 857 } 863 858 864 859 static inline int rdev_set_antenna(struct cfg80211_registered_device *rdev, 865 - u32 tx_ant, u32 rx_ant) 860 + int radio_idx, u32 tx_ant, u32 rx_ant) 866 861 { 867 862 int ret; 868 - trace_rdev_set_antenna(&rdev->wiphy, tx_ant, rx_ant); 869 - ret = rdev->ops->set_antenna(&rdev->wiphy, tx_ant, rx_ant); 863 + trace_rdev_set_antenna(&rdev->wiphy, radio_idx, tx_ant, rx_ant); 864 + ret = rdev->ops->set_antenna(&rdev->wiphy, -1, tx_ant, rx_ant); 870 865 trace_rdev_return_int(&rdev->wiphy, ret); 871 866 return ret; 872 867 } 873 868 874 869 static inline int rdev_get_antenna(struct cfg80211_registered_device *rdev, 875 - u32 *tx_ant, u32 *rx_ant) 870 + int radio_idx, u32 *tx_ant, u32 *rx_ant) 876 871 { 877 872 int ret; 878 - trace_rdev_get_antenna(&rdev->wiphy); 879 - ret = rdev->ops->get_antenna(&rdev->wiphy, tx_ant, rx_ant); 873 + trace_rdev_get_antenna(&rdev->wiphy, radio_idx); 874 + ret = rdev->ops->get_antenna(&rdev->wiphy, radio_idx, tx_ant, rx_ant); 880 875 if (ret) 881 876 trace_rdev_return_int(&rdev->wiphy, ret); 882 877 else
+61 -28
net/wireless/trace.h
··· 406 406 TP_ARGS(wiphy) 407 407 ); 408 408 409 - DEFINE_EVENT(wiphy_only_evt, rdev_get_antenna, 410 - TP_PROTO(struct wiphy *wiphy), 411 - TP_ARGS(wiphy) 409 + TRACE_EVENT(rdev_get_antenna, 410 + TP_PROTO(struct wiphy *wiphy, int radio_idx), 411 + TP_ARGS(wiphy, radio_idx), 412 + TP_STRUCT__entry( 413 + WIPHY_ENTRY 414 + __field(int, radio_idx) 415 + ), 416 + TP_fast_assign( 417 + WIPHY_ASSIGN; 418 + __entry->radio_idx = radio_idx; 419 + ), 420 + TP_printk(WIPHY_PR_FMT ", radio_idx: %d", 421 + WIPHY_PR_ARG, __entry->radio_idx) 412 422 ); 413 423 414 424 DEFINE_EVENT(wiphy_only_evt, rdev_rfkill_poll, ··· 1688 1678 ); 1689 1679 1690 1680 TRACE_EVENT(rdev_set_wiphy_params, 1691 - TP_PROTO(struct wiphy *wiphy, u32 changed), 1692 - TP_ARGS(wiphy, changed), 1681 + TP_PROTO(struct wiphy *wiphy, int radio_idx, u32 changed), 1682 + TP_ARGS(wiphy, radio_idx, changed), 1693 1683 TP_STRUCT__entry( 1694 1684 WIPHY_ENTRY 1685 + __field(int, radio_idx) 1695 1686 __field(u32, changed) 1696 1687 ), 1697 1688 TP_fast_assign( 1698 1689 WIPHY_ASSIGN; 1690 + __entry->radio_idx = radio_idx; 1699 1691 __entry->changed = changed; 1700 1692 ), 1701 - TP_printk(WIPHY_PR_FMT ", changed: %u", 1702 - WIPHY_PR_ARG, __entry->changed) 1693 + TP_printk(WIPHY_PR_FMT ", radio_idx: %d, changed: %u", 1694 + WIPHY_PR_ARG, __entry->radio_idx, __entry->changed) 1703 1695 ); 1704 1696 1705 1697 DECLARE_EVENT_CLASS(wiphy_wdev_link_evt, ··· 1722 1710 WIPHY_PR_ARG, WDEV_PR_ARG, __entry->link_id) 1723 1711 ); 1724 1712 1725 - DEFINE_EVENT(wiphy_wdev_link_evt, rdev_get_tx_power, 1713 + TRACE_EVENT(rdev_get_tx_power, 1726 1714 TP_PROTO(struct wiphy *wiphy, struct wireless_dev *wdev, 1727 - unsigned int link_id), 1728 - TP_ARGS(wiphy, wdev, link_id) 1715 + int radio_idx, unsigned int link_id), 1716 + TP_ARGS(wiphy, wdev, radio_idx, link_id), 1717 + TP_STRUCT__entry( 1718 + WIPHY_ENTRY 1719 + WDEV_ENTRY 1720 + __field(int, radio_idx) 1721 + __field(unsigned int, link_id) 1722 + ), 1723 + TP_fast_assign( 1724 + WIPHY_ASSIGN; 1725 + WDEV_ASSIGN; 1726 + __entry->radio_idx = radio_idx; 1727 + __entry->link_id = link_id; 1728 + ), 1729 + TP_printk(WIPHY_PR_FMT ", " WDEV_PR_FMT 1730 + ", radio_idx: %d, link_id: %u", 1731 + WIPHY_PR_ARG, WDEV_PR_ARG, 1732 + __entry->radio_idx, __entry->link_id) 1729 1733 ); 1730 1734 1731 1735 TRACE_EVENT(rdev_set_tx_power, 1732 1736 TP_PROTO(struct wiphy *wiphy, struct wireless_dev *wdev, 1733 - enum nl80211_tx_power_setting type, int mbm), 1734 - TP_ARGS(wiphy, wdev, type, mbm), 1737 + int radio_idx, enum nl80211_tx_power_setting type, 1738 + int mbm), 1739 + TP_ARGS(wiphy, wdev, radio_idx, type, mbm), 1735 1740 TP_STRUCT__entry( 1736 1741 WIPHY_ENTRY 1737 1742 WDEV_ENTRY 1743 + __field(int, radio_idx) 1738 1744 __field(enum nl80211_tx_power_setting, type) 1739 1745 __field(int, mbm) 1740 1746 ), 1741 1747 TP_fast_assign( 1742 1748 WIPHY_ASSIGN; 1743 1749 WDEV_ASSIGN; 1750 + __entry->radio_idx = radio_idx; 1744 1751 __entry->type = type; 1745 1752 __entry->mbm = mbm; 1746 1753 ), 1747 - TP_printk(WIPHY_PR_FMT ", " WDEV_PR_FMT ", type: %u, mbm: %d", 1748 - WIPHY_PR_ARG, WDEV_PR_ARG,__entry->type, __entry->mbm) 1754 + TP_printk(WIPHY_PR_FMT ", " WDEV_PR_FMT 1755 + ", radio_idx: %d, type: %u, mbm: %d", 1756 + WIPHY_PR_ARG, WDEV_PR_ARG, 1757 + __entry->radio_idx, __entry->type, __entry->mbm) 1749 1758 ); 1750 1759 1751 1760 TRACE_EVENT(rdev_return_int_int, ··· 1899 1866 __entry->rx_max) 1900 1867 ); 1901 1868 1902 - DECLARE_EVENT_CLASS(tx_rx_evt, 1903 - TP_PROTO(struct wiphy *wiphy, u32 tx, u32 rx), 1904 - TP_ARGS(wiphy, tx, rx), 1869 + TRACE_EVENT(rdev_set_antenna, 1870 + TP_PROTO(struct wiphy *wiphy, int radio_idx, u32 tx, u32 rx), 1871 + TP_ARGS(wiphy, radio_idx, tx, rx), 1905 1872 TP_STRUCT__entry( 1906 1873 WIPHY_ENTRY 1874 + __field(int, radio_idx) 1907 1875 __field(u32, tx) 1908 1876 __field(u32, rx) 1909 1877 ), 1910 1878 TP_fast_assign( 1911 1879 WIPHY_ASSIGN; 1880 + __entry->radio_idx = radio_idx; 1912 1881 __entry->tx = tx; 1913 1882 __entry->rx = rx; 1914 1883 ), 1915 - TP_printk(WIPHY_PR_FMT ", tx: %u, rx: %u ", 1916 - WIPHY_PR_ARG, __entry->tx, __entry->rx) 1917 - ); 1918 - 1919 - DEFINE_EVENT(tx_rx_evt, rdev_set_antenna, 1920 - TP_PROTO(struct wiphy *wiphy, u32 tx, u32 rx), 1921 - TP_ARGS(wiphy, tx, rx) 1884 + TP_printk(WIPHY_PR_FMT ", radio_idx: %d, tx: %u, rx: %u ", 1885 + WIPHY_PR_ARG, __entry->radio_idx, 1886 + __entry->tx, __entry->rx) 1922 1887 ); 1923 1888 1924 1889 DECLARE_EVENT_CLASS(wiphy_netdev_id_evt, ··· 4157 4126 4158 4127 TRACE_EVENT(cfg80211_mlo_reconf_add_done, 4159 4128 TP_PROTO(struct net_device *netdev, u16 link_mask, 4160 - const u8 *buf, size_t len), 4161 - TP_ARGS(netdev, link_mask, buf, len), 4129 + const u8 *buf, size_t len, bool driver_initiated), 4130 + TP_ARGS(netdev, link_mask, buf, len, driver_initiated), 4162 4131 TP_STRUCT__entry( 4163 4132 NETDEV_ENTRY 4164 4133 __field(u16, link_mask) 4165 4134 __dynamic_array(u8, buf, len) 4135 + __field(bool, driver_initiated) 4166 4136 ), 4167 4137 TP_fast_assign( 4168 4138 NETDEV_ASSIGN; 4169 4139 __entry->link_mask = link_mask; 4170 4140 memcpy(__get_dynamic_array(buf), buf, len); 4141 + __entry->driver_initiated = driver_initiated; 4171 4142 ), 4172 - TP_printk(NETDEV_PR_FMT ", link_mask:0x%x", 4173 - NETDEV_PR_ARG, __entry->link_mask) 4143 + TP_printk(NETDEV_PR_FMT ", link_mask:0x%x, driver_initiated:%d", 4144 + NETDEV_PR_ARG, __entry->link_mask, __entry->driver_initiated) 4174 4145 ); 4175 4146 4176 4147 TRACE_EVENT(rdev_assoc_ml_reconf,
+36
net/wireless/util.c
··· 2516 2516 } 2517 2517 EXPORT_SYMBOL(cfg80211_check_combinations); 2518 2518 2519 + int cfg80211_get_radio_idx_by_chan(struct wiphy *wiphy, 2520 + const struct ieee80211_channel *chan) 2521 + { 2522 + const struct wiphy_radio *radio; 2523 + int i, j; 2524 + u32 freq; 2525 + 2526 + if (!chan) 2527 + return -EINVAL; 2528 + 2529 + freq = ieee80211_channel_to_khz(chan); 2530 + for (i = 0; i < wiphy->n_radio; i++) { 2531 + radio = &wiphy->radio[i]; 2532 + for (j = 0; j < radio->n_freq_range; j++) { 2533 + if (freq >= radio->freq_range[j].start_freq && 2534 + freq < radio->freq_range[j].end_freq) 2535 + return i; 2536 + } 2537 + } 2538 + 2539 + return -ENOENT; 2540 + } 2541 + EXPORT_SYMBOL(cfg80211_get_radio_idx_by_chan); 2542 + 2519 2543 int ieee80211_get_ratemask(struct ieee80211_supported_band *sband, 2520 2544 const u8 *rates, unsigned int n_rates, 2521 2545 u32 *mask) ··· 2649 2625 2650 2626 return false; 2651 2627 } 2628 + 2629 + int cfg80211_link_sinfo_alloc_tid_stats(struct link_station_info *link_sinfo, 2630 + gfp_t gfp) 2631 + { 2632 + link_sinfo->pertid = kcalloc(IEEE80211_NUM_TIDS + 1, 2633 + sizeof(*link_sinfo->pertid), gfp); 2634 + if (!link_sinfo->pertid) 2635 + return -ENOMEM; 2636 + 2637 + return 0; 2638 + } 2639 + EXPORT_SYMBOL(cfg80211_link_sinfo_alloc_tid_stats); 2652 2640 2653 2641 int cfg80211_sinfo_alloc_tid_stats(struct station_info *sinfo, gfp_t gfp) 2654 2642 {
+5 -5
net/wireless/wext-compat.c
··· 263 263 else 264 264 wdev->wiphy->rts_threshold = rts->value; 265 265 266 - err = rdev_set_wiphy_params(rdev, WIPHY_PARAM_RTS_THRESHOLD); 266 + err = rdev_set_wiphy_params(rdev, -1, WIPHY_PARAM_RTS_THRESHOLD); 267 267 if (err) 268 268 wdev->wiphy->rts_threshold = orts; 269 269 return err; ··· 304 304 wdev->wiphy->frag_threshold = frag->value & ~0x1; 305 305 } 306 306 307 - err = rdev_set_wiphy_params(rdev, WIPHY_PARAM_FRAG_THRESHOLD); 307 + err = rdev_set_wiphy_params(rdev, -1, WIPHY_PARAM_FRAG_THRESHOLD); 308 308 if (err) 309 309 wdev->wiphy->frag_threshold = ofrag; 310 310 return err; ··· 355 355 changed |= WIPHY_PARAM_RETRY_SHORT; 356 356 } 357 357 358 - err = rdev_set_wiphy_params(rdev, changed); 358 + err = rdev_set_wiphy_params(rdev, -1, changed); 359 359 if (err) { 360 360 wdev->wiphy->retry_short = oshort; 361 361 wdev->wiphy->retry_long = olong; ··· 890 890 891 891 guard(wiphy)(&rdev->wiphy); 892 892 893 - return rdev_set_tx_power(rdev, wdev, type, DBM_TO_MBM(dbm)); 893 + return rdev_set_tx_power(rdev, wdev, -1, type, DBM_TO_MBM(dbm)); 894 894 } 895 895 896 896 static int cfg80211_wext_giwtxpower(struct net_device *dev, ··· 910 910 return -EOPNOTSUPP; 911 911 912 912 scoped_guard(wiphy, &rdev->wiphy) { 913 - err = rdev_get_tx_power(rdev, wdev, 0, &val); 913 + err = rdev_get_tx_power(rdev, wdev, -1, 0, &val); 914 914 } 915 915 if (err) 916 916 return err;