From 1ea85d4671a37d29f5bbae423838f2323f410c6e Mon Sep 17 00:00:00 2001 From: Amir Patel Date: Wed, 9 Jan 2019 15:19:10 +0530 Subject: [PATCH] qcacmn: Add support for STA inactive time in Hawkeye Currently there is not STA inactive time support for lithium. Read inactive_time from htt_peer_stats_cmn_tlv by sending HTT_DBG_EXT_STATS_PEER_INFO to firmware. After sending command, wait on completion variable till firmware to response, trigger completion upon firmware response. CRs-Fixed: 2319219 Change-Id: I93e6343641ae5c72610a57dd6ba551cca0b010c1 --- dp/inc/cdp_txrx_host_stats.h | 7 +++--- dp/inc/cdp_txrx_ops.h | 2 +- dp/wifi3.0/dp_htt.c | 41 ++++++++++++++++++++++++++++++++++++ dp/wifi3.0/dp_main.c | 21 ++++++++++++++---- dp/wifi3.0/dp_peer.h | 12 +++++++++++ dp/wifi3.0/dp_stats.c | 4 +++- dp/wifi3.0/dp_types.h | 6 ++++++ 7 files changed, 84 insertions(+), 9 deletions(-) diff --git a/dp/inc/cdp_txrx_host_stats.h b/dp/inc/cdp_txrx_host_stats.h index adcb442620..f89a2ba09a 100644 --- a/dp/inc/cdp_txrx_host_stats.h +++ b/dp/inc/cdp_txrx_host_stats.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2018 The Linux Foundation. All rights reserved. + * Copyright (c) 2016-2019 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 @@ -383,7 +383,8 @@ cdp_reset_lro_stats(ol_txrx_soc_handle soc, struct cdp_vdev *vdev) } static inline void cdp_get_dp_fw_peer_stats(ol_txrx_soc_handle soc, - struct cdp_pdev *pdev, uint8_t *mac, uint32_t caps) + struct cdp_pdev *pdev, uint8_t *mac, uint32_t caps, + uint32_t copy_stats) { if (!soc || !soc->ops) { QDF_TRACE(QDF_MODULE_ID_CDP, QDF_TRACE_LEVEL_DEBUG, @@ -397,7 +398,7 @@ static inline void cdp_get_dp_fw_peer_stats(ol_txrx_soc_handle soc, return; soc->ops->host_stats_ops->get_fw_peer_stats - (pdev, mac, caps); + (pdev, mac, caps, copy_stats); } static inline void cdp_get_dp_htt_stats(ol_txrx_soc_handle soc, diff --git a/dp/inc/cdp_txrx_ops.h b/dp/inc/cdp_txrx_ops.h index df01880c22..1c0d61fc38 100644 --- a/dp/inc/cdp_txrx_ops.h +++ b/dp/inc/cdp_txrx_ops.h @@ -755,7 +755,7 @@ struct cdp_host_stats_ops { void (*get_fw_peer_stats)(struct cdp_pdev *pdev, uint8_t *addr, - uint32_t cap); + uint32_t cap, uint32_t copy_stats); void (*get_htt_stats)(struct cdp_pdev *pdev, void *data, uint32_t data_len); diff --git a/dp/wifi3.0/dp_htt.c b/dp/wifi3.0/dp_htt.c index 30ead236ff..3ebeeeece5 100644 --- a/dp/wifi3.0/dp_htt.c +++ b/dp/wifi3.0/dp_htt.c @@ -1643,6 +1643,12 @@ static inline void dp_process_htt_stat_msg(struct htt_stats_context *htt_stats, else dp_htt_stats_print_tag(tlv_type, tlv_start); + if (tlv_type == HTT_STATS_PEER_DETAILS_TAG || + tlv_type == HTT_STATS_PEER_STATS_CMN_TAG) + dp_peer_update_inactive_time(pdev, + tlv_type, + tlv_start); + msg_remain_len -= tlv_remain_len; msg_word = (uint32_t *) @@ -3608,3 +3614,38 @@ QDF_STATUS dp_h2t_cfg_stats_msg_send(struct dp_pdev *pdev, return 0; } #endif + +void +dp_peer_update_inactive_time(struct dp_pdev *pdev, uint32_t tag_type, + uint32_t *tag_buf) +{ + switch (tag_type) { + case HTT_STATS_PEER_DETAILS_TAG: + { + htt_peer_details_tlv *dp_stats_buf = + (htt_peer_details_tlv *)tag_buf; + + pdev->fw_stats_peer_id = dp_stats_buf->sw_peer_id; + } + break; + case HTT_STATS_PEER_STATS_CMN_TAG: + { + htt_peer_stats_cmn_tlv *dp_stats_buf = + (htt_peer_stats_cmn_tlv *)tag_buf; + + struct dp_peer *peer = dp_peer_find_by_id(pdev->soc, + pdev->fw_stats_peer_id); + + if (peer && !peer->bss_peer) { + peer->stats.tx.inactive_time = + dp_stats_buf->inactive_time; + qdf_event_set(&pdev->fw_peer_stats_event); + } + if (peer) + dp_peer_unref_del_find_by_id(peer); + } + break; + default: + qdf_err("Invalid tag_type"); + } +} diff --git a/dp/wifi3.0/dp_main.c b/dp/wifi3.0/dp_main.c index e812f9b585..eb46540540 100644 --- a/dp/wifi3.0/dp_main.c +++ b/dp/wifi3.0/dp_main.c @@ -3370,6 +3370,7 @@ static struct cdp_pdev *dp_pdev_attach_wifi3(struct cdp_soc_t *txrx_soc, /* initlialize cal client timer */ dp_cal_client_attach(&pdev->cal_client_ctx, pdev, pdev->soc->osdev, &dp_iterate_update_peer_list); + qdf_event_create(&pdev->fw_peer_stats_event); return (struct cdp_pdev *)pdev; @@ -7829,6 +7830,7 @@ dp_disable_enhanced_stats(struct cdp_pdev *pdev_handle) * @pdev_handle: DP_PDEV handle * @mac_addr: mac address of the peer * @cap: Type of htt stats requested + * @is_wait: if set, wait on completion from firmware response * * Currently Supporting only MAC ID based requests Only * 1: HTT_PEER_STATS_REQ_MODE_NO_QUERY @@ -7839,7 +7841,7 @@ dp_disable_enhanced_stats(struct cdp_pdev *pdev_handle) */ static void dp_get_fw_peer_stats(struct cdp_pdev *pdev_handle, uint8_t *mac_addr, - uint32_t cap) + uint32_t cap, uint32_t is_wait) { struct dp_pdev *pdev = (struct dp_pdev *)pdev_handle; int i; @@ -7863,9 +7865,20 @@ dp_get_fw_peer_stats(struct cdp_pdev *pdev_handle, uint8_t *mac_addr, config_param3 |= (mac_addr[4] & 0x000000ff); config_param3 |= ((mac_addr[5] << 8) & 0x0000ff00); - dp_h2t_ext_stats_msg_send(pdev, HTT_DBG_EXT_STATS_PEER_INFO, - config_param0, config_param1, config_param2, - config_param3, 0, 0, 0); + if (is_wait) { + qdf_event_reset(&pdev->fw_peer_stats_event); + dp_h2t_ext_stats_msg_send(pdev, HTT_DBG_EXT_STATS_PEER_INFO, + config_param0, config_param1, + config_param2, config_param3, + 0, 1, 0); + qdf_wait_single_event(&pdev->fw_peer_stats_event, + DP_FW_PEER_STATS_CMP_TIMEOUT_MSEC); + } else { + dp_h2t_ext_stats_msg_send(pdev, HTT_DBG_EXT_STATS_PEER_INFO, + config_param0, config_param1, + config_param2, config_param3, + 0, 0, 0); + } } diff --git a/dp/wifi3.0/dp_peer.h b/dp/wifi3.0/dp_peer.h index 7db40d20bb..3458cab568 100644 --- a/dp/wifi3.0/dp_peer.h +++ b/dp/wifi3.0/dp_peer.h @@ -23,6 +23,8 @@ #include "dp_types.h" #define DP_INVALID_PEER_ID 0xffff + +#define DP_FW_PEER_STATS_CMP_TIMEOUT_MSEC 5000 /** * __dp_peer_find_by_id() - Returns peer object given the peer id * @@ -197,4 +199,14 @@ bool dp_peer_find_by_id_valid(struct dp_soc *soc, uint16_t peer_id); } \ } while (0) +/** + * dp_peer_update_inactive_time - Update inactive time for peer + * @pdev: pdev object + * @tag_type: htt_tlv_tag type + * #tag_buf: buf message + */ +void +dp_peer_update_inactive_time(struct dp_pdev *pdev, uint32_t tag_type, + uint32_t *tag_buf); + #endif /* _DP_PEER_H_ */ diff --git a/dp/wifi3.0/dp_stats.c b/dp/wifi3.0/dp_stats.c index be6d31e51d..a21ab44dd4 100644 --- a/dp/wifi3.0/dp_stats.c +++ b/dp/wifi3.0/dp_stats.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2018 The Linux Foundation. All rights reserved. + * Copyright (c) 2017-2019 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 @@ -646,6 +646,8 @@ static inline void dp_print_peer_stats_cmn_tlv(uint32_t *tag_buf) dp_stats_buf->block_bitmap); DP_TRACE_STATS(FATAL, "current_timestamp = %d\n", dp_stats_buf->current_timestamp); + DP_TRACE_STATS(FATAL, "inactive_time = %d", + dp_stats_buf->inactive_time); } /* diff --git a/dp/wifi3.0/dp_types.h b/dp/wifi3.0/dp_types.h index f1a3a9849d..9e5d620c4d 100644 --- a/dp/wifi3.0/dp_types.h +++ b/dp/wifi3.0/dp_types.h @@ -1376,6 +1376,12 @@ struct dp_pdev { * disabled */ uint8_t dp_peer_based_pktlog; + + /* Cached peer_id from htt_peer_details_tlv */ + uint8_t fw_stats_peer_id; + + /* qdf_event for fw_peer_stats */ + qdf_event_t fw_peer_stats_event; }; struct dp_peer;