Преглед на файлове

qcacmn: Fix IPA WDI3 Tx issues

Fix bug to enable IPA WDI3 Tx H/W path.

Change-Id: Ice691dccc649b38971985cd8da042719d943cec7
CRs-Fixed: 2085751
Yun Park преди 7 години
родител
ревизия
601d0d868a
променени са 10 файла, в които са добавени 447 реда и са изтрити 344 реда
  1. 2 1
      dp/inc/cdp_txrx_ops.h
  2. 4 2
      dp/inc/cdp_txrx_peer_ops.h
  3. 2 1
      dp/wifi3.0/dp_internal.h
  4. 327 5
      dp/wifi3.0/dp_ipa.c
  5. 19 0
      dp/wifi3.0/dp_ipa.h
  6. 21 320
      dp/wifi3.0/dp_main.c
  7. 3 3
      dp/wifi3.0/dp_peer.c
  8. 3 4
      dp/wifi3.0/dp_types.h
  9. 41 2
      hal/wifi3.0/hal_api.h
  10. 25 6
      hal/wifi3.0/hal_srng.c

+ 2 - 1
dp/inc/cdp_txrx_ops.h

@@ -901,7 +901,8 @@ struct cdp_peer_ops {
 			uint8_t *peer_addr,
 			enum ol_txrx_peer_state state);
 	QDF_STATUS (*get_vdevid)(void *peer, uint8_t *vdev_id);
-	struct cdp_vdev * (*get_vdev_by_sta_id)(uint8_t sta_id);
+	struct cdp_vdev * (*get_vdev_by_sta_id)(struct cdp_pdev *pdev,
+			uint8_t sta_id);
 	QDF_STATUS (*register_ocb_peer)(uint8_t *mac_addr, uint8_t *peer_id);
 	uint8_t * (*peer_get_peer_mac_addr)(void *peer);
 	int (*get_peer_state)(void *peer);

+ 4 - 2
dp/inc/cdp_txrx_peer_ops.h

@@ -339,6 +339,7 @@ cdp_peer_get_vdevid(ol_txrx_soc_handle soc, void *peer, uint8_t *vdev_id)
 /**
  * cdp_peer_get_vdev_by_sta_id() - Get vdev instance by local peer id
  * @soc - data path soc handle
+ * @pdev - data path device instance
  * @sta_id - local peer id
  *
  * Get virtaul interface id by local peer id
@@ -347,7 +348,8 @@ cdp_peer_get_vdevid(ol_txrx_soc_handle soc, void *peer, uint8_t *vdev_id)
  *         NULL in case cannot find
  */
 static inline struct cdp_vdev
-*cdp_peer_get_vdev_by_sta_id(ol_txrx_soc_handle soc, uint8_t sta_id)
+*cdp_peer_get_vdev_by_sta_id(ol_txrx_soc_handle soc, struct cdp_pdev *pdev,
+			     uint8_t sta_id)
 {
 	if (!soc || !soc->ops || !soc->ops->peer_ops) {
 		QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL,
@@ -356,7 +358,7 @@ static inline struct cdp_vdev
 	}
 
 	if (soc->ops->peer_ops->get_vdev_by_sta_id)
-		return soc->ops->peer_ops->get_vdev_by_sta_id(sta_id);
+		return soc->ops->peer_ops->get_vdev_by_sta_id(pdev, sta_id);
 
 	return NULL;
 }

+ 2 - 1
dp/wifi3.0/dp_internal.h

@@ -257,7 +257,8 @@ void *dp_peer_find_by_local_id(struct cdp_pdev *pdev_handle, uint8_t local_id);
 QDF_STATUS dp_peer_state_update(struct cdp_pdev *pdev_handle, uint8_t *peer_mac,
 		enum ol_txrx_peer_state state);
 QDF_STATUS dp_get_vdevid(void *peer_handle, uint8_t *vdev_id);
-struct cdp_vdev *dp_get_vdev_by_sta_id(uint8_t sta_id);
+struct cdp_vdev *dp_get_vdev_by_sta_id(struct cdp_pdev *pdev_handle,
+		uint8_t sta_id);
 struct cdp_vdev *dp_get_vdev_for_peer(void *peer);
 uint8_t *dp_peer_get_peer_mac_addr(void *peer);
 int dp_get_peer_state(void *peer_handle);

+ 327 - 5
dp/wifi3.0/dp_ipa.c

@@ -16,7 +16,7 @@
 
 #ifdef IPA_OFFLOAD
 
-#include <ipa_wdi3.h>
+#include <linux/ipa_wdi3.h>
 #include <qdf_types.h>
 #include <qdf_lock.h>
 #include <hal_api.h>
@@ -25,9 +25,311 @@
 #include <wdi_event.h>
 #include <queue.h>
 #include "dp_types.h"
+#include "dp_htt.h"
 #include "dp_tx.h"
 #include "dp_ipa.h"
 
+/**
+ * dp_tx_ipa_uc_detach - Free autonomy TX resources
+ * @soc: data path instance
+ * @pdev: core txrx pdev context
+ *
+ * Free allocated TX buffers with WBM SRNG
+ *
+ * Return: none
+ */
+static void dp_tx_ipa_uc_detach(struct dp_soc *soc, struct dp_pdev *pdev)
+{
+	int idx;
+
+	for (idx = 0; idx < soc->ipa_uc_tx_rsc.alloc_tx_buf_cnt; idx++) {
+		if (soc->ipa_uc_tx_rsc.tx_buf_pool_vaddr[idx]) {
+			qdf_mem_free(soc->ipa_uc_tx_rsc.tx_buf_pool_vaddr[idx]);
+			soc->ipa_uc_tx_rsc.tx_buf_pool_vaddr[idx] = NULL;
+		}
+	}
+
+	qdf_mem_free(soc->ipa_uc_tx_rsc.tx_buf_pool_vaddr);
+	soc->ipa_uc_tx_rsc.tx_buf_pool_vaddr = NULL;
+}
+
+/**
+ * dp_rx_ipa_uc_detach - free autonomy RX resources
+ * @soc: data path instance
+ * @pdev: core txrx pdev context
+ *
+ * This function will detach DP RX into main device context
+ * will free DP Rx resources.
+ *
+ * Return: none
+ */
+static void dp_rx_ipa_uc_detach(struct dp_soc *soc, struct dp_pdev *pdev)
+{
+}
+
+int dp_ipa_uc_detach(struct dp_soc *soc, struct dp_pdev *pdev)
+{
+	/* TX resource detach */
+	dp_tx_ipa_uc_detach(soc, pdev);
+
+	/* RX resource detach */
+	dp_rx_ipa_uc_detach(soc, pdev);
+
+	return QDF_STATUS_SUCCESS;	/* success */
+}
+
+/* Hard coded config parameters until dp_ops_cfg.cfg_attach implemented */
+#define CFG_IPA_UC_TX_BUF_SIZE_DEFAULT            (2048)
+
+/**
+ * dp_tx_ipa_uc_attach - Allocate autonomy TX resources
+ * @soc: data path instance
+ * @pdev: Physical device handle
+ *
+ * Allocate TX buffer from non-cacheable memory
+ * Attache allocated TX buffers with WBM SRNG
+ *
+ * Return: int
+ */
+static int dp_tx_ipa_uc_attach(struct dp_soc *soc, struct dp_pdev *pdev)
+{
+	uint32_t tx_buffer_count;
+	uint32_t ring_base_align = 8;
+	void *buffer_vaddr_unaligned;
+	void *buffer_vaddr;
+	qdf_dma_addr_t buffer_paddr_unaligned;
+	qdf_dma_addr_t buffer_paddr;
+	struct hal_srng *wbm_srng =
+			soc->tx_comp_ring[IPA_TX_COMP_RING_IDX].hal_srng;
+	struct hal_srng_params srng_params;
+	uint32_t paddr_lo;
+	uint32_t paddr_hi;
+	void *ring_entry;
+	int num_entries;
+	int retval = QDF_STATUS_SUCCESS;
+	/*
+	 * Uncomment when dp_ops_cfg.cfg_attach is implemented
+	 * unsigned int uc_tx_buf_sz =
+	 *		dp_cfg_ipa_uc_tx_buf_size(pdev->osif_pdev);
+	 */
+	unsigned int uc_tx_buf_sz = CFG_IPA_UC_TX_BUF_SIZE_DEFAULT;
+	unsigned int alloc_size = uc_tx_buf_sz + ring_base_align - 1;
+
+	hal_get_srng_params(soc->hal_soc, (void *)wbm_srng, &srng_params);
+	num_entries = srng_params.num_entries;
+
+	QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR,
+		  "requested %d buffers to be posted to wbm ring",
+		   num_entries);
+
+	soc->ipa_uc_tx_rsc.tx_buf_pool_vaddr = qdf_mem_malloc(num_entries *
+			sizeof(*soc->ipa_uc_tx_rsc.tx_buf_pool_vaddr));
+	if (!soc->ipa_uc_tx_rsc.tx_buf_pool_vaddr) {
+		QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR,
+			  "%s: IPA WBM Ring mem_info alloc fail", __func__);
+		return -ENOMEM;
+	}
+
+	hal_srng_access_start(soc->hal_soc, (void *)wbm_srng);
+
+	/*
+	 * Allocate Tx buffers as many as possible
+	 * Populate Tx buffers into WBM2IPA ring
+	 * This initial buffer population will simulate H/W as source ring,
+	 * and update HP
+	 */
+	for (tx_buffer_count = 0;
+		tx_buffer_count < num_entries - 1; tx_buffer_count++) {
+		buffer_vaddr_unaligned = qdf_mem_alloc_consistent(soc->osdev,
+			soc->osdev->dev, alloc_size, &buffer_paddr_unaligned);
+		if (!buffer_vaddr_unaligned)
+			break;
+
+		ring_entry = hal_srng_dst_get_next_hp(soc->hal_soc,
+				(void *)wbm_srng);
+		if (!ring_entry) {
+			QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR,
+				  "Failed to get WBM ring entry\n");
+			qdf_mem_free_consistent(soc->osdev, soc->osdev->dev,
+				alloc_size, buffer_vaddr_unaligned,
+				buffer_paddr_unaligned, 0);
+			goto fail;
+		}
+
+		buffer_vaddr = (void *)qdf_align((unsigned long)
+			buffer_vaddr_unaligned, ring_base_align);
+		buffer_paddr = buffer_paddr_unaligned +
+			((unsigned long)(buffer_vaddr) -
+			 (unsigned long)buffer_vaddr_unaligned);
+
+		paddr_lo = ((u64)buffer_paddr & 0x00000000ffffffff);
+		paddr_hi = ((u64)buffer_paddr & 0x0000001f00000000) >> 32;
+		HAL_WBM_PADDR_LO_SET(ring_entry, paddr_lo);
+		HAL_WBM_PADDR_HI_SET(ring_entry, paddr_hi);
+
+		soc->ipa_uc_tx_rsc.tx_buf_pool_vaddr[tx_buffer_count] =
+			buffer_vaddr;
+	}
+
+	hal_srng_access_end(soc->hal_soc, wbm_srng);
+
+	soc->ipa_uc_tx_rsc.alloc_tx_buf_cnt = tx_buffer_count;
+
+	QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR,
+		  "IPA WDI TX buffer: %d allocated\n",
+		  tx_buffer_count);
+
+	return retval;
+
+fail:
+	hal_srng_access_end(soc->hal_soc, wbm_srng);
+	qdf_mem_free(soc->ipa_uc_tx_rsc.tx_buf_pool_vaddr);
+	return retval;
+}
+
+/**
+ * dp_rx_ipa_uc_attach - Allocate autonomy RX resources
+ * @soc: data path instance
+ * @pdev: core txrx pdev context
+ *
+ * This function will attach a DP RX instance into the main
+ * device (SOC) context.
+ *
+ * Return: QDF_STATUS_SUCCESS: success
+ *         QDF_STATUS_E_RESOURCES: Error return
+ */
+static int dp_rx_ipa_uc_attach(struct dp_soc *soc, struct dp_pdev *pdev)
+{
+	return QDF_STATUS_SUCCESS;
+}
+
+int dp_ipa_uc_attach(struct dp_soc *soc, struct dp_pdev *pdev)
+{
+	int error;
+
+	/* TX resource attach */
+	error = dp_tx_ipa_uc_attach(soc, pdev);
+	if (error) {
+		QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR,
+			  "DP IPA UC TX attach fail code %d\n", error);
+		return error;
+	}
+
+	/* RX resource attach */
+	error = dp_rx_ipa_uc_attach(soc, pdev);
+	if (error) {
+		QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR,
+			  "DP IPA UC RX attach fail code %d\n", error);
+		dp_tx_ipa_uc_detach(soc, pdev);
+		return error;
+	}
+
+	return QDF_STATUS_SUCCESS;	/* success */
+}
+
+/*
+ * dp_ipa_ring_resource_setup() - setup IPA ring resources
+ * @soc: data path SoC handle
+ *
+ * Return: none
+ */
+int dp_ipa_ring_resource_setup(struct dp_soc *soc,
+		struct dp_pdev *pdev)
+{
+	struct hal_soc *hal_soc = (struct hal_soc *)soc->hal_soc;
+	struct hal_srng *hal_srng;
+	struct hal_srng_params srng_params;
+	qdf_dma_addr_t hp_addr;
+	unsigned long addr_offset, dev_base_paddr;
+
+	/* IPA TCL_DATA Ring - HAL_SRNG_SW2TCL3 */
+	hal_srng = soc->tcl_data_ring[IPA_TCL_DATA_RING_IDX].hal_srng;
+	hal_get_srng_params(hal_soc, (void *)hal_srng, &srng_params);
+
+	soc->ipa_uc_tx_rsc.ipa_tcl_ring_base_paddr =
+		srng_params.ring_base_paddr;
+	soc->ipa_uc_tx_rsc.ipa_tcl_ring_base_vaddr =
+		srng_params.ring_base_vaddr;
+	soc->ipa_uc_tx_rsc.ipa_tcl_ring_size =
+		(srng_params.num_entries * srng_params.entry_size) << 2;
+	/*
+	 * For the register backed memory addresses, use the scn->mem_pa to
+	 * calculate the physical address of the shadow registers
+	 */
+	dev_base_paddr =
+		(unsigned long)
+		((struct hif_softc *)(hal_soc->hif_handle))->mem_pa;
+	addr_offset = (unsigned long)(hal_srng->u.src_ring.hp_addr) -
+		      (unsigned long)(hal_soc->dev_base_addr);
+	soc->ipa_uc_tx_rsc.ipa_tcl_hp_paddr =
+				(qdf_dma_addr_t)(addr_offset + dev_base_paddr);
+
+	QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_INFO,
+		"%s: addr_offset=%x, dev_base_paddr=%x, ipa_tcl_hp_paddr=%x",
+		__func__, (unsigned int)addr_offset,
+		(unsigned int)dev_base_paddr,
+		(unsigned int)(soc->ipa_uc_tx_rsc.ipa_tcl_hp_paddr));
+
+	/* IPA TX COMP Ring - HAL_SRNG_WBM2SW2_RELEASE */
+	hal_srng = soc->tx_comp_ring[IPA_TX_COMP_RING_IDX].hal_srng;
+	hal_get_srng_params(hal_soc, (void *)hal_srng, &srng_params);
+
+	soc->ipa_uc_tx_rsc.ipa_wbm_ring_base_paddr =
+		srng_params.ring_base_paddr;
+	soc->ipa_uc_tx_rsc.ipa_wbm_ring_base_vaddr =
+		srng_params.ring_base_vaddr;
+	soc->ipa_uc_tx_rsc.ipa_wbm_ring_size =
+		(srng_params.num_entries * srng_params.entry_size) << 2;
+	addr_offset = (unsigned long)(hal_srng->u.dst_ring.tp_addr) -
+		      (unsigned long)(hal_soc->dev_base_addr);
+	soc->ipa_uc_tx_rsc.ipa_wbm_tp_paddr =
+				(qdf_dma_addr_t)(addr_offset + dev_base_paddr);
+
+	QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_INFO,
+		"%s: addr_offset=%x, dev_base_paddr=%x, ipa_wbm_tp_paddr=%x",
+		__func__, (unsigned int)addr_offset,
+		(unsigned int)dev_base_paddr,
+		(unsigned int)(soc->ipa_uc_tx_rsc.ipa_wbm_tp_paddr));
+
+	/* IPA REO_DEST Ring - HAL_SRNG_REO2SW4 */
+	hal_srng = soc->reo_dest_ring[IPA_REO_DEST_RING_IDX].hal_srng;
+	hal_get_srng_params(hal_soc, (void *)hal_srng, &srng_params);
+
+	soc->ipa_uc_rx_rsc.ipa_reo_ring_base_paddr =
+		srng_params.ring_base_paddr;
+	soc->ipa_uc_rx_rsc.ipa_reo_ring_base_vaddr =
+		srng_params.ring_base_vaddr;
+	soc->ipa_uc_rx_rsc.ipa_reo_ring_size =
+		(srng_params.num_entries * srng_params.entry_size) << 2;
+	addr_offset = (unsigned long)(hal_srng->u.dst_ring.tp_addr) -
+		      (unsigned long)(hal_soc->dev_base_addr);
+	soc->ipa_uc_rx_rsc.ipa_reo_tp_paddr =
+				(qdf_dma_addr_t)(addr_offset + dev_base_paddr);
+
+	QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_INFO,
+		"%s: addr_offset=%x, dev_base_paddr=%x, ipa_reo_tp_paddr=%x",
+		__func__, (unsigned int)addr_offset,
+		(unsigned int)dev_base_paddr,
+		(unsigned int)(soc->ipa_uc_rx_rsc.ipa_reo_tp_paddr));
+
+	hal_srng = pdev->rx_refill_buf_ring2.hal_srng;
+	hal_get_srng_params(hal_soc, (void *)hal_srng, &srng_params);
+	soc->ipa_uc_rx_rsc.ipa_rx_refill_buf_ring_base_paddr =
+		srng_params.ring_base_paddr;
+	soc->ipa_uc_rx_rsc.ipa_rx_refill_buf_ring_base_vaddr =
+		srng_params.ring_base_vaddr;
+	soc->ipa_uc_rx_rsc.ipa_rx_refill_buf_ring_size =
+		(srng_params.num_entries * srng_params.entry_size) << 2;
+	hp_addr = hal_srng_get_hp_addr(hal_soc, (void *)hal_srng);
+	soc->ipa_uc_rx_rsc.ipa_rx_refill_buf_hp_paddr = hp_addr;
+
+	QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_INFO,
+		"%s: ipa_rx_refill_buf_hp_paddr=%x", __func__,
+		(unsigned int)(soc->ipa_uc_rx_rsc.ipa_rx_refill_buf_hp_paddr));
+
+	return 0;
+}
+
 /**
  * dp_ipa_uc_get_resource() - Client request resource information
  * @ppdev - handle to the device instance
@@ -87,11 +389,14 @@ QDF_STATUS dp_ipa_set_doorbell_paddr(struct cdp_pdev *ppdev)
 	struct dp_pdev *pdev = (struct dp_pdev *)ppdev;
 	struct dp_soc *soc = pdev->soc;
 	struct dp_ipa_resources *ipa_res = &pdev->ipa_resource;
+	struct hal_srng *wbm_srng =
+			soc->tx_comp_ring[IPA_TX_COMP_RING_IDX].hal_srng;
+	struct hal_srng *reo_srng =
+			soc->reo_dest_ring[IPA_REO_DEST_RING_IDX].hal_srng;
 
-	hal_srng_set_hp_paddr(soc->tx_comp_ring[IPA_TX_COMP_RING_IDX].
-			      hal_srng, ipa_res->tx_comp_doorbell_paddr);
-	hal_srng_set_hp_paddr(soc->reo_dest_ring[IPA_REO_DEST_RING_IDX].
-			      hal_srng, ipa_res->rx_ready_doorbell_paddr);
+	hal_srng_dst_set_hp_paddr(wbm_srng, ipa_res->tx_comp_doorbell_paddr);
+	hal_srng_dst_init_hp(wbm_srng, ipa_res->tx_comp_doorbell_vaddr);
+	hal_srng_dst_set_hp_paddr(reo_srng, ipa_res->rx_ready_doorbell_paddr);
 
 	return QDF_STATUS_SUCCESS;
 }
@@ -259,8 +564,13 @@ QDF_STATUS dp_ipa_setup(struct cdp_pdev *ppdev, void *ipa_i2w_cb,
 	struct ipa_wdi3_setup_info rx;
 	struct ipa_wdi3_conn_in_params pipe_in;
 	struct ipa_wdi3_conn_out_params pipe_out;
+	struct tcl_data_cmd *tcl_desc_ptr;
+	uint8_t *desc_addr;
+	uint32_t desc_size;
 	int ret;
 
+	qdf_mem_zero(&tx, sizeof(struct ipa_wdi3_setup_info));
+	qdf_mem_zero(&rx, sizeof(struct ipa_wdi3_setup_info));
 	qdf_mem_zero(&pipe_in, sizeof(struct ipa_wdi3_conn_in_params));
 	qdf_mem_zero(&pipe_out, sizeof(struct ipa_wdi3_conn_out_params));
 
@@ -290,6 +600,17 @@ QDF_STATUS dp_ipa_setup(struct cdp_pdev *ppdev, void *ipa_i2w_cb,
 	tx.num_pkt_buffers = ipa_res->tx_num_alloc_buffer;
 	tx.pkt_offset = 0;
 
+	/* Preprogram TCL descriptor */
+	desc_addr = (uint8_t *)(tx.desc_format_template);
+	desc_size = sizeof(struct tcl_data_cmd);
+	HAL_TX_DESC_SET_TLV_HDR(desc_addr, HAL_TX_TCL_DATA_TAG, desc_size);
+	tcl_desc_ptr = (struct tcl_data_cmd *)(tx.desc_format_template+1);
+	tcl_desc_ptr->buf_addr_info.return_buffer_manager =
+						HAL_RX_BUF_RBM_SW2_BM;
+	tcl_desc_ptr->addrx_en = 1;	/* Address X search enable in ASE */
+	tcl_desc_ptr->encap_type = HAL_TX_ENCAP_TYPE_ETHERNET;
+	tcl_desc_ptr->packet_offset = 2;	/* padding for alignment */
+
 	/* RX PIPE */
 	/**
 	 * Transfer Ring: REO Ring
@@ -334,6 +655,7 @@ QDF_STATUS dp_ipa_setup(struct cdp_pdev *ppdev, void *ipa_i2w_cb,
 		(unsigned int)pipe_out.rx_uc_db_pa);
 
 	ipa_res->tx_comp_doorbell_paddr = pipe_out.tx_uc_db_pa;
+	ipa_res->tx_comp_doorbell_vaddr = pipe_out.tx_uc_db_va;
 	ipa_res->rx_ready_doorbell_paddr = pipe_out.rx_uc_db_pa;
 
 	QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_DEBUG,

+ 19 - 0
dp/wifi3.0/dp_ipa.h

@@ -73,6 +73,25 @@ QDF_STATUS dp_ipa_enable_pipes(struct cdp_pdev *pdev);
 QDF_STATUS dp_ipa_disable_pipes(struct cdp_pdev *pdev);
 QDF_STATUS dp_ipa_set_perf_level(int client,
 		uint32_t max_supported_bw_mbps);
+int dp_ipa_uc_detach(struct dp_soc *soc, struct dp_pdev *pdev);
+int dp_ipa_uc_attach(struct dp_soc *soc, struct dp_pdev *pdev);
+int dp_ipa_ring_resource_setup(struct dp_soc *soc,
+		struct dp_pdev *pdev);
+#else
+static inline int dp_ipa_uc_detach(struct dp_soc *soc, struct dp_pdev *pdev)
+{
+	return QDF_STATUS_SUCCESS;
+}
 
+static inline int dp_ipa_uc_attach(struct dp_soc *soc, struct dp_pdev *pdev)
+{
+	return QDF_STATUS_SUCCESS;
+}
+
+static inline int dp_ipa_ring_resource_setup(struct dp_soc *soc,
+					     struct dp_pdev *pdev)
+{
+	return 0;
+}
 #endif
 #endif /* _DP_IPA_H_ */

+ 21 - 320
dp/wifi3.0/dp_main.c

@@ -49,7 +49,6 @@ cdp_dump_flow_pool_info(struct cdp_soc_t *soc)
 	return;
 }
 #endif
-#include <ol_cfg.h>
 #include "dp_ipa.h"
 
 #define DP_INTR_POLL_TIMER_MS	10
@@ -64,7 +63,7 @@ cdp_dump_flow_pool_info(struct cdp_soc_t *soc)
 
 #ifdef IPA_OFFLOAD
 /* Exclude IPA rings from the interrupt context */
-#define TX_RING_MASK_VAL	0x7
+#define TX_RING_MASK_VAL	0xb
 #define RX_RING_MASK_VAL	0x7
 #else
 #define TX_RING_MASK_VAL	0xF
@@ -586,201 +585,6 @@ static void dp_srng_cleanup(struct dp_soc *soc, struct dp_srng *srng,
 	srng->hal_srng = NULL;
 }
 
-#ifdef IPA_OFFLOAD
-/**
- * dp_tx_ipa_uc_detach - Free autonomy TX resources
- * @soc: data path instance
- * @pdev: core txrx pdev context
- *
- * Free allocated TX buffers with WBM SRNG
- *
- * Return: none
- */
-static void dp_tx_ipa_uc_detach(struct dp_soc *soc, struct dp_pdev *pdev)
-{
-	int idx;
-
-	for (idx = 0; idx < soc->ipa_uc_tx_rsc.alloc_tx_buf_cnt; idx++) {
-		if (soc->ipa_uc_tx_rsc.tx_buf_pool_vaddr[idx])
-			qdf_mem_free(soc->ipa_uc_tx_rsc.tx_buf_pool_vaddr[idx]);
-	}
-
-	qdf_mem_free(soc->ipa_uc_tx_rsc.tx_buf_pool_vaddr);
-	soc->ipa_uc_tx_rsc.tx_buf_pool_vaddr = NULL;
-}
-
-/**
- * dp_rx_ipa_uc_detach - free autonomy RX resources
- * @soc: data path instance
- * @pdev: core txrx pdev context
- *
- * This function will detach DP RX into main device context
- * will free DP Rx resources.
- *
- * Return: none
- */
-static void dp_rx_ipa_uc_detach(struct dp_soc *soc, struct dp_pdev *pdev)
-{
-}
-
-static int dp_ipa_uc_detach(struct dp_soc *soc, struct dp_pdev *pdev)
-{
-	/* TX resource detach */
-	dp_tx_ipa_uc_detach(soc, pdev);
-
-	/* RX resource detach */
-	dp_rx_ipa_uc_detach(soc, pdev);
-
-	dp_srng_cleanup(soc, &pdev->ipa_rx_refill_buf_ring, RXDMA_BUF, 2);
-
-	return QDF_STATUS_SUCCESS;	/* success */
-}
-
-/* Hard coded config parameters until dp_ops_cfg.cfg_attach implemented */
-#define CFG_IPA_UC_TX_BUF_SIZE_DEFAULT            (2048)
-
-/**
- * dp_tx_ipa_uc_attach - Allocate autonomy TX resources
- * @soc: data path instance
- * @pdev: Physical device handle
- *
- * Allocate TX buffer from non-cacheable memory
- * Attache allocated TX buffers with WBM SRNG
- *
- * Return: int
- */
-static int dp_tx_ipa_uc_attach(struct dp_soc *soc, struct dp_pdev *pdev)
-{
-	uint32_t tx_buffer_count;
-	uint32_t ring_base_align = 8;
-	void *buffer_vaddr_unaligned;
-	void *buffer_vaddr;
-	qdf_dma_addr_t buffer_paddr_unaligned;
-	qdf_dma_addr_t buffer_paddr;
-	void *wbm_srng = soc->tx_comp_ring[IPA_TX_COMP_RING_IDX].hal_srng;
-	uint32_t paddr_lo;
-	uint32_t paddr_hi;
-	void *ring_entry;
-	int ring_size = ((struct hal_srng *)wbm_srng)->ring_size;
-	int retval = QDF_STATUS_SUCCESS;
-	/*
-	 * Uncomment when dp_ops_cfg.cfg_attach is implemented
-	 * unsigned int uc_tx_buf_sz =
-	 *		dp_cfg_ipa_uc_tx_buf_size(pdev->osif_pdev);
-	 */
-	unsigned int uc_tx_buf_sz = CFG_IPA_UC_TX_BUF_SIZE_DEFAULT;
-	unsigned int alloc_size = uc_tx_buf_sz + ring_base_align - 1;
-
-	QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR,
-		  "requested %d buffers to be posted to wbm ring",
-			 ring_size);
-
-	soc->ipa_uc_tx_rsc.tx_buf_pool_vaddr = qdf_mem_malloc(ring_size *
-			sizeof(*soc->ipa_uc_tx_rsc.tx_buf_pool_vaddr));
-	if (!soc->ipa_uc_tx_rsc.tx_buf_pool_vaddr) {
-		QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR,
-			  "%s: IPA WBM Ring mem_info alloc fail", __func__);
-		return -ENOMEM;
-	}
-
-	hal_srng_access_start(soc->hal_soc, wbm_srng);
-
-	/* Allocate TX buffers as many as possible */
-	for (tx_buffer_count = 0;
-		tx_buffer_count < ring_size; tx_buffer_count++) {
-
-		ring_entry = hal_srng_src_get_next(soc->hal_soc, wbm_srng);
-		if (!ring_entry) {
-			QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR,
-				  "Failed to get WBM ring entry\n");
-			goto fail;
-		}
-
-		buffer_vaddr_unaligned = qdf_mem_alloc_consistent(soc->osdev,
-			soc->osdev->dev, alloc_size, &buffer_paddr_unaligned);
-		if (!buffer_vaddr_unaligned) {
-			QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR,
-				  "IPA WDI TX buffer alloc fail %d allocated\n",
-				  tx_buffer_count);
-			break;
-		}
-
-		buffer_vaddr = buffer_vaddr_unaligned +
-			((unsigned long)buffer_vaddr_unaligned %
-			ring_base_align);
-		buffer_paddr = buffer_paddr_unaligned +
-			((unsigned long)(buffer_vaddr) -
-			 (unsigned long)buffer_vaddr_unaligned);
-
-		paddr_lo = ((u64)buffer_paddr & 0x00000000ffffffff);
-		paddr_hi = ((u64)buffer_paddr & 0x0000001f00000000) >> 32;
-		HAL_WBM_PADDR_LO_SET(ring_entry, paddr_lo);
-		HAL_WBM_PADDR_HI_SET(ring_entry, paddr_hi);
-
-		soc->ipa_uc_tx_rsc.tx_buf_pool_vaddr[tx_buffer_count] =
-			buffer_vaddr;
-	}
-
-	hal_srng_access_end(soc->hal_soc, wbm_srng);
-	soc->ipa_uc_tx_rsc.alloc_tx_buf_cnt = tx_buffer_count;
-
-	return retval;
-
-fail:
-	qdf_mem_free(soc->ipa_uc_tx_rsc.tx_buf_pool_vaddr);
-	return retval;
-}
-
-/**
- * dp_rx_ipa_uc_attach - Allocate autonomy RX resources
- * @soc: data path instance
- * @pdev: core txrx pdev context
- *
- * This function will attach a DP RX instance into the main
- * device (SOC) context.
- *
- * Return: QDF_STATUS_SUCCESS: success
- *         QDF_STATUS_E_RESOURCES: Error return
- */
-static int dp_rx_ipa_uc_attach(struct dp_soc *soc, struct dp_pdev *pdev)
-{
-	return QDF_STATUS_SUCCESS;
-}
-
-static int dp_ipa_uc_attach(struct dp_soc *soc, struct dp_pdev *pdev)
-{
-	int error;
-
-	/* TX resource attach */
-	error = dp_tx_ipa_uc_attach(soc, pdev);
-	if (error) {
-		QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR,
-			  "DP IPA UC TX attach fail code %d\n", error);
-		return error;
-	}
-
-	/* RX resource attach */
-	error = dp_rx_ipa_uc_attach(soc, pdev);
-	if (error) {
-		QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR,
-			  "DP IPA UC RX attach fail code %d\n", error);
-		dp_tx_ipa_uc_detach(soc, pdev);
-		return error;
-	}
-
-	return QDF_STATUS_SUCCESS;	/* success */
-}
-#else
-static int dp_ipa_uc_detach(struct dp_soc *soc, struct dp_pdev *pdev)
-{
-	return QDF_STATUS_SUCCESS;
-}
-static int dp_ipa_uc_attach(struct dp_soc *soc, struct dp_pdev *pdev)
-{
-	return QDF_STATUS_SUCCESS;
-}
-#endif
-
 /* TODO: Need this interface from HIF */
 void *hif_get_hal_handle(void *hif_handle);
 
@@ -2170,99 +1974,6 @@ dp_dscp_tid_map_setup(struct dp_pdev *pdev)
 	}
 }
 
-/*
- * dp_ipa_ring_resource_setup() - setup IPA ring resources
- * @soc: data path SoC handle
- *
- * Return: none
- */
-#ifdef IPA_OFFLOAD
-static inline int dp_ipa_ring_resource_setup(struct dp_soc *soc,
-		struct dp_pdev *pdev)
-{
-	void *hal_srng;
-	struct hal_srng_params srng_params;
-	qdf_dma_addr_t hp_addr, tp_addr;
-
-	/* IPA TCL_DATA Ring - HAL_SRNG_SW2TCL4 */
-	hal_srng = soc->tcl_data_ring[IPA_TCL_DATA_RING_IDX].hal_srng;
-	hal_get_srng_params(soc->hal_soc, hal_srng, &srng_params);
-
-	soc->ipa_uc_tx_rsc.ipa_tcl_ring_base_paddr =
-		srng_params.ring_base_paddr;
-	soc->ipa_uc_tx_rsc.ipa_tcl_ring_base_vaddr =
-		srng_params.ring_base_vaddr;
-	soc->ipa_uc_tx_rsc.ipa_tcl_ring_size =
-		srng_params.num_entries * srng_params.entry_size;
-	hp_addr = hal_srng_get_hp_addr(soc->hal_soc, hal_srng);
-	soc->ipa_uc_tx_rsc.ipa_tcl_hp_paddr = hp_addr;
-
-
-	/* IPA TX COMP Ring - HAL_SRNG_WBM2SW3_RELEASE */
-	hal_srng = soc->tx_comp_ring[IPA_TX_COMP_RING_IDX].hal_srng;
-	hal_get_srng_params(soc->hal_soc, hal_srng, &srng_params);
-
-	soc->ipa_uc_tx_rsc.ipa_wbm_ring_base_paddr =
-		srng_params.ring_base_paddr;
-	soc->ipa_uc_tx_rsc.ipa_wbm_ring_base_vaddr =
-		srng_params.ring_base_vaddr;
-	soc->ipa_uc_tx_rsc.ipa_wbm_ring_size =
-		srng_params.num_entries * srng_params.entry_size;
-	tp_addr = hal_srng_get_tp_addr(soc->hal_soc, hal_srng);
-	soc->ipa_uc_tx_rsc.ipa_wbm_tp_paddr = tp_addr;
-
-	/* IPA REO_DEST Ring - HAL_SRNG_REO2SW4 */
-	hal_srng = soc->reo_dest_ring[IPA_REO_DEST_RING_IDX].hal_srng;
-	hal_get_srng_params(soc->hal_soc, hal_srng, &srng_params);
-
-	soc->ipa_uc_rx_rsc.ipa_reo_ring_base_paddr =
-		srng_params.ring_base_paddr;
-	soc->ipa_uc_rx_rsc.ipa_reo_ring_base_vaddr =
-		srng_params.ring_base_vaddr;
-	soc->ipa_uc_rx_rsc.ipa_reo_ring_size =
-		srng_params.num_entries * srng_params.entry_size;
-	tp_addr = hal_srng_get_tp_addr(soc->hal_soc, hal_srng);
-	soc->ipa_uc_rx_rsc.ipa_reo_tp_paddr = tp_addr;
-
-	/* IPA RX_REFILL_BUF Ring - ipa_rx_refill_buf_ring */
-	if (dp_srng_setup(soc, &pdev->ipa_rx_refill_buf_ring, RXDMA_BUF, 2,
-				pdev->pdev_id, RXDMA_BUF_RING_SIZE)) {
-		QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
-				"%s: dp_srng_setup failed IPA rx refill ring\n",
-				__func__);
-		return -EFAULT;
-	}
-
-	hal_srng = pdev->ipa_rx_refill_buf_ring.hal_srng;
-	hal_get_srng_params(soc->hal_soc, hal_srng, &srng_params);
-	soc->ipa_uc_rx_rsc.ipa_rx_refill_buf_ring_base_paddr =
-		srng_params.ring_base_paddr;
-	soc->ipa_uc_rx_rsc.ipa_rx_refill_buf_ring_base_vaddr =
-		srng_params.ring_base_vaddr;
-	soc->ipa_uc_rx_rsc.ipa_rx_refill_buf_ring_size =
-		srng_params.num_entries * srng_params.entry_size;
-	hp_addr = hal_srng_get_hp_addr(soc->hal_soc, hal_srng);
-	soc->ipa_uc_rx_rsc.ipa_rx_refill_buf_hp_paddr = hp_addr;
-
-	QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
-		"%s: ring_base_paddr:%pK, ring_base_vaddr:%pK"
-		"_entries:%d, hp_addr:%pK\n",
-		__func__,
-		(void *)srng_params.ring_base_paddr,
-		(void *)srng_params.ring_base_vaddr,
-		srng_params.num_entries,
-		(void *)hp_addr);
-
-	return 0;
-}
-#else
-static inline int dp_ipa_ring_resource_setup(struct dp_soc *soc,
-					     struct dp_pdev *pdev)
-{
-	return 0;
-}
-#endif
-
 /*
 * dp_pdev_attach_wifi3() - attach txrx pdev
 * @osif_pdev: Opaque PDEV handle from OSIF/HDD
@@ -2402,7 +2113,7 @@ static struct cdp_pdev *dp_pdev_attach_wifi3(struct cdp_soc_t *txrx_soc,
 
 	if (dp_srng_setup(soc, &pdev->rxdma_mon_desc_ring,
 		RXDMA_MONITOR_DESC, 0, pdev_id, RXDMA_MONITOR_DESC_RING_SIZE)) {
-		QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
+		QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR,
 			"dp_srng_setup failed for rxdma_mon_desc_ring\n");
 		goto fail1;
 	}
@@ -2414,19 +2125,27 @@ static struct cdp_pdev *dp_pdev_attach_wifi3(struct cdp_soc_t *txrx_soc,
 		goto fail1;
 	}
 
+	/* Setup second Rx refill buffer ring */
+	if (dp_srng_setup(soc, &pdev->rx_refill_buf_ring2, RXDMA_BUF, 2,
+				pdev->pdev_id, RXDMA_REFILL_RING_SIZE)) {
+		QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR,
+			FL("dp_srng_setup failed second rx refill ring"));
+		goto fail1;
+	}
+
 	if (dp_ipa_ring_resource_setup(soc, pdev))
 		goto fail1;
 
 	if (dp_ipa_uc_attach(soc, pdev) != QDF_STATUS_SUCCESS) {
-		QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
-			"%s: dp_ipa_uc_attach failed\n", __func__);
+		QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR,
+			FL("dp_ipa_uc_attach failed"));
 		goto fail1;
 	}
 
 	/* Rx specific init */
 	if (dp_rx_pdev_attach(pdev)) {
 		QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR,
-			FL("dp_rx_pdev_attach failed "));
+			FL("dp_rx_pdev_attach failed"));
 		goto fail0;
 	}
 	DP_STATS_INIT(pdev);
@@ -2543,6 +2262,8 @@ static void dp_pdev_detach_wifi3(struct cdp_pdev *txrx_pdev, int force)
 
 	dp_ipa_uc_detach(soc, pdev);
 
+	dp_srng_cleanup(soc, &pdev->rx_refill_buf_ring2, RXDMA_BUF, 2);
+
 	/* Cleanup per PDEV REO rings if configured */
 	if (wlan_cfg_per_pdev_rx_ring(soc->wlan_cfg_ctx)) {
 		dp_srng_cleanup(soc, &soc->reo_dest_ring[pdev->pdev_id],
@@ -2691,27 +2412,6 @@ static void dp_soc_detach_wifi3(void *txrx_soc)
 	qdf_mem_free(soc);
 }
 
-/*
- * dp_setup_ipa_rx_refill_buf_ring() - setup IPA RX Refill buffer ring
- * @soc: data path SoC handle
- * @pdev: physical device handle
- *
- * Return: void
- */
-#ifdef IPA_OFFLOAD
-static inline void dp_config_ipa_rx_refill_buf_ring(struct dp_soc *soc,
-						   struct dp_pdev *pdev)
-{
-	htt_srng_setup(soc->htt_handle, 0,
-		       pdev->ipa_rx_refill_buf_ring.hal_srng, RXDMA_BUF);
-}
-#else
-static inline void dp_config_ipa_rx_refill_buf_ring(struct dp_soc *soc,
-						   struct dp_pdev *pdev)
-{
-}
-#endif
-
 /*
  * dp_rxdma_ring_config() - configure the RX DMA rings
  *
@@ -2744,7 +2444,10 @@ static void dp_rxdma_ring_config(struct dp_soc *soc)
 				 pdev->rx_refill_buf_ring.hal_srng,
 				 RXDMA_BUF);
 
-			dp_config_ipa_rx_refill_buf_ring(soc, pdev);
+			if (pdev->rx_refill_buf_ring2.hal_srng)
+				htt_srng_setup(soc->htt_handle, 0,
+					pdev->rx_refill_buf_ring2.hal_srng,
+					RXDMA_BUF);
 
 			if (soc->cdp_soc.ol_ops->
 				is_hw_dbs_2x2_capable) {
@@ -4333,11 +4036,9 @@ dp_print_ring_stats(struct dp_pdev *pdev)
 			&pdev->rx_refill_buf_ring,
 			"Rx Refill Buf Ring");
 
-	#ifdef IPA_OFFLOAD
 	dp_print_ring_stat_from_hal(pdev->soc,
-			&pdev->ipa_rx_refill_buf_ring,
-			"IPA Rx Refill Buf Ring");
-	#endif
+			&pdev->rx_refill_buf_ring2,
+			"Second Rx Refill Buf Ring");
 
 	dp_print_ring_stat_from_hal(pdev->soc,
 			&pdev->rxdma_mon_buf_ring,

+ 3 - 3
dp/wifi3.0/dp_peer.c

@@ -1751,10 +1751,11 @@ QDF_STATUS dp_get_vdevid(void *peer_handle, uint8_t *vdev_id)
 	return QDF_STATUS_SUCCESS;
 }
 
-struct cdp_vdev *dp_get_vdev_by_sta_id(uint8_t sta_id)
+struct cdp_vdev *dp_get_vdev_by_sta_id(struct cdp_pdev *pdev_handle,
+				       uint8_t sta_id)
 {
+	struct dp_pdev *pdev = (struct dp_pdev *)pdev_handle;
 	struct dp_peer *peer = NULL;
-	struct dp_pdev *pdev = NULL;
 
 	if (sta_id >= WLAN_MAX_STA_COUNT) {
 		QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_INFO_HIGH,
@@ -1762,7 +1763,6 @@ struct cdp_vdev *dp_get_vdev_by_sta_id(uint8_t sta_id)
 		return NULL;
 	}
 
-	pdev = cds_get_context(QDF_MODULE_ID_TXRX);
 	if (!pdev) {
 		QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_INFO_HIGH,
 			  "PDEV not found for sta_id [%d]", sta_id);

+ 3 - 4
dp/wifi3.0/dp_types.h

@@ -837,6 +837,7 @@ struct dp_ipa_resources {
 
 	/* IPA UC doorbell registers paddr */
 	qdf_dma_addr_t tx_comp_doorbell_paddr;
+	uint32_t *tx_comp_doorbell_vaddr;
 	qdf_dma_addr_t rx_ready_doorbell_paddr;
 };
 #endif
@@ -896,10 +897,8 @@ struct dp_pdev {
 	/* Ring used to replenish rx buffers (maybe to the firmware of MAC) */
 	struct dp_srng rx_refill_buf_ring;
 
-#ifdef IPA_OFFLOAD
-	/* Ring used to replenish IPA rx buffers */
-	struct dp_srng ipa_rx_refill_buf_ring;
-#endif
+	/* Second ring used to replenish rx buffers */
+	struct dp_srng rx_refill_buf_ring2;
 
 	/* Empty ring used by firmware to post rx buffers to the MAC */
 	struct dp_srng rx_mac_buf_ring[MAX_RX_MAC_RINGS];

+ 41 - 2
hal/wifi3.0/hal_api.h

@@ -338,11 +338,18 @@ extern void *hal_srng_setup(void *hal_soc, int ring_type, int ring_num,
 extern void hal_reo_remap_IX0(struct hal_soc *hal, uint32_t remap_val);
 
 /**
- * hal_srng_set_hp_paddr() - Set physical address to SRNG head pointer
+ * hal_srng_set_hp_paddr() - Set physical address to dest SRNG head pointer
  * @sring: sring pointer
  * @paddr: physical address
  */
-extern void hal_srng_set_hp_paddr(struct hal_srng *sring, uint64_t paddr);
+extern void hal_srng_dst_set_hp_paddr(struct hal_srng *sring, uint64_t paddr);
+
+/**
+ * hal_srng_dst_init_hp() - Initilaize head pointer with cached head pointer
+ * @srng: sring pointer
+ * @vaddr: virtual address
+ */
+extern void hal_srng_dst_init_hp(struct hal_srng *srng, uint32_t *vaddr);
 
 /**
  * hal_srng_cleanup - Deinitialize HW SRNG ring.
@@ -429,6 +436,37 @@ static inline void *hal_srng_dst_get_next(void *hal_soc, void *hal_ring)
 	return NULL;
 }
 
+/**
+ * hal_srng_dst_get_next_hp - Get next entry from a destination ring and move
+ * cached head pointer
+ *
+ * @hal_soc: Opaque HAL SOC handle
+ * @hal_ring: Destination ring pointer
+ *
+ * Return: Opaque pointer for next ring entry; NULL on failire
+ */
+static inline void *hal_srng_dst_get_next_hp(void *hal_soc, void *hal_ring)
+{
+	struct hal_srng *srng = (struct hal_srng *)hal_ring;
+	uint32_t *desc;
+	/* TODO: Using % is expensive, but we have to do this since
+	 * size of some SRNG rings is not power of 2 (due to descriptor
+	 * sizes). Need to create separate API for rings used
+	 * per-packet, with sizes power of 2 (TCL2SW, REO2SW,
+	 * SW2RXDMA and CE rings)
+	 */
+	uint32_t next_hp = (srng->u.dst_ring.cached_hp + srng->entry_size) %
+		srng->ring_size;
+
+	if (next_hp != srng->u.dst_ring.tp) {
+		desc = &(srng->ring_base_vaddr[srng->u.dst_ring.cached_hp]);
+		srng->u.dst_ring.cached_hp = next_hp;
+		return (void *)desc;
+	}
+
+	return NULL;
+}
+
 /**
  * hal_srng_dst_peek - Get next entry from a ring without moving tail pointer.
  * hal_srng_dst_get_next should be called subsequently to move the tail pointer
@@ -755,6 +793,7 @@ static inline void hal_srng_access_end(void *hal_soc, void *hal_ring)
 static inline void hal_srng_access_end_reap(void *hal_soc, void *hal_ring)
 {
 	struct hal_srng *srng = (struct hal_srng *)hal_ring;
+
 	SRNG_UNLOCK(&(srng->lock));
 }
 

+ 25 - 6
hal/wifi3.0/hal_srng.c

@@ -967,18 +967,37 @@ void hal_reo_remap_IX0(struct hal_soc *hal, uint32_t remap_val)
 }
 
 /**
- * hal_srng_set_hp_paddr() - Set physical address to SRNG head pointer
- * @sring: sring pointer
+ * hal_srng_dst_set_hp_paddr() - Set physical address to dest ring head pointer
+ * @srng: sring pointer
  * @paddr: physical address
  */
-void hal_srng_set_hp_paddr(struct hal_srng *sring,
-				uint64_t paddr)
+void hal_srng_dst_set_hp_paddr(struct hal_srng *srng,
+			       uint64_t paddr)
 {
-	SRNG_DST_REG_WRITE(sring, HP_ADDR_LSB,
+	SRNG_DST_REG_WRITE(srng, HP_ADDR_LSB,
 			   paddr & 0xffffffff);
-	SRNG_DST_REG_WRITE(sring, HP_ADDR_MSB,
+	SRNG_DST_REG_WRITE(srng, HP_ADDR_MSB,
 			   paddr >> 32);
 }
+
+/**
+ * hal_srng_dst_init_hp() - Initilaize destination ring head pointer
+ * @srng: sring pointer
+ * @vaddr: virtual address
+ */
+void hal_srng_dst_init_hp(struct hal_srng *srng,
+			  uint32_t *vaddr)
+{
+	srng->u.dst_ring.hp_addr = vaddr;
+	SRNG_DST_REG_WRITE(srng, HP, srng->u.dst_ring.cached_hp);
+	*(srng->u.dst_ring.hp_addr) = srng->u.dst_ring.cached_hp;
+
+	QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR,
+		"hp_addr=%p, cached_hp=%d, hp=%d\n",
+		(void *)srng->u.dst_ring.hp_addr, srng->u.dst_ring.cached_hp,
+		*(srng->u.dst_ring.hp_addr));
+}
+
 /**
  * hal_srng_dst_hw_init - Private function to initialize SRNG
  * destination ring HW