mirror of
https://github.com/openwrt/openwrt.git
synced 2025-01-06 13:58:53 +00:00
mac80211: update to version 6.12.6
- drop patches accepted upstream - include build fixes in the tarball - based on https://github.com/nbd168/backports commit 410656ef04d2 Signed-off-by: Felix Fietkau <nbd@nbd.name>
This commit is contained in:
parent
de0c143742
commit
a85059438f
@ -10,13 +10,13 @@ include $(INCLUDE_DIR)/kernel.mk
|
||||
|
||||
PKG_NAME:=mac80211
|
||||
|
||||
PKG_VERSION:=6.11.2
|
||||
PKG_VERSION:=6.12.6
|
||||
PKG_RELEASE:=1
|
||||
PKG_LICENSE:=GPL-2.0-only
|
||||
PKG_LICENSE_FILES:=COPYING
|
||||
|
||||
PKG_SOURCE_URL:=http://mirror2.openwrt.org/sources/
|
||||
PKG_HASH:=700ea5abef8dde9e3c6df2acd32ff443da735d773d56db9a80269e2237549b34
|
||||
PKG_HASH:=28ec39425a1b3270e1422d92a8131a6a3d8919cc13e8ee250c315e55d922ba68
|
||||
|
||||
PKG_SOURCE:=backports-$(PKG_VERSION).tar.xz
|
||||
PKG_BUILD_DIR:=$(KERNEL_BUILD_DIR)/$(if $(BUILD_VARIANT),$(PKG_NAME)-$(BUILD_VARIANT)/)backports-$(PKG_VERSION)
|
||||
|
@ -8,7 +8,7 @@
|
||||
#include "../ath.h"
|
||||
#include "ath5k.h"
|
||||
#include "debug.h"
|
||||
@@ -71,7 +72,7 @@ static void ath5k_pci_read_cachesize(str
|
||||
@@ -73,7 +74,7 @@ static void ath5k_pci_read_cachesize(str
|
||||
}
|
||||
|
||||
/*
|
||||
@ -17,7 +17,7 @@
|
||||
*/
|
||||
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
|
||||
@@ -81,6 +82,19 @@ ath5k_pci_eeprom_read(struct ath_common
|
||||
struct ath5k_hw *ah = common->ah;
|
||||
u32 status, timeout;
|
||||
|
||||
@ -37,7 +37,7 @@
|
||||
/*
|
||||
* Initialize EEPROM access
|
||||
*/
|
||||
@@ -122,6 +136,16 @@ static int ath5k_pci_eeprom_read_mac(str
|
||||
@@ -124,6 +138,16 @@ static int ath5k_pci_eeprom_read_mac(str
|
||||
u16 data;
|
||||
int octet;
|
||||
|
||||
|
@ -451,7 +451,7 @@ Acked-by: Jeff Johnson <quic_jjohnson@quicinc.com>
|
||||
enum ath12k_dev_flags {
|
||||
ATH12K_CAC_RUNNING,
|
||||
ATH12K_FLAG_CRASH_FLUSH,
|
||||
@@ -313,6 +319,8 @@ struct ath12k_vif_iter {
|
||||
@@ -319,6 +325,8 @@ struct ath12k_vif_iter {
|
||||
#define ATH12K_RX_RATE_TABLE_11AX_NUM 576
|
||||
#define ATH12K_RX_RATE_TABLE_NUM 320
|
||||
|
||||
@ -460,7 +460,7 @@ Acked-by: Jeff Johnson <quic_jjohnson@quicinc.com>
|
||||
struct ath12k_rx_peer_rate_stats {
|
||||
u64 ht_mcs_count[HAL_RX_MAX_MCS_HT + 1];
|
||||
u64 vht_mcs_count[HAL_RX_MAX_MCS_VHT + 1];
|
||||
@@ -648,6 +656,13 @@ struct ath12k {
|
||||
@@ -654,6 +662,13 @@ struct ath12k {
|
||||
u32 freq_low;
|
||||
u32 freq_high;
|
||||
|
||||
@ -474,7 +474,7 @@ Acked-by: Jeff Johnson <quic_jjohnson@quicinc.com>
|
||||
bool nlo_enabled;
|
||||
};
|
||||
|
||||
@@ -880,6 +895,8 @@ struct ath12k_base {
|
||||
@@ -886,6 +901,8 @@ struct ath12k_base {
|
||||
/* continuous recovery fail count */
|
||||
atomic_t fail_cont_count;
|
||||
unsigned long reset_fail_timeout;
|
||||
@ -485,7 +485,7 @@ Acked-by: Jeff Johnson <quic_jjohnson@quicinc.com>
|
||||
u32 fw_crash_counter;
|
||||
--- a/drivers/net/wireless/ath/ath12k/mac.c
|
||||
+++ b/drivers/net/wireless/ath/ath12k/mac.c
|
||||
@@ -2946,6 +2946,11 @@ static void ath12k_bss_assoc(struct ath1
|
||||
@@ -2949,6 +2949,11 @@ static void ath12k_bss_assoc(struct ath1
|
||||
if (ret)
|
||||
ath12k_warn(ar->ab, "failed to set vdev %i OBSS PD parameters: %d\n",
|
||||
arvif->vdev_id, ret);
|
||||
@ -497,7 +497,7 @@ Acked-by: Jeff Johnson <quic_jjohnson@quicinc.com>
|
||||
}
|
||||
|
||||
static void ath12k_bss_disassoc(struct ath12k *ar,
|
||||
@@ -3521,7 +3526,7 @@ void __ath12k_mac_scan_finish(struct ath
|
||||
@@ -3524,7 +3529,7 @@ void __ath12k_mac_scan_finish(struct ath
|
||||
ar->scan_channel = NULL;
|
||||
ar->scan.roc_freq = 0;
|
||||
cancel_delayed_work(&ar->scan.timeout);
|
||||
@ -506,9 +506,9 @@ Acked-by: Jeff Johnson <quic_jjohnson@quicinc.com>
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -3782,7 +3787,12 @@ scan:
|
||||
@@ -3790,7 +3795,12 @@ scan:
|
||||
|
||||
ret = ath12k_start_scan(ar, &arg);
|
||||
ret = ath12k_start_scan(ar, arg);
|
||||
if (ret) {
|
||||
- ath12k_warn(ar->ab, "failed to start hw scan: %d\n", ret);
|
||||
+ if (ret == -EBUSY)
|
||||
@ -520,7 +520,7 @@ Acked-by: Jeff Johnson <quic_jjohnson@quicinc.com>
|
||||
spin_lock_bh(&ar->data_lock);
|
||||
ar->scan.state = ATH12K_SCAN_IDLE;
|
||||
spin_unlock_bh(&ar->data_lock);
|
||||
@@ -3801,6 +3811,11 @@ exit:
|
||||
@@ -3810,6 +3820,11 @@ exit:
|
||||
|
||||
mutex_unlock(&ar->conf_mutex);
|
||||
|
||||
@ -532,7 +532,7 @@ Acked-by: Jeff Johnson <quic_jjohnson@quicinc.com>
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -5985,7 +6000,7 @@ static int ath12k_mac_start(struct ath12
|
||||
@@ -5994,7 +6009,7 @@ static int ath12k_mac_start(struct ath12
|
||||
|
||||
/* TODO: Do we need to enable ANI? */
|
||||
|
||||
@ -541,7 +541,7 @@ Acked-by: Jeff Johnson <quic_jjohnson@quicinc.com>
|
||||
|
||||
ar->num_started_vdevs = 0;
|
||||
ar->num_created_vdevs = 0;
|
||||
@@ -6165,6 +6180,9 @@ static void ath12k_mac_stop(struct ath12
|
||||
@@ -6174,6 +6189,9 @@ static void ath12k_mac_stop(struct ath12
|
||||
cancel_delayed_work_sync(&ar->scan.timeout);
|
||||
cancel_work_sync(&ar->regd_update_work);
|
||||
cancel_work_sync(&ar->ab->rfkill_work);
|
||||
@ -551,7 +551,7 @@ Acked-by: Jeff Johnson <quic_jjohnson@quicinc.com>
|
||||
|
||||
spin_lock_bh(&ar->data_lock);
|
||||
list_for_each_entry_safe(ppdu_stats, tmp, &ar->ppdu_stats_info, list) {
|
||||
@@ -6411,6 +6429,117 @@ static void ath12k_mac_op_update_vif_off
|
||||
@@ -6420,6 +6438,117 @@ static void ath12k_mac_op_update_vif_off
|
||||
ath12k_mac_update_vif_offload(arvif);
|
||||
}
|
||||
|
||||
@ -669,7 +669,7 @@ Acked-by: Jeff Johnson <quic_jjohnson@quicinc.com>
|
||||
static int ath12k_mac_vdev_create(struct ath12k *ar, struct ieee80211_vif *vif)
|
||||
{
|
||||
struct ath12k_hw *ah = ar->ah;
|
||||
@@ -6525,6 +6654,7 @@ static int ath12k_mac_vdev_create(struct
|
||||
@@ -6534,6 +6663,7 @@ static int ath12k_mac_vdev_create(struct
|
||||
arvif->vdev_id, ret);
|
||||
goto err_peer_del;
|
||||
}
|
||||
@ -677,7 +677,7 @@ Acked-by: Jeff Johnson <quic_jjohnson@quicinc.com>
|
||||
break;
|
||||
case WMI_VDEV_TYPE_STA:
|
||||
param_id = WMI_STA_PS_PARAM_RX_WAKE_POLICY;
|
||||
@@ -6563,6 +6693,13 @@ static int ath12k_mac_vdev_create(struct
|
||||
@@ -6572,6 +6702,13 @@ static int ath12k_mac_vdev_create(struct
|
||||
arvif->vdev_id, ret);
|
||||
goto err_peer_del;
|
||||
}
|
||||
@ -691,7 +691,7 @@ Acked-by: Jeff Johnson <quic_jjohnson@quicinc.com>
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
@@ -6903,6 +7040,11 @@ static void ath12k_mac_op_remove_interfa
|
||||
@@ -6912,6 +7049,11 @@ static void ath12k_mac_op_remove_interfa
|
||||
ath12k_dbg(ab, ATH12K_DBG_MAC, "mac remove interface (vdev %d)\n",
|
||||
arvif->vdev_id);
|
||||
|
||||
@ -703,7 +703,7 @@ Acked-by: Jeff Johnson <quic_jjohnson@quicinc.com>
|
||||
if (arvif->vdev_type == WMI_VDEV_TYPE_AP) {
|
||||
ret = ath12k_peer_delete(ar, arvif->vdev_id, vif->addr);
|
||||
if (ret)
|
||||
@@ -7743,6 +7885,14 @@ ath12k_mac_op_unassign_vif_chanctx(struc
|
||||
@@ -7752,6 +7894,14 @@ ath12k_mac_op_unassign_vif_chanctx(struc
|
||||
ar->num_started_vdevs == 1 && ar->monitor_vdev_created)
|
||||
ath12k_mac_monitor_stop(ar);
|
||||
|
||||
@ -718,7 +718,7 @@ Acked-by: Jeff Johnson <quic_jjohnson@quicinc.com>
|
||||
mutex_unlock(&ar->conf_mutex);
|
||||
}
|
||||
|
||||
@@ -8281,6 +8431,14 @@ ath12k_mac_op_reconfig_complete(struct i
|
||||
@@ -8290,6 +8440,14 @@ ath12k_mac_op_reconfig_complete(struct i
|
||||
ath12k_warn(ar->ab, "pdev %d successfully recovered\n",
|
||||
ar->pdev->pdev_id);
|
||||
|
||||
@ -733,7 +733,7 @@ Acked-by: Jeff Johnson <quic_jjohnson@quicinc.com>
|
||||
if (ab->is_reset) {
|
||||
recovery_count = atomic_inc_return(&ab->recovery_count);
|
||||
|
||||
@@ -9330,6 +9488,9 @@ static void ath12k_mac_setup(struct ath1
|
||||
@@ -9339,6 +9497,9 @@ static void ath12k_mac_setup(struct ath1
|
||||
|
||||
INIT_WORK(&ar->wmi_mgmt_tx_work, ath12k_mgmt_over_wmi_tx_work);
|
||||
skb_queue_head_init(&ar->wmi_mgmt_tx_queue);
|
||||
@ -888,36 +888,36 @@ Acked-by: Jeff Johnson <quic_jjohnson@quicinc.com>
|
||||
#endif
|
||||
--- a/drivers/net/wireless/ath/ath12k/hw.c
|
||||
+++ b/drivers/net/wireless/ath/ath12k/hw.c
|
||||
@@ -926,6 +926,7 @@ static const struct ath12k_hw_params ath
|
||||
.supports_dynamic_smps_6ghz = true,
|
||||
|
||||
@@ -928,6 +928,7 @@ static const struct ath12k_hw_params ath
|
||||
.iova_mask = 0,
|
||||
|
||||
.supports_aspm = false,
|
||||
+ .current_cc_support = false,
|
||||
},
|
||||
{
|
||||
.name = "wcn7850 hw2.0",
|
||||
@@ -1004,6 +1005,7 @@ static const struct ath12k_hw_params ath
|
||||
.supports_dynamic_smps_6ghz = false,
|
||||
|
||||
@@ -1008,6 +1009,7 @@ static const struct ath12k_hw_params ath
|
||||
.iova_mask = ATH12K_PCIE_MAX_PAYLOAD_SIZE - 1,
|
||||
|
||||
.supports_aspm = true,
|
||||
+ .current_cc_support = true,
|
||||
},
|
||||
{
|
||||
.name = "qcn9274 hw2.0",
|
||||
@@ -1078,6 +1080,7 @@ static const struct ath12k_hw_params ath
|
||||
.supports_dynamic_smps_6ghz = true,
|
||||
|
||||
@@ -1084,6 +1086,7 @@ static const struct ath12k_hw_params ath
|
||||
.iova_mask = 0,
|
||||
|
||||
.supports_aspm = false,
|
||||
+ .current_cc_support = false,
|
||||
},
|
||||
};
|
||||
|
||||
--- a/drivers/net/wireless/ath/ath12k/hw.h
|
||||
+++ b/drivers/net/wireless/ath/ath12k/hw.h
|
||||
@@ -189,6 +189,7 @@ struct ath12k_hw_params {
|
||||
bool tcl_ring_retry:1;
|
||||
@@ -190,6 +190,7 @@ struct ath12k_hw_params {
|
||||
bool reoq_lut_support:1;
|
||||
bool supports_shadow_regs:1;
|
||||
bool supports_aspm:1;
|
||||
+ bool current_cc_support:1;
|
||||
|
||||
u32 num_tcl_banks;
|
||||
|
@ -1,11 +0,0 @@
|
||||
--- a/drivers/net/wireless/ath/ath5k/pci.c
|
||||
+++ b/drivers/net/wireless/ath/ath5k/pci.c
|
||||
@@ -47,6 +47,8 @@ static const struct pci_device_id ath5k_
|
||||
{ PCI_VDEVICE(ATHEROS, 0x001b) }, /* 5413 Eagle */
|
||||
{ PCI_VDEVICE(ATHEROS, 0x001c) }, /* PCI-E cards */
|
||||
{ PCI_VDEVICE(ATHEROS, 0x001d) }, /* 2417 Nala */
|
||||
+ { PCI_VDEVICE(ATHEROS, 0xff16) }, /* 2413,2414 sx76x on lantiq_danube */
|
||||
+ { PCI_VDEVICE(ATHEROS, 0xff1a) }, /* 2417 arv45xx on lantiq_danube */
|
||||
{ PCI_VDEVICE(ATHEROS, 0xff1b) }, /* AR5BXB63 */
|
||||
{ 0 }
|
||||
};
|
@ -8,7 +8,7 @@ This reverts commit 71f5137bf010c6faffab50c0ec15374c59c4a411.
|
||||
|
||||
--- a/drivers/net/wireless/ath/ath9k/hw.c
|
||||
+++ b/drivers/net/wireless/ath/ath9k/hw.c
|
||||
@@ -2977,7 +2977,8 @@ void ath9k_hw_apply_txpower(struct ath_h
|
||||
@@ -2975,7 +2975,8 @@ void ath9k_hw_apply_txpower(struct ath_h
|
||||
{
|
||||
struct ath_regulatory *reg = ath9k_hw_regulatory(ah);
|
||||
struct ieee80211_channel *channel;
|
||||
@ -18,7 +18,7 @@ This reverts commit 71f5137bf010c6faffab50c0ec15374c59c4a411.
|
||||
u16 ctl = NO_CTL;
|
||||
|
||||
if (!chan)
|
||||
@@ -2989,9 +2990,14 @@ void ath9k_hw_apply_txpower(struct ath_h
|
||||
@@ -2987,9 +2988,14 @@ void ath9k_hw_apply_txpower(struct ath_h
|
||||
channel = chan->chan;
|
||||
chan_pwr = min_t(int, channel->max_power * 2, MAX_COMBINED_POWER);
|
||||
new_pwr = min_t(int, chan_pwr, reg->power_limit);
|
||||
|
@ -11,7 +11,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||
|
||||
--- a/drivers/net/wireless/ath/ath9k/hw.c
|
||||
+++ b/drivers/net/wireless/ath/ath9k/hw.c
|
||||
@@ -2996,6 +2996,10 @@ void ath9k_hw_apply_txpower(struct ath_h
|
||||
@@ -2994,6 +2994,10 @@ void ath9k_hw_apply_txpower(struct ath_h
|
||||
if (ant_gain > max_gain)
|
||||
ant_reduction = ant_gain - max_gain;
|
||||
|
||||
|
@ -49,9 +49,9 @@ Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
|
||||
void brcmf_of_probe(struct device *dev, enum brcmf_bus_type bus_type,
|
||||
struct brcmf_mp_device *settings)
|
||||
{
|
||||
@@ -114,6 +144,8 @@ void brcmf_of_probe(struct device *dev,
|
||||
of_node_put(root);
|
||||
@@ -113,6 +143,8 @@ void brcmf_of_probe(struct device *dev,
|
||||
}
|
||||
of_node_put(root);
|
||||
|
||||
+ brcmf_of_probe_cc(dev, settings);
|
||||
+
|
||||
|
@ -1,10 +0,0 @@
|
||||
--- a/drivers/staging/rtl8723bs/Kconfig
|
||||
+++ b/drivers/staging/rtl8723bs/Kconfig
|
||||
@@ -5,7 +5,6 @@ config RTL8723BS
|
||||
depends on m
|
||||
depends on WLAN && MMC && CFG80211
|
||||
depends on m
|
||||
- select CFG80211_WEXT
|
||||
depends on CRYPTO
|
||||
select BPAUTO_CRYPTO_LIB_ARC4
|
||||
help
|
@ -1,14 +0,0 @@
|
||||
--- a/backport-include/net/dropreason.h
|
||||
+++ b/backport-include/net/dropreason.h
|
||||
@@ -3,10 +3,9 @@
|
||||
|
||||
#include <linux/version.h>
|
||||
|
||||
+#include <net/dropreason-core.h>
|
||||
#if LINUX_VERSION_IS_GEQ(6,0,0)
|
||||
#include_next <net/dropreason.h>
|
||||
-#else
|
||||
-#include <net/dropreason-core.h>
|
||||
#endif
|
||||
|
||||
#if LINUX_VERSION_IS_LESS(6,4,0)
|
@ -1,6 +1,6 @@
|
||||
--- a/drivers/bus/mhi/host/trace.h
|
||||
+++ b/drivers/bus/mhi/host/trace.h
|
||||
@@ -103,7 +103,7 @@ TRACE_EVENT(mhi_gen_tre,
|
||||
@@ -104,7 +104,7 @@ TRACE_EVENT(mhi_gen_tre,
|
||||
),
|
||||
|
||||
TP_fast_assign(
|
||||
@ -8,8 +8,8 @@
|
||||
+ __assign_str(name, mhi_cntrl->mhi_dev->name);
|
||||
__entry->ch_num = mhi_chan->chan;
|
||||
__entry->wp = mhi_tre;
|
||||
__entry->tre_ptr = mhi_tre->ptr;
|
||||
@@ -131,7 +131,7 @@ TRACE_EVENT(mhi_intvec_states,
|
||||
__entry->tre_ptr = le64_to_cpu(mhi_tre->ptr);
|
||||
@@ -132,7 +132,7 @@ TRACE_EVENT(mhi_intvec_states,
|
||||
),
|
||||
|
||||
TP_fast_assign(
|
||||
@ -18,7 +18,7 @@
|
||||
__entry->local_ee = mhi_cntrl->ee;
|
||||
__entry->state = mhi_cntrl->dev_state;
|
||||
__entry->dev_ee = dev_ee;
|
||||
@@ -158,7 +158,7 @@ TRACE_EVENT(mhi_tryset_pm_state,
|
||||
@@ -159,7 +159,7 @@ TRACE_EVENT(mhi_tryset_pm_state,
|
||||
),
|
||||
|
||||
TP_fast_assign(
|
||||
@ -27,16 +27,16 @@
|
||||
if (pm_state)
|
||||
pm_state = __fls(pm_state);
|
||||
__entry->pm_state = pm_state;
|
||||
@@ -184,7 +184,7 @@ DECLARE_EVENT_CLASS(mhi_process_event_ri
|
||||
@@ -185,7 +185,7 @@ DECLARE_EVENT_CLASS(mhi_process_event_ri
|
||||
),
|
||||
|
||||
TP_fast_assign(
|
||||
- __assign_str(name);
|
||||
+ __assign_str(name, mhi_cntrl->mhi_dev->name);
|
||||
__entry->rp = rp;
|
||||
__entry->ptr = rp->ptr;
|
||||
__entry->dword0 = rp->dword[0];
|
||||
@@ -226,7 +226,7 @@ DECLARE_EVENT_CLASS(mhi_update_channel_s
|
||||
__entry->ptr = le64_to_cpu(rp->ptr);
|
||||
__entry->dword0 = le32_to_cpu(rp->dword[0]);
|
||||
@@ -227,7 +227,7 @@ DECLARE_EVENT_CLASS(mhi_update_channel_s
|
||||
),
|
||||
|
||||
TP_fast_assign(
|
||||
@ -45,7 +45,7 @@
|
||||
__entry->ch_num = mhi_chan->chan;
|
||||
__entry->state = state;
|
||||
__entry->reason = reason;
|
||||
@@ -265,7 +265,7 @@ TRACE_EVENT(mhi_pm_st_transition,
|
||||
@@ -266,7 +266,7 @@ TRACE_EVENT(mhi_pm_st_transition,
|
||||
),
|
||||
|
||||
TP_fast_assign(
|
||||
|
@ -0,0 +1,44 @@
|
||||
--- a/net/wireless/core.c
|
||||
+++ b/net/wireless/core.c
|
||||
@@ -165,11 +165,15 @@ int cfg80211_switch_netns(struct cfg8021
|
||||
list_for_each_entry(wdev, &rdev->wiphy.wdev_list, list) {
|
||||
if (!wdev->netdev)
|
||||
continue;
|
||||
+#if LINUX_VERSION_IS_GEQ(6,12,0)
|
||||
wdev->netdev->netns_local = false;
|
||||
+#endif
|
||||
err = dev_change_net_namespace(wdev->netdev, net, "wlan%d");
|
||||
if (err)
|
||||
break;
|
||||
+#if LINUX_VERSION_IS_GEQ(6,12,0)
|
||||
wdev->netdev->netns_local = true;
|
||||
+#endif
|
||||
}
|
||||
|
||||
if (err) {
|
||||
@@ -181,11 +185,15 @@ int cfg80211_switch_netns(struct cfg8021
|
||||
list) {
|
||||
if (!wdev->netdev)
|
||||
continue;
|
||||
+#if LINUX_VERSION_IS_GEQ(6,12,0)
|
||||
wdev->netdev->netns_local = false;
|
||||
+#endif
|
||||
err = dev_change_net_namespace(wdev->netdev, net,
|
||||
"wlan%d");
|
||||
WARN_ON(err);
|
||||
+#if LINUX_VERSION_IS_GEQ(6,12,0)
|
||||
wdev->netdev->netns_local = true;
|
||||
+#endif
|
||||
}
|
||||
|
||||
return err;
|
||||
@@ -1518,7 +1526,9 @@ static int cfg80211_netdev_notifier_call
|
||||
SET_NETDEV_DEVTYPE(dev, &wiphy_type);
|
||||
wdev->netdev = dev;
|
||||
/* can only change netns with wiphy */
|
||||
+#if LINUX_VERSION_IS_GEQ(6,12,0)
|
||||
dev->netns_local = true;
|
||||
+#endif
|
||||
|
||||
cfg80211_init_wdev(wdev);
|
||||
break;
|
@ -1,169 +0,0 @@
|
||||
From e0f83d268974dab0361d11904dfc9acec53f96a6 Mon Sep 17 00:00:00 2001
|
||||
From: Eric Dumazet <edumazet@google.com>
|
||||
Date: Fri, 11 Oct 2024 17:12:17 +0000
|
||||
Subject: [PATCH] genetlink: hold RCU in genlmsg_mcast()
|
||||
|
||||
[ Upstream commit 56440d7ec28d60f8da3bfa09062b3368ff9b16db ]
|
||||
|
||||
While running net selftests with CONFIG_PROVE_RCU_LIST=y I saw
|
||||
one lockdep splat [1].
|
||||
|
||||
genlmsg_mcast() uses for_each_net_rcu(), and must therefore hold RCU.
|
||||
|
||||
Instead of letting all callers guard genlmsg_multicast_allns()
|
||||
with a rcu_read_lock()/rcu_read_unlock() pair, do it in genlmsg_mcast().
|
||||
|
||||
This also means the @flags parameter is useless, we need to always use
|
||||
GFP_ATOMIC.
|
||||
|
||||
[1]
|
||||
[10882.424136] =============================
|
||||
[10882.424166] WARNING: suspicious RCU usage
|
||||
[10882.424309] 6.12.0-rc2-virtme #1156 Not tainted
|
||||
[10882.424400] -----------------------------
|
||||
[10882.424423] net/netlink/genetlink.c:1940 RCU-list traversed in non-reader section!!
|
||||
[10882.424469]
|
||||
other info that might help us debug this:
|
||||
|
||||
[10882.424500]
|
||||
rcu_scheduler_active = 2, debug_locks = 1
|
||||
[10882.424744] 2 locks held by ip/15677:
|
||||
[10882.424791] #0: ffffffffb6b491b0 (cb_lock){++++}-{3:3}, at: genl_rcv (net/netlink/genetlink.c:1219)
|
||||
[10882.426334] #1: ffffffffb6b49248 (genl_mutex){+.+.}-{3:3}, at: genl_rcv_msg (net/netlink/genetlink.c:61 net/netlink/genetlink.c:57 net/netlink/genetlink.c:1209)
|
||||
[10882.426465]
|
||||
stack backtrace:
|
||||
[10882.426805] CPU: 14 UID: 0 PID: 15677 Comm: ip Not tainted 6.12.0-rc2-virtme #1156
|
||||
[10882.426919] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.16.3-debian-1.16.3-2 04/01/2014
|
||||
[10882.427046] Call Trace:
|
||||
[10882.427131] <TASK>
|
||||
[10882.427244] dump_stack_lvl (lib/dump_stack.c:123)
|
||||
[10882.427335] lockdep_rcu_suspicious (kernel/locking/lockdep.c:6822)
|
||||
[10882.427387] genlmsg_multicast_allns (net/netlink/genetlink.c:1940 (discriminator 7) net/netlink/genetlink.c:1977 (discriminator 7))
|
||||
[10882.427436] l2tp_tunnel_notify.constprop.0 (net/l2tp/l2tp_netlink.c:119) l2tp_netlink
|
||||
[10882.427683] l2tp_nl_cmd_tunnel_create (net/l2tp/l2tp_netlink.c:253) l2tp_netlink
|
||||
[10882.427748] genl_family_rcv_msg_doit (net/netlink/genetlink.c:1115)
|
||||
[10882.427834] genl_rcv_msg (net/netlink/genetlink.c:1195 net/netlink/genetlink.c:1210)
|
||||
[10882.427877] ? __pfx_l2tp_nl_cmd_tunnel_create (net/l2tp/l2tp_netlink.c:186) l2tp_netlink
|
||||
[10882.427927] ? __pfx_genl_rcv_msg (net/netlink/genetlink.c:1201)
|
||||
[10882.427959] netlink_rcv_skb (net/netlink/af_netlink.c:2551)
|
||||
[10882.428069] genl_rcv (net/netlink/genetlink.c:1220)
|
||||
[10882.428095] netlink_unicast (net/netlink/af_netlink.c:1332 net/netlink/af_netlink.c:1357)
|
||||
[10882.428140] netlink_sendmsg (net/netlink/af_netlink.c:1901)
|
||||
[10882.428210] ____sys_sendmsg (net/socket.c:729 (discriminator 1) net/socket.c:744 (discriminator 1) net/socket.c:2607 (discriminator 1))
|
||||
|
||||
Fixes: 33f72e6f0c67 ("l2tp : multicast notification to the registered listeners")
|
||||
Signed-off-by: Eric Dumazet <edumazet@google.com>
|
||||
Cc: James Chapman <jchapman@katalix.com>
|
||||
Cc: Tom Parkin <tparkin@katalix.com>
|
||||
Cc: Johannes Berg <johannes.berg@intel.com>
|
||||
Link: https://patch.msgid.link/20241011171217.3166614-1-edumazet@google.com
|
||||
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||
Signed-off-by: Sasha Levin <sashal@kernel.org>
|
||||
---
|
||||
drivers/target/target_core_user.c | 2 +-
|
||||
include/net/genetlink.h | 3 +--
|
||||
net/l2tp/l2tp_netlink.c | 4 ++--
|
||||
net/netlink/genetlink.c | 28 ++++++++++++++--------------
|
||||
net/wireless/nl80211.c | 8 ++------
|
||||
5 files changed, 20 insertions(+), 25 deletions(-)
|
||||
|
||||
--- a/backport-include/net/genetlink.h
|
||||
+++ b/backport-include/net/genetlink.h
|
||||
@@ -150,7 +150,7 @@ int genlmsg_multicast(const struct genl_
|
||||
#define genlmsg_multicast_allns LINUX_BACKPORT(genlmsg_multicast_allns)
|
||||
int backport_genlmsg_multicast_allns(const struct genl_family *family,
|
||||
struct sk_buff *skb, u32 portid,
|
||||
- unsigned int group, gfp_t flags);
|
||||
+ unsigned int group);
|
||||
|
||||
#define genl_family_attrbuf LINUX_BACKPORT(genl_family_attrbuf)
|
||||
static inline struct nlattr **genl_family_attrbuf(struct genl_family *family)
|
||||
--- a/compat/backport-genetlink.c
|
||||
+++ b/compat/backport-genetlink.c
|
||||
@@ -198,23 +198,23 @@ int genlmsg_multicast(const struct genl_
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(genlmsg_multicast);
|
||||
|
||||
-static int genlmsg_mcast(struct sk_buff *skb, u32 portid, unsigned long group,
|
||||
- gfp_t flags)
|
||||
+static int genlmsg_mcast(struct sk_buff *skb, u32 portid, unsigned long group)
|
||||
{
|
||||
struct sk_buff *tmp;
|
||||
struct net *net, *prev = NULL;
|
||||
bool delivered = false;
|
||||
int err;
|
||||
|
||||
+ rcu_read_lock();
|
||||
for_each_net_rcu(net) {
|
||||
if (prev) {
|
||||
- tmp = skb_clone(skb, flags);
|
||||
+ tmp = skb_clone(skb, GFP_ATOMIC);
|
||||
if (!tmp) {
|
||||
err = -ENOMEM;
|
||||
goto error;
|
||||
}
|
||||
err = nlmsg_multicast(prev->genl_sock, tmp,
|
||||
- portid, group, flags);
|
||||
+ portid, group, GFP_ATOMIC);
|
||||
if (!err)
|
||||
delivered = true;
|
||||
else if (err != -ESRCH)
|
||||
@@ -223,25 +223,29 @@ static int genlmsg_mcast(struct sk_buff
|
||||
|
||||
prev = net;
|
||||
}
|
||||
+ err = nlmsg_multicast(prev->genl_sock, skb, portid, group, GFP_ATOMIC);
|
||||
+
|
||||
+ rcu_read_unlock();
|
||||
|
||||
- err = nlmsg_multicast(prev->genl_sock, skb, portid, group, flags);
|
||||
if (!err)
|
||||
delivered = true;
|
||||
else if (err != -ESRCH)
|
||||
return err;
|
||||
return delivered ? 0 : -ESRCH;
|
||||
error:
|
||||
+ rcu_read_unlock();
|
||||
+
|
||||
kfree_skb(skb);
|
||||
return err;
|
||||
}
|
||||
|
||||
int backport_genlmsg_multicast_allns(const struct genl_family *family,
|
||||
struct sk_buff *skb, u32 portid,
|
||||
- unsigned int group, gfp_t flags)
|
||||
+ unsigned int group)
|
||||
{
|
||||
group = __backport_genl_group(family, group);
|
||||
if (group == INVALID_GROUP)
|
||||
return -EINVAL;
|
||||
- return genlmsg_mcast(skb, portid, group, flags);
|
||||
+ return genlmsg_mcast(skb, portid, group);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(backport_genlmsg_multicast_allns);
|
||||
--- a/net/wireless/nl80211.c
|
||||
+++ b/net/wireless/nl80211.c
|
||||
@@ -17956,10 +17956,8 @@ void nl80211_common_reg_change_event(enu
|
||||
|
||||
genlmsg_end(msg, hdr);
|
||||
|
||||
- rcu_read_lock();
|
||||
genlmsg_multicast_allns(&nl80211_fam, msg, 0,
|
||||
- NL80211_MCGRP_REGULATORY, GFP_ATOMIC);
|
||||
- rcu_read_unlock();
|
||||
+ NL80211_MCGRP_REGULATORY);
|
||||
|
||||
return;
|
||||
|
||||
@@ -18692,10 +18690,8 @@ void nl80211_send_beacon_hint_event(stru
|
||||
|
||||
genlmsg_end(msg, hdr);
|
||||
|
||||
- rcu_read_lock();
|
||||
genlmsg_multicast_allns(&nl80211_fam, msg, 0,
|
||||
- NL80211_MCGRP_REGULATORY, GFP_ATOMIC);
|
||||
- rcu_read_unlock();
|
||||
+ NL80211_MCGRP_REGULATORY);
|
||||
|
||||
return;
|
||||
|
@ -1,6 +1,6 @@
|
||||
--- a/drivers/net/wireless/marvell/mwl8k.c
|
||||
+++ b/drivers/net/wireless/marvell/mwl8k.c
|
||||
@@ -5709,6 +5709,7 @@ MODULE_FIRMWARE("mwl8k/fmimage_8366.fw")
|
||||
@@ -5712,6 +5712,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[] = {
|
||||
|
@ -30,7 +30,7 @@ the card-specific structure.
|
||||
|
||||
#define MWIFIEX_DMA_ALIGN_SZ 64
|
||||
#define MWIFIEX_RX_HEADROOM 64
|
||||
@@ -100,7 +100,7 @@
|
||||
@@ -123,7 +123,7 @@
|
||||
#define MWIFIEX_RATE_INDEX_OFDM0 4
|
||||
|
||||
#define MWIFIEX_MAX_STA_NUM 3
|
||||
|
@ -1,6 +1,6 @@
|
||||
--- a/drivers/net/wireless/marvell/mwl8k.c
|
||||
+++ b/drivers/net/wireless/marvell/mwl8k.c
|
||||
@@ -6295,6 +6295,8 @@ static int mwl8k_probe(struct pci_dev *p
|
||||
@@ -6298,6 +6298,8 @@ static int mwl8k_probe(struct pci_dev *p
|
||||
|
||||
priv->running_bsses = 0;
|
||||
|
||||
@ -9,7 +9,7 @@
|
||||
return rc;
|
||||
|
||||
err_stop_firmware:
|
||||
@@ -6328,8 +6330,6 @@ static void mwl8k_remove(struct pci_dev
|
||||
@@ -6331,8 +6333,6 @@ static void mwl8k_remove(struct pci_dev
|
||||
return;
|
||||
priv = hw->priv;
|
||||
|
||||
|
@ -116,7 +116,7 @@ Signed-off-by: Pali Rohár <pali@kernel.org>
|
||||
mwifiex_recycle_cmd_node(adapter, cmd_node);
|
||||
queue_work(adapter->workqueue, &adapter->main_work);
|
||||
return -1;
|
||||
@@ -653,8 +732,8 @@ int mwifiex_send_cmd(struct mwifiex_priv
|
||||
@@ -655,8 +734,8 @@ int mwifiex_send_cmd(struct mwifiex_priv
|
||||
/* Return error, since the command preparation failed */
|
||||
if (ret) {
|
||||
mwifiex_dbg(adapter, ERROR,
|
||||
@ -127,7 +127,7 @@ Signed-off-by: Pali Rohár <pali@kernel.org>
|
||||
mwifiex_insert_cmd_to_free_q(adapter, cmd_node);
|
||||
return -1;
|
||||
}
|
||||
@@ -902,8 +981,9 @@ int mwifiex_process_cmdresp(struct mwifi
|
||||
@@ -904,8 +983,9 @@ int mwifiex_process_cmdresp(struct mwifi
|
||||
if (adapter->hw_status == MWIFIEX_HW_STATUS_INITIALIZING) {
|
||||
if (ret) {
|
||||
mwifiex_dbg(adapter, ERROR,
|
||||
@ -139,7 +139,7 @@ Signed-off-by: Pali Rohár <pali@kernel.org>
|
||||
mwifiex_init_fw_complete(adapter);
|
||||
return -1;
|
||||
} else if (adapter->last_init_cmd == cmdresp_no)
|
||||
@@ -1265,8 +1345,8 @@ mwifiex_process_sleep_confirm_resp(struc
|
||||
@@ -1287,8 +1367,8 @@ mwifiex_process_sleep_confirm_resp(struc
|
||||
|
||||
if (command != HostCmd_CMD_802_11_PS_MODE_ENH) {
|
||||
mwifiex_dbg(adapter, ERROR,
|
||||
@ -152,7 +152,7 @@ Signed-off-by: Pali Rohár <pali@kernel.org>
|
||||
|
||||
--- a/drivers/net/wireless/marvell/mwifiex/main.h
|
||||
+++ b/drivers/net/wireless/marvell/mwifiex/main.h
|
||||
@@ -1084,6 +1084,8 @@ void mwifiex_cancel_all_pending_cmd(stru
|
||||
@@ -1100,6 +1100,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);
|
||||
|
||||
@ -177,7 +177,7 @@ Signed-off-by: Pali Rohár <pali@kernel.org>
|
||||
adapter->cmd_wait_q.status = -1;
|
||||
--- a/drivers/net/wireless/marvell/mwifiex/uap_cmd.c
|
||||
+++ b/drivers/net/wireless/marvell/mwifiex/uap_cmd.c
|
||||
@@ -802,7 +802,8 @@ int mwifiex_uap_prepare_cmd(struct mwifi
|
||||
@@ -964,7 +964,8 @@ int mwifiex_uap_prepare_cmd(struct mwifi
|
||||
break;
|
||||
default:
|
||||
mwifiex_dbg(priv->adapter, ERROR,
|
||||
|
@ -1,30 +0,0 @@
|
||||
From 8fbcaa308591b91e9037ab6a8d733873b749a70d Mon Sep 17 00:00:00 2001
|
||||
From: Bitterblue Smith <rtl8821cerfe2@gmail.com>
|
||||
Date: Sat, 6 Jul 2024 01:40:58 +0300
|
||||
Subject: [PATCH] wifi: rtw88: Set efuse->ext_lna_5g - fix typo
|
||||
|
||||
efuse->ext_lna_2g is set twice and efuse->ext_lna_5g is not set at all.
|
||||
Set each one once.
|
||||
|
||||
Nothing uses these members right now. They will be used by the RTL8821AU
|
||||
and RTL8812AU drivers.
|
||||
|
||||
Signed-off-by: Bitterblue Smith <rtl8821cerfe2@gmail.com>
|
||||
Acked-by: Ping-Ke Shih <pkshih@realtek.com>
|
||||
Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
|
||||
Link: https://patch.msgid.link/8ccc9e13-0d45-417d-8f88-93a0ad294f77@gmail.com
|
||||
---
|
||||
drivers/net/wireless/realtek/rtw88/main.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
--- a/drivers/net/wireless/realtek/rtw88/main.c
|
||||
+++ b/drivers/net/wireless/realtek/rtw88/main.c
|
||||
@@ -2006,7 +2006,7 @@ static int rtw_chip_efuse_info_setup(str
|
||||
efuse->ext_pa_2g = efuse->pa_type_2g & BIT(4) ? 1 : 0;
|
||||
efuse->ext_lna_2g = efuse->lna_type_2g & BIT(3) ? 1 : 0;
|
||||
efuse->ext_pa_5g = efuse->pa_type_5g & BIT(0) ? 1 : 0;
|
||||
- efuse->ext_lna_2g = efuse->lna_type_5g & BIT(3) ? 1 : 0;
|
||||
+ efuse->ext_lna_5g = efuse->lna_type_5g & BIT(3) ? 1 : 0;
|
||||
|
||||
if (!is_valid_ether_addr(efuse->addr)) {
|
||||
eth_random_addr(efuse->addr);
|
@ -1,284 +0,0 @@
|
||||
From 315c23a64e99552502dd4d18d6ddc073fad9a7c3 Mon Sep 17 00:00:00 2001
|
||||
From: Bitterblue Smith <rtl8821cerfe2@gmail.com>
|
||||
Date: Thu, 11 Jul 2024 01:11:33 +0300
|
||||
Subject: [PATCH] wifi: rtw88: usb: Support USB 3 with RTL8822CU/RTL8822BU
|
||||
|
||||
The Realtek wifi 5 devices which support USB 3 are weird: when first
|
||||
plugged in, they pretend to be USB 2. The driver needs to send some
|
||||
commands to the device, which make it disappear and come back as a
|
||||
USB 3 device.
|
||||
|
||||
Implement the required commands in rtw88.
|
||||
|
||||
When a USB 3 device is plugged into a USB 2 port, rtw88 will try to
|
||||
switch it to USB 3 mode only once. The device will disappear and come
|
||||
back still in USB 2 mode, of course.
|
||||
|
||||
Some people experience heavy interference in the 2.4 GHz band in
|
||||
USB 3 mode, so add a module parameter switch_usb_mode with the
|
||||
default value 1 to let people disable the switching.
|
||||
|
||||
Signed-off-by: Bitterblue Smith <rtl8821cerfe2@gmail.com>
|
||||
Acked-by: Ping-Ke Shih <pkshih@realtek.com>
|
||||
Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
|
||||
Link: https://patch.msgid.link/77906c62-5674-426f-bde1-1b2a12a0339d@gmail.com
|
||||
---
|
||||
drivers/net/wireless/realtek/rtw88/debug.h | 1 +
|
||||
drivers/net/wireless/realtek/rtw88/main.h | 2 +
|
||||
drivers/net/wireless/realtek/rtw88/reg.h | 11 +++
|
||||
drivers/net/wireless/realtek/rtw88/rtw8822b.c | 1 +
|
||||
drivers/net/wireless/realtek/rtw88/rtw8822b.h | 4 +-
|
||||
drivers/net/wireless/realtek/rtw88/rtw8822c.c | 1 +
|
||||
drivers/net/wireless/realtek/rtw88/rtw8822c.h | 24 +++---
|
||||
drivers/net/wireless/realtek/rtw88/usb.c | 84 +++++++++++++++++++
|
||||
8 files changed, 116 insertions(+), 12 deletions(-)
|
||||
|
||||
--- a/drivers/net/wireless/realtek/rtw88/debug.h
|
||||
+++ b/drivers/net/wireless/realtek/rtw88/debug.h
|
||||
@@ -25,6 +25,7 @@ enum rtw_debug_mask {
|
||||
RTW_DBG_HW_SCAN = 0x00010000,
|
||||
RTW_DBG_STATE = 0x00020000,
|
||||
RTW_DBG_SDIO = 0x00040000,
|
||||
+ RTW_DBG_USB = 0x00080000,
|
||||
|
||||
RTW_DBG_UNEXP = 0x80000000,
|
||||
RTW_DBG_ALL = 0xffffffff
|
||||
--- a/drivers/net/wireless/realtek/rtw88/main.h
|
||||
+++ b/drivers/net/wireless/realtek/rtw88/main.h
|
||||
@@ -1785,6 +1785,8 @@ struct rtw_efuse {
|
||||
bool share_ant;
|
||||
u8 bt_setting;
|
||||
|
||||
+ u8 usb_mode_switch;
|
||||
+
|
||||
struct {
|
||||
u8 hci;
|
||||
u8 bw;
|
||||
--- a/drivers/net/wireless/realtek/rtw88/reg.h
|
||||
+++ b/drivers/net/wireless/realtek/rtw88/reg.h
|
||||
@@ -15,6 +15,7 @@
|
||||
#define BIT_WLOCK_1C_B6 BIT(5)
|
||||
#define REG_SYS_PW_CTRL 0x0004
|
||||
#define BIT_PFM_WOWL BIT(3)
|
||||
+#define BIT_APFM_OFFMAC BIT(9)
|
||||
#define REG_SYS_CLK_CTRL 0x0008
|
||||
#define BIT_CPU_CLK_EN BIT(14)
|
||||
|
||||
@@ -133,6 +134,14 @@
|
||||
#define REG_PMC_DBG_CTRL1 0xa8
|
||||
#define BITS_PMC_BT_IQK_STS GENMASK(22, 21)
|
||||
|
||||
+#define REG_PAD_CTRL2 0x00C4
|
||||
+#define BIT_RSM_EN_V1 BIT(16)
|
||||
+#define BIT_NO_PDN_CHIPOFF_V1 BIT(17)
|
||||
+#define BIT_MASK_USB23_SW_MODE_V1 GENMASK(19, 18)
|
||||
+#define BIT_USB3_USB2_TRANSITION BIT(20)
|
||||
+#define BIT_USB_MODE_U2 1
|
||||
+#define BIT_USB_MODE_U3 2
|
||||
+
|
||||
#define REG_EFUSE_ACCESS 0x00CF
|
||||
#define EFUSE_ACCESS_ON 0x69
|
||||
#define EFUSE_ACCESS_OFF 0x00
|
||||
@@ -568,6 +577,8 @@
|
||||
#define BIT_WL_SECURITY_CLK BIT(15)
|
||||
#define BIT_DDMA_EN BIT(8)
|
||||
|
||||
+#define REG_SW_MDIO 0x10C0
|
||||
+
|
||||
#define REG_H2C_PKT_READADDR 0x10D0
|
||||
#define REG_H2C_PKT_WRITEADDR 0x10D4
|
||||
#define REG_FW_DBG6 0x10F8
|
||||
--- a/drivers/net/wireless/realtek/rtw88/rtw8822b.c
|
||||
+++ b/drivers/net/wireless/realtek/rtw88/rtw8822b.c
|
||||
@@ -46,6 +46,7 @@ static int rtw8822b_read_efuse(struct rt
|
||||
|
||||
map = (struct rtw8822b_efuse *)log_map;
|
||||
|
||||
+ efuse->usb_mode_switch = u8_get_bits(map->usb_mode, BIT(7));
|
||||
efuse->rfe_option = map->rfe_option;
|
||||
efuse->rf_board_option = map->rf_board_option;
|
||||
efuse->crystal_cap = map->xtal_k;
|
||||
--- a/drivers/net/wireless/realtek/rtw88/rtw8822b.h
|
||||
+++ b/drivers/net/wireless/realtek/rtw88/rtw8822b.h
|
||||
@@ -72,7 +72,9 @@ struct rtw8822bs_efuse {
|
||||
|
||||
struct rtw8822b_efuse {
|
||||
__le16 rtl_id;
|
||||
- u8 res0[0x0e];
|
||||
+ u8 res0[4];
|
||||
+ u8 usb_mode;
|
||||
+ u8 res1[0x09];
|
||||
|
||||
/* power index for four RF paths */
|
||||
struct rtw_txpwr_idx txpwr_idx_table[4];
|
||||
--- a/drivers/net/wireless/realtek/rtw88/rtw8822c.c
|
||||
+++ b/drivers/net/wireless/realtek/rtw88/rtw8822c.c
|
||||
@@ -49,6 +49,7 @@ static int rtw8822c_read_efuse(struct rt
|
||||
|
||||
map = (struct rtw8822c_efuse *)log_map;
|
||||
|
||||
+ efuse->usb_mode_switch = u8_get_bits(map->usb_mode, BIT(7));
|
||||
efuse->rfe_option = map->rfe_option;
|
||||
efuse->rf_board_option = map->rf_board_option;
|
||||
efuse->crystal_cap = map->xtal_k & XCAP_MASK;
|
||||
--- a/drivers/net/wireless/realtek/rtw88/rtw8822c.h
|
||||
+++ b/drivers/net/wireless/realtek/rtw88/rtw8822c.h
|
||||
@@ -59,16 +59,18 @@ struct rtw8822ce_efuse {
|
||||
|
||||
struct rtw8822c_efuse {
|
||||
__le16 rtl_id;
|
||||
- u8 res0[0x0e];
|
||||
+ u8 res0[4];
|
||||
+ u8 usb_mode;
|
||||
+ u8 res1[0x09];
|
||||
|
||||
/* power index for four RF paths */
|
||||
struct rtw_txpwr_idx txpwr_idx_table[4];
|
||||
|
||||
u8 channel_plan; /* 0xb8 */
|
||||
u8 xtal_k;
|
||||
- u8 res1;
|
||||
+ u8 res2;
|
||||
u8 iqk_lck;
|
||||
- u8 res2[5]; /* 0xbc */
|
||||
+ u8 res3[5]; /* 0xbc */
|
||||
u8 rf_board_option;
|
||||
u8 rf_feature_option;
|
||||
u8 rf_bt_setting;
|
||||
@@ -80,21 +82,21 @@ struct rtw8822c_efuse {
|
||||
u8 rf_antenna_option; /* 0xc9 */
|
||||
u8 rfe_option;
|
||||
u8 country_code[2];
|
||||
- u8 res3[3];
|
||||
+ u8 res4[3];
|
||||
u8 path_a_thermal; /* 0xd0 */
|
||||
u8 path_b_thermal;
|
||||
- u8 res4[2];
|
||||
+ u8 res5[2];
|
||||
u8 rx_gain_gap_2g_ofdm;
|
||||
- u8 res5;
|
||||
- u8 rx_gain_gap_2g_cck;
|
||||
u8 res6;
|
||||
- u8 rx_gain_gap_5gl;
|
||||
+ u8 rx_gain_gap_2g_cck;
|
||||
u8 res7;
|
||||
- u8 rx_gain_gap_5gm;
|
||||
+ u8 rx_gain_gap_5gl;
|
||||
u8 res8;
|
||||
- u8 rx_gain_gap_5gh;
|
||||
+ u8 rx_gain_gap_5gm;
|
||||
u8 res9;
|
||||
- u8 res10[0x42];
|
||||
+ u8 rx_gain_gap_5gh;
|
||||
+ u8 res10;
|
||||
+ u8 res11[0x42];
|
||||
union {
|
||||
struct rtw8822ce_efuse e;
|
||||
struct rtw8822cu_efuse u;
|
||||
--- a/drivers/net/wireless/realtek/rtw88/usb.c
|
||||
+++ b/drivers/net/wireless/realtek/rtw88/usb.c
|
||||
@@ -14,6 +14,11 @@
|
||||
#include "ps.h"
|
||||
#include "usb.h"
|
||||
|
||||
+static bool rtw_switch_usb_mode = true;
|
||||
+module_param_named(switch_usb_mode, rtw_switch_usb_mode, bool, 0644);
|
||||
+MODULE_PARM_DESC(switch_usb_mode,
|
||||
+ "Set to N to disable switching to USB 3 mode to avoid potential interference in the 2.4 GHz band (default: Y)");
|
||||
+
|
||||
#define RTW_USB_MAX_RXQ_LEN 512
|
||||
|
||||
struct rtw_usb_txcb {
|
||||
@@ -841,6 +846,77 @@ static void rtw_usb_intf_deinit(struct r
|
||||
usb_set_intfdata(intf, NULL);
|
||||
}
|
||||
|
||||
+static int rtw_usb_switch_mode_new(struct rtw_dev *rtwdev)
|
||||
+{
|
||||
+ enum usb_device_speed cur_speed;
|
||||
+ u8 id = rtwdev->chip->id;
|
||||
+ bool can_switch;
|
||||
+ u32 pad_ctrl2;
|
||||
+
|
||||
+ if (rtw_read8(rtwdev, REG_SYS_CFG2 + 3) == 0x20)
|
||||
+ cur_speed = USB_SPEED_SUPER;
|
||||
+ else
|
||||
+ cur_speed = USB_SPEED_HIGH;
|
||||
+
|
||||
+ if (cur_speed == USB_SPEED_SUPER)
|
||||
+ return 0;
|
||||
+
|
||||
+ pad_ctrl2 = rtw_read32(rtwdev, REG_PAD_CTRL2);
|
||||
+
|
||||
+ can_switch = !!(pad_ctrl2 & (BIT_MASK_USB23_SW_MODE_V1 |
|
||||
+ BIT_USB3_USB2_TRANSITION));
|
||||
+
|
||||
+ if (!can_switch) {
|
||||
+ rtw_dbg(rtwdev, RTW_DBG_USB,
|
||||
+ "Switching to USB 3 mode unsupported by the chip\n");
|
||||
+ return 0;
|
||||
+ }
|
||||
+
|
||||
+ /* At this point cur_speed is USB_SPEED_HIGH. If we already tried
|
||||
+ * to switch don't try again - it's a USB 2 port.
|
||||
+ */
|
||||
+ if (u32_get_bits(pad_ctrl2, BIT_MASK_USB23_SW_MODE_V1) == BIT_USB_MODE_U3)
|
||||
+ return 0;
|
||||
+
|
||||
+ /* Enable IO wrapper timeout */
|
||||
+ if (id == RTW_CHIP_TYPE_8822B || id == RTW_CHIP_TYPE_8821C)
|
||||
+ rtw_write8_clr(rtwdev, REG_SW_MDIO + 3, BIT(0));
|
||||
+
|
||||
+ u32p_replace_bits(&pad_ctrl2, BIT_USB_MODE_U3, BIT_MASK_USB23_SW_MODE_V1);
|
||||
+ pad_ctrl2 |= BIT_RSM_EN_V1;
|
||||
+
|
||||
+ rtw_write32(rtwdev, REG_PAD_CTRL2, pad_ctrl2);
|
||||
+ rtw_write8(rtwdev, REG_PAD_CTRL2 + 1, 4);
|
||||
+
|
||||
+ rtw_write16_set(rtwdev, REG_SYS_PW_CTRL, BIT_APFM_OFFMAC);
|
||||
+ usleep_range(1000, 1001);
|
||||
+ rtw_write32_set(rtwdev, REG_PAD_CTRL2, BIT_NO_PDN_CHIPOFF_V1);
|
||||
+
|
||||
+ return 1;
|
||||
+}
|
||||
+
|
||||
+static int rtw_usb_switch_mode(struct rtw_dev *rtwdev)
|
||||
+{
|
||||
+ u8 id = rtwdev->chip->id;
|
||||
+
|
||||
+ if (id != RTW_CHIP_TYPE_8822C && id != RTW_CHIP_TYPE_8822B)
|
||||
+ return 0;
|
||||
+
|
||||
+ if (!rtwdev->efuse.usb_mode_switch) {
|
||||
+ rtw_dbg(rtwdev, RTW_DBG_USB,
|
||||
+ "Switching to USB 3 mode disabled by chip's efuse\n");
|
||||
+ return 0;
|
||||
+ }
|
||||
+
|
||||
+ if (!rtw_switch_usb_mode) {
|
||||
+ rtw_dbg(rtwdev, RTW_DBG_USB,
|
||||
+ "Switching to USB 3 mode disabled by module parameter\n");
|
||||
+ return 0;
|
||||
+ }
|
||||
+
|
||||
+ return rtw_usb_switch_mode_new(rtwdev);
|
||||
+}
|
||||
+
|
||||
int rtw_usb_probe(struct usb_interface *intf, const struct usb_device_id *id)
|
||||
{
|
||||
struct rtw_dev *rtwdev;
|
||||
@@ -896,6 +972,14 @@ int rtw_usb_probe(struct usb_interface *
|
||||
goto err_destroy_rxwq;
|
||||
}
|
||||
|
||||
+ ret = rtw_usb_switch_mode(rtwdev);
|
||||
+ if (ret) {
|
||||
+ /* Not a fail, but we do need to skip rtw_register_hw. */
|
||||
+ rtw_dbg(rtwdev, RTW_DBG_USB, "switching to USB 3 mode\n");
|
||||
+ ret = 0;
|
||||
+ goto err_destroy_rxwq;
|
||||
+ }
|
||||
+
|
||||
ret = rtw_register_hw(rtwdev, rtwdev->hw);
|
||||
if (ret) {
|
||||
rtw_err(rtwdev, "failed to register hw\n");
|
@ -1,454 +0,0 @@
|
||||
From 8db6c1ca64664ef9b071e6eeb646023ac5b240a8 Mon Sep 17 00:00:00 2001
|
||||
From: Ping-Ke Shih <pkshih@realtek.com>
|
||||
Date: Thu, 18 Jul 2024 14:41:55 +0800
|
||||
Subject: [PATCH] wifi: rtw88: debugfs: support multiple adapters debugging
|
||||
|
||||
Originally in order to read partial registers from large area, we write
|
||||
a range value stored into a static variable and read registers according
|
||||
to the static variable.
|
||||
|
||||
However, if we install more than one adapters supported by this driver,
|
||||
the static variables will be overwritten by latter adapters. To resolve
|
||||
the problem, move the static variables to struct rtw_dev for each adapter.
|
||||
|
||||
With changes, smatch spends too much time to parse rtw_debugfs_init():
|
||||
debug.c:1289 rtw_debugfs_init() parse error: turning off implications
|
||||
after 60 seconds
|
||||
Move stuffs of adding debugfs entries to three rtw_debugfs_add_xxx()
|
||||
functions.
|
||||
|
||||
Reported-by: Bitterblue Smith <rtl8821cerfe2@gmail.com>
|
||||
Closes: https://lore.kernel.org/linux-wireless/cd6a2acf3c2c36d938b40140b52a779516f446a9.camel@realtek.com/T/#m27662022c70d9f893ba96f6c6a8dd8fce2434dfe
|
||||
Tested-by: Bitterblue Smith <rtl8821cerfe2@gmail.com>
|
||||
Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
|
||||
Link: https://patch.msgid.link/20240718064155.38955-1-pkshih@realtek.com
|
||||
---
|
||||
drivers/net/wireless/realtek/rtw88/debug.c | 303 ++++++++++++---------
|
||||
drivers/net/wireless/realtek/rtw88/debug.h | 2 +
|
||||
drivers/net/wireless/realtek/rtw88/main.c | 1 +
|
||||
drivers/net/wireless/realtek/rtw88/main.h | 3 +-
|
||||
4 files changed, 180 insertions(+), 129 deletions(-)
|
||||
|
||||
--- a/drivers/net/wireless/realtek/rtw88/debug.c
|
||||
+++ b/drivers/net/wireless/realtek/rtw88/debug.c
|
||||
@@ -43,6 +43,62 @@ struct rtw_debugfs_priv {
|
||||
};
|
||||
};
|
||||
|
||||
+struct rtw_debugfs {
|
||||
+ struct rtw_debugfs_priv mac_0;
|
||||
+ struct rtw_debugfs_priv mac_1;
|
||||
+ struct rtw_debugfs_priv mac_2;
|
||||
+ struct rtw_debugfs_priv mac_3;
|
||||
+ struct rtw_debugfs_priv mac_4;
|
||||
+ struct rtw_debugfs_priv mac_5;
|
||||
+ struct rtw_debugfs_priv mac_6;
|
||||
+ struct rtw_debugfs_priv mac_7;
|
||||
+ struct rtw_debugfs_priv mac_10;
|
||||
+ struct rtw_debugfs_priv mac_11;
|
||||
+ struct rtw_debugfs_priv mac_12;
|
||||
+ struct rtw_debugfs_priv mac_13;
|
||||
+ struct rtw_debugfs_priv mac_14;
|
||||
+ struct rtw_debugfs_priv mac_15;
|
||||
+ struct rtw_debugfs_priv mac_16;
|
||||
+ struct rtw_debugfs_priv mac_17;
|
||||
+ struct rtw_debugfs_priv bb_8;
|
||||
+ struct rtw_debugfs_priv bb_9;
|
||||
+ struct rtw_debugfs_priv bb_a;
|
||||
+ struct rtw_debugfs_priv bb_b;
|
||||
+ struct rtw_debugfs_priv bb_c;
|
||||
+ struct rtw_debugfs_priv bb_d;
|
||||
+ struct rtw_debugfs_priv bb_e;
|
||||
+ struct rtw_debugfs_priv bb_f;
|
||||
+ struct rtw_debugfs_priv bb_18;
|
||||
+ struct rtw_debugfs_priv bb_19;
|
||||
+ struct rtw_debugfs_priv bb_1a;
|
||||
+ struct rtw_debugfs_priv bb_1b;
|
||||
+ struct rtw_debugfs_priv bb_1c;
|
||||
+ struct rtw_debugfs_priv bb_1d;
|
||||
+ struct rtw_debugfs_priv bb_1e;
|
||||
+ struct rtw_debugfs_priv bb_1f;
|
||||
+ struct rtw_debugfs_priv bb_2c;
|
||||
+ struct rtw_debugfs_priv bb_2d;
|
||||
+ struct rtw_debugfs_priv bb_40;
|
||||
+ struct rtw_debugfs_priv bb_41;
|
||||
+ struct rtw_debugfs_priv rf_dump;
|
||||
+ struct rtw_debugfs_priv tx_pwr_tbl;
|
||||
+ struct rtw_debugfs_priv write_reg;
|
||||
+ struct rtw_debugfs_priv h2c;
|
||||
+ struct rtw_debugfs_priv rf_write;
|
||||
+ struct rtw_debugfs_priv rf_read;
|
||||
+ struct rtw_debugfs_priv read_reg;
|
||||
+ struct rtw_debugfs_priv fix_rate;
|
||||
+ struct rtw_debugfs_priv dump_cam;
|
||||
+ struct rtw_debugfs_priv rsvd_page;
|
||||
+ struct rtw_debugfs_priv phy_info;
|
||||
+ struct rtw_debugfs_priv coex_enable;
|
||||
+ struct rtw_debugfs_priv coex_info;
|
||||
+ struct rtw_debugfs_priv edcca_enable;
|
||||
+ struct rtw_debugfs_priv fw_crash;
|
||||
+ struct rtw_debugfs_priv force_lowest_basic_rate;
|
||||
+ struct rtw_debugfs_priv dm_cap;
|
||||
+};
|
||||
+
|
||||
static const char * const rtw_dm_cap_strs[] = {
|
||||
[RTW_DM_CAP_NA] = "NA",
|
||||
[RTW_DM_CAP_TXGAPK] = "TXGAPK",
|
||||
@@ -524,7 +580,7 @@ static int rtw_debug_get_bb_page(struct
|
||||
return 0;
|
||||
}
|
||||
|
||||
-static int rtw_debug_get_rf_dump(struct seq_file *m, void *v)
|
||||
+static int rtw_debugfs_get_rf_dump(struct seq_file *m, void *v)
|
||||
{
|
||||
struct rtw_debugfs_priv *debugfs_priv = m->private;
|
||||
struct rtw_dev *rtwdev = debugfs_priv->rtwdev;
|
||||
@@ -1074,139 +1130,102 @@ static int rtw_debugfs_get_dm_cap(struct
|
||||
return 0;
|
||||
}
|
||||
|
||||
-#define rtw_debug_impl_mac(page, addr) \
|
||||
-static struct rtw_debugfs_priv rtw_debug_priv_mac_ ##page = { \
|
||||
+#define rtw_debug_priv_mac(addr) \
|
||||
+{ \
|
||||
.cb_read = rtw_debug_get_mac_page, \
|
||||
.cb_data = addr, \
|
||||
}
|
||||
|
||||
-rtw_debug_impl_mac(0, 0x0000);
|
||||
-rtw_debug_impl_mac(1, 0x0100);
|
||||
-rtw_debug_impl_mac(2, 0x0200);
|
||||
-rtw_debug_impl_mac(3, 0x0300);
|
||||
-rtw_debug_impl_mac(4, 0x0400);
|
||||
-rtw_debug_impl_mac(5, 0x0500);
|
||||
-rtw_debug_impl_mac(6, 0x0600);
|
||||
-rtw_debug_impl_mac(7, 0x0700);
|
||||
-rtw_debug_impl_mac(10, 0x1000);
|
||||
-rtw_debug_impl_mac(11, 0x1100);
|
||||
-rtw_debug_impl_mac(12, 0x1200);
|
||||
-rtw_debug_impl_mac(13, 0x1300);
|
||||
-rtw_debug_impl_mac(14, 0x1400);
|
||||
-rtw_debug_impl_mac(15, 0x1500);
|
||||
-rtw_debug_impl_mac(16, 0x1600);
|
||||
-rtw_debug_impl_mac(17, 0x1700);
|
||||
-
|
||||
-#define rtw_debug_impl_bb(page, addr) \
|
||||
-static struct rtw_debugfs_priv rtw_debug_priv_bb_ ##page = { \
|
||||
+#define rtw_debug_priv_bb(addr) \
|
||||
+{ \
|
||||
.cb_read = rtw_debug_get_bb_page, \
|
||||
.cb_data = addr, \
|
||||
}
|
||||
|
||||
-rtw_debug_impl_bb(8, 0x0800);
|
||||
-rtw_debug_impl_bb(9, 0x0900);
|
||||
-rtw_debug_impl_bb(a, 0x0a00);
|
||||
-rtw_debug_impl_bb(b, 0x0b00);
|
||||
-rtw_debug_impl_bb(c, 0x0c00);
|
||||
-rtw_debug_impl_bb(d, 0x0d00);
|
||||
-rtw_debug_impl_bb(e, 0x0e00);
|
||||
-rtw_debug_impl_bb(f, 0x0f00);
|
||||
-rtw_debug_impl_bb(18, 0x1800);
|
||||
-rtw_debug_impl_bb(19, 0x1900);
|
||||
-rtw_debug_impl_bb(1a, 0x1a00);
|
||||
-rtw_debug_impl_bb(1b, 0x1b00);
|
||||
-rtw_debug_impl_bb(1c, 0x1c00);
|
||||
-rtw_debug_impl_bb(1d, 0x1d00);
|
||||
-rtw_debug_impl_bb(1e, 0x1e00);
|
||||
-rtw_debug_impl_bb(1f, 0x1f00);
|
||||
-rtw_debug_impl_bb(2c, 0x2c00);
|
||||
-rtw_debug_impl_bb(2d, 0x2d00);
|
||||
-rtw_debug_impl_bb(40, 0x4000);
|
||||
-rtw_debug_impl_bb(41, 0x4100);
|
||||
-
|
||||
-static struct rtw_debugfs_priv rtw_debug_priv_rf_dump = {
|
||||
- .cb_read = rtw_debug_get_rf_dump,
|
||||
-};
|
||||
-
|
||||
-static struct rtw_debugfs_priv rtw_debug_priv_tx_pwr_tbl = {
|
||||
- .cb_read = rtw_debugfs_get_tx_pwr_tbl,
|
||||
-};
|
||||
-
|
||||
-static struct rtw_debugfs_priv rtw_debug_priv_write_reg = {
|
||||
- .cb_write = rtw_debugfs_set_write_reg,
|
||||
-};
|
||||
-
|
||||
-static struct rtw_debugfs_priv rtw_debug_priv_h2c = {
|
||||
- .cb_write = rtw_debugfs_set_h2c,
|
||||
-};
|
||||
-
|
||||
-static struct rtw_debugfs_priv rtw_debug_priv_rf_write = {
|
||||
- .cb_write = rtw_debugfs_set_rf_write,
|
||||
-};
|
||||
-
|
||||
-static struct rtw_debugfs_priv rtw_debug_priv_rf_read = {
|
||||
- .cb_write = rtw_debugfs_set_rf_read,
|
||||
- .cb_read = rtw_debugfs_get_rf_read,
|
||||
-};
|
||||
-
|
||||
-static struct rtw_debugfs_priv rtw_debug_priv_read_reg = {
|
||||
- .cb_write = rtw_debugfs_set_read_reg,
|
||||
- .cb_read = rtw_debugfs_get_read_reg,
|
||||
-};
|
||||
-
|
||||
-static struct rtw_debugfs_priv rtw_debug_priv_fix_rate = {
|
||||
- .cb_write = rtw_debugfs_set_fix_rate,
|
||||
- .cb_read = rtw_debugfs_get_fix_rate,
|
||||
-};
|
||||
-
|
||||
-static struct rtw_debugfs_priv rtw_debug_priv_dump_cam = {
|
||||
- .cb_write = rtw_debugfs_set_single_input,
|
||||
- .cb_read = rtw_debugfs_get_dump_cam,
|
||||
-};
|
||||
-
|
||||
-static struct rtw_debugfs_priv rtw_debug_priv_rsvd_page = {
|
||||
- .cb_write = rtw_debugfs_set_rsvd_page,
|
||||
- .cb_read = rtw_debugfs_get_rsvd_page,
|
||||
-};
|
||||
-
|
||||
-static struct rtw_debugfs_priv rtw_debug_priv_phy_info = {
|
||||
- .cb_read = rtw_debugfs_get_phy_info,
|
||||
-};
|
||||
-
|
||||
-static struct rtw_debugfs_priv rtw_debug_priv_coex_enable = {
|
||||
- .cb_write = rtw_debugfs_set_coex_enable,
|
||||
- .cb_read = rtw_debugfs_get_coex_enable,
|
||||
-};
|
||||
-
|
||||
-static struct rtw_debugfs_priv rtw_debug_priv_coex_info = {
|
||||
- .cb_read = rtw_debugfs_get_coex_info,
|
||||
-};
|
||||
-
|
||||
-static struct rtw_debugfs_priv rtw_debug_priv_edcca_enable = {
|
||||
- .cb_write = rtw_debugfs_set_edcca_enable,
|
||||
- .cb_read = rtw_debugfs_get_edcca_enable,
|
||||
-};
|
||||
-
|
||||
-static struct rtw_debugfs_priv rtw_debug_priv_fw_crash = {
|
||||
- .cb_write = rtw_debugfs_set_fw_crash,
|
||||
- .cb_read = rtw_debugfs_get_fw_crash,
|
||||
-};
|
||||
-
|
||||
-static struct rtw_debugfs_priv rtw_debug_priv_force_lowest_basic_rate = {
|
||||
- .cb_write = rtw_debugfs_set_force_lowest_basic_rate,
|
||||
- .cb_read = rtw_debugfs_get_force_lowest_basic_rate,
|
||||
-};
|
||||
-
|
||||
-static struct rtw_debugfs_priv rtw_debug_priv_dm_cap = {
|
||||
- .cb_write = rtw_debugfs_set_dm_cap,
|
||||
- .cb_read = rtw_debugfs_get_dm_cap,
|
||||
+#define rtw_debug_priv_get(name) \
|
||||
+{ \
|
||||
+ .cb_read = rtw_debugfs_get_ ##name, \
|
||||
+}
|
||||
+
|
||||
+#define rtw_debug_priv_set(name) \
|
||||
+{ \
|
||||
+ .cb_write = rtw_debugfs_set_ ##name, \
|
||||
+}
|
||||
+
|
||||
+#define rtw_debug_priv_set_and_get(name) \
|
||||
+{ \
|
||||
+ .cb_write = rtw_debugfs_set_ ##name, \
|
||||
+ .cb_read = rtw_debugfs_get_ ##name, \
|
||||
+}
|
||||
+
|
||||
+#define rtw_debug_priv_set_single_and_get(name) \
|
||||
+{ \
|
||||
+ .cb_write = rtw_debugfs_set_single_input, \
|
||||
+ .cb_read = rtw_debugfs_get_ ##name, \
|
||||
+}
|
||||
+
|
||||
+static const struct rtw_debugfs rtw_debugfs_templ = {
|
||||
+ .mac_0 = rtw_debug_priv_mac(0x0000),
|
||||
+ .mac_1 = rtw_debug_priv_mac(0x0100),
|
||||
+ .mac_2 = rtw_debug_priv_mac(0x0200),
|
||||
+ .mac_3 = rtw_debug_priv_mac(0x0300),
|
||||
+ .mac_4 = rtw_debug_priv_mac(0x0400),
|
||||
+ .mac_5 = rtw_debug_priv_mac(0x0500),
|
||||
+ .mac_6 = rtw_debug_priv_mac(0x0600),
|
||||
+ .mac_7 = rtw_debug_priv_mac(0x0700),
|
||||
+ .mac_10 = rtw_debug_priv_mac(0x1000),
|
||||
+ .mac_11 = rtw_debug_priv_mac(0x1100),
|
||||
+ .mac_12 = rtw_debug_priv_mac(0x1200),
|
||||
+ .mac_13 = rtw_debug_priv_mac(0x1300),
|
||||
+ .mac_14 = rtw_debug_priv_mac(0x1400),
|
||||
+ .mac_15 = rtw_debug_priv_mac(0x1500),
|
||||
+ .mac_16 = rtw_debug_priv_mac(0x1600),
|
||||
+ .mac_17 = rtw_debug_priv_mac(0x1700),
|
||||
+ .bb_8 = rtw_debug_priv_bb(0x0800),
|
||||
+ .bb_9 = rtw_debug_priv_bb(0x0900),
|
||||
+ .bb_a = rtw_debug_priv_bb(0x0a00),
|
||||
+ .bb_b = rtw_debug_priv_bb(0x0b00),
|
||||
+ .bb_c = rtw_debug_priv_bb(0x0c00),
|
||||
+ .bb_d = rtw_debug_priv_bb(0x0d00),
|
||||
+ .bb_e = rtw_debug_priv_bb(0x0e00),
|
||||
+ .bb_f = rtw_debug_priv_bb(0x0f00),
|
||||
+ .bb_18 = rtw_debug_priv_bb(0x1800),
|
||||
+ .bb_19 = rtw_debug_priv_bb(0x1900),
|
||||
+ .bb_1a = rtw_debug_priv_bb(0x1a00),
|
||||
+ .bb_1b = rtw_debug_priv_bb(0x1b00),
|
||||
+ .bb_1c = rtw_debug_priv_bb(0x1c00),
|
||||
+ .bb_1d = rtw_debug_priv_bb(0x1d00),
|
||||
+ .bb_1e = rtw_debug_priv_bb(0x1e00),
|
||||
+ .bb_1f = rtw_debug_priv_bb(0x1f00),
|
||||
+ .bb_2c = rtw_debug_priv_bb(0x2c00),
|
||||
+ .bb_2d = rtw_debug_priv_bb(0x2d00),
|
||||
+ .bb_40 = rtw_debug_priv_bb(0x4000),
|
||||
+ .bb_41 = rtw_debug_priv_bb(0x4100),
|
||||
+ .rf_dump = rtw_debug_priv_get(rf_dump),
|
||||
+ .tx_pwr_tbl = rtw_debug_priv_get(tx_pwr_tbl),
|
||||
+ .write_reg = rtw_debug_priv_set(write_reg),
|
||||
+ .h2c = rtw_debug_priv_set(h2c),
|
||||
+ .rf_write = rtw_debug_priv_set(rf_write),
|
||||
+ .rf_read = rtw_debug_priv_set_and_get(rf_read),
|
||||
+ .read_reg = rtw_debug_priv_set_and_get(read_reg),
|
||||
+ .fix_rate = rtw_debug_priv_set_and_get(fix_rate),
|
||||
+ .dump_cam = rtw_debug_priv_set_single_and_get(dump_cam),
|
||||
+ .rsvd_page = rtw_debug_priv_set_and_get(rsvd_page),
|
||||
+ .phy_info = rtw_debug_priv_get(phy_info),
|
||||
+ .coex_enable = rtw_debug_priv_set_and_get(coex_enable),
|
||||
+ .coex_info = rtw_debug_priv_get(coex_info),
|
||||
+ .edcca_enable = rtw_debug_priv_set_and_get(edcca_enable),
|
||||
+ .fw_crash = rtw_debug_priv_set_and_get(fw_crash),
|
||||
+ .force_lowest_basic_rate = rtw_debug_priv_set_and_get(force_lowest_basic_rate),
|
||||
+ .dm_cap = rtw_debug_priv_set_and_get(dm_cap),
|
||||
};
|
||||
|
||||
#define rtw_debugfs_add_core(name, mode, fopname, parent) \
|
||||
do { \
|
||||
- rtw_debug_priv_ ##name.rtwdev = rtwdev; \
|
||||
+ struct rtw_debugfs_priv *priv = &rtwdev->debugfs->name; \
|
||||
+ priv->rtwdev = rtwdev; \
|
||||
if (IS_ERR(debugfs_create_file(#name, mode, \
|
||||
- parent, &rtw_debug_priv_ ##name,\
|
||||
+ parent, priv, \
|
||||
&file_ops_ ##fopname))) \
|
||||
pr_debug("Unable to initialize debugfs:%s\n", \
|
||||
#name); \
|
||||
@@ -1219,12 +1238,9 @@ static struct rtw_debugfs_priv rtw_debug
|
||||
#define rtw_debugfs_add_r(name) \
|
||||
rtw_debugfs_add_core(name, S_IFREG | 0444, single_r, debugfs_topdir)
|
||||
|
||||
-void rtw_debugfs_init(struct rtw_dev *rtwdev)
|
||||
+static
|
||||
+void rtw_debugfs_add_basic(struct rtw_dev *rtwdev, struct dentry *debugfs_topdir)
|
||||
{
|
||||
- struct dentry *debugfs_topdir;
|
||||
-
|
||||
- debugfs_topdir = debugfs_create_dir("rtw88",
|
||||
- rtwdev->hw->wiphy->debugfsdir);
|
||||
rtw_debugfs_add_w(write_reg);
|
||||
rtw_debugfs_add_rw(read_reg);
|
||||
rtw_debugfs_add_w(rf_write);
|
||||
@@ -1236,6 +1252,17 @@ void rtw_debugfs_init(struct rtw_dev *rt
|
||||
rtw_debugfs_add_r(coex_info);
|
||||
rtw_debugfs_add_rw(coex_enable);
|
||||
rtw_debugfs_add_w(h2c);
|
||||
+ rtw_debugfs_add_r(rf_dump);
|
||||
+ rtw_debugfs_add_r(tx_pwr_tbl);
|
||||
+ rtw_debugfs_add_rw(edcca_enable);
|
||||
+ rtw_debugfs_add_rw(fw_crash);
|
||||
+ rtw_debugfs_add_rw(force_lowest_basic_rate);
|
||||
+ rtw_debugfs_add_rw(dm_cap);
|
||||
+}
|
||||
+
|
||||
+static
|
||||
+void rtw_debugfs_add_sec0(struct rtw_dev *rtwdev, struct dentry *debugfs_topdir)
|
||||
+{
|
||||
rtw_debugfs_add_r(mac_0);
|
||||
rtw_debugfs_add_r(mac_1);
|
||||
rtw_debugfs_add_r(mac_2);
|
||||
@@ -1252,6 +1279,11 @@ void rtw_debugfs_init(struct rtw_dev *rt
|
||||
rtw_debugfs_add_r(bb_d);
|
||||
rtw_debugfs_add_r(bb_e);
|
||||
rtw_debugfs_add_r(bb_f);
|
||||
+}
|
||||
+
|
||||
+static
|
||||
+void rtw_debugfs_add_sec1(struct rtw_dev *rtwdev, struct dentry *debugfs_topdir)
|
||||
+{
|
||||
rtw_debugfs_add_r(mac_10);
|
||||
rtw_debugfs_add_r(mac_11);
|
||||
rtw_debugfs_add_r(mac_12);
|
||||
@@ -1274,14 +1306,29 @@ void rtw_debugfs_init(struct rtw_dev *rt
|
||||
rtw_debugfs_add_r(bb_40);
|
||||
rtw_debugfs_add_r(bb_41);
|
||||
}
|
||||
- rtw_debugfs_add_r(rf_dump);
|
||||
- rtw_debugfs_add_r(tx_pwr_tbl);
|
||||
- rtw_debugfs_add_rw(edcca_enable);
|
||||
- rtw_debugfs_add_rw(fw_crash);
|
||||
- rtw_debugfs_add_rw(force_lowest_basic_rate);
|
||||
- rtw_debugfs_add_rw(dm_cap);
|
||||
}
|
||||
|
||||
+void rtw_debugfs_init(struct rtw_dev *rtwdev)
|
||||
+{
|
||||
+ struct dentry *debugfs_topdir;
|
||||
+
|
||||
+ rtwdev->debugfs = kmemdup(&rtw_debugfs_templ, sizeof(rtw_debugfs_templ),
|
||||
+ GFP_KERNEL);
|
||||
+ if (!rtwdev->debugfs)
|
||||
+ return;
|
||||
+
|
||||
+ debugfs_topdir = debugfs_create_dir("rtw88",
|
||||
+ rtwdev->hw->wiphy->debugfsdir);
|
||||
+
|
||||
+ rtw_debugfs_add_basic(rtwdev, debugfs_topdir);
|
||||
+ rtw_debugfs_add_sec0(rtwdev, debugfs_topdir);
|
||||
+ rtw_debugfs_add_sec1(rtwdev, debugfs_topdir);
|
||||
+}
|
||||
+
|
||||
+void rtw_debugfs_deinit(struct rtw_dev *rtwdev)
|
||||
+{
|
||||
+ kfree(rtwdev->debugfs);
|
||||
+}
|
||||
#endif /* CPTCFG_RTW88_DEBUGFS */
|
||||
|
||||
#ifdef CPTCFG_RTW88_DEBUG
|
||||
--- a/drivers/net/wireless/realtek/rtw88/debug.h
|
||||
+++ b/drivers/net/wireless/realtek/rtw88/debug.h
|
||||
@@ -34,11 +34,13 @@ enum rtw_debug_mask {
|
||||
#ifdef CPTCFG_RTW88_DEBUGFS
|
||||
|
||||
void rtw_debugfs_init(struct rtw_dev *rtwdev);
|
||||
+void rtw_debugfs_deinit(struct rtw_dev *rtwdev);
|
||||
void rtw_debugfs_get_simple_phy_info(struct seq_file *m);
|
||||
|
||||
#else
|
||||
|
||||
static inline void rtw_debugfs_init(struct rtw_dev *rtwdev) {}
|
||||
+static inline void rtw_debugfs_deinit(struct rtw_dev *rtwdev) {}
|
||||
|
||||
#endif /* CPTCFG_RTW88_DEBUGFS */
|
||||
|
||||
--- a/drivers/net/wireless/realtek/rtw88/main.c
|
||||
+++ b/drivers/net/wireless/realtek/rtw88/main.c
|
||||
@@ -2300,6 +2300,7 @@ void rtw_unregister_hw(struct rtw_dev *r
|
||||
|
||||
ieee80211_unregister_hw(hw);
|
||||
rtw_unset_supported_band(hw, chip);
|
||||
+ rtw_debugfs_deinit(rtwdev);
|
||||
}
|
||||
EXPORT_SYMBOL(rtw_unregister_hw);
|
||||
|
||||
--- a/drivers/net/wireless/realtek/rtw88/main.h
|
||||
+++ b/drivers/net/wireless/realtek/rtw88/main.h
|
||||
@@ -50,6 +50,7 @@ extern const struct ieee80211_ops rtw_op
|
||||
#define RTW_MAX_CHANNEL_NUM_5G 49
|
||||
|
||||
struct rtw_dev;
|
||||
+struct rtw_debugfs;
|
||||
|
||||
enum rtw_hci_type {
|
||||
RTW_HCI_TYPE_PCIE,
|
||||
@@ -2053,7 +2054,7 @@ struct rtw_dev {
|
||||
bool beacon_loss;
|
||||
struct completion lps_leave_check;
|
||||
|
||||
- struct dentry *debugfs;
|
||||
+ struct rtw_debugfs *debugfs;
|
||||
|
||||
u8 sta_cnt;
|
||||
u32 rts_threshold;
|
@ -1,25 +0,0 @@
|
||||
From 7e989b0c1e33210c07340bf5228aa83ea52515b5 Mon Sep 17 00:00:00 2001
|
||||
From: Zong-Zhe Yang <kevin_yang@realtek.com>
|
||||
Date: Thu, 18 Jul 2024 15:06:15 +0800
|
||||
Subject: [PATCH] wifi: rtw88: select WANT_DEV_COREDUMP
|
||||
|
||||
We have invoked device coredump when fw crash.
|
||||
Should select WANT_DEV_COREDUMP by ourselves.
|
||||
|
||||
Signed-off-by: Zong-Zhe Yang <kevin_yang@realtek.com>
|
||||
Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
|
||||
Link: https://patch.msgid.link/20240718070616.42217-1-pkshih@realtek.com
|
||||
---
|
||||
drivers/net/wireless/realtek/rtw88/Kconfig | 1 +
|
||||
1 file changed, 1 insertion(+)
|
||||
|
||||
--- a/drivers/net/wireless/realtek/rtw88/Kconfig
|
||||
+++ b/drivers/net/wireless/realtek/rtw88/Kconfig
|
||||
@@ -14,6 +14,7 @@ if RTW88
|
||||
config RTW88_CORE
|
||||
tristate
|
||||
depends on m
|
||||
+ select BPAUTO_WANT_DEV_COREDUMP
|
||||
|
||||
config RTW88_PCI
|
||||
tristate
|
@ -1,151 +0,0 @@
|
||||
From 53ed4b25a79aeec5991c2dc579e635b136ef7676 Mon Sep 17 00:00:00 2001
|
||||
From: Po-Hao Huang <phhuang@realtek.com>
|
||||
Date: Wed, 24 Jul 2024 13:05:01 +0800
|
||||
Subject: [PATCH] wifi: rtw88: 8822c: Parse channel from IE to correct invalid
|
||||
hardware reports
|
||||
|
||||
For CCK packets we could get incorrect reports from hardware.
|
||||
And this causes wrong frequencies being reported. Parse the channel
|
||||
information from IE if provided by AP to fix this.
|
||||
|
||||
Signed-off-by: Po-Hao Huang <phhuang@realtek.com>
|
||||
Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
|
||||
Link: https://patch.msgid.link/20240724050501.7550-1-pkshih@realtek.com
|
||||
---
|
||||
drivers/net/wireless/realtek/rtw88/main.h | 1 +
|
||||
drivers/net/wireless/realtek/rtw88/pci.c | 1 +
|
||||
drivers/net/wireless/realtek/rtw88/rtw8822c.c | 7 ++--
|
||||
drivers/net/wireless/realtek/rtw88/rx.c | 41 +++++++++++++++++++
|
||||
drivers/net/wireless/realtek/rtw88/rx.h | 13 ++++++
|
||||
drivers/net/wireless/realtek/rtw88/sdio.c | 1 +
|
||||
drivers/net/wireless/realtek/rtw88/usb.c | 2 +
|
||||
7 files changed, 63 insertions(+), 3 deletions(-)
|
||||
|
||||
--- a/drivers/net/wireless/realtek/rtw88/main.h
|
||||
+++ b/drivers/net/wireless/realtek/rtw88/main.h
|
||||
@@ -623,6 +623,7 @@ struct rtw_rx_pkt_stat {
|
||||
bool crc_err;
|
||||
bool decrypted;
|
||||
bool is_c2h;
|
||||
+ bool channel_invalid;
|
||||
|
||||
s32 signal_power;
|
||||
u16 pkt_len;
|
||||
--- a/drivers/net/wireless/realtek/rtw88/pci.c
|
||||
+++ b/drivers/net/wireless/realtek/rtw88/pci.c
|
||||
@@ -1088,6 +1088,7 @@ static u32 rtw_pci_rx_napi(struct rtw_de
|
||||
/* remove rx_desc */
|
||||
skb_pull(new, pkt_offset);
|
||||
|
||||
+ rtw_update_rx_freq_for_invalid(rtwdev, new, &rx_status, &pkt_stat);
|
||||
rtw_rx_stats(rtwdev, pkt_stat.vif, new);
|
||||
memcpy(new->cb, &rx_status, sizeof(rx_status));
|
||||
ieee80211_rx_napi(rtwdev->hw, NULL, new, napi);
|
||||
--- a/drivers/net/wireless/realtek/rtw88/rtw8822c.c
|
||||
+++ b/drivers/net/wireless/realtek/rtw88/rtw8822c.c
|
||||
@@ -2576,9 +2576,10 @@ static void query_phy_status_page0(struc
|
||||
rx_power[RF_PATH_B] -= 110;
|
||||
|
||||
channel = GET_PHY_STAT_P0_CHANNEL(phy_status);
|
||||
- if (channel == 0)
|
||||
- channel = rtwdev->hal.current_channel;
|
||||
- rtw_set_rx_freq_band(pkt_stat, channel);
|
||||
+ if (channel != 0)
|
||||
+ rtw_set_rx_freq_band(pkt_stat, channel);
|
||||
+ else
|
||||
+ pkt_stat->channel_invalid = true;
|
||||
|
||||
pkt_stat->rx_power[RF_PATH_A] = rx_power[RF_PATH_A];
|
||||
pkt_stat->rx_power[RF_PATH_B] = rx_power[RF_PATH_B];
|
||||
--- a/drivers/net/wireless/realtek/rtw88/rx.c
|
||||
+++ b/drivers/net/wireless/realtek/rtw88/rx.c
|
||||
@@ -146,6 +146,47 @@ static void rtw_set_rx_freq_by_pktstat(s
|
||||
rx_status->band = pkt_stat->band;
|
||||
}
|
||||
|
||||
+void rtw_update_rx_freq_from_ie(struct rtw_dev *rtwdev, struct sk_buff *skb,
|
||||
+ struct ieee80211_rx_status *rx_status,
|
||||
+ struct rtw_rx_pkt_stat *pkt_stat)
|
||||
+{
|
||||
+ struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)skb->data;
|
||||
+ int channel = rtwdev->hal.current_channel;
|
||||
+ size_t hdr_len, ielen;
|
||||
+ int channel_number;
|
||||
+ u8 *variable;
|
||||
+
|
||||
+ if (!test_bit(RTW_FLAG_SCANNING, rtwdev->flags))
|
||||
+ goto fill_rx_status;
|
||||
+
|
||||
+ if (ieee80211_is_beacon(mgmt->frame_control)) {
|
||||
+ variable = mgmt->u.beacon.variable;
|
||||
+ hdr_len = offsetof(struct ieee80211_mgmt,
|
||||
+ u.beacon.variable);
|
||||
+ } else if (ieee80211_is_probe_resp(mgmt->frame_control)) {
|
||||
+ variable = mgmt->u.probe_resp.variable;
|
||||
+ hdr_len = offsetof(struct ieee80211_mgmt,
|
||||
+ u.probe_resp.variable);
|
||||
+ } else {
|
||||
+ goto fill_rx_status;
|
||||
+ }
|
||||
+
|
||||
+ if (skb->len > hdr_len)
|
||||
+ ielen = skb->len - hdr_len;
|
||||
+ else
|
||||
+ goto fill_rx_status;
|
||||
+
|
||||
+ channel_number = cfg80211_get_ies_channel_number(variable, ielen,
|
||||
+ NL80211_BAND_2GHZ);
|
||||
+ if (channel_number != -1)
|
||||
+ channel = channel_number;
|
||||
+
|
||||
+fill_rx_status:
|
||||
+ rtw_set_rx_freq_band(pkt_stat, channel);
|
||||
+ rtw_set_rx_freq_by_pktstat(pkt_stat, rx_status);
|
||||
+}
|
||||
+EXPORT_SYMBOL(rtw_update_rx_freq_from_ie);
|
||||
+
|
||||
void rtw_rx_fill_rx_status(struct rtw_dev *rtwdev,
|
||||
struct rtw_rx_pkt_stat *pkt_stat,
|
||||
struct ieee80211_hdr *hdr,
|
||||
--- a/drivers/net/wireless/realtek/rtw88/rx.h
|
||||
+++ b/drivers/net/wireless/realtek/rtw88/rx.h
|
||||
@@ -50,5 +50,18 @@ void rtw_rx_fill_rx_status(struct rtw_de
|
||||
struct ieee80211_hdr *hdr,
|
||||
struct ieee80211_rx_status *rx_status,
|
||||
u8 *phy_status);
|
||||
+void rtw_update_rx_freq_from_ie(struct rtw_dev *rtwdev, struct sk_buff *skb,
|
||||
+ struct ieee80211_rx_status *rx_status,
|
||||
+ struct rtw_rx_pkt_stat *pkt_stat);
|
||||
+
|
||||
+static inline
|
||||
+void rtw_update_rx_freq_for_invalid(struct rtw_dev *rtwdev, struct sk_buff *skb,
|
||||
+ struct ieee80211_rx_status *rx_status,
|
||||
+ struct rtw_rx_pkt_stat *pkt_stat)
|
||||
+{
|
||||
+ if (pkt_stat->channel_invalid)
|
||||
+ rtw_update_rx_freq_from_ie(rtwdev, skb, rx_status, pkt_stat);
|
||||
+}
|
||||
+
|
||||
|
||||
#endif
|
||||
--- a/drivers/net/wireless/realtek/rtw88/sdio.c
|
||||
+++ b/drivers/net/wireless/realtek/rtw88/sdio.c
|
||||
@@ -948,6 +948,7 @@ static void rtw_sdio_rx_skb(struct rtw_d
|
||||
skb_put(skb, pkt_stat->pkt_len);
|
||||
skb_reserve(skb, pkt_offset);
|
||||
|
||||
+ rtw_update_rx_freq_for_invalid(rtwdev, skb, rx_status, pkt_stat);
|
||||
rtw_rx_stats(rtwdev, pkt_stat->vif, skb);
|
||||
|
||||
ieee80211_rx_irqsafe(rtwdev->hw, skb);
|
||||
--- a/drivers/net/wireless/realtek/rtw88/usb.c
|
||||
+++ b/drivers/net/wireless/realtek/rtw88/usb.c
|
||||
@@ -579,6 +579,8 @@ static void rtw_usb_rx_handler(struct wo
|
||||
|
||||
skb_put(skb, pkt_stat.pkt_len);
|
||||
skb_reserve(skb, pkt_offset);
|
||||
+
|
||||
+ rtw_update_rx_freq_for_invalid(rtwdev, skb, &rx_status, &pkt_stat);
|
||||
memcpy(skb->cb, &rx_status, sizeof(rx_status));
|
||||
ieee80211_rx_irqsafe(rtwdev->hw, skb);
|
||||
}
|
@ -1,73 +0,0 @@
|
||||
From fbbd8cb347e25b68d25c4f3871821afc495ee7a9 Mon Sep 17 00:00:00 2001
|
||||
From: Bitterblue Smith <rtl8821cerfe2@gmail.com>
|
||||
Date: Thu, 8 Aug 2024 01:19:36 +0300
|
||||
Subject: [PATCH] wifi: rtw88: usb: Init RX burst length according to USB speed
|
||||
|
||||
This is needed in order to make USB RX aggregation work with RTL8811CU
|
||||
(and presumably RTL8822BU and RTL8822CU also).
|
||||
|
||||
I don't know what BIT_DMA_BURST_CNT, BIT_DMA_MODE, and BIT_DROP_DATA_EN
|
||||
are doing.
|
||||
|
||||
Tested with RTL8822CU, RTL8811CU, and RTL8723DU.
|
||||
|
||||
The RX speed is unchanged in my tests.
|
||||
|
||||
Tested-by: Sascha Hauer <s.hauer@pengutronix.de>
|
||||
Signed-off-by: Bitterblue Smith <rtl8821cerfe2@gmail.com>
|
||||
Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
|
||||
Link: https://patch.msgid.link/ac569c6f-7129-4341-b523-901fe10cabff@gmail.com
|
||||
---
|
||||
drivers/net/wireless/realtek/rtw88/reg.h | 6 ++++++
|
||||
drivers/net/wireless/realtek/rtw88/usb.c | 23 ++++++++++++++++++++++-
|
||||
2 files changed, 28 insertions(+), 1 deletion(-)
|
||||
|
||||
--- a/drivers/net/wireless/realtek/rtw88/reg.h
|
||||
+++ b/drivers/net/wireless/realtek/rtw88/reg.h
|
||||
@@ -322,6 +322,12 @@
|
||||
#define REG_RXDMA_DPR 0x028C
|
||||
#define REG_RXDMA_MODE 0x0290
|
||||
#define BIT_DMA_MODE BIT(1)
|
||||
+#define BIT_DMA_BURST_CNT GENMASK(3, 2)
|
||||
+#define BIT_DMA_BURST_SIZE GENMASK(5, 4)
|
||||
+#define BIT_DMA_BURST_SIZE_64 2
|
||||
+#define BIT_DMA_BURST_SIZE_512 1
|
||||
+#define BIT_DMA_BURST_SIZE_1024 0
|
||||
+
|
||||
#define REG_RXPKTNUM 0x02B0
|
||||
|
||||
#define REG_INT_MIG 0x0304
|
||||
--- a/drivers/net/wireless/realtek/rtw88/usb.c
|
||||
+++ b/drivers/net/wireless/realtek/rtw88/usb.c
|
||||
@@ -720,9 +720,30 @@ static void rtw_usb_link_ps(struct rtw_d
|
||||
/* empty function for rtw_hci_ops */
|
||||
}
|
||||
|
||||
+static void rtw_usb_init_burst_pkt_len(struct rtw_dev *rtwdev)
|
||||
+{
|
||||
+ struct rtw_usb *rtwusb = rtw_get_usb_priv(rtwdev);
|
||||
+ enum usb_device_speed speed = rtwusb->udev->speed;
|
||||
+ u8 rxdma, burst_size;
|
||||
+
|
||||
+ rxdma = BIT_DMA_BURST_CNT | BIT_DMA_MODE;
|
||||
+
|
||||
+ if (speed == USB_SPEED_SUPER)
|
||||
+ burst_size = BIT_DMA_BURST_SIZE_1024;
|
||||
+ else if (speed == USB_SPEED_HIGH)
|
||||
+ burst_size = BIT_DMA_BURST_SIZE_512;
|
||||
+ else
|
||||
+ burst_size = BIT_DMA_BURST_SIZE_64;
|
||||
+
|
||||
+ u8p_replace_bits(&rxdma, burst_size, BIT_DMA_BURST_SIZE);
|
||||
+
|
||||
+ rtw_write8(rtwdev, REG_RXDMA_MODE, rxdma);
|
||||
+ rtw_write16_set(rtwdev, REG_TXDMA_OFFSET_CHK, BIT_DROP_DATA_EN);
|
||||
+}
|
||||
+
|
||||
static void rtw_usb_interface_cfg(struct rtw_dev *rtwdev)
|
||||
{
|
||||
- /* empty function for rtw_hci_ops */
|
||||
+ rtw_usb_init_burst_pkt_len(rtwdev);
|
||||
}
|
||||
|
||||
static struct rtw_hci_ops rtw_usb_ops = {
|
@ -1,31 +0,0 @@
|
||||
From 38ea04a79ad0f8cc30bb5e9ad98d665e4ae5060c Mon Sep 17 00:00:00 2001
|
||||
From: Bitterblue Smith <rtl8821cerfe2@gmail.com>
|
||||
Date: Thu, 8 Aug 2024 01:20:36 +0300
|
||||
Subject: [PATCH] wifi: rtw88: usb: Update the RX stats after every frame
|
||||
|
||||
Update the number of received unicast data frames and bytes every time
|
||||
a frame is received. This is what the PCI and SDIO drivers do.
|
||||
|
||||
This has an influence on the power saving, bluetooth coexistence, and
|
||||
(in a future patch) the use of RX aggregation.
|
||||
|
||||
Tested with RTL8822CU, RTL8811CU, and RTL8723DU.
|
||||
|
||||
Tested-by: Sascha Hauer <s.hauer@pengutronix.de>
|
||||
Signed-off-by: Bitterblue Smith <rtl8821cerfe2@gmail.com>
|
||||
Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
|
||||
Link: https://patch.msgid.link/75a2ca52-8f01-45c5-926f-d3a68ae3b284@gmail.com
|
||||
---
|
||||
drivers/net/wireless/realtek/rtw88/usb.c | 1 +
|
||||
1 file changed, 1 insertion(+)
|
||||
|
||||
--- a/drivers/net/wireless/realtek/rtw88/usb.c
|
||||
+++ b/drivers/net/wireless/realtek/rtw88/usb.c
|
||||
@@ -581,6 +581,7 @@ static void rtw_usb_rx_handler(struct wo
|
||||
skb_reserve(skb, pkt_offset);
|
||||
|
||||
rtw_update_rx_freq_for_invalid(rtwdev, skb, &rx_status, &pkt_stat);
|
||||
+ rtw_rx_stats(rtwdev, pkt_stat.vif, skb);
|
||||
memcpy(skb->cb, &rx_status, sizeof(rx_status));
|
||||
ieee80211_rx_irqsafe(rtwdev->hw, skb);
|
||||
}
|
@ -1,118 +0,0 @@
|
||||
From df3d8f463b1dfc7cb8f4fb52b1b81d290b850d03 Mon Sep 17 00:00:00 2001
|
||||
From: Bitterblue Smith <rtl8821cerfe2@gmail.com>
|
||||
Date: Thu, 8 Aug 2024 01:21:36 +0300
|
||||
Subject: [PATCH] wifi: rtw88: usb: Support RX aggregation
|
||||
|
||||
The chips can be configured to aggregate several frames into a single
|
||||
USB transfer. Modify rtw_usb_rx_handler() to support this case.
|
||||
|
||||
RX aggregation improves the RX speed of RTL8811CU on certain ARM
|
||||
systems, like the NanoPi NEO Core2. It also improves the RX speed of
|
||||
RTL8822CU on some x86_64 systems.
|
||||
|
||||
Currently none of the chips are configured to aggregate frames.
|
||||
|
||||
Tested with RTL8822CU, RTL8811CU, and RTL8723DU.
|
||||
|
||||
Reviewed-by: Sascha Hauer <s.hauer@pengutronix.de>
|
||||
Tested-by: Sascha Hauer <s.hauer@pengutronix.de>
|
||||
Signed-off-by: Bitterblue Smith <rtl8821cerfe2@gmail.com>
|
||||
Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
|
||||
Link: https://patch.msgid.link/f845826d-de71-492d-9a22-e48c07989a1f@gmail.com
|
||||
---
|
||||
drivers/net/wireless/realtek/rtw88/usb.c | 61 ++++++++++++++++--------
|
||||
1 file changed, 40 insertions(+), 21 deletions(-)
|
||||
|
||||
--- a/drivers/net/wireless/realtek/rtw88/usb.c
|
||||
+++ b/drivers/net/wireless/realtek/rtw88/usb.c
|
||||
@@ -546,11 +546,12 @@ static void rtw_usb_rx_handler(struct wo
|
||||
struct rtw_usb *rtwusb = container_of(work, struct rtw_usb, rx_work);
|
||||
struct rtw_dev *rtwdev = rtwusb->rtwdev;
|
||||
const struct rtw_chip_info *chip = rtwdev->chip;
|
||||
- struct rtw_rx_pkt_stat pkt_stat;
|
||||
+ u32 pkt_desc_sz = chip->rx_pkt_desc_sz;
|
||||
struct ieee80211_rx_status rx_status;
|
||||
+ u32 pkt_offset, next_pkt, urb_len;
|
||||
+ struct rtw_rx_pkt_stat pkt_stat;
|
||||
+ struct sk_buff *next_skb;
|
||||
struct sk_buff *skb;
|
||||
- u32 pkt_desc_sz = chip->rx_pkt_desc_sz;
|
||||
- u32 pkt_offset;
|
||||
u8 *rx_desc;
|
||||
int limit;
|
||||
|
||||
@@ -559,31 +560,48 @@ static void rtw_usb_rx_handler(struct wo
|
||||
if (!skb)
|
||||
break;
|
||||
|
||||
- rx_desc = skb->data;
|
||||
- chip->ops->query_rx_desc(rtwdev, rx_desc, &pkt_stat,
|
||||
- &rx_status);
|
||||
- pkt_offset = pkt_desc_sz + pkt_stat.drv_info_sz +
|
||||
- pkt_stat.shift;
|
||||
-
|
||||
- if (pkt_stat.is_c2h) {
|
||||
- skb_put(skb, pkt_stat.pkt_len + pkt_offset);
|
||||
- rtw_fw_c2h_cmd_rx_irqsafe(rtwdev, pkt_offset, skb);
|
||||
- continue;
|
||||
- }
|
||||
-
|
||||
if (skb_queue_len(&rtwusb->rx_queue) >= RTW_USB_MAX_RXQ_LEN) {
|
||||
dev_dbg_ratelimited(rtwdev->dev, "failed to get rx_queue, overflow\n");
|
||||
dev_kfree_skb_any(skb);
|
||||
continue;
|
||||
}
|
||||
|
||||
- skb_put(skb, pkt_stat.pkt_len);
|
||||
- skb_reserve(skb, pkt_offset);
|
||||
+ urb_len = skb->len;
|
||||
+
|
||||
+ do {
|
||||
+ rx_desc = skb->data;
|
||||
+ chip->ops->query_rx_desc(rtwdev, rx_desc, &pkt_stat,
|
||||
+ &rx_status);
|
||||
+ pkt_offset = pkt_desc_sz + pkt_stat.drv_info_sz +
|
||||
+ pkt_stat.shift;
|
||||
+
|
||||
+ next_pkt = round_up(pkt_stat.pkt_len + pkt_offset, 8);
|
||||
+
|
||||
+ if (urb_len >= next_pkt + pkt_desc_sz)
|
||||
+ next_skb = skb_clone(skb, GFP_KERNEL);
|
||||
+ else
|
||||
+ next_skb = NULL;
|
||||
+
|
||||
+ if (pkt_stat.is_c2h) {
|
||||
+ skb_trim(skb, pkt_stat.pkt_len + pkt_offset);
|
||||
+ rtw_fw_c2h_cmd_rx_irqsafe(rtwdev, pkt_offset, skb);
|
||||
+ } else {
|
||||
+ skb_pull(skb, pkt_offset);
|
||||
+ skb_trim(skb, pkt_stat.pkt_len);
|
||||
+ rtw_update_rx_freq_for_invalid(rtwdev, skb,
|
||||
+ &rx_status,
|
||||
+ &pkt_stat);
|
||||
+ rtw_rx_stats(rtwdev, pkt_stat.vif, skb);
|
||||
+ memcpy(skb->cb, &rx_status, sizeof(rx_status));
|
||||
+ ieee80211_rx_irqsafe(rtwdev->hw, skb);
|
||||
+ }
|
||||
+
|
||||
+ skb = next_skb;
|
||||
+ if (skb)
|
||||
+ skb_pull(skb, next_pkt);
|
||||
|
||||
- rtw_update_rx_freq_for_invalid(rtwdev, skb, &rx_status, &pkt_stat);
|
||||
- rtw_rx_stats(rtwdev, pkt_stat.vif, skb);
|
||||
- memcpy(skb->cb, &rx_status, sizeof(rx_status));
|
||||
- ieee80211_rx_irqsafe(rtwdev->hw, skb);
|
||||
+ urb_len -= next_pkt;
|
||||
+ } while (skb);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -627,6 +645,7 @@ static void rtw_usb_read_port_complete(s
|
||||
if (skb)
|
||||
dev_kfree_skb_any(skb);
|
||||
} else {
|
||||
+ skb_put(skb, urb->actual_length);
|
||||
skb_queue_tail(&rtwusb->rx_queue, skb);
|
||||
queue_work(rtwusb->rxwq, &rtwusb->rx_work);
|
||||
}
|
@ -1,168 +0,0 @@
|
||||
From 002a5db9a52a0e7af0fa9a450d31049748435748 Mon Sep 17 00:00:00 2001
|
||||
From: Bitterblue Smith <rtl8821cerfe2@gmail.com>
|
||||
Date: Thu, 8 Aug 2024 01:23:06 +0300
|
||||
Subject: [PATCH] wifi: rtw88: Enable USB RX aggregation for 8822c/8822b/8821c
|
||||
|
||||
Enable USB RX aggregation when there is at least 1 Mbps RX or TX
|
||||
traffic, otherwise disable it.
|
||||
|
||||
USB RX aggregation improves the RX speed of RTL8811CU on certain ARM
|
||||
systems, like the NanoPi NEO Core2. Before: 28 Mbps, after: 231 Mbps.
|
||||
|
||||
It also improves the RX speed of RTL8822CU on some x86_64 systems.
|
||||
Before: ~200 Mbps, after: ~300 Mbps.
|
||||
|
||||
The official drivers for these chips use the same logic for SDIO, but
|
||||
for some reason the SDIO driver in rtw88 always enables RX aggregation,
|
||||
so this patch only toggles aggregation for USB devices.
|
||||
|
||||
RTL8703B is likely not found in USB devices, and RTL8723DU doesn't like
|
||||
aggregation.
|
||||
|
||||
Tested-by: Sascha Hauer <s.hauer@pengutronix.de>
|
||||
Signed-off-by: Bitterblue Smith <rtl8821cerfe2@gmail.com>
|
||||
Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
|
||||
Link: https://patch.msgid.link/b4c0d54c-6755-4b0f-9dd7-f9196fd74b68@gmail.com
|
||||
---
|
||||
drivers/net/wireless/realtek/rtw88/hci.h | 7 ++++
|
||||
drivers/net/wireless/realtek/rtw88/main.c | 13 +++++---
|
||||
drivers/net/wireless/realtek/rtw88/pci.c | 1 +
|
||||
drivers/net/wireless/realtek/rtw88/sdio.c | 1 +
|
||||
drivers/net/wireless/realtek/rtw88/usb.c | 40 +++++++++++++++++++++++
|
||||
5 files changed, 58 insertions(+), 4 deletions(-)
|
||||
|
||||
--- a/drivers/net/wireless/realtek/rtw88/hci.h
|
||||
+++ b/drivers/net/wireless/realtek/rtw88/hci.h
|
||||
@@ -18,6 +18,7 @@ struct rtw_hci_ops {
|
||||
void (*deep_ps)(struct rtw_dev *rtwdev, bool enter);
|
||||
void (*link_ps)(struct rtw_dev *rtwdev, bool enter);
|
||||
void (*interface_cfg)(struct rtw_dev *rtwdev);
|
||||
+ void (*dynamic_rx_agg)(struct rtw_dev *rtwdev, bool enable);
|
||||
|
||||
int (*write_data_rsvd_page)(struct rtw_dev *rtwdev, u8 *buf, u32 size);
|
||||
int (*write_data_h2c)(struct rtw_dev *rtwdev, u8 *buf, u32 size);
|
||||
@@ -72,6 +73,12 @@ static inline void rtw_hci_interface_cfg
|
||||
rtwdev->hci.ops->interface_cfg(rtwdev);
|
||||
}
|
||||
|
||||
+static inline void rtw_hci_dynamic_rx_agg(struct rtw_dev *rtwdev, bool enable)
|
||||
+{
|
||||
+ if (rtwdev->hci.ops->dynamic_rx_agg)
|
||||
+ rtwdev->hci.ops->dynamic_rx_agg(rtwdev, enable);
|
||||
+}
|
||||
+
|
||||
static inline int
|
||||
rtw_hci_write_data_rsvd_page(struct rtw_dev *rtwdev, u8 *buf, u32 size)
|
||||
{
|
||||
--- a/drivers/net/wireless/realtek/rtw88/main.c
|
||||
+++ b/drivers/net/wireless/realtek/rtw88/main.c
|
||||
@@ -212,6 +212,7 @@ static void rtw_watch_dog_work(struct wo
|
||||
struct rtw_traffic_stats *stats = &rtwdev->stats;
|
||||
struct rtw_watch_dog_iter_data data = {};
|
||||
bool busy_traffic = test_bit(RTW_FLAG_BUSY_TRAFFIC, rtwdev->flags);
|
||||
+ u32 tx_unicast_mbps, rx_unicast_mbps;
|
||||
bool ps_active;
|
||||
|
||||
mutex_lock(&rtwdev->mutex);
|
||||
@@ -236,10 +237,11 @@ static void rtw_watch_dog_work(struct wo
|
||||
else
|
||||
ps_active = false;
|
||||
|
||||
- ewma_tp_add(&stats->tx_ewma_tp,
|
||||
- (u32)(stats->tx_unicast >> RTW_TP_SHIFT));
|
||||
- ewma_tp_add(&stats->rx_ewma_tp,
|
||||
- (u32)(stats->rx_unicast >> RTW_TP_SHIFT));
|
||||
+ tx_unicast_mbps = stats->tx_unicast >> RTW_TP_SHIFT;
|
||||
+ rx_unicast_mbps = stats->rx_unicast >> RTW_TP_SHIFT;
|
||||
+
|
||||
+ ewma_tp_add(&stats->tx_ewma_tp, tx_unicast_mbps);
|
||||
+ ewma_tp_add(&stats->rx_ewma_tp, rx_unicast_mbps);
|
||||
stats->tx_throughput = ewma_tp_read(&stats->tx_ewma_tp);
|
||||
stats->rx_throughput = ewma_tp_read(&stats->rx_ewma_tp);
|
||||
|
||||
@@ -259,6 +261,9 @@ static void rtw_watch_dog_work(struct wo
|
||||
|
||||
rtw_phy_dynamic_mechanism(rtwdev);
|
||||
|
||||
+ rtw_hci_dynamic_rx_agg(rtwdev,
|
||||
+ tx_unicast_mbps >= 1 || rx_unicast_mbps >= 1);
|
||||
+
|
||||
data.rtwdev = rtwdev;
|
||||
/* rtw_iterate_vifs internally uses an atomic iterator which is needed
|
||||
* to avoid taking local->iflist_mtx mutex
|
||||
--- a/drivers/net/wireless/realtek/rtw88/pci.c
|
||||
+++ b/drivers/net/wireless/realtek/rtw88/pci.c
|
||||
@@ -1601,6 +1601,7 @@ static struct rtw_hci_ops rtw_pci_ops =
|
||||
.deep_ps = rtw_pci_deep_ps,
|
||||
.link_ps = rtw_pci_link_ps,
|
||||
.interface_cfg = rtw_pci_interface_cfg,
|
||||
+ .dynamic_rx_agg = NULL,
|
||||
|
||||
.read8 = rtw_pci_read8,
|
||||
.read16 = rtw_pci_read16,
|
||||
--- a/drivers/net/wireless/realtek/rtw88/sdio.c
|
||||
+++ b/drivers/net/wireless/realtek/rtw88/sdio.c
|
||||
@@ -1157,6 +1157,7 @@ static struct rtw_hci_ops rtw_sdio_ops =
|
||||
.deep_ps = rtw_sdio_deep_ps,
|
||||
.link_ps = rtw_sdio_link_ps,
|
||||
.interface_cfg = rtw_sdio_interface_cfg,
|
||||
+ .dynamic_rx_agg = NULL,
|
||||
|
||||
.read8 = rtw_sdio_read8,
|
||||
.read16 = rtw_sdio_read16,
|
||||
--- a/drivers/net/wireless/realtek/rtw88/usb.c
|
||||
+++ b/drivers/net/wireless/realtek/rtw88/usb.c
|
||||
@@ -766,6 +766,45 @@ static void rtw_usb_interface_cfg(struct
|
||||
rtw_usb_init_burst_pkt_len(rtwdev);
|
||||
}
|
||||
|
||||
+static void rtw_usb_dynamic_rx_agg_v1(struct rtw_dev *rtwdev, bool enable)
|
||||
+{
|
||||
+ u8 size, timeout;
|
||||
+ u16 val16;
|
||||
+
|
||||
+ rtw_write32_set(rtwdev, REG_RXDMA_AGG_PG_TH, BIT_EN_PRE_CALC);
|
||||
+ rtw_write8_set(rtwdev, REG_TXDMA_PQ_MAP, BIT_RXDMA_AGG_EN);
|
||||
+ rtw_write8_clr(rtwdev, REG_RXDMA_AGG_PG_TH + 3, BIT(7));
|
||||
+
|
||||
+ if (enable) {
|
||||
+ size = 0x5;
|
||||
+ timeout = 0x20;
|
||||
+ } else {
|
||||
+ size = 0x0;
|
||||
+ timeout = 0x1;
|
||||
+ }
|
||||
+ val16 = u16_encode_bits(size, BIT_RXDMA_AGG_PG_TH) |
|
||||
+ u16_encode_bits(timeout, BIT_DMA_AGG_TO_V1);
|
||||
+
|
||||
+ rtw_write16(rtwdev, REG_RXDMA_AGG_PG_TH, val16);
|
||||
+}
|
||||
+
|
||||
+static void rtw_usb_dynamic_rx_agg(struct rtw_dev *rtwdev, bool enable)
|
||||
+{
|
||||
+ switch (rtwdev->chip->id) {
|
||||
+ case RTW_CHIP_TYPE_8822C:
|
||||
+ case RTW_CHIP_TYPE_8822B:
|
||||
+ case RTW_CHIP_TYPE_8821C:
|
||||
+ rtw_usb_dynamic_rx_agg_v1(rtwdev, enable);
|
||||
+ break;
|
||||
+ case RTW_CHIP_TYPE_8723D:
|
||||
+ /* Doesn't like aggregation. */
|
||||
+ break;
|
||||
+ case RTW_CHIP_TYPE_8703B:
|
||||
+ /* Likely not found in USB devices. */
|
||||
+ break;
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
static struct rtw_hci_ops rtw_usb_ops = {
|
||||
.tx_write = rtw_usb_tx_write,
|
||||
.tx_kick_off = rtw_usb_tx_kick_off,
|
||||
@@ -775,6 +814,7 @@ static struct rtw_hci_ops rtw_usb_ops =
|
||||
.deep_ps = rtw_usb_deep_ps,
|
||||
.link_ps = rtw_usb_link_ps,
|
||||
.interface_cfg = rtw_usb_interface_cfg,
|
||||
+ .dynamic_rx_agg = rtw_usb_dynamic_rx_agg,
|
||||
|
||||
.write8 = rtw_usb_write8,
|
||||
.write16 = rtw_usb_write16,
|
@ -1,231 +0,0 @@
|
||||
From 902cb7b11f9a7ff07233cc4c626b54c3e4703149 Mon Sep 17 00:00:00 2001
|
||||
From: Ping-Ke Shih <pkshih@realtek.com>
|
||||
Date: Mon, 19 Aug 2024 10:52:48 +0800
|
||||
Subject: [PATCH] wifi: rtw88: assign mac_id for vif/sta and update to TX desc
|
||||
|
||||
A mac_id as an instance in firmware has to be assigned for each station
|
||||
including AP and connected stations. Firmware will use the mac_id to
|
||||
control TX rate and do statistics.
|
||||
|
||||
Assignment rule is to assign mac_id to each vif when adding vif.
|
||||
For station mode, sta->mac_id will reuse vif->mac_id. For AP mode,
|
||||
dynamically allocate an sta->mac_id to a station, and vif->mac_id is
|
||||
used to send broadcast/multicast packets which are not belong to
|
||||
a station. For example,
|
||||
|
||||
vif->mac_id sta->mac_id
|
||||
vif0 (STA mode) 0 0
|
||||
vif1 (AP mode) 1 2...
|
||||
|
||||
By the way, remove unused RTW_BC_MC_MACID, which was planed to send
|
||||
broadcast/multicast packets on fixed mac_id.
|
||||
|
||||
Tested-on RTL8822CE with STA + AP SCC mode.
|
||||
|
||||
Link: https://lore.kernel.org/linux-wireless/e4be0a75-43b2-4ae5-9aab-5c4a88e78097@gmail.com/
|
||||
Cc: Bitterblue Smith <rtl8821cerfe2@gmail.com>
|
||||
Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
|
||||
Link: https://patch.msgid.link/20240819025248.17939-1-pkshih@realtek.com
|
||||
---
|
||||
drivers/net/wireless/realtek/rtw88/mac80211.c | 13 ++++++--
|
||||
drivers/net/wireless/realtek/rtw88/main.c | 30 ++++++++-----------
|
||||
drivers/net/wireless/realtek/rtw88/main.h | 14 +++++++--
|
||||
drivers/net/wireless/realtek/rtw88/tx.c | 11 +++++--
|
||||
drivers/net/wireless/realtek/rtw88/tx.h | 1 +
|
||||
5 files changed, 44 insertions(+), 25 deletions(-)
|
||||
|
||||
--- a/drivers/net/wireless/realtek/rtw88/mac80211.c
|
||||
+++ b/drivers/net/wireless/realtek/rtw88/mac80211.c
|
||||
@@ -167,6 +167,12 @@ static int rtw_ops_add_interface(struct
|
||||
|
||||
mutex_lock(&rtwdev->mutex);
|
||||
|
||||
+ rtwvif->mac_id = rtw_acquire_macid(rtwdev);
|
||||
+ if (rtwvif->mac_id >= RTW_MAX_MAC_ID_NUM) {
|
||||
+ mutex_unlock(&rtwdev->mutex);
|
||||
+ return -ENOSPC;
|
||||
+ }
|
||||
+
|
||||
port = find_first_zero_bit(rtwdev->hw_port, RTW_PORT_NUM);
|
||||
if (port >= RTW_PORT_NUM) {
|
||||
mutex_unlock(&rtwdev->mutex);
|
||||
@@ -214,7 +220,8 @@ static int rtw_ops_add_interface(struct
|
||||
|
||||
mutex_unlock(&rtwdev->mutex);
|
||||
|
||||
- rtw_dbg(rtwdev, RTW_DBG_STATE, "start vif %pM on port %d\n", vif->addr, rtwvif->port);
|
||||
+ rtw_dbg(rtwdev, RTW_DBG_STATE, "start vif %pM mac_id %d on port %d\n",
|
||||
+ vif->addr, rtwvif->mac_id, rtwvif->port);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -225,7 +232,8 @@ static void rtw_ops_remove_interface(str
|
||||
struct rtw_vif *rtwvif = (struct rtw_vif *)vif->drv_priv;
|
||||
u32 config = 0;
|
||||
|
||||
- rtw_dbg(rtwdev, RTW_DBG_STATE, "stop vif %pM on port %d\n", vif->addr, rtwvif->port);
|
||||
+ rtw_dbg(rtwdev, RTW_DBG_STATE, "stop vif %pM mac_id %d on port %d\n",
|
||||
+ vif->addr, rtwvif->mac_id, rtwvif->port);
|
||||
|
||||
mutex_lock(&rtwdev->mutex);
|
||||
|
||||
@@ -242,6 +250,7 @@ static void rtw_ops_remove_interface(str
|
||||
config |= PORT_SET_BCN_CTRL;
|
||||
rtw_vif_port_config(rtwdev, rtwvif, config);
|
||||
clear_bit(rtwvif->port, rtwdev->hw_port);
|
||||
+ rtw_release_macid(rtwdev, rtwvif->mac_id);
|
||||
rtw_recalc_lps(rtwdev, NULL);
|
||||
|
||||
mutex_unlock(&rtwdev->mutex);
|
||||
--- a/drivers/net/wireless/realtek/rtw88/main.c
|
||||
+++ b/drivers/net/wireless/realtek/rtw88/main.c
|
||||
@@ -311,17 +311,6 @@ static void rtw_ips_work(struct work_str
|
||||
mutex_unlock(&rtwdev->mutex);
|
||||
}
|
||||
|
||||
-static u8 rtw_acquire_macid(struct rtw_dev *rtwdev)
|
||||
-{
|
||||
- unsigned long mac_id;
|
||||
-
|
||||
- mac_id = find_first_zero_bit(rtwdev->mac_id_map, RTW_MAX_MAC_ID_NUM);
|
||||
- if (mac_id < RTW_MAX_MAC_ID_NUM)
|
||||
- set_bit(mac_id, rtwdev->mac_id_map);
|
||||
-
|
||||
- return mac_id;
|
||||
-}
|
||||
-
|
||||
static void rtw_sta_rc_work(struct work_struct *work)
|
||||
{
|
||||
struct rtw_sta_info *si = container_of(work, struct rtw_sta_info,
|
||||
@@ -340,12 +329,14 @@ int rtw_sta_add(struct rtw_dev *rtwdev,
|
||||
struct rtw_vif *rtwvif = (struct rtw_vif *)vif->drv_priv;
|
||||
int i;
|
||||
|
||||
- si->mac_id = rtw_acquire_macid(rtwdev);
|
||||
- if (si->mac_id >= RTW_MAX_MAC_ID_NUM)
|
||||
- return -ENOSPC;
|
||||
+ if (vif->type == NL80211_IFTYPE_STATION) {
|
||||
+ si->mac_id = rtwvif->mac_id;
|
||||
+ } else {
|
||||
+ si->mac_id = rtw_acquire_macid(rtwdev);
|
||||
+ if (si->mac_id >= RTW_MAX_MAC_ID_NUM)
|
||||
+ return -ENOSPC;
|
||||
+ }
|
||||
|
||||
- if (vif->type == NL80211_IFTYPE_STATION && vif->cfg.assoc == 0)
|
||||
- rtwvif->mac_id = si->mac_id;
|
||||
si->rtwdev = rtwdev;
|
||||
si->sta = sta;
|
||||
si->vif = vif;
|
||||
@@ -370,11 +361,13 @@ void rtw_sta_remove(struct rtw_dev *rtwd
|
||||
bool fw_exist)
|
||||
{
|
||||
struct rtw_sta_info *si = (struct rtw_sta_info *)sta->drv_priv;
|
||||
+ struct ieee80211_vif *vif = si->vif;
|
||||
int i;
|
||||
|
||||
cancel_work_sync(&si->rc_work);
|
||||
|
||||
- rtw_release_macid(rtwdev, si->mac_id);
|
||||
+ if (vif->type != NL80211_IFTYPE_STATION)
|
||||
+ rtw_release_macid(rtwdev, si->mac_id);
|
||||
if (fw_exist)
|
||||
rtw_fw_media_status_report(rtwdev, si->mac_id, false);
|
||||
|
||||
@@ -614,6 +607,8 @@ static void rtw_reset_vif_iter(void *dat
|
||||
rtw_bf_disassoc(rtwdev, vif, NULL);
|
||||
rtw_vif_assoc_changed(rtwvif, NULL);
|
||||
rtw_txq_cleanup(rtwdev, vif->txq);
|
||||
+
|
||||
+ rtw_release_macid(rtwdev, rtwvif->mac_id);
|
||||
}
|
||||
|
||||
void rtw_fw_recovery(struct rtw_dev *rtwdev)
|
||||
@@ -2139,7 +2134,6 @@ int rtw_core_init(struct rtw_dev *rtwdev
|
||||
rtwdev->sec.total_cam_num = 32;
|
||||
rtwdev->hal.current_channel = 1;
|
||||
rtwdev->dm_info.fix_rate = U8_MAX;
|
||||
- set_bit(RTW_BC_MC_MACID, rtwdev->mac_id_map);
|
||||
|
||||
rtw_stats_init(rtwdev);
|
||||
|
||||
--- a/drivers/net/wireless/realtek/rtw88/main.h
|
||||
+++ b/drivers/net/wireless/realtek/rtw88/main.h
|
||||
@@ -742,7 +742,6 @@ struct rtw_txq {
|
||||
unsigned long flags;
|
||||
};
|
||||
|
||||
-#define RTW_BC_MC_MACID 1
|
||||
DECLARE_EWMA(rssi, 10, 16);
|
||||
|
||||
struct rtw_sta_info {
|
||||
@@ -805,7 +804,7 @@ struct rtw_bf_info {
|
||||
struct rtw_vif {
|
||||
enum rtw_net_type net_type;
|
||||
u16 aid;
|
||||
- u8 mac_id; /* for STA mode only */
|
||||
+ u8 mac_id;
|
||||
u8 mac_addr[ETH_ALEN];
|
||||
u8 bssid[ETH_ALEN];
|
||||
u8 port;
|
||||
@@ -2131,6 +2130,17 @@ static inline bool rtw_chip_has_tx_stbc(
|
||||
return rtwdev->chip->tx_stbc;
|
||||
}
|
||||
|
||||
+static inline u8 rtw_acquire_macid(struct rtw_dev *rtwdev)
|
||||
+{
|
||||
+ unsigned long mac_id;
|
||||
+
|
||||
+ mac_id = find_first_zero_bit(rtwdev->mac_id_map, RTW_MAX_MAC_ID_NUM);
|
||||
+ if (mac_id < RTW_MAX_MAC_ID_NUM)
|
||||
+ set_bit(mac_id, rtwdev->mac_id_map);
|
||||
+
|
||||
+ return mac_id;
|
||||
+}
|
||||
+
|
||||
static inline void rtw_release_macid(struct rtw_dev *rtwdev, u8 mac_id)
|
||||
{
|
||||
clear_bit(mac_id, rtwdev->mac_id_map);
|
||||
--- a/drivers/net/wireless/realtek/rtw88/tx.c
|
||||
+++ b/drivers/net/wireless/realtek/rtw88/tx.c
|
||||
@@ -46,7 +46,8 @@ void rtw_tx_fill_tx_desc(struct rtw_tx_p
|
||||
le32_encode_bits(pkt_info->ls, RTW_TX_DESC_W0_LS) |
|
||||
le32_encode_bits(pkt_info->dis_qselseq, RTW_TX_DESC_W0_DISQSELSEQ);
|
||||
|
||||
- tx_desc->w1 = le32_encode_bits(pkt_info->qsel, RTW_TX_DESC_W1_QSEL) |
|
||||
+ tx_desc->w1 = le32_encode_bits(pkt_info->mac_id, RTW_TX_DESC_W1_MACID) |
|
||||
+ le32_encode_bits(pkt_info->qsel, RTW_TX_DESC_W1_QSEL) |
|
||||
le32_encode_bits(pkt_info->rate_id, RTW_TX_DESC_W1_RATE_ID) |
|
||||
le32_encode_bits(pkt_info->sec_type, RTW_TX_DESC_W1_SEC_TYPE) |
|
||||
le32_encode_bits(pkt_info->pkt_offset, RTW_TX_DESC_W1_PKT_OFFSET) |
|
||||
@@ -401,14 +402,18 @@ void rtw_tx_pkt_info_update(struct rtw_d
|
||||
const struct rtw_chip_info *chip = rtwdev->chip;
|
||||
struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
|
||||
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
|
||||
+ struct ieee80211_vif *vif = info->control.vif;
|
||||
struct rtw_sta_info *si;
|
||||
- struct ieee80211_vif *vif = NULL;
|
||||
+ struct rtw_vif *rtwvif;
|
||||
__le16 fc = hdr->frame_control;
|
||||
bool bmc;
|
||||
|
||||
if (sta) {
|
||||
si = (struct rtw_sta_info *)sta->drv_priv;
|
||||
- vif = si->vif;
|
||||
+ pkt_info->mac_id = si->mac_id;
|
||||
+ } else if (vif) {
|
||||
+ rtwvif = (struct rtw_vif *)vif->drv_priv;
|
||||
+ pkt_info->mac_id = rtwvif->mac_id;
|
||||
}
|
||||
|
||||
if (ieee80211_is_mgmt(fc) || ieee80211_is_nullfunc(fc))
|
||||
--- a/drivers/net/wireless/realtek/rtw88/tx.h
|
||||
+++ b/drivers/net/wireless/realtek/rtw88/tx.h
|
||||
@@ -27,6 +27,7 @@ struct rtw_tx_desc {
|
||||
#define RTW_TX_DESC_W0_BMC BIT(24)
|
||||
#define RTW_TX_DESC_W0_LS BIT(26)
|
||||
#define RTW_TX_DESC_W0_DISQSELSEQ BIT(31)
|
||||
+#define RTW_TX_DESC_W1_MACID GENMASK(7, 0)
|
||||
#define RTW_TX_DESC_W1_QSEL GENMASK(12, 8)
|
||||
#define RTW_TX_DESC_W1_RATE_ID GENMASK(20, 16)
|
||||
#define RTW_TX_DESC_W1_SEC_TYPE GENMASK(23, 22)
|
@ -547,7 +547,7 @@ Link: https://patch.msgid.link/913f1747-38fc-4409-85a4-57bb9cee506b@gmail.com
|
||||
|
||||
--- a/drivers/net/wireless/realtek/rtw88/usb.c
|
||||
+++ b/drivers/net/wireless/realtek/rtw88/usb.c
|
||||
@@ -570,8 +570,8 @@ static void rtw_usb_rx_handler(struct wo
|
||||
@@ -571,8 +571,8 @@ static void rtw_usb_rx_handler(struct wo
|
||||
|
||||
do {
|
||||
rx_desc = skb->data;
|
||||
|
@ -1,70 +0,0 @@
|
||||
From 4aefde403da7af30757915e0462d88398c9388c5 Mon Sep 17 00:00:00 2001
|
||||
From: Bitterblue Smith <rtl8821cerfe2@gmail.com>
|
||||
Date: Tue, 8 Oct 2024 21:44:02 +0300
|
||||
Subject: [PATCH] wifi: rtw88: Fix the RX aggregation in USB 3 mode
|
||||
|
||||
RTL8822CU, RTL8822BU, and RTL8821CU don't need BIT_EN_PRE_CALC.
|
||||
In fact, RTL8822BU in USB 3 mode doesn't pass all the frames to the
|
||||
driver, resulting in much lower download speed than normal:
|
||||
|
||||
$ iperf3 -c 192.168.0.1 -R
|
||||
Connecting to host 192.168.0.1, port 5201
|
||||
Reverse mode, remote host 192.168.0.1 is sending
|
||||
[ 5] local 192.168.0.50 port 43062 connected to 192.168.0.1 port 5201
|
||||
[ ID] Interval Transfer Bitrate
|
||||
[ 5] 0.00-1.00 sec 26.9 MBytes 225 Mbits/sec
|
||||
[ 5] 1.00-2.00 sec 7.50 MBytes 62.9 Mbits/sec
|
||||
[ 5] 2.00-3.00 sec 8.50 MBytes 71.3 Mbits/sec
|
||||
[ 5] 3.00-4.00 sec 8.38 MBytes 70.3 Mbits/sec
|
||||
[ 5] 4.00-5.00 sec 7.75 MBytes 65.0 Mbits/sec
|
||||
[ 5] 5.00-6.00 sec 8.00 MBytes 67.1 Mbits/sec
|
||||
[ 5] 6.00-7.00 sec 8.00 MBytes 67.1 Mbits/sec
|
||||
[ 5] 7.00-8.00 sec 7.75 MBytes 65.0 Mbits/sec
|
||||
[ 5] 8.00-9.00 sec 7.88 MBytes 66.1 Mbits/sec
|
||||
[ 5] 9.00-10.00 sec 7.88 MBytes 66.1 Mbits/sec
|
||||
- - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
[ ID] Interval Transfer Bitrate Retr
|
||||
[ 5] 0.00-10.02 sec 102 MBytes 85.1 Mbits/sec 224 sender
|
||||
[ 5] 0.00-10.00 sec 98.6 MBytes 82.7 Mbits/sec receiver
|
||||
|
||||
Don't set BIT_EN_PRE_CALC. Then the speed is much better:
|
||||
|
||||
% iperf3 -c 192.168.0.1 -R
|
||||
Connecting to host 192.168.0.1, port 5201
|
||||
Reverse mode, remote host 192.168.0.1 is sending
|
||||
[ 5] local 192.168.0.50 port 39000 connected to 192.168.0.1 port 5201
|
||||
[ ID] Interval Transfer Bitrate
|
||||
[ 5] 0.00-1.00 sec 52.8 MBytes 442 Mbits/sec
|
||||
[ 5] 1.00-2.00 sec 71.9 MBytes 603 Mbits/sec
|
||||
[ 5] 2.00-3.00 sec 74.8 MBytes 627 Mbits/sec
|
||||
[ 5] 3.00-4.00 sec 75.9 MBytes 636 Mbits/sec
|
||||
[ 5] 4.00-5.00 sec 76.0 MBytes 638 Mbits/sec
|
||||
[ 5] 5.00-6.00 sec 74.1 MBytes 622 Mbits/sec
|
||||
[ 5] 6.00-7.00 sec 74.0 MBytes 621 Mbits/sec
|
||||
[ 5] 7.00-8.00 sec 76.0 MBytes 638 Mbits/sec
|
||||
[ 5] 8.00-9.00 sec 74.4 MBytes 624 Mbits/sec
|
||||
[ 5] 9.00-10.00 sec 63.9 MBytes 536 Mbits/sec
|
||||
- - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
[ ID] Interval Transfer Bitrate Retr
|
||||
[ 5] 0.00-10.00 sec 717 MBytes 601 Mbits/sec 24 sender
|
||||
[ 5] 0.00-10.00 sec 714 MBytes 599 Mbits/sec receiver
|
||||
|
||||
Fixes: 002a5db9a52a ("wifi: rtw88: Enable USB RX aggregation for 8822c/8822b/8821c")
|
||||
Signed-off-by: Bitterblue Smith <rtl8821cerfe2@gmail.com>
|
||||
Acked-by: Ping-Ke Shih <pkshih@realtek.com>
|
||||
Signed-off-by: Kalle Valo <kvalo@kernel.org>
|
||||
Link: https://patch.msgid.link/afb94a82-3d18-459e-97fc-1a217608cdf0@gmail.com
|
||||
---
|
||||
drivers/net/wireless/realtek/rtw88/usb.c | 1 -
|
||||
1 file changed, 1 deletion(-)
|
||||
|
||||
--- a/drivers/net/wireless/realtek/rtw88/usb.c
|
||||
+++ b/drivers/net/wireless/realtek/rtw88/usb.c
|
||||
@@ -771,7 +771,6 @@ static void rtw_usb_dynamic_rx_agg_v1(st
|
||||
u8 size, timeout;
|
||||
u16 val16;
|
||||
|
||||
- rtw_write32_set(rtwdev, REG_RXDMA_AGG_PG_TH, BIT_EN_PRE_CALC);
|
||||
rtw_write8_set(rtwdev, REG_TXDMA_PQ_MAP, BIT_RXDMA_AGG_EN);
|
||||
rtw_write8_clr(rtwdev, REG_RXDMA_AGG_PG_TH + 3, BIT(7));
|
||||
|
@ -174,7 +174,7 @@ Link: https://patch.msgid.link/2b3e3e6f-541b-4a3b-8ca3-65b267e6a95a@gmail.com
|
||||
void rtw_tx_rsvd_page_pkt_info_update(struct rtw_dev *rtwdev,
|
||||
--- a/drivers/net/wireless/realtek/rtw88/usb.c
|
||||
+++ b/drivers/net/wireless/realtek/rtw88/usb.c
|
||||
@@ -457,7 +457,7 @@ static int rtw_usb_write_data(struct rtw
|
||||
@@ -458,7 +458,7 @@ static int rtw_usb_write_data(struct rtw
|
||||
skb_put_data(skb, buf, size);
|
||||
skb_push(skb, chip->tx_pkt_desc_sz);
|
||||
memset(skb->data, 0, chip->tx_pkt_desc_sz);
|
||||
@ -183,7 +183,7 @@ Link: https://patch.msgid.link/2b3e3e6f-541b-4a3b-8ca3-65b267e6a95a@gmail.com
|
||||
rtw_tx_fill_txdesc_checksum(rtwdev, pkt_info, skb->data);
|
||||
|
||||
ret = rtw_usb_write_port(rtwdev, qsel, skb,
|
||||
@@ -524,7 +524,7 @@ static int rtw_usb_tx_write(struct rtw_d
|
||||
@@ -525,7 +525,7 @@ static int rtw_usb_tx_write(struct rtw_d
|
||||
pkt_desc = skb_push(skb, chip->tx_pkt_desc_sz);
|
||||
memset(pkt_desc, 0, chip->tx_pkt_desc_sz);
|
||||
ep = qsel_to_ep(rtwusb, pkt_info->qsel);
|
||||
|
@ -17,7 +17,7 @@ Link: https://patch.msgid.link/e443f5d9-4b53-4f64-985c-64313ec80bef@gmail.com
|
||||
|
||||
--- a/drivers/net/wireless/realtek/rtw88/usb.c
|
||||
+++ b/drivers/net/wireless/realtek/rtw88/usb.c
|
||||
@@ -477,6 +477,7 @@ static int rtw_usb_write_data_rsvd_page(
|
||||
@@ -478,6 +478,7 @@ static int rtw_usb_write_data_rsvd_page(
|
||||
pkt_info.tx_pkt_size = size;
|
||||
pkt_info.qsel = TX_DESC_QSEL_BEACON;
|
||||
pkt_info.offset = chip->tx_pkt_desc_sz;
|
||||
|
@ -12,7 +12,7 @@ Signed-off-by: Bitterblue Smith <rtl8821cerfe2@gmail.com>
|
||||
|
||||
--- a/drivers/net/wireless/realtek/rtw88/usb.c
|
||||
+++ b/drivers/net/wireless/realtek/rtw88/usb.c
|
||||
@@ -929,6 +929,32 @@ static void rtw_usb_intf_deinit(struct r
|
||||
@@ -930,6 +930,32 @@ static void rtw_usb_intf_deinit(struct r
|
||||
usb_set_intfdata(intf, NULL);
|
||||
}
|
||||
|
||||
@ -45,7 +45,7 @@ Signed-off-by: Bitterblue Smith <rtl8821cerfe2@gmail.com>
|
||||
static int rtw_usb_switch_mode_new(struct rtw_dev *rtwdev)
|
||||
{
|
||||
enum usb_device_speed cur_speed;
|
||||
@@ -982,7 +1008,8 @@ static int rtw_usb_switch_mode(struct rt
|
||||
@@ -983,7 +1009,8 @@ static int rtw_usb_switch_mode(struct rt
|
||||
{
|
||||
u8 id = rtwdev->chip->id;
|
||||
|
||||
@ -55,7 +55,7 @@ Signed-off-by: Bitterblue Smith <rtl8821cerfe2@gmail.com>
|
||||
return 0;
|
||||
|
||||
if (!rtwdev->efuse.usb_mode_switch) {
|
||||
@@ -997,7 +1024,10 @@ static int rtw_usb_switch_mode(struct rt
|
||||
@@ -998,7 +1025,10 @@ static int rtw_usb_switch_mode(struct rt
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -19,7 +19,7 @@ Signed-off-by: Bitterblue Smith <rtl8821cerfe2@gmail.com>
|
||||
|
||||
--- a/drivers/net/wireless/realtek/rtw88/usb.c
|
||||
+++ b/drivers/net/wireless/realtek/rtw88/usb.c
|
||||
@@ -788,6 +788,32 @@ static void rtw_usb_dynamic_rx_agg_v1(st
|
||||
@@ -789,6 +789,32 @@ static void rtw_usb_dynamic_rx_agg_v1(st
|
||||
rtw_write16(rtwdev, REG_RXDMA_AGG_PG_TH, val16);
|
||||
}
|
||||
|
||||
@ -52,7 +52,7 @@ Signed-off-by: Bitterblue Smith <rtl8821cerfe2@gmail.com>
|
||||
static void rtw_usb_dynamic_rx_agg(struct rtw_dev *rtwdev, bool enable)
|
||||
{
|
||||
switch (rtwdev->chip->id) {
|
||||
@@ -796,6 +822,10 @@ static void rtw_usb_dynamic_rx_agg(struc
|
||||
@@ -797,6 +823,10 @@ static void rtw_usb_dynamic_rx_agg(struc
|
||||
case RTW_CHIP_TYPE_8821C:
|
||||
rtw_usb_dynamic_rx_agg_v1(rtwdev, enable);
|
||||
break;
|
||||
|
@ -1,6 +1,6 @@
|
||||
--- a/net/mac80211/main.c
|
||||
+++ b/net/mac80211/main.c
|
||||
@@ -1581,24 +1581,6 @@ int ieee80211_register_hw(struct ieee802
|
||||
@@ -1583,24 +1583,6 @@ int ieee80211_register_hw(struct ieee802
|
||||
|
||||
ieee80211_check_wbrf_support(local);
|
||||
|
||||
|
@ -16,7 +16,7 @@ and we should ignore this.
|
||||
|
||||
--- a/net/wireless/core.c
|
||||
+++ b/net/wireless/core.c
|
||||
@@ -654,21 +654,6 @@ static int wiphy_verify_combinations(str
|
||||
@@ -678,21 +678,6 @@ int wiphy_verify_iface_combinations(stru
|
||||
c->limits[j].max > 1))
|
||||
return -EINVAL;
|
||||
|
||||
|
@ -113,7 +113,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||
{
|
||||
--- a/net/wireless/core.h
|
||||
+++ b/net/wireless/core.h
|
||||
@@ -467,6 +467,8 @@ void cfg80211_set_dfs_state(struct wiphy
|
||||
@@ -475,6 +475,8 @@ void cfg80211_set_dfs_state(struct wiphy
|
||||
enum nl80211_dfs_state dfs_state);
|
||||
|
||||
void cfg80211_dfs_channels_update_work(struct work_struct *work);
|
||||
@ -124,7 +124,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||
|
||||
--- a/net/wireless/mlme.c
|
||||
+++ b/net/wireless/mlme.c
|
||||
@@ -1037,6 +1037,8 @@ void cfg80211_dfs_channels_update_work(s
|
||||
@@ -1031,6 +1031,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;
|
||||
@ -133,7 +133,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||
} else {
|
||||
if (regulatory_pre_cac_allowed(wiphy) ||
|
||||
cfg80211_any_wiphy_oper_chan(wiphy, c))
|
||||
@@ -1044,11 +1046,10 @@ void cfg80211_dfs_channels_update_work(s
|
||||
@@ -1038,11 +1040,10 @@ void cfg80211_dfs_channels_update_work(s
|
||||
|
||||
time_dfs_update = REG_PRE_CAC_EXPIRY_GRACE_MS;
|
||||
radar_event = NL80211_RADAR_PRE_CAC_EXPIRED;
|
||||
|
@ -85,7 +85,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||
const struct ieee80211_ops *ops;
|
||||
--- a/net/mac80211/main.c
|
||||
+++ b/net/mac80211/main.c
|
||||
@@ -952,6 +952,7 @@ struct ieee80211_hw *ieee80211_alloc_hw_
|
||||
@@ -954,6 +954,7 @@ struct ieee80211_hw *ieee80211_alloc_hw_
|
||||
spin_lock_init(&local->rx_path_lock);
|
||||
spin_lock_init(&local->queue_stop_reason_lock);
|
||||
|
||||
|
@ -1,24 +0,0 @@
|
||||
From: Felix Fietkau <nbd@nbd.name>
|
||||
Date: Wed, 2 Oct 2024 11:45:35 +0200
|
||||
Subject: [PATCH] wifi: mac80211: do not pass a stopped vif to the driver in
|
||||
.get_txpower
|
||||
|
||||
Avoid potentially crashing in the driver because of uninitialized private data
|
||||
|
||||
Fixes: 5b3dc42b1b0d ("mac80211: add support for driver tx power reporting")
|
||||
Cc: stable@vger.kernel.org
|
||||
Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||
---
|
||||
|
||||
--- a/net/mac80211/cfg.c
|
||||
+++ b/net/mac80211/cfg.c
|
||||
@@ -3134,7 +3134,8 @@ static int ieee80211_get_tx_power(struct
|
||||
struct ieee80211_local *local = wiphy_priv(wiphy);
|
||||
struct ieee80211_sub_if_data *sdata = IEEE80211_WDEV_TO_SUB_IF(wdev);
|
||||
|
||||
- if (local->ops->get_txpower)
|
||||
+ if (local->ops->get_txpower &&
|
||||
+ (sdata->flags & IEEE80211_SDATA_IN_DRIVER))
|
||||
return drv_get_txpower(local, sdata, dbm);
|
||||
|
||||
if (local->emulate_chanctx)
|
@ -23,15 +23,15 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||
|
||||
--- a/include/net/cfg80211.h
|
||||
+++ b/include/net/cfg80211.h
|
||||
@@ -6227,6 +6227,7 @@ enum ieee80211_ap_reg_power {
|
||||
@@ -6271,6 +6271,7 @@ enum ieee80211_ap_reg_power {
|
||||
* entered.
|
||||
* @links[].cac_time_ms: CAC time in ms
|
||||
* @links.cac_time_ms: CAC time in ms
|
||||
* @valid_links: bitmap describing what elements of @links are valid
|
||||
+ * @radio_mask: Bitmask of radios that this interface is allowed to operate on.
|
||||
*/
|
||||
struct wireless_dev {
|
||||
struct wiphy *wiphy;
|
||||
@@ -6339,6 +6340,8 @@ struct wireless_dev {
|
||||
@@ -6383,6 +6384,8 @@ struct wireless_dev {
|
||||
unsigned int cac_time_ms;
|
||||
} links[IEEE80211_MLD_MAX_NUM_LINKS];
|
||||
u16 valid_links;
|
||||
@ -40,7 +40,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||
};
|
||||
|
||||
static inline const u8 *wdev_address(struct wireless_dev *wdev)
|
||||
@@ -6525,6 +6528,17 @@ bool cfg80211_radio_chandef_valid(const
|
||||
@@ -6569,6 +6572,17 @@ bool cfg80211_radio_chandef_valid(const
|
||||
const struct cfg80211_chan_def *chandef);
|
||||
|
||||
/**
|
||||
@ -246,7 +246,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||
continue;
|
||||
|
||||
for (i = 0; i < rdev_req->n_channels; i++) {
|
||||
@@ -3490,9 +3491,12 @@ int cfg80211_wext_siwscan(struct net_dev
|
||||
@@ -3519,9 +3520,12 @@ int cfg80211_wext_siwscan(struct net_dev
|
||||
continue;
|
||||
|
||||
for (j = 0; j < wiphy->bands[band]->n_channels; j++) {
|
||||
@ -298,7 +298,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||
+EXPORT_SYMBOL(cfg80211_wdev_channel_allowed);
|
||||
--- a/net/wireless/core.c
|
||||
+++ b/net/wireless/core.c
|
||||
@@ -1415,6 +1415,8 @@ void cfg80211_init_wdev(struct wireless_
|
||||
@@ -1424,6 +1424,8 @@ void cfg80211_init_wdev(struct wireless_
|
||||
/* allow mac80211 to determine the timeout */
|
||||
wdev->ps_timeout = -1;
|
||||
|
@ -1,233 +0,0 @@
|
||||
From: Ming Yen Hsieh <mingyen.hsieh@mediatek.com>
|
||||
Date: Wed, 4 Sep 2024 19:12:56 +0800
|
||||
Subject: [PATCH] wifi: mac80211: introduce EHT rate support in AQL airtime
|
||||
|
||||
Add definitions related to EHT mode and airtime calculation
|
||||
according to the 802.11BE_D4.0.
|
||||
|
||||
Co-developed-by: Bo Jiao <Bo.Jiao@mediatek.com>
|
||||
Signed-off-by: Bo Jiao <Bo.Jiao@mediatek.com>
|
||||
Signed-off-by: Deren Wu <deren.wu@mediatek.com>
|
||||
Signed-off-by: Quan Zhou <quan.zhou@mediatek.com>
|
||||
Signed-off-by: Ming Yen Hsieh <mingyen.hsieh@mediatek.com>
|
||||
Link: https://patch.msgid.link/20240904111256.11734-1-mingyen.hsieh@mediatek.com
|
||||
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
|
||||
---
|
||||
|
||||
--- a/net/mac80211/airtime.c
|
||||
+++ b/net/mac80211/airtime.c
|
||||
@@ -55,10 +55,21 @@
|
||||
#define HE_DURATION_S(shift, streams, gi, bps) \
|
||||
(HE_DURATION(streams, gi, bps) >> shift)
|
||||
|
||||
+/* gi in HE/EHT is identical. It matches enum nl80211_eht_gi as well */
|
||||
+#define EHT_GI_08 HE_GI_08
|
||||
+#define EHT_GI_16 HE_GI_16
|
||||
+#define EHT_GI_32 HE_GI_32
|
||||
+
|
||||
+#define EHT_DURATION(streams, gi, bps) \
|
||||
+ HE_DURATION(streams, gi, bps)
|
||||
+#define EHT_DURATION_S(shift, streams, gi, bps) \
|
||||
+ HE_DURATION_S(shift, streams, gi, bps)
|
||||
+
|
||||
#define BW_20 0
|
||||
#define BW_40 1
|
||||
#define BW_80 2
|
||||
#define BW_160 3
|
||||
+#define BW_320 4
|
||||
|
||||
/*
|
||||
* Define group sort order: HT40 -> SGI -> #streams
|
||||
@@ -68,17 +79,26 @@
|
||||
#define IEEE80211_VHT_STREAM_GROUPS 8 /* BW(=4) * SGI(=2) */
|
||||
|
||||
#define IEEE80211_HE_MAX_STREAMS 8
|
||||
+#define IEEE80211_HE_STREAM_GROUPS 12 /* BW(=4) * GI(=3) */
|
||||
+
|
||||
+#define IEEE80211_EHT_MAX_STREAMS 8
|
||||
+#define IEEE80211_EHT_STREAM_GROUPS 15 /* BW(=5) * GI(=3) */
|
||||
|
||||
#define IEEE80211_HT_GROUPS_NB (IEEE80211_MAX_STREAMS * \
|
||||
IEEE80211_HT_STREAM_GROUPS)
|
||||
#define IEEE80211_VHT_GROUPS_NB (IEEE80211_MAX_STREAMS * \
|
||||
IEEE80211_VHT_STREAM_GROUPS)
|
||||
+#define IEEE80211_HE_GROUPS_NB (IEEE80211_HE_MAX_STREAMS * \
|
||||
+ IEEE80211_HE_STREAM_GROUPS)
|
||||
+#define IEEE80211_EHT_GROUPS_NB (IEEE80211_EHT_MAX_STREAMS * \
|
||||
+ IEEE80211_EHT_STREAM_GROUPS)
|
||||
|
||||
#define IEEE80211_HT_GROUP_0 0
|
||||
#define IEEE80211_VHT_GROUP_0 (IEEE80211_HT_GROUP_0 + IEEE80211_HT_GROUPS_NB)
|
||||
#define IEEE80211_HE_GROUP_0 (IEEE80211_VHT_GROUP_0 + IEEE80211_VHT_GROUPS_NB)
|
||||
+#define IEEE80211_EHT_GROUP_0 (IEEE80211_HE_GROUP_0 + IEEE80211_HE_GROUPS_NB)
|
||||
|
||||
-#define MCS_GROUP_RATES 12
|
||||
+#define MCS_GROUP_RATES 14
|
||||
|
||||
#define HT_GROUP_IDX(_streams, _sgi, _ht40) \
|
||||
IEEE80211_HT_GROUP_0 + \
|
||||
@@ -203,6 +223,69 @@
|
||||
#define HE_GROUP(_streams, _gi, _bw) \
|
||||
__HE_GROUP(_streams, _gi, _bw, \
|
||||
HE_GROUP_SHIFT(_streams, _gi, _bw))
|
||||
+
|
||||
+#define EHT_BW2VBPS(_bw, r5, r4, r3, r2, r1) \
|
||||
+ ((_bw) == BW_320 ? r5 : BW2VBPS(_bw, r4, r3, r2, r1))
|
||||
+
|
||||
+#define EHT_GROUP_IDX(_streams, _gi, _bw) \
|
||||
+ (IEEE80211_EHT_GROUP_0 + \
|
||||
+ IEEE80211_EHT_MAX_STREAMS * 3 * (_bw) + \
|
||||
+ IEEE80211_EHT_MAX_STREAMS * (_gi) + \
|
||||
+ (_streams) - 1)
|
||||
+
|
||||
+#define __EHT_GROUP(_streams, _gi, _bw, _s) \
|
||||
+ [EHT_GROUP_IDX(_streams, _gi, _bw)] = { \
|
||||
+ .shift = _s, \
|
||||
+ .duration = { \
|
||||
+ EHT_DURATION_S(_s, _streams, _gi, \
|
||||
+ EHT_BW2VBPS(_bw, 1960, 980, 490, 234, 117)), \
|
||||
+ EHT_DURATION_S(_s, _streams, _gi, \
|
||||
+ EHT_BW2VBPS(_bw, 3920, 1960, 980, 468, 234)), \
|
||||
+ EHT_DURATION_S(_s, _streams, _gi, \
|
||||
+ EHT_BW2VBPS(_bw, 5880, 2937, 1470, 702, 351)), \
|
||||
+ EHT_DURATION_S(_s, _streams, _gi, \
|
||||
+ EHT_BW2VBPS(_bw, 7840, 3920, 1960, 936, 468)), \
|
||||
+ EHT_DURATION_S(_s, _streams, _gi, \
|
||||
+ EHT_BW2VBPS(_bw, 11760, 5880, 2940, 1404, 702)), \
|
||||
+ EHT_DURATION_S(_s, _streams, _gi, \
|
||||
+ EHT_BW2VBPS(_bw, 15680, 7840, 3920, 1872, 936)), \
|
||||
+ EHT_DURATION_S(_s, _streams, _gi, \
|
||||
+ EHT_BW2VBPS(_bw, 17640, 8820, 4410, 2106, 1053)), \
|
||||
+ EHT_DURATION_S(_s, _streams, _gi, \
|
||||
+ EHT_BW2VBPS(_bw, 19600, 9800, 4900, 2340, 1170)), \
|
||||
+ EHT_DURATION_S(_s, _streams, _gi, \
|
||||
+ EHT_BW2VBPS(_bw, 23520, 11760, 5880, 2808, 1404)), \
|
||||
+ EHT_DURATION_S(_s, _streams, _gi, \
|
||||
+ EHT_BW2VBPS(_bw, 26133, 13066, 6533, 3120, 1560)), \
|
||||
+ EHT_DURATION_S(_s, _streams, _gi, \
|
||||
+ EHT_BW2VBPS(_bw, 29400, 14700, 7350, 3510, 1755)), \
|
||||
+ EHT_DURATION_S(_s, _streams, _gi, \
|
||||
+ EHT_BW2VBPS(_bw, 32666, 16333, 8166, 3900, 1950)), \
|
||||
+ EHT_DURATION_S(_s, _streams, _gi, \
|
||||
+ EHT_BW2VBPS(_bw, 35280, 17640, 8820, 4212, 2106)), \
|
||||
+ EHT_DURATION_S(_s, _streams, _gi, \
|
||||
+ EHT_BW2VBPS(_bw, 39200, 19600, 9800, 4680, 2340)) \
|
||||
+ } \
|
||||
+}
|
||||
+
|
||||
+#define EHT_GROUP_SHIFT(_streams, _gi, _bw) \
|
||||
+ GROUP_SHIFT(EHT_DURATION(_streams, _gi, \
|
||||
+ EHT_BW2VBPS(_bw, 1960, 980, 490, 234, 117)))
|
||||
+
|
||||
+#define EHT_GROUP(_streams, _gi, _bw) \
|
||||
+ __EHT_GROUP(_streams, _gi, _bw, \
|
||||
+ EHT_GROUP_SHIFT(_streams, _gi, _bw))
|
||||
+
|
||||
+#define EHT_GROUP_RANGE(_gi, _bw) \
|
||||
+ EHT_GROUP(1, _gi, _bw), \
|
||||
+ EHT_GROUP(2, _gi, _bw), \
|
||||
+ EHT_GROUP(3, _gi, _bw), \
|
||||
+ EHT_GROUP(4, _gi, _bw), \
|
||||
+ EHT_GROUP(5, _gi, _bw), \
|
||||
+ EHT_GROUP(6, _gi, _bw), \
|
||||
+ EHT_GROUP(7, _gi, _bw), \
|
||||
+ EHT_GROUP(8, _gi, _bw)
|
||||
+
|
||||
struct mcs_group {
|
||||
u8 shift;
|
||||
u16 duration[MCS_GROUP_RATES];
|
||||
@@ -376,6 +459,26 @@ static const struct mcs_group airtime_mc
|
||||
HE_GROUP(6, HE_GI_32, BW_160),
|
||||
HE_GROUP(7, HE_GI_32, BW_160),
|
||||
HE_GROUP(8, HE_GI_32, BW_160),
|
||||
+
|
||||
+ EHT_GROUP_RANGE(EHT_GI_08, BW_20),
|
||||
+ EHT_GROUP_RANGE(EHT_GI_16, BW_20),
|
||||
+ EHT_GROUP_RANGE(EHT_GI_32, BW_20),
|
||||
+
|
||||
+ EHT_GROUP_RANGE(EHT_GI_08, BW_40),
|
||||
+ EHT_GROUP_RANGE(EHT_GI_16, BW_40),
|
||||
+ EHT_GROUP_RANGE(EHT_GI_32, BW_40),
|
||||
+
|
||||
+ EHT_GROUP_RANGE(EHT_GI_08, BW_80),
|
||||
+ EHT_GROUP_RANGE(EHT_GI_16, BW_80),
|
||||
+ EHT_GROUP_RANGE(EHT_GI_32, BW_80),
|
||||
+
|
||||
+ EHT_GROUP_RANGE(EHT_GI_08, BW_160),
|
||||
+ EHT_GROUP_RANGE(EHT_GI_16, BW_160),
|
||||
+ EHT_GROUP_RANGE(EHT_GI_32, BW_160),
|
||||
+
|
||||
+ EHT_GROUP_RANGE(EHT_GI_08, BW_320),
|
||||
+ EHT_GROUP_RANGE(EHT_GI_16, BW_320),
|
||||
+ EHT_GROUP_RANGE(EHT_GI_32, BW_320),
|
||||
};
|
||||
|
||||
static u32
|
||||
@@ -422,6 +525,9 @@ static u32 ieee80211_get_rate_duration(s
|
||||
case RATE_INFO_BW_160:
|
||||
bw = BW_160;
|
||||
break;
|
||||
+ case RATE_INFO_BW_320:
|
||||
+ bw = BW_320;
|
||||
+ break;
|
||||
default:
|
||||
WARN_ON_ONCE(1);
|
||||
return 0;
|
||||
@@ -443,14 +549,27 @@ static u32 ieee80211_get_rate_duration(s
|
||||
idx = status->rate_idx;
|
||||
group = HE_GROUP_IDX(streams, status->he_gi, bw);
|
||||
break;
|
||||
+ case RX_ENC_EHT:
|
||||
+ streams = status->nss;
|
||||
+ idx = status->rate_idx;
|
||||
+ group = EHT_GROUP_IDX(streams, status->eht.gi, bw);
|
||||
+ break;
|
||||
default:
|
||||
WARN_ON_ONCE(1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
- if (WARN_ON_ONCE((status->encoding != RX_ENC_HE && streams > 4) ||
|
||||
- (status->encoding == RX_ENC_HE && streams > 8)))
|
||||
- return 0;
|
||||
+ switch (status->encoding) {
|
||||
+ case RX_ENC_EHT:
|
||||
+ case RX_ENC_HE:
|
||||
+ if (WARN_ON_ONCE(streams > 8))
|
||||
+ return 0;
|
||||
+ break;
|
||||
+ default:
|
||||
+ if (WARN_ON_ONCE(streams > 4))
|
||||
+ return 0;
|
||||
+ break;
|
||||
+ }
|
||||
|
||||
if (idx >= MCS_GROUP_RATES)
|
||||
return 0;
|
||||
@@ -517,7 +636,9 @@ static bool ieee80211_fill_rate_info(str
|
||||
stat->nss = ri->nss;
|
||||
stat->rate_idx = ri->mcs;
|
||||
|
||||
- if (ri->flags & RATE_INFO_FLAGS_HE_MCS)
|
||||
+ if (ri->flags & RATE_INFO_FLAGS_EHT_MCS)
|
||||
+ stat->encoding = RX_ENC_EHT;
|
||||
+ else if (ri->flags & RATE_INFO_FLAGS_HE_MCS)
|
||||
stat->encoding = RX_ENC_HE;
|
||||
else if (ri->flags & RATE_INFO_FLAGS_VHT_MCS)
|
||||
stat->encoding = RX_ENC_VHT;
|
||||
@@ -529,7 +650,14 @@ static bool ieee80211_fill_rate_info(str
|
||||
if (ri->flags & RATE_INFO_FLAGS_SHORT_GI)
|
||||
stat->enc_flags |= RX_ENC_FLAG_SHORT_GI;
|
||||
|
||||
- stat->he_gi = ri->he_gi;
|
||||
+ switch (stat->encoding) {
|
||||
+ case RX_ENC_EHT:
|
||||
+ stat->eht.gi = ri->eht_gi;
|
||||
+ break;
|
||||
+ default:
|
||||
+ stat->he_gi = ri->he_gi;
|
||||
+ break;
|
||||
+ }
|
||||
|
||||
if (stat->encoding != RX_ENC_LEGACY)
|
||||
return true;
|
@ -1,122 +0,0 @@
|
||||
From: Karthikeyan Periyasamy <quic_periyasa@quicinc.com>
|
||||
Date: Tue, 17 Sep 2024 19:32:39 +0530
|
||||
Subject: [PATCH] wifi: cfg80211: check radio iface combination for multi radio
|
||||
per wiphy
|
||||
|
||||
Currently, wiphy_verify_combinations() fails for the multi-radio per wiphy
|
||||
due to the condition check on new global interface combination that DFS
|
||||
only works on one channel. In a multi-radio scenario, new global interface
|
||||
combination encompasses the capabilities of all radio combinations, so it
|
||||
supports more than one channel with DFS. For multi-radio per wiphy,
|
||||
interface combination verification needs to be performed for radio specific
|
||||
interface combinations. This is necessary as the new global interface
|
||||
combination combines the capabilities of all radio combinations.
|
||||
|
||||
Fixes: a01b1e9f9955 ("wifi: mac80211: add support for DFS with multiple radios")
|
||||
Signed-off-by: Karthikeyan Periyasamy <quic_periyasa@quicinc.com>
|
||||
---
|
||||
|
||||
--- a/net/wireless/core.c
|
||||
+++ b/net/wireless/core.c
|
||||
@@ -599,16 +599,20 @@ use_default_name:
|
||||
}
|
||||
EXPORT_SYMBOL(wiphy_new_nm);
|
||||
|
||||
-static int wiphy_verify_combinations(struct wiphy *wiphy)
|
||||
+static
|
||||
+int wiphy_verify_iface_combinations(struct wiphy *wiphy,
|
||||
+ const struct ieee80211_iface_combination *iface_comb,
|
||||
+ int n_iface_comb,
|
||||
+ bool combined_radio)
|
||||
{
|
||||
const struct ieee80211_iface_combination *c;
|
||||
int i, j;
|
||||
|
||||
- for (i = 0; i < wiphy->n_iface_combinations; i++) {
|
||||
+ for (i = 0; i < n_iface_comb; i++) {
|
||||
u32 cnt = 0;
|
||||
u16 all_iftypes = 0;
|
||||
|
||||
- c = &wiphy->iface_combinations[i];
|
||||
+ c = &iface_comb[i];
|
||||
|
||||
/*
|
||||
* Combinations with just one interface aren't real,
|
||||
@@ -621,9 +625,13 @@ static int wiphy_verify_combinations(str
|
||||
if (WARN_ON(!c->num_different_channels))
|
||||
return -EINVAL;
|
||||
|
||||
- /* DFS only works on one channel. */
|
||||
- if (WARN_ON(c->radar_detect_widths &&
|
||||
- (c->num_different_channels > 1)))
|
||||
+ /* DFS only works on one channel. Avoid this check
|
||||
+ * for multi-radio global combination, since it hold
|
||||
+ * the capabilities of all radio combinations.
|
||||
+ */
|
||||
+ if (!combined_radio &&
|
||||
+ WARN_ON(c->radar_detect_widths &&
|
||||
+ c->num_different_channels > 1))
|
||||
return -EINVAL;
|
||||
|
||||
if (WARN_ON(!c->n_limits))
|
||||
@@ -644,13 +652,21 @@ static int wiphy_verify_combinations(str
|
||||
if (WARN_ON(wiphy->software_iftypes & types))
|
||||
return -EINVAL;
|
||||
|
||||
- /* Only a single P2P_DEVICE can be allowed */
|
||||
- if (WARN_ON(types & BIT(NL80211_IFTYPE_P2P_DEVICE) &&
|
||||
+ /* Only a single P2P_DEVICE can be allowed, avoid this
|
||||
+ * check for multi-radio global combination, since it
|
||||
+ * hold the capabilities of all radio combinations.
|
||||
+ */
|
||||
+ if (!combined_radio &&
|
||||
+ WARN_ON(types & BIT(NL80211_IFTYPE_P2P_DEVICE) &&
|
||||
c->limits[j].max > 1))
|
||||
return -EINVAL;
|
||||
|
||||
- /* Only a single NAN can be allowed */
|
||||
- if (WARN_ON(types & BIT(NL80211_IFTYPE_NAN) &&
|
||||
+ /* Only a single NAN can be allowed, avoid this
|
||||
+ * check for multi-radio global combination, since it
|
||||
+ * hold the capabilities of all radio combinations.
|
||||
+ */
|
||||
+ if (!combined_radio &&
|
||||
+ WARN_ON(types & BIT(NL80211_IFTYPE_NAN) &&
|
||||
c->limits[j].max > 1))
|
||||
return -EINVAL;
|
||||
|
||||
@@ -674,6 +690,34 @@ static int wiphy_verify_combinations(str
|
||||
return 0;
|
||||
}
|
||||
|
||||
+static int wiphy_verify_combinations(struct wiphy *wiphy)
|
||||
+{
|
||||
+ int i, ret;
|
||||
+ bool combined_radio = false;
|
||||
+
|
||||
+ if (wiphy->n_radio) {
|
||||
+ for (i = 0; i < wiphy->n_radio; i++) {
|
||||
+ const struct wiphy_radio *radio = &wiphy->radio[i];
|
||||
+
|
||||
+ ret = wiphy_verify_iface_combinations(wiphy,
|
||||
+ radio->iface_combinations,
|
||||
+ radio->n_iface_combinations,
|
||||
+ false);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ combined_radio = true;
|
||||
+ }
|
||||
+
|
||||
+ ret = wiphy_verify_iface_combinations(wiphy,
|
||||
+ wiphy->iface_combinations,
|
||||
+ wiphy->n_iface_combinations,
|
||||
+ combined_radio);
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
int wiphy_register(struct wiphy *wiphy)
|
||||
{
|
||||
struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
|
@ -10,7 +10,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||
|
||||
--- a/net/mac80211/scan.c
|
||||
+++ b/net/mac80211/scan.c
|
||||
@@ -1178,14 +1178,14 @@ int ieee80211_request_ibss_scan(struct i
|
||||
@@ -1176,14 +1176,14 @@ int ieee80211_request_ibss_scan(struct i
|
||||
unsigned int n_channels)
|
||||
{
|
||||
struct ieee80211_local *local = sdata->local;
|
||||
@ -27,7 +27,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||
|
||||
/* fill internal scan request */
|
||||
if (!channels) {
|
||||
@@ -1202,7 +1202,9 @@ int ieee80211_request_ibss_scan(struct i
|
||||
@@ -1200,7 +1200,9 @@ int ieee80211_request_ibss_scan(struct i
|
||||
&local->hw.wiphy->bands[band]->channels[i];
|
||||
|
||||
if (tmp_ch->flags & (IEEE80211_CHAN_NO_IR |
|
||||
@ -38,7 +38,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||
continue;
|
||||
|
||||
local->int_scan_req->channels[n_ch] = tmp_ch;
|
||||
@@ -1211,21 +1213,23 @@ int ieee80211_request_ibss_scan(struct i
|
||||
@@ -1209,21 +1211,23 @@ int ieee80211_request_ibss_scan(struct i
|
||||
}
|
||||
|
||||
if (WARN_ON_ONCE(n_ch == 0))
|
||||
@ -66,7 +66,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||
|
||||
local->int_scan_req->n_channels = n_ch;
|
||||
}
|
||||
@@ -1235,9 +1239,7 @@ int ieee80211_request_ibss_scan(struct i
|
||||
@@ -1233,9 +1237,7 @@ int ieee80211_request_ibss_scan(struct i
|
||||
memcpy(local->int_scan_req->ssids[0].ssid, ssid, IEEE80211_MAX_SSID_LEN);
|
||||
local->int_scan_req->ssids[0].ssid_len = ssid_len;
|
||||
|
@ -1,64 +0,0 @@
|
||||
From: Issam Hamdi <ih@simonwunderlich.de>
|
||||
Date: Fri, 16 Aug 2024 16:24:18 +0200
|
||||
Subject: [PATCH] wifi: cfg80211: Set correct chandef when starting CAC
|
||||
|
||||
When starting CAC in a mode other than AP mode, it return a
|
||||
"WARNING: CPU: 0 PID: 63 at cfg80211_chandef_dfs_usable+0x20/0xaf [cfg80211]"
|
||||
caused by the chandef.chan being null at the end of CAC.
|
||||
|
||||
Solution: Ensure the channel definition is set for the different modes
|
||||
when starting CAC to avoid getting a NULL 'chan' at the end of CAC.
|
||||
|
||||
Call Trace:
|
||||
? show_regs.part.0+0x14/0x16
|
||||
? __warn+0x67/0xc0
|
||||
? cfg80211_chandef_dfs_usable+0x20/0xaf [cfg80211]
|
||||
? report_bug+0xa7/0x130
|
||||
? exc_overflow+0x30/0x30
|
||||
? handle_bug+0x27/0x50
|
||||
? exc_invalid_op+0x18/0x60
|
||||
? handle_exception+0xf6/0xf6
|
||||
? exc_overflow+0x30/0x30
|
||||
? cfg80211_chandef_dfs_usable+0x20/0xaf [cfg80211]
|
||||
? exc_overflow+0x30/0x30
|
||||
? cfg80211_chandef_dfs_usable+0x20/0xaf [cfg80211]
|
||||
? regulatory_propagate_dfs_state.cold+0x1b/0x4c [cfg80211]
|
||||
? cfg80211_propagate_cac_done_wk+0x1a/0x30 [cfg80211]
|
||||
? process_one_work+0x165/0x280
|
||||
? worker_thread+0x120/0x3f0
|
||||
? kthread+0xc2/0xf0
|
||||
? process_one_work+0x280/0x280
|
||||
? kthread_complete_and_exit+0x20/0x20
|
||||
? ret_from_fork+0x19/0x24
|
||||
|
||||
Reported-by: Kretschmer Mathias <mathias.kretschmer@fit.fraunhofer.de>
|
||||
Signed-off-by: Issam Hamdi <ih@simonwunderlich.de>
|
||||
Link: https://patch.msgid.link/20240816142418.3381951-1-ih@simonwunderlich.de
|
||||
[shorten subject, remove OCB, reorder cases to match previous list]
|
||||
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
|
||||
---
|
||||
|
||||
--- a/net/wireless/nl80211.c
|
||||
+++ b/net/wireless/nl80211.c
|
||||
@@ -10144,7 +10144,20 @@ static int nl80211_start_radar_detection
|
||||
|
||||
err = rdev_start_radar_detection(rdev, dev, &chandef, cac_time_ms);
|
||||
if (!err) {
|
||||
- wdev->links[0].ap.chandef = chandef;
|
||||
+ switch (wdev->iftype) {
|
||||
+ case NL80211_IFTYPE_AP:
|
||||
+ case NL80211_IFTYPE_P2P_GO:
|
||||
+ wdev->links[0].ap.chandef = chandef;
|
||||
+ break;
|
||||
+ case NL80211_IFTYPE_ADHOC:
|
||||
+ wdev->u.ibss.chandef = chandef;
|
||||
+ break;
|
||||
+ case NL80211_IFTYPE_MESH_POINT:
|
||||
+ wdev->u.mesh.chandef = chandef;
|
||||
+ break;
|
||||
+ default:
|
||||
+ break;
|
||||
+ }
|
||||
wdev->cac_started = true;
|
||||
wdev->cac_start_time = jiffies;
|
||||
wdev->cac_time_ms = cac_time_ms;
|
@ -9,7 +9,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||
|
||||
--- a/net/mac80211/chan.c
|
||||
+++ b/net/mac80211/chan.c
|
||||
@@ -1167,7 +1167,7 @@ ieee80211_replace_chanctx(struct ieee802
|
||||
@@ -1169,7 +1169,7 @@ ieee80211_replace_chanctx(struct ieee802
|
||||
static bool
|
||||
ieee80211_find_available_radio(struct ieee80211_local *local,
|
||||
const struct ieee80211_chan_req *chanreq,
|
||||
@ -18,7 +18,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||
{
|
||||
struct wiphy *wiphy = local->hw.wiphy;
|
||||
const struct wiphy_radio *radio;
|
||||
@@ -1178,6 +1178,9 @@ ieee80211_find_available_radio(struct ie
|
||||
@@ -1180,6 +1180,9 @@ ieee80211_find_available_radio(struct ie
|
||||
return true;
|
||||
|
||||
for (i = 0; i < wiphy->n_radio; i++) {
|
||||
@ -28,7 +28,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||
radio = &wiphy->radio[i];
|
||||
if (!cfg80211_radio_chandef_valid(radio, &chanreq->oper))
|
||||
continue;
|
||||
@@ -1211,7 +1214,9 @@ int ieee80211_link_reserve_chanctx(struc
|
||||
@@ -1213,7 +1216,9 @@ int ieee80211_link_reserve_chanctx(struc
|
||||
new_ctx = ieee80211_find_reservation_chanctx(local, chanreq, mode);
|
||||
if (!new_ctx) {
|
||||
if (ieee80211_can_create_new_chanctx(local, -1) &&
|
||||
@ -39,7 +39,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||
new_ctx = ieee80211_new_chanctx(local, chanreq, mode,
|
||||
false, radio_idx);
|
||||
else
|
||||
@@ -1881,7 +1886,9 @@ int _ieee80211_link_use_channel(struct i
|
||||
@@ -1883,7 +1888,9 @@ int _ieee80211_link_use_channel(struct i
|
||||
/* Note: context is now reserved */
|
||||
if (ctx)
|
||||
reserved = true;
|
@ -1,136 +0,0 @@
|
||||
From: Aditya Kumar Singh <quic_adisi@quicinc.com>
|
||||
Date: Fri, 6 Sep 2024 12:14:19 +0530
|
||||
Subject: [PATCH] Revert "wifi: mac80211: move radar detect work to sdata"
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
This reverts commit ce9e660ef32e ("wifi: mac80211: move radar detect work to sdata").
|
||||
|
||||
To enable radar detection with MLO, it’s essential to handle it on a
|
||||
per-link basis. This is because when using MLO, multiple links may already
|
||||
be active and beaconing. In this scenario, another link should be able to
|
||||
initiate a radar detection. Also, if underlying links are associated with
|
||||
different hardware devices but grouped together for MLO, they could
|
||||
potentially start radar detection simultaneously. Therefore, it makes
|
||||
sense to manage radar detection settings separately for each link by moving
|
||||
them back to a per-link data structure.
|
||||
|
||||
Signed-off-by: Aditya Kumar Singh <quic_adisi@quicinc.com>
|
||||
Link: https://patch.msgid.link/20240906064426.2101315-2-quic_adisi@quicinc.com
|
||||
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
|
||||
---
|
||||
|
||||
--- a/net/mac80211/cfg.c
|
||||
+++ b/net/mac80211/cfg.c
|
||||
@@ -1658,7 +1658,7 @@ static int ieee80211_stop_ap(struct wiph
|
||||
|
||||
if (sdata->wdev.cac_started) {
|
||||
chandef = link_conf->chanreq.oper;
|
||||
- wiphy_delayed_work_cancel(wiphy, &sdata->dfs_cac_timer_work);
|
||||
+ wiphy_delayed_work_cancel(wiphy, &link->dfs_cac_timer_work);
|
||||
cfg80211_cac_event(sdata->dev, &chandef,
|
||||
NL80211_RADAR_CAC_ABORTED,
|
||||
GFP_KERNEL);
|
||||
@@ -3482,7 +3482,7 @@ static int ieee80211_start_radar_detecti
|
||||
if (err)
|
||||
goto out_unlock;
|
||||
|
||||
- wiphy_delayed_work_queue(wiphy, &sdata->dfs_cac_timer_work,
|
||||
+ wiphy_delayed_work_queue(wiphy, &sdata->deflink.dfs_cac_timer_work,
|
||||
msecs_to_jiffies(cac_time_ms));
|
||||
|
||||
out_unlock:
|
||||
@@ -3499,7 +3499,7 @@ static void ieee80211_end_cac(struct wip
|
||||
|
||||
list_for_each_entry(sdata, &local->interfaces, list) {
|
||||
wiphy_delayed_work_cancel(wiphy,
|
||||
- &sdata->dfs_cac_timer_work);
|
||||
+ &sdata->deflink.dfs_cac_timer_work);
|
||||
|
||||
if (sdata->wdev.cac_started) {
|
||||
ieee80211_link_release_channel(&sdata->deflink);
|
||||
--- a/net/mac80211/ieee80211_i.h
|
||||
+++ b/net/mac80211/ieee80211_i.h
|
||||
@@ -1069,6 +1069,7 @@ struct ieee80211_link_data {
|
||||
int ap_power_level; /* in dBm */
|
||||
|
||||
bool radar_required;
|
||||
+ struct wiphy_delayed_work dfs_cac_timer_work;
|
||||
|
||||
union {
|
||||
struct ieee80211_link_data_managed mgd;
|
||||
@@ -1167,8 +1168,6 @@ struct ieee80211_sub_if_data {
|
||||
struct ieee80211_link_data deflink;
|
||||
struct ieee80211_link_data __rcu *link[IEEE80211_MLD_MAX_NUM_LINKS];
|
||||
|
||||
- struct wiphy_delayed_work dfs_cac_timer_work;
|
||||
-
|
||||
/* for ieee80211_set_active_links_async() */
|
||||
struct wiphy_work activate_links_work;
|
||||
u16 desired_active_links;
|
||||
--- a/net/mac80211/iface.c
|
||||
+++ b/net/mac80211/iface.c
|
||||
@@ -551,7 +551,7 @@ static void ieee80211_do_stop(struct iee
|
||||
wiphy_work_cancel(local->hw.wiphy,
|
||||
&sdata->deflink.color_change_finalize_work);
|
||||
wiphy_delayed_work_cancel(local->hw.wiphy,
|
||||
- &sdata->dfs_cac_timer_work);
|
||||
+ &sdata->deflink.dfs_cac_timer_work);
|
||||
|
||||
if (sdata->wdev.cac_started) {
|
||||
chandef = sdata->vif.bss_conf.chanreq.oper;
|
||||
@@ -1744,8 +1744,6 @@ static void ieee80211_setup_sdata(struct
|
||||
wiphy_work_init(&sdata->work, ieee80211_iface_work);
|
||||
wiphy_work_init(&sdata->activate_links_work,
|
||||
ieee80211_activate_links_work);
|
||||
- wiphy_delayed_work_init(&sdata->dfs_cac_timer_work,
|
||||
- ieee80211_dfs_cac_timer_work);
|
||||
|
||||
switch (type) {
|
||||
case NL80211_IFTYPE_P2P_GO:
|
||||
--- a/net/mac80211/link.c
|
||||
+++ b/net/mac80211/link.c
|
||||
@@ -45,6 +45,8 @@ void ieee80211_link_init(struct ieee8021
|
||||
ieee80211_color_collision_detection_work);
|
||||
INIT_LIST_HEAD(&link->assigned_chanctx_list);
|
||||
INIT_LIST_HEAD(&link->reserved_chanctx_list);
|
||||
+ wiphy_delayed_work_init(&link->dfs_cac_timer_work,
|
||||
+ ieee80211_dfs_cac_timer_work);
|
||||
|
||||
if (!deflink) {
|
||||
switch (sdata->vif.type) {
|
||||
--- a/net/mac80211/mlme.c
|
||||
+++ b/net/mac80211/mlme.c
|
||||
@@ -3031,15 +3031,16 @@ void ieee80211_dynamic_ps_timer(struct t
|
||||
|
||||
void ieee80211_dfs_cac_timer_work(struct wiphy *wiphy, struct wiphy_work *work)
|
||||
{
|
||||
- struct ieee80211_sub_if_data *sdata =
|
||||
- container_of(work, struct ieee80211_sub_if_data,
|
||||
+ struct ieee80211_link_data *link =
|
||||
+ container_of(work, struct ieee80211_link_data,
|
||||
dfs_cac_timer_work.work);
|
||||
- struct cfg80211_chan_def chandef = sdata->vif.bss_conf.chanreq.oper;
|
||||
+ struct cfg80211_chan_def chandef = link->conf->chanreq.oper;
|
||||
+ struct ieee80211_sub_if_data *sdata = link->sdata;
|
||||
|
||||
lockdep_assert_wiphy(sdata->local->hw.wiphy);
|
||||
|
||||
if (sdata->wdev.cac_started) {
|
||||
- ieee80211_link_release_channel(&sdata->deflink);
|
||||
+ ieee80211_link_release_channel(link);
|
||||
cfg80211_cac_event(sdata->dev, &chandef,
|
||||
NL80211_RADAR_CAC_FINISHED,
|
||||
GFP_KERNEL);
|
||||
--- a/net/mac80211/util.c
|
||||
+++ b/net/mac80211/util.c
|
||||
@@ -3460,7 +3460,7 @@ void ieee80211_dfs_cac_cancel(struct iee
|
||||
|
||||
list_for_each_entry(sdata, &local->interfaces, list) {
|
||||
wiphy_delayed_work_cancel(local->hw.wiphy,
|
||||
- &sdata->dfs_cac_timer_work);
|
||||
+ &sdata->deflink.dfs_cac_timer_work);
|
||||
|
||||
if (sdata->wdev.cac_started) {
|
||||
chandef = sdata->vif.bss_conf.chanreq.oper;
|
@ -88,7 +88,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||
bool cfg80211_any_usable_channels(struct wiphy *wiphy,
|
||||
--- a/net/wireless/core.h
|
||||
+++ b/net/wireless/core.h
|
||||
@@ -510,6 +510,7 @@ static inline unsigned int elapsed_jiffi
|
||||
@@ -518,6 +518,7 @@ static inline unsigned int elapsed_jiffi
|
||||
}
|
||||
|
||||
int cfg80211_set_monitor_channel(struct cfg80211_registered_device *rdev,
|
@ -1,50 +0,0 @@
|
||||
From: Aditya Kumar Singh <quic_adisi@quicinc.com>
|
||||
Date: Fri, 6 Sep 2024 12:14:20 +0530
|
||||
Subject: [PATCH] wifi: mac80211: remove label usage in
|
||||
ieee80211_start_radar_detection()
|
||||
|
||||
After locks rework [1], ieee80211_start_radar_detection() function is no
|
||||
longer acquiring any lock as such explicitly. Hence, it is not unlocking
|
||||
anything as well. However, label "out_unlock" is still used which creates
|
||||
confusion. Also, now there is no need of goto label as such.
|
||||
|
||||
Get rid of the goto logic and use direct return statements.
|
||||
|
||||
[1]: https://lore.kernel.org/all/20230828135928.b1c6efffe9ad.I4aec875e25abc9ef0b5ad1e70b5747fd483fbd3c@changeid/
|
||||
|
||||
Signed-off-by: Aditya Kumar Singh <quic_adisi@quicinc.com>
|
||||
Link: https://patch.msgid.link/20240906064426.2101315-3-quic_adisi@quicinc.com
|
||||
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
|
||||
---
|
||||
|
||||
--- a/net/mac80211/cfg.c
|
||||
+++ b/net/mac80211/cfg.c
|
||||
@@ -3468,10 +3468,8 @@ static int ieee80211_start_radar_detecti
|
||||
|
||||
lockdep_assert_wiphy(local->hw.wiphy);
|
||||
|
||||
- if (!list_empty(&local->roc_list) || local->scanning) {
|
||||
- err = -EBUSY;
|
||||
- goto out_unlock;
|
||||
- }
|
||||
+ if (!list_empty(&local->roc_list) || local->scanning)
|
||||
+ return -EBUSY;
|
||||
|
||||
/* whatever, but channel contexts should not complain about that one */
|
||||
sdata->deflink.smps_mode = IEEE80211_SMPS_OFF;
|
||||
@@ -3480,13 +3478,12 @@ static int ieee80211_start_radar_detecti
|
||||
err = ieee80211_link_use_channel(&sdata->deflink, &chanreq,
|
||||
IEEE80211_CHANCTX_SHARED);
|
||||
if (err)
|
||||
- goto out_unlock;
|
||||
+ return err;
|
||||
|
||||
wiphy_delayed_work_queue(wiphy, &sdata->deflink.dfs_cac_timer_work,
|
||||
msecs_to_jiffies(cac_time_ms));
|
||||
|
||||
- out_unlock:
|
||||
- return err;
|
||||
+ return 0;
|
||||
}
|
||||
|
||||
static void ieee80211_end_cac(struct wiphy *wiphy,
|
@ -95,7 +95,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||
if (ret)
|
||||
return ret;
|
||||
done:
|
||||
@@ -3049,7 +3057,8 @@ static int ieee80211_set_tx_power(struct
|
||||
@@ -3050,7 +3058,8 @@ static int ieee80211_set_tx_power(struct
|
||||
if (wdev) {
|
||||
sdata = IEEE80211_WDEV_TO_SUB_IF(wdev);
|
||||
|
||||
@ -105,7 +105,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||
if (!ieee80211_hw_check(&local->hw, WANT_MONITOR_VIF))
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
@@ -3097,7 +3106,8 @@ static int ieee80211_set_tx_power(struct
|
||||
@@ -3098,7 +3107,8 @@ static int ieee80211_set_tx_power(struct
|
||||
}
|
||||
|
||||
list_for_each_entry(sdata, &local->interfaces, list) {
|
||||
@ -115,7 +115,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||
has_monitor = true;
|
||||
continue;
|
||||
}
|
||||
@@ -3107,7 +3117,8 @@ static int ieee80211_set_tx_power(struct
|
||||
@@ -3108,7 +3118,8 @@ static int ieee80211_set_tx_power(struct
|
||||
sdata->vif.bss_conf.txpower_type = txp_type;
|
||||
}
|
||||
list_for_each_entry(sdata, &local->interfaces, list) {
|
||||
@ -125,7 +125,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||
continue;
|
||||
ieee80211_recalc_txpower(sdata, update_txp_type);
|
||||
}
|
||||
@@ -4299,7 +4310,8 @@ static int ieee80211_cfg_get_channel(str
|
||||
@@ -4303,7 +4314,8 @@ static int ieee80211_cfg_get_channel(str
|
||||
if (chanctx_conf) {
|
||||
*chandef = link->conf->chanreq.oper;
|
||||
ret = 0;
|
||||
@ -137,7 +137,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||
*chandef = local->monitor_chanreq.oper;
|
||||
--- a/net/mac80211/chan.c
|
||||
+++ b/net/mac80211/chan.c
|
||||
@@ -337,6 +337,10 @@ ieee80211_get_chanctx_max_required_bw(st
|
||||
@@ -339,6 +339,10 @@ ieee80211_get_chanctx_max_required_bw(st
|
||||
case NL80211_IFTYPE_P2P_DEVICE:
|
||||
case NL80211_IFTYPE_NAN:
|
||||
continue;
|
||||
@ -148,7 +148,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||
case NL80211_IFTYPE_ADHOC:
|
||||
case NL80211_IFTYPE_MESH_POINT:
|
||||
case NL80211_IFTYPE_OCB:
|
||||
@@ -345,7 +349,6 @@ ieee80211_get_chanctx_max_required_bw(st
|
||||
@@ -347,7 +351,6 @@ ieee80211_get_chanctx_max_required_bw(st
|
||||
case NL80211_IFTYPE_WDS:
|
||||
case NL80211_IFTYPE_UNSPECIFIED:
|
||||
case NUM_NL80211_IFTYPES:
|
||||
@ -156,7 +156,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||
case NL80211_IFTYPE_P2P_CLIENT:
|
||||
case NL80211_IFTYPE_P2P_GO:
|
||||
WARN_ON_ONCE(1);
|
||||
@@ -954,6 +957,10 @@ void ieee80211_recalc_smps_chanctx(struc
|
||||
@@ -956,6 +959,10 @@ void ieee80211_recalc_smps_chanctx(struc
|
||||
if (!link->sdata->u.mgd.associated)
|
||||
continue;
|
||||
break;
|
||||
@ -167,7 +167,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||
case NL80211_IFTYPE_AP:
|
||||
case NL80211_IFTYPE_ADHOC:
|
||||
case NL80211_IFTYPE_MESH_POINT:
|
||||
@@ -966,6 +973,11 @@ void ieee80211_recalc_smps_chanctx(struc
|
||||
@@ -968,6 +975,11 @@ void ieee80211_recalc_smps_chanctx(struc
|
||||
if (rcu_access_pointer(link->conf->chanctx_conf) != &chanctx->conf)
|
||||
continue;
|
||||
|
||||
@ -296,8 +296,8 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||
}
|
||||
--- a/net/mac80211/util.c
|
||||
+++ b/net/mac80211/util.c
|
||||
@@ -754,7 +754,8 @@ static void __iterate_interfaces(struct
|
||||
list_for_each_entry_rcu(sdata, &local->interfaces, list) {
|
||||
@@ -739,7 +739,8 @@ static void __iterate_interfaces(struct
|
||||
lockdep_is_held(&local->hw.wiphy->mtx)) {
|
||||
switch (sdata->vif.type) {
|
||||
case NL80211_IFTYPE_MONITOR:
|
||||
- if (!(sdata->u.mntr.flags & MONITOR_FLAG_ACTIVE))
|
||||
@ -306,7 +306,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||
continue;
|
||||
break;
|
||||
case NL80211_IFTYPE_AP_VLAN:
|
||||
@@ -1857,8 +1858,10 @@ int ieee80211_reconfig(struct ieee80211_
|
||||
@@ -1856,8 +1857,10 @@ int ieee80211_reconfig(struct ieee80211_
|
||||
}
|
||||
|
||||
list_for_each_entry(sdata, &local->interfaces, list) {
|
||||
@ -318,7 +318,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||
ieee80211_sdata_running(sdata)) {
|
||||
res = drv_add_interface(local, sdata);
|
||||
if (WARN_ON(res))
|
||||
@@ -1871,11 +1874,14 @@ int ieee80211_reconfig(struct ieee80211_
|
||||
@@ -1870,11 +1873,14 @@ int ieee80211_reconfig(struct ieee80211_
|
||||
*/
|
||||
if (res) {
|
||||
list_for_each_entry_continue_reverse(sdata, &local->interfaces,
|
@ -1,42 +0,0 @@
|
||||
From: Aditya Kumar Singh <quic_adisi@quicinc.com>
|
||||
Date: Fri, 6 Sep 2024 12:14:21 +0530
|
||||
Subject: [PATCH] wifi: trace: unlink rdev_end_cac trace event from
|
||||
wiphy_netdev_evt class
|
||||
|
||||
rdev_end_cac trace event is linked with wiphy_netdev_evt event class.
|
||||
There is no option to pass link ID currently to wiphy_netdev_evt class.
|
||||
A subsequent change would pass link ID to rdev_end_cac event and hence
|
||||
it can no longer derive the event class from wiphy_netdev_evt.
|
||||
|
||||
Therefore, unlink rdev_end_cac event from wiphy_netdev_evt and define it's
|
||||
own independent trace event. Link ID would be passed in subsequent change.
|
||||
|
||||
Signed-off-by: Aditya Kumar Singh <quic_adisi@quicinc.com>
|
||||
Link: https://patch.msgid.link/20240906064426.2101315-4-quic_adisi@quicinc.com
|
||||
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
|
||||
---
|
||||
|
||||
--- a/net/wireless/trace.h
|
||||
+++ b/net/wireless/trace.h
|
||||
@@ -805,9 +805,18 @@ DEFINE_EVENT(wiphy_netdev_evt, rdev_flus
|
||||
TP_ARGS(wiphy, netdev)
|
||||
);
|
||||
|
||||
-DEFINE_EVENT(wiphy_netdev_evt, rdev_end_cac,
|
||||
- TP_PROTO(struct wiphy *wiphy, struct net_device *netdev),
|
||||
- TP_ARGS(wiphy, netdev)
|
||||
+TRACE_EVENT(rdev_end_cac,
|
||||
+ TP_PROTO(struct wiphy *wiphy, struct net_device *netdev),
|
||||
+ TP_ARGS(wiphy, netdev),
|
||||
+ TP_STRUCT__entry(
|
||||
+ WIPHY_ENTRY
|
||||
+ NETDEV_ENTRY
|
||||
+ ),
|
||||
+ TP_fast_assign(
|
||||
+ WIPHY_ASSIGN;
|
||||
+ NETDEV_ASSIGN;
|
||||
+ ),
|
||||
+ TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT, WIPHY_PR_ARG, NETDEV_PR_ARG)
|
||||
);
|
||||
|
||||
DECLARE_EVENT_CLASS(station_add_change,
|
@ -1,309 +0,0 @@
|
||||
From: Aditya Kumar Singh <quic_adisi@quicinc.com>
|
||||
Date: Fri, 6 Sep 2024 12:14:22 +0530
|
||||
Subject: [PATCH] wifi: cfg80211: move DFS related members to links[] in
|
||||
wireless_dev
|
||||
|
||||
A few members related to DFS handling are currently under per wireless
|
||||
device data structure. However, in order to support DFS with MLO, there is
|
||||
a need to have them on a per-link manner.
|
||||
|
||||
Hence, as a preliminary step, move members cac_started, cac_start_time
|
||||
and cac_time_ms to be on a per-link basis.
|
||||
|
||||
Since currently, link ID is not known at all places, use default value of
|
||||
0 for now.
|
||||
|
||||
Signed-off-by: Aditya Kumar Singh <quic_adisi@quicinc.com>
|
||||
Link: https://patch.msgid.link/20240906064426.2101315-5-quic_adisi@quicinc.com
|
||||
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
|
||||
---
|
||||
|
||||
--- a/drivers/net/wireless/marvell/mwifiex/11h.c
|
||||
+++ b/drivers/net/wireless/marvell/mwifiex/11h.c
|
||||
@@ -117,7 +117,7 @@ void mwifiex_dfs_cac_work_queue(struct w
|
||||
dfs_cac_work);
|
||||
|
||||
chandef = priv->dfs_chandef;
|
||||
- if (priv->wdev.cac_started) {
|
||||
+ if (priv->wdev.links[0].cac_started) {
|
||||
mwifiex_dbg(priv->adapter, MSG,
|
||||
"CAC timer finished; No radar detected\n");
|
||||
cfg80211_cac_event(priv->netdev, &chandef,
|
||||
@@ -174,7 +174,7 @@ int mwifiex_stop_radar_detection(struct
|
||||
*/
|
||||
void mwifiex_abort_cac(struct mwifiex_private *priv)
|
||||
{
|
||||
- if (priv->wdev.cac_started) {
|
||||
+ if (priv->wdev.links[0].cac_started) {
|
||||
if (mwifiex_stop_radar_detection(priv, &priv->dfs_chandef))
|
||||
mwifiex_dbg(priv->adapter, ERROR,
|
||||
"failed to stop CAC in FW\n");
|
||||
--- a/drivers/net/wireless/marvell/mwifiex/cfg80211.c
|
||||
+++ b/drivers/net/wireless/marvell/mwifiex/cfg80211.c
|
||||
@@ -1880,7 +1880,7 @@ mwifiex_cfg80211_del_station(struct wiph
|
||||
struct mwifiex_sta_node *sta_node;
|
||||
u8 deauth_mac[ETH_ALEN];
|
||||
|
||||
- if (!priv->bss_started && priv->wdev.cac_started) {
|
||||
+ if (!priv->bss_started && priv->wdev.links[0].cac_started) {
|
||||
mwifiex_dbg(priv->adapter, INFO, "%s: abort CAC!\n", __func__);
|
||||
mwifiex_abort_cac(priv);
|
||||
}
|
||||
@@ -3978,7 +3978,7 @@ mwifiex_cfg80211_channel_switch(struct w
|
||||
return -EBUSY;
|
||||
}
|
||||
|
||||
- if (priv->wdev.cac_started)
|
||||
+ if (priv->wdev.links[0].cac_started)
|
||||
return -EBUSY;
|
||||
|
||||
if (cfg80211_chandef_identical(¶ms->chandef,
|
||||
--- a/drivers/net/wireless/quantenna/qtnfmac/event.c
|
||||
+++ b/drivers/net/wireless/quantenna/qtnfmac/event.c
|
||||
@@ -520,21 +520,21 @@ static int qtnf_event_handle_radar(struc
|
||||
cfg80211_radar_event(wiphy, &chandef, GFP_KERNEL);
|
||||
break;
|
||||
case QLINK_RADAR_CAC_FINISHED:
|
||||
- if (!vif->wdev.cac_started)
|
||||
+ if (!vif->wdev.links[0].cac_started)
|
||||
break;
|
||||
|
||||
cfg80211_cac_event(vif->netdev, &chandef,
|
||||
NL80211_RADAR_CAC_FINISHED, GFP_KERNEL);
|
||||
break;
|
||||
case QLINK_RADAR_CAC_ABORTED:
|
||||
- if (!vif->wdev.cac_started)
|
||||
+ if (!vif->wdev.links[0].cac_started)
|
||||
break;
|
||||
|
||||
cfg80211_cac_event(vif->netdev, &chandef,
|
||||
NL80211_RADAR_CAC_ABORTED, GFP_KERNEL);
|
||||
break;
|
||||
case QLINK_RADAR_CAC_STARTED:
|
||||
- if (vif->wdev.cac_started)
|
||||
+ if (vif->wdev.links[0].cac_started)
|
||||
break;
|
||||
|
||||
if (!wiphy_ext_feature_isset(wiphy,
|
||||
--- a/include/net/cfg80211.h
|
||||
+++ b/include/net/cfg80211.h
|
||||
@@ -6198,9 +6198,6 @@ enum ieee80211_ap_reg_power {
|
||||
* @address: The address for this device, valid only if @netdev is %NULL
|
||||
* @is_running: true if this is a non-netdev device that has been started, e.g.
|
||||
* the P2P Device.
|
||||
- * @cac_started: true if DFS channel availability check has been started
|
||||
- * @cac_start_time: timestamp (jiffies) when the dfs state was entered.
|
||||
- * @cac_time_ms: CAC time in ms
|
||||
* @ps: powersave mode is enabled
|
||||
* @ps_timeout: dynamic powersave timeout
|
||||
* @ap_unexpected_nlportid: (private) netlink port ID of application
|
||||
@@ -6224,6 +6221,11 @@ enum ieee80211_ap_reg_power {
|
||||
* unprotected beacon report
|
||||
* @links: array of %IEEE80211_MLD_MAX_NUM_LINKS elements containing @addr
|
||||
* @ap and @client for each link
|
||||
+ * @links[].cac_started: true if DFS channel availability check has been
|
||||
+ * started
|
||||
+ * @links[].cac_start_time: timestamp (jiffies) when the dfs state was
|
||||
+ * entered.
|
||||
+ * @links[].cac_time_ms: CAC time in ms
|
||||
* @valid_links: bitmap describing what elements of @links are valid
|
||||
*/
|
||||
struct wireless_dev {
|
||||
@@ -6265,11 +6267,6 @@ struct wireless_dev {
|
||||
u32 owner_nlportid;
|
||||
bool nl_owner_dead;
|
||||
|
||||
- /* FIXME: need to rework radar detection for MLO */
|
||||
- bool cac_started;
|
||||
- unsigned long cac_start_time;
|
||||
- unsigned int cac_time_ms;
|
||||
-
|
||||
#ifdef CPTCFG_CFG80211_WEXT
|
||||
/* wext data */
|
||||
struct {
|
||||
@@ -6336,6 +6333,10 @@ struct wireless_dev {
|
||||
struct cfg80211_internal_bss *current_bss;
|
||||
} client;
|
||||
};
|
||||
+
|
||||
+ bool cac_started;
|
||||
+ unsigned long cac_start_time;
|
||||
+ unsigned int cac_time_ms;
|
||||
} links[IEEE80211_MLD_MAX_NUM_LINKS];
|
||||
u16 valid_links;
|
||||
};
|
||||
--- a/net/mac80211/cfg.c
|
||||
+++ b/net/mac80211/cfg.c
|
||||
@@ -1656,7 +1656,7 @@ static int ieee80211_stop_ap(struct wiph
|
||||
ieee80211_link_info_change_notify(sdata, link,
|
||||
BSS_CHANGED_BEACON_ENABLED);
|
||||
|
||||
- if (sdata->wdev.cac_started) {
|
||||
+ if (sdata->wdev.links[0].cac_started) {
|
||||
chandef = link_conf->chanreq.oper;
|
||||
wiphy_delayed_work_cancel(wiphy, &link->dfs_cac_timer_work);
|
||||
cfg80211_cac_event(sdata->dev, &chandef,
|
||||
@@ -3498,9 +3498,9 @@ static void ieee80211_end_cac(struct wip
|
||||
wiphy_delayed_work_cancel(wiphy,
|
||||
&sdata->deflink.dfs_cac_timer_work);
|
||||
|
||||
- if (sdata->wdev.cac_started) {
|
||||
+ if (sdata->wdev.links[0].cac_started) {
|
||||
ieee80211_link_release_channel(&sdata->deflink);
|
||||
- sdata->wdev.cac_started = false;
|
||||
+ sdata->wdev.links[0].cac_started = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3955,7 +3955,7 @@ __ieee80211_channel_switch(struct wiphy
|
||||
if (!list_empty(&local->roc_list) || local->scanning)
|
||||
return -EBUSY;
|
||||
|
||||
- if (sdata->wdev.cac_started)
|
||||
+ if (sdata->wdev.links[0].cac_started)
|
||||
return -EBUSY;
|
||||
|
||||
if (WARN_ON(link_id >= IEEE80211_MLD_MAX_NUM_LINKS))
|
||||
--- a/net/mac80211/iface.c
|
||||
+++ b/net/mac80211/iface.c
|
||||
@@ -553,7 +553,7 @@ static void ieee80211_do_stop(struct iee
|
||||
wiphy_delayed_work_cancel(local->hw.wiphy,
|
||||
&sdata->deflink.dfs_cac_timer_work);
|
||||
|
||||
- if (sdata->wdev.cac_started) {
|
||||
+ if (sdata->wdev.links[0].cac_started) {
|
||||
chandef = sdata->vif.bss_conf.chanreq.oper;
|
||||
WARN_ON(local->suspended);
|
||||
ieee80211_link_release_channel(&sdata->deflink);
|
||||
--- a/net/mac80211/mlme.c
|
||||
+++ b/net/mac80211/mlme.c
|
||||
@@ -3039,7 +3039,7 @@ void ieee80211_dfs_cac_timer_work(struct
|
||||
|
||||
lockdep_assert_wiphy(sdata->local->hw.wiphy);
|
||||
|
||||
- if (sdata->wdev.cac_started) {
|
||||
+ if (sdata->wdev.links[0].cac_started) {
|
||||
ieee80211_link_release_channel(link);
|
||||
cfg80211_cac_event(sdata->dev, &chandef,
|
||||
NL80211_RADAR_CAC_FINISHED,
|
||||
--- a/net/mac80211/scan.c
|
||||
+++ b/net/mac80211/scan.c
|
||||
@@ -585,7 +585,7 @@ static bool __ieee80211_can_leave_ch(str
|
||||
return false;
|
||||
|
||||
list_for_each_entry(sdata_iter, &local->interfaces, list) {
|
||||
- if (sdata_iter->wdev.cac_started)
|
||||
+ if (sdata_iter->wdev.links[0].cac_started)
|
||||
return false;
|
||||
}
|
||||
|
||||
--- a/net/mac80211/util.c
|
||||
+++ b/net/mac80211/util.c
|
||||
@@ -3462,7 +3462,7 @@ void ieee80211_dfs_cac_cancel(struct iee
|
||||
wiphy_delayed_work_cancel(local->hw.wiphy,
|
||||
&sdata->deflink.dfs_cac_timer_work);
|
||||
|
||||
- if (sdata->wdev.cac_started) {
|
||||
+ if (sdata->wdev.links[0].cac_started) {
|
||||
chandef = sdata->vif.bss_conf.chanreq.oper;
|
||||
ieee80211_link_release_channel(&sdata->deflink);
|
||||
cfg80211_cac_event(sdata->dev,
|
||||
--- a/net/wireless/ibss.c
|
||||
+++ b/net/wireless/ibss.c
|
||||
@@ -94,7 +94,7 @@ int __cfg80211_join_ibss(struct cfg80211
|
||||
|
||||
lockdep_assert_held(&rdev->wiphy.mtx);
|
||||
|
||||
- if (wdev->cac_started)
|
||||
+ if (wdev->links[0].cac_started)
|
||||
return -EBUSY;
|
||||
|
||||
if (wdev->u.ibss.ssid_len)
|
||||
--- a/net/wireless/mesh.c
|
||||
+++ b/net/wireless/mesh.c
|
||||
@@ -127,7 +127,7 @@ int __cfg80211_join_mesh(struct cfg80211
|
||||
if (!rdev->ops->join_mesh)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
- if (wdev->cac_started)
|
||||
+ if (wdev->links[0].cac_started)
|
||||
return -EBUSY;
|
||||
|
||||
if (!setup->chandef.chan) {
|
||||
--- a/net/wireless/mlme.c
|
||||
+++ b/net/wireless/mlme.c
|
||||
@@ -1124,13 +1124,14 @@ void cfg80211_cac_event(struct net_devic
|
||||
|
||||
trace_cfg80211_cac_event(netdev, event);
|
||||
|
||||
- if (WARN_ON(!wdev->cac_started && event != NL80211_RADAR_CAC_STARTED))
|
||||
+ if (WARN_ON(!wdev->links[0].cac_started &&
|
||||
+ event != NL80211_RADAR_CAC_STARTED))
|
||||
return;
|
||||
|
||||
switch (event) {
|
||||
case NL80211_RADAR_CAC_FINISHED:
|
||||
- timeout = wdev->cac_start_time +
|
||||
- msecs_to_jiffies(wdev->cac_time_ms);
|
||||
+ timeout = wdev->links[0].cac_start_time +
|
||||
+ msecs_to_jiffies(wdev->links[0].cac_time_ms);
|
||||
WARN_ON(!time_after_eq(jiffies, timeout));
|
||||
cfg80211_set_dfs_state(wiphy, chandef, NL80211_DFS_AVAILABLE);
|
||||
memcpy(&rdev->cac_done_chandef, chandef,
|
||||
@@ -1139,10 +1140,10 @@ void cfg80211_cac_event(struct net_devic
|
||||
cfg80211_sched_dfs_chan_update(rdev);
|
||||
fallthrough;
|
||||
case NL80211_RADAR_CAC_ABORTED:
|
||||
- wdev->cac_started = false;
|
||||
+ wdev->links[0].cac_started = false;
|
||||
break;
|
||||
case NL80211_RADAR_CAC_STARTED:
|
||||
- wdev->cac_started = true;
|
||||
+ wdev->links[0].cac_started = true;
|
||||
break;
|
||||
default:
|
||||
WARN_ON(1);
|
||||
--- a/net/wireless/nl80211.c
|
||||
+++ b/net/wireless/nl80211.c
|
||||
@@ -6066,7 +6066,7 @@ static int nl80211_start_ap(struct sk_bu
|
||||
if (!rdev->ops->start_ap)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
- if (wdev->cac_started)
|
||||
+ if (wdev->links[0].cac_started)
|
||||
return -EBUSY;
|
||||
|
||||
if (wdev->links[link_id].ap.beacon_interval)
|
||||
@@ -10122,7 +10122,7 @@ static int nl80211_start_radar_detection
|
||||
goto unlock;
|
||||
}
|
||||
|
||||
- if (cfg80211_beaconing_iface_active(wdev) || wdev->cac_started) {
|
||||
+ if (cfg80211_beaconing_iface_active(wdev) || wdev->links[0].cac_started) {
|
||||
err = -EBUSY;
|
||||
goto unlock;
|
||||
}
|
||||
@@ -10158,9 +10158,9 @@ static int nl80211_start_radar_detection
|
||||
default:
|
||||
break;
|
||||
}
|
||||
- wdev->cac_started = true;
|
||||
- wdev->cac_start_time = jiffies;
|
||||
- wdev->cac_time_ms = cac_time_ms;
|
||||
+ wdev->links[0].cac_started = true;
|
||||
+ wdev->links[0].cac_start_time = jiffies;
|
||||
+ wdev->links[0].cac_time_ms = cac_time_ms;
|
||||
}
|
||||
unlock:
|
||||
wiphy_unlock(wiphy);
|
||||
--- a/net/wireless/reg.c
|
||||
+++ b/net/wireless/reg.c
|
||||
@@ -4241,7 +4241,7 @@ static void cfg80211_check_and_end_cac(s
|
||||
list_for_each_entry(wdev, &rdev->wiphy.wdev_list, list) {
|
||||
struct cfg80211_chan_def *chandef;
|
||||
|
||||
- if (!wdev->cac_started)
|
||||
+ if (!wdev->links[0].cac_started)
|
||||
continue;
|
||||
|
||||
/* FIXME: radar detection is tied to link 0 for now */
|
@ -1,435 +0,0 @@
|
||||
From: Aditya Kumar Singh <quic_adisi@quicinc.com>
|
||||
Date: Fri, 6 Sep 2024 12:14:23 +0530
|
||||
Subject: [PATCH] wifi: cfg80211: handle DFS per link
|
||||
|
||||
Currently, during starting a radar detection, no link id information is
|
||||
parsed and passed down. In order to support starting radar detection
|
||||
during Multi Link Operation, it is required to pass link id as well.
|
||||
|
||||
Add changes to first parse and then pass link id in the start radar
|
||||
detection path.
|
||||
|
||||
Additionally, update notification APIs to allow drivers/mac80211 to
|
||||
pass the link ID.
|
||||
|
||||
However, everything is handled at link 0 only until all API's are ready to
|
||||
handle it per link.
|
||||
|
||||
Signed-off-by: Aditya Kumar Singh <quic_adisi@quicinc.com>
|
||||
Link: https://patch.msgid.link/20240906064426.2101315-6-quic_adisi@quicinc.com
|
||||
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
|
||||
---
|
||||
|
||||
--- a/drivers/net/wireless/marvell/mwifiex/11h.c
|
||||
+++ b/drivers/net/wireless/marvell/mwifiex/11h.c
|
||||
@@ -122,7 +122,7 @@ void mwifiex_dfs_cac_work_queue(struct w
|
||||
"CAC timer finished; No radar detected\n");
|
||||
cfg80211_cac_event(priv->netdev, &chandef,
|
||||
NL80211_RADAR_CAC_FINISHED,
|
||||
- GFP_KERNEL);
|
||||
+ GFP_KERNEL, 0);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -182,7 +182,8 @@ void mwifiex_abort_cac(struct mwifiex_pr
|
||||
"Aborting delayed work for CAC.\n");
|
||||
cancel_delayed_work_sync(&priv->dfs_cac_work);
|
||||
cfg80211_cac_event(priv->netdev, &priv->dfs_chandef,
|
||||
- NL80211_RADAR_CAC_ABORTED, GFP_KERNEL);
|
||||
+ NL80211_RADAR_CAC_ABORTED, GFP_KERNEL,
|
||||
+ 0);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -221,7 +222,7 @@ int mwifiex_11h_handle_chanrpt_ready(str
|
||||
cfg80211_cac_event(priv->netdev,
|
||||
&priv->dfs_chandef,
|
||||
NL80211_RADAR_DETECTED,
|
||||
- GFP_KERNEL);
|
||||
+ GFP_KERNEL, 0);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
--- a/drivers/net/wireless/marvell/mwifiex/cfg80211.c
|
||||
+++ b/drivers/net/wireless/marvell/mwifiex/cfg80211.c
|
||||
@@ -4145,7 +4145,7 @@ static int
|
||||
mwifiex_cfg80211_start_radar_detection(struct wiphy *wiphy,
|
||||
struct net_device *dev,
|
||||
struct cfg80211_chan_def *chandef,
|
||||
- u32 cac_time_ms)
|
||||
+ u32 cac_time_ms, int link_id)
|
||||
{
|
||||
struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev);
|
||||
struct mwifiex_radar_params radar_params;
|
||||
--- a/drivers/net/wireless/quantenna/qtnfmac/cfg80211.c
|
||||
+++ b/drivers/net/wireless/quantenna/qtnfmac/cfg80211.c
|
||||
@@ -837,7 +837,7 @@ static int qtnf_channel_switch(struct wi
|
||||
static int qtnf_start_radar_detection(struct wiphy *wiphy,
|
||||
struct net_device *ndev,
|
||||
struct cfg80211_chan_def *chandef,
|
||||
- u32 cac_time_ms)
|
||||
+ u32 cac_time_ms, int link_id)
|
||||
{
|
||||
struct qtnf_vif *vif = qtnf_netdev_get_priv(ndev);
|
||||
int ret;
|
||||
--- a/drivers/net/wireless/quantenna/qtnfmac/event.c
|
||||
+++ b/drivers/net/wireless/quantenna/qtnfmac/event.c
|
||||
@@ -524,14 +524,14 @@ static int qtnf_event_handle_radar(struc
|
||||
break;
|
||||
|
||||
cfg80211_cac_event(vif->netdev, &chandef,
|
||||
- NL80211_RADAR_CAC_FINISHED, GFP_KERNEL);
|
||||
+ NL80211_RADAR_CAC_FINISHED, GFP_KERNEL, 0);
|
||||
break;
|
||||
case QLINK_RADAR_CAC_ABORTED:
|
||||
if (!vif->wdev.links[0].cac_started)
|
||||
break;
|
||||
|
||||
cfg80211_cac_event(vif->netdev, &chandef,
|
||||
- NL80211_RADAR_CAC_ABORTED, GFP_KERNEL);
|
||||
+ NL80211_RADAR_CAC_ABORTED, GFP_KERNEL, 0);
|
||||
break;
|
||||
case QLINK_RADAR_CAC_STARTED:
|
||||
if (vif->wdev.links[0].cac_started)
|
||||
@@ -542,7 +542,7 @@ static int qtnf_event_handle_radar(struc
|
||||
break;
|
||||
|
||||
cfg80211_cac_event(vif->netdev, &chandef,
|
||||
- NL80211_RADAR_CAC_STARTED, GFP_KERNEL);
|
||||
+ NL80211_RADAR_CAC_STARTED, GFP_KERNEL, 0);
|
||||
break;
|
||||
default:
|
||||
pr_warn("%s: unhandled radar event %u\n",
|
||||
--- a/include/net/cfg80211.h
|
||||
+++ b/include/net/cfg80211.h
|
||||
@@ -4841,9 +4841,9 @@ struct cfg80211_ops {
|
||||
int (*start_radar_detection)(struct wiphy *wiphy,
|
||||
struct net_device *dev,
|
||||
struct cfg80211_chan_def *chandef,
|
||||
- u32 cac_time_ms);
|
||||
+ u32 cac_time_ms, int link_id);
|
||||
void (*end_cac)(struct wiphy *wiphy,
|
||||
- struct net_device *dev);
|
||||
+ struct net_device *dev, unsigned int link_id);
|
||||
int (*update_ft_ies)(struct wiphy *wiphy, struct net_device *dev,
|
||||
struct cfg80211_update_ft_ies_params *ftie);
|
||||
int (*crit_proto_start)(struct wiphy *wiphy,
|
||||
@@ -8745,6 +8745,7 @@ void cfg80211_sta_opmode_change_notify(s
|
||||
* @chandef: chandef for the current channel
|
||||
* @event: type of event
|
||||
* @gfp: context flags
|
||||
+ * @link_id: valid link_id for MLO operation or 0 otherwise.
|
||||
*
|
||||
* This function is called when a Channel availability check (CAC) is finished
|
||||
* or aborted. This must be called to notify the completion of a CAC process,
|
||||
@@ -8752,7 +8753,8 @@ void cfg80211_sta_opmode_change_notify(s
|
||||
*/
|
||||
void cfg80211_cac_event(struct net_device *netdev,
|
||||
const struct cfg80211_chan_def *chandef,
|
||||
- enum nl80211_radar_event event, gfp_t gfp);
|
||||
+ enum nl80211_radar_event event, gfp_t gfp,
|
||||
+ unsigned int link_id);
|
||||
|
||||
/**
|
||||
* cfg80211_background_cac_abort - Channel Availability Check offchan abort event
|
||||
--- a/net/mac80211/cfg.c
|
||||
+++ b/net/mac80211/cfg.c
|
||||
@@ -1661,7 +1661,7 @@ static int ieee80211_stop_ap(struct wiph
|
||||
wiphy_delayed_work_cancel(wiphy, &link->dfs_cac_timer_work);
|
||||
cfg80211_cac_event(sdata->dev, &chandef,
|
||||
NL80211_RADAR_CAC_ABORTED,
|
||||
- GFP_KERNEL);
|
||||
+ GFP_KERNEL, 0);
|
||||
}
|
||||
|
||||
drv_stop_ap(sdata->local, sdata, link_conf);
|
||||
@@ -3459,7 +3459,7 @@ static int ieee80211_set_bitrate_mask(st
|
||||
static int ieee80211_start_radar_detection(struct wiphy *wiphy,
|
||||
struct net_device *dev,
|
||||
struct cfg80211_chan_def *chandef,
|
||||
- u32 cac_time_ms)
|
||||
+ u32 cac_time_ms, int link_id)
|
||||
{
|
||||
struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
|
||||
struct ieee80211_chan_req chanreq = { .oper = *chandef };
|
||||
@@ -3487,7 +3487,7 @@ static int ieee80211_start_radar_detecti
|
||||
}
|
||||
|
||||
static void ieee80211_end_cac(struct wiphy *wiphy,
|
||||
- struct net_device *dev)
|
||||
+ struct net_device *dev, unsigned int link_id)
|
||||
{
|
||||
struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
|
||||
struct ieee80211_local *local = sdata->local;
|
||||
--- a/net/mac80211/iface.c
|
||||
+++ b/net/mac80211/iface.c
|
||||
@@ -559,7 +559,7 @@ static void ieee80211_do_stop(struct iee
|
||||
ieee80211_link_release_channel(&sdata->deflink);
|
||||
cfg80211_cac_event(sdata->dev, &chandef,
|
||||
NL80211_RADAR_CAC_ABORTED,
|
||||
- GFP_KERNEL);
|
||||
+ GFP_KERNEL, 0);
|
||||
}
|
||||
|
||||
if (sdata->vif.type == NL80211_IFTYPE_AP) {
|
||||
--- a/net/mac80211/mlme.c
|
||||
+++ b/net/mac80211/mlme.c
|
||||
@@ -3043,7 +3043,7 @@ void ieee80211_dfs_cac_timer_work(struct
|
||||
ieee80211_link_release_channel(link);
|
||||
cfg80211_cac_event(sdata->dev, &chandef,
|
||||
NL80211_RADAR_CAC_FINISHED,
|
||||
- GFP_KERNEL);
|
||||
+ GFP_KERNEL, 0);
|
||||
}
|
||||
}
|
||||
|
||||
--- a/net/mac80211/util.c
|
||||
+++ b/net/mac80211/util.c
|
||||
@@ -3468,7 +3468,7 @@ void ieee80211_dfs_cac_cancel(struct iee
|
||||
cfg80211_cac_event(sdata->dev,
|
||||
&chandef,
|
||||
NL80211_RADAR_CAC_ABORTED,
|
||||
- GFP_KERNEL);
|
||||
+ GFP_KERNEL, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
--- a/net/wireless/mlme.c
|
||||
+++ b/net/wireless/mlme.c
|
||||
@@ -1111,18 +1111,19 @@ EXPORT_SYMBOL(__cfg80211_radar_event);
|
||||
|
||||
void cfg80211_cac_event(struct net_device *netdev,
|
||||
const struct cfg80211_chan_def *chandef,
|
||||
- enum nl80211_radar_event event, gfp_t gfp)
|
||||
+ enum nl80211_radar_event event, gfp_t gfp,
|
||||
+ unsigned int link_id)
|
||||
{
|
||||
struct wireless_dev *wdev = netdev->ieee80211_ptr;
|
||||
struct wiphy *wiphy = wdev->wiphy;
|
||||
struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
|
||||
unsigned long timeout;
|
||||
|
||||
- /* not yet supported */
|
||||
- if (wdev->valid_links)
|
||||
+ if (WARN_ON(wdev->valid_links &&
|
||||
+ !(wdev->valid_links & BIT(link_id))))
|
||||
return;
|
||||
|
||||
- trace_cfg80211_cac_event(netdev, event);
|
||||
+ trace_cfg80211_cac_event(netdev, event, link_id);
|
||||
|
||||
if (WARN_ON(!wdev->links[0].cac_started &&
|
||||
event != NL80211_RADAR_CAC_STARTED))
|
||||
--- a/net/wireless/nl80211.c
|
||||
+++ b/net/wireless/nl80211.c
|
||||
@@ -10122,7 +10122,20 @@ static int nl80211_start_radar_detection
|
||||
goto unlock;
|
||||
}
|
||||
|
||||
- if (cfg80211_beaconing_iface_active(wdev) || wdev->links[0].cac_started) {
|
||||
+ if (cfg80211_beaconing_iface_active(wdev)) {
|
||||
+ /* During MLO other link(s) can beacon, only the current link
|
||||
+ * can not already beacon
|
||||
+ */
|
||||
+ if (wdev->valid_links &&
|
||||
+ !wdev->links[0].ap.beacon_interval) {
|
||||
+ /* nothing */
|
||||
+ } else {
|
||||
+ err = -EBUSY;
|
||||
+ goto unlock;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ if (wdev->links[0].cac_started) {
|
||||
err = -EBUSY;
|
||||
goto unlock;
|
||||
}
|
||||
@@ -10142,7 +10155,8 @@ static int nl80211_start_radar_detection
|
||||
if (WARN_ON(!cac_time_ms))
|
||||
cac_time_ms = IEEE80211_DFS_MIN_CAC_TIME_MS;
|
||||
|
||||
- err = rdev_start_radar_detection(rdev, dev, &chandef, cac_time_ms);
|
||||
+ err = rdev_start_radar_detection(rdev, dev, &chandef, cac_time_ms,
|
||||
+ 0);
|
||||
if (!err) {
|
||||
switch (wdev->iftype) {
|
||||
case NL80211_IFTYPE_AP:
|
||||
@@ -16512,10 +16526,10 @@ nl80211_set_ttlm(struct sk_buff *skb, st
|
||||
SELECTOR(__sel, NETDEV_UP_NOTMX, \
|
||||
NL80211_FLAG_NEED_NETDEV_UP | \
|
||||
NL80211_FLAG_NO_WIPHY_MTX) \
|
||||
- SELECTOR(__sel, NETDEV_UP_NOTMX_NOMLO, \
|
||||
+ SELECTOR(__sel, NETDEV_UP_NOTMX_MLO, \
|
||||
NL80211_FLAG_NEED_NETDEV_UP | \
|
||||
NL80211_FLAG_NO_WIPHY_MTX | \
|
||||
- NL80211_FLAG_MLO_UNSUPPORTED) \
|
||||
+ NL80211_FLAG_MLO_VALID_LINK_ID) \
|
||||
SELECTOR(__sel, NETDEV_UP_CLEAR, \
|
||||
NL80211_FLAG_NEED_NETDEV_UP | \
|
||||
NL80211_FLAG_CLEAR_SKB) \
|
||||
@@ -17410,7 +17424,7 @@ static const struct genl_small_ops nl802
|
||||
.flags = GENL_UNS_ADMIN_PERM,
|
||||
.internal_flags = IFLAGS(NL80211_FLAG_NEED_NETDEV_UP |
|
||||
NL80211_FLAG_NO_WIPHY_MTX |
|
||||
- NL80211_FLAG_MLO_UNSUPPORTED),
|
||||
+ NL80211_FLAG_MLO_VALID_LINK_ID),
|
||||
},
|
||||
{
|
||||
.cmd = NL80211_CMD_GET_PROTOCOL_FEATURES,
|
||||
--- a/net/wireless/rdev-ops.h
|
||||
+++ b/net/wireless/rdev-ops.h
|
||||
@@ -1200,26 +1200,27 @@ static inline int
|
||||
rdev_start_radar_detection(struct cfg80211_registered_device *rdev,
|
||||
struct net_device *dev,
|
||||
struct cfg80211_chan_def *chandef,
|
||||
- u32 cac_time_ms)
|
||||
+ u32 cac_time_ms, int link_id)
|
||||
{
|
||||
int ret = -EOPNOTSUPP;
|
||||
|
||||
trace_rdev_start_radar_detection(&rdev->wiphy, dev, chandef,
|
||||
- cac_time_ms);
|
||||
+ cac_time_ms, link_id);
|
||||
if (rdev->ops->start_radar_detection)
|
||||
ret = rdev->ops->start_radar_detection(&rdev->wiphy, dev,
|
||||
- chandef, cac_time_ms);
|
||||
+ chandef, cac_time_ms,
|
||||
+ link_id);
|
||||
trace_rdev_return_int(&rdev->wiphy, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static inline void
|
||||
rdev_end_cac(struct cfg80211_registered_device *rdev,
|
||||
- struct net_device *dev)
|
||||
+ struct net_device *dev, unsigned int link_id)
|
||||
{
|
||||
- trace_rdev_end_cac(&rdev->wiphy, dev);
|
||||
+ trace_rdev_end_cac(&rdev->wiphy, dev, link_id);
|
||||
if (rdev->ops->end_cac)
|
||||
- rdev->ops->end_cac(&rdev->wiphy, dev);
|
||||
+ rdev->ops->end_cac(&rdev->wiphy, dev, link_id);
|
||||
trace_rdev_return_void(&rdev->wiphy);
|
||||
}
|
||||
|
||||
--- a/net/wireless/reg.c
|
||||
+++ b/net/wireless/reg.c
|
||||
@@ -4229,6 +4229,8 @@ EXPORT_SYMBOL(regulatory_pre_cac_allowed
|
||||
static void cfg80211_check_and_end_cac(struct cfg80211_registered_device *rdev)
|
||||
{
|
||||
struct wireless_dev *wdev;
|
||||
+ unsigned int link_id;
|
||||
+
|
||||
/* If we finished CAC or received radar, we should end any
|
||||
* CAC running on the same channels.
|
||||
* the check !cfg80211_chandef_dfs_usable contain 2 options:
|
||||
@@ -4241,16 +4243,17 @@ static void cfg80211_check_and_end_cac(s
|
||||
list_for_each_entry(wdev, &rdev->wiphy.wdev_list, list) {
|
||||
struct cfg80211_chan_def *chandef;
|
||||
|
||||
- if (!wdev->links[0].cac_started)
|
||||
- continue;
|
||||
+ for_each_valid_link(wdev, link_id) {
|
||||
+ if (!wdev->links[link_id].cac_started)
|
||||
+ continue;
|
||||
|
||||
- /* FIXME: radar detection is tied to link 0 for now */
|
||||
- chandef = wdev_chandef(wdev, 0);
|
||||
- if (!chandef)
|
||||
- continue;
|
||||
+ chandef = wdev_chandef(wdev, link_id);
|
||||
+ if (!chandef)
|
||||
+ continue;
|
||||
|
||||
- if (!cfg80211_chandef_dfs_usable(&rdev->wiphy, chandef))
|
||||
- rdev_end_cac(rdev, wdev->netdev);
|
||||
+ if (!cfg80211_chandef_dfs_usable(&rdev->wiphy, chandef))
|
||||
+ rdev_end_cac(rdev, wdev->netdev, link_id);
|
||||
+ }
|
||||
}
|
||||
}
|
||||
|
||||
--- a/net/wireless/trace.h
|
||||
+++ b/net/wireless/trace.h
|
||||
@@ -806,17 +806,21 @@ DEFINE_EVENT(wiphy_netdev_evt, rdev_flus
|
||||
);
|
||||
|
||||
TRACE_EVENT(rdev_end_cac,
|
||||
- TP_PROTO(struct wiphy *wiphy, struct net_device *netdev),
|
||||
- TP_ARGS(wiphy, netdev),
|
||||
+ TP_PROTO(struct wiphy *wiphy, struct net_device *netdev,
|
||||
+ unsigned int link_id),
|
||||
+ TP_ARGS(wiphy, netdev, link_id),
|
||||
TP_STRUCT__entry(
|
||||
WIPHY_ENTRY
|
||||
NETDEV_ENTRY
|
||||
+ __field(unsigned int, link_id)
|
||||
),
|
||||
TP_fast_assign(
|
||||
WIPHY_ASSIGN;
|
||||
NETDEV_ASSIGN;
|
||||
+ __entry->link_id = link_id;
|
||||
),
|
||||
- TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT, WIPHY_PR_ARG, NETDEV_PR_ARG)
|
||||
+ TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT ", link_id: %d",
|
||||
+ WIPHY_PR_ARG, NETDEV_PR_ARG, __entry->link_id)
|
||||
);
|
||||
|
||||
DECLARE_EVENT_CLASS(station_add_change,
|
||||
@@ -2661,24 +2665,26 @@ TRACE_EVENT(rdev_external_auth,
|
||||
TRACE_EVENT(rdev_start_radar_detection,
|
||||
TP_PROTO(struct wiphy *wiphy, struct net_device *netdev,
|
||||
struct cfg80211_chan_def *chandef,
|
||||
- u32 cac_time_ms),
|
||||
- TP_ARGS(wiphy, netdev, chandef, cac_time_ms),
|
||||
+ u32 cac_time_ms, int link_id),
|
||||
+ TP_ARGS(wiphy, netdev, chandef, cac_time_ms, link_id),
|
||||
TP_STRUCT__entry(
|
||||
WIPHY_ENTRY
|
||||
NETDEV_ENTRY
|
||||
CHAN_DEF_ENTRY
|
||||
__field(u32, cac_time_ms)
|
||||
+ __field(int, link_id)
|
||||
),
|
||||
TP_fast_assign(
|
||||
WIPHY_ASSIGN;
|
||||
NETDEV_ASSIGN;
|
||||
CHAN_DEF_ASSIGN(chandef);
|
||||
__entry->cac_time_ms = cac_time_ms;
|
||||
+ __entry->link_id = link_id;
|
||||
),
|
||||
TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT ", " CHAN_DEF_PR_FMT
|
||||
- ", cac_time_ms=%u",
|
||||
+ ", cac_time_ms=%u, link_id=%d",
|
||||
WIPHY_PR_ARG, NETDEV_PR_ARG, CHAN_DEF_PR_ARG,
|
||||
- __entry->cac_time_ms)
|
||||
+ __entry->cac_time_ms, __entry->link_id)
|
||||
);
|
||||
|
||||
TRACE_EVENT(rdev_set_mcast_rate,
|
||||
@@ -3492,18 +3498,21 @@ TRACE_EVENT(cfg80211_radar_event,
|
||||
);
|
||||
|
||||
TRACE_EVENT(cfg80211_cac_event,
|
||||
- TP_PROTO(struct net_device *netdev, enum nl80211_radar_event evt),
|
||||
- TP_ARGS(netdev, evt),
|
||||
+ TP_PROTO(struct net_device *netdev, enum nl80211_radar_event evt,
|
||||
+ unsigned int link_id),
|
||||
+ TP_ARGS(netdev, evt, link_id),
|
||||
TP_STRUCT__entry(
|
||||
NETDEV_ENTRY
|
||||
__field(enum nl80211_radar_event, evt)
|
||||
+ __field(unsigned int, link_id)
|
||||
),
|
||||
TP_fast_assign(
|
||||
NETDEV_ASSIGN;
|
||||
__entry->evt = evt;
|
||||
+ __entry->link_id = link_id;
|
||||
),
|
||||
- TP_printk(NETDEV_PR_FMT ", event: %d",
|
||||
- NETDEV_PR_ARG, __entry->evt)
|
||||
+ TP_printk(NETDEV_PR_FMT ", event: %d, link_id=%u",
|
||||
+ NETDEV_PR_ARG, __entry->evt, __entry->link_id)
|
||||
);
|
||||
|
||||
DECLARE_EVENT_CLASS(cfg80211_rx_evt,
|
@ -11,7 +11,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||
|
||||
--- a/net/mac80211/ieee80211_i.h
|
||||
+++ b/net/mac80211/ieee80211_i.h
|
||||
@@ -1374,7 +1374,7 @@ struct ieee80211_local {
|
||||
@@ -1373,7 +1373,7 @@ struct ieee80211_local {
|
||||
spinlock_t queue_stop_reason_lock;
|
||||
|
||||
int open_count;
|
@ -1,134 +0,0 @@
|
||||
From: Aditya Kumar Singh <quic_adisi@quicinc.com>
|
||||
Date: Fri, 6 Sep 2024 12:14:24 +0530
|
||||
Subject: [PATCH] wifi: mac80211: handle DFS per link
|
||||
|
||||
In order to support DFS with MLO, handle the link ID now passed from
|
||||
cfg80211, adjust the code to do everything per link and call the
|
||||
notifications to cfg80211 correctly.
|
||||
|
||||
Signed-off-by: Aditya Kumar Singh <quic_adisi@quicinc.com>
|
||||
Link: https://patch.msgid.link/20240906064426.2101315-7-quic_adisi@quicinc.com
|
||||
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
|
||||
---
|
||||
|
||||
--- a/net/mac80211/cfg.c
|
||||
+++ b/net/mac80211/cfg.c
|
||||
@@ -3464,6 +3464,7 @@ static int ieee80211_start_radar_detecti
|
||||
struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
|
||||
struct ieee80211_chan_req chanreq = { .oper = *chandef };
|
||||
struct ieee80211_local *local = sdata->local;
|
||||
+ struct ieee80211_link_data *link_data;
|
||||
int err;
|
||||
|
||||
lockdep_assert_wiphy(local->hw.wiphy);
|
||||
@@ -3471,16 +3472,20 @@ static int ieee80211_start_radar_detecti
|
||||
if (!list_empty(&local->roc_list) || local->scanning)
|
||||
return -EBUSY;
|
||||
|
||||
+ link_data = sdata_dereference(sdata->link[link_id], sdata);
|
||||
+ if (!link_data)
|
||||
+ return -ENOLINK;
|
||||
+
|
||||
/* whatever, but channel contexts should not complain about that one */
|
||||
- sdata->deflink.smps_mode = IEEE80211_SMPS_OFF;
|
||||
- sdata->deflink.needed_rx_chains = local->rx_chains;
|
||||
+ link_data->smps_mode = IEEE80211_SMPS_OFF;
|
||||
+ link_data->needed_rx_chains = local->rx_chains;
|
||||
|
||||
- err = ieee80211_link_use_channel(&sdata->deflink, &chanreq,
|
||||
+ err = ieee80211_link_use_channel(link_data, &chanreq,
|
||||
IEEE80211_CHANCTX_SHARED);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
- wiphy_delayed_work_queue(wiphy, &sdata->deflink.dfs_cac_timer_work,
|
||||
+ wiphy_delayed_work_queue(wiphy, &link_data->dfs_cac_timer_work,
|
||||
msecs_to_jiffies(cac_time_ms));
|
||||
|
||||
return 0;
|
||||
@@ -3491,16 +3496,21 @@ static void ieee80211_end_cac(struct wip
|
||||
{
|
||||
struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
|
||||
struct ieee80211_local *local = sdata->local;
|
||||
+ struct ieee80211_link_data *link_data;
|
||||
|
||||
lockdep_assert_wiphy(local->hw.wiphy);
|
||||
|
||||
list_for_each_entry(sdata, &local->interfaces, list) {
|
||||
+ link_data = sdata_dereference(sdata->link[link_id], sdata);
|
||||
+ if (!link_data)
|
||||
+ continue;
|
||||
+
|
||||
wiphy_delayed_work_cancel(wiphy,
|
||||
- &sdata->deflink.dfs_cac_timer_work);
|
||||
+ &link_data->dfs_cac_timer_work);
|
||||
|
||||
- if (sdata->wdev.links[0].cac_started) {
|
||||
- ieee80211_link_release_channel(&sdata->deflink);
|
||||
- sdata->wdev.links[0].cac_started = false;
|
||||
+ if (sdata->wdev.links[link_id].cac_started) {
|
||||
+ ieee80211_link_release_channel(link_data);
|
||||
+ sdata->wdev.links[link_id].cac_started = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
--- a/net/mac80211/link.c
|
||||
+++ b/net/mac80211/link.c
|
||||
@@ -77,6 +77,16 @@ void ieee80211_link_stop(struct ieee8021
|
||||
&link->color_change_finalize_work);
|
||||
wiphy_work_cancel(link->sdata->local->hw.wiphy,
|
||||
&link->csa.finalize_work);
|
||||
+
|
||||
+ if (link->sdata->wdev.links[link->link_id].cac_started) {
|
||||
+ wiphy_delayed_work_cancel(link->sdata->local->hw.wiphy,
|
||||
+ &link->dfs_cac_timer_work);
|
||||
+ cfg80211_cac_event(link->sdata->dev,
|
||||
+ &link->conf->chanreq.oper,
|
||||
+ NL80211_RADAR_CAC_ABORTED,
|
||||
+ GFP_KERNEL, link->link_id);
|
||||
+ }
|
||||
+
|
||||
ieee80211_link_release_channel(link);
|
||||
}
|
||||
|
||||
--- a/net/mac80211/util.c
|
||||
+++ b/net/mac80211/util.c
|
||||
@@ -3455,20 +3455,30 @@ void ieee80211_dfs_cac_cancel(struct iee
|
||||
{
|
||||
struct ieee80211_sub_if_data *sdata;
|
||||
struct cfg80211_chan_def chandef;
|
||||
+ struct ieee80211_link_data *link;
|
||||
+ unsigned int link_id;
|
||||
|
||||
lockdep_assert_wiphy(local->hw.wiphy);
|
||||
|
||||
list_for_each_entry(sdata, &local->interfaces, list) {
|
||||
- wiphy_delayed_work_cancel(local->hw.wiphy,
|
||||
- &sdata->deflink.dfs_cac_timer_work);
|
||||
+ for (link_id = 0; link_id < IEEE80211_MLD_MAX_NUM_LINKS;
|
||||
+ link_id++) {
|
||||
+ link = sdata_dereference(sdata->link[link_id],
|
||||
+ sdata);
|
||||
+ if (!link)
|
||||
+ continue;
|
||||
|
||||
- if (sdata->wdev.links[0].cac_started) {
|
||||
- chandef = sdata->vif.bss_conf.chanreq.oper;
|
||||
- ieee80211_link_release_channel(&sdata->deflink);
|
||||
- cfg80211_cac_event(sdata->dev,
|
||||
- &chandef,
|
||||
+ wiphy_delayed_work_cancel(local->hw.wiphy,
|
||||
+ &link->dfs_cac_timer_work);
|
||||
+
|
||||
+ if (!sdata->wdev.links[link_id].cac_started)
|
||||
+ continue;
|
||||
+
|
||||
+ chandef = link->conf->chanreq.oper;
|
||||
+ ieee80211_link_release_channel(link);
|
||||
+ cfg80211_cac_event(sdata->dev, &chandef,
|
||||
NL80211_RADAR_CAC_ABORTED,
|
||||
- GFP_KERNEL, 0);
|
||||
+ GFP_KERNEL, link_id);
|
||||
}
|
||||
}
|
||||
}
|
@ -1,168 +0,0 @@
|
||||
From: Aditya Kumar Singh <quic_adisi@quicinc.com>
|
||||
Date: Fri, 6 Sep 2024 12:14:25 +0530
|
||||
Subject: [PATCH] wifi: cfg80211/mac80211: use proper link ID for DFS
|
||||
|
||||
Now that all APIs have support to handle DFS per link, use proper link ID
|
||||
instead of 0.
|
||||
|
||||
Signed-off-by: Aditya Kumar Singh <quic_adisi@quicinc.com>
|
||||
Link: https://patch.msgid.link/20240906064426.2101315-8-quic_adisi@quicinc.com
|
||||
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
|
||||
---
|
||||
|
||||
--- a/net/mac80211/cfg.c
|
||||
+++ b/net/mac80211/cfg.c
|
||||
@@ -1656,12 +1656,12 @@ static int ieee80211_stop_ap(struct wiph
|
||||
ieee80211_link_info_change_notify(sdata, link,
|
||||
BSS_CHANGED_BEACON_ENABLED);
|
||||
|
||||
- if (sdata->wdev.links[0].cac_started) {
|
||||
+ if (sdata->wdev.links[link_id].cac_started) {
|
||||
chandef = link_conf->chanreq.oper;
|
||||
wiphy_delayed_work_cancel(wiphy, &link->dfs_cac_timer_work);
|
||||
cfg80211_cac_event(sdata->dev, &chandef,
|
||||
NL80211_RADAR_CAC_ABORTED,
|
||||
- GFP_KERNEL, 0);
|
||||
+ GFP_KERNEL, link_id);
|
||||
}
|
||||
|
||||
drv_stop_ap(sdata->local, sdata, link_conf);
|
||||
@@ -3965,7 +3965,7 @@ __ieee80211_channel_switch(struct wiphy
|
||||
if (!list_empty(&local->roc_list) || local->scanning)
|
||||
return -EBUSY;
|
||||
|
||||
- if (sdata->wdev.links[0].cac_started)
|
||||
+ if (sdata->wdev.links[link_id].cac_started)
|
||||
return -EBUSY;
|
||||
|
||||
if (WARN_ON(link_id >= IEEE80211_MLD_MAX_NUM_LINKS))
|
||||
--- a/net/mac80211/mlme.c
|
||||
+++ b/net/mac80211/mlme.c
|
||||
@@ -3039,11 +3039,11 @@ void ieee80211_dfs_cac_timer_work(struct
|
||||
|
||||
lockdep_assert_wiphy(sdata->local->hw.wiphy);
|
||||
|
||||
- if (sdata->wdev.links[0].cac_started) {
|
||||
+ if (sdata->wdev.links[link->link_id].cac_started) {
|
||||
ieee80211_link_release_channel(link);
|
||||
cfg80211_cac_event(sdata->dev, &chandef,
|
||||
NL80211_RADAR_CAC_FINISHED,
|
||||
- GFP_KERNEL, 0);
|
||||
+ GFP_KERNEL, link->link_id);
|
||||
}
|
||||
}
|
||||
|
||||
--- a/net/mac80211/scan.c
|
||||
+++ b/net/mac80211/scan.c
|
||||
@@ -575,6 +575,7 @@ static bool __ieee80211_can_leave_ch(str
|
||||
{
|
||||
struct ieee80211_local *local = sdata->local;
|
||||
struct ieee80211_sub_if_data *sdata_iter;
|
||||
+ unsigned int link_id;
|
||||
|
||||
lockdep_assert_wiphy(local->hw.wiphy);
|
||||
|
||||
@@ -585,8 +586,9 @@ static bool __ieee80211_can_leave_ch(str
|
||||
return false;
|
||||
|
||||
list_for_each_entry(sdata_iter, &local->interfaces, list) {
|
||||
- if (sdata_iter->wdev.links[0].cac_started)
|
||||
- return false;
|
||||
+ for_each_valid_link(&sdata_iter->wdev, link_id)
|
||||
+ if (sdata_iter->wdev.links[link_id].cac_started)
|
||||
+ return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
--- a/net/wireless/mlme.c
|
||||
+++ b/net/wireless/mlme.c
|
||||
@@ -1125,14 +1125,14 @@ void cfg80211_cac_event(struct net_devic
|
||||
|
||||
trace_cfg80211_cac_event(netdev, event, link_id);
|
||||
|
||||
- if (WARN_ON(!wdev->links[0].cac_started &&
|
||||
+ if (WARN_ON(!wdev->links[link_id].cac_started &&
|
||||
event != NL80211_RADAR_CAC_STARTED))
|
||||
return;
|
||||
|
||||
switch (event) {
|
||||
case NL80211_RADAR_CAC_FINISHED:
|
||||
- timeout = wdev->links[0].cac_start_time +
|
||||
- msecs_to_jiffies(wdev->links[0].cac_time_ms);
|
||||
+ timeout = wdev->links[link_id].cac_start_time +
|
||||
+ msecs_to_jiffies(wdev->links[link_id].cac_time_ms);
|
||||
WARN_ON(!time_after_eq(jiffies, timeout));
|
||||
cfg80211_set_dfs_state(wiphy, chandef, NL80211_DFS_AVAILABLE);
|
||||
memcpy(&rdev->cac_done_chandef, chandef,
|
||||
@@ -1141,10 +1141,10 @@ void cfg80211_cac_event(struct net_devic
|
||||
cfg80211_sched_dfs_chan_update(rdev);
|
||||
fallthrough;
|
||||
case NL80211_RADAR_CAC_ABORTED:
|
||||
- wdev->links[0].cac_started = false;
|
||||
+ wdev->links[link_id].cac_started = false;
|
||||
break;
|
||||
case NL80211_RADAR_CAC_STARTED:
|
||||
- wdev->links[0].cac_started = true;
|
||||
+ wdev->links[link_id].cac_started = true;
|
||||
break;
|
||||
default:
|
||||
WARN_ON(1);
|
||||
--- a/net/wireless/nl80211.c
|
||||
+++ b/net/wireless/nl80211.c
|
||||
@@ -6066,7 +6066,7 @@ static int nl80211_start_ap(struct sk_bu
|
||||
if (!rdev->ops->start_ap)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
- if (wdev->links[0].cac_started)
|
||||
+ if (wdev->links[link_id].cac_started)
|
||||
return -EBUSY;
|
||||
|
||||
if (wdev->links[link_id].ap.beacon_interval)
|
||||
@@ -10073,6 +10073,7 @@ static int nl80211_start_radar_detection
|
||||
struct cfg80211_registered_device *rdev = info->user_ptr[0];
|
||||
struct net_device *dev = info->user_ptr[1];
|
||||
struct wireless_dev *wdev = dev->ieee80211_ptr;
|
||||
+ int link_id = nl80211_link_id(info->attrs);
|
||||
struct wiphy *wiphy = wdev->wiphy;
|
||||
struct cfg80211_chan_def chandef;
|
||||
enum nl80211_dfs_regions dfs_region;
|
||||
@@ -10127,7 +10128,7 @@ static int nl80211_start_radar_detection
|
||||
* can not already beacon
|
||||
*/
|
||||
if (wdev->valid_links &&
|
||||
- !wdev->links[0].ap.beacon_interval) {
|
||||
+ !wdev->links[link_id].ap.beacon_interval) {
|
||||
/* nothing */
|
||||
} else {
|
||||
err = -EBUSY;
|
||||
@@ -10135,7 +10136,7 @@ static int nl80211_start_radar_detection
|
||||
}
|
||||
}
|
||||
|
||||
- if (wdev->links[0].cac_started) {
|
||||
+ if (wdev->links[link_id].cac_started) {
|
||||
err = -EBUSY;
|
||||
goto unlock;
|
||||
}
|
||||
@@ -10156,7 +10157,7 @@ static int nl80211_start_radar_detection
|
||||
cac_time_ms = IEEE80211_DFS_MIN_CAC_TIME_MS;
|
||||
|
||||
err = rdev_start_radar_detection(rdev, dev, &chandef, cac_time_ms,
|
||||
- 0);
|
||||
+ link_id);
|
||||
if (!err) {
|
||||
switch (wdev->iftype) {
|
||||
case NL80211_IFTYPE_AP:
|
||||
@@ -10172,9 +10173,9 @@ static int nl80211_start_radar_detection
|
||||
default:
|
||||
break;
|
||||
}
|
||||
- wdev->links[0].cac_started = true;
|
||||
- wdev->links[0].cac_start_time = jiffies;
|
||||
- wdev->links[0].cac_time_ms = cac_time_ms;
|
||||
+ wdev->links[link_id].cac_started = true;
|
||||
+ wdev->links[link_id].cac_start_time = jiffies;
|
||||
+ wdev->links[link_id].cac_time_ms = cac_time_ms;
|
||||
}
|
||||
unlock:
|
||||
wiphy_unlock(wiphy);
|
@ -1,360 +0,0 @@
|
||||
From: Aditya Kumar Singh <quic_adisi@quicinc.com>
|
||||
Date: Fri, 6 Sep 2024 12:14:26 +0530
|
||||
Subject: [PATCH] wifi: mac80211: handle ieee80211_radar_detected() for MLO
|
||||
|
||||
Currently DFS works under assumption there could be only one channel
|
||||
context in the hardware. Hence, drivers just calls the function
|
||||
ieee80211_radar_detected() passing the hardware structure. However, with
|
||||
MLO, this obviously will not work since number of channel contexts will be
|
||||
more than one and hence drivers would need to pass the channel information
|
||||
as well on which the radar is detected.
|
||||
|
||||
Also, when radar is detected in one of the links, other link's CAC should
|
||||
not be cancelled.
|
||||
|
||||
Hence, in order to support DFS with MLO, do the following changes -
|
||||
* Add channel context conf pointer as an argument to the function
|
||||
ieee80211_radar_detected(). During MLO, drivers would have to pass on
|
||||
which channel context conf radar is detected. Otherwise, drivers could
|
||||
just pass NULL.
|
||||
* ieee80211_radar_detected() will iterate over all channel contexts
|
||||
present and
|
||||
* if channel context conf is passed, only mark that as radar
|
||||
detected
|
||||
* if NULL is passed, then mark all channel contexts as radar
|
||||
detected
|
||||
* Then as usual, schedule the radar detected work.
|
||||
* In the worker, go over all the contexts again and for all such context
|
||||
which is marked with radar detected, cancel the ongoing CAC by calling
|
||||
ieee80211_dfs_cac_cancel() and then notify cfg80211 via
|
||||
cfg80211_radar_event().
|
||||
* To cancel the CAC, pass the channel context as well where radar is
|
||||
detected to ieee80211_dfs_cac_cancel(). This ensures that CAC is
|
||||
canceled only on the links using the provided context, leaving other
|
||||
links unaffected.
|
||||
|
||||
This would also help in scenarios where there is split phy 5 GHz radio,
|
||||
which is capable of DFS channels in both lower and upper band. In this
|
||||
case, simultaneous radars can be detected.
|
||||
|
||||
Signed-off-by: Aditya Kumar Singh <quic_adisi@quicinc.com>
|
||||
Link: https://patch.msgid.link/20240906064426.2101315-9-quic_adisi@quicinc.com
|
||||
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
|
||||
---
|
||||
|
||||
--- a/drivers/net/wireless/ath/ath10k/debug.c
|
||||
+++ b/drivers/net/wireless/ath/ath10k/debug.c
|
||||
@@ -3,7 +3,7 @@
|
||||
* Copyright (c) 2005-2011 Atheros Communications Inc.
|
||||
* Copyright (c) 2011-2017 Qualcomm Atheros, Inc.
|
||||
* Copyright (c) 2018, The Linux Foundation. All rights reserved.
|
||||
- * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
+ * Copyright (c) 2022, 2024 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
@@ -1774,7 +1774,7 @@ static ssize_t ath10k_write_simulate_rad
|
||||
if (!arvif->is_started)
|
||||
return -EINVAL;
|
||||
|
||||
- ieee80211_radar_detected(ar->hw);
|
||||
+ ieee80211_radar_detected(ar->hw, NULL);
|
||||
|
||||
return count;
|
||||
}
|
||||
--- a/drivers/net/wireless/ath/ath10k/mac.c
|
||||
+++ b/drivers/net/wireless/ath/ath10k/mac.c
|
||||
@@ -1437,7 +1437,7 @@ static void ath10k_recalc_radar_detectio
|
||||
* by indicating that radar was detected.
|
||||
*/
|
||||
ath10k_warn(ar, "failed to start CAC: %d\n", ret);
|
||||
- ieee80211_radar_detected(ar->hw);
|
||||
+ ieee80211_radar_detected(ar->hw, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
--- a/drivers/net/wireless/ath/ath10k/wmi.c
|
||||
+++ b/drivers/net/wireless/ath/ath10k/wmi.c
|
||||
@@ -3990,7 +3990,7 @@ static void ath10k_radar_detected(struct
|
||||
if (ar->dfs_block_radar_events)
|
||||
ath10k_info(ar, "DFS Radar detected, but ignored as requested\n");
|
||||
else
|
||||
- ieee80211_radar_detected(ar->hw);
|
||||
+ ieee80211_radar_detected(ar->hw, NULL);
|
||||
}
|
||||
|
||||
static void ath10k_radar_confirmation_work(struct work_struct *work)
|
||||
--- a/drivers/net/wireless/ath/ath11k/wmi.c
|
||||
+++ b/drivers/net/wireless/ath/ath11k/wmi.c
|
||||
@@ -8358,7 +8358,7 @@ ath11k_wmi_pdev_dfs_radar_detected_event
|
||||
if (ar->dfs_block_radar_events)
|
||||
ath11k_info(ab, "DFS Radar detected, but ignored as requested\n");
|
||||
else
|
||||
- ieee80211_radar_detected(ar->hw);
|
||||
+ ieee80211_radar_detected(ar->hw, NULL);
|
||||
|
||||
exit:
|
||||
rcu_read_unlock();
|
||||
--- a/drivers/net/wireless/ath/ath12k/wmi.c
|
||||
+++ b/drivers/net/wireless/ath/ath12k/wmi.c
|
||||
@@ -6789,7 +6789,7 @@ ath12k_wmi_pdev_dfs_radar_detected_event
|
||||
if (ar->dfs_block_radar_events)
|
||||
ath12k_info(ab, "DFS Radar detected, but ignored as requested\n");
|
||||
else
|
||||
- ieee80211_radar_detected(ath12k_ar_to_hw(ar));
|
||||
+ ieee80211_radar_detected(ath12k_ar_to_hw(ar), NULL);
|
||||
|
||||
exit:
|
||||
rcu_read_unlock();
|
||||
--- a/drivers/net/wireless/ath/ath9k/dfs.c
|
||||
+++ b/drivers/net/wireless/ath/ath9k/dfs.c
|
||||
@@ -280,7 +280,7 @@ ath9k_dfs_process_radar_pulse(struct ath
|
||||
if (!pd->add_pulse(pd, pe, NULL))
|
||||
return;
|
||||
DFS_STAT_INC(sc, radar_detected);
|
||||
- ieee80211_radar_detected(sc->hw);
|
||||
+ ieee80211_radar_detected(sc->hw, NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
--- a/drivers/net/wireless/ath/ath9k/dfs_debug.c
|
||||
+++ b/drivers/net/wireless/ath/ath9k/dfs_debug.c
|
||||
@@ -116,7 +116,7 @@ static ssize_t write_file_simulate_radar
|
||||
{
|
||||
struct ath_softc *sc = file->private_data;
|
||||
|
||||
- ieee80211_radar_detected(sc->hw);
|
||||
+ ieee80211_radar_detected(sc->hw, NULL);
|
||||
|
||||
return count;
|
||||
}
|
||||
--- a/drivers/net/wireless/mediatek/mt76/mt7615/mcu.c
|
||||
+++ b/drivers/net/wireless/mediatek/mt76/mt7615/mcu.c
|
||||
@@ -394,7 +394,7 @@ mt7615_mcu_rx_radar_detected(struct mt76
|
||||
if (mt76_phy_dfs_state(mphy) < MT_DFS_STATE_CAC)
|
||||
return;
|
||||
|
||||
- ieee80211_radar_detected(mphy->hw);
|
||||
+ ieee80211_radar_detected(mphy->hw, NULL);
|
||||
dev->hw_pattern++;
|
||||
}
|
||||
|
||||
--- a/drivers/net/wireless/mediatek/mt76/mt76x02_dfs.c
|
||||
+++ b/drivers/net/wireless/mediatek/mt76/mt76x02_dfs.c
|
||||
@@ -630,7 +630,7 @@ static void mt76x02_dfs_tasklet(struct t
|
||||
radar_detected = mt76x02_dfs_check_detection(dev);
|
||||
if (radar_detected) {
|
||||
/* sw detector rx radar pattern */
|
||||
- ieee80211_radar_detected(dev->mt76.hw);
|
||||
+ ieee80211_radar_detected(dev->mt76.hw, NULL);
|
||||
mt76x02_dfs_detector_reset(dev);
|
||||
|
||||
return;
|
||||
@@ -658,7 +658,7 @@ static void mt76x02_dfs_tasklet(struct t
|
||||
|
||||
/* hw detector rx radar pattern */
|
||||
dfs_pd->stats[i].hw_pattern++;
|
||||
- ieee80211_radar_detected(dev->mt76.hw);
|
||||
+ ieee80211_radar_detected(dev->mt76.hw, NULL);
|
||||
mt76x02_dfs_detector_reset(dev);
|
||||
|
||||
return;
|
||||
--- a/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c
|
||||
+++ b/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c
|
||||
@@ -293,7 +293,7 @@ mt7915_mcu_rx_radar_detected(struct mt79
|
||||
&dev->rdd2_chandef,
|
||||
GFP_ATOMIC);
|
||||
else
|
||||
- ieee80211_radar_detected(mphy->hw);
|
||||
+ ieee80211_radar_detected(mphy->hw, NULL);
|
||||
dev->hw_pattern++;
|
||||
}
|
||||
|
||||
--- a/drivers/net/wireless/mediatek/mt76/mt7996/mcu.c
|
||||
+++ b/drivers/net/wireless/mediatek/mt76/mt7996/mcu.c
|
||||
@@ -371,7 +371,7 @@ mt7996_mcu_rx_radar_detected(struct mt79
|
||||
&dev->rdd2_chandef,
|
||||
GFP_ATOMIC);
|
||||
else
|
||||
- ieee80211_radar_detected(mphy->hw);
|
||||
+ ieee80211_radar_detected(mphy->hw, NULL);
|
||||
dev->hw_pattern++;
|
||||
}
|
||||
|
||||
--- a/drivers/net/wireless/ti/wl18xx/event.c
|
||||
+++ b/drivers/net/wireless/ti/wl18xx/event.c
|
||||
@@ -142,7 +142,7 @@ int wl18xx_process_mailbox_events(struct
|
||||
wl18xx_radar_type_decode(mbox->radar_type));
|
||||
|
||||
if (!wl->radar_debug_mode)
|
||||
- ieee80211_radar_detected(wl->hw);
|
||||
+ ieee80211_radar_detected(wl->hw, NULL);
|
||||
}
|
||||
|
||||
if (vector & PERIODIC_SCAN_REPORT_EVENT_ID) {
|
||||
--- a/drivers/net/wireless/virtual/mac80211_hwsim.c
|
||||
+++ b/drivers/net/wireless/virtual/mac80211_hwsim.c
|
||||
@@ -1146,7 +1146,7 @@ static int hwsim_write_simulate_radar(vo
|
||||
{
|
||||
struct mac80211_hwsim_data *data = dat;
|
||||
|
||||
- ieee80211_radar_detected(data->hw);
|
||||
+ ieee80211_radar_detected(data->hw, NULL);
|
||||
|
||||
return 0;
|
||||
}
|
||||
--- a/include/net/mac80211.h
|
||||
+++ b/include/net/mac80211.h
|
||||
@@ -6717,8 +6717,11 @@ void ieee80211_cqm_beacon_loss_notify(st
|
||||
* ieee80211_radar_detected - inform that a radar was detected
|
||||
*
|
||||
* @hw: pointer as obtained from ieee80211_alloc_hw()
|
||||
+ * @chanctx_conf: Channel context on which radar is detected. Mandatory to
|
||||
+ * pass a valid pointer during MLO. For non-MLO %NULL can be passed
|
||||
*/
|
||||
-void ieee80211_radar_detected(struct ieee80211_hw *hw);
|
||||
+void ieee80211_radar_detected(struct ieee80211_hw *hw,
|
||||
+ struct ieee80211_chanctx_conf *chanctx_conf);
|
||||
|
||||
/**
|
||||
* ieee80211_chswitch_done - Complete channel switch process
|
||||
--- a/net/mac80211/chan.c
|
||||
+++ b/net/mac80211/chan.c
|
||||
@@ -681,6 +681,7 @@ ieee80211_alloc_chanctx(struct ieee80211
|
||||
ctx->mode = mode;
|
||||
ctx->conf.radar_enabled = false;
|
||||
ctx->conf.radio_idx = radio_idx;
|
||||
+ ctx->radar_detected = false;
|
||||
_ieee80211_recalc_chanctx_min_def(local, ctx, NULL, false);
|
||||
|
||||
return ctx;
|
||||
--- a/net/mac80211/ieee80211_i.h
|
||||
+++ b/net/mac80211/ieee80211_i.h
|
||||
@@ -895,6 +895,8 @@ struct ieee80211_chanctx {
|
||||
struct ieee80211_chan_req req;
|
||||
|
||||
struct ieee80211_chanctx_conf conf;
|
||||
+
|
||||
+ bool radar_detected;
|
||||
};
|
||||
|
||||
struct mac80211_qos_map {
|
||||
@@ -2632,7 +2634,8 @@ void ieee80211_recalc_chanctx_min_def(st
|
||||
bool ieee80211_is_radar_required(struct ieee80211_local *local);
|
||||
|
||||
void ieee80211_dfs_cac_timer_work(struct wiphy *wiphy, struct wiphy_work *work);
|
||||
-void ieee80211_dfs_cac_cancel(struct ieee80211_local *local);
|
||||
+void ieee80211_dfs_cac_cancel(struct ieee80211_local *local,
|
||||
+ struct ieee80211_chanctx *chanctx);
|
||||
void ieee80211_dfs_radar_detected_work(struct wiphy *wiphy,
|
||||
struct wiphy_work *work);
|
||||
int ieee80211_send_action_csa(struct ieee80211_sub_if_data *sdata,
|
||||
--- a/net/mac80211/pm.c
|
||||
+++ b/net/mac80211/pm.c
|
||||
@@ -32,7 +32,7 @@ int __ieee80211_suspend(struct ieee80211
|
||||
|
||||
ieee80211_scan_cancel(local);
|
||||
|
||||
- ieee80211_dfs_cac_cancel(local);
|
||||
+ ieee80211_dfs_cac_cancel(local, NULL);
|
||||
|
||||
ieee80211_roc_purge(local, NULL);
|
||||
|
||||
--- a/net/mac80211/util.c
|
||||
+++ b/net/mac80211/util.c
|
||||
@@ -3451,11 +3451,16 @@ u64 ieee80211_calculate_rx_timestamp(str
|
||||
return ts;
|
||||
}
|
||||
|
||||
-void ieee80211_dfs_cac_cancel(struct ieee80211_local *local)
|
||||
+/* Cancel CAC for the interfaces under the specified @local. If @ctx is
|
||||
+ * also provided, only the interfaces using that ctx will be canceled.
|
||||
+ */
|
||||
+void ieee80211_dfs_cac_cancel(struct ieee80211_local *local,
|
||||
+ struct ieee80211_chanctx *ctx)
|
||||
{
|
||||
struct ieee80211_sub_if_data *sdata;
|
||||
struct cfg80211_chan_def chandef;
|
||||
struct ieee80211_link_data *link;
|
||||
+ struct ieee80211_chanctx_conf *chanctx_conf;
|
||||
unsigned int link_id;
|
||||
|
||||
lockdep_assert_wiphy(local->hw.wiphy);
|
||||
@@ -3468,6 +3473,11 @@ void ieee80211_dfs_cac_cancel(struct iee
|
||||
if (!link)
|
||||
continue;
|
||||
|
||||
+ chanctx_conf = sdata_dereference(link->conf->chanctx_conf,
|
||||
+ sdata);
|
||||
+ if (ctx && &ctx->conf != chanctx_conf)
|
||||
+ continue;
|
||||
+
|
||||
wiphy_delayed_work_cancel(local->hw.wiphy,
|
||||
&link->dfs_cac_timer_work);
|
||||
|
||||
@@ -3488,9 +3498,8 @@ void ieee80211_dfs_radar_detected_work(s
|
||||
{
|
||||
struct ieee80211_local *local =
|
||||
container_of(work, struct ieee80211_local, radar_detected_work);
|
||||
- struct cfg80211_chan_def chandef = local->hw.conf.chandef;
|
||||
+ struct cfg80211_chan_def chandef;
|
||||
struct ieee80211_chanctx *ctx;
|
||||
- int num_chanctx = 0;
|
||||
|
||||
lockdep_assert_wiphy(local->hw.wiphy);
|
||||
|
||||
@@ -3498,25 +3507,46 @@ void ieee80211_dfs_radar_detected_work(s
|
||||
if (ctx->replace_state == IEEE80211_CHANCTX_REPLACES_OTHER)
|
||||
continue;
|
||||
|
||||
- num_chanctx++;
|
||||
+ if (!ctx->radar_detected)
|
||||
+ continue;
|
||||
+
|
||||
+ ctx->radar_detected = false;
|
||||
+
|
||||
chandef = ctx->conf.def;
|
||||
+
|
||||
+ ieee80211_dfs_cac_cancel(local, ctx);
|
||||
+ cfg80211_radar_event(local->hw.wiphy, &chandef, GFP_KERNEL);
|
||||
}
|
||||
+}
|
||||
|
||||
- ieee80211_dfs_cac_cancel(local);
|
||||
+static void
|
||||
+ieee80211_radar_mark_chan_ctx_iterator(struct ieee80211_hw *hw,
|
||||
+ struct ieee80211_chanctx_conf *chanctx_conf,
|
||||
+ void *data)
|
||||
+{
|
||||
+ struct ieee80211_chanctx *ctx =
|
||||
+ container_of(chanctx_conf, struct ieee80211_chanctx,
|
||||
+ conf);
|
||||
|
||||
- if (num_chanctx > 1)
|
||||
- /* XXX: multi-channel is not supported yet */
|
||||
- WARN_ON(1);
|
||||
- else
|
||||
- cfg80211_radar_event(local->hw.wiphy, &chandef, GFP_KERNEL);
|
||||
+ if (ctx->replace_state == IEEE80211_CHANCTX_REPLACES_OTHER)
|
||||
+ return;
|
||||
+
|
||||
+ if (data && data != chanctx_conf)
|
||||
+ return;
|
||||
+
|
||||
+ ctx->radar_detected = true;
|
||||
}
|
||||
|
||||
-void ieee80211_radar_detected(struct ieee80211_hw *hw)
|
||||
+void ieee80211_radar_detected(struct ieee80211_hw *hw,
|
||||
+ struct ieee80211_chanctx_conf *chanctx_conf)
|
||||
{
|
||||
struct ieee80211_local *local = hw_to_local(hw);
|
||||
|
||||
trace_api_radar_detected(local);
|
||||
|
||||
+ ieee80211_iter_chan_contexts_atomic(hw, ieee80211_radar_mark_chan_ctx_iterator,
|
||||
+ chanctx_conf);
|
||||
+
|
||||
wiphy_work_queue(hw->wiphy, &local->radar_detected_work);
|
||||
}
|
||||
EXPORT_SYMBOL(ieee80211_radar_detected);
|
@ -1,79 +0,0 @@
|
||||
From: Felix Fietkau <nbd@nbd.name>
|
||||
Date: Sun, 6 Oct 2024 17:34:08 +0200
|
||||
Subject: [PATCH] wifi: mac80211: skip non-uploaded keys in ieee80211_iter_keys
|
||||
|
||||
Sync iterator conditions with ieee80211_iter_keys_rcu.
|
||||
|
||||
Fixes: 830af02f24fb ("mac80211: allow driver to iterate keys")
|
||||
Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||
---
|
||||
|
||||
--- a/net/mac80211/key.c
|
||||
+++ b/net/mac80211/key.c
|
||||
@@ -987,6 +987,26 @@ void ieee80211_reenable_keys(struct ieee
|
||||
}
|
||||
}
|
||||
|
||||
+static void
|
||||
+ieee80211_key_iter(struct ieee80211_hw *hw,
|
||||
+ struct ieee80211_vif *vif,
|
||||
+ struct ieee80211_key *key,
|
||||
+ void (*iter)(struct ieee80211_hw *hw,
|
||||
+ struct ieee80211_vif *vif,
|
||||
+ struct ieee80211_sta *sta,
|
||||
+ struct ieee80211_key_conf *key,
|
||||
+ void *data),
|
||||
+ void *iter_data)
|
||||
+{
|
||||
+ /* skip keys of station in removal process */
|
||||
+ if (key->sta && key->sta->removed)
|
||||
+ return;
|
||||
+ if (!(key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE))
|
||||
+ return;
|
||||
+ iter(hw, vif, key->sta ? &key->sta->sta : NULL,
|
||||
+ &key->conf, iter_data);
|
||||
+}
|
||||
+
|
||||
void ieee80211_iter_keys(struct ieee80211_hw *hw,
|
||||
struct ieee80211_vif *vif,
|
||||
void (*iter)(struct ieee80211_hw *hw,
|
||||
@@ -1005,16 +1025,13 @@ void ieee80211_iter_keys(struct ieee8021
|
||||
if (vif) {
|
||||
sdata = vif_to_sdata(vif);
|
||||
list_for_each_entry_safe(key, tmp, &sdata->key_list, list)
|
||||
- iter(hw, &sdata->vif,
|
||||
- key->sta ? &key->sta->sta : NULL,
|
||||
- &key->conf, iter_data);
|
||||
+ ieee80211_key_iter(hw, vif, key, iter, iter_data);
|
||||
} else {
|
||||
list_for_each_entry(sdata, &local->interfaces, list)
|
||||
list_for_each_entry_safe(key, tmp,
|
||||
&sdata->key_list, list)
|
||||
- iter(hw, &sdata->vif,
|
||||
- key->sta ? &key->sta->sta : NULL,
|
||||
- &key->conf, iter_data);
|
||||
+ ieee80211_key_iter(hw, &sdata->vif, key,
|
||||
+ iter, iter_data);
|
||||
}
|
||||
}
|
||||
EXPORT_SYMBOL(ieee80211_iter_keys);
|
||||
@@ -1031,17 +1048,8 @@ _ieee80211_iter_keys_rcu(struct ieee8021
|
||||
{
|
||||
struct ieee80211_key *key;
|
||||
|
||||
- list_for_each_entry_rcu(key, &sdata->key_list, list) {
|
||||
- /* skip keys of station in removal process */
|
||||
- if (key->sta && key->sta->removed)
|
||||
- continue;
|
||||
- if (!(key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE))
|
||||
- continue;
|
||||
-
|
||||
- iter(hw, &sdata->vif,
|
||||
- key->sta ? &key->sta->sta : NULL,
|
||||
- &key->conf, iter_data);
|
||||
- }
|
||||
+ list_for_each_entry_rcu(key, &sdata->key_list, list)
|
||||
+ ieee80211_key_iter(hw, &sdata->vif, key, iter, iter_data);
|
||||
}
|
||||
|
||||
void ieee80211_iter_keys_rcu(struct ieee80211_hw *hw,
|
@ -1,32 +0,0 @@
|
||||
From: Benjamin Lin <benjamin-jw.lin@mediatek.com>
|
||||
Date: Mon, 18 Nov 2024 16:07:22 +0800
|
||||
Subject: [PATCH] wifi: mac80211: fix incorrect timing to initialize
|
||||
station NSS capability
|
||||
|
||||
Station's spatial streaming capability should be initialized before
|
||||
handling VHT OMN, because the handling requires the capability information.
|
||||
|
||||
Fixes: a8bca3e9371d ("wifi: mac80211: track capability/opmode NSS separately")
|
||||
Signed-off-by: Benjamin Lin <benjamin-jw.lin@mediatek.com>
|
||||
---
|
||||
|
||||
--- a/net/mac80211/cfg.c
|
||||
+++ b/net/mac80211/cfg.c
|
||||
@@ -1914,6 +1914,8 @@ static int sta_link_apply_parameters(str
|
||||
params->eht_capa_len,
|
||||
link_sta);
|
||||
|
||||
+ ieee80211_sta_init_nss(link_sta);
|
||||
+
|
||||
if (params->opmode_notif_used) {
|
||||
/* returned value is only needed for rc update, but the
|
||||
* rc isn't initialized here yet, so ignore it
|
||||
@@ -1923,8 +1925,6 @@ static int sta_link_apply_parameters(str
|
||||
sband->band);
|
||||
}
|
||||
|
||||
- ieee80211_sta_init_nss(link_sta);
|
||||
-
|
||||
return 0;
|
||||
}
|
||||
|
@ -1,53 +0,0 @@
|
||||
From: "Gustavo A. R. Silva" <gustavoars@kernel.org>
|
||||
Date: Fri, 25 Oct 2024 16:05:50 -0600
|
||||
Subject: [PATCH] wifi: mac80211: ieee80211_i: Fix memory corruption bug in
|
||||
struct ieee80211_chanctx
|
||||
|
||||
Move the `struct ieee80211_chanctx_conf conf` to the end of
|
||||
`struct ieee80211_chanctx` and fix a memory corruption bug
|
||||
triggered e.g. in `hwsim_set_chanctx_magic()`: `radar_detected`
|
||||
is being overwritten when `cp->magic = HWSIM_CHANCTX_MAGIC;`
|
||||
See the function call sequence below:
|
||||
|
||||
drv_add_chanctx(... struct ieee80211_chanctx *ctx) ->
|
||||
local->ops->add_chanctx(&local->hw, &ctx->conf) ->
|
||||
mac80211_hwsim_add_chanctx(... struct ieee80211_chanctx_conf *ctx) ->
|
||||
hwsim_set_chanctx_magic(ctx)
|
||||
|
||||
This also happens in a number of other drivers.
|
||||
|
||||
Also, add a code comment to try to prevent people from introducing
|
||||
new members after `struct ieee80211_chanctx_conf conf`. Notice that
|
||||
`struct ieee80211_chanctx_conf` is a flexible structure --a structure
|
||||
that contains a flexible-array member, so it should always be at
|
||||
the end of any other containing structures.
|
||||
|
||||
This change also fixes 50 of the following warnings:
|
||||
|
||||
net/mac80211/ieee80211_i.h:895:39: warning: structure containing a flexible array member is not at the end of another structure [-Wflex-array-member-not-at-end]
|
||||
|
||||
-Wflex-array-member-not-at-end was introduced in GCC-14, and we are
|
||||
getting ready to enable it, globally.
|
||||
|
||||
Fixes: bca8bc0399ac ("wifi: mac80211: handle ieee80211_radar_detected() for MLO")
|
||||
Signed-off-by: Gustavo A. R. Silva <gustavoars@kernel.org>
|
||||
Link: https://patch.msgid.link/ZxwWPrncTeSi1UTq@kspp
|
||||
[also refer to other drivers in commit message]
|
||||
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
|
||||
---
|
||||
|
||||
--- a/net/mac80211/ieee80211_i.h
|
||||
+++ b/net/mac80211/ieee80211_i.h
|
||||
@@ -894,9 +894,10 @@ struct ieee80211_chanctx {
|
||||
/* temporary data for search algorithm etc. */
|
||||
struct ieee80211_chan_req req;
|
||||
|
||||
- struct ieee80211_chanctx_conf conf;
|
||||
-
|
||||
bool radar_detected;
|
||||
+
|
||||
+ /* MUST be last - ends in a flexible-array member. */
|
||||
+ struct ieee80211_chanctx_conf conf;
|
||||
};
|
||||
|
||||
struct mac80211_qos_map {
|
@ -1,24 +0,0 @@
|
||||
From: Ben Greear <greearb@candelatech.com>
|
||||
Date: Thu, 10 Oct 2024 13:39:54 -0700
|
||||
Subject: [PATCH] mac80211: fix user-power when emulating chanctx
|
||||
|
||||
ieee80211_calc_hw_conf_chan was ignoring the configured
|
||||
user_txpower. If it is set, use it to potentially decrease
|
||||
txpower as requested.
|
||||
|
||||
Signed-off-by: Ben Greear <greearb@candelatech.com>
|
||||
Link: https://patch.msgid.link/20241010203954.1219686-1-greearb@candelatech.com
|
||||
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
|
||||
---
|
||||
|
||||
--- a/net/mac80211/main.c
|
||||
+++ b/net/mac80211/main.c
|
||||
@@ -167,6 +167,8 @@ static u32 ieee80211_calc_hw_conf_chan(s
|
||||
}
|
||||
|
||||
power = ieee80211_chandef_max_power(&chandef);
|
||||
+ if (local->user_power_level != IEEE80211_UNSET_POWER_LEVEL)
|
||||
+ power = min(local->user_power_level, power);
|
||||
|
||||
rcu_read_lock();
|
||||
list_for_each_entry_rcu(sdata, &local->interfaces, list) {
|
@ -1,83 +0,0 @@
|
||||
From: Remi Pommarel <repk@triplefau.lt>
|
||||
Date: Tue, 24 Sep 2024 21:28:04 +0200
|
||||
Subject: [PATCH] wifi: cfg80211: Add wiphy_delayed_work_pending()
|
||||
|
||||
Add wiphy_delayed_work_pending() to check if any delayed work timer is
|
||||
pending, that can be used to be sure that wiphy_delayed_work_queue()
|
||||
won't postpone an already pending delayed work.
|
||||
|
||||
Signed-off-by: Remi Pommarel <repk@triplefau.lt>
|
||||
Link: https://patch.msgid.link/20240924192805.13859-2-repk@triplefau.lt
|
||||
[fix return value kernel-doc]
|
||||
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
|
||||
---
|
||||
|
||||
--- a/include/net/cfg80211.h
|
||||
+++ b/include/net/cfg80211.h
|
||||
@@ -6141,6 +6141,50 @@ void wiphy_delayed_work_flush(struct wip
|
||||
struct wiphy_delayed_work *dwork);
|
||||
|
||||
/**
|
||||
+ * wiphy_delayed_work_pending - Find out whether a wiphy delayable
|
||||
+ * work item is currently pending.
|
||||
+ *
|
||||
+ * @wiphy: the wiphy, for debug purposes
|
||||
+ * @dwork: the delayed work in question
|
||||
+ *
|
||||
+ * Return: true if timer is pending, false otherwise
|
||||
+ *
|
||||
+ * How wiphy_delayed_work_queue() works is by setting a timer which
|
||||
+ * when it expires calls wiphy_work_queue() to queue the wiphy work.
|
||||
+ * Because wiphy_delayed_work_queue() uses mod_timer(), if it is
|
||||
+ * called twice and the second call happens before the first call
|
||||
+ * deadline, the work will rescheduled for the second deadline and
|
||||
+ * won't run before that.
|
||||
+ *
|
||||
+ * wiphy_delayed_work_pending() can be used to detect if calling
|
||||
+ * wiphy_work_delayed_work_queue() would start a new work schedule
|
||||
+ * or delayed a previous one. As seen below it cannot be used to
|
||||
+ * detect precisely if the work has finished to execute nor if it
|
||||
+ * is currently executing.
|
||||
+ *
|
||||
+ * CPU0 CPU1
|
||||
+ * wiphy_delayed_work_queue(wk)
|
||||
+ * mod_timer(wk->timer)
|
||||
+ * wiphy_delayed_work_pending(wk) -> true
|
||||
+ *
|
||||
+ * [...]
|
||||
+ * expire_timers(wk->timer)
|
||||
+ * detach_timer(wk->timer)
|
||||
+ * wiphy_delayed_work_pending(wk) -> false
|
||||
+ * wk->timer->function() |
|
||||
+ * wiphy_work_queue(wk) | delayed work pending
|
||||
+ * list_add_tail() | returns false but
|
||||
+ * queue_work(cfg80211_wiphy_work) | wk->func() has not
|
||||
+ * | been run yet
|
||||
+ * [...] |
|
||||
+ * cfg80211_wiphy_work() |
|
||||
+ * wk->func() V
|
||||
+ *
|
||||
+ */
|
||||
+bool wiphy_delayed_work_pending(struct wiphy *wiphy,
|
||||
+ struct wiphy_delayed_work *dwork);
|
||||
+
|
||||
+/**
|
||||
* enum ieee80211_ap_reg_power - regulatory power for an Access Point
|
||||
*
|
||||
* @IEEE80211_REG_UNSET_AP: Access Point has no regulatory power mode
|
||||
--- a/net/wireless/core.c
|
||||
+++ b/net/wireless/core.c
|
||||
@@ -1735,6 +1735,13 @@ void wiphy_delayed_work_flush(struct wip
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(wiphy_delayed_work_flush);
|
||||
|
||||
+bool wiphy_delayed_work_pending(struct wiphy *wiphy,
|
||||
+ struct wiphy_delayed_work *dwork)
|
||||
+{
|
||||
+ return timer_pending(&dwork->timer);
|
||||
+}
|
||||
+EXPORT_SYMBOL_GPL(wiphy_delayed_work_pending);
|
||||
+
|
||||
static int __init cfg80211_init(void)
|
||||
{
|
||||
int err;
|
@ -1,148 +0,0 @@
|
||||
From: Remi Pommarel <repk@triplefau.lt>
|
||||
Date: Tue, 24 Sep 2024 21:28:05 +0200
|
||||
Subject: [PATCH] wifi: mac80211: Convert color collision detection to wiphy
|
||||
work
|
||||
|
||||
Call to ieee80211_color_collision_detection_work() needs wiphy lock to
|
||||
be held (see lockdep assert in cfg80211_bss_color_notify()). Not locking
|
||||
wiphy causes the following lockdep error:
|
||||
|
||||
WARNING: CPU: 2 PID: 42 at net/wireless/nl80211.c:19505 cfg80211_bss_color_notify+0x1a4/0x25c
|
||||
Modules linked in:
|
||||
CPU: 2 PID: 42 Comm: kworker/u8:3 Tainted: G W 6.4.0-02327-g36c6cb260481 #1048
|
||||
Hardware name:
|
||||
Workqueue: phy1 ieee80211_color_collision_detection_work
|
||||
pstate: 60000005 (nZCv daif -PAN -UAO -TCO -DIT -SSBS BTYPE=--)
|
||||
pc : cfg80211_bss_color_notify+0x1a4/0x25c
|
||||
lr : cfg80211_bss_color_notify+0x1a0/0x25c
|
||||
sp : ffff000002947d00
|
||||
x29: ffff000002947d00 x28: ffff800008e1a000 x27: ffff000002bd4705
|
||||
x26: ffff00000d034000 x25: ffff80000903cf40 x24: 0000000000000000
|
||||
x23: ffff00000cb70720 x22: 0000000000800000 x21: ffff800008dfb008
|
||||
x20: 000000000000008d x19: ffff00000d035fa8 x18: 0000000000000010
|
||||
x17: 0000000000000001 x16: 000003564b1ce96a x15: 000d69696d057970
|
||||
x14: 000000000000003b x13: 0000000000000001 x12: 0000000000040000
|
||||
x11: 0000000000000001 x10: ffff80000978f9c0 x9 : ffff0000028d3174
|
||||
x8 : ffff800008e30000 x7 : 0000000000000000 x6 : 0000000000000028
|
||||
x5 : 000000000002f498 x4 : ffff00000d034a80 x3 : 0000000000800000
|
||||
x2 : ffff800016143000 x1 : 0000000000000000 x0 : 0000000000000000
|
||||
Call trace:
|
||||
cfg80211_bss_color_notify+0x1a4/0x25c
|
||||
ieee80211_color_collision_detection_work+0x20/0x118
|
||||
process_one_work+0x294/0x554
|
||||
worker_thread+0x70/0x440
|
||||
kthread+0xf4/0xf8
|
||||
ret_from_fork+0x10/0x20
|
||||
irq event stamp: 77372
|
||||
hardirqs last enabled at (77371): [<ffff800008a346fc>] _raw_spin_unlock_irq+0x2c/0x4c
|
||||
hardirqs last disabled at (77372): [<ffff800008a28754>] el1_dbg+0x20/0x48
|
||||
softirqs last enabled at (77350): [<ffff8000089e120c>] batadv_send_outstanding_bcast_packet+0xb8/0x120
|
||||
softirqs last disabled at (77348): [<ffff8000089e11d4>] batadv_send_outstanding_bcast_packet+0x80/0x120
|
||||
|
||||
The wiphy lock cannot be taken directly from color collision detection
|
||||
delayed work (ieee80211_color_collision_detection_work()) because this
|
||||
work is cancel_delayed_work_sync() under this wiphy lock causing a
|
||||
potential deadlock( see [0] for details).
|
||||
|
||||
To fix that ieee80211_color_collision_detection_work() could be
|
||||
converted to a wiphy work and cancel_delayed_work_sync() can be simply
|
||||
replaced by wiphy_delayed_work_cancel() serving the same purpose under
|
||||
wiphy lock.
|
||||
|
||||
This could potentially fix [1].
|
||||
|
||||
[0]: https://lore.kernel.org/linux-wireless/D4A40Q44OAY2.W3SIF6UEPBUN@freebox.fr/
|
||||
[1]: https://lore.kernel.org/lkml/000000000000612f290618eee3e5@google.com/
|
||||
|
||||
Reported-by: Nicolas Escande <nescande@freebox.fr>
|
||||
Signed-off-by: Remi Pommarel <repk@triplefau.lt>
|
||||
Link: https://patch.msgid.link/20240924192805.13859-3-repk@triplefau.lt
|
||||
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
|
||||
---
|
||||
|
||||
--- a/net/mac80211/cfg.c
|
||||
+++ b/net/mac80211/cfg.c
|
||||
@@ -4836,12 +4836,12 @@ void ieee80211_color_change_finalize_wor
|
||||
ieee80211_color_change_finalize(link);
|
||||
}
|
||||
|
||||
-void ieee80211_color_collision_detection_work(struct work_struct *work)
|
||||
+void ieee80211_color_collision_detection_work(struct wiphy *wiphy,
|
||||
+ struct wiphy_work *work)
|
||||
{
|
||||
- struct delayed_work *delayed_work = to_delayed_work(work);
|
||||
struct ieee80211_link_data *link =
|
||||
- container_of(delayed_work, struct ieee80211_link_data,
|
||||
- color_collision_detect_work);
|
||||
+ container_of(work, struct ieee80211_link_data,
|
||||
+ color_collision_detect_work.work);
|
||||
struct ieee80211_sub_if_data *sdata = link->sdata;
|
||||
|
||||
cfg80211_obss_color_collision_notify(sdata->dev, link->color_bitmap,
|
||||
@@ -4894,7 +4894,8 @@ ieee80211_obss_color_collision_notify(st
|
||||
return;
|
||||
}
|
||||
|
||||
- if (delayed_work_pending(&link->color_collision_detect_work)) {
|
||||
+ if (wiphy_delayed_work_pending(sdata->local->hw.wiphy,
|
||||
+ &link->color_collision_detect_work)) {
|
||||
rcu_read_unlock();
|
||||
return;
|
||||
}
|
||||
@@ -4903,9 +4904,9 @@ ieee80211_obss_color_collision_notify(st
|
||||
/* queue the color collision detection event every 500 ms in order to
|
||||
* avoid sending too much netlink messages to userspace.
|
||||
*/
|
||||
- ieee80211_queue_delayed_work(&sdata->local->hw,
|
||||
- &link->color_collision_detect_work,
|
||||
- msecs_to_jiffies(500));
|
||||
+ wiphy_delayed_work_queue(sdata->local->hw.wiphy,
|
||||
+ &link->color_collision_detect_work,
|
||||
+ msecs_to_jiffies(500));
|
||||
|
||||
rcu_read_unlock();
|
||||
}
|
||||
--- a/net/mac80211/ieee80211_i.h
|
||||
+++ b/net/mac80211/ieee80211_i.h
|
||||
@@ -1056,7 +1056,7 @@ struct ieee80211_link_data {
|
||||
} csa;
|
||||
|
||||
struct wiphy_work color_change_finalize_work;
|
||||
- struct delayed_work color_collision_detect_work;
|
||||
+ struct wiphy_delayed_work color_collision_detect_work;
|
||||
u64 color_bitmap;
|
||||
|
||||
/* context reservation -- protected with wiphy mutex */
|
||||
@@ -2010,7 +2010,8 @@ int ieee80211_channel_switch(struct wiph
|
||||
/* color change handling */
|
||||
void ieee80211_color_change_finalize_work(struct wiphy *wiphy,
|
||||
struct wiphy_work *work);
|
||||
-void ieee80211_color_collision_detection_work(struct work_struct *work);
|
||||
+void ieee80211_color_collision_detection_work(struct wiphy *wiphy,
|
||||
+ struct wiphy_work *work);
|
||||
|
||||
/* interface handling */
|
||||
#define MAC80211_SUPPORTED_FEATURES_TX (NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM | \
|
||||
--- a/net/mac80211/link.c
|
||||
+++ b/net/mac80211/link.c
|
||||
@@ -41,8 +41,8 @@ void ieee80211_link_init(struct ieee8021
|
||||
ieee80211_csa_finalize_work);
|
||||
wiphy_work_init(&link->color_change_finalize_work,
|
||||
ieee80211_color_change_finalize_work);
|
||||
- INIT_DELAYED_WORK(&link->color_collision_detect_work,
|
||||
- ieee80211_color_collision_detection_work);
|
||||
+ wiphy_delayed_work_init(&link->color_collision_detect_work,
|
||||
+ ieee80211_color_collision_detection_work);
|
||||
INIT_LIST_HEAD(&link->assigned_chanctx_list);
|
||||
INIT_LIST_HEAD(&link->reserved_chanctx_list);
|
||||
wiphy_delayed_work_init(&link->dfs_cac_timer_work,
|
||||
@@ -72,7 +72,8 @@ void ieee80211_link_stop(struct ieee8021
|
||||
if (link->sdata->vif.type == NL80211_IFTYPE_STATION)
|
||||
ieee80211_mgd_stop_link(link);
|
||||
|
||||
- cancel_delayed_work_sync(&link->color_collision_detect_work);
|
||||
+ wiphy_delayed_work_cancel(link->sdata->local->hw.wiphy,
|
||||
+ &link->color_collision_detect_work);
|
||||
wiphy_work_cancel(link->sdata->local->hw.wiphy,
|
||||
&link->color_change_finalize_work);
|
||||
wiphy_work_cancel(link->sdata->local->hw.wiphy,
|
Loading…
Reference in New Issue
Block a user