Browse Source

Merge "qcacmn: TX Optimization"

Linux Build Service Account 5 years ago
parent
commit
09575dee2f

+ 1 - 0
dp/inc/cdp_txrx_mob_def.h

@@ -23,6 +23,7 @@
 
 #define TX_WMM_AC_NUM	4
 #define ENABLE_DP_HIST_STATS
+#define DP_MEMORY_OPT
 #define DP_RX_DISABLE_NDI_MDNS_FORWARDING
 
 #define OL_TXQ_PAUSE_REASON_FW                (1 << 0)

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

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017-2019, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2017-2020, 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 above
@@ -17,10 +17,10 @@
 #ifndef _DP_IPA_H_
 #define _DP_IPA_H_
 
+#define IPA_TCL_DATA_RING_IDX	2
 #ifdef IPA_OFFLOAD
 
 #define DP_IPA_MAX_IFACE	3
-#define IPA_TCL_DATA_RING_IDX	2
 #define IPA_TX_COMP_RING_IDX	2
 #define IPA_REO_DEST_RING_IDX	3
 #define IPA_RX_REFILL_BUF_RING_IDX	2

+ 59 - 32
dp/wifi3.0/dp_main.c

@@ -2883,6 +2883,40 @@ static inline void dp_create_ext_stats_event(struct dp_soc *soc)
 }
 #endif
 
+static
+QDF_STATUS dp_setup_tx_ring_pair_by_index(struct dp_soc *soc, uint8_t index)
+{
+	int tx_ring_size;
+	int tx_comp_ring_size;
+	struct wlan_cfg_dp_soc_ctxt *soc_cfg_ctx = soc->wlan_cfg_ctx;
+	int cached;
+
+	tx_ring_size = wlan_cfg_tx_ring_size(soc_cfg_ctx);
+	if (dp_srng_setup(soc, &soc->tcl_data_ring[index], TCL_DATA,
+			  index, 0, tx_ring_size, 0)) {
+		dp_err("dp_srng_setup failed for tcl_data_ring");
+		goto fail1;
+	}
+
+	tx_comp_ring_size = wlan_cfg_tx_comp_ring_size(soc_cfg_ctx);
+	/* Disable cached desc if NSS offload is enabled */
+	cached = WLAN_CFG_DST_RING_CACHED_DESC;
+	if (wlan_cfg_get_dp_soc_nss_cfg(soc_cfg_ctx))
+		cached = 0;
+
+	if (dp_srng_setup(soc, &soc->tx_comp_ring[index],
+			  WBM2SW_RELEASE, index, 0, tx_comp_ring_size,
+			cached)) {
+		dp_err("dp_srng_setup failed for tx_comp_ring");
+		goto fail1;
+	}
+
+	return QDF_STATUS_SUCCESS;
+
+fail1:
+	return QDF_STATUS_E_FAILURE;
+}
+
 /*
  * dp_soc_cmn_setup() - Common SoC level initializion
  * @soc:		Datapath SOC handle
@@ -2899,6 +2933,7 @@ static int dp_soc_cmn_setup(struct dp_soc *soc)
 	int reo_dst_ring_size;
 	uint32_t entries;
 	struct wlan_cfg_dp_soc_ctxt *soc_cfg_ctx;
+	QDF_STATUS status;
 
 	if (qdf_atomic_read(&soc->cmn_init_done))
 		return 0;
@@ -2934,32 +2969,17 @@ static int dp_soc_cmn_setup(struct dp_soc *soc)
 			wlan_cfg_tx_comp_ring_size(soc_cfg_ctx);
 		tx_ring_size =
 			wlan_cfg_tx_ring_size(soc_cfg_ctx);
+
 		for (i = 0; i < soc->num_tcl_data_rings; i++) {
-			if (dp_srng_setup(soc, &soc->tcl_data_ring[i],
-					  TCL_DATA, i, 0, tx_ring_size, 0)) {
-				QDF_TRACE(QDF_MODULE_ID_DP,
-					QDF_TRACE_LEVEL_ERROR,
-					FL("dp_srng_setup failed for tcl_data_ring[%d]"), i);
+			status = dp_setup_tx_ring_pair_by_index(soc, i);
+			if (status != QDF_STATUS_SUCCESS)
 				goto fail1;
-			}
-
-			/* Disable cached desc if NSS offload is enabled */
-			cached = WLAN_CFG_DST_RING_CACHED_DESC;
-			if (wlan_cfg_get_dp_soc_nss_cfg(soc_cfg_ctx))
-				cached = 0;
-			/*
-			 * TBD: Set IPA WBM ring size with ini IPA UC tx buffer
-			 * count
-			 */
-			if (dp_srng_setup(soc, &soc->tx_comp_ring[i],
-					  WBM2SW_RELEASE, i, 0,
-					  tx_comp_ring_size,
-					  cached)) {
-				QDF_TRACE(QDF_MODULE_ID_DP,
-					QDF_TRACE_LEVEL_ERROR,
-					FL("dp_srng_setup failed for tx_comp_ring[%d]"), i);
+		}
+		if (wlan_cfg_is_ipa_enabled(soc->wlan_cfg_ctx)) {
+			status = dp_setup_tx_ring_pair_by_index(soc,
+						IPA_TCL_DATA_RING_IDX);
+			if (status != QDF_STATUS_SUCCESS)
 				goto fail1;
-			}
 		}
 	} else {
 		/* This will be incremented during per pdev ring setup */
@@ -4349,11 +4369,10 @@ static void dp_soc_deinit(void *txrx_soc)
 	/* Tx data rings */
 	if (!wlan_cfg_per_pdev_tx_ring(soc->wlan_cfg_ctx)) {
 		for (i = 0; i < soc->num_tcl_data_rings; i++) {
-			dp_srng_deinit(soc, &soc->tcl_data_ring[i],
-				       TCL_DATA, i);
-			dp_srng_deinit(soc, &soc->tx_comp_ring[i],
-				       WBM2SW_RELEASE, i);
+			dp_tx_deinit_pair_by_index(soc, i);
 		}
+		if (wlan_cfg_is_ipa_enabled(soc->wlan_cfg_ctx))
+			dp_tx_deinit_pair_by_index(soc, IPA_TCL_DATA_RING_IDX);
 	}
 
 	/* TCL command and status rings */
@@ -4402,6 +4421,12 @@ static void dp_soc_deinit(void *txrx_soc)
 	dp_soc_mem_reset(soc);
 }
 
+void dp_tx_deinit_pair_by_index(struct dp_soc *soc, int index)
+{
+	dp_srng_deinit(soc, &soc->tcl_data_ring[index], TCL_DATA, index);
+	dp_srng_deinit(soc, &soc->tx_comp_ring[index], WBM2SW_RELEASE, index);
+}
+
 /**
  * dp_soc_deinit_wifi3() - Deinitialize txrx SOC
  * @txrx_soc: Opaque DP SOC handle
@@ -4456,6 +4481,12 @@ static void dp_soc_detach(struct cdp_soc_t *txrx_soc)
 			dp_srng_cleanup(soc, &soc->tx_comp_ring[i],
 				WBM2SW_RELEASE, i);
 		}
+		if (wlan_cfg_is_ipa_enabled(soc->wlan_cfg_ctx)) {
+			dp_srng_cleanup(soc, &soc->tcl_data_ring[IPA_TCL_DATA_RING_IDX],
+				TCL_DATA, IPA_TCL_DATA_RING_IDX);
+			dp_srng_cleanup(soc, &soc->tx_comp_ring[IPA_TCL_DATA_RING_IDX],
+				WBM2SW_RELEASE, IPA_TCL_DATA_RING_IDX);
+		}
 	}
 
 	/* TCL command and status rings */
@@ -6301,7 +6332,6 @@ void dp_peer_unref_delete(struct dp_peer *peer)
 	struct cdp_peer_cookie peer_cookie;
 	enum wlan_op_mode vdev_opmode;
 	uint8_t vdev_mac_addr[QDF_MAC_ADDR_SIZE];
-	struct dp_ast_entry *peer_ast_entry = NULL;
 
 	/*
 	 * Hold the lock all the way from checking if the peer ref count
@@ -6333,10 +6363,7 @@ void dp_peer_unref_delete(struct dp_peer *peer)
 
 		qdf_spin_lock_bh(&soc->ast_lock);
 		if (peer->self_ast_entry) {
-			peer_ast_entry = peer->self_ast_entry;
-			dp_peer_unlink_ast_entry(soc, peer_ast_entry);
-			dp_peer_free_ast_entry(soc, peer_ast_entry);
-			peer->self_ast_entry = NULL;
+			dp_peer_del_ast(soc, peer->self_ast_entry);
 		}
 		qdf_spin_unlock_bh(&soc->ast_lock);
 

+ 29 - 6
dp/wifi3.0/dp_peer.c

@@ -34,6 +34,34 @@
 #include "dp_tx_capture.h"
 #endif
 
+#ifdef FEATURE_WDS
+static inline bool
+dp_peer_ast_free_in_unmap_supported(struct dp_peer *peer,
+				    struct dp_ast_entry *ast_entry)
+{
+	/* if peer map v2 is enabled we are not freeing ast entry
+	 * here and it is supposed to be freed in unmap event (after
+	 * we receive delete confirmation from target)
+	 *
+	 * if peer_id is invalid we did not get the peer map event
+	 * for the peer free ast entry from here only in this case
+	 */
+
+	if ((ast_entry->type != CDP_TXRX_AST_TYPE_WDS_HM_SEC) &&
+	    (ast_entry->type != CDP_TXRX_AST_TYPE_SELF))
+		return true;
+
+	return false;
+}
+#else
+static inline bool
+dp_peer_ast_free_in_unmap_supported(struct dp_peer *peer,
+				    struct dp_ast_entry *ast_entry)
+{
+	return false;
+}
+#endif
+
 static inline void
 dp_set_ssn_valid_flag(struct hal_reo_cmd_params *params,
 					uint8_t valid)
@@ -935,12 +963,7 @@ void dp_peer_del_ast(struct dp_soc *soc, struct dp_ast_entry *ast_entry)
 	 * if peer_id is invalid we did not get the peer map event
 	 * for the peer free ast entry from here only in this case
 	 */
-
-	/* For HM_SEC and SELF type we do not receive unmap event
-	 * free ast_entry from here it self
-	 */
-	if ((ast_entry->type != CDP_TXRX_AST_TYPE_WDS_HM_SEC) &&
-	    (ast_entry->type != CDP_TXRX_AST_TYPE_SELF))
+	if (dp_peer_ast_free_in_unmap_supported(peer, ast_entry))
 		return;
 
 	/* for WDS secondary entry ast_entry->next_hop would be set so

+ 15 - 7
dp/wifi3.0/dp_rx_mon_status.c

@@ -430,22 +430,30 @@ static inline void dp_rx_rate_stats_update(struct dp_peer *peer,
 	uint32_t ratekbps = 0;
 	uint32_t ppdu_rx_rate = 0;
 	uint32_t nss = 0;
+	uint8_t mcs = 0;
 	uint32_t rix;
 	uint16_t ratecode;
-	struct cdp_rx_stats_ppdu_user *ppdu_user;
+	struct cdp_rx_stats_ppdu_user *ppdu_user = NULL;
 
 	if (!peer || !ppdu)
 		return;
 
-	ppdu_user = &ppdu->user[user];
+	if (ppdu->u.ppdu_type != HAL_RX_TYPE_SU) {
+		ppdu_user = &ppdu->user[user];
 
-	if (ppdu_user->nss == 0)
-		nss = 0;
-	else
-		nss = ppdu_user->nss - 1;
+		if (ppdu_user->nss == 0)
+			nss = 0;
+		else
+			nss = ppdu_user->nss - 1;
+		mcs = ppdu_user->mcs;
+
+	} else {
+		mcs = ppdu->u.mcs;
+		nss = ppdu->u.nss;
+	}
 
 	ratekbps = dp_getrateindex(ppdu->u.gi,
-				   ppdu_user->mcs,
+				   mcs,
 				   nss,
 				   ppdu->u.preamble,
 				   ppdu->u.bw,

+ 4 - 0
dp/wifi3.0/dp_tx.c

@@ -28,6 +28,7 @@
 #include "qdf_nbuf.h"
 #include "qdf_net_types.h"
 #include <wlan_cfg.h>
+#include "dp_ipa.h"
 #if defined(MESH_MODE_SUPPORT) || defined(FEATURE_PERPKT_INFO)
 #include "if_meta_hdr.h"
 #endif
@@ -4327,6 +4328,9 @@ QDF_STATUS dp_tx_soc_attach(struct dp_soc *soc)
 			hal_tx_init_data_ring(soc->hal_soc,
 					soc->tcl_data_ring[i].hal_srng);
 		}
+		if (wlan_cfg_is_ipa_enabled(soc->wlan_cfg_ctx))
+			hal_tx_init_data_ring(soc->hal_soc,
+					soc->tcl_data_ring[IPA_TCL_DATA_RING_IDX].hal_srng);
 	}
 
 	/*

+ 14 - 0
dp/wifi3.0/dp_tx.h

@@ -153,6 +153,20 @@ struct dp_tx_msdu_info_s {
 	uint8_t is_tx_sniffer;
 };
 
+/**
+ * dp_tx_deinit_pair_by_index() - Deinit TX rings based on index
+ * @soc: core txrx context
+ * @index: index of ring to deinit
+ *
+ * Deinit 1 TCL and 1 WBM2SW release ring on as needed basis using
+ * index of the respective TCL/WBM2SW release in soc structure.
+ * For example, if the index is 2 then &soc->tcl_data_ring[2]
+ * and &soc->tx_comp_ring[2] will be deinitialized.
+ *
+ * Return: none
+ */
+void dp_tx_deinit_pair_by_index(struct dp_soc *soc, int index);
+
 QDF_STATUS dp_tx_vdev_attach(struct dp_vdev *vdev);
 QDF_STATUS dp_tx_vdev_detach(struct dp_vdev *vdev);
 void dp_tx_vdev_update_search_flags(struct dp_vdev *vdev);

+ 4 - 1
hif/src/usb/if_usb.c

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013-2019 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2013-2020 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
@@ -27,6 +27,9 @@
 #include "epping_main.h"
 #include "hif_main.h"
 #include "usb_api.h"
+#ifdef CONFIG_PLD_USB_CNSS
+#include "pld_common.h"
+#endif
 
 #define DELAY_FOR_TARGET_READY 200	/* 200ms */
 

+ 10 - 2
qdf/linux/src/i_qdf_lock.h

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014-2018 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2014-2018, 2020 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
@@ -84,7 +84,15 @@ typedef struct __qdf_spinlock {
 
 typedef struct semaphore __qdf_semaphore_t;
 
-typedef struct wakeup_source qdf_wake_lock_t;
+/**
+ * typedef struct - qdf_wake_lock_t
+ * @lock: this lock needs to be used in kernel version < 5.4
+ * @priv: this lock pointer needs to be used in kernel version >= 5.4
+ */
+typedef struct qdf_wake_lock {
+	struct wakeup_source lock;
+	struct wakeup_source *priv;
+} qdf_wake_lock_t;
 
 struct hif_pm_runtime_lock;
 typedef struct qdf_runtime_lock {

+ 19 - 11
qdf/linux/src/qdf_lock.c

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014-2019 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2014-2020 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
@@ -244,8 +244,8 @@ qdf_export_symbol(qdf_mutex_release);
 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 10, 0))
 const char *qdf_wake_lock_name(qdf_wake_lock_t *lock)
 {
-	if (lock->name)
-		return lock->name;
+	if (lock)
+		return lock->lock.name;
 	return "UNNAMED_WAKELOCK";
 }
 #else
@@ -268,13 +268,21 @@ qdf_export_symbol(qdf_wake_lock_name);
 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 4, 0))
 QDF_STATUS qdf_wake_lock_create(qdf_wake_lock_t *lock, const char *name)
 {
-	wakeup_source_register(lock->dev, name);
+	lock->priv = wakeup_source_register(lock->lock.dev, name);
+	if (!(lock->priv)) {
+		QDF_BUG(0);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	lock->lock = *(lock->priv);
+
 	return QDF_STATUS_SUCCESS;
 }
 #elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 10, 0))
 QDF_STATUS qdf_wake_lock_create(qdf_wake_lock_t *lock, const char *name)
 {
-	wakeup_source_init(lock, name);
+	wakeup_source_init(&(lock->lock), name);
+	lock->priv = &(lock->lock);
 	return QDF_STATUS_SUCCESS;
 }
 #else
@@ -300,7 +308,7 @@ QDF_STATUS qdf_wake_lock_acquire(qdf_wake_lock_t *lock, uint32_t reason)
 	host_diag_log_wlock(reason, qdf_wake_lock_name(lock),
 			    WIFI_POWER_EVENT_DEFAULT_WAKELOCK_TIMEOUT,
 			    WIFI_POWER_EVENT_WAKELOCK_TAKEN);
-	__pm_stay_awake(lock);
+	__pm_stay_awake(lock->priv);
 
 	return QDF_STATUS_SUCCESS;
 }
@@ -324,7 +332,7 @@ qdf_export_symbol(qdf_wake_lock_acquire);
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 12, 0)
 QDF_STATUS qdf_wake_lock_timeout_acquire(qdf_wake_lock_t *lock, uint32_t msec)
 {
-	pm_wakeup_ws_event(lock, msec, true);
+	pm_wakeup_ws_event(lock->priv, msec, true);
 	return QDF_STATUS_SUCCESS;
 }
 #elif LINUX_VERSION_CODE >= KERNEL_VERSION(3, 10, 0)
@@ -333,7 +341,7 @@ QDF_STATUS qdf_wake_lock_timeout_acquire(qdf_wake_lock_t *lock, uint32_t msec)
 	/* Wakelock for Rx is frequent.
 	 * It is reported only during active debug
 	 */
-	__pm_wakeup_event(lock, msec);
+	__pm_wakeup_event(&(lock->lock), msec);
 	return QDF_STATUS_SUCCESS;
 }
 #else /* LINUX_VERSION_CODE */
@@ -359,7 +367,7 @@ QDF_STATUS qdf_wake_lock_release(qdf_wake_lock_t *lock, uint32_t reason)
 	host_diag_log_wlock(reason, qdf_wake_lock_name(lock),
 			    WIFI_POWER_EVENT_DEFAULT_WAKELOCK_TIMEOUT,
 			    WIFI_POWER_EVENT_WAKELOCK_RELEASED);
-	__pm_relax(lock);
+	__pm_relax(lock->priv);
 
 	return QDF_STATUS_SUCCESS;
 }
@@ -382,13 +390,13 @@ qdf_export_symbol(qdf_wake_lock_release);
 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 1, 0))
 QDF_STATUS qdf_wake_lock_destroy(qdf_wake_lock_t *lock)
 {
-	wakeup_source_unregister(lock);
+	wakeup_source_unregister(lock->priv);
 	return QDF_STATUS_SUCCESS;
 }
 #elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 10, 0))
 QDF_STATUS qdf_wake_lock_destroy(qdf_wake_lock_t *lock)
 {
-	wakeup_source_trash(lock);
+	wakeup_source_trash(&(lock->lock));
 	return QDF_STATUS_SUCCESS;
 }
 #else

+ 11 - 2
qdf/linux/src/qdf_nbuf.c

@@ -114,7 +114,7 @@ static uint32_t nbuf_tx_data[QDF_NBUF_TX_PKT_STATE_MAX];
 static qdf_atomic_t nbuf_count;
 #endif
 
-#if defined(NBUF_MEMORY_DEBUG)
+#if defined(NBUF_MEMORY_DEBUG) || defined(QDF_NBUF_GLOBAL_COUNT)
 static bool is_initial_mem_debug_disabled;
 #endif
 
@@ -340,7 +340,12 @@ qdf_export_symbol(__qdf_nbuf_count_get);
 void __qdf_nbuf_count_inc(qdf_nbuf_t nbuf)
 {
 	int num_nbuf = 1;
-	qdf_nbuf_t ext_list = qdf_nbuf_get_ext_list(nbuf);
+	qdf_nbuf_t ext_list;
+
+	if (qdf_likely(is_initial_mem_debug_disabled))
+		return;
+
+	ext_list = qdf_nbuf_get_ext_list(nbuf);
 
 	/* Take care to account for frag_list */
 	while (ext_list) {
@@ -364,6 +369,9 @@ void __qdf_nbuf_count_dec(__qdf_nbuf_t nbuf)
 	qdf_nbuf_t ext_list;
 	int num_nbuf;
 
+	if (qdf_likely(is_initial_mem_debug_disabled))
+		return;
+
 	if (qdf_nbuf_get_users(nbuf) > 1)
 		return;
 
@@ -4444,6 +4452,7 @@ qdf_export_symbol(qdf_nbuf_init_fast);
  */
 void __qdf_nbuf_mod_init(void)
 {
+	is_initial_mem_debug_disabled = qdf_mem_debug_config_get();
 	qdf_atomic_init(&nbuf_count);
 	qdf_debugfs_create_atomic(NBUF_DEBUGFS_NAME, S_IRUSR, NULL, &nbuf_count);
 }

+ 10 - 1
scheduler/inc/scheduler_api.h

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014-2019 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2014-2020 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
@@ -92,6 +92,15 @@ struct scheduler_msg {
 #endif /* WLAN_SCHED_HISTORY_SIZE */
 };
 
+/**
+ * sched_history_print() - print scheduler history
+ *
+ * This API prints the scheduler history.
+ *
+ * Return: None
+ */
+void sched_history_print(void);
+
 typedef QDF_STATUS (*scheduler_msg_process_fn_t) (struct scheduler_msg  *msg);
 typedef void (*hdd_suspend_callback)(void);
 

+ 50 - 1
scheduler/src/scheduler_core.c

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014-2019 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2014-2020 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
@@ -28,6 +28,15 @@ DEFINE_QDF_FLEX_MEM_POOL(sched_pool, sizeof(struct scheduler_msg),
 
 #ifdef WLAN_SCHED_HISTORY_SIZE
 
+#define SCHEDULER_HISTORY_HEADER "|Callback                               "\
+				 "|Message Type"			   \
+				 "|Queue Duration(us)|Queue Depth"	   \
+				 "|Run Duration(us)|"
+
+#define SCHEDULER_HISTORY_LINE "--------------------------------------" \
+			       "--------------------------------------" \
+			       "--------------------------------------"
+
 /**
  * struct sched_history_item - metrics for a scheduler message
  * @callback: the message's execution callback
@@ -87,12 +96,52 @@ static void sched_history_stop(void)
 	sched_history_index %= WLAN_SCHED_HISTORY_SIZE;
 }
 
+void sched_history_print(void)
+{
+	struct sched_history_item *history, *item;
+	uint32_t history_idx;
+	uint32_t idx, index;
+
+	history = qdf_mem_malloc(sizeof(*history) * WLAN_SCHED_HISTORY_SIZE);
+
+	if (!history) {
+		sched_err("Mem alloc failed");
+		return;
+	}
+
+	qdf_mem_copy(history, &sched_history,
+		     (sizeof(*history) * WLAN_SCHED_HISTORY_SIZE));
+	history_idx = sched_history_index;
+
+	sched_nofl_fatal(SCHEDULER_HISTORY_LINE);
+	sched_nofl_fatal(SCHEDULER_HISTORY_HEADER);
+	sched_nofl_fatal(SCHEDULER_HISTORY_LINE);
+
+	for (idx = 0; idx < WLAN_SCHED_HISTORY_SIZE; idx++) {
+		index = (history_idx + idx) % WLAN_SCHED_HISTORY_SIZE;
+		item = history + index;
+
+		if (!item->callback)
+			continue;
+
+		sched_nofl_fatal("%40pF|%12d|%18d|%11d|%16d|",
+				 item->callback, item->type_id,
+				 item->queue_duration_us,
+				 item->queue_depth,
+				 item->run_duration_us);
+	}
+
+	sched_nofl_fatal(SCHEDULER_HISTORY_LINE);
+
+	qdf_mem_free(history);
+}
 #else /* WLAN_SCHED_HISTORY_SIZE */
 
 static inline void sched_history_queue(struct scheduler_mq_type *queue,
 				       struct scheduler_msg *msg) { }
 static inline void sched_history_start(struct scheduler_msg *msg) { }
 static inline void sched_history_stop(void) { }
+void sched_history_print(void) { }
 
 #endif /* WLAN_SCHED_HISTORY_SIZE */
 

+ 7 - 0
wlan_cfg/wlan_cfg.c

@@ -829,10 +829,17 @@ int wlan_cfg_per_pdev_lmac_ring(struct wlan_cfg_dp_soc_ctxt *cfg)
 	return cfg->per_pdev_lmac_ring;
 }
 
+#ifdef DP_MEMORY_OPT
+int wlan_cfg_num_tcl_data_rings(struct wlan_cfg_dp_soc_ctxt *cfg)
+{
+	return 1;
+}
+#else
 int wlan_cfg_num_tcl_data_rings(struct wlan_cfg_dp_soc_ctxt *cfg)
 {
 	return cfg->num_tcl_data_rings;
 }
+#endif
 
 int wlan_cfg_tx_ring_size(struct wlan_cfg_dp_soc_ctxt *cfg)
 {

+ 1 - 1
wmi/src/wmi_unified.c

@@ -1617,7 +1617,7 @@ static uint8_t *wmi_id_to_name(uint32_t wmi_command)
 
 static inline void wmi_log_cmd_id(uint32_t cmd_id, uint32_t tag)
 {
-	WMI_LOGD("Send WMI command:%s command_id:%d htc_tag:%d\n",
+	WMI_LOGD("Send WMI command:%s command_id:%d htc_tag:%d",
 		 wmi_id_to_name(cmd_id), cmd_id, tag);
 }