If there is an error during some initialization related to firmware,
the buffers dp->tx_ring[i].tx_status are released.
However this is released again when the device is unbinded (ath12k_pci),
and we get:
WARNING: CPU: 0 PID: 2098 at mm/slub.c:4689 free_large_kmalloc+0x4d/0x80
Call Trace:
free_large_kmalloc
ath12k_dp_free
ath12k_core_deinit
ath12k_pci_remove
...
The issue is always reproducible from a VM because the MSI addressing
initialization is failing.
In order to fix the issue, just set the buffers to NULL after releasing in
order to avoid the double free.
cc: stable@vger.kernel.org
Fixes: d889913205 ("wifi: ath12k: driver for Qualcomm Wi-Fi 7 devices")
Signed-off-by: Jose Ignacio Tornos Martinez <jtornosm@redhat.com>
Link: https://patch.msgid.link/20241017181004.199589-3-jtornosm@redhat.com
Signed-off-by: Jeff Johnson <quic_jjohnson@quicinc.com>
If there is an error during some initialization related to firmware,
the function ath12k_dp_cc_cleanup is called to release resources.
However this is released again when the device is unbinded (ath12k_pci),
and we get:
BUG: kernel NULL pointer dereference, address: 0000000000000020
at RIP: 0010:ath12k_dp_cc_cleanup.part.0+0xb6/0x500 [ath12k]
Call Trace:
ath12k_dp_cc_cleanup
ath12k_dp_free
ath12k_core_deinit
ath12k_pci_remove
...
The issue is always reproducible from a VM because the MSI addressing
initialization is failing.
In order to fix the issue, just set to NULL the released structure in
ath12k_dp_cc_cleanup at the end.
cc: stable@vger.kernel.org
Fixes: d889913205 ("wifi: ath12k: driver for Qualcomm Wi-Fi 7 devices")
Signed-off-by: Jose Ignacio Tornos Martinez <jtornosm@redhat.com>
Link: https://patch.msgid.link/20241017181004.199589-2-jtornosm@redhat.com
Signed-off-by: Jeff Johnson <quic_jjohnson@quicinc.com>
Currently, when ath12k retrieves values from the structure
rx_msdu_end_wcn7850, the information obtained is incorrect. This is because
the definition of the rx_msdu_end_wcn7850 structure in ath12k is incorrect.
In fact, the rx_msdu_end structure used by WCN7850 is the same as the
rx_msdu_end structure of QCN9274.
Commit ed823fd113 ("wifi: ath12k: add msdu_end structure for WCN7850")
introduced this structure. The original issue trying to be fixed with that
commit is that the TID information retrieved from the rx_msdu_end structure
was incorrect, and it was thought that the structure wasn't correct, so a
supposedly correct structure was introduced. However it was subsequently
discovered that the TID information is only guaranteed to be valid in the
rx_msdu_start structure, so that commit added the logic to retrieve the TID
from the rx_msdu_start, but unfortunately kept the rx_msdu_end_wcn7850
structure.
To address this issue, revert the code related to the rx_msdu_end_wcn7850
structure, retaining the TID retrieval logic.
This patch does not affect QCN9274.
Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0.c5-00481-QCAHMTSWPL_V1.0_V2.0_SILICONZ-3
Fixes: ed823fd113 ("wifi: ath12k: add msdu_end structure for WCN7850")
Signed-off-by: Lingbo Kong <quic_lingbok@quicinc.com>
Link: https://patch.msgid.link/20241008093039.11076-1-quic_lingbok@quicinc.com
Signed-off-by: Jeff Johnson <quic_jjohnson@quicinc.com>
Currently ath12k_mac_op_assign_vif_chanctx() uses ahvif->deflink to create and
start vdev based on incoming channel context. With MLO multiple links could be
associated to the ahvif. Use link id from link_conf passed by mac80211 and do
vdev create start for intended link of ahvif.
Add ath12k_mac_assign_link_vif() helper to allocate and initialize link arvif
object based on input link_id. The first link arvif that is being created in
an ahvif will use preallocated ahvif->deflink object and the rest gets
allocated.
Currently link arvif can be removed in two call backs namely
ath12k_mac_op_remove_interface() and ath12k_mac_op_unassign_vif_chanctx():
* ath12k_mac_op_unassign_vif_chanctx() carries link_info so
obtain link_id from link_info and handle removal for that
link
* ath12k_mac_op_remove_interface() is done at interface/MLD
level hence loop through the active link arvifs and remove
all of them
Add ath12k_mac_unassign_link_vif() helper to reset/destroy the link arvifs
allocated for an ahvif.
For scan request from mac80211, check if the any of the link arvifs of the
ahvif is already created on the radio in which scan is requested and use it. If
not use deflink(link 0) for creating scan arvif.
Also ath12k creates vdev during assign_vif_chanctx() mac80211 op callback as it
knows channel associated with given link only in this callback. Whereas
mac80211 updates addition/deletion of links to an ML vif via
.change_vif_links() callback and this is done before channel assignment. Hence
register an dummy ath12k_mac_op_change_vif_links() function to
change_vif_links() and acknowledge mac80211s link updates.
Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.0.1-00029-QCAHKSWPL_SILICONZ-1
Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0.c5-00481-QCAHMTSWPL_V1.0_V2.0_SILICONZ-3
Signed-off-by: Sriram R <quic_srirrama@quicinc.com>
Co-developed-by: Rameshkumar Sundaram <quic_ramess@quicinc.com>
Signed-off-by: Rameshkumar Sundaram <quic_ramess@quicinc.com>
Signed-off-by: Kalle Valo <quic_kvalo@quicinc.com>
Link: https://patch.msgid.link/20241015171416.518022-12-kvalo@kernel.org
Signed-off-by: Jeff Johnson <quic_jjohnson@quicinc.com>
Currently ath12k_mac_op_update_vif_offload() updates for vif encapsulation and
decapsulation offload configurations for intended vif's deflink.
But for an ML vif encapapsulation and decapsulation offloads are an MLD level
configuration so apply the same configuration for all affiliated links of the
ML vif.
Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.0.1-00029-QCAHKSWPL_SILICONZ-1
Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0.c5-00481-QCAHMTSWPL_V1.0_V2.0_SILICONZ-3
Signed-off-by: Sriram R <quic_srirrama@quicinc.com>
Signed-off-by: Rameshkumar Sundaram <quic_ramess@quicinc.com>
Signed-off-by: Kalle Valo <quic_kvalo@quicinc.com>
Link: https://patch.msgid.link/20241015171416.518022-11-kvalo@kernel.org
Signed-off-by: Jeff Johnson <quic_jjohnson@quicinc.com>
Currently ath12k_mac_op_set_key() uses ahvif's deflink to set/cache keys
depending upon the availability of corresponding vdev. But with MLO the
incoming vif could have multiple links affiliated to it, hence use the link id
provided in the key info argument and apply/cache the key to the corresponding
link arvif. When the set key is a pairwise key intended for an ML station then
set the same key on all the affiliated link stations.
Also there could be multiple keys associates to a single link: group keys,
mgmt/beacon protection keys and so on. Current key caching design lacks support
for caching multiple keys for a given link cache. Add support to store a list
of all link keys in the ahvifs link cache as well as update, flush and free the
same whenever required.
Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.0.1-00029-QCAHKSWPL_SILICONZ-1
Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0.c5-00481-QCAHMTSWPL_V1.0_V2.0_SILICONZ-3
Signed-off-by: Rameshkumar Sundaram <quic_ramess@quicinc.com>
Signed-off-by: Kalle Valo <quic_kvalo@quicinc.com>
Link: https://patch.msgid.link/20241015171416.518022-9-kvalo@kernel.org
Signed-off-by: Jeff Johnson <quic_jjohnson@quicinc.com>
Currently bss_info_changed callback (which is registered with
ath12k_mac_op_bss_info_changed()) is used to inform vif (struct ieee80211_vif) and bss
(struct ieee80211_bss_conf) level configuration changes to driver.
With MLO, vif level config as well each link config changes inside vif needs to
be updated and mac80211 uses vif_cfg_changed() and link_info_changed() callback
ops for the same, this is also backward compatible where mac80211 will update
default link conf changes in case VIF is non-MLO.
Rename ath12k_mac_op_bss_info_changed() to ath12k_mac_op_link_info_changed()
and register the same to link_info_changed callback. Register
ath12k_mac_op_vif_cfg_changed() to vif_cfg_changed() callback and handle all
vif level configuration changes there.
Also, currently ath12k_mac_op_bss_info_changed() uses deflink to apply the
config or to cache the config based on the availability of corresponding vdev.
With MLO multiple links can be affiliated to a vif/BSS, so use the link id
provided by mac80211 to fetch the corresponding link to which the bss change
was intended.
For non-MLO link id 0 will be provided by mac80211 and deflink (which is mapped
to ahvif->links[0]) will be used.
Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.0.1-00029-QCAHKSWPL_SILICONZ-1
Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0.c5-00481-QCAHMTSWPL_V1.0_V2.0_SILICONZ-3
Signed-off-by: Sriram R <quic_srirrama@quicinc.com>
Co-developed-by: Rameshkumar Sundaram <quic_ramess@quicinc.com>
Signed-off-by: Rameshkumar Sundaram <quic_ramess@quicinc.com>
Signed-off-by: Kalle Valo <quic_kvalo@quicinc.com>
Link: https://patch.msgid.link/20241015171416.518022-8-kvalo@kernel.org
Signed-off-by: Jeff Johnson <quic_jjohnson@quicinc.com>
Currently ath12k_get_arvif_iter() takes input ahvif's deflink to check if it
matches with given radio (ar) but in case MLO there could be multiple links
affiliated with ahvif, hence iterate through the links of the ahvif and find
the right arvif that belongs to the given radio.
Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.0.1-00029-QCAHKSWPL_SILICONZ-1
Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0.c5-00481-QCAHMTSWPL_V1.0_V2.0_SILICONZ-3
Signed-off-by: Rameshkumar Sundaram <quic_ramess@quicinc.com>
Signed-off-by: Kalle Valo <quic_kvalo@quicinc.com>
Link: https://patch.msgid.link/20241015171416.518022-7-kvalo@kernel.org
Signed-off-by: Jeff Johnson <quic_jjohnson@quicinc.com>
With MLO, multiple links can be affiliated to a vif (struct ieee80211_vif) and
hence ath12k_mac_vif_chan() needs to know the link id to fetch the channel
context among the links. Rename ath12k_mac_vif_chan() to
ath12k_mac_vif_link_chan() and introduce link id argument to fetch the channel
context from the link bss corresponding to the link id.
For non-MLO vif, link 0's (i.e. deflink) channel context will be returned.
Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.0.1-00029-QCAHKSWPL_SILICONZ-1
Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0.c5-00481-QCAHMTSWPL_V1.0_V2.0_SILICONZ-3
Signed-off-by: Rameshkumar Sundaram <quic_ramess@quicinc.com>
Signed-off-by: Kalle Valo <quic_kvalo@quicinc.com>
Link: https://patch.msgid.link/20241015171416.518022-6-kvalo@kernel.org
Signed-off-by: Jeff Johnson <quic_jjohnson@quicinc.com>
Currently vif configuration cache pointers are placed in arvif and caching is
done whenever a link vif configuration is received before driver created vdev
for it (i.e. before channel is assigned), this is possible because current code
only uses default link (ahvif->deflink) which is preallocated.
With MLO changes the ieee80211_vif drv priv is now ahvif and its arvifs (struct
ath12k_link_vif) other than deflink can be allocated dynamically during channel
assignment. Hence maintain link level cache in ahvif and whenever channel is
assigned for link vif and vdev is created, flush the corresponding link vif
cache from ahvif.
Current code uses cache of ATH12K_DEFAULT_LINK_ID (0) which is the cache of
ahvif->deflink.
Co-developed-by: Sriram R <quic_srirrama@quicinc.com>
Signed-off-by: Sriram R <quic_srirrama@quicinc.com>
Signed-off-by: Rameshkumar Sundaram <quic_ramess@quicinc.com>
Signed-off-by: Kalle Valo <quic_kvalo@quicinc.com>
Link: https://patch.msgid.link/20241015171416.518022-5-kvalo@kernel.org
Signed-off-by: Jeff Johnson <quic_jjohnson@quicinc.com>
To prepare the driver for MLO support, split the driver sta data structure to
scale for multiple links. This requires changing the use of arsta to per link
and not per hw which can now comprise of multiple links. Also since most
configurations from mac80211 are done per link, do refactoring of the driver
functions to apply these configurations at link level.
Split struct ath12k_sta, which is the driver private of struct ieee80211_sta,
to store link specific information as struct ath12k_link_sta. For default use
cases struct ath12k_sta will have a preallocated link sta called deflink which
will be used by non ML STAs and the first link sta of ML STA.
With MLO support to be added, remaining link stas will allocated during state
change where new STA is added. These link stas will be freed when STA is
deleted.
Current ath12k_sta(arsta) structure:
+-----------------+ +----------------+
| | | |
| ieee80211_sta | | ieee80211_sta |
| private data | | private data |
| | | |
| ath12k_sta | | ath12k_sta |
| (arsta) | | (arsta) |
|+---------------+| | +-------------+|
|| *arvif (link || | |*arvif (link ||
|| vif of an ar || | | vif of an ar||
|| say 5GHz) || | | say 6GHz) ||
|+---------------+| | +-------------+|
+-----------------+ +----------------+
New struct ath12k_sta (ahsta) containing ath12k_link_sta(s) (arsta) (deflink is
preallocated member which is always the first link if ieee80211_sta is ML STA
and is the only link sta otherwise):
+---------------------------------------+
| ieee80211_sta |
| private data |
| |
| ath12k_sta (ahsta) |
| +-------------------------------------+
| | ath12k_link_sta deflink (arsta) |
| | |
| | *arvif (link vif of ar (5GHz)) |
| +-------------------------------------+
| +-------------------------------------+
| | ath12k_link_sta *link (arsta) |
| | |
| | *arvif (link vif of ar (6GHz)) |
| | |
| +-------------------------------------+
| |
+---------------------------------------+
To refactor existing ath12k_sta to make use of link stas, following changes are
made:
1. Limit struct ieee80211_sta argument mac80211 ops unless otherwise really required.
2. struct ath12k_sta, now called by variable name arsta, stores multiple
arstas (struct ah12k_link_sta) and also has a back pointer to struct
ath12k_sta.
3. Pass struct ath12k_link_sta to mac functions that passed struct
ieee80211_sta argument and fetch struct ath12k_sta (ahsta) and struct
ieee80211_sta(sta) internally. This is done to avoid passing link id in all
the functions and performing validation across these functions. Rather the
validation and sta to arsta conversion can be done only at the mac80211 ops.
4. In this patchset, only ahsta->deflink is used to be on par with the
existing code. When MLO support is added the link id will be used to fetch the
arsta.
5. Change ath12k_sta_to_arsta() to ath12k_vif_to_ahsta() to fetch the
ML level sta. The link sta can be fetched from ahsta->link[], or the
deflink can be accessed via ahsta->deflink. API to access link
sta (arsta) by passing link_id can be introduced with MLO Support.
6. The ieee80211_sta can be accessed from ahsta using ath12k_ahsta_to_sta()
Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.0.1-00029-QCAHKSWPL_SILICONZ-1
Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0.c5-00481-QCAHMTSWPL_V1.0_V2.0_SILICONZ-3
Signed-off-by: Sriram R <quic_srirrama@quicinc.com>
Co-developed-by: Rameshkumar Sundaram <quic_ramess@quicinc.com>
Signed-off-by: Rameshkumar Sundaram <quic_ramess@quicinc.com>
Signed-off-by: Kalle Valo <quic_kvalo@quicinc.com>
Link: https://patch.msgid.link/20241015171416.518022-4-kvalo@kernel.org
Signed-off-by: Jeff Johnson <quic_jjohnson@quicinc.com>
Currently ieee80211_vif/ahvif is passed as argument for all vif related control
path functions that are being called from mac80211 ops. With MLO support being
added multiple link vifs can be part of an ieee80211_vif/ahvif and all these
functions will need link id along with ieee80211_vif/ahvif to be passed to
fetch the corresponding link vif (arvif) to which the control/config applies.
Also all these functions need to validate the locking dependency before
dereferencing and start using the link vifs.
To avoid these redundant link dereferences and validations, limit
ieee80211_vif/ahvif argument to mac80211 ops unless otherwise really required.
Do link vif dereference only in mac80211 ops. Replace vif arg with
ath12k_link_vif and internally fetch ath12k_vif (ahvif) and vif (ieee80211_vif)
if required on other functions.
Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.0.1-00029-QCAHKSWPL_SILICONZ-1
Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0.c5-00481-QCAHMTSWPL_V1.0_V2.0_SILICONZ-3
Signed-off-by: Sriram R <quic_srirrama@quicinc.com>
Co-developed-by: Rameshkumar Sundaram <quic_ramess@quicinc.com>
Signed-off-by: Rameshkumar Sundaram <quic_ramess@quicinc.com>
Signed-off-by: Kalle Valo <quic_kvalo@quicinc.com>
Link: https://patch.msgid.link/20241015171416.518022-3-kvalo@kernel.org
Signed-off-by: Jeff Johnson <quic_jjohnson@quicinc.com>
To prepare the driver for MLO support, split the driver vif data structure to
scale for multiple links. This requires changing the use of arvif to per link
and not per hw which can now comprise of multiple links. Also since most
configurations from mac80211 are done per link, do refactoring of the driver
functions to apply these configurations at link level.
Split ath12k_vif which is the driver private of ieee80211_vif to store link
specific information as ath12k_link_vif. For default use cases the ath12k vif
will have a preallocated link vif called deflink which will be used by non ML
and the first link vif of ML vif.
With MLO support to be added, remaining link vifs will be allocated during
channel assignment where vdev create/start happens. These link vifs will be
freed during interface down.
Current ath12k_vif(arvif) structure
+---------------+ +---------------+ +---------------+
| ieee80211_vif | | ieee80211_vif | | ieee80211_vif |
| private data | | private data | | private data |
| | | | | |
| ath12k_vif | | ath12k_vif | | ath12k_vif |
| (arvif) | | (arvif) | | (arvif) |
| | | | | |
| +----------+ | | +----------+ | | +----------+ |
| |*ar (2GHz)| | | |*ar (5GHz)| | | |*ar (2GHz)| |
| +----------+ | | +----------+ | | +----------+ |
| | | | | |
+---------------+ +---------------+ +---------------+
The new ath12k_vif (ahvif) containing ath12k_link_vif(s) (arvif) (deflink is
preallocated member which is always the first link if ieee80211_vif is MLD and
is the only link otherwise):
+---------------------------------+
| ieee80211_vif |
| private data |
| |
| ath12k_vif(ahvif) |
| |
| +-------------------------------+
| |ath12k_link_vif deflink (arvif)|
| | +---------------+ |
| | | *ar(2GHz) | |
| +-------------------------------+
| +-------------------------------+
| | ath12k_link_vif *link (arvif)|
| | +---------------+ |
| | | *ar(5GHz) | |
| +-------------------------------+
| +-------------------------------+
| | ath12k_link_vif *link (arvif)|
| | +---------------+ |
| | | *ar(6GHz) | |
| +-------------------------------+
| |
+---------------------------------+
To refactor existing ath12k_vif to make use of link vifs, following
changes are made:
1. ath12k_vif now called by variable name ahvif storing multiple
arvifs (struct ah12k_link_vif) and also has a back pointer to ieee80211_vif.
2. In this patch set, only deflink is used to be on par with the
existing code. When MLO support is added the link id will be used to fetch
the arvif.
3. For mac80211 ops which doesn't use specific link_id, the config or info
is common for the vif, hence apply the config to all link vifs.
The links_map in the ahvif, will be used to identify all the link vifs that
are setup.
4. Change ath12k_vif_to_arvif() as ath12k_vif_to_ahvif() to fetch the
hw level vif. The link vif can be fetched from ahvif->link[], or the
deflink can be accessed via ahvif->deflink. API to access link
vif (arvif) by passing link_id can be introduced with MLO Support.
5. The ieee80211_vif can be accessed from ahvif using ath12k_ahvif_to_vif().
The locking continues to use wiphy_lock() for protecting access to most data in
struct ath12k&co, there are no changes in that regard. Though struct
ath12k_vif::link[] is protected with RCU.
Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.0.1-00029-QCAHKSWPL_SILICONZ-1
Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0.c5-00481-QCAHMTSWPL_V1.0_V2.0_SILICONZ-3
Signed-off-by: Sriram R <quic_srirrama@quicinc.com>
Co-developed-by: Rameshkumar Sundaram <quic_ramess@quicinc.com>
Signed-off-by: Rameshkumar Sundaram <quic_ramess@quicinc.com>
Signed-off-by: Kalle Valo <quic_kvalo@quicinc.com>
Link: https://patch.msgid.link/20241015171416.518022-2-kvalo@kernel.org
Signed-off-by: Jeff Johnson <quic_jjohnson@quicinc.com>
Add support to request DMAC reset stats from firmware through HTT stats
type 45. These stats give debug SoC error stats such as reset count, reset
time, engage time and count, disengage time and count and destination
ring mask.
Sample output:
-------------
echo 45 > /sys/kernel/debug/ath12k/pci-0000\:06\:00.0/mac0/htt_stats_type
cat /sys/kernel/debug/ath12k/pci-0000\:06\:00.0/mac0/htt_stats
HTT_DMAC_RESET_STATS_TLV:
reset_count = 1
reset_time_ms = 3013430342
disengage_time_ms = 3013430342
engage_time_ms = 3013430342
disengage_count = 1
engage_count = 1
drain_dest_ring_mask = 0x0
Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.1.1-00214-QCAHKSWPL_SILICONZ-1
Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0-03427-QCAHMTSWPL_V1.0_V2.0_SILICONZ-1.15378.4
Signed-off-by: Rajat Soni <quic_rajson@quicinc.com>
Signed-off-by: Roopni Devanathan <quic_rdevanat@quicinc.com>
Link: https://patch.msgid.link/20241014065259.3968727-1-quic_rdevanat@quicinc.com
Signed-off-by: Jeff Johnson <quic_jjohnson@quicinc.com>
In case of firmware assert snapshot of firmware memory is essential for
debugging. Add firmware coredump collection support for PCI bus.
Collect RDDM and firmware paging dumps from MHI and pack them in TLV
format and also pack various memory shared during QMI phase in separate
TLVs. Add necessary header and share the dumps to user space using dev
coredump framework. Coredump collection is disabled by default and can
be enabled using menuconfig. Dump collected for a radio is 55 MB
approximately.
Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.2.1-00201-QCAHKSWPL_SILICONZ-1
Tested-on: WCN7850 WLAN.HMT.1.0-03427-QCAHMTSWPL_V1.0_V2.0_SILICONZ-1.15378.4
Signed-off-by: Sowmiya Sree Elavalagan <quic_ssreeela@quicinc.com>
Acked-by: Jeff Johnson <quic_jjohnson@quicinc.com>
Link: https://patch.msgid.link/20240717085604.4131642-1-quic_ssreeela@quicinc.com
Signed-off-by: Jeff Johnson <quic_jjohnson@quicinc.com>
When running 'rmmod ath10k', ath10k_sdio_remove() will free sdio
workqueue by destroy_workqueue(). But if CONFIG_INIT_ON_FREE_DEFAULT_ON
is set to yes, kernel panic will happen:
Call trace:
destroy_workqueue+0x1c/0x258
ath10k_sdio_remove+0x84/0x94
sdio_bus_remove+0x50/0x16c
device_release_driver_internal+0x188/0x25c
device_driver_detach+0x20/0x2c
This is because during 'rmmod ath10k', ath10k_sdio_remove() will call
ath10k_core_destroy() before destroy_workqueue(). wiphy_dev_release()
will finally be called in ath10k_core_destroy(). This function will free
struct cfg80211_registered_device *rdev and all its members, including
wiphy, dev and the pointer of sdio workqueue. Then the pointer of sdio
workqueue will be set to NULL due to CONFIG_INIT_ON_FREE_DEFAULT_ON.
After device release, destroy_workqueue() will use NULL pointer then the
kernel panic happen.
Call trace:
ath10k_sdio_remove
->ath10k_core_unregister
……
->ath10k_core_stop
->ath10k_hif_stop
->ath10k_sdio_irq_disable
->ath10k_hif_power_down
->del_timer_sync(&ar_sdio->sleep_timer)
->ath10k_core_destroy
->ath10k_mac_destroy
->ieee80211_free_hw
->wiphy_free
……
->wiphy_dev_release
->destroy_workqueue
Need to call destroy_workqueue() before ath10k_core_destroy(), free
the work queue buffer first and then free pointer of work queue by
ath10k_core_destroy(). This order matches the error path order in
ath10k_sdio_probe().
No work will be queued on sdio workqueue between it is destroyed and
ath10k_core_destroy() is called. Based on the call_stack above, the
reason is:
Only ath10k_sdio_sleep_timer_handler(), ath10k_sdio_hif_tx_sg() and
ath10k_sdio_irq_disable() will queue work on sdio workqueue.
Sleep timer will be deleted before ath10k_core_destroy() in
ath10k_hif_power_down().
ath10k_sdio_irq_disable() only be called in ath10k_hif_stop().
ath10k_core_unregister() will call ath10k_hif_power_down() to stop hif
bus, so ath10k_sdio_hif_tx_sg() won't be called anymore.
Tested-on: QCA6174 hw3.2 SDIO WLAN.RMH.4.4.1-00189
Signed-off-by: Kang Yang <quic_kangyang@quicinc.com>
Tested-by: David Ruth <druth@chromium.org>
Reviewed-by: David Ruth <druth@chromium.org>
Link: https://patch.msgid.link/20241008022246.1010-1-quic_kangyang@quicinc.com
Signed-off-by: Jeff Johnson <quic_jjohnson@quicinc.com>
Now that we have switched to using wiphy_lock() there's no need to have
update_wk cancel call separately, for consistency move it to the rest of code
handling IEEE80211_STA_NONE state.
No functional changes.
Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0.c5-00481-QCAHMTSWPL_V1.0_V2.0_SILICONZ-3
Signed-off-by: Kalle Valo <quic_kvalo@quicinc.com>
Link: https://patch.msgid.link/20241007165932.78081-7-kvalo@kernel.org
Signed-off-by: Jeff Johnson <quic_jjohnson@quicinc.com>
In ath12k_mac_set_key() removing the exit label was a bit more complex so do
it in a separate patch. Remove the else branch and remove now the unnecessary
ret initialisation.
No functional changes.
Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0.c5-00481-QCAHMTSWPL_V1.0_V2.0_SILICONZ-3
Signed-off-by: Kalle Valo <quic_kvalo@quicinc.com>
Link: https://patch.msgid.link/20241007165932.78081-6-kvalo@kernel.org
Signed-off-by: Jeff Johnson <quic_jjohnson@quicinc.com>
Switch from using driver specific ar->conf_mutex to wiphy->mtx. The benefits are:
* one lock less and simplified locking
* possibility to use wiphy_work_queue() without other locks
Most of the mac80211 ops are called within wiphy_lock(), most notable exception
being tx op. This can be checked with lockdep_assert_wiphy() from
net/mac80211/driver-ops.[ch] and I veried that by manually going through all
the ops in ath12k_ops which had lockdep_assert_wiphy().
The conversion was simple:
* All conf_mutex lock() and unlock() calls which
already were called under wiphy_lock() I replaced with
lockdep_assert_wiphy().
* The rest of conf_mutex calls I replaced with wiphy_lock() and wiphy_unlock().
* All lockdep_asset_held(conf_mutex) calls I replaced with
lockdep_assert_wiphy().
One exception was in ath12k_core_post_reconfigure_recovery() where the wiphy
lock needs to be taken before hw_mutex to avoid a lockdep warning.
Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0.c5-00481-QCAHMTSWPL_V1.0_V2.0_SILICONZ-3
Signed-off-by: Kalle Valo <quic_kvalo@quicinc.com>
Link: https://patch.msgid.link/20241007165932.78081-4-kvalo@kernel.org
Signed-off-by: Jeff Johnson <quic_jjohnson@quicinc.com>
For preparation to switch ath12k to use wiphy_lock() we can convert
ath12k_sta_rc_update_wk() to use wiphy_work_queue() for consistency. To avoid
any deadlocks do the struct ath12k_sta::update_wk conversion before switching
to using wiphy_lock() throughout the driver.
Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0.c5-00481-QCAHMTSWPL_V1.0_V2.0_SILICONZ-3
Signed-off-by: Kalle Valo <quic_kvalo@quicinc.com>
Link: https://patch.msgid.link/20241007165932.78081-3-kvalo@kernel.org
Signed-off-by: Jeff Johnson <quic_jjohnson@quicinc.com>
Currently, mem_ce and mem iomem addresses are used to calculate the
CE offset address. mem_ce is initialized with mem address, and for
targets where ce_remap is needed, mem_ce is remapped to a new address
space during AHB probe.
For targets such as WCN6750 in which CE address space is same as WCSS
address space (i.e. "ce_remap" hw_param is set to false), mem_ce and
mem iomem addresses are same. In the initial SRNG setup for such targets,
the CE offset address and hence CE register base addresses are
calculated correctly in ath11k_hal_srng_init() as both mem and mem_ce
are initialized with same iomem address.
Later, after the firmware download, mem is initialized with BAR address
received in qmi_wlanfw_device_info_resp_msg_v01 QMI message, while mem_ce
is not updated.
After initial setup success, during Subsystem Restart (SSR), as part
of reinitialization, ath11k_hal_srng_init() will be called again,
and CE offset address will be calculated incorrectly this time as mem_ce
address was not updated. Due to the incorrect CE offset address,
APPS accesses an invalid CE register address which leads to improper
behavior in firmware after SSR is triggered.
To fix the above issue, update mem_ce to mem iomem address in
ath11k_qmi_request_device_info() for targets which do not support
ce_remap feature.
Signed-off-by: Balaji Pothunoori <quic_bpothuno@quicinc.com>
Fixes: b42b3678c9 ("wifi: ath11k: remap ce register space for IPQ5018")
Link: https://patch.msgid.link/20240927095825.22317-1-quic_bpothuno@quicinc.com
Signed-off-by: Jeff Johnson <quic_jjohnson@quicinc.com>
A previous patch addressed a fortified-memcpy warning on older compilers,
but there is still a warning on gcc-14 in some configurations:
In file included from include/linux/string.h:390,
from drivers/net/wireless/ath/ath12k/wow.c:7:
drivers/net/wireless/ath/ath12k/wow.c: In function 'ath12k_wow_convert_8023_to_80211.isra':
include/linux/fortify-string.h:114:33: error: '__builtin_memcpy' accessing 18446744073709551610 or more bytes at offsets 0 and 0 overlaps 9223372036854775797 bytes at offset -9223372036854775803 [-Werror=restrict]
include/linux/fortify-string.h:679:26: note: in expansion of macro '__fortify_memcpy_chk'
679 | #define memcpy(p, q, s) __fortify_memcpy_chk(p, q, s, \
| ^~~~~~~~~~~~~~~~~~~~
drivers/net/wireless/ath/ath12k/wow.c:199:25: note: in expansion of macro 'memcpy'
199 | memcpy(pat + a3_ofs - pkt_ofs,
| ^~~~~~
Address this the same way as the other two, using size_add().
Fixes: b49991d83b ("wifi: ath12k: fix build vs old compiler")
Fixes: 4a3c212eee ("wifi: ath12k: add basic WoW functionalities")
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
Acked-by: Kalle Valo <kvalo@kernel.org>
Link: https://patch.msgid.link/20241004095420.637091-1-arnd@kernel.org
Signed-off-by: Jeff Johnson <quic_jjohnson@quicinc.com>
The API print_array_to_buf() currently supports printing
arrays with 0 indexing. In some cases, a few arrays need
to be printed with 1-based indexing, i.e., array should be
printed, starting with 1.
Add a new version of print_array_to_buf(), named
print_array_to_buf_index(), which implements the functionality
of print_array_to_index(), but with an extra variable, pointing
to the index starting with which the array should be printed.
Modify print_array_to_buf() to call
print_array_to_buf_index() with 0 as the starting index.
Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.0.1-00029-QCAHKSWPL_SILICONZ-1
Signed-off-by: Roopni Devanathan <quic_rdevanat@quicinc.com>
Link: https://patch.msgid.link/20241004085915.1788951-1-quic_rdevanat@quicinc.com
Signed-off-by: Jeff Johnson <quic_jjohnson@quicinc.com>
During ath12k module removal, in ath12k_core_deinit(),
ath12k_mac_destroy() un-registers ah->hw from mac80211 and frees
the ah->hw as well as all the ar's in it. After this
ath12k_core_soc_destroy()-> ath12k_dp_free()-> ath12k_dp_cc_cleanup()
tries to access one of the freed ar's from pending skb.
This is because during mac destroy, driver failed to flush few
data packets, which were accessed later in ath12k_dp_cc_cleanup()
and freed, but using ar from the packet led to this use-after-free.
BUG: KASAN: use-after-free in ath12k_dp_cc_cleanup.part.0+0x5e2/0xd40 [ath12k]
Write of size 4 at addr ffff888150bd3514 by task modprobe/8926
CPU: 0 UID: 0 PID: 8926 Comm: modprobe Not tainted
6.11.0-rc2-wt-ath+ #1746
Hardware name: Intel(R) Client Systems NUC8i7HVK/NUC8i7HVB, BIOS
HNKBLi70.86A.0067.2021.0528.1339 05/28/2021
Call Trace:
<TASK>
dump_stack_lvl+0x7d/0xe0
print_address_description.constprop.0+0x33/0x3a0
print_report+0xb5/0x260
? kasan_addr_to_slab+0x24/0x80
kasan_report+0xd8/0x110
? ath12k_dp_cc_cleanup.part.0+0x5e2/0xd40 [ath12k]
? ath12k_dp_cc_cleanup.part.0+0x5e2/0xd40 [ath12k]
kasan_check_range+0xf3/0x1a0
__kasan_check_write+0x14/0x20
ath12k_dp_cc_cleanup.part.0+0x5e2/0xd40 [ath12k]
ath12k_dp_free+0x178/0x420 [ath12k]
ath12k_core_stop+0x176/0x200 [ath12k]
ath12k_core_deinit+0x13f/0x210 [ath12k]
ath12k_pci_remove+0xad/0x1c0 [ath12k]
pci_device_remove+0x9b/0x1b0
device_remove+0xbf/0x150
device_release_driver_internal+0x3c3/0x580
? __kasan_check_read+0x11/0x20
driver_detach+0xc4/0x190
bus_remove_driver+0x130/0x2a0
driver_unregister+0x68/0x90
pci_unregister_driver+0x24/0x240
? find_module_all+0x13e/0x1e0
ath12k_pci_exit+0x10/0x20 [ath12k]
__do_sys_delete_module+0x32c/0x580
? module_flags+0x2f0/0x2f0
? kmem_cache_free+0xf0/0x410
? __fput+0x56f/0xab0
? __fput+0x56f/0xab0
? debug_smp_processor_id+0x17/0x20
__x64_sys_delete_module+0x4f/0x70
x64_sys_call+0x522/0x9f0
do_syscall_64+0x64/0x130
entry_SYSCALL_64_after_hwframe+0x4b/0x53
RIP: 0033:0x7f8182c6ac8b
Commit 24de1b7b23 ("wifi: ath12k: fix flush failure in recovery
scenarios") added the change to decrement the pending packets count
in case of recovery which make sense as ah->hw as well all
ar's in it are intact during recovery, but during core deinit there
is no use in decrementing packets count or waking up the empty waitq
as the module is going to be removed also ar's from pending skb's
can't be used and the packets should just be released back.
To fix this, avoid accessing ar from skb->cb when driver is being
unregistered.
Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.1.1-00214-QCAHKSWPL_SILICONZ-1
Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0.c5-00481-QCAHMTSWPL_V1.0_V2.0_SILICONZ-3
Fixes: 24de1b7b23 ("wifi: ath12k: fix flush failure in recovery scenarios")
Signed-off-by: Rameshkumar Sundaram <quic_ramess@quicinc.com>
Acked-by: Jeff Johnson <quic_jjohnson@quicinc.com>
Link: https://patch.msgid.link/20241001092652.3134334-1-quic_ramess@quicinc.com
Signed-off-by: Jeff Johnson <quic_jjohnson@quicinc.com>
During peer create, dp setup for the peer is done where Rx TID is
updated for all the TIDs. Peer object for self peer will not go through
dp setup.
When core halts, dp cleanup is done for all the peers. While cleanup,
rx_tid::ab is accessed which causes below stack trace for self peer.
WARNING: CPU: 6 PID: 12297 at drivers/net/wireless/ath/ath12k/dp_rx.c:851
Call Trace:
__warn+0x7b/0x1a0
ath12k_dp_rx_frags_cleanup+0xd2/0xe0 [ath12k]
report_bug+0x10b/0x200
handle_bug+0x3f/0x70
exc_invalid_op+0x13/0x60
asm_exc_invalid_op+0x16/0x20
ath12k_dp_rx_frags_cleanup+0xd2/0xe0 [ath12k]
ath12k_dp_rx_frags_cleanup+0xca/0xe0 [ath12k]
ath12k_dp_rx_peer_tid_cleanup+0x39/0xa0 [ath12k]
ath12k_mac_peer_cleanup_all+0x61/0x100 [ath12k]
ath12k_core_halt+0x3b/0x100 [ath12k]
ath12k_core_reset+0x494/0x4c0 [ath12k]
sta object in peer will be updated when remote peer is created. Hence
use peer::sta to detect the self peer and skip the cleanup.
Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.0.1-00029-QCAHKSWPL_SILICONZ-1
Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0.c5-00481-QCAHMTSWPL_V1.0_V2.0_SILICONZ-3
Fixes: d889913205 ("wifi: ath12k: driver for Qualcomm Wi-Fi 7 devices")
Signed-off-by: Ramya Gnanasekar <quic_rgnanase@quicinc.com>
Acked-by: Jeff Johnson <quic_jjohnson@quicinc.com>
Signed-off-by: Kalle Valo <quic_kvalo@quicinc.com>
Link: https://patch.msgid.link/20240905042851.2282306-1-quic_rgnanase@quicinc.com
Those two fields are used to store the per SPT page of tx/rx descriptors send to
the firmware for cookie conversion. Right now they are in struct ath12k_spt_info
which means they are duplicated PPT page times while we only need one instance
of them. This works for now as we always use the first spt_info as a global
storage for all PPT pages.
Let's move them into struct ath12k_dp where they belong, alongside of the
spt_info array they are tied to, to avoid waisting a good bit of memory.
Tested-on: QCN9274 hw2.0 PCI CI_WLAN.WBE.1.3-03283.1-QCAHKSWPL_SILICONZ-2
Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0.c5-00481-QCAHMTSWPL_V1.0_V2.0_SILICONZ-3
Signed-off-by: Nicolas Escande <nico.escande@gmail.com>
Reviewed-by: Remi Pommarel <repk@triplefau.lt>
Acked-by: Jeff Johnson <quic_jjohnson@quicinc.com>
Signed-off-by: Kalle Valo <quic_kvalo@quicinc.com>
Link: https://patch.msgid.link/20240830081942.3623380-1-nico.escande@gmail.com
On SC7280 platforms which are running with TrustZone, it is not
necessary to manually map the memory regions used by the wifi hardware.
However, ath11k will currently fail to load unless both memory regions
are specified.
This breaks wifi on the rb3gen2 which only specifies the firmware memory
region and does not use the CE region.
Adjust the order of operations in ath11k_ahb_fw_resources_init() to
check for the wifi-firmware subnode before attempting to parse the
memory regions.
Signed-off-by: Caleb Connolly <caleb.connolly@linaro.org>
Acked-by: Jeff Johnson <quic_jjohnson@quicinc.com>
Reviewed-by: Raj Kumar Bhagat <quic_rajkbhag@quicinc.com>
Signed-off-by: Kalle Valo <quic_kvalo@quicinc.com>
Link: https://patch.msgid.link/20240904095815.1572186-2-caleb.connolly@linaro.org
Fix the following W=1 kernel build warning:
drivers/net/wireless/ath/ath11k/wow.c: In function ‘ath11k_vif_wow_set_wakeups’:
drivers/net/wireless/ath/ath11k/wow.c:461:1: warning: the frame size of 1352 bytes is larger than 1024 bytes [-Wframe-larger-than=]
Remove the nonessential variable 'struct cfg80211_pkt_pattern
old_pattern' by relocating bitmask to bytemask conversion into
ath11k_wow_convert_8023_to_80211().
Tested-on: WCN6855 hw2.1 PCI WLAN.HSP.1.1-04358-QCAHSPSWPL_V1_V2_SILICONZ_LITE-1
Signed-off-by: Miaoqing Pan <quic_miaoqing@quicinc.com>
Acked-by: Jeff Johnson <quic_jjohnson@quicinc.com>
Signed-off-by: Kalle Valo <quic_kvalo@quicinc.com>
Link: https://patch.msgid.link/20240829075253.657667-1-quic_miaoqing@quicinc.com
WCN6750 firmware sends the log messages via WMI_DIAG_EVENTID only
when the host driver enables the same via QMI_WLANFW_WLAN_INI_REQ_V01
QMI message. This is further controlled via fw_wmi_diag_event.
Hence set this flag to true for the firmware to send the logs.
These logs are further collected in the user space through
the trace infrastructure.
Tested-on: WCN6750 hw1.0 AHB WLAN.MSL.2.0.c2-00233-QCAMSLSWPLZ-1
Signed-off-by: Balaji Pothunoori <quic_bpothuno@quicinc.com>
Acked-by: Jeff Johnson <quic_jjohnson@quicinc.com>
Signed-off-by: Kalle Valo <quic_kvalo@quicinc.com>
Link: https://patch.msgid.link/20240828103043.2413-1-quic_bpothuno@quicinc.com
Currently struct ath11k_hal::srng_config pointer is not assigned
to NULL after freeing the memory in ath11k_hal_srng_deinit().
This could lead to double free issue in a scenario where
ath11k_hal_srng_deinit() is invoked back to back.
In the current code, although the chances are very low, the above
said scenario could happen when hardware recovery has failed and
then there is another FW assert where ath11k_hal_srng_deinit() is
invoked once again as part of recovery.
Fix this by assigning the struct ath11k_hal::srng_config pointer
to NULL after freeing the memory.
Tested-on: WCN6750 hw1.0 AHB WLAN.MSL.1.0.1-00887-QCAMSLSWPLZ-1
Tested-on: WCN6855 hw2.0 PCI WLAN.HSP.1.1-03125-QCAHSPSWPL_V1_V2_SILICONZ_LITE-3.6510.16
Tested-on: IPQ5018 hw1.0 AHB WLAN.HK.2.6.0.1-00861-QCAHKSWPL_SILICONZ-1
Tested-on: QCN9074 hw1.0 PCI WLAN.HK.2.7.0.1-01744-QCAHKSWPL_SILICONZ-1
Signed-off-by: Manikanta Pubbisetty <quic_mpubbise@quicinc.com>
Signed-off-by: Balaji Pothunoori <quic_bpothuno@quicinc.com>
Acked-by: Jeff Johnson <quic_jjohnson@quicinc.com>
Signed-off-by: Kalle Valo <quic_kvalo@quicinc.com>
Link: https://patch.msgid.link/20240826053326.8878-1-quic_bpothuno@quicinc.com