diff --git a/dp/inc/cdp_txrx_host_stats.h b/dp/inc/cdp_txrx_host_stats.h index 03dcba2b4b87..67165dbc10fd 100644 --- a/dp/inc/cdp_txrx_host_stats.h +++ b/dp/inc/cdp_txrx_host_stats.h @@ -401,6 +401,16 @@ static inline void cdp_get_dp_fw_peer_stats(ol_txrx_soc_handle soc, (pdev, mac, caps); } +static inline void cdp_get_dp_htt_stats(ol_txrx_soc_handle soc, + struct cdp_pdev *pdev, + void *data, uint32_t data_len) +{ + if (soc->ops->host_stats_ops->get_htt_stats) + return soc->ops->host_stats_ops->get_htt_stats + (pdev, data, data_len); + return; +} + /** * @brief Parse the stats header and get the payload from the message. * diff --git a/dp/inc/cdp_txrx_ops.h b/dp/inc/cdp_txrx_ops.h index 01932f575240..646c160c0678 100644 --- a/dp/inc/cdp_txrx_ops.h +++ b/dp/inc/cdp_txrx_ops.h @@ -559,7 +559,9 @@ struct cdp_host_stats_ops { void (*get_fw_peer_stats)(struct cdp_pdev *pdev, uint8_t *addr, uint32_t cap); - + void + (*get_htt_stats)(struct cdp_pdev *pdev, void *data, + uint32_t data_len); }; struct cdp_wds_ops { diff --git a/dp/wifi3.0/dp_htt.c b/dp/wifi3.0/dp_htt.c index 45bfa0bbcc7f..1e09746c7ee6 100644 --- a/dp/wifi3.0/dp_htt.c +++ b/dp/wifi3.0/dp_htt.c @@ -1131,6 +1131,45 @@ fail0: return QDF_STATUS_E_FAILURE; } +#if defined(CONFIG_WIN) && WDI_EVENT_ENABLE +static inline QDF_STATUS dp_send_htt_stat_resp(struct htt_stats_context *htt_stats, + struct dp_soc *soc, qdf_nbuf_t htt_msg) + +{ + uint32_t pdev_id; + uint32_t *msg_word = NULL; + uint32_t msg_remain_len = 0; + + msg_word = (uint32_t *) qdf_nbuf_data(htt_msg); + + /*COOKIE MSB*/ + pdev_id = *(msg_word + 2); + + /* stats message length + 16 size of HTT header*/ + msg_remain_len = qdf_min(htt_stats->msg_len + 16, + (uint32_t)DP_EXT_MSG_LENGTH); + + dp_wdi_event_handler(WDI_EVENT_HTT_STATS, soc, + msg_word, msg_remain_len, + WDI_NO_VAL, pdev_id); + + if (htt_stats->msg_len >= DP_EXT_MSG_LENGTH) { + htt_stats->msg_len -= DP_EXT_MSG_LENGTH; + } + /* Need to be freed here as WDI handler will + * make a copy of pkt to send data to application + */ + qdf_nbuf_free(htt_msg); + return QDF_STATUS_SUCCESS; +} +#else +static inline QDF_STATUS dp_send_htt_stat_resp(struct htt_stats_context *htt_stats, + struct dp_soc *soc, qdf_nbuf_t htt_msg) +{ + return QDF_STATUS_E_NOSUPPORT; +} +#endif + /** * dp_process_htt_stat_msg(): Process the list of buffers of HTT EXT stats * @htt_stats: htt stats info @@ -1151,7 +1190,8 @@ fail0: * * return: void */ -static inline void dp_process_htt_stat_msg(struct htt_stats_context *htt_stats) +static inline void dp_process_htt_stat_msg(struct htt_stats_context *htt_stats, + struct dp_soc *soc) { htt_tlv_tag_t tlv_type = 0xff; qdf_nbuf_t htt_msg = NULL; @@ -1161,11 +1201,19 @@ static inline void dp_process_htt_stat_msg(struct htt_stats_context *htt_stats) uint32_t msg_remain_len = 0; uint32_t tlv_remain_len = 0; uint32_t *tlv_start; + int cookie_val; /* Process node in the HTT message queue */ while ((htt_msg = qdf_nbuf_queue_remove(&htt_stats->msg)) != NULL) { msg_word = (uint32_t *) qdf_nbuf_data(htt_msg); + cookie_val = *(msg_word + 1); + if (cookie_val) { + if (dp_send_htt_stat_resp(htt_stats, soc, htt_msg) + == QDF_STATUS_SUCCESS) { + continue; + } + } /* read 5th word */ msg_word = msg_word + 4; msg_remain_len = qdf_min(htt_stats->msg_len, @@ -1315,8 +1363,7 @@ void htt_t2h_stats_handler(void *context) rem_stats = --soc->htt_stats.num_stats; qdf_spin_unlock_bh(&soc->htt_stats.lock); - dp_process_htt_stat_msg(&htt_stats); - + dp_process_htt_stat_msg(&htt_stats, soc); /* If there are more stats to process, schedule stats work again */ if (rem_stats) qdf_sched_work(0, &soc->htt_stats.work); @@ -2583,7 +2630,7 @@ htt_soc_detach(void *htt_soc) QDF_STATUS dp_h2t_ext_stats_msg_send(struct dp_pdev *pdev, uint32_t stats_type_upload_mask, uint32_t config_param_0, uint32_t config_param_1, uint32_t config_param_2, - uint32_t config_param_3) + uint32_t config_param_3, int cookie_val) { struct htt_soc *soc = pdev->soc->htt_handle; struct dp_htt_htc_pkt *pkt; @@ -2620,6 +2667,13 @@ QDF_STATUS dp_h2t_ext_stats_msg_send(struct dp_pdev *pdev, return QDF_STATUS_E_FAILURE; } + QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_INFO, + "-----%s:%d----\n cookie <-> %d\n config_param_0 %u\n" + "config_param_1 %u\n config_param_2 %u\n" + "config_param_4 %u\n -------------\n", + __func__, __LINE__, cookie_val, config_param_0, + config_param_1, config_param_2, config_param_3); + msg_word = (uint32_t *) qdf_nbuf_data(msg); qdf_nbuf_push_head(msg, HTC_HDR_ALIGNMENT_PADDING); @@ -2649,6 +2703,20 @@ QDF_STATUS dp_h2t_ext_stats_msg_send(struct dp_pdev *pdev, HTT_H2T_EXT_STATS_REQ_CONFIG_PARAM_SET(*msg_word, config_param_3); HTT_H2T_EXT_STATS_REQ_CONFIG_PARAM_SET(*msg_word, 0); + + /* word 5 */ + msg_word++; + + /* word 6 */ + msg_word++; + *msg_word = 0; + HTT_H2T_EXT_STATS_REQ_CONFIG_PARAM_SET(*msg_word, cookie_val); + + /* word 7 */ + msg_word++; + *msg_word = 0; + HTT_H2T_EXT_STATS_REQ_CONFIG_PARAM_SET(*msg_word, pdev->pdev_id); + pkt = htt_htc_pkt_alloc(soc); if (!pkt) { qdf_nbuf_free(msg); diff --git a/dp/wifi3.0/dp_internal.h b/dp/wifi3.0/dp_internal.h index be69f1d7ea67..f9cd44e46f67 100644 --- a/dp/wifi3.0/dp_internal.h +++ b/dp/wifi3.0/dp_internal.h @@ -301,7 +301,7 @@ void dp_tx_me_free_descriptor(struct cdp_pdev *pdev); QDF_STATUS dp_h2t_ext_stats_msg_send(struct dp_pdev *pdev, uint32_t stats_type_upload_mask, uint32_t config_param_0, uint32_t config_param_1, uint32_t config_param_2, - uint32_t config_param_3); + uint32_t config_param_3, int cookie); void dp_htt_stats_print_tag(uint8_t tag_type, uint32_t *tag_buf); void dp_peer_rxtid_stats(struct dp_peer *peer, void (*callback_fn), void *cb_ctxt); diff --git a/dp/wifi3.0/dp_main.c b/dp/wifi3.0/dp_main.c index 49fccd47591d..690e3660bf44 100644 --- a/dp/wifi3.0/dp_main.c +++ b/dp/wifi3.0/dp_main.c @@ -4757,10 +4757,41 @@ dp_get_fw_peer_stats(struct cdp_pdev *pdev_handle, uint8_t *mac_addr, dp_h2t_ext_stats_msg_send(pdev, HTT_DBG_EXT_STATS_PEER_INFO, config_param0, config_param1, config_param2, - config_param3); + config_param3, 0); } +/* This struct definition will be removed from here + * once it get added in FW headers*/ +struct httstats_cmd_req { + uint32_t config_param0; + uint32_t config_param1; + uint32_t config_param2; + uint32_t config_param3; + int cookie; + u_int8_t stats_id; +}; + +/* + * dp_get_htt_stats: function to process the httstas request + * @pdev_handle: DP pdev handle + * @data: pointer to request data + * @data_len: length for request data + * + * return: void + */ +static void +dp_get_htt_stats(struct cdp_pdev *pdev_handle, void *data, uint32_t data_len) +{ + struct dp_pdev *pdev = (struct dp_pdev *)pdev_handle; + struct httstats_cmd_req *req = (struct httstats_cmd_req *)data; + + QDF_ASSERT(data_len == sizeof(struct httstats_cmd_req)); + dp_h2t_ext_stats_msg_send(pdev, req->stats_id, + req->config_param0, req->config_param1, + req->config_param2, req->config_param3, + req->cookie); +} /* * dp_set_pdev_param: function to set parameters in pdev * @pdev_handle: DP pdev handle @@ -4903,7 +4934,7 @@ static int dp_fw_stats_process(struct cdp_vdev *vdev_handle, pdev = vdev->pdev; return dp_h2t_ext_stats_msg_send(pdev, stats, req->param0, - req->param1, req->param2, req->param3); + req->param1, req->param2, req->param3, 0); } /** @@ -5420,6 +5451,7 @@ static struct cdp_mon_ops dp_ops_mon = { static struct cdp_host_stats_ops dp_ops_host_stats = { .txrx_per_peer_stats = dp_get_host_peer_stats, .get_fw_peer_stats = dp_get_fw_peer_stats, + .get_htt_stats = dp_get_htt_stats, .txrx_enable_enhanced_stats = dp_enable_enhanced_stats, .txrx_disable_enhanced_stats = dp_disable_enhanced_stats, /* TODO */ diff --git a/os_if/linux/qca_vendor.h b/os_if/linux/qca_vendor.h index f8709cd24bed..249017277822 100644 --- a/os_if/linux/qca_vendor.h +++ b/os_if/linux/qca_vendor.h @@ -245,6 +245,9 @@ * @QCA_NL80211_VENDOR_SUBCMD_SPECTRAL_SCAN_GET_STATUS: Get the current * status of spectral scan. The status values are specified * by enum qca_wlan_vendor_attr_spectral_scan_status. + * @QCA_NL80211_VENDOR_SUBCMD_HTT_STATS: Request the firmware + * DP stats for a particualr stats type for response evnet + * it carries the stats data sent from the FW */ enum qca_nl80211_vendor_subcmds { @@ -444,6 +447,7 @@ enum qca_nl80211_vendor_subcmds { QCA_NL80211_VENDOR_SUBCMD_SPECTRAL_SCAN_GET_DIAG_STATS = 159, QCA_NL80211_VENDOR_SUBCMD_SPECTRAL_SCAN_GET_CAP_INFO = 160, QCA_NL80211_VENDOR_SUBCMD_SPECTRAL_SCAN_GET_STATUS = 161, + QCA_NL80211_VENDOR_SUBCMD_HTT_STATS = 162, }; enum qca_wlan_vendor_tos { @@ -863,6 +867,7 @@ enum qca_nl80211_vendor_subcmds_index { QCA_NL80211_VENDOR_SUBCMD_PWR_SAVE_FAIL_DETECTED_INDEX, QCA_NL80211_VENDOR_SUBCMD_NUD_STATS_GET_INDEX, QCA_NL80211_VENDOR_SUBCMD_HANG_REASON_INDEX, + QCA_NL80211_VENDOR_SUBCMD_HTT_STATS_INDEX, }; /**