Kaynağa Gözat

qcacmn: return msdu link descriptors to wbm release ring

add support to return msdu link descriptors received on rxDMA error ring
to wbm release ring without freeing the nbufs (msdus).

Change-Id: Ic12c3f0531a639b61d3d77cee6266ce595e4d1c9
Tallapragada Kalyan 7 yıl önce
ebeveyn
işleme
0017291c13
3 değiştirilmiş dosya ile 80 ekleme ve 28 silme
  1. 2 1
      dp/wifi3.0/dp_rx.h
  2. 40 24
      dp/wifi3.0/dp_rx_err.c
  3. 38 3
      dp/wifi3.0/hal_rx.h

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

@@ -643,11 +643,12 @@ QDF_STATUS dp_rx_buffers_replenish(struct dp_soc *dp_soc, uint32_t mac_id,
  * @soc: core DP main context
  * @buf_addr_info: opaque pointer to the REO error ring descriptor
  * @buf_addr_info: void pointer to the buffer_addr_info
+ * @bm_action: put to idle_list or release to msdu_list
  * Return: QDF_STATUS
  */
 QDF_STATUS
 dp_rx_link_desc_buf_return(struct dp_soc *soc, struct dp_srng *dp_rxdma_srng,
-				void *buf_addr_info);
+				void *buf_addr_info, uint8_t bm_action);
 
 uint32_t
 dp_rxdma_err_process(struct dp_soc *soc, uint32_t mac_id,

+ 40 - 24
dp/wifi3.0/dp_rx_err.c

@@ -677,7 +677,7 @@ fail:
  * Return: QDF_STATUS
  */
 	static QDF_STATUS
-dp_rx_link_desc_return(struct dp_soc *soc, void *ring_desc)
+dp_rx_link_desc_return(struct dp_soc *soc, void *ring_desc, uint8_t bm_action)
 {
 	void *buf_addr_info = HAL_RX_REO_BUF_ADDR_INFO_GET(ring_desc);
 	struct dp_srng *wbm_desc_rel_ring = &soc->wbm_desc_rel_ring;
@@ -709,7 +709,7 @@ dp_rx_link_desc_return(struct dp_soc *soc, void *ring_desc)
 	if (qdf_likely(src_srng_desc)) {
 		/* Return link descriptor through WBM ring (SW2WBM)*/
 		hal_rx_msdu_link_desc_set(hal_soc,
-				src_srng_desc, buf_addr_info);
+				src_srng_desc, buf_addr_info, bm_action);
 		status = QDF_STATUS_SUCCESS;
 	} else {
 		struct hal_srng *srng = (struct hal_srng *)wbm_rel_srng;
@@ -841,7 +841,8 @@ dp_rx_err_process(struct dp_soc *soc, void *hal_ring, uint32_t quota)
 			continue;
 		}
 		/* Return link descriptor through WBM ring (SW2WBM)*/
-		dp_rx_link_desc_return(soc, ring_desc);
+		dp_rx_link_desc_return(soc, ring_desc,
+					HAL_BM_ACTION_PUT_IN_IDLE_LIST);
 	}
 
 done:
@@ -1109,6 +1110,8 @@ dp_rx_err_mpdu_pop(struct dp_soc *soc, uint32_t mac_id,
 	uint32_t i;
 	uint8_t push_reason;
 	uint8_t rxdma_error_code = 0;
+	uint8_t bm_action = HAL_BM_ACTION_PUT_IN_IDLE_LIST;
+	struct dp_pdev *pdev = soc->pdev_list[mac_id];
 
 	msdu = 0;
 
@@ -1134,29 +1137,42 @@ dp_rx_err_mpdu_pop(struct dp_soc *soc, uint32_t mac_id,
 				HAL_RX_NUM_MSDU_DESC:msdu_cnt;
 
 		hal_rx_msdu_list_get(rx_msdu_link_desc, &msdu_list, &num_msdus);
-
 		msdu_cnt -= num_msdus;
 
 		if (msdu_list.sw_cookie[0] != HAL_RX_COOKIE_SPECIAL) {
-			for (i = 0; i < num_msdus; i++) {
-				struct dp_rx_desc *rx_desc =
-					dp_rx_cookie_2_va_rxdma_buf(soc,
-						msdu_list.sw_cookie[i]);
-				qdf_assert(rx_desc);
-				msdu = rx_desc->nbuf;
-
-				qdf_nbuf_unmap_single(soc->osdev, msdu,
-					QDF_DMA_FROM_DEVICE);
-
-				QDF_TRACE(QDF_MODULE_ID_DP,
-					QDF_TRACE_LEVEL_DEBUG,
-					"[%s][%d] msdu_nbuf=%pK \n",
-					__func__, __LINE__, msdu);
-
-				qdf_nbuf_free(msdu);
-				rx_bufs_used++;
-				dp_rx_add_to_free_desc_list(head,
-					tail, rx_desc);
+			/* if the msdus belongs to NSS offloaded radio &&
+			 * the rbm is not SW3_BM then return the msdu_link
+			 * descriptor without freeing the msdus (nbufs). let
+			 * these buffers be given to NSS completion ring for
+			 * NSS to free them.
+			 * else iterate through the msdu link desc list and
+			 * free each msdu in the list.
+			 */
+			if (msdu_list.rbm[0] != HAL_RX_BUF_RBM_SW3_BM &&
+				wlan_cfg_get_dp_pdev_nss_enabled(
+							  pdev->wlan_cfg_ctx))
+				bm_action = HAL_BM_ACTION_RELEASE_MSDU_LIST;
+			else {
+				for (i = 0; i < num_msdus; i++) {
+					struct dp_rx_desc *rx_desc =
+						dp_rx_cookie_2_va_rxdma_buf(soc,
+							msdu_list.sw_cookie[i]);
+					qdf_assert(rx_desc);
+					msdu = rx_desc->nbuf;
+
+					qdf_nbuf_unmap_single(soc->osdev, msdu,
+						QDF_DMA_FROM_DEVICE);
+
+					QDF_TRACE(QDF_MODULE_ID_DP,
+						QDF_TRACE_LEVEL_DEBUG,
+						"[%s][%d] msdu_nbuf=%pK \n",
+						__func__, __LINE__, msdu);
+
+					qdf_nbuf_free(msdu);
+					rx_bufs_used++;
+					dp_rx_add_to_free_desc_list(head,
+						tail, rx_desc);
+				}
 			}
 		} else {
 			rxdma_error_code = HAL_RXDMA_ERR_WAR;
@@ -1165,7 +1181,7 @@ dp_rx_err_mpdu_pop(struct dp_soc *soc, uint32_t mac_id,
 		hal_rx_mon_next_link_desc_get(rx_msdu_link_desc, &buf_info,
 			&p_buf_addr_info);
 
-		dp_rx_link_desc_return(soc, p_last_buf_addr_info);
+		dp_rx_link_desc_return(soc, p_last_buf_addr_info, bm_action);
 		p_last_buf_addr_info = p_buf_addr_info;
 
 	} while (buf_info.paddr && msdu_cnt);

+ 38 - 3
dp/wifi3.0/hal_rx.h

@@ -302,6 +302,25 @@ enum hal_rx_ret_buf_manager {
  * shift by the corresponding _LSB. This is because, they are
  * finally taken and "OR'ed" into a single word again.
  */
+#define HAL_RX_FIRST_MSDU_IN_MPDU_FLAG_SET(msdu_info_ptr, val)		\
+	((*(((uint32_t *)msdu_info_ptr) +				\
+		(RX_MSDU_DESC_INFO_0_FIRST_MSDU_IN_MPDU_FLAG_OFFSET >> 2))) |= \
+		(val << RX_MSDU_DESC_INFO_0_FIRST_MSDU_IN_MPDU_FLAG_LSB) & \
+		RX_MSDU_DESC_INFO_0_FIRST_MSDU_IN_MPDU_FLAG_MASK)
+
+#define HAL_RX_LAST_MSDU_IN_MPDU_FLAG_SET(msdu_info_ptr, val)		\
+	((*(((uint32_t *)msdu_info_ptr) +				\
+		(RX_MSDU_DESC_INFO_0_LAST_MSDU_IN_MPDU_FLAG_OFFSET >> 2))) |= \
+		(val << RX_MSDU_DESC_INFO_0_LAST_MSDU_IN_MPDU_FLAG_LSB) & \
+		RX_MSDU_DESC_INFO_0_LAST_MSDU_IN_MPDU_FLAG_MASK)
+
+#define HAL_RX_MSDU_CONTINUATION_FLAG_SET(msdu_info_ptr, val)		\
+	((*(((uint32_t *)msdu_info_ptr) +				\
+		(RX_MSDU_DESC_INFO_0_MSDU_CONTINUATION_OFFSET >> 2))) |= \
+		(val << RX_MSDU_DESC_INFO_0_MSDU_CONTINUATION_LSB) & \
+		RX_MSDU_DESC_INFO_0_MSDU_CONTINUATION_MASK)
+
+
 #define HAL_RX_FIRST_MSDU_IN_MPDU_FLAG_GET(msdu_info_ptr)	\
 	((*_OFFSET_TO_WORD_PTR(msdu_info_ptr,			\
 		RX_MSDU_DESC_INFO_0_FIRST_MSDU_IN_MPDU_FLAG_OFFSET)) & \
@@ -1746,6 +1765,7 @@ hal_rx_mpdu_end_mic_err_get(uint8_t *buf)
 struct hal_rx_msdu_list {
 	struct hal_rx_msdu_desc_info msdu_info[HAL_RX_NUM_MSDU_DESC];
 	uint32_t sw_cookie[HAL_RX_NUM_MSDU_DESC];
+	uint8_t rbm[HAL_RX_NUM_MSDU_DESC];
 };
 
 struct hal_buf_info {
@@ -1789,9 +1809,20 @@ static inline void hal_rx_msdu_list_get(void *msdu_link_desc,
 		 * sometimes due to HW issue. Check msdu buffer address also */
 		if (HAL_RX_BUFFER_ADDR_31_0_GET(
 			&msdu_details[i].buffer_addr_info_details) == 0) {
+			/* set the last msdu bit in the prev msdu_desc_info */
+			msdu_desc_info =
+				HAL_RX_MSDU_DESC_INFO_GET(&msdu_details[i - 1]);
+			HAL_RX_LAST_MSDU_IN_MPDU_FLAG_SET(msdu_desc_info, 1);
 			break;
 		}
 		msdu_desc_info = HAL_RX_MSDU_DESC_INFO_GET(&msdu_details[i]);
+
+		/* set first MSDU bit or the last MSDU bit */
+		if (!i)
+			HAL_RX_FIRST_MSDU_IN_MPDU_FLAG_SET(msdu_desc_info, 1);
+		else if (i == (HAL_RX_NUM_MSDU_DESC - 1))
+			HAL_RX_LAST_MSDU_IN_MPDU_FLAG_SET(msdu_desc_info, 1);
+
 		msdu_list->msdu_info[i].msdu_flags =
 			 HAL_RX_MSDU_FLAGS_GET(msdu_desc_info);
 		msdu_list->msdu_info[i].msdu_len =
@@ -1799,7 +1830,8 @@ static inline void hal_rx_msdu_list_get(void *msdu_link_desc,
 		msdu_list->sw_cookie[i] =
 			 HAL_RX_BUF_COOKIE_GET(
 				&msdu_details[i].buffer_addr_info_details);
-
+		 msdu_list->rbm[i] = HAL_RX_BUF_RBM_GET(
+				&msdu_details[i].buffer_addr_info_details);
 		QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG,
 			"[%s][%d] i=%d sw_cookie=%d\n",
 			__func__, __LINE__, i, msdu_list->sw_cookie[i]);
@@ -1942,6 +1974,7 @@ enum hal_rxdma_error_code {
  * HW BM action settings in WBM release ring
  */
 #define HAL_BM_ACTION_PUT_IN_IDLE_LIST 0
+#define HAL_BM_ACTION_RELEASE_MSDU_LIST 1
 
 /**
  * enum hal_rx_wbm_error_source: Indicates which module initiated the
@@ -2030,12 +2063,14 @@ static inline bool hal_rx_reo_is_2k_jump(void *rx_desc)
  * @ soc		: HAL version of the SOC pointer
  * @ src_srng_desc	: void pointer to the WBM Release Ring descriptor
  * @ buf_addr_info	: void pointer to the buffer_addr_info
+ * @ bm_action		: put in IDLE list or release to MSDU_LIST
  *
  * Return: void
  */
 /* look at implementation at dp_hw_link_desc_pool_setup()*/
 static inline void hal_rx_msdu_link_desc_set(struct hal_soc *soc,
-			void *src_srng_desc, void *buf_addr_info)
+			void *src_srng_desc, void *buf_addr_info,
+			uint8_t bm_action)
 {
 	struct wbm_release_ring *wbm_rel_srng =
 			(struct wbm_release_ring *)src_srng_desc;
@@ -2046,7 +2081,7 @@ static inline void hal_rx_msdu_link_desc_set(struct hal_soc *soc,
 	HAL_DESC_SET_FIELD(src_srng_desc, WBM_RELEASE_RING_2,
 		RELEASE_SOURCE_MODULE, HAL_RX_WBM_ERR_SRC_SW);
 	HAL_DESC_SET_FIELD(src_srng_desc, WBM_RELEASE_RING_2, BM_ACTION,
-		HAL_BM_ACTION_PUT_IN_IDLE_LIST);
+		bm_action);
 	HAL_DESC_SET_FIELD(src_srng_desc, WBM_RELEASE_RING_2,
 		BUFFER_OR_DESC_TYPE, HAL_RX_WBM_BUF_TYPE_MSDU_LINK_DESC);
 }