diff options
| author | Mohit Khanna <mkhannaqca@codeaurora.org> | 2016-10-11 13:18:29 -0700 |
|---|---|---|
| committer | qcabuildsw <qcabuildsw@localhost> | 2016-11-17 00:19:41 -0800 |
| commit | d6842e02850efc50b438c9e6805747483daa2141 (patch) | |
| tree | afa7bc389a13292b5f2a0cef4e8561b251001da2 | |
| parent | 47c3365e1069a873d3d656871acf9c6bc749d73c (diff) | |
qcacld-3.0: Add NAPI statistics to dumpstats
Currently NAPI stats are retrieved as a part of iwpriv getStats command.
The buffer available for this command is limited and NAPI stats get
truncated.
Add a new dumpStats parameter (9) to dump NAPI stats.
The following command will dump NAPI Stats into kmsg.
>iwpriv wlan0 dumpStats 9
Cleanup existing getStats
Change-Id: I0d804295d96a495b4afa576c8258f08c9c2b9bbb
CRs-Fixed: 1076563
| -rw-r--r-- | core/dp/ol/inc/ol_txrx_ctrl_api.h | 1 | ||||
| -rw-r--r-- | core/dp/txrx/ol_txrx.c | 58 | ||||
| -rw-r--r-- | core/hdd/inc/wlan_hdd_main.h | 4 | ||||
| -rw-r--r-- | core/hdd/inc/wlan_hdd_napi.h | 9 | ||||
| -rw-r--r-- | core/hdd/inc/wlan_hdd_wext.h | 1 | ||||
| -rw-r--r-- | core/hdd/src/wlan_hdd_hostapd.c | 8 | ||||
| -rw-r--r-- | core/hdd/src/wlan_hdd_ioctl.c | 300 | ||||
| -rw-r--r-- | core/hdd/src/wlan_hdd_main.c | 43 | ||||
| -rw-r--r-- | core/hdd/src/wlan_hdd_napi.c | 59 | ||||
| -rw-r--r-- | core/hdd/src/wlan_hdd_wext.c | 76 |
10 files changed, 176 insertions, 383 deletions
diff --git a/core/dp/ol/inc/ol_txrx_ctrl_api.h b/core/dp/ol/inc/ol_txrx_ctrl_api.h index bb7339d4d990..f4228b71e279 100644 --- a/core/dp/ol/inc/ol_txrx_ctrl_api.h +++ b/core/dp/ol/inc/ol_txrx_ctrl_api.h @@ -70,6 +70,7 @@ #define WLAN_TXRX_DESC_STATS 6 #define WLAN_HIF_STATS 7 #define WLAN_LRO_STATS 8 +#define WLAN_NAPI_STATS 9 #define WLAN_SCHEDULER_STATS 21 #define WLAN_TX_QUEUE_STATS 22 #define WLAN_BUNDLE_STATS 23 diff --git a/core/dp/txrx/ol_txrx.c b/core/dp/txrx/ol_txrx.c index 60a806839ac4..74845898908e 100644 --- a/core/dp/txrx/ol_txrx.c +++ b/core/dp/txrx/ol_txrx.c @@ -3632,6 +3632,8 @@ void ol_txrx_stats_display_tso(ol_txrx_pdev_handle pdev) TXRX_STATS_TSO_MSDU_IDX(pdev)); for (msdu_idx = 0; msdu_idx < NUM_MAX_TSO_MSDUS; msdu_idx++) { + if (TXRX_STATS_TSO_MSDU_TOTAL_LEN(pdev, msdu_idx) == 0) + continue; QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR, "jumbo pkt idx: %d num segs %d gso_len %d total_len %d nr_frags %d", msdu_idx, @@ -3664,7 +3666,6 @@ void ol_txrx_stats_display_tso(ol_txrx_pdev_handle pdev) tso_seg.tso_flags.tcp_seq_num, tso_seg.tso_flags.ip_id); } - QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR, "\n"); } } #else @@ -3697,7 +3698,7 @@ ol_txrx_stats(uint8_t vdev_id, char *buffer, unsigned buf_len) } len = scnprintf(buffer, buf_len, - "\nTXRX stats:\n\nllQueue State : %s\n pause %u unpause %u\n overflow %u\n llQueue timer state : %s\n", + "\n\nTXRX stats:\nllQueue State : %s\npause %u unpause %u\noverflow %u\nllQueue timer state : %s", ((vdev->ll_pause.is_q_paused == false) ? "UNPAUSED" : "PAUSED"), vdev->ll_pause.q_pause_cnt, @@ -4166,44 +4167,21 @@ void ol_txrx_ipa_uc_get_stat(ol_txrx_pdev_handle pdev) #endif /* IPA_UC_OFFLOAD */ /** - * ol_txrx_display_stats_help() - print statistics help + * ol_txrx_display_stats() - Display OL TXRX display stats + * @value: Module id for which stats needs to be displayed * - * Return: none + * Return: QDF_STATUS_SUCCESS on success, QDF_STATUS_E code on failure */ -static void ol_txrx_display_stats_help(void) -{ - QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR, - "iwpriv wlan0 dumpStats [option] - dump statistics"); - QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR, - "iwpriv wlan0 clearStats [option] - clear statistics"); - QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR, - "options:"); - QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR, - " 1 -- TXRX Layer statistics"); - QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR, - " 2 -- Bandwidth compute timer stats"); - QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR, - " 3 -- TSO statistics"); - QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR, - " 4 -- Network queue statistics"); - QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR, - " 5 -- Flow control statistics"); - QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR, - " 6 -- Per Layer statistics"); - QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR, - " 7 -- Copy engine interrupt statistics"); - -} - -void ol_txrx_display_stats(uint16_t value) +QDF_STATUS ol_txrx_display_stats(uint16_t value) { ol_txrx_pdev_handle pdev; + QDF_STATUS status = QDF_STATUS_SUCCESS; pdev = cds_get_context(QDF_MODULE_ID_TXRX); if (!pdev) { QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR, "%s: pdev is NULL", __func__); - return; + return QDF_STATUS_E_NULL_VALUE; } switch (value) { @@ -4240,20 +4218,28 @@ void ol_txrx_display_stats(uint16_t value) #endif #endif default: - ol_txrx_display_stats_help(); + status = QDF_STATUS_E_INVAL; break; } + return status; } -void ol_txrx_clear_stats(uint16_t value) +/** + * ol_txrx_clear_stats() - Clear OL TXRX stats + * @value: Module id for which stats needs to be cleared + * + * Return: QDF_STATUS_SUCCESS on success, QDF_STATUS_E code on failure + */ +QDF_STATUS ol_txrx_clear_stats(uint16_t value) { ol_txrx_pdev_handle pdev; + QDF_STATUS status = QDF_STATUS_SUCCESS; pdev = cds_get_context(QDF_MODULE_ID_TXRX); if (!pdev) { QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR, "%s: pdev is NULL", __func__); - return; + return QDF_STATUS_E_NULL_VALUE; } switch (value) { @@ -4283,9 +4269,11 @@ void ol_txrx_clear_stats(uint16_t value) break; #endif default: - ol_txrx_display_stats_help(); + status = QDF_STATUS_E_INVAL; break; } + + return status; } /** diff --git a/core/hdd/inc/wlan_hdd_main.h b/core/hdd/inc/wlan_hdd_main.h index 13572103286b..1ae408e2c7b1 100644 --- a/core/hdd/inc/wlan_hdd_main.h +++ b/core/hdd/inc/wlan_hdd_main.h @@ -333,7 +333,7 @@ extern spinlock_t hdd_context_lock; #define WLAN_SAP_HDD_TX_FLOW_CONTROL_OS_Q_BLOCK_TIME 100 #define WLAN_HDD_TX_FLOW_CONTROL_MAX_24BAND_CH 14 -#define NUM_TX_RX_HISTOGRAM 1024 +#define NUM_TX_RX_HISTOGRAM 128 #define NUM_TX_RX_HISTOGRAM_MASK (NUM_TX_RX_HISTOGRAM - 1) /** @@ -1764,7 +1764,7 @@ void hdd_clean_up_pre_cac_interface(hdd_context_t *hdd_ctx); void wlan_hdd_txrx_pause_cb(uint8_t vdev_id, enum netif_action_type action, enum netif_reason_type reason); -void hdd_wlan_dump_stats(hdd_adapter_t *adapter, int value); +int hdd_wlan_dump_stats(hdd_adapter_t *adapter, int value); void wlan_hdd_deinit_tx_rx_histogram(hdd_context_t *hdd_ctx); void wlan_hdd_display_tx_rx_histogram(hdd_context_t *pHddCtx); void wlan_hdd_clear_tx_rx_histogram(hdd_context_t *pHddCtx); diff --git a/core/hdd/inc/wlan_hdd_napi.h b/core/hdd/inc/wlan_hdd_napi.h index 3e81ef6dae01..23be72f46b54 100644 --- a/core/hdd/inc/wlan_hdd_napi.h +++ b/core/hdd/inc/wlan_hdd_napi.h @@ -48,11 +48,7 @@ struct hdd_context_s; int hdd_napi_enabled(int id); int hdd_napi_create(void); int hdd_napi_destroy(int force); - -int hdd_napi_stats(char *buf, - int max, - char *indp, - struct qca_napi_data *napid); +int hdd_display_napi_stats(void); /* the following triggers napi_enable/disable as required */ int hdd_napi_event(enum qca_napi_event event, void *data); @@ -91,8 +87,7 @@ static inline int hdd_napi_serialize(int is_on) static inline int hdd_napi_enabled(int id) { return 0; } static inline int hdd_napi_create(void) { return 0; } static inline int hdd_napi_destroy(int force) { return 0; } -static inline int hdd_napi_stats(char *buf, int max, char *indp, - struct qca_napi_data *napid) { return 0; } +static inline int hdd_display_napi_stats(void) { return 0; } static inline int hdd_napi_event(enum qca_napi_event event, void *data) { return 0; diff --git a/core/hdd/inc/wlan_hdd_wext.h b/core/hdd/inc/wlan_hdd_wext.h index 8829dfa07b78..aab5fdc60adb 100644 --- a/core/hdd/inc/wlan_hdd_wext.h +++ b/core/hdd/inc/wlan_hdd_wext.h @@ -310,6 +310,7 @@ extern int hdd_wlan_get_rts_threshold(hdd_adapter_t *pAdapter, union iwreq_data *wrqu); extern int hdd_wlan_get_frag_threshold(hdd_adapter_t *pAdapter, union iwreq_data *wrqu); +extern void hdd_display_stats_help(void); extern void hdd_wlan_get_version(hdd_context_t *hdd_ctx, union iwreq_data *wrqu, char *extra); diff --git a/core/hdd/src/wlan_hdd_hostapd.c b/core/hdd/src/wlan_hdd_hostapd.c index 239fd3edb97c..aa568a4a2ddf 100644 --- a/core/hdd/src/wlan_hdd_hostapd.c +++ b/core/hdd/src/wlan_hdd_hostapd.c @@ -3135,7 +3135,7 @@ static __iw_softap_setparam(struct net_device *dev, case QCASAP_DUMP_STATS: { hdd_notice("QCASAP_DUMP_STATS val %d", set_value); - hdd_wlan_dump_stats(pHostapdAdapter, set_value); + ret = hdd_wlan_dump_stats(pHostapdAdapter, set_value); break; } case QCASAP_CLEAR_STATS: @@ -3160,7 +3160,11 @@ static __iw_softap_setparam(struct net_device *dev, hdd_clear_hif_stats(); break; default: - ol_txrx_clear_stats(set_value); + if (ol_txrx_clear_stats(set_value) == + QDF_STATUS_E_INVAL) { + hdd_display_stats_help(); + ret = EINVAL; + } } break; } diff --git a/core/hdd/src/wlan_hdd_ioctl.c b/core/hdd/src/wlan_hdd_ioctl.c index 683b17a8c5f3..38bce8dbe581 100644 --- a/core/hdd/src/wlan_hdd_ioctl.c +++ b/core/hdd/src/wlan_hdd_ioctl.c @@ -6133,303 +6133,6 @@ static int drv_cmd_get_linkspeed(hdd_adapter_t *adapter, return ret; } -#ifdef FEATURE_NAPI -/** - * hdd_parse_napi() - helper functions to drv_cmd_napi - * @str : source string to parse - * @cmd : pointer to cmd part after parsing - * @sub : pointer to subcmd part after parsing - * @aux : pointer to optional aux part after parsing - * - * Example: - * NAPI SCALE <n> +-- IN str - * | | +------ OUT aux - * | +------------ OUT subcmd - * +----------------- OUT cmd - * - * Return: ==0: success; !=0: failure - */ -static int hdd_parse_napi(char **str, char **cmd, char **sub, char **aux) -{ - int rc; - char *token, *lcmd = NULL, *lsub = NULL, *laux = NULL; - - NAPI_DEBUG("-->\n"); - - token = strsep(str, " \t"); - if (NULL == token) { - hdd_err("cannot parse cmd"); - goto parse_end; - } - lcmd = token; - - token = strsep(str, " \t"); - if (NULL == token) { - hdd_err("cannot parse subcmd"); - goto parse_end; - } - lsub = token; - - token = strsep(str, " \t"); - if (NULL == token) - hdd_warn("cannot parse aux\n"); - else - laux = token; - -parse_end: - if ((NULL == lcmd) || (NULL == lsub)) - rc = -EINVAL; - else { - rc = 0; - *cmd = lcmd; - *sub = lsub; - if (NULL != aux) - *aux = laux; - } - NAPI_DEBUG("<--[rc=%d]\n", rc); - return rc; -} - - -/** - * hdd_parse_stats() - print NAPI stats into a buffer - * @buf : buffer to write stats into - * @max : "size of buffer" - * @idp : NULL: all stats, otherwise, ptr to the NAPI instance - * @napid: binary structure to retrieve the stats from - * - * Return: number of bytes written into the buffer - */ -int hdd_napi_stats(char *buf, - int max, - char *indp, - struct qca_napi_data *napid) -{ - int n = 0; - int i, j, k; /* NAPI, CPU, bucket indices */ - int from, to; - struct qca_napi_info *napii; - struct qca_napi_stat *napis; - - NAPI_DEBUG("-->\n"); - - if (NULL == napid) - return n; - if (NULL == indp) { - from = 0; - to = CE_COUNT_MAX; - } else { - if (0 > kstrtoint(indp, 10, &to)) { - from = 0; - to = CE_COUNT_MAX; - } else - from = to; - } - - for (i = from; i < to; i++) - if (napid->ce_map & (0x01 << i)) { - napii = &(napid->napis[i]); - for (j = 0; j < NR_CPUS; j++) { - napis = &(napii->stats[j]); - n += scnprintf(buf + n, max - n, - "STATS: NAPI[%d] CPU: %d scheds: %d polls: %d completes: %d done: %d ", - i, j, - napis->napi_schedules, - napis->napi_polls, - napis->napi_completes, - napis->napi_workdone); - - for (k = 0; k < QCA_NAPI_NUM_BUCKETS; k++) { - n += scnprintf( - buf + n, max - n, - " %d", - napis->napi_budget_uses[k]); - } - n += scnprintf(buf+n, max - n, "\n"); - } - } - - NAPI_DEBUG("<--[n=%d]\n", n); - return n; -} - -/** - * napi_set_scale() - sets the scale attribute in all NAPI entries - * @sc : scale to set - * - * Return: void - */ -static void napi_set_scale(uint8_t sc) -{ - uint32_t i; - struct qca_napi_data *napi_data; - - napi_data = hdd_napi_get_all(); - if (likely(NULL != napi_data)) - for (i = 0; i < CE_COUNT_MAX; i++) - if (napi_data->ce_map & (0x01 << i)) - napi_data->napis[i].scale = sc; - - return; -} -/** - * drv_cmd_napi() - processes NAPI commands - * @adapter : net_device - * @hdd_ctx : HDD context - * @command : command string from user command (including "NAPI") - * @command_len: length of command - * @priv_data : ifr_data - * - * Commands supported: - * NAPI ENABLE : enables NAPI administratively. Note that this may not - * enable NAPI functionally, as some other conditions - * may not have been satisfied yet - * NAPI DISABLE : reverse operation of "enable" - * NAPI STATUS : get global status of NAPI instances - * NAPI STATS [<n>] : get the stats for a given NAPI instance - * NAPI SCALE <n> : set the scale factor - * - * Return: 0: success; !0: failure - */ -static int drv_cmd_napi(hdd_adapter_t *adapter, - hdd_context_t *hdd_ctx, - uint8_t *command, - uint8_t command_len, - hdd_priv_data_t *priv_data) -{ - int rc = 0; - int n, l; - char *cmd = NULL, *subcmd = NULL, *aux = NULL; - char *synopsis = "NAPI ENABLE\n" - "NAPI DISABLE\n" - "NAPI STATUS\n" - "NAPI STATS [<n>] -- if no <n> then all\n" - "NAPI SCALE <n> -- set the scale\n"; - char *reply = NULL; - - /* make a local copy, as strsep modifies the str in place */ - char *str = NULL; - - NAPI_DEBUG("-->\n"); - - /** - * NOTE TO MAINTAINER: from this point to the end of the function, - * please do not return anywhere in the code except the very end - * to avoid memory leakage (goto end_drv_napi instead) - * or make sure that reply+str is freed - */ - reply = kmalloc(MAX_USER_COMMAND_SIZE, GFP_KERNEL); - if (NULL == reply) { - hdd_err("could not allocate reply buffer"); - rc = -ENOMEM; - goto end_drv_napi; - } - - str = kmalloc(strlen(command) + 1, GFP_KERNEL); - if (NULL == str) { - hdd_err("could not allocate copy of input buffer"); - rc = -ENOMEM; - goto end_drv_napi; - } - - strlcpy(str, command, strlen(command) + 1); - hdd_debug("parsing command into cmd=0x%p sub=0x%p aux=0x%p\n", - cmd, subcmd, aux); - - - rc = hdd_parse_napi(&str, &cmd, &subcmd, &aux); - - if (0 != rc) { - const char *msg = "unknown or badly formatted cmd\n%s"; - l = QDF_MIN(MAX_USER_COMMAND_SIZE, - strlen(msg)+strlen(synopsis)); - n = scnprintf(reply, l, msg, synopsis); - - if (copy_to_user(priv_data->buf, reply, - QDF_MIN(priv_data->total_len, l))) - hdd_err("failed to copy data to user buffer"); - hdd_debug("reply: %s", reply); - - rc = -EINVAL; - } else { - hdd_debug("cmd=(%s) subcmd=(%s) aux=(%s)\n", - cmd, subcmd, aux); - if (!strcmp(subcmd, "ENABLE")) - hdd_napi_event(NAPI_EVT_CMD_STATE, (void *)1); - else if (!strcmp(subcmd, "DISABLE")) - hdd_napi_event(NAPI_EVT_CMD_STATE, (void *)0); - else if (!strcmp(subcmd, "STATUS")) { - int n = 0; - uint32_t i; - struct qca_napi_data *napi_data; - - napi_data = hdd_napi_get_all(); - if (unlikely(NULL == napi_data)) - goto status_end; - n += scnprintf(reply+n, MAX_USER_COMMAND_SIZE - n, - "NAPI state: 0x%08x map: 0x%08x\n", - napi_data->state, - napi_data->ce_map); - - for (i = 0; i < CE_COUNT_MAX; i++) - if (napi_data->ce_map & (0x01 << i)) { - n += scnprintf( - reply + n, - MAX_USER_COMMAND_SIZE - n, - "#%d: id: %d, scale=%d\n", - i, - napi_data->napis[i].id, - napi_data->napis[i].scale); - } - status_end: - hdd_info("wlan: STATUS DATA:\n%s", reply); - if (copy_to_user(priv_data->buf, reply, - QDF_MIN(n, priv_data->total_len))) - rc = -EINVAL; - } else if (!strcmp(subcmd, "STATS")) { - int n = 0; - struct qca_napi_data *napi_data; - - napi_data = hdd_napi_get_all(); - if (NULL != napi_data) { - n = hdd_napi_stats(reply, MAX_USER_COMMAND_SIZE, - aux, napi_data); - NAPI_DEBUG("STATS: returns %d\n", n); - } - if (n > 0) { - if (copy_to_user(priv_data->buf, reply, - QDF_MIN(priv_data->total_len, - n))) - rc = -EINVAL; - hdd_info("wlan: STATS_DATA\n%s\n", reply); - } else - rc = -EINVAL; - } else if (!strcmp(subcmd, "SCALE")) { - if (NULL == aux) { - rc = -EINVAL; - hdd_err("wlan: SCALE cmd requires <n>"); - } else { - uint8_t sc; - rc = kstrtou8(aux, 10, &sc); - if (rc) { - hdd_err("wlan: bad scale (%s)", aux); - rc = -EINVAL; - } else - napi_set_scale(sc); - } - } /* SCALE */ - } -end_drv_napi: - if (NULL != str) - kfree(str); - if (NULL != reply) - kfree(reply); - - NAPI_DEBUG("<--[rc=%d]\n", rc); - return rc; -} -#endif /* FEATURE_NAPI */ - /** * hdd_set_rx_filter() - set RX filter * @adapter: Pointer to adapter @@ -7193,9 +6896,6 @@ static const hdd_drv_cmd_t hdd_drv_cmds[] = { #endif {"RSSI", drv_cmd_get_rssi}, {"LINKSPEED", drv_cmd_get_linkspeed}, -#ifdef FEATURE_NAPI - {"NAPI", drv_cmd_napi}, -#endif /* FEATURE_NAPI */ {"RXFILTER-REMOVE", drv_cmd_rx_filter_remove}, {"RXFILTER-ADD", drv_cmd_rx_filter_add}, {"SET_FCC_CHANNEL", drv_cmd_set_fcc_channel}, diff --git a/core/hdd/src/wlan_hdd_main.c b/core/hdd/src/wlan_hdd_main.c index 4ec62ecfba51..4e71f4c4c8dc 100644 --- a/core/hdd/src/wlan_hdd_main.c +++ b/core/hdd/src/wlan_hdd_main.c @@ -5585,17 +5585,24 @@ void wlan_hdd_display_tx_rx_histogram(hdd_context_t *hdd_ctx) hdd_err("index, total_rx, interval_rx, total_tx, interval_tx, bus_bw_level, RX TP Level, TX TP Level"); for (i = 0; i < NUM_TX_RX_HISTOGRAM; i++) { - hdd_err("%d: %llu, %llu, %llu, %llu, %s, %s, %s", - i, hdd_ctx->hdd_txrx_hist[i].total_rx, - hdd_ctx->hdd_txrx_hist[i].interval_rx, - hdd_ctx->hdd_txrx_hist[i].total_tx, - hdd_ctx->hdd_txrx_hist[i].interval_tx, - convert_level_to_string( - hdd_ctx->hdd_txrx_hist[i].next_vote_level), - convert_level_to_string( - hdd_ctx->hdd_txrx_hist[i].next_rx_level), - convert_level_to_string( - hdd_ctx->hdd_txrx_hist[i].next_tx_level)); + /* using hdd_log to avoid printing function name */ + if (hdd_ctx->hdd_txrx_hist[i].total_rx != 0 || + hdd_ctx->hdd_txrx_hist[i].total_tx != 0) + hdd_log(QDF_TRACE_LEVEL_ERROR, + "%d: %llu, %llu, %llu, %llu, %s, %s, %s", + i, hdd_ctx->hdd_txrx_hist[i].total_rx, + hdd_ctx->hdd_txrx_hist[i].interval_rx, + hdd_ctx->hdd_txrx_hist[i].total_tx, + hdd_ctx->hdd_txrx_hist[i].interval_tx, + convert_level_to_string( + hdd_ctx->hdd_txrx_hist[i]. + next_vote_level), + convert_level_to_string( + hdd_ctx->hdd_txrx_hist[i]. + next_rx_level), + convert_level_to_string( + hdd_ctx->hdd_txrx_hist[i]. + next_tx_level)); } return; } @@ -5632,7 +5639,7 @@ void wlan_hdd_display_netif_queue_history(hdd_context_t *hdd_ctx) while (NULL != adapter_node && QDF_STATUS_SUCCESS == status) { adapter = adapter_node->pAdapter; - hdd_err("\nNetif queue operation statistics:"); + hdd_err("Netif queue operation statistics:"); hdd_err("Session_id %d device mode %d", adapter->sessionId, adapter->device_mode); hdd_err("Current pause_map value %x", adapter->pause_map); @@ -5658,7 +5665,9 @@ void wlan_hdd_display_netif_queue_history(hdd_context_t *hdd_ctx) if (adapter->pause_map & (1 << i)) pause_delta = delta; - hdd_err("%s: %d: %d: %ums", + /* using hdd_log to avoid printing function name */ + hdd_log(QDF_TRACE_LEVEL_ERROR, + "%s: %d: %d: %ums", hdd_reason_type_to_string(i), adapter->queue_oper_stats[i].pause_count, adapter->queue_oper_stats[i].unpause_count, @@ -5667,14 +5676,18 @@ void wlan_hdd_display_netif_queue_history(hdd_context_t *hdd_ctx) pause_delta)); } - hdd_err("\nNetif queue operation history:"); + hdd_err("Netif queue operation history:"); hdd_err("Total entries: %d current index %d", WLAN_HDD_MAX_HISTORY_ENTRY, adapter->history_index); hdd_err("index: time: action_type: reason_type: pause_map"); for (i = 0; i < WLAN_HDD_MAX_HISTORY_ENTRY; i++) { - hdd_err("%d: %u: %s: %s: %x", + /* using hdd_log to avoid printing function name */ + if (adapter->queue_oper_history[i].time == 0) + continue; + hdd_log(QDF_TRACE_LEVEL_ERROR, + "%d: %u: %s: %s: %x", i, qdf_system_ticks_to_msecs( adapter->queue_oper_history[i].time), hdd_action_type_to_string( diff --git a/core/hdd/src/wlan_hdd_napi.c b/core/hdd/src/wlan_hdd_napi.c index 3e5766f96c40..3e79d995bccb 100644 --- a/core/hdd/src/wlan_hdd_napi.c +++ b/core/hdd/src/wlan_hdd_napi.c @@ -369,3 +369,62 @@ int hdd_napi_poll(struct napi_struct *napi, int budget) { return hif_napi_poll(cds_get_context(QDF_MODULE_ID_HIF), napi, budget); } + +/** + * hdd_display_napi_stats() - print NAPI stats + * + * Return: == 0: success; !=0: failure + */ +int hdd_display_napi_stats(void) +{ + int i, j, k, n; /* NAPI, CPU, bucket indices, bucket buf write index*/ + int max; + struct qca_napi_data *napid; + struct qca_napi_info *napii; + struct qca_napi_stat *napis; + /* + * Expecting each NAPI bucket item to need at max 5 numerals + space for + * formatting. For example "10000 " Thus the array needs to have + * (5 + 1) * QCA_NAPI_NUM_BUCKETS bytes of space. Leaving one space at + * the end of the "buf" arrary for end of string char. + */ + char buf[6 * QCA_NAPI_NUM_BUCKETS + 1] = {'\0'}; + + napid = hdd_napi_get_all(); + if (NULL == napid) { + hdd_err("%s unable to retrieve napi structure", __func__); + return -EFAULT; + } + qdf_print("[NAPI -- STATS]: scheds polls comps done time-lim pkt-lim napi-buckets(%d)", QCA_NAPI_NUM_BUCKETS); + + for (i = 0; i < CE_COUNT_MAX; i++) + if (napid->ce_map & (0x01 << i)) { + napii = &(napid->napis[i]); + for (j = 0; j < NR_CPUS; j++) { + napis = &(napii->stats[j]); + n = 0; + max = sizeof(buf); + for (k = 0; k < QCA_NAPI_NUM_BUCKETS; k++) { + n += scnprintf( + buf + n, max - n, + " %d", + napis->napi_budget_uses[k]); + } + + if (napis->napi_schedules != 0) + qdf_print("NAPI[%2d]CPU[%2d]: %7d %7d %7d %7d %8d %7d %s", + i, j, + napis->napi_schedules, + napis->napi_polls, + napis->napi_completes, + napis->napi_workdone, + napis->time_limit_reached, + napis->rxpkt_thresh_reached, + buf); + } + } + + hif_napi_stats(napid); + return 0; +} + diff --git a/core/hdd/src/wlan_hdd_wext.c b/core/hdd/src/wlan_hdd_wext.c index cffa762b6476..adb98b0ebb3b 100644 --- a/core/hdd/src/wlan_hdd_wext.c +++ b/core/hdd/src/wlan_hdd_wext.c @@ -612,14 +612,14 @@ void hdd_wlan_get_stats(hdd_adapter_t *pAdapter, uint16_t *length, } len = scnprintf(buffer, buf_len, - "\nTransmit" - "\ncalled %u, dropped %u," - "\n dropped BK %u, BE %u, VI %u, VO %u" - "\n classified BK %u, BE %u, VI %u, VO %u" - "\ncompleted %u," - "\n\nReceive Total" - "\n packets %u, dropped %u, delivered %u, refused %u" + "\nTransmit[%lu] - " + "called %u, dropped %u," + "\n[dropped] BK %u, BE %u, VI %u, VO %u" + "\n[classified] BK %u, BE %u, VI %u, VO %u" + "\n\nReceive[%lu] - " + "packets %u, dropped %u, delivered %u, refused %u" "\n", + qdf_system_ticks(), pStats->txXmitCalled, pStats->txXmitDropped, @@ -632,21 +632,22 @@ void hdd_wlan_get_stats(hdd_adapter_t *pAdapter, uint16_t *length, pStats->txXmitClassifiedAC[SME_AC_BE], pStats->txXmitClassifiedAC[SME_AC_VI], pStats->txXmitClassifiedAC[SME_AC_VO], - - pStats->txCompleted, + qdf_system_ticks(), total_rx_pkt, total_rx_dropped, total_rx_delv, total_rx_refused ); for (i = 0; i < NUM_CPUS; i++) { + if (pStats->rxPackets[i] == 0) + continue; len += scnprintf(buffer + len, buf_len - len, - "\nReceive CPU: %d" - "\n packets %u, dropped %u, delivered %u, refused %u", + "Rx CPU[%d]:" + "packets %u, dropped %u, delivered %u, refused %u\n", i, pStats->rxPackets[i], pStats->rxDropped[i], pStats->rxDelivered[i], pStats->rxRefused[i]); } len += scnprintf(buffer + len, buf_len - len, - "\n\nTX_FLOW" + "\nTX_FLOW" "\nCurrent status: %s" "\ntx-flow timer start count %u" "\npause count %u, unpause count %u", @@ -657,10 +658,6 @@ void hdd_wlan_get_stats(hdd_adapter_t *pAdapter, uint16_t *length, len += ol_txrx_stats(pAdapter->sessionId, &buffer[len], (buf_len - len)); - - len += hdd_napi_stats(buffer + len, buf_len - len, - NULL, hdd_napi_get_all()); - *length = len + 1; } @@ -698,20 +695,41 @@ void hdd_wlan_list_fw_profile(uint16_t *length, *length = len + 1; } +/** + * hdd_display_stats_help() - print statistics help + * + * Return: none + */ +void hdd_display_stats_help(void) +{ + hdd_err("iwpriv wlan0 dumpStats [option] - dump statistics"); + hdd_err("iwpriv wlan0 clearStats [option] - clear statistics"); + hdd_err("options:"); + hdd_err(" 1 -- TXRX Layer statistics"); + hdd_err(" 2 -- Bandwidth compute timer stats"); + hdd_err(" 3 -- TSO statistics"); + hdd_err(" 4 -- Network queue statistics"); + hdd_err(" 5 -- Flow control statistics"); + hdd_err(" 6 -- Per Layer statistics"); + hdd_err(" 7 -- Copy engine interrupt statistics"); + hdd_err(" 8 -- LRO statistics"); + hdd_err(" 9 -- NAPI statistics"); +} /** * hdd_wlan_dump_stats() - display dump Stats * @adapter: adapter handle * @value: value from user * - * Return: none + * Return: 0 => success, error code on failure */ -void hdd_wlan_dump_stats(hdd_adapter_t *adapter, int value) +int hdd_wlan_dump_stats(hdd_adapter_t *adapter, int value) { + int ret = 0; + QDF_STATUS status; hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(adapter); switch (value) { - case WLAN_TXRX_HIST_STATS: wlan_hdd_display_tx_rx_histogram(hdd_ctx); break; @@ -723,11 +741,21 @@ void hdd_wlan_dump_stats(hdd_adapter_t *adapter, int value) break; case WLAN_LRO_STATS: hdd_lro_display_stats(hdd_ctx); + case WLAN_NAPI_STATS: + if (hdd_display_napi_stats()) { + hdd_err("error displaying napi stats"); + ret = EFAULT; + } break; default: - ol_txrx_display_stats(value); + status = ol_txrx_display_stats(value); + if (status == QDF_STATUS_E_INVAL) { + hdd_display_stats_help(); + ret = EINVAL; + } break; } + return ret; } /** @@ -5934,7 +5962,7 @@ static int __iw_setint_getnone(struct net_device *dev, case WE_DUMP_STATS: { hdd_notice("WE_DUMP_STATS val %d", set_value); - hdd_wlan_dump_stats(pAdapter, set_value); + ret = hdd_wlan_dump_stats(pAdapter, set_value); break; } @@ -5957,7 +5985,11 @@ static int __iw_setint_getnone(struct net_device *dev, hdd_clear_hif_stats(); break; default: - ol_txrx_clear_stats(set_value); + if (ol_txrx_clear_stats(set_value) == + QDF_STATUS_E_INVAL) { + hdd_display_stats_help(); + ret = EINVAL; + } } break; } |
