Linux wireless drivers development
 help / color / mirror / Atom feed
* [PATCH] wifi: rtw89: wow: fix unsupported cipher debug messages
From: zhaoguohan @ 2026-07-15  6:08 UTC (permalink / raw)
  To: Ping-Ke Shih, linux-wireless; +Cc: linux-kernel

From: GuoHan Zhao <zhaoguohan@kylinos.cn>

Correct two WoWLAN debug messages to say "unsupported cipher".

Signed-off-by: GuoHan Zhao <zhaoguohan@kylinos.cn>
---
 drivers/net/wireless/realtek/rtw89/wow.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/net/wireless/realtek/rtw89/wow.c b/drivers/net/wireless/realtek/rtw89/wow.c
index 8dadd8df4fc6..a162a8431b6e 100644
--- a/drivers/net/wireless/realtek/rtw89/wow.c
+++ b/drivers/net/wireless/realtek/rtw89/wow.c
@@ -358,7 +358,7 @@ static void rtw89_wow_get_key_info_iter(struct ieee80211_hw *hw,
 		key_info->gtk_keyidx = key->keyidx;
 		break;
 	default:
-		rtw89_debug(rtwdev, RTW89_DBG_WOW, "unsupport cipher %x\n",
+		rtw89_debug(rtwdev, RTW89_DBG_WOW, "unsupported cipher %x\n",
 			    key->cipher);
 		goto err;
 	}
@@ -443,7 +443,7 @@ static void rtw89_wow_set_key_info_iter(struct ieee80211_hw *hw,
 	case WLAN_CIPHER_SUITE_WEP104:
 		break;
 	default:
-		rtw89_debug(rtwdev, RTW89_DBG_WOW, "unsupport cipher %x\n",
+		rtw89_debug(rtwdev, RTW89_DBG_WOW, "unsupported cipher %x\n",
 			    key->cipher);
 		goto err;
 	}

base-commit: 58717b2a1365d06c8c64b72aa948541b53fe31eb
-- 
2.43.0


^ permalink raw reply related

* Re: [PATCH v2 0/3] MIPS: BCM47XX: convert buttons to software nodes
From: Dmitry Torokhov @ 2026-07-15  6:09 UTC (permalink / raw)
  To: Arnd Bergmann, Rafał Miłecki, Michael Büsch,
	Hauke Mehrtens, Thomas Bogendoerfer, Waldemar Brodkorb,
	Bartosz Golaszewski, linux-wireless, linux-kernel, linux-mips,
	Bartosz Golaszewski
In-Reply-To: <ala9C6XMB3-ywpph@waldemar-brodkorb.de>

Hi Waldemar,

On Wed, Jul 15, 2026 at 12:49:47AM +0200, Waldemar Brodkorb wrote:
> Hi,
> Arnd Bergmann wrote,
> 
> > On Mon, Jul 13, 2026, at 23:58, Dmitry Torokhov wrote:
> > > This series converts the legacy gpio-keys platform device on BCM47XX
> > > boards to use software nodes and static properties.
> > >
> > > To do this properly without relying on legacy name-based matching
> > > (which is being removed from gpiolib), we introduce and register
> > > software nodes for the underlying GPIO controllers (BCMA and SSB)
> > > and reference them in the button properties.
> > >
> > > The first two patches add the software nodes to bcma-gpio and
> > > ssb-gpio respectively. The third patch performs the conversion
> > > for the BCM47XX buttons.
> > >
> > > Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
> > > ---
> > > As Johannes mentioned on v1 this best should go through MIPS tree.
> > 
> > Adding Waldemar to Cc. He has recently done some work to
> > get this platform working again in FreeWRT and should
> > be able to test your patches on hardware.
> 
> I normally use LTS kernel on the hardware (Linksys WRT54GS v1.0).
> But for testing I updated to 7.1.3. Attached is the dmesg without
> Dmitry's patches.  Button works, I can go into failsafe mode after
> pressing the reset button on bootup.
> 
> With Dmitry's three patches applied I directly getting into failsafe
> mode without pressing any button. Dmesg looks similar, but I get
> following kernel message:
> platform gpio-keys.0: deferred probe pending: gpio-keys: failed to get gpio
> 
> Looking at /dev I see no /dev/input/event0 device node anymore.
> 
> Attached is the small failsafe script I use on bootup.
> Hope this helps.
> 
> Do I need to change my failsafe script for the new stuff or is
> something else broken now? Do I miss some new kernel config option?
> Or is the patch only for latest Linus git repo.

Thank you very much for testing. I think 7.1 should work. Could you
please apply the test patch below and send me new dmesg? Hopefully I'll
be able to figure out where I messed up.


diff --git a/arch/mips/bcm47xx/buttons.c b/arch/mips/bcm47xx/buttons.c
index 151a4ee2803f..72524dc390dd 100644
--- a/arch/mips/bcm47xx/buttons.c
+++ b/arch/mips/bcm47xx/buttons.c
@@ -521,6 +521,9 @@ bcm47xx_buttons_add(const struct bcm47xx_gpio_key *buttons, int nbuttons)
 		return -ENODEV;
 	}
 
+	pr_info("XXX: bcm47xx_buttons_add called, bus_type=%d, gpio_swnode=%p (&ssb_gpio_swnode=%p)\n",
+		bcm47xx_bus_type, gpio_swnode, &ssb_gpio_swnode);
+
 	/* 1 node for gpio-keys device, 1 node for each button, 1 terminator */
 	const struct software_node **node_group __free(kfree) =
 		kcalloc(1 + nbuttons + 1, sizeof(*node_group), GFP_KERNEL);
diff --git a/drivers/base/swnode.c b/drivers/base/swnode.c
index 869228a65cb3..20f89e6a57f6 100644
--- a/drivers/base/swnode.c
+++ b/drivers/base/swnode.c
@@ -561,8 +561,11 @@ software_node_get_reference_args(const struct fwnode_handle *fwnode,
 	else
 		return -EINVAL;
 
-	if (!refnode)
+	if (!refnode) {
+		pr_info("XXX: software_node_get_reference_args: refnode is NULL for swnode=%p (%s), fwnode=%p\n",
+			ref->swnode, ref->swnode ? ref->swnode->name : "none", ref->fwnode);
 		return -ENOTCONN;
+	}
 
 	if (nargs_prop) {
 		error = fwnode_property_read_u32(refnode, nargs_prop, &nargs_prop_val);
diff --git a/drivers/ssb/driver_gpio.c b/drivers/ssb/driver_gpio.c
index 87922479946c..28de62a42140 100644
--- a/drivers/ssb/driver_gpio.c
+++ b/drivers/ssb/driver_gpio.c
@@ -238,8 +238,10 @@ static int ssb_gpio_chipco_init(struct ssb_bus *bus)
 	chip->to_irq		= ssb_gpio_to_irq;
 #endif
 	chip->ngpio		= 16;
-	if (bus->bustype == SSB_BUSTYPE_SSB)
+	if (bus->bustype == SSB_BUSTYPE_SSB) {
 		chip->fwnode	= software_node_fwnode(&ssb_gpio_swnode);
+		pr_info("XXX: chipcommon chip->fwnode set to %p\n", chip->fwnode);
+	}
 	/* There is just one SoC in one device and its GPIO addresses should be
 	 * deterministic to address them more easily. The other buses could get
 	 * a random base number.
@@ -444,6 +446,7 @@ static int ssb_gpio_extif_init(struct ssb_bus *bus)
 	if (bus->bustype == SSB_BUSTYPE_SSB) {
 		chip->base	= 0;
 		chip->fwnode	= software_node_fwnode(&ssb_gpio_swnode);
+		pr_info("XXX: extif chip->fwnode set to %p\n", chip->fwnode);
 	} else {
 		chip->base	= -1;
 	}
@@ -481,8 +484,10 @@ int ssb_gpio_init(struct ssb_bus *bus)
 	 * one SoC instance in the system, so there are no concerns with
 	 * registration conflicts.
 	 */
+	pr_info("XXX: ssb_gpio_init called, bustype=%d\n", bus->bustype);
 	if (bus->bustype == SSB_BUSTYPE_SSB) {
 		err = software_node_register(&ssb_gpio_swnode);
+		pr_info("XXX: software_node_register(&ssb_gpio_swnode) returned %d\n", err);
 		if (err)
 			return err;
 	}


Thanks.

-- 
Dmitry

^ permalink raw reply related

* RE: [PATCH] wifi: rtw89: wow: fix unsupported cipher debug messages
From: Ping-Ke Shih @ 2026-07-15  6:17 UTC (permalink / raw)
  To: zhaoguohan@kylinos.cn, linux-wireless@vger.kernel.org
  Cc: linux-kernel@vger.kernel.org
In-Reply-To: <20260715060813.476245-1-zhaoguohan@kylinos.cn>

zhaoguohan@kylinos.cn <zhaoguohan@kylinos.cn> wrote:
> From: GuoHan Zhao <zhaoguohan@kylinos.cn>
> 
> Correct two WoWLAN debug messages to say "unsupported cipher".
> 
> Signed-off-by: GuoHan Zhao <zhaoguohan@kylinos.cn>

Acked-by: Ping-Ke Shih <pkshih@realtek.com>



^ permalink raw reply

* [PATCH v2] wifi: ath11k/ath12k: release QMI handles on late init failures
From: Guangshuo Li @ 2026-07-15  6:40 UTC (permalink / raw)
  To: Jeff Johnson, Anilkumar Kolli, Sriram R, Shashidhar Lakkavalli,
	Kalle Valo, Venkateswara Naralasetty, Vasanthakumar Thiagarajan,
	Baochen Qiang, linux-wireless, ath11k, linux-kernel, ath12k
  Cc: Guangshuo Li

ath11k and ath12k initialize their QMI handles before allocating the QMI
event workqueues and registering the service lookups.

If either of these later initialization steps fails, the functions
return without releasing the initialized QMI handles, leaking their
resources.

Release the QMI handles on the late failure paths in both drivers.

ath12k_qmi_deinit_service() uses ab->qmi.ab to determine whether QMI
service initialization completed successfully. Set it only after all
initialization steps succeed. Keep the ath11k assignment unchanged
because ath11k does not use it as an initialization-success guard.

Fixes: d5c65159f289 ("ath11k: driver for Qualcomm IEEE 802.11ax devices")
Fixes: 088a099690e4 ("wifi: ath12k: fix error handling in creating hardware group")
Signed-off-by: Guangshuo Li <lgs201920130244@gmail.com>
---
v2:
  - Set ath12k ab->qmi.ab only after QMI service initialization succeeds,
    as suggested by Baochen Qiang.
  - Fix the same late initialization QMI handle leak in ath11k, as
    suggested by Vasanthakumar Thiagarajan.
  - Drop the Reviewed-by tag due to the code changes.

 drivers/net/wireless/ath/ath11k/qmi.c | 10 ++++++++--
 drivers/net/wireless/ath/ath12k/qmi.c | 13 ++++++++++---
 2 files changed, 18 insertions(+), 5 deletions(-)

diff --git a/drivers/net/wireless/ath/ath11k/qmi.c b/drivers/net/wireless/ath/ath11k/qmi.c
index 410a7ee076a0..6e3f82169d24 100644
--- a/drivers/net/wireless/ath/ath11k/qmi.c
+++ b/drivers/net/wireless/ath/ath11k/qmi.c
@@ -3329,7 +3329,8 @@ int ath11k_qmi_init_service(struct ath11k_base *ab)
 	ab->qmi.event_wq = alloc_ordered_workqueue("ath11k_qmi_driver_event", 0);
 	if (!ab->qmi.event_wq) {
 		ath11k_err(ab, "failed to allocate workqueue\n");
-		return -EFAULT;
+		ret = -EFAULT;
+		goto err_release_qmi_handle;
 	}
 
 	INIT_LIST_HEAD(&ab->qmi.event_list);
@@ -3342,9 +3343,14 @@ int ath11k_qmi_init_service(struct ath11k_base *ab)
 	if (ret < 0) {
 		ath11k_warn(ab, "failed to add qmi lookup: %d\n", ret);
 		destroy_workqueue(ab->qmi.event_wq);
-		return ret;
+		goto err_release_qmi_handle;
 	}
 
+	return ret;
+
+err_release_qmi_handle:
+	qmi_handle_release(&ab->qmi.handle);
+
 	return ret;
 }
 
diff --git a/drivers/net/wireless/ath/ath12k/qmi.c b/drivers/net/wireless/ath/ath12k/qmi.c
index fd762b5d7bb5..692f1b2c2031 100644
--- a/drivers/net/wireless/ath/ath12k/qmi.c
+++ b/drivers/net/wireless/ath/ath12k/qmi.c
@@ -4041,7 +4041,6 @@ int ath12k_qmi_init_service(struct ath12k_base *ab)
 
 	memset(&ab->qmi.target, 0, sizeof(struct target_info));
 	memset(&ab->qmi.target_mem, 0, sizeof(struct target_mem_chunk));
-	ab->qmi.ab = ab;
 
 	ab->qmi.target_mem_mode = ab->target_mem_mode;
 	ret = qmi_handle_init(&ab->qmi.handle, ATH12K_QMI_RESP_LEN_MAX,
@@ -4054,7 +4053,8 @@ int ath12k_qmi_init_service(struct ath12k_base *ab)
 	ab->qmi.event_wq = alloc_ordered_workqueue("ath12k_qmi_driver_event", 0);
 	if (!ab->qmi.event_wq) {
 		ath12k_err(ab, "failed to allocate workqueue\n");
-		return -EFAULT;
+		ret = -EFAULT;
+		goto err_release_qmi_handle;
 	}
 
 	INIT_LIST_HEAD(&ab->qmi.event_list);
@@ -4067,9 +4067,16 @@ int ath12k_qmi_init_service(struct ath12k_base *ab)
 	if (ret < 0) {
 		ath12k_warn(ab, "failed to add qmi lookup\n");
 		destroy_workqueue(ab->qmi.event_wq);
-		return ret;
+		goto err_release_qmi_handle;
 	}
 
+	ab->qmi.ab = ab;
+
+	return ret;
+
+err_release_qmi_handle:
+	qmi_handle_release(&ab->qmi.handle);
+
 	return ret;
 }
 
-- 
2.43.0


^ permalink raw reply related

* [PATCH v2] wifi: brcmfmac: set F2 blocksize to 256 for BCM43752
From: LiangCheng Wang @ 2026-07-15  6:49 UTC (permalink / raw)
  To: Arend van Spriel, Kalle Valo, Angus Ainslie
  Cc: Gokul Sivakumar, Wig Cheng, linux-wireless, brcm80211,
	brcm80211-dev-list.pdl, linux-kernel, stable, LiangCheng Wang

The BCM43752 is not reliable with the default 512-byte SDIO function 2
block size: on an i.MX8MP board with an AMPAK AP6275S module at
SDR104 / 200 MHz, an iperf TX stress test kills WLAN within seconds:

  mmc_submit_one: CMD53 sg block write failed -84
  brcmf_sdio_dpc: failed backplane access over SDIO, halting operation

Commit d2587c57ffd8 ("brcmfmac: add 43752 SDIO ids and initialization")
set up the 43752 like the 4373 for the F2 watermark but missed the F2
block size, which the 4373 limits to 256 bytes. The vendor driver
(bcmdhd) also programs a 256-byte F2 block size for this chip and runs
the same hardware without errors.

Group the 43752 with the 4373, matching the F2 watermark handling.
With this change a 10-minute bidirectional iperf3 soak completes with
zero SDIO errors at ~270 Mbit/s in each direction.

Backporting note: kernels before v6.18 name this id
SDIO_DEVICE_ID_BROADCOM_CYPRESS_43752, so on those trees the case
label added by this patch must be adjusted to that name. Cherry-picking
the rename commit 74e2ef72bd4b ("wifi: brcmfmac: fix 43752 SDIO FWVID
incorrectly labelled as Cypress (CYW)") first is not a clean
alternative: on trees before v6.17 its context collides with the 43751
additions, and trees before v6.2 lack the FWVID framework it touches.

Fixes: d2587c57ffd8 ("brcmfmac: add 43752 SDIO ids and initialization")
Cc: stable@vger.kernel.org # see patch description, needs adjustments for <= 6.17
Signed-off-by: LiangCheng Wang <zaq14760@gmail.com>
---
The failure was isolated by testing combinations of scatter-gather
support and F2 block size, all at SDR104 / 200 MHz, with an iperf
multi-stream stress test plus a 5-10 minute bidirectional iperf3 soak:

  sg/glom  F2 blksz  result
  on       512       fatal halt within seconds (CMD53 write -84,
                     "failed backplane access", wlan dead)
  txglom off, 512    survives, but ~14 recoverable CMD53 errors/min
  rx glom on
  off      512       firmware PSM watchdog reset after ~3 minutes
  off      256       0 errors, but TX limited to ~142 Mbit/s
  on       256       0 errors, RX 265 / TX 273 Mbit/s (this patch)

So the corruption tracks the 512-byte block size, not scatter-gather;
glomming only amplifies it. The vendor bcmdhd driver logging "set
sd_f2_blocksize 256" at probe is what pointed at the missing override.

The BCM43751 shares the 43752 firmware handling and F2 watermark case
and may need the same fix, but I have no 43751 hardware to verify.

Tested on:
- i.MX8MP (usdhc SDIO host, AMPAK AP6275S module) with Linux kernel
  6.12.34 plus this patch

Gokul suggested having stable cherry-pick the 74e2ef72bd4b rename
first. I rehearsed that on 6.12.95: the rename does not cherry-pick
cleanly, as its context collides in four files with the 43751
additions from v6.17. The conflicts are small and easy to resolve by
hand, but the prerequisite tag format promises a clean cherry-pick,
so it would not be accurate here. Moreover, the Fixes range goes back
to v5.15, and trees before v6.2 cannot take the rename at all: its
CYW->WCC change touches the FWVID framework, which does not exist
there.

Adjusting the single identifier in this patch instead works the same
way on every affected tree (build-tested on 6.12.95), so I kept that
approach: the stable tag uses the documented "needs adjustments" form
and the details are in the patch description.

Changes in v2:
- Rewrite the stable tag in the stable-kernel-rules.rst "needs
  adjustments" form (Arend)
- Add a backporting note to the patch description: adjust the id name
  for kernels before v6.18, rather than cherry-picking the rename
  first (Gokul)
- Link to v1: https://lore.kernel.org/r/20260713-b43752-f2-blksz-v1-1-8697fcfeaef4@gmail.com
---
 drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c
index d24b80e492e084160e1d085b8c20242de3e07c28..3f7a05c4d27ad4c284a6ecc7f0b014a1e985526d 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c
@@ -911,6 +911,7 @@ int brcmf_sdiod_probe(struct brcmf_sdio_dev *sdiodev)
 		return ret;
 	}
 	switch (sdiodev->func2->device) {
+	case SDIO_DEVICE_ID_BROADCOM_43752:
 	case SDIO_DEVICE_ID_BROADCOM_CYPRESS_4373:
 		f2_blksz = SDIO_4373_FUNC2_BLOCKSIZE;
 		break;

---
base-commit: a13c140cc289c0b7b3770bce5b3ad42ab35074aa
change-id: 20260713-b43752-f2-blksz-efda1de3ede9

Best regards,
-- 
LiangCheng Wang <zaq14760@gmail.com>


^ permalink raw reply related

* [PATCH ath-current] wifi: ath12k: fix frequency range for single-pdev devices
From: Shenghan Gao @ 2026-07-15  6:52 UTC (permalink / raw)
  To: Jeff Johnson
  Cc: Aditya Kumar Singh, Vasanthakumar Thiagarajan, linux-wireless,
	ath12k, linux-kernel

Commit 0d777aa2ca77 ("wifi: ath12k: fix mac pdev frequency range update")
made ath12k_regd_update() handle each supported band independently.
However, it uses WMI band capability values as indices into
pdev->cap.band[]. Those values are bit flags, while cap.band[] is indexed
by enum nl80211_band. As a result, the 2.4 GHz lookup reads the
5 GHz entry, while the 5 GHz lookup reads the 60 GHz entry.

Also, the 5 GHz range is skipped whenever the radio supports 6 GHz. This
is valid when 5 and 6 GHz belong to separate pdevs, but not for single-pdev
devices such as WCN7850, where the same pdev covers both bands. After a
regulatory update, 5 GHz is therefore omitted from ar->freq_range and later
filtered out of the channel list sent to firmware.

On the tested WCN7850, the 11d regulatory update left the frequency range
at 2402-2482 MHz and sent 13 channels to firmware. A subsequent 5 GHz scan
failed with WMI_SCAN_REASON_INTERNAL_FAILURE. With both ranges combined,
the range is 2402-5835 MHz and 26 channels are sent to firmware.

Index cap.band[] with NL80211_BAND_* and update 5 GHz for single-pdev
devices even when 6 GHz is supported.

Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.1.c7-00108-QCAHMTSWPL_V1.0_V2.0_SILICONZ_UPSTREAM-3

Fixes: 0d777aa2ca77 ("wifi: ath12k: fix mac pdev frequency range update")
Cc: stable@vger.kernel.org
Assisted-by: Codex:GPT-5.6 Sol
Signed-off-by: Shenghan Gao <gsh20040816@gmail.com>
---
Testing notes:

- Runtime testing was performed on WCN7850 under the CN regulatory domain.
- 2.4 and 5 GHz scanning and 5 GHz association were verified.
- 6 GHz operation was not tested because it is unavailable under the CN
  regulatory domain.
- QCC2072 was not tested because the hardware was not available.

 drivers/net/wireless/ath/ath12k/reg.c | 7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/drivers/net/wireless/ath/ath12k/reg.c b/drivers/net/wireless/ath/ath12k/reg.c
index 89abf2e87ad1..c3bb1df2b1e2 100644
--- a/drivers/net/wireless/ath/ath12k/reg.c
+++ b/drivers/net/wireless/ath/ath12k/reg.c
@@ -300,7 +300,7 @@ int ath12k_regd_update(struct ath12k *ar, bool init)
 
 	if (supported_bands & WMI_HOST_WLAN_2GHZ_CAP) {
 		if (ab->hw_params->single_pdev_only) {
-			phy_id = ar->pdev->cap.band[WMI_HOST_WLAN_2GHZ_CAP].phy_id;
+			phy_id = ar->pdev->cap.band[NL80211_BAND_2GHZ].phy_id;
 			reg_cap = &ab->hal_reg_cap[phy_id];
 		}
 
@@ -310,9 +310,10 @@ int ath12k_regd_update(struct ath12k *ar, bool init)
 		ath12k_mac_update_freq_range(ar, freq_low, freq_high);
 	}
 
-	if (supported_bands & WMI_HOST_WLAN_5GHZ_CAP && !ar->supports_6ghz) {
+	if (supported_bands & WMI_HOST_WLAN_5GHZ_CAP &&
+	    (!ar->supports_6ghz || ab->hw_params->single_pdev_only)) {
 		if (ab->hw_params->single_pdev_only) {
-			phy_id = ar->pdev->cap.band[WMI_HOST_WLAN_5GHZ_CAP].phy_id;
+			phy_id = ar->pdev->cap.band[NL80211_BAND_5GHZ].phy_id;
 			reg_cap = &ab->hal_reg_cap[phy_id];
 		}
 

base-commit: a1a21995c2e1cc2ca6b2226cfe4f5f018370182a
-- 
2.55.0

^ permalink raw reply related

* Re: [PATCH mt76 v5 16/16] wifi: mt76: mt7996: Add SW path for HW-RRO v3.1
From: Chukun Pan @ 2026-07-15  7:00 UTC (permalink / raw)
  To: lorenzo
  Cc: Bo.Jiao, angelogioacchino.delregno, linux-arm-kernel,
	linux-mediatek, linux-wireless, matthias.bgg, nbd, rex.lu,
	ryder.lee, sean.wang, shayne.chen, sujuan.chen, Chukun Pan
In-Reply-To: <20250909-mt7996-rro-rework-v5-16-7d66f6eb7795@kernel.org>

Hi,

> +	if (dev->mt76.hwrro_mode == MT76_HWRRO_V3_1) {
> +		/* rxdmad_c */
> +		mdev->q_rx[MT_RXQ_RRO_RXDMAD_C].flags = MT_WED_RRO_Q_RXDMAD_C;

This introduces the RRO_Q_RXDMAD_C flag for the MT7992 chipset.
However, the mt76_wed_dma_setup function lacks handling for
MT76_WED_RRO_Q_RXDMAD_C, causing it to return -EINVAL:

[   20.049167] mt7996e 0000:01:00.0: attaching wed device 0 version 3
[   20.114412] platform 15010000.wed: MTK WED WO Firmware Version: ..
[   20.123728] platform 15010000.wed: MTK WED WO Chip ID 00 Region 2
[   20.965401] mt7996e 0000:01:00.0: probe with driver mt7996e failed with error -22

Can you fix this?

Thanks,
Chukun

^ permalink raw reply

* Re: [PATCH mt76 v5 16/16] wifi: mt76: mt7996: Add SW path for HW-RRO v3.1
From: Lorenzo Bianconi @ 2026-07-15  7:46 UTC (permalink / raw)
  To: Chukun Pan
  Cc: Bo.Jiao, angelogioacchino.delregno, linux-arm-kernel,
	linux-mediatek, linux-wireless, matthias.bgg, nbd, rex.lu,
	ryder.lee, sean.wang, shayne.chen, sujuan.chen
In-Reply-To: <20260715070001.1503928-1-amadeus@jmu.edu.cn>

[-- Attachment #1: Type: text/plain, Size: 865 bytes --]

> Hi,

Hi Chukun,

> 
> > +	if (dev->mt76.hwrro_mode == MT76_HWRRO_V3_1) {
> > +		/* rxdmad_c */
> > +		mdev->q_rx[MT_RXQ_RRO_RXDMAD_C].flags = MT_WED_RRO_Q_RXDMAD_C;
> 
> This introduces the RRO_Q_RXDMAD_C flag for the MT7992 chipset.
> However, the mt76_wed_dma_setup function lacks handling for
> MT76_WED_RRO_Q_RXDMAD_C, causing it to return -EINVAL:
> 
> [   20.049167] mt7996e 0000:01:00.0: attaching wed device 0 version 3
> [   20.114412] platform 15010000.wed: MTK WED WO Firmware Version: ..
> [   20.123728] platform 15010000.wed: MTK WED WO Chip ID 00 Region 2
> [   20.965401] mt7996e 0000:01:00.0: probe with driver mt7996e failed with error -22
> 
> Can you fix this?

IIRC WED is not supported for HW RRO3.1 at the moment, it is not just a matter of
fixing mt76_wed_dma_setup().

Regards,
Lorenzo

> 
> Thanks,
> Chukun

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]

^ permalink raw reply

* [PATCH v5] wifi: brcmfmac: add DPP support
From: Jason Huang @ 2026-07-15  8:47 UTC (permalink / raw)
  To: linux-wireless
  Cc: brcm80211, brcm80211-dev-list.pdl, linux-kernel, arend.vanspriel,
	Jason Huang, Kurt Lee
In-Reply-To: <20260708071230.312836-1-Jason.Huang2@infineon.com>

From: Jason Huang <jason.huang2@infineon.com>

Add DPP AKM handling and RSN parsing support. Map DPP to the firmware
wpa_auth value and recognize DPP public action frames in the P2P
action-frame TX path.

Gate sup_wpa programming on firmware supplicant capability. Disable it
only when the selected connection mode does not use firmware supplicant.
This keeps pure SAE and 802.1X firmware-supplicant paths intact while
avoiding stale firmware supplicant state for DPP.

Signed-off-by: Kurt Lee <kurt.lee@cypress.com>
Signed-off-by: Jason Huang <jason.huang2@infineon.com>
---
Changes since v4:

- Drop the pre-existing P2P device vif fixes; they are now a standalone
  wireless patch.
- Keep this patch limited to DPP AKM/RSN parsing and DPP public action frame
  handling.

 .../broadcom/brcm80211/brcmfmac/cfg80211.c    | 151 ++++++++++--------
 .../broadcom/brcm80211/brcmfmac/p2p.c         |  54 +++++--
 .../broadcom/brcm80211/include/brcmu_wifi.h   |   2 +
 3 files changed, 130 insertions(+), 77 deletions(-)

diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
index 4b70845e1a26..d61c3e03a106 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
@@ -8,6 +8,7 @@
 #include <linux/kernel.h>
 #include <linux/etherdevice.h>
 #include <linux/module.h>
+#include <linux/unaligned.h>
 #include <linux/vmalloc.h>
 #include <net/cfg80211.h>
 #include <net/netlink.h>
@@ -2154,6 +2155,9 @@ brcmf_set_key_mgmt(struct net_device *ndev, struct cfg80211_connect_params *sme)
 			val = WPA2_AUTH_PSK | WPA2_AUTH_FT;
 			profile->is_ft = true;
 			break;
+		case WLAN_AKM_SUITE_WFA_DPP:
+			val = WFA_AUTH_DPP;
+			break;
 		default:
 			bphy_err(drvr, "invalid akm suite (%d)\n",
 				 sme->crypto.akm_suites[0]);
@@ -2466,43 +2470,50 @@ brcmf_cfg80211_connect(struct wiphy *wiphy, struct net_device *ndev,
 		goto done;
 	}
 
-	if (sme->crypto.psk &&
-	    profile->use_fwsup != BRCMF_PROFILE_FWSUP_SAE) {
-		if (WARN_ON(profile->use_fwsup != BRCMF_PROFILE_FWSUP_NONE)) {
-			err = -EINVAL;
-			goto done;
-		}
-		brcmf_dbg(INFO, "using PSK offload\n");
-		profile->use_fwsup = BRCMF_PROFILE_FWSUP_PSK;
-	}
-
-	if (profile->use_fwsup != BRCMF_PROFILE_FWSUP_NONE) {
-		/* enable firmware supplicant for this interface */
-		err = brcmf_fil_iovar_int_set(ifp, "sup_wpa", 1);
-		if (err < 0) {
-			bphy_err(drvr, "failed to enable fw supplicant\n");
-			goto done;
+	if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_FWSUP)) {
+		u32 akm = sme->crypto.n_akm_suites ? sme->crypto.akm_suites[0] : 0;
+		bool is_sae_akm = akm == WLAN_AKM_SUITE_SAE ||
+			akm == WLAN_AKM_SUITE_FT_OVER_SAE;
+
+		if (sme->crypto.psk && !is_sae_akm &&
+		    profile->use_fwsup != BRCMF_PROFILE_FWSUP_SAE) {
+			if (WARN_ON(profile->use_fwsup !=
+				    BRCMF_PROFILE_FWSUP_NONE)) {
+				err = -EINVAL;
+				goto done;
+			}
+			brcmf_dbg(INFO, "using PSK offload\n");
+			profile->use_fwsup = BRCMF_PROFILE_FWSUP_PSK;
 		}
-	}
-
-	if (profile->use_fwsup == BRCMF_PROFILE_FWSUP_PSK)
-		err = brcmf_set_pmk(ifp, sme->crypto.psk,
-				    BRCMF_WSEC_MAX_PSK_LEN);
-	else if (profile->use_fwsup == BRCMF_PROFILE_FWSUP_SAE) {
-		/* clean up user-space RSNE */
-		err = brcmf_fil_iovar_data_set(ifp, "wpaie", NULL, 0);
-		if (err) {
-			bphy_err(drvr, "failed to clean up user-space RSNE\n");
-			goto done;
+		if (profile->use_fwsup != BRCMF_PROFILE_FWSUP_NONE) {
+			/* enable firmware supplicant for this interface */
+			err = brcmf_fil_iovar_int_set(ifp, "sup_wpa", 1);
+			if (err < 0) {
+				bphy_err(drvr, "failed to enable fw supplicant\n");
+				goto done;
+			}
+		} else {
+			err = brcmf_fil_iovar_int_set(ifp, "sup_wpa", 0);
 		}
-		err = brcmf_fwvid_set_sae_password(ifp, &sme->crypto);
-		if (!err && sme->crypto.psk)
+		if (profile->use_fwsup == BRCMF_PROFILE_FWSUP_PSK)
 			err = brcmf_set_pmk(ifp, sme->crypto.psk,
 					    BRCMF_WSEC_MAX_PSK_LEN);
+		else if (profile->use_fwsup == BRCMF_PROFILE_FWSUP_SAE &&
+			 sme->crypto.sae_pwd &&
+			 brcmf_feat_is_enabled(ifp, BRCMF_FEAT_SAE)) {
+			/* clean up user-space RSNE */
+			if (brcmf_fil_iovar_data_set(ifp, "wpaie", NULL, 0)) {
+				bphy_err(drvr, "failed to clean up user-space RSNE\n");
+				goto done;
+			}
+			err = brcmf_fwvid_set_sae_password(ifp, &sme->crypto);
+			if (!err && sme->crypto.psk)
+				err = brcmf_set_pmk(ifp, sme->crypto.psk,
+						    BRCMF_WSEC_MAX_PSK_LEN);
+		}
+		if (err)
+			goto done;
 	}
-	if (err)
-		goto done;
-
 	/* Join with specific BSSID and cached SSID
 	 * If SSID is zero join based on BSSID only
 	 */
@@ -4519,6 +4530,11 @@ static bool brcmf_valid_wpa_oui(u8 *oui, bool is_rsn_ie)
 	return (memcmp(oui, WPA_OUI, TLV_OUI_LEN) == 0);
 }
 
+static bool brcmf_valid_dpp_suite(u8 *oui)
+{
+	return get_unaligned_be32(oui) == WLAN_AKM_SUITE_WFA_DPP;
+}
+
 static s32
 brcmf_configure_wpaie(struct brcmf_if *ifp,
 		      const struct brcmf_vs_tlv *wpa_ie,
@@ -4632,42 +4648,47 @@ brcmf_configure_wpaie(struct brcmf_if *ifp,
 		goto exit;
 	}
 	for (i = 0; i < count; i++) {
-		if (!brcmf_valid_wpa_oui(&data[offset], is_rsn_ie)) {
+		if (brcmf_valid_dpp_suite(&data[offset])) {
+			wpa_auth |= WFA_AUTH_DPP;
+			offset += TLV_OUI_LEN;
+		} else if (brcmf_valid_wpa_oui(&data[offset], is_rsn_ie)) {
+			offset += TLV_OUI_LEN;
+			switch (data[offset]) {
+			case RSN_AKM_NONE:
+				brcmf_dbg(TRACE, "RSN_AKM_NONE\n");
+				wpa_auth |= WPA_AUTH_NONE;
+				break;
+			case RSN_AKM_UNSPECIFIED:
+				brcmf_dbg(TRACE, "RSN_AKM_UNSPECIFIED\n");
+				is_rsn_ie ?
+					(wpa_auth |= WPA2_AUTH_UNSPECIFIED) :
+					(wpa_auth |= WPA_AUTH_UNSPECIFIED);
+				break;
+			case RSN_AKM_PSK:
+				brcmf_dbg(TRACE, "RSN_AKM_PSK\n");
+				is_rsn_ie ? (wpa_auth |= WPA2_AUTH_PSK) :
+					    (wpa_auth |= WPA_AUTH_PSK);
+				break;
+			case RSN_AKM_SHA256_PSK:
+				brcmf_dbg(TRACE, "RSN_AKM_MFP_PSK\n");
+				wpa_auth |= WPA2_AUTH_PSK_SHA256;
+				break;
+			case RSN_AKM_SHA256_1X:
+				brcmf_dbg(TRACE, "RSN_AKM_MFP_1X\n");
+				wpa_auth |= WPA2_AUTH_1X_SHA256;
+				break;
+			case RSN_AKM_SAE:
+				brcmf_dbg(TRACE, "RSN_AKM_SAE\n");
+				wpa_auth |= WPA3_AUTH_SAE_PSK;
+				break;
+			default:
+				bphy_err(drvr, "Invalid key mgmt info\n");
+			}
+		} else {
 			err = -EINVAL;
 			bphy_err(drvr, "invalid OUI\n");
 			goto exit;
 		}
-		offset += TLV_OUI_LEN;
-		switch (data[offset]) {
-		case RSN_AKM_NONE:
-			brcmf_dbg(TRACE, "RSN_AKM_NONE\n");
-			wpa_auth |= WPA_AUTH_NONE;
-			break;
-		case RSN_AKM_UNSPECIFIED:
-			brcmf_dbg(TRACE, "RSN_AKM_UNSPECIFIED\n");
-			is_rsn_ie ? (wpa_auth |= WPA2_AUTH_UNSPECIFIED) :
-				    (wpa_auth |= WPA_AUTH_UNSPECIFIED);
-			break;
-		case RSN_AKM_PSK:
-			brcmf_dbg(TRACE, "RSN_AKM_PSK\n");
-			is_rsn_ie ? (wpa_auth |= WPA2_AUTH_PSK) :
-				    (wpa_auth |= WPA_AUTH_PSK);
-			break;
-		case RSN_AKM_SHA256_PSK:
-			brcmf_dbg(TRACE, "RSN_AKM_MFP_PSK\n");
-			wpa_auth |= WPA2_AUTH_PSK_SHA256;
-			break;
-		case RSN_AKM_SHA256_1X:
-			brcmf_dbg(TRACE, "RSN_AKM_MFP_1X\n");
-			wpa_auth |= WPA2_AUTH_1X_SHA256;
-			break;
-		case RSN_AKM_SAE:
-			brcmf_dbg(TRACE, "RSN_AKM_SAE\n");
-			wpa_auth |= WPA3_AUTH_SAE_PSK;
-			break;
-		default:
-			bphy_err(drvr, "Invalid key mgmt info\n");
-		}
 		offset++;
 	}
 
@@ -4687,10 +4708,12 @@ brcmf_configure_wpaie(struct brcmf_if *ifp,
 				 */
 				if (!(wpa_auth & (WPA2_AUTH_PSK_SHA256 |
 						  WPA2_AUTH_1X_SHA256 |
+						  WFA_AUTH_DPP |
 						  WPA3_AUTH_SAE_PSK))) {
 					err = -EINVAL;
 					goto exit;
 				}
+
 				/* Firmware has requirement that WPA2_AUTH_PSK/
 				 * WPA2_AUTH_UNSPECIFIED be set, if SHA256 OUI
 				 * is to be included in the rsn ie.
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.c
index 6e0c90f4718b..58a9738e81ac 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.c
@@ -6,6 +6,7 @@
 #include <linux/netdevice.h>
 #include <linux/etherdevice.h>
 #include <linux/rtnetlink.h>
+#include <linux/unaligned.h>
 #include <net/cfg80211.h>
 
 #include <brcmu_wifi.h>
@@ -44,9 +45,6 @@
 
 #define BRCMF_SCB_TIMEOUT_VALUE	20
 
-#define P2P_VER			9	/* P2P version: 9=WiFi P2P v1.0 */
-#define P2P_PUB_AF_CATEGORY	0x04
-#define P2P_PUB_AF_ACTION	0x09
 #define P2P_AF_CATEGORY		0x7f
 #define P2P_OUI			"\x50\x6F\x9A"	/* P2P OUI */
 #define P2P_OUI_LEN		3		/* P2P OUI length */
@@ -143,10 +141,10 @@ struct brcmf_p2p_scan_le {
 /**
  * struct brcmf_p2p_pub_act_frame - WiFi P2P Public Action Frame
  *
- * @category: P2P_PUB_AF_CATEGORY
- * @action: P2P_PUB_AF_ACTION
+ * @category: WLAN_CATEGORY_PUBLIC
+ * @action: WLAN_PUB_ACTION_VENDOR_SPECIFIC
  * @oui: P2P_OUI
- * @oui_type: OUI type - P2P_VER
+ * @oui_type: OUI type - WLAN_OUI_TYPE_WFA_P2P
  * @subtype: OUI subtype - P2P_TYPE_*
  * @dialog_token: nonzero, identifies req/rsp transaction
  * @elts: Variable length information elements.
@@ -166,7 +164,7 @@ struct brcmf_p2p_pub_act_frame {
  *
  * @category: P2P_AF_CATEGORY
  * @oui: OUI - P2P_OUI
- * @type: OUI Type - P2P_VER
+ * @type: OUI Type - WLAN_OUI_TYPE_WFA_P2P
  * @subtype: OUI Subtype - P2P_AF_*
  * @dialog_token: nonzero, identifies req/resp tranaction
  * @elts: Variable length information elements.
@@ -228,10 +226,38 @@ static bool brcmf_p2p_is_pub_action(void *frame, u32 frame_len)
 	if (frame_len < sizeof(*pact_frm))
 		return false;
 
-	if (pact_frm->category == P2P_PUB_AF_CATEGORY &&
-	    pact_frm->action == P2P_PUB_AF_ACTION &&
-	    pact_frm->oui_type == P2P_VER &&
-	    memcmp(pact_frm->oui, P2P_OUI, P2P_OUI_LEN) == 0)
+	if (pact_frm->category == WLAN_CATEGORY_PUBLIC &&
+	    pact_frm->action == WLAN_PUB_ACTION_VENDOR_SPECIFIC &&
+	    pact_frm->oui_type == WLAN_OUI_TYPE_WFA_P2P &&
+	    get_unaligned_be24(pact_frm->oui) == WLAN_OUI_WFA)
+		return true;
+
+	return false;
+}
+
+/**
+ * brcmf_p2p_is_dpp_pub_action() - true if dpp public type frame.
+ *
+ * @frame: action frame data.
+ * @frame_len: length of action frame data.
+ *
+ * Determine if action frame is dpp public action type
+ */
+static bool brcmf_p2p_is_dpp_pub_action(void *frame, u32 frame_len)
+{
+	struct brcmf_p2p_pub_act_frame *pact_frm;
+
+	if (!frame)
+		return false;
+
+	pact_frm = (struct brcmf_p2p_pub_act_frame *)frame;
+	if (frame_len < sizeof(struct brcmf_p2p_pub_act_frame) - 1)
+		return false;
+
+	if (pact_frm->category == WLAN_CATEGORY_PUBLIC &&
+	    pact_frm->action == WLAN_PUB_ACTION_VENDOR_SPECIFIC &&
+	    pact_frm->oui_type == WLAN_OUI_TYPE_WFA_DPP &&
+	    get_unaligned_be24(pact_frm->oui) == WLAN_OUI_WFA)
 		return true;
 
 	return false;
@@ -257,7 +283,7 @@ static bool brcmf_p2p_is_p2p_action(void *frame, u32 frame_len)
 		return false;
 
 	if (act_frm->category == P2P_AF_CATEGORY &&
-	    act_frm->type  == P2P_VER &&
+	    act_frm->type  == WLAN_OUI_TYPE_WFA_P2P &&
 	    memcmp(act_frm->oui, P2P_OUI, P2P_OUI_LEN) == 0)
 		return true;
 
@@ -1789,7 +1815,9 @@ bool brcmf_p2p_send_action_frame(struct brcmf_cfg80211_info *cfg,
 			goto exit;
 		}
 	} else if (brcmf_p2p_is_p2p_action(action_frame->data,
-					   action_frame_len)) {
+					   action_frame_len) ||
+		   brcmf_p2p_is_dpp_pub_action(action_frame->data,
+					       action_frame_len)) {
 		/* do not configure anything. it will be */
 		/* sent with a default configuration     */
 	} else {
diff --git a/drivers/net/wireless/broadcom/brcm80211/include/brcmu_wifi.h b/drivers/net/wireless/broadcom/brcm80211/include/brcmu_wifi.h
index 7552bdb91991..c465208c4331 100644
--- a/drivers/net/wireless/broadcom/brcm80211/include/brcmu_wifi.h
+++ b/drivers/net/wireless/broadcom/brcm80211/include/brcmu_wifi.h
@@ -233,6 +233,8 @@ static inline bool ac_bitmap_tst(u8 bitmap, int prec)
 
 #define WPA3_AUTH_SAE_PSK	0x40000	/* SAE with 4-way handshake */
 
+#define WFA_AUTH_DPP		0x200000 /* WFA DPP AUTH */
+
 #define DOT11_DEFAULT_RTS_LEN		2347
 #define DOT11_DEFAULT_FRAG_LEN		2346
 

base-commit: 3737936e2be920977aea7d9f7eb8cb4468d700d7
-- 
2.25.1


^ permalink raw reply related

* Re: [PATCH mt76 v5 16/16] wifi: mt76: mt7996: Add SW path for HW-RRO v3.1
From: Chukun Pan @ 2026-07-15  9:00 UTC (permalink / raw)
  To: lorenzo
  Cc: Bo.Jiao, amadeus, angelogioacchino.delregno, linux-arm-kernel,
	linux-mediatek, linux-wireless, matthias.bgg, nbd, rex.lu,
	ryder.lee, sean.wang, shayne.chen, sujuan.chen
In-Reply-To: <alc6xTe4uPIJHQy8@lore-desk>

Hi,

> IIRC WED is not supported for HW RRO3.1 at the moment

Okay, seeing this commit, I mistakenly thought it meant support:
net: mediatek: wed: Introduce MT7992 WED support to MT7988 SoC

Sorry for the noise.

Thanks,
Chukun

^ permalink raw reply

* RE: [PATCH] wifi: rtw89: 8852au: Add support for Mercusys MA72XH
From: Ping-Ke Shih @ 2026-07-15  9:16 UTC (permalink / raw)
  To: Abhishek Tamboli
  Cc: linux-wireless@vger.kernel.org, linux-kernel@vger.kernel.org
In-Reply-To: <9bfdb983981d4bb98a4692ac6f1711f6@realtek.com>

Ping-Ke Shih <pkshih@realtek.com> wrote:
> Abhishek Tamboli <abhishektamboli9@gmail.com> wrote:
> > Add the ID 2c4e:0124 to the rtw_8852au_id_table to
> > support the Mercusys MA72XH usb adapter.
> >
> > Link: https://bugzilla.kernel.org/show_bug.cgi?id=221738
> 
> Not sure why I have no permission to access this. Maybe it gets broken.
> I'll wait a while to see if people will fix it.

I seems that my Windows desktop can't access this link, but
Ubuntu is fine. I have not idea why. 

Anyway, the reporter is still not confirmed if this patch works.
Can you post the update here when getting acked?

Ping-Ke


^ permalink raw reply

* Re: [PATCH v4] wifi: brcmfmac: add DPP support
From: HungTsung Huang @ 2026-07-15  9:22 UTC (permalink / raw)
  To: Arend van Spriel
  Cc: linux-wireless, brcm80211, brcm80211-dev-list.pdl, linux-kernel
In-Reply-To: <20260712223314.2182929-1-arend.vanspriel@broadcom.com>

Hi Arend,

Thanks for the clarification.

Could you please confirm whether it is OK to submit the standalone P2P fix
to wireless in parallel to wireless-next origin/main? My understanding is
that the P2P fix does not need to wait for the DPP support patch to be
accepted, since it fixes pre-existing bugs and the DPP patch no longer
depends on it.

The reason I added:
> > +         p2p->bss_idx[P2PAPI_BSSCFG_DEVICE].vif &&
> >           p2p->bss_idx[P2PAPI_BSSCFG_DEVICE].vif->saved_ie.probe_req_ie_len) {

was that DPP public action frames can be sent through the primary interface
without a P2P device vif being created. The existing peer channel search path
assumed the P2P device vif was always available before accessing saved
Probe Request IEs, which could dereference a NULL vif in that case. However,
I agree this is a pre-existing P2P bug rather than part of DPP support, so I
moved it into the standalone P2P fix patch.

Regards,
Jason

^ permalink raw reply

* Re: [PATCH v2 0/3] MIPS: BCM47XX: convert buttons to software nodes
From: Waldemar Brodkorb @ 2026-07-15 10:16 UTC (permalink / raw)
  To: Dmitry Torokhov
  Cc: Arnd Bergmann, Rafał Miłecki, Michael Büsch,
	Hauke Mehrtens, Thomas Bogendoerfer, Waldemar Brodkorb,
	Bartosz Golaszewski, linux-wireless, linux-kernel, linux-mips,
	Bartosz Golaszewski
In-Reply-To: <alci_45CzdVznaN2@google.com>

[-- Attachment #1: Type: text/plain, Size: 2308 bytes --]

H Dmitry,
Dmitry Torokhov wrote,

> Hi Waldemar,
> 
> On Wed, Jul 15, 2026 at 12:49:47AM +0200, Waldemar Brodkorb wrote:
> > Hi,
> > Arnd Bergmann wrote,
> > 
> > > On Mon, Jul 13, 2026, at 23:58, Dmitry Torokhov wrote:
> > > > This series converts the legacy gpio-keys platform device on BCM47XX
> > > > boards to use software nodes and static properties.
> > > >
> > > > To do this properly without relying on legacy name-based matching
> > > > (which is being removed from gpiolib), we introduce and register
> > > > software nodes for the underlying GPIO controllers (BCMA and SSB)
> > > > and reference them in the button properties.
> > > >
> > > > The first two patches add the software nodes to bcma-gpio and
> > > > ssb-gpio respectively. The third patch performs the conversion
> > > > for the BCM47XX buttons.
> > > >
> > > > Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
> > > > ---
> > > > As Johannes mentioned on v1 this best should go through MIPS tree.
> > > 
> > > Adding Waldemar to Cc. He has recently done some work to
> > > get this platform working again in FreeWRT and should
> > > be able to test your patches on hardware.
> > 
> > I normally use LTS kernel on the hardware (Linksys WRT54GS v1.0).
> > But for testing I updated to 7.1.3. Attached is the dmesg without
> > Dmitry's patches.  Button works, I can go into failsafe mode after
> > pressing the reset button on bootup.
> > 
> > With Dmitry's three patches applied I directly getting into failsafe
> > mode without pressing any button. Dmesg looks similar, but I get
> > following kernel message:
> > platform gpio-keys.0: deferred probe pending: gpio-keys: failed to get gpio
> > 
> > Looking at /dev I see no /dev/input/event0 device node anymore.
> > 
> > Attached is the small failsafe script I use on bootup.
> > Hope this helps.
> > 
> > Do I need to change my failsafe script for the new stuff or is
> > something else broken now? Do I miss some new kernel config option?
> > Or is the patch only for latest Linus git repo.
> 
> Thank you very much for testing. I think 7.1 should work. Could you
> please apply the test patch below and send me new dmesg? Hopefully I'll
> be able to figure out where I messed up.
> 
> Thanks.

Attached. Should we shorten the CC List next time?

best regards
 Waldemar

[-- Attachment #2: dmesg-debug.txt --]
[-- Type: text/plain, Size: 10136 bytes --]

Linux version 7.1.3 (wbx@macbook) (mipsel-freewrt-linux-uclibc-gcc (GCC) 16.1.0, GNU ld (GNU Binutils) 2.46.1) #1 Wed Jul 15 11:24:45 CEST 2026
printk: legacy bootconsole [early0] enabled
CPU0 revision is: 00029007 (Broadcom BMIPS3300)
bcm47xx: Using ssb bus
ssb: Found chip with id 0x4712, rev 0x01 and package 0x00
can not parse nvram name (null)ag0(null) with value 255 got -34
ssb: Sonics Silicon Backplane found at address 0x18000000
Primary instruction cache 8kB, VIPT, 2-way, linesize 16 bytes.
Primary data cache 4kB, 2-way, VIPT, no aliases, linesize 16 bytes
Zone ranges:
  Normal   [mem 0x0000000000000000-0x0000000001ffffff]
Movable zone start for each node
Early memory node ranges
  node   0: [mem 0x0000000000000000-0x0000000001ffffff]
Initmem setup node 0 [mem 0x0000000000000000-0x0000000001ffffff]
pcpu-alloc: s0 r0 d32768 u32768 alloc=1*32768
pcpu-alloc: [0] 0 
Kernel command line: root=/dev/mtdblock4 rootfstype=squashfs init=/etc/preinit noinitrd console=ttyS0,115200
Unknown kernel command line parameters "noinitrd", will be passed to user space.
printk: log buffer data + meta data: 131072 + 409600 = 540672 bytes
Dentry cache hash table entries: 4096 (order: 2, 16384 bytes, linear)
Inode-cache hash table entries: 2048 (order: 1, 8192 bytes, linear)
Built 1 zonelists, mobility grouping on.  Total pages: 8192
mem auto-init: stack:all(zero), heap alloc:off, heap free:off
SLUB: HWalign=32, Order=0-3, MinObjects=0, CPUs=1, Nodes=1
NR_IRQS: 256
MIPS: machine is Linksys WRT54G/GS/GL
clocksource: MIPS: mask: 0xffffffff max_cycles: 0xffffffff, max_idle_ns: 19112604467 ns
sched_clock: 32 bits at 100MHz, resolution 10ns, wraps every 21474836475ns
Console: colour dummy device 80x25
Calibrating delay loop... 198.65 BogoMIPS (lpj=397312)
pid_max: default: 32768 minimum: 301
Mount-cache hash table entries: 1024 (order: 0, 4096 bytes, linear)
Mountpoint-cache hash table entries: 1024 (order: 0, 4096 bytes, linear)
VFS: Finished mounting rootfs on nullfs
Memory: 25676K/32768K available (4009K kernel code, 556K rwdata, 956K rodata, 228K init, 268K bss, 6348K reserved, 0K cma-reserved)
devtmpfs: initialized
clocksource: jiffies: mask: 0xffffffff max_cycles: 0xffffffff, max_idle_ns: 7645041785100000 ns
posixtimers hash table entries: 512 (order: 0, 2048 bytes, linear)
futex hash table entries: 256 (4096 bytes on 1 NUMA nodes, total 4 KiB, linear).
NET: Registered PF_NETLINK/PF_ROUTE protocol family
clocksource: Switched to clocksource MIPS
PCI host bridge to bus 0000:00
pci_bus 0000:00: root bus resource [mem 0x40000000-0x7fffffff]
pci_bus 0000:00: root bus resource [io  0x0100-0x07ff]
pci_bus 0000:00: No busn resource found for root bus, will use [bus 00-ff]
pci 0000:00:00.0: PCI: Fixing up bridge 0000:00:00.0
pci 0000:00:00.0: PCI: Fixing up device 0000:00:00.0
pci 0000:00:00.0: PCI: Fixing latency timer of device 0000:00:00.0 to 168
pci 0000:00:00.0: ssb_pcicore_fixup_pcibridge+0x0/0xf8 took 17901 usecs
pci 0000:00:00.0: [14e4:4712] type 00 class 0x060000 conventional PCI endpoint
pci 0000:00:00.0: BAR 0 [mem 0x00000000-0x00001fff]
pci 0000:00:00.0: BAR 1 [mem 0x00000000-0x07ffffff pref]
pci 0000:00:01.0: [14e4:4712] type 00 class 0x060000 conventional PCI endpoint
pci 0000:00:01.0: BAR 0 [mem 0x00000000-0x00001fff]
pci 0000:00:01.0: BAR 1 [mem 0x00000000-0x07ffffff pref]
pci 0000:00:02.0: [14e4:4712] type 00 class 0x060000 conventional PCI endpoint
pci 0000:00:02.0: BAR 0 [mem 0x00000000-0x00001fff]
pci 0000:00:02.0: BAR 1 [mem 0x00000000-0x07ffffff pref]
pci 0000:00:03.0: [14e4:4712] type 00 class 0x060000 conventional PCI endpoint
pci 0000:00:03.0: BAR 0 [mem 0x00000000-0x00001fff]
pci 0000:00:03.0: BAR 1 [mem 0x00000000-0x07ffffff pref]
pci 0000:00:04.0: [14e4:4712] type 00 class 0x060000 conventional PCI endpoint
pci 0000:00:04.0: BAR 0 [mem 0x00000000-0x00001fff]
pci 0000:00:04.0: BAR 1 [mem 0x00000000-0x07ffffff pref]
pci 0000:00:05.0: [14e4:4712] type 00 class 0x060000 conventional PCI endpoint
pci 0000:00:05.0: BAR 0 [mem 0x00000000-0x00001fff]
pci 0000:00:05.0: BAR 1 [mem 0x00000000-0x07ffffff pref]
pci 0000:00:06.0: [14e4:4712] type 00 class 0x060000 conventional PCI endpoint
pci 0000:00:06.0: BAR 0 [mem 0x00000000-0x00001fff]
pci 0000:00:06.0: BAR 1 [mem 0x00000000-0x07ffffff pref]
pci 0000:00:07.0: [14e4:4712] type 00 class 0x060000 conventional PCI endpoint
pci 0000:00:07.0: BAR 0 [mem 0x00000000-0x00001fff]
pci 0000:00:07.0: BAR 1 [mem 0x00000000-0x07ffffff pref]
pci 0000:00:08.0: [14e4:4712] type 00 class 0x060000 conventional PCI endpoint
pci 0000:00:08.0: BAR 0 [mem 0x00000000-0x00001fff]
pci 0000:00:08.0: BAR 1 [mem 0x00000000-0x07ffffff pref]
pci 0000:00:09.0: [14e4:4712] type 00 class 0x060000 conventional PCI endpoint
pci 0000:00:09.0: BAR 0 [mem 0x00000000-0x00001fff]
pci 0000:00:09.0: BAR 1 [mem 0x00000000-0x07ffffff pref]
pci 0000:00:0a.0: [14e4:4712] type 00 class 0x060000 conventional PCI endpoint
pci 0000:00:0a.0: BAR 0 [mem 0x00000000-0x00001fff]
pci 0000:00:0a.0: BAR 1 [mem 0x00000000-0x07ffffff pref]
pci 0000:00:0b.0: [14e4:4712] type 00 class 0x060000 conventional PCI endpoint
pci 0000:00:0b.0: BAR 0 [mem 0x00000000-0x00001fff]
pci 0000:00:0b.0: BAR 1 [mem 0x00000000-0x07ffffff pref]
pci 0000:00:0c.0: [14e4:4712] type 00 class 0x060000 conventional PCI endpoint
pci 0000:00:0c.0: BAR 0 [mem 0x00000000-0x00001fff]
pci 0000:00:0c.0: BAR 1 [mem 0x00000000-0x07ffffff pref]
pci 0000:00:0d.0: [14e4:4712] type 00 class 0x060000 conventional PCI endpoint
pci 0000:00:0d.0: BAR 0 [mem 0x00000000-0x00001fff]
pci 0000:00:0d.0: BAR 1 [mem 0x00000000-0x07ffffff pref]
pci 0000:00:0e.0: [14e4:4712] type 00 class 0x060000 conventional PCI endpoint
pci 0000:00:0e.0: BAR 0 [mem 0x00000000-0x00001fff]
pci 0000:00:0e.0: BAR 1 [mem 0x00000000-0x07ffffff pref]
pci 0000:00:0f.0: [14e4:4712] type 00 class 0x060000 conventional PCI endpoint
pci 0000:00:0f.0: BAR 0 [mem 0x00000000-0x00001fff]
pci 0000:00:0f.0: BAR 1 [mem 0x00000000-0x07ffffff pref]
pci_bus 0000:00: busn_res: [bus 00-ff] end is updated to 00
ssb: XXX: ssb_gpio_init called, bustype=0
ssb: XXX: software_node_register(&ssb_gpio_swnode) returned 0
ssb: XXX: chipcommon chip->fwnode set to (ptrval)
gpio gpiochip0: Static allocation of GPIO base is deprecated, use dynamic allocation.
NET: Registered PF_INET protocol family
IP idents hash table entries: 2048 (order: 2, 16384 bytes, linear)
tcp_listen_portaddr_hash hash table entries: 1024 (order: 0, 4096 bytes, linear)
Table-perturb hash table entries: 65536 (order: 6, 262144 bytes, linear)
TCP established hash table entries: 1024 (order: 0, 4096 bytes, linear)
TCP bind hash table entries: 1024 (order: 1, 8192 bytes, linear)
TCP: Hash tables configured (established 1024 bind 1024)
UDP hash table entries: 256 (order: 1, 8192 bytes, linear)
NET: Registered PF_UNIX/PF_LOCAL protocol family
PCI: CLS 0 bytes, default 16
bcm47xx: XXX: bcm47xx_buttons_add called, bus_type=0, gpio_swnode=(ptrval) (&ssb_gpio_swnode=(ptrval))
Initialise system trusted keyrings
workingset: timestamp_bits=30 (anon: 26) max_order=13 bucket_order=0 (anon: 0)
squashfs: version 4.0 (2009/01/31) Phillip Lougher
Key type asymmetric registered
Asymmetric key parser 'x509' registered
io scheduler mq-deadline registered
Serial: 8250/16550 driver, 2 ports, IRQ sharing disabled
printk: legacy console [ttyS0] disabled
serial8250.0: ttyS0 at MMIO 0xb8000300 (irq = 3, base_baud = 3125000) is a 16550A
printk: legacy console [ttyS0] enabled
printk: legacy bootconsole [early0] disabled
serial8250.0: ttyS1 at MMIO 0xb8000400 (irq = 3, base_baud = 3125000) is a 16550A
physmap-flash physmap-flash.0: physmap platform flash device: [mem 0x1c000000-0x1e000000]
physmap-flash.0: Found 1 x16 devices at 0x0 in 16-bit bank. Manufacturer ID 0x000089 Chip ID 0x000017
physmap-flash.0: Found an alias at 0x800000 for the chip at 0x0
physmap-flash.0: Found an alias at 0x1000000 for the chip at 0x0
physmap-flash.0: Found an alias at 0x1800000 for the chip at 0x0
Intel/Sharp Extended Query Table at 0x0031
Intel/Sharp Extended Query Table at 0x0031
Using buffer write method
cfi_cmdset_0001: Erase suspend on write enabled
erase region 0: offset=0x0,size=0x20000,blocks=64
4 bcm47xxpart partitions found on MTD device physmap-flash.0
Creating 4 MTD partitions on "physmap-flash.0":
0x000000000000-0x000000040000 : "boot"
0x000000040000-0x0000007c0000 : "firmware"
failed to parse "brcm,trx-magic" DT attribute, using default: -89
3 trx partitions found on MTD device firmware
Creating 3 MTD partitions on "firmware":
0x00000000001c-0x000000000938 : "loader"
mtd: partition "loader" doesn't start on an erase/write block boundary -- force read-only
0x000000000938-0x0000001c0800 : "linux"
mtd: partition "linux" doesn't start on an erase/write block boundary -- force read-only
0x0000001c0800-0x000000780000 : "rootfs"
mtd: partition "rootfs" doesn't start on an erase/write block boundary -- force read-only
0x0000007c0000-0x0000007e0000 : "fwcf"
0x0000007e0000-0x000000800000 : "nvram"
b44 ssb0:1: could not find PHY at 30, use fixed one
Generic PHY fixed-0:00: attached PHY driver (mii_bus:phy_addr=fixed-0:00, irq=POLL)
b44 ssb0:1 eth0: Broadcom 44xx/47xx 10/100 PCI ethernet driver 00:0f:66:c8:74:47
NET: Registered PF_PACKET protocol family
8021q: 802.1Q VLAN Support v1.8
Loading compiled-in X.509 certificates
XXX: software_node_get_reference_args: refnode is NULL for swnode=(ptrval) (gpio-keys), fwnode=(ptrval)
VFS: Mounted root (squashfs filesystem) readonly on device 31:4.
devtmpfs: mounted
VFS: Pivoted into new rootfs
Freeing unused kernel image (initmem) memory: 228K
This architecture does not have kernel memory protection.
Run /etc/preinit as init process
  with arguments:
    /etc/preinit
    noinitrd
  with environment:
    HOME=/
    TERM=linux
random: crng init done
b44 ssb0:1 eth0: Link is up at 100 Mbps, half duplex
b44 ssb0:1 eth0: Flow control is off for TX and off for RX
b44 ssb0:1 eth0: Link is Up - 100Mbps/Full - flow control off
XXX: software_node_get_reference_args: refnode is NULL for swnode=8d67cb1c ((efault)), fwnode=b3963255
platform gpio-keys.0: deferred probe pending: gpio-keys: failed to get gpio

^ permalink raw reply

* Re: [PATCH v8 4/9] nvmem: layouts: Support fixed-layout as the nvmem device node itself
From: Bartosz Golaszewski @ 2026-07-15 12:07 UTC (permalink / raw)
  To: Loic Poulain
  Cc: linux-mmc, devicetree, linux-kernel, linux-arm-msm, linux-block,
	linux-wireless, ath10k, linux-bluetooth, netdev, daniel,
	Ulf Hansson, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Bjorn Andersson, Konrad Dybcio, Jens Axboe, Johannes Berg,
	Jeff Johnson, Bartosz Golaszewski, Marcel Holtmann,
	Luiz Augusto von Dentz, Balakrishna Godavarthi, Rocky Liao,
	David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Simon Horman, Srinivas Kandagatla, Andrew Lunn, Heiner Kallweit,
	Russell King, Saravana Kannan, Christian Marangi
In-Reply-To: <20260703-block-as-nvmem-v8-4-98ae32bfc49a@oss.qualcomm.com>

On Fri, 3 Jul 2026 15:45:17 +0200, Loic Poulain
<loic.poulain@oss.qualcomm.com> said:
> of_nvmem_layout_get_container() only looks for a child node named
> "nvmem-layout" to locate the cell definitions. This does not cover
> providers whose device tree node is itself the fixed-layout container,
> such as an eMMC boot partition block device whose fwnode points directly
> at a "fixed-layout" compatible partitions node.
>
> When no "nvmem-layout" child is present, fall back to returning the nvmem
> device node itself if it is compatible with "fixed-layout", so that its
> cells are parsed by nvmem_add_cells_from_fixed_layout().
>
> Signed-off-by: Loic Poulain <loic.poulain@oss.qualcomm.com>
> ---
>  drivers/nvmem/layouts.c | 13 ++++++++++++-
>  1 file changed, 12 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/nvmem/layouts.c b/drivers/nvmem/layouts.c
> index b90584e1b99eab4217cbe7ec48373e18a7caf0dc..efa631ce7283bdd6c8ecda75915911b5e3a33c99 100644
> --- a/drivers/nvmem/layouts.c
> +++ b/drivers/nvmem/layouts.c
> @@ -167,7 +167,18 @@ static int nvmem_layout_bus_populate(struct nvmem_device *nvmem,
>
>  struct device_node *of_nvmem_layout_get_container(struct nvmem_device *nvmem)
>  {
> -	return of_get_child_by_name(nvmem->dev.of_node, "nvmem-layout");
> +	struct device_node *np;
> +
> +	/* Search for nvmem-layout child */
> +	np = of_get_child_by_name(nvmem->dev.of_node, "nvmem-layout");
> +	if (np)
> +		return np;
> +
> +	/* The nvmem of_node is itself a fixed-layout node */
> +	if (of_device_is_compatible(nvmem->dev.of_node, "fixed-layout"))
> +		return of_node_get(nvmem->dev.of_node);
> +
> +	return NULL;
>  }
>  EXPORT_SYMBOL_GPL(of_nvmem_layout_get_container);
>
>
> --
> 2.34.1
>
>

I have it on my TODO list to convert nvmem layouts to be fwnode-agnostic. While
I'm not sure when I'll have the time to look into it, I think it makes sense
to not introduce any new OF-specific interfaces. Can you make it into:

  struct fwnode_handle *nvmem_layout_get_container_node(struct
nvmem_device *nvmem);

by replacing of_get_child_by_name() with fwnode_get_name_child_node() and
of_device_is_compatible() with device_is_compatible()? That would mean less
churn in the future.

Other than that, it looks good.

Bart

^ permalink raw reply

* Re: [PATCH v9 11/14] net: ipa: Switch to generic PAS TZ APIs
From: Alex Elder @ 2026-07-15 12:16 UTC (permalink / raw)
  To: Bjorn Andersson, Sumit Garg
  Cc: konradybcio, linux-arm-msm, devicetree, dri-devel, freedreno,
	linux-media, netdev, linux-wireless, ath12k, linux-remoteproc,
	robh, krzk+dt, conor+dt, robin.clark, sean, akhilpo, lumag,
	abhinav.kumar, jesszhan0024, marijn.suijten, airlied, simona,
	vikash.garodia, bod, mchehab, elder, andrew+netdev, davem,
	edumazet, kuba, pabeni, jjohnson, mathieu.poirier,
	trilokkumar.soni, mukesh.ojha, pavan.kondeti, jorge.ramirez,
	tonyh, vignesh.viswanathan, srinivas.kandagatla, amirreza.zarrabi,
	jenswi, op-tee, apurupa, skare, linux-kernel, Sumit Garg,
	Alex Elder, Konrad Dybcio
In-Reply-To: <alJp8jMzcw9EPZoy@baldur>

On 7/11/26 11:06 AM, Bjorn Andersson wrote:
> On Thu, Jul 02, 2026 at 05:28:27PM +0530, Sumit Garg wrote:
>> From: Sumit Garg <sumit.garg@oss.qualcomm.com>
>>
>> Switch ipa client driver over to generic PAS TZ APIs. Generic PAS TZ
>> service allows to support multiple TZ implementation backends like QTEE
>> based SCM PAS service, OP-TEE based PAS service and any further future TZ
>> backend service.
>>
> 
> Please find an immutable branch with the dependencies for this patch at:
>    https://git.kernel.org/pub/scm/linux/kernel/git/qcom/linux.git 20260702115835.167602-2-sumit.garg@kernel.org
> 
> Alternatively, if you think there will be no conflicting patches in the
> time leading up to next merge window provide an Ack and I can pick this
> through the qcom tree.

I don't see any reason there would be any conflicts (certainly
no difficult conflicts) with this commit, so I think you can
safely take it with the others through the Qualcomm tree.

So if my ack is what you're looking for:

Acked-by: Alex Elder <elder@riscstar.com>

Thank you Sumit and Bjorn.

> 
> Thanks,
> Bjorn
> 
>> Reviewed-by: Alex Elder <elder@riscstar.com>
>> Reviewed-by: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com>
>> Signed-off-by: Sumit Garg <sumit.garg@oss.qualcomm.com>
>> ---
>>   drivers/net/ipa/Kconfig    |  2 +-
>>   drivers/net/ipa/ipa_main.c | 13 ++++++++-----
>>   2 files changed, 9 insertions(+), 6 deletions(-)
>>
>> diff --git a/drivers/net/ipa/Kconfig b/drivers/net/ipa/Kconfig
>> index 01d219d3760c..a9aff1b7977d 100644
>> --- a/drivers/net/ipa/Kconfig
>> +++ b/drivers/net/ipa/Kconfig
>> @@ -6,7 +6,7 @@ config QCOM_IPA
>>   	depends on QCOM_RPROC_COMMON || (QCOM_RPROC_COMMON=n && COMPILE_TEST)
>>   	depends on QCOM_AOSS_QMP || QCOM_AOSS_QMP=n
>>   	select QCOM_MDT_LOADER
>> -	select QCOM_SCM
>> +	select QCOM_PAS
>>   	select QCOM_QMI_HELPERS
>>   	help
>>   	  Choose Y or M here to include support for the Qualcomm
>> diff --git a/drivers/net/ipa/ipa_main.c b/drivers/net/ipa/ipa_main.c
>> index 788dd99af2a4..3cd9e44680e9 100644
>> --- a/drivers/net/ipa/ipa_main.c
>> +++ b/drivers/net/ipa/ipa_main.c
>> @@ -14,7 +14,7 @@
>>   #include <linux/pm_runtime.h>
>>   #include <linux/types.h>
>>   
>> -#include <linux/firmware/qcom/qcom_scm.h>
>> +#include <linux/firmware/qcom/qcom_pas.h>
>>   #include <linux/soc/qcom/mdt_loader.h>
>>   
>>   #include "ipa.h"
>> @@ -624,10 +624,13 @@ static int ipa_firmware_load(struct device *dev)
>>   	}
>>   
>>   	ret = qcom_mdt_load(dev, fw, path, IPA_PAS_ID, virt, phys, size, NULL);
>> -	if (ret)
>> +	if (ret) {
>>   		dev_err(dev, "error %d loading \"%s\"\n", ret, path);
>> -	else if ((ret = qcom_scm_pas_auth_and_reset(IPA_PAS_ID)))
>> -		dev_err(dev, "error %d authenticating \"%s\"\n", ret, path);
>> +	} else {
>> +		ret = qcom_pas_auth_and_reset(IPA_PAS_ID);
>> +		if (ret)
>> +			dev_err(dev, "error %d authenticating \"%s\"\n", ret, path);
>> +	}
>>   
>>   	memunmap(virt);
>>   out_release_firmware:
>> @@ -758,7 +761,7 @@ static enum ipa_firmware_loader ipa_firmware_loader(struct device *dev)
>>   		return IPA_LOADER_INVALID;
>>   out_self:
>>   	/* We need Trust Zone to load firmware; make sure it's available */
>> -	if (qcom_scm_is_available())
>> +	if (qcom_pas_is_available())
>>   		return IPA_LOADER_SELF;
>>   
>>   	return IPA_LOADER_DEFER;
>> -- 
>> 2.53.0
>>


^ permalink raw reply

* Re: [PATCH] wifi: mt76: pass LED define via ccflags-y in driver submodules
From: Mateus B. Cassiano @ 2026-07-15 12:17 UTC (permalink / raw)
  To: nbd
  Cc: lorenzo, ryder.lee, shayne.chen, sean.wang, linux-wireless,
	linux-mediatek
In-Reply-To: <20260715044431.1207-2-mbc07@live.com>

On Wed, 15 Jul 2026 00:44:32 -0400, Mateus B. Cassiano wrote:
> mt7996 in particular enables IS_ENABLED(CONFIG_MT76_LEDS) code paths
> that appear to have never been built with the define before, so it
> would be good if someone with mt7996 hardware could confirm nothing
> regresses. I'm happy to drop the mt7996 hunk and keep only the others
> if preferred.

A user has since confirmed on the closed GitHub PR that the patch also
works as expected on mt7996 hardware:

https://github.com/openwrt/mt76/pull/1090#issuecomment-4979596316
https://forum.banana-pi.org/t/bpi-r4-mt7996-be14-per-band-wifi-7-leds-now-work-incl-mlo/27574/11?u=avbohemen

^ permalink raw reply

* [PATCH v2 0/3] ath11k/ath12k: implement TX flow control
From: Jose Ignacio Tornos Martinez @ 2026-07-15 12:50 UTC (permalink / raw)
  To: jjohnson
  Cc: ath11k, ath12k, linux-wireless, linux-kernel,
	Jose Ignacio Tornos Martinez

This series implements custom wake_tx_queue operations for ath11k and
ath12k drivers to prevent hardware ring overflow issues under heavy
traffic.

Without proper flow control, both drivers experience -ENOMEM errors
("failed to transmit frame -12") when the hardware TCL ring fills up.
Additionally, ath12k can hang under sustained high throughput. These
issues are more commonly observed in VMs with PCIe passthrough but
also occur on bare metal systems.

The implementation follows the pattern used in the iwlwifi driver,
checking hardware ring space before dequeuing packets from mac80211.
Per-ring locking serializes ring access while allowing TX completions
to run, preventing deadlocks.

Testing shows stable operation with eliminated -ENOMEM errors, no hangs,
and improved throughput under heavy traffic conditions.

Jose Ignacio Tornos Martinez (3):
  mac80211: add ieee80211_tx_peek API
  wifi: ath11k: implement custom wake_tx_queue with flow control
  wifi: ath12k: implement custom wake_tx_queue with flow control

v2: Address feedback from Zhi-Jun You:
    - Add ieee80211_tx_peek() API in mac80211 to peek at the next frame
      without dequeuing, enabling accurate ring selection before dequeue
    - Use get_ring_selector() on the peeked skb to determine the exact
      target ring matching dp_tx, fixing ring mismatch on multi-ring
      platforms (ipq8074, wcn6750, qcn9274, wcn7850)
    Address feedback from Tamizh Chelvam Raja:
    - Fix ath12k radio assignment: obtain ar from txq->vif through the
      arvif chain instead of ah->radio flexible array
    Move CRASH_FLUSH check inside the TX loop 
v1: https://lore.kernel.org/all/20260710155443.1761760-1-jtornosm@redhat.com/
--
2.49.0


^ permalink raw reply

* [PATCH v2 1/3] mac80211: add ieee80211_tx_peek API
From: Jose Ignacio Tornos Martinez @ 2026-07-15 12:50 UTC (permalink / raw)
  To: jjohnson
  Cc: ath11k, ath12k, linux-wireless, linux-kernel,
	Jose Ignacio Tornos Martinez
In-Reply-To: <20260715125017.277242-1-jtornosm@redhat.com>

Add ieee80211_tx_peek() to allow drivers to inspect the next frame
in a TXQ without removing it.

Drivers implementing custom wake_tx_queue operations may need to
determine which hardware TX ring to use before dequeuing a packet,
using properties like the skb hash or queue mapping that are only
available from the skb itself.

The function checks pending fragments first, then iterates through
all fair-queue flows (new_flows and old_flows) to find the first
queued frame, matching the iteration behavior of fq_tin_dequeue.
It also pre-caches the skb hash via skb_get_hash() so that
hash-based ring selectors see a stable value through the subsequent
dequeue and TX path.

Signed-off-by: Jose Ignacio Tornos Martinez <jtornosm@redhat.com>
---
New in v2

 include/net/mac80211.h | 20 ++++++++++++++++++++
 net/mac80211/tx.c      | 39 +++++++++++++++++++++++++++++++++++++++
 2 files changed, 59 insertions(+)

diff --git a/include/net/mac80211.h b/include/net/mac80211.h
index 4f95da023746..9289b8dca972 100644
--- a/include/net/mac80211.h
+++ b/include/net/mac80211.h
@@ -7742,6 +7742,26 @@ void ieee80211_unreserve_tid(struct ieee80211_sta *sta, u8 tid);
 struct sk_buff *ieee80211_tx_dequeue(struct ieee80211_hw *hw,
 				     struct ieee80211_txq *txq);
 
+/**
+ * ieee80211_tx_peek - peek at the next packet in a software tx queue
+ *
+ * @hw: pointer as obtained from ieee80211_alloc_hw()
+ * @txq: pointer obtained from station or virtual interface, or from
+ *	ieee80211_next_txq()
+ *
+ * Return: the next skb without dequeuing it, or %NULL if the queue is empty.
+ * The returned pointer is const — the caller must not modify or free the skb.
+ * The skb remains queued and will be returned by a subsequent
+ * ieee80211_tx_dequeue() call.
+ *
+ * This is useful for drivers that need to inspect the next frame (e.g. to
+ * determine the target TX ring) before deciding whether to dequeue.
+ *
+ * Must be called in the same context as ieee80211_tx_dequeue().
+ */
+const struct sk_buff *ieee80211_tx_peek(struct ieee80211_hw *hw,
+					struct ieee80211_txq *txq);
+
 /**
  * ieee80211_tx_dequeue_ni - dequeue a packet from a software tx queue
  * (in process context)
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c
index c13b209fad47..91bfd8ef9428 100644
--- a/net/mac80211/tx.c
+++ b/net/mac80211/tx.c
@@ -3857,6 +3857,45 @@ static bool ieee80211_xmit_fast(struct ieee80211_sub_if_data *sdata,
 	return true;
 }
 
+const struct sk_buff *ieee80211_tx_peek(struct ieee80211_hw *hw,
+					struct ieee80211_txq *txq)
+{
+	struct txq_info *txqi = container_of(txq, struct txq_info, txq);
+	struct ieee80211_local *local = hw_to_local(hw);
+	struct fq_tin *tin = &txqi->tin;
+	struct fq *fq = &local->fq;
+	struct sk_buff *skb = NULL;
+	struct fq_flow *flow;
+
+	WARN_ON_ONCE(softirq_count() == 0);
+
+	spin_lock_bh(&fq->lock);
+
+	skb = skb_peek(&txqi->frags);
+	if (skb)
+		goto out;
+
+	list_for_each_entry(flow, &tin->new_flows, flowchain) {
+		skb = skb_peek(&flow->queue);
+		if (skb)
+			goto out;
+	}
+
+	list_for_each_entry(flow, &tin->old_flows, flowchain) {
+		skb = skb_peek(&flow->queue);
+		if (skb)
+			goto out;
+	}
+
+out:
+	if (skb)
+		skb_get_hash(skb);
+
+	spin_unlock_bh(&fq->lock);
+	return skb;
+}
+EXPORT_SYMBOL_GPL(ieee80211_tx_peek);
+
 struct sk_buff *ieee80211_tx_dequeue(struct ieee80211_hw *hw,
 				     struct ieee80211_txq *txq)
 {
-- 
2.54.0


^ permalink raw reply related

* [PATCH v2 2/3] wifi: ath11k: implement custom wake_tx_queue with flow control
From: Jose Ignacio Tornos Martinez @ 2026-07-15 12:50 UTC (permalink / raw)
  To: jjohnson
  Cc: ath11k, ath12k, linux-wireless, linux-kernel,
	Jose Ignacio Tornos Martinez
In-Reply-To: <20260715125017.277242-1-jtornosm@redhat.com>

Under heavy traffic, ath11k experiences frequent -ENOMEM errors
("failed to transmit frame -12") when the hardware TCL ring fills up.
This issue is more commonly observed in VMs with PCIe passthrough but
also occurs on bare metal systems. It is particularly problematic on
devices with a single shared TCL ring where all traffic classes
compete for the same 512 descriptor slots.

Implement a custom wake_tx_queue operation that:

1. Checks hardware ring space before dequeuing packets from mac80211
2. Uses per-ring locking to serialize ring access and prevent races
3. Syncs with hardware state to get accurate free slot count
4. Uses ieee80211_tx_peek() to determine the exact target ring via
   get_ring_selector(), matching dp_tx on all platforms
5. Returns early during firmware crash in the same way as other
   tx paths

This approach follows the pattern used in the iwlwifi driver, adapted
for ath11k's hardware ring architecture.

This eliminates -ENOMEM errors and improves throughput by optimizing
resource usage and preventing unnecessary packet drops.

Signed-off-by: Jose Ignacio Tornos Martinez <jtornosm@redhat.com>
---
v2: Address feedback from Zhi-Jun You:
    - Add ieee80211_tx_peek() API in mac80211 to peek at the next frame
      without dequeuing, enabling accurate ring selection before dequeue
    - Use get_ring_selector() on the peeked skb to determine the exact
      target ring matching dp_tx, fixing ring mismatch on multi-ring
      platforms (ipq8074, wcn6750, qcn9274, wcn7850)
    Move CRASH_FLUSH check inside the TX loop
v1: https://lore.kernel.org/all/20260710155443.1761760-2-jtornosm@redhat.com/

 drivers/net/wireless/ath/ath11k/dp.c  |  1 +
 drivers/net/wireless/ath/ath11k/dp.h  |  2 +
 drivers/net/wireless/ath/ath11k/mac.c | 60 ++++++++++++++++++++++++++-
 3 files changed, 62 insertions(+), 1 deletion(-)

diff --git a/drivers/net/wireless/ath/ath11k/dp.c b/drivers/net/wireless/ath/ath11k/dp.c
index f389b97acbdd..2e5978ec2b05 100644
--- a/drivers/net/wireless/ath/ath11k/dp.c
+++ b/drivers/net/wireless/ath/ath11k/dp.c
@@ -1087,6 +1087,7 @@ int ath11k_dp_alloc(struct ath11k_base *ab)
 	for (i = 0; i < ab->hw_params.hal_params->num_tx_rings; i++) {
 		idr_init(&dp->tx_ring[i].txbuf_idr);
 		spin_lock_init(&dp->tx_ring[i].tx_idr_lock);
+		spin_lock_init(&dp->tx_ring[i].wake_tx_lock);
 		dp->tx_ring[i].tcl_data_ring_id = i;
 
 		dp->tx_ring[i].tx_status_head = 0;
diff --git a/drivers/net/wireless/ath/ath11k/dp.h b/drivers/net/wireless/ath/ath11k/dp.h
index 84f66839f0c6..6d99501aa269 100644
--- a/drivers/net/wireless/ath/ath11k/dp.h
+++ b/drivers/net/wireless/ath/ath11k/dp.h
@@ -87,6 +87,8 @@ struct dp_tx_ring {
 	struct idr txbuf_idr;
 	/* Protects txbuf_idr and num_pending */
 	spinlock_t tx_idr_lock;
+	/* Serializes wake_tx_queue operations for this ring */
+	spinlock_t wake_tx_lock;
 	struct hal_wbm_release_ring *tx_status;
 	int tx_status_head;
 	int tx_status_tail;
diff --git a/drivers/net/wireless/ath/ath11k/mac.c b/drivers/net/wireless/ath/ath11k/mac.c
index 2d55cdc4d165..046cefd53178 100644
--- a/drivers/net/wireless/ath/ath11k/mac.c
+++ b/drivers/net/wireless/ath/ath11k/mac.c
@@ -10065,9 +10065,67 @@ static int ath11k_mac_op_sta_state(struct ieee80211_hw *hw,
 	return ret;
 }
 
+static void ath11k_mac_op_wake_tx_queue(struct ieee80211_hw *hw,
+					struct ieee80211_txq *txq)
+{
+	struct ieee80211_tx_control control = {
+		.sta = txq->sta,
+	};
+	const struct sk_buff *peek_skb;
+	struct ath11k *ar = hw->priv;
+	struct dp_tx_ring *tx_ring;
+	struct hal_srng *tcl_ring;
+	struct sk_buff *skb;
+	u32 ring_selector;
+	int num_free;
+	u8 ring_id;
+
+	if (!ar)
+		return;
+
+	while (1) {
+		if (unlikely(test_bit(ATH11K_FLAG_CRASH_FLUSH,
+				      &ar->ab->dev_flags)))
+			break;
+
+		peek_skb = ieee80211_tx_peek(hw, txq);
+		if (!peek_skb)
+			break;
+
+		ring_selector = ar->ab->hw_params.hw_ops->get_ring_selector(
+					(struct sk_buff *)peek_skb);
+		ring_id = ring_selector %
+			  ar->ab->hw_params.hal_params->num_tx_rings;
+
+		tx_ring = &ar->ab->dp.tx_ring[ring_id];
+		tcl_ring = &ar->ab->hal.srng_list[tx_ring->tcl_data_ring.ring_id];
+
+		spin_lock_bh(&tx_ring->wake_tx_lock);
+
+		spin_lock(&tcl_ring->lock);
+		num_free = ath11k_hal_srng_src_num_free(ar->ab, tcl_ring, true);
+		spin_unlock(&tcl_ring->lock);
+
+		if (num_free == 0) {
+			spin_unlock_bh(&tx_ring->wake_tx_lock);
+			break;
+		}
+
+		skb = ieee80211_tx_dequeue(hw, txq);
+		if (!skb) {
+			spin_unlock_bh(&tx_ring->wake_tx_lock);
+			break;
+		}
+
+		ath11k_mac_op_tx(hw, &control, skb);
+
+		spin_unlock_bh(&tx_ring->wake_tx_lock);
+	}
+}
+
 static const struct ieee80211_ops ath11k_ops = {
 	.tx				= ath11k_mac_op_tx,
-	.wake_tx_queue			= ieee80211_handle_wake_tx_queue,
+	.wake_tx_queue			= ath11k_mac_op_wake_tx_queue,
 	.start                          = ath11k_mac_op_start,
 	.stop                           = ath11k_mac_op_stop,
 	.reconfig_complete              = ath11k_mac_op_reconfig_complete,
-- 
2.54.0


^ permalink raw reply related

* [PATCH v2 3/3] wifi: ath12k: implement custom wake_tx_queue with flow control
From: Jose Ignacio Tornos Martinez @ 2026-07-15 12:50 UTC (permalink / raw)
  To: jjohnson
  Cc: ath11k, ath12k, linux-wireless, linux-kernel,
	Jose Ignacio Tornos Martinez
In-Reply-To: <20260715125017.277242-1-jtornosm@redhat.com>

Under heavy traffic, ath12k can hang and experiences -ENOMEM errors
("failed to transmit frame -12") when the hardware TCL ring fills up.
This issue is more commonly observed in VMs with PCIe passthrough but
also occurs on bare metal systems.

Implement a custom wake_tx_queue operation that:

1. Checks hardware ring space before dequeuing packets from mac80211
2. Uses per-ring locking to serialize ring access and prevent races
3. Syncs with hardware state to get accurate free slot count
4. Uses ieee80211_tx_peek() to determine the exact target ring via
   get_ring_selector(), matching dp_tx on all platforms
5. Returns early during firmware crash in the same way as other
   tx paths

This approach follows the pattern used in the iwlwifi driver, adapted
for ath12k's hardware ring architecture.

This prevents hangs, eliminates -ENOMEM errors, and improves throughput
by optimizing resource usage and preventing unnecessary packet drops.

Signed-off-by: Jose Ignacio Tornos Martinez <jtornosm@redhat.com>
---
v2: Address feedback from Zhi-Jun You:
    - Add ieee80211_tx_peek() API in mac80211 to peek at the next frame
      without dequeuing, enabling accurate ring selection before dequeue
    - Use get_ring_selector() on the peeked skb to determine the exact
      target ring matching dp_tx, fixing ring mismatch on multi-ring
      platforms (ipq8074, wcn6750, qcn9274, wcn7850)
    Address feedback from Tamizh Chelvam Raja:
    - Fix ath12k radio assignment: obtain ar from txq->vif through the
      arvif chain instead of ah->radio flexible array
    Move CRASH_FLUSH check inside the TX loop
v1: https://lore.kernel.org/all/20260710155443.1761760-3-jtornosm@redhat.com/

 drivers/net/wireless/ath/ath12k/dp.c       |  1 +
 drivers/net/wireless/ath/ath12k/dp.h       |  2 +
 drivers/net/wireless/ath/ath12k/hal.c      |  1 +
 drivers/net/wireless/ath/ath12k/wifi7/hw.c | 65 +++++++++++++++++++++-
 4 files changed, 68 insertions(+), 1 deletion(-)

diff --git a/drivers/net/wireless/ath/ath12k/dp.c b/drivers/net/wireless/ath/ath12k/dp.c
index af5f11fc1d84..3d46cfbf0a1c 100644
--- a/drivers/net/wireless/ath/ath12k/dp.c
+++ b/drivers/net/wireless/ath/ath12k/dp.c
@@ -1539,6 +1539,7 @@ static int ath12k_dp_setup(struct ath12k_base *ab)
 	}
 
 	for (i = 0; i < ab->hw_params->max_tx_ring; i++) {
+		spin_lock_init(&dp->tx_ring[i].wake_tx_lock);
 		dp->tx_ring[i].tcl_data_ring_id = i;
 
 		dp->tx_ring[i].tx_status_head = 0;
diff --git a/drivers/net/wireless/ath/ath12k/dp.h b/drivers/net/wireless/ath/ath12k/dp.h
index f8cfc7bb29dd..68d2020be9b8 100644
--- a/drivers/net/wireless/ath/ath12k/dp.h
+++ b/drivers/net/wireless/ath/ath12k/dp.h
@@ -58,6 +58,8 @@ struct dp_tx_ring {
 	u8 tcl_data_ring_id;
 	struct dp_srng tcl_data_ring;
 	struct dp_srng tcl_comp_ring;
+	/* Serializes wake_tx_queue operations for this ring */
+	spinlock_t wake_tx_lock;
 	struct hal_wbm_completion_ring_tx *tx_status;
 	int tx_status_head;
 	int tx_status_tail;
diff --git a/drivers/net/wireless/ath/ath12k/hal.c b/drivers/net/wireless/ath/ath12k/hal.c
index a164563fff28..c1c656e4550b 100644
--- a/drivers/net/wireless/ath/ath12k/hal.c
+++ b/drivers/net/wireless/ath/ath12k/hal.c
@@ -390,6 +390,7 @@ int ath12k_hal_srng_src_num_free(struct ath12k_base *ab, struct hal_srng *srng,
 	else
 		return ((srng->ring_size - hp + tp) / srng->entry_size) - 1;
 }
+EXPORT_SYMBOL(ath12k_hal_srng_src_num_free);
 
 void *ath12k_hal_srng_src_next_peek(struct ath12k_base *ab,
 				    struct hal_srng *srng)
diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hw.c b/drivers/net/wireless/ath/ath12k/wifi7/hw.c
index d9fdd2fc8298..306d51da3ea1 100644
--- a/drivers/net/wireless/ath/ath12k/wifi7/hw.c
+++ b/drivers/net/wireless/ath/ath12k/wifi7/hw.c
@@ -1100,9 +1100,72 @@ static void ath12k_wifi7_mac_op_tx(struct ieee80211_hw *hw,
 	}
 }
 
+static void ath12k_wifi7_mac_op_wake_tx_queue(struct ieee80211_hw *hw,
+					      struct ieee80211_txq *txq)
+{
+	struct ath12k_vif *ahvif = ath12k_vif_to_ahvif(txq->vif);
+	struct ath12k_link_vif *arvif = &ahvif->deflink;
+	struct ieee80211_tx_control control = {
+		.sta = txq->sta,
+	};
+	const struct sk_buff *peek_skb;
+	struct dp_tx_ring *tx_ring;
+	struct hal_srng *tcl_ring;
+	struct ath12k_dp *dp;
+	struct sk_buff *skb;
+	struct ath12k *ar;
+	u32 ring_selector;
+	int num_free;
+	u8 ring_id;
+
+	ar = arvif->ar;
+	if (!ar)
+		return;
+
+	dp = ar->ab->dp;
+
+	while (1) {
+		if (unlikely(test_bit(ATH12K_FLAG_CRASH_FLUSH,
+				      &ar->ab->dev_flags)))
+			break;
+
+		peek_skb = ieee80211_tx_peek(hw, txq);
+		if (!peek_skb)
+			break;
+
+		ring_selector = dp->hw_params->hw_ops->get_ring_selector(
+					(struct sk_buff *)peek_skb);
+		ring_id = ring_selector % dp->hw_params->max_tx_ring;
+
+		tx_ring = &dp->tx_ring[ring_id];
+		tcl_ring = &dp->hal->srng_list[tx_ring->tcl_data_ring.ring_id];
+
+		spin_lock_bh(&tx_ring->wake_tx_lock);
+
+		spin_lock(&tcl_ring->lock);
+		num_free = ath12k_hal_srng_src_num_free(ar->ab, tcl_ring, true);
+		spin_unlock(&tcl_ring->lock);
+
+		if (num_free == 0) {
+			spin_unlock_bh(&tx_ring->wake_tx_lock);
+			break;
+		}
+
+		skb = ieee80211_tx_dequeue(hw, txq);
+		if (!skb) {
+			spin_unlock_bh(&tx_ring->wake_tx_lock);
+			break;
+		}
+
+		ath12k_wifi7_mac_op_tx(hw, &control, skb);
+
+		spin_unlock_bh(&tx_ring->wake_tx_lock);
+	}
+}
+
 static const struct ieee80211_ops ath12k_ops_wifi7 = {
 	.tx				= ath12k_wifi7_mac_op_tx,
-	.wake_tx_queue			= ieee80211_handle_wake_tx_queue,
+	.wake_tx_queue			= ath12k_wifi7_mac_op_wake_tx_queue,
 	.start                          = ath12k_mac_op_start,
 	.stop                           = ath12k_mac_op_stop,
 	.reconfig_complete              = ath12k_mac_op_reconfig_complete,
-- 
2.54.0


^ permalink raw reply related

* Re: [PATCH] morsemicro: add firmware for mm8108 support
From: Josh Boyer @ 2026-07-15 13:02 UTC (permalink / raw)
  To: Lachlan Hodges
  Cc: linux-firmware, linux-wireless, arien.judge, dan.callaghan,
	ayman.grais
In-Reply-To: <20260707044618.2476204-1-lachlan.hodges@morsemicro.com>

On Tue, Jul 7, 2026 at 12:47 AM Lachlan Hodges
<lachlan.hodges@morsemicro.com> wrote:
>
> Add firmware and board files for the mm8108 chipset to be used
> with the mm81x Wi-Fi driver.
>
> Signed-off-by: Lachlan Hodges <lachlan.hodges@morsemicro.com>
> ---
>  LICENSES/LICENCE.morsemicro                 | 125 ++++++++++++++++++++

This is problematic and we can't accept this firmware under this
license.  Please see LICENSE-CRITERIA.md in the repo.  More comments
below.

josh

>  WHENCE                                      |  14 +++
>  morsemicro/mm81x/v56/bcf_aw_hm677.bin       | Bin 0 -> 2124 bytes
>  morsemicro/mm81x/v56/bcf_mm8108_mf15457.bin | Bin 0 -> 2124 bytes
>  morsemicro/mm81x/v56/mm8108.bin             | Bin 0 -> 479624 bytes
>  5 files changed, 139 insertions(+)
>  create mode 100644 LICENSES/LICENCE.morsemicro
>  create mode 100644 morsemicro/mm81x/v56/bcf_aw_hm677.bin
>  create mode 100644 morsemicro/mm81x/v56/bcf_mm8108_mf15457.bin
>  create mode 100644 morsemicro/mm81x/v56/mm8108.bin
>
> diff --git a/LICENSES/LICENCE.morsemicro b/LICENSES/LICENCE.morsemicro
> new file mode 100644
> index 000000000000..adf90750d1af
> --- /dev/null
> +++ b/LICENSES/LICENCE.morsemicro
> @@ -0,0 +1,125 @@
> +                                  MORSE MICRO
> +                     BINARY DISTRIBUTION LICENSE AGREEMENT
> +
> +1. Parties.
> +This Software License Agreement (SLA) is between Morse Micro Pty. Ltd. and the
> +user of the Software set forth (“you”, “user”, “customer”), and is effective as
> +of the date of first access or download of the software by you. Morse Micro is
> +licensing this software to you free of charge upon the condition that you
> +accept all the terms of this SLA and only use this Software in conjunction with
> +Morse Micro products. ANY USE, REPRODUCTION, OR DISTRIBUTION OF THE SOFTWARE
> +CONSTITUTES YOUR ACCEPTANCE OF THIS AGREEMENT.
> +
> +2. Definitions.
> +"Software" means any binary or source code that you have received from Morse
> +Micro or its authorized licensees and/or those portions of such software

A random user downloading the firmware from the linux-firmware
repository will not have received it from Morse Micro directly, nor is
the linux-firmware repo an authorized licensee.

> +produced by Program’s code within the Software, as well as any other machine
> +readable materials (including, but not limited to, libraries, source files,
> +header files, and data files), any updates or error corrections provided by
> +Morse Micro, and any user manuals, programming guides and other documentation
> +provided to you by Morse Micro under this SLA.
> +
> +3. License and Restrictions.
> +Morse Micro grants you a non-exclusive, non-transferable, limited license
> +without license fees to:
> +
> +    a. use the software solely with a hardware product that includes one of the
> +    Morse Micro Wi-Fi HaLow chips, including
> +    wireless modules or evaluation kits;
> +
> +    b. to reproduce and distribute the Software complete, unmodified, and as
> +    provided by Morse Micro, solely for use with a hardware product that
> +    includes one of the Morse Micro Wi-Fi HaLow chips, including wireless
> +    modules or evaluation kits.

The distribution restriction here prohibits normal distribution of the
firmware for basically every Linux distributor, where they would
normally include all firmware files on installation media regardless
of the hardware the OS is being installed on.  It also prohibits
normal distribution via git repos, because we have no control on who
downloads the firmware and for what purpose.

> +4. Reservation of Rights.
> +You should distribute Software with a copy of this SLA. Software is
> +copyrighted. Title to Software and all associated intellectual property rights
> +is retained by Morse Micro. Except as expressly provided herein, no license or
> +right, express or implied, is hereby conveyed or granted to you by Morse Micro.
> +You must retain all copyright notices on all Software, derivative works and
> +documentation. The intellectual property and proprietary rights of whatever
> +nature in the Software and derivative works are and will remain the exclusive
> +property of Morse Micro or its suppliers. Nothing in this Agreement should be
> +construed as transferring any aspects of such rights to you or any third party.
> +Morse Micro and its suppliers reserve any and all rights not expressly granted
> +in this Agreement. You may not sell, assign, sublicense, lease, or otherwise
> +transfer any part of this license. You must not:
> +
> +    a. use, license, sell or otherwise distribute the Software except as
> +    provided in this SLA;
> +
> +    b. attempt to modify in any way, reverse engineer, decompile or disassemble
> +    any portion of the Software;
> +
> +    c. use the Software or other material in violation of any applicable law or
> +    regulation, including but not limited to any regulatory agency.
> +
> +5. Ownership.
> +The Software is licensed and not sold.  Title to and ownership of the Software,
> +including all intellectual property rights thereto, and any portion thereof
> +remain with Morse Micro or its licensors. You hereby covenant that you will not
> +assert any claim that the Software created by or for Morse Micro infringe any
> +intellectual property right owned or controlled by you.
> +
> +6. Termination.
> +This SLA will terminate immediately without notice from Morse Micro if you fail
> +to comply with any of its provisions, including the export laws provisions and
> +Section 10 that may govern the export of the Software from certain
> +jurisdictions, including technical data.

This is effectively either unenforceable after including it in the
linux-firmware repo, or prohibitive enough that we can't include it at
all.

> +7. Disclaimer and Limitation of Liability.
> +THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. MORSE MICRO
> +FURTHER DISCLAIMS ALL WARRANTIES, EXPRESS AND IMPLIED, INCLUDING WITHOUT
> +LIMITATION, ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
> +PURPOSE OR NON-INFRINGEMENT. IN NO EVENT SHALL MORSE MICRO BE LIABLE FOR ANY
> +INDIRECT, INCIDENTAL, SPECIAL, PUNITIVE OR CONSEQUENTIAL DAMAGES, OR DAMAGES
> +FOR LOSS OF PROFITS, REVENUE, DATA OR DATA USE, INCURRED BY YOU OR ANY THIRD
> +PARTY, WHETHER IN AN ACTION IN CONTRACT OR TORT, EVEN IF MORSE MICRO HAS BEEN
> +ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. THE SOFTWARE IS NOT INTENDED FOR
> +USE IN ENVIRONMENTS OR APPLICATIONS WHERE EXTRAORDINARILY HIGH LEVELS OF
> +QUALITY, RELIABILITY, AND FAILURE TOLERANCE ARE DEMANDED, AND/OR WHERE A
> +MALFUNCTION OR FAILURE COULD LEAD TO SIGNIFICANT HARM TO LIFE, HEALTH,
> +PROPERTY, OR RESULT IN SEVERE SOCIETAL REPERCUSSIONS ("CRITICAL APPLICATIONS").
> +CRITICAL APPLICATIONS ENCOMPASS, BUT ARE NOT LIMITED TO, EQUIPMENT UTILIZED IN
> +NUCLEAR FACILITIES, AVIATION AND SPACE EQUIPMENT, MEDICAL DEVICES, AUTOMOTIVE,
> +TRAIN, MARINE, AND OTHER TRANSPORTATION EQUIPMENT, DEVICES INVOLVED IN
> +CONTROLLING COMBUSTION OR EXPLOSIONS, SAFETY DEVICES, ELEVATORS AND ESCALATORS,
> +DEVICES ASSOCIATED WITH ELECTRIC POWER, AND EQUIPMENT USED IN FINANCE-RELATED
> +FIELDS.
> +
> +8. Survival.
> +Sections 4, 5, 6, 7 and 10 will survive termination or expiration of this SLA.
> +
> +9. Privacy.
> +Some features of the Software, if activated, may transmit a limited amount of
> +data to Morse Micro (or its service provider) about the status of the system
> +before a crash event. Morse Micro does not associate the data with personally
> +identifiable information.
> +
> +10. Export Laws.
> +YOU UNDERSTAND AND AGREE THAT THE SOFTWARE IS SUBJECT TO ALL APPLICABLE EXPORT-
> +RELATED LAWS AND REGULATIONS AND THAT YOU MAY NOT EXPORT, RE-EXPORT OR TRANSFER
> +THE SOFTWARE OR ANY DIRECT PRODUCT OF THE SOFTWARE EXCEPT AS PERMITTED UNDER
> +THOSE LAWS. WITHOUT LIMITING THE FOREGOING, EXPORT, RE-EXPORT, OR TRANSFER OF
> +THE SOFTWARE TO CUBA, IRAN, NORTH KOREA, SUDAN, AND SYRIA IS PROHIBITED.
> +
> +11. Governing Law.
> +The laws of New South Wales, Australia, govern all matters arising out of or
> +relating to this SLA without giving effect to any conflict of law principles.
> +If any provision of this SLA is held to be unenforceable, this SLA will remain
> +in effect with the provision omitted, unless omission would frustrate the
> +intent of the parties, in which case this Agreement will immediately terminate.
> +
> +12. Entire Agreement.
> +This Agreement constitutes the entire agreement between the parties and
> +supersedes all prior and contemporaneous agreements, proposals or
> +representations, written or oral, concerning its subject matter. No
> +modification, amendment, or waiver of any provision of this Agreement will be
> +effective unless in writing and either signed or accepted electronically by the
> +party against whom the modification, amendment or waiver is to be asserted. A
> +waiver of any breach under this Agreement does not constitute a waiver of any
> +other breach or future breach.
> +
> +
> +MORSE MICRO
>

^ permalink raw reply

* Re: [PATCH] wifi: mwifiex: bound uAP association event IEs to the event buffer
From: Francesco Dolcini @ 2026-07-15 13:22 UTC (permalink / raw)
  To: HE WEI (ギカク)
  Cc: Brian Norris, Francesco Dolcini, Miri Korenblit, Johannes Berg,
	Kalle Valo, Kees Cook, linux-wireless, linux-kernel
In-Reply-To: <20260629120333.94222-1-skyexpoc@gmail.com>

On Mon, Jun 29, 2026 at 09:03:33PM +0900, HE WEI (ギカク) wrote:
> mwifiex_process_uap_event() handles EVENT_UAP_STA_ASSOC by exposing the
> (re)association request IEs that the firmware copies into the event:
> 
> 	sinfo->assoc_req_ies = &event->data[len];
> 	len = (u8 *)sinfo->assoc_req_ies - (u8 *)&event->frame_control;
> 	sinfo->assoc_req_ies_len = le16_to_cpu(event->len) - (u16)len;
> 
> event->len is supplied by the device firmware and is never validated,

Why not validating event->len instead, when we receive an MWIFIEX_TYPE_EVENT
from the firmware? we could just add a new, validated, u16 event_len, in struct
mwifiex_adapter and after that we can just use it in the code.

and we reject invalid events as soon as possible in the software.


> Fixes: e568634ae7ac ("mwifiex: add AP event handling framework")
> Signed-off-by: HE WEI (ギカク) <skyexpoc@gmail.com>
> ---
>  .../net/wireless/marvell/mwifiex/uap_event.c   | 18 ++++++++++++++++++
>  1 file changed, 18 insertions(+)
> 
> diff --git a/drivers/net/wireless/marvell/mwifiex/uap_event.c b/drivers/net/wireless/marvell/mwifiex/uap_event.c
> index 679fdae0f001..adca7da29f0f 100644
> --- a/drivers/net/wireless/marvell/mwifiex/uap_event.c
> +++ b/drivers/net/wireless/marvell/mwifiex/uap_event.c
> @@ -126,6 +126,24 @@ int mwifiex_process_uap_event(struct mwifiex_private *priv)
>  				sinfo->assoc_req_ies = &event->data[len];
>  				len = (u8 *)sinfo->assoc_req_ies -
>  				      (u8 *)&event->frame_control;
> +
> +				/*
> +				 * event->len is reported by the device firmware and is not
> +				 * otherwise validated.  Reject a length that underflows the
> +				 * header, or that would place the association request IEs
> +				 * outside the fixed-size event_body[] buffer the event was
> +				 * copied into; otherwise the IE walk in
> +				 * mwifiex_set_sta_ht_cap() reads past event_body and out
> +				 * of the adapter slab object.
> +				 */
> +				if (le16_to_cpu(event->len) < len ||
> +				    (u8 *)&event->frame_control + le16_to_cpu(event->len) >
> +				    adapter->event_body + MAX_EVENT_SIZE) {
> +					mwifiex_dbg(adapter, ERROR,
> +						    "invalid STA assoc event length\n");
> +					kfree(sinfo);
> +					return -1;
> +				}

In case we want to keep the change here, I would ask you to make the
code slighly more compact.

just define a

evt_len = le16_to_cpu(event->len)

and use it.


^ permalink raw reply

* Re: [PATCH] wifi: mwifiex: bound uAP association event IEs to the event buffer
From: HE WEI(ギカク) @ 2026-07-15 13:38 UTC (permalink / raw)
  To: Francesco Dolcini
  Cc: Brian Norris, Miri Korenblit, Johannes Berg, Kalle Valo,
	Kees Cook, linux-wireless, linux-kernel
In-Reply-To: <20260715132234.GA56330@francesco-nb>

> Why not validating event->len instead, when we receive an
> MWIFIEX_TYPE_EVENT from the firmware? we could just add a new,
> validated, u16 event_len, in struct mwifiex_adapter and after that we
> can just use it in the code. and we reject invalid events as soon as
> possible in the software.

Thanks for the review. I don't think that maps onto the code cleanly,
because event->len is not the transport-level event length. It is
struct mwifiex_assoc_event.len (fw.h), a __le16 that lives at offset 8
*inside* the event body and is specific to the EVENT_UAP_STA_ASSOC /
TLV_TYPE_UAP_MGMT_FRAME payload. It measures the 802.11 (re)assoc
frame starting at frame_control, not the whole event.

At the point where we receive an MWIFIEX_TYPE_EVENT (usb.c, sdio.c,
pcie.c -> mwifiex_process_event) the driver only looks at the 4-byte
event_cause and the transport frame length (skb->len, or the PCIe
transfer-header length); it copies the rest of the body into
event_body[] without interpreting it, and each of the ~40 event causes
then casts event_body to its own type-specific struct. So a generic,
receive-time u16 in struct mwifiex_adapter can validate how many bytes
the transport delivered, but it cannot validate event->len there, and
the two are not interchangeable: event->len excludes the
sta_addr/type/len header, so it is about 10 bytes smaller than the
delivered length. Substituting it in the code would compute a wrong
assoc_req_ies_len and re-introduce an over-read.

Storing a validated received length in the adapter is a reasonable
hardening on its own. It would give a tighter bound than
event_body[MAX_EVENT_SIZE] and could help other handlers, but it
touches all three transports (which I can't exercise on real hardware)
and it still needs this per-event check on event->len. I'd rather keep
the security fix minimal and in the one function that knows the
assoc-event layout, and leave the receive-time refactor as a separate
change if you would like it.

> In case we want to keep the change here, I would ask you to make the
> code slightly more compact. just define a evt_len =
> le16_to_cpu(event->len) and use it.

v2 folds event->len into a local evt_len as you suggested, which also
shortens the bounds check. I'll send it as a proper [PATCH v2]; the
hunk is:

if (len != -1) {
u16 evt_len = le16_to_cpu(event->len);

sinfo->assoc_req_ies = &event->data[len];
len = (u8 *)sinfo->assoc_req_ies -
      (u8 *)&event->frame_control;

/*
* event->len is reported by the device firmware
* and is not otherwise validated.  Reject a
* length that underflows the header, or that
* would place the association request IEs
* outside the fixed-size event_body[] buffer the
* event was copied into; otherwise the IE walk
* in mwifiex_set_sta_ht_cap() reads past
* event_body and out of the adapter slab object.
*/
if (evt_len < len ||
    (u8 *)&event->frame_control + evt_len >
    adapter->event_body + MAX_EVENT_SIZE) {
mwifiex_dbg(adapter, ERROR,
    "invalid STA assoc event length\n");
kfree(sinfo);
return -1;
}
sinfo->assoc_req_ies_len = evt_len - (u16)len;
}

^ permalink raw reply

* Re: [PATCH] wifi: mwifiex: copy only event bodies after headers
From: Francesco Dolcini @ 2026-07-15 13:50 UTC (permalink / raw)
  To: Pengpeng Hou
  Cc: Brian Norris, Francesco Dolcini, linux-wireless, linux-kernel
In-Reply-To: <20260704011317.50900-1-pengpeng@iscas.ac.cn>

On Sat, Jul 04, 2026 at 09:13:17AM +0800, Pengpeng Hou wrote:
> mwifiex event packets carry a four-byte event cause followed by the
> event body.  The USB and SDIO receive paths read the event cause and
> then copy adapter->event_body from skb->data + MWIFIEX_EVENT_HEADER_LEN,
> but pass the full skb->len as the copy length.  That makes the source
> range extend past the skb by the size of the event header.
> 
> Require the event header before reading the event cause, and copy only
> the bytes after the header into adapter->event_body.  Keep the existing
> per-path total event-size checks so this stays a narrow bounds fix.
> 
> Signed-off-by: Pengpeng Hou <pengpeng@iscas.ac.cn>
> ---
>  drivers/net/wireless/marvell/mwifiex/sdio.c | 10 ++++++++--
>  drivers/net/wireless/marvell/mwifiex/usb.c  |  5 +++--
>  2 files changed, 11 insertions(+), 4 deletions(-)
> 
> --- a/drivers/net/wireless/marvell/mwifiex/sdio.c
> +++ b/drivers/net/wireless/marvell/mwifiex/sdio.c
> @@ -1712,12 +1712,18 @@
>  	case MWIFIEX_TYPE_EVENT:
>  		mwifiex_dbg(adapter, EVENT,
>  			    "info: --- Rx: Event ---\n");
> +		if (skb->len < MWIFIEX_EVENT_HEADER_LEN) {
> +			mwifiex_dbg(adapter, ERROR,
> +				    "event packet too short: %u\n", skb->len);
> +			dev_kfree_skb_any(skb);
> +			return -1;
> +		}
>  		adapter->event_cause = get_unaligned_le32(skb->data);
>  
> -		if ((skb->len > 0) && (skb->len  < MAX_EVENT_SIZE))
> +		if (skb->len < MAX_EVENT_SIZE)

if (skb->len >= MWIFIEX_EVENT_HEADER_LEN && ... , instead ?


if we want to free the skb and return -1, we should probably not just do
it when skb->len < MWIFIEX_EVENT_HEADER_LEN, but also when the frame is
too big?

Francesco


^ permalink raw reply

* [PATCH v2] wifi: mwifiex: bound uAP association event IEs to the event buffer
From: HE WEI (ギカク) @ 2026-07-15 13:57 UTC (permalink / raw)
  To: Brian Norris
  Cc: Francesco Dolcini, Miri Korenblit, Johannes Berg, Kees Cook,
	Kalle Valo, linux-wireless, linux-kernel,
	HE WEI (ギカク)

mwifiex_process_uap_event() handles EVENT_UAP_STA_ASSOC by exposing the
(re)association request IEs that the firmware copies into the event:

	sinfo->assoc_req_ies = &event->data[len];
	len = (u8 *)sinfo->assoc_req_ies - (u8 *)&event->frame_control;
	sinfo->assoc_req_ies_len = le16_to_cpu(event->len) - (u16)len;

event->len is supplied by the device firmware and is never validated,
and the subtraction is unchecked.  assoc_req_ies points into
adapter->event_body[MAX_EVENT_SIZE], a fixed-size array embedded in the
kmalloc()'d struct mwifiex_adapter.

On the ap_11n_enabled path mwifiex_set_sta_ht_cap() walks these IEs with
cfg80211_find_ie(), whose for_each_element() loop dereferences each
element header.  A firmware-reported event->len larger than the bytes
actually received makes assoc_req_ies_len describe IEs that extend past
event_body, so the walk reads out of the adapter slab object, a
slab-out-of-bounds read (KASAN: slab-out-of-bounds in cfg80211_find_ie).
An event->len smaller than the header instead makes the int subtraction
negative, which wraps to a huge size_t when stored in assoc_req_ies_len.
The same length is handed to cfg80211_new_sta(), so a more modest
over-claim can also copy stale event_body bytes into the
NL80211_CMD_NEW_STATION notification.

A malicious or malfunctioning mwifiex device (USB/SDIO/PCIe) can deliver
such an event while the interface is in AP/uAP mode.

Validate event->len before use: reject a length that underflows the
header or that would place the IEs outside the event_body[] buffer the
event was copied into.  event->len here is struct mwifiex_assoc_event.len,
a payload field internal to this event, not the transport frame length,
so it is validated in this handler rather than at the generic
MWIFIEX_TYPE_EVENT receive path, which only sees the event cause and the
transport frame length.  The bound is against event_body[MAX_EVENT_SIZE]
rather than the actually-received length because the transports store the
event differently (USB and SDIO leave the 4-byte event header in
event_skb, PCIe strips it via skb_pull), whereas event_body is the single
fixed buffer all of them copy the event into.  This is the event-path
analogue of the receive-path bounds checks added in commit 119585281617
("wifi: mwifiex: Fix OOB and integer underflow when rx packets").

Fixes: e568634ae7ac ("mwifiex: add AP event handling framework")
Signed-off-by: HE WEI (ギカク) <skyexpoc@gmail.com>
---
v2: fold le16_to_cpu(event->len) into a local evt_len as requested, which
    also shortens the bounds check.  No functional change.

 .../net/wireless/marvell/mwifiex/uap_event.c  | 24 +++++++++++++++++--
 1 file changed, 22 insertions(+), 2 deletions(-)

diff --git a/drivers/net/wireless/marvell/mwifiex/uap_event.c b/drivers/net/wireless/marvell/mwifiex/uap_event.c
index 679fdae0f001..ba1bdbbff687 100644
--- a/drivers/net/wireless/marvell/mwifiex/uap_event.c
+++ b/drivers/net/wireless/marvell/mwifiex/uap_event.c
@@ -123,11 +123,31 @@ int mwifiex_process_uap_event(struct mwifiex_private *priv)
 				len = ETH_ALEN;
 
 			if (len != -1) {
+				u16 evt_len = le16_to_cpu(event->len);
+
 				sinfo->assoc_req_ies = &event->data[len];
 				len = (u8 *)sinfo->assoc_req_ies -
 				      (u8 *)&event->frame_control;
-				sinfo->assoc_req_ies_len =
-					le16_to_cpu(event->len) - (u16)len;
+
+				/*
+				 * event->len is reported by the device firmware
+				 * and is not otherwise validated.  Reject a
+				 * length that underflows the header, or that
+				 * would place the association request IEs
+				 * outside the fixed-size event_body[] buffer the
+				 * event was copied into; otherwise the IE walk
+				 * in mwifiex_set_sta_ht_cap() reads past
+				 * event_body and out of the adapter slab object.
+				 */
+				if (evt_len < len ||
+				    (u8 *)&event->frame_control + evt_len >
+				    adapter->event_body + MAX_EVENT_SIZE) {
+					mwifiex_dbg(adapter, ERROR,
+						    "invalid STA assoc event length\n");
+					kfree(sinfo);
+					return -1;
+				}
+				sinfo->assoc_req_ies_len = evt_len - (u16)len;
 			}
 		}
 		cfg80211_new_sta(priv->netdev->ieee80211_ptr, event->sta_addr,
-- 
2.54.0


^ permalink raw reply related


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox