From: Sowmiya Sree Elavalagan Store MSI data values for each interrupt vector during configuration and use them for ring setup on hybrid devices. Hybrid devices require explicit MSI data values rather than calculated offsets. Add ce_msi_data and dp_msi_data arrays to store values captured from MSI descriptors. Use stored values for ring configuration on QCN6432, ensuring hardware uses exact platform MSI allocated values. Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.6-01243-QCAHKSWPL_SILICONZ-1 Tested-on: IPQ5332 hw1.0 AHB WLAN.WBE.1.6-01322-QCAHKSWPL_SILICONZ-1 Tested-on: QCN6432 hw1.0 AHB WLAN.WBE.1.6-01322-QCAHKSWPL_SILICONZ-1 Signed-off-by: Sowmiya Sree Elavalagan Co-developed-by: Aaradhana Sahu Signed-off-by: Aaradhana Sahu --- drivers/net/wireless/ath/ath12k/ce.c | 7 ++++++- drivers/net/wireless/ath/ath12k/core.h | 2 ++ drivers/net/wireless/ath/ath12k/dp.c | 9 +++++++-- drivers/net/wireless/ath/ath12k/pcic.c | 2 ++ 4 files changed, 17 insertions(+), 3 deletions(-) diff --git a/drivers/net/wireless/ath/ath12k/ce.c b/drivers/net/wireless/ath/ath12k/ce.c index c99e915e3885..cc8ed8451a2f 100644 --- a/drivers/net/wireless/ath/ath12k/ce.c +++ b/drivers/net/wireless/ath/ath12k/ce.c @@ -270,7 +270,12 @@ static void ath12k_ce_srng_msi_ring_params_setup(struct ath12k_base *ab, u32 ce_ ring_params->msi_addr = addr_lo; ring_params->msi_addr |= (dma_addr_t)(((u64)addr_hi) << 32); - ring_params->msi_data = (msi_data_idx % msi_data_count) + msi_data_start; + + if (ab->hw_params->hybrid_bus_type) + ring_params->msi_data = ab->msi.ce_msi_data[ce_id]; + else + ring_params->msi_data = (msi_data_idx % msi_data_count) + msi_data_start; + ring_params->flags |= HAL_SRNG_FLAGS_MSI_INTR; } diff --git a/drivers/net/wireless/ath/ath12k/core.h b/drivers/net/wireless/ath/ath12k/core.h index bbbde9f05ea9..575139555dd7 100644 --- a/drivers/net/wireless/ath/ath12k/core.h +++ b/drivers/net/wireless/ath/ath12k/core.h @@ -1172,6 +1172,8 @@ struct ath12k_base { u32 ep_base_data; u32 addr_lo; u32 addr_hi; + u32 ce_msi_data[CE_COUNT_MAX]; + u32 dp_msi_data[ATH12K_EXT_IRQ_GRP_NUM_MAX]; } msi; /* must be last */ diff --git a/drivers/net/wireless/ath/ath12k/dp.c b/drivers/net/wireless/ath/ath12k/dp.c index 6cf254b2d2a7..0f0800388935 100644 --- a/drivers/net/wireless/ath/ath12k/dp.c +++ b/drivers/net/wireless/ath/ath12k/dp.c @@ -225,8 +225,13 @@ static void ath12k_dp_srng_msi_setup(struct ath12k_base *ab, ring_params->msi_addr = addr_lo; ring_params->msi_addr |= (dma_addr_t)(((u64)addr_hi) << 32); - ring_params->msi_data = (msi_group_number % msi_data_count) - + msi_data_start; + + if (ab->hw_params->hybrid_bus_type) + ring_params->msi_data = ab->msi.dp_msi_data[msi_group_number]; + else + ring_params->msi_data = (msi_group_number % msi_data_count) + + msi_data_start; + ring_params->flags |= HAL_SRNG_FLAGS_MSI_INTR; } diff --git a/drivers/net/wireless/ath/ath12k/pcic.c b/drivers/net/wireless/ath/ath12k/pcic.c index 13097cdf2794..b6d306fd3b99 100644 --- a/drivers/net/wireless/ath/ath12k/pcic.c +++ b/drivers/net/wireless/ath/ath12k/pcic.c @@ -275,6 +275,7 @@ static int ath12k_pcic_ext_irq_config(struct ath12k_base *ab, } ab->irq_num[irq_idx] = desc->irq; + ab->msi.dp_msi_data[i] = desc->msg.data; disable_irq_nosync(ab->irq_num[irq_idx]); } @@ -318,6 +319,7 @@ static int ath12k_pcic_ce_irq_config(struct ath12k_base *ab, } ab->irq_num[irq_idx] = desc->irq; + ab->msi.ce_msi_data[i] = desc->msg.data; ath12k_pcic_ce_irq_disable(ab, i); vec_idx = (vec_idx + 1) % num_msi; -- 2.34.1