new file mode 100644
@@ -0,0 +1,137 @@
+From 2b867c226aa6dae11cf320342b624caaef23b3f1 Mon Sep 17 00:00:00 2001
+From: P Praneesh <ppranees@codeaurora.org>
+Date: Mon, 14 Dec 2020 21:56:00 +0530
+Subject: [PATCH 5/6] ath11k: Use exclusive srng_write32 hif api for srng write
+ access
+
+Currently the pci_write32() performs multiple checks on the offset
+argument to identify if its a DP or CE mem offset, and selects
+a corresponding window start address to be added to the offset
+before performing the write operation.
+This could be costly for certain calls falling in the hotpath
+such as ath11k_hal_srng_access_end() which is used by the CE
+and DP code to update the srng head and tail pointer for src and
+dest rings correspondingly.
+
+Hence offload the window start determination during ring
+initialization itself and use the same offset which has window
+start address included for write operation.
+
+Added srng_write32 hif operation for this purpose.
+read32 is not used much in the datapath, hence using the
+existing hif call itself
+
+Signed-off-by: Sriram R <srirrama@codeaurora.org>
+Signed-off-by: P Praneesh <ppranees@codeaurora.org>
+---
+ drivers/net/wireless/ath/ath11k/ahb.c | 1 +
+ drivers/net/wireless/ath/ath11k/hal.c | 13 ++++++++-----
+ drivers/net/wireless/ath/ath11k/hif.h | 6 ++++++
+ drivers/net/wireless/ath/ath11k/pci.c | 7 +++++++
+ 4 files changed, 22 insertions(+), 5 deletions(-)
+
+--- a/drivers/net/wireless/ath/ath11k/ahb.c
++++ b/drivers/net/wireless/ath/ath11k/ahb.c
+@@ -745,6 +745,7 @@ static const struct ath11k_hif_ops ath11
+ .stop = ath11k_ahb_stop,
+ .read32 = ath11k_ahb_read32,
+ .write32 = ath11k_ahb_write32,
++ .srng_write32 = ath11k_ahb_write32,
+ .irq_enable = ath11k_ahb_ext_irq_enable,
+ .irq_disable = ath11k_ahb_ext_irq_disable,
+ .map_service_to_pipe = ath11k_ahb_map_service_to_pipe,
+--- a/drivers/net/wireless/ath/ath11k/hal.c
++++ b/drivers/net/wireless/ath/ath11k/hal.c
+@@ -837,13 +837,13 @@ void ath11k_hal_srng_access_end(struct a
+ if (srng->ring_dir == HAL_SRNG_DIR_SRC) {
+ srng->u.src_ring.last_tp =
+ *(volatile u32 *)srng->u.src_ring.tp_addr;
+- ath11k_hif_write32(ab,
++ ath11k_hif_srng_write32(ab,
+ (unsigned long)srng->u.src_ring.hp_addr -
+ (unsigned long)mem,
+ srng->u.src_ring.hp);
+ } else {
+ srng->u.dst_ring.last_hp = *srng->u.dst_ring.hp_addr;
+- ath11k_hif_write32(ab,
++ ath11k_hif_srng_write32(ab,
+ (unsigned long)srng->u.dst_ring.tp_addr -
+ (unsigned long)mem,
+ srng->u.dst_ring.tp);
+@@ -957,6 +957,7 @@ int ath11k_hal_srng_setup(struct ath11k_
+ int i;
+ u32 reg_base;
+ unsigned long *mem;
++ u32 offset;
+
+ ring_id = ath11k_hal_srng_get_ring_id(ab, type, ring_num, mac_id);
+ if (ring_id < 0)
+@@ -1015,8 +1016,9 @@ int ath11k_hal_srng_setup(struct ath11k_
+ lmac_idx);
+ srng->flags |= HAL_SRNG_FLAGS_LMAC_RING;
+ } else {
++ offset = ath11k_hif_get_window_offset(ab, reg_base);
+ srng->u.src_ring.hp_addr =
+- (u32 *)((unsigned long)mem + reg_base);
++ (u32 *)((unsigned long)mem + offset);
+ }
+ } else {
+ /* During initialization loop count in all the descriptors
+@@ -1040,9 +1042,10 @@ int ath11k_hal_srng_setup(struct ath11k_
+ lmac_idx);
+ srng->flags |= HAL_SRNG_FLAGS_LMAC_RING;
+ } else {
+- srng->u.dst_ring.tp_addr =
+- (u32 *)((unsigned long)mem + reg_base +
++ offset = ath11k_hif_get_window_offset(ab, reg_base +
+ (HAL_REO1_RING_TP(ab) - HAL_REO1_RING_HP(ab)));
++ srng->u.dst_ring.tp_addr =
++ (u32 *)((unsigned long)mem + offset);
+ }
+ }
+
+--- a/drivers/net/wireless/ath/ath11k/hif.h
++++ b/drivers/net/wireless/ath/ath11k/hif.h
+@@ -11,6 +11,7 @@
+ struct ath11k_hif_ops {
+ u32 (*read32)(struct ath11k_base *sc, u32 address);
+ void (*write32)(struct ath11k_base *sc, u32 address, u32 data);
++ void (*srng_write32)(struct ath11k_base *sc, u32 address, u32 data);
+ void (*irq_enable)(struct ath11k_base *sc);
+ void (*irq_disable)(struct ath11k_base *sc);
+ int (*start)(struct ath11k_base *sc);
+@@ -72,6 +73,11 @@ static inline void ath11k_hif_write32(st
+ sc->hif.ops->write32(sc, address, data);
+ }
+
++static inline void ath11k_hif_srng_write32(struct ath11k_base *sc, u32 address, u32 data)
++{
++ sc->hif.ops->srng_write32(sc, address, data);
++}
++
+ static inline int ath11k_hif_map_service_to_pipe(struct ath11k_base *sc, u16 service_id,
+ u8 *ul_pipe, u8 *dl_pipe)
+ {
+--- a/drivers/net/wireless/ath/ath11k/pci.c
++++ b/drivers/net/wireless/ath/ath11k/pci.c
+@@ -140,6 +140,12 @@ void ath11k_pci_write32(struct ath11k_ba
+ }
+ EXPORT_SYMBOL(ath11k_pci_write32);
+
++/* To be used for ce/dp srng pointer write */
++void ath11k_pci_srng_write32(struct ath11k_base *ab, u32 offset, u32 value)
++{
++ iowrite32(value, ab->mem + offset);
++}
++
+ u32 ath11k_pci_read32(struct ath11k_base *ab, u32 offset)
+ {
+ struct ath11k_pci *ab_pci = NULL;
+@@ -1012,6 +1018,7 @@ static const struct ath11k_hif_ops ath11
+ .stop = ath11k_pci_stop,
+ .read32 = ath11k_pci_read32,
+ .write32 = ath11k_pci_write32,
++ .srng_write32 = ath11k_pci_srng_write32,
+ .power_down = ath11k_pci_power_down,
+ .power_up = ath11k_pci_power_up,
+ .irq_enable = ath11k_pci_ext_irq_enable,