Przeglądaj źródła

qcacmn: Log DHCP, EAPOL packets to logging queue

Log DHCP and EAPOL packets to wlan connectivity logging
queue.

Change-Id: Ib0c84c389c0f5fd7e742722c0e03c84b9732de19
CRs-Fixed: 3030936
Ananya Gupta 3 lat temu
rodzic
commit
29d256f801
2 zmienionych plików z 175 dodań i 7 usunięć
  1. 17 2
      qdf/inc/qdf_nbuf.h
  2. 158 5
      qdf/linux/src/qdf_trace.c

+ 17 - 2
qdf/inc/qdf_nbuf.h

@@ -95,13 +95,28 @@
 /* EAPOL Related MASK */
 #define EAPOL_PACKET_TYPE_OFFSET		15
 #define EAPOL_KEY_INFO_OFFSET			19
-#define EAPOL_PKT_LEN_OFFSET            16
-#define EAPOL_KEY_LEN_OFFSET            21
+#define EAPOL_PKT_LEN_OFFSET			16
+#define EAPOL_KEY_LEN_OFFSET			21
+#define EAPOL_PACKET_TYPE_KEY			3
 #define EAPOL_MASK				0x8013
 #define EAPOL_M1_BIT_MASK			0x8000
 #define EAPOL_M2_BIT_MASK			0x0001
 #define EAPOL_M3_BIT_MASK			0x8013
 #define EAPOL_M4_BIT_MASK			0x0003
+#define EAPOL_KEY_TYPE_MASK			0x0800
+#define EAPOL_KEY_ENCRYPTED_MASK		0x0010
+
+/* EAP Related Mask */
+
+#define EAP_CODE_OFFSET				18
+#define EAP_LENGTH_OFFSET			20
+#define EAP_TYPE_OFFSET				22
+#define QDF_EAP_REQUEST				1
+#define QDF_EAP_RESPONE				2
+#define QDF_EAP_SUCCESS				3
+#define QDF_EAP_FAILURE				4
+#define QDF_EAP_INITIATE			5
+#define QDF_EAP_FINISH				6
 
 /* ARP Related MASK */
 #define QDF_NBUF_PKT_ARP_OPCODE_OFFSET	20

+ 158 - 5
qdf/linux/src/qdf_trace.c

@@ -47,6 +47,10 @@ qdf_declare_param(qdf_log_flush_timer_period, uint);
 #include "qdf_mc_timer.h"
 #include <host_diag_core_log.h>
 
+#ifdef WLAN_FEATURE_CONNECTIVITY_LOGGING
+#include <wlan_connectivity_logging.h>
+#endif
+
 /* Global qdf print id */
 
 /* Preprocessor definitions and constants */
@@ -1720,6 +1724,143 @@ static bool qdf_log_icmp_pkt(uint8_t vdev_id, struct sk_buff *skb,
 	return false;
 }
 
+#ifdef WLAN_FEATURE_CONNECTIVITY_LOGGING
+/**
+ * qdf_subtype_to_wlan_main_tag() - Convert qdf subtype to wlan main tag
+ * @subtype: EAPoL key subtype
+ *
+ * Return: Wlan main tag subtype
+ */
+static int qdf_subtype_to_wlan_main_tag(enum qdf_proto_subtype subtype)
+{
+	switch (subtype) {
+	case QDF_PROTO_DHCP_DISCOVER:
+		return WLAN_DHCP_DISCOVER;
+	case QDF_PROTO_DHCP_REQUEST:
+		return WLAN_DHCP_REQUEST;
+	case QDF_PROTO_DHCP_OFFER:
+		return WLAN_DHCP_OFFER;
+	case QDF_PROTO_DHCP_ACK:
+		return WLAN_DHCP_ACK;
+	case QDF_PROTO_DHCP_NACK:
+		return WLAN_DHCP_NACK;
+	case QDF_PROTO_EAPOL_M1:
+		return WLAN_EAPOL_M1;
+	case QDF_PROTO_EAPOL_M2:
+		return WLAN_EAPOL_M2;
+	case QDF_PROTO_EAPOL_M3:
+		return WLAN_EAPOL_M3;
+	case QDF_PROTO_EAPOL_M4:
+		return WLAN_EAPOL_M4;
+	default:
+		return WLAN_TAG_MAX;
+	}
+}
+
+/**
+ * qdf_get_wlan_eap_code() - Get EAP code
+ * @data: skb data pointer
+ *
+ * Return: EAP code value
+ */
+static int qdf_get_wlan_eap_code(uint8_t *data)
+{
+	uint8_t code = *(data + EAP_CODE_OFFSET);
+
+	switch (code) {
+	case QDF_EAP_REQUEST:
+		return WLAN_EAP_REQUEST;
+	case QDF_EAP_RESPONE:
+		return WLAN_EAP_RESPONSE;
+	case QDF_EAP_SUCCESS:
+		return WLAN_EAP_SUCCESS;
+	case QDF_EAP_FAILURE:
+		return WLAN_EAP_FAILURE;
+	default:
+		return WLAN_TAG_MAX;
+	}
+}
+
+/**
+ * qdf_eapol_get_key_type() - Get EAPOL key type
+ * @data: skb data pointer
+ * @subtype: EAPoL key subtype
+ *
+ * Return: EAPOL key type
+ */
+static
+uint8_t qdf_eapol_get_key_type(uint8_t *data, enum qdf_proto_subtype subtype)
+{
+	uint16_t key_info = *(uint16_t *)(data + EAPOL_KEY_INFO_OFFSET);
+
+	/* If key type is PTK, key type will be set in EAPOL Key info */
+	if (key_info & EAPOL_KEY_TYPE_MASK)
+		return qdf_subtype_to_wlan_main_tag(subtype);
+	else if (key_info & EAPOL_KEY_ENCRYPTED_MASK)
+		return WLAN_GTK_M1;
+	else
+		return WLAN_GTK_M2;
+}
+
+/**
+ * qdf_fill_wlan_connectivity_log() - Fill and queue protocol packet to logging
+ * the logging queue
+ * @type: Protocol type
+ * @subtype: Protocol subtype
+ * @dir: Rx or Tx
+ * @qdf_tx_status: Tx completion status
+ * @vdev_id: DP vdev ID
+ * @data: skb data pointer
+ *
+ * Return: None
+ */
+static
+void qdf_fill_wlan_connectivity_log(enum qdf_proto_type type,
+				    enum qdf_proto_subtype subtype,
+				    enum qdf_proto_dir dir,
+				    enum qdf_dp_tx_rx_status qdf_tx_status,
+				    uint8_t vdev_id, uint8_t *data)
+{
+	struct wlan_log_record log_buf;
+	uint8_t pkt_type;
+
+	log_buf.timestamp_us = qdf_get_time_of_the_day_ms() * 1000;
+	log_buf.vdev_id = vdev_id;
+	if (type == QDF_PROTO_TYPE_DHCP) {
+		log_buf.log_subtype = qdf_subtype_to_wlan_main_tag(subtype);
+	} else if (type == QDF_PROTO_TYPE_EAPOL) {
+		pkt_type = *(data + EAPOL_PACKET_TYPE_OFFSET);
+		if (pkt_type == 0) {
+			log_buf.log_subtype = qdf_get_wlan_eap_code(data);
+			log_buf.pkt_info.eap_type = *(data + EAP_TYPE_OFFSET);
+			log_buf.pkt_info.eap_len =
+			   qdf_ntohs(*(uint16_t *)(data + EAP_LENGTH_OFFSET));
+		} else if (pkt_type == EAPOL_PACKET_TYPE_KEY) {
+			log_buf.log_subtype = qdf_eapol_get_key_type(data,
+								     subtype);
+		}
+	} else {
+		return;
+	}
+
+	/*Tx completion status needs to be logged*/
+	if (dir == QDF_TX)
+		log_buf.pkt_info.tx_status = qdf_tx_status;
+
+	wlan_connectivity_log_enqueue(&log_buf);
+}
+
+#else
+static inline
+void qdf_fill_wlan_connectivity_log(enum qdf_proto_type type,
+				    enum qdf_proto_subtype subtype,
+				    enum qdf_proto_dir dir,
+				    enum qdf_dp_tx_rx_status qdf_tx_status,
+				    uint8_t vdev_id, uint8_t *data)
+{
+}
+#endif
+
 /**
  * qdf_log_eapol_pkt() - log EAPOL packet
  * @vdev_id: ID of the vdev
@@ -1750,12 +1891,15 @@ static bool qdf_log_eapol_pkt(uint8_t vdev_id, struct sk_buff *skb,
 
 	subtype = qdf_nbuf_get_eapol_subtype(skb);
 
-	if (dp_eap_event && dir == QDF_RX)
+	if (dp_eap_event && dir == QDF_RX) {
 		qdf_dp_log_proto_pkt_info(skb->data + QDF_NBUF_SRC_MAC_OFFSET,
 					  skb->data + QDF_NBUF_DEST_MAC_OFFSET,
 					  QDF_PROTO_TYPE_EAPOL, subtype, dir,
 					  QDF_TRACE_DEFAULT_MSDU_ID,
 					  QDF_TX_RX_STATUS_INVALID);
+		qdf_fill_wlan_connectivity_log(QDF_PROTO_TYPE_EAPOL, subtype,
+					       QDF_RX, 0, vdev_id, skb->data);
+	}
 
 	if (dp_eap_trace) {
 		QDF_NBUF_CB_DP_TRACE_PRINT(skb) = true;
@@ -1825,12 +1969,15 @@ static bool qdf_log_dhcp_pkt(uint8_t vdev_id, struct sk_buff *skb,
 
 	subtype = qdf_nbuf_get_dhcp_subtype(skb);
 
-	if (dp_dhcp_event && dir == QDF_RX)
+	if (dp_dhcp_event && dir == QDF_RX) {
 		qdf_dp_log_proto_pkt_info(skb->data + QDF_NBUF_SRC_MAC_OFFSET,
 					  skb->data + QDF_NBUF_DEST_MAC_OFFSET,
 					  QDF_PROTO_TYPE_DHCP, subtype, dir,
 					  QDF_TRACE_DEFAULT_MSDU_ID,
 					  QDF_TX_RX_STATUS_INVALID);
+		qdf_fill_wlan_connectivity_log(QDF_PROTO_TYPE_DHCP, subtype,
+					       QDF_RX, 0, vdev_id, 0);
+	}
 
 	if (dp_dhcp_trace) {
 		QDF_NBUF_CB_DP_TRACE_PRINT(skb) = true;
@@ -2331,16 +2478,22 @@ void qdf_dp_trace_ptr(qdf_nbuf_t nbuf, enum QDF_DP_TRACE_ID code,
 	struct qdf_dp_trace_ptr_buf buf;
 	int buf_size = sizeof(struct qdf_dp_trace_ptr_buf);
 	enum qdf_proto_type pkt_type;
+	enum qdf_proto_subtype subtype;
 
 	pkt_type = qdf_dp_get_pkt_proto_type(nbuf);
 	if ((code == QDF_DP_TRACE_FREE_PACKET_PTR_RECORD ||
 	     code == QDF_DP_TRACE_LI_DP_FREE_PACKET_PTR_RECORD) &&
-	    qdf_dp_proto_log_enable_check(pkt_type, qdf_tx_status))
+	    qdf_dp_proto_log_enable_check(pkt_type, qdf_tx_status)) {
+		subtype = qdf_dp_get_pkt_subtype(nbuf, pkt_type);
 		qdf_dp_log_proto_pkt_info(nbuf->data + QDF_NBUF_SRC_MAC_OFFSET,
 					 nbuf->data + QDF_NBUF_DEST_MAC_OFFSET,
-					 pkt_type,
-					 qdf_dp_get_pkt_subtype(nbuf, pkt_type),
+					 pkt_type, subtype,
 					 QDF_TX, msdu_id, qdf_tx_status);
+		qdf_fill_wlan_connectivity_log(pkt_type, subtype,
+					       QDF_TX, qdf_tx_status,
+					       QDF_NBUF_CB_TX_VDEV_CTX(nbuf),
+					       nbuf->data);
+	}
 
 	if (qdf_dp_enable_check(nbuf, code, QDF_TX) == false)
 		return;