ソースを参照

qcacmn: Resolve null pointer dereference issue in flush txdesc

On Flushing txdesc resource on pdev detach caused null ptr
issue, resolved it by adding dummy function to not free desc
resources for mcl, as it is freed in vdev detach.

Change-Id: I9ab777571623c926b4ecbf9c95ba0837101eba26
CRs-Fixed: 2179488
Ruchi, Agrawal 7 年 前
コミット
e8eeb44420
1 ファイル変更55 行追加52 行削除
  1. 55 52
      dp/wifi3.0/dp_tx.c

+ 55 - 52
dp/wifi3.0/dp_tx.c

@@ -2788,7 +2788,7 @@ uint32_t dp_tx_comp_handler(struct dp_soc *soc, void *hal_srng, uint32_t quota)
 					htt_tx_status);
 		} else {
 			/* Pool id is not matching. Error */
-			if (tx_desc && (tx_desc->pool_id != pool_id)) {
+			if (tx_desc->pool_id != pool_id) {
 				QDF_TRACE(QDF_MODULE_ID_DP,
 					QDF_TRACE_LEVEL_FATAL,
 					"Tx Comp pool id %d not matched %d",
@@ -2964,57 +2964,6 @@ QDF_STATUS dp_tx_pdev_attach(struct dp_pdev *pdev)
 	return QDF_STATUS_SUCCESS;
 }
 
-/* dp_tx_desc_flush() - release resources associated
- *                      to tx_desc
- * @pdev: physical device instance
- *
- * This function will free all outstanding Tx buffers,
- * including ME buffer for which either free during
- * completion didn't happened or completion is not
- * received.
-*/
-static void dp_tx_desc_flush(struct dp_pdev *pdev)
-{
-	uint8_t i, num_pool;
-	uint32_t j;
-	uint32_t num_desc;
-	struct dp_soc *soc = pdev->soc;
-	struct dp_tx_desc_s *tx_desc = NULL;
-
-	num_desc = wlan_cfg_get_num_tx_desc(soc->wlan_cfg_ctx);
-	num_pool = wlan_cfg_get_num_tx_desc_pool(soc->wlan_cfg_ctx);
-
-	for (i = 0; i < num_pool; i++) {
-		for (j = 0; j < num_desc; j++) {
-			tx_desc = dp_tx_desc_find(soc, i,
-					(j & DP_TX_DESC_ID_PAGE_MASK) >>
-					DP_TX_DESC_ID_PAGE_OS,
-					(j & DP_TX_DESC_ID_OFFSET_MASK) >>
-					DP_TX_DESC_ID_OFFSET_OS);
-
-			if (tx_desc && (tx_desc->pdev == pdev) &&
-				(tx_desc->flags & DP_TX_DESC_FLAG_ALLOCATED)) {
-				dp_tx_comp_free_buf(soc, tx_desc);
-				dp_tx_desc_release(tx_desc, i);
-			}
-		}
-	}
-}
-
-/**
- * dp_tx_pdev_detach() - detach pdev from dp tx
- * @pdev: physical device instance
- *
- * Return: QDF_STATUS_SUCCESS: success
- *         QDF_STATUS_E_RESOURCES: Error return
- */
-QDF_STATUS dp_tx_pdev_detach(struct dp_pdev *pdev)
-{
-	dp_tx_desc_flush(pdev);
-	dp_tx_me_exit(pdev);
-	return QDF_STATUS_SUCCESS;
-}
-
 #ifdef QCA_LL_TX_FLOW_CONTROL_V2
 /* Pools will be allocated dynamically */
 static int dp_tx_alloc_static_pools(struct dp_soc *soc, int num_pool,
@@ -3037,6 +2986,10 @@ static void dp_tx_delete_static_pools(struct dp_soc *soc, int num_pool)
 	for (i = 0; i < num_pool; i++)
 		qdf_spinlock_destroy(&soc->tx_desc[i].flow_pool_lock);
 }
+
+static void dp_tx_desc_flush(struct dp_pdev *pdev)
+{
+}
 #else /* QCA_LL_TX_FLOW_CONTROL_V2! */
 static int dp_tx_alloc_static_pools(struct dp_soc *soc, int num_pool,
 					int num_desc)
@@ -3067,8 +3020,58 @@ static void dp_tx_delete_static_pools(struct dp_soc *soc, int num_pool)
 	}
 }
 
+/* dp_tx_desc_flush() - release resources associated
+ *                      to tx_desc
+ * @pdev: physical device instance
+ *
+ * This function will free all outstanding Tx buffers,
+ * including ME buffer for which either free during
+ * completion didn't happened or completion is not
+ * received.
+*/
+static void dp_tx_desc_flush(struct dp_pdev *pdev)
+{
+	uint8_t i, num_pool;
+	uint32_t j;
+	uint32_t num_desc;
+	struct dp_soc *soc = pdev->soc;
+	struct dp_tx_desc_s *tx_desc = NULL;
+
+	num_desc = wlan_cfg_get_num_tx_desc(soc->wlan_cfg_ctx);
+	num_pool = wlan_cfg_get_num_tx_desc_pool(soc->wlan_cfg_ctx);
+
+	for (i = 0; i < num_pool; i++) {
+		for (j = 0; j < num_desc; j++) {
+			tx_desc = dp_tx_desc_find(soc, i,
+					(j & DP_TX_DESC_ID_PAGE_MASK) >>
+					DP_TX_DESC_ID_PAGE_OS,
+					(j & DP_TX_DESC_ID_OFFSET_MASK) >>
+					DP_TX_DESC_ID_OFFSET_OS);
+
+			if (tx_desc && (tx_desc->pdev == pdev) &&
+				(tx_desc->flags & DP_TX_DESC_FLAG_ALLOCATED)) {
+				dp_tx_comp_free_buf(soc, tx_desc);
+				dp_tx_desc_release(tx_desc, i);
+			}
+		}
+	}
+}
 #endif /* !QCA_LL_TX_FLOW_CONTROL_V2 */
 
+/**
+ * dp_tx_pdev_detach() - detach pdev from dp tx
+ * @pdev: physical device instance
+ *
+ * Return: QDF_STATUS_SUCCESS: success
+ *         QDF_STATUS_E_RESOURCES: Error return
+ */
+QDF_STATUS dp_tx_pdev_detach(struct dp_pdev *pdev)
+{
+	dp_tx_desc_flush(pdev);
+	dp_tx_me_exit(pdev);
+	return QDF_STATUS_SUCCESS;
+}
+
 /**
  * dp_tx_soc_detach() - detach soc from dp tx
  * @soc: core txrx main context