* Re: [PATCH v3 19/21] wifi: rtl8xxxu: add hw crypto support for AP mode
From: Bitterblue Smith @ 2026-03-11 22:16 UTC (permalink / raw)
To: Ping-Ke Shih, Martin Kaistra, linux-wireless@vger.kernel.org
Cc: Jes Sorensen, Sebastian Andrzej Siewior
In-Reply-To: <deb687c2fd62467ebcf139acd8aae9c0@realtek.com>
On 11/03/2026 04:38, Ping-Ke Shih wrote:
> Bitterblue Smith <rtl8821cerfe2@gmail.com> wrote:
>> On 25/02/2026 04:28, Ping-Ke Shih wrote:
>>> Martin Kaistra <martin.kaistra@linutronix.de> wrote:
>>>> Am 21.02.26 um 23:09 schrieb Bitterblue Smith:
>>>>> On 22/12/2023 12:14, Martin Kaistra wrote:
>>>>>> Add a custom function for allocating entries in the sec cam. This allows
>>>>>> us to store multiple keys with the same keyidx.
>>>>>>
>>>>>> The maximum number of sec cam entries for 8188f is 16 according to the
>>>>>> vendor driver. Add the number to rtl8xxxu_fileops, so that other chips
>>>>>> which might support more entries, can set a different number there.
>>>>>>
>>>>>> Set the bssid as mac address for group keys instead of just using the
>>>>>> ethernet broadcast address and use BIT(6) in the sec cam ctrl entry
>>>>>> for differentiating them from pairwise keys like in the vendor driver.
>>>>>>
>>>>>> Add the TXDESC_EN_DESC_ID bit and the hw_key_idx to tx
>>>>>> broadcast/multicast packets in AP mode.
>>>>>>
>>>>>> Finally, allow the usage of rtl8xxxu_set_key() for AP mode.
>>>>>>
>>>>>> Signed-off-by: Martin Kaistra <martin.kaistra@linutronix.de>
>>>>>> Reviewed-by: Ping-Ke Shih <pkshih@realtek.com>
>>>>>> ---
>>>>>> .../net/wireless/realtek/rtl8xxxu/rtl8xxxu.h | 5 ++
>>>>>> .../realtek/rtl8xxxu/rtl8xxxu_8188f.c | 1 +
>>>>>> .../wireless/realtek/rtl8xxxu/rtl8xxxu_core.c | 48 +++++++++++++++----
>>>>>> 3 files changed, 44 insertions(+), 10 deletions(-)
>>>>>>
>>>>>> diff --git a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu.h
>>>> b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu.h
>>>>>> index c5e6d8f7d26bd..62e6318bc0924 100644
>>>>>> --- a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu.h
>>>>>> +++ b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu.h
>>>>>> @@ -498,6 +498,7 @@ struct rtl8xxxu_txdesc40 {
>>>>>> #define DESC_RATE_ID_SHIFT 16
>>>>>> #define DESC_RATE_ID_MASK 0xf
>>>>>> #define TXDESC_NAVUSEHDR BIT(20)
>>>>>> +#define TXDESC_EN_DESC_ID BIT(21)
>>>>>> #define TXDESC_SEC_RC4 0x00400000
>>>>>> #define TXDESC_SEC_AES 0x00c00000
>>>>>> #define TXDESC_PKT_OFFSET_SHIFT 26
>>>>>> @@ -1775,6 +1776,7 @@ struct rtl8xxxu_cfo_tracking {
>>>>>> #define RTL8XXXU_MAX_MAC_ID_NUM 128
>>>>>> #define RTL8XXXU_BC_MC_MACID 0
>>>>>> #define RTL8XXXU_BC_MC_MACID1 1
>>>>>> +#define RTL8XXXU_MAX_SEC_CAM_NUM 64
>>>>>>
>>>>>> struct rtl8xxxu_priv {
>>>>>> struct ieee80211_hw *hw;
>>>>>> @@ -1908,6 +1910,7 @@ struct rtl8xxxu_priv {
>>>>>> char led_name[32];
>>>>>> struct led_classdev led_cdev;
>>>>>> DECLARE_BITMAP(mac_id_map, RTL8XXXU_MAX_MAC_ID_NUM);
>>>>>> + DECLARE_BITMAP(cam_map, RTL8XXXU_MAX_SEC_CAM_NUM);
>>>>>> };
>>>>>>
>>>>>> struct rtl8xxxu_sta_info {
>>>>>> @@ -1919,6 +1922,7 @@ struct rtl8xxxu_sta_info {
>>>>>>
>>>>>> struct rtl8xxxu_vif {
>>>>>> int port_num;
>>>>>> + u8 hw_key_idx;
>>>>>> };
>>>>>>
>>>>>> struct rtl8xxxu_rx_urb {
>>>>>> @@ -1993,6 +1997,7 @@ struct rtl8xxxu_fileops {
>>>>>> u16 max_aggr_num;
>>>>>> u8 supports_ap:1;
>>>>>> u16 max_macid_num;
>>>>>> + u16 max_sec_cam_num;
>>>>>> u32 adda_1t_init;
>>>>>> u32 adda_1t_path_on;
>>>>>> u32 adda_2t_path_on_a;
>>>>>> diff --git a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_8188f.c
>>>> b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_8188f.c
>>>>>> index 1e1c8fa194cb8..574a5fe951543 100644
>>>>>> --- a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_8188f.c
>>>>>> +++ b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_8188f.c
>>>>>> @@ -1751,6 +1751,7 @@ struct rtl8xxxu_fileops rtl8188fu_fops = {
>>>>>> .max_aggr_num = 0x0c14,
>>>>>> .supports_ap = 1,
>>>>>> .max_macid_num = 16,
>>>>>> + .max_sec_cam_num = 16,
>>>>>> .adda_1t_init = 0x03c00014,
>>>>>> .adda_1t_path_on = 0x03c00014,
>>>>>> .trxff_boundary = 0x3f7f,
>>>>>> diff --git a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c
>>>> b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c
>>>>>> index ecf54eb8dba61..7aafae9fe76b8 100644
>>>>>> --- a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c
>>>>>> +++ b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c
>>>>>> @@ -4559,8 +4559,10 @@ static void rtl8xxxu_cam_write(struct rtl8xxxu_priv
>> *priv,
>>>>>> * This is a bit of a hack - the lower bits of the cipher
>>>>>> * suite selector happens to match the cipher index in the CAM
>>>>>> */
>>>>>> - addr = key->keyidx << CAM_CMD_KEY_SHIFT;
>>>>>> + addr = key->hw_key_idx << CAM_CMD_KEY_SHIFT;
>>>>>> ctrl = (key->cipher & 0x0f) << 2 | key->keyidx | CAM_WRITE_VALID;
>>>>>> + if (!(key->flags & IEEE80211_KEY_FLAG_PAIRWISE))
>>>>>> + ctrl |= BIT(6);
>>>>>>
>>>>>> for (j = 5; j >= 0; j--) {
>>>>>> switch (j) {
>>>>>> @@ -5546,13 +5548,14 @@ static void rtl8xxxu_tx(struct ieee80211_hw *hw,
>>>>>> struct rtl8xxxu_tx_urb *tx_urb;
>>>>>> struct ieee80211_sta *sta = NULL;
>>>>>> struct ieee80211_vif *vif = tx_info->control.vif;
>>>>>> + struct rtl8xxxu_vif *rtlvif = (struct rtl8xxxu_vif *)vif->drv_priv;
>>>>>> struct device *dev = &priv->udev->dev;
>>>>>> u32 queue, rts_rate;
>>>>>> u16 pktlen = skb->len;
>>>>>> int tx_desc_size = priv->fops->tx_desc_size;
>>>>>> u8 macid;
>>>>>> int ret;
>>>>>> - bool ampdu_enable, sgi = false, short_preamble = false;
>>>>>> + bool ampdu_enable, sgi = false, short_preamble = false, bmc = false;
>>>>>>
>>>>>> if (skb_headroom(skb) < tx_desc_size) {
>>>>>> dev_warn(dev,
>>>>>> @@ -5594,10 +5597,14 @@ static void rtl8xxxu_tx(struct ieee80211_hw *hw,
>>>>>> tx_desc->txdw0 =
>>>>>> TXDESC_OWN | TXDESC_FIRST_SEGMENT |
>> TXDESC_LAST_SEGMENT;
>>>>>> if (is_multicast_ether_addr(ieee80211_get_DA(hdr)) ||
>>>>>> - is_broadcast_ether_addr(ieee80211_get_DA(hdr)))
>>>>>> + is_broadcast_ether_addr(ieee80211_get_DA(hdr))) {
>>>>>> tx_desc->txdw0 |= TXDESC_BROADMULTICAST;
>>>>>> + bmc = true;
>>>>>> + }
>>>>>> +
>>>>>>
>>>>>> tx_desc->txdw1 = cpu_to_le32(queue << TXDESC_QUEUE_SHIFT);
>>>>>> + macid = rtl8xxxu_get_macid(priv, sta);
>>>>>>
>>>>>> if (tx_info->control.hw_key) {
>>>>>> switch (tx_info->control.hw_key->cipher) {
>>>>>> @@ -5612,6 +5619,10 @@ static void rtl8xxxu_tx(struct ieee80211_hw *hw,
>>>>>> default:
>>>>>> break;
>>>>>> }
>>>>>> + if (bmc && rtlvif->hw_key_idx != 0xff) {
>>>>>> + tx_desc->txdw1 |= TXDESC_EN_DESC_ID;
>>>>>> + macid = rtlvif->hw_key_idx;
>>>>>> + }
>>>>>> }
>>>>>>
>>>>>> /* (tx_info->flags & IEEE80211_TX_CTL_AMPDU) && */
>>>>>> @@ -5655,7 +5666,6 @@ static void rtl8xxxu_tx(struct ieee80211_hw *hw,
>>>>>> else
>>>>>> rts_rate = 0;
>>>>>>
>>>>>> - macid = rtl8xxxu_get_macid(priv, sta);
>>>>>> priv->fops->fill_txdesc(hw, hdr, tx_info, tx_desc, sgi,
>> short_preamble,
>>>>>> ampdu_enable, rts_rate, macid);
>>>>>>
>>>>>> @@ -6667,6 +6677,7 @@ static int rtl8xxxu_add_interface(struct ieee80211_hw
>> *hw,
>>>>>>
>>>>>> priv->vifs[port_num] = vif;
>>>>>> rtlvif->port_num = port_num;
>>>>>> + rtlvif->hw_key_idx = 0xff;
>>>>>>
>>>>>> rtl8xxxu_set_linktype(priv, vif->type, port_num);
>>>>>> ether_addr_copy(priv->mac_addr, vif->addr);
>>>>>> @@ -6843,11 +6854,19 @@ static int rtl8xxxu_set_rts_threshold(struct
>> ieee80211_hw *hw, u32 rts)
>>>>>> return 0;
>>>>>> }
>>>>>>
>>>>>> +static int rtl8xxxu_get_free_sec_cam(struct ieee80211_hw *hw)
>>>>>> +{
>>>>>> + struct rtl8xxxu_priv *priv = hw->priv;
>>>>>> +
>>>>>> + return find_first_zero_bit(priv->cam_map,
>> priv->fops->max_sec_cam_num);
>>>>>> +}
>>>>>> +
>>>>>> static int rtl8xxxu_set_key(struct ieee80211_hw *hw, enum set_key_cmd
>> cmd,
>>>>>> struct ieee80211_vif *vif,
>>>>>> struct ieee80211_sta *sta,
>>>>>> struct ieee80211_key_conf *key)
>>>>>> {
>>>>>> + struct rtl8xxxu_vif *rtlvif = (struct rtl8xxxu_vif *)vif->drv_priv;
>>>>>> struct rtl8xxxu_priv *priv = hw->priv;
>>>>>> struct device *dev = &priv->udev->dev;
>>>>>> u8 mac_addr[ETH_ALEN];
>>>>>> @@ -6859,9 +6878,6 @@ static int rtl8xxxu_set_key(struct ieee80211_hw *hw,
>> enum set_key_cmd cmd,
>>>>>> dev_dbg(dev, "%s: cmd %02x, cipher %08x, index %i\n",
>>>>>> __func__, cmd, key->cipher, key->keyidx);
>>>>>>
>>>>>> - if (vif->type != NL80211_IFTYPE_STATION)
>>>>>> - return -EOPNOTSUPP;
>>>>>> -
>>>>>> if (key->keyidx > 3)
>>>>>> return -EOPNOTSUPP;
>>>>>>
>>>>>> @@ -6885,7 +6901,7 @@ static int rtl8xxxu_set_key(struct ieee80211_hw *hw,
>> enum set_key_cmd cmd,
>>>>>> ether_addr_copy(mac_addr, sta->addr);
>>>>>> } else {
>>>>>> dev_dbg(dev, "%s: group key\n", __func__);
>>>>>> - eth_broadcast_addr(mac_addr);
>>>>>> + ether_addr_copy(mac_addr, vif->bss_conf.bssid);
>>>>>> }
>>>>>>
>>>>>> val16 = rtl8xxxu_read16(priv, REG_CR);
>>>>>> @@ -6899,16 +6915,28 @@ static int rtl8xxxu_set_key(struct ieee80211_hw *hw,
>> enum set_key_cmd cmd,
>>>>>>
>>>>>> switch (cmd) {
>>>>>> case SET_KEY:
>>>>>> - key->hw_key_idx = key->keyidx;
>>>>>> +
>>>>>> + retval = rtl8xxxu_get_free_sec_cam(hw);
>>>>>> + if (retval < 0)
>>>>>> + return -EOPNOTSUPP;
>>>>>> +
>>>>>> + key->hw_key_idx = retval;
>>>>>> +
>>>>>> + if (vif->type == NL80211_IFTYPE_AP && !(key->flags &
>> IEEE80211_KEY_FLAG_PAIRWISE))
>>>>>> + rtlvif->hw_key_idx = key->hw_key_idx;
>>>>>> +
>>>>>> key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV;
>>>>>> rtl8xxxu_cam_write(priv, key, mac_addr);
>>>>>> + set_bit(key->hw_key_idx, priv->cam_map);
>>>>>
>>>>> Hi Martin,
>>>>
>>>> Hi Bitterblue,
>>>>
>>>>>
>>>>> It turns out RTL8188CUS and RTL8192CU don't like this patch, specifically
>>>>> when we use iwd. After the WPA2 handshake no more data is transmitted.
>>>>>
>>>>> Before this patch, key->hw_key_idx was the same as key->keyidx. After
>>>>> this patch, when we use iwd, the group key is installed first. It has
>>>>> key->keyidx = 1, but it gets key->hw_key_idx = 0. The pairwise key is
>>>>> installed second. It has key->keyidx = 0, but it gets key->hw_key_idx = 1.
>>>>> Both keyidx and hw_key_idx are passed to the chip in rtl8xxxu_cam_write().
>>>>>
>>>>> It's fine with wpa_supplicant. wpa_supplicant installs the pairwise key
>>>>> first, with key->keyidx = 0, then the group key, with key->keyidx = 1.
>>>>>
>>>>> This patch imitating rtw88 makes the old chips work again with iwd.
>>>>> What do you think?
>>>>
>>>> So you reserve the first 4 entries for group keys and use key->keyidx as
>>>> key->hw_key_idx directly for those, right? Does that work if 2 virtual
>>>> interfaces are used at the same time?
>>>> I will do some tests in the next days, but I suspect this be an issue.
>>>
>>> Ah. I'm not aware that rtl8xxxu can support 2 virtual interfaces, and
>>> only RTL8188FU declares .supports_concurrent = 1, so maybe we can have
>>> special handling for this chip?
>>
>> I would like to enable supports_concurrent for more chips, if I can test
>> this feature.
>>
>>>
>>> I'd share some information about security CAM for reference. Since data is
>>> quite old (10+ years), I can't guarantee all are correct.
>>>
>>> 1. default key switch in rtl8xxxu_set_key()
>>> SEC_CFG_TXBC_USE_DEFKEY and SEC_CFG_RXBC_USE_DEFKEY mean that
>>> broadcast/multicast packets use default key (CAM entries 0~3 for
>>> keyidx 0~3).
>>> For two interfaces case, that'd a problem, so maybe we should use
>>> software encryption/decryption for non-pairwise key.
>>>
>>> val8 = SEC_CFG_TX_SEC_ENABLE | SEC_CFG_TXBC_USE_DEFKEY |
>>> SEC_CFG_RX_SEC_ENABLE | SEC_CFG_RXBC_USE_DEFKEY;
>>> val8 |= SEC_CFG_TX_USE_DEFKEY | SEC_CFG_RX_USE_DEFKEY;
>>> rtl8xxxu_write8(priv, REG_SECURITY_CFG, val8);
>>>
>>> 2. group key (GK) field of security CAM in rtl8xxxu_cam_write()
>>> The group key field of security CAM is BIT(6) which isn't supported
>>> by earlier chips (sorry I have no data about the exact chips).
>>>
>>
>> BIT 6 is used in the rtl8188eu driver, and not used in the rtl8192cu driver,
>> so I assume it's just the older RTL8188CU/RTL8192CU and RTL8723AU that don't
>> support it.
>>
>>> If a chip can support group key field, the CAM layout with default key
>>> enabled for two interfaces (STA-1+AP-1) can be
>>>
>>> STA-1 <-> AP-10
>>> AP-1 <-> STA-20
>>>
>>> CAM GK MAC KEY
>>> 0
>>> 1 1 00: AP-1 (GTK) // should be on entry 0~3 depends on key_idx
>>> 2
>>> 3
>>> 4
>>> 5 1 AP-10 AP-10 (GTK) // can be on any entry after 4
>>> 6
>>>
>>
>> What are the numbers 1, 10, and 20 in "AP-1", "AP-10", "STA-20" ?
>
> Just represent different roles.
>
> For rtl8xxxu, two interfaces are STA-1 and AP-1, and STA-1 connect to AP-10,
> and AP-1 is connected from STA-20.
>
> I don't add pairwise key to above example, because it is simple, just one
> entry to a PTK. Instead, I only list group key in the example.
>
> For AP role (AP-1), it can send broadcast packets to many stations, so
> use default key.
> (but it should not receive a broadcast packet from stations)
>
> For station role (STA-1), it should receive broadcast packets from
> specific AP-10, so add an entry with AP-10's MAC address.
>
Oh, now I understand, thank you.
>>
>>> (pairwise key can be on any entry after 4)
>>>
>>> if (!(key->flags & IEEE80211_KEY_FLAG_PAIRWISE))
>>> ctrl |= BIT(6);
>>>
>>> My perspective are
>>> 1. currently default key is enabled, so we should treat CAM entry 0~3 as
>>> special cases. That means rtl8xxxu_get_free_sec_cam() should be modified
>>> as Bitterblue's version.
>>>
>>> 2. For two interfaces, I guess RTL8188FU can support GK bit, so it'd be worth
>>> to try the method of example 2 above.
>>>
>>> If we want earlier chips can support two interfaces, I think we should
>>> disable default key.
>>
>> Indeed, the rtl8192cu driver (out of kernel) doesn't set SEC_CFG_TXBC_USE_DEFKEY
>> and SEC_CFG_RXBC_USE_DEFKEY when concurrent mode is enabled.
>>
>>> Seemingly, it is not possible that using hardware
>>> crypto when operating one interface and then switching to use software>
>> crypto when operating two interfaces. That means broadcast/multicast
>>> packets should be by software crypto entirely if we want to support two
>>> interfaces.
>>>
>>> 3. I think rtw88 has similar problem for two interfaces.
>>>
>>>>
>>>>>
>>>>> diff --git a/drivers/net/wireless/realtek/rtl8xxxu/core.c
>>>> b/drivers/net/wireless/realtek/rtl8xxxu/core.c
>>>>> index ee278f0548e4..f7b35655bec5 100644
>>>>> --- a/drivers/net/wireless/realtek/rtl8xxxu/core.c
>>>>> +++ b/drivers/net/wireless/realtek/rtl8xxxu/core.c
>>>>> @@ -6942,7 +6942,8 @@ static int rtl8xxxu_get_free_sec_cam(struct
>> ieee80211_hw *hw)
>>>>> {
>>>>> struct rtl8xxxu_priv *priv = hw->priv;
>>>>>
>>>>> - return find_first_zero_bit(priv->cam_map,
>> priv->fops->max_sec_cam_num);
>>>>> + return find_next_zero_bit(priv->cam_map,
>> priv->fops->max_sec_cam_num,
>>>>> + RTL8XXXU_SEC_DEFAULT_KEY_NUM);
>>>>> }
>>>>>
>>>>> static int rtl8xxxu_set_key(struct ieee80211_hw *hw, enum set_key_cmd
>> cmd,
>>>>> @@ -6999,12 +7000,15 @@ static int rtl8xxxu_set_key(struct ieee80211_hw *hw,
>> enum set_key_cmd cmd,
>>>>>
>>>>> switch (cmd) {
>>>>> case SET_KEY:
>>>>> + if (key->flags & IEEE80211_KEY_FLAG_PAIRWISE) {
>>>>> + retval = rtl8xxxu_get_free_sec_cam(hw);
>>>>> + if (retval < 0)
>>>>> + return -EOPNOTSUPP;
>>>>>
>>>>> - retval = rtl8xxxu_get_free_sec_cam(hw);
>>>>> - if (retval < 0)
>>>>> - return -EOPNOTSUPP;
>>>>> -
>>>>> - key->hw_key_idx = retval;
>>>>> + key->hw_key_idx = retval;
>>>>> + } else {
>>>>> + key->hw_key_idx = key->keyidx;
>>>>> + }
>>>>>
>>>>> if (vif->type == NL80211_IFTYPE_AP && !(key->flags &
>> IEEE80211_KEY_FLAG_PAIRWISE))
>>>>> rtlvif->hw_key_idx = key->hw_key_idx;
>>>>> diff --git a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu.h
>>>> b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu.h
>>>>> index 4b05dba22e67..188f4bbe99cd 100644
>>>>> --- a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu.h
>>>>> +++ b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu.h
>>>>> @@ -1788,6 +1788,7 @@ struct rtl8xxxu_cfo_tracking {
>>>>> #define RTL8XXXU_BC_MC_MACID 0
>>>>> #define RTL8XXXU_BC_MC_MACID1 1
>>>>> #define RTL8XXXU_MAX_SEC_CAM_NUM 64
>>>>> +#define RTL8XXXU_SEC_DEFAULT_KEY_NUM 4
>>>>>
>>>>> struct rtl8xxxu_priv {
>>>>> struct ieee80211_hw *hw;
>>>
>
^ permalink raw reply
* Re: [PATCH 49/61] media: Prefer IS_ERR_OR_NULL over manual NULL check
From: Kieran Bingham @ 2026-03-11 23:03 UTC (permalink / raw)
To: 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, lin
Cc: Shuah Khan, Mauro Carvalho Chehab
In-Reply-To: <20260310-b4-is_err_or_null-v1-49-bd63b656022d@avm.de>
Quoting Philipp Hahn (2026-03-10 11:49:15)
> Prefer using IS_ERR_OR_NULL() over using IS_ERR() and a manual NULL
> check.
>
> Change generated with coccinelle.
>
> To: Shuah Khan <skhan@linuxfoundation.org>
> To: Kieran Bingham <kieran.bingham@ideasonboard.com>
> To: Mauro Carvalho Chehab <mchehab@kernel.org>
> Cc: linux-media@vger.kernel.org
> Cc: linux-kernel@vger.kernel.org
> Signed-off-by: Philipp Hahn <phahn-oss@avm.de>
> ---
> drivers/media/test-drivers/vimc/vimc-streamer.c | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/drivers/media/test-drivers/vimc/vimc-streamer.c b/drivers/media/test-drivers/vimc/vimc-streamer.c
> index 15d863f97cbf96b7ca7fbf3d7b6b6ec39fcc8ae3..da5aca50bcb4990c06f28e5a883eb398606991e9 100644
> --- a/drivers/media/test-drivers/vimc/vimc-streamer.c
> +++ b/drivers/media/test-drivers/vimc/vimc-streamer.c
> @@ -167,7 +167,7 @@ static int vimc_streamer_thread(void *data)
> for (i = stream->pipe_size - 1; i >= 0; i--) {
> frame = stream->ved_pipeline[i]->process_frame(
> stream->ved_pipeline[i], frame);
> - if (!frame || IS_ERR(frame))
> + if (IS_ERR_OR_NULL(frame))
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
> break;
> }
> //wait for 60hz
>
> --
> 2.43.0
>
^ permalink raw reply
* [PATCH wireless-next 03/28] wifi: iwlwifi: mld: Add check for null vif in stats callback.
From: greearb @ 2026-03-11 23:07 UTC (permalink / raw)
To: linux-wireless; +Cc: Ben Greear
In-Reply-To: <20260311230730.163348-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 01/28] wifi: iwlwifi: mld: Check for NULL before lookup.
From: greearb @ 2026-03-11 23:07 UTC (permalink / raw)
To: linux-wireless; +Cc: Ben Greear
In-Reply-To: <20260311230730.163348-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 00/28] iwlwifi + mac80211 stability
From: greearb @ 2026-03-11 23:07 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.
Ben Greear (28):
wifi: iwlwifi: mld: Check for NULL before lookup.
wifi: iwlwifi: mld: Fix un-set return value in error case.
wifi: iwlwifi: mld: Add check for null vif in stats callback.
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 | 21 +++-
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 +-
20 files changed, 286 insertions(+), 45 deletions(-)
--
2.42.0
^ permalink raw reply
* [PATCH wireless-next 02/28] wifi: iwlwifi: mld: Fix un-set return value in error case.
From: greearb @ 2026-03-11 23:07 UTC (permalink / raw)
To: linux-wireless; +Cc: Ben Greear
In-Reply-To: <20260311230730.163348-1-greearb@candelatech.com>
From: Ben Greear <greearb@candelatech.com>
Ensure 'err' is set in error return path.
Signed-off-by: Ben Greear <greearb@candelatech.com>
---
drivers/net/wireless/intel/iwlwifi/mld/mac80211.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/net/wireless/intel/iwlwifi/mld/mac80211.c b/drivers/net/wireless/intel/iwlwifi/mld/mac80211.c
index 0c53d6bd9651..d44ec81d2ce4 100644
--- a/drivers/net/wireless/intel/iwlwifi/mld/mac80211.c
+++ b/drivers/net/wireless/intel/iwlwifi/mld/mac80211.c
@@ -2519,7 +2519,7 @@ iwl_mld_change_vif_links(struct ieee80211_hw *hw,
struct ieee80211_bss_conf *link_conf;
u16 removed = old_links & ~new_links;
u16 added = new_links & ~old_links;
- int err;
+ int err = -EINVAL;
lockdep_assert_wiphy(mld->wiphy);
--
2.42.0
^ permalink raw reply related
* [PATCH wireless-next 11/28] wifi: iwlwifi: mld: Fix stale reference in fw_id_to_link_sta
From: greearb @ 2026-03-11 23:07 UTC (permalink / raw)
To: linux-wireless; +Cc: Ben Greear
In-Reply-To: <20260311230730.163348-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 08/28] wifi: mac80211: Debugfs safety checks.
From: greearb @ 2026-03-11 23:07 UTC (permalink / raw)
To: linux-wireless; +Cc: Ben Greear
In-Reply-To: <20260311230730.163348-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 06/28] wifi: mac80211: Mark sta as uploaded if single transition succeeds.
From: greearb @ 2026-03-11 23:07 UTC (permalink / raw)
To: linux-wireless; +Cc: Ben Greear
In-Reply-To: <20260311230730.163348-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 04/28] wifi: mac80211: Check debugfs creation return values.
From: greearb @ 2026-03-11 23:07 UTC (permalink / raw)
To: linux-wireless; +Cc: Ben Greear
In-Reply-To: <20260311230730.163348-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 05/28] wifi: mac80211: do not fail taking sta to lower state.
From: greearb @ 2026-03-11 23:07 UTC (permalink / raw)
To: linux-wireless; +Cc: Ben Greear
In-Reply-To: <20260311230730.163348-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 09/28] wifi: mac80211: Use warn-on-once in drv_remove_chanctxt
From: greearb @ 2026-03-11 23:07 UTC (permalink / raw)
To: linux-wireless; +Cc: Ben Greear
In-Reply-To: <20260311230730.163348-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 14/28] wifi: mac80211: Add dmesg log regarding warn-on in drv-stop.
From: greearb @ 2026-03-11 23:07 UTC (permalink / raw)
To: linux-wireless; +Cc: Ben Greear
In-Reply-To: <20260311230730.163348-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 23/28] wifi: iwlwifi: mld: Support force-cleanup op
From: greearb @ 2026-03-11 23:07 UTC (permalink / raw)
To: linux-wireless; +Cc: Ben Greear
In-Reply-To: <20260311230730.163348-1-greearb@candelatech.com>
From: Ben Greear <greearb@candelatech.com>
This lets mac80211 force the driver to clean up any lingering
configuration, fixing use-after-free in case of unrecoverable
hardware failure.
Signed-off-by: Ben Greear <greearb@candelatech.com>
---
drivers/net/wireless/intel/iwlwifi/mld/mac80211.c | 13 +++++++++++++
1 file changed, 13 insertions(+)
diff --git a/drivers/net/wireless/intel/iwlwifi/mld/mac80211.c b/drivers/net/wireless/intel/iwlwifi/mld/mac80211.c
index badaceb120b3..03810291ed33 100644
--- a/drivers/net/wireless/intel/iwlwifi/mld/mac80211.c
+++ b/drivers/net/wireless/intel/iwlwifi/mld/mac80211.c
@@ -560,6 +560,18 @@ iwl_mld_restart_cleanup(struct iwl_mld *mld)
iwl_mld_ftm_restart_cleanup(mld);
}
+/* mac80211 thinks our driver/firmware/hardware has crashed
+ * and cannot be recovered. Force clean any existing configuration
+ * (stas, etc), as mac80211 will not attempt further cleanup.
+ */
+static void iwl_mld_mac80211_force_cleanup(struct ieee80211_hw *hw)
+{
+ struct iwl_mld *mld = IWL_MAC80211_GET_MLD(hw);
+
+ IWL_ERR(mld, "mac80211-force-cleanup called, calling mld_restart_cleanup.\n");
+ iwl_mld_restart_cleanup(mld);
+}
+
static
int iwl_mld_mac80211_start(struct ieee80211_hw *hw)
{
@@ -2717,6 +2729,7 @@ const struct ieee80211_ops iwl_mld_hw_ops = {
.config = iwl_mld_mac80211_config,
.get_antenna = iwl_mld_get_antenna,
.set_antenna = iwl_mld_set_antenna,
+ .force_cleanup = iwl_mld_mac80211_force_cleanup,
.add_interface = iwl_mld_mac80211_add_interface,
.remove_interface = iwl_mld_mac80211_remove_interface,
.conf_tx = iwl_mld_mac80211_conf_tx,
--
2.42.0
^ permalink raw reply related
* [PATCH wireless-next 19/28] wifi: iwlwifi: mld: Improve error message in rx path.
From: greearb @ 2026-03-11 23:07 UTC (permalink / raw)
To: linux-wireless; +Cc: Ben Greear
In-Reply-To: <20260311230730.163348-1-greearb@candelatech.com>
From: Ben Greear <greearb@candelatech.com>
Print return code that is causing the failure path.
Signed-off-by: Ben Greear <greearb@candelatech.com>
---
drivers/net/wireless/intel/iwlwifi/mld/rx.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/net/wireless/intel/iwlwifi/mld/rx.c b/drivers/net/wireless/intel/iwlwifi/mld/rx.c
index 214dcfde2fb4..f5c20a3aa869 100644
--- a/drivers/net/wireless/intel/iwlwifi/mld/rx.c
+++ b/drivers/net/wireless/intel/iwlwifi/mld/rx.c
@@ -2204,8 +2204,8 @@ void iwl_mld_sync_rx_queues(struct iwl_mld *mld,
ret = wait_event_timeout(mld->rxq_sync.waitq,
READ_ONCE(mld->rxq_sync.state) == 0,
SYNC_RX_QUEUE_TIMEOUT);
- WARN_ONCE(!ret, "RXQ sync failed: state=0x%lx, cookie=%d\n",
- mld->rxq_sync.state, mld->rxq_sync.cookie);
+ WARN_ONCE(!ret, "RXQ sync failed: state=0x%lx, cookie=%d, ret: %d\n",
+ mld->rxq_sync.state, mld->rxq_sync.cookie, ret);
out:
mld->rxq_sync.state = 0;
--
2.42.0
^ permalink raw reply related
* [PATCH wireless-next 07/28] wifi: mac80211: Fix use-after-free of debugfs inodes.
From: greearb @ 2026-03-11 23:07 UTC (permalink / raw)
To: linux-wireless; +Cc: Ben Greear
In-Reply-To: <20260311230730.163348-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 17/28] wifi: iwlwifi: mld: use warn-on-once in error path.
From: greearb @ 2026-03-11 23:07 UTC (permalink / raw)
To: linux-wireless; +Cc: Ben Greear
In-Reply-To: <20260311230730.163348-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 12/28] wifi: iwlwifi: mld: Improve logging in error cases.
From: greearb @ 2026-03-11 23:07 UTC (permalink / raw)
To: linux-wireless; +Cc: Ben Greear
In-Reply-To: <20260311230730.163348-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 10/28] wifi: mac80211: Ensure sta debugfs is not double-freed.
From: greearb @ 2026-03-11 23:07 UTC (permalink / raw)
To: linux-wireless; +Cc: Ben Greear
In-Reply-To: <20260311230730.163348-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 27/28] wifi: iwlwifi: mld: Convert to WARN_ONCE in link removal path.
From: greearb @ 2026-03-11 23:07 UTC (permalink / raw)
To: linux-wireless; +Cc: Ben Greear
In-Reply-To: <20260311230730.163348-1-greearb@candelatech.com>
From: Ben Greear <greearb@candelatech.com>
While the comment indicates this should not happen, it does at least
when firmware is being problematic. Change to WARN_ON_ONCE to
decrease log spam.
Signed-off-by: Ben Greear <greearb@candelatech.com>
---
drivers/net/wireless/intel/iwlwifi/mld/sta.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/net/wireless/intel/iwlwifi/mld/sta.h b/drivers/net/wireless/intel/iwlwifi/mld/sta.h
index 1897b121aae2..44c54e6d68e6 100644
--- a/drivers/net/wireless/intel/iwlwifi/mld/sta.h
+++ b/drivers/net/wireless/intel/iwlwifi/mld/sta.h
@@ -170,7 +170,7 @@ iwl_mld_cleanup_sta(void *data, struct ieee80211_sta *sta)
continue;
/* Should not happen as link removal should always succeed */
- WARN_ON(1);
+ WARN_ON_ONCE(1);
RCU_INIT_POINTER(mld_sta->link[link_id], NULL);
RCU_INIT_POINTER(mld_sta->mld->fw_id_to_link_sta[mld_link_sta->fw_id],
NULL);
--
2.42.0
^ permalink raw reply related
* [PATCH wireless-next 21/28] wifi: iwlwifi: mld: Protect from null mld_sta
From: greearb @ 2026-03-11 23:07 UTC (permalink / raw)
To: linux-wireless; +Cc: Ben Greear
In-Reply-To: <20260311230730.163348-1-greearb@candelatech.com>
From: Ben Greear <greearb@candelatech.com>
Torture tests were crashing here, protect against a null
mld_sta.
Signed-off-by: Ben Greear <greearb@candelatech.com>
---
drivers/net/wireless/intel/iwlwifi/mld/mac80211.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/drivers/net/wireless/intel/iwlwifi/mld/mac80211.c b/drivers/net/wireless/intel/iwlwifi/mld/mac80211.c
index aa4d391ffc00..badaceb120b3 100644
--- a/drivers/net/wireless/intel/iwlwifi/mld/mac80211.c
+++ b/drivers/net/wireless/intel/iwlwifi/mld/mac80211.c
@@ -1911,6 +1911,7 @@ static void iwl_mld_mac80211_flush(struct ieee80211_hw *hw,
iwl_mld_add_txq_list(mld);
for (int i = 0; i < mld->fw->ucode_capa.num_stations; i++) {
+ struct iwl_mld_sta *mld_sta;
struct ieee80211_link_sta *link_sta =
wiphy_dereference(mld->wiphy,
mld->fw_id_to_link_sta[i]);
@@ -1919,7 +1920,8 @@ static void iwl_mld_mac80211_flush(struct ieee80211_hw *hw,
continue;
/* Check that the sta belongs to the given vif */
- if (vif && vif != iwl_mld_sta_from_mac80211(link_sta->sta)->vif)
+ mld_sta = iwl_mld_sta_from_mac80211(link_sta->sta);
+ if (vif && (!mld_sta || vif != mld_sta->vif))
continue;
if (drop)
--
2.42.0
^ permalink raw reply related
* [PATCH wireless-next 25/28] wifi: iwlwifi: mld: Fix bad return address in tx code.
From: greearb @ 2026-03-11 23:07 UTC (permalink / raw)
To: linux-wireless; +Cc: Ben Greear
In-Reply-To: <20260311230730.163348-1-greearb@candelatech.com>
From: Ben Greear <greearb@candelatech.com>
iwl_mld_txq_from_mac80211 was returning the offset into
txq without checking if txq was NULL. In case txq is
NULL, this would return a small, but non NULL pointer.
The safety check in calling code would then treat it
as non-null and attempt to dereference.
Signed-off-by: Ben Greear <greearb@candelatech.com>
---
drivers/net/wireless/intel/iwlwifi/mld/tx.h | 2 ++
1 file changed, 2 insertions(+)
diff --git a/drivers/net/wireless/intel/iwlwifi/mld/tx.h b/drivers/net/wireless/intel/iwlwifi/mld/tx.h
index 520f15f9d33c..8b0da098c25f 100644
--- a/drivers/net/wireless/intel/iwlwifi/mld/tx.h
+++ b/drivers/net/wireless/intel/iwlwifi/mld/tx.h
@@ -45,6 +45,8 @@ static inline void iwl_mld_init_txq(struct iwl_mld_txq *mld_txq)
static inline struct iwl_mld_txq *
iwl_mld_txq_from_mac80211(struct ieee80211_txq *txq)
{
+ if (!txq)
+ return NULL;
return (void *)txq->drv_priv;
}
--
2.42.0
^ permalink raw reply related
* [PATCH wireless-next 16/28] wifi: iwlwifi: mld: Check for null in iwl_mld_wait_sta_txqs_empty
From: greearb @ 2026-03-11 23:07 UTC (permalink / raw)
To: linux-wireless; +Cc: Ben Greear
In-Reply-To: <20260311230730.163348-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 18/28] wifi: iwlwifi: mld: Use warn-on-once in emlsr exit logic.
From: greearb @ 2026-03-11 23:07 UTC (permalink / raw)
To: linux-wireless; +Cc: Ben Greear
In-Reply-To: <20260311230730.163348-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 28/28] wifi: mac80211: Decrease WARN spam.
From: greearb @ 2026-03-11 23:07 UTC (permalink / raw)
To: linux-wireless; +Cc: Ben Greear
In-Reply-To: <20260311230730.163348-1-greearb@candelatech.com>
From: Ben Greear <greearb@candelatech.com>
Comment one of them out, and make another WARN_ONCE.
Signed-off-by: Ben Greear <greearb@candelatech.com>
---
net/mac80211/link.c | 1 -
net/mac80211/util.c | 3 ++-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/net/mac80211/link.c b/net/mac80211/link.c
index 6125e79f67c9..e3a825ea3a04 100644
--- a/net/mac80211/link.c
+++ b/net/mac80211/link.c
@@ -544,7 +544,6 @@ static int _ieee80211_set_active_links(struct ieee80211_sub_if_data *sdata,
ret = drv_change_sta_links(local, sdata, &sta->sta,
old_active | active_links,
active_links);
- WARN_ON_ONCE(ret);
/*
* Do it again, just in case - the driver might very
diff --git a/net/mac80211/util.c b/net/mac80211/util.c
index ec11ee6b8752..df156f8b5211 100644
--- a/net/mac80211/util.c
+++ b/net/mac80211/util.c
@@ -1879,7 +1879,8 @@ int ieee80211_reconfig(struct ieee80211_local *local)
if (suspended)
WARN(1, "Hardware became unavailable upon resume. This could be a software issue prior to suspend or a hardware issue.\n");
else
- WARN(1, "Hardware became unavailable during restart.\n");
+ WARN_ONCE(1, "Hardware became unavailable during restart: %d\n", res);
+
ieee80211_wake_queues_by_reason(hw, IEEE80211_MAX_QUEUE_MAP,
IEEE80211_QUEUE_STOP_REASON_SUSPEND,
false);
--
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