Kaynağa Gözat

qcacmn: Add support to handle RAW packets in RX path

API to handle pkts received on vdev which has RAW mode
enabled. Currently supports only MPDU with single MSDU.

Change-Id: Ife00699646bd97c5de0021fc32db434a544058f6
CRs-Fixed: 1111781
Kalyan Tallapragada 8 yıl önce
ebeveyn
işleme
277f45e2b1

+ 30 - 0
dp/wifi3.0/dp_main.c

@@ -1589,6 +1589,34 @@ static void dp_peer_setup_wifi3(struct cdp_vdev *vdev_hdl, void *peer_hdl)
 	return;
 }
 
+/*
+ * dp_set_vdev_tx_encap_type() - set the encap type of the vdev
+ * @vdev_handle: virtual device object
+ * @htt_pkt_type: type of pkt
+ *
+ * Return: void
+ */
+static void dp_set_vdev_tx_encap_type(struct cdp_vdev *vdev_handle,
+	 enum htt_cmn_pkt_type val)
+{
+	struct dp_vdev *vdev = (struct dp_vdev *)vdev_handle;
+	vdev->tx_encap_type = val;
+}
+
+/*
+ * dp_set_vdev_rx_decap_type() - set the decap type of the vdev
+ * @vdev_handle: virtual device object
+ * @htt_pkt_type: type of pkt
+ *
+ * Return: void
+ */
+static void dp_set_vdev_rx_decap_type(struct cdp_vdev *vdev_handle,
+	 enum htt_cmn_pkt_type val)
+{
+	struct dp_vdev *vdev = (struct dp_vdev *)vdev_handle;
+	vdev->rx_decap_type = val;
+}
+
 /*
  * dp_peer_authorize() - authorize txrx peer
  * @peer_handle:		Datapath peer handle
@@ -1824,6 +1852,8 @@ static struct cdp_cmn_ops dp_ops_cmn = {
 
 static struct cdp_ctrl_ops dp_ops_ctrl = {
 	.txrx_peer_authorize = dp_peer_authorize,
+	.txrx_set_vdev_rx_decap_type = dp_set_vdev_rx_decap_type,
+	.txrx_set_tx_encap_type = dp_set_vdev_tx_encap_type,
 	/* TODO: Add other functions */
 };
 

+ 65 - 1
dp/wifi3.0/dp_rx.c

@@ -159,6 +159,51 @@ QDF_STATUS dp_rx_buffers_replenish(struct dp_soc *dp_soc, uint32_t mac_id,
 	return QDF_STATUS_SUCCESS;
 }
 
+/*
+ * dp_rx_deliver_raw() - process RAW mode pkts and hand over the
+ *				pkts to RAW mode simulation to
+ *				decapsulate the pkt.
+ *
+ * @vdev: vdev on which RAW mode is enabled
+ * @nbuf_list: list of RAW pkts to process
+ *
+ * Return: void
+ */
+static void
+dp_rx_deliver_raw(struct dp_vdev *vdev, qdf_nbuf_t nbuf_list)
+{
+	qdf_nbuf_t deliver_list_head = NULL;
+	qdf_nbuf_t deliver_list_tail = NULL;
+	qdf_nbuf_t nbuf;
+
+	nbuf = nbuf_list;
+	while (nbuf) {
+		qdf_nbuf_t next = qdf_nbuf_next(nbuf);
+
+		DP_RX_LIST_APPEND(deliver_list_head, deliver_list_tail, nbuf);
+
+		/*
+		 * reset the chfrag_start and chfrag_end bits in nbuf cb
+		 * as this is a non-amsdu pkt and RAW mode simulation expects
+		 * these bit s to be 0 for non-amsdu pkt.
+		 */
+		if (qdf_nbuf_is_chfrag_start(nbuf) &&
+			 qdf_nbuf_is_chfrag_end(nbuf)) {
+			qdf_nbuf_set_chfrag_start(nbuf, 0);
+			qdf_nbuf_set_chfrag_end(nbuf, 0);
+		}
+
+		nbuf = next;
+	}
+
+	vdev->osif_rsim_rx_decap(vdev->osif_vdev, &deliver_list_head,
+				 &deliver_list_tail);
+
+	vdev->osif_rx(vdev->osif_vdev, deliver_list_head);
+}
+
+
+
 /**
  * dp_rx_intrabss_fwd() - Implements the Intra-BSS forwarding logic
  *
@@ -208,6 +253,7 @@ dp_rx_process(struct dp_soc *soc, void *hal_ring, uint32_t quota)
 	struct dp_peer *peer = NULL;
 	struct dp_vdev *vdev = NULL;
 	struct hal_rx_mpdu_desc_info mpdu_desc_info;
+	struct hal_rx_msdu_desc_info msdu_desc_info;
 	enum hal_reo_error_status error;
 	uint32_t pkt_len;
 	static uint32_t peer_mdata;
@@ -292,6 +338,22 @@ dp_rx_process(struct dp_soc *soc, void *hal_ring, uint32_t quota)
 			goto fail;
 		}
 
+		/* Get MSDU DESC info */
+		hal_rx_msdu_desc_info_get(ring_desc, &msdu_desc_info);
+
+		/*
+		 * save msdu flags first, last and continuation msdu in
+		 * nbuf->cb
+		 */
+		if (msdu_desc_info.msdu_flags & HAL_MSDU_F_FIRST_MSDU_IN_MPDU)
+			qdf_nbuf_set_chfrag_start(rx_desc->nbuf, 1);
+
+		if (msdu_desc_info.msdu_flags & HAL_MSDU_F_MSDU_CONTINUATION)
+			qdf_nbuf_set_chfrag_cont(rx_desc->nbuf, 1);
+
+		if (msdu_desc_info.msdu_flags & HAL_MSDU_F_LAST_MSDU_IN_MPDU)
+			qdf_nbuf_set_chfrag_end(rx_desc->nbuf, 1);
+
 		qdf_nbuf_queue_add(&vdev->rxq, rx_desc->nbuf);
 fail:
 		dp_rx_add_to_free_desc_list(&head, &tail, rx_desc);
@@ -425,7 +487,9 @@ done:
 						nbuf);
 		}
 
-		if (qdf_likely(vdev->osif_rx) && deliver_list_head)
+		if (qdf_unlikely(vdev->rx_decap_type == htt_pkt_type_raw))
+			dp_rx_deliver_raw(vdev, deliver_list_head);
+		else if (qdf_likely(vdev->osif_rx) && deliver_list_head)
 			vdev->osif_rx(vdev->osif_vdev, deliver_list_head);
 
 	}

+ 48 - 4
qdf/inc/qdf_nbuf.h

@@ -555,8 +555,12 @@ qdf_nbuf_frag_push_head(qdf_nbuf_t buf,
 
 #define qdf_nbuf_num_frags_init(_nbuf) __qdf_nbuf_num_frags_init((_nbuf))
 
-/* For efficiency, it is the responsibility of the caller to ensure that val
- * is either 0 or 1.
+/**
+ * qdf_nbuf_set_chfrag_start() - set msdu start bit
+ * @buf: Network buffer
+ * @val: 0/1
+ *
+ * Return: void
  */
 static inline void
 qdf_nbuf_set_chfrag_start(qdf_nbuf_t buf, uint8_t val)
@@ -564,19 +568,59 @@ qdf_nbuf_set_chfrag_start(qdf_nbuf_t buf, uint8_t val)
 	__qdf_nbuf_set_chfrag_start(buf, val);
 }
 
+/**
+ * qdf_nbuf_is_chfrag_start() - get msdu start bit
+ * @buf: Network buffer
+ *
+ * Return: integer value - 0/1
+ */
 static inline int qdf_nbuf_is_chfrag_start(qdf_nbuf_t buf)
 {
 	return __qdf_nbuf_is_chfrag_start(buf);
 }
 
-/* For efficiency, it is the responsibility of the caller to ensure that val
- * is either 0 or 1.
+/**
+ * qdf_nbuf_set_chfrag_cont() - set msdu continuation bit
+ * @buf: Network buffer
+ * @val: 0/1
+ *
+ * Return: void
+ */
+static inline void
+qdf_nbuf_set_chfrag_cont(qdf_nbuf_t buf, uint8_t val)
+{
+	__qdf_nbuf_set_chfrag_cont(buf, val);
+}
+
+/**
+ * qdf_nbuf_is_chfrag_cont() - get msdu continuation bit
+ * @buf: Network buffer
+ *
+ * Return: integer value - 0/1
+ */
+static inline int qdf_nbuf_is_chfrag_cont(qdf_nbuf_t buf)
+{
+	return __qdf_nbuf_is_chfrag_cont(buf);
+}
+
+/**
+ * qdf_nbuf_set_chfrag_end() - set msdu end bit
+ * @buf: Network buffer
+ * @val: 0/1
+ *
+ * Return: void
  */
 static inline void qdf_nbuf_set_chfrag_end(qdf_nbuf_t buf, uint8_t val)
 {
 	__qdf_nbuf_set_chfrag_end(buf, val);
 }
 
+/**
+ * qdf_nbuf_is_chfrag_end() - set msdu end bit
+ * @buf: Network buffer
+ *
+ * Return: integer value - 0/1
+ */
 static inline int qdf_nbuf_is_chfrag_end(qdf_nbuf_t buf)
 {
 	return __qdf_nbuf_is_chfrag_end(buf);

+ 13 - 1
qdf/linux/src/i_qdf_nbuf.h

@@ -165,9 +165,10 @@ struct qdf_nbuf_cb {
 							flag_nbuf:1,
 							num:1,
 							flag_chfrag_start:1,
+							flag_chfrag_cont:1,
 							flag_chfrag_end:1,
 							flag_ext_header:1,
-							reserved:2;
+							reserved:1;
 					} bits;
 					uint8_t u8;
 				} flags;
@@ -257,6 +258,9 @@ struct qdf_nbuf_cb {
 #define QDF_NBUF_CB_TX_EXTRA_FRAG_FLAGS_CHFRAG_START(skb) \
 	(((struct qdf_nbuf_cb *) \
 	((skb)->cb))->u.tx.extra_frag.flags.bits.flag_chfrag_start)
+#define QDF_NBUF_CB_TX_EXTRA_FRAG_FLAGS_CHFRAG_CONT(skb) \
+	(((struct qdf_nbuf_cb *) \
+	((skb)->cb))->u.tx.extra_frag.flags.bits.flag_chfrag_cont)
 #define QDF_NBUF_CB_TX_EXTRA_FRAG_FLAGS_CHFRAG_END(skb) \
 		(((struct qdf_nbuf_cb *) \
 		((skb)->cb))->u.tx.extra_frag.flags.bits.flag_chfrag_end)
@@ -407,6 +411,14 @@ typedef void (*qdf_nbuf_trace_update_t)(char *);
 #define __qdf_nbuf_is_chfrag_start(skb) \
 	(QDF_NBUF_CB_TX_EXTRA_FRAG_FLAGS_CHFRAG_START((skb)))
 
+#define __qdf_nbuf_set_chfrag_cont(skb, val) \
+	do { \
+		(QDF_NBUF_CB_TX_EXTRA_FRAG_FLAGS_CHFRAG_CONT((skb))) = val; \
+	} while (0)
+
+#define __qdf_nbuf_is_chfrag_cont(skb) \
+	(QDF_NBUF_CB_TX_EXTRA_FRAG_FLAGS_CHFRAG_CONT((skb)))
+
 #define __qdf_nbuf_set_chfrag_end(skb, val) \
 	do { \
 		(QDF_NBUF_CB_TX_EXTRA_FRAG_FLAGS_CHFRAG_END((skb))) = val; \

+ 2 - 0
wmi/src/wmi_unified_tlv.c

@@ -14707,6 +14707,8 @@ static void populate_vdev_param_tlv(uint32_t *vdev_param)
 				WMI_VDEV_PARAM_MCC_BROADCAST_PROBE_ENABLE;
 	vdev_param[wmi_vdev_param_mgmt_tx_power] = WMI_VDEV_PARAM_MGMT_TX_POWER;
 	vdev_param[wmi_vdev_param_beacon_rate] = WMI_VDEV_PARAM_BEACON_RATE;
+	vdev_param[wmi_vdev_param_rx_decap_type] = WMI_VDEV_PARAM_RX_DECAP_TYPE;
+	vdev_param[wmi_vdev_param_tx_encap_type] = WMI_VDEV_PARAM_TX_ENCAP_TYPE;
 }
 #endif