diff options
| author | Jeff Johnson <jeff.johnson@oss.qualcomm.com> | 2026-06-30 14:28:50 -0700 |
|---|---|---|
| committer | Jeff Johnson <jeff.johnson@oss.qualcomm.com> | 2026-06-30 14:28:50 -0700 |
| commit | 0e6c3476fe2074826e4f0c6f8575b9464496f707 (patch) | |
| tree | ad416085b85ce9190ecf08a78a6a133bb4364a34 | |
| parent | 7ac20fad74bd5b59f68fba6af689cf115d0538a2 (diff) | |
| parent | 913998f903fb1432c0046c33003db38a9e8bedb1 (diff) | |
| download | ath-0e6c3476fe2074826e4f0c6f8575b9464496f707.tar.gz | |
Merge branch 'ath-next'
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 |
