* Re: [PATCH rtw-next] wifi: rtw88: Enable receiving control frames in monitor mode
From: Bitterblue Smith @ 2026-06-23 14:18 UTC (permalink / raw)
To: Ping-Ke Shih, linux-wireless@vger.kernel.org; +Cc: Georg Bißeling
In-Reply-To: <7f12ff0969754a9fa4d78b0ae3d2409e@realtek.com>
On 23/06/2026 04:15, Ping-Ke Shih wrote:
> Bitterblue Smith <rtl8821cerfe2@gmail.com> wrote:
>> From: Bitterblue Smith (S.E.A. Datentechnik GmbH) <rtl8821cerfe2@gmail.com>
>>
>> By default RTL8723D, RTL8703B, RTL8812A, RTL8821A, and RTL8814A are
>> configured to filter out all control frames except PS-Poll, even in
>> monitor mode.
>>
>> Handle FIF_CONTROL in rtw_ops_configure_filter(). When it's set,
>> configure REG_RXFLTMAP1 to let all control frames through. When it's
>> unset, restore the original value. Because some drivers configure
>> REG_RXFLTMAP1 differently, keep track of its value in a new member of
>> struct rtw_hal.
>
> All behaviors are unchanged for non-monitor mode, right?
>
I think so.
>>
>> Signed-off-by: Bitterblue Smith (S.E.A. Datentechnik GmbH) <rtl8821cerfe2@gmail.com>
>
> Once you migrate to your company mail, maybe you can add an entry to .mailmap,
> which only affects the output of git-shortlog though.
>
Seeing the company name in parentheses with no explanation makes you
think I'm part of the company, doesn't it? But I'm not, they just
sponsored this patch:
https://lore.kernel.org/all/20250203174626.1131225-1-kuba@kernel.org/
It's confusing, I don't know why they didn't go with a simple
"Sponsored-by" tag.
> Acked-by: Ping-Ke Shih <pkshih@realtek.com>
>
>
^ permalink raw reply
* [PATCH 2/2] wifi: ath12k: Flush the posted write after writing to PCIE_SOC_GLOBAL_RESET
From: Manivannan Sadhasivam @ 2026-06-23 14:16 UTC (permalink / raw)
To: jjohnson
Cc: linux-wireless, ath12k, ath11k, linux-kernel, mani,
Manivannan Sadhasivam, Alex Williamson
In-Reply-To: <20260623141649.41087-1-manivannan.sadhasivam@oss.qualcomm.com>
ath12k_pci_soc_global_reset() tries to reset the device by writing to the
PCIE_SOC_GLOBAL_RESET register. But it doesn't do a read-back to ensure
that the write gets flushed to the device before the delay.
This may lead to the delay on the host to be insufficient, if the posted
write doesn't reach the device before the delay.
So add a read-back after writing to the PCIE_SOC_GLOBAL_RESET register and
before the delay.
Compile tested only.
Fixes: d889913205cf ("wifi: ath12k: driver for Qualcomm Wi-Fi 7 devices")
Reported-by: Alex Williamson <alex@shazbot.org>
Closes: https://lore.kernel.org/linux-pci/20260622160822.09350246@shazbot.org
Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@oss.qualcomm.com>
---
drivers/net/wireless/ath/ath12k/pci.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/drivers/net/wireless/ath/ath12k/pci.c b/drivers/net/wireless/ath/ath12k/pci.c
index d9a22d6afbb0..fee4129ea405 100644
--- a/drivers/net/wireless/ath/ath12k/pci.c
+++ b/drivers/net/wireless/ath/ath12k/pci.c
@@ -188,6 +188,8 @@ static void ath12k_pci_soc_global_reset(struct ath12k_base *ab)
val |= PCIE_SOC_GLOBAL_RESET_V;
ath12k_pci_write32(ab, PCIE_SOC_GLOBAL_RESET, val);
+ /* Flush the posted write to the device */
+ ath12k_pci_read32(ab, PCIE_SOC_GLOBAL_RESET);
/* TODO: exact time to sleep is uncertain */
delay = 10;
@@ -197,6 +199,8 @@ static void ath12k_pci_soc_global_reset(struct ath12k_base *ab)
val &= ~PCIE_SOC_GLOBAL_RESET_V;
ath12k_pci_write32(ab, PCIE_SOC_GLOBAL_RESET, val);
+ /* Flush the posted write to the device */
+ ath12k_pci_read32(ab, PCIE_SOC_GLOBAL_RESET);
mdelay(delay);
--
2.43.0
^ permalink raw reply related
* [PATCH 1/2] wifi: ath11k: Flush the posted write after writing to PCIE_SOC_GLOBAL_RESET
From: Manivannan Sadhasivam @ 2026-06-23 14:16 UTC (permalink / raw)
To: jjohnson
Cc: linux-wireless, ath12k, ath11k, linux-kernel, mani,
Manivannan Sadhasivam, Alex Williamson
ath11k_pci_soc_global_reset() tries to reset the device by writing to the
PCIE_SOC_GLOBAL_RESET register. But it doesn't do a read-back to ensure
that the write gets flushed to the device before the delay.
This may lead to the delay on the host to be insufficient, if the posted
write doesn't reach the device before the delay.
So add a read-back after writing to the PCIE_SOC_GLOBAL_RESET register and
before the delay.
Compile tested only.
Fixes: f3c603d412b3 ("ath11k: reset MHI during power down and power up")
Reported-by: Alex Williamson <alex@shazbot.org>
Closes: https://lore.kernel.org/linux-pci/20260622160822.09350246@shazbot.org
Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@oss.qualcomm.com>
---
drivers/net/wireless/ath/ath11k/pci.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/drivers/net/wireless/ath/ath11k/pci.c b/drivers/net/wireless/ath/ath11k/pci.c
index 35bb9e7a63a2..a163168f3617 100644
--- a/drivers/net/wireless/ath/ath11k/pci.c
+++ b/drivers/net/wireless/ath/ath11k/pci.c
@@ -199,6 +199,8 @@ static void ath11k_pci_soc_global_reset(struct ath11k_base *ab)
val |= PCIE_SOC_GLOBAL_RESET_V;
ath11k_pcic_write32(ab, PCIE_SOC_GLOBAL_RESET, val);
+ /* Flush the posted write to the device */
+ ath11k_pcic_read32(ab, PCIE_SOC_GLOBAL_RESET);
/* TODO: exact time to sleep is uncertain */
delay = 10;
@@ -208,6 +210,8 @@ static void ath11k_pci_soc_global_reset(struct ath11k_base *ab)
val &= ~PCIE_SOC_GLOBAL_RESET_V;
ath11k_pcic_write32(ab, PCIE_SOC_GLOBAL_RESET, val);
+ /* Flush the posted write to the device */
+ ath11k_pcic_read32(ab, PCIE_SOC_GLOBAL_RESET);
mdelay(delay);
--
2.43.0
^ permalink raw reply related
* Re: [PATCH v9] PCI: Add device-specific reset for Qualcomm devices
From: Alex Williamson @ 2026-06-23 14:15 UTC (permalink / raw)
To: Jose Ignacio Tornos Martinez
Cc: mani, ath11k, ath12k, bhelgaas, jjohnson, linux-kernel, linux-pci,
linux-wireless, mhi, alex
In-Reply-To: <20260623125637.1188867-1-jtornosm@redhat.com>
On Tue, 23 Jun 2026 14:56:35 +0200
Jose Ignacio Tornos Martinez <jtornosm@redhat.com> wrote:
> Alex, Mani - would you prefer a dedicated VFIO PCI variant driver (similar
> to mlx5-vfio-pci) to ensure the reset logic only runs in VFIO scenarios, or
> is the quirks.c approach acceptable? I can implement either approach.
It should be a device specific reset in quirks.c. Thanks,
Alex
^ permalink raw reply
* Re: [PATCH v1 1/2] overflow: Allow to sum a few arguments at once
From: Andy Shevchenko @ 2026-06-23 14:09 UTC (permalink / raw)
To: Johannes Berg
Cc: Kees Cook, linux-hardening, linux-kernel, linux-wireless,
Gustavo A. R. Silva
In-Reply-To: <54974e4298efd26a52c9c0e9ada88d57e8695a09.camel@sipsolutions.net>
On Mon, Jun 22, 2026 at 01:16:29PM +0200, Johannes Berg wrote:
> On Sat, 2026-06-20 at 09:56 +0300, Andy Shevchenko wrote:
> > Johannes, are you okay to take a new version (I assume the wish is to have
> > the balanced additions)? If so, I will prepare one.
>
> Sure, I can take the patches, sounds good to me.
Will send soon, for the record the *.i file is 61 character less with the patch.
Was
size = __builtin_choose_expr((sizeof(int) == sizeof(*(8 ? ((void *)((long)(n_channels) * 0l)) : (int *)8))), sizeof(*(request)) + __builtin_choose_expr((sizeof(int) == sizeof(*(8 ? ((void *)((long)(n_channels) * 0l)) : (int *)8))), (n_channels) * sizeof(*(request)->channels) + ((int)sizeof(struct {_Static_assert(!(!(!__builtin_types_compatible_p(typeof(((request)->channels)), typeof(&((request)->channels)[0])))), "must be array");})), size_mul(n_channels, sizeof(*(request)->channels) + ((int)sizeof(struct {_Static_assert(!(!(!__builtin_types_compatible_p(typeof(((request)->channels)), typeof(&((request)->channels)[0])))), "must be array");})))), __size_add(sizeof(*(request)), __builtin_choose_expr((sizeof(int) == sizeof(*(8 ? ((void *)((long)(n_channels) * 0l)) : (int *)8))), (n_channels) * sizeof(*(request)->channels) + ((int)sizeof(struct {_Static_assert(!(!(!__builtin_types_compatible_p(typeof(((request)->channels)), typeof(&((request)->channels)[0])))), "must be array");})), size_mul(n_channels, sizeof(*(request)->channels) + ((int)sizeof(struct {_Static_assert(!(!(!__builtin_types_compatible_p(typeof(((request)->channels)), typeof(&((request)->channels)[0])))), "must be array");}))))));
- size = __size_add(size, size_mul(sizeof(*request->ssids), n_ssids));
- size = __size_add(size, size_mul(sizeof(*request->match_sets), n_match_sets));
- size = __size_add(size, size_mul(sizeof(*request->scan_plans), n_plans));
- size = __size_add(size, ie_len);
Now
size = __size_add(__size_add(__size_add(__builtin_choose_expr((sizeof(int) == sizeof(*(8 ? ((void *)((long)(n_channels) * 0l)) : (int *)8))), sizeof(*(request)) + __builtin_choose_expr((sizeof(int) == sizeof(*(8 ? ((void *)((long)(n_channels) * 0l)) : (int *)8))), (n_channels) * sizeof(*(request)->channels) + ((int)sizeof(struct {_Static_assert(!(!(!__builtin_types_compatible_p(typeof(((request)->channels)), typeof(&((request)->channels)[0])))), "must be array");})), size_mul(n_channels, sizeof(*(request)->channels) + ((int)sizeof(struct {_Static_assert(!(!(!__builtin_types_compatible_p(typeof(((request)->channels)), typeof(&((request)->channels)[0])))), "must be array");})))), __size_add(sizeof(*(request)), __builtin_choose_expr((sizeof(int) == sizeof(*(8 ? ((void *)((long)(n_channels) * 0l)) : (int *)8))), (n_channels) * sizeof(*(request)->channels) + ((int)sizeof(struct {_Static_assert(!(!(!__builtin_types_compatible_p(typeof(((request)->channels)), typeof(&((request)->channels)[0])))), "must be array");})), size_mul(n_channels, sizeof(*(request)->channels) + ((int)sizeof(struct {_Static_assert(!(!(!__builtin_types_compatible_p(typeof(((request)->channels)), typeof(&((request)->channels)[0])))), "must be array");})))))), ie_len), size_mul(sizeof(*request->ssids), n_ssids)), __size_add(size_mul(sizeof(*request->match_sets), n_match_sets), size_mul(sizeof(*request->scan_plans), n_plans)));
--
With Best Regards,
Andy Shevchenko
^ permalink raw reply
* Re: [PATCH v9] PCI: Add device-specific reset for Qualcomm devices
From: Manivannan Sadhasivam @ 2026-06-23 13:50 UTC (permalink / raw)
To: Alex Williamson
Cc: Jose Ignacio Tornos Martinez, ath11k, ath12k, bhelgaas, jjohnson,
linux-kernel, linux-pci, linux-wireless, mhi
In-Reply-To: <20260622160822.09350246@shazbot.org>
On Mon, Jun 22, 2026 at 04:08:22PM -0600, Alex Williamson wrote:
> On Mon, 22 Jun 2026 18:22:39 +0200
> Manivannan Sadhasivam <mani@kernel.org> wrote:
>
> > On Thu, Jun 18, 2026 at 08:33:08AM +0200, Jose Ignacio Tornos Martinez wrote:
> > > Hi Mani,
> > >
> > > Let me clarify the exact scenario and where the reset is necessary:
> > >
> > > * For the commented WiFi devices (WCN6855/WCN7850):
> > >
> > > Standard VFIO passthrough flow (this works fine):
> > > 1. Unbind native driver (ath11k/ath12k/MHI)
> > > 2. Bind vfio-pci driver
> > > 3. Assign device to VM
> > > 4. VM boots, loads its own driver → device works perfectly
> > > 5. VM shuts down cleanly → device can be reassigned → works fine
> > >
> > > The problem occurs with unclean VM termination:
> > > 1. VM crashes or is force-terminated
> > > 2. VFIO tries to reset the device before reassignment
> > > 3. Without a working PCI reset method, reset fails
> > > 4. Device stuck in undefined state → cannot be reassigned to another VM
> > >
> > > Unbinding the driver again doesn't help because the device hardware
> > > itself is in a bad state. From hypervisor:
> > > $ lspci -vvv -s 0000:03:00.0
> > > 03:00.0 Network controller: Qualcomm Technologies, Inc (rev ff) (prog-if ff)
> > > !!! Unknown header type 7f
> > > And a full host power-cycle is necessary to recover.
> > >
> >
> > Can you try the global reset available in the WLAN device BAR space?
> >
> > WCN6855: https://git.kernel.org/pub/scm/linux/kernel/git/pci/pci.git/tree/drivers/net/wireless/ath/ath11k/pci.c#n193
> > WCN7850: https://git.kernel.org/pub/scm/linux/kernel/git/pci/pci.git/tree/drivers/net/wireless/ath/ath12k/pci.c#n182
> >
> > > * For the commented modem devices (SDX62/SDX65):
> > >
> > > Even worse because it fails during the first VM boot without proper reset
> > > capability, standard VFIO passthrough flow:
> > > 1. Unbind native driver (MHI)
> > > 2. Bind vfio-pci driver
> > > 3. Assign device to VM
> > > 4. VM boots, loads its own driver and crashes:
> > > [ 24.024165] mhi mhi0: Device failed to enter MHI Ready
> > > [ 24.024168] mhi mhi0: MHI did not enter READY state
> > >
> > > Unbind/rebind attempts fail:
> > > [ 352.643601] mhi mhi0: Requested to power ON
> > > [ 352.643611] mhi mhi0: Power on setup success
> > > [ 373.442954] mhi mhi0: Device failed to clear MHI Reset
> > > [ 373.442970] mhi mhi0: MHI did not enter READY state
> > > And requires a full host power cycle to recover,
> > > even outside of VFIO scenarios.
> > >
> > > * MHI Host driver's remove callback may handle clean software state
> > > teardown, but it doesn't provide a PCI reset capability that VFIO can
> > > invoke. VFIO needs a reset method registered in the PCI reset hierarchy
> > > (device_specific, pm, flr, bus, etc.). VFIO invokes this reset both during
> > > initial device binding (before the VM starts) and when reassigning the
> > > device between VMs - without a working reset method, the device cannot
> > > reach a clean state for initialization.
> > >
> >
> > Likewise, there is a SoC reset available in the modem BAR space. You can try it:
> > https://git.kernel.org/pub/scm/linux/kernel/git/pci/pci.git/tree/drivers/bus/mhi/host/main.c#n178
> >
> > If these works, then you can hook these in the device_specific reset callback.
>
>
> These look promising as simple flows to implement in a device specific
> reset: save command register, set memory enable, ioremap BAR space,
> match read/write/delay sequences of reset function and caller, iounmap,
> restore command.
>
> Note the delay in this latter reset is in the caller. It's also
> surprising that none of these implement a read to flush the posted
> write that initiates the reset. I wonder if that contributes to the 2s
> delay in the latter example.
>
While I agree that the absence of read-back after the posted write is a problem,
especially with a delay afterwards, the delay itself is required to let the
device reset itself and do a warm boot.
I'll submit fixes to do a read-back after triggering the reset to ensure that
the write gets flushed to the device before the delay.
- Mani
--
மணிவண்ணன் சதாசிவம்
^ permalink raw reply
* Re: [PATCH v9] PCI: Add device-specific reset for Qualcomm devices
From: Manivannan Sadhasivam @ 2026-06-23 13:40 UTC (permalink / raw)
To: Jose Ignacio Tornos Martinez
Cc: alex, ath11k, ath12k, bhelgaas, jjohnson, linux-kernel, linux-pci,
linux-wireless, mhi
In-Reply-To: <20260623125637.1188867-1-jtornosm@redhat.com>
On Tue, Jun 23, 2026 at 02:56:35PM +0200, Jose Ignacio Tornos Martinez wrote:
> Hi Mani and Alex,
>
> Thank you both for the guidance.
>
>
> I think your insight about the BAR-space reset mechanisms is a much better
> approach to have a "real" reset. With that, I've implemented device-specific
> reset functions based on the driver code Mani referenced:
>
> WCN6855/WCN7850 WiFi (reset_qualcomm_wifi):
> - Uses SoC global reset via BAR0 offset 0x3008
> - Follows the sequence from ath11k_pci_soc_global_reset() /
> ath12k_pci_soc_global_reset() / ath11k_pci_sw_reset()
> - Set reset bit → 10ms delay → clear reset bit → 10ms delay → verify link
> recovery (up to 5s)
> - Includes MHI controller reset cleanup (offset 0x38) to clear SYSERR after SoC
> reset
> - Both WCN6855 and WCN7850 share identical register offsets and reset sequence
>
> SDX62/SDX65 modems (reset_qualcomm_modem):
> - Uses MHI SoC reset via BAR0 offset 0xb0
> - Follows the sequence from mhi_soc_reset() / mhi_pci_reset_prepare()
> - Write reset request → 2s delay for reset completion
>
> All implementations follow Alex's pattern: save command register ->
> enable memory decode -> ioremap BAR -> perform reset sequence ->
> iounmap -> restore command.
> Testing results: The implementation shows successful reset behavior for both
> WiFi and modem devices in VFIO passthrough scenarios.
>
Cool!
>
> Regarding the approach (quirks.c vs dedicated VFIO driver):
>
> Mani, I understand your concern about potential conflicts with the native
> drivers. I want to make sure I implement this correctly. Could you clarify
> when you envision the conflict occurring?
> From what I can see, the native drivers call their reset functions directly
> without using pci_try_reset_function(), so the device-specific reset in
> quirks.c could be enough, but I may be missing some error recovery paths or
> other scenarios.
>
MHI driver is calling pci_try_reset_function():
$ git grep -r pci_try_reset_function drivers/bus/mhi
drivers/bus/mhi/host/pci_generic.c: err = pci_try_reset_function(pdev);
So I was worried that it could create conflict. But looking more, I
understood that it won't create any conflict, but just an additional SoC reset:
pci_try_reset_function()
-> pci_dev_save_and_disable()
-> mhi_pci_reset_prepare()
-> mhi_soc_reset() <- First reset
-> __pci_reset_function_locked()
-> pci_dev_specific_reset() <- Second reset
But this additional SoC reset wouldn't cause any issue to the device due to the
2s delay, but the total recovery delay would compound to 4s now.
And that also should be fine as this path gets triggered only when the device
dies during the recovery work (very rare).
So you can implement the reset in quirks.c with device_specific reset.
- Mani
--
மணிவண்ணன் சதாசிவம்
^ permalink raw reply
* Re: [PATCHv2 ath-next] wifi: ath9k: mark static arrays as const
From: Toke Høiland-Jørgensen @ 2026-06-23 12:58 UTC (permalink / raw)
To: Rosen Penev; +Cc: linux-wireless, open list
In-Reply-To: <CAKxU2N-bku8uZJ2nqtXb5nMhaPpxYnHqefNBj=WWe6HeKRaBXA@mail.gmail.com>
Rosen Penev <rosenp@gmail.com> writes:
> On Mon, Jun 22, 2026 at 4:49 AM Toke Høiland-Jørgensen <toke@toke.dk> wrote:
>>
>> Rosen Penev <rosenp@gmail.com> writes:
>>
>> > PN9Data is a read-only lookup table and is never modified. Adding const
>> > lets the compiler place it in .rodata and prevents accidental writes.
>> >
>> > Use the same treatment for bits_per_symbol. It's not modified either.
>> >
>> > Assisted-by: opencode:big-pickle
>> > Signed-off-by: Rosen Penev <rosenp@gmail.com>
>>
>> Again, which actual bug are you fixing here?
> Patches are required to be bugfixes?
Well, or at least have some concrete benefit? You're changing working
code here, we've had to revert patches of this kind before because it
broke things.
For this patch specifically, there's one of two cases:
- The array is never written to, in which case the patch has no
practical effect
or
- The array *is* actually written to somewhere, in which case the kernel
will now crash as soon as someone tries to run the code.
Either way, I don't see how the risk/benefit tradeoff comes off positive
for this patch?
-Toke
^ permalink raw reply
* Re: [PATCH v9] PCI: Add device-specific reset for Qualcomm devices
From: Jose Ignacio Tornos Martinez @ 2026-06-23 12:57 UTC (permalink / raw)
To: baochen.qiang
Cc: alex, ath11k, ath12k, bhelgaas, jjohnson, jtornosm, linux-kernel,
linux-pci, linux-wireless, mani, mhi
In-Reply-To: <5abb5812-cdd8-47d4-b5a0-33f7351589ea@oss.qualcomm.com>
Hello Baochen,
> what is the difference between a clean VM shutdown and an unclean termination?
> specifically, will pci driver's .shutdown callback be triggered during the clean VM
> shutdown, and not be triggered during a unclean termination?
Clean VM shutdown: The guest OS shuts down normally, so the guest kernel
calls the driver's .shutdown/.remove callbacks. The driver can properly
deinitialize the device, leaving it in a clean state.
Unclean VM termination (crash, force-off): The guest kernel never runs, so
driver callbacks are not triggered. The device remains in whatever state it
was in (DMA active, interrupts enabled, etc.). At this point, only VFIO on
the host can interact with the device to reset it before reassigning it to
the next assignment. Without a working reset method, the device stays in this
undefined state and can't be reused.
That's why VFIO calls pci_try_reset_function() - it's the only way to clean
up the device when the guest driver couldn't.
Best regards
José Ignacio
^ permalink raw reply
* Re: [PATCH v9] PCI: Add device-specific reset for Qualcomm devices
From: Jose Ignacio Tornos Martinez @ 2026-06-23 12:56 UTC (permalink / raw)
To: mani
Cc: alex, ath11k, ath12k, bhelgaas, jjohnson, jtornosm, linux-kernel,
linux-pci, linux-wireless, mhi
In-Reply-To: <r4jeqtx247iosfjdps6g4fqwtsdzine5qlgh33sdt4p6ktmaln@o725aolrpj4l>
Hi Mani and Alex,
Thank you both for the guidance.
I think your insight about the BAR-space reset mechanisms is a much better
approach to have a "real" reset. With that, I've implemented device-specific
reset functions based on the driver code Mani referenced:
WCN6855/WCN7850 WiFi (reset_qualcomm_wifi):
- Uses SoC global reset via BAR0 offset 0x3008
- Follows the sequence from ath11k_pci_soc_global_reset() /
ath12k_pci_soc_global_reset() / ath11k_pci_sw_reset()
- Set reset bit → 10ms delay → clear reset bit → 10ms delay → verify link
recovery (up to 5s)
- Includes MHI controller reset cleanup (offset 0x38) to clear SYSERR after SoC
reset
- Both WCN6855 and WCN7850 share identical register offsets and reset sequence
SDX62/SDX65 modems (reset_qualcomm_modem):
- Uses MHI SoC reset via BAR0 offset 0xb0
- Follows the sequence from mhi_soc_reset() / mhi_pci_reset_prepare()
- Write reset request → 2s delay for reset completion
All implementations follow Alex's pattern: save command register ->
enable memory decode -> ioremap BAR -> perform reset sequence ->
iounmap -> restore command.
Testing results: The implementation shows successful reset behavior for both
WiFi and modem devices in VFIO passthrough scenarios.
Regarding the approach (quirks.c vs dedicated VFIO driver):
Mani, I understand your concern about potential conflicts with the native
drivers. I want to make sure I implement this correctly. Could you clarify
when you envision the conflict occurring?
From what I can see, the native drivers call their reset functions directly
without using pci_try_reset_function(), so the device-specific reset in
quirks.c could be enough, but I may be missing some error recovery paths or
other scenarios.
Alex, Mani - would you prefer a dedicated VFIO PCI variant driver (similar
to mlx5-vfio-pci) to ensure the reset logic only runs in VFIO scenarios, or
is the quirks.c approach acceptable? I can implement either approach.
With the decision I will send v10.
Thank you again for all your help
Best regards
José Ignacio
^ permalink raw reply
* [PATCH wireless-next] wifi: cfg80211: Avoid UNPROT_BEACON on AP interfaces
From: Dhanavandhana Kannan @ 2026-06-23 10:34 UTC (permalink / raw)
To: johannes; +Cc: linux-wireless, Dhanavandhana Kannan
Currently, an AP may receive unprotected beacons from neighbouring
BSSes, which cfg80211_rx_unprot_mlme_mgmt() forwards to userspace via
NL80211_CMD_UNPROT_BEACON regardless of interface type.
While the kernel rate-limits these events to once per 10 seconds per
wdev, in multi-BSS scenarios each AP interface maintains its own
rate-limit state, increasing the number of reported events.
In AP mode, hostapd has no handler for NL80211_CMD_UNPROT_BEACON and
logs an unhandled event message for each occurrence, leading to excessive
log noise and making it harder to identify real issues.
Since an AP does not need to act on unprotected beacons from neighbouring
BSSes, skip reporting this event when operating in AP mode.
Signed-off-by: Dhanavandhana Kannan <dhanavandhana.kannan@oss.qualcomm.com>
---
net/wireless/nl80211.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index 53b4b3f76697..5d2feb5002c5 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -20890,6 +20890,9 @@ void cfg80211_rx_unprot_mlme_mgmt(struct net_device *dev, const u8 *buf,
} else if (ieee80211_is_disassoc(mgmt->frame_control)) {
event.cmd = NL80211_CMD_UNPROT_DISASSOCIATE;
} else if (ieee80211_is_beacon(mgmt->frame_control)) {
+ if (wdev->iftype == NL80211_IFTYPE_AP ||
+ wdev->iftype == NL80211_IFTYPE_P2P_GO)
+ return;
if (wdev->unprot_beacon_reported &&
elapsed_jiffies_msecs(wdev->unprot_beacon_reported) < 10000)
return;
base-commit: 972c4dd19cb92e03d75b66c426cfade07582a1ba
--
2.34.1
^ permalink raw reply related
* [PATCH ath-next] wifi: ath12k: Advertise multicast Ethernet encapsulation offload support
From: Tamizh Chelvam Raja @ 2026-06-23 10:05 UTC (permalink / raw)
To: ath12k; +Cc: linux-wireless, Tamizh Chelvam Raja
Advertise IEEE80211_OFFLOAD_ENCAP_MCAST to inform mac80211 that
multicast frame encapsulation is handled in hardware. This allows
mac80211 to pass Ethernet-formatted multicast frames directly to
the driver.
In ath12k_wifi7_mac_op_tx(), refine the logic that selects the MLO
multicast replication path. Add a sta pointer check so that only unicast
Hardware-encap frames use the direct transmit path, while multicast
Hardware-encap frames fall through to the MLO replication loop and are
transmitted on each active link.
In the MLO replication loop, use skb_clone() for Hardware-encap frames.
These frames are already in Ethernet format and do not require
802.11 link address rewriting by ath12k_mlo_mcast_update_tx_link_address().
Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.6-01243-QCAHKSWPL_SILICONZ-1
Signed-off-by: Tamizh Chelvam Raja <tamizh.raja@oss.qualcomm.com>
---
drivers/net/wireless/ath/ath12k/mac.c | 6 ++-
drivers/net/wireless/ath/ath12k/wifi7/hw.c | 61 +++++++++++++++++-----
2 files changed, 53 insertions(+), 14 deletions(-)
diff --git a/drivers/net/wireless/ath/ath12k/mac.c b/drivers/net/wireless/ath/ath12k/mac.c
index af354bef5c0d..26b46a404580 100644
--- a/drivers/net/wireless/ath/ath12k/mac.c
+++ b/drivers/net/wireless/ath/ath12k/mac.c
@@ -10117,7 +10117,8 @@ static void ath12k_mac_update_vif_offload(struct ath12k_link_vif *arvif)
if (vif->type != NL80211_IFTYPE_STATION &&
vif->type != NL80211_IFTYPE_AP)
vif->offload_flags &= ~(IEEE80211_OFFLOAD_ENCAP_ENABLED |
- IEEE80211_OFFLOAD_DECAP_ENABLED);
+ IEEE80211_OFFLOAD_DECAP_ENABLED |
+ IEEE80211_OFFLOAD_ENCAP_MCAST);
if (vif->offload_flags & IEEE80211_OFFLOAD_ENCAP_ENABLED) {
ahvif->dp_vif.tx_encap_type = ATH12K_HW_TXRX_ETHERNET;
@@ -10136,6 +10137,9 @@ static void ath12k_mac_update_vif_offload(struct ath12k_link_vif *arvif)
vif->offload_flags &= ~IEEE80211_OFFLOAD_ENCAP_ENABLED;
}
+ if (vif->offload_flags & IEEE80211_OFFLOAD_ENCAP_ENABLED)
+ vif->offload_flags |= IEEE80211_OFFLOAD_ENCAP_MCAST;
+
param_id = WMI_VDEV_PARAM_RX_DECAP_TYPE;
if (vif->offload_flags & IEEE80211_OFFLOAD_DECAP_ENABLED)
param_value = ATH12K_HW_TXRX_ETHERNET;
diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hw.c b/drivers/net/wireless/ath/ath12k/wifi7/hw.c
index 3d59fa452ec0..e5bf9d218104 100644
--- a/drivers/net/wireless/ath/ath12k/wifi7/hw.c
+++ b/drivers/net/wireless/ath/ath12k/wifi7/hw.c
@@ -903,6 +903,7 @@ static void ath12k_wifi7_mac_op_tx(struct ieee80211_hw *hw,
struct ethhdr *eth;
bool is_prb_rsp;
u16 mcbc_gsn;
+ u8 cb_flags;
u8 link_id;
int ret;
struct ath12k_dp *tmp_dp;
@@ -996,8 +997,13 @@ static void ath12k_wifi7_mac_op_tx(struct ieee80211_hw *hw,
ieee80211_has_protected(hdr->frame_control))
is_dvlan = true;
+ /*
+ * Add a sta pointer check to differentiate multicast encapsulation
+ * offload packets, as the ATH12K_SKB_HW_80211_ENCAP flag is also set
+ * for such packets.
+ */
if (!vif->valid_links || !is_mcast || is_dvlan ||
- (skb_cb->flags & ATH12K_SKB_HW_80211_ENCAP) ||
+ ((skb_cb->flags & ATH12K_SKB_HW_80211_ENCAP) && sta) ||
test_bit(ATH12K_FLAG_RAW_MODE, &ar->ab->dev_flags)) {
ret = ath12k_wifi7_dp_tx(dp_pdev, arvif, arsta, skb, false, 0, is_mcast);
if (unlikely(ret)) {
@@ -1009,6 +1015,7 @@ static void ath12k_wifi7_mac_op_tx(struct ieee80211_hw *hw,
mcbc_gsn = atomic_inc_return(&ahvif->dp_vif.mcbc_gsn) & 0xfff;
links_map = ahvif->links_map;
+ cb_flags = skb_cb->flags;
for_each_set_bit(link_id, &links_map,
IEEE80211_MLD_MAX_NUM_LINKS) {
tmp_arvif = rcu_dereference(ahvif->link[link_id]);
@@ -1016,21 +1023,45 @@ static void ath12k_wifi7_mac_op_tx(struct ieee80211_hw *hw,
continue;
tmp_ar = tmp_arvif->ar;
- tmp_dp_pdev = ath12k_dp_to_pdev_dp(tmp_ar->ab->dp,
+ tmp_dp = ath12k_ab_to_dp(tmp_ar->ab);
+ tmp_dp_pdev = ath12k_dp_to_pdev_dp(tmp_dp,
tmp_ar->pdev_idx);
if (!tmp_dp_pdev)
continue;
- msdu_copied = skb_copy(skb, GFP_ATOMIC);
- if (!msdu_copied) {
- ath12k_err(ar->ab,
- "skb copy failure link_id 0x%X vdevid 0x%X\n",
- link_id, tmp_arvif->vdev_id);
- continue;
- }
- ath12k_mlo_mcast_update_tx_link_address(vif, link_id,
- msdu_copied,
- info_flags);
+ if (cb_flags & ATH12K_SKB_HW_80211_ENCAP) {
+ /*
+ * skb->data may be modified for the iova_mask devices.
+ * It is better to use skb_copy() for such devices
+ * to avoid any potential skb corruption related issues.
+ */
+ if (tmp_dp->hw_params->iova_mask)
+ msdu_copied = skb_copy(skb, GFP_ATOMIC);
+ else
+ /*
+ * ath12k_wifi7_dp_tx() should treat cloned HW-encap
+ * Ethernet multicast frames as read-only.
+ */
+ msdu_copied = skb_clone(skb, GFP_ATOMIC);
+ if (!msdu_copied) {
+ ath12k_err(ar->ab,
+ "skb copy/clone failure link_id 0x%X vdevid 0x%X\n",
+ link_id, tmp_arvif->vdev_id);
+ continue;
+ }
+ } else {
+ msdu_copied = skb_copy(skb, GFP_ATOMIC);
+ if (!msdu_copied) {
+ ath12k_err(ar->ab,
+ "skb copy failure link_id 0x%X vdevid 0x%X\n",
+ link_id, tmp_arvif->vdev_id);
+ continue;
+ }
+
+ ath12k_mlo_mcast_update_tx_link_address(vif, link_id,
+ msdu_copied,
+ info_flags);
+ }
skb_cb = ATH12K_SKB_CB(msdu_copied);
skb_cb->link_id = link_id;
@@ -1046,7 +1077,6 @@ static void ath12k_wifi7_mac_op_tx(struct ieee80211_hw *hw,
if (unlikely(!ahvif->dp_vif.key_cipher))
goto skip_peer_find;
- tmp_dp = ath12k_ab_to_dp(tmp_ar->ab);
spin_lock_bh(&tmp_dp->dp_lock);
peer = ath12k_dp_link_peer_find_by_addr(tmp_dp,
tmp_arvif->bssid);
@@ -1065,11 +1095,16 @@ static void ath12k_wifi7_mac_op_tx(struct ieee80211_hw *hw,
skb_cb->cipher = key->cipher;
skb_cb->flags |= ATH12K_SKB_CIPHER_SET;
+ if (skb_cb->flags & ATH12K_SKB_HW_80211_ENCAP)
+ goto skip_fctl_protected_check;
+
hdr = (struct ieee80211_hdr *)msdu_copied->data;
if (!ieee80211_has_protected(hdr->frame_control))
hdr->frame_control |=
cpu_to_le16(IEEE80211_FCTL_PROTECTED);
}
+
+skip_fctl_protected_check:
spin_unlock_bh(&tmp_dp->dp_lock);
skip_peer_find:
base-commit: 972c4dd19cb92e03d75b66c426cfade07582a1ba
--
2.34.1
^ permalink raw reply related
* Re: [PATCH] wifi: mac80211: only accept IBSS channel switch from our own BSSID
From: Johannes Berg @ 2026-06-23 9:12 UTC (permalink / raw)
To: Yingjie Cao; +Cc: linux-wireless, linux-kernel, stable
In-Reply-To: <c3fd8617849368e579a56c4397b7ee8624ef27ad.camel@sipsolutions.net>
On Tue, 2026-06-23 at 11:10 +0200, Johannes Berg wrote:
> On Tue, 2026-06-23 at 17:04 +0800, Yingjie Cao wrote:
> > ieee80211_rx_bss_info() acts on a channel switch announcement (CSA)
> > carried in a received beacon or probe response before it verifies that
> > the frame's BSSID matches our own IBSS; it only checks that the SSID
> > matches. ieee80211_rx_mgmt_spectrum_mgmt() acts on a spectrum management
> > (channel switch) action frame without checking the BSSID at all.
> >
> > Because of this, any station in radio range that knows the IBSS SSID
> > (which is broadcast in cleartext) can inject a beacon or action frame
> > carrying a CSA element that points at an unsupported channel. The switch
> > then fails in ieee80211_ibss_process_chanswitch(), which queues
> > csa_connection_drop_work and tears the whole IBSS down. The members
> > rejoin and the attacker repeats, resulting in a persistent,
> > unauthenticated denial of service. Encrypted IBSS networks are equally
> > affected because beacons are not protected. Since both of these CSA
> > entry points are IBSS-specific, the impact is confined to IBSS (ad-hoc)
> > mode; managed-mode CSA is handled separately in mlme.c and is unaffected.
>
> Once you rewrite this to be more honest, you'll see that the whole Cc
> stable thing and all is fairly much pointless?
>
> Or have you not realised yet that stations can also trivially fake their
> MAC address?
Also, since you don't have a track record in wifi, I'll point once again
to https://docs.kernel.org/process/coding-assistants.html
johannes
^ permalink raw reply
* Re: [PATCH] wifi: mac80211: only accept IBSS channel switch from our own BSSID
From: Johannes Berg @ 2026-06-23 9:10 UTC (permalink / raw)
To: Yingjie Cao; +Cc: linux-wireless, linux-kernel, stable
In-Reply-To: <20260623090437.13198-1-yingjcao@sigvoid.com>
On Tue, 2026-06-23 at 17:04 +0800, Yingjie Cao wrote:
> ieee80211_rx_bss_info() acts on a channel switch announcement (CSA)
> carried in a received beacon or probe response before it verifies that
> the frame's BSSID matches our own IBSS; it only checks that the SSID
> matches. ieee80211_rx_mgmt_spectrum_mgmt() acts on a spectrum management
> (channel switch) action frame without checking the BSSID at all.
>
> Because of this, any station in radio range that knows the IBSS SSID
> (which is broadcast in cleartext) can inject a beacon or action frame
> carrying a CSA element that points at an unsupported channel. The switch
> then fails in ieee80211_ibss_process_chanswitch(), which queues
> csa_connection_drop_work and tears the whole IBSS down. The members
> rejoin and the attacker repeats, resulting in a persistent,
> unauthenticated denial of service. Encrypted IBSS networks are equally
> affected because beacons are not protected. Since both of these CSA
> entry points are IBSS-specific, the impact is confined to IBSS (ad-hoc)
> mode; managed-mode CSA is handled separately in mlme.c and is unaffected.
Once you rewrite this to be more honest, you'll see that the whole Cc
stable thing and all is fairly much pointless?
Or have you not realised yet that stations can also trivially fake their
MAC address?
johannes
^ permalink raw reply
* Re: [PATCH ath-next] wifi: ath10k: fix skb leak on incomplete msdu during rx pop
From: Baochen Qiang @ 2026-06-23 9:09 UTC (permalink / raw)
To: Manikanta Pubbisetty, ath10k; +Cc: linux-wireless
In-Reply-To: <20260623064355.1876743-1-manikanta.pubbisetty@oss.qualcomm.com>
On 6/23/2026 2:43 PM, Manikanta Pubbisetty wrote:
> When ath10k_htt_rx_pop_paddr32_list() or
> ath10k_htt_rx_pop_paddr64_list() encounters an incomplete frame
> (RX_ATTENTION_FLAGS_MSDU_DONE not set), it returns -EIO without
> purging the skb list built up so far, leaking any skbs already
> queued in the list.
>
> Other early-exit paths within these same functions already call
> __skb_queue_purge() before returning an error. Add it before the
> -EIO return as well to be consistent and prevent the leak.
>
> Tested-on: WCN3990 hw1.0 WLAN.HL.3.2.2.c10-00754-QCAHLSWMTPL-1
>
> Fixes: c545070e404b ("ath10k: implement rx reorder support")
> Fixes: 3b0b55b19d1d ("ath10k: Add support for 64 bit HTT in-order indication msg")
> Signed-off-by: Manikanta Pubbisetty <manikanta.pubbisetty@oss.qualcomm.com>
Reviewed-by: Baochen Qiang <baochen.qiang@oss.qualcomm.com>
^ permalink raw reply
* [PATCH] wifi: mac80211: only accept IBSS channel switch from our own BSSID
From: Yingjie Cao @ 2026-06-23 9:04 UTC (permalink / raw)
To: Johannes Berg; +Cc: linux-wireless, linux-kernel, stable
ieee80211_rx_bss_info() acts on a channel switch announcement (CSA)
carried in a received beacon or probe response before it verifies that
the frame's BSSID matches our own IBSS; it only checks that the SSID
matches. ieee80211_rx_mgmt_spectrum_mgmt() acts on a spectrum management
(channel switch) action frame without checking the BSSID at all.
Because of this, any station in radio range that knows the IBSS SSID
(which is broadcast in cleartext) can inject a beacon or action frame
carrying a CSA element that points at an unsupported channel. The switch
then fails in ieee80211_ibss_process_chanswitch(), which queues
csa_connection_drop_work and tears the whole IBSS down. The members
rejoin and the attacker repeats, resulting in a persistent,
unauthenticated denial of service. Encrypted IBSS networks are equally
affected because beacons are not protected. Since both of these CSA
entry points are IBSS-specific, the impact is confined to IBSS (ad-hoc)
mode; managed-mode CSA is handled separately in mlme.c and is unaffected.
Only honour a channel switch that originates from our own IBSS, i.e.
when the BSSID matches. A CSA carried in a beacon from a foreign BSSID
that merely shares our SSID is now ignored; such a beacon remains a
candidate for the normal IBSS merge path. A channel switch coming from a
station in our own IBSS keeps working exactly as before.
Fixes: cd7760e62c2a ("mac80211: add support for CSA in IBSS mode")
Cc: stable@vger.kernel.org
Signed-off-by: Yingjie Cao <yingjcao@sigvoid.com>
---
net/mac80211/ibss.c | 19 +++++++++++++++----
1 file changed, 15 insertions(+), 4 deletions(-)
diff --git a/net/mac80211/ibss.c b/net/mac80211/ibss.c
index 97292ff51475..6440fd915aa5 100644
--- a/net/mac80211/ibss.c
+++ b/net/mac80211/ibss.c
@@ -895,6 +895,10 @@ ieee80211_rx_mgmt_spectrum_mgmt(struct ieee80211_sub_if_data *sdata,
if (mgmt->u.action.action_code != WLAN_ACTION_SPCT_CHL_SWITCH)
return;
+ /* only act on channel switch frames coming from our own IBSS */
+ if (!ether_addr_equal(mgmt->bssid, sdata->u.ibss.bssid))
+ return;
+
if (!sdata->vif.bss_conf.csa_active)
ieee80211_ibss_process_chanswitch(sdata, elems, false);
}
@@ -1111,14 +1115,21 @@ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata,
sdata->u.ibss.ssid_len))
goto put_bss;
- /* process channel switch */
- if (sdata->vif.bss_conf.csa_active ||
- ieee80211_ibss_process_chanswitch(sdata, elems, true))
+ /* don't process beacons while a channel switch is in progress */
+ if (sdata->vif.bss_conf.csa_active)
goto put_bss;
/* same BSSID */
- if (ether_addr_equal(cbss->bssid, sdata->u.ibss.bssid))
+ if (ether_addr_equal(cbss->bssid, sdata->u.ibss.bssid)) {
+ /*
+ * Only act on a channel switch announcement that comes from
+ * our own IBSS (i.e. matching BSSID). Acting on a CSA from a
+ * foreign BSSID that merely shares our SSID would let any
+ * station force us off-channel or tear the cell down.
+ */
+ ieee80211_ibss_process_chanswitch(sdata, elems, true);
goto put_bss;
+ }
/* we use a fixed BSSID */
if (sdata->u.ibss.fixed_bssid)
--
2.39.5 (Apple Git-154)
^ permalink raw reply related
* Re: [PATCH v9] PCI: Add device-specific reset for Qualcomm devices
From: Baochen Qiang @ 2026-06-23 8:55 UTC (permalink / raw)
To: Jose Ignacio Tornos Martinez, mani
Cc: alex, ath11k, ath12k, bhelgaas, jjohnson, linux-kernel, linux-pci,
linux-wireless, mhi
In-Reply-To: <20260618063309.9536-1-jtornosm@redhat.com>
On 6/18/2026 2:33 PM, Jose Ignacio Tornos Martinez wrote:
> Hi Mani,
>
> Let me clarify the exact scenario and where the reset is necessary:
>
> * For the commented WiFi devices (WCN6855/WCN7850):
>
> Standard VFIO passthrough flow (this works fine):
> 1. Unbind native driver (ath11k/ath12k/MHI)
> 2. Bind vfio-pci driver
> 3. Assign device to VM
> 4. VM boots, loads its own driver → device works perfectly
> 5. VM shuts down cleanly → device can be reassigned → works fine
>
> The problem occurs with unclean VM termination:
> 1. VM crashes or is force-terminated
> 2. VFIO tries to reset the device before reassignment
> 3. Without a working PCI reset method, reset fails
> 4. Device stuck in undefined state → cannot be reassigned to another VM
>
> Unbinding the driver again doesn't help because the device hardware
> itself is in a bad state. From hypervisor:
> $ lspci -vvv -s 0000:03:00.0
> 03:00.0 Network controller: Qualcomm Technologies, Inc (rev ff) (prog-if ff)
> !!! Unknown header type 7f
> And a full host power-cycle is necessary to recover.
>
what is the difference between a clean VM shutdown and an unclean termination?
specifically, will pci driver's .shutdown callback be triggered during the clean VM
shutdown, and not be triggered during a unclean termination?
> * For the commented modem devices (SDX62/SDX65):
>
> Even worse because it fails during the first VM boot without proper reset
> capability, standard VFIO passthrough flow:
> 1. Unbind native driver (MHI)
> 2. Bind vfio-pci driver
> 3. Assign device to VM
> 4. VM boots, loads its own driver and crashes:
> [ 24.024165] mhi mhi0: Device failed to enter MHI Ready
> [ 24.024168] mhi mhi0: MHI did not enter READY state
>
> Unbind/rebind attempts fail:
> [ 352.643601] mhi mhi0: Requested to power ON
> [ 352.643611] mhi mhi0: Power on setup success
> [ 373.442954] mhi mhi0: Device failed to clear MHI Reset
> [ 373.442970] mhi mhi0: MHI did not enter READY state
> And requires a full host power cycle to recover,
> even outside of VFIO scenarios.
>
> * MHI Host driver's remove callback may handle clean software state
> teardown, but it doesn't provide a PCI reset capability that VFIO can
> invoke. VFIO needs a reset method registered in the PCI reset hierarchy
> (device_specific, pm, flr, bus, etc.). VFIO invokes this reset both during
> initial device binding (before the VM starts) and when reassigning the
> device between VMs - without a working reset method, the device cannot
> reach a clean state for initialization.
>
>
>
> I hope this clarifies the scenario better. Please let me know if I can
> provide more information or run any specific tests to help investigate this
> further.
>
> Thanks
>
> Best regards
> José Ignacio
>
>
^ permalink raw reply
* Re: [PATCH v3 2/3] wifi: ath6kl: fix OOB read from firmware IE lengths in connect event
From: Vasanthakumar Thiagarajan @ 2026-06-23 7:45 UTC (permalink / raw)
To: Tristan Madani, Johannes Berg
Cc: linux-wireless, linux-kernel, Tristan Madani
In-Reply-To: <20260421135009.348084-3-tristmd@gmail.com>
On 4/21/2026 7:20 PM, Tristan Madani wrote:
> From: Tristan Madani <tristan@talencesecurity.com>
>
> The firmware-controlled beacon_ie_len, assoc_req_len, and assoc_resp_len
> fields in ath6kl_wmi_connect_event_rx() are not validated against the
> buffer length. Their sum (up to 765) can exceed the actual WMI event
> data, causing out-of-bounds reads during IE parsing and state corruption
> of wmi->is_wmm_enabled.
>
> Add a check that the total IE length fits within the buffer.
>
> Fixes: bdcd81707973 ("Add ath6kl cleaned up driver")
> Signed-off-by: Tristan Madani <tristan@talencesecurity.com>
> ---
> Changes in v3:
> - Regenerated from wireless-next with proper git format-patch to
> produce valid index hashes (v2 had post-processed index lines).
>
> Changes in v2:
> - No code changes from v1.
>
> drivers/net/wireless/ath/ath6kl/wmi.c | 8 ++++++++
> 1 file changed, 8 insertions(+)
>
> diff --git a/drivers/net/wireless/ath/ath6kl/wmi.c b/drivers/net/wireless/ath/ath6kl/wmi.c
> index 72611a2ceb9d8..1cafbac2938fe 100644
> --- a/drivers/net/wireless/ath/ath6kl/wmi.c
> +++ b/drivers/net/wireless/ath/ath6kl/wmi.c
> @@ -862,6 +862,14 @@ static int ath6kl_wmi_connect_event_rx(struct wmi *wmi, u8 *datap, int len,
>
> ev = (struct wmi_connect_event *) datap;
>
> + if (len < sizeof(*ev) + ev->beacon_ie_len +
> + ev->assoc_req_len + ev->assoc_resp_len) {
> + ath6kl_dbg(ATH6KL_DBG_WMI,
> + "connect event: IE lengths %u+%u+%u exceed buffer %d\n",
> + ev->beacon_ie_len, ev->assoc_req_len,
> + ev->assoc_resp_len, len);
> + return -EINVAL;
> + }
> if (vif->nw_type == AP_NETWORK) {
> /* AP mode start/STA connected event */
> struct net_device *dev = vif->ndev;
Reviewed-by: Vasanthakumar Thiagarajan <vasanthakumar.thiagarajan@oss.qualcomm.com>
^ permalink raw reply
* Re: [PATCH v3 1/3] wifi: ath6kl: fix OOB access from firmware ADDBA window size
From: Vasanthakumar Thiagarajan @ 2026-06-23 7:10 UTC (permalink / raw)
To: Tristan Madani, Johannes Berg
Cc: linux-wireless, linux-kernel, Tristan Madani
In-Reply-To: <20260421135009.348084-2-tristmd@gmail.com>
On 4/21/2026 7:20 PM, Tristan Madani wrote:
> From: Tristan Madani <tristan@talencesecurity.com>
>
> aggr_recv_addba_req_evt() logs a debug message when the firmware-supplied
> win_sz is outside [AGGR_WIN_SZ_MIN, AGGR_WIN_SZ_MAX] but does not
> return. The out-of-range win_sz is then used in TID_WINDOW_SZ() to
> compute a kzalloc size and stored in rxtid->hold_q_sz, leading to
> zero-size or overflowed allocations and subsequent OOB access.
>
> Return early when win_sz is out of the valid range.
>
> Fixes: bdcd81707973 ("Add ath6kl cleaned up driver")
> Signed-off-by: Tristan Madani <tristan@talencesecurity.com>
> ---
> Changes in v3:
> - Regenerated from wireless-next with proper git format-patch to
> produce valid index hashes (v2 had post-processed index lines).
>
> Changes in v2:
> - No code changes from v1.
>
> drivers/net/wireless/ath/ath6kl/txrx.c | 4 +++-
> 1 file changed, 3 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/net/wireless/ath/ath6kl/txrx.c b/drivers/net/wireless/ath/ath6kl/txrx.c
> index 97fdac7237e26..5575b535f94cd 100644
> --- a/drivers/net/wireless/ath/ath6kl/txrx.c
> +++ b/drivers/net/wireless/ath/ath6kl/txrx.c
> @@ -1723,9 +1723,11 @@ void aggr_recv_addba_req_evt(struct ath6kl_vif *vif, u8 tid_mux, u16 seq_no,
>
> rxtid = &aggr_conn->rx_tid[tid];
>
> - if (win_sz < AGGR_WIN_SZ_MIN || win_sz > AGGR_WIN_SZ_MAX)
> + if (win_sz < AGGR_WIN_SZ_MIN || win_sz > AGGR_WIN_SZ_MAX) {
> ath6kl_dbg(ATH6KL_DBG_WLAN_RX, "%s: win_sz %d, tid %d\n",
> __func__, win_sz, tid);
> + return;
> + }
I think, before returning, it makes sense to clean up the previously active session also
upon an event with unexpected aggregation window size for the tid.
Vasanth
^ permalink raw reply
* Re: [PATCH ath-next] wifi: ath12k: advertise ieee_link_id in vdev start MLO params
From: Manish Dharanenthiran @ 2026-06-23 6:51 UTC (permalink / raw)
To: Rameshkumar Sundaram, ath12k
Cc: linux-wireless, Hari Naraayana Desikan Kannan, Karthik M
In-Reply-To: <c5feff91-9303-492c-a031-1b2a1e7f3b7c@oss.qualcomm.com>
On 6/19/2026 11:58 PM, Rameshkumar Sundaram wrote:
> On 6/19/2026 11:25 AM, Manish Dharanenthiran wrote:
>> Firmware builds the AP MLD partner profile from the hw_link_id passed in
>> the vdev start parameters. However, hw_link_id is not always the same as
>> the logical per-MLD ieee_link_id, since ieee_link_id is assigned per MLD
>> and not per pdev.
>>
>> This matters in mixed MLO and SLO setups. For example:
>>
>> MLD 1 - 5 GHz + 6 GHz (2-link MLO): ieee_link_id 0 and 1
>> MLD 2 - 6 GHz only (1-link SLO): ieee_link_id 0
>> MLD 3 - 5 GHz only (1-link SLO): ieee_link_id 0
>>
>> The same physical 6 GHz radio can use ieee_link_id 1 for one
>> MLD and ieee_link_id 0 for another. Pass the correct ieee_link_id to
>> firmware so it can build accurate per-STA profile elements.
>>
>> Add ieee_link_id to wmi_vdev_start_mlo_params for the self link and to
>> wmi_partner_link_info for each partner link. Populate these fields in
>> ath12k_mac_mlo_get_vdev_args() from the corresponding vdev link_id
>> before encoding the WMI command.
>>
>> Introduce two new flags in ML params to indicate to firmware when
>> the new fields are valid:
>>
>> ATH12K_WMI_FLAG_MLO_IEEE_LINK_IDX_VALID BIT(18) for the
>> self link
>> ATH12K_WMI_FLAG_MLO_IEEE_LINK_IDX_VALID_PARTNER BIT(19) for partner
>> links
>>
>> Firmware parses ieee_link_id only when the matching flag is set.
>>
>> Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.6-01243-QCAHKSWPL_SILICONZ-1
>>
[snip]
>> - ath12k_dbg(ar->ab, ATH12K_DBG_WMI, "vdev %d start ml flags
>> 0x%x\n",
>> - arg->vdev_id, ml_params->flags);
>> + ml_params->ieee_link_id = cpu_to_le32(arg->ml.ieee_link_id);
>> +
>> + ath12k_dbg(ar->ab, ATH12K_DBG_WMI, "vdev %d start link_id %d
>> ml flags 0x%x\n",
>
> %u for vdev and link_id ?
> Also this part of change is not describe in commit text.
>
Addressed the comments in v2
>> + arg->vdev_id, arg->ml.ieee_link_id,
>> + le32_to_cpu(ml_params->flags));
>> ptr += sizeof(*ml_params);
>> @@ -1244,19 +1248,23 @@ int ath12k_wmi_vdev_start(struct ath12k *ar,
>> struct wmi_vdev_start_req_arg *arg,
>> partner_info = ptr;
>> for (i = 0; i < arg->ml.num_partner_links; i++) {
>> + struct wmi_ml_partner_info *pinfo = &arg-
>> >ml.partner_info[i];
>> +
>> partner_info->tlv_header =
>> ath12k_wmi_tlv_cmd_hdr(WMI_TAG_MLO_PARTNER_LINK_PARAMS,
>> sizeof(*partner_info));
>> - partner_info->vdev_id =
>> - cpu_to_le32(arg->ml.partner_info[i].vdev_id);
>> - partner_info->hw_link_id =
>> - cpu_to_le32(arg->ml.partner_info[i].hw_link_id);
>> + partner_info->vdev_id = cpu_to_le32(pinfo->vdev_id);
>> + partner_info->hw_link_id = cpu_to_le32(pinfo->hw_link_id);
>> ether_addr_copy(partner_info->vdev_addr.addr,
>> - arg->ml.partner_info[i].addr);
>> -
>> - ath12k_dbg(ar->ab, ATH12K_DBG_WMI, "partner vdev %d
>> hw_link_id %d macaddr%pM\n",
>> - partner_info->vdev_id, partner_info->hw_link_id,
>> - partner_info->vdev_addr.addr);
>> + pinfo->addr);
>> + partner_info->flags =
>> +
>> cpu_to_le32(ATH12K_WMI_FLAG_MLO_IEEE_LINK_IDX_VALID_PARTNER);
>> + partner_info->ieee_link_id = cpu_to_le32(pinfo-
>> >ieee_link_id);
>> +
>> + ath12k_dbg(ar->ab, ATH12K_DBG_WMI, "partner vdev %d
>> hw_link_id %d macaddr %pM link_id %d ml flags 0x%x\n",
>
> %u for vdev_id, hw_link_id and ieee_link_id ?
>
Addressed these in v2.
[snip]
>
>
>
> --
> Ramesh
^ permalink raw reply
* [PATCH ath-next] wifi: ath10k: fix skb leak on incomplete msdu during rx pop
From: Manikanta Pubbisetty @ 2026-06-23 6:43 UTC (permalink / raw)
To: ath10k; +Cc: linux-wireless, Manikanta Pubbisetty
When ath10k_htt_rx_pop_paddr32_list() or
ath10k_htt_rx_pop_paddr64_list() encounters an incomplete frame
(RX_ATTENTION_FLAGS_MSDU_DONE not set), it returns -EIO without
purging the skb list built up so far, leaking any skbs already
queued in the list.
Other early-exit paths within these same functions already call
__skb_queue_purge() before returning an error. Add it before the
-EIO return as well to be consistent and prevent the leak.
Tested-on: WCN3990 hw1.0 WLAN.HL.3.2.2.c10-00754-QCAHLSWMTPL-1
Fixes: c545070e404b ("ath10k: implement rx reorder support")
Fixes: 3b0b55b19d1d ("ath10k: Add support for 64 bit HTT in-order indication msg")
Signed-off-by: Manikanta Pubbisetty <manikanta.pubbisetty@oss.qualcomm.com>
---
drivers/net/wireless/ath/ath10k/htt_rx.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/drivers/net/wireless/ath/ath10k/htt_rx.c b/drivers/net/wireless/ath/ath10k/htt_rx.c
index faac359aa9ac..b3f1b7186721 100644
--- a/drivers/net/wireless/ath/ath10k/htt_rx.c
+++ b/drivers/net/wireless/ath/ath10k/htt_rx.c
@@ -706,6 +706,7 @@ static int ath10k_htt_rx_pop_paddr32_list(struct ath10k_htt *htt,
if (!(__le32_to_cpu(rxd_attention->flags) &
RX_ATTENTION_FLAGS_MSDU_DONE)) {
ath10k_warn(htt->ar, "tried to pop an incomplete frame, oops!\n");
+ __skb_queue_purge(list);
return -EIO;
}
}
@@ -770,6 +771,7 @@ static int ath10k_htt_rx_pop_paddr64_list(struct ath10k_htt *htt,
if (!(__le32_to_cpu(rxd_attention->flags) &
RX_ATTENTION_FLAGS_MSDU_DONE)) {
ath10k_warn(htt->ar, "tried to pop an incomplete frame, oops!\n");
+ __skb_queue_purge(list);
return -EIO;
}
}
base-commit: 972c4dd19cb92e03d75b66c426cfade07582a1ba
--
2.34.1
^ permalink raw reply related
* Re: [PATCH] wifi: ath6kl: fix use-after-free in aggr_reset_state()
From: Rameshkumar Sundaram @ 2026-06-23 6:36 UTC (permalink / raw)
To: Daniel Hodges, linux-wireless
Cc: tglx, mingo, joe, vthiagar, rmani, jouni, kvalo, linux-kernel,
stable
In-Reply-To: <20260206185207.30098-1-git@danielhodges.dev>
On 2/7/2026 12:22 AM, Daniel Hodges wrote:
> The aggr_reset_state() function uses timer_delete() (non-synchronous)
> for the aggregation timer before proceeding to delete TID state and
> before the structure is freed by callers like aggr_module_destroy().
>
> If the timer callback (aggr_timeout) is executing when aggr_reset_state()
> is called, the callback will continue to access aggr_conn fields like
> rx_tid[] and stat[] which may be freed immediately after by
> kfree(aggr_info->aggr_conn) in aggr_module_destroy().
>
> Additionally, the timer callback can re-arm itself via mod_timer() while
> aggr_reset_state() is running, creating a more complex race condition.
>
> Use timer_delete_sync() instead to ensure any running timer callback
> has completed before returning.
>
> Fixes: bdcd81707973 ("Add ath6kl cleaned up driver")
> Cc: stable@vger.kernel.org
> Signed-off-by: Daniel Hodges <git@danielhodges.dev>
> ---
> drivers/net/wireless/ath/ath6kl/txrx.c | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/drivers/net/wireless/ath/ath6kl/txrx.c b/drivers/net/wireless/ath/ath6kl/txrx.c
> index c3b06b515c4f..25ff5dec221c 100644
> --- a/drivers/net/wireless/ath/ath6kl/txrx.c
> +++ b/drivers/net/wireless/ath/ath6kl/txrx.c
> @@ -1828,7 +1828,7 @@ void aggr_reset_state(struct aggr_info_conn *aggr_conn)
> return;
>
> if (aggr_conn->timer_scheduled) {
> - timer_delete(&aggr_conn->timer);
> + timer_delete_sync(&aggr_conn->timer);
> aggr_conn->timer_scheduled = false;
> }
>
I am not familiar with ath6kl either, but while looking through the code,
aggr_reset_state() still calls timer_delete_sync() only when
aggr_conn->timer_scheduled is true. However aggr_timeout() clears
timer_scheduled near the beginning of the callback, before it walks
aggr_conn->rx_tid[] and updates aggr_conn->stat[].
So aggr_reset_state() can observe timer_scheduled == false while the
timer callback is still running, skip timer_delete_sync(), and then
delete the TID state / allow aggr_conn to be freed. That still leaves
the UAF window open.
I think timer_delete_sync() should be called unconditionally after the
aggr_conn NULL check, and timer_scheduled can then be cleared afterwards.
--
Ramesh
^ permalink raw reply
* Re: [PATCH] wifi: ath6kl: fix use-after-free in aggr_reset_state()
From: Vasanthakumar Thiagarajan @ 2026-06-23 6:33 UTC (permalink / raw)
To: Daniel Hodges, linux-wireless
Cc: tglx, mingo, joe, vthiagar, rmani, jouni, kvalo, linux-kernel,
stable
In-Reply-To: <20260206185207.30098-1-git@danielhodges.dev>
On 2/7/2026 12:22 AM, Daniel Hodges wrote:
> The aggr_reset_state() function uses timer_delete() (non-synchronous)
> for the aggregation timer before proceeding to delete TID state and
> before the structure is freed by callers like aggr_module_destroy().
>
> If the timer callback (aggr_timeout) is executing when aggr_reset_state()
> is called, the callback will continue to access aggr_conn fields like
> rx_tid[] and stat[] which may be freed immediately after by
> kfree(aggr_info->aggr_conn) in aggr_module_destroy().
>
> Additionally, the timer callback can re-arm itself via mod_timer() while
> aggr_reset_state() is running, creating a more complex race condition.
>
> Use timer_delete_sync() instead to ensure any running timer callback
> has completed before returning.
>
> Fixes: bdcd81707973 ("Add ath6kl cleaned up driver")
> Cc: stable@vger.kernel.org
> Signed-off-by: Daniel Hodges <git@danielhodges.dev>
> ---
> drivers/net/wireless/ath/ath6kl/txrx.c | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/drivers/net/wireless/ath/ath6kl/txrx.c b/drivers/net/wireless/ath/ath6kl/txrx.c
> index c3b06b515c4f..25ff5dec221c 100644
> --- a/drivers/net/wireless/ath/ath6kl/txrx.c
> +++ b/drivers/net/wireless/ath/ath6kl/txrx.c
> @@ -1828,7 +1828,7 @@ void aggr_reset_state(struct aggr_info_conn *aggr_conn)
> return;
>
> if (aggr_conn->timer_scheduled) {
> - timer_delete(&aggr_conn->timer);
> + timer_delete_sync(&aggr_conn->timer);
> aggr_conn->timer_scheduled = false;
> }
>
Reviewed-by: Vasanthakumar Thiagarajan <vasanthakumar.thiagarajan@oss.qualcomm.com>
^ permalink raw reply
* Re: [PATCH] wifi: ath6kl: fix use-after-free in aggr_reset_state()
From: Vasanthakumar Thiagarajan @ 2026-06-23 6:33 UTC (permalink / raw)
To: Jeff Johnson, Daniel Hodges, linux-wireless
Cc: tglx, mingo, joe, vthiagar, rmani, jouni, linux-kernel, stable
In-Reply-To: <e46348dc-a95e-496e-8b49-2838b25bf9f8@oss.qualcomm.com>
On 6/18/2026 7:00 AM, Jeff Johnson wrote:
> On 6/17/2026 6:26 PM, Jeff Johnson wrote:
>> On 2/6/2026 10:52 AM, Daniel Hodges wrote:
>>> The aggr_reset_state() function uses timer_delete() (non-synchronous)
>>> for the aggregation timer before proceeding to delete TID state and
>>> before the structure is freed by callers like aggr_module_destroy().
>>>
>>> If the timer callback (aggr_timeout) is executing when aggr_reset_state()
>>> is called, the callback will continue to access aggr_conn fields like
>>> rx_tid[] and stat[] which may be freed immediately after by
>>> kfree(aggr_info->aggr_conn) in aggr_module_destroy().
>>>
>>> Additionally, the timer callback can re-arm itself via mod_timer() while
>>> aggr_reset_state() is running, creating a more complex race condition.
>>>
>>> Use timer_delete_sync() instead to ensure any running timer callback
>>> has completed before returning.
>>>
>>> Fixes: bdcd81707973 ("Add ath6kl cleaned up driver")
>>> Cc: stable@vger.kernel.org
>>> Signed-off-by: Daniel Hodges <git@danielhodges.dev>
>>> ---
>>> drivers/net/wireless/ath/ath6kl/txrx.c | 2 +-
>>> 1 file changed, 1 insertion(+), 1 deletion(-)
>>>
>>> diff --git a/drivers/net/wireless/ath/ath6kl/txrx.c b/drivers/net/wireless/ath/ath6kl/txrx.c
>>> index c3b06b515c4f..25ff5dec221c 100644
>>> --- a/drivers/net/wireless/ath/ath6kl/txrx.c
>>> +++ b/drivers/net/wireless/ath/ath6kl/txrx.c
>>> @@ -1828,7 +1828,7 @@ void aggr_reset_state(struct aggr_info_conn *aggr_conn)
>>> return;
>>>
>>> if (aggr_conn->timer_scheduled) {
>>> - timer_delete(&aggr_conn->timer);
>>> + timer_delete_sync(&aggr_conn->timer);
>>
>> My review agent claims this still doesn't fix the UAF since aggr_timeout() can
>> call mod_timer() to rearm itself and hence the timer can fire again.
>> Instead it suggests timer_shutdown_sync() should be used since that prevents
>> any rearm from taking effect.
>>
>> But I'm not familiar with this driver so I don't know if there are reasons to
>> not use timer_shutdown_sync(), i.e. if the timer will be reused again then
>> timer_setup() will need to be called again.
>
> Interesting enough, another iteration of the same agent says:
> **The fix is correct.** `timer_delete_sync()` loops until the timer is both
> not-running and not-pending — it handles the re-arm case because after the
> callback calls `mod_timer()`, the sync loop picks that up and cancels it.
Yeah, my understanding is also that timer_delete_sync() will ensure that the
timer will not be pending (including the one armed from the timer callback itself)
or running when it returns with the caller ensuring the timer is not rearmed concurrently.
With that, I think this code change is fine and no need to use timer_shutdown_sync().
Vasanth
^ permalink raw reply
* [PATCH ath-next v2] wifi: ath12k: advertise ieee_link_id in vdev start MLO params
From: Manish Dharanenthiran @ 2026-06-23 5:46 UTC (permalink / raw)
To: ath12k
Cc: linux-wireless, Hari Naraayana Desikan Kannan, Karthik M,
Manish Dharanenthiran
Firmware builds the AP MLD partner profile from the hw_link_id passed in
the vdev start parameters. However, hw_link_id is not always the same as
the logical per-MLD ieee_link_id, since ieee_link_id is assigned per MLD
and not per pdev.
This matters in mixed MLO and SLO setups. For example:
MLD 1 - 5 GHz + 6 GHz (2-link MLO): ieee_link_id 0 and 1
MLD 2 - 6 GHz only (1-link SLO): ieee_link_id 0
MLD 3 - 5 GHz only (1-link SLO): ieee_link_id 0
The same physical 6 GHz radio can use ieee_link_id 1 for one
MLD and ieee_link_id 0 for another. Pass the correct ieee_link_id to
firmware so it can build accurate per-STA profile elements.
Add ieee_link_id to wmi_vdev_start_mlo_params for the self link and to
wmi_partner_link_info for each partner link. Populate these fields in
ath12k_mac_mlo_get_vdev_args() from the corresponding vdev link_id
before encoding the WMI command.
Introduce two new flags in ML params to indicate to firmware when
the new fields are valid:
ATH12K_WMI_FLAG_MLO_IEEE_LINK_IDX_VALID BIT(18) for the self link
ATH12K_WMI_FLAG_MLO_IEEE_LINK_IDX_VALID_PARTNER BIT(19) for partner links
Firmware parses ieee_link_id only when the matching flag is set.
Also fix the debug message by using correct format specifiers and host-endian
values instead of __le32 values.
Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.6-01243-QCAHKSWPL_SILICONZ-1
Co-developed-by: Hari Naraayana Desikan Kannan <hari.kannan@oss.qualcomm.com>
Signed-off-by: Hari Naraayana Desikan Kannan <hari.kannan@oss.qualcomm.com>
Co-developed-by: Karthik M <karthik.m@oss.qualcomm.com>
Signed-off-by: Karthik M <karthik.m@oss.qualcomm.com>
Signed-off-by: Manish Dharanenthiran <manish.dharanenthiran@oss.qualcomm.com>
---
Changes in v2:
- Addressed comments on debug message.
- Modified commit message to include the details of debug message
modification.
- Link to v1: https://lore.kernel.org/r/20260619-ieee_link_id-v1-1-36cf573cb81d@oss.qualcomm.com
---
drivers/net/wireless/ath/ath12k/mac.c | 3 +++
drivers/net/wireless/ath/ath12k/wmi.c | 32 ++++++++++++++++++++------------
drivers/net/wireless/ath/ath12k/wmi.h | 7 +++++++
3 files changed, 30 insertions(+), 12 deletions(-)
diff --git a/drivers/net/wireless/ath/ath12k/mac.c b/drivers/net/wireless/ath/ath12k/mac.c
index af354bef5c0d..773ecd6da8e5 100644
--- a/drivers/net/wireless/ath/ath12k/mac.c
+++ b/drivers/net/wireless/ath/ath12k/mac.c
@@ -11253,6 +11253,8 @@ ath12k_mac_mlo_get_vdev_args(struct ath12k_link_vif *arvif,
ml_arg->assoc_link = arvif->is_sta_assoc_link;
+ ml_arg->ieee_link_id = arvif->link_id;
+
partner_info = ml_arg->partner_info;
links = ahvif->links_map;
@@ -11276,6 +11278,7 @@ ath12k_mac_mlo_get_vdev_args(struct ath12k_link_vif *arvif,
partner_info->vdev_id = arvif_p->vdev_id;
partner_info->hw_link_id = arvif_p->ar->pdev->hw_link_id;
+ partner_info->ieee_link_id = arvif_p->link_id;
ether_addr_copy(partner_info->addr, link_conf->addr);
ml_arg->num_partner_links++;
partner_info++;
diff --git a/drivers/net/wireless/ath/ath12k/wmi.c b/drivers/net/wireless/ath/ath12k/wmi.c
index 84a31b953db8..22ff17708722 100644
--- a/drivers/net/wireless/ath/ath12k/wmi.c
+++ b/drivers/net/wireless/ath/ath12k/wmi.c
@@ -1228,10 +1228,14 @@ int ath12k_wmi_vdev_start(struct ath12k *ar, struct wmi_vdev_start_req_arg *arg,
le32_encode_bits(arg->ml.mcast_link,
ATH12K_WMI_FLAG_MLO_MCAST_VDEV) |
le32_encode_bits(arg->ml.link_add,
- ATH12K_WMI_FLAG_MLO_LINK_ADD);
+ ATH12K_WMI_FLAG_MLO_LINK_ADD) |
+ cpu_to_le32(ATH12K_WMI_FLAG_MLO_IEEE_LINK_IDX_VALID);
- ath12k_dbg(ar->ab, ATH12K_DBG_WMI, "vdev %d start ml flags 0x%x\n",
- arg->vdev_id, ml_params->flags);
+ ml_params->ieee_link_id = cpu_to_le32(arg->ml.ieee_link_id);
+
+ ath12k_dbg(ar->ab, ATH12K_DBG_WMI, "vdev %u start link_id %u ml flags 0x%x\n",
+ arg->vdev_id, arg->ml.ieee_link_id,
+ le32_to_cpu(ml_params->flags));
ptr += sizeof(*ml_params);
@@ -1244,19 +1248,23 @@ int ath12k_wmi_vdev_start(struct ath12k *ar, struct wmi_vdev_start_req_arg *arg,
partner_info = ptr;
for (i = 0; i < arg->ml.num_partner_links; i++) {
+ struct wmi_ml_partner_info *pinfo = &arg->ml.partner_info[i];
+
partner_info->tlv_header =
ath12k_wmi_tlv_cmd_hdr(WMI_TAG_MLO_PARTNER_LINK_PARAMS,
sizeof(*partner_info));
- partner_info->vdev_id =
- cpu_to_le32(arg->ml.partner_info[i].vdev_id);
- partner_info->hw_link_id =
- cpu_to_le32(arg->ml.partner_info[i].hw_link_id);
+ partner_info->vdev_id = cpu_to_le32(pinfo->vdev_id);
+ partner_info->hw_link_id = cpu_to_le32(pinfo->hw_link_id);
ether_addr_copy(partner_info->vdev_addr.addr,
- arg->ml.partner_info[i].addr);
-
- ath12k_dbg(ar->ab, ATH12K_DBG_WMI, "partner vdev %d hw_link_id %d macaddr%pM\n",
- partner_info->vdev_id, partner_info->hw_link_id,
- partner_info->vdev_addr.addr);
+ pinfo->addr);
+ partner_info->flags =
+ cpu_to_le32(ATH12K_WMI_FLAG_MLO_IEEE_LINK_IDX_VALID_PARTNER);
+ partner_info->ieee_link_id = cpu_to_le32(pinfo->ieee_link_id);
+
+ ath12k_dbg(ar->ab, ATH12K_DBG_WMI, "partner vdev %u hw_link_id %u macaddr %pM link_id %u ml flags 0x%x\n",
+ pinfo->vdev_id, pinfo->hw_link_id,
+ pinfo->addr, pinfo->ieee_link_id,
+ le32_to_cpu(partner_info->flags));
partner_info++;
}
diff --git a/drivers/net/wireless/ath/ath12k/wmi.h b/drivers/net/wireless/ath/ath12k/wmi.h
index c452e3d57a29..51f3426e1fcd 100644
--- a/drivers/net/wireless/ath/ath12k/wmi.h
+++ b/drivers/net/wireless/ath/ath12k/wmi.h
@@ -2954,10 +2954,13 @@ struct wmi_vdev_create_mlo_params {
#define ATH12K_WMI_FLAG_MLO_EMLSR_SUPPORT BIT(6)
#define ATH12K_WMI_FLAG_MLO_FORCED_INACTIVE BIT(7)
#define ATH12K_WMI_FLAG_MLO_LINK_ADD BIT(8)
+#define ATH12K_WMI_FLAG_MLO_IEEE_LINK_IDX_VALID BIT(18)
+#define ATH12K_WMI_FLAG_MLO_IEEE_LINK_IDX_VALID_PARTNER BIT(19)
struct wmi_vdev_start_mlo_params {
__le32 tlv_header;
__le32 flags;
+ __le32 ieee_link_id;
} __packed;
struct wmi_partner_link_info {
@@ -2965,6 +2968,8 @@ struct wmi_partner_link_info {
__le32 vdev_id;
__le32 hw_link_id;
struct ath12k_wmi_mac_addr_params vdev_addr;
+ __le32 flags;
+ __le32 ieee_link_id;
} __packed;
struct wmi_vdev_delete_cmd {
@@ -3120,6 +3125,7 @@ struct wmi_ml_partner_info {
bool primary_umac;
bool logical_link_idx_valid;
u32 logical_link_idx;
+ u32 ieee_link_id;
};
struct wmi_ml_arg {
@@ -3127,6 +3133,7 @@ struct wmi_ml_arg {
bool assoc_link;
bool mcast_link;
bool link_add;
+ u32 ieee_link_id;
u8 num_partner_links;
struct wmi_ml_partner_info partner_info[ATH12K_WMI_MLO_MAX_LINKS];
};
---
base-commit: 63abe299b12b317dfee5bcd09037da4668a4431a
change-id: 20260610-ieee_link_id-3424c332b216
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox