mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-26 06:33:19 -04:00
Merge 5e1b73532e on remote branch
Change-Id: I78233e6358a615f989640c7a00855515bd3788e3
This commit is contained in:
commit
ae3b3e5534
21 changed files with 430 additions and 42 deletions
|
|
@ -1837,8 +1837,20 @@ void dp_peer_stats_update_protocol_cnt(struct cdp_soc_t *soc,
|
|||
|
||||
#ifdef QCA_LL_TX_FLOW_CONTROL_V2
|
||||
void dp_tx_dump_flow_pool_info(struct cdp_soc_t *soc_hdl);
|
||||
|
||||
/**
|
||||
* dp_tx_dump_flow_pool_info_compact() - dump flow pool info
|
||||
* @soc: DP soc context
|
||||
*
|
||||
* Return: none
|
||||
*/
|
||||
void dp_tx_dump_flow_pool_info_compact(struct dp_soc *soc);
|
||||
int dp_tx_delete_flow_pool(struct dp_soc *soc, struct dp_tx_desc_pool_s *pool,
|
||||
bool force);
|
||||
#else
|
||||
static inline void dp_tx_dump_flow_pool_info_compact(struct dp_soc *soc)
|
||||
{
|
||||
}
|
||||
#endif /* QCA_LL_TX_FLOW_CONTROL_V2 */
|
||||
|
||||
#ifdef QCA_OL_DP_SRNG_LOCK_LESS_ACCESS
|
||||
|
|
|
|||
|
|
@ -7503,7 +7503,7 @@ QDF_STATUS dp_reset_monitor_mode(struct cdp_soc_t *soc_hdl,
|
|||
*
|
||||
* Return: outstanding tx
|
||||
*/
|
||||
static uint32_t dp_get_tx_pending(struct cdp_pdev *pdev_handle)
|
||||
static int32_t dp_get_tx_pending(struct cdp_pdev *pdev_handle)
|
||||
{
|
||||
struct dp_pdev *pdev = (struct dp_pdev *)pdev_handle;
|
||||
|
||||
|
|
@ -10085,6 +10085,8 @@ static QDF_STATUS dp_txrx_dump_stats(struct cdp_soc_t *psoc, uint16_t value,
|
|||
case CDP_DUMP_TX_FLOW_POOL_INFO:
|
||||
if (level == QDF_STATS_VERBOSITY_LEVEL_HIGH)
|
||||
cdp_dump_flow_pool_info((struct cdp_soc_t *)soc);
|
||||
else
|
||||
dp_tx_dump_flow_pool_info_compact(soc);
|
||||
break;
|
||||
|
||||
case CDP_DP_NAPI_STATS:
|
||||
|
|
@ -11559,6 +11561,7 @@ static QDF_STATUS dp_runtime_suspend(struct cdp_soc_t *soc_hdl, uint8_t pdev_id)
|
|||
struct dp_soc *soc = cdp_soc_t_to_dp_soc(soc_hdl);
|
||||
struct dp_pdev *pdev;
|
||||
uint8_t i;
|
||||
int32_t tx_pending;
|
||||
|
||||
pdev = dp_get_pdev_from_soc_pdev_id_wifi3(soc, pdev_id);
|
||||
if (!pdev) {
|
||||
|
|
@ -11567,9 +11570,11 @@ static QDF_STATUS dp_runtime_suspend(struct cdp_soc_t *soc_hdl, uint8_t pdev_id)
|
|||
}
|
||||
|
||||
/* Abort if there are any pending TX packets */
|
||||
if (dp_get_tx_pending(dp_pdev_to_cdp_pdev(pdev)) > 0) {
|
||||
tx_pending = dp_get_tx_pending(dp_pdev_to_cdp_pdev(pdev));
|
||||
if (tx_pending) {
|
||||
QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_INFO,
|
||||
FL("Abort suspend due to pending TX packets"));
|
||||
FL("Abort suspend due to pending TX packets %d"),
|
||||
tx_pending);
|
||||
|
||||
/* perform a force flush if tx is pending */
|
||||
for (i = 0; i < soc->num_tcl_data_rings; i++) {
|
||||
|
|
@ -12042,6 +12047,7 @@ static QDF_STATUS dp_bus_suspend(struct cdp_soc_t *soc_hdl, uint8_t pdev_id)
|
|||
struct dp_pdev *pdev = dp_get_pdev_from_soc_pdev_id_wifi3(soc, pdev_id);
|
||||
int timeout = SUSPEND_DRAIN_WAIT;
|
||||
int drain_wait_delay = 50; /* 50 ms */
|
||||
int32_t tx_pending;
|
||||
|
||||
if (qdf_unlikely(!pdev)) {
|
||||
dp_err("pdev is NULL");
|
||||
|
|
@ -12049,10 +12055,11 @@ static QDF_STATUS dp_bus_suspend(struct cdp_soc_t *soc_hdl, uint8_t pdev_id)
|
|||
}
|
||||
|
||||
/* Abort if there are any pending TX packets */
|
||||
while (dp_get_tx_pending((struct cdp_pdev *)pdev) > 0) {
|
||||
while ((tx_pending = dp_get_tx_pending((struct cdp_pdev *)pdev))) {
|
||||
qdf_sleep(drain_wait_delay);
|
||||
if (timeout <= 0) {
|
||||
dp_err("TX frames are pending, abort suspend");
|
||||
dp_info("TX frames are pending %d, abort suspend",
|
||||
tx_pending);
|
||||
return QDF_STATUS_E_TIMEOUT;
|
||||
}
|
||||
timeout = timeout - drain_wait_delay;
|
||||
|
|
|
|||
|
|
@ -1199,29 +1199,67 @@ static void dp_rx_fill_gro_info(struct dp_soc *soc, uint8_t *rx_tlv,
|
|||
*
|
||||
* @nbuf: pointer to msdu.
|
||||
* @mpdu_len: mpdu length
|
||||
* @l3_pad_len: L3 padding length by HW
|
||||
*
|
||||
* Return: returns true if nbuf is last msdu of mpdu else retuns false.
|
||||
*/
|
||||
static inline bool dp_rx_adjust_nbuf_len(qdf_nbuf_t nbuf, uint16_t *mpdu_len)
|
||||
static inline bool dp_rx_adjust_nbuf_len(qdf_nbuf_t nbuf,
|
||||
uint16_t *mpdu_len,
|
||||
uint32_t l3_pad_len)
|
||||
{
|
||||
bool last_nbuf;
|
||||
uint32_t pkt_hdr_size;
|
||||
|
||||
if (*mpdu_len > (RX_DATA_BUFFER_SIZE - RX_PKT_TLVS_LEN)) {
|
||||
pkt_hdr_size = RX_PKT_TLVS_LEN + l3_pad_len;
|
||||
|
||||
if ((*mpdu_len + pkt_hdr_size) > RX_DATA_BUFFER_SIZE) {
|
||||
qdf_nbuf_set_pktlen(nbuf, RX_DATA_BUFFER_SIZE);
|
||||
last_nbuf = false;
|
||||
*mpdu_len -= (RX_DATA_BUFFER_SIZE - pkt_hdr_size);
|
||||
} else {
|
||||
qdf_nbuf_set_pktlen(nbuf, (*mpdu_len + RX_PKT_TLVS_LEN));
|
||||
qdf_nbuf_set_pktlen(nbuf, (*mpdu_len + pkt_hdr_size));
|
||||
last_nbuf = true;
|
||||
*mpdu_len = 0;
|
||||
}
|
||||
|
||||
*mpdu_len -= (RX_DATA_BUFFER_SIZE - RX_PKT_TLVS_LEN);
|
||||
|
||||
return last_nbuf;
|
||||
}
|
||||
|
||||
/**
|
||||
* dp_get_l3_hdr_pad_len() - get L3 header padding length.
|
||||
*
|
||||
* @soc: DP soc handle
|
||||
* @nbuf: pointer to msdu.
|
||||
*
|
||||
* Return: returns padding length in bytes.
|
||||
*/
|
||||
static inline uint32_t dp_get_l3_hdr_pad_len(struct dp_soc *soc,
|
||||
qdf_nbuf_t nbuf)
|
||||
{
|
||||
uint32_t l3_hdr_pad = 0;
|
||||
uint8_t *rx_tlv_hdr;
|
||||
struct hal_rx_msdu_metadata msdu_metadata;
|
||||
|
||||
while (nbuf) {
|
||||
if (!qdf_nbuf_is_rx_chfrag_cont(nbuf)) {
|
||||
/* scattered msdu end with continuation is 0 */
|
||||
rx_tlv_hdr = qdf_nbuf_data(nbuf);
|
||||
hal_rx_msdu_metadata_get(soc->hal_soc,
|
||||
rx_tlv_hdr,
|
||||
&msdu_metadata);
|
||||
l3_hdr_pad = msdu_metadata.l3_hdr_pad;
|
||||
break;
|
||||
}
|
||||
nbuf = nbuf->next;
|
||||
}
|
||||
|
||||
return l3_hdr_pad;
|
||||
}
|
||||
|
||||
/**
|
||||
* dp_rx_sg_create() - create a frag_list for MSDUs which are spread across
|
||||
* multiple nbufs.
|
||||
* @soc: DP SOC handle
|
||||
* @nbuf: pointer to the first msdu of an amsdu.
|
||||
*
|
||||
* This function implements the creation of RX frag_list for cases
|
||||
|
|
@ -1229,12 +1267,13 @@ static inline bool dp_rx_adjust_nbuf_len(qdf_nbuf_t nbuf, uint16_t *mpdu_len)
|
|||
*
|
||||
* Return: returns the head nbuf which contains complete frag_list.
|
||||
*/
|
||||
qdf_nbuf_t dp_rx_sg_create(qdf_nbuf_t nbuf)
|
||||
qdf_nbuf_t dp_rx_sg_create(struct dp_soc *soc, qdf_nbuf_t nbuf)
|
||||
{
|
||||
qdf_nbuf_t parent, frag_list, next = NULL;
|
||||
uint16_t frag_list_len = 0;
|
||||
uint16_t mpdu_len;
|
||||
bool last_nbuf;
|
||||
uint32_t l3_hdr_pad_offset = 0;
|
||||
|
||||
/*
|
||||
* Use msdu len got from REO entry descriptor instead since
|
||||
|
|
@ -1242,6 +1281,7 @@ qdf_nbuf_t dp_rx_sg_create(qdf_nbuf_t nbuf)
|
|||
* from REO descriptor is right for non-raw RX scatter msdu.
|
||||
*/
|
||||
mpdu_len = QDF_NBUF_CB_RX_PKT_LEN(nbuf);
|
||||
|
||||
/*
|
||||
* this is a case where the complete msdu fits in one single nbuf.
|
||||
* in this case HW sets both start and end bit and we only need to
|
||||
|
|
@ -1254,6 +1294,8 @@ qdf_nbuf_t dp_rx_sg_create(qdf_nbuf_t nbuf)
|
|||
return nbuf;
|
||||
}
|
||||
|
||||
l3_hdr_pad_offset = dp_get_l3_hdr_pad_len(soc, nbuf);
|
||||
|
||||
/*
|
||||
* This is a case where we have multiple msdus (A-MSDU) spread across
|
||||
* multiple nbufs. here we create a fraglist out of these nbufs.
|
||||
|
|
@ -1273,7 +1315,24 @@ qdf_nbuf_t dp_rx_sg_create(qdf_nbuf_t nbuf)
|
|||
* nbufs will form the frag_list of the parent nbuf.
|
||||
*/
|
||||
qdf_nbuf_set_rx_chfrag_start(parent, 1);
|
||||
last_nbuf = dp_rx_adjust_nbuf_len(parent, &mpdu_len);
|
||||
/*
|
||||
* L3 header padding is only needed for the 1st buffer
|
||||
* in a scattered msdu
|
||||
*/
|
||||
last_nbuf = dp_rx_adjust_nbuf_len(parent, &mpdu_len,
|
||||
l3_hdr_pad_offset);
|
||||
|
||||
/*
|
||||
* HW issue: MSDU cont bit is set but reported MPDU length can fit
|
||||
* in to single buffer
|
||||
*
|
||||
* Increment error stats and avoid SG list creation
|
||||
*/
|
||||
if (last_nbuf) {
|
||||
qdf_nbuf_pull_head(parent,
|
||||
RX_PKT_TLVS_LEN + l3_hdr_pad_offset);
|
||||
return parent;
|
||||
}
|
||||
|
||||
/*
|
||||
* this is where we set the length of the fragments which are
|
||||
|
|
@ -1281,7 +1340,7 @@ qdf_nbuf_t dp_rx_sg_create(qdf_nbuf_t nbuf)
|
|||
* till we hit the last_nbuf of the list.
|
||||
*/
|
||||
do {
|
||||
last_nbuf = dp_rx_adjust_nbuf_len(nbuf, &mpdu_len);
|
||||
last_nbuf = dp_rx_adjust_nbuf_len(nbuf, &mpdu_len, 0);
|
||||
qdf_nbuf_pull_head(nbuf, RX_PKT_TLVS_LEN);
|
||||
frag_list_len += qdf_nbuf_len(nbuf);
|
||||
|
||||
|
|
@ -1298,7 +1357,8 @@ qdf_nbuf_t dp_rx_sg_create(qdf_nbuf_t nbuf)
|
|||
qdf_nbuf_append_ext_list(parent, frag_list, frag_list_len);
|
||||
parent->next = next;
|
||||
|
||||
qdf_nbuf_pull_head(parent, RX_PKT_TLVS_LEN);
|
||||
qdf_nbuf_pull_head(parent,
|
||||
RX_PKT_TLVS_LEN + l3_hdr_pad_offset);
|
||||
return parent;
|
||||
}
|
||||
|
||||
|
|
@ -2833,7 +2893,7 @@ done:
|
|||
qdf_nbuf_pull_head(nbuf, RX_PKT_TLVS_LEN);
|
||||
} else if (qdf_nbuf_is_rx_chfrag_cont(nbuf)) {
|
||||
msdu_len = QDF_NBUF_CB_RX_PKT_LEN(nbuf);
|
||||
nbuf = dp_rx_sg_create(nbuf);
|
||||
nbuf = dp_rx_sg_create(soc, nbuf);
|
||||
next = nbuf->next;
|
||||
|
||||
if (qdf_nbuf_is_raw_frame(nbuf)) {
|
||||
|
|
|
|||
|
|
@ -676,6 +676,7 @@ dp_rx_wbm_err_process(struct dp_intr *int_ctx, struct dp_soc *soc,
|
|||
/**
|
||||
* dp_rx_sg_create() - create a frag_list for MSDUs which are spread across
|
||||
* multiple nbufs.
|
||||
* @soc: core txrx main context
|
||||
* @nbuf: pointer to the first msdu of an amsdu.
|
||||
*
|
||||
* This function implements the creation of RX frag_list for cases
|
||||
|
|
@ -683,7 +684,7 @@ dp_rx_wbm_err_process(struct dp_intr *int_ctx, struct dp_soc *soc,
|
|||
*
|
||||
* Return: returns the head nbuf which contains complete frag_list.
|
||||
*/
|
||||
qdf_nbuf_t dp_rx_sg_create(qdf_nbuf_t nbuf);
|
||||
qdf_nbuf_t dp_rx_sg_create(struct dp_soc *soc, qdf_nbuf_t nbuf);
|
||||
|
||||
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -606,7 +606,7 @@ more_msdu_link_desc:
|
|||
rx_tlv_hdr_last = qdf_nbuf_data(tail_nbuf);
|
||||
|
||||
if (qdf_unlikely(head_nbuf != tail_nbuf)) {
|
||||
nbuf = dp_rx_sg_create(head_nbuf);
|
||||
nbuf = dp_rx_sg_create(soc, head_nbuf);
|
||||
qdf_nbuf_set_is_frag(nbuf, 1);
|
||||
DP_STATS_INC(soc, rx.err.reo_err_oor_sg_count, 1);
|
||||
}
|
||||
|
|
@ -2375,7 +2375,7 @@ done:
|
|||
* QCN9000 has this support
|
||||
*/
|
||||
if (qdf_nbuf_is_rx_chfrag_cont(nbuf)) {
|
||||
nbuf = dp_rx_sg_create(nbuf);
|
||||
nbuf = dp_rx_sg_create(soc, nbuf);
|
||||
next = nbuf->next;
|
||||
/*
|
||||
* SG error handling is not done correctly,
|
||||
|
|
|
|||
|
|
@ -5956,6 +5956,8 @@ void dp_txrx_path_stats(struct dp_soc *soc)
|
|||
pdev->stats.tx.dropped.fw_rem_notx);
|
||||
DP_PRINT_STATS("Invalid peer on tx path: %u",
|
||||
pdev->soc->stats.tx.tx_invalid_peer.num);
|
||||
DP_PRINT_STATS("Tx desc freed in non-completion path: %u",
|
||||
pdev->soc->stats.tx.tx_comp_exception);
|
||||
|
||||
DP_PRINT_STATS("Tx packets sent per interrupt:");
|
||||
DP_PRINT_STATS("Single Packet: %u",
|
||||
|
|
|
|||
|
|
@ -4900,6 +4900,7 @@ more_data:
|
|||
!tx_desc->flags)) {
|
||||
dp_info_rl("Descriptor freed in vdev_detach %d",
|
||||
tx_desc_id);
|
||||
DP_STATS_INC(soc, tx.tx_comp_exception, 1);
|
||||
continue;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2015-2020 The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2015-2021 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
|
||||
|
|
@ -29,6 +29,8 @@
|
|||
#include "dp_internal.h"
|
||||
#define INVALID_FLOW_ID 0xFF
|
||||
#define MAX_INVALID_BIN 3
|
||||
#define GLOBAL_FLOW_POOL_STATS_LEN 25
|
||||
#define FLOW_POOL_LOG_LEN 50
|
||||
|
||||
#ifdef QCA_AC_BASED_FLOW_CONTROL
|
||||
/**
|
||||
|
|
@ -222,6 +224,46 @@ void dp_tx_dump_flow_pool_info(struct cdp_soc_t *soc_hdl)
|
|||
qdf_spin_unlock_bh(&soc->flow_pool_array_lock);
|
||||
}
|
||||
|
||||
void dp_tx_dump_flow_pool_info_compact(struct dp_soc *soc)
|
||||
{
|
||||
struct dp_txrx_pool_stats *pool_stats = &soc->pool_stats;
|
||||
struct dp_tx_desc_pool_s *pool = NULL;
|
||||
char *comb_log_str;
|
||||
uint32_t comb_log_str_size;
|
||||
int bytes_written = 0;
|
||||
int i;
|
||||
|
||||
comb_log_str_size = GLOBAL_FLOW_POOL_STATS_LEN +
|
||||
(FLOW_POOL_LOG_LEN * MAX_TXDESC_POOLS) + 1;
|
||||
comb_log_str = qdf_mem_malloc(comb_log_str_size);
|
||||
if (!comb_log_str)
|
||||
return;
|
||||
|
||||
bytes_written = qdf_snprintf(&comb_log_str[bytes_written],
|
||||
comb_log_str_size, "G:(%d,%d,%d) ",
|
||||
pool_stats->pool_map_count,
|
||||
pool_stats->pool_unmap_count,
|
||||
pool_stats->pkt_drop_no_pool);
|
||||
|
||||
for (i = 0; i < MAX_TXDESC_POOLS; i++) {
|
||||
pool = &soc->tx_desc[i];
|
||||
if (pool->status > FLOW_POOL_INVALID)
|
||||
continue;
|
||||
bytes_written += qdf_snprintf(&comb_log_str[bytes_written],
|
||||
(bytes_written >= comb_log_str_size) ? 0 :
|
||||
comb_log_str_size - bytes_written,
|
||||
"| %d %d: (%d,%d,%d)",
|
||||
pool->flow_pool_id, pool->status,
|
||||
pool->pool_size, pool->avail_desc,
|
||||
pool->pkt_drop_no_desc);
|
||||
}
|
||||
|
||||
QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_INFO_HIGH,
|
||||
"FLOW_POOL_STATS %s", comb_log_str);
|
||||
|
||||
qdf_mem_free(comb_log_str);
|
||||
}
|
||||
|
||||
/**
|
||||
* dp_tx_clear_flow_pool_stats() - clear flow pool statistics
|
||||
*
|
||||
|
|
|
|||
|
|
@ -911,6 +911,8 @@ struct dp_soc_stats {
|
|||
uint32_t tx_comp_loop_pkt_limit_hit;
|
||||
/* Head pointer Out of sync at the end of dp_tx_comp_handler */
|
||||
uint32_t hp_oos2;
|
||||
/* tx desc freed as part of vdev detach */
|
||||
uint32_t tx_comp_exception;
|
||||
} tx;
|
||||
|
||||
/* SOC level RX stats */
|
||||
|
|
|
|||
|
|
@ -1067,8 +1067,8 @@ enum qdf_dp_tx_rx_status qdf_dp_get_status_from_a_status(uint8_t status)
|
|||
|
||||
void qdf_trace_display(void);
|
||||
|
||||
void __printf(3, 4) qdf_snprintf(char *str_buffer, unsigned int size,
|
||||
char *str_format, ...);
|
||||
int __printf(3, 4) qdf_snprintf(char *str_buffer, unsigned int size,
|
||||
char *str_format, ...);
|
||||
|
||||
#define QDF_SNPRINTF qdf_snprintf
|
||||
|
||||
|
|
|
|||
|
|
@ -110,11 +110,18 @@ static tp_qdf_dp_trace_cb qdf_dp_trace_cb_table[QDF_DP_TRACE_MAX + 1];
|
|||
* string contains printf-like replacement parameters, which follow
|
||||
* this parameter in the variable argument list.
|
||||
*
|
||||
* Return: None
|
||||
* Return: num of bytes written to buffer
|
||||
*/
|
||||
void qdf_snprintf(char *str_buffer, unsigned int size, char *str_format, ...)
|
||||
int qdf_snprintf(char *str_buffer, unsigned int size, char *str_format, ...)
|
||||
{
|
||||
snprintf(str_buffer, size, str_format);
|
||||
va_list args;
|
||||
int i;
|
||||
|
||||
va_start(args, str_format);
|
||||
i = vsnprintf(str_buffer, size, str_format, args);
|
||||
va_end(args);
|
||||
|
||||
return i;
|
||||
}
|
||||
qdf_export_symbol(qdf_snprintf);
|
||||
|
||||
|
|
|
|||
|
|
@ -97,11 +97,10 @@ static bool vdev_mgr_is_opmode_sap_or_p2p_go(enum QDF_OPMODE op_mode)
|
|||
return (op_mode == QDF_SAP_MODE || op_mode == QDF_P2P_GO_MODE);
|
||||
}
|
||||
|
||||
static bool vdev_mgr_is_49G_5G_6G_chan_freq(uint16_t chan_freq)
|
||||
static bool vdev_mgr_is_49G_5G_chan_freq(uint16_t chan_freq)
|
||||
{
|
||||
return WLAN_REG_IS_5GHZ_CH_FREQ(chan_freq) ||
|
||||
WLAN_REG_IS_49GHZ_FREQ(chan_freq) ||
|
||||
WLAN_REG_IS_6GHZ_CHAN_FREQ(chan_freq);
|
||||
WLAN_REG_IS_49GHZ_FREQ(chan_freq);
|
||||
}
|
||||
#else
|
||||
static inline bool vdev_mgr_is_opmode_sap_or_p2p_go(enum QDF_OPMODE op_mode)
|
||||
|
|
@ -109,7 +108,7 @@ static inline bool vdev_mgr_is_opmode_sap_or_p2p_go(enum QDF_OPMODE op_mode)
|
|||
return true;
|
||||
}
|
||||
|
||||
static inline bool vdev_mgr_is_49G_5G_6G_chan_freq(uint16_t chan_freq)
|
||||
static inline bool vdev_mgr_is_49G_5G_chan_freq(uint16_t chan_freq)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
|
@ -151,7 +150,7 @@ static QDF_STATUS vdev_mgr_start_param_update(
|
|||
|
||||
op_mode = wlan_vdev_mlme_get_opmode(vdev);
|
||||
if (vdev_mgr_is_opmode_sap_or_p2p_go(op_mode) &&
|
||||
vdev_mgr_is_49G_5G_6G_chan_freq(des_chan->ch_freq)) {
|
||||
vdev_mgr_is_49G_5G_chan_freq(des_chan->ch_freq)) {
|
||||
tgt_dfs_set_current_channel_for_freq(pdev, des_chan->ch_freq,
|
||||
des_chan->ch_flags,
|
||||
des_chan->ch_flagext,
|
||||
|
|
|
|||
60
umac/thermal/dispatcher/inc/wlan_thermal_public_struct.h
Normal file
60
umac/thermal/dispatcher/inc/wlan_thermal_public_struct.h
Normal file
|
|
@ -0,0 +1,60 @@
|
|||
/* Copyright (c) 2020-2021, 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
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/**
|
||||
* DOC: declare the thermal public structure
|
||||
*/
|
||||
#ifndef _WLAN_THERMAL_PUBLIC_STRUCT_H_
|
||||
#define _WLAN_THERMAL_PUBLIC_STRUCT_H_
|
||||
|
||||
/**
|
||||
* enum thermal_throttle_level - firmware offload throttle level
|
||||
* @THERMAL_FULLPERF: no any throtting
|
||||
* @THERMAL_MITIGATION: throtting tx to do mitigation
|
||||
* @THERMAL_SHUTOFF: shut down the tx completely
|
||||
* @THERMAL_UNKNOWN: unknown level from target.
|
||||
*/
|
||||
enum thermal_throttle_level {
|
||||
THERMAL_FULLPERF,
|
||||
THERMAL_MITIGATION,
|
||||
THERMAL_SHUTOFF,
|
||||
THERMAL_UNKNOWN,
|
||||
};
|
||||
|
||||
enum thermal_stats_request_type {
|
||||
thermal_stats_none = 0,
|
||||
thermal_stats_init,
|
||||
thermal_stats_req,
|
||||
thermal_stats_clear,
|
||||
thermal_stats_current_all_sensors_temp,
|
||||
};
|
||||
|
||||
/**
|
||||
* thermal_throt_level_stats - thermal throttle info from Target
|
||||
* @start_temp_level: Start temperature range to capture thermal stats
|
||||
* @end_temp_level: End temperature range to capture thermal stats
|
||||
* @total_time_ms_lo: Start time for every thermal stats level in msec
|
||||
* @total_time_ms_hi: End time for every thermal stats level in msec
|
||||
* @num_entry: Thermal stats counter for every time temp level for this range
|
||||
*/
|
||||
struct thermal_throt_level_stats {
|
||||
uint32_t start_temp_level;
|
||||
uint32_t end_temp_level;
|
||||
uint32_t total_time_ms_lo;
|
||||
uint32_t total_time_ms_hi;
|
||||
uint32_t num_entry;
|
||||
};
|
||||
|
||||
#endif /* _WLAN_THERMAL_PUBLIC_STRUCT_H_ */
|
||||
|
|
@ -32,6 +32,7 @@
|
|||
#include "wlan_mgmt_txrx_utils_api.h"
|
||||
#include <wlan_dfs_public_struct.h>
|
||||
#include <wlan_crypto_global_def.h>
|
||||
#include "wlan_thermal_public_struct.h"
|
||||
#ifdef WLAN_POWER_MANAGEMENT_OFFLOAD
|
||||
#include "wmi_unified_pmo_api.h"
|
||||
#endif
|
||||
|
|
@ -2965,13 +2966,19 @@ wmi_extract_chan_stats(wmi_unified_t wmi_handle, void *evt_buf,
|
|||
* @wmi_handle: wmi handle
|
||||
* @evt_buf: Pointer to event buffer
|
||||
* @temp: Pointer to hold extracted temperature
|
||||
* @level: Pointer to hold extracted level
|
||||
* @level: Pointer to hold extracted level in host enum
|
||||
* @therm_throt_levels: Pointer to hold extracted number of level in thermal
|
||||
* stats
|
||||
* @tt_lvl_stats_event: Pointer to hold extracted thermal stats for each level
|
||||
* @pdev_id: Pointer to hold extracted pdev_id
|
||||
*
|
||||
* Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure
|
||||
*/
|
||||
QDF_STATUS wmi_extract_thermal_stats(wmi_unified_t wmi_handle, void *evt_buf,
|
||||
uint32_t *temp, uint32_t *level,
|
||||
uint32_t *temp,
|
||||
enum thermal_throttle_level *level,
|
||||
uint32_t *therm_throt_levels,
|
||||
struct thermal_throt_level_stats *tt_stats,
|
||||
uint32_t *pdev_id);
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2019-2020 The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2019-2021 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
|
||||
|
|
@ -87,4 +87,20 @@ wmi_unified_send_dscp_tip_map_cmd(struct wmi_unified *wmi_handle,
|
|||
}
|
||||
#endif /* WLAN_SEND_DSCP_UP_MAP_TO_FW */
|
||||
|
||||
/**
|
||||
* wmi_unified_send_get_thermal_stats_cmd() - Send WMI get thermal stats req
|
||||
* @wmi_handle: wmi handle
|
||||
* @req_type: Request type
|
||||
* @temp_offset: temperature offset for setting the range for thermal stats
|
||||
|
||||
* Send WMI get thermal stats req command to firmware.
|
||||
*
|
||||
* Return: QDF_STATUS
|
||||
*/
|
||||
#ifdef THERMAL_STATS_SUPPORT
|
||||
QDF_STATUS
|
||||
wmi_unified_send_get_thermal_stats_cmd(struct wmi_unified *wmi_handle,
|
||||
enum thermal_stats_request_type req_type,
|
||||
uint8_t temp_offset);
|
||||
#endif /* THERMAL_STATS_SUPPORT */
|
||||
#endif /* _WMI_UNIFIED_FWOL_API_H_ */
|
||||
|
|
|
|||
|
|
@ -5257,6 +5257,9 @@ typedef enum {
|
|||
#ifdef FEATURE_WLAN_TDLS
|
||||
wmi_service_tdls_ax_support,
|
||||
#endif
|
||||
#endif
|
||||
#ifdef THERMAL_STATS_SUPPORT
|
||||
wmi_service_thermal_stats_temp_range_supported,
|
||||
#endif
|
||||
wmi_services_max,
|
||||
} wmi_conv_service_ids;
|
||||
|
|
|
|||
|
|
@ -1796,7 +1796,10 @@ QDF_STATUS (*extract_mib_stats)(wmi_unified_t wmi_handle, void *evt_buf,
|
|||
#endif
|
||||
|
||||
QDF_STATUS (*extract_thermal_stats)(wmi_unified_t wmi_handle, void *evt_buf,
|
||||
uint32_t *temp, uint32_t *level, uint32_t *pdev_id);
|
||||
uint32_t *temp, enum thermal_throttle_level *level,
|
||||
uint32_t *therm_throt_levels,
|
||||
struct thermal_throt_level_stats *tt_temp_range_stats_event,
|
||||
uint32_t *pdev_id);
|
||||
|
||||
QDF_STATUS (*extract_thermal_level_stats)(wmi_unified_t wmi_handle,
|
||||
void *evt_buf, uint8_t idx, uint32_t *levelcount,
|
||||
|
|
@ -2416,6 +2419,12 @@ QDF_STATUS (*send_dscp_tid_map_cmd)(wmi_unified_t wmi_handle,
|
|||
uint32_t *dscp_to_tid_map);
|
||||
#endif
|
||||
|
||||
#ifdef THERMAL_STATS_SUPPORT
|
||||
QDF_STATUS (*send_get_thermal_stats_cmd)(wmi_unified_t wmi_handle,
|
||||
enum thermal_stats_request_type req,
|
||||
uint8_t temp_offset);
|
||||
#endif /* THERMAL_STATS_SUPPORT */
|
||||
|
||||
QDF_STATUS (*send_pdev_get_pn_cmd)(wmi_unified_t wmi_handle,
|
||||
struct peer_request_pn_param *pn_params);
|
||||
QDF_STATUS (*extract_get_pn_data)(wmi_unified_t wmi_handle,
|
||||
|
|
|
|||
|
|
@ -2225,12 +2225,16 @@ wmi_extract_chan_stats(wmi_unified_t wmi_handle, void *evt_buf,
|
|||
}
|
||||
|
||||
QDF_STATUS wmi_extract_thermal_stats(wmi_unified_t wmi_handle, void *evt_buf,
|
||||
uint32_t *temp, uint32_t *level,
|
||||
uint32_t *temp,
|
||||
enum thermal_throttle_level *level,
|
||||
uint32_t *therm_throt_levels,
|
||||
struct thermal_throt_level_stats *tt_stats,
|
||||
uint32_t *pdev_id)
|
||||
{
|
||||
if (wmi_handle->ops->extract_thermal_stats)
|
||||
return wmi_handle->ops->extract_thermal_stats(wmi_handle,
|
||||
evt_buf, temp, level, pdev_id);
|
||||
evt_buf, temp, level, therm_throt_levels,
|
||||
tt_stats, pdev_id);
|
||||
|
||||
return QDF_STATUS_E_FAILURE;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2019-2020 The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2019-2021 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
|
||||
|
|
@ -71,3 +71,18 @@ wmi_unified_send_dscp_tip_map_cmd(struct wmi_unified *wmi_handle,
|
|||
return QDF_STATUS_E_FAILURE;
|
||||
}
|
||||
#endif /* WLAN_SEND_DSCP_UP_MAP_TO_FW */
|
||||
|
||||
#ifdef THERMAL_STATS_SUPPORT
|
||||
QDF_STATUS
|
||||
wmi_unified_send_get_thermal_stats_cmd(struct wmi_unified *wmi_handle,
|
||||
enum thermal_stats_request_type req_type,
|
||||
uint8_t temp_offset)
|
||||
{
|
||||
if (wmi_handle->ops->send_get_thermal_stats_cmd)
|
||||
return wmi_handle->ops->send_get_thermal_stats_cmd(wmi_handle,
|
||||
req_type,
|
||||
temp_offset);
|
||||
|
||||
return QDF_STATUS_E_FAILURE;
|
||||
}
|
||||
#endif /* THERMAL_STATS_SUPPORT */
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2019-2020 The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2019-2021 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
|
||||
|
|
@ -207,11 +207,65 @@ static void wmi_fwol_attach_dscp_tid_tlv(struct wmi_ops *ops)
|
|||
}
|
||||
#endif /* WLAN_SEND_DSCP_UP_MAP_TO_FW */
|
||||
|
||||
#ifdef THERMAL_STATS_SUPPORT
|
||||
/**
|
||||
* send_get_thermal_stats_cmd_tlv() - send get thermal stats cmd to fw
|
||||
* @wmi_handle: wmi handle
|
||||
* @req_type: req type
|
||||
* @temp_offset: temperature offset
|
||||
*
|
||||
* Send WMI_REQUEST_THERMAL_STATS_CMDID to fw.
|
||||
*
|
||||
* Return: QDF_STATUS
|
||||
*/
|
||||
static QDF_STATUS
|
||||
send_get_thermal_stats_cmd_tlv(wmi_unified_t wmi_handle,
|
||||
enum thermal_stats_request_type req_type,
|
||||
uint8_t temp_offset)
|
||||
{
|
||||
wmi_buf_t buf;
|
||||
wmi_thermal_stats_cmd_fixed_param *cmd;
|
||||
uint16_t len = sizeof(*cmd);
|
||||
QDF_STATUS ret;
|
||||
|
||||
buf = wmi_buf_alloc(wmi_handle, len);
|
||||
if (!buf) {
|
||||
wmi_err("Failed to allocate wmi buffer");
|
||||
return QDF_STATUS_E_NOMEM;
|
||||
}
|
||||
|
||||
cmd = (wmi_thermal_stats_cmd_fixed_param *)wmi_buf_data(buf);
|
||||
WMITLV_SET_HDR(&cmd->tlv_header,
|
||||
WMITLV_TAG_STRUC_wmi_thermal_stats_cmd_fixed_param,
|
||||
WMITLV_GET_STRUCT_TLVLEN
|
||||
(wmi_thermal_stats_cmd_fixed_param));
|
||||
cmd->thermal_action = req_type;
|
||||
cmd->thermal_offset = temp_offset;
|
||||
ret = wmi_unified_cmd_send(wmi_handle, buf, len,
|
||||
WMI_REQUEST_THERMAL_STATS_CMDID);
|
||||
if (QDF_IS_STATUS_ERROR(ret)) {
|
||||
wmi_err("Failed to send get thermal stats cmd = %d", ret);
|
||||
wmi_buf_free(buf);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void wmi_fwol_attach_thermal_stats_tlv(struct wmi_ops *ops)
|
||||
{
|
||||
ops->send_get_thermal_stats_cmd = send_get_thermal_stats_cmd_tlv;
|
||||
}
|
||||
#else
|
||||
static void wmi_fwol_attach_thermal_stats_tlv(struct wmi_ops *ops)
|
||||
{
|
||||
}
|
||||
#endif /* THERMAL_STATS_SUPPORT */
|
||||
|
||||
void wmi_fwol_attach_tlv(wmi_unified_t wmi_handle)
|
||||
{
|
||||
struct wmi_ops *ops = wmi_handle->ops;
|
||||
|
||||
wmi_fwol_attach_elna_tlv(ops);
|
||||
wmi_fwol_attach_dscp_tid_tlv(ops);
|
||||
|
||||
wmi_fwol_attach_thermal_stats_tlv(ops);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11457,19 +11457,97 @@ static QDF_STATUS extract_scan_radio_cap_service_ready_ext2_tlv(
|
|||
return QDF_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* wmi_tgt_thermal_level_to_host() - Convert target thermal level to host enum
|
||||
* @level: target thermal level from WMI_THERM_THROT_STATS_EVENTID event
|
||||
*
|
||||
* Return: host thermal throt level
|
||||
*/
|
||||
static enum thermal_throttle_level
|
||||
wmi_tgt_thermal_level_to_host(uint32_t level)
|
||||
{
|
||||
switch (level) {
|
||||
case WMI_THERMAL_FULLPERF:
|
||||
return THERMAL_FULLPERF;
|
||||
case WMI_THERMAL_MITIGATION:
|
||||
return THERMAL_MITIGATION;
|
||||
case WMI_THERMAL_SHUTOFF:
|
||||
return THERMAL_SHUTOFF;
|
||||
default:
|
||||
return THERMAL_UNKNOWN;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef THERMAL_STATS_SUPPORT
|
||||
static void
|
||||
populate_thermal_stats(WMI_THERM_THROT_STATS_EVENTID_param_tlvs *param_buf,
|
||||
uint32_t *therm_throt_levels,
|
||||
struct thermal_throt_level_stats *tt_temp_range_stats)
|
||||
{
|
||||
uint8_t lvl_idx;
|
||||
wmi_therm_throt_stats_event_fixed_param *tt_stats_event;
|
||||
wmi_thermal_throt_temp_range_stats *wmi_tt_stats;
|
||||
|
||||
tt_stats_event = param_buf->fixed_param;
|
||||
*therm_throt_levels = (tt_stats_event->therm_throt_levels >
|
||||
WMI_THERMAL_STATS_TEMP_THRESH_LEVEL_MAX) ?
|
||||
WMI_THERMAL_STATS_TEMP_THRESH_LEVEL_MAX :
|
||||
tt_stats_event->therm_throt_levels;
|
||||
|
||||
wmi_tt_stats = param_buf->temp_range_stats;
|
||||
if (!wmi_tt_stats) {
|
||||
wmi_err("wmi_tt_stats Null");
|
||||
return;
|
||||
}
|
||||
|
||||
for (lvl_idx = 0; lvl_idx < *therm_throt_levels; lvl_idx++) {
|
||||
tt_temp_range_stats[lvl_idx].start_temp_level =
|
||||
wmi_tt_stats[lvl_idx].start_temp_level;
|
||||
tt_temp_range_stats[lvl_idx].end_temp_level =
|
||||
wmi_tt_stats[lvl_idx].end_temp_level;
|
||||
tt_temp_range_stats[lvl_idx].total_time_ms_lo =
|
||||
wmi_tt_stats[lvl_idx].total_time_ms_lo;
|
||||
tt_temp_range_stats[lvl_idx].total_time_ms_hi =
|
||||
wmi_tt_stats[lvl_idx].total_time_ms_hi;
|
||||
tt_temp_range_stats[lvl_idx].num_entry =
|
||||
wmi_tt_stats[lvl_idx].num_entry;
|
||||
wmi_debug("level %d, start temp %d, end temp %d, total time low %d, total time high %d, counter %d",
|
||||
lvl_idx, wmi_tt_stats[lvl_idx].start_temp_level,
|
||||
wmi_tt_stats[lvl_idx].end_temp_level,
|
||||
wmi_tt_stats[lvl_idx].total_time_ms_lo,
|
||||
wmi_tt_stats[lvl_idx].total_time_ms_hi,
|
||||
wmi_tt_stats[lvl_idx].num_entry);
|
||||
}
|
||||
}
|
||||
#else
|
||||
static void
|
||||
populate_thermal_stats(WMI_THERM_THROT_STATS_EVENTID_param_tlvs *param_buf,
|
||||
uint32_t *therm_throt_levels,
|
||||
struct thermal_throt_level_stats *tt_temp_range_stats)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* extract_thermal_stats_tlv() - extract thermal stats from event
|
||||
* @wmi_handle: wmi handle
|
||||
* @param evt_buf: Pointer to event buffer
|
||||
* @param temp: Pointer to hold extracted temperature
|
||||
* @param level: Pointer to hold extracted level
|
||||
* @param level: Pointer to hold extracted level in host enum
|
||||
* @param therm_throt_levels: Pointer to hold extracted thermal throttle temp
|
||||
* range
|
||||
* @param tt_temp_range_stats_event: Pointer to hold extracted thermal stats for
|
||||
* every level
|
||||
*
|
||||
* Return: 0 for success or error code
|
||||
*/
|
||||
static QDF_STATUS
|
||||
extract_thermal_stats_tlv(wmi_unified_t wmi_handle,
|
||||
void *evt_buf, uint32_t *temp,
|
||||
uint32_t *level, uint32_t *pdev_id)
|
||||
enum thermal_throttle_level *level,
|
||||
uint32_t *therm_throt_levels,
|
||||
struct thermal_throt_level_stats *tt_temp_range_stats_event,
|
||||
uint32_t *pdev_id)
|
||||
{
|
||||
WMI_THERM_THROT_STATS_EVENTID_param_tlvs *param_buf;
|
||||
wmi_therm_throt_stats_event_fixed_param *tt_stats_event;
|
||||
|
|
@ -11480,12 +11558,17 @@ extract_thermal_stats_tlv(wmi_unified_t wmi_handle,
|
|||
return QDF_STATUS_E_INVAL;
|
||||
|
||||
tt_stats_event = param_buf->fixed_param;
|
||||
|
||||
wmi_debug("thermal temperature %d level %d",
|
||||
tt_stats_event->temp, tt_stats_event->level);
|
||||
*pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host(
|
||||
wmi_handle,
|
||||
tt_stats_event->pdev_id);
|
||||
*temp = tt_stats_event->temp;
|
||||
*level = tt_stats_event->level;
|
||||
*level = wmi_tgt_thermal_level_to_host(tt_stats_event->level);
|
||||
|
||||
if (tt_stats_event->therm_throt_levels)
|
||||
populate_thermal_stats(param_buf, therm_throt_levels,
|
||||
tt_temp_range_stats_event);
|
||||
|
||||
return QDF_STATUS_SUCCESS;
|
||||
}
|
||||
|
|
@ -15762,6 +15845,10 @@ static void populate_tlv_service(uint32_t *wmi_service)
|
|||
#endif
|
||||
wmi_service[wmi_service_ampdu_tx_buf_size_256_support] =
|
||||
WMI_SERVICE_AMPDU_TX_BUF_SIZE_256_SUPPORT;
|
||||
#ifdef THERMAL_STATS_SUPPORT
|
||||
wmi_service[wmi_service_thermal_stats_temp_range_supported] =
|
||||
WMI_SERVICE_THERMAL_THROT_STATS_TEMP_RANGE_SUPPORT;
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
Loading…
Reference in a new issue