qcacld-3.0: Handle thermal stats event from target

Handle firmware thermal stats event and populate the thermal
information to upper layer with vendor command event.

Change-Id: I83286367ab542c08a205a7636f3d03189b0500e5
CRs-Fixed: 2786623
这个提交包含在:
Liangwei Dong
2020-09-18 14:00:42 +08:00
提交者 snandini
父节点 32c5130b24
当前提交 e8a9b19747
修改 11 个文件,包含 629 行新增19 行删除

查看文件

@@ -266,18 +266,32 @@ struct wlan_fwol_cfg {
bool enable_ilp;
};
/**
* struct wlan_fwol_thermal_throttle_info - FW offload thermal throttle info
* @level: thermal throttle level
*/
struct wlan_fwol_thermal_throttle_info {
enum thermal_throttle_level level;
};
/**
* struct wlan_fwol_psoc_obj - FW offload psoc priv object
* @cfg: cfg items
* @cbs: callback functions
* @tx_ops: tx operations for target interface
* @rx_ops: rx operations for target interface
* @thermal_throttle: cached target thermal stats information
* @thermal_cbs: thermal notification callbacks to hdd layer
*/
struct wlan_fwol_psoc_obj {
struct wlan_fwol_cfg cfg;
struct wlan_fwol_callbacks cbs;
struct wlan_fwol_tx_ops tx_ops;
struct wlan_fwol_rx_ops rx_ops;
#ifdef FW_THERMAL_THROTTLE_SUPPORT
struct wlan_fwol_thermal_throttle_info thermal_throttle;
struct fwol_thermal_callbacks thermal_cbs;
#endif
};
/**

查看文件

@@ -24,6 +24,7 @@
#define _WLAN_FWOL_PUBLIC_STRUCTS_H_
#include "wlan_objmgr_psoc_obj.h"
#include "wlan_thermal_public_struct.h"
#ifdef WLAN_FEATURE_ELNA
/**
@@ -70,6 +71,18 @@ struct wlan_fwol_callbacks {
#endif
};
/**
* struct thermal_throttle_info - thermal throttle info from Target
* @temperature: current temperature in c Degree
* @level: target thermal level info
* @pdev_id: pdev id
*/
struct thermal_throttle_info {
uint32_t temperature;
enum thermal_throttle_level level;
uint32_t pdev_id;
};
/**
* struct wlan_fwol_tx_ops - structure of tx func pointers
* @set_elna_bypass: set eLNA bypass
@@ -99,13 +112,29 @@ struct wlan_fwol_tx_ops {
/**
* struct wlan_fwol_rx_ops - structure of rx func pointers
* @get_elna_bypass_resp: get eLNA bypass response
* @notify_thermal_throttle_handler: thermal stats indication callback to fwol
* core from target if layer
*/
struct wlan_fwol_rx_ops {
#ifdef WLAN_FEATURE_ELNA
QDF_STATUS (*get_elna_bypass_resp)(struct wlan_objmgr_psoc *psoc,
struct get_elna_bypass_response *resp);
#endif
#ifdef FW_THERMAL_THROTTLE_SUPPORT
QDF_STATUS (*notify_thermal_throttle_handler)(
struct wlan_objmgr_psoc *psoc,
struct thermal_throttle_info *info);
#endif
};
/**
* struct fwol_thermal_callbacks - structure of rx callback to hdd layer
* @notify_thermal_throttle_handler: thermal throttle event callback
*/
struct fwol_thermal_callbacks {
QDF_STATUS (*notify_thermal_throttle_handler)(
struct wlan_objmgr_psoc *psoc,
struct thermal_throttle_info *info);
};
#endif /* _WLAN_FWOL_PUBLIC_STRUCTS_H_ */

查看文件

@@ -49,6 +49,22 @@ QDF_STATUS ucfg_fwol_psoc_open(struct wlan_objmgr_psoc *psoc);
*/
void ucfg_fwol_psoc_close(struct wlan_objmgr_psoc *psoc);
/**
* ucfg_fwol_psoc_enable() - FWOL component enable
* @psoc: pointer to psoc object
*
* Return: QDF Status
*/
QDF_STATUS ucfg_fwol_psoc_enable(struct wlan_objmgr_psoc *psoc);
/**
* ucfg_fwol_psoc_close() - FWOL component disable
* @psoc: pointer to psoc object
*
* Return: None
*/
void ucfg_fwol_psoc_disable(struct wlan_objmgr_psoc *psoc);
/**
* ucfg_fwol_init() - initialize fwol_ctx context.
*
@@ -67,6 +83,66 @@ QDF_STATUS ucfg_fwol_init(void);
*/
void ucfg_fwol_deinit(void);
#ifdef FW_THERMAL_THROTTLE_SUPPORT
/**
* ucfg_fwol_thermal_register_callbacks() - Register thermal callbacks
* to be called by fwol thermal
* @psoc: psoc object
* @cb: callback functions
*
* Currently only one callback notify_thermal_throttle_handler can be
* registered to fwol thermal core. The client will be notified by the callback
* when new thermal throttle level is changed in target.
*
* Return: QDF_STATUS
*/
QDF_STATUS ucfg_fwol_thermal_register_callbacks(
struct wlan_objmgr_psoc *psoc,
struct fwol_thermal_callbacks *cb);
/**
* ucfg_fwol_thermal_unregister_callbacks() - unregister thermal callbacks
* @psoc: psoc object
*
* Return: QDF_STATUS
*/
QDF_STATUS ucfg_fwol_thermal_unregister_callbacks(
struct wlan_objmgr_psoc *psoc);
/**
* ucfg_fwol_thermal_get_target_level() - get thermal level based on cached
* target thermal throttle level
* @psoc: psoc object
* @level: target thermal throttle level info
*
* Return: QDF_STATUS
*/
QDF_STATUS
ucfg_fwol_thermal_get_target_level(struct wlan_objmgr_psoc *psoc,
enum thermal_throttle_level *level);
#else
static inline QDF_STATUS ucfg_fwol_thermal_register_callbacks(
struct wlan_objmgr_psoc *psoc,
struct fwol_thermal_callbacks *cb)
{
return QDF_STATUS_SUCCESS;
}
static inline QDF_STATUS ucfg_fwol_thermal_unregister_callbacks(
struct wlan_objmgr_psoc *psoc)
{
return QDF_STATUS_SUCCESS;
}
static inline QDF_STATUS
ucfg_fwol_thermal_get_target_level(struct wlan_objmgr_psoc *psoc,
enum thermal_throttle_level *level)
{
return QDF_STATUS_E_FAILURE;
}
#endif
/**
* ucfg_fwol_get_coex_config_params() - Get coex config params
* @psoc: Pointer to psoc object
@@ -614,6 +690,15 @@ static inline void ucfg_fwol_psoc_close(struct wlan_objmgr_psoc *psoc)
{
}
static inline QDF_STATUS ucfg_fwol_psoc_enable(struct wlan_objmgr_psoc *psoc)
{
return QDF_STATUS_SUCCESS;
}
static inline void ucfg_fwol_psoc_disable(struct wlan_objmgr_psoc *psoc)
{
}
static inline QDF_STATUS ucfg_fwol_init(void)
{
return QDF_STATUS_SUCCESS;
@@ -623,6 +708,26 @@ static inline void ucfg_fwol_deinit(void)
{
}
static inline QDF_STATUS ucfg_fwol_thermal_register_callbacks(
struct wlan_objmgr_psoc *psoc,
struct fwol_thermal_callbacks *cb)
{
return QDF_STATUS_SUCCESS;
}
static inline QDF_STATUS ucfg_fwol_thermal_unregister_callbacks(
struct wlan_objmgr_psoc *psoc)
{
return QDF_STATUS_SUCCESS;
}
static inline QDF_STATUS
ucfg_fwol_thermal_get_target_level(struct wlan_objmgr_psoc *psoc,
enum thermal_throttle_level *level)
{
return QDF_STATUS_E_FAILURE;
}
static inline QDF_STATUS
ucfg_fwol_get_coex_config_params(struct wlan_objmgr_psoc *psoc,
struct wlan_fwol_coex_config *coex_config)

查看文件

@@ -166,9 +166,61 @@ static void tgt_fwol_register_elna_rx_ops(struct wlan_fwol_rx_ops *rx_ops)
}
#endif /* WLAN_FEATURE_ELNA */
#ifdef FW_THERMAL_THROTTLE_SUPPORT
/**
* notify_thermal_throttle_handler() - Thermal throttle stats event handler
* @psoc: psoc object
* @info: thermal throttle stats info from target if layer
*
* The handle will be registered to target if layer. Target if layer
* will notify the new level from firmware thermal stats event.
*
* Return: QDF_STATUS_SUCCESS for success
*/
static QDF_STATUS
notify_thermal_throttle_handler(struct wlan_objmgr_psoc *psoc,
struct thermal_throttle_info *info)
{
struct wlan_fwol_psoc_obj *fwol_obj;
QDF_STATUS status = QDF_STATUS_E_FAILURE;
struct fwol_thermal_callbacks *thermal_cbs;
if (!psoc) {
fwol_err("NULL psoc handle");
return QDF_STATUS_E_INVAL;
}
fwol_obj = fwol_get_psoc_obj(psoc);
if (!fwol_obj) {
fwol_err("Failed to get FWOL Obj");
return QDF_STATUS_E_INVAL;
}
thermal_cbs = &fwol_obj->thermal_cbs;
fwol_obj->thermal_throttle.level = info->level;
if (thermal_cbs->notify_thermal_throttle_handler)
status = thermal_cbs->notify_thermal_throttle_handler(psoc,
info);
else
fwol_debug("no thermal throttle handler");
return status;
}
static void tgt_fwol_register_thermal_rx_ops(struct wlan_fwol_rx_ops *rx_ops)
{
rx_ops->notify_thermal_throttle_handler =
notify_thermal_throttle_handler;
}
#else
static void tgt_fwol_register_thermal_rx_ops(struct wlan_fwol_rx_ops *rx_ops)
{
}
#endif
QDF_STATUS tgt_fwol_register_rx_ops(struct wlan_fwol_rx_ops *rx_ops)
{
tgt_fwol_register_elna_rx_ops(rx_ops);
tgt_fwol_register_thermal_rx_ops(rx_ops);
return QDF_STATUS_SUCCESS;
}

查看文件

@@ -34,15 +34,23 @@ QDF_STATUS ucfg_fwol_psoc_open(struct wlan_objmgr_psoc *psoc)
if (QDF_IS_STATUS_ERROR(status))
fwol_err("Failed to initialize FWOL CFG");
tgt_fwol_register_ev_handler(psoc);
return status;
}
void ucfg_fwol_psoc_close(struct wlan_objmgr_psoc *psoc)
{
/* Clear the FWOL CFG Structure */
}
QDF_STATUS ucfg_fwol_psoc_enable(struct wlan_objmgr_psoc *psoc)
{
tgt_fwol_register_ev_handler(psoc);
return QDF_STATUS_SUCCESS;
}
void ucfg_fwol_psoc_disable(struct wlan_objmgr_psoc *psoc)
{
tgt_fwol_unregister_ev_handler(psoc);
}
@@ -160,6 +168,55 @@ void ucfg_fwol_deinit(void)
fwol_err("unable to unregister psoc create handle");
}
#ifdef FW_THERMAL_THROTTLE_SUPPORT
QDF_STATUS ucfg_fwol_thermal_register_callbacks(
struct wlan_objmgr_psoc *psoc,
struct fwol_thermal_callbacks *cb)
{
struct wlan_fwol_psoc_obj *fwol_obj;
fwol_obj = fwol_get_psoc_obj(psoc);
if (!fwol_obj) {
fwol_err("Failed to get fwol obj");
return QDF_STATUS_E_FAILURE;
}
fwol_obj->thermal_cbs = *cb;
return QDF_STATUS_SUCCESS;
}
QDF_STATUS ucfg_fwol_thermal_unregister_callbacks(
struct wlan_objmgr_psoc *psoc)
{
struct wlan_fwol_psoc_obj *fwol_obj;
fwol_obj = fwol_get_psoc_obj(psoc);
if (!fwol_obj) {
fwol_err("Failed to get fwol obj");
return QDF_STATUS_E_FAILURE;
}
qdf_mem_zero(&fwol_obj->thermal_cbs, sizeof(fwol_obj->thermal_cbs));
return QDF_STATUS_SUCCESS;
}
QDF_STATUS
ucfg_fwol_thermal_get_target_level(struct wlan_objmgr_psoc *psoc,
enum thermal_throttle_level *level)
{
struct wlan_fwol_psoc_obj *fwol_obj;
fwol_obj = fwol_get_psoc_obj(psoc);
if (!fwol_obj) {
fwol_err("Failed to get fwol obj");
return QDF_STATUS_E_FAILURE;
}
*level = fwol_obj->thermal_throttle.level;
return QDF_STATUS_SUCCESS;
}
#endif
QDF_STATUS
ucfg_fwol_get_coex_config_params(struct wlan_objmgr_psoc *psoc,
struct wlan_fwol_coex_config *coex_config)

查看文件

@@ -240,10 +240,143 @@ target_if_fwol_register_dscp_up_tx_ops(struct wlan_fwol_tx_ops *tx_ops)
}
#endif
#ifdef FW_THERMAL_THROTTLE_SUPPORT
/**
* target_if_fwol_thermal_throttle_event_handler() - handler for thermal
* throttle event
* @scn: scn handle
* @event_buf: pointer to the event buffer
* @len: length of the buffer
*
* Return: 0 on success
*/
static int
target_if_fwol_thermal_throttle_event_handler(ol_scn_t scn, uint8_t *event_buf,
uint32_t len)
{
QDF_STATUS status;
struct thermal_throttle_info info = {0};
struct wlan_objmgr_psoc *psoc;
wmi_unified_t wmi_handle;
struct wlan_fwol_psoc_obj *fwol_obj;
struct wlan_fwol_rx_ops *rx_ops;
target_if_debug("scn:%pK, data:%pK, datalen:%d", scn, event_buf, len);
if (!scn || !event_buf) {
target_if_err("scn: 0x%pK, data: 0x%pK", scn, event_buf);
return -EINVAL;
}
psoc = target_if_get_psoc_from_scn_hdl(scn);
if (!psoc) {
target_if_err("null psoc");
return -EINVAL;
}
wmi_handle = get_wmi_unified_hdl_from_psoc(psoc);
if (!wmi_handle) {
target_if_err("Invalid wmi_handle");
return -EINVAL;
}
fwol_obj = fwol_get_psoc_obj(psoc);
if (!fwol_obj) {
target_if_err("Failed to get FWOL Obj");
return -EINVAL;
}
rx_ops = &fwol_obj->rx_ops;
if (rx_ops->notify_thermal_throttle_handler) {
status = wmi_extract_thermal_stats(wmi_handle,
event_buf,
&info.temperature,
&info.level,
&info.pdev_id);
if (QDF_IS_STATUS_ERROR(status) ||
info.level == THERMAL_UNKNOWN) {
target_if_debug("Failed to convert thermal target level");
return -EINVAL;
}
status = rx_ops->notify_thermal_throttle_handler(psoc, &info);
if (QDF_IS_STATUS_ERROR(status)) {
target_if_debug("notify thermal_throttle failed.");
return -EINVAL;
}
} else {
target_if_debug("No notify thermal_throttle callback");
return -EINVAL;
}
return 0;
};
/**
* target_if_fwol_register_thermal_throttle_handler() - Register handler for
* thermal throttle stats firmware event
* @psoc: psoc object
*
* Return: void
*/
static void
target_if_fwol_register_thermal_throttle_handler(struct wlan_objmgr_psoc *psoc)
{
QDF_STATUS status;
struct wlan_fwol_psoc_obj *fwol_obj;
fwol_obj = fwol_get_psoc_obj(psoc);
if (!fwol_obj) {
target_if_err("Failed to get FWOL Obj");
return;
}
if (!fwol_obj->cfg.thermal_temp_cfg.thermal_mitigation_enable) {
target_if_debug("thermal mitigation offload not enabled");
return;
}
status = wmi_unified_register_event(
get_wmi_unified_hdl_from_psoc(psoc),
wmi_tt_stats_event_id,
target_if_fwol_thermal_throttle_event_handler);
if (QDF_IS_STATUS_ERROR(status))
target_if_debug("Failed to register thermal stats event cb");
}
/**
* target_if_fwol_unregister_thermal_stats_handler() - Register handler for
* thermal throttle stats firmware event
* @psoc: psoc object
*
* Return: void
*/
static void
target_if_fwol_unregister_thermal_throttle_handler(
struct wlan_objmgr_psoc *psoc)
{
QDF_STATUS status;
status = wmi_unified_unregister_event_handler(
get_wmi_unified_hdl_from_psoc(psoc),
wmi_tt_stats_event_id);
if (QDF_IS_STATUS_ERROR(status))
target_if_debug("Failed to unregister thermal stats event cb");
}
#else
static void
target_if_fwol_register_thermal_throttle_handler(struct wlan_objmgr_psoc *psoc)
{
}
static void
target_if_fwol_unregister_thermal_throttle_handler(
struct wlan_objmgr_psoc *psoc)
{
}
#endif
QDF_STATUS target_if_fwol_register_event_handler(struct wlan_objmgr_psoc *psoc,
void *arg)
{
target_if_fwol_register_elna_event_handler(psoc, arg);
target_if_fwol_register_thermal_throttle_handler(psoc);
return QDF_STATUS_SUCCESS;
}
@@ -252,6 +385,7 @@ QDF_STATUS
target_if_fwol_unregister_event_handler(struct wlan_objmgr_psoc *psoc,
void *arg)
{
target_if_fwol_unregister_thermal_throttle_handler(psoc);
target_if_fwol_unregister_elna_event_handler(psoc, arg);
return QDF_STATUS_SUCCESS;