Linux wireless drivers development
 help / color / mirror / Atom feed
* Re: [PATCH ath-next v2 0/2] wifi: ath12k: fix peer delete race in MLO scenario
From: Rameshkumar Sundaram @ 2026-07-13  4:58 UTC (permalink / raw)
  To: Baochen Qiang, Jeff Johnson; +Cc: linux-wireless, ath12k
In-Reply-To: <20260629-ath12k-mlo-peer-delete-race-v2-0-362b25590d19@oss.qualcomm.com>

On 6/29/2026 12:31 PM, Baochen Qiang wrote:
> Patch 1 fixes a pre-existing UAF in ath12k_mac_vdev_create()'s
> err_peer_del rollback path.
> 
> Patch 2 fixes "Timeout in receiving peer delete response" on MLO
> disconnect, caused by a per-radio shared completion that gets
> clobbered between back-to-back WMI peer_delete sends.
> 
> Signed-off-by: Baochen Qiang <baochen.qiang@oss.qualcomm.com>
> ---
> Changes in v2:
> - rebased on ToT
> - patch 2/2: make ath12k_peer_delete_wait_register()
>               and ath12k_peer_delete_wait_unregister() static to peer.c
> - Link to v1: https://lore.kernel.org/r/20260617-ath12k-mlo-peer-delete-race-v1-0-ab3c4f455dfb@oss.qualcomm.com
> 
> ---
> Baochen Qiang (2):
>        wifi: ath12k: fix dp_link_peer dangling references on AP vdev rollback
>        wifi: ath12k: fix MLO peer delete race
> 
>   drivers/net/wireless/ath/ath12k/core.c |   2 +-
>   drivers/net/wireless/ath/ath12k/core.h |   5 +-
>   drivers/net/wireless/ath/ath12k/mac.c  |  20 +----
>   drivers/net/wireless/ath/ath12k/peer.c | 130 ++++++++++++++++++++++++++-------
>   drivers/net/wireless/ath/ath12k/peer.h |  14 +++-
>   drivers/net/wireless/ath/ath12k/wmi.c  |  16 ++--
>   6 files changed, 133 insertions(+), 54 deletions(-)
> ---
> base-commit: 1547a99cd8d8c1ab3e04dbd92b72b3b5f7cb85a9
Reviewed-by: Rameshkumar Sundaram <rameshkumar.sundaram@oss.qualcomm.com>

^ permalink raw reply

* Re: [PATCH 1/2] wifi: ath12k: skip PCIe global reset on initial power-up
From: Nazar Mokrynskyi @ 2026-07-13  3:34 UTC (permalink / raw)
  To: Baochen Qiang, ath12k; +Cc: linux-wireless, jeff.johnson
In-Reply-To: <fe668799-6024-4370-acfc-ee64fb3a4d5c@oss.qualcomm.com>

The patches I sent only allow VM to start once.
Any attempt to shutdown or reboot the VM results in host crashing instantly due to PCIe errors.

The only way to somewhat gracefully reboot the host that I found is to unbind corresponding host bridge first (so it doesn't propagate PCIe error), then kill the VM (instead of attempting to shut down gracefully) and then reboot the host.

This is not great, but still much better than not being able to use the hardware at all. These cards were paperweight for me for far too long.
I've been running a system with these patches for probably close to 3 months now and have not found other issues except performance is not that great.

I sent a suggestion to allow ignoring PCIe errors in vfio so it doesn't crash the host here: https://lore.kernel.org/kvm/70de9b8f-b7c7-481b-8cb1-931e3b82eb0e@mokrynskyi.com/
But maintainers weren't too happy about it.

While searching for that thread I found this recent development, which looks related to the issues I'm having: https://lkml.org/lkml/2026/6/30/398

Sincerely, Nazar Mokrynskyi
github.com/nazar-pc

13.07.26 06:03, Baochen Qiang:
>
> On 5/6/2026 1:24 AM, Nazar Mokrynskyi wrote:
>> ath12k_pci_sw_reset() unconditionally calls ath12k_pci_soc_global_reset()
>> regardless of whether the device is being powered up for the first time or
>> recovering from a previous run. The global reset drops the PCIe link and
>> relies on the host root complex to perform physical link retraining before
>> the MHI BHI register can be accessed.
>>
>> When the device is passed through to a VM via VFIO, no physical link
>> retraining occurs after the reset since QEMU's virtual PCIe bridge does
>> not implement hardware LTSSM negotiation. As a result, all subsequent
>> MMIO reads return 0xffffffff and MHI initialization fails with -EREMOTEIO.
>>
>> On initial power-up, vfio-pci has already performed a Function Level
>> Reset before handing the device to the guest driver, placing it in a
>> known clean state equivalent to what the global reset achieves. The global
> AFAIK this is not the fact. Some internal registers are not cleanly reset without a global
> reset.
>
>> reset is therefore redundant on power-up and only necessary on the
>> shutdown/recovery path where it tears down an already-running firmware.
> is ath12k recovery working in Qemu in your setup? I doubt it since recovery would also hit
> the link retraining issue ? Also how about the rmmod / insmod sequence in Qemu, since
> rmmod also triggers global reset ?
>
> To me this is more like a Qemu/vfio issue than a driver issue. The QEMU's behavior that
> virtual PCIe bridge does not implement hardware LTSSM negotiation basically breaks all
> hardware requiring runtime PCIe link retraining. Not sure why it is designed like this. If
> it can not be fixed/changed in Qemu, can we do it in the host vfio?
>
>> Skip ath12k_pci_soc_global_reset() when power_on is true to allow MHI
>> initialization to succeed under VFIO passthrough without affecting bare
>> metal behavior.
>>
>> Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.6-01243-QCAHKSWPL_SILICONZ-1
>>
>> Signed-off-by: Nazar Mokrynskyi <nazar@mokrynskyi.com>
>> ---
>>  drivers/net/wireless/ath/ath12k/pci.c | 3 ++-
>>  1 file changed, 2 insertions(+), 1 deletion(-)
>>
>> diff --git a/drivers/net/wireless/ath/ath12k/pci.c b/drivers/net/wireless/ath/ath12k/pci.c
>> index 375277ca2..a3d7aeb72 100644
>> --- a/drivers/net/wireless/ath/ath12k/pci.c
>> +++ b/drivers/net/wireless/ath/ath12k/pci.c
>> @@ -303,7 +303,8 @@ static void ath12k_pci_sw_reset(struct ath12k_base *ab, bool power_on)
>>  
>>  	ath12k_mhi_clear_vector(ab);
>>  	ath12k_pci_clear_dbg_registers(ab);
>> -	ath12k_pci_soc_global_reset(ab);
>> +	if (!power_on)
>> +		ath12k_pci_soc_global_reset(ab);
>>  	ath12k_mhi_set_mhictrl_reset(ab);
>>  }
>>  

^ permalink raw reply

* Re: [PATCH] wifi: ath12k: release QMI handle on late init failures
From: Baochen Qiang @ 2026-07-13  3:33 UTC (permalink / raw)
  To: Guangshuo Li, Jeff Johnson, Vasanthakumar Thiagarajan,
	linux-wireless, ath12k, linux-kernel
In-Reply-To: <20260708100924.744386-1-lgs201920130244@gmail.com>



On 7/8/2026 6:09 PM, Guangshuo Li wrote:
> The change referenced by the Fixes tag makes hardware group creation
> skip the device whose ath12k_core_soc_create() failed, and only destroys
> devices that were created successfully before it.
> 
> That avoids releasing an uninitialized QMI handle when qmi_handle_init()
> fails, but it also means that ath12k_qmi_init_service() must clean up any
> resources it has already acquired before returning an error.
> 
> qmi_handle_init() can succeed before later initialization steps fail. If
> the QMI event workqueue allocation fails, or qmi_add_lookup() fails, the
> function returns an error without releasing the already initialized QMI
> handle. Since the failed device is now skipped by the hardware group
> rollback path, that handle is leaked.
> 
> Release the QMI handle on those late failure paths and clear ab->qmi.ab
> so the failed device is left in the same state as the qmi_handle_init()
> failure path.
> 
> Fixes: 088a099690e4 ("wifi: ath12k: fix error handling in creating hardware group")
> Signed-off-by: Guangshuo Li <lgs201920130244@gmail.com>
> ---
>  drivers/net/wireless/ath/ath12k/qmi.c | 11 +++++++++--
>  1 file changed, 9 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/net/wireless/ath/ath12k/qmi.c b/drivers/net/wireless/ath/ath12k/qmi.c
> index fd762b5d7bb5..31e9fa9a62be 100644
> --- a/drivers/net/wireless/ath/ath12k/qmi.c
> +++ b/drivers/net/wireless/ath/ath12k/qmi.c
> @@ -4054,7 +4054,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 +4068,15 @@ 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;
>  	}
>  
> +	return ret;
> +
> +err_release_qmi_handle:
> +	qmi_handle_release(&ab->qmi.handle);
> +	ab->qmi.ab = NULL;

since ath12k_qmi_deinit_service() NULL-checks ab->qmi.ab to determine whether qmi service
init succeeds, does it make more sense to move ab->qmi.ab initialization in
ath12k_qmi_init_service() to the last step? This achieves symmetry and also avoids reset
in the failure path.

> +
>  	return ret;
>  }
>  


^ permalink raw reply

* Re: [PATCH] wifi: ath12k: release QMI handle on late init failures
From: Baochen Qiang @ 2026-07-13  3:27 UTC (permalink / raw)
  To: Guangshuo Li, Jeff Johnson, Vasanthakumar Thiagarajan,
	linux-wireless, ath12k, linux-kernel
In-Reply-To: <8133bce1-2b7e-46fb-8989-f5946ff341a8@oss.qualcomm.com>



On 7/13/2026 11:17 AM, Baochen Qiang wrote:
> 
> 
> On 7/8/2026 6:09 PM, Guangshuo Li wrote:
>> The change referenced by the Fixes tag makes hardware group creation
>> skip the device whose ath12k_core_soc_create() failed, and only destroys
>> devices that were created successfully before it.
>>
>> That avoids releasing an uninitialized QMI handle when qmi_handle_init()
>> fails, but it also means that ath12k_qmi_init_service() must clean up any
>> resources it has already acquired before returning an error.
>>
>> qmi_handle_init() can succeed before later initialization steps fail. If
>> the QMI event workqueue allocation fails, or qmi_add_lookup() fails, the
>> function returns an error without releasing the already initialized QMI
>> handle. Since the failed device is now skipped by the hardware group
>> rollback path, that handle is leaked.
>>
>> Release the QMI handle on those late failure paths and clear ab->qmi.ab
>> so the failed device is left in the same state as the qmi_handle_init()
>> failure path.
>>
>> Fixes: 088a099690e4 ("wifi: ath12k: fix error handling in creating hardware group")
>> Signed-off-by: Guangshuo Li <lgs201920130244@gmail.com>
>> ---
>>  drivers/net/wireless/ath/ath12k/qmi.c | 11 +++++++++--
>>  1 file changed, 9 insertions(+), 2 deletions(-)
>>
>> diff --git a/drivers/net/wireless/ath/ath12k/qmi.c b/drivers/net/wireless/ath/ath12k/qmi.c
>> index fd762b5d7bb5..31e9fa9a62be 100644
>> --- a/drivers/net/wireless/ath/ath12k/qmi.c
>> +++ b/drivers/net/wireless/ath/ath12k/qmi.c
>> @@ -4054,7 +4054,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 +4068,15 @@ 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;
>>  	}
>>  
>> +	return ret;
>> +
>> +err_release_qmi_handle:
>> +	qmi_handle_release(&ab->qmi.handle);
>> +	ab->qmi.ab = NULL;
> 
> should this be ?
> 
> 	ab->qmi.handle = NULL;

I was wrong, please ignore this comment.

> 
>> +
>>  	return ret;
>>  }
>>  
> 


^ permalink raw reply

* Re: [PATCH] wifi: ath12k: release QMI handle on late init failures
From: Baochen Qiang @ 2026-07-13  3:17 UTC (permalink / raw)
  To: Guangshuo Li, Jeff Johnson, Vasanthakumar Thiagarajan,
	linux-wireless, ath12k, linux-kernel
In-Reply-To: <20260708100924.744386-1-lgs201920130244@gmail.com>



On 7/8/2026 6:09 PM, Guangshuo Li wrote:
> The change referenced by the Fixes tag makes hardware group creation
> skip the device whose ath12k_core_soc_create() failed, and only destroys
> devices that were created successfully before it.
> 
> That avoids releasing an uninitialized QMI handle when qmi_handle_init()
> fails, but it also means that ath12k_qmi_init_service() must clean up any
> resources it has already acquired before returning an error.
> 
> qmi_handle_init() can succeed before later initialization steps fail. If
> the QMI event workqueue allocation fails, or qmi_add_lookup() fails, the
> function returns an error without releasing the already initialized QMI
> handle. Since the failed device is now skipped by the hardware group
> rollback path, that handle is leaked.
> 
> Release the QMI handle on those late failure paths and clear ab->qmi.ab
> so the failed device is left in the same state as the qmi_handle_init()
> failure path.
> 
> Fixes: 088a099690e4 ("wifi: ath12k: fix error handling in creating hardware group")
> Signed-off-by: Guangshuo Li <lgs201920130244@gmail.com>
> ---
>  drivers/net/wireless/ath/ath12k/qmi.c | 11 +++++++++--
>  1 file changed, 9 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/net/wireless/ath/ath12k/qmi.c b/drivers/net/wireless/ath/ath12k/qmi.c
> index fd762b5d7bb5..31e9fa9a62be 100644
> --- a/drivers/net/wireless/ath/ath12k/qmi.c
> +++ b/drivers/net/wireless/ath/ath12k/qmi.c
> @@ -4054,7 +4054,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 +4068,15 @@ 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;
>  	}
>  
> +	return ret;
> +
> +err_release_qmi_handle:
> +	qmi_handle_release(&ab->qmi.handle);
> +	ab->qmi.ab = NULL;

should this be ?

	ab->qmi.handle = NULL;

> +
>  	return ret;
>  }
>  


^ permalink raw reply

* Re: [PATCH 2/3] wifi: mt76: mt792x: Add TX page pool support for IOMMU-enabled systems
From: Eason Lai (賴易聖) @ 2026-07-13  3:13 UTC (permalink / raw)
  To: lorenzo@kernel.org
  Cc: Yf Luo (羅元富), nbd@nbd.name,
	Kun Wu (吳謹至), Quan Zhou (周全),
	Deren Wu (武德仁), Ryder Lee,
	linux-wireless@vger.kernel.org, Sean Wang,
	Leon Yen (顏良儒),
	linux-mediatek@lists.infradead.org,
	Litien Chang (張立典),
	JB Tsai (蔡志彬)
In-Reply-To: <ak9bWO47T3fo2NkI@lore-desk>

On Thu, 2026-07-09 at 10:27 +0200, Lorenzo Bianconi wrote:
> On Jul 09, Eason Lai wrote:
> > From: Eason Lai <Eason.Lai@mediatek.com>
> > 
> > Add support for TX page pool allocation in mt792x devices when
> > IOMMU is
> > enabled. This optimization reduces DMA mapping overhead by
> > pre-allocating and reusing page pool buffers for TX operations.
> 
> Can you please provide some test results here? In particular
> regarding the
> resulting throughput.
> 

On MT8196, the HE160 TCP UL peak throuhgput could drop below 1.4Gbps
when IOMMU is enabled. With this series, the throughput reaches the
expected performance (>1.8G bps).

> > 
> > Key changes:
> > - Export DMA helper functions and ops for mt792x usage
> >   - Add tx_prealloc_enabled flag to track page pool state
> >     - Implement mt792x-specific DMA queue operations with TX page
> > pool
> >       - Create page pools per TX queue when IOMMU is detected
> >         - Handle page pool buffer cleanup in both success and error
> >           paths
> > - Add proper skip_unmap flag handling for page pool buffers
> > 
> > The page pool path is used for linear skbs without fragments,
> > falling
> > back to standard DMA mapping for complex skb structures.
> > 
> > Signed-off-by: Eason Lai <Eason.Lai@mediatek.com>
> > ---
> 
> [...]
> 
> >  
> > -static void
> > +void
> >  mt76_dma_kick_queue(struct mt76_dev *dev, struct mt76_queue *q)
> >  {
> >  	wmb();
> > @@ -409,6 +417,7 @@ mt76_dma_kick_queue(struct mt76_dev *dev,
> > struct mt76_queue *q)
> >  	else
> >  		Q_WRITE(q, cpu_idx, q->head);
> >  }
> > +EXPORT_SYMBOL_GPL(mt76_dma_kick_queue);
> 
> this is already available in mt76_queue_ops struct.
> 

Thanks. I'll use mt76_queue_kick() in v2.

> >  
> >  static void
> >  mt76_dma_tx_cleanup(struct mt76_dev *dev, struct mt76_queue *q,
> > bool flush)
> > @@ -1152,7 +1161,7 @@ mt76_dma_init(struct mt76_dev *dev,
> >  	return 0;
> >  }
> >  
> > -static const struct mt76_queue_ops mt76_dma_ops = {
> > +const struct mt76_queue_ops mt76_dma_ops = {
> >  	.init = mt76_dma_init,
> >  	.alloc = mt76_dma_alloc_queue,
> >  	.reset_q = mt76_dma_queue_reset,
> > @@ -1164,6 +1173,7 @@ static const struct mt76_queue_ops
> > mt76_dma_ops = {
> >  	.rx_reset = mt76_dma_rx_reset,
> >  	.kick = mt76_dma_kick_queue,
> >  };
> > +EXPORT_SYMBOL_GPL(mt76_dma_ops);
> >  
> >  void mt76_dma_attach(struct mt76_dev *dev)
> >  {
> > diff --git a/drivers/net/wireless/mediatek/mt76/mt76.h
> > b/drivers/net/wireless/mediatek/mt76/mt76.h
> > index 927c21536f4e..25e24fa36eca 100644
> > --- a/drivers/net/wireless/mediatek/mt76/mt76.h
> > +++ b/drivers/net/wireless/mediatek/mt76/mt76.h
> > @@ -957,6 +957,8 @@ struct mt76_dev {
> >  	int tx_dma_idx[4];
> >  	enum mt76_hwrro_mode hwrro_mode;
> >  
> > +	bool tx_prealloc_enabled;
> > +
> >  	struct mt76_worker tx_worker;
> >  	struct napi_struct tx_napi;
> >  
> > @@ -1785,7 +1787,16 @@ mt76_tx_status_get_hw(struct mt76_dev *dev,
> > struct sk_buff *skb)
> >  
> >  void mt76_put_txwi(struct mt76_dev *dev, struct mt76_txwi_cache
> > *t);
> >  void mt76_put_rxwi(struct mt76_dev *dev, struct mt76_txwi_cache
> > *t);
> > +struct mt76_txwi_cache *mt76_get_txwi(struct mt76_dev *dev);
> >  struct mt76_txwi_cache *mt76_get_rxwi(struct mt76_dev *dev);
> > +int mt76_dma_add_buf(struct mt76_dev *dev, struct mt76_queue *q,
> > +		     struct mt76_queue_buf *buf, int nbufs, u32
> > info,
> > +		     struct sk_buff *skb, void *txwi);
> > +void mt76_dma_tx_cleanup_idx(struct mt76_dev *dev, struct
> > mt76_queue *q, int idx,
> > +			     struct mt76_queue_entry *prev_e);
> > +void mt76_dma_kick_queue(struct mt76_dev *dev, struct mt76_queue
> > *q);
> > +void mt76_dma_sync_idx(struct mt76_dev *dev, struct mt76_queue
> > *q);
> > +extern const struct mt76_queue_ops mt76_dma_ops;
> >  void mt76_free_pending_rxwi(struct mt76_dev *dev);
> >  void mt76_rx_complete(struct mt76_dev *dev, struct sk_buff_head
> > *frames,
> >  		      struct napi_struct *napi);
> > diff --git a/drivers/net/wireless/mediatek/mt76/mt76_connac_mac.c
> > b/drivers/net/wireless/mediatek/mt76/mt76_connac_mac.c
> > index 0339e2e7ab60..d4b36b0832b8 100644
> > --- a/drivers/net/wireless/mediatek/mt76/mt76_connac_mac.c
> > +++ b/drivers/net/wireless/mediatek/mt76/mt76_connac_mac.c
> > @@ -250,6 +250,12 @@ void mt76_connac_txp_skb_unmap(struct mt76_dev
> > *dev,
> >  {
> >  	struct mt76_connac_txp_common *txp;
> >  
> > +	if (t->page_pool_buf) {
> > +		mt76_put_page_pool_buf(t->page_pool_buf, false);
> > +		t->page_pool_buf = NULL;
> > +		return;
> > +	}
> > +
> >  	txp = mt76_connac_txwi_to_txp(dev, t);
> >  	if (is_mt76_fw_txp(dev))
> >  		mt76_connac_txp_skb_unmap_fw(dev, &txp->fw);
> > diff --git a/drivers/net/wireless/mediatek/mt76/mt7925/pci.c
> > b/drivers/net/wireless/mediatek/mt76/mt7925/pci.c
> > index c4161754c01d..3d69d8c67dea 100644
> > --- a/drivers/net/wireless/mediatek/mt76/mt7925/pci.c
> > +++ b/drivers/net/wireless/mediatek/mt76/mt7925/pci.c
> > @@ -214,7 +214,7 @@ static int mt7925_dma_init(struct mt792x_dev
> > *dev)
> >  {
> >  	int ret;
> >  
> > -	mt76_dma_attach(&dev->mt76);
> > +	mt792x_dma_attach(&dev->mt76);
> >  
> >  	ret = mt792x_dma_disable(dev, true);
> >  	if (ret)
> > @@ -263,6 +263,8 @@ static int mt7925_dma_init(struct mt792x_dev
> > *dev)
> >  			  mt792x_poll_tx);
> >  	napi_enable(&dev->mt76.tx_napi);
> >  
> > +	mt792x_dma_tx_page_pool_init(dev);
> > +
> >  	return mt792x_dma_enable(dev);
> >  }
> >  
> > diff --git a/drivers/net/wireless/mediatek/mt76/mt792x.h
> > b/drivers/net/wireless/mediatek/mt76/mt792x.h
> > index 4ff93f2cd624..7ac0318dc249 100644
> > --- a/drivers/net/wireless/mediatek/mt76/mt792x.h
> > +++ b/drivers/net/wireless/mediatek/mt76/mt792x.h
> > @@ -418,8 +418,10 @@ void mt792x_sta_statistics(struct ieee80211_hw
> > *hw,
> >  			   struct station_info *sinfo);
> >  void mt792x_set_coverage_class(struct ieee80211_hw *hw, int
> > radio_idx,
> >  			       s16 coverage_class);
> > +void mt792x_dma_attach(struct mt76_dev *dev);
> >  void mt792x_dma_cleanup(struct mt792x_dev *dev);
> >  int mt792x_dma_enable(struct mt792x_dev *dev);
> > +int mt792x_dma_tx_page_pool_init(struct mt792x_dev *dev);
> >  int mt792x_wpdma_reset(struct mt792x_dev *dev, bool force);
> >  int mt792x_wpdma_reinit_cond(struct mt792x_dev *dev);
> >  int mt792x_dma_disable(struct mt792x_dev *dev, bool force);
> > diff --git a/drivers/net/wireless/mediatek/mt76/mt792x_dma.c
> > b/drivers/net/wireless/mediatek/mt76/mt792x_dma.c
> > index 002aece857b2..b341f1cb3ce0 100644
> > --- a/drivers/net/wireless/mediatek/mt76/mt792x_dma.c
> > +++ b/drivers/net/wireless/mediatek/mt76/mt792x_dma.c
> > @@ -3,6 +3,9 @@
> >  
> >  #include <linux/module.h>
> >  #include <linux/firmware.h>
> > +#include <linux/iommu.h>
> > +#include <net/page_pool/helpers.h>
> > +#include <linux/of.h>
> >  
> >  #include "mt792x.h"
> >  #include "dma.h"
> > @@ -266,6 +269,323 @@ int mt792x_wpdma_reinit_cond(struct
> > mt792x_dev *dev)
> >  }
> >  EXPORT_SYMBOL_GPL(mt792x_wpdma_reinit_cond);
> >  
> > +static int mt792x_create_tx_page_pool(struct mt76_dev *dev, struct
> > mt76_queue *q)
> > +{
> > +	struct page_pool_params pp_params = {
> > +		.order = 0,
> > +		.flags = 0,
> > +		.nid = NUMA_NO_NODE,
> > +		.dev = dev->dma_dev,
> > +	};
> > +
> > +	if (!q || !dev->tx_prealloc_enabled)
> > +		return 0;
> > +
> > +	if (!mt76_is_mmio(dev))
> > +		return 0;
> 
> do you really need this check? you already check it in
> mt792x_dma_tx_page_pool_init().
> 

OK, I will remove it in v2.

> > +
> > +	pp_params.pool_size = 256;
> > +	pp_params.flags |= PP_FLAG_DMA_MAP;
> > +	pp_params.dma_dir = DMA_BIDIRECTIONAL;
> > +	pp_params.max_len = PAGE_SIZE;
> > +	pp_params.offset = 0;
> > +
> > +	q->page_pool = page_pool_create(&pp_params);
> > +	if (IS_ERR(q->page_pool)) {
> > +		int err = PTR_ERR(q->page_pool);
> > +
> > +		q->page_pool = NULL;
> > +		dev_warn(dev->dev, "Failed to create TX page pool
> > for queue %d (err=%d)\n",
> > +			 q->hw_idx, err);
> > +		return 0;
> > +	}
> > +
> > +	return 0;
> > +}
> > +
> > +int mt792x_dma_tx_page_pool_init(struct mt792x_dev *dev)
> > +{
> > +	struct mt76_dev *mdev = &dev->mt76;
> > +	int i, ret, pool_count = 0;
> > +
> > +	if (!iommu_get_domain_for_dev(mdev->dma_dev))
> > +		return 0;
> > +
> > +	if (!mt76_is_mmio(mdev))
> > +		return 0;
> > +
> > +	mdev->tx_prealloc_enabled = true;
> > +
> > +	for (i = 0; i < ARRAY_SIZE(mdev->phy.q_tx); i++) {
> > +		struct mt76_queue *q = mdev->phy.q_tx[i];
> > +
> > +		if (!q)
> > +			continue;
> > +
> > +		ret = mt792x_create_tx_page_pool(mdev, q);
> > +		if (ret)
> > +			return ret;
> > +
> > +		if (q->page_pool)
> > +			pool_count++;
> > +	}
> > +
> > +	if (pool_count > 0)
> > +		dev_info(mdev->dev,
> > +			 "IOMMU enabled, created %d TX page
> > pools\n", pool_count);
> > +
> > +	return 0;
> > +}
> > +EXPORT_SYMBOL_GPL(mt792x_dma_tx_page_pool_init);
> > +
> > +static void mt792x_dma_tx_page_pool_cleanup(struct mt792x_dev
> > *dev)
> > +{
> > +	struct mt76_dev *mdev = &dev->mt76;
> > +	int i;
> > +
> > +	for (i = 0; i < ARRAY_SIZE(mdev->phy.q_tx); i++) {
> > +		struct mt76_queue *q = mdev->phy.q_tx[i];
> > +
> > +		if (!q || !q->page_pool)
> > +			continue;
> > +
> > +		page_pool_destroy(q->page_pool);
> > +		q->page_pool = NULL;
> > +	}
> > +
> > +	mdev->tx_prealloc_enabled = false;
> > +}
> > +
> > +static void *
> > +mt792x_dma_tx_alloc_page_pool_buf(struct mt76_dev *dev, struct
> > mt76_queue *q,
> > +				  struct sk_buff *skb, dma_addr_t
> > *dma_addr,
> > +				  int *buf_len)
> > +{
> > +	struct page *page;
> > +	void *buf;
> > +	int len;
> > +	u32 offset;
> > +
> > +	if (!q->page_pool || !dev->tx_prealloc_enabled)
> > +		return NULL;
> > +
> > +	len = skb_headlen(skb);
> > +	if (len > PAGE_SIZE)
> > +		return NULL;
> > +
> > +	buf = mt76_get_page_pool_buf(q, &offset, len);
> > +	if (!buf)
> > +		return NULL;
> > +
> > +	page = virt_to_head_page(buf);
> > +	*dma_addr = page_pool_get_dma_addr(page) + offset;
> > +	if (unlikely(!*dma_addr)) {
> > +		dev_warn_ratelimited(dev->dev, "Page pool returned
> > NULL DMA address\n");
> > +		mt76_put_page_pool_buf(buf, false);
> > +		return NULL;
> > +	}
> > +
> > +	*buf_len = len;
> > +
> > +	dma_sync_single_for_cpu(dev->dma_dev, *dma_addr, len,
> > DMA_TO_DEVICE);
> > +	skb_copy_from_linear_data(skb, buf, len);
> 
> I would like to see some results here since usually it is not a good
> idea to
> copy all the packets (even if it is just the linear part).
> 

The results are shown above.

> > +	dma_sync_single_for_device(dev->dma_dev, *dma_addr, len,
> > DMA_TO_DEVICE);
> > +
> > +	return buf;
> > +}
> > +
> > +static int
> > +mt792x_dma_tx_queue_skb(struct mt76_phy *phy, struct mt76_queue
> > *q,
> > +			enum mt76_txq_id qid, struct sk_buff *skb,
> > +			struct mt76_wcid *wcid, struct
> > ieee80211_sta *sta)
> > +{
> > +	struct ieee80211_tx_status status = {
> > +		.sta = sta,
> > +	};
> > +	struct mt76_tx_info tx_info = {
> > +		.skb = skb,
> > +	};
> > +	struct mt76_dev *dev = phy->dev;
> > +	struct ieee80211_hw *hw;
> > +	int len, n = 0, ret = -ENOMEM;
> > +	struct mt76_txwi_cache *t;
> > +	struct sk_buff *iter;
> > +	dma_addr_t addr;
> > +	u8 *txwi;
> > +
> > +	if (test_bit(MT76_RESET, &phy->state))
> > +		goto free_skb;
> > +
> > +	t = mt76_get_txwi(dev);
> > +	if (!t)
> > +		goto free_skb;
> > +
> > +	txwi = mt76_get_txwi_ptr(dev, t);
> > +
> > +	skb->prev = NULL;
> > +	skb->next = NULL;
> > +	if (dev->drv->drv_flags & MT_DRV_TX_ALIGNED4_SKBS)
> > +		mt76_insert_hdr_pad(skb);
> > +
> > +	len = skb_headlen(skb);
> > +
> > +	if (dev->tx_prealloc_enabled && q->page_pool &&
> > +	    !skb_has_frag_list(skb) && !skb_shinfo(skb)->nr_frags)
> > {
> > +		void *buf;
> > +		int pp_len;
> > +
> > +		buf = mt792x_dma_tx_alloc_page_pool_buf(dev, q,
> > skb, &addr, &pp_len);
> > +		if (buf) {
> > +			t->page_pool_buf = buf;
> > +			len = pp_len;
> > +
> > +			tx_info.buf[n].addr = t->dma_addr;
> > +			tx_info.buf[n++].len = dev->drv-
> > >txwi_size;
> > +			tx_info.buf[n].addr = addr;
> > +			tx_info.buf[n].len = len;
> > +			tx_info.buf[n].skip_unmap = true;
> > +			n++;
> > +
> > +			goto skip_dma_map;
> > +		}
> > +	}
> > +
> > +	addr = dma_map_single(dev->dma_dev, skb->data, len,
> > DMA_TO_DEVICE);
> > +	if (unlikely(dma_mapping_error(dev->dma_dev, addr)))
> > +		goto free;
> > +
> > +	t->page_pool_buf = NULL;
> > +
> > +	tx_info.buf[n].addr = t->dma_addr;
> > +	tx_info.buf[n++].len = dev->drv->txwi_size;
> > +	tx_info.buf[n].addr = addr;
> > +	tx_info.buf[n++].len = len;
> > +
> > +skip_dma_map:
> > +	skb_walk_frags(skb, iter) {
> > +		if (n == ARRAY_SIZE(tx_info.buf))
> > +			goto unmap;
> > +
> > +		addr = dma_map_single(dev->dma_dev, iter->data,
> > iter->len,
> > +				      DMA_TO_DEVICE);
> > +		if (unlikely(dma_mapping_error(dev->dma_dev,
> > addr)))
> > +			goto unmap;
> > +
> > +		tx_info.buf[n].addr = addr;
> > +		tx_info.buf[n].skip_unmap = false;
> > +		tx_info.buf[n++].len = iter->len;
> > +	}
> > +	tx_info.nbuf = n;
> > +
> > +	if (q->queued + (tx_info.nbuf + 1) / 2 >= q->ndesc - 1) {
> > +		ret = -ENOMEM;
> > +		goto unmap;
> > +	}
> > +
> > +	dma_sync_single_for_cpu(dev->dma_dev, t->dma_addr, dev-
> > >drv->txwi_size,
> > +				DMA_TO_DEVICE);
> > +	ret = dev->drv->tx_prepare_skb(dev, txwi, qid, wcid, sta,
> > &tx_info);
> > +	dma_sync_single_for_device(dev->dma_dev, t->dma_addr, dev-
> > >drv->txwi_size,
> > +				   DMA_TO_DEVICE);
> > +	if (ret < 0)
> > +		goto unmap;
> > +
> > +	return mt76_dma_add_buf(dev, q, tx_info.buf, tx_info.nbuf,
> > +				tx_info.info, tx_info.skb, t);
> > +
> > +unmap:
> > +	for (n--; n > 0; n--) {
> > +		if (!tx_info.buf[n].skip_unmap)
> > +			dma_unmap_single(dev->dma_dev,
> > tx_info.buf[n].addr,
> > +					 tx_info.buf[n].len,
> > DMA_TO_DEVICE);
> > +	}
> > +
> > +	if (t->page_pool_buf) {
> > +		mt76_put_page_pool_buf(t->page_pool_buf, false);
> > +		t->page_pool_buf = NULL;
> > +	}
> > +
> > +free:
> > +#ifdef CONFIG_NL80211_TESTMODE
> > +	if (mt76_is_testmode_skb(dev, skb, &hw)) {
> > +		struct mt76_phy *phy = hw->priv;
> > +
> > +		if (tx_info.skb == phy->test.tx_skb)
> > +			phy->test.tx_done--;
> > +	}
> > +#endif
> > +
> > +	mt76_put_txwi(dev, t);
> > +
> > +free_skb:
> > +	status.skb = tx_info.skb;
> > +	hw = mt76_tx_status_get_hw(dev, tx_info.skb);
> > +	spin_lock_bh(&dev->rx_lock);
> > +	ieee80211_tx_status_ext(hw, &status);
> > +	spin_unlock_bh(&dev->rx_lock);
> > +
> > +	return ret;
> > +}
> > +
> > +static void
> > +mt792x_dma_tx_cleanup(struct mt76_dev *dev, struct mt76_queue *q,
> > bool flush)
> 
> this is almost a copy of mt76_dma_tx_cleanup(). Can we do something
> better
> here?
> 

Yes, it's minor enough that there's no need to split the logic into a
separate mt792x_dma_tx_cleanup() function. I will make the change in
mt76_dma_tx_cleanup() in v2. 
 
> > +{
> > +	struct mt76_queue_entry entry;
> > +	int last;
> > +
> > +	if (!q || !q->ndesc)
> > +		return;
> > +
> > +	spin_lock_bh(&q->cleanup_lock);
> > +	if (flush)
> > +		last = -1;
> > +	else
> > +		last = Q_READ(q, dma_idx);
> > +
> > +	while (q->queued > 0 && q->tail != last) {
> > +		mt76_dma_tx_cleanup_idx(dev, q, q->tail, &entry);
> > +		mt76_npu_txdesc_cleanup(q, q->tail);
> > +		mt76_queue_tx_complete(dev, q, &entry);
> > +
> > +		if (entry.txwi) {
> > +			if (entry.skb && entry.txwi-
> > >page_pool_buf) {
> > +				mt76_put_page_pool_buf(entry.txwi-
> > >page_pool_buf, false);
> > +				entry.txwi->page_pool_buf = NULL;
> > +			}
> > +
> > +			if (!(dev->drv->drv_flags &
> > MT_DRV_TXWI_NO_FREE))
> > +				mt76_put_txwi(dev, entry.txwi);
> > +		}
> > +
> > +		if (!flush && q->tail == last)
> > +			last = Q_READ(q, dma_idx);
> > +	}
> > +	spin_unlock_bh(&q->cleanup_lock);
> > +
> > +	if (flush) {
> > +		spin_lock_bh(&q->lock);
> > +		mt76_dma_sync_idx(dev, q);
> > +		mt76_dma_kick_queue(dev, q);
> > +		spin_unlock_bh(&q->lock);
> > +	}
> > +
> > +	if (!q->queued)
> > +		wake_up(&dev->tx_wait);
> > +}
> > +
> > +static struct mt76_queue_ops mt792x_queue_ops;
> > +
> > +void mt792x_dma_attach(struct mt76_dev *dev)
> > +{
> > +	mt792x_queue_ops = mt76_dma_ops;
> 
> can you please take a look to mt7615_mmio_probe()?
> 
> Regards,
> Lorenzo
> 

Yes, I've referenced it and will make this change in v2 if you're OK
with it.

    void mt792x_dma_attach(struct mt76_dev *dev)
    {
    -    mt702x_queue_ops = mt76_dma_ops;
    +    mt76_dma_attach(dev);
    +    mt792x_queue_ops = *dev->queue_ops;
    +    mt792x_queue_ops.tx_queue_skb = mt792x_dma_tx_queue_skb;
    -    mt792x_queue_ops.tx_cleanup = mt792x_dma_tx_cleanup;
         dev->queue_ops = &mt792x_queue_ops;
    }

Thanks,
Eason

> > +
> > +	mt792x_queue_ops.tx_queue_skb = mt792x_dma_tx_queue_skb;
> > +	mt792x_queue_ops.tx_cleanup = mt792x_dma_tx_cleanup;
> > +
> > +	dev->queue_ops = &mt792x_queue_ops;
> > +}
> > +EXPORT_SYMBOL_GPL(mt792x_dma_attach);
> > +
> >  int mt792x_dma_disable(struct mt792x_dev *dev, bool force)
> >  {
> >  	/* disable WFDMA0 */
> > @@ -326,6 +646,8 @@ void mt792x_dma_cleanup(struct mt792x_dev *dev)
> >  		 MT_WFDMA0_RST_LOGIC_RST);
> >  
> >  	mt76_dma_cleanup(&dev->mt76);
> > +
> > +	mt792x_dma_tx_page_pool_cleanup(dev);
> >  }
> >  EXPORT_SYMBOL_GPL(mt792x_dma_cleanup);
> >  
> > -- 
> > 2.45.2
> > 


^ permalink raw reply

* Re: [PATCH 1/2] wifi: ath12k: skip PCIe global reset on initial power-up
From: Baochen Qiang @ 2026-07-13  3:03 UTC (permalink / raw)
  To: Nazar Mokrynskyi, ath12k; +Cc: linux-wireless, jeff.johnson
In-Reply-To: <20260505172415.566328-2-nazar@mokrynskyi.com>



On 5/6/2026 1:24 AM, Nazar Mokrynskyi wrote:
> ath12k_pci_sw_reset() unconditionally calls ath12k_pci_soc_global_reset()
> regardless of whether the device is being powered up for the first time or
> recovering from a previous run. The global reset drops the PCIe link and
> relies on the host root complex to perform physical link retraining before
> the MHI BHI register can be accessed.
> 
> When the device is passed through to a VM via VFIO, no physical link
> retraining occurs after the reset since QEMU's virtual PCIe bridge does
> not implement hardware LTSSM negotiation. As a result, all subsequent
> MMIO reads return 0xffffffff and MHI initialization fails with -EREMOTEIO.
> 
> On initial power-up, vfio-pci has already performed a Function Level
> Reset before handing the device to the guest driver, placing it in a
> known clean state equivalent to what the global reset achieves. The global

AFAIK this is not the fact. Some internal registers are not cleanly reset without a global
reset.

> reset is therefore redundant on power-up and only necessary on the
> shutdown/recovery path where it tears down an already-running firmware.

is ath12k recovery working in Qemu in your setup? I doubt it since recovery would also hit
the link retraining issue ? Also how about the rmmod / insmod sequence in Qemu, since
rmmod also triggers global reset ?

To me this is more like a Qemu/vfio issue than a driver issue. The QEMU's behavior that
virtual PCIe bridge does not implement hardware LTSSM negotiation basically breaks all
hardware requiring runtime PCIe link retraining. Not sure why it is designed like this. If
it can not be fixed/changed in Qemu, can we do it in the host vfio?

> 
> Skip ath12k_pci_soc_global_reset() when power_on is true to allow MHI
> initialization to succeed under VFIO passthrough without affecting bare
> metal behavior.
> 
> Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.6-01243-QCAHKSWPL_SILICONZ-1
> 
> Signed-off-by: Nazar Mokrynskyi <nazar@mokrynskyi.com>
> ---
>  drivers/net/wireless/ath/ath12k/pci.c | 3 ++-
>  1 file changed, 2 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/net/wireless/ath/ath12k/pci.c b/drivers/net/wireless/ath/ath12k/pci.c
> index 375277ca2..a3d7aeb72 100644
> --- a/drivers/net/wireless/ath/ath12k/pci.c
> +++ b/drivers/net/wireless/ath/ath12k/pci.c
> @@ -303,7 +303,8 @@ static void ath12k_pci_sw_reset(struct ath12k_base *ab, bool power_on)
>  
>  	ath12k_mhi_clear_vector(ab);
>  	ath12k_pci_clear_dbg_registers(ab);
> -	ath12k_pci_soc_global_reset(ab);
> +	if (!power_on)
> +		ath12k_pci_soc_global_reset(ab);
>  	ath12k_mhi_set_mhictrl_reset(ab);
>  }
>  


^ permalink raw reply

* Re: [PATCH ath-next] wifi: ath12k: Fix ath12k_wifi7_mac_op_tx() style issues
From: Baochen Qiang @ 2026-07-13  2:10 UTC (permalink / raw)
  To: Jeff Johnson, Jeff Johnson; +Cc: linux-wireless, ath12k, linux-kernel
In-Reply-To: <20260711-ath12k_wifi7_mac_op_tx-line-length-v1-1-10e4899b98ef@oss.qualcomm.com>



On 7/11/2026 11:31 PM, Jeff Johnson wrote:
> Commit e47d6c9bb416 ("wifi: ath12k: Advertise multicast Ethernet
> encapsulation offload support") introduced a few style issues.
> 
> ath12k-check reports:
> drivers/net/wireless/ath/ath12k/wifi7/hw.c:1042: line length of 92 exceeds 90 columns
> 
> And automated review did not like one if/else that did not use braces
> for a single statement that also included a block comment.
> 
> Fix these issues.
> 
> Signed-off-by: Jeff Johnson <jeff.johnson@oss.qualcomm.com>

Reviewed-by: Baochen Qiang <baochen.qiang@oss.qualcomm.com>

^ permalink raw reply

* Re: [PATCH ath-current v2] wifi: ath6kl: avoid buffer overreads in WMI event handlers
From: Baochen Qiang @ 2026-07-13  2:06 UTC (permalink / raw)
  To: Jeff Johnson, linux-wireless; +Cc: linux-kernel
In-Reply-To: <20260711-ath6kl_wmi_scan_complete_rx-v2-1-22dc0f7f45e7@oss.qualcomm.com>



On 7/12/2026 2:04 AM, Jeff Johnson wrote:
> The following WMI event handlers currently read from the event buffer
> without first verifying that the message was large enough to hold the
> expected event:
> ath6kl_wmi_scan_complete_rx()
> ath6kl_wmi_addba_req_event_rx()
> ath6kl_wmi_delba_req_event_rx()
> 
> Add length checks to prevent overread.
> 
> Fixes: bdcd81707973 ("Add ath6kl cleaned up driver")
> Assisted-by: Claude:claude-sonnet-4-6
> Signed-off-by: Jeff Johnson <jeff.johnson@oss.qualcomm.com>
> ---
> Changes in v2:
> - Added fixes for two more functions: ath6kl_wmi_addba_req_event_rx and ath6kl_wmi_delba_req_event_rx
> - v1 subject: [PATCH ath-current] wifi: ath6kl: avoid buffer overread in ath6kl_wmi_scan_complete_rx()
> - Link to v1: https://patch.msgid.link/20260711-ath6kl_wmi_scan_complete_rx-v1-1-7b11e5f8b96c@oss.qualcomm.com
> ---
>  drivers/net/wireless/ath/ath6kl/wmi.c | 17 +++++++++++++++--
>  1 file changed, 15 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/net/wireless/ath/ath6kl/wmi.c b/drivers/net/wireless/ath/ath6kl/wmi.c
> index 72611a2ceb9d..08030d88c7d3 100644
> --- a/drivers/net/wireless/ath/ath6kl/wmi.c
> +++ b/drivers/net/wireless/ath/ath6kl/wmi.c
> @@ -1276,6 +1276,9 @@ static int ath6kl_wmi_scan_complete_rx(struct wmi *wmi, u8 *datap, int len,
>  {
>  	struct wmi_scan_complete_event *ev;
>  
> +	if (len < sizeof(*ev))
> +		return -EINVAL;
> +
>  	ev = (struct wmi_scan_complete_event *) datap;
>  
>  	ath6kl_scan_complete_evt(vif, a_sle32_to_cpu(ev->status));
> @@ -3352,7 +3355,12 @@ static int ath6kl_wmi_get_pmkid_list_event_rx(struct wmi *wmi, u8 *datap,
>  static int ath6kl_wmi_addba_req_event_rx(struct wmi *wmi, u8 *datap, int len,
>  					 struct ath6kl_vif *vif)
>  {
> -	struct wmi_addba_req_event *cmd = (struct wmi_addba_req_event *) datap;
> +	struct wmi_addba_req_event *cmd;
> +
> +	if (len < sizeof(*cmd))
> +		return -EINVAL;
> +
> +	cmd = (struct wmi_addba_req_event *) datap;

Nit: No space is necessary after a cast. This is a preexisting issue, since you are
touching, better to fix it together.

>  
>  	aggr_recv_addba_req_evt(vif, cmd->tid,
>  				le16_to_cpu(cmd->st_seq_no), cmd->win_sz);
> @@ -3363,7 +3371,12 @@ static int ath6kl_wmi_addba_req_event_rx(struct wmi *wmi, u8 *datap, int len,
>  static int ath6kl_wmi_delba_req_event_rx(struct wmi *wmi, u8 *datap, int len,
>  					 struct ath6kl_vif *vif)
>  {
> -	struct wmi_delba_event *cmd = (struct wmi_delba_event *) datap;
> +	struct wmi_delba_event *cmd;
> +
> +	if (len < sizeof(*cmd))
> +		return -EINVAL;
> +
> +	cmd = (struct wmi_delba_event *) datap;

same here

>  
>  	aggr_recv_delba_req_evt(vif, cmd->tid);
>  
> 
> ---
> base-commit: fa1b1469f1c5f0f54ed9dab80106a117e7736bfd
> change-id: 20260711-ath6kl_wmi_scan_complete_rx-a97c9cb39da7

Reviewed-by: Baochen Qiang <baochen.qiang@oss.qualcomm.com>


^ permalink raw reply

* [PATCH ath-next] wifi: ath11k: add purwa-iot-evk and qcs6490-rb3gen2 to usecase firmware table
From: Miaoqing Pan @ 2026-07-13  2:03 UTC (permalink / raw)
  To: jjohnson; +Cc: ath11k, linux-wireless, linux-kernel, Miaoqing Pan

Add purwa-iot-evk and qcs6490-rb3gen2 platform support to the
usecase firmware lookup table for WCN6855 hw2.1.

These platforms use the nfa765 firmware path for usecase-based
firmware selection.

Also reorder the table entries by compatible string.

Tested-on: WCN6855 hw2.1 PCI WLAN.HSP.1.1-04685-QCAHSPSWPL_V1_V2_SILICONZ_IOE-1

Signed-off-by: Miaoqing Pan <miaoqing.pan@oss.qualcomm.com>
---
 drivers/net/wireless/ath/ath11k/core.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/net/wireless/ath/ath11k/core.c b/drivers/net/wireless/ath/ath11k/core.c
index 8dacc878c006..8039124e7832 100644
--- a/drivers/net/wireless/ath/ath11k/core.c
+++ b/drivers/net/wireless/ath/ath11k/core.c
@@ -1049,9 +1049,11 @@ static const struct __ath11k_core_usecase_firmware_table {
 	const char *compatible;
 	const char *firmware_name;
 } ath11k_core_usecase_firmware_table[] = {
+	{ ATH11K_HW_WCN6855_HW21, "qcom,hamoa-iot-evk", "nfa765"},
 	{ ATH11K_HW_WCN6855_HW21, "qcom,lemans-evk", "nfa765"},
 	{ ATH11K_HW_WCN6855_HW21, "qcom,monaco-evk", "nfa765"},
-	{ ATH11K_HW_WCN6855_HW21, "qcom,hamoa-iot-evk", "nfa765"},
+	{ ATH11K_HW_WCN6855_HW21, "qcom,purwa-iot-evk", "nfa765"},
+	{ ATH11K_HW_WCN6855_HW21, "qcom,qcs6490-rb3gen2", "nfa765"},
 	{ /* Sentinel */ }
 };
 

base-commit: 951dc0a744e4dc8490935316d3b76e23990bde3c
-- 
2.34.1


^ permalink raw reply related

* [PATCH] mac80211: don't encrypt pre-auth (ETH_P_PREAUTH) frames
From: Deepanshu Kartikey @ 2026-07-13  1:59 UTC (permalink / raw)
  To: johannes
  Cc: linux-wireless, linux-kernel, Deepanshu Kartikey,
	syzbot+b6ce23950fd636e6efb6

Pre-authentication frames (ETH_P_PREAUTH, 0x88C7) are sent before
the authentication handshake completes with the target AP, so no
encryption key exists for them yet. Unlike normal EAPOL frames
(ETH_P_8021X, 0x888E) which are registered as the control port
protocol, pre-auth frames are not recognized as control port frames,
causing the kernel to incorrectly assign the current AP's key and
attempt encryption, resulting in a WARN_ON in ieee80211_encrypt_tx_skb
when the cipher is not handled.

Fix this by setting IEEE80211_TX_INTFL_DONT_ENCRYPT for pre-auth
frames in ieee80211_tx_h_check_control_port_protocol(), so that
key selection skips them and they are sent unencrypted as intended.

Reported-by: syzbot+b6ce23950fd636e6efb6@syzkaller.appspotmail.com
Closes: https://syzkaller.appspot.com/bug?extid=b6ce23950fd636e6efb6
Signed-off-by: Deepanshu Kartikey <kartikey406@gmail.com>
---
 net/mac80211/tx.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c
index c13b209fad47..b3acfd69380f 100644
--- a/net/mac80211/tx.c
+++ b/net/mac80211/tx.c
@@ -557,6 +557,9 @@ ieee80211_tx_h_check_control_port_protocol(struct ieee80211_tx_data *tx)
 		info->flags |= IEEE80211_TX_CTL_USE_MINRATE;
 	}
 
+	if (tx->skb->protocol == htons(ETH_P_PREAUTH))
+		info->flags |= IEEE80211_TX_INTFL_DONT_ENCRYPT;
+
 	return TX_CONTINUE;
 }
 
-- 
2.43.0


^ permalink raw reply related

* Re: [PATCH 1/3] wifi: mt76: Separate skb and page_pool_buf pointers in mt76_txwi_cache
From: Eason Lai (賴易聖) @ 2026-07-13  1:57 UTC (permalink / raw)
  To: lorenzo@kernel.org
  Cc: Yf Luo (羅元富), nbd@nbd.name,
	Kun Wu (吳謹至), Quan Zhou (周全),
	Deren Wu (武德仁), Ryder Lee,
	linux-wireless@vger.kernel.org, Sean Wang,
	Leon Yen (顏良儒),
	linux-mediatek@lists.infradead.org,
	Litien Chang (張立典),
	JB Tsai (蔡志彬)
In-Reply-To: <ak9Zjm-czxVIjrhX@lore-desk>

On Thu, 2026-07-09 at 10:19 +0200, Lorenzo Bianconi wrote:
> > From: Eason Lai <Eason.Lai@mediatek.com>
> > 
> > Refactor mt76_txwi_cache structure to use separate skb and
> > page_pool_buf
> > fields instead of a union with ptr. This improves type safety and
> > makes
> > the code more explicit about which pointer type is being used in
> > different contexts.
> > 
> > Also add skip_unmap flag to tx_info.buf to handle cases where DMA
> > unmapping should be skipped.
> > 
> > Signed-off-by: Eason Lai <Eason.Lai@mediatek.com>
> > ---
> >  drivers/net/wireless/mediatek/mt76/dma.c      | 29 ++++++++++++---
> > ----
> >  drivers/net/wireless/mediatek/mt76/mt76.h     |  4 +--
> >  .../net/wireless/mediatek/mt76/mt7996/mac.c   | 10 +++----
> >  drivers/net/wireless/mediatek/mt76/tx.c       |  2 +-
> >  drivers/net/wireless/mediatek/mt76/wed.c      |  6 ++--
> >  5 files changed, 28 insertions(+), 23 deletions(-)
> > 
> > diff --git a/drivers/net/wireless/mediatek/mt76/dma.c
> > b/drivers/net/wireless/mediatek/mt76/dma.c
> > index f8c2fe5f2f58..2716278788bd 100644
> > --- a/drivers/net/wireless/mediatek/mt76/dma.c
> > +++ b/drivers/net/wireless/mediatek/mt76/dma.c
> > @@ -43,7 +43,8 @@ mt76_alloc_rxwi(struct mt76_dev *dev)
> >  	if (!t)
> >  		return NULL;
> >  
> > -	t->ptr = NULL;
> > +	t->skb = NULL;
> > +	t->page_pool_buf = NULL;
> >  	return t;
> >  }
> >  
> > @@ -84,8 +85,11 @@ mt76_get_txwi(struct mt76_dev *dev)
> >  {
> >  	struct mt76_txwi_cache *t = __mt76_get_txwi(dev);
> >  
> > -	if (t)
> > +	if (t) {
> > +		t->skb = NULL;
> > +		t->page_pool_buf = NULL;
> >  		return t;
> > +	}
> >  
> >  	return mt76_alloc_txwi(dev);
> >  }
> > @@ -147,8 +151,8 @@ mt76_free_pending_rxwi(struct mt76_dev *dev)
> >  
> >  	local_bh_disable();
> >  	while ((t = __mt76_get_rxwi(dev)) != NULL) {
> > -		if (t->ptr)
> > -			mt76_put_page_pool_buf(t->ptr, false);
> > +		if (t->page_pool_buf)
> > +			mt76_put_page_pool_buf(t->page_pool_buf,
> > false);
> >  		kfree(t);
> >  	}
> >  	local_bh_enable();
> > @@ -475,14 +479,14 @@ mt76_dma_get_rxdmad_c_buf(struct mt76_dev
> > *dev, struct mt76_queue *q,
> >  	if (more)
> >  		*more = !FIELD_GET(RRO_RXDMAD_DATA1_LS_MASK,
> > data1);
> >  
> > -	buf = t->ptr;
> > +	buf = t->page_pool_buf;
> >  	ind_reason = FIELD_GET(RRO_RXDMAD_DATA2_IND_REASON_MASK,
> > data2);
> >  	if (ind_reason == MT_DMA_WED_IND_REASON_REPEAT ||
> >  	    ind_reason == MT_DMA_WED_IND_REASON_OLDPKT) {
> >  		mt76_put_page_pool_buf(buf, false);
> >  		buf = ERR_PTR(-EAGAIN);
> >  	}
> > -	t->ptr = NULL;
> > +	t->page_pool_buf = NULL;
> >  	t->dma_addr = 0;
> >  
> >  	mt76_put_rxwi(dev, t);
> > @@ -529,9 +533,9 @@ mt76_dma_get_buf(struct mt76_dev *dev, struct
> > mt76_queue *q, int idx,
> >  				SKB_WITH_OVERHEAD(q->buf_size),
> >  				page_pool_get_dma_dir(q-
> > >page_pool));
> >  
> > -		buf = t->ptr;
> > +		buf = t->page_pool_buf;
> >  		t->dma_addr = 0;
> > -		t->ptr = NULL;
> > +		t->page_pool_buf = NULL;
> >  
> >  		mt76_put_rxwi(dev, t);
> >  		if (drop)
> > @@ -694,6 +698,7 @@ mt76_dma_tx_queue_skb(struct mt76_phy *phy,
> > struct mt76_queue *q,
> >  			goto unmap;
> >  
> >  		tx_info.buf[n].addr = addr;
> > +		tx_info.buf[n].skip_unmap = false;
> >  		tx_info.buf[n++].len = iter->len;
> >  	}
> >  	tx_info.nbuf = n;
> > @@ -718,9 +723,11 @@ mt76_dma_tx_queue_skb(struct mt76_phy *phy,
> > struct mt76_queue *q,
> >  				tx_info.info, tx_info.skb, t);
> >  
> >  unmap:
> > -	for (n--; n > 0; n--)
> > -		dma_unmap_single(dev->dma_dev,
> > tx_info.buf[n].addr,
> > -				 tx_info.buf[n].len,
> > DMA_TO_DEVICE);
> > +	for (n--; n > 0; n--) {
> > +		if (!tx_info.buf[n].skip_unmap)
> > +			dma_unmap_single(dev->dma_dev,
> > tx_info.buf[n].addr,
> > +					 tx_info.buf[n].len,
> > DMA_TO_DEVICE);
> > +	}
> >  
> >  free:
> >  #ifdef CONFIG_NL80211_TESTMODE
> > diff --git a/drivers/net/wireless/mediatek/mt76/mt76.h
> > b/drivers/net/wireless/mediatek/mt76/mt76.h
> > index 527bef97e122..927c21536f4e 100644
> > --- a/drivers/net/wireless/mediatek/mt76/mt76.h
> > +++ b/drivers/net/wireless/mediatek/mt76/mt76.h
> > @@ -445,10 +445,8 @@ struct mt76_txwi_cache {
> >  	struct list_head list;
> >  	dma_addr_t dma_addr;
> >  
> > -	union {
> >  		struct sk_buff *skb;
> > -		void *ptr;
> > -	};
> > +	void *page_pool_buf;
> 
> if you do not rename the pointer here, the patch would be much less
> intrusive.
> 
> Regards,
> Lorenzo
> 

OK, I will revert the original naming in V2.

> >  
> >  	u8 qid;
> >  	u8 phy_idx;
> > diff --git a/drivers/net/wireless/mediatek/mt76/mt7996/mac.c
> > b/drivers/net/wireless/mediatek/mt76/mt7996/mac.c
> > index e2a83da3a09c..924b0dc0ff1e 100644
> > --- a/drivers/net/wireless/mediatek/mt76/mt7996/mac.c
> > +++ b/drivers/net/wireless/mediatek/mt76/mt7996/mac.c
> > @@ -1775,12 +1775,12 @@ static void mt7996_rx_token_put(struct
> > mt7996_dev *dev)
> >  		struct mt76_txwi_cache *t;
> >  
> >  		t = mt76_rx_token_release(&dev->mt76, i);
> > -		if (!t || !t->ptr)
> > +		if (!t || !t->page_pool_buf)
> >  			continue;
> >  
> > -		mt76_put_page_pool_buf(t->ptr, false);
> > +		mt76_put_page_pool_buf(t->page_pool_buf, false);
> >  		t->dma_addr = 0;
> > -		t->ptr = NULL;
> > +		t->page_pool_buf = NULL;
> >  
> >  		mt76_put_rxwi(&dev->mt76, t);
> >  	}
> > @@ -1928,14 +1928,14 @@ void mt7996_rro_rx_process(struct mt76_dev
> > *mdev, void *data)
> >  				goto next_page;
> >  
> >  			qid = t->qid;
> > -			buf = t->ptr;
> > +			buf = t->page_pool_buf;
> >  			q = &mdev->q_rx[qid];
> >  			dma_sync_single_for_cpu(mdev->dma_dev, t-
> > >dma_addr,
> >  						SKB_WITH_OVERHEAD(
> > q->buf_size),
> >  						page_pool_get_dma_
> > dir(q->page_pool));
> >  
> >  			t->dma_addr = 0;
> > -			t->ptr = NULL;
> > +			t->page_pool_buf = NULL;
> >  			mt76_put_rxwi(mdev, t);
> >  			if (!buf)
> >  				goto next_page;
> > diff --git a/drivers/net/wireless/mediatek/mt76/tx.c
> > b/drivers/net/wireless/mediatek/mt76/tx.c
> > index 22f9690634c9..665156a7ea65 100644
> > --- a/drivers/net/wireless/mediatek/mt76/tx.c
> > +++ b/drivers/net/wireless/mediatek/mt76/tx.c
> > @@ -899,7 +899,7 @@ int mt76_rx_token_consume(struct mt76_dev *dev,
> > void *ptr,
> >  	token = idr_alloc(&dev->rx_token, t, 0, dev-
> > >rx_token_size,
> >  			  GFP_ATOMIC);
> >  	if (token >= 0) {
> > -		t->ptr = ptr;
> > +		t->page_pool_buf = ptr;
> >  		t->dma_addr = phys;
> >  	}
> >  	spin_unlock_bh(&dev->rx_token_lock);
> > diff --git a/drivers/net/wireless/mediatek/mt76/wed.c
> > b/drivers/net/wireless/mediatek/mt76/wed.c
> > index ed657d952de2..e1cf81d722b8 100644
> > --- a/drivers/net/wireless/mediatek/mt76/wed.c
> > +++ b/drivers/net/wireless/mediatek/mt76/wed.c
> > @@ -15,11 +15,11 @@ void mt76_wed_release_rx_buf(struct
> > mtk_wed_device *wed)
> >  		struct mt76_txwi_cache *t;
> >  
> >  		t = mt76_rx_token_release(dev, i);
> > -		if (!t || !t->ptr)
> > +		if (!t || !t->page_pool_buf)
> >  			continue;
> >  
> > -		mt76_put_page_pool_buf(t->ptr, false);
> > -		t->ptr = NULL;
> > +		mt76_put_page_pool_buf(t->page_pool_buf, false);
> > +		t->page_pool_buf = NULL;
> >  
> >  		mt76_put_rxwi(dev, t);
> >  	}
> > -- 
> > 2.45.2
> > 


^ permalink raw reply

* Re: [PATCH] wifi: ath10k: Drop redundant NULL check on devm_clk_get()
From: Baochen Qiang @ 2026-07-13  1:53 UTC (permalink / raw)
  To: Krzysztof Kozlowski, Jeff Johnson, linux-wireless, ath10k,
	linux-kernel
In-Reply-To: <20260705172405.119084-2-krzysztof.kozlowski@oss.qualcomm.com>



On 7/6/2026 1:24 AM, Krzysztof Kozlowski wrote:
> devm_clk_get() does not return NULL (only valid clock or ERR pointer),
> so simplify the code to drop redundant IS_ERR_OR_NULL().
> 
> Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski@oss.qualcomm.com>

Reviewed-by: Baochen Qiang <baochen.qiang@oss.qualcomm.com>

^ permalink raw reply

* Re: [PATCH] wifi: brcmfmac: guard P2P device vif in action frame search
From: Arend van Spriel @ 2026-07-12 22:35 UTC (permalink / raw)
  To: Guangshuo Li
  Cc: John W. Linville, Arend van Spriel, Bjorn Helgaas,
	Gokul Sivakumar, Hante Meuleman, Johannes Berg,
	Peddolla Harshavardhan Reddy, Pieter-Paul Giesberts, Piotr Haber,
	brcm80211-dev-list.pdl, brcm80211, linux-kernel, linux-wireless
In-Reply-To: <20260708063929.718152-1-lgs201920130244@gmail.com>

On Wed,  8 Jul 2026 14:39:29 +0800, Guangshuo Li wrote:
> brcmf_p2p_send_action_frame() checks the P2P device vif saved probe
> request IE when deciding whether to perform a peer channel search. The
> P2P device vif is not guaranteed to exist, for example in standalone AP
> mode where no P2P device interface has been created.
> ---
>  .../broadcom/brcm80211/brcmfmac/p2p.c | 1 +

This fix is already part of the pending DPP series by Jason Huang / Kurt
Lee (Infineon/Cypress), which I reviewed on 2026-07-06 and asked to be
split out as a separate patch with a Fixes: tag. I expect the DPP authors
will be addressing this in their next revision.

Could you clarify what your relation is to that series and whether you are
working with those authors?

I am not applying this patch.

Regards,
Arend

^ permalink raw reply

* Re: [PATCH v4] wifi: brcmfmac: add DPP support
From: Arend van Spriel @ 2026-07-12 22:33 UTC (permalink / raw)
  To: Jason Huang
  Cc: arend.vanspriel, brcm80211-dev-list.pdl, brcm80211, linux-kernel,
	linux-wireless, Kurt Lee
In-Reply-To: <20260708071230.312836-1-Jason.Huang2@infineon.com>

On Wed, 8 Jul 2026 15:12:30 +0800, Jason Huang wrote:
> 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.

[...]

> +	    p2p->bss_idx[P2PAPI_BSSCFG_DEVICE].vif &&
>  	    p2p->bss_idx[P2PAPI_BSSCFG_DEVICE].vif->saved_ie.probe_req_ie_len) {

[...]

> ---
>  .../broadcom/brcm80211/brcmfmac/cfg80211.c    | 151 ++++++++++--------
>  .../broadcom/brcm80211/brcmfmac/p2p.c         |  59 +++++--
>  .../broadcom/brcm80211/include/brcmu_wifi.h   |   2 +

In the v2 review I asked to split the P2P device vif bug fix into a
separate patch with a Fixes: tag for stable backport. The null guard and
the fallback vif in brcmf_p2p_abort_action_frame() are both pre-existing
P2P bugs that should be split out and submitted as a standalone patch so
they can be backported to stable independently of the DPP feature.

Please also add a changelog below the --- line describing what changed
since v3.

Note that the P2P device vif fixes are pre-existing bugs that need to go
to the wireless tree for stable backport, separate from the DPP feature
which targets wireless-next.

Regards,
Arend

^ permalink raw reply

* Re: [PATCH] wifi: brcmfmac: cyw: clean up PMKID and cookie code
From: Arend van Spriel @ 2026-07-12 22:30 UTC (permalink / raw)
  To: Bogdan Nicolae
  Cc: linux-wireless, brcm80211, brcm80211-dev-list.pdl, linux-kernel,
	Bogdan Nicolae
In-Reply-To: <20260709122315.11400-1-bogdan.nicolae@gmail.com>

On 09/07/2026 14:23, Bogdan Nicolae wrote:
> Avoid setting packet_id to cookie, which is always 0. Instead, use an
> increasing atomic counter. Avoids mismatches of completion events later
> in brcmf_notify_mgmt_tx_status, where packet_id != vif->mgmt_tx_id is
> checked.
> 
> Also, zero out auth_status on initialization. Otherwise, garbage will
> leak from the stack to the firmware (when bssid is less than 32 bytes
> and/or when params->pmkid is set). Then, pass the params->pmkid to the
> firmware (without it, the firmware caches a garbage PMKID on successful
> authentication and denies a subsequent association request that includes
> the PMKID).
> 
> Signed-off-by: Bogdan Nicolae <bogdan.nicolae@acm.org>

I always get a bit confused when people use different email addresses to 
send and sign-off patches.
   > ---
>   .../net/wireless/broadcom/brcm80211/brcmfmac/cyw/core.c   | 8 ++++++--
>   1 file changed, 6 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cyw/core.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cyw/core.c
> index ce09d44fa..cca53ff19 100644
> --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cyw/core.c
> +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cyw/core.c
> @@ -23,6 +23,8 @@
>   #define MGMT_AUTH_FRAME_DWELL_TIME	4000
>   #define MGMT_AUTH_FRAME_WAIT_TIME	(MGMT_AUTH_FRAME_DWELL_TIME + 100)
>   
> +static atomic_t brcmf_cyw_mgmt_tx_id = ATOMIC_INIT(0);
> +
>   static int brcmf_cyw_set_sae_pwd(struct brcmf_if *ifp,
>   				 struct cfg80211_crypto_settings *crypto)
>   {
> @@ -155,7 +157,7 @@ int brcmf_cyw_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev,
>   
>   	memcpy(&mf_params->da[0], &mgmt->da[0], ETH_ALEN);
>   	memcpy(&mf_params->bssid[0], &mgmt->bssid[0], ETH_ALEN);
> -	mf_params->packet_id = cpu_to_le32(*cookie);
> +	mf_params->packet_id = cpu_to_le32(atomic_inc_return(&brcmf_cyw_mgmt_tx_id));

As I understand things the cookie value here is an output parameter. The 
driver should assign it:

+	*cookie = atomic_inc_return(&brcmf_cyw_mgmt_tx_id);
	mf_params->packet_id = cpu_to_le32(*cookie);

>   	memcpy(mf_params->data, &buf[DOT11_MGMT_HDR_LEN],
>   	       le16_to_cpu(mf_params->len));
>
Regards,
Arend

^ permalink raw reply

* [PATCH] wifi: mwifiex: replace one-element arrays with flexible array members
From: Georgi Valkov @ 2026-07-12 22:23 UTC (permalink / raw)
  To: briannorris
  Cc: francesco, johannes.berg, bhelgaas, error27, s.kerkmann, kees,
	linux-wireless, linux-kernel, gvalkov

Replace deprecated one-element arrays with flexible array members.
CONFIG_FORTIFY_SOURCE reports the following warning when
one-element arrays are used as variable-length buffers:

sta_cmd.c:1033 mwifiex_sta_prepare_cmd
memcpy: detected field-spanning write (size 84) of single field
"domain->triplet" at .../marvell/mwifiex/sta_cmd.c:1033 (size 3)

Convert affected structs to use flexible array members.
- Preserve existing wire layouts.
- Replace affected uses of sizeof(member) with sizeof(type).
- Replace unions containing one-element arrays with
  u8 flexible arrays, and document the stored parameter-set type.

Tested-on: WRT3200ACM, OpenWrt
Signed-off-by: Georgi Valkov <gvalkov@gmail.com>
---
 drivers/net/wireless/marvell/mwifiex/fw.h     | 20 +++++++------------
 drivers/net/wireless/marvell/mwifiex/join.c   |  8 ++++----
 .../net/wireless/marvell/mwifiex/sta_cmd.c    |  2 +-
 3 files changed, 12 insertions(+), 18 deletions(-)

diff --git a/drivers/net/wireless/marvell/mwifiex/fw.h b/drivers/net/wireless/marvell/mwifiex/fw.h
index e9e896606912..ec3e3f806134 100644
--- a/drivers/net/wireless/marvell/mwifiex/fw.h
+++ b/drivers/net/wireless/marvell/mwifiex/fw.h
@@ -823,7 +823,7 @@ struct chan_band_param_set {
 
 struct mwifiex_ie_types_chan_band_list_param_set {
 	struct mwifiex_ie_types_header header;
-	struct chan_band_param_set chan_band_param[1];
+	struct chan_band_param_set chan_band_param[];
 } __packed;
 
 struct mwifiex_ie_types_rates_param_set {
@@ -886,7 +886,7 @@ struct mwifiex_ie_types_wildcard_ssid_params {
 #define TSF_DATA_SIZE            8
 struct mwifiex_ie_types_tsf_timestamp {
 	struct mwifiex_ie_types_header header;
-	u8 tsf_data[1];
+	u8 tsf_data[];
 } __packed;
 
 struct mwifiex_cf_param_set {
@@ -902,10 +902,7 @@ struct mwifiex_ibss_param_set {
 
 struct mwifiex_ie_types_ss_param_set {
 	struct mwifiex_ie_types_header header;
-	union {
-		struct mwifiex_cf_param_set cf_param_set[1];
-		struct mwifiex_ibss_param_set ibss_param_set[1];
-	} cf_ibss;
+	u8 cf_ibss[];	/* CF and IBSS param sets are stored here */
 } __packed;
 
 struct mwifiex_fh_param_set {
@@ -921,10 +918,7 @@ struct mwifiex_ds_param_set {
 
 struct mwifiex_ie_types_phy_param_set {
 	struct mwifiex_ie_types_header header;
-	union {
-		struct mwifiex_fh_param_set fh_param_set[1];
-		struct mwifiex_ds_param_set ds_param_set[1];
-	} fh_ds;
+	u8 fh_ds[];	/* FH and DS param sets are stored here */
 } __packed;
 
 struct mwifiex_ie_types_auth_type {
@@ -1383,7 +1377,7 @@ struct host_cmd_ds_802_11_snmp_mib {
 	__le16 query_type;
 	__le16 oid;
 	__le16 buf_size;
-	u8 value[1];
+	u8 value[];
 } __packed;
 
 struct mwifiex_rate_scope {
@@ -1551,7 +1545,7 @@ struct mwifiex_scan_cmd_config {
 	 *  TLV_TYPE_CHANLIST, mwifiex_ie_types_chan_list_param_set
 	 *  WLAN_EID_SSID, mwifiex_ie_types_ssid_param_set
 	 */
-	u8 tlv_buf[1];	/* SSID TLV(s) and ChanList TLVs are stored
+	u8 tlv_buf[];	/* SSID TLV(s) and ChanList TLVs are stored
 				   here */
 } __packed;
 
@@ -1683,7 +1677,7 @@ struct host_cmd_ds_802_11_bg_scan_query_rsp {
 struct mwifiex_ietypes_domain_param_set {
 	struct mwifiex_ie_types_header header;
 	u8 country_code[IEEE80211_COUNTRY_STRING_LEN];
-	struct ieee80211_country_ie_triplet triplet[1];
+	struct ieee80211_country_ie_triplet triplet[];
 } __packed;
 
 struct host_cmd_ds_802_11d_domain_info {
diff --git a/drivers/net/wireless/marvell/mwifiex/join.c b/drivers/net/wireless/marvell/mwifiex/join.c
index 5a1a0287c1d5..a2c427e6af3f 100644
--- a/drivers/net/wireless/marvell/mwifiex/join.c
+++ b/drivers/net/wireless/marvell/mwifiex/join.c
@@ -421,15 +421,15 @@ int mwifiex_cmd_802_11_associate(struct mwifiex_private *priv,
 
 	phy_tlv = (struct mwifiex_ie_types_phy_param_set *) pos;
 	phy_tlv->header.type = cpu_to_le16(WLAN_EID_DS_PARAMS);
-	phy_tlv->header.len = cpu_to_le16(sizeof(phy_tlv->fh_ds.ds_param_set));
-	memcpy(&phy_tlv->fh_ds.ds_param_set,
+	phy_tlv->header.len = cpu_to_le16(sizeof(struct mwifiex_ds_param_set));
+	memcpy(phy_tlv->fh_ds,
 	       &bss_desc->phy_param_set.ds_param_set.current_chan,
-	       sizeof(phy_tlv->fh_ds.ds_param_set));
+	       sizeof(struct mwifiex_ds_param_set));
 	pos += sizeof(phy_tlv->header) + le16_to_cpu(phy_tlv->header.len);
 
 	ss_tlv = (struct mwifiex_ie_types_ss_param_set *) pos;
 	ss_tlv->header.type = cpu_to_le16(WLAN_EID_CF_PARAMS);
-	ss_tlv->header.len = cpu_to_le16(sizeof(ss_tlv->cf_ibss.cf_param_set));
+	ss_tlv->header.len = cpu_to_le16(sizeof(struct mwifiex_cf_param_set));
 	pos += sizeof(ss_tlv->header) + le16_to_cpu(ss_tlv->header.len);
 
 	/* Get the common rates supported between the driver and the BSS Desc */
diff --git a/drivers/net/wireless/marvell/mwifiex/sta_cmd.c b/drivers/net/wireless/marvell/mwifiex/sta_cmd.c
index 623ddde8c8e5..071f7cb305e1 100644
--- a/drivers/net/wireless/marvell/mwifiex/sta_cmd.c
+++ b/drivers/net/wireless/marvell/mwifiex/sta_cmd.c
@@ -108,7 +108,7 @@ static int mwifiex_cmd_802_11_snmp_mib(struct mwifiex_private *priv,
 		    "cmd: SNMP_CMD: cmd_oid = 0x%x\n", cmd_oid);
 	cmd->command = cpu_to_le16(HostCmd_CMD_802_11_SNMP_MIB);
 	cmd->size = cpu_to_le16(sizeof(struct host_cmd_ds_802_11_snmp_mib)
-				- 1 + S_DS_GEN);
+				+ S_DS_GEN);
 
 	snmp_mib->oid = cpu_to_le16((u16)cmd_oid);
 	if (cmd_action == HostCmd_ACT_GEN_GET) {
-- 
2.55.0


^ permalink raw reply related

* [PATCH] wifi: mwifiex: fix freeze for 60 seconds caused by request_firmware
From: Georgi Valkov @ 2026-07-12 22:17 UTC (permalink / raw)
  To: briannorris
  Cc: francesco, s.kerkmann, johannes.berg, kees, linux-wireless,
	linux-kernel, gvalkov

Fix regression in rgpower table loading, caused by using
request_firmware(): when the requested firmware does not exist, e.g.
nxp/rgpower_WW.bin does not exist on OpenWRT builds for WRT3200ACM,
request_firmware() falls back to firmware_fallback_sysfs(), which expects
the firmware to be provided by user space using SYSFS. No such utility is
provided in this configuration, so the entire system locks up for 60
seconds, until the request times out. During this time, no other log
messages are observed, and the device does not respond to commands over
UART.

The request_firmware() call is performed in the following context:
current->comm kworker/1:2  in_task 1  irqs_disabled 0  in_atomic 0

Fixed by using request_firmware_direct(). This prevents fallback to SYSFS,
and avoids delay. The rgpower table is optional. The driver falls back
to the device tree power table if the firmware is not present.

The error code is printed for debugging and returned to the caller,
which only cares for success or failure, so there are no side effects.

Fixes: 7b6f16a25806 ("wifi: mwifiex: add rgpower table loading support")
Signed-off-by: Georgi Valkov <gvalkov@gmail.com>
---
 drivers/net/wireless/marvell/mwifiex/sta_ioctl.c | 14 ++++++++------
 1 file changed, 8 insertions(+), 6 deletions(-)

diff --git a/drivers/net/wireless/marvell/mwifiex/sta_ioctl.c b/drivers/net/wireless/marvell/mwifiex/sta_ioctl.c
index a6550548d3b4..9460d5352b23 100644
--- a/drivers/net/wireless/marvell/mwifiex/sta_ioctl.c
+++ b/drivers/net/wireless/marvell/mwifiex/sta_ioctl.c
@@ -196,6 +196,7 @@ static int mwifiex_request_rgpower_table(struct mwifiex_private *priv)
 	struct mwifiex_adapter *adapter = priv->adapter;
 	char rgpower_table_name[30];
 	char country_code[3];
+	int ret;
 
 	strscpy(country_code, domain_info->country_code, sizeof(country_code));
 
@@ -214,16 +215,17 @@ static int mwifiex_request_rgpower_table(struct mwifiex_private *priv)
 		adapter->rgpower_data = NULL;
 	}
 
-	if ((request_firmware(&adapter->rgpower_data, rgpower_table_name,
-			      adapter->dev))) {
+	ret = request_firmware_direct(&adapter->rgpower_data, rgpower_table_name,
+				      adapter->dev);
+
+	if (ret) {
 		mwifiex_dbg(
 			adapter, INFO,
-			"info: %s: failed to request regulatory power table\n",
-			__func__);
-		return -EIO;
+			"info: %s: failed to request regulatory power table: %d\n",
+			__func__, ret);
 	}
 
-	return 0;
+	return ret;
 }
 
 static int mwifiex_dnld_rgpower_table(struct mwifiex_private *priv)
-- 
2.55.0


^ permalink raw reply related

* Re: [PATCH] wifi: brcmfmac: drain bus_reset work on device removal
From: Arend van Spriel @ 2026-07-12 21:57 UTC (permalink / raw)
  To: Fan Wu
  Cc: David S . Miller, Arend van Spriel, Chi-Hsien Lin,
	Chung-Hsien Hsu, Franky Lin, Hante Meuleman, Jakub Kicinski,
	Kalle Valo, SHA-cyfmac-dev-list, Wright Feng,
	brcm80211-dev-list.pdl, linux-kernel, linux-wireless, netdev,
	stable
In-Reply-To: <20260709101635.103005-1-fanwu01@zju.edu.cn>

On Thu,  9 Jul 2026 10:16:35 +0000, Fan Wu wrote:
> brcmf_fw_crashed() and the debugfs "reset" entry both schedule
> drvr->bus_reset, whose callback recovers drvr through container_of()
> and dereferences it.

[...]

The patch does not apply cleanly on wl-next/main -- a rebase is needed.

I looked more carefully at the cancel_work_sync-under-lock concern that was
raised in the thread. brcmf_core_bus_reset() never acquires bus_reset_lock,
so there is no deadlock. If the work has already started when
brcmf_bus_cancel_reset_work() is called, cancel_work_sync() waits for it to
finish; by then the reset op (brcmf_pcie_reset) has completed its own
teardown and reinitialized the device, so the subsequent remove teardown acts
on a clean device. The design is correct as submitted; only the rebase is
needed.

Regards,
Arend

^ permalink raw reply

* [syzbot] [wireless?] WARNING in ieee80211_encrypt_tx_skb
From: syzbot @ 2026-07-12 21:33 UTC (permalink / raw)
  To: johannes, linux-kernel, linux-wireless, netdev, syzkaller-bugs

Hello,

syzbot found the following issue on:

HEAD commit:    61c03dfde854 Merge tag 'ntfs-for-7.2-rc3' of git://git.ker..
git tree:       upstream
console output: https://syzkaller.appspot.com/x/log.txt?x=116470b9580000
kernel config:  https://syzkaller.appspot.com/x/.config?x=20c9876b0f77b546
dashboard link: https://syzkaller.appspot.com/bug?extid=b6ce23950fd636e6efb6
compiler:       Debian clang version 22.1.8 (++20260613092233+e80beda6e255-1~exp1~20260613092250.77), Debian LLD 22.1.8
syz repro:      https://syzkaller.appspot.com/x/repro.syz?x=16b85432580000
C reproducer:   https://syzkaller.appspot.com/x/repro.c?x=162e20b9580000

Downloadable assets:
disk image (non-bootable): https://storage.googleapis.com/syzbot-assets/d900f083ada3/non_bootable_disk-61c03dfd.raw.xz
vmlinux: https://storage.googleapis.com/syzbot-assets/e06f2aec094f/vmlinux-61c03dfd.xz
kernel image: https://storage.googleapis.com/syzbot-assets/a85168c67732/bzImage-61c03dfd.xz

IMPORTANT: if you fix the issue, please add the following tag to the commit:
Reported-by: syzbot+b6ce23950fd636e6efb6@syzkaller.appspotmail.com

R10: 0000000000000000 R11: 0000000000000246 R12: 0000000000000001
R13: 00007fb87e825fac R14: 00007fb87e825fa0 R15: 00007fb87e825fa0
 </TASK>
------------[ cut here ]------------
res != TX_CONTINUE
WARNING: net/mac80211/tx.c:5460 at ieee80211_encrypt_tx_skb+0x3e4/0x3f0 net/mac80211/tx.c:5460, CPU#0: syz.0.17/5534
Modules linked in:
CPU: 0 UID: 0 PID: 5534 Comm: syz.0.17 Not tainted syzkaller #0 PREEMPT(full) 
Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.16.3-debian-1.16.3-2 04/01/2014
RIP: 0010:ieee80211_encrypt_tx_skb+0x3e4/0x3f0 net/mac80211/tx.c:5460
Code: ff ff ff e8 9e 1a 7a f6 90 0f 0b 90 e9 0b ff ff ff e8 90 1a 7a f6 90 0f 0b 90 bb ea ff ff ff e9 20 ff ff ff e8 7d 1a 7a f6 90 <0f> 0b 90 eb eb e8 d2 bb 84 00 66 90 90 90 90 90 90 90 90 90 90 90
RSP: 0018:ffffc90003526a20 EFLAGS: 00010293
RAX: ffffffff8b4c6813 RBX: 0000000000000000 RCX: ffff88803a6f0000
RDX: 0000000000000000 RSI: 0000000000000001 RDI: 0000000000000000
RBP: ffffc90003526b90 R08: ffff8880129723cf R09: 0000000000000000
R10: ffff8880129723c0 R11: ffffed100252e47a R12: ffffc90003526a68
R13: 1ffff920006a4d48 R14: dffffc0000000000 R15: 0000000000000001
FS:  00005555940ec500(0000) GS:ffff88808c54d000(0000) knlGS:0000000000000000
CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: 0000200000003700 CR3: 0000000012968000 CR4: 0000000000352ef0
Call Trace:
 <TASK>
 mac80211_hwsim_tx+0x1de/0x2500 drivers/net/wireless/virtual/mac80211_hwsim_main.c:2116
 ieee80211_hwsim_wake_tx_queue+0xd4/0x150 drivers/net/wireless/virtual/mac80211_hwsim_main.c:2291
 drv_wake_tx_queue net/mac80211/driver-ops.h:1394 [inline]
 schedule_and_wake_txq net/mac80211/driver-ops.h:1401 [inline]
 ieee80211_queue_skb+0x1923/0x22c0 net/mac80211/tx.c:1674
 __ieee80211_xmit_fast+0x8ea/0x2160 net/mac80211/tx.c:3785
 ieee80211_xmit_fast net/mac80211/tx.c:3853 [inline]
 __ieee80211_subif_start_xmit+0x12af/0x1690 net/mac80211/tx.c:4367
 ieee80211_tx_control_port+0xaba/0xcd0 net/mac80211/tx.c:6592
 rdev_tx_control_port net/wireless/rdev-ops.h:783 [inline]
 nl80211_tx_control_port+0x604/0x990 net/wireless/nl80211.c:18403
 genl_family_rcv_msg_doit+0x233/0x340 net/netlink/genetlink.c:1114
 genl_family_rcv_msg net/netlink/genetlink.c:1194 [inline]
 genl_rcv_msg+0x614/0x7a0 net/netlink/genetlink.c:1209
 netlink_rcv_skb+0x226/0x4a0 net/netlink/af_netlink.c:2556
 genl_rcv+0x28/0x40 net/netlink/genetlink.c:1218
 netlink_unicast_kernel net/netlink/af_netlink.c:1319 [inline]
 netlink_unicast+0x7bb/0x940 net/netlink/af_netlink.c:1345
 netlink_sendmsg+0x813/0xb40 net/netlink/af_netlink.c:1900
 sock_sendmsg_nosec+0x13a/0x180 net/socket.c:775
 __sock_sendmsg net/socket.c:790 [inline]
 ____sys_sendmsg+0x54e/0x850 net/socket.c:2684
 ___sys_sendmsg+0x2a5/0x360 net/socket.c:2738
 __sys_sendmsg net/socket.c:2770 [inline]
 __do_sys_sendmsg net/socket.c:2775 [inline]
 __se_sys_sendmsg net/socket.c:2773 [inline]
 __x64_sys_sendmsg+0x1b1/0x290 net/socket.c:2773
 do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline]
 do_syscall_64+0x174/0x580 arch/x86/entry/syscall_64.c:94
 entry_SYSCALL_64_after_hwframe+0x77/0x7f
RIP: 0033:0x7fb87e59de59
Code: ff c3 66 2e 0f 1f 84 00 00 00 00 00 0f 1f 44 00 00 48 89 f8 48 89 f7 48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 c7 c1 e8 ff ff ff f7 d8 64 89 01 48
RSP: 002b:00007ffca021cc48 EFLAGS: 00000246 ORIG_RAX: 000000000000002e
RAX: ffffffffffffffda RBX: 00007fb87e825fa0 RCX: 00007fb87e59de59
RDX: 0000000000000800 RSI: 0000200000003700 RDI: 0000000000000003
RBP: 00007ffca021ccb0 R08: 0000000000000000 R09: 0000000000000000
R10: 0000000000000000 R11: 0000000000000246 R12: 0000000000000001
R13: 00007fb87e825fac R14: 00007fb87e825fa0 R15: 00007fb87e825fa0
 </TASK>


---
This report is generated by a bot. It may contain errors.
See https://goo.gl/tpsmEJ for more information about syzbot.
syzbot engineers can be reached at syzkaller@googlegroups.com.

syzbot will keep track of this issue. See:
https://goo.gl/tpsmEJ#status for how to communicate with syzbot.

If the report is already addressed, let syzbot know by replying with:
#syz fix: exact-commit-title

If you want syzbot to run the reproducer, reply with:
#syz test: git://repo/address.git branch-or-commit-hash
If you attach or paste a git patch, syzbot will apply it before testing.

If you want to overwrite report's subsystems, reply with:
#syz set subsystems: new-subsystem
(See the list of subsystem names on the web dashboard)

If the report is a duplicate of another one, reply with:
#syz dup: exact-subject-of-another-report

If you want to undo deduplication, reply with:
#syz undup

^ permalink raw reply

* Re: [PATCH v2] wifi: ath12k: fix scan command endianness on big endian
From: Jeff Johnson @ 2026-07-12 21:19 UTC (permalink / raw)
  To: Baochen Qiang, Alexander Wilhelm, Jeff Johnson
  Cc: linux-wireless, ath12k, linux-kernel
In-Reply-To: <afbff608-a005-43c4-af76-968a58bf0cc3@oss.qualcomm.com>

On 7/3/2026 1:18 AM, Baochen Qiang wrote:
> On 7/3/2026 3:35 PM, Alexander Wilhelm wrote:
>> @@ -2795,7 +2799,7 @@ int ath12k_wmi_send_scan_start_cmd(struct ath12k *ar,
>>  		hint_bssid = ptr;
>>  		for (i = 0; i < arg->num_hint_bssid; ++i) {
>>  			hint_bssid->freq_flags =
>> -				arg->hint_bssid[i].freq_flags;
>> +				cpu_to_le32(arg->hint_bssid[i].freq_flags);
>>  			ether_addr_copy(&arg->hint_bssid[i].bssid.addr[0],
>>  					&hint_bssid->bssid.addr[0]);
> 
> the src and dst are wrongly swapped, should be
> 
> ether_addr_copy(&hint_bssid->bssid.addr[0], &arg->hint_bssid[i].bssid.addr[0]);
> 
> However since this is a pre-exising issue and not related to endian handling, not sure if
> we should fix it as well in the same patch.
> 
> Jeff, your thought?
Fixing this should be a separate patch since this is an existing issue that is
unrelated to endian handling.

I already have an AI agent fired up to verify the issue so I'll have it
generate the patch.

/jeff

^ permalink raw reply

* Re: [PATCH 01/13 RFC net-next] net: ipv4: introduce CONFIG_IPV4 to decouple the IPv4 stack
From: Arnd Bergmann @ 2026-07-12 11:01 UTC (permalink / raw)
  To: Fernando Fernandez Mancera, Netdev
  Cc: David S . Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	David Ahern, Simon Horman, Ido Schimmel, Jason Gunthorpe,
	Leon Romanovsky, Andrew Lunn, Anthony L Nguyen, Przemek Kitszel,
	Elad Nachman, Saeed Mahameed, Tariq Toukan, Mark Bloch,
	Petr Machata, Edward Cree, Maxime Coquelin, Alexandre Torgue,
	Arend van Spriel, Miri Korenblit, Keith Busch, Jens Axboe,
	Christoph Hellwig, Sagi Grimberg, Chaitanya Kulkarni,
	Saurav Kashyap, Javed Hasan, GR-QLogic-Storage-Upstream,
	James E . J . Bottomley, Martin K. Petersen, Nilesh Javali,
	Manish Rangankar, Varun Prakash, Alexander Viro,
	Christian Brauner, Jan Kara, David Howells, Marc Dionne,
	Trond Myklebust, Anna Schumaker, Chuck Lever, Jeff Layton,
	NeilBrown, Olga Kornievskaia, Dai Ngo, Tom Talpey, Marek Lindner,
	Simon Wunderlich, Antonio Quartulli, Sven Eckelmann,
	Nikolay Aleksandrov, Pablo Neira Ayuso, Florian Westphal,
	Phil Sutter, Johannes Berg, Matthieu Baerts, Mat Martineau,
	Geliang Tang, Julian Anastasov, Aaron Conole, Eelco Chaudron,
	Ilya Maximets, Allison Henderson, Jamal Hadi Salim, Jiri Pirko,
	Marcelo Ricardo Leitner, Xin Long, D. Wythe, Dust Li,
	Sidraya Jayagond, Wenjia Zhang, Mahanta Jambigi, Tony Lu, Wen Gu,
	Jon Maloy, Steffen Klassert, Herbert Xu, Vikas Gupta,
	Rajashekar Hudumula, Justin Chen, Bhargava Marreddy,
	Nicolai Buchwitz, Florian Fainelli, Heiner Kallweit,
	Krzysztof Kozlowski, Russell King, Yao Zi, Yanteng Si,
	Maxime Chevallier, Julian Braha, Joey Lu, Shangjuan Wei,
	Chen-Yu Tsai, Inochi Amaoto, Lad, Prabhakar, Qingfang Deng,
	Greg Kroah-Hartman, Eric Biggers, Ethan Nelson-Moore,
	Ard Biesheuvel, Dmitry Safonov, Kuniyuki Iwashima, Alyssa Ross,
	linux-rdma, linux-kernel, intel-wired-lan@lists.osuosl.org,
	open list:NETRONOME ETHERNET DRIVERS, linux-net-drivers,
	linux-stm32, linux-arm-kernel, linux-wireless, brcm80211,
	brcm80211-dev-list.pdl, linux-nvme, linux-scsi, target-devel,
	linux-fsdevel, linux-afs, linux-nfs, b.a.t.m.a.n,
	open list:ETHERNET BRIDGE, netfilter-devel, coreteam, mptcp,
	lvs-devel, dev, rds-devel, linux-sctp, linux-s390,
	open list:TIPC NETWORK LAYER
In-Reply-To: <20260712013941.4570-2-fmancera@suse.de>

On Sun, Jul 12, 2026, at 03:38, Fernando Fernandez Mancera wrote:
> Historically, the IPv4 protocol has been linked to the core INET
> subsystem. Because shared infrastructure like the TCP/UDP engine,
> routing or INET hashtables live inside net/ipv4/, it has been impossible
> to compile a kernel with only IPv6 support.
>
> This patch introduces the CONFIG_IPV4 Kconfig symbol, which is set to
> 'def_bool y' for now. This does not allow to completely disable the
> IPv4 stack yet but it lays the necessary build-system work for that
> goal.

I expect this will cause additional (trivial) build regression in the
next step when randconfig builds run into obscure corner cases, either
with INET=y IPV4=n IPV6=y or with INET=y IPV4=n IPV6=n.

I can probably give your patch (with IPV4 visible or disabled) an
early go on the randconfig tree to find these more quickly.
If I run into regressions, should I just add more 'depends on IPV4',
or do you have other plans?

Should we have some logic to ensure that at least one of IPV4 or
IPV6 is enabled? I think this would work

config IPV4
      bool "The IPv4 protocol" if IPV6
      default INET

which only allows turning IPV4 off if IPV6 has enabled.

       Arnd

^ permalink raw reply

* Re: [PATCH net-next v2 3/3] net: ipv4: clear dev->ip_ptr before destroying inetdev
From: Ido Schimmel @ 2026-07-12  7:20 UTC (permalink / raw)
  To: Yuyang Huang
  Cc: David S. Miller, Andrew Lunn, David Ahern, Elad Nachman,
	Eric Dumazet, Jakub Kicinski, Johannes Berg, Paolo Abeni,
	Simon Horman, linux-kernel, linux-wireless, netdev,
	Kuniyuki Iwashima
In-Reply-To: <20260711005405.2861680-4-yuyanghuang@google.com>

On Sat, Jul 11, 2026 at 09:54:04AM +0900, Yuyang Huang wrote:
> To prevent RCU readers from accessing a partially destroyed in_device,
> clear dev->ip_ptr early in inetdev_destroy() before freeing the
> multicast list and individual IP addresses. This aligns the IPv4 teardown
> sequence with the IPv6 implementation.
> 
> Cc: Ido Schimmel <idosch@nvidia.com>
> Cc: Kuniyuki Iwashima <kuniyu@google.com>
> Signed-off-by: Yuyang Huang <yuyanghuang@google.com>

Reviewed-by: Ido Schimmel <idosch@nvidia.com>

^ permalink raw reply

* Re: [PATCH] wifi: rtl8xxxu: fix use-after-free from rx_urb_wq on stop
From: Ping-Ke Shih @ 2026-07-12  4:22 UTC (permalink / raw)
  To: Fan Wu, Jes.Sorensen; +Cc: kvalo, linux-wireless, linux-kernel, stable, Fan Wu
In-Reply-To: <20260630033117.3377-1-fanwu01@zju.edu.cn>

Fan Wu <fanwu01@zju.edu.cn> wrote:

> rtl8xxxu arms rx_urb_wq from the RX completion path:
> rtl8xxxu_rx_complete() hands the URB to rtl8xxxu_queue_rx_urb(), which
> queues it on rx_urb_pending_list and, once the list grows past
> RTL8XXXU_RX_URB_PENDING_WATER, schedules rx_urb_wq.  The worker
> rtl8xxxu_rx_urb_work() drains rx_urb_pending_list, recovers priv through
> container_of, and resubmits each URB through rtl8xxxu_submit_rx_urb(),
> which anchors it on rx_anchor and dereferences priv->udev.
> 
> rtl8xxxu_stop() cancels the sibling work items (c2hcmd_work, ra_watchdog,
> update_beacon_work) but never cancels rx_urb_wq, so a worker armed during
> the last burst of RX traffic can run rtl8xxxu_rx_urb_work() after
> rtl8xxxu_disconnect() has called ieee80211_free_hw(), which frees priv,
> producing a use-after-free.  The window opens under active RX traffic
> (pending count above the watermark) followed by a disconnect.
> 
> There are two teardown races to close:
> 
>   * rtl8xxxu_queue_rx_urb() decided whether to enqueue under rx_urb_lock
>     but called schedule_work() after dropping the lock.  A completion
>     that observed shutdown == false and released the lock could then call
>     schedule_work() after rtl8xxxu_stop() had set shutdown and
>     cancel_work_sync() had already returned, arming the worker to run
>     after the teardown.  Move schedule_work() under the same !shutdown
>     branch so the arming decision is atomic with the shutdown check.
> 
>   * rtl8xxxu_rx_urb_work() anchors every URB it drained back onto
>     rx_anchor through rtl8xxxu_submit_rx_urb().  A worker still running
>     when usb_kill_anchored_urbs(&priv->rx_anchor) returned would submit a
>     URB that escaped the kill.  In rtl8xxxu_stop(), call
>     cancel_work_sync(&priv->rx_urb_wq) before the kill so the worker is
>     drained first.
> 
> After priv->shutdown is set under rx_urb_lock, completions can no longer
> queue rx_urb_wq. cancel_work_sync() then drains the last queued or running
> worker, and the following usb_kill_anchored_urbs() kills the URBs it may
> have submitted.
> 
> rtl8xxxu_disconnect() is covered because ieee80211_unregister_hw()
> guarantees .stop() runs for a live interface before ieee80211_free_hw()
> frees priv.  The probe error path needs no cancel: rx_urb_wq is
> INIT_WORK()'d there but cannot have been scheduled, since no URB is
> submitted before ieee80211_register_hw() succeeds.
> 
> This bug was found by static analysis.
> 
> Fixes: 26f1fad29ad9 ("New driver: rtl8xxxu (mac80211)")
> Cc: stable@vger.kernel.org
> Signed-off-by: Fan Wu <fanwu01@zju.edu.cn>

1 patch(es) applied to rtw-next branch of rtw.git, thanks.

6c080026ecc1 wifi: rtl8xxxu: fix use-after-free from rx_urb_wq on stop

---
https://github.com/pkshih/rtw.git


^ permalink raw reply

* RE: [PATCH] rtlwifi: rtl8192d: remove dead SMPS rate mask code
From: Ping-Ke Shih @ 2026-07-12  3:58 UTC (permalink / raw)
  To: Chelsy Ratnawat
  Cc: linux-wireless@vger.kernel.org, linux-kernel@vger.kernel.org
In-Reply-To: <20260709194315.157030-1-chelsyratnawat2001@gmail.com>

Chelsy Ratnawat <chelsyratnawat2001@gmail.com> wrote:
> mimo_ps is initialized to IEEE80211_SMPS_OFF and never modified in
> rtl92d_update_hal_rate_table(). Therefore, the IEEE80211_SMPS_STATIC
> case is unreachable.
> Remove the unused mimo_ps variable and the dead branch.
> 
> Signed-off-by: Chelsy Ratnawat <chelsyratnawat2001@gmail.com>

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

I'd use "wifi: rtlwifi: ..." as prefix while merging this patch.


^ permalink raw reply


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