* Re: [PATCH] wifi: rtl8xxxu: Enable AP mode for RTL8188EU
From: Bitterblue Smith @ 2026-03-12 15:58 UTC (permalink / raw)
To: Georg Müller, Jes.Sorensen; +Cc: linux-wireless, linux-kernel
In-Reply-To: <20260312142155.2642993-1-georgmueller@gmx.net>
On 12/03/2026 16:21, Georg Müller wrote:
> Allow devices with this driver to be used as a wireless access point.
>
> I successfully tested this with a TP-Link TP-Link TL-WN725N adapter.
>
> Experiments two years ago failed, but some other improvements to the
> driver seemed to have resolved theses issues.
>
The rate control code still doesn't handle more than one station.
It's not going to work right.
It shouldn't be too complicated. The ra_info member of rtl8xxxu_priv
needs to become an array.
> The max_macid_num is conservative. The old driver used 32 [1], some
> other sources said 64. I have not enough adapters to test any of the
> higher values. Given the usage of this chipset in nano dongles, I think
> the 16 might be high enough.
>
> Signed-off-by: Georg Müller <georgmueller@gmx.net>
> ---
> drivers/net/wireless/realtek/rtl8xxxu/8188e.c | 2 ++
> 1 file changed, 2 insertions(+)
>
> diff --git a/drivers/net/wireless/realtek/rtl8xxxu/8188e.c b/drivers/net/wireless/realtek/rtl8xxxu/8188e.c
> index 766a7a7c7d28..c6aecb28d28b 100644
> --- a/drivers/net/wireless/realtek/rtl8xxxu/8188e.c
> +++ b/drivers/net/wireless/realtek/rtl8xxxu/8188e.c
> @@ -1867,6 +1867,8 @@ struct rtl8xxxu_fileops rtl8188eu_fops = {
> .init_reg_pkt_life_time = 1,
> .gen2_thermal_meter = 1,
> .max_sec_cam_num = 32,
> + .supports_ap = 1,
> + .max_macid_num = 16,
> .adda_1t_init = 0x0b1b25a0,
> .adda_1t_path_on = 0x0bdb25a0,
> /*
^ permalink raw reply
* Re: [PATCH] wifi: rtl8xxxu: Enable AP mode for RTL8188EU
From: Georg Müller @ 2026-03-12 16:08 UTC (permalink / raw)
To: Bitterblue Smith, Jes.Sorensen; +Cc: linux-wireless, linux-kernel
In-Reply-To: <093ad0f2-8265-4560-a51f-397eb34f7f1c@gmail.com>
Am 12.03.26 um 16:58 schrieb Bitterblue Smith:
> On 12/03/2026 16:21, Georg Müller wrote:
>> Allow devices with this driver to be used as a wireless access point.
>>
>> I successfully tested this with a TP-Link TP-Link TL-WN725N adapter.
>>
>> Experiments two years ago failed, but some other improvements to the
>> driver seemed to have resolved theses issues.
>>
>
> The rate control code still doesn't handle more than one station.
> It's not going to work right.
>
> It shouldn't be too complicated. The ra_info member of rtl8xxxu_priv
> needs to become an array.
Ok, I have only tested it with one client in my setup.
So the ra_info array needs to of size max_macid_num?
Dynamically allocated or hard-coded in struct rtl8xxxu_priv (8188e seems
to be the only user of struct rtl8xxxu_ra_info)?
Best regards,
Georg
^ permalink raw reply
* Re: [PATCH 38/61] net: Prefer IS_ERR_OR_NULL over manual NULL check
From: Przemek Kitszel @ 2026-03-12 16:11 UTC (permalink / raw)
To: Philipp Hahn
Cc: amd-gfx, apparmor, bpf, ceph-devel, cocci, dm-devel, dri-devel,
gfs2, intel-gfx, intel-wired-lan, iommu, kvm, linux-arm-kernel,
linux-block, linux-bluetooth, linux-btrfs, linux-cifs, linux-clk,
linux-erofs, linux-ext4, linux-fsdevel, linux-gpio, linux-hyperv,
linux-input, linux-kernel, linux-leds, linux-media, linux-mips,
linux-mm, linux-modules, linux-mtd, linux-nfs, linux-omap,
linux-phy, linux-pm, linux-rockchip, linux-s390, linux-scsi,
linux-sctp, linux-security-module, linux-sh, linux-sound,
linux-stm32, linux-trace-kernel, linux-usb, linux-wireless,
netdev, ntfs3, samba-technical, sched-ext, target-devel,
tipc-discussion, v9fs, Igor Russkikh, Andrew Lunn,
David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
Pavan Chebbi, Michael Chan, Potnuri Bharat Teja, Tony Nguyen,
Taras Chornyi, Maxime Coquelin, Alexandre Torgue,
Iyappan Subramanian, Keyur Chudgar, Quan Nguyen, Heiner Kallweit,
Russell King
In-Reply-To: <20260310-b4-is_err_or_null-v1-38-bd63b656022d@avm.de>
On 3/10/26 12:49, Philipp Hahn wrote:
> Prefer using IS_ERR_OR_NULL() over using IS_ERR() and a manual NULL
> check.
>
> Change generated with coccinelle.
>
> To: Igor Russkikh <irusskikh@marvell.com>
> To: Andrew Lunn <andrew+netdev@lunn.ch>
> To: "David S. Miller" <davem@davemloft.net>
> To: Eric Dumazet <edumazet@google.com>
> To: Jakub Kicinski <kuba@kernel.org>
> To: Paolo Abeni <pabeni@redhat.com>
> To: Pavan Chebbi <pavan.chebbi@broadcom.com>
> To: Michael Chan <mchan@broadcom.com>
> To: Potnuri Bharat Teja <bharat@chelsio.com>
> To: Tony Nguyen <anthony.l.nguyen@intel.com>
> To: Przemek Kitszel <przemyslaw.kitszel@intel.com>
> To: Taras Chornyi <taras.chornyi@plvision.eu>
> To: Maxime Coquelin <mcoquelin.stm32@gmail.com>
> To: Alexandre Torgue <alexandre.torgue@foss.st.com>
> To: Iyappan Subramanian <iyappan@os.amperecomputing.com>
> To: Keyur Chudgar <keyur@os.amperecomputing.com>
> To: Quan Nguyen <quan@os.amperecomputing.com>
> To: Heiner Kallweit <hkallweit1@gmail.com>
> To: Russell King <linux@armlinux.org.uk>
> Cc: netdev@vger.kernel.org
> Cc: linux-kernel@vger.kernel.org
> Cc: intel-wired-lan@lists.osuosl.org
> Cc: linux-stm32@st-md-mailman.stormreply.com
> Cc: linux-arm-kernel@lists.infradead.org
> Cc: linux-usb@vger.kernel.org
> Signed-off-by: Philipp Hahn <phahn-oss@avm.de>
this is too trivial change, especially when combined like that
https://docs.kernel.org/process/maintainer-netdev.html#clean-up-patches
> ---
> drivers/net/ethernet/aquantia/atlantic/aq_ring.c | 2 +-
> drivers/net/ethernet/broadcom/tg3.c | 2 +-
> drivers/net/ethernet/chelsio/cxgb4/cxgb4_tc_flower.c | 3 +--
> drivers/net/ethernet/intel/ice/devlink/devlink.c | 2 +-
> drivers/net/ethernet/marvell/prestera/prestera_router.c | 2 +-
> drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 2 +-
> drivers/net/mdio/mdio-xgene.c | 2 +-
> drivers/net/usb/r8152.c | 2 +-
> 8 files changed, 8 insertions(+), 9 deletions(-)
>
> diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_ring.c b/drivers/net/ethernet/aquantia/atlantic/aq_ring.c
> index e270327e47fd804cc8ee5cfd53ed1b993c955c41..43edef35c4b1ff606b2f1519a07fad4c9a990ad4 100644
> --- a/drivers/net/ethernet/aquantia/atlantic/aq_ring.c
> +++ b/drivers/net/ethernet/aquantia/atlantic/aq_ring.c
> @@ -810,7 +810,7 @@ static int __aq_ring_xdp_clean(struct aq_ring_s *rx_ring,
> }
>
> skb = aq_xdp_run_prog(aq_nic, &xdp, rx_ring, buff);
> - if (IS_ERR(skb) || !skb)
> + if (IS_ERR_OR_NULL(skb))
> continue;
>
> if (ptp_hwtstamp_len > 0)
> diff --git a/drivers/net/ethernet/broadcom/tg3.c b/drivers/net/ethernet/broadcom/tg3.c
> index 2328fce336447eb4a796f9300ccc0ab536ff0a35..8ed79f34f03d81184dcc12e6eaff009cb8f7756e 100644
> --- a/drivers/net/ethernet/broadcom/tg3.c
> +++ b/drivers/net/ethernet/broadcom/tg3.c
> @@ -7943,7 +7943,7 @@ static int tg3_tso_bug(struct tg3 *tp, struct tg3_napi *tnapi,
>
> segs = skb_gso_segment(skb, tp->dev->features &
> ~(NETIF_F_TSO | NETIF_F_TSO6));
> - if (IS_ERR(segs) || !segs) {
> + if (IS_ERR_OR_NULL(segs)) {
> tnapi->tx_dropped++;
> goto tg3_tso_bug_end;
> }
> diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_tc_flower.c b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_tc_flower.c
> index 3307e50426819087ad985178c4a5383f16b8e7b4..1c8a6445d4b2e3535d8f1b7908dd02d8dd2f23fa 100644
> --- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_tc_flower.c
> +++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_tc_flower.c
> @@ -1032,8 +1032,7 @@ static void ch_flower_stats_handler(struct work_struct *work)
> do {
> rhashtable_walk_start(&iter);
>
> - while ((flower_entry = rhashtable_walk_next(&iter)) &&
> - !IS_ERR(flower_entry)) {
> + while (!IS_ERR_OR_NULL((flower_entry = rhashtable_walk_next(&iter)))) {
> ret = cxgb4_get_filter_counters(adap->port[0],
> flower_entry->filter_id,
> &packets, &bytes,
> diff --git a/drivers/net/ethernet/intel/ice/devlink/devlink.c b/drivers/net/ethernet/intel/ice/devlink/devlink.c
> index 6c72bd15db6d75a1d4fa04ef8fefbd26fb6e84bd..3d08b9187fd76ca3198af28111b6f1c1765ea01e 100644
> --- a/drivers/net/ethernet/intel/ice/devlink/devlink.c
> +++ b/drivers/net/ethernet/intel/ice/devlink/devlink.c
> @@ -791,7 +791,7 @@ static void ice_traverse_tx_tree(struct devlink *devlink, struct ice_sched_node
> node->parent->rate_node);
> }
>
> - if (rate_node && !IS_ERR(rate_node))
> + if (!IS_ERR_OR_NULL(rate_node))
> node->rate_node = rate_node;
>
> traverse_children:
> diff --git a/drivers/net/ethernet/marvell/prestera/prestera_router.c b/drivers/net/ethernet/marvell/prestera/prestera_router.c
> index b036b173a308b5f994ad8538eb010fa27196988c..4492938e8a3da91d32efe8d45ccbe2eb437c0e49 100644
> --- a/drivers/net/ethernet/marvell/prestera/prestera_router.c
> +++ b/drivers/net/ethernet/marvell/prestera/prestera_router.c
> @@ -1061,7 +1061,7 @@ static void __prestera_k_arb_hw_state_upd(struct prestera_switch *sw,
> n = NULL;
> }
>
> - if (!IS_ERR(n) && n) {
> + if (!IS_ERR_OR_NULL(n)) {
> neigh_event_send(n, NULL);
> neigh_release(n);
> } else {
> diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
> index 6827c99bde8c22db42b363d2d36ad6f26075ed50..356a4e9ce04b1fcf8786d7274d31ace404be2cf6 100644
> --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
> +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
> @@ -1275,7 +1275,7 @@ static int stmmac_init_phy(struct net_device *dev)
> /* Some DT bindings do not set-up the PHY handle. Let's try to
> * manually parse it
> */
> - if (!phy_fwnode || IS_ERR(phy_fwnode)) {
> + if (IS_ERR_OR_NULL(phy_fwnode)) {
> int addr = priv->plat->phy_addr;
> struct phy_device *phydev;
>
> diff --git a/drivers/net/mdio/mdio-xgene.c b/drivers/net/mdio/mdio-xgene.c
> index a8f91a4b7fed0927ee14e408000cd3a2bfb9b09a..09b30b563295c6085dc1358ac361301e5cf6b2a8 100644
> --- a/drivers/net/mdio/mdio-xgene.c
> +++ b/drivers/net/mdio/mdio-xgene.c
> @@ -265,7 +265,7 @@ struct phy_device *xgene_enet_phy_register(struct mii_bus *bus, int phy_addr)
> struct phy_device *phy_dev;
>
> phy_dev = get_phy_device(bus, phy_addr, false);
> - if (!phy_dev || IS_ERR(phy_dev))
> + if (IS_ERR_OR_NULL(phy_dev))
> return NULL;
>
> if (phy_device_register(phy_dev))
> diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c
> index 0c83bbbea2e7c322ee6339893e281237663bd3ae..73f17ebd7d40007eec5004f887a46249defd28ab 100644
> --- a/drivers/net/usb/r8152.c
> +++ b/drivers/net/usb/r8152.c
> @@ -2218,7 +2218,7 @@ static void r8152_csum_workaround(struct r8152 *tp, struct sk_buff *skb,
>
> features &= ~(NETIF_F_SG | NETIF_F_IPV6_CSUM | NETIF_F_TSO6);
> segs = skb_gso_segment(skb, features);
> - if (IS_ERR(segs) || !segs)
> + if (IS_ERR_OR_NULL(segs))
> goto drop;
>
> __skb_queue_head_init(&seg_list);
>
^ permalink raw reply
* Re: [PATCH v3] wifi: ath9k: Obtain system GPIOS from descriptors
From: Andy Shevchenko @ 2026-03-12 16:23 UTC (permalink / raw)
To: Linus Walleij
Cc: Kalle Valo, Arnd Bergmann, Alban Bedel, Bartosz Golaszewski,
Toke Høiland-Jørgensen, Michał Kępień,
linux-wireless, brcm80211-dev-list.pdl, linux-gpio
In-Reply-To: <20260312-descriptors-wireless-v3-1-5230e0870c31@kernel.org>
On Thu, Mar 12, 2026 at 04:09:53PM +0100, Linus Walleij wrote:
> The ath9k has an odd use of system-wide GPIOs: if the chip
> does not have internal GPIO capability, it will try to obtain a
> GPIO line from the system GPIO controller:
>
> if (BIT(gpio) & ah->caps.gpio_mask)
> ath9k_hw_gpio_cfg_wmac(...);
> else if (AR_SREV_SOC(ah))
> ath9k_hw_gpio_cfg_soc(ah, gpio, out, label);
>
> Where ath9k_hw_gpio_cfg_soc() will attempt to issue
> gpio_request_one() passing the local GPIO number of the controller
> (0..31) to gpio_request_one().
>
> This is somewhat peculiar and possibly even dangerous: there is
> nowadays no guarantee of the numbering of these system-wide
> GPIOs, and assuming that GPIO 0..31 as used by ath9k would
> correspond to GPIOs 0..31 on the system as a whole seems a bit
> wild.
>
> Register all 32 GPIOs at index 0..31 directly in the ATH79K
> GPIO driver and associate with the NULL device (making them
> widely available) if and only if we are probing ATH79K wifi
> from the AHB bus (used for SoCs). We obtain these offsets from
> the NULL device if necessary.
>
> These GPIOs should ideally be defined in the device tree
> instead, but we have no control over that for the legacy
> code path.
>
> Testcompiled with the ath79 defconfig.
...
> +#define ATH79K_WIFI_DESCS 32
> +static int ath79_gpio_register_wifi_descriptors(struct device *dev,
> + const char *label)
> +{
> + struct gpiod_lookup_table *lookup;
> + int i;
> +
> + /* Create a gpiod lookup using gpiochip-local offsets + 1 for NULL */
> + lookup = devm_kzalloc(dev,
> + struct_size(lookup, table, ATH79K_WIFI_DESCS + 1),
> + GFP_KERNEL);
> +
Redundant blank line.
> + if (!lookup)
> + return -ENOMEM;
> +
> + /*
> + * Ugly system-wide lookup for the NULL device: we know this
> + * is already NULL but explicitly assign it here for people to
> + * know what is going on. (Yes this is an ugly legacy hack, live
> + * with it.)
> + */
> + lookup->dev_id = NULL;
> +
> + for (i = 0; i < ATH79K_WIFI_DESCS; i++) {
> + lookup->table[i] = (struct gpiod_lookup)
The macro below is already compound literal, the '(struct gpiod_lookup)'
is redundant.
> + /*
> + * Set the HW offset on the chip and the lookup
> + * index to the same value, so looking up index 0
> + * will get HW offset 0, index 1 HW offset 1 etc.
> + */
> + GPIO_LOOKUP_IDX(label, i, "ath9k", i, GPIO_ACTIVE_HIGH);
> + }
> +
> + gpiod_add_lookup_table(lookup);
> +
> + return 0;
> +}
...
> + /*
> + * Obtains a system specific GPIO descriptor from another GPIO controller.
> + * Ideally this should come from the device tree, this is a legacy code
> + * path.
> + */
> + gpiod = gpiod_get_index(NULL, "ath9k", gpio, flags);
> +
Redundant blank line.
> + if (IS_ERR(gpiod)) {
> + err = PTR_ERR(gpiod);
What about
err = PTR_ERR_OR_ZERO(...);
if (err) {
...
?
> ath_err(ath9k_hw_common(ah), "request GPIO%d failed:%d\n",
> gpio, err);
> return;
> }
...
Have you considered using software nodes instead?
--
With Best Regards,
Andy Shevchenko
^ permalink raw reply
* Re: [PATCH 1/2] mt76: connac: fix txpower_cur not updated in mt76_connac_mcu_set_rate_txpower()
From: bryam vargas @ 2026-03-12 16:30 UTC (permalink / raw)
To: Sean Wang
Cc: linux-wireless, nbd, lorenzo,
moderated list:ARM/Mediatek SoC support
In-Reply-To: <CAGp9Lzr4KsXEXbj+4h+Lk2fKU7z6BqtL5krzZmu-_So2-bN4_Q@mail.gmail.com>
Hi Sean,
Thanks for the thorough v2 review on both patches — really helpful.
I spent the last few days digging deeper into the txpower reporting
path across mt76 sub-drivers (mt7615, mt7915, mt7996, mt7921, mt7925)
to find the most efficient fix. Turns out, Razvan Grigore already
nailed it 13 months ago:
https://patchwork.kernel.org/project/linux-wireless/patch/20250211081247.5892-3-razvan.grigore@vampirebyte.ro/
His patch adds 3 lines to mt7921_set_tx_sar_pwr() — same pattern as
mt7915 (mcu.c:3393) and mt7996 (mcu.c:4802):
tx_power = mt76_get_power_bound(mphy, hw->conf.power_level);
tx_power = mt76_get_rate_power_limits(mphy, mphy->chandef.chan,
&limits_array, tx_power);
mphy->txpower_cur = tx_power;
This runs before mt76_connac_mcu_set_rate_txpower(), so it uses the
same SAR-bounded, DT-capped value that the firmware receives. And
since set_tx_sar_pwr() is called from all four paths you pointed out
(init, config, regd_update, set_sar_specs), it covers every scenario
— including the ones Lucid Duck's BSS_CHANGED_TXPOWER approach misses
when not associated.
I'm withdrawing both of my patches. Razvan's approach is the right
one, and I don't want to duplicate his work.
What I'll focus on instead:
- Testing: I'll verify Razvan's patch on my MT7921U (NAB9, 2400m
altitude, daily use serving real users) and provide Tested-by.
- SEFI/USB reset: You're right that v2 was premature. I'll file a
proper bug with full dmesg, lsusb topology, and usbmon captures
first, then propose a fix only after the failure mode is understood.
- WF_MIB over USB: Still interested in your thoughts on my March 12
email about MT_MIB_SDR9/36/37 returning 0 on mt7921u. From what
I've seen, the USB variant has several gaps beyond txpower — survey
data, channel time counters — that I'd like to help close.
Best regards,
Bryam Vargas
^ permalink raw reply
* Re: [PATCH 00/61] treewide: Use IS_ERR_OR_NULL over manual NULL check - refactor
From: Jason Gunthorpe @ 2026-03-12 16:54 UTC (permalink / raw)
To: James Bottomley
Cc: Kuan-Wei Chiu, Philipp Hahn, amd-gfx, apparmor, bpf, ceph-devel,
cocci, dm-devel, dri-devel, gfs2, intel-gfx, intel-wired-lan,
iommu, kvm, linux-arm-kernel, linux-block, linux-bluetooth,
linux-btrfs, linux-cifs, linux-clk, linux-erofs, linux-ext4,
linux-fsdevel, linux-gpio, linux-hyperv, linux-input,
linux-kernel, linux-leds, linux-media, linux-mips, linux-mm,
linux-modules, linux-mtd, linux-nfs, linux-omap, linux-phy,
linux-pm, linux-rockchip, linux-s390, linux-scsi, linux-sctp,
linux-security-module, linux-sh, linux-sound, linux-stm32,
linux-trace-kernel, linux-usb, linux-wireless, netdev, ntfs3,
samba-technical, sched-ext, target-devel, tipc-discussion, v9fs
In-Reply-To: <f5688b895eaebabae6545a0d9baf8f1404e8454e.camel@HansenPartnership.com>
On Thu, Mar 12, 2026 at 11:32:37AM -0400, James Bottomley wrote:
> On Thu, 2026-03-12 at 09:57 -0300, Jason Gunthorpe wrote:
> > On Wed, Mar 11, 2026 at 02:40:36AM +0800, Kuan-Wei Chiu wrote:
> >
> > > IMHO, the necessity of IS_ERR_OR_NULL() often highlights a
> > > confusing or flawed API design. It usually implies that the caller
> > > is unsure whether a failure results in an error pointer or a NULL
> > > pointer.
> >
> > +1
> >
> > IS_ERR_OR_NULL() should always be looked on with suspicion. Very
> > little should be returning some tri-state 'ERR' 'NULL' 'SUCCESS'
> > pointer. What does the middle condition even mean? IS_ERR_OR_NULL()
> > implies ERR and NULL are semanticly the same, so fix the things to
> > always use ERR.
>
> Not in any way supporting the original patch. However, the pattern
> ERR, NULL, PTR is used extensively in the dentry code of filesystems.
> See the try_lookup..() set of functions in fs/namei.c
>
> The meaning is
>
> PTR - I found it
> NULL - It definitely doesn't exist
> ERR - something went wrong during the lookup.
>
> So I don't think you can blanket say this pattern is wrong.
Lots of places also would return ENOENT, I'd argue that is easier to
use..
But yes, I did use the word "suspicion" not blanket wrong :)
Jason
^ permalink raw reply
* [PATCH wireless-next v2 01/28] wifi: iwlwifi: mld: Check for NULL before lookup.
From: greearb @ 2026-03-12 16:59 UTC (permalink / raw)
To: linux-wireless; +Cc: Ben Greear
In-Reply-To: <20260312170026.285494-1-greearb@candelatech.com>
From: Ben Greear <greearb@candelatech.com>
Do not call iwl_mld_sta_from_mac80211(sta) unless we have
verified sta is non NULL.
Signed-off-by: Ben Greear <greearb@candelatech.com>
---
drivers/net/wireless/intel/iwlwifi/mld/agg.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/drivers/net/wireless/intel/iwlwifi/mld/agg.c b/drivers/net/wireless/intel/iwlwifi/mld/agg.c
index 3bf36f8f6874..a757077b0a7a 100644
--- a/drivers/net/wireless/intel/iwlwifi/mld/agg.c
+++ b/drivers/net/wireless/intel/iwlwifi/mld/agg.c
@@ -194,7 +194,7 @@ iwl_mld_reorder(struct iwl_mld *mld, struct napi_struct *napi,
struct iwl_mld_baid_data *baid_data;
struct iwl_mld_reorder_buffer *buffer;
struct iwl_mld_reorder_buf_entry *entries;
- struct iwl_mld_sta *mld_sta = iwl_mld_sta_from_mac80211(sta);
+ struct iwl_mld_sta *mld_sta;
struct iwl_mld_link_sta *mld_link_sta;
u32 reorder = le32_to_cpu(desc->reorder_data);
bool amsdu, last_subframe, is_old_sn, is_dup;
@@ -221,6 +221,8 @@ iwl_mld_reorder(struct iwl_mld *mld, struct napi_struct *napi,
"Got valid BAID without a valid station assigned\n"))
return IWL_MLD_PASS_SKB;
+ mld_sta = iwl_mld_sta_from_mac80211(sta);
+
/* not a data packet */
if (!ieee80211_is_data_qos(hdr->frame_control) ||
is_multicast_ether_addr(hdr->addr1))
--
2.42.0
^ permalink raw reply related
* [PATCH wireless-next v2 00/28] iwlwifi + mac80211 stability
From: greearb @ 2026-03-12 16:59 UTC (permalink / raw)
To: linux-wireless; +Cc: Ben Greear
From: Ben Greear <greearb@candelatech.com>
mac80211 and iwlwifi stability patches from our internal
tree.
General test case is 40 be200 radios attempting to connect and
run max traffic against an AP that doesn't really like that many
eMLSR stations. Firmware crashes, AP rejections, assoc timeouts,
and other problems are seen often, and that seems to hit a lot
of edge cases. Kernel has kasan, lockdep and other debugging
enabled.
This was primarily tested against 6.18.14 stable kernel, but has been
revised to work against wireless-next and it is passing at least the
first hour of tests so far. Likely some problems still remain in
this area.
checkpatch seems mostly satisfied.
v2: Remove 0002 patch that did not actually do anything useful.
Add new patch to check debugfs creation in net/wireless. Hopefully
this solves the syzbot WARNING that was reported.
Ben Greear (28):
wifi: iwlwifi: mld: Check for NULL before lookup.
wifi: iwlwifi: mld: Add check for null vif in stats callback.
wifi: wireless: Check debugfs create return values.
wifi: mac80211: Check debugfs creation return values.
wifi: mac80211: do not fail taking sta to lower state.
wifi: mac80211: Mark sta as uploaded if single transition succeeds.
wifi: mac80211: Fix use-after-free of debugfs inodes.
wifi: mac80211: Debugfs safety checks.
wifi: mac80211: Use warn-on-once in drv_remove_chanctxt
wifi: mac80211: Ensure sta debugfs is not double-freed.
wifi: iwlwifi: mld: Fix stale reference in fw_id_to_link_sta
wifi: iwlwifi: mld: Improve logging in error cases.
wifi: iwlwifi: mld: Remove warning about BAID.
wifi: mac80211: Add dmesg log regarding warn-on in drv-stop.
wifi: iwlwifi: mld: Fix use-after-free of bss_conf
wifi: iwlwifi: mld: Check for null in iwl_mld_wait_sta_txqs_empty
wifi: iwlwifi: mld: use warn-on-once in error path.
wifi: iwlwifi: mld: Use warn-on-once in emlsr exit logic.
wifi: iwlwifi: mld: Improve error message in rx path.
wifi: iwlwifi: mld: Improve logging message.
wifi: iwlwifi: mld: Protect from null mld_sta
wifi: mac80211: Add force-cleanup call to driver.
wifi: iwlwifi: mld: Support force-cleanup op
wifi: iwlwifi: mld: Fix NPE in flush logic.
wifi: iwlwifi: mld: Fix bad return address in tx code.
wifi: mac80211: Ensure link work-items are only initialized once.
wifi: iwlwifi: mld: Convert to WARN_ONCE in link removal path.
wifi: mac80211: Decrease WARN spam.
drivers/net/wireless/intel/iwlwifi/mld/agg.c | 20 +++-
drivers/net/wireless/intel/iwlwifi/mld/link.c | 42 +++++--
.../net/wireless/intel/iwlwifi/mld/mac80211.c | 19 +++-
drivers/net/wireless/intel/iwlwifi/mld/mlo.c | 5 +-
drivers/net/wireless/intel/iwlwifi/mld/rx.c | 4 +-
drivers/net/wireless/intel/iwlwifi/mld/sta.c | 20 +++-
drivers/net/wireless/intel/iwlwifi/mld/sta.h | 2 +-
.../net/wireless/intel/iwlwifi/mld/stats.c | 2 +-
drivers/net/wireless/intel/iwlwifi/mld/tx.h | 2 +
include/net/mac80211.h | 7 ++
net/mac80211/debugfs.c | 11 ++
net/mac80211/debugfs_key.c | 6 +
net/mac80211/debugfs_netdev.c | 106 +++++++++++++++++-
net/mac80211/debugfs_sta.c | 15 +++
net/mac80211/driver-ops.c | 10 +-
net/mac80211/driver-ops.h | 12 +-
net/mac80211/ieee80211_i.h | 1 +
net/mac80211/link.c | 29 +++--
net/mac80211/sta_info.c | 8 +-
net/mac80211/util.c | 8 +-
net/wireless/core.c | 11 ++
21 files changed, 296 insertions(+), 44 deletions(-)
--
2.42.0
^ permalink raw reply
* [PATCH wireless-next v2 02/28] wifi: iwlwifi: mld: Add check for null vif in stats callback.
From: greearb @ 2026-03-12 17:00 UTC (permalink / raw)
To: linux-wireless; +Cc: Ben Greear
In-Reply-To: <20260312170026.285494-1-greearb@candelatech.com>
From: Ben Greear <greearb@candelatech.com>
A crash was seen in this area, protect against null.
Signed-off-by: Ben Greear <greearb@candelatech.com>
---
drivers/net/wireless/intel/iwlwifi/mld/stats.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/net/wireless/intel/iwlwifi/mld/stats.c b/drivers/net/wireless/intel/iwlwifi/mld/stats.c
index 7b8709716324..8d6bd7219b94 100644
--- a/drivers/net/wireless/intel/iwlwifi/mld/stats.c
+++ b/drivers/net/wireless/intel/iwlwifi/mld/stats.c
@@ -415,7 +415,7 @@ iwl_mld_process_per_link_stats(struct iwl_mld *mld,
bss_conf = wiphy_dereference(mld->wiphy,
mld->fw_id_to_bss_conf[fw_id]);
- if (!bss_conf || bss_conf->vif->type != NL80211_IFTYPE_STATION)
+ if (!bss_conf || !bss_conf->vif || bss_conf->vif->type != NL80211_IFTYPE_STATION)
continue;
link_stats = &per_link[fw_id];
--
2.42.0
^ permalink raw reply related
* [PATCH wireless-next v2 04/28] wifi: mac80211: Check debugfs creation return values.
From: greearb @ 2026-03-12 17:00 UTC (permalink / raw)
To: linux-wireless; +Cc: Ben Greear
In-Reply-To: <20260312170026.285494-1-greearb@candelatech.com>
From: Ben Greear <greearb@candelatech.com>
Add return error checking for the debugfs directory create
calls. Assign error pointers to NULL instead of potential error
codes that the create logic may return.
Signed-off-by: Ben Greear <greearb@candelatech.com>
---
net/mac80211/debugfs.c | 11 +++++++++++
net/mac80211/debugfs_key.c | 6 ++++++
net/mac80211/debugfs_netdev.c | 33 +++++++++++++++++++++++++++++++++
net/mac80211/debugfs_sta.c | 15 +++++++++++++++
4 files changed, 65 insertions(+)
diff --git a/net/mac80211/debugfs.c b/net/mac80211/debugfs.c
index e8d0a8b71d59..1f428f8a7633 100644
--- a/net/mac80211/debugfs.c
+++ b/net/mac80211/debugfs.c
@@ -680,6 +680,12 @@ void debugfs_hw_add(struct ieee80211_local *local)
return;
local->debugfs.keys = debugfs_create_dir("keys", phyd);
+ if (IS_ERR(local->debugfs.keys)) {
+ pr_err("Failed to create local keys debugfs dir, rv: %ld phyd: 0x%px\n",
+ (long)(local->debugfs.keys), phyd);
+ local->debugfs.keys = NULL;
+ return;
+ }
DEBUGFS_ADD(total_ps_buffered);
DEBUGFS_ADD(wep_iv);
@@ -705,6 +711,11 @@ void debugfs_hw_add(struct ieee80211_local *local)
phyd, &local->aql_threshold);
statsd = debugfs_create_dir("statistics", phyd);
+ if (IS_ERR(statsd)) {
+ pr_err("Failed to create local stats debugfs dir, rv: %ld phyd: 0x%px\n",
+ (long)(statsd), phyd);
+ return;
+ }
#ifdef CONFIG_MAC80211_DEBUG_COUNTERS
DEBUGFS_STATS_ADD(dot11TransmittedFragmentCount);
diff --git a/net/mac80211/debugfs_key.c b/net/mac80211/debugfs_key.c
index 117f58af5ff9..670bcfa8c4ed 100644
--- a/net/mac80211/debugfs_key.c
+++ b/net/mac80211/debugfs_key.c
@@ -335,6 +335,12 @@ void ieee80211_debugfs_key_add(struct ieee80211_key *key)
keycount++;
key->debugfs.dir = debugfs_create_dir(buf,
key->local->debugfs.keys);
+ if (IS_ERR(key->debugfs.dir)) {
+ pr_err("Failed to create key debugfs dir, rv: %ld phyd: 0x%px\n",
+ (long)(key->debugfs.dir), key->local->debugfs.keys);
+ key->debugfs.dir = NULL;
+ return;
+ }
sta = key->sta;
if (sta) {
diff --git a/net/mac80211/debugfs_netdev.c b/net/mac80211/debugfs_netdev.c
index f3c6a41e4911..51d2ae232a85 100644
--- a/net/mac80211/debugfs_netdev.c
+++ b/net/mac80211/debugfs_netdev.c
@@ -882,6 +882,11 @@ static void add_mesh_stats(struct ieee80211_sub_if_data *sdata)
{
struct dentry *dir = debugfs_create_dir("mesh_stats",
sdata->vif.debugfs_dir);
+ if (IS_ERR(dir)) {
+ sdata_err(sdata, "Failed to create mesh stats dir, rv: %ld vif dir: 0x%px\n",
+ (long)(dir), sdata->vif.debugfs_dir);
+ return;
+ }
#define MESHSTATS_ADD(name)\
debugfs_create_file(#name, 0400, dir, sdata, &name##_ops)
@@ -897,6 +902,11 @@ static void add_mesh_config(struct ieee80211_sub_if_data *sdata)
{
struct dentry *dir = debugfs_create_dir("mesh_config",
sdata->vif.debugfs_dir);
+ if (IS_ERR(dir)) {
+ sdata_err(sdata, "Failed to create mesh config dir, rv: %ld vif dir: 0x%px\n",
+ (long)(dir), sdata->vif.debugfs_dir);
+ return;
+ }
#define MESHPARAMS_ADD(name) \
debugfs_create_file(#name, 0600, dir, sdata, &name##_ops)
@@ -1003,10 +1013,25 @@ static void ieee80211_debugfs_add_netdev(struct ieee80211_sub_if_data *sdata,
sprintf(buf, "netdev:%s", sdata->name);
sdata->vif.debugfs_dir = debugfs_create_dir(buf,
sdata->local->hw.wiphy->debugfsdir);
+
+ if (IS_ERR(sdata->vif.debugfs_dir)) {
+ sdata_err(sdata, "Failed to create netdev dir, rv: %ld name: %s wiphy dir: 0x%px\n",
+ (long)(sdata->vif.debugfs_dir), buf, sdata->local->hw.wiphy->debugfsdir);
+ sdata->vif.debugfs_dir = NULL;
+ return;
+ }
+
/* deflink also has this */
sdata->deflink.debugfs_dir = sdata->vif.debugfs_dir;
+
sdata->debugfs.subdir_stations = debugfs_create_dir("stations",
sdata->vif.debugfs_dir);
+ if (IS_ERR(sdata->debugfs.subdir_stations)) {
+ sdata_err(sdata, "Failed to create netdev subdir-stations dir, rv: %ld wiphy dir: 0x%px\n",
+ (long)(sdata->debugfs.subdir_stations), sdata->vif.debugfs_dir);
+ sdata->debugfs.subdir_stations = NULL;
+ return;
+ }
add_files(sdata);
if (!mld_vif)
add_link_files(&sdata->deflink, sdata->vif.debugfs_dir);
@@ -1058,6 +1083,14 @@ void ieee80211_link_debugfs_add(struct ieee80211_link_data *link)
debugfs_create_dir(link_dir_name,
link->sdata->vif.debugfs_dir);
+ if (IS_ERR(link->debugfs_dir)) {
+ sdata_err(link->sdata, "Failed to create debugfs dir, rv: %ld link-dir-name: %s vif dir: 0x%px\n",
+ (long)(link->debugfs_dir), link_dir_name,
+ link->sdata->vif.debugfs_dir);
+ link->debugfs_dir = NULL;
+ return;
+ }
+
DEBUGFS_ADD(link->debugfs_dir, addr);
add_link_files(link, link->debugfs_dir);
}
diff --git a/net/mac80211/debugfs_sta.c b/net/mac80211/debugfs_sta.c
index ef75255d47d5..23cb2099e3b3 100644
--- a/net/mac80211/debugfs_sta.c
+++ b/net/mac80211/debugfs_sta.c
@@ -1250,6 +1250,12 @@ void ieee80211_sta_debugfs_add(struct sta_info *sta)
* dir might still be around.
*/
sta->debugfs_dir = debugfs_create_dir(mac, stations_dir);
+ if (IS_ERR(sta->debugfs_dir)) {
+ sdata_err(sdata, "Failed to create sta debugfs dir, rv: %ld name: %s stations dir: 0x%px\n",
+ (long)(sta->debugfs_dir), mac, stations_dir);
+ sta->debugfs_dir = NULL;
+ return;
+ }
DEBUGFS_ADD(flags);
DEBUGFS_ADD(aid);
@@ -1303,6 +1309,15 @@ void ieee80211_link_sta_debugfs_add(struct link_sta_info *link_sta)
debugfs_create_dir(link_dir_name,
link_sta->sta->debugfs_dir);
+ if (IS_ERR(link_sta->debugfs_dir)) {
+ sdata_err(link_sta->sta->sdata,
+ "Failed to create link-sta debugfs dir, rv: %ld name: %s stations dir: 0x%px\n",
+ (long)(link_sta->debugfs_dir), link_dir_name,
+ link_sta->sta->debugfs_dir);
+ link_sta->debugfs_dir = NULL;
+ return;
+ }
+
DEBUGFS_ADD(addr);
} else {
if (WARN_ON(link_sta != &link_sta->sta->deflink))
--
2.42.0
^ permalink raw reply related
* [PATCH wireless-next v2 06/28] wifi: mac80211: Mark sta as uploaded if single transition succeeds.
From: greearb @ 2026-03-12 17:00 UTC (permalink / raw)
To: linux-wireless; +Cc: Ben Greear
In-Reply-To: <20260312170026.285494-1-greearb@candelatech.com>
From: Ben Greear <greearb@candelatech.com>
The hope is that this would allow cleanup code to run properly in
case this fails halfway through.
Signed-off-by: Ben Greear <greearb@candelatech.com>
---
net/mac80211/sta_info.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c
index 4259e9c13ed7..ad211c714dbb 100644
--- a/net/mac80211/sta_info.c
+++ b/net/mac80211/sta_info.c
@@ -836,18 +836,18 @@ static int sta_info_insert_drv_state(struct ieee80211_local *local,
err = drv_sta_state(local, sdata, sta, state, state + 1);
if (err)
break;
- }
-
- if (!err) {
/*
* Drivers using legacy sta_add/sta_remove callbacks only
* get uploaded set to true after sta_add is called.
+ * We are at least somewhat added now.
*/
if (!local->ops->sta_add)
sta->uploaded = true;
- return 0;
}
+ if (!err)
+ return 0;
+
if (sdata->vif.type == NL80211_IFTYPE_ADHOC) {
sdata_info(sdata,
"failed to move IBSS STA %pM to state %d (%d) - keeping it anyway\n",
--
2.42.0
^ permalink raw reply related
* [PATCH wireless-next v2 03/28] wifi: wireless: Check debugfs create return values.
From: greearb @ 2026-03-12 17:00 UTC (permalink / raw)
To: linux-wireless; +Cc: Ben Greear
In-Reply-To: <20260312170026.285494-1-greearb@candelatech.com>
From: Ben Greear <greearb@candelatech.com>
Check for error pointers and warn and assign to NULL in that
case so that mac80211 code does not try to use it to create
debugfs objects inside the invalid wiphy debugfs inode.
Signed-off-by: Ben Greear <greearb@candelatech.com>
---
net/wireless/core.c | 11 +++++++++++
1 file changed, 11 insertions(+)
diff --git a/net/wireless/core.c b/net/wireless/core.c
index 23afc250bc10..16cfc249fde6 100644
--- a/net/wireless/core.c
+++ b/net/wireless/core.c
@@ -1041,6 +1041,12 @@ int wiphy_register(struct wiphy *wiphy)
/* add to debugfs */
rdev->wiphy.debugfsdir = debugfs_create_dir(wiphy_name(&rdev->wiphy),
ieee80211_debugfs_dir);
+ if (IS_ERR(rdev->wiphy.debugfsdir)) {
+ pr_err("Failed to create wiphy.debugfsdir, rv: %ld phyd: 0x%px\n",
+ (long)(rdev->wiphy.debugfsdir), ieee80211_debugfs_dir);
+ rdev->wiphy.debugfsdir = NULL;
+ }
+
if (wiphy->n_radio > 0) {
int idx;
char radio_name[RADIO_DEBUGFSDIR_MAX_LEN];
@@ -1887,6 +1893,11 @@ static int __init cfg80211_init(void)
goto out_fail_nl80211;
ieee80211_debugfs_dir = debugfs_create_dir("ieee80211", NULL);
+ if (IS_ERR(ieee80211_debugfs_dir)) {
+ pr_info("Failed to create ieee80211 debugfs dir, rv: %ld\n",
+ (long)(ieee80211_debugfs_dir));
+ ieee80211_debugfs_dir = NULL;
+ }
err = regulatory_init();
if (err)
--
2.42.0
^ permalink raw reply related
* [PATCH wireless-next v2 05/28] wifi: mac80211: do not fail taking sta to lower state.
From: greearb @ 2026-03-12 17:00 UTC (permalink / raw)
To: linux-wireless; +Cc: Ben Greear
In-Reply-To: <20260312170026.285494-1-greearb@candelatech.com>
From: Ben Greear <greearb@candelatech.com>
If sdata-in-driver-check fails, then we assume STA is definitely
not in the driver, and so going to less connected states should not
fail.
Signed-off-by: Ben Greear <greearb@candelatech.com>
---
net/mac80211/driver-ops.c | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/net/mac80211/driver-ops.c b/net/mac80211/driver-ops.c
index 49753b73aba2..59998d0af3ff 100644
--- a/net/mac80211/driver-ops.c
+++ b/net/mac80211/driver-ops.c
@@ -143,8 +143,12 @@ int drv_sta_state(struct ieee80211_local *local,
lockdep_assert_wiphy(local->hw.wiphy);
sdata = get_bss_sdata(sdata);
- if (!check_sdata_in_driver(sdata))
+ if (!check_sdata_in_driver(sdata)) {
+ /* Going down should not fail in this case. */
+ if (new_state < old_state)
+ return 0;
return -EIO;
+ }
trace_drv_sta_state(local, sdata, &sta->sta, old_state, new_state);
if (local->ops->sta_state) {
--
2.42.0
^ permalink raw reply related
* [PATCH wireless-next v2 07/28] wifi: mac80211: Fix use-after-free of debugfs inodes.
From: greearb @ 2026-03-12 17:00 UTC (permalink / raw)
To: linux-wireless; +Cc: Ben Greear
In-Reply-To: <20260312170026.285494-1-greearb@candelatech.com>
From: Ben Greear <greearb@candelatech.com>
When recursively removing debugfs files, clean up child link
debugfs pointers since the recursive removal will have deleted
their memory. This fixes use-after-free problem when those child
links are eventually cleaned up.
Signed-off-by: Ben Greear <greearb@candelatech.com>
---
net/mac80211/debugfs_netdev.c | 19 +++++++++++++++++++
1 file changed, 19 insertions(+)
diff --git a/net/mac80211/debugfs_netdev.c b/net/mac80211/debugfs_netdev.c
index 51d2ae232a85..bc2da35db4ae 100644
--- a/net/mac80211/debugfs_netdev.c
+++ b/net/mac80211/debugfs_netdev.c
@@ -1039,9 +1039,28 @@ static void ieee80211_debugfs_add_netdev(struct ieee80211_sub_if_data *sdata,
void ieee80211_debugfs_remove_netdev(struct ieee80211_sub_if_data *sdata)
{
+ struct ieee80211_link_data *link;
+ int i;
+
if (!sdata->vif.debugfs_dir)
return;
+ /* In case where there were errors on station creation and maybe
+ * teardown, we may get here with some links still active. We are
+ * about to recursively delete debugfs, so remove any pointers the
+ * links may have.
+ */
+ rcu_read_lock();
+
+ for (i = 0; i < IEEE80211_MLD_MAX_NUM_LINKS; i++) {
+ link = rcu_access_pointer(sdata->link[i]);
+ if (!link)
+ continue;
+
+ link->debugfs_dir = NULL;
+ }
+ rcu_read_unlock();
+
debugfs_remove_recursive(sdata->vif.debugfs_dir);
sdata->vif.debugfs_dir = NULL;
sdata->debugfs.subdir_stations = NULL;
--
2.42.0
^ permalink raw reply related
* [PATCH wireless-next v2 11/28] wifi: iwlwifi: mld: Fix stale reference in fw_id_to_link_sta
From: greearb @ 2026-03-12 17:00 UTC (permalink / raw)
To: linux-wireless; +Cc: Ben Greear
In-Reply-To: <20260312170026.285494-1-greearb@candelatech.com>
From: Ben Greear <greearb@candelatech.com>
If memory cannot be allocated, clear the fw_id_to_link_sta so there
is not a dangling pointer that may later be accessed and cause
use-after-free.
Signed-off-by: Ben Greear <greearb@candelatech.com>
---
drivers/net/wireless/intel/iwlwifi/mld/sta.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/drivers/net/wireless/intel/iwlwifi/mld/sta.c b/drivers/net/wireless/intel/iwlwifi/mld/sta.c
index 6b7a89e050e6..c478cee570a2 100644
--- a/drivers/net/wireless/intel/iwlwifi/mld/sta.c
+++ b/drivers/net/wireless/intel/iwlwifi/mld/sta.c
@@ -540,8 +540,10 @@ iwl_mld_add_link_sta(struct iwl_mld *mld, struct ieee80211_link_sta *link_sta)
mld_link_sta = &mld_sta->deflink;
} else {
mld_link_sta = kzalloc_obj(*mld_link_sta);
- if (!mld_link_sta)
+ if (!mld_link_sta) {
+ RCU_INIT_POINTER(mld->fw_id_to_link_sta[fw_id], NULL);
return -ENOMEM;
+ }
}
mld_link_sta->fw_id = fw_id;
--
2.42.0
^ permalink raw reply related
* [PATCH wireless-next v2 16/28] wifi: iwlwifi: mld: Check for null in iwl_mld_wait_sta_txqs_empty
From: greearb @ 2026-03-12 17:00 UTC (permalink / raw)
To: linux-wireless; +Cc: Ben Greear
In-Reply-To: <20260312170026.285494-1-greearb@candelatech.com>
From: Ben Greear <greearb@candelatech.com>
I saw some crashes here in eMLSR torture test, looks like mld_txq
was NULL, so add check.
Signed-off-by: Ben Greear <greearb@candelatech.com>
---
drivers/net/wireless/intel/iwlwifi/mld/sta.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/net/wireless/intel/iwlwifi/mld/sta.c b/drivers/net/wireless/intel/iwlwifi/mld/sta.c
index 6338ca46f68e..288fc4b7604e 100644
--- a/drivers/net/wireless/intel/iwlwifi/mld/sta.c
+++ b/drivers/net/wireless/intel/iwlwifi/mld/sta.c
@@ -789,7 +789,7 @@ void iwl_mld_wait_sta_txqs_empty(struct iwl_mld *mld, struct ieee80211_sta *sta)
struct iwl_mld_txq *mld_txq =
iwl_mld_txq_from_mac80211(sta->txq[i]);
- if (!mld_txq->status.allocated)
+ if (!mld_txq || !mld_txq->status.allocated)
continue;
iwl_trans_wait_txq_empty(mld->trans, mld_txq->fw_id);
--
2.42.0
^ permalink raw reply related
* [PATCH wireless-next v2 17/28] wifi: iwlwifi: mld: use warn-on-once in error path.
From: greearb @ 2026-03-12 17:00 UTC (permalink / raw)
To: linux-wireless; +Cc: Ben Greear
In-Reply-To: <20260312170026.285494-1-greearb@candelatech.com>
From: Ben Greear <greearb@candelatech.com>
Just splat a WARNING once, and add debug output to indicate
a bit about why it is hitting the warn path.
Signed-off-by: Ben Greear <greearb@candelatech.com>
---
drivers/net/wireless/intel/iwlwifi/mld/agg.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/drivers/net/wireless/intel/iwlwifi/mld/agg.c b/drivers/net/wireless/intel/iwlwifi/mld/agg.c
index 23d55374ef8a..413a8688e4eb 100644
--- a/drivers/net/wireless/intel/iwlwifi/mld/agg.c
+++ b/drivers/net/wireless/intel/iwlwifi/mld/agg.c
@@ -496,7 +496,9 @@ static void iwl_mld_free_reorder_buffer(struct iwl_mld *mld,
* sync internal DELBA notification should trigger a release
* of all frames in the reorder buffer.
*/
- WARN_ON(1);
+ WARN_ON_ONCE(1);
+ IWL_ERR(mld, "free-reorder-buffer problem, rxq: %d num-stored: %d, will purge frames\n",
+ i, reorder_buf->num_stored);
for (int j = 0; j < data->buf_size; j++)
__skb_queue_purge(&entries[j].frames);
--
2.42.0
^ permalink raw reply related
* [PATCH wireless-next v2 14/28] wifi: mac80211: Add dmesg log regarding warn-on in drv-stop.
From: greearb @ 2026-03-12 17:00 UTC (permalink / raw)
To: linux-wireless; +Cc: Ben Greear
In-Reply-To: <20260312170026.285494-1-greearb@candelatech.com>
From: Ben Greear <greearb@candelatech.com>
And make it WARN_ON_ONCE.
Signed-off-by: Ben Greear <greearb@candelatech.com>
---
net/mac80211/driver-ops.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/net/mac80211/driver-ops.c b/net/mac80211/driver-ops.c
index 59998d0af3ff..397a0281412a 100644
--- a/net/mac80211/driver-ops.c
+++ b/net/mac80211/driver-ops.c
@@ -38,8 +38,10 @@ void drv_stop(struct ieee80211_local *local, bool suspend)
might_sleep();
lockdep_assert_wiphy(local->hw.wiphy);
- if (WARN_ON(!local->started))
+ if (WARN_ON_ONCE(!local->started)) {
+ pr_err("mac80211: drv-stop called but local is not started.\n");
return;
+ }
trace_drv_stop(local, suspend);
local->ops->stop(&local->hw, suspend);
--
2.42.0
^ permalink raw reply related
* [PATCH wireless-next v2 10/28] wifi: mac80211: Ensure sta debugfs is not double-freed.
From: greearb @ 2026-03-12 17:00 UTC (permalink / raw)
To: linux-wireless; +Cc: Ben Greear
In-Reply-To: <20260312170026.285494-1-greearb@candelatech.com>
From: Ben Greear <greearb@candelatech.com>
I saw an instance where use-after-free was found when attempting to
delete sta's debugfs. Add check to netdev debugfs free logic to ensure
any sta's that still exist have nulled out debugfs entries since
netdev is going to do a recursive debugfs delete.
Signed-off-by: Ben Greear <greearb@candelatech.com>
---
net/mac80211/debugfs_netdev.c | 24 ++++++++++++++++++++++++
1 file changed, 24 insertions(+)
diff --git a/net/mac80211/debugfs_netdev.c b/net/mac80211/debugfs_netdev.c
index 000859b8c005..2e4bc34e6c5c 100644
--- a/net/mac80211/debugfs_netdev.c
+++ b/net/mac80211/debugfs_netdev.c
@@ -1063,6 +1063,8 @@ ieee80211_debugfs_clear_link_ptr(struct ieee80211_sub_if_data *sdata,
void ieee80211_debugfs_remove_netdev(struct ieee80211_sub_if_data *sdata)
{
struct ieee80211_link_data *link;
+ struct rhashtable_iter hti;
+ struct sta_info *sta;
struct dentry *dir;
int i;
@@ -1083,6 +1085,28 @@ void ieee80211_debugfs_remove_netdev(struct ieee80211_sub_if_data *sdata)
link->debugfs_dir = NULL;
}
+
+ /* And, same for all stations. See ieee80211_sta_debugfs_add where
+ * they are added to the sdata->debugfs.subdir_stations directory
+ */
+ rhashtable_walk_enter(&sdata->local->sta_hash.ht, &hti);
+ rhashtable_walk_start(&hti);
+
+ while ((sta = rhashtable_walk_next(&hti))) {
+ if (IS_ERR(sta)) {
+ if (PTR_ERR(sta) != -EAGAIN)
+ break;
+ continue;
+ }
+ if (sta->sdata != sdata)
+ continue;
+
+ sta->debugfs_dir = NULL;
+ }
+
+ rhashtable_walk_stop(&hti);
+ rhashtable_walk_exit(&hti);
+
rcu_read_unlock();
dir = sdata->vif.debugfs_dir;
--
2.42.0
^ permalink raw reply related
* [PATCH wireless-next v2 12/28] wifi: iwlwifi: mld: Improve logging in error cases.
From: greearb @ 2026-03-12 17:00 UTC (permalink / raw)
To: linux-wireless; +Cc: Ben Greear
In-Reply-To: <20260312170026.285494-1-greearb@candelatech.com>
From: Ben Greear <greearb@candelatech.com>
To give better understanding of how and when failures
happen.
Signed-off-by: Ben Greear <greearb@candelatech.com>
---
drivers/net/wireless/intel/iwlwifi/mld/sta.c | 11 ++++++++---
1 file changed, 8 insertions(+), 3 deletions(-)
diff --git a/drivers/net/wireless/intel/iwlwifi/mld/sta.c b/drivers/net/wireless/intel/iwlwifi/mld/sta.c
index c478cee570a2..6338ca46f68e 100644
--- a/drivers/net/wireless/intel/iwlwifi/mld/sta.c
+++ b/drivers/net/wireless/intel/iwlwifi/mld/sta.c
@@ -574,7 +574,8 @@ static int iwl_mld_rm_sta_from_fw(struct iwl_mld *mld, u8 fw_sta_id)
WIDE_ID(MAC_CONF_GROUP, STA_REMOVE_CMD),
&cmd);
if (ret)
- IWL_ERR(mld, "Failed to remove station. Id=%d\n", fw_sta_id);
+ IWL_ERR(mld, "Failed to remove station. Id=%d ret: %d\n",
+ fw_sta_id, ret);
return ret;
}
@@ -735,8 +736,10 @@ int iwl_mld_add_sta(struct iwl_mld *mld, struct ieee80211_sta *sta,
int ret;
ret = iwl_mld_init_sta(mld, sta, vif, type);
- if (ret)
+ if (ret) {
+ IWL_ERR(mld, "iwl-mld-add-sta, mld-init-sta failed. ret=%d\n", ret);
return ret;
+ }
/* We could have add only the deflink link_sta, but it will not work
* in the restart case if the single link that is active during
@@ -744,8 +747,10 @@ int iwl_mld_add_sta(struct iwl_mld *mld, struct ieee80211_sta *sta,
*/
for_each_sta_active_link(mld_sta->vif, sta, link_sta, link_id) {
ret = iwl_mld_add_link_sta(mld, link_sta);
- if (ret)
+ if (ret) {
+ IWL_ERR(mld, "iwl-mld-add-sta, mld-add-link-sta failed. ret=%d\n", ret);
goto destroy_sta;
+ }
}
return 0;
--
2.42.0
^ permalink raw reply related
* [PATCH wireless-next v2 08/28] wifi: mac80211: Debugfs safety checks.
From: greearb @ 2026-03-12 17:00 UTC (permalink / raw)
To: linux-wireless; +Cc: Ben Greear
In-Reply-To: <20260312170026.285494-1-greearb@candelatech.com>
From: Ben Greear <greearb@candelatech.com>
Safety checks in case links are not be properly cleaned up at
the time we are removing netdev debugfs. Since link debugfs
is child of netdev debugfs, and we are about to recursively clean
up the netdev tree, be sure to null out any debugfs inode pointers
in the child links.
Root cause of the inode use-after-free is something
different, but this patch may also make system more resiliant.
Signed-off-by: Ben Greear <greearb@candelatech.com>
---
net/mac80211/debugfs_netdev.c | 30 ++++++++++++++++++++++++++++--
1 file changed, 28 insertions(+), 2 deletions(-)
diff --git a/net/mac80211/debugfs_netdev.c b/net/mac80211/debugfs_netdev.c
index bc2da35db4ae..000859b8c005 100644
--- a/net/mac80211/debugfs_netdev.c
+++ b/net/mac80211/debugfs_netdev.c
@@ -1037,9 +1037,33 @@ static void ieee80211_debugfs_add_netdev(struct ieee80211_sub_if_data *sdata,
add_link_files(&sdata->deflink, sdata->vif.debugfs_dir);
}
+static void
+ieee80211_debugfs_clear_link_ptr(struct ieee80211_sub_if_data *sdata,
+ struct dentry *dir)
+{
+ struct ieee80211_link_data *link;
+ int i;
+
+ rcu_read_lock();
+
+ if (sdata->vif.debugfs_dir == dir)
+ sdata->vif.debugfs_dir = NULL;
+
+ for (i = 0; i < IEEE80211_MLD_MAX_NUM_LINKS; i++) {
+ link = rcu_access_pointer(sdata->link[i]);
+ if (!link)
+ continue;
+
+ if (dir == link->debugfs_dir)
+ link->debugfs_dir = NULL;
+ }
+ rcu_read_unlock();
+}
+
void ieee80211_debugfs_remove_netdev(struct ieee80211_sub_if_data *sdata)
{
struct ieee80211_link_data *link;
+ struct dentry *dir;
int i;
if (!sdata->vif.debugfs_dir)
@@ -1061,8 +1085,10 @@ void ieee80211_debugfs_remove_netdev(struct ieee80211_sub_if_data *sdata)
}
rcu_read_unlock();
- debugfs_remove_recursive(sdata->vif.debugfs_dir);
+ dir = sdata->vif.debugfs_dir;
+ debugfs_remove_recursive(dir);
sdata->vif.debugfs_dir = NULL;
+ ieee80211_debugfs_clear_link_ptr(sdata, dir);
sdata->debugfs.subdir_stations = NULL;
}
@@ -1151,7 +1177,7 @@ void ieee80211_link_debugfs_drv_remove(struct ieee80211_link_data *link)
/* Recreate the directory excluding the driver data */
debugfs_remove_recursive(link->debugfs_dir);
- link->debugfs_dir = NULL;
+ ieee80211_debugfs_clear_link_ptr(link->sdata, link->debugfs_dir);
ieee80211_link_debugfs_add(link);
}
--
2.42.0
^ permalink raw reply related
* [PATCH wireless-next v2 15/28] wifi: iwlwifi: mld: Fix use-after-free of bss_conf
From: greearb @ 2026-03-12 17:00 UTC (permalink / raw)
To: linux-wireless; +Cc: Ben Greear
In-Reply-To: <20260312170026.285494-1-greearb@candelatech.com>
From: Ben Greear <greearb@candelatech.com>
In certain failure paths, the driver is not fully configured, and
it fails to find the link object. We still need to remove pointers
to the bss_conf to keep from crashing shortly afterwards.
Search all indices for stale pointer if we cannot do the fast
lookup by ID.
Signed-off-by: Ben Greear <greearb@candelatech.com>
---
drivers/net/wireless/intel/iwlwifi/mld/link.c | 42 +++++++++++++++----
1 file changed, 34 insertions(+), 8 deletions(-)
diff --git a/drivers/net/wireless/intel/iwlwifi/mld/link.c b/drivers/net/wireless/intel/iwlwifi/mld/link.c
index b5430e8a73d6..1e4959ceb3db 100644
--- a/drivers/net/wireless/intel/iwlwifi/mld/link.c
+++ b/drivers/net/wireless/intel/iwlwifi/mld/link.c
@@ -504,23 +504,49 @@ void iwl_mld_remove_link(struct iwl_mld *mld,
struct iwl_mld_vif *mld_vif = iwl_mld_vif_from_mac80211(bss_conf->vif);
struct iwl_mld_link *link = iwl_mld_link_from_mac80211(bss_conf);
bool is_deflink = link == &mld_vif->deflink;
- u8 fw_id = link->fw_id;
+ u16 fw_id;
- if (WARN_ON(!link || link->active))
- return;
+ if (WARN_ON_ONCE(!link)) {
+ IWL_ERR(mld, "Remove nonexistent link, bss_conf: 0x%px link-id: %d\n",
+ bss_conf, bss_conf->link_id);
+ fw_id = 0xffff;
+ } else {
+ fw_id = link->fw_id;
+ }
+
+ /* Not cleaning it up seems worse than cleaning up an active link,
+ * so continue on even in warning case.
+ */
+ if (link && WARN_ON_ONCE(link->active))
+ IWL_ERR(mld, "Removing active link, id: %d\n",
+ bss_conf->link_id);
iwl_mld_rm_link_from_fw(mld, bss_conf);
/* Continue cleanup on failure */
- if (!is_deflink)
+ if (link && !is_deflink)
kfree_rcu(link, rcu_head);
+ rcu_read_lock();
RCU_INIT_POINTER(mld_vif->link[bss_conf->link_id], NULL);
- if (WARN_ON(fw_id >= mld->fw->ucode_capa.num_links))
- return;
-
- RCU_INIT_POINTER(mld->fw_id_to_bss_conf[fw_id], NULL);
+ if (fw_id >= mld->fw->ucode_capa.num_links) {
+ struct ieee80211_bss_conf *tmp_bss_conf;
+ int i;
+
+ /* Search for any existing back-pointer */
+ for (i = 0; i < ARRAY_SIZE(mld->fw_id_to_bss_conf); i++) {
+ tmp_bss_conf = rcu_dereference(mld->fw_id_to_bss_conf[i]);
+ if (tmp_bss_conf == bss_conf) {
+ IWL_ERR(mld, "WARNING: Found bss_conf in fw_id_to_bss_conf[%i], Nulling pointer.\n",
+ i);
+ RCU_INIT_POINTER(mld->fw_id_to_bss_conf[i], NULL);
+ }
+ }
+ } else {
+ RCU_INIT_POINTER(mld->fw_id_to_bss_conf[fw_id], NULL);
+ }
+ rcu_read_unlock();
}
void iwl_mld_handle_missed_beacon_notif(struct iwl_mld *mld,
--
2.42.0
^ permalink raw reply related
* [PATCH wireless-next v2 18/28] wifi: iwlwifi: mld: Use warn-on-once in emlsr exit logic.
From: greearb @ 2026-03-12 17:00 UTC (permalink / raw)
To: linux-wireless; +Cc: Ben Greear
In-Reply-To: <20260312170026.285494-1-greearb@candelatech.com>
From: Ben Greear <greearb@candelatech.com>
Only splat warning once, and improve logging to indicate more
about why it is in the problem state.
Signed-off-by: Ben Greear <greearb@candelatech.com>
---
drivers/net/wireless/intel/iwlwifi/mld/mlo.c | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/drivers/net/wireless/intel/iwlwifi/mld/mlo.c b/drivers/net/wireless/intel/iwlwifi/mld/mlo.c
index f842f5183223..7a37ca64a612 100644
--- a/drivers/net/wireless/intel/iwlwifi/mld/mlo.c
+++ b/drivers/net/wireless/intel/iwlwifi/mld/mlo.c
@@ -164,7 +164,10 @@ static void iwl_mld_check_emlsr_prevention(struct iwl_mld *mld,
* The timeouts are chosen so that this will not happen, i.e.
* IWL_MLD_EMLSR_PREVENT_LONG > IWL_MLD_PREVENT_EMLSR_TIMEOUT
*/
- WARN_ON(mld_vif->emlsr.exit_repeat_count > 3);
+ if (WARN_ON_ONCE(mld_vif->emlsr.exit_repeat_count > 3)) {
+ IWL_ERR(mld, "check-emlsr-prevention exit repeats: %d > 3, blocked-reasons: 0x%x\n",
+ mld_vif->emlsr.exit_repeat_count, mld_vif->emlsr.blocked_reasons);
+ }
}
IWL_DEBUG_EHT(mld,
--
2.42.0
^ permalink raw reply related
* [PATCH wireless-next v2 09/28] wifi: mac80211: Use warn-on-once in drv_remove_chanctxt
From: greearb @ 2026-03-12 17:00 UTC (permalink / raw)
To: linux-wireless; +Cc: Ben Greear
In-Reply-To: <20260312170026.285494-1-greearb@candelatech.com>
From: Ben Greear <greearb@candelatech.com>
But still log it to dmesg.
Signed-off-by: Ben Greear <greearb@candelatech.com>
---
net/mac80211/driver-ops.h | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/net/mac80211/driver-ops.h b/net/mac80211/driver-ops.h
index 51bf3c7822a7..e2283d7dcd1e 100644
--- a/net/mac80211/driver-ops.h
+++ b/net/mac80211/driver-ops.h
@@ -1035,8 +1035,10 @@ static inline void drv_remove_chanctx(struct ieee80211_local *local,
might_sleep();
lockdep_assert_wiphy(local->hw.wiphy);
- if (WARN_ON(!ctx->driver_present))
+ if (WARN_ON_ONCE(!ctx->driver_present)) {
+ pr_err("drv-remove-chanctx, NOT driver_present, not sending request to driver.");
return;
+ }
trace_drv_remove_chanctx(local, ctx);
if (local->ops->remove_chanctx)
--
2.42.0
^ permalink raw reply related
* [PATCH wireless-next v2 13/28] wifi: iwlwifi: mld: Remove warning about BAID.
From: greearb @ 2026-03-12 17:00 UTC (permalink / raw)
To: linux-wireless; +Cc: Ben Greear
In-Reply-To: <20260312170026.285494-1-greearb@candelatech.com>
From: Ben Greear <greearb@candelatech.com>
It seems to be expected behaviour, and is seen fairly often
in testing in adverse conditions, so make it a one-line log
message instead of WARN splat.
Signed-off-by: Ben Greear <greearb@candelatech.com>
---
drivers/net/wireless/intel/iwlwifi/mld/agg.c | 12 +++++++++---
1 file changed, 9 insertions(+), 3 deletions(-)
diff --git a/drivers/net/wireless/intel/iwlwifi/mld/agg.c b/drivers/net/wireless/intel/iwlwifi/mld/agg.c
index a757077b0a7a..23d55374ef8a 100644
--- a/drivers/net/wireless/intel/iwlwifi/mld/agg.c
+++ b/drivers/net/wireless/intel/iwlwifi/mld/agg.c
@@ -216,10 +216,16 @@ iwl_mld_reorder(struct iwl_mld *mld, struct napi_struct *napi,
if (baid == IWL_RX_REORDER_DATA_INVALID_BAID)
return IWL_MLD_PASS_SKB;
- /* no sta yet */
- if (WARN_ONCE(!sta,
- "Got valid BAID without a valid station assigned\n"))
+ /* no sta yet. This happens fairly often, don't WARN_ON about it. */
+ if (!sta) {
+ static bool done_once;
+
+ if (!done_once) {
+ IWL_ERR(mld, "Got valid BAID without a valid station assigned, will not log again.\n");
+ done_once = true;
+ }
return IWL_MLD_PASS_SKB;
+ }
mld_sta = iwl_mld_sta_from_mac80211(sta);
--
2.42.0
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox