Explorar el Código

qcacmn: Add support for Thermal Stats Events

Add support for extracting Thermal Stats Events
from thermal event TLV for FW event
WMI_THERM_THROT_STATS_EVENTID.

Also, added support for FW Cmd to request for
Thermal Stats: WMI_REQUEST_THERMAL_STATS_CMDID

Change-Id: I2bc80d082bda45e2255371bcb0c31d35d9806525
CRs-Fixed: 3016845
Utkarsh Bhatnagar hace 3 años
padre
commit
b7ab2f5cd7

+ 25 - 1
umac/thermal/dispatcher/inc/wlan_thermal_public_struct.h

@@ -1,4 +1,4 @@
-/* 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 above
@@ -35,4 +35,28 @@ enum thermal_throttle_level {
 	 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_ */

+ 5 - 0
wmi/inc/wmi_unified_api.h

@@ -3017,6 +3017,9 @@ wmi_extract_chan_stats(wmi_unified_t wmi_handle, void *evt_buf,
  * @evt_buf: Pointer to event buffer
  * @temp: Pointer to hold extracted temperature
  * @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
@@ -3024,6 +3027,8 @@ 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,
 				     enum thermal_throttle_level *level,
+				     uint32_t *therm_throt_levels,
+				     struct thermal_throt_level_stats *tt_stats,
 				     uint32_t *pdev_id);
 
 /**

+ 17 - 0
wmi/inc/wmi_unified_fwol_api.h

@@ -102,4 +102,21 @@ wmi_unified_send_set_mdns_config_cmd(struct wmi_unified *wmi_handle,
 				     struct mdns_config_info *mdns_info);
 #endif /* WLAN_FEATURE_MDNS_OFFLOAD */
 
+/**
+ * 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_ */

+ 3 - 0
wmi/inc/wmi_unified_param.h

@@ -5287,6 +5287,9 @@ typedef enum {
 	wmi_service_aoa_for_rcc_supported,
 #ifdef WLAN_FEATURE_P2P_P2P_STA
 	wmi_service_p2p_p2p_cc_support,
+#endif
+#ifdef THERMAL_STATS_SUPPORT
+	wmi_service_thermal_stats_temp_range_supported,
 #endif
 	wmi_services_max,
 } wmi_conv_service_ids;

+ 10 - 1
wmi/inc/wmi_unified_priv.h

@@ -1897,7 +1897,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, enum thermal_throttle_level *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,
@@ -2504,6 +2507,12 @@ QDF_STATUS (*send_set_mdns_config_cmd)(wmi_unified_t wmi_handle,
 				       struct mdns_config_info *mdns_info);
 #endif /* WLAN_FEATURE_MDNS_OFFLOAD */
 
+#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,

+ 4 - 1
wmi/src/wmi_unified_api.c

@@ -2282,11 +2282,14 @@ 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,
 				     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;
 }

+ 15 - 0
wmi/src/wmi_unified_fwol_api.c

@@ -84,3 +84,18 @@ wmi_unified_send_set_mdns_config_cmd(struct wmi_unified *wmi_handle,
 	return QDF_STATUS_E_FAILURE;
 }
 #endif /* WLAN_FEATURE_MDNS_OFFLOAD */
+
+#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 */

+ 55 - 1
wmi/src/wmi_unified_fwol_tlv.c

@@ -427,6 +427,60 @@ static void wmi_fwol_attach_mdns_tlv(struct wmi_ops *ops)
 }
 #endif /* WLAN_FEATURE_MDNS_OFFLOAD */
 
+#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 /* FW_THERMAL_THROTTLE_SUPPORT */
+
 void wmi_fwol_attach_tlv(wmi_unified_t wmi_handle)
 {
 	struct wmi_ops *ops = wmi_handle->ops;
@@ -434,5 +488,5 @@ void wmi_fwol_attach_tlv(wmi_unified_t wmi_handle)
 	wmi_fwol_attach_elna_tlv(ops);
 	wmi_fwol_attach_dscp_tid_tlv(ops);
 	wmi_fwol_attach_mdns_tlv(ops);
-
+	wmi_fwol_attach_thermal_stats_tlv(ops);
 }

+ 66 - 1
wmi/src/wmi_unified_tlv.c

@@ -12078,19 +12078,76 @@ wmi_tgt_thermal_level_to_host(uint32_t level)
 	}
 }
 
+#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 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,
-		enum thermal_throttle_level *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;
@@ -12109,6 +12166,10 @@ extract_thermal_stats_tlv(wmi_unified_t wmi_handle,
 	*temp = tt_stats_event->temp;
 	*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;
 }
 
@@ -17123,6 +17184,10 @@ static void populate_tlv_service(uint32_t *wmi_service)
 	wmi_service[wmi_service_p2p_p2p_cc_support] =
 			WMI_SERVICE_P2P_P2P_CONCURRENCY_SUPPORT;
 #endif
+#ifdef THERMAL_STATS_SUPPORT
+	wmi_service[wmi_service_thermal_stats_temp_range_supported] =
+			WMI_SERVICE_THERMAL_THROT_STATS_TEMP_RANGE_SUPPORT;
+#endif
 }
 
 /**