qcacmn: PPDU stats

Add following changes in the context of PPDU stats
1. Mirror copy mode enhancements
2. Fix memory leak due to mgmt. TLV
3. Reset RX monitor lite ring when enhanced stats disabled

Change-Id: Ifb260929290bc483dc05b152a11cd675104f3a0d
This commit is contained in:
Soumya Bhat 2017-12-15 13:48:53 +05:30 • committed by snandini
commit 7422db894d
5 changed files with 74 additions and 33 deletions

View file

@ -2129,12 +2129,16 @@ static void dp_process_ppdu_stats_user_compltn_flush_tlv(struct dp_pdev *pdev,
static void dp_process_ppdu_stats_tx_mgmtctrl_payload_tlv(
struct dp_pdev *pdev, uint32_t *tag_buf, uint32_t length)
{
htt_ppdu_stats_tx_mgmtctrl_payload_tlv *dp_stats_buf =
(htt_ppdu_stats_tx_mgmtctrl_payload_tlv *)tag_buf;
htt_ppdu_stats_tx_mgmtctrl_payload_tlv *dp_stats_buf;
qdf_nbuf_t nbuf;
uint32_t payload_size;
qdf_nbuf_t nbuf = NULL;
if ((!pdev->tx_sniffer_enable) && (!pdev->mcopy_mode))
return;
uint32_t payload_size = length - HTT_MGMT_CTRL_TLV_RESERVERD_LEN;
payload_size = length - HTT_MGMT_CTRL_TLV_RESERVERD_LEN;
nbuf = NULL;
dp_stats_buf = (htt_ppdu_stats_tx_mgmtctrl_payload_tlv *)tag_buf;
nbuf = qdf_nbuf_alloc(pdev->soc->osdev, payload_size, 0, 4, true);
@ -2276,7 +2280,7 @@ static void dp_txrx_ppdu_stats_handler(struct dp_soc *soc,
int i;
if (!pdev->enhanced_stats_en && !pdev->tx_sniffer_enable &&
!pdev->am_copy_mode)
!pdev->mcopy_mode)
return;
if (!pdev->tx_ppdu_info.buf) {
@ -2302,6 +2306,9 @@ static void dp_txrx_ppdu_stats_handler(struct dp_soc *soc,
sizeof(struct cdp_tx_completion_ppdu)) == NULL) {
QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
"No tailroom for HTT PPDU");
qdf_nbuf_free(pdev->tx_ppdu_info.buf);
pdev->tx_ppdu_info.buf = NULL;
pdev->tx_ppdu_info.last_user = 0;
return;
}
@ -2336,9 +2343,12 @@ static void dp_txrx_ppdu_stats_handler(struct dp_soc *soc,
pdev->tx_ppdu_info.buf, HTT_INVALID_PEER,
WDI_NO_VAL, pdev_id);
pdev->tx_ppdu_info.buf = NULL;
pdev->tx_ppdu_info.last_user = 0;
} else {
qdf_nbuf_free(pdev->tx_ppdu_info.buf);
}
pdev->tx_ppdu_info.buf = NULL;
pdev->tx_ppdu_info.last_user = 0;
}
#else
static void dp_txrx_ppdu_stats_handler(struct dp_soc *soc,

View file

@ -4806,6 +4806,25 @@ dp_get_host_peer_stats(struct cdp_pdev *pdev_handle, char *mac_addr)
return;
}
/*
* dp_ppdu_ring_reset()- Reset PPDU Stats ring
* @pdev: DP_PDEV handle
*
* Return: void
*/
static void
dp_ppdu_ring_reset(struct dp_pdev *pdev)
{
struct htt_rx_ring_tlv_filter htt_tlv_filter;
qdf_mem_set(&(htt_tlv_filter), sizeof(htt_tlv_filter), 0x0);
htt_h2t_rx_ring_cfg(pdev->soc->htt_handle, pdev->pdev_id,
pdev->rxdma_mon_status_ring.hal_srng, RXDMA_MONITOR_STATUS,
RX_BUFFER_SIZE, &htt_tlv_filter);
}
/*
* dp_ppdu_ring_cfg()- Configure PPDU Stats ring
* @pdev: DP_PDEV handle
@ -4859,27 +4878,30 @@ dp_config_debug_sniffer(struct cdp_pdev *pdev_handle, int val)
switch (val) {
case 0:
pdev->tx_sniffer_enable = 0;
pdev->am_copy_mode = 0;
pdev->soc->process_tx_status = 0;
pdev->mcopy_mode = 0;
if (!pdev->enhanced_stats_en)
if (!pdev->enhanced_stats_en) {
dp_h2t_cfg_stats_msg_send(pdev, 0, pdev->pdev_id);
dp_ppdu_ring_reset(pdev);
}
break;
case 1:
pdev->tx_sniffer_enable = 1;
pdev->am_copy_mode = 0;
pdev->soc->process_tx_status = 1;
dp_h2t_cfg_stats_msg_send(pdev,
pdev->mcopy_mode = 0;
if (!pdev->enhanced_stats_en)
dp_h2t_cfg_stats_msg_send(pdev,
DP_PPDU_STATS_CFG_ALL, pdev->pdev_id);
break;
case 2:
pdev->am_copy_mode = 1;
pdev->mcopy_mode = 1;
pdev->tx_sniffer_enable = 0;
pdev->soc->process_tx_status = 1;
dp_ppdu_ring_cfg(pdev);
dp_h2t_cfg_stats_msg_send(pdev,
if (!pdev->enhanced_stats_en) {
dp_ppdu_ring_cfg(pdev);
dp_h2t_cfg_stats_msg_send(pdev,
DP_PPDU_STATS_CFG_ALL, pdev->pdev_id);
}
break;
default:
QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR,
@ -4900,8 +4922,11 @@ dp_enable_enhanced_stats(struct cdp_pdev *pdev_handle)
struct dp_pdev *pdev = (struct dp_pdev *)pdev_handle;
pdev->enhanced_stats_en = 1;
dp_ppdu_ring_cfg(pdev);
dp_h2t_cfg_stats_msg_send(pdev, 0xffff, pdev->pdev_id);
if (!pdev->mcopy_mode)
dp_ppdu_ring_cfg(pdev);
if (!pdev->tx_sniffer_enable && !pdev->mcopy_mode)
dp_h2t_cfg_stats_msg_send(pdev, 0xffff, pdev->pdev_id);
}
/*
@ -4917,8 +4942,11 @@ dp_disable_enhanced_stats(struct cdp_pdev *pdev_handle)
pdev->enhanced_stats_en = 0;
if (!pdev->tx_sniffer_enable && !pdev->am_copy_mode)
if (!pdev->tx_sniffer_enable && !pdev->mcopy_mode)
dp_h2t_cfg_stats_msg_send(pdev, 0, pdev->pdev_id);
if (!pdev->mcopy_mode)
dp_ppdu_ring_reset(pdev);
}
/*

View file

@ -172,17 +172,17 @@ static void dp_rx_stats_update(struct dp_soc *soc, struct dp_peer *peer,
#endif
/**
* dp_rx_handle_am_copy_mode() - Allocate and deliver first MSDU payload
* dp_rx_handle_mcopy_mode() - Allocate and deliver first MSDU payload
* @soc: core txrx main context
* @pdev: pdev strcuture
* @ppdu_info: structure for rx ppdu ring
*
* Return: QDF_STATUS_SUCCESS - If nbuf to be freed by caller
* QDF_STATUS_E_ALREADY - If nbuf not to be freed by caller
*/
*/
#ifdef FEATURE_PERPKT_INFO
static inline QDF_STATUS
dp_rx_handle_am_copy_mode(struct dp_soc *soc, struct dp_pdev *pdev,
dp_rx_handle_mcopy_mode(struct dp_soc *soc, struct dp_pdev *pdev,
struct hal_rx_ppdu_info *ppdu_info, qdf_nbuf_t nbuf)
{
uint8_t size = 0;
@ -197,14 +197,17 @@ dp_rx_handle_am_copy_mode(struct dp_soc *soc, struct dp_pdev *pdev,
size = ppdu_info->first_msdu_payload - qdf_nbuf_data(nbuf);
ppdu_info->first_msdu_payload = NULL;
qdf_nbuf_pull_head(nbuf, size);
if (qdf_nbuf_pull_head(nbuf, size) == NULL)
return QDF_STATUS_SUCCESS;
dp_wdi_event_handler(WDI_EVENT_RX_DATA, soc,
nbuf, HTT_INVALID_PEER, WDI_NO_VAL, pdev->pdev_id);
return QDF_STATUS_E_ALREADY;
}
#else
static inline QDF_STATUS
dp_rx_handle_am_copy_mode(struct dp_soc *soc, struct dp_pdev *pdev,
dp_rx_handle_mcopy_mode(struct dp_soc *soc, struct dp_pdev *pdev,
struct hal_rx_ppdu_info *ppdu_info, qdf_nbuf_t nbuf)
{
return QDF_STATUS_SUCCESS;
@ -292,8 +295,7 @@ dp_rx_mon_status_process_tlv(struct dp_soc *soc, uint32_t mac_id,
status_nbuf, HTT_INVALID_PEER, WDI_NO_VAL, mac_id);
#endif
#endif
if ((pdev->monitor_vdev != NULL) || (pdev->enhanced_stats_en)
|| (pdev->am_copy_mode)) {
if ((pdev->monitor_vdev != NULL) || (pdev->enhanced_stats_en)) {
do {
tlv_status = hal_rx_status_get_tlv_info(rx_tlv,
@ -306,8 +308,8 @@ dp_rx_mon_status_process_tlv(struct dp_soc *soc, uint32_t mac_id,
} while (tlv_status == HAL_TLV_STATUS_PPDU_NOT_DONE);
}
if (pdev->am_copy_mode) {
am_copy_status = dp_rx_handle_am_copy_mode(soc,
if (pdev->mcopy_mode) {
am_copy_status = dp_rx_handle_mcopy_mode(soc,
pdev, ppdu_info, status_nbuf);
if (am_copy_status == QDF_STATUS_SUCCESS)
qdf_nbuf_free(status_nbuf);
@ -317,7 +319,7 @@ dp_rx_mon_status_process_tlv(struct dp_soc *soc, uint32_t mac_id,
if (tlv_status == HAL_TLV_STATUS_PPDU_DONE) {
if (pdev->enhanced_stats_en ||
pdev->am_copy_mode)
pdev->mcopy_mode)
dp_rx_handle_ppdu_stats(soc, pdev, ppdu_info);
pdev->mon_ppdu_status = DP_PPDU_STATUS_DONE;

View file

@ -1992,7 +1992,7 @@ dp_send_compl_to_stack(struct dp_soc *soc, struct dp_pdev *pdev,
struct tx_capture_hdr *ppdu_hdr;
struct dp_peer *peer = NULL;
if (qdf_unlikely(!pdev->tx_sniffer_enable && !pdev->am_copy_mode))
if (qdf_unlikely(!pdev->tx_sniffer_enable && !pdev->mcopy_mode))
return QDF_STATUS_E_NOSUPPORT;
peer = (peer_id == HTT_INVALID_PEER) ? NULL :
@ -2004,7 +2004,7 @@ dp_send_compl_to_stack(struct dp_soc *soc, struct dp_pdev *pdev,
return QDF_STATUS_E_INVAL;
}
if (pdev->am_copy_mode) {
if (pdev->mcopy_mode) {
if ((pdev->am_copy_id.tx_ppdu_id == ppdu_id) &&
(pdev->am_copy_id.tx_peer_id == peer_id)) {
return QDF_STATUS_E_INVAL;

View file

@ -1093,7 +1093,8 @@ struct dp_pdev {
} tx_ppdu_info;
bool tx_sniffer_enable;
bool am_copy_mode;
/* mirror copy mode */
bool mcopy_mode;
struct {
uint16_t tx_ppdu_id;