--- /dev/null
+--- a/ath10k-6.4/mac.c
++++ b/ath10k-6.4/mac.c
+@@ -2310,8 +2310,8 @@ static void ath10k_mac_vif_ap_csa_count_
+ if (!arvif->is_up)
+ return;
+
+- if (!ieee80211_beacon_cntdwn_is_complete(vif)) {
+- ieee80211_beacon_update_cntdwn(vif);
++ if (!ieee80211_beacon_cntdwn_is_complete(vif, 0)) {
++ ieee80211_beacon_update_cntdwn(vif, 0);
+
+ ret = ath10k_mac_setup_bcn_tmpl(arvif);
+ if (ret)
+@@ -2323,7 +2323,7 @@ static void ath10k_mac_vif_ap_csa_count_
+ ath10k_warn(ar, "failed to update prb tmpl during csa: %d\n",
+ ret);
+ } else {
+- ieee80211_csa_finish(vif);
++ ieee80211_csa_finish(vif, 0);
+ }
+ }
+
+--- a/ath10k-6.4/wmi.c
++++ b/ath10k-6.4/wmi.c
+@@ -4284,8 +4284,8 @@ void ath10k_wmi_event_host_swba(struct a
+ * actual channel switch is done
+ */
+ if (arvif->vif->bss_conf.csa_active &&
+- ieee80211_beacon_cntdwn_is_complete(arvif->vif)) {
+- ieee80211_csa_finish(arvif->vif);
++ ieee80211_beacon_cntdwn_is_complete(arvif->vif, 0)) {
++ ieee80211_csa_finish(arvif->vif, 0);
+ continue;
+ }
+
PKG_NAME:=mac80211
-PKG_VERSION:=6.6.15
+PKG_VERSION:=6.9.1
PKG_RELEASE:=1
PKG_LICENSE:=GPL-2.0-only
PKG_LICENSE_FILES:=COPYING
PKG_SOURCE_URL:=http://mirror2.openwrt.org/sources/
-PKG_HASH:=3bbc461121134fda9089c084a5eed577d05e7837a157edf9a3797937172a3ece
+PKG_HASH:=6bb29f9788db8c3528701ddbdb62af5c31d06bc65ce1da0b811603e8cb6fd6c7
PKG_SOURCE:=backports-$(PKG_VERSION).tar.xz
PKG_BUILD_DIR:=$(KERNEL_BUILD_DIR)/$(if $(BUILD_VARIANT),$(PKG_NAME)-$(BUILD_VARIANT)/)backports-$(PKG_VERSION)
$(call KernelPackage/mac80211/Default)
TITLE:=Qualcomm 802.11ax wireless chipset support (common code)
URL:=https://wireless.wiki.kernel.org/en/users/drivers/ath11k
- DEPENDS+= +kmod-ath +@DRIVER_11AC_SUPPORT +@DRIVER_11AX_SUPPORT \
+ DEPENDS+= +kmod-ath +@DRIVER_11AC_SUPPORT +@DRIVER_11AX_SUPPORT @!LINUX_5_15 @!LINUX_6_1 \
+kmod-crypto-michael-mic +ATH11K_THERMAL:kmod-hwmon-core +ATH11K_THERMAL:kmod-thermal
FILES:=$(PKG_BUILD_DIR)/drivers/soc/qcom/qmi_helpers.ko \
$(PKG_BUILD_DIR)/drivers/net/wireless/ath/ath11k/ath11k.ko
define KernelPackage/iwlwifi
$(call KernelPackage/mac80211/Default)
- DEPENDS:= +kmod-mac80211 +kmod-ptp @PCI_SUPPORT +@DRIVER_11AC_SUPPORT +@DRIVER_11AX_SUPPORT
+ DEPENDS:= +kmod-mac80211 +kmod-ptp @PCI_SUPPORT +@DRIVER_11AC_SUPPORT +@DRIVER_11AX_SUPPORT @!LINUX_5_15 @!LINUX_6_1
TITLE:=Intel AGN Wireless support
FILES:= \
$(PKG_BUILD_DIR)/drivers/net/wireless/intel/iwlwifi/iwlwifi.ko \
help
--- a/local-symbols
+++ b/local-symbols
-@@ -101,6 +101,7 @@ ADM8211=
+@@ -100,6 +100,7 @@ ADM8211=
ATH_COMMON=
WLAN_VENDOR_ATH=
ATH_DEBUG=
--- a/net/wireless/reg.c
+++ b/net/wireless/reg.c
-@@ -3340,6 +3340,8 @@ void regulatory_hint_country_ie(struct w
+@@ -3364,6 +3364,8 @@ void regulatory_hint_country_ie(struct w
enum environment_cap env = ENVIRON_ANY;
struct regulatory_request *request = NULL, *lr;
/* IE len must be evenly divisible by 2 */
if (country_ie_len & 0x01)
return;
-@@ -3591,6 +3593,7 @@ static bool is_wiphy_all_set_reg_flag(en
+@@ -3615,6 +3617,7 @@ static bool is_wiphy_all_set_reg_flag(en
void regulatory_hint_disconnect(void)
{
static bool
ath5k_pci_eeprom_read(struct ath_common *common, u32 offset, u16 *data)
@@ -79,6 +80,19 @@ ath5k_pci_eeprom_read(struct ath_common
- struct ath5k_hw *ah = (struct ath5k_hw *) common->ah;
+ struct ath5k_hw *ah = common->ah;
u32 status, timeout;
+ struct ath5k_platform_data *pdata = NULL;
void ath10k_thermal_event_temperature(struct ath10k *ar, int temperature);
--- a/local-symbols
+++ b/local-symbols
-@@ -160,6 +160,7 @@ ATH10K_SNOC=
+@@ -159,6 +159,7 @@ ATH10K_SNOC=
ATH10K_DEBUG=
ATH10K_DEBUGFS=
ATH10K_SPECTRAL=
--- a/drivers/net/wireless/ath/ath10k/core.c
+++ b/drivers/net/wireless/ath/ath10k/core.c
-@@ -3507,6 +3507,16 @@ int ath10k_core_register(struct ath10k *
+@@ -3524,6 +3524,16 @@ int ath10k_core_register(struct ath10k *
queue_work(ar->workqueue, &ar->register_work);
--- a/drivers/net/wireless/ath/ath10k/mac.c
+++ b/drivers/net/wireless/ath/ath10k/mac.c
-@@ -9917,6 +9917,21 @@ static int ath10k_mac_init_rd(struct ath
+@@ -9918,6 +9918,21 @@ static int ath10k_mac_init_rd(struct ath
return 0;
}
int ath10k_mac_register(struct ath10k *ar)
{
static const u32 cipher_suites[] = {
-@@ -10275,6 +10290,12 @@ int ath10k_mac_register(struct ath10k *a
+@@ -10280,6 +10295,12 @@ int ath10k_mac_register(struct ath10k *a
ar->hw->weight_multiplier = ATH10K_AIRTIME_WEIGHT_MULTIPLIER;
ath10k_core-$(CONFIG_DEV_COREDUMP) += coredump.o
--- a/local-symbols
+++ b/local-symbols
-@@ -161,6 +161,7 @@ ATH10K_DEBUG=
+@@ -160,6 +160,7 @@ ATH10K_DEBUG=
ATH10K_DEBUGFS=
ATH10K_SPECTRAL=
ATH10K_THERMAL=
WCN36XX=
--- a/drivers/net/wireless/ath/ath10k/core.c
+++ b/drivers/net/wireless/ath/ath10k/core.c
-@@ -26,6 +26,7 @@
+@@ -27,6 +27,7 @@
#include "testmode.h"
#include "wmi-ops.h"
#include "coredump.h"
unsigned int ath10k_debug_mask;
EXPORT_SYMBOL(ath10k_debug_mask);
-@@ -65,6 +66,7 @@ static const struct ath10k_hw_params ath
+@@ -66,6 +67,7 @@ static const struct ath10k_hw_params ath
.dev_id = QCA988X_2_0_DEVICE_ID,
.bus = ATH10K_BUS_PCI,
.name = "qca988x hw2.0",
.patch_load_addr = QCA988X_HW_2_0_PATCH_LOAD_ADDR,
.uart_pin = 7,
.cc_wraparound_type = ATH10K_HW_CC_WRAP_SHIFTED_ALL,
-@@ -146,6 +148,7 @@ static const struct ath10k_hw_params ath
+@@ -149,6 +151,7 @@ static const struct ath10k_hw_params ath
.dev_id = QCA9887_1_0_DEVICE_ID,
.bus = ATH10K_BUS_PCI,
.name = "qca9887 hw1.0",
.patch_load_addr = QCA9887_HW_1_0_PATCH_LOAD_ADDR,
.uart_pin = 7,
.cc_wraparound_type = ATH10K_HW_CC_WRAP_SHIFTED_ALL,
-@@ -387,6 +390,7 @@ static const struct ath10k_hw_params ath
+@@ -396,6 +399,7 @@ static const struct ath10k_hw_params ath
.dev_id = QCA99X0_2_0_DEVICE_ID,
.bus = ATH10K_BUS_PCI,
.name = "qca99x0 hw2.0",
.patch_load_addr = QCA99X0_HW_2_0_PATCH_LOAD_ADDR,
.uart_pin = 7,
.otp_exe_param = 0x00000700,
-@@ -433,6 +437,7 @@ static const struct ath10k_hw_params ath
+@@ -443,6 +447,7 @@ static const struct ath10k_hw_params ath
.dev_id = QCA9984_1_0_DEVICE_ID,
.bus = ATH10K_BUS_PCI,
.name = "qca9984/qca9994 hw1.0",
.patch_load_addr = QCA9984_HW_1_0_PATCH_LOAD_ADDR,
.uart_pin = 7,
.cc_wraparound_type = ATH10K_HW_CC_WRAP_SHIFTED_EACH,
-@@ -486,6 +491,7 @@ static const struct ath10k_hw_params ath
+@@ -497,6 +502,7 @@ static const struct ath10k_hw_params ath
.dev_id = QCA9888_2_0_DEVICE_ID,
.bus = ATH10K_BUS_PCI,
.name = "qca9888 hw2.0",
.patch_load_addr = QCA9888_HW_2_0_PATCH_LOAD_ADDR,
.uart_pin = 7,
.cc_wraparound_type = ATH10K_HW_CC_WRAP_SHIFTED_EACH,
-@@ -3222,6 +3228,10 @@ int ath10k_core_start(struct ath10k *ar,
+@@ -3239,6 +3245,10 @@ int ath10k_core_start(struct ath10k *ar,
goto err_hif_stop;
}
return 0;
err_hif_stop:
-@@ -3480,9 +3490,18 @@ static void ath10k_core_register_work(st
+@@ -3497,9 +3507,18 @@ static void ath10k_core_register_work(st
goto err_spectral_destroy;
}
err_spectral_destroy:
ath10k_spectral_destroy(ar);
err_debug_destroy:
-@@ -3528,6 +3547,8 @@ void ath10k_core_unregister(struct ath10
+@@ -3545,6 +3564,8 @@ void ath10k_core_unregister(struct ath10
if (!test_bit(ATH10K_FLAG_CORE_REGISTERED, &ar->dev_flags))
return;
* relayfs debugfs file cleanly. Otherwise the parent debugfs tree
--- a/drivers/net/wireless/ath/ath10k/core.h
+++ b/drivers/net/wireless/ath/ath10k/core.h
-@@ -14,6 +14,7 @@
+@@ -15,6 +15,7 @@
#include <linux/pci.h>
#include <linux/uuid.h>
#include <linux/time.h>
#include "htt.h"
#include "htc.h"
-@@ -1256,6 +1257,13 @@ struct ath10k {
+@@ -1257,6 +1258,13 @@ struct ath10k {
} testmode;
struct {
u32 fw_crash_counter;
--- a/drivers/net/wireless/ath/ath10k/hw.h
+++ b/drivers/net/wireless/ath/ath10k/hw.h
-@@ -519,6 +519,7 @@ struct ath10k_hw_params {
+@@ -520,6 +520,7 @@ struct ath10k_hw_params {
const char *name;
u32 patch_load_addr;
int uart_pin;
+#endif /* _LEDS_H_ */
--- a/drivers/net/wireless/ath/ath10k/mac.c
+++ b/drivers/net/wireless/ath/ath10k/mac.c
-@@ -24,6 +24,7 @@
+@@ -25,6 +25,7 @@
#include "wmi-tlv.h"
#include "wmi-ops.h"
#include "wow.h"
{
--- a/drivers/net/wireless/ath/ath10k/wmi-tlv.c
+++ b/drivers/net/wireless/ath/ath10k/wmi-tlv.c
-@@ -4601,6 +4601,8 @@ static const struct wmi_ops wmi_tlv_ops
+@@ -4606,6 +4606,8 @@ static const struct wmi_ops wmi_tlv_ops
.gen_echo = ath10k_wmi_tlv_op_gen_echo,
.gen_vdev_spectral_conf = ath10k_wmi_tlv_op_gen_vdev_spectral_conf,
.gen_vdev_spectral_enable = ath10k_wmi_tlv_op_gen_vdev_spectral_enable,
static const struct wmi_peer_flags_map wmi_tlv_peer_flags_map = {
--- a/drivers/net/wireless/ath/ath10k/wmi.c
+++ b/drivers/net/wireless/ath/ath10k/wmi.c
-@@ -7472,6 +7472,49 @@ ath10k_wmi_op_gen_peer_set_param(struct
+@@ -7473,6 +7473,49 @@ ath10k_wmi_op_gen_peer_set_param(struct
return skb;
}
static struct sk_buff *
ath10k_wmi_op_gen_set_psmode(struct ath10k *ar, u32 vdev_id,
enum wmi_sta_ps_mode psmode)
-@@ -9138,6 +9181,9 @@ static const struct wmi_ops wmi_ops = {
+@@ -9137,6 +9180,9 @@ static const struct wmi_ops wmi_ops = {
.fw_stats_fill = ath10k_wmi_main_op_fw_stats_fill,
.get_vdev_subtype = ath10k_wmi_op_get_vdev_subtype,
.gen_echo = ath10k_wmi_op_gen_echo,
/* .gen_bcn_tmpl not implemented */
/* .gen_prb_tmpl not implemented */
/* .gen_p2p_go_bcn_ie not implemented */
-@@ -9208,6 +9254,8 @@ static const struct wmi_ops wmi_10_1_ops
+@@ -9207,6 +9253,8 @@ static const struct wmi_ops wmi_10_1_ops
.fw_stats_fill = ath10k_wmi_10x_op_fw_stats_fill,
.get_vdev_subtype = ath10k_wmi_op_get_vdev_subtype,
.gen_echo = ath10k_wmi_op_gen_echo,
/* .gen_bcn_tmpl not implemented */
/* .gen_prb_tmpl not implemented */
/* .gen_p2p_go_bcn_ie not implemented */
-@@ -9280,6 +9328,8 @@ static const struct wmi_ops wmi_10_2_ops
+@@ -9279,6 +9327,8 @@ static const struct wmi_ops wmi_10_2_ops
.gen_delba_send = ath10k_wmi_op_gen_delba_send,
.fw_stats_fill = ath10k_wmi_10x_op_fw_stats_fill,
.get_vdev_subtype = ath10k_wmi_op_get_vdev_subtype,
/* .gen_pdev_enable_adaptive_cca not implemented */
};
-@@ -9351,6 +9401,8 @@ static const struct wmi_ops wmi_10_2_4_o
+@@ -9350,6 +9400,8 @@ static const struct wmi_ops wmi_10_2_4_o
ath10k_wmi_op_gen_pdev_enable_adaptive_cca,
.get_vdev_subtype = ath10k_wmi_10_2_4_op_get_vdev_subtype,
.gen_bb_timing = ath10k_wmi_10_2_4_op_gen_bb_timing,
/* .gen_bcn_tmpl not implemented */
/* .gen_prb_tmpl not implemented */
/* .gen_p2p_go_bcn_ie not implemented */
-@@ -9432,6 +9484,8 @@ static const struct wmi_ops wmi_10_4_ops
+@@ -9431,6 +9483,8 @@ static const struct wmi_ops wmi_10_4_ops
.gen_pdev_bss_chan_info_req = ath10k_wmi_10_2_op_gen_pdev_bss_chan_info,
.gen_echo = ath10k_wmi_op_gen_echo,
.gen_pdev_get_tpc_config = ath10k_wmi_10_2_4_op_gen_pdev_get_tpc_config,
int ath10k_wmi_attach(struct ath10k *ar)
--- a/drivers/net/wireless/ath/ath10k/wmi.h
+++ b/drivers/net/wireless/ath/ath10k/wmi.h
-@@ -3030,6 +3030,41 @@ enum wmi_10_4_feature_mask {
+@@ -3034,6 +3034,41 @@ enum wmi_10_4_feature_mask {
};
--- a/drivers/net/wireless/ath/ath10k/core.h
+++ b/drivers/net/wireless/ath/ath10k/core.h
-@@ -1312,6 +1312,10 @@ struct ath10k {
+@@ -1313,6 +1313,10 @@ struct ath10k {
s32 tx_power_2g_limit;
s32 tx_power_5g_limit;
if (ret)
--- a/drivers/net/wireless/ath/ath10k/mac.c
+++ b/drivers/net/wireless/ath/ath10k/mac.c
-@@ -10292,7 +10292,7 @@ int ath10k_mac_register(struct ath10k *a
+@@ -10297,7 +10297,7 @@ int ath10k_mac_register(struct ath10k *a
ar->hw->weight_multiplier = ATH10K_AIRTIME_WEIGHT_MULTIPLIER;
#ifdef CPTCFG_MAC80211_LEDS
--- a/drivers/net/wireless/ath/ath10k/mac.c
+++ b/drivers/net/wireless/ath/ath10k/mac.c
-@@ -1028,6 +1028,40 @@ static inline int ath10k_vdev_setup_sync
+@@ -1022,6 +1022,40 @@ static inline int ath10k_vdev_setup_sync
return ar->last_wmi_vdev_start_status;
}
static int ath10k_monitor_vdev_start(struct ath10k *ar, int vdev_id)
{
struct cfg80211_chan_def *chandef = NULL;
-@@ -1060,7 +1094,8 @@ static int ath10k_monitor_vdev_start(str
+@@ -1054,7 +1088,8 @@ static int ath10k_monitor_vdev_start(str
arg.channel.min_power = 0;
arg.channel.max_power = channel->max_power * 2;
arg.channel.max_reg_power = channel->max_reg_power * 2;
reinit_completion(&ar->vdev_setup_done);
reinit_completion(&ar->vdev_delete_done);
-@@ -1506,7 +1541,8 @@ static int ath10k_vdev_start_restart(str
+@@ -1500,7 +1535,8 @@ static int ath10k_vdev_start_restart(str
arg.channel.min_power = 0;
arg.channel.max_power = chandef->chan->max_power * 2;
arg.channel.max_reg_power = chandef->chan->max_reg_power * 2;
if (arvif->vdev_type == WMI_VDEV_TYPE_AP) {
arg.ssid = arvif->u.ap.ssid;
-@@ -3437,7 +3473,8 @@ static int ath10k_update_channel_list(st
+@@ -3431,7 +3467,8 @@ static int ath10k_update_channel_list(st
ch->min_power = 0;
ch->max_power = channel->max_power * 2;
ch->max_reg_power = channel->max_reg_power * 2;
--- a/drivers/net/wireless/ath/ath10k/core.c
+++ b/drivers/net/wireless/ath/ath10k/core.c
-@@ -8,6 +8,7 @@
+@@ -9,6 +9,7 @@
#include <linux/module.h>
#include <linux/firmware.h>
#include <linux/of.h>
#include <linux/property.h>
#include <linux/dmi.h>
#include <linux/ctype.h>
-@@ -3398,6 +3399,8 @@ static int ath10k_core_probe_fw(struct a
+@@ -3415,6 +3416,8 @@ static int ath10k_core_probe_fw(struct a
device_get_mac_address(ar->dev, ar->mac_addr);
--- a/drivers/net/wireless/ath/ath10k/mac.c
+++ b/drivers/net/wireless/ath/ath10k/mac.c
-@@ -10088,7 +10088,6 @@ int ath10k_mac_register(struct ath10k *a
+@@ -10089,7 +10089,6 @@ int ath10k_mac_register(struct ath10k *a
ieee80211_hw_set(ar->hw, CHANCTX_STA_CSA);
ieee80211_hw_set(ar->hw, QUEUE_CONTROL);
ieee80211_hw_set(ar->hw, SUPPORTS_TX_FRAG);
--- a/drivers/net/wireless/ath/ath10k/htt.h
+++ b/drivers/net/wireless/ath/ath10k/htt.h
-@@ -235,7 +235,11 @@ enum htt_rx_ring_flags {
+@@ -236,7 +236,11 @@ enum htt_rx_ring_flags {
};
#define HTT_RX_RING_SIZE_MIN 128
#define HTT_RX_RING_FILL_LEVEL_DUAL_MAC (HTT_RX_RING_SIZE - 1)
--- a/drivers/net/wireless/ath/ath10k/pci.c
+++ b/drivers/net/wireless/ath/ath10k/pci.c
-@@ -131,7 +131,11 @@ static const struct ce_attr pci_host_ce_
+@@ -132,7 +132,11 @@ static const struct ce_attr pci_host_ce_
.flags = CE_ATTR_FLAGS,
.src_nentries = 0,
.src_sz_max = 2048,
.recv_cb = ath10k_pci_htt_htc_rx_cb,
},
-@@ -140,7 +144,11 @@ static const struct ce_attr pci_host_ce_
+@@ -141,7 +145,11 @@ static const struct ce_attr pci_host_ce_
.flags = CE_ATTR_FLAGS,
.src_nentries = 0,
.src_sz_max = 2048,
.recv_cb = ath10k_pci_htc_rx_cb,
},
-@@ -167,7 +175,11 @@ static const struct ce_attr pci_host_ce_
+@@ -168,7 +176,11 @@ static const struct ce_attr pci_host_ce_
.flags = CE_ATTR_FLAGS,
.src_nentries = 0,
.src_sz_max = 512,
.recv_cb = ath10k_pci_htt_rx_cb,
},
-@@ -192,7 +204,11 @@ static const struct ce_attr pci_host_ce_
+@@ -193,7 +205,11 @@ static const struct ce_attr pci_host_ce_
.flags = CE_ATTR_FLAGS,
.src_nentries = 0,
.src_sz_max = 2048,
+++ /dev/null
-From 4a93b554cf9fa64faa7cf164c0d32fc3ce67108b Mon Sep 17 00:00:00 2001
-From: Arowa Suliman <arowa@chromium.org>
-Date: Sat, 26 Aug 2023 08:42:42 +0300
-Subject: [PATCH] wifi: ath11k: mhi: add a warning message for MHI_CB_EE_RDDM
- crash
-
-Currently, the ath11k driver does not print a crash signature when a
-MHI_CB_EE_RDDM crash happens. Checked by triggering a simulated crash using the
-command and checking dmesg for logs:
-
-echo assert > /sys/kernel/debug/ath11k/../simulate_fw_crash
-
-Add a warning when firmware crash MHI_CB_EE_RDDM happens.
-
-Tested-on: WCN6855 hw2.0 PCI WLAN.HSP.1.1-03125-QCAHSPSWPL_V1_V2_SILICONZ_LITE-3.6510.23
-
-Signed-off-by: Arowa Suliman <arowa@chromium.org>
-Reviewed-by: Jeff Johnson <quic_jjohnson@quicinc.com>
-Signed-off-by: Kalle Valo <quic_kvalo@quicinc.com>
-Link: https://lore.kernel.org/r/20230714001126.463127-1-arowa@chromium.org
----
- drivers/net/wireless/ath/ath11k/mhi.c | 1 +
- 1 file changed, 1 insertion(+)
-
---- a/drivers/net/wireless/ath/ath11k/mhi.c
-+++ b/drivers/net/wireless/ath/ath11k/mhi.c
-@@ -333,6 +333,7 @@ static void ath11k_mhi_op_status_cb(stru
- ath11k_warn(ab, "firmware crashed: MHI_CB_SYS_ERROR\n");
- break;
- case MHI_CB_EE_RDDM:
-+ ath11k_warn(ab, "firmware crashed: MHI_CB_EE_RDDM\n");
- if (!(test_bit(ATH11K_FLAG_UNREGISTERING, &ab->dev_flags)))
- queue_work(ab->workqueue_aux, &ab->reset_work);
- break;
+++ /dev/null
-From 5bd2ced044bb95029d5c44cf7d23ced73e0fc05b Mon Sep 17 00:00:00 2001
-From: Muna Sinada <quic_msinada@quicinc.com>
-Date: Sat, 26 Aug 2023 08:42:46 +0300
-Subject: [PATCH] wifi: ath11k: move references from rsvd2 to info fields
-
-Remove references to reserved fields and add new info fields for
-struct hal_rx_ppdu_end_user_stats. Reserved fields should not be
-accessed, therefore existing references to it are to be changed to
-referencing specific info fields.
-
-Tested-on: IPQ8074 hw2.0 AHB WLAN.HK.2.4.0.1-00356-QCAHKSWPL_SILICONZ-1
-
-Signed-off-by: Muna Sinada <quic_msinada@quicinc.com>
-Acked-by: Jeff Johnson <quic_jjohnson@quicinc.com>
-Signed-off-by: Kalle Valo <quic_kvalo@quicinc.com>
-Link: https://lore.kernel.org/r/1692827868-15667-1-git-send-email-quic_msinada@quicinc.com
----
- drivers/net/wireless/ath/ath11k/hal_rx.c | 10 +++++-----
- drivers/net/wireless/ath/ath11k/hal_rx.h | 11 ++++++++---
- 2 files changed, 13 insertions(+), 8 deletions(-)
-
---- a/drivers/net/wireless/ath/ath11k/hal_rx.c
-+++ b/drivers/net/wireless/ath/ath11k/hal_rx.c
-@@ -814,7 +814,7 @@ ath11k_hal_rx_handle_ofdma_info(void *rx
-
- rx_user_status->ul_ofdma_user_v0_word0 = __le32_to_cpu(ppdu_end_user->info6);
-
-- rx_user_status->ul_ofdma_user_v0_word1 = __le32_to_cpu(ppdu_end_user->rsvd2[10]);
-+ rx_user_status->ul_ofdma_user_v0_word1 = __le32_to_cpu(ppdu_end_user->info9);
- }
-
- static inline void
-@@ -825,11 +825,11 @@ ath11k_hal_rx_populate_byte_count(void *
- (struct hal_rx_ppdu_end_user_stats *)rx_tlv;
-
- rx_user_status->mpdu_ok_byte_count =
-- FIELD_GET(HAL_RX_PPDU_END_USER_STATS_RSVD2_6_MPDU_OK_BYTE_COUNT,
-- __le32_to_cpu(ppdu_end_user->rsvd2[6]));
-+ FIELD_GET(HAL_RX_PPDU_END_USER_STATS_INFO8_MPDU_OK_BYTE_COUNT,
-+ __le32_to_cpu(ppdu_end_user->info7));
- rx_user_status->mpdu_err_byte_count =
-- FIELD_GET(HAL_RX_PPDU_END_USER_STATS_RSVD2_8_MPDU_ERR_BYTE_COUNT,
-- __le32_to_cpu(ppdu_end_user->rsvd2[8]));
-+ FIELD_GET(HAL_RX_PPDU_END_USER_STATS_INFO9_MPDU_ERR_BYTE_COUNT,
-+ __le32_to_cpu(ppdu_end_user->info8));
- }
-
- static inline void
---- a/drivers/net/wireless/ath/ath11k/hal_rx.h
-+++ b/drivers/net/wireless/ath/ath11k/hal_rx.h
-@@ -222,8 +222,8 @@ struct hal_rx_ppdu_start {
- #define HAL_RX_PPDU_END_USER_STATS_INFO6_TID_BITMAP GENMASK(15, 0)
- #define HAL_RX_PPDU_END_USER_STATS_INFO6_TID_EOSP_BITMAP GENMASK(31, 16)
-
--#define HAL_RX_PPDU_END_USER_STATS_RSVD2_6_MPDU_OK_BYTE_COUNT GENMASK(24, 0)
--#define HAL_RX_PPDU_END_USER_STATS_RSVD2_8_MPDU_ERR_BYTE_COUNT GENMASK(24, 0)
-+#define HAL_RX_PPDU_END_USER_STATS_INFO7_MPDU_OK_BYTE_COUNT GENMASK(24, 0)
-+#define HAL_RX_PPDU_END_USER_STATS_INFO8_MPDU_ERR_BYTE_COUNT GENMASK(24, 0)
-
- struct hal_rx_ppdu_end_user_stats {
- __le32 rsvd0[2];
-@@ -236,7 +236,12 @@ struct hal_rx_ppdu_end_user_stats {
- __le32 info4;
- __le32 info5;
- __le32 info6;
-- __le32 rsvd2[11];
-+ __le32 rsvd2[5];
-+ __le32 info7;
-+ __le32 rsvd3;
-+ __le32 info8;
-+ __le32 rsvd3[2];
-+ __le32 info9;
- } __packed;
-
- struct hal_rx_ppdu_end_user_stats_ext {
+++ /dev/null
-From 7791487cd16cafd018cba0bf73789111a9f16843 Mon Sep 17 00:00:00 2001
-From: Muna Sinada <quic_msinada@quicinc.com>
-Date: Sat, 26 Aug 2023 08:42:46 +0300
-Subject: [PATCH] wifi: ath11k: fix tid bitmap is 0 in peer rx mu stats
-
-Correct parsing of reading offset for rx tid 16 bit bitmap. Incorrect
-offset caused peer rx mu stats tid bitmap to always be zero. This
-correction is in the software context and does not affect the
-firmware interface.
-
-Tested-on: IPQ8074 hw2.0 AHB WLAN.HK.2.4.0.1-00356-QCAHKSWPL_SILICONZ-1
-
-Signed-off-by: Muna Sinada <quic_msinada@quicinc.com>
-Acked-by: Jeff Johnson <quic_jjohnson@quicinc.com>
-Signed-off-by: Kalle Valo <quic_kvalo@quicinc.com>
-Link: https://lore.kernel.org/r/1692827868-15667-2-git-send-email-quic_msinada@quicinc.com
----
- drivers/net/wireless/ath/ath11k/hal_rx.c | 10 +++++-----
- drivers/net/wireless/ath/ath11k/hal_rx.h | 17 +++++++++--------
- 2 files changed, 14 insertions(+), 13 deletions(-)
-
---- a/drivers/net/wireless/ath/ath11k/hal_rx.c
-+++ b/drivers/net/wireless/ath/ath11k/hal_rx.c
-@@ -814,7 +814,7 @@ ath11k_hal_rx_handle_ofdma_info(void *rx
-
- rx_user_status->ul_ofdma_user_v0_word0 = __le32_to_cpu(ppdu_end_user->info6);
-
-- rx_user_status->ul_ofdma_user_v0_word1 = __le32_to_cpu(ppdu_end_user->info9);
-+ rx_user_status->ul_ofdma_user_v0_word1 = __le32_to_cpu(ppdu_end_user->info10);
- }
-
- static inline void
-@@ -826,10 +826,10 @@ ath11k_hal_rx_populate_byte_count(void *
-
- rx_user_status->mpdu_ok_byte_count =
- FIELD_GET(HAL_RX_PPDU_END_USER_STATS_INFO8_MPDU_OK_BYTE_COUNT,
-- __le32_to_cpu(ppdu_end_user->info7));
-+ __le32_to_cpu(ppdu_end_user->info8));
- rx_user_status->mpdu_err_byte_count =
- FIELD_GET(HAL_RX_PPDU_END_USER_STATS_INFO9_MPDU_ERR_BYTE_COUNT,
-- __le32_to_cpu(ppdu_end_user->info8));
-+ __le32_to_cpu(ppdu_end_user->info9));
- }
-
- static inline void
-@@ -903,8 +903,8 @@ ath11k_hal_rx_parse_mon_status_tlv(struc
- FIELD_GET(HAL_RX_PPDU_END_USER_STATS_INFO2_AST_INDEX,
- __le32_to_cpu(eu_stats->info2));
- ppdu_info->tid =
-- ffs(FIELD_GET(HAL_RX_PPDU_END_USER_STATS_INFO6_TID_BITMAP,
-- __le32_to_cpu(eu_stats->info6))) - 1;
-+ ffs(FIELD_GET(HAL_RX_PPDU_END_USER_STATS_INFO7_TID_BITMAP,
-+ __le32_to_cpu(eu_stats->info7))) - 1;
- ppdu_info->tcp_msdu_count =
- FIELD_GET(HAL_RX_PPDU_END_USER_STATS_INFO4_TCP_MSDU_CNT,
- __le32_to_cpu(eu_stats->info4));
---- a/drivers/net/wireless/ath/ath11k/hal_rx.h
-+++ b/drivers/net/wireless/ath/ath11k/hal_rx.h
-@@ -149,7 +149,7 @@ struct hal_rx_mon_ppdu_info {
- u8 beamformed;
- u8 rssi_comb;
- u8 rssi_chain_pri20[HAL_RX_MAX_NSS];
-- u8 tid;
-+ u16 tid;
- u16 ht_flags;
- u16 vht_flags;
- u16 he_flags;
-@@ -219,11 +219,11 @@ struct hal_rx_ppdu_start {
- #define HAL_RX_PPDU_END_USER_STATS_INFO5_OTHER_MSDU_CNT GENMASK(15, 0)
- #define HAL_RX_PPDU_END_USER_STATS_INFO5_TCP_ACK_MSDU_CNT GENMASK(31, 16)
-
--#define HAL_RX_PPDU_END_USER_STATS_INFO6_TID_BITMAP GENMASK(15, 0)
--#define HAL_RX_PPDU_END_USER_STATS_INFO6_TID_EOSP_BITMAP GENMASK(31, 16)
-+#define HAL_RX_PPDU_END_USER_STATS_INFO7_TID_BITMAP GENMASK(15, 0)
-+#define HAL_RX_PPDU_END_USER_STATS_INFO7_TID_EOSP_BITMAP GENMASK(31, 16)
-
--#define HAL_RX_PPDU_END_USER_STATS_INFO7_MPDU_OK_BYTE_COUNT GENMASK(24, 0)
--#define HAL_RX_PPDU_END_USER_STATS_INFO8_MPDU_ERR_BYTE_COUNT GENMASK(24, 0)
-+#define HAL_RX_PPDU_END_USER_STATS_INFO8_MPDU_OK_BYTE_COUNT GENMASK(24, 0)
-+#define HAL_RX_PPDU_END_USER_STATS_INFO9_MPDU_ERR_BYTE_COUNT GENMASK(24, 0)
-
- struct hal_rx_ppdu_end_user_stats {
- __le32 rsvd0[2];
-@@ -236,12 +236,13 @@ struct hal_rx_ppdu_end_user_stats {
- __le32 info4;
- __le32 info5;
- __le32 info6;
-- __le32 rsvd2[5];
- __le32 info7;
-- __le32 rsvd3;
-+ __le32 rsvd2[4];
- __le32 info8;
-- __le32 rsvd3[2];
-+ __le32 rsvd3;
- __le32 info9;
-+ __le32 rsvd4[2];
-+ __le32 info10;
- } __packed;
-
- struct hal_rx_ppdu_end_user_stats_ext {
+++ /dev/null
-From 1133af5aea588a58043244a4ecb5ce511b310356 Mon Sep 17 00:00:00 2001
-From: Wen Gong <quic_wgong@quicinc.com>
-Date: Wed, 30 Aug 2023 02:02:26 -0400
-Subject: [PATCH] wifi: ath11k: add chip id board name while searching
- board-2.bin for WCN6855
-
-Sometimes board-2.bin does not have the board data which matched the
-parameters such as bus type, vendor, device, subsystem-vendor,
-subsystem-device, qmi-chip-id and qmi-board-id, then wlan will load fail.
-
-Hence add another type which only matches the bus type and qmi-chip-id,
-then the ratio of missing board data reduced.
-
-Tested-on: WCN6855 hw2.0 PCI WLAN.HSP.1.1-03125-QCAHSPSWPL_V1_V2_SILICONZ_LITE-3.6510.23
-
-Signed-off-by: Wen Gong <quic_wgong@quicinc.com>
-Signed-off-by: Kalle Valo <quic_kvalo@quicinc.com>
-Link: https://lore.kernel.org/r/20230830060226.18664-1-quic_wgong@quicinc.com
----
- drivers/net/wireless/ath/ath11k/core.c | 108 ++++++++++++++++++++-----
- 1 file changed, 87 insertions(+), 21 deletions(-)
-
---- a/drivers/net/wireless/ath/ath11k/core.c
-+++ b/drivers/net/wireless/ath/ath11k/core.c
-@@ -985,9 +985,15 @@ int ath11k_core_check_dt(struct ath11k_b
- return 0;
- }
-
-+enum ath11k_bdf_name_type {
-+ ATH11K_BDF_NAME_FULL,
-+ ATH11K_BDF_NAME_BUS_NAME,
-+ ATH11K_BDF_NAME_CHIP_ID,
-+};
-+
- static int __ath11k_core_create_board_name(struct ath11k_base *ab, char *name,
- size_t name_len, bool with_variant,
-- bool bus_type_mode)
-+ enum ath11k_bdf_name_type name_type)
- {
- /* strlen(',variant=') + strlen(ab->qmi.target.bdf_ext) */
- char variant[9 + ATH11K_QMI_BDF_EXT_STR_LENGTH] = { 0 };
-@@ -998,11 +1004,8 @@ static int __ath11k_core_create_board_na
-
- switch (ab->id.bdf_search) {
- case ATH11K_BDF_SEARCH_BUS_AND_BOARD:
-- if (bus_type_mode)
-- scnprintf(name, name_len,
-- "bus=%s",
-- ath11k_bus_str(ab->hif.bus));
-- else
-+ switch (name_type) {
-+ case ATH11K_BDF_NAME_FULL:
- scnprintf(name, name_len,
- "bus=%s,vendor=%04x,device=%04x,subsystem-vendor=%04x,subsystem-device=%04x,qmi-chip-id=%d,qmi-board-id=%d%s",
- ath11k_bus_str(ab->hif.bus),
-@@ -1012,6 +1015,19 @@ static int __ath11k_core_create_board_na
- ab->qmi.target.chip_id,
- ab->qmi.target.board_id,
- variant);
-+ break;
-+ case ATH11K_BDF_NAME_BUS_NAME:
-+ scnprintf(name, name_len,
-+ "bus=%s",
-+ ath11k_bus_str(ab->hif.bus));
-+ break;
-+ case ATH11K_BDF_NAME_CHIP_ID:
-+ scnprintf(name, name_len,
-+ "bus=%s,qmi-chip-id=%d",
-+ ath11k_bus_str(ab->hif.bus),
-+ ab->qmi.target.chip_id);
-+ break;
-+ }
- break;
- default:
- scnprintf(name, name_len,
-@@ -1030,19 +1046,29 @@ static int __ath11k_core_create_board_na
- static int ath11k_core_create_board_name(struct ath11k_base *ab, char *name,
- size_t name_len)
- {
-- return __ath11k_core_create_board_name(ab, name, name_len, true, false);
-+ return __ath11k_core_create_board_name(ab, name, name_len, true,
-+ ATH11K_BDF_NAME_FULL);
- }
-
- static int ath11k_core_create_fallback_board_name(struct ath11k_base *ab, char *name,
- size_t name_len)
- {
-- return __ath11k_core_create_board_name(ab, name, name_len, false, false);
-+ return __ath11k_core_create_board_name(ab, name, name_len, false,
-+ ATH11K_BDF_NAME_FULL);
- }
-
- static int ath11k_core_create_bus_type_board_name(struct ath11k_base *ab, char *name,
- size_t name_len)
- {
-- return __ath11k_core_create_board_name(ab, name, name_len, false, true);
-+ return __ath11k_core_create_board_name(ab, name, name_len, false,
-+ ATH11K_BDF_NAME_BUS_NAME);
-+}
-+
-+static int ath11k_core_create_chip_id_board_name(struct ath11k_base *ab, char *name,
-+ size_t name_len)
-+{
-+ return __ath11k_core_create_board_name(ab, name, name_len, false,
-+ ATH11K_BDF_NAME_CHIP_ID);
- }
-
- const struct firmware *ath11k_core_firmware_request(struct ath11k_base *ab,
-@@ -1289,16 +1315,21 @@ int ath11k_core_fetch_board_data_api_1(s
- #define BOARD_NAME_SIZE 200
- int ath11k_core_fetch_bdf(struct ath11k_base *ab, struct ath11k_board_data *bd)
- {
-- char boardname[BOARD_NAME_SIZE], fallback_boardname[BOARD_NAME_SIZE];
-+ char *boardname = NULL, *fallback_boardname = NULL, *chip_id_boardname = NULL;
- char *filename, filepath[100];
-- int ret;
-+ int ret = 0;
-
- filename = ATH11K_BOARD_API2_FILE;
-+ boardname = kzalloc(BOARD_NAME_SIZE, GFP_KERNEL);
-+ if (!boardname) {
-+ ret = -ENOMEM;
-+ goto exit;
-+ }
-
-- ret = ath11k_core_create_board_name(ab, boardname, sizeof(boardname));
-+ ret = ath11k_core_create_board_name(ab, boardname, BOARD_NAME_SIZE);
- if (ret) {
- ath11k_err(ab, "failed to create board name: %d", ret);
-- return ret;
-+ goto exit;
- }
-
- ab->bd_api = 2;
-@@ -1307,13 +1338,19 @@ int ath11k_core_fetch_bdf(struct ath11k_
- ATH11K_BD_IE_BOARD_NAME,
- ATH11K_BD_IE_BOARD_DATA);
- if (!ret)
-- goto success;
-+ goto exit;
-+
-+ fallback_boardname = kzalloc(BOARD_NAME_SIZE, GFP_KERNEL);
-+ if (!fallback_boardname) {
-+ ret = -ENOMEM;
-+ goto exit;
-+ }
-
- ret = ath11k_core_create_fallback_board_name(ab, fallback_boardname,
-- sizeof(fallback_boardname));
-+ BOARD_NAME_SIZE);
- if (ret) {
- ath11k_err(ab, "failed to create fallback board name: %d", ret);
-- return ret;
-+ goto exit;
- }
-
- ret = ath11k_core_fetch_board_data_api_n(ab, bd, fallback_boardname,
-@@ -1321,7 +1358,28 @@ int ath11k_core_fetch_bdf(struct ath11k_
- ATH11K_BD_IE_BOARD_NAME,
- ATH11K_BD_IE_BOARD_DATA);
- if (!ret)
-- goto success;
-+ goto exit;
-+
-+ chip_id_boardname = kzalloc(BOARD_NAME_SIZE, GFP_KERNEL);
-+ if (!chip_id_boardname) {
-+ ret = -ENOMEM;
-+ goto exit;
-+ }
-+
-+ ret = ath11k_core_create_chip_id_board_name(ab, chip_id_boardname,
-+ BOARD_NAME_SIZE);
-+ if (ret) {
-+ ath11k_err(ab, "failed to create chip id board name: %d", ret);
-+ goto exit;
-+ }
-+
-+ ret = ath11k_core_fetch_board_data_api_n(ab, bd, chip_id_boardname,
-+ ATH11K_BD_IE_BOARD,
-+ ATH11K_BD_IE_BOARD_NAME,
-+ ATH11K_BD_IE_BOARD_DATA);
-+
-+ if (!ret)
-+ goto exit;
-
- ab->bd_api = 1;
- ret = ath11k_core_fetch_board_data_api_1(ab, bd, ATH11K_DEFAULT_BOARD_FILE);
-@@ -1334,14 +1392,22 @@ int ath11k_core_fetch_bdf(struct ath11k_
- ath11k_err(ab, "failed to fetch board data for %s from %s\n",
- fallback_boardname, filepath);
-
-+ ath11k_err(ab, "failed to fetch board data for %s from %s\n",
-+ chip_id_boardname, filepath);
-+
- ath11k_err(ab, "failed to fetch board.bin from %s\n",
- ab->hw_params.fw.dir);
-- return ret;
- }
-
--success:
-- ath11k_dbg(ab, ATH11K_DBG_BOOT, "using board api %d\n", ab->bd_api);
-- return 0;
-+exit:
-+ kfree(boardname);
-+ kfree(fallback_boardname);
-+ kfree(chip_id_boardname);
-+
-+ if (!ret)
-+ ath11k_dbg(ab, ATH11K_DBG_BOOT, "using board api %d\n", ab->bd_api);
-+
-+ return ret;
- }
-
- int ath11k_core_fetch_regdb(struct ath11k_base *ab, struct ath11k_board_data *bd)
+++ /dev/null
-From ac13a7842ab46a87aa315514d6d7e19b03cb2adc Mon Sep 17 00:00:00 2001
-From: Dmitry Antipov <dmantipov@yandex.ru>
-Date: Wed, 6 Sep 2023 12:36:55 +0300
-Subject: [PATCH] wifi: ath11k: drop NULL pointer check in
- ath11k_update_per_peer_tx_stats()
-
-Since 'user_stats' is a fixed-size array of 'struct htt_ppdu_user_stats'
-in 'struct htt_ppdu_stats', any of its member can't be NULL and so
-relevant check may be dropped.
-
-Found by Linux Verification Center (linuxtesting.org) with SVACE.
-
-Signed-off-by: Dmitry Antipov <dmantipov@yandex.ru>
-Acked-by: Jeff Johnson <quic_jjohnson@quicinc.com>
-Signed-off-by: Kalle Valo <quic_kvalo@quicinc.com>
-Link: https://lore.kernel.org/r/20230906093704.14001-1-dmantipov@yandex.ru
----
- drivers/net/wireless/ath/ath11k/dp_rx.c | 3 ---
- 1 file changed, 3 deletions(-)
-
---- a/drivers/net/wireless/ath/ath11k/dp_rx.c
-+++ b/drivers/net/wireless/ath/ath11k/dp_rx.c
-@@ -1388,9 +1388,6 @@ ath11k_update_per_peer_tx_stats(struct a
- u8 tid = HTT_PPDU_STATS_NON_QOS_TID;
- bool is_ampdu = false;
-
-- if (!usr_stats)
-- return;
--
- if (!(usr_stats->tlv_flags & BIT(HTT_PPDU_STATS_TAG_USR_RATE)))
- return;
-
+++ /dev/null
-From 82ae3f4635382ff23e2ece55b5d5e713223951ec Mon Sep 17 00:00:00 2001
-From: Dmitry Antipov <dmantipov@yandex.ru>
-Date: Thu, 24 Aug 2023 10:50:44 +0300
-Subject: [PATCH] wifi: ath11k: drop redundant check in
- ath11k_dp_rx_mon_dest_process()
-
-In 'ath11k_dp_rx_mon_dest_process()', 'mon_dst_srng' points to
-a member of 'srng_list', which is a fixed-size array inside
-'struct ath11k_hal'. This way, if 'ring_id' is valid (i. e.
-between 0 and HAL_SRNG_RING_ID_MAX - 1 inclusive), 'mon_dst_srng'
-can't be NULL and so relevant check may be dropped.
-
-Found by Linux Verification Center (linuxtesting.org) with SVACE.
-
-Signed-off-by: Dmitry Antipov <dmantipov@yandex.ru>
-Acked-by: Jeff Johnson <quic_jjohnson@quicinc.com>
-Signed-off-by: Kalle Valo <quic_kvalo@quicinc.com>
-Link: https://lore.kernel.org/r/20230824075121.121144-1-dmantipov@yandex.ru
----
- drivers/net/wireless/ath/ath11k/dp_rx.c | 7 -------
- 1 file changed, 7 deletions(-)
-
---- a/drivers/net/wireless/ath/ath11k/dp_rx.c
-+++ b/drivers/net/wireless/ath/ath11k/dp_rx.c
-@@ -5100,13 +5100,6 @@ static void ath11k_dp_rx_mon_dest_proces
-
- mon_dst_srng = &ar->ab->hal.srng_list[ring_id];
-
-- if (!mon_dst_srng) {
-- ath11k_warn(ar->ab,
-- "HAL Monitor Destination Ring Init Failed -- %p",
-- mon_dst_srng);
-- return;
-- }
--
- spin_lock_bh(&pmon->mon_lock);
-
- ath11k_hal_srng_access_begin(ar->ab, mon_dst_srng);
+++ /dev/null
-From 9066794113c4813b6ce4a66ed6ce14ecdf35625d Mon Sep 17 00:00:00 2001
-From: Dmitry Antipov <dmantipov@yandex.ru>
-Date: Thu, 24 Aug 2023 10:50:45 +0300
-Subject: [PATCH] wifi: ath11k: remove unused members of 'struct ath11k_base'
-
-Remove set but otherwise unused 'wlan_init_status' and
-'wmi_ready' members of 'struct ath11k_base', adjust
-'ath11k_wmi_tlv_rdy_parse()' accordingly.
-
-Signed-off-by: Dmitry Antipov <dmantipov@yandex.ru>
-Acked-by: Jeff Johnson <quic_jjohnson@quicinc.com>
-Signed-off-by: Kalle Valo <quic_kvalo@quicinc.com>
-Link: https://lore.kernel.org/r/20230824075121.121144-2-dmantipov@yandex.ru
----
- drivers/net/wireless/ath/ath11k/core.h | 2 --
- drivers/net/wireless/ath/ath11k/wmi.c | 2 --
- 2 files changed, 4 deletions(-)
-
---- a/drivers/net/wireless/ath/ath11k/core.h
-+++ b/drivers/net/wireless/ath/ath11k/core.h
-@@ -901,8 +901,6 @@ struct ath11k_base {
- struct list_head peers;
- wait_queue_head_t peer_mapping_wq;
- u8 mac_addr[ETH_ALEN];
-- bool wmi_ready;
-- u32 wlan_init_status;
- int irq_num[ATH11K_IRQ_NUM_MAX];
- struct ath11k_ext_irq_grp ext_irq_grp[ATH11K_EXT_IRQ_GRP_NUM_MAX];
- struct ath11k_targ_cap target_caps;
---- a/drivers/net/wireless/ath/ath11k/wmi.c
-+++ b/drivers/net/wireless/ath/ath11k/wmi.c
-@@ -7222,14 +7222,12 @@ static int ath11k_wmi_tlv_rdy_parse(stru
- memset(&fixed_param, 0, sizeof(fixed_param));
- memcpy(&fixed_param, (struct wmi_ready_event *)ptr,
- min_t(u16, sizeof(fixed_param), len));
-- ab->wlan_init_status = fixed_param.ready_event_min.status;
- rdy_parse->num_extra_mac_addr =
- fixed_param.ready_event_min.num_extra_mac_addr;
-
- ether_addr_copy(ab->mac_addr,
- fixed_param.ready_event_min.mac_addr.addr);
- ab->pktlog_defs_checksum = fixed_param.pktlog_defs_checksum;
-- ab->wmi_ready = true;
- break;
- case WMI_TAG_ARRAY_FIXED_STRUCT:
- addr_list = (struct wmi_mac_addr *)ptr;
+++ /dev/null
-From 458f66c30df2b8495790cf6fca76ebad44046921 Mon Sep 17 00:00:00 2001
-From: Dmitry Antipov <dmantipov@yandex.ru>
-Date: Thu, 21 Sep 2023 11:16:57 +0300
-Subject: [PATCH] wifi: ath11k: use kstrtoul_from_user() where appropriate
-
-Use 'kstrtoul_from_user()' in 'ath11k_write_file_spectral_count()'
-and 'ath11k_write_file_spectral_bins()'
-
-Signed-off-by: Dmitry Antipov <dmantipov@yandex.ru>
-Acked-by: Jeff Johnson <quic_jjohnson@quicinc.com>
-Signed-off-by: Kalle Valo <quic_kvalo@quicinc.com>
-Link: https://lore.kernel.org/r/20230824075121.121144-4-dmantipov@yandex.ru
----
- drivers/net/wireless/ath/ath11k/spectral.c | 26 +++++++---------------
- 1 file changed, 8 insertions(+), 18 deletions(-)
-
---- a/drivers/net/wireless/ath/ath11k/spectral.c
-+++ b/drivers/net/wireless/ath/ath11k/spectral.c
-@@ -386,16 +386,11 @@ static ssize_t ath11k_write_file_spectra
- {
- struct ath11k *ar = file->private_data;
- unsigned long val;
-- char buf[32];
-- ssize_t len;
--
-- len = min(count, sizeof(buf) - 1);
-- if (copy_from_user(buf, user_buf, len))
-- return -EFAULT;
-+ ssize_t ret;
-
-- buf[len] = '\0';
-- if (kstrtoul(buf, 0, &val))
-- return -EINVAL;
-+ ret = kstrtoul_from_user(user_buf, count, 0, &val);
-+ if (ret)
-+ return ret;
-
- if (val > ATH11K_SPECTRAL_SCAN_COUNT_MAX)
- return -EINVAL;
-@@ -441,16 +436,11 @@ static ssize_t ath11k_write_file_spectra
- {
- struct ath11k *ar = file->private_data;
- unsigned long val;
-- char buf[32];
-- ssize_t len;
--
-- len = min(count, sizeof(buf) - 1);
-- if (copy_from_user(buf, user_buf, len))
-- return -EFAULT;
-+ ssize_t ret;
-
-- buf[len] = '\0';
-- if (kstrtoul(buf, 0, &val))
-- return -EINVAL;
-+ ret = kstrtoul_from_user(user_buf, count, 0, &val);
-+ if (ret)
-+ return ret;
-
- if (val < ATH11K_SPECTRAL_MIN_BINS ||
- val > ar->ab->hw_params.spectral.max_fft_bins)
+++ /dev/null
-From 87fd0602610d6965c45afc61780ac98842e8f902 Mon Sep 17 00:00:00 2001
-From: Wu Yunchuan <yunchuan@nfschina.com>
-Date: Thu, 21 Sep 2023 11:50:05 +0300
-Subject: [PATCH] wifi: ath11k: remove unnecessary (void*) conversions
-
-No need cast (void *) to (struct ath11k_base *),
-struct hal_rx_msdu_link *), (struct ath11k_buffer_addr *) or
-other types.
-
-Signed-off-by: Wu Yunchuan <yunchuan@nfschina.com>
-Acked-by: Jeff Johnson <quic_jjohnson@quicinc.com>
-Signed-off-by: Kalle Valo <quic_kvalo@quicinc.com>
-Link: https://lore.kernel.org/r/20230919045150.524304-1-yunchuan@nfschina.com
----
- drivers/net/wireless/ath/ath11k/dp.c | 2 +-
- drivers/net/wireless/ath/ath11k/dp_rx.c | 13 +++++--------
- drivers/net/wireless/ath/ath11k/hal.c | 8 +++-----
- drivers/net/wireless/ath/ath11k/hal_rx.c | 17 +++++++----------
- drivers/net/wireless/ath/ath11k/hal_tx.c | 2 +-
- drivers/net/wireless/ath/ath11k/mac.c | 4 ++--
- drivers/net/wireless/ath/ath11k/spectral.c | 2 +-
- drivers/net/wireless/ath/ath11k/wmi.c | 6 +++---
- 8 files changed, 23 insertions(+), 31 deletions(-)
-
---- a/drivers/net/wireless/ath/ath11k/dp.c
-+++ b/drivers/net/wireless/ath/ath11k/dp.c
-@@ -1009,7 +1009,7 @@ void ath11k_dp_vdev_tx_attach(struct ath
-
- static int ath11k_dp_tx_pending_cleanup(int buf_id, void *skb, void *ctx)
- {
-- struct ath11k_base *ab = (struct ath11k_base *)ctx;
-+ struct ath11k_base *ab = ctx;
- struct sk_buff *msdu = skb;
-
- dma_unmap_single(ab->dev, ATH11K_SKB_CB(msdu)->paddr, msdu->len,
---- a/drivers/net/wireless/ath/ath11k/dp_rx.c
-+++ b/drivers/net/wireless/ath/ath11k/dp_rx.c
-@@ -1256,7 +1256,7 @@ static int ath11k_htt_tlv_ppdu_stats_par
- int cur_user;
- u16 peer_id;
-
-- ppdu_info = (struct htt_ppdu_stats_info *)data;
-+ ppdu_info = data;
-
- switch (tag) {
- case HTT_PPDU_STATS_TAG_COMMON:
-@@ -4492,8 +4492,7 @@ int ath11k_dp_rx_monitor_link_desc_retur
- src_srng_desc = ath11k_hal_srng_src_get_next_entry(ar->ab, hal_srng);
-
- if (src_srng_desc) {
-- struct ath11k_buffer_addr *src_desc =
-- (struct ath11k_buffer_addr *)src_srng_desc;
-+ struct ath11k_buffer_addr *src_desc = src_srng_desc;
-
- *src_desc = *((struct ath11k_buffer_addr *)p_last_buf_addr_info);
- } else {
-@@ -4512,8 +4511,7 @@ void ath11k_dp_rx_mon_next_link_desc_get
- u8 *rbm,
- void **pp_buf_addr_info)
- {
-- struct hal_rx_msdu_link *msdu_link =
-- (struct hal_rx_msdu_link *)rx_msdu_link_desc;
-+ struct hal_rx_msdu_link *msdu_link = rx_msdu_link_desc;
- struct ath11k_buffer_addr *buf_addr_info;
-
- buf_addr_info = (struct ath11k_buffer_addr *)&msdu_link->buf_addr_info;
-@@ -4554,7 +4552,7 @@ static void ath11k_hal_rx_msdu_list_get(
- u32 first = FIELD_PREP(RX_MSDU_DESC_INFO0_FIRST_MSDU_IN_MPDU, 1);
- u8 tmp = 0;
-
-- msdu_link = (struct hal_rx_msdu_link *)msdu_link_desc;
-+ msdu_link = msdu_link_desc;
- msdu_details = &msdu_link->msdu_link[0];
-
- for (i = 0; i < HAL_RX_NUM_MSDU_DESC; i++) {
-@@ -4651,8 +4649,7 @@ ath11k_dp_rx_mon_mpdu_pop(struct ath11k
- bool is_frag, is_first_msdu;
- bool drop_mpdu = false;
- struct ath11k_skb_rxcb *rxcb;
-- struct hal_reo_entrance_ring *ent_desc =
-- (struct hal_reo_entrance_ring *)ring_entry;
-+ struct hal_reo_entrance_ring *ent_desc = ring_entry;
- int buf_id;
- u32 rx_link_buf_info[2];
- u8 rbm;
---- a/drivers/net/wireless/ath/ath11k/hal.c
-+++ b/drivers/net/wireless/ath/ath11k/hal.c
-@@ -571,7 +571,7 @@ u32 ath11k_hal_ce_get_desc_size(enum hal
- void ath11k_hal_ce_src_set_desc(void *buf, dma_addr_t paddr, u32 len, u32 id,
- u8 byte_swap_data)
- {
-- struct hal_ce_srng_src_desc *desc = (struct hal_ce_srng_src_desc *)buf;
-+ struct hal_ce_srng_src_desc *desc = buf;
-
- desc->buffer_addr_low = paddr & HAL_ADDR_LSB_REG_MASK;
- desc->buffer_addr_info =
-@@ -586,8 +586,7 @@ void ath11k_hal_ce_src_set_desc(void *bu
-
- void ath11k_hal_ce_dst_set_desc(void *buf, dma_addr_t paddr)
- {
-- struct hal_ce_srng_dest_desc *desc =
-- (struct hal_ce_srng_dest_desc *)buf;
-+ struct hal_ce_srng_dest_desc *desc = buf;
-
- desc->buffer_addr_low = paddr & HAL_ADDR_LSB_REG_MASK;
- desc->buffer_addr_info =
-@@ -597,8 +596,7 @@ void ath11k_hal_ce_dst_set_desc(void *bu
-
- u32 ath11k_hal_ce_dst_status_get_length(void *buf)
- {
-- struct hal_ce_srng_dst_status_desc *desc =
-- (struct hal_ce_srng_dst_status_desc *)buf;
-+ struct hal_ce_srng_dst_status_desc *desc = buf;
- u32 len;
-
- len = FIELD_GET(HAL_CE_DST_STATUS_DESC_FLAGS_LEN, desc->flags);
---- a/drivers/net/wireless/ath/ath11k/hal_rx.c
-+++ b/drivers/net/wireless/ath/ath11k/hal_rx.c
-@@ -265,7 +265,7 @@ out:
- void ath11k_hal_rx_buf_addr_info_set(void *desc, dma_addr_t paddr,
- u32 cookie, u8 manager)
- {
-- struct ath11k_buffer_addr *binfo = (struct ath11k_buffer_addr *)desc;
-+ struct ath11k_buffer_addr *binfo = desc;
- u32 paddr_lo, paddr_hi;
-
- paddr_lo = lower_32_bits(paddr);
-@@ -279,7 +279,7 @@ void ath11k_hal_rx_buf_addr_info_set(voi
- void ath11k_hal_rx_buf_addr_info_get(void *desc, dma_addr_t *paddr,
- u32 *cookie, u8 *rbm)
- {
-- struct ath11k_buffer_addr *binfo = (struct ath11k_buffer_addr *)desc;
-+ struct ath11k_buffer_addr *binfo = desc;
-
- *paddr =
- (((u64)FIELD_GET(BUFFER_ADDR_INFO1_ADDR, binfo->info1)) << 32) |
-@@ -292,7 +292,7 @@ void ath11k_hal_rx_msdu_link_info_get(vo
- u32 *msdu_cookies,
- enum hal_rx_buf_return_buf_manager *rbm)
- {
-- struct hal_rx_msdu_link *link = (struct hal_rx_msdu_link *)link_desc;
-+ struct hal_rx_msdu_link *link = link_desc;
- struct hal_rx_msdu_details *msdu;
- int i;
-
-@@ -699,7 +699,7 @@ u32 ath11k_hal_reo_qdesc_size(u32 ba_win
- void ath11k_hal_reo_qdesc_setup(void *vaddr, int tid, u32 ba_window_size,
- u32 start_seq, enum hal_pn_type type)
- {
-- struct hal_rx_reo_queue *qdesc = (struct hal_rx_reo_queue *)vaddr;
-+ struct hal_rx_reo_queue *qdesc = vaddr;
- struct hal_rx_reo_queue_ext *ext_desc;
-
- memset(qdesc, 0, sizeof(*qdesc));
-@@ -809,8 +809,7 @@ static inline void
- ath11k_hal_rx_handle_ofdma_info(void *rx_tlv,
- struct hal_rx_user_status *rx_user_status)
- {
-- struct hal_rx_ppdu_end_user_stats *ppdu_end_user =
-- (struct hal_rx_ppdu_end_user_stats *)rx_tlv;
-+ struct hal_rx_ppdu_end_user_stats *ppdu_end_user = rx_tlv;
-
- rx_user_status->ul_ofdma_user_v0_word0 = __le32_to_cpu(ppdu_end_user->info6);
-
-@@ -821,8 +820,7 @@ static inline void
- ath11k_hal_rx_populate_byte_count(void *rx_tlv, void *ppduinfo,
- struct hal_rx_user_status *rx_user_status)
- {
-- struct hal_rx_ppdu_end_user_stats *ppdu_end_user =
-- (struct hal_rx_ppdu_end_user_stats *)rx_tlv;
-+ struct hal_rx_ppdu_end_user_stats *ppdu_end_user = rx_tlv;
-
- rx_user_status->mpdu_ok_byte_count =
- FIELD_GET(HAL_RX_PPDU_END_USER_STATS_INFO8_MPDU_OK_BYTE_COUNT,
-@@ -1540,8 +1538,7 @@ void ath11k_hal_rx_reo_ent_buf_paddr_get
- u32 *sw_cookie, void **pp_buf_addr,
- u8 *rbm, u32 *msdu_cnt)
- {
-- struct hal_reo_entrance_ring *reo_ent_ring =
-- (struct hal_reo_entrance_ring *)rx_desc;
-+ struct hal_reo_entrance_ring *reo_ent_ring = rx_desc;
- struct ath11k_buffer_addr *buf_addr_info;
- struct rx_mpdu_desc *rx_mpdu_desc_info_details;
-
---- a/drivers/net/wireless/ath/ath11k/hal_tx.c
-+++ b/drivers/net/wireless/ath/ath11k/hal_tx.c
-@@ -37,7 +37,7 @@ static const u8 dscp_tid_map[DSCP_TID_MA
- void ath11k_hal_tx_cmd_desc_setup(struct ath11k_base *ab, void *cmd,
- struct hal_tx_info *ti)
- {
-- struct hal_tcl_data_cmd *tcl_cmd = (struct hal_tcl_data_cmd *)cmd;
-+ struct hal_tcl_data_cmd *tcl_cmd = cmd;
-
- tcl_cmd->buf_addr_info.info0 =
- FIELD_PREP(BUFFER_ADDR_INFO0_ADDR, ti->paddr);
---- a/drivers/net/wireless/ath/ath11k/mac.c
-+++ b/drivers/net/wireless/ath/ath11k/mac.c
-@@ -6970,8 +6970,8 @@ err:
-
- static int ath11k_mac_vif_unref(int buf_id, void *skb, void *ctx)
- {
-- struct ieee80211_vif *vif = (struct ieee80211_vif *)ctx;
-- struct ath11k_skb_cb *skb_cb = ATH11K_SKB_CB((struct sk_buff *)skb);
-+ struct ieee80211_vif *vif = ctx;
-+ struct ath11k_skb_cb *skb_cb = ATH11K_SKB_CB(skb);
-
- if (skb_cb->vif == vif)
- skb_cb->vif = NULL;
---- a/drivers/net/wireless/ath/ath11k/spectral.c
-+++ b/drivers/net/wireless/ath/ath11k/spectral.c
-@@ -592,7 +592,7 @@ int ath11k_spectral_process_fft(struct a
- return -EINVAL;
- }
-
-- tlv = (struct spectral_tlv *)data;
-+ tlv = data;
- tlv_len = FIELD_GET(SPECTRAL_TLV_HDR_LEN, __le32_to_cpu(tlv->header));
- /* convert Dword into bytes */
- tlv_len *= ATH11K_SPECTRAL_DWORD_SIZE;
---- a/drivers/net/wireless/ath/ath11k/wmi.c
-+++ b/drivers/net/wireless/ath/ath11k/wmi.c
-@@ -2281,7 +2281,7 @@ int ath11k_wmi_send_scan_start_cmd(struc
- tlv->header = FIELD_PREP(WMI_TLV_TAG, WMI_TAG_ARRAY_UINT32) |
- FIELD_PREP(WMI_TLV_LEN, len);
- ptr += TLV_HDR_SIZE;
-- tmp_ptr = (u32 *)ptr;
-+ tmp_ptr = ptr;
-
- for (i = 0; i < params->num_chan; ++i)
- tmp_ptr[i] = params->chan_list[i];
-@@ -4148,7 +4148,7 @@ static int ath11k_init_cmd_send(struct a
- ptr += TLV_HDR_SIZE + len;
-
- if (param->hw_mode_id != WMI_HOST_HW_MODE_MAX) {
-- hw_mode = (struct wmi_pdev_set_hw_mode_cmd_param *)ptr;
-+ hw_mode = ptr;
- hw_mode->tlv_header = FIELD_PREP(WMI_TLV_TAG,
- WMI_TAG_PDEV_SET_HW_MODE_CMD) |
- FIELD_PREP(WMI_TLV_LEN,
-@@ -4168,7 +4168,7 @@ static int ath11k_init_cmd_send(struct a
- len = sizeof(*band_to_mac);
-
- for (idx = 0; idx < param->num_band_to_mac; idx++) {
-- band_to_mac = (void *)ptr;
-+ band_to_mac = ptr;
-
- band_to_mac->tlv_header = FIELD_PREP(WMI_TLV_TAG,
- WMI_TAG_PDEV_BAND_TO_MAC) |
+++ /dev/null
-From 4fd15bb705d3faa7e6adab2daba2e3af80d9b6bd Mon Sep 17 00:00:00 2001
-From: Dmitry Antipov <dmantipov@yandex.ru>
-Date: Tue, 26 Sep 2023 07:29:04 +0300
-Subject: [PATCH] wifi: ath11k: fix ath11k_mac_op_remain_on_channel() stack
- usage
-
-When compiling with clang 16.0.6, I've noticed the following:
-
-drivers/net/wireless/ath/ath11k/mac.c:8903:12: warning: stack frame
-size (1032) exceeds limit (1024) in 'ath11k_mac_op_remain_on_channel'
-[-Wframe-larger-than]
-static int ath11k_mac_op_remain_on_channel(struct ieee80211_hw *hw,
- ^
-68/1032 (6.59%) spills, 964/1032 (93.41%) variables
-
-So switch to kzalloc()'ed instance of 'struct scan_req_params' like
-it's done in 'ath11k_mac_op_hw_scan()'. Compile tested only.
-
-Signed-off-by: Dmitry Antipov <dmantipov@yandex.ru>
-Acked-by: Jeff Johnson <quic_jjohnson@quicinc.com>
-Signed-off-by: Kalle Valo <quic_kvalo@quicinc.com>
-Link: https://lore.kernel.org/r/20230926042906.13725-1-dmantipov@yandex.ru
----
- drivers/net/wireless/ath/ath11k/mac.c | 44 +++++++++++++++------------
- 1 file changed, 25 insertions(+), 19 deletions(-)
-
---- a/drivers/net/wireless/ath/ath11k/mac.c
-+++ b/drivers/net/wireless/ath/ath11k/mac.c
-@@ -8908,7 +8908,7 @@ static int ath11k_mac_op_remain_on_chann
- {
- struct ath11k *ar = hw->priv;
- struct ath11k_vif *arvif = ath11k_vif_to_arvif(vif);
-- struct scan_req_params arg;
-+ struct scan_req_params *arg;
- int ret;
- u32 scan_time_msec;
-
-@@ -8940,27 +8940,31 @@ static int ath11k_mac_op_remain_on_chann
-
- scan_time_msec = ar->hw->wiphy->max_remain_on_channel_duration * 2;
-
-- memset(&arg, 0, sizeof(arg));
-- ath11k_wmi_start_scan_init(ar, &arg);
-- arg.num_chan = 1;
-- arg.chan_list = kcalloc(arg.num_chan, sizeof(*arg.chan_list),
-- GFP_KERNEL);
-- if (!arg.chan_list) {
-+ arg = kzalloc(sizeof(*arg), GFP_KERNEL);
-+ if (!arg) {
- ret = -ENOMEM;
- goto exit;
- }
-+ ath11k_wmi_start_scan_init(ar, arg);
-+ arg->num_chan = 1;
-+ arg->chan_list = kcalloc(arg->num_chan, sizeof(*arg->chan_list),
-+ GFP_KERNEL);
-+ if (!arg->chan_list) {
-+ ret = -ENOMEM;
-+ goto free_arg;
-+ }
-
-- arg.vdev_id = arvif->vdev_id;
-- arg.scan_id = ATH11K_SCAN_ID;
-- arg.chan_list[0] = chan->center_freq;
-- arg.dwell_time_active = scan_time_msec;
-- arg.dwell_time_passive = scan_time_msec;
-- arg.max_scan_time = scan_time_msec;
-- arg.scan_flags |= WMI_SCAN_FLAG_PASSIVE;
-- arg.scan_flags |= WMI_SCAN_FILTER_PROBE_REQ;
-- arg.burst_duration = duration;
-+ arg->vdev_id = arvif->vdev_id;
-+ arg->scan_id = ATH11K_SCAN_ID;
-+ arg->chan_list[0] = chan->center_freq;
-+ arg->dwell_time_active = scan_time_msec;
-+ arg->dwell_time_passive = scan_time_msec;
-+ arg->max_scan_time = scan_time_msec;
-+ arg->scan_flags |= WMI_SCAN_FLAG_PASSIVE;
-+ arg->scan_flags |= WMI_SCAN_FILTER_PROBE_REQ;
-+ arg->burst_duration = duration;
-
-- ret = ath11k_start_scan(ar, &arg);
-+ ret = ath11k_start_scan(ar, arg);
- if (ret) {
- ath11k_warn(ar->ab, "failed to start roc scan: %d\n", ret);
-
-@@ -8986,7 +8990,9 @@ static int ath11k_mac_op_remain_on_chann
- ret = 0;
-
- free_chan_list:
-- kfree(arg.chan_list);
-+ kfree(arg->chan_list);
-+free_arg:
-+ kfree(arg);
- exit:
- mutex_unlock(&ar->conf_mutex);
- return ret;
+++ /dev/null
-From 9e61589ac3c2d23c528d3ffd44604d98553ea1cb Mon Sep 17 00:00:00 2001
-From: Kalle Valo <quic_kvalo@quicinc.com>
-Date: Wed, 27 Sep 2023 17:27:08 +0300
-Subject: [PATCH] wifi: ath11k: mac: fix struct ieee80211_sband_iftype_data
- handling
-
-Commit e8c1841278a7 ("wifi: cfg80211: annotate iftype_data pointer with
-sparse") added sparse checks for struct ieee80211_sband_iftype_data handling
-which immediately found an issue in ath11k:
-
-drivers/net/wireless/ath/ath11k/mac.c:7952:22: warning: incorrect type in argument 1 (different address spaces)
-drivers/net/wireless/ath/ath11k/mac.c:7952:22: expected struct ieee80211_sta_he_cap const *he_cap
-drivers/net/wireless/ath/ath11k/mac.c:7952:22: got struct ieee80211_sta_he_cap const [noderef] __iftype_data *
-
-The problem here is that we are accessing sband->iftype_data directly even
-though we should use for_each_sband_iftype_data() or similar. Fortunately
-there's ieee80211_get_he_iftype_cap_vif() which is just what we need here so
-use it to get HE capabilities.
-
-Tested-on: WCN6855 hw2.0 PCI WLAN.HSP.1.1-03125-QCAHSPSWPL_V1_V2_SILICONZ_LITE-3.6510.23
-
-Reported-by: Johannes Berg <johannes@sipsolutions.net>
-Signed-off-by: Kalle Valo <quic_kvalo@quicinc.com>
-Link: https://lore.kernel.org/r/20230927142708.2897504-2-kvalo@kernel.org
----
- drivers/net/wireless/ath/ath11k/mac.c | 10 ++++++++--
- 1 file changed, 8 insertions(+), 2 deletions(-)
-
---- a/drivers/net/wireless/ath/ath11k/mac.c
-+++ b/drivers/net/wireless/ath/ath11k/mac.c
-@@ -7913,12 +7913,14 @@ ath11k_mac_get_tx_mcs_map(const struct i
-
- static bool
- ath11k_mac_bitrate_mask_get_single_nss(struct ath11k *ar,
-+ struct ath11k_vif *arvif,
- enum nl80211_band band,
- const struct cfg80211_bitrate_mask *mask,
- int *nss)
- {
- struct ieee80211_supported_band *sband = &ar->mac.sbands[band];
- u16 vht_mcs_map = le16_to_cpu(sband->vht_cap.vht_mcs.tx_mcs_map);
-+ const struct ieee80211_sta_he_cap *he_cap;
- u16 he_mcs_map = 0;
- u8 ht_nss_mask = 0;
- u8 vht_nss_mask = 0;
-@@ -7949,7 +7951,11 @@ ath11k_mac_bitrate_mask_get_single_nss(s
- return false;
- }
-
-- he_mcs_map = le16_to_cpu(ath11k_mac_get_tx_mcs_map(&sband->iftype_data->he_cap));
-+ he_cap = ieee80211_get_he_iftype_cap_vif(sband, arvif->vif);
-+ if (!he_cap)
-+ return false;
-+
-+ he_mcs_map = le16_to_cpu(ath11k_mac_get_tx_mcs_map(he_cap));
-
- for (i = 0; i < ARRAY_SIZE(mask->control[band].he_mcs); i++) {
- if (mask->control[band].he_mcs[i] == 0)
-@@ -8365,7 +8371,7 @@ ath11k_mac_op_set_bitrate_mask(struct ie
- ieee80211_iterate_stations_atomic(ar->hw,
- ath11k_mac_disable_peer_fixed_rate,
- arvif);
-- } else if (ath11k_mac_bitrate_mask_get_single_nss(ar, band, mask,
-+ } else if (ath11k_mac_bitrate_mask_get_single_nss(ar, arvif, band, mask,
- &single_nss)) {
- rate = WMI_FIXED_RATE_NONE;
- nss = single_nss;
+++ /dev/null
-From 69fcb525905600a151997cd16367bb92c34a2b14 Mon Sep 17 00:00:00 2001
-From: Aditya Kumar Singh <quic_adisi@quicinc.com>
-Date: Tue, 3 Oct 2023 17:26:54 +0300
-Subject: [PATCH] wifi: ath11k: fix CAC running state during virtual interface
- start
-
-Currently channel definition's primary channel's DFS CAC time
-as well as primary channel's state i.e usable are used to set
-the CAC_RUNNING flag for the ath11k radio structure. However,
-this is wrong since certain channel definition are possbile
-where primary channel may not be a DFS channel but, secondary
-channel is a DFS channel. For example - channel 36 with 160 MHz
-bandwidth.
-In such cases, the flag will not be set which is wrong.
-
-Fix this issue by using cfg80211_chandef_dfs_usable() function
-from cfg80211 which return trues if at least one channel is in
-usable state.
-
-While at it, modify the CAC running debug log message to print
-the CAC time as well in milli-seconds.
-
-Tested-on: QCN9074 hw1.0 PCI WLAN.HK.2.7.0.1-01744-QCAHKSWPL_SILICONZ-1
-
-Signed-off-by: Aditya Kumar Singh <quic_adisi@quicinc.com>
-Acked-by: Jeff Johnson <quic_jjohnson@quicinc.com>
-Signed-off-by: Kalle Valo <quic_kvalo@quicinc.com>
-Link: https://lore.kernel.org/r/20230912051857.2284-3-quic_adisi@quicinc.com
----
- drivers/net/wireless/ath/ath11k/mac.c | 19 +++++++++++--------
- 1 file changed, 11 insertions(+), 8 deletions(-)
-
---- a/drivers/net/wireless/ath/ath11k/mac.c
-+++ b/drivers/net/wireless/ath/ath11k/mac.c
-@@ -5,6 +5,7 @@
- */
-
- #include <net/mac80211.h>
-+#include <net/cfg80211.h>
- #include <linux/etherdevice.h>
- #include <linux/bitfield.h>
- #include <linux/inetdevice.h>
-@@ -7196,6 +7197,7 @@ ath11k_mac_vdev_start_restart(struct ath
- struct wmi_vdev_start_req_arg arg = {};
- const struct cfg80211_chan_def *chandef = &ctx->def;
- int ret = 0;
-+ unsigned int dfs_cac_time;
-
- lockdep_assert_held(&ar->conf_mutex);
-
-@@ -7275,20 +7277,21 @@ ath11k_mac_vdev_start_restart(struct ath
- ath11k_dbg(ab, ATH11K_DBG_MAC, "vdev %pM started, vdev_id %d\n",
- arvif->vif->addr, arvif->vdev_id);
-
-- /* Enable CAC Flag in the driver by checking the channel DFS cac time,
-- * i.e dfs_cac_ms value which will be valid only for radar channels
-- * and state as NL80211_DFS_USABLE which indicates CAC needs to be
-+ /* Enable CAC Flag in the driver by checking the all sub-channel's DFS
-+ * state as NL80211_DFS_USABLE which indicates CAC needs to be
- * done before channel usage. This flags is used to drop rx packets.
- * during CAC.
- */
- /* TODO Set the flag for other interface types as required */
-- if (arvif->vdev_type == WMI_VDEV_TYPE_AP &&
-- chandef->chan->dfs_cac_ms &&
-- chandef->chan->dfs_state == NL80211_DFS_USABLE) {
-+ if (arvif->vdev_type == WMI_VDEV_TYPE_AP && ctx->radar_enabled &&
-+ cfg80211_chandef_dfs_usable(ar->hw->wiphy, chandef)) {
- set_bit(ATH11K_CAC_RUNNING, &ar->dev_flags);
-+ dfs_cac_time = cfg80211_chandef_dfs_cac_time(ar->hw->wiphy,
-+ chandef);
- ath11k_dbg(ab, ATH11K_DBG_MAC,
-- "CAC Started in chan_freq %d for vdev %d\n",
-- arg.channel.freq, arg.vdev_id);
-+ "cac started dfs_cac_time %u center_freq %d center_freq1 %d for vdev %d\n",
-+ dfs_cac_time, arg.channel.freq, chandef->center_freq1,
-+ arg.vdev_id);
- }
-
- ret = ath11k_mac_set_txbf_conf(arvif);
+++ /dev/null
-From 77f1ee6fd8b6e470f721d05a2e269039d5cafcb7 Mon Sep 17 00:00:00 2001
-From: Aditya Kumar Singh <quic_adisi@quicinc.com>
-Date: Tue, 3 Oct 2023 17:26:54 +0300
-Subject: [PATCH] wifi: ath11k: fix Tx power value during active CAC
-
-Tx power is fetched from firmware's pdev stats. However, during active
-CAC, firmware does not fill the current Tx power and sends the max
-initialised value filled during firmware init. If host sends this power
-to user space, this is wrong since in certain situations, the Tx power
-could be greater than the max allowed by the regulatory. Hence, host
-should not be fetching the Tx power during an active CAC.
-
-Fix this issue by returning -EAGAIN error so that user space knows that there's
-no valid value available.
-
-Tested-on: QCN9074 hw1.0 PCI WLAN.HK.2.7.0.1-01744-QCAHKSWPL_SILICONZ-1
-
-Fixes: 9a2aa68afe3d ("wifi: ath11k: add get_txpower mac ops")
-Signed-off-by: Aditya Kumar Singh <quic_adisi@quicinc.com>
-Acked-by: Jeff Johnson <quic_jjohnson@quicinc.com>
-Signed-off-by: Kalle Valo <quic_kvalo@quicinc.com>
-Link: https://lore.kernel.org/r/20230912051857.2284-4-quic_adisi@quicinc.com
----
- drivers/net/wireless/ath/ath11k/mac.c | 8 ++++++++
- 1 file changed, 8 insertions(+)
-
---- a/drivers/net/wireless/ath/ath11k/mac.c
-+++ b/drivers/net/wireless/ath/ath11k/mac.c
-@@ -9068,6 +9068,14 @@ static int ath11k_mac_op_get_txpower(str
- return -EAGAIN;
- }
-
-+ /* Firmware doesn't provide Tx power during CAC hence no need to fetch
-+ * the stats.
-+ */
-+ if (test_bit(ATH11K_CAC_RUNNING, &ar->dev_flags)) {
-+ mutex_unlock(&ar->conf_mutex);
-+ return -EAGAIN;
-+ }
-+
- req_param.pdev_id = ar->pdev->pdev_id;
- req_param.stats_id = WMI_REQUEST_PDEV_STAT;
-
+++ /dev/null
-From e149353e6562f3e3246f75dfc4cca6a0cc5b4efc Mon Sep 17 00:00:00 2001
-From: Aloka Dixit <quic_alokad@quicinc.com>
-Date: Mon, 9 Oct 2023 10:13:54 +0300
-Subject: [PATCH] wifi: ath11k: call ath11k_mac_fils_discovery() without
- condition
-
-Mac80211 does not set flags BSS_CHANGED_FILS_DISCOVERY and
-BSS_CHANGED_UNSOL_BCAST_PROBE_RESP if there are no updates to
-FILS discovery and unsolicited broadcast probe response transmission
-configurations respectively. This results in the transmissions getting
-stopped during BSS change operations which do not include these
-attributes. Remove the checks for the flags and always send the existing
-configuration to firmware.
-
-Tested-on: IPQ8074 hw2.0 AHB WLAN.HK.2.7.0.1-01744-QCAHKSWPL_SILICONZ-1
-
-Signed-off-by: Aloka Dixit <quic_alokad@quicinc.com>
-Acked-by: Jeff Johnson <quic_jjohnson@quicinc.com>
-Signed-off-by: Kalle Valo <quic_kvalo@quicinc.com>
-Link: https://lore.kernel.org/r/20231004044915.6817-1-quic_alokad@quicinc.com
----
- drivers/net/wireless/ath/ath11k/mac.c | 4 +---
- 1 file changed, 1 insertion(+), 3 deletions(-)
-
---- a/drivers/net/wireless/ath/ath11k/mac.c
-+++ b/drivers/net/wireless/ath/ath11k/mac.c
-@@ -3732,9 +3732,7 @@ static void ath11k_mac_op_bss_info_chang
- arvif->vdev_id, ret);
- }
-
-- if (changed & BSS_CHANGED_FILS_DISCOVERY ||
-- changed & BSS_CHANGED_UNSOL_BCAST_PROBE_RESP)
-- ath11k_mac_fils_discovery(arvif, info);
-+ ath11k_mac_fils_discovery(arvif, info);
-
- if (changed & BSS_CHANGED_ARP_FILTER) {
- ipv4_cnt = min(vif->cfg.arp_addr_cnt, ATH11K_IPV4_MAX_COUNT);
+++ /dev/null
-From a47111663491ff2829df0626493ce81b48dd880a Mon Sep 17 00:00:00 2001
-From: Kalle Valo <quic_kvalo@quicinc.com>
-Date: Tue, 10 Oct 2023 09:22:50 +0300
-Subject: [PATCH] wifi: ath11k: ath11k_debugfs_register(): fix
- format-truncation warning
-
-In v6.6-rc4 with GCC 13.2 I see a new warning:
-
-drivers/net/wireless/ath/ath11k/debugfs.c: In function 'ath11k_debugfs_register':
-drivers/net/wireless/ath/ath11k/debugfs.c:1597:51: error: '%d' directive output may be truncated writing between 1 and 3 bytes into a region of size 2 [-Werror=format-truncation=]
-drivers/net/wireless/ath/ath11k/debugfs.c:1597:48: note: directive argument in the range [0, 255]
-drivers/net/wireless/ath/ath11k/debugfs.c:1597:9: note: 'snprintf' output between 5 and 7 bytes into a destination of size 5
-
-Increase the size of pdev_name to 10 bytes to make sure there's enough room for
-the string. Also change the format to '%u' as ar->pdev_idx is u8.
-
-Compile tested only.
-
-Signed-off-by: Kalle Valo <quic_kvalo@quicinc.com>
-Link: https://lore.kernel.org/r/20231010062250.2580951-1-kvalo@kernel.org
----
- drivers/net/wireless/ath/ath11k/debugfs.c | 4 ++--
- 1 file changed, 2 insertions(+), 2 deletions(-)
-
---- a/drivers/net/wireless/ath/ath11k/debugfs.c
-+++ b/drivers/net/wireless/ath/ath11k/debugfs.c
-@@ -1591,10 +1591,10 @@ static const struct file_operations fops
- int ath11k_debugfs_register(struct ath11k *ar)
- {
- struct ath11k_base *ab = ar->ab;
-- char pdev_name[5];
-+ char pdev_name[10];
- char buf[100] = {0};
-
-- snprintf(pdev_name, sizeof(pdev_name), "%s%d", "mac", ar->pdev_idx);
-+ snprintf(pdev_name, sizeof(pdev_name), "%s%u", "mac", ar->pdev_idx);
-
- ar->debug.debugfs_pdev = debugfs_create_dir(pdev_name, ab->debugfs_soc);
- if (IS_ERR(ar->debug.debugfs_pdev))
+++ /dev/null
-From 534c2dd8099a9cc4bad8ea8b3c7fa1f730e10d5d Mon Sep 17 00:00:00 2001
-From: Aditya Kumar Singh <quic_adisi@quicinc.com>
-Date: Tue, 10 Oct 2023 10:27:19 +0300
-Subject: [PATCH] wifi: ath11k: add parsing of phy bitmap for reg rules
-
-Certain regulatory domains could put restrictions on phy mode operation.
-For example, in a few countries HE Operation is not allowed. For such
-countries, firmware indicates this via phy bitmap in each reg rule.
-
-Currently, there is no logic to parse this info and then pass it on to the
-cfg80211/regulatory.
-
-Add parsing of this phy bitmap from the regulatory channel change event and
-then accordingly map it to cfg80211/regulatory flags and pass it on to it.
-
-While at it, correct typo in debug print s/dsf/dfs.
-
-Tested-on: IPQ8074 hw2.0 AHB WLAN.HK.2.7.0.1-01744-QCAHKSWPL_SILICONZ-1
-
-Signed-off-by: Aditya Kumar Singh <quic_adisi@quicinc.com>
-Acked-by: Jeff Johnson <quic_jjohnson@quicinc.com>
-Signed-off-by: Kalle Valo <quic_kvalo@quicinc.com>
-Link: https://lore.kernel.org/r/20231004092655.25020-1-quic_adisi@quicinc.com
----
- drivers/net/wireless/ath/ath11k/reg.c | 11 +++++++++++
- drivers/net/wireless/ath/ath11k/reg.h | 3 +++
- drivers/net/wireless/ath/ath11k/wmi.c | 5 +++--
- 3 files changed, 17 insertions(+), 2 deletions(-)
-
---- a/drivers/net/wireless/ath/ath11k/reg.c
-+++ b/drivers/net/wireless/ath/ath11k/reg.c
-@@ -352,6 +352,16 @@ static u32 ath11k_map_fw_reg_flags(u16 r
- return flags;
- }
-
-+static u32 ath11k_map_fw_phy_flags(u32 phy_flags)
-+{
-+ u32 flags = 0;
-+
-+ if (phy_flags & ATH11K_REG_PHY_BITMAP_NO11AX)
-+ flags |= NL80211_RRF_NO_HE;
-+
-+ return flags;
-+}
-+
- static bool
- ath11k_reg_can_intersect(struct ieee80211_reg_rule *rule1,
- struct ieee80211_reg_rule *rule2)
-@@ -685,6 +695,7 @@ ath11k_reg_build_regd(struct ath11k_base
- }
-
- flags |= ath11k_map_fw_reg_flags(reg_rule->flags);
-+ flags |= ath11k_map_fw_phy_flags(reg_info->phybitmap);
-
- ath11k_reg_update_rule(tmp_regd->reg_rules + i,
- reg_rule->start_freq,
---- a/drivers/net/wireless/ath/ath11k/reg.h
-+++ b/drivers/net/wireless/ath/ath11k/reg.h
-@@ -24,6 +24,9 @@ enum ath11k_dfs_region {
- ATH11K_DFS_REG_UNDEF,
- };
-
-+/* Phy bitmaps */
-+#define ATH11K_REG_PHY_BITMAP_NO11AX BIT(5)
-+
- /* ATH11K Regulatory API's */
- void ath11k_reg_init(struct ath11k *ar);
- void ath11k_reg_free(struct ath11k_base *ab);
---- a/drivers/net/wireless/ath/ath11k/wmi.c
-+++ b/drivers/net/wireless/ath/ath11k/wmi.c
-@@ -5440,10 +5440,11 @@ static int ath11k_pull_reg_chan_list_ext
- }
-
- ath11k_dbg(ab, ATH11K_DBG_WMI,
-- "cc_ext %s dsf %d BW: min_2ghz %d max_2ghz %d min_5ghz %d max_5ghz %d",
-+ "cc_ext %s dfs %d BW: min_2ghz %d max_2ghz %d min_5ghz %d max_5ghz %d phy_bitmap 0x%x",
- reg_info->alpha2, reg_info->dfs_region,
- reg_info->min_bw_2ghz, reg_info->max_bw_2ghz,
-- reg_info->min_bw_5ghz, reg_info->max_bw_5ghz);
-+ reg_info->min_bw_5ghz, reg_info->max_bw_5ghz,
-+ reg_info->phybitmap);
-
- ath11k_dbg(ab, ATH11K_DBG_WMI,
- "num_2ghz_reg_rules %d num_5ghz_reg_rules %d",
+++ /dev/null
-From 480d230bef0ecd06e72ae3a84117142e38e77503 Mon Sep 17 00:00:00 2001
-From: Jeff Johnson <quic_jjohnson@quicinc.com>
-Date: Mon, 9 Oct 2023 09:36:54 -0700
-Subject: [PATCH] wifi: ath11k: Remove unused struct ath11k_htc_frame
-
-struct ath11k_htc_frame is unused, and since it illogically contains
-two consecutive flexible arrays, it could never be used, so remove it.
-
-No functional changes, compile tested only.
-
-Signed-off-by: Jeff Johnson <quic_jjohnson@quicinc.com>
-Signed-off-by: Kalle Valo <quic_kvalo@quicinc.com>
-Link: https://lore.kernel.org/r/20231009-ath11k_htc_frame-v1-1-81d405b7a195@quicinc.com
----
- drivers/net/wireless/ath/ath11k/htc.h | 12 ------------
- 1 file changed, 12 deletions(-)
-
---- a/drivers/net/wireless/ath/ath11k/htc.h
-+++ b/drivers/net/wireless/ath/ath11k/htc.h
-@@ -156,18 +156,6 @@ struct ath11k_htc_record {
- };
- } __packed __aligned(4);
-
--/* note: the trailer offset is dynamic depending
-- * on payload length. this is only a struct layout draft
-- */
--struct ath11k_htc_frame {
-- struct ath11k_htc_hdr hdr;
-- union {
-- struct ath11k_htc_msg msg;
-- u8 payload[0];
-- };
-- struct ath11k_htc_record trailer[0];
--} __packed __aligned(4);
--
- enum ath11k_htc_svc_gid {
- ATH11K_HTC_SVC_GRP_RSVD = 0,
- ATH11K_HTC_SVC_GRP_WMI = 1,
+++ /dev/null
-From 10c65f97b424fcee439463f933140df2a0022f98 Mon Sep 17 00:00:00 2001
-From: Jeff Johnson <quic_jjohnson@quicinc.com>
-Date: Mon, 9 Oct 2023 09:39:42 -0700
-Subject: [PATCH] wifi: ath11k: Introduce and use ath11k_sta_to_arsta()
-
-Currently, the logic to return an ath11k_sta pointer, given a
-ieee80211_sta pointer, uses typecasting throughout the driver. In
-general, conversion functions are preferable to typecasting since
-using a conversion function allows the compiler to validate the types
-of both the input and output parameters.
-
-ath11k already defines a conversion function ath11k_vif_to_arvif() for
-a similar conversion. So introduce ath11k_sta_to_arsta() for this use
-case, and convert all of the existing typecasting to use this
-function.
-
-No functional changes, compile tested only.
-
-Signed-off-by: Jeff Johnson <quic_jjohnson@quicinc.com>
-Signed-off-by: Kalle Valo <quic_kvalo@quicinc.com>
-Link: https://lore.kernel.org/r/20231009-ath11k_sta_to_arsta-v1-1-1563e3a307e8@quicinc.com
----
- drivers/net/wireless/ath/ath11k/core.h | 5 ++++
- drivers/net/wireless/ath/ath11k/debugfs.c | 4 +--
- drivers/net/wireless/ath/ath11k/debugfs_sta.c | 30 +++++++++----------
- drivers/net/wireless/ath/ath11k/dp_rx.c | 8 ++---
- drivers/net/wireless/ath/ath11k/dp_tx.c | 4 +--
- drivers/net/wireless/ath/ath11k/mac.c | 18 +++++------
- drivers/net/wireless/ath/ath11k/peer.c | 2 +-
- drivers/net/wireless/ath/ath11k/wmi.c | 6 ++--
- 8 files changed, 41 insertions(+), 36 deletions(-)
-
---- a/drivers/net/wireless/ath/ath11k/core.h
-+++ b/drivers/net/wireless/ath/ath11k/core.h
-@@ -1223,6 +1223,11 @@ static inline struct ath11k_vif *ath11k_
- return (struct ath11k_vif *)vif->drv_priv;
- }
-
-+static inline struct ath11k_sta *ath11k_sta_to_arsta(struct ieee80211_sta *sta)
-+{
-+ return (struct ath11k_sta *)sta->drv_priv;
-+}
-+
- static inline struct ath11k *ath11k_ab_to_ar(struct ath11k_base *ab,
- int mac_id)
- {
---- a/drivers/net/wireless/ath/ath11k/debugfs.c
-+++ b/drivers/net/wireless/ath/ath11k/debugfs.c
-@@ -1459,7 +1459,7 @@ static void ath11k_reset_peer_ps_duratio
- struct ieee80211_sta *sta)
- {
- struct ath11k *ar = data;
-- struct ath11k_sta *arsta = (struct ath11k_sta *)sta->drv_priv;
-+ struct ath11k_sta *arsta = ath11k_sta_to_arsta(sta);
-
- spin_lock_bh(&ar->data_lock);
- arsta->ps_total_duration = 0;
-@@ -1510,7 +1510,7 @@ static void ath11k_peer_ps_state_disable
- struct ieee80211_sta *sta)
- {
- struct ath11k *ar = data;
-- struct ath11k_sta *arsta = (struct ath11k_sta *)sta->drv_priv;
-+ struct ath11k_sta *arsta = ath11k_sta_to_arsta(sta);
-
- spin_lock_bh(&ar->data_lock);
- arsta->peer_ps_state = WMI_PEER_PS_STATE_DISABLED;
---- a/drivers/net/wireless/ath/ath11k/debugfs_sta.c
-+++ b/drivers/net/wireless/ath/ath11k/debugfs_sta.c
-@@ -136,7 +136,7 @@ static ssize_t ath11k_dbg_sta_dump_tx_st
- size_t count, loff_t *ppos)
- {
- struct ieee80211_sta *sta = file->private_data;
-- struct ath11k_sta *arsta = (struct ath11k_sta *)sta->drv_priv;
-+ struct ath11k_sta *arsta = ath11k_sta_to_arsta(sta);
- struct ath11k *ar = arsta->arvif->ar;
- struct ath11k_htt_data_stats *stats;
- static const char *str_name[ATH11K_STATS_TYPE_MAX] = {"succ", "fail",
-@@ -243,7 +243,7 @@ static ssize_t ath11k_dbg_sta_dump_rx_st
- size_t count, loff_t *ppos)
- {
- struct ieee80211_sta *sta = file->private_data;
-- struct ath11k_sta *arsta = (struct ath11k_sta *)sta->drv_priv;
-+ struct ath11k_sta *arsta = ath11k_sta_to_arsta(sta);
- struct ath11k *ar = arsta->arvif->ar;
- struct ath11k_rx_peer_stats *rx_stats = arsta->rx_stats;
- int len = 0, i, retval = 0;
-@@ -340,7 +340,7 @@ static int
- ath11k_dbg_sta_open_htt_peer_stats(struct inode *inode, struct file *file)
- {
- struct ieee80211_sta *sta = inode->i_private;
-- struct ath11k_sta *arsta = (struct ath11k_sta *)sta->drv_priv;
-+ struct ath11k_sta *arsta = ath11k_sta_to_arsta(sta);
- struct ath11k *ar = arsta->arvif->ar;
- struct debug_htt_stats_req *stats_req;
- int type = ar->debug.htt_stats.type;
-@@ -376,7 +376,7 @@ static int
- ath11k_dbg_sta_release_htt_peer_stats(struct inode *inode, struct file *file)
- {
- struct ieee80211_sta *sta = inode->i_private;
-- struct ath11k_sta *arsta = (struct ath11k_sta *)sta->drv_priv;
-+ struct ath11k_sta *arsta = ath11k_sta_to_arsta(sta);
- struct ath11k *ar = arsta->arvif->ar;
-
- mutex_lock(&ar->conf_mutex);
-@@ -413,7 +413,7 @@ static ssize_t ath11k_dbg_sta_write_peer
- size_t count, loff_t *ppos)
- {
- struct ieee80211_sta *sta = file->private_data;
-- struct ath11k_sta *arsta = (struct ath11k_sta *)sta->drv_priv;
-+ struct ath11k_sta *arsta = ath11k_sta_to_arsta(sta);
- struct ath11k *ar = arsta->arvif->ar;
- int ret, enable;
-
-@@ -453,7 +453,7 @@ static ssize_t ath11k_dbg_sta_read_peer_
- size_t count, loff_t *ppos)
- {
- struct ieee80211_sta *sta = file->private_data;
-- struct ath11k_sta *arsta = (struct ath11k_sta *)sta->drv_priv;
-+ struct ath11k_sta *arsta = ath11k_sta_to_arsta(sta);
- struct ath11k *ar = arsta->arvif->ar;
- char buf[32] = {0};
- int len;
-@@ -480,7 +480,7 @@ static ssize_t ath11k_dbg_sta_write_delb
- size_t count, loff_t *ppos)
- {
- struct ieee80211_sta *sta = file->private_data;
-- struct ath11k_sta *arsta = (struct ath11k_sta *)sta->drv_priv;
-+ struct ath11k_sta *arsta = ath11k_sta_to_arsta(sta);
- struct ath11k *ar = arsta->arvif->ar;
- u32 tid, initiator, reason;
- int ret;
-@@ -531,7 +531,7 @@ static ssize_t ath11k_dbg_sta_write_addb
- size_t count, loff_t *ppos)
- {
- struct ieee80211_sta *sta = file->private_data;
-- struct ath11k_sta *arsta = (struct ath11k_sta *)sta->drv_priv;
-+ struct ath11k_sta *arsta = ath11k_sta_to_arsta(sta);
- struct ath11k *ar = arsta->arvif->ar;
- u32 tid, status;
- int ret;
-@@ -581,7 +581,7 @@ static ssize_t ath11k_dbg_sta_write_addb
- size_t count, loff_t *ppos)
- {
- struct ieee80211_sta *sta = file->private_data;
-- struct ath11k_sta *arsta = (struct ath11k_sta *)sta->drv_priv;
-+ struct ath11k_sta *arsta = ath11k_sta_to_arsta(sta);
- struct ath11k *ar = arsta->arvif->ar;
- u32 tid, buf_size;
- int ret;
-@@ -632,7 +632,7 @@ static ssize_t ath11k_dbg_sta_read_aggr_
- size_t count, loff_t *ppos)
- {
- struct ieee80211_sta *sta = file->private_data;
-- struct ath11k_sta *arsta = (struct ath11k_sta *)sta->drv_priv;
-+ struct ath11k_sta *arsta = ath11k_sta_to_arsta(sta);
- struct ath11k *ar = arsta->arvif->ar;
- char buf[64];
- int len = 0;
-@@ -652,7 +652,7 @@ static ssize_t ath11k_dbg_sta_write_aggr
- size_t count, loff_t *ppos)
- {
- struct ieee80211_sta *sta = file->private_data;
-- struct ath11k_sta *arsta = (struct ath11k_sta *)sta->drv_priv;
-+ struct ath11k_sta *arsta = ath11k_sta_to_arsta(sta);
- struct ath11k *ar = arsta->arvif->ar;
- u32 aggr_mode;
- int ret;
-@@ -697,7 +697,7 @@ ath11k_write_htt_peer_stats_reset(struct
- size_t count, loff_t *ppos)
- {
- struct ieee80211_sta *sta = file->private_data;
-- struct ath11k_sta *arsta = (struct ath11k_sta *)sta->drv_priv;
-+ struct ath11k_sta *arsta = ath11k_sta_to_arsta(sta);
- struct ath11k *ar = arsta->arvif->ar;
- struct htt_ext_stats_cfg_params cfg_params = { 0 };
- int ret;
-@@ -756,7 +756,7 @@ static ssize_t ath11k_dbg_sta_read_peer_
- size_t count, loff_t *ppos)
- {
- struct ieee80211_sta *sta = file->private_data;
-- struct ath11k_sta *arsta = (struct ath11k_sta *)sta->drv_priv;
-+ struct ath11k_sta *arsta = ath11k_sta_to_arsta(sta);
- struct ath11k *ar = arsta->arvif->ar;
- char buf[20];
- int len;
-@@ -783,7 +783,7 @@ static ssize_t ath11k_dbg_sta_read_curre
- loff_t *ppos)
- {
- struct ieee80211_sta *sta = file->private_data;
-- struct ath11k_sta *arsta = (struct ath11k_sta *)sta->drv_priv;
-+ struct ath11k_sta *arsta = ath11k_sta_to_arsta(sta);
- struct ath11k *ar = arsta->arvif->ar;
- u64 time_since_station_in_power_save;
- char buf[20];
-@@ -817,7 +817,7 @@ static ssize_t ath11k_dbg_sta_read_total
- size_t count, loff_t *ppos)
- {
- struct ieee80211_sta *sta = file->private_data;
-- struct ath11k_sta *arsta = (struct ath11k_sta *)sta->drv_priv;
-+ struct ath11k_sta *arsta = ath11k_sta_to_arsta(sta);
- struct ath11k *ar = arsta->arvif->ar;
- char buf[20];
- u64 power_save_duration;
---- a/drivers/net/wireless/ath/ath11k/dp_rx.c
-+++ b/drivers/net/wireless/ath/ath11k/dp_rx.c
-@@ -1099,7 +1099,7 @@ int ath11k_dp_rx_ampdu_start(struct ath1
- struct ieee80211_ampdu_params *params)
- {
- struct ath11k_base *ab = ar->ab;
-- struct ath11k_sta *arsta = (void *)params->sta->drv_priv;
-+ struct ath11k_sta *arsta = ath11k_sta_to_arsta(params->sta);
- int vdev_id = arsta->arvif->vdev_id;
- int ret;
-
-@@ -1117,7 +1117,7 @@ int ath11k_dp_rx_ampdu_stop(struct ath11
- {
- struct ath11k_base *ab = ar->ab;
- struct ath11k_peer *peer;
-- struct ath11k_sta *arsta = (void *)params->sta->drv_priv;
-+ struct ath11k_sta *arsta = ath11k_sta_to_arsta(params->sta);
- int vdev_id = arsta->arvif->vdev_id;
- dma_addr_t paddr;
- bool active;
-@@ -1456,7 +1456,7 @@ ath11k_update_per_peer_tx_stats(struct a
- }
-
- sta = peer->sta;
-- arsta = (struct ath11k_sta *)sta->drv_priv;
-+ arsta = ath11k_sta_to_arsta(sta);
-
- memset(&arsta->txrate, 0, sizeof(arsta->txrate));
-
-@@ -5248,7 +5248,7 @@ int ath11k_dp_rx_process_mon_status(stru
- goto next_skb;
- }
-
-- arsta = (struct ath11k_sta *)peer->sta->drv_priv;
-+ arsta = ath11k_sta_to_arsta(peer->sta);
- ath11k_dp_rx_update_peer_stats(arsta, ppdu_info);
-
- if (ath11k_debugfs_is_pktlog_peer_valid(ar, peer->addr))
---- a/drivers/net/wireless/ath/ath11k/dp_tx.c
-+++ b/drivers/net/wireless/ath/ath11k/dp_tx.c
-@@ -467,7 +467,7 @@ void ath11k_dp_tx_update_txcompl(struct
- }
-
- sta = peer->sta;
-- arsta = (struct ath11k_sta *)sta->drv_priv;
-+ arsta = ath11k_sta_to_arsta(sta);
-
- memset(&arsta->txrate, 0, sizeof(arsta->txrate));
- pkt_type = FIELD_GET(HAL_TX_RATE_STATS_INFO0_PKT_TYPE,
-@@ -627,7 +627,7 @@ static void ath11k_dp_tx_complete_msdu(s
- ieee80211_free_txskb(ar->hw, msdu);
- return;
- }
-- arsta = (struct ath11k_sta *)peer->sta->drv_priv;
-+ arsta = ath11k_sta_to_arsta(peer->sta);
- status.sta = peer->sta;
- status.skb = msdu;
- status.info = info;
---- a/drivers/net/wireless/ath/ath11k/mac.c
-+++ b/drivers/net/wireless/ath/ath11k/mac.c
-@@ -2832,7 +2832,7 @@ static void ath11k_peer_assoc_prepare(st
-
- lockdep_assert_held(&ar->conf_mutex);
-
-- arsta = (struct ath11k_sta *)sta->drv_priv;
-+ arsta = ath11k_sta_to_arsta(sta);
-
- memset(arg, 0, sizeof(*arg));
-
-@@ -4313,7 +4313,7 @@ static int ath11k_mac_op_set_key(struct
- ath11k_warn(ab, "peer %pM disappeared!\n", peer_addr);
-
- if (sta) {
-- arsta = (struct ath11k_sta *)sta->drv_priv;
-+ arsta = ath11k_sta_to_arsta(sta);
-
- switch (key->cipher) {
- case WLAN_CIPHER_SUITE_TKIP:
-@@ -4904,7 +4904,7 @@ static int ath11k_mac_station_add(struct
- {
- struct ath11k_base *ab = ar->ab;
- struct ath11k_vif *arvif = ath11k_vif_to_arvif(vif);
-- struct ath11k_sta *arsta = (struct ath11k_sta *)sta->drv_priv;
-+ struct ath11k_sta *arsta = ath11k_sta_to_arsta(sta);
- struct peer_create_params peer_param;
- int ret;
-
-@@ -5028,7 +5028,7 @@ static int ath11k_mac_op_sta_state(struc
- {
- struct ath11k *ar = hw->priv;
- struct ath11k_vif *arvif = ath11k_vif_to_arvif(vif);
-- struct ath11k_sta *arsta = (struct ath11k_sta *)sta->drv_priv;
-+ struct ath11k_sta *arsta = ath11k_sta_to_arsta(sta);
- struct ath11k_peer *peer;
- int ret = 0;
-
-@@ -5194,7 +5194,7 @@ static void ath11k_mac_op_sta_set_4addr(
- struct ieee80211_sta *sta, bool enabled)
- {
- struct ath11k *ar = hw->priv;
-- struct ath11k_sta *arsta = (struct ath11k_sta *)sta->drv_priv;
-+ struct ath11k_sta *arsta = ath11k_sta_to_arsta(sta);
-
- if (enabled && !arsta->use_4addr_set) {
- ieee80211_queue_work(ar->hw, &arsta->set_4addr_wk);
-@@ -5208,7 +5208,7 @@ static void ath11k_mac_op_sta_rc_update(
- u32 changed)
- {
- struct ath11k *ar = hw->priv;
-- struct ath11k_sta *arsta = (struct ath11k_sta *)sta->drv_priv;
-+ struct ath11k_sta *arsta = ath11k_sta_to_arsta(sta);
- struct ath11k_vif *arvif = ath11k_vif_to_arvif(vif);
- struct ath11k_peer *peer;
- u32 bw, smps;
-@@ -6201,7 +6201,7 @@ static void ath11k_mac_op_tx(struct ieee
- }
-
- if (control->sta)
-- arsta = (struct ath11k_sta *)control->sta->drv_priv;
-+ arsta = ath11k_sta_to_arsta(control->sta);
-
- ret = ath11k_dp_tx(ar, arvif, arsta, skb);
- if (unlikely(ret)) {
-@@ -8233,7 +8233,7 @@ static void ath11k_mac_set_bitrate_mask_
- struct ieee80211_sta *sta)
- {
- struct ath11k_vif *arvif = data;
-- struct ath11k_sta *arsta = (struct ath11k_sta *)sta->drv_priv;
-+ struct ath11k_sta *arsta = ath11k_sta_to_arsta(sta);
- struct ath11k *ar = arvif->ar;
-
- spin_lock_bh(&ar->data_lock);
-@@ -8637,7 +8637,7 @@ static void ath11k_mac_op_sta_statistics
- struct ieee80211_sta *sta,
- struct station_info *sinfo)
- {
-- struct ath11k_sta *arsta = (struct ath11k_sta *)sta->drv_priv;
-+ struct ath11k_sta *arsta = ath11k_sta_to_arsta(sta);
- struct ath11k *ar = arsta->arvif->ar;
- s8 signal;
- bool db2dbm = test_bit(WMI_TLV_SERVICE_HW_DB2DBM_CONVERSION_SUPPORT,
---- a/drivers/net/wireless/ath/ath11k/peer.c
-+++ b/drivers/net/wireless/ath/ath11k/peer.c
-@@ -446,7 +446,7 @@ int ath11k_peer_create(struct ath11k *ar
- peer->sec_type_grp = HAL_ENCRYPT_TYPE_OPEN;
-
- if (sta) {
-- arsta = (struct ath11k_sta *)sta->drv_priv;
-+ arsta = ath11k_sta_to_arsta(sta);
- arsta->tcl_metadata |= FIELD_PREP(HTT_TCL_META_DATA_TYPE, 0) |
- FIELD_PREP(HTT_TCL_META_DATA_PEER_ID,
- peer->peer_id);
---- a/drivers/net/wireless/ath/ath11k/wmi.c
-+++ b/drivers/net/wireless/ath/ath11k/wmi.c
-@@ -6453,7 +6453,7 @@ static int ath11k_wmi_tlv_rssi_chain_par
- goto exit;
- }
-
-- arsta = (struct ath11k_sta *)sta->drv_priv;
-+ arsta = ath11k_sta_to_arsta(sta);
-
- BUILD_BUG_ON(ARRAY_SIZE(arsta->chain_signal) >
- ARRAY_SIZE(stats_rssi->rssi_avg_beacon));
-@@ -6541,7 +6541,7 @@ static int ath11k_wmi_tlv_fw_stats_data_
- arvif->bssid,
- NULL);
- if (sta) {
-- arsta = (struct ath11k_sta *)sta->drv_priv;
-+ arsta = ath11k_sta_to_arsta(sta);
- arsta->rssi_beacon = src->beacon_snr;
- ath11k_dbg(ab, ATH11K_DBG_WMI,
- "stats vdev id %d snr %d\n",
-@@ -7468,7 +7468,7 @@ static void ath11k_wmi_event_peer_sta_ps
- goto exit;
- }
-
-- arsta = (struct ath11k_sta *)sta->drv_priv;
-+ arsta = ath11k_sta_to_arsta(sta);
-
- spin_lock_bh(&ar->data_lock);
-
--- a/drivers/net/wireless/ath/ath11k/core.c
+++ b/drivers/net/wireless/ath/ath11k/core.c
-@@ -168,8 +168,8 @@ static const struct ath11k_hw_params ath
+@@ -170,8 +170,8 @@ static const struct ath11k_hw_params ath
.supports_shadow_regs = false,
.idle_ps = false,
.supports_sta_ps = false,
--- a/drivers/net/wireless/ath/ath11k/mhi.c
+++ b/drivers/net/wireless/ath/ath11k/mhi.c
-@@ -294,6 +294,34 @@ static void ath11k_mhi_op_runtime_put(st
+@@ -239,6 +239,34 @@ static void ath11k_mhi_op_runtime_put(st
{
}
static char *ath11k_mhi_op_callback_to_str(enum mhi_callback reason)
{
switch (reason) {
-@@ -315,6 +343,8 @@ static char *ath11k_mhi_op_callback_to_s
+@@ -260,6 +288,8 @@ static char *ath11k_mhi_op_callback_to_s
return "MHI_CB_FATAL_ERROR";
case MHI_CB_BW_REQ:
return "MHI_CB_BW_REQ";
default:
return "UNKNOWN";
}
-@@ -337,27 +367,14 @@ static void ath11k_mhi_op_status_cb(stru
+@@ -282,27 +312,14 @@ static void ath11k_mhi_op_status_cb(stru
if (!(test_bit(ATH11K_FLAG_UNREGISTERING, &ab->dev_flags)))
queue_work(ab->workqueue_aux, &ab->reset_work);
break;
struct device_node *np;
--- a/drivers/net/wireless/ath/ath11k/mhi.h
+++ b/drivers/net/wireless/ath/ath11k/mhi.h
-@@ -16,6 +16,9 @@
+@@ -17,6 +17,9 @@
#define MHICTRL 0x38
#define MHICTRL_RESET_MASK 0x2
int ath11k_mhi_register(struct ath11k_pci *ar_pci);
--- a/drivers/net/wireless/ath/ath11k/pci.c
+++ b/drivers/net/wireless/ath/ath11k/pci.c
-@@ -371,13 +371,20 @@ static void ath11k_pci_sw_reset(struct a
+@@ -374,13 +374,20 @@ static void ath11k_pci_sw_reset(struct a
static void ath11k_pci_init_qmi_ce_config(struct ath11k_base *ab)
{
struct ath11k_qmi_ce_cfg *cfg = &ab->qmi.ce_cfg;
--- a/drivers/net/wireless/ath/ath11k/mac.c
+++ b/drivers/net/wireless/ath/ath11k/mac.c
-@@ -9455,6 +9455,7 @@ static int __ath11k_mac_register(struct
+@@ -10029,6 +10029,7 @@ static int __ath11k_mac_register(struct
if (ret)
goto err;
+ Enable ath11k thermal sensors and throttling support.
--- a/drivers/net/wireless/ath/ath11k/Makefile
+++ b/drivers/net/wireless/ath/ath11k/Makefile
-@@ -22,7 +22,7 @@ ath11k-y += core.o \
+@@ -23,7 +23,7 @@ ath11k-y += core.o \
ath11k-$(CPTCFG_ATH11K_DEBUGFS) += debugfs.o debugfs_htt_stats.o debugfs_sta.o
ath11k-$(CPTCFG_NL80211_TESTMODE) += testmode.o
ath11k-$(CPTCFG_ATH11K_TRACING) += trace.o
--- a/drivers/net/wireless/ath/ath11k/thermal.h
+++ b/drivers/net/wireless/ath/ath11k/thermal.h
-@@ -25,7 +25,7 @@ struct ath11k_thermal {
+@@ -26,7 +26,7 @@ struct ath11k_thermal {
int temperature;
};
-#if IS_REACHABLE(CONFIG_THERMAL)
+#if IS_REACHABLE(CPTCFG_ATH11K_THERMAL)
- int ath11k_thermal_register(struct ath11k_base *sc);
- void ath11k_thermal_unregister(struct ath11k_base *sc);
+ int ath11k_thermal_register(struct ath11k_base *ab);
+ void ath11k_thermal_unregister(struct ath11k_base *ab);
int ath11k_thermal_set_throttling(struct ath11k *ar, u32 throttle_state);
--- a/local-symbols
+++ b/local-symbols
-@@ -173,6 +173,7 @@ ATH11K_DEBUG=
+@@ -172,6 +172,7 @@ ATH11K_DEBUG=
ATH11K_DEBUGFS=
ATH11K_TRACING=
ATH11K_SPECTRAL=
--- a/drivers/net/wireless/ath/ath11k/pci.c
+++ b/drivers/net/wireless/ath/ath11k/pci.c
-@@ -459,7 +459,11 @@ static int ath11k_pci_alloc_msi(struct a
+@@ -462,7 +462,11 @@ static int ath11k_pci_alloc_msi(struct a
pci_read_config_dword(pci_dev, pci_dev->msi_cap + PCI_MSI_ADDRESS_LO,
&ab->pci.msi.addr_lo);
--- a/drivers/net/wireless/ath/ath11k/core.c
+++ b/drivers/net/wireless/ath/ath11k/core.c
-@@ -36,7 +36,7 @@ bool ath11k_ftm_mode;
+@@ -37,7 +37,7 @@ bool ath11k_ftm_mode;
module_param_named(ftm_mode, ath11k_ftm_mode, bool, 0444);
MODULE_PARM_DESC(ftm_mode, "Boots up in factory test mode");
{
.hw_rev = ATH11K_HW_IPQ8074,
.name = "ipq8074 hw2.0",
-@@ -2040,7 +2040,8 @@ static void ath11k_core_reset(struct wor
+@@ -2138,7 +2138,8 @@ static void ath11k_core_reset(struct wor
static int ath11k_init_hw_params(struct ath11k_base *ab)
{
const struct ath11k_hw_params *hw_params = NULL;
for (i = 0; i < ARRAY_SIZE(ath11k_hw_params); i++) {
hw_params = &ath11k_hw_params[i];
-@@ -2056,7 +2057,31 @@ static int ath11k_init_hw_params(struct
+@@ -2154,7 +2155,31 @@ static int ath11k_init_hw_params(struct
ab->hw_params = *hw_params;
--- a/drivers/net/wireless/ath/ath11k/reg.c
+++ b/drivers/net/wireless/ath/ath11k/reg.c
-@@ -362,129 +362,6 @@ static u32 ath11k_map_fw_phy_flags(u32 p
+@@ -363,134 +363,6 @@ static u32 ath11k_map_fw_phy_flags(u32 p
return flags;
}
- /* Use the flags of both the rules */
- new_rule->flags = rule1->flags | rule2->flags;
-
+- if ((rule1->flags & NL80211_RRF_PSD) && (rule2->flags & NL80211_RRF_PSD))
+- new_rule->psd = min_t(s8, rule1->psd, rule2->psd);
+- else
+- new_rule->flags &= ~NL80211_RRF_PSD;
+-
- /* To be safe, lts use the max cac timeout of both rules */
- new_rule->dfs_cac_ms = max_t(u32, rule1->dfs_cac_ms,
- rule2->dfs_cac_ms);
static const char *
ath11k_reg_get_regdom_str(enum nl80211_dfs_regions dfs_region)
{
-@@ -619,9 +496,9 @@ ath11k_reg_update_weather_radar_band(str
+@@ -641,11 +513,11 @@ ath11k_reg_ap_pwr_convert(enum ieee80211
struct ieee80211_regdomain *
ath11k_reg_build_regd(struct ath11k_base *ab,
-- struct cur_regulatory_info *reg_info, bool intersect)
-+ struct cur_regulatory_info *reg_info)
+- struct cur_regulatory_info *reg_info, bool intersect,
++ struct cur_regulatory_info *reg_info,
+ enum wmi_vdev_type vdev_type,
+ enum ieee80211_ap_reg_power power_type)
{
- struct ieee80211_regdomain *tmp_regd, *default_regd, *new_regd = NULL;
+ struct ieee80211_regdomain *new_regd = NULL;
- struct cur_reg_rule *reg_rule;
+ struct cur_reg_rule *reg_rule, *reg_rule_6ghz;
u8 i = 0, j = 0, k = 0;
u8 num_rules;
-@@ -638,26 +515,26 @@ ath11k_reg_build_regd(struct ath11k_base
- num_rules += reg_info->num_6ghz_rules_ap[WMI_REG_INDOOR_AP];
+@@ -688,26 +560,26 @@ ath11k_reg_build_regd(struct ath11k_base
+ }
if (!num_rules)
- goto ret;
reg_info->dfs_region, num_rules);
/* Update reg_rules[] below. Firmware is expected to
* send these rules in order(2 GHz rules first and then 5 GHz)
-@@ -697,7 +574,7 @@ ath11k_reg_build_regd(struct ath11k_base
+@@ -746,7 +618,7 @@ ath11k_reg_build_regd(struct ath11k_base
flags |= ath11k_map_fw_reg_flags(reg_rule->flags);
flags |= ath11k_map_fw_phy_flags(reg_info->phybitmap);
reg_rule->start_freq,
reg_rule->end_freq, max_bw,
reg_rule->ant_gain, reg_rule->reg_power,
-@@ -712,7 +589,7 @@ ath11k_reg_build_regd(struct ath11k_base
+@@ -761,7 +633,7 @@ ath11k_reg_build_regd(struct ath11k_base
reg_info->dfs_region == ATH11K_DFS_REG_ETSI &&
(reg_rule->end_freq > ETSI_WEATHER_RADAR_BAND_LOW &&
reg_rule->start_freq < ETSI_WEATHER_RADAR_BAND_HIGH)){
reg_rule, &i,
flags, max_bw);
continue;
-@@ -723,37 +600,20 @@ ath11k_reg_build_regd(struct ath11k_base
+@@ -772,51 +644,23 @@ ath11k_reg_build_regd(struct ath11k_base
"\t%d. (%d - %d @ %d) (%d, %d) (%d ms) (FLAGS %d) (%d, %d)\n",
i + 1, reg_rule->start_freq, reg_rule->end_freq,
max_bw, reg_rule->ant_gain, reg_rule->reg_power,
}
- tmp_regd->n_reg_rules = i;
--
++ new_regd->n_reg_rules = i;
+
- if (intersect) {
- default_regd = ab->default_regd[reg_info->phy_id];
-
- } else {
- new_regd = tmp_regd;
- }
-+ new_regd->n_reg_rules = i;
-
+-
-ret:
return new_regd;
}
---- a/drivers/net/wireless/ath/ath11k/reg.h
-+++ b/drivers/net/wireless/ath/ath11k/reg.h
-@@ -33,7 +33,7 @@ void ath11k_reg_free(struct ath11k_base
- void ath11k_regd_update_work(struct work_struct *work);
- struct ieee80211_regdomain *
- ath11k_reg_build_regd(struct ath11k_base *ab,
-- struct cur_regulatory_info *reg_info, bool intersect);
-+ struct cur_regulatory_info *reg_info);
- int ath11k_regd_update(struct ath11k *ar);
- int ath11k_reg_update_chan_list(struct ath11k *ar, bool wait);
- #endif
---- a/drivers/net/wireless/ath/ath11k/wmi.c
-+++ b/drivers/net/wireless/ath/ath11k/wmi.c
-@@ -7060,24 +7060,12 @@ static void ath11k_wmi_htc_tx_complete(s
- wake_up(&wmi->tx_ce_desc_wq);
- }
-
-static bool ath11k_reg_is_world_alpha(char *alpha)
-{
- if (alpha[0] == '0' && alpha[1] == '0')
- return false;
-}
-
- static int ath11k_reg_chan_list_event(struct ath11k_base *ab,
- struct sk_buff *skb,
- enum wmi_reg_chan_list_cmd_type id)
+ static enum wmi_vdev_type ath11k_reg_get_ar_vdev_type(struct ath11k *ar)
+ {
+ struct ath11k_vif *arvif;
+@@ -839,7 +683,6 @@ int ath11k_reg_handle_chan_list(struct a
+ enum ieee80211_ap_reg_power power_type)
{
- struct cur_regulatory_info *reg_info = NULL;
- struct ieee80211_regdomain *regd = NULL;
+ struct ieee80211_regdomain *regd;
- bool intersect = false;
- int ret = 0, pdev_idx, i, j;
+ int pdev_idx;
struct ath11k *ar;
-
-@@ -7141,17 +7129,7 @@ static int ath11k_reg_chan_list_event(st
+ enum wmi_vdev_type vdev_type;
+@@ -891,24 +734,14 @@ int ath11k_reg_handle_chan_list(struct a
(char *)reg_info->alpha2, 2))
- goto mem_free;
+ goto retfail;
- /* Intersect new rules with default regd if a new country setting was
- * requested, i.e a default regd was already set during initialization
- !ath11k_reg_is_world_alpha((char *)reg_info->alpha2))
- intersect = true;
-
-- regd = ath11k_reg_build_regd(ab, reg_info, intersect);
-+ regd = ath11k_reg_build_regd(ab, reg_info);
+ ar = ab->pdevs[pdev_idx].ar;
+ vdev_type = ath11k_reg_get_ar_vdev_type(ar);
+
+ ath11k_dbg(ab, ATH11K_DBG_WMI,
+- "wmi handle chan list power type %d vdev type %d intersect %d\n",
+- power_type, vdev_type, intersect);
++ "wmi handle chan list power type %d vdev type %d\n",
++ power_type, vdev_type);
+
+- regd = ath11k_reg_build_regd(ab, reg_info, intersect, vdev_type, power_type);
++ regd = ath11k_reg_build_regd(ab, reg_info, vdev_type, power_type);
if (!regd) {
ath11k_warn(ab, "failed to build regd from reg_info\n");
goto fallback;
+--- a/drivers/net/wireless/ath/ath11k/reg.h
++++ b/drivers/net/wireless/ath/ath11k/reg.h
+@@ -35,7 +35,7 @@ void ath11k_reg_free(struct ath11k_base
+ void ath11k_regd_update_work(struct work_struct *work);
+ struct ieee80211_regdomain *
+ ath11k_reg_build_regd(struct ath11k_base *ab,
+- struct cur_regulatory_info *reg_info, bool intersect,
++ struct cur_regulatory_info *reg_info,
+ enum wmi_vdev_type vdev_type,
+ enum ieee80211_ap_reg_power power_type);
+ int ath11k_regd_update(struct ath11k *ar);
void (*spectral_scan_trigger)(struct ath_hw *ah);
--- a/drivers/net/wireless/ath/ath9k/ar9003_phy.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.c
-@@ -1918,6 +1918,26 @@ void ar9003_hw_init_rate_txpower(struct
+@@ -1915,6 +1915,26 @@ void ar9003_hw_init_rate_txpower(struct
}
}
void ar9003_hw_attach_phy_ops(struct ath_hw *ah)
{
struct ath_hw_private_ops *priv_ops = ath9k_hw_private_ops(ah);
-@@ -1954,6 +1974,7 @@ void ar9003_hw_attach_phy_ops(struct ath
+@@ -1951,6 +1971,7 @@ void ar9003_hw_attach_phy_ops(struct ath
priv_ops->set_radar_params = ar9003_hw_set_radar_params;
priv_ops->fast_chan_change = ar9003_hw_fast_chan_change;
static const u8 ofdm2pwr[] = {
ALL_TARGET_LEGACY_6_24,
ALL_TARGET_LEGACY_6_24,
-@@ -1068,11 +1054,6 @@ static bool ar9003_hw_ani_control(struct
+@@ -1065,11 +1051,6 @@ static bool ar9003_hw_ani_control(struct
struct ath_common *common = ath9k_hw_common(ah);
struct ath9k_channel *chan = ah->curchan;
struct ar5416AniState *aniState = &ah->ani;
s32 value, value2;
switch (cmd & ah->ani_function) {
-@@ -1086,61 +1067,6 @@ static bool ar9003_hw_ani_control(struct
+@@ -1083,61 +1064,6 @@ static bool ar9003_hw_ani_control(struct
*/
u32 on = param ? 1 : 0;
--- a/local-symbols
+++ b/local-symbols
-@@ -128,6 +128,7 @@ ATH9K_WOW=
+@@ -127,6 +127,7 @@ ATH9K_WOW=
ATH9K_RFKILL=
ATH9K_CHANNEL_CONTEXT=
ATH9K_PCOEM=
+
config ATH9K_DEBUGFS
bool "Atheros ath9k debugging"
- depends on ATH9K && DEBUG_FS
+ depends on ATH9K && DEBUG_FS && MAC80211_DEBUGFS
if (!dev_get_platdata(&pdev->dev)) {
dev_err(&pdev->dev, "no platform data specified\n");
-@@ -118,13 +367,16 @@ static int ath_ahb_probe(struct platform
+@@ -118,17 +367,23 @@ static int ath_ahb_probe(struct platform
sc->mem = mem;
sc->irq = irq;
if (ret) {
dev_err(&pdev->dev, "failed to initialize device\n");
goto err_irq;
-@@ -155,6 +407,9 @@ static int ath_ahb_remove(struct platfor
- free_irq(sc->irq, sc);
- ieee80211_free_hw(sc->hw);
}
+#ifdef CONFIG_OF
+ pdev->dev.platform_data = NULL;
+#endif
- return 0;
- }
-@@ -164,6 +419,9 @@ static struct platform_driver ath_ahb_dr
- .remove = ath_ahb_remove,
+ ah = sc->sc_ah;
+ ath9k_hw_name(ah, hw_name, sizeof(hw_name));
+@@ -162,6 +417,9 @@ static struct platform_driver ath_ahb_dr
+ .remove_new = ath_ahb_remove,
.driver = {
.name = "ath9k",
+#ifdef CONFIG_OF
static int modparam_bad_frames_preempt;
module_param_named(bad_frames_preempt, modparam_bad_frames_preempt, int, 0444);
MODULE_PARM_DESC(bad_frames_preempt,
-@@ -2869,10 +2874,10 @@ static int b43_gpio_init(struct b43_wlde
+@@ -2870,10 +2875,10 @@ static int b43_gpio_init(struct b43_wlde
u32 mask, set;
b43_maskset32(dev, B43_MMIO_MACCTL, ~B43_MACCTL_GPOUTSMSK, 0);
antenna = b43_antenna_to_phyctl(antenna);
ctl = b43_shm_read16(dev, B43_SHM_SHARED, B43_SHM_SH_BEACPHYCTL);
/* We can't send beacons with short preamble. Would get PHY errors. */
-@@ -3284,8 +3284,8 @@ static int b43_chip_init(struct b43_wlde
+@@ -3285,8 +3285,8 @@ static int b43_chip_init(struct b43_wlde
/* Select the antennae */
if (phy->ops->set_rx_antenna)
if (phy->type == B43_PHYTYPE_B) {
value16 = b43_read16(dev, 0x005E);
-@@ -3986,7 +3986,6 @@ static int b43_op_config(struct ieee8021
+@@ -3988,7 +3988,6 @@ static int b43_op_config(struct ieee8021
struct b43_wldev *dev = wl->current_dev;
struct b43_phy *phy = &dev->phy;
struct ieee80211_conf *conf = &hw->conf;
int err = 0;
mutex_lock(&wl->mutex);
-@@ -4029,11 +4028,9 @@ static int b43_op_config(struct ieee8021
+@@ -4031,11 +4030,9 @@ static int b43_op_config(struct ieee8021
}
/* Antennas for RX and management frame TX. */
if (wl->radio_enabled != phy->radio_on) {
if (wl->radio_enabled) {
-@@ -5176,6 +5173,47 @@ static int b43_op_get_survey(struct ieee
+@@ -5178,6 +5175,47 @@ static int b43_op_get_survey(struct ieee
return 0;
}
+}
+
static const struct ieee80211_ops b43_hw_ops = {
- .tx = b43_op_tx,
- .wake_tx_queue = ieee80211_handle_wake_tx_queue,
-@@ -5198,6 +5236,8 @@ static const struct ieee80211_ops b43_hw
+ .add_chanctx = ieee80211_emulate_add_chanctx,
+ .remove_chanctx = ieee80211_emulate_remove_chanctx,
+@@ -5204,6 +5242,8 @@ static const struct ieee80211_ops b43_hw
.sw_scan_complete = b43_op_sw_scan_complete_notifier,
.get_survey = b43_op_get_survey,
.rfkill_poll = b43_rfkill_poll,
};
/* Hard-reset the chip. Do not call this directly.
-@@ -5499,6 +5539,8 @@ static int b43_one_core_attach(struct b4
+@@ -5505,6 +5545,8 @@ static int b43_one_core_attach(struct b4
if (!wldev)
goto out;
wldev->use_pio = b43_modparam_pio;
wldev->dev = dev;
wldev->wl = wl;
-@@ -5590,6 +5632,9 @@ static struct b43_wl *b43_wireless_init(
+@@ -5596,6 +5638,9 @@ static struct b43_wl *b43_wireless_init(
wiphy_ext_feature_set(hw->wiphy, NL80211_EXT_FEATURE_CQM_RSSI_LIST);
--- a/drivers/net/wireless/broadcom/b43/main.c
+++ b/drivers/net/wireless/broadcom/b43/main.c
-@@ -2886,6 +2886,14 @@ static int b43_gpio_init(struct b43_wlde
+@@ -2887,6 +2887,14 @@ static int b43_gpio_init(struct b43_wlde
} else if (dev->dev->chip_id == 0x5354) {
/* Don't allow overtaking buttons GPIOs */
set &= 0x2; /* 0x2 is LED GPIO on BCM5354 */
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
-@@ -979,8 +979,36 @@ static struct wireless_dev *brcmf_cfg802
+@@ -980,8 +980,36 @@ static struct wireless_dev *brcmf_cfg802
struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
struct brcmf_pub *drvr = cfg->pub;
struct wireless_dev *wdev;
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
-@@ -3327,6 +3327,10 @@ brcmf_cfg80211_set_power_mgmt(struct wip
+@@ -3313,6 +3313,10 @@ brcmf_cfg80211_set_power_mgmt(struct wip
* preference in cfg struct to apply this to
* FW later while initializing the dongle
*/
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
-@@ -7987,6 +7987,7 @@ static s32 brcmf_translate_country_code(
+@@ -7979,6 +7979,7 @@ static s32 brcmf_translate_country_code(
return 0;
}
static int
brcmf_parse_dump_obss(char *buf, struct brcmf_dump_survey *survey)
{
-@@ -8209,6 +8210,7 @@ exit:
+@@ -8201,6 +8202,7 @@ exit:
brcmf_set_mpc(ifp, 1);
return err;
}
static void brcmf_cfg80211_reg_notifier(struct wiphy *wiphy,
struct regulatory_request *req)
-@@ -8361,8 +8363,10 @@ struct brcmf_cfg80211_info *brcmf_cfg802
+@@ -8353,8 +8355,10 @@ struct brcmf_cfg80211_info *brcmf_cfg802
if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_WOWL_GTK))
ops->set_rekey_data = brcmf_cfg80211_set_rekey_data;
#endif
--- a/local-symbols
+++ b/local-symbols
-@@ -493,43 +493,6 @@ USB_VL600=
+@@ -477,43 +477,6 @@ USB_VL600=
USB_NET_CH9200=
USB_NET_AQC111=
USB_RTL8153_ECM=
config B43_PHY_G
--- a/drivers/net/wireless/broadcom/b43/main.c
+++ b/drivers/net/wireless/broadcom/b43/main.c
-@@ -2853,7 +2853,7 @@ static struct ssb_device *b43_ssb_gpio_d
+@@ -2854,7 +2854,7 @@ static struct ssb_device *b43_ssb_gpio_d
{
struct ssb_bus *bus = dev->dev->sdev->bus;
return (bus->chipco.dev ? bus->chipco.dev : bus->pcicore.dev);
#else
return bus->chipco.dev;
-@@ -4871,7 +4871,7 @@ static int b43_wireless_core_init(struct
+@@ -4873,7 +4873,7 @@ static int b43_wireless_core_init(struct
}
if (sprom->boardflags_lo & B43_BFL_XTAL_NOSLOW)
hf |= B43_HF_DSCRQ; /* Disable slowclock requests from ucode. */
depends on CORDIC
--- a/Kconfig.local
+++ b/Kconfig.local
-@@ -1483,117 +1483,6 @@ config BACKPORTED_USB_NET_AQC111
+@@ -1435,117 +1435,6 @@ config BACKPORTED_USB_NET_AQC111
config BACKPORTED_USB_RTL8153_ECM
tristate
default USB_RTL8153_ECM
--- a/drivers/net/wireless/virtual/mac80211_hwsim.c
+++ b/drivers/net/wireless/virtual/mac80211_hwsim.c
-@@ -6179,7 +6179,9 @@ static struct genl_family hwsim_genl_fam
+@@ -6331,7 +6331,9 @@ static struct genl_family hwsim_genl_fam
.module = THIS_MODULE,
.small_ops = hwsim_ops,
.n_small_ops = ARRAY_SIZE(hwsim_ops),
};
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
-@@ -17551,7 +17551,9 @@ static struct genl_family nl80211_fam __
+@@ -17498,7 +17498,9 @@ static struct genl_family nl80211_fam __
.n_ops = ARRAY_SIZE(nl80211_ops),
.small_ops = nl80211_small_ops,
.n_small_ops = ARRAY_SIZE(nl80211_small_ops),
-MHI_BUS_EP=
QCOM_AOSS_QMP=
QCOM_COMMAND_DB=
- QCOM_CPR=
+ QCOM_GENI_SE=
--- a/backport-include/linux/random.h
+++ b/backport-include/linux/random.h
-@@ -23,7 +23,7 @@ static inline u16 get_random_u16(void)
+@@ -15,7 +15,7 @@ static inline u16 get_random_u16(void)
}
#endif
+++ /dev/null
-From: Felix Fietkau <nbd@nbd.name>
-Date: Mon, 17 Apr 2023 19:42:38 +0200
-Subject: [PATCH] Revert "wifi: iwlwifi: Use generic thermal_zone_get_trip()
- function"
-
-This reverts commit 3d2f20ad46f83b333025f5e8e4afc34be8f13c4c.
----
-
---- a/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h
-+++ b/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h
-@@ -531,7 +531,7 @@ struct iwl_mvm_tt_mgmt {
- * @tzone: thermal zone device data
- */
- struct iwl_mvm_thermal_device {
-- struct thermal_trip trips[IWL_MAX_DTS_TRIPS];
-+ s16 temp_trips[IWL_MAX_DTS_TRIPS];
- u8 fw_trips_index[IWL_MAX_DTS_TRIPS];
- struct thermal_zone_device *tzone;
- };
---- a/drivers/net/wireless/intel/iwlwifi/mvm/tt.c
-+++ b/drivers/net/wireless/intel/iwlwifi/mvm/tt.c
-@@ -573,11 +573,11 @@ int iwl_mvm_send_temp_report_ths_cmd(str
- * and uncompressed, the FW should get it compressed and sorted
- */
-
-- /* compress trips to cmd array, remove uninitialized values*/
-+ /* compress temp_trips to cmd array, remove uninitialized values*/
- for (i = 0; i < IWL_MAX_DTS_TRIPS; i++) {
-- if (mvm->tz_device.trips[i].temperature != INT_MIN) {
-+ if (mvm->tz_device.temp_trips[i] != S16_MIN) {
- cmd.thresholds[idx++] =
-- cpu_to_le16((s16)(mvm->tz_device.trips[i].temperature / 1000));
-+ cpu_to_le16(mvm->tz_device.temp_trips[i]);
- }
- }
- cmd.num_temps = cpu_to_le32(idx);
-@@ -593,8 +593,8 @@ int iwl_mvm_send_temp_report_ths_cmd(str
- */
- for (i = 0; i < idx; i++) {
- for (j = 0; j < IWL_MAX_DTS_TRIPS; j++) {
-- if ((int)(le16_to_cpu(cmd.thresholds[i]) * 1000) ==
-- mvm->tz_device.trips[j].temperature)
-+ if (le16_to_cpu(cmd.thresholds[i]) ==
-+ mvm->tz_device.temp_trips[j])
- mvm->tz_device.fw_trips_index[i] = j;
- }
- }
-@@ -638,12 +638,37 @@ out:
- return ret;
- }
-
-+static int iwl_mvm_tzone_get_trip_temp(struct thermal_zone_device *device,
-+ int trip, int *temp)
-+{
-+ struct iwl_mvm *mvm = (struct iwl_mvm *)device->devdata;
-+
-+ if (trip < 0 || trip >= IWL_MAX_DTS_TRIPS)
-+ return -EINVAL;
-+
-+ *temp = mvm->tz_device.temp_trips[trip] * 1000;
-+
-+ return 0;
-+}
-+
-+static int iwl_mvm_tzone_get_trip_type(struct thermal_zone_device *device,
-+ int trip, enum thermal_trip_type *type)
-+{
-+ if (trip < 0 || trip >= IWL_MAX_DTS_TRIPS)
-+ return -EINVAL;
-+
-+ *type = THERMAL_TRIP_PASSIVE;
-+
-+ return 0;
-+}
-+
- static int iwl_mvm_tzone_set_trip_temp(struct thermal_zone_device *device,
- int trip, int temp)
- {
- struct iwl_mvm *mvm = thermal_zone_device_priv(device);
- struct iwl_mvm_thermal_device *tzone;
-- int ret;
-+ int i, ret;
-+ s16 temperature;
-
- mutex_lock(&mvm->mutex);
-
-@@ -653,17 +678,40 @@ static int iwl_mvm_tzone_set_trip_temp(s
- goto out;
- }
-
-+ if (trip < 0 || trip >= IWL_MAX_DTS_TRIPS) {
-+ ret = -EINVAL;
-+ goto out;
-+ }
-+
- if ((temp / 1000) > S16_MAX) {
- ret = -EINVAL;
- goto out;
- }
-
-+ temperature = (s16)(temp / 1000);
- tzone = &mvm->tz_device;
-+
- if (!tzone) {
- ret = -EIO;
- goto out;
- }
-
-+ /* no updates*/
-+ if (tzone->temp_trips[trip] == temperature) {
-+ ret = 0;
-+ goto out;
-+ }
-+
-+ /* already existing temperature */
-+ for (i = 0; i < IWL_MAX_DTS_TRIPS; i++) {
-+ if (tzone->temp_trips[i] == temperature) {
-+ ret = -EINVAL;
-+ goto out;
-+ }
-+ }
-+
-+ tzone->temp_trips[trip] = temperature;
-+
- ret = iwl_mvm_send_temp_report_ths_cmd(mvm);
- out:
- mutex_unlock(&mvm->mutex);
-@@ -672,6 +720,8 @@ out:
-
- static struct thermal_zone_device_ops tzone_ops = {
- .get_temp = iwl_mvm_tzone_get_temp,
-+ .get_trip_temp = iwl_mvm_tzone_get_trip_temp,
-+ .get_trip_type = iwl_mvm_tzone_get_trip_type,
- .set_trip_temp = iwl_mvm_tzone_set_trip_temp,
- };
-
-@@ -693,8 +743,7 @@ static void iwl_mvm_thermal_zone_registe
- BUILD_BUG_ON(ARRAY_SIZE(name) >= THERMAL_NAME_LENGTH);
-
- sprintf(name, "iwlwifi_%u", atomic_inc_return(&counter) & 0xFF);
-- mvm->tz_device.tzone = thermal_zone_device_register_with_trips(name,
-- mvm->tz_device.trips,
-+ mvm->tz_device.tzone = thermal_zone_device_register(name,
- IWL_MAX_DTS_TRIPS,
- IWL_WRITABLE_TRIPS_MSK,
- mvm, &tzone_ops,
-@@ -717,10 +766,8 @@ static void iwl_mvm_thermal_zone_registe
- /* 0 is a valid temperature,
- * so initialize the array with S16_MIN which invalid temperature
- */
-- for (i = 0 ; i < IWL_MAX_DTS_TRIPS; i++) {
-- mvm->tz_device.trips[i].temperature = INT_MIN;
-- mvm->tz_device.trips[i].type = THERMAL_TRIP_PASSIVE;
-- }
-+ for (i = 0 ; i < IWL_MAX_DTS_TRIPS; i++)
-+ mvm->tz_device.temp_trips[i] = S16_MIN;
- }
-
- static int iwl_mvm_tcool_get_max_state(struct thermal_cooling_device *cdev,
--- /dev/null
+--- a/drivers/net/wireless/intel/iwlwifi/mvm/tt.c
++++ b/drivers/net/wireless/intel/iwlwifi/mvm/tt.c
+@@ -689,13 +689,23 @@ static void iwl_mvm_thermal_zone_registe
+ for (i = 0 ; i < IWL_MAX_DTS_TRIPS; i++) {
+ mvm->tz_device.trips[i].temperature = THERMAL_TEMP_INVALID;
+ mvm->tz_device.trips[i].type = THERMAL_TRIP_PASSIVE;
++#if LINUX_VERSION_IS_GEQ(6,9,0)
+ mvm->tz_device.trips[i].flags = THERMAL_TRIP_FLAG_RW_TEMP;
++#endif
+ }
++#if LINUX_VERSION_IS_GEQ(6,9,0)
+ mvm->tz_device.tzone = thermal_zone_device_register_with_trips(name,
+ mvm->tz_device.trips,
+ IWL_MAX_DTS_TRIPS,
+ mvm, &tzone_ops,
+ NULL, 0, 0);
++#else
++ mvm->tz_device.tzone = thermal_zone_device_register_with_trips(name,
++ mvm->tz_device.trips,
++ IWL_MAX_DTS_TRIPS, 0,
++ mvm, &tzone_ops,
++ NULL, 0, 0);
++#endif
+ if (IS_ERR(mvm->tz_device.tzone)) {
+ IWL_DEBUG_TEMP(mvm,
+ "Failed to register to thermal zone (err = %ld)\n",
--- /dev/null
+--- a/net/wireless/nl80211.c
++++ b/net/wireless/nl80211.c
+@@ -16379,9 +16379,14 @@ static u32 nl80211_internal_flags[] = {
+ #undef SELECTOR
+ };
+
++#if LINUX_VERSION_IS_LESS(6,2,0)
++static int nl80211_pre_doit(const struct genl_ops *ops, struct sk_buff *skb,
++ struct genl_info *info)
++#else
+ static int nl80211_pre_doit(const struct genl_split_ops *ops,
+ struct sk_buff *skb,
+ struct genl_info *info)
++#endif
+ {
+ struct cfg80211_registered_device *rdev = NULL;
+ struct wireless_dev *wdev = NULL;
+@@ -16481,9 +16486,14 @@ out_unlock:
+ return err;
+ }
+
++#if LINUX_VERSION_IS_LESS(6,2,0)
++static void nl80211_post_doit(const struct genl_ops *ops, struct sk_buff *skb,
++ struct genl_info *info)
++#else
+ static void nl80211_post_doit(const struct genl_split_ops *ops,
+ struct sk_buff *skb,
+ struct genl_info *info)
++#endif
+ {
+ u32 internal_flags = nl80211_internal_flags[ops->internal_flags];
+
+++ /dev/null
---- a/net/wireless/nl80211.c
-+++ b/net/wireless/nl80211.c
-@@ -16442,8 +16442,7 @@ static u32 nl80211_internal_flags[] = {
- #undef SELECTOR
- };
-
--static int nl80211_pre_doit(const struct genl_split_ops *ops,
-- struct sk_buff *skb,
-+static int nl80211_pre_doit(const struct genl_ops *ops, struct sk_buff *skb,
- struct genl_info *info)
- {
- struct cfg80211_registered_device *rdev = NULL;
-@@ -16544,8 +16543,7 @@ out_unlock:
- return err;
- }
-
--static void nl80211_post_doit(const struct genl_split_ops *ops,
-- struct sk_buff *skb,
-+static void nl80211_post_doit(const struct genl_ops *ops, struct sk_buff *skb,
- struct genl_info *info)
- {
- u32 internal_flags = nl80211_internal_flags[ops->internal_flags];
+++ /dev/null
---- a/backport-include/net/genetlink.h
-+++ b/backport-include/net/genetlink.h
-@@ -3,6 +3,7 @@
- #include_next <net/genetlink.h>
- #include <linux/version.h>
-
-+#if LINUX_VERSION_IS_LESS(4,12,0)
- static inline void __bp_genl_info_userhdr_set(struct genl_info *info,
- void *userhdr)
- {
-@@ -14,7 +15,6 @@ static inline void *__bp_genl_info_userh
- return info->userhdr;
- }
-
--#if LINUX_VERSION_IS_LESS(4,12,0)
- #define GENL_SET_ERR_MSG(info, msg) NL_SET_ERR_MSG(genl_info_extack(info), msg)
-
- static inline int genl_err_attr(struct genl_info *info, int err,
-@@ -44,11 +44,13 @@ static inline struct netlink_ext_ack *ge
- #endif
- }
-
-+#if LINUX_VERSION_IS_LESS(6,6,0)
- /* this gets put in place of info->userhdr, since we use that above */
- static inline void *genl_info_userhdr(struct genl_info *info)
- {
- return (u8 *)info->genlhdr + GENL_HDRLEN;
- }
-+#endif
-
- #if LINUX_VERSION_IS_LESS(4,10,0)
- #define __genl_ro_after_init
--- /dev/null
+--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c
++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c
+@@ -1581,7 +1581,11 @@ static int brcmf_usb_reset_device(struct
+
+ void brcmf_usb_exit(void)
+ {
++#if LINUX_VERSION_IS_GEQ(6,8,0)
+ struct device_driver *drv = &brcmf_usbdrvr.driver;
++#else
++ struct device_driver *drv = &brcmf_usbdrvr.drvwrap.driver;
++#endif
+ int ret;
+
+ brcmf_dbg(USB, "Enter\n");
+++ /dev/null
---- a/net/wireless/nl80211.c
-+++ b/net/wireless/nl80211.c
-@@ -16442,8 +16442,14 @@ static u32 nl80211_internal_flags[] = {
- #undef SELECTOR
- };
-
-+#if LINUX_VERSION_IS_LESS(6,2,0)
- static int nl80211_pre_doit(const struct genl_ops *ops, struct sk_buff *skb,
- struct genl_info *info)
-+#else
-+static int nl80211_pre_doit(const struct genl_split_ops *ops,
-+ struct sk_buff *skb,
-+ struct genl_info *info)
-+#endif
- {
- struct cfg80211_registered_device *rdev = NULL;
- struct wireless_dev *wdev = NULL;
-@@ -16543,8 +16549,14 @@ out_unlock:
- return err;
- }
-
-+#if LINUX_VERSION_IS_LESS(6,2,0)
- static void nl80211_post_doit(const struct genl_ops *ops, struct sk_buff *skb,
- struct genl_info *info)
-+#else
-+static void nl80211_post_doit(const struct genl_split_ops *ops,
-+ struct sk_buff *skb,
-+ struct genl_info *info)
-+#endif
- {
- u32 internal_flags = nl80211_internal_flags[ops->internal_flags];
-
+++ /dev/null
---- a/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h
-+++ b/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h
-@@ -531,7 +531,11 @@ struct iwl_mvm_tt_mgmt {
- * @tzone: thermal zone device data
- */
- struct iwl_mvm_thermal_device {
-+#if LINUX_VERSION_IS_LESS(6,6,0)
- s16 temp_trips[IWL_MAX_DTS_TRIPS];
-+#else
-+ struct thermal_trip trips[IWL_MAX_DTS_TRIPS];
-+#endif
- u8 fw_trips_index[IWL_MAX_DTS_TRIPS];
- struct thermal_zone_device *tzone;
- };
---- a/drivers/net/wireless/intel/iwlwifi/mvm/tt.c
-+++ b/drivers/net/wireless/intel/iwlwifi/mvm/tt.c
-@@ -573,6 +573,7 @@ int iwl_mvm_send_temp_report_ths_cmd(str
- * and uncompressed, the FW should get it compressed and sorted
- */
-
-+#if LINUX_VERSION_IS_LESS(6,6,0)
- /* compress temp_trips to cmd array, remove uninitialized values*/
- for (i = 0; i < IWL_MAX_DTS_TRIPS; i++) {
- if (mvm->tz_device.temp_trips[i] != S16_MIN) {
-@@ -580,6 +581,15 @@ int iwl_mvm_send_temp_report_ths_cmd(str
- cpu_to_le16(mvm->tz_device.temp_trips[i]);
- }
- }
-+#else
-+ /* compress trips to cmd array, remove uninitialized values*/
-+ for (i = 0; i < IWL_MAX_DTS_TRIPS; i++) {
-+ if (mvm->tz_device.trips[i].temperature != INT_MIN) {
-+ cmd.thresholds[idx++] =
-+ cpu_to_le16((s16)(mvm->tz_device.trips[i].temperature / 1000));
-+ }
-+ }
-+#endif
- cmd.num_temps = cpu_to_le32(idx);
-
- if (!idx)
-@@ -593,8 +603,13 @@ int iwl_mvm_send_temp_report_ths_cmd(str
- */
- for (i = 0; i < idx; i++) {
- for (j = 0; j < IWL_MAX_DTS_TRIPS; j++) {
-+#if LINUX_VERSION_IS_LESS(6,6,0)
- if (le16_to_cpu(cmd.thresholds[i]) ==
- mvm->tz_device.temp_trips[j])
-+#else
-+ if ((int)(le16_to_cpu(cmd.thresholds[i]) * 1000) ==
-+ mvm->tz_device.trips[j].temperature)
-+#endif
- mvm->tz_device.fw_trips_index[i] = j;
- }
- }
-@@ -638,6 +653,7 @@ out:
- return ret;
- }
-
-+#if LINUX_VERSION_IS_LESS(6,6,0)
- static int iwl_mvm_tzone_get_trip_temp(struct thermal_zone_device *device,
- int trip, int *temp)
- {
-@@ -661,14 +677,19 @@ static int iwl_mvm_tzone_get_trip_type(s
-
- return 0;
- }
-+#endif
-
- static int iwl_mvm_tzone_set_trip_temp(struct thermal_zone_device *device,
- int trip, int temp)
- {
- struct iwl_mvm *mvm = thermal_zone_device_priv(device);
- struct iwl_mvm_thermal_device *tzone;
-+#if LINUX_VERSION_IS_LESS(6,6,0)
- int i, ret;
- s16 temperature;
-+#else
-+ int ret;
-+#endif
-
- mutex_lock(&mvm->mutex);
-
-@@ -678,17 +699,21 @@ static int iwl_mvm_tzone_set_trip_temp(s
- goto out;
- }
-
-+#if LINUX_VERSION_IS_LESS(6,6,0)
- if (trip < 0 || trip >= IWL_MAX_DTS_TRIPS) {
- ret = -EINVAL;
- goto out;
- }
-+#endif
-
- if ((temp / 1000) > S16_MAX) {
- ret = -EINVAL;
- goto out;
- }
-
-+#if LINUX_VERSION_IS_LESS(6,6,0)
- temperature = (s16)(temp / 1000);
-+#endif
- tzone = &mvm->tz_device;
-
- if (!tzone) {
-@@ -696,6 +721,7 @@ static int iwl_mvm_tzone_set_trip_temp(s
- goto out;
- }
-
-+#if LINUX_VERSION_IS_LESS(6,6,0)
- /* no updates*/
- if (tzone->temp_trips[trip] == temperature) {
- ret = 0;
-@@ -711,6 +737,7 @@ static int iwl_mvm_tzone_set_trip_temp(s
- }
-
- tzone->temp_trips[trip] = temperature;
-+#endif
-
- ret = iwl_mvm_send_temp_report_ths_cmd(mvm);
- out:
-@@ -720,8 +747,10 @@ out:
-
- static struct thermal_zone_device_ops tzone_ops = {
- .get_temp = iwl_mvm_tzone_get_temp,
-+#if LINUX_VERSION_IS_LESS(6,6,0)
- .get_trip_temp = iwl_mvm_tzone_get_trip_temp,
- .get_trip_type = iwl_mvm_tzone_get_trip_type,
-+#endif
- .set_trip_temp = iwl_mvm_tzone_set_trip_temp,
- };
-
-@@ -743,7 +772,12 @@ static void iwl_mvm_thermal_zone_registe
- BUILD_BUG_ON(ARRAY_SIZE(name) >= THERMAL_NAME_LENGTH);
-
- sprintf(name, "iwlwifi_%u", atomic_inc_return(&counter) & 0xFF);
-+#if LINUX_VERSION_IS_LESS(6,6,0)
- mvm->tz_device.tzone = thermal_zone_device_register(name,
-+#else
-+ mvm->tz_device.tzone = thermal_zone_device_register_with_trips(name,
-+ mvm->tz_device.trips,
-+#endif
- IWL_MAX_DTS_TRIPS,
- IWL_WRITABLE_TRIPS_MSK,
- mvm, &tzone_ops,
-@@ -766,8 +800,15 @@ static void iwl_mvm_thermal_zone_registe
- /* 0 is a valid temperature,
- * so initialize the array with S16_MIN which invalid temperature
- */
-+#if LINUX_VERSION_IS_LESS(6,6,0)
- for (i = 0 ; i < IWL_MAX_DTS_TRIPS; i++)
- mvm->tz_device.temp_trips[i] = S16_MIN;
-+#else
-+ for (i = 0 ; i < IWL_MAX_DTS_TRIPS; i++) {
-+ mvm->tz_device.trips[i].temperature = INT_MIN;
-+ mvm->tz_device.trips[i].type = THERMAL_TRIP_PASSIVE;
-+ }
-+#endif
- }
-
- static int iwl_mvm_tcool_get_max_state(struct thermal_cooling_device *cdev,
--- a/drivers/net/wireless/marvell/mwl8k.c
+++ b/drivers/net/wireless/marvell/mwl8k.c
-@@ -5703,6 +5703,7 @@ MODULE_FIRMWARE("mwl8k/fmimage_8366.fw")
+@@ -5707,6 +5707,7 @@ MODULE_FIRMWARE("mwl8k/fmimage_8366.fw")
MODULE_FIRMWARE(MWL8K_8366_AP_FW(MWL8K_8366_AP_FW_API));
static const struct pci_device_id mwl8k_pci_id_table[] = {
--- a/drivers/net/wireless/marvell/mwl8k.c
+++ b/drivers/net/wireless/marvell/mwl8k.c
-@@ -6289,6 +6289,8 @@ static int mwl8k_probe(struct pci_dev *p
+@@ -6293,6 +6293,8 @@ static int mwl8k_probe(struct pci_dev *p
priv->running_bsses = 0;
return rc;
err_stop_firmware:
-@@ -6322,8 +6324,6 @@ static void mwl8k_remove(struct pci_dev
+@@ -6326,8 +6328,6 @@ static void mwl8k_remove(struct pci_dev
return;
priv = hw->priv;
mwifiex_init_fw_complete(adapter);
return -1;
} else if (adapter->last_init_cmd == cmdresp_no)
-@@ -1273,8 +1353,8 @@ mwifiex_process_sleep_confirm_resp(struc
+@@ -1265,8 +1345,8 @@ mwifiex_process_sleep_confirm_resp(struc
if (command != HostCmd_CMD_802_11_PS_MODE_ENH) {
mwifiex_dbg(adapter, ERROR,
--- a/drivers/net/wireless/marvell/mwifiex/main.h
+++ b/drivers/net/wireless/marvell/mwifiex/main.h
-@@ -1086,6 +1086,8 @@ void mwifiex_cancel_all_pending_cmd(stru
+@@ -1084,6 +1084,8 @@ void mwifiex_cancel_all_pending_cmd(stru
void mwifiex_cancel_pending_scan_cmd(struct mwifiex_adapter *adapter);
void mwifiex_cancel_scan(struct mwifiex_adapter *adapter);
+++ /dev/null
-From 2ecfe6f07e8e6257cad3d3290c5aec2102120041 Mon Sep 17 00:00:00 2001
-From: Shiji Yang <yangshiji66@outlook.com>
-Date: Sat, 23 Sep 2023 09:01:01 +0800
-Subject: wifi: rt2x00: fix MT7620 low RSSI issue
-
-On Mediatek vendor driver[1], MT7620 (RT6352) uses different RSSI
-base value '-2' compared to the other RT2x00 chips. This patch
-introduces the SoC specific base value to fix the low RSSI value
-reports on MT7620.
-
-[1] Found on MT76x2E_MT7620_LinuxAP_V3.0.4.0_P3 ConvertToRssi().
-
-Signed-off-by: Shiji Yang <yangshiji66@outlook.com>
-Acked-by: Stanislaw Gruszka <stf_xl@wp.pl>
-Signed-off-by: Kalle Valo <kvalo@kernel.org>
-Link: https://lore.kernel.org/r/TYAP286MB031571CDB146C414A908A66DBCFEA@TYAP286MB0315.JPNP286.PROD.OUTLOOK.COM
----
- drivers/net/wireless/ralink/rt2x00/rt2800lib.c | 7 ++++---
- 1 file changed, 4 insertions(+), 3 deletions(-)
-
---- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
-+++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
-@@ -856,6 +856,7 @@ static int rt2800_agc_to_rssi(struct rt2
- s8 rssi0 = rt2x00_get_field32(rxwi_w2, RXWI_W2_RSSI0);
- s8 rssi1 = rt2x00_get_field32(rxwi_w2, RXWI_W2_RSSI1);
- s8 rssi2 = rt2x00_get_field32(rxwi_w2, RXWI_W2_RSSI2);
-+ s8 base_val = rt2x00_rt(rt2x00dev, RT6352) ? -2 : -12;
- u16 eeprom;
- u8 offset0;
- u8 offset1;
-@@ -880,9 +881,9 @@ static int rt2800_agc_to_rssi(struct rt2
- * If the value in the descriptor is 0, it is considered invalid
- * and the default (extremely low) rssi value is assumed
- */
-- rssi0 = (rssi0) ? (-12 - offset0 - rt2x00dev->lna_gain - rssi0) : -128;
-- rssi1 = (rssi1) ? (-12 - offset1 - rt2x00dev->lna_gain - rssi1) : -128;
-- rssi2 = (rssi2) ? (-12 - offset2 - rt2x00dev->lna_gain - rssi2) : -128;
-+ rssi0 = (rssi0) ? (base_val - offset0 - rt2x00dev->lna_gain - rssi0) : -128;
-+ rssi1 = (rssi1) ? (base_val - offset1 - rt2x00dev->lna_gain - rssi1) : -128;
-+ rssi2 = (rssi2) ? (base_val - offset2 - rt2x00dev->lna_gain - rssi2) : -128;
-
- /*
- * mac80211 only accepts a single RSSI value. Calculating the
+++ /dev/null
-From 69708fbb2c698f262e03360d064c7066e0679953 Mon Sep 17 00:00:00 2001
-From: Shiji Yang <yangshiji66@outlook.com>
-Date: Sat, 14 Oct 2023 14:55:01 +0800
-Subject: wifi: rt2x00: fix rt2800 watchdog function
-
-The watchdog function is broken on rt2800 series SoCs. This patch
-fixes the incorrect watchdog logic to make it work again.
-
-1. Update current wdt queue index if it's not equal to the previous
- index. Watchdog compares the current and previous queue index to
- judge if the queue hung.
-2. Make sure hung_{rx,tx} 'true' status won't be override by the
- normal queue. Any queue hangs should trigger a reset action.
-3. Clear the watchdog counter of all queues before resetting the
- hardware. This change may help to avoid the reset loop.
-4. Change hang check function return type to bool as we only need
- to return two status, yes or no.
-
-Signed-off-by: Shiji Yang <yangshiji66@outlook.com>
-Acked-by: Stanislaw Gruszka <stf_xl@wp.pl>
-Signed-off-by: Kalle Valo <kvalo@kernel.org>
-Link: https://lore.kernel.org/r/TYAP286MB0315BC1D83D31154924F0D39BCD1A@TYAP286MB0315.JPNP286.PROD.OUTLOOK.COM
----
- drivers/net/wireless/ralink/rt2x00/rt2800lib.c | 17 +++++++++++------
- 1 file changed, 11 insertions(+), 6 deletions(-)
-
---- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
-+++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
-@@ -1237,13 +1237,14 @@ void rt2800_txdone_nostatus(struct rt2x0
- }
- EXPORT_SYMBOL_GPL(rt2800_txdone_nostatus);
-
--static int rt2800_check_hung(struct data_queue *queue)
-+static bool rt2800_check_hung(struct data_queue *queue)
- {
- unsigned int cur_idx = rt2800_drv_get_dma_done(queue);
-
-- if (queue->wd_idx != cur_idx)
-+ if (queue->wd_idx != cur_idx) {
-+ queue->wd_idx = cur_idx;
- queue->wd_count = 0;
-- else
-+ } else
- queue->wd_count++;
-
- return queue->wd_count > 16;
-@@ -1280,7 +1281,7 @@ void rt2800_watchdog(struct rt2x00_dev *
- case QID_MGMT:
- if (rt2x00queue_empty(queue))
- continue;
-- hung_tx = rt2800_check_hung(queue);
-+ hung_tx = hung_tx || rt2800_check_hung(queue);
- break;
- case QID_RX:
- /* For station mode we should reactive at least
-@@ -1289,7 +1290,7 @@ void rt2800_watchdog(struct rt2x00_dev *
- */
- if (rt2x00dev->intf_sta_count == 0)
- continue;
-- hung_rx = rt2800_check_hung(queue);
-+ hung_rx = hung_rx || rt2800_check_hung(queue);
- break;
- default:
- break;
-@@ -1302,8 +1303,12 @@ void rt2800_watchdog(struct rt2x00_dev *
- if (hung_rx)
- rt2x00_warn(rt2x00dev, "Watchdog RX hung detected\n");
-
-- if (hung_tx || hung_rx)
-+ if (hung_tx || hung_rx) {
-+ queue_for_each(rt2x00dev, queue)
-+ queue->wd_count = 0;
-+
- ieee80211_restart_hw(rt2x00dev->hw);
-+ }
- }
- EXPORT_SYMBOL_GPL(rt2800_watchdog);
-
+++ /dev/null
-From 1ffe76d5ae78553948d67a978acd9945c2f0a175 Mon Sep 17 00:00:00 2001
-From: Shiji Yang <yangshiji66@outlook.com>
-Date: Thu, 19 Oct 2023 19:58:56 +0800
-Subject: wifi: rt2x00: improve MT7620 register initialization
-
-1. Do not hard reset the BBP. We can use soft reset instead. This
- change has some help to the calibration failure issue.
-2. Enable falling back to legacy rate from the HT/RTS rate by
- setting the HT_FBK_TO_LEGACY register.
-3. Implement MCS rate specific maximum PSDU size. It can improve
- the transmission quality under the low RSSI condition.
-4. Set BBP_84 register value to 0x19. This is used for extension
- channel overlapping IOT.
-
-Signed-off-by: Shiji Yang <yangshiji66@outlook.com>
-Acked-by: Stanislaw Gruszka <stf_xl@wp.pl>
-Signed-off-by: Kalle Valo <kvalo@kernel.org>
-Link: https://lore.kernel.org/r/TYAP286MB031553CCD4B7A3B89C85935DBCD4A@TYAP286MB0315.JPNP286.PROD.OUTLOOK.COM
----
- drivers/net/wireless/ralink/rt2x00/rt2800.h | 18 ++++++++++++++++++
- drivers/net/wireless/ralink/rt2x00/rt2800lib.c | 24 ++++++++++++++++++++++++
- drivers/net/wireless/ralink/rt2x00/rt2800mmio.c | 3 +++
- 3 files changed, 45 insertions(+)
-
---- a/drivers/net/wireless/ralink/rt2x00/rt2800.h
-+++ b/drivers/net/wireless/ralink/rt2x00/rt2800.h
-@@ -871,6 +871,18 @@
- #define LED_CFG_LED_POLAR FIELD32(0x40000000)
-
- /*
-+ * AMPDU_MAX_LEN_20M1S: Per MCS max A-MPDU length, 20 MHz, MCS 0-7
-+ * AMPDU_MAX_LEN_20M2S: Per MCS max A-MPDU length, 20 MHz, MCS 8-15
-+ * AMPDU_MAX_LEN_40M1S: Per MCS max A-MPDU length, 40 MHz, MCS 0-7
-+ * AMPDU_MAX_LEN_40M2S: Per MCS max A-MPDU length, 40 MHz, MCS 8-15
-+ * Maximum A-MPDU length = 2^(AMPDU_MAX - 5) kilobytes
-+ */
-+#define AMPDU_MAX_LEN_20M1S 0x1030
-+#define AMPDU_MAX_LEN_20M2S 0x1034
-+#define AMPDU_MAX_LEN_40M1S 0x1038
-+#define AMPDU_MAX_LEN_40M2S 0x103C
-+
-+/*
- * AMPDU_BA_WINSIZE: Force BlockAck window size
- * FORCE_WINSIZE_ENABLE:
- * 0: Disable forcing of BlockAck window size
-@@ -1545,6 +1557,12 @@
- */
- #define EXP_ACK_TIME 0x1380
-
-+/*
-+ * HT_FBK_TO_LEGACY: Enable/Disable HT/RTS fallback to OFDM/CCK rate
-+ * Not available for legacy SoCs
-+ */
-+#define HT_FBK_TO_LEGACY 0x1384
-+
- /* TX_PWR_CFG_5 */
- #define TX_PWR_CFG_5 0x1384
- #define TX_PWR_CFG_5_MCS16_CH0 FIELD32(0x0000000f)
---- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
-+++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
-@@ -5851,6 +5851,7 @@ static int rt2800_init_registers(struct
- struct rt2800_drv_data *drv_data = rt2x00dev->drv_data;
- u32 reg;
- u16 eeprom;
-+ u8 bbp;
- unsigned int i;
- int ret;
-
-@@ -5860,6 +5861,19 @@ static int rt2800_init_registers(struct
- if (ret)
- return ret;
-
-+ if (rt2x00_rt(rt2x00dev, RT6352)) {
-+ rt2800_register_write(rt2x00dev, MAC_SYS_CTRL, 0x01);
-+
-+ bbp = rt2800_bbp_read(rt2x00dev, 21);
-+ bbp |= 0x01;
-+ rt2800_bbp_write(rt2x00dev, 21, bbp);
-+ bbp = rt2800_bbp_read(rt2x00dev, 21);
-+ bbp &= (~0x01);
-+ rt2800_bbp_write(rt2x00dev, 21, bbp);
-+
-+ rt2800_register_write(rt2x00dev, MAC_SYS_CTRL, 0x00);
-+ }
-+
- rt2800_register_write(rt2x00dev, LEGACY_BASIC_RATE, 0x0000013f);
- rt2800_register_write(rt2x00dev, HT_BASIC_RATE, 0x00008003);
-
-@@ -6013,6 +6027,14 @@ static int rt2800_init_registers(struct
- reg = rt2800_register_read(rt2x00dev, TX_ALC_CFG_1);
- rt2x00_set_field32(®, TX_ALC_CFG_1_ROS_BUSY_EN, 0);
- rt2800_register_write(rt2x00dev, TX_ALC_CFG_1, reg);
-+
-+ rt2800_register_write(rt2x00dev, AMPDU_MAX_LEN_20M1S, 0x77754433);
-+ rt2800_register_write(rt2x00dev, AMPDU_MAX_LEN_20M2S, 0x77765543);
-+ rt2800_register_write(rt2x00dev, AMPDU_MAX_LEN_40M1S, 0x77765544);
-+ rt2800_register_write(rt2x00dev, AMPDU_MAX_LEN_40M2S, 0x77765544);
-+
-+ rt2800_register_write(rt2x00dev, HT_FBK_TO_LEGACY, 0x1010);
-+
- } else {
- rt2800_register_write(rt2x00dev, TX_SW_CFG0, 0x00000000);
- rt2800_register_write(rt2x00dev, TX_SW_CFG1, 0x00080606);
-@@ -7231,6 +7253,8 @@ static void rt2800_init_bbp_6352(struct
- rt2800_bbp_dcoc_write(rt2x00dev, 159, 0x64);
-
- rt2800_bbp4_mac_if_ctrl(rt2x00dev);
-+
-+ rt2800_bbp_write(rt2x00dev, 84, 0x19);
- }
-
- static void rt2800_init_bbp(struct rt2x00_dev *rt2x00dev)
---- a/drivers/net/wireless/ralink/rt2x00/rt2800mmio.c
-+++ b/drivers/net/wireless/ralink/rt2x00/rt2800mmio.c
-@@ -760,6 +760,9 @@ int rt2800mmio_init_registers(struct rt2
-
- rt2x00mmio_register_write(rt2x00dev, PWR_PIN_CFG, 0x00000003);
-
-+ if (rt2x00_rt(rt2x00dev, RT6352))
-+ return 0;
-+
- reg = 0;
- rt2x00_set_field32(®, MAC_SYS_CTRL_RESET_CSR, 1);
- rt2x00_set_field32(®, MAC_SYS_CTRL_RESET_BBP, 1);
+++ /dev/null
-From a28533c6be1711584bf3ec978309d5c590029821 Mon Sep 17 00:00:00 2001
-From: Shiji Yang <yangshiji66@outlook.com>
-Date: Thu, 19 Oct 2023 19:58:57 +0800
-Subject: wifi: rt2x00: rework MT7620 channel config function
-
-1. Move the channel configuration code from rt2800_vco_calibration()
- to the rt2800_config_channel().
-2. Use MT7620 SoC specific AGC initial LNA value instead of the
- RT5592's value.
-3. BBP{195,196} pairing write has been replaced with
- rt2800_bbp_glrt_write() to reduce redundant code.
-
-Signed-off-by: Shiji Yang <yangshiji66@outlook.com>
-Acked-by: Stanislaw Gruszka <stf_xl@wp.pl>
-Signed-off-by: Kalle Valo <kvalo@kernel.org>
-Link: https://lore.kernel.org/r/TYAP286MB0315622A4340BFFA530B1B86BCD4A@TYAP286MB0315.JPNP286.PROD.OUTLOOK.COM
----
- drivers/net/wireless/ralink/rt2x00/rt2800lib.c | 91 ++++++++++----------------
- 1 file changed, 35 insertions(+), 56 deletions(-)
-
---- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
-+++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
-@@ -3861,14 +3861,6 @@ static void rt2800_config_channel_rf7620
- rfcsr |= tx_agc_fc;
- rt2800_rfcsr_write_bank(rt2x00dev, 7, 59, rfcsr);
- }
--
-- if (conf_is_ht40(conf)) {
-- rt2800_bbp_glrt_write(rt2x00dev, 141, 0x10);
-- rt2800_bbp_glrt_write(rt2x00dev, 157, 0x2f);
-- } else {
-- rt2800_bbp_glrt_write(rt2x00dev, 141, 0x1a);
-- rt2800_bbp_glrt_write(rt2x00dev, 157, 0x40);
-- }
- }
-
- static void rt2800_config_alc_rt6352(struct rt2x00_dev *rt2x00dev,
-@@ -4437,32 +4429,46 @@ static void rt2800_config_channel(struct
- usleep_range(1000, 1500);
- }
-
-- if (rt2x00_rt(rt2x00dev, RT5592) || rt2x00_rt(rt2x00dev, RT6352)) {
-- reg = 0x10;
-- if (!conf_is_ht40(conf)) {
-- if (rt2x00_rt(rt2x00dev, RT6352) &&
-- rt2x00_has_cap_external_lna_bg(rt2x00dev)) {
-- reg |= 0x5;
-- } else {
-- reg |= 0xa;
-- }
-- }
-- rt2800_bbp_write(rt2x00dev, 195, 141);
-- rt2800_bbp_write(rt2x00dev, 196, reg);
-+ if (rt2x00_rt(rt2x00dev, RT5592)) {
-+ bbp = conf_is_ht40(conf) ? 0x10 : 0x1a;
-+ rt2800_bbp_glrt_write(rt2x00dev, 141, bbp);
-
-- /* AGC init.
-- * Despite the vendor driver using different values here for
-- * RT6352 chip, we use 0x1c for now. This may have to be changed
-- * once TSSI got implemented.
-- */
-- reg = (rf->channel <= 14 ? 0x1c : 0x24) + 2*rt2x00dev->lna_gain;
-- rt2800_bbp_write_with_rx_chain(rt2x00dev, 66, reg);
-+ bbp = (rf->channel <= 14 ? 0x1c : 0x24) + 2 * rt2x00dev->lna_gain;
-+ rt2800_bbp_write_with_rx_chain(rt2x00dev, 66, bbp);
-
-- if (rt2x00_rt(rt2x00dev, RT5592))
-- rt2800_iq_calibrate(rt2x00dev, rf->channel);
-+ rt2800_iq_calibrate(rt2x00dev, rf->channel);
- }
-
- if (rt2x00_rt(rt2x00dev, RT6352)) {
-+ /* BBP for GLRT BW */
-+ bbp = conf_is_ht40(conf) ?
-+ 0x10 : rt2x00_has_cap_external_lna_bg(rt2x00dev) ?
-+ 0x15 : 0x1a;
-+ rt2800_bbp_glrt_write(rt2x00dev, 141, bbp);
-+
-+ bbp = conf_is_ht40(conf) ? 0x2f : 0x40;
-+ rt2800_bbp_glrt_write(rt2x00dev, 157, bbp);
-+
-+ if (rt2x00dev->default_ant.rx_chain_num == 1) {
-+ rt2800_bbp_write(rt2x00dev, 91, 0x07);
-+ rt2800_bbp_write(rt2x00dev, 95, 0x1a);
-+ rt2800_bbp_glrt_write(rt2x00dev, 128, 0xa0);
-+ rt2800_bbp_glrt_write(rt2x00dev, 170, 0x12);
-+ rt2800_bbp_glrt_write(rt2x00dev, 171, 0x10);
-+ } else {
-+ rt2800_bbp_write(rt2x00dev, 91, 0x06);
-+ rt2800_bbp_write(rt2x00dev, 95, 0x9a);
-+ rt2800_bbp_glrt_write(rt2x00dev, 128, 0xe0);
-+ rt2800_bbp_glrt_write(rt2x00dev, 170, 0x30);
-+ rt2800_bbp_glrt_write(rt2x00dev, 171, 0x30);
-+ }
-+
-+ /* AGC init */
-+ bbp = rf->channel <= 14 ? 0x04 + 2 * rt2x00dev->lna_gain : 0;
-+ rt2800_bbp_write_with_rx_chain(rt2x00dev, 66, bbp);
-+
-+ usleep_range(1000, 1500);
-+
- if (test_bit(CAPABILITY_EXTERNAL_PA_TX0,
- &rt2x00dev->cap_flags)) {
- reg = rt2800_register_read(rt2x00dev, RF_CONTROL3);
-@@ -5608,26 +5614,6 @@ void rt2800_vco_calibration(struct rt2x0
- rt2800_register_write(rt2x00dev, TX_PIN_CFG, tx_pin);
-
- if (rt2x00_rt(rt2x00dev, RT6352)) {
-- if (rt2x00dev->default_ant.rx_chain_num == 1) {
-- rt2800_bbp_write(rt2x00dev, 91, 0x07);
-- rt2800_bbp_write(rt2x00dev, 95, 0x1A);
-- rt2800_bbp_write(rt2x00dev, 195, 128);
-- rt2800_bbp_write(rt2x00dev, 196, 0xA0);
-- rt2800_bbp_write(rt2x00dev, 195, 170);
-- rt2800_bbp_write(rt2x00dev, 196, 0x12);
-- rt2800_bbp_write(rt2x00dev, 195, 171);
-- rt2800_bbp_write(rt2x00dev, 196, 0x10);
-- } else {
-- rt2800_bbp_write(rt2x00dev, 91, 0x06);
-- rt2800_bbp_write(rt2x00dev, 95, 0x9A);
-- rt2800_bbp_write(rt2x00dev, 195, 128);
-- rt2800_bbp_write(rt2x00dev, 196, 0xE0);
-- rt2800_bbp_write(rt2x00dev, 195, 170);
-- rt2800_bbp_write(rt2x00dev, 196, 0x30);
-- rt2800_bbp_write(rt2x00dev, 195, 171);
-- rt2800_bbp_write(rt2x00dev, 196, 0x30);
-- }
--
- if (rt2x00_has_cap_external_lna_bg(rt2x00dev)) {
- rt2800_bbp_write(rt2x00dev, 75, 0x68);
- rt2800_bbp_write(rt2x00dev, 76, 0x4C);
-@@ -5635,13 +5621,6 @@ void rt2800_vco_calibration(struct rt2x0
- rt2800_bbp_write(rt2x00dev, 80, 0x0C);
- rt2800_bbp_write(rt2x00dev, 82, 0xB6);
- }
--
-- /* On 11A, We should delay and wait RF/BBP to be stable
-- * and the appropriate time should be 1000 micro seconds
-- * 2005/06/05 - On 11G, we also need this delay time.
-- * Otherwise it's difficult to pass the WHQL.
-- */
-- usleep_range(1000, 1500);
- }
- }
- EXPORT_SYMBOL_GPL(rt2800_vco_calibration);
+++ /dev/null
-From cca74bed37af1c8217bcd8282d9b384efdbf73bd Mon Sep 17 00:00:00 2001
-From: Shiji Yang <yangshiji66@outlook.com>
-Date: Thu, 19 Oct 2023 19:58:58 +0800
-Subject: wifi: rt2x00: rework MT7620 PA/LNA RF calibration
-
-1. Move MT7620 PA/LNA calibration code to dedicated functions.
-2. For external PA/LNA devices, restore RF and BBP registers before
- R-Calibration.
-3. Do Rx DCOC calibration again before RXIQ calibration.
-4. Add some missing LNA related registers' initialization.
-
-Signed-off-by: Shiji Yang <yangshiji66@outlook.com>
-Acked-by: Stanislaw Gruszka <stf_xl@wp.pl>
-Signed-off-by: Kalle Valo <kvalo@kernel.org>
-Link: https://lore.kernel.org/r/TYAP286MB0315979F92DC563019B8F238BCD4A@TYAP286MB0315.JPNP286.PROD.OUTLOOK.COM
----
- drivers/net/wireless/ralink/rt2x00/rt2800lib.c | 176 +++++++++++++++++--------
- drivers/net/wireless/ralink/rt2x00/rt2x00.h | 6 +
- 2 files changed, 130 insertions(+), 52 deletions(-)
-
---- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
-+++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
-@@ -4468,41 +4468,6 @@ static void rt2800_config_channel(struct
- rt2800_bbp_write_with_rx_chain(rt2x00dev, 66, bbp);
-
- usleep_range(1000, 1500);
--
-- if (test_bit(CAPABILITY_EXTERNAL_PA_TX0,
-- &rt2x00dev->cap_flags)) {
-- reg = rt2800_register_read(rt2x00dev, RF_CONTROL3);
-- reg |= 0x00000101;
-- rt2800_register_write(rt2x00dev, RF_CONTROL3, reg);
--
-- reg = rt2800_register_read(rt2x00dev, RF_BYPASS3);
-- reg |= 0x00000101;
-- rt2800_register_write(rt2x00dev, RF_BYPASS3, reg);
--
-- rt2800_rfcsr_write_chanreg(rt2x00dev, 43, 0x73);
-- rt2800_rfcsr_write_chanreg(rt2x00dev, 44, 0x73);
-- rt2800_rfcsr_write_chanreg(rt2x00dev, 45, 0x73);
-- rt2800_rfcsr_write_chanreg(rt2x00dev, 46, 0x27);
-- rt2800_rfcsr_write_chanreg(rt2x00dev, 47, 0xC8);
-- rt2800_rfcsr_write_chanreg(rt2x00dev, 48, 0xA4);
-- rt2800_rfcsr_write_chanreg(rt2x00dev, 49, 0x05);
-- rt2800_rfcsr_write_chanreg(rt2x00dev, 54, 0x27);
-- rt2800_rfcsr_write_chanreg(rt2x00dev, 55, 0xC8);
-- rt2800_rfcsr_write_chanreg(rt2x00dev, 56, 0xA4);
-- rt2800_rfcsr_write_chanreg(rt2x00dev, 57, 0x05);
-- rt2800_rfcsr_write_chanreg(rt2x00dev, 58, 0x27);
-- rt2800_rfcsr_write_chanreg(rt2x00dev, 59, 0xC8);
-- rt2800_rfcsr_write_chanreg(rt2x00dev, 60, 0xA4);
-- rt2800_rfcsr_write_chanreg(rt2x00dev, 61, 0x05);
-- rt2800_rfcsr_write_dccal(rt2x00dev, 05, 0x00);
--
-- rt2800_register_write(rt2x00dev, TX0_RF_GAIN_CORRECT,
-- 0x36303636);
-- rt2800_register_write(rt2x00dev, TX0_RF_GAIN_ATTEN,
-- 0x6C6C6B6C);
-- rt2800_register_write(rt2x00dev, TX1_RF_GAIN_ATTEN,
-- 0x6C6C6B6C);
-- }
- }
-
- bbp = rt2800_bbp_read(rt2x00dev, 4);
-@@ -5612,16 +5577,6 @@ void rt2800_vco_calibration(struct rt2x0
- }
- }
- rt2800_register_write(rt2x00dev, TX_PIN_CFG, tx_pin);
--
-- if (rt2x00_rt(rt2x00dev, RT6352)) {
-- if (rt2x00_has_cap_external_lna_bg(rt2x00dev)) {
-- rt2800_bbp_write(rt2x00dev, 75, 0x68);
-- rt2800_bbp_write(rt2x00dev, 76, 0x4C);
-- rt2800_bbp_write(rt2x00dev, 79, 0x1C);
-- rt2800_bbp_write(rt2x00dev, 80, 0x0C);
-- rt2800_bbp_write(rt2x00dev, 82, 0xB6);
-- }
-- }
- }
- EXPORT_SYMBOL_GPL(rt2800_vco_calibration);
-
-@@ -10348,6 +10303,128 @@ do_cal:
- rt2800_register_write(rt2x00dev, RF_BYPASS0, MAC_RF_BYPASS0);
- }
-
-+static void rt2800_restore_rf_bbp_rt6352(struct rt2x00_dev *rt2x00dev)
-+{
-+ if (rt2x00_has_cap_external_pa(rt2x00dev)) {
-+ rt2800_register_write(rt2x00dev, RF_CONTROL3, 0x0);
-+ rt2800_register_write(rt2x00dev, RF_BYPASS3, 0x0);
-+ }
-+
-+ if (rt2x00_has_cap_external_lna_bg(rt2x00dev)) {
-+ rt2800_rfcsr_write_chanreg(rt2x00dev, 14, 0x16);
-+ rt2800_rfcsr_write_chanreg(rt2x00dev, 17, 0x23);
-+ rt2800_rfcsr_write_chanreg(rt2x00dev, 18, 0x02);
-+ }
-+
-+ if (rt2x00_has_cap_external_pa(rt2x00dev)) {
-+ rt2800_rfcsr_write_chanreg(rt2x00dev, 43, 0xd3);
-+ rt2800_rfcsr_write_chanreg(rt2x00dev, 44, 0xb3);
-+ rt2800_rfcsr_write_chanreg(rt2x00dev, 45, 0xd5);
-+ rt2800_rfcsr_write_chanreg(rt2x00dev, 46, 0x27);
-+ rt2800_rfcsr_write_chanreg(rt2x00dev, 47, 0x6c);
-+ rt2800_rfcsr_write_chanreg(rt2x00dev, 48, 0xfc);
-+ rt2800_rfcsr_write_chanreg(rt2x00dev, 49, 0x1f);
-+ rt2800_rfcsr_write_chanreg(rt2x00dev, 54, 0x27);
-+ rt2800_rfcsr_write_chanreg(rt2x00dev, 55, 0x66);
-+ rt2800_rfcsr_write_chanreg(rt2x00dev, 56, 0xff);
-+ rt2800_rfcsr_write_chanreg(rt2x00dev, 57, 0x1c);
-+ rt2800_rfcsr_write_chanreg(rt2x00dev, 58, 0x20);
-+ rt2800_rfcsr_write_chanreg(rt2x00dev, 59, 0x6b);
-+ rt2800_rfcsr_write_chanreg(rt2x00dev, 60, 0xf7);
-+ rt2800_rfcsr_write_chanreg(rt2x00dev, 61, 0x09);
-+ }
-+
-+ if (rt2x00_has_cap_external_lna_bg(rt2x00dev)) {
-+ rt2800_bbp_write(rt2x00dev, 75, 0x60);
-+ rt2800_bbp_write(rt2x00dev, 76, 0x44);
-+ rt2800_bbp_write(rt2x00dev, 79, 0x1c);
-+ rt2800_bbp_write(rt2x00dev, 80, 0x0c);
-+ rt2800_bbp_write(rt2x00dev, 82, 0xB6);
-+ }
-+
-+ if (rt2x00_has_cap_external_pa(rt2x00dev)) {
-+ rt2800_register_write(rt2x00dev, TX0_RF_GAIN_CORRECT, 0x3630363a);
-+ rt2800_register_write(rt2x00dev, TX0_RF_GAIN_ATTEN, 0x6c6c666c);
-+ rt2800_register_write(rt2x00dev, TX1_RF_GAIN_ATTEN, 0x6c6c666c);
-+ }
-+}
-+
-+static void rt2800_calibration_rt6352(struct rt2x00_dev *rt2x00dev)
-+{
-+ u32 reg;
-+
-+ if (rt2x00_has_cap_external_pa(rt2x00dev) ||
-+ rt2x00_has_cap_external_lna_bg(rt2x00dev))
-+ rt2800_restore_rf_bbp_rt6352(rt2x00dev);
-+
-+ rt2800_r_calibration(rt2x00dev);
-+ rt2800_rf_self_txdc_cal(rt2x00dev);
-+ rt2800_rxdcoc_calibration(rt2x00dev);
-+ rt2800_bw_filter_calibration(rt2x00dev, true);
-+ rt2800_bw_filter_calibration(rt2x00dev, false);
-+ rt2800_loft_iq_calibration(rt2x00dev);
-+
-+ /* missing DPD calibration for internal PA devices */
-+
-+ rt2800_rxdcoc_calibration(rt2x00dev);
-+ rt2800_rxiq_calibration(rt2x00dev);
-+
-+ if (!rt2x00_has_cap_external_pa(rt2x00dev) &&
-+ !rt2x00_has_cap_external_lna_bg(rt2x00dev))
-+ return;
-+
-+ if (rt2x00_has_cap_external_pa(rt2x00dev)) {
-+ reg = rt2800_register_read(rt2x00dev, RF_CONTROL3);
-+ reg |= 0x00000101;
-+ rt2800_register_write(rt2x00dev, RF_CONTROL3, reg);
-+
-+ reg = rt2800_register_read(rt2x00dev, RF_BYPASS3);
-+ reg |= 0x00000101;
-+ rt2800_register_write(rt2x00dev, RF_BYPASS3, reg);
-+ }
-+
-+ if (rt2x00_has_cap_external_lna_bg(rt2x00dev)) {
-+ rt2800_rfcsr_write_chanreg(rt2x00dev, 14, 0x66);
-+ rt2800_rfcsr_write_chanreg(rt2x00dev, 17, 0x20);
-+ rt2800_rfcsr_write_chanreg(rt2x00dev, 18, 0x42);
-+ }
-+
-+ if (rt2x00_has_cap_external_pa(rt2x00dev)) {
-+ rt2800_rfcsr_write_chanreg(rt2x00dev, 43, 0x73);
-+ rt2800_rfcsr_write_chanreg(rt2x00dev, 44, 0x73);
-+ rt2800_rfcsr_write_chanreg(rt2x00dev, 45, 0x73);
-+ rt2800_rfcsr_write_chanreg(rt2x00dev, 46, 0x27);
-+ rt2800_rfcsr_write_chanreg(rt2x00dev, 47, 0xc8);
-+ rt2800_rfcsr_write_chanreg(rt2x00dev, 48, 0xa4);
-+ rt2800_rfcsr_write_chanreg(rt2x00dev, 49, 0x05);
-+ rt2800_rfcsr_write_chanreg(rt2x00dev, 54, 0x27);
-+ rt2800_rfcsr_write_chanreg(rt2x00dev, 55, 0xc8);
-+ rt2800_rfcsr_write_chanreg(rt2x00dev, 56, 0xa4);
-+ rt2800_rfcsr_write_chanreg(rt2x00dev, 57, 0x05);
-+ rt2800_rfcsr_write_chanreg(rt2x00dev, 58, 0x27);
-+ rt2800_rfcsr_write_chanreg(rt2x00dev, 59, 0xc8);
-+ rt2800_rfcsr_write_chanreg(rt2x00dev, 60, 0xa4);
-+ rt2800_rfcsr_write_chanreg(rt2x00dev, 61, 0x05);
-+ }
-+
-+ if (rt2x00_has_cap_external_pa(rt2x00dev))
-+ rt2800_rfcsr_write_dccal(rt2x00dev, 05, 0x00);
-+
-+ if (rt2x00_has_cap_external_lna_bg(rt2x00dev)) {
-+ rt2800_bbp_write(rt2x00dev, 75, 0x68);
-+ rt2800_bbp_write(rt2x00dev, 76, 0x4c);
-+ rt2800_bbp_write(rt2x00dev, 79, 0x1c);
-+ rt2800_bbp_write(rt2x00dev, 80, 0x0c);
-+ rt2800_bbp_write(rt2x00dev, 82, 0xb6);
-+ }
-+
-+ if (rt2x00_has_cap_external_pa(rt2x00dev)) {
-+ rt2800_register_write(rt2x00dev, TX0_RF_GAIN_CORRECT, 0x36303636);
-+ rt2800_register_write(rt2x00dev, TX0_RF_GAIN_ATTEN, 0x6c6c6b6c);
-+ rt2800_register_write(rt2x00dev, TX1_RF_GAIN_ATTEN, 0x6c6c6b6c);
-+ }
-+}
-+
- static void rt2800_init_rfcsr_6352(struct rt2x00_dev *rt2x00dev)
- {
- /* Initialize RF central register to default value */
-@@ -10612,13 +10689,8 @@ static void rt2800_init_rfcsr_6352(struc
- rt2800_rfcsr_write_dccal(rt2x00dev, 5, 0x00);
- rt2800_rfcsr_write_dccal(rt2x00dev, 17, 0x7C);
-
-- rt2800_r_calibration(rt2x00dev);
-- rt2800_rf_self_txdc_cal(rt2x00dev);
-- rt2800_rxdcoc_calibration(rt2x00dev);
-- rt2800_bw_filter_calibration(rt2x00dev, true);
-- rt2800_bw_filter_calibration(rt2x00dev, false);
-- rt2800_loft_iq_calibration(rt2x00dev);
-- rt2800_rxiq_calibration(rt2x00dev);
-+ /* Do calibration and init PA/LNA */
-+ rt2800_calibration_rt6352(rt2x00dev);
- }
-
- static void rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev)
---- a/drivers/net/wireless/ralink/rt2x00/rt2x00.h
-+++ b/drivers/net/wireless/ralink/rt2x00/rt2x00.h
-@@ -1263,6 +1263,12 @@ rt2x00_has_cap_external_lna_bg(struct rt
- }
-
- static inline bool
-+rt2x00_has_cap_external_pa(struct rt2x00_dev *rt2x00dev)
-+{
-+ return rt2x00_has_cap_flag(rt2x00dev, CAPABILITY_EXTERNAL_PA_TX0);
-+}
-+
-+static inline bool
- rt2x00_has_cap_double_antenna(struct rt2x00_dev *rt2x00dev)
- {
- return rt2x00_has_cap_flag(rt2x00dev, CAPABILITY_DOUBLE_ANTENNA);
+++ /dev/null
-From b1275cdd7456ef811747dfb4f3c46310ddd300cd Mon Sep 17 00:00:00 2001
-From: Shiji Yang <yangshiji66@outlook.com>
-Date: Sat, 4 Nov 2023 16:57:58 +0800
-Subject: wifi: rt2x00: introduce DMA busy check watchdog for rt2800
-
-When I tried to fix the watchdog of rt2800, I found that sometimes
-the watchdog can not reset the hung device. This is because the
-queue is not completely stuck, it just becomes very slow. The MTK
-vendor driver for the new chip MT7603/MT7612 has a DMA busy watchdog
-to detect device hangs by checking DMA busy status. This watchdog
-implementation is something similar to it. To reduce unnecessary
-reset, we can check the INT_SOURCE_CSR register together as I found
-that when the radio hung, the RX/TX coherent interrupt will always
-stuck at triggered state.
-
-The 'watchdog' module parameter has been extended to control all
-watchdogs(0=disabled, 1=hang watchdog, 2=DMA watchdog, 3=both). This
-new watchdog function is a slight schedule and it won't affect the
-transmission speed. So we can turn on it by default. Due to the
-INT_SOURCE_CSR register is invalid on rt2800 USB NICs, the DMA busy
-watchdog will be automatically disabled for them.
-
-Tested on MT7620 and RT5350.
-
-Signed-off-by: Shiji Yang <yangshiji66@outlook.com>
-Acked-by: Stanislaw Gruszka <stf_xl@wp.pl>
-Signed-off-by: Kalle Valo <kvalo@kernel.org>
-Link: https://lore.kernel.org/r/TYAP286MB0315D7462CE08A119A99DE34BCA4A@TYAP286MB0315.JPNP286.PROD.OUTLOOK.COM
----
- drivers/net/wireless/ralink/rt2x00/rt2800.h | 4 ++
- drivers/net/wireless/ralink/rt2x00/rt2800lib.c | 77 ++++++++++++++++++++++----
- drivers/net/wireless/ralink/rt2x00/rt2x00.h | 3 +
- 3 files changed, 73 insertions(+), 11 deletions(-)
-
---- a/drivers/net/wireless/ralink/rt2x00/rt2800.h
-+++ b/drivers/net/wireless/ralink/rt2x00/rt2800.h
-@@ -3194,4 +3194,8 @@ enum rt2800_eeprom_word {
- */
- #define BCN_TBTT_OFFSET 64
-
-+/* Watchdog type mask */
-+#define RT2800_WATCHDOG_HANG BIT(0)
-+#define RT2800_WATCHDOG_DMA_BUSY BIT(1)
-+
- #endif /* RT2800_H */
---- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
-+++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
-@@ -30,9 +30,10 @@
- #include "rt2800lib.h"
- #include "rt2800.h"
-
--static bool modparam_watchdog;
--module_param_named(watchdog, modparam_watchdog, bool, S_IRUGO);
--MODULE_PARM_DESC(watchdog, "Enable watchdog to detect tx/rx hangs and reset hardware if detected");
-+static unsigned int modparam_watchdog = RT2800_WATCHDOG_DMA_BUSY;
-+module_param_named(watchdog, modparam_watchdog, uint, 0444);
-+MODULE_PARM_DESC(watchdog, "Enable watchdog to recover tx/rx hangs.\n"
-+ "\t\t(0=disabled, 1=hang watchdog, 2=DMA watchdog(default), 3=both)");
-
- /*
- * Register access.
-@@ -1261,15 +1262,12 @@ static void rt2800_update_survey(struct
- chan_survey->time_ext_busy += rt2800_register_read(rt2x00dev, CH_BUSY_STA_SEC);
- }
-
--void rt2800_watchdog(struct rt2x00_dev *rt2x00dev)
-+static bool rt2800_watchdog_hung(struct rt2x00_dev *rt2x00dev)
- {
- struct data_queue *queue;
- bool hung_tx = false;
- bool hung_rx = false;
-
-- if (test_bit(DEVICE_STATE_SCANNING, &rt2x00dev->flags))
-- return;
--
- rt2800_update_survey(rt2x00dev);
-
- queue_for_each(rt2x00dev, queue) {
-@@ -1297,18 +1295,72 @@ void rt2800_watchdog(struct rt2x00_dev *
- }
- }
-
-+ if (!hung_tx && !hung_rx)
-+ return false;
-+
- if (hung_tx)
- rt2x00_warn(rt2x00dev, "Watchdog TX hung detected\n");
-
- if (hung_rx)
- rt2x00_warn(rt2x00dev, "Watchdog RX hung detected\n");
-
-- if (hung_tx || hung_rx) {
-- queue_for_each(rt2x00dev, queue)
-- queue->wd_count = 0;
-+ queue_for_each(rt2x00dev, queue)
-+ queue->wd_count = 0;
-+
-+ return true;
-+}
-+
-+static bool rt2800_watchdog_dma_busy(struct rt2x00_dev *rt2x00dev)
-+{
-+ bool busy_rx, busy_tx;
-+ u32 reg_cfg = rt2800_register_read(rt2x00dev, WPDMA_GLO_CFG);
-+ u32 reg_int = rt2800_register_read(rt2x00dev, INT_SOURCE_CSR);
-+
-+ if (rt2x00_get_field32(reg_cfg, WPDMA_GLO_CFG_RX_DMA_BUSY) &&
-+ rt2x00_get_field32(reg_int, INT_SOURCE_CSR_RX_COHERENT))
-+ rt2x00dev->rxdma_busy++;
-+ else
-+ rt2x00dev->rxdma_busy = 0;
-
-+ if (rt2x00_get_field32(reg_cfg, WPDMA_GLO_CFG_TX_DMA_BUSY) &&
-+ rt2x00_get_field32(reg_int, INT_SOURCE_CSR_TX_COHERENT))
-+ rt2x00dev->txdma_busy++;
-+ else
-+ rt2x00dev->txdma_busy = 0;
-+
-+ busy_rx = rt2x00dev->rxdma_busy > 30 ? true : false;
-+ busy_tx = rt2x00dev->txdma_busy > 30 ? true : false;
-+
-+ if (!busy_rx && !busy_tx)
-+ return false;
-+
-+ if (busy_rx)
-+ rt2x00_warn(rt2x00dev, "Watchdog RX DMA busy detected\n");
-+
-+ if (busy_tx)
-+ rt2x00_warn(rt2x00dev, "Watchdog TX DMA busy detected\n");
-+
-+ rt2x00dev->rxdma_busy = 0;
-+ rt2x00dev->txdma_busy = 0;
-+
-+ return true;
-+}
-+
-+void rt2800_watchdog(struct rt2x00_dev *rt2x00dev)
-+{
-+ bool reset = false;
-+
-+ if (test_bit(DEVICE_STATE_SCANNING, &rt2x00dev->flags))
-+ return;
-+
-+ if (modparam_watchdog & RT2800_WATCHDOG_DMA_BUSY)
-+ reset = rt2800_watchdog_dma_busy(rt2x00dev);
-+
-+ if (modparam_watchdog & RT2800_WATCHDOG_HANG)
-+ reset = rt2800_watchdog_hung(rt2x00dev) || reset;
-+
-+ if (reset)
- ieee80211_restart_hw(rt2x00dev->hw);
-- }
- }
- EXPORT_SYMBOL_GPL(rt2800_watchdog);
-
-@@ -12016,6 +12068,9 @@ int rt2800_probe_hw(struct rt2x00_dev *r
- __set_bit(REQUIRE_TASKLET_CONTEXT, &rt2x00dev->cap_flags);
- }
-
-+ /* USB NICs don't support DMA watchdog as INT_SOURCE_CSR is invalid */
-+ if (rt2x00_is_usb(rt2x00dev))
-+ modparam_watchdog &= ~RT2800_WATCHDOG_DMA_BUSY;
- if (modparam_watchdog) {
- __set_bit(CAPABILITY_RESTART_HW, &rt2x00dev->cap_flags);
- rt2x00dev->link.watchdog_interval = msecs_to_jiffies(100);
---- a/drivers/net/wireless/ralink/rt2x00/rt2x00.h
-+++ b/drivers/net/wireless/ralink/rt2x00/rt2x00.h
-@@ -926,6 +926,9 @@ struct rt2x00_dev {
- */
- u16 beacon_int;
-
-+ /* Rx/Tx DMA busy watchdog counter */
-+ u16 rxdma_busy, txdma_busy;
-+
- /**
- * Timestamp of last received beacon
- */
+++ /dev/null
-From 570beb6285fd355904b22625da20809f477096c5 Mon Sep 17 00:00:00 2001
-From: Shiji Yang <yangshiji66@outlook.com>
-Date: Sat, 4 Nov 2023 16:57:59 +0800
-Subject: wifi: rt2x00: disable RTS threshold for rt2800 by default
-
-rt2800 has a lot of registers to control the RTS enable/disable
-status for different rates. And the driver control them via
-rt2800_set_rts_threshold(). When RTS was disabled in user
-interface, this function won't be called at all. This means that
-the RTS is still 'on' for CCK and OFDM rates. So we'd better to
-disable them by default because it should be like this. The RTS
-for HT20 and HT40 is already default off so we don't need to
-touch them. If we toggle the RTS status, these register bits
-will be enable/disable again by rt2800_set_rts_threshold().
-
-Signed-off-by: Shiji Yang <yangshiji66@outlook.com>
-Acked-by: Stanislaw Gruszka <stf_xl@wp.pl>
-Signed-off-by: Kalle Valo <kvalo@kernel.org>
-Link: https://lore.kernel.org/r/TYAP286MB03155DDB953155B7A2DE849ABCA4A@TYAP286MB0315.JPNP286.PROD.OUTLOOK.COM
----
- drivers/net/wireless/ralink/rt2x00/rt2800lib.c | 4 ++--
- 1 file changed, 2 insertions(+), 2 deletions(-)
-
---- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
-+++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
-@@ -6100,7 +6100,7 @@ static int rt2800_init_registers(struct
- rt2x00_set_field32(®, CCK_PROT_CFG_TX_OP_ALLOW_MM40, 0);
- rt2x00_set_field32(®, CCK_PROT_CFG_TX_OP_ALLOW_GF20, 1);
- rt2x00_set_field32(®, CCK_PROT_CFG_TX_OP_ALLOW_GF40, 0);
-- rt2x00_set_field32(®, CCK_PROT_CFG_RTS_TH_EN, 1);
-+ rt2x00_set_field32(®, CCK_PROT_CFG_RTS_TH_EN, 0);
- rt2800_register_write(rt2x00dev, CCK_PROT_CFG, reg);
-
- reg = rt2800_register_read(rt2x00dev, OFDM_PROT_CFG);
-@@ -6113,7 +6113,7 @@ static int rt2800_init_registers(struct
- rt2x00_set_field32(®, OFDM_PROT_CFG_TX_OP_ALLOW_MM40, 0);
- rt2x00_set_field32(®, OFDM_PROT_CFG_TX_OP_ALLOW_GF20, 1);
- rt2x00_set_field32(®, OFDM_PROT_CFG_TX_OP_ALLOW_GF40, 0);
-- rt2x00_set_field32(®, OFDM_PROT_CFG_RTS_TH_EN, 1);
-+ rt2x00_set_field32(®, OFDM_PROT_CFG_RTS_TH_EN, 0);
- rt2800_register_write(rt2x00dev, OFDM_PROT_CFG, reg);
-
- reg = rt2800_register_read(rt2x00dev, MM20_PROT_CFG);
+++ /dev/null
-From a11d965a218f0cd95b13fe44d0bcd8a20ce134a8 Mon Sep 17 00:00:00 2001
-From: Shiji Yang <yangshiji66@outlook.com>
-Date: Sat, 4 Nov 2023 16:58:00 +0800
-Subject: wifi: rt2x00: restart beacon queue when hardware reset
-
-When a hardware reset is triggered, all registers are reset, so all
-queues are forced to stop in hardware interface. However, mac80211
-will not automatically stop the queue. If we don't manually stop the
-beacon queue, the queue will be deadlocked and unable to start again.
-This patch fixes the issue where Apple devices cannot connect to the
-AP after calling ieee80211_restart_hw().
-
-Signed-off-by: Shiji Yang <yangshiji66@outlook.com>
-Acked-by: Stanislaw Gruszka <stf_xl@wp.pl>
-Signed-off-by: Kalle Valo <kvalo@kernel.org>
-Link: https://lore.kernel.org/r/TYAP286MB031530EB6D98DCE4DF20766CBCA4A@TYAP286MB0315.JPNP286.PROD.OUTLOOK.COM
----
- drivers/net/wireless/ralink/rt2x00/rt2x00dev.c | 3 +++
- drivers/net/wireless/ralink/rt2x00/rt2x00mac.c | 11 +++++++++++
- 2 files changed, 14 insertions(+)
-
---- a/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c
-+++ b/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c
-@@ -101,6 +101,7 @@ void rt2x00lib_disable_radio(struct rt2x
- rt2x00link_stop_tuner(rt2x00dev);
- rt2x00queue_stop_queues(rt2x00dev);
- rt2x00queue_flush_queues(rt2x00dev, true);
-+ rt2x00queue_stop_queue(rt2x00dev->bcn);
-
- /*
- * Disable radio.
-@@ -1286,6 +1287,7 @@ int rt2x00lib_start(struct rt2x00_dev *r
- rt2x00dev->intf_ap_count = 0;
- rt2x00dev->intf_sta_count = 0;
- rt2x00dev->intf_associated = 0;
-+ rt2x00dev->intf_beaconing = 0;
-
- /* Enable the radio */
- retval = rt2x00lib_enable_radio(rt2x00dev);
-@@ -1312,6 +1314,7 @@ void rt2x00lib_stop(struct rt2x00_dev *r
- rt2x00dev->intf_ap_count = 0;
- rt2x00dev->intf_sta_count = 0;
- rt2x00dev->intf_associated = 0;
-+ rt2x00dev->intf_beaconing = 0;
- }
-
- static inline void rt2x00lib_set_if_combinations(struct rt2x00_dev *rt2x00dev)
---- a/drivers/net/wireless/ralink/rt2x00/rt2x00mac.c
-+++ b/drivers/net/wireless/ralink/rt2x00/rt2x00mac.c
-@@ -598,6 +598,17 @@ void rt2x00mac_bss_info_changed(struct i
- */
- if (changes & BSS_CHANGED_BEACON_ENABLED) {
- mutex_lock(&intf->beacon_skb_mutex);
-+
-+ /*
-+ * Clear the 'enable_beacon' flag and clear beacon because
-+ * the beacon queue has been stopped after hardware reset.
-+ */
-+ if (test_bit(DEVICE_STATE_RESET, &rt2x00dev->flags) &&
-+ intf->enable_beacon) {
-+ intf->enable_beacon = false;
-+ rt2x00queue_clear_beacon(rt2x00dev, vif);
-+ }
-+
- if (!bss_conf->enable_beacon && intf->enable_beacon) {
- rt2x00dev->intf_beaconing--;
- intf->enable_beacon = false;
--- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
+++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
-@@ -8711,7 +8711,7 @@ static void rt2800_rxdcoc_calibration(st
- rt2800_rfcsr_write_bank(rt2x00dev, 5, 4, saverfb5r4);
- rt2800_rfcsr_write_bank(rt2x00dev, 7, 4, saverfb7r4);
+@@ -8692,7 +8692,7 @@ static void rt2800_rxdcoc_calibration(st
+ rfvalue |= 0x03;
+ rt2800_rfcsr_write_bank(rt2x00dev, 0, 2, rfvalue);
- rt2800_bbp_write(rt2x00dev, 158, 141);
+ rt2800_bbp_write(rt2x00dev, 158, 140);
bbpreg = rt2800_bbp_read(rt2x00dev, 159);
- bbpreg = bbpreg & (~0x40);
+ bbpreg |= 0x10;
rt2800_bbp_write(rt2x00dev, 159, bbpreg);
--- a/local-symbols
+++ b/local-symbols
-@@ -352,6 +352,7 @@ RT2X00_LIB_FIRMWARE=
+@@ -340,6 +340,7 @@ RT2X00_LIB_FIRMWARE=
RT2X00_LIB_CRYPTO=
RT2X00_LIB_LEDS=
RT2X00_LIB_DEBUGFS=
/* Firmware functions */
static char *rt2800soc_get_firmware_name(struct rt2x00_dev *rt2x00dev)
{
-@@ -168,7 +155,7 @@ static const struct rt2800_ops rt2800soc
+@@ -172,7 +159,7 @@ static const struct rt2800_ops rt2800soc
.register_multiread = rt2x00mmio_register_multiread,
.register_multiwrite = rt2x00mmio_register_multiwrite,
.regbusy_read = rt2x00mmio_regbusy_read,
--- a/drivers/net/wireless/ralink/rt2x00/rt2800soc.c
+++ b/drivers/net/wireless/ralink/rt2x00/rt2800soc.c
-@@ -226,10 +226,17 @@ static int rt2800soc_probe(struct platfo
+@@ -230,10 +230,17 @@ static int rt2800soc_probe(struct platfo
return rt2x00soc_probe(pdev, &rt2800soc_ops);
}
#include "rt2x00.h"
#include "rt2800lib.h"
-@@ -11285,6 +11286,17 @@ static int rt2800_init_eeprom(struct rt2
+@@ -11282,6 +11283,17 @@ static int rt2800_init_eeprom(struct rt2
rt2800_init_led(rt2x00dev, &rt2x00dev->led_assoc, LED_TYPE_ASSOC);
rt2800_init_led(rt2x00dev, &rt2x00dev->led_qual, LED_TYPE_QUALITY);
static const unsigned int rt2800_eeprom_map[EEPROM_WORD_COUNT] = {
[EEPROM_CHIP_ID] = 0x0000,
[EEPROM_VERSION] = 0x0001,
-@@ -10407,8 +10425,10 @@ static void rt2800_calibration_rt6352(st
+@@ -10404,8 +10422,10 @@ static void rt2800_calibration_rt6352(st
u32 reg;
if (rt2x00_has_cap_external_pa(rt2x00dev) ||
rt2800_r_calibration(rt2x00dev);
rt2800_rf_self_txdc_cal(rt2x00dev);
-@@ -10426,6 +10446,8 @@ static void rt2800_calibration_rt6352(st
+@@ -10423,6 +10443,8 @@ static void rt2800_calibration_rt6352(st
!rt2x00_has_cap_external_lna_bg(rt2x00dev))
return;
+static int rt2800pci_get_chipeco(void) { return 0; }
+
static const struct ieee80211_ops rt2800pci_mac80211_ops = {
- .tx = rt2x00mac_tx,
- .wake_tx_queue = ieee80211_handle_wake_tx_queue,
-@@ -329,6 +333,9 @@ static const struct rt2800_ops rt2800pci
+ .add_chanctx = ieee80211_emulate_add_chanctx,
+ .remove_chanctx = ieee80211_emulate_remove_chanctx,
+@@ -333,6 +337,9 @@ static const struct rt2800_ops rt2800pci
.drv_init_registers = rt2800mmio_init_registers,
.drv_get_txwi = rt2800mmio_get_txwi,
.drv_get_dma_done = rt2800mmio_get_dma_done,
+#endif
+
static const struct ieee80211_ops rt2800soc_mac80211_ops = {
- .tx = rt2x00mac_tx,
- .wake_tx_queue = ieee80211_handle_wake_tx_queue,
-@@ -161,6 +188,9 @@ static const struct rt2800_ops rt2800soc
+ .add_chanctx = ieee80211_emulate_add_chanctx,
+ .remove_chanctx = ieee80211_emulate_remove_chanctx,
+@@ -165,6 +192,9 @@ static const struct rt2800_ops rt2800soc
.drv_init_registers = rt2800mmio_init_registers,
.drv_get_txwi = rt2800mmio_get_txwi,
.drv_get_dma_done = rt2800mmio_get_dma_done,
+static int rt2800usb_get_chipeco(void) { return 0; }
+
static const struct ieee80211_ops rt2800usb_mac80211_ops = {
- .tx = rt2x00mac_tx,
- .wake_tx_queue = ieee80211_handle_wake_tx_queue,
-@@ -672,6 +676,9 @@ static const struct rt2800_ops rt2800usb
+ .add_chanctx = ieee80211_emulate_add_chanctx,
+ .remove_chanctx = ieee80211_emulate_remove_chanctx,
+@@ -676,6 +680,9 @@ static const struct rt2800_ops rt2800usb
.drv_init_registers = rt2800usb_init_registers,
.drv_get_txwi = rt2800usb_get_txwi,
.drv_get_dma_done = rt2800usb_get_dma_done,
/* BBP for G band GLRT function (BBP_128 ~ BBP_221) */
rt2800_bbp_glrt_write(rt2x00dev, 0, 0x00);
-@@ -10381,6 +10410,9 @@ static void rt2800_restore_rf_bbp_rt6352
+@@ -10378,6 +10407,9 @@ static void rt2800_restore_rf_bbp_rt6352
rt2800_register_write(rt2x00dev, RF_BYPASS3, 0x0);
}
if (rt2x00_has_cap_external_lna_bg(rt2x00dev)) {
rt2800_rfcsr_write_chanreg(rt2x00dev, 14, 0x16);
rt2800_rfcsr_write_chanreg(rt2x00dev, 17, 0x23);
-@@ -10458,6 +10490,9 @@ static void rt2800_calibration_rt6352(st
+@@ -10455,6 +10487,9 @@ static void rt2800_calibration_rt6352(st
rt2800_register_write(rt2x00dev, RF_BYPASS3, reg);
}
if (rt2x00_has_cap_external_lna_bg(rt2x00dev)) {
rt2800_rfcsr_write_chanreg(rt2x00dev, 14, 0x66);
rt2800_rfcsr_write_chanreg(rt2x00dev, 17, 0x20);
-@@ -10548,31 +10583,36 @@ static void rt2800_init_rfcsr_6352(struc
+@@ -10545,31 +10580,36 @@ static void rt2800_init_rfcsr_6352(struc
rt2800_rfcsr_write(rt2x00dev, 42, 0x5B);
rt2800_rfcsr_write(rt2x00dev, 43, 0x00);
/* Initialize RF channel register to default value */
rt2800_rfcsr_write_chanreg(rt2x00dev, 0, 0x03);
-@@ -10638,63 +10678,71 @@ static void rt2800_init_rfcsr_6352(struc
+@@ -10635,63 +10675,71 @@ static void rt2800_init_rfcsr_6352(struc
rt2800_rfcsr_write_bank(rt2x00dev, 6, 45, 0xC5);
/* Initialize RF DC calibration register to default value */
rt2800_rfcsr_write_dccal(rt2x00dev, 0, 0x47);
-@@ -10757,12 +10805,17 @@ static void rt2800_init_rfcsr_6352(struc
+@@ -10754,12 +10802,17 @@ static void rt2800_init_rfcsr_6352(struc
rt2800_rfcsr_write_dccal(rt2x00dev, 62, 0x00);
rt2800_rfcsr_write_dccal(rt2x00dev, 63, 0x00);
+++ /dev/null
-From d55cb6d8a99441aff55cb9ce663a07f7f1667e83 Mon Sep 17 00:00:00 2001
-From: Martin Kaistra <martin.kaistra@linutronix.de>
-Date: Fri, 22 Dec 2023 11:14:22 +0100
-Subject: [PATCH 01/21] wifi: rtl8xxxu: remove assignment of priv->vif in
- rtl8xxxu_bss_info_changed()
-
-priv->vif gets already set in rtl8xxxu_add_interface, there is no need
-to set it also in rtl8xxxu_bss_info_changed().
-
-Signed-off-by: Martin Kaistra <martin.kaistra@linutronix.de>
-Reviewed-by: Ping-Ke Shih <pkshih@realtek.com>
-Signed-off-by: Kalle Valo <kvalo@kernel.org>
-Link: https://msgid.link/20231222101442.626837-2-martin.kaistra@linutronix.de
----
- drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c | 1 -
- 1 file changed, 1 deletion(-)
-
---- a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c
-+++ b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c
-@@ -5004,7 +5004,6 @@ rtl8xxxu_bss_info_changed(struct ieee802
-
- rtl8xxxu_update_ra_report(rarpt, highest_rate, sgi, bw);
-
-- priv->vif = vif;
- priv->rssi_level = RTL8XXXU_RATR_STA_INIT;
-
- priv->fops->update_rate_mask(priv, ramask, 0, sgi,
+++ /dev/null
-From 2bbd7d584046038ce655e476628bb15e1460fac6 Mon Sep 17 00:00:00 2001
-From: Martin Kaistra <martin.kaistra@linutronix.de>
-Date: Fri, 22 Dec 2023 11:14:23 +0100
-Subject: [PATCH 02/21] wifi: rtl8xxxu: prepare supporting two virtual
- interfaces
-
-To prepare for concurrent mode, add an array ("vifs") to rtl8xxxu_priv
-to keep track of both interfaces.
-
-Keep the old priv->vif as long there are still users of it and let
-priv->vifs[0] point to the same location.
-
-Signed-off-by: Martin Kaistra <martin.kaistra@linutronix.de>
-Reviewed-by: Ping-Ke Shih <pkshih@realtek.com>
-Signed-off-by: Kalle Valo <kvalo@kernel.org>
-Link: https://msgid.link/20231222101442.626837-3-martin.kaistra@linutronix.de
----
- drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu.h | 2 ++
- drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c | 10 +++++++---
- 2 files changed, 9 insertions(+), 3 deletions(-)
-
---- a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu.h
-+++ b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu.h
-@@ -1897,6 +1897,8 @@ struct rtl8xxxu_priv {
- * is supported and no iface_combinations are provided.
- */
- struct ieee80211_vif *vif;
-+
-+ struct ieee80211_vif *vifs[2];
- struct delayed_work ra_watchdog;
- struct work_struct c2hcmd_work;
- struct sk_buff_head c2hcmd_queue;
---- a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c
-+++ b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c
-@@ -6569,10 +6569,12 @@ static int rtl8xxxu_add_interface(struct
- int ret;
- u8 val8;
-
-- if (!priv->vif)
-+ if (!priv->vif) {
- priv->vif = vif;
-- else
-+ priv->vifs[0] = vif;
-+ } else {
- return -EOPNOTSUPP;
-+ }
-
- switch (vif->type) {
- case NL80211_IFTYPE_STATION:
-@@ -6622,8 +6624,10 @@ static void rtl8xxxu_remove_interface(st
-
- dev_dbg(&priv->udev->dev, "%s\n", __func__);
-
-- if (priv->vif)
-+ if (priv->vif) {
- priv->vif = NULL;
-+ priv->vifs[0] = NULL;
-+ }
- }
-
- static int rtl8xxxu_config(struct ieee80211_hw *hw, u32 changed)
+++ /dev/null
-From 7f444692cde83c1455682c2d0d2c9a666422b867 Mon Sep 17 00:00:00 2001
-From: Martin Kaistra <martin.kaistra@linutronix.de>
-Date: Fri, 22 Dec 2023 11:14:24 +0100
-Subject: [PATCH 03/21] wifi: rtl8xxxu: support setting linktype for both
- interfaces
-
-To prepare for concurrent mode, enhance the set_linktype function to be
-able to set the linktype in the MSR register for both hardware ports.
-
-Until the users of set_linktype can handle multiple interfaces, use
-port_num = 0.
-
-Signed-off-by: Martin Kaistra <martin.kaistra@linutronix.de>
-Reviewed-by: Ping-Ke Shih <pkshih@realtek.com>
-Signed-off-by: Kalle Valo <kvalo@kernel.org>
-Link: https://msgid.link/20231222101442.626837-4-martin.kaistra@linutronix.de
----
- .../wireless/realtek/rtl8xxxu/rtl8xxxu_core.c | 37 +++++++++++--------
- 1 file changed, 22 insertions(+), 15 deletions(-)
-
---- a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c
-+++ b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c
-@@ -1633,33 +1633,41 @@ rtl8xxxu_gen1_set_tx_power(struct rtl8xx
- }
-
- static void rtl8xxxu_set_linktype(struct rtl8xxxu_priv *priv,
-- enum nl80211_iftype linktype)
-+ enum nl80211_iftype linktype, int port_num)
- {
-- u8 val8;
--
-- val8 = rtl8xxxu_read8(priv, REG_MSR);
-- val8 &= ~MSR_LINKTYPE_MASK;
-+ u8 val8, type;
-
- switch (linktype) {
- case NL80211_IFTYPE_UNSPECIFIED:
-- val8 |= MSR_LINKTYPE_NONE;
-+ type = MSR_LINKTYPE_NONE;
- break;
- case NL80211_IFTYPE_ADHOC:
-- val8 |= MSR_LINKTYPE_ADHOC;
-+ type = MSR_LINKTYPE_ADHOC;
- break;
- case NL80211_IFTYPE_STATION:
-- val8 |= MSR_LINKTYPE_STATION;
-+ type = MSR_LINKTYPE_STATION;
- break;
- case NL80211_IFTYPE_AP:
-- val8 |= MSR_LINKTYPE_AP;
-+ type = MSR_LINKTYPE_AP;
- break;
- default:
-- goto out;
-+ return;
-+ }
-+
-+ switch (port_num) {
-+ case 0:
-+ val8 = rtl8xxxu_read8(priv, REG_MSR) & 0x0c;
-+ val8 |= type;
-+ break;
-+ case 1:
-+ val8 = rtl8xxxu_read8(priv, REG_MSR) & 0x03;
-+ val8 |= type << 2;
-+ break;
-+ default:
-+ return;
- }
-
- rtl8xxxu_write8(priv, REG_MSR, val8);
--out:
-- return;
- }
-
- static void
-@@ -4236,7 +4244,6 @@ static int rtl8xxxu_init_device(struct i
- }
-
- rtl8xxxu_set_mac(priv);
-- rtl8xxxu_set_linktype(priv, NL80211_IFTYPE_STATION);
-
- /*
- * Configure initial WMAC settings
-@@ -4964,7 +4971,7 @@ rtl8xxxu_bss_info_changed(struct ieee802
- if (changed & BSS_CHANGED_ASSOC) {
- dev_dbg(dev, "Changed ASSOC: %i!\n", vif->cfg.assoc);
-
-- rtl8xxxu_set_linktype(priv, vif->type);
-+ rtl8xxxu_set_linktype(priv, vif->type, 0);
-
- if (vif->cfg.assoc) {
- u32 ramask;
-@@ -6610,7 +6617,7 @@ static int rtl8xxxu_add_interface(struct
- ret = -EOPNOTSUPP;
- }
-
-- rtl8xxxu_set_linktype(priv, vif->type);
-+ rtl8xxxu_set_linktype(priv, vif->type, 0);
- ether_addr_copy(priv->mac_addr, vif->addr);
- rtl8xxxu_set_mac(priv);
-
+++ /dev/null
-From a047e46a7b98de384a158b25a05dc09aa7d70c5f Mon Sep 17 00:00:00 2001
-From: Martin Kaistra <martin.kaistra@linutronix.de>
-Date: Fri, 22 Dec 2023 11:14:25 +0100
-Subject: [PATCH 04/21] wifi: rtl8xxxu: 8188e: convert usage of priv->vif to
- priv->vifs[0]
-
-The driver currently does not support AP or concurrent mode for 8188e,
-so just use priv->vifs[0] instead of priv->vif for now.
-
-Signed-off-by: Martin Kaistra <martin.kaistra@linutronix.de>
-Reviewed-by: Ping-Ke Shih <pkshih@realtek.com>
-Signed-off-by: Kalle Valo <kvalo@kernel.org>
-Link: https://msgid.link/20231222101442.626837-5-martin.kaistra@linutronix.de
----
- drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_8188e.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
---- a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_8188e.c
-+++ b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_8188e.c
-@@ -1699,7 +1699,7 @@ void rtl8188e_handle_ra_tx_report2(struc
- /* We only use macid 0, so only the first item is relevant.
- * AP mode will use more of them if it's ever implemented.
- */
-- if (!priv->vif || priv->vif->type == NL80211_IFTYPE_STATION)
-+ if (!priv->vifs[0] || priv->vifs[0]->type == NL80211_IFTYPE_STATION)
- items = 1;
-
- for (macid = 0; macid < items; macid++) {
+++ /dev/null
-From 00add60cad3c9690ac0f9d4f6685f96ccd607670 Mon Sep 17 00:00:00 2001
-From: Martin Kaistra <martin.kaistra@linutronix.de>
-Date: Fri, 22 Dec 2023 11:14:26 +0100
-Subject: [PATCH 05/21] wifi: rtl8xxxu: support setting mac address register
- for both interfaces
-
-To prepare for concurrent mode, enhance rtl8xxxu_set_mac() to write the
-mac address of the respective interface to REG_MACID or REG_MACID1.
-
-Remove the call to rtl8xxxu_set_mac() from the init function as we set
-it in rtl8xxxu_add_interface() later anyway.
-
-Until rtl8xxxu_add_interface() can handle both interfaces, call
-rtl8xxxu_set_mac() with port_num = 0.
-
-Signed-off-by: Martin Kaistra <martin.kaistra@linutronix.de>
-Reviewed-by: Ping-Ke Shih <pkshih@realtek.com>
-Signed-off-by: Kalle Valo <kvalo@kernel.org>
-Link: https://msgid.link/20231222101442.626837-6-martin.kaistra@linutronix.de
----
- .../wireless/realtek/rtl8xxxu/rtl8xxxu_core.c | 20 +++++++++++++------
- 1 file changed, 14 insertions(+), 6 deletions(-)
-
---- a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c
-+++ b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c
-@@ -3580,15 +3580,25 @@ void rtl8723a_phy_lc_calibrate(struct rt
- rtl8xxxu_write8(priv, REG_TXPAUSE, 0x00);
- }
-
--static int rtl8xxxu_set_mac(struct rtl8xxxu_priv *priv)
-+static int rtl8xxxu_set_mac(struct rtl8xxxu_priv *priv, int port_num)
- {
- int i;
- u16 reg;
-
-- reg = REG_MACID;
-+ switch (port_num) {
-+ case 0:
-+ reg = REG_MACID;
-+ break;
-+ case 1:
-+ reg = REG_MACID1;
-+ break;
-+ default:
-+ WARN_ONCE("%s: invalid port_num\n", __func__);
-+ return -EINVAL;
-+ }
-
- for (i = 0; i < ETH_ALEN; i++)
-- rtl8xxxu_write8(priv, reg + i, priv->mac_addr[i]);
-+ rtl8xxxu_write8(priv, reg + i, priv->vifs[port_num]->addr[i]);
-
- return 0;
- }
-@@ -4243,8 +4253,6 @@ static int rtl8xxxu_init_device(struct i
- rtl8xxxu_write32(priv, REG_HIMR, 0xffffffff);
- }
-
-- rtl8xxxu_set_mac(priv);
--
- /*
- * Configure initial WMAC settings
- */
-@@ -6619,7 +6627,7 @@ static int rtl8xxxu_add_interface(struct
-
- rtl8xxxu_set_linktype(priv, vif->type, 0);
- ether_addr_copy(priv->mac_addr, vif->addr);
-- rtl8xxxu_set_mac(priv);
-+ rtl8xxxu_set_mac(priv, 0);
-
- return ret;
- }
+++ /dev/null
-From 9aa776209ca31695bead52674ad943848ccc97d5 Mon Sep 17 00:00:00 2001
-From: Martin Kaistra <martin.kaistra@linutronix.de>
-Date: Fri, 22 Dec 2023 11:14:27 +0100
-Subject: [PATCH 06/21] wifi: rtl8xxxu: extend wifi connected check to both
- interfaces
-
-There are multiple places in the code where the current connection
-status of wifi is checked. The driver will support two interfaces soon
-and either one of them (or both) could be connected.
-
-Convert all uses of (vif && vif->cfg.assoc) to a new helper
-function rtl8xxxu_is_assoc() which checks both interfaces.
-
-Signed-off-by: Martin Kaistra <martin.kaistra@linutronix.de>
-Reviewed-by: Ping-Ke Shih <pkshih@realtek.com>
-Signed-off-by: Kalle Valo <kvalo@kernel.org>
-Link: https://msgid.link/20231222101442.626837-7-martin.kaistra@linutronix.de
----
- .../wireless/realtek/rtl8xxxu/rtl8xxxu_core.c | 20 +++++++++----------
- 1 file changed, 9 insertions(+), 11 deletions(-)
-
---- a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c
-+++ b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c
-@@ -6043,18 +6043,20 @@ void rtl8723bu_update_bt_link_info(struc
- btcoex->bt_busy = false;
- }
-
-+static inline bool rtl8xxxu_is_assoc(struct rtl8xxxu_priv *priv)
-+{
-+ return (priv->vifs[0] && priv->vifs[0]->cfg.assoc) ||
-+ (priv->vifs[1] && priv->vifs[1]->cfg.assoc);
-+}
-+
- static
- void rtl8723bu_handle_bt_inquiry(struct rtl8xxxu_priv *priv)
- {
-- struct ieee80211_vif *vif;
- struct rtl8xxxu_btcoex *btcoex;
-- bool wifi_connected;
-
-- vif = priv->vif;
- btcoex = &priv->bt_coex;
-- wifi_connected = (vif && vif->cfg.assoc);
-
-- if (!wifi_connected) {
-+ if (!rtl8xxxu_is_assoc(priv)) {
- rtl8723bu_set_ps_tdma(priv, 0x8, 0x0, 0x0, 0x0, 0x0);
- rtl8723bu_set_coex_with_type(priv, 0);
- } else if (btcoex->has_sco || btcoex->has_hid || btcoex->has_a2dp) {
-@@ -6072,15 +6074,11 @@ void rtl8723bu_handle_bt_inquiry(struct
- static
- void rtl8723bu_handle_bt_info(struct rtl8xxxu_priv *priv)
- {
-- struct ieee80211_vif *vif;
- struct rtl8xxxu_btcoex *btcoex;
-- bool wifi_connected;
-
-- vif = priv->vif;
- btcoex = &priv->bt_coex;
-- wifi_connected = (vif && vif->cfg.assoc);
-
-- if (wifi_connected) {
-+ if (rtl8xxxu_is_assoc(priv)) {
- u32 val32 = 0;
- u32 high_prio_tx = 0, high_prio_rx = 0;
-
-@@ -7103,7 +7101,7 @@ static void rtl8xxxu_track_cfo(struct rt
- int cfo_khz_a, cfo_khz_b, cfo_average;
- int crystal_cap;
-
-- if (!priv->vif || !priv->vif->cfg.assoc) {
-+ if (!rtl8xxxu_is_assoc(priv)) {
- /* Reset */
- cfo->adjust = true;
-
+++ /dev/null
-From 80fd8687db41b1e04f78c37137d090f2165cca6e Mon Sep 17 00:00:00 2001
-From: Martin Kaistra <martin.kaistra@linutronix.de>
-Date: Fri, 22 Dec 2023 11:14:28 +0100
-Subject: [PATCH 07/21] wifi: rtl8xxxu: extend check for matching bssid to both
- interfaces
-
-The driver will support two interfaces soon, which both can be in
-station mode, so extend the check, whether cfo information should be
-parsed, to cover both interfaces.
-
-For better code readability put the lines with priv->vifs[port_num] in a
-separate function.
-
-Signed-off-by: Martin Kaistra <martin.kaistra@linutronix.de>
-Reviewed-by: Ping-Ke Shih <pkshih@realtek.com>
-Signed-off-by: Kalle Valo <kvalo@kernel.org>
-Link: https://msgid.link/20231222101442.626837-8-martin.kaistra@linutronix.de
----
- .../wireless/realtek/rtl8xxxu/rtl8xxxu_core.c | 22 ++++++++++++-------
- 1 file changed, 14 insertions(+), 8 deletions(-)
-
---- a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c
-+++ b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c
-@@ -5706,6 +5706,16 @@ static void rtl8xxxu_update_beacon_work_
- rtl8xxxu_send_beacon_frame(hw, vif);
- }
-
-+static inline bool rtl8xxxu_is_packet_match_bssid(struct rtl8xxxu_priv *priv,
-+ struct ieee80211_hdr *hdr,
-+ int port_num)
-+{
-+ return priv->vifs[port_num] &&
-+ priv->vifs[port_num]->type == NL80211_IFTYPE_STATION &&
-+ priv->vifs[port_num]->cfg.assoc &&
-+ ether_addr_equal(priv->vifs[port_num]->bss_conf.bssid, hdr->addr2);
-+}
-+
- void rtl8723au_rx_parse_phystats(struct rtl8xxxu_priv *priv,
- struct ieee80211_rx_status *rx_status,
- struct rtl8723au_phy_stats *phy_stats,
-@@ -5722,12 +5732,10 @@ void rtl8723au_rx_parse_phystats(struct
- rx_status->signal = priv->fops->cck_rssi(priv, phy_stats);
- } else {
- bool parse_cfo = priv->fops->set_crystal_cap &&
-- priv->vif &&
-- priv->vif->type == NL80211_IFTYPE_STATION &&
-- priv->vif->cfg.assoc &&
- !crc_icv_err &&
- !ieee80211_is_ctl(hdr->frame_control) &&
-- ether_addr_equal(priv->vif->bss_conf.bssid, hdr->addr2);
-+ (rtl8xxxu_is_packet_match_bssid(priv, hdr, 0) ||
-+ rtl8xxxu_is_packet_match_bssid(priv, hdr, 1));
-
- if (parse_cfo) {
- priv->cfo_tracking.cfo_tail[0] = phy_stats->path_cfotail[0];
-@@ -5762,12 +5770,10 @@ static void jaguar2_rx_parse_phystats_ty
- bool crc_icv_err)
- {
- bool parse_cfo = priv->fops->set_crystal_cap &&
-- priv->vif &&
-- priv->vif->type == NL80211_IFTYPE_STATION &&
-- priv->vif->cfg.assoc &&
- !crc_icv_err &&
- !ieee80211_is_ctl(hdr->frame_control) &&
-- ether_addr_equal(priv->vif->bss_conf.bssid, hdr->addr2);
-+ (rtl8xxxu_is_packet_match_bssid(priv, hdr, 0) ||
-+ rtl8xxxu_is_packet_match_bssid(priv, hdr, 1));
- u8 pwdb_max = 0;
- int rx_path;
-
+++ /dev/null
-From f86dd8eaf8da84ee5b803d90b8c311d7e2725d0b Mon Sep 17 00:00:00 2001
-From: Martin Kaistra <martin.kaistra@linutronix.de>
-Date: Fri, 22 Dec 2023 11:14:29 +0100
-Subject: [PATCH 08/21] wifi: rtl8xxxu: don't parse CFO, if both interfaces are
- connected in STA mode
-
-If both interfaces are in STATION mode and both are connected to an AP,
-there might be conflicting CFO values for the two connections. Ignore
-the CFO information in this case.
-
-Signed-off-by: Martin Kaistra <martin.kaistra@linutronix.de>
-Reviewed-by: Ping-Ke Shih <pkshih@realtek.com>
-Signed-off-by: Kalle Valo <kvalo@kernel.org>
-Link: https://msgid.link/20231222101442.626837-9-martin.kaistra@linutronix.de
----
- drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c | 10 ++++++++++
- 1 file changed, 10 insertions(+)
-
---- a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c
-+++ b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c
-@@ -5716,6 +5716,14 @@ static inline bool rtl8xxxu_is_packet_ma
- ether_addr_equal(priv->vifs[port_num]->bss_conf.bssid, hdr->addr2);
- }
-
-+static inline bool rtl8xxxu_is_sta_sta(struct rtl8xxxu_priv *priv)
-+{
-+ return (priv->vifs[0] && priv->vifs[0]->cfg.assoc &&
-+ priv->vifs[0]->type == NL80211_IFTYPE_STATION) &&
-+ (priv->vifs[1] && priv->vifs[1]->cfg.assoc &&
-+ priv->vifs[1]->type == NL80211_IFTYPE_STATION);
-+}
-+
- void rtl8723au_rx_parse_phystats(struct rtl8xxxu_priv *priv,
- struct ieee80211_rx_status *rx_status,
- struct rtl8723au_phy_stats *phy_stats,
-@@ -5734,6 +5742,7 @@ void rtl8723au_rx_parse_phystats(struct
- bool parse_cfo = priv->fops->set_crystal_cap &&
- !crc_icv_err &&
- !ieee80211_is_ctl(hdr->frame_control) &&
-+ !rtl8xxxu_is_sta_sta(priv) &&
- (rtl8xxxu_is_packet_match_bssid(priv, hdr, 0) ||
- rtl8xxxu_is_packet_match_bssid(priv, hdr, 1));
-
-@@ -5772,6 +5781,7 @@ static void jaguar2_rx_parse_phystats_ty
- bool parse_cfo = priv->fops->set_crystal_cap &&
- !crc_icv_err &&
- !ieee80211_is_ctl(hdr->frame_control) &&
-+ !rtl8xxxu_is_sta_sta(priv) &&
- (rtl8xxxu_is_packet_match_bssid(priv, hdr, 0) ||
- rtl8xxxu_is_packet_match_bssid(priv, hdr, 1));
- u8 pwdb_max = 0;
+++ /dev/null
-From 3ff7a05996f901a7a10068b42e9dc8435f908a4c Mon Sep 17 00:00:00 2001
-From: Martin Kaistra <martin.kaistra@linutronix.de>
-Date: Fri, 22 Dec 2023 11:14:30 +0100
-Subject: [PATCH 09/21] wifi: rtl8xxxu: support setting bssid register for
- multiple interfaces
-
-To prepare for concurrent mode, enhance rtl8xxxu_set_bssid() to write the
-BSSID of the respective interface to REG_BSSID or REG_BSSID1.
-
-Like done with rtl8xxxu_set_mac(), call rtl8xxxu_set_bssid() with
-port_num = 0, until the callers also support multiple interfaces.
-
-Signed-off-by: Martin Kaistra <martin.kaistra@linutronix.de>
-Reviewed-by: Ping-Ke Shih <pkshih@realtek.com>
-Signed-off-by: Kalle Valo <kvalo@kernel.org>
-Link: https://msgid.link/20231222101442.626837-10-martin.kaistra@linutronix.de
----
- .../wireless/realtek/rtl8xxxu/rtl8xxxu_core.c | 18 ++++++++++++++----
- 1 file changed, 14 insertions(+), 4 deletions(-)
-
---- a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c
-+++ b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c
-@@ -3603,14 +3603,24 @@ static int rtl8xxxu_set_mac(struct rtl8x
- return 0;
- }
-
--static int rtl8xxxu_set_bssid(struct rtl8xxxu_priv *priv, const u8 *bssid)
-+static int rtl8xxxu_set_bssid(struct rtl8xxxu_priv *priv, const u8 *bssid, int port_num)
- {
- int i;
- u16 reg;
-
- dev_dbg(&priv->udev->dev, "%s: (%pM)\n", __func__, bssid);
-
-- reg = REG_BSSID;
-+ switch (port_num) {
-+ case 0:
-+ reg = REG_BSSID;
-+ break;
-+ case 1:
-+ reg = REG_BSSID1;
-+ break;
-+ default:
-+ WARN_ONCE("%s: invalid port_num\n", __func__);
-+ return -EINVAL;
-+ }
-
- for (i = 0; i < ETH_ALEN; i++)
- rtl8xxxu_write8(priv, reg + i, bssid[i]);
-@@ -5068,7 +5078,7 @@ rtl8xxxu_bss_info_changed(struct ieee802
-
- if (changed & BSS_CHANGED_BSSID) {
- dev_dbg(dev, "Changed BSSID!\n");
-- rtl8xxxu_set_bssid(priv, bss_conf->bssid);
-+ rtl8xxxu_set_bssid(priv, bss_conf->bssid, 0);
- }
-
- if (changed & BSS_CHANGED_BASIC_RATES) {
-@@ -5097,7 +5107,7 @@ static int rtl8xxxu_start_ap(struct ieee
- struct device *dev = &priv->udev->dev;
-
- dev_dbg(dev, "Start AP mode\n");
-- rtl8xxxu_set_bssid(priv, vif->bss_conf.bssid);
-+ rtl8xxxu_set_bssid(priv, vif->bss_conf.bssid, 0);
- rtl8xxxu_write16(priv, REG_BCN_INTERVAL, vif->bss_conf.beacon_int);
- priv->fops->report_connect(priv, RTL8XXXU_BC_MC_MACID, 0, true);
-
+++ /dev/null
-From 43532c050f8eec4056a21978fdb5b958e1477553 Mon Sep 17 00:00:00 2001
-From: Martin Kaistra <martin.kaistra@linutronix.de>
-Date: Fri, 22 Dec 2023 11:14:31 +0100
-Subject: [PATCH 10/21] wifi: rtl8xxxu: support multiple interfaces in
- set_aifs()
-
-In concurrent mode supported by this driver, both interfaces will use
-the same channel and same wireless mode.
-It is therefore possible to get the wireless mode by checking the first
-connected interface.
-
-Signed-off-by: Martin Kaistra <martin.kaistra@linutronix.de>
-Reviewed-by: Ping-Ke Shih <pkshih@realtek.com>
-Signed-off-by: Kalle Valo <kvalo@kernel.org>
-Link: https://msgid.link/20231222101442.626837-11-martin.kaistra@linutronix.de
----
- drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c | 10 ++++++++--
- 1 file changed, 8 insertions(+), 2 deletions(-)
-
---- a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c
-+++ b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c
-@@ -4913,14 +4913,20 @@ static void rtl8xxxu_set_aifs(struct rtl
- u8 aifs, aifsn, sifs;
- int i;
-
-- if (priv->vif) {
-+ for (i = 0; i < ARRAY_SIZE(priv->vifs); i++) {
-+ if (!priv->vifs[i])
-+ continue;
-+
- struct ieee80211_sta *sta;
-
- rcu_read_lock();
-- sta = ieee80211_find_sta(priv->vif, priv->vif->bss_conf.bssid);
-+ sta = ieee80211_find_sta(priv->vifs[i], priv->vifs[i]->bss_conf.bssid);
- if (sta)
- wireless_mode = rtl8xxxu_wireless_mode(priv->hw, sta);
- rcu_read_unlock();
-+
-+ if (wireless_mode)
-+ break;
- }
-
- if (priv->hw->conf.chandef.chan->band == NL80211_BAND_5GHZ ||
+++ /dev/null
-From 05b22e9b7d84253f765cde01cb09d144094b61c9 Mon Sep 17 00:00:00 2001
-From: Martin Kaistra <martin.kaistra@linutronix.de>
-Date: Fri, 22 Dec 2023 11:14:32 +0100
-Subject: [PATCH 11/21] wifi: rtl8xxxu: support multiple interfaces in
- update_beacon_work_callback()
-
-As we only want to support AP mode/sending beacons on port 0, it is
-enough to replace priv->vif with priv->vifs[0].
-
-Signed-off-by: Martin Kaistra <martin.kaistra@linutronix.de>
-Reviewed-by: Ping-Ke Shih <pkshih@realtek.com>
-Signed-off-by: Kalle Valo <kvalo@kernel.org>
-Link: https://msgid.link/20231222101442.626837-12-martin.kaistra@linutronix.de
----
- drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
---- a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c
-+++ b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c
-@@ -5712,7 +5712,7 @@ static void rtl8xxxu_update_beacon_work_
- struct rtl8xxxu_priv *priv =
- container_of(work, struct rtl8xxxu_priv, update_beacon_work);
- struct ieee80211_hw *hw = priv->hw;
-- struct ieee80211_vif *vif = priv->vif;
-+ struct ieee80211_vif *vif = priv->vifs[0];
-
- if (!vif) {
- WARN_ONCE(true, "no vif to update beacon\n");
+++ /dev/null
-From 6b76638287055791e74b32c401a39ea1b91e7158 Mon Sep 17 00:00:00 2001
-From: Martin Kaistra <martin.kaistra@linutronix.de>
-Date: Fri, 22 Dec 2023 11:14:33 +0100
-Subject: [PATCH 12/21] wifi: rtl8xxxu: support multiple interfaces in
- configure_filter()
-
-As we only want to support AP mode/sending beacons on port 0, change
-from priv->vif to priv->vifs[0] in the check for AP mode.
-Additionally, if we are in AP mode, don't filter RX beacon and probe
-response frames to still allow working STATION mode on the other
-interface.
-
-Signed-off-by: Martin Kaistra <martin.kaistra@linutronix.de>
-Reviewed-by: Ping-Ke Shih <pkshih@realtek.com>
-Signed-off-by: Kalle Valo <kvalo@kernel.org>
-Link: https://msgid.link/20231222101442.626837-13-martin.kaistra@linutronix.de
----
- drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c | 4 ++--
- 1 file changed, 2 insertions(+), 2 deletions(-)
-
---- a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c
-+++ b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c
-@@ -6794,8 +6794,8 @@ static void rtl8xxxu_configure_filter(st
- else
- rcr |= RCR_CHECK_BSSID_BEACON | RCR_CHECK_BSSID_MATCH;
-
-- if (priv->vif && priv->vif->type == NL80211_IFTYPE_AP)
-- rcr &= ~RCR_CHECK_BSSID_MATCH;
-+ if (priv->vifs[0] && priv->vifs[0]->type == NL80211_IFTYPE_AP)
-+ rcr &= ~(RCR_CHECK_BSSID_MATCH | RCR_CHECK_BSSID_BEACON);
-
- if (*total_flags & FIF_CONTROL)
- rcr |= RCR_ACCEPT_CTRL_FRAME;
+++ /dev/null
-From 3f9baa99f8429ea6f56e7cc8d881c027518e9573 Mon Sep 17 00:00:00 2001
-From: Martin Kaistra <martin.kaistra@linutronix.de>
-Date: Fri, 22 Dec 2023 11:14:34 +0100
-Subject: [PATCH 13/21] wifi: rtl8xxxu: support multiple interfaces in
- watchdog_callback()
-
-Check first whether priv->vifs[0] exists and is of type STATION, then go
-to priv->vifs[1]. Make sure to call refresh_rate_mask for both
-interfaces.
-
-Signed-off-by: Martin Kaistra <martin.kaistra@linutronix.de>
-Reviewed-by: Ping-Ke Shih <pkshih@realtek.com>
-Signed-off-by: Kalle Valo <kvalo@kernel.org>
-Link: https://msgid.link/20231222101442.626837-14-martin.kaistra@linutronix.de
----
- .../wireless/realtek/rtl8xxxu/rtl8xxxu_core.c | 19 +++++++++++--------
- 1 file changed, 11 insertions(+), 8 deletions(-)
-
---- a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c
-+++ b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c
-@@ -7200,11 +7200,15 @@ static void rtl8xxxu_watchdog_callback(s
- {
- struct ieee80211_vif *vif;
- struct rtl8xxxu_priv *priv;
-+ int i;
-
- priv = container_of(work, struct rtl8xxxu_priv, ra_watchdog.work);
-- vif = priv->vif;
-+ for (i = 0; i < ARRAY_SIZE(priv->vifs); i++) {
-+ vif = priv->vifs[i];
-+
-+ if (!vif || vif->type != NL80211_IFTYPE_STATION)
-+ continue;
-
-- if (vif && vif->type == NL80211_IFTYPE_STATION) {
- int signal;
- struct ieee80211_sta *sta;
-
-@@ -7215,22 +7219,21 @@ static void rtl8xxxu_watchdog_callback(s
-
- dev_dbg(dev, "%s: no sta found\n", __func__);
- rcu_read_unlock();
-- goto out;
-+ continue;
- }
- rcu_read_unlock();
-
- signal = ieee80211_ave_rssi(vif);
-
-- priv->fops->report_rssi(priv, 0,
-+ priv->fops->report_rssi(priv, rtl8xxxu_get_macid(priv, sta),
- rtl8xxxu_signal_to_snr(signal));
-
-- if (priv->fops->set_crystal_cap)
-- rtl8xxxu_track_cfo(priv);
--
- rtl8xxxu_refresh_rate_mask(priv, signal, sta, false);
- }
-
--out:
-+ if (priv->fops->set_crystal_cap)
-+ rtl8xxxu_track_cfo(priv);
-+
- schedule_delayed_work(&priv->ra_watchdog, 2 * HZ);
- }
-
+++ /dev/null
-From eef55f1545c92c7181d5083453dee1296298ad3e Mon Sep 17 00:00:00 2001
-From: Martin Kaistra <martin.kaistra@linutronix.de>
-Date: Fri, 22 Dec 2023 11:14:35 +0100
-Subject: [PATCH 14/21] wifi: rtl8xxxu: support multiple interfaces in
- {add,remove}_interface()
-
-Add a custom struct to store in vif->drv_priv with a reference to
-port_num and fill it when a new interface is added. Choose a free
-port_num for the newly added interface.
-
-As we only want to support AP mode/sending beacons on port 0, only change
-the beacon settings if a new interface is actually assigned to port 0.
-
-Call set_linktype() and set_mac() with the appropriate port_num.
-
-Signed-off-by: Martin Kaistra <martin.kaistra@linutronix.de>
-Reviewed-by: Ping-Ke Shih <pkshih@realtek.com>
-Signed-off-by: Kalle Valo <kvalo@kernel.org>
-Link: https://msgid.link/20231222101442.626837-15-martin.kaistra@linutronix.de
----
- .../net/wireless/realtek/rtl8xxxu/rtl8xxxu.h | 4 ++
- .../wireless/realtek/rtl8xxxu/rtl8xxxu_core.c | 52 +++++++++++--------
- 2 files changed, 34 insertions(+), 22 deletions(-)
-
---- a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu.h
-+++ b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu.h
-@@ -1921,6 +1921,10 @@ struct rtl8xxxu_sta_info {
- u8 macid;
- };
-
-+struct rtl8xxxu_vif {
-+ int port_num;
-+};
-+
- struct rtl8xxxu_rx_urb {
- struct urb urb;
- struct ieee80211_hw *hw;
---- a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c
-+++ b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c
-@@ -6610,28 +6610,33 @@ error:
- static int rtl8xxxu_add_interface(struct ieee80211_hw *hw,
- struct ieee80211_vif *vif)
- {
-+ struct rtl8xxxu_vif *rtlvif = (struct rtl8xxxu_vif *)vif->drv_priv;
- struct rtl8xxxu_priv *priv = hw->priv;
-- int ret;
-+ int port_num;
- u8 val8;
-
-- if (!priv->vif) {
-- priv->vif = vif;
-- priv->vifs[0] = vif;
-- } else {
-+ if (!priv->vifs[0])
-+ port_num = 0;
-+ else if (!priv->vifs[1])
-+ port_num = 1;
-+ else
- return -EOPNOTSUPP;
-- }
-
- switch (vif->type) {
- case NL80211_IFTYPE_STATION:
-- rtl8xxxu_stop_tx_beacon(priv);
-+ if (port_num == 0) {
-+ rtl8xxxu_stop_tx_beacon(priv);
-
-- val8 = rtl8xxxu_read8(priv, REG_BEACON_CTRL);
-- val8 |= BEACON_ATIM | BEACON_FUNCTION_ENABLE |
-- BEACON_DISABLE_TSF_UPDATE;
-- rtl8xxxu_write8(priv, REG_BEACON_CTRL, val8);
-- ret = 0;
-+ val8 = rtl8xxxu_read8(priv, REG_BEACON_CTRL);
-+ val8 |= BEACON_ATIM | BEACON_FUNCTION_ENABLE |
-+ BEACON_DISABLE_TSF_UPDATE;
-+ rtl8xxxu_write8(priv, REG_BEACON_CTRL, val8);
-+ }
- break;
- case NL80211_IFTYPE_AP:
-+ if (port_num == 1)
-+ return -EOPNOTSUPP;
-+
- rtl8xxxu_write8(priv, REG_BEACON_CTRL,
- BEACON_DISABLE_TSF_UPDATE | BEACON_CTRL_MBSSID);
- rtl8xxxu_write8(priv, REG_ATIMWND, 0x0c); /* 12ms */
-@@ -6648,31 +6653,32 @@ static int rtl8xxxu_add_interface(struct
- val8 = rtl8xxxu_read8(priv, REG_CCK_CHECK);
- val8 &= ~BIT_BCN_PORT_SEL;
- rtl8xxxu_write8(priv, REG_CCK_CHECK, val8);
--
-- ret = 0;
- break;
- default:
-- ret = -EOPNOTSUPP;
-+ return -EOPNOTSUPP;
- }
-
-- rtl8xxxu_set_linktype(priv, vif->type, 0);
-+ priv->vifs[port_num] = vif;
-+ priv->vif = vif;
-+ rtlvif->port_num = port_num;
-+
-+ rtl8xxxu_set_linktype(priv, vif->type, port_num);
- ether_addr_copy(priv->mac_addr, vif->addr);
-- rtl8xxxu_set_mac(priv, 0);
-+ rtl8xxxu_set_mac(priv, port_num);
-
-- return ret;
-+ return 0;
- }
-
- static void rtl8xxxu_remove_interface(struct ieee80211_hw *hw,
- struct ieee80211_vif *vif)
- {
-+ struct rtl8xxxu_vif *rtlvif = (struct rtl8xxxu_vif *)vif->drv_priv;
- struct rtl8xxxu_priv *priv = hw->priv;
-
- dev_dbg(&priv->udev->dev, "%s\n", __func__);
-
-- if (priv->vif) {
-- priv->vif = NULL;
-- priv->vifs[0] = NULL;
-- }
-+ priv->vif = NULL;
-+ priv->vifs[rtlvif->port_num] = NULL;
- }
-
- static int rtl8xxxu_config(struct ieee80211_hw *hw, u32 changed)
-@@ -7661,6 +7667,8 @@ static int rtl8xxxu_probe(struct usb_int
- if (ret)
- goto err_set_intfdata;
-
-+ hw->vif_data_size = sizeof(struct rtl8xxxu_vif);
-+
- hw->wiphy->max_scan_ssids = 1;
- hw->wiphy->max_scan_ie_len = IEEE80211_MAX_DATA_LEN;
- if (priv->fops->max_macid_num)
+++ /dev/null
-From 073401c3b6b9eaea027240baf07f2b84dd2d2d26 Mon Sep 17 00:00:00 2001
-From: Martin Kaistra <martin.kaistra@linutronix.de>
-Date: Fri, 22 Dec 2023 11:14:36 +0100
-Subject: [PATCH 15/21] wifi: rtl8xxxu: support multiple interfaces in
- bss_info_changed()
-
-Call set_linktype and set_bssid now with correct port_num. Call
-stop_tx_beacon only for port 0, as we don't support beacons on port 1.
-Explicit changes to BEACON will only happen for AP type interfaces, so
-we don't need an additional check there.
-
-Signed-off-by: Martin Kaistra <martin.kaistra@linutronix.de>
-Reviewed-by: Ping-Ke Shih <pkshih@realtek.com>
-Signed-off-by: Kalle Valo <kvalo@kernel.org>
-Link: https://msgid.link/20231222101442.626837-16-martin.kaistra@linutronix.de
----
- drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c | 8 +++++---
- 1 file changed, 5 insertions(+), 3 deletions(-)
-
---- a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c
-+++ b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c
-@@ -4983,6 +4983,7 @@ static void
- rtl8xxxu_bss_info_changed(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
- struct ieee80211_bss_conf *bss_conf, u64 changed)
- {
-+ struct rtl8xxxu_vif *rtlvif = (struct rtl8xxxu_vif *)vif->drv_priv;
- struct rtl8xxxu_priv *priv = hw->priv;
- struct device *dev = &priv->udev->dev;
- struct ieee80211_sta *sta;
-@@ -4995,7 +4996,7 @@ rtl8xxxu_bss_info_changed(struct ieee802
- if (changed & BSS_CHANGED_ASSOC) {
- dev_dbg(dev, "Changed ASSOC: %i!\n", vif->cfg.assoc);
-
-- rtl8xxxu_set_linktype(priv, vif->type, 0);
-+ rtl8xxxu_set_linktype(priv, vif->type, rtlvif->port_num);
-
- if (vif->cfg.assoc) {
- u32 ramask;
-@@ -5042,7 +5043,8 @@ rtl8xxxu_bss_info_changed(struct ieee802
-
- rtl8xxxu_write8(priv, REG_BCN_MAX_ERR, 0xff);
-
-- rtl8xxxu_stop_tx_beacon(priv);
-+ if (rtlvif->port_num == 0)
-+ rtl8xxxu_stop_tx_beacon(priv);
-
- /* joinbss sequence */
- rtl8xxxu_write16(priv, REG_BCN_PSR_RPT,
-@@ -5084,7 +5086,7 @@ rtl8xxxu_bss_info_changed(struct ieee802
-
- if (changed & BSS_CHANGED_BSSID) {
- dev_dbg(dev, "Changed BSSID!\n");
-- rtl8xxxu_set_bssid(priv, bss_conf->bssid, 0);
-+ rtl8xxxu_set_bssid(priv, bss_conf->bssid, rtlvif->port_num);
- }
-
- if (changed & BSS_CHANGED_BASIC_RATES) {
+++ /dev/null
-From 61fdbd9e2a9d74c716bf4d9684653de5efdee691 Mon Sep 17 00:00:00 2001
-From: Martin Kaistra <martin.kaistra@linutronix.de>
-Date: Fri, 22 Dec 2023 11:14:37 +0100
-Subject: [PATCH 16/21] wifi: rtl8xxxu: support multiple interface in
- start_ap()
-
-Call set_bssid() with the correct port_num now.
-
-Signed-off-by: Martin Kaistra <martin.kaistra@linutronix.de>
-Reviewed-by: Ping-Ke Shih <pkshih@realtek.com>
-Signed-off-by: Kalle Valo <kvalo@kernel.org>
-Link: https://msgid.link/20231222101442.626837-17-martin.kaistra@linutronix.de
----
- drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c | 3 ++-
- 1 file changed, 2 insertions(+), 1 deletion(-)
-
---- a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c
-+++ b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c
-@@ -5111,11 +5111,12 @@ error:
- static int rtl8xxxu_start_ap(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
- struct ieee80211_bss_conf *link_conf)
- {
-+ struct rtl8xxxu_vif *rtlvif = (struct rtl8xxxu_vif *)vif->drv_priv;
- struct rtl8xxxu_priv *priv = hw->priv;
- struct device *dev = &priv->udev->dev;
-
- dev_dbg(dev, "Start AP mode\n");
-- rtl8xxxu_set_bssid(priv, vif->bss_conf.bssid, 0);
-+ rtl8xxxu_set_bssid(priv, vif->bss_conf.bssid, rtlvif->port_num);
- rtl8xxxu_write16(priv, REG_BCN_INTERVAL, vif->bss_conf.beacon_int);
- priv->fops->report_connect(priv, RTL8XXXU_BC_MC_MACID, 0, true);
-
+++ /dev/null
-From 5ce0d7e8aee03e73b35f0fe1f1ebbdd4e45776f3 Mon Sep 17 00:00:00 2001
-From: Martin Kaistra <martin.kaistra@linutronix.de>
-Date: Fri, 22 Dec 2023 11:14:38 +0100
-Subject: [PATCH 17/21] wifi: rtl8xxxu: add macids for STA mode
-
-Until now, the driver only assigned a dedicated macid for connections
-made in AP mode, in STA mode the return value of rtl8xxxu_get_macid()
-was simply 0.
-To differentiate between port 0 and 1, when both are in STA mode,
-allocate a second macid (with value 1) and set sta_info->macid according
-to the used port_num in rtl8xxxu_sta_add().
-
-Signed-off-by: Martin Kaistra <martin.kaistra@linutronix.de>
-Reviewed-by: Ping-Ke Shih <pkshih@realtek.com>
-Signed-off-by: Kalle Valo <kvalo@kernel.org>
-Link: https://msgid.link/20231222101442.626837-18-martin.kaistra@linutronix.de
----
- .../net/wireless/realtek/rtl8xxxu/rtl8xxxu.h | 1 +
- .../wireless/realtek/rtl8xxxu/rtl8xxxu_core.c | 18 +++++++++++++++++-
- 2 files changed, 18 insertions(+), 1 deletion(-)
-
---- a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu.h
-+++ b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu.h
-@@ -1774,6 +1774,7 @@ struct rtl8xxxu_cfo_tracking {
- #define RTL8XXXU_HW_LED_CONTROL 2
- #define RTL8XXXU_MAX_MAC_ID_NUM 128
- #define RTL8XXXU_BC_MC_MACID 0
-+#define RTL8XXXU_BC_MC_MACID1 1
-
- struct rtl8xxxu_priv {
- struct ieee80211_hw *hw;
---- a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c
-+++ b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c
-@@ -4053,10 +4053,13 @@ static inline u8 rtl8xxxu_get_macid(stru
- {
- struct rtl8xxxu_sta_info *sta_info;
-
-- if (!priv->vif || priv->vif->type == NL80211_IFTYPE_STATION || !sta)
-+ if (!sta)
- return 0;
-
- sta_info = (struct rtl8xxxu_sta_info *)sta->drv_priv;
-+ if (!sta_info)
-+ return 0;
-+
- return sta_info->macid;
- }
-
-@@ -4536,6 +4539,7 @@ static int rtl8xxxu_init_device(struct i
- rtl8188e_ra_info_init_all(&priv->ra_info);
-
- set_bit(RTL8XXXU_BC_MC_MACID, priv->mac_id_map);
-+ set_bit(RTL8XXXU_BC_MC_MACID1, priv->mac_id_map);
-
- exit:
- return ret;
-@@ -7375,6 +7379,7 @@ static int rtl8xxxu_sta_add(struct ieee8
- struct ieee80211_sta *sta)
- {
- struct rtl8xxxu_sta_info *sta_info = (struct rtl8xxxu_sta_info *)sta->drv_priv;
-+ struct rtl8xxxu_vif *rtlvif = (struct rtl8xxxu_vif *)vif->drv_priv;
- struct rtl8xxxu_priv *priv = hw->priv;
-
- if (vif->type == NL80211_IFTYPE_AP) {
-@@ -7384,6 +7389,17 @@ static int rtl8xxxu_sta_add(struct ieee8
-
- rtl8xxxu_refresh_rate_mask(priv, 0, sta, true);
- priv->fops->report_connect(priv, sta_info->macid, H2C_MACID_ROLE_STA, true);
-+ } else {
-+ switch (rtlvif->port_num) {
-+ case 0:
-+ sta_info->macid = RTL8XXXU_BC_MC_MACID;
-+ break;
-+ case 1:
-+ sta_info->macid = RTL8XXXU_BC_MC_MACID1;
-+ break;
-+ default:
-+ break;
-+ }
- }
-
- return 0;
+++ /dev/null
-From f232e9d91bb84817c60c051a3e3b56dd2721a7b3 Mon Sep 17 00:00:00 2001
-From: Martin Kaistra <martin.kaistra@linutronix.de>
-Date: Fri, 22 Dec 2023 11:14:39 +0100
-Subject: [PATCH 18/21] wifi: rtl8xxxu: remove obsolete priv->vif
-
-Now that all uses of priv->vif have been converted to priv->vifs[]
-remove the old attribute.
-
-Signed-off-by: Martin Kaistra <martin.kaistra@linutronix.de>
-Reviewed-by: Ping-Ke Shih <pkshih@realtek.com>
-Signed-off-by: Kalle Valo <kvalo@kernel.org>
-Link: https://msgid.link/20231222101442.626837-19-martin.kaistra@linutronix.de
----
- drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu.h | 5 -----
- drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c | 2 --
- 2 files changed, 7 deletions(-)
-
---- a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu.h
-+++ b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu.h
-@@ -1893,11 +1893,6 @@ struct rtl8xxxu_priv {
- u8 rssi_level;
- DECLARE_BITMAP(tx_aggr_started, IEEE80211_NUM_TIDS);
- DECLARE_BITMAP(tid_tx_operational, IEEE80211_NUM_TIDS);
-- /*
-- * Only one virtual interface permitted because only STA mode
-- * is supported and no iface_combinations are provided.
-- */
-- struct ieee80211_vif *vif;
-
- struct ieee80211_vif *vifs[2];
- struct delayed_work ra_watchdog;
---- a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c
-+++ b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c
-@@ -6666,7 +6666,6 @@ static int rtl8xxxu_add_interface(struct
- }
-
- priv->vifs[port_num] = vif;
-- priv->vif = vif;
- rtlvif->port_num = port_num;
-
- rtl8xxxu_set_linktype(priv, vif->type, port_num);
-@@ -6684,7 +6683,6 @@ static void rtl8xxxu_remove_interface(st
-
- dev_dbg(&priv->udev->dev, "%s\n", __func__);
-
-- priv->vif = NULL;
- priv->vifs[rtlvif->port_num] = NULL;
- }
-
+++ /dev/null
-From b837f78fbffa5f8e7e7c59879db54793abf161ec Mon Sep 17 00:00:00 2001
-From: Martin Kaistra <martin.kaistra@linutronix.de>
-Date: Fri, 22 Dec 2023 11:14:40 +0100
-Subject: [PATCH 19/21] wifi: rtl8xxxu: add hw crypto support for AP mode
-
-Add a custom function for allocating entries in the sec cam. This allows
-us to store multiple keys with the same keyidx.
-
-The maximum number of sec cam entries for 8188f is 16 according to the
-vendor driver. Add the number to rtl8xxxu_fileops, so that other chips
-which might support more entries, can set a different number there.
-
-Set the bssid as mac address for group keys instead of just using the
-ethernet broadcast address and use BIT(6) in the sec cam ctrl entry
-for differentiating them from pairwise keys like in the vendor driver.
-
-Add the TXDESC_EN_DESC_ID bit and the hw_key_idx to tx
-broadcast/multicast packets in AP mode.
-
-Finally, allow the usage of rtl8xxxu_set_key() for AP mode.
-
-Signed-off-by: Martin Kaistra <martin.kaistra@linutronix.de>
-Reviewed-by: Ping-Ke Shih <pkshih@realtek.com>
-Signed-off-by: Kalle Valo <kvalo@kernel.org>
-Link: https://msgid.link/20231222101442.626837-20-martin.kaistra@linutronix.de
----
- .../net/wireless/realtek/rtl8xxxu/rtl8xxxu.h | 5 ++
- .../realtek/rtl8xxxu/rtl8xxxu_8188f.c | 1 +
- .../wireless/realtek/rtl8xxxu/rtl8xxxu_core.c | 48 +++++++++++++++----
- 3 files changed, 44 insertions(+), 10 deletions(-)
-
---- a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu.h
-+++ b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu.h
-@@ -498,6 +498,7 @@ struct rtl8xxxu_txdesc40 {
- #define DESC_RATE_ID_SHIFT 16
- #define DESC_RATE_ID_MASK 0xf
- #define TXDESC_NAVUSEHDR BIT(20)
-+#define TXDESC_EN_DESC_ID BIT(21)
- #define TXDESC_SEC_RC4 0x00400000
- #define TXDESC_SEC_AES 0x00c00000
- #define TXDESC_PKT_OFFSET_SHIFT 26
-@@ -1775,6 +1776,7 @@ struct rtl8xxxu_cfo_tracking {
- #define RTL8XXXU_MAX_MAC_ID_NUM 128
- #define RTL8XXXU_BC_MC_MACID 0
- #define RTL8XXXU_BC_MC_MACID1 1
-+#define RTL8XXXU_MAX_SEC_CAM_NUM 64
-
- struct rtl8xxxu_priv {
- struct ieee80211_hw *hw;
-@@ -1908,6 +1910,7 @@ struct rtl8xxxu_priv {
- char led_name[32];
- struct led_classdev led_cdev;
- DECLARE_BITMAP(mac_id_map, RTL8XXXU_MAX_MAC_ID_NUM);
-+ DECLARE_BITMAP(cam_map, RTL8XXXU_MAX_SEC_CAM_NUM);
- };
-
- struct rtl8xxxu_sta_info {
-@@ -1919,6 +1922,7 @@ struct rtl8xxxu_sta_info {
-
- struct rtl8xxxu_vif {
- int port_num;
-+ u8 hw_key_idx;
- };
-
- struct rtl8xxxu_rx_urb {
-@@ -1993,6 +1997,7 @@ struct rtl8xxxu_fileops {
- u16 max_aggr_num;
- u8 supports_ap:1;
- u16 max_macid_num;
-+ u16 max_sec_cam_num;
- u32 adda_1t_init;
- u32 adda_1t_path_on;
- u32 adda_2t_path_on_a;
---- a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_8188f.c
-+++ b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_8188f.c
-@@ -1751,6 +1751,7 @@ struct rtl8xxxu_fileops rtl8188fu_fops =
- .max_aggr_num = 0x0c14,
- .supports_ap = 1,
- .max_macid_num = 16,
-+ .max_sec_cam_num = 16,
- .adda_1t_init = 0x03c00014,
- .adda_1t_path_on = 0x03c00014,
- .trxff_boundary = 0x3f7f,
---- a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c
-+++ b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c
-@@ -4559,8 +4559,10 @@ static void rtl8xxxu_cam_write(struct rt
- * This is a bit of a hack - the lower bits of the cipher
- * suite selector happens to match the cipher index in the CAM
- */
-- addr = key->keyidx << CAM_CMD_KEY_SHIFT;
-+ addr = key->hw_key_idx << CAM_CMD_KEY_SHIFT;
- ctrl = (key->cipher & 0x0f) << 2 | key->keyidx | CAM_WRITE_VALID;
-+ if (!(key->flags & IEEE80211_KEY_FLAG_PAIRWISE))
-+ ctrl |= BIT(6);
-
- for (j = 5; j >= 0; j--) {
- switch (j) {
-@@ -5546,13 +5548,14 @@ static void rtl8xxxu_tx(struct ieee80211
- struct rtl8xxxu_tx_urb *tx_urb;
- struct ieee80211_sta *sta = NULL;
- struct ieee80211_vif *vif = tx_info->control.vif;
-+ struct rtl8xxxu_vif *rtlvif = (struct rtl8xxxu_vif *)vif->drv_priv;
- struct device *dev = &priv->udev->dev;
- u32 queue, rts_rate;
- u16 pktlen = skb->len;
- int tx_desc_size = priv->fops->tx_desc_size;
- u8 macid;
- int ret;
-- bool ampdu_enable, sgi = false, short_preamble = false;
-+ bool ampdu_enable, sgi = false, short_preamble = false, bmc = false;
-
- if (skb_headroom(skb) < tx_desc_size) {
- dev_warn(dev,
-@@ -5594,10 +5597,14 @@ static void rtl8xxxu_tx(struct ieee80211
- tx_desc->txdw0 =
- TXDESC_OWN | TXDESC_FIRST_SEGMENT | TXDESC_LAST_SEGMENT;
- if (is_multicast_ether_addr(ieee80211_get_DA(hdr)) ||
-- is_broadcast_ether_addr(ieee80211_get_DA(hdr)))
-+ is_broadcast_ether_addr(ieee80211_get_DA(hdr))) {
- tx_desc->txdw0 |= TXDESC_BROADMULTICAST;
-+ bmc = true;
-+ }
-+
-
- tx_desc->txdw1 = cpu_to_le32(queue << TXDESC_QUEUE_SHIFT);
-+ macid = rtl8xxxu_get_macid(priv, sta);
-
- if (tx_info->control.hw_key) {
- switch (tx_info->control.hw_key->cipher) {
-@@ -5612,6 +5619,10 @@ static void rtl8xxxu_tx(struct ieee80211
- default:
- break;
- }
-+ if (bmc && rtlvif->hw_key_idx != 0xff) {
-+ tx_desc->txdw1 |= TXDESC_EN_DESC_ID;
-+ macid = rtlvif->hw_key_idx;
-+ }
- }
-
- /* (tx_info->flags & IEEE80211_TX_CTL_AMPDU) && */
-@@ -5655,7 +5666,6 @@ static void rtl8xxxu_tx(struct ieee80211
- else
- rts_rate = 0;
-
-- macid = rtl8xxxu_get_macid(priv, sta);
- priv->fops->fill_txdesc(hw, hdr, tx_info, tx_desc, sgi, short_preamble,
- ampdu_enable, rts_rate, macid);
-
-@@ -6667,6 +6677,7 @@ static int rtl8xxxu_add_interface(struct
-
- priv->vifs[port_num] = vif;
- rtlvif->port_num = port_num;
-+ rtlvif->hw_key_idx = 0xff;
-
- rtl8xxxu_set_linktype(priv, vif->type, port_num);
- ether_addr_copy(priv->mac_addr, vif->addr);
-@@ -6843,11 +6854,19 @@ static int rtl8xxxu_set_rts_threshold(st
- return 0;
- }
-
-+static int rtl8xxxu_get_free_sec_cam(struct ieee80211_hw *hw)
-+{
-+ struct rtl8xxxu_priv *priv = hw->priv;
-+
-+ return find_first_zero_bit(priv->cam_map, priv->fops->max_sec_cam_num);
-+}
-+
- static int rtl8xxxu_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
- struct ieee80211_vif *vif,
- struct ieee80211_sta *sta,
- struct ieee80211_key_conf *key)
- {
-+ struct rtl8xxxu_vif *rtlvif = (struct rtl8xxxu_vif *)vif->drv_priv;
- struct rtl8xxxu_priv *priv = hw->priv;
- struct device *dev = &priv->udev->dev;
- u8 mac_addr[ETH_ALEN];
-@@ -6859,9 +6878,6 @@ static int rtl8xxxu_set_key(struct ieee8
- dev_dbg(dev, "%s: cmd %02x, cipher %08x, index %i\n",
- __func__, cmd, key->cipher, key->keyidx);
-
-- if (vif->type != NL80211_IFTYPE_STATION)
-- return -EOPNOTSUPP;
--
- if (key->keyidx > 3)
- return -EOPNOTSUPP;
-
-@@ -6885,7 +6901,7 @@ static int rtl8xxxu_set_key(struct ieee8
- ether_addr_copy(mac_addr, sta->addr);
- } else {
- dev_dbg(dev, "%s: group key\n", __func__);
-- eth_broadcast_addr(mac_addr);
-+ ether_addr_copy(mac_addr, vif->bss_conf.bssid);
- }
-
- val16 = rtl8xxxu_read16(priv, REG_CR);
-@@ -6899,16 +6915,28 @@ static int rtl8xxxu_set_key(struct ieee8
-
- switch (cmd) {
- case SET_KEY:
-- key->hw_key_idx = key->keyidx;
-+
-+ retval = rtl8xxxu_get_free_sec_cam(hw);
-+ if (retval < 0)
-+ return -EOPNOTSUPP;
-+
-+ key->hw_key_idx = retval;
-+
-+ if (vif->type == NL80211_IFTYPE_AP && !(key->flags & IEEE80211_KEY_FLAG_PAIRWISE))
-+ rtlvif->hw_key_idx = key->hw_key_idx;
-+
- key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV;
- rtl8xxxu_cam_write(priv, key, mac_addr);
-+ set_bit(key->hw_key_idx, priv->cam_map);
- retval = 0;
- break;
- case DISABLE_KEY:
- rtl8xxxu_write32(priv, REG_CAM_WRITE, 0x00000000);
- val32 = CAM_CMD_POLLING | CAM_CMD_WRITE |
-- key->keyidx << CAM_CMD_KEY_SHIFT;
-+ key->hw_key_idx << CAM_CMD_KEY_SHIFT;
- rtl8xxxu_write32(priv, REG_CAM_CMD, val32);
-+ rtlvif->hw_key_idx = 0xff;
-+ clear_bit(key->hw_key_idx, priv->cam_map);
- retval = 0;
- break;
- default:
+++ /dev/null
-From 69abad618efd17e50bc6f880332ab36b660b0b34 Mon Sep 17 00:00:00 2001
-From: Martin Kaistra <martin.kaistra@linutronix.de>
-Date: Fri, 22 Dec 2023 11:14:41 +0100
-Subject: [PATCH 20/21] wifi: rtl8xxxu: make supporting AP mode only on port 0
- transparent
-
-When the driver is used for concurrent mode, both virtual interfaces can
-be set to station or AP mode, though only one can be in AP mode at the
-same time.
-
-In order to keep the code simple, use only hw port 0 for AP mode. When
-an interface is added in AP mode which would be assigned to port 1, use
-a switch_port function to transparently swap the mapping between virtual
-interface and hw port.
-
-Signed-off-by: Martin Kaistra <martin.kaistra@linutronix.de>
-Reviewed-by: Ping-Ke Shih <pkshih@realtek.com>
-Signed-off-by: Kalle Valo <kvalo@kernel.org>
-Link: https://msgid.link/20231222101442.626837-21-martin.kaistra@linutronix.de
----
- .../wireless/realtek/rtl8xxxu/rtl8xxxu_core.c | 91 ++++++++++++++++++-
- 1 file changed, 89 insertions(+), 2 deletions(-)
-
---- a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c
-+++ b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c
-@@ -6624,6 +6624,91 @@ error:
- return ret;
- }
-
-+static void rtl8xxxu_switch_ports(struct rtl8xxxu_priv *priv)
-+{
-+ u8 macid[ETH_ALEN], bssid[ETH_ALEN], macid_1[ETH_ALEN], bssid_1[ETH_ALEN];
-+ u8 msr, bcn_ctrl, bcn_ctrl_1, atimwnd[2], atimwnd_1[2];
-+ struct rtl8xxxu_vif *rtlvif;
-+ struct ieee80211_vif *vif;
-+ u8 tsftr[8], tsftr_1[8];
-+ int i;
-+
-+ msr = rtl8xxxu_read8(priv, REG_MSR);
-+ bcn_ctrl = rtl8xxxu_read8(priv, REG_BEACON_CTRL);
-+ bcn_ctrl_1 = rtl8xxxu_read8(priv, REG_BEACON_CTRL_1);
-+
-+ for (i = 0; i < ARRAY_SIZE(atimwnd); i++)
-+ atimwnd[i] = rtl8xxxu_read8(priv, REG_ATIMWND + i);
-+ for (i = 0; i < ARRAY_SIZE(atimwnd_1); i++)
-+ atimwnd_1[i] = rtl8xxxu_read8(priv, REG_ATIMWND_1 + i);
-+
-+ for (i = 0; i < ARRAY_SIZE(tsftr); i++)
-+ tsftr[i] = rtl8xxxu_read8(priv, REG_TSFTR + i);
-+ for (i = 0; i < ARRAY_SIZE(tsftr); i++)
-+ tsftr_1[i] = rtl8xxxu_read8(priv, REG_TSFTR1 + i);
-+
-+ for (i = 0; i < ARRAY_SIZE(macid); i++)
-+ macid[i] = rtl8xxxu_read8(priv, REG_MACID + i);
-+
-+ for (i = 0; i < ARRAY_SIZE(bssid); i++)
-+ bssid[i] = rtl8xxxu_read8(priv, REG_BSSID + i);
-+
-+ for (i = 0; i < ARRAY_SIZE(macid_1); i++)
-+ macid_1[i] = rtl8xxxu_read8(priv, REG_MACID1 + i);
-+
-+ for (i = 0; i < ARRAY_SIZE(bssid_1); i++)
-+ bssid_1[i] = rtl8xxxu_read8(priv, REG_BSSID1 + i);
-+
-+ /* disable bcn function, disable update TSF */
-+ rtl8xxxu_write8(priv, REG_BEACON_CTRL, (bcn_ctrl &
-+ (~BEACON_FUNCTION_ENABLE)) | BEACON_DISABLE_TSF_UPDATE);
-+ rtl8xxxu_write8(priv, REG_BEACON_CTRL_1, (bcn_ctrl_1 &
-+ (~BEACON_FUNCTION_ENABLE)) | BEACON_DISABLE_TSF_UPDATE);
-+
-+ /* switch msr */
-+ msr = (msr & 0xf0) | ((msr & 0x03) << 2) | ((msr & 0x0c) >> 2);
-+ rtl8xxxu_write8(priv, REG_MSR, msr);
-+
-+ /* write port0 */
-+ rtl8xxxu_write8(priv, REG_BEACON_CTRL, bcn_ctrl_1 & ~BEACON_FUNCTION_ENABLE);
-+ for (i = 0; i < ARRAY_SIZE(atimwnd_1); i++)
-+ rtl8xxxu_write8(priv, REG_ATIMWND + i, atimwnd_1[i]);
-+ for (i = 0; i < ARRAY_SIZE(tsftr_1); i++)
-+ rtl8xxxu_write8(priv, REG_TSFTR + i, tsftr_1[i]);
-+ for (i = 0; i < ARRAY_SIZE(macid_1); i++)
-+ rtl8xxxu_write8(priv, REG_MACID + i, macid_1[i]);
-+ for (i = 0; i < ARRAY_SIZE(bssid_1); i++)
-+ rtl8xxxu_write8(priv, REG_BSSID + i, bssid_1[i]);
-+
-+ /* write port1 */
-+ rtl8xxxu_write8(priv, REG_BEACON_CTRL_1, bcn_ctrl & ~BEACON_FUNCTION_ENABLE);
-+ for (i = 0; i < ARRAY_SIZE(atimwnd); i++)
-+ rtl8xxxu_write8(priv, REG_ATIMWND_1 + i, atimwnd[i]);
-+ for (i = 0; i < ARRAY_SIZE(tsftr); i++)
-+ rtl8xxxu_write8(priv, REG_TSFTR1 + i, tsftr[i]);
-+ for (i = 0; i < ARRAY_SIZE(macid); i++)
-+ rtl8xxxu_write8(priv, REG_MACID1 + i, macid[i]);
-+ for (i = 0; i < ARRAY_SIZE(bssid); i++)
-+ rtl8xxxu_write8(priv, REG_BSSID1 + i, bssid[i]);
-+
-+ /* write bcn ctl */
-+ rtl8xxxu_write8(priv, REG_BEACON_CTRL, bcn_ctrl_1);
-+ rtl8xxxu_write8(priv, REG_BEACON_CTRL_1, bcn_ctrl);
-+
-+ vif = priv->vifs[0];
-+ priv->vifs[0] = priv->vifs[1];
-+ priv->vifs[1] = vif;
-+
-+ /* priv->vifs[0] is NULL here, based on how this function is currently
-+ * called from rtl8xxxu_add_interface().
-+ * When this function will be used in the future for a different
-+ * scenario, please check whether vifs[0] or vifs[1] can be NULL and if
-+ * necessary add code to set port_num = 1.
-+ */
-+ rtlvif = (struct rtl8xxxu_vif *)priv->vifs[1]->drv_priv;
-+ rtlvif->port_num = 1;
-+}
-+
- static int rtl8xxxu_add_interface(struct ieee80211_hw *hw,
- struct ieee80211_vif *vif)
- {
-@@ -6651,8 +6736,10 @@ static int rtl8xxxu_add_interface(struct
- }
- break;
- case NL80211_IFTYPE_AP:
-- if (port_num == 1)
-- return -EOPNOTSUPP;
-+ if (port_num == 1) {
-+ rtl8xxxu_switch_ports(priv);
-+ port_num = 0;
-+ }
-
- rtl8xxxu_write8(priv, REG_BEACON_CTRL,
- BEACON_DISABLE_TSF_UPDATE | BEACON_CTRL_MBSSID);
+++ /dev/null
-From 1cd165adf314f6bf25cde58f02f4ff51d01730b0 Mon Sep 17 00:00:00 2001
-From: Martin Kaistra <martin.kaistra@linutronix.de>
-Date: Fri, 22 Dec 2023 11:14:42 +0100
-Subject: [PATCH 21/21] wifi: rtl8xxxu: declare concurrent mode support for
- 8188f
-
-Everything is in place now for concurrent mode, we can tell the system
-that we support it.
-We will allow a maximum of 2 virtual interfaces, one of them can be in
-AP mode.
-
-Signed-off-by: Martin Kaistra <martin.kaistra@linutronix.de>
-Reviewed-by: Ping-Ke Shih <pkshih@realtek.com>
-Signed-off-by: Kalle Valo <kvalo@kernel.org>
-Link: https://msgid.link/20231222101442.626837-22-martin.kaistra@linutronix.de
----
- .../net/wireless/realtek/rtl8xxxu/rtl8xxxu.h | 1 +
- .../realtek/rtl8xxxu/rtl8xxxu_8188f.c | 1 +
- .../wireless/realtek/rtl8xxxu/rtl8xxxu_core.c | 19 +++++++++++++++++++
- 3 files changed, 21 insertions(+)
-
---- a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu.h
-+++ b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu.h
-@@ -1992,6 +1992,7 @@ struct rtl8xxxu_fileops {
- u8 init_reg_rxfltmap:1;
- u8 init_reg_pkt_life_time:1;
- u8 init_reg_hmtfr:1;
-+ u8 supports_concurrent:1;
- u8 ampdu_max_time;
- u8 ustime_tsf_edca;
- u16 max_aggr_num;
---- a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_8188f.c
-+++ b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_8188f.c
-@@ -1752,6 +1752,7 @@ struct rtl8xxxu_fileops rtl8188fu_fops =
- .supports_ap = 1,
- .max_macid_num = 16,
- .max_sec_cam_num = 16,
-+ .supports_concurrent = 1,
- .adda_1t_init = 0x03c00014,
- .adda_1t_path_on = 0x03c00014,
- .trxff_boundary = 0x3f7f,
---- a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c
-+++ b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c
-@@ -7665,6 +7665,20 @@ static void rtl8xxxu_deinit_led(struct r
- led_classdev_unregister(led);
- }
-
-+struct ieee80211_iface_limit rtl8xxxu_limits[] = {
-+ { .max = 2, .types = BIT(NL80211_IFTYPE_STATION), },
-+ { .max = 1, .types = BIT(NL80211_IFTYPE_AP), },
-+};
-+
-+struct ieee80211_iface_combination rtl8xxxu_combinations[] = {
-+ {
-+ .limits = rtl8xxxu_limits,
-+ .n_limits = ARRAY_SIZE(rtl8xxxu_limits),
-+ .max_interfaces = 2,
-+ .num_different_channels = 1,
-+ },
-+};
-+
- static int rtl8xxxu_probe(struct usb_interface *interface,
- const struct usb_device_id *id)
- {
-@@ -7810,6 +7824,11 @@ static int rtl8xxxu_probe(struct usb_int
- hw->wiphy->interface_modes |= BIT(NL80211_IFTYPE_AP);
- hw->queues = 4;
-
-+ if (priv->fops->supports_concurrent) {
-+ hw->wiphy->iface_combinations = rtl8xxxu_combinations;
-+ hw->wiphy->n_iface_combinations = ARRAY_SIZE(rtl8xxxu_combinations);
-+ }
-+
- sband = &rtl8xxxu_supported_band;
- sband->ht_cap.ht_supported = true;
- sband->ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K;
+++ /dev/null
-From 9475cc7ac31503521af95e38151e9d856e8ff30b Mon Sep 17 00:00:00 2001
-From: Bitterblue Smith <rtl8821cerfe2@gmail.com>
-Date: Sun, 31 Dec 2023 00:45:54 +0200
-Subject: [PATCH 1/2] wifi: rtl8xxxu: Fix LED control code of RTL8192FU
-
-Some devices, like the Comfast CF-826F, use LED1, which already works.
-Others, like Asus USB-N13 C1, use LED0, which doesn't work correctly.
-
-Write the right values to the LED control registers to make LED0 work
-as well.
-
-This is unfortunately tested only with the Comfast CF-826F.
-
-Signed-off-by: Bitterblue Smith <rtl8821cerfe2@gmail.com>
-Reviewed-by: Ping-Ke Shih <pkshih@realtek.com>
-Signed-off-by: Kalle Valo <kvalo@kernel.org>
-Link: https://msgid.link/7a2c3158-3a45-4466-b11e-fc09802b20e2@gmail.com
----
- .../realtek/rtl8xxxu/rtl8xxxu_8192f.c | 32 +++++++++++++------
- .../wireless/realtek/rtl8xxxu/rtl8xxxu_regs.h | 15 +++++++++
- 2 files changed, 38 insertions(+), 9 deletions(-)
-
---- a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_8192f.c
-+++ b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_8192f.c
-@@ -2014,26 +2014,40 @@ static int rtl8192fu_led_brightness_set(
- struct rtl8xxxu_priv *priv = container_of(led_cdev,
- struct rtl8xxxu_priv,
- led_cdev);
-- u16 ledcfg;
-+ u32 ledcfg;
-
- /* Values obtained by observing the USB traffic from the Windows driver. */
- rtl8xxxu_write32(priv, REG_SW_GPIO_SHARE_CTRL_0, 0x20080);
- rtl8xxxu_write32(priv, REG_SW_GPIO_SHARE_CTRL_1, 0x1b0000);
-
-- ledcfg = rtl8xxxu_read16(priv, REG_LEDCFG0);
-+ ledcfg = rtl8xxxu_read32(priv, REG_LEDCFG0);
-+
-+ /* Comfast CF-826F uses LED1. Asus USB-N13 C1 uses LED0. Set both. */
-+
-+ u32p_replace_bits(&ledcfg, LED_GPIO_ENABLE, LEDCFG0_LED2EN);
-+ u32p_replace_bits(&ledcfg, LED_IO_MODE_OUTPUT, LEDCFG0_LED0_IO_MODE);
-+ u32p_replace_bits(&ledcfg, LED_IO_MODE_OUTPUT, LEDCFG0_LED1_IO_MODE);
-
- if (brightness == LED_OFF) {
-- /* Value obtained like above. */
-- ledcfg = BIT(1) | BIT(7);
-+ u32p_replace_bits(&ledcfg, LED_MODE_SW_CTRL, LEDCFG0_LED0CM);
-+ u32p_replace_bits(&ledcfg, LED_SW_OFF, LEDCFG0_LED0SV);
-+ u32p_replace_bits(&ledcfg, LED_MODE_SW_CTRL, LEDCFG0_LED1CM);
-+ u32p_replace_bits(&ledcfg, LED_SW_OFF, LEDCFG0_LED1SV);
- } else if (brightness == LED_ON) {
-- /* Value obtained like above. */
-- ledcfg = BIT(1) | BIT(7) | BIT(11);
-+ u32p_replace_bits(&ledcfg, LED_MODE_SW_CTRL, LEDCFG0_LED0CM);
-+ u32p_replace_bits(&ledcfg, LED_SW_ON, LEDCFG0_LED0SV);
-+ u32p_replace_bits(&ledcfg, LED_MODE_SW_CTRL, LEDCFG0_LED1CM);
-+ u32p_replace_bits(&ledcfg, LED_SW_ON, LEDCFG0_LED1SV);
- } else if (brightness == RTL8XXXU_HW_LED_CONTROL) {
-- /* Value obtained by brute force. */
-- ledcfg = BIT(8) | BIT(9);
-+ u32p_replace_bits(&ledcfg, LED_MODE_TX_OR_RX_EVENTS,
-+ LEDCFG0_LED0CM);
-+ u32p_replace_bits(&ledcfg, LED_SW_OFF, LEDCFG0_LED0SV);
-+ u32p_replace_bits(&ledcfg, LED_MODE_TX_OR_RX_EVENTS,
-+ LEDCFG0_LED1CM);
-+ u32p_replace_bits(&ledcfg, LED_SW_OFF, LEDCFG0_LED1SV);
- }
-
-- rtl8xxxu_write16(priv, REG_LEDCFG0, ledcfg);
-+ rtl8xxxu_write32(priv, REG_LEDCFG0, ledcfg);
-
- return 0;
- }
---- a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_regs.h
-+++ b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_regs.h
-@@ -146,6 +146,21 @@
- #define GPIO_INTM_EDGE_TRIG_IRQ BIT(9)
-
- #define REG_LEDCFG0 0x004c
-+#define LEDCFG0_LED0CM GENMASK(2, 0)
-+#define LEDCFG0_LED1CM GENMASK(10, 8)
-+#define LED_MODE_SW_CTRL 0x0
-+#define LED_MODE_TX_OR_RX_EVENTS 0x3
-+#define LEDCFG0_LED0SV BIT(3)
-+#define LEDCFG0_LED1SV BIT(11)
-+#define LED_SW_OFF 0x0
-+#define LED_SW_ON 0x1
-+#define LEDCFG0_LED0_IO_MODE BIT(7)
-+#define LEDCFG0_LED1_IO_MODE BIT(15)
-+#define LED_IO_MODE_OUTPUT 0x0
-+#define LED_IO_MODE_INPUT 0x1
-+#define LEDCFG0_LED2EN BIT(21)
-+#define LED_GPIO_DISABLE 0x0
-+#define LED_GPIO_ENABLE 0x1
- #define LEDCFG0_DPDT_SELECT BIT(23)
- #define REG_LEDCFG1 0x004d
- #define LEDCFG1_HW_LED_CONTROL BIT(1)
+++ /dev/null
-From 80850ca041f2c7ee28fa5e47c5c1b106415f099f Mon Sep 17 00:00:00 2001
-From: Bitterblue Smith <rtl8821cerfe2@gmail.com>
-Date: Tue, 2 Jan 2024 21:33:07 +0200
-Subject: [PATCH 2/2] wifi: rtl8xxxu: Fix off by one initial RTS rate
-
-rtl8xxxu_set_basic_rates() sets the wrong initial RTS rate. It sets the
-next higher rate than the one it should set, e.g. 36M instead of 24M.
-
-The while loop was supposed to find the index of the most significant
-bit which is 1, but it was copied incorrectly from the vendor driver.
-Use __fls() instead.
-
-Signed-off-by: Bitterblue Smith <rtl8821cerfe2@gmail.com>
-Reviewed-by: Ping-Ke Shih <pkshih@realtek.com>
-Signed-off-by: Kalle Valo <kvalo@kernel.org>
-Link: https://msgid.link/761e6836-6cd6-4930-91b6-0446834655c5@gmail.com
----
- drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c | 7 +++----
- 1 file changed, 3 insertions(+), 4 deletions(-)
-
---- a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c
-+++ b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c
-@@ -4870,10 +4870,9 @@ static void rtl8xxxu_set_basic_rates(str
-
- dev_dbg(&priv->udev->dev, "%s: rates %08x\n", __func__, rate_cfg);
-
-- while (rate_cfg) {
-- rate_cfg = (rate_cfg >> 1);
-- rate_idx++;
-- }
-+ if (rate_cfg)
-+ rate_idx = __fls(rate_cfg);
-+
- rtl8xxxu_write8(priv, REG_INIRTS_RATE_SEL, rate_idx);
- }
-
+++ /dev/null
-From 1213acb478a7181cd73eeaf00db430f1e45b1361 Mon Sep 17 00:00:00 2001
-From: Martin Kaistra <martin.kaistra@linutronix.de>
-Date: Thu, 11 Jan 2024 17:36:27 +0100
-Subject: [PATCH 1/2] wifi: rtl8xxxu: add cancel_work_sync() for c2hcmd_work
-
-The workqueue might still be running, when the driver is stopped. To
-avoid a use-after-free, call cancel_work_sync() in rtl8xxxu_stop().
-
-Fixes: e542e66b7c2e ("rtl8xxxu: add bluetooth co-existence support for single antenna")
-Signed-off-by: Martin Kaistra <martin.kaistra@linutronix.de>
-Reviewed-by: Ping-Ke Shih <pkshih@realtek.com>
-Signed-off-by: Kalle Valo <kvalo@kernel.org>
-Link: https://msgid.link/20240111163628.320697-2-martin.kaistra@linutronix.de
----
- drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c | 1 +
- 1 file changed, 1 insertion(+)
-
---- a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c
-+++ b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c
-@@ -7480,6 +7480,7 @@ static void rtl8xxxu_stop(struct ieee802
- if (priv->usb_interrupts)
- rtl8xxxu_write32(priv, REG_USB_HIMR, 0);
-
-+ cancel_work_sync(&priv->c2hcmd_work);
- cancel_delayed_work_sync(&priv->ra_watchdog);
-
- rtl8xxxu_free_rx_resources(priv);
+++ /dev/null
-From ece90a8622320bf5a24d3326da1f8e109891573c Mon Sep 17 00:00:00 2001
-From: Martin Kaistra <martin.kaistra@linutronix.de>
-Date: Thu, 11 Jan 2024 17:36:28 +0100
-Subject: [PATCH 2/2] wifi: rtl8xxxu: enable channel switch support
-
-The CSA countdown in the beacon frames, which are sent out by firmware,
-needs to get updated by the driver. To achieve this, convert
-update_beacon_work to delayed_work and schedule it with the beacon
-interval in case CSA is active and the countdown is not complete.
-
-Signed-off-by: Martin Kaistra <martin.kaistra@linutronix.de>
-Reviewed-by: Ping-Ke Shih <pkshih@realtek.com>
-Signed-off-by: Kalle Valo <kvalo@kernel.org>
-Link: https://msgid.link/20240111163628.320697-3-martin.kaistra@linutronix.de
----
- .../net/wireless/realtek/rtl8xxxu/rtl8xxxu.h | 2 +-
- .../wireless/realtek/rtl8xxxu/rtl8xxxu_core.c | 19 +++++++++++++++----
- 2 files changed, 16 insertions(+), 5 deletions(-)
-
---- a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu.h
-+++ b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu.h
-@@ -1900,7 +1900,7 @@ struct rtl8xxxu_priv {
- struct delayed_work ra_watchdog;
- struct work_struct c2hcmd_work;
- struct sk_buff_head c2hcmd_queue;
-- struct work_struct update_beacon_work;
-+ struct delayed_work update_beacon_work;
- struct rtl8xxxu_btcoex bt_coex;
- struct rtl8xxxu_ra_report ra_report;
- struct rtl8xxxu_cfo_tracking cfo_tracking;
---- a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c
-+++ b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c
-@@ -4605,7 +4605,7 @@ static int rtl8xxxu_set_tim(struct ieee8
- {
- struct rtl8xxxu_priv *priv = hw->priv;
-
-- schedule_work(&priv->update_beacon_work);
-+ schedule_delayed_work(&priv->update_beacon_work, 0);
-
- return 0;
- }
-@@ -5107,7 +5107,7 @@ rtl8xxxu_bss_info_changed(struct ieee802
- }
-
- if (changed & BSS_CHANGED_BEACON)
-- schedule_work(&priv->update_beacon_work);
-+ schedule_delayed_work(&priv->update_beacon_work, 0);
-
- error:
- return;
-@@ -5726,7 +5726,7 @@ static void rtl8xxxu_send_beacon_frame(s
- static void rtl8xxxu_update_beacon_work_callback(struct work_struct *work)
- {
- struct rtl8xxxu_priv *priv =
-- container_of(work, struct rtl8xxxu_priv, update_beacon_work);
-+ container_of(work, struct rtl8xxxu_priv, update_beacon_work.work);
- struct ieee80211_hw *hw = priv->hw;
- struct ieee80211_vif *vif = priv->vifs[0];
-
-@@ -5735,6 +5735,14 @@ static void rtl8xxxu_update_beacon_work_
- return;
- }
-
-+ if (vif->bss_conf.csa_active) {
-+ if (ieee80211_beacon_cntdwn_is_complete(vif)) {
-+ ieee80211_csa_finish(vif);
-+ return;
-+ }
-+ schedule_delayed_work(&priv->update_beacon_work,
-+ msecs_to_jiffies(vif->bss_conf.beacon_int));
-+ }
- rtl8xxxu_send_beacon_frame(hw, vif);
- }
-
-@@ -7482,6 +7490,7 @@ static void rtl8xxxu_stop(struct ieee802
-
- cancel_work_sync(&priv->c2hcmd_work);
- cancel_delayed_work_sync(&priv->ra_watchdog);
-+ cancel_delayed_work_sync(&priv->update_beacon_work);
-
- rtl8xxxu_free_rx_resources(priv);
- rtl8xxxu_free_tx_resources(priv);
-@@ -7763,7 +7772,7 @@ static int rtl8xxxu_probe(struct usb_int
- spin_lock_init(&priv->rx_urb_lock);
- INIT_WORK(&priv->rx_urb_wq, rtl8xxxu_rx_urb_work);
- INIT_DELAYED_WORK(&priv->ra_watchdog, rtl8xxxu_watchdog_callback);
-- INIT_WORK(&priv->update_beacon_work, rtl8xxxu_update_beacon_work_callback);
-+ INIT_DELAYED_WORK(&priv->update_beacon_work, rtl8xxxu_update_beacon_work_callback);
- skb_queue_head_init(&priv->c2hcmd_queue);
-
- usb_set_intfdata(interface, hw);
-@@ -7824,6 +7833,8 @@ static int rtl8xxxu_probe(struct usb_int
- hw->wiphy->interface_modes |= BIT(NL80211_IFTYPE_AP);
- hw->queues = 4;
-
-+ hw->wiphy->flags |= WIPHY_FLAG_HAS_CHANNEL_SWITCH;
-+
- if (priv->fops->supports_concurrent) {
- hw->wiphy->iface_combinations = rtl8xxxu_combinations;
- hw->wiphy->n_iface_combinations = ARRAY_SIZE(rtl8xxxu_combinations);
+++ /dev/null
-From 426e7b4773921d07ab4ab8ba16fbad396d6c9971 Mon Sep 17 00:00:00 2001
-From: Ping-Ke Shih <pkshih@realtek.com>
-Date: Tue, 16 Jan 2024 16:09:44 +0800
-Subject: [PATCH 1/2] wifi: rtl8xxxu: convert EN_DESC_ID of TX descriptor to
- le32 type
-
-Fields of TX descriptor are little-endian order, so correct EN_DESC_ID
-field to le32 type.
-
-Fixes: b837f78fbffa ("wifi: rtl8xxxu: add hw crypto support for AP mode")
-Reported-by: kernel test robot <lkp@intel.com>
-Closes: https://lore.kernel.org/oe-kbuild-all/202401161318.YtXoCkjU-lkp@intel.com/
-Cc: Martin Kaistra <martin.kaistra@linutronix.de>
-Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
-Signed-off-by: Kalle Valo <kvalo@kernel.org>
-Link: https://msgid.link/20240116080945.20172-1-pkshih@realtek.com
----
- drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
---- a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c
-+++ b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c
-@@ -5619,7 +5619,7 @@ static void rtl8xxxu_tx(struct ieee80211
- break;
- }
- if (bmc && rtlvif->hw_key_idx != 0xff) {
-- tx_desc->txdw1 |= TXDESC_EN_DESC_ID;
-+ tx_desc->txdw1 |= cpu_to_le32(TXDESC_EN_DESC_ID);
- macid = rtlvif->hw_key_idx;
- }
- }
+++ /dev/null
-From 92c7428f942da7dfcdc629b05b5114f80822d7a4 Mon Sep 17 00:00:00 2001
-From: Ping-Ke Shih <pkshih@realtek.com>
-Date: Tue, 16 Jan 2024 16:09:45 +0800
-Subject: [PATCH 2/2] wifi: rtl8xxxu: make instances of iface limit and
- combination to be static const
-
-rtl8xxxu_limits and rtl8xxxu_combinations can be static const, so add
-modifiers as desire. Otherwise, Sparse reports warnings
-
-rtl8xxxu_core.c:7677:30: warning: symbol 'rtl8xxxu_limits' was not declared. Should it be static?
-rtl8xxxu_core.c:7682:36: warning: symbol 'rtl8xxxu_combinations' was not declared. Should it be static?
-
-Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
-Signed-off-by: Kalle Valo <kvalo@kernel.org>
-Link: https://msgid.link/20240116080945.20172-2-pkshih@realtek.com
----
- drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c | 4 ++--
- 1 file changed, 2 insertions(+), 2 deletions(-)
-
---- a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c
-+++ b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c
-@@ -7674,12 +7674,12 @@ static void rtl8xxxu_deinit_led(struct r
- led_classdev_unregister(led);
- }
-
--struct ieee80211_iface_limit rtl8xxxu_limits[] = {
-+static const struct ieee80211_iface_limit rtl8xxxu_limits[] = {
- { .max = 2, .types = BIT(NL80211_IFTYPE_STATION), },
- { .max = 1, .types = BIT(NL80211_IFTYPE_AP), },
- };
-
--struct ieee80211_iface_combination rtl8xxxu_combinations[] = {
-+static const struct ieee80211_iface_combination rtl8xxxu_combinations[] = {
- {
- .limits = rtl8xxxu_limits,
- .n_limits = ARRAY_SIZE(rtl8xxxu_limits),
+++ /dev/null
-From 563d5025cf3b51c7bf20e6966af433ed5f838875 Mon Sep 17 00:00:00 2001
-From: Martin Kaistra <martin.kaistra@linutronix.de>
-Date: Tue, 16 Jan 2024 10:50:01 +0100
-Subject: [PATCH] wifi: rtl8xxxu: add missing number of sec cam entries for all
- variants
-
-Commit b837f78fbffa ("wifi: rtl8xxxu: add hw crypto support for AP
-mode") introduced max_sec_cam_num as a member of rtl8xxxu_fileops.
-It was missed to set this number for all variants except 8188f, which
-caused rtl8xxxu_get_free_sec_cam() to always return 0 and therefore breaking
-encrypted traffic.
-
-Fix it by adding the numbers for all variants. The values are taken from
-the vendor drivers and rtlwifi.
-
-Link: https://lore.kernel.org/linux-wireless/20240111163603.2325-1-zenmchen@gmail.com/
-Fixes: b837f78fbffa ("wifi: rtl8xxxu: add hw crypto support for AP mode")
-Signed-off-by: Martin Kaistra <martin.kaistra@linutronix.de>
-Signed-off-by: Kalle Valo <kvalo@kernel.org>
-Link: https://msgid.link/20240116095001.399500-1-martin.kaistra@linutronix.de
----
- drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_8188e.c | 1 +
- drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_8192c.c | 1 +
- drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_8192e.c | 1 +
- drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_8192f.c | 1 +
- drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_8710b.c | 1 +
- drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_8723a.c | 1 +
- drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_8723b.c | 1 +
- 7 files changed, 7 insertions(+)
-
---- a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_8188e.c
-+++ b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_8188e.c
-@@ -1882,6 +1882,7 @@ struct rtl8xxxu_fileops rtl8188eu_fops =
- .has_tx_report = 1,
- .init_reg_pkt_life_time = 1,
- .gen2_thermal_meter = 1,
-+ .max_sec_cam_num = 32,
- .adda_1t_init = 0x0b1b25a0,
- .adda_1t_path_on = 0x0bdb25a0,
- /*
---- a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_8192c.c
-+++ b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_8192c.c
-@@ -613,6 +613,7 @@ struct rtl8xxxu_fileops rtl8192cu_fops =
- .rx_agg_buf_size = 16000,
- .tx_desc_size = sizeof(struct rtl8xxxu_txdesc32),
- .rx_desc_size = sizeof(struct rtl8xxxu_rxdesc16),
-+ .max_sec_cam_num = 32,
- .adda_1t_init = 0x0b1b25a0,
- .adda_1t_path_on = 0x0bdb25a0,
- .adda_2t_path_on_a = 0x04db25a4,
---- a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_8192e.c
-+++ b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_8192e.c
-@@ -1769,6 +1769,7 @@ struct rtl8xxxu_fileops rtl8192eu_fops =
- .needs_full_init = 1,
- .supports_ap = 1,
- .max_macid_num = 128,
-+ .max_sec_cam_num = 64,
- .adda_1t_init = 0x0fc01616,
- .adda_1t_path_on = 0x0fc01616,
- .adda_2t_path_on_a = 0x0fc01616,
---- a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_8192f.c
-+++ b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_8192f.c
-@@ -2095,6 +2095,7 @@ struct rtl8xxxu_fileops rtl8192fu_fops =
- .max_aggr_num = 0x1f1f,
- .supports_ap = 1,
- .max_macid_num = 128,
-+ .max_sec_cam_num = 64,
- .trxff_boundary = 0x3f3f,
- .pbp_rx = PBP_PAGE_SIZE_256,
- .pbp_tx = PBP_PAGE_SIZE_256,
---- a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_8710b.c
-+++ b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_8710b.c
-@@ -1877,6 +1877,7 @@ struct rtl8xxxu_fileops rtl8710bu_fops =
- .max_aggr_num = 0x0c14,
- .supports_ap = 1,
- .max_macid_num = 16,
-+ .max_sec_cam_num = 32,
- .adda_1t_init = 0x03c00016,
- .adda_1t_path_on = 0x03c00016,
- .trxff_boundary = 0x3f7f,
---- a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_8723a.c
-+++ b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_8723a.c
-@@ -510,6 +510,7 @@ struct rtl8xxxu_fileops rtl8723au_fops =
- .rx_agg_buf_size = 16000,
- .tx_desc_size = sizeof(struct rtl8xxxu_txdesc32),
- .rx_desc_size = sizeof(struct rtl8xxxu_rxdesc16),
-+ .max_sec_cam_num = 32,
- .adda_1t_init = 0x0b1b25a0,
- .adda_1t_path_on = 0x0bdb25a0,
- .adda_2t_path_on_a = 0x04db25a4,
---- a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_8723b.c
-+++ b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_8723b.c
-@@ -1744,6 +1744,7 @@ struct rtl8xxxu_fileops rtl8723bu_fops =
- .max_aggr_num = 0x0c14,
- .supports_ap = 1,
- .max_macid_num = 128,
-+ .max_sec_cam_num = 64,
- .adda_1t_init = 0x01c00014,
- .adda_1t_path_on = 0x01c00014,
- .adda_2t_path_on_a = 0x01c00014,
+++ /dev/null
-From 17903a283593c1dbf9da041f836004163ca30f7b Mon Sep 17 00:00:00 2001
-From: Dan Carpenter <dan.carpenter@linaro.org>
-Date: Wed, 31 Jan 2024 10:10:07 +0300
-Subject: [PATCH] wifi: rtl8xxxu: fix error messages
-
-The first parameter of WARN_ONCE() is a condition so this code will end
-up printing the function name instead of the proper message.
-
-Fixes: 3ff7a05996f9 ("wifi: rtl8xxxu: support setting bssid register for multiple interfaces")
-Signed-off-by: Dan Carpenter <dan.carpenter@linaro.org>
-Reviewed-by: Ping-Ke Shih <pkshih@realtek.com>
-Signed-off-by: Kalle Valo <kvalo@kernel.org>
-Link: https://msgid.link/7b144531-a8da-4725-8911-9b614a525a35@moroto.mountain
----
- drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c | 4 ++--
- 1 file changed, 2 insertions(+), 2 deletions(-)
-
---- a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c
-+++ b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c
-@@ -3593,7 +3593,7 @@ static int rtl8xxxu_set_mac(struct rtl8x
- reg = REG_MACID1;
- break;
- default:
-- WARN_ONCE("%s: invalid port_num\n", __func__);
-+ WARN_ONCE(1, "%s: invalid port_num\n", __func__);
- return -EINVAL;
- }
-
-@@ -3618,7 +3618,7 @@ static int rtl8xxxu_set_bssid(struct rtl
- reg = REG_BSSID1;
- break;
- default:
-- WARN_ONCE("%s: invalid port_num\n", __func__);
-+ WARN_ONCE(1, "%s: invalid port_num\n", __func__);
- return -EINVAL;
- }
-
+++ /dev/null
-From 1209f487d452ff7e822dec30661fd6b5163fb8cf Mon Sep 17 00:00:00 2001
-From: Chun Qiu <cqca@cock.lu>
-Date: Mon, 29 Jan 2024 13:30:30 +0800
-Subject: [PATCH] wifi: rtl8xxxu: Add TP-Link TL-WN823N V2
-
-TP-Link TL-WN823N V2 (2357:0135) is based on rtl8192fu and has been
-tested to work with the rtl8xxxu driver.
-
-Signed-off-by: Chun Qiu <cqca@cock.lu>
-Signed-off-by: Kalle Valo <kvalo@kernel.org>
-Link: https://msgid.link/20240129053030.16369-1-cqca@cock.lu
----
- drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c | 5 ++++-
- 1 file changed, 4 insertions(+), 1 deletion(-)
-
---- a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c
-+++ b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c
-@@ -7733,7 +7733,7 @@ static int rtl8xxxu_probe(struct usb_int
- untested = 0;
- break;
- case 0x2357:
-- if (id->idProduct == 0x0109)
-+ if (id->idProduct == 0x0109 || id->idProduct == 0x0135)
- untested = 0;
- break;
- case 0x0b05:
-@@ -8025,6 +8025,9 @@ static const struct usb_device_id dev_ta
- .driver_info = (unsigned long)&rtl8192fu_fops},
- {USB_DEVICE_AND_INTERFACE_INFO(USB_VENDOR_ID_REALTEK, 0x318b, 0xff, 0xff, 0xff),
- .driver_info = (unsigned long)&rtl8192fu_fops},
-+/* TP-Link TL-WN823N V2 */
-+{USB_DEVICE_AND_INTERFACE_INFO(0x2357, 0x0135, 0xff, 0xff, 0xff),
-+ .driver_info = (unsigned long)&rtl8192fu_fops},
- #ifdef CPTCFG_RTL8XXXU_UNTESTED
- /* Still supported by rtlwifi */
- {USB_DEVICE_AND_INTERFACE_INFO(USB_VENDOR_ID_REALTEK, 0x8176, 0xff, 0xff, 0xff),
+++ /dev/null
-From 94dd7ce1885e530a7b10bbe50d5d68ba1bb99e6e Mon Sep 17 00:00:00 2001
-From: Martin Kaistra <martin.kaistra@linutronix.de>
-Date: Mon, 5 Feb 2024 10:30:40 +0100
-Subject: [PATCH] wifi: rtl8xxxu: update rate mask per sta
-
-Until now, rtl8xxxu_watchdog_callback() only fetches RSSI and updates
-the rate mask in station mode. This means, in AP mode only the default
-rate mask is used.
-
-In order to have the rate mask reflect the actual connection quality,
-extend rtl8xxxu_watchdog_callback() to iterate over every sta. Like in
-the rtw88 driver, add a function to collect all currently present stas
-and then iterate over a list of copies to ensure no RCU lock problems
-for register access via USB. Remove the existing RCU lock in
-rtl8xxxu_refresh_rate_mask().
-
-Since the currently used ieee80211_ave_rssi() is only for 'vif', add
-driver-level tracking of RSSI per sta.
-
-Signed-off-by: Martin Kaistra <martin.kaistra@linutronix.de>
-Reviewed-by: Ping-Ke Shih <pkshih@realtek.com>
-Signed-off-by: Kalle Valo <kvalo@kernel.org>
-Link: https://msgid.link/20240205093040.1941140-1-martin.kaistra@linutronix.de
----
- .../net/wireless/realtek/rtl8xxxu/rtl8xxxu.h | 8 +-
- .../wireless/realtek/rtl8xxxu/rtl8xxxu_core.c | 188 ++++++++++++++----
- 2 files changed, 158 insertions(+), 38 deletions(-)
-
---- a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu.h
-+++ b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu.h
-@@ -6,6 +6,7 @@
- */
-
- #include <asm/byteorder.h>
-+#include <linux/average.h>
-
- #define RTL8XXXU_DEBUG_REG_WRITE 0x01
- #define RTL8XXXU_DEBUG_REG_READ 0x02
-@@ -1858,6 +1859,8 @@ struct rtl8xxxu_priv {
- int next_mbox;
- int nr_out_eps;
-
-+ /* Ensure no added or deleted stas while iterating */
-+ struct mutex sta_mutex;
- struct mutex h2c_mutex;
- /* Protect the indirect register accesses of RTL8710BU. */
- struct mutex syson_indirect_access_mutex;
-@@ -1892,7 +1895,6 @@ struct rtl8xxxu_priv {
- u8 pi_enabled:1;
- u8 no_pape:1;
- u8 int_buf[USB_INTR_CONTENT_LENGTH];
-- u8 rssi_level;
- DECLARE_BITMAP(tx_aggr_started, IEEE80211_NUM_TIDS);
- DECLARE_BITMAP(tid_tx_operational, IEEE80211_NUM_TIDS);
-
-@@ -1913,11 +1915,15 @@ struct rtl8xxxu_priv {
- DECLARE_BITMAP(cam_map, RTL8XXXU_MAX_SEC_CAM_NUM);
- };
-
-+DECLARE_EWMA(rssi, 10, 16);
-+
- struct rtl8xxxu_sta_info {
- struct ieee80211_sta *sta;
- struct ieee80211_vif *vif;
-
- u8 macid;
-+ struct ewma_rssi avg_rssi;
-+ u8 rssi_level;
- };
-
- struct rtl8xxxu_vif {
---- a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c
-+++ b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c
-@@ -4991,10 +4991,11 @@ rtl8xxxu_bss_info_changed(struct ieee802
- struct rtl8xxxu_vif *rtlvif = (struct rtl8xxxu_vif *)vif->drv_priv;
- struct rtl8xxxu_priv *priv = hw->priv;
- struct device *dev = &priv->udev->dev;
-+ struct rtl8xxxu_sta_info *sta_info;
- struct ieee80211_sta *sta;
- struct rtl8xxxu_ra_report *rarpt;
-+ u8 val8, macid;
- u32 val32;
-- u8 val8;
-
- rarpt = &priv->ra_report;
-
-@@ -5017,6 +5018,7 @@ rtl8xxxu_bss_info_changed(struct ieee802
- rcu_read_unlock();
- goto error;
- }
-+ macid = rtl8xxxu_get_macid(priv, sta);
-
- if (sta->deflink.ht_cap.ht_supported)
- dev_info(dev, "%s: HT supported\n", __func__);
-@@ -5037,14 +5039,15 @@ rtl8xxxu_bss_info_changed(struct ieee802
- bw = RATE_INFO_BW_40;
- else
- bw = RATE_INFO_BW_20;
-+
-+ sta_info = (struct rtl8xxxu_sta_info *)sta->drv_priv;
-+ sta_info->rssi_level = RTL8XXXU_RATR_STA_INIT;
- rcu_read_unlock();
-
- rtl8xxxu_update_ra_report(rarpt, highest_rate, sgi, bw);
-
-- priv->rssi_level = RTL8XXXU_RATR_STA_INIT;
--
- priv->fops->update_rate_mask(priv, ramask, 0, sgi,
-- bw == RATE_INFO_BW_40, 0);
-+ bw == RATE_INFO_BW_40, macid);
-
- rtl8xxxu_write8(priv, REG_BCN_MAX_ERR, 0xff);
-
-@@ -6317,6 +6320,76 @@ static void rtl8188e_c2hcmd_callback(str
- }
- }
-
-+#define rtl8xxxu_iterate_vifs_atomic(priv, iterator, data) \
-+ ieee80211_iterate_active_interfaces_atomic((priv)->hw, \
-+ IEEE80211_IFACE_ITER_NORMAL, iterator, data)
-+
-+struct rtl8xxxu_rx_update_rssi_data {
-+ struct rtl8xxxu_priv *priv;
-+ struct ieee80211_hdr *hdr;
-+ struct ieee80211_rx_status *rx_status;
-+ u8 *bssid;
-+};
-+
-+static void rtl8xxxu_rx_update_rssi_iter(void *data, u8 *mac,
-+ struct ieee80211_vif *vif)
-+{
-+ struct rtl8xxxu_rx_update_rssi_data *iter_data = data;
-+ struct ieee80211_sta *sta;
-+ struct ieee80211_hdr *hdr = iter_data->hdr;
-+ struct rtl8xxxu_priv *priv = iter_data->priv;
-+ struct rtl8xxxu_sta_info *sta_info;
-+ struct ieee80211_rx_status *rx_status = iter_data->rx_status;
-+ u8 *bssid = iter_data->bssid;
-+
-+ if (!ether_addr_equal(vif->bss_conf.bssid, bssid))
-+ return;
-+
-+ if (!(ether_addr_equal(vif->addr, hdr->addr1) ||
-+ ieee80211_is_beacon(hdr->frame_control)))
-+ return;
-+
-+ sta = ieee80211_find_sta_by_ifaddr(priv->hw, hdr->addr2,
-+ vif->addr);
-+ if (!sta)
-+ return;
-+
-+ sta_info = (struct rtl8xxxu_sta_info *)sta->drv_priv;
-+ ewma_rssi_add(&sta_info->avg_rssi, -rx_status->signal);
-+}
-+
-+static inline u8 *get_hdr_bssid(struct ieee80211_hdr *hdr)
-+{
-+ __le16 fc = hdr->frame_control;
-+ u8 *bssid;
-+
-+ if (ieee80211_has_tods(fc))
-+ bssid = hdr->addr1;
-+ else if (ieee80211_has_fromds(fc))
-+ bssid = hdr->addr2;
-+ else
-+ bssid = hdr->addr3;
-+
-+ return bssid;
-+}
-+
-+static void rtl8xxxu_rx_update_rssi(struct rtl8xxxu_priv *priv,
-+ struct ieee80211_rx_status *rx_status,
-+ struct ieee80211_hdr *hdr)
-+{
-+ struct rtl8xxxu_rx_update_rssi_data data = {};
-+
-+ if (ieee80211_is_ctl(hdr->frame_control))
-+ return;
-+
-+ data.priv = priv;
-+ data.hdr = hdr;
-+ data.rx_status = rx_status;
-+ data.bssid = get_hdr_bssid(hdr);
-+
-+ rtl8xxxu_iterate_vifs_atomic(priv, rtl8xxxu_rx_update_rssi_iter, &data);
-+}
-+
- int rtl8xxxu_parse_rxdesc16(struct rtl8xxxu_priv *priv, struct sk_buff *skb)
- {
- struct ieee80211_hw *hw = priv->hw;
-@@ -6376,18 +6449,26 @@ int rtl8xxxu_parse_rxdesc16(struct rtl8x
- skb_queue_tail(&priv->c2hcmd_queue, skb);
- schedule_work(&priv->c2hcmd_work);
- } else {
-+ struct ieee80211_hdr *hdr;
-+
- phy_stats = (struct rtl8723au_phy_stats *)skb->data;
-
- skb_pull(skb, drvinfo_sz + desc_shift);
-
- skb_trim(skb, pkt_len);
-
-- if (rx_desc->phy_stats)
-+ hdr = (struct ieee80211_hdr *)skb->data;
-+ if (rx_desc->phy_stats) {
- priv->fops->parse_phystats(
- priv, rx_status, phy_stats,
- rx_desc->rxmcs,
-- (struct ieee80211_hdr *)skb->data,
-+ hdr,
- rx_desc->crc32 || rx_desc->icverr);
-+ if (!rx_desc->crc32 && !rx_desc->icverr)
-+ rtl8xxxu_rx_update_rssi(priv,
-+ rx_status,
-+ hdr);
-+ }
-
- rx_status->mactime = rx_desc->tsfl;
- rx_status->flag |= RX_FLAG_MACTIME_START;
-@@ -6484,10 +6565,15 @@ int rtl8xxxu_parse_rxdesc24(struct rtl8x
- } else {
- struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
-
-- if (rx_desc->phy_stats)
-+ if (rx_desc->phy_stats) {
- priv->fops->parse_phystats(priv, rx_status, phy_stats,
- rx_desc->rxmcs, hdr,
- rx_desc->crc32 || rx_desc->icverr);
-+ if (!rx_desc->crc32 && !rx_desc->icverr)
-+ rtl8xxxu_rx_update_rssi(priv,
-+ rx_status,
-+ hdr);
-+ }
-
- rx_status->mactime = rx_desc->tsfl;
- rx_status->flag |= RX_FLAG_MACTIME_START;
-@@ -7111,6 +7197,7 @@ static void rtl8xxxu_refresh_rate_mask(s
- int signal, struct ieee80211_sta *sta,
- bool force)
- {
-+ struct rtl8xxxu_sta_info *sta_info = (struct rtl8xxxu_sta_info *)sta->drv_priv;
- struct ieee80211_hw *hw = priv->hw;
- u16 wireless_mode;
- u8 rssi_level, ratr_idx;
-@@ -7119,7 +7206,7 @@ static void rtl8xxxu_refresh_rate_mask(s
- u8 go_up_gap = 5;
- u8 macid = rtl8xxxu_get_macid(priv, sta);
-
-- rssi_level = priv->rssi_level;
-+ rssi_level = sta_info->rssi_level;
- snr = rtl8xxxu_signal_to_snr(signal);
- snr_thresh_high = RTL8XXXU_SNR_THRESH_HIGH;
- snr_thresh_low = RTL8XXXU_SNR_THRESH_LOW;
-@@ -7144,18 +7231,16 @@ static void rtl8xxxu_refresh_rate_mask(s
- else
- rssi_level = RTL8XXXU_RATR_STA_LOW;
-
-- if (rssi_level != priv->rssi_level || force) {
-+ if (rssi_level != sta_info->rssi_level || force) {
- int sgi = 0;
- u32 rate_bitmap = 0;
-
-- rcu_read_lock();
- rate_bitmap = (sta->deflink.supp_rates[0] & 0xfff) |
- (sta->deflink.ht_cap.mcs.rx_mask[0] << 12) |
- (sta->deflink.ht_cap.mcs.rx_mask[1] << 20);
- if (sta->deflink.ht_cap.cap &
- (IEEE80211_HT_CAP_SGI_40 | IEEE80211_HT_CAP_SGI_20))
- sgi = 1;
-- rcu_read_unlock();
-
- wireless_mode = rtl8xxxu_wireless_mode(hw, sta);
- switch (wireless_mode) {
-@@ -7236,7 +7321,7 @@ static void rtl8xxxu_refresh_rate_mask(s
- break;
- }
-
-- priv->rssi_level = rssi_level;
-+ sta_info->rssi_level = rssi_level;
- priv->fops->update_rate_mask(priv, rate_bitmap, ratr_idx, sgi, txbw_40mhz, macid);
- }
- }
-@@ -7329,40 +7414,60 @@ static void rtl8xxxu_track_cfo(struct rt
- rtl8xxxu_set_atc_status(priv, abs(cfo_average) >= CFO_TH_ATC);
- }
-
--static void rtl8xxxu_watchdog_callback(struct work_struct *work)
-+static void rtl8xxxu_ra_iter(void *data, struct ieee80211_sta *sta)
- {
-- struct ieee80211_vif *vif;
-- struct rtl8xxxu_priv *priv;
-- int i;
-+ struct rtl8xxxu_sta_info *sta_info = (struct rtl8xxxu_sta_info *)sta->drv_priv;
-+ struct rtl8xxxu_priv *priv = data;
-+ int signal = -ewma_rssi_read(&sta_info->avg_rssi);
-
-- priv = container_of(work, struct rtl8xxxu_priv, ra_watchdog.work);
-- for (i = 0; i < ARRAY_SIZE(priv->vifs); i++) {
-- vif = priv->vifs[i];
-+ priv->fops->report_rssi(priv, rtl8xxxu_get_macid(priv, sta),
-+ rtl8xxxu_signal_to_snr(signal));
-+ rtl8xxxu_refresh_rate_mask(priv, signal, sta, false);
-+}
-+
-+struct rtl8xxxu_stas_entry {
-+ struct list_head list;
-+ struct ieee80211_sta *sta;
-+};
-
-- if (!vif || vif->type != NL80211_IFTYPE_STATION)
-- continue;
-+struct rtl8xxxu_iter_stas_data {
-+ struct rtl8xxxu_priv *priv;
-+ struct list_head list;
-+};
-
-- int signal;
-- struct ieee80211_sta *sta;
-+static void rtl8xxxu_collect_sta_iter(void *data, struct ieee80211_sta *sta)
-+{
-+ struct rtl8xxxu_iter_stas_data *iter_stas = data;
-+ struct rtl8xxxu_stas_entry *stas_entry;
-
-- rcu_read_lock();
-- sta = ieee80211_find_sta(vif, vif->bss_conf.bssid);
-- if (!sta) {
-- struct device *dev = &priv->udev->dev;
-+ stas_entry = kmalloc(sizeof(*stas_entry), GFP_ATOMIC);
-+ if (!stas_entry)
-+ return;
-
-- dev_dbg(dev, "%s: no sta found\n", __func__);
-- rcu_read_unlock();
-- continue;
-- }
-- rcu_read_unlock();
-+ stas_entry->sta = sta;
-+ list_add_tail(&stas_entry->list, &iter_stas->list);
-+}
-
-- signal = ieee80211_ave_rssi(vif);
-+static void rtl8xxxu_watchdog_callback(struct work_struct *work)
-+{
-
-- priv->fops->report_rssi(priv, rtl8xxxu_get_macid(priv, sta),
-- rtl8xxxu_signal_to_snr(signal));
-+ struct rtl8xxxu_iter_stas_data iter_data;
-+ struct rtl8xxxu_stas_entry *sta_entry, *tmp;
-+ struct rtl8xxxu_priv *priv;
-
-- rtl8xxxu_refresh_rate_mask(priv, signal, sta, false);
-+ priv = container_of(work, struct rtl8xxxu_priv, ra_watchdog.work);
-+ iter_data.priv = priv;
-+ INIT_LIST_HEAD(&iter_data.list);
-+
-+ mutex_lock(&priv->sta_mutex);
-+ ieee80211_iterate_stations_atomic(priv->hw, rtl8xxxu_collect_sta_iter,
-+ &iter_data);
-+ list_for_each_entry_safe(sta_entry, tmp, &iter_data.list, list) {
-+ list_del_init(&sta_entry->list);
-+ rtl8xxxu_ra_iter(priv, sta_entry->sta);
-+ kfree(sta_entry);
- }
-+ mutex_unlock(&priv->sta_mutex);
-
- if (priv->fops->set_crystal_cap)
- rtl8xxxu_track_cfo(priv);
-@@ -7504,10 +7609,15 @@ static int rtl8xxxu_sta_add(struct ieee8
- struct rtl8xxxu_vif *rtlvif = (struct rtl8xxxu_vif *)vif->drv_priv;
- struct rtl8xxxu_priv *priv = hw->priv;
-
-+ mutex_lock(&priv->sta_mutex);
-+ ewma_rssi_init(&sta_info->avg_rssi);
- if (vif->type == NL80211_IFTYPE_AP) {
-+ sta_info->rssi_level = RTL8XXXU_RATR_STA_INIT;
- sta_info->macid = rtl8xxxu_acquire_macid(priv);
-- if (sta_info->macid >= RTL8XXXU_MAX_MAC_ID_NUM)
-+ if (sta_info->macid >= RTL8XXXU_MAX_MAC_ID_NUM) {
-+ mutex_unlock(&priv->sta_mutex);
- return -ENOSPC;
-+ }
-
- rtl8xxxu_refresh_rate_mask(priv, 0, sta, true);
- priv->fops->report_connect(priv, sta_info->macid, H2C_MACID_ROLE_STA, true);
-@@ -7523,6 +7633,7 @@ static int rtl8xxxu_sta_add(struct ieee8
- break;
- }
- }
-+ mutex_unlock(&priv->sta_mutex);
-
- return 0;
- }
-@@ -7534,8 +7645,10 @@ static int rtl8xxxu_sta_remove(struct ie
- struct rtl8xxxu_sta_info *sta_info = (struct rtl8xxxu_sta_info *)sta->drv_priv;
- struct rtl8xxxu_priv *priv = hw->priv;
-
-+ mutex_lock(&priv->sta_mutex);
- if (vif->type == NL80211_IFTYPE_AP)
- rtl8xxxu_release_macid(priv, sta_info->macid);
-+ mutex_unlock(&priv->sta_mutex);
-
- return 0;
- }
-@@ -7766,6 +7879,7 @@ static int rtl8xxxu_probe(struct usb_int
- mutex_init(&priv->usb_buf_mutex);
- mutex_init(&priv->syson_indirect_access_mutex);
- mutex_init(&priv->h2c_mutex);
-+ mutex_init(&priv->sta_mutex);
- INIT_LIST_HEAD(&priv->tx_urb_free_list);
- spin_lock_init(&priv->tx_urb_lock);
- INIT_LIST_HEAD(&priv->rx_urb_pending_list);
+++ /dev/null
-From 513c559ca9f05394da79fbf20a8f89eec5f53dce Mon Sep 17 00:00:00 2001
-From: Ping-Ke Shih <pkshih@realtek.com>
-Date: Fri, 16 Feb 2024 11:39:23 +0800
-Subject: [PATCH] wifi: rtl8xxxu: check vif before using in rtl8xxxu_tx()
-
-The 'vif' is from tx_info of SKB, and other codes check 'vif' before using,
-which raises smatch warnings:
-
-drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c:5656 rtl8xxxu_tx()
- warn: variable dereferenced before check 'vif' (see line 5553)
-
-Compile tested only.
-
-Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
-Signed-off-by: Kalle Valo <kvalo@kernel.org>
-Link: https://msgid.link/20240216033923.34683-1-pkshih@realtek.com
----
- drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c | 4 ++--
- 1 file changed, 2 insertions(+), 2 deletions(-)
-
---- a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c
-+++ b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c
-@@ -5550,7 +5550,7 @@ static void rtl8xxxu_tx(struct ieee80211
- struct rtl8xxxu_tx_urb *tx_urb;
- struct ieee80211_sta *sta = NULL;
- struct ieee80211_vif *vif = tx_info->control.vif;
-- struct rtl8xxxu_vif *rtlvif = (struct rtl8xxxu_vif *)vif->drv_priv;
-+ struct rtl8xxxu_vif *rtlvif = vif ? (struct rtl8xxxu_vif *)vif->drv_priv : NULL;
- struct device *dev = &priv->udev->dev;
- u32 queue, rts_rate;
- u16 pktlen = skb->len;
-@@ -5621,7 +5621,7 @@ static void rtl8xxxu_tx(struct ieee80211
- default:
- break;
- }
-- if (bmc && rtlvif->hw_key_idx != 0xff) {
-+ if (bmc && rtlvif && rtlvif->hw_key_idx != 0xff) {
- tx_desc->txdw1 |= cpu_to_le32(TXDESC_EN_DESC_ID);
- macid = rtlvif->hw_key_idx;
- }
+++ /dev/null
-From a7e178259c5bc900da762b33d3a20b7ee1206f07 Mon Sep 17 00:00:00 2001
-From: Shiji Yang <yangshiji66@outlook.com>
-Date: Fri, 23 Feb 2024 21:34:32 +0800
-Subject: [PATCH] wifi: rtl8xxxu: fix mixed declarations in rtl8xxxu_set_aifs()
-
-Moving struct ieee80211_sta *sta variable definition to the front
-of the code to fix the ISO C90 forbids mixed declarations and code
-warning.
-
-Fixes: 43532c050f8e ("wifi: rtl8xxxu: support multiple interfaces in set_aifs()")
-Signed-off-by: Shiji Yang <yangshiji66@outlook.com>
-Reviewed-by: Ping-Ke Shih <pkshih@realtek.com>
-Signed-off-by: Kalle Valo <kvalo@kernel.org>
-Link: https://msgid.link/TYAP286MB03157A408E0D69F2F6FBD88ABC552@TYAP286MB0315.JPNP286.PROD.OUTLOOK.COM
----
- drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c | 4 ++--
- 1 file changed, 2 insertions(+), 2 deletions(-)
-
---- a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c
-+++ b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c
-@@ -4919,11 +4919,11 @@ static void rtl8xxxu_set_aifs(struct rtl
- int i;
-
- for (i = 0; i < ARRAY_SIZE(priv->vifs); i++) {
-+ struct ieee80211_sta *sta;
-+
- if (!priv->vifs[i])
- continue;
-
-- struct ieee80211_sta *sta;
--
- rcu_read_lock();
- sta = ieee80211_find_sta(priv->vifs[i], priv->vifs[i]->bss_conf.bssid);
- if (sta)
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
-@@ -1635,7 +1635,6 @@ static int ieee80211_stop_ap(struct wiph
- link_conf->bssid_indicator = 0;
+@@ -1647,12 +1647,6 @@ static int ieee80211_stop_ap(struct wiph
- __sta_info_flush(sdata, true);
-- ieee80211_free_keys(sdata, true);
+ __sta_info_flush(sdata, true, link_id);
+- ieee80211_remove_link_keys(link, &keys);
+- if (!list_empty(&keys)) {
+- synchronize_net();
+- ieee80211_free_key_list(local, &keys);
+- }
+-
link_conf->enable_beacon = false;
sdata->beacon_rate_set = false;
+ sdata->vif.cfg.ssid_len = 0;
--- a/net/mac80211/main.c
+++ b/net/mac80211/main.c
-@@ -1393,24 +1393,6 @@ int ieee80211_register_hw(struct ieee802
- debugfs_hw_add(local);
- rate_control_add_debugfs(local);
+@@ -1564,24 +1564,6 @@ int ieee80211_register_hw(struct ieee802
+
+ ieee80211_check_wbrf_support(local);
- rtnl_lock();
- wiphy_lock(hw->wiphy);
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
-@@ -2847,6 +2847,8 @@ static int ieee80211_scan(struct wiphy *
+@@ -2844,6 +2844,8 @@ static int ieee80211_scan(struct wiphy *
*/
fallthrough;
case NL80211_IFTYPE_AP:
--- a/net/mac80211/sta_info.c
+++ b/net/mac80211/sta_info.c
-@@ -561,6 +561,11 @@ __sta_info_alloc(struct ieee80211_sub_if
+@@ -565,6 +565,11 @@ __sta_info_alloc(struct ieee80211_sub_if
+ spin_lock_init(&sta->ps_lock);
INIT_WORK(&sta->drv_deliver_wk, sta_deliver_ps_frames);
- INIT_WORK(&sta->ampdu_mlme.work, ieee80211_ba_session_work);
- mutex_init(&sta->ampdu_mlme.mtx);
+ wiphy_work_init(&sta->ampdu_mlme.work, ieee80211_ba_session_work);
+#if LINUX_VERSION_IS_LESS(6,2,0)
+ sta->ampdu_mlme.dialog_token_allocator = prandom_u32_max(U8_MAX);
+#else
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
-@@ -92,6 +92,8 @@ extern const u8 ieee80211_ac_to_qos_mask
- */
- #define AIRTIME_ACTIVE_DURATION (HZ / 10)
+@@ -101,6 +101,8 @@ ieee80211_sta_keep_active(struct sta_inf
+ return time_before_eq(jiffies, sta->airtime[ac].last_active + HZ / 10);
+ }
+#define AIRTIME_QUANTUM_SHIFT 3
+
--- a/net/mac80211/tx.c
+++ b/net/mac80211/tx.c
-@@ -4060,7 +4060,7 @@ struct ieee80211_txq *ieee80211_next_txq
+@@ -4082,7 +4082,7 @@ struct ieee80211_txq *ieee80211_next_txq
if (deficit < 0)
sta->airtime[txqi->txq.ac].deficit +=
if (deficit < 0 || !aql_check) {
list_move_tail(&txqi->schedule_order,
-@@ -4203,7 +4203,8 @@ bool ieee80211_txq_may_transmit(struct i
+@@ -4225,7 +4225,8 @@ bool ieee80211_txq_may_transmit(struct i
}
sta = container_of(iter->txq.sta, struct sta_info, sta);
if (ieee80211_sta_deficit(sta, ac) < 0)
list_move_tail(&iter->schedule_order, &local->active_txqs[ac]);
}
-@@ -4211,7 +4212,7 @@ bool ieee80211_txq_may_transmit(struct i
+@@ -4233,7 +4234,7 @@ bool ieee80211_txq_may_transmit(struct i
if (sta->airtime[ac].deficit >= 0)
goto out;
+++ /dev/null
-From: Felix Fietkau <nbd@nbd.name>
-Date: Fri, 30 Jun 2023 13:11:51 +0200
-Subject: [PATCH] mac80211: split mesh fast tx cache into
- local/proxied/forwarded
-
-Depending on the origin of the packets (and their SA), 802.11 + mesh headers
-could be filled in differently. In order to properly deal with that, add a
-new field to the lookup key, indicating the type (local, proxied or
-forwarded). This can fix spurious packet drop issues that depend on the order
-in which nodes/hosts communicate with each other.
-
-Signed-off-by: Felix Fietkau <nbd@nbd.name>
----
-
---- a/net/mac80211/mesh.c
-+++ b/net/mac80211/mesh.c
-@@ -765,6 +765,9 @@ bool ieee80211_mesh_xmit_fast(struct iee
- struct sk_buff *skb, u32 ctrl_flags)
- {
- struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh;
-+ struct ieee80211_mesh_fast_tx_key key = {
-+ .type = MESH_FAST_TX_TYPE_LOCAL
-+ };
- struct ieee80211_mesh_fast_tx *entry;
- struct ieee80211s_hdr *meshhdr;
- u8 sa[ETH_ALEN] __aligned(2);
-@@ -800,7 +803,10 @@ bool ieee80211_mesh_xmit_fast(struct iee
- return false;
- }
-
-- entry = mesh_fast_tx_get(sdata, skb->data);
-+ ether_addr_copy(key.addr, skb->data);
-+ if (!ether_addr_equal(skb->data + ETH_ALEN, sdata->vif.addr))
-+ key.type = MESH_FAST_TX_TYPE_PROXIED;
-+ entry = mesh_fast_tx_get(sdata, &key);
- if (!entry)
- return false;
-
---- a/net/mac80211/mesh.h
-+++ b/net/mac80211/mesh.h
-@@ -134,9 +134,38 @@ struct mesh_path {
- #define MESH_FAST_TX_CACHE_TIMEOUT 8000 /* msecs */
-
- /**
-+ * enum ieee80211_mesh_fast_tx_type - cached mesh fast tx entry type
-+ *
-+ * @MESH_FAST_TX_TYPE_LOCAL: tx from the local vif address as SA
-+ * @MESH_FAST_TX_TYPE_PROXIED: local tx with a different SA (e.g. bridged)
-+ * @MESH_FAST_TX_TYPE_FORWARDED: forwarded from a different mesh point
-+ * @NUM_MESH_FAST_TX_TYPE: number of entry types
-+ */
-+enum ieee80211_mesh_fast_tx_type {
-+ MESH_FAST_TX_TYPE_LOCAL,
-+ MESH_FAST_TX_TYPE_PROXIED,
-+ MESH_FAST_TX_TYPE_FORWARDED,
-+
-+ /* must be last */
-+ NUM_MESH_FAST_TX_TYPE
-+};
-+
-+
-+/**
-+ * struct ieee80211_mesh_fast_tx_key - cached mesh fast tx entry key
-+ *
-+ * @addr: The Ethernet DA for this entry
-+ * @type: cache entry type
-+ */
-+struct ieee80211_mesh_fast_tx_key {
-+ u8 addr[ETH_ALEN] __aligned(2);
-+ u16 type;
-+};
-+
-+/**
- * struct ieee80211_mesh_fast_tx - cached mesh fast tx entry
- * @rhash: rhashtable pointer
-- * @addr_key: The Ethernet DA which is the key for this entry
-+ * @key: the lookup key for this cache entry
- * @fast_tx: base fast_tx data
- * @hdr: cached mesh and rfc1042 headers
- * @hdrlen: length of mesh + rfc1042
-@@ -147,7 +176,7 @@ struct mesh_path {
- */
- struct ieee80211_mesh_fast_tx {
- struct rhash_head rhash;
-- u8 addr_key[ETH_ALEN] __aligned(2);
-+ struct ieee80211_mesh_fast_tx_key key;
-
- struct ieee80211_fast_tx fast_tx;
- u8 hdr[sizeof(struct ieee80211s_hdr) + sizeof(rfc1042_header)];
-@@ -333,7 +362,8 @@ void mesh_path_tx_root_frame(struct ieee
-
- bool mesh_action_is_path_sel(struct ieee80211_mgmt *mgmt);
- struct ieee80211_mesh_fast_tx *
--mesh_fast_tx_get(struct ieee80211_sub_if_data *sdata, const u8 *addr);
-+mesh_fast_tx_get(struct ieee80211_sub_if_data *sdata,
-+ struct ieee80211_mesh_fast_tx_key *key);
- bool ieee80211_mesh_xmit_fast(struct ieee80211_sub_if_data *sdata,
- struct sk_buff *skb, u32 ctrl_flags);
- void mesh_fast_tx_cache(struct ieee80211_sub_if_data *sdata,
---- a/net/mac80211/mesh_pathtbl.c
-+++ b/net/mac80211/mesh_pathtbl.c
-@@ -36,8 +36,8 @@ static const struct rhashtable_params me
- static const struct rhashtable_params fast_tx_rht_params = {
- .nelem_hint = 10,
- .automatic_shrinking = true,
-- .key_len = ETH_ALEN,
-- .key_offset = offsetof(struct ieee80211_mesh_fast_tx, addr_key),
-+ .key_len = sizeof(struct ieee80211_mesh_fast_tx_key),
-+ .key_offset = offsetof(struct ieee80211_mesh_fast_tx, key),
- .head_offset = offsetof(struct ieee80211_mesh_fast_tx, rhash),
- .hashfn = mesh_table_hash,
- };
-@@ -426,20 +426,21 @@ static void mesh_fast_tx_entry_free(stru
- }
-
- struct ieee80211_mesh_fast_tx *
--mesh_fast_tx_get(struct ieee80211_sub_if_data *sdata, const u8 *addr)
-+mesh_fast_tx_get(struct ieee80211_sub_if_data *sdata,
-+ struct ieee80211_mesh_fast_tx_key *key)
- {
- struct ieee80211_mesh_fast_tx *entry;
- struct mesh_tx_cache *cache;
-
- cache = &sdata->u.mesh.tx_cache;
-- entry = rhashtable_lookup(&cache->rht, addr, fast_tx_rht_params);
-+ entry = rhashtable_lookup(&cache->rht, key, fast_tx_rht_params);
- if (!entry)
- return NULL;
-
- if (!(entry->mpath->flags & MESH_PATH_ACTIVE) ||
- mpath_expired(entry->mpath)) {
- spin_lock_bh(&cache->walk_lock);
-- entry = rhashtable_lookup(&cache->rht, addr, fast_tx_rht_params);
-+ entry = rhashtable_lookup(&cache->rht, key, fast_tx_rht_params);
- if (entry)
- mesh_fast_tx_entry_free(cache, entry);
- spin_unlock_bh(&cache->walk_lock);
-@@ -484,18 +485,24 @@ void mesh_fast_tx_cache(struct ieee80211
- if (!sta)
- return;
-
-+ build.key.type = MESH_FAST_TX_TYPE_LOCAL;
- if ((meshhdr->flags & MESH_FLAGS_AE) == MESH_FLAGS_AE_A5_A6) {
- /* This is required to keep the mppath alive */
- mppath = mpp_path_lookup(sdata, meshhdr->eaddr1);
- if (!mppath)
- return;
- build.mppath = mppath;
-+ if (!ether_addr_equal(meshhdr->eaddr2, sdata->vif.addr))
-+ build.key.type = MESH_FAST_TX_TYPE_PROXIED;
- } else if (ieee80211_has_a4(hdr->frame_control)) {
- mppath = mpath;
- } else {
- return;
- }
-
-+ if (!ether_addr_equal(hdr->addr4, sdata->vif.addr))
-+ build.key.type = MESH_FAST_TX_TYPE_FORWARDED;
-+
- /* rate limit, in case fast xmit can't be enabled */
- if (mppath->fast_tx_check == jiffies)
- return;
-@@ -542,7 +549,7 @@ void mesh_fast_tx_cache(struct ieee80211
- }
- }
-
-- memcpy(build.addr_key, mppath->dst, ETH_ALEN);
-+ memcpy(build.key.addr, mppath->dst, ETH_ALEN);
- build.timestamp = jiffies;
- build.fast_tx.band = info->band;
- build.fast_tx.da_offs = offsetof(struct ieee80211_hdr, addr3);
-@@ -644,13 +651,19 @@ void mesh_fast_tx_flush_addr(struct ieee
- const u8 *addr)
- {
- struct mesh_tx_cache *cache = &sdata->u.mesh.tx_cache;
-+ struct ieee80211_mesh_fast_tx_key key = {};
- struct ieee80211_mesh_fast_tx *entry;
-+ int i;
-
-+ ether_addr_copy(key.addr, addr);
- cache = &sdata->u.mesh.tx_cache;
- spin_lock_bh(&cache->walk_lock);
-- entry = rhashtable_lookup_fast(&cache->rht, addr, fast_tx_rht_params);
-- if (entry)
-- mesh_fast_tx_entry_free(cache, entry);
-+ for (i = 0; i < NUM_MESH_FAST_TX_TYPE; i++) {
-+ key.type = i;
-+ entry = rhashtable_lookup_fast(&cache->rht, &key, fast_tx_rht_params);
-+ if (entry)
-+ mesh_fast_tx_entry_free(cache, entry);
-+ }
- spin_unlock_bh(&cache->walk_lock);
- }
-
---- a/net/mac80211/rx.c
-+++ b/net/mac80211/rx.c
-@@ -2726,7 +2726,10 @@ ieee80211_rx_mesh_fast_forward(struct ie
- struct sk_buff *skb, int hdrlen)
- {
- struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh;
-- struct ieee80211_mesh_fast_tx *entry = NULL;
-+ struct ieee80211_mesh_fast_tx_key key = {
-+ .type = MESH_FAST_TX_TYPE_FORWARDED
-+ };
-+ struct ieee80211_mesh_fast_tx *entry;
- struct ieee80211s_hdr *mesh_hdr;
- struct tid_ampdu_tx *tid_tx;
- struct sta_info *sta;
-@@ -2735,9 +2738,13 @@ ieee80211_rx_mesh_fast_forward(struct ie
-
- mesh_hdr = (struct ieee80211s_hdr *)(skb->data + sizeof(eth));
- if ((mesh_hdr->flags & MESH_FLAGS_AE) == MESH_FLAGS_AE_A5_A6)
-- entry = mesh_fast_tx_get(sdata, mesh_hdr->eaddr1);
-+ ether_addr_copy(key.addr, mesh_hdr->eaddr1);
- else if (!(mesh_hdr->flags & MESH_FLAGS_AE))
-- entry = mesh_fast_tx_get(sdata, skb->data);
-+ ether_addr_copy(key.addr, skb->data);
-+ else
-+ return false;
-+
-+ entry = mesh_fast_tx_get(sdata, &key);
- if (!entry)
- return false;
-
+++ /dev/null
-From: Johannes Berg <johannes.berg@intel.com>
-Date: Mon, 28 Aug 2023 09:54:39 +0200
-Subject: [PATCH] wifi: cfg80211: annotate iftype_data pointer with sparse
-
-There were are a number of cases in mac80211 and iwlwifi (at
-least) that used the sband->iftype_data pointer directly,
-instead of using the accessors to find the right array entry
-to use.
-
-Make sparse warn when such a thing is done.
-
-To not have a lot of casts, add two helper functions/macros
-
- - ieee80211_set_sband_iftype_data()
- - for_each_sband_iftype_data()
-
-Signed-off-by: Johannes Berg <johannes.berg@intel.com>
----
-
---- a/drivers/net/wireless/ath/ath11k/mac.c
-+++ b/drivers/net/wireless/ath/ath11k/mac.c
-@@ -5893,8 +5893,9 @@ static void ath11k_mac_setup_he_cap(stru
- ar->mac.iftype[NL80211_BAND_2GHZ],
- NL80211_BAND_2GHZ);
- band = &ar->mac.sbands[NL80211_BAND_2GHZ];
-- band->iftype_data = ar->mac.iftype[NL80211_BAND_2GHZ];
-- band->n_iftype_data = count;
-+ _ieee80211_set_sband_iftype_data(band,
-+ ar->mac.iftype[NL80211_BAND_2GHZ],
-+ count);
- }
-
- if (cap->supported_bands & WMI_HOST_WLAN_5G_CAP) {
-@@ -5902,8 +5903,9 @@ static void ath11k_mac_setup_he_cap(stru
- ar->mac.iftype[NL80211_BAND_5GHZ],
- NL80211_BAND_5GHZ);
- band = &ar->mac.sbands[NL80211_BAND_5GHZ];
-- band->iftype_data = ar->mac.iftype[NL80211_BAND_5GHZ];
-- band->n_iftype_data = count;
-+ _ieee80211_set_sband_iftype_data(band,
-+ ar->mac.iftype[NL80211_BAND_5GHZ],
-+ count);
- }
-
- if (cap->supported_bands & WMI_HOST_WLAN_5G_CAP &&
-@@ -5912,8 +5914,9 @@ static void ath11k_mac_setup_he_cap(stru
- ar->mac.iftype[NL80211_BAND_6GHZ],
- NL80211_BAND_6GHZ);
- band = &ar->mac.sbands[NL80211_BAND_6GHZ];
-- band->iftype_data = ar->mac.iftype[NL80211_BAND_6GHZ];
-- band->n_iftype_data = count;
-+ _ieee80211_set_sband_iftype_data(band,
-+ ar->mac.iftype[NL80211_BAND_6GHZ],
-+ count);
- }
- }
-
---- a/drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c
-+++ b/drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c
-@@ -1078,8 +1078,8 @@ static void iwl_init_he_hw_capab(struct
-
- memcpy(iftype_data, iwl_he_eht_capa, sizeof(iwl_he_eht_capa));
-
-- sband->iftype_data = iftype_data;
-- sband->n_iftype_data = ARRAY_SIZE(iwl_he_eht_capa);
-+ _ieee80211_set_sband_iftype_data(sband, iftype_data,
-+ ARRAY_SIZE(iwl_he_eht_capa));
-
- for (i = 0; i < sband->n_iftype_data; i++)
- iwl_nvm_fixup_sband_iftd(trans, data, sband, &iftype_data[i],
---- a/drivers/net/wireless/mediatek/mt76/mt7915/init.c
-+++ b/drivers/net/wireless/mediatek/mt76/mt7915/init.c
-@@ -1127,8 +1127,7 @@ void mt7915_set_stream_he_caps(struct mt
- n = mt7915_init_he_caps(phy, NL80211_BAND_2GHZ, data);
-
- band = &phy->mt76->sband_2g.sband;
-- band->iftype_data = data;
-- band->n_iftype_data = n;
-+ _ieee80211_set_sband_iftype_data(band, data, n);
- }
-
- if (phy->mt76->cap.has_5ghz) {
-@@ -1136,8 +1135,7 @@ void mt7915_set_stream_he_caps(struct mt
- n = mt7915_init_he_caps(phy, NL80211_BAND_5GHZ, data);
-
- band = &phy->mt76->sband_5g.sband;
-- band->iftype_data = data;
-- band->n_iftype_data = n;
-+ _ieee80211_set_sband_iftype_data(band, data, n);
- }
-
- if (phy->mt76->cap.has_6ghz) {
-@@ -1145,8 +1143,7 @@ void mt7915_set_stream_he_caps(struct mt
- n = mt7915_init_he_caps(phy, NL80211_BAND_6GHZ, data);
-
- band = &phy->mt76->sband_6g.sband;
-- band->iftype_data = data;
-- band->n_iftype_data = n;
-+ _ieee80211_set_sband_iftype_data(band, data, n);
- }
- }
-
---- a/drivers/net/wireless/mediatek/mt76/mt7921/main.c
-+++ b/drivers/net/wireless/mediatek/mt76/mt7921/main.c
-@@ -196,8 +196,7 @@ void mt7921_set_stream_he_caps(struct mt
- n = mt7921_init_he_caps(phy, NL80211_BAND_2GHZ, data);
-
- band = &phy->mt76->sband_2g.sband;
-- band->iftype_data = data;
-- band->n_iftype_data = n;
-+ _ieee80211_set_sband_iftype_data(band, data, n);
- }
-
- if (phy->mt76->cap.has_5ghz) {
-@@ -205,16 +204,14 @@ void mt7921_set_stream_he_caps(struct mt
- n = mt7921_init_he_caps(phy, NL80211_BAND_5GHZ, data);
-
- band = &phy->mt76->sband_5g.sband;
-- band->iftype_data = data;
-- band->n_iftype_data = n;
-+ _ieee80211_set_sband_iftype_data(band, data, n);
-
- if (phy->mt76->cap.has_6ghz) {
- data = phy->iftype[NL80211_BAND_6GHZ];
- n = mt7921_init_he_caps(phy, NL80211_BAND_6GHZ, data);
-
- band = &phy->mt76->sband_6g.sband;
-- band->iftype_data = data;
-- band->n_iftype_data = n;
-+ _ieee80211_set_sband_iftype_data(band, data, n);
- }
- }
- }
---- a/drivers/net/wireless/mediatek/mt76/mt7996/init.c
-+++ b/drivers/net/wireless/mediatek/mt76/mt7996/init.c
-@@ -828,8 +828,7 @@ __mt7996_set_stream_he_eht_caps(struct m
- n++;
- }
-
-- sband->iftype_data = data;
-- sband->n_iftype_data = n;
-+ _ieee80211_set_sband_iftype_data(sband, data, n);
- }
-
- void mt7996_set_stream_he_eht_caps(struct mt7996_phy *phy)
---- a/drivers/net/wireless/quantenna/qtnfmac/commands.c
-+++ b/drivers/net/wireless/quantenna/qtnfmac/commands.c
-@@ -1335,7 +1335,7 @@ static int qtnf_cmd_band_fill_iftype(con
- return -EINVAL;
- }
-
-- kfree(band->iftype_data);
-+ kfree((__force void *)band->iftype_data);
- band->iftype_data = NULL;
- band->n_iftype_data = tlv->n_iftype_data;
- if (band->n_iftype_data == 0)
-@@ -1347,7 +1347,8 @@ static int qtnf_cmd_band_fill_iftype(con
- band->n_iftype_data = 0;
- return -ENOMEM;
- }
-- band->iftype_data = iftype_data;
-+
-+ _ieee80211_set_sband_iftype_data(band, iftype_data, tlv->n_iftype_data);
-
- for (i = 0; i < band->n_iftype_data; i++)
- qtnf_cmd_conv_iftype(iftype_data++, &tlv->iftype_data[i]);
---- a/drivers/net/wireless/quantenna/qtnfmac/core.c
-+++ b/drivers/net/wireless/quantenna/qtnfmac/core.c
-@@ -549,7 +549,7 @@ static void qtnf_core_mac_detach(struct
- if (!wiphy->bands[band])
- continue;
-
-- kfree(wiphy->bands[band]->iftype_data);
-+ kfree((__force void *)wiphy->bands[band]->iftype_data);
- wiphy->bands[band]->n_iftype_data = 0;
-
- kfree(wiphy->bands[band]->channels);
---- a/drivers/net/wireless/realtek/rtw89/core.c
-+++ b/drivers/net/wireless/realtek/rtw89/core.c
-@@ -3359,8 +3359,7 @@ static void rtw89_init_he_cap(struct rtw
- idx++;
- }
-
-- sband->iftype_data = iftype_data;
-- sband->n_iftype_data = idx;
-+ _ieee80211_set_sband_iftype_data(sband, iftype_data, idx);
- }
-
- static int rtw89_core_set_supported_band(struct rtw89_dev *rtwdev)
-@@ -3405,11 +3404,11 @@ err:
- hw->wiphy->bands[NL80211_BAND_5GHZ] = NULL;
- hw->wiphy->bands[NL80211_BAND_6GHZ] = NULL;
- if (sband_2ghz)
-- kfree(sband_2ghz->iftype_data);
-+ kfree((__force void *)sband_2ghz->iftype_data);
- if (sband_5ghz)
-- kfree(sband_5ghz->iftype_data);
-+ kfree((__force void *)sband_5ghz->iftype_data);
- if (sband_6ghz)
-- kfree(sband_6ghz->iftype_data);
-+ kfree((__force void *)sband_6ghz->iftype_data);
- kfree(sband_2ghz);
- kfree(sband_5ghz);
- kfree(sband_6ghz);
-@@ -3421,11 +3420,11 @@ static void rtw89_core_clr_supported_ban
- struct ieee80211_hw *hw = rtwdev->hw;
-
- if (hw->wiphy->bands[NL80211_BAND_2GHZ])
-- kfree(hw->wiphy->bands[NL80211_BAND_2GHZ]->iftype_data);
-+ kfree((__force void *)hw->wiphy->bands[NL80211_BAND_2GHZ]->iftype_data);
- if (hw->wiphy->bands[NL80211_BAND_5GHZ])
-- kfree(hw->wiphy->bands[NL80211_BAND_5GHZ]->iftype_data);
-+ kfree((__force void *)hw->wiphy->bands[NL80211_BAND_5GHZ]->iftype_data);
- if (hw->wiphy->bands[NL80211_BAND_6GHZ])
-- kfree(hw->wiphy->bands[NL80211_BAND_6GHZ]->iftype_data);
-+ kfree((__force void *)hw->wiphy->bands[NL80211_BAND_6GHZ]->iftype_data);
- kfree(hw->wiphy->bands[NL80211_BAND_2GHZ]);
- kfree(hw->wiphy->bands[NL80211_BAND_5GHZ]);
- kfree(hw->wiphy->bands[NL80211_BAND_6GHZ]);
---- a/drivers/net/wireless/realtek/rtw89/regd.c
-+++ b/drivers/net/wireless/realtek/rtw89/regd.c
-@@ -377,7 +377,7 @@ bottom:
- return;
-
- wiphy->bands[NL80211_BAND_6GHZ] = NULL;
-- kfree(sband->iftype_data);
-+ kfree((__force void *)sband->iftype_data);
- kfree(sband);
- }
-
---- a/drivers/net/wireless/virtual/mac80211_hwsim.c
-+++ b/drivers/net/wireless/virtual/mac80211_hwsim.c
-@@ -4899,25 +4899,19 @@ static const struct ieee80211_sband_ifty
-
- static void mac80211_hwsim_sband_capab(struct ieee80211_supported_band *sband)
- {
-- u16 n_iftype_data;
--
-- if (sband->band == NL80211_BAND_2GHZ) {
-- n_iftype_data = ARRAY_SIZE(sband_capa_2ghz);
-- sband->iftype_data =
-- (struct ieee80211_sband_iftype_data *)sband_capa_2ghz;
-- } else if (sband->band == NL80211_BAND_5GHZ) {
-- n_iftype_data = ARRAY_SIZE(sband_capa_5ghz);
-- sband->iftype_data =
-- (struct ieee80211_sband_iftype_data *)sband_capa_5ghz;
-- } else if (sband->band == NL80211_BAND_6GHZ) {
-- n_iftype_data = ARRAY_SIZE(sband_capa_6ghz);
-- sband->iftype_data =
-- (struct ieee80211_sband_iftype_data *)sband_capa_6ghz;
-- } else {
-- return;
-+ switch (sband->band) {
-+ case NL80211_BAND_2GHZ:
-+ ieee80211_set_sband_iftype_data(sband, sband_capa_2ghz);
-+ break;
-+ case NL80211_BAND_5GHZ:
-+ ieee80211_set_sband_iftype_data(sband, sband_capa_5ghz);
-+ break;
-+ case NL80211_BAND_6GHZ:
-+ ieee80211_set_sband_iftype_data(sband, sband_capa_6ghz);
-+ break;
-+ default:
-+ break;
- }
--
-- sband->n_iftype_data = n_iftype_data;
- }
-
- #ifdef CPTCFG_MAC80211_MESH
---- a/include/net/cfg80211.h
-+++ b/include/net/cfg80211.h
-@@ -415,6 +415,19 @@ struct ieee80211_sta_eht_cap {
- u8 eht_ppe_thres[IEEE80211_EHT_PPE_THRES_MAX_LEN];
- };
-
-+/* sparse defines __CHECKER__; see Documentation/dev-tools/sparse.rst */
-+#ifdef __CHECKER__
-+/*
-+ * This is used to mark the sband->iftype_data pointer which is supposed
-+ * to be an array with special access semantics (per iftype), but a lot
-+ * of code got it wrong in the past, so with this marking sparse will be
-+ * noisy when the pointer is used directly.
-+ */
-+# define __iftd __attribute__((noderef, address_space(__iftype_data)))
-+#else
-+# define __iftd
-+#endif /* __CHECKER__ */
-+
- /**
- * struct ieee80211_sband_iftype_data - sband data per interface type
- *
-@@ -548,10 +561,48 @@ struct ieee80211_supported_band {
- struct ieee80211_sta_s1g_cap s1g_cap;
- struct ieee80211_edmg edmg_cap;
- u16 n_iftype_data;
-- const struct ieee80211_sband_iftype_data *iftype_data;
-+ const struct ieee80211_sband_iftype_data __iftd *iftype_data;
- };
-
- /**
-+ * _ieee80211_set_sband_iftype_data - set sband iftype data array
-+ * @sband: the sband to initialize
-+ * @iftd: the iftype data array pointer
-+ * @n_iftd: the length of the iftype data array
-+ *
-+ * Set the sband iftype data array; use this where the length cannot
-+ * be derived from the ARRAY_SIZE() of the argument, but prefer
-+ * ieee80211_set_sband_iftype_data() where it can be used.
-+ */
-+static inline void
-+_ieee80211_set_sband_iftype_data(struct ieee80211_supported_band *sband,
-+ const struct ieee80211_sband_iftype_data *iftd,
-+ u16 n_iftd)
-+{
-+ sband->iftype_data = (const void __iftd __force *)iftd;
-+ sband->n_iftype_data = n_iftd;
-+}
-+
-+/**
-+ * ieee80211_set_sband_iftype_data - set sband iftype data array
-+ * @sband: the sband to initialize
-+ * @iftd: the iftype data array
-+ */
-+#define ieee80211_set_sband_iftype_data(sband, iftd) \
-+ _ieee80211_set_sband_iftype_data(sband, iftd, ARRAY_SIZE(iftd))
-+
-+/**
-+ * for_each_sband_iftype_data - iterate sband iftype data entries
-+ * @sband: the sband whose iftype_data array to iterate
-+ * @i: iterator counter
-+ * @iftd: iftype data pointer to set
-+ */
-+#define for_each_sband_iftype_data(sband, i, iftd) \
-+ for (i = 0, iftd = (const void __force *)&(sband)->iftype_data[i]; \
-+ i < (sband)->n_iftype_data; \
-+ i++, iftd = (const void __force *)&(sband)->iftype_data[i])
-+
-+/**
- * ieee80211_get_sband_iftype_data - return sband data for a given iftype
- * @sband: the sband to search for the STA on
- * @iftype: enum nl80211_iftype
-@@ -562,6 +613,7 @@ static inline const struct ieee80211_sba
- ieee80211_get_sband_iftype_data(const struct ieee80211_supported_band *sband,
- u8 iftype)
- {
-+ const struct ieee80211_sband_iftype_data *data;
- int i;
-
- if (WARN_ON(iftype >= NL80211_IFTYPE_MAX))
-@@ -570,10 +622,7 @@ ieee80211_get_sband_iftype_data(const st
- if (iftype == NL80211_IFTYPE_AP_VLAN)
- iftype = NL80211_IFTYPE_AP;
-
-- for (i = 0; i < sband->n_iftype_data; i++) {
-- const struct ieee80211_sband_iftype_data *data =
-- &sband->iftype_data[i];
--
-+ for_each_sband_iftype_data(sband, i, data) {
- if (data->types_mask & BIT(iftype))
- return data;
- }
---- a/net/mac80211/main.c
-+++ b/net/mac80211/main.c
-@@ -1052,6 +1052,7 @@ int ieee80211_register_hw(struct ieee802
- supp_he = false;
- supp_eht = false;
- for (band = 0; band < NUM_NL80211_BANDS; band++) {
-+ const struct ieee80211_sband_iftype_data *iftd;
- struct ieee80211_supported_band *sband;
-
- sband = local->hw.wiphy->bands[band];
-@@ -1098,11 +1099,7 @@ int ieee80211_register_hw(struct ieee802
- supp_ht = supp_ht || sband->ht_cap.ht_supported;
- supp_vht = supp_vht || sband->vht_cap.vht_supported;
-
-- for (i = 0; i < sband->n_iftype_data; i++) {
-- const struct ieee80211_sband_iftype_data *iftd;
--
-- iftd = &sband->iftype_data[i];
--
-+ for_each_sband_iftype_data(sband, i, iftd) {
- supp_he = supp_he || iftd->he_cap.has_he;
- supp_eht = supp_eht || iftd->eht_cap.has_eht;
- }
---- a/net/wireless/chan.c
-+++ b/net/wireless/chan.c
-@@ -6,7 +6,7 @@
- *
- * Copyright 2009 Johannes Berg <johannes@sipsolutions.net>
- * Copyright 2013-2014 Intel Mobile Communications GmbH
-- * Copyright 2018-2022 Intel Corporation
-+ * Copyright 2018-2023 Intel Corporation
- */
-
- #include <linux/export.h>
-@@ -1162,8 +1162,7 @@ bool cfg80211_chandef_usable(struct wiph
- if (!sband)
- return false;
-
-- for (i = 0; i < sband->n_iftype_data; i++) {
-- iftd = &sband->iftype_data[i];
-+ for_each_sband_iftype_data(sband, i, iftd) {
- if (!iftd->eht_cap.has_eht)
- continue;
-
---- a/net/wireless/core.c
-+++ b/net/wireless/core.c
-@@ -5,7 +5,7 @@
- * Copyright 2006-2010 Johannes Berg <johannes@sipsolutions.net>
- * Copyright 2013-2014 Intel Mobile Communications GmbH
- * Copyright 2015-2017 Intel Deutschland GmbH
-- * Copyright (C) 2018-2022 Intel Corporation
-+ * Copyright (C) 2018-2023 Intel Corporation
- */
-
- #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
-@@ -819,6 +819,7 @@ int wiphy_register(struct wiphy *wiphy)
-
- /* sanity check supported bands/channels */
- for (band = 0; band < NUM_NL80211_BANDS; band++) {
-+ const struct ieee80211_sband_iftype_data *iftd;
- u16 types = 0;
- bool have_he = false;
-
-@@ -875,14 +876,11 @@ int wiphy_register(struct wiphy *wiphy)
- return -EINVAL;
- }
-
-- for (i = 0; i < sband->n_iftype_data; i++) {
-- const struct ieee80211_sband_iftype_data *iftd;
-+ for_each_sband_iftype_data(sband, i, iftd) {
- bool has_ap, has_non_ap;
- u32 ap_bits = BIT(NL80211_IFTYPE_AP) |
- BIT(NL80211_IFTYPE_P2P_GO);
-
-- iftd = &sband->iftype_data[i];
--
- if (WARN_ON(!iftd->types_mask))
- return -EINVAL;
- if (WARN_ON(types & iftd->types_mask))
---- a/net/wireless/nl80211.c
-+++ b/net/wireless/nl80211.c
-@@ -1907,20 +1907,20 @@ static int nl80211_send_band_rateinfo(st
- struct nlattr *nl_iftype_data =
- nla_nest_start_noflag(msg,
- NL80211_BAND_ATTR_IFTYPE_DATA);
-+ const struct ieee80211_sband_iftype_data *iftd;
- int err;
-
- if (!nl_iftype_data)
- return -ENOBUFS;
-
-- for (i = 0; i < sband->n_iftype_data; i++) {
-+ for_each_sband_iftype_data(sband, i, iftd) {
- struct nlattr *iftdata;
-
- iftdata = nla_nest_start_noflag(msg, i + 1);
- if (!iftdata)
- return -ENOBUFS;
-
-- err = nl80211_send_iftype_data(msg, sband,
-- &sband->iftype_data[i]);
-+ err = nl80211_send_iftype_data(msg, sband, iftd);
- if (err)
- return err;
-
+++ /dev/null
-From 30ca8b0c4d6c9fb1d76e5894b1e8bf7c6a12224d Mon Sep 17 00:00:00 2001
-From: Aditya Kumar Singh <quic_adisi@quicinc.com>
-Date: Tue, 12 Sep 2023 10:48:55 +0530
-Subject: [PATCH] wifi: cfg80211: export DFS CAC time and usable state helper
- functions
-
-cfg80211 has cfg80211_chandef_dfs_usable() function to know whether
-at least one channel in the chandef is in usable state or not. Also,
-cfg80211_chandef_dfs_cac_time() function is there which tells the CAC
-time required for the given chandef.
-
-Make these two functions visible to drivers by exporting their symbol
-to global list of kernel symbols.
-
-Lower level drivers can make use of these two functions to be aware
-if CAC is required on the given chandef and for how long. For example
-drivers which maintains the CAC state internally can make use of these.
-
-Signed-off-by: Aditya Kumar Singh <quic_adisi@quicinc.com>
-Reviewed-by: Jeff Johnson <quic_jjohnson@quicinc.com>
-Link: https://lore.kernel.org/r/20230912051857.2284-2-quic_adisi@quicinc.com
-Signed-off-by: Johannes Berg <johannes.berg@intel.com>
----
- include/net/cfg80211.h | 24 ++++++++++++++++++++++++
- net/wireless/chan.c | 2 ++
- net/wireless/core.h | 17 -----------------
- 3 files changed, 26 insertions(+), 17 deletions(-)
-
---- a/include/net/cfg80211.h
-+++ b/include/net/cfg80211.h
-@@ -1008,6 +1008,30 @@ int cfg80211_chandef_dfs_required(struct
- enum nl80211_iftype iftype);
-
- /**
-+ * cfg80211_chandef_dfs_usable - checks if chandef is DFS usable and we
-+ * can/need start CAC on such channel
-+ * @wiphy: the wiphy to validate against
-+ * @chandef: the channel definition to check
-+ *
-+ * Return: true if all channels available and at least
-+ * one channel requires CAC (NL80211_DFS_USABLE)
-+ */
-+bool cfg80211_chandef_dfs_usable(struct wiphy *wiphy,
-+ const struct cfg80211_chan_def *chandef);
-+
-+/**
-+ * cfg80211_chandef_dfs_cac_time - get the DFS CAC time (in ms) for given
-+ * channel definition
-+ * @wiphy: the wiphy to validate against
-+ * @chandef: the channel definition to check
-+ *
-+ * Returns: DFS CAC time (in ms) which applies for this channel definition
-+ */
-+unsigned int
-+cfg80211_chandef_dfs_cac_time(struct wiphy *wiphy,
-+ const struct cfg80211_chan_def *chandef);
-+
-+/**
- * nl80211_send_chandef - sends the channel definition.
- * @msg: the msg to send channel definition
- * @chandef: the channel definition to check
---- a/net/wireless/chan.c
-+++ b/net/wireless/chan.c
-@@ -666,6 +666,7 @@ bool cfg80211_chandef_dfs_usable(struct
-
- return (r1 + r2 > 0);
- }
-+EXPORT_SYMBOL(cfg80211_chandef_dfs_usable);
-
- /*
- * Checks if center frequency of chan falls with in the bandwidth
-@@ -965,6 +966,7 @@ cfg80211_chandef_dfs_cac_time(struct wip
-
- return max(t1, t2);
- }
-+EXPORT_SYMBOL(cfg80211_chandef_dfs_cac_time);
-
- static bool cfg80211_secondary_chans_ok(struct wiphy *wiphy,
- u32 center_freq, u32 bandwidth,
---- a/net/wireless/core.h
-+++ b/net/wireless/core.h
-@@ -476,29 +476,12 @@ int cfg80211_scan(struct cfg80211_regist
-
- extern struct work_struct cfg80211_disconnect_work;
-
--/**
-- * cfg80211_chandef_dfs_usable - checks if chandef is DFS usable
-- * @wiphy: the wiphy to validate against
-- * @chandef: the channel definition to check
-- *
-- * Checks if chandef is usable and we can/need start CAC on such channel.
-- *
-- * Return: true if all channels available and at least
-- * one channel requires CAC (NL80211_DFS_USABLE)
-- */
--bool cfg80211_chandef_dfs_usable(struct wiphy *wiphy,
-- const struct cfg80211_chan_def *chandef);
--
- void cfg80211_set_dfs_state(struct wiphy *wiphy,
- const struct cfg80211_chan_def *chandef,
- enum nl80211_dfs_state dfs_state);
-
- void cfg80211_dfs_channels_update_work(struct work_struct *work);
-
--unsigned int
--cfg80211_chandef_dfs_cac_time(struct wiphy *wiphy,
-- const struct cfg80211_chan_def *chandef);
--
- void cfg80211_sched_dfs_chan_update(struct cfg80211_registered_device *rdev);
-
- int
+++ /dev/null
-From: Felix Fietkau <nbd@nbd.name>
-Date: Wed, 3 Jan 2024 15:10:18 +0100
-Subject: [PATCH] wifi: mac80211: fix race condition on enabling fast-xmit
-
-fast-xmit must only be enabled after the sta has been uploaded to the driver,
-otherwise it could end up passing the not-yet-uploaded sta via drv_tx calls
-to the driver, leading to potential crashes because of uninitialized drv_priv
-data.
-Add a missing sta->uploaded check and re-check fast xmit after inserting a sta.
-
-Signed-off-by: Felix Fietkau <nbd@nbd.name>
----
-
---- a/net/mac80211/sta_info.c
-+++ b/net/mac80211/sta_info.c
-@@ -918,6 +918,7 @@ static int sta_info_insert_finish(struct
-
- if (ieee80211_vif_is_mesh(&sdata->vif))
- mesh_accept_plinks_update(sdata);
-+ ieee80211_check_fast_xmit(sta);
-
- return 0;
- out_remove:
---- a/net/mac80211/tx.c
-+++ b/net/mac80211/tx.c
-@@ -3034,7 +3034,7 @@ void ieee80211_check_fast_xmit(struct st
- sdata->vif.type == NL80211_IFTYPE_STATION)
- goto out;
-
-- if (!test_sta_flag(sta, WLAN_STA_AUTHORIZED))
-+ if (!test_sta_flag(sta, WLAN_STA_AUTHORIZED) || !sta->uploaded)
- goto out;
-
- if (test_sta_flag(sta, WLAN_STA_PS_STA) ||
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
-@@ -175,6 +175,8 @@ enum ieee80211_channel_flags {
+@@ -189,6 +189,8 @@ enum ieee80211_channel_flags {
* @dfs_state: current state of this channel. Only relevant if radar is required
* on this channel.
* @dfs_state_entered: timestamp (jiffies) when the dfs state was entered.
+ * @dfs_state_last_available: timestamp (jiffies) of the last time when the
+ * channel was available.
* @dfs_cac_ms: DFS CAC time in milliseconds, this is valid for DFS channels.
+ * @psd: power spectral density (in dBm)
*/
- struct ieee80211_channel {
-@@ -191,6 +193,7 @@ struct ieee80211_channel {
+@@ -206,6 +208,7 @@ struct ieee80211_channel {
int orig_mag, orig_mpwr;
enum nl80211_dfs_state dfs_state;
unsigned long dfs_state_entered;
+ unsigned long dfs_state_last_available;
unsigned int dfs_cac_ms;
+ s8 psd;
};
-
--- a/net/wireless/ap.c
+++ b/net/wireless/ap.c
@@ -30,6 +30,9 @@ static int ___cfg80211_stop_ap(struct cf
--- a/net/wireless/chan.c
+++ b/net/wireless/chan.c
-@@ -461,6 +461,8 @@ static void cfg80211_set_chans_dfs_state
+@@ -560,6 +560,8 @@ static void cfg80211_set_chans_dfs_state
c->dfs_state = dfs_state;
c->dfs_state_entered = jiffies;
}
}
-@@ -874,6 +876,49 @@ static bool cfg80211_get_chans_dfs_avail
+@@ -1049,6 +1051,49 @@ static bool cfg80211_get_chans_dfs_avail
return true;
}
{
--- a/net/wireless/core.h
+++ b/net/wireless/core.h
-@@ -481,6 +481,8 @@ void cfg80211_set_dfs_state(struct wiphy
+@@ -467,6 +467,8 @@ void cfg80211_set_dfs_state(struct wiphy
enum nl80211_dfs_state dfs_state);
void cfg80211_dfs_channels_update_work(struct work_struct *work);
--- a/net/wireless/mlme.c
+++ b/net/wireless/mlme.c
-@@ -930,6 +930,8 @@ void cfg80211_dfs_channels_update_work(s
+@@ -1037,6 +1037,8 @@ void cfg80211_dfs_channels_update_work(s
if (c->dfs_state == NL80211_DFS_UNAVAILABLE) {
time_dfs_update = IEEE80211_DFS_MIN_NOP_TIME_MS;
radar_event = NL80211_RADAR_NOP_FINISHED;
} else {
if (regulatory_pre_cac_allowed(wiphy) ||
cfg80211_any_wiphy_oper_chan(wiphy, c))
-@@ -937,11 +939,10 @@ void cfg80211_dfs_channels_update_work(s
+@@ -1044,11 +1046,10 @@ void cfg80211_dfs_channels_update_work(s
time_dfs_update = REG_PRE_CAC_EXPIRY_GRACE_MS;
radar_event = NL80211_RADAR_PRE_CAC_EXPIRED;
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
-@@ -3324,6 +3324,7 @@ enum wiphy_params_flags {
+@@ -3416,6 +3416,7 @@ enum wiphy_params_flags {
/* The per TXQ device queue limit in airtime */
#define IEEE80211_DEFAULT_AQL_TXQ_LIMIT_L 5000
#define IEEE80211_DEFAULT_AQL_TXQ_LIMIT_H 12000
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
-@@ -1328,10 +1328,12 @@ struct ieee80211_local {
+@@ -1337,10 +1337,12 @@ struct ieee80211_local {
spinlock_t handle_wake_tx_queue_lock;
u16 airtime_flags;
const struct ieee80211_ops *ops;
--- a/net/mac80211/main.c
+++ b/net/mac80211/main.c
-@@ -788,6 +788,7 @@ struct ieee80211_hw *ieee80211_alloc_hw_
+@@ -944,6 +944,7 @@ struct ieee80211_hw *ieee80211_alloc_hw_
spin_lock_init(&local->rx_path_lock);
spin_lock_init(&local->queue_stop_reason_lock);
spin_lock_init(&local->active_txq_lock[i]);
--- a/net/mac80211/sta_info.c
+++ b/net/mac80211/sta_info.c
-@@ -2343,13 +2343,28 @@ EXPORT_SYMBOL(ieee80211_sta_recalc_aggre
+@@ -2357,13 +2357,28 @@ EXPORT_SYMBOL(ieee80211_sta_recalc_aggre
void ieee80211_sta_update_pending_airtime(struct ieee80211_local *local,
struct sta_info *sta, u8 ac,
atomic_add(tx_airtime,
--- a/net/mac80211/tx.c
+++ b/net/mac80211/tx.c
-@@ -2536,7 +2536,7 @@ static u16 ieee80211_store_ack_skb(struc
+@@ -2554,7 +2554,7 @@ static u16 ieee80211_store_ack_skb(struc
spin_lock_irqsave(&local->ack_status_lock, flags);
id = idr_alloc(&local->ack_status_frames, ack_skb,
spin_unlock_irqrestore(&local->ack_status_lock, flags);
if (id >= 0) {
-@@ -3958,20 +3958,20 @@ begin:
+@@ -3983,20 +3983,20 @@ begin:
encap_out:
- IEEE80211_SKB_CB(skb)->control.vif = vif;
+ info->control.vif = vif;
- if (tx.sta &&
- wiphy_ext_feature_isset(local->hw.wiphy, NL80211_EXT_FEATURE_AQL)) {
}
return skb;
-@@ -4026,6 +4026,7 @@ struct ieee80211_txq *ieee80211_next_txq
+@@ -4048,6 +4048,7 @@ struct ieee80211_txq *ieee80211_next_txq
struct ieee80211_txq *ret = NULL;
struct txq_info *txqi = NULL, *head = NULL;
bool found_eligible_txq = false;
spin_lock_bh(&local->active_txq_lock[ac]);
-@@ -4049,26 +4050,26 @@ struct ieee80211_txq *ieee80211_next_txq
+@@ -4071,26 +4072,26 @@ struct ieee80211_txq *ieee80211_next_txq
if (!head)
head = txqi;
if (txqi->schedule_round == local->schedule_round[ac])
goto out;
-@@ -4133,7 +4134,8 @@ bool ieee80211_txq_airtime_check(struct
+@@ -4155,7 +4156,8 @@ bool ieee80211_txq_airtime_check(struct
return true;
if (!txq->sta)
if (unlikely(txq->tid == IEEE80211_NUM_TIDS))
return true;
-@@ -4182,15 +4184,15 @@ bool ieee80211_txq_may_transmit(struct i
+@@ -4204,15 +4206,15 @@ bool ieee80211_txq_may_transmit(struct i
spin_lock_bh(&local->active_txq_lock[ac]);
if (iter == txqi)
--- a/include/net/mac80211.h
+++ b/include/net/mac80211.h
-@@ -1116,6 +1116,7 @@ ieee80211_rate_get_vht_nss(const struct
- * link the frame will be transmitted on
- * @hw_queue: HW queue to put the frame on, skb_get_queue_mapping() gives the AC
- * @ack_frame_id: internal frame ID for TX status, used internally
-+ * @tx_time_mc: TX time is for a multicast packet
- * @tx_time_est: TX time estimate in units of 4us, used internally
- * @control: union part for control data
- * @control.rates: TX rates array to try
-@@ -1155,8 +1156,9 @@ struct ieee80211_tx_info {
- /* common information */
- u32 flags;
- u32 band:3,
-- ack_frame_id:13,
-+ ack_frame_id:12,
+@@ -1180,8 +1180,8 @@ struct ieee80211_tx_info {
+ status_data_idr:1,
+ status_data:13,
hw_queue:4,
+ tx_time_mc:1,
tx_time_est:10;
- /* 2 free bits */
+- /* 1 free bit */
+ union {
+ struct {
--- a/net/mac80211/sta_info.h
+++ b/net/mac80211/sta_info.h
@@ -147,7 +147,8 @@ struct airtime_info {
--- a/net/mac80211/status.c
+++ b/net/mac80211/status.c
-@@ -716,7 +716,7 @@ static void ieee80211_report_used_skb(st
+@@ -717,7 +717,7 @@ static void ieee80211_report_used_skb(st
ieee80211_sta_update_pending_airtime(local, sta,
skb_get_queue_mapping(skb),
tx_time_est,
rcu_read_unlock();
}
-@@ -1127,10 +1127,11 @@ void ieee80211_tx_status_ext(struct ieee
+@@ -1138,10 +1138,11 @@ void ieee80211_tx_status_ext(struct ieee
/* Do this here to avoid the expensive lookup of the sta
* in ieee80211_report_used_skb().
*/
+++ /dev/null
-From: Felix Fietkau <nbd@nbd.name>
-Date: Wed, 21 Feb 2024 14:41:40 +0100
-Subject: [PATCH] wifi: mac80211: only call drv_sta_rc_update for uploaded
- stations
-
-When a station has not been uploaded yet, receiving SMPS or channel width
-notification action frames can lead to rate_control_rate_update calling
-drv_sta_rc_update with uninitialized driver private data.
-Fix this by adding a missing check for sta->uploaded.
-
-Signed-off-by: Felix Fietkau <nbd@nbd.name>
----
-
---- a/net/mac80211/rate.c
-+++ b/net/mac80211/rate.c
-@@ -119,7 +119,8 @@ void rate_control_rate_update(struct iee
- rcu_read_unlock();
- }
-
-- drv_sta_rc_update(local, sta->sdata, &sta->sta, changed);
-+ if (sta->uploaded)
-+ drv_sta_rc_update(local, sta->sdata, &sta->sta, changed);
- }
-
- int ieee80211_rate_control_register(const struct rate_control_ops *ops)
+++ /dev/null
-From: Felix Fietkau <nbd@nbd.name>
-Date: Sat, 16 Mar 2024 08:37:21 +0100
-Subject: [PATCH] wifi: mac80211: check/clear fast rx for non-4addr sta VLAN
- changes
-
-When moving a station out of a VLAN and deleting the VLAN afterwards, the
-fast_rx entry still holds a pointer to the VLAN's netdev, which can cause
-use-after-free bugs. Fix this by immediately calling ieee80211_check_fast_rx
-after the VLAN change.
-
-Cc: stable@vger.kernel.org
-Reported-by: ranygh@riseup.net
-Signed-off-by: Felix Fietkau <nbd@nbd.name>
----
-
---- a/net/mac80211/cfg.c
-+++ b/net/mac80211/cfg.c
-@@ -2184,15 +2184,14 @@ static int ieee80211_change_station(stru
- }
-
- if (sta->sdata->vif.type == NL80211_IFTYPE_AP_VLAN &&
-- sta->sdata->u.vlan.sta) {
-- ieee80211_clear_fast_rx(sta);
-+ sta->sdata->u.vlan.sta)
- RCU_INIT_POINTER(sta->sdata->u.vlan.sta, NULL);
-- }
-
- if (test_sta_flag(sta, WLAN_STA_AUTHORIZED))
- ieee80211_vif_dec_num_mcast(sta->sdata);
-
- sta->sdata = vlansdata;
-+ ieee80211_check_fast_rx(sta);
- ieee80211_check_fast_xmit(sta);
-
- if (test_sta_flag(sta, WLAN_STA_AUTHORIZED)) {
--- a/net/mac80211/sta_info.c
+++ b/net/mac80211/sta_info.c
-@@ -2445,6 +2445,13 @@ static void sta_stats_decode_rate(struct
+@@ -2459,6 +2459,13 @@ static void sta_stats_decode_rate(struct
sband = local->hw.wiphy->bands[band];
--- /dev/null
+commit 4060c836fcae5d815de922b6e3934305696a6abb
+Author: Felix Fietkau <nbd@nbd.name>
+Date: Sun May 19 14:14:12 2024 +0200
+
+ mt76: sync with upstream changes
+
+ Signed-off-by: Felix Fietkau <nbd@nbd.name>
+
+diff --git a/mac80211.c b/mac80211.c
+index aac110953c2a..2a3f2b23cc16 100644
+--- a/mac80211.c
++++ b/mac80211.c
+@@ -1626,8 +1626,8 @@ EXPORT_SYMBOL_GPL(mt76_get_sar_power);
+ static void
+ __mt76_csa_finish(void *priv, u8 *mac, struct ieee80211_vif *vif)
+ {
+- if (vif->bss_conf.csa_active && ieee80211_beacon_cntdwn_is_complete(vif))
+- ieee80211_csa_finish(vif);
++ if (vif->bss_conf.csa_active && ieee80211_beacon_cntdwn_is_complete(vif, 0))
++ ieee80211_csa_finish(vif, 0);
+ }
+
+ void mt76_csa_finish(struct mt76_dev *dev)
+@@ -1651,7 +1651,7 @@ __mt76_csa_check(void *priv, u8 *mac, struct ieee80211_vif *vif)
+ if (!vif->bss_conf.csa_active)
+ return;
+
+- dev->csa_complete |= ieee80211_beacon_cntdwn_is_complete(vif);
++ dev->csa_complete |= ieee80211_beacon_cntdwn_is_complete(vif, 0);
+ }
+
+ void mt76_csa_check(struct mt76_dev *dev)
+diff --git a/mt76.h b/mt76.h
+index 465b6b24848f..eeddbdfc8f88 100644
+--- a/mt76.h
++++ b/mt76.h
+@@ -1617,6 +1617,18 @@ s8 mt76_get_rate_power_limits(struct mt76_phy *phy,
+ struct mt76_power_limits *dest,
+ s8 target_power);
+
++static inline bool mt76_queue_is_rx(struct mt76_dev *dev, struct mt76_queue *q)
++{
++ int i;
++
++ for (i = 0; i < ARRAY_SIZE(dev->q_rx); i++) {
++ if (q == &dev->q_rx[i])
++ return true;
++ }
++
++ return false;
++}
++
+ static inline bool mt76_queue_is_wed_tx_free(struct mt76_queue *q)
+ {
+ return (q->flags & MT_QFLAG_WED) &&
+diff --git a/mt7603/main.c b/mt7603/main.c
+index c88909a18c4e..0961df3addf5 100644
+--- a/mt7603/main.c
++++ b/mt7603/main.c
+@@ -707,6 +707,10 @@ static void mt7603_tx(struct ieee80211_hw *hw,
+ }
+
+ const struct ieee80211_ops mt7603_ops = {
++ .add_chanctx = ieee80211_emulate_add_chanctx,
++ .remove_chanctx = ieee80211_emulate_remove_chanctx,
++ .change_chanctx = ieee80211_emulate_change_chanctx,
++ .switch_vif_chanctx = ieee80211_emulate_switch_vif_chanctx,
+ .tx = mt7603_tx,
+ .start = mt7603_start,
+ .stop = mt7603_stop,
+@@ -734,6 +738,7 @@ const struct ieee80211_ops mt7603_ops = {
+ .set_sar_specs = mt7603_set_sar_specs,
+ };
+
++MODULE_DESCRIPTION("MediaTek MT7603E and MT76x8 wireless driver");
+ MODULE_LICENSE("Dual BSD/GPL");
+
+ static int __init mt7603_init(void)
+diff --git a/mt7615/Kconfig b/mt7615/Kconfig
+index 30fba36ff46b..1ab1439143f4 100644
+--- a/mt7615/Kconfig
++++ b/mt7615/Kconfig
+@@ -11,7 +11,7 @@ config MT7615E
+ depends on MAC80211
+ depends on PCI
+ help
+- This adds support for MT7615-based wireless PCIe devices,
++ This adds support for MT7615-based PCIe wireless devices,
+ which support concurrent dual-band operation at both 5GHz
+ and 2.4GHz, IEEE 802.11ac 4x4:4SS 1733Mbps PHY rate, wave2
+ MU-MIMO up to 4 users/group and 160MHz channels.
+diff --git a/mt7615/main.c b/mt7615/main.c
+index dab16b5fc386..0971c164b57e 100644
+--- a/mt7615/main.c
++++ b/mt7615/main.c
+@@ -1375,4 +1375,5 @@ const struct ieee80211_ops mt7615_ops = {
+ };
+ EXPORT_SYMBOL_GPL(mt7615_ops);
+
++MODULE_DESCRIPTION("MediaTek MT7615E and MT7663E wireless driver");
+ MODULE_LICENSE("Dual BSD/GPL");
+diff --git a/mt7615/mcu.c b/mt7615/mcu.c
+index 804d6ec71157..10c6ea047ed5 100644
+--- a/mt7615/mcu.c
++++ b/mt7615/mcu.c
+@@ -353,7 +353,7 @@ static void
+ mt7615_mcu_csa_finish(void *priv, u8 *mac, struct ieee80211_vif *vif)
+ {
+ if (vif->bss_conf.csa_active)
+- ieee80211_csa_finish(vif);
++ ieee80211_csa_finish(vif, 0);
+ }
+
+ static void
+diff --git a/mt7615/mmio.c b/mt7615/mmio.c
+index ac036a072439..87a956ea3ad7 100644
+--- a/mt7615/mmio.c
++++ b/mt7615/mmio.c
+@@ -270,4 +270,5 @@ static void __exit mt7615_exit(void)
+
+ module_init(mt7615_init);
+ module_exit(mt7615_exit);
++MODULE_DESCRIPTION("MediaTek MT7615E MMIO helpers");
+ MODULE_LICENSE("Dual BSD/GPL");
+diff --git a/mt7615/sdio.c b/mt7615/sdio.c
+index fa2328802752..9692890ba51b 100644
+--- a/mt7615/sdio.c
++++ b/mt7615/sdio.c
+@@ -180,7 +180,6 @@ static void mt7663s_remove(struct sdio_func *func)
+ mt76_free_device(&dev->mt76);
+ }
+
+-#ifdef CONFIG_PM
+ static int mt7663s_suspend(struct device *dev)
+ {
+ struct sdio_func *func = dev_to_sdio_func(dev);
+@@ -235,31 +234,24 @@ static int mt7663s_resume(struct device *dev)
+ return err;
+ }
+
+-static const struct dev_pm_ops mt7663s_pm_ops = {
+- .suspend = mt7663s_suspend,
+- .resume = mt7663s_resume,
+-};
+-#endif
+-
+ MODULE_DEVICE_TABLE(sdio, mt7663s_table);
+ MODULE_FIRMWARE(MT7663_OFFLOAD_FIRMWARE_N9);
+ MODULE_FIRMWARE(MT7663_OFFLOAD_ROM_PATCH);
+ MODULE_FIRMWARE(MT7663_FIRMWARE_N9);
+ MODULE_FIRMWARE(MT7663_ROM_PATCH);
+
++static DEFINE_SIMPLE_DEV_PM_OPS(mt7663s_pm_ops, mt7663s_suspend, mt7663s_resume);
++
+ static struct sdio_driver mt7663s_driver = {
+ .name = KBUILD_MODNAME,
+ .probe = mt7663s_probe,
+ .remove = mt7663s_remove,
+ .id_table = mt7663s_table,
+-#ifdef CONFIG_PM
+- .drv = {
+- .pm = &mt7663s_pm_ops,
+- }
+-#endif
++ .drv.pm = pm_sleep_ptr(&mt7663s_pm_ops),
+ };
+ module_sdio_driver(mt7663s_driver);
+
+ MODULE_AUTHOR("Sean Wang <sean.wang@mediatek.com>");
+ MODULE_AUTHOR("Lorenzo Bianconi <lorenzo@kernel.org>");
++MODULE_DESCRIPTION("MediaTek MT7663S (SDIO) wireless driver");
+ MODULE_LICENSE("Dual BSD/GPL");
+diff --git a/mt7615/usb.c b/mt7615/usb.c
+index 04963b9f7498..df737e1ff27b 100644
+--- a/mt7615/usb.c
++++ b/mt7615/usb.c
+@@ -281,4 +281,5 @@ module_usb_driver(mt7663u_driver);
+
+ MODULE_AUTHOR("Sean Wang <sean.wang@mediatek.com>");
+ MODULE_AUTHOR("Lorenzo Bianconi <lorenzo@kernel.org>");
++MODULE_DESCRIPTION("MediaTek MT7663U (USB) wireless driver");
+ MODULE_LICENSE("Dual BSD/GPL");
+diff --git a/mt7615/usb_sdio.c b/mt7615/usb_sdio.c
+index 0052d103e276..820b39590027 100644
+--- a/mt7615/usb_sdio.c
++++ b/mt7615/usb_sdio.c
+@@ -349,4 +349,5 @@ EXPORT_SYMBOL_GPL(mt7663_usb_sdio_register_device);
+
+ MODULE_AUTHOR("Lorenzo Bianconi <lorenzo@kernel.org>");
+ MODULE_AUTHOR("Sean Wang <sean.wang@mediatek.com>");
++MODULE_DESCRIPTION("MediaTek MT7663 SDIO/USB helpers");
+ MODULE_LICENSE("Dual BSD/GPL");
+diff --git a/mt76_connac_mcu.c b/mt76_connac_mcu.c
+index 14fde16ecd97..95a44d6dd6b0 100644
+--- a/mt76_connac_mcu.c
++++ b/mt76_connac_mcu.c
+@@ -3170,4 +3170,5 @@ exit:
+ EXPORT_SYMBOL_GPL(mt76_connac2_mcu_fill_message);
+
+ MODULE_AUTHOR("Lorenzo Bianconi <lorenzo@kernel.org>");
++MODULE_DESCRIPTION("MediaTek MT76x connac layer helpers");
+ MODULE_LICENSE("Dual BSD/GPL");
+diff --git a/mt76_connac_mcu.h b/mt76_connac_mcu.h
+index b080fb853bd9..c976e76c3432 100644
+--- a/mt76_connac_mcu.h
++++ b/mt76_connac_mcu.h
+@@ -128,7 +128,7 @@ struct mt76_connac2_mcu_rxd {
+ u8 rsv1[2];
+ u8 s2d_index;
+
+- u8 tlv[0];
++ u8 tlv[];
+ };
+
+ struct mt76_connac2_patch_hdr {
+@@ -1460,7 +1460,7 @@ struct mt76_connac_beacon_loss_event {
+ } __packed;
+
+ struct mt76_connac_rssi_notify_event {
+- s32 rssi[4];
++ __le32 rssi[4];
+ } __packed;
+
+ struct mt76_connac_mcu_bss_event {
+diff --git a/mt76x0/eeprom.c b/mt76x0/eeprom.c
+index c3a392a1a659..bcd24c9072ec 100644
+--- a/mt76x0/eeprom.c
++++ b/mt76x0/eeprom.c
+@@ -342,4 +342,5 @@ int mt76x0_eeprom_init(struct mt76x02_dev *dev)
+ return 0;
+ }
+
++MODULE_DESCRIPTION("MediaTek MT76x EEPROM helpers");
+ MODULE_LICENSE("Dual BSD/GPL");
+diff --git a/mt76x0/pci.c b/mt76x0/pci.c
+index 9277ff38b7a2..79b7996ad1a8 100644
+--- a/mt76x0/pci.c
++++ b/mt76x0/pci.c
+@@ -59,6 +59,10 @@ mt76x0e_flush(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
+ }
+
+ static const struct ieee80211_ops mt76x0e_ops = {
++ .add_chanctx = ieee80211_emulate_add_chanctx,
++ .remove_chanctx = ieee80211_emulate_remove_chanctx,
++ .change_chanctx = ieee80211_emulate_change_chanctx,
++ .switch_vif_chanctx = ieee80211_emulate_switch_vif_chanctx,
+ .tx = mt76x02_tx,
+ .start = mt76x0e_start,
+ .stop = mt76x0e_stop,
+@@ -302,6 +306,7 @@ static const struct pci_device_id mt76x0e_device_table[] = {
+ MODULE_DEVICE_TABLE(pci, mt76x0e_device_table);
+ MODULE_FIRMWARE(MT7610E_FIRMWARE);
+ MODULE_FIRMWARE(MT7650E_FIRMWARE);
++MODULE_DESCRIPTION("MediaTek MT76x0E (PCIe) wireless driver");
+ MODULE_LICENSE("Dual BSD/GPL");
+
+ static struct pci_driver mt76x0e_driver = {
+diff --git a/mt76x0/usb.c b/mt76x0/usb.c
+index 0422c332354a..bba44f289b4e 100644
+--- a/mt76x0/usb.c
++++ b/mt76x0/usb.c
+@@ -118,6 +118,10 @@ static int mt76x0u_start(struct ieee80211_hw *hw)
+ }
+
+ static const struct ieee80211_ops mt76x0u_ops = {
++ .add_chanctx = ieee80211_emulate_add_chanctx,
++ .remove_chanctx = ieee80211_emulate_remove_chanctx,
++ .change_chanctx = ieee80211_emulate_change_chanctx,
++ .switch_vif_chanctx = ieee80211_emulate_switch_vif_chanctx,
+ .tx = mt76x02_tx,
+ .start = mt76x0u_start,
+ .stop = mt76x0u_stop,
+@@ -336,6 +340,7 @@ err:
+ MODULE_DEVICE_TABLE(usb, mt76x0_device_table);
+ MODULE_FIRMWARE(MT7610E_FIRMWARE);
+ MODULE_FIRMWARE(MT7610U_FIRMWARE);
++MODULE_DESCRIPTION("MediaTek MT76x0U (USB) wireless driver");
+ MODULE_LICENSE("GPL");
+
+ static struct usb_driver mt76x0_driver = {
+diff --git a/mt76x02_usb_mcu.c b/mt76x02_usb_mcu.c
+index 02da543dfc5c..b2cc44914294 100644
+--- a/mt76x02_usb_mcu.c
++++ b/mt76x02_usb_mcu.c
+@@ -293,4 +293,5 @@ void mt76x02u_init_mcu(struct mt76_dev *dev)
+ EXPORT_SYMBOL_GPL(mt76x02u_init_mcu);
+
+ MODULE_AUTHOR("Lorenzo Bianconi <lorenzo.bianconi83@gmail.com>");
++MODULE_DESCRIPTION("MediaTek MT76x02 MCU helpers");
+ MODULE_LICENSE("Dual BSD/GPL");
+diff --git a/mt76x02_util.c b/mt76x02_util.c
+index 8a0e8124b894..8020446be37b 100644
+--- a/mt76x02_util.c
++++ b/mt76x02_util.c
+@@ -696,4 +696,5 @@ void mt76x02_config_mac_addr_list(struct mt76x02_dev *dev)
+ }
+ EXPORT_SYMBOL_GPL(mt76x02_config_mac_addr_list);
+
++MODULE_DESCRIPTION("MediaTek MT76x02 helpers");
+ MODULE_LICENSE("Dual BSD/GPL");
+diff --git a/mt76x2/eeprom.c b/mt76x2/eeprom.c
+index 8c01855885ce..1fe5f5a02f93 100644
+--- a/mt76x2/eeprom.c
++++ b/mt76x2/eeprom.c
+@@ -506,4 +506,5 @@ int mt76x2_eeprom_init(struct mt76x02_dev *dev)
+ }
+ EXPORT_SYMBOL_GPL(mt76x2_eeprom_init);
+
++MODULE_DESCRIPTION("MediaTek MT76x2 EEPROM helpers");
+ MODULE_LICENSE("Dual BSD/GPL");
+diff --git a/mt76x2/pci.c b/mt76x2/pci.c
+index df85ebc6e1df..30959746e924 100644
+--- a/mt76x2/pci.c
++++ b/mt76x2/pci.c
+@@ -165,6 +165,7 @@ mt76x2e_resume(struct pci_dev *pdev)
+ MODULE_DEVICE_TABLE(pci, mt76x2e_device_table);
+ MODULE_FIRMWARE(MT7662_FIRMWARE);
+ MODULE_FIRMWARE(MT7662_ROM_PATCH);
++MODULE_DESCRIPTION("MediaTek MT76x2E (PCIe) wireless driver");
+ MODULE_LICENSE("Dual BSD/GPL");
+
+ static struct pci_driver mt76pci_driver = {
+diff --git a/mt76x2/pci_main.c b/mt76x2/pci_main.c
+index b38bb7a2362b..bfc8c69f43fa 100644
+--- a/mt76x2/pci_main.c
++++ b/mt76x2/pci_main.c
+@@ -132,6 +132,10 @@ static int mt76x2_set_antenna(struct ieee80211_hw *hw, u32 tx_ant,
+ }
+
+ const struct ieee80211_ops mt76x2_ops = {
++ .add_chanctx = ieee80211_emulate_add_chanctx,
++ .remove_chanctx = ieee80211_emulate_remove_chanctx,
++ .change_chanctx = ieee80211_emulate_change_chanctx,
++ .switch_vif_chanctx = ieee80211_emulate_switch_vif_chanctx,
+ .tx = mt76x02_tx,
+ .start = mt76x2_start,
+ .stop = mt76x2_stop,
+diff --git a/mt76x2/usb.c b/mt76x2/usb.c
+index e0643b0dfdc5..e92bb871f231 100644
+--- a/mt76x2/usb.c
++++ b/mt76x2/usb.c
+@@ -148,4 +148,5 @@ static struct usb_driver mt76x2u_driver = {
+ module_usb_driver(mt76x2u_driver);
+
+ MODULE_AUTHOR("Lorenzo Bianconi <lorenzo.bianconi83@gmail.com>");
++MODULE_DESCRIPTION("MediaTek MT76x2U (USB) wireless driver");
+ MODULE_LICENSE("Dual BSD/GPL");
+diff --git a/mt76x2/usb_main.c b/mt76x2/usb_main.c
+index ac07ed1f63a3..9fe390fdd730 100644
+--- a/mt76x2/usb_main.c
++++ b/mt76x2/usb_main.c
+@@ -103,6 +103,10 @@ mt76x2u_config(struct ieee80211_hw *hw, u32 changed)
+ }
+
+ const struct ieee80211_ops mt76x2u_ops = {
++ .add_chanctx = ieee80211_emulate_add_chanctx,
++ .remove_chanctx = ieee80211_emulate_remove_chanctx,
++ .change_chanctx = ieee80211_emulate_change_chanctx,
++ .switch_vif_chanctx = ieee80211_emulate_switch_vif_chanctx,
+ .tx = mt76x02_tx,
+ .start = mt76x2u_start,
+ .stop = mt76x2u_stop,
+diff --git a/mt7915/Kconfig b/mt7915/Kconfig
+index 896ec38c23d9..193112c49bd1 100644
+--- a/mt7915/Kconfig
++++ b/mt7915/Kconfig
+@@ -7,7 +7,7 @@ config MT7915E
+ depends on PCI
+ select RELAY
+ help
+- This adds support for MT7915-based wireless PCIe devices,
++ This adds support for MT7915-based PCIe wireless devices,
+ which support concurrent dual-band operation at both 5GHz
+ and 2.4GHz IEEE 802.11ax 4x4:4SS 1024-QAM, 160MHz channels,
+ OFDMA, spatial reuse and dual carrier modulation.
+diff --git a/mt7915/init.c b/mt7915/init.c
+index eee1879892ab..f1ef965f0be0 100644
+--- a/mt7915/init.c
++++ b/mt7915/init.c
+@@ -4,6 +4,7 @@
+ #include <linux/etherdevice.h>
+ #include <linux/hwmon.h>
+ #include <linux/hwmon-sysfs.h>
++#include <linux/of.h>
+ #include <linux/thermal.h>
+ #include "mt7915.h"
+ #include "mac.h"
+@@ -1151,8 +1152,7 @@ void mt7915_set_stream_he_caps(struct mt7915_phy *phy)
+ n = mt7915_init_he_caps(phy, NL80211_BAND_2GHZ, data);
+
+ band = &phy->mt76->sband_2g.sband;
+- band->iftype_data = data;
+- band->n_iftype_data = n;
++ _ieee80211_set_sband_iftype_data(band, data, n);
+ }
+
+ if (phy->mt76->cap.has_5ghz) {
+@@ -1160,8 +1160,7 @@ void mt7915_set_stream_he_caps(struct mt7915_phy *phy)
+ n = mt7915_init_he_caps(phy, NL80211_BAND_5GHZ, data);
+
+ band = &phy->mt76->sband_5g.sband;
+- band->iftype_data = data;
+- band->n_iftype_data = n;
++ _ieee80211_set_sband_iftype_data(band, data, n);
+ }
+
+ if (phy->mt76->cap.has_6ghz) {
+@@ -1169,8 +1168,7 @@ void mt7915_set_stream_he_caps(struct mt7915_phy *phy)
+ n = mt7915_init_he_caps(phy, NL80211_BAND_6GHZ, data);
+
+ band = &phy->mt76->sband_6g.sband;
+- band->iftype_data = data;
+- band->n_iftype_data = n;
++ _ieee80211_set_sband_iftype_data(band, data, n);
+ }
+ }
+
+diff --git a/mt7915/main.c b/mt7915/main.c
+index b47b39be8e36..2e36c9f35099 100644
+--- a/mt7915/main.c
++++ b/mt7915/main.c
+@@ -1703,6 +1703,10 @@ mt7915_net_fill_forward_path(struct ieee80211_hw *hw,
+ #endif
+
+ const struct ieee80211_ops mt7915_ops = {
++ .add_chanctx = ieee80211_emulate_add_chanctx,
++ .remove_chanctx = ieee80211_emulate_remove_chanctx,
++ .change_chanctx = ieee80211_emulate_change_chanctx,
++ .switch_vif_chanctx = ieee80211_emulate_switch_vif_chanctx,
+ .tx = mt7915_tx,
+ .start = mt7915_start,
+ .stop = mt7915_stop,
+diff --git a/mt7915/mcu.c b/mt7915/mcu.c
+index 6ca12156d8ff..f85af872bf7e 100644
+--- a/mt7915/mcu.c
++++ b/mt7915/mcu.c
+@@ -228,7 +228,7 @@ mt7915_mcu_csa_finish(void *priv, u8 *mac, struct ieee80211_vif *vif)
+ if (!vif->bss_conf.csa_active || vif->type == NL80211_IFTYPE_STATION)
+ return;
+
+- ieee80211_csa_finish(vif);
++ ieee80211_csa_finish(vif, 0);
+ }
+
+ static void
+@@ -463,10 +463,10 @@ static bool mt7915_check_he_obss_narrow_bw_ru(struct ieee80211_hw *hw,
+ .tolerated = true,
+ };
+
+- if (!(vif->bss_conf.chandef.chan->flags & IEEE80211_CHAN_RADAR))
++ if (!(vif->bss_conf.chanreq.oper.chan->flags & IEEE80211_CHAN_RADAR))
+ return false;
+
+- cfg80211_bss_iter(hw->wiphy, &vif->bss_conf.chandef,
++ cfg80211_bss_iter(hw->wiphy, &vif->bss_conf.chanreq.oper,
+ mt7915_check_he_obss_narrow_bw_ru_iter,
+ &iter_data);
+
+diff --git a/mt7915/mmio.c b/mt7915/mmio.c
+index 2131ffb6e475..252580b77465 100644
+--- a/mt7915/mmio.c
++++ b/mt7915/mmio.c
+@@ -994,4 +994,5 @@ static void __exit mt7915_exit(void)
+
+ module_init(mt7915_init);
+ module_exit(mt7915_exit);
++MODULE_DESCRIPTION("MediaTek MT7915E MMIO helpers");
+ MODULE_LICENSE("Dual BSD/GPL");
+diff --git a/mt7921/main.c b/mt7921/main.c
+index 26045e771b73..c3b537583e44 100644
+--- a/mt7921/main.c
++++ b/mt7921/main.c
+@@ -196,8 +196,7 @@ void mt7921_set_stream_he_caps(struct mt792x_phy *phy)
+ n = mt7921_init_he_caps(phy, NL80211_BAND_2GHZ, data);
+
+ band = &phy->mt76->sband_2g.sband;
+- band->iftype_data = data;
+- band->n_iftype_data = n;
++ _ieee80211_set_sband_iftype_data(band, data, n);
+ }
+
+ if (phy->mt76->cap.has_5ghz) {
+@@ -205,16 +204,14 @@ void mt7921_set_stream_he_caps(struct mt792x_phy *phy)
+ n = mt7921_init_he_caps(phy, NL80211_BAND_5GHZ, data);
+
+ band = &phy->mt76->sband_5g.sband;
+- band->iftype_data = data;
+- band->n_iftype_data = n;
++ _ieee80211_set_sband_iftype_data(band, data, n);
+
+ if (phy->mt76->cap.has_6ghz) {
+ data = phy->iftype[NL80211_BAND_6GHZ];
+ n = mt7921_init_he_caps(phy, NL80211_BAND_6GHZ, data);
+
+ band = &phy->mt76->sband_6g.sband;
+- band->iftype_data = data;
+- band->n_iftype_data = n;
++ _ieee80211_set_sband_iftype_data(band, data, n);
+ }
+ }
+ }
+@@ -1469,5 +1466,6 @@ const struct ieee80211_ops mt7921_ops = {
+ };
+ EXPORT_SYMBOL_GPL(mt7921_ops);
+
++MODULE_DESCRIPTION("MediaTek MT7921 core driver");
+ MODULE_LICENSE("Dual BSD/GPL");
+ MODULE_AUTHOR("Sean Wang <sean.wang@mediatek.com>");
+diff --git a/mt7921/pci.c b/mt7921/pci.c
+index f519c52bbd15..81cd14546932 100644
+--- a/mt7921/pci.c
++++ b/mt7921/pci.c
+@@ -570,4 +570,5 @@ MODULE_FIRMWARE(MT7922_FIRMWARE_WM);
+ MODULE_FIRMWARE(MT7922_ROM_PATCH);
+ MODULE_AUTHOR("Sean Wang <sean.wang@mediatek.com>");
+ MODULE_AUTHOR("Lorenzo Bianconi <lorenzo@kernel.org>");
++MODULE_DESCRIPTION("MediaTek MT7921E (PCIe) wireless driver");
+ MODULE_LICENSE("Dual BSD/GPL");
+diff --git a/mt7921/sdio.c b/mt7921/sdio.c
+index 47e19023e2ba..497c9fc01bbd 100644
+--- a/mt7921/sdio.c
++++ b/mt7921/sdio.c
+@@ -201,7 +201,6 @@ static void mt7921s_remove(struct sdio_func *func)
+ mt7921s_unregister_device(dev);
+ }
+
+-#ifdef CONFIG_PM
+ static int mt7921s_suspend(struct device *__dev)
+ {
+ struct sdio_func *func = dev_to_sdio_func(__dev);
+@@ -312,27 +311,20 @@ failed:
+ return err;
+ }
+
+-static const struct dev_pm_ops mt7921s_pm_ops = {
+- .suspend = mt7921s_suspend,
+- .resume = mt7921s_resume,
+-};
+-#endif
+-
+ MODULE_DEVICE_TABLE(sdio, mt7921s_table);
+ MODULE_FIRMWARE(MT7921_FIRMWARE_WM);
+ MODULE_FIRMWARE(MT7921_ROM_PATCH);
+
++static DEFINE_SIMPLE_DEV_PM_OPS(mt7921s_pm_ops, mt7921s_suspend, mt7921s_resume);
++
+ static struct sdio_driver mt7921s_driver = {
+ .name = KBUILD_MODNAME,
+ .probe = mt7921s_probe,
+ .remove = mt7921s_remove,
+ .id_table = mt7921s_table,
+-#ifdef CONFIG_PM
+- .drv = {
+- .pm = &mt7921s_pm_ops,
+- }
+-#endif
++ .drv.pm = pm_sleep_ptr(&mt7921s_pm_ops),
+ };
+ module_sdio_driver(mt7921s_driver);
++MODULE_DESCRIPTION("MediaTek MT7921S (SDIO) wireless driver");
+ MODULE_AUTHOR("Sean Wang <sean.wang@mediatek.com>");
+ MODULE_LICENSE("Dual BSD/GPL");
+diff --git a/mt7921/usb.c b/mt7921/usb.c
+index 1b0f3a862fba..d944ac042d59 100644
+--- a/mt7921/usb.c
++++ b/mt7921/usb.c
+@@ -336,5 +336,6 @@ static struct usb_driver mt7921u_driver = {
+ };
+ module_usb_driver(mt7921u_driver);
+
++MODULE_DESCRIPTION("MediaTek MT7921U (USB) wireless driver");
+ MODULE_AUTHOR("Lorenzo Bianconi <lorenzo@kernel.org>");
+ MODULE_LICENSE("Dual BSD/GPL");
+diff --git a/mt7925/main.c b/mt7925/main.c
+index 24a99aabe5b9..adfeef619617 100644
+--- a/mt7925/main.c
++++ b/mt7925/main.c
+@@ -14,7 +14,7 @@
+ static void
+ mt7925_init_he_caps(struct mt792x_phy *phy, enum nl80211_band band,
+ struct ieee80211_sband_iftype_data *data,
+- enum nl80211_iftype iftype)
++ enum nl80211_iftype iftype)
+ {
+ struct ieee80211_sta_he_cap *he_cap = &data->he_cap;
+ struct ieee80211_he_cap_elem *he_cap_elem = &he_cap->he_cap_elem;
+@@ -53,7 +53,7 @@ mt7925_init_he_caps(struct mt792x_phy *phy, enum nl80211_band band,
+ IEEE80211_HE_PHY_CAP2_UL_MU_FULL_MU_MIMO |
+ IEEE80211_HE_PHY_CAP2_UL_MU_PARTIAL_MU_MIMO;
+
+- switch (i) {
++ switch (iftype) {
+ case NL80211_IFTYPE_AP:
+ he_cap_elem->mac_cap_info[2] |=
+ IEEE80211_HE_MAC_CAP2_BSR;
+@@ -1475,4 +1475,5 @@ const struct ieee80211_ops mt7925_ops = {
+ EXPORT_SYMBOL_GPL(mt7925_ops);
+
+ MODULE_AUTHOR("Deren Wu <deren.wu@mediatek.com>");
++MODULE_DESCRIPTION("MediaTek MT7925 core driver");
+ MODULE_LICENSE("Dual BSD/GPL");
+diff --git a/mt7925/pci.c b/mt7925/pci.c
+index b3241559619b..79d74a485df4 100644
+--- a/mt7925/pci.c
++++ b/mt7925/pci.c
+@@ -586,4 +586,5 @@ MODULE_FIRMWARE(MT7925_FIRMWARE_WM);
+ MODULE_FIRMWARE(MT7925_ROM_PATCH);
+ MODULE_AUTHOR("Deren Wu <deren.wu@mediatek.com>");
+ MODULE_AUTHOR("Lorenzo Bianconi <lorenzo@kernel.org>");
++MODULE_DESCRIPTION("MediaTek MT7925E (PCIe) wireless driver");
+ MODULE_LICENSE("Dual BSD/GPL");
+diff --git a/mt7925/usb.c b/mt7925/usb.c
+index 43cc62b46dd1..682db1bab21c 100644
+--- a/mt7925/usb.c
++++ b/mt7925/usb.c
+@@ -329,4 +329,5 @@ static struct usb_driver mt7925u_driver = {
+ module_usb_driver(mt7925u_driver);
+
+ MODULE_AUTHOR("Lorenzo Bianconi <lorenzo@kernel.org>");
++MODULE_DESCRIPTION("MediaTek MT7925U (USB) wireless driver");
+ MODULE_LICENSE("Dual BSD/GPL");
+diff --git a/mt792x_core.c b/mt792x_core.c
+index fb35eff6dc7b..a405af8d9052 100644
+--- a/mt792x_core.c
++++ b/mt792x_core.c
+@@ -685,9 +685,10 @@ mt792x_get_mac80211_ops(struct device *dev,
+ if (!(*fw_features & MT792x_FW_CAP_CNM)) {
+ ops->remain_on_channel = NULL;
+ ops->cancel_remain_on_channel = NULL;
+- ops->add_chanctx = NULL;
+- ops->remove_chanctx = NULL;
+- ops->change_chanctx = NULL;
++ ops->add_chanctx = ieee80211_emulate_add_chanctx;
++ ops->remove_chanctx = ieee80211_emulate_remove_chanctx;
++ ops->change_chanctx = ieee80211_emulate_change_chanctx;
++ ops->switch_vif_chanctx = ieee80211_emulate_switch_vif_chanctx;
+ ops->assign_vif_chanctx = NULL;
+ ops->unassign_vif_chanctx = NULL;
+ ops->mgd_prepare_tx = NULL;
+@@ -863,5 +864,6 @@ int mt792x_load_firmware(struct mt792x_dev *dev)
+ }
+ EXPORT_SYMBOL_GPL(mt792x_load_firmware);
+
++MODULE_DESCRIPTION("MediaTek MT792x core driver");
+ MODULE_LICENSE("Dual BSD/GPL");
+ MODULE_AUTHOR("Lorenzo Bianconi <lorenzo@kernel.org>");
+diff --git a/mt792x_usb.c b/mt792x_usb.c
+index fbf49da16b92..b49668a4b784 100644
+--- a/mt792x_usb.c
++++ b/mt792x_usb.c
+@@ -312,5 +312,6 @@ void mt792xu_disconnect(struct usb_interface *usb_intf)
+ }
+ EXPORT_SYMBOL_GPL(mt792xu_disconnect);
+
++MODULE_DESCRIPTION("MediaTek MT792x USB helpers");
+ MODULE_LICENSE("Dual BSD/GPL");
+ MODULE_AUTHOR("Lorenzo Bianconi <lorenzo@kernel.org>");
+diff --git a/mt7996/init.c b/mt7996/init.c
+index 9aa97e4a7f55..283df84f1b43 100644
+--- a/mt7996/init.c
++++ b/mt7996/init.c
+@@ -4,9 +4,10 @@
+ */
+
+ #include <linux/etherdevice.h>
+-#include <linux/thermal.h>
++#include <linux/of.h>
+ #include <linux/hwmon.h>
+ #include <linux/hwmon-sysfs.h>
++#include <linux/thermal.h>
+ #include "mt7996.h"
+ #include "mac.h"
+ #include "mcu.h"
+@@ -1278,8 +1279,7 @@ __mt7996_set_stream_he_eht_caps(struct mt7996_phy *phy,
+ n++;
+ }
+
+- sband->iftype_data = data;
+- sband->n_iftype_data = n;
++ _ieee80211_set_sband_iftype_data(sband, data, n);
+ }
+
+ void mt7996_set_stream_he_eht_caps(struct mt7996_phy *phy)
+diff --git a/mt7996/main.c b/mt7996/main.c
+index 40ccfdc5b9cf..7c97140d8255 100644
+--- a/mt7996/main.c
++++ b/mt7996/main.c
+@@ -1467,6 +1467,10 @@ mt7996_net_fill_forward_path(struct ieee80211_hw *hw,
+ #endif
+
+ const struct ieee80211_ops mt7996_ops = {
++ .add_chanctx = ieee80211_emulate_add_chanctx,
++ .remove_chanctx = ieee80211_emulate_remove_chanctx,
++ .change_chanctx = ieee80211_emulate_change_chanctx,
++ .switch_vif_chanctx = ieee80211_emulate_switch_vif_chanctx,
+ .tx = mt7996_tx,
+ .start = mt7996_start,
+ .stop = mt7996_stop,
+diff --git a/mt7996/mcu.c b/mt7996/mcu.c
+index 8a8d10419346..7901a5fbb002 100644
+--- a/mt7996/mcu.c
++++ b/mt7996/mcu.c
+@@ -341,7 +341,7 @@ mt7996_mcu_csa_finish(void *priv, u8 *mac, struct ieee80211_vif *vif)
+ if (!vif->bss_conf.csa_active || vif->type == NL80211_IFTYPE_STATION)
+ return;
+
+- ieee80211_csa_finish(vif);
++ ieee80211_csa_finish(vif, 0);
+ }
+
+ static void
+diff --git a/mt7996/mmio.c b/mt7996/mmio.c
+index 8fe56ed9646d..928a9663b49e 100644
+--- a/mt7996/mmio.c
++++ b/mt7996/mmio.c
+@@ -670,4 +670,5 @@ static void __exit mt7996_exit(void)
+
+ module_init(mt7996_init);
+ module_exit(mt7996_exit);
++MODULE_DESCRIPTION("MediaTek MT7996 MMIO helpers");
+ MODULE_LICENSE("Dual BSD/GPL");
+diff --git a/sdio.c b/sdio.c
+index 44c7e1b66fc3..8e9576747052 100644
+--- a/sdio.c
++++ b/sdio.c
+@@ -677,4 +677,5 @@ EXPORT_SYMBOL_GPL(mt76s_init);
+
+ MODULE_AUTHOR("Sean Wang <sean.wang@mediatek.com>");
+ MODULE_AUTHOR("Lorenzo Bianconi <lorenzo@kernel.org>");
++MODULE_DESCRIPTION("MediaTek MT76x SDIO helpers");
+ MODULE_LICENSE("Dual BSD/GPL");
+diff --git a/usb.c b/usb.c
+index dc690d1cdcc5..58ff06823389 100644
+--- a/usb.c
++++ b/usb.c
+@@ -286,8 +286,7 @@ static bool mt76u_check_sg(struct mt76_dev *dev)
+ struct usb_device *udev = interface_to_usbdev(uintf);
+
+ return (!disable_usb_sg && udev->bus->sg_tablesize > 0 &&
+- (udev->bus->no_sg_constraint ||
+- udev->speed == USB_SPEED_WIRELESS));
++ udev->bus->no_sg_constraint);
+ }
+
+ static int
+@@ -1136,4 +1135,5 @@ int mt76u_init(struct mt76_dev *dev, struct usb_interface *intf)
+ EXPORT_SYMBOL_GPL(mt76u_init);
+
+ MODULE_AUTHOR("Lorenzo Bianconi <lorenzo.bianconi83@gmail.com>");
++MODULE_DESCRIPTION("MediaTek MT76x USB helpers");
+ MODULE_LICENSE("Dual BSD/GPL");
+diff --git a/util.c b/util.c
+index fc76c66ff1a5..d6c01a2dd198 100644
+--- a/util.c
++++ b/util.c
+@@ -138,4 +138,5 @@ int __mt76_worker_fn(void *ptr)
+ }
+ EXPORT_SYMBOL_GPL(__mt76_worker_fn);
+
++MODULE_DESCRIPTION("MediaTek MT76x helpers");
+ MODULE_LICENSE("Dual BSD/GPL");
--- a/core.c
+++ b/core.c
-@@ -718,7 +718,7 @@ static void mwl_chnl_switch_event(struct
+@@ -718,8 +718,8 @@ static void mwl_chnl_switch_event(struct
vif = container_of((void *)mwl_vif, struct ieee80211_vif,
drv_priv);
- if (vif->csa_active)
+- ieee80211_csa_finish(vif);
+ if (vif->bss_conf.csa_active)
- ieee80211_csa_finish(vif);
++ ieee80211_csa_finish(vif, 0);
}
spin_unlock_bh(&priv->vif_lock);
+
--- a/debugfs.c
+++ b/debugfs.c
@@ -498,9 +498,9 @@ static ssize_t mwl_debugfs_vif_read(stru
if (priv->chip_type == MWL8997)
ether_addr_copy(pcmd->start_cmd.bssid, mwl_vif->bssid);
pcmd->start_cmd.bss_type = 1;
+@@ -674,7 +678,7 @@ static int mwl_fwcmd_set_ap_beacon(struc
+ phy_ds_param_set = &pcmd->start_cmd.phy_param_set.ds_param_set;
+ phy_ds_param_set->elem_id = WLAN_EID_DS_PARAMS;
+ phy_ds_param_set->len = sizeof(phy_ds_param_set->current_chnl);
+- phy_ds_param_set->current_chnl = bss_conf->chandef.chan->hw_value;
++ phy_ds_param_set->current_chnl = bss_conf->chanreq.oper.chan->hw_value;
+
+ pcmd->start_cmd.probe_delay = cpu_to_le16(10);
+ pcmd->start_cmd.cap_info = cpu_to_le16(mwl_vif->beacon_info.cap_info);
+@@ -768,9 +772,9 @@ static int mwl_fwcmd_set_country_code(st
+ bool enable = false;
+
+ if (b_inf->ie_country_ptr) {
+- if (bss_conf->chandef.chan->band == NL80211_BAND_2GHZ)
++ if (bss_conf->chanreq.oper.chan->band == NL80211_BAND_2GHZ)
+ a_band = false;
+- else if (bss_conf->chandef.chan->band == NL80211_BAND_5GHZ)
++ else if (bss_conf->chanreq.oper.chan->band == NL80211_BAND_5GHZ)
+ a_band = true;
+ else
+ return -EINVAL;
@@ -2090,7 +2094,7 @@ int mwl_fwcmd_set_beacon(struct ieee8021
if (mwl_fwcmd_set_wsc_ie(hw, b_inf->ie_wsc_len, b_inf->ie_wsc_ptr))
goto err;
}
--- a/hif/pcie/8864/tx.c
+++ b/hif/pcie/8864/tx.c
+@@ -490,7 +490,7 @@ static void pcie_non_pfu_tx_done(struct
+ } else
+ memmove(dma_data->data - hdrlen, &dma_data->wh, hdrlen);
+ skb_pull(done_skb, sizeof(*dma_data) - hdrlen);
+- ieee80211_tx_status(priv->hw, done_skb);
++ ieee80211_tx_status_skb(priv->hw, done_skb);
+ dev_kfree_skb_any(done_skb);
+ done_skb = NULL;
+ }
@@ -743,7 +743,7 @@ void pcie_8864_tx_xmit(struct ieee80211_
index = SYSADPT_TX_WMM_QUEUES - index - 1;
txpriority = index;
!(xmitcontrol & EAGLE_TXD_XMITCTRL_USE_MC_RATE) &&
ieee80211_is_data_qos(wh->frame_control)) {
tid = qos & 0xf;
+@@ -925,4 +925,4 @@ void pcie_8864_tx_del_sta_amsdu_pkts(str
+ }
+ }
+ spin_unlock_bh(&sta_info->amsdu_lock);
+-}
+\ No newline at end of file
++}
--- a/hif/pcie/8964/tx_ndp.c
+++ b/hif/pcie/8964/tx_ndp.c
-@@ -607,7 +607,7 @@ void pcie_tx_xmit_ndp(struct ieee80211_h
+@@ -287,7 +287,7 @@ static inline int pcie_tx_skb_ndp(struct
+ skb_get(tx_skb);
+ pcie_tx_prepare_info(priv, tx_ctrl->rate, tx_info);
+ tx_ctrl->flags |= TX_CTRL_TYPE_DATA;
+- ieee80211_tx_status(priv->hw, tx_skb);
++ ieee80211_tx_status_skb(priv->hw, tx_skb);
+ }
+
+ if (++tx_send_head_new >= MAX_NUM_TX_DESC)
+@@ -488,7 +488,7 @@ void pcie_tx_done_ndp(struct ieee80211_h
+ }
+
+ pcie_tx_prepare_info(priv, 0, tx_info);
+- ieee80211_tx_status(hw, skb);
++ ieee80211_tx_status_skb(hw, skb);
+
+ bypass_ack:
+ if (++tx_done_tail >= MAX_TX_RING_DONE_SIZE)
+@@ -601,13 +601,13 @@ void pcie_tx_xmit_ndp(struct ieee80211_h
+ ack_skb = skb_copy(skb, GFP_ATOMIC);
+ ack_info = IEEE80211_SKB_CB(ack_skb);
+ pcie_tx_prepare_info(priv, 0, ack_info);
+- ieee80211_tx_status(hw, ack_skb);
++ ieee80211_tx_status_skb(hw, ack_skb);
+ }
+
pcie_tx_encapsulate_frame(priv, skb, k_conf);
} else {
tid = qos & 0x7;
pcie_priv->txbd_ring_size);
for (num = 0; num < PCIE_MAX_TXRX_BD; num++) {
+@@ -444,7 +444,7 @@ static void pcie_pfu_tx_done(struct mwl_
+ } else
+ memmove(dma_data->data - hdrlen, &dma_data->wh, hdrlen);
+ skb_pull(done_skb, sizeof(*pfu_dma) - hdrlen);
+- ieee80211_tx_status(priv->hw, done_skb);
++ ieee80211_tx_status_skb(priv->hw, done_skb);
+ }
+ }
+ next:
@@ -694,7 +694,7 @@ void pcie_8997_tx_xmit(struct ieee80211_
index = SYSADPT_TX_WMM_QUEUES - index - 1;
txpriority = index;
!(xmitcontrol & EAGLE_TXD_XMITCTRL_USE_MC_RATE) &&
ieee80211_is_data_qos(wh->frame_control)) {
tid = qos & 0xf;
+@@ -875,4 +875,4 @@ void pcie_8997_tx_del_sta_amsdu_pkts(str
+ }
+ }
+ spin_unlock_bh(&sta_info->amsdu_lock);
+-}
+\ No newline at end of file
++}
--- a/mac80211.c
+++ b/mac80211.c
@@ -368,15 +368,15 @@ static void mwl_mac80211_bss_info_change