wifi: ath12k: fix PCI read and write
authorP Praneesh <quic_ppranees@quicinc.com>
Mon, 29 Jan 2024 06:57:22 +0000 (12:27 +0530)
committerKalle Valo <quic_kvalo@quicinc.com>
Fri, 2 Feb 2024 12:32:52 +0000 (14:32 +0200)
Currently, PCI read is failing for the registers belonging to
SECURITY_CONTROL_WLAN registers. These registers read is required
to read the board-id to identify the dual-mac QCN9274 hardware.

The failure is because, for these registers (SECURITY_CONTROL_WLAN)
offset, ath12k_pci_get_window_start() returns window_start as 0. Due
to this PCI read is done without PCI select window and with
window_start offset as 0.

Hence, fix PCI read and write by doing PCI select window and by using
the correct window_start offset - WINDOW_START for
SECURITY_CONTROL_WLAN registers.

Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.1.1-00188-QCAHKSWPL_SILICONZ-1
Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.0.1-00029-QCAHKSWPL_SILICONZ-1
Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0.c5-00481-QCAHMTSWPL_V1.0_V2.0_SILICONZ-3

Signed-off-by: P Praneesh <quic_ppranees@quicinc.com>
Co-developed-by: Karthikeyan Periyasamy <quic_periyasa@quicinc.com>
Signed-off-by: Karthikeyan Periyasamy <quic_periyasa@quicinc.com>
Signed-off-by: Raj Kumar Bhagat <quic_rajkbhag@quicinc.com>
Acked-by: Jeff Johnson <quic_jjohnson@quicinc.com>
Signed-off-by: Kalle Valo <quic_kvalo@quicinc.com>
Link: https://msgid.link/20240129065724.2310207-12-quic_rajkbhag@quicinc.com
drivers/net/wireless/ath/ath12k/pci.c

index d334f41f9658ee241f4aef5283a4738d957d20cd..14954bc05144368feadf85729bcada2ec29692c5 100644 (file)
@@ -205,18 +205,17 @@ static u32 ath12k_pci_get_window_start(struct ath12k_base *ab,
        /* If offset lies within CE register range, use 2nd window */
        else if ((offset ^ HAL_CE_WFSS_CE_REG_BASE) < WINDOW_RANGE_MASK)
                window_start = 2 * WINDOW_START;
-       /* If offset lies within PCI_BAR_WINDOW0_BASE and within PCI_SOC_PCI_REG_BASE
-        * use 0th window
-        */
-       else if (((offset ^ PCI_BAR_WINDOW0_BASE) < WINDOW_RANGE_MASK) &&
-                !((offset ^ PCI_SOC_PCI_REG_BASE) < PCI_SOC_RANGE_MASK))
-               window_start = 0;
        else
                window_start = WINDOW_START;
 
        return window_start;
 }
 
+static inline bool ath12k_pci_is_offset_within_mhi_region(u32 offset)
+{
+       return (offset >= PCI_MHIREGLEN_REG && offset <= PCI_MHI_REGION_END);
+}
+
 static void ath12k_pci_soc_global_reset(struct ath12k_base *ab)
 {
        u32 val, delay;
@@ -1172,15 +1171,17 @@ u32 ath12k_pci_read32(struct ath12k_base *ab, u32 offset)
                if (window_start == WINDOW_START) {
                        spin_lock_bh(&ab_pci->window_lock);
                        ath12k_pci_select_window(ab_pci, offset);
-                       val = ioread32(ab->mem + window_start +
-                                      (offset & WINDOW_RANGE_MASK));
+
+                       if (ath12k_pci_is_offset_within_mhi_region(offset)) {
+                               offset = offset - PCI_MHIREGLEN_REG;
+                               val = ioread32(ab->mem +
+                                              (offset & WINDOW_RANGE_MASK));
+                       } else {
+                               val = ioread32(ab->mem + window_start +
+                                              (offset & WINDOW_RANGE_MASK));
+                       }
                        spin_unlock_bh(&ab_pci->window_lock);
                } else {
-                       if ((!window_start) &&
-                           (offset >= PCI_MHIREGLEN_REG &&
-                            offset <= PCI_MHI_REGION_END))
-                               offset = offset - PCI_MHIREGLEN_REG;
-
                        val = ioread32(ab->mem + window_start +
                                       (offset & WINDOW_RANGE_MASK));
                }
@@ -1217,15 +1218,17 @@ void ath12k_pci_write32(struct ath12k_base *ab, u32 offset, u32 value)
                if (window_start == WINDOW_START) {
                        spin_lock_bh(&ab_pci->window_lock);
                        ath12k_pci_select_window(ab_pci, offset);
-                       iowrite32(value, ab->mem + window_start +
-                                 (offset & WINDOW_RANGE_MASK));
+
+                       if (ath12k_pci_is_offset_within_mhi_region(offset)) {
+                               offset = offset - PCI_MHIREGLEN_REG;
+                               iowrite32(value, ab->mem +
+                                         (offset & WINDOW_RANGE_MASK));
+                       } else {
+                               iowrite32(value, ab->mem + window_start +
+                                         (offset & WINDOW_RANGE_MASK));
+                       }
                        spin_unlock_bh(&ab_pci->window_lock);
                } else {
-                       if ((!window_start) &&
-                           (offset >= PCI_MHIREGLEN_REG &&
-                            offset <= PCI_MHI_REGION_END))
-                               offset = offset - PCI_MHIREGLEN_REG;
-
                        iowrite32(value, ab->mem + window_start +
                                  (offset & WINDOW_RANGE_MASK));
                }