qcacmn: Fix the next link descriptor read issue

Link descriptor were getting freed by the pointer
of the previous freed link descriptor. This patch
fixes by copying the address of the current in a
local descriptor info and using it to free the
current.

Change-Id: I95e137ba5b1f0ad21b0e6fb39f6671e1d5b65ba6
CRs-Fixed: 2577624
diff --git a/dp/wifi3.0/dp_rx.h b/dp/wifi3.0/dp_rx.h
index 5541667..8b88d88 100644
--- a/dp/wifi3.0/dp_rx.h
+++ b/dp/wifi3.0/dp_rx.h
@@ -978,7 +978,7 @@
  */
 QDF_STATUS
 dp_rx_link_desc_return_by_addr(struct dp_soc *soc,
-			       hal_link_desc_t link_desc_addr,
+			       hal_buff_addrinfo_t link_desc_addr,
 			       uint8_t bm_action);
 
 /**
diff --git a/dp/wifi3.0/dp_rx_err.c b/dp/wifi3.0/dp_rx_err.c
index ebbe1a4..29fd9ac 100644
--- a/dp/wifi3.0/dp_rx_err.c
+++ b/dp/wifi3.0/dp_rx_err.c
@@ -165,7 +165,7 @@
  */
 QDF_STATUS
 dp_rx_link_desc_return_by_addr(struct dp_soc *soc,
-			       hal_link_desc_t link_desc_addr,
+			       hal_buff_addrinfo_t link_desc_addr,
 			       uint8_t bm_action)
 {
 	struct dp_srng *wbm_desc_rel_ring = &soc->wbm_desc_rel_ring;
@@ -1719,8 +1719,6 @@
 	struct hal_rx_msdu_list msdu_list;
 	uint16_t num_msdus;
 	struct hal_buf_info buf_info;
-	void *p_buf_addr_info;
-	void *p_last_buf_addr_info;
 	uint32_t rx_bufs_used = 0;
 	uint32_t msdu_cnt;
 	uint32_t i;
@@ -1728,6 +1726,7 @@
 	uint8_t rxdma_error_code = 0;
 	uint8_t bm_action = HAL_BM_ACTION_PUT_IN_IDLE_LIST;
 	struct dp_pdev *pdev = dp_get_pdev_for_mac_id(soc, mac_id);
+	uint32_t rx_link_buf_info[HAL_RX_BUFFINFO_NUM_DWORDS];
 	hal_rxdma_desc_t ring_desc;
 
 	msdu = 0;
@@ -1735,7 +1734,7 @@
 	last = NULL;
 
 	hal_rx_reo_ent_buf_paddr_get(rxdma_dst_ring_desc, &buf_info,
-		&p_last_buf_addr_info, &msdu_cnt);
+					&msdu_cnt);
 
 	push_reason =
 		hal_rx_reo_ent_rxdma_push_reason_get(rxdma_dst_ring_desc);
@@ -1811,12 +1810,18 @@
 			rxdma_error_code = HAL_RXDMA_ERR_WAR;
 		}
 
-		hal_rx_mon_next_link_desc_get(rx_msdu_link_desc, &buf_info,
-			&p_buf_addr_info);
+		/*
+		 * Store the current link buffer into to the local structure
+		 * to be used for release purpose.
+		 */
+		hal_rxdma_buff_addr_info_set(rx_link_buf_info, buf_info.paddr,
+					     buf_info.sw_cookie, buf_info.rbm);
 
-		dp_rx_link_desc_return(soc, p_last_buf_addr_info, bm_action);
-		p_last_buf_addr_info = p_buf_addr_info;
-
+		hal_rx_mon_next_link_desc_get(rx_msdu_link_desc, &buf_info);
+		dp_rx_link_desc_return_by_addr(soc,
+					       (hal_buff_addrinfo_t)
+						rx_link_buf_info,
+						bm_action);
 	} while (buf_info.paddr);
 
 	DP_STATS_INC(soc, rx.err.rxdma_error[rxdma_error_code], 1);
@@ -1907,18 +1912,15 @@
 	struct hal_rx_msdu_list msdu_list;
 	uint16_t num_msdus;
 	struct hal_buf_info buf_info;
-	void *p_buf_addr_info;
-	void *p_last_buf_addr_info;
-	uint32_t rx_bufs_used = 0;
-	uint32_t msdu_cnt;
-	uint32_t i;
+	uint32_t rx_bufs_used = 0, msdu_cnt, i;
+	uint32_t rx_link_buf_info[HAL_RX_BUFFINFO_NUM_DWORDS];
 
 	msdu = 0;
 
 	last = NULL;
 
 	hal_rx_reo_ent_buf_paddr_get(rxdma_dst_ring_desc, &buf_info,
-				     &p_last_buf_addr_info, &msdu_cnt);
+				     &msdu_cnt);
 
 	do {
 		rx_msdu_link_desc =
@@ -1951,13 +1953,17 @@
 			}
 		}
 
-		hal_rx_mon_next_link_desc_get(rx_msdu_link_desc, &buf_info,
-					      &p_buf_addr_info);
+		/*
+		 * Store the current link buffer into to the local structure
+		 * to be used for release purpose.
+		 */
+		hal_rxdma_buff_addr_info_set(rx_link_buf_info, buf_info.paddr,
+					     buf_info.sw_cookie, buf_info.rbm);
 
-		dp_rx_link_desc_return(soc, p_last_buf_addr_info,
+		hal_rx_mon_next_link_desc_get(rx_msdu_link_desc, &buf_info);
+		dp_rx_link_desc_return_by_addr(soc, (hal_buff_addrinfo_t)
+					rx_link_buf_info,
 				       HAL_BM_ACTION_PUT_IN_IDLE_LIST);
-		p_last_buf_addr_info = p_buf_addr_info;
-
 	} while (buf_info.paddr);
 
 	return rx_bufs_used;
diff --git a/dp/wifi3.0/dp_rx_mon_dest.c b/dp/wifi3.0/dp_rx_mon_dest.c
index 46dd84f..284c77d 100644
--- a/dp/wifi3.0/dp_rx_mon_dest.c
+++ b/dp/wifi3.0/dp_rx_mon_dest.c
@@ -55,7 +55,7 @@
  */
 static QDF_STATUS
 dp_rx_mon_link_desc_return(struct dp_pdev *dp_pdev,
-	void *buf_addr_info, int mac_id)
+	hal_buff_addrinfo_t buf_addr_info, int mac_id)
 {
 	struct dp_srng *dp_srng;
 	hal_ring_handle_t hal_ring_hdl;
@@ -153,14 +153,15 @@
  */
 static inline
 QDF_STATUS dp_rx_monitor_link_desc_return(struct dp_pdev *pdev,
-					  void *p_last_buf_addr_info,
+					  hal_buff_addrinfo_t
+					  p_last_buf_addr_info,
 					  uint8_t mac_id, uint8_t bm_action)
 {
 	if (pdev->soc->wlan_cfg_ctx->rxdma1_enable)
 		return dp_rx_mon_link_desc_return(pdev, p_last_buf_addr_info,
 						  mac_id);
 
-	return dp_rx_link_desc_return(pdev->soc, p_last_buf_addr_info,
+	return dp_rx_link_desc_return_by_addr(pdev->soc, p_last_buf_addr_info,
 				      bm_action);
 }
 
@@ -269,8 +270,6 @@
 	uint16_t num_msdus;
 	uint32_t rx_buf_size, rx_pkt_offset;
 	struct hal_buf_info buf_info;
-	void *p_buf_addr_info;
-	void *p_last_buf_addr_info;
 	uint32_t rx_bufs_used = 0;
 	uint32_t msdu_ppdu_id, msdu_cnt;
 	uint8_t *data;
@@ -280,13 +279,13 @@
 	bool drop_mpdu = false;
 	uint8_t bm_action = HAL_BM_ACTION_PUT_IN_IDLE_LIST;
 	uint64_t nbuf_paddr = 0;
+	uint32_t rx_link_buf_info[HAL_RX_BUFFINFO_NUM_DWORDS];
 
 	msdu = 0;
 
 	last = NULL;
 
-	hal_rx_reo_ent_buf_paddr_get(rxdma_dst_ring_desc, &buf_info,
-		&p_last_buf_addr_info, &msdu_cnt);
+	hal_rx_reo_ent_buf_paddr_get(rxdma_dst_ring_desc, &buf_info, &msdu_cnt);
 
 	if ((hal_rx_reo_ent_rxdma_push_reason_get(rxdma_dst_ring_desc) ==
 		HAL_RX_WBM_RXDMA_PSH_RSN_ERROR)) {
@@ -505,19 +504,22 @@
 				tail, rx_desc);
 		}
 
-		hal_rx_mon_next_link_desc_get(rx_msdu_link_desc, &buf_info,
-			&p_buf_addr_info);
+		/*
+		 * Store the current link buffer into to the local
+		 * structure to be  used for release purpose.
+		 */
+		hal_rxdma_buff_addr_info_set(rx_link_buf_info, buf_info.paddr,
+					     buf_info.sw_cookie, buf_info.rbm);
 
+		hal_rx_mon_next_link_desc_get(rx_msdu_link_desc, &buf_info);
 		if (dp_rx_monitor_link_desc_return(dp_pdev,
-						   p_last_buf_addr_info,
+						   (hal_buff_addrinfo_t)
+						   rx_link_buf_info,
 						   mac_id,
 						   bm_action)
 						   != QDF_STATUS_SUCCESS)
 			QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR,
 				  "dp_rx_monitor_link_desc_return failed");
-
-		p_last_buf_addr_info = p_buf_addr_info;
-
 	} while (buf_info.paddr && msdu_cnt);
 
 	if (last)
diff --git a/hal/wifi3.0/hal_api.h b/hal/wifi3.0/hal_api.h
index 3389b3d..46fb142 100644
--- a/hal/wifi3.0/hal_api.h
+++ b/hal/wifi3.0/hal_api.h
@@ -76,6 +76,12 @@
 struct hal_rxdma_desc;
 typedef struct hal_rxdma_desc *hal_rxdma_desc_t;
 
+/**
+ * hal_buff_addrinfo - opaque handle for DP buffer address info
+ */
+struct hal_buff_addrinfo;
+typedef struct hal_buff_addrinfo *hal_buff_addrinfo_t;
+
 #ifdef ENABLE_VERBOSE_DEBUG
 static inline void
 hal_set_verbose_debug(bool flag)
diff --git a/hal/wifi3.0/hal_api_mon.h b/hal/wifi3.0/hal_api_mon.h
index 1cf89ea..607159f 100644
--- a/hal/wifi3.0/hal_api_mon.h
+++ b/hal/wifi3.0/hal_api_mon.h
@@ -265,7 +265,6 @@
 static inline
 void hal_rx_reo_ent_buf_paddr_get(hal_rxdma_desc_t rx_desc,
 				  struct hal_buf_info *buf_info,
-				  void **pp_buf_addr_info,
 				  uint32_t *msdu_cnt
 )
 {
@@ -292,18 +291,17 @@
 		(HAL_RX_BUFFER_ADDR_39_32_GET(buf_addr_info)) << 32));
 
 	buf_info->sw_cookie = HAL_RX_BUF_COOKIE_GET(buf_addr_info);
+	buf_info->rbm = HAL_RX_BUF_RBM_GET(buf_addr_info);
 
 	QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG,
 		"[%s][%d] ReoAddr=%pK, addrInfo=%pK, paddr=0x%llx, loopcnt=%d",
 		__func__, __LINE__, reo_ent_ring, buf_addr_info,
 	(unsigned long long)buf_info->paddr, loop_cnt);
-
-	*pp_buf_addr_info = (void *)buf_addr_info;
 }
 
 static inline
 void hal_rx_mon_next_link_desc_get(void *rx_msdu_link_desc,
-	struct hal_buf_info *buf_info, void **pp_buf_addr_info)
+			struct hal_buf_info *buf_info)
 {
 	struct rx_msdu_link *msdu_link =
 		(struct rx_msdu_link *)rx_msdu_link_desc;
@@ -317,8 +315,7 @@
 		(HAL_RX_BUFFER_ADDR_39_32_GET(buf_addr_info)) << 32));
 
 	buf_info->sw_cookie = HAL_RX_BUF_COOKIE_GET(buf_addr_info);
-
-	*pp_buf_addr_info = (void *)buf_addr_info;
+	buf_info->rbm = HAL_RX_BUF_RBM_GET(buf_addr_info);
 }
 
 /**
@@ -334,7 +331,7 @@
 static inline
 void hal_rx_mon_msdu_link_desc_set(hal_soc_handle_t hal_soc_hdl,
 				   void *src_srng_desc,
-				   void *buf_addr_info)
+				   hal_buff_addrinfo_t buf_addr_info)
 {
 	struct buffer_addr_info *wbm_srng_buffer_addr_info =
 			(struct buffer_addr_info *)src_srng_desc;
diff --git a/hal/wifi3.0/hal_hw_headers.h b/hal/wifi3.0/hal_hw_headers.h
index 286f0c0..5348c9b 100644
--- a/hal/wifi3.0/hal_hw_headers.h
+++ b/hal/wifi3.0/hal_hw_headers.h
@@ -87,6 +87,9 @@
 #define SRNG_LOOP_CNT_MASK REO_DESTINATION_RING_15_LOOPING_COUNT_MASK
 #define SRNG_LOOP_CNT_LSB REO_DESTINATION_RING_15_LOOPING_COUNT_LSB
 
+/* HAL Macro to get the buffer info size */
+#define HAL_RX_BUFFINFO_NUM_DWORDS NUM_OF_DWORDS_BUFFER_ADDR_INFO
+
 #define HAL_DEFAULT_BE_BK_VI_REO_TIMEOUT_MS 100 /* milliseconds */
 #define HAL_DEFAULT_VO_REO_TIMEOUT_MS 40 /* milliseconds */
 
diff --git a/hal/wifi3.0/hal_rx.h b/hal/wifi3.0/hal_rx.h
index 1c0fcb0..cc567ea 100644
--- a/hal/wifi3.0/hal_rx.h
+++ b/hal/wifi3.0/hal_rx.h
@@ -1702,6 +1702,7 @@
 struct hal_buf_info {
 	uint64_t paddr;
 	uint32_t sw_cookie;
+	uint8_t rbm;
 };
 
 /**
@@ -2096,7 +2097,7 @@
 static inline
 void hal_rx_msdu_link_desc_set(hal_soc_handle_t hal_soc_hdl,
 			       void *src_srng_desc,
-			       hal_link_desc_t buf_addr_info,
+			       hal_buff_addrinfo_t buf_addr_info,
 			       uint8_t bm_action)
 {
 	struct wbm_release_ring *wbm_rel_srng =