mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-06 03:45:24 -04:00
qcacld-3.0: Add support to get thermal throttle stats
Add support for sending WMI_REQUEST_THERMAL_STATS_CMDID to request for the thermal stats via vendor cmd: QCA_WLAN_VENDOR_ATTR_THERMAL_CMD_TYPE_GET_THERMAL_STATS This vendor cmd can either be used to clear the thermal stats or to request for the thermal stats. Added ini gThermalStatsTempOffset, which can configure thermal temperature offset value for capturing thermal stats in thermal range such as Thermal STATS starts capturing from temperature threshold to temperature threshold + offset. If this ini is set to 0, then the events are disabled. Also, add support for the FW event where the requested thermal stats are sent in FW event WMI_THERM_THROT_STATS_EVENTID(). The following attributes are sent in the events for every level: STATS_MIN_TEMPERATURE STATS_MAX_TEMPERATURE STATS_DWELL_TIME STATS_TEMP_LEVEL_COUNTER Change-Id: If8acdeec5bde33be346332ccaf39d78d0151203d CRs-Fixed: 3016818
This commit is contained in:
parent
149fdae30e
commit
1fba4f1b08
17 changed files with 879 additions and 22 deletions
1
Kbuild
1
Kbuild
|
|
@ -2603,6 +2603,7 @@ cppflags-y += -DANI_OS_TYPE_ANDROID=6 \
|
|||
-Werror\
|
||||
-D__linux__
|
||||
|
||||
cppflags-$(CONFIG_THERMAL_STATS_SUPPORT) += -DTHERMAL_STATS_SUPPORT
|
||||
cppflags-$(CONFIG_PTT_SOCK_SVC_ENABLE) += -DPTT_SOCK_SVC_ENABLE
|
||||
cppflags-$(CONFIG_FEATURE_WLAN_WAPI) += -DFEATURE_WLAN_WAPI
|
||||
cppflags-$(CONFIG_FEATURE_WLAN_WAPI) += -DATH_SUPPORT_WAPI
|
||||
|
|
|
|||
|
|
@ -51,10 +51,12 @@
|
|||
/**
|
||||
* enum wlan_fwol_southbound_event - fw offload south bound event type
|
||||
* @WLAN_FWOL_EVT_GET_ELNA_BYPASS_RESPONSE: get eLNA bypass response
|
||||
* @WLAN_FWOL_EVT_GET_THERMAL_STATS_RESPONSE: get Thermal Stats response
|
||||
*/
|
||||
enum wlan_fwol_southbound_event {
|
||||
WLAN_FWOL_EVT_INVALID = 0,
|
||||
WLAN_FWOL_EVT_GET_ELNA_BYPASS_RESPONSE,
|
||||
WLAN_FWOL_EVT_GET_THERMAL_STATS_RESPONSE,
|
||||
WLAN_FWOL_EVT_LAST,
|
||||
WLAN_FWOL_EVT_MAX = WLAN_FWOL_EVT_LAST - 1
|
||||
};
|
||||
|
|
@ -116,6 +118,7 @@ struct wlan_fwol_coex_config {
|
|||
* @priority_apps: Priority of the apps mitigation to consider by fw
|
||||
* @priority_wpps: Priority of the wpps mitigation to consider by fw
|
||||
* @thermal_action: thermal action as defined enum thermal_mgmt_action_code
|
||||
* @therm_stats_offset: thermal temp offset as set in gThermalStatsTempOffset
|
||||
*/
|
||||
struct wlan_fwol_thermal_temp {
|
||||
bool thermal_mitigation_enable;
|
||||
|
|
@ -128,6 +131,9 @@ struct wlan_fwol_thermal_temp {
|
|||
uint8_t priority_apps;
|
||||
uint8_t priority_wpps;
|
||||
enum thermal_mgmt_action_code thermal_action;
|
||||
#ifdef THERMAL_STATS_SUPPORT
|
||||
uint8_t therm_stats_offset;
|
||||
#endif
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
@ -275,18 +281,30 @@ struct wlan_fwol_cfg {
|
|||
bool disable_hw_assist;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct wlan_fwol_capability_info - FW offload capability component
|
||||
* @fw_thermal_stats_cap: Thermal Stats Fw capability
|
||||
**/
|
||||
struct wlan_fwol_capability_info {
|
||||
#ifdef THERMAL_STATS_SUPPORT
|
||||
bool fw_thermal_stats_cap;
|
||||
#endif
|
||||
};
|
||||
|
||||
/**
|
||||
* 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
|
||||
* @capability_info: fwol capability info
|
||||
*/
|
||||
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;
|
||||
struct wlan_fwol_capability_info capability_info;
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
@ -294,6 +312,7 @@ struct wlan_fwol_psoc_obj {
|
|||
* @psoc: psoc handle
|
||||
* @event_id: event ID
|
||||
* @get_elna_bypass_response: get eLNA bypass response
|
||||
* @get_thermal_stats_response: get thermal stats response
|
||||
*/
|
||||
struct wlan_fwol_rx_event {
|
||||
struct wlan_objmgr_psoc *psoc;
|
||||
|
|
@ -301,6 +320,9 @@ struct wlan_fwol_rx_event {
|
|||
union {
|
||||
#ifdef WLAN_FEATURE_ELNA
|
||||
struct get_elna_bypass_response get_elna_bypass_response;
|
||||
#endif
|
||||
#ifdef THERMAL_STATS_SUPPORT
|
||||
struct thermal_throttle_info get_thermal_stats_response;
|
||||
#endif
|
||||
};
|
||||
};
|
||||
|
|
|
|||
|
|
@ -111,6 +111,22 @@ fwol_init_coex_config_in_cfg(struct wlan_objmgr_psoc *psoc,
|
|||
CFG_BLE_SCAN_COEX_POLICY);
|
||||
}
|
||||
|
||||
#ifdef THERMAL_STATS_SUPPORT
|
||||
static void
|
||||
fwol_init_thermal_stats_in_cfg(struct wlan_objmgr_psoc *psoc,
|
||||
struct wlan_fwol_thermal_temp *thermal_temp)
|
||||
{
|
||||
thermal_temp->therm_stats_offset =
|
||||
cfg_get(psoc, CFG_THERMAL_STATS_TEMP_OFFSET);
|
||||
}
|
||||
#else
|
||||
static void
|
||||
fwol_init_thermal_stats_in_cfg(struct wlan_objmgr_psoc *psoc,
|
||||
struct wlan_fwol_thermal_temp *thermal_temp)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
||||
static void
|
||||
fwol_init_thermal_temp_in_cfg(struct wlan_objmgr_psoc *psoc,
|
||||
struct wlan_fwol_thermal_temp *thermal_temp)
|
||||
|
|
@ -155,7 +171,7 @@ fwol_init_thermal_temp_in_cfg(struct wlan_objmgr_psoc *psoc,
|
|||
cfg_get(psoc, CFG_THERMAL_WPPS_PRIOITY);
|
||||
thermal_temp->thermal_action =
|
||||
cfg_get(psoc, CFG_THERMAL_MGMT_ACTION);
|
||||
|
||||
fwol_init_thermal_stats_in_cfg(psoc, thermal_temp);
|
||||
}
|
||||
|
||||
QDF_STATUS fwol_init_neighbor_report_cfg(struct wlan_objmgr_psoc *psoc,
|
||||
|
|
@ -622,6 +638,59 @@ fwol_process_get_elna_bypass_resp(struct wlan_fwol_rx_event *event)
|
|||
}
|
||||
#endif /* WLAN_FEATURE_ELNA */
|
||||
|
||||
#ifdef THERMAL_STATS_SUPPORT
|
||||
/**
|
||||
* fwol_process_get_thermal_stats_resp() - Process get thermal stats response
|
||||
* @event: response event
|
||||
*
|
||||
* Return: QDF_STATUS_SUCCESS on success
|
||||
*/
|
||||
static QDF_STATUS
|
||||
fwol_process_get_thermal_stats_resp(struct wlan_fwol_rx_event *event)
|
||||
{
|
||||
QDF_STATUS status = QDF_STATUS_SUCCESS;
|
||||
struct wlan_objmgr_psoc *psoc;
|
||||
struct wlan_fwol_psoc_obj *fwol_obj;
|
||||
struct wlan_fwol_callbacks *cbs;
|
||||
struct thermal_throttle_info *resp;
|
||||
|
||||
if (!event) {
|
||||
fwol_err("Event buffer is NULL");
|
||||
return QDF_STATUS_E_FAILURE;
|
||||
}
|
||||
|
||||
psoc = event->psoc;
|
||||
if (!psoc) {
|
||||
fwol_err("psoc is NULL");
|
||||
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;
|
||||
}
|
||||
|
||||
cbs = &fwol_obj->cbs;
|
||||
if (cbs && cbs->get_thermal_stats_callback) {
|
||||
resp = &event->get_thermal_stats_response;
|
||||
cbs->get_thermal_stats_callback(cbs->get_thermal_stats_context,
|
||||
resp);
|
||||
} else {
|
||||
fwol_err("NULL pointer for callback");
|
||||
status = QDF_STATUS_E_IO;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
#else
|
||||
static QDF_STATUS
|
||||
fwol_process_get_thermal_stats_resp(struct wlan_fwol_rx_event *event)
|
||||
{
|
||||
return QDF_STATUS_E_NOSUPPORT;
|
||||
}
|
||||
#endif /* THERMAL_STATS_SUPPORT */
|
||||
|
||||
QDF_STATUS fwol_process_event(struct scheduler_msg *msg)
|
||||
{
|
||||
QDF_STATUS status;
|
||||
|
|
@ -641,6 +710,9 @@ QDF_STATUS fwol_process_event(struct scheduler_msg *msg)
|
|||
case WLAN_FWOL_EVT_GET_ELNA_BYPASS_RESPONSE:
|
||||
status = fwol_process_get_elna_bypass_resp(event);
|
||||
break;
|
||||
case WLAN_FWOL_EVT_GET_THERMAL_STATS_RESPONSE:
|
||||
status = fwol_process_get_thermal_stats_resp(event);
|
||||
break;
|
||||
default:
|
||||
status = QDF_STATUS_E_INVAL;
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2012-2018,2020 The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2012-2018,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
|
||||
|
|
@ -430,6 +430,31 @@
|
|||
CFG_VALUE_OR_DEFAULT, \
|
||||
"Thermal management action")
|
||||
|
||||
/* <ini>
|
||||
* gThermalStatsTempOffset - Configure the thermal stats offset
|
||||
*
|
||||
* @Min: 0
|
||||
* @Max: 10
|
||||
* @Default: 5
|
||||
*
|
||||
* This ini will configure Thermal temperature offset value for capturing
|
||||
* thermal stats in thermal range.
|
||||
* Thermal STATS start capturing from temperature threshold to temperature
|
||||
* threshold + offset.
|
||||
* If the value 0 is given then then thermal STATS capture is disabled
|
||||
*
|
||||
* Usage: External
|
||||
*
|
||||
* </ini>
|
||||
*/
|
||||
#define CFG_THERMAL_STATS_TEMP_OFFSET CFG_INI_UINT( \
|
||||
"gThermalStatsTempOffset", \
|
||||
0, \
|
||||
10, \
|
||||
5, \
|
||||
CFG_VALUE_OR_DEFAULT, \
|
||||
"Thermal Stats Temperature Offset")
|
||||
|
||||
#define CFG_THERMAL_TEMP_ALL \
|
||||
CFG(CFG_THERMAL_TEMP_MIN_LEVEL0) \
|
||||
CFG(CFG_THERMAL_TEMP_MAX_LEVEL0) \
|
||||
|
|
@ -450,6 +475,7 @@
|
|||
CFG(CFG_THERMAL_SAMPLING_TIME) \
|
||||
CFG(CFG_THERMAL_APPS_PRIORITY) \
|
||||
CFG(CFG_THERMAL_WPPS_PRIOITY) \
|
||||
CFG(CFG_THERMAL_MGMT_ACTION)
|
||||
CFG(CFG_THERMAL_MGMT_ACTION) \
|
||||
CFG(CFG_THERMAL_STATS_TEMP_OFFSET)
|
||||
#endif
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
@ -24,6 +24,8 @@
|
|||
#define _WLAN_FWOL_PUBLIC_STRUCTS_H_
|
||||
|
||||
#include "wlan_objmgr_psoc_obj.h"
|
||||
#include "wlan_thermal_public_struct.h"
|
||||
#include "wmi_unified.h"
|
||||
|
||||
#ifdef WLAN_FEATURE_ELNA
|
||||
/**
|
||||
|
|
@ -57,10 +59,28 @@ struct get_elna_bypass_response {
|
|||
};
|
||||
#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
|
||||
* @therm_throt_levels: Number of thermal throttle levels
|
||||
* @level_info: Thermal Stats for each level
|
||||
*/
|
||||
struct thermal_throttle_info {
|
||||
uint32_t temperature;
|
||||
enum thermal_throttle_level level;
|
||||
uint32_t pdev_id;
|
||||
uint32_t therm_throt_levels;
|
||||
struct thermal_throt_level_stats level_info[WMI_THERMAL_STATS_TEMP_THRESH_LEVEL_MAX];
|
||||
};
|
||||
|
||||
/**
|
||||
* struct wlan_fwol_callbacks - fw offload callbacks
|
||||
* @get_elna_bypass_callback: callback for get eLNA bypass
|
||||
* @get_elna_bypass_context: context for get eLNA bypass
|
||||
* @get_thermal_stats_callback: callback for get thermal stats
|
||||
* @get_thermal_stats_context: context for get thermal stats
|
||||
*/
|
||||
struct wlan_fwol_callbacks {
|
||||
#ifdef WLAN_FEATURE_ELNA
|
||||
|
|
@ -68,6 +88,11 @@ struct wlan_fwol_callbacks {
|
|||
struct get_elna_bypass_response *response);
|
||||
void *get_elna_bypass_context;
|
||||
#endif
|
||||
#ifdef THERMAL_STATS_SUPPORT
|
||||
void (*get_thermal_stats_callback)(void *context,
|
||||
struct thermal_throttle_info *response);
|
||||
void *get_thermal_stats_context;
|
||||
#endif
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
@ -77,6 +102,7 @@ struct wlan_fwol_callbacks {
|
|||
* @reg_evt_handler: register event handler
|
||||
* @unreg_evt_handler: unregister event handler
|
||||
* @send_dscp_up_map_to_fw: send dscp-to-up map values to FW
|
||||
* @get_thermal_stats: send get_thermal_stats cmd to FW
|
||||
*/
|
||||
struct wlan_fwol_tx_ops {
|
||||
#ifdef WLAN_FEATURE_ELNA
|
||||
|
|
@ -94,17 +120,27 @@ struct wlan_fwol_tx_ops {
|
|||
struct wlan_objmgr_psoc *psoc,
|
||||
uint32_t *dscp_to_up_map);
|
||||
#endif
|
||||
#ifdef THERMAL_STATS_SUPPORT
|
||||
QDF_STATUS (*get_thermal_stats)(struct wlan_objmgr_psoc *psoc,
|
||||
enum thermal_stats_request_type req_type,
|
||||
uint8_t therm_stats_offset);
|
||||
#endif
|
||||
};
|
||||
|
||||
/**
|
||||
* struct wlan_fwol_rx_ops - structure of rx func pointers
|
||||
* @get_elna_bypass_resp: get eLNA bypass response
|
||||
* @get_thermal_stats_resp: thermal stats cmd response callback to fwol
|
||||
*/
|
||||
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 THERMAL_STATS_SUPPORT
|
||||
QDF_STATUS (*get_thermal_stats_resp)(struct wlan_objmgr_psoc *psoc,
|
||||
struct thermal_throttle_info *resp);
|
||||
#endif
|
||||
};
|
||||
|
||||
#endif /* _WLAN_FWOL_PUBLIC_STRUCTS_H_ */
|
||||
|
|
|
|||
|
|
@ -608,6 +608,26 @@ QDF_STATUS ucfg_fwol_send_dscp_up_map_to_fw(
|
|||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* ucfg_fwol_update_fw_cap_info - API to update fwol capability info
|
||||
* @psoc: pointer to psoc object
|
||||
* @caps: pointer to wlan_fwol_capability_info struct
|
||||
*
|
||||
* Used to update fwol capability info.
|
||||
*
|
||||
* Return: void
|
||||
*/
|
||||
void ucfg_fwol_update_fw_cap_info(struct wlan_objmgr_psoc *psoc,
|
||||
struct wlan_fwol_capability_info *caps);
|
||||
|
||||
#ifdef THERMAL_STATS_SUPPORT
|
||||
QDF_STATUS ucfg_fwol_send_get_thermal_stats_cmd(struct wlan_objmgr_psoc *psoc,
|
||||
enum thermal_stats_request_type req_type,
|
||||
void (*callback)(void *context,
|
||||
struct thermal_throttle_info *response),
|
||||
void *context);
|
||||
#endif /* THERMAL_STATS_SUPPORT */
|
||||
|
||||
/**
|
||||
* ucfg_fwol_configure_global_params - API to configure global params
|
||||
* @psoc: pointer to psoc object
|
||||
|
|
|
|||
|
|
@ -166,9 +166,67 @@ static void tgt_fwol_register_elna_rx_ops(struct wlan_fwol_rx_ops *rx_ops)
|
|||
}
|
||||
#endif /* WLAN_FEATURE_ELNA */
|
||||
|
||||
#ifdef THERMAL_STATS_SUPPORT
|
||||
static QDF_STATUS
|
||||
tgt_fwol_get_thermal_stats_resp(struct wlan_objmgr_psoc *psoc,
|
||||
struct thermal_throttle_info *resp)
|
||||
{
|
||||
QDF_STATUS status;
|
||||
struct scheduler_msg msg = {0};
|
||||
struct wlan_fwol_rx_event *event;
|
||||
|
||||
event = qdf_mem_malloc(sizeof(*event));
|
||||
if (!event)
|
||||
return QDF_STATUS_E_NOMEM;
|
||||
|
||||
status = wlan_objmgr_psoc_try_get_ref(psoc, WLAN_FWOL_SB_ID);
|
||||
if (QDF_IS_STATUS_ERROR(status)) {
|
||||
fwol_err("Failed to get psoc ref");
|
||||
fwol_release_rx_event(event);
|
||||
return status;
|
||||
}
|
||||
|
||||
event->psoc = psoc;
|
||||
event->event_id = WLAN_FWOL_EVT_GET_THERMAL_STATS_RESPONSE;
|
||||
event->get_thermal_stats_response = *resp;
|
||||
msg.type = WLAN_FWOL_EVT_GET_THERMAL_STATS_RESPONSE;
|
||||
msg.bodyptr = event;
|
||||
msg.callback = fwol_process_event;
|
||||
msg.flush_callback = fwol_flush_callback;
|
||||
status = scheduler_post_message(QDF_MODULE_ID_FWOL,
|
||||
QDF_MODULE_ID_FWOL,
|
||||
QDF_MODULE_ID_TARGET_IF, &msg);
|
||||
|
||||
if (QDF_IS_STATUS_SUCCESS(status))
|
||||
return QDF_STATUS_SUCCESS;
|
||||
|
||||
fwol_err("failed to send WLAN_FWOL_EVT_GET_THERMAL_STATS_RESPONSE msg");
|
||||
fwol_flush_callback(&msg);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
static void
|
||||
tgt_fwol_register_thermal_stats_resp(struct wlan_fwol_rx_ops *rx_ops)
|
||||
{
|
||||
rx_ops->get_thermal_stats_resp = tgt_fwol_get_thermal_stats_resp;
|
||||
}
|
||||
#else
|
||||
static void
|
||||
tgt_fwol_register_thermal_stats_resp(struct wlan_fwol_rx_ops *rx_ops)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
||||
static void tgt_fwol_register_thermal_rx_ops(struct wlan_fwol_rx_ops *rx_ops)
|
||||
{
|
||||
tgt_fwol_register_thermal_stats_resp(rx_ops);
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1001,6 +1001,96 @@ QDF_STATUS ucfg_fwol_send_dscp_up_map_to_fw(struct wlan_objmgr_vdev *vdev,
|
|||
}
|
||||
#endif /* WLAN_SEND_DSCP_UP_MAP_TO_FW */
|
||||
|
||||
void ucfg_fwol_update_fw_cap_info(struct wlan_objmgr_psoc *psoc,
|
||||
struct wlan_fwol_capability_info *caps)
|
||||
{
|
||||
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_mem_copy(&fwol_obj->capability_info, caps,
|
||||
sizeof(fwol_obj->capability_info));
|
||||
}
|
||||
|
||||
#ifdef THERMAL_STATS_SUPPORT
|
||||
static QDF_STATUS
|
||||
ucfg_fwol_get_cap(struct wlan_objmgr_psoc *psoc,
|
||||
struct wlan_fwol_capability_info *cap_info)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
if (!cap_info) {
|
||||
fwol_err("Failed to get fwol obj");
|
||||
return QDF_STATUS_E_FAILURE;
|
||||
}
|
||||
*cap_info = fwol_obj->capability_info;
|
||||
|
||||
return QDF_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
QDF_STATUS ucfg_fwol_send_get_thermal_stats_cmd(struct wlan_objmgr_psoc *psoc,
|
||||
enum thermal_stats_request_type req_type,
|
||||
void (*callback)(void *context,
|
||||
struct thermal_throttle_info *response),
|
||||
void *context)
|
||||
{
|
||||
QDF_STATUS status;
|
||||
struct wlan_fwol_psoc_obj *fwol_obj;
|
||||
struct wlan_fwol_tx_ops *tx_ops;
|
||||
struct wlan_fwol_thermal_temp thermal_temp = {0};
|
||||
struct wlan_fwol_capability_info cap_info;
|
||||
struct wlan_fwol_callbacks *cbs;
|
||||
|
||||
fwol_obj = fwol_get_psoc_obj(psoc);
|
||||
if (!fwol_obj) {
|
||||
fwol_err("Failed to get FWOL Obj");
|
||||
return QDF_STATUS_E_INVAL;
|
||||
}
|
||||
|
||||
status = ucfg_fwol_get_thermal_temp(psoc, &thermal_temp);
|
||||
if (QDF_IS_STATUS_ERROR(status))
|
||||
return QDF_STATUS_E_INVAL;
|
||||
|
||||
status = ucfg_fwol_get_cap(psoc, &cap_info);
|
||||
if (QDF_IS_STATUS_ERROR(status))
|
||||
return QDF_STATUS_E_INVAL;
|
||||
|
||||
if (!thermal_temp.therm_stats_offset ||
|
||||
!cap_info.fw_thermal_stats_cap) {
|
||||
fwol_err("Command Disabled in Ini gThermalStatsTempOffset %d or not enabled in FW %d",
|
||||
thermal_temp.therm_stats_offset,
|
||||
cap_info.fw_thermal_stats_cap);
|
||||
return QDF_STATUS_E_INVAL;
|
||||
}
|
||||
|
||||
/* Registering Callback for the Request command */
|
||||
if (callback && context) {
|
||||
cbs = &fwol_obj->cbs;
|
||||
cbs->get_thermal_stats_callback = callback;
|
||||
cbs->get_thermal_stats_context = context;
|
||||
}
|
||||
|
||||
tx_ops = &fwol_obj->tx_ops;
|
||||
if (tx_ops && tx_ops->get_thermal_stats)
|
||||
status = tx_ops->get_thermal_stats(psoc, req_type,
|
||||
thermal_temp.therm_stats_offset);
|
||||
else
|
||||
status = QDF_STATUS_E_INVAL;
|
||||
|
||||
return status;
|
||||
}
|
||||
#endif /* THERMAL_STATS_SUPPORT */
|
||||
|
||||
QDF_STATUS ucfg_fwol_configure_global_params(struct wlan_objmgr_psoc *psoc,
|
||||
struct wlan_objmgr_pdev *pdev)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
@ -240,10 +240,203 @@ target_if_fwol_register_dscp_up_tx_ops(struct wlan_fwol_tx_ops *tx_ops)
|
|||
}
|
||||
#endif
|
||||
|
||||
#ifdef THERMAL_STATS_SUPPORT
|
||||
/**
|
||||
* target_if_fwol_get_thermal_stats() - send get thermal stats request to FW
|
||||
* @psoc: pointer to PSOC object
|
||||
* @req_type: get thermal stats request type
|
||||
* @therm_stats_offset: thermal temp stats offset for each temp range
|
||||
*
|
||||
* Return: QDF_STATUS_SUCCESS on success
|
||||
*/
|
||||
static QDF_STATUS
|
||||
target_if_fwol_get_thermal_stats(struct wlan_objmgr_psoc *psoc,
|
||||
enum thermal_stats_request_type req_type,
|
||||
uint8_t therm_stats_offset)
|
||||
{
|
||||
QDF_STATUS status;
|
||||
wmi_unified_t wmi_handle = get_wmi_unified_hdl_from_psoc(psoc);
|
||||
|
||||
if (!wmi_handle) {
|
||||
target_if_err("Invalid wmi_handle");
|
||||
return QDF_STATUS_E_INVAL;
|
||||
}
|
||||
|
||||
status = wmi_unified_send_get_thermal_stats_cmd(wmi_handle, req_type,
|
||||
therm_stats_offset);
|
||||
if (status)
|
||||
target_if_err("Failed to send get thermal stats cmd %d",
|
||||
status);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
static void
|
||||
target_if_fwol_register_thermal_stats_tx_ops(struct wlan_fwol_tx_ops *tx_ops)
|
||||
{
|
||||
tx_ops->get_thermal_stats = target_if_fwol_get_thermal_stats;
|
||||
}
|
||||
|
||||
static QDF_STATUS
|
||||
target_if_fwol_handle_thermal_lvl_stats_evt(struct wlan_objmgr_psoc *psoc,
|
||||
struct wlan_fwol_rx_ops *rx_ops,
|
||||
struct thermal_throttle_info *info)
|
||||
{
|
||||
QDF_STATUS status = QDF_STATUS_E_FAILURE;
|
||||
|
||||
if (rx_ops->get_thermal_stats_resp && info->therm_throt_levels)
|
||||
status = rx_ops->get_thermal_stats_resp(psoc, info);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
static bool
|
||||
target_if_fwol_is_thermal_stats_enable(struct wlan_fwol_psoc_obj *fwol_obj)
|
||||
{
|
||||
return (fwol_obj->capability_info.fw_thermal_stats_cap &&
|
||||
fwol_obj->cfg.thermal_temp_cfg.therm_stats_offset);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 = QDF_STATUS_E_FAILURE;
|
||||
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)
|
||||
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;
|
||||
}
|
||||
|
||||
status = wmi_extract_thermal_stats(wmi_handle,
|
||||
event_buf,
|
||||
&info.temperature,
|
||||
&info.level,
|
||||
&info.therm_throt_levels,
|
||||
info.level_info,
|
||||
&info.pdev_id);
|
||||
if (QDF_IS_STATUS_ERROR(status)) {
|
||||
target_if_debug("Failed to convert thermal target level");
|
||||
return -EINVAL;
|
||||
}
|
||||
rx_ops = &fwol_obj->rx_ops;
|
||||
if (!rx_ops) {
|
||||
target_if_debug("rx_ops Null");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
status = target_if_fwol_handle_thermal_lvl_stats_evt(psoc, rx_ops,
|
||||
&info);
|
||||
if (QDF_IS_STATUS_ERROR(status))
|
||||
target_if_debug("thermal stats level response failed.");
|
||||
|
||||
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 (!target_if_fwol_is_thermal_stats_enable(fwol_obj)) {
|
||||
target_if_debug("thermal stats offload not enabled");
|
||||
return;
|
||||
}
|
||||
status = wmi_unified_register_event_handler(
|
||||
get_wmi_unified_hdl_from_psoc(psoc),
|
||||
wmi_tt_stats_event_id,
|
||||
target_if_fwol_thermal_throttle_event_handler,
|
||||
WMI_RX_SERIALIZER_CTX);
|
||||
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)
|
||||
{
|
||||
}
|
||||
static void
|
||||
target_if_fwol_register_thermal_stats_tx_ops(struct wlan_fwol_tx_ops *tx_ops)
|
||||
{
|
||||
}
|
||||
#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;
|
||||
}
|
||||
|
|
@ -253,6 +446,7 @@ target_if_fwol_unregister_event_handler(struct wlan_objmgr_psoc *psoc,
|
|||
void *arg)
|
||||
{
|
||||
target_if_fwol_unregister_elna_event_handler(psoc, arg);
|
||||
target_if_fwol_unregister_thermal_throttle_handler(psoc);
|
||||
|
||||
return QDF_STATUS_SUCCESS;
|
||||
}
|
||||
|
|
@ -261,6 +455,7 @@ QDF_STATUS target_if_fwol_register_tx_ops(struct wlan_fwol_tx_ops *tx_ops)
|
|||
{
|
||||
target_if_fwol_register_elna_tx_ops(tx_ops);
|
||||
target_if_fwol_register_dscp_up_tx_ops(tx_ops);
|
||||
target_if_fwol_register_thermal_stats_tx_ops(tx_ops);
|
||||
|
||||
tx_ops->reg_evt_handler = target_if_fwol_register_event_handler;
|
||||
tx_ops->unreg_evt_handler = target_if_fwol_unregister_event_handler;
|
||||
|
|
|
|||
|
|
@ -207,6 +207,8 @@ CONFIG_QCOM_TDLS := y
|
|||
|
||||
CONFIG_WLAN_SYSFS := y
|
||||
|
||||
CONFIG_THERMAL_STATS_SUPPORT := y
|
||||
|
||||
ifeq ($(CONFIG_WLAN_SYSFS), y)
|
||||
CONFIG_WLAN_SYSFS_STA_INFO := y
|
||||
CONFIG_WLAN_SYSFS_CHANNEL := y
|
||||
|
|
|
|||
|
|
@ -2213,6 +2213,9 @@ struct hdd_context {
|
|||
qdf_work_t twt_en_dis_work;
|
||||
#endif
|
||||
bool dump_in_progress;
|
||||
#ifdef THERMAL_STATS_SUPPORT
|
||||
bool is_therm_stats_in_progress;
|
||||
#endif
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -196,6 +196,7 @@
|
|||
#include "wlan_cm_roam_ucfg_api.h"
|
||||
#include <cdp_txrx_ctrl.h>
|
||||
#include "qdf_lock.h"
|
||||
#include "wlan_hdd_thermal.h"
|
||||
|
||||
#ifdef MODULE
|
||||
#define WLAN_MODULE_NAME module_name(THIS_MODULE)
|
||||
|
|
@ -13887,6 +13888,17 @@ static int hdd_init_mws_coex(struct hdd_context *hdd_ctx)
|
|||
}
|
||||
#endif
|
||||
|
||||
#ifdef THERMAL_STATS_SUPPORT
|
||||
static void hdd_thermal_stats_cmd_init(struct hdd_context *hdd_ctx)
|
||||
{
|
||||
hdd_send_get_thermal_stats_cmd(hdd_ctx, thermal_stats_init, NULL, NULL);
|
||||
}
|
||||
#else
|
||||
static void hdd_thermal_stats_cmd_init(struct hdd_context *hdd_ctx)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* hdd_features_init() - Init features
|
||||
* @hdd_ctx: HDD context
|
||||
|
|
@ -14001,6 +14013,7 @@ static int hdd_features_init(struct hdd_context *hdd_ctx)
|
|||
wlan_cm_set_6ghz_key_mgmt_mask(hdd_ctx->psoc,
|
||||
ALLOWED_KEYMGMT_6G_MASK);
|
||||
}
|
||||
hdd_thermal_stats_cmd_init(hdd_ctx);
|
||||
|
||||
hdd_exit();
|
||||
return 0;
|
||||
|
|
|
|||
|
|
@ -36,8 +36,12 @@
|
|||
#include <qca_vendor.h>
|
||||
#include "wlan_fwol_ucfg_api.h"
|
||||
#include <pld_common.h>
|
||||
#include "os_if_fwol.h"
|
||||
#include "wlan_osif_request_manager.h"
|
||||
#include "wlan_fwol_public_structs.h"
|
||||
|
||||
#define DC_OFF_PERCENT_WPPS 50
|
||||
#define WLAN_WAIT_TIME_GET_THERM_LVL 1000
|
||||
|
||||
const struct nla_policy
|
||||
wlan_hdd_thermal_mitigation_policy
|
||||
|
|
@ -143,6 +147,223 @@ hdd_send_thermal_mitigation_val(struct hdd_context *hdd_ctx, uint32_t level,
|
|||
return QDF_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
#ifdef THERMAL_STATS_SUPPORT
|
||||
QDF_STATUS
|
||||
hdd_send_get_thermal_stats_cmd(struct hdd_context *hdd_ctx,
|
||||
enum thermal_stats_request_type request_type,
|
||||
void (*callback)(void *context,
|
||||
struct thermal_throttle_info *response),
|
||||
void *context)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (!hdd_ctx->psoc) {
|
||||
hdd_err_rl("NULL pointer for psoc");
|
||||
return QDF_STATUS_E_INVAL;
|
||||
}
|
||||
|
||||
|
||||
/* Send Get Thermal Stats cmd to FW */
|
||||
ret = os_if_fwol_get_thermal_stats_req(hdd_ctx->psoc, request_type,
|
||||
callback, context);
|
||||
if (ret)
|
||||
return QDF_STATUS_E_FAILURE;
|
||||
|
||||
return QDF_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* hdd_get_thermal_stats_cb() - Get thermal stats callback
|
||||
* @context: Call context
|
||||
* @response: Pointer to response structure
|
||||
*
|
||||
* Return: void
|
||||
*/
|
||||
static void
|
||||
hdd_get_thermal_stats_cb(void *context,
|
||||
struct thermal_throttle_info *response)
|
||||
{
|
||||
struct osif_request *request;
|
||||
struct thermal_throttle_info *priv;
|
||||
|
||||
request = osif_request_get(context);
|
||||
if (!request) {
|
||||
osif_err("Obsolete request");
|
||||
return;
|
||||
}
|
||||
|
||||
priv = osif_request_priv(request);
|
||||
qdf_mem_copy(priv, response, sizeof(struct thermal_throttle_info));
|
||||
|
||||
osif_request_complete(request);
|
||||
osif_request_put(request);
|
||||
}
|
||||
|
||||
#define THERMAL_MIN_TEMP QCA_WLAN_VENDOR_ATTR_THERMAL_STATS_MIN_TEMPERATURE
|
||||
#define THERMAL_MAX_TEMP QCA_WLAN_VENDOR_ATTR_THERMAL_STATS_MAX_TEMPERATURE
|
||||
#define THERMAL_DWELL_TIME QCA_WLAN_VENDOR_ATTR_THERMAL_STATS_DWELL_TIME
|
||||
#define THERMAL_LVL_COUNT QCA_WLAN_VENDOR_ATTR_THERMAL_STATS_TEMP_LEVEL_COUNTER
|
||||
|
||||
/**
|
||||
* hdd_get_curr_thermal_stats_val() - Indicate thermal stats
|
||||
* to upper layer when query vendor command
|
||||
* @wiphy: Pointer to wireless phy
|
||||
* @hdd_ctx: hdd context
|
||||
*
|
||||
* Return: 0 for success
|
||||
*/
|
||||
static int
|
||||
hdd_get_curr_thermal_stats_val(struct wiphy *wiphy,
|
||||
struct hdd_context *hdd_ctx)
|
||||
{
|
||||
int ret = 0;
|
||||
uint8_t i = 0;
|
||||
struct osif_request *request = NULL;
|
||||
int skb_len = 0;
|
||||
struct thermal_throttle_info *priv;
|
||||
struct thermal_throttle_info *get_tt_stats = NULL;
|
||||
struct sk_buff *skb = NULL;
|
||||
void *cookie;
|
||||
struct nlattr *therm_attr;
|
||||
struct nlattr *tt_levels;
|
||||
static const struct osif_request_params params = {
|
||||
.priv_size = sizeof(*priv),
|
||||
.timeout_ms = WLAN_WAIT_TIME_GET_THERM_LVL,
|
||||
.dealloc = NULL,
|
||||
};
|
||||
|
||||
if (hdd_ctx->is_therm_stats_in_progress) {
|
||||
hdd_err("request already in progress");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
request = osif_request_alloc(¶ms);
|
||||
if (!request) {
|
||||
hdd_err("request allocation failure");
|
||||
return -ENOMEM;
|
||||
}
|
||||
cookie = osif_request_cookie(request);
|
||||
hdd_ctx->is_therm_stats_in_progress = true;
|
||||
ret = hdd_send_get_thermal_stats_cmd(hdd_ctx, thermal_stats_req,
|
||||
hdd_get_thermal_stats_cb,
|
||||
cookie);
|
||||
if (QDF_IS_STATUS_ERROR(ret)) {
|
||||
hdd_err("Failure while sending command to fw");
|
||||
ret = -EAGAIN;
|
||||
goto completed;
|
||||
}
|
||||
|
||||
ret = osif_request_wait_for_response(request);
|
||||
if (ret) {
|
||||
hdd_err("Timed out while retrieving thermal stats");
|
||||
ret = -EAGAIN;
|
||||
goto completed;
|
||||
}
|
||||
|
||||
get_tt_stats = osif_request_priv(request);
|
||||
if (!get_tt_stats) {
|
||||
hdd_err("invalid get_tt_stats");
|
||||
ret = -EINVAL;
|
||||
goto completed;
|
||||
}
|
||||
|
||||
skb_len = NLMSG_HDRLEN + (get_tt_stats->therm_throt_levels) *
|
||||
(NLA_HDRLEN + (NLA_HDRLEN +
|
||||
sizeof(get_tt_stats->level_info[i].start_temp_level) +
|
||||
NLA_HDRLEN +
|
||||
sizeof(get_tt_stats->level_info[i].end_temp_level) +
|
||||
NLA_HDRLEN +
|
||||
sizeof(get_tt_stats->level_info[i].total_time_ms_lo) +
|
||||
NLA_HDRLEN +
|
||||
sizeof(get_tt_stats->level_info[i].num_entry)));
|
||||
|
||||
skb = wlan_cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
|
||||
skb_len);
|
||||
if (!skb) {
|
||||
hdd_err_rl("cfg80211_vendor_cmd_alloc_reply_skb failed");
|
||||
ret = -ENOMEM;
|
||||
goto completed;
|
||||
}
|
||||
|
||||
therm_attr = nla_nest_start(skb, QCA_WLAN_VENDOR_ATTR_THERMAL_STATS);
|
||||
if (!therm_attr) {
|
||||
hdd_err_rl("nla_nest_start failed for attr failed");
|
||||
ret = -EINVAL;
|
||||
goto completed;
|
||||
}
|
||||
|
||||
for (i = 0; i < get_tt_stats->therm_throt_levels; i++) {
|
||||
tt_levels = nla_nest_start(skb, i);
|
||||
if (!tt_levels) {
|
||||
hdd_err_rl("nla_nest_start failed for thermal level %d",
|
||||
i);
|
||||
ret = -EINVAL;
|
||||
goto completed;
|
||||
}
|
||||
|
||||
hdd_debug("level %d, Temp Range: %d - %d, Dwell time %d, Counter %d",
|
||||
i, get_tt_stats->level_info[i].start_temp_level,
|
||||
get_tt_stats->level_info[i].end_temp_level,
|
||||
get_tt_stats->level_info[i].total_time_ms_lo,
|
||||
get_tt_stats->level_info[i].num_entry);
|
||||
|
||||
if (nla_put_u32(skb, THERMAL_MIN_TEMP,
|
||||
get_tt_stats->level_info[i].start_temp_level) ||
|
||||
nla_put_u32(skb, THERMAL_MAX_TEMP,
|
||||
get_tt_stats->level_info[i].end_temp_level) ||
|
||||
nla_put_u32(skb, THERMAL_DWELL_TIME,
|
||||
(get_tt_stats->level_info[i].total_time_ms_lo)) ||
|
||||
nla_put_u32(skb, THERMAL_LVL_COUNT,
|
||||
get_tt_stats->level_info[i].num_entry)) {
|
||||
hdd_err("nla put failure");
|
||||
kfree_skb(skb);
|
||||
ret = -EINVAL;
|
||||
hdd_ctx->is_therm_stats_in_progress = false;
|
||||
break;
|
||||
}
|
||||
nla_nest_end(skb, tt_levels);
|
||||
}
|
||||
nla_nest_end(skb, therm_attr);
|
||||
wlan_cfg80211_vendor_cmd_reply(skb);
|
||||
|
||||
completed:
|
||||
hdd_ctx->is_therm_stats_in_progress = false;
|
||||
osif_request_put(request);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#undef THERMAL_MIN_TEMP
|
||||
#undef THERMAL_MAX_TEMP
|
||||
#undef THERMAL_DWELL_TIME
|
||||
#undef THERMAL_LVL_COUNT
|
||||
|
||||
static QDF_STATUS
|
||||
hdd_send_thermal_stats_clear_cmd(struct hdd_context *hdd_ctx)
|
||||
{
|
||||
QDF_STATUS status;
|
||||
|
||||
status = hdd_send_get_thermal_stats_cmd(hdd_ctx,
|
||||
thermal_stats_clear, NULL,
|
||||
NULL);
|
||||
|
||||
return status;
|
||||
}
|
||||
#else
|
||||
static int
|
||||
hdd_get_curr_thermal_stats_val(struct wiphy *wiphy,
|
||||
struct hdd_context *hdd_ctx)
|
||||
{
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
static QDF_STATUS
|
||||
hdd_send_thermal_stats_clear_cmd(struct hdd_context *hdd_ctx)
|
||||
{
|
||||
return QDF_STATUS_E_NOSUPPORT;
|
||||
}
|
||||
#endif /* THERMAL_STATS_SUPPORT */
|
||||
|
||||
/**
|
||||
* __wlan_hdd_cfg80211_set_thermal_mitigation_policy() - Set the thermal policy
|
||||
* @wiphy: Pointer to wireless phy
|
||||
|
|
@ -162,9 +383,14 @@ __wlan_hdd_cfg80211_set_thermal_mitigation_policy(struct wiphy *wiphy,
|
|||
struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_THERMAL_CMD_MAX + 1];
|
||||
uint32_t level, cmd_type;
|
||||
QDF_STATUS status;
|
||||
int ret;
|
||||
|
||||
hdd_enter();
|
||||
|
||||
ret = wlan_hdd_validate_context(hdd_ctx);
|
||||
if (ret)
|
||||
return -EINVAL;
|
||||
|
||||
if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
|
||||
hdd_err_rl("Command not allowed in FTM mode");
|
||||
return -EPERM;
|
||||
|
|
@ -184,23 +410,35 @@ __wlan_hdd_cfg80211_set_thermal_mitigation_policy(struct wiphy *wiphy,
|
|||
}
|
||||
|
||||
cmd_type = nla_get_u32(tb[QCA_WLAN_VENDOR_ATTR_THERMAL_CMD_VALUE]);
|
||||
if (cmd_type != QCA_WLAN_VENDOR_ATTR_THERMAL_CMD_TYPE_SET_LEVEL) {
|
||||
hdd_err_rl("invalid thermal cmd value");
|
||||
return -EINVAL;
|
||||
switch (cmd_type) {
|
||||
case QCA_WLAN_VENDOR_ATTR_THERMAL_CMD_TYPE_SET_LEVEL:
|
||||
if (!tb[QCA_WLAN_VENDOR_ATTR_THERMAL_LEVEL]) {
|
||||
hdd_err_rl("attr thermal throttle set failed");
|
||||
return -EINVAL;
|
||||
}
|
||||
level = nla_get_u32(tb[QCA_WLAN_VENDOR_ATTR_THERMAL_LEVEL]);
|
||||
|
||||
hdd_debug("thermal mitigation level from userspace %d", level);
|
||||
status = hdd_send_thermal_mitigation_val(hdd_ctx, level,
|
||||
THERMAL_MONITOR_APPS);
|
||||
ret = qdf_status_to_os_return(status);
|
||||
break;
|
||||
case QCA_WLAN_VENDOR_ATTR_THERMAL_CMD_TYPE_GET_THERMAL_STATS:
|
||||
ret = hdd_get_curr_thermal_stats_val(wiphy, hdd_ctx);
|
||||
break;
|
||||
case QCA_WLAN_VENDOR_ATTR_THERMAL_CMD_TYPE_CLEAR_THERMAL_STATS:
|
||||
status = hdd_send_thermal_stats_clear_cmd(hdd_ctx);
|
||||
if (QDF_IS_STATUS_ERROR(status)) {
|
||||
hdd_err("Failure while sending command to fw");
|
||||
ret = -EINVAL;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
ret = -EINVAL;
|
||||
}
|
||||
|
||||
if (!tb[QCA_WLAN_VENDOR_ATTR_THERMAL_LEVEL]) {
|
||||
hdd_err_rl("attr thermal throttle set failed");
|
||||
return -EINVAL;
|
||||
}
|
||||
level =
|
||||
nla_get_u32(tb[QCA_WLAN_VENDOR_ATTR_THERMAL_LEVEL]);
|
||||
|
||||
hdd_debug("thermal mitigation level from userspace %d", level);
|
||||
status = hdd_send_thermal_mitigation_val(hdd_ctx, level,
|
||||
THERMAL_MONITOR_APPS);
|
||||
hdd_exit();
|
||||
return qdf_status_to_os_return(status);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2020 The Linux Foundation. All rights reserved.
|
||||
* 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
|
||||
|
|
@ -195,4 +195,13 @@ int wlan_hdd_pld_set_thermal_mitigation(struct device *dev,
|
|||
}
|
||||
|
||||
#endif /* FEATURE_THERMAL_VENDOR_COMMANDS */
|
||||
|
||||
#ifdef THERMAL_STATS_SUPPORT
|
||||
QDF_STATUS
|
||||
hdd_send_get_thermal_stats_cmd(struct hdd_context *hdd_ctx,
|
||||
enum thermal_stats_request_type request_type,
|
||||
void (*callback)(void *context,
|
||||
struct thermal_throttle_info *response),
|
||||
void *context);
|
||||
#endif /* THERMAL_STATS_SUPPORT */
|
||||
#endif /* __HDD_THERMAL_H */
|
||||
|
|
|
|||
|
|
@ -114,6 +114,7 @@
|
|||
#endif
|
||||
|
||||
#include "wlan_pkt_capture_ucfg_api.h"
|
||||
#include "wlan_fwol_ucfg_api.h"
|
||||
|
||||
#define WMA_LOG_COMPLETION_TIMER 3000 /* 3 seconds */
|
||||
#define WMI_TLV_HEADROOM 128
|
||||
|
|
@ -5804,10 +5805,52 @@ static void wma_set_mlme_caps(struct wlan_objmgr_psoc *psoc)
|
|||
wma_err("Failed to set sae roam support");
|
||||
}
|
||||
|
||||
#ifdef THERMAL_STATS_SUPPORT
|
||||
static void wma_set_thermal_stats_fw_cap(tp_wma_handle wma,
|
||||
struct wlan_fwol_capability_info *cap)
|
||||
{
|
||||
cap->fw_thermal_stats_cap = wmi_service_enabled(wma->wmi_handle,
|
||||
wmi_service_thermal_stats_temp_range_supported);
|
||||
}
|
||||
#else
|
||||
static void wma_set_thermal_stats_fw_cap(tp_wma_handle wma,
|
||||
struct wlan_fwol_capability_info *cap)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* wma_set_fwol_caps() - Populate fwol component related capabilities
|
||||
* to the fwol component
|
||||
*
|
||||
* @psoc: Pointer to psoc object
|
||||
*
|
||||
* Return: None
|
||||
*/
|
||||
static void wma_set_fwol_caps(struct wlan_objmgr_psoc *psoc)
|
||||
{
|
||||
tp_wma_handle wma;
|
||||
struct wlan_fwol_capability_info cap_info;
|
||||
wma = cds_get_context(QDF_MODULE_ID_WMA);
|
||||
|
||||
if (!wma) {
|
||||
wma_err_rl("wma Null");
|
||||
return;
|
||||
}
|
||||
if (!psoc) {
|
||||
wma_err_rl("psoc Null");
|
||||
return;
|
||||
}
|
||||
|
||||
wma_set_thermal_stats_fw_cap(wma, &cap_info);
|
||||
ucfg_fwol_update_fw_cap_info(psoc, &cap_info);
|
||||
}
|
||||
|
||||
static void wma_set_component_caps(struct wlan_objmgr_psoc *psoc)
|
||||
{
|
||||
wma_set_pmo_caps(psoc);
|
||||
wma_set_mlme_caps(psoc);
|
||||
wma_set_fwol_caps(psoc);
|
||||
}
|
||||
|
||||
#if defined(WLAN_FEATURE_GTK_OFFLOAD) && defined(WLAN_POWER_MANAGEMENT_OFFLOAD)
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
@ -26,6 +26,7 @@
|
|||
#define __OS_IF_FWOL_H__
|
||||
|
||||
#include "wlan_objmgr_vdev_obj.h"
|
||||
#include "wlan_fwol_public_structs.h"
|
||||
|
||||
#ifdef WLAN_FEATURE_ELNA
|
||||
/**
|
||||
|
|
@ -82,4 +83,12 @@ static inline int os_if_fwol_send_dscp_up_map_to_fw(
|
|||
}
|
||||
#endif /* WLAN_SEND_DSCP_UP_MAP_TO_FW */
|
||||
|
||||
#ifdef THERMAL_STATS_SUPPORT
|
||||
int os_if_fwol_get_thermal_stats_req(struct wlan_objmgr_psoc *psoc,
|
||||
enum thermal_stats_request_type req,
|
||||
void (*callback)(void *context,
|
||||
struct thermal_throttle_info *response),
|
||||
void *context);
|
||||
#endif /* THERMAL_STATS_SUPPORT */
|
||||
|
||||
#endif /* __OS_IF_FWOL_H__ */
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
@ -145,3 +145,23 @@ int os_if_fwol_send_dscp_up_map_to_fw(struct wlan_objmgr_vdev *vdev,
|
|||
return qdf_status_to_os_return(status);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef THERMAL_STATS_SUPPORT
|
||||
int os_if_fwol_get_thermal_stats_req(struct wlan_objmgr_psoc *psoc,
|
||||
enum thermal_stats_request_type req,
|
||||
void (*callback)(void *context,
|
||||
struct thermal_throttle_info *response),
|
||||
void *context)
|
||||
{
|
||||
QDF_STATUS status;
|
||||
|
||||
|
||||
status = ucfg_fwol_send_get_thermal_stats_cmd(psoc, req, callback,
|
||||
context);
|
||||
if (!QDF_IS_STATUS_SUCCESS(status))
|
||||
osif_err("Failed to send get thermal stats cmd to FW, %d",
|
||||
status);
|
||||
|
||||
return qdf_status_to_os_return(status);
|
||||
}
|
||||
#endif
|
||||
|
|
|
|||
Loading…
Reference in a new issue