qcacld-3.0: Add FW Profiling support
Add Profiling stats support in HOST driver to
have CPU based profiling for critical data
path functions in FW.
Change-Id: Ib6d4f0b220f622cf304536c8e538d4dc34c6434b
CRs-Fixed: 921950
diff --git a/core/hdd/inc/qc_sap_ioctl.h b/core/hdd/inc/qc_sap_ioctl.h
index 5fee04f..6983a7a 100644
--- a/core/hdd/inc/qc_sap_ioctl.h
+++ b/core/hdd/inc/qc_sap_ioctl.h
@@ -147,6 +147,7 @@
/* Private ioctls and their sub-ioctls */
#define QCSAP_PRIV_GET_CHAR_SET_NONE (SIOCIWFIRSTPRIV + 13)
#define QCSAP_GET_STATS 1
+#define QCSAP_LIST_FW_PROFILE 2
#define QCSAP_IOCTL_CLR_STATS (SIOCIWFIRSTPRIV+14)
#define QCSAP_IOCTL_PRIV_SET_THREE_INT_GET_NONE (SIOCIWFIRSTPRIV+15)
@@ -171,6 +172,8 @@
#define QCSAP_IOCTL_SET_FW_CRASH_INJECT 1
#endif
#define QCSAP_IOCTL_DUMP_DP_TRACE_LEVEL 2
+#define QCSAP_ENABLE_FW_PROFILE 3
+#define QCSAP_SET_FW_PROFILE_HIST_INTVL 4
#define MAX_VAR_ARGS 7
#define QCSAP_IOCTL_PRIV_GET_SOFTAP_LINK_SPEED (SIOCIWFIRSTPRIV + 31)
@@ -237,6 +240,8 @@
QCASAP_DUMP_STATS,
QCASAP_CLEAR_STATS,
QCASAP_SET_RADAR_DBG,
+ QCSAP_GET_FW_PROFILE_DATA,
+ QCSAP_START_FW_PROFILING
};
int iw_softap_get_channel_list(struct net_device *dev,
diff --git a/core/hdd/inc/wlan_hdd_wext.h b/core/hdd/inc/wlan_hdd_wext.h
index 1f78e49..7bb8606 100644
--- a/core/hdd/inc/wlan_hdd_wext.h
+++ b/core/hdd/inc/wlan_hdd_wext.h
@@ -306,6 +306,8 @@
extern void hdd_wlan_get_stats(hdd_adapter_t *pAdapter, uint16_t *length,
char *buffer, uint16_t buf_len);
+extern void hdd_wlan_list_fw_profile(uint16_t *length,
+ char *buffer, uint16_t buf_len);
extern int iw_set_essid(struct net_device *dev,
struct iw_request_info *info,
diff --git a/core/hdd/src/wlan_hdd_hostapd.c b/core/hdd/src/wlan_hdd_hostapd.c
index c5b5955..ed01195 100644
--- a/core/hdd/src/wlan_hdd_hostapd.c
+++ b/core/hdd/src/wlan_hdd_hostapd.c
@@ -2032,29 +2032,36 @@
return ret;
}
+/**
+ * iw_softap_set_two_ints_getnone() - Generic "set two integer" ioctl handler
+ * @dev: device upon which the ioctl was received
+ * @info: ioctl request information
+ * @wrqu: ioctl request data
+ * @extra: ioctl extra data
+ *
+ * Return: 0 on success, non-zero on error
+ */
static int __iw_softap_set_two_ints_getnone(struct net_device *dev,
struct iw_request_info *info,
union iwreq_data *wrqu, char *extra)
{
- hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
- hdd_context_t *pHddCtx;
+ hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
+ int ret;
int *value = (int *)extra;
int sub_cmd = value[0];
- int ret = 0;
+ hdd_context_t *hdd_ctx;
- pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
- ret = wlan_hdd_validate_context(pHddCtx);
- if (ret != 0) {
- hddLog(LOGE, FL("HDD context is not valid!"));
+ hdd_ctx = WLAN_HDD_GET_CTX(adapter);
+ ret = wlan_hdd_validate_context(hdd_ctx);
+ if (ret != 0)
goto out;
- }
switch (sub_cmd) {
#ifdef DEBUG
case QCSAP_IOCTL_SET_FW_CRASH_INJECT:
hddLog(LOGE, "WE_SET_FW_CRASH_INJECT: %d %d",
value[1], value[2]);
- ret = wma_cli_set2_command(pAdapter->sessionId,
+ ret = wma_cli_set2_command(adapter->sessionId,
GEN_PARAM_CRASH_INJECT,
value[1], value[2],
GEN_CMD);
@@ -2066,6 +2073,19 @@
if (value[1] == DUMP_DP_TRACE)
cdf_dp_trace_dump_all(value[2]);
break;
+ case QCSAP_ENABLE_FW_PROFILE:
+ hddLog(LOG1, "QCSAP_ENABLE_FW_PROFILE: %d %d",
+ value[1], value[2]);
+ ret = wma_cli_set2_command(adapter->sessionId,
+ WMI_WLAN_PROFILE_ENABLE_PROFILE_ID_CMDID,
+ value[1], value[2], DBG_CMD);
+ break;
+ case QCSAP_SET_FW_PROFILE_HIST_INTVL:
+ hddLog(LOG1, "QCSAP_SET_FW_PROFILE_HIST_INTVL: %d %d",
+ value[1], value[2]);
+ ret = wma_cli_set2_command(adapter->sessionId,
+ WMI_WLAN_PROFILE_SET_HIST_INTVL_CMDID,
+ value[1], value[2], DBG_CMD);
default:
hddLog(LOGE, FL("Invalid IOCTL command %d"), sub_cmd);
break;
@@ -2793,6 +2813,12 @@
}
break;
}
+ case QCSAP_START_FW_PROFILING:
+ hddLog(LOG1, "QCSAP_START_FW_PROFILING %d", set_value);
+ ret = wma_cli_set_command(pHostapdAdapter->sessionId,
+ WMI_WLAN_PROFILE_TRIGGER_CMDID,
+ set_value, DBG_CMD);
+ break;
default:
hddLog(LOGE, FL("Invalid setparam command %d value %d"),
sub_cmd, set_value);
@@ -3007,6 +3033,12 @@
ret = wlan_hdd_get_temperature(pHostapdAdapter, value);
break;
}
+ case QCSAP_GET_FW_PROFILE_DATA:
+ hddLog(LOG1, "QCSAP_GET_FW_PROFILE_DATA");
+ ret = wma_cli_set_command(pHostapdAdapter->sessionId,
+ WMI_WLAN_PROFILE_GET_PROFILE_DATA_CMDID,
+ 0, DBG_CMD);
+ break;
default:
hddLog(LOGE, FL("Invalid getparam command %d"), sub_cmd);
ret = -EINVAL;
@@ -3415,31 +3447,44 @@
return ret;
}
+/**
+ * iw_get_char_setnone() - Generic "get char" private ioctl handler
+ * @dev: device upon which the ioctl was received
+ * @info: ioctl request information
+ * @wrqu: ioctl request data
+ * @extra: ioctl extra data
+ *
+ * Return: 0 on success, non-zero on error
+ */
static int __iw_get_char_setnone(struct net_device *dev,
struct iw_request_info *info,
union iwreq_data *wrqu, char *extra)
{
hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
- CDF_STATUS status;
+ int ret;
int sub_cmd = wrqu->data.flags;
hdd_context_t *hdd_ctx;
ENTER();
hdd_ctx = WLAN_HDD_GET_CTX(adapter);
- status = wlan_hdd_validate_context(hdd_ctx);
- if (status != 0)
- return status;
+ ret = wlan_hdd_validate_context(hdd_ctx);
+ if (ret != 0)
+ return ret;
switch (sub_cmd) {
case QCSAP_GET_STATS:
hdd_wlan_get_stats(adapter, &(wrqu->data.length),
extra, WE_MAX_STR_LEN);
break;
+ case QCSAP_LIST_FW_PROFILE:
+ hdd_wlan_list_fw_profile(&(wrqu->data.length),
+ extra, WE_MAX_STR_LEN);
+ break;
}
EXIT();
- return status;
+ return ret;
}
static int iw_get_char_setnone(struct net_device *dev,
@@ -5465,6 +5510,10 @@
IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
0, "clearStats"
}, {
+ QCSAP_START_FW_PROFILING,
+ IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
+ 0, "startProfile"
+ }, {
QCSAP_IOCTL_GETPARAM, 0,
IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getparam"
}, {
@@ -5530,6 +5579,9 @@
QCASAP_GET_TEMP_CMD, 0,
IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "get_temp"
}, {
+ QCSAP_GET_FW_PROFILE_DATA, 0,
+ IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getProfileData"
+ }, {
QCSAP_IOCTL_GET_STAWPAIE,
IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | 1, 0,
"get_staWPAIE"
@@ -5572,6 +5624,10 @@
IW_PRIV_TYPE_CHAR | WE_MAX_STR_LEN, "getStats"
}
, {
+ QCSAP_LIST_FW_PROFILE, 0,
+ IW_PRIV_TYPE_CHAR | WE_MAX_STR_LEN, "listProfile"
+ }
+ , {
QCSAP_IOCTL_PRIV_GET_SOFTAP_LINK_SPEED,
IW_PRIV_TYPE_CHAR | 18,
IW_PRIV_TYPE_CHAR | 5, "getLinkSpeed"
@@ -5677,6 +5733,17 @@
0, "dump_dp_trace"
}
,
+ {
+ QCSAP_ENABLE_FW_PROFILE,
+ IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2,
+ 0, "enableProfile"
+ }
+ ,
+ {
+ QCSAP_SET_FW_PROFILE_HIST_INTVL,
+ IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2,
+ 0, "set_hist_intvl"
+ }
};
static const iw_handler hostapd_private[] = {
diff --git a/core/hdd/src/wlan_hdd_wext.c b/core/hdd/src/wlan_hdd_wext.c
index 4e68ecb..047131f 100644
--- a/core/hdd/src/wlan_hdd_wext.c
+++ b/core/hdd/src/wlan_hdd_wext.c
@@ -213,6 +213,8 @@
#define WE_SET_CTS_CBW 84
#define WE_DUMP_STATS 85
#define WE_CLEAR_STATS 86
+/* Private sub ioctl for starting/stopping the profiling */
+#define WE_START_FW_PROFILE 87
/* Private ioctls and their sub-ioctls */
#define WLAN_PRIV_SET_NONE_GET_INT (SIOCIWFIRSTPRIV + 1)
@@ -314,6 +316,7 @@
#define WE_GET_OEM_DATA_CAP 13
#endif
#define WE_GET_SNR 14
+#define WE_LIST_FW_PROFILE 15
/* Private ioctls and their sub-ioctls */
#define WLAN_PRIV_SET_NONE_GET_NONE (SIOCIWFIRSTPRIV + 6)
@@ -328,6 +331,7 @@
#define WE_DUMP_PCIE_LOG 16
#endif
#define WE_GET_RECOVERY_STAT 17
+#define WE_GET_FW_PROFILE_DATA 18
/* Private ioctls and their sub-ioctls */
#define WLAN_PRIV_SET_VAR_INT_GET_NONE (SIOCIWFIRSTPRIV + 7)
@@ -424,6 +428,9 @@
#endif
#define WE_DUMP_DP_TRACE_LEVEL 3
#define DUMP_DP_TRACE 0
+/* Private sub ioctl for enabling and setting histogram interval of profiling */
+#define WE_ENABLE_FW_PROFILE 4
+#define WE_SET_FW_PROFILE_HIST_INTVL 5
/* (SIOCIWFIRSTPRIV + 29) is currently unused */
@@ -648,6 +655,41 @@
}
/**
+ * hdd_wlan_list_fw_profile() - Get fw profiling points
+ * @length: Size of the data copied
+ * @buffer: Pointer to char buffer.
+ * @buf_len: Length of the char buffer.
+ *
+ * This function called when the "iwpriv wlan0 listProfile" command is given.
+ * It is used to get the supported profiling points in FW.
+ *
+ * Return - none
+ */
+void hdd_wlan_list_fw_profile(uint16_t *length,
+ char *buffer, uint16_t buf_len)
+{
+ uint32_t len = 0;
+
+ len = scnprintf(buffer, buf_len,
+ "PROF_CPU_IDLE: %u\n"
+ "PROF_PPDU_PROC: %u\n"
+ "PROF_PPDU_POST: %u\n"
+ "PROF_HTT_TX_INPUT: %u\n"
+ "PROF_MSDU_ENQ: %u\n"
+ "PROF_PPDU_POST_HAL: %u\n"
+ "PROF_COMPUTE_TX_TIME: %u\n",
+ PROF_CPU_IDLE,
+ PROF_PPDU_PROC,
+ PROF_PPDU_POST,
+ PROF_HTT_TX_INPUT,
+ PROF_MSDU_ENQ,
+ PROF_PPDU_POST_HAL,
+ PROF_COMPUTE_TX_TIME);
+
+ *length = len + 1;
+}
+
+/**
* hdd_wlan_dump_stats() - display dump Stats
* @adapter: adapter handle
* @value: value from user
@@ -6072,6 +6114,14 @@
sme_set_scan_disable(WLAN_HDD_GET_HAL_CTX(pAdapter), set_value);
break;
}
+ case WE_START_FW_PROFILE:
+ {
+ hddLog(LOG1, "WE_START_FW_PROFILE %d", set_value);
+ ret = wma_cli_set_command(pAdapter->sessionId,
+ WMI_WLAN_PROFILE_TRIGGER_CMDID,
+ set_value, DBG_CMD);
+ break;
+ }
default:
{
hddLog(LOGE, "%s: Invalid sub command %d", __func__,
@@ -6896,6 +6946,11 @@
break;
}
+ case WE_LIST_FW_PROFILE:
+ hdd_wlan_list_fw_profile(&(wrqu->data.length),
+ extra, WE_MAX_STR_LEN);
+ break;
+
/* The case prints the current state of the HDD, SME, CSR, PE,
* TL it can be extended for WDI Global State as well. And
* currently it only checks P2P_CLIENT adapter. P2P_DEVICE
@@ -7409,6 +7464,12 @@
break;
}
+ case WE_GET_FW_PROFILE_DATA:
+ ret = wma_cli_set_command(pAdapter->sessionId,
+ WMI_WLAN_PROFILE_GET_PROFILE_DATA_CMDID,
+ 0, DBG_CMD);
+ break;
+
case WE_SET_REASSOC_TRIGGER:
{
hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
@@ -9431,6 +9492,20 @@
value[1], value[2], GEN_CMD);
break;
#endif
+ case WE_ENABLE_FW_PROFILE:
+ hddLog(LOGE, "WE_ENABLE_FW_PROFILE: %d %d",
+ value[1], value[2]);
+ ret = wma_cli_set2_command(pAdapter->sessionId,
+ WMI_WLAN_PROFILE_ENABLE_PROFILE_ID_CMDID,
+ value[1], value[2], DBG_CMD);
+ break;
+ case WE_SET_FW_PROFILE_HIST_INTVL:
+ hddLog(LOGE, "WE_SET_FW_PROFILE_HIST_INTVL: %d %d",
+ value[1], value[2]);
+ ret = wma_cli_set2_command(pAdapter->sessionId,
+ WMI_WLAN_PROFILE_SET_HIST_INTVL_CMDID,
+ value[1], value[2], DBG_CMD);
+ break;
case WE_SET_DUAL_MAC_FW_MODE_CONFIG:
hdd_debug("Ioctl to set dual fw mode config");
if (hdd_ctx->config->dual_mac_feature_disable) {
@@ -9986,6 +10061,10 @@
IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
0, "clearStats"},
+ {WE_START_FW_PROFILE,
+ IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
+ 0, "startProfile"},
+
{WLAN_PRIV_SET_NONE_GET_INT,
0,
IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
@@ -10322,6 +10401,10 @@
0,
IW_PRIV_TYPE_CHAR | WE_MAX_STR_LEN,
"getStats"},
+ {WE_LIST_FW_PROFILE,
+ 0,
+ IW_PRIV_TYPE_CHAR | WE_MAX_STR_LEN,
+ "listProfile"},
{WE_GET_STATES,
0,
IW_PRIV_TYPE_CHAR | WE_MAX_STR_LEN,
@@ -10388,12 +10471,17 @@
0,
0,
"getRecoverStat"},
- {
- WE_SET_REASSOC_TRIGGER,
- 0,
- 0,
- "reassoc"
- },
+
+ {WE_GET_FW_PROFILE_DATA,
+ 0,
+ 0,
+ "getProfileData"},
+
+ {WE_SET_REASSOC_TRIGGER,
+ 0,
+ 0,
+ "reassoc"},
+
{WE_DUMP_AGC_START,
0,
0,
@@ -10608,6 +10696,14 @@
0, "crash_inject"}
,
#endif
+ {WE_ENABLE_FW_PROFILE,
+ IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2,
+ 0, "enableProfile"}
+ ,
+ {WE_SET_FW_PROFILE_HIST_INTVL,
+ IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2,
+ 0, "set_hist_intvl"}
+ ,
{WE_SET_DUAL_MAC_FW_MODE_CONFIG,
IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2,
0, "set_fw_mode_cfg"}
diff --git a/core/wma/inc/wma.h b/core/wma/inc/wma.h
index f15e518..b72d9fc 100644
--- a/core/wma/inc/wma.h
+++ b/core/wma/inc/wma.h
@@ -1631,6 +1631,28 @@
};
/**
+ * enum profile_id_t - Firmware profiling index
+ * @PROF_CPU_IDLE: cpu idle profile
+ * @PROF_PPDU_PROC: ppdu processing profile
+ * @PROF_PPDU_POST: ppdu post profile
+ * @PROF_HTT_TX_INPUT: htt tx input profile
+ * @PROF_MSDU_ENQ: msdu enqueue profile
+ * @PROF_PPDU_POST_HAL: ppdu post profile
+ * @PROF_COMPUTE_TX_TIME: tx time profile
+ * @PROF_MAX_ID: max profile index
+ */
+enum profile_id_t {
+ PROF_CPU_IDLE,
+ PROF_PPDU_PROC,
+ PROF_PPDU_POST,
+ PROF_HTT_TX_INPUT,
+ PROF_MSDU_ENQ,
+ PROF_PPDU_POST_HAL,
+ PROF_COMPUTE_TX_TIME,
+ PROF_MAX_ID,
+};
+
+/**
* struct p2p_ie - P2P IE structural definition.
* @p2p_id: p2p id
* @p2p_len: p2p length
diff --git a/core/wma/inc/wma_internal.h b/core/wma/inc/wma_internal.h
index c455e12..d927a76 100644
--- a/core/wma/inc/wma_internal.h
+++ b/core/wma/inc/wma_internal.h
@@ -868,6 +868,12 @@
uint32_t value);
#endif
+int wma_profile_data_report_event_handler(void *handle, uint8_t *event_buf,
+ uint32_t len);
+
+int32_t wmi_unified_fw_profiling_cmd(wmi_unified_t wmi_handle,
+ uint32_t cmd, uint32_t value1, uint32_t value2);
+
void wma_wow_tx_complete(void *wma);
int wmi_unified_nat_keepalive_enable(tp_wma_handle wma, uint8_t vdev_id);
diff --git a/core/wma/src/wma_features.c b/core/wma/src/wma_features.c
index d7f54aa..c1e7df5 100644
--- a/core/wma/src/wma_features.c
+++ b/core/wma/src/wma_features.c
@@ -1025,6 +1025,137 @@
}
#endif /* FEATURE_GREEN_AP */
+/**
+ * wmi_unified_fw_profiling_cmd() - send FW profiling cmd to WLAN FW
+ * @wma: wma handle
+ * @cmd: Profiling command index
+ * @value1: parameter1 value
+ * @value2: parameter2 value
+ *
+ * Return: 0 for success else error code
+ */
+int32_t wmi_unified_fw_profiling_cmd(wmi_unified_t wmi_handle,
+ uint32_t cmd, uint32_t value1, uint32_t value2)
+{
+ wmi_buf_t buf;
+ int32_t len = 0;
+ int ret;
+ wmi_wlan_profile_trigger_cmd_fixed_param *prof_trig_cmd;
+ wmi_wlan_profile_set_hist_intvl_cmd_fixed_param *hist_intvl_cmd;
+ wmi_wlan_profile_enable_profile_id_cmd_fixed_param *profile_enable_cmd;
+ wmi_wlan_profile_get_prof_data_cmd_fixed_param *profile_getdata_cmd;
+
+ switch (cmd) {
+ case WMI_WLAN_PROFILE_TRIGGER_CMDID:
+ len = sizeof(wmi_wlan_profile_trigger_cmd_fixed_param);
+ buf = wmi_buf_alloc(wmi_handle, len);
+ if (!buf) {
+ WMA_LOGP("%s: wmi_buf_alloc Failed", __func__);
+ return -ENOMEM;
+ }
+ prof_trig_cmd =
+ (wmi_wlan_profile_trigger_cmd_fixed_param *)
+ wmi_buf_data(buf);
+ WMITLV_SET_HDR(&prof_trig_cmd->tlv_header,
+ WMITLV_TAG_STRUC_wmi_wlan_profile_trigger_cmd_fixed_param,
+ WMITLV_GET_STRUCT_TLVLEN
+ (wmi_wlan_profile_trigger_cmd_fixed_param));
+ prof_trig_cmd->enable = value1;
+ ret = wmi_unified_cmd_send(wmi_handle, buf, len,
+ WMI_WLAN_PROFILE_TRIGGER_CMDID);
+ if (ret) {
+ WMA_LOGE("PROFILE_TRIGGER cmd Failed with value %d",
+ value1);
+ cdf_nbuf_free(buf);
+ return ret;
+ }
+ break;
+
+ case WMI_WLAN_PROFILE_GET_PROFILE_DATA_CMDID:
+ len = sizeof(wmi_wlan_profile_get_prof_data_cmd_fixed_param);
+ buf = wmi_buf_alloc(wmi_handle, len);
+ if (!buf) {
+ WMA_LOGP("%s: wmi_buf_alloc Failed", __func__);
+ return -ENOMEM;
+ }
+ profile_getdata_cmd =
+ (wmi_wlan_profile_get_prof_data_cmd_fixed_param *)
+ wmi_buf_data(buf);
+ WMITLV_SET_HDR(&profile_getdata_cmd->tlv_header,
+ WMITLV_TAG_STRUC_wmi_wlan_profile_get_prof_data_cmd_fixed_param,
+ WMITLV_GET_STRUCT_TLVLEN
+ (wmi_wlan_profile_get_prof_data_cmd_fixed_param));
+ ret = wmi_unified_cmd_send(wmi_handle, buf, len,
+ WMI_WLAN_PROFILE_GET_PROFILE_DATA_CMDID);
+ if (ret) {
+ WMA_LOGE("PROFILE_DATA cmd Failed for id %d value %d",
+ value1, value2);
+ cdf_nbuf_free(buf);
+ return ret;
+ }
+ break;
+
+ case WMI_WLAN_PROFILE_SET_HIST_INTVL_CMDID:
+ len = sizeof(wmi_wlan_profile_set_hist_intvl_cmd_fixed_param);
+ buf = wmi_buf_alloc(wmi_handle, len);
+ if (!buf) {
+ WMA_LOGP("%s: wmi_buf_alloc Failed", __func__);
+ return -ENOMEM;
+ }
+ hist_intvl_cmd =
+ (wmi_wlan_profile_set_hist_intvl_cmd_fixed_param *)
+ wmi_buf_data(buf);
+ WMITLV_SET_HDR(&hist_intvl_cmd->tlv_header,
+ WMITLV_TAG_STRUC_wmi_wlan_profile_set_hist_intvl_cmd_fixed_param,
+ WMITLV_GET_STRUCT_TLVLEN
+ (wmi_wlan_profile_set_hist_intvl_cmd_fixed_param));
+ hist_intvl_cmd->profile_id = value1;
+ hist_intvl_cmd->value = value2;
+ ret = wmi_unified_cmd_send(wmi_handle, buf, len,
+ WMI_WLAN_PROFILE_SET_HIST_INTVL_CMDID);
+ if (ret) {
+ WMA_LOGE("HIST_INTVL cmd Failed for id %d value %d",
+ value1, value2);
+ cdf_nbuf_free(buf);
+ return ret;
+ }
+ break;
+
+ case WMI_WLAN_PROFILE_ENABLE_PROFILE_ID_CMDID:
+ len =
+ sizeof(wmi_wlan_profile_enable_profile_id_cmd_fixed_param);
+ buf = wmi_buf_alloc(wmi_handle, len);
+ if (!buf) {
+ WMA_LOGP("%s: wmi_buf_alloc Failed", __func__);
+ return -ENOMEM;
+ }
+ profile_enable_cmd =
+ (wmi_wlan_profile_enable_profile_id_cmd_fixed_param *)
+ wmi_buf_data(buf);
+ WMITLV_SET_HDR(&profile_enable_cmd->tlv_header,
+ WMITLV_TAG_STRUC_wmi_wlan_profile_enable_profile_id_cmd_fixed_param,
+ WMITLV_GET_STRUCT_TLVLEN
+ (wmi_wlan_profile_enable_profile_id_cmd_fixed_param));
+ profile_enable_cmd->profile_id = value1;
+ profile_enable_cmd->enable = value2;
+ ret = wmi_unified_cmd_send(wmi_handle, buf, len,
+ WMI_WLAN_PROFILE_ENABLE_PROFILE_ID_CMDID);
+ if (ret) {
+ WMA_LOGE("enable cmd Failed for id %d value %d",
+ value1, value2);
+ cdf_nbuf_free(buf);
+ return ret;
+ }
+ break;
+
+ default:
+ WMA_LOGD("%s: invalid profiling command", __func__);
+ break;
+ }
+
+ return 0;
+}
+
#ifdef FEATURE_WLAN_LPHB
/**
* wma_lphb_handler() - send LPHB indication to SME
diff --git a/core/wma/src/wma_main.c b/core/wma/src/wma_main.c
index c2eafde..e9c6bd9 100644
--- a/core/wma/src/wma_main.c
+++ b/core/wma/src/wma_main.c
@@ -955,6 +955,52 @@
WMA_LOGE("dbglog_report_enable failed ret %d",
ret);
break;
+ case WMI_WLAN_PROFILE_TRIGGER_CMDID:
+ ret = wmi_unified_fw_profiling_cmd(wma->wmi_handle,
+ WMI_WLAN_PROFILE_TRIGGER_CMDID,
+ privcmd->param_value, 0);
+ if (ret)
+ WMA_LOGE("Profile cmd failed for %d ret %d",
+ WMI_WLAN_PROFILE_TRIGGER_CMDID, ret);
+ break;
+ case WMI_WLAN_PROFILE_ENABLE_PROFILE_ID_CMDID:
+ ret = wmi_unified_fw_profiling_cmd(wma->wmi_handle,
+ WMI_WLAN_PROFILE_ENABLE_PROFILE_ID_CMDID,
+ privcmd->param_value,
+ privcmd->param_sec_value);
+ if (ret)
+ WMA_LOGE("Profile cmd failed for %d ret %d",
+ WMI_WLAN_PROFILE_ENABLE_PROFILE_ID_CMDID,
+ ret);
+ break;
+ case WMI_WLAN_PROFILE_SET_HIST_INTVL_CMDID:
+ ret = wmi_unified_fw_profiling_cmd(wma->wmi_handle,
+ WMI_WLAN_PROFILE_SET_HIST_INTVL_CMDID,
+ privcmd->param_value,
+ privcmd->param_sec_value);
+ if (ret)
+ WMA_LOGE("Profile cmd failed for %d ret %d",
+ WMI_WLAN_PROFILE_SET_HIST_INTVL_CMDID,
+ ret);
+ break;
+ case WMI_WLAN_PROFILE_LIST_PROFILE_ID_CMDID:
+ ret = wmi_unified_fw_profiling_cmd(wma->wmi_handle,
+ WMI_WLAN_PROFILE_LIST_PROFILE_ID_CMDID,
+ 0, 0);
+ if (ret)
+ WMA_LOGE("Profile cmd failed for %d ret %d",
+ WMI_WLAN_PROFILE_LIST_PROFILE_ID_CMDID,
+ ret);
+ break;
+ case WMI_WLAN_PROFILE_GET_PROFILE_DATA_CMDID:
+ ret = wmi_unified_fw_profiling_cmd(wma->wmi_handle,
+ WMI_WLAN_PROFILE_GET_PROFILE_DATA_CMDID,
+ 0, 0);
+ if (ret)
+ WMA_LOGE("Profile cmd failed for %d ret %d",
+ WMI_WLAN_PROFILE_GET_PROFILE_DATA_CMDID,
+ ret);
+ break;
#ifdef FEATURE_GREEN_AP
case WMI_PDEV_GREEN_AP_PS_ENABLE_CMDID:
/* Set the Green AP */
@@ -1640,6 +1686,10 @@
wmi_unified_register_event_handler(wma_handle->wmi_handle,
WMI_DEBUG_PRINT_EVENTID,
wma_unified_debug_print_event_handler);
+ /* Register profiling event Handler */
+ wmi_unified_register_event_handler(wma_handle->wmi_handle,
+ WMI_WLAN_PROFILE_DATA_EVENTID,
+ wma_profile_data_report_event_handler);
wma_handle->tgt_cfg_update_cb = tgt_cfg_cb;
wma_handle->dfs_radar_indication_cb = radar_ind_cb;
diff --git a/core/wma/src/wma_utils.c b/core/wma/src/wma_utils.c
index fd34f80..a8f81d5 100644
--- a/core/wma/src/wma_utils.c
+++ b/core/wma/src/wma_utils.c
@@ -381,6 +381,78 @@
}
#endif /* WLAN_FEATURE_STATS_EXT */
+/**
+ * wma_profile_data_report_event_handler() - fw profiling handler
+ * @handle: wma handle
+ * @event_buf: event buffer received from fw
+ * @len: length of data
+ *
+ * Return: 0 for success or error code
+ */
+int wma_profile_data_report_event_handler(void *handle, uint8_t *event_buf,
+ uint32_t len)
+{
+ WMI_WLAN_PROFILE_DATA_EVENTID_param_tlvs *param_buf;
+ wmi_wlan_profile_ctx_t *profile_ctx;
+ wmi_wlan_profile_t *profile_data;
+ uint32_t i = 0;
+ uint32_t entries;
+ uint8_t *buf_ptr;
+ param_buf = (WMI_WLAN_PROFILE_DATA_EVENTID_param_tlvs *) event_buf;
+
+ if (!param_buf) {
+ WMA_LOGE("%s: Invalid profile data event buf", __func__);
+ return -EINVAL;
+ }
+ profile_ctx = param_buf->profile_ctx;
+ buf_ptr = (uint8_t *)profile_ctx;
+ buf_ptr = buf_ptr + sizeof(wmi_wlan_profile_ctx_t) + WMI_TLV_HDR_SIZE;
+ profile_data = (wmi_wlan_profile_t *) buf_ptr;
+ entries = profile_ctx->bin_count;
+ CDF_TRACE(CDF_MODULE_ID_WMA, CDF_TRACE_LEVEL_ERROR,
+ "Profile data stats\n");
+ CDF_TRACE(CDF_MODULE_ID_WMA, CDF_TRACE_LEVEL_ERROR,
+ "TOT: %d\n"
+ "tx_msdu_cnt: %d\n"
+ "tx_mpdu_cnt: %d\n"
+ "tx_ppdu_cnt: %d\n"
+ "rx_msdu_cnt: %d\n"
+ "rx_mpdu_cnt: %d\n"
+ "bin_count: %d\n",
+ profile_ctx->tot,
+ profile_ctx->tx_msdu_cnt,
+ profile_ctx->tx_mpdu_cnt,
+ profile_ctx->tx_ppdu_cnt,
+ profile_ctx->rx_msdu_cnt,
+ profile_ctx->rx_mpdu_cnt,
+ profile_ctx->bin_count);
+
+ for (i = 0; i < entries; i++) {
+ if (i == WMI_WLAN_PROFILE_MAX_BIN_CNT)
+ break;
+ CDF_TRACE(CDF_MODULE_ID_WMA, CDF_TRACE_LEVEL_ERROR,
+ "Profile ID: %d\n"
+ "Profile Count: %d\n"
+ "Profile TOT: %d\n"
+ "Profile Min: %d\n"
+ "Profile Max: %d\n"
+ "Profile hist_intvl: %d\n"
+ "Profile hist[0]: %d\n"
+ "Profile hist[1]: %d\n"
+ "Profile hist[2]: %d\n",
+ profile_data[i].id,
+ profile_data[i].cnt,
+ profile_data[i].tot,
+ profile_data[i].min,
+ profile_data[i].max,
+ profile_data[i].hist_intvl,
+ profile_data[i].hist[0],
+ profile_data[i].hist[1],
+ profile_data[i].hist[2]);
+ }
+
+ return 0;
+}
#ifdef WLAN_FEATURE_LINK_LAYER_STATS