소스 검색

qcacmn: Handle allocation of descriptors to special packets

Special frames like EAPOL should not be dropped as it would cause
failure in connection. To prevent the dropping of higher priority
special frames, reserve a set of descriptors from the tx descriptor
pool.

Check the regular soc or pdev limit for the allocating tx descriptors
for the regular packets and use the reserved set of descriptors
only for the special packets.

CRs-Fixed: 3331359
Change-Id: I15532fb5e325ba6ad997090008bda8c52707a05b
Sreeramya Soratkal 2 년 전
부모
커밋
d148f093d2
5개의 변경된 파일73개의 추가작업 그리고 17개의 파일을 삭제
  1. 1 1
      dp/wifi3.0/be/dp_be_tx.c
  2. 2 1
      dp/wifi3.0/dp_main.c
  3. 2 2
      dp/wifi3.0/dp_tx.c
  4. 57 13
      dp/wifi3.0/dp_tx.h
  5. 11 0
      dp/wifi3.0/dp_types.h

+ 1 - 1
dp/wifi3.0/be/dp_be_tx.c

@@ -1582,7 +1582,7 @@ qdf_nbuf_t dp_tx_fast_send_be(struct cdp_soc_t *soc_hdl, uint8_t vdev_id,
 	DP_STATS_INC(vdev, tx_i.rcvd_per_core[desc_pool_id], 1);
 
 	pdev = vdev->pdev;
-	if (dp_tx_limit_check(vdev))
+	if (dp_tx_limit_check(vdev, nbuf))
 		return nbuf;
 
 	tx_desc = dp_tx_desc_alloc(soc, desc_pool_id);

+ 2 - 1
dp/wifi3.0/dp_main.c

@@ -15562,7 +15562,7 @@ void *dp_soc_init(struct dp_soc *soc, HTC_HANDLE htc_handle,
 	qdf_atomic_init(&soc->num_tx_exception);
 	soc->num_tx_allowed =
 		wlan_cfg_get_dp_soc_tx_device_limit(soc->wlan_cfg_ctx);
-
+	soc->num_reg_tx_allowed = soc->num_tx_allowed - MAX_TX_SPL_DESC;
 	if (soc->cdp_soc.ol_ops->get_dp_cfg_param) {
 		int ret = soc->cdp_soc.ol_ops->get_dp_cfg_param(soc->ctrl_psoc,
 				CDP_CFG_MAX_PEER_ID);
@@ -17170,6 +17170,7 @@ static QDF_STATUS dp_pdev_init(struct cdp_soc_t *txrx_soc,
 	qdf_event_create(&pdev->fw_obss_stats_event);
 
 	pdev->num_tx_allowed = wlan_cfg_get_num_tx_desc(soc->wlan_cfg_ctx);
+	pdev->num_reg_tx_allowed = pdev->num_tx_allowed - MAX_TX_SPL_DESC;
 
 	if (dp_rxdma_ring_setup(soc, pdev)) {
 		dp_init_err("%pK: RXDMA ring config failed", soc);

+ 2 - 2
dp/wifi3.0/dp_tx.c

@@ -1155,7 +1155,7 @@ struct dp_tx_desc_s *dp_tx_prepare_desc_single(struct dp_vdev *vdev,
 	struct dp_pdev *pdev = vdev->pdev;
 	struct dp_soc *soc = pdev->soc;
 
-	if (dp_tx_limit_check(vdev))
+	if (dp_tx_limit_check(vdev, nbuf))
 		return NULL;
 
 	/* Allocate software Tx descriptor */
@@ -1300,7 +1300,7 @@ static struct dp_tx_desc_s *dp_tx_prepare_desc(struct dp_vdev *vdev,
 	struct dp_pdev *pdev = vdev->pdev;
 	struct dp_soc *soc = pdev->soc;
 
-	if (dp_tx_limit_check(vdev))
+	if (dp_tx_limit_check(vdev, nbuf))
 		return NULL;
 
 	/* Allocate software Tx descriptor */

+ 57 - 13
dp/wifi3.0/dp_tx.h

@@ -1162,33 +1162,77 @@ dp_update_tx_desc_stats(struct dp_pdev *pdev)
 #endif /* CONFIG_WLAN_SYSFS_MEM_STATS */
 
 #ifdef QCA_TX_LIMIT_CHECK
+static inline bool is_spl_packet(qdf_nbuf_t nbuf)
+{
+	if (qdf_nbuf_is_ipv4_eapol_pkt(nbuf))
+		return true;
+	return false;
+}
+
 /**
- * dp_tx_limit_check - Check if allocated tx descriptors reached
- * soc max limit and pdev max limit
+ * is_dp_spl_tx_limit_reached - Check if the packet is a special packet to allow
+ * allocation if allocated tx descriptors are within the soc max limit
+ * and pdev max limit.
  * @vdev: DP vdev handle
  *
  * Return: true if allocated tx descriptors reached max configured value, else
  * false
  */
 static inline bool
-dp_tx_limit_check(struct dp_vdev *vdev)
+is_dp_spl_tx_limit_reached(struct dp_vdev *vdev, qdf_nbuf_t nbuf)
+{
+	struct dp_pdev *pdev = vdev->pdev;
+	struct dp_soc *soc = pdev->soc;
+
+	if (is_spl_packet(nbuf)) {
+		if (qdf_atomic_read(&soc->num_tx_outstanding) >=
+				soc->num_tx_allowed)
+			return true;
+
+		if (qdf_atomic_read(&pdev->num_tx_outstanding) >=
+			pdev->num_tx_allowed)
+			return true;
+
+		return false;
+	}
+
+	return true;
+}
+
+/**
+ * dp_tx_limit_check - Check if allocated tx descriptors reached
+ * soc max reg limit and pdev max reg limit for regular packets. Also check if
+ * the limit is reached for special packets.
+ * @vdev: DP vdev handle
+ *
+ * Return: true if allocated tx descriptors reached max limit for regular
+ * packets and in case of special packets, if the limit is reached max
+ * configured vale for the soc/pdev, else false
+ */
+static inline bool
+dp_tx_limit_check(struct dp_vdev *vdev, qdf_nbuf_t nbuf)
 {
 	struct dp_pdev *pdev = vdev->pdev;
 	struct dp_soc *soc = pdev->soc;
 
 	if (qdf_atomic_read(&soc->num_tx_outstanding) >=
-			soc->num_tx_allowed) {
-		dp_tx_info("queued packets are more than max tx, drop the frame");
-		DP_STATS_INC(vdev, tx_i.dropped.desc_na.num, 1);
-		return true;
+			soc->num_reg_tx_allowed) {
+		if (is_dp_spl_tx_limit_reached(vdev, nbuf)) {
+			dp_tx_info("queued packets are more than max tx, drop the frame");
+			DP_STATS_INC(vdev, tx_i.dropped.desc_na.num, 1);
+			return true;
+		}
 	}
 
 	if (qdf_atomic_read(&pdev->num_tx_outstanding) >=
-			pdev->num_tx_allowed) {
-		dp_tx_info("queued packets are more than max tx, drop the frame");
-		DP_STATS_INC(vdev, tx_i.dropped.desc_na.num, 1);
-		DP_STATS_INC(vdev, tx_i.dropped.desc_na_exc_outstand.num, 1);
-		return true;
+			pdev->num_reg_tx_allowed) {
+		if (is_dp_spl_tx_limit_reached(vdev, nbuf)) {
+			dp_tx_info("queued packets are more than max tx, drop the frame");
+			DP_STATS_INC(vdev, tx_i.dropped.desc_na.num, 1);
+			DP_STATS_INC(vdev,
+				     tx_i.dropped.desc_na_exc_outstand.num, 1);
+			return true;
+		}
 	}
 	return false;
 }
@@ -1251,7 +1295,7 @@ dp_tx_outstanding_dec(struct dp_pdev *pdev)
 
 #else //QCA_TX_LIMIT_CHECK
 static inline bool
-dp_tx_limit_check(struct dp_vdev *vdev)
+dp_tx_limit_check(struct dp_vdev *vdev, qdf_nbuf_t nbuf)
 {
 	return false;
 }

+ 11 - 0
dp/wifi3.0/dp_types.h

@@ -81,6 +81,9 @@
 #define MAX_TXDESC_POOLS 4
 #endif
 
+/* Max no of descriptors to handle special frames like EAPOL */
+#define MAX_TX_SPL_DESC 1024
+
 #define MAX_RXDESC_POOLS 4
 #define MAX_PPE_TXDESC_POOLS 1
 
@@ -2473,6 +2476,8 @@ struct dp_soc {
 	qdf_atomic_t num_tx_exception;
 	/* Num Tx allowed */
 	uint32_t num_tx_allowed;
+	/* Num Regular Tx allowed */
+	uint32_t num_reg_tx_allowed;
 	/* Preferred HW mode */
 	uint8_t preferred_hw_mode;
 
@@ -3139,6 +3144,12 @@ struct dp_pdev {
 	/* User configured max number of tx buffers */
 	uint32_t num_tx_allowed;
 
+	/*
+	 * User configured max num of tx buffers excluding the
+	 * number of buffers reserved for handling special frames
+	 */
+	uint32_t num_reg_tx_allowed;
+
 	/* unique cookie required for peer session */
 	uint32_t next_peer_cookie;