Quellcode durchsuchen

qcacmn: Add support for delivering unencrypted errors

In mesh mode, it is possible to receive unencrypted frames while security
is enabled. Deliver such frames to OS stack.

Change-Id: Id148b6ecc1432b419ae97c92f2340155f3d851bf
CRs-Fixed: 2004658
Pamidipati, Vijay vor 8 Jahren
Ursprung
Commit
eb8a92cedc
4 geänderte Dateien mit 134 neuen und 22 gelöschten Zeilen
  1. 3 4
      dp/wifi3.0/dp_rx.c
  2. 1 1
      dp/wifi3.0/dp_rx.h
  3. 129 16
      dp/wifi3.0/dp_rx_err.c
  4. 1 1
      dp/wifi3.0/hal_rx.h

+ 3 - 4
dp/wifi3.0/dp_rx.c

@@ -220,7 +220,7 @@ QDF_STATUS dp_rx_buffers_replenish(struct dp_soc *dp_soc, uint32_t mac_id,
  */
 void
 dp_rx_deliver_raw(struct dp_vdev *vdev, qdf_nbuf_t nbuf_list,
-					struct cdp_peer *peer)
+					struct dp_peer *peer)
 {
 	qdf_nbuf_t deliver_list_head = NULL;
 	qdf_nbuf_t deliver_list_tail = NULL;
@@ -248,7 +248,7 @@ dp_rx_deliver_raw(struct dp_vdev *vdev, qdf_nbuf_t nbuf_list,
 	}
 
 	vdev->osif_rsim_rx_decap(vdev->osif_vdev, &deliver_list_head,
-				 &deliver_list_tail, peer);
+				 &deliver_list_tail, (struct cdp_peer*) peer);
 
 	vdev->osif_rx(vdev->osif_vdev, deliver_list_head);
 }
@@ -1308,8 +1308,7 @@ done:
 
 		if (qdf_unlikely(vdev->rx_decap_type == htt_cmn_pkt_type_raw) ||
 			(vdev->rx_decap_type == htt_cmn_pkt_type_native_wifi))
-			dp_rx_deliver_raw(vdev, deliver_list_head,
-						(struct cdp_peer *) peer);
+			dp_rx_deliver_raw(vdev, deliver_list_head, peer);
 		else if (qdf_likely(vdev->osif_rx) && deliver_list_head)
 			vdev->osif_rx(vdev->osif_vdev, deliver_list_head);
 	}

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

@@ -305,7 +305,7 @@ void dp_rx_desc_pool_free(struct dp_soc *soc,
 				struct rx_desc_pool *rx_desc_pool);
 
 void dp_rx_deliver_raw(struct dp_vdev *vdev, qdf_nbuf_t nbuf_list,
-				struct cdp_peer *peer);
+				struct dp_peer *peer);
 
 /**
  * dp_rx_add_to_free_desc_list() - Adds to a local free descriptor list

+ 129 - 16
dp/wifi3.0/dp_rx_err.c

@@ -342,10 +342,7 @@ dp_rx_null_q_desc_handle(struct dp_soc *soc, struct dp_rx_desc *rx_desc,
 	 * Advance the packet start pointer by total size of
 	 * pre-header TLV's
 	 */
-	qdf_nbuf_pull_head(nbuf, RX_PKT_TLVS_LEN);
-
-	if (l2_hdr_offset)
-		qdf_nbuf_pull_head(nbuf, l2_hdr_offset);
+	qdf_nbuf_pull_head(nbuf, (l2_hdr_offset + RX_PKT_TLVS_LEN));
 
 	nbuf_data = qdf_nbuf_data(nbuf);
 	for (count = 0; count < soc->mect_cnt; count++) {
@@ -393,7 +390,7 @@ dp_rx_null_q_desc_handle(struct dp_soc *soc, struct dp_rx_desc *rx_desc,
 
 	if (qdf_unlikely(vdev->rx_decap_type == htt_cmn_pkt_type_raw)) {
 		qdf_nbuf_set_next(nbuf, NULL);
-		dp_rx_deliver_raw(vdev, nbuf, (struct cdp_peer *) peer);
+		dp_rx_deliver_raw(vdev, nbuf, peer);
 	} else {
 		if (qdf_unlikely(peer->bss_peer)) {
 			QDF_TRACE(QDF_MODULE_ID_DP,
@@ -423,6 +420,115 @@ fail:
 	return rx_bufs_used;
 }
 
+/**
+* dp_rx_err_deliver() - Function to deliver error frames to OS
+*
+* @soc: core DP main context
+* @rx_desc : pointer to the sw rx descriptor
+* @head: pointer to head of rx descriptors to be added to free list
+* @tail: pointer to tail of rx descriptors to be added to free list
+* quota: upper limit of descriptors that can be reaped
+*
+* Return: uint32_t: No. of Rx buffers reaped
+*/
+static uint32_t
+dp_rx_err_deliver(struct dp_soc *soc, struct dp_rx_desc *rx_desc,
+			union dp_rx_desc_list_elem_t **head,
+			union dp_rx_desc_list_elem_t **tail,
+			uint32_t quota)
+{
+	uint32_t rx_bufs_used = 0;
+	uint32_t pkt_len, l2_hdr_offset;
+	uint16_t msdu_len;
+	qdf_nbuf_t nbuf;
+	struct dp_vdev *vdev;
+	uint16_t peer_id = 0xFFFF;
+	struct dp_peer *peer = NULL;
+
+	rx_bufs_used++;
+
+	nbuf = rx_desc->nbuf;
+
+	qdf_nbuf_unmap_single(soc->osdev, nbuf,
+				QDF_DMA_BIDIRECTIONAL);
+
+	rx_desc->rx_buf_start = qdf_nbuf_data(nbuf);
+
+	/*
+	 * Check if DMA completed -- msdu_done is the last bit
+	 * to be written
+	 */
+	if (!hal_rx_attn_msdu_done_get(rx_desc->rx_buf_start)) {
+
+		QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR,
+				FL("MSDU DONE failure"));
+
+		hal_rx_dump_pkt_tlvs(rx_desc->rx_buf_start,
+					QDF_TRACE_LEVEL_INFO);
+		qdf_assert(0);
+	}
+
+	peer_id = hal_rx_mpdu_start_sw_peer_id_get(rx_desc->rx_buf_start);
+	peer = dp_peer_find_by_id(soc, peer_id);
+
+	if (!peer) {
+		QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR,
+				FL("peer is NULL"));
+		DP_STATS_INC_PKT(soc, rx.err.rx_invalid_peer, 1,
+				qdf_nbuf_len(nbuf));
+		/* Drop & free packet */
+		qdf_nbuf_free(nbuf);
+		goto fail;
+	}
+
+	vdev = peer->vdev;
+	if (!vdev) {
+		QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR,
+				FL("INVALID vdev %p OR osif_rx"), vdev);
+		/* Drop & free packet */
+		qdf_nbuf_free(nbuf);
+		DP_STATS_INC(soc, rx.err.invalid_vdev, 1);
+		goto fail;
+	}
+
+	/* Drop & free packet if mesh mode not enabled */
+	if (!vdev->mesh_vdev) {
+		qdf_nbuf_free(nbuf);
+		DP_STATS_INC(soc, rx.err.invalid_vdev, 1);
+		goto fail;
+	}
+
+	l2_hdr_offset =
+		hal_rx_msdu_end_l3_hdr_padding_get(rx_desc->rx_buf_start);
+
+	msdu_len =
+		hal_rx_msdu_start_msdu_len_get(rx_desc->rx_buf_start);
+
+	pkt_len = msdu_len + l2_hdr_offset + RX_PKT_TLVS_LEN;
+
+	/* Set length in nbuf */
+	qdf_nbuf_set_pktlen(nbuf, pkt_len);
+
+	qdf_nbuf_set_next(nbuf, NULL);
+
+	/*
+	 * Advance the packet start pointer by total size of
+	 * pre-header TLV's
+	 */
+	qdf_nbuf_pull_head(nbuf, (l2_hdr_offset + RX_PKT_TLVS_LEN));
+
+	if (qdf_unlikely(vdev->rx_decap_type == htt_cmn_pkt_type_raw)) {
+		dp_rx_deliver_raw(vdev, nbuf, peer);
+	} else {
+		DP_STATS_INC(vdev->pdev, rx.to_stack.num, 1);
+		vdev->osif_rx(vdev->osif_vdev, nbuf);
+	}
+fail:
+	dp_rx_add_to_free_desc_list(head, tail, rx_desc);
+
+	return rx_bufs_used;
+}
+
 /**
  * dp_rx_link_desc_return() - Return a MPDU link descriptor to HW
  *			      (WBM), following error handling
@@ -432,7 +538,7 @@ fail:
  *
  * Return: QDF_STATUS
  */
-static QDF_STATUS
+	static QDF_STATUS
 dp_rx_link_desc_return(struct dp_soc *soc, void *ring_desc)
 {
 	void *buf_addr_info = HAL_RX_REO_BUF_ADDR_INFO_GET(ring_desc);
@@ -646,6 +752,7 @@ dp_rx_wbm_err_process(struct dp_soc *soc, void *hal_ring, uint32_t quota)
 	struct dp_pdev *dp_pdev;
 	struct dp_srng *dp_rxdma_srng;
 	struct rx_desc_pool *rx_desc_pool;
+	uint8_t	 pool_id;
 
 	/* Debug -- Remove later */
 	qdf_assert(soc && hal_ring);
@@ -702,6 +809,8 @@ dp_rx_wbm_err_process(struct dp_soc *soc, void *hal_ring, uint32_t quota)
 			continue;
 		}
 
+		pool_id = rx_desc->pool_id;
+
 		/* XXX */
 		buf_type = HAL_RX_WBM_BUF_TYPE_GET(ring_desc);
 
@@ -716,7 +825,6 @@ dp_rx_wbm_err_process(struct dp_soc *soc, void *hal_ring, uint32_t quota)
 				HAL_RX_WBM_REO_PUSH_REASON_GET(ring_desc);
 
 			if (push_reason == HAL_RX_WBM_REO_PSH_RSN_ERROR) {
-
 				uint8_t reo_error_code =
 				   HAL_RX_WBM_REO_ERROR_CODE_GET(ring_desc);
 
@@ -734,11 +842,11 @@ dp_rx_wbm_err_process(struct dp_soc *soc, void *hal_ring, uint32_t quota)
 						"Got pkt with REO ERROR: %d",
 						reo_error_code);
 
-					rx_bufs_used[rx_desc->pool_id] +=
+					rx_bufs_used[pool_id] +=
 						dp_rx_null_q_desc_handle(soc,
 						rx_desc,
-						&head[rx_desc->pool_id],
-						&tail[rx_desc->pool_id], quota);
+						&head[pool_id],
+						&tail[pool_id], quota);
 					continue;
 				/* TODO */
 				/* Add per error code accounting */
@@ -763,15 +871,20 @@ dp_rx_wbm_err_process(struct dp_soc *soc, void *hal_ring, uint32_t quota)
 						rxdma_error_code], 1);
 
 				switch (rxdma_error_code) {
-
-				/* TODO */
-				/* Add per error code accounting */
+				case HAL_RXDMA_ERR_UNENCRYPTED:
+					rx_bufs_used[pool_id] +=
+						dp_rx_err_deliver(soc,
+								rx_desc,
+								&head[pool_id],
+								&tail[pool_id],
+								quota);
+					continue;
 
 				default:
 					QDF_TRACE(QDF_MODULE_ID_DP,
-						QDF_TRACE_LEVEL_ERROR,
-						"RXDMA error %d detected",
-						rxdma_error_code);
+							QDF_TRACE_LEVEL_ERROR,
+							"RXDMA error %d",
+							rxdma_error_code);
 				}
 			}
 		} else {

+ 1 - 1
dp/wifi3.0/hal_rx.h

@@ -1827,7 +1827,7 @@ enum hal_rxdma_error_code {
 	HAL_RXDMA_ERR_FCS,
 	HAL_RXDMA_ERR_DECRYPT,
 	HAL_RXDMA_ERR_TKIP_MIC,
-	HAL_RXDMA_ERR_UNECRYPTED,
+	HAL_RXDMA_ERR_UNENCRYPTED,
 	HAL_RXDMA_ERR_MSDU_LEN,
 	HAL_RXDMA_ERR_MSDU_LIMIT,
 	HAL_RXDMA_ERR_WIFI_PARSE,