mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-05-16 06:41:39 -04:00
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:
@@ -17,6 +17,7 @@ properties:
|
||||
compatible:
|
||||
enum:
|
||||
- qcom,ipq5332-wifi
|
||||
- qcom,ipq5424-wifi
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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() */
|
||||
|
||||
Reference in New Issue
Block a user