ath.git patches for v6.20/v7.0 (#3)

A set of small features and cleanups for the next merge window.
 -----BEGIN PGP SIGNATURE-----
 
 iHUEABYKAB0WIQQ/mtSHzPUi16IfDEksFbugiYzLewUCaYC1fQAKCRAsFbugiYzL
 ewYLAQDbVliEG5O2mVij/CIwUwfkvuYim9xolxec+TzfwShPsAD+NM4qAuHTFKOp
 bK0hF4v+Bxy03SE/5QuhPZsC1RsQTgE=
 =1LW5
 -----END PGP SIGNATURE-----

Merge tag 'ath-next-20260202' of git://git.kernel.org/pub/scm/linux/kernel/git/ath/ath

Jeff Johnson says:
==================
ath.git patches for v6.20/v7.0 (#3)

A set of small features and cleanups for the next merge window.
==================

Signed-off-by: Johannes Berg <johannes.berg@intel.com>
This commit is contained in:
Johannes Berg 2026-02-02 17:55:04 +01:00
commit 19dd0cc36a
13 changed files with 730 additions and 12 deletions

View File

@ -37,6 +37,7 @@ properties:
firmware-name:
maxItems: 1
deprecated: true
description:
If present, a board or platform specific string used to lookup
usecase-specific firmware files for the device.

View File

@ -2487,7 +2487,11 @@ void ath10k_sdio_fw_crashed_dump(struct ath10k *ar)
if (fast_dump)
ath10k_bmi_start(ar);
mutex_lock(&ar->dump_mutex);
spin_lock_bh(&ar->data_lock);
ar->stats.fw_crash_counter++;
spin_unlock_bh(&ar->data_lock);
ath10k_sdio_disable_intrs(ar);
@ -2505,6 +2509,8 @@ void ath10k_sdio_fw_crashed_dump(struct ath10k *ar)
ath10k_sdio_enable_intrs(ar);
mutex_unlock(&ar->dump_mutex);
ath10k_core_start_recovery(ar);
}

View File

@ -1,6 +1,7 @@
// SPDX-License-Identifier: ISC
/*
* Copyright (c) 2018 The Linux Foundation. All rights reserved.
* Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
*/
#include <linux/bits.h>
@ -11,6 +12,7 @@
#include <linux/of_device.h>
#include <linux/platform_device.h>
#include <linux/property.h>
#include <linux/pwrseq/consumer.h>
#include <linux/regulator/consumer.h>
#include <linux/remoteproc/qcom_rproc.h>
#include <linux/of_reserved_mem.h>
@ -1023,10 +1025,14 @@ static int ath10k_hw_power_on(struct ath10k *ar)
ath10k_dbg(ar, ATH10K_DBG_SNOC, "soc power on\n");
ret = regulator_bulk_enable(ar_snoc->num_vregs, ar_snoc->vregs);
ret = pwrseq_power_on(ar_snoc->pwrseq);
if (ret)
return ret;
ret = regulator_bulk_enable(ar_snoc->num_vregs, ar_snoc->vregs);
if (ret)
goto pwrseq_off;
ret = clk_bulk_prepare_enable(ar_snoc->num_clks, ar_snoc->clks);
if (ret)
goto vreg_off;
@ -1035,18 +1041,28 @@ static int ath10k_hw_power_on(struct ath10k *ar)
vreg_off:
regulator_bulk_disable(ar_snoc->num_vregs, ar_snoc->vregs);
pwrseq_off:
pwrseq_power_off(ar_snoc->pwrseq);
return ret;
}
static int ath10k_hw_power_off(struct ath10k *ar)
{
struct ath10k_snoc *ar_snoc = ath10k_snoc_priv(ar);
int ret_seq = 0;
int ret_vreg;
ath10k_dbg(ar, ATH10K_DBG_SNOC, "soc power off\n");
clk_bulk_disable_unprepare(ar_snoc->num_clks, ar_snoc->clks);
return regulator_bulk_disable(ar_snoc->num_vregs, ar_snoc->vregs);
ret_vreg = regulator_bulk_disable(ar_snoc->num_vregs, ar_snoc->vregs);
if (ar_snoc->pwrseq)
ret_seq = pwrseq_power_off(ar_snoc->pwrseq);
return ret_vreg ? : ret_seq;
}
static void ath10k_snoc_wlan_disable(struct ath10k *ar)
@ -1762,7 +1778,38 @@ static int ath10k_snoc_probe(struct platform_device *pdev)
goto err_release_resource;
}
ar_snoc->num_vregs = ARRAY_SIZE(ath10k_regulators);
/*
* devm_pwrseq_get() can return -EPROBE_DEFER in two cases:
* - it is not supposed to be used
* - it is supposed to be used, but the driver hasn't probed yet.
*
* There is no simple way to distinguish between these two cases, but:
* - if it is not supposed to be used, then regulator_bulk_get() will
* return all regulators as expected, continuing the probe
* - if it is supposed to be used, but wasn't probed yet, we will get
* -EPROBE_DEFER from regulator_bulk_get() too.
*
* For backwards compatibility with DTs specifying regulators directly
* rather than using the PMU device, ignore the defer error from
* pwrseq.
*/
ar_snoc->pwrseq = devm_pwrseq_get(&pdev->dev, "wlan");
if (IS_ERR(ar_snoc->pwrseq)) {
ret = PTR_ERR(ar_snoc->pwrseq);
ar_snoc->pwrseq = NULL;
if (ret != -EPROBE_DEFER)
goto err_free_irq;
ar_snoc->num_vregs = ARRAY_SIZE(ath10k_regulators);
} else {
/*
* The first regulator (vdd-0.8-cx-mx) is used to power on part
* of the SoC rather than the PMU on WCN399x, the rest are
* handled via pwrseq.
*/
ar_snoc->num_vregs = 1;
}
ar_snoc->vregs = devm_kcalloc(&pdev->dev, ar_snoc->num_vregs,
sizeof(*ar_snoc->vregs), GFP_KERNEL);
if (!ar_snoc->vregs) {

View File

@ -1,6 +1,7 @@
/* SPDX-License-Identifier: ISC */
/*
* Copyright (c) 2018 The Linux Foundation. All rights reserved.
* Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
*/
#ifndef _SNOC_H_
@ -53,6 +54,7 @@ enum ath10k_snoc_flags {
};
struct clk_bulk_data;
struct pwrseq_desc;
struct regulator_bulk_data;
struct ath10k_snoc {
@ -73,6 +75,7 @@ struct ath10k_snoc {
struct ath10k_snoc_ce_irq ce_irqs[CE_COUNT_MAX];
struct ath10k_ce ce;
struct timer_list rx_post_retry;
struct pwrseq_desc *pwrseq;
struct regulator_bulk_data *vregs;
size_t num_vregs;
struct clk_bulk_data *clks;

View File

@ -5289,8 +5289,6 @@ ath10k_wmi_event_peer_sta_ps_state_chg(struct ath10k *ar, struct sk_buff *skb)
struct ath10k_sta *arsta;
u8 peer_addr[ETH_ALEN];
lockdep_assert_held(&ar->data_lock);
ev = (struct wmi_peer_sta_ps_state_chg_event *)skb->data;
ether_addr_copy(peer_addr, ev->peer_macaddr.addr);
@ -5305,7 +5303,9 @@ ath10k_wmi_event_peer_sta_ps_state_chg(struct ath10k *ar, struct sk_buff *skb)
}
arsta = (struct ath10k_sta *)sta->drv_priv;
spin_lock_bh(&ar->data_lock);
arsta->peer_ps_state = __le32_to_cpu(ev->peer_ps_state);
spin_unlock_bh(&ar->data_lock);
exit:
rcu_read_unlock();

View File

@ -1044,6 +1044,33 @@ static const struct dmi_system_id ath11k_pm_quirk_table[] = {
{}
};
static const struct __ath11k_core_usecase_firmware_table {
u32 hw_rev;
const char *compatible;
const char *firmware_name;
} ath11k_core_usecase_firmware_table[] = {
{ ATH11K_HW_WCN6855_HW21, "qcom,lemans-evk", "nfa765"},
{ ATH11K_HW_WCN6855_HW21, "qcom,monaco-evk", "nfa765"},
{ ATH11K_HW_WCN6855_HW21, "qcom,hamoa-iot-evk", "nfa765"},
{ /* Sentinel */ }
};
const char *ath11k_core_get_usecase_firmware(struct ath11k_base *ab)
{
const struct __ath11k_core_usecase_firmware_table *entry = NULL;
entry = ath11k_core_usecase_firmware_table;
while (entry->compatible) {
if (ab->hw_rev == entry->hw_rev &&
of_machine_is_compatible(entry->compatible))
return entry->firmware_name;
entry++;
}
return NULL;
}
EXPORT_SYMBOL(ath11k_core_get_usecase_firmware);
void ath11k_fw_stats_pdevs_free(struct list_head *head)
{
struct ath11k_fw_stats_pdev *i, *tmp;

View File

@ -1292,6 +1292,7 @@ bool ath11k_core_coldboot_cal_support(struct ath11k_base *ab);
const struct firmware *ath11k_core_firmware_request(struct ath11k_base *ab,
const char *filename);
const char *ath11k_core_get_usecase_firmware(struct ath11k_base *ab);
static inline const char *ath11k_scan_state_str(enum ath11k_scan_state state)
{
@ -1346,6 +1347,9 @@ static inline void ath11k_core_create_firmware_path(struct ath11k_base *ab,
of_property_read_string(ab->dev->of_node, "firmware-name", &fw_name);
if (!fw_name)
fw_name = ath11k_core_get_usecase_firmware(ab);
if (fw_name && strncmp(filename, "board", 5))
snprintf(buf, buf_len, "%s/%s/%s/%s", ATH11K_FW_DIR,
ab->hw_params.fw.dir, fw_name, filename);

View File

@ -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/vmalloc.h>
@ -29,8 +29,10 @@ print_array_to_buf_index(u8 *buf, u32 offset, const char *header, u32 stats_inde
" %u:%u,", stats_index++, le32_to_cpu(array[i]));
}
/* To overwrite the last trailing comma */
index--;
*(buf + offset + index) = '\0';
if (array_len > 0) {
index--;
*(buf + offset + index) = '\0';
}
if (footer) {
index += scnprintf(buf + offset + index,
@ -5537,6 +5539,189 @@ ath12k_htt_print_pdev_rtt_tbr_cmd_res_stats_tlv(const void *tag_buf, u16 tag_len
stats_req->buf_len = len;
}
static void
ath12k_htt_print_rx_pdev_fw_stats_tlv(const void *tag_buf, u16 tag_len,
struct debug_htt_stats_req *stats_req)
{
const struct htt_rx_pdev_fw_stats_tlv *htt_stats_buf = tag_buf;
u32 buf_len = ATH12K_HTT_STATS_BUF_SIZE;
u32 len = stats_req->buf_len;
u8 *buf = stats_req->buf;
if (tag_len < sizeof(*htt_stats_buf))
return;
len += scnprintf(buf + len, buf_len - len, "HTT_RX_PDEV_FW_STATS_TLV:\n");
len += scnprintf(buf + len, buf_len - len, "mac_id = %u\n",
le32_to_cpu(htt_stats_buf->mac_id__word) & 0xFF);
len += scnprintf(buf + len, buf_len - len, "ppdu_recvd = %u\n",
le32_to_cpu(htt_stats_buf->ppdu_recvd));
len += scnprintf(buf + len, buf_len - len, "mpdu_cnt_fcs_ok = %u\n",
le32_to_cpu(htt_stats_buf->mpdu_cnt_fcs_ok));
len += scnprintf(buf + len, buf_len - len, "mpdu_cnt_fcs_err = %u\n",
le32_to_cpu(htt_stats_buf->mpdu_cnt_fcs_err));
len += scnprintf(buf + len, buf_len - len, "tcp_msdu_cnt = %u\n",
le32_to_cpu(htt_stats_buf->tcp_msdu_cnt));
len += scnprintf(buf + len, buf_len - len, "tcp_ack_msdu_cnt = %u\n",
le32_to_cpu(htt_stats_buf->tcp_ack_msdu_cnt));
len += scnprintf(buf + len, buf_len - len, "udp_msdu_cnt = %u\n",
le32_to_cpu(htt_stats_buf->udp_msdu_cnt));
len += scnprintf(buf + len, buf_len - len, "other_msdu_cnt = %u\n",
le32_to_cpu(htt_stats_buf->other_msdu_cnt));
len += scnprintf(buf + len, buf_len - len, "fw_ring_mpdu_ind = %u\n",
le32_to_cpu(htt_stats_buf->fw_ring_mpdu_ind));
len += print_array_to_buf(buf, len, "fw_ring_mgmt_subtype",
htt_stats_buf->fw_ring_mgmt_subtype,
ATH12K_HTT_STATS_SUBTYPE_MAX, "\n");
len += print_array_to_buf(buf, len, "fw_ring_ctrl_subtype",
htt_stats_buf->fw_ring_ctrl_subtype,
ATH12K_HTT_STATS_SUBTYPE_MAX, "\n");
len += scnprintf(buf + len, buf_len - len, "fw_ring_mcast_data_msdu = %u\n",
le32_to_cpu(htt_stats_buf->fw_ring_mcast_data_msdu));
len += scnprintf(buf + len, buf_len - len, "fw_ring_bcast_data_msdu = %u\n",
le32_to_cpu(htt_stats_buf->fw_ring_bcast_data_msdu));
len += scnprintf(buf + len, buf_len - len, "fw_ring_ucast_data_msdu = %u\n",
le32_to_cpu(htt_stats_buf->fw_ring_ucast_data_msdu));
len += scnprintf(buf + len, buf_len - len, "fw_ring_null_data_msdu = %u\n",
le32_to_cpu(htt_stats_buf->fw_ring_null_data_msdu));
len += scnprintf(buf + len, buf_len - len, "fw_ring_mpdu_drop = %u\n",
le32_to_cpu(htt_stats_buf->fw_ring_mpdu_drop));
len += scnprintf(buf + len, buf_len - len, "ofld_local_data_ind_cnt = %u\n",
le32_to_cpu(htt_stats_buf->ofld_local_data_ind_cnt));
len += scnprintf(buf + len, buf_len - len,
"ofld_local_data_buf_recycle_cnt = %u\n",
le32_to_cpu(htt_stats_buf->ofld_local_data_buf_recycle_cnt));
len += scnprintf(buf + len, buf_len - len, "drx_local_data_ind_cnt = %u\n",
le32_to_cpu(htt_stats_buf->drx_local_data_ind_cnt));
len += scnprintf(buf + len, buf_len - len,
"drx_local_data_buf_recycle_cnt = %u\n",
le32_to_cpu(htt_stats_buf->drx_local_data_buf_recycle_cnt));
len += scnprintf(buf + len, buf_len - len, "local_nondata_ind_cnt = %u\n",
le32_to_cpu(htt_stats_buf->local_nondata_ind_cnt));
len += scnprintf(buf + len, buf_len - len, "local_nondata_buf_recycle_cnt = %u\n",
le32_to_cpu(htt_stats_buf->local_nondata_buf_recycle_cnt));
len += scnprintf(buf + len, buf_len - len, "fw_status_buf_ring_refill_cnt = %u\n",
le32_to_cpu(htt_stats_buf->fw_status_buf_ring_refill_cnt));
len += scnprintf(buf + len, buf_len - len, "fw_status_buf_ring_empty_cnt = %u\n",
le32_to_cpu(htt_stats_buf->fw_status_buf_ring_empty_cnt));
len += scnprintf(buf + len, buf_len - len, "fw_pkt_buf_ring_refill_cnt = %u\n",
le32_to_cpu(htt_stats_buf->fw_pkt_buf_ring_refill_cnt));
len += scnprintf(buf + len, buf_len - len, "fw_pkt_buf_ring_empty_cnt = %u\n",
le32_to_cpu(htt_stats_buf->fw_pkt_buf_ring_empty_cnt));
len += scnprintf(buf + len, buf_len - len, "fw_link_buf_ring_refill_cnt = %u\n",
le32_to_cpu(htt_stats_buf->fw_link_buf_ring_refill_cnt));
len += scnprintf(buf + len, buf_len - len, "fw_link_buf_ring_empty_cnt = %u\n",
le32_to_cpu(htt_stats_buf->fw_link_buf_ring_empty_cnt));
len += scnprintf(buf + len, buf_len - len, "host_pkt_buf_ring_refill_cnt = %u\n",
le32_to_cpu(htt_stats_buf->host_pkt_buf_ring_refill_cnt));
len += scnprintf(buf + len, buf_len - len, "host_pkt_buf_ring_empty_cnt = %u\n",
le32_to_cpu(htt_stats_buf->host_pkt_buf_ring_empty_cnt));
len += scnprintf(buf + len, buf_len - len, "mon_pkt_buf_ring_refill_cnt = %u\n",
le32_to_cpu(htt_stats_buf->mon_pkt_buf_ring_refill_cnt));
len += scnprintf(buf + len, buf_len - len, "mon_pkt_buf_ring_empty_cnt = %u\n",
le32_to_cpu(htt_stats_buf->mon_pkt_buf_ring_empty_cnt));
len += scnprintf(buf + len, buf_len - len,
"mon_status_buf_ring_refill_cnt = %u\n",
le32_to_cpu(htt_stats_buf->mon_status_buf_ring_refill_cnt));
len += scnprintf(buf + len, buf_len - len, "mon_status_buf_ring_empty_cnt = %u\n",
le32_to_cpu(htt_stats_buf->mon_status_buf_ring_empty_cnt));
len += scnprintf(buf + len, buf_len - len, "mon_desc_buf_ring_refill_cnt = %u\n",
le32_to_cpu(htt_stats_buf->mon_desc_buf_ring_refill_cnt));
len += scnprintf(buf + len, buf_len - len, "mon_desc_buf_ring_empty_cnt = %u\n",
le32_to_cpu(htt_stats_buf->mon_desc_buf_ring_empty_cnt));
len += scnprintf(buf + len, buf_len - len, "mon_dest_ring_update_cnt = %u\n",
le32_to_cpu(htt_stats_buf->mon_dest_ring_update_cnt));
len += scnprintf(buf + len, buf_len - len, "mon_dest_ring_full_cnt = %u\n",
le32_to_cpu(htt_stats_buf->mon_dest_ring_full_cnt));
len += scnprintf(buf + len, buf_len - len, "rx_suspend_cnt = %u\n",
le32_to_cpu(htt_stats_buf->rx_suspend_cnt));
len += scnprintf(buf + len, buf_len - len, "rx_suspend_fail_cnt = %u\n",
le32_to_cpu(htt_stats_buf->rx_suspend_fail_cnt));
len += scnprintf(buf + len, buf_len - len, "rx_resume_cnt = %u\n",
le32_to_cpu(htt_stats_buf->rx_resume_cnt));
len += scnprintf(buf + len, buf_len - len, "rx_resume_fail_cnt = %u\n",
le32_to_cpu(htt_stats_buf->rx_resume_fail_cnt));
len += scnprintf(buf + len, buf_len - len, "rx_ring_switch_cnt = %u\n",
le32_to_cpu(htt_stats_buf->rx_ring_switch_cnt));
len += scnprintf(buf + len, buf_len - len, "rx_ring_restore_cnt = %u\n",
le32_to_cpu(htt_stats_buf->rx_ring_restore_cnt));
len += scnprintf(buf + len, buf_len - len, "rx_flush_cnt = %u\n",
le32_to_cpu(htt_stats_buf->rx_flush_cnt));
len += scnprintf(buf + len, buf_len - len, "rx_recovery_reset_cnt = %u\n",
le32_to_cpu(htt_stats_buf->rx_recovery_reset_cnt));
len += scnprintf(buf + len, buf_len - len, "rx_lwm_prom_filter_dis = %u\n",
le32_to_cpu(htt_stats_buf->rx_lwm_prom_filter_dis));
len += scnprintf(buf + len, buf_len - len, "rx_hwm_prom_filter_en = %u\n",
le32_to_cpu(htt_stats_buf->rx_hwm_prom_filter_en));
len += scnprintf(buf + len, buf_len - len, "bytes_received_low_32 = %u\n",
le32_to_cpu(htt_stats_buf->bytes_received_low_32));
len += scnprintf(buf + len, buf_len - len, "bytes_received_high_32 = %u\n",
le32_to_cpu(htt_stats_buf->bytes_received_high_32));
stats_req->buf_len = len;
}
static void
ath12k_htt_print_tx_hwq_stats_cmn_tlv(const void *tag_buf, u16 tag_len,
struct debug_htt_stats_req *stats_req)
{
const struct htt_tx_hwq_stats_cmn_tlv *htt_stats_buf = tag_buf;
u32 buf_len = ATH12K_HTT_STATS_BUF_SIZE;
u32 len = stats_req->buf_len;
u8 *buf = stats_req->buf;
if (tag_len < sizeof(*htt_stats_buf))
return;
len += scnprintf(buf + len, buf_len - len, "HTT_TX_HWQ_STATS_CMN_TLV:\n");
len += scnprintf(buf + len, buf_len - len, "mac_id = %u\n",
le32_to_cpu(htt_stats_buf->mac_id__hwq_id__word) & 0xFF);
len += scnprintf(buf + len, buf_len - len, "hwq_id = %u\n",
(le32_to_cpu(htt_stats_buf->mac_id__hwq_id__word) & 0xFF00) >> 8);
len += scnprintf(buf + len, buf_len - len, "xretry = %u\n",
le32_to_cpu(htt_stats_buf->xretry));
len += scnprintf(buf + len, buf_len - len, "underrun_cnt = %u\n",
le32_to_cpu(htt_stats_buf->underrun_cnt));
len += scnprintf(buf + len, buf_len - len, "flush_cnt = %u\n",
le32_to_cpu(htt_stats_buf->flush_cnt));
len += scnprintf(buf + len, buf_len - len, "filt_cnt = %u\n",
le32_to_cpu(htt_stats_buf->filt_cnt));
len += scnprintf(buf + len, buf_len - len, "null_mpdu_bmap = %u\n",
le32_to_cpu(htt_stats_buf->null_mpdu_bmap));
len += scnprintf(buf + len, buf_len - len, "user_ack_failure = %u\n",
le32_to_cpu(htt_stats_buf->user_ack_failure));
len += scnprintf(buf + len, buf_len - len, "ack_tlv_proc = %u\n",
le32_to_cpu(htt_stats_buf->ack_tlv_proc));
len += scnprintf(buf + len, buf_len - len, "sched_id_proc = %u\n",
le32_to_cpu(htt_stats_buf->sched_id_proc));
len += scnprintf(buf + len, buf_len - len, "null_mpdu_tx_count = %u\n",
le32_to_cpu(htt_stats_buf->null_mpdu_tx_count));
len += scnprintf(buf + len, buf_len - len, "mpdu_bmap_not_recvd = %u\n",
le32_to_cpu(htt_stats_buf->mpdu_bmap_not_recvd));
len += scnprintf(buf + len, buf_len - len, "num_bar = %u\n",
le32_to_cpu(htt_stats_buf->num_bar));
len += scnprintf(buf + len, buf_len - len, "rts = %u\n",
le32_to_cpu(htt_stats_buf->rts));
len += scnprintf(buf + len, buf_len - len, "cts2self = %u\n",
le32_to_cpu(htt_stats_buf->cts2self));
len += scnprintf(buf + len, buf_len - len, "qos_null = %u\n",
le32_to_cpu(htt_stats_buf->qos_null));
len += scnprintf(buf + len, buf_len - len, "mpdu_tried_cnt = %u\n",
le32_to_cpu(htt_stats_buf->mpdu_tried_cnt));
len += scnprintf(buf + len, buf_len - len, "mpdu_queued_cnt = %u\n",
le32_to_cpu(htt_stats_buf->mpdu_queued_cnt));
len += scnprintf(buf + len, buf_len - len, "mpdu_ack_fail_cnt = %u\n",
le32_to_cpu(htt_stats_buf->mpdu_ack_fail_cnt));
len += scnprintf(buf + len, buf_len - len, "mpdu_filt_cnt = %u\n",
le32_to_cpu(htt_stats_buf->mpdu_filt_cnt));
len += scnprintf(buf + len, buf_len - len, "false_mpdu_ack_count = %u\n",
le32_to_cpu(htt_stats_buf->false_mpdu_ack_count));
len += scnprintf(buf + len, buf_len - len, "txq_timeout = %u\n",
le32_to_cpu(htt_stats_buf->txq_timeout));
stats_req->buf_len = len;
}
static int ath12k_dbg_htt_ext_stats_parse(struct ath12k_base *ab,
u16 tag, u16 len, const void *tag_buf,
void *user_data)
@ -5690,6 +5875,9 @@ static int ath12k_dbg_htt_ext_stats_parse(struct ath12k_base *ab,
case HTT_STATS_SFM_CLIENT_USER_TAG:
ath12k_htt_print_sfm_client_user_tlv(tag_buf, len, stats_req);
break;
case HTT_STATS_RX_PDEV_FW_STATS_TAG:
ath12k_htt_print_rx_pdev_fw_stats_tlv(tag_buf, len, stats_req);
break;
case HTT_STATS_TX_PDEV_MU_MIMO_STATS_TAG:
ath12k_htt_print_tx_pdev_mu_mimo_sch_stats_tlv(tag_buf, len, stats_req);
break;
@ -5833,6 +6021,9 @@ static int ath12k_dbg_htt_ext_stats_parse(struct ath12k_base *ab,
case HTT_STATS_PDEV_RTT_TBR_CMD_RESULT_STATS_TAG:
ath12k_htt_print_pdev_rtt_tbr_cmd_res_stats_tlv(tag_buf, len, stats_req);
break;
case HTT_STATS_TX_HWQ_CMN_TAG:
ath12k_htt_print_tx_hwq_stats_cmn_tlv(tag_buf, len, stats_req);
break;
default:
break;
}

View File

@ -127,6 +127,8 @@ struct ath12k_htt_extd_stats_msg {
enum ath12k_dbg_htt_ext_stats_type {
ATH12K_DBG_HTT_EXT_STATS_RESET = 0,
ATH12K_DBG_HTT_EXT_STATS_PDEV_TX = 1,
ATH12K_DBG_HTT_EXT_STATS_PDEV_RX = 2,
ATH12K_DBG_HTT_EXT_STATS_PDEV_TX_HWQ = 3,
ATH12K_DBG_HTT_EXT_STATS_PDEV_TX_SCHED = 4,
ATH12K_DBG_HTT_EXT_STATS_PDEV_ERROR = 5,
ATH12K_DBG_HTT_EXT_STATS_PDEV_TQM = 6,
@ -173,6 +175,7 @@ enum ath12k_dbg_htt_tlv_tag {
HTT_STATS_TX_PDEV_SIFS_TAG = 2,
HTT_STATS_TX_PDEV_FLUSH_TAG = 3,
HTT_STATS_STRING_TAG = 5,
HTT_STATS_TX_HWQ_CMN_TAG = 6,
HTT_STATS_TX_TQM_GEN_MPDU_TAG = 11,
HTT_STATS_TX_TQM_LIST_MPDU_TAG = 12,
HTT_STATS_TX_TQM_LIST_MPDU_CNT_TAG = 13,
@ -188,6 +191,7 @@ enum ath12k_dbg_htt_tlv_tag {
HTT_STATS_TX_PDEV_MU_MIMO_STATS_TAG = 25,
HTT_STATS_SFM_CMN_TAG = 26,
HTT_STATS_SRING_STATS_TAG = 27,
HTT_STATS_RX_PDEV_FW_STATS_TAG = 28,
HTT_STATS_TX_PDEV_RATE_STATS_TAG = 34,
HTT_STATS_RX_PDEV_RATE_STATS_TAG = 35,
HTT_STATS_TX_PDEV_SCHEDULER_TXQ_STATS_TAG = 36,
@ -2075,4 +2079,81 @@ struct ath12k_htt_stats_pdev_rtt_tbr_cmd_result_stats_tlv {
__le32 mu_res[ATH12K_HTT_FTYPE_MAX][ATH12K_HTT_MAX_SCH_CMD_RESULT];
} __packed;
struct htt_rx_pdev_fw_stats_tlv {
__le32 mac_id__word;
__le32 ppdu_recvd;
__le32 mpdu_cnt_fcs_ok;
__le32 mpdu_cnt_fcs_err;
__le32 tcp_msdu_cnt;
__le32 tcp_ack_msdu_cnt;
__le32 udp_msdu_cnt;
__le32 other_msdu_cnt;
__le32 fw_ring_mpdu_ind;
__le32 fw_ring_mgmt_subtype[ATH12K_HTT_STATS_SUBTYPE_MAX];
__le32 fw_ring_ctrl_subtype[ATH12K_HTT_STATS_SUBTYPE_MAX];
__le32 fw_ring_mcast_data_msdu;
__le32 fw_ring_bcast_data_msdu;
__le32 fw_ring_ucast_data_msdu;
__le32 fw_ring_null_data_msdu;
__le32 fw_ring_mpdu_drop;
__le32 ofld_local_data_ind_cnt;
__le32 ofld_local_data_buf_recycle_cnt;
__le32 drx_local_data_ind_cnt;
__le32 drx_local_data_buf_recycle_cnt;
__le32 local_nondata_ind_cnt;
__le32 local_nondata_buf_recycle_cnt;
__le32 fw_status_buf_ring_refill_cnt;
__le32 fw_status_buf_ring_empty_cnt;
__le32 fw_pkt_buf_ring_refill_cnt;
__le32 fw_pkt_buf_ring_empty_cnt;
__le32 fw_link_buf_ring_refill_cnt;
__le32 fw_link_buf_ring_empty_cnt;
__le32 host_pkt_buf_ring_refill_cnt;
__le32 host_pkt_buf_ring_empty_cnt;
__le32 mon_pkt_buf_ring_refill_cnt;
__le32 mon_pkt_buf_ring_empty_cnt;
__le32 mon_status_buf_ring_refill_cnt;
__le32 mon_status_buf_ring_empty_cnt;
__le32 mon_desc_buf_ring_refill_cnt;
__le32 mon_desc_buf_ring_empty_cnt;
__le32 mon_dest_ring_update_cnt;
__le32 mon_dest_ring_full_cnt;
__le32 rx_suspend_cnt;
__le32 rx_suspend_fail_cnt;
__le32 rx_resume_cnt;
__le32 rx_resume_fail_cnt;
__le32 rx_ring_switch_cnt;
__le32 rx_ring_restore_cnt;
__le32 rx_flush_cnt;
__le32 rx_recovery_reset_cnt;
__le32 rx_lwm_prom_filter_dis;
__le32 rx_hwm_prom_filter_en;
__le32 bytes_received_low_32;
__le32 bytes_received_high_32;
} __packed;
struct htt_tx_hwq_stats_cmn_tlv {
__le32 mac_id__hwq_id__word;
__le32 xretry;
__le32 underrun_cnt;
__le32 flush_cnt;
__le32 filt_cnt;
__le32 null_mpdu_bmap;
__le32 user_ack_failure;
__le32 ack_tlv_proc;
__le32 sched_id_proc;
__le32 null_mpdu_tx_count;
__le32 mpdu_bmap_not_recvd;
__le32 num_bar;
__le32 rts;
__le32 cts2self;
__le32 qos_null;
__le32 mpdu_tried_cnt;
__le32 mpdu_queued_cnt;
__le32 mpdu_ack_fail_cnt;
__le32 mpdu_filt_cnt;
__le32 false_mpdu_ack_count;
__le32 txq_timeout;
} __packed;
#endif

View File

@ -4281,8 +4281,10 @@ ath12k_mac_op_change_vif_links(struct ieee80211_hw *hw,
if (WARN_ON(!arvif))
return -EINVAL;
if (!arvif->is_created)
if (!arvif->is_created) {
ath12k_mac_unassign_link_vif(arvif);
continue;
}
if (WARN_ON(!arvif->ar))
return -EINVAL;
@ -4505,6 +4507,166 @@ static void ath12k_wmi_vdev_params_up(struct ath12k *ar,
arvif->vdev_id, ret);
}
static int ath12k_mac_config_obss_pd(struct ath12k_link_vif *arvif,
const struct ieee80211_he_obss_pd *he_obss_pd)
{
struct ath12k_wmi_obss_pd_arg obss_pd_arg = {};
u32 srg_bitmap[2], non_srg_bitmap[2];
struct ath12k *ar = arvif->ar;
u32 param_id, pdev_id;
u32 param_val;
int ret;
if (ar->ab->hw_params->single_pdev_only)
pdev_id = ath12k_mac_get_target_pdev_id_from_vif(arvif);
else
pdev_id = ar->pdev->pdev_id;
/* Set and enable SRG/non-SRG OBSS PD threshold */
param_id = WMI_PDEV_PARAM_SET_CMD_OBSS_PD_THRESHOLD;
if (ar->monitor_started || !he_obss_pd->enable) {
ret = ath12k_wmi_pdev_set_param(ar, param_id, 0, pdev_id);
if (ret)
ath12k_warn(ar->ab,
"failed to set OBSS PD threshold for pdev %u: %d\n",
pdev_id, ret);
return ret;
}
/*
* This service flag indicates firmware support for SRG/SRP-based
* spatial reuse. It also specifies whether OBSS PD threshold values
* should be interpreted as dB (offset) or dBm (absolute) units.
*/
obss_pd_arg.srp_support = test_bit(WMI_TLV_SERVICE_SRG_SRP_SPATIAL_REUSE_SUPPORT,
ar->ab->wmi_ab.svc_map);
if (!(he_obss_pd->sr_ctrl &
IEEE80211_HE_SPR_NON_SRG_OBSS_PD_SR_DISALLOWED)) {
if (he_obss_pd->sr_ctrl & IEEE80211_HE_SPR_NON_SRG_OFFSET_PRESENT)
obss_pd_arg.non_srg_th = ATH12K_OBSS_PD_MAX_THRESHOLD +
he_obss_pd->non_srg_max_offset;
else
obss_pd_arg.non_srg_th = ATH12K_OBSS_PD_NON_SRG_MAX_THRESHOLD;
if (!obss_pd_arg.srp_support)
obss_pd_arg.non_srg_th -= ATH12K_DEFAULT_NOISE_FLOOR;
obss_pd_arg.non_srg_enabled = true;
}
if (he_obss_pd->sr_ctrl & IEEE80211_HE_SPR_SRG_INFORMATION_PRESENT) {
obss_pd_arg.srg_th = ATH12K_OBSS_PD_MAX_THRESHOLD +
he_obss_pd->max_offset;
obss_pd_arg.srg_enabled = true;
}
ath12k_dbg(ar->ab, ATH12K_DBG_MAC,
"pdev %u OBSS PD sr_ctrl 0x%x srg_th %d dBm non_srg_th %d dBm\n",
pdev_id, he_obss_pd->sr_ctrl,
obss_pd_arg.srg_th, obss_pd_arg.non_srg_th);
param_val = ath12k_wmi_build_obss_pd(&obss_pd_arg);
ret = ath12k_wmi_pdev_set_param(ar, param_id, param_val, pdev_id);
if (ret) {
ath12k_warn(ar->ab,
"failed to set OBSS PD threshold for pdev %u: %d\n",
pdev_id, ret);
return ret;
}
/* Enable OBSS PD for all access category */
param_id = WMI_PDEV_PARAM_SET_CMD_OBSS_PD_PER_AC;
param_val = 0xf;
ret = ath12k_wmi_pdev_set_param(ar, param_id, param_val, pdev_id);
if (ret) {
ath12k_warn(ar->ab,
"failed to set OBSS PD per ac for pdev %u: %d\n",
pdev_id, ret);
return ret;
}
/* Set SR prohibit */
param_id = WMI_PDEV_PARAM_ENABLE_SR_PROHIBIT;
param_val = !!(he_obss_pd->sr_ctrl &
IEEE80211_HE_SPR_HESIGA_SR_VAL15_ALLOWED);
ret = ath12k_wmi_pdev_set_param(ar, param_id, param_val, pdev_id);
if (ret) {
ath12k_warn(ar->ab, "failed to set SR prohibit for pdev %u: %d\n",
pdev_id, ret);
return ret;
}
if (!obss_pd_arg.srp_support)
return 0;
memcpy(srg_bitmap, he_obss_pd->bss_color_bitmap, sizeof(srg_bitmap));
/* Set SRG BSS color bitmap */
ret = ath12k_wmi_pdev_set_srg_bss_color_bitmap(ar, pdev_id, srg_bitmap);
if (ret) {
ath12k_warn(ar->ab,
"failed to set SRG bss color bitmap for pdev %u: %d\n",
pdev_id, ret);
return ret;
}
/* Enable BSS colors for SRG */
ret = ath12k_wmi_pdev_srg_obss_color_enable_bitmap(ar, pdev_id, srg_bitmap);
if (ret) {
ath12k_warn(ar->ab,
"failed to enable SRG bss color bitmap pdev %u: %d\n",
pdev_id, ret);
return ret;
}
memcpy(srg_bitmap, he_obss_pd->partial_bssid_bitmap, sizeof(srg_bitmap));
/* Set SRG partial bssid bitmap */
ret = ath12k_wmi_pdev_set_srg_partial_bssid_bitmap(ar, pdev_id, srg_bitmap);
if (ret) {
ath12k_warn(ar->ab,
"failed to set SRG partial bssid bitmap for pdev %u: %d\n",
pdev_id, ret);
return ret;
}
/* Enable partial bssid mask for SRG */
ret = ath12k_wmi_pdev_srg_obss_bssid_enable_bitmap(ar, pdev_id, srg_bitmap);
if (ret) {
ath12k_warn(ar->ab,
"failed to enable SRG bssid bitmap pdev %u: %d\n",
pdev_id, ret);
return ret;
}
/*
* No explicit non-SRG bitmap from mac80211; enable all colors/bssids
* as non-SRG candidates. Actual SRG members are filtered by SRG bitmaps.
*/
memset(non_srg_bitmap, 0xff, sizeof(non_srg_bitmap));
/* Enable BSS colors for non-SRG */
ret = ath12k_wmi_pdev_non_srg_obss_color_enable_bitmap(ar, pdev_id,
non_srg_bitmap);
if (ret) {
ath12k_warn(ar->ab,
"failed to enable non SRG color bitmap pdev %u: %d\n",
pdev_id, ret);
return ret;
}
/* Enable partial bssid mask for non-SRG */
ret = ath12k_wmi_pdev_non_srg_obss_bssid_enable_bitmap(ar, pdev_id,
non_srg_bitmap);
if (ret) {
ath12k_warn(ar->ab,
"failed to enable non SRG bssid bitmap pdev %u: %d\n",
pdev_id, ret);
return ret;
}
return 0;
}
static void ath12k_mac_bss_info_changed(struct ath12k *ar,
struct ath12k_link_vif *arvif,
struct ieee80211_bss_conf *info,
@ -4796,9 +4958,13 @@ static void ath12k_mac_bss_info_changed(struct ath12k *ar,
ath12k_wmi_send_twt_disable_cmd(ar, ar->pdev->pdev_id);
}
if (changed & BSS_CHANGED_HE_OBSS_PD)
ath12k_wmi_send_obss_spr_cmd(ar, arvif->vdev_id,
&info->he_obss_pd);
if (changed & BSS_CHANGED_HE_OBSS_PD) {
if (vif->type == NL80211_IFTYPE_AP)
ath12k_mac_config_obss_pd(arvif, &info->he_obss_pd);
else
ath12k_wmi_send_obss_spr_cmd(ar, arvif->vdev_id,
&info->he_obss_pd);
}
if (changed & BSS_CHANGED_HE_BSS_COLOR) {
if (vif->type == NL80211_IFTYPE_AP) {

View File

@ -138,6 +138,9 @@ struct ath12k_reg_tpc_power_info {
struct ath12k_chan_power_info chan_power_info[ATH12K_NUM_PWR_LEVELS];
};
#define ATH12K_OBSS_PD_MAX_THRESHOLD -82
#define ATH12K_OBSS_PD_NON_SRG_MAX_THRESHOLD -62
extern const struct htt_rx_ring_tlv_filter ath12k_mac_mon_status_filter_default;
#define ATH12K_SCAN_11D_INTERVAL 600000

View File

@ -126,6 +126,14 @@ struct wmi_tlv_mgmt_rx_parse {
bool frame_buf_done;
};
struct wmi_pdev_set_obss_bitmap_arg {
u32 tlv_tag;
u32 pdev_id;
u32 cmd_id;
const u32 *bitmap;
const char *label;
};
static const struct ath12k_wmi_tlv_policy ath12k_wmi_tlv_policies[] = {
[WMI_TAG_ARRAY_BYTE] = { .min_len = 0 },
[WMI_TAG_ARRAY_UINT32] = { .min_len = 0 },
@ -3560,6 +3568,140 @@ ath12k_wmi_send_obss_spr_cmd(struct ath12k *ar, u32 vdev_id,
return ret;
}
u32 ath12k_wmi_build_obss_pd(const struct ath12k_wmi_obss_pd_arg *arg)
{
u32 param_val = 0;
param_val |= u32_encode_bits((u8)arg->srg_th, GENMASK(15, 8));
param_val |= u32_encode_bits((u8)arg->non_srg_th, GENMASK(7, 0));
if (arg->srp_support)
param_val |= ATH12K_OBSS_PD_THRESHOLD_IN_DBM;
if (arg->srg_enabled && arg->srp_support)
param_val |= ATH12K_OBSS_PD_SRG_EN;
if (arg->non_srg_enabled)
param_val |= ATH12K_OBSS_PD_NON_SRG_EN;
return param_val;
}
static int ath12k_wmi_pdev_set_obss_bitmap(struct ath12k *ar,
const struct wmi_pdev_set_obss_bitmap_arg *arg)
{
struct wmi_pdev_obss_pd_bitmap_cmd *cmd;
struct ath12k_wmi_pdev *wmi = ar->wmi;
const int len = sizeof(*cmd);
struct sk_buff *skb;
int ret;
skb = ath12k_wmi_alloc_skb(wmi->wmi_ab, len);
if (!skb)
return -ENOMEM;
cmd = (struct wmi_pdev_obss_pd_bitmap_cmd *)skb->data;
cmd->tlv_header = ath12k_wmi_tlv_cmd_hdr(arg->tlv_tag, len);
cmd->pdev_id = cpu_to_le32(arg->pdev_id);
memcpy(cmd->bitmap, arg->bitmap, sizeof(cmd->bitmap));
ath12k_dbg(ar->ab, ATH12K_DBG_WMI,
"wmi set pdev %u %s %08x %08x\n",
arg->pdev_id, arg->label, arg->bitmap[0], arg->bitmap[1]);
ret = ath12k_wmi_cmd_send(wmi, skb, arg->cmd_id);
if (ret) {
ath12k_warn(ar->ab, "failed to send %s: %d\n", arg->label, ret);
dev_kfree_skb(skb);
}
return ret;
}
int ath12k_wmi_pdev_set_srg_bss_color_bitmap(struct ath12k *ar,
u32 pdev_id, const u32 *bitmap)
{
struct wmi_pdev_set_obss_bitmap_arg arg = {
.tlv_tag = WMI_TAG_PDEV_SRG_BSS_COLOR_BITMAP_CMD,
.pdev_id = pdev_id,
.cmd_id = WMI_PDEV_SET_SRG_BSS_COLOR_BITMAP_CMDID,
.bitmap = bitmap,
.label = "SRG bss color bitmap",
};
return ath12k_wmi_pdev_set_obss_bitmap(ar, &arg);
}
int ath12k_wmi_pdev_set_srg_partial_bssid_bitmap(struct ath12k *ar,
u32 pdev_id, const u32 *bitmap)
{
struct wmi_pdev_set_obss_bitmap_arg arg = {
.tlv_tag = WMI_TAG_PDEV_SRG_PARTIAL_BSSID_BITMAP_CMD,
.pdev_id = pdev_id,
.cmd_id = WMI_PDEV_SET_SRG_PARTIAL_BSSID_BITMAP_CMDID,
.bitmap = bitmap,
.label = "SRG partial bssid bitmap",
};
return ath12k_wmi_pdev_set_obss_bitmap(ar, &arg);
}
int ath12k_wmi_pdev_srg_obss_color_enable_bitmap(struct ath12k *ar,
u32 pdev_id, const u32 *bitmap)
{
struct wmi_pdev_set_obss_bitmap_arg arg = {
.tlv_tag = WMI_TAG_PDEV_SRG_OBSS_COLOR_ENABLE_BITMAP_CMD,
.pdev_id = pdev_id,
.cmd_id = WMI_PDEV_SET_SRG_OBSS_COLOR_ENABLE_BITMAP_CMDID,
.bitmap = bitmap,
.label = "SRG obss color enable bitmap",
};
return ath12k_wmi_pdev_set_obss_bitmap(ar, &arg);
}
int ath12k_wmi_pdev_srg_obss_bssid_enable_bitmap(struct ath12k *ar,
u32 pdev_id, const u32 *bitmap)
{
struct wmi_pdev_set_obss_bitmap_arg arg = {
.tlv_tag = WMI_TAG_PDEV_SRG_OBSS_BSSID_ENABLE_BITMAP_CMD,
.pdev_id = pdev_id,
.cmd_id = WMI_PDEV_SET_SRG_OBSS_BSSID_ENABLE_BITMAP_CMDID,
.bitmap = bitmap,
.label = "SRG obss bssid enable bitmap",
};
return ath12k_wmi_pdev_set_obss_bitmap(ar, &arg);
}
int ath12k_wmi_pdev_non_srg_obss_color_enable_bitmap(struct ath12k *ar,
u32 pdev_id, const u32 *bitmap)
{
struct wmi_pdev_set_obss_bitmap_arg arg = {
.tlv_tag = WMI_TAG_PDEV_NON_SRG_OBSS_COLOR_ENABLE_BITMAP_CMD,
.pdev_id = pdev_id,
.cmd_id = WMI_PDEV_SET_NON_SRG_OBSS_COLOR_ENABLE_BITMAP_CMDID,
.bitmap = bitmap,
.label = "non SRG obss color enable bitmap",
};
return ath12k_wmi_pdev_set_obss_bitmap(ar, &arg);
}
int ath12k_wmi_pdev_non_srg_obss_bssid_enable_bitmap(struct ath12k *ar,
u32 pdev_id, const u32 *bitmap)
{
struct wmi_pdev_set_obss_bitmap_arg arg = {
.tlv_tag = WMI_TAG_PDEV_NON_SRG_OBSS_BSSID_ENABLE_BITMAP_CMD,
.pdev_id = pdev_id,
.cmd_id = WMI_PDEV_SET_NON_SRG_OBSS_BSSID_ENABLE_BITMAP_CMDID,
.bitmap = bitmap,
.label = "non SRG obss bssid enable bitmap",
};
return ath12k_wmi_pdev_set_obss_bitmap(ar, &arg);
}
int ath12k_wmi_obss_color_cfg_cmd(struct ath12k *ar, u32 vdev_id,
u8 bss_color, u32 period,
bool enable)

View File

@ -374,6 +374,12 @@ enum wmi_tlv_cmd_id {
WMI_PDEV_DMA_RING_CFG_REQ_CMDID,
WMI_PDEV_HE_TB_ACTION_FRM_CMDID,
WMI_PDEV_PKTLOG_FILTER_CMDID,
WMI_PDEV_SET_SRG_BSS_COLOR_BITMAP_CMDID = 0x403b,
WMI_PDEV_SET_SRG_PARTIAL_BSSID_BITMAP_CMDID,
WMI_PDEV_SET_SRG_OBSS_COLOR_ENABLE_BITMAP_CMDID,
WMI_PDEV_SET_SRG_OBSS_BSSID_ENABLE_BITMAP_CMDID,
WMI_PDEV_SET_NON_SRG_OBSS_COLOR_ENABLE_BITMAP_CMDID,
WMI_PDEV_SET_NON_SRG_OBSS_BSSID_ENABLE_BITMAP_CMDID,
WMI_PDEV_SET_BIOS_SAR_TABLE_CMDID = 0x4044,
WMI_PDEV_SET_BIOS_GEO_TABLE_CMDID = 0x4045,
WMI_PDEV_SET_BIOS_INTERFACE_CMDID = 0x404A,
@ -1076,6 +1082,9 @@ enum wmi_tlv_pdev_param {
WMI_PDEV_PARAM_RADIO_CHAN_STATS_ENABLE,
WMI_PDEV_PARAM_RADIO_DIAGNOSIS_ENABLE,
WMI_PDEV_PARAM_MESH_MCAST_ENABLE,
WMI_PDEV_PARAM_SET_CMD_OBSS_PD_THRESHOLD = 0xbc,
WMI_PDEV_PARAM_SET_CMD_OBSS_PD_PER_AC = 0xbe,
WMI_PDEV_PARAM_ENABLE_SR_PROHIBIT = 0xc6,
};
enum wmi_tlv_vdev_param {
@ -1987,6 +1996,12 @@ enum wmi_tlv_tag {
WMI_TAG_SERVICE_READY_EXT2_EVENT = 0x334,
WMI_TAG_FILS_DISCOVERY_TMPL_CMD = 0x344,
WMI_TAG_MAC_PHY_CAPABILITIES_EXT = 0x36F,
WMI_TAG_PDEV_SRG_BSS_COLOR_BITMAP_CMD = 0x37b,
WMI_TAG_PDEV_SRG_PARTIAL_BSSID_BITMAP_CMD,
WMI_TAG_PDEV_SRG_OBSS_COLOR_ENABLE_BITMAP_CMD = 0x381,
WMI_TAG_PDEV_SRG_OBSS_BSSID_ENABLE_BITMAP_CMD,
WMI_TAG_PDEV_NON_SRG_OBSS_COLOR_ENABLE_BITMAP_CMD,
WMI_TAG_PDEV_NON_SRG_OBSS_BSSID_ENABLE_BITMAP_CMD,
WMI_TAG_REGULATORY_RULE_EXT_STRUCT = 0x3A9,
WMI_TAG_REG_CHAN_LIST_CC_EXT_EVENT,
WMI_TAG_TPC_STATS_GET_CMD = 0x38B,
@ -2244,6 +2259,7 @@ enum wmi_tlv_service {
WMI_TLV_SERVICE_FREQINFO_IN_METADATA = 219,
WMI_TLV_SERVICE_EXT2_MSG = 220,
WMI_TLV_SERVICE_BEACON_PROTECTION_SUPPORT = 244,
WMI_TLV_SERVICE_SRG_SRP_SPATIAL_REUSE_SUPPORT = 249,
WMI_TLV_SERVICE_MBSS_PARAM_IN_VDEV_START_SUPPORT = 253,
WMI_MAX_EXT_SERVICE = 256,
@ -4925,6 +4941,12 @@ struct wmi_obss_spatial_reuse_params_cmd {
__le32 vdev_id;
} __packed;
struct wmi_pdev_obss_pd_bitmap_cmd {
__le32 tlv_header;
__le32 pdev_id;
__le32 bitmap[2];
} __packed;
#define ATH12K_BSS_COLOR_COLLISION_SCAN_PERIOD_MS 200
#define ATH12K_OBSS_COLOR_COLLISION_DETECTION_DISABLE 0
#define ATH12K_OBSS_COLOR_COLLISION_DETECTION 1
@ -6329,6 +6351,18 @@ struct ath12k_wmi_rssi_dbm_conv_info_arg {
/* each WMI cmd can hold 58 channel entries at most */
#define ATH12K_WMI_MAX_NUM_CHAN_PER_CMD 58
#define ATH12K_OBSS_PD_THRESHOLD_IN_DBM BIT(29)
#define ATH12K_OBSS_PD_SRG_EN BIT(30)
#define ATH12K_OBSS_PD_NON_SRG_EN BIT(31)
struct ath12k_wmi_obss_pd_arg {
bool srp_support;
bool srg_enabled;
bool non_srg_enabled;
s8 srg_th;
s8 non_srg_th;
};
int ath12k_wmi_cmd_send(struct ath12k_wmi_pdev *wmi, struct sk_buff *skb,
u32 cmd_id);
struct sk_buff *ath12k_wmi_alloc_skb(struct ath12k_wmi_base *wmi_sc, u32 len);
@ -6432,6 +6466,19 @@ int ath12k_wmi_send_twt_enable_cmd(struct ath12k *ar, u32 pdev_id);
int ath12k_wmi_send_twt_disable_cmd(struct ath12k *ar, u32 pdev_id);
int ath12k_wmi_send_obss_spr_cmd(struct ath12k *ar, u32 vdev_id,
struct ieee80211_he_obss_pd *he_obss_pd);
u32 ath12k_wmi_build_obss_pd(const struct ath12k_wmi_obss_pd_arg *arg);
int ath12k_wmi_pdev_set_srg_bss_color_bitmap(struct ath12k *ar, u32 pdev_id,
const u32 *bitmap);
int ath12k_wmi_pdev_set_srg_partial_bssid_bitmap(struct ath12k *ar, u32 pdev_id,
const u32 *bitmap);
int ath12k_wmi_pdev_srg_obss_color_enable_bitmap(struct ath12k *ar, u32 pdev_id,
const u32 *bitmap);
int ath12k_wmi_pdev_srg_obss_bssid_enable_bitmap(struct ath12k *ar, u32 pdev_id,
const u32 *bitmap);
int ath12k_wmi_pdev_non_srg_obss_color_enable_bitmap(struct ath12k *ar, u32 pdev_id,
const u32 *bitmap);
int ath12k_wmi_pdev_non_srg_obss_bssid_enable_bitmap(struct ath12k *ar, u32 pdev_id,
const u32 *bitmap);
int ath12k_wmi_obss_color_cfg_cmd(struct ath12k *ar, u32 vdev_id,
u8 bss_color, u32 period,
bool enable);