소스 검색

qcacmn: Handling of IGMP packets in MLO Multipass

Due to the CCE rule in QCN9224 IGMP packets will be routed
to err ring. When multipass is enabled, perform multipass processing
before handing over the packet to stack.

Change-Id: I50b747710eb3c49eab60c81bbc61e75e2f8650ed
CRs-Fixed: 3275888
Sai Rupesh Chevuru 2 년 전
부모
커밋
ef34b5b9ab
3개의 변경된 파일102개의 추가작업 그리고 13개의 파일을 삭제
  1. 8 0
      dp/wifi3.0/be/dp_be_rx.c
  2. 3 0
      qdf/inc/qdf_nbuf.h
  3. 91 13
      qdf/linux/src/qdf_nbuf.c

+ 8 - 0
dp/wifi3.0/be/dp_be_rx.c

@@ -1218,6 +1218,14 @@ bool dp_rx_mlo_igmp_handler(struct dp_soc *soc,
 	      qdf_nbuf_is_ipv6_igmp_pkt(nbuf)))
 		return false;
 
+	if (qdf_unlikely(vdev->multipass_en)) {
+		if (dp_rx_multipass_process(peer, nbuf, tid) == false) {
+			DP_PEER_PER_PKT_STATS_INC(peer,
+						  rx.multipass_rx_pkt_drop, 1);
+			return false;
+		}
+	}
+
 	if (!peer->bss_peer) {
 		if (dp_rx_intrabss_mcbc_fwd(soc, peer, NULL, nbuf, tid_stats))
 			dp_rx_err("forwarding failed");

+ 3 - 0
qdf/inc/qdf_nbuf.h

@@ -66,14 +66,17 @@
 #define QDF_NBUF_SRC_MAC_OFFSET			6
 #define QDF_NBUF_TRAC_IPV4_TOS_OFFSET		15
 #define QDF_NBUF_TRAC_IPV4_PROTO_TYPE_OFFSET  23
+#define QDF_NBUF_TRAC_VLAN_IPV4_PROTO_TYPE_OFFSET  27
 #define QDF_NBUF_TRAC_IPV4_DEST_ADDR_OFFSET   30
 #define QDF_NBUF_TRAC_IPV4_SRC_ADDR_OFFSET    26
 #define QDF_NBUF_TRAC_IPV6_PROTO_TYPE_OFFSET  20
+#define QDF_NBUF_TRAC_VLAN_IPV6_PROTO_TYPE_OFFSET  24
 #define QDF_NBUF_TRAC_IPV4_ADDR_MCAST_MASK    0xE0000000
 #define QDF_NBUF_TRAC_IPV4_ADDR_BCAST_MASK    0xF0000000
 #define QDF_NBUF_TRAC_IPV6_DEST_ADDR_OFFSET   38
 #define QDF_NBUF_TRAC_IPV6_DEST_ADDR          0xFF00
 #define QDF_NBUF_TRAC_IPV6_OFFSET		14
+#define QDF_NBUF_TRAC_VLAN_IPV6_OFFSET		18
 #define QDF_NBUF_TRAC_IPV6_HEADER_SIZE   40
 #define QDF_NBUF_TRAC_ICMP_TYPE         1
 #define QDF_NBUF_TRAC_IGMP_TYPE         2

+ 91 - 13
qdf/linux/src/qdf_nbuf.c

@@ -1873,6 +1873,56 @@ bool __qdf_nbuf_is_ipv4_wapi_pkt(struct sk_buff *skb)
 }
 qdf_export_symbol(__qdf_nbuf_is_ipv4_wapi_pkt);
 
+/**
+ * qdf_nbuf_is_ipv6_vlan_pkt() - check wheather packet is vlan IPV6
+ * @data: Pointer to network data buffer
+ *
+ * This api is for vlan header included ipv6 packet.
+ *
+ * Return: true if packet is vlan header included IPV6
+ *	   false otherwise.
+ */
+static bool qdf_nbuf_is_ipv6_vlan_pkt(uint8_t *data)
+{
+	uint16_t ether_type;
+
+	ether_type = *(uint16_t *)(data + QDF_NBUF_TRAC_ETH_TYPE_OFFSET);
+
+	if (unlikely(ether_type == QDF_SWAP_U16(QDF_ETH_TYPE_8021Q))) {
+		ether_type = *(uint16_t *)(data +
+					   QDF_NBUF_TRAC_VLAN_ETH_TYPE_OFFSET);
+
+		if (ether_type == QDF_SWAP_U16(QDF_NBUF_TRAC_IPV6_ETH_TYPE))
+			return true;
+	}
+	return false;
+}
+
+/**
+ * qdf_nbuf_is_ipv4_vlan_pkt() - check wheather packet is vlan IPV4
+ * @data: Pointer to network data buffer
+ *
+ * This api is for vlan header included ipv4 packet.
+ *
+ * Return: true if packet is vlan header included IPV4
+ *	   false otherwise.
+ */
+static bool qdf_nbuf_is_ipv4_vlan_pkt(uint8_t *data)
+{
+	uint16_t ether_type;
+
+	ether_type = *(uint16_t *)(data + QDF_NBUF_TRAC_ETH_TYPE_OFFSET);
+
+	if (unlikely(ether_type == QDF_SWAP_U16(QDF_ETH_TYPE_8021Q))) {
+		ether_type = *(uint16_t *)(data +
+					   QDF_NBUF_TRAC_VLAN_ETH_TYPE_OFFSET);
+
+		if (ether_type == QDF_SWAP_U16(QDF_NBUF_TRAC_IPV4_ETH_TYPE))
+			return true;
+	}
+	return false;
+}
+
 /**
  * __qdf_nbuf_data_is_ipv4_igmp_pkt() - check if skb data is a igmp packet
  * @data: Pointer to network data buffer
@@ -1884,15 +1934,26 @@ qdf_export_symbol(__qdf_nbuf_is_ipv4_wapi_pkt);
  */
 bool __qdf_nbuf_data_is_ipv4_igmp_pkt(uint8_t *data)
 {
-	if (__qdf_nbuf_data_is_ipv4_pkt(data)) {
-		uint8_t pkt_type;
+	uint8_t pkt_type;
 
+	if (__qdf_nbuf_data_is_ipv4_pkt(data)) {
 		pkt_type = (uint8_t)(*(uint8_t *)(data +
 				QDF_NBUF_TRAC_IPV4_PROTO_TYPE_OFFSET));
+		goto is_igmp;
+	}
 
-		if (pkt_type == QDF_NBUF_TRAC_IGMP_TYPE)
-			return true;
+	if (qdf_nbuf_is_ipv4_vlan_pkt(data)) {
+		pkt_type = (uint8_t)(*(uint8_t *)(
+				data +
+				QDF_NBUF_TRAC_VLAN_IPV4_PROTO_TYPE_OFFSET));
+		goto is_igmp;
 	}
+
+	return false;
+is_igmp:
+	if (pkt_type == QDF_NBUF_TRAC_IGMP_TYPE)
+		return true;
+
 	return false;
 }
 
@@ -1909,21 +1970,38 @@ qdf_export_symbol(__qdf_nbuf_data_is_ipv4_igmp_pkt);
  */
 bool __qdf_nbuf_data_is_ipv6_igmp_pkt(uint8_t *data)
 {
-	if (__qdf_nbuf_data_is_ipv6_pkt(data)) {
-		uint8_t pkt_type;
-		uint8_t next_hdr;
+	uint8_t pkt_type;
+	uint8_t next_hdr;
 
+	if (__qdf_nbuf_data_is_ipv6_pkt(data)) {
 		pkt_type = (uint8_t)(*(uint8_t *)(data +
 				QDF_NBUF_TRAC_IPV6_PROTO_TYPE_OFFSET));
-		next_hdr = (uint8_t)(*(uint8_t *)(data +
+		next_hdr = (uint8_t)(*(uint8_t *)(
+				data +
+				QDF_NBUF_TRAC_IPV6_OFFSET +
 				QDF_NBUF_TRAC_IPV6_HEADER_SIZE));
+		goto is_mld;
+	}
 
-		if (pkt_type == QDF_NBUF_TRAC_ICMPV6_TYPE)
-			return true;
-		if ((pkt_type == QDF_NBUF_TRAC_HOPOPTS_TYPE) &&
-		    (next_hdr == QDF_NBUF_TRAC_HOPOPTS_TYPE))
-			return true;
+	if (qdf_nbuf_is_ipv6_vlan_pkt(data)) {
+		pkt_type = (uint8_t)(*(uint8_t *)(
+				data +
+				QDF_NBUF_TRAC_VLAN_IPV6_PROTO_TYPE_OFFSET));
+		next_hdr = (uint8_t)(*(uint8_t *)(
+				data +
+				QDF_NBUF_TRAC_VLAN_IPV6_OFFSET +
+				QDF_NBUF_TRAC_IPV6_HEADER_SIZE));
+		goto is_mld;
 	}
+
+	return false;
+is_mld:
+	if (pkt_type == QDF_NBUF_TRAC_ICMPV6_TYPE)
+		return true;
+	if ((pkt_type == QDF_NBUF_TRAC_HOPOPTS_TYPE) &&
+	    (next_hdr == QDF_NBUF_TRAC_ICMPV6_TYPE))
+		return true;
+
 	return false;
 }