Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
099fad5
wifi: ath12k: Remove struct wmi_bcn_send_from_host_cmd
jeff-t-johnson Oct 10, 2025
cea6eea
wifi: ath12k: Fix MSDU buffer types handling in RX error path
Sep 30, 2025
e318476
wifi: ath12k: track dropped MSDU buffer type packets in REO exception…
Sep 30, 2025
cb405c4
wifi: ath12k: Defer vdev bring-up until CSA finalize to avoid stale b…
Sep 24, 2025
f184b39
wifi: ath12k: Fix NSS value update in ext_rx_stats
Oct 7, 2025
2adc104
wifi: ath12k: fix VHT MCS assignment
Oct 9, 2025
eb87968
wifi: ath12k: fix TX and RX MCS rate configurations in HE mode
Oct 9, 2025
1f29887
wifi: ath12k: Add MODULE_FIRMWARE() entries
tiwai Oct 3, 2025
ee266b7
wifi: ath12k: add support for BSS color change
WeiZhang-stone Oct 17, 2025
c9540f2
wifi: ath12k: restore register window after global reset
Oct 17, 2025
ccb5a59
wifi: ath12k: Assert base_lock is held before allocating REO update e…
Oct 21, 2025
69d7527
wifi: ath12k: fix potential memory leak in ath12k_wow_arp_ns_offload()
Oct 28, 2025
dec6814
wifi: ath12k: fix reusing m3 memory
Oct 29, 2025
1cf04f5
wifi: ath12k: fix error handling in creating hardware group
Oct 30, 2025
aa9086d
wifi: ath12k: generalize GI and LTF fixed rate functions
Oct 24, 2025
c354645
wifi: ath12k: add EHT rate handling to existing set rate functions
Oct 24, 2025
af28c61
wifi: ath12k: Add EHT MCS/NSS rates to Peer Assoc
Oct 24, 2025
ba3ec9f
wifi: ath12k: Add EHT fixed GI/LTF
Oct 24, 2025
d9927dc
wifi: ath12k: add EHT rates to ath12k_mac_op_set_bitrate_mask()
Oct 24, 2025
9754a06
wifi: ath12k: Set EHT fixed rates for associated STAs
Oct 24, 2025
4849eac
wifi: ath12k: enforce vdev limit in ath12k_mac_vdev_create()
Oct 26, 2025
f36b302
wifi: ath12k: unassign arvif on scan vdev create failure
Oct 26, 2025
a6836b7
wifi: ath12k: Make firmware stats reset caller-driven
Oct 31, 2025
c87579b
wifi: ath12k: Fix timeout error during beacon stats retrieval
Oct 31, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 17 additions & 7 deletions drivers/net/wireless/ath/ath12k/core.c
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
// SPDX-License-Identifier: BSD-3-Clause-Clear
/*
* Copyright (c) 2018-2021 The Linux Foundation. All rights reserved.
* Copyright (c) 2021-2025 Qualcomm Innovation Center, Inc. All rights reserved.
* Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
*/

Expand Down Expand Up @@ -1250,7 +1249,6 @@ void ath12k_fw_stats_reset(struct ath12k *ar)
spin_lock_bh(&ar->data_lock);
ath12k_fw_stats_free(&ar->fw_stats);
ar->fw_stats.num_vdev_recvd = 0;
ar->fw_stats.num_bcn_recvd = 0;
spin_unlock_bh(&ar->data_lock);
}

Expand Down Expand Up @@ -2106,14 +2104,27 @@ static int ath12k_core_hw_group_create(struct ath12k_hw_group *ag)
ret = ath12k_core_soc_create(ab);
if (ret) {
mutex_unlock(&ab->core_lock);
ath12k_err(ab, "failed to create soc core: %d\n", ret);
return ret;
ath12k_err(ab, "failed to create soc %d core: %d\n", i, ret);
goto destroy;
}

mutex_unlock(&ab->core_lock);
}

return 0;

destroy:
for (i--; i >= 0; i--) {
ab = ag->ab[i];
if (!ab)
continue;

mutex_lock(&ab->core_lock);
ath12k_core_soc_destroy(ab);
mutex_unlock(&ab->core_lock);
}

return ret;
}

void ath12k_core_hw_group_set_mlo_capable(struct ath12k_hw_group *ag)
Expand Down Expand Up @@ -2188,16 +2199,15 @@ int ath12k_core_init(struct ath12k_base *ab)
if (ret) {
mutex_unlock(&ag->mutex);
ath12k_warn(ab, "unable to create hw group\n");
goto err_destroy_hw_group;
goto err_unassign_hw_group;
}
}

mutex_unlock(&ag->mutex);

return 0;

err_destroy_hw_group:
ath12k_core_hw_group_destroy(ab->ag);
err_unassign_hw_group:
ath12k_core_hw_group_unassign(ab);
err_unregister_notifier:
ath12k_core_panic_notifier_unregister(ab);
Expand Down
4 changes: 3 additions & 1 deletion drivers/net/wireless/ath/ath12k/core.h
Original file line number Diff line number Diff line change
Expand Up @@ -355,6 +355,8 @@ struct ath12k_link_vif {
struct wmi_vdev_install_key_arg group_key;
bool pairwise_key_done;
u16 num_stations;
bool is_csa_in_progress;
struct wiphy_work bcn_tx_work;
};

struct ath12k_vif {
Expand Down Expand Up @@ -645,7 +647,6 @@ struct ath12k_fw_stats {
struct list_head vdevs;
struct list_head bcn;
u32 num_vdev_recvd;
u32 num_bcn_recvd;
};

struct ath12k_dbg_htt_stats {
Expand Down Expand Up @@ -964,6 +965,7 @@ struct ath12k_device_dp_stats {
u32 tx_wbm_rel_source[HAL_WBM_REL_SRC_MODULE_MAX];
u32 tx_enqueued[DP_TCL_NUM_RING_MAX];
u32 tx_completed[DP_TCL_NUM_RING_MAX];
u32 reo_excep_msdu_buf_type;
};

struct ath12k_reg_freq {
Expand Down
14 changes: 7 additions & 7 deletions drivers/net/wireless/ath/ath12k/debugfs.c
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// SPDX-License-Identifier: BSD-3-Clause-Clear
/*
* Copyright (c) 2018-2021 The Linux Foundation. All rights reserved.
* Copyright (c) 2021-2025 Qualcomm Innovation Center, Inc. All rights reserved.
* Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
*/

#include "core.h"
Expand Down Expand Up @@ -1178,6 +1178,9 @@ static ssize_t ath12k_debugfs_dump_device_dp_stats(struct file *file,
len += scnprintf(buf + len, size - len, "\n");
}

len += scnprintf(buf + len, size - len, "\nREO excep MSDU buf type:%u\n",
device_stats->reo_excep_msdu_buf_type);

len += scnprintf(buf + len, size - len, "\nRx WBM REL SRC Errors:\n");

for (i = 0; i < HAL_WBM_REL_SRC_MODULE_MAX; i++) {
Expand Down Expand Up @@ -1283,6 +1286,7 @@ static int ath12k_open_vdev_stats(struct inode *inode, struct file *file)

ath12k_wmi_fw_stats_dump(ar, &ar->fw_stats, param.stats_id,
buf);
ath12k_fw_stats_reset(ar);

file->private_data = no_free_ptr(buf);

Expand Down Expand Up @@ -1349,12 +1353,7 @@ static int ath12k_open_bcn_stats(struct inode *inode, struct file *file)

ath12k_wmi_fw_stats_dump(ar, &ar->fw_stats, param.stats_id,
buf);
/* since beacon stats request is looped for all active VDEVs, saved fw
* stats is not freed for each request until done for all active VDEVs
*/
spin_lock_bh(&ar->data_lock);
ath12k_fw_stats_bcn_free(&ar->fw_stats.bcn);
spin_unlock_bh(&ar->data_lock);
ath12k_fw_stats_reset(ar);

file->private_data = no_free_ptr(buf);

Expand Down Expand Up @@ -1415,6 +1414,7 @@ static int ath12k_open_pdev_stats(struct inode *inode, struct file *file)

ath12k_wmi_fw_stats_dump(ar, &ar->fw_stats, param.stats_id,
buf);
ath12k_fw_stats_reset(ar);

file->private_data = no_free_ptr(buf);

Expand Down
19 changes: 12 additions & 7 deletions drivers/net/wireless/ath/ath12k/dp_mon.c
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// SPDX-License-Identifier: BSD-3-Clause-Clear
/*
* Copyright (c) 2019-2021 The Linux Foundation. All rights reserved.
* Copyright (c) 2021-2025 Qualcomm Innovation Center, Inc. All rights reserved.
* Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
*/

#include "dp_mon.h"
Expand Down Expand Up @@ -105,7 +105,7 @@ static void ath12k_dp_mon_parse_vht_sig_a(const struct hal_rx_vht_sig_a_info *vh
if (ppdu_info->is_stbc && nsts > 0)
nsts = ((nsts + 1) >> 1) - 1;

ppdu_info->nss = u32_get_bits(nsts, VHT_SIG_SU_NSS_MASK);
ppdu_info->nss = u32_get_bits(nsts, VHT_SIG_SU_NSS_MASK) + 1;
ppdu_info->bw = u32_get_bits(info0, HAL_RX_VHT_SIG_A_INFO_INFO0_BW);
ppdu_info->beamformed = u32_get_bits(info1,
HAL_RX_VHT_SIG_A_INFO_INFO1_BEAMFORMED);
Expand All @@ -129,7 +129,7 @@ static void ath12k_dp_mon_parse_ht_sig(const struct hal_rx_ht_sig_info *ht_sig,
ppdu_info->is_stbc = u32_get_bits(info1, HAL_RX_HT_SIG_INFO_INFO1_STBC);
ppdu_info->ldpc = u32_get_bits(info1, HAL_RX_HT_SIG_INFO_INFO1_FEC_CODING);
ppdu_info->gi = u32_get_bits(info1, HAL_RX_HT_SIG_INFO_INFO1_GI);
ppdu_info->nss = (ppdu_info->mcs >> 3);
ppdu_info->nss = (ppdu_info->mcs >> 3) + 1;
}

static void ath12k_dp_mon_parse_l_sig_b(const struct hal_rx_lsig_b_info *lsigb,
Expand Down Expand Up @@ -233,7 +233,9 @@ ath12k_dp_mon_parse_he_sig_b2_ofdma(const struct hal_rx_he_sig_b2_ofdma_info *of
value = value << HE_STA_ID_SHIFT;
ppdu_info->he_data4 |= value;

ppdu_info->nss = u32_get_bits(info0, HAL_RX_HE_SIG_B2_OFDMA_INFO_INFO0_STA_NSTS);
ppdu_info->nss =
u32_get_bits(info0,
HAL_RX_HE_SIG_B2_OFDMA_INFO_INFO0_STA_NSTS) + 1;
ppdu_info->beamformed = u32_get_bits(info0,
HAL_RX_HE_SIG_B2_OFDMA_INFO_INFO0_STA_TXBF);
}
Expand Down Expand Up @@ -261,7 +263,9 @@ ath12k_dp_mon_parse_he_sig_b2_mu(const struct hal_rx_he_sig_b2_mu_info *he_sig_b
value = value << HE_STA_ID_SHIFT;
ppdu_info->he_data4 |= value;

ppdu_info->nss = u32_get_bits(info0, HAL_RX_HE_SIG_B2_MU_INFO_INFO0_STA_NSTS);
ppdu_info->nss =
u32_get_bits(info0,
HAL_RX_HE_SIG_B2_MU_INFO_INFO0_STA_NSTS) + 1;
}

static void
Expand Down Expand Up @@ -553,7 +557,8 @@ static void ath12k_dp_mon_parse_he_sig_su(const struct hal_rx_he_sig_a_su_info *
ppdu_info->is_stbc = u32_get_bits(info1, HAL_RX_HE_SIG_A_SU_INFO_INFO1_STBC);
ppdu_info->beamformed = u32_get_bits(info1, HAL_RX_HE_SIG_A_SU_INFO_INFO1_TXBF);
dcm = u32_get_bits(info0, HAL_RX_HE_SIG_A_SU_INFO_INFO0_DCM);
ppdu_info->nss = u32_get_bits(info0, HAL_RX_HE_SIG_A_SU_INFO_INFO0_NSTS);
ppdu_info->nss = u32_get_bits(info0,
HAL_RX_HE_SIG_A_SU_INFO_INFO0_NSTS) + 1;
ppdu_info->dcm = dcm;
}

Expand Down Expand Up @@ -2179,7 +2184,7 @@ static void ath12k_dp_mon_update_radiotap(struct ath12k *ar,
spin_unlock_bh(&ar->data_lock);

rxs->flag |= RX_FLAG_MACTIME_START;
rxs->nss = ppduinfo->nss + 1;
rxs->nss = ppduinfo->nss;
if (test_bit(WMI_TLV_SERVICE_HW_DB2DBM_CONVERSION_SUPPORT,
ar->ab->wmi_ab.svc_map))
rxs->signal = ppduinfo->rssi_comb;
Expand Down
74 changes: 68 additions & 6 deletions drivers/net/wireless/ath/ath12k/dp_rx.c
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// SPDX-License-Identifier: BSD-3-Clause-Clear
/*
* Copyright (c) 2018-2021 The Linux Foundation. All rights reserved.
* Copyright (c) 2021-2025 Qualcomm Innovation Center, Inc. All rights reserved.
* Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
*/

#include <linux/ieee80211.h>
Expand Down Expand Up @@ -1089,6 +1089,8 @@ static int ath12k_dp_prepare_reo_update_elem(struct ath12k_dp *dp,
{
struct dp_reo_update_rx_queue_elem *elem;

lockdep_assert_held(&dp->ab->base_lock);

elem = kzalloc(sizeof(*elem), GFP_ATOMIC);
if (!elem)
return -ENOMEM;
Expand Down Expand Up @@ -3781,6 +3783,50 @@ ath12k_dp_process_rx_err_buf(struct ath12k *ar, struct hal_reo_dest_ring *desc,
return 0;
}

static int ath12k_dp_h_msdu_buffer_type(struct ath12k_base *ab,
struct list_head *list,
struct hal_reo_dest_ring *desc)
{
struct ath12k_rx_desc_info *desc_info;
struct ath12k_skb_rxcb *rxcb;
struct sk_buff *msdu;
u64 desc_va;

ab->device_stats.reo_excep_msdu_buf_type++;

desc_va = (u64)le32_to_cpu(desc->buf_va_hi) << 32 |
le32_to_cpu(desc->buf_va_lo);
desc_info = (struct ath12k_rx_desc_info *)(uintptr_t)desc_va;
if (!desc_info) {
u32 cookie;

cookie = le32_get_bits(desc->buf_addr_info.info1,
BUFFER_ADDR_INFO1_SW_COOKIE);
desc_info = ath12k_dp_get_rx_desc(ab, cookie);
if (!desc_info) {
ath12k_warn(ab, "Invalid cookie in manual descriptor retrieval: 0x%x\n",
cookie);
return -EINVAL;
}
}

if (desc_info->magic != ATH12K_DP_RX_DESC_MAGIC) {
ath12k_warn(ab, "rx exception, magic check failed with value: %u\n",
desc_info->magic);
return -EINVAL;
}

msdu = desc_info->skb;
desc_info->skb = NULL;
list_add_tail(&desc_info->list, list);
rxcb = ATH12K_SKB_RXCB(msdu);
dma_unmap_single(ab->dev, rxcb->paddr, msdu->len + skb_tailroom(msdu),
DMA_FROM_DEVICE);
dev_kfree_skb_any(msdu);

return 0;
}

int ath12k_dp_rx_process_err(struct ath12k_base *ab, struct napi_struct *napi,
int budget)
{
Expand Down Expand Up @@ -3825,6 +3871,26 @@ int ath12k_dp_rx_process_err(struct ath12k_base *ab, struct napi_struct *napi,
drop = false;
ab->device_stats.err_ring_pkts++;

hw_link_id = le32_get_bits(reo_desc->info0,
HAL_REO_DEST_RING_INFO0_SRC_LINK_ID);
device_id = hw_links[hw_link_id].device_id;
partner_ab = ath12k_ag_to_ab(ag, device_id);

/* Below case is added to handle data packet from un-associated clients.
* As it is expected that AST lookup will fail for
* un-associated station's data packets.
*/
if (le32_get_bits(reo_desc->info0, HAL_REO_DEST_RING_INFO0_BUFFER_TYPE) ==
HAL_REO_DEST_RING_BUFFER_TYPE_MSDU) {
if (!ath12k_dp_h_msdu_buffer_type(partner_ab,
&rx_desc_used_list[device_id],
reo_desc)) {
num_buffs_reaped[device_id]++;
tot_n_bufs_reaped++;
}
goto next_desc;
}

ret = ath12k_hal_desc_reo_parse_err(ab, reo_desc, &paddr,
&desc_bank);
if (ret) {
Expand All @@ -3833,11 +3899,6 @@ int ath12k_dp_rx_process_err(struct ath12k_base *ab, struct napi_struct *napi,
continue;
}

hw_link_id = le32_get_bits(reo_desc->info0,
HAL_REO_DEST_RING_INFO0_SRC_LINK_ID);
device_id = hw_links[hw_link_id].device_id;
partner_ab = ath12k_ag_to_ab(ag, device_id);

pdev_id = ath12k_hw_mac_id_to_pdev_id(partner_ab->hw_params,
hw_links[hw_link_id].pdev_idx);
ar = partner_ab->pdevs[pdev_id].ar;
Expand Down Expand Up @@ -3886,6 +3947,7 @@ int ath12k_dp_rx_process_err(struct ath12k_base *ab, struct napi_struct *napi,
}
}

next_desc:
if (tot_n_bufs_reaped >= quota) {
tot_n_bufs_reaped = quota;
goto exit;
Expand Down
10 changes: 2 additions & 8 deletions drivers/net/wireless/ath/ath12k/hal_rx.c
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// SPDX-License-Identifier: BSD-3-Clause-Clear
/*
* Copyright (c) 2018-2021 The Linux Foundation. All rights reserved.
* Copyright (c) 2021-2025 Qualcomm Innovation Center, Inc. All rights reserved.
* Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
*/

#include "debug.h"
Expand Down Expand Up @@ -323,7 +323,7 @@ int ath12k_hal_desc_reo_parse_err(struct ath12k_base *ab,
{
enum hal_reo_dest_ring_push_reason push_reason;
enum hal_reo_dest_ring_error_code err_code;
u32 cookie, val;
u32 cookie;

push_reason = le32_get_bits(desc->info0,
HAL_REO_DEST_RING_INFO0_PUSH_REASON);
Expand All @@ -338,12 +338,6 @@ int ath12k_hal_desc_reo_parse_err(struct ath12k_base *ab,
return -EINVAL;
}

val = le32_get_bits(desc->info0, HAL_REO_DEST_RING_INFO0_BUFFER_TYPE);
if (val != HAL_REO_DEST_RING_BUFFER_TYPE_LINK_DESC) {
ath12k_warn(ab, "expected buffer type link_desc");
return -EINVAL;
}

ath12k_hal_rx_reo_ent_paddr_get(ab, &desc->buf_addr_info, paddr, &cookie);
*desc_bank = u32_get_bits(cookie, DP_LINK_DESC_BANK_MASK);

Expand Down
Loading