Merge "qcacmn: TX Optimization"

This commit is contained in:
Linux Build Service Account 2020-02-13 00:39:58 -08:00 • committed by Gerrit - the friendly Code Review server
commit 09575dee2f
15 changed files with 236 additions and 66 deletions

View file

@ -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)

View file

@ -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

View file

@ -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);
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);
for (i = 0; i < soc->num_tcl_data_rings; i++) {
status = dp_setup_tx_ring_pair_by_index(soc, i);
if (status != QDF_STATUS_SUCCESS)
goto fail1;
}
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);

View file

@ -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

View file

@ -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,

View file

@ -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);
}
/*

View file

@ -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);

View file

@ -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 */

View file

@ -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 {

View file

@ -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

View file

@ -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);
}

View file

@ -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);

View file

@ -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 */

View file

@ -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)
{

View file

@ -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);
}