For ath10k, document NVMEM device tree bindings.
For ath11k, fix an error path resource leak.
For ath12k, fix monitor RX buffer lifecycle issues, properly align QMI
memory to meet firmware requirements, extend datapath device stats
coverage, and a few other cleanups.
-----BEGIN PGP SIGNATURE-----
iHUEABYKAB0WIQQ/mtSHzPUi16IfDEksFbugiYzLewUCarln3AAKCRAsFbugiYzL
ewvsAP0ZJbiy/TgZdDGdcT1eqzkPcGm5xcIlf1SjxEpVpXYC+gD+KadlhSk6KkLZ
TCLJPcK9YXRP+SDfB8mmLrM7dKk//wk=
=y2fT
-----END PGP SIGNATURE-----
Merge tag 'ath-next-20260927' of git://git.kernel.org/pub/scm/linux/kernel/git/ath/ath
Jeff Johnson says:
==================
ath.git patches for v7.4 (PR #2)
For ath10k, document NVMEM device tree bindings.
For ath11k, fix an error path resource leak.
For ath12k, fix monitor RX buffer lifecycle issues, properly align QMI
memory to meet firmware requirements, extend datapath device stats
coverage, and a few other cleanups.
==================
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
When an association with AP times out, and the connection is an
Enhanced Privacy Protection (EPP) connection where the TK is already
installed, send an explicit deauthentication frame to the AP so it
would clear its local state. Not doing so might impact (fail) future
connection attempts with this AP (that might think that the station
is still connected).
This cannot be done by user space, since as part of the association
timeout flow, the station and corresponding keys are removed.
Assisted-by: GithubCopilot:claude-opus-5.0
Signed-off-by: Ilan Peer <ilan.peer@intel.com>
Reviewed-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Miri Korenblit <miriam.rachel.korenblit@intel.com>
Link: https://patch.msgid.link/20260926212249.736b01b4a76d.Ie528ea57d4d8dc8abfca406f8bae55a3902ff740@changeid
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
lbs_process_rxed_packet() computes the packet header pointer as
skb->data + rxpd->pkt_ptr, where pkt_ptr is a 32-bit value supplied
by the device, and never checks it against the packet length. The
only validation (skb->len < ETH_HLEN + 8 + sizeof(struct rxpd))
bounds the total length, not pkt_ptr.
A bogus device can report an arbitrary pkt_ptr:
- the memcmp() against the RFC1042 header reads 6 bytes at
pkt_ptr + 14, potentially past the skb buffer
- if the compared bytes happen to match, the EthernetII header
reconstruction writes 12 bytes at pkt_ptr + 8;
- hdrchop derived from pkt_ptr is later passed to skb_pull().
Validate pkt_ptr before using it: it must leave room for a full
struct rxpackethdr within the received frame. It is not expected
to affect the driver behavior in most cases, only invalid pkt_ptr
packets being dropped.
Discovered by Atuin - Automated Vulnerability Discovery Engine.
Assisted-by: LLM
Signed-off-by: Tianchu Chen <flynnnchen@tencent.com>
Link: https://patch.msgid.link/f22d4f23e5e54b1debd6038b3b75119f97920a73@linux.dev
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
If our .suspend() fails, we forget to unwind the early steps -- namely,
re-attaching our network interfaces. This commonly occurs if, for
example, we fail to program WoWLAN patterns to the device. Without this,
the interface won't work again.
Tested on a Rockchip RK3399 Gru/Kevin Chromebook, with Marvell 8997
PCIe WLAN.
Signed-off-by: Brian Norris <briannorris@chromium.org>
Link: https://patch.msgid.link/20260925172218.1.Ie4146d413a6be79caa11cf34e19b23f514ad3f5e@changeid
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
I came across a rare warning in the b43legacy driver while building
randconfig kernels using clang-21.1.8, with KASAN enabled:
drivers/net/wireless/broadcom/b43legacy/main.c:3250:12: error: stack frame size (1392) exceeds limit (1280) in 'b43legacy_wireless_core_init' [-Werror,-Wframe-larger-than]
3250 | static int b43legacy_wireless_core_init(struct b43legacy_wldev *dev)
| ^
There are no actual large variables on the stack here, just excessive
spills, and the code looks fine otherwise, so this is really an
optimization quirk in the compiler. Marking the prepare_phy_data_for_init()
function as noinline completely avoids the issue, with no function in
this file using more than 200 bytes of stack space, same as without KASAN.
Link: https://pastebin.com/raw/KpV124Ep # .config
Link: https://pastebin.com/CxWfsBN0 # assembler output, truncated
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
Link: https://patch.msgid.link/20260925130749.4191347-1-arnd@kernel.org
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
cw1200_rx_cb() stores the link ID from the device-supplied WSM
header (a 4-bit field, range 0-15) into priv->action_linkid for P2P
public action frames without an upper bound check. The work handler
cw1200_link_id_reset() then uses it to index link_id_db[], which has
only CW1200_MAX_STA_IN_AP_MODE (5) entries, so a device reporting a
link ID of 6-15 makes the driver read and write cw1200_common fields
past the array (a status copy and a constant store onto adjacent
work/lock/timer fields), corrupting driver state.
The first link ID check in the same function (used for timestamp
tracking) already validates against CW1200_MAX_STA_IN_AP_MODE and
degrades out-of-range IDs to untracked handling, so out-of-range
link IDs on the RX path are anticipated; the P2P remap branch was
missed.
Add the same bound to the remap branch. This is expected to keep
driver behavior unchanged in most cases: the driver itself only
assigns link IDs 1..5, and a P2P public action frame carrying any
other ID now degrades to the same untracked handling the first
branch already applies, instead of corrupting memory.
Discovered by Atuin - Automated Vulnerability Discovery Engine.
Assisted-by: LLM
Signed-off-by: Tianchu Chen <flynnnchen@tencent.com>
Link: https://patch.msgid.link/969ee752d023e7431481605c320fa0636cc6f20c@linux.dev
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
mwifiex_sdio_fw_dump() reads the number of memory regions (dump_num)
from a device register and uses it to index the static 15-entry
mem_type_mapping_tbl[] without any bounds check. A bogus device can
report a dump_num larger than the table; each out-of-table loop
iteration then reads entry->mem_name and entry->done_flag and stores
a vmalloc pointer and a device-controlled size past the end of the
table, into adjacent .data (up to ~5.6KiB when dump_num is 255).
The dump path runs after command timeouts or firmware crashes, so a
bogus device can first force an error to trigger the dump and then
report a bogus dump_num.
Limit dump_num to the table size instead of aborting the dump. This
is not expected to change the behavior on normal devices.
Discovered by Atuin - Automated Vulnerability Discovery Engine.
Assisted-by: LLM
Signed-off-by: Tianchu Chen <flynnnchen@tencent.com>
Acked-by: Brian Norris <briannorris@chromium.org>
Link: https://patch.msgid.link/33a45fd59b5569cbce79142d2e012e191989ec26@linux.dev
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
When an interface owning the active hardware ROC is purged, a ROC
queued for another interface can become the head of roc_list without
being started. Subsequent requests only append to the non-empty list,
so no driver work is scheduled and the entries are never freed.
Flush pending ROC start work and cancel pending completion work before
handing the remaining queue to the normal next-ROC path. This preserves
the existing software ROC handling and avoids stale workers operating
on the newly started ROC.
Reported-by: Vega <vega@nebusec.ai>
Assisted-by: LLM
Signed-off-by: Ruide Cao <caoruide123@gmail.com>
Signed-off-by: Ren Wei <weir@nebusec.ai>
Link: https://patch.msgid.link/6975ce9d8e9a153e8319d10e6e7c7be004d6df88.1787220252.git.vega.cover-letter@nebusec.ai
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Simulate firmware completing a deferred NAN schedule update in
mac80211_hwsim by calling ieee80211_nan_sched_update_done() from a delayed
work, so that the completion notification reaches user space after the
update request returns, as it would with real hardware. This doesn't really
implement the schedule update flow and doesn't announce anything to the
peers. However, it should be good enough meanwhile for some minimal testing.
Signed-off-by: Andrei Otcheretianski <andrei.otcheretianski@intel.com>
Reviewed-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Miri Korenblit <miriam.rachel.korenblit@intel.com>
Link: https://patch.msgid.link/20260922144356.81f62b390ef6.I21654fe82a0065a055a1b958297b2beb4337a1f0@changeid
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
When IEEE80211_PROBE_FLAG_MIN_CONTENT is set, restrict the probe
request supported rates per Draft P802.11bi D5.0 specification:
- 2 GHz: only include 1, 2, 5.5, 6, 11, 12, 24 Mb/s
- 5/6 GHz: only include 6, 12, 24 Mb/s
Also skip the Extended Supported Rates element for minimal
content probes.
Signed-off-by: Ilan Peer <ilan.peer@intel.com>
Assisted-by: GitHub-Copilot:claude-opus-4-6
Signed-off-by: Miri Korenblit <miriam.rachel.korenblit@intel.com>
Link: https://patch.msgid.link/20260922143146.13a6fab60516.I3ebb1fa5d41622b1a0ddf9d008328fc19ad980a1@changeid
[drop strange comment about extended element]
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
A NAN peer that has dual radio can schedule a slot to 2 different
channels.
Until now, for single radio devices, we disallowed such a peer schedule.
This was done so because the assumption was that the user space needs to
pick one of the channels for us, according to its logic.
But for devices that have their ULW logic offloaded, it can be useful if we
program it with the full information and let it decide what to do.
For example:
- peer has slot S scheduled to C1 and C2
- local schedule has S scheduled to C1
- in practice, the device is on C2 at S, for example due to non-NAN
activity
In that case, this extra information can actually be useful to the
device, and bring to more efficient usage of the time.
Allow a peer schedule that has a single slot scheduled to two different
channels.
Signed-off-by: Miri Korenblit <miriam.rachel.korenblit@intel.com>
Link: https://patch.msgid.link/20260922140131.6c3e3f552bda.I056644aaeea3f96605272651c4108e9ff224caf1@changeid
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
This is now the standard way to print data for sysfs read
callbacks.
Assisted-by: GitHubCopilot:GPT-5.3-Codex
Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
Reviewed-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Miri Korenblit <miriam.rachel.korenblit@intel.com>
Link: https://patch.msgid.link/20260922135556.49646df6da77.If5066fce4d8f42221009e77d76c68132e18c6a0d@changeid
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
valid_regdb() walks the regulatory.db country table and returns
true as soon as either:
- a zero coll_ptr entry (the required terminator) is found, or
- the next country entry would no longer fit in the buffer.
The second case silently accepts a database image whose country
table reaches the end of the buffer without a zero-terminator.
The callers of valid_regdb() assume that every country is zero
terminated.
Exit immediately upon zero terminator, don't accept a database
without a zero terminator.
Assisted-by: GitHubCopilot:GPT-5.3-Codex
Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
Reviewed-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Miri Korenblit <miriam.rachel.korenblit@intel.com>
Link: https://patch.msgid.link/20260922133709.3d75b1440a1b.Ib92fa3a47e4cd5109c6139e9a4aac85c50f9be22@changeid
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
In cfg80211_nan_set_local_schedule(), after calling the driver,
the old channel definitions were freed and only then the new ones were
allocated and stored.
This had two problems:
- On allocation failure the previous channel definitions had already been
freed while the driver had already applied the new schedule, leaving
the wdev with no channel definitions.
- If the driver completes a deferred schedule update synchronously,
the completion notification to user space fired before the new
channel definitions were stored, exposing an inconsistent state.
Allocate and fill the new channel definitions before calling the driver,
swap them in, and roll back on failure. Also set the pending flag before
the driver call so that a synchronous deferred completion can clear it.
Signed-off-by: Andrei Otcheretianski <andrei.otcheretianski@intel.com>
Signed-off-by: Miri Korenblit <miriam.rachel.korenblit@intel.com>
Link: https://patch.msgid.link/20260922132247.d0665fa8a5c1.I0b45103342d4a911142a2325b9259258758a0670@changeid
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
My static analyzer identified a potential issue in 'net/mac80211/mesh_pathtbl.c':
mpath_expired() reads mpath->flags and mpath->exp_time without holding
mpath->state_lock, while mesh_path_fix_nexthop() and the other writers update
both fields under that lock. In mpath_lookup() and
__mesh_path_lookup_by_idx() the unlocked check is followed by taking the lock
and clearing MESH_PATH_ACTIVE, so the check and the update are not atomic:
CPU0 (mpath_lookup) CPU1 (mesh_path_fix_nexthop)
mpath_expired() reads the stale
flags/exp_time and returns true
spin_lock_bh(&mpath->state_lock)
mpath->exp_time = 0;
mpath->flags = FIXED|SN_VALID;
mesh_path_activate(mpath);
spin_unlock_bh(&mpath->state_lock)
spin_lock_bh(&mpath->state_lock)
mpath->flags &= ~MESH_PATH_ACTIVE;
spin_unlock_bh(&mpath->state_lock)
A path which mesh_path_fix_nexthop() has just set up as MESH_PATH_FIXED and
MESH_PATH_ACTIVE then has MESH_PATH_ACTIVE cleared again, and forwarding to
that destination silently stops.
Take mpath->state_lock before evaluating mpath_expired() so that the check and
the clearing of MESH_PATH_ACTIVE are atomic with respect to the writers.
Fixes: 60854fd945 ("mac80211: mesh: convert path table to rhashtable")
Signed-off-by: Ginger Li <ginger.jzllee@gmail.com>
Link: https://patch.msgid.link/20260922054253.11976-1-ginger.jzllee@gmail.com
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Current logic only looks globally at interface counts to validate that a
monitor can have its channel configured. This works to ensure that the
wiphy is not pulled off the channel currently being used by another
active interface, but fails to allow for the case where the channels in
use on the other active interface and the desired channel for the
monitor fall on disjoint sets of radios.
Instead, search for any interface which would cause conflict, otherwise
allowing for the configuration.
Suggested-by: Dylan Eskew <dylan.eskew@candelatech.com>
Signed-off-by: Rory Little <roryl@candelatech.com>
Link: https://patch.msgid.link/20260921210441.3137-1-roryl@candelatech.com
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
AP power type is regulatory operating state, so changing it requires
full AP reconfiguration and validation. Allowing it through
color-change could bypass stricter checks done in AP setup.
Keep color-change behavior limited to color updates only.
Signed-off-by: Pagadala Yesu Anjaneyulu <pagadala.yesu.anjaneyulu@intel.com>
Reviewed-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Miri Korenblit <miriam.rachel.korenblit@intel.com>
Link: https://patch.msgid.link/20260921224731.1d8727ce4fbf.I1049058ae5e60b7ebcb450d03f6b13cee573eeea@changeid
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Defer the cfg80211_reg_can_beacon_relax() check
from __nl80211_set_channel() for AP and P2P-GO.
At __nl80211_set_channel() stage AP type is not fully known
before start_ap, so this early check incorrectly rejects valid
VLP AP bring-up. start_ap has the required AP context and already
performs the regulatory validation, so start checking after start_ap.
This way, VLP APs can be brought up. Also handle the CSA scenario by
running regulatory beaconing validation during channel switch and
preserving/updating AP reg_power across CSA completion.
Signed-off-by: Pagadala Yesu Anjaneyulu <pagadala.yesu.anjaneyulu@intel.com>
Reviewed-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Miri Korenblit <miriam.rachel.korenblit@intel.com>
Link: https://patch.msgid.link/20260921224731.67fbc8a28a2c.I5633284cb4c82ffb4e4e32e6f2dcc9a71fd5b06a@changeid
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Implement the nan_set_non_evac_channels operation in mac80211. It marks
the provided channels as non-evacuable in the current local schedule and
clears the flag on all other channels. All provided channels must exist
in the current schedule, otherwise -ENOENT is returned.
ieee80211_nan_find_evac_chan() skips channels marked as non-evacuable
when selecting a channel to evacuate for concurrent operations.
Fixes: 42c9de58d9 ("wifi: mac80211: add NAN channel evacuation support")
Signed-off-by: Andrei Otcheretianski <andrei.otcheretianski@intel.com>
Reviewed-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Miri Korenblit <miriam.rachel.korenblit@intel.com>
Link: https://patch.msgid.link/20260921215936.ef5884349253.I38b685378c3557679ed6387922a94a7da821555c@changeid
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Add a new NL80211_CMD_NAN_SET_NON_EVAC_CHANNELS command that lets user
space mark a set of NAN channels as non-evacuable. The command carries
the channels as nested NL80211_ATTR_NAN_CHANNEL attributes (chandef
only) and replaces the entire set of non-evacuable channels; channels
not included in the list become evacuable again.
All provided channels must already exist in the current local schedule,
otherwise -ENOENT is returned. The command is rejected with -EBUSY
while a schedule update is pending.
This prevents the kernel from evacuating channels that carry NDC or
immutable schedules, so evacuating these channels would break existing
NDP connections.
Fixes: 154b0296c0 ("wifi: nl80211: Add a notification to notify NAN channel evacuation")
Signed-off-by: Andrei Otcheretianski <andrei.otcheretianski@intel.com>
Reviewed-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Miri Korenblit <miriam.rachel.korenblit@intel.com>
Link: https://patch.msgid.link/20260921215936.2efc32011e73.Ice8839058e114f6f9783079807df446388187dda@changeid
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Add the handling of CIP during association, when adding a station in AP
mode and also add some checks whether the keys are being installed
correctly.
For internal use, add a new key flag CIP that is used for both the
pairwise key and CIGTK. The CIGTK will then have the MCAST_KEY and CIP
flags set.
As the CIGTK uses key indices 0 and 1, add a new variable to track it
separately from the other GTKs.
Signed-off-by: Benjamin Berg <benjamin.berg@intel.com>
Link: https://patch.msgid.link/20260921144048.f032c70e0bc2.I30cf9ae29629188b8674e2268a6b592c1a63128b@changeid
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
The CIGTK keys use a key index of 0 or 1, which is not unique. As such,
a new parameter is needed to differentiate the key type. Add the
parameter to prepare for handling the CIGTK in the future.
Signed-off-by: Benjamin Berg <benjamin.berg@intel.com>
Link: https://patch.msgid.link/20260921144048.8bfea7df6b06.I3d046fbe7dfb3883471773f84e7a791b5b97000e@changeid
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
The Control Integrity Protocol consists of a set of capabilities for the
MIC padding as well as a new CIGTK that can be installed. The CIGTK uses
a fixed GMAC-256 cipher for which no RSN extension is defined as it is
bound to the pairwise cipher being GCMP-256. The CIGTK uses the key
index 0 and 1, making it necessary to add a new key type for it.
Add a new CIP feature flag and attributes for CIP Capabilities and
enabling the feature for stations and the association.
Also extend the cfg80211 API to pass the key type rather than a single
pairwise boolean.
Signed-off-by: Benjamin Berg <benjamin.berg@intel.com>
Link: https://patch.msgid.link/20260921144048.aa7939493375.I49c0be0a1b05d625cc307e9bdd13c32a6c18667f@changeid
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Since there are two sets of key flags, one for the driver
and one internal to mac80211, add the first set in debugfs
as well. This will be used by hwsim tests to determine if
a key is pairwise or not, since the next changes will make
mac80211 use only per-STA GTKs.
Link: https://patch.msgid.link/20260921144048.641cb1492f2e.I3a7d6912def9ba2623b41cc672704cbe3beb0bf3@changeid
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Document the NVMEM cells supported by the ath10k driver, the
mac-address, pre-calibration data, and calibration data.
Since such data may also originate from chipset OTP or be supplied
via other device tree structures. All of these cells are optional
and can be provided independently, in any combination.
Reviewed-by: Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>
Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@oss.qualcomm.com>
Signed-off-by: Loic Poulain <loic.poulain@oss.qualcomm.com>
Link: https://patch.msgid.link/20260806-block-as-nvmem-v10-2-be598b2a5606@oss.qualcomm.com
Signed-off-by: Jeff Johnson <jeff.johnson@oss.qualcomm.com>
When HW CC is not done, the WBM RX error path falls back to
cookie-based descriptor retrieval via ath12k_dp_get_rx_desc(). This
fallback path is taken before knowing whether the retrieval will
succeed, so it is not a drop event and should not be counted in the
drop[] array.
Add a dedicated sw_desc_fallback counter in
ath12k_device_dp_rx_wbm_err_stats to track how often the HW CC
fallback path is taken, distinct from actual packet drops. Expose
the counter in the device_dp_stats debugfs file as a separate line.
Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.6.r1-00402-QCAHKSWPL_SILICONZ-1
Signed-off-by: Aniruddha Mishra <aniruddha.mishra@oss.qualcomm.com>
Co-developed-by: Pardeep Kaur <pardeep.kaur@oss.qualcomm.com>
Signed-off-by: Pardeep Kaur <pardeep.kaur@oss.qualcomm.com>
Reviewed-by: Rameshkumar Sundaram <rameshkumar.sundaram@oss.qualcomm.com>
Reviewed-by: Baochen Qiang <baochen.qiang@oss.qualcomm.com>
Link: https://patch.msgid.link/20260819053247.1420393-9-pardeep.kaur@oss.qualcomm.com
Signed-off-by: Jeff Johnson <jeff.johnson@oss.qualcomm.com>
The REO Rx Received section in device_dp_stats debugfs uses a 1-based
ring index ("Ring1:", "Ring2:", ...) which is inconsistent with the rest
of ath12k where rings are indexed from 0. Fix it to use 0-based indexing
and lowercase "ring%d:" to match the style used by all other ring counters
in the same function.
Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.6.r1-00402-QCAHKSWPL_SILICONZ-1
Signed-off-by: Pardeep Kaur <pardeep.kaur@oss.qualcomm.com>
Reviewed-by: Rameshkumar Sundaram <rameshkumar.sundaram@oss.qualcomm.com>
Reviewed-by: Baochen Qiang <baochen.qiang@oss.qualcomm.com>
Link: https://patch.msgid.link/20260819053247.1420393-8-pardeep.kaur@oss.qualcomm.com
Signed-off-by: Jeff Johnson <jeff.johnson@oss.qualcomm.com>
The device DP stats provide visibility into RX errors and drops but
lack a counter for successfully delivered packets. Without this, it is
difficult to correlate REO ring activity with actual stack delivery
during debugging or performance analysis.
Add sent_to_stack[DP_REO_DST_RING_MAX][ATH12K_MAX_DEVICES] to
ath12k_device_dp_stats to track successful deliveries per REO ring per
device. The counter is attributed to the ring owner's dp and indexed by
partner_dp->device_id, keeping it in the same debugfs file as reo_rx[]
for direct comparison in MLO configurations.
Increment the counter just before each MSDU is handed off to the stack
via ath12k_dp_rx_deliver_msdu(). Add a likely()/WARN_ON_ONCE() bounds
check on ring_id before indexing sent_to_stack[], consistent with all
other new stat arrays in this series.
Expose the per-ring per-device counts in the device_dp_stats debugfs
file under a new 'REO sent to stack:' section.
Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.6.r1-00402-QCAHKSWPL_SILICONZ-1
Signed-off-by: Hariharan Ramanathan <hariharan.ramanathan@oss.qualcomm.com>
Co-developed-by: Pardeep Kaur <pardeep.kaur@oss.qualcomm.com>
Signed-off-by: Pardeep Kaur <pardeep.kaur@oss.qualcomm.com>
Reviewed-by: Rameshkumar Sundaram <rameshkumar.sundaram@oss.qualcomm.com>
Reviewed-by: Baochen Qiang <baochen.qiang@oss.qualcomm.com>
Link: https://patch.msgid.link/20260819053247.1420393-7-pardeep.kaur@oss.qualcomm.com
Signed-off-by: Jeff Johnson <jeff.johnson@oss.qualcomm.com>
Without fine-grained drop counters, diagnosing RX failures in the
WBM error path requires intrusive debugging. Introduce per-drop-reason
counters to track exactly where and why packets are dropped during
WBM RX error handling.
Introduce a new dp_stats.h header and define ath12k_wbm_err_drop_reason
enum there covering all drop points in the WBM RX error path: descriptor
parse failures, SW descriptor retrieval errors, null partner DP,
invalid HW link ID, null pdev/ar, CAC running, scatter-gather drops,
and invalid NWifi header length. The new header is included by dp.h
which is already included by all consumers.
Add ath12k_device_dp_rx_wbm_err_stats struct grouping rxdma_error[],
reo_error[], and the new drop[] counters, replacing the flat arrays
previously in ath12k_device_dp_stats.
Add bounds checks before indexing rxdma_error[] and reo_error[] with
hardware-supplied err_code values to prevent out-of-bounds writes, using
the same likely/WARN_ON_ONCE pattern as the TX stats bounds fixes.
Add ath12k_wifi7_dp_rx_wbm_err_free_skb() helper to combine drop stat
increment and skb free at each drop site, reducing repetition. Define
the helper at the top of dp_rx.c before its first use.
Increment WBM_ERR_DROP_RXDMA_GENERIC only inside rxdma_err()'s
default: branch so it counts only unhandled RXDMA errors, not every
RXDMA drop - consistent with how WBM_ERR_DROP_REO_GENERIC is counted.
Expose WBM RX drop counts in the device_dp_stats debugfs file under a
new 'WBM Rx Drop Count' section.
Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.6.r1-00402-QCAHKSWPL_SILICONZ-1
Signed-off-by: Aniruddha Mishra <aniruddha.mishra@oss.qualcomm.com>
Co-developed-by: Pardeep Kaur <pardeep.kaur@oss.qualcomm.com>
Signed-off-by: Pardeep Kaur <pardeep.kaur@oss.qualcomm.com>
Reviewed-by: Rameshkumar Sundaram <rameshkumar.sundaram@oss.qualcomm.com>
Reviewed-by: Baochen Qiang <baochen.qiang@oss.qualcomm.com>
Link: https://patch.msgid.link/20260819053247.1420393-6-pardeep.kaur@oss.qualcomm.com
Signed-off-by: Jeff Johnson <jeff.johnson@oss.qualcomm.com>
There is no way to reset device DP stats counters without reloading
the driver, making it difficult to isolate issues to a specific time
window during debugging.
Add a write handler to the device_dp_stats debugfs file so that
writing 'reset' clears all device DP stats counters. Change the file
mode from 0400 to 0600 to allow write access. Use
simple_write_to_buffer() to correctly handle partial writes and
non-zero ppos, consistent with ath12k_write_simulate_fw_crash().
No lock is taken around the memset since the counters are updated
locklessly in the datapath; taking dp_lock would be misleading as it
does not protect device_stats updates.
Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.6.r1-00402-QCAHKSWPL_SILICONZ-1
Signed-off-by: Hariharan Ramanathan <hariharan.ramanathan@oss.qualcomm.com>
Co-developed-by: Pardeep Kaur <pardeep.kaur@oss.qualcomm.com>
Signed-off-by: Pardeep Kaur <pardeep.kaur@oss.qualcomm.com>
Reviewed-by: Rameshkumar Sundaram <rameshkumar.sundaram@oss.qualcomm.com>
Reviewed-by: Baochen Qiang <baochen.qiang@oss.qualcomm.com>
Link: https://patch.msgid.link/20260819053247.1420393-5-pardeep.kaur@oss.qualcomm.com
Signed-off-by: Jeff Johnson <jeff.johnson@oss.qualcomm.com>
When ath12k_dp_tx_assign_buffer() fails, the TX path returns -ENOMEM
silently with no visibility into which traffic class is affected.
Without a counter, TX descriptor pool exhaustion is invisible during
debugging.
Add txbuf_na[] indexed by pool_id to ath12k_device_dp_tx_err_stats to
track TX descriptor pool allocation failures per traffic class and
increment it on assign failure in the TX path. Expose the per-pool
counts in debugfs under a new 'TX Descriptor Pool Alloc Failures'
section.
Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.6.r1-00402-QCAHKSWPL_SILICONZ-1
Signed-off-by: Hariharan Ramanathan <hariharan.ramanathan@oss.qualcomm.com>
Co-developed-by: Pardeep Kaur <pardeep.kaur@oss.qualcomm.com>
Signed-off-by: Pardeep Kaur <pardeep.kaur@oss.qualcomm.com>
Reviewed-by: Rameshkumar Sundaram <rameshkumar.sundaram@oss.qualcomm.com>
Reviewed-by: Baochen Qiang <baochen.qiang@oss.qualcomm.com>
Link: https://patch.msgid.link/20260819053247.1420393-4-pardeep.kaur@oss.qualcomm.com
Signed-off-by: Jeff Johnson <jeff.johnson@oss.qualcomm.com>
The variable wbm_status in ath12k_dp_tx_process_htt_tx_complete()
holds a value from the HTT TX WBM completion status field, not a
generic WBM status. Rename it to htt_status to accurately reflect
the field origin and improve code clarity.
Also fix ts.acked assignment inside the HAL_WBM_REL_HTT_TX_COMP_STATUS_OK
case to use true directly since the condition is always true within
that case branch.
Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.6.r1-00402-QCAHKSWPL_SILICONZ-1
Signed-off-by: Hariharan Ramanathan <hariharan.ramanathan@oss.qualcomm.com>
Co-developed-by: Pardeep Kaur <pardeep.kaur@oss.qualcomm.com>
Signed-off-by: Pardeep Kaur <pardeep.kaur@oss.qualcomm.com>
Reviewed-by: Rameshkumar Sundaram <rameshkumar.sundaram@oss.qualcomm.com>
Reviewed-by: Baochen Qiang <baochen.qiang@oss.qualcomm.com>
Link: https://patch.msgid.link/20260819053247.1420393-3-pardeep.kaur@oss.qualcomm.com
Signed-off-by: Jeff Johnson <jeff.johnson@oss.qualcomm.com>
The fw_tx_status[], tx_wbm_rel_source[], and tqm_rel_reason[] arrays
are indexed directly by values read from hardware without bounds checks.
Values at or beyond MAX_FW_TX_STATUS, HAL_WBM_REL_SRC_MODULE_MAX, or
MAX_TQM_RELEASE_REASON respectively would write past the end of the
arrays causing memory corruption.
Add likely() bounds checks before incrementing each counter. For
tx_wbm_rel_source[] and tqm_rel_reason[], add WARN_ON_ONCE() on the
out-of-bounds else branch. For fw_tx_status[], no WARN_ON_ONCE is added
since the switch statement that follows already calls ath12k_warn() in
its default: branch for unknown values, avoiding a double-warn.
Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.6.r1-00402-QCAHKSWPL_SILICONZ-1
Fixes: c5c62287e6 ("wifi: ath12k: Add device dp stats support")
Signed-off-by: Pardeep Kaur <pardeep.kaur@oss.qualcomm.com>
Reviewed-by: Rameshkumar Sundaram <rameshkumar.sundaram@oss.qualcomm.com>
Reviewed-by: Baochen Qiang <baochen.qiang@oss.qualcomm.com>
Link: https://patch.msgid.link/20260819053247.1420393-2-pardeep.kaur@oss.qualcomm.com
Signed-off-by: Jeff Johnson <jeff.johnson@oss.qualcomm.com>
ath12k_dp_rx_h_find_link_peer() is no longer referenced anywhere,
remove the unused helper and its declaration to avoid dead code.
Tested-on: QCC2072 hw1.0 PCI CI_WLAN.COL.1.0.c2-00229.1-QCACOLSWPL_V1_TO_SILICON-1
Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.1.c7-00108-QCAHMTSWPL_V1.0_V2.0_SILICONZ_UPSTREAM-3
Signed-off-by: Miaoqing Pan <miaoqing.pan@oss.qualcomm.com>
Reviewed-by: Rameshkumar Sundaram <rameshkumar.sundaram@oss.qualcomm.com>
Link: https://patch.msgid.link/20260803010532.302038-1-miaoqing.pan@oss.qualcomm.com
Signed-off-by: Jeff Johnson <jeff.johnson@oss.qualcomm.com>
Currently, while processing the WMI Service Ready Ext event, the iterator
in ath11k_service_ready_ext_event() can dispatch the HAL Regulatory
Capabilities handler ath11k_wmi_tlv_ext_soc_hal_reg_caps_parse() which can
allocate ab->reg_info_store.
If a subsequent failure occurs during iteration, the ab->reg_info_store
allocation is leaked.
Directly free and clear the pointer on the error path.
Note that the normal cleanup function ath11k_reg_free() cannot be used
since other regulatory-related fields are not yet populated at this point.
Compile tested only.
Fixes: 7004bdceef ("wifi: ath11k: store cur_regulatory_info for each radio")
Assisted-by: Claude:claude-sonnet-4-6
Reviewed-by: Baochen Qiang <baochen.qiang@oss.qualcomm.com>
Link: https://patch.msgid.link/20260817-reg_info_store-leak-v1-1-77025a99b074@oss.qualcomm.com
Signed-off-by: Jeff Johnson <jeff.johnson@oss.qualcomm.com>
ath12k_qmi_alloc_chunk() allocates the target memory chunks the firmware
requests via dma_alloc_coherent() and hands the resulting physical
addresses to the firmware. The firmware does not require every chunk to
be aligned, but each unaligned chunk consumes extra TLB entries when the
firmware maps it, and too many unaligned chunks exhaust the TLB and make
the firmware crash. The firmware team recommends aligning the chunks to
64 KB so that the TLB stays within budget. dma_alloc_coherent() only
guarantees page alignment, so a chunk can end up unaligned.
Align the physical address handed to the firmware to 64 KB. A natural
allocation is often already 64 KB aligned, so try the exact size first
and keep it when it happens to be aligned; only when it is not, free it
and over-allocate by SZ_64K - PAGE_SIZE and round the base up. Since the
DMA allocator already guarantees page alignment, that padding is enough
to reach the next 64 KB boundary. Record the raw allocation in
paddr_unaligned/vaddr_unaligned/total_size so the chunk can still be
freed correctly.
Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.1.c5-00302-QCAHMTSWPL_V1.0_V2.0_SILICONZ-1.115823.3
Tested-on: QCC2072 hw1.0 PCI WLAN.COL.1.0.c2-00074-QCACOLSWPL_V1_TO_SILICONZ-1
Signed-off-by: Baochen Qiang <baochen.qiang@oss.qualcomm.com>
Reviewed-by: Rameshkumar Sundaram <rameshkumar.sundaram@oss.qualcomm.com>
Link: https://patch.msgid.link/20260730-ath12k-align-qmi-memory-v1-3-0fef98dda614@oss.qualcomm.com
Signed-off-by: Jeff Johnson <jeff.johnson@oss.qualcomm.com>
paddr and size of a chunk are not cleared after the chunk is freed, which
is safe now since the code checks vaddr only and it is properly cleared
on free. However, leaving stale values can mislead diagnostics and future
maintenance. Clear both to reduce such risk, this also aligns with
ath12k_qmi_free_mlo_mem_chunk().
Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.1.c5-00302-QCAHMTSWPL_V1.0_V2.0_SILICONZ-1.115823.3
Tested-on: QCC2072 hw1.0 PCI WLAN.COL.1.0.c2-00074-QCACOLSWPL_V1_TO_SILICONZ-1
Signed-off-by: Baochen Qiang <baochen.qiang@oss.qualcomm.com>
Reviewed-by: Rameshkumar Sundaram <rameshkumar.sundaram@oss.qualcomm.com>
Link: https://patch.msgid.link/20260730-ath12k-align-qmi-memory-v1-2-0fef98dda614@oss.qualcomm.com
Signed-off-by: Jeff Johnson <jeff.johnson@oss.qualcomm.com>
When a target memory chunk fails to allocate, ath12k_qmi_alloc_chunk()
compares the requested chunk size against ATH12K_QMI_MAX_CHUNK_SIZE to
decide whether to ask the firmware to retry with smaller chunks
(-EAGAIN) or to give up (-ENOMEM). This threshold is the boundary that
tells a first (big) request apart from a retry (small) request, so it
has to match the size the firmware actually falls back to on retry.
That fallback size is not the same across all firmware, though. On
WCN7850 and QCC2072 the firmware splits the request into 512 KB chunks
on retry, whereas on QCN9274, IPQ5332 and IPQ5424 the firmware retries
with larger 2 MB segments instead of 512 KB. A single hardcoded 2 MB
threshold is therefore wrong for the former, and a hardcoded 512 KB
threshold would be wrong for the latter.
Replace the hardcoded ATH12K_QMI_MAX_CHUNK_SIZE with a per-device
qmi_max_chunk_size parameter: SZ_512K for WCN7850 and QCC2072, SZ_2M for
QCN9274, IPQ5332 and IPQ5424. No functional change for the latter (the
value stays 2 MB); the former now use the correct 512 KB boundary.
Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.1.c5-00302-QCAHMTSWPL_V1.0_V2.0_SILICONZ-1.115823.3
Tested-on: QCC2072 hw1.0 PCI WLAN.COL.1.0.c2-00074-QCACOLSWPL_V1_TO_SILICONZ-1
Signed-off-by: Baochen Qiang <baochen.qiang@oss.qualcomm.com>
Reviewed-by: Rameshkumar Sundaram <rameshkumar.sundaram@oss.qualcomm.com>
Link: https://patch.msgid.link/20260730-ath12k-align-qmi-memory-v1-1-0fef98dda614@oss.qualcomm.com
Signed-off-by: Jeff Johnson <jeff.johnson@oss.qualcomm.com>
ath12k_dp_cc_cleanup() assumes that every rx_desc_info entry with a
non-NULL skb still has an active DMA mapping and therefore always
calls dma_unmap_single() before freeing the skb.
This assumption is not true for the monitor RX path.
ath12k_wifi7_dp_rx_mon_mpdu_pop() may DMA-unmap a buffer and mark
rxcb->unmapped before returning early to hold the MSDU for later
reprocessing. In that state desc_info->skb remains populated, so
module removal can trigger a second dma_unmap_single() from
ath12k_dp_cc_cleanup().
IOMMU reports the issue as:
dma_unmap_phys()
dma_unmap_page_attrs()
ath12k_dp_cc_cleanup()
ath12k_dp_cmn_device_deinit()
ath12k_core_stop()
Skip dma_unmap_single() when rxcb->unmapped is already set and free
the skb directly.
Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.1.c7-00108-QCAHMTSWPL_V1.0_V2.0_SILICONZ_UPSTREAM-3
Fixes: 72bfbf19b7 ("wifi: ath12k: add support to reap and process mon dest ring")
Signed-off-by: Kang Yang <kang.yang@oss.qualcomm.com>
Reviewed-by: Baochen Qiang <baochen.qiang@oss.qualcomm.com>
Reviewed-by: Vasanthakumar Thiagarajan <vasanthakumar.thiagarajan@oss.qualcomm.com>
Link: https://patch.msgid.link/20260916060325.854-7-kang.yang@oss.qualcomm.com
Signed-off-by: Jeff Johnson <jeff.johnson@oss.qualcomm.com>
ath12k_dp_mon_comp_ppduid() updates *ppdu_id and returns
msdu_ppdu_id to indicate that a PPDU transition was detected.
When PPDU IDs wrap around, msdu_ppdu_id can be 0. In that case
the function updates *ppdu_id but returns 0, causing
ath12k_wifi7_dp_rx_mon_mpdu_pop() to interpret the result as
"no PPDU update" and continue processing the MPDU.
The MSDUs are then linked into head_msdu while their RX
descriptors have already been detached. Later,
ath12k_wifi7_dp_rx_mon_dest_process() detects the PPDU
mismatch and exits with the partially built MSDU chain,
leaking the SKBs.
kmemleak reports the leak through:
kmemleak_alloc()
__netdev_alloc_skb()
ath12k_dp_rx_bufs_replenish()
ath12k_wifi7_dp_rx_mon_dest_process()
Fix this by returning a boolean value from
ath12k_dp_mon_comp_ppduid() so the update notification is
independent of the actual PPDU ID value.
Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.1.c7-00108-QCAHMTSWPL_V1.0_V2.0_SILICONZ_UPSTREAM-3
Fixes: 72bfbf19b7 ("wifi: ath12k: add support to reap and process mon dest ring")
Signed-off-by: Kang Yang <kang.yang@oss.qualcomm.com>
Reviewed-by: Baochen Qiang <baochen.qiang@oss.qualcomm.com>
Reviewed-by: Vasanthakumar Thiagarajan <vasanthakumar.thiagarajan@oss.qualcomm.com>
Link: https://patch.msgid.link/20260916060325.854-6-kang.yang@oss.qualcomm.com
Signed-off-by: Jeff Johnson <jeff.johnson@oss.qualcomm.com>
ath12k_wifi7_dp_rx_mon_dest_process() allocates a dp_mon_mpdu with
kzalloc(GFP_ATOMIC) for each delivered MPDU. On allocation failure
it breaks out of the reap loop without calling
ath12k_hal_srng_dst_get_next_entry(), leaving the destination ring
tail pointer parked on the current entry -- the same entry will
be peek()ed on every subsequent NAPI schedule, stalling monitor
RX until the mon_dest_ring_stuck_cnt recovery path resyncs the
PPDU ID. The head_msdu chain accumulated for this iteration is
also orphaned since the break bypasses both the delivery and
the cleanup paths.
kmemleak reports these skbs in field testing:
kmemleak_alloc()
__netdev_alloc_skb()
ath12k_dp_rx_bufs_replenish()
ath12k_wifi7_dp_rx_mon_dest_process()
dp_mon_mpdu is used only within a single reap loop iteration and
is passed synchronously to ath12k_wifi7_dp_mon_rx_deliver(); the
callee does not retain the pointer. Place it on the stack instead
of using kzalloc(GFP_ATOMIC). This eliminates the allocation
failure path (and the ring stall it caused) and saves a
kzalloc/kfree pair per delivered MPDU.
Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.1.c7-00108-QCAHMTSWPL_V1.0_V2.0_SILICONZ_UPSTREAM-3
Fixes: 72bfbf19b7 ("wifi: ath12k: add support to reap and process mon dest ring")
Signed-off-by: Kang Yang <kang.yang@oss.qualcomm.com>
Reviewed-by: Baochen Qiang <baochen.qiang@oss.qualcomm.com>
Reviewed-by: Vasanthakumar Thiagarajan <vasanthakumar.thiagarajan@oss.qualcomm.com>
Link: https://patch.msgid.link/20260916060325.854-5-kang.yang@oss.qualcomm.com
Signed-off-by: Jeff Johnson <jeff.johnson@oss.qualcomm.com>
ath12k_wifi7_dp_rx_mon_mpdu_pop() assigns *tail_msdu from the loop
cursor msdu at function exit. That cursor reflects the state of the
last msdu_list entry processed, not the end of the accumulated MSDU
chain: on next_msdu paths (invalid skb, drop_mpdu, first-MSDU rx_desc
invalid) it is set to NULL, and on the set_pktlen failure path it
becomes a dangling pointer to a freed skb. When these occur on the
final iteration, callers see head_msdu populated with a valid chain
while tail_msdu is NULL or points to freed memory.
The chain end is already tracked by the local variable last, which is
updated only after each MSDU has been validated and linked. Use it as
the source for tail_msdu so head_msdu and tail_msdu are either both
NULL or both point into the same live chain.
Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.1.c7-00108-QCAHMTSWPL_V1.0_V2.0_SILICONZ_UPSTREAM-3
Fixes: 72bfbf19b7 ("wifi: ath12k: add support to reap and process mon dest ring")
Signed-off-by: Kang Yang <kang.yang@oss.qualcomm.com>
Reviewed-by: Baochen Qiang <baochen.qiang@oss.qualcomm.com>
Reviewed-by: Vasanthakumar Thiagarajan <vasanthakumar.thiagarajan@oss.qualcomm.com>
Link: https://patch.msgid.link/20260916060325.854-4-kang.yang@oss.qualcomm.com
Signed-off-by: Jeff Johnson <jeff.johnson@oss.qualcomm.com>
ath12k_wifi7_dp_rx_mon_mpdu_pop() aborts processing when a duplicate
monitor link descriptor is detected.
Previous iterations may already have linked MSDUs onto *head_msdu
and detached the corresponding RX buffers from their descriptors.
Returning without completing or freeing the chain leaves those
skbs orphaned, resulting in a memory leak.
kmemleak reports these skbs in field testing:
kmemleak_alloc()
__netdev_alloc_skb()
ath12k_dp_rx_bufs_replenish()
ath12k_wifi7_dp_rx_mon_dest_process()
Free the accumulated MSDU chain before returning and clear
*head_msdu so callers observe a consistent state.
Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.1.c7-00108-QCAHMTSWPL_V1.0_V2.0_SILICONZ_UPSTREAM-3
Fixes: 72bfbf19b7 ("wifi: ath12k: add support to reap and process mon dest ring")
Signed-off-by: Kang Yang <kang.yang@oss.qualcomm.com>
Reviewed-by: Baochen Qiang <baochen.qiang@oss.qualcomm.com>
Reviewed-by: Vasanthakumar Thiagarajan <vasanthakumar.thiagarajan@oss.qualcomm.com>
Link: https://patch.msgid.link/20260916060325.854-3-kang.yang@oss.qualcomm.com
Signed-off-by: Jeff Johnson <jeff.johnson@oss.qualcomm.com>