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

Jeff Johnson says:
==================
ath.git patches for v7.1 (PR #3)

Add ath12k support for IPQ5424.

And of course there is the usual set of cleanups and bug fixes touching
the ath10k and ath12k drivers.
==================

Signed-off-by: Johannes Berg <johannes.berg@intel.com>
This commit is contained in:
Johannes Berg
2026-04-08 08:34:51 +02:00
17 changed files with 383 additions and 46 deletions

View File

@@ -17,6 +17,7 @@ properties:
compatible:
enum:
- qcom,ipq5332-wifi
- qcom,ipq5424-wifi
reg:
maxItems: 1

View File

@@ -3,7 +3,7 @@
* Copyright (c) 2005-2011 Atheros Communications Inc.
* Copyright (c) 2011-2017 Qualcomm Atheros, Inc.
* Copyright (c) 2018-2019, The Linux Foundation. All rights reserved.
* Copyright (c) 2024 Qualcomm Innovation Center, Inc. All rights reserved.
* Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
*/
#include "core.h"
#include "debug.h"
@@ -14,6 +14,7 @@
#include "wmi-tlv.h"
#include "p2p.h"
#include "testmode.h"
#include "txrx.h"
#include <linux/bitfield.h>
/***************/
@@ -224,8 +225,9 @@ static int ath10k_wmi_tlv_parse_peer_stats_info(struct ath10k *ar, u16 tag, u16
const void *ptr, void *data)
{
const struct wmi_tlv_peer_stats_info *stat = ptr;
struct ieee80211_sta *sta;
u32 vdev_id = *(u32 *)data;
struct ath10k_sta *arsta;
struct ath10k_peer *peer;
if (tag != WMI_TLV_TAG_STRUCT_PEER_STATS_INFO)
return -EPROTO;
@@ -241,20 +243,20 @@ static int ath10k_wmi_tlv_parse_peer_stats_info(struct ath10k *ar, u16 tag, u16
__le32_to_cpu(stat->last_tx_rate_code),
__le32_to_cpu(stat->last_tx_bitrate_kbps));
rcu_read_lock();
sta = ieee80211_find_sta_by_ifaddr(ar->hw, stat->peer_macaddr.addr, NULL);
if (!sta) {
rcu_read_unlock();
ath10k_warn(ar, "not found station for peer stats\n");
guard(spinlock_bh)(&ar->data_lock);
peer = ath10k_peer_find(ar, vdev_id, stat->peer_macaddr.addr);
if (!peer || !peer->sta) {
ath10k_warn(ar, "not found %s with vdev id %u mac addr %pM for peer stats\n",
peer ? "sta" : "peer", vdev_id, stat->peer_macaddr.addr);
return -EINVAL;
}
arsta = (struct ath10k_sta *)sta->drv_priv;
arsta = (struct ath10k_sta *)peer->sta->drv_priv;
arsta->rx_rate_code = __le32_to_cpu(stat->last_rx_rate_code);
arsta->rx_bitrate_kbps = __le32_to_cpu(stat->last_rx_bitrate_kbps);
arsta->tx_rate_code = __le32_to_cpu(stat->last_tx_rate_code);
arsta->tx_bitrate_kbps = __le32_to_cpu(stat->last_tx_bitrate_kbps);
rcu_read_unlock();
return 0;
}
@@ -266,6 +268,7 @@ static int ath10k_wmi_tlv_op_pull_peer_stats_info(struct ath10k *ar,
const struct wmi_tlv_peer_stats_info_ev *ev;
const void *data;
u32 num_peer_stats;
u32 vdev_id;
int ret;
tb = ath10k_wmi_tlv_parse_alloc(ar, skb->data, skb->len, GFP_ATOMIC);
@@ -284,15 +287,16 @@ static int ath10k_wmi_tlv_op_pull_peer_stats_info(struct ath10k *ar,
}
num_peer_stats = __le32_to_cpu(ev->num_peers);
vdev_id = __le32_to_cpu(ev->vdev_id);
ath10k_dbg(ar, ATH10K_DBG_WMI,
"wmi tlv peer stats info update peer vdev id %d peers %i more data %d\n",
__le32_to_cpu(ev->vdev_id),
vdev_id,
num_peer_stats,
__le32_to_cpu(ev->more_data));
ret = ath10k_wmi_tlv_iter(ar, data, ath10k_wmi_tlv_len(data),
ath10k_wmi_tlv_parse_peer_stats_info, NULL);
ath10k_wmi_tlv_parse_peer_stats_info, &vdev_id);
if (ret)
ath10k_warn(ar, "failed to parse stats info tlv: %d\n", ret);

View File

@@ -382,8 +382,12 @@ static int ath12k_ahb_power_up(struct ath12k_base *ab)
ATH12K_AHB_UPD_SWID;
/* Load FW image to a reserved memory location */
ret = qcom_mdt_load(dev, fw, fw_name, pasid, mem_region, mem_phys, mem_size,
&mem_phys);
if (ab_ahb->scm_auth_enabled)
ret = qcom_mdt_load(dev, fw, fw_name, pasid, mem_region,
mem_phys, mem_size, &mem_phys);
else
ret = qcom_mdt_load_no_init(dev, fw, fw_name, mem_region,
mem_phys, mem_size, &mem_phys);
if (ret) {
ath12k_err(ab, "Failed to load MDT segments: %d\n", ret);
goto err_fw;
@@ -414,11 +418,13 @@ static int ath12k_ahb_power_up(struct ath12k_base *ab)
goto err_fw2;
}
/* Authenticate FW image using peripheral ID */
ret = qcom_scm_pas_auth_and_reset(pasid);
if (ret) {
ath12k_err(ab, "failed to boot the remote processor %d\n", ret);
goto err_fw2;
if (ab_ahb->scm_auth_enabled) {
/* Authenticate FW image using peripheral ID */
ret = qcom_scm_pas_auth_and_reset(pasid);
if (ret) {
ath12k_err(ab, "failed to boot the remote processor %d\n", ret);
goto err_fw2;
}
}
/* Instruct Q6 to spawn userPD thread */
@@ -475,13 +481,15 @@ static void ath12k_ahb_power_down(struct ath12k_base *ab, bool is_suspend)
qcom_smem_state_update_bits(ab_ahb->stop_state, BIT(ab_ahb->stop_bit), 0);
pasid = (u32_encode_bits(ab_ahb->userpd_id, ATH12K_USERPD_ID_MASK)) |
ATH12K_AHB_UPD_SWID;
/* Release the firmware */
ret = qcom_scm_pas_shutdown(pasid);
if (ret)
ath12k_err(ab, "scm pas shutdown failed for userPD%d: %d\n",
ab_ahb->userpd_id, ret);
if (ab_ahb->scm_auth_enabled) {
pasid = (u32_encode_bits(ab_ahb->userpd_id, ATH12K_USERPD_ID_MASK)) |
ATH12K_AHB_UPD_SWID;
/* Release the firmware */
ret = qcom_scm_pas_shutdown(pasid);
if (ret)
ath12k_err(ab, "scm pas shutdown failed for userPD%d\n",
ab_ahb->userpd_id);
}
}
static void ath12k_ahb_init_qmi_ce_config(struct ath12k_base *ab)

View File

@@ -68,6 +68,7 @@ struct ath12k_ahb {
int userpd_irq_num[ATH12K_USERPD_MAX_IRQ];
const struct ath12k_ahb_ops *ahb_ops;
const struct ath12k_ahb_device_family_ops *device_family_ops;
bool scm_auth_enabled;
};
struct ath12k_ahb_driver {

View File

@@ -38,10 +38,15 @@
#define PIPEDIR_INOUT 3 /* bidirectional */
#define PIPEDIR_INOUT_H2H 4 /* bidirectional, host to host */
/* CE address/mask */
#define CE_HOST_IE_ADDRESS 0x75804C
#define CE_HOST_IE_2_ADDRESS 0x758050
#define CE_HOST_IE_3_ADDRESS CE_HOST_IE_ADDRESS
/* IPQ5332 CE address/mask */
#define CE_HOST_IPQ5332_IE_ADDRESS 0x75804C
#define CE_HOST_IPQ5332_IE_2_ADDRESS 0x758050
#define CE_HOST_IPQ5332_IE_3_ADDRESS CE_HOST_IPQ5332_IE_ADDRESS
/* IPQ5424 CE address/mask */
#define CE_HOST_IPQ5424_IE_ADDRESS 0x21804C
#define CE_HOST_IPQ5424_IE_2_ADDRESS 0x218050
#define CE_HOST_IPQ5424_IE_3_ADDRESS CE_HOST_IPQ5424_IE_ADDRESS
#define CE_HOST_IE_3_SHIFT 0xC

View File

@@ -835,8 +835,6 @@ static int ath12k_core_soc_create(struct ath12k_base *ab)
goto err_qmi_deinit;
}
ath12k_debugfs_pdev_create(ab);
return 0;
err_qmi_deinit:
@@ -869,6 +867,8 @@ static int ath12k_core_pdev_create(struct ath12k_base *ab)
goto err_dp_pdev_free;
}
ath12k_debugfs_pdev_create(ab);
return 0;
err_dp_pdev_free:

View File

@@ -157,6 +157,7 @@ enum ath12k_hw_rev {
ATH12K_HW_WCN7850_HW20,
ATH12K_HW_IPQ5332_HW10,
ATH12K_HW_QCC2072_HW10,
ATH12K_HW_IPQ5424_HW10,
};
enum ath12k_firmware_mode {
@@ -588,6 +589,7 @@ struct ath12k_dbg_htt_stats {
struct ath12k_debug {
struct dentry *debugfs_pdev;
struct dentry *debugfs_pdev_symlink;
struct dentry *debugfs_pdev_symlink_default;
struct ath12k_dbg_htt_stats htt_stats;
enum wmi_halphy_ctrl_path_stats_id tpc_stats_type;
bool tpc_request;
@@ -673,6 +675,7 @@ struct ath12k {
u8 pdev_idx;
u8 lmac_id;
u8 hw_link_id;
u8 radio_idx;
struct completion peer_assoc_done;
struct completion peer_delete_done;
@@ -1366,13 +1369,13 @@ static inline struct ath12k_hw *ath12k_hw_to_ah(struct ieee80211_hw *hw)
return hw->priv;
}
static inline struct ath12k *ath12k_ah_to_ar(struct ath12k_hw *ah, u8 hw_link_id)
static inline struct ath12k *ath12k_ah_to_ar(struct ath12k_hw *ah, u8 radio_idx)
{
if (WARN(hw_link_id >= ah->num_radio,
"bad hw link id %d, so switch to default link\n", hw_link_id))
hw_link_id = 0;
if (WARN(radio_idx >= ah->num_radio,
"bad radio index %d, use default radio\n", radio_idx))
radio_idx = 0;
return &ah->radio[hw_link_id];
return &ah->radio[radio_idx];
}
static inline struct ath12k_hw *ath12k_ar_to_ah(struct ath12k *ar)

View File

@@ -1473,18 +1473,35 @@ void ath12k_debugfs_register(struct ath12k *ar)
{
struct ath12k_base *ab = ar->ab;
struct ieee80211_hw *hw = ar->ah->hw;
char pdev_name[5];
struct ath12k_hw *ah = ath12k_hw_to_ah(hw);
struct dentry *ath12k_fs;
char buf[100] = {};
char pdev_name[5];
scnprintf(pdev_name, sizeof(pdev_name), "%s%d", "mac", ar->pdev_idx);
ar->debug.debugfs_pdev = debugfs_create_dir(pdev_name, ab->debugfs_soc);
/* Create a symlink under ieee80211/phy* */
scnprintf(buf, sizeof(buf), "../../ath12k/%pd2", ar->debug.debugfs_pdev);
ar->debug.debugfs_pdev_symlink = debugfs_create_symlink("ath12k",
hw->wiphy->debugfsdir,
buf);
if (ar->radio_idx == 0) {
scnprintf(buf, sizeof(buf), "../../ath12k/%pd2",
ar->debug.debugfs_pdev);
ath12k_fs = hw->wiphy->debugfsdir;
/* symbolic link for compatibility */
ar->debug.debugfs_pdev_symlink_default = debugfs_create_symlink("ath12k",
ath12k_fs,
buf);
}
if (ah->num_radio > 1) {
scnprintf(buf, sizeof(buf), "../../../ath12k/%pd2",
ar->debug.debugfs_pdev);
ath12k_fs = hw->wiphy->radio_cfg[ar->radio_idx].radio_debugfsdir;
ar->debug.debugfs_pdev_symlink = debugfs_create_symlink("ath12k",
ath12k_fs,
buf);
}
if (ar->mac.sbands[NL80211_BAND_5GHZ].channels) {
debugfs_create_file("dfs_simulate_radar", 0200,
@@ -1513,7 +1530,9 @@ void ath12k_debugfs_unregister(struct ath12k *ar)
/* Remove symlink under ieee80211/phy* */
debugfs_remove(ar->debug.debugfs_pdev_symlink);
debugfs_remove(ar->debug.debugfs_pdev_symlink_default);
debugfs_remove_recursive(ar->debug.debugfs_pdev);
ar->debug.debugfs_pdev_symlink = NULL;
ar->debug.debugfs_pdev_symlink_default = NULL;
ar->debug.debugfs_pdev = NULL;
}

View File

@@ -5722,6 +5722,75 @@ ath12k_htt_print_tx_hwq_stats_cmn_tlv(const void *tag_buf, u16 tag_len,
stats_req->buf_len = len;
}
static void
ath12k_htt_print_chan_switch_stats_tlv(const void *tag_buf, u16 tag_len,
struct debug_htt_stats_req *stats_req)
{
const struct ath12k_htt_chan_switch_stats_tlv *sbuf = tag_buf;
u32 buf_len = ATH12K_HTT_STATS_BUF_SIZE;
u32 switch_freq, switch_profile;
u32 len = stats_req->buf_len;
u8 *buf = stats_req->buf;
u8 i;
if (tag_len < sizeof(*sbuf))
return;
i = min(le32_to_cpu(sbuf->switch_count), ATH12K_HTT_CHAN_SWITCH_STATS_BUF_LEN);
if (!i)
return;
len += scnprintf(buf + len, buf_len - len, "Channel Change Timings:\n");
len += scnprintf(buf + len, buf_len - len,
"|%-20s|%-21s|%-7s|%-12s|%-12s|%-15s|",
"PRIMARY CHANNEL FREQ", "BANDWIDTH CENTER FREQ", "PHYMODE",
"TX_CHAINMASK", "RX_CHAINMASK", "SWITCH TIME(us)");
len += scnprintf(buf + len, buf_len - len,
"%-7s|%-11s|%-7s|%-8s|%-7s|%-10s|\n",
"INI(us)", "TPC+CTL(us)", "CAL(us)", "MISC(us)", "CTL(us)",
"SW PROFILE");
/*
* sbuf->switch_count has the number of successful channel changes. The firmware
* sends the record of channel change in such a way that sbuf->chan_stats[0] will
* point to the channel change that occurred first and the recent channel change
* records will be stored in sbuf->chan_stats[9]. As and when new channel change
* occurs, sbuf->chan_stats[0] will be replaced by records from the next index,
* sbuf->chan_stats[1]. While printing the records, reverse chronological order
* is followed, i.e., the most recent channel change records are printed first
* and the oldest one, last.
*/
while (i--) {
switch_freq = le32_to_cpu(sbuf->chan_stats[i].chan_switch_freq);
switch_profile = le32_to_cpu(sbuf->chan_stats[i].chan_switch_profile);
len += scnprintf(buf + len, buf_len - len,
"|%20u|%21u|%7u|%12u|%12u|%15u|",
u32_get_bits(switch_freq,
ATH12K_HTT_STATS_CHAN_SWITCH_BW_MHZ),
u32_get_bits(switch_freq,
ATH12K_HTT_STATS_CHAN_SWITCH_BAND_FREQ),
u32_get_bits(switch_profile,
ATH12K_HTT_STATS_CHAN_SWITCH_PHY_MODE),
u32_get_bits(switch_profile,
ATH12K_HTT_STATS_CHAN_SWITCH_TX_CHAINMASK),
u32_get_bits(switch_profile,
ATH12K_HTT_STATS_CHAN_SWITCH_RX_CHAINMASK),
le32_to_cpu(sbuf->chan_stats[i].chan_switch_time));
len += scnprintf(buf + len, buf_len - len,
"%7u|%11u|%7u|%8u|%7u|%10u|\n",
le32_to_cpu(sbuf->chan_stats[i].ini_module_time),
le32_to_cpu(sbuf->chan_stats[i].tpc_module_time),
le32_to_cpu(sbuf->chan_stats[i].cal_module_time),
le32_to_cpu(sbuf->chan_stats[i].misc_module_time),
le32_to_cpu(sbuf->chan_stats[i].ctl_module_time),
u32_get_bits(switch_profile,
ATH12K_HTT_STATS_CHAN_SWITCH_SW_PROFILE));
}
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)
@@ -6024,6 +6093,9 @@ static int ath12k_dbg_htt_ext_stats_parse(struct ath12k_base *ab,
case HTT_STATS_TX_HWQ_CMN_TAG:
ath12k_htt_print_tx_hwq_stats_cmn_tlv(tag_buf, len, stats_req);
break;
case HTT_STATS_CHAN_SWITCH_STATS_TAG:
ath12k_htt_print_chan_switch_stats_tlv(tag_buf, len, stats_req);
break;
default:
break;
}

View File

@@ -164,6 +164,7 @@ enum ath12k_dbg_htt_ext_stats_type {
ATH12K_DBG_HTT_PDEV_MLO_IPC_STATS = 64,
ATH12K_DBG_HTT_EXT_PDEV_RTT_RESP_STATS = 65,
ATH12K_DBG_HTT_EXT_PDEV_RTT_INITIATOR_STATS = 66,
ATH12K_DBG_HTT_EXT_CHAN_SWITCH_STATS = 76,
/* keep this last */
ATH12K_DBG_HTT_NUM_EXT_STATS,
@@ -267,6 +268,7 @@ enum ath12k_dbg_htt_tlv_tag {
HTT_STATS_PDEV_RTT_HW_STATS_TAG = 196,
HTT_STATS_PDEV_RTT_TBR_SELFGEN_QUEUED_STATS_TAG = 197,
HTT_STATS_PDEV_RTT_TBR_CMD_RESULT_STATS_TAG = 198,
HTT_STATS_CHAN_SWITCH_STATS_TAG = 213,
HTT_STATS_MAX_TAG,
};
@@ -2156,4 +2158,28 @@ struct htt_tx_hwq_stats_cmn_tlv {
__le32 txq_timeout;
} __packed;
#define ATH12K_HTT_CHAN_SWITCH_STATS_BUF_LEN 10
#define ATH12K_HTT_STATS_CHAN_SWITCH_BW_MHZ GENMASK(15, 0)
#define ATH12K_HTT_STATS_CHAN_SWITCH_BAND_FREQ GENMASK(31, 16)
#define ATH12K_HTT_STATS_CHAN_SWITCH_PHY_MODE GENMASK(7, 0)
#define ATH12K_HTT_STATS_CHAN_SWITCH_TX_CHAINMASK GENMASK(15, 8)
#define ATH12K_HTT_STATS_CHAN_SWITCH_RX_CHAINMASK GENMASK(23, 16)
#define ATH12K_HTT_STATS_CHAN_SWITCH_SW_PROFILE GENMASK(31, 24)
struct ath12k_htt_chan_switch_stats_tlv {
struct {
__le32 chan_switch_freq;
__le32 chan_switch_profile;
__le32 chan_switch_time;
__le32 cal_module_time;
__le32 ini_module_time;
__le32 tpc_module_time;
__le32 misc_module_time;
__le32 ctl_module_time;
__le32 reserved;
} chan_stats[ATH12K_HTT_CHAN_SWITCH_STATS_BUF_LEN];
__le32 switch_count; /* shows how many channel changes have occurred */
} __packed;
#endif

View File

@@ -11131,7 +11131,7 @@ ath12k_mac_mlo_get_vdev_args(struct ath12k_link_vif *arvif,
if (arvif == arvif_p)
continue;
if (!arvif_p->is_created)
if (!arvif_p->is_started)
continue;
link_conf = wiphy_dereference(ahvif->ah->hw->wiphy,
@@ -15065,6 +15065,7 @@ static struct ath12k_hw *ath12k_mac_hw_allocate(struct ath12k_hw_group *ag,
ar->hw_link_id = pdev->hw_link_id;
ar->pdev = pdev;
ar->pdev_idx = pdev_idx;
ar->radio_idx = i;
pdev->ar = ar;
ag->hw_links[ar->hw_link_id].device_id = ab->device_id;
@@ -15132,7 +15133,6 @@ int ath12k_mac_allocate(struct ath12k_hw_group *ag)
if (!ab)
continue;
ath12k_debugfs_pdev_create(ab);
ath12k_mac_set_device_defaults(ab);
total_radio += ab->num_radios;
}

View File

@@ -19,6 +19,9 @@ static const struct of_device_id ath12k_wifi7_ahb_of_match[] = {
{ .compatible = "qcom,ipq5332-wifi",
.data = (void *)ATH12K_HW_IPQ5332_HW10,
},
{ .compatible = "qcom,ipq5424-wifi",
.data = (void *)ATH12K_HW_IPQ5424_HW10,
},
{ }
};
@@ -38,6 +41,11 @@ static int ath12k_wifi7_ahb_probe(struct platform_device *pdev)
switch (hw_rev) {
case ATH12K_HW_IPQ5332_HW10:
ab_ahb->userpd_id = ATH12K_IPQ5332_USERPD_ID;
ab_ahb->scm_auth_enabled = true;
break;
case ATH12K_HW_IPQ5424_HW10:
ab_ahb->userpd_id = ATH12K_IPQ5332_USERPD_ID;
ab_ahb->scm_auth_enabled = false;
break;
default:
return -EOPNOTSUPP;

View File

@@ -50,6 +50,13 @@ static const struct ath12k_hw_version_map ath12k_wifi7_hw_ver_map[] = {
.hal_params = &ath12k_hw_hal_params_wcn7850,
.hw_regs = &qcc2072_regs,
},
[ATH12K_HW_IPQ5424_HW10] = {
.hal_ops = &hal_qcn9274_ops,
.hal_desc_sz = sizeof(struct hal_rx_desc_qcn9274_compact),
.tcl_to_wbm_rbm_map = ath12k_hal_tcl_to_wbm_rbm_map_qcn9274,
.hal_params = &ath12k_hw_hal_params_ipq5332,
.hw_regs = &ipq5424_regs,
},
};
int ath12k_wifi7_hal_init(struct ath12k_base *ab)

View File

@@ -364,6 +364,9 @@
#define HAL_IPQ5332_CE_WFSS_REG_BASE 0x740000
#define HAL_IPQ5332_CE_SIZE 0x100000
#define HAL_IPQ5424_CE_WFSS_REG_BASE 0x200000
#define HAL_IPQ5424_CE_SIZE 0x100000
#define HAL_RX_MAX_BA_WINDOW 256
#define HAL_DEFAULT_BE_BK_VI_REO_TIMEOUT_USEC (100 * 1000)

View File

@@ -484,6 +484,94 @@ const struct ath12k_hw_regs ipq5332_regs = {
HAL_IPQ5332_CE_WFSS_REG_BASE,
};
const struct ath12k_hw_regs ipq5424_regs = {
/* SW2TCL(x) R0 ring configuration address */
.tcl1_ring_id = 0x00000918,
.tcl1_ring_misc = 0x00000920,
.tcl1_ring_tp_addr_lsb = 0x0000092c,
.tcl1_ring_tp_addr_msb = 0x00000930,
.tcl1_ring_consumer_int_setup_ix0 = 0x00000940,
.tcl1_ring_consumer_int_setup_ix1 = 0x00000944,
.tcl1_ring_msi1_base_lsb = 0x00000958,
.tcl1_ring_msi1_base_msb = 0x0000095c,
.tcl1_ring_base_lsb = 0x00000910,
.tcl1_ring_base_msb = 0x00000914,
.tcl1_ring_msi1_data = 0x00000960,
.tcl2_ring_base_lsb = 0x00000988,
.tcl_ring_base_lsb = 0x00000b68,
/* TCL STATUS ring address */
.tcl_status_ring_base_lsb = 0x00000d48,
/* REO DEST ring address */
.reo2_ring_base = 0x00000578,
.reo1_misc_ctrl_addr = 0x00000b9c,
.reo1_sw_cookie_cfg0 = 0x0000006c,
.reo1_sw_cookie_cfg1 = 0x00000070,
.reo1_qdesc_lut_base0 = 0x00000074,
.reo1_qdesc_lut_base1 = 0x00000078,
.reo1_ring_base_lsb = 0x00000500,
.reo1_ring_base_msb = 0x00000504,
.reo1_ring_id = 0x00000508,
.reo1_ring_misc = 0x00000510,
.reo1_ring_hp_addr_lsb = 0x00000514,
.reo1_ring_hp_addr_msb = 0x00000518,
.reo1_ring_producer_int_setup = 0x00000524,
.reo1_ring_msi1_base_lsb = 0x00000548,
.reo1_ring_msi1_base_msb = 0x0000054C,
.reo1_ring_msi1_data = 0x00000550,
.reo1_aging_thres_ix0 = 0x00000B28,
.reo1_aging_thres_ix1 = 0x00000B2C,
.reo1_aging_thres_ix2 = 0x00000B30,
.reo1_aging_thres_ix3 = 0x00000B34,
/* REO Exception ring address */
.reo2_sw0_ring_base = 0x000008c0,
/* REO Reinject ring address */
.sw2reo_ring_base = 0x00000320,
.sw2reo1_ring_base = 0x00000398,
/* REO cmd ring address */
.reo_cmd_ring_base = 0x000002A8,
/* REO status ring address */
.reo_status_ring_base = 0x00000aa0,
/* WBM idle link ring address */
.wbm_idle_ring_base_lsb = 0x00000d3c,
.wbm_idle_ring_misc_addr = 0x00000d4c,
.wbm_r0_idle_list_cntl_addr = 0x00000240,
.wbm_r0_idle_list_size_addr = 0x00000244,
.wbm_scattered_ring_base_lsb = 0x00000250,
.wbm_scattered_ring_base_msb = 0x00000254,
.wbm_scattered_desc_head_info_ix0 = 0x00000260,
.wbm_scattered_desc_head_info_ix1 = 0x00000264,
.wbm_scattered_desc_tail_info_ix0 = 0x00000270,
.wbm_scattered_desc_tail_info_ix1 = 0x00000274,
.wbm_scattered_desc_ptr_hp_addr = 0x0000027c,
/* SW2WBM release ring address */
.wbm_sw_release_ring_base_lsb = 0x0000037c,
/* WBM2SW release ring address */
.wbm0_release_ring_base_lsb = 0x00000e08,
.wbm1_release_ring_base_lsb = 0x00000e80,
/* PPE release ring address */
.ppe_rel_ring_base = 0x0000046c,
/* CE address */
.umac_ce0_src_reg_base = 0x00200000 -
HAL_IPQ5424_CE_WFSS_REG_BASE,
.umac_ce0_dest_reg_base = 0x00201000 -
HAL_IPQ5424_CE_WFSS_REG_BASE,
.umac_ce1_src_reg_base = 0x00202000 -
HAL_IPQ5424_CE_WFSS_REG_BASE,
.umac_ce1_dest_reg_base = 0x00203000 -
HAL_IPQ5424_CE_WFSS_REG_BASE,
};
static inline
bool ath12k_hal_rx_desc_get_first_msdu_qcn9274(struct hal_rx_desc *desc)
{

View File

@@ -17,6 +17,7 @@ extern const struct hal_ops hal_qcn9274_ops;
extern const struct ath12k_hw_regs qcn9274_v1_regs;
extern const struct ath12k_hw_regs qcn9274_v2_regs;
extern const struct ath12k_hw_regs ipq5332_regs;
extern const struct ath12k_hw_regs ipq5424_regs;
extern const struct ath12k_hal_tcl_to_wbm_rbm_map
ath12k_hal_tcl_to_wbm_rbm_map_qcn9274[DP_TCL_NUM_RING_MAX];
extern const struct ath12k_hw_hal_params ath12k_hw_hal_params_qcn9274;

View File

@@ -329,9 +329,15 @@ static const struct ath12k_hw_ring_mask ath12k_wifi7_hw_ring_mask_wcn7850 = {
};
static const struct ce_ie_addr ath12k_wifi7_ce_ie_addr_ipq5332 = {
.ie1_reg_addr = CE_HOST_IE_ADDRESS - HAL_IPQ5332_CE_WFSS_REG_BASE,
.ie2_reg_addr = CE_HOST_IE_2_ADDRESS - HAL_IPQ5332_CE_WFSS_REG_BASE,
.ie3_reg_addr = CE_HOST_IE_3_ADDRESS - HAL_IPQ5332_CE_WFSS_REG_BASE,
.ie1_reg_addr = CE_HOST_IPQ5332_IE_ADDRESS - HAL_IPQ5332_CE_WFSS_REG_BASE,
.ie2_reg_addr = CE_HOST_IPQ5332_IE_2_ADDRESS - HAL_IPQ5332_CE_WFSS_REG_BASE,
.ie3_reg_addr = CE_HOST_IPQ5332_IE_3_ADDRESS - HAL_IPQ5332_CE_WFSS_REG_BASE,
};
static const struct ce_ie_addr ath12k_wifi7_ce_ie_addr_ipq5424 = {
.ie1_reg_addr = CE_HOST_IPQ5424_IE_ADDRESS - HAL_IPQ5424_CE_WFSS_REG_BASE,
.ie2_reg_addr = CE_HOST_IPQ5424_IE_2_ADDRESS - HAL_IPQ5424_CE_WFSS_REG_BASE,
.ie3_reg_addr = CE_HOST_IPQ5424_IE_3_ADDRESS - HAL_IPQ5424_CE_WFSS_REG_BASE,
};
static const struct ce_remap ath12k_wifi7_ce_remap_ipq5332 = {
@@ -340,6 +346,12 @@ static const struct ce_remap ath12k_wifi7_ce_remap_ipq5332 = {
.cmem_offset = HAL_SEQ_WCSS_CMEM_OFFSET,
};
static const struct ce_remap ath12k_wifi7_ce_remap_ipq5424 = {
.base = HAL_IPQ5424_CE_WFSS_REG_BASE,
.size = HAL_IPQ5424_CE_SIZE,
.cmem_offset = HAL_SEQ_WCSS_CMEM_OFFSET,
};
static const struct ath12k_hw_params ath12k_wifi7_hw_params[] = {
{
.name = "qcn9274 hw1.0",
@@ -753,6 +765,85 @@ static const struct ath12k_hw_params ath12k_wifi7_hw_params[] = {
.dp_primary_link_only = false,
},
{
.name = "ipq5424 hw1.0",
.hw_rev = ATH12K_HW_IPQ5424_HW10,
.fw = {
.dir = "IPQ5424/hw1.0",
.board_size = 256 * 1024,
.cal_offset = 128 * 1024,
.m3_loader = ath12k_m3_fw_loader_remoteproc,
.download_aux_ucode = false,
},
.max_radios = 1,
.single_pdev_only = false,
.qmi_service_ins_id = ATH12K_QMI_WLFW_SERVICE_INS_ID_V01_IPQ5332,
.internal_sleep_clock = false,
.hw_ops = &qcn9274_ops,
.ring_mask = &ath12k_wifi7_hw_ring_mask_ipq5332,
.host_ce_config = ath12k_wifi7_host_ce_config_ipq5332,
.ce_count = 12,
.target_ce_config = ath12k_wifi7_target_ce_config_wlan_ipq5332,
.target_ce_count = 12,
.svc_to_ce_map =
ath12k_wifi7_target_service_to_ce_map_wlan_ipq5332,
.svc_to_ce_map_len = 18,
.rxdma1_enable = true,
.num_rxdma_per_pdev = 1,
.num_rxdma_dst_ring = 0,
.rx_mac_buf_ring = false,
.vdev_start_delay = false,
.interface_modes = BIT(NL80211_IFTYPE_STATION) |
BIT(NL80211_IFTYPE_AP) |
BIT(NL80211_IFTYPE_MESH_POINT),
.supports_monitor = true,
.idle_ps = false,
.download_calib = true,
.supports_suspend = false,
.tcl_ring_retry = true,
.reoq_lut_support = false,
.supports_shadow_regs = false,
.num_tcl_banks = 48,
.max_tx_ring = 4,
.mhi_config = NULL,
.wmi_init = &ath12k_wifi7_wmi_init_qcn9274,
.qmi_cnss_feature_bitmap = BIT(CNSS_QDSS_CFG_MISS_V01),
.rfkill_pin = 0,
.rfkill_cfg = 0,
.rfkill_on_level = 0,
.rddm_size = 0,
.def_num_link = 0,
.max_mlo_peer = 256,
.otp_board_id_register = 0,
.supports_sta_ps = false,
.acpi_guid = NULL,
.supports_dynamic_smps_6ghz = false,
.iova_mask = 0,
.supports_aspm = false,
.ce_ie_addr = &ath12k_wifi7_ce_ie_addr_ipq5424,
.ce_remap = &ath12k_wifi7_ce_remap_ipq5424,
.bdf_addr_offset = 0x940000,
.current_cc_support = false,
.dp_primary_link_only = true,
},
};
/* Note: called under rcu_read_lock() */