Преглед на файлове

qcacmn: Add pktlog handler to process rate events

Add dp_msg_pktlog_handler to handle
rate events from the firmware.

Change-Id: I24776caa3b78ec38d94421f243ec72d81ee3102d
CRs-Fixed: 2340639
Venkata Sharath Chandra Manchala преди 6 години
родител
ревизия
0ce469e330
променени са 4 файла, в които са добавени 187 реда и са изтрити 27 реда
  1. 3 4
      dp/wifi3.0/dp_htt.c
  2. 2 3
      utils/pktlog/include/pktlog_ac_i.h
  3. 110 15
      utils/pktlog/pktlog_ac.c
  4. 72 5
      utils/pktlog/pktlog_internal.c

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

@@ -2874,7 +2874,7 @@ dp_ppdu_stats_ind_handler(struct htt_soc *soc,
 #endif
 
 #if defined(WDI_EVENT_ENABLE) && \
-		!defined(REMOVE_PKT_LOG) && defined(CONFIG_WIN)
+	!defined(REMOVE_PKT_LOG)
 /*
  * dp_pktlog_msg_handler() - Pktlog msg handler
  * @htt_soc:	 HTT SOC handle
@@ -2884,7 +2884,7 @@ dp_ppdu_stats_ind_handler(struct htt_soc *soc,
  */
 static void
 dp_pktlog_msg_handler(struct htt_soc *soc,
-				uint32_t *msg_word)
+		      uint32_t *msg_word)
 {
 	uint8_t pdev_id;
 	uint32_t *pl_hdr;
@@ -2900,11 +2900,10 @@ dp_pktlog_msg_handler(struct htt_soc *soc,
 #else
 static void
 dp_pktlog_msg_handler(struct htt_soc *soc,
-				uint32_t *msg_word)
+		      uint32_t *msg_word)
 {
 }
 #endif
-
 /*
  * dp_htt_t2h_msg_handler() - Generic Target to host Msg/event handler
  * @context:	Opaque context (HTT SOC handle)

+ 2 - 3
utils/pktlog/include/pktlog_ac_i.h

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012-2017 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2012-2018 The Linux Foundation. All rights reserved.
  *
  * Permission to use, copy, modify, and/or distribute this software for
  * any purpose with or without fee is hereby granted, provided that the
@@ -45,9 +45,7 @@ struct ath_pktlog_arg {
 #endif
 	size_t log_size;
 	uint16_t timestamp;
-#ifdef HELIUMPLUS
 	uint32_t type_specific_data;
-#endif
 	char *buf;
 };
 
@@ -64,5 +62,6 @@ A_STATUS process_rate_update(void *pdev, void *data);
 A_STATUS process_sw_event(void *pdev, void *data);
 int process_pktlog_lite(void *context, void *log_data, uint16_t log_type);
 int process_rx_desc_remote(void *pdev, void *data);
+A_STATUS process_offload_pktlog(struct cdp_pdev *pdev, void *data);
 #endif /* REMOVE_PKT_LOG */
 #endif

+ 110 - 15
utils/pktlog/pktlog_ac.c

@@ -50,6 +50,7 @@ wdi_event_subscribe PKTLOG_RCUPDATE_SUBSCRIBER;
 wdi_event_subscribe PKTLOG_SW_EVENT_SUBSCRIBER;
 wdi_event_subscribe PKTLOG_LITE_T2H_SUBSCRIBER;
 wdi_event_subscribe PKTLOG_LITE_RX_SUBSCRIBER;
+wdi_event_subscribe PKTLOG_OFFLOAD_SUBSCRIBER;
 
 struct ol_pl_arch_dep_funcs ol_pl_funcs = {
 	.pktlog_init = pktlog_init,
@@ -164,18 +165,25 @@ pktlog_enable_tgt(struct hif_opaque_softc *_scn, uint32_t log_state,
 	if (log_state & ATH_PKTLOG_SW_EVENT)
 		types |= WMI_PKTLOG_EVENT_SW;
 
+	QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG,
+		  "%s: Pktlog events: %d", __func__, types);
+
 	return pktlog_wma_post_msg(types, WMI_PDEV_PKTLOG_ENABLE_CMDID,
 				   ini_triggered, user_triggered);
 }
 
+#ifdef HELIUMPLUS
+/**
+ * wdi_pktlog_subscribe() - Subscribe pktlog callbacks
+ * @cdp_pdev: abstract pdev handle
+ * @log_state: Pktlog registration
+ *
+ * Return: zero on success, non-zero on failure
+ */
 static inline A_STATUS
 wdi_pktlog_subscribe(struct cdp_pdev *cdp_pdev, int32_t log_state)
 {
-#ifdef CONFIG_MCL
 	void *soc = cds_get_context(QDF_MODULE_ID_SOC);
-#else
-	/*TODO: WIN implementation to get soc */
-#endif
 
 	if (!cdp_pdev) {
 		qdf_print("Invalid pdev in %s", __func__);
@@ -220,28 +228,80 @@ wdi_pktlog_subscribe(struct cdp_pdev *cdp_pdev, int32_t log_state)
 			return A_ERROR;
 		}
 	}
+
+	return A_OK;
+}
+#else
+static inline A_STATUS
+wdi_pktlog_subscribe(struct cdp_pdev *cdp_pdev, int32_t log_state)
+{
+	void *soc = cds_get_context(QDF_MODULE_ID_SOC);
+
+	if (!cdp_pdev) {
+		qdf_print("Invalid pdev in %s", __func__);
+		return A_ERROR;
+	}
+
+	if ((log_state & ATH_PKTLOG_TX) ||
+	    (log_state  & ATH_PKTLOG_RCFIND) ||
+	    (log_state & ATH_PKTLOG_RCUPDATE) ||
+	    (log_state & ATH_PKTLOG_RX)) {
+		if (cdp_wdi_event_sub(soc,
+				      cdp_pdev,
+				      &PKTLOG_OFFLOAD_SUBSCRIBER,
+				      WDI_EVENT_OFFLOAD_ALL)) {
+			return A_ERROR;
+		}
+	}
+
+	if (log_state & ATH_PKTLOG_RX) {
+		if (cdp_wdi_event_sub(soc, cdp_pdev,
+				      &PKTLOG_RX_SUBSCRIBER,
+				      WDI_EVENT_RX_DESC)) {
+			return A_ERROR;
+		}
+	}
+
+	if (log_state & ATH_PKTLOG_SW_EVENT) {
+		if (cdp_wdi_event_sub(soc, cdp_pdev,
+				      &PKTLOG_SW_EVENT_SUBSCRIBER,
+				      WDI_EVENT_SW_EVENT)) {
+			return A_ERROR;
+		}
+	}
+
 	if (log_state & ATH_PKTLOG_LITE_T2H) {
 		if (cdp_wdi_event_sub(soc, cdp_pdev,
-				  &PKTLOG_LITE_T2H_SUBSCRIBER,
-				  WDI_EVENT_LITE_T2H)) {
+				      &PKTLOG_LITE_T2H_SUBSCRIBER,
+				      WDI_EVENT_LITE_T2H)) {
 			return A_ERROR;
 		}
 	}
+
 	if (log_state & ATH_PKTLOG_LITE_RX) {
 		if (cdp_wdi_event_sub(soc, cdp_pdev,
-				&PKTLOG_LITE_RX_SUBSCRIBER,
-				WDI_EVENT_LITE_RX)) {
+				      &PKTLOG_LITE_RX_SUBSCRIBER,
+				      WDI_EVENT_LITE_RX)) {
 			return A_ERROR;
 		}
 	}
 
 	return A_OK;
 }
+#endif
 
 void pktlog_callback(void *pdev, enum WDI_EVENT event, void *log_data,
 		u_int16_t peer_id, uint32_t status)
 {
 	switch (event) {
+	case WDI_EVENT_OFFLOAD_ALL:
+	{
+		if (process_offload_pktlog(pdev, log_data)) {
+			qdf_print("Unable to process offload info");
+			return;
+		}
+		break;
+	}
 	case WDI_EVENT_TX_STATUS:
 	{
 		/*
@@ -349,14 +409,19 @@ lit_pktlog_callback(void *context, enum WDI_EVENT event, void *log_data,
 	}
 }
 
+#ifdef HELIUMPLUS
+/**
+ * wdi_pktlog_unsubscribe() - Unsubscribe pktlog callbacks
+ * @cdp_pdev: abstract pdev handle
+ * @log_state: Pktlog registration
+ *
+ * Return: zero on success, non-zero on failure
+ */
 A_STATUS
 wdi_pktlog_unsubscribe(struct cdp_pdev *pdev, uint32_t log_state)
 {
-#ifdef CONFIG_MCL
 	void *soc = cds_get_context(QDF_MODULE_ID_SOC);
-#else
 	/* TODO: WIN implementation to get soc */
-#endif
 
 	if (log_state & ATH_PKTLOG_TX) {
 		if (cdp_wdi_event_unsub(soc, pdev,
@@ -376,6 +441,7 @@ wdi_pktlog_unsubscribe(struct cdp_pdev *pdev, uint32_t log_state)
 			return A_ERROR;
 		}
 	}
+
 	if (log_state & ATH_PKTLOG_RCFIND) {
 		if (cdp_wdi_event_unsub(soc, pdev,
 				    &PKTLOG_RCFIND_SUBSCRIBER,
@@ -397,23 +463,51 @@ wdi_pktlog_unsubscribe(struct cdp_pdev *pdev, uint32_t log_state)
 			return A_ERROR;
 		}
 	}
+
+	return A_OK;
+}
+#else
+A_STATUS
+wdi_pktlog_unsubscribe(struct cdp_pdev *pdev, uint32_t log_state)
+{
+	void *soc = cds_get_context(QDF_MODULE_ID_SOC);
+
+	if ((log_state & ATH_PKTLOG_TX) ||
+	    (log_state  & ATH_PKTLOG_RCFIND) ||
+	    (log_state & ATH_PKTLOG_RCUPDATE) ||
+	    (log_state & ATH_PKTLOG_RX)) {
+		if (cdp_wdi_event_unsub(soc,
+					pdev,
+					&PKTLOG_OFFLOAD_SUBSCRIBER,
+					WDI_EVENT_OFFLOAD_ALL)) {
+			return A_ERROR;
+		}
+	}
+	if (log_state & ATH_PKTLOG_RX) {
+		if (cdp_wdi_event_unsub(soc, pdev,
+					&PKTLOG_RX_SUBSCRIBER,
+					WDI_EVENT_RX_DESC)) {
+			return A_ERROR;
+		}
+	}
 	if (log_state & ATH_PKTLOG_LITE_T2H) {
 		if (cdp_wdi_event_unsub(soc, pdev,
-				  &PKTLOG_LITE_T2H_SUBSCRIBER,
-				  WDI_EVENT_LITE_T2H)) {
+					&PKTLOG_LITE_T2H_SUBSCRIBER,
+					WDI_EVENT_LITE_T2H)) {
 			return A_ERROR;
 		}
 	}
 	if (log_state & ATH_PKTLOG_LITE_RX) {
 		if (cdp_wdi_event_unsub(soc, pdev,
-				&PKTLOG_LITE_RX_SUBSCRIBER,
-				WDI_EVENT_LITE_RX)) {
+					&PKTLOG_LITE_RX_SUBSCRIBER,
+					WDI_EVENT_LITE_RX)) {
 			return A_ERROR;
 		}
 	}
 
 	return A_OK;
 }
+#endif
 
 int pktlog_disable(struct hif_opaque_softc *scn)
 {
@@ -515,6 +609,7 @@ void pktlog_init(struct hif_opaque_softc *scn)
 	} else if (pl_dev->callback_type == PKTLOG_LITE_CALLBACK_REGISTRATION) {
 		PKTLOG_LITE_T2H_SUBSCRIBER.callback = lit_pktlog_callback;
 		PKTLOG_LITE_RX_SUBSCRIBER.callback = lit_pktlog_callback;
+		PKTLOG_OFFLOAD_SUBSCRIBER.callback = pktlog_callback;
 	}
 }
 

+ 72 - 5
utils/pktlog/pktlog_internal.c

@@ -110,9 +110,7 @@ void pktlog_getbuf_intsafe(struct ath_pktlog_arg *plarg)
 	log_hdr->size = (uint16_t) log_size;
 	log_hdr->missed_cnt = plarg->missed_cnt;
 	log_hdr->timestamp = plarg->timestamp;
-#ifdef HELIUMPLUS
 	log_hdr->type_specific_data = plarg->type_specific_data;
-#endif
 	cur_wr_offset += sizeof(*log_hdr);
 
 	if ((buf_size - cur_wr_offset) < log_size) {
@@ -157,9 +155,8 @@ char *pktlog_getbuf(struct pktlog_dev_t *pl_dev,
 	plarg.flags = pl_hdr->flags;
 	plarg.missed_cnt = pl_hdr->missed_cnt;
 	plarg.timestamp = pl_hdr->timestamp;
-#ifdef HELIUMPLUS
 	plarg.type_specific_data = pl_hdr->type_specific_data;
-#endif
+
 	if (flags & PHFLAGS_INTERRUPT_CONTEXT) {
 		/*
 		 * We are already in interrupt context, no need to make it
@@ -453,7 +450,6 @@ A_STATUS process_tx_info(struct cdp_pdev *txrx_pdev, void *data)
 	}
 	return A_OK;
 }
-
 #else
 A_STATUS process_tx_info(struct cdp_pdev *txrx_pdev, void *data)
 {
@@ -640,6 +636,77 @@ A_STATUS process_tx_info(struct cdp_pdev *txrx_pdev, void *data)
 }
 #endif
 
+/**
+ * process_offload_pktlog() - Process full pktlog events
+ * pdev: abstract pdev handle
+ * data: pktlog buffer
+ *
+ * Return: zero on success, non-zero on failure
+ */
+A_STATUS
+process_offload_pktlog(struct cdp_pdev *pdev, void *data)
+{
+	struct pktlog_dev_t *pl_dev = get_pktlog_handle();
+	struct ath_pktlog_info *pl_info;
+	struct ath_pktlog_hdr pl_hdr;
+	uint32_t *pl_tgt_hdr;
+	void *txdesc_hdr_ctl = NULL;
+	size_t log_size = 0;
+	size_t tmp_log_size = 0;
+
+	if (!pl_dev) {
+		QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR,
+			  "Invalid context in %s\n", __func__);
+		return A_ERROR;
+	}
+
+	if (!data) {
+		QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR,
+			  "Invalid data in %s\n", __func__);
+		return A_ERROR;
+	}
+
+	pl_tgt_hdr = (uint32_t *)data;
+
+	pl_hdr.flags = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_FLAGS_OFFSET) &
+			ATH_PKTLOG_HDR_FLAGS_MASK) >>
+				ATH_PKTLOG_HDR_FLAGS_SHIFT;
+	pl_hdr.missed_cnt =  (*(pl_tgt_hdr + ATH_PKTLOG_HDR_MISSED_CNT_OFFSET) &
+			ATH_PKTLOG_HDR_MISSED_CNT_MASK) >>
+				ATH_PKTLOG_HDR_MISSED_CNT_SHIFT;
+	pl_hdr.log_type =  (*(pl_tgt_hdr + ATH_PKTLOG_HDR_LOG_TYPE_OFFSET) &
+			ATH_PKTLOG_HDR_LOG_TYPE_MASK) >>
+				ATH_PKTLOG_HDR_LOG_TYPE_SHIFT;
+	pl_hdr.size =  (*(pl_tgt_hdr + ATH_PKTLOG_HDR_SIZE_OFFSET) &
+			ATH_PKTLOG_HDR_SIZE_MASK) >> ATH_PKTLOG_HDR_SIZE_SHIFT;
+	pl_hdr.timestamp = *(pl_tgt_hdr + ATH_PKTLOG_HDR_TIMESTAMP_OFFSET);
+	pl_hdr.type_specific_data = *(pl_tgt_hdr
+			+ ATH_PKTLOG_HDR_TYPE_SPECIFIC_DATA_OFFSET);
+
+	/*
+	 *  Must include to process different types
+	 *  TX_CTL, TX_STATUS, TX_MSDU_ID, TX_FRM_HDR
+	 */
+	pl_info = pl_dev->pl_info;
+	tmp_log_size = sizeof(frm_hdr) + pl_hdr.size;
+	log_size = pl_hdr.size;
+	txdesc_hdr_ctl =
+		(void *)pktlog_getbuf(pl_dev, pl_info, log_size, &pl_hdr);
+	if (!txdesc_hdr_ctl) {
+		QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR,
+			  "Failed to allocate pktlog descriptor");
+		return A_NO_MEMORY;
+	}
+	qdf_assert(txdesc_hdr_ctl);
+	qdf_assert(pl_hdr->size < PKTLOG_MAX_TX_WORDS * sizeof(u_int32_t));
+	qdf_mem_copy(txdesc_hdr_ctl,
+		     ((void *)data + sizeof(struct ath_pktlog_hdr)),
+		     pl_hdr.size);
+	cds_pkt_stats_to_logger_thread(&pl_hdr, NULL, txdesc_hdr_ctl);
+
+	return A_OK;
+}
+
 /* TODO: hardware dependent function */
 A_STATUS process_rx_info_remote(void *pdev, void *data)
 {