소스 검색

qcacmn: Fix the use of the incorrect rx pkt tlv length

Currently the monitor mode processing assumes the
rx pkt tlv to be consisting of RX_PACKET_HEADER tlv.
This assumption is incorrect in case of sta+monitor
mode, where the RX_PACKET_HDR tlv has not been subscribed.

Due to the above incorrect assumption, a certain portion
of the actual payload is being discarded, when the
rx_pkt_hdr tlvs are stripped off from the received buffer.

To mitigate this issue, use the rx_pkt_tlv length based
on the tlvs which are enabled, and configured to the
rxdma for reception.

Change-Id: I8f29db85bbd50316e3c2073ae9a2e79fd724be05
CRs-Fixed: 3318038
Rakesh Pillai 2 년 전
부모
커밋
6271fe1a98
4개의 변경된 파일22개의 추가작업 그리고 4개의 파일을 삭제
  1. 5 1
      dp/wifi3.0/dp_main.c
  2. 2 0
      dp/wifi3.0/dp_types.h
  3. 13 1
      dp/wifi3.0/monitor/1.0/dp_rx_mon_1.0.h
  4. 2 2
      dp/wifi3.0/monitor/1.0/dp_rx_mon_dest_1.0.c

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

@@ -15362,8 +15362,12 @@ void *dp_soc_init(struct dp_soc *soc, HTC_HANDLE htc_handle,
 	dp_soc_set_interrupt_mode(soc);
 	if (soc->cdp_soc.ol_ops->get_con_mode &&
 	    soc->cdp_soc.ol_ops->get_con_mode() ==
-	    QDF_GLOBAL_MONITOR_MODE)
+	    QDF_GLOBAL_MONITOR_MODE) {
 		is_monitor_mode = true;
+		soc->curr_rx_pkt_tlv_size = soc->rx_mon_pkt_tlv_size;
+	} else {
+		soc->curr_rx_pkt_tlv_size = soc->rx_pkt_tlv_size;
+	}
 
 	num_dp_msi = dp_get_num_msi_available(soc, soc->intr_mode);
 	if (num_dp_msi < 0) {

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

@@ -2132,6 +2132,8 @@ struct dp_soc {
 	uint16_t rx_mon_pkt_tlv_size;
 	/* rx pkt tlv size */
 	uint16_t rx_pkt_tlv_size;
+	/* rx pkt tlv size in current operation mode */
+	uint16_t curr_rx_pkt_tlv_size;
 
 	struct dp_arch_ops arch_ops;
 

+ 13 - 1
dp/wifi3.0/monitor/1.0/dp_rx_mon_1.0.h

@@ -163,6 +163,18 @@ dp_rx_mon_link_desc_return(struct dp_pdev *dp_pdev,
 }
 #endif
 
+#if defined(WLAN_MAX_PDEVS) && (WLAN_MAX_PDEVS == 1)
+static inline uint16_t dp_rx_mon_get_rx_pkt_tlv_size(struct dp_soc *soc)
+{
+	return soc->curr_rx_pkt_tlv_size;
+}
+#else
+static inline uint16_t dp_rx_mon_get_rx_pkt_tlv_size(struct dp_soc *soc)
+{
+	return soc->rx_mon_pkt_tlv_size;
+}
+#endif
+
 /**
  * dp_mon_adjust_frag_len() - MPDU and MSDU may spread across
  *				multiple nbufs. This function
@@ -712,7 +724,7 @@ dp_rx_mon_parse_desc_buffer(struct dp_soc *dp_soc,
 			    bool *is_frag_non_raw_p, void *data)
 {
 	struct hal_rx_mon_dest_buf_info frame_info;
-	uint32_t rx_pkt_tlv_len = dp_soc->rx_mon_pkt_tlv_size;
+	uint32_t rx_pkt_tlv_len = dp_rx_mon_get_rx_pkt_tlv_size(dp_soc);
 
 	/*
 	 * HW structures call this L3 header padding

+ 2 - 2
dp/wifi3.0/monitor/1.0/dp_rx_mon_dest_1.0.c

@@ -389,7 +389,7 @@ dp_rx_mon_mpdu_pop(struct dp_soc *soc, uint32_t mac_id,
 					     total_frag_len, frag_len,
 				      msdu_list.msdu_info[i].msdu_flags);
 
-			rx_pkt_offset = soc->rx_mon_pkt_tlv_size;
+			rx_pkt_offset = dp_rx_mon_get_rx_pkt_tlv_size(soc);
 
 			rx_buf_size = rx_pkt_offset + l2_hdr_offset
 					+ frag_len;
@@ -1436,7 +1436,7 @@ void dp_rx_msdus_set_payload(struct dp_soc *soc, qdf_nbuf_t msdu,
 	uint32_t rx_pkt_offset;
 
 	data = qdf_nbuf_data(msdu);
-	rx_pkt_offset = soc->rx_mon_pkt_tlv_size;
+	rx_pkt_offset = dp_rx_mon_get_rx_pkt_tlv_size(soc);
 	qdf_nbuf_pull_head(msdu, rx_pkt_offset + l2_hdr_offset);
 }