aboutsummaryrefslogtreecommitdiffstats
diff options
authorJeff Johnson <jeff.johnson@oss.qualcomm.com>2026-06-30 14:28:50 -0700
committerJeff Johnson <jeff.johnson@oss.qualcomm.com>2026-06-30 14:28:50 -0700
commit0e6c3476fe2074826e4f0c6f8575b9464496f707 (patch)
treead416085b85ce9190ecf08a78a6a133bb4364a34
parent7ac20fad74bd5b59f68fba6af689cf115d0538a2 (diff)
parent913998f903fb1432c0046c33003db38a9e8bedb1 (diff)
downloadath-0e6c3476fe2074826e4f0c6f8575b9464496f707.tar.gz
Merge branch 'ath-next'
-rw-r--r--drivers/net/wireless/ath/ath12k/ahb.c1
-rw-r--r--drivers/net/wireless/ath/ath12k/ahb.h2
-rw-r--r--drivers/net/wireless/ath/ath12k/core.c7
-rw-r--r--drivers/net/wireless/ath/ath12k/debugfs.c14
-rw-r--r--drivers/net/wireless/ath/ath12k/dp.c14
-rw-r--r--drivers/net/wireless/ath/ath12k/dp.h3
-rw-r--r--drivers/net/wireless/ath/ath12k/dp_mon.c70
-rw-r--r--drivers/net/wireless/ath/ath12k/dp_mon.h4
-rw-r--r--drivers/net/wireless/ath/ath12k/hal.c42
-rw-r--r--drivers/net/wireless/ath/ath12k/hal.h13
-rw-r--r--drivers/net/wireless/ath/ath12k/mac.c9
-rw-r--r--drivers/net/wireless/ath/ath12k/pci.c12
-rw-r--r--drivers/net/wireless/ath/ath12k/qmi.c214
-rw-r--r--drivers/net/wireless/ath/ath12k/qmi.h26
-rw-r--r--drivers/net/wireless/ath/ath12k/wifi7/dp_mon.c66
-rw-r--r--drivers/net/wireless/ath/ath12k/wifi7/hal_qcc2072.c4
-rw-r--r--drivers/net/wireless/ath/ath12k/wifi7/hal_qcn9274.c13
-rw-r--r--drivers/net/wireless/ath/ath12k/wifi7/hal_wcn7850.c13
-rw-r--r--drivers/net/wireless/ath/ath12k/wifi7/hw.c61
-rw-r--r--drivers/net/wireless/ath/ath12k/wmi.c47
-rw-r--r--drivers/net/wireless/ath/ath12k/wmi.h7
-rw-r--r--kernel/irq/manage.c1
22 files changed, 350 insertions, 293 deletions
diff --git a/drivers/net/wireless/ath/ath12k/ahb.c b/drivers/net/wireless/ath/ath12k/ahb.c
index 30733a244454e..4912172e106eb 100644
--- a/drivers/net/wireless/ath/ath12k/ahb.c
+++ b/drivers/net/wireless/ath/ath12k/ahb.c
@@ -17,7 +17,6 @@
#include "hif.h"
#define ATH12K_IRQ_CE0_OFFSET 4
-#define ATH12K_MAX_UPDS 1
#define ATH12K_UPD_IRQ_WRD_LEN 18
static struct ath12k_ahb_driver *ath12k_ahb_family_drivers[ATH12K_DEVICE_FAMILY_MAX];
diff --git a/drivers/net/wireless/ath/ath12k/ahb.h b/drivers/net/wireless/ath/ath12k/ahb.h
index 0fa15daaa3e6c..a153db6cf1d3d 100644
--- a/drivers/net/wireless/ath/ath12k/ahb.h
+++ b/drivers/net/wireless/ath/ath12k/ahb.h
@@ -27,7 +27,7 @@
#define ATH12K_USERPD_SPAWN_TIMEOUT (5 * HZ)
#define ATH12K_USERPD_READY_TIMEOUT (10 * HZ)
#define ATH12K_USERPD_STOP_TIMEOUT (5 * HZ)
-#define ATH12K_USERPD_ID_MASK GENMASK(9, 8)
+#define ATH12K_USERPD_ID_MASK GENMASK(10, 8)
#define ATH12K_USERPD_FW_NAME_LEN 35
enum ath12k_ahb_smp2p_msg_id {
diff --git a/drivers/net/wireless/ath/ath12k/core.c b/drivers/net/wireless/ath/ath12k/core.c
index 742d4fd1b598c..0e7c732f82226 100644
--- a/drivers/net/wireless/ath/ath12k/core.c
+++ b/drivers/net/wireless/ath/ath12k/core.c
@@ -49,7 +49,7 @@ ath12k_mem_profile_based_param ath12k_mem_profile_based_param[] = {
.dp_params = {
.tx_comp_ring_size = 32768,
.rxdma_monitor_buf_ring_size = 4096,
- .rxdma_monitor_dst_ring_size = 8092,
+ .rxdma_monitor_dst_ring_size = 8192,
.num_pool_tx_desc = 32768,
.rx_desc_count = 12288,
},
@@ -708,8 +708,10 @@ static void ath12k_core_stop(struct ath12k_base *ab)
ath12k_core_to_group_ref_put(ab);
- if (!test_bit(ATH12K_FLAG_CRASH_FLUSH, &ab->dev_flags))
+ if (!test_bit(ATH12K_FLAG_CRASH_FLUSH, &ab->dev_flags)) {
+ ath12k_dp_reoq_lut_addr_reset(ath12k_ab_to_dp(ab));
ath12k_qmi_firmware_stop(ab);
+ }
ath12k_acpi_stop(ab);
@@ -1371,6 +1373,7 @@ err_core_stop:
goto exit;
err_deinit:
+ ath12k_dp_reoq_lut_addr_reset(ath12k_ab_to_dp(ab));
ath12k_dp_cmn_device_deinit(ath12k_ab_to_dp(ab));
mutex_unlock(&ab->core_lock);
mutex_unlock(&ag->mutex);
diff --git a/drivers/net/wireless/ath/ath12k/debugfs.c b/drivers/net/wireless/ath/ath12k/debugfs.c
index d17d4a8f1cb7d..d54995b7adb27 100644
--- a/drivers/net/wireless/ath/ath12k/debugfs.c
+++ b/drivers/net/wireless/ath/ath12k/debugfs.c
@@ -1031,6 +1031,7 @@ static ssize_t ath12k_debugfs_dump_device_dp_stats(struct file *file,
struct ath12k_device_dp_stats *device_stats = &dp->device_stats;
int len = 0, i, j, ret;
struct ath12k *ar;
+ u32 center_freq;
const int size = 4096;
static const char *rxdma_err[HAL_REO_ENTR_RING_RXDMA_ECODE_MAX] = {
[HAL_REO_ENTR_RING_RXDMA_ECODE_OVERFLOW_ERR] = "Overflow",
@@ -1082,6 +1083,9 @@ static ssize_t ath12k_debugfs_dump_device_dp_stats(struct file *file,
if (!buf)
return -ENOMEM;
+ len += scnprintf(buf + len, size - len,
+ "DEVICE DP STATS (timestamp: %lldms):\n\n",
+ ktime_to_ms(ktime_get()));
len += scnprintf(buf + len, size - len, "DEVICE RX STATS:\n\n");
len += scnprintf(buf + len, size - len, "err ring pkts: %u\n",
device_stats->err_ring_pkts);
@@ -1161,6 +1165,12 @@ static ssize_t ath12k_debugfs_dump_device_dp_stats(struct file *file,
for (i = 0; i < ab->num_radios; i++) {
ar = ath12k_mac_get_ar_by_pdev_id(ab, DP_SW2HW_MACID(i));
if (ar) {
+ spin_lock_bh(&ar->data_lock);
+ center_freq = ar->rx_channel ? ar->rx_channel->center_freq : 0;
+ spin_unlock_bh(&ar->data_lock);
+ len += scnprintf(buf + len, size - len,
+ "\nradio%d center_freq: %u\n",
+ i, center_freq);
len += scnprintf(buf + len, size - len,
"\nradio%d tx_pending: %u\n", i,
atomic_read(&ar->dp.num_tx_pending));
@@ -1173,7 +1183,7 @@ static ssize_t ath12k_debugfs_dump_device_dp_stats(struct file *file,
for (i = 0; i < DP_REO_DST_RING_MAX; i++) {
len += scnprintf(buf + len, size - len, "Ring%d:", i + 1);
- for (j = 0; j < ATH12K_MAX_DEVICES; j++) {
+ for (j = 0; j < ab->ag->num_devices; j++) {
len += scnprintf(buf + len, size - len,
"\t%d:%u", j,
device_stats->reo_rx[i][j]);
@@ -1190,7 +1200,7 @@ static ssize_t ath12k_debugfs_dump_device_dp_stats(struct file *file,
for (i = 0; i < HAL_WBM_REL_SRC_MODULE_MAX; i++) {
len += scnprintf(buf + len, size - len, "%s:", wbm_rel_src[i]);
- for (j = 0; j < ATH12K_MAX_DEVICES; j++) {
+ for (j = 0; j < ab->ag->num_devices; j++) {
len += scnprintf(buf + len,
size - len,
"\t%d:%u", j,
diff --git a/drivers/net/wireless/ath/ath12k/dp.c b/drivers/net/wireless/ath/ath12k/dp.c
index af5f11fc1d84a..fbc0788b37a06 100644
--- a/drivers/net/wireless/ath/ath12k/dp.c
+++ b/drivers/net/wireless/ath/ath12k/dp.c
@@ -1097,7 +1097,6 @@ static void ath12k_dp_reoq_lut_cleanup(struct ath12k_base *ab)
return;
if (dp->reoq_lut.vaddr_unaligned) {
- ath12k_hal_write_reoq_lut_addr(ab, 0);
dma_free_coherent(ab->dev, dp->reoq_lut.size,
dp->reoq_lut.vaddr_unaligned,
dp->reoq_lut.paddr_unaligned);
@@ -1105,7 +1104,6 @@ static void ath12k_dp_reoq_lut_cleanup(struct ath12k_base *ab)
}
if (dp->ml_reoq_lut.vaddr_unaligned) {
- ath12k_hal_write_ml_reoq_lut_addr(ab, 0);
dma_free_coherent(ab->dev, dp->ml_reoq_lut.size,
dp->ml_reoq_lut.vaddr_unaligned,
dp->ml_reoq_lut.paddr_unaligned);
@@ -1568,6 +1566,7 @@ fail_dp_rx_free:
ath12k_dp_rx_free(ab);
fail_cmn_reoq_cleanup:
+ ath12k_dp_reoq_lut_addr_reset(dp);
ath12k_dp_reoq_lut_cleanup(ab);
fail_cmn_srng_cleanup:
@@ -1627,3 +1626,14 @@ void ath12k_dp_cmn_hw_group_assign(struct ath12k_dp *dp,
dp->device_id = ab->device_id;
dp_hw_grp->dp[dp->device_id] = dp;
}
+
+void ath12k_dp_reoq_lut_addr_reset(struct ath12k_dp *dp)
+{
+ struct ath12k_base *ab = dp->ab;
+
+ if (dp->reoq_lut.vaddr_unaligned)
+ ath12k_hal_write_reoq_lut_addr(ab, 0);
+
+ if (dp->ml_reoq_lut.vaddr_unaligned)
+ ath12k_hal_write_ml_reoq_lut_addr(ab, 0);
+}
diff --git a/drivers/net/wireless/ath/ath12k/dp.h b/drivers/net/wireless/ath/ath12k/dp.h
index f8cfc7bb29dd7..64f79e43341ea 100644
--- a/drivers/net/wireless/ath/ath12k/dp.h
+++ b/drivers/net/wireless/ath/ath12k/dp.h
@@ -205,7 +205,7 @@ struct ath12k_pdev_dp {
#define DP_REO_CMD_RING_SIZE 256
#define DP_REO_STATUS_RING_SIZE 2048
#define DP_RXDMA_BUF_RING_SIZE 4096
-#define DP_RX_MAC_BUF_RING_SIZE 2048
+#define DP_RX_MAC_BUF_RING_SIZE 4096
#define DP_RXDMA_REFILL_RING_SIZE 2048
#define DP_RXDMA_ERR_DST_RING_SIZE 1024
#define DP_RXDMA_MON_STATUS_RING_SIZE 1024
@@ -701,4 +701,5 @@ struct ath12k_rx_desc_info *ath12k_dp_get_rx_desc(struct ath12k_dp *dp,
u32 cookie);
struct ath12k_tx_desc_info *ath12k_dp_get_tx_desc(struct ath12k_dp *dp,
u32 desc_id);
+void ath12k_dp_reoq_lut_addr_reset(struct ath12k_dp *dp);
#endif
diff --git a/drivers/net/wireless/ath/ath12k/dp_mon.c b/drivers/net/wireless/ath/ath12k/dp_mon.c
index 44c5cff75f169..7d5be77b081f8 100644
--- a/drivers/net/wireless/ath/ath12k/dp_mon.c
+++ b/drivers/net/wireless/ath/ath12k/dp_mon.c
@@ -493,12 +493,8 @@ EXPORT_SYMBOL(ath12k_dp_mon_update_radiotap);
void ath12k_dp_mon_rx_deliver_msdu(struct ath12k_pdev_dp *dp_pdev,
struct napi_struct *napi,
struct sk_buff *msdu,
- const struct hal_rx_mon_ppdu_info *ppduinfo,
- struct ieee80211_rx_status *status,
- u8 decap)
+ struct ieee80211_rx_status *status)
{
- struct ath12k_dp *dp = dp_pdev->dp;
- struct ath12k_base *ab = dp->ab;
static const struct ieee80211_radiotap_he known = {
.data1 = cpu_to_le16(IEEE80211_RADIOTAP_HE_DATA1_DATA_MCS_KNOWN |
IEEE80211_RADIOTAP_HE_DATA1_BW_RU_ALLOC_KNOWN),
@@ -506,14 +502,6 @@ void ath12k_dp_mon_rx_deliver_msdu(struct ath12k_pdev_dp *dp_pdev,
};
struct ieee80211_rx_status *rx_status;
struct ieee80211_radiotap_he *he = NULL;
- struct ieee80211_sta *pubsta = NULL;
- struct ath12k_dp_link_peer *peer;
- struct ath12k_skb_rxcb *rxcb = ATH12K_SKB_RXCB(msdu);
- struct hal_rx_desc_data rx_info;
- bool is_mcbc = rxcb->is_mcbc;
- bool is_eapol_tkip = rxcb->is_eapol;
- struct hal_rx_desc *rx_desc = (struct hal_rx_desc *)msdu->data;
- u8 addr[ETH_ALEN] = {};
status->link_valid = 0;
@@ -524,64 +512,10 @@ void ath12k_dp_mon_rx_deliver_msdu(struct ath12k_pdev_dp *dp_pdev,
status->flag |= RX_FLAG_RADIOTAP_HE;
}
- ath12k_dp_extract_rx_desc_data(dp->hal, &rx_info, rx_desc, rx_desc);
-
- rcu_read_lock();
- spin_lock_bh(&dp->dp_lock);
- peer = ath12k_dp_rx_h_find_link_peer(dp_pdev, msdu, &rx_info);
- if (peer && peer->sta) {
- pubsta = peer->sta;
- memcpy(addr, peer->addr, ETH_ALEN);
- if (pubsta->valid_links) {
- status->link_valid = 1;
- status->link_id = peer->link_id;
- }
- }
-
- spin_unlock_bh(&dp->dp_lock);
- rcu_read_unlock();
-
- ath12k_dbg(ab, ATH12K_DBG_DATA,
- "rx skb %p len %u peer %pM %u %s %s%s%s%s%s%s%s%s %srate_idx %u vht_nss %u freq %u band %u flag 0x%x fcs-err %i mic-err %i amsdu-more %i\n",
- msdu,
- msdu->len,
- addr,
- rxcb->tid,
- (is_mcbc) ? "mcast" : "ucast",
- (status->encoding == RX_ENC_LEGACY) ? "legacy" : "",
- (status->encoding == RX_ENC_HT) ? "ht" : "",
- (status->encoding == RX_ENC_VHT) ? "vht" : "",
- (status->encoding == RX_ENC_HE) ? "he" : "",
- (status->bw == RATE_INFO_BW_40) ? "40" : "",
- (status->bw == RATE_INFO_BW_80) ? "80" : "",
- (status->bw == RATE_INFO_BW_160) ? "160" : "",
- (status->bw == RATE_INFO_BW_320) ? "320" : "",
- status->enc_flags & RX_ENC_FLAG_SHORT_GI ? "sgi " : "",
- status->rate_idx,
- status->nss,
- status->freq,
- status->band, status->flag,
- !!(status->flag & RX_FLAG_FAILED_FCS_CRC),
- !!(status->flag & RX_FLAG_MMIC_ERROR),
- !!(status->flag & RX_FLAG_AMSDU_MORE));
-
- ath12k_dbg_dump(ab, ATH12K_DBG_DP_RX, NULL, "dp rx msdu: ",
- msdu->data, msdu->len);
rx_status = IEEE80211_SKB_RXCB(msdu);
*rx_status = *status;
- /* TODO: trace rx packet */
-
- /* PN for multicast packets are not validate in HW,
- * so skip 802.3 rx path
- * Also, fast_rx expects the STA to be authorized, hence
- * eapol packets are sent in slow path.
- */
- if (decap == DP_RX_DECAP_TYPE_ETHERNET2_DIX && !is_eapol_tkip &&
- !(is_mcbc && rx_status->flag & RX_FLAG_DECRYPTED))
- rx_status->flag |= RX_FLAG_8023;
-
- ieee80211_rx_napi(ath12k_pdev_dp_to_hw(dp_pdev), pubsta, msdu, napi);
+ ieee80211_rx_napi(ath12k_pdev_dp_to_hw(dp_pdev), NULL, msdu, napi);
}
EXPORT_SYMBOL(ath12k_dp_mon_rx_deliver_msdu);
diff --git a/drivers/net/wireless/ath/ath12k/dp_mon.h b/drivers/net/wireless/ath/ath12k/dp_mon.h
index 167028d27513b..162cdcaa57a77 100644
--- a/drivers/net/wireless/ath/ath12k/dp_mon.h
+++ b/drivers/net/wireless/ath/ath12k/dp_mon.h
@@ -112,9 +112,7 @@ void ath12k_dp_mon_update_radiotap(struct ath12k_pdev_dp *dp_pdev,
void ath12k_dp_mon_rx_deliver_msdu(struct ath12k_pdev_dp *dp_pdev,
struct napi_struct *napi,
struct sk_buff *msdu,
- const struct hal_rx_mon_ppdu_info *ppduinfo,
- struct ieee80211_rx_status *status,
- u8 decap);
+ struct ieee80211_rx_status *status);
struct sk_buff *
ath12k_dp_mon_rx_merg_msdus(struct ath12k_pdev_dp *dp_pdev,
struct dp_mon_mpdu *mon_mpdu,
diff --git a/drivers/net/wireless/ath/ath12k/hal.c b/drivers/net/wireless/ath/ath12k/hal.c
index a164563fff289..c0c3d2f047ef0 100644
--- a/drivers/net/wireless/ath/ath12k/hal.c
+++ b/drivers/net/wireless/ath/ath12k/hal.c
@@ -828,8 +828,8 @@ void *ath12k_hal_encode_tlv64_hdr(void *tlv, u64 tag, u64 len)
{
struct hal_tlv_64_hdr *tlv64 = tlv;
- tlv64->tl = le64_encode_bits(tag, HAL_TLV_HDR_TAG) |
- le64_encode_bits(len, HAL_TLV_HDR_LEN);
+ tlv64->tl = le64_encode_bits(tag, HAL_TLV_64_HDR_TAG) |
+ le64_encode_bits(len, HAL_TLV_64_HDR_LEN);
return tlv64->value;
}
@@ -846,26 +846,44 @@ void *ath12k_hal_encode_tlv32_hdr(void *tlv, u64 tag, u64 len)
}
EXPORT_SYMBOL(ath12k_hal_encode_tlv32_hdr);
-u16 ath12k_hal_decode_tlv64_hdr(void *tlv, void **desc)
+void *ath12k_hal_decode_tlv64_hdr(void *tlv, u16 *tag, u16 *len, u16 *usrid)
{
struct hal_tlv_64_hdr *tlv64 = tlv;
- u16 tag;
- tag = le64_get_bits(tlv64->tl, HAL_SRNG_TLV_HDR_TAG);
- *desc = tlv64->value;
+ if (tag)
+ *tag = le64_get_bits(tlv64->tl, HAL_TLV_64_HDR_TAG);
+ if (len)
+ *len = le64_get_bits(tlv64->tl, HAL_TLV_64_HDR_LEN);
+ if (usrid)
+ *usrid = le64_get_bits(tlv64->tl, HAL_TLV_64_USR_ID);
- return tag;
+ return tlv64->value;
}
EXPORT_SYMBOL(ath12k_hal_decode_tlv64_hdr);
-u16 ath12k_hal_decode_tlv32_hdr(void *tlv, void **desc)
+void *ath12k_hal_decode_tlv32_hdr(void *tlv, u16 *tag, u16 *len, u16 *usrid)
{
struct hal_tlv_hdr *tlv32 = tlv;
- u16 tag;
- tag = le32_get_bits(tlv32->tl, HAL_SRNG_TLV_HDR_TAG);
- *desc = tlv32->value;
+ if (tag)
+ *tag = le32_get_bits(tlv32->tl, HAL_TLV_HDR_TAG);
+ if (len)
+ *len = le32_get_bits(tlv32->tl, HAL_TLV_HDR_LEN);
+ if (usrid)
+ *usrid = le32_get_bits(tlv32->tl, HAL_TLV_USR_ID);
- return tag;
+ return tlv32->value;
}
EXPORT_SYMBOL(ath12k_hal_decode_tlv32_hdr);
+
+u32 ath12k_hal_get_tlv64_hdr_align(void)
+{
+ return HAL_TLV_64_ALIGN;
+}
+EXPORT_SYMBOL(ath12k_hal_get_tlv64_hdr_align);
+
+u32 ath12k_hal_get_tlv32_hdr_align(void)
+{
+ return HAL_TLV_ALIGN;
+}
+EXPORT_SYMBOL(ath12k_hal_get_tlv32_hdr_align);
diff --git a/drivers/net/wireless/ath/ath12k/hal.h b/drivers/net/wireless/ath/ath12k/hal.h
index 21c551d8b2481..ba2c22fb2982b 100644
--- a/drivers/net/wireless/ath/ath12k/hal.h
+++ b/drivers/net/wireless/ath/ath12k/hal.h
@@ -1441,10 +1441,12 @@ struct hal_ops {
u8 *rbm, u32 *msdu_cnt);
void *(*reo_cmd_enc_tlv_hdr)(void *tlv, u64 tag, u64 len);
u16 (*reo_status_dec_tlv_hdr)(void *tlv, void **desc);
+ void *(*mon_rx_status_dec_tlv_hdr)(void *tlv, u16 *tag, u16 *len, u16 *usrid);
+ u32 (*get_tlv_hdr_align)(void);
};
#define HAL_TLV_HDR_TAG GENMASK(9, 1)
-#define HAL_TLV_HDR_LEN GENMASK(25, 10)
+#define HAL_TLV_HDR_LEN GENMASK(21, 10)
#define HAL_TLV_USR_ID GENMASK(31, 26)
#define HAL_TLV_ALIGN 4
@@ -1464,9 +1466,6 @@ struct hal_tlv_64_hdr {
u8 value[];
} __packed;
-#define HAL_SRNG_TLV_HDR_TAG GENMASK(9, 1)
-#define HAL_SRNG_TLV_HDR_LEN GENMASK(25, 10)
-
dma_addr_t ath12k_hal_srng_get_tp_addr(struct ath12k_base *ab,
struct hal_srng *srng);
dma_addr_t ath12k_hal_srng_get_hp_addr(struct ath12k_base *ab,
@@ -1556,6 +1555,8 @@ void ath12k_hal_rx_reo_ent_buf_paddr_get(struct ath12k_hal *hal, void *rx_desc,
u8 *rbm, u32 *msdu_cnt);
void *ath12k_hal_encode_tlv64_hdr(void *tlv, u64 tag, u64 len);
void *ath12k_hal_encode_tlv32_hdr(void *tlv, u64 tag, u64 len);
-u16 ath12k_hal_decode_tlv64_hdr(void *tlv, void **desc);
-u16 ath12k_hal_decode_tlv32_hdr(void *tlv, void **desc);
+void *ath12k_hal_decode_tlv64_hdr(void *tlv, u16 *tag, u16 *len, u16 *usrid);
+void *ath12k_hal_decode_tlv32_hdr(void *tlv, u16 *tag, u16 *len, u16 *usrid);
+u32 ath12k_hal_get_tlv64_hdr_align(void);
+u32 ath12k_hal_get_tlv32_hdr_align(void);
#endif
diff --git a/drivers/net/wireless/ath/ath12k/mac.c b/drivers/net/wireless/ath/ath12k/mac.c
index af354bef5c0d7..16339469c24cd 100644
--- a/drivers/net/wireless/ath/ath12k/mac.c
+++ b/drivers/net/wireless/ath/ath12k/mac.c
@@ -10117,7 +10117,8 @@ static void ath12k_mac_update_vif_offload(struct ath12k_link_vif *arvif)
if (vif->type != NL80211_IFTYPE_STATION &&
vif->type != NL80211_IFTYPE_AP)
vif->offload_flags &= ~(IEEE80211_OFFLOAD_ENCAP_ENABLED |
- IEEE80211_OFFLOAD_DECAP_ENABLED);
+ IEEE80211_OFFLOAD_DECAP_ENABLED |
+ IEEE80211_OFFLOAD_ENCAP_MCAST);
if (vif->offload_flags & IEEE80211_OFFLOAD_ENCAP_ENABLED) {
ahvif->dp_vif.tx_encap_type = ATH12K_HW_TXRX_ETHERNET;
@@ -10136,6 +10137,9 @@ static void ath12k_mac_update_vif_offload(struct ath12k_link_vif *arvif)
vif->offload_flags &= ~IEEE80211_OFFLOAD_ENCAP_ENABLED;
}
+ if (vif->offload_flags & IEEE80211_OFFLOAD_ENCAP_ENABLED)
+ vif->offload_flags |= IEEE80211_OFFLOAD_ENCAP_MCAST;
+
param_id = WMI_VDEV_PARAM_RX_DECAP_TYPE;
if (vif->offload_flags & IEEE80211_OFFLOAD_DECAP_ENABLED)
param_value = ATH12K_HW_TXRX_ETHERNET;
@@ -11253,6 +11257,8 @@ ath12k_mac_mlo_get_vdev_args(struct ath12k_link_vif *arvif,
ml_arg->assoc_link = arvif->is_sta_assoc_link;
+ ml_arg->ieee_link_id = arvif->link_id;
+
partner_info = ml_arg->partner_info;
links = ahvif->links_map;
@@ -11276,6 +11282,7 @@ ath12k_mac_mlo_get_vdev_args(struct ath12k_link_vif *arvif,
partner_info->vdev_id = arvif_p->vdev_id;
partner_info->hw_link_id = arvif_p->ar->pdev->hw_link_id;
+ partner_info->ieee_link_id = arvif_p->link_id;
ether_addr_copy(partner_info->addr, link_conf->addr);
ml_arg->num_partner_links++;
partner_info++;
diff --git a/drivers/net/wireless/ath/ath12k/pci.c b/drivers/net/wireless/ath/ath12k/pci.c
index d9a22d6afbb02..ae8a9acee3f11 100644
--- a/drivers/net/wireless/ath/ath12k/pci.c
+++ b/drivers/net/wireless/ath/ath12k/pci.c
@@ -5,6 +5,7 @@
*/
#include <linux/module.h>
+#include <linux/interrupt.h>
#include <linux/msi.h>
#include <linux/pci.h>
#include <linux/time.h>
@@ -537,6 +538,8 @@ static int ath12k_pci_ext_irq_config(struct ath12k_base *ab)
int i, j, n, ret, num_vectors = 0;
u32 user_base_data = 0, base_vector = 0, base_idx;
struct ath12k_ext_irq_grp *irq_grp;
+ bool threaded_napi = false;
+ int irq;
base_idx = ATH12K_PCI_IRQ_CE0_OFFSET + CE_COUNT_MAX;
ret = ath12k_pci_get_user_msi_assignment(ab, "DP",
@@ -546,6 +549,10 @@ static int ath12k_pci_ext_irq_config(struct ath12k_base *ab)
if (ret < 0)
return ret;
+ irq = ath12k_pci_get_msi_irq(ab->dev, base_vector);
+ if (irq >= 0)
+ threaded_napi = !irq_can_set_affinity(irq);
+
for (i = 0; i < ATH12K_EXT_IRQ_GRP_NUM_MAX; i++) {
irq_grp = &ab->ext_irq_grp[i];
u32 num_irq = 0;
@@ -560,6 +567,8 @@ static int ath12k_pci_ext_irq_config(struct ath12k_base *ab)
netif_napi_add(irq_grp->napi_ndev, &irq_grp->napi,
ath12k_pci_ext_grp_napi_poll);
+ if (threaded_napi)
+ netif_threaded_enable(irq_grp->napi_ndev);
if (ab->hw_params->ring_mask->tx[i] ||
ab->hw_params->ring_mask->rx[i] ||
@@ -578,7 +587,8 @@ static int ath12k_pci_ext_irq_config(struct ath12k_base *ab)
for (j = 0; j < irq_grp->num_irq; j++) {
int irq_idx = irq_grp->irqs[j];
int vector = (i % num_vectors) + base_vector;
- int irq = ath12k_pci_get_msi_irq(ab->dev, vector);
+
+ irq = ath12k_pci_get_msi_irq(ab->dev, vector);
ab->irq_num[irq_idx] = irq;
diff --git a/drivers/net/wireless/ath/ath12k/qmi.c b/drivers/net/wireless/ath/ath12k/qmi.c
index fd762b5d7bb59..1f3efcc16ac34 100644
--- a/drivers/net/wireless/ath/ath12k/qmi.c
+++ b/drivers/net/wireless/ath/ath12k/qmi.c
@@ -21,45 +21,45 @@
static const struct qmi_elem_info wlfw_host_mlo_chip_info_s_v01_ei[] = {
{
- .data_type = QMI_UNSIGNED_1_BYTE,
- .elem_len = 1,
- .elem_size = sizeof(u8),
+ .data_type = QMI_UNSIGNED_1_BYTE,
+ .elem_len = 1,
+ .elem_size = sizeof(u8),
.array_type = NO_ARRAY,
- .tlv_type = 0,
- .offset = offsetof(struct wlfw_host_mlo_chip_info_s_v01,
+ .tlv_type = 0,
+ .offset = offsetof(struct wlfw_host_mlo_chip_info_s_v01,
chip_id),
},
{
- .data_type = QMI_UNSIGNED_1_BYTE,
- .elem_len = 1,
- .elem_size = sizeof(u8),
+ .data_type = QMI_UNSIGNED_1_BYTE,
+ .elem_len = 1,
+ .elem_size = sizeof(u8),
.array_type = NO_ARRAY,
- .tlv_type = 0,
- .offset = offsetof(struct wlfw_host_mlo_chip_info_s_v01,
+ .tlv_type = 0,
+ .offset = offsetof(struct wlfw_host_mlo_chip_info_s_v01,
num_local_links),
},
{
- .data_type = QMI_UNSIGNED_1_BYTE,
- .elem_len = QMI_WLFW_MAX_NUM_MLO_LINKS_PER_CHIP_V01,
- .elem_size = sizeof(u8),
- .array_type = STATIC_ARRAY,
- .tlv_type = 0,
- .offset = offsetof(struct wlfw_host_mlo_chip_info_s_v01,
+ .data_type = QMI_UNSIGNED_1_BYTE,
+ .elem_len = QMI_WLFW_MAX_NUM_MLO_LINKS_PER_CHIP_V01,
+ .elem_size = sizeof(u8),
+ .array_type = STATIC_ARRAY,
+ .tlv_type = 0,
+ .offset = offsetof(struct wlfw_host_mlo_chip_info_s_v01,
hw_link_id),
},
{
- .data_type = QMI_UNSIGNED_1_BYTE,
- .elem_len = QMI_WLFW_MAX_NUM_MLO_LINKS_PER_CHIP_V01,
- .elem_size = sizeof(u8),
- .array_type = STATIC_ARRAY,
- .tlv_type = 0,
- .offset = offsetof(struct wlfw_host_mlo_chip_info_s_v01,
+ .data_type = QMI_UNSIGNED_1_BYTE,
+ .elem_len = QMI_WLFW_MAX_NUM_MLO_LINKS_PER_CHIP_V01,
+ .elem_size = sizeof(u8),
+ .array_type = STATIC_ARRAY,
+ .tlv_type = 0,
+ .offset = offsetof(struct wlfw_host_mlo_chip_info_s_v01,
valid_mlo_link_id),
},
{
- .data_type = QMI_EOTI,
+ .data_type = QMI_EOTI,
.array_type = NO_ARRAY,
- .tlv_type = QMI_COMMON_TLV_TYPE,
+ .tlv_type = QMI_COMMON_TLV_TYPE,
},
};
@@ -585,21 +585,21 @@ static const struct qmi_elem_info qmi_wlanfw_phy_cap_resp_msg_v01_ei[] = {
board_id),
},
{
- .data_type = QMI_OPT_FLAG,
- .elem_len = 1,
- .elem_size = sizeof(u8),
- .array_type = NO_ARRAY,
- .tlv_type = 0x13,
- .offset = offsetof(struct qmi_wlanfw_phy_cap_resp_msg_v01,
+ .data_type = QMI_OPT_FLAG,
+ .elem_len = 1,
+ .elem_size = sizeof(u8),
+ .array_type = NO_ARRAY,
+ .tlv_type = 0x13,
+ .offset = offsetof(struct qmi_wlanfw_phy_cap_resp_msg_v01,
single_chip_mlo_support_valid),
},
{
- .data_type = QMI_UNSIGNED_1_BYTE,
- .elem_len = 1,
- .elem_size = sizeof(u8),
- .array_type = NO_ARRAY,
- .tlv_type = 0x13,
- .offset = offsetof(struct qmi_wlanfw_phy_cap_resp_msg_v01,
+ .data_type = QMI_UNSIGNED_1_BYTE,
+ .elem_len = 1,
+ .elem_size = sizeof(u8),
+ .array_type = NO_ARRAY,
+ .tlv_type = 0x13,
+ .offset = offsetof(struct qmi_wlanfw_phy_cap_resp_msg_v01,
single_chip_mlo_support),
},
{
@@ -1625,42 +1625,45 @@ static const struct qmi_elem_info qmi_wlanfw_m3_info_resp_msg_v01_ei[] = {
static const struct qmi_elem_info qmi_wlanfw_aux_uc_info_req_msg_v01_ei[] = {
{
- .data_type = QMI_UNSIGNED_8_BYTE,
- .elem_len = 1,
- .elem_size = sizeof(u64),
- .array_type = NO_ARRAY,
- .tlv_type = 0x01,
- .offset = offsetof(struct qmi_wlanfw_aux_uc_info_req_msg_v01, addr),
+ .data_type = QMI_UNSIGNED_8_BYTE,
+ .elem_len = 1,
+ .elem_size = sizeof(u64),
+ .array_type = NO_ARRAY,
+ .tlv_type = 0x01,
+ .offset = offsetof(struct qmi_wlanfw_aux_uc_info_req_msg_v01,
+ addr),
},
{
- .data_type = QMI_UNSIGNED_4_BYTE,
- .elem_len = 1,
- .elem_size = sizeof(u32),
- .array_type = NO_ARRAY,
- .tlv_type = 0x02,
- .offset = offsetof(struct qmi_wlanfw_aux_uc_info_req_msg_v01, size),
+ .data_type = QMI_UNSIGNED_4_BYTE,
+ .elem_len = 1,
+ .elem_size = sizeof(u32),
+ .array_type = NO_ARRAY,
+ .tlv_type = 0x02,
+ .offset = offsetof(struct qmi_wlanfw_aux_uc_info_req_msg_v01,
+ size),
},
{
- .data_type = QMI_EOTI,
- .array_type = NO_ARRAY,
- .tlv_type = QMI_COMMON_TLV_TYPE,
+ .data_type = QMI_EOTI,
+ .array_type = NO_ARRAY,
+ .tlv_type = QMI_COMMON_TLV_TYPE,
},
};
static const struct qmi_elem_info qmi_wlanfw_aux_uc_info_resp_msg_v01_ei[] = {
{
- .data_type = QMI_STRUCT,
- .elem_len = 1,
- .elem_size = sizeof(struct qmi_response_type_v01),
- .array_type = NO_ARRAY,
- .tlv_type = 0x02,
- .offset = offsetof(struct qmi_wlanfw_aux_uc_info_resp_msg_v01, resp),
- .ei_array = qmi_response_type_v01_ei,
+ .data_type = QMI_STRUCT,
+ .elem_len = 1,
+ .elem_size = sizeof(struct qmi_response_type_v01),
+ .array_type = NO_ARRAY,
+ .tlv_type = 0x02,
+ .offset = offsetof(struct qmi_wlanfw_aux_uc_info_resp_msg_v01,
+ resp),
+ .ei_array = qmi_response_type_v01_ei,
},
{
- .data_type = QMI_EOTI,
- .array_type = NO_ARRAY,
- .tlv_type = QMI_COMMON_TLV_TYPE,
+ .data_type = QMI_EOTI,
+ .array_type = NO_ARRAY,
+ .tlv_type = QMI_COMMON_TLV_TYPE,
},
};
@@ -1772,7 +1775,8 @@ static const struct qmi_elem_info qmi_wlanfw_shadow_reg_cfg_s_v01_ei[] = {
},
{
.data_type = QMI_EOTI,
- .array_type = QMI_COMMON_TLV_TYPE,
+ .array_type = NO_ARRAY,
+ .tlv_type = QMI_COMMON_TLV_TYPE,
},
};
@@ -1925,7 +1929,7 @@ static const struct qmi_elem_info qmi_wlanfw_wlan_cfg_req_msg_v01_ei[] = {
.data_type = QMI_OPT_FLAG,
.elem_len = 1,
.elem_size = sizeof(u8),
- .array_type = NO_ARRAY,
+ .array_type = NO_ARRAY,
.tlv_type = 0x13,
.offset = offsetof(struct qmi_wlanfw_wlan_cfg_req_msg_v01,
shadow_reg_valid),
@@ -1934,7 +1938,7 @@ static const struct qmi_elem_info qmi_wlanfw_wlan_cfg_req_msg_v01_ei[] = {
.data_type = QMI_DATA_LEN,
.elem_len = 1,
.elem_size = sizeof(u8),
- .array_type = NO_ARRAY,
+ .array_type = NO_ARRAY,
.tlv_type = 0x13,
.offset = offsetof(struct qmi_wlanfw_wlan_cfg_req_msg_v01,
shadow_reg_len),
@@ -1943,7 +1947,7 @@ static const struct qmi_elem_info qmi_wlanfw_wlan_cfg_req_msg_v01_ei[] = {
.data_type = QMI_STRUCT,
.elem_len = QMI_WLANFW_MAX_NUM_SHADOW_REG_V01,
.elem_size = sizeof(struct qmi_wlanfw_shadow_reg_cfg_s_v01),
- .array_type = VAR_LEN_ARRAY,
+ .array_type = VAR_LEN_ARRAY,
.tlv_type = 0x13,
.offset = offsetof(struct qmi_wlanfw_wlan_cfg_req_msg_v01,
shadow_reg),
@@ -2003,15 +2007,17 @@ static const struct qmi_elem_info qmi_wlanfw_wlan_cfg_resp_msg_v01_ei[] = {
static const struct qmi_elem_info qmi_wlanfw_mem_ready_ind_msg_v01_ei[] = {
{
- .data_type = QMI_EOTI,
- .array_type = NO_ARRAY,
+ .data_type = QMI_EOTI,
+ .array_type = NO_ARRAY,
+ .tlv_type = QMI_COMMON_TLV_TYPE,
},
};
static const struct qmi_elem_info qmi_wlanfw_fw_ready_ind_msg_v01_ei[] = {
{
- .data_type = QMI_EOTI,
- .array_type = NO_ARRAY,
+ .data_type = QMI_EOTI,
+ .array_type = NO_ARRAY,
+ .tlv_type = QMI_COMMON_TLV_TYPE,
},
};
@@ -2094,14 +2100,14 @@ static int ath12k_host_cap_parse_mlo(struct ath12k_base *ab,
if (!ag->mlo_capable) {
ath12k_dbg(ab, ATH12K_DBG_QMI,
- "MLO is disabled hence skip QMI MLO cap");
+ "MLO is disabled hence skip QMI MLO cap\n");
return 0;
}
if (!ab->qmi.num_radios || ab->qmi.num_radios == U8_MAX) {
ag->mlo_capable = false;
ath12k_dbg(ab, ATH12K_DBG_QMI,
- "skip QMI MLO cap due to invalid num_radio %d\n",
+ "skip QMI MLO cap due to invalid num_radio %u\n",
ab->qmi.num_radios);
return 0;
}
@@ -2125,7 +2131,7 @@ static int ath12k_host_cap_parse_mlo(struct ath12k_base *ab,
req->mlo_num_chips_valid = 1;
req->mlo_num_chips = ag->num_devices;
- ath12k_dbg(ab, ATH12K_DBG_QMI, "mlo capability advertisement device_id %d group_id %d num_devices %d",
+ ath12k_dbg(ab, ATH12K_DBG_QMI, "mlo capability advertisement device_id %u group_id %u num_devices %u\n",
req->mlo_chip_id, req->mlo_group_id, req->mlo_num_chips);
mutex_lock(&ag->mutex);
@@ -2146,14 +2152,14 @@ static int ath12k_host_cap_parse_mlo(struct ath12k_base *ab,
info->chip_id = partner_ab->device_id;
info->num_local_links = partner_ab->qmi.num_radios;
- ath12k_dbg(ab, ATH12K_DBG_QMI, "mlo device id %d num_link %d\n",
+ ath12k_dbg(ab, ATH12K_DBG_QMI, "mlo device id %u num_link %u\n",
info->chip_id, info->num_local_links);
for (j = 0; j < info->num_local_links; j++) {
info->hw_link_id[j] = partner_ab->wsi_info.hw_link_id_base + j;
info->valid_mlo_link_id[j] = 1;
- ath12k_dbg(ab, ATH12K_DBG_QMI, "mlo hw_link_id %d\n",
+ ath12k_dbg(ab, ATH12K_DBG_QMI, "mlo hw_link_id %u\n",
info->hw_link_id[j]);
hw_link_id++;
@@ -2268,7 +2274,7 @@ int ath12k_qmi_host_cap_send(struct ath12k_base *ab)
goto out;
if (resp.resp.result != QMI_RESULT_SUCCESS_V01) {
- ath12k_warn(ab, "Host capability request failed, result: %d, err: %d\n",
+ ath12k_warn(ab, "Host capability request failed, result: %u, err: %u\n",
resp.resp.result, resp.resp.error);
ret = -EINVAL;
goto out;
@@ -2320,7 +2326,7 @@ static void ath12k_qmi_phy_cap_send(struct ath12k_base *ab)
ab->qmi.num_radios = resp.num_phy;
ath12k_dbg(ab, ATH12K_DBG_QMI,
- "phy capability resp valid %d single_chip_mlo_support %d valid %d num_phy %d valid %d board_id %d\n",
+ "phy capability resp valid %u single_chip_mlo_support %u valid %u num_phy %u valid %u board_id %u\n",
resp.single_chip_mlo_support_valid, resp.single_chip_mlo_support,
resp.num_phy_valid, resp.num_phy,
resp.board_id_valid, resp.board_id);
@@ -2332,7 +2338,7 @@ out:
ab->qmi.num_radios = ab->hw_params->def_num_link;
ath12k_dbg(ab, ATH12K_DBG_QMI,
- "no valid response from PHY capability, choose default num_phy %d\n",
+ "no valid response from PHY capability, choose default num_phy %u\n",
ab->qmi.num_radios);
}
@@ -2393,7 +2399,7 @@ static int ath12k_qmi_fw_ind_register_send(struct ath12k_base *ab)
}
if (resp->resp.result != QMI_RESULT_SUCCESS_V01) {
- ath12k_warn(ab, "FW Ind register request failed, result: %d, err: %d\n",
+ ath12k_warn(ab, "FW Ind register request failed, result: %u, err: %u\n",
resp->resp.result, resp->resp.error);
ret = -EINVAL;
goto out;
@@ -2428,7 +2434,7 @@ int ath12k_qmi_respond_fw_mem_request(struct ath12k_base *ab)
if (!test_bit(ATH12K_FLAG_FIXED_MEM_REGION, &ab->dev_flags) &&
ab->qmi.target_mem_delayed) {
delayed = true;
- ath12k_dbg(ab, ATH12K_DBG_QMI, "qmi delays mem_request %d\n",
+ ath12k_dbg(ab, ATH12K_DBG_QMI, "qmi delays mem_request %u\n",
ab->qmi.mem_seg_count);
} else {
delayed = false;
@@ -2474,7 +2480,7 @@ int ath12k_qmi_respond_fw_mem_request(struct ath12k_base *ab)
if (delayed && resp.resp.error == 0)
goto out;
- ath12k_warn(ab, "Respond mem req failed, result: %d, err: %d\n",
+ ath12k_warn(ab, "Respond mem req failed, result: %u, err: %u\n",
resp.resp.result, resp.resp.error);
ret = -EINVAL;
goto out;
@@ -2606,13 +2612,13 @@ static int ath12k_qmi_alloc_chunk(struct ath12k_base *ab,
if (chunk->size > ATH12K_QMI_MAX_CHUNK_SIZE) {
ab->qmi.target_mem_delayed = true;
ath12k_warn(ab,
- "qmi dma allocation failed (%d B type %u), will try later with small size\n",
+ "qmi dma allocation failed (%u B type %u), will try later with small size\n",
chunk->size,
chunk->type);
ath12k_qmi_free_target_mem_chunk(ab);
return -EAGAIN;
}
- ath12k_warn(ab, "memory allocation failure for %u size: %d\n",
+ ath12k_warn(ab, "memory allocation failure for %u size: %u\n",
chunk->type, chunk->size);
return -ENOMEM;
}
@@ -2659,7 +2665,7 @@ static int ath12k_qmi_alloc_target_mem_chunk(struct ath12k_base *ab)
mlo_size += chunk->size;
if (ag->mlo_mem.mlo_mem_size &&
mlo_size > ag->mlo_mem.mlo_mem_size) {
- ath12k_err(ab, "QMI MLO memory allocation failure, requested size %d is more than allocated size %d",
+ ath12k_err(ab, "QMI MLO memory allocation failure, requested size %d is more than allocated size %d\n",
mlo_size, ag->mlo_mem.mlo_mem_size);
ret = -EINVAL;
goto err;
@@ -2668,7 +2674,7 @@ static int ath12k_qmi_alloc_target_mem_chunk(struct ath12k_base *ab)
mlo_chunk = &ag->mlo_mem.chunk[mlo_idx];
if (mlo_chunk->paddr) {
if (chunk->size != mlo_chunk->size) {
- ath12k_err(ab, "QMI MLO chunk memory allocation failure for index %d, requested size %d is more than allocated size %d",
+ ath12k_err(ab, "QMI MLO chunk memory allocation failure for index %d, requested size %u is more than allocated size %u\n",
mlo_idx, chunk->size, mlo_chunk->size);
ret = -EINVAL;
goto err;
@@ -2699,7 +2705,7 @@ static int ath12k_qmi_alloc_target_mem_chunk(struct ath12k_base *ab)
if (!ag->mlo_mem.mlo_mem_size) {
ag->mlo_mem.mlo_mem_size = mlo_size;
} else if (ag->mlo_mem.mlo_mem_size != mlo_size) {
- ath12k_err(ab, "QMI MLO memory size error, expected size is %d but requested size is %d",
+ ath12k_err(ab, "QMI MLO memory size error, expected size is %d but requested size is %d\n",
ag->mlo_mem.mlo_mem_size, mlo_size);
ret = -EINVAL;
goto err;
@@ -2884,7 +2890,7 @@ int ath12k_qmi_request_target_cap(struct ath12k_base *ab)
}
if (resp.resp.result != QMI_RESULT_SUCCESS_V01) {
- ath12k_warn(ab, "qmi targetcap req failed, result: %d, err: %d\n",
+ ath12k_warn(ab, "qmi targetcap req failed, result: %u, err: %u\n",
resp.resp.result, resp.resp.error);
ret = -EINVAL;
goto out;
@@ -2936,7 +2942,7 @@ int ath12k_qmi_request_target_cap(struct ath12k_base *ab)
ab->qmi.target.chip_id, ab->qmi.target.chip_family,
ab->qmi.target.board_id, ab->qmi.target.soc_id);
- ath12k_info(ab, "fw_version 0x%x fw_build_timestamp %s fw_build_id %s",
+ ath12k_info(ab, "fw_version 0x%x fw_build_timestamp %s fw_build_id %s\n",
ab->qmi.target.fw_version,
ab->qmi.target.fw_build_timestamp,
ab->qmi.target.fw_build_id);
@@ -3006,7 +3012,7 @@ static int ath12k_qmi_load_file_target_mem(struct ath12k_base *ab,
if (ret < 0)
goto out;
- ath12k_dbg(ab, ATH12K_DBG_QMI, "qmi bdf download req fixed addr type %d\n",
+ ath12k_dbg(ab, ATH12K_DBG_QMI, "qmi bdf download req fixed addr type %u\n",
type);
ret = qmi_send_request(&ab->qmi.handle, NULL, &txn,
@@ -3023,7 +3029,7 @@ static int ath12k_qmi_load_file_target_mem(struct ath12k_base *ab,
goto out;
if (resp.resp.result != QMI_RESULT_SUCCESS_V01) {
- ath12k_warn(ab, "qmi BDF download failed, result: %d, err: %d\n",
+ ath12k_warn(ab, "qmi BDF download failed, result: %u, err: %u\n",
resp.resp.result, resp.resp.error);
ret = -EINVAL;
goto out;
@@ -3036,7 +3042,7 @@ static int ath12k_qmi_load_file_target_mem(struct ath12k_base *ab,
temp += req->data_len;
req->seg_id++;
ath12k_dbg(ab, ATH12K_DBG_QMI,
- "qmi bdf download request remaining %i\n",
+ "qmi bdf download request remaining %u\n",
remaining);
}
}
@@ -3127,7 +3133,7 @@ out_qmi_cal:
release_firmware(fw_entry);
return ret;
default:
- ath12k_warn(ab, "unknown file type for load %d", type);
+ ath12k_warn(ab, "unknown file type for load %d\n", type);
goto out;
}
@@ -3239,7 +3245,7 @@ int ath12k_qmi_wlanfw_m3_info_send(struct ath12k_base *ab)
if (ab->hw_params->fw.m3_loader == ath12k_m3_fw_loader_driver) {
ret = ath12k_qmi_m3_load(ab);
if (ret) {
- ath12k_err(ab, "failed to load m3 firmware: %d", ret);
+ ath12k_err(ab, "failed to load m3 firmware: %d\n", ret);
return ret;
}
req.addr = m3_mem->paddr;
@@ -3269,7 +3275,7 @@ int ath12k_qmi_wlanfw_m3_info_send(struct ath12k_base *ab)
}
if (resp.resp.result != QMI_RESULT_SUCCESS_V01) {
- ath12k_warn(ab, "qmi M3 info request failed, result: %d, err: %d\n",
+ ath12k_warn(ab, "qmi M3 info request failed, result: %u, err: %u\n",
resp.resp.result, resp.resp.error);
ret = -EINVAL;
goto out;
@@ -3364,7 +3370,7 @@ int ath12k_qmi_wlanfw_aux_uc_info_send(struct ath12k_base *ab)
ret = ath12k_qmi_aux_uc_load(ab);
if (ret) {
- ath12k_err(ab, "failed to load aux_uc firmware: %d", ret);
+ ath12k_err(ab, "failed to load aux_uc firmware: %d\n", ret);
return ret;
}
@@ -3394,7 +3400,7 @@ int ath12k_qmi_wlanfw_aux_uc_info_send(struct ath12k_base *ab)
}
if (resp.resp.result != QMI_RESULT_SUCCESS_V01) {
- ath12k_warn(ab, "qmi AUX_UC info request failed, result: %d, err: %d\n",
+ ath12k_warn(ab, "qmi AUX_UC info request failed, result: %u, err: %u\n",
resp.resp.result, resp.resp.error);
ret = -EINVAL;
goto out;
@@ -3426,7 +3432,7 @@ static int ath12k_qmi_wlanfw_mode_send(struct ath12k_base *ab,
qmi_wlanfw_wlan_mode_req_msg_v01_ei, &req);
if (ret < 0) {
qmi_txn_cancel(&txn);
- ath12k_warn(ab, "qmi failed to send mode request, mode: %d, err = %d\n",
+ ath12k_warn(ab, "qmi failed to send mode request, mode: %u, err = %d\n",
mode, ret);
goto out;
}
@@ -3437,13 +3443,13 @@ static int ath12k_qmi_wlanfw_mode_send(struct ath12k_base *ab,
ath12k_warn(ab, "WLFW service is dis-connected\n");
return 0;
}
- ath12k_warn(ab, "qmi failed set mode request, mode: %d, err = %d\n",
+ ath12k_warn(ab, "qmi failed set mode request, mode: %u, err = %d\n",
mode, ret);
goto out;
}
if (resp.resp.result != QMI_RESULT_SUCCESS_V01) {
- ath12k_warn(ab, "Mode request failed, mode: %d, result: %d err: %d\n",
+ ath12k_warn(ab, "Mode request failed, mode: %u, result: %u err: %u\n",
mode, resp.resp.result, resp.resp.error);
ret = -EINVAL;
goto out;
@@ -3536,7 +3542,7 @@ static int ath12k_qmi_wlanfw_wlan_cfg_send(struct ath12k_base *ab)
}
if (resp.resp.result != QMI_RESULT_SUCCESS_V01) {
- ath12k_warn(ab, "qmi wlan config request failed, result: %d, err: %d\n",
+ ath12k_warn(ab, "qmi wlan config request failed, result: %u, err: %u\n",
resp.resp.result, resp.resp.error);
ret = -EINVAL;
goto out;
@@ -3580,7 +3586,7 @@ static int ath12k_qmi_wlanfw_wlan_ini_send(struct ath12k_base *ab)
}
if (resp.resp.result != QMI_RESULT_SUCCESS_V01) {
- ath12k_warn(ab, "QMI wlan ini response failure: %d %d\n",
+ ath12k_warn(ab, "QMI wlan ini response failure: %u %u\n",
resp.resp.result, resp.resp.error);
ret = -EINVAL;
goto out;
@@ -3663,7 +3669,7 @@ void ath12k_qmi_trigger_host_cap(struct ath12k_base *ab)
spin_unlock(&qmi->event_lock);
- ath12k_dbg(ab, ATH12K_DBG_QMI, "trigger host cap for device id %d\n",
+ ath12k_dbg(ab, ATH12K_DBG_QMI, "trigger host cap for device id %u\n",
ab->device_id);
ath12k_qmi_driver_event_post(qmi, ATH12K_QMI_EVENT_HOST_CAP, NULL);
@@ -3833,7 +3839,7 @@ static void ath12k_qmi_msg_mem_request_cb(struct qmi_handle *qmi_hdl,
for (i = 0; i < qmi->mem_seg_count ; i++) {
ab->qmi.target_mem[i].type = msg->mem_seg[i].type;
ab->qmi.target_mem[i].size = msg->mem_seg[i].size;
- ath12k_dbg(ab, ATH12K_DBG_QMI, "qmi mem seg type %d size %d\n",
+ ath12k_dbg(ab, ATH12K_DBG_QMI, "qmi mem seg type %d size %u\n",
msg->mem_seg[i].type, msg->mem_seg[i].size);
}
@@ -3954,7 +3960,7 @@ static int ath12k_qmi_event_host_cap(struct ath12k_qmi *qmi)
ret = ath12k_qmi_host_cap_send(ab);
if (ret < 0) {
- ath12k_warn(ab, "failed to send qmi host cap for device id %d: %d\n",
+ ath12k_warn(ab, "failed to send qmi host cap for device id %u: %d\n",
ab->device_id, ret);
return ret;
}
@@ -4024,7 +4030,7 @@ static void ath12k_qmi_driver_event_work(struct work_struct *work)
set_bit(ATH12K_FLAG_QMI_FAIL, &ab->dev_flags);
break;
default:
- ath12k_warn(ab, "invalid event type: %d", event->type);
+ ath12k_warn(ab, "invalid event type: %d\n", event->type);
break;
}
diff --git a/drivers/net/wireless/ath/ath12k/qmi.h b/drivers/net/wireless/ath/ath12k/qmi.h
index 2a63e214eb42c..80a9b42a25484 100644
--- a/drivers/net/wireless/ath/ath12k/qmi.h
+++ b/drivers/net/wireless/ath/ath12k/qmi.h
@@ -13,7 +13,6 @@
#define ATH12K_HOST_VERSION_STRING "WIN"
#define ATH12K_QMI_WLANFW_TIMEOUT_MS 10000
#define ATH12K_QMI_MAX_BDF_FILE_NAME_SIZE 64
-#define ATH12K_QMI_CALDB_ADDRESS 0x4BA00000
#define ATH12K_QMI_WLANFW_MAX_BUILD_ID_LEN_V01 128
#define ATH12K_QMI_WLFW_SERVICE_VERS_V01 0x01
#define ATH12K_QMI_WLFW_SERVICE_INS_ID_V01 0x02
@@ -24,9 +23,7 @@
#define ATH12K_QMI_WLANFW_MAX_TIMESTAMP_LEN_V01 32
#define ATH12K_QMI_RESP_LEN_MAX 8192
#define ATH12K_QMI_WLANFW_MAX_NUM_MEM_SEG_V01 52
-#define ATH12K_QMI_CALDB_SIZE 0x480000
#define ATH12K_QMI_BDF_EXT_STR_LENGTH 0x20
-#define ATH12K_QMI_FW_MEM_REQ_SEGMENT_CNT 3
#define ATH12K_QMI_WLFW_MAX_DEV_MEM_NUM_V01 4
#define ATH12K_QMI_DEVMEM_CMEM_INDEX 0
@@ -160,8 +157,6 @@ struct ath12k_qmi {
#define QMI_WLANFW_HOST_CAP_REQ_MSG_V01_MAX_LEN 261
#define QMI_WLANFW_HOST_CAP_REQ_V01 0x0034
-#define QMI_WLANFW_HOST_CAP_RESP_MSG_V01_MAX_LEN 7
-#define QMI_WLFW_HOST_CAP_RESP_V01 0x0034
#define QMI_WLFW_MAX_NUM_GPIO_V01 32
#define QMI_WLANFW_MAX_PLATFORM_NAME_LEN_V01 64
#define QMI_WLANFW_MAX_HOST_DDR_RANGE_SIZE_V01 3
@@ -267,8 +262,6 @@ struct qmi_wlanfw_host_cap_resp_msg_v01 {
#define QMI_WLANFW_PHY_CAP_REQ_MSG_V01_MAX_LEN 0
#define QMI_WLANFW_PHY_CAP_REQ_V01 0x0057
-#define QMI_WLANFW_PHY_CAP_RESP_MSG_V01_MAX_LEN 18
-#define QMI_WLANFW_PHY_CAP_RESP_V01 0x0057
struct qmi_wlanfw_phy_cap_req_msg_v01 {
};
@@ -285,8 +278,6 @@ struct qmi_wlanfw_phy_cap_resp_msg_v01 {
#define QMI_WLANFW_IND_REGISTER_REQ_MSG_V01_MAX_LEN 54
#define QMI_WLANFW_IND_REGISTER_REQ_V01 0x0020
-#define QMI_WLANFW_IND_REGISTER_RESP_MSG_V01_MAX_LEN 18
-#define QMI_WLANFW_IND_REGISTER_RESP_V01 0x0020
#define QMI_WLANFW_CLIENT_ID 0x4b4e454c
struct qmi_wlanfw_ind_register_req_msg_v01 {
@@ -322,12 +313,8 @@ struct qmi_wlanfw_ind_register_resp_msg_v01 {
u64 fw_status;
};
-#define QMI_WLANFW_REQUEST_MEM_IND_MSG_V01_MAX_LEN 1824
#define QMI_WLANFW_RESPOND_MEM_REQ_MSG_V01_MAX_LEN 888
-#define QMI_WLANFW_RESPOND_MEM_RESP_MSG_V01_MAX_LEN 7
-#define QMI_WLANFW_REQUEST_MEM_IND_V01 0x0035
#define QMI_WLANFW_RESPOND_MEM_REQ_V01 0x0036
-#define QMI_WLANFW_RESPOND_MEM_RESP_V01 0x0036
#define QMI_WLANFW_MAX_NUM_MEM_CFG_V01 2
#define QMI_WLANFW_MAX_STR_LEN_V01 16
@@ -385,9 +372,7 @@ struct qmi_wlanfw_fw_ready_ind_msg_v01 {
};
#define QMI_WLANFW_CAP_REQ_MSG_V01_MAX_LEN 0
-#define QMI_WLANFW_CAP_RESP_MSG_V01_MAX_LEN 207
#define QMI_WLANFW_CAP_REQ_V01 0x0024
-#define QMI_WLANFW_CAP_RESP_V01 0x0024
enum qmi_wlanfw_pipedir_enum_v01 {
QMI_WLFW_PIPEDIR_NONE_V01 = 0,
@@ -500,8 +485,6 @@ struct qmi_wlanfw_cap_req_msg_v01 {
};
#define QMI_WLANFW_BDF_DOWNLOAD_REQ_MSG_V01_MAX_LEN 6182
-#define QMI_WLANFW_BDF_DOWNLOAD_RESP_MSG_V01_MAX_LEN 7
-#define QMI_WLANFW_BDF_DOWNLOAD_RESP_V01 0x0025
#define QMI_WLANFW_BDF_DOWNLOAD_REQ_V01 0x0025
/* TODO: Need to check with MCL and FW team that data can be pointer and
* can be last element in structure
@@ -529,8 +512,6 @@ struct qmi_wlanfw_bdf_download_resp_msg_v01 {
};
#define QMI_WLANFW_M3_INFO_REQ_MSG_V01_MAX_MSG_LEN 18
-#define QMI_WLANFW_M3_INFO_RESP_MSG_V01_MAX_MSG_LEN 7
-#define QMI_WLANFW_M3_INFO_RESP_V01 0x003C
#define QMI_WLANFW_M3_INFO_REQ_V01 0x003C
struct qmi_wlanfw_m3_info_req_msg_v01 {
@@ -543,7 +524,6 @@ struct qmi_wlanfw_m3_info_resp_msg_v01 {
};
#define QMI_WLANFW_AUX_UC_INFO_REQ_MSG_V01_MAX_MSG_LEN 18
-#define QMI_WLANFW_AUX_UC_INFO_RESP_MSG_V01_MAX_MSG_LEN 7
#define QMI_WLANFW_AUX_UC_INFO_REQ_V01 0x005A
struct qmi_wlanfw_aux_uc_info_req_msg_v01 {
@@ -556,13 +536,9 @@ struct qmi_wlanfw_aux_uc_info_resp_msg_v01 {
};
#define QMI_WLANFW_WLAN_MODE_REQ_MSG_V01_MAX_LEN 11
-#define QMI_WLANFW_WLAN_MODE_RESP_MSG_V01_MAX_LEN 7
#define QMI_WLANFW_WLAN_CFG_REQ_MSG_V01_MAX_LEN 803
-#define QMI_WLANFW_WLAN_CFG_RESP_MSG_V01_MAX_LEN 7
#define QMI_WLANFW_WLAN_MODE_REQ_V01 0x0022
-#define QMI_WLANFW_WLAN_MODE_RESP_V01 0x0022
#define QMI_WLANFW_WLAN_CFG_REQ_V01 0x0023
-#define QMI_WLANFW_WLAN_CFG_RESP_V01 0x0023
#define QMI_WLANFW_MAX_STR_LEN_V01 16
#define QMI_WLANFW_MAX_NUM_CE_V01 12
#define QMI_WLANFW_MAX_NUM_SVC_V01 24
@@ -605,9 +581,7 @@ struct qmi_wlanfw_wlan_cfg_resp_msg_v01 {
};
#define ATH12K_QMI_WLANFW_WLAN_INI_REQ_V01 0x002F
-#define ATH12K_QMI_WLANFW_WLAN_INI_RESP_V01 0x002F
#define QMI_WLANFW_WLAN_INI_REQ_MSG_V01_MAX_LEN 7
-#define QMI_WLANFW_WLAN_INI_RESP_MSG_V01_MAX_LEN 7
struct qmi_wlanfw_wlan_ini_req_msg_v01 {
/* Must be set to true if enable_fwlog is being passed */
diff --git a/drivers/net/wireless/ath/ath12k/wifi7/dp_mon.c b/drivers/net/wireless/ath/ath12k/wifi7/dp_mon.c
index 7dd4a49d64d5f..016b0c38e51e2 100644
--- a/drivers/net/wireless/ath/ath12k/wifi7/dp_mon.c
+++ b/drivers/net/wireless/ath/ath12k/wifi7/dp_mon.c
@@ -1565,16 +1565,17 @@ ath12k_wifi7_dp_mon_parse_status_msdu_end(struct ath12k_mon_data *pmon,
static enum hal_rx_mon_status
ath12k_wifi7_dp_mon_rx_parse_status_tlv(struct ath12k_pdev_dp *dp_pdev,
struct ath12k_mon_data *pmon,
- const struct hal_tlv_64_hdr *tlv)
+ const void *tlv)
{
struct hal_rx_mon_ppdu_info *ppdu_info = &pmon->mon_ppdu_info;
- const void *tlv_data = tlv->value;
- u32 info[7], userid;
- u16 tlv_tag, tlv_len;
+ struct ath12k *ar = ath12k_pdev_dp_to_ar(dp_pdev);
+ struct ath12k_hal *hal = &ar->ab->hal;
+ u16 tlv_tag, tlv_len, userid;
+ void *tlv_data;
+ u32 info[7];
- tlv_tag = le64_get_bits(tlv->tl, HAL_TLV_64_HDR_TAG);
- tlv_len = le64_get_bits(tlv->tl, HAL_TLV_64_HDR_LEN);
- userid = le64_get_bits(tlv->tl, HAL_TLV_64_USR_ID);
+ tlv_data = hal->ops->mon_rx_status_dec_tlv_hdr((void *)tlv, &tlv_tag,
+ &tlv_len, &userid);
if (ppdu_info->tlv_aggr.in_progress && ppdu_info->tlv_aggr.tlv_tag != tlv_tag) {
ath12k_wifi7_dp_mon_parse_eht_sig_hdr(ppdu_info,
@@ -2480,7 +2481,6 @@ ath12k_wifi7_dp_mon_rx_deliver(struct ath12k_pdev_dp *dp_pdev,
{
struct sk_buff *mon_skb, *skb_next, *header;
struct ieee80211_rx_status *rxs = &dp_pdev->rx_status;
- u8 decap = DP_RX_DECAP_TYPE_RAW;
mon_skb = ath12k_dp_mon_rx_merg_msdus(dp_pdev, mon_mpdu, ppduinfo, rxs);
if (!mon_skb)
@@ -2507,12 +2507,8 @@ ath12k_wifi7_dp_mon_rx_deliver(struct ath12k_pdev_dp *dp_pdev,
}
rxs->flag |= RX_FLAG_ONLY_MONITOR;
- if (!(rxs->flag & RX_FLAG_ONLY_MONITOR))
- decap = mon_mpdu->decap_format;
-
ath12k_dp_mon_update_radiotap(dp_pdev, ppduinfo, mon_skb, rxs);
- ath12k_dp_mon_rx_deliver_msdu(dp_pdev, napi, mon_skb, ppduinfo,
- rxs, decap);
+ ath12k_dp_mon_rx_deliver_msdu(dp_pdev, napi, mon_skb, rxs);
mon_skb = skb_next;
} while (mon_skb);
rxs->flag = 0;
@@ -2930,11 +2926,12 @@ static enum dp_mon_status_buf_state
ath12k_wifi7_dp_rx_mon_buf_done(struct ath12k_base *ab, struct hal_srng *srng,
struct dp_rxdma_mon_ring *rx_ring)
{
+ struct ath12k_hal *hal = &ab->hal;
struct ath12k_skb_rxcb *rxcb;
- struct hal_tlv_64_hdr *tlv;
struct sk_buff *skb;
void *status_desc;
dma_addr_t paddr;
+ u16 tlv_tag;
u32 cookie;
int buf_id;
u8 rbm;
@@ -2959,8 +2956,8 @@ ath12k_wifi7_dp_rx_mon_buf_done(struct ath12k_base *ab, struct hal_srng *srng,
skb->len + skb_tailroom(skb),
DMA_FROM_DEVICE);
- tlv = (struct hal_tlv_64_hdr *)skb->data;
- if (le64_get_bits(tlv->tl, HAL_TLV_HDR_TAG) != HAL_RX_STATUS_BUFFER_DONE)
+ hal->ops->mon_rx_status_dec_tlv_hdr(skb->data, &tlv_tag, NULL, NULL);
+ if (tlv_tag != HAL_RX_STATUS_BUFFER_DONE)
return DP_MON_STATUS_NO_DMA;
return DP_MON_STATUS_REPLINISH;
@@ -2972,41 +2969,40 @@ ath12k_wifi7_dp_mon_parse_rx_dest(struct ath12k_pdev_dp *dp_pdev,
struct sk_buff *skb)
{
struct ath12k *ar = ath12k_pdev_dp_to_ar(dp_pdev);
- struct hal_tlv_64_hdr *tlv;
+ struct ath12k_hal *hal = &ar->ab->hal;
+ u8 *tlv_value, *tlv = skb->data;
struct ath12k_skb_rxcb *rxcb;
enum hal_rx_mon_status hal_status;
u16 tlv_tag, tlv_len;
- u8 *ptr = skb->data;
+ u32 tlv_hdr_len;
+
+ tlv_hdr_len = hal->ops->get_tlv_hdr_align();
do {
- tlv = (struct hal_tlv_64_hdr *)ptr;
- tlv_tag = le64_get_bits(tlv->tl, HAL_TLV_64_HDR_TAG);
+ tlv_value = hal->ops->mon_rx_status_dec_tlv_hdr(tlv, &tlv_tag,
+ &tlv_len, NULL);
/* The actual length of PPDU_END is the combined length of many PHY
* TLVs that follow. Skip the TLV header and
* rx_rxpcu_classification_overview that follows the header to get to
* next TLV.
*/
-
if (tlv_tag == HAL_RX_PPDU_END)
tlv_len = sizeof(struct hal_rx_rxpcu_classification_overview);
- else
- tlv_len = le64_get_bits(tlv->tl, HAL_TLV_64_HDR_LEN);
hal_status = ath12k_wifi7_dp_mon_rx_parse_status_tlv(dp_pdev, pmon,
tlv);
if (ar->monitor_started && ar->ab->hw_params->rxdma1_enable &&
ath12k_wifi7_dp_mon_parse_rx_dest_tlv(dp_pdev, pmon, hal_status,
- tlv->value))
+ tlv_value))
return HAL_RX_MON_STATUS_PPDU_DONE;
- ptr += sizeof(*tlv) + tlv_len;
- ptr = PTR_ALIGN(ptr, HAL_TLV_64_ALIGN);
+ tlv = PTR_ALIGN(tlv + tlv_len + tlv_hdr_len, tlv_hdr_len);
- if ((ptr - skb->data) > skb->len)
+ if (unlikely(tlv - skb->data > skb->len ||
+ skb->len - (tlv - skb->data) < tlv_hdr_len))
break;
-
} while ((hal_status == HAL_RX_MON_STATUS_PPDU_NOT_DONE) ||
(hal_status == HAL_RX_MON_STATUS_BUF_ADDR) ||
(hal_status == HAL_RX_MON_STATUS_MPDU_START) ||
@@ -3056,15 +3052,16 @@ ath12k_wifi7_dp_rx_reap_mon_status_ring(struct ath12k_base *ab, int mac_id,
int buf_id, srng_id, num_buffs_reaped = 0;
enum dp_mon_status_buf_state reap_status;
struct dp_rxdma_mon_ring *rx_ring;
+ struct ath12k_hal *hal = &ab->hal;
struct ath12k_mon_data *pmon;
struct ath12k_skb_rxcb *rxcb;
- struct hal_tlv_64_hdr *tlv;
void *rx_mon_status_desc;
struct hal_srng *srng;
struct ath12k_dp *dp;
struct sk_buff *skb;
struct ath12k *ar;
dma_addr_t paddr;
+ u16 tlv_tag;
u32 cookie;
u8 rbm;
@@ -3109,14 +3106,13 @@ ath12k_wifi7_dp_rx_reap_mon_status_ring(struct ath12k_base *ab, int mac_id,
skb->len + skb_tailroom(skb),
DMA_FROM_DEVICE);
- tlv = (struct hal_tlv_64_hdr *)skb->data;
- if (le64_get_bits(tlv->tl, HAL_TLV_HDR_TAG) !=
- HAL_RX_STATUS_BUFFER_DONE) {
+ hal->ops->mon_rx_status_dec_tlv_hdr(skb->data, &tlv_tag,
+ NULL, NULL);
+ if (tlv_tag != HAL_RX_STATUS_BUFFER_DONE) {
pmon->buf_state = DP_MON_STATUS_NO_DMA;
ath12k_warn(ab,
- "mon status DONE not set %llx, buf_id %d\n",
- le64_get_bits(tlv->tl, HAL_TLV_HDR_TAG),
- buf_id);
+ "mon status DONE not set %x, buf_id %d\n",
+ tlv_tag, buf_id);
/* RxDMA status done bit might not be set even
* though tp is moved by HW.
*/
diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hal_qcc2072.c b/drivers/net/wireless/ath/ath12k/wifi7/hal_qcc2072.c
index 8cebb229ebed8..7cf00fda996f3 100644
--- a/drivers/net/wireless/ath/ath12k/wifi7/hal_qcc2072.c
+++ b/drivers/net/wireless/ath/ath12k/wifi7/hal_qcc2072.c
@@ -455,7 +455,7 @@ static u16 ath12k_hal_reo_status_dec_tlv_hdr_qcc2072(void *tlv, void **desc)
struct hal_reo_get_queue_stats_status_qcc2072 *status_tlv;
u16 tag;
- tag = ath12k_hal_decode_tlv32_hdr(tlv, (void **)&status_tlv);
+ status_tlv = ath12k_hal_decode_tlv32_hdr(tlv, &tag, NULL, NULL);
/*
* actual desc of REO status entry starts after tlv32_padding,
* see hal_reo_get_queue_stats_status_qcc2072
@@ -506,6 +506,8 @@ const struct hal_ops hal_qcc2072_ops = {
.rx_reo_ent_buf_paddr_get = ath12k_wifi7_hal_rx_reo_ent_buf_paddr_get,
.reo_cmd_enc_tlv_hdr = ath12k_hal_encode_tlv32_hdr,
.reo_status_dec_tlv_hdr = ath12k_hal_reo_status_dec_tlv_hdr_qcc2072,
+ .mon_rx_status_dec_tlv_hdr = ath12k_hal_decode_tlv32_hdr,
+ .get_tlv_hdr_align = ath12k_hal_get_tlv32_hdr_align,
};
u32 ath12k_hal_rx_desc_get_mpdu_start_offset_qcc2072(void)
diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hal_qcn9274.c b/drivers/net/wireless/ath/ath12k/wifi7/hal_qcn9274.c
index 9d5180ef83b48..052b59265af85 100644
--- a/drivers/net/wireless/ath/ath12k/wifi7/hal_qcn9274.c
+++ b/drivers/net/wireless/ath/ath12k/wifi7/hal_qcn9274.c
@@ -950,6 +950,15 @@ void ath12k_hal_extract_rx_desc_data_qcn9274(struct hal_rx_desc_data *rx_desc_da
rx_desc_data->err_bitmap = ath12k_hal_rx_h_mpdu_err_qcn9274(rx_desc);
}
+static u16 ath12k_hal_reo_status_dec_tlv_hdr_qcn9274(void *tlv, void **desc)
+{
+ u16 tag;
+
+ *desc = ath12k_hal_decode_tlv64_hdr(tlv, &tag, NULL, NULL);
+
+ return tag;
+}
+
const struct ath12k_hw_hal_params ath12k_hw_hal_params_qcn9274 = {
.rx_buf_rbm = HAL_RX_BUF_RBM_SW3_BM,
.wbm2sw_cc_enable = HAL_WBM_SW_COOKIE_CONV_CFG_WBM2SW0_EN |
@@ -1138,5 +1147,7 @@ const struct hal_ops hal_qcn9274_ops = {
.rx_msdu_list_get = ath12k_wifi7_hal_rx_msdu_list_get,
.rx_reo_ent_buf_paddr_get = ath12k_wifi7_hal_rx_reo_ent_buf_paddr_get,
.reo_cmd_enc_tlv_hdr = ath12k_hal_encode_tlv64_hdr,
- .reo_status_dec_tlv_hdr = ath12k_hal_decode_tlv64_hdr,
+ .reo_status_dec_tlv_hdr = ath12k_hal_reo_status_dec_tlv_hdr_qcn9274,
+ .mon_rx_status_dec_tlv_hdr = ath12k_hal_decode_tlv64_hdr,
+ .get_tlv_hdr_align = ath12k_hal_get_tlv64_hdr_align,
};
diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hal_wcn7850.c b/drivers/net/wireless/ath/ath12k/wifi7/hal_wcn7850.c
index efbbc1cbd3e42..61be8443e46ee 100644
--- a/drivers/net/wireless/ath/ath12k/wifi7/hal_wcn7850.c
+++ b/drivers/net/wireless/ath/ath12k/wifi7/hal_wcn7850.c
@@ -756,6 +756,15 @@ int ath12k_hal_srng_create_config_wcn7850(struct ath12k_hal *hal)
return 0;
}
+static u16 ath12k_hal_reo_status_dec_tlv_hdr_wcn7850(void *tlv, void **desc)
+{
+ u16 tag;
+
+ *desc = ath12k_hal_decode_tlv64_hdr(tlv, &tag, NULL, NULL);
+
+ return tag;
+}
+
const struct ath12k_hal_tcl_to_wbm_rbm_map
ath12k_hal_tcl_to_wbm_rbm_map_wcn7850[DP_TCL_NUM_RING_MAX] = {
{
@@ -821,5 +830,7 @@ const struct hal_ops hal_wcn7850_ops = {
.rx_msdu_list_get = ath12k_wifi7_hal_rx_msdu_list_get,
.rx_reo_ent_buf_paddr_get = ath12k_wifi7_hal_rx_reo_ent_buf_paddr_get,
.reo_cmd_enc_tlv_hdr = ath12k_hal_encode_tlv64_hdr,
- .reo_status_dec_tlv_hdr = ath12k_hal_decode_tlv64_hdr,
+ .reo_status_dec_tlv_hdr = ath12k_hal_reo_status_dec_tlv_hdr_wcn7850,
+ .mon_rx_status_dec_tlv_hdr = ath12k_hal_decode_tlv64_hdr,
+ .get_tlv_hdr_align = ath12k_hal_get_tlv64_hdr_align,
};
diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hw.c b/drivers/net/wireless/ath/ath12k/wifi7/hw.c
index 3d59fa452ec03..e5bf9d2181040 100644
--- a/drivers/net/wireless/ath/ath12k/wifi7/hw.c
+++ b/drivers/net/wireless/ath/ath12k/wifi7/hw.c
@@ -903,6 +903,7 @@ static void ath12k_wifi7_mac_op_tx(struct ieee80211_hw *hw,
struct ethhdr *eth;
bool is_prb_rsp;
u16 mcbc_gsn;
+ u8 cb_flags;
u8 link_id;
int ret;
struct ath12k_dp *tmp_dp;
@@ -996,8 +997,13 @@ static void ath12k_wifi7_mac_op_tx(struct ieee80211_hw *hw,
ieee80211_has_protected(hdr->frame_control))
is_dvlan = true;
+ /*
+ * Add a sta pointer check to differentiate multicast encapsulation
+ * offload packets, as the ATH12K_SKB_HW_80211_ENCAP flag is also set
+ * for such packets.
+ */
if (!vif->valid_links || !is_mcast || is_dvlan ||
- (skb_cb->flags & ATH12K_SKB_HW_80211_ENCAP) ||
+ ((skb_cb->flags & ATH12K_SKB_HW_80211_ENCAP) && sta) ||
test_bit(ATH12K_FLAG_RAW_MODE, &ar->ab->dev_flags)) {
ret = ath12k_wifi7_dp_tx(dp_pdev, arvif, arsta, skb, false, 0, is_mcast);
if (unlikely(ret)) {
@@ -1009,6 +1015,7 @@ static void ath12k_wifi7_mac_op_tx(struct ieee80211_hw *hw,
mcbc_gsn = atomic_inc_return(&ahvif->dp_vif.mcbc_gsn) & 0xfff;
links_map = ahvif->links_map;
+ cb_flags = skb_cb->flags;
for_each_set_bit(link_id, &links_map,
IEEE80211_MLD_MAX_NUM_LINKS) {
tmp_arvif = rcu_dereference(ahvif->link[link_id]);
@@ -1016,21 +1023,45 @@ static void ath12k_wifi7_mac_op_tx(struct ieee80211_hw *hw,
continue;
tmp_ar = tmp_arvif->ar;
- tmp_dp_pdev = ath12k_dp_to_pdev_dp(tmp_ar->ab->dp,
+ tmp_dp = ath12k_ab_to_dp(tmp_ar->ab);
+ tmp_dp_pdev = ath12k_dp_to_pdev_dp(tmp_dp,
tmp_ar->pdev_idx);
if (!tmp_dp_pdev)
continue;
- msdu_copied = skb_copy(skb, GFP_ATOMIC);
- if (!msdu_copied) {
- ath12k_err(ar->ab,
- "skb copy failure link_id 0x%X vdevid 0x%X\n",
- link_id, tmp_arvif->vdev_id);
- continue;
- }
- ath12k_mlo_mcast_update_tx_link_address(vif, link_id,
- msdu_copied,
- info_flags);
+ if (cb_flags & ATH12K_SKB_HW_80211_ENCAP) {
+ /*
+ * skb->data may be modified for the iova_mask devices.
+ * It is better to use skb_copy() for such devices
+ * to avoid any potential skb corruption related issues.
+ */
+ if (tmp_dp->hw_params->iova_mask)
+ msdu_copied = skb_copy(skb, GFP_ATOMIC);
+ else
+ /*
+ * ath12k_wifi7_dp_tx() should treat cloned HW-encap
+ * Ethernet multicast frames as read-only.
+ */
+ msdu_copied = skb_clone(skb, GFP_ATOMIC);
+ if (!msdu_copied) {
+ ath12k_err(ar->ab,
+ "skb copy/clone failure link_id 0x%X vdevid 0x%X\n",
+ link_id, tmp_arvif->vdev_id);
+ continue;
+ }
+ } else {
+ msdu_copied = skb_copy(skb, GFP_ATOMIC);
+ if (!msdu_copied) {
+ ath12k_err(ar->ab,
+ "skb copy failure link_id 0x%X vdevid 0x%X\n",
+ link_id, tmp_arvif->vdev_id);
+ continue;
+ }
+
+ ath12k_mlo_mcast_update_tx_link_address(vif, link_id,
+ msdu_copied,
+ info_flags);
+ }
skb_cb = ATH12K_SKB_CB(msdu_copied);
skb_cb->link_id = link_id;
@@ -1046,7 +1077,6 @@ static void ath12k_wifi7_mac_op_tx(struct ieee80211_hw *hw,
if (unlikely(!ahvif->dp_vif.key_cipher))
goto skip_peer_find;
- tmp_dp = ath12k_ab_to_dp(tmp_ar->ab);
spin_lock_bh(&tmp_dp->dp_lock);
peer = ath12k_dp_link_peer_find_by_addr(tmp_dp,
tmp_arvif->bssid);
@@ -1065,11 +1095,16 @@ static void ath12k_wifi7_mac_op_tx(struct ieee80211_hw *hw,
skb_cb->cipher = key->cipher;
skb_cb->flags |= ATH12K_SKB_CIPHER_SET;
+ if (skb_cb->flags & ATH12K_SKB_HW_80211_ENCAP)
+ goto skip_fctl_protected_check;
+
hdr = (struct ieee80211_hdr *)msdu_copied->data;
if (!ieee80211_has_protected(hdr->frame_control))
hdr->frame_control |=
cpu_to_le16(IEEE80211_FCTL_PROTECTED);
}
+
+skip_fctl_protected_check:
spin_unlock_bh(&tmp_dp->dp_lock);
skip_peer_find:
diff --git a/drivers/net/wireless/ath/ath12k/wmi.c b/drivers/net/wireless/ath/ath12k/wmi.c
index 84a31b953db81..ad739bffcf88f 100644
--- a/drivers/net/wireless/ath/ath12k/wmi.c
+++ b/drivers/net/wireless/ath/ath12k/wmi.c
@@ -1228,10 +1228,14 @@ int ath12k_wmi_vdev_start(struct ath12k *ar, struct wmi_vdev_start_req_arg *arg,
le32_encode_bits(arg->ml.mcast_link,
ATH12K_WMI_FLAG_MLO_MCAST_VDEV) |
le32_encode_bits(arg->ml.link_add,
- ATH12K_WMI_FLAG_MLO_LINK_ADD);
+ ATH12K_WMI_FLAG_MLO_LINK_ADD) |
+ cpu_to_le32(ATH12K_WMI_FLAG_MLO_IEEE_LINK_IDX_VALID);
- ath12k_dbg(ar->ab, ATH12K_DBG_WMI, "vdev %d start ml flags 0x%x\n",
- arg->vdev_id, ml_params->flags);
+ ml_params->ieee_link_id = cpu_to_le32(arg->ml.ieee_link_id);
+
+ ath12k_dbg(ar->ab, ATH12K_DBG_WMI, "vdev %u start link_id %u ml flags 0x%x\n",
+ arg->vdev_id, arg->ml.ieee_link_id,
+ le32_to_cpu(ml_params->flags));
ptr += sizeof(*ml_params);
@@ -1244,19 +1248,23 @@ int ath12k_wmi_vdev_start(struct ath12k *ar, struct wmi_vdev_start_req_arg *arg,
partner_info = ptr;
for (i = 0; i < arg->ml.num_partner_links; i++) {
+ struct wmi_ml_partner_info *pinfo = &arg->ml.partner_info[i];
+
partner_info->tlv_header =
ath12k_wmi_tlv_cmd_hdr(WMI_TAG_MLO_PARTNER_LINK_PARAMS,
sizeof(*partner_info));
- partner_info->vdev_id =
- cpu_to_le32(arg->ml.partner_info[i].vdev_id);
- partner_info->hw_link_id =
- cpu_to_le32(arg->ml.partner_info[i].hw_link_id);
+ partner_info->vdev_id = cpu_to_le32(pinfo->vdev_id);
+ partner_info->hw_link_id = cpu_to_le32(pinfo->hw_link_id);
ether_addr_copy(partner_info->vdev_addr.addr,
- arg->ml.partner_info[i].addr);
+ pinfo->addr);
+ partner_info->flags =
+ cpu_to_le32(ATH12K_WMI_FLAG_MLO_IEEE_LINK_IDX_VALID_PARTNER);
+ partner_info->ieee_link_id = cpu_to_le32(pinfo->ieee_link_id);
- ath12k_dbg(ar->ab, ATH12K_DBG_WMI, "partner vdev %d hw_link_id %d macaddr%pM\n",
- partner_info->vdev_id, partner_info->hw_link_id,
- partner_info->vdev_addr.addr);
+ ath12k_dbg(ar->ab, ATH12K_DBG_WMI, "partner vdev %u hw_link_id %u macaddr %pM link_id %u ml flags 0x%x\n",
+ pinfo->vdev_id, pinfo->hw_link_id,
+ pinfo->addr, pinfo->ieee_link_id,
+ le32_to_cpu(partner_info->flags));
partner_info++;
}
@@ -5154,6 +5162,7 @@ static void ath12k_wmi_eht_caps_parse(struct ath12k_pdev *pdev, u32 band,
__le32 cap_info_internal)
{
struct ath12k_band_cap *cap_band = &pdev->cap.band[band];
+ u8 *phy_cap = (u8 *)&cap_band->eht_cap_phy_info[0];
u32 support_320mhz;
u8 i;
@@ -5167,8 +5176,22 @@ static void ath12k_wmi_eht_caps_parse(struct ath12k_pdev *pdev, u32 band,
for (i = 0; i < WMI_MAX_EHTCAP_PHY_SIZE; i++)
cap_band->eht_cap_phy_info[i] = le32_to_cpu(cap_phy_info[i]);
- if (band == NL80211_BAND_6GHZ)
+ if (band == NL80211_BAND_6GHZ) {
cap_band->eht_cap_phy_info[0] |= support_320mhz;
+ } else {
+ /*
+ * Firmware may report 6 GHz/320 MHz specific capabilities for
+ * non-6 GHz bands, so explicitly clear them.
+ */
+ phy_cap[0] &= ~IEEE80211_EHT_PHY_CAP0_320MHZ_IN_6GHZ;
+ phy_cap[1] &= ~IEEE80211_EHT_PHY_CAP1_BEAMFORMEE_SS_320MHZ_MASK;
+ phy_cap[2] &= ~IEEE80211_EHT_PHY_CAP2_SOUNDING_DIM_320MHZ_MASK;
+ phy_cap[3] &= ~IEEE80211_EHT_PHY_CAP3_SOUNDING_DIM_320MHZ_MASK;
+ phy_cap[6] &= ~IEEE80211_EHT_PHY_CAP6_MCS15_SUPP_320MHZ;
+ phy_cap[6] &= ~IEEE80211_EHT_PHY_CAP6_EHT_DUP_6GHZ_SUPP;
+ phy_cap[7] &= ~IEEE80211_EHT_PHY_CAP7_NON_OFDMA_UL_MU_MIMO_320MHZ;
+ phy_cap[7] &= ~IEEE80211_EHT_PHY_CAP7_MU_BEAMFORMER_320MHZ;
+ }
cap_band->eht_mcs_20_only = le32_to_cpu(supp_mcs[0]);
cap_band->eht_mcs_80 = le32_to_cpu(supp_mcs[1]);
diff --git a/drivers/net/wireless/ath/ath12k/wmi.h b/drivers/net/wireless/ath/ath12k/wmi.h
index c452e3d57a29a..51f3426e1fcd9 100644
--- a/drivers/net/wireless/ath/ath12k/wmi.h
+++ b/drivers/net/wireless/ath/ath12k/wmi.h
@@ -2954,10 +2954,13 @@ struct wmi_vdev_create_mlo_params {
#define ATH12K_WMI_FLAG_MLO_EMLSR_SUPPORT BIT(6)
#define ATH12K_WMI_FLAG_MLO_FORCED_INACTIVE BIT(7)
#define ATH12K_WMI_FLAG_MLO_LINK_ADD BIT(8)
+#define ATH12K_WMI_FLAG_MLO_IEEE_LINK_IDX_VALID BIT(18)
+#define ATH12K_WMI_FLAG_MLO_IEEE_LINK_IDX_VALID_PARTNER BIT(19)
struct wmi_vdev_start_mlo_params {
__le32 tlv_header;
__le32 flags;
+ __le32 ieee_link_id;
} __packed;
struct wmi_partner_link_info {
@@ -2965,6 +2968,8 @@ struct wmi_partner_link_info {
__le32 vdev_id;
__le32 hw_link_id;
struct ath12k_wmi_mac_addr_params vdev_addr;
+ __le32 flags;
+ __le32 ieee_link_id;
} __packed;
struct wmi_vdev_delete_cmd {
@@ -3120,6 +3125,7 @@ struct wmi_ml_partner_info {
bool primary_umac;
bool logical_link_idx_valid;
u32 logical_link_idx;
+ u32 ieee_link_id;
};
struct wmi_ml_arg {
@@ -3127,6 +3133,7 @@ struct wmi_ml_arg {
bool assoc_link;
bool mcast_link;
bool link_add;
+ u32 ieee_link_id;
u8 num_partner_links;
struct wmi_ml_partner_info partner_info[ATH12K_WMI_MLO_MAX_LINKS];
};
diff --git a/kernel/irq/manage.c b/kernel/irq/manage.c
index 7eb07e3bdb4c2..f73fda08417ab 100644
--- a/kernel/irq/manage.c
+++ b/kernel/irq/manage.c
@@ -171,6 +171,7 @@ int irq_can_set_affinity(unsigned int irq)
{
return __irq_can_set_affinity(irq_to_desc(irq));
}
+EXPORT_SYMBOL_GPL(irq_can_set_affinity);
/**
* irq_can_set_affinity_usr - Check if affinity of a irq can be set from user space